diff --git a/.bzrignore b/.bzrignore new file mode 100644 index 000000000..8cdc9d12d --- /dev/null +++ b/.bzrignore @@ -0,0 +1,65 @@ +00_header +10_* +30_os-prober +40_custom +aclocal.m4 +autom4te.cache +build_env.mk +.bzrignore +config.cache +config.guess +config.h +config.h.in +config.log +config.status +config.sub +configure +conf/*.mk +conf/gcry.rmk +*.d +DISTLIST +docs/*.info +docs/stamp-vti +docs/version.texi +*.elf +*.exec +genkernsyms.sh +gensymlist.sh +grub-dumpbios +grub-editenv +grub-emu +grub_emu_init.c +grub_emu_init.h +grub-fstest +grub_fstest_init.c +grub_fstest_init.h +grub-install +grub-mk* +grub-pbkdf2 +grub-pe2elf +grub-probe +grub_probe_init.c +grub_probe_init.h +grub_script.tab.c +grub_script.tab.h +grub-setup +grub_setup_init.c +grub_setup_init.h +*.img +include/grub/cpu +include/grub/machine +install-sh +lib/libgcrypt-grub +*.lst +Makefile +*.mod +mod-*.c +missing +*.pf2 +po/*.mo +po/grub.pot +stamp-h +stamp-h1 +stamp-h.in +symlist.c +update-grub_lib diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 33ffaa404..000000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -po/exclude.pot binary diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 524f2e6d0..000000000 --- a/.gitignore +++ /dev/null @@ -1,285 +0,0 @@ -# -# Ignore patterns in this directory and all subdirectories. -# -*.1 -*.8 -*.a -*.exec -*.exec.exe -*.image -*.image.exe -*.img -*.log -*.lst -*.marker -*.mod -*.o -*.pf2 -*.pp -*.pyc -*.trs -*~ -.deps-core/ -.deps-util/ -.deps/ -.dirstamp -DISTLIST -GPATH -GRTAGS -GSYMS -GTAGS -Makefile -Makefile.in -ascii.bitmaps -genkernsyms.sh -gensymlist.sh -grub-bin2h -grub-emu -grub-emu-lite -grub-emu-lite.exe -grub-emu.exe -grub-macho2img -grub_emu_init.c -grub_emu_init.h -grub_probe_init.c -grub_probe_init.h -grub_script.tab.c -grub_script.tab.h -grub_script.yy.c -grub_script.yy.h -grub_script_check_init.c -grub_script_check_init.h -grub_setup_init.c -grub_setup_init.h -mdate-sh -mod-*.c -update-grub_lib -widthspec.bin - -# -# Ignore patterns relative to this .gitignore file's directory. -# -/00_header -/10_* -/20_linux_xen -/30_os-prober -/30_uefi-firmware -/40_custom -/41_custom -/ABOUT-NLS -/ChangeLog -/INSTALL.grub -/Makefile.util.am -/Makefile.utilgcry.def -/aclocal.m4 -/ahci_test -/ascii.h -/autom4te.cache/ -/btrfs_test -/build-aux/ -/build-grub-gen-asciih -/build-grub-gen-widthspec -/build-grub-mkfont -/cdboot_test -/cmp_test -/compile -/config-util.h -/config-util.h.in -/config.cache -/config.guess -/config.h -/config.log -/config.status -/config.sub -/configure -/contrib -/core_compress_test -/cpio_test -/date_test -/depcomp -/docs/*.info -/docs/*.info-[0-9]* -/docs/stamp-1 -/docs/stamp-vti -/docs/version-dev.texi -/docs/version.texi -/ehci_test -/erofs_test -/example_grub_script_test -/example_scripted_test -/example_unit_test -/exfat_test -/ext234_test -/f2fs_test -/fat_test -/fddboot_test -/file_filter_test -/garbage-gen -/garbage-gen.exe -/gettext_strings_test -/gnulib/ -/grub-2.[0-9]*/ -/grub-2.[0-9]*.tar.gz -/grub-bios-setup -/grub-bios-setup.exe -/grub-core/*.module -/grub-core/*.module.exe -/grub-core/*.pp -/grub-core/Makefile.core.am -/grub-core/Makefile.gcry.def -/grub-core/bootinfo.txt -/grub-core/build-grub-module-verifier -/grub-core/build-grub-pe2elf.exe -/grub-core/contrib -/grub-core/gdb_grub -/grub-core/genmod.sh -/grub-core/gensyminfo.sh -/grub-core/gentrigtables -/grub-core/gentrigtables.exe -/grub-core/gmodule.pl -/grub-core/grub.chrp -/grub-core/kernel.img.bin -/grub-core/lib/gnulib -/grub-core/lib/libgcrypt-grub -/grub-core/lib/libtasn1-grub -/grub-core/modinfo.sh -/grub-core/rs_decoder.h -/grub-core/symlist.c -/grub-core/symlist.h -/grub-core/tests/asn1/tests -/grub-core/trigtables.c -/grub-core/unidata.c -/grub-editenv -/grub-editenv.exe -/grub-file -/grub-file.exe -/grub-fs-tester -/grub-fstest -/grub-fstest.exe -/grub-glue-efi -/grub-glue-efi.exe -/grub-install -/grub-install.exe -/grub-kbdcomp -/grub-macbless -/grub-macbless.exe -/grub-menulst2cfg -/grub-menulst2cfg.exe -/grub-mk* -/grub-mount -/grub-ofpathname -/grub-ofpathname.exe -/grub-probe -/grub-probe.exe -/grub-protect -/grub-protect.exe -/grub-reboot -/grub-render-label -/grub-render-label.exe -/grub-script-check -/grub-script-check.exe -/grub-set-default -/grub-shell -/grub-shell-tester -/grub-sparc64-setup -/grub-sparc64-setup.exe -/grub-syslinux2cfg -/grub-syslinux2cfg.exe -/grub_cmd_date -/grub_cmd_echo -/grub_cmd_regexp -/grub_cmd_set_date -/grub_cmd_sleep -/grub_cmd_test -/grub_cmd_tr -/grub_fstest_init.c -/grub_fstest_init.h -/grub_func_test -/grub_script_blanklines -/grub_script_blockarg -/grub_script_break -/grub_script_comments -/grub_script_continue -/grub_script_dollar -/grub_script_echo1 -/grub_script_echo_keywords -/grub_script_escape_comma -/grub_script_eval -/grub_script_expansion -/grub_script_final_semicolon -/grub_script_for1 -/grub_script_functions -/grub_script_gettext -/grub_script_if -/grub_script_leading_whitespace -/grub_script_no_commands -/grub_script_not -/grub_script_return -/grub_script_setparams -/grub_script_shift -/grub_script_strcmp -/grub_script_test -/grub_script_vars1 -/grub_script_while1 -/gzcompress_test -/hddboot_test -/help_test -/hfs_test -/hfsplus_test -/include/grub/cpu -/include/grub/gcrypt/g10lib.h -/include/grub/gcrypt/gcrypt.h -/include/grub/machine -/install-sh -/iso9660_test -/jfs_test -/lib/libgcrypt-grub -/libgrub_a_init.c -/lzocompress_test -/luks1_test -/luks2_test -/m4/ -/minixfs_test -/missing -/netboot_test -/nilfs2_test -/ntfs_test -/ohci_test -/partmap_test -/pata_test -/po/*.gmo -/po/*.mo -/po/*.po -/po/LINGUAS -/po/Makefile.in.in -/po/Makevars -/po/Makevars.template -/po/POTFILES -/po/POTFILES-shell.in -/po/POTFILES.in -/po/Rules-quot -/po/grub.pot -/po/remove-potcdate.sed -/po/stamp-po -/printf_test -/priority_queue_unit_test -/pseries_test -/reiserfs_test -/romfs_test -/squashfs_test -/stamp-h -/stamp-h.in -/stamp-h1 -/syslinux_test -/tar_test -/test_sha512sum -/test_unset -/tests/syslinux/ubuntu10.04_grub.cfg -/texinfo.tex -/udf_test -/uhci_test -/util/bash-completion.d/grub -/widthspec.h -/xfs_test -/xzcompress_test -/zfs_test diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 4bd05a30a..000000000 --- a/.travis.yml +++ /dev/null @@ -1,109 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0+ -# Originally Copyright Roger Meier -# Adapted for GRUB by Alexander Graf -# -# Build GRUB on Travis CI - https://www.travis-ci.org/ -# - -dist: xenial - -language: c - -addons: - apt: - packages: - - autopoint - - libsdl1.2-dev - - lzop - - ovmf - - python - - qemu-system - - unifont - -env: - global: - # Include all cross toolchain paths, so we can just call them later down. - - PATH=/tmp/qemu-install/bin:/tmp/grub/bin:/usr/bin:/bin:/tmp/cross/gcc-8.1.0-nolibc/aarch64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/arm-linux-gnueabi/bin:/tmp/cross/gcc-8.1.0-nolibc/ia64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/mips64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/powerpc64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/riscv32-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/riscv64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/sparc64-linux/bin - -before_script: - # Install necessary toolchains based on $CROSS_TARGETS variable. - - mkdir /tmp/cross - # These give us binaries like /tmp/cross/gcc-8.1.0-nolibc/ia64-linux/bin/ia64-linux-gcc - - for i in $CROSS_TARGETS; do - ( cd /tmp/cross; wget -t 3 -O - https://mirrors.kernel.org/pub/tools/crosstool/files/bin/x86_64/8.1.0/x86_64-gcc-8.1.0-nolibc-$i.tar.xz | tar xJ ); - done - -script: - # Comments must be outside the command strings below, or the Travis parser - # will get confused. - - ./bootstrap - - # Build all selected GRUB targets. - - for target in $GRUB_TARGETS; do - plat=${target#*-}; - arch=${target%-*}; - [ "$arch" = "arm64" ] && arch=aarch64-linux; - [ "$arch" = "arm" ] && arch=arm-linux-gnueabi; - [ "$arch" = "ia64" ] && arch=ia64-linux; - [ "$arch" = "mipsel" ] && arch=mips64-linux; - [ "$arch" = "powerpc" ] && arch=powerpc64-linux; - [ "$arch" = "riscv32" ] && arch=riscv32-linux; - [ "$arch" = "riscv64" ] && arch=riscv64-linux; - [ "$arch" = "sparc64" ] && arch=sparc64-linux; - echo "Building $target"; - mkdir obj-$target; - JOBS=`getconf _NPROCESSORS_ONLN 2> /dev/null || echo 1`; - [ "$JOBS" == 1 ] || JOBS=$(($JOBS + 1)); - ( cd obj-$target && ../configure --target=$arch --with-platform=$plat --prefix=/tmp/grub && make -j$JOBS && make -j$JOBS install ) &> log || ( cat log; false ); - done - - # Our test canary. - - echo -e "insmod echo\\ninsmod reboot\\necho hello world\\nreboot" > grub.cfg - - # Assemble images and possibly run them. - - for target in $GRUB_TARGETS; do grub-mkimage -c grub.cfg -p / -O $target -o grub-$target echo reboot normal; done - - # Run images we know how to run. - - if [[ "$GRUB_TARGETS" == *"x86_64-efi"* ]]; then qemu-system-x86_64 -bios /usr/share/ovmf/OVMF.fd -m 512 -no-reboot -nographic -net nic -net user,tftp=.,bootfile=grub-x86_64-efi | tee grub.log && grep "hello world" grub.log; fi - -matrix: - include: - # Each env setting here is a dedicated build. - - name: "x86_64" - env: - - GRUB_TARGETS="x86_64-efi x86_64-xen" - - name: "i386" - env: - - GRUB_TARGETS="i386-coreboot i386-efi i386-ieee1275 i386-multiboot i386-pc i386-qemu i386-xen i386-xen_pvh" - - name: "powerpc" - env: - - GRUB_TARGETS="powerpc-ieee1275" - - CROSS_TARGETS="powerpc64-linux" - - name: "sparc64" - env: - - GRUB_TARGETS="sparc64-ieee1275" - - CROSS_TARGETS="sparc64-linux" - - name: "ia64" - env: - - GRUB_TARGETS="ia64-efi" - - CROSS_TARGETS="ia64-linux" - - name: "mips" - env: - - GRUB_TARGETS="mips-arc mipsel-arc mipsel-qemu_mips mips-qemu_mips" - - CROSS_TARGETS="mips64-linux" - - name: "arm" - env: - - GRUB_TARGETS="arm-coreboot arm-efi arm-uboot" - - CROSS_TARGETS="arm-linux-gnueabi" - - name: "arm64" - env: - - GRUB_TARGETS="arm64-efi" - - CROSS_TARGETS="aarch64-linux" - - name: "riscv32" - env: - - GRUB_TARGETS="riscv32-efi" - - CROSS_TARGETS="riscv32-linux" - - name: "riscv64" - env: - - GRUB_TARGETS="riscv64-efi" - - CROSS_TARGETS="riscv64-linux" diff --git a/BUGS b/BUGS deleted file mode 100644 index 46faa6452..000000000 --- a/BUGS +++ /dev/null @@ -1,7 +0,0 @@ -GRUB team is aware of following problems: - - Currently search and assembling multidevice abstractions scans - all the devices which can be slow. - - Cache isn't used correctly for video which results in slowness. - -While these are bugs their solution has a potential of breaking more and more -seriously. So it was decided for 1.99 that they aren't fixed. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 000000000..56f19acde --- /dev/null +++ b/ChangeLog @@ -0,0 +1,25216 @@ +2010-03-06 Vladimir Serbinenko + + * NEWS: Put the date of 1.98 release. + +2010-03-06 Vladimir Serbinenko + + * configure.ac: Update CPPFLAGS and not CFLAGS when checking for + ft2build.h. + +2010-03-06 Vladimir Serbinenko + + * normal/cmdline.c (grub_cmdline_get): Fix gabled line after + completition in the middle of string. + +2010-03-06 Vladimir Serbinenko + + * util/grub-mkrescue.in: Use mktemp with explicit template. + +2010-03-06 Vladimir Serbinenko + + * loader/i386/bsd.c (grub_bsd_get_device): Fix a memory leak. + +2010-03-06 Vladimir Serbinenko + + * loader/i386/multiboot_mbi.c (grub_multiboot_set_bootdev): Free the + right pointer. + +2010-03-05 Vladimir Serbinenko + + Fix FreeBSD compilation. + + * Makefile.in (TARGET_CPPFLAGS): Remove -nostdinc -isystem. + * configure.ac: Add -nostdinc -isystem to TARGET_CPPFLAGS if it works. + +2010-03-05 Vladimir Serbinenko + + * util/import_gcry.py: Add autogenerated files to MAINTAINER_CLEANFILES. + +2010-03-04 Vladimir Serbinenko + + * gettext/gettext.c (grub_gettext_init_ext): Fix a memory leak. + +2010-03-04 Vladimir Serbinenko + + * disk/scsi.c (grub_scsi_iterate): Fix a memory leak. + +2010-03-04 Robert Millan + + Support relative image path in theme file. + + * gfxmenu/gui_image.c (grub_gui_image): New member theme_dir. + (image_set_property): Handle theme_dir and relative path. + +2010-03-04 Vladimir Serbinenko + + * configure.ac: Alias amd64 to x86_64. + +2010-03-04 Vladimir Serbinenko + + * NEWS: mention multiboot on EFI. + +2010-03-04 Vladimir Serbinenko + + * kern/main.c (grub_load_modules): Handle errors from init functions of + embeded modules. + +2010-03-04 Vladimir Serbinenko + + * normal/autofs.c (autoload_fs_module): Handle errors. + +2010-03-04 Vladimir Serbinenko + + Disable linux.mod on qemu-mips since it's not functional and leads + to compilation failure. + + * conf/mips.rmk (pkglib_MODULES): Remove linux.mod. + * conf/mips-yeeloong.rmk (pkglib_MODULES): Add linux.mod. + * conf/mips.rmk (linux_mod_SOURCES): Move from here ... + * conf/mips-yeeloong.rmk (linux_mod_SOURCES): ... here + * conf/mips.rmk (linux_mod_CFLAGS): Move from here ... + * conf/mips-yeeloong.rmk (linux_mod_CFLAGS): ... here + * conf/mips.rmk (linux_mod_ASFLAGS): Move from here ... + * conf/mips-yeeloong.rmk (linux_mod_ASFLAGS): ... here + * conf/mips.rmk (linux_mod_LDFLAGS): Move from here ... + * conf/mips-yeeloong.rmk (linux_mod_LDFLAGS): ... here + Reported by: BVK Chaitanya + +2010-03-04 Jordan Uggla + + * INSTALL: Add gettext as a dependency and add qemu to a new section + "Prerequisites for make-check". + +2010-03-04 Christian Franke + + * util/grub-pe2elf.c: Add missing include "progname.h". + +2010-03-04 Vladimir Serbinenko + + * normal/crypto.c (read_crypto_list): Fix a typo. + Reported by: Seth Goldberg. + +2010-03-04 Vladimir Serbinenko + + * Makefile.in (DISTCLEANFILES): Add stamp-h1. + Reported by: Seth Goldberg. + +2010-03-04 Vladimir Serbinenko + + * Makefile.in (CLEANFILES) [FONT_SOURCE && grub_mkfont]: Add + ascii.bitmaps. + +2010-03-04 Vladimir Serbinenko + + * genmk.rb: Remove terminal*.lst in make clean. + Reported by: Seth Goldberg. + +2010-03-04 Vladimir Serbinenko + + * util/i386/efi/grub-install.in: Copy gettext files. + +2010-03-01 Vladimir Serbinenko + + * fs/ext2.c (grub_ext2_read_block): Fix an integer overflow. + +2010-03-01 Vladimir Serbinenko + + Wait for user entry basing on presence of output rather than on errors. + + * include/grub/normal.h (grub_normal_get_line_counter): New proto. + (grub_install_newline_hook): Likewise. + * normal/main.c (GRUB_MOD_INIT): Call grub_install_newline_hook. + * normal/menu.c (show_menu): Check line_counter to determine presence + of output. + * normal/term.c (grub_normal_line_counter): New variable. + (grub_normal_get_line_counter): New function. + (grub_install_newline_hook): Likewise. + +2010-03-01 Vladimir Serbinenko + + * commands/cat.c (grub_cmd_cat): Propagate grub_gzfile_open error. + +2010-03-01 Vladimir Serbinenko + + * configure.ac: Update version to 1.98. + +2010-02-26 Vladimir Serbinenko + + * util/grub.d/10_linux.in (linux_entry): Don't default to + gfxpayload=keep if Linux doesn't support video handover. + +2010-02-25 Vladimir Serbinenko + + Don't compile video modules on yeeloong since video subsystem is part + of kernel. + + * conf/common.rmk (pkglib_MODULES) [yeeloong]: Remove video.mod, + video_fb.mod, bitmap.mod, font.mod, gfxterm.mod and bufio.mod + * conf/mips-yeeloong.rmk (kernel_img_HEADERS): Add bitmap.h, + video.h, gfxterm.h, font.h, bitmap_scale.h and bufio.h. + * conf/mips.rmk (kernel_img_HEADERS): Add values instead of overwriting. + * include/grub/bitmap.h: Add EXPORT_FUNC and EXPORT_VAR. + * include/grub/bitmap_scale.h: Likewise. + * include/grub/bufio.h: Likewise. + * include/grub/font.h: Likewise. + * include/grub/gfxterm.h: Likewise. + * include/grub/video.h: Likewise. + * include/grub/vbe.h: Don't include video_fb.h. + * video/i386/pc/vbe.c: Include video_fb.h. + * commands/i386/pc/vbetest.c: Include video.h. + +2010-02-25 Jordan Uggla + + * util/grub-mkconfig.in (GRUB_SAVEDEFAULT): Export new variable. + * util/grub-mkconfig_lib.in (save_default_entry): Only save a new + default entry if GRUB_SAVEDEFAULT=true. This allows using + GRUB_DEFAULT=saved on its own to let grub-reboot work, without + saving a new default on every boot. + +2010-02-24 Vladimir Serbinenko + + * normal/crypto.c (read_crypto_list): Fix a memory leak. + * normal/term.c (read_terminal_list): Likewise. + * normal/main.c (grub_normal_init_page): Likewise. + (grub_normal_read_line_real): Likewise. + +2010-02-24 Vladimir Serbinenko + + * loader/i386/multiboot_mbi.c (grub_multiboot_set_bootdev): Fix a + memory leak. + Reported by: Seth Goldberg. + +2010-02-24 Joey Korkames + + * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Remove + duplicate declaration of `start'. + +2010-02-20 Vladimir Serbinenko + + * fs/iso9660.c (grub_iso9660_iterate_dir): Strip version from joliet + filename. + Reported by: Georgy Buranov + +2010-02-20 Carles Pina i Estany + + * util/grub-mkrawimage.c (usage): Change string formatting to + improve gettext. + +2010-02-20 Manoel Rebelo Abranches + + * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Add delete and + backspace keys. + +2010-02-20 Vladimir Serbinenko + + * video/fb/video_fb.c (grub_video_fb_scroll): Fix a pixel size bug. + Reported by: Michael Suchanek. + +2010-02-18 Samuel Thibault + + * util/grub-mkconfig.in: Export GRUB_INIT_TUNE. + * util/grub.d/00_header.in: Handle GRUB_INIT_TUNE. + +2010-02-16 Vladimir Serbinenko + + Remove any reference to non-free fonts. + + * commands/videotest.c (grub_cmd_videotest): Use unifont by default. + * docs/gfxmenu-theme-example.txt: Removed. It's both outdated and + uses non-free components. + * font/font.c (grub_font_get_name): Remove example name. + * gfxmenu/gui_label.c (grub_gui_label_new): Use unifont by default. + * gfxmenu/gui_list.c (grub_gui_list_new): Likewise. + * gfxmenu/gui_progress_bar.c (grub_gui_progress_bar_new): Likewise. + * gfxmenu/view.c (grub_gfxmenu_view_new): Likewise. + +2010-02-16 Georgy Buranov + + * disk/efi/efidisk.c (grub_efidisk_get_device_name): Fix a typo. + +2010-02-15 Vladimir Serbinenko + + * term/serial.c (serial_get_divisor) [GRUB_MACHINE_MIPS_YEELOONG]: + Double divisor. + (serial_hw_init) [GRUB_MACHINE_MIPS_YEELOONG]: Don't enable advanced + features. + (GRUB_MOD_INIT) [GRUB_MACHINE_MIPS_YEELOONG]: Default to 115200. + +2010-02-15 Vladimir Serbinenko + + * gensymlist.sh.in: Use TARGET_CC instead of CC. + +2010-02-14 Samuel Thibault + + * commands/i386/pc/play.c (GRUB_MOD_INIT(play)): Fix help. + * docs/grub.texi (Command-line and menu entry commands): Document play + command. + +2010-02-14 Samuel Thibault + + * commands/i386/pc/play.c (grub_cmd_play): If grub_file_open fails, + parse arguments as inline tempo and notes. Move code for playing notes + to... + (play): ... new function. + +2010-02-14 Samuel Thibault + + * commands/i386/pc/play.c (T_REST, T_FINE, struct note, beep_on): Use + grub_uint16_t instead of short. + (grub_cmd_play): Use grub_uint32_t instead of int, convert data from + disk from little endian to cpu endianness. + +2010-02-07 Samuel Thibault + + * commands/i386/pc/play.c (BASE_TEMPO): Set to 60 * + GRUB_TICKS_PER_SECOND instead of 120. + +2010-02-14 Vladimir Serbinenko + + * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Wait for possible + escape sequence after \e. + +2010-02-14 Vladimir Serbinenko + + * term/ieee1275/ofconsole.c (grub_ofconsole_putchar): Don't output + non-ASCII characters. + +2010-02-14 Vladimir Serbinenko + + * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Enclose + set root in single quotes to prevent \, from being unescaped. + +2010-02-14 Vladimir Serbinenko + + Prevent unknown commands from stopping menuentry execution. + + * script/execute.c (grub_script_execute_cmdline): Print error after + unknown command. + +2010-02-14 Vladimir Serbinenko + + * fs/i386/pc/pxe.c (GRUB_MOD_INIT): Fix typo. + Reported by: Pavel Pisa. + +2010-02-13 Vladimir Serbinenko + + * io/gzio.c (grub_gzio_open): Use grub_zalloc. + +2010-02-13 Vladimir Serbinenko + + Merge grub_ieee1275_map_physical into grub_map and rename to + grub_ieee1275_map + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_map): New proto. + * include/grub/sparc64/ieee1275/ieee1275.h (grub_ieee1275_map_physical): + Remove. + * kern/ieee1275/openfw.c (grub_map): Rename to ... + (grub_ieee1275_map): ... this. All users updated. Add phys_lo when + necessary. + * kern/sparc64/ieee1275/ieee1275.c (grub_ieee1275_map_physical): Remove. + +2010-02-13 Vladimir Serbinenko + + * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Check device type before + opening and not after. + +2010-02-13 Vladimir Serbinenko + + * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Macroify + constants. + +2010-02-13 Vladimir Serbinenko + + * loader/sparc64/ieee1275/linux.c (align_addr): Remove. + (alloc_phys): Use ALIGN_UP instead of align_addr. + +2010-02-13 Vladimir Serbinenko + + * loader/sparc64/ieee1275/linux.c (alloc_phys): Correct bounds checking. + +2010-02-13 Vladimir Serbinenko + + * kern/sparc64/ieee1275/crt0.S (codestart): Move modules backwards. + +2010-02-13 Vladimir Serbinenko + + * disk/ieee1275/ofdisk.c (grub_ofdisk_read): Remove excessively + verbose dprintf. + +2010-02-13 Vladimir Serbinenko + + Fix over-4GiB seek on sparc64. + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_seek): + Replace pos_i and pos_lo with pos. All users updated. + * include/grub/powerpc/ieee1275/ieee1275.h (GRUB_IEEE1275_CELL_SIZEOF): + New constant. + * include/grub/sparc64/ieee1275/ieee1275.h (GRUB_IEEE1275_CELL_SIZEOF): + Likewise. + * kern/ieee1275/ieee1275.c (grub_ieee1275_seek): Split pos into pos_hi + and pos_lo. + +2010-02-13 Vladimir Serbinenko + + * util/grub-mkrawimage.c (main): Call set_program_name. + +2010-02-13 Vladimir Serbinenko + + Properly align 64-bit targets. + + * util/grub-mkrawimage.c (ALIGN_ADDR): New macro. + (generate_image): Use ALIGN_ADDR. + +2010-02-13 Vladimir Serbinenko + + Properly create cross-endian images. + + * include/grub/types.h (grub_host_to_target_addr): New macro + * util/grub-mkrawimage.c (generate_image): Add missing host_to_target. + +2010-02-13 Vladimir Serbinenko + + * util/grub-mkrawimage.c (generate_image): Add forgotten ALIGN_UP. + +2010-02-10 Vladimir Serbinenko + + Pass SIMPLE framebuffer size in bytes and not 64K blocks. + + * loader/i386/efi/linux.c (grub_linux_setup_video): Don't divide by 64K. + * loader/i386/linux.c (grub_linux_setup_video): Likewise. + (grub_linux_boot): Divide by 64K when on VESA. + +2010-02-10 Vladimir Serbinenko + + Support GRUB_GFXPAYLOAD_LINUX. + + * util/grub-mkconfig.in: Export GRUB_GFXPAYLOAD_LINUX. + * util/grub.d/10_linux.in (linux_entry): Handle GRUB_GFXPAYLOAD_LINUX. + +2010-02-10 Vladimir Serbinenko + + * script/execute.c (grub_script_execute_cmdline): Use grub_print_error + to show messages instead of discarding them. + Process errors after executing command and not before. Keep old method + too as precaution. + +2010-02-09 Vladimir Serbinenko + + * configure.ac: Check for ft2build.h. + +2010-02-07 Vladimir Serbinenko + + * kern/ieee1275/openfw.c (grub_halt): Try executing "poweroff". + +2010-02-07 Vladimir Serbinenko + + * genkernsyms.sh.in: Use TARGET_CC. + +2010-02-07 Colin Watson + + * NEWS: Update. + +2010-02-07 Vladimir Serbinenko + + * include/grub/multiboot2.h: Remove leftover file. + * include/grub/normal.h [GRUB_UTIL]: Remove leftover declarations. + * include/grub/partition.h [GRUB_UTIL]: Likewise. + +2010-02-07 Yves Blusseau + + * gnulib/getdelim.c: add missing header (type ssize_t must be defined). + +2010-02-07 Vladimir Serbinenko + + Fix warnings in grub-emu when compiling with maximum warning options. + + * util/grub-emu.c (ENABLE_RELOCATABLE): New definition. + (grub_arch_modules_addr): Return 0 and not NULL. + * util/misc.c (ENABLE_RELOCATABLE): New definition. + (xstrdup): Use newstr instead of dup. + * util/hostdisk.c (grub_util_biosdisk_get_grub_dev): Rename one instance + of disk to dsk to avoid shadowing. + (find_free_slot): Fix prototype. + * util/getroot.c (grub_util_is_dmraid): Make static. + * include/grub/time.h (grub_get_rtc) [GRUB_MACHINE_EMU || GRUB_UTIL]: + Add missing prototype. + * util/sdl.c (grub_video_sdl_set_viewport): Remove. + +2010-02-07 Vladimir Serbinenko + + * loader/i386/linux.c (grub_linux_setup_video): Handle error + appropriately. + +2010-02-07 Vladimir Serbinenko + + * fs/reiserfs.c (grub_reiserfs_read): Use #if 0 instead of commenting + code out. + +2010-02-07 Vladimir Serbinenko + + * include/grub/cache.h (grub_arch_sync_caches) [i386 || x86_64]: Inline. + * kern/i386/coreboot/init.c (grub_arch_sync_caches): Remove. + * kern/i386/efi/init.c (grub_arch_sync_caches): Likewise. + * kern/i386/ieee1275/init.c (grub_arch_sync_caches): Likewise. + * kern/i386/pc/init.c (grub_arch_sync_caches): Likewise. + * util/misc.c (grub_arch_sync_caches) [i386 || x86_64]: Likewise. + +2010-02-07 Vladimir Serbinenko + + * include/grub/err.h (grub_err_printf): Don't export. + +2010-02-07 Vladimir Serbinenko + + * include/grub/dl.h (grub_dl_register_symbol): Don't export. + +2010-02-07 Vladimir Serbinenko + + * include/grub/i18n.h (grub_gettext_dummy): Removed. + * kern/misc.c (grub_gettext_dummy): Make static. + +2010-02-06 Vladimir Serbinenko + + * kern/misc.c (grub_utf8_to_ucs4): Don't eat valid characters preceeded + by non-valid ones. + * kern/term.c (grub_putchar): Likewise. + +2010-02-06 Vladimir Serbinenko + + * partmap/sun.c (sun_partition_map_iterate): Restructure flow to fix + buggy hook call and memory leak. + +2010-02-06 Vladimir Serbinenko + + * commands/ls.c (grub_ls_list_files): Free pathname on exit. + +2010-02-06 Vladimir Serbinenko + + * fs/fat.c (grub_fat_iterate_dir): Free unibuf at exit. + +2010-02-06 Vladimir Serbinenko + + * loader/i386/pc/xnu.c (grub_xnu_set_video): Add const qualifier to + modevar. + Return grub_errno on allocation error. + +2010-02-06 Vladimir Serbinenko + + * disk/ieee1275/ofdisk.c (grub_ofdisk_read): Correct error handling. + +2010-02-06 Yves Blusseau + + * conf/common.rmk (grub_script_check_SOURCES): add missing dependencies. + (grub_mkpasswd_pbkdf2_SOURCES): Likewise. + +2010-02-06 Vladimir Serbinenko + + * fs/i386/pc/pxe.c (grub_pxefs_dir): Return with failure on + non-pxe disk. + (grub_pxefs_open): Likewise. + +2010-02-06 Robert Millan + + * util/grub.d/10_hurd.in: Add --class information to menuentries. + * util/grub.d/10_kfreebsd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. + +2010-02-06 Colin D Bennett + + * conf/common.rmk (pkglib_MODULES): Add gfxmenu.mod. + (gfxmenu_mod_SOURCES): New variable. + (gfxmenu_mod_CFLAGS): Likewise. + (gfxmenu_mod_LDFLAGS): Likewise. + * include/grub/term.h (grub_term_set_current_output): Declare + argument as const. + * docs/gfxmenu-theme-example.txt: New file. + * gfxmenu/gfxmenu.c: Likewise. + * gfxmenu/gui_box.c: Likewise. + * gfxmenu/gui_canvas.c: Likewise. + * gfxmenu/gui_circular_progress.c: Likewise. + * gfxmenu/gui_image.c: Likewise. + * gfxmenu/gui_label.c: Likewise. + * gfxmenu/gui_list.c: Likewise. + * gfxmenu/gui_progress_bar.c: Likewise. + * gfxmenu/gui_string_util.c: Likewise. + * gfxmenu/gui_util.c: Likewise. + * gfxmenu/icon_manager.c: Likewise. + * gfxmenu/model.c: Likewise. + * gfxmenu/named_colors.c: Likewise. + * gfxmenu/theme_loader.c: Likewise. + * gfxmenu/view.c: Likewise. + * gfxmenu/widget-box.c: Likewise. + * include/grub/gfxmenu_model.h: Likewise. + * include/grub/gfxmenu_view.h: Likewise. + * include/grub/gfxwidgets.h: Likewise. + * include/grub/gui.h: Likewise. + * include/grub/gui_string_util.h: Likewise. + * include/grub/icon_manager.h: Likewise. + +2010-02-06 Vladimir Serbinenko + + Agglomerate scrolling in gfxterm. + + * term/gfxterm.c (grub_virtual_screen): New member 'total_screen'. + (grub_virtual_screen_setup): Initialise 'total_screen'. + (write_char): Split to ... + (paint_char): ... this ... + (write_char): ... and this. + (paint_char): Handle delayed scrolling. + (draw_cursor): Likewise. + (scroll_up): Split to ... + (real_scroll): ... this ... + (scroll_up): ... and this. + (real_scroll): Handle multi-line scroll and draw below-the-bottom + characters. + (grub_gfxterm_refresh): Call real_scroll. + +2010-02-06 Colin D Bennett + + * include/grub/misc.h (grub_iscntrl): New inline function. + (grub_isalnum): Likewise. + (grub_strtol): Likewise. + +2010-02-06 Colin D Bennett + + * normal/menu_text.c (get_entry_number): Move from here ... + * normal/menu.c (get_entry_number): ... moved here. + * include/grub/menu.h (grub_menu_get_default_entry_index): + New prototype. + * normal/menu.c (grub_menu_get_default_entry_index): New function. + * normal/menu_text.c (run_menu): Use grub_menu_get_default_entry_index. + * include/grub/menu_viewer.h (grub_menu_viewer_init): New prototype. + (grub_menu_viewer_should_return): Likewise. + * normal/main.c (GRUB_MOD_INIT (normal)): Call grub_menu_viewer_init. + * normal/menu_text.c (run_menu): Enable menu switching. + * normal/menu_viewer.c (should_return): New variable. + (menu_viewer_changed): Likewise. + (grub_menu_viewer_show_menu): Handle menu viewer changes. + (grub_menu_viewer_should_return): New function. + (menuviewer_write_hook): Likewise. + (grub_menu_viewer_init): Likewise. + +2010-02-06 Colin D Bennet +2010-02-06 Vladimir Serbinenko + + Support for gfxterm in a window. + + * include/grub/gfxterm.h: New file. + * include/grub/video.h (struct grub_video_rect): New declaration. + (grub_video_rect_t): Likewise. + * term/gfxterm.c (struct grub_gfxterm_window): New type. + (refcount): New variable. + (render_target): Likewise. + (window): Likewise. + (repaint_callback): Likewise. + (grub_virtual_screen_setup): Use 'render_target'. + (init_window): New function. + (grub_gfxterm_init_window): Likewise. + (grub_gfxterm_init): Check reference counter. + Use init_window. + (destroy_window): New function. + (grub_gfxterm_destroy_window): Likewise. + (grub_gfxterm_fini): Check reference counter. + Use destroy_window. + (redraw_screen_rect): Restore viewport. + Use 'render_target' and 'window'. + Call 'repaint_callback'. + (write_char): Use 'render_target'. + (draw_cursor): Likewise. + (scroll_up): Restore viewport. + Use 'render_target' and 'window'. + Call 'repaint_callback'. + (grub_gfxterm_cls): Likewise. + (grub_gfxterm_refresh): Use 'window'. + (grub_gfxterm_set_repaint_callback): New function. + (grub_gfxterm_background_image_cmd): Use 'window'. + (grub_gfxterm_get_term): New function. + (GRUB_MOD_INIT(term_gfxterm)): Set 'refcount' to 0. + +2010-02-06 Colin D Bennett + + Bitmap scaling support. + + * conf/common.rmk (pkglib_MODULES): Add bitmap_scale.mod. + (bitmap_scale_mod_SOURCES): New variable. + (bitmap_scale_mod_CFLAGS): Likewise. + (bitmap_scale_mod_LDFLAGS): Likewise. + * include/grub/bitmap_scale.h: New file. + * term/gfxterm.c (BACKGROUND_CMD_ARGINDEX_MODE): New definiton. + (background_image_cmd_options): New variable. + (grub_gfxterm_background_image_cmd): Support bitmap stretching. + (cmd): Rename and change type to ... + (background_image_cmd_handle): ... this. All users updated. + (GRUB_MOD_INIT(term_gfxterm)): Make background_image extended command. + * video/bitmap_scale.c: New file. + +2010-02-06 Vladimir Serbinenko + + SDL support. + + * Makefile.in (LIBSDL): New variable. + (enable_grub_emu_sdl): Likewise. + * conf/i386-pc.rmk (grub_emu_SOURCES): Add video files. + (grub_emu_SOURCES) [enable_grub_emu_sdl]: Add util/sdl.c. + (grub_emu_LDFLAGS) [enable_grub_emu_sdl]: Add $(LIBSDL). + * configure.ac: Detect SDL availability and add --enable-grub-emu-sdl + * util/sdl.c: New file. + +2010-02-06 Colin D Bennett +2010-02-06 Vladimir Serbinenko + + Double buffering support. + + * commands/i386/pc/videotest.c (grub_cmd_videotest): Swap doublebuffers. + * include/grub/video.h: Update comment. + * include/grub/video_fb.h (grub_video_fb_doublebuf_update_screen_t): + New type. + (grub_video_fb_doublebuf_blit_init): New prototype. + * term/gfxterm.c (scroll_up): Support double buffering. + (grub_gfxterm_refresh): Likewise. + * video/fb/video_fb.c (doublebuf_blit_update_screen): New function. + (grub_video_fb_doublebuf_blit_init): Likewise. + * video/i386/pc/vbe.c (framebuffer): Remove 'render_target'. Add + 'front_target', 'back_target', 'offscreen_buffer', 'page_size', + 'displayed_page', 'render_page' and 'update_screen'. + (grub_video_vbe_fini): Free offscreen buffer. + (doublebuf_pageflipping_commit): New function. + (doublebuf_pageflipping_update_screen): Likewise. + (doublebuf_pageflipping_init): Likewise. + (double_buffering_init): Likewise. + (grub_video_vbe_setup): Enable doublebuffering. + (grub_video_vbe_swap_buffers): Implement. + (grub_video_vbe_set_active_render_target): Handle double buffering. + (grub_video_vbe_get_active_render_target): Likewise. + (grub_video_vbe_get_info_and_fini): Likewise. Free offscreen_buffer. + (grub_video_vbe_adapter): Use grub_video_vbe_get_active_render_target. + (grub_video_vbe_enable_double_buffering): Likewise. + (grub_video_vbe_swap_buffers): Use update_screen. + (grub_video_set_mode): Use double buffering. + +2010-02-06 Robert Millan + + * maintainance/gentrigtables.py: Remove. + * lib/trig.c: Likewise. + + * gentrigtables.c: New file. C rewrite of gentrigtables.py. + + * conf/common.rmk (trig_mod_SOURCES): Replace `lib/trig.c' with + `trigtables.c'. + (trigtables.c): New rule. + (gentrigtables): Likewise. + (DISTCLEANFILES): Add `trigtables.c' and `gentrigtables'. + +2010-02-06 Robert Millan + + * maintainance/gentrigtables.py: Avoid duplicate hardcoding of + integer constants. + +2010-02-06 Colin D Bennet + + Trigonometry support. + + * include/grub/trig.h: New file. + * lib/trig.c: Likewise. + * maintainance/gentrigtables.py: Likewise. + * conf/common.rmk (pkglib_MODULES): Add trig.mod. + (trig_mod_SOURCES): New variable. + (trig_mod_CFLAGS): Likewise. + (trig_mod_LDFLAGS): Likewise. + +2010-02-06 Vladimir Serbinenko + + * kern/ieee1275/openfw.c (grub_ieee1275_encode_devname): Support whole + disk devices. + +2010-02-06 Vladimir Serbinenko + + * kern/ieee1275/openfw.c (grub_devalias_iterate): Stop iterating on + error. + +2010-02-03 Vladimir Serbinenko + + * util/hostdisk.c (open_device): Don't use partition device when reading + before the partition. + (grub_util_biosdisk_read): Don't read from partition and before the + partition in single operation. + (grub_util_biosdisk_write): Don't write to partition and before the + partition in single operation. + +2010-02-03 Torsten Landschoff + + * kern/disk.c (grub_disk_read): Fix offset computation when reading + last sectors. + +2010-02-03 Vladimir Serbinenko + + * disk/i386/pc/biosdisk.c (grub_biosdisk_read): Handle non-2048 aligned + CDROM reads. + (grub_biosdisk_write): Refuse to write to CDROM. + +2010-01-31 Vladimir Serbinenko + + * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Fix off-by-one error. + +2010-01-31 Vladimir Serbinenko + + * font/font.c (find_glyph): Check that bmp_idx is available before + using it. + (grub_font_get_string_width): Never call grub_font_get_glyph_internal + with (font == NULL). + +2010-01-28 Christian Schmitt + + * util/ieee1275/grub-install.in: Fix nvsetenv arguments. + +2010-01-28 BVK Chaitanya + + * include/grub/script_sh.h (sourcecode): Add const qualifier. + * util/grub-script-check.c (getline): Fix empty lines case. + +2010-01-28 Robert Millan + + * Makefile.in (check): Exit with fail status when one of the tests + fails. + * tests/example_functional_test.c (example_test): Fix reversed assert. + * tests/example_unit_test.c (example_test): Likewise. + +2010-01-28 Colin Watson + + * util/grub.d/10_linux.in: This script does not use any of the + contents of gettext.sh, only the external command `gettext', so stop + sourcing it. (Moreover, gettext.sh isn't necessarily installed in + the same prefix as GRUB.) + * util/grub.d/10_kfreebsd.in: Likewise. + +2010-01-27 Vladimir Serbinenko + + * normal/cmdline.c (grub_cmdline_get): Fix completion in the middle + of the line. + +2010-01-27 Vladimir Serbinenko + + * kern/disk.c (grub_disk_read): Fix offset computation when reading + last sectors. + +2010-01-27 Vladimir Serbinenko + + * commands/hashsum.c (hash_file): Avoid possible stack overflow by + having a 4KiB and not 32KiB buffer size. + +2010-01-27 Robert Millan + + * util/hostfs.c: Include `'. + (grub_hostfs_read): Handle errors from fseeko() and fread(). + +2010-01-27 Robert Millan + + * kern/disk.c (grub_disk_read): Fix bug that would cause infinite + loop when using read hooks on files whose size isn't sector-aligned. + +2010-01-27 Robert Millan + + Remove unused parameter. + + * fs/iso9660.c (struct grub_iso9660_data): Remove `length' parameter. + (grub_iso9660_open): Remove initialization of `data->length'. + +2010-01-27 Robert Millan + + * util/grub-fstest.c (fstest): Rewrite allocation, fixing a few + memleak conditions. + +2010-01-27 Carles Pina i Estany + + * util/lvm.c: New macro LVM_DEV_MAPPER_STRING. + (grub_util_lvm_isvolume): Use LVM_DEV_MAPPER_STRING. + +2010-01-26 Carles Pina i Estany + + * util/bin2h.c (usage): Fix warning (space after backslash). + +2010-01-26 Carles Pina i Estany + + * font/font.c: Include `grub/fontformat.h. + Remove font file format constants. + (grub_font_load): Use the new macros. + * include/grub/fontformat.h: New file. + * util/grub-mkfont.c: Include `grub/fontformat.c'. + (write_font_pf2): Use the new macros. + +2010-01-26 Robert Millan + + * util/bin2h.c (usage): Make --help actually explain what `grub-bin2h' + does. + +2010-01-26 Robert Millan + + * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_PXE_DL): New macro. + + * boot/i386/pc/pxeboot.S: Include `'. + (_start): Macroify `0x7F'. + + * kern/i386/pc/init.c: Include `'. + (make_install_device): Use "(pxe)" as fallback prefix when booting + via PXE. + +2010-01-26 Vladimir Serbinenko + + * configure.ac: Reset LIBS after check for libgcc symbols. + +2010-01-25 Colin Watson + + * util/hostdisk.c (open_device): Add trailing newline to debug + message. + +2010-01-25 GrĂ©goire Sutre + + * configure.ac: Check for `limits.h'. + * util/misc.c: Include `' (for PATH_MAX). + +2010-01-24 Robert Millan + + * loader/mips/linux.c (grub_cmd_linux, grub_cmd_initrd): Don't + capitalize error strings. + +2010-01-24 Samuel Thibault + + * util/grub.d/10_hurd.in: Add a recovery mode. + +2010-01-23 Vladimir Serbinenko + + * configure.ac: Check for libgcc symbols with -nostdlib. + +2010-01-23 BVK Chaitanya + + * acinclude.m4: Quote underquoted AC_DEFUN parameters. + +2010-01-22 Vladimir Serbinenko + + * term/ieee1275/ofconsole.c (grub_ofconsole_setcolorstate): Allocate on + stack since heap may be unavailable at that point. + (grub_ofconsole_gotoxy): Likewise. + +2010-01-22 Vladimir Serbinenko + + * configure.ac: Check for _restgpr_14_x. + * include/grub/powerpc/libgcc.h [HAVE__RESTGPR_14_X]: Add _restgpr_*_x + and _savegpr_* prototypes. + +2010-01-22 Robert Millan + + Use generic grub_reboot() for i386-efi. + + * kern/efi/efi.c [__i386__] (grub_reboot): Remove. + * kern/i386/efi/startup.S: Include `"../realmode.S"'. + * kern/i386/realmode.S: Include `'. + +2010-01-22 Vladimir Serbinenko + + * kern/ieee1275/init.c (grub_machine_set_prefix): Don't check for + presence of "prefix" variable as it breaks when normal.mod is + embedded. + +2010-01-21 Vladimir Serbinenko + + * term/ieee1275/ofconsole.c (grub_ofconsole_dimensions): Allocate on + stack since heap is unavailable at that point. + +2010-01-21 Vladimir Serbinenko + + * include/grub/i386/bsd.h (FREEBSD_N_BIOS_GEOM): Removed. + (grub_freebsd_bootinfo): Rewritten. + * loader/i386/bsd.c (grub_freebsd_boot): Use new grub_freebsd_bootinfo. + +2010-01-21 Vladimir Serbinenko + + * util/misc.c (make_system_path_relative_to_its_root): Fix typo. + +2010-01-21 Robert Millan + + * po/POTFILES: Remove mkisofs-related files. They have their own TLP + domain now. + +2010-01-20 Felix Zielcke + + * util/misc.c (make_system_path_relative_to_its_root): Change the work + around for handling "/" to the correct fix. Fix a memory leak. Use + xstrdup instead of strdup. + +2010-01-20 Vladimir Serbinenko + + * conf/mips.rmk (kernel_img_HEADERS): Add env_private.h + +2010-01-20 Vladimir Serbinenko + + Optimise glyph lookup by Basic Multilingual Plane lookup array. + + * font/font.c (struct grub_font): New member 'bmp_idx'. + (font_init): Initialise 'bmp_idx'. + (load_font_index): Fill 'bmp_idx'. + (find_glyph): Make inline. Use bmp_idx for BMP characters. + +2010-01-20 Vladimir Serbinenko + + * video/fb/video_fb.c (grub_video_fb_scroll): Optimise by avoiding + unnecessary calls. + +2010-01-20 Vladimir Serbinenko + + Move context handling out of the kernel. + + * conf/any-emu.rmk (grub_emu_SOURCES): Add normal/context.c. + * conf/common.rmk (normal_mod_SOURCES): Add normal/context.c. + * conf/i386-coreboot.rmk (kernel_img_HEADERS): Add env_private.h. + * conf/i386-efi.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * include/grub/env.h: Include grub/menu.h. + (grub_env_var_type): Removed. + (grub_env_var): Replaced field 'type' with 'global'. + (grub_env_find): New prototype. + (grub_env_context_open): Remove EXPORT_FUNC. + (grub_env_context_close): Likewise. + (grub_env_export): Likewise. + (grub_env_set_data_slot): Removed. + (grub_env_get_data_slot): Likewise. + (grub_env_unset_data_slot): Likewise. + (grub_env_unset_menu): New prototype. + (grub_env_set_menu): Likewise. + (grub_env_get_menu): Likewise. + * include/grub/env_private.h: New file. + * include/grub/normal.h (grub_context_init): New prototype. + (grub_context_fini): Likewise. + * kern/corecmd.c (grub_core_cmd_export): Moved from here ... + * normal/context.c (grub_cmd_export): ... to here. + * kern/env.c: Include env_private.h. + (HASHSZ): Moved to include/grub/env_private.h. + (grub_env_context): Likewise. + (grub_env_sorted_var): Likewise. + (current_context): Renamed from this ... + (grub_current_context): ...to this. 'static' removed. All users updated. + (grub_env_find): Removed 'static'. + (grub_env_context_open): Moved to normal/context.c. + (grub_env_context_close): Likewise. + (grub_env_export): Likewise. + (mangle_data_slot_name): Removed. + (grub_env_set_data_slot): Likewise. + (grub_env_get_data_slot): Likewise. + (grub_env_unset_data_slot): Likewise. + * kern/main.c (grub_set_root_dev): Don't export root. + It will be done later. + (grub_main): Don't export prefix. + It will be done later. + * normal/context.c: New file. + * normal/main.c (free_menu): Use grub_env_unset_menu. + (grub_normal_add_menu_entry): Use grub_env_get_menu. + (read_config_file): Use grub_env_get_menu and grub_env_set_menu. + (GRUB_MOD_INIT(normal)): Call grub_context_init. + (GRUB_MOD_FINI(normal)): Call grub_context_fini. + +2010-01-20 Vladimir Serbinenko + + setpci support. + + * commands/setpci.c: New file. + * conf/i386.rmk (pkglib_MODULES): Add setpci.mod. + (setpci_mod_SOURCES): New variable. + (setpci_mod_CFLAGS): Likewise. + (setpci_mod_LDFLAGS): Likewise. + +2010-01-20 Vladimir Serbinenko + + Byte-addressable PCI configuration space. + + * bus/pci.c (grub_pci_make_address): Use byte address instead of + dword address. + (grub_pci_iterate): Use macroses GRUB_PCI_REG_PCI_ID and + GRUB_PCI_REG_CACHELINE. + * bus/usb/ohci.c (grub_ohci_pci_iter): Use macroses + GRUB_PCI_REG_CLASS and GRUB_PCI_REG_ADDRESS_REG0. + * bus/usb/uhci.c (grub_ohci_pci_iter): Use macroses + GRUB_PCI_REG_CLASS and GRUB_PCI_REG_ADDRESS_REG4. + * commands/efi/fixvideo.c (scan_card): Use macros GRUB_PCI_REG_CLASS. + * commands/efi/loadbios.c (enable_rom_area): Pass byte-address to + grub_pci_make_address. + (lock_rom_area): Likewise. + * commands/lspci.c (grub_lspci_iter): Use macroses + GRUB_PCI_REG_CLASS and GRUB_PCI_REG_ADDRESSES. Handle byte-addressing + of grub_pci_make_address. + * disk/ata.c (grub_ata_pciinit): Likewise. + * include/grub/pci.h (GRUB_PCI_REG_PCI_ID): New macro. + (GRUB_PCI_REG_VENDOR): Likewise. + (GRUB_PCI_REG_DEVICE): Likewise. + (GRUB_PCI_REG_COMMAND): Likewise. + (GRUB_PCI_REG_STATUS): Likewise. + (GRUB_PCI_REG_REVISION): Likewise. + (GRUB_PCI_REG_CLASS): Likewise. + (GRUB_PCI_REG_CACHELINE): Likewise. + (GRUB_PCI_REG_LAT_TIMER): Likewise. + (GRUB_PCI_REG_HEADER_TYPE): Likewise. + (GRUB_PCI_REG_BIST): Likewise. + (GRUB_PCI_REG_ADDRESSES): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_CIS_POINTER): Likewise. + (GRUB_PCI_REG_SUBVENDOR): Likewise. + (GRUB_PCI_REG_SUBSYSTEM): Likewise. + (GRUB_PCI_REG_ROM_ADDRESS): Likewise. + (GRUB_PCI_REG_CAP_POINTER): Likewise. + (GRUB_PCI_REG_IRQ_LINE): Likewise. + (GRUB_PCI_REG_IRQ_PIN): Likewise. + (GRUB_PCI_REG_MIN_GNT): Likewise. + (GRUB_PCI_REG_MAX_LAT): Likewise. + * loader/i386/efi/linux.c (find_framebuf): Use GRUB_PCI_REG_CLASS. + * loader/i386/efi/xnu.c (find_framebuf): Likewise. + * video/efi_uga.c (find_framebuf): Likewise. + * video/sm712.c (grub_video_sm712_setup): Likewise. + * util/pci.c (grub_pci_make_address): Use byte-addressed configuration + space. + +2010-01-20 Robert Millan + + * util/grub.d/10_linux.in (linux_entry): Set gfxpayload=keep when it + can be reliably determined to be supported. + +2010-01-20 Robert Millan + + * loader/i386/linux.c (grub_cmd_linux): If `vga=' was used, write down + that VESA is supported. + (grub_linux_boot): Use generic framebuffer unless VESA is known to be + supported. + +2010-01-20 Vladimir Serbinenko + + * conf/common.rmk (font/font.c_DEPENDENCIES): Condition on FONT_SOURCE. + +2010-01-20 Robert Millan + + * util/misc.c (make_system_path_relative_to_its_root): Work around + special-casing of "/", as previous incarnation of this routine did. + +2010-01-20 Vladimir Serbinenko + + Fix any-emu compilation. + + * conf/any-emu.rmk (bin_UTILITIES): Add grub-bin2h. + * grub_bin2h_SOURCES: New variable. + +2010-01-20 Robert Millan + + * util/grub.d/00_header.in: Fix stupid mistake from last commit. + +2010-01-20 Robert Millan + + * util/grub.d/00_header.in: Fix handling of locale_dir. + +2010-01-20 Vladimir Serbinenko + + * configure.ac: Add /usr/share/fonts/unifont/unifont.pcf.gz + as possible unifont location (Gentoo). + Reported by: Alexander BrĂ¼ning + +2010-01-20 Vladimir Serbinenko + + Don't try to generate lists for kernel.img. + + * conf/i386-efi.rmk (pkglib_PROGRAMS): New variable. + (pkglib_MODULES): Remove kernel.img. + (kernel_img_EXPORTS): Removed. + (kernel_img_RELOCATABLE): New variable. + * conf/x86_64-efi.rmk: Likewise. + * genmk.rb: Remove *_EXPORTS support and add *_RELOCATABLE support. + +2010-01-20 Vladimir Serbinenko + + * include/grub/misc.h (grub_sprintf): Removed. All users switched to + grub_xasprintf or grub_snprintf. + (grub_vsprintf): Likewise. + (grub_snprintf): New proto. + (grub_vsnprintf): Likewise. + (grub_xasprintf): Likewise. + (grub_xvasprintf): Likewise. + * kern/misc.c (grub_vprintf): Use grub_vsnprintf_real. + (grub_sprintf): Removed. + (grub_vsnprintf): New function. + (grub_snprintf): Likewise. + (grub_xvasprintf): Likewise. + (grub_xasprintf): Likewise. + (grub_vsprintf): Renamed to ... + (grub_vsnprintf_real): ...this. New argument max_len. + +2010-01-20 BVK Chaitanya + + * include/grub/script_sh.h (sourcecode): Remove const qualifier to + fix grub-script-check warning. + +2010-01-20 Vladimir Serbinenko + + * include/grub/font.h (grub_font_load): Fix prototype. + +2010-01-20 Vladimir Serbinenko + + * conf/mips.rmk (kernel_img_HEADERS) [yeeloong]: Add pci.h. + +2010-01-20 Vladimir Serbinenko + + * include/grub/x86_64/at_keyboard.h: New file. + +2010-01-20 Vladimir Serbinenko + + * loader/mips/linux.c: Include missing grub/i18n.h. + +2009-12-20 Robert Millan + + * normal/menu.c (notify_execution_failure): Clarify error message. + +2009-12-20 Robert Millan + + * commands/loadenv.c (check_blocklists): Use `grub_err_t' as + return value (and revert all return statements). Update users. + +2010-01-20 Dan Merillat + + * kern/device.c (grub_device_iterate): Allocate new part_ent + structure based on sizeof (*p) rather than sizeof (p->next), to + account for structure padding. + + * util/grub-probe.c (probe_raid_level): Return -1 immediately if + disk is NULL, which might happen for LVM physical volumes with no + LVM signature. + +2009-12-20 Robert Millan + + * loader/mips/linux.c (grub_cmd_initrd) + (GRUB_MOD_INIT(linux)): Adjust and gettextize a few strings. + +2009-12-20 Robert Millan + + * kern/mips/yeeloong/init.c (grub_video_sm712_init) + (grub_video_video_init, grub_video_bitmap_init) + (grub_font_manager_init, grub_term_gfxterm_init) + (grub_at_keyboard_init): New extern declarations. + (grub_machine_init): Initialize gfxterm and at_keyboard. + + * kern/main.c (grub_main): Revert grub_printf delay kludge. + + * util/grub-install.in: Revert embed of `at_keyboard.mod' and + `gfxterm.mod' into core image. + + * conf/mips.rmk (pkglib_IMAGES, kernel_img_SOURCES) + (kernel_img_CFLAGS, kernel_img_ASFLAGS, kernel_img_LDFLAGS) + (kernel_img_FORMAT): Copy to ... + + * conf/mips-qemu-mips.rmk (pkglib_IMAGES, kernel_img_SOURCES) + (kernel_img_CFLAGS, kernel_img_ASFLAGS, kernel_img_LDFLAGS) + (kernel_img_FORMAT): ... here, and ... + + * conf/mips-yeeloong.rmk (pkglib_IMAGES, kernel_img_SOURCES) + (kernel_img_CFLAGS, kernel_img_ASFLAGS, kernel_img_LDFLAGS) + (kernel_img_FORMAT): ... here. + + (kernel_img_SOURCES): Add files necessary for output (gfxterm) + and input (at_keyboard) terminals in kernel. + (kernel_img_CFLAGS): Add `-DUSE_ASCII_FAILBACK'. + + (pkglib_MODULES): Remove `pci.mod'. + (pci_mod_SOURCES, pci_mod_CFLAGS, pci_mod_LDFLAGS) + (sm712_mod_SOURCES, sm712_mod_CFLAGS, sm712_mod_LDFLAGS) + (at_keyboard_mod_SOURCES, at_keyboard_mod_CFLAGS) + (at_keyboard_mod_LDFLAGS): Remove variables. + +2010-01-11 Felix Zielcke + + * po/POTFILES: Replace `term/i386/pc/serial.c' with `term/serial.c'. + +2009-12-10 Robert Millan + + * include/grub/mips/libgcc.h: Only export symbols for functions + that libgcc provides. + +2009-12-02 Vladimir Serbinenko + + MIPS support. + + * bus/bonito.c: New file. + * bus/pci.c (grub_pci_iterate): Use GRUB_PCI_NUM_BUS and + GRUB_PCI_NUM_DEVICES. + * term/i386/pc/serial.c: Move to ... + * term/serial.c: ... here. All users updated. + * util/i386/pc/grub-mkimage.c: Move to ... + * util/grub-mkrawimage.c: ... here. All users updated. + * term/i386/pc/at_keyboard.c: Move to ... + * term/at_keyboard.c: ... here. All users updated. + * conf/mips-qemu-mips.rmk: New file. + * conf/mips-yeeloong.rmk: Likewise. + * conf/mips.rmk: Likewise. + * configure.ac: New platforms mipsel-yeeloong, mips-qemu-mips and + mipsel-qemu-mips. + * disk/ata.c (grub_ata_device_initialize): Add GRUB_MACHINE_PCI_IO_BASE + to port addresses. + (grub_ata_pciinit): Support CS5536. + * font/font.c (grub_font_load): Use grub_file_t instead of filename. + * font/font_cmd.c (loadfont_command): Open file before passing it to + grub_font_load. + (pseudo_file_read): New function. + (pseudo_file_close): Likewise. + (pseudo_fs): New structure. + (load_font_module): New function. + (GRUB_MOD_INIT(font_manager)): Load embedded font. + * fs/cpio.c (grub_cpio_open): Handle partial matches correctly. + * genmk.rb: Strip .rel.dyn, .reginfo, .note and .comment. + * genmoddep.awk: Ignore __gnu_local_gp. It's defined by linker. + * include/grub/i386/at_keyboard.h: Split into ... + * include/grub/at_keyboard.h: ... this ... + * include/grub/i386/at_keyboard.h: ... and this. + * include/grub/dl.h (grub_arch_dl_init_linker) [_mips && !GRUB_UTIL]: + New prototype. + * include/grub/elfload.h (grub_elf32_size): New parameter. All users + updated. + (grub_elf64_size): Likewise. + * include/grub/font.h (grub_font_load): Use grub_file_t instead of + filename. + * include/grub/i386/io.h (grub_port_t): New type. All users updated. + * include/grub/i386/coreboot/serial.h: Rewritten. + * include/grub/i386/ieee1275/serial.h: Include + grub/i386/coreboot/serial.h instead of grub/i386/pc/serial.h. + * include/grub/i386/pc/serial.h: Moved from here ... + * include/grub/serial.h: ... to here. All users updated. + * include/grub/i386/pci.h (GRUB_MACHINE_PCI_IO_BASE): New definition. + (GRUB_PCI_NUM_BUS): Likewise. + (GRUB_PCI_NUM_DEVICES): Likewise. + (grub_pci_device_map_range): Add missing volatile keyword. + * include/grub/kernel.h (OBJ_TYPE_FONT): New enum value. + * include/grub/mips/at_keyboard.h: New file. + * include/grub/mips/cache.h: Likewise. + * include/grub/mips/io.h: Likewise. + * include/grub/mips/kernel.h: Likewise. + * include/grub/mips/libgcc.h: Likewise. + * include/grub/mips/pci.h: Likewise. + * include/grub/mips/qemu-mips/boot.h: Likewise. + * include/grub/mips/qemu-mips/kernel.h: Likewise. + * include/grub/mips/qemu-mips/loader.h: Likewise. + * include/grub/mips/qemu-mips/memory.h: Likewise. + * include/grub/mips/qemu-mips/serial.h: Likewise. + * include/grub/mips/qemu-mips/time.h: Likewise. + * include/grub/mips/relocator.h: Likewise. + * include/grub/mips/time.h: Likewise. + * include/grub/mips/types.h: Likewise. + * include/grub/mips/yeeloong/at_keyboard.h: Likewise. + * include/grub/mips/yeeloong/boot.h: Likewise. + * include/grub/mips/yeeloong/kernel.h: Likewise. + * include/grub/mips/yeeloong/loader.h: Likewise. + * include/grub/mips/yeeloong/memory.h: Likewise. + * include/grub/mips/yeeloong/pci.h: Likewise. + * include/grub/mips/yeeloong/serial.h: Likewise. + * include/grub/mips/yeeloong/time.h: Likewise. + * kern/dl.c (grub_dl_resolve_symbols): Handle STT_OBJECT correctly. + * kern/elf.c (grub_elf32_size): New parameter. All users + updated. + (grub_elf64_size): Likewise. + * kern/main.c (grub_main): Call grub_arch_dl_init_linker if necessary. + Load modules before saying "Welcome to GRUB!". + Call grub_refresh after saying "Welcome to GRUB!". + * kern/mips/cache.S: New file. + * kern/mips/cache_flush.S: Likewise. + * kern/mips/dl.c: Likewise. + * kern/mips/init.c: Likewise. + * kern/mips/qemu-mips/init.c: Likewise. + * kern/mips/startup.S: Likewise. + * kern/mips/yeeloong/init.c: Likewise. + * kern/term.c (grub_putcode): Handle NULL terminal. + (grub_getcharwidth): Likewise. + (grub_getkey): Likewise. + (grub_checkkey): Likewise. + (grub_getkeystatus): Likewise. + (grub_getxy): Likewise. + (grub_getwh): Likewise. + (grub_gotoxy): Likewise. + (grub_cls): Likewise. + (grub_setcolorstate): Likewise. + (grub_setcolor): Likewise. + (grub_getcolor): Likewise. + (grub_refresh): Likewise. + * lib/mips/relocator.c (JUMP_SIZEOF): Fix incorrect value. + (write_jump): Add hatch nop. + * lib/mips/relocator_asm.S: Use kern/mips/cache_flush.S. + * lib/mips/setjmp.S: New file. + * loader/mips/linux.c: Likewise. + * term/i386/pc/at_keyboard.c: Move from here ... + * term/at_keyboard.c: ... to here. + * term/i386/pc/serial.c: Moved from here ... + * term/serial.c: ... to here. All users updated. + (TEXT_HEIGHT): Set to 24 to fit linux terminal. + (serial_hw_io_addr): Use GRUB_MACHINE_SERIAL_PORTS. + (serial_translate_key_sequence): Avoid deadlock. + (grub_serial_getkey): Handle backspace. + (grub_serial_putchar): Fix newline handling. + * util/i386/pc/grub-mkimage.c: Move from here ... + * util/grub-mkrawimage.c: ... to here. All users updated. + (generate_image): New parameters 'font_path' and 'format'. + Support embedding font. + Use grub_host_to_target* instead of grub_cpu_to_le*. + (generate_image) [GRUB_MACHINE_MIPS]: Support ELF encapsulation. + (options) [GRUB_PLATFORM_IMAGE_DEFAULT]: New option "--format". + (options): New option "--font". + (usage): Likewise. + (main) [GRUB_PLATFORM_IMAGE_DEFAULT]: Handle "--format". + (main): Handle "--font". + * term/gfxterm.c (grub_virtual_screen): New member bg_color_display. + (grub_virtual_screen_setup): Set bg_color_display. + (redraw_screen_rect): Use bg_color_display instead of incorrect + bg_color. + (grub_gfxterm_cls): Likewise. + * util/elf/grub-mkimage.c (load_modules): New parameter 'config_path'. + Support embedding config file. + (add_segments): Likewise. + (options): New option "--config". + (main): Handle "--config". + * video/sm712.c: New file. + +2010-01-18 Robert Millan + + Fix parallel builds. + + * conf/common.rmk (font/font.c_DEPENDENCIES): New variable (makes + font.c depend on ascii.h). + +2010-01-12 Carles Pina i Estany + + * Makefile.in (DUSE_ASCII_FAILBACK): New macro. + +2010-01-11 Carles Pina i Estany + + * font/font.c (GENERATE_ASCII): Change the name to USE_ASCII_FAILBACK. + By default: disabled. + * Makefile.in (ascii.h): Remove the non-needed grub/bin2h size + parameter. + +2010-01-10 Carles Pina i Estany + + * font/font.c: Update copyright years. + * util/grub-mkfont.c (write_font_ascii_bitmap): Change comment format. + +2010-01-10 Carles Pina i Estany + + * font/font.c: Include `ascii.h'. + (ASCII_BITMAP_SIZE): New macro. + (ascii_font_glyph): Define. + (ascii_glyph_lookup): New function. + (grub_font_get_string_width): Change comment. If glyph not found, use + ascii_glyph_lookup. + (grub_font_get_glyph_with_fallback): If glyph not available returns + ascii_glyph_lookup. + * util/grub-mkfont.c (file_formats): New enum. + (options): Add `ascii-bitmaps' new option. + (usage): Add `asii-bitmaps' new option. + (write_font_ascii_bitmap): New function. + (write_font): Rename to ... + (write_font_p2): ... this. Remove print_glyphs call. + (main): Use file_format. Implement code for ranges if ascii-bitmaps is + used. Call print_glyphs. + * Makefile.in (pkgdata_DATA): Add `ascii.h'. + +2010-01-14 Robert Millan + + * conf/common.rmk (bin_UTILITIES): Add `grub-bin2h'. + (grub_bin2h_SOURCES): New variable. + * util/bin2h.c: New file. + +2010-01-20 Vladimir Serbinenko + + * include/multiboot.h: Resynced with spec. + * include/multiboot2.h: Likewise. + * loader/i386/multiboot_mbi.c (grub_fill_multiboot_mmap): Handle + GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE and GRUB_MACHINE_MEMORY_NVS. + +2010-01-18 Robert Millan + + * include/grub/term.h (grub_term_register_input, + grub_term_register_output): Check return of terminal init() + routines, and abort if errors are raised. + + * commands/terminal.c: Update copyright year. + +2010-01-18 Robert Millan + + * commands/terminal.c (grub_cmd_terminal_input) + (grub_cmd_terminal_output): Check return of terminal init() + routines, and abort if errors are raised. + +2010-01-18 Vladimir Serbinenko + + * include/grub/i386/bsd.h: Fix include pathes. + +2010-01-18 Vladimir Serbinenko + + Add missing *BSD copyright headers. + + * include/grub/aout.h: Add BSD licence. + * include/grub/i386/bsd.h: Parts under different licences moved to ... + * include/grub/i386/freebsd_linker.h: ... here, + * include/grub/i386/freebsd_reboot.h: ... here, + * include/grub/i386/netbsd_bootinfo.h: ... here, + * include/grub/i386/netbsd_reboot.h: ... here, + * include/grub/i386/openbsd_bootarg.h: ... here, + * include/grub/i386/openbsd_reboot.h: ... and here. Added appropriate + licence to each file. + +2010-01-18 Robert Millan + + * acinclude.m4: Remove `nop' assembly instruction; it's not + implemented by all architectures. + +2010-01-18 Robert Millan + + * loader/i386/efi/linux.c (grub_cmd_linux): Stop pretending we're + ELILO. This is no longer necessary. + +2010-01-18 BVK Chaitanya + + Added new tool, grub-scrit-check to verify grub.cfg syntax. + + * util/grub-script-check.c: grub-script-check tool. + * conf/common.rmk: Make rules for grub-script-check. + +2010-01-18 Robert Millan + + Fix annoying UI bug in rescue mode. Thanks to Tristan Gingold for + spotting it back in 2008. Shame on me for forgetting he did. + + * kern/rescue_reader.c (grub_rescue_run): Skip zero-length lines. + +2010-01-18 Robert Millan + + * include/grub/i386/linux.h (GRUB_VIDEO_TYPE_TEXT): Rename to ... + (GRUB_VIDEO_LINUX_TYPE_TEXT): ... this. Update all users. + (GRUB_VIDEO_TYPE_VLFB): Rename to ... + (GRUB_VIDEO_LINUX_TYPE_VESA): ... this. Update all users. + (GRUB_VIDEO_TYPE_EFI): Rename to ... + (GRUB_VIDEO_LINUX_TYPE_SIMPLE): ... this. Update all users. + +2010-01-17 Robert Millan + + * include/grub/test.h: Add license header. + * tests/example_functional_test.c: Likewise. + * tests/example_unit_test.c: Likewise. + * tests/lib/functional_test.c: Likewise. + * tests/lib/test.c: Likewise. + * tests/lib/unit_test.c: Likewise. + +2010-01-17 Vladimir Serbinenko + + Use flag-based instead of hook-based video mode selection and "auto" + keyword. + + * include/grub/video.h (grub_video_adapter): Changed 'setup' member. + (grub_video_set_mode): Changed prototype. All users updated. + (grub_video_check_mode_flag): New inline function. + * video/video.c (parse_modespec): New function. + (grub_video_set_mode): Parse flags and keywords. + +2010-01-17 Carles Pina i Estany + + * util/misc.c (grub_util_info): Fix the order of the parameters in a + fprintf call. + +2010-01-16 GrĂ©goire Sutre + + * genmk.rb (class SCRIPT): Replace option -i of sed by a pipe. + +2010-01-16 Carles Pina i Estany + + * util/grub-editenv.c (usage): Use `program_name' instead of hardcoded + string. + * util/grub-emu.c (usage): Likewise. + * util/grub-mkpasswd-pbkdf2.c (usage): Likewise. + * util/i386/efi/grub-mkimage.c (usage): Likewise. + * util/i386/pc/grub-mkimage.c (usage): Likewise. + * util/i386/pc/grub-setup.c (usage): Likewise. + +2010-01-16 Carles Pina i Estany + + * util/misc.c (grub_util_warn): Gettextizze, print full stop after + the message. + (grub_util_info): Likewise. + (grub_util_error): Likewise. + * util/elf/grub-mkimage.c: Fix capitalisation, quotes, full stops + and/or new lines in `grub_util_warna', `grub_util_info', + `grub_util_error' calls. + * util/getroot.c: Likewise. + * util/grub-editenv.c: Likewise. + * util/grub-emu.c: Likewise. + * util/grub-fstest.c: Likewise. + * util/grub-mkdevicemap.c: Likewise. + * util/grub-mkfont.c: Likewise. + * util/grub-mkpasswd-pbkdf2.c: Likewise. + * util/grub-mkrelpath.c: Likewise. + * util/grub-pe2elf.c: Likewise. + * util/grub-probe.c: Likewise. + * util/hostdisk.c: Likewise. + * util/i386/efi/grub-mkimage.c: Likewise. + * util/i386/pc/grub-mkimage.c: Likewise. + * util/i386/pc/grub-setup.c: Likewise. + * util/ieee1275/ofpath.c: Likewise. + * util/mkisofs/eltorito.c: Likewise. + * util/mkisofs/rock.c: Likewise. + * util/mkisofs/write.c: Likewise. + * util/raid.c: Likewise. + * util/sparc64/ieee1275/grub-mkimage.c: Likewise. + * util/sparc64/ieee1275/grub-setup.c: Likewise. + +2010-01-15 Vladimir Serbinenko + + Enable multiboot on non-pc. + + * conf/i386-coreboot.rmk, conf/i386-pc.rmk (pkglib_MODULES): Move + multiboot.mod and multiboot2.mod to ... + * conf/i386.rmk (pkglib_MODULES): ... here. + * conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_SOURCES): + Moved to ... + * conf/i386.rmk (multiboot_mod_SOURCES): .. here. + * conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_CFLAGS): + Moved to ... + * conf/i386.rmk (multiboot_mod_CFLAGS): .. here. + * conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_ASFLAGS): + Moved to ... + * conf/i386.rmk (multiboot_mod_ASFLAGS): .. here. + * conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_LDFLAGS): + Moved to ... + * conf/i386.rmk (multiboot_mod_LDFLAGS): .. here. + * conf/x86_64-efi.rmk (pkglib_MODULES): Remove ata.mod and + relocator.mod. + (ata_mod_SOURCES): Removed. + (ata_mod_CFLAGS): Likewise. + (ata_mod_LDFLAGS): Likewise. + (relocator_mod_SOURCES): Removed. + (relocator_mod_CFLAGS): Likewise. + (relocator_mod_ASFLAGS): Likewise. + (relocator_mod_LDFLAGS): Likewise. + Include i386.mk. + * include/grub/x86_64/multiboot.h: New file. + * loader/i386/multiboot.c (grub_multiboot_boot) [GRUB_MACHINE_EFI]: + Terminate EFI. + +2010-01-15 Vladimir Serbinenko + + Video multiboot support. + + * include/grub/multiboot.h (grub_multiboot_set_accepts_video): + New prototype. + * include/multiboot.h: Resynced with multiboot specification. + * include/multiboot2.h: Likewise. + * loader/i386/multiboot.c (UNSUPPORTED_FLAGS): Support video flags. + (grub_multiboot): Parse MULTIBOOT_VIDEO_MODE fields. + * loader/i386/multiboot_mbi.c (DEFAULT_VIDEO_MODE): New constant. + (HAS_VGA_TEXT): Likewise. + (accepts_video): New variable. + (grub_multiboot_set_accepts_video): New function. + (grub_multiboot_get_mbi_size): Account for video structures. + (set_video_mode): New function. + (retrieve_video_parameters): Likewise. + (grub_multiboot_make_mbi): Fill video fields. + +2010-01-15 Vladimir Serbinenko + + Video driver ids. + + * include/grub/video.h (grub_video_driver_id): New type. + (grub_video_adapter): New member 'id'. All users updated. + (grub_video_get_driver_id): New proto. + * video/video.c (grub_video_get_driver_id): New function. + +2010-01-14 Carles Pina i Estany + + * util/grub.d/30_os-prober.in: Use `set var=val' rather than plain + `var=val'. + +2010-01-14 Carles Pina i Estany + + * normal/cmdline.c (print_completion): Gettextizze. + +2001-01-14 Carles Pina i Estany + + * loader/i386/pc/chainloader.c: Include `'. + +2010-01-14 Carles Pina i Estany + + * gettext/gettext.c (grub_gettext_translate): Push and pop + grub_errno. + (grub_gettext_delete_list): Change comment style. + * kern/err.c (grub_error): Gettextizze. + (grub_fatal): Gettextizze. + +2010-01-14 Robert Millan + + * include/grub/i386/loader.h (grub_linux16_boot): Renamed to ... + (grub_linux16_real_boot): ... this. + * kern/i386/loader.S: Likewise. + * loader/i386/pc/linux.c: Include `' and `'. + (grub_linux16_boot): New function. Switches to text mode and calls + grub_linux16_real_boot(). + + * loader/i386/bsd.c: Include `'. + (grub_freebsd_boot, grub_openbsd_boot, grub_netbsd_boot): Switch to + text mode before calling grub_unix_real_boot(). + + * loader/i386/multiboot.c: Include `'. + (grub_multiboot_boot): Switch to text mode before calling + grub_relocator32_boot(). + + * loader/i386/pc/chainloader.c: Include `'. + (grub_chainloader_boot): Switch to text mode before calling + grub_chainloader_real_boot(). + +2010-01-05 Jordan Uggla +2010-01-05 Colin Watson + + * util/grub-reboot.in: Make sure prev_saved_entry always gets a + non-empty value. + +2010-01-05 Jordan Uggla +2010-01-05 Colin Watson + + * util/grub.d/00_header.in: Define a "savedefault" function for use + in menu entries. + * util/grub-mkconfig_lib.in (save_default_entry): Use it. + +2010-01-05 Jordan Uggla +2010-01-05 Colin Watson + + * util/grub-mkconfig_lib.in (save_default_entry): Only set + saved_entry if boot_once is unset. + * util/grub.d/00_header.in: Set boot_once to "true" if there was a + previous saved entry (i.e. grub-reboot). + +2009-12-08 Colin Watson + + * util/grub.d/30_os-prober.in: Call save_default_entry for hurd. + +2009-12-08 Colin Watson + + * util/grub.d/00_header.in: Use `set var=val' rather than plain + `var=val'. + * util/grub-mkconfig_lib.in (save_default_entry): Likewise. + +2009-12-08 Colin Watson + + * util/grub-reboot.in: Fix --version output. + * util/grub-set-default.in: Likewise. + +2009-12-08 Colin Watson + + * util/grub.d/00_header.in: Silently ignore zero-sized environment + blocks. + +2009-12-08 Colin Watson + + * util/grub.d/00_header.in: Quote the value assigned to `default', + in case it contains spaces. + +2009-12-08 Colin Watson + + * util/grub.d/30_os-prober.in: Fix merge error that moved a + `save_default_entry' call from the macosx case to the linux case. + +2009-10-25 Vladimir Serbinenko +2009-10-25 Colin Watson + + * normal/menu.c (grub_menu_execute_entry): Save selected entry title + in `chosen' environment variable. + * normal/menu_text.c (get_entry_number): Check if the variable + matches the title of a menu entry. + (run_menu): Pass menu to get_entry_number. + + * util/grub-reboot.in: New file. + * util/grub-set-default.in: New file. + * conf/common.rmk (grub-reboot): New utility. + (grub-set-default): New utility. + + * util/grub-mkconfig_lib.in (save_default_entry): New function. + * util/grub.d/00_header.in: If GRUB_DEFAULT is `saved', set + default to `${saved_entry}'. If `${prev_saved_entry}' is non-empty, + move it to `saved_entry' for the next boot. Load environment on + initialisation. + * util/grub.d/10_kfreebsd.in: Call save_default_entry. + * util/grub.d/10_hurd.in: Likewise. + * util/grub.d/10_linux.in (linux_entry): Likewise. + * util/grub.d/10_windows.in: Likewise. + * util/grub.d/30_os-prober.in: Likewise. + + * util/grub-install.in: Create environment block. + * util/i386/efi/grub-install.in: Likewise. + * util/ieee1275/grub-install.in: Likewise. + * util/sparc64/ieee1275/grub-install.in: Likewise. + +2010-01-14 BVK Chaitanya + + Unit testing framework for GRUB. + + * Makefile.in: Test framework build rules for 'make check'. + * conf/tests.rmk: Build rules for individual tests and framework. + + * include/grub/test.h: Header file for whitebox tests. + * tests/lib/functional_test.c: Framework support for whitebox + functional tests. + * tests/lib/test.c: Common whitebox testing code for unit and + functional tests. + * tests/lib/unit_test.c: Framework support for whitebox unit + tests. + + * tests/util/grub-shell-tester.in: Support utility for grub-script + tests. + * tests/util/grub-shell.in: Utility to execute grub-script + commands in a Qemu instance. + + * tests/example_functional_test.c: Example whitebox functional + test. + * tests/example_grub_script_test.in: Example grub-script test. + * tests/example_scripted_test.in: Example scripted test. + * tests/example_unit_test.c: Example whitebox unit test. + +2010-01-14 Vladimir Serbinenko + + * conf/i386-coreboot.rmk (multiboot_mod_SOURCES): + Add loader/i386/multiboot_mbi.c. + (multiboot2_mod_SOURCES): Likewise. + * conf/i386-pc.rmk (multiboot_mod_SOURCES): Likewise. + (multiboot2_mod_SOURCES): Likewise. + * include/grub/multiboot.h (grub_multiboot_get_mbi_size): New proto. + (grub_multiboot_make_mbi): Likewise. + (grub_multiboot_free_mbi): Likewise. + (grub_multiboot_init_mbi): Likewise. + (grub_multiboot_add_module): Likewise. + (grub_multiboot_set_bootdev): Likewise. + * loader/i386/multiboot.c (mbi): Removed. + (mbi_dest): Likewise. + (alloc_mbi): New variable. + (grub_multiboot_payload_size): Removed. All users updated. + (grub_multiboot_pure_size): New variable. + (grub_multiboot_boot): Use grub_multiboot_make_mbi. + (grub_multiboot_unload): Use grub_multiboot_free_mbi. + (grub_get_multiboot_mmap_len): Moved to loader/i386/multiboot_mbi.c. + (grub_fill_multiboot_mmap): Likewise. + (grub_multiboot_get_bootdev): Likewise. + (grub_multiboot): Use multiboot_mbi functions. + * loader/i386/multiboot_mbi.c: New file. + +2010-01-13 Vladimir Serbinenko + + * kern/efi/init.c (grub_efi_fini): Don't call grub_efi_mm_fini as + it would result in module crash. + +2010-01-13 Vladimir Serbinenko + + * term/ieee1275/ofconsole.c (grub_ofconsole_putchar): Handle '\r'. + (grub_ofconsole_getwh): Split to ... + (grub_ofconsole_getwh): ... this. + (grub_ofconsole_dimensions): ...and this. + (grub_ofconsole_init_output): Call grub_ofconsole_dimensions. + +2010-01-13 Robert Millan + + * util/mkisofs/rock.c (generate_rock_ridge_attributes): Fix a typo. + +2010-01-12 Vladimir Serbinenko + + * loader/i386/pc/multiboot2.c: Removed stalled file. + +2010-01-12 Vladimir Serbinenko + + * util/grub-mkpasswd-pbkdf2.c (main): Use grub_util_init_nls. + Reported by: GrĂ©goire Sutre + +2010-01-11 Robert Millan + + * util/misc.c (canonicalize_file_name): New function. + (make_system_path_relative_to_its_root): Use canonicalize_file_name() + instead of realpath(). + +2010-01-11 Colin Watson + + * util/grub-install.in (usage): Clarify meaning of --root-directory, + and make it clearer that it's optional. Based on confusion + witnessed on IRC. + +2010-01-10 Vladimir Serbinenko + + * term/i386/pc/vga_text.c (inc_y): Fix off-by-one error which resulted + in premature implicit newline. + +2010-01-10 Vladimir Serbinenko + + * normal/cmdline.c (grub_cmdline_get): Fix off-by-one error + which resulted in garbled command line at the end of screen. + +2010-01-10 Robert Millan + + * loader/i386/ieee1275/linux.c (grub_linux_boot): Rework video position + initialization with similar approach as with other Linux loaders. + +2010-01-10 Robert Millan + + Fix i386-ieee1275 build. + + * loader/i386/ieee1275/linux.c (grub_linux_boot): Use grub_term_width() + and grub_term_height() for video_{width,height} initialization. + +2010-01-10 Robert Millan + + Fix grub-emu build. + + * conf/any-emu.rmk (grub_emu_SOURCES): Remove `kern/reader.c'. + +2010-01-07 Vladimir Serbinenko +2010-01-09 Robert Millan + + Support for multiple terminals. + + * Makefile.in (pkglib_DATA): terminal.lst. + (terminal.lst): New target. + * commands/handler.c (grub_cmd_handler): Don't handle terminals. + (GRUB_MOD_INIT(handler)): Likewise. + (GRUB_MOD_FINI(handler)): Likewise. + * commands/help.c (grub_cmd_help): Handle multiple terminals. + * commands/keystatus.c (grub_cmd_keystatus): Likewise. + * commands/sleep.c (do_print): Use grub_term_restore_pos. + (grub_cmd_sleep): Use grub_term_save_pos. + * commands/terminal.c: New file. + * conf/any-emu.rmk (grub_emu_SOURCES): Add normal/term.c + commands/terminal.c and lib/charset.c. + * conf/common.rmk (normal_mod_SOURCES): Add normal/term.c. + (pkglib_MODULES): Add terminal.mod. + (terminal_mod_SOURCES): New variable. + (terminal_mod_CFLAGS): Likewise. + (terminal_mod_LDFLAGS): Likewise. + * genhandlerlist.sh: Don't handle terminals. + * genmk.rb: Generate terminal-*.lst. + * genterminallist.sh: New file. + * include/grub/charset.h (grub_ucs4_to_utf8_alloc): New proto. + (grub_is_valid_utf8): Likewise. + (grub_utf8_to_ucs4_alloc): Likewise. + * include/grub/menu_viewer.h (grub_menu_viewer): Rewritten. + (grub_menu_register_viewer): Changed argument. + (grub_menu_try_text): New proto. + (grub_gfxmenu_try_hook): New declaration. + * include/grub/normal.h (grub_normal_exit_level): New declaration. + (grub_menu_init_page): Additional argument term. + (grub_normal_init_page): Likewise. + (grub_cmdline_get): Arguments simplified. + (grub_utf8_to_ucs4_alloc): Removed. + (grub_print_ucs4): Additional argument term. + (grub_getstringwidth): Likewise. + (grub_print_message_indented): Likewise. + (grub_menu_text_register_instances): New proto. + (grub_show_menu): Likewise. + (read_terminal_list): Likewise. + (grub_set_more): Likewise. + * include/grub/parser.h: Include handler.h. + * include/grub/reader.h: Rewritten. + * include/grub/term.h (GRUB_TERM_NEED_INIT): Removed. + (GRUB_TERM_WIDTH): Changed to function. + (GRUB_TERM_HEIGHT): Likewise. + (GRUB_TERM_BORDER_WIDTH): Likewise. + (GRUB_TERM_BORDER_HEIGHT): Likewise. + (GRUB_TERM_NUM_ENTRIES): Likewise. + (GRUB_TERM_ENTRY_WIDTH): Likewise. + (GRUB_TERM_CURSOR_X): Likewise. + (grub_term_input_class): Likewise. + (grub_term_output_class): Likewise. + (grub_term_outputs_disabled): New declaration. + (grub_term_inputs_disabled): Likewise. + (grub_term_outputs): Likewise. + (grub_term_inputs): Likewise. + (grub_term_register_input): Rewritten. + (grub_term_register_output): Likewise. + (grub_term_unregister_input): Likewise. + (grub_term_unregister_output): Likewise. + (FOR_ACTIVE_TERM_INPUTS): New macro. + (FOR_DISABLED_TERM_INPUTS): Likewise. + (FOR_ACTIVE_TERM_OUTPUTS): Likewise. + (FOR_DISABLED_TERM_OUTPUTS): Likewise. + * include/grub/terminfo.h: Add oterm argument to all protypes. + * kern/main.c (grub_main): Don't call grub_register_rescue_reader. + Use grub_rescue_run. + * kern/misc.c (grub_utf8_to_ucs4): Put '?' for invalid characters. + All users updated. + * kern/reader.c: Removed. All users updated. + * kern/rescue_reader.c (grub_rescue_init): Removed. + (grub_rescue_reader): Likewise. + (grub_register_rescue_reader): Likewise. + (grub_rescue_run): New function based on kern/reader.c. + * kern/term.c: Adapted for multiterm. + * lib/charset.c (grub_ucs4_to_utf8_alloc): New function. + (grub_is_valid_utf8): Likewise. + (grub_utf8_to_ucs4_alloc): Moved from normal/menu_text.c. + * loader/i386/efi/linux.c (grub_cmd_linux): Retrieve parameters of + right terminal. + * loader/i386/linux.c (grub_linux_boot): Likewise. + * normal/auth.c (grub_username_get): New function. + (grub_auth_check_authentication): Use grub_username_get. + * normal/cmdline.c: Changed to UCS4. Adapted for multiterm. + * normal/color.c: Adapt for multiterm. + * normal/main.c (read_config_file): Don't use grub_reader_loop. + (grub_normal_init_page): Additional argument term. + (read_lists): Call read_terminal_lists. + (grub_enter_normal_mode): Call grub_cmdline_run. + Handle grub_normal_exit_level. + (grub_cmd_normal): Make reentrant. + (grub_cmd_normal_exit): New function. + (grub_normal_reader_init): Additional argument nested. Handle multiterm. + * normal/menu.c: Adapt for multiterm. + * normal/menu_entry.c: Likewise. + * normal/menu_text.c: Likewise. + * normal/menu_viewer.c: Removed. All users updated. + * normal/term.c: New file. + * util/console.c: Change order of includes to workaround a bug in + ncurses headers. + * term/terminfo.c: New argument oterm on all exported functions. + All users updated. + * util/grub-editenv.c (grub_term_input_class): Removed. + (grub_term_output_class): Likewise. + +2010-01-09 Robert Millan + + Make loader output a bit more user-friendly. + + * util/grub.d/10_hurd.in: Print message indicating that GNU Mach + is being loaded. Likewise for the Hurd. + + * util/grub.d/10_kfreebsd.in (kfreebsd_entry): Print message indicating + that kernel of FreeBSD ${version} is being loaded. + + * loader/i386/linux.c (grub_cmd_linux): Move debug info to + grub_dprintf(). + (grub_cmd_initrd): Likewise. + * util/grub.d/10_linux.in (linux_entry): Print message indicating + that Linux ${version} is being loaded. Likewise for initrd. + +2010-01-09 Carles Pina i Estany + + * gettext/gettext.c (GRUB_MOD_INIT): Gettextizze. + +2010-01-08 Carles Pina i Estany + + * loader/efi/appleloader.c: Include `'. + (GRUB_MOD_INIT): Gettextizze. + * loader/efi/chainloader.c: Include `'. + (GRUB_MOD_INIT): Gettextizze. + * loader/i386/efi/linux.c: Include `'. + (grub_cmd_linux): Capitalise Linux. + (GRUB_MOD_INIT): Gettextizze. + * loader/i386/ieee1275/linux.c: Include `'. + (grub_cmd_linux): Capitalise Linux. + (GRUB_MOD_INIT): Gettextizze. + * loader/i386/linux.c: Include `'. + (grub_cmd_linux): Capitalise Linux. + (GRUB_MOD_INIT): Gettextizze. + * loader/i386/pc/chainloader.c: Include `'. + (GRUB_MOD_INIT): Gettextizze. + * loader/i386/pc/linux.c: Include `'. + (grub_cmd_linux): Capitalise Linux. + (GRUB_MOD_INIT): Gettextizze. + * loader/i386/xnu.c: Include `'. + (grub_cpu_xnu_init): Gettextizze. + * loader/multiboot_loader.c: Include `'. + (GRUB_MOD_INIT): Gettextizze. + * loader/powerpc/ieee1275/linux.c: Include `'. + (GRUB_MOD_INIT): Gettextizze. + * loader/sparc64/ieee1275/linux.c: Include `'. + (grub_linux_load64): Capitalise Linux. + (GRUB_MOD_INIT): Gettextizze. + * loader/xnu.c: Include `'. + (GRUB_MOD_INIT): Gettextizze. + * po/POTFILES: Add `loader/efi/appleloader.c', + `loader/efi/chainloader.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_loader.c', + `loader/powerpc/ieee1275/linux.c', `loader/sparc64/ieee1275/linux.c' + and `loader/xnu.c'. + +2010-01-08 Robert Millan + + * src/mkisofs.c: Remove `ifdef linux' portability kludge. + +2010-01-08 Robert Millan + + * util/mkisofs/defaults.h (APPID_DEFAULT): Redefine using PACKAGE_NAME. + (SYSTEM_ID_DEFAULT): Set to "GNU" unconditionally. + * util/mkisofs/mkisofs.c (main): Readjust --version output. + +2010-01-07 Robert Millan + + Reset Multiboot 2 support. New loader implements the draft in + /branches/multiboot2 and shares as much code as possible with the + production Multiboot 1 implementation. + + * loader/ieee1275/multiboot2.c: Remove file. Update all users. + * loader/multiboot2.c: Likewise. + * loader/i386/multiboot_helper.S: Likewise. + * include/multiboot2.h: Replace with latest version from the draft + in /branches/multiboot2. + + * conf/i386-coreboot.rmk (multiboot_mod_SOURCES): Remove + `loader/i386/multiboot_helper.S', `loader/i386/pc/multiboot2.c' + and `loader/multiboot2.c'. + (pkglib_MODULES): Add `multiboot2.mod'. + (multiboot2_mod_SOURCES): New variable. + (multiboot2_mod_LDFLAGS): Likewise. + (multiboot2_mod_CFLAGS): Likewise. Define `GRUB_USE_MULTIBOOT2'. + + * conf/i386-pc.rmk: Likewise. + + * conf/powerpc-ieee1275.rmk (pkglib_MODULES): Remove `multiboot.mod'. + (multiboot_mod_SOURCES): Remove variable. + (multiboot_mod_LDFLAGS): Likewise. + (multiboot_mod_CFLAGS): Likewise. + + * include/grub/multiboot.h [GRUB_USE_MULTIBOOT2]: Include + `' instead of `'. + [GRUB_USE_MULTIBOOT2] (MULTIBOOT_BOOTLOADER_MAGIC) + (MULTIBOOT_HEADER_MAGIC): New macros. + + * loader/multiboot_loader.c (module_version_status): Remove variable. + (find_multi_boot2_header): Remove function. + (grub_cmd_multiboot_loader): Remove Multiboot 2 / Multiboot 1 selection + logic. Always check for the Multiboot version we're compiling for. + (grub_cmd_module_loader): Likewise. + [GRUB_USE_MULTIBOOT2] (GRUB_MOD_INIT(multiboot)): Register `multiboot2' + command instead of `multiboot'. + +2010-01-07 Robert Millan + + * include/multiboot.h (MULTIBOOT_UNSUPPORTED): Moved from here ... + * loader/i386/multiboot.c (UNSUPPORTED_FLAGS): ... to here. Update + all users. + +2010-01-07 Robert Millan +2010-01-07 Vladimir Serbinenko + + Fix breakage introduced with previous commit. + + * normal/dyncmd.c (read_command_list): Avoid unregistering kernel + commands. + * normal/handler.c (read_handler_list): Revert part of previous commit + affecting this file. + * normal/main.c (read_lists): Move read_handler_list() call back to ... + (grub_normal_execute): ... here. + +2010-01-07 Robert Millan + + Merge prefix-redefinition-fix branch. + + * normal/autofs.c (read_fs_list): Make function capable of being + run multiple times, gracefuly replacing the previous data + structures. + * normal/dyncmd.c (read_command_list): Likewise. + * normal/handler.c (read_handler_list): Likewise. + * normal/main.c (read_lists): New function. Calls all the + list reading functions. + (grub_normal_execute): Use read_lists() instead of calling all + list reading functions explicitly. Register read_lists() as a + variable hook attached to ${prefix}. + +2010-01-07 Vladimir Serbinenko + + Merge crypto branch. + + * Makefile.in (pkglib_DATA): Add crypto.lst. + (crypto.lst): New target. + * commands/hashsum.c: New file. + * commands/password.c (check_password): Use grub_crypto_memcmp. + * commands/password_pbkdf2.c: New file. + * commands/xnu_uuid.c: Remove MD5. Use GRUB_MD_MD5. + * conf/any-emu.rmk (grub_emu_SOURCES): Add lib/crypto.c, + normal/crypto.c and lib/libgcrypt-grub/cipher/md5.c. + (grub_emu_CFLAGS): Add -Wno-missing-field-initializers -Wno-error + -I$(srcdir)/lib/libgcrypt_wrap. + * conf/common.rmk (normal_mod_SOURCES): Add normal/crypto.c. + (pkglib_MODULES): Add crypto.mod, hashsum.mod, pbkdf2.mod and + password_pbkdf2.mod. + (crypto_mod_SOURCES): New variable. + (crypto_mod_CFLAGS): Likewise. + (crypto_mod_LDFLAGS): Likewise. + (hashsum_mod_SOURCES): New variable. + (hashsum_mod_CFLAGS): Likewise. + (hashsum_mod_LDFLAGS): Likewise. + (pbkdf2_mod_SOURCES): New variable. + (pbkdf2_mod_CFLAGS): Likewise. + (pbkdf2_mod_LDFLAGS): Likewise. + (password_pbkdf2_mod_SOURCES): New variable. + (password_pbkdf2_mod_CFLAGS): Likewise. + (password_pbkdf2_mod_LDFLAGS): Likewise. + (bin_UTILITIES): Add grub-mkpasswd-pbkdf2. + (grub_mkpasswd_pbkdf2_SOURCES): New variable. + (grub_mkpasswd_pbkdf2_CFLAGS): Likewise. + Include conf/gcry.rmk. + * include/grub/auth.h: Rewritten. + * include/grub/crypto.h: New file. + * include/grub/disk.h (grub_disk_dev_id): Add GRUB_DISK_DEVICE_LUKS_ID. + * include/grub/normal.h (read_crypto_list): New prototype. + * lib/crypto.c: New file. + * lib/libgcrypt_wrap/cipher_wrap.h: Likewise. + * lib/pbkdf2.c: Likewise. + * normal/auth.c (grub_auth_strcmp): Removed. + (grub_iswordseparator): Likewise. + (grub_auth_strword): Likewise. + (is_authenticated): Use grub_strword. + (grub_auth_check_authentication): Use grub_strcmp, grub_password_get + and grub_strword. Pass entered password to authentication callback. + * normal/crypto.c: New file. + * normal/main.c: Call read_crypto_list. + * util/grub-mkpasswd-pbkdf2.c: New file. + * util/import_gcry.py: Generate crypto.lst. Add hash blocklen. + +2010-01-06 Vladimir Serbinenko + + Fix descent and ascent calculation. + + * util/grub-mkfont.c (grub_font_info): New fields 'asce' and 'max_y'. + (options): New option "asce". + (usage): Likewise. + (add_char): Ignore invalid glyphs for descent calculation. + Calculate ascent from actual content. + (print_glyphs): Use 'asce'. + (write_font): Likewise. Allow ascent override. + (main): Handle "asce" option. + +2010-01-06 Carles Pina i Estany + + * kern/err.c: Include `'. + (grub_print_error): Add full stop. Gettextizze. + * loader/i386/bsd.c (grub_netbsd_boot): Change grub_error description. + (grub_bsd_load_elf): Capitalise ELF. + (grub_cmd_freebsd_loadenv): Add `s' in error string. + (grub_cmd_freebsd_module): Likewise. + (grub_cmd_freebsd_module_elf): Likewise. + * loader/i386/bsdXX.c (SUFFIX): Capitalise ELF. + +2010-01-06 Carles Pina i Estany + + * commands/search.c (GRUB_MOD_INIT): Use HELP_MESSAGE. + * commands/search_file.c (HELP_MESSAGE): New macro. + * commands/search_label.c (HELP_MESSAGE): Likewise. + * commands/search_uuid.c (HELP_MESSAGE): Likewise. + * po/POTFILES: Add `commands/search_file.c', + `commands/search_label.c', `commands_uuid.c'. Remove duplicate + `commands/search.c'. + +2010-01-05 Robert Millan + + * config.rpath: Update from Gnulib. + +2010-01-05 Yves Blusseau + + * commands/acpi.c (grub_acpi_create_ebda): fix incorrect message. + +2010-01-05 Yves Blusseau + + * util/sparc64/ieee1275/grub-mkimage.c (main): Typo fix. + +2010-01-05 Colin Watson + + * util/mkisofs/write.c (padblock_write): Switch size and nmemb + arguments to fread so that we get a return value in bytes, rather + than something that will normally be rounded down to 0. + Adjust error handling to avoid producing garbage when size_t is not + the same size as long long. + +2010-01-05 Colin Watson + + * util/mkisofs/write.c (padblock_write): Check return value of + fread. + +2010-01-05 Robert Millan + + Remove grub-mkfloppy. Images produced by grub-mkrescue are valid + floppy images now. + + * util/i386/pc/grub-mkfloppy.in: Remove. Update all users. + +2010-01-04 Robert Millan + + * disk/i386/pc/biosdisk.c (grub_biosdisk_rw): Use ALIGN_UP macro + instead of manual alignment. + * kern/disk.c (grub_disk_read): Remove grub_dprintf call (excessively + verbose). Avoid attempts to read past end of the device + (grub_disk_adjust_range() guarantees that we can read `size' bytes, + but GRUB_DISK_CACHE_SIZE may exceed that). + +2010-01-04 Robert Millan + + * commands/crc.c (grub_cmd_crc): Abort on read errors. + * fs/iso9660.c (grub_iso9660_read): Check for read error and pass + it to upper layer. + +2010-01-04 Vladimir Serbinenko + + * include/grub/efi/api.h (GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE): + New constant. + (grub_efi_piwg_device_path): New structure + (grub_efi_piwg_device_path_t): New type. + * loader/efi/appleloader.c (piwg_full_device_path): New structure. + (devpath_1): Transform to a structure. All users updated. + (devpath_2): Likewise. + (devpath_3): Likewise. + (devpath_4): Likewise. + (devpath_5): Likewise. + +2010-01-04 Vladimir Serbinenko + + * loader/efi/appleloader.c: Restored. Update all users. + +2010-01-03 Robert Millan + + * boot/i386/pc/diskboot.S: Fix inaccurate comment. + + * util/i386/pc/grub-setup.c: Include `'. + (struct boot_blocklist): Move from here ... + * include/grub/i386/pc/boot.h [ASM_FILE] + (struct grub_boot_blocklist): ... to here. Update all users. + (setup): Only initialize `start' member of `first_block' + structure. Add assert() calls to verify the other members. + + * util/i386/pc/grub-mkimage.c: Include `'. + (generate_image): Fix broken blocklist length initialization. + Add assert() call to verify blocklist `segment' field. + +2010-01-03 Robert Millan + + * loader/efi/appleloader.c: Remove. Update all users. + +2010-01-03 Robert Millan + + * boot/i386/pc/boot.S: Update copyright year. + * boot/i386/pc/cdboot.S: Likewise. + * boot/i386/pc/diskboot.S: Likewise. + * boot/i386/pc/lnxboot.S: Likewise. + * boot/i386/pc/pxeboot.S: Likewise. + * bus/pci.c: Likewise. + * commands/cmp.c: Likewise. + * commands/help.c: Likewise. + * commands/hexdump.c: Likewise. + * commands/i386/pc/halt.c: Likewise. + * commands/i386/pc/play.c: Likewise. + * commands/i386/pc/vbeinfo.c: Likewise. + * commands/ls.c: Likewise. + * commands/test.c: Likewise. + * disk/dmraid_nvidia.c: Likewise. + * disk/i386/pc/biosdisk.c: Likewise. + * disk/ieee1275/nand.c: Likewise. + * disk/ieee1275/ofdisk.c: Likewise. + * disk/lvm.c: Likewise. + * disk/raid.c: Likewise. + * disk/raid6_recover.c: Likewise. + * disk/scsi.c: Likewise. + * fs/affs.c: Likewise. + * fs/cpio.c: Likewise. + * fs/ext2.c: Likewise. + * fs/hfs.c: Likewise. + * fs/iso9660.c: Likewise. + * fs/ntfs.c: Likewise. + * fs/sfs.c: Likewise. + * fs/udf.c: Likewise. + * fs/ufs.c: Likewise. + * fs/xfs.c: Likewise. + * gencmdlist.sh: Likewise. + * genmk.rb: Likewise. + * include/grub/disk.h: Likewise. + * include/grub/efi/api.h: Likewise. + * include/grub/efi/efi.h: Likewise. + * include/grub/efi/pe32.h: Likewise. + * include/grub/elf.h: Likewise. + * include/grub/fs.h: Likewise. + * include/grub/i386/at_keyboard.h: Likewise. + * include/grub/i386/pc/memory.h: Likewise. + * include/grub/i386/pc/vbe.h: Likewise. + * include/grub/i386/pci.h: Likewise. + * include/grub/i386/tsc.h: Likewise. + * include/grub/ieee1275/ieee1275.h: Likewise. + * include/grub/ntfs.h: Likewise. + * include/grub/sparc64/ieee1275/ieee1275.h: Likewise. + * include/grub/sparc64/libgcc.h: Likewise. + * include/grub/symbol.h: Likewise. + * include/grub/types.h: Likewise. + * include/multiboot2.h: Likewise. + * io/gzio.c: Likewise. + * kern/device.c: Likewise. + * kern/disk.c: Likewise. + * kern/efi/efi.c: Likewise. + * kern/efi/mm.c: Likewise. + * kern/elf.c: Likewise. + * kern/file.c: Likewise. + * kern/i386/dl.c: Likewise. + * kern/i386/pc/init.c: Likewise. + * kern/i386/pc/startup.S: Likewise. + * kern/ieee1275/ieee1275.c: Likewise. + * kern/ieee1275/init.c: Likewise. + * kern/main.c: Likewise. + * kern/mm.c: Likewise. + * kern/powerpc/dl.c: Likewise. + * kern/sparc64/dl.c: Likewise. + * kern/x86_64/dl.c: Likewise. + * lib/hexdump.c: Likewise. + * loader/efi/appleloader.c: Likewise. + * loader/i386/ieee1275/linux.c: Likewise. + * loader/i386/pc/chainloader.c: Likewise. + * loader/i386/pc/linux.c: Likewise. + * loader/i386/pc/multiboot2.c: Likewise. + * loader/ieee1275/multiboot2.c: Likewise. + * loader/multiboot2.c: Likewise. + * loader/multiboot_loader.c: Likewise. + * loader/powerpc/ieee1275/linux.c: Likewise. + * normal/completion.c: Likewise. + * normal/menu_entry.c: Likewise. + * partmap/apple.c: Likewise. + * util/grub.d/10_hurd.in: Likewise. + * util/hostfs.c: Likewise. + * video/readers/png.c: Likewise. + +2010-01-03 Colin Watson + + * include/grub/misc.h (GNUC_PREREQ): New macro. + (ATTRIBUTE_ERROR): New macro. + * include/grub/list.h (grub_bad_type_cast_real): Use + ATTRIBUTE_ERROR. + +2010-01-03 Carles Pina i Estany + + * normal/menu_text.c (print_message): Change messages. + +2010-01-03 Carles Pina i Estany + + * normal/menu_entry.c (store_completion): Gettextizze. + +2010-01-03 Carles Pina i Estany + + * kern/env.c (grub_env_unset): Set the variable to "" if has hooks. + +2010-01-03 Carles Pina i Estany + + * po/POTFILES: Sort correctly. + +2010-01-03 Carles Pina i Estany + + * commands/acpi.c (GRUB_MOD_INIT): Capitalise some words from help. + * commands/efi/loadbios.c (GRUB_MOD_INIT): Capitalise BIOS. + * commands/i386/pc/drivemap.c (GRUB_MOD_INIT): Remove space. Add + full stop. + * commands/loadenv.c (GRUB_MOD_INIT): Remove command name from + summary. Gettextizze the strings. + * commands/probe.c (grub_cmd_probe): Capitalise UUID and FS. + * commands/xnu_uuid.c (GRUB_MOD_INIT): Capitalise XNU. + * disk/loopback.c (grub_arg_options): Capitalise first letter. Add + full stop. + (GRUB_MOD_INIT): Remove command name from summary. + * hello/hello.c (GRUD_MOT_INIT): Add missing full stop. Improve the + summary. + * loader/i386/bsd.c (grub_arg_option): Capitalise CDROM. + * term/i386/pc/serial.c (options): Add full stops. + (GRUB_MOD_INIT): Remove command name from the summary. + +2010-01-03 Carles Pina i Estany + + * commands/acpi.c: Gettextizze help strings and/or options. Include + `grub/i18n.h' if needed. + * commands/blocklist.c: Likewise. + * commands/boot.c: Likewise. + * commands/cat.c: Likewise. + * commands/cmp.c: Likewise. + * commands/configfile.c: Likewise. + * commands/crc.c: Likewise. + * commands/date.c: Likewise. + * commands/echo.c: Likewise. + * commands/efi/fixvideo.c: Likewise. + * commands/efi/loadbios.c: Likewise. + * commands/gptsync.c: Likewise. + * commands/halt.c: Likewise. + * commands/handler.c: Likewise. + * commands/hdparm.c: Likewise. + * commands/hexdump.c: Likewise. + * commands/i386/cpuid.c: Likewise. + * commands/i386/pc/drivemap.c: Likewise. + * commands/i386/pc/halt.c: Likewise. + * commands/i386/pc/pxecmd.c: Likewise. + * commands/i386/pc/vbeinfo.c: Likewise. + * commands/i386/pc/vbetest.c: Likewise. + * commands/ieee1275/suspend.c: Likewise. + * commands/keystatus.c: Likewise. + * commands/loadenv.c: Likewise. + * commands/ls.c: Likewise. + * commands/lsmmap.c: Likewise. + * commands/lspci.c: Likewise. + * commands/memrw.c: Likewise. + * commands/minicmd.c: Likewise. + * commands/parttool.c: Likewise. + * commands/password.c: Likewise. + * commands/probe.c: Likewise. + * commands/read.c: Likewise. + * commands/reboot.c: Likewise. + * commands/search.c: Likewise. + * commands/sleep.c: Likewise. + * commands/test.c: Likewise. + * commands/true.c: Likewise. + * commands/usbtest.c: Likewise. + * commands/videotest.c: Likewise. + * commands/xnu_uuid.c: Likewise. + * disk/loopback.c: Likewise. + * hello/hello.c: Likewise. + * loader/i386/bsd.c: Likewise. + * term/i386/pc/serial.c: Likewise. + * po/POTFILES: Add new files. + +2010-01-02 Colin Watson + + * term/i386/pc/at_keyboard.c + (keyboard_controller_wait_untill_ready): Rename to ... + (keyboard_controller_wait_until_ready): ... this. Update all users. + +2010-01-01 Carles Pina i Estany + + * commands/help.c: Include `grub/mm.h' and `grub/normal.h'. + (grub_cmd_help): Print the cmd->name before the cmd->summary. Cut the + string using string width. + * normal/menu_text.c (grub_print_message_indented): Use + grub_print_spaces and not print_spaces. + (print_timeout): Likewise. + (print_spaces): Move to... + * include/grub/term.h: ... here. Change the name to grub_print_spaces. + +2010-01-01 Robert Millan + + Import from Gnulib. + + * gnulib/getdelim.c: New file. + * gnulib/getline.c: Likewise. + +2009-12-31 BVK Chaitanya + + * include/grub/list.h (grub_assert_fail): Removed. + (grub_bad_type_cast_real): New function. + (grub_bad_type_cast): New macro. + (GRUB_AS_LIST): Use grub_bad_type_cast. + (GRUB_AS_LIST_P): Likewise. + (GRUB_AS_NAMED_LIST): Likewise. + (GRUB_AS_NAMED_LIST_P): Likewise. + (GRUB_AS_PRIO_LIST): Likewise. + (GRUB_AS_PRIO_LIST_P): Likewise. + * include/grub/handler.h (GRUB_AS_HANDLER): Likewise. + +2009-12-29 Vladimir Serbinenko + + * loader/sparc64/ieee1275/linux.c (GRUB_MOD_INIT (linux)): + Fix syntax error. + +2009-12-29 Robert Millan + + * configure.ac: Check for TARGET_CFLAGS initialization before we + initialize it ourselves (sigh). + Move a few modifications to TARGET_CFLAGS to be unconditional + (extra warning flags, loop alignment, i386 CPU extensions, GCC 4.4 + eh_frame) + + * gettext/gettext.c (grub_gettext_delete_list): Add `void' argument. + * term/i386/pc/at_keyboard.c + (keyboard_controller_wait_untill_ready): Likewise. + (keyboard_controller_led): Rename `led_status' paramter to avoid + name conflict. + +2009-12-28 Carles Pina i Estany + + * normal/misc.c (grub_normal_print_device_info): Add spaces and double + quotes. + +2009-12-27 Vladimir Serbinenko + + * kern/parser.c (grub_parser_split_cmdline): Don't dereference NULL. + +2009-12-27 Vladimir Serbinenko + + * normal/menu_text.c (grub_print_message_indented): Prevent + past-the-end-of-array dereference. + +2009-12-27 Vladimir Serbinenko + + * video/readers/jpeg.c (GRUB_MOD_FINI (grub_cmd_jpegtest)): Rename to .. + (GRUB_MOD_FINI (video_reader_jpeg)): ...this + +2009-12-27 Carles Pina i Estany + + * normal/cmdline.c (grub_cmdline_get): Print a space after prompt. + * normal/main.c (grub_normal_read_line): Remove a space from the + default prompt. + +2009-12-27 Carles Pina i Estany + + * loader/i386/efi/linux.c (GRUB_MOD_INIT): Improve command summary. + * loader/i386/ieee1275/linux.c (GRUB_MOD_INIT): Likewise. + * loader/i386/linux.c (GRUB_MOD_INIT): Likewise. + * loader/i386/pc/linux.c (GRUB_MOD_INIT): Likewise. + * loader/powerpc/ieee1275/linux.c (GRUB_MOD_INIT): Likewise. + * loader/sparc64/ieee1275/linux.c (GRUB_MOD_INIT): Likewise. + * loader/xnu.c (GRUB_MOD_INIT): Likewise. + +2009-12-26 Carles Pina i Estany + + * video/readers/jpeg.c (cmd): Declare. + (grub_cmd_jpegtest): Use `grub_command_t' type. + (GRUB_MOD_INIT): Fix arguments passed to `grub_register_command'. + Assign to `cmd'. + (GRUB_MOD_FINI): Use `cmd' to unregister. + * video/readers/png.c (cmd): Declare. + (grub_cmd_pngtest): Use `grub_command_t' type. + (GRUB_MOD_INIT): Fix arguments passed to `grub_register_command'. + Assign to `cmd'. + (GRUB_MOD_FINI): Use `cmd' to unregister. + * video/readers/tga.c (cmd): Declare. + (grub_cmd_tgatest): Use `grub_command_t' type. + (GRUB_MOD_INIT): Fix arguments passed to `grub_register_command'. + Assign to `cmd'. + (GRUB_MOD_FINI): Use `cmd' to unregister. + +2009-12-26 Carles Pina i Estany + + * efiemu/main.c (GRUB_MOD_INIT): Fix capitalizations and/or full + stops. + * kern/corecmd.c (grub_register_core_commands): Likewise. + * loader/efi/chainloader.c (GRUB_MOD_INIT): Likewise. + * loader/i386/bsd.c (GRUB_MOD_INIT): Likewise. + * loader/i386/efi/linux.c (GRUB_MOD_INIT): Likewise. + * loader/i386/ieee1275/linux.c (GRUB_MOD_INIT): Likewise. + * loader/i386/linux.c (GRUB_MOD_INIT): Likewise. + * loader/i386/pc/chainloader.c (GRUB_MOD_INIT): Likewise. + * loader/i386/pc/linux.c (GRUB_MOD_INIT): Likewise. + * loader/multiboot_loader.c (GRUB_MOD_INIT): Likewise. + * loader/powerpc/ieee1275/linux.c (GRUB_MOD_INIT): Likewise. + * loader/sparc64/ieee1275/linux.c (GRUB_MOD_INIT): Likewise. + * loader/xnu.c (GRUB_MOD_INIT): Likewise. + * mmap/mmap.c (GRUB_MOD_INIT): Likewise. + * normal/handler.c (insert_handler): Likewise. + * normal/main.c (GRUB_MOD_INIT): Likewise. + * term/gfxterm.c (GRUB_MOD_INIT): Likewise. + +2009-12-26 Carles Pina i Estany + + * commands/help.c (grub_cmd_help): Print the command name before the + summary. + (GRUB_MOD_INIT): Remove command name from the summary. + * kern/command.c (GRUB_MOD_INIT): If summary is null assign an empty + string as summary. + * lib/arg.c (find_long): Print the command name before the summary. + * commands/acpi.c (GRUB_MOD_INIT): Remove command name from the + summary. + * commands/blocklist.c (GRUB_MOD_INIT): Likewise. + * commands/cat.c (GRUB_MOD_INIT): Likewise. + * commands/cmp.c (GRUB_MOD_INIT): Likewise. + * commands/configfile.c (GRUB_MOD_INIT): Likewise. + * commands/crc.c (GRUB_MOD_INIT): Likewise. + * commands/date.c (GRUB_MOD_INIT): Likewise. + * commands/echo.c (GRUB_MOD_INIT): Likewise. + * commands/efi/loadbios.c (GRUB_MOD_INIT): Likewise. + * commands/gptsync.c (GRUB_MOD_INIT): Likewise. + * commands/handler.c (GRUB_MOD_INIT): Likewise. + * commands/hdparm.c (GRUB_MOD_INIT): Likewise. + * commands/hexdump.c (GRUB_MOD_INIT): Likewise. + * commands/i386/cpuid.c (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/halt.c (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/play.c (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/pxecmd.c (GRUB_MOD_INIT): Likewise. + * commands/keystatus.c (GRUB_MOD_INIT): Likewise. + * commands/loadenv.c (GRUB_MOD_INIT): Likewise. + * commands/ls.c (GRUB_MOD_INIT): Likewise. + * commands/lspci.c (GRUB_MOD_INIT): Likewise. + * commands/memrw.c (GRUB_MOD_INIT): Likewise. + * commands/minicmd.c (GRUB_MOD_INIT): Likewise. + * commands/parttool.c (GRUB_MOD_INIT): Likewise. + * commands/password.c (GRUB_MOD_INIT): Likewise. + * commands/probe.c (GRUB_MOD_INIT): Likewise. + * commands/read.c (GRUB_MOD_INIT): Likewise. + * commands/search.c (GRUB_MOD_INIT): Likewise. + * commands/sleep.c (GRUB_MOD_INIT): Likewise. + * commands/test.c (GRUB_MOD_INIT): Likewise. + * commands/xnu_uuid.c (GRUB_MOD_INIT): Likewise. + * efiemu/main.c (GRUB_MOD_INIT): Likewise. + * font/font_cmd.c (GRUB_MOD_INIT): Likewise. + * gettext/gettext.c (GRUB_MOD_INIT): Likewise. + * kern/corecmd.c (GRUB_MOD_INIT): Likewise. + * lib/arg.c (GRUB_MOD_INIT): Likewise. + * loader/efi/appleloader.c (GRUB_MOD_INIT): Likewise. + * loader/i386/bsd.c (GRUB_MOD_INIT): Likewise. + * loader/xnu.c (GRUB_MOD_INIT): Likewise. + * mmap/mmap.c (GRUB_MOD_INIT): Likewise. + * term/terminfo.c (GRUB_MOD_INIT): Likewise. + * video/readers/jpeg.c (GRUB_MOD_INIT): Likewise. + * video/readers/png.c (GRUB_MOD_INIT): Likewise. + * video/readers/tga.c (GRUB_MOD_INIT): Likewise. + +2009-12-25 Vladimir Serbinenko + + Use search command for preliminar UUID search. + + * commands/search.c: Split into ... + * commands/search_wrap.c: ...this + * commands/search.c: ...and this. + * commands/search_file.c: New file. + * commands/search_label.c: New file. + * commands/search_uuid.c: New file. + * conf/any-emu.rmk (grub_emu_SOURCES): Remove commands/search.c. + Add commands/search_wrap.c, commands/search_file.c, + commands/search_label.c and commands/search_uuid.c. + * conf/common.rmk (pkglib_MODULES): Remove fs_uuid.mod and fs_file.mod. + (search_mod_SOURCES): Set to commands/search_wrap.c. + (pkglib_MODULES): Add search_fs_file.mod, search_fs_uuid.mod and + search_label.mod. + (search_fs_file_mod_SOURCES): New variable. + (search_fs_file_mod_CFLAGS): Likewise. + (search_fs_file_mod_LDFLAGS): Likewise. + (search_label_mod_SOURCES): Likewise. + (search_label_mod_CFLAGS): Likewise. + (search_label_mod_LDFLAGS): Likewise. + (search_fs_uuid_mod_SOURCES): New variable. + (search_fs_uuid_mod_CFLAGS): Likewise. + (search_fs_uuid_mod_LDFLAGS): Likewise. + (fs_file_mod_SOURCES): Removed. + (fs_file_mod_CFLAGS): Likewise. + (fs_file_mod_LDFLAGS): Likewise. + (fs_uuid_mod_SOURCES): Removed. + (fs_uuid_mod_CFLAGS): Likewise. + (fs_uuid_mod_LDFLAGS): Likewise. + * conf/sparc64-ieee1275.rmk (grub_install_SOURCES): + Set to util/grub-install.in. + * disk/fs_file.c: Removed. + * disk/fs_uuid.c: Likewise. + * include/grub/search.h: New file. + * util/grub-install.in: Handle sparc64. + Create and use load.cfg. + * util/sparc64/ieee1275/grub-install.in: Removed. + +2009-12-25 Vladimir Serbinenko + + * kern/i386/pc/startup.S (grub_biosdisk_get_diskinfo_int13_extensions): + Ignore return status if CF is cleared. + (grub_biosdisk_get_diskinfo_standard): Likewise. + +2009-12-25 Robert Millan + + * term/i386/pc/at_keyboard.c + (keyboard_controller_wait_untill_ready): New function. + (grub_keyboard_controller_write, grub_keyboard_controller_read) + (keyboard_controller_led): Use keyboard_controller_wait_untill_ready() + for keyboard polling, rather than duplicate the same loop. This + saves a few bytes in code size. + +2009-12-25 Vladimir Serbinenko + + Support for (pxe[:server[:gateway]]) syntax and + use environment variable for PXE. + + * commands/i386/pc/pxecmd.c (options): Removed. + (print_ip): Removed. + (grub_cmd_pxe): Removed + (grub_cmd_pxe_unload): New function. + * fs/i386/pc/pxe.c (grub_pxe_disk_data): New structure. + (grub_pxe_your_ip): Made static. + (grub_pxe_default_server_ip): Likewise. + (grub_pxe_default_gateway_ip): Likewise. + (grub_pxe_blksize): Likewise. + (parse_ip): New function. + (grub_pxe_open): Support server and gateway specification. + (grub_pxe_close): Free disk->data. + (grub_pxefs_open): Use disk->data. + (grub_pxefs_read): Likewise. + (grub_env_write_readonly): New function. + (set_mac_env): Likewise. + (set_env_limn_ro): Likewise. + (parse_dhcp_vendor): Likewise. + (grub_pxe_detect): Set the environment variables. + (set_ip_env): New function. + (write_ip_env): Likewise. + (grub_env_write_pxe_default_server): Likewise. + (grub_env_write_pxe_default_gateway): Likewise. + (grub_env_write_pxe_blocksize): Likewise. + (GRUB_MOD_INIT(pxe)): Set environment variables. + * include/grub/i386/pc/pxe.h (grub_pxe_mac_addr): Rename to ... + (grub_pxe_mac_addr_t): ... this. All users updated. + (grub_pxe_your_ip): Removed. + (grub_pxe_server_ip): Likewise. + (grub_pxe_gateway_ip): Likewise. + (grub_pxe_blksize): Likewise. + +2009-12-25 Carles Pina i Estany + + * commands/help.c: Include `'. + (grub_cmd_help): Gettextizze. + (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/play.c: Include `'. + (GRUB_MOD_INIT): Gettextizze. + * commands/search.c: Include `'. + (options): Gettextizze. + (GRUB_MOD_INIT): Gettextizze. + * lib/arg.c: Include `'. + (help_options): Gettextizze. + (find_long): Likewise. + (grub_arg_show_help): Likewise. + * normal/dyncmd.c: Include `'. + (read_command_list): Gettextizze. + * po/POTFILES: Add `commands/i386/pc/play.c', `commands/search.c', + `commands/help.c', `lib/arg.c' and `normal/dyncmd.c'. + +2009-12-25 Robert Millan + + * include/grub/i386/at_keyboard.h (NUM_LOCK, SCROLL_LOCK): New macros. + * term/i386/pc/at_keyboard.c (KEYBOARD_STATUS_NUM_LOCK) + (KEYBOARD_LED_SCROLL, KEYBOARD_LED_NUM, KEYBOARD_LED_CAPS): New macros. + (led_status): New variable. + (keyboard_controller_led): New function. + (grub_at_keyboard_getkey_noblock): Handle num lock and scroll lock, + update led status for caps lock, num lock and scroll lock. + +2009-12-25 Felix Zielcke + + * util/hostdisk.c (open_device): Fix a comment. + +2009-12-24 Robert Millan + + * util/grub-install.in (host_os): New variable. + * util/i386/efi/grub-install.in (host_os): Likewise. + +2009-12-24 Robert Millan + + * util/mkisofs/write.c (padblock_write): Abort when given an + excedingly large embed image, instead of silently truncating it. + +2009-12-24 Robert Millan + + * include/multiboot.h: Indentation fixes. + +2009-12-24 Robert Millan + + * include/multiboot.h (struct multiboot_aout_symbol_table) + (struct multiboot_elf_section_header_table): New structure + declarations (stolen from GRUB Legacy). + (struct multiboot_info): Replace opaque `syms' with a.out and ELF + table information. + + (multiboot_aout_symbol_table_t, multiboot_elf_section_header_table_t) + (multiboot_info_t, multiboot_memory_map_t, multiboot_module_t): New + type aliases. + +2009-12-24 Robert Millan + + * include/multiboot.h: Make comments src2texi-friendly. + +2009-12-24 Robert Millan + + For consistency with [multiboot]/docs/boot.S. + + * include/multiboot.h (MULTIBOOT_MAGIC): Rename from this ... + (MULTIBOOT_HEADER_MAGIC): ... to this. Update all users. + (MULTIBOOT_MAGIC2): Rename from this ... + (MULTIBOOT_BOOTLOADER_MAGIC): ... to this. Update all users. + +2009-12-24 Robert Millan + + * include/multiboot.h: Remove `'. + (multiboot_uint16_t, multiboot_uint32_t, multiboot_uint64_t): New + types. Update all users. + +2009-12-25 Carles Pina i Estany + + * commands/efi/loadbios.c: Capitalize acronyms, replace `could not' by + `couldn't' and `can not' by `cannot'. + * commands/i386/pc/drivemap.c: Likewise. + * disk/ata.c: Likewise. + * disk/ieee1275/nand.c: Likewise. + * fs/affs.c: Likewise. + * fs/fat.c: Likewise. + * fs/hfs.c: Likewise. + * fs/hfsplus.c: Likewise. + * fs/iso9660.c: Likewise. + * fs/jfs.c: Likewise. + * fs/minix.c: Likewise. + * fs/reiserfs.c: Likewise. + * fs/sfs.c: Likewise. + * fs/udf.c: Likewise. + * fs/ufs.c: Likewise. + * fs/xfs.c: Likewise. + * loader/powerpc/ieee1275/linux.c: Likewise. + * loader/sparc64/ieee1275/linux.c: Likewise. + * util/grub-probe.c: Likewise. + * util/misc.c: Likewise. + +2009-12-24 Carles Pina i Estany + + * bus/usb/usbhub.c: Fix capitalization, fullstop and newlines in + grub_errno calls. + * commands/acpi.c: Likewise. + * commands/blocklist.c: Likewise. + * commands/efi/loadbios.c: Likewise. + * commands/i386/pc/drivemap.c: Likewise. + * commands/loadenv.c: Likewise. + * commands/memrw.c: Likewise. + * commands/password.c: Likewise. + * commands/videotest.c: Likewise. + * disk/ata.c: Likewise. + * disk/ata_pthru.c: Likewise. + * disk/dmraid_nvidia.c: Likewise. + * disk/ieee1275/nand.c: Likewise. + * disk/ieee1275/ofdisk.c: Likewise. + * disk/loopback.c: Likewise. + * disk/lvm.c: Likewise. + * disk/mdraid_linux.c: Likewise. + * disk/raid.c: Likewise. + * disk/raid6_recover.c: Likewise. + * disk/scsi.c: Likewise. + * efiemu/main.c: Likewise. + * efiemu/mm.c: Likewise. + * efiemu/pnvram.c: Likewise. + * efiemu/symbols.c: Likewise. + * font/font.c: Likewise. + * fs/cpio.c: Likewise. + * fs/hfsplus.c: Likewise. + * fs/iso9660.c: Likewise. + * fs/jfs.c: Likewise. + * fs/minix.c: Likewise. + * fs/ntfs.c: Likewise. + * fs/ntfscomp.c: Likewise. + * fs/reiserfs.c: Likewise. + * fs/ufs.c: Likewise. + * fs/xfs.c: Likewise. + * gettext/gettext.c: Likewise. + * include/grub/auth.h: Likewise. + * kern/elf.c: Likewise. + * kern/file.c: Likewise. + * kern/ieee1275/init.c: Likewise. + * kern/ieee1275/mmap.c: Likewise. + * kern/ieee1275/openfw.c: Likewise. + * kern/powerpc/dl.c: Likewise. + * kern/sparc64/dl.c: Likewise. + * lib/arg.c: Likewise. + * loader/i386/bsd.c: Likewise. + * loader/i386/bsdXX.c: Likewise. + * loader/i386/efi/linux.c: Likewise. + * loader/i386/efi/xnu.c: Likewise. + * loader/i386/ieee1275/linux.c: Likewise. + * loader/i386/linux.c: Likewise. + * loader/i386/multiboot.c: Likewise. + * loader/i386/pc/linux.c: Likewise. + * loader/i386/pc/multiboot2.c: Likewise. + * loader/i386/xnu.c: Likewise. + * loader/ieee1275/multiboot2.c: Likewise. + * loader/macho.c: Likewise. + * loader/machoXX.c: Likewise. + * loader/multiboot2.c: Likewise. + * loader/multiboot_loader.c: Likewise. + * loader/powerpc/ieee1275/linux.c: Likewise. + * loader/sparc64/ieee1275/linux.c: Likewise. + * loader/xnu.c: Likewise. + * loader/xnu_resume.c: Likewise. + * mmap/i386/pc/mmap.c: Likewise. + * normal/menu_viewer.c: Likewise. + * partmap/acorn.c: Likewise. + * partmap/amiga.c: Likewise. + * partmap/apple.c: Likewise. + * script/lexer.c: Likewise. + * term/gfxterm.c: Likewise. + * term/i386/pc/serial.c: Likewise. + * term/i386/pc/vga.c: Likewise. + * term/ieee1275/ofconsole.c: Likewise. + * term/terminfo.c: Likewise. + * video/bitmap.c: Likewise. + * video/efi_gop.c: Likewise. + * video/efi_uga.c: Likewise. + * video/fb/video_fb.c: Likewise. + * video/i386/pc/vbe.c: Likewise. + * video/readers/tga.c: Likewise. + * video/video.c: Likewise. + +2009-12-23 Felix Zielcke + + * commands/i386/pc/drivemap.c: Remove all trailing whitespace. + * commands/lspci.c: Likewise. + * commands/probe.c: Likewise. + * commands/xnu_uuid.c: Likewise. + * conf/i386-coreboot.rmk: Likewise. + * conf/i386-efi.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * fs/i386/pc/pxe.c: Likewise. + * gettext/gettext.c: Likewise. + * include/grub/efi/graphics_output.h: Likewise. + * include/grub/i386/pc/memory.h: Likewise. + * kern/env.c: Likewise. + * kern/i386/qemu/startup.S: Likewise. + * lib/i386/pc/biosnum.c: Likewise. + * lib/i386/relocator.c: Likewise. + * lib/i386/relocator_asm.S: Likewise. + * lib/relocator.c: Likewise. + * loader/i386/bsd.c: Likewise. + * loader/i386/multiboot.c: Likewise. + * loader/i386/pc/chainloader.c: Likewise. + * loader/i386/xnu.c: Likewise. + * loader/xnu.c: Likewise. + * normal/main.c: Likewise. + * normal/menu_text.c: Likewise. + * util/getroot.c: Likewise. + * util/grub-mkconfig_lib.in: Likewise. + * util/grub.d/00_header.in: Likewise. + * util/i386/pc/grub-mkimage.c: Likewise. + * util/mkisofs/eltorito.c: Likewise. + * util/mkisofs/exclude.h: Likewise. + * util/mkisofs/hash.c: Likewise. + * util/mkisofs/iso9660.h: Likewise. + * util/mkisofs/joliet.c: Likewise. + * util/mkisofs/mkisofs.c: Likewise. + * util/mkisofs/mkisofs.h: Likewise. + * util/mkisofs/multi.c: Likewise. + * util/mkisofs/name.c: Likewise. + * util/mkisofs/rock.c: Likewise. + * util/mkisofs/tree.c: Likewise. + * util/mkisofs/write.c: Likewise. + * video/efi_gop.c: Likewise. + +2009-12-23 Vladimir Serbinenko + + * video/efi_gop.c (grub_video_gop_get_bitmask): Fix off-by-one in mask + size counting. + +2009-12-22 Felix Zielcke + + * util/grub-mkrescue.in (pkglib_DATA): Set to @pkglib_DATA@. + * genmk.rb (class SCRIPT): Modify the target file instead of source. + +2009-12-22 Vladimir Serbinenko + + * commands/memrw.c (grub_cmd_write): Support for mask parameter. + (GRUB_MOD_INIT(memrw)): Update help line. + +2009-12-22 Vladimir Serbinenko + + * commands/memrw.c (cmd_read_byte, cmd_read_word, cmd_read_dword): + Use grub_extcmd_t. All users updated. + (options): New variable. + (grub_cmd_read): Restructure for readability. Support "-v" option. + (grub_cmd_write): Restructure for readability. + +2009-12-22 Felix Zielcke + + * genmk.rb (class SCRIPT): Prepend #{src} path with $(srcdir). + +2009-12-22 Felix Zielcke + + * genmk.rb (class SCRIPT): Use sed to substitute @pkglib_DATA@ + with the actual contents of the correspondending make variable. + * util/grub-mkrescue.in (pkglib_DATA): New variable. + (process_input_dir): Copy all $pkglib_DATA files instead of explicitly + specifying `*.lst' and `efiemu??.o' + +2009-12-22 Felix Zielcke + + * util/grub.d/30_os-prober.in (osx_entry): Add round brackets + after function name. + Noticed by Rene Engelhard . + +2009-12-22 Vladimir Serbinenko + + * commands/lspci.c (grub_pci_classes): Add "USB Controller". + (options): New variable. + (iospace): Likewise. + (grub_lspci_iter): List IO spaces if "-i" was given. + (grub_cmd_lspci): Parse options. + (GRUB_MOD_INIT(lspci)): Use extcmd. + (GRUB_MOD_FINI(lspci)): Likewise. + +2009-12-22 Felix Zielcke + + * util/grub.d/30_os-prober.in (osx_entry): Remove non POSIX compliant + `function' keyword. + Patch by Tony Mancill . + +2009-12-22 Vladimir Serbinenko + + * bus/usb/uhci.c (grub_uhci_transfer): Set a limit transaction time. + (grub_uhci_portstatus): Likewise. + (grub_uhci_portstatus): Add necessary delay. + * bus/usb/usbhub.c (grub_usb_hub_add_dev): Fix loop-break condition. + +2009-12-21 Carles Pina i Estany + + * commands/acpi.c (options): Fix capitalizations and/or full stops. + (GRUB_MOD_INIT): Likewise. + * commands/boot.c (GRUB_MOD_INIT): Likewise. + * commands/cmp.c (grub_cmd_cmp): Improve the help message. + * commands/echo.c (options): Fix capitalizations and/or full stops. + * commands/efi/loadbios.c (enable_rom_area): Likewise. + (enable_rom_area): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/gptsync.c (GRUB_MOD_INIT): Likewise. + * commands/halt.c (GRUB_MOD_INIT): Improve the help message. + * commands/handler.c (GRUB_MOD_INIT): Likewise. + * commands/hdparm.c (options): Fix capitalizations and/or full stops. + * commands/hexdump.c (options): Likewise. + * commands/i386/cpuid.c (options): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/drivemap.c (options): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/halt (options): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/play.c (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/pxecmd.c (options): Likewise. + * commands/i386/pc/vbetest.c (GRUB_MOD_INIT): Likewise. + * commands/ieee1275/suspend.c (GRUB_MOD_INIT): Likewise. + * commands/keystatus.c (options): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/loadenv.c (options): Likewise. + * commands/ls.c (options): Likewise. + * commands/lspci.c (GRUB_MOD_INIT): Likewise. + * commands/memrw.c (GRUB_MOD_INIT): Likewise. + * commands/minicmd.c (GRUB_MOD_INIT): Likewise. + * commands/parttool.c (helpmsg): Likewise. + * commands/probe.c (options): Likewise. + * commands/read.c (GRUB_MOD_INIT): Likewise. + * commands/reboot.c (GRUB_MOD_INIT): Likewise. + * commands/search.c (options): Likewise. + * commands/sleep.c (options): Likewise. + * commands/test.c (GRUB_MOD_INIT): Likewise. + * commands/true.c (GRUB_MOD_INIT): Likewise. + * commands/usbtest.c (GRUB_MOD_INIT): Likewise. + * commands/videotest.c (GRUB_MOD_INIT): Likewise. + * lib/arg.c (help_options): Likewise. + * Makefile.in ($(srcdir)/po/$(PACKAGE).pot): Pass -ctranslate to + `$(XGETTEXT)'. + * po/POTFILES: Add `commands/loadenv.c'. + +2009-12-21 Felix Zielcke + + * util/grub-mkrescue.in (process_input_dir): Copy `*.lst' files + instead of specifying them explicit. + +2009-12-21 Robert Millan + + * NEWS: Add grub-probe support for GNU/Hurd. + +2009-12-21 Robert Millan + + * NEWS: gettext was added after 1.97. + +2009-12-21 Robert Millan + + * util/mkisofs/msdos_partition.h: New file (based on + include/grub/msdos_partition.h). + * util/mkisofs/mkisofs.c (use_protective_msdos_label): New variable. + (OPTION_PROTECTIVE_MSDOS_LABEL): New macro. + (ld_options, main): Recognize --protective-msdos-label. + * util/mkisofs/mkisofs.h (use_protective_msdos_label): New declaration. + * util/mkisofs/write.c: Include `"msdos_partition.h"'. + (padblock_write): If `use_protective_msdos_label' is set, patch a + protective DOS-style label in the output image. + + * util/grub-mkrescue.in: Use --protective-msdos-label. + +2009-12-21 Robert Millan + + * util/grub-mkrescue.in: Do not zero-pad image for BIOS-based disk + boot. + +2009-12-21 Robert Millan + + * util/mkisofs/mkisofs.c (use_embedded_boot, boot_image_embed): New + variables. + (ld_options, main): Recognize `--embedded-boot'. + * util/mkisofs/mkisofs.h (use_embedded_boot, boot_image_embed): New + declarations. + * util/mkisofs/write.c (PADBLOCK_SIZE): New variable. + (padblock_size): Use `PADBLOCK_SIZE' instead of hardcoding 16. + (padblock_write): Likewise. Rewrite to support embedded boot image. + + * util/grub-mkrescue.in: When building i386-pc images, embed core.img + for BIOS-based disk boot instead of only ElTorito. + +2009-12-21 Robert Millan + + * util/grub-mkrescue.in: Remove `configfile' and `sh' from i386-pc + build (not needed for bootstrap). + +2009-12-21 Robert Millan + + * util/grub-mkrescue.in: Remove `memdisk', `tar' and `search' modules + from i386-pc build (not needed for bootstrap). + Rewrite a pair of strings. + +2009-12-21 Robert Millan + + * normal/main.c (grub_normal_reader_init): Set left margin back to 3. + +2009-12-21 Vladimir Serbinenko + + * video/i386/pc/vbe.c (grub_video_vbe_fini): Set 'last_set_mode'. + +2009-12-21 Andreas Born + + * kern/env.c (grub_env_context_open): Mark exported variable for + reexport. + +2009-12-21 Andreas Born + + * kern/env.c (grub_env_export): Create nonexistent variables before + exporting. + +2009-12-20 Carles Pina i Estany + + * include/grub/auth.h: Include `'. + (GRUB_GET_PASSWORD): Gettextizze string. + * include/grub/normal.h (STANDARD_MARGIN): New macro, moved from + menu_text.c. + (grub_utf8_to_ucs4_alloc): Fix indentation. + (grub_print_ucs4): Likewise. + (grub_getstringwidth): Likewise. + (print_message_indented): New declaration. + * normal/auth.c: Include `'. + (grub_auth_check_authentication): Gettexttize string. + * normal/cmdline.c: Include `'. + (grub_cmdline_get): Gettextizze. + * normal/color.c: Include `'. + (grub_parse_color_name_pair): Gettexttize strings. + * normal/main.c (grub_normal_reader_init): Cleanup gettexttized + string (use `print_message_indented'). + * normal/menu_text.c (STANDARD_MARGIN): Moved from here to + `include/grub/normal.h'. + (print_message_indented): Renamed to ... + (grub_print_message_indented): ... this. Remove `static' qualifer (now + used in normal/main.c). + (print_message): Use `grub_print_message_indented' instead of + `print_message_indented'. + (print_timeout): Likewise. + * normal/misc.c: Include `' and `'. + (grub_normal_print_device_info): Gettexttize strings. + * po/POTFILES: Add `auth.c', `color.c' and `misc.c'. + +2009-12-20 Vladimir Serbinenko + + * kern/parser.c (grub_parser_split_cmdline): Fix incorrect counting + of arguments. Return number of tokens and not arguments. All users + updated. + +2009-12-20 Vladimir Serbinenko + + * util/i386/pc/grub-setup.c (setup): Don't install on non-GPT, + non-MSDOS paritions. + +2009-12-19 Vladimir Serbinenko + + * include/grub/types.h (UNUSED): Removed since it conflicts with + NetBSD headers. All users changed to direct __attribute__ ((unused)). + Reported by GrĂ©goire Sutre. + +2009-12-19 Carles Pina i Estany + + * include/grub/normal.h (grub_utf8_to_ucs4): New declaration. + (grub_print_ucs4_alloc): Likewise. + (grub_getstringwidth): Likewise. + * normal/main.c (grub_normal_init_page): Gettextize version string. + * normal/menu_text.c (grub_utf8_to_ucs4_alloc): New definition. + (getstringwidth): Renamed to ... + (grub_getstringwidth): ... this. Remove `static' qualifier (now used + in normal/main.c). Use `grub_utf8_to_ucs4_alloc'. + (grub_print_ucs4): Remove `static' qualifer (now used in + normal/main.c). + * po/POTFILES: Add normal/main.c. + +2009-12-19 Carles Pina i Estany + + * normal/menu_text.c (STANDARD_MARGIN): New macro. + (print_message_indented): Add `margin_left' and `margin_right' + parameters. + (print_message): Update `print_message_indented' calls. Adds '\n' to the + strings. + (print_timeout): Use `print_message_indented' to print the message. + Deletes `second_stage' parameter. + (run_menu): Update `print_timeout' calls. + +2009-12-18 Vladimir Serbinenko + + Fix console palette on OpenFirmware. + + * term/ieee1275/ofconsole.c (MAX): Removed. + (colors): Redone based on VGA palette. + (grub_ofconsole_setcolor): Discard brightness bit since only 8 + colors are supported. + (grub_ofconsole_init_output): Use ARRAY_SIZE instead of hardcoded size. + +2009-12-18 Vladimir Serbinenko + + Fix potential EfiEmu double prepare. + + * efiemu/main.c (prepared): New variable + (grub_efiemu_unload): Set prepare to '0'. + (grub_efiemu_prepare): Return if already prepared. Set prepared. + + set_virtual_address_map support. + + * include/grub/efi/efi.h (grub_efi_set_virtual_address_map): New + prototype. + * include/grub/efiemu/efiemu.h (grub_efiemu_write_sym_markers): New + prototype. + (grub_efiemu_crc32): Likewise. + (grub_efiemu_crc64): Likewise. + (grub_efiemu_set_virtual_address_map): Likewise. + * include/grub/autoefi.h (grub_autoefi_exit_boot_services): + New definition. + (grub_autoefi_set_virtual_address_map): Likewise. + * kern/efi/efi.c (grub_efi_set_virtual_address_map): New function. + * loader/i386/xnu.c (grub_xnu_boot): Call set_virtual_address_map. + Restructure flow to accomodate it. + * efiemu/prepare.c (grub_efiemu_prepare): Support set_virtual_address_map. + (grub_efiemu_crc): Recompute CRC32. + * efiemu/runtime/efiemu.c (ptv_relocated): Renamed to ... + (efiemu_ptv_relocated): ... this. Made global. All users updated. + * efiemu/symbols.c (relocated_handle): New variable. + (grub_efiemu_free_syms): Free relocated_handle. + (grub_efiemu_alloc_syms): Allocate relocated_handle. + (grub_efiemu_write_sym_markers): New function. + (grub_efiemu_set_virtual_address_map): Likewise. + + Newer XNU parameters. + + * include/grub/i386/xnu.h (GRUB_XNU_BOOTARGS_VERMINOR): Change to 5. + * include/grub/xnu.h (grub_xnu_extheader): Add nameaddr and namesize. + (grub_xnu_fill_devicetree): New prototype. + (grub_xnu_heap_real_start): New variable. + * loader/xnu.c (get_name_ptr): New function. + (grub_xnu_load_driver): Fill namelen and name. + + 64-bit xnu support. + + * conf/i386-efi.rmk (xnu_mod_SOURCES): Add 'loader/macho32.c' + and 'loader/macho64.c'. + * conf/i386-pc.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * include/grub/i386/macho.h (grub_macho_thread64): New structure. + * include/grub/xnu.h (grub_xnu_is_64bit): New variable. + * include/grub/macho.h (grub_macho_segment64): New structure. + * include/grub/machoload.h (grub_macho32_size): Renamed from ... + (grub_macho_size32): ... to this. + (grub_macho32_get_entry_point): Renamed from ... + (grub_macho_get_entry_point32): ... to this. + (grub_macho_contains_macho64): New prototype. + (grub_macho_size64): Likewise. + (grub_macho_get_entry_point64): Likewise. + (grub_macho32_load): Renamed from ... + (grub_macho_load32): ... to this. + (grub_macho32_filesize): Renamed from ... + (grub_macho_filesize32): ... to this. + (grub_macho32_readfile): Renamed from ... + (grub_macho_readfile32): ... to this. + (grub_macho_filesize64): New prototype. + (grub_macho_readfile64): Likewise. + (grub_macho_parse32): Likewise. + (grub_macho_parse64): Likewise. + * loader/macho.c: Split into ... + * loader/machoXX.c: ... and this. Replace 32 with XX. + * loader/macho32.c: New file. + * loader/macho64.c: Likewise. + * loader/xnu.c (grub_xnu_is_64bit): New variable. + (grub_cmd_xnu_kernel): Make 32-bit only. + (grub_cmd_xnu_kernel64): New function. + (grub_xnu_load_driver): Support Mach-O 64. + (grub_cmd_xnu_mkext): Likewise. + * util/grub.d/30_os-prober.in (osx_entry): New function. + Generate entries for 64-bit boot too. + + Eliminate ad-hoc tree format in XNU and EfiEmu. + + * efiemu/main.c (grub_efiemu_prepare): Update comment. + * efiemu/pnvram.c: Rewritten to use environment variables. + All users updated. + + Inline utf16_to_utf8. + + * kern/misc.c (grub_utf16_to_utf8): Move from here ... + * include/grub/charset.h (grub_utf16_to_utf8): ... to here. Inlined. + All users updated. + * include/grub/misc.h (grub_utf16_to_utf8): Removed. + + * bus/usb/usb.c (grub_usb_get_string): Move from here ... + * commands/usbtest.c (grub_usb_get_string): ... move here. + (usb_print_str): Fix error handling. + * include/grub/usb.h (grub_usb_get_string): Remove. + + UTF-8 to UTF-16 transformation. + + * conf/common.rmk (pkglib_MODULES): Add charset.mod + (charset_mod_SOURCES): New variable. + (charset_mod_CFLAGS): Likewise. + (charset_mod_LDFLAGS): Likewise. + * include/grub/utf.h: New file. + * lib/utf.c: New file. (Based on grub_utf8_to_ucs4 from kern/misc.c) + + Support for device properties. + + * include/grub/i386/xnu.h (grub_xnu_devprop_header): New structure. + (grub_xnu_devprop_device_header): Likewise. + (grub_xnu_devprop_device_descriptor): Likewise. + (grub_xnu_devprop_add_device): New prototype. + (grub_xnu_devprop_remove_device): Likewise. + (grub_xnu_devprop_remove_property): Likewise. + (grub_xnu_devprop_add_property_utf8): Likewise. + (grub_xnu_devprop_add_property_utf16): Likewise. + (grub_cpu_xnu_init): Likewise. + (grub_cpu_xnu_fini): Likewise. + (grub_cpu_xnu_unload): Likewise. + * loader/i386/xnu.c (grub_xnu_devprop_device_descriptor): New structure. + (property_descriptor): Likewise. + (devices): New variable. + (grub_xnu_devprop_remove_property): New function. + (grub_xnu_devprop_add_device): Likewise. + (grub_xnu_devprop_remove_device): Likewise. + (grub_xnu_devprop_add_property): Likewise. + (grub_xnu_devprop_add_property_utf8): Likewise. + (grub_xnu_devprop_add_property_utf16): Likewise. + (hextoval): Likewise. + (grub_cpu_xnu_fill_devprop): Likewise. + (grub_cmd_devprop_load): Likewise. + (grub_xnu_boot): Call grub_cpu_xnu_fill_devprop, + grub_xnu_fill_devicetree, grub_xnu_fill_devicetree + (cmd_devprop_load): New variable. + (grub_cpu_xnu_init): New function. + (grub_cpu_xnu_fini): Likewise. + * loader/i386/xnu.c (grub_xnu_unload): Call grub_cpu_xnu_unload. + * loader/xnu.c (grub_xnu_parse_devtree): Remove. + (grub_cmd_xnu_devtree): Likewise. + (hextoval): New function. + (unescape): Likewise. + (grub_xnu_fill_devicetree): Likewise. + + * util/grub.d/30_os-prober.in: Load devprop.bin. Don't load devtree.txt. + * util/i386/efi/grub-dumpdevtree: Generate devprop.bin. + +2009-12-18 Vladimir Serbinenko + + Workaround for broken ATI VBE. + + * video/i386/pc/vbe.c (last_set_mode): New variable. + (grub_vbe_set_video_mode): Set 'last_set_mode'. + (grub_vbe_get_video_mode): Use 'last_set_mode' if get_mode fails. + (grub_video_vbe_setup): Don't check for reserved flag. + +2009-12-17 Felix Zielcke + + * gendistlist.sh: Use POSIX compliant `!' instead of `-not' in + the `find' command. + +2009-12-16 Vladimir Serbinenko + + UUID support for HFS. + + * fs/hfs.c (grub_hfs_uuid): New function. + (grub_hfs_fs): New value .uuid. + * include/grub/hfs.h (grub_hfs_sblock): New field 'num_serial'. + +2009-12-14 Felix Zielcke + + Fix a segfault with parsing unknown long options. + + * util/grub-mkrelpath.c (options): Zero terminate it. + +2009-12-13 Carles Pina i Estany + + * include/grub/misc.h (grub_puts): New declaration. + (grub_puts_): Likewise. + * kern/misc.c (grub_puts): New definition. + (grub_puts_): Likewise. + +2009-12-13 Robert Millan + + * util/grub-probe.c (probe): Improve error message. + +2009-12-13 Robert Millan + + * loader/i386/multiboot_elfxx.c + (CONCAT(grub_multiboot_load_elf, XX)): Fix `grub_multiboot_payload_eip' + initialization. + +2009-12-13 Vladimir Serbinenko + + Relocator framework + + * loader/i386/xnu_helper.S: Removed. All users updated. + * conf/i386.rmk (pkglib_MODULES): Add relocator.mod. + (relocator_mod_SOURCES): New variable. + (relocator_mod_CFLAGS): Likewise. + (relocator_mod_LDFLAGS): Likewise. + (relocator_mod_ASFLAGS): Likewise. + * conf/x86_64.rmk: Likewise. + * include/grub/i386/multiboot.h (grub_multiboot_payload_orig): Removed. + (grub_multiboot_payload_entry_offset): Likewise. + (grub_multiboot_forward_relocator): Likewise. + (grub_multiboot_forward_relocator_end): Likewise. + (grub_multiboot_backward_relocator): Likewise. + (grub_multiboot_backward_relocator_end): Likewise. + (grub_multiboot_payload_eip): New variable. + (grub_multiboot_payload_orig): Likewise. + * include/grub/i386/pc/memory.h: Include grub/i386/memory.h. + (GRUB_MEMORY_MACHINE_CR0_PE_ON): Move from here ... + * include/grub/i386/memory.h + (GRUB_MEMORY_CPU_CR0_PE_ON): ... to here + (GRUB_MEMORY_CPU_CR4_PAE_ON): New definition. + (GRUB_MEMORY_CPU_CR0_PAGING_ON): Likewise. + (GRUB_MEMORY_CPU_AMD64_MSR): Likewise. + (GRUB_MEMORY_CPU_AMD64_MSR_ON): Likewise. + * include/grub/i386/relocator.h: New file. + * include/grub/x86_64/relocator.h: Likewise. + * include/grub/i386/xnu.h: Include grub/cpu/relocator.h. + (XNU_RELOCATOR): New macro. + (grub_xnu_launcher_start): Remove. + (grub_xnu_launcher_end): Likewise. + * include/grub/xnu.h (grub_xnu_boot_resume): New prototype. + (grub_xnu_heap_real_start): Remove. + (grub_xnu_heap_start): Change to void *. All users updated. + * kern/i386/realmode.S (real_to_prot): Use GRUB_MEMORY_CPU_CR0_PE_ON. + * lib/i386/relocator.c: New file. + * lib/i386/relocator_asm.S: Likewise. + * lib/i386/relocator_backward.S: Likewise. + * lib/mips/relocator.c: Likewise. + * lib/mips/relocator_asm.S: Likewise. + * lib/relocator.c: Likewise. + * loader/i386/multiboot.c: Include grub/i386/relocator.h. + (entry): Removed. + (playground): Likewise. + (grub_multiboot_payload_orig): New variable. + (grub_multiboot_payload_dest): Likewise. + (grub_multiboot_payload_size): Likewise. + (grub_multiboot_payload_eip): Likewise. + (grub_multiboot_payload_esp): Likewise. + (grub_multiboot_boot): Use grub_relocator32_boot. + (grub_multiboot_unload): Free relocators. + (grub_multiboot): Setup stack. Use relocators. + * loader/i386/multiboot_elfxx.c: Include grub/i386/relocator.h. + (grub_multiboot_load_elfXX): Use relocators. + * loader/i386/multiboot_helper.S (grub_multiboot_payload_orig): Removed. + (grub_multiboot_payload_size): Likewise. + (grub_multiboot_payload_dest): Likewise. + (grub_multiboot_payload_entry_offset): Likewise. + (grub_multiboot_forward_relocator): Likewise. + (grub_multiboot_backward_relocator): Likewise. + (grub_multiboot_real_boot): Likewise. + * loader/i386/xnu.c (grub_xnu_heap_will_be_at): New variable. + (grub_xnu_entry_point): Likewise. + (grub_xnu_arg1): Likewise. + (grub_xnu_stack): Likewise. + (grub_xnu_launch): Removed. + (grub_xnu_boot_resume): New function. + (grub_xnu_boot): Use relocators. + * loader/i386/xnu_helper.S: Removed. + * loader/xnu.c (grub_xnu_heap_start): New variable. + (grub_xnu_heap_size): Likewise. + (grub_xnu_heap_malloc): Use relocators. + * loader/xnu_resume.c (grub_xnu_resume): Use relocators. + +2009-12-13 Vladimir Serbinenko + + * kern/i386/pc/startup.S (multiboot_entry): Setup stack before calling + anything. + +2009-12-13 Carles Pina i Estany + + * script/execute.c (grub_script_execute_cmdline): Set grub_errno to + GRUB_ERR_NONE before calling grub_env_set. + +2009-12-12 Robert Millan + + * gendistlist.sh (EXTRA_DISTFILES): Add `genvideolist.sh'. + * genmk.rb (video): New variable. + (CLEANFILES, VIDEOFILES): Add #{video}. + (#{video}): New target rule. + * genvideolist.sh: New file. + * Makefile.in (pkglib_DATA): Add video.lst. + (video.lst): New target rule. + * util/grub-mkconfig.in: Initialize ${GRUB_VIDEO_BACKEND} using + `video.lst'. + * util/grub.d/30_os-prober.in: Replace `vbe' with + ${GRUB_VIDEO_BACKEND}. + +2009-12-11 Robert Millan + + * THANKS: Add David Miller. + +2009-12-11 Vladimir Serbinenko + + libpciaccess support. + + * Makefile.in (LIBPCIACCESS): New variable. + (enable_grub_emu_pci): Likewise. + * conf/any-emu.rmk (grub_emu_SOURCES) [enable_grub_emu_pci]: Add + util/pci.c and commands/lspci.c. + (grub_emu_LDFLAGS) [enable_grub_emu_pci]: Add $(LIBPCIACCESS). + * configure.ac (grub-emu-pci): New option. + * include/grub/i386/pci.h (grub_pci_device_map_range): New function. + (grub_pci_device_unmap_range): Likewise. + * include/grub/pci.h [GRUB_UTIL]: Include grub/pciutils.h. + (grub_pci_device) [!GRUB_UTIL]: New structure. All users updated. + (grub_pci_address_t) [!GRUB_UTIL]: New type. + (grub_pci_device_t) [!GRUB_UTIL]: Likewise. + (grub_pci_get_bus) [!GRUB_UTIL]: New function. + (grub_pci_get_device) [!GRUB_UTIL]: Likewise. + (grub_pci_get_function) [!GRUB_UTIL]: Likewise. + * include/grub/pciutils.h: New file. + * util/pci.c: Likewise. + +2009-12-11 Felix Zielcke + + * util/misc.c: Don't include twice. + +2009-12-10 Felix Zielcke + + * disk/i386/pc/biosdisk.c (grub_biosdisk_open): Show the disk + name in an error message. + (grub_biosdisk_rw): Likewise. + +2009-12-10 Vladimir Serbinenko + + Eliminate NTFS 4Gib barrier. + + * fs/ntfs.c (read_attr): Use grub_disk_addr_t and grub_size_t. + (read_run_data): Likewise. + (grub_ntfs_read_run_list): Likewise. + (grub_ntfs_read_block): Likewise. + (grub_ntfs_iterate_dir): Likewise. + (read_mft): Likewise. + (read_data): Likewise. + Use COM_LOG_LEN. + * fs/ntfscomp.c (read_block): Cast ctx->target_vcn & 0xF to unsigned + to avoid 64-bit division + * include/grub/ntfs.h (COM_LOG_LEN): New definition. + (grub_ntfs_rlst): Use grub_disk_addr_t. + +2009-12-10 Vladimir Serbinenko + + Eliminate grub-fstest 4Gib barrier. + + * util/grub-fstest.c (skip, leng): Use grub_disk_addr_t. + (read_file): Fix error reporting. + +2009-12-10 Vladimir Serbinenko + + Eliminate hexdump 4Gib barrier. + + * commands/hexdump.c (grub_cmd_hexdump): Use grub_disk_addr_t. + * lib/arg.c (grub_arg_parse): Use grub_strtoull. + +2009-12-10 Vladimir Serbinenko + + * kern/device.c (grub_device_iterate): Ignore errors during first scan. + Fixes amarsh bug. + +2009-12-09 Bruce Dubbs + + Remove miscellaneous files in distclean target. + + * Makefile.in: Remove docs/{grub.info,version.texi,stamp-vti} + +2009-12-09 Colin Watson + + * util/grub-mkconfig_lib.in: Don't set grub_probe or grub_mkrelpath + if they're already set. This resolves the conflict between my + grub-install change on 2009-10-06 and Felix' change on 2009-11-11, + fixing the --grub-probe option again. + * util/sparc64/ieee1275/grub-install.in: Revert the last piece of my + change on 2009-10-06, so that we now once again source + `${libdir}/grub/grub-mkconfig_lib' after options have been parsed. + +2009-12-08 Robert Millan + + * conf/common.rmk [sparc64-ieee1275] (grub_mkdevicemap_SOURCES): Use + `util/ieee1275/ofpath.c' and `util/ieee1275/devicemap.c' instead of + `util/devicemap.c'. + +2009-12-08 Carles Pina i Estany + + * include/grub/misc.h (grub_printf_): New declaration. + * kern/misc.c (grub_printf_): New definition. + * normal/main.c (grub_normal_reader_init): Use `grub_printf_' and `N_' + instead of `grub_printf' and `_'. + * normal/menu_entry.c (store_completion): Likewise. + (run): Likewise. + (grub_menu_entry_run): Likewise. + * normal/menu_text.c (grub_wait_after_message): Likewise. + (notify_booting): Likewise. + (notify_fallback): Likewise. + (notify_execution_failure): Likewise. + +2009-12-07 Colin Watson + + * configure.ac: Check for vasprintf. + * util/misc.c (asprintf): Move allocation from here ... + (vasprintf): ... to here. New function. + (xasprintf): New function. + * include/grub/util/misc.h (vasprintf, xasprintf): Add + prototypes. + * util/getroot.c (grub_util_get_grub_dev): Use xasprintf. + * util/grub-mkfont.c (write_font): Likewise. + * util/grub-probe.c (probe): Likewise. + * util/hostdisk.c (make_device_name): Likewise. + +2009-12-06 David S. Miller + + * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Recognize + anything even prefixed with 'cdrom' as a cdrom. + +2009-12-06 Felix Zielcke + + * util/misc.c (make_system_path_relative_to_its_root): Correctly cope with + mount points. + +2009-12-05 Carles Pina i Estany + + * gettext/gettext.c: Include `'. Define grub_gettext_msg, + grub_gettext_msg_list. + (grub_gettext_gettranslation_from_position): Return const char * + and not char *. + (grub_gettext_translate): Add the translated strings into a list, + returns from the list if existing there. + (grub_gettext_init_ext): Add \n at the end of grub_dprintf string. + (grub_gettext_delete_list): Delete the list. + (grub_gettext_env_write_lang): Call grub_gettext_delete_list when + lang environment variable is changed. + (GRUB_MOD_FINI): Call grub_gettext_delete_list. + +2009-12-05 Vladimir Serbinenko + + Rename kernel.mod to kernel.img. + + * conf/i386-efi.rmk (pkglib_MODULES): Change kernel.mod to kernel.img. + (kernel_mod_EXPORTS): Rename to ... + (kernel_img_EXPORTS): ... this. + (kernel_mod_SOURCES): Rename to ... + (kernel_img_SOURCES): ... this. + (kernel_mod_HEADERS): Rename to ... + (kernel_img_HEADERS): ... this. All users updated. + (kernel_mod_CFLAGS): Rename to ... + (kernel_img_CFLAGS): ... this. + (kernel_mod_ASFLAGS): Rename to ... + (kernel_img_ASFLAGS): ... this. + (kernel_mod_LDFLAGS): Rename to ... + (kernel_img_LDFLAGS): ... this. + * conf/x86_64-efi.rmk: Likewise. + * util/i386/efi/grub-mkimage.c (read_kernel_module): Rename to ... + (read_kernel_image): ... this. All users updated. + (read_kernel_image): Read "kernel.img" instead of "kernel.mod". + +2009-12-05 Carles Pina i Estany + + * normal/menu_text.c (grub_color_menu_high): Gettexttize string. + (print_spaces): New function. + (grub_print_ucs4): New function. + (getstringwidth): New function. + (print_message_indented): New function. + (print_message): Gettexttize strings using print_message_indented. + (run_menu): Replaces grub_printf by print_spaces and dynamic terminal + width. + (get_entry_number): Gettextize and uses dynamic terminal width. + (notify_booting, notify_fallback, notify_execution_failure): + Gettextize. + * normal/menu_entry.c (store_completion): Cleanup the gettextized + string. + (run): Likewise. + (grub_menu_entry_run): Likewise. + * PO/POTFILES: Add normal/menu_entry.c. + +2009-12-05 Vladimir Serbinenko + + * configure.ac (TARGET_ASFLAGS): Add "-D". + +2009-12-05 Carles Pina i Estany + + * util/grub-install.in: Install gettext .mo files. + * util/grub-mkrescue.in (process_input_dir): Copy gettext .mo files. + +2009-12-05 Carles Pina i Estany + + * gettext/gettext.c (grub_gettext_init_ext): Replace grub_printf with + grub_dprintf. + +2009-12-05 Robert Millan + + * kern/ieee1275/openfw.c (grub_reboot): Disable for i386. The + non-firmware-dependant one in realmode.S takes precedence. + +2009-12-04 Robert Millan + + * commands/halt.c: Replace misc arch-specific headers with + `'. + * commands/reboot.c: Likewise. + * commands/i386/pc/halt.c: Replace `' with + `'. + * conf/i386-coreboot.rmk (kernel_img_HEADERS): Remove `cpu/reboot.h'. + (halt_mod_SOURCES): Move `kern/i386/halt.c' from here ... + (kernel_img_SOURCES): ... to here. + + * include/grub/efi/efi.h (grub_reboot, grub_halt): Remove prototypes. + * include/grub/i386/pc/init.h: Likewise. + * include/grub/powerpc/ieee1275/kernel.h: Likewise. + * include/grub/sparc64/ieee1275/kernel.h: Likewise. + + * include/grub/misc.h (grub_reboot, grub_halt): New prototypes. + + * include/grub/i386/halt.h: Remove. + * include/grub/i386/reboot.h: Likewise. + + * kern/i386/halt.c: Remove `'. + +2009-12-03 David S. Miller + + * conf/sparc64-ieee1275.rmk (grub_mkimage_SOURCES, + grub_setup_SOURCES, grub_ofpathname_SOURCES): Add gnulib/progname.c + * util/sparc64/ieee1275/grub-mkimage.c: Include and + "progname.h" + * util/sparc64/ieee1275/grub-ofpathname.c: Likewise. + * util/sparc64/ieee1275/grub-setup.c: Likewise. + (usage): Add missing comma in printf. + +2009-12-02 Robert Millan + + Use the same reboot approach on i386 coreboot and qemu as we do on + BIOS. + + * conf/i386-coreboot.rmk (kernel_img_HEADERS): Add `cpu/reboot.h'. + (reboot_mod_SOURCES): Remove `kern/i386/reboot.c'. + * kern/i386/reboot.c: Remove. + * include/grub/i386/reboot.h (grub_reboot): Export function. + * kern/i386/pc/startup.S (grub_reboot): Move from here ... + * kern/i386/realmode.S (grub_reboot): ... to here. Jump to + 0xf000:0xfff0 instead of 0xffff:0x0000. + [!GRUB_MACHINE_PCBIOS] (prot_to_real): Do not restore interrupts. + * kern/i386/qemu/startup.S: Include `"../realmode.S"'. + +2009-11-30 Robert Millan + + Fix $srcdir != $objdir build. + + * Makefile.in (po/%.po): Rewrite as ... + ($(foreach lang, $(LINGUAS), $(srcdir)/po/$(lang).po)): ... this. + +2009-11-29 Samuel Thibault + + Fix GNU/Hurd grub-install crash. + * util/grub-probe.c (probe): Try to access `path' only when it is not + NULL. + +2009-11-28 Vladimir Serbinenko + + Correct module naming. + + * video/efi_uga.c (GRUB_MOD_INIT(efi_fb)): Renamed from this ... + (GRUB_MOD_INIT(efi_uga)): ... to this + (GRUB_MOD_FINI(efi_fb)): Renamed from this ... + (GRUB_MOD_FINI(efi_uga)): ... to this + * video/efi_gop.c (GRUB_MOD_INIT(efi_fb)): Renamed from this ... + (GRUB_MOD_INIT(efi_gop)): ... to this + (GRUB_MOD_FINI(efi_fb)): Renamed from this ... + (GRUB_MOD_FINI(efi_gop)): ... to this + +2009-11-28 Robert Millan + + * util/mkisofs/mkisofs.c (ld_options): Mark all `arg' strings as + translatable. + (usage): Translate `arg' strings using gettext(). + Thanks to Jordi Mallach for the suggestion. + +2009-11-28 Vladimir Serbinenko + + GOP support. Based on patch from Bean + (http://lists.gnu.org/archive/html/grub-devel/2009-08/msg00384.html) + + * video/efi_gop.c: New file. + * include/grub/efi/graphics_output.h: Likewise. + * conf/i386-efi.rmk (pkglib_MODULES): Add `efi_gop.mod'. + (efi_fb_mod_SOURCES, efi_fb_mod_CFLAGS, efi_fb_mod_LDFLAGS): New + variables. + * conf/x86_64-efi.rmk: Likewise. + +2009-11-28 Vladimir Serbinenko + + Rename efi_fb to efi_uga. + + * conf/i386-efi.rmk (pkglib_MODULES): Rename 'efi_fb.mod' to + 'efi_uga.mod'. + (efi_fb_mod_SOURCES): Rename this ... + (efi_uga_mod_SOURCES): ... to this. + (efi_fb_mod_CFLAGS): Rename this ... + (efi_uga_mod_CFLAGS): ... to this. + (efi_fb_mod_LDFLAGS): Rename this ... + (efi_uga_mod_LDFLAGS): ... to this. + * conf/x86_64-efi.rmk (pkglib_MODULES): Rename 'efi_fb.mod' to + 'efi_uga.mod'. + (efi_fb_mod_SOURCES): Rename this ... + (efi_uga_mod_SOURCES): ... to this. + (efi_fb_mod_CFLAGS): Rename this ... + (efi_uga_mod_CFLAGS): ... to this. + (efi_fb_mod_LDFLAGS): Rename this ... + (efi_uga_mod_LDFLAGS): ... to this. + * video/efi_fb.c: Move this ... + * video/efi_uga.c: ... to this. Change prefix to 'grub_video_uga_'. + +2009-11-27 Robert Millan + + * po/README: New file. Explain our PO file workflow. + +2009-11-27 Robert Millan + + * po/ChangeLog: Remove. Move relevant entries back to ... + * ChangeLog: ... here. + * po/ca.po: Remove (now handled by TLP). + * po/id.po: Likewise. + * po/zh_CN.po: Likewise. + * Makefile.in (LINGUAS): Initialize in a way that supports + empty set. + +2009-11-27 Robert Millan + + * Makefile.in (LINGUAS): Rewrite by scanning po/ directory instead of + reliing on po/LINGUAS. + ($(foreach lang, $(LINGUAS), $(srcdir)/po/$(lang).po)): Rewrite as ... + (po/%.po): ... this. + +2009-11-26 Felix Zielcke + + * util/i386/efi/grub-mkimage.c: Include "progname.h". + (main): Use `program_name' instead of nonexistent `progname'. + +2009-11-26 Felix Zielcke + + * conf/i386-efi.rmk (grub_mkimage_SOURCES): Add `gnulib/progname.c'. + * conf/x86_64-efi.rmk (grub_mkimage_SOURCES): Likewise. + +2009-11-26 Robert Millan + + * conf/i386-coreboot.rmk: Cleanup stale filenames from my previous + commit. + * conf/i386-efi.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + +2009-11-26 Felix Zielcke + + * conf/any-emu.rmk (grub_emu_SOURCES): Add `gnulib/progname.c'. + +2009-11-26 Felix Zielcke + + * conf/any-emu.rmk (grub_mkfont_SOURCES): Add `gnulib/progname.c'. + +2009-11-26 Robert Millan + + * conf/common.rmk (sbin_UTILITIES): Add `grub-mkdevicemap'. + (grub_mkdevicemap_SOURCES): New variable. + (grub_probe_SOURCES, grub_fstest_SOURCES, grub_mkfont_SOURCES) + (grub_mkrelpath_SOURCES, grub_editenv_SOURCES) + (grub_pe2elf_SOURCES): Add `gnulib/progname.c'. + * conf/i386-coreboot.rmk (sbin_UTILITIES): Remove `grub-mkdevicemap'. + (grub_mkdevicemap_SOURCES): Remove. + * conf/i386-efi.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * util/elf/grub-mkimage.c: Include `' and `"progname.h"'. + (usage): Fix strings to use `program_name'. + (main): Initialize gettext. + * util/grub-editenv.c: Likewise. + * util/grub-emu.c: Likewise. + * util/grub-fstest.c: Likewise. + * util/grub-mkdevicemap.c: Likewise. + * util/grub-mkfont.c: Likewise. + * util/grub-mkrelpath.c: Likewise. + * util/grub-pe2elf.c: Likewise. + * util/grub-probe.c: Likewise. + * util/sparc64/ieee1275/grub-mkimage.c: Likewise. + * util/sparc64/ieee1275/grub-ofpathname.c: Likewise. + * util/sparc64/ieee1275/grub-setup.c: Likewise. + + * util/misc.c: Include `"progname.h"'. + (progname): Remove variable. + (grub_util_warn, grub_util_info, grub_util_error): Use `program_name'. + +2009-11-25 Felix Zielcke + + * util/grub.d/10_linux.in (linux_entry): Quote the arguments to + printf and print a newline after the menuentry header line. + * util/grub.d/10_kfreebsd.in (kfreebsd_entry): Likewise. + +2009-11-25 Felix Zielcke + + autoconf >= 2.60 support $(localedir). + + * INSTALL: Note that autoconf 2.60 is required. + * configure.ac (AC_PREREQ): Bump to 2.60. + * util/grub.d/10_kfreebsd.in (TEXTDOMAINDIR): Set to lowercased @localedir@. + * util/grub.d/10_linux.in (TEXTDOMAINDIR): Likewise. + +2009-11-25 Yves Blusseau + + * configure.ac: move the call to AM_GNU_GETTEXT to avoid warnings when + aclocal is run. + +2009-11-25 Robert Millan + + * normal/main.c (grub_normal_read_line): Fix off-by-one + buffer overflow. + +2009-11-25 Robert Millan + + * normal/main.c (grub_normal_execute): Replace "parser.sh" with + "parser.grub" in grub_command_execute() call. + +2009-11-24 Carles Pina i Estany + + * conf/i386-coreboot.rmk (kernel_img_HEADERS): Add i18n.h. + * conf/i386-efi.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * gettext/gettex.c: Include . + * include/grub/misc.h (grub_gettext_dummy, grub_gettext): Move from + here ... + * include/grub/i18n.h: ... to here + * include/grub/i18n.h: ... to here. + * kern/misc.c: Include + (grub_gettext_dummy): Move above user. + +2009-11-24 Felix Zielcke + + * util/Makefile.in (install-local): Convert a `for' into a normal + shell expansion. + +2009-11-24 Robert Millan + + * autogen.sh: Add automake call. + * config.guess: Remove. + * config.sub: Likewise. + * install-sh: Likewise. + +2009-11-24 Felix Zielcke + + * util/Makefile.in (install-local): Fix the use of $lang shell variable. + +2009-11-24 Felix Zielcke + + * util/Makefile.in (install-local): Convert a make `$(foreach)' + function to a normal shell `for'. + +2009-11-24 Felix Zielcke + + * conf/i386-coreboot.rmk (grub_mkimage_SOURCES): Add `gnulib/progname.c'. + +2009-11-24 Felix Zielcke + + * util/grub-mkrelpath.c: New file. + * conf/common.rmk (bin_UTILITIES): Add grub-mkrelpath. + (grub_mkrelpath_SOURCES): New variable. + * include/grub/util/misc.h: New function prototype. + * util/misc.c (make_system_path_relative_to_its_root): New function. + + * util/grub-mkconfig_lib.in (bindir): New variable. + (grub_mkrelpath): Likewise. + (make_system_path_relative_to_its_root): Use grub-mkrelpath. + + * util/probe.c (probe): Make the file path relative to its root. + Change a info message to use the GRUB path. Enable again the + check if we can read the file with GRUB facilities. + + * util/i386/pc/grub-setup.c (setup): Make core.img path relative + to its root. + +2009-11-24 Felix Zielcke + + * Makefile.in: Don't include GRUB_CONTRIB makefiles with emu + platform. + +2009-11-24 Felix Zielcke + + * util/getroot.c (grub_util_get_dev_abstraction): Properly use + strncmp(). + +2009-11-24 Felix Zielcke + + * util/getroot.c (grub_util_is_dmraid): New function. + (grub_util_get_dev_abstraction): Treat dmraid and multipath + devices as normal ones, not as LVM. + +2009-11-23 Carles Pina i Estany + + * conf/common.rmk: Add grub-gettext_lib target and updates + lib_DATA and CLEANFILES. Adds gettext.mod SOURCES, CFLAGS, + LDFLAGS. + * gettext/gettext.c: New file. (Reads mo files). + * include/grub/file.h (grub_file_pread): New prototype. + * include/grub/i18n.h (_): New prototype. + * include/grub/misc.h (grub_gettext_dummy, grub_gettext): New + prototypes. + * kern/misc.c (grub_gettext_dummy): New function. + * normal/menu_text.c: Include . + * normal/menu_text.c (print_timeout): Gettexttize string. + * normal/menu_text.c (print_message): Gettexttize string. + * po/POTFILES: Add `normal/menu_text.c'. + * po/ca.po: Add new translations. + * util/grub.d/00_header.in: Define locale_dir and lang. insmod + gettext module and defines locale_dir and lang in grub.cfg. + * NEWS: Add gettext support. + +2009-11-23 Robert Millan + + * util/hostdisk.c: Include `'. + (find_grub_drive): Use ARRAY_SIZE for map size calculation. + (make_device_name): Rewrite using asprintf. + (convert_system_partition_to_system_disk): Replace 0 with NULL. + (find_system_device): If a device is not found, generate one just + by reusing the OS path name. + (read_device_map): Make it permissible for device.map not to exist. + +2009-11-23 Robert Millan + + * script/sh/execute.c: Move from here ... + * script/execute.c: ... to here. Update all users. + * script/sh/function.c: Move from here ... + * script/function.c: ... to here. Update all users. + * script/sh/lexer.c: Move from here ... + * script/lexer.c: ... to here. Update all users. + * script/sh/main.c: Move from here ... + * script/main.c: ... to here. Update all users. + * script/sh/parser.y: Move from here ... + * script/parser.y: ... to here. Update all users. + * script/sh/script.c: Move from here ... + * script/script.c: ... to here. Update all users. + +2009-11-23 Robert Millan + + * configure.ac: Detect all `emu' platforms. Define + GRUB_MACHINE_* macros in TARGET_CFLAGS. Remove + --enable-grub-emu logic. Disable include/grub/machine + symlink on `emu' platforms. + + * genkernsyms.sh.in: Use @TARGET_CFLAGS@ during symbol generation. + * gensymlist.sh.in: Likewise. + + * include/grub/i386/coreboot/machine.h: Remove file. + * include/grub/i386/efi/machine.h: Likewise. + * include/grub/i386/ieee1275/machine.h: Likewise. + * include/grub/i386/pc/machine.h: Likewise. + * include/grub/i386/qemu/machine.h: Likewise. + * include/grub/powerpc/ieee1275/machine.h: Likewise. + * include/grub/sparc64/ieee1275/machine.h: Likewise. + * include/grub/x86_64/efi/machine.h: Likewise. + + * commands/acpi.c: Remove `'. + * commands/halt.c: Likewise. + * commands/reboot.c: Likewise. + * include/grub/autoefi.h: Likewise. + * include/grub/i386/at_keyboard.h: Likewise. + * include/grub/i386/kernel.h: Likewise. + * include/grub/i386/loader.h: Likewise. + * include/grub/i386/pc/memory.h: Likewise. + * kern/dl.c: Likewise. + * kern/i386/coreboot/init.c: Likewise. + * loader/i386/bsd.c: Likewise. + * loader/i386/linux.c: Likewise. + * loader/multiboot_loader.c: Likewise. + * term/i386/pc/serial.c: Likewise. + * term/usb_keyboard.c: Likewise. + + * include/grub/time.h [!GRUB_MACHINE_EMU]: Remove + `' + [!GRUB_MACHINE_EMU] (GRUB_TICKS_PER_SECOND): New macro. + * util/misc.c: Remove `' and + `'. + + * Makefile.in (enable_grub_emu): Remove variable. + Include $(srcdir)/conf/any-emu.mk for the `emu' platform. + + * conf/any-emu.rmk: New file. + * conf/common.rmk (grub_emu_init.lst, grub_emu_init.h) + (grub_emu_init.c): Move from here ... + * conf/any-emu.rmk: ... to here. + + * conf/i386-coreboot.rmk (sbin_UTILITIES): Remove `grub-emu'. + (grub_emu_SOURCES, grub_emu_LDFLAGS): Move from here ... + * conf/any-emu.rmk: ... to here. + +2009-11-23 Robert Millan + + * include/grub/parser.h (grub_parser_register): Document need + of `name' parameter. + * normal/main.c (grub_normal_read_line): Simplify prompt string. + * script/sh/main.c (grub_sh_parser, GRUB_MOD_INIT(sh)): Rename + "sh" to "grub". + +2009-11-23 Robert Millan + + * Makefile.in ($(srcdir)/po/$(PACKAGE).pot): Pass --keyword=N_ to + `$(XGETTEXT)'. + * include/grub/i18n.h (N_): New macro. + * util/mkisofs/mkisofs.h: Likewise. + * util/mkisofs/mkisofs.c (ld_options): Wrap all translatable strings + around N_(). + (usage): Use gettext() to translate help strings when printing them. + +2009-11-23 Robert Millan + + Based on patch from Bean + (http://lists.gnu.org/archive/html/grub-devel/2009-08/msg00384.html) + + * video/efi_fb.c: New file. + * conf/i386-efi.rmk (pkglib_MODULES): Add `efi_fb.mod'. + (efi_fb_mod_SOURCES, efi_fb_mod_CFLAGS, efi_fb_mod_LDFLAGS): New + variables. + * conf/x86_64-efi.rmk: Likewise. + +2009-11-22 Robert Millan + + * util/i386/pc/grub-mkimage.c: Ungettextize grub_util_info() strings. + * util/i386/pc/grub-setup.c: Likewise. + +2009-11-21 Samuel Thibault + + * util/getroot.c [__GNU__]: Include , , and + + [__GNU__] (grub_guess_root_device): Call file_name_lookup and + file_get_storage_info to implement grub_guess_root_device. + +2009-11-21 Felix Zielcke + + * Makefile.in (target): Use make's builtin $(shell) function + instead of calling directly $(SHELL) to create the locale directories, + inside the $(foreach) function. + +2009-11-21 Felix Zielcke + + * util/grub-mkrescue.in: Print an error and usage if output option + has not been given. + +2009-11-21 Felix Zielcke + + Patch from LoĂ¯c Minier . + * util/grub.d/30_os-prober.in: Cope with Linux entries where + root and /boot are on different devices. + +2009-11-21 Robert Millan + + Fix build for srcdir != objdir. + + * Makefile.in (po/$(PACKAGE).pot): Rename to ... + ($(srcdir)/po/$(PACKAGE).pot): ... this. Run $(XGETTEXT) from + $(srcdir). + ($(foreach lang, $(LINGUAS), po/$(lang).po)): Rename to ... + ($(foreach lang, $(LINGUAS), $(srcdir)/po/$(lang).po): ... this. Use $^ + reference for input. + +2009-11-21 Robert Millan + + * util/grub-mkrescue.in: Use source directory direcly (without copiing + or hardlinking it). Remove -J option, Joliet is not compatible with + multiple source directories. + +2009-11-21 Carles Pina i Estany +2009-11-21 Robert Millan + + * util/grub-mkrescue.in: Recognize `--override-directory' option. + (process_input_dir): New function. Process an arbitrary input + directory. + Misc adjustments to support both "override mode" and system-wide mode. + +2009-11-20 Felix Zielcke + + * configure.ac (UNIFONT_BDF): Rename to ... + (FONT_SOURCE): ... this. Update all users. + +2009-11-20 Felix Zielcke + + * configure.ac: Add `/usr/share/fonts/X11/misc/unifont.pcf.gz' + to the list of unifont files to look for. + +2009-11-19 Robert Millan + + Patch from Joe Auricchio + * commands/minicmd.c (grub_mini_cmd_clear): New function. + (GRUB_MOD_INIT(minicmd)): Register grub_mini_cmd_clear(). + (GRUB_MOD_FINI(minicmd)): Unregister grub_mini_cmd_clear(). + +2009-11-19 Felix Zielcke + + * Makefile.in (install-local): Add a missing backslash. + +2009-11-19 Felix Zielcke + + * include/grub/x86_64/io.h: New file. + +2009-11-19 Robert Millan + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add `gnulib/progname.c'. + * util/i386/pc/grub-setup.c: Include `'. + Include `"progname.h"'. + (main): Initialize gettext. + * util/i386/pc/grub-setup.c: Gettexttize. + * util/i386/pc/grub-mkimage.c: Likewise. + + * Makefile.in (po/*.po): Redefine as ... + ($(foreach lang, $(LINGUAS), po/$(lang).po)): ... this. + + * po/POTFILES: Add `util/i386/pc/grub-setup.c'. + +2009-11-19 Robert Millan + + * conf/common.rmk (grub_mkisofs_SOURCES): Add `gnulib/progname.c'. + * util/mkisofs/mkisofs.c: Include `"progname.h"'. + (program_name): Remove. + (main): Initialize gettext support. + * util/mkisofs/mkisofs.h: Include `'. + Include `'. + (_): New macro. + + * util/mkisofs/eltorito.c: Gettexttize. + * util/mkisofs/joliet.c: Likewise. + * util/mkisofs/mkisofs.c: Likewise. + * util/mkisofs/multi.c: Likewise. + * util/mkisofs/rock.c: Likewise. + * util/mkisofs/tree.c: Likewise. + * util/mkisofs/write.c: Likewise. + + * po/POTFILES: Update with new files. + +2009-11-18 Robert Millan + + * util/mkisofs/eltorito.c: Fix minor mistake in license text. + * util/mkisofs/iso9660.h: Likewise. + * util/mkisofs/joliet.c: Likewise. + * util/mkisofs/mkisofs.c: Likewise. + * util/mkisofs/mkisofs.h: Likewise. + * util/mkisofs/rock.c: Likewise. + * util/mkisofs/tree.c: Likewise. + * util/mkisofs/write.c: Likewise. + + * util/mkisofs/eltorito.c (rcsid): Remove. + * util/mkisofs/hash.c: Likewise. + * util/mkisofs/joliet.c: Likewise. + * util/mkisofs/name.c: Likewise. + * util/mkisofs/rock.c: Likewise. + * util/mkisofs/tree.c: Likewise. + * util/mkisofs/write.c: Likewise. + +2009-11-18 Robert Millan + + * util/mkisofs/match.c: Rewrite from scratch, using a linked list + instead of static allocation. + * util/mkisofs/match.h: Likewise. + +2009-11-18 Robert Millan + + * po/POTFILES-shell: New file. List `util/grub.d/10_kfreebsd.in' + and `util/grub.d/10_linux.in'. + * Makefile.in (po/$(PACKAGE).pot): Process `po/POTFILES-shell' for + translatable Shell files. + +2009-11-18 Robert Millan + + * Makefile.in ($(srcdir)/aclocal.m4): New target. + +2009-11-17 Robert Millan + + * INSTALL: Document Automake is needed for bootstrap. + * po/ca.po: Fix PO-Revision-Date and Language-Team fields. + * util/grub.d/10_kfreebsd.in (bindir): New variable. + Add gettext initialization. + (kfreebsd_entry): Make menuentry output translatable. + +2009-11-17 Robert Millan + + * Makefile.in (XGETTEXT, MSGMERGE, MSGFMT): New variables. + (po/$(PACKAGE).pot): Replace `xgettext' with `$(XGETTEXT)'. + (po/*.po): Replace `msgmerge' with `$(MSGMERGE)'. + (po/%.mo): Replace `msgfmt' with `$(MSGFMT)'. + (LINGUAS): Auto-generate using `po/LINGUAS'. + * po/LINGUAS: New file. + +2009-11-17 Robert Millan + + * configure.ac: Call AM_GNU_GETTEXT() (defines localedir, among + other things). + * Makefile.in (CPPFLAGS): Add `-DLOCALEDIR=\"$(localedir)\"'. + * util/i386/pc/grub-mkimage.c (main): Issue setlocale() and + bindtextdomain() calls for gettext initialization. + +2009-11-17 Robert Millan + + * gnulib/progname.c: New file (imported from Gnulib). + * gnulib/progname.h: Likewise. + * conf/i386-pc.rmk (grub_mkimage_SOURCES): Add `gnulib/progname.c'. + * util/i386/pc/grub-mkimage.c: Include `"progname.h"'. + (usage): Replace `progname' with `program_name'. + (main): Use set_program_name() for program name initialization. + +2009-11-17 Robert Millan + + * conf/common.rmk (grub_mkisofs_CFLAGS): Move `-I$(srcdir)/gnulib' + from here ... + * Makefile.in (CPPFLAGS): ... to here. + +2009-11-16 Robert Millan + + * aclocal.m4: Move from here ... + * acinclude.m4: ... to here. + * autogen.sh: Add call to `aclocal'. + * configure.ac: Add AM_INIT_AUTOMAKE() after AC_INIT() call. + +2009-11-16 Robert Millan + + * Makefile.in (CLEANFILES): Add `po/*.mo'. + (LINGUAS): New variable. + (all-local): Add `$(foreach lang, $(LINGUAS), po/$(lang).mo)'. + (install-local): Install MO files. + (po/$(PACKAGE).pot, po/*.po, po/%.mo): New rules. + * include/grub/i18n.h: New file. + * po/POTFILES: New file. + * po/ca.po: New file. + * util/grub.d/10_linux.in (bindir): New variable. + Add gettext initialization. + (linux_entry): Make menuentry output translatable. + * util/i386/pc/grub-mkimage.c: Include `'. + (usage): Make --help output translatable. + (main): Initialize gettext. + +2009-11-17 Robert Millan + + * import_gcry.py: New file (written by Vladimir with minor + adjustments). + * autogen.sh: Use import_gcry.py to auto-generate GRUB-ified + ciphers. + * INSTALL: Document that Python is required for bootstrap. + +2009-11-17 Robert Millan + + Import ciphers from libgcrypt 1.4.4. + + * lib/libgcrypt/cipher/ChangeLog + * lib/libgcrypt/cipher/ac.c + * lib/libgcrypt/cipher/arcfour.c + * lib/libgcrypt/cipher/bithelp.h + * lib/libgcrypt/cipher/blowfish.c + * lib/libgcrypt/cipher/camellia-glue.c + * lib/libgcrypt/cipher/camellia.c + * lib/libgcrypt/cipher/camellia.h + * lib/libgcrypt/cipher/cast5.c + * lib/libgcrypt/cipher/cipher.c + * lib/libgcrypt/cipher/crc.c + * lib/libgcrypt/cipher/des.c + * lib/libgcrypt/cipher/dsa.c + * lib/libgcrypt/cipher/ecc.c + * lib/libgcrypt/cipher/elgamal.c + * lib/libgcrypt/cipher/hash-common.c + * lib/libgcrypt/cipher/hash-common.h + * lib/libgcrypt/cipher/hmac-tests.c + * lib/libgcrypt/cipher/md.c + * lib/libgcrypt/cipher/md4.c + * lib/libgcrypt/cipher/md5.c + * lib/libgcrypt/cipher/primegen.c + * lib/libgcrypt/cipher/pubkey.c + * lib/libgcrypt/cipher/rfc2268.c + * lib/libgcrypt/cipher/rijndael-tables.h + * lib/libgcrypt/cipher/rijndael.c + * lib/libgcrypt/cipher/rmd.h + * lib/libgcrypt/cipher/rmd160.c + * lib/libgcrypt/cipher/rsa.c + * lib/libgcrypt/cipher/seed.c + * lib/libgcrypt/cipher/serpent.c + * lib/libgcrypt/cipher/sha1.c + * lib/libgcrypt/cipher/sha256.c + * lib/libgcrypt/cipher/sha512.c + * lib/libgcrypt/cipher/tiger.c + * lib/libgcrypt/cipher/twofish.c + * lib/libgcrypt/cipher/whirlpool.c + +2009-11-16 Robert Millan + + Fix build for systems without error(). + + * gnulib/error.c: New file (imported from Gnulib). + * gnulib/error.h: Likewise. + * conf/common.rmk (grub_mkisofs_SOURCES): Add `gnulib/error.c'. + * util/mkisofs/mkisofs.c (program_name): Remove `static' qualifier + (this variable is now used by error()). + +2009-11-16 Felix Zielcke + + * util/mkisofs/name.c (iso9660_file_length): Use isascii macro + instead of relying that char is signed. + +2009-11-16 Vladimir Serbinenko + + * fs/i386/pc/pxe.c (grub_pxefs_open): Correctly handle PXE choosing + blocksize different from specified. + (grub_pxefs_read): Likewise. + +2009-11-16 Felix Zielcke + + Enable ata.mod on x86_64-efi, i386-efi and i386-ieee1275. + + * disk/ata.c (grub_ata_dumpinfo): Add a cast. + (grub_ata_readwrite): Likewise. Update 2 format strings. + (grub_atapi_read): Likewise. + + * conf/i386-coreboot.rmk (pkglib_MODULES): Move `ata.mod' from here ... + * conf/i386.rmk (pkglib_MODULES): ... to here ... + * conf/x86_64-efi.rmk (pkglib_MODULES): ... and here. + * conf/i386-coreboot.rmk (ata_mod_SOURCES, ata_mod_CFLAGS) + (ata_mod_LDFLAGS): Move from here ... + * conf/i386.rmk: ... to here ... + * conf/x86_64-efi.rmk: ... and here. + * conf/i386-pc.rmk (pkglib_MODULES): Remove `ata.mod' + (ata_mod_SOURCES, ata_mod_CFLAGS, ata_mod_LDFLAGS): Remove. + +2009-11-16 Robert Millan + + Relicense multiboot.h, with RMS' blessing. + + * include/multiboot.h: Change to X11 license. + +2009-11-15 Robert Millan + + Support --version in grub-mkisofs. + + * util/mkisofs/mkisofs.c (rcsid): Remove variable. + (OPTION_VERSION): New macro. + (ld_options): Recognize --version. + (usage): Move `program_name' from here ... + (program_name): ... to here. Add `static' qualifier. + (main): Recognize `OPTION_VERSION'. + +2009-11-15 Felix Zielcke + + * Makefile.in (TARGET_CPPFLAGS): Replace `-isystem=$(srcdir)/include' + with `-nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include)'. + +2009-11-14 Robert Millan + + Fix help2man generation for mkisofs. + + * util/mkisofs/mkisofs.c (ld_options): Recognize --help. + (usage): Send output to stdout (rather than stderr). + +2009-11-14 Robert Millan + + * conf/i386-coreboot.rmk (grub_mkrescue_SOURCES): Replace + `util/i386/coreboot/grub-mkrescue.in' with `util/grub-mkrescue.in'. + * conf/i386-pc.rmk (grub_mkrescue_SOURCES): Replace + `util/i386/pc/grub-mkrescue.in' with `util/grub-mkrescue.in'. + (bin_SCRIPTS): Add `grub-mkfloppy'. + (grub_mkfloppy_SOURCES): New variable. + + * util/grub-mkrescue.in: New file. + * util/i386/pc/grub-mkfloppy.in: New file. + + * util/i386/coreboot/grub-mkrescue.in: Remove. + * util/i386/pc/grub-mkrescue.in: Remove. + +2009-11-13 Robert Millan + + * include/grub/multiboot.h (struct grub_multiboot_header): Move + from here ... + * include/multiboot.h (struct multiboot_header): ... to here. Update + all users. + * include/grub/multiboot.h (struct grub_multiboot_info): Move + from here ... + * include/multiboot.h (struct multiboot_info): ... to here. Update + all users. + * include/grub/multiboot.h (struct grub_multiboot_mmap_entry): Move + from here ... + * include/multiboot.h (struct multiboot_mmap_entry): ... to here. + Update all users. + * include/grub/multiboot.h (struct grub_mod_list): Move + from here ... + * include/multiboot.h (struct multiboot_mod_list): ... to here. + Update all users. + +2009-11-13 Robert Millan + + * include/multiboot2.h (multiboot_word): Rename from this ... + (multiboot2_word): ... to this. Update all users. + (multiboot_header): Rename from this ... + (multiboot2_header): ... to this. Update all users. + (multiboot_tag_header): Rename from this ... + (multiboot2_tag_header): ... to this. Update all users. + (multiboot_tag_start): Rename from this ... + (multiboot2_tag_start): ... to this. Update all users. + (multiboot_tag_name): Rename from this ... + (multiboot2_tag_name): ... to this. Update all users. + (multiboot_tag_module): Rename from this ... + (multiboot2_tag_module): ... to this. Update all users. + (multiboot_tag_memory): Rename from this ... + (multiboot2_tag_memory): ... to this. Update all users. + (multiboot_tag_unused): Rename from this ... + (multiboot2_tag_unused): ... to this. Update all users. + (multiboot_tag_end): Rename from this ... + (multiboot2_tag_end): ... to this. Update all users. + +2009-11-13 Robert Millan + + Disable Multiboot2 in i386-ieee1275. It didn't actually work, and on + this platform we should support Multiboot1 first. + + * conf/i386-ieee1275.rmk (pkglib_MODULES): Remove `multiboot.mod'. + (multiboot_mod_SOURCES, multiboot_mod_CFLAGS) + (multiboot_mod_LDFLAGS, multiboot_mod_ASFLAGS): Remove. + +2009-11-12 Robert Millan + + * util/mkisofs/eltorito.c (init_boot_catalog): Handle return code + of write calls (converting them to fwrite() if they aren't already). + (get_torito_desc): Likewise. + * util/mkisofs/rock.c (generate_rock_ridge_attributes): Likewise. + +2009-11-12 Robert Millan + + * util/i386/pc/grub-install.in: Move from here ... + * util/grub-install.in: ... to here. Update all users. + +2009-11-11 Colin Watson + + * util/powerpc/ieee1275/grub-mkrescue.in: Fix --version output. + +2009-11-11 Robert Millan + + Support for El Torito without floppy emulation. + + * util/mkisofs/eltorito.c: Include `'. + (init_boot_catalog): Improve error handling. + (get_torito_desc): Don't use floppy emulation unless requested by + user. Patch boot information table when requested via + `-boot-info-table'. + * util/mkisofs/iso9660.h (struct eltorito_boot_info): New struct. + * util/mkisofs/mkisofs.c (use_eltorito_emul_floppy) + (use_boot_info_table): New variables. + (OPTION_BOOT_INFO_TABLE, OPTION_NO_EMUL_BOOT) + (OPTION_ELTORITO_EMUL_FLOPPY): New macros. + (ld_options): Handle `-boot-info-table', `-no-emul-boot' and + `--eltorito-emul-floppy'. + (main): Handle `OPTION_BOOT_INFO_TABLE', `OPTION_NO_EMUL_BOOT' + and `OPTION_ELTORITO_EMUL_FLOPPY'. + * util/mkisofs/mkisofs.h (use_eltorito_emul_floppy) + (use_boot_info_table, get_731): New prototypes. + * util/mkisofs/write.c (get_731): New function. + +2009-11-11 Felix Zielcke + + Fix the generation of the man page. + + * util/pc/i386/grub-install.in: Source + `${libdir}/grub/grub-mkconfig_lib' after options have been parsed. + +2009-11-11 Robert Millan + + Large file support for grub-mkisofs. + + * conf/common.rmk (grub_mkisofs_CFLAGS): Add `-D_FILE_OFFSET_BITS=64'. + * util/mkisofs/mkisofs.c (next_extent, last_extent) + (session_start): Upgrade type to `uint64_t'. Update all users. + * util/mkisofs/mkisofs.h: Include `'. + (struct directory_entry): Upgrade type of `starting_block' and + `size' to `uint64_t'. Update all users. + (struct deferred): Remove unused structure. + (xfwrite): Upgrade type of `count' and `size' to `uint64_t'. + Update all users. + * util/mkisofs/tree.c (stat_filter, lstat_filter): Return -1 when + file is larger than `UINT32_MAX'. + * util/mkisofs/write.c (xfwrite): Upgrade type of `count' and + `size' to `uint64_t'. Update all users. Fix handling of fwrite() + return value. + (struct deferred_write): Upgrade type of `extent' and `size' to + `uint64_t'. Update all users. + (last_extent_written): Upgrade type to `uint64_t'. Update all + users. + (write_one_file): Upgrade type of `count' and `size' to `uint64_t'. + Update all users. Upgrade type of `remain' to `int64_t' and + `use' to `size_t'. Use error() to handle fread() errors. + (write_files): Rely on write_one_file() rather than calling + xfwrite() directly. + +2009-11-09 Felix Zielcke + + * util/mkisofs/mkisofs.c (ld_options): Fix a spelling mistake. + +2009-11-09 Robert Millan + + * util/mkisofs/fnmatch.c: Remove. + * util/mkisofs/getopt1.c: Likewise. + * util/mkisofs/getopt.c: Likewise. + * conf/common.rmk (grub_mkisofs_SOURCES): Replace + `util/mkisofs/fnmatch.c', `util/mkisofs/getopt1.c' and + `util/mkisofs/getopt.c' with `gnulib/fnmatch.c', + `gnulib/getopt1.c' and `gnulib/getopt.c'. + (grub_mkisofs_CFLAGS): Add `-I$(srcdir)/gnulib'. + + * configure.ac: Detect `mingw32msvc' host_os. + Check for lstat(), getuid() and getgid(). + + * util/mkisofs/joliet.c: Include `'. Replace all + instances of `u_char' with `uint8_t'. + + * util/mkisofs/mkisofs.h: Include `'. + [!HAVE_GETUID] (getuid): New function (stub). + [!HAVE_GETGID] (getgid): Likewise. + [!HAVE_LSTAT] (lstat): Likewise. + [!S_IROTH] (S_IROTH): New macro (dummy). + [!S_IRGRP] (S_IRGRP): Likewise. + +2009-11-09 Robert Millan + + * gnulib/fnmatch_loop.c (EXT): Fix warning (signed and unsigned type in + conditional expression). + +2009-11-09 Robert Millan + + Import from Gnulib. + + * gnulib/fnmatch.c: New file. + * gnulib/fnmatch.h: Likewise. + * gnulib/fnmatch_loop.c: Likewise. + * gnulib/getopt.c: Likewise. + * gnulib/getopt.h: Likewise. + * gnulib/getopt1.c: Likewise. + * gnulib/getopt_int.h: Likewise. + * gnulib/gettext.h: Likewise. + +2009-11-09 Robert Millan + + * normal/dyncmd.c (read_command_list): Replace `0' with `NULL'. + * normal/handler.c (read_handler_list): Likewise. + +2009-11-09 Robert Millan + + Misc cleanup. + + * kern/command.c (grub_register_command_prio): Use + grub_zalloc() instead of explicitly zeroing data. + * kern/list.c: Include `'. + (grub_named_list_find): Replace `0' with `NULL'. + * normal/autofs.c (struct grub_fs_module_list): Remove ad-hoc type. + (fs_module_list): Change type to `grub_named_list_t'. Update all + users. + * normal/dyncmd.c (read_command_list): Add space between function + call and parenthesis. + * normal/handler.c (read_handler_list): Likewise. + +2009-11-09 Robert Millan + + * normal/auth.c (punishment_delay): Moved from here ... + (grub_auth_strcmp): ... to here (inside function). + +2009-11-09 Robert Millan + + * include/grub/list.h (struct grub_named_list): Remove `const' + qualifier from `name'. + (struct grub_prio_list): Likewise. + +2009-11-09 Robert Millan + + * normal/auth.c: Include `'. + (grub_auth_strcmp): Replace `strcmp' with `grub_strcmp'. + +2009-11-09 Robert Millan + + * normal/auth.c (punishment_delay): New variable. + (grub_auth_strcmp): Rewrite using grub_get_time_ms (). + (grub_auth_check_authentication): Punish failed login attempts with + an incremental (2^N) delay. + +2009-11-09 Robert Millan + + * conf/common.rmk (grub_mkisofs_CFLAGS): Prefix include + path with $(srcdir). + +2009-11-09 Vladimir Serbinenko + + * normal/auth.c (grub_auth_strcmp): Fixed incorrect variable usage. + +2009-11-09 Robert Millan + + * util/i386/coreboot/grub-mkrescue.in: New file. + * conf/i386-coreboot.rmk (bin_SCRIPTS, grub_mkrescue_SOURCES): New + variables. + + * conf/common.rmk (bin_UTILITIES): Add `grub-mkisofs'. + (grub_mkisofs_SOURCES, grub_mkisofs_CFLAGS): New variables. + * configure.ac: Add header and function checks to satisfy grub-mkisofs + requirements. + * util/mkisofs/defaults.h: New file. + * util/mkisofs/eltorito.c: Likewise. + * util/mkisofs/exclude.h: Likewise. + * util/mkisofs/fnmatch.c: Likewise. + * util/mkisofs/getopt.c: Likewise. + * util/mkisofs/getopt1.c: Likewise. + * util/mkisofs/hash.c: Likewise. + * util/mkisofs/include/fctldefs.h: Likewise. + * util/mkisofs/include/mconfig.h: Likewise. + * util/mkisofs/include/prototyp.h: Likewise. + * util/mkisofs/include/statdefs.h: Likewise. + * util/mkisofs/iso9660.h: Likewise. + * util/mkisofs/joliet.c: Likewise. + * util/mkisofs/match.c: Likewise. + * util/mkisofs/match.h: Likewise. + * util/mkisofs/mkisofs.c: Likewise. + * util/mkisofs/mkisofs.h: Likewise. + * util/mkisofs/multi.c: Likewise. + * util/mkisofs/name.c: Likewise. + * util/mkisofs/rock.c: Likewise. + * util/mkisofs/tree.c: Likewise. + * util/mkisofs/write.c: Likewise. + +2009-11-09 Vladimir Serbinenko + + * normal/auth.c (grub_auth_strcmp): Fix bug which resulted in function + being insecure. + +2009-11-08 Robert Millan + + * util/i386/pc/grub-mkrescue.in: Fix miss-identification as + `grub-mkimage' (and use $0 when possible). + +2009-11-08 Robert Millan + + * kern/i386/multiboot_mmap.c (grub_machine_mmap_init): Improve + error message for excessively large memory map. + +2009-11-08 Robert Millan + + * autogen.sh: Use `sh gendistlist.sh' to avoid reliing on + executable bit. + +2009-11-08 Robert Millan + + * kern/i386/multiboot_mmap.c (grub_machine_mmap_init): Improve error + message for coreboot users. + +2009-11-07 Robert Millan + + Fix build with GNU gold. + + * conf/i386-pc.rmk (boot_img_LDFLAGS, pxeboot_img_LDFLAGS) + (diskboot_img_LDFLAGS, lnxboot_img_LDFLAGS) + (cdboot_img_LDFLAGS): Prepend `0x' qualifier to hexadecimal + link addresses. + * aclocal.m4: Likewise. + +2009-11-04 Felix Zielcke + + * configure.ac (AC_PREREQ): Bump to 2.59d. + * INSTALL: Make it more clear when Autoconf and Ruby are + needed and when to run `./autogen.sh'. + +2009-11-03 Samuel Thibault + + * util/grub.d/30_os-prober.in: Restore default behavior for unsupported + OSes. + +2009-11-02 Samuel Thibault + + * util/grub.d/30_os-prober.in: Add GNU/Hurd support + +2009-11-02 Samuel Thibault + + * util/grub.d/10_hurd.in: Drop /dev/ prefix from root device path before + giving it to GNU Mach. + +2009-11-02 Samuel Thibault + + * util/hostdisk.c (grub_util_biosdisk_get_grub_dev): Subtract 1 from + GNU partition number to get internal GRUB partition number. + +2009-11-02 Samuel Thibault + + * util/grub.d/10_hurd.in: Call prepare_grub_to_access_device + ${GRUB_DEVICE_BOOT} before loading /boot kernel. + +2009-11-01 Robert Millan + + Based on patch from BVK Chaitanya + * kern/misc.c (grub_strchr, grub_strrchr): Fix to handle c == '\0' + case. + +2009-11-01 Felix Zielcke + + * Makefile.in (TARGET_CPPFLAGS): Add `-I$(srcdir)/include'. + +2009-10-30 Robert Millan + + Fix build problem. + + * Makefile.in (TARGET_CPPFLAGS): Replace `-nostdinc' with + `-isystem=$(srcdir)/include'. + +2009-10-30 Robert Millan + + * util/i386/pc/grub-install.in: Remove hint that device.map should be + checked (grub-install doesn't currently rely on it). + +2009-10-29 Robert Millan + + Revert SVN r2660. + + * conf/common.rmk (script/sh/lexer.c_DEPENDENCIES): Moved from here ... + * conf/i386-coreboot.rmk (script/sh/lexer.c_DEPENDENCIES): ... to here. + * conf/i386-efi.rmk (script/sh/lexer.c_DEPENDENCIES): ... and here. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + +2009-10-28 Robert Millan + + * Makefile.in (TARGET_CPPFLAGS): Add `-nostdinc'. + +2009-10-28 Robert Millan + + * include/grub/misc.h: Stop checking for APPLE_CC. + +2009-10-28 Robert Millan + + * kern/i386/coreboot/init.c (grub_exit): Reimplement in a way that + doesn't cause an infinite call loop. + +2009-10-28 Felix Zielcke + + * commands/acpi.c (grub_cmd_acpi): Fix the out of memory error + strings. + +2009-10-26 Robert Millan + + * autogen.sh: Support addition of external modules via `GRUB_CONTRIB' + variable. + * Makefile.in: Likewise. + +2009-10-26 Robert Millan + + * gendistlist.sh: Simplify .svn check. Skip .bzr as well. + +2009-10-26 Robert Millan + + * Makefile.in (RMKFILES): Rewrite using $(wildcard). + +2009-10-26 Robert Millan + + * disk/scsi.c: Remove `' (not needed). + +2009-10-26 Robert Millan + + * gensymlist.sh.in (COMPILE_TIME_ASSERT): Copy macro declaration + from here ... + * include/grub/misc.h (COMPILE_TIME_ASSERT): ... to here. + +2009-10-26 Robert Millan + + * Makefile.in (docs/grub.info): Use make syntax to ignore errors + in $(MAKEINFO) invocation. This makes it clear in output that + errors are being ignored. + +2009-10-26 Robert Millan + + * conf/i386-coreboot.rmk (script/sh/lexer.c_DEPENDENCIES): Moved + from here ... + * conf/common.rmk (script/sh/lexer.c_DEPENDENCIES): ... to here. + * conf/i386-efi.rmk (script/sh/lexer.c_DEPENDENCIES): Remove. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + +2009-10-26 Colin Watson + + * util/grub-editenv.c (main): If only a command is given, use + DEFAULT_DIRECTORY "/" GRUB_ENVBLK_DEFCFG as a default file name. + (usage): FILENAME is now optional and has a default. + +2009-10-26 Colin Watson + + Improve grub-mkconfig performance when there are several menu + entries on a single filesystem. + + * util/grub.d/10_linux.in (linux_entry): Cache the output of + prepare_grub_to_access_device. + * util/grub.d/10_kfreebsd.in (kfreebsd_entry): Likewise. + * util/grub.d/30_os-prober.in: Likewise. + +2009-10-26 Robert Millan + + * util/grub.d/10_freebsd.in: Remove. + * util/grub.d/10_kfreebsd.in: New file (based on 10_linux.in). + * configure.ac: Set host_kernel=kfreebsd for FreeBSD and GNU/kFreeBSD. + +2009-10-26 Robert Millan + + * docs/grub.cfg: Fix example usage of *BSD loaders. + +2009-10-25 Robert Millan + + * util/i386/pc/grub-setup.c (setup): Add missing parameter to + grub_util_error() call. + +2009-10-25 Robert Millan + + * include/grub/fs.h [GRUB_UTIL] (struct grub_fs): Add + `reserved_first_sector' member. + * fs/ext2.c [GRUB_UTIL] (grub_ext2_fs): Initialize + `reserved_first_sector' to 1. + * fs/fat.c [GRUB_UTIL] (grub_fat_fs): Likewise. + * fs/ntfs.c [GRUB_UTIL] (grub_ntfs_fs): Likewise. + * fs/hfsplus.c [GRUB_UTIL] (grub_hfsplus_fs): Likewise. + * util/i386/pc/grub-setup.c (setup): Add safety check that probes for + filesystems which begin at first sector. + (options): New option --skip-fs-probe. + (main): Handle --skip-fs-probe and pass it to setup(). + +2009-10-25 Robert Millan + + * include/grub/misc.h: Fix wrong evaluation of APPLE_CC. + (memset): Fix function prototype. + +2009-10-25 Robert Millan +2009-10-25 Vasily Averin + + * fs/ext2.c (grub_ext2_iterate_dir): Avoid infinite loop when + `dirent.direntlen == 0'. + +2009-10-25 Robert Millan + + * fs/cpio.c [MODE_USTAR]: Initialize `tar' module instead of + `cpio'. + [! MODE_USTAR]: Initialize `cpio' module instead of `tar'. + +2009-10-25 Robert Millan + + * configure.ac: Check for `__ashldi3', `__ashrdi3', `__lshrdi3', + `__trampoline_setup' and `__ucmpdi2'. + * include/grub/powerpc/libgcc.h: Only export symbols for functions + that libgcc provides. + +2009-10-25 Robert Millan + + * include/grub/powerpc/libgcc.h (memset): Remove function prototype. + * include/grub/sparc64/libgcc.h (memset): Likewise. + * include/grub/misc.h (memset, memcmp): New function prototypes. + +2009-10-25 Robert Millan + + * fs/cpio.c [MODE_USTAR]: Finish `tar' module instead of + `cpio'. + [! MODE_USTAR]: Finish `cpio' module instead of `tar'. + +2009-10-25 Robert Millan + + Patch from Samuel Thibault + * docs/grub.cfg: Compensate for recent change in multiboot + loader (since 2009-08-14 it won't pass filename to payload). + * util/grub.d/10_hurd.in: Likewise. + +2009-10-21 Felix Zielcke + + * config.guess: Update to latest version from config git + repository. + * config.sub: Likewise. + +2009-10-20 Robert Millan + + Fix build on sparc64. + + * configure.ac: Perform checks for libgcc symbols before + adding `-nostdlib' to LDFLAGS. + +2009-10-16 Vladimir Serbinenko + + Let user specify OpenBSD root device. + + * loader/i386/bsd.c (openbsd_root): New variable. + (openbsd_opts): New option 'root'. + (OPENBSD_ROOT_ARG): New macro. + (grub_openbsd_boot): Use 'openbsd_root'. + (grub_cmd_openbsd): Fill 'openbsd_root'. + +2009-10-16 Robert Millan + + * NEWS: Misc adjustments. + +2009-10-16 Vladimir Serbinenko + + * NEWS: Mentioned XNU, ACPI, gptsync, password and parttool. + +2009-10-16 Robert Millan + + * configure.ac: Bump version to 1.97. + +2009-10-16 Colin Watson + + * configure.ac (TARGET_CFLAGS): Add -mno-mmx -mno-sse -mno-sse2 + -mno-3dnow on x86 architectures. Some toolchains enable these + features by default, but they rely on registers that aren't enabled + in GRUB. Thanks to Vladimir Serbinenko for the suggestion. + +2009-10-15 Robert Millan + + Make entry text a bit more readable. + + * util/grub.d/10_linux.in: Add `with' before `Linux'. + +2009-10-15 Vladimir Serbinenko + + * loader/i386/pc/xnu.c (grub_xnu_set_video): Fix loading splash image. + +2009-10-15 Vladimir Serbinenko + + * commands/xnu_uuid.c (grub_cmd_xnu_uuid): Remove duplicated bitwise + operations. + +2009-10-15 Vladimir Serbinenko + + * configure.ac: Add missing dollar. + +2009-10-15 Vladimir Serbinenko + + Revert 2009-06-10 Pavel Roskin + + * configure.ac: Put checks for __bswapsi2 and __bswapdi2. + * include/grub/powerpc/libgcc.h: Don't use weak attribute for all + exports. + * include/grub/sparc64/libgcc.h: Likewise. Use + preprocessor conditionals. + +2009-10-14 Robert Millan + + * conf/common.rmk (grub-dumpbios): Remove rule. + (sbin_SCRIPTS, CLEANFILES): Remove `grub-dumpbios'. + * util/grub-dumpbios.in: Remove file. + +2009-10-14 Robert Millan + + Refer to kernel of FreeBSD "kFreeBSD" to avoid confusion between + the Operating System (FreeBSD) and its kernel (kernel of FreeBSD). + + * loader/i386/bsd.c (grub_freebsd_boot): Read kernel environment + from "kFreeBSD" namespace (rather than "FreeBSD"). Update all + users. + + (GRUB_MOD_INIT (bsd)): Rename "freebsd" command to "kfreebsd", + "openbsd" to "kopenbsd", "netbsd" to "knetbsd", "freebsd_loadenv" + to "kfreebsd_loadenv", "freebsd_module" to "kfreebsd_module", + and "freebsd_module_elf" to "kfreebsd_module_elf". Update all + users. + +2009-10-12 Robert Millan + + * term/tparm.c: Switch to GPLv3. + +2009-10-09 Robert Millan + + * include/grub/i386/cpuid.h: Add header protection. + +2009-10-09 Robert Millan + + Fail gracefuly when attempting to load 64-bit kFreeBSD on IA32 CPU. + + * include/grub/i386/cpuid.h: New file. + * commands/i386/cpuid.c: Include `'. + (has_longmode): Rename to ... + (grub_cpuid_has_longmode): ... this. Update all users. Remove + `static' attribute. + * loader/i386/bsd.c: Include `'. + (grub_bsd_load_elf): Fail if load of 64-bit kernel was requested + on a CPU that doesn't implement AMD64 instruction set. + +2009-10-06 Colin Watson + + * Makefile.in (docs/stamp-vti): Depend on configure.ac as well, so + that version.texi is rebuilt on version number changes. + +2009-10-06 Colin Watson + + * Makefile.in: Don't set info_INFOS unless makeinfo was found. + Fixes bug #27602. + +2009-10-06 Colin Watson + + * util/i386/pc/grub-install.in: Source + ${libdir}/grub/grub-mkconfig_lib before option processing, in order + that the --grub-probe option will work. + * util/sparc64/ieee1275/grub-install.in: Likewise. + +2009-10-05 Robert Millan + + * configure.ac: Bump version to 1.97~beta4. + +2009-10-03 Robert Millan + + Resync grub-mkdevicemap in x86_64-efi. + + * conf/x86_64-efi.rmk (sbin_UTILITIES): Enable `grub-mkdevicemap'. + (grub_mkdevicemap_SOURCES): Add missing `util/deviceiter.c' and + `util/devicemap.c'. + +2009-10-01 Colin Watson + + * util/grub-editenv.c (create_envblk_file): Write new block with a + .new suffix and then rename it into place, to ensure atomic + creation. + +2009-09-28 Robert Millan + + Do not automatically install headers. + + * Makefile.in (include_DATA): Remove. Update all users. + +2009-09-26 Robert Millan + + * conf/common.rmk (pkglib_MODULES): Remove `lua.mod'. + (lua_mod_SOURCES, lua_mod_CFLAGS, lua_mod_LDFLAGS): Remove. + + * util/osdetect.lua: Remove. + * script/lua/lauxlib.c: Likewise. + * script/lua/ldebug.c: Likewise. + * script/lua/grub_main.c: Likewise. + * script/lua/lauxlib.h: Likewise. + * script/lua/ldebug.h: Likewise. + * script/lua/ltablib.c: Likewise. + * script/lua/liolib.c: Likewise. + * script/lua/lstrlib.c: Likewise. + * script/lua/lualib.h: Likewise. + * script/lua/ldo.c: Likewise. + * script/lua/ldump.c: Likewise. + * script/lua/ldo.h: Likewise. + * script/lua/loslib.c: Likewise. + * script/lua/lundump.c: Likewise. + * script/lua/grub_lib.c: Likewise. + * script/lua/ldblib.c: Likewise. + * script/lua/lundump.h: Likewise. + * script/lua/lmem.c: Likewise. + * script/lua/grub_lib.h: Likewise. + * script/lua/lmathlib.c: Likewise. + * script/lua/lstate.c: Likewise. + * script/lua/ltm.c: Likewise. + * script/lua/lvm.c: Likewise. + * script/lua/lmem.h: Likewise. + * script/lua/lstate.h: Likewise. + * script/lua/ltm.h: Likewise. + * script/lua/ltable.c: Likewise. + * script/lua/lvm.h: Likewise. + * script/lua/llex.c: Likewise. + * script/lua/lgc.c: Likewise. + * script/lua/grub_lua.h: Likewise. + * script/lua/loadlib.c: Likewise. + * script/lua/lfunc.c: Likewise. + * script/lua/lopcodes.c: Likewise. + * script/lua/lparser.c: Likewise. + * script/lua/ltable.h: Likewise. + * script/lua/llex.h: Likewise. + * script/lua/lgc.h: Likewise. + * script/lua/lfunc.h: Likewise. + * script/lua/lbaselib.c: Likewise. + * script/lua/lopcodes.h: Likewise. + * script/lua/lparser.h: Likewise. + * script/lua/lzio.c: Likewise. + * script/lua/linit.c: Likewise. + * script/lua/lobject.c: Likewise. + * script/lua/llimits.h: Likewise. + * script/lua/lstring.c: Likewise. + * script/lua/lzio.h: Likewise. + * script/lua/lapi.c: Likewise. + * script/lua/lcode.c: Likewise. + * script/lua/lua.h: Likewise. + * script/lua/lobject.h: Likewise. + * script/lua/lstring.h: Likewise. + * script/lua/lapi.h: Likewise. + * script/lua/lcode.h: Likewise. + * script/lua/luaconf.h: Likewise. + +2009-09-26 Colin Watson + + * docs/grub.texi (Command-line and menu entry commands): Document + date and echo commands. + +2009-09-24 Pavel Roskin + + * include/grub/kernel.h (struct grub_module_header): Remove + `grub_module_header_types'. Make `type' unsigned. Make `size' + 32-bit on all platforms. + * util/elf/grub-mkimage.c (load_modules): Treat `type' as an + 8-bit field. Use grub_host_to_target32() for `size'. + * util/i386/efi/grub-mkimage.c (make_mods_section): Likewise. + * util/i386/pc/grub-mkimage.c (generate_image): Likewise. + * util/sparc64/ieee1275/grub-mkimage.c (generate_image): Likewise. + +2009-09-24 Robert Millan + + Fix "lost keypress" bug in at_keyboard. + + * term/i386/pc/at_keyboard.c (grub_at_keyboard_checkkey): New function. + Checks for readyness of input buffer (without flushing it). + (grub_at_keyboard_term): Use grub_at_keyboard_checkkey() rather + than grub_at_keyboard_getkey_noblock() for `checkkey' struct member. + +2009-09-24 Robert Millan + + * util/i386/pc/grub-mkimage.c (generate_image): Enclose BIOS-specific + size check within GRUB_MACHINE_PCBIOS section. + +2009-09-24 Robert Millan + + * include/grub/i386/at_keyboard.h (KEYBOARD_ISREADY): Negate + return value. + * term/i386/pc/at_keyboard.c (grub_keyboard_getkey): Negate + KEYBOARD_ISREADY check. + (grub_at_keyboard_checkkey): Rename to ... + (grub_at_keyboard_getkey_noblock): ... this. Update all users. + Remove gratuitous cast. + +2009-09-23 Colin Watson + + * configure.ac: Call AC_PROG_MKDIR_P. + * Makefile.in (docs/stamp-vti): Create docs directory. Create + version.texi in $(builddir) rather than $(srcdir). + (docs/grub.info): Create docs directory. Prepend $(builddir)/docs + to makeinfo's @include search path. + +2009-09-23 Felix Zielcke + + * util/grub-mkconfig_lib.in (grub_file_is_not_garbage): Cope with `*.dpkg-*' + +2009-09-23 Felix Zielcke + + * util/grub-mkconfig_lib.in (grub_file_is_not_garbage): Add support + for `*.dpkg-new'. + +2009-09-21 Colin Watson + + Build info documentation. Some code borrowed from Automake. + + * configure.ac: Check for makeinfo. + * Makefile.in (MAKEINFO, INFOS, info_INFOS): New variables. + (MAINTAINER_CLEANFILES): Add $(INFOS), docs/stamp-vti, and + docs/version.texi. + (MOSTLYCLEANFILES): Add vti.tmp. + (docs/version.texi, docs/stamp-vti): Update automatically. + (docs/grub.info): Build info documentation. Use --force and ignore + errors for now. + (all-local): Add $(INFOS). + (install-local): Install info files. + (uninstall): Uninstall info files. + * docs/version.texi: Remove from revision control. This file is + automatically generated on build now. + * gendistlist.sh: Add `*.info'. + +2009-09-21 Felix Zielcke + + * kern/term.c: Fix indentation. + +2009-09-21 Felix Zielcke + + * util/hostdisk.c: Fix a comment. + +2009-09-20 Robert Millan + + Fix regression introduced in r2539. + + * term/usb_keyboard.c (USB_HID_DEVICE_TO_HOST): Change from 0x61 + to 0xA1. + +2009-09-19 Colin Watson + + * util/grub.d/30_os-prober.in: Don't throw away stderr from + os-prober. Under normal operation, it does not print anything to + stderr; if it does, we need to debug it, and throwing away stderr + makes that excessively difficult. + +2009-09-16 Vladimir Serbinenko + + * mmap/mmap.c (grub_cmd_badram): Fix off-by-one error. + +2009-09-16 Robert Millan + + * aclocal.m4 (AC_LANG_PROGRAM): New macro. Overrides stock + AC_LANG_PROGRAM from autoconf. + (grub_ASM_USCORE, grub_PROG_OBJCOPY_ABSOLUTE): Add missing + prototypes (fixes warning). + + * configure.ac: Add `-Werror' to TARGET_CFLAGS unless + `--disable-werror' was used. + +2009-09-16 Robert Millan + + * partmap/msdos.c (pc_partition_map_iterate): Fix possible use of + uninitialized `lastaddr'. + +2009-09-15 Vladimir Serbinenko + + * partmap/msdos.c (pc_partition_map_iterate): Detect and break loops. + +2009-09-14 Colin Watson + + * commands/test.c (get_fileinfo): Return immediately if + grub_fs_probe fails. + +2009-09-14 JosĂ© MartĂ­nez + + * commands/acpi.c (grub_cmd_acpi): Fix loading ACPI tables from file. + +2009-09-14 Colin Watson + + * util/grub.d/30_os-prober.in: Cope with Windows 7 in os-prober + output. + +2009-09-13 Robert Millan + + * configure.ac: Remove --enable-grub-pe2elf. Only build + grub-pe2elf when needed by the build system itself. + * conf/common.rmk: Remove $(enable_grub_pe2elf) check. + +2009-09-12 Robert Millan + + * configure.ac: Bump version to 1.97~beta3. + * docs/version.texi: Likewise. + +2009-09-12 Robert Millan + + * video/i386/pc/vbe.c (grub_vbe_get_video_mode_info): Move packed + mode special handling (grub_vbe_bios_set_dac_palette_width() call) + from here ... + * loader/i386/linux.c [GRUB_MACHINE_PCBIOS] + (grub_linux_setup_video): ... to here (with some adjustments). + +2009-09-12 Robert Millan + + Fix memory corruption issue (spotted by Colin Watson). + + * kern/i386/pc/startup.S (grub_vbe_bios_getset_dac_palette): Fix bug + causing returned size to be stored in an incorrect memory location. + Fix use of uninitialized value when storing the returned size. + +2009-09-12 Yves Blusseau + + Change clean rules to properly remove files + + * genmk.rb: add new clean rules + * Makefile.in (clean): add the new targets + (mostlyclean): likewise + +2009-09-11 Colin Watson + + * include/grub/ntfs.h (struct grub_fshelp_node): Change `size' + to grub_uint64_t. + * fs/ntfs.c (init_file): Understand 64-bit sizes for + non-resident files. + +2009-09-11 Colin Watson + + * configure.ac: Don't look for help2man when cross-compiling. Fixes + part of bug #27349. + +2009-09-10 Felix Zielcke + + * util/grub-mkconfig.in: Make the created config mode 400 and + print a warning if it fails. + +2009-09-10 Robert Millan + + * util/grub.d/40_custom.in: Ask user to type custom entries below + comment, rather than below 'exec tail' line. + +2009-09-10 Colin Watson + + * util/grub.d/40_custom.in: Make sure that the explanatory text is + visible in grub.cfg. + +2009-09-10 Colin Watson + + * util/grub.d/40_custom.in: Make it a little clearer how to use this + file. + +2009-09-10 Felix Zielcke + + * docs/grub.cfg: Add an example menu entry for memtest86+. + +2009-09-09 Felix Zielcke + + * config.guess: Update to latest version from config git. + * config.sub: Likewise. + +2009-09-08 Colin Watson + + * script/sh/execute.c (grub_script_execute_cmdline): Set "?" in + unknown-command case. Fixes bug #27320. + +2009-09-08 Felix Zielcke + + * kern/rescue_parser.c (grub_rescue_parse_line): Only suggest to try + `help' if the command exists. + +2009-09-06 Robert Millan + + * INSTALL: Require GCC 4.1.3 or later. + +2009-09-06 Yves Blusseau + + * Makefile.in (RMKFILES): add i386-qemu.rmk + (MAINTAINER_CLEANFILES): add $(srcdir)/DISTLIST $(srcdir)/config.h.in + $(srcdir)/stamp-h.in + +2009-09-05 Robert Millan + + * util/grub-probe.c (probe): Comment out buggy codepath, which + was unexpectedly enabled by Colin Watson's 2009-09-02 fix. This + should be re-enabled after 1.97. + +2009-09-05 Felix Zielcke + + * gendistlist.sh: Add `grub-dumpdevtree' and `*.lua' to the list + find searches for. + +2009-09-04 Vladimir Serbinenko + + * loader/i386/xnu.c (grub_cpu_xnu_fill_devicetree): Remove + unnecessary calls to grub_error. + +2009-09-04 Colin Watson + + * NEWS: Mention `keystatus' and Unicode fonts. + +2009-09-04 Robert Millan + + * configure.ac: Bump version to 1.97~beta2. + * docs/version.texi: Likewise. + +2009-09-03 Colin Watson + + * configure.ac: By default, GCC 4.4 generates .eh_frame sections + containing unwind information in some cases where it previously did + not. Use -fno-dwarf2-cfi-asm if available to restore the old + behaviour. See http://patchwork.kernel.org/patch/8555/ for related + discussion. + +2009-09-02 Yves BLUSSEAU + + Embedding loadenv module into grub-emu + + * conf/i386-pc.rmk (grub_emu_SOURCES): add lib/envblk.c and + commands/loadenv.c + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Likewise + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise + +2009-09-03 Magnus Granberg + + * aclocal.m4: Add grub_CHECK_PIE. It check if the compiler + include -fPIE in the default specs. + * configure.ac: Check if pie_possible is yes and add -fno-PIE + to TARGET_CFLAGS. + +2009-09-03 Felix Zielcke + + * INSTALL: Note that GNU Bison 2.3 or later is required. + +2009-09-03 Colin Watson + + * kern/i386/pc/startup.S: Fix typo. + +2009-09-02 Vladimir Serbinenko + + * efiemu/loadcore.c (SUFFIX (grub_efiemu_loadcore_load)): Fix style + according to GCS. + +2009-09-02 Colin Watson + + * docs/grub.texi (Naming convention): Describe one-based partition + numbering. + (Device syntax): Likewise. + (File name syntax): Likewise. + (Block list syntax): Likewise. + (Making a GRUB bootable CD-ROM): Talk about grub.cfg rather than + menu.lst. + (File name syntax): Likewise. + (Command-line and menu entry commands): Document acpi, blocklist, + crc, export, insmod, keystatus, ls, set, and unset commands. + +2009-09-02 Colin Watson + + * commands/keystatus.c (GRUB_MOD_INIT (keystatus)): Adjust summary + to avoid implying that only one of --shift, --ctrl, or --alt may be + used. + +2009-09-02 Colin Watson + + * util/grub-probe.c (probe): Test st.st_mode using S_ISREG macro + rather than comparing against S_IFREG, which will almost never work. + +2009-09-01 Vladimir Serbinenko + + * commands/loadenv.c (check_blocklists): Fix off-by-one error. + (write_blocklists): Likewise. + +2009-09-01 Colin Watson + + * script/lua/grub_lua.h (fputs): Supply a format string as the first + argument to grub_printf. + +2009-09-01 Felix Zielcke + + * genmk.rb: Add quotes around $(TARGET_OBJ2ELF) to cope with + non GNU test. + +2009-08-30 Vladimir Serbinenko + + * kern/file.c (grub_file_read): Spelling fix + +2009-08-30 Vladimir Serbinenko + + * loader/i386/bsdXX.c (SUFFIX (grub_freebsd_load_elfmodule)): Fix + loading of headers in some cases. + +2009-08-30 Robert Millan + + * configure.ac: Bump version to 1.97~beta1. + * docs/version.texi: Likewise. + +2009-08-29 Vladimir Serbinenko + + * include/grub/i386/xnu.h: Add license header. + include grub/err.h explicitly. + +2009-08-29 Robert Millan + + * util/grub.d/10_freebsd.in: Detect `ufs1' and `ufs2' and map them + to `ufs' in the vfs.root.mountfrom kernel parameter. + +2009-08-29 Robert Millan + + * term/i386/pc/serial.c: Include `'. + + [GRUB_MACHINE_PCBIOS] (serial_hw_io_addr): Macroify initialization + value (0x0400 -> GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR). + + [! GRUB_MACHINE_PCBIOS] (GRUB_SERIAL_PORT_NUM): Calculate using + `ARRAY_SIZE' macro. + +2009-08-28 Vladimir Serbinenko + + * kern/file.c (grub_file_read): Check offset. + * fs/hfs.c (grub_hfs_read_file): Remove unnecessary offset check. + * fs/jfs.c (grub_jfs_read_file): Likewise. + * fs/ntfs.c (grub_ntfs_read): Likewise. + * fs/reiserfs.c (grub_reiserfs_read): Likewise. + * fs/minix.c (grub_minix_read_file): Correct offset check. + * fs/ufs.c (grub_ufs_read_file): Likewise. + +2009-08-28 Colin Watson + + * term/i386/pc/console.c (bios_data_area): Cast + GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR explicitly. + +2009-08-28 Vladimir Serbinenko + + 1-bit optimised blitters. + + * include/grub/fbblit.h (grub_video_fbblit_replace_32bit_1bit): New + prototype. + (grub_video_fbblit_replace_24bit_1bit): Likewise. + (grub_video_fbblit_replace_16bit_1bit): Likewise. + (grub_video_fbblit_replace_8bit_1bit): Likewise. + (grub_video_fbblit_blend_XXXA8888_1bit): Likewise. + (grub_video_fbblit_blend_XXX888_1bit): Likewise. + (grub_video_fbblit_blend_XXX565_1bit): Likewise. + * video/fb/fbblit.c (grub_video_fbblit_replace_32bit_1bit): New + function. + (grub_video_fbblit_replace_24bit_1bit): Likewise. + (grub_video_fbblit_replace_16bit_1bit): Likewise. + (grub_video_fbblit_replace_8bit_1bit): Likewise. + (grub_video_fbblit_blend_XXXA8888_1bit): Likewise. + (grub_video_fbblit_blend_XXX888_1bit): Likewise. + (grub_video_fbblit_blend_XXX565_1bit): Likewise. + * video/fb/video_fb.c (common_blitter): Use 1-bit optimised blitters + when possible. + * video/video.c (grub_video_get_blit_format): Return + GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED if bpp = 1. + +2009-08-28 Colin Watson + + * normal/cmdline.c (grub_cmdline_get): Supply a format string as + the first argument to grub_printf. + +2009-08-28 Colin Watson +2009-08-28 Robert Millan + + Add `getkeystatus' terminal method. Add a new `keystatus' command + to query it. + + * include/grub/term.h (GRUB_TERM_STATUS_SHIFT, + GRUB_TERM_STATUS_CTRL, GRUB_TERM_STATUS_ALT): Definitions for + modifier key bitmasks. + (struct grub_term_input): Add `getkeystatus' member. + (grub_getkeystatus): Add prototype. + * kern/term.c (grub_getkeystatus): New function. + + * include/grub/i386/pc/memory.h + (GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR): New macro. + (struct grub_machine_bios_data_area): Define necessary parts of BIOS + Data Area layout. + * term/i386/pc/console.c (grub_console_getkeystatus): New function. + (grub_console_term_input): Set `getkeystatus' member. + * term/usb_keyboard.c (grub_usb_hid): Macroify HID protocol + constants. + (grub_usb_keyboard_getreport): Likewise. + (grub_usb_keyboard_checkkey): Likewise. + (grub_usb_keyboard_getkeystatus): New function. + (grub_usb_keyboard_term): Set `getkeystatus' member. + + * commands/keystatus.c: New file. + * conf/common.rmk (pkglib_MODULES): Add keystatus.mod. + (keystatus_mod_SOURCES): New variable. + (keystatus_mod_CFLAGS): Likewise. + (keystatus_mod_LDFLAGS): Likewise. + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Add + commands/keystatus.c. + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-pc.rmk (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. + +2009-08-28 Vladimir Serbinenko + + Split befs.mod and afs.mod into *_be.mod and *.mod + + * conf/common.rmk (grub_probe_SOURCES): Add afs_be.c and befs_be.c. + (grub_fstest_SOURCES): Likewise. + (pkglib_MODULES): Add afs_be.mod and befs_be.mod. + (afs_be_mod_SOURCES): New variable. + (afs_be_mod_CFLAGS): Likewise. + (afs_be_mod_LDFLAGS): Likewise. + (befs_be_mod_SOURCES): Likewise. + (befs_be_mod_CFLAGS): Likewise. + (befs_be_mod_LDFLAGS): Likewise. + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Add afs_be.c and befs_be.c. + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-pc.rmk (grub_setup_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. + * fs/afs_be.c: New file. + * fs/befs_be.c: New file. + * fs/afs.c (GRUB_AFS_FSNAME_SUFFIX): New definition. + (GRUB_AFS_FSNAME): Use GRUB_AFS_FSNAME_SUFFIX. + (U16): Replaced with ... + (grub_afs_to_cpu16): ...this. All users updated. + (U32): Replaced with ... + (grub_afs_to_cpu32): ...this. All users updated. + (U64): Replaced with ... + (grub_afs_to_cpu64): ...this. All users updated. + (GRUB_AFS_BO_LITTLE_ENDIAN): Remove. + (GRUB_AFS_BO_BIG_ENDIAN): Likewise. + (grub_afs_validate_sblock): Check only one endianness. + (GRUB_MOD_INIT (befs)) [MODE_BIGENDIAN && MODE_BFS]: Rename to .. + (GRUB_MOD_INIT (befs_be)) [MODE_BIGENDIAN && MODE_BFS]: ... this. + (GRUB_MOD_INIT (afs)) [MODE_BIGENDIAN && !MODE_BFS]: Rename to .. + (GRUB_MOD_INIT (afs_be)) [MODE_BIGENDIAN && !MODE_BFS]: ... this. + (GRUB_MOD_FINI (befs)) [MODE_BIGENDIAN && MODE_BFS]: Rename to .. + (GRUB_MOD_FINI (befs_be)) [MODE_BIGENDIAN && MODE_BFS]: ... this. + (GRUB_MOD_FINI (afs)) [MODE_BIGENDIAN && !MODE_BFS]: Rename to .. + (GRUB_MOD_FINI (afs_be)) [MODE_BIGENDIAN && !MODE_BFS]: ... this. + +2009-08-26 Bean + + * fs/xfs.c (GRUB_XFS_INO_INOINAG): Replace 1L with 1LL to support + 64-bit number. + (GRUB_XFS_FSB_TO_BLOCK): Likewise. + (grub_xfs_inode_block): Change return type to grub_uint64_t. + (grub_xfs_read_inode): Change type of block to grub_uint64_t. + +2009-08-25 Vladimir Serbinenko + + NetBSD memory map support. + + * include/grub/i386/bsd.h (NETBSD_BTINFO_MEMMAP): New definition. + (grub_netbsd_btinfo_mmap_header): New structure. + (grub_netbsd_btinfo_mmap_entry): Likewise. + * loader/i386/bsd.c (grub_netbsd_boot): Pass memory map. + +2009-08-25 Vladimir Serbinenko + + Enable bsd.mod on coreboot. + + * conf/i386-coreboot.rmk (pkglib_MODULES): Add bsd.mod. + (bsd_mod_SOURCES): New variable. + (bsd_mod_CFLAGS): Likewise. + (bsd_mod_LDFLAGS): Likewise. + (bsd_mod_ASFLAGS): Likewise. + * loader/i386/bsd.c [!GRUB_MACHINE_PCBIOS]: Fix includes. + (grub_bsd_get_device) [!GRUB_MACHINE_PCBIOS]: Set *biosdev to 0xff. + +2009-08-25 Vladimir Serbinenko + + Cleanup NetBSD root support. + + * loader/i386/bsd.c (grub_netbsd_boot): Remove call to + grub_bsd_get_device. + Fix typo. + +2009-08-25 Felix Zielcke + + * util/grub.d/00_header.in: Move check for the video backend of + gfxterm from here ... + * util/grub-mkconfig.in: ... to here. Enable gfxterm if there's + a suitable video backend. + +2009-08-25 Vladimir Serbinenko + + Fix breakage in grub-setup. + + * util/i386/pc/grub-setup.c (setup): Use "part_msdos" instead of + "msdos_partition_map". + +2009-08-25 Vladimir Serbinenko + + Fix breakage in normal/auth.c. + + * normal/auth.c (grub_iswordseparator): New function. + +2009-08-25 Vladimir Serbinenko + + Authentication support. + + * commands/password.c: New file. + * conf/common.rmk (pkglib_MODULES): Add password.mod. + (password_mod_SOURCES): New variable. + (password_mod_CFLAGS): Likewise. + (password_mod_LDFLAGS): Likewise. + (normal_mod_SOURCES): Add normal/auth.c. + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Add commands/password.c and + normal/auth.c. + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-pc.rmk (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. + * include/grub/auth.h: New file. + * include/grub/err.h (grub_err_t): New enum value + GRUB_ERR_ACCESS_DENIED. + * include/grub/menu.h (grub_menu_entry): New fields 'restricted' and + 'users'. + * include/grub/normal.h (grub_cmdline_get): New argument 'history'. + * normal/cmdline.c (grub_cmdline_get): New argument 'history'. All + users updated. + * normal/auth.c: New file. + * normal/main.c (grub_normal_add_menu_entry): Handle --users option. + (grub_cmdline_run): Don't allow to go to command line without + authentication. + * normal/menu.c (grub_menu_execute_entry): Handle restricted entries. + * normal/menu_entry.c (grub_menu_entry_run): Don't allow editing + menuentry without superuser rights. + * normal/menu_viewer.c (grub_menu_viewer_show_menu): Don't exit if + user isn't a superuser. + +2009-08-24 Vladimir Serbinenko + + Save space by inlining misc.c functions. + + * kern/misc.c (grub_iswordseparator): Made static. + * kern/misc.c (grub_strcat): Moved from here ... + * include/grub/misc.h (grub_strcat): ... here. Inlined. + * kern/misc.c (grub_strncat): Moved from here ... + * include/grub/misc.h (grub_strncat): ... here. Inlined. + * kern/misc.c (grub_strcasecmp): Moved from here ... + * include/grub/misc.h (grub_strcasecmp): ... here. Inlined. + * kern/misc.c (grub_strncasecmp): Moved from here ... + * include/grub/misc.h (grub_strncasecmp): ... here. Inlined. + * kern/misc.c (grub_isalpha): Moved from here ... + * include/grub/misc.h (grub_isalpha): ... here. Inlined. + * kern/misc.c (grub_isdigit): Moved from here ... + * include/grub/misc.h (grub_isdigit): ... here. Inlined. + * kern/misc.c (grub_isgraph): Moved from here ... + * include/grub/misc.h (grub_isgraph): ... here. Inlined. + * kern/misc.c (grub_tolower): Moved from here ... + * include/grub/misc.h (grub_tolower): ... here. Inlined. + +2009-08-24 Vladimir Serbinenko + + * script/sh/function.c (grub_script_function_find): Cut error message + not to flood terminal. + * script/sh/lexer.c (grub_script_yylex): Remove command line length + limit. + * script/sh/script.c (grub_script_arg_add): Duplicate string. + +2009-08-24 Colin Watson + + * term/usb_keyboard.c (grub_usb_keyboard_getreport): Make + `report' grub_uint8_t *. + (grub_usb_keyboard_checkkey): Make `data' elements grub_uint8_t. + Use a 50-millisecond timeout rather than just repeating + grub_usb_keyboard_getreport 50 times. + (grub_usb_keyboard_getkey): Make `data' elements grub_uint8_t. + +2009-08-24 Vladimir Serbinenko + + Rename *_partition_map to part_* + + * partmap/acorn.c (grub_acorn_partition_map): Set name to 'part_acorn'. + * partmap/amiga.c (grub_amiga_partition_map): Set name to 'part_amiga'. + * partmap/apple.c (grub_apple_partition_map): Set name to 'part_apple'. + * partmap/gpt.c (grub_gpt_partition_map): Set name to 'part_gpt'. + All users updated. + * partmap/msdos.c (grub_msdos_partition_map): Set name to 'part_msdos'. + All users updated. + * partmap/sun.c (grub_sun_partition_map): Set name to 'part_sun'. + * util/grub-probe.c (probe_partmap): Don't transform partition name + to get module name. + +2009-08-24 Vladimir Serbinenko + + Fix OpenBSD and NetBSD support. + + * include/grub/i386/bsd.h (GRUB_BSD_TEMP_BUFFER): Change to resolve + memory address conflict. + (OPENBSD_MMAP_ACPI): New definition. + (OPENBSD_MMAP_NVS): Likewise. + * loader/i386/bsd.c (grub_openbsd_boot): Support OPENBSD_MMAP_ACPI + and OPENBSD_MMAP_NVS. + Add memory map terminator + Explicit cast when calling grub_unix_real_boot. + (grub_netbsd_boot): Explicit cast when calling grub_unix_real_boot. + +2009-08-24 Vladimir Serbinenko + + Let user specify NetBSD root device. + + * loader/i386/bsd.c (netbsd_root): New variable. + (netbsd_opts): New option 'root'. + (NETBSD_ROOT_ARG): New macro. + (grub_netbsd_boot): Use 'netbsd_root'. + (grub_bsd_unload): Free 'netbsd_root'. + (grub_cmd_netbsd): Fill 'netbsd_root'. + +2009-08-24 Vladimir Serbinenko + + Support for 64-bit NetBSD. + + * loader/i386/bsd.c (grub_bsd_load_elf): Apply correct mask to entry + point when booting non-FreeBSD. + +2009-08-24 Vladimir Serbinenko + + Support --no-smp and --no-acpi for NetBSD. + + * include/grub/i386/bsd.h (NETBSD_AB_NOSMP): New definition. + (NETBSD_AB_NOACPI): Likewise. + * loader/i386/bsd.c (netbsd_opts): New entries no-smp and no-acpi. + (netbsd_flags): Add NETBSD_AB_NOSMP, NETBSD_AB_NOACPI. + +2009-08-23 Vladimir Serbinenko + + * fs/hfsplus.c (grub_hfsplus_mount): Don't ignore grub_hfsplus_read_file + errors. + (grub_hfsplus_btree_iterate_node): Don't ignore grub_hfsplus_read_file + errors. Call grub_error when needed. + +2009-08-23 Vladimir Serbinenko + + * commands/search.c (search_fs): Try searching without autoload first. + * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Load + filesystem module explicitly for faster booting. + +2009-08-23 Colin Watson + + * util/grub-mkconfig.in: Export GRUB_DISABLE_OS_PROBER. + +2009-08-23 Colin Watson + + * util/grub.d/30_os-prober.in: Disable os-prober if + `GRUB_DISABLE_OS_PROBER' was set to true. + +2009-08-23 Robert Millan + + * partmap/pc.c: Rename to ... + * partmap/msdos.c: ... this. Update all users. + (grub_pc_partition_map): Rename to ... + (grub_msdos_partition_map): ... this. Update all users. + + * parttool/pcpart.c: Rename to ... + * parttool/msdospart.c: ... this. Update all users. + + * include/grub/pc_partition.h: Rename to ... + * include/grub/msdos_partition.h: ... this. Update all users. + (grub_pc_partition_bsd_entry): Rename to ... + (grub_msdos_partition_bsd_entry): ... this. Update all users. + (grub_pc_partition_disk_label): Rename to ... + (grub_msdos_partition_disk_label): ... this. Update all users. + (grub_pc_partition_entry): Rename to ... + (grub_msdos_partition_entry): ... this. Update all users. + (grub_pc_partition_mbr): Rename to ... + (grub_msdos_partition_mbr): ... this. Update all users. + (grub_pc_partition): Rename to ... + (grub_msdos_partition): ... this. Update all users. + (grub_pc_partition_is_empty): Rename to ... + (grub_msdos_partition_is_empty): ... this. Update all users. + (grub_pc_partition_is_extended): Rename to ... + (grub_msdos_partition_is_extended): ... this. Update all users. + (grub_pc_partition_is_bsd): Rename to ... + (grub_msdos_partition_is_bsd): ... this. Update all users. + + * conf/common.rmk (amiga_mod_SOURCES, amiga_mod_CFLAGS) + (amiga_mod_LDFLAGS, apple_mod_SOURCES, apple_mod_CFLAGS) + (apple_mod_LDFLAGS, msdos_mod_SOURCES, msdos_mod_CFLAGS) + (msdos_mod_LDFLAGS, sun_mod_SOURCES, sun_mod_CFLAGS) + (sun_mod_LDFLAGS, acorn_mod_SOURCES, acorn_mod_CFLAGS) + (acorn_mod_LDFLAGS, gpt_mod_SOURCES, gpt_mod_CFLAGS) + (gpt_mod_LDFLAGS): Rename to ... + (part_amiga_mod_SOURCES, part_amiga_mod_CFLAGS, part_amiga_mod_LDFLAGS) + (part_apple_mod_SOURCES, part_apple_mod_CFLAGS, part_apple_mod_LDFLAGS) + (part_msdos_mod_SOURCES, part_msdos_mod_CFLAGS, part_msdos_mod_LDFLAGS) + (part_sun_mod_SOURCES, part_sun_mod_CFLAGS, part_sun_mod_LDFLAGS) + (part_acorn_mod_SOURCES, part_acorn_mod_CFLAGS, part_acorn_mod_LDFLAGS) + (part_gpt_mod_SOURCES, part_gpt_mod_CFLAGS) + (part_gpt_mod_LDFLAGS): ... this. + (pkglib_MODULES): Prefix partition modules with `part_'. Rename + `pcpart.mod' to `msdospart.mod'. + (pcpart_mod_SOURCES, pcpart_mod_CFLAGS, pcpart_mod_LDFLAGS): Rename + to ... + (msdospart_mod_SOURCES, msdospart_mod_CFLAGS) + (msdospart_mod_LDFLAGS): ... this. + +2009-08-23 Vladimir Serbinenko + + * loader/i386/bsd.c (freebsd_opts): Rewritten to use extcmd. + (openbsd_opts): Likewise. + (netbsd_opts): Likewise. + (freebsd_flags): Added 0 terminator. + (openbsd_flags): Likewise. + (netbsd_flags): Likewise. + (grub_bsd_parse_flags): Rewritten to use extcmd. All users updated. + (grub_cmd_freebsd): Transformed into extended command. + (grub_cmd_openbsd): Likewise. + (grub_cmd_netbsd): Likewise. + (cmd_freebsd): Changed type to grub_extcmd_t. + (cmd_openbsd): Likewise. + (cmd_netbsd): Likewise. + (GRUB_MOD_INIT (bsd)): Register grub_cmd_freebsd, grub_cmd_netbsd and + grub_cmd_openbsd as extended commands. + (GRUB_MOD_FINI (bsd)): Use grub_unregister_extcmd for cmd_freebsd, + cmd_netbsd and cmd_openbsd + +2009-08-22 Vladimir Serbinenko + + * commands/xnu_uuid.c (transform): Use grub_memcpy instead of memcpy. + +2009-08-21 Pavel Roskin + + * Makefile.in (install-local): When checking if a file is in the + build directory, use "test -e" to detect symlinks. + + * Makefile.in (install-local): Remove all files in + $(DESTDIR)$(pkglibdir) before installing new files there. + +2009-08-18 Felix Zielcke + + * util/powerpc/ieee1275/grub-mkrescue.in (grub_mkimage): Use + grub-mkelfimage. + +2009-08-18 Felix Zielcke + + * util/grub-mkconfig.in: Don't use gfxterm by default if not + explicitly specified by the user. + +2009-08-18 Pavel Roskin + + * include/grub/fbfill.h (struct grub_video_fbrender_target): Use + grub_uint8_t pointer for data. + * include/grub/fbutil.h (struct grub_video_fbblit_info): + Likewise. + * video/fb/fbutil.c: Remove unnecessary casts. + +2009-08-17 Michal Suchanek + + VBE cleanup. + + * video/i386/pc/vbe.c (vbe_mode_in_use): Removed (duplicate). + (grub_vbe_set_video_mode): Save active mode info + only after setting the mode. + (grub_video_vbe_setup): Call 'grub_vbe_set_video_mode' with NULL as + second argument. + +2009-08-17 Michal Suchanek + + Rename variables for clarity. + + * video/i386/pc/vbe.c (active_mode_info): Renamed to ... + (active_vbe_mode_info): ... this. All users updated. + (framebuffer): Rename 'active_mode' to 'active_vbe_mode'. + All users updated. + (initial_mode): Rename to ... + (initial_vbe_mode): ... this. All users updated. + (mode_in_use): Rename to .. + (vbe_mode_in_use): ... this. All users updated. + (mode_list): Rename to .. + (vbe_mode_list): ... this. All users updated. + (grub_vbe_set_video_mode): Rename 'mode' to 'vbe_mode', 'mode_info' to + 'vbe_mode_info' and 'old_mode' to 'old_vbe_mode'. + (grub_video_vbe_init): Rename 'rm_mode_list' to 'rm_vbe_mode_list' and + 'mode_list_size' to 'vbe_mode_list_size'. + (grub_video_vbe_setup): Rename 'mode_info' to 'vbe_mode_info', + 'best_mode_info' to 'best_vbe_mode_info' and + 'best_mode' to 'best_vbe_mode' + +2009-08-17 Michal Suchanek + + Remove duplicate grub_video_fb_get_video_ptr. + + * include/grub/fbutil.h (get_data_ptr): Rename to ... + (grub_video_fb_get_video_ptr): ... this. + * include/grub/video_fb.h (grub_video_fb_get_video_ptr): Removed. + * video/fb/fbutil.c: Add comment about addressing. + (get_data_ptr): Rename to ... + (grub_video_fb_get_video_ptr): ... this. All users updated. + * video/fb/video_fb.c (grub_video_fb_get_video_ptr): Remove. + +2009-08-17 Robert Millan + + * fs/fat.c (grub_fat_read_data): Remove `#if 0' braces around the + grub_dprintf() that was just added. + +2009-08-17 Robert Millan + + * loader/i386/linux.c (GRUB_ASSUME_LINUX_HAS_FB_SUPPORT) + (DEFAULT_VIDEO_MODE): Remove macros. + (grub_linux_boot): Remove assumption that Linux has FB support, + and use "text" as default video mode. + +2009-08-15 Vladimir Serbinenko + + * fs/affs.c (grub_affs_read_symlink): Change leftover grub_printf into + grub_dprintf. + * fs/fat.c (grub_fat_read_data): Likewise. + +2009-08-14 Vladimir Serbinenko + + * loader/i386/multiboot.c (grub_multiboot): Don't pass filename to + payload. + (grub_module): Likewise. + +2009-08-14 Vladimir Serbinenko + + * loader/i386/multiboot.c (grub_multiboot_unload): Don't free mbi and + mbi->cmdline but free playground. + +2009-08-14 Vladimir Serbinenko + + Handle group offset on UFS1. + + * fs/ufs.c (grub_ufs_sblock): New field 'cylg_mask'. + (grub_ufs_read_inode) [!MODE_UFS2]: handle cylg_offset and cylg_mask. + +2009-08-14 Vladimir Serbinenko + + Split ufs.mod into ufs1.mod and ufs2.mod. + + * conf/common.rmk (grub_probe_SOURCES): Add fs/ufs2.c. + (grub_fstest_SOURCES): Likewise. + (pkglib_MODULES): Remove ufs.mod. Add ufs1.mod and ufs2.mod. + (ufs_mod_SOURCES): Remove. + (ufs_mod_CFLAGS): Likewise. + (ufs_mod_LDFLAGS): Likewise. + (ufs1_mod_SOURCES): New variable. + (ufs1_mod_CFLAGS): Likewise. + (ufs1_mod_LDFLAGS): Likewise. + (ufs2_mod_SOURCES): New variable. + (ufs2_mod_CFLAGS): Likewise. + (ufs2_mod_LDFLAGS): Likewise. + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Add fs/ufs2.c. + * conf/i386-efi.rmk (util/i386/efi/grub-mkimage.c_DEPENDENCIES): + Likewise. + (grub_emu_SOURCES): Likewise. + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-pc.rmk (grub_emu_SOURCES): Likewise. + (grub_setup_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/sparc64.rmk (grub_emu_SOURCES): Likewise. + (grub_setup_SOURCES): Likewise. + * conf/x86_64-efi.rmk (util/i386/efi/grub-mkimage.c_DEPENDENCIES): + Likewise. + * fs/ufs2.c: New file. + * fs/ufs.c: Separate UFS1 from UFS2 by using preprocessor. + +2009-08-14 Vladimir Serbinenko + + Framebuffer split. + + * commands/i386/pc/vbetest.c (grub_cmd_vbetest): Restore video + subsystem at the end. + * conf/common.rmk (pkglib_MODULES): Add video_fb.mod. + (video_fb_mod_SOURCES): New variable. + (video_fb_mod_CFLAGS): Likewise. + (video_fb_mod_LDFLAGS): Likewise. + * conf/i386-pc.rmk (vbe_mod_SOURCES): Remove video/i386/pc/vbeblit.c, + video/i386/pc/vbefill.c and video/i386/pc/vbeutil.c. + * video/i386/pc/vbeblit.c: Moved from here ... + * video/fb/fbblit.c: ..here. Replaced 'vbe' with 'fb'. + * video/i386/pc/vbefill.c: Moved from here ... + * video/fb/fbfill.c: ..here. Replaced 'vbe' with 'fb'. + * video/i386/pc/vbeutil.c: Moved from here ... + * video/fb/fbutil.c: ..here. Replaced 'vbe' with 'fb'. + * include/grub/i386/pc/vbeblit.h: Moved from here ... + * include/grub/fbblit.h: ... here. Replaced 'vbe' with 'fb'. + * include/grub/i386/pc/vbefill.h: Moved from here ... + * include/grub/fbfill.h: ... here. Replaced 'vbe' with 'fb'. + * include/grub/i386/pc/vbeutil.h: Moved from here ... + * include/grub/fbutil.h: ... here. Replaced 'vbe' with 'fb'. + * include/grub/i386/pc/vbe.h: Moved framebuffer part ... + * include/grub/video_fb.h: ... here. Replaced 'vbe' with 'fb'. + * include/grub/video.h (GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER): Removed. + (GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER): Likewise. + (grub_video_adapter): Added 'get_info_and_fini'. + (grub_video_get_info_and_fini): New prototype. + (grub_video_set_mode): make modestring const char *. + * loader/i386/linux.c (grub_linux_setup_video): Use + grub_video_get_info_and_fini. + (grub_linux_boot): Move modesetting just before booting. + * loader/i386/pc/xnu.c (grub_xnu_set_video): Use + grub_video_get_info_and_fini. + * video/i386/pc/vbe.c: Moved framebuffer part ... + * video/fb/video_fb.c: ... here. Replaced 'vbe' with 'fb'. + * video/i386/pc/vbe.c (grub_vbe_set_video_mode): Use + grub_video_fbstd_colors and grub_video_fb_set_palette. + (grub_video_vbe_init): Clear 'framebuffer' variable and use + grub_video_fb_init. + (grub_video_vbe_fini): Use grub_video_fb_fini. + (grub_video_vbe_setup): Use framebuffer.render_target instead of + render_target and use grub_video_fb_set_active_render_target and + grub_video_fb_set_palette. + (grub_video_vbe_set_palette): Use grub_video_fb_set_palette. + (grub_video_vbe_set_viewport): Use grub_video_fb_set_viewport. + (grub_video_vbe_adapter): Use framebuffer. + * video/video.c (grub_video_get_info_and_fini): New function. + (grub_video_set_mode): Make modestring const char *. + (GRUB_MOD_INIT(video_video)): Don't set variables to 0 since these + values are already initialised. + +2009-08-14 Pavel Roskin + + * boot/i386/pc/cdboot.S: Use LOCAL for local labels. Eliminate + ABS and APPLE_CC. + * boot/i386/pc/diskboot.S: Likewise. + * boot/i386/pc/lnxboot.S: Likewise. Hardcode the number of code + sectors allow compilation on MacOSX. + * conf/i386-pc.rmk: Enable unconditional compilation of + lnxboot.img. + +2009-08-13 Colin Watson + + * util/grub-mkconfig.in: Export GRUB_HIDDEN_TIMEOUT. + * util/grub.d/00_header.in: Enter interruptible sleep if + GRUB_HIDDEN_TIMEOUT is set. + +2009-08-13 Yves Blusseau + + * include/grub/symbol.h: Add the LOCAL macro. + * boot/i386/pc/boot.S: Use the LOCAL macro for all labels + starting with "L_". + +2009-08-13 Pavel Roskin + + * boot/i386/pc/boot.S: Remove ABS macro, it's not required by + any modern compilers we support. + + * boot/i386/pc/boot.S: Remove all code dependent on APPLE_CC. + Use local labels starting with "L_" so that Apple assembler + knows they are local. + +2009-08-10 Robert Millan + + * include/grub/i386/bsd.h (KERNEL_TYPE_NONE, KERNEL_TYPE_FREEBSD) + (KERNEL_TYPE_OPENBSD, KERNEL_TYPE_NETBSD): Convert to ... + (bsd_kernel_types): ... this enum. + + * loader/i386/bsd.c (grub_cmd_freebsd_loadenv, grub_cmd_freebsd_module) + (grub_cmd_freebsd_module_elf): Abort with "You need to load the + kernel first." when `kernel_type' is set to KERNEL_TYPE_NONE. + + (grub_bsd_load_aout, grub_bsd_load, grub_cmd_freebsd_loadenv) + (grub_cmd_freebsd_module, grub_cmd_freebsd_module_elf) + (GRUB_MOD_INIT (bsd)): Fix capitalization in a few error + messages. + +2009-08-08 Robert Millan + + * util/grub-dumpdevtree: Moved from here ... + * util/i386/efi/grub-dumpdevtree: ... to here. + (hexify): New function. Converts a string to its hex version. + Generate hex versions of "efi" and "device-properties" by calling + hexify() on the ASCII strings rather than by hardcoding numbers. + +2009-08-08 Robert Millan + + * fs/jfs.c: Update copyright year. + +2009-08-08 Felix Zielcke + + * util/grub.d/00_header.in: Fix a comment. + * util/grub.d/10_linux.in: Likewise. + * util/grub.d/10_windows.in: Likewise. + * util/grub.d/10_hurd.in: Likewise. + +2009-08-08 Felix Zielcke + + * util/grub-mkconfig.in: Allow the user to specify the used font + with GRUB_FONT. + +2009-08-08 Pavel Roskin + + * include/grub/powerpc/libgcc.h: Export __ashrdi3() if + available, xfs.mod needs it now. + + * util/grub-mkconfig_lib.in (version_test_numeric): Don't use + the "g" modifier in sed when the intention is to strip something + once. This fixes comparison of kernels with multiple dashes. + + * util/grub-mkconfig.in: Define datarootdir, datadir may depend + on it. Add missing space before closing bracket. Fix + misleading formatting. + +2009-08-07 Robert Millan + + * docs/grub.texi: Major overhaul. Remove all sections that are + specific to GRUB Legacy, or mostly composed of Legacy-specific + information. + +2009-08-07 Robert Millan + + * docs/version.texi: New file. Provides version information for + grub.texi. + +2009-08-07 Robert Millan + + * docs/grub.texi: Update CVS information to SVN. + Replace outdated "GRUB 2 will include" phrase with "GRUB 2 includes". + +2009-08-07 Felix Zielcke + + * util/grub-mkconfig.in: Remove a wrong `fi'. + +2009-08-07 Felix Zielcke + + * fs/uuid.c (grub_jfs_superblock): New fields unused2 and uuid. + (grub_jfs_uuid): New function. + (grub_jfs_fs): Set uuid field to grub_jfs_uuid. + +2009-08-07 Felix Zielcke + + * util/grub-mkconfig_lib.in (font_path): Move the functionality + of it to ... + * util/grub-mkconfig.in: ... here. Prefer unicode.pf2 and + unifont.pf2 over ascii.pf2. Export LANG=C in case ascii.pf2 gets used. + +2009-08-07 Robert Millan + + * util/grub.d/10_linux.in (test_numeric): Moved from here ... + * util/grub-mkconfig_lib.in (version_test_numeric): ... to here. + Update all users. + + * util/grub.d/10_linux.in (test_gt): Strip any basename prefix, + not just "vmlinu[zx]". + Moved from here ... + * util/grub-mkconfig_lib.in (version_test_gt): ... to here. Update + all users. + + * util/grub.d/10_linux.in (find_latest): Moved from here ... + * util/grub-mkconfig_lib.in (version_find_latest): ... to here. Update + all users. + +2009-08-07 Robert Millan + + * util/grub.d/10_freebsd.in: Use an absolute device path for + `vfs.root.mountfrom'. Set `vfs.root.mountfrom.options=rw'. + +2009-08-06 Felix Zielcke + + * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Fix + handling of multiple abstraction modules. + +2009-08-04 Robert Millan + + Fix a bug resulting in black screen when loading Linux using a + packed video mode. + + * kern/i386/pc/startup.S (grub_vbe_bios_getset_dac_palette_width): New + function. + + * include/grub/i386/pc/vbe.h (GRUB_VBE_CAPABILITY_DACWIDTH): New macro. + (grub_vbe_bios_getset_dac_palette_width): New function. + (grub_vbe_bios_get_dac_palette_width) + (grub_vbe_bios_set_dac_palette_width): New macros (act as wrappers for + grub_vbe_bios_getset_dac_palette_width()). + + * video/i386/pc/vbe.c (grub_vbe_probe): Use `GRUB_VBE_STATUS_OK' to + check for return status. + (grub_vbe_get_video_mode_info): When getting information for a packed + mode (<= 8 bpp), obtain DAC palette width using + grub_vbe_bios_getset_dac_palette_width(), and use that for initializing + {red,green,blue}_mark_size. + +2009-08-04 Felix Zielcke + + * commands/search.c (options): Fix help output to match actual code. + +2009-08-02 Vladimir Serbinenko + + * commands/hexdump.c (grub_cmd_hexdump): Use grub_disk_read instead + of homegrown code. + +2009-08-01 Vladimir Serbinenko + + * util/hostfs.c (grub_hostfs_dir): Don't use DT_DIR: It doesn't work + on XFS or ReiserFS. + +2009-08-01 Vladimir Serbinenko + + Support Apple partition map with sector size different from 512 bytes. + + * partmap/apple.c (grub_apple_header): New field 'blocksize'. + (apple_partition_map_iterate): Respect 'aheader.blocksize' + and 'apart.partmap_size'. + +2009-08-01 Vladimir Serbinenko +2009-08-01 Robert Millan + + Fix cpuid command. + + * commands/i386/cpuid.c (options): New variable. + (grub_cmd_cpuid): Return real error. + (GRUB_MOD_INIT(cpuid)): Declare options. + +2009-07-31 Vladimir Serbinenko + + * partmap/pc.c (pc_partition_map_iterate): Check that boot flags are + valid. + +2009-07-31 Bean + + * fs/xfs.c (grub_xfs_sblock): Change unused5 field to log2_sect and + log2_inode. + (grub_fshelp_node): Move inode field to the end. + (grub_xfs_data): Remove inode field. + (grub_xfs_inode_block): Calculate inode size using sblock. + (grub_xfs_inode_offset): Likewise. + (grub_xfs_read_inode): Calculate inode size using sblock. + (grub_xfs_read_block): Replace XFS_INODE_EXTENTS with nrec. + (grub_xfs_iterate_dir): Calculate inode size using sblock. + (grub_xfs_mount): Use grub_zalloc instead of grub_malloc. Realloc data + to match inode size. + (grub_xfs_dir): goto mount_fail when mount fails, as data->diropen is + not accessible when data is null. + (grub_xfs_open): Likewise. + +2009-07-31 Bean + + * disk/lvm.c (grub_lvm_scan_device): Ignore extra copy of metadata. + Don't change pv->disk if it's already set. + + * disk/raid.c (grub_raid_scan_device): Merge this function into ... + (grub_raid_register): ... here. + (grub_raid_rescan): Removed. + + * include/grub/raid.h (grub_raid_rescan): Removed. + + * util/grub-fstest.c: Remove include file . + (fstest): Replace grub_raid_rescan with module fini function followed + by init function. + + * util/grub-probe.c: Add include file . + (probe_raid_level): New function. + (probe): Detect abstraction by walking the disk device, support two + level of abstraction (LVM on RAID) when detecting partition map. + +2009-07-31 Pavel Roskin + + * disk/raid5_recover.c (grub_raid5_recover): Revert conversion + to grub_zalloc(), it was erroneous. + Reported by Bean + +2009-07-30 Vladimir Serbinenko + + * util/i386/pc/grub-setup.c (setup): Check that no partition is in + embedding zone, not only the first one. + +2009-07-29 Joe Auricchio + + * term/gfxterm.c (clear_char): New function. + (grub_virtual_screen_setup): Use clear_char. + (scroll_up): Likewise. + (grub_virtual_screen_cls): Likewise. + +2009-07-29 Felix Zielcke + + * util/deviceiter.c (get_acceleraid_disk_name): New static + function. + (grub_util_iterate_devices): Handle Accelraid devices. + * util/hostdisk.c (convert_system_partition_to_system_disk): Likewise. + +2009-07-28 Robert Millan + + * loader/i386/linux.c (grub_cmd_linux): Use ',' rather than ';' as + separator for the suggested gfxpayload string (';' collides with the + parser and needs escaping). + +2009-07-28 Vladimir Serbinenko + + * loader/i386/multiboot_helper.S (grub_multiboot_backward_relocator): + Clear direction flag before jumping to OS. + (grub_multiboot2_real_boot): Likewise. + +2009-07-28 Felix Zielcke + + * util/i386/pc/grub-install: Fix parsing of --disk-module + option. + +2009-07-28 Felix Zielcke + + * util/i386/pc/grub-setup.c (setup): Fix 2 incorrect checks + when embedding. + +2009-07-26 Felix Zielcke + + * util/grub-mkconfig.in (package_version): New variable. + Use it do display the version. + +2009-07-25 Felix Zielcke + + * kern/file.c (grub_file_open): Revert to previous check with + grub_errno. + +2009-07-25 Vladimir Serbinenko + + * commands/probe.c (GRUB_MOD_INIT (probe)): Remove "[--target=target]" + from help line. It's out of sync with code. + +2009-07-25 Vladimir Serbinenko + + * kern/parser.c (grub_parser_execute): Fix a bug causing truncated + entries on failed boot. + +2009-07-25 Felix Zielcke + + * kern/file.c (grub_file_open): Fix an error check. + +2009-07-24 Vladimir Serbinenko + + * util/i386/pc/grub-setup.c (setup): Fix segmentation fault when + partition map couldn't be identified. + +2009-07-23 Pavel Roskin + + * commands/xnu_uuid.c (transform): Use GRUB_CPU_WORDS_BIGENDIAN + instead of WORDS_BIGENDIAN. Use grub_le_to_cpu32(), so that the + case of little endian words becomes just an optimization. + Respect const modifier. + (md5_final): Use code that doesn't depend on endianness. + + * include/grub/misc.h (ALIGN_UP): Cast align to the type of addr + to avoid loss of upper bits if align is unsigned and shorter + than addr. + +2009-07-21 Vladimir Serbinenko + + UUID support for UFS + + * fs/ufs.c (grub_ufs_sblock): Add uuidhi and uuidlow. + (grub_ufs_uuid): New function. + (grub_ufs_fs): add .uuid + +2009-07-21 Pavel Roskin + + * kern/dl.c (grub_dl_check_header): Make static. + +2009-07-21 Felix Zielcke + + * util/grub.d/30_os-prober.in: Remove unused CHAINROOT. Don't + add drivemap for Vista. It breaks Windows 7. + +2009-07-21 Vladimir Serbinenko + + * fs/ufs.c (grub_ufs_sblock): Fix offset of mtime2 which was off by + 128 bytes + +2009-07-20 Vladimir Serbinenko + + Add BFS support + + * conf/common.rmk (grub_probe_SOURCES): Add fs/befs.c. + (grub_fstest_SOURCES): Likewise. + (pkglib_MODULES): Add befs.mod. + (befs_mod_SOURCES): New variable. + (befs_mod_CFLAGS): Likewise. + (befs_mod_LDFLAGS): Likewise. + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-pc.rmk (grub_emu_SOURCES): Likewise. + (grub_setup_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise. + (grub_setup_SOURCES): Likewise. + * fs/befs.c: New file. + * fs/afs.c (GRUB_AFS_FSNAME): New declaration. + (GRUB_AFS_SBLOCK_SECTOR): Likewise. + (GRUB_AFS_SBLOCK_MAGIC1) [MODE_BFS]: New conditional declaration. + (GRUB_AFS_BTREE_MAGIC) [MODE_BFS]: Likewise + (B_KEY_INDEX_ALIGN): New declaration. + (B_KEY_INDEX_OFFSET): Use B_KEY_INDEX_ALIGN. + (grub_afs_bnode) [MODE_BFS]: Make key_count and key_size 16-bit + (grub_afs_btree) [MODE_BFS]: New conditional declaration. + (grub_afs_sblock) [MODE_BFS]: Remove link_count. + (grub_afs_validate_sblock) [MODE_BFS]: Support BFS + (grub_afs_mount) [MODE_BFS]: Likewise. + (grub_afs_dir) [MODE_BFS]: Divide mtime by 65536 and not 1000000. + (grub_afs_fs): Use GRUB_AFS_FSNAME + (GRUB_MOD_INIT (afs)) [MODE_BFS]: Rename to ... + (GRUB_MOD_INIT (befs)) [MODE_BFS]: ... this + (GRUB_MOD_FINI (afs)) [MODE_BFS]: Rename to ... + (GRUB_MOD_FINI (befs)) [MODE_BFS]: ... this + +2009-07-19 Yves BLUSSEAU + + * util/getroot.c (find_root_device): Add support for MacOSX. + * util/hostdisk.c: Likewise. + +2009-07-20 Vladimir Serbinenko + + * font/font.c (find_glyph): Check whether a font is present to avoid + segmentation fault. + +2009-07-20 Joe Auricchio + + * term/gfxterm.c (grub_virtual_screen_setup): Clear virtual_screen. + +2009-07-20 Pavel Roskin + + * configure.ac: Trim excessively wordy excuses. + +2009-07-20 Vladimir Serbinenko + + Add symlink, mtime and label support to AtheFS. + + * fs/afs.c (grub_afs_sblock): Declare `name' as char. + (grub_afs_iterate_dir): Handle symlinks. + (grub_afs_open): Use grub_afs_read_symlink. + (grub_afs_dir): Likewise. + Pass mtime. + (grub_afs_label): New function. + (grub_afs_fs): Add grub_afs_label. + (grub_afs_read_symlink): New function. + +2009-07-20 Vladimir Serbinenko + + Fix AtheFS support. + + * fs/afs.c: Fix comments style. + (grub_afs_blockrun): Declare as packed. + (grub_afs_datastream): Likewise. + (grub_afs_bnode): Likewise. + (grub_afs_btree): Likewise. + (grub_afs_sblock): Likewise. + Declare `name' as char. + (grub_afs_inode): Declare as packed. + Change void *vnode to grub_uint32_t unused. + (grub_afs_iterate_dir): Check that key_size is positive. + (grub_afs_mount): Don't read superblock twice. + (grub_afs_dir): Don't free node in case of error, + grub_fshelp_find_file already handles this. + (grub_afs_open): Likewise. + +2009-07-19 Pavel Roskin + + * Makefile.in: Remove LIBLZO and enable_lzo. + * conf/i386-pc.rmk: Remove lzo support. + * configure.ac: Remove checks for lzo, don't define ENABLE_LZMA. + * include/grub/i386/pc/kernel.h: Define ENABLE_LZMA. Remove lzo + support. + * kern/i386/pc/lzo1x.S: Remove. + * kern/i386/pc/startup.S: Remove lzo support. + * util/i386/pc/grub-mkimage.c: Likewise. + +2009-07-19 Vladimir Serbinenko + + * disk/usbms.c (grub_usbms_transfer): Fix double semicolon. + * fs/xfs.c (grub_xfs_dir): Likewise. + * fs/afs.c (grub_afs_dir): Likewise. + * fs/iso9660.c (grub_iso9660_iterate_dir): Likewise. + (grub_iso9660_open): Likewise. + * fs/jfs.c (grub_jfs_open): Likewise. + * fs/ext2.c (grub_ext2_dir): Likewise. + * include/grub/macho.h (grub_macho_fat_arch): Likewise. + * script/sh/lexer.c (grub_script_yylex): Likewise. + +2009-07-16 Pavel Roskin + + * configure.ac: Never add "-c" to CFLAGS. + + * configure.ac: Fix incorrect comparison for grub_cv_cc_efiemu. + + * configure.ac: Fix wrong use of grub_cv_cc_no_red_zone where + grub_cv_cc_efiemu should be used. + + * configure.ac: Typo fixes. + + * kern/mm.c (grub_zalloc): New function. + (grub_debug_zalloc): Likewise. + * include/grub/mm.h: Declare grub_zalloc() and + grub_debug_zalloc(). + * util/misc.c (grub_zalloc): New function. + * bus/usb/uhci.c (grub_uhci_pci_iter): Use grub_zalloc() + instead of grub_malloc(), remove unneeded initializations. + * bus/usb/usbhub.c (grub_usb_hub_add_dev): Likewise. + * commands/extcmd.c (grub_extcmd_dispatcher): Likewise. + * commands/parttool.c (grub_cmd_parttool): Likewise. + * disk/i386/pc/biosdisk.c (grub_biosdisk_open): Likewise. + * disk/raid5_recover.c (grub_raid5_recover): Likewise. + * disk/raid6_recover.c (grub_raid6_recover): Likewise. + * disk/usbms.c (grub_usbms_finddevs): Likewise. + * efiemu/mm.c (grub_efiemu_request_memalign): Likewise. + * efiemu/pnvram.c (grub_efiemu_pnvram): Likewise. + (grub_cmd_efiemu_pnvram): Likewise. + * fs/i386/pc/pxe.c (grub_pxefs_open): Likewise. + * fs/iso9660.c (grub_iso9660_mount): Likewise. + (grub_iso9660_iterate_dir): Likewise. + * fs/jfs.c (grub_jfs_opendir): Likewise. + * fs/ntfs.c (list_file): Likewise. + (grub_ntfs_mount): Likewise. + * kern/disk.c (grub_disk_open): Likewise. + * kern/dl.c (grub_dl_load_core): Likewise. + * kern/elf.c (grub_elf_file): Likewise. + * kern/env.c (grub_env_context_open): Likewise. + (grub_env_set): Likewise. + (grub_env_set_data_slot): Likewise. + * kern/file.c (grub_file_open): Likewise. + * kern/fs.c (grub_fs_blocklist_open): Likewise. + * loader/i386/multiboot.c (grub_module): Likewise. + * loader/xnu.c (grub_xnu_create_key): Likewise. + (grub_xnu_create_value): Likewise. + * normal/main.c (grub_normal_add_menu_entry): Likewise. + (read_config_file): Likewise. + * normal/menu_entry.c (make_screen): Likewise. + * partmap/sun.c (sun_partition_map_iterate): Likewise. + * script/sh/lexer.c (grub_script_lexer_init): Likewise. + * script/sh/script.c (grub_script_parse): Likewise. + * video/bitmap.c (grub_video_bitmap_create): Likewise. + * video/readers/jpeg.c (grub_video_reader_jpeg): Likewise. + * video/readers/png.c (grub_png_output_byte): Likewise. + (grub_video_reader_png): Likewise. + +2009-07-16 Vladimir Serbinenko + + Enable all targets that can be built by default + + * configure.ac: enable efiemu runtime, grub-emu, grub-emu-usb, + grub-mkfont and grub-fstest if they can be built + +2009-07-16 Vladimir Serbinenko + + Fix hang and segmentation fault in grub-emu-usb + + * disk/scsi.c (grub_scsi_open): return err and not grub_errno + * util/usb.c (grub_libusb_devices): likewise + (grub_libusb_init): rename to ... + (GRUB_MOD_INIT (libusb)):...this + (grub_libusb_fini): rename to .. + (GRUB_MOD_FINI (libusb)):...this + * disk/usbms.c (grub_usbms_transfer): fix retry logic + * include/grub/disk.h (grub_raid_init): removed, it's useless + (grub_raid_fini): likewise + (grub_lvm_init): likewise + (grub_lvm_fini): likewise + * util/grub-emu.c (main): don't call grub_libusb_init, it's done + by grub_init_all + +2009-07-16 Vladimir Serbinenko + + Fix libusb + + * Makefile.in (LIBUSB): new macro + * genmk.rb (Utility/print_tail): new method + (Utility/rule): use intermediary variable #{prefix}_OBJECTS + (top level): call util.print_tail at the end. + +2009-07-16 Vladimir Serbinenko + + Make FreeBSD accept zpool.cache + + * loader/i386/bsd.c (grub_freebsd_add_meta_module): spoof filename if + type is /boot/zfs/zpool.cache + +2009-07-16 Vladimir Serbinenko + + Fix 64-bit efiemu + + * include/grub/efiemu/efiemu.h (grub_efiemu_configuration_table64_t): + correct wrong typedef + * efiemu/prepare.c (SUFFIX (grub_efiemu_prepare)): minor style fixes + +2009-07-15 Pavel Roskin + + * include/grub/disk.h (struct grub_disk_dev): Use enum for id. + * kern/disk.c (struct grub_disk_cache): Likewise. + + * commands/probe.c (options): Typo fix. + + * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_BPB_END): + Increase to 0x5a to accommodate FAT32. Adjust other offsets + accordingly. + Original patch by Yves Blusseau + + * boot/i386/pc/boot.S (general_error_string): Add DOS newline at + the end of "Error" to make the message more readable. + + * boot/i386/pc/boot.S (kernel_segment): Remove. + (copy_buffer): Use GRUB_BOOT_MACHINE_KERNEL_ADDR in segment 0 + for destination. + + * boot/i386/pc/boot.S (boot_version): Remove. + * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_VER_MAJ): + Remove. + + * include/grub/i386/pc/boot.h: Sort all offsets. + (GRUB_BOOT_MACHINE_KERNEL_ADDRESS): Remove, it's unused. + (GRUB_BOOT_MACHINE_KERNEL_SEGMENT): Likewise. + * boot/i386/pc/boot.S: Assert location of every offset listed in + include/grub/i386/pc/boot.h. + +2009-07-13 Pavel Roskin + + * include/grub/i386/coreboot/machine.h: Rename + GRUB_MACHINE_LINUXBIOS to GRUB_MACHINE_COREBOOT. + * loader/multiboot_loader.c (grub_cmd_multiboot_loader): Allow + multiboot 1 for GRUB_MACHINE_COREBOOT and GRUB_MACHINE_QEMU. + + * kern/dl.c: Force native word size to suppress warnings when + compiling grub-emu. + + * kern/device.c (grub_device_iterate): Change struct part_ent to + hold the name, not a pointer to it. Use one grub_malloc() per + partition, not two. Free partition_name if grub_malloc() fails. + Set ents to NULL only before grub_partition_iterate() is called. + +2009-07-11 Bean + + * kern/ieee1275/openfw.c (grub_children_iterate): Fix size of + childname. + +2009-07-10 Bean +2009-07-10 Robert Millan + + * kern/ieee1275/openfw.c (grub_children_iterate) + (grub_devalias_iterate): Fix size evaluation for property or path + strings, which was broken since r2132. + +2009-07-07 Pavel Roskin + + * commands/search.c (search_file): Merge into ... + (search_fs): ... this. Accept search type as argument. + (grub_cmd_search): Pass search type to search_fs(). + + * include/grub/util/console.h: New file. + * util/console.c: Use it instead of grub/machine/console.h. + * util/grub-emu.c: Likewise. + + * lib/arg.c (find_long_option): Remove. + (find_long): Add `len' argument, make `s' const char *. + (grub_arg_parse): Parse long options in place, not in a + temporary buffer. + +2009-07-06 Pavel Roskin + + * commands/search.c (search_fs): Fix potential NULL pointer + dereference. + + * commands/search.c (search_fs): Replace QUID macro with quid_fn + function pointer. + +2009-07-06 Daniel Mierswa + + * commands/search.c (search_fs): Use grub_strcasecmp() for UUID + comparison. + +2009-07-05 Pavel Roskin + + * include/grub/i386/linux.h (struct linux_kernel_params): + Restore padding3, it's still needed. + + * util/grub.d/10_freebsd.in: Fix spelling of `device.hints' on + FreeBSD. + * util/osdetect.lua: Likewise. + +2009-07-05 Bean + + * conf/common.rmk (lua_mode_SOURCES): Add script/lua/lstrlib.c. + + * script/lua/grub_lib.c (grub_lua_run): Check input parameter. + (grub_lua_getenv): Likewise. + (grub_lua_setenv): Likewise. + (save_errno): New function. + (push_result): Likewise. + (grub_lua_enum_device): Likewise. + (grub_lua_enum_file): Likewise. + (grub_lua_file_open): Likewise. + (grub_lua_file_close): Likewise. + (grub_lua_file_seek): Likewise. + (grub_lua_file_read): Likewise. + (grub_lua_file_getline): Likewise. + (grub_lua_file_getsize): Likewise. + (grub_lua_file_getpos): Likewise. + (grub_lua_file_eof): Likewise. + (grub_lua_file_exist): Likewise. + (grub_lua_add_menu): Likewise. + + * script/lua/grub_lua.h (isupper): New inline function. + (islower): Likewise. + (ispunct): Likewise. + (isxdigit): Likewise. + (strcspn): Change to normal function. + (strpbkr): New function declaration. + (memchr): Likewise. + + * script/lua/grub_main.c (scan_str): New function. + (strcspn): Likewise. + (strpbrk): Likewise. + (memchr): Likewise. + + * script/lua/linit.c (lualibs): Enable the string library. + + * util/osdetect.lua: New file. + +2009-07-04 Robert Millan + + * include/grub/i386/linux.h (struct linux_kernel_params): Add + `capabilities' member. + +2009-07-02 Pavel Roskin + + * genparttoollist.sh: Add missing newline at the end. + +2009-07-01 Pavel Roskin + + * kern/x86_64/efi/callwrap.S: Add missing newline at the end. + + * util/hostdisk.c (open_device): Remove `const' from + `sysctl_size', as sysctlbyname() can change it (in this case it + doesn't actually happen). + + * include/grub/types.h: Define GRUB_LONG_MAX and GRUB_LONG_MIN + using signed long int constants. + + * util/hostdisk.c (grub_util_biosdisk_get_grub_dev): Make `p' + constant to avoid a warning on FreeBSD. + + * util/hostdisk.c (device_is_wholedisk): Compile only on systems + where it's needed. + + * Makefile.in: Install include/grub/machine symlink. + + * Makefile.in: When installing symlinks, use "cp -fR", which + works on FreeBSD and MacOSX. + From Yves Blusseau + + * kern/dl.c (grub_dl_resolve_symbol): Make static. + * include/grub/dl.h: Remove grub_dl_resolve_symbol(). + + * util/misc.c: Move grub_reboot() and grub_halt() ... + * util/grub-emu.c: ... here. Make main_env static. + * include/grub/util/misc.h: Remove main_env. + + * kern/mm.c: Use correct format to print size_t. + + * include/grub/elf.h: Define Elf_Sword and Elf_Xword. + * kern/i386/dl.c: Use ELF symbols without "32" or "64". + * kern/powerpc/dl.c: Likewise. + * kern/sparc64/dl.c: Likewise. + * kern/x86_64/dl.c: Likewise. + +2009-07-01 Robert Millan + + Fix grub-emu build on sparc64-ieee1275. + + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Synchronize with ... + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): ... this. + +2009-07-01 Robert Millan + + * util/misc.c: Include `' and `'. + (grub_reboot, grub_halt): New functions. + + * util/i386/pc/misc.c: Delete. Update all users. + * util/sparc64/ieee1275/misc.c: Likewise. + * util/powerpc/ieee1275/misc.c: Likewise. + +2009-07-01 Robert Millan + + * conf/i386.rmk (setjmp_mod_SOURCES) + (setjmp_mod_ASFLAGS, setjmp_mod_LDFLAGS): Move to ... + * conf/common.rmk (setjmp_mod_SOURCES) + (setjmp_mod_ASFLAGS, setjmp_mod_LDFLAGS): ... here, and modify + to use $(target_cpu). + * conf/x86_64-efi.rmk (setjmp_mod_SOURCES) + (setjmp_mod_ASFLAGS, setjmp_mod_LDFLAGS): Remove. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + + * conf/i386-pc.rmk (kernel_img_SOURCES): Use + $(target_cpu) for kern/$(target_cpu)/dl.c. + * conf/i386-efi.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * conf/i386-coreboot.rmk: Likewise. + * conf/powerpc-ieee1275.rmk (kernel_img_SOURCES): Use + $(target_cpu) for kern/$(target_cpu)/dl.c and for + kern/$(target_cpu)/cache.S. + * conf/sparc64-ieee1275.rmk: Likewise. + +2009-07-01 Robert Millan + + * include/grub/i386/linux.h (linux_kernel_params): Change `mmap_size' + type to `grub_uint8_t', and adjust `padding9' accordingly. + +2009-06-29 Robert Millan + + * include/grub/i386/linux.h (GRUB_VIDEO_TYPE_TEXT): New macro. + + * loader/i386/linux.c [__i386__] (grub_linux_boot): Simplify inline + assembly in final jump, using register constraints. + + (grub_linux_boot): For text mode, initialize `have_vga' using + GRUB_VIDEO_TYPE_TEXT rather than 0 (this changes its value to 1). + + Initialize `video_cursor_x' and `video_cursor_y' as late as possible, + right before the final jump. + + Set `video_mode' to 0x3. + + Document initialization of `video_page', `video_mode' and + `video_ega_bx'. + +2009-06-29 Robert Millan + + * include/grub/i386/linux.h (GRUB_LINUX_FLAG_QUIET): New macro. + * loader/i386/linux.c (grub_cmd_linux): Recognize "quiet" option, + and set GRUB_LINUX_FLAG_QUIET appropriately. + +2009-06-29 Robert Millan + + Fix build on Debian / sparc. + + * configure.ac: Recognize `sparc' target_cpu (as sparc64). + +2009-06-28 Pavel Roskin + + * kern/i386/qemu/mmap.c (grub_machine_mmap_iterate): Use cast to + fix a warning. + + * util/grub.d/10_linux.in: Match SUSE style initrd names. + +2009-06-27 Robert Millan + + * loader/i386/linux.c (grub_linux_boot): Fix uninitialized use of + `err'. + +2009-06-27 Robert Millan + + Revert r2338. + + * loader/i386/linux.c (grub_cmd_linux): Don't call grub_error when + file can't be opened. grub_file_open() is already supposed to set + grub_errno / grub_errmsg appropriately. + * loader/i386/pc/linux.c (grub_cmd_linux): Likewise. + +2009-06-27 Pavel Roskin +2009-06-27 Robert Millan + + * include/grub/dl.h: Include grub/elf.h. + (struct grub_dl): Add symtab field. + * kern/dl.c [GRUB_MACHINE_QEMU]: Define + GRUB_MODULES_MACHINE_READONLY. + (grub_dl_resolve_symbols): Populate mod->symtab, making a copy + of the header for read-only modules. + (grub_dl_unload): Free mod->symtab for read-only modules. + * kern/i386/dl.c: Use mod->symtab. + * kern/powerpc/dl.c: Likewise. + * kern/sparc64/dl.c: Likewise. + * kern/x86_64/dl.c: Likewise. + + * conf/i386-qemu.rmk: New file. + * kern/i386/qemu/startup.S: Likewise. + * kern/i386/qemu/mmap.c: Likewise. + * boot/i386/qemu/boot.S: Likewise. + * include/grub/i386/qemu/time.h: Likewise. + * include/grub/i386/qemu/serial.h: Likewise. + * include/grub/i386/qemu/kernel.h: Likewise. + * include/grub/i386/qemu/console.h: Likewise. + * include/grub/i386/qemu/boot.h: Likewise. + * include/grub/i386/qemu/init.h: Likewise. + * include/grub/i386/qemu/machine.h: Likewise. + * include/grub/i386/qemu/loader.h: Likewise. + * include/grub/i386/qemu/memory.h: Likewise. + + * conf/i386-coreboot.rmk (GRUB_BOOT_MACHINE_LINK_ADDR) + (GRUB_KERNEL_MACHINE_LINK_ADDR): New variables. + [qemu] (pkglib_IMAGES): Add `boot.img'. + [qemu] (boot_img_SOURCES, boot_img_ASFLAGS, boot_img_LDFLAGS) + [qemu] (boot_img_FORMAT): New variables. + [qemu] (bin_UTILITIES): Add `grub-mkimage'. + [qemu] (grub_mkimage_SOURCES, grub_mkimage_CFLAGS): New variables. + [qemu] (kernel_img_SOURCES, kernel_img_HEADERS, kernel_img_CFLAGS) + [qemu] (kernel_img_ASFLAGS, kernel_img_LDFLAGS) + [qemu] (kernel_img_FORMAT): New variables. + + * configure.ac: Recognise `i386-qemu'. + + * util/i386/pc/grub-mkimage.c (compress_kernel): Add dummy variant + (for no compression). + [GRUB_MACHINE_QEMU] (generate_image): Misc adjustments to produce + a valid i386 ROM image. Make `GRUB_KERNEL_MACHINE_COMPRESSED_SIZE', + `GRUB_KERNEL_MACHINE_INSTALL_DOS_PART' and + `GRUB_KERNEL_MACHINE_INSTALL_BSD_PART' optional features (with + ifdefs). + +2009-06-27 Pavel Roskin + + * efiemu/prepare.c: Eliminate TYPE macro, it makes code hard to + read. + * efiemu/prepare32.c: Likewise. + * efiemu/prepare64.c: Likewise. + +2009-06-26 Pavel Roskin + + * include/grub/types.h: Define GRUB_TARGET_WORDSIZE. + * include/grub/elf.h: Define symbols without "32" or "64" based + on GRUB_TARGET_WORDSIZE. + * include/grub/multiboot2.h: Use GRUB_TARGET_WORDSIZE. + * efiemu/loadcore32.c: Redefine GRUB_TARGET_WORDSIZE, remove own + ELF definitions. + * efiemu/loadcore64.c: Likewise. + * loader/i386/bsd32.c: Likewise. + * loader/i386/bsd64.c: Likewise. + * kern/dl.c: Remove own ELF definitions. + * util/i386/efi/grub-mkimage.c: Likewise. + +2009-06-23 Robert Millan + + * kern/i386/pc/startup.S (real_to_prot): Access `gdtdesc' using + segment 0x0 unconditionally, because the reference generated by + GAS is an absolute address. + +2009-06-22 Robert Millan + + * include/grub/i386/kernel.h: Include `'. + [! GRUB_MACHINE_IEEE1275]: Set `GRUB_MOD_ALIGN' to 0x1. + +2009-06-22 Robert Millan + + * commands/search.c (grub_cmd_search): Macroify hardcoded args[] + indexes. Check for -f explicitly. + (search_file): Improve error message. + (GRUB_MOD_INIT(search)): Add missing `-n' to help output. + +2009-06-22 Robert Millan + + * conf/i386-pc.rmk (GRUB_MEMORY_MACHINE_LINK_ADDR): Rename to ... + (GRUB_KERNEL_MACHINE_LINK_ADDR): ... this. Update all users. + +2009-06-22 Robert Millan + + * conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/i386/misc.S'. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-coreboot.rmk: Likewise. + + * kern/i386/pc/startup.S (grub_stop): Remove function. + * kern/i386/ieee1275/startup.S: Likewise. + * kern/i386/coreboot/startup.S: Likewise. + * kern/i386/misc.S (grub_stop): New function. + +2009-06-22 Robert Millan + + * kern/i386/pc/startup.S (real_to_prot): Move from here ... + * kern/i386/realmode.S (real_to_prot): ... to here. + +2009-06-22 Robert Millan + + * conf/i386-ieee1275.rmk (pkglib_PROGRAMS): Replace `kernel.elf' + with `kernel.img'. + (kernel_elf_SOURCES): Rename to ... + (kernel_img_SOURCES): ... this. + (kernel_elf_HEADERS): Rename to ... + (kernel_img_HEADERS): ... this. Update all users. + (kernel_elf_ASFLAGS): Rename to ... + (kernel_img_ASFLAGS): ... this. + (kernel_elf_CFLAGS): Rename to ... + (kernel_img_CFLAGS): ... this. + (kernel_elf_LDFLAGS): Rename to ... + (kernel_img_LDFLAGS): ... this. + * conf/i386-coreboot.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + + * util/elf/grub-mkimage.c (add_segments): Replace "kernel.elf" + with "kernel.img". + +2009-06-21 Pavel Roskin + + * loader/powerpc/ieee1275/linux.c (offset_phdr): Fix prototypes + to match nested functions. + * loader/sparc64/ieee1275/linux.c: Likewise. + + * conf/i386-ieee1275.rmk: Define kernel_elf_ASFLAGS. + +2009-06-21 Robert Millan + + * configure.ac: Enable `END_SYMBOL' / `BSS_START_SYMBOL' test on + all i386 platforms. + +2009-06-21 Robert Millan + + Fix asm file handling on ELF, and remove workarounds. + + * genmk.rb (class Programs): Detect assembly files, and set ASFLAGS + and -DASM_FILE=1 appropriately (copied from `class Images' stanza). + * kern/i386/ieee1275/startup.S (ASM_FILE): Remove macro. + * kern/i386/coreboot/startup.S (ASM_FILE): Likewise. + +2009-06-21 Vladimir Serbinenko + + Load BSD ELF modules + + * conf/i386-pc.rmk (bsd_mod_SOURCES): Add loader/i386/bsd32.c + and loader/i386/bsd64.c + * include/grub/i386/bsd.h (FREEBSD_MODTYPE_MODULE): Remove + (FREEBSD_MODTYPE_ELF_MODULE): New definition + (FREEBSD_MODTYPE_ELF_MODULE_OBJ): Likewise + (grub_freebsd_load_elfmodule32): New declaration + (grub_freebsd_load_elfmoduleobj64): Likewise + (grub_freebsd_load_elf_meta32): Likewise + (grub_freebsd_load_elf_meta64): Likewise + (grub_freebsd_add_meta): Likewise + (grub_freebsd_add_meta_module): Likewise + * loader/i386/bsd.c (grub_freebsd_add_meta): Make global + (grub_freebsd_add_meta_module): Likewise and move module-specific + parts to grub_cmd_freebsd and grub_cmd_freebsd_module + (grub_cmd_freebsd): Add elf-kernel specific parts + based on grub_freebsd_add_meta_module + (grub_cmd_freebsd_module): Add type parsing moved from + grub_freebsd_add_meta_module + (grub_cmd_freebsd_module_elf): New function + (cmd_freebsd_module_elf): New variable + (GRUB_MOD_INIT): Register freebsd_module_elf + * loader/i386/bsd32.c: New file + * loader/i386/bsd64.c: Likewise + * loader/i386/bsdXX.c: Likewise + * kern/elf.c (grub_elf32_load): Let hook decide which pheaders to load + (grub_elf64_load): Likewise + * include/grub/elfload.h (grub_elf32_load_hook_t): New parameter do_load + All users updated + (grub_elf64_load_hook_t): Likewise + +2009-06-21 Colin Watson + + * util/grub-mkconfig.in (GRUB_DISABLE_LINUX_RECOVERY): Export + variable. + * util/grub.d/10_linux.in: If GRUB_DISABLE_LINUX_RECOVERY is true, + don't write a menu entry for recovery mode. + +2009-06-20 Robert Millan + + * util/i386/pc/grub-mkimage.c (main): Oops, free `output' only + after it's no longer needed. + +2009-06-20 Robert Millan + + * include/grub/i386/loader.h (grub_linux_prot_size) + (grub_linux_tmp_addr, grub_linux_real_addr) + (grub_linux_is_bzimage, grub_linux16_boot): Declare only on + GRUB_MACHINE_PCBIOS. + * util/i386/pc/grub-mkimage.c (compress_kernel): Move + common grub_util_info() call to ... + (generate_image): ... here. + Fix use of uninitialized memory, comparison of signed with + unsigned integers and memory leak. + Remove bogus module address message. + +2009-06-20 Vladimir Serbinenko + + * disk/mdraid_linux.c (GRUB_MOD_FINI): use grub_raid_unregister and not + grub_raid_register + * disk/dmraid_nvidia.c (GRUB_MOD_FINI): likewise + +2009-06-19 Pavel Roskin + + * configure.ac: Remove stray AC_MSG_CHECKING. + +2009-06-19 Vladimir Serbinenko + + * disk/scsi.c (grub_scsi_open): use continue instead of big if + +2009-06-18 Pavel Roskin + + * conf/common.rmk: Add fs_file.mod. + * disk/fs_file.c: New file. + * include/grub/disk.h (enum grub_disk_dev_id): Add + GRUB_DISK_DEVICE_FILE_ID. + +2009-06-18 Vladimir Serbinenko + + Fix build with Apple's toolchain. Part 2 + + * aclocal.m4 (grub_PROG_TARGET_CC): add missing prototype for main and + a fake start + +2009-06-18 Vladimir Serbinenko + + Fix build with Apple's toolchain. Part 1 + + * commands/i386/pc/drivemap_int13h.S: use assembly-time constants + for long calls + * configure.ac: remove a leftover AC_MSG_RESULT + (CFLAGS): don't add -Wl,--defsym,___main=0x8100 when building with + Apple's toolchain + +2009-06-18 Vladimir Serbinenko + + Fix warnings + + * fs/ntfscomp.c (decomp_get16): initialize c1 and c2 + (decomp_block): initialize ch + use grub_memcpy instead of memcpy + +2009-06-17 Pavel Roskin + + * include/grub/i386/coreboot/console.h: Don't use the i386-pc + version, use declarations needed to use vga_text as the startup + console. + + * conf/i386-coreboot.rmk (kernel_elf_SOURCES): Remove + term/i386/pc/at_keyboard.c, it doesn't need to be compiled into + the kernel. + * kern/i386/coreboot/init.c: Don't call grub_at_keyboard_init() + and grub_at_keyboard_fini(), it's done on module load and + unload. + +2009-06-17 Felix Zielcke + + * loader/i386/linux.c (grub_cmd_linux): Set grub_error if the + file can't be found. + * loader/i386/pc/linux.c (grub_cmd_linux): Likewise. + +2009-06-17 Vladimir Serbinenko + + Fix newline handling + + * include/grub/script_sh.h (grub_lexer_param): new field was_newline + * script/sh/lexer.c (grub_script_lexer_init): initialize was_newline + (grub_script_yylex): don't segfault on unterminated script + newline terminates command and variable + +2009-06-17 Vladimir Serbinenko + + avoid double grub_adjust_range call. Bug reported by David Simner + + * kern/disk.c (grub_disk_write): change to raw disk access before + calling disk_read + +2009-06-17 Colin Watson + + * util/elf/grub-mkimage.c (usage): Prefix each option line with two + spaces, for the benefit of help2man. + * util/i386/efi/grub-mkimage.c (usage): Likewise. + +2009-06-16 Pavel Roskin + + * kern/i386/halt.c: Include grub/machine/init.h. + * kern/i386/reboot.c: Include grub/cpu/reboot.h. + +2009-06-16 Felix Zielcke + + * util/grub.d/30_os-prober.in: Use ${root} in the generated + drivemap menuentry. + +2009-06-16 James Jarvis + + * commands/help.c GRUB_MOD_INIT(echo): Fix the help output of + `echo' command. + +2009-06-16 Pavel Roskin + + * boot/i386/pc/boot.S: Remove root_drive. Assert offset of + boot_drive_check by using GRUB_BOOT_MACHINE_DRIVE_CHECK. Don't + save %dx, we only need %dl and we never change it. + * boot/i386/pc/cdboot.S: Don't set the root drive. + * boot/i386/pc/pxeboot.S: Likewise. + * include/grub/i386/pc/boot.h: Remove + GRUB_BOOT_MACHINE_ROOT_DRIVE, adjust + GRUB_BOOT_MACHINE_DRIVE_CHECK. + * include/grub/i386/pc/kernel.h: Remove grub_root_drive. + * kern/i386/pc/init.c (make_install_device): Remove references + to grub_root_drive. + * kern/i386/pc/startup.S: Likewise. + * util/i386/pc/grub-setup.c (setup): Don't set root_drive. + +2009-06-16 Vladimir Serbinenko + + xnu_uuid command + + * commands/xnu_uuid.c: new file + * conf/common.rmk (pkglib_MODULES): add xnu_uuid.mod + (xnu_uuid_mod_SOURCES): new variable + (xnu_uuid_mod_CFLAGS): likewise + (xnu_uuid_mod_LDFLAGS): likewise + * conf/i386-coreboot.rmk (grub_emu_SOURCES): add commands/probe.c + * conf/i386-ieee1275.rmk: likewise + * conf/i386-pc.rmk: likewise + * conf/powerpc-ieee1275.rmk: likewise + * conf/sparc64-ieee1275.rmk: likewise + * util/grub.d/30_os-prober.in: use UUID for Mac OS X/Darwin + +2009-06-16 Pavel Roskin + + * configure.ac: Avoid '==' in test command, it's not portable. + +2009-06-16 Vladimir Serbinenko + + Probe command + + * commands/probe.c: new file + * conf/common.rmk (pkglib_MODULES): add probe.mod + (probe_mod_SOURCES): new variable + (probe_mod_CFLAGS): likewise + (probe_mod_LDFLAGS): likewise + * conf/i386-coreboot.rmk (grub_emu_SOURCES): add commands/probe.c + * conf/i386-ieee1275.rmk: likewise + * conf/i386-pc.rmk: likewise + * conf/powerpc-ieee1275.rmk: likewise + * conf/sparc64-ieee1275.rmk: likewise + +2009-06-15 Vladimir Serbinenko + + Fix handling of string like \"hello\" and "a + b" + + * script/sh/lexer.c (check_textstate): accept GRUB_PARSER_STATE_ESC + (grub_script_yylex): fix parsing of quoting, escaping and newline + +2009-06-13 Vladimir Serbinenko + + * loader/i386/multiboot.c (grub_multiboot_get_bootdev): fix partition + handling + +2009-06-13 Jun Inoue + + * util/grub-mkconfig.in: Fix parsing of --output option. + +2009-06-12 Pavel Roskin + + * Makefile.in (pkgdata_SRCDIR): Remove. genmodsrc.sh and + genmk.rb don't need to be generated or installed. + +2009-06-12 Vladimir Serbinenko + + * commands/i386/pc/drivemap_int13h.S: add more comments + +2009-06-11 Pavel Roskin + + * Makefile.in (uninstall): Uninstall manuals. + + * Makefile.in: Rename lib_DATA to lib_SCRIPTS, move it from + PKGLIB to SCRIPTS. This fixes installation of grub-mkconfig_lib + and update-grub_lib in two places. + * conf/common.rmk: Rename lib_DATA to lib_SCRIPTS. + + * disk/usbms.c (grub_usbms_transfer): Initialize `err' to fix + a compiler warning. + + * loader/i386/bsd.c (grub_freebsd_boot): Rename `entry' to + `entry_lo' to fix variable shadowing. + +2009-06-11 Christian Franke + + * kern/misc.c (__enable_execute_stack): Add missing return type + to prevent gcc warning. + +2009-06-11 Felix Zielcke + + * conf/i386-ieee1275.rmk (COMMON_LDFLAGS): Remove `-static -lgcc'. + +2009-06-11 Pavel Roskin + + * Makefile.in: Don't rely on any scripts being executable. + Always use $(SHELL) to run shell scripts. + + * configure.ac: Always define ___main if using -nostdlib. This + fixes tests on Cygwin. + +2009-06-11 Giuseppe Caizzone + + UDF fix + + * fs/udf.c (grub_udf_read_block): handle the fact that ad->length + is in bytes and not in blocks + +2009-06-11 Pavel Roskin + + * kern/i386/halt.c (grub_halt): Make `i' unsigned to fix a + warning. + +2009-06-11 Felix Zielcke + + * util/grub.d/30_os-prober.in: Fix a comment. Source + ${libdir}/grub/grub-mkconfig_lib. Use prepare_grub_to_access_device + to set the root device. Place drivemap command in the generated + chain entry. + +2009-06-11 Pavel Roskin + + * configure.ac: Remove host_m32. Issues with 64-bit utilities + have long been resolved. + +2009-06-11 Colin Watson + + * util/grub.d/10_linux.in: Capitalise "Linux". + + * util/grub-pe2elf.c (usage): Fix references to grub-editenv. + +2009-06-11 Pavel Roskin + + * kern/efi/efi.c (grub_exit): Add infinite loop at the end to + fix a gcc warning and ensure that the function won't ever exit. + + * kern/i386/ieee1275/init.c: Add missing prototype for + grub_stop_floppy(). + + * loader/ieee1275/multiboot2.c [__i386__]: Include + grub/cpu/multiboot.h. + + * term/i386/pc/serial.c (serial_translate_key_sequence): Avoid + casts to short - they are not portable and cause warnings. Fix + use of uninitialized values in input_buf. Use ARRAY_SIZE. + +2009-06-11 Vladimir Serbinenko + + Drivemap fixes + + * commands/i386/pc/drivemap.c (grub_get_root_biosnumber_drivemap): + new function + (grub_get_root_biosnumber_saved): new variable + (GRUB_MOD_INIT): register grub_get_root_biosnumber_drivemap + (GRUB_MOD_FINI): unregister grub_get_root_biosnumber_drivemap + * commands/i386/pc/drivemap_int13h.S (grub_drivemap_handler): restore + %dx after the call if necessary + * conf/common.rmk (pkglib_MODULES): remove boot.mod + (boot_mod_SOURCES): remove + (boot_mod_CFLAGS): remove + (boot_mod_LDFLAGS): remove + * conf/i386-coreboot.rmk (pkglib_MODULES): add boot.mod + (boot_mod_SOURCES): new variable + (boot_mod_CFLAGS): likewise + (boot_mod_LDFLAGS): likewise + * conf/i386-efi.rmk: likewise + * conf/i386-ieee1275.rmk: likewise + * conf/i386-pc.rmk: likewise + * conf/powerpc-ieee1275.rmk: likewise + * conf/sparc64-ieee1275.rmk: likewise + * conf/x86_64-efi.rmk: likewise + * include/grub/i386/pc/biosnum.h: new file + * lib/i386/pc/biosnum.c: likewise + * loader/i386/bsd.c (grub_bsd_get_device): use grub_get_root_biosnumber + * loader/i386/multiboot.c (grub_multiboot_get_bootdev): likewise + * loader/i386/pc/chainloader.c (grub_chainloader_cmd): likewise + +2009-06-10 Pavel Roskin + + * io/gzio.c (test_header): Don't reuse one buffer for all data. + Use separate variables. Read only the file size at the end, but + not the checksum that we don't use. + + * kern/file.c (grub_file_read): Use void pointer for the buffer. + Adjust all callers. + + * kern/ieee1275/openfw.c: Remove libc includes. + * kern/ieee1275/cmain.c: Likewise. + * include/grub/ieee1275/ieee1275.h: Likewise. + + * kern/i386/coreboot/init.c: Include grub/cpu/tsc.h to fix + compiler warnings. + +2009-06-10 Felix Zielcke + + * Makefile.in: Remove all trailing whitespace. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * docs/grub.texi: Likewise. + * docs/texinfo.tex: Likewise. + * disk/fs_uuid.c: Likewise. + * disk/lvm.c: Likewise. + * disk/scsi.c: Likewise. + * disk/ata.c: Likewise. + * disk/ieee1275/ofdisk.c: Likewise. + * disk/i386/pc/biosdisk.c: Likewise. + * disk/host.c: Likewise. + * disk/raid.c: Likewise. + * disk/efi/efidisk.c: Likewise. + * disk/usbms.c: Likewise. + * disk/memdisk.c: Likewise. + * disk/loopback.c: Likewise. + * kern/powerpc/dl.c: Likewise. + * kern/device.c: Likewise. + * kern/dl.c: Likewise. + * kern/sparc64/dl.c: Likewise. + * kern/ieee1275/ieee1275.c: Likewise. + * kern/term.c: Likewise. + * kern/fs.c: Likewise. + * kern/i386/dl.c: Likewise. + * kern/i386/pc/startup.S: Likewise. + * kern/i386/pc/init.c: Likewise. + * kern/i386/pc/mmap.c: Likewise. + * kern/i386/pc/lzo1x.S: Likewise. + * kern/i386/ieee1275/init.c: Likewise. + * kern/i386/realmode.S: Likewise. + * kern/i386/tsc.c: Likewise. + * kern/partition.c: Likewise. + * kern/corecmd.c: Likewise. + * kern/file.c: Likewise. + * kern/efi/efi.c: Likewise. + * kern/efi/init.c: Likewise. + * kern/efi/mm.c: Likewise. + * kern/main.c: Likewise. + * kern/err.c: Likewise. + * kern/env.c: Likewise. + * kern/disk.c: Likewise. + * kern/generic/millisleep.c: Likewise. + * kern/generic/rtc_get_time_ms.c: Likewise. + * kern/misc.c: Likewise. + * kern/parser.c: Likewise. + * genmk.rb: Likewise. + * configure.ac: Likewise. + * boot/i386/pc/diskboot.S: Likewise. + * boot/i386/pc/pxeboot.S: Likewise. + * boot/i386/pc/boot.S: Likewise. + * boot/i386/pc/lnxboot.S: Likewise. + * boot/i386/pc/cdboot.S: Likewise. + * parttool/pcpart.c: Likewise. + * video/readers/tga.c: Likewise. + * video/video.c: Likewise. + * video/bitmap.c: Likewise. + * lib/envblk.c: Likewise. + * lib/i386/setjmp.S: Likewise. + * fs/xfs.c: Likewise. + * fs/afs.c: Likewise. + * fs/fat.c: Likewise. + * fs/ntfs.c: Likewise. + * fs/udf.c: Likewise. + * fs/affs.c: Likewise. + * fs/iso9660.c: Likewise. + * fs/hfs.c: Likewise. + * fs/fshelp.c: Likewise. + * fs/ext2.c: Likewise. + * fs/jfs.c: Likewise. + * fs/reiserfs.c: Likewise. + * fs/hfsplus.c: Likewise. + * fs/minix.c: Likewise. + * fs/cpio.c: Likewise. + * fs/sfs.c: Likewise. + * fs/ufs.c: Likewise. + * efiemu/prepare.c: Likewise. + * efiemu/loadcore_common.c: Likewise. + * efiemu/runtime/efiemu.sh: Likewise. + * efiemu/runtime/efiemu.S: Likewise. + * efiemu/runtime/efiemu.c: Likewise. + * efiemu/pnvram.c: Likewise. + * efiemu/main.c: Likewise. + * efiemu/i386/pc/cfgtables.c: Likewise. + * efiemu/i386/loadcore64.c: Likewise. + * efiemu/i386/loadcore32.c: Likewise. + * efiemu/loadcore.c: Likewise. + * efiemu/symbols.c: Likewise. + * efiemu/mm.c: Likewise. + * include/grub/autoefi.h: Likewise. + * include/grub/datetime.h: Likewise. + * include/grub/term.h: Likewise. + * include/grub/hfs.h: Likewise. + * include/grub/lvm.h: Likewise. + * include/grub/i386/tsc.h: Likewise. + * include/grub/i386/linux.h: Likewise. + * include/grub/i386/xnu.h: Likewise. + * include/grub/i386/efiemu.h: Likewise. + * include/grub/i386/pc/biosdisk.h: Likewise. + * include/grub/i386/pc/memory.h: Likewise. + * include/grub/i386/pc/vbe.h: Likewise. + * include/grub/parttool.h: Likewise. + * include/grub/video.h: Likewise. + * include/grub/memory.h: Likewise. + * include/grub/fs.h: Likewise. + * include/grub/partition.h: Likewise. + * include/grub/xnu.h: Likewise. + * include/grub/efi/api.h: Likewise. + * include/grub/efi/pe32.h: Likewise. + * include/grub/efi/memory.h: Likewise. + * include/grub/multiboot.h: Likewise. + * include/grub/usbdesc.h: Likewise. + * include/grub/multiboot2.h: Likewise. + * include/grub/acpi.h: Likewise. + * include/grub/efiemu/efiemu.h: Likewise. + * include/grub/disk.h: Likewise. + * include/grub/ieee1275/ieee1275.h: Likewise. + * include/grub/net.h: Likewise. + * include/grub/machoload.h: Likewise. + * include/grub/macho.h: Likewise. + * include/multiboot.h: Likewise. + * genmoddep.awk: Likewise. + * normal/main.c: Likewise. + * normal/menu_entry.c: Likewise. + * normal/menu_viewer.c: Likewise. + * normal/completion.c: Likewise. + * normal/cmdline.c: Likewise. + * normal/misc.c: Likewise. + * normal/datetime.c: Likewise. + * bus/usb/usbtrans.c: Likewise. + * bus/usb/ohci.c: Likewise. + * bus/usb/uhci.c: Likewise. + * bus/usb/usb.c: Likewise. + * mmap/efi/mmap.c: Likewise. + * mmap/i386/pc/mmap_helper.S: Likewise. + * mmap/i386/pc/mmap.c: Likewise. + * mmap/i386/mmap.c: Likewise. + * mmap/i386/uppermem.c: Likewise. + * mmap/mmap.c: Likewise. + * commands/acpi.c: Likewise. + * commands/echo.c: Likewise. + * commands/blocklist.c: Likewise. + * commands/loadenv.c: Likewise. + * commands/usbtest.c: Likewise. + * commands/boot.c: Likewise. + * commands/parttool.c: Likewise. + * commands/search.c: Likewise. + * commands/cat.c: Likewise. + * commands/i386/pc/play.c: Likewise. + * commands/i386/pc/drivemap.c: Likewise. + * commands/i386/pc/vbeinfo.c: Likewise. + * commands/i386/pc/acpi.c: Likewise. + * commands/i386/pc/vbetest.c: Likewise. + * commands/ls.c: Likewise. + * commands/cmp.c: Likewise. + * commands/test.c: Likewise. + * commands/efi/acpi.c: Likewise. + * commands/gptsync.c: Likewise. + * commands/help.c: Likewise. + * partmap/amiga.c: Likewise. + * partmap/apple.c: Likewise. + * partmap/acorn.c: Likewise. + * partmap/pc.c: Likewise. + * partmap/sun.c: Likewise. + * partmap/gpt.c: Likewise. + * script/sh/lexer.c: Likewise. + * script/sh/function.c: Likewise. + * font/font.c: Likewise. + * font/font_cmd.c: Likewise. + * loader/powerpc/ieee1275/linux.c: Likewise. + * loader/efi/chainloader.c: Likewise. + * loader/multiboot_loader.c: Likewise. + * loader/macho.c: Likewise. + * loader/i386/multiboot.c: Likewise. + * loader/i386/linux.c: Likewise. + * loader/i386/pc/linux.c: Likewise. + * loader/i386/pc/multiboot2.c: Likewise. + * loader/i386/pc/chainloader.c: Likewise. + * loader/i386/pc/xnu.c: Likewise. + * loader/i386/bsd_trampoline.S: Likewise. + * loader/i386/efi/linux.c: Likewise. + * loader/i386/multiboot_elfxx.c: Likewise. + * loader/i386/bsd_helper.S: Likewise. + * loader/i386/bsd.c: Likewise. + * loader/i386/linux_trampoline.S: Likewise. + * loader/i386/xnu_helper.S: Likewise. + * loader/i386/xnu.c: Likewise. + * loader/i386/bsd_pagetable.c: Likewise. + * loader/i386/multiboot_helper.S: Likewise. + * loader/xnu.c: Likewise. + * loader/xnu_resume.c: Likewise. + * io/gzio.c: Likewise. + * term/efi/console.c: Likewise. + * term/terminfo.c: Likewise. + * term/ieee1275/ofconsole.c: Likewise. + * term/i386/pc/serial.c: Likewise. + * term/i386/pc/vesafb.c: Likewise. + * term/i386/pc/vga.c: Likewise. + * term/usb_keyboard.c: Likewise. + * term/gfxterm.c: Likewise. + * aclocal.m4: Likewise. + * util/lvm.c: Likewise. + * util/grub.d/30_os-prober.in: Likewise. + * util/grub.d/10_hurd.in: Likewise. + * util/console.c: Likewise. + * util/grub-macho2img.c: Likewise. + * util/grub-probe.c: Likewise. + * util/hostfs.c: Likewise. + * util/i386/pc/grub-mkimage.c: Likewise. + * util/i386/pc/grub-setup.c: Likewise. + * util/i386/efi/grub-mkimage.c: Likewise. + * util/grub-mkconfig.in: Likewise. + * util/raid.c: Likewise. + * util/resolve.c: Likewise. + * util/grub-mkdevicemap.c: Likewise. + * util/grub-emu.c: Likewise. + * util/getroot.c: Likewise. + * util/hostdisk.c: Likewise. + * util/usb.c: Likewise. + * util/grub-editenv.c: Likewise. + * util/misc.c: Likewise. + +2009-06-10 Felix Zielcke + + * gendistlist.sh (EXTRA_DISTFILES): Add `genhandlerlist.sh' and + `genparttoollist.sh'. + (DISTDIRS): Add `efiemu', `mmap', `parttool' and `script'. + Add `*.sh' to the list find searches for and change `mdate.sh' + to `mdate-sh'. + +2009-06-10 Pavel Roskin + + * include/grub/multiboot2.h: Provide compatibility defines for + multiboot2.h. + * include/multiboot2.h: Include stdint.h only if needed, using + angle brackets. + * loader/i386/pc/multiboot2.c: Include multiboot2.h after + grub/multiboot2.h. + * loader/ieee1275/multiboot2.c: Likewise. + * loader/multiboot2.c: Likewise. + * loader/multiboot_loader.c: Likewise. + + * configure.ac: Use -nostdlib when probing for the target. It + should not be required to have libc for the target. + + * configure.ac: Remove checks for __bswapsi2 and __bswapdi2, + they fail without libc headers for the target. + * include/grub/powerpc/libgcc.h: Use weak attribute for all + exports. + * include/grub/sparc64/libgcc.h: Likewise. Don't use + preprocessor conditionals. + + * conf/common.rmk: Compile tar.mod from tar.c, not cpio.c. The + build system doesn't need to be aware of the tar.c internals. + +2009-06-09 Michel Hermier + + * fs/i386/pc/pxe.c (grub_pxefs_read): Fix returned values. + +2009-06-09 Robert Millan + + * util/deviceiter.c (grub_util_iterate_devices): Increase number of + disk limit to 26 for IDE, Virtio, Xen and SCSI. + +2009-06-09 Felix Zielcke + + * util/i386/pc/grub-install.in: Change the error message if UUIDs + aren't available if ata.mod gets used. + +2009-06-09 Oliver Henshaw + + * bus/usb/ohci.c (grub_ohci_pci_iter): Link struct only after + initialising controller. + * bus/usb/uhci.c (grub_uhci_pci_iter): Likewise. + +2009-06-08 Felix Zielcke + + * util/i386/pc/grub-install.in: Add a parameter --disk-module + to choose between ata and biosdisk module on i386-pc. + +2009-06-08 Oliver Henshaw + + * bus/usb/ohci.c (grub_ohci_pci_iter): Define the Class, + Subclass and Programming Interface fields in terms of the 3 byte + Class Code register. + * bus/usb/uhci.c (grub_uhci_pci_iter): Likewise. + + * bus/usb/ohci.c (grub_ohci_pci_iter): Check that programming + interface is OHCI. Add grub_dprintf for symmetry with + bus/usb/uhci.c. + * bus/usb/uhci.c (grub_uhci_pci_iter): Check that programming + interface is UHCI. Add interf variable for programming + interface. Print interface with class/subclass. + + * bus/usb/ohci.c: Set interf with correct field. + + * bus/usb/uhci.c: Remove unneeded doubled lines. + * bus/usb/ohci.c: Likewise. Change interf to grub_uint32_t. + Remove whitespace inside comment. + +2009-06-08 Robert Millan + + * loader/i386/linux.c (grub_cmd_linux): When processing `vga=', use + as fallback an equivalent option without depth. + +2009-06-08 Vladimir Serbinenko + + Not fail if unable to retrieve C/H/S on LBA disks + + * disk/i386/pc/biosdisk.c (grub_biosdisk_open): behave gracefully + if unable to retrieve C/H/S on LBA disks + +2009-06-08 Pavel Roskin + + * fs/hfs.c (grub_hfs_find_dir): Use union to avoid a warning + about aliasing. + +2009-06-08 Felix Zielcke + + * Makefile.in (uninstall): Remove all $lib_DATA files. + +2009-06-08 Vladimir Serbinenko + + Bugfix: install on partitionless device + + * util/hostdisk.c (grub_util_biosdisk_get_grub_dev): check if os_dev + is a whole disk + +2009-06-08 Felix Zielcke + + * Makefile.in (uninstall): Remove all $include_DATA files. + +2009-06-08 Felix Zielcke + + * commands/true.c: New file. Implement the true and false commands. + * conf/common.rmk.c (pkglib_MODULES): Add `true.mod'. + (true_mod_SOURCES): New variable. + (true_mod_CFLAGS): Likewise. + (true_mod_LDFLAGS): Likewise. + +2009-06-05 Colin D Bennett + + Optimized font character lookup using binary search instead of linear + search. Fonts now are required to have the character index ordered by + code point. + + * font/font.c (load_font_index): Verify that fonts have ordered + character indices. + (find_glyph): Use binary search instead of linear search to find a + character in a font. + +2009-06-05 Michael Scherer + + * fs/hfsplus.c (grub_hfsplus_mount): Determine if the filesystem + uses case sensitive btree. + (grub_hfsplus_iterate_dir): Use GRUB_FSHELP_CASE_INSENSITIVE + only for case insensitive filesystems. + +2009-06-05 Vladimir Serbinenko + + * conf/i386-pc.rmk (efiemu_mod_CFLAGS): remove -Werror -Wall + * conf/common.rmk (search_mod_CFLAGS): likewise + +2009-06-04 Vladimir Serbinenko + + * kern/i386/pc/startup.S [APPLE_CC]: block of nops to + compensate a compiler bug + +2009-06-04 Vladimir Serbinenko + + * include/grub/term.h (GRUB_TERM_BACKSPACE): explicitly define as 8 + instead of '\b' + +2009-06-04 Vladimir Serbinenko + + Definitions for creating asm symbols with Apple's CC + + * include/grub/symbol.h [APPLE_CC] (FUNCTION): new macro + [APPLE_CC] (VARIABLE): likewise + +2009-06-04 Vladimir Serbinenko + + Disable lnxboot.img when compiled + with Apple's CC + + * conf/i386-pc.rmk (pkglib_IMAGES): remove lnxboot.img + pkglib_IMAGES [! TARGET_APPLE_CC] (pkglib_IMAGES): add lnxboot.img + * boot/i386/pc/lnxboot.S [APPLE_CC]: define an #error + [! APPLE_CC] (CODE_LENG): skip + [! APPLE_CC] (setup_sects): likewise + [! APPLE_CC]: skip filling + +2009-06-04 Vladimir Serbinenko + + Address in trampolines based on 32-bit registers when compiled + with Apple's CC + + * loader/i386/xnu_helper.S [APPLE_CC]: use 32-bit registers + for addresses + * loader/i386/linux_trampoline.S [APPLE_CC]: likewise + +2009-06-04 Vladimir Serbinenko + + Avoid aliases when compiling with Apple's CC for PCBIOS machine + + * kern/misc.c [APPLE_CC] (memcpy): new function + [APPLE_CC] (memmove): likewise + [APPLE_CC && !GRUB_UTIL] (grub_err_printf): likewise + (memcpy): define alias conditionally on !APPLE_CC + (memset): likewise + (abort): likewise + * include/grub/misc.h (memove): don't define when both GRUB_UTIL and + APPLE_CC are defined + * include/grub/list.h [APPLE_CC] (grub_assert_fail): new function + (grub_assert_fail): make prototype conditional + +2009-06-04 Vladimir Serbinenko + + Use grub-macho2img when compiling with Apple's CC for PCBIOS machine + + * conf/common.rmk (bin_UTILITIES): add (on false on condition) + grub-macho2img + (CLEANFILES): add grub-macho2img + (grub_macho2img_SOURCES): new variable + * kern/i386/pc/startup.S (bss_start): new variable + (bss_end): likewise + * genmk.rb: use grub-macho2img for *.img when compiled with Apple's CC + * util/grub-macho2img.c: new file + +2009-06-04 Vladimir Serbinenko + + Use objconv when compiling with Apple's CC + + * conf/i386-pc.rmk (efiemu32.o): use OBJCONV if defined + (efiemu64.o): likewise + (efiemu64_c.o): omit -mcmodel=large and add -DAPPLE_CC=1 + when compiling with Apple's CC + (efiemu64_s.o): likewise + * configure.ac: check for objconv when compiling with Apple's CC + * genmk.rb: use objconv for modules when compiled with Apple's CC + +2009-06-04 Vladimir Serbinenko + + Define segment as well as section when compiling with + Apple's CC + + * efiemu/runtime/efiemu.c (PHYSICAL_ATTRIBUTE): new definition + (efiemu_set_virtual_address_map): declare with PHYSICAL_ATTRIBUTE + (efiemu_convert_pointer): likewise + (efiemu_set_virtual_address_map): likewise + (efiemu_convert_pointer): likewise + (efiemu_getcrc32): likewise + (init_crc32_table): likewise + (reflect): likewise + * include/grub/dl.h (GRUB_MOD_NAME): define segment with Apple's CC + (GRUB_MOD_DEP): likewise + +2009-06-04 Vladimir Serbinenko + + Allow a compilation without -mcmodel=large + + * kern/efi/mm.c (grub_efi_allocate_pages): don't allocate >4GiB + when compiled without -mcmodel=large + (filter_memory_map): remove memory post 4 GiB when compiled + without -mcmodel=large + * configure.ac: fail gracefully and add -DMCMODEL_SMALL=1 to + TARGET_CFLAGS when -mcmodel=large isn't supported + +2009-06-04 Vladimir Serbinenko + + Remove nested functions in efiemu core + + * efiemu/runtime/efiemu.c (reflect): make static instead of nested + +2009-06-04 Vladimir Serbinenko + + Avoid clobbering %ebx/%rbx in inline assembly with Apple's CC + + * efiemu/runtime/efiemu.c (write_cmos): use %cl instead of %bl as + temporary storage + * include/grub/i386/tsc.h (grub_get_tsc): restore %rbx/%ebx when + using Apple's CC + (grub_cpu_is_tsc_supported): likewise + * loader/i386/xnu.c (guessfsb): restore %rbx/%ebx in inline assembly + +2009-06-04 Vladimir Serbinenko + + Absolute addressing through constant with Apple's cc + + * kern/i386/pc/startup.S: Define necessary constants + and address through it when using ABS with Apple's CC + * boot/i386/pc/diskboot.S: likewise + * boot/i386/pc/boot.S: likewise + * boot/i386/pc/lnxboot.S: likewise + * boot/i386/pc/cdboot.S: likewise + * mmap/i386/pc/mmap_helper.S: likewise + * commands/i386/pc/drivemap_int13h.S: likewise + +2009-06-04 Vladimir Serbinenko + + Check if compiler is apple cc + + * Makefile.in (ASFLAGS): new variable + (TARGET_ASFLAGS): likewise + (TARGET_MODULE_FORMAT): likewise + (TARGET_APPLE_CC): likewise + (OBJCONV): likewise + (TARGET_IMG_CFLAGS): likewise + (TARGET_CPPFLAGS): add includedir + * configure.ac: call grub_apple_cc and grub_apple_target_cc + (TARGET_IMG_LDFLAGS): Add -Wl,-Ttext,. All users updated + Check for linker script only if compiler isn't Apple's CC + (TARGET_MODULE_FORMAT): set + (TARGET_APPLE_CC): likewise + (TARGET_ASFLAGS): likewise + (ASFLAGS): likewise + Check for objcopy only if compiler isn't Apple's CC + Check for BSS symbol only if compiler isn't Apple's CC + * genmk.rb: adapt nm options if we use Apple's utils + * aclocal.m4 (grub_apple_cc): new test + (grub_apple_target_cc): likewise + +2009-06-04 Vladimir Serbinenko + + Simplify sed expressions and improve awk + + * Makefile.in (install-local): simplify sed expression + * gencmdlist.sh: likewise + * genmoddep.awk: avoid adding module as a dependency of itself + +2009-06-04 Vladimir Serbinenko + + Add missing start symbols + + * boot/i386/pc/boot.S: add start + * boot/i386/pc/pxeboot.S: likewise + +2009-06-04 Vladimir Serbinenko + + Fix wrong assumptions with grub-mkimage on EFI + + * i386/efi/grub-mkimage.c (read_kernel_module): don't write prefix here + (relocate_addresses): consider both r_addend and value at offset + (make_mods_section): zerofill modinfo and header + (convert_elf): write prefix here + +2009-06-04 Vladimir Serbinenko + + Use .asciz instead of .string + + * i386/pc/diskboot.S: use .asciz instead of .string + * i386/pc/boot.S: likewise + * include/grub/dl.h (GRUB_MOD_DEP): likewise + (GRUB_MOD_NAME): likewise + +2009-06-04 Vladimir Serbinenko + + gfxpayload support + + * commands/videotest.c (grub_cmd_videotest): use grub_video_set_mode + * include/grub/video.h (GRUB_VIDEO_MODE_TYPE_PURE_TEXT): new definition + (grub_video_setup): remove + (grub_video_set_mode): new prototype + * loader/i386/linux.c (DEFAULT_VIDEO_MODE): new definition + (vid_mode): remove + (linux_vesafb_res): compile only on PCBIOS + (grub_linux_boot): support gfxpayload + * loader/i386/pc/xnu.c (video_hook): new function + (grub_xnu_set_video): support gfxpayload + * term/gfxterm.c (DEFAULT_VIDEO_WIDTH): removed + (DEFAULT_VIDEO_HEIGHT): likewise + (DEFAULT_VIDEO_FLAGS): likewise + (DEFAULT_VIDEO_MODE): new definition + (video_hook): new function + (grub_gfxterm_init): use grub_video_set_mode + * util/grub.d/30_os-prober.in: remove explicit modesetting before + loading xnu + * video/video.c (grub_video_setup): removed + (grub_video_set_mode): new function based on grub_gfxterm_init and + grub_video_setup + +2009-06-04 Vladimir Serbinenko + + Avoid calling biosdisk in drivemap + + * commands/i386/pc/drivemap.c (parse_biosdisk): remove + (revparse_biosdisk): likewise + (list_mappings): derive name from id directly + (grub_cmd_drivemap): use tryparse_diskstring + +2009-06-04 Vladimir Serbinenko + + Script fixes + + * include/grub/script_sh.h (grub_script_cmdline): remove cmdline + (grub_lexer_param): add tokenonhold + (grub_script_create_cmdline): remove cmdline. All callers updated + (grub_script_function_create): make functionname + grub_script_arg. All callers updated + (grub_script_execute_argument_to_string): new prototype + * kern/parser.c (state_transitions): reorder + (grub_parser_cmdline_state): fix a bug and make more compact + * script/sh/execute.c (grub_script_execute_argument_to_string): + make global + (grub_script_execute_cmdline): use new format + * script/sh/function.c (grub_script_function_create): make functionname + grub_script_arg. All callers updated + * script/sh/lexer.c (grub_script_lexer_init): initialize tokenonhold + (grub_script_yylex): remove + (grub_script_yylex2): renamed to ... + (grub_script_yylex): ...renamed + parse the expressions like a${b}c + * script/sh/parser.y (GRUB_PARSER_TOKEN_ARG): new typed terminal + (GRUB_PARSER_TOKEN_VAR): remove + (GRUB_PARSER_TOKEN_NAME): likewise + ("if"): declare as typeless + ("while"): likewise + ("function"): likewise + ("else"): likewise + ("then"): likewise + ("fi"): likewise + (text): remove + (argument): likewise + (script): accept empty scripts and make exit on error + (arguments): use GRUB_PARSER_TOKEN_ARG + (function): likewise + (command): move error handling to script + (menuentry): move grub_script_lexer_ref before + * script/sh/script.c (grub_script_create_cmdline): remove cmdline + argument. All callers updated + +2009-06-04 Robert Millan + + Prevent GRUB from probing floppies during boot. + + * conf/common.rmk (search_mod_CFLAGS): Use `-Werror -Wall'. + * commands/search.c (options): Add --no-floppy. + (search_fs, search_file, grub_cmd_search): Support --no-floppy. + * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Use + --no-floppy when searching for UUIDs. + +2009-06-04 Robert Millan + + Simplify the code duplication in commands/search.c. + + * commands/search.c (search_label, search_fs_uuid): Merge into ... + (search_fs): ... this. Update all users. + +2009-06-03 Felix Zielcke + + * util/grub-mkconfig.in (update_grub_dir): Rename to grub_mkconfig_dir. + +2009-05-28 Pavel Roskin + + * Makefile.in: Don't use "cp -d", it doesn't work on FreeBSD. + Remove the original symlink explicitly. + + * fs/hfs.c (grub_hfs_find_dir): Skip sequences of slashes, not + just one slash. That's how grub_fshelp_find_file() does it. + +2009-05-26 Pavel Roskin + + * genmk.rb: Avoid shadowing variable `s', rename the outer `s' + to `str'. + + * util/getroot.c (grub_util_get_dev_abstraction): Mark os_dev as + possibly unused. + +2009-05-25 Christian Franke + + * disk/ata.c (grub_ata_wait_not_busy): Add debug output of status + register. + (grub_atapi_identify): Add wait after drive select. + (grub_ata_identify): Do more strict status register check before + calling grub_atapi_identify (). Suppress error message if status + register is 0x00 after command failure. Add status register + check after PIO read to avoid bogus identify due to stuck DRQ. + Thanks to Pavel Roskin for testing. + (grub_device_initialize): Remove unsafe status register check. + Thanks to 'phcoder' for problem report and patch. + Prevent sign extension in debug message. + +2009-05-23 Colin D Bennett + + Cleaned up `include/grub/normal.h'. Grouped prototypes by + definition file, and functions defined in `normal/menu.c' have had + their prototypes moved to `include/grub/menu.h' for consistency. + + * include/grub/menu.h (grub_menu_execute_callback): Added; moved + from normal.h. + (grub_menu_get_entry): Likewise. + (grub_menu_get_timeout): Likewise. + (grub_menu_set_timeout): Likewise. + (grub_menu_execute_entry): Likewise. + (grub_menu_execute_with_fallback): Likewise. + (grub_menu_entry_run): Likewise. + + * include/grub/normal.h: Re-ordered and grouped function + prototypes by file that the function is defined in. + (grub_menu_execute_callback): Removed; moved to menu.h. + (grub_menu_get_entry): Likewise. + (grub_menu_get_timeout): Likewise. + (grub_menu_set_timeout): Likewise. + (grub_menu_execute_entry): Likewise. + (grub_menu_execute_with_fallback): Likewise. + (grub_menu_entry_run): Likewise. + (grub_menu_addentry): Renamed from this ... + (grub_normal_add_menu_entry): ... to this. + + * normal/main.c (grub_menu_addentry): Renamed from this ... + (grub_normal_add_menu_entry): ... to this. + + * script/sh/execute.c (grub_script_execute_menuentry): Update + reference to renamed grub_menu_addentry function. + +2009-05-23 Felix Zielcke + + * commands/i386/pc/drivemap.c (MODNAME): Remove. Update all users. + +2009-05-22 Pavel Roskin + + * aclocal.m4 (grub_I386_CHECK_REGPARM_BUG): Remove. + * configure.ac: Don't call grub_I386_CHECK_REGPARM_BUG. Define + NESTED_FUNC_ATTR using AH_BOTTOM. Use regparm(1) only when + compiling for the i386 targets, but not for the utilities. + + * include/grub/i386/pc/kernel.h (grub_boot_drive): Change type + to grub_uint8_t. + (grub_root_drive): Likewise. + * kern/i386/pc/startup.S (grub_boot_drive): Change size to byte, + remove alignment. + (grub_root_drive): Change size to byte. + (grub_start_addr): Remove. + (grub_end_addr): Likewise. + (grub_apm_bios_info): Likewise. + +2009-05-21 Felix Zielcke + + * normal/i386: Remove. + * normal/powerpc: Likewise. + * normal/sparc64: Likewise. + * normal/x86_64: Likewise. + +2009-05-19 Vladimir Serbinenko + + * conf/x86_64-efi.rmk (linux_mod_ASFLAGS): Add missing variable + * loader/i386/linux_trampoline.S: Fix indentation + * loader/i386/xnu_helper.S: Likewise + +2009-05-18 Colin D Bennett + + Display error messages when parsing a Lua statement fails. + Previously, executing a syntactically invalid statement like + ")foo" or "bar;" would silently fail. + + * script/lua/grub_main.c (handle_lua_error): New function. + (grub_lua_parse_line): Improved reporting of Lua parser and + execution errors. + +2009-05-17 Vladimir Serbinenko + + Remove -Werror which causes build to fail on some systems + + * conf/i386-pc.rmk (xnu_mod_CFLAGS): Remove -Werror -Wall + * conf/i386-efi.rmk (xnu_mod_CFLAGS): Likewise + * conf/x86_64-efi.rmk (xnu_mod_CFLAGS): Likewise + +2009-05-17 Vladimir Serbinenko + + trampoline for linux on 64-bit platform + + * conf/x86_64-efi.rmk (linux_mod_SOURCES): added + loader/i386/efi/linux_trampoline.S + * include/grub/x86_64/efi/loader.h (grub_linux_real_boot): removed + declaration + * kern/x86_64/efi/startup.S (grub_linux_real_boot): moved from + here + * loader/i386/linux_trampoline.S: moved here + * loader/i386/efi/linux.c (allocate_pages): reserve space for + trampoline + (jumpvector): removed + (grub_linux_trampoline_start): new declaration + (grub_linux_trampoline_end): likewise + (grub_linux_boot): use trampoline when on 64-bit platform + * loader/i386/linux.c: likewise + +2009-05-16 Pavel Roskin + + * script/lua/grub_lib.c (grub_lua_getenv): Make name and value + const to avoid a warning. + (grub_lua_setenv): Likewise. + * script/lua/grub_main.c (grub_lua_parse_line): Use size_t for + lmsg to fix a warning. + +2009-05-16 Felix Zielcke + + * conf/i386.rmk (setjmp_mod_CFLAGS): Rename to ... + (setjmp_mod_ASFLAGS): ... this. Set to $(COMMON_ASFLAGS). + * conf/x86_64-efi.rmk (setjmp_mod_CFLAGS): Rename to ... + (setjmp_mod_ASFLAGS): ... this. Set to $(COMMON_ASFLAGS). + * conf/powerpc-ieee1275.rmk (setjmp_mod_CFLAGS): Rename to ... + (setjmp_mod_ASFLAGS): ... this. Set to $(COMMON_ASFLAGS). + * conf/sparc64-ieee1275.rmk (setjmp_mod_CFLAGS): Rename to ... + (setjmp_mod_ASFLAGS): ... this. Set to $(COMMON_ASFLAGS). + +2009-05-16 Felix Zielcke + + * util/grub-mkconfig.in: Export GRUB_TERMINAL_INPUT. + +2009-05-16 Bean + + * conf/common.rmk (pkglib_MODULES): Add lua.mod. + (lua_mod_SOURCES): New variable. + (lua_mod_CFLAGS): Likewise. + (lua_mod_LDFLAGS): Likewise. + + * conf/i386.rmk (pkglib_MODULES): Add setjmp.mod. + (setjmp_mod_SOURCES): New variable. + (setjmp_mod_CFLAGS): Likewise. + (setjmp_LDFLAGS): Likewise. + + * conf/x86_64-efi.rmk (pkglib_MODULES): Add setjmp.mod. + (setjmp_mod_SOURCES): New variable. + (setjmp_mod_CFLAGS): Likewise. + (setjmp_LDFLAGS): Likewise. + + * conf/powerpc-ieee1275.rmk (pkglib_MODULES): Add setjmp.mod. + (setjmp_mod_SOURCES): New variable. + (setjmp_mod_CFLAGS): Likewise. + (setjmp_LDFLAGS): Likewise. + + * conf/sparc64-ieee1275.rmk (pkglib_MODULES): Add setjmp.mod. + (setjmp_mod_SOURCES): New variable. + (setjmp_mod_CFLAGS): Likewise. + (setjmp_LDFLAGS): Likewise. + + * normal/i386/setjmp.S: Moved from here ... + * lib/i386/setjmp.S: ... Moved here + * normal/x86_64/setjmp.S: Moved from here ... + * lib/x86_64/setjmp.S: ... Moved here + * normal/powerpc/setjmp.S: Moved from here ... + * lib/powerpc/setjmp.S: ... Moved here + * normal/sparc64/setjmp.S: Moved from here ... + * lib/sparc64/setjmp.S: ... Moved here + + * include/grub/i386/setjmp.h (grub_setjmp): Don't use attribute + returns_twice in mingw. + + * script/lua/grub_lib.c: New file. + * script/lua/grub_lib.h: Likewise. + * script/lua/grub_lua.h: Likewise. + * script/lua/grub_main.c: Likewise. + * script/lua/lapi.c: Likewise. + * script/lua/lapi.h: Likewise. + * script/lua/lauxlib.c: Likewise. + * script/lua/lauxlib.h: Likewise. + * script/lua/lbaselib.c: Likewise. + * script/lua/lcode.c: Likewise. + * script/lua/lcode.h: Likewise. + * script/lua/ldblib.c: Likewise. + * script/lua/ldebug.c: Likewise. + * script/lua/ldebug.h: Likewise. + * script/lua/ldo.c: Likewise. + * script/lua/ldo.h: Likewise. + * script/lua/ldump.c: Likewise. + * script/lua/lfunc.c: Likewise. + * script/lua/lfunc.h: Likewise. + * script/lua/lgc.c: Likewise. + * script/lua/lgc.h: Likewise. + * script/lua/linit.c: Likewise. + * script/lua/liolib.c: Likewise. + * script/lua/llex.c: Likewise. + * script/lua/llex.h: Likewise. + * script/lua/llimits.h: Likewise. + * script/lua/lmathlib.c: Likewise. + * script/lua/lmem.c: Likewise. + * script/lua/lmem.h: Likewise. + * script/lua/loadlib.c: Likewise. + * script/lua/lobject.c: Likewise. + * script/lua/lobject.h: Likewise. + * script/lua/lopcodes.c: Likewise. + * script/lua/lopcodes.h: Likewise. + * script/lua/loslib.c: Likewise. + * script/lua/lparser.c: Likewise. + * script/lua/lparser.h: Likewise. + * script/lua/lstate.c: Likewise. + * script/lua/lstate.h: Likewise. + * script/lua/lstring.c: Likewise. + * script/lua/lstring.h: Likewise. + * script/lua/lstrlib.c: Likewise. + * script/lua/ltable.c: Likewise. + * script/lua/ltable.h: Likewise. + * script/lua/ltablib.c: Likewise. + * script/lua/ltm.c: Likewise. + * script/lua/ltm.h: Likewise. + * script/lua/lua.h: Likewise. + * script/lua/luaconf.h: Likewise. + * script/lua/lualib.h: Likewise. + * script/lua/lundump.c: Likewise. + * script/lua/lundump.h: Likewise. + * script/lua/lvm.c: Likewise. + * script/lua/lvm.h: Likewise. + * script/lua/lzio.c: Likewise. + * script/lua/lzio.h: Likewise. + +2009-05-16 Bean + + * include/grub/kernel.h (grub_module_header_types): Add type + OBJ_TYPE_CONFIG. + + * kern/main.c (grub_load_config): New function. + (grub_main): Call grub_load_config to read boot config. + + * grub-mkimage (generate_image): New parameter config_path. + (options): New option --config. + (main): Parse --config option, and pass it to generate_image. + +2009-05-14 Christian Franke + + * commands/i386/pc/drivemap_int13h.S: Add missing EXT_C for symbols. + This fixes build on Cygwin. + +2009-05-14 Pavel Roskin + + * commands/i386/pc/drivemap_int13h.S: Eliminate unconditional + jump. This saves two bytes, so the typical case of 2 swapped + drives would fit 32 bytes. + +2009-05-13 Pavel Roskin + + * loader/i386/multiboot.c (grub_multiboot): Cast mmap_addr to + grub_uint32_t to avoid a warning. + + * loader/i386/linux.c (allocate_pages): When assigning + real_mode_mem, cast through grub_size_t to fix a warning. The + code already makes sure that the value would fit a pointer. + (grub_linux_setup_video): Cast render_target->data to + grub_size_t to fix a warning. + +2009-05-13 Javier MartĂ­n + + * commands/i386/pc/drivemap.c: New file - implement drivemap + command. + * commands/i386/pc/drivemap_int13h.S: New file - int13 handler. + * conf/i386-pc.rmk: Add drivemap.c and drivemap_int13h.S. + +2009-05-13 Pavel Roskin + + * util/i386/pc/grub-setup.c (setup): Remove unused variable + embedding_area_exists. + +2009-05-13 Robert Millan + + * util/i386/pc/grub-setup.c (setup): Restructure code flow to make + it easier to understand / work with. + Improve warning messages for cases where there's no embedding area, + or when it is too small (or core.img too large). + +2009-05-13 Pavel Roskin + + * loader/i386/pc/multiboot2.c: Add necessary includes for + grub_multiboot2_real_boot(). + + * fs/iso9660.c (grub_iso9660_iterate_dir): The file mode in the + PX record is always little-endian. We only need the lower 2 + bytes of the mode. + + * fs/cpio.c: Use the same name "struct head" for tar and cpio to + facilitate code reuse. + (grub_cpio_mount): Use "struct head", not a char buffer. This + fixes a warning reported by gcc 4.4. + + * kernel/disk.c (grub_disk_read): Use void pointer for the + buffer. + (grub_disk_write): Use const void pointer for the buffer. + Adjust all callers. Remove unnecessary casts. + +2009-05-10 Robert Millan + + * util/i386/pc/grub-install.in: Update copyright year. + +2009-05-09 Vladimir Serbinenko + + gptsync + + * commands/gptsync.c: new file + * conf/common.rmk (pkglib_MODULES): add gptsync.mod + (gptsync_mod_SOURCES): new variable + (gptsync_mod_CFLAGS): likewise + (gptsync_mod_LDFLAGS): likewise + * include/grub/pc_partition.h (GRUB_PC_PARTITION_TYPE_NTFS): + new definition + (GRUB_PC_PARTITION_TYPE_HFS): likewise + * conf/i386-coreboot.rmk (grub_emu_SOURCES): add commands/gptsync.c + * conf/i386-ieee1275.rmk: likewise + * conf/i386-pc.rmk: likewise + * conf/powerpc-ieee1275.rmk: likewise + +2009-05-09 Vladimir Serbinenko + + Fixed grub-emu + + * kern/dl.c (grub_dl_ref): omit when compiling grub-emu + (grub_dl_ref): likewise + +2009-05-08 Robert Millan + + * util/i386/pc/grub-setup.c (setup): Factorize find_usable_region(), + split in two functions (one for msdos and one for gpt). + +2009-05-08 Pavel Roskin + + * disk/raid.c (grub_raid_block_xor): Make buf2 constant, it's + not modified. + + * disk/raid6_recover.c (grub_raid6_recover): Fix warnings about + uninitialized err[0] and err[1]. Rename them to bad1 and bad2. + Initialize them with -1. Add sanity check for bad1. Eliminate + nerr variable. + +2009-05-08 David S. Miller + + * util/sparc64/ieee1275/grub-ofpathname.c (main): Set progname. + +2009-05-06 Robert Millan + + * util/i386/pc/grub-setup.c (setup): Fix check for embed region + existence. + +2009-05-05 Felix Zielcke + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add + `kern/rescue_reader.c', `kern/rescue_parser.c' and `normal/autofs.c'. + +2009-05-05 David S. Miller + + * util/sparc64/ieee1275/grub-install.in: Fix sed arg quoting. + +2009-05-05 Pavel Roskin + + * include/grub/dl.h [GRUB_UTIL]: Provide inline implementations + of grub_dl_ref() and grub_dl_unref(). + * commands/parttool.c: Remove preprocessor conditionals around + grub_dl_ref() and grub_dl_unref(). + * fs/affs.c: Likewise. + * fs/afs.c: Likewise. + * fs/cpio.c: Likewise. + * fs/ext2.c: Likewise. + * fs/fat.c: Likewise. + * fs/hfs.c: Likewise. + * fs/hfsplus.c: Likewise. + * fs/iso9660.c: Likewise. + * fs/jfs.c: Likewise. + * fs/minix.c: Likewise. + * fs/ntfs.c: Likewise. + * fs/reiserfs.c: Likewise. + * fs/sfs.c: Likewise. + * fs/udf.c: Likewise. + * fs/ufs.c: Likewise. + * fs/xfs.c: Likewise. + * include/grub/dl.h: Likewise. + * loader/xnu.c: Likewise. + +2009-05-04 Pavel Roskin + + * commands/acpi.c: Remove unused variable my_mod. + * partmap/amiga.c: Likewise. + * partmap/apple.c: Likewise. + * partmap/gpt.c: Likewise. + * partmap/pc.c: Likewise. + * partmap/sun.c: Likewise. + * term/gfxterm.c: Likewise. + * term/i386/pc/vesafb.c: Likewise. + * term/i386/pc/vga.c: Likewise. + +2009-05-04 David S. Miller + + * kern/ieee1275/openfw.c (grub_children_iterate): Fix string + pointer args to grub_ieee1275_get_property(). + + * conf/sparc64-ieee1275.rmk: Fix build due to missing '\'. + + * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Bypass cdrom + devices, and do not traverse down under controller nodes. + + * disk/ieee1275/ofdisk.c (compute_dev_path): New. + (grub_ofdisk_open): Use it to un-escape "," characters. + * kern/disk.c (find_part_sep): New. + (grub_disk_open): Use it to find the first non-escaped ',' + character in the disk name. + * util/ieee1275/devicemap.c (escape_of_path): New. + (grub_util_emit_devicemap_entry): Use it. + * util/sparc64/ieee1275/grub-install.in: Update script to + strip partition specifiers properly by not triggering on + '\' escaped ',' characters. + +2009-05-04 Robert Millan + + * include/grub/i386/linux.h (GRUB_LINUX_VID_MODE_VESA_START): Set + to 0x300. + * loader/i386/linux.c (vga_modes, linux_vesafb_res): Add a few + resolutions. + (linux_vesafb_modes): Add a lot of additional modes to the list (based + on documentation from Wikipedia). + +2009-05-04 Pavel Roskin + + * disk/ata.c: Spelling fixes. + * disk/raid.c: Likewise. + * disk/usbms.c: Likewise. + * disk/dmraid_nvidia.c: Likewise. + * kern/ieee1275/openfw.c: Likewise. + * kern/ieee1275/init.c: Likewise. + * kern/ieee1275/cmain.c: Likewise. + * boot/i386/pc/cdboot.S: Likewise. + * video/readers/png.c: Likewise. + * video/i386/pc/vbe.c: Likewise. + * fs/udf.c: Likewise. + * fs/hfs.c: Likewise. + * fs/reiserfs.c: Likewise. + * efiemu/runtime/efiemu.c: Likewise. + * efiemu/main.c: Likewise. + * efiemu/mm.c: Likewise. + * include/grub/elf.h: Likewise. + * include/grub/xnu.h: Likewise. + * include/grub/usbdesc.h: Likewise. + * include/grub/usb.h: Likewise. + * include/grub/script_sh.h: Likewise. + * include/grub/lib/LzmaEnc.h: Likewise. + * include/grub/efiemu/efiemu.h: Likewise. + * include/grub/command.h: Likewise. + * normal/menu.c: Likewise. + * normal/main.c: Likewise. + * normal/datetime.c: Likewise. + * bus/usb/uhci.c: Likewise. + * mmap/i386/uppermem.c: Likewise. + * mmap/mmap.c: Likewise. + * commands/acpi.c: Likewise. + * commands/test.c: Likewise. + * partmap/apple.c: Likewise. + * font/font.c: Likewise. + * loader/sparc64/ieee1275/linux.c: Likewise. + * loader/macho.c: Likewise. + * loader/i386/bsd_trampoline.S: Likewise. + * loader/i386/bsd.c: Likewise. + * loader/xnu.c: Likewise. + * term/i386/pc/vesafb.c: Likewise. + * term/usb_keyboard.c: Likewise. + * util/resolve.c: Likewise. + * util/getroot.c: Likewise. + +2009-05-04 Felix Zielcke + + * conf/i386-pc.rmk (libpkg_DATA): Rename to pkglib_DATA. + +2009-05-04 Robert Millan + + * loader/i386/linux.c [GRUB_MACHINE_PCBIOS] (grub_cmd_linux): Fix + build error. + +2009-05-04 Robert Millan + + * loader/i386/linux.c (grub_cmd_linux): Make "vga=" compatibility + parameter only available on BIOS. + +2009-05-04 Vladimir Serbinenko + + Removed wrong semicolon in declaration + + * grub/misc.h (grub_dprintf): remove semicolon + +2009-05-04 Robert Millan + + * loader/i386/linux.c (GRUB_ASSUME_LINUX_HAS_FB_SUPPORT): New macro. + (grub_linux_boot): Don't check for `linux_vesafb_modes' bounds (this + is done by grub_cmd_linux() now). + [! GRUB_ASSUME_LINUX_HAS_FB_SUPPORT]: If "vga=" parameter wasn't set, + restore video to text mode. + (grub_cmd_linux): Default `vid_mode' initialization to 0, which + indicates lack of "vga=" parameter. "vga=0" is mapped to + `GRUB_LINUX_VID_MODE_NORMAL'. + +2009-05-04 Felix Zielcke + + * conf/i386-efi.rmk (grub_emu_SOURCES): Remove `normal/execute.c', + `normal/lexer.c', `kern/rescue.c', `normal/function.c', `normal/misc.c' + and `normal/script.c'. Add `kern/rescue_reader.c', + `kern/rescue_parser.c', `script/sh/main.c', `script/sh/execute.c', + `script/sh/function.c', `script/sh/lexer.c', `script/sh/script.c' and + `grub_script.tab.c'. + + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Likewise. + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * Makefile.in: Remove duplicated 2008 in Copyright line. + +2009-05-04 Robert Millan + + * util/misc.c (grub_util_warn): New function. Emits a warning + unconditionally. + * include/grub/util/misc.h (grub_util_warn): New declaration. + + * util/i386/pc/grub-install.in: Understand --force and pass it down + to grub-setup. + + * util/i386/pc/grub-setup.c (main): Understand --force and pass it + down to setup(). + (setup): Improve error messages and add warnings when requested to + install in odd layouts. Refuse to install using blocklists unless + --force was set. + +2009-05-04 martin f. krafft + + * disk/raid.c (grub_raid_scan_device): Improve debug message. + +2009-05-04 Vladimir Serbinenko + + Updated copyright year + + * fs/hfsplus.c: updated copyright year + +2009-05-04 Vladimir Serbinenko + + HFS+ UUID + + * fs/hfsplus.c (grub_hfsplus_volheader): added num_serial field + in the space previously used by unused3 + (grub_hfsplus_uuid): new function + (grub_hfsplus_fs): added uuid field + +2009-05-03 Pavel Roskin + + * disk/ata.c: Don't cast mod to void in GRUB_MOD_INIT to + suppress warnings. It's no longer needed. + * disk/host.c: Likewise. + * disk/ata_pthru.c: Likewise. + * disk/loopback.c: Likewise. + * hook/datehook.c: Likewise. + * parttool/pcpart.c: Likewise. + * fs/i386/pc/pxe.c: Likewise. + * fs/ntfscomp.c: Likewise. + * efiemu/main.c: Likewise. + * mmap/mmap.c: Likewise. + * commands/crc.c: Likewise. + * commands/hexdump.c: Likewise. + * commands/hdparm.c: Likewise. + * commands/acpi.c: Likewise. + * commands/echo.c: Likewise. + * commands/minicmd.c: Likewise. + * commands/blocklist.c: Likewise. + * commands/memrw.c: Likewise. + * commands/loadenv.c: Likewise. + * commands/usbtest.c: Likewise. + * commands/lsmmap.c: Likewise. + * commands/boot.c: Likewise. + * commands/parttool.c: Likewise. + * commands/configfile.c: Likewise. + * commands/search.c: Likewise. + * commands/ieee1275/suspend.c: Likewise. + * commands/cat.c: Likewise. + * commands/i386/pc/pxecmd.c: Likewise. + * commands/i386/pc/play.c: Likewise. + * commands/i386/pc/halt.c: Likewise. + * commands/i386/pc/vbeinfo.c: Likewise. + * commands/i386/pc/vbetest.c: Likewise. + * commands/lspci.c: Likewise. + * commands/date.c: Likewise. + * commands/handler.c: Likewise. + * commands/ls.c: Likewise. + * commands/test.c: Likewise. + * commands/cmp.c: Likewise. + * commands/efi/loadbios.c: Likewise. + * commands/efi/fixvideo.c: Likewise. + * commands/halt.c: Likewise. + * commands/help.c: Likewise. + * commands/reboot.c: Likewise. + * hello/hello.c: Likewise. + * script/sh/main.c: Likewise. + * loader/xnu.c: Likewise. + * term/terminfo.c: Likewise. + * term/i386/pc/serial.c: Likewise. + * term/usb_keyboard.c: Likewise. + +2009-05-03 David S. Miller + + * normal/menu.c: Include grub/parser.h + +2009-05-03 Pavel Roskin + + * mmap/efi/mmap.c (grub_mmap_malign_and_register): Return void*, + not char*. + * mmap/i386/mmap.c (grub_mmap_malign_and_register): Likewise. + Suggested by Javier MartĂ­n + + * util/i386/pc/grub-mkrescue.in: Allow for the case when + efiemu??.o doesn't exist. + * util/i386/pc/grub-install.in: Likewise. Use "cp -f" for + copying. + +2009-05-03 Bean Vladimir Serbinenko + + FreeBSD 64-bit support + + * conf/i386-pc.rmk (bsd_mod_SOURCES): add loader/i386/bsd_helper.S + and loader/i386/bsd_trampoline.S + (bsd_mod_ASFLAGS): new variable + * include/grub/i386/bsd.h (FREEBSD_MODINFOMD_SMAP): new definition + (FREEBSD_MODTYPE_KERNEL64): likewise + (grub_bsd64_trampoline_start): likewise + (grub_bsd64_trampoline_end): likewise + (grub_bsd64_trampoline_selfjump): likewise + (grub_bsd64_trampoline_gdt): likewise + * include/grub/i386/loader.h (grub_unix_real_boot): moved from here ... + * include/grub/i386/bsd.h (grub_unix_real_boot): ... moved here + * kern/i386/loader.S (grub_unix_real_boot): moved from here ... + * loader/i386/bsd_helper.S (grub_unix_real_boot): moved here + * include/grub/gpt_partition.h (grub_gpt_partentry): Corrected the type + of "attrib" member + * loader/i386/bsd_pagetable.c: new file + * loader/i386/bsd_trampoline.S: likewise + * loader/i386/bsd.c (ALIGN_QWORD): new macro + (ALIGN_VAR): likewise + (entry_hi): new variable + (kern_end_mdofs): likewise + (is_64bit): likewise + (grub_freebsd_add_meta): use ALIGN_VAR + (grub_e820_mmap): new declaration + (grub_freebsd_add_mmap): new function + (grub_freebsd_add_meta_module): support 64 bit kernels + (grub_freebsd_list_modules): use ALIGN_VAR + (gdt_descriptor): new declaration + (grub_freebsd_boot): support 64 bit kernels + (grub_bsd_elf64_hook): new function + (grub_bsd_load_elf): support elf64 + +2009-05-03 Bean + + * script/sh/execute.c (grub_script_execute_cmdif): Reset grub_errno + after we get the result of if statement. + +2009-05-03 Bean + + * Makefile.in (enable_efiemu): New variable. + + * conf/i386-pc.rmk: Only compile efiemu runtimes when enable_efiemu is + set. + (efiemu32.o): Use macro $< for source file, add $(srcdir) to include + path. + (efi64_c.o): Use macro $< for source file, add $(srcdir) to include + path, add -mno-red-zone option. + (efiemu64_s.o): Likewise. + (efiemu64.o): Use macro $^ for source file. + + * configure.ac (--enable-efiemu): New option. + +2009-05-03 Vladimir Serbinenko + + xnu support + + * conf/i386-efi.rmk (kernel_mod_HEADERS): added i386/pit.h + (pkglib_MODULES): add xnu.mod + (xnu_mod_SOURCES): new variable + (xnu_mod_CFLAGS): likewise + (xnu_mod_LDFLAGS): likewise + (xnu_mod_ASFLAGS): likewise + * conf/i386-pc.rmk: likewise + * conf/x86_64-efi.rmk: likewise + * include/grub/efi/efi.h (grub_efi_finish_boot_services): + new declaration + * include/grub/i386/macho.h: new file + * include/grub/i386/xnu.h: likewise + * include/grub/macho.h: likewise + * include/grub/machoload.h: likewise + * include/grub/x86_64/macho.h: likewise + * include/grub/x86_64/xnu.h: likewise + * include/grub/xnu.h: likewise + * kern/efi/efi.c (grub_efi_finish_boot_services): new function + * kern/efi/mm.c (MAX_HEAP_SIZE): increase + * loader/i386/efi/xnu.c: new file + * loader/i386/pc/xnu.c: likewise + * loader/i386/xnu.c: likewise + * loader/i386/xnu_helper.S: likewise + * loader/macho.c: likewise + * loader/xnu.c: likewise + * loader/xnu_resume.c: likewise + * util/grub-dumpdevtree: likewise + * include/grub/i386/pit.h: include grub/err.h + (grub_pit_wait): export + * util/grub.d/30_os-prober.in: support Darwin/Mac OS X + +2009-05-02 Vladimir Serbinenko + + Efiemu + + * conf/i386-pc.rmk: new modules efiemu, efiemu_acpi, efiemu_pnvram, + _linux_efi, linux_efi. + new files in grub-emu + new targets efiemu32.o and efiemu64.o + * loader/linux_normal_efiemu.c: likewise + * loader/i386/efi/linux.c: added preliminary efiemu support + * util/i386/pc/grub-install.in: add efiemu??.o to the list of + files to copy + * include/grub/autoefi.h: new file + * include/grub/i386/efiemu.h: likewise + * include/grub/i386/pc/efiemu.h: likewise + * include/grub/efi/api.h: add LL suffix when necessary + new definitions relating to tables + * include/grub/efiemu/efiemu.h: new file + * include/grub/efiemu/runtime.h: likewise + * efiemu/prepare.c: likewise + * efiemu/loadcore_common.c: likewise + * efiemu/loadcore64.c: likewise + * efiemu/runtime/efiemu.sh: likewise + * efiemu/runtime/efiemu.S: likewise + * efiemu/runtime/efiemu.c: likewise + * efiemu/runtime/config.h: likewise + * efiemu/prepare32.c: likewise + * efiemu/main.c: likewise + * efiemu/modules/pnvram.c: likewise + * efiemu/modules/i386: likewise + * efiemu/modules/i386/pc: likewise + * efiemu/modules/acpi.c: likewise + * efiemu/i386/pc/cfgtables.c: likewise + * efiemu/i386/loadcore64.c: likewise + * efiemu/i386/loadcore32.c: likewise + * efiemu/prepare64.c: likewise + * efiemu/loadcore.c: likewise + * efiemu/symbols.c: likewise + * efiemu/mm.c: likewise + * efiemu/loadcore32.c: likewise + +2009-05-02 Vladimir Serbinenko + + ACPI spoofing + + * commands/acpi.c: new file + * commands/i386/pc/acpi.c: likewise + * commands/efi/acpi.c: likewise + * include/grub/acpi.h: likewise + * conf/i386-pc.rmk (pkglib_MODULES): added acpi.mod + (acpi_mod_SOURCES): new variable + (acpi_mod_CFLAGS): likewise + (acpi_mod_LDFLAGS): likewise + * conf/i386-efi.rmk: likewise + * conf/x86_64-efi.rmk: likewise + +2009-05-02 Vladimir Serbinenko + + Missing part from mmap patch + + * mmap/efi/mmap.c (grub_machine_mmap_unregister): renamed to + (grub_mmap_unregister) + (grub_mmap_free_and_unregister): use grub_mmap_register + +2009-05-02 Vladimir Serbinenko + + Mmap services + + * loader/i386/efi/linux.c (grub_linux_boot): use grub_mmap_iterate + * loader/i386/linux.c (find_mmap_size): likewise + (allocate_pages): likewise + * loader/i386/multiboot.c (grub_get_multiboot_mmap_len): likewise + (grub_fill_multiboot_mmap): likewise + (grub_multiboot): use grub_mmap_get_lower and grub_mmap_get_upper + * loader/i386/pc/linux.c (grub_cmd_linux): use grub_mmap_get_lower + * include/grub/i386/bsd.h (OPENBSD_MMAP_AVAILABLE): new definition + (OPENBSD_MMAP_RESERVED): likewise + * include/grub/i386/pc/memory.h: include grub/memory.h + (grub_lower_mem): removed + (grub_upper_mem): likewise + (GRUB_MACHINE_MEMORY_ACPI): new definition + (GRUB_MACHINE_MEMORY_NVS): likewise + (GRUB_MACHINE_MEMORY_MAX_TYPE): likewise + (GRUB_MACHINE_MEMORY_HOLE): likewise + (grub_machine_mmap_register): likewise + (grub_machine_mmap_unregister): likewise + (grub_machine_get_upper): likewise + (grub_machine_get_lower): likewise + (grub_machine_get_post64): likewise + * include/grub/i386/efi/memory.h: new file + * include/grub/x86_64/efi/memory.h: likewise + * include/grub/efi/memory.h: likewise + * conf/i386-pc.rmk (pkglib_MODULES): added mmap.mod + (mmap_mod_SOURCES): new variable + (mmap_mod_LDFLAGS): likewise + (mmap_mod_ASFLAGS): likewise + * conf/i386-coreboot.rmk: likewise + * conf/i386-ieee1275.rmk: likewise + * conf/i386-efi.rmk: likewise + * conf/x86_64-efi.rmk: likewise + * include/grub/types.h (UINT_TO_PTR): new macro + (PTR_TO_UINT32): likewise + (PTR_TO_UINT64): likewise + * include/grub/memory.h: new file + * mmap/i386/pc/mmap.c: likewise + * mmap/i386/pc/mmap_helper.S: likewise + * mmap/i386/uppermem.c: likewise + * mmap/mmap.c: likewise + * mmap/efi/mmap.c: likewise + * kern/i386/coreboot/init.c (grub_machine_init): don't use + grub_upper_mem + * kern/i386/pc/init.c (grub_lower_mem): removed variable + (grub_upper_mem): likewise + (grub_machine_init): don't use grub_upper_mem, + make grub_lower_mem local + * loader/i386/bsd.c (grub_openbsd_boot): use grub_mmap_get_lower, + grub_mmap_iterate and grub_mmap_get_upper + (grub_netbsd_boot): use grub_mmap_get_lower and grub_mmap_get_upper + +2009-05-02 Bean + + * conf/common.rmk (grub_script.tab.c): Change normal/parser.y to + script/sh/parser.y. + (pkglib_MODULES): Add normal.mod and sh.mod. + (normal_SOURCES): New variable. + (normal_mod_CFLAGS): Likewise. + (normal_mod_LDFLAGS): Likewise. + (sh_mod_SOURCES): Likewise. + (sh_mod_CFLAGS): Likewise. + (sh_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (normal/lexer.c_DEPENDENCIES): Changed to + script/sh/lexer.c_DEPENDENCIES. + (kernel_img_SOURCES): Remove kern/rescue.c, and kern/reader.c, + kern/rescue_reader.c and kern/rescue_parser.c. + (kernel_img_HEADERS): Remove rescue.h, add reader.h. + (grub_emu_SOURCES): Change source files. + (pkglib_MODULES): Remove normal.mod. + (normal_SOURCES): Removed. + (normal_mod_CFLAGS): Likewise. + (normal_mod_LDFLAGS): Likewise. + * conf/i386-coreboot.rmk: Likewise. + * conf/i386-efi.rmk: Likewise. + * conf/i386-ieee1276.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + + * include/grub/command.h (grub_command_execute): New inline function. + + * include/grub/menu.h (grub_menu_entry): Removed commands field. + + * include/grub/normal.h: Remove . + (grub_fs_module_list): Moved to normal/autofs.c. + (grub_exit_env): Removed. + (grub_command_execute): Likewise. + (grub_normal_menu_addentry): Renamed to grub_menu_addentry, removed + parameter script. + (read_command_list): New function declaration. + (read_fs_list): Likewise. + + * include/parser.h: Include . + (grub_parser_split_cmdline): Change type of getline parameter. + (grub_parser): New structure. + (grub_parser_class): New variable. + (grub_parser_execute): New function declaration. + (grub_register_rescue_parser): Likewise. + (grub_parser_register): New inline function. + (grub_parser_unregister): Likewise. + (grub_parser_get_current): Likewise. + (grub_parser_set_current): Likewise. + + * include/grub/reader.h: New file. + * kern/reader.c: Likewise. + * kern/rescue_parser.c: Likewise. + * kern/rescue_reader.c: Likewise. + * normal/autofs.c: Likewise. + * normal/dyncmd.c: Likewise. + + * include/grub/rescue.h: Removed. + * normal/command.h: Likewise. + + * include/grub/script.h: Moved to ... + * include/grub/script_sh.h: ... Moved here. + * normal/execute.c: Moved to ... + * script/sh/execute.c: ... Moved here. + * normal/function.c: Moved to ... + * script/sh/function.c: ... Moved here. + * normal/lexer.c: Moved to ... + * script/sh/lexer.c: ... Moved here. + * normal/parser.y: Moved to ... + * script/sh/parser.y: ... Moved here. + * normal/script.c: Moved to ... + * script/sh/script.c: ... Moved here. + + * normal/main.c: Remove and , include + . + (grub_exit_env): Removed. + (fs_module_list): Moved to normal/autofs.c. + (grub_file_getline): Don't handle comment here. + (free_menu): Skip removed field entry->commands. + (grub_normal_menu_addentry): Removed as grub_menu_entry, removed + script parameter. + (read_config_file): Removed nested parameter, change getline function. + (grub_enter_normal_mode): Removed. + (grub_dyncmd_dispatcher): Moved to normal/dyncmd.c. + (read_command_list): Likewise. + (autoload_fs_module): Moved to normal/autofs.c. + (read_fs_list): Likewise. + (reader_nested): New variable. + (grub_normal_execute): Run parser.sh to switch to sh parser. + (grub_cmd_rescue): Removed. + (cmd_normal): Removed. + (grub_cmd_normal): Unregister itself at the beginning. Don't register + rescue command. + (grub_cmdline_run): New function. + (grub_normal_reader_init): Likewise. + (grub_normal_read_line): Likewise. + (grub_env_write_pager): Likewise. + (cmdline): New variable. + (grub_normal_reader): Likewise. + (GRUB_MOD_INIT): Register normal reader and set as current, register + pager hook, register normal command with grub_register_command_prio, + so that it won't show up in command.lst. + (GRUB_MOD_FINI): Unregister normal reader, unhook pager, clear + grub_fs_autoload_hook. + + * normal/menu.c: Remove , add . + (grub_menu_execute_entry): Replace grub_script_execute with + grub_parser_execute, change parameter to grub_command_execute. + + * normal/menu_text.c: Remove . + + * normal/menu_entry.c: Remove , add + and . + (run): Change editor_getline to use new parser interface. Change + parameter to grub_command_execute. + + * kern/main.c: Remove , include , + and . + (grub_load_normal_mode): Execute normal command. + (grub_main): Call grub_register_core_commands, + grub_register_rescue_parser and grub_register_rescue_reader, use + grub_reader_loop to enter input loop. + + * kern/parser.c (grub_parser_split_cmdline): Change type of + getline parameter. + (grub_parser_class): New variable. + (grub_parser_execute): New function. + + * loader/i386/multiboot.c: Remove . + * loader/multiboot2.c: Likewise. + * loader/sparc64/ieee1275/linux.c: Likewise. + + * util/grub-emu.c (read_command_list): New dummy function. + +2009-05-02 Robert Millan + + * util/deviceiter.c (grub_util_iterate_devices): Increase max drive + count to 16 for CCISS and IDA. + +2009-05-02 Robert Millan + + * normal/menu_text.c (grub_wait_after_message): Print a newline + after waiting for user input. + + * loader/i386/linux.c: Include `'. + (grub_cmd_linux): Improve the error message about `ask' mode, by + waiting for user input so it's not missed (we can do this, since + user requested interaction). + +2009-05-02 Vladimir Serbinenko + + Added missing lst to grub-mkrescue + + * util/i386/pc/grub-mkrescue.in: added ${input_dir}/handler.lst + and ${input_dir}/parttool.lst + +2009-04-30 David S. Miller + + * util/hostdisk.c (device_is_wholedisk): New function. + (grub_util_biosdisk_get_grub_dev): Shortcut when hdg.start is + zero only if device_is_wholedisk() returns true. + + * util/hostdisk.c (convert_system_partition_to_system_disk): + Handle virtual disk devices named /dev/vdiskX as found on sparc + and powerpc. + + * kern/sparc64/ieee1275/init.c (grub_machine_set_prefix): If + lettered partition specifier is found, convert to numbered. + +2009-04-29 David S. Miller + + * include/grub/powerpc/ieee1275/memory.h: Include ieee1275.h. + * include/grub/sparc64/ieee1275/memory.h: Likewise. + + * normal/command.c: Add missing newline at end of file. + + * commands/lsmmap.c (grub_cmd_lsmmap): Add casts to avoid printf + warnings. + * kern/ieee1275/openfw.c (grub_claimmap): Likewise. + * disk/ieee1275/ofdisk.c (grub_ofdisk_open, grub_ofdisk_close, + grub_ofdisk_read): Likewise, and deal similarly with the fact that + ihandles have a 32-bit type but need to be stored in a "void *". + +2009-04-28 Pavel Roskin + + * disk/fs_uuid.c (grub_fs_uuid_open): Use parent->data for dev, + not disk. Adjust all dependencies. + (grub_fs_uuid_close): Use grub_device_close(), not + grub_disk_close(). + + * disk/fs_uuid.c (grub_fs_uuid_open): Allocate memory to copy + parent's partition, don't copy it by reference, as it gets freed + on close. + +2009-04-27 Vladimir Serbinenko + + Preboot hooks support + + * commands/boot.c (struct grub_preboot_t): new declaration + (preboots_head): new variable + (preboots_tail): likewise + (grub_loader_register_preboot_hook): new function + (grub_loader_unregister_preboot_hook): likewise + (grub_loader_set): launch preboot hooks + * include/grub/loader.h (grub_loader_preboot_hook_prio_t): new type + (grub_loader_register_preboot_hook): new declaration + (grub_loader_unregister_preboot_hook): likewise + +2009-04-27 Vladimir Serbinenko + + Warning fix + + * disk/scsi.c (grub_scsi_open): added missing cast when + calling grub_dprintf + +2009-04-26 Vladimir Serbinenko + + Bug and warning fixes + + * include/grub/i386/pc/init.h (grub_stop_floppy): added missing + declaration + * commands/test.c (test_parse): fixed bug with file tests and corrected + declaration of find_file + +2009-04-26 Pavel Roskin + + * Makefile.in: Don't install empty manual pages if help2man is + missing. Use help2man option for output, not shell redirection. + +2009-04-26 David S. Miller + + * util/grub-mkdevicemap.c (make_device_map): Add missing + NESTED_FUNC_ATTR to process_device(). + +2009-04-25 Vladimir Serbinenko + + Test command + + * commands/test.c: rewritten to use bash-like test + +2009-04-25 Vladimir Serbinenko + + Parttool autoloading and improvements + + * Makefile.in (pkglib_DATA): add parttool.lst + (parttool.lst): new target + * genmk.rb: generate parttool-* + (CLEANFILES): add #{parttool} + (PARTTOOLFILES): new variable + * genparttoollist.sh: new file + * parttool/pcpart.c (grub_pcpart_boot): more feedback + (grub_pcpart_type): likewise + * commands/parttool.c (helpmsg): new variable + (grub_cmd_parttool): output help if not enough arguments are supplied + autoload modules + (GRUB_MOD_INIT(parttool)): use helpmsg + +2009-04-24 David S. Miller + + Avoiding opening same device multiple times in device iterator. + + * kern/device.c: (grub_device_iterate): Define struct part_ent, + and use it to build a list of partitions in iterate_disk() and + iterate_partition(). + + * disk/fs_uuid.c (grub_fs_uuid_close): Call grub_disk_close() + on disk->data. + + * disk/ieee1275/nand.c (grub_nand_iterate): Return + grub_devalias_iterate() result instead of unconditional 0. + * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Likewise. + Also, capture hook return value, either directly or via + grub_children_iterate(), and propagate to caller. + * include/grub/ieee1275/ieee1275.h (grub_devalias_iterate, + grub_children_iterate): Return value is now 'int' instead of + 'grub_err_t'. + * kern/ieee1275/openfw.c (grub_children_iterate): Fix to behave + like a proper iterator, stopping when hooks return non-zero. + (grub_devalias_iterate): Likewise. + +2009-04-23 David S. Miller + + * kern/sparc64/ieee1275/openfw.c: Unused, delete. + +2009-04-22 David S. Miller + + * kern/ieee1275/mmap.c (grub_machine_mmap_iterate): If size_cells + is larger than address_cells, use that value for address_cells too. + + * include/grub/ieee1275/ieee1275.h (IEEE1275_MAX_PROP_LEN, + IEEE1275_MAX_PATH_LEN): Define. + * kern/ieee1275/openfw.c (grub_children_iterate): Dynamically + allocate 'childtype', 'childpath', 'childname', and 'fullname'. + (grub_devalias_iterate): Dynamically allocate 'aliasname' and + 'devtype'. Explicitly NULL terminate devalias expansion. + + * util/sparc64/ieee1275/misc.c: New file. + * util/sparc64/ieee1275/grub-setup.c: New file. + * util/sparc64/ieee1275/grub-ofpathname.c: New file. + * util/sparc64/ieee1275/grub-mkimage.c: New file. + * util/sparc64/ieee1275/grub-install.in: New file. + * util/ieee1275/ofpath.c: New file. + * util/ieee1275/devicemap.c: New file. + * util/devicemap.c: New file. + * util/deviceiter.c: New file. + * kern/sparc64/ieee1275/init.c: New file. + * include/grub/util/ofpath.h: New file. + * include/grub/util/deviceiter.h: New file. + * util/grub-mkdevicemap.c: Include deviceiter.h. + Implement using grub_util_emit_devicemap_entry and + grub_util_iterate_devices. + * conf/i386-corebook.rmk: Build util/deviceiter.c and + util/devicemap.c into grub-mkdevicemap + * conf/i386-efi.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Add rules to build boot block + images and installation utilities. Build kernel as image + instead of as elf binary. Use common rules as much as possible. + +2009-04-19 Vladimir Serbinenko + + Correct GPT definition + + * include/grub/gpt_partition.h (grub_gpt_partentry): Corrected the type + of "attrib" member + +2009-04-19 Felix Zielcke + + * INSTALL: Replace `autogen.sh' with `./autogen.sh'. + +2009-04-19 David S. Miller + + * loader/sparc64/ieee1275/linux.c: Include grub/command.h + (grub_rescue_cmd_linux): Rename to... + (grub_cmd_linux): and fix prototype. + (grub_rescue_cmd_initrd): Rename to... + (grub_cmd_initrd): and fix prototype. + (cmd_linux, cmd_initrd): New. + (GRUB_MOD_INIT(linux)): Use grub_register_command(). + (GRUB_MOD_FINI(linux): Use grub_unregister_command(). + +2009-04-17 Pavel Roskin + + * bus/usb/ohci.c (grub_ohci_transaction): Fix incorrect printf + format. + (grub_ohci_transfer): Likewise. + + * bus/usb/usbtrans.c (grub_usb_control_msg): Warning fix. + + * loader/multiboot_loader.c (grub_cmd_multiboot_loader): Fix + return without a value. Fix inconsistent indentation. + + * fs/i386/pc/pxe.c (grub_pxefs_dir): Fix function prototype to + match struct grub_fs. + + * disk/ata.c (grub_ata_pciinit): Use NESTED_FUNC_ATTR. + * bus/usb/ohci.c (grub_ohci_pci_iter): Likewise. + * bus/usb/uhci.c (grub_uhci_pci_iter): Likewise. + * commands/lspci.c (grub_lspci_iter): Likewise. + +2009-04-16 Bean + + * commands/efi/loadbios.c (grub_cmd_fakebios): Add missing return + value. + +2009-04-15 Pavel Roskin + + * include/grub/types.h: Rename ULONG_MAX to GRUB_ULONG_MAX and + LONG_MAX to GRUB_LONG_MAX. Introduce GRUB_LONG_MIN. Update all + users of ULONG_MAX, LONG_MAX and LONG_MIN to use the new + definitions. + +2009-04-15 Felix Zielcke + + * disk/lvm.c (grub_lvm_scan_device): Add `LVM' to the error messages, + that no multiple data or metadata areas are supported and `Unknown + metadata header'. + +2009-04-15 Vladimir Serbinenko + + Move loader out of the kernel + + * kern/loader.c: moved to ... + * commands/boot.c: ... moved here + * commands/minicmd.c (grub_mini_cmd_boot): moved to ... + * commands/boot.c (grub_cmd_boot): moved here. All users updated + * include/grub/kernel.h (grub_machine_fini): export + * include/grub/loader.h (grub_loader_is_loaded): update declaration + (grub_loader_set): likewise + (grub_loader_unset): likewise + (grub_loader_boot): likewise + * conf/common.rmk: new module boot.mod + (pkglib_MODULES): add boot.mod + * conf/i386-coreboot.rmk (kernel_elf_SOURCES): remove kern/loader.c + (grub_emu_SOURCES): likewise + * conf/i386-efi.rmk (kernel_elf_SOURCES): likewise + (grub_emu_SOURCES): likewise + * conf/i386-ieee1275.rmk (kernel_elf_SOURCES): likewise + (grub_emu_SOURCES): likewise + * conf/i386-pc.rmk (kernel_elf_SOURCES): likewise + (grub_emu_SOURCES): likewise + * conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): likewise + (grub_emu_SOURCES): likewise + * conf/sparc64-ieee1275.rmk (kernel_elf_SOURCES): likewise + (grub_emu_SOURCES): likewise + * conf/x86_64-efi.rmk (kernel_elf_SOURCES): likewise + (grub_emu_SOURCES): likewise + +2009-04-15 Vladimir Serbinenko + + use grub_lltoa instead of grub_itoa and grub_ltoa for all purposes + + * kern/misc.c (grub_itoa): Removed function + (grub_ltoa): likewise + (grub_vsprintf): use grub_lltoa + +2009-04-15 Vladimir Serbinenko + + Restore grub-emu + + * conf/i386-pc.rmk (grub_emu_SOURCES): add normal/handler.c + * conf/i386-coreboot.rmk: likewise + * conf/i386-ieee1275.rmk: likewise + * conf/powerpc-ieee1275.rmk: likewise + +2009-04-15 Felix Zielcke + + * INSTALL: Add that `./autogen.sh' needs to be run before + `./configure.'. + +2009-04-14 Bean + + * Makefile.in (pkglib_DATA): Add handler.lst. + (handler.lst): New rule. + + * conf/i386-pc.rmk (normal_mod_SOURCES): Add normal/handler.c. + * conf/i386-coreboot.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-efi.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + + * genhandlerlist.sh: New file. + + * genmk.rb: Add rules to generate handler.lst. + + * include/grub/normal.h (grub_file_getline): New function definition. + (read_handler_list): Likewise. + (free_handler_list): Likewise. + + * include/grub/term.h (grub_term_register_input): Add name parameter + for auto generation of handler.lst. + (grub_term_register_output): Likewise. + + * normal/handler.c: New file. + + * normal/main.c (get_line): Renamed to grub_file_getline. + (read_config_file): Use the newly renamed grub_file_getline. + (read_command_list): Likewise. + (read_fs_list): Likewise. + (grub_normal_execute): Call read_handler_list to parse handler.lst. + (GRUB_MOD_FINI): Call free_handler_list to free handler list. + + * term/efi/console.c (grub_console_init): Add name parameter for auto + generation of handler.lst. + * term/gfxterm.c: Likewise. + * term/i386/pc/at_keyboard.c: Likewise. + * term/i386/pc/console.c: Likewise. + * term/i386/pc/serial.c: Likewise. + * term/i386/pc/vesafb.c: Likewise. + * term/i386/pc/vga.c: Likewise. + * term/i386/pc/vga_text.c: Likewise. + * term/ieee1275/ofconsole.c: Likewise. + * term/usb_keyboard.c: Likewise. + +2009-04-14 Bean + + * util/grub-pe2elf.c (write_symbol_table): Terminate short name symbol + properly with null character. + +2009-04-14 Felix Zielcke + + * configure: Remove. + * config.h.in: Likewise. + * stamp-h.in: Likewise. + * DISTLIST: Likewise. + * conf/common.mk: Likewise. + * conf/i386-coreboot.mk: Likewise. + * conf/i386-efi.mk: Likewise. + * conf/i386-ieee1275.mk: Likewise. + * conf/i386.mk: Likewise. + * conf/i386-pc.mk: Likewise. + * conf/powerpc-ieee1275.mk: Likewise. + * conf/sparc64-ieee1275.mk: Likewise. + * conf/x86_64-efi.mk: Likewise. + + * INSTALL: Remove the sentence that Ruby and autoconf are only required if you + develop on GRUB. + +2009-04-14 John Stanley + David S. Miller + + * util/hostdisk.c (make_device_name): Fix buffer length + calculations. + +2009-04-14 Felix Zielcke + + * util/hostdisk.c [__FreeBSD__ || __FreeBSD_kernel__]: Include + and . + (open_device) [__FreeBSD__ || __FreeBSD_kernel_]: Use sysctlgetbyname() + to add 0x10 to `kern.geom.debugflags' if it's not already set, before + opening the device and reset them afterwards. + +2009-04-13 Pavel Roskin + + * conf/common.rmk (grub_fstest_SOURCES): Add normal/datetime.c. + Reported by John Stanley + +2009-04-13 Robert Millan + + * util/grub.d/10_freebsd.in: Detect Debian GNU/kFreeBSD and use + that name for menuentries when appropriate. + +2009-04-13 Felix Zielcke + + * util/grub.d/10_freebsd.in: Add a missing `fi'. + +2009-04-13 Robert Millan + + * loader/i386/linux.c (grub_cmd_linux): Don't pass `vga=ask' parameter + to Linux, simply abort telling the user it's no longer supported. + +2009-04-13 Felix Zielcke + + * util/grub.d/10_freebsd.in: Don't exit if /boot/devices.hints + doesn't exist. Check also for /boot/kernel/kernel.gz. Print + `freebsd_loadenv' only when devices.hints exist. + +2009-04-13 Pavel Roskin + + * term/usb_keyboard.c (grub_usb_keyboard_getkey): Warning fixes. + +2009-04-13 Felix Zielcke + + * util/i386/pc/grub-install.in (install_drive): Remove the BSD + partition number. + (grub_drive): Likewise. + +2009-04-13 David S. Miller + + * kern/sparc64/ieee1275/ieee1275.c: New file. + * include/grub/sparc64/ieee1275/ieee1275.h (IEEE1275_MAP_WRITE, + IEEE1275_MAP_READ, IEEE1275_MAP_EXEC, IEEE1275_MAP_LOCKED, + IEEE1275_MAP_CACHED, IEEE1275_MAP_SE, IEEE1275_MAP_GLOBAL, + IEEE1275_MAP_IE, IEEE1275_MAP_DEFAULT): Define. + (grub_ieee1275_map_physical, grub_ieee1275_claim_vaddr, + grub_ieee1275_alloc_physmem): Declare new exported functions. + + * include/grub/sparc64/ieee1275/loader.h: New file. + * include/grub/sparc64/ieee1275/memory.h: Likewise. + * include/grub/sparc64/kernel.h: Likewise. + * loader/sparc64/ieee1275/linux.c: Likewise. + + * conf/common.rmk (grub_probe_SOURCES): Add Sun partition module. + (grub_fstest_SOURCES): Likewise. + + * util/hostdisk.c (make_device_name): Do not make any assumptions + about the length of drive names. + + * kern/dl.c (grub_dl_load_file): Close file immediately when + we are done using it. + +2009-04-12 David S. Miller + + * kern/misc.c (grub_ltoa): Fix cast when handling negative + values. Noticed by Pavel Roskin. + + * configure.ac: Check for __bswapsi2 and__bswapdi2 using + target compiler. + + * genmk.rb: Add more flexible image type specification, also + pass --strip-unneeded to objcopy. + * conf/i386-pc.rmk: Use *_FORMAT. + * conf/i386-pc.mk: Rebuilt. + + * disk/ieee1275/ofdisk.c (struct ofdisk_hash_ent): New struct. + (OFDISK_HASH_SZ): Define. + (ofdisk_hash): New hash table. + (ofdisk_hash_fn, ofdisk_hash_find, ofdisk_hash_add): New functions. + (grub_ofdisk_open): Use ofdisk_hash_ent address as disk->id + instead of device phandle which is not unique. + + * kern/sparc64/ieee1275/init.c: Delete, replace with... + * kern/sparc64/ieee1275/crt0.S: assembler implementation. + * include/grub/sparc64/ieee1275/kernel.h: Declare grub_prefix[]. + (GRUB_MOD_ALIGN, GRUB_MOD_GAP, GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE, + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE, + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE, GRUB_KERNEL_MACHINE_PREFIX, + GRUB_KERNEL_MACHINE_DATA_END): Define. + (grub_kernel_image_size, grub_total_module_size): Declare. + +2009-04-12 Pavel Roskin + + * configure.ac: Change the logic when we check for target tools. + Do it when the target is specified and it's different from the + specified value of the host. + +2009-04-11 Felix Zielcke + + * util/hostdisk.c [__FreeBSD_kernel__]: Include sys/disk.h. + (grub_util_biosdisk_open) [__FreeBSD_kernel__]: Add support for + GNU/kFreeBSD. Check if a device is a character device. Use + DIOCGMEDIASIZE to get the size. + (convert_system_partition_to_system_disk) [__FreeBSD_kernel__]: Add + support for GNU/kFreeBSD. + (grub_util_biosdisk_get_grub_dev) [__FreeBSD_kernel__]: Check if OS_DEV + is a character device instead of a block device. Add support for + FreeBSD device names. + + * util/getroot.c (find_root_device) [__FreeBSD_kernel__]: Check if ENT + is a character device instead of a block device. + + * util/grub-probe.c (probe) [__FreeBSD_kernel__]: Check if DEVICE_NAME + is a character device instead of a block device. + +2009-04-11 Andrey Shuvikov + + * util/hostdisk.c [__FreeBSD__]: Include sys/disk.h. + (grub_util_biosdisk_open) [__FreeBSD__]: Add support for + FreeBSD. Check if a device is a character device. Use + DIOCGMEDIASIZE to get the size. + (convert_system_partition_to_system_disk) [__FreeBSD__]: Add + support for FreeBSD. + (grub_util_biosdisk_get_grub_dev) [__FreeBSD__]: Check if OS_DEV + is a character device instead of a block device. Add support for + FreeBSD device names. + + * util/getroot.c (find_root_device) [__FreeBSD__]: Check if ENT is + a character device instead of a block device. + (grub_util_check_char_device): New function. + + * util/grub-probe.c (probe) [__FreeBSD__]: Check if DEVICE_NAME is + a character device instead of a block device. + + * include/grub/util/getroot.h (grub_util_check_char_device): New + prototype. + +2009-04-11 David S. Miller + + * conf/sparc64-ieee1275.rmk (kernel_img_LDFLAGS): Link with + static libgcc. + * configure.ac: Check for __bswapsi2 and __bswapdi2 presence. + * include/grub/sparc64/libgcc.h (__bswapsi2): Export libgcc + function, if present. + (__bswapdi2): Likewise. + + * include/grub/sparc64/ieee1275/boot.h: New file. + * boot/sparc64/ieee1275/boot.S: Likewise. + * boot/sparc64/ieee1275/diskboot.S: Likewise. + + * kern/misc.c (grub_ltoa): New function. + (grub_vsprintf): Use it to format 'long' integers. + +2009-04-10 David S. Miller + + * disk/ieee1275/nand.c (grub_nand_open): All ieee1275 call arg + slots are of type grub_ieee1275_cell_t. + (grub_nand_read): Likewise. + * kern/ieee1275/ieee1275.c (IEEE1275_PHANDLE_INVALID, + IEEE1275_IHANDLE_INVALID): Use grub_ieee1275_cell_t since these + macros are used to compare values in arg/ret block of the call. + (grub_ieee1275_finddevice, grub_ieee1275_get_property, + grub_ieee1275_next_property, grub_ieee1275_get_property_length, + grub_ieee1275_instance_to_package, grub_ieee1275_package_to_path, + grub_ieee1275_instance_to_path, grub_ieee1275_write, + grub_ieee1275_read, grub_ieee1275_seek, grub_ieee1275_peer, + grub_ieee1275_child, grub_ieee1275_parent, grub_ieee1275_open, + grub_ieee1275_close, grub_ieee1275_set_property, + grub_ieee1275_set_color): All ieee1275 call arg slots are of type + grub_ieee1275_cell_t. + * kern/ieee1275/openfw.c (grub_map): Likewise. + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_ihandle_t, + grub_ieee1275_phandle_t): Define as grub_unit32_t type. + + * kern/ieee1275/init.c (grub_machine_init): Make 'actual' grub_ssize_t. + * kern/ieee1275/openfw.c (grub_children_iterate): Likewise. + (grub_devalias_iterate): Likewise. + +2009-04-10 Vladimir Serbinenko + + UFS improvements + + * fs/ufs.c (INODE_NBLOCKS): new definition + (struct grub_ufs_dirent): added fields for non-BSD dirents + (grub_ufs_get_file_block): fixed double indirect handling + (grub_ufs_lookup_symlink): use more robust way to determine whether + symlink is inline + (grub_ufs_find_file): support for non-BSD dirents + (grub_ufs_dir): support for non-BSD dirents + +2009-04-10 Bean + + * include/grub/efi/api.h (grub_efi_configuration_table): Add packed + attribute, otherwise the size would be wrong for i386 platform. + + * include/grub/pci.h (grub_pci_read_word): New inline function. + (grub_pci_read_byte): Likewise. + (grub_pci_write): Likewise. + (grub_pci_write_word): Likewise. + (grub_pci_write_byte): Likewise. + + * include/grub/pci.h (grub_pci_iteratefunc_t): Add NESTED_FUNC_ATTR. + + * loader/i386/efi/linux.c (fake_bios_data): Moved to loadbios module. + (find_framebuf): Scan pci to locate the frame buffer address. + + * commands/efi/fixvideo.c: New file. + + * commands/efi/loadbios.c: Likewise. + + * commands/memrw.c: Likewise. + + * util/grub-dumpbios.in: Likewise. + + * conf/common.rmk (grub-dumpbios): New utility. + (pkglib_MODULES): New module memrw.mod. + (memrw_mod_SOURCE): New macro. + (memrw_mod_CFLAGS): Likewise. + (memrw_mod_LDFLAGS): Likewise. + + * conf/i386-efi.rmk (pkglib_MODULES): New module loadbios.mod and + fixvideo.mod. + (loadbios_mod_SOURCE): New macro. + (loadbios_mod_CFLAGS): Likewise. + (loadbios_mod_LDFLAGS): Likewise. + (fixvideo_mod_SOURCE): Likewise. + (fixvideo_mod_CFLAGS): Likewise. + (fixvideo_mod_LDFLAGS): Likewise. + + * conf/x86_64.rmk (pkglib_MODULES): New module loadbios.mod and + fixvideo.mod. + (loadbios_mod_SOURCE): New macro. + (loadbios_mod_CFLAGS): Likewise. + (loadbios_mod_LDFLAGS): Likewise. + (fixvideo_mod_SOURCE): Likewise. + (fixvideo_mod_CFLAGS): Likewise. + (fixvideo_mod_LDFLAGS): Likewise. + +2009-04-08 Felix Zielcke + + * disk/lvm.c (grub_lvm_scan_device): Add a missing NULL check. + +2009-04-07 David S. Miller + + * kern/sparc64/dl.c (grub_arch_dl_relocate_symbols): Add + support for R_SPARC_OLO10 relocations. Fix compile warning for + R_SPARC_WDISP30 case. + * kern/sparc64/cache.S: Fix grub_arch_sync_caches implementation. + +2009-04-06 Pavel Roskin + + * include/grub/misc.h (ARRAY_SIZE): New macro. + * include/grub/i386/linux.h (GRUB_LINUX_VID_MODE_VESA_START): + New macro. + * loader/i386/linux.c (allocate_pages): Use free_pages(). + (grub_linux_unload): Don't use free_pages(). + (grub_linux_boot): Prevent accessing linux_vesafb_modes with a + wrong index. Treat all other modes as text modes. + (grub_cmd_linux): Initialize vid_mode unconditionally to + GRUB_LINUX_VID_MODE_NORMAL. Recognize and support "vga=ask". + + * commands/help.c (print_command_help): Use cmd->prio, not + cmd->flags to check for GRUB_PRIO_LIST_FLAG_ACTIVE. + +2009-04-06 Vladimir Serbinenko + + Parttool + + * parttool/pcpart.c: new file + * commands/parttool.c: likewise + * conf/common.rmk (pkglib_MODULES): Added parttool.mod and pcpart.mod + (parttool_mod_SOURCES): new variable + (parttool_mod_CFLAGS): likewise + (parttool_mod_LDFLAGS): likewise + (pcpart_mod_SOURCES): likewise + (pcpart_mod_CFLAGS): likewise + (pcpart_mod_LDFLAGS): likewise + * conf/i386-coreboot.rmk (grub_emu_SOURCES): added commands/parttool.c + and parttool/pcpart.c + * conf/i386-efi.rmk: likewise + * conf/i386-ieee1275.rmk: likewise + * conf/i386-pc.rmk: likewise + * conf/powerpc-ieee1275.rmk: likewise + * conf/sparc64-ieee1275.rmk: likewise + * conf/x86_64-ieee1275.rmk: likewise + +2009-04-05 Vladimir Serbinenko + + Support for mtime and further expandability of dir command + + * include/grub/lib/datetime.h: moved to ... + * include/grub/datetime.h: ... moved here and added + declaration of grub_unixtime2datetime. All users updated + * include/grub/fs.h: new syntax for dir and mtime functions in + struct grub_fs + * include/grub/fshelp.h: new declarations of GRUB_FSHELP_TYPE_MASK + and GRUB_FSHELP_FLAGS_MASK + * commands/ls.c (grub_ls_list_files): Write mtime in long format + * fs/ext2.c (grub_ext2_dir): use new dir syntax and supply mtime + (grub_ext2_mtime): new function + * fs/hfsplus.c (grub_hfsplus_dir): use new dir syntax and supply mtime + (grub_hfsplus_mtime): new function + * fs/ufs.c (GRUB_UFS_ATTR_TYPE): new definition + (GRUB_UFS_ATTR_FILE): likewise + (GRUB_UFS_ATTR_LNK): likewise + (struct grub_ufs_sblock): new fields mtime + (grub_ufs_read_inode): new parameter to read inode to a separate buffer + all users updated + (grub_ufs_dir): mtime support + (grub_ufs_mtime): new function + * fs/affs.c (grub_affs_dir): use new dir syntax + * fs/afs.c (grub_afs_dir): likewise + * fs/cpio.c (grub_cpio_dir): likewise + * fs/fat.c (grub_fat_find_dir): likewise + * fs/hfs.c (grub_hfs_dir): likewise + * fs/iso9660.c (grub_iso9660_dir): likewise + * fs/jfs.c (grub_jfs_dir): likewise + * fs/minix.c (grub_minix_dir): likewise + * fs/ntfs.c (grub_ntfs_dir): likewise + * fs/reiserfs.c (grub_reiserfs_dir): likewise + * fs/sfs.c (grub_sfs_dir): likewise + * fs/xfs.c (grub_xfs_dir): likewise + * util/hostfs.c (grub_hostfs_dir): likewise + * lib/datetime.c: moved to ... + * normal/datetime.c: ... moved here + (grub_unixtime2datetime): new function + * kern/rescue.c (grub_rescue_print_files): use new dir syntax + * normal/completion.c (iterate_dir): use new dir syntax + * normal/misc.c (grub_normal_print_device_info): tell the + last modification time of a volume + * kern/fs.c (grub_fs_probe): updated dummy function to use new syntax + * conf/common.rmk: added lib/datetime.c to ls.mod + * conf/i386-coreboot.rmk (grub_emu_SOURCES): add normal/datetime.c + (normal_mod_SOURCES): likewise + (datetime_mod_SOURCES): Removed lib/datetime.c + * conf/i386-efi.rmk: likewise + * conf/i386-ieee1275.rmk: likewise + * conf/i386-pc.rmk: likewise + * conf/powerpc-ieee1275.rmk: likewise + * conf/sparc64-ieee1275.rmk: likewise + * conf/x86_64-efi.rmk: likewise + +2009-04-05 Vladimir Serbinenko + + Trim trailing spaces in FAT label and support mtools-like labels + + * fs/fat.c (grub_fat_iterate_dir): New function based + on grub_fat_find_dir + (grub_fat_find_dir): use grub_fat_iterate_dir + (grub_fat_label): likewise + +2009-04-04 Vladimir Serbinenko + + * conf/powerpc-ieee1275.rmk (kernel_elf_HEADERS): add list.h + and command.h + remove extraneous kernel_elf_HEADERS + +2009-04-04 Bean + + * include/grub/util/misc.h: Add dummy function fsync for mingw. + + * util/misc.c: Likewise. + +2009-04-04 Yoshinori K. Okuji + + * loader/i386/efi/linux.c (fake_bios_data): Use grub_dprintf + instead of grub_printf. + +2009-04-03 Robert Millan + + * loader/i386/linux.c (grub_linux_setup_video): Fill + `params->{red,green,blue,reserved}_{mask_size,field_pos}' with + values from `mode info' structure instead of hardcoded + values. + +2009-04-01 Pavel Roskin + + * Makefile.in: Remove all references to MODULE_LDFLAGS, it's + unused now. + * genmk.rb: Likewise. + * configure.ac: Likewise. + +2009-04-01 Manoel Abranches + + * aclocal.m4: Move --build-id=none from MODULE_LDFLAGS to + TARGET_LDFLAGS. This corrects a problem with grub-mkelfimage. + +2009-04-01 David S. Miller + + * normal/sparc64/setjmp.S: Fix setjmp implementation. + * include/grub/sparc64/setjmp.h (grub_jmp_buf): Update. + (grub_setjmp): Mark with 'returns_twice' attribute. + * include/grub/i386/setjmp.h (grub_setjmp): Likewise + * include/grub/powerpc/setjmp.h (grub_setjmp): Likewise. + * include/grub/x86_64/setjmp.h (grub_setjmp): Likewise. + +2009-04-01 Robert Millan + + Reapply fix from 2008-07-28 which was accidentally reverted; also + perform the same fix to a similar check in same function. + + * disk/raid.c (grub_raid_scan_device): Do not abort when two disks + with the same number are found, just use issue a warning with + grub_dprintf(), as this error has been reported to be non-fatal. + +2009-03-31 Pavel Roskin + + * aclocal.m4 (grub_I386_CHECK_REGPARM_BUG): Provide safe default + for cross-compilation. + +2009-03-30 Robert Millan + + Fix i386-ieee1275 build. + + * include/grub/i386/ieee1275/loader.h (grub_multiboot2_real_boot): + Remove declaration. + +2009-03-30 Pavel Roskin + + * fs/hfs.c (grub_hfs_strncasecmp): Integrate into ... + (grub_hfs_cmp_catkeys): ... this. Don't assume strings to be + zero-terminated, rely only on the strlen value. Fix comparison + of strings differing in length. + +2009-03-30 Robert Millan + + * loader/i386/linux.c (grub_cmd_linux): Check for zImage before + checking for abi version. Improve error messages on BIOS to notify + user about `linux16' command. + +2009-03-29 Vladimir Serbinenko + + Leak fixes + + * kern/disk.c (grub_disk_cache_store): Invalidate previous cache + in case of collision + * disk/scsi.c (grub_scsi_open): free scsi in case of error + +2009-03-29 Robert Millan + + * loader/i386/linux.c (grub_cmd_linux): Parse "vga=" parameter and + set `vid_mode' accordingly. + (grub_linux_boot): Process `vid_mode' and set video mode. + +2009-03-29 Robert Millan + + * util/grub.d/10_linux.in (linux_entry): New function. + Factorize generation of Linux boot entries. + +2009-03-29 Yoshinori K. Okuji + + Make the format of Environment Block plain text. The boot loader + part is not tested well yet. + + * util/grub-editenv.c (DEFAULT_ENVBLK_SIZE): New macro. + (buffer): Removed. + (envblk): Likewise. + (usage): Remove "info" and "clear". Add "unset". Update the + description of "set", as this does not delete variables any + longer. + (create_envblk_file): Complete rewrite. + (open_envblk_file): Likewise. + (cmd_info): Removed. + (cmd_list): Likewise. + (cmd_set): Likewise. + (cmd_clear): Likewise. + (list_variables): New function. + (write_envblk): Likewise. + (set_variables): Likewise. + (unset_variables): Likewise. + (main): Complete rewrite. + + * commands/loadenv.c (buffer): Removed. + (envblk): Likewise. + (open_envblk_file): New function. + (read_envblk_file): Complete rewrite. + (grub_cmd_load_env): Likewise. + (grub_cmd_list_env): Likewise. + (struct blocklist): New struct. + (free_blocklists): New function. + (check_blocklists): Likewise. + (write_blocklists): Likewise. + (grub_cmd_save_env): Complete rewrite. + + * include/grub/lib/envblk.h (GRUB_ENVBLK_SIGNATURE): Replaced with + a plain text signature. + (GRUB_ENVBLK_MAXLEN): Removed. + (struct grub_envblk): Complete rewrite. + (grub_envblk_find): Removed. + (grub_envblk_insert): Likewise. + (grub_envblk_open): New prototype. + (grub_envblk_set): Likewise. + (grub_envblk_delete): Put const to VALUE. + (grub_envblk_iterate): Put const to NAME and VALUE. + (grub_envblk_close): New prototype. + (grub_envblk_buffer): New inline function. + (grub_envblk_size): Likewise. + + * lib/envblk.c: Include grub/mm.h. + (grub_env_find): Removed. + (grub_envblk_open): New function. + (grub_envblk_close): Likewise. + (escaped_value_len): Likewise. + (find_next_line): Likewise. + (grub_envblk_insert): Removed. + (grub_envblk_set): New function. + (grub_envblk_delete): Complete rewrite. + (grub_envblk_iterate): Likewise. + +2009-03-28 Robert Millan + + * conf/i386-pc.rmk (pkglib_MODULES): Add `linux16.mod'. + (linux16_mod_SOURCES, linux16_mod_CFLAGS, linux16_mod_LDFLAGS): New + variables. Use 16-bit loader. + (linux_mod_SOURCES, linux_mod_CFLAGS, linux_mod_LDFLAGS): Use 32-bit + loader. + * kern/i386/loader.S (grub_linux_boot): Rename to ... + (grub_linux16_boot): ... this. Update all users. + * loader/i386/linux.c (grub_linux32_boot): Rename to ... + (grub_linux_boot): ... this. Update all users. + + * loader/i386/pc/linux.c (GRUB_MOD_INIT(linux)): Rename to ... + (GRUB_MOD_INIT(linux16)): ... this. Rename `linux' and `initrd' + commands to `linux16' and `initrd16'. + (GRUB_MOD_FINI(linux)): Rename to ... + (GRUB_MOD_FINI(linux16)): ... this. + +2009-03-24 Pavel Roskin + + * genmk.rb: Define ASM_FILE for *.S files for *.lst generation, + not just for compilation. + +2009-03-22 Vladimir Serbinenko + + Move multiboot helper out of kernel + + * conf/i386-pc.rmk (multiboot_mod_SOURCES): Add + `loader/i386/multiboot_helper.S'. + * conf/i386-coreboot.rmk: Likewise + * conf/i386-ieee1275.rmk: Likewise + + * kern/i386/loader.S: Move multiboot helpers from here... + * loader/i386/multiboot_helper.S: ...moved here + * include/grub/i386/loader.h: Move declarations of multiboot + helpers from here... + * include/grub/i386/multiboot.h: ...moved here + * loader/i386/multiboot.c: Added include of grub/cpu/multiboot.h + +2009-03-22 Yoshinori K. Okuji + + * kern/env.c (grub_env_context_open): Added an argument to specify + whether a new context inherits exported variables from current + one. This is useful when making a sandbox to interpret a config + file. + All callers updated. + + * include/grub/env.h (grub_env_context_open): Updated the prototype. + +2009-03-22 Yoshinori K. Okuji + + * kern/env.c (grub_env_context_close): Fix memory leaks. + +2009-03-22 Yoshinori K. Okuji + + * normal/main.c (grub_normal_execute): Added an argument + BATCH to specify if an interactive interface should be provided + after reading a config file. + All callers updated. + (read_command_list): Prevent being executed twice. + (read_fs_list): Likewise. + + * include/grub/normal.h (grub_normal_execute): Updated the + prototype. + +2009-03-22 Pavel Roskin + + * kern/powerpc/ieee1275/startup.S: Replace EXT_C(start) with + _start. + * kern/i386/pc/startup.S: Likewise. + * kern/i386/efi/startup.S: Likewise. + * kern/i386/ieee1275/startup.S: Likewise. + * kern/i386/coreboot/startup.S: Likewise. + * kern/x86_64/efi/startup.S: Likewise. + + * aclocal.m4 (grub_CHECK_START_SYMBOL): Remove. + * configure.ac: Don't call grub_CHECK_START_SYMBOL. + * kern/i386/pc/startup.S: Use _start instead of START_SYMBOL. + +2009-03-21 Vladimir Serbinenko + + Bugfixes in multiboot for bugs uncovered by solaris kernel. + + * loader/i386/multiboot_elfxx.c (grub_multiboot_load_elf): Corrected + limit detection. + Use vaddr of correct segment for entry_point. + +2009-03-21 Bean + + * commands/blocklist.c: Add include file , remove + and . + (grub_cmd_blocklist): Use the new command interface. + (GRUB_MOD_INIT): Likewise. + (GRUB_MOD_FINI): Likewise. + * commands/boot.c: Likewise. + * commands/cat.c: Likewise. + * commands/cmp.c: Likewise. + * commands/configfile.c: Likewise. + * commands/crc.c: Likewise. + * commands/echo.c: Likewise. + * commands/halt.c: Likewise. + * commands/handler.c: Likewise. + * commands/hdparm.c: Likewise. + * commands/help.c: Likewise. + * commands/hexdump.c: Likewise. + * commands/loadenv.c: Likewise. + * commands/ls.c: Likewise. + * commands/lsmmap.c: Likewise. + * commands/lspci.c: Likewise. + * commands/loadenv.c: Likewise. + * commands/read.c: Likewise. + * commands/reboot.c: Likewise. + * commands/search.c: Likewise. + * commands/sleep.c: Likewise. + * commands/test.c: Likewise. + * commands/usbtest.c: Likewise. + * commands/videotest.c: Likewise. + * commands/i386/cpuid.c: Likewise. + * commands/i386/pc/halt.c: Likewise. + * commands/i386/pc/play.c: Likewise. + * commands/i386/pc/pxecmd.c: Likewise. + * commands/i386/pc/vbeinfo.c: Likewise. + * commands/i386/pc/vbetest.c: Likewise. + * commands/ieee1275/suspend.c: Likewise. + * disk/loopback.c: Likewise. + * font/font_cmd.c: Likewise. + * hello/hello.c: Likewise. + * loader/efi/appleloader.c: Likewise. + * loader/efi/chainloader.c: Likewise. + * loader/i386/bsd.c: Likewise. + * loader/i386/efi/linux.c: Likewise. + * loader/i386/ieee1275/linux.c: Likewise. + * loader/i386/linux.c: Likewise. + * loader/i386/pc/chainloader.c: Likewise. + * loader/i386/pc/linux.c: Likewise. + * loader/powerpc/ieee1275/linux.c: Likewise. + * loader/multiboot_loader.c: Likewise. + * term/gfxterm.c: Likewise. + * term/i386/pc/serial.c: Likewise. + * term/terminfo.c: Likewise. + + * term/i386/pc/vesafb.c: Removed . + * term/i386/pc/vga.c: Likewise. + * video/readers/jpeg.c: Likewise. + * video/readers/png.c: Likewise. + * video/readers/tga.c: Likewise. + + * util/grub-fstest (cmd_loopback): Removed. + (cmd_blocklist): Likewise. + (cmd_ls): Likewise. + (grub_register_command): Likewise. + (grub_unregister_command): Likewise. + (execute_command): Use grub_command_find to locate command and execute + it. + + * include/grub/efi/chainloader.h: Removed. + * loader/efi/chainloader_normal.c: Likewise. + * loader/i386/bsd_normal.c: Likewise. + * loader/i386/pc/chainloader_normal.c: Likewise. + * loader/i386/pc/multiboot_normal.c: Likewise. + * loader/linux_normal.c: Likewise. + * loader/multiboot_loader_normal.c: Likewise. + * loader/powerpc/ieee1275/linux_normal.c: Likewise. + + * gencmdlist.sh: Scan new registration command grub_register_extcmd + and grub_register_command_p1. + + * conf/common.rmk (grub_fstest_SOURCES): Add kern/list.c, + kern/command.c, lib/arg.c and commands/extcmd.c. + (pkglib_MODULES): Remove boot.mod, and minicmd.mod and extcmd.mod. + (minicmd_mod_SOURCES): New variable. + (minicmd_mod_CFLAGS): Likewise. + (minicmd_mod_LDFLAGS): Likewise. + (extcmd_mod_SOURCES): Likewise. + (extcmd_mod_CFLAGS): Likewise. + (extcmd_mod_LDFLAGS): Likewise. + (boot_mod_SOURCES): Removed. + (boot_mod_CFLAGS): Likewise. + (boot_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (kernel_img_SOURCES): Add kern/command.c and + kern/corecmd.c. + (kernel_img_HEADERS): Add command.h. + (grub_emu_SOURCES): Remove commands/boot.c and normal/arg.c, add + commands/minicmd.c, kern/command.c, kern/corecmd.c, commands/extcmd.c + and lib/arg.c. + (pkglib_MODULES): Change _linux.mod, _chain.mod, _bsd.mod and + _multiboot.mod as linux.mod, chain.mod, bsd.mod and multiboot.mod, + remove the corresponding normal mode command. + (normal_mod_SOURCES): Remove normal/arg.c. + * conf/i386-coreboot.rmk: Likewise. + * conf/i386-efi.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + + * include/grub/arg.h: Move from here ... + * include/grub/lib/arg.h: ... to here. + + * normal/arg.c: Move from here ... + * lib/arg.c: ... to here. + + * commands/extcmd.c: New file. + * commands/minicmd.c: Likewise. + * include/grub/command.h: Likewise. + * include/grub/extcmd.h: Likewise. + * kern/command.c: Likewise. + * kern/corecmd.c: Likewise. + + * kern/list.c (grub_list_iterate): Return int instead of void. + (grub_list_insert): New function. + (grub_prio_list_insert): Likewise. + + * kern/rescue.c (grub_rescue_command): Removed. + (grub_rescue_command_list): Likewise. + (grub_rescue_register_command): Likewise. + (grub_rescue_unregister_command): Likewise. + (grub_rescue_cmd_boot): Move to minicmd.c + (grub_rescue_cmd_help): Likewise. + (grub_rescue_cmd_info): Likewise. + (grub_rescue_cmd_boot): Likewise. + (grub_rescue_cmd_testload): Likewise. + (grub_rescue_cmd_dump): Likewise. + (grub_rescue_cmd_rmmod): Likewise. + (grub_rescue_cmd_lsmod): Likewise. + (grub_rescue_cmd_exit): Likewise. + (grub_rescue_print_devices): Moved to corecmd.c. + (grub_rescue_print_files): Likewise. + (grub_rescue_cmd_ls): Likewise. + (grub_rescue_cmd_insmod): Likewise. + (grub_rescue_cmd_set): Likewise. + (grub_rescue_cmd_unset): Likewise. + (attempt_normal_mode): Use grub_command_find to get normal module. + (grub_enter_rescue_mode): Use grub_register_core_commands to register + commands, remove grub_rescue_register_command calls. + + * normal/command.c (grub_register_command): Removed. + (grub_unregister_command): Likewise. + (grub_command_find): Likewise. + (grub_iterate_commands): Likewise. + (rescue_command): Likewise. + (export_command): Moved to corecmd.c. + (set_command): Removed. + (unset_command): Likewise. + (insmod_command): Likewise. + (rmmod_command): Likewise. + (lsmod_command): Likewise. + (grub_command_init): Likewise. + + * normal/completion.c (iterate_command): Use cmd->prio to check for + active command. + (complete_arguments): Use grub_extcmd_t structure to find options. + (grub_normal_do_completion): Change function grub_iterate_commands to + grub_command_iterate. + + * normal/execute.c (grub_script_execute_cmd): No need to parse + argument here. + + * normal/main.c (grub_dyncmd_dispatcher): New function. + (read_command_list): Register unload commands as dyncmd. + (grub_cmd_normal): Use new command interface, register rescue, + unregister normal at entry, register normal, unregister rescue at exit. + + * include/grub/list.h (grub_list_test_t): New type. + (grub_list_iterate): Return int instead of void. + (grub_list_insert): New function. + (GRUB_AS_NAMED_LIST_P): New macro. + (GRUB_AS_PRIO_LIST): Likewise. + (GRUB_AS_PRIO_LIST_P): Likewise. + (GRUB_PRIO_LIST_PRIO_MASK): New constant. + (GRUB_PRIO_LIST_FLAG_ACTIVE): Likewise. + (grub_prio_list): New structure. + (grub_prio_list_insert): New function. + (grub_prio_list_remove): New inline function. + + * include/grub/normal.h: Remove , add . + (GRUB_COMMAND_FLAG_CMDLINE): Moved to command.h. + (GRUB_COMMAND_FLAG_MENU): Likewise. + (GRUB_COMMAND_FLAG_BOTH): Likewise. + (GRUB_COMMAND_FLAG_TITLE): Likewise. + (GRUB_COMMAND_FLAG_NO_ECHO): Likewise. + (GRUB_COMMAND_FLAG_NO_ARG_PARSE): Removed. + (GRUB_COMMAND_FLAG_NOT_LOADED): Likewise. + (grub_command): Likewise. + (grub_register_command): Likewise. + (grub_command_find): Likewise. + (grub_iterate_commands): Likewise. + (grub_command_init): Likewise. + (grub_arg_parse): Likewise. + (grub_arg_show_help): Likewise. + + * include/grub/rescue.h (grub_rescue_register_command): Removed. + (grub_rescue_unregister_command): Likewise. + + * include/grub/i386/bsd.h: Remove grub_rescue_cmd_freebsd, + grub_rescue_cmd_openbsd, grub_rescue_cmd_netbsd, + grub_rescue_cmd_freebsd_loadenv and grub_rescue_cmd_freebsd_module. + + * include/grub/i386/efi/loader.h: Remove grub_rescue_cmd_linux and + grub_rescue_cmd_initrd. + * include/grub/i386/loader.h: Likewise. + * include/grub/x86_64/loader.h: Likewise. + + * include/grub/i386/pc/chainloader.h: Remove grub_chainloader_cmd. + +2009-03-21 Bean + + * util/hostdisk.c (read_device_map): Use grub_util_get_disk_size + instead of stat in mingw environment. + + * util/misc.c (grub_millisleep): Use Sleep in mingw environment. + + * aclocal.m4 (grub_CHECK_LINK_DIR): New function. + + * configure.ac: Use grub_CHECK_LINK_DIR to determine whether to use + AC_CONFIG_LINKS. + +2009-03-21 Bean + + * fs/ext2.c (grub_ext2_mount): Change errno to GRUB_ERR_BAD_FS for + out of range error. + +2009-03-18 Michel Dänzer + + * fs/ext2.c (grub_ext2_read_block): Take endianness into account when + checking inode flags for EXT4_EXTENTS_FLAG. + +2009-03-18 Robert Millan + + * loader/i386/linux.c: Include `' and + `'.. + (grub_linux_setup_video): New function. Loosely based on the EFI one. + (grub_linux32_boot): Attempt to configure video settings with + grub_linux_setup_video(). + (grub_rescue_cmd_linux): Set noreturn=0 in grub_loader_set, in order + to avoid grub_console_fini() which would step out of graphical mode + unconditionally. + +2009-03-14 Robert Millan + + Fix build on powerpc. + * conf/powerpc-ieee1275.rmk (kernel_elf_HEADERS): Add `handler.h'. + +2009-03-12 Vladimir Serbinenko + + * term/gfxterm.c (GRUB_MOD_FINI(term_gfxterm)): Correct name of + background image command. + +2009-03-12 Colin D Bennett + + * term/gfxterm.c (draw_cursor): Ensure character is redrawn. + (grub_gfxterm_putchar): Extract pairs of identical calls to + draw_cursor out of conditional blocks. + +2009-03-11 Pavel Roskin + + * fs/hfs.c (grub_hfs_strncasecmp): New function. + (grub_hfs_cmp_catkeys): Use HFS specific string comparison. + +2009-03-11 Robert Millan + + * loader/i386/multiboot_elfxx.c + (CONCAT(grub_multiboot_load_elf, XX)): Do not reject ET_DYN files. + +2009-03-11 Felix Zielcke + + * conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): Add `kern/list.c' and + `kern/handler.c'. + +2009-03-11 Robert Millan + + * loader/i386/multiboot.c (code_size): New variable. + (grub_multiboot): Define offsets by adding to `code_size' rather + than subtracting from `grub_multiboot_payload_size'. Provide + 4-byte alignment to MBI and others by increasing + `boot_loader_name_length' appropriately. + + * loader/i386/multiboot_elfxx.c + (CONCAT(grub_multiboot_load_elf, XX)): Initialize `code_size'. + +2009-03-09 Felix Zielcke + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Remove duplicated + `fs/ext2.c'. + +2009-03-08 Robert Millan + + Make loader/i386/linux.c usable on i386-pc again. + + * kern/i386/pc/init.c (grub_machine_init): Disable addition of low + memory to heap. + * loader/i386/linux.c [GRUB_MACHINE_PCBIOS] (allocate_pages): Remove + `#error' stanza. + +2009-03-07 Bean + + * loader/i386/efi/linux.c (grub_rescue_cmd_initrd): Fix a bug in initrd + allocation. + +2009-03-06 Robert Millan + + Fix display issue on terminals with screen size other than 80x25 + (e.g. gfxterm with resolution higher than 640x480). + + * normal/main.c (grub_normal_init_page): Display title text in a + position relative to the center of the terminal instead of relying + on a hardcoded offset. + +2009-03-04 Robert Millan + + Filter /etc/grub.d/10_* so that only add-ons for native kernels are + installed. + + * Makefile.in (host_kernel): New variable. + * conf/common.rmk (grub-mkconfig_SCRIPTS): Conditionalize all 10_*.in + scripts instead of just the windows one. + * configure.ac: Initialize and AC_SUBST `host_kernel'. + +2009-03-04 Felix Zielcke + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `kern/list.c' and + `kern/handler.c'. + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + +2009-03-04 Felix Zielcke + + * partmap/pc.c (pc_partition_map_iterate): Skip over invalid BSD partitions + or if there's no space for the disk label and print the partition number on a + invalid magic. + +2009-03-04 Felix Zielcke + + * util/misc.c: Include . + (grub_millisleep): New function. + +2009-03-04 Bean + + * configure.ac: Only test -mcmodel=large option in x86_64-efi, also add + another option -mno-red-zone. + + * commands/handler.c: Change module description. + + * kern/handler.c: Add missing space at the end of description line. + + * kern/list.c: Likewise. + +2009-03-03 Robert Millan + + Move more components to the relocation area, and fix mbi pointer + handling to use the destination rather than the origin (thanks to + Vladimir Serbinenko for spotting). + + * loader/i386/multiboot.c (mbi_dest): New variable. + (grub_multiboot_boot): Use `mbi_dest' instead of `mbi'. + (grub_multiboot): Put cmdline, boot_loader_name and mbi in the + relocation area. + +2009-03-01 Bean + + * include/grub/efi/api.h (GRUB_EFI_MPS_TABLE_GUID): New constant. + (GRUB_EFI_ACPI_TABLE_GUID): Likewise. + (GRUB_EFI_ACPI_20_TABLE_GUID): Likewise. + (GRUB_EFI_SMBIOS_TABLE_GUID): Likewise. + + * loader/i386/efi/linux.c (acpi_guid): New variable. + (acpi_guid): Likewise. + (EBDA_SEG_ADDR): New constant. + (LOW_MEM_ADDR): Likewise. + (FAKE_EBDA_SEG): Likewise. + (fake_bios_data): New function. + (grub_linux_boot): Call fake_bios_data. + +2009-03-01 Bean + + * commands/terminal.c: Removed. + + * commands/handler.c: New file. + + * include/grub/list.h: Likewise. + + * include/grub/handler.h: Likewise. + + * kern/list.c: Likewise. + + * kern/handler.c: Likewise. + + * kern/term.h: Include header file . + (grub_term_input): Move next field to the beginning. + (grub_term_output): Likewise. + (grub_term_input_class): New variable. + (grub_term_output_class): Likewise. + (grub_term_register_input): Changed to inline function. + (grub_term_register_output): Likewise. + (grub_term_unregister_input): Likewise. + (grub_term_unregister_output): Likewise. + (grub_term_set_current_input): Likewise. + (grub_term_set_current_output): Likewise. + (grub_term_get_current_input): Likewise. + (grub_term_get_current_output): Likewise. + (grub_term_iterate_input): Removed. + (grub_term_iterate_output): Likewise. + + * kern/term.c (grub_term_list_input): Removed. + (grub_term_list_output): Likewise. + (grub_term_input_class): New variable. + (grub_term_output_class): Likewise. + (grub_cur_term_input): Change variable as macro. + (grub_cur_term_output): Likewise. + (grub_term_register_input): Removed. + (grub_term_register_output): Likewise. + (grub_term_unregister_input): Likewise. + (grub_term_unregister_output): Likewise. + (grub_term_set_current_input): Likewise. + (grub_term_set_current_output): Likewise. + (grub_term_iterate_input): Likewise. + (grub_term_iterate_output): Likewise. + (grub_term_get_current_input): Likewise. + (grub_term_get_current_output): Likewise. + + * util/grub-editenv.c: Include header file . + (grub_term_get_current_input): Removed. + (grub_term_get_current_output): Likewise. + (grub_term_input_class): New variable. + (grub_term_output_class): Likewise. + + * util/grub-fstest.c (grub_term_get_current_input): Removed. + (grub_term_get_current_output): Likewise. + (grub_term_input_class): New variable. + (grub_term_output_class): Likewise. + + * util/grub-probe.c (grub_term_get_current_input): Removed. + (grub_term_get_current_output): Likewise. + (grub_term_input_class): New variable. + (grub_term_output_class): Likewise. + + * util/i386/pc/grub-setup.c (grub_term_get_current_input): Removed. + (grub_term_get_current_output): Likewise. + (grub_term_input_class): New variable. + (grub_term_output_class): Likewise. + + * conf/common.rmk (pkglib_MODULES): Replace terminal with handler. + (terminal_mod_SOURCES): Likewise. + (terminal_mod_CFLAGS): Likewise. + (terminal_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Replace terminal.c with + handler.c. + (kernel_img_SOURCES): Add list.c and handler.c. + (kernel_img_HEADERS): Add list.h and handler.h. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Replace terminal.c with + handler.c. + (kernel_mod_SOURCES): Add list.c and handler.c. + (kernel_mod_HEADERS): Add list.h and handler.h. + + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Replace terminal.c with + handler.c. + (kernel_elf_SOURCES): Add list.c and handler.c. + (kernel_elf_HEADERS): Add list.h and handler.h. + + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Replace terminal.c with + handler.c. + (kernel_elf_SOURCES): Add list.c and handler.c. + (kernel_elf_HEADERS): Add list.h and handler.h. + + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Replace terminal.c with + handler.c. + (kernel_mod_SOURCES): Add list.c and handler.c. + (kernel_mod_HEADERS): Add list.h and handler.h. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Replace terminal.c with + handler.c. + (kernel_elf_SOURCES): Add list.c and handler.c. + (kernel_elf_HEADERS): Add list.h and handler.h. + +2009-02-27 Robert Millan + + Factorize elf32 / elf64 code in Multiboot loader. This will + prevent it from getting out of sync again. + + * loader/i386/multiboot.c (grub_multiboot_is_elf32, + grub_multiboot_load_elf32, grub_multiboot_is_elf64, + grub_multiboot_load_elf64): Move from here ... + * loader/i386/multiboot_elfxx.c (grub_multiboot_is_elf, + grub_multiboot_load_elf): ... to here (new file). + +2009-02-27 Robert Millan + + * util/grub.d/10_linux.in: Rename "single-user mode" to + "recovery mode". + +2009-02-27 Vladimir Serbinenko + + Don't leak in SCSI code. + * disk/scsi.c (grub_scsi_close): free `scsi'. + +2009-02-27 Robert Millan + + * loader/i386/pc/multiboot.c: Move from here ... + * loader/i386/multiboot.c: ... to here. Update all users. + +2009-02-27 Robert Millan + + Patch from Alexandre Bique + * util/i386/pc/grub-setup.c (setup): Fix directory path. + +2009-02-27 Krzysztof Smiechowicz + + * fs/sfs.c (grub_sfs_read_extent): Correction to traversing extent + b-tree. + +2009-02-27 Robert Millan + + * kern/misc.c (grub_strtoull): Fix bug (it mistakenly parsed the + `0x' qualifier as 0 when base is specified as parameter). + +2009-02-24 Bean + + * configure.ac: Check for -mcmodel=large in x86_64 target. + + * include/grub/efi/api.h (efi_call_10): New macro. + (efi_wrap_10): New function. + + * include/grub/efi/pe32.h (GRUB_PE32_REL_BASE_HIGH): New macro. + (GRUB_PE32_REL_BASED_HIGH): Likewise. + (GRUB_PE32_REL_BASED_LOW): Likewise. + (GRUB_PE32_REL_BASED_HIGHLOW): Likewise. + (GRUB_PE32_REL_BASED_HIGHADJ): Likewise. + (GRUB_PE32_REL_BASED_MIPS_JMPADDR): Likewise. + (GRUB_PE32_REL_BASED_SECTION): Likewise. + (GRUB_PE32_REL_BASED_REL): Likewise. + (GRUB_PE32_REL_BASED_IA64_IMM64): Likewise. + (GRUB_PE32_REL_BASED_DIR64): Likewise. + (GRUB_PE32_REL_BASED_HIGH3ADJ): Likewise. + + * kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Fixed relocation + issue. + + * kern/x86_64/efi/callwrap.S (efi_wrap_6): Bug fix. + (efi_wrap_10): New function. + + * kern/x86_64/efi/startup.S (codestart): Use relative addressing. + + * loader/efi/appleloader.c (devpath_5): Add support for late 2008 + MB/MBP model (NV chipset). + (devdata_devs): Add devpath_5 to the list. + + * load/i386/efi/linux.c (video_base): Remove variable. + (RGB_MASK): New macro. + (RGB_MAGIC): Likewise. + (LINE_MIN): Likewise. + (LINE_MAX): Likewise. + (FBTEST_STEP): Likewise. + (FBTEST_COUNT): Likewise. + (fb_list): New variable. + (grub_find_video_card): Remove function. + (find_framebuf): New function. + (grub_linux_setup_video): Use find_framebuf to get frame buffer and + line length. + + * util/i386/efi/grub-mkimage.c (grub_reloc_section): Fix relocation + problem for x86_64. + +2009-02-22 Vesa Jääskeläinen + + Patch #25624 by Kevin Lacquement . + + * util/grub-mkconfig.in: Use ${grub_mkdevicemap} instead of hard + coding tool name. + +2009-02-22 Robert Millan + + * include/multiboot.h (MULTIBOOT_INFO_ALIGN): New macro. + * loader/i386/pc/multiboot.c (grub_multiboot): Include the MBI + in our relocation, instead of using it directly from heap. Also + use `MULTIBOOT_INFO_ALIGN' to ensure it is aligned. + +2009-02-21 Robert Millan + + Implement USB keyboard support (based on patch by Marco Gerards) + + * conf/i386-pc.rmk (pkglib_MODULES): Add `usb_keyboard.mod'. + (usb_keyboard_mod_SOURCES, usb_keyboard_mod_CFLAGS) + (usb_keyboard_mod_LDFLAGS): New variables. + + * term/usb_keyboard.c: New file. + +2009-02-14 Vladimir Serbinenko + + Corrected wrong declaration + + * kern/disk.c: corrected declaration of grub_disk_ata_pass_through. + +2009-02-14 Christian Franke + + * commands/lspci.c (grub_pci_classes): Add `SATA Controller'. + (grub_lspci_iter): Print class code and programming interface byte. + +2009-02-14 Christian Franke + + * gendistlist.sh: Ignore `.svn' directories. + +2009-02-14 Felix Zielcke + + * fs/fat.c: Add 2009 to Copyright line. + +2009-02-14 Christian Franke + + * commands/hdparm.c: New file. Provides `hdparm' command + which sends ATA commands via grub_disk_ata_pass_through (). + + * conf/i386-pc.rmk: Add ata_pthru.mod and hdparm.mod. + + * disk/ata.c: Include . Move + and to include/grub/ata.h. + (enum grub_ata_addressing_t): Move to include/grub/ata.h. + (GRUB_CDROM_SECTOR_SIZE): Remove. + (GRUB_ATA_*): Move to include/grub/ata.h. + (GRUB_ATAPI_*): Likewise. + (enum grub_ata_commands): Likewise. + (enum grub_ata_timeout_milliseconds): Likewise. + (struct grub_ata_device): Likewise. + (grub_ata_regset): Likewise. + (grub_ata_regget): Likewise. + (grub_ata_regset2): Likewise. + (grub_ata_regget2): Likewise. + (grub_ata_check_ready): Likewise. + (grub_ata_wait_not_busy): Remove static, exported in + include/grub/ata.h. + (grub_ata_wait_drq): Likewise. + (grub_ata_pio_read): Likewise. + + * disk/ata_pthru.c: New file. Provides grub_ata_pass_through () + function for hdparm.mod. + + * include/grub/ata.h: New file, contains declarations from + disk/ata.c. + (enum grub_ata_commands): Add new commands for commands/hdparm.c. + + * include/grub/disk.h (grub_disk_ata_pass_through_parms): New struct. + (grub_disk_ata_pass_through): New exported variable. + + * kern/disk.c (grub_disk_ata_pass_through): New variable. + +2009-02-13 Colin D Bennett + + Support multiple fallback entries, and provide an API to support + executing default+fallback menu entries. Renamed the `terminal' menu + viewer to `text'. + + * include/grub/normal.h (grub_normal_text_menu_viewer): New global + variable declaration. + (grub_menu_execute_callback): New structure declaration. + (grub_menu_execute_callback_t): New typedef. + (grub_menu_execute_with_fallback): New function declaration. + (grub_menu_get_entry): Likewise. + (grub_menu_get_timeout): Likewise. + (grub_menu_set_timeout): Likewise. + + * normal/main.c (GRUB_MOD_INIT(normal)): Refer to new variable name. + + * normal/menu.c (grub_wait_after_message): Moved to + `normal/menu_text.c'. + (draw_border): Likewise. + (print_message): Likewise. + (print_entry): Likewise. + (print_entries): Likewise. + (grub_menu_init_page): Likewise. + (get_entry_number): Likewise. + (print_timeout): Likewise. + (run_menu): Likewise. + (grub_menu_execute_entry): Likewise. + (show_text_menu): Likewise. + (get_and_remove_first_entry_number): New function. + (grub_menu_execute_with_fallback): Likewise. + (get_entry): Renamed to ... + (grub_menu_get_entry): .. this and made it global. + (get_timeout): Renamed to ... + (grub_menu_get_timeout): ... this and made it global. + (set_timeout): Renamed to ... + (grub_menu_set_timeout): ... this and made it global. + (grub_normal_terminal_menu_viewer): Renamed to ... + (grub_normal_text_menu_viewer): ... this. + + * normal/menu_text.c: New file. Extracted text-menu-specific code + from normal/menu.c. + + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Add `normal/menu_text.c'. + (normal_mod_SOURCES): Likewise. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + + * conf/i386-pc.rmk, (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + +2009-02-11 Robert Millan + + * util/grub.d/00_header.in: Update old reference to `font' command. + +2009-02-10 Felix Zielcke + + * fs/fat.c (grub_fat_mount): Fix wrong comparison. + + Based on patch from Javier MartĂ­n. + +2009-02-09 Felix Zielcke + + * conf/common.rmk (grub_probe_SOURCES): Move fs/ext2.c before fs/fat.c + to avoid false positives with FAT. + (grub_fstest_SOURCES): Likewise. + * conf/i386-pc.rmk (grub_emu_SOURCES): Likewise. + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Likewise. + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + +2009-02-09 Felix Zielcke + + * fs/fat.c (grub_fat_mount): Try to avoid false positives by checking + bpb.version_specific.fat12_or_fat16.fstype and + bpb.version_specific.fat32.fstype. + +2009-02-08 Robert Millan + + * fs/tar.c: Replace "fs/cpio.c" with "cpio.c". + +2009-02-08 Robert Millan + + * Makefile.in (host_os, host_cpu): New variables. + (target_os): Remove. Update all users. + +2009-02-08 Marco Gerards + + * Makefile.in (enable_grub_emu_usb): New variable. + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `disk/scsi.c'. + (grub_emu_SOURCES) [grub_emu_SOURCES]: Add `disk/usbms.c', + `util/usb.c', `bus/usb/usb.c' and `commands/usbtest.c'. + (grub_emu_LDFLAGS): Add `$(LIBUSB)'. + (pkglib_MODULES): Add `usb.mod', `uhci.mod', `ohci.mod', + `usbtest.mod' and `usbms.mod'. + (usb_mod_SOURCES, usb_mod_CFLAGS, usb_mod_LDFLAGS) + (usbtest_mod_SOURCES, usbtest_mod_CFLAGS, usbtest_mod_LDFLAGS) + (uhci_mod_SOURCES, uhci_mod_CFLAGS, uhci_mod_LDFLAGS, + (ohci_mod_SOURCES, ohci_mod_CFLAGS, ohci_mod_LDFLAGS) + (usbms_mod_SOURCES, usbms_mod_CFLAGS, usbms_mod_LDFLAGS): New + variables. + + * disk/usbms.c: New file. + + * include/grub/usb.h: Likewise. + + * include/grub/usbtrans.h: Likewise. + + * include/grub/usbdesc.h: Likewise. + + * bus/usb/usbtrans.c: Likewise. + + * bus/usb/ohci.c: Likewise. + + * bus/usb/uhci.c: Likewise. + + * bus/usb/usbhub.c: Likewise. + + * bus/usb/usb.c: Likewise. + + * commands/usbtest.c: Likewise. + + * util/usb.c: Likewise. + + * include/grub/err.h (grub_err_t): Add `GRUB_ERR_IO'. + + * configure.ac: Test for libusb presence. + + * util/grub-emu.c (main) [HAVE_LIBUSB_H]: Call `grub_libusb_init'. + +2009-02-08 Vesa Jääskeläinen + + * kern/mm.c: Add more comments. + +2009-02-08 Robert Millan + + Patch from Javier MartĂ­n. + * fs/ext2.c (EXT2_DRIVER_SUPPORTED_INCOMPAT): Add + `EXT4_FEATURE_INCOMPAT_FLEX_BG'. + +2009-02-08 Robert Millan + + * fs/cpio.c: Split tar functionality to ... + * fs/tar.c: ... here (new file). Update all users. + +2009-02-07 Robert Millan + + * fs/ext2.c (grub_ext2_mount): Avoid mounting filesystems with + backward-incompatible features. + + Based on patch from Javier MartĂ­n, with some adjustments. + +2009-02-07 Michael Scherer + + * fs/hfs.c (grub_hfsplus_iterate_dir): Treat hfs+ as case insensitive. + +2009-02-07 Robert Millan + + * conf/common.rmk (grub_probe_SOURCES, grub_fstest_SOURCES): Move + position of `disk/lvm.c' to ensure grub_init_all() always picks it + after the RAID stuff. + +2009-02-05 Vesa Jääskeläinen + + Fixes problem when running vbetest command as reported by + Vladimir Serbinenko . + + * (grub_vbe_set_video_mode): Fixed problem with text modes. + +2009-02-04 Felix Zielcke + + util/getroot.c (grub_util_get_grub_dev): Add support for /dev/mdNpN and + /dev/md/NpN style mdraid devices. + +2009-02-03 Felix Zielcke + + * util/unifont2pff.rb: Remove. + +2009-02-03 Felix Zielcke + + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Add a missing trailing + `#'. + +2009-02-03 Felix Zielcke + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `normal/menu_viewer.c'. + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + +2009-02-02 Christian Franke + + * lib/hexdump.c (hexdump): Print at most 3 lines if data is identical. + +2009-02-01 Felix Zielcke + + * INSTALL: Note that we now require at least autoconf 2.59 and + that LZO is optional. + +2009-02-01 Vesa Jääskeläinen + + Base on patch on bug #24154 created by Tomas Tintera + . + + * video/i386/pc/vbe.c (grub_video_vbe_scroll): Fix downward scrolling. + +2009-02-01 Vesa Jääskeläinen + + Based on patch on bug #25318 created by Bernhard Rosenkraenzer + . + + * normal/parser.y (script_init): Add missing semicolon. + +2009-01-31 Colin D Bennett + + * normal/main.c: Add include to grub/menu_viewer.h. + (free_menu_entry_classes): Added. + (grub_normal_menu_addentry): Added class property handling. + (grub_normal_execute): Changed to use new menu viewer for menu viewing. + (GRUB_MOD_INIT(normal)): Added register for text based menu viewer. + + * normal/menu_viewer.c: New file. + + * normal/menu.c (run_menu_entry): Renamed to ... + (grub_menu_execute_entry): ... this and made it as global. + (grub_menu_run): Renamed to ... + (show_text_menu): ... this and made it local. + (show_text_menu): Adapt to new function names. + (grub_normal_terminal_menu_viewer): New global variable. + + * include/grub/menu.h: New file. + + * include/grub/menu_viewer.h: New file. + + * include/grub/normal.h: Added include to grub/menu.h. + (grub_menu_entry): Moved to include/grub/menu.h. + (grub_menu_entry_t): Likewise. + (grub_menu): Likewise. + (grub_menu_t): Likewise. + (grub_normal_terminal_menu_viewer): Added. + (grub_menu_execute_entry): Likewise. + (grub_menu_run): Removed. + + * DISTLIST: Added include/grub/menu.h. + Added include/grub/menu_viewer.h. + Added normal/menu_viewer.c. + +2009-01-31 Vesa Jääskeläinen + + * normal/execute.c (grub_script_execute_menuentry): Changed to use + arglist for menutitle arguments. + + * normal/main.c (grub_normal_menu_addentry): Likewise. + + * normal/parser.y (menuentry): Likewise. + + * normal/script.c (grub_script_create_cmdmenu): Likewise. + + * include/grub/script.h (grub_script_cmd_menuentry): Likewise. + (grub_script_create_cmdmenu): Likewise. + + * include/grub/normal.h (grub_normal_menu_addentry): Likewise. + + * conf/i386-pc.rmk (normal_mod_SOURCES): Adapt Colin D Bennett's + changes. + + * conf/x86_64-efi.rmk (normal_mod_SOURCES): Likewise. + + * conf/i386-coreboot.rmk (normal_mod_SOURCES): Likewise. + + * conf/i386-efi.rmk (normal_mod_SOURCES): Likewise. + + * conf/i386-ieee1275.rmk (normal_mod_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (normal_mod_SOURCES): Likewise. + + * conf/sparc64-ieee1275.rmk (normal_mod_SOURCES): Likewise. + +2009-01-30 Christian Franke + + * normal/arg.c (grub_arg_show_help): Add indentation if '\n' appears + in option help text. + +2009-01-27 Pavel Roskin + + * disk/fs_uuid.c (search_fs_uuid): Ignore case of the UUID. + +2009-01-27 Vesa Jääskeläinen + + * commands/lsmmap.c: Add include to grub/machine/memory.h. + + * fs/i386/pc/pxe.c (grub_pxefs_open): Fix sign problem. + + * term/i386/pc/at_keyboard.c (GRUB_MOD_FINI(at_keyboard)): Use proper + unregister function. + +2009-01-27 Vesa Jääskeläinen + + * disk/scsi.c (grub_scsi_read): Fix sign problem. + + * term/i386/pc/vga_text.c (grub_vga_text_init_fini). Fix declaration. + + * util/grub-mkfont.c (usage): Fix typo. + + * util/elf/grub-mkimage.c (load_modules): Fix warning. + +2009-01-26 Daniel Mierswa + + * fs/fat.c (grub_fat_uuid): Fix shift of the first two bytes. + + * commands/search.c (search_fs_uuid): Ignore case of the UUID. + + * kern/misc.c (grub_strcasecmp): New function. + (grub_strcasecmp): Use grub_size_t instead of int for length. + Fix return value. + * include/grub/misc.h: Update function prototypes. + +2009-01-26 Robert Millan + + * configure.ac: Fix cross-compilation check. + +2009-01-22 Christian Franke + + * kern/misc.c (grub_vsprintf): Fix size and termination of `format2' + (precision) digit string. Allow `.format2' without `format1' (width). + Limit input chars for `%s' output to `format2' if specified. This is + compatible with standard printf (). + +2009-01-22 Christian Franke + + * disk/ata.c (grub_ata_wait_status): Replace by ... + (grub_ata_wait_not_busy): ... this function. Checks only BSY bit, + other status bits may be invalid while BSY is asserted. + (grub_ata_check_ready): New function. + (grub_ata_cmd): Removed. + (grub_ata_wait_drq): New function. + (grub_ata_strncpy): Remove inline. + (grub_ata_pio_read): Reduce to actual block transfer. BSY wait + and error check now done by grub_ata_wait_drq (). + (grub_ata_pio_write): Likewise. + (grub_atapi_identify): Set DEV before check for !BSY. Use + grub_ata_wait_drq () to wait for data. + (grub_ata_device_initialize): Add status register check to + detect missing SATA slave devices. Add debug messages. + (grub_atapi_wait_drq): Use grub_ata_wait_not_busy (). + (grub_atapi_packet): Set DEV before check for !BSY. Replace + transfer loop by grub_ata_pio_write (). + (grub_ata_identify): Set DEV before check for !BSY. Use + grub_ata_wait_drq () to wait for data. + (grub_ata_setaddress): Set DEV before check for !BSY. + (grub_ata_readwrite): Remove duplicate code, handle batch/rest and + read/write in one loop. Fix invalid command on write. Fix incomplete + command on (size % batch) == 0. Add missing error check after write of + last block. Add debug messages. + (grub_atapi_read): Replace transfer loop by grub_ata_pio_read (). + +2009-01-19 Christian Franke + + * disk/ata.c (GRUB_ATAPI_REG_*): New defines. + (GRUB_ATAPI_IREASON_*): Likewise. + (grub_ata_pio_write): Fix timeout error return. + (grub_atapi_identify): Add grub_ata_wait () after cmd. + (grub_atapi_wait_drq): New function. + (grub_atapi_packet): New parameter `size'. + Use grub_atapi_wait_drq () and direct write instead of + grub_ata_pio_write (). + (grub_atapi_read): Replace grub_ata_pio_read () by a loop which + reads the number of bytes requested by the device for each DRQ + assertion. + (grub_atapi_write): Remove old implementation, return not + implemented instead. + +2009-01-19 Christian Franke + + * disk/scsi.c (grub_scsi_read10): Use scsi->blocksize instead + of 512 to calculate data size. + (grub_scsi_read12): Likewise. + (grub_scsi_write10): Likewise. + (grub_scsi_write12): Likewise. + (grub_scsi_read): Adjust size according to blocksize. + Add checks for invalid blocksize and unaligned transfer. + +2009-01-19 Vesa Jääskeläinen + + * font/font.c (grub_font_loader_init): Re-position unknown glyph. + + * term/gfxterm.c (write_char): Fix background rendering for wide + width glyphs. + +2009-01-19 Robert Millan + + * config.guess: Update to latest version from config git. + * config.sub: Likewise. + +2009-01-17 Felix Zielcke + + * Makefile.in: Change font compilation to use new grub-mkfont instead + of java version. + + * util/fonttool/src/org/gnu/grub/fonttool/BDFLoader.java: Remove. + * util/fonttool/src/org/gnu/grub/fonttool/CharDefs.java: Likewise. + * util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise. + * util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise. + * util/fonttool/src/org/gnu/grub/fonttool/Converter.java: Likewise. + * util/fonttool/src/org/gnu/grub/fonttool/Font.java: Likewise. + * util/fonttool/src/org/gnu/grub/fonttool/Glyph.java: Likewise. + * util/fonttool/src/org/gnu/grub/fonttool/PFF2Sections.java: Likewise. + * util/fonttool/src/org/gnu/grub/fonttool/PFF2Writer.java: Likewise. + +2009-01-16 Christian Franke + + * disk/ata.c (enum grub_ata_commands): Remove EXEC_DEV_DIAGNOSTICS. + (enum grub_ata_timeout_milliseconds): New enum. + (grub_ata_wait_status): Add parameter milliseconds. + (grub_ata_cmd): Remove variable `err'. Remove wait for !DRQ to allow + recovery from timed-out commands. + (grub_ata_pio_read): Add parameter milliseconds. Fix error return, + return grub_errno instead of REG_ERROR. + (grub_ata_pio_write): Add parameter milliseconds. + (grub_atapi_identify): Fix size of ATAPI IDENTIFY sector. + Pass milliseconds to grub_ata_wait_status () and + grub_ata_pio_read (). + (grub_atapi_packet): Pass milliseconds to grub_ata_pio_write (). + (grub_ata_identify): Remove variable `ataerr'. Pass milliseconds to + grub_ata_wait_status (). Fix IDENTIFY timeout check. + (grub_ata_device_initialize): Remove EXECUTE DEVICE DIAGNOSTICS. + It is not suitable for device detection, because DEV bit is ignored, + the command may run too long, and not all devices set the signature + properly. + (grub_ata_pciinit): Clear grub_errno before grub_ata_device_initialize (). + (grub_ata_setaddress): Pass milliseconds to grub_ata_wait_status (). + Fix device selection, DEV bit must be set first to address the registers + of the correct device. + (grub_ata_readwrite): Pass milliseconds to grub_ata_wait_status () and + grub_ata_pio_read/write (). + (grub_atapi_read): Pass milliseconds to grub_ata_pio_read (). + (grub_atapi_write): Pass milliseconds to grub_ata_pio_write (). + +2009-01-13 Carles Pina i Estany + + * util/grub-editenv.c (main): Use fseeko(), not fseek(). + +2009-01-13 Bean + + * util/grub-mkfont.c (write_font): forget to remove some debug code. + +2009-01-13 Bean + + * Makefile.in: (enable_grub_mkfont): New variable. + (freetype_cflags): Likewise. + (freetype_libs): Likewise. + + * common.rmk (bin_UTILITIES): Add `grub-mkfont' if requested. + (grub_mkfont_SOURCES): New variable. + (grub_mkfont_CFLAGS): Likewise. + (grub_mkfont_LDFLAGS): Likewise. + + * configure.ac (--enable-grub-mkfont): New option. Check for freetype2 + library if `--enable-grub-mkfont' is requested. + (enable_grub_mkfont): New variable. + (freetype_cflags): Likewise. + (freetype_libs): Likewise. + + * util/grub-mkfont.c: New file. + +2009-01-12 Christian Franke + + * disk/ata.c (grub_ata_pciinit): Fix bit numbers of compatibility + mode check. Fix setting of compat_use[]. + +2009-01-10 Robert Millan + + Update a few copyright years which we forgot to do in 2008 (only for + files whose changes made in 2008 were copyright-significant) + + * Makefile.in: Add 2008 to Copyright line. + * disk/ieee1275/ofdisk.c: Likewise. + * disk/efi/efidisk.c: Likewise. + * kern/dl.c: Likewise. + * kern/sparc64/ieee1275/init.c: Likewise. + * kern/mm.c: Likewise. + * kern/efi/mm.c: Likewise. + * boot/i386/pc/boot.S: Likewise. + * genfslist.sh: Likewise. + * fs/iso9660.c: Likewise. + * fs/hfs.c: Likewise. + * fs/jfs.c: Likewise. + * fs/minix.c: Likewise. + * fs/ufs.c: Likewise. + * gensymlist.sh.in: Likewise. + * genkernsyms.sh.in: Likewise. + * include/grub/misc.h: Likewise. + * include/grub/types.h: Likewise. + * include/grub/symbol.h: Likewise. + * include/grub/elf.h: Likewise. + * include/grub/kernel.h: Likewise. + * include/grub/disk.h: Likewise. + * include/grub/dl.h: Likewise. + * include/grub/i386/linux.h: Likewise. + * include/grub/i386/pc/biosdisk.h: Likewise. + * include/grub/efi/api.h: Likewise. + * include/grub/efi/pe32.h: Likewise. + * include/grub/util/misc.h: Likewise. + * normal/execute.c: Likewise. + * normal/arg.c: Likewise. + * normal/completion.c: Likewise. + * normal/lexer.c: Likewise. + * normal/parser.y: Likewise. + * normal/misc.c: Likewise. + * commands/i386/pc/vbeinfo.c: Likewise. + * commands/hexdump.c: Likewise. + * commands/terminal.c: Likewise. + * commands/ls.c: Likewise. + * commands/help.c: Likewise. + * partmap/pc.c: Likewise. + * loader/efi/chainloader.c: Likewise. + * loader/multiboot_loader.c: Likewise. + * loader/i386/pc/multiboot2.c: Likewise. + * term/efi/console.c: Likewise. + * term/i386/pc/serial.c: Likewise. + * util/lvm.c: Likewise. + * util/console.c: Likewise. + * util/i386/efi/grub-mkimage.c: Likewise. + * util/raid.c: Likewise. + +2009-01-06 Vesa Jääskeläinen + + * commands/videotest.c: Removed include to grub/machine/memory.h. + + * conf/i386-pc.rmk (pkglib_MODULES): Removed video.mod, gfxterm.mod, + videotest.mod, bitmap.mod, tga.mod, jpeg.mod, png.mod. + (video_mod_SOURCES): Removed. + (video_mod_CFLAGS): Likewise. + (video_mod_LDFLAGS): Likewise. + (gfxterm_mod_SOURCES): Likewise. + (gfxterm_mod_CFLAGS): Likewise. + (gfxterm_mod_LDFLAGS): Likewise. + (videotest_mod_SOURCES): Likewise. + (videotest_mod_CFLAGS): Likewise. + (videotest_mod_LDFLAGS): Likewise. + (bitmap_mod_SOURCES): Likewise. + (bitmap_mod_CFLAGS): Likewise. + (bitmap_mod_LDFLAGS): Likewise. + (tga_mod_SOURCES): Likewise. + (tga_mod_CFLAGS): Likewise. + (tga_mod_LDFLAGS): Likewise. + (jpeg_mod_SOURCES): Likewise. + (jpeg_mod_CFLAGS): Likewise. + (jpeg_mod_LDFLAGS): Likewise. + (png_mod_SOURCES): Likewise. + (png_mod_CFLAGS): Likewise. + (png_mod_LDFLAGS): Likewise. + + * conf/common.rmk (pkglib_MODULES): Added video.mod, videotest.mod, + bitmap.mod, tga.mod, jpeg.mod, png.mod, font.mod, gfxterm.mod + (video_mod_SOURCES): Added. + (video_mod_CFLAGS): Likewise. + (video_mod_LDFLAGS): Likewise. + (videotest_mod_SOURCES): Likewise. + (videotest_mod_CFLAGS): Likewise. + (videotest_mod_LDFLAGS): Likewise. + (bitmap_mod_SOURCES): Likewise. + (bitmap_mod_CFLAGS): Likewise. + (bitmap_mod_LDFLAGS): Likewise. + (tga_mod_SOURCES): Likewise. + (tga_mod_CFLAGS): Likewise. + (tga_mod_LDFLAGS): Likewise. + (jpeg_mod_SOURCES): Likewise. + (jpeg_mod_CFLAGS): Likewise. + (jpeg_mod_LDFLAGS): Likewise. + (png_mod_SOURCES): Likewise. + (png_mod_CFLAGS): Likewise. + (png_mod_LDFLAGS): Likewise. + (gfxterm_mod_SOURCES): Likewise. + (gfxterm_mod_CFLAGS): Likewise. + (gfxterm_mod_LDFLAGS): Likewise. + + * term/gfxterm.c: Removed include to grub/machine/memory.h, + grub/machine/console.h. + +2009-01-04 Jerone Young + + Make on screen instructions clearer + + Based on patch created by Jidanni + + * normal/menu.c: print clearer instructions on the screen + +2009-01-02 Colin D Bennett + + New font engine. + + Additional changes by Vesa Jääskeläinen to adapt to + build system and fixed gfxterm.c to work with different sized fonts. + + * configure.ac: Changed UNIFONT_HEX to UNIFONT_BDF. + + * configure: Re-generated. + + * DISTLIST: Removed font/manager.c. + Added font/font.c. + Added font/font_cmd.c. + + * Makefile.in: Changed UNIFONT_HEX to UNIFONT_BDF. Added Font tool + compilation. + + * include/grub/misc.h (grub_utf8_to_ucs4): Changed prototype. Changed users. + + * kern/misc.c (grub_utf8_to_ucs4): Changed prototype. + + * kern/term.c: Changed users of grub_utf8_to_ucs4. + + * normal/menu.c: Likewise. + + * conf/common.rmk (font_mod_SOURCES): Removed font/manager.c. + (font_mod_SOURCES): Added font/font_cmd.c, font/font.c. + + * include/grub/font.h: Replaced with new file. + + * include/grub/video.h (GRUB_VIDEO_MODE_TYPE_ALPHA): Changed value. + (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED): Likewise. + (GRUB_VIDEO_MODE_TYPE_COLOR_MASK): Likewise. + (GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP): Added. + (grub_video_blit_format): Added GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED. + (grub_video_mode_info): Added bg_red, bg_green, bg_blue, bg_alpha, + fg_red, fg_green, fg_blue, fg_alpha. + (grub_video_adapter): Removed blit_glyph. + (grub_video_blit_glyph): Removed. + + * font/manager.c: Removed file. + + * font/font.c: New file. + + * font/font_cmd.c: Likewise. + + * video/video.c (grub_video_blit_glyph): Removed. + + * video/i386/pc/vbe.c (grub_video_vbe_map_rgb): Added 1-bit support. + (grub_video_vbe_map_rgba): Likewise. + (grub_video_vbe_unmap_color_int): Likewise. + (grub_video_vbe_blit_glyph): Removed. + (grub_video_vbe_adapter): Removed blit_glyph. + + * video/i386/pc/vbeutil.c (get_data_ptr): Added 1-bit support. + (get_pixel): Likewise. + (set_pixel): Likewise. + + * commands/videotest.c (grub_cmd_videotest): Added more tests for fonts. + + * term/gfxterm.c: Adapted to new font engine. + + * term/i386/pc/vesafb.c: Marked as deprecated. Made it compile. + + * term/i386/pc/vga.c: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/BDFLoader.java: New file. + + * util/fonttool/src/org/gnu/grub/fonttool/CharDefs.java: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/Converter.java: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/Font.java: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/Glyph.java: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/PFF2Sections.java: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/PFF2Writer.java: Likewise. + + * util/grub.d/00_header.in: Changed to use new loadfont command. + + * util/grub-mkconfig_lib.in: Changed font extension. + +2008-12-28 Felix Zielcke + + * util/getroot.c (grub_util_get_grub_dev): Add support for + /dev/md/dNNpNN style partitionable mdraid devices. + +2008-12-12 Alex Smith + + * fs/i386/pc/pxe.c (grub_pxefs_open): Handle the one open connection + at a time limit of the PXE TFTP API correctly. + (grub_pxefs_close): Likewise. + +2008-11-29 Robert Millan + + * disk/ata.c (grub_ata_pciinit): Handle errors raised by + grub_ata_device_initialize() calls. + +2008-11-28 Krzysztof Smiechowicz + + * fs/affs.c (grub_affs_iterate_dir): Return failure when directory + iteration failed. + * fs/sfs.c (grub_sfs_iterate_dir): Likewise. + +2008-11-28 Robert Millan + + Fix build on powerpc-ieee1275. Based on patch created by + Manoel Abranches . + * conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): Add + `kern/ieee1275/mmap.c'. + * include/grub/powerpc/ieee1275/memory.h: New file. + + Provide grub-install on coreboot. + * conf/i386-coreboot.rmk (sbin_SCRIPTS): Add `grub-install'. + (grub_install_SOURCES): New variable. + * util/i386/pc/grub-install.in: Add a few condition checks to make it + usable on coreboot. + +2008-11-25 Felix Zielcke + + * util/grub-fstest.c (grub_term_get_current_input): Change return type + to `grub_term_input_t'. + (grub_term_get_current_output): Change return type to + `grub_term_output_t'. + +2008-11-22 Robert Millan + + Fix breakage on coreboot due to declaration mismatch. + * term/i386/pc/vga_text.c (grub_vga_text_init_fini): New function. + (grub_vga_text_term): Use grub_vga_text_init_fini() instead of + grub_vga_text_cls(). + + * kern/i386/loader.S (grub_multiboot_backward_relocator): Improve + comments. Avoid copying one more byte than necessary (just in case). + + * conf/powerpc-ieee1275.rmk (kernel_elf_LDFLAGS): Change link address + to 0x200000 (avoids trouble with some OFW implementations, and matches + with the one in Yaboot). + Reported by Manoel Abranches + +2008-11-20 Robert Millan + + * kern/i386/coreboot/init.c (grub_time_tics): Remove variable. + (grub_get_rtc, grub_exit): Abort with grub_fatal() if called. + + * util/grub-mkconfig_lib.in (grub_warn): New function. + (convert_system_path_to_grub_path): Use grub_warn() when issuing + warnings, to obtain consistent formatting. + * util/grub.d/00_header.in: Likewise. + * util/update-grub_lib.in: Likewise. + + * loader/i386/linux.c (allocate_pages): Fix a warning. + Move comment text to `#error' stanza. + + Harmonize ieee1275's grub_available_iterate() with the generic + grub_machine_mmap_iterate() interface (fixes a recently-introduced + build problem on i386-ieee1275): + * kern/ieee1275/openfw.c (grub_available_iterate): Moved from here ... + * kern/ieee1275/mmap.c (grub_machine_mmap_iterate): ... here. Add third + parameter `type'. Update all users of this function. + * conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Add + `kern/ieee1275/mmap.c'. + * kern/ieee1275/init.c + * include/grub/ieee1275/ieee1275.h (grub_available_iterate): Replace + with ... + (grub_machine_mmap_iterate): ... this. + * include/grub/i386/pc/memory.h (grub_machine_mmap_iterate): Change + return type to `grub_err_t'. Update all implementations of this + function prototype. + * include/grub/i386/coreboot/memory.h (grub_machine_mmap_iterate): + Likewise. + + Add `lsmmap' command (lists firmware-provided memory map): + * commands/lsmmap.c: New file. + * conf/i386-pc.rmk (pkglib_MODULES): Add `lsmmap.mod'. + (lsmmap_mod_SOURCES, lsmmap_mod_CFLAGS, lsmmap_mod_LDFLAGS): New + variables. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/i386-coreboot.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + +2008-11-19 Robert Millan + + * loader/i386/pc/linux.c (grub_rescue_cmd_initrd): Fix a typo. + * loader/i386/linux.c (grub_rescue_cmd_initrd): Implement a few needed + constraints to initrd allocation (based on code from + loader/i386/pc/linux.c). Without them, initrd was allocated too high + for Linux to find it. + +2008-11-14 Robert Millan + + * fs/cpio.c (grub_cpio_open): Compare `name' and `fn' by hand in + order to cope with duplicate slashes. + +2008-11-14 Robert Millan + + * include/grub/i386/coreboot/memory.h (GRUB_MEMORY_MACHINE_LOWER_SIZE): + Redefine to match with GRUB_MEMORY_MACHINE_UPPER_START (0x100000). We + don't want to mess with lower memory, because it is used in the Linux + loader. + + * loader/i386/linux.c (allocate_pages): Allocate `real_mode_mem' in + an appropriate place in lower memory, between 0x10000 and 0x90000, + like loader/i386/efi/linux.c does. Linux often panics if real_mode_mem + is in our heap (probably as a result of it being corrupted during + decompression). Add #error instance with comment to explain why this + loader isn't currently usable on PC/BIOS. + +2008-11-14 Robert Millan + + * term/i386/pc/serial.c [! GRUB_MACHINE_PCBIOS] + (GRUB_SERIAL_PORT_NUM): Fix miscalculation. + +2008-11-12 Robert Millan + + Make loader/i386/linux.c buildable on i386-pc (although disabled). + + * include/grub/i386/pc/init.h: Include `'. + (struct grub_machine_mmap_entry, grub_machine_mmap_iterate): Move + from here ... + * include/grub/i386/pc/memory.h: ... to here. + +2008-11-12 Robert Millan + + Fix build problems on i386-ieee1275 and *-efi (introduced by vga_text + split). + + * include/grub/i386/pc/console.h: Include `'. + (grub_console_cur_color, grub_console_real_putchar) + (grub_console_putchar, grub_console_getcharwidth, grub_console_getwh) + (grub_console_setcolorstate, grub_console_setcolor) + (grub_console_getcolor): Move from here ... + * include/grub/i386/vga_common.h: ... to here (new file). + + * term/i386/pc/vga_text.c: Replace `' with + `' and `' with + `'. + * term/i386/vga_common.c: Replace `' with + `'. + +2008-11-12 Robert Millan + + * conf/i386-pc.rmk (kernel_img_SOURCES): Add `term/i386/vga_common.c'. + * conf/i386.rmk (pkglib_MODULES): Add `vga_text.mod'. + (vga_text_mod_SOURCES, vga_text_mod_CFLAGS, vga_text_mod_LDFLAGS): New + variables. + * conf/i386-coreboot.rmk (kernel_elf_SOURCES): Replace + `term/i386/pc/console.c' with `term/i386/vga_common.c'. + + * kern/i386/coreboot/init.c (grub_machine_init): Replace call to + grub_console_init() with call to grub_vga_text_init(). + (grub_machine_fini): Replace call to + grub_console_fini() with call to grub_vga_text_fini() and + grub_at_keyboard_fini(). + + * include/grub/i386/pc/console.h: Include `'. + (grub_console_putchar, grub_console_getcharwidth, grub_console_getwh) + (grub_console_setcolorstate, grub_console_setcolor) + (grub_console_getcolor): New function prototypes. + + * term/i386/pc/vga_text.c: Include `'. + (grub_vga_text_getxy, grub_vga_text_gotoxy, grub_vga_text_cls) + (grub_vga_text_setcursor): Static-ize. + (grub_vga_text_term): New structure. + (GRUB_MOD_INIT(vga_text), GRUB_MOD_FINI(vga_text)): New functions. + + * term/i386/pc/console.c: Remove `'. + (grub_console_cur_color, grub_console_standard_color) + (grub_console_normal_color, grub_console_highlight_color) + (map_char, grub_console_putchar, grub_console_getcharwidth) + (grub_console_getwh, grub_console_setcolorstate, grub_console_setcolor) + (grub_console_getcolor): Move from here ... + * term/i386/vga_common.c: ... to here (same function names). + +2008-11-12 Robert Millan + + Use newly-added Multiboot support in coreboot. + + * conf/i386-coreboot.rmk (kernel_elf_SOURCES): Replace + `kern/i386/coreboot/mmap.c' with `kern/i386/multiboot_mmap.c'. + + * kern/i386/coreboot/startup.S: Enable Multiboot header, fix its + alignment, set `MULTIBOOT_MEMORY_INFO' flag. + (codestart): Store the MBI in `startup_multiboot_info' when we're + being loaded using Multiboot. + + * kern/i386/coreboot/init.c (grub_machine_init): Move + grub_at_keyboard_init() call to beginning of function (useful for + debugging). Call grub_machine_mmap_init() before attempting to use + grub_machine_mmap_iterate(). + (grub_lower_mem, grub_upper_mem): Move from here ... + * kern/i386/multiboot_mmap.c (grub_lower_mem, grub_upper_mem): ... to + here (new file). + + * include/grub/i386/coreboot/memory.h (grub_machine_mmap_init): New + function prototype. + +2008-11-12 Robert Millan + + Fix a regression introduced by the at_keyboard.mod split. Because + some terminals are default on some platforms and non-default on + others, the first terminal being registered determines which is + going to be default. + + * kern/term.c (grub_term_register_input): If this is the first + terminal being registered, set it as the current one. + (grub_term_register_output): Likewise. + + * term/efi/console.c (grub_console_init): Do not call + grub_term_set_current_output() or grub_term_set_current_input(). + * term/ieee1275/ofconsole.c (grub_console_init): Likewise. + * term/i386/pc/console.c (grub_console_init): Likewise. + (grub_console_fini): Do not call grub_term_set_current_input() + (but leave grub_term_set_current_output() to restore text mode). + +2008-11-10 Robert Millan + + * util/grub.d/00_header.in: Add backward compatibility check for + versions of terminal.mod that don't understand `terminal_input' or + `terminal_output'. + +2008-11-09 Robert Millan + + * commands/terminal.c (GRUB_MOD_FINI(terminal)): Unregister + `terminal_input' / `terminal_output', not `terminal'. + +2008-11-08 Robert Millan + + * Makefile.in (include_DATA): Fix srcdir=. assumption. + (DISTCLEANFILES): Add `build_env.mk'. + +2008-11-08 Robert Millan + + * term/i386/pc/vesafb.c (grub_vesafb_term): Change type to + `struct grub_term_output'. Remove `.checkkey' and `.getkey' + members. Update all users. + * util/console.c (grub_ncurses_term): Split in ... + (grub_ncurses_term_input): ... this, and ... + (grub_ncurses_term_output): ... this. Update all users. + * term/ieee1275/ofconsole.c: Remove stale `#endif'. + +2008-11-08 Robert Millan + + * Makefile.in (PKGLIB): Add $(pkglib_BUILDDIR). + (PKGDATA): Add $(pkgdata_SRCDIR). + (pkglib_BUILDDIR): New variable. + (pkgdata_SRCDIR): New variable. + (build_env.mk): New target. + (include_DATA): New variable. + (install-local): Install $(include_DATA) files in $(includedir). + +2008-11-07 Pavel Roskin + + * gendistlist.sh: Use C locale for sorting to ensure consistent + output on all systems. + + * util/grub.d/00_header.in: Remove incorrect space before + "serial". + +2008-11-07 Robert Millan + + * include/multiboot2.h (struct multiboot_header): Add `flags' member as + per specification. + * loader/multiboot2.c (grub_multiboot2): Fix Multiboot2 header check. + * loader/multiboot_loader.c (find_multi_boot2_header): New function + (based on find_multi_boot1_header). + (grub_rescue_cmd_multiboot_loader): Check for Multiboot2 header, + using find_multi_boot2_header(), and abort if neither Multiboot or + Multiboot headers were found. + +2008-11-07 Robert Millan + + Modularize at_keyboard.mod: + + * conf/i386.rmk (pkglib_MODULES): Add `at_keyboard.mod'. + (at_keyboard_mod_SOURCES, at_keyboard_mod_CFLAGS) + (at_keyboard_mod_LDFLAGS): New variables. + + Actual terminal split: + + * include/grub/term.h (struct grub_term): Split in ... + (struct grub_term_input): ... this, and ... + (struct grub_term_output): ... this. Update all users. + (grub_term_set_current): Split in ... + (grub_term_set_current_input): ... this, and ... + (grub_term_set_current_output): ... this. + (grub_term_get_current): Split in ... + (grub_term_get_current_input): ... this, and ... + (grub_term_get_current_output): ... this. + (grub_term_register): Split in ... + (grub_term_register_input): ... this, and ... + (grub_term_register_output): ... this. + (grub_term_unregister): Split in ... + (grub_term_unregister_input): ... this, and ... + (grub_term_unregister_output): ... this. + (grub_term_iterate): Split in ... + (grub_term_iterate_input): ... this, and ... + (grub_term_iterate_output): ... this. + + * kern/term.c (grub_term_list): Split in ... + (grub_term_list_input): ... this, and ... + (grub_term_list_output): ... this. Update all users. + (grub_cur_term): Split in ... + (grub_cur_term_input): ... this, and ... + (grub_cur_term_output): ... this. Update all users. + (grub_term_set_current): Split in ... + (grub_term_set_current_input): ... this, and ... + (grub_term_set_current_output): ... this. + (grub_term_get_current): Split in ... + (grub_term_get_current_input): ... this, and ... + (grub_term_get_current_output): ... this. + (grub_term_register): Split in ... + (grub_term_register_input): ... this, and ... + (grub_term_register_output): ... this. + (grub_term_unregister): Split in ... + (grub_term_unregister_input): ... this, and ... + (grub_term_unregister_output): ... this. + (grub_term_iterate): Split in ... + (grub_term_iterate_input): ... this, and ... + (grub_term_iterate_output): ... this. + + * kern/misc.c (grub_abort): Split use of grub_term_get_current() into + a check for input and one for output (and only attempt to get keys + from user when input works). + + * util/grub-probe.c (grub_term_get_current): Split in ... + (grub_term_get_current_input): ... this, and ... + (grub_term_get_current_output): ... this. + * util/grub-fstest.c: Likewise. + * util/i386/pc/grub-setup.c: Likewise. + * util/grub-editenv.c: Likewise. + + Portability adjustments: + + * conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Remove + `term/i386/pc/at_keyboard.c'. + * kern/ieee1275/init.c [__i386__] (grub_machine_init): Remove call to + grub_keyboard_controller_init() (now handled by terminal .init). + * kern/i386/coreboot/init.c (grub_machine_init): Add call to + grub_at_keyboard_init(). + * include/grub/i386/ieee1275/console.h (grub_keyboard_controller_init) + (grub_console_checkkey, grub_console_getkey): Remove (now provided by + at_keyboard.mod via input terminal interface). + * include/grub/i386/coreboot/console.h: Convert into a stub for + `'. + + Migrate full terminals to new API: + + * term/efi/console.c (grub_console_term): Split into ... + (grub_console_term_input): ... this, and ... + (grub_console_term_output): ... this. Update all users. + * term/ieee1275/ofconsole.c: Remove __i386__ hack. + (grub_ofconsole_init): Split into ... + (grub_ofconsole_init_input): ... this, and ... + (grub_ofconsole_init_output): ... this. + (grub_ofconsole_term): Split into ... + (grub_ofconsole_term_input): ... this, and ... + (grub_ofconsole_term_output): ... this. Update all users. + * term/i386/pc/serial.c (grub_serial_term): Split into ... + (grub_serial_term_input): ... this, and ... + (grub_serial_term_output): ... this. Update all users. + * term/i386/pc/console.c (grub_console_term): Split into ... + (grub_console_term_input): ... this, and ... + (grub_console_term_output): ... this. Update all users. + (grub_console_term_input): Only enable it on PC/BIOS platform. + (grub_console_init): Remove grub_keyboard_controller_init() call. + + Migrate input terminals to new API: + + * term/i386/pc/at_keyboard.c: Replace `cpu' and `machine' with + `i386' and `i386/pc' to enable build on x86_64 (this driver is + i386-specific anyway). + (grub_console_checkkey): Rename to ... + (grub_at_keyboard_checkkey): ... this. Static-ize. Update all + users. + (grub_keyboard_controller_orig): New variable. + (grub_console_getkey): Rename to ... + (grub_at_keyboard_getkey): ... this. Static-ize. Update all + users. + (grub_keyboard_controller_init): Static-ize. Save original + controller value so that it can be restored ... + (grub_keyboard_controller_fini): ... here (new function). + (grub_at_keyboard_term): New structure. + (GRUB_MOD_INIT(at_keyboard), GRUB_MOD_FINI(at_keyboard)): New + functions. + + Migrate output terminals to new API: + + * term/i386/pc/vga.c (grub_vga_term): Change type to + `struct grub_term_output'. Remove `.checkkey' and `.getkey' + members. Update all users. + * term/gfxterm.c (grub_video_term): Change type to + `struct grub_term_output'. Remove `.checkkey' and `.getkey' + members. Update all users. + * include/grub/i386/pc/console.h (grub_console_checkkey) + (grub_console_getkey): Do not export (no longer needed by gfxterm, + etc). + + Migrate `terminal' command and userland tools to new API: + + * commands/terminal.c (grub_cmd_terminal): Split into ... + (grub_cmd_terminal_input): ... this, and ... + (grub_cmd_terminal_output): ... this. + (GRUB_MOD_INIT(terminal)): Split `terminal' command in two commands: + `terminal_input' and `terminal_output'. + * util/grub.d/00_header.in: Adjust `terminal' calls to new + `terminal_input' / `terminal_output' API. + * util/grub-mkconfig.in: Export ${GRUB_TERMINAL_INPUT} and + ${GRUB_TERMINAL_OUTPUT} instead of ${GRUB_TERMINAL} (and if user + provided ${GRUB_TERMINAL}, convert it). + +2008-11-04 Robert Millan + + * util/grub.d/10_freebsd.in: New file. Generate grub configuration + for FreeBSD. + * conf/common.rmk (grub-mkconfig_SCRIPTS): Add 10_freebsd. + +2008-11-03 Bean + + * kern/elf.c (grub_elf32_load): Revert to previous code. + (grub_elf64_load): Likewise. + + * loader/i386/bsd.c (grub_bsd_elf32_hook): Change return address. + +2008-11-01 Robert Millan + + * Makefile.in (CPPFLAGS): Fix builddir=. assumption. + (TARGET_CPPFLAGS): Likewise. + * genmk.rb (mod_src): Fix builddir=. and srcdir=. assumptions. + +2008-11-01 Carles Pina i Estany + + * normal/menu.c (run_menu): Add Previous and Next Page keys in menu. + +2008-10-29 Guillem Jover + + * disk/lvm.c (grub_lvm_scan_device): Fix error recovery by delaying the + addition of objects until the code is not going to be able to fail. + +2008-10-29 Guillem Jover + + * disk/lvm.c (grub_lvm_scan_device): Fix possible NULL value handling + (add a missing NULL check, and correct them by moving the pointer + operations after the actual check). + +2008-10-29 Robert Millan + + * util/i386/pc/grub-install.in: Handle empty string as output from + make_system_path_relative_to_its_root(). + +2008-10-05 Hans Lambermont + + * disk/lvm.c (grub_lvm_scan_device): Allocate buffer space for the + circular metadata worst case scenario. If the metadata is circular + then copy the wrap in place. + * include/grub/lvm.h: Add GRUB_LVM_MDA_HEADER_SIZE, from the LVM2 + project lib/format_text/layout.h + Circular metadata bug found and patch debugged by Jan Derk Gerlings. + +2008-10-03 Felix Zielcke + + * util/i386/pc/grub-install.in: Source grub-mkconfig_lib instead of update-grub_lib. + +2008-10-03 Felix Zielcke + + * util/update-grub_lib.in: Mention filename in warning message. + +2008-09-29 Felix Zielcke + + * NEWS: Update for rename of update-grub to grub-mkconfig. + +2008-09-29 Felix Zielcke + + * util/update-grub_lib.in: Copy to ... + * util/grub-mkconfig_lib.in: ... this. Update all users. + * util/update-grub_lib.in: Make it a stub to `grub-mkconfig_lib.in'. + * util/update-grub.in: Rename to ... + * util/grub-mkconfig.in: ... this. Update all users. Remove `-y' + option. Add `--output' option to allow users to specify the generated + configuration file. Default to stdout. + (update_grub_dir): Rename to ... + (grub_mkconfig_dir): ... this. + (grub_cfg): Default to an empty string. + * conf/common.rmk (update-grub): Rename to ... + (grub-mkconfig): ... this. + (update-grub_lib): Copy to ... + (grub-mkconfig_lib): ... this. + (update-grub_SCRIPTS): Copy to ... + (grub-mkconfig_SCRIPTS): ... this. Update all users. + (update-grub_DATA): Rename to ... + (grub-mkconfig_DATA): ... this. + +2008-09-28 Robert Millan + + * fs/iso9660.c (struct grub_iso9660_primary_voldesc): Rename `created' + to `modified'. Add the real `created' field. + (grub_iso9660_uuid): Use `modified' rather than `created' for + constructing the UUID. + +2008-09-28 Felix Zielcke + + fs/jfs.c (grub_jfs_find_file): Treat multiple slashes like one. + Based on code from Tomas Ebenlendr . + +2008-09-28 Bean + + * fs/ntfs.c (grub_ntfs_iterate_dir): Fix a bug in the previous patch. + Thanks to Christian Franke for finding this bug. + +2008-09-25 Robert Millan + + * util/grub-mkdevicemap.c (make_device_map): Actually replace all + instances of grub_util_get_disk_name() (see previous commit). + +2008-09-25 Robert Millan + + * conf/i386-pc.rmk (grub_mkdevicemap_SOURCES): Remove + `util/i386/get_disk_name.c'. + * conf/i386-efi.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * conf/i386-coreboot.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/powerpc-ieee1275.rmk (grub_mkdevicemap_SOURCES): Remove + `util/ieee1275/get_disk_name.c'. + * include/grub/util/misc.h (grub_util_get_disk_name): Remove. + * util/ieee1275/get_disk_name.c: Remove file. + * util/i386/get_disk_name.c: Remove file. + * util/grub-mkdevicemap.c (make_device_map): Back to hardcoding + "hd%d" for device.map entries, rather than using + grub_util_get_disk_name(). + +2008-09-24 Carles Pina i Estany + + * disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Fix `unused parameter' + warning. + * commands/i386/pc/pxecmd.c (dmraid_nvidia): Likewise. + +2008-09-24 Carles Pina i Estany + + * include/grub/i386/pc/console.h (GRUB_TERM_NPAGE): + Changed to 0x5100. + (GRUB_TERM_PPAGE): Changed to 0x4900. + +2008-09-24 Robert Millan + + * include/grub/powerpc/ieee1275/console.h (GRUB_CONSOLE_KEY_*): Remove + macros (they were i386-pc specific). + * include/grub/sparc64/ieee1275/console.h: Likewise. + * include/grub/efi/console.h: Likewise. + +2008-09-22 Bean + + * fs/ntfs.c (grub_ntfs_iterate_dir): Fix a rare case where $BITMAP is + resident and in attribute list. + + * include/grub/ntfs.h (BMP_LEN): Removed. + +2008-09-22 Bean + + * disk/ata.c (grub_atapi_open): Initialize devfnd, no need to set + scsi->name and scsi->luns, as they will be set in grub_scsi_open. + + * disk/scsi.c (grub_scsi_open): Don't call p->close (scsi) here when + error occurs, as grub_disk_open will call grub_disk_close, which will + call p->close (scsi). + +2008-09-21 Felix Zielcke + + * configure.ac (AC_INIT): Quote `GRUB' string and version number. + (AC_PREREQ): Bumped to 2.59. + (AC_TRY_COMPILE): Replace obsolete macro with ... + (AC_COMPILE_IFELSE): ... this. + * aclocal.m4 (AC_TRY_LINK): Replace obsolete macro with ... + (AC_LINK_IFELSE): ... this. + +2008-09-21 Felix Zielcke + + * autogen.sh: Add a call to `gendistlist.sh'. + +2008-09-19 Christian Franke + + * aclocal.m4 (grub_CHECK_ENABLE_EXECUTE_STACK): New function. + * configure.ac: Call grub_CHECK_ENABLE_EXECUTE_STACK. + * include/grub/misc.h [NEED_ENABLE_EXECUTE_STACK]: + Export __enable_execute_stack() to modules. + * kern/misc.c [NEED_ENABLE_EXECUTE_STACK] (__enable_execute_stack): + New function. + +2008-09-09 Felix Zielcke + + * Makefile.in (RMKFILES): Add `i386.rmk' and `x86_64-efi.rmk'. + Sort the list. + +2008-09-09 Felix Zielcke + + * util/hostdisk.c: Replace #include with + #include . + +2008-09-08 Robert Millan + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Skip + segments when their filesz is zero (grub_file_read() interprets + zero-size as "read until EOF", which results in memory corruption). + Use `lowest_segment' rather than 0 for calculating the current + segment load address. + +2008-09-08 Robert Millan + + * util/hostdisk.c (open_device): Replace a grub_util_info() call + with grub_dprintf("hostdisk", ...), as it was so verbose that it + clobbered useful information. + +2008-09-08 Robert Millan + + * include/grub/util/biosdisk.h: Move to ... + * include/grub/util/hostdisk.h: ... here. Update all users. + * util/biosdisk.c: Move to ... + * util/hostdisk.c: ... here. Update all users. + +2008-09-07 Robert Millan + + * loader/i386/pc/multiboot.c (mmap_addr, mmap_length): Remove + variables. + (grub_multiboot): Move `mbi' allocation upwards, so that mmap address + and length can be stored directly in the `mbi->mmap_addr' and + `mbi->mmap_length' struct fields. + +2008-09-07 Robert Millan + + * conf/i386.rmk: New file. Provides declaration for building + `cpuid.mod'. + * conf/i386-pc.rmk (pkglib_MODULES): Remove `cpuid.mod'. + (cpuid_mod_SOURCES, cpuid_mod_CFLAGS, cpuid_mod_LDFLAGS): Remove + variables. + Include `conf/i386.mk'. + * conf/i386-efi.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * conf/i386-coreboot.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + +2008-09-07 Vesa Jääskeläinen + + Based on patch created by Colin D Bennett . + Adds optimization support for BGR based modes. + + * include/grub/i386/pc/vbeblit.h (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8) Removed. + (grub_video_i386_vbeblit_R8G8B8X8_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8A8): Likewise. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8A8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8): Likewise. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8): Likewise. + (grub_video_i386_vbeblit_index_index): Likewise. + (grub_video_i386_vbeblit_replace_directN): Added. + (grub_video_i386_vbeblit_replace_BGRX8888_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_BGRX8888_RGB888): Likewise. + (grub_video_i386_vbeblit_replace_BGR888_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_BGR888_RGB888): Likewise. + (grub_video_i386_vbeblit_replace_RGBX8888_RGB888): Likewise. + (grub_video_i386_vbeblit_replace_RGB888_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_index_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_index_RGB888): Likewise. + (grub_video_i386_vbeblit_blend_BGRA8888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_BGR888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_RGBA8888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_RGB888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_index_RGBA8888): Likewise. + + * include/grub/i386/pc/vbefill.h (grub_video_i386_vbefill_R8G8B8A8) Removed. + (grub_video_i386_vbefill_R8G8B8): Likewise. + (grub_video_i386_vbefill_index): Likewise. + (grub_video_i386_vbefill_direct32): Added. + (grub_video_i386_vbefill_direct24): Likewise. + (grub_video_i386_vbefill_direct16): Likewise. + (grub_video_i386_vbefill_direct8): Likewise. + + * include/grub/video.h (grub_video_blit_format): Removed + GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8, GRUB_VIDEO_BLIT_FORMAT_R8G8B8. + (grub_video_blit_format): Added GRUB_VIDEO_BLIT_FORMAT_RGBA_8888, + GRUB_VIDEO_BLIT_FORMAT_BGRA_8888, GRUB_VIDEO_BLIT_FORMAT_RGB_888, + GRUB_VIDEO_BLIT_FORMAT_BGR_888, GRUB_VIDEO_BLIT_FORMAT_RGB_565, + GRUB_VIDEO_BLIT_FORMAT_BGR_565. + + * video/video.c (grub_video_get_blit_format): Updated to use new + blit formats. Added handling for 16 bit color modes. + + * video/i386/pc/vbe.c (grub_video_vbe_fill_rect): Updated to use new + fillers. + (common_blitter): Updated to use new blitters. + + * video/i386/pc/vbeblit.c (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8): + Removed. + (grub_video_i386_vbeblit_R8G8B8X8_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8A8): Likewise. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8A8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8): Likewise. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8): Likewise. + (grub_video_i386_vbeblit_index_index): Likewise. + (grub_video_i386_vbeblit_replace_directN): Added. + (grub_video_i386_vbeblit_replace_BGRX8888_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_BGRX8888_RGB888): Likewise. + (grub_video_i386_vbeblit_replace_BGR888_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_BGR888_RGB888): Likewise. + (grub_video_i386_vbeblit_replace_RGBX8888_RGB888): Likewise. + (grub_video_i386_vbeblit_replace_RGB888_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_index_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_index_RGB888): Likewise. + (grub_video_i386_vbeblit_blend_BGRA8888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_BGR888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_RGBA8888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_RGB888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_index_RGBA8888): Likewise. + + * video/i386/pc/vbefill.c (grub_video_i386_vbefill_R8G8B8A8): Removed. + (grub_video_i386_vbefill_R8G8B8): Likewise. + (grub_video_i386_vbefill_index): Likewise. + (grub_video_i386_vbefill_direct32): Added. + (grub_video_i386_vbefill_direct24): Likewise. + (grub_video_i386_vbefill_direct16): Likewise. + (grub_video_i386_vbefill_direct8): Likewise. + + * video/readers/jpeg.c (grub_jpeg_decode_sos): Adapt to new blitter + types. + + * video/readers/tga.c (grub_video_reader_tga): Adapt to new blitter + types. + + * video/readers/png.c (grub_png_decode_image_header): Adapt to new + blitter types. + + * video/bitmap.c (grub_video_bitmap_create): Adapt to new blitter + types. + +2008-09-06 Felix Zielcke + + * disk/raid.c (insert_array): Set `array->chunk_size' to 64 for + RAID level 1. + +2008-09-06 Felix Zielcke + + * fs/iso9660.c (grub_iso9660_date): New structure. + (grub_iso9660_primary_voldesc): Add `grub_iso9660_date' member. + (grub_iso9660_uuid): New function. + +2008-09-05 Bean + + * fs/fshelp.c (grub_fshelp_find_file): Handle case insensitive names. + + * fs/ntfs.c (list_file): Ignore names in DOS namespace, set the case + insensitive bit for names in Win32 and Win32 & DOS namespace. + + * include/grub/fshelp.h (GRUB_FSHELP_CASE_INSENSITIVE): New macro. + + * include/grub/types.h (LONG_MAX): Likewise. + +2008-09-04 Felix Zielcke + + * util/getroot.c: Include . + (grub_util_get_grub_dev): Rewrite to use asprintf for mdraid devices, + add support for /dev/md/N devices and handle LVM double dash escaping. + +2008-09-04 Felix Zielcke + + * config.guess: Update to latest version from config git. + * config.sub: Likewise. + +2008-09-03 Robert Millan + + * disk/scsi.c (grub_scsi_open): Remove size limit when printing + `disk->total_sectors'. + +2008-09-01 Colin D Bennett + + * include/grub/normal.h: Fixed incorrect comment for + GRUB_COMMAND_FLAG_NO_ARG_PARSE. + +2008-09-01 Colin D Bennett + + * commands/i386/pc/vbeinfo.c (grub_cmd_vbeinfo): Replaced constant + values with defines. + + * include/grub/i386/pc/vbe.h (GRUB_VBE_MODEATTR_SUPPORTED): Added. + (GRUB_VBE_MODEATTR_RESERVED_1): Likewise. + (GRUB_VBE_MODEATTR_BIOS_TTY_OUTPUT_SUPPORT): Likewise. + (GRUB_VBE_MODEATTR_COLOR): Likewise. + (GRUB_VBE_MODEATTR_GRAPHICS): Likewise. + (GRUB_VBE_MODEATTR_VGA_COMPATIBLE): Likewise. + (GRUB_VBE_MODEATTR_VGA_WINDOWED_AVAIL): Likewise. + (GRUB_VBE_MODEATTR_LFB_AVAIL): Likewise. + (GRUB_VBE_MODEATTR_DOUBLE_SCAN_AVAIL): Likewise. + (GRUB_VBE_MODEATTR_INTERLACED_AVAIL): Likewise. + (GRUB_VBE_MODEATTR_TRIPLE_BUF_AVAIL): Likewise. + (GRUB_VBE_MODEATTR_STEREO_AVAIL): Likewise. + (GRUB_VBE_MODEATTR_DUAL_DISPLAY_START): Likewise. + (GRUB_VBE_MEMORY_MODEL_TEXT): Likewise. + (GRUB_VBE_MEMORY_MODEL_CGA): Likewise. + (GRUB_VBE_MEMORY_MODEL_HERCULES): Likewise. + (GRUB_VBE_MEMORY_MODEL_PLANAR): Likewise. + (GRUB_VBE_MEMORY_MODEL_NONCHAIN4_256): Likewise. + (GRUB_VBE_MEMORY_MODEL_YUV): Likewise. + +2008-08-31 Robert Millan + + * loader/i386/pc/multiboot.c (grub_get_multiboot_mmap_len): Fix + declaration. + (grub_multiboot): Fix a few warnings. + +2008-08-31 Robert Millan + + * loader/i386/pc/multiboot.c: Update comment not to say that + boot_device support is unimplemented. + +2008-08-31 Robert Millan + + * loader/i386/pc/multiboot.c: Update comment not to say that a.out + or memory map support are unimplemented. + +2008-08-31 Colin D Bennett + + * util/i386/pc/grub-mkrescue.in: Support multiple overlay directories. + +2008-08-31 Colin D Bennett + + * commands/i386/pc/vbeinfo.c (grub_cmd_vbeinfo): Show VBE version and + total video memory in 'vbeinfo' output; show color format details for + each video mode. + +2008-08-30 Pavel Roskin + + * util/genmoddep.c: Remove for real this time. + * DISTLIST: Remove util/genmoddep.c. + +2008-08-30 Robert Millan + + * kern/i386/pc/startup.S (multiboot_header): Force 4-byte alignment + as required by Multiboot spec (it was already 4-byte aligned, but + only by chance). + +2008-08-29 Pavel Roskin + + * kern/powerpc/ieee1275/crt0.S: Rename to ... + * kern/powerpc/ieee1275/startup.S: ... this. + * conf/powerpc-ieee1275.rmk: Adjust for the above. + * DISTLIST: Likewise. + + * kern/powerpc/ieee1275/crt0.S: Include grub/symbol.h and + grub/cpu/kernel.h. Add start label for consistency with other + platforms. Add grub_prefix immediately after start. Add jump + to the code after grub_prefix. + * include/grub/powerpc/kernel.h: Provide valid values for + GRUB_KERNEL_CPU_PREFIX and GRUB_KERNEL_CPU_DATA_END. + +2008-08-29 Bean + + * configure.ac: Change host_os to cygwin for mingw. + (asprintf): New check for function. + + * include/grub/symbol.h: Replace #ifndef __CYGWIN__ with + #if ! defined (__CYGWIN__) && ! defined (__MINGW32__). + + * include/grub/util/misc.h: #include and , + declare asprintf if HAVE_ASPRINTF is not set, declare fseeko, ftello, + sync, sleep and grub_util_get_disk_size for mingw. + + * util/biosdisk.c (grub_util_biosdisk_open): Use grub_util_get_disk_size + to get size in mingw. + (open_device): Use flag O_BINARY if it's defined. + (find_root_device): Add dummy code for mingw. + + * util/grub-mkdevicemap.c (get_floppy_disk_name): Return 0 for mingw. + (get_ide_disk_name): Return //./PHYSICALDRIVE%d for mingw. + (get_scsi_disk_name): Return 0 for mingw. + + * util/hostfs.c: #include . + (grub_hostfs_open): Use "rb" flag to open file, use + grub_util_get_disk_size to get disk size for mingw. + + * util/misc.c: #include and in mingw. + (asprintf): New function if HAVE_ASPRINTF is not set. + (sync): New function for mingw. + (sleep): Likewise. + (grub_util_get_disk_size): Likewise. + +2008-08-28 Pavel Roskin + + * conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): Add + kern/time.c. + +2008-08-28 Robert Millan + + * util/biosdisk.c (find_grub_drive): Declare missing `i' variable. + +2008-08-28 Robert Millan + + Change find_grub_drive() syntax so it doesn't prevent it from + detecting NULL names as errors. + + * util/biosdisk.c (find_grub_drive): Move free slot search code + from here ... + (find_free_slot): ... to here. + (read_device_map): Use find_free_slot() to search for free slots. + +2008-08-27 Marco Gerards + + * conf/common.rmk (pkglib_MODULES): Add scsi.mod. + (scsi_mod_SOURCES): New variable. + (scsi_mod_CFLAGS): Likewise + (scsi_mod_LDFLAGS): Likewise. + + * disk/scsi.c: New file. + + * include/grub/scsi.h: Likewise. + + * include/grub/scsicmd.h: Likewise. + + * disk/ata.c: Include . + (grub_atapi_packet): Do not use grub_ata_cmd, use registers + instead. + (grub_ata_iterate): Skip ATAPI devices. + (grub_ata_open): Only handle ATAPI devices. + (struct grub_atapi_read): Removed. + (grub_atapi_readsector): Likewise. + (grub_ata_read): No longer handle ATAPI devices. + (grub_ata_write): Likewise. + (grub_atapi_iterate): New function. + (grub_atapi_read): Likewise. + (grub_atapi_write): Likewise. + (grub_atapi_open): Likewise. + (grub_atapi_close): Likewise. + (grub_atapi_dev): New variable. + (GRUB_MOD_INIT(ata)): Register ATAPI as SCSI device. + (GRUB_MOD_FINI(ata)): Unregister ATAPI. + + * include/grub/disk.h (enum grub_disk_dev_id): Add + `GRUB_DISK_DEVICE_SCSI_ID'. + +2008-08-26 Robert Millan + + * util/biosdisk.c (grub_util_biosdisk_open, open_device) + (grub_util_biosdisk_get_grub_dev): Make error messages a bit more + descriptive. + +2008-08-23 Bean + + * conf/common.rmk (grub_probe_SOURCES): Add disk/mdraid_linux.c. + (grub_fstest_SOURCES): Add disk/raid5_recover.c, disk/raid6_recover.c, + disk/mdraid_linux.c and disk/dmraid_nvidia.c and lib/crc.c. + (pkglib_MODULES): Add raid5rec.mod, raid6rec.mod, mdraid.mod and + dm_nv.mod. + (raid5rec_mod_SOURCES): New macro. + (raid5rec_mod_CFLAGS): Likewise. + (raid5rec_mod_LDFLAGS): Likewise. + (raid6rec_mod_SOURCES): Likewise. + (raid6rec_mod_CFLAGS): Likewise. + (raid6rec_mod_LDFLAGS): Likewise. + (mdraid_mod_SOURCES): Likewise. + (mdraid_mod_CFLAGS): Likewise. + (mdraid_mod_LDFLAGS): Likewise. + (dm_nv_mod_SOURCES): Likewise. + (dm_nv_mod_CFLAGS): Likewise. + (dm_nv_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add disk/mdraid_linux.c. + (grub_emu_SOURCES): Add disk/raid5_recover.c, disk/raid6_recover.c, + disk/mdraid_linux.c and disk/dmraid_nvidia.c. + + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Add disk/raid5_recover.c, + disk/raid6_recover.c, disk/mdraid_linux.c and disk/dmraid_nvidia.c. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * disk/raid5_recover.c: New file. + + * disk/raid6_recover.c: Likewise. + + * disk/mdraid_linux.c: Likewise. + + * disk/dmraid_nvidia.c: Likewise. + + * disk/i386/pc/biosdisk.c: Set total_sectors of cdrom device to + ULONG_MAX. + + * disk/raid.c (grub_raid_open): Use the size of the smallest disk to + calculate the size of raid device. + (grub_raid_read): Simplify raid0 code. Support raid4, raid6 and four + different layout of raid5. + (grub_raid_scan_device): Remove code specific to mdraid. + (grub_raid_list): New variable. + (free_array): New function. + (grub_raid_register): Likewise. + (grub_raid_unregister): Likewise. + (grub_raid_rescan): Likewise. + (GRUB_MOD_INIT): Don't iterate device here. + (GRUB_MOD_FINI): Use free_array to release resource. + + * include/grub/raid.h: Remove macro and structure specific to mdraid. + (grub_raid5_recover_func_t): New function variable type. + (grub_raid6_recover_func_t): Likewise. + (grub_raid5_recover_func): New variable. + (grub_raid6_recover_func): Likewise. + (grub_raid_register): New function. + (grub_raid_unregister): Likewise. + (grub_raid_rescan): Likewise. + (grub_raid_block_xor): Likewise. + + * util/grub-fstest.c: Add #include and . + (CMD_CRC): New macro. + (part): Removed. + (read_file): Handle device as well as file. + (cmd_crc): New function. + (fstest): Handle multiple disks. + (options): Remove part, raw and long, add root and diskcount. + (usage): Add crc, remove -p, -r, -l, add -r and -c. + (main): Find the first non option entry and ignore subsequent options, + add handling for the new options, support multiple disks. + + * util/grub-probe.c (probe): Add mdraid to abstraction_name. + +2008-08-23 Bean + + * normal/x86_64/setjmp.S (grub_longjmp): Return 1 when val = 0. + + * genfslist.sh: Ignore kernel.mod. + + * genpartmaplist.sh: Likewise. + +2008-08-23 Robert Millan + + * util/getroot.c (find_root_device): Skip anything that starts with + a dot, not just directories. This avoids things like /dev/.tmp.md0. + +2008-08-22 Felix Zielcke + + * util/update-grub.in (GRUB_GFXMODE): Export variable. + * util/grub.d/00_header.in: Allow the administrator to change default + gfxmode via ${GRUB_GFXMODE}. + +2008-08-21 Felix Zielcke + + * fs/ntfs.c (grub_ntfs_mount): Fix a memory leak. + +2008-08-21 Robert Millan + + * loader/i386/linux.c: New file. Implements generic 32-bit Linux + loader. + * conf/i386-coreboot.rmk (_linux_mod_SOURCES): Replace + `loader/i386/pc/linux.c' with `loader/i386/linux.c'. + +2008-08-20 Carles Pina i Estany + + * menu/normal.c (run_menu): Replace hardcoded numbers with macros + (16 for GRUB_TERM_UP and 14 for GRUB_TERM_DOWN) + +2008-08-19 Robert Millan + + * term/gfxterm.c (DEFAULT_CURSOR_COLOR): Remove. + (struct grub_virtual_screen): Remove `cursor_color'. + (grub_virtual_screen_setup): Remove `virtual_screen.cursor_color' + initialization. + (write_cursor): Use `virtual_screen.fg_color' to draw cursor. + +2008-08-18 Robert Millan + + Unify (identical) linux_normal.c files. + * loader/i386/efi/linux_normal.c: Move from here ... + * loader/linux_normal.c: ... to here. Update all users. + * loader/i386/pc/linux_normal.c: Delete. Update all users. + * loader/i386/ieee1275/linux_normal.c: Likewise. + +2008-08-18 Robert Millan + + * include/grub/i386/linux.h (LINUX_LOADER_ID_LILO) + (LINUX_LOADER_ID_LOADLIN, LINUX_LOADER_ID_BOOTSECT) + (LINUX_LOADER_ID_SYSLINUX, LINUX_LOADER_ID_ETHERBOOT) + (LINUX_LOADER_ID_ELILO, LINUX_LOADER_ID_GRUB, LINUX_LOADER_ID_UBOOT) + (LINUX_LOADER_ID_XEN, LINUX_LOADER_ID_GUJIN, LINUX_LOADER_ID_QEMU): + New macros. + (GRUB_LINUX_CL_OFFSET, GRUB_LINUX_CL_END_OFFSET): Move from here ... + * loader/i386/pc/linux.c (GRUB_LINUX_CL_OFFSET) + (GRUB_LINUX_CL_END_OFFSET): ... to here. + * loader/i386/efi/linux.c (GRUB_EFI_CL_OFFSET): Rename to ... + (GRUB_LINUX_CL_OFFSET): ... this. Update all users. + (GRUB_EFI_CL_END_OFFSET): Rename to ... + (GRUB_LINUX_CL_END_OFFSET): ... this. Update all users. + (grub_rescue_cmd_linux): Macroify `type_of_loader' initialization. + Initialize `params->video_cursor_x' and `params->video_cursor_y' + portably using grub_getxy(). + Replace `-EFI' with `-bzImage' in boot message. + +2008-08-17 Robert Millan + + * include/grub/x86_64/kernel.h: New file ( stub). + +2008-08-17 Robert Millan + + * conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/i386/pc/mmap.c'. + + * include/grub/i386/pc/init.h (GRUB_MACHINE_MEMORY_AVAILABLE) + (GRUB_MACHINE_MEMORY_RESERVED): New macros. + (grub_machine_mmap_iterate): New function declaration. + * include/grub/multiboot.h (struct grub_multiboot_mmap_entry): New + structure. + (GRUB_MMAP_MEMORY_AVAILABLE, GRUB_MMAP_MEMORY_RESERVED): New + macros. + + * kern/i386/pc/init.c (grub_machine_init): Replace hardcoded region + type check value with `GRUB_MACHINE_MEMORY_AVAILABLE'. + Move e820 parsing from here ... + * kern/i386/pc/mmap.c: New file. + (grub_machine_mmap_iterate): ... to here. + + * include/grub/i386/coreboot/memory.h: Remove `'. + (GRUB_LINUXBIOS_MEMORY_AVAILABLE): Rename (for consistency) to ... + (GRUB_MACHINE_MEMORY_AVAILABLE): ... this. Update all users. + (grub_available_iterate): Redeclare to return `void', and redeclare + its hook to use grub_uint64_t as addr and size parameters, and rename + to ... + (grub_machine_mmap_iterate): ... this. Update all users. + + * kern/i386/coreboot/mmap.c (grub_mmap_iterate): Simplify parser loop + to make it more readable. Rename to ... + (grub_machine_mmap_iterate): ... this. + + * loader/i386/pc/multiboot.c (mmap_addr, mmap_length): New variables. + (grub_get_multiboot_mmap_len, grub_fill_multiboot_mmap): New functions. + (grub_multiboot): Allocate an extra region after the payload, and fill + it with a Multiboot memory map. Adjust a.out loader to calculate size + with the extra space. + (grub_multiboot_load_elf32): Adjust elf32 loader to calculate size + with the extra space. + +2008-08-17 Carles Pina i Estany + + * menu/normal.c (run_menu): Add Home and End keys in grub-menu. + +2008-08-17 Felix Zielcke + + * gendistlist.sh: Add *.y, *.tex, *.texi, grub.cfg, README, *.sc, + mdate-sh to the list `find' searches for. + * DISTLIST: Regenerated. + +2008-08-16 Felix Zielcke + + * gendistlist.sh (EXTRA_DISTFILES): Remove gensymlist.sh, + genkernsyms.sh. Add geninit.sh, geninitheader.sh, genkernsyms.sh.in, + genmoddep.awk, gensymlist.sh.in. + (DISTDIRS): Add bus, docs, hook, lib. + * DISTLIST: Regenerated. + * NEWS: Add cygwin support and change the `os-prober' entry a bit. + +2008-08-16 Robert Millan + + * disk/raid.c (grub_raid_init): Handle/report errors set by + grub_device_iterate(). + * disk/lvm.c (grub_lvm_init): Likewise. + +2008-08-15 Bean + + * conf/i386-pc.rmk (pkglib_MODULES): Add datetime.mod, date.mod + and datehook.mod. + (datetime_mod_SOURCES): New macro. + (datetime_mod_CFLAGS): Likewise. + (datetime_mod_LDFLAGS): Likewise. + (date_mod_SOURCES): Likewise. + (date_mod_CFLAGS): Likewise. + (date_mod_LDFLAGS): Likewise. + (datehook_mod_SOURCES): Likewise. + (datehook_mod_CFLAGS): Likewise. + (datehook_mod_LDFLAGS): Likewise. + + * conf/i386-coreboot.rmk (pkglib_MODULES): Add datetime.mod, date.mod + and datehook.mod. + (datetime_mod_SOURCES): New macro. + (datetime_mod_CFLAGS): Likewise. + (datetime_mod_LDFLAGS): Likewise. + (date_mod_SOURCES): Likewise. + (date_mod_CFLAGS): Likewise. + (date_mod_LDFLAGS): Likewise. + (datehook_mod_SOURCES): Likewise. + (datehook_mod_CFLAGS): Likewise. + (datehook_mod_LDFLAGS): Likewise. + + * conf/i386-ieee1275.rmk (pkglib_MODULES): Add datetime.mod, date.mod + and datehook.mod. + (datetime_mod_SOURCES): New macro. + (datetime_mod_CFLAGS): Likewise. + (datetime_mod_LDFLAGS): Likewise. + (date_mod_SOURCES): Likewise. + (date_mod_CFLAGS): Likewise. + (date_mod_LDFLAGS): Likewise. + (datehook_mod_SOURCES): Likewise. + (datehook_mod_CFLAGS): Likewise. + (datehook_mod_LDFLAGS): Likewise. + + * conf/i386-efi.rmk (pkglib_MODULES): Add datetime.mod, date.mod + and datehook.mod. + (datetime_mod_SOURCES): New macro. + (datetime_mod_CFLAGS): Likewise. + (datetime_mod_LDFLAGS): Likewise. + (date_mod_SOURCES): Likewise. + (date_mod_CFLAGS): Likewise. + (date_mod_LDFLAGS): Likewise. + (datehook_mod_SOURCES): Likewise. + (datehook_mod_CFLAGS): Likewise. + (datehook_mod_LDFLAGS): Likewise. + + * conf/x86_64-efi.rmk (pkglib_MODULES): Add datetime.mod, date.mod + and datehook.mod. + (datetime_mod_SOURCES): New macro. + (datetime_mod_CFLAGS): Likewise. + (datetime_mod_LDFLAGS): Likewise. + (date_mod_SOURCES): Likewise. + (date_mod_CFLAGS): Likewise. + (date_mod_LDFLAGS): Likewise. + (datehook_mod_SOURCES): Likewise. + (datehook_mod_CFLAGS): Likewise. + (datehook_mod_LDFLAGS): Likewise. + + * kern/env.c (grub_env_insert): Fix a bug in prevp pointer. + + * commands/date.c: New file. + + * hook/datehook.c: Likewise. + + * include/grub/lib/datetime.h: Likewise. + + * include/grub/i386/cmos.h: Likewise. + + * lib/datetime.c: Likewise. + + * lib/i386/datetime.c: Likewise. + + * lib/efi/datetime.c: Likewise. + +2008-08-14 Robert Millan + + * conf/common.rmk (bin_UTILITIES): Add `grub-mkelfimage'. + (grub_mkelfimage_SOURCES): New variable. + (util/elf/grub-mkimage.c_DEPENDENCIES): Likewise. + + * conf/i386-coreboot.rmk (bin_UTILITIES, grub_mkimage_SOURCES) + (grub_mkimage_LDFLAGS, util/elf/grub-mkimage.c_DEPENDENCIES): Remove. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + + * kern/ieee1275/init.c: Include `'. + * kern/i386/coreboot/init.c: Likewise. + + * kern/i386/ieee1275/startup.S: Replace `' + with `'. + (GRUB_KERNEL_MACHINE_PREFIX, GRUB_KERNEL_MACHINE_DATA_END): Renamed + to ... + (GRUB_KERNEL_CPU_PREFIX, GRUB_KERNEL_CPU_DATA_END): ... this. + * kern/i386/coreboot/startup.S: Likewise. + + * include/grub/powerpc/ieee1275/kernel.h (GRUB_MOD_ALIGN) + (GRUB_MOD_GAP): Remove. + * include/grub/powerpc/kernel.h: New file. + * include/grub/i386/ieee1275/kernel.h (GRUB_KERNEL_MACHINE_PREFIX) + (GRUB_KERNEL_MACHINE_DATA_END): Remove. + * include/grub/i386/kernel.h: New file. + * include/grub/i386/coreboot/kernel.h (GRUB_MOD_ALIGN) + (GRUB_MOD_GAP, GRUB_KERNEL_MACHINE_PREFIX) + (GRUB_KERNEL_MACHINE_DATA_END): Remove. + + * util/ieee1275/grub-install.in (grub_mkimage): Initialize to use + `grub-mkelfimage'. + Use --directory when invoking grub_mkimage. + + * util/elf/grub-mkimage.c: Include `'. + (add_segments): Replace GRUB_KERNEL_MACHINE_DATA_END and + GRUB_KERNEL_MACHINE_PREFIX with GRUB_KERNEL_CPU_DATA_END + and GRUB_KERNEL_CPU_PREFIX. + +2008-08-14 Felix Zielcke + + * include/grub/err.h (grub_err_printf): New function prototype. + * util/misc.c (grub_err_printf): New function. + * kern/misc.c [! GRUB_UTIL] (grub_err_printf): New alias for + grub_printf. + * kern/err.c (grub_print_error): Use grub_err_printf. + +2008-08-13 Robert Millan + + * docs/grub.cfg: Remove `/dev/' prefix in GNU/Hurd boot entry. + +2008-08-13 Robert Millan + + * docs/grub.cfg: Use the native device name for the example GNU/Hurd + boot entry. + +2008-08-12 Robert Millan + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Move part + of the relocation code from here ... + (grub_multiboot): ... to here. + (forward_relocator, backward_relocator): Move from here ... + * kern/i386/loader.S (grub_multiboot_forward_relocator) + (grub_multiboot_backward_relocator): ... to here. + (grub_multiboot_real_boot): Use %edx for entry offset. Put Multiboot + magic in %eax. Use %ebp for jumping (so %edx is not trashed). + * include/grub/i386/loader.h (grub_multiboot_forward_relocator) + (grub_multiboot_forward_relocator_end) + (grub_multiboot_backward_relocator) + (grub_multiboot_backward_relocator_end): New variables. + +2008-08-12 Bean + + * disk/raid.c (grub_raid_read): Fix a bug in raid0 code. + +2008-08-11 Robert Millan + + * kern/i386/linuxbios/startup.S: Move from here ... + * kern/i386/coreboot/startup.S: ... to here. + + * kern/i386/linuxbios/init.c: Move from here ... + * kern/i386/coreboot/init.c: ... to here. + + * kern/i386/linuxbios/table.c: Move from here ... + * kern/i386/coreboot/mmap.c: ... to here. + + * conf/i386-coreboot.rmk (kernel_elf_SOURCES): Update moved files. + +2008-08-11 Robert Millan + + * kern/device.c (grub_device_open): Do not handle grub_disk_open() + errors. Leave it to the upper layer to handle them. + +2008-08-09 Christian Franke + + * Makefile.in: Add `target_os' and `enable_grub_pe2elf'. + * conf/common.rmk: Install `grub-pe2elf' only if requested. + Install `grub.d/10_windows' only on Cygwin. + * configure.ac: Add subst of `target_os'. + Check `target_os' also before setting TARGET_OBJ2ELF. + Add `--enable-grub-pe2elf'. + +2008-08-08 Robert Millan + + * kern/disk.c: Replace `' with `'. + (grub_last_time): Change type to grub_uint64_t. + (grub_disk_open): Migrate code from to using grub_get_time_ms(). + (grub_disk_close): Likewise. + + * normal/menu.c: Replace `' with `'. + (run_menu): Migrate code from to using grub_get_time_ms(). + + * util/misc.c (grub_get_time_ms): New function. + +2008-08-08 Marco Gerards + + * disk/ata.c (grub_ata_regget): Change return type to + `grub_uint8_t'. + (grub_ata_regget2): Likewise. + (grub_ata_wait_status): New function. + (grub_ata_wait_busy): Removed function, updated all users to use + `grub_ata_wait_status'. + (grub_ata_wait_drq): Likewise. + (grub_ata_cmd): New function. + (grub_ata_pio_read): Change return type to `grub_uint8_t'. Add + error handling. + (grub_ata_pio_write): Add error handling. + (grub_atapi_identify): Likewise. + (grub_atapi_packet): Use `grub_ata_cmd' and improve error + handling. + (grub_ata_identify): Use `grub_ata_cmd' and improve error + handling. Actually use the detected registers. Reorder the + detection logic such that it is easier to read. + (grub_ata_pciinit): Do not assign the same ID to each controller. + (grub_ata_setaddress): Use `grub_ata_cmd' and improve error + handling. + (grub_atapi_readsector): Check the result of `grub_ata_pio_read'. + + * include/grub/err.h (grub_err_t): Add `GRUB_ERR_TIMEOUT'. + +2008-08-08 Marco Gerards + + * NEWS: Update. + +2008-08-07 Bean + + * include/grub/x86_64/pci.h: New file. + +2008-08-07 Christian Franke + + * kern/i386/pit.c (TIMER2_SPEAKER): New define. + (TIMER2_GATE): Likewise. + (grub_pit_wait): Add enable/disable of the timer2 gate + bit of port 0x61. This fixes a possible infinite loop. + +2008-08-07 Bean + + * conf/x86_64-efi.rmk (kernel_mod_SOURCES): Add kern/time.c, + kern/i386/tsc.c and kern/i386/pit.c. + + * include/grub/i386/tsc.h (grub_cpu_is_cpuid_supported): Handle + x86_64 platform. + + * kern/i386/efi/init.c: Replace with + . + + * kern/i386/pit.c: Replace with . + +2008-08-07 Bean + + * conf/i386-efi.rmk (kernel_mod_SOURCES): Add kern/time.c. + + * conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Add kern/time.c, + + * include/grub/i386/pit.h: Use macro KERNEL_CPU_PIT_HEADER to avoid + multiple inclusion. Add #include . + +2008-08-06 Christian Franke + + * conf/common.rmk: Build and install `10_windows'. + * util/grub.d/10_windows.in: New script. + +2008-08-06 Pavel Roskin + + * kern/i386/pit.c: Include `'. + +2008-08-06 Robert Millan + + * conf/i386-coreboot.rmk (kernel_elf_ASFLAGS): New variable. + * kern/i386/tsc.c: Include `'. + +2008-08-06 Bean + + * fs/i386/pc/pxe.c (grub_pxe_data): New member block_size. + (grub_pxefs_fs_int): Remove dummy definition. + (grub_pxefs_open): Use data->block_size to store the current block + size setting. + (grub_pxefs_read): Use block size stored in data->block_size. As the + value of grub_pxe_blksize can be changed after the file is opened. + +2008-08-06 Bean + + * fs/i386/pc/pxe.c (curr_file): new variable. + (grub_pxefs_open): Simply the handling of pxe file system. Don't + require the dummy internal file system anymore. + (grub_pxefs_read): Removed. + (grub_pxefs_close): Likewise. + (grub_pxefs_fs_int): Likewise. + (grub_pxefs_read_int): Renamed to grub_pxefs_read. Reinitialize tftp + connection when we switch file. + (grub_pxefs_close_int): Renamed to grub_pxefs_close. + +2008-08-06 Robert Millan + + * conf/i386-coreboot.rmk (pkglib_MODULES): Add `reboot.mod' and + `halt.mod'. + (reboot_mod_SOURCES, reboot_mod_CFLAGS, reboot_mod_LDFLAGS) + (halt_mod_SOURCES, halt_mod_CFLAGS, halt_mod_LDFLAGS): New variables. + + * kern/i386/halt.c: New file. + * kern/i386/reboot.c: Likewise. + * include/grub/i386/reboot.h: Likewise. + * include/grub/i386/halt.h: Likewise. + + * commands/halt.c [! GRUB_MACHINE_IEEE1275 ! GRUB_MACHINE_EFI]: + Include `'. + * commands/reboot.c [! GRUB_MACHINE_IEEE1275 ! GRUB_MACHINE_EFI] + [! GRUB_MACHINE_PCBIOS]: Include `'. + + * term/i386/pc/at_keyboard.c: Include `'. + (SHIFT_L, SHIFT_R, CTRL, ALT, CAPS_LOCK, KEYBOARD_REG_DATA) + (KEYBOARD_REG_STATUS, KEYBOARD_COMMAND_ISREADY, KEYBOARD_COMMAND_READ) + (KEYBOARD_COMMAND_WRITE, KEYBOARD_COMMAND_REBOOT) + (KEYBOARD_SCANCODE_SET1, KEYBOARD_ISMAKE, KEYBOARD_ISREADY) + (KEYBOARD_SCANCODE, OLPC_UP, OLPC_DOWN, OLPC_LEFT, OLPC_RIGHT): Move + from here ... + * include/grub/i386/at_keyboard.h: ... to here. + +2008-08-05 Robert Millan + + * conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/i386/pit.c'. + * conf/i386-efi.rmk (kernel_mod_SOURCES): Likewise. + * conf/i386-coreboot.rmk (kernel_elf_SOURCES): Likewise. Also add + `kern/i386/tsc.c', `kern/generic/rtc_get_time_ms.c' and + `kern/generic/millisleep.c'. + + * kern/i386/tsc.c (calibrate_tsc): Rewrite using grub_pit_wait() + instead of grub_get_rtc(). + (grub_tsc_init): Initialize `tsc_boot_time'. + + * kern/i386/linuxbios/init.c (grub_millisleep): Remove stub. + (grub_machine_init): Use grub_tsc_init() rather than + installing an RTC-based handler via grub_install_get_time_ms(). + + * kern/i386/pit.c: New file. + * include/grub/i386/pit.h: Likewise. + +2008-08-05 Bean + + * boot/i386/pc/pxeboot.S (_start): Use drive number 0x7F for pxe. + + * conf/i386-pc.rmk (kernel_img_HEADERS): Add machine/pxe.h. + (pkglib_MODULES): Add pxe.mod and pxecmd.mod. + (pxe_mod_SOURCES): New macro. + (pxe_mod_CFLAGS): Likewise. + (pxe_mod_LDFLAGS): Likewise. + (pxecmd_mod_SOURCES): Likewise. + (pxecmd_mod_CFLAGS): Likewise. + (pxecmd_mod_LDFLAGS): Likewise. + + * kern/i386/pc/startup.S (grub_pxe_scan): New function. + (grub_pxe_call): Likewise. + + * include/grub/disk.h (grub_disk_dev_id): Add GRUB_DISK_DEVICE_PXE_ID. + + * commands/i386/pc/pxecmd.c: New file. + + * fs/i386/pc/pxe.c: Likewise. + + * include/grub/i386/pc/pxe.h: Likewise. + +2008-08-05 Bean + + * util/console.c (grub_console_cur_color): New variable. + (grub_console_standard_color): Likewise. + (grub_console_normal_color): Likewise. + (grub_console_highlight_color): Likewise. + (color_map): Likewise. + (use_color): Likewise. + (NUM_COLORS): New macro. + (grub_ncurses_setcolorstate): Handle color properly. + (grub_ncurses_setcolor): Don't change color here, just remember the + settings, color will be set in grub_ncurses_setcolorstate. + (grub_ncurses_getcolor): New function. + (grub_ncurses_init): Initialize color pairs. + (grub_ncurses_term): New member grub_ncurses_getcolor. + +2008-08-05 Colin D Bennett + + High resolution timer support. Implemented for x86 CPUs using TSC. + Extracted generic grub_millisleep() so it's linked in only as needed. + This requires a Pentium compatible CPU; if the RDTSC instruction is + not supported, then it falls back on the generic grub_get_time_ms() + implementation that uses the machine's RTC. + + * conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/time.c', + `kern/i386/tsc.c', `kern/generic/rtc_get_time_ms.c' and + `kern/generic/millisleep.c'. + + * conf/i386-efi.rmk (kernel_mod_SOURCES): Add `kern/i386/tsc.c', + `kern/generic/rtc_get_time_ms.c' and `kern/generic/millisleep.c'. + + * conf/x86_64-efi.rml (kernel_mod_SOURCES): Add + `kern/generic/millisleep.c' and `kern/generic/rtc_get_time_ms.c'. + + * conf/sparc64-ieee1275.rmk (kernel_elf_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): Add + `kern/generic/millisleep.c'. + + * conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Likewise. + + * conf/i386-coreboot.rmk (kernel_elf_SOURCES): Add `kern/time.c'. + + * kern/generic/rtc_get_time_ms.c: New file. + + * kern/generic/millisleep.c: New file. + + * kern/misc.c: Don't include + anymore. + (grub_millisleep_generic): Removed. + + * commands/sleep.c (grub_interruptible_millisleep): Uses + grub_get_time_ms() instead of grub_get_rtc(). + + * include/grub/i386/tsc.h (grub_get_tsc): New file. New inline + function. + (grub_cpu_is_cpuid_supported): New inline function. + (grub_cpu_is_tsc_supported): New inline function. + (grub_tsc_init): New function prototype. + (grub_tsc_get_time_ms): New function prototype. + + * kern/i386/tsc.c (grub_get_time_ms): New file. + + * include/grub/time.h: Include . Don't include + anymore. + (grub_millisleep): Removed. + (grub_machine_init): Call grub_tsc_init. + + * kern/i386/linuxbios/init.c (grub_machine_init): Install the RTC + get_time_ms() implementation. + + * kern/sparc64/ieee1275/init.c (grub_millisleep): Removed. + (ieee1275_get_time_ms): New function. + (grub_machine_init): Install get_time_ms() implementation. + + * kern/i386/pc/init.c: Include . + (grub_machine_init): Call grub_tsc_init(). + (grub_millisleep): Removed. + + * kern/ieee1275/init.c (grub_millisleep): Removed. + (grub_machine_init): Install ieee1275_get_time_ms() + implementation. + (ieee1275_get_time_ms): New function. + (grub_get_rtc): Now calls ieee1275_get_time_ms(), which does the + real work. + +2008-08-05 Marco Gerards + + * disk/ata.c: Include . + (enum grub_ata_commands): Add `GRUB_ATA_CMD_EXEC_DEV_DIAGNOSTICS'. + (grub_ata_initialize): Rewritten. + (grub_ata_device_initialize): New function. + +2008-08-04 Pavel Roskin + + * kern/main.c: Include grub/mm.h. + +2008-08-04 Robert Millan + + * conf/i386-coreboot.rmk (COMMON_ASFLAGS, COMMON_CFLAGS) + (COMMON_LDFLAGS): Harmonize with i386-pc version (fixes a code + corruption problem). + +2008-08-04 Robert Millan + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Fix misc + warnings introduced in my last commit. + +2008-08-03 Robert Millan + + Make PCI available on all i386 architectures. + + * include/grub/i386/pc/pci.h: Move from here ... + * include/grub/i386/pci.h: ... to here. + + * include/grub/i386/pc/pci.h: Remove. + * include/grub/i386/efi/pci.h: Remove. + * include/grub/x86_64/efi/pci.h: Remove. + + * include/grub/pci.h: Replace `' with + `'. + + * conf/i386-coreboot.rmk (pkglib_MODULES): Add `pci' and `lspci'. + (pci_mod_SOURCES, pci_mod_CFLAGS, pci_mod_LDFLAGS, lspci_mod_SOURCES) + (lspci_mod_CFLAGS, lspci_mod_LDFLAGS): New variables. + + * conf/i386-ieee1275.rmk: Likewise. + +2008-08-03 Robert Millan + + * term/i386/pc/vga_text.c (CRTC_CURSOR_DISABLE): New macro. + (grub_console_setcursor): Make it possible to set cursor off. + +2008-08-03 Robert Millan + + * util/grub.d/00_header.in: Be platform-agnostic. Probe for existence + of modules instead of assuming which platform provides what. + * util/update-grub.in: Likewise. + +2008-08-03 Robert Millan + + * kern/i386/pc/init.c (make_install_device): Check for `grub_prefix' + instead of `grub_install_dos_part' to determine whether a drive needs + to be prepended to prefix (`grub_install_dos_part' is not reliable, + because it can be overridden when loading GRUB via Multiboot). + +2008-08-02 Robert Millan + + * util/i386/pc/grub-install.in: Remove trailing slash from prefix. + +2008-08-02 Robert Millan + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Add a pair + of informational grub_dprintf() calls. + +2008-08-02 Robert Millan + + * disk/memdisk.c (memdisk_size): Don't initialize. + (GRUB_MOD_INIT(memdisk)): Find memdisk using grub_module_iterate(). + + * include/grub/i386/pc/kernel.h + (GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE): Remove macro. + (GRUB_KERNEL_MACHINE_PREFIX, GRUB_KERNEL_MACHINE_DATA_END): Shift. + (grub_memdisk_image_size, grub_arch_memdisk_addr) + (grub_arch_memdisk_size): Remove. + + * include/grub/kernel.h (struct grub_module_header): Remove `offset' + field (was only used to transfer a constant). Add `type' field to + support multiple module types. + (grub_module_iterate): New function. + + * kern/device.c (grub_device_open): Do not hide error messages + when grub_disk_open() fails. Use grub_print_error() instead. + + * kern/i386/pc/init.c (grub_arch_modules_addr) + (grub_arch_memdisk_size): Remove functions. + (grub_arch_modules_addr): Return the module address in high memory + (now that it isn't copied anymore). + + * kern/i386/pc/startup.S (grub_memdisk_image_size): Remove variable. + (codestart): Don't add grub_memdisk_image_size to %ecx in LZMA + decompression routine (grub_total_module_size already includes that + now). Don't copy modules back to low memory. + + * kern/main.c: Include `'. + (grub_load_modules): Split out (and use) ... + (grub_module_iterate): ... this function, which iterates through + module objects and runs a hook. + Comment out grub_mm_init_region() call, as it would cause non-ELF + modules to be overwritten. + + * util/i386/pc/grub-mkimage.c (generate_image): Instead of appending + the memdisk image in its own region, make it part of the module list. + * util/elf/grub-mkimage.c (options): Add "memdisk"|'m' option. + (main): Parse --memdisk|-m option, and pass user-provided path as + parameter to generate_image(). + (add_segments): Pass `memdisk_path' down to load_modules(). + (load_modules): Embed memdisk image in module section when requested. + * util/i386/efi/grub-mkimage.c (make_mods_section): Initialize + `header.type' instead of `header.offset'. + + * conf/powerpc-ieee1275.rmk (pkglib_MODULES): Add `memdisk.mod'. + (memdisk_mod_SOURCES, memdisk_mod_CFLAGS) + (memdisk_mod_LDFLAGS): New variables. + * conf/i386-coreboot.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + +2008-08-02 Robert Millan + + * loader/i386/pc/multiboot.c (playground, forward_relocator) + (backward_relocator): New variables. Used to allocate and relocate + the payload, respectively. + (grub_multiboot_load_elf32): Load into heap instead of requested + address, install the appropriate relocator code in each bound of + the payload, and set the entry point such that + grub_multiboot_real_boot() will jump to one of them. + + * kern/i386/loader.S (grub_multiboot_payload_size) + (grub_multiboot_payload_orig, grub_multiboot_payload_dest) + (grub_multiboot_payload_entry_offset): New variables. + (grub_multiboot_real_boot): Set cpu context to what the relocator + expects, and jump to the relocator instead of the payload. + + * include/grub/i386/loader.h (grub_multiboot_payload_size) + (grub_multiboot_payload_orig, grub_multiboot_payload_dest) + (grub_multiboot_payload_entry_offset): Export. + +2008-08-01 Bean + + * normal/menu_entry.c (editor_getline): Don't return the original + string as result, as it will be released by lexer once it has done + using it. + +2008-08-01 Robert Millan + + * util/grub.d/10_linux.in: Use prepare_grub_to_access_device() from + within menuentries, not before them. + util/grub.d/10_hurd.in: Likewise. + +2008-08-01 Bean + + * conf/common.rmk (pkglib_MODULES): Add bufio.mod. + (bufio_mod_SOURCES): New macro. + (bufio_mod_CFLAGS): Likewise. + (bufio_mod_LDFLAGS): Likewise. + + * include/grub/bufio.h: New file. + + * io/bufio.c: Likewise. + + * video/png.c: Replace with . + (grub_video_reader_png): Use grub_buffile_open to open file. + + * video/jpeg.c: Replace with . + (grub_video_reader_jpeg): Use grub_buffile_open to open file. + + * video/tga.c: Replace with . + (grub_video_reader_tga): Use grub_buffile_open to open file. + + * font/manager.c: Include . + (add_font): Use grub_buffile_open to open file. + +2008-07-31 Robert Millan + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): When loading + ELF segments, use a macro for arbitrarily accessing any of them instead + of preparing a pointer that allows access to one at a time. + (grub_multiboot_load_elf64): Likewise. + +2008-07-31 Bean + + * boot/i386/pc/lnxboot.S (real_code_2): Replace 0x50 with + GRUB_KERNEL_MACHINE_DATA_END. + +2008-07-30 Robert Millan + + * include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_DATA_END): + Increase from 0x50 to 0x60. + * util/i386/pc/grub-install.in: Detect cross-disk installs, and + use UUIDs to identify the root drive for them. If that's not + possible, abort. + * util/i386/pc/grub-setup.c (setup): Do not special-case, or even + check, for cross-disk installs. + +2008-07-30 Robert Millan + + * kern/ieee1275/init.c (grub_machine_set_prefix): If `grub_prefix' + is non-empty, use it to set the `prefix' environment variable instead + of the usual approach. + * kern/i386/linuxbios/init.c (make_install_device): Remove function. + (grub_machine_set_prefix): Use `grub_prefix' to set the `prefix' + environment variable instead of dummy make_install_device(). + + * kern/i386/ieee1275/startup.S: Include `'. + (start): Insert a data section, with `grub_prefix' variable. + * kern/i386/linuxbios/startup.S: Likewise. + + * include/grub/powerpc/ieee1275/kernel.h [!ASM_FILE] (grub_prefix): + New variable reference. + * include/grub/i386/ieee1275/kernel.h (GRUB_KERNEL_MACHINE_PREFIX): + New macro. Defines offset of `grub_prefix' within startup.S (relative + to `start'). + (GRUB_KERNEL_MACHINE_DATA_END): New macro. Defines the end of data + section within startup.S (relative to `start'). + * include/grub/i386/coreboot/kernel.h: Likewise. + + * util/elf/grub-mkimage.c (add_segments): Receive `prefix' parameter. + Overwrite grub_prefix with its contents, at the beginning of the + first segment. + (main): Understand -p|--prefix. + +2008-07-30 Robert Millan + + * util/grub.d/10_hurd.in: Source ${libdir}/grub/update-grub_lib. + +2008-07-30 Robert Millan + + * term/i386/pc/vga_text.c (grub_console_cls): Use + grub_console_gotoxy() to go back to beginning of the screen. + Found by Patrick Georgi + +2008-07-29 Christian Franke + + * util/update-grub_lib.in (make_system_path_relative_to_its_root): + Add conversion of emulated mount points on Cygwin. + +2008-07-29 Christian Franke + + * util/update-grub.in: Add a check for admin + group on Cygwin. + Remove old `grub.cfg.new' before creation. + Add `-f' to `mv' to handle the different filesystem + semantics of Windows. + +2008-07-29 Bean + + * normal/main.c (get_line): Fix buffer overflow bug. + +2008-07-28 Robert Millan + + * partmap/apple.c (GRUB_APPLE_HEADER_MAGIC): New macro. + (struct grub_apple_header): New struct. Describes the layout of + the partmap header. + (apple_partition_map_iterate): Check the header magic as well as the + partition magic (which was already being checked). + +2008-07-28 Pavel Roskin + + * genmk.rb: Add a warning to the beginning of the output that + it's a generated file and should not be edited. + +2008-07-28 Robert Millan + + * disk/raid.c (grub_raid_scan_device): Do not abort when two disks + with the same number are found, just use issue a warning with + grub_dprintf(), as this error has been reported to be non-fatal. + +2008-07-27 Robert Millan + + * disk/ata.c (grub_ata_dumpinfo): Use grub_dprintf() for debugging + information. + +2008-07-27 Bean + + * fs/fat.c (GRUB_FAT_MAXFILE): New constant. + (grub_fat_find_dir): Ignore case when comparing filename. + +2008-07-27 Bean + + * fs/xfs.c (grub_xfs_dir_header): Change field i8count back to + smallino, as it's more descriptive, and i8count can be confused with + the other field count. + (grub_xfs_iterate_dir): Adjust grub_xfs_dir_entry pointer for small + inode type. + +2008-07-27 Bean + + * commands/crc.c: New file. + + * lib/crc.c: Likewise. + + * include/grub/lib/crc.h: Likewise. + + * util/grub-fstest.c: grub/hexdump.h => grub/lib/hexdump.h. + + * commands/hexdump.c: grub/hexdump.h => grub/lib/hexdump.h. + (hexdump): Move this function to ... + + * lib/hexdump.c: ... here. + + * include/grub/hexdump.h: Renamed to ... + + * include/grub/lib/hexdump.h: ... this. + + * commands/loadenv.c: grub/envblk.h => grub/lib/envblk.h + + * util/grub-editenv.c: Likewise. + + * include/envblk.h: Renamed to ... + + * include/lib/envblk.h: ... this. + + * util/envblk.c: Renamed to ... + + * lib/envblk.c: ... this. + + * conf/common.rmk (grub_fstest_SOURCES): commands/hexdump.c => + lib/hexdump.c. + (grub_editenv_SOURCES): util/envblk.c => lib/envblk.c + (pkglib_MODULES): Add crc.mod. + (hexdump_mod_SOURCES): Add lib/hexdump.c. + (loadenv_mod_SOURCES): util/envblk.c => lib/envblk.c. + (crc_mod_SOURCES): New macro. + (crc_mod_CFLAGS): Likewise. + (crc_mod_LDFLAGS): Likewise. + + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Add lib/hexdump.c. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. + +2008-07-27 Felix Zielcke + + * commands/help.c: Include . + (TERM_WIDTH): Removed. Updated all users. + +2008-07-27 Pavel Roskin + + * util/getroot.c (find_root_device): Rephrase a comment to avoid + spurious warnings about a comment within a comment. + +2008-07-25 Robert Millan + + * util/getroot.c (find_root_device): Skip devices that match + /dev/dm-[0-9]. This lets the real device be found for any type of + abstraction (LVM, EVMS, RAID..). + (grub_guess_root_device): Do not traverse /dev/mapper (for LVM) + and /dev/evms (for EVMS) before traversing /dev. If a /dev/dm-[0-9] + device is found first, find_root_device() will now skip it. + +2008-07-24 Pavel Roskin + + * include/grub/types.h: Use __builtin_bswap32() and + __builtin_bswap64() with gcc 4.3 and newer. + +2008-07-24 Christian Franke + + * util/i386/pc/grub-install.in: If `--debug' is specified, + pass `--verbose' to grub-setup. + Abort script if make_system_path_relative_to_its_root() fails. + +2008-07-24 Bean + + * configure.ac: Fixed a bug caused by the previous cygwin patch, + variable `target_platform' should be `platform'. + +2008-07-24 Bean + + * video/reader/png.c (DEFLATE_HLIT_MAX): Change value. + (grub_png_init_fixed_block): New function. + (grub_png_decode_image_data): Handle fixed huffman code compression. + +2008-07-24 Bean + + * common.rmk (bin_UTILITIES): Add grub-pe2elf. + (grub_pe2elf_SOURCES): New macro. + (CLEANFILES): Add grub-pe2elf. + + * include/grub/efi/pe32.h (GRUB_PE32_SCN_ALIGN_1BYTES): New constant. + (GRUB_PE32_SCN_ALIGN_2BYTES): Likewise. + (GRUB_PE32_SCN_ALIGN_4BYTES): Likewise. + (GRUB_PE32_SCN_ALIGN_8BYTES): Likewise. + (GRUB_PE32_SCN_ALIGN_16BYTES): Likewise. + (GRUB_PE32_SCN_ALIGN_32BYTES): Likewise. + (GRUB_PE32_SCN_ALIGN_64BYTES): Likewise. + (GRUB_PE32_SCN_ALIGN_SHIFT): Likewise. + (GRUB_PE32_SCN_ALIGN_MASK): Likewise. + (GRUB_PE32_SYM_CLASS_EXTERNAL): Likewise. + (GRUB_PE32_SYM_CLASS_STATIC): Likewise. + (GRUB_PE32_SYM_CLASS_FILE): Likewise. + (GRUB_PE32_DT_FUNCTION): Likewise. + (GRUB_PE32_REL_I386_DIR32): Likewise. + (GRUB_PE32_REL_I386_REL32): Likewise. + (grub_pe32_symbol): New structure. + (grub_pe32_reloc): Likewise. + + * util/grub-pe2elf.c: New file. + + * configure.ac: Set TARGET_OBJ2ELF if host os is cygwin. Don't test for + start symbol in non pc platform. + + * genmk.rb: Use TARGET_OBJ2ELF to convert native object format to elf. + + The following patches are from Christian Franke. + + * include/grub/dl.h: Remove .previous, gas supports this only + for ELF format. + + * include/grub/symbol.h [__CYGWIN__] (#define FUNCTION/VARIABLE): + Remove .type, gas supports this only for ELF format. + + * kern/dl.c (grub_dl_resolve_dependencies): Add check for trailing + nullbytes in symbol table. This fixes an infinite loop if table is + zero filled. + + * Makefile.in: Add autoconf replacements TARGET_IMG_LDSCRIPT, + TARGET_IMG_LDFLAGS and EXEEXT. + + * aclocal.m4 (grub_PROG_OBJCOPY_ABSOLUTE): Replace -Wl,-N by + TARGET_IMG_LDFLAGS_AC. + (grub_CHECK_STACK_ARG_PROBE): New function. + + * conf/i386-pc.rmk: Replace -Wl,-N by TARGET_IMG_LDFLAGS. + + * conf/i386-pc-cygwin-ld-img.sc: New linker script. + + * configure.ac: Add check for linker script "conf/${target}-img-ld.c" + to set TARGET_IMG_LD* accordingly. + Add check for Cygwin to set TARGET_MOD_OBJCOPY accordingly. + Add call to grub_CHECK_STACK_ARG_PROBE. + Use TARGET_IMG_LDFLAGS to check start, bss_start, end symbols. + + * genkernsyms.sh.in: Handle HAVE_ASM_USCORE case. + + * genmk.rb: Add EXEEXT to CLEANFILES. + +2008-07-23 Robert Millan + + * Makefile.in (UNICODE_ARROWS, UNICODE_LINES): New variables (they + define the codes for arrows and lines used for the menu). + (ascii.pff): Generate fonts for $(UNICODE_ARROWS) and $(UNICODE_LINES) + as well. + + * util/update-grub_lib.in (font_path): Prefer ascii.pff over complete + fonts, because the latter are too slow. + +2008-07-21 Bean + + * kern/i386/pc/startup.S (gate_a20_try_bios): Change test order for + a20. Run keyboard test last, as it will cause macbook to halt. + +2008-07-18 Pavel Roskin + + * kern/dl.c: Go back to using GRUB_CPU_SIZEOF_VOID_P. We cannot + load foreign architecture modules correctly anyway. Keep + support for loading host architecture modules, whether we + compile them or not. + +2008-07-17 Pavel Roskin + + * configure.ac: Use -m32 or -m64 regardless of whether we had to + change target_cpu. The compiler default can mismatch target_cpu + in any case. + + * disk/efi/efidisk.c: Fix format warnings on x86_64. + * kern/efi/efi.c: Likewise. + + * aclocal.m4 (grub_PROG_TARGET_CC): New macro. Check if the + target compiler is functional. + * configure.ac: Call grub_PROG_TARGET_CC once all target flags + are set up. + + * configure.ac: Default to efi platform for x86_64-apple. Allow + powerpc64 CPU, default to ieee1275 platform for it. Split CPU + adjustments from the rest, only do them if target is not + explicitly given. Merge other adjustments with the final sanity + check. Remove an extraneous check for supported CPU. Be + specific which CPU and which platform is not supported. + + * configure.ac: Default to pc platform for x86_64. + +2008-07-17 Robert Millan + + Partial LinuxBIOS -> Coreboot rename. + + * conf/i386-linuxbios.rmk: Renamed to ... + * conf/i386-coreboot.rmk: ... this. + * Makefile.in (RMKFILES): s/i386-linuxbios.rmk/i386-coreboot.rmk/g. + * configure.ac: Accept "coreboot" as input platform (but maintain + compatibility with "linuxbios"). + * include/grub/i386/linuxbios: Renamed to ... + * include/grub/i386/coreboot: ... this. + +2008-07-17 Bean + + * conf/i386/efi.rmk (pkglib_MODULES): add pci.mod and lspci.mod. + (appleldr_mod_SOURCE): New variable. + (appleldr_mod_CFLAGS): Likewise. + (appleldr_mod_LDFLAGS): Likewise. + (pci_mod_SOURCES): Likewise. + (pci_mod_CFLAGS): Likewise. + (pci_mod_LDFLAGS): Likewise. + (lspci_mod_SOURCES): Likewise. + (lspci_mod_CFLAGS): Likewise. + (lspci_mod_LDFLAGS): Likewise. + + * conf/x86_64-efi.rmk: New file. + + * disk/efi/efidisk.c (grub_efidisk_read): Wrap efi calls with efi_call_N + macro. + (grub_efidisk_write): Likewise. + + * include/efi/api.h (efi_call_0): New macro. + (efi_call_1): Likewise. + (efi_call_2): Likewise. + (efi_call_3): Likewise. + (efi_call_4): Likewise. + (efi_call_5): Likewise. + (efi_call_6): Likewise. + + * include/grub/efi/chainloader.h (grub_chainloader_cmd): Rename to + grub_rescue_cmd_chainloader. + + * include/grub/efi/pe32.h (GRUB_PE32_MACHINE_X86_64): New macro. + (grub_pe32_optional_header): Change some fields based on i386 or + x86_64 platform. + (GRUB_PE32_PE32_MAGIC): Likewise. + + * include/grub/efi/uga_draw.h: New file. + + * include/grub/elf.h (STN_ABS): New constant. + (R_X86_64_NONE): Relocation constant for x86_64. + (R_X86_64_64): Likewise. + (R_X86_64_PC32): Likewise. + (R_X86_64_GOT32): Likewise. + (R_X86_64_PLT32): Likewise. + (R_X86_64_COPY): Likewise. + (R_X86_64_GLOB_DAT): Likewise. + (R_X86_64_JUMP_SLOT): Likewise. + (R_X86_64_RELATIVE): Likewise. + (R_X86_64_GOTPCREL): Likewise. + (R_X86_64_32): Likewise. + (R_X86_64_32S): Likewise. + (R_X86_64_16): Likewise. + (R_X86_64_PC16): Likewise. + (R_X86_64_8): Likewise. + (R_X86_64_PC8): Likewise. + + * include/grub/i386/efi/pci.h: New file. + + * include/grub/i386/linux.h (GRUB_LINUX_EFI_SIGNATURE): + Change it value based on platform. + (GRUB_LINUX_EFI_SIGNATURE_0204): New constant. + (GRUB_E820_RAM): Likewise. + (GRUB_E820_RESERVED): Likewise. + (GRUB_E820_ACPI): Likewise. + (GRUB_E820_NVS): Likewise. + (GRUB_E820_EXEC_CODE): Likewise. + (GRUB_E820_MAX_ENTRY): Likewise. + (grub_e820_mmap): New structure. + (linux_kernel_header): Change the efi field according to different + kernel version, also field from linux_kernel_header. + + * include/grub/kernel.h (grub_module_info): Add padding for x86_64. + + * include/grub/pci.h (GRUB_PCI_ADDR_SPACE_MASK): New constant. + (GRUB_PCI_ADDR_SPACE_MEMORY): Likewise. + (GRUB_PCI_ADDR_SPACE_IO): Likewise. + (GRUB_PCI_ADDR_MEM_TYPE_MASK): Likewise. + (GRUB_PCI_ADDR_MEM_TYPE_32): Likewise. + (GRUB_PCI_ADDR_MEM_TYPE_1M): Likewise. + (GRUB_PCI_ADDR_MEM_TYPE_64): Likewise. + (GRUB_PCI_ADDR_MEM_PREFETCH): Likewise. + (GRUB_PCI_ADDR_MEM_MASK): Likewise. + (GRUB_PCI_ADDR_IO_MASK): Likewise. + + * include/grub/x86_64/efi/kernel.h: New file. + + * include/grub/x86_64/efi/loader.h: Likewise. + + * include/grub/x86_64/efi/machine.h: Likewise. + + * include/grub/x86_64/efi/pci.h: Likewise. + + * include/grub/x86_64/efi/time.h: Likewise. + + * include/grub/x86_64/linux.h: Likewise. + + * include/grub/x86_64/setjmp.h: Likewise. + + * include/grub/x86_64/time.h: Likewise. + + * include/grub/x86_64/types.h: Likewise. + + * kern/dl.c (GRUB_CPU_SIZEOF_VOID_P): Changed to + GRUB_TARGET_SIZEOF_VOID_P. + + * kern/efi/efi.c (grub_efi_locate_protocol): Wrap efi calls. + (grub_efi_locate_handle): Likewise. + (grub_efi_open_protocol): Likewise. + (grub_efi_set_text_mode): Likewise. + (grub_efi_stall): Likewise. + (grub_exit): Likewise. + (grub_reboot): Likewise. + (grub_halt): Likewise. + (grub_efi_exit_boot_services): Likewise. + (grub_get_rtc): Likewise. + + * kern/efi/mm.c (MEMORY_MAP_SIZE): Change to 0x3000 for new models. + (GRUB_CPU_SIZEOF_VOID_P): Changed to GRUB_TARGET_SIZEOF_VOID_P. + (grub_efi_allocate_pages): Wrap efi calls. + (grub_efi_free_pages): Wrap efi calls. + (grub_efi_get_memory_map): Wrap efi calls. + + * kern/x86_64/dl.c: New file. + + * kern/x86_64/efi/callwrap.S: Likewise. + + * kern/x86_64/efi/startup.S: Likewise. + + * loader/efi/appleloader.c: Likewise. + + * loader/efi/chainloader.c (cmdline): New variable. + (grub_chainloader_unload): Wrap efi calls. + (grub_chainloader_boot): Likewise. + (grub_rescue_cmd_chainloader): Wrap efi calls, handle + command line. + + * loader/efi/chainloader_normal.c (chainloader_command): + Change grub_chainloader_cmd to grub_rescue_cmd_chainloader, pass + command line. + + * loader/i386/efi/linux.c (allocate_pages): Change allocation + method. + (grub_e820_add_region): New function. + (grub_linux_boot): Construct e820 map from efi map, handle x86_64 + booting. + (grub_find_video_card): New function. + (grub_linux_setup_video): New function. + (grub_rescue_cmd_linux): Probe for video information. + + * normal/x86_64/setjmp.S: New file. + + * term/efi/console.c (map_char): New function. + (grub_console_putchar): Map unicode char. + (grub_console_checkkey): Wrap efi calls. + (grub_console_getkey): Likewise. + (grub_console_getwh): Likewise. + (grub_console_gotoxy): Likewise. + (grub_console_cls): Likewise. + (grub_console_setcolorstate): Likewise. + (grub_console_setcursor): Likewise. + + * util/i386/efi/grub-mkimage.c: Add support for x86_64. + +2008-07-16 Pavel Roskin + + * loader/i386/efi/linux.c (allocate_pages): Fix warnings in + format strings. + + * util/i386/efi/grub-mkimage.c (get_target_address): Return a + pointer, not an integer. This fixes a warning and prevents + precision loss on 64-bit systems. + (relocate_addresses): Remove unneeded cast. + +2008-07-15 Pavel Roskin + + * kern/i386/ieee1275/init.c: Include grub/cache.h. + + * term/ieee1275/ofconsole.c: Disable code unused on i386. + + * kern/ieee1275/ieee1275.c (grub_ieee1275_get_integer_property): + Fix comparison between signed and unsigned. + + * include/grub/i386/ieee1275/console.h: Declare + grub_console_init() and grub_console_fini(). + + * loader/i386/ieee1275/linux.c (grub_set_bootpath): Remove. + It's empty and unused. + + * fs/ext2.c (grub_ext2_read_block): Initialize blknr in the + beginning to avoid warnings with some compilers. + + * loader/ieee1275/multiboot2.c: Include grub/machine/loader.h. + [__i386__] (grub_mb2_arch_boot): Avoid unnecessary cast. + +2008-07-14 Pavel Roskin + + * kern/env.c (grub_register_variable_hook): Don't copy empty + string, it leaks memory. Pass "" to grub_env_set(), it should + handle constant strings. + + * commands/blocklist.c (grub_cmd_blocklist): Fix format warning. + * commands/cmp.c (grub_cmd_cmp): Likewise. + * kern/dl.c (grub_dl_flush_cache): Likewise. + (grub_dl_load_core): Likewise. + * kern/elf.c (grub_elf32_load_phdrs): Likewise. + (grub_elf64_load_phdrs): Likewise. + +2008-07-13 Pavel Roskin + + * lib/LzmaEnc.c (LzmaEnc_SetProps): Fix warning about comparison + between signed and unsigned. + (LzmaEnc_Finish): Fix warning about an unused parameter. + +2008-07-13 Bean + + * Makefile.in (enable_lzo): New rule. + + * conf/i386-pc.rmk (grub_mkimage_SOURCES): New test with enable_lzo. + + * configure.ac (ENABLE_LZO): New option --enable-lzo. + + * boot/i386/pc/lnxboot.S: #include . + + * include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE): Change + its value according to the compression algorithm used, lzo or lzma. + + * util/i386/pc/grub-mkimage.c (compress_kernel): Use different + compression algorithm according to configure macro. + + * kern/i386/pc/startup.S (codestart): Likewise. + + * kern/i386/pc/lzma_decode.S: New file. + + * include/grub/lib/LzFind.h: Likewise. + + * include/grub/lib/LzHash.h: Likewise. + + * include/grub/lib/LzmaDec.h: Likewise. + + * include/grub/lib/LzmaEnc.h: Likewise. + + * include/grub/lib/LzmaTypes.h: Likewise. + + * lib/LzFind.c: Likewise. + + * lib/LzmaDec.c: Likewise. + + * lib/LzmaEnc.c: Likewise. + +2008-07-13 Bean + + * fs/ext2.c (EXT4_EXTENTS_FLAG): New macro. + (grub_ext4_extent_header): New structure. + (grub_ext4_extent): Likewise. + (grub_ext4_extent_idx): Likewise. + (grub_ext4_find_leaf): New function. + (grub_ext2_read_block): Handle extents. + +2008-07-12 Robert Millan + + * util/i386/pc/grub-mkrescue.in: s/grub-install/grub-mkrescue/g. + +2008-07-11 Robert Millan + + * util/grub.d/40_custom.in: New file. Example on how to add custom + entries to /etc/grub.d. + * conf/common.rmk (%, update-grub_SCRIPTS, CLEANFILES): Install + 40_custom (implicitly, by merging all the grub.d rules). + +2008-07-11 Pavel Roskin + + * commands/read.c (grub_getline): Fix invalid memory access. + Don't add newline to the variable value. + + * term/i386/pc/serial.c (GRUB_SERIAL_PORT_NUM): New constant. + [!GRUB_MACHINE_PCBIOS] (serial_hw_io_addr): Add COM2 and COM3. + (serial_hw_get_port): Check validity of the port number. + (grub_cmd_serial): Check return value of serial_hw_get_port(). + +2008-07-07 Pavel Roskin + + * boot/i386/pc/diskboot.S (notification_string): Replace + "Loading kernel" with just "loading". This is shorter, less + confusing and saves a few bytes for possible future changes. + +2008-07-05 Pavel Roskin + + * disk/ata.c (grub_ata_dumpinfo): Don't output addressing and + size for ATAPI devices, they are undefined. Output sector + number in decimal form. + + * disk/ata.c: Use named constants for status bits. + +2008-07-04 Pavel Roskin + + * kern/i386/linuxbios/init.c (grub_machine_init): Cast addr to + grub_addr_t before casting it to the void pointer to fix a + warning. Non-addressable regions are discarded earlier. + (grub_arch_modules_addr): Cast _end to grub_addr_t. + * kern/i386/linuxbios/table.c: Include grub/misc.h. + (check_signature): Don't shadow table_header. + (grub_linuxbios_table_iterate): Cast numeric constants to + grub_linuxbios_table_header_t. + * include/grub/i386/linuxbios/init.h: Add noreturn attribute to + grub_stop(). + + * kern/ieee1275/init.c: Cast _start and _end to grub_addr_t to + prevent warnings. + + * include/grub/misc.h (ALIGN_UP): Avoid unnecessary cast to a + pointer, which can cause warnings. Support 64-bit addresses. + + * util/elf/grub-mkimage.c: Use GRUB_TARGET_SIZEOF_LONG instead + of sizeof(long). This fixes PowerPC image generation on x86_64. + +2008-07-04 Robert Millan + + This fixes a performance issue when pc & gpt partmap iterators + didn't abort iteration even after our hook found what it was + looking for (often causing expensive probes of non-existent drives). + + Some callers relied on previous buggy behaviour, since they would + raise an error when their own hooks caused early abortion of its + iteration. + + * kern/device.c (grub_device_open): Improve error message. + * disk/lvm.c (grub_lvm_open): Likewise. + * disk/raid.c (grub_raid_open): Likewise. + + * partmap/pc.c (pc_partition_map_iterate): Abort parent iteration + when hook requests it, independently of grub_errno. + (pc_partition_map_probe): Do not fail when find_func() caused + early abortion of pc_partition_map_iterate(). + + * partmap/gpt.c (gpt_partition_map_iterate): Abort parent iteration + when hook requests it, independently of grub_errno. + (gpt_partition_map_probe): Do not fail when find_func() caused + early abortion of gpt_partition_map_iterate(). + + * kern/partition.c (grub_partition_iterate): Abort parent iteration + when hook requests it, independently of grub_errno. Do not fail when + part_map_iterate_hook() caused early abortion of p->iterate(). + + * util/biosdisk.c (grub_util_biosdisk_get_grub_dev): Do not fail + when grub_partition_iterate() returned with non-zero. + +2008-07-03 Pavel Roskin + + * disk/ata.c (grub_ata_pio_write): Check status before writing, + like we do in grub_ata_pio_read(). + (grub_ata_readwrite): Always write individual sectors. Fix the + sector count for the remainder. + (grub_ata_write): Enable writing to ATA devices. Correctly + report error for ATAPI devices. + +2008-07-02 Pavel Roskin + + * boot/i386/pc/cdboot.S: Add _start entry to fix a linker + warning. + + * disk/ata.c (grub_ata_readwrite): Don't increment sector number + for every read sector, we already increment it for the whole + batch. This fixes reading more than 256 sectors at once. + + * util/grub-editenv.c (cmd_info): Cast argument to long + explicitly. ptrdiff_t reduces to int on i386. + + * util/grub-editenv.c (main): Be specific which parameter is + missing. + + * disk/memdisk.c (memdisk_addr): Make a pointer to fix warnings. + (memdisk): Make memdisk_orig_addr a pointer. + + * fs/reiserfs.c (grub_reiserfs_read): Fix misuse of grub_size_t + for file offsets, use grub_off_t instead. Fix printf format + warnings. + + * fs/reiserfs.c: Remove #warning, TODO list items don't belong + there. Real unexpected warnings should not drown in the noise + about known problems. + + * commands/hexdump.c (grub_cmd_hexdump): Fix misuse of + grub_disk_addr_t for memory addresses. + + * loader/aout.c (grub_aout_load): Cast load_addr to pointer + explicitly to fix a warning. + + * util/grub-editenv.c (cmd_info): Fix warning in printf format. + + * Makefile.in (MODULE_LDFLAGS): New variable. + * aclocal.m4 (grub_PROG_LD_BUILD_ID_NONE): New macro. Check if + the linker accepts --build-id=none. + * configure.ac: Call grub_PROG_LD_BUILD_ID_NONE. Substitute + MODULE_LDFLAGS. + * genmk.rb: Use MODULE_LDFLAGS when linking modules. + + * fs/xfs.c (struct grub_xfs_dir_header): Use names similar to + those in Linux XFS code. Provide a way to access 64-bit parent + inode. + (grub_xfs_iterate_dir): Use the new names. Avoid reading past + the end of struct grub_xfs_dir_header. + +2008-07-02 Bean + + * include/grub/ieee1275.h (grub_ieee1275_flag): New constant + GRUB_IEEE1275_FLAG_CANNOT_INTERPRET, GRUB_IEEE1275_FLAG_FORCE_CLAIM + and GRUB_IEEE1275_FLAG_NO_ANSI. + + * kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set flag + GRUB_IEEE1275_FLAG_CANNOT_INTERPRET, GRUB_IEEE1275_FLAG_FORCE_CLAIM + and GRUB_IEEE1275_FLAG_NO_ANSI for Open Hackware. + + * kern/ieee1275/ieee1275.c (grub_ieee1275_interpret): Return + immediately if GRUB_IEEE1275_FLAG_CANNOT_INTERPRET is set. + + * kern/ieee1275/init.c (grub_claim_heap): Claim memory directly if + GRUB_IEEE1275_FLAG_FORCE_CLAIM is set. + + * term/ieee1275/ofconsole.c (grub_ofconsole_writeesc): Don't output + esc sequence on non ANSI terminal. + (grub_ofconsole_gotoxy): Emulate backspace key on non ANSI terminal. + + * util/elf/grub-mkimage.c (add_segments): Move ELF header to the + beginning of file. + +2008-07-02 Bean + + * conf/common.rmk (bin_UTILITIES): Add grub-editenv. + (grub_editenv_SOURCES): New variable. + (pkglib_MODULES): Add loadenv.mod. + (loadenv_mod_SOURCES): New variable. + (loadenv_mod_CFLAGS): Likewise. + (loadenv_mod_LDFLAGS): Likewise. + + * include/grub/envblk.h: New file. + + * util/envblk.c: New file. + + * util/grub-editenv.c: New file. + + * commands/loadenv.c: New file. + +2008-07-01 Pavel Roskin + + * include/multiboot2.h (struct multiboot_tag_module): Use char, + not unsigned char. This fixes warnings and is consistent with + other tags. + + * disk/fs_uuid.c (search_fs_uuid): Correctly increment count. + + * normal/parser.y: Define YYENABLE_NLS as 0 to fix warnings. + + * term/tparm.c (analyze): Always set *popcount. + + * loader/i386/pc/linux.c (grub_rescue_cmd_linux): Remove useless + cast to fix a warning. + + * loader/i386/pc/multiboot2.c (grub_mb2_arch_module_alloc): Use + cast to suppress a warning. + + * fs/afs.c (grub_afs_read_block): Return grub_disk_addr_t, as + grub_fshelp_read_file() expects. + + * fs/fat.c: Fix UUID calculation on big-endian systems. We + write uuid as a 32-bit value in CPU byte order, so declare and + use it as such. + + * disk/raid.c: Cast grub_dprintf() arguments to unsigned long + long if the format specifier expects it. + * partmap/gpt.c (gpt_partition_map_iterate): Likewise. + * partmap/pc.c (pc_partition_map_iterate): Likewise. + * fs/ntfs.c (grub_ntfs_uuid): Cast data->uuid to unsigned long + long to fix a warning. + * fs/reiserfs.c (grub_reiserfs_read): Change casts in + grub_dprintf() arguments to fix warnings. + +2008-06-30 Pavel Roskin + + * util/i386/pc/grub-setup.c (setup): Write install_dos_part and + install_bsd_part immediately before core.img is embedded or + modified on disk. This fixes core.img verification if core.img + cannot be embedded. + + * util/i386/pc/grub-setup.c (setup): Use core_path_dev, not + core_path to calculate the blocklist. + Patch from Javier MartĂ­n + +2008-06-29 Robert Millan + + * fs/xfs.c (GRUB_XFS_FSB_TO_BLOCK): New macro. Maps filesystem + block to disk block. + (grub_xfs_read_block): Use GRUB_XFS_FSB_TO_BLOCK() on result. + Patch from Niels Böhm + +2008-06-29 Robert Millan + + * util/update-grub_lib.in (font_path): Search for fonts in + /boot/grub first, which is more likely to be readable (we aren't + deciding where fonts live, just looking for them). + +2008-06-26 Pavel Roskin + + * util/biosdisk.c (read_device_map): Don't leave dead map + entries for devices failing stat() check. + + * util/i386/pc/grub-setup.c (setup): Don't reuse core_path, use + core_path_dev for the core.img path on the target device. + +2008-06-26 Robert Millan + + * disk/fs_uuid.c: New file. + * conf/common.rmk (pkglib_MODULES): Add `fs_uuid.mod'. + (fs_uuid_mod_SOURCES, fs_uuid_mod_CFLAGS) + (fs_uuid_mod_LDFLAGS): New variables. + * include/grub/disk.h (grub_disk_dev_id): Add + `GRUB_DISK_DEVICE_UUID_ID'. + * kern/disk.c (grub_disk_dev_iterate): Allow disk devices not to + implement iterate(). + +2008-06-26 Robert Millan + + * util/grub.d/10_linux.in: Avoid passing UUIDs to Linux when either + "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" does not exist, or when a + Linux image includes no initrd. + +2008-06-21 Javier MartĂ­n + + * util/i386/pc/grub-setup.c (setup): Remove literal "core.img" in a + call to resolve the core image location that effectively appended the + name twice. + +2008-06-21 Robert Millan + + * util/grub.d/00_header.in: Move last prepare_grub_to_access_device() + call from here ... + + * util/grub.d/10_hurd.in: ... to here ... + * util/grub.d/10_linux.in: ... and here. + +2008-06-19 Robert Millan + + * kern/main.c (grub_main): Export `prefix' variable immediately + after it has been set by grub_machine_set_prefix(). + +2008-06-19 Robert Millan + + * commands/search.c (search_label, search_fs_uuid, search_file): Print + search result when not saving to variable, not the other way around. + When saving to variable, abort iteration as soon as a match is found. + +2008-06-19 Robert Millan + + * util/update-grub_lib.in (prepare_grub_to_access_device): Remove + check for partition that provides /boot/grub. Its logic is flawed, + as it prevents prepare_grub_to_access_device() from being called + multiple times. + +2008-06-19 Robert Millan + + * util/update-grub_lib.in (prepare_grub_to_access_device): Issue + "insmod" command directly when abstraction modules are needed, + instead of relying on GRUB_PRELOAD_MODULES (which had no effect + since it had already been processed). + +2008-06-19 Pavel Roskin + + * conf/i386-efi.rmk: Recompile grub-mkimage.c if Makefile has + changed. This is needed in case GRUB_LIBDIR changes. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-linuxbios.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + +2008-06-18 Pavel Roskin + + * conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): Rename + kernel_elf_symlist.c to symlist.c for consistency with other + architectures. Update all users. + * conf/sparc64-ieee1275.rmk (kernel_elf_SOURCES): Likewise. + +2008-06-18 Robert Millan + + * util/i386/pc/grub-install.in: If the drive is LVM or RAID, prepend + it in prefix. + + * util/i386/pc/grub-setup.c (main): Don't handle prefix at all. Set + `must_embed' to 1 when root_dev is a RAID device. When dest_dev is + a RAID device, run setup() for all members independently on whether + LVM abstraction is being used. + (setup): Don't handle prefix at all; let grub-mkimage take care of it. + If grub-mkimage has set `*install_dos_part == -2', don't override this + value. + Perform *install_dos_part adjustments independently on whether + we're embedding or not. + Clarify error message when image is too big for embedding. + Remove duplicate *install_dos_part stanza. + +2008-06-17 Robert Millan + + * term/ieee1275/ofconsole.c (fgcolor, bgcolor): Remove variables. + (grub_ofconsole_normal_color, grub_ofconsole_highlight_color): New + variables. + (grub_ofconsole_setcolor, grub_ofconsole_getcolor): Load/store + values in grub_ofconsole_normal_color and + grub_ofconsole_highlight_color (they're not directly related to + background and foreground). + (grub_ofconsole_setcolorstate): Extract background and foreground + from grub_ofconsole_normal_color and grub_ofconsole_highlight_color. + +2008-06-17 Robert Millan + + * util/update-grub_lib.in (prepare_grub_to_access_device): Use + /boot/grub for the check in last commit, not /boot (they could be + different partitions). + +2008-06-16 Robert Millan + + * util/update-grub_lib.in (prepare_grub_to_access_device): If we were + asked to setup access for the same partition that provides /boot, + don't bother using UUIDs since our root already has the value we + want. + +2008-06-16 Robert Millan + + * util/biosdisk.c (convert_system_partition_to_system_disk): Detect + I2O devices. + Patch from Sven Mueller . + +2008-06-16 Robert Millan + + * util/update-grub.in: Check for $EUID instead of $UID. + Reported by Vincent Zweije. + +2008-06-16 Bean + + * fs/ext2.c (grub_ext2_blockgroup): Revert to pre-journal state. + (grub_ext2_read_block): Likewise. + (grub_ext2_read_inode): Likewise. + (grub_ext2_mount): Likewise. + (grub_ext2_close): Likewise. + (grub_ext3_get_journal): Removed. + + * fs/reiserfs.c (grub_reiserfs_get_item): Revert to pre-journal state. + (grub_reiserfs_read_symlink): Likewise. + (grub_reiserfs_mount): Likewise. + (grub_reiserfs_open): Likewise. + (grub_reiserfs_read): Likewise. + (grub_reiserfs_close): Likewise. + (grub_reiserfs_get_journal): Removed. + + * fs/fshelp.c (grub_fshelp_read): Removed. + (grub_fshelp_map_block): Likewise. + + * include/grub/fshelp.h (grub_fshelp_journal_type): Removed. + (grub_fshelp_journal): Likewise. + (grub_fshelp_read): Likewise. + (grub_fshelp_map_block): Likewise. + +2008-06-16 Pavel Roskin + + * conf/powerpc-ieee1275.rmk: Remove -msoft-float, we don't use + floating point anymore. + * include/grub/powerpc/libgcc.h: Leave only necessary exports. + +2008-06-15 Pavel Roskin + + * commands/ls.c (grub_ls_list_files): Use integer calculations + for human readable format, avoid floating point use. + * kern/misc.c (grub_ftoa): Remove. + (grub_vsprintf): Remove floating point support. + +2008-06-15 Robert Millan + + * util/grub.d/10_linux.in: Use the underlying device for loop-AES + devices. + Reported by Max Vozeler. + +2008-06-15 Robert Millan + + * util/i386/pc/grub-mkimage.c (generate_image): If we included a drive + in our prefix, set install_{dos,bsd}_part = -2 to indicate this can be + skipped later. + (main): If a memdisk was requested, add "(memdisk)" drive explicitly to + the beginning of the prefix. + + * kern/i386/pc/init.c (make_install_device): Remove memdisk check. + It is assumed that if we have a memdisk, grub-mkimage has set + grub_prefix to include the "(memdisk)" drive in it. + +2008-06-15 Robert Millan + + * term/i386/pc/console.c [GRUB_MACHINE_LINUXBIOS] (grub_console_init): + Initialize keyboard controller after registering the terminal, so that + grub_printf() can be called from grub_keyboard_controller_init(). + +2008-06-15 Robert Millan + + * fs/sfs.c (grub_sfs_read_extent): Fix the count of nodes in + extent-btree which is written as big endian on disk. + Reported by Alain Greppin . + +2008-06-14 Robert Millan + + * util/i386/efi/grub-install.in (modules): Remove `_chain'. + * util/i386/pc/grub-install.in (modules): Likewise. + +2008-06-13 Pavel Roskin + + * commands/ls.c (grub_ls_list_files): Fix format warnings. + +2008-06-13 Bean + + * commands/hexdump.c (grub_cmd_hexdump): Adjust offset for partition. + + * fs/ext2.c (grub_ext3_get_journal): Fix revoke block handling. + + * fs/fshelp.c (grub_fshelp_map_block): Don't map block 0 as it's used + to indicate sparse block. + +2008-06-12 Pavel Roskin + + * fs/ext2.c (grub_ext2_read_inode): Don't normalize block + number, grub_fshelp_read() does it for us. + + * fs/fshelp.c (grub_fshelp_read): New function. Implement + linear disk read with journal translation. + * fs/ext2.c: Use grub_fshelp_read() instead of grub_disk_read(). + * include/grub/fshelp.h: Declare grub_fshelp_read(). + +2008-06-09 Pavel Roskin + + * fs/minix.c (grub_minix_mount): Handle error reading + superblock. + +2008-06-08 Robert Millan + + * util/i386/pc/grub-setup.c (main): If install drive is an LVM, + don't append the RAID prefix afterwards. + Reported by Clint Adams. + +2008-06-08 Robert Millan + + Based on description from Pavel: + * kern/disk.c (grub_disk_check_range): Rename to ... + (grub_disk_adjust_range): ... this. Add a comment explaining the + tasks performed by this function. + +2008-06-08 Robert Millan + + * include/grub/ntfs.h (struct grub_ntfs_bpb): Rename `serial_number' to + `num_serial' (for consistency with other variables). + (struct grub_ntfs_data): Add `uuid' member. + * fs/ntfs.c (grub_ntfs_mount): Initialize `data->uuid'. + (grub_ntfs_uuid): New function. + (grub_ntfs_fs): Reference grub_ntfs_uuid() in `uuid' struct member. + +2008-06-07 Pavel Roskin + + * util/biosdisk.c (open_device): Revert last change to the + function, it broke installation. The sector needs to be + different dependent on which device is opened. + +2008-06-06 Robert Millan + + Ensure GRUB_KERNEL_MACHINE_DATA_END is always consistent with the + rest of GRUB, and breakage doesn't happen if its value were modified. + + * include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE): + Redefine as an offset from `GRUB_KERNEL_MACHINE_DATA_END' instead of + a constant (same value). + * kern/i386/pc/startup.S: Replace hardcoded `0x50' with + `GRUB_KERNEL_MACHINE_DATA_END' (same value). + +2008-06-06 Robert Millan + + * util/biosdisk.c (open_device): Do not modify sector offset when + accessing a partition. kern/disk.c already handles this for us. + +2008-06-06 Robert Millan + + * util/grub-emu.c (grub_machine_init): Move code in this function from + here ... + (main): ... to here (before grub_util_biosdisk_init() call, to prevent + segfault in case grub_printf() is called). + + * util/i386/pc/grub-install.in: Append `--device-map=${device_map}' to + grub_probe. Update all users not to explicitly add it again. + (grub_device): New variable; contains corresponding device for grubdir. + (fs_module, partmap_module, devabstraction_module): Pass + `--device ${grub_device}' to grub_probe to avoid traversing /dev + every time. + +2008-06-05 Robert Millan + + * normal/misc.c (grub_normal_print_device_info): When a filesystem UUID + is found, print it (same layout as with labels). + +2008-06-04 Robert Millan + + * util/biosdisk.c (get_drive): Rename to ... + (find_grub_drive): ... this. Update all users. + + (get_os_disk): Rename to ... + (convert_system_partition_to_system_disk): ... this. Update all users. + + (find_drive): Rename to ... + (find_system_device): ... this. Update all users. + +2008-06-04 Robert Millan + + * util/biosdisk.c (get_os_disk): Handle IDA devices. + * util/grub-mkdevicemap.c (get_mmc_disk_name) + (make_device_map): Likewise. + +2008-06-01 Robert Millan + + * util/biosdisk.c (get_drive): Verify that `map[i].drive' is non-NULL + before dereferencing it. + + * fs/fat.c (struct grub_fat_bpb): Move fat32-specific fields into a + union with fat12/fat16-specific ones. Add some new fields, including + `num_serial' for both versions. + (struct grub_fat_data): Add `uuid' member. + (grub_fat_mount): Refer to fat32-specific fields in `bpb' by their new + names. Initialize `data->uuid' using `num_serial'. + (grub_fat_uuid): New function. + (grub_fat_fs): Reference grub_fat_uuid() in `uuid' struct member. + + * fs/reiserfs.c (grub_reiserfs_superblock): Add `uuid' field. + (grub_reiserfs_uuid): New function. + (grub_reiserfs_fs): Reference grub_reiserfs_uuid() in `uuid' struct + member. + + * fs/xfs.c (grub_xfs_sblock): Add `uuid' field. + (grub_xfs_uuid): New function. + (grub_xfs_fs): Reference grub_reiserfs_uuid() in `uuid' struct member. + +2008-06-01 Robert Millan + + * util/update-grub_lib.in (prepare_grub_to_access_device): Generate + code that is backward compatible with pre-uuid search command. + +2008-05-31 Robert Millan + + * disk/i386/pc/biosdisk.c (grub_biosdisk_iterate): Iterate through + floppies after everything else, to ensure floppy drive isn't accessed + unnecessarily (patch from Bean). + +2008-05-31 Robert Millan + + * commands/search.c (search_label, search_fs_uuid, search_file): Do + not print device names when we were asked to set a variable. + +2008-05-31 Robert Millan + + * term/ieee1275/ofconsole.c (grub_ofconsole_setcursor): Implement + using "cursor-on" and "cursor-off" commands (understood at least by + the Open Firmware flavour on OLPC). + +2008-05-31 Michael Gorven + + * term/terminfo.c (grub_terminfo_set_current): Correct vt100 cursor + on and off sequences. + +2008-05-31 Robert Millan + + * util/update-grub_lib.in: Replace `grub-probe' with `${grub_probe}'. + * util/update-grub.in: Likewise. + +2008-05-30 Pavel Roskin + + * util/biosdisk.c (linux_find_partition): Simplify logic and + make the code more universal. Keep special processing for + devfs, but use a simple rule for all other devices. If the + device ends with a number, append 'p' and the partition number. + Otherwise, append only the partition number. + +2008-05-30 Robert Millan + + * util/update-grub.in (GRUB_DISABLE_LINUX_UUID): Export variable. + * util/grub.d/10_linux.in: If GRUB_DEVICE_UUID is set, and + GRUB_DISABLE_LINUX_UUID isn't true, use the filesystem UUIDs as + the `root' parameter to Linux. + +2008-05-30 Robert Millan + + * commands/search.c (options): Rename --fs_uuid to --fs-uuid. + * util/update-grub_lib.in (prepare_grub_to_access_device): Replace + --fs_uuid with --fs-uuid. + * util/update-grub.in: Allow filesystem UUID probes to fail (since not + all filesystems support them). + +2008-05-30 Robert Millan + + * fs/ext2.c (grub_ext2_uuid): Use `04x' instead of '02x' as + grub_printf() flags, since we're printing in units of 2 bytes. + +2008-05-30 Robert Millan + + * util/grub.d/00_header.in: Remove obsolete comment referencing + convert_system_path_to_grub_path(). + * util/update-grub.in: Likewise. + * util/update-grub_lib.in (is_path_readable_by_grub): New function. + (convert_system_path_to_grub_path): Add a warning message explaining + that this function is deprecated. Rely on is_path_readable_by_grub() + for the readability checks. + (font_path): Use is_path_readable_by_grub() for the readability + check rather than convert_system_path_to_grub_path(). + +2008-05-30 Robert Millan + + * util/update-grub_lib.in (prepare_grub_to_access_device): New function. + * util/update-grub.in: Set `GRUB_FONT_PATH' to the system path, without + converting it first. + * util/grub.d/00_header.in: Use prepare_grub_to_access_device() to setup + grub.cfg for access to font file, and afterwards call it again to set + the root device. + +2008-05-30 Robert Millan + + * commands/search.c (options): Add --fs_uuid option. + (search_fs_uuid): New function. + (grub_cmd_search): Fix --set argument passing. + Use search_fs_uuid() when requested via --fs_uuid. + (grub_search_init): Update help message. + * fs/ext2.c (struct grub_ext2_sblock): Rename `unique_id' to `uuid' + and redeclare it as an array of 16-bit words. + (grub_ext2_uuid): New function. + (grub_ext2_fs): Reference grub_ext2_uuid() in `uuid' struct member. + * include/grub/fs.h (struct grub_fs): Add `uuid' struct member. + * util/update-grub.in (GRUB_DEVICE_UUID, GRUB_DEVICE_BOOT) + (GRUB_DEVICE_BOOT_UUID): New variables. + (GRUB_DRIVE. GRUB_DRIVE_BOOT. GRUB_DRIVE_BOOT_GRUB): Remove. + * util/grub.d/00_header.in: Set root using `search --fs_uuid' command + whenever possible. + * util/grub.d/10_hurd.in: Avoid explicit use of root drive. Instead, + just assume `root' variable has the right value. + * util/grub.d/10_linux.in: Likewise. + * util/grub-probe.c (probe): Probe for filesystem UUID when requested + via PRINT_FS_UUID. + (main): Recognise `-t fs_uuid' argument. + +2008-05-30 Robert Millan + + * util/biosdisk.c (map): Redefine structure to hold information + about GRUB drive name. + (get_drive): Reimplement without assuming (and verifying) BIOS-like + drive names. + (call_hook): Remove. + (grub_util_biosdisk_iterate): Access drive names via `.drive' struct + member. Assume drive has partitions. + (grub_util_biosdisk_open): Access device names via `.device' struct + member. + (open_device): Likewise. + (find_drive): Likewise. + (read_device_map): Adjust map[] usage to match the new struct + definition. Don't check for duplicates (still possible, but not cheap + anymore). + (grub_util_biosdisk_fini): Free malloced buffers referenced by map[]. + (make_device_name): Remove assumption of BIOS-like drive names. + +2008-05-30 Pavel Roskin + + * conf/i386-efi.rmk (normal/execute.c_DEPENDENCIES): Remove, as + compiling execute.c doesn't need grub_script.tab.h anymore. + (normal/command.c_DEPENDENCIES): Likewise. + (normal/function.c_DEPENDENCIES): Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-linuxbios.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + +2008-05-29 Pavel Roskin + + * disk/lvm.c (grub_lvm_scan_device): Check for the buffer end + when scanning metadata for volume group name. + + * include/grub/script.h: Don't include grub_script.tab.h. It's + a generated file, which may only be included from the files with + DEPENDENCIES rules in the makefile. Don't use typedef YYSTYPE, + use union YYSTYPE, as the later allows forward declaration. + * normal/lexer.c: Don't use typedef YYSTYPE, use union YYSTYPE. + +2008-05-29 Robert Millan + + * term/i386/pc/at_keyboard.c: Include `grub/machine/machine.h'. + (OLPC_UP, OLPC_DOWN, OLPC_LEFT, OLPC_RIGHT): New macros. + [GRUB_MACHINE_IEEE1275] (keyboard_map): Add OLPC scan codes + (grub_console_checkkey): Add grub_dprintf() call to report unknown + scan codes. + +2008-05-29 Robert Millan + + * term/i386/pc/at_keyboard.c (grub_console_checkkey): Add support for + control key combinations. + +2008-05-29 Robert Millan + + * util/powerpc/ieee1275/grub-install.in: Move from here ... + * util/ieee1275/grub-install.in: ... to here. + * powerpc-ieee1275.rmk (grub_install_SOURCES): Update location. + * i386-ieee1275.rmk (sbin_SCRIPTS): New variable. + (grub_install_SOURCES): Likewise. + +2008-05-29 Robert Millan + + * fs/affs.c: Update copyright year. + * fs/ext2.c: Likewise. + * fs/fshelp.c: Likewise. + * fs/hfsplus.c: Likewise. + * fs/ntfs.c: Likewise. + * fs/xfs.c: Likewise. + * include/grub/fshelp.h: Likewise. + * util/grub-mkdevicemap.c: Likewise. + +2008-05-28 Robert Millan + + * util/update-grub.in: Allow chmod call to fail, since /boot/grub/ + might need to be fatfs to support some firmware implementations + (e.g. OFW or EFI). + +2008-05-28 Robert Millan + + * util/biosdisk.c (linux_find_partition, get_os_disk): Handle MMC + devices. + * util/grub-mkdevicemap.c (get_mmc_disk_name) + (make_device_map): Likewise. + +2008-05-20 Bean + + * fs/fshelp.c (grub_fshelp_map_block): New function. + (grub_fshelp_find_file): Use 64-bit type for pos and block address. + Use `>>' and `&' operator to avoid 64-bit divide and modulo. + + * include/grub/fshelp.h (grub_fshelp_journal_type): New enum. + (GRUB_FSHELP_JOURNAL_UNUSED_MAPPING): New macro. + (grub_fshelp_journal): New structure. + (grub_fshelp_map_block): New function prototype. + (grub_fshelp_read_file): Use grub_disk_addr_t as block type. + (grub_fshelp_map_block): Likewise. + + * fs/ext2.c (EXT3_FEATURE_COMPAT_HAS_JOURNAL): New macro. + (EXT3_JOURNAL_MAGIC_NUMBER): Likewise. + (EXT3_JOURNAL_DESCRIPTOR_BLOCK): Likewise. + (EXT3_JOURNAL_COMMIT_BLOCK): Likewise. + (EXT3_JOURNAL_SUPERBLOCK_V1): Likewise. + (EXT3_JOURNAL_SUPERBLOCK_V2): Likewise. + (EXT3_JOURNAL_REVOKE_BLOCK): Likewise. + (EXT3_JOURNAL_FLAG_ESCAPE): Likewise. + (EXT3_JOURNAL_FLAG_SAME_UUID): Likewise. + (EXT3_JOURNAL_FLAG_DELETED): Likewise. + (EXT3_JOURNAL_FLAG_LAST_TAG): Likewise. + (grub_ext2_sblock): New members for journal support. + (grub_ext3_journal_header): New structure. + (grub_ext3_journal_revoke_header): Likewise. + (grub_ext3_journal_block_tag): Likewise. + (grub_ext3_journal_sblock): Likewise. + (grub_fshelp_node): New members logfile and journal. + (grub_ext2_read_block): Change block type to grub_disk_addr_t. Use + grub_fshelp_map_block to get real block number. + (grub_ext2_blockgroup): Use grub_fshelp_map_block to get real block + number. + (grub_ext2_read_inode): Likewise. + (grub_ext3_get_journal): New function. + (grub_read_inode): Initialize journal using grub_ext3_get_journal. + (grub_ext2_close): Release memory used by journal. + + * fs/reiserfs.c (REISERFS_MAGIC_STRING): Changed to "ReIsEr". + (REISERFS_MAGIC_DESC_BLOCK): New macro. + (grub_reiserfs_transaction_header): Renamed to + grub_reiserfs_description_block, replace field data with real_blocks. + (grub_reiserfs_commit_block): New structure. + (grub_reiserfs_data): New member journal. + (grub_reiserfs_get_item): Use grub_fshelp_map_block to get real block + number. + (grub_reiserfs_read_symlink): Likewise. + (grub_reiserfs_iterate_dir): Likewise. + (grub_reiserfs_open): Likewise. + (grub_reiserfs_read): Likewise. + (grub_reiserfs_get_journal): New function. + (grub_reiserfs_mount): Use "ReIsEr" as super block magic, as there are + three varieties ReIsErFs, ReIsEr2Fs and ReIsEr3Fs. Initialize journal + using grub_reiserfs_get_journal. + (grub_reiserfs_close): Release memory used by journal. + + * fs/affs.c (grub_affs_read_block): Change block type to + grub_disk_addr_t. Use grub_divmod64 to do 64-bit division. + + * fs/afs.c (grub_afs_read_block): Change block type to grub_disk_addr_t. + + * fs/hfsplus.c (grub_hfsplus_read_block): Likewise. + + * fs/ntfs.c (grub_ntfs_read_block): Likewise. + + * fs/udf.c (grub_udf_read_block): Change block type to + grub_disk_addr_t. Use type cast to avoid warning. + + * fs/xfs.c (grub_xfs_read_block): Likewise. + +2008-05-16 Christian Franke + + * commands/cat.c (grub_cmd_cat): Remove non-ESC keys from keyboard queue + to ensure that break with ESC will always work. + * commands/sleep.c (grub_interruptible_millisleep): Likewise. + Remove ESC from keyboard queue. + +2008-05-16 Christian Franke + + * util/biosdisk.c: [__CYGWIN__] Add includes. + (grub_util_biosdisk_open): Use Linux code also for Cygwin. + (get_os_disk): Move variable declarations to OS specific + parts to avoid warning. + [__GNU__] (get_os_disk): Fix /dev/sdXsN case. + [__CYGWIN__] (get_os_disk): Add Cygwin /dev/sdXN device names. + (grub_util_biosdisk_get_grub_dev): Use Linux code also for + Cygwin. + * util/getroot.c: [__CYGWIN__] Add includes. + (strip_extra_slashes): Fix "/" case. + [__CYGWIN__] (get_win32_path): New function. + [__CYGWIN__] (grub_get_prefix): Add conversion to win32 path. + [__CYGWIN__] (find_root_device): Disable. + [__CYGWIN__] (get_bootsec_serial): New function. + [__CYGWIN__] (find_cygwin_root_device): Likewise. + [__linux__] (grub_guess_root_device): Add early returns to simplify + structure. + [__CYGWIN__] (grub_guess_root_device): Call find_cygwin_root_device. + [__linux__] (grub_util_get_dev_abstraction): Enable LVM and RAID + check for Linux only. + +2008-05-15 Bean + + * kern/i386/pc/startup.S (grub_console_getkey): Workaround for the + keyboard hang problem in apple's intel mac. + +2008-05-09 Robert Millan + + * util/biosdisk.c (linux_find_partition, get_os_disk): Handle Virtio + devices. + * util/grub-mkdevicemap.c (get_virtio_disk_name) + (make_device_map): Likewise. + Reported by Aurelien Jarno + +2008-05-07 Ian Campbell + + * util/biosdisk.c (get_os_disk): Recognise xvd type disks. + * util/grub-mkdevicemap.c (get_xvd_disk_name): New function. + (make_device_map): Output entries for xvd type disks. + +2008-05-07 Robert Millan + + * util/biosdisk.c (linux_find_partition, get_os_disk): Handle CCISS + devices. + * util/grub-mkdevicemap.c (get_cciss_disk_name) + (make_device_map): Likewise. + Reported by Roland Dreier + +2008-05-07 Robert Millan + + * disk/lvm.c (grub_lvm_scan_device): Detect errors in an additional + grub_strstr() call. Correct a few mistakes in failure path handling. + +2008-05-06 Robert Millan + + * util/update-grub_lib.in (make_system_path_relative_to_its_root): + Do not print a trailing slash (therefore, the root directory is an + empty string). + (convert_system_path_to_grub_path): Do not remove trailing slash + from make_system_path_relative_to_its_root() output. + + * util/i386/pc/grub-install.in: Add trailing slash to output from + make_system_path_relative_to_its_root(). + +2008-05-06 Robert Millan + + * util/grub-fstest.c (grub_refresh): Call `fflush (stdout)'. This + ensures that output lines aren't intermangled with those sent to + stderr (via grub_util_info()). + * util/grub-probe.c (grub_refresh): Likewise. + * util/i386/pc/grub-setup.c (grub_refresh): Likewise. + +2008-05-05 Christian Franke + + * util/grub-mkdevicemap.c (get_floppy_disk_name) [__CYGWIN__]: + Add Cygwin device names. + (get_ide_disk_name) [__CYGWIN__]: Likewise. + (get_scsi_disk_name) [__CYGWIN__]: Likewise. + (check_device): Return error instead of success on empty name. + (make_device_map): Move label inside linux specific code to + prevent compiler warning. + +2008-04-30 Robert Millan + + Based on patch from Fabian Greffrath + * util/grub.d/10_linux.in: Add ${GRUB_CMDLINE_LINUX_DEFAULT} to the + first boot option. + * util/update-grub.in: Export GRUB_CMDLINE_LINUX_DEFAULT. + +2008-04-29 Robert Millan + + * docs/grub.cfg: New file (example GRUB configuration). + +2008-04-26 Robert Millan + + * DISTLIST: Sort (sort -u < DISTLIST | sponge DISTLIST). Add + `loader/i386/ieee1275/linux.c', `loader/i386/ieee1275/linux_normal.c' + and `disk/ieee1275/nand.c'. + +2008-04-25 Bean + + * Makefile.in (RMKFILES): Add missing arch i386-ieee1275 and + i386-linuxbios. + + * commands/hexdump.c (grub_cmd_hexdump): Support dumping of device, + change the buffer size to 4096 for cdrom device. + + * conf/i386-ieee1275.rmk (pkglib_MODULES): Add _linux.mod, linux.mod + and nand.mod. + (_linux_mod_SOURCES): New variable. + (_linux_mod_CFLAGS): Likewise. + (_linux_mod_LDFLAGS): Likewise. + (linux_mod_SOURCES): Likewise. + (linux_mod_CFLAGS): Likewise. + (linux_mod_LDFLAGS): Likewise. + (nand_mod_SOURCES): Likewise. + (nand_mod_CFLAGS): Likewise. + (nand_mod_LDFLAGS): Likewise. + + * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Return + GRUB_ERR_UNKNOWN_DEVICE instead of GRUB_ERR_BAD_DEVICE if no device + type property. (nand device in olpc don't have this property) + + * include/grub/disk.h (grub_disk_dev_id): New macro + GRUB_DISK_DEVICE_NAND_ID. + + * include/grub/i386/ieee1275/loader.h (grub_rescue_cmd_linux): New + function prototype. + (grub_rescue_cmd_initrd): Likewise. + + * include/grub/i386/linux.h (GRUB_LINUX_OFW_SIGNATURE): New macro. + (linux_kernel_params): Add new member ofw_signature, ofw_num_items, + ofw_cif_handler and ofw_idt, adjust padding number. + + * include/grub/i386/pc/memory.h (grub_upper_mem): Export it if + GRUB_MACHINE_IEEE1275 is defined. + + * include/grub/ieee1275/ieee1275.h (grub_available_iterate): + Use NESTED_FUNC_ATTR attribute on the hook parameter. + + * kern/powerpc/ieee1275/init.c (grub_claim_heap): Use NESTED_FUNC_ATTR + on nested function heap_init. + (grub_upper_mem): New variable for i386-ieee1275. + (grub_get_extended_memory): New function for i386-ieee1275. + (grub_machine_init): Call grub_get_extended_memory for i386-ieee1275. + + * kern/powerpc/ieee1275/openfw.c (grub_available_iterate): Use + NESTED_FUNC_ATTR on the hook parameter. Don't quit if no device type + property. + + * loader/i386/ieee1275/linux.c: New file. + + * loader/i386/ieee1275/linux_normal.c: New file. + + * disk/ieee1275/nand.c: New file. + +2008-04-18 Thomas Schwinge + + * util/i386/pc/grub-mkrescue.in (grub_mkimage): Don't overwrite correct + value. + * util/powerpc/ieee1275/grub-mkrescue.in (grub_mkimage): Likewise. + +2008-04-18 Robert Millan + + Restructures early code path on ieee1275 to unify grub_main() as + the first C function that is executed in every platform. + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_init): New prototype. + * kern/i386/ieee1275/startup.S (_start): Jump to grub_main() instead of + cmain(). + * kern/powerpc/ieee1275/crt0.S (_start): Likewise. + * kern/ieee1275/cmain.c (cmain): Rename to ... + * kern/ieee1275/cmain.c (grub_ieee1275_init): ... this. + * kern/ieee1275/init.c (grub_machine_init): Call grub_ieee1275_init() + at the beginning. + +2008-04-18 Robert Millan + + * util/update-grub.in: Fix syntax error when setting + `GRUB_PRELOAD_MODULES'. + Reported by Stephane Chazelas + +2008-04-17 Lubomir Kundrak + + * aclocal.m4 (grub_PROG_OBJCOPY_ABSOLUTE): take only .text + section into account, newer toolchains generate unique build ids + * configure.ac: remove the test for --build-id=none acceptance, + we want build ids to be preserved + * genmk.rb: add -R .note.gnu.build-id to objcopy, so build id + far from other sections don't cause the raw binary images grow + size + +2008-04-15 Robert Millan + + * disk/lvm.c: Update copyright year. + * kern/misc.c: Likewise. + +2008-04-14 Vesa Jaaskelainen + + * disk/lvm.c (grub_lvm_scan_device): Add forgotten failure path when + there is no memory left for physical volume name. + +2008-04-14 Vesa Jaaskelainen + + * disk/lvm.c (grub_lvm_scan_device): Fix logical volume's physical + volume name mapping to support bigger than 9 character names properly. + +2008-04-13 Robert Millan + + * disk/i386/pc/biosdisk.c (grub_biosdisk_rw): Fix CHS limit check, + as per http://www.allensmith.net/Storage/HDDlimit/Int13h.htm + +2008-04-13 Christian Franke + + * util/i386/pc/grub-mkrescue.in: Add --emulation=floppy + to create a floppy emulation boot CD when non emulation mode + does not work. + Enable Joliet CD filesystem extension. + +2008-04-13 Robert Millan + + * kern/misc.c (grub_strncat): Fix off-by-one error. + Reported by Zhang Huan + + * kern/env.c (grub_env_context_close): Clear current context, not + previous one. + Patch from Zhang Huan + + * kern/misc.c (grub_strcat): Minor speed optimization (same code size). + +2008-04-13 Robert Millan + + Improve robustness when handling LVM. + + * disk/lvm.c (grub_lvm_getvalue): Return 0 when `*p' is NULL + (and leave `*p' unmodified). + (grub_lvm_iterate): Don't assume `vg->lvs != NULL' when iterating + through it. + (grub_lvm_memberlist): Don't assume `lv->vg->pvs != NULL' when + iterating through it. + (grub_lvm_open): Don't assume `vg->lvs != NULL' when iterating + through it. + (grub_lvm_scan_device): Check the return value (and fail gracefully + when due) on each grub_lvm_getvalue() or grub_strstr() call. + Don't assume `vg->pvs != NULL' when iterating through it. + +2008-04-13 Robert Millan + + * gendistlist.sh (EXTRA_DISTFILES): Add `genpartmaplist.sh'. + * genmk.rb (partmap): New variable. + (CLEANFILES, PARTMAPFILES): Add #{partmap}. + (#{partmap}): New target rule. + * genpartmaplist.sh: New file. + * Makefile.in (pkglib_DATA): Add partmap.lst. + (partmap.lst): New target rule. + * util/i386/pc/grub-mkrescue.in: Generate grub.cfg that loads needed + modules (including all partition maps), instead of preloading them. + +2007-04-13 Fabian Greffrath + + * util/grub.d/30_os-prober.in: New script. Use `os-prober' and + `linux-boot-prober' (if installed) to detect other operating + systems which are installed on the computer and add them to + the boot menu. + * conf/common.rmk: Build and install 30_os-prober. + +2008-04-12 Robert Millan + + * kern/powerpc/ieee1275/init.c: Move from here ... + * kern/ieee1275/init.c: ... to here. Update all users. + + * kern/powerpc/ieee1275/cmain.c: Move from here ... + * kern/ieee1275/cmain.c: ... to here. Update all users. + + * kern/powerpc/ieee1275/openfw.c: Move from here ... + * kern/ieee1275/openfw.c: ... to here. Update all users. + + * loader/powerpc/ieee1275/multiboot2.c: Move from here ... + * loader/ieee1275/multiboot2.c: ... to here. Update all users. + +2008-04-10 Pavel Roskin + + * configure.ac: Always use "_cv_" in cache variables for + compatibility with Autoconf 2.62. + +2008-04-07 Robert Millan + + Revert grub/machine/init.h addition by Pavel (since it breaks on + i386-ieee1275 and others): + * util/i386/pc/misc.c: Remove grub/machine/init.h. + * util/powerpc/ieee1275/misc.c: Likewise. + +2008-04-07 Robert Millan + + * util/grub-probe.c (probe): Improve error message. + +2008-04-07 Robert Millan + + * util/biosdisk.c (read_device_map): Skip devices that don't exist + (this prevents the presence of a bogus entry from ruining the whole + thing). + +2008-04-06 Pavel Roskin + + * util/biosdisk.c: Include grub/util/biosdisk.h. + * util/grub-fstest.c (execute_command): Make static. + * util/grub-mkdevicemap.c (check_device): Likewise. + * util/i386/pc/misc.c: Include grub/machine/init.h. + * util/powerpc/ieee1275/misc.c: Likewise. + * util/lvm.c: Include grub/util/lvm.h. + * util/misc.c: Include grub/kernel.h, grub/misc.h and + grub/cache.h. + * util/raid.c: Include grub/util/raid.h. + (grub_util_getdiskname): Make static. + + * util/grub-emu.c (main): Remove calls to grub_hostfs_init() and + grub_hostfs_fini(), as they are called from grub_init_all() and + grub_fini_all() respectively. This fixes an infinite loop in + grub-fstest due to double registration of hostfs. + Reported by Christian Franke + +2008-04-05 Pavel Roskin + + * bus/pci.c (grub_pci_iterate): For multifunction devices, probe + all 8 functions. Otherwise, probe function 0 only. + +2008-04-04 Pavel Roskin + + * commands/lspci.c (grub_lspci_iter): Print the bus number + correctly. + + * commands/lspci.c (grub_pci_classes): Fix typos. + (grub_lspci_iter): Don't print func twice. Print vendor ID + before device ID, as it's normally done. + + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_find_options): + Fix signedness warnings. + * kern/powerpc/ieee1275/openfw.c (grub_available_iterate): + Likewise. + * util/ieee1275/get_disk_name.c: Include config.h so that + _GNU_SOURCE is defined and getline() is declared. Mark an + unused argument as such. Fix a signedness warning. + +2008-04-02 Pavel Roskin + + * genkernsyms.sh.in: Use more robust assignments for CC and + srcdir. Quote srcdir. + * gensymlist.sh.in: Likewise. Assert at the compile time that + the symbol table is not empty. + + * disk/raid.c (grub_raid_memberlist): Fix a signedness warning. + * fs/cpio.c (grub_cpio_read): Likewise. + +2008-04-01 Pavel Roskin + + * disk/ata.c (grub_ata_open): Don't lose precision in disk->id. + * disk/host.c (grub_host_open): Likewise. + * disk/loopback.c (grub_loopback_open): Likewise. + * disk/memdisk.c (grub_memdisk_open): Use a string pointer for + disk->id as in disk/host.c, not a multi-character constant. + + * util/grub-fstest.c (cmd_cmp): Use fseeko(), not fseek(). The + later is obsolete, potentially dangerous and sets a bad example. + * util/i386/efi/grub-mkimage.c (make_header): Likewise. + * util/misc.c (grub_util_get_image_size): Likewise. + + * disk/loopback.c (options): Improve help for "--partitions". + + * normal/arg.c (grub_arg_show_help): Fix spacing of the long + options to align them with the short options, e.g. "echo -e". + +2008-03-31 Bean + + * video/reader/png.c (grub_png_data): New member is_16bit and + image_data. + (grub_png_decode_image_header): Detect 16 bit png image. + (grub_png_convert_image): New function to convert 16 bit image to 8 bit. + (grub_png_decode_png): Call grub_png_convert_image for 16 bit image. + (grub_video_reader_png): Release memory occupied by image_data. + + * fs/ntfs.c (find_attr): Handle non-resident attribute list larger than + 4096 bytes. + (grub_nfs_mount): Skip the test for sector per cluster. + + * include/grub/ntfs.h (MAX_SPC): Removed. + +2008-03-31 Bean + + * conf/common.rmk (pkgdata_MODULES): Add afs.mod. + (grub_probe_SOURCES): Add fs/afs.c. + (grub_fstest_SOURCES): Likewise. + (afs_mod_SOURCES): New variable. + (afs_mod_CFLAGS): Likewise. + (afs_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/afs.c. + (grub_emu_SOURCES): Likewise. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * fs/afs.c: New file. + +2008-03-30 Pavel Roskin + + * disk/host.c: Include grub/misc.h to fix a warning. + * util/hostfs.c: Use GRUB_MOD_INIT and GRUB_MOD_FINI to fix + warnings about implicit declarations. + + * fs/udf.c (grub_udf_mount): Fix warning about a shadowing a + variable. + * include/grub/i386/loader.h: Change declaration of + grub_linux_boot() to match what grub_loader_set() expects. + * util/getroot.c (grub_guess_root_device): Return const char* to + fix a warning. + * util/grub-probe.c (probe): Fix a warning about uninitialized + abstraction_name variable. + * util/i386/get_disk_name.c (grub_util_get_disk_name): Mark + second argument as unused to fix a warning. + + * loader/i386/pc/multiboot2.c (grub_mb2_arch_elf64_hook): Add + missing grub_error() call. + + * util/update-grub_lib.in: Define datarootdir, since Autoconf + 2.60 and newer uses it to define datadir. + + * commands/sleep.c: Fix warning about implicit declaration. + * disk/memdisk.c: Likewise. + * loader/aout.c: Likewise. + * loader/i386/bsd_normal.c: Likewise. + * util/grub-probe.c: Likewise. + + * commands/i386/cpuid.c (has_longmode): Make static. + * disk/i386/pc/biosdisk.c (cd_drive): Likewise. + * include/grub/i386/bsd.h (bios_memmap_t): Remove, it's unused. + + * kern/i386/pc/startup.S (real_to_prot): Use %cs prefix to load + GDT. This is more robust, as %ds can change. + (grub_biosdisk_rw_int13_extensions): Don't clear %ds before + calling real_to_prot(). + (grub_biosdisk_get_diskinfo_int13_extensions): Likewise. + +2008-03-28 Pavel Roskin + + * kern/i386/pc/startup.S: Assert that uncompressed functions + don't spill beyond GRUB_KERNEL_MACHINE_RAW_SIZE. + * kern/i386/pc/lzo1x.S: Remove all .align directives in the + code, as they push parts of the code (error handlers) beyond + GRUB_KERNEL_MACHINE_RAW_SIZE. Speed is not as important in this + code as correctness and size. + +2008-03-28 Pavel Roskin + + * kern/i386/pc/startup.S + (grub_biosdisk_get_diskinfo_int13_extensions): When converting + data block address to the real mode, keep offset minimal. This + works around a bug in AWARD BIOS on old Athlon systems, which + makes CD detection hang. + +2008-03-26 Pavel Roskin + + * normal/color.c (grub_parse_color_name_pair): Make `name' a + const. + * include/grub/normal.h: Add grub_parse_color_name_pair() + declaration. + +2008-03-24 Bean + + * disk/i386/pc/biosdisk.c (cd_start): Removed. + (cd_count): Removed. + (cd_drive): New variable. + (grub_biosdisk_get_drive): Don't check for (cdN) device. + (grub_biosdisk_call_hook): Likewise. + (grub_biosdisk_iterate): Change cdrom detection method. + (grub_biosdisk_open): Replace cd_start with cd_drive. + (GRUB_MOD_INIT): Use grub_biosdisk_get_cdinfo_int13_extension to + detect cdrom device. + + * include/grub/i386/pc/biosdisk.h (GRUB_BIOSDISK_MACHINE_CDROM_START): + Removed. + (GRUB_BIOSDISK_MACHINE_CDROM_END): Removed. + (GRUB_BIOSDISK_CDTYPE_NO_EMUL): New macro. + (GRUB_BIOSDISK_CDTYPE_1_2_M): Likewise. + (GRUB_BIOSDISK_CDTYPE_1_44_M): Likewise. + (GRUB_BIOSDISK_CDTYPE_2_88_M): Likewise. + (GRUB_BIOSDISK_CDTYPE_HARDDISK): Likewise. + (GRUB_BIOSDISK_CDTYPE_MASK): Likewise. + (grub_biosdisk_cdrp): New structure. + (grub_biosdisk_get_cdinfo_int13_extensions): New function. + + * include/grub/i386/pc/kernel.h (grub_boot_drive): Export this variable. + + * kern/i386/pc/init.c (make_install_device): Don't use (cdN) as root + device. + + * kern/i386/pc/startup.S (grub_biosdisk_get_cdinfo_int13_extensions): + New function. + +2008-03-20 Robert Millan + + Remove 2 TiB limit in ata.mod. + * disk/ata.c (grub_ata_device): Promote `size' to grub_uint64_t. + (grub_ata_dumpinfo): Print sector count with 0x%llx. + (grub_ata_identify): Interpret `&info16[100]' as a pointer to + grub_uint64_t instead of grub_uint32_t. + +2008-03-05 Bean + + * loader/i386/pc/multiboot.c (grub_multiboot_get_bootdev): New function. + (grub_multiboot): Set boot device. + + * boot/i386/pc/lnxboot.S (real_code_2): Set %dh to 0xFF. + +2008-03-02 Bean + + * fs/reiserfs.c (grub_reiserfs_read_symlink): Add 0 at the end of + symlink_buffer. + +2008-03-01 Yoshinori K. Okuji + + * DISTLIST: Added docs/fdl.texi, docs/grub.texi, docs/mdate-sh and + texinfo.tex. + + * docs/grub.texi: New file. Copied from GRUB Legacy, and slightly + modified. + + * docs/fdl.texi: New file. + + * docs/mdate-sh: New file. Copied from gnulib. + * docs/texinfo.tex: Likewise. + + * config.guess: Updated from gnulib. + * install-sh: Likewise. + +2008-02-28 Robert Millan + + * conf/i386-linuxbios.rmk (pkglib_MODULES): Add aout.mod. + (aout_mod_SOURCES): New variable. + (aout_mod_CFLAGS): Likewise. + (aout_mod_LDFLAGS): Likewise. + + * conf/i386-ieee1275.rmk: Likewise. + +2008-02-28 Robert Millan + + * util/update-grub.in: Reorganise terminal validity check. Accept + `ieee1275:console' (OLPC) and `*:gfxterm' as valid too. + Based on suggestion by Franklin PIAT. + +2008-02-28 Fabian Greffrath + + * include/grub/util/getroot.h (grub_util_check_block_device): Export new + function. + * util/getroot.c (grub_util_check_block_device): New function that + returns the given argument if it is a block device and returns NULL else. + * util/grub-probe.c (argument_is_device): New variable. + (probe): Promote device_name from a variable to an argument. Receive + device_name from grub_util_check_block_device() if path is NULL and from + grub_guess_root_device() else. Do not free() device_name anymore. + (options): Introduce new parameter '-d, --device'. + (main): Add description of the new parameter to the help screen. + Rename path variable to argument. Set argument_is_device if the '-d' + option is given. Pass argument to probe() depending on + argument_is_device. + +2008-02-24 Bean + + * fs/iso9660.c (GRUB_ISO9660_VOLDESC_BOOT): New macro. + (GRUB_ISO9660_VOLDESC_PRIMARY): Likewise. + (GRUB_ISO9660_VOLDESC_SUPP): Likewise. + (GRUB_ISO9660_VOLDESC_PART): Likewise. + (GRUB_ISO9660_VOLDESC_END): Likewise. + (grub_iso9660_primary_voldesc): New member escape. + (grub_iso9660_data): New member joliet. + (grub_iso9660_convert_string): New function. + (grub_iso9660_mount): Detect joliet extension. + (grub_iso9660_iterate_dir): Convert filename when joliet is detected. + (grub_iso9660_iso9660_label): Likewise. + + * conf/common.rmk (pkgdata_MODULES): Add udf.mod. + (grub_setup_SOURCES): Add fs/udf.c. + (grub_fstest_SOURCES): Likewise. + (udf_mod_SOURCES): New variable. + (udf_mod_CFLAGS): Likewise. + (udf_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/udf.c. + (grub_emu_SOURCES): Likewise. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * fs/udf.c: New file. + +2008-02-24 Robert Millan + + * conf/i386-efi.rmk (normal/function.c_DEPENDENCIES) + (normal/lexer.c_DEPENDENCIES): New variables. + * conf/i386-ieee1275.rmk (normal/function.c_DEPENDENCIES) + (normal/lexer.c_DEPENDENCIES): Likewise. + * conf/i386-linuxbios.rmk (normal/function.c_DEPENDENCIES) + (normal/lexer.c_DEPENDENCIES): Likewise. + * conf/i386-pc.rmk (normal/function.c_DEPENDENCIES) + (normal/lexer.c_DEPENDENCIES): Likewise. + * conf/powerpc-ieee1275.rmk (normal/function.c_DEPENDENCIES) + (normal/lexer.c_DEPENDENCIES): Likewise. + * conf/sparc64-ieee1275.rmk (normal/function.c_DEPENDENCIES) + (normal/lexer.c_DEPENDENCIES): Likewise. + +2008-02-23 Robert Millan + + * partmap/gpt.c (grub_gpt_magic): Add `0x' qualifier to each member, + since they were intended to be in hex. This didn't break previously + because of a bug in gpt_partition_map_iterate() (see below). + + (gpt_partition_map_iterate): Replace `grub_memcmp' with `! grub_memcmp' + when checking the validity of GPT header. + Remove `partno', since it always provides the same information as `i'. + +2008-02-21 Yoshinori K. Okuji + + * include/grub/efi/time.h: Fix a wrong comment. + +2008-02-19 Pavel Roskin + + * kern/rescue.c (grub_enter_rescue_mode): Improve initial + message. + +2008-02-19 Bean + + * conf/i386-pc.rmk (pkglib_MODULES): Add aout.mod _bsd.mod and bsd.mod. + (aout_mod_SOURCES): New variable. + (aout_mod_CFLAGS): Likewise. + (aout_mod_LDFLAGS): Likewise. + (_bsd_mod_SOURCES): New variable. + (_bsd_mod_CFLAGS): Likewise. + (_bsd_mod_LDFLAGS): Likewise. + (bsd_mod_SOURCES): New variable. + (bsd_mod_CFLAGS): Likewise. + (bsd_mod_LDFLAGS): Likewise. + + * include/grub/aout.h: New file. + + * include/grub/i386/loader.h (grub_unix_real_boot): New function. + + * include/grub/i386/bsd.h: New file. + + * include/grub/i386/pc/init.h (grub_get_mmap_entry): Use EXPORT_FUNC + to make it public. + + * kern/elf.c (grub_elf32_load): Get the physical address after the hook + function is called, so that it's possible to change it inside the hook. + (grub_elf64_load): Likewise. + (grub_elf_file): Don't close the file if elf header is not found. + (grub_elf_close): Close the file if grub_elf_file fails (The new + grub_elf_file won't close it). + (grub_elf32_size): Use NESTED_FUNC_ATTR for nested function calcsize. + (grub_elf64_size): Likewise. + + * kern/i386/loader.S (grub_unix_real_boot): New function. + + * loader/aout.c: New file. + + * loader/i386/bsd.c: New file. + + * loader/i386/bsd_normal.c: New file. + + * loader/i386/pc/multiboot.c (grub_multiboot): Handle a.out format. + + * loader/multiboot2.c (grub_multiboot2): Reset grub_errno so that it + can test other formats. + +2008-02-19 Robert Millan + + * partmap/gpt.c: Include `'. + (grub_gpt_partition_type_empty): Redefine with macro from + `'. + (gpt_partition_map_iterate): Adjust partition type comparison. + + Export `entry' as partmap-specific `part.data' struct. + (grub_gpt_header, grub_gpt_partentry): Move from here ... + + * include/grub/gpt_partition.h (grub_gpt_header) + (grub_gpt_partentry): ... to here (new file). + + * util/i386/pc/grub-setup.c: Include `'. + + (grub_gpt_partition_type_bios_boot): New const variable, defined + with macro from `'. + + (setup): Replace `first_start' with `embed_region', which keeps + track of the embed region (and is partmap-agnostic). + + Replace find_first_partition_start() with find_usable_region(), + which finds a usable region for embedding using partmap-specific + knowledge (supports PC/MSDOS and GPT). + + Fix all assumptions that the embed region start at sector 1, using + `embed_region.start' from now on. Similarly, use `embed_region.end' + rather than `first_start' to calculate available size. + + In grub_util_info() message, replace "into after the MBR" with an + indication of the specific sector our embed region starts at. + +2008-02-19 Robert Millan + + * DISTLIST: Replace `commands/ieee1275/halt.c' and + `commands/ieee1275/reboot.c' with `commands/halt.c' and + `commands/reboot.c'. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES, reboot_mod_SOURCES) + (halt_mod_SOURCES): Likewise. + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES, reboot_mod_SOURCES) + (halt_mod_SOURCES): Likewise. + +2008-02-17 Christian Franke + + * commands/cat.c (grub_cmd_cat): Add break on GRUB_TERM_ESC key. + +2008-02-17 Robert Millan + + * util/i386/pc/grub-setup.c (setup): In find_first_partition_start(), + set `first_start' to 0 for non-PC/MSDOS partition maps. + +2008-02-16 Robert Millan + + * util/i386/pc/grub-setup.c (setup): In find_first_partition_start(), + do not assume partition map is PC/MSDOS before performing checks that + are specific to that layout. + +2008-02-13 Robert Millan + + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Remove + `commands/i386/pc/halt.c' and `commands/i386/pc/reboot.c'. + * kern/i386/linuxbios/init.c (grub_halt, grub_reboot): Remove stubs. + +2008-02-13 Yoshinori K. Okuji + + * configure.ac: Only a cosmetic change on the handling of + -fno-stack-protector. + +2008-02-12 Alexandre Boeglin + + * conf/i386-efi.rmk (grub_emu_SOURCES): Replace + commands/i386/pc/halt.c and reboot.c by commands/halt.c and + reboot.c. + (grub_install_SOURCES): Add halt.mod and reboot.mod. + (halt_mod_SOURCES): New variable. + (halt_mod_CFLAGS): Likewise. + (halt_mod_LDFLAGS): Likewise. + (reboot_mod_SOURCES): Likewise. + (reboot_mod_CFLAGS): Likewise. + (reboot_mod_LDFLAGS): Likewise. + + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Replace + commands/ieee1275/halt.c and reboot.c by commands/halt.c and + reboot.c. + (halt_mod_SOURCES): Likewise. + (reboot_mod_SOURCES): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Replace + commands/i386/pc/reboot.c by commands/reboot.c. + (reboot_mod_SOURCES): Likewise. + + * commands/i386/pc/reboot.c: merge this file ... + + * commands/ieee1275/reboot.c: ... and this file ... + + * commands/reboot.c: ... to this file. + Add some precompiler directive to include the correct header for + each machine. + + * commands/ieee1275/halt.c: move this file ... + + * commands/halt.c: ... to here. + Add some precompiler directive to include the correct header for + each machine. + + * include/grub/efi/efi.h (grub_reboot): New function declaration. + (grub_halt): Likewise. + + * kern/efi/efi.c (grub_reboot): New function. + (grub_halt): Likewise. + +2008-02-12 Robert Millan + + * util/getroot.c (grub_guess_root_device): Inspect /dev/evms before + /dev (like it is done for /dev/mapper). This doesn't provide support + for EVMS, but at least it is now easy to identify the problem when it + arises. + +2008-02-11 Robert Millan + + * util/biosdisk.c (grub_util_biosdisk_open, linux_find_partition) + (grub_util_biosdisk_get_grub_dev): Check open() exit status by + comparing it with -1, not 0. + +2008-02-10 Robert Millan + + * conf/i386-efi.rmk (grub_emu_SOURCES): Add `disk/raid.c' and + `disk/lvm.c'. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-pc.rmk (grub_setup_SOURCES): Likewise. + + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Move `disk/raid.c' and + `disk/lvm.c' to the end of the list. + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-pc.rmk (grub_emu_SOURCES): Likewise. + +2008-02-10 Robert Millan + + * kern/main.c (grub_load_normal_mode): Do not reset `grub_errno'. Call + grub_print_error() instead. This will let user know why we're entering + rescue mode. + Based on suggestions from Sam Morris. + +2008-02-10 Alexandre Boeglin + + * normal/arg.c (grub_arg_parse): If one of the args is "--", call add_arg() + on remaining N args, instead of "--" arg N times. + +2008-02-09 Vesa Jaaskelainen + + * font/manager.c (unknown_glyph): Added variable for unknown glyph. + (fill_with_default_glyph): Changed to use unknown_glyph for fill + pattern for unknown glyphs. + +2008-02-09 Robert Millan + + * configure.ac: Probe for `help2man'. + * Makefile.in (builddir): New variable. + (HELP2MAN): Likewise. Set to `true' when @HELP2MAN@ doesn't provide it, + or otherwise add a few flags/options to it. + (install-local): For every executable utility or script that is + installed, invoke $(HELP2MAN) to install a manpage based on --help + output. + + * util/i386/pc/grub-install.in: Move down `update-grub_lib' sourcing, so + that it doesn't prevent --help from working in build tree. + + * util/i386/pc/grub-mkrescue.in (usage): Replace `grub-devel@gnu.org' + with `bug-grub@gnu.org'. + * util/powerpc/ieee1275/grub-mkrescue.in (usage): Likewise. + * util/update-grub.in (usage): New function. + Implement proper argument check, with support for --help and --version + (as well as existing -y). + +2008-02-09 Christian Franke + + * commands/cat.c (grub_cmd_cat): Print '\r' as hex to + avoid overwriting previous output. + * kern/rescue.c (grub_rescue_cmd_cat): Likewise. + +2008-02-09 Robert Millan + + * normal/menu.c (run_menu): If timeout is set to zero, don't bother + drawing the menu. + +2008-02-09 Robert Millan + + * commands/sleep.c: New file. + * conf/common.rmk (pkglib_MODULES): Add `commands/sleep.c'. + (sleep_mod_SOURCES): New variable. + (sleep_mod_CFLAGS): Likewise. + (sleep_mod_LDFLAGS): Likewise. + +2008-02-09 Robert Millan + + * disk/raid.c (grub_raid_scan_device): Add a pair of sanity checks for + situations in which we can deduce the RAID size and the superblock + doesn't match it. + +2008-02-09 Robert Millan + + * disk/lvm.c [GRUB_UTIL] (grub_lvm_memberlist): New function. Construct + and return a grub_diskmemberlist_t composed of LVM physical volumes. + [GRUB_UTIL] (grub_lvm_dev): Add `memberlist' member. + + * disk/raid.c [GRUB_UTIL] (grub_raid_memberlist): New function. Construct + and return a grub_diskmemberlist_t composed of physical array members. + [GRUB_UTIL] (grub_raid_dev): Add `memberlist' member. + + * include/grub/disk.h [GRUB_UTIL] (grub_disk_memberlist): New struct + prototype. + [GRUB_UTIL] (struct grub_disk_dev): Add `memberlist' function pointer. + [GRUB_UTIL] (struct grub_disk_memberlist): New struct declaration. + [GRUB_UTIL] (grub_disk_memberlist_t): New typedef. + + * util/grub-probe.c (probe): Move partmap probing code from here ... + (probe_partmap): ... to here. + (probe): Use probe_partmap() once for the disk we're probing, and + additionally, when such disk contains a memberlist() struct member, + once for each disk that is contained in the structure returned by + memberlist(). + +2008-02-09 Robert Millan + + * util/grub-probe.c (main): When `verbosity > 1', set `debug' + environment variable to 'all' in order to obtain debug output from + non-util/ code. + * util/i386/pc/grub-setup.c (main): Likewise. + +2008-02-08 Robert Millan + + * disk/raid.c (grub_raid_scan_device): Check for + `array->device[sb.this_disk.number]' rather than for + `array->device[sb.this_disk.number]->name', since the latter is not + guaranteed to be accessible. + +2008-02-08 Robert Millan + + * disk/raid.c: Update copyright. + * fs/cpio.c: Likewise. + * include/grub/raid.h: Likewise. + * loader/i386/pc/multiboot.c: Likewise. + * util/hostfs.c: Likewise. + +2008-02-08 Robert Millan + + * include/grub/raid.h (struct grub_raid_array): Change type of `device' + to a grub_disk_t array. + * disk/raid.c (grub_raid_read): Replace `device[x].disk' accesses with + `device[x]'. + (grub_raid_scan_device): Replace `device[x].name' accesses with + `device[x]->name'. Simplify initialization of `array->device[x]'. + +2008-02-08 Robert Millan + + * disk/raid.c (grub_raid_open, grub_raid_scan_device): Add a few + grub_dprintf() calls. + * kern/disk.c (grub_disk_read): Include grub_errmsg in out of range + error message. + +2008-02-07 Christian Franke + + * util/hostfs.c (grub_hostfs_open): Use fseeko and ftello + instead of fseek and ftell to support large files. + (grub_hostfs_read): Likewise. + +2008-02-07 Robert Millan + + Patch from Jeroen Dekkers. + * disk/raid.c (grub_raid_scan_device): Reset `grub_errno' on disk + failure, since successfully reading all array members might not be + required. + +2008-02-06 Robert Millan + + * util/grub-probe.c (probe): Simplify partmap probing (with the + assumption that the first word up to the underscore equals to + the module name). + +2008-02-06 Christian Franke + + * fs/cpio.c (grub_cpio_find_file): Return GRUB_ERR_NONE + (and set *ofs = 0) instead of GRUB_ERR_FILE_NOT_FOUND on + last block of a cpio or tar stream. + Check for "TRAILER!!!" instead of any empty data + block to detect last block of a cpio stream. + (grub_cpio_dir): Fix constness of variable np. + (grub_cpio_open): Return GRUB_ERR_FILE_NOT_FOUND if + cpio or tar trailer is detected. This fixes a crash + on open of a non existing file. + +2008-02-05 Bean + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Get physical + address of entry. + (grub_multiboot_load_elf64): Likewise. + (grub_multiboot): Initialize mbi structure. + + * util/grub-fstest.c: Don't include unused header file script.h. + + * conf/common.rmk (grub-fstest.c_DEPENDENCIES): Move to the beginning + of file. + (grub_fstest_SOURCES): Likewise. + +2008-02-05 Robert Millan + + * include/grub/term.h (GRUB_TERM_LEFT, GRUB_TERM_RIGHT) + (GRUB_TERM_UP, GRUB_TERM_DOWN, GRUB_TERM_HOME, GRUB_TERM_END) + (GRUB_TERM_DC, GRUB_TERM_PPAGE, GRUB_TERM_NPAGE, GRUB_TERM_ESC) + (GRUB_TERM_TAB, GRUB_TERM_BACKSPACE): New macros. + + * kern/i386/pc/startup.S: Include `'. + (translation_table): Replace hardcoded values with macros + provided by `'. + + * term/i386/pc/at_keyboard.c: Include `'. + (keyboard_map): Correct/add a few values, with macros provided + by `'. + (keyboard_map_shift): Zero values that don't differ from their + `keyboard_map' equivalents. + (grub_console_checkkey): Optimize KEYBOARD_STATUS_CAPS_LOCK toggling. + Discard the second scan code that is always sent by Caps lock. + Only use `keyboard_map_shift' when it provides a non-zero value, + otherwise fallback to `keyboard_map'. + +2008-02-04 Bean + + * Makefile.in (enable_grub_fstest): New variable. + + * conf/common.rmk (grub_fstest_init.lst): New rule. + (grub_fstest_init.h): Likewise. + (grub_fstest_init.c): Likewise. + (util/grub-fstest.c_DEPENDENCIES): New variable. + (grub_fstest_SOURCES): Likewise. + + * configure.ac (enable_grub_fstest): Check for --enable-grub-fstest. + + * util/grub-fstest.c: New file. + +2008-02-03 Yoshinori K. Okuji + + Make grub-setup handle a separate root device. + + * util/i386/pc/grub-setup.c (setup): Always open the root device, + so that the root device can be compared with the destination + device. + When embedding the core image, if the root and destination devices + are different, set ROOT_DRIVE to ROOT_DEV->DISK->ID. Otherwise, to + 0xFF. + When not embedding, set ROOT_DRIVE to 0xFF. + +2008-02-03 Yoshinori K. Okuji + + Add support for having a grub directory in a different drive. This + is still only the data handling part. + + * kern/i386/pc/startup.S (multiboot_trampoline): Set %dh to 0xFF. + (codestart): Save %dh in GRUB_ROOT_DRIVE. + (grub_root_drive): New variable. + + * kern/i386/pc/init.c (make_install_device): Use GRUB_ROOT_DRIVE + instead of GRUB_BOOT_DRIVE to construct a device name. Set + GRUB_ROOT_DRIVE to GRUB_BOOT_DRIVE if it is 0xFF, otherwise use it + as it was. + + * include/grub/i386/pc/kernel.h (grub_root_drive): New prototype. + + * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_ROOT_DRIVE): New + macro. + (GRUB_BOOT_MACHINE_DRIVE_CHECK): Set to 0x4f. + + * boot/i386/pc/pxeboot.S (_start): Set %dh to 0xFF. For now, this + is bogus, because PXE booting does not specify any drive + correctly. + + * boot/i386/pc/lnxboot.S (reg_edx): Set the second byte to 0xFF. I + am not sure if this is really correct. + + * boot/i386/pc/cdboot.S: Set %dh to 0xFF, because the root drive + is always identical to the boot drive when booting from a CD. + + * boot/i386/pc/boot.S (MOV_MEM_TO_AL): Removed. Not needed any + longer. + (root_drive): New variable. + (real_start): Unconditionally set %dh to ROOT_DRIVE. + (setup_sectors): Push %dx right after popping it, because %dh will + be modified later. + (copy_buffer): Restore %dx. + +2008-02-03 Robert Millan + + * util/i386/pc/grub-mkrescue.in: Rewrite most of image generation to + use `cdboot.img' for cdrom images. + +2008-02-03 Robert Millan + + * util/grub.d/00_header.in: Issue scripting commands for GRUB to + only setup gfxterm when `font' command has succeeded. + +2008-02-03 Robert Millan + + * loader/multiboot_loader.c [GRUB_MACHINE_LINUXBIOS] + (grub_rescue_cmd_multiboot_loader) + (grub_rescue_cmd_module_loader): Enable multiboot1 calls. + +2008-02-03 Pavel Roskin + + * kern/i386/pc/startup.S (grub_chainloader_real_boot): Pop + %edx and %esi from stack only after grub_gate_a20() is called. + grub_gate_a20() clobbers %edx. + +2008-02-03 Yoshinori K. Okuji + + * configure.ac (AC_INIT): Bumped to 1.96. + + * DISTLIST: Added boot/i386/pc/cdboot.S, bus/pci.c, + commands/lspci.c,disk/memdisk.c, include/grub/pci.h, + include/grub/i386/pc/pci.h, video/readers/jpeg.c, and + video/readers/png.c. + +2008-02-03 Bean + + * conf/i386-pc.rmk (pkglib_IMAGES): Add cdboot.img. + (cdboot_img_SOURCES): New variable. + (cdboot_img_ASFLAGS): New variable. + (cdboot_img_LDFLAGS): New variable. + + * boot/i386/pc/cdboot.S: New file. + + * disk/i386/pc/biosdisk.c (cd_start): New variable. + (cd_count): Likewise. + (grub_biosdisk_get_drive): Add support for cd device. + (grub_biosdisk_call_hook): Likewise. + (grub_biosdisk_iterate): Likewise. + (grub_biosdisk_open): Likewise. + (GRUB_BIOSDISK_CDROM_RETRY_COUNT): New macro. + (grub_biosdisk_rw): Support reading from cd device. + (GRUB_MOD_INIT): Iterate cd devices. + + * include/grub/i386/pc/biosdisk.h (GRUB_BIOSDISK_FLAG_CDROM): New macro. + (GRUB_BIOSDISK_MACHINE_CDROM_START): Likewise. + (GRUB_BIOSDISK_MACHINE_CDROM_END): Likewise. + + * kern/i386/pc/init.c (make_install_device): Check for cd device. + +2008-02-02 Robert Millan + + * commands/read.c: New file. + * conf/common.rmk (pkglib_MODULES): Add `commands/read.c'. + (read_mod_SOURCES): New variable. + (read_mod_CFLAGS): Likewise. + (read_mod_LDFLAGS): Likewise. + +2008-02-02 Robert Millan + + * normal/main.c (grub_normal_execute): Check for `menu->size' when + determining whether menu has to be displayed. + +2008-02-02 Marco Gerards + + * bus/pci.c: New file. + + * include/grub/pci.h: Likewise. + + * include/grub/i386/pc/pci.h: Likewise. + + * commands/lspci.c: Likewise. + + * conf/i386-pc.rmk (pkglib_MODULES): Add `pci.mod' and + `lspci.mod'. + (pci_mod_SOURCES): New variable. + (pci_mod_CFLAGS): Likewise. + (pci_mod_LDFLAGS): Likewise. + (lspci_mod_SOURCES): Likewise. + (lspci_mod_CFLAGS): Likewise. + (lspci_mod_LDFLAGS): Likewise. + +2008-02-02 Bean + + * fs/ufs.c (INODE_BLKSZ): Fix incorrect value. + (grub_ufs_get_file_block): Fix indirect block calculation problem. + + * fs/xfs.c (grub_xfs_sblock): New member log2_dirblk. + (grub_xfs_btree_node): New structure. + (grub_xfs_btree_root): New structure. + (grub_xfs_inode): New members nblocks, extsize, nextents and btree. + (GRUB_XFS_EXTENT_OFFSET): Use exts instead of inode->data.extents. + (GRUB_XFS_EXTENT_BLOCK): Likewise. + (GRUB_XFS_EXTENT_SIZE): Likewise. + (grub_xfs_read_block): Support btree format type. + (grub_xfs_iterate_dir): Use NESTED_FUNC_ATTR in call_hook. + Use directory block as basic unit. + + * fs/fshelp.c (grub_fshelp_read_file): Bug fix for sparse block. + + * aclocal.m4 (grub_i386_CHECK_REGPARM_BUG): Define NESTED_FUNC_ATTR as + __attribute__ ((__regparm__ (1))). + +2008-02-01 Robert Millan + + Correct a mistake in previous commit. + + * conf/i386-pc.rmk (normal/execute.c_DEPENDENCIES): Move to the + top. + (normal/command.c_DEPENDENCIES): New variable. + +2008-02-01 Robert Millan + + * conf/i386-efi.rmk (normal/execute.c_DEPENDENCIES): Move to the + top. + (normal/command.c_DEPENDENCIES): New variable. + (grub-emu_DEPENDENCIES, normal_mod_DEPENDENCIES): Remove variables. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-linuxbios.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + (grub_emu_SOURCES): Add `fs/fshelp.c'. + + * genmk.rb: Add `$(#{src}_DEPENDENCIES)' in targets that require it. + +2008-02-01 Robert Millan + + * kern/disk.c (grub_disk_read, grub_disk_write): Add grub_dprintf() + call at beginning of function. + +2008-01-31 Pavel Roskin + + * util/powerpc/ieee1275/grub-mkrescue.in: New file. + * conf/powerpc-ieee1275.rmk (bin_SCRIPTS): New variable. + (grub_mkrescue_SOURCES): Likewise. + * DISTLIST: Add util/powerpc/ieee1275/grub-mkrescue.in. + +2008-01-30 Robert Millan + + * conf/i386-pc.rmk (sbin_UTILITIES): Remove `grub-probe'. + (util/grub-probe.c_DEPENDENCIES, grub_probe_SOURCES): Moved from here ... + * conf/common.rmk (util/grub-probe.c_DEPENDENCIES) + (grub_probe_SOURCES): ... to here. + + * conf/i386-efi.rmk (sbin_UTILITIES): Remove `grub-probe'. + (util/grub-probe.c_DEPENDENCIES, grub_probe_SOURCES): Remove. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-linuxbios.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + +2008-01-30 Tristan Gingold + + * kern/rescue.c: Silently accept empty lines. + +2008-01-29 Bean + + * boot/i386/pc/lnxboot.S (data_start): Code cleanup. + (real_code_2): Code cleanup and change comment style. + (move_memory): Avoid using 32-bit address mode. + +2008-01-29 Bean + + * conf/i386-pc.rmk (pkglib_MODULES): Add `png.mod'. + (png_mod_SOURCES): New variable. + (png_mod_CFLAGS): Likewise. + (png_mod_LDFLAGS): Likewise. + + * video/readers/png.c: New file. + +2008-01-28 Robert Millan + + * include/grub/i386/linuxbios/kernel.h (GRUB_MOD_GAP): New macro. + * kern/powerpc/ieee1275/init.c (grub_arch_modules_addr): Remove + `ifndef GRUB_MOD_GAP' hack. + * util/elf/grub-mkimage.c (add_segments): Likewise. + +2008-01-27 Robert Millan + + * kern/powerpc/ieee1275/init.c (grub_arch_modules_addr): Skip + `GRUB_MOD_GAP' for platforms in which it's not defined. + * util/elf/grub-mkimage.c (add_segments): Likewise. + +2008-01-27 Robert Millan + + Get grub-emu to build again (including parallel builds). + + * conf/i386-pc.rmk (util/grub-emu.c_DEPENDENCIES): Remove variable. + Split into ... + (util/grub-emu.c_DEPENDENCIES): ... this, ... + (normal/execute.c_DEPENDENCIES): ... this, ... + (grub-emu_DEPENDENCIES): ... and this. + + * conf/i386-efi.rmk: Likewise. + * conf/i386-linuxbios.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + (grub_emu_SOURCES): Remove duplicated `kern/file.c'. + +2008-01-27 Robert Millan + + * NEWS: Add a few items. + +2008-01-27 Robert Millan + + Fix parallel builds with grub-emu. Based on earlier commit for + grub-probe and grub-setup. + + * conf/i386-pc.rmk (grub-emu_DEPENDENCIES): Renamed to ... + (util/grub-emu.c_DEPENDENCIES): ... this. + * conf/i386-efi.rmk (grub-emu_DEPENDENCIES): Renamed to ... + (util/grub-emu.c_DEPENDENCIES): ... this. + * conf/i386-linuxbios.rmk (grub-emu_DEPENDENCIES): Renamed to ... + (util/grub-emu.c_DEPENDENCIES): ... this. + * conf/i386-ieee1275.rmk (grub-emu_DEPENDENCIES): Renamed to ... + (util/grub-emu.c_DEPENDENCIES): ... this. + * conf/powerpc-ieee1275.rmk (grub-emu_DEPENDENCIES): Renamed to ... + (util/grub-emu.c_DEPENDENCIES): ... this. + +2008-01-27 Pavel Roskin + + * include/grub/powerpc/ieee1275/kernel.h: Introduce GRUB_MOD_GAP + to create a gap between _end and the modules added to the image + with grub-mkrescue. That fixes "CLAIM failed" on PowerMAC. + * kern/powerpc/ieee1275/init.c: Use GRUB_MOD_GAP. + * util/elf/grub-mkimage.c (add_segments): Likewise. + +2008-01-26 Pavel Roskin + + * kern/dl.c (grub_dl_load): Don't abort if prefix is not set, + just return an error. + +2008-01-26 Bean + + * fs/reiserfs.c (grub_fshelp_node): New member next_offset. + (grub_reiserfs_get_item): Save offset of the next item. + (grub_reiserfs_iterate_dir): Use next_offset to find next item. + +2008-01-25 Robert Millan + + * conf/i386-pc.rmk (grub_setup_SOURCES, grub_emu_SOURCES): Regroup to + make all filesystem sources appear together (possibly fixing omissions + while at it). + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-pc.rmk (grub_probe_SOURCES): Likewise. Additionally, + add `kern/file.c'. + * conf/i386-efi.rmk (grub_probe_SOURCES): Likewise. + * conf/i386-ieee1275.rmk (grub_probe_SOURCES): Likewise. + * conf/i386-linuxbios.rmk (grub_probe_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_probe_SOURCES): Likewise. + + * util/grub-probe.c: Include `' and `'. + (probe): Add a sanity check to make sure of our ability to read + requested files when probing for filesystem type. + + * genmk.rb: Update copyright year (2007). + + * include/grub/fs.h (grub_fat_init, grub_fat_fini, grub_ext2_init) + (grub_ext2_fini, grub_ufs_init, grub_ufs_fini, grub_minix_init) + (grub_minix_fini, grub_hfs_init, grub_hfs_fini, grub_jfs_init) + (grub_jfs_fini, grub_xfs_init, grub_xfs_fini, grub_affs_init) + (grub_affs_fini, grub_sfs_init, grub_sfs_fini, grub_iso9660_init) + : Remove function prototypes. + +2008-01-25 Robert Millan + + Revert my previous commits (based on wrong assumption of how grub_errno + works). + + * kern/disk.c (grub_disk_open): Stop resetting grub_errno. + * kern/file.c (grub_file_open): Likewise. + +2008-01-24 Pavel Roskin + + * include/grub/ieee1275/ieee1275.h: Introduce flag for firmwares + that hang if GRUB tries to setup colors. + * term/ieee1275/ofconsole.c (grub_ofconsole_init): Don't set + colors for firmwares that don't support it. + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_set_flag): + Recognize Open Hack'Ware, set flags to work around its + limitations. + +2008-01-24 Robert Millan + + * kern/file.c (grub_file_open): Do not account previous failures of + unrelated functions when grub_errno is checked for. + Reported by Oleg Strikov. + +2008-01-24 Bean + + * fs/ufs.c (GRUB_UFS_VOLNAME_LEN): New macro. + (grub_ufs_sblock): New member volume name. + (grub_ufs_find_file): Fix string copy bug. + (grub_ufs_label): Implement this function properly. + + * fs/hfs.c (grub_hfs_cnid_type): New enum. + (grub_hfs_iterate_records): Use the correct file number for extents + and catalog file. Fix problem in next index calculation. + (grub_hfs_find_node): Replace recursive function call with loop. + (grub_hfs_iterate_dir): Replace recursive function call with loop. + +2008-01-23 Robert Millan + + * include/grub/i386/ieee1275/loader.h: Include `', + `' and `'. + (grub_multiboot2_real_boot): New function prototype. + + * include/grub/i386/pc/memory.h: Include `'. + [!GRUB_MACHINE_IEEE1275] (grub_lower_mem, grub_upper_mem): Disable. + + * kern/i386/ieee1275/init.c (grub_os_area_addr) + (grub_os_area_size, grub_lower_mem, grub_upper_mem): Remove variables. + +2008-01-23 Robert Millan + + * kern/mm.c (grub_mm_init_region): Replace grub_dprintf() call with + #ifdef'ed out grub_printf(). + +2008-01-23 Robert Millan + + * term/i386/pc/at_keyboard.c (grub_keyboard_isr): #ifdef out + grub_dprintf calls, since they make "debug=all" mode unusable. + (grub_console_checkkey): Likewise. + +2008-01-23 Robert Millan + + * conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Add + `term/i386/pc/at_keyboard.c'. + (pkglib_MODULES): Add `serial.mod'. + (serial_mod_SOURCES): New variable. + (serial_mod_CFLAGS): Likewise. + (serial_mod_LDFLAGS): Likewise. + + * include/grub/i386/ieee1275/console.h: Add `'. Remove + `'. + (grub_keyboard_controller_init): New function prototype. + (grub_console_checkkey): Likewise. + (grub_console_getkey): Likewise. + + * kern/powerpc/ieee1275/init.c (grub_machine_init): Initialize AT + keyboard on i386. + + * term/ieee1275/ofconsole.c (grub_ofconsole_term): On i386, use + grub_ofconsole_checkkey() and grub_ofconsole_getkey() for input. + +2008-01-23 Robert Millan + + * kern/i386/pc/init.c (make_install_device): When memdisk image is + present, "(memdisk)/boot/grub" becomes the default prefix. + + * util/i386/pc/grub-mkrescue.in: Switch to a minimal core.img plus + a memdisk tarball with all the modules. Add --overlay=DIR option that + allows users to overlay additional files into the image. + +2008-01-23 Robert Millan + + * conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Add `machine/loader.h' + and `machine/memory.h'. + (pkglib_MODULES): Add `multiboot.mod' and `_multiboot.mod'. + (_multiboot_mod_SOURCES): New variable. + (_multiboot_mod_CFLAGS): Likewise. + (_multiboot_mod_LDFLAGS): Likewise. + (multiboot_mod_SOURCES): Likewise. + (multiboot_mod_CFLAGS): Likewise. + (multiboot_mod_LDFLAGS): Likewise. + + * include/grub/i386/ieee1275/loader.h: New file. + + * include/grub/i386/ieee1275/machine.h: Likewise. + + * include/grub/i386/ieee1275/memory.h: Likewise. + + * include/grub/i386/pc/init.h (grub_os_area_addr): Remove (redundant) + variable declaration. + (grub_os_area_size): Likewise. + + * kern/i386/ieee1275/init.c (grub_os_area_addr, grub_os_area_size) + (grub_lower_mem, grub_upper_mem): New variables. + (grub_stop_floppy): New function (just to make + grub_multiboot2_real_boot() happy). + + * kern/i386/ieee1275/startup.S: Include `', + `', `' and `'. + (grub_stop): New function. + Include `"../realmode.S"' and `"../loader.S"'. + + * loader/multiboot_loader.c: Include `'. + Replace `__i386__' #ifdefs with `GRUB_MACHINE_PCBIOS'. + + * loader/powerpc/ieee1275/multiboot2.c (grub_mb2_arch_boot): On i386, + rely on grub_multiboot2_real_boot() for final boot. + +2008-01-22 Robert Millan + + * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): When + `GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY' flag is set, skip any + device that doesn't look like an SD card. + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): Add + `GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY' flag. + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_set_flag): Detect + OLPC laptop, and set `GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY' when + found. + +2008-01-22 Robert Millan + + * kern/powerpc/ieee1275/init.c (grub_claim_heap): Add sanity check to + avoid claiming over our own code. + +2008-01-22 Bean + + * conf/i386-pc.rmk (pkglib_MODULES): Add `jpeg.mod'. + (jpeg_mod_SOURCES): New variable. + (jpeg_mod_CFLAGS): Likewise. + (jpeg_mod_LDFLAGS): Likewise. + + * video/readers/jpeg.c : New file. + +2008-01-22 Bean + + * fs/cpio.c (grub_cpio_find_file): Return GRUB_ERR_FILE_NOT_FOUND when + there are no more items. + +2008-01-21 Robert Millan + + * kern/mm.c (grub_mm_init_region): Improve debug message. + +2008-01-21 Robert Millan + + * conf/i386-pc.rmk (GRUB_MEMORY_MACHINE_LINK_ADDR): New variable. + (kernel_img_LDFLAGS): Use `GRUB_MEMORY_MACHINE_LINK_ADDR' as link + address. + (grub_mkimage_CFLAGS): Propagate `GRUB_MEMORY_MACHINE_LINK_ADDR' as + a C macro. + * include/grub/i386/pc/memory.h (GRUB_MEMORY_MACHINE_UPPER): New macro. + Indicates start of upper memory. + * util/i386/pc/grub-mkimage.c: Include `'. + (generate_image): Abort when image size is big enough to corrupt + upper memory. + + * include/grub/i386/pc/vga.h: Include `'. + (GRUB_MEMORY_MACHINE_VGA_ADDR): Alias for `GRUB_MEMORY_MACHINE_UPPER'. + * term/i386/pc/vga.c (VGA_MEM): Use `GRUB_MEMORY_MACHINE_VGA_ADDR' + instead of hardcoding 0xA0000. + * video/i386/pc/vbe.c: Include `'. + (grub_vbe_set_video_mode): Use `GRUB_MEMORY_MACHINE_VGA_ADDR' + instead of hardcoding 0xA0000. + +2008-01-21 Robert Millan + + * disk/memdisk.c (memdisk_size): New variable. + (grub_memdisk_open): Replace grub_arch_memdisk_size() call with + `memdisk_size'. + (grub_memdisk_init): Initialize `memdisk_size'. Reallocate memdisk + image to dynamic memory. + (grub_memdisk_fini): Replace grub_arch_memdisk_size() call with + `memdisk_size'. Free memdisk block. + +2008-01-21 Robert Millan + + Fix detection of very small filesystems (like tar). + + * fs/reiserfs.c (grub_reiserfs_mount): When disk is too small to + contain a ReiserFS, abort with GRUB_ERR_BAD_FS rather than + GRUB_ERR_OUT_OF_RANGE (which made the upper layer think there's + a problem with this disk). + +2008-01-21 Robert Millan + + * disk/i386/pc/biosdisk.c (grub_biosdisk_iterate): Add debug message + on grub_biosdisk_rw_standard() error. + +2008-01-21 Robert Millan + + * include/grub/ieee1275/ieee1275.h: Add 2008 to Copyright line for + recent changes. + * kern/elf.c: Likewise. + * kern/ieee1275/ieee1275.c: Likewise. + * kern/powerpc/ieee1275/openfw.c: Likewise. + * term/ieee1275/ofconsole.c: Likewise. + +2008-01-21 Robert Millan + + * include/grub/i386/pc/kernel.h: Include `'. + + * include/grub/kernel.h (grub_arch_memdisk_addr) + (grub_arch_memdisk_size): Moved from here ... + + * include/grub/i386/pc/kernel.h (grub_arch_memdisk_addr) + (grub_arch_memdisk_size): ... to here. + +2008-01-21 Robert Millan + + Mostly based on bugfix from Bean. + + * kern/elf.c (grub_elf32_phdr_iterate): Use `NESTED_FUNC_ATTR' + attribute with hook() parameter. + (grub_elf32_load): Use `NESTED_FUNC_ATTR' with grub_elf32_load_segment() + declaration. + (grub_elf64_phdr_iterate): Use `NESTED_FUNC_ATTR' + attribute with hook() parameter. + (grub_elf64_load): Use `NESTED_FUNC_ATTR' with grub_elf64_load_segment() + declaration. + +2008-01-21 Robert Millan + + * conf/i386-pc.rmk (kernel_img_HEADERS): Add `machine/kernel.h'. + (pkglib_MODULES): Add `memdisk.mod'. + (memdisk_mod_SOURCES): New variable. + (memdisk_mod_CFLAGS): Likewise. + (memdisk_mod_LDFLAGS): Likewise. + + * disk/memdisk.c: New file. + + * include/grub/disk.h (grub_disk_dev_id): Add + `GRUB_DISK_DEVICE_MEMDISK_ID'. + + * include/grub/i386/pc/kernel.h + (GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE): New macro. + (GRUB_KERNEL_MACHINE_PREFIX): Increment by 4. + (grub_kernel_image_size): New variable declaration. + (grub_total_module_size): Likewise. + (grub_memdisk_image_size): Likewise. + + * include/grub/i386/pc/memory.h + (GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR): New macro. + + * include/grub/kernel.h: Include `'. + (grub_arch_memdisk_addr): New variable declaration. + (grub_arch_memdisk_size): Likewise. + + * kern/i386/pc/init.c (grub_arch_memdisk_addr): New function. + (grub_arch_memdisk_size): Likewise. + + * kern/i386/pc/startup.S (grub_memdisk_image_size): New variable. + (codestart): Replace hardcoded `0x100000' with + `GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR' macro. + + * util/i386/pc/grub-mkimage.c: Include `'. + (generate_image): Add `memdisk_path' parameter. When `memdisk_path' is + not NULL, append the contents of the file it refers to, at the end of + the compressed kernel image. Initialize `grub_memdisk_image_size' + variable (at `GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE' offset). + (options): Add "memdisk"|'m' option. + (main): Parse --memdisk|-m option, and pass user-provided path as + parameter to generate_image(). + +2008-01-20 Robert Millan + + * kern/sparc64/ieee1275/openfw.c (grub_devalias_iterate): Copy debug + grub_dprintf() calls from here ... + * kern/powerpc/ieee1275/openfw.c (grub_devalias_iterate): ... to here. + +2008-01-20 Robert Millan + + Fix detection of "real mode" when /options/real-mode? doesn't exist. + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_mmu): New variable + declaration. + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_mmu): New variable. + (grub_ieee1275_find_options): If `grub_ieee1275_mmu' is 0, set + `GRUB_IEEE1275_FLAG_REAL_MODE'. + (cmain): Initialize `grub_ieee1275_mmu' (using /chosen/mmu integer + property). + * kern/powerpc/ieee1275/openfw.c (grub_map): Rely on pre-initialized + `grub_ieee1275_mmu' rather than obtaining a handler on every call. + +2008-01-19 Robert Millan + + Get rid of confusing function (superseded by + `grub_ieee1275_get_integer_property') + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_decode_int_4): Remove + prototype. + * kern/ieee1275/ieee1275.c (grub_ieee1275_decode_int_4): Remove + function. + * term/ieee1275/ofconsole.c (grub_ofconsole_init): Avoid use of + grub_ieee1275_decode_int_4(), by obtaining integer properties directly + in native endianness from grub_ieee1275_get_integer_property(). + +2008-01-19 Robert Millan + + * kern/powerpc/ieee1275/openfw.c (grub_halt): Issue "power-off" + command after "shut-down", since implementations differ on which + the command for halt is. + +2008-01-19 Robert Millan + + * include/grub/i386/linuxbios/console.h: Add header protection. + (grub_keyboard_controller_init): New function prototype. + * term/i386/pc/at_keyboard.c (KEYBOARD_COMMAND_ISREADY): New macro. + (KEYBOARD_COMMAND_READ): Likewise. + (KEYBOARD_COMMAND_WRITE): Likewise. + (KEYBOARD_SCANCODE_SET1): Likewise. + (grub_keyboard_controller_write): New function. + (grub_keyboard_controller_read): Likewise. + (grub_keyboard_controller_init): Likewise. + + * term/i386/pc/console.c: Include `'. + (grub_console_init): On coreboot/LinuxBIOS, call + grub_keyboard_controller_init(). + +2008-01-19 Robert Millan + + PowerPC changes provided by Pavel Roskin. + + * kern/powerpc/ieee1275/cmain.c (cmain): Don't take any arguments. + * kern/powerpc/ieee1275/crt0.S: Store r5 in grub_ieee1275_entry_fn, + don't rely on cmain() doing it. + * kern/i386/ieee1275/startup.S (_start): Store %eax in + grub_ieee1275_entry_fn, don't rely on cmain() doing it. + +2008-01-16 Robert Millan + + * include/grub/i386/linuxbios/memory.h + (GRUB_MEMORY_MACHINE_LINUXBIOS_TABLE_ADDR): Remove macro. + * kern/i386/linuxbios/table.c (grub_linuxbios_table_iterate): Do not + receive `table_header' as argument. Instead, probe for it in the + known memory ranges where it can be present. + (grub_available_iterate): Do not pass a fixed `table_header' address + to grub_linuxbios_table_iterate(). + +2008-01-15 Robert Millan + + * configure.ac: Add `i386-ieee1275' to the list of supported targets. + * conf/i386-ieee1275.rmk: New file. + * include/grub/i386/ieee1275/console.h: Likewise. + * include/grub/i386/ieee1275/ieee1275.h: Likewise. + * include/grub/i386/ieee1275/kernel.h: Likewise. + * include/grub/i386/ieee1275/time.h: Likewise. + * kern/i386/ieee1275/init.c: Likewise. + * kern/i386/ieee1275/startup.S: Likewise. + +2008-01-15 Robert Millan + + * kern/misc.c (grub_vsprintf): Do not reset `longlongfmt' to zero + when pointers are 32-bit (but still do set it to one when they are + 64-bit). + +2008-01-15 Robert Millan + + * include/grub/ieee1275/ieee1275.h + (grub_ieee1275_get_integer_property): New function prototype. + + * kern/ieee1275/ieee1275.c: Include `'. + (grub_ieee1275_get_integer_property): New function. Wraps around + grub_ieee1275_get_property() to handle endianness. + + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_find_options): Replace + grub_ieee1275_get_property() with grub_ieee1275_get_integer_property() + where appropriate. + * kern/powerpc/ieee1275/openfw.c (grub_available_iterate): Likewise. + (grub_map): Likewise. + * kern/sparc64/ieee1275/openfw.c (grub_map): Likewise. + +2008-01-15 Bean + + * normal/execute.c (grub_script_exec_argument_to_string): Check for undefined variable. + (grub_script_execute_cmdline): Reset grub_errno. + + * normal/main.c (read_config_file): Reset grub_errno. + + * normal/parse.y (script_init): New. + (script): Move function and menuentry here. + (delimiter): New. + (command): Add delimiter at the end of command. + (commands): Adjust to match the new command. + (commandblock): Remove grub_script_lexer_record_start. + (menuentry): Add grub_script_lexer_record_start, use the new commands. + (if): Use the new commands. + + * conf/common.rmk (pkgdata_MODULES): Add echo.mod. + +2008-01-15 Robert Millan + + * normal/menu.c (run_menu): Move timeout message from here ... + (print_timeout): ... to here. + (run_menu): Use print_timeout() once during initial draw to print + the whole message, and again in every clock tick to update only + the number of seconds. + +2008-01-15 Robert Millan + + * kern/powerpc/ieee1275/openfw.c (grub_available_iterate): Obtain + actual size of `available' from grub_ieee1275_get_property(), and + restrict parsing to that bound. + +2008-01-15 Christian Franke + + * util/grub-emu.c: Replace by . + (argp_program_version): Remove variable. + (argp_program_bug_address): Likewise. + (options): Convert from struct argp_option to struct option. + (struct arguments): Remove. + (parse_opt): Remove. + (usage): New function. + (main): Replace struct args members by simple variables. + Replace argp_parse() by getopt_long(). + Add switch to evaluate options. + Add missing "(...)" around root_dev in prefix string. + +2008-01-14 Robert Millan + + * kern/powerpc/ieee1275/init.c (grub_exit): Reimplement as a wrapper + for grub_ieee1275_exit(), in order to improve portability. + +2008-01-14 Robert Millan + + * util/grub.d/10_linux.in (prefix): Define. + (exec_prefix): Likewise. Both definitions are later used by `libdir'. + +2008-01-13 Pavel Roskin + + * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Don't use + grub_errno if no errors have been detected. + +2008-01-12 Robert Millan + + * include/grub/util/getroot.h (grub_dev_abstraction_types): New enum. + (grub_util_get_dev_abstraction): New function prototype. + + * util/getroot.c: Include `' + (grub_util_get_grub_dev): Move detection of abstraction type to ... + (grub_util_get_dev_abstraction): ... here (new function). + + * util/grub-probe.c: Convert PRINT_* to an enum. Add + `PRINT_ABSTRACTION'. + (probe): Probe for abstraction type when requested. + (main): Understand `--target=abstraction'. + + * util/i386/efi/grub-install.in: Add abstraction module to core + image when it is found to be necessary. + * util/i386/pc/grub-install.in: Likewise. + * util/powerpc/ieee1275/grub-install.in: Likewise. + + * util/update-grub_lib.in (font_path): Return system path without + converting to GRUB path. + * util/update-grub.in: Convert system path returned by font_path() + to a GRUB path. Use `grub-probe -t abstraction' to determine what + abstraction module is needed for loading fonts (if any). Export + that as `GRUB_PRELOAD_MODULES'. + * util/grub.d/00_header.in: Process `GRUB_PRELOAD_MODULES' (print + insmod commands). + +2008-01-12 Yoshinori K. Okuji + + Remove some unused code from reiserfs. + + * fs/reiserfs.c (struct grub_reiserfs_key) + [GRUB_REISERFS_KEYV2_BITFIELD]: Removed offset and type. + (struct grub_reiserfs_node_body): Removed. + (grub_reiserfs_get_key_v2_type) [GRUB_REISERFS_KEYV2_BITFIELD]: + Likewise. + (grub_reiserfs_get_key_offset) [GRUB_REISERFS_KEYV2_BITFIELD]: + Likewise. + (grub_reiserfs_set_key_offset) [GRUB_REISERFS_KEYV2_BITFIELD]: + Likewise. + (grub_reiserfs_set_key_offset) [GRUB_REISERFS_KEYV2_BITFIELD]: + Likewise. + (grub_reiserfs_set_key_type) [GRUB_REISERFS_KEYV2_BITFIELD]: + Likewise. + (grub_reiserfs_iterate_dir) [GRUB_REISERFS_KEYV2_BITFIELD]: + Likewise. + (grub_reiserfs_open) [GRUB_REISERFS_KEYV2_BITFIELD]: Likewise. + (grub_reiserfs_read) [GRUB_REISERFS_KEYV2_BITFIELD]: Likewise. + (grub_reiserfs_dir) [GRUB_REISERFS_KEYV2_BITFIELD]: Likewise. + +2008-01-10 Robert Millan + + * util/update-grub_lib.in (grub_file_is_not_garbage): New function. + Determines if a file is garbage left by packaging systems, etc. + * util/update-grub.in: Use grub_file_is_not_garbage() as a condition + for processing /etc/grub.d scripts. + * util/grub.d/10_hurd.in: Fix `GRUB_DISTRIBUTOR' comparison. + * util/grub.d/10_linux.in: Likewise. Use grub_file_is_not_garbage() + as a condition for processing Linux images. + +2008-01-10 Pavel Roskin + + * include/grub/powerpc/libgcc.h (__ucmpdi2): New export. Needed + to compile reiserfs.c on PowerPC. + +2008-01-10 Robert Millan + + * kern/device.c (grub_device_iterate): Do not abort device iteration + when one of the devices cannot be opened. + * kern/disk.c (grub_disk_open): Do not account previous failures of + unrelated functions when grub_errno is checked for. + +2008-01-08 Robert Millan + + * loader/i386/pc/linux.c (grub_rescue_cmd_linux): For + `! grub_linux_is_bzimage', change order of address comparison to make + it more intuitive, and improve "too big zImage" error message. + +2008-01-08 Robert Millan + + * Makefile.in (uninstall): Handle `$(update-grub_SCRIPTS)' and + `$(update-grub_DATA)'. + (distcheck): Fix race condition when invoking `$(MAKE)' on multiple + targets. + +2008-01-07 Robert Millan + + * boot/i386/pc/boot.S (boot_drive_check): Add a comment indicating + which instruction is modified by grub-setup during installation + (since it wasn't obvious by only looking at this file). + +2008-01-07 Robert Millan + + * TODO: Rewrite. Just refer to the wiki and the BTS instead of + listing actual TODO items. + +2008-01-06 Yoshinori K. Okuji + + * fs/reiserfs.c (grub_reiserfs_get_key_v2_type): Handle endianness + correctly. + (grub_reiserfs_get_key_offset): Likewise. + (grub_reiserfs_set_key_offset): Likewise. + (grub_reiserfs_set_key_type): Likewise. + (grub_reiserfs_iterate_dir): Return 1 if found, otherwise 0. + + (GRUB_REISERFS_KEYV2_BITFIELD): Undefined. Probably it would be + better to remove the bitfield version completely. + +2008-01-06 Yoshinori K. Okuji + + * fs/reiserfs.c (grub_reiserfs_iterate_dir): ENTRY_ITEM must be + allocated from the heap, due to the fshelp implementation. + (grub_reiserfs_dir): Free NODE, due to the same reason. + +2008-01-06 Yoshinori K. Okuji + + Mostly from Vincent Pelletier: + + * fs/reiserfs.c: New file. + + * conf/common.rmk (pkglib_MODULES): Added reiserfs.mod. + (reiserfs_mod_SOURCES): New variable. + (reiserfs_mod_CFLAGS): Likewise. + (reiserfs_mod_LDFLAGS): Likewise. + + * DISTLIST: Added boot/i386/pc/lnxboot.S, commands/hexdump.c, + disk/ata.c, fs/cpio.c, fs/ntfscomp.c, fs/reiserfs.c, + include/grub/ntfs.h, include/grub/i386/pc/machine.h, and + normal/color.c. + +2008-01-06 Robert Millan + + * normal/color.c: Remove `'. + +2008-01-05 Jeroen Dekkers + + * include/grub/normal.h: Include . + +2008-01-05 Robert Millan + + * util/i386/pc/grub-setup.c (usage): Replace obsolete `(hd0,0)' in + usage example with `(hd0,1)'. + Reported by Samuel Thibault. + +2008-01-05 Robert Millan + + * kern/i386/loader.S (grub_linux_is_bzimage): New variable. + (grub_linux_boot_zimage): Rename to ... + (grub_linux_boot): ... this. + (grub_linux_boot_bzimage): Merge with `grub_linux_boot_zimage'. + (grub_linux_boot_zimage): Conditionalize zImage copy. + + * include/grub/i386/loader.h (grub_linux_is_bzimage): Add prototype. + (grub_linux_boot_bzimage): Remove prototype. + (grub_linux_boot_zimage): Rename to ... + (grub_linux_boot): ... this. + + * loader/i386/pc/linux.c (big_linux): Replace with `grub_linux_is_bzimage'. + (grub_linux_boot): Remove function. + +2008-01-05 Robert Millan + + * include/grub/normal.h (grub_env_write_color_normal): New prototype. + (grub_env_write_color_highlight): Likewise. + (grub_wait_after_message): Likewise. + + * normal/color.c: New file. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `normal/color.c'. + (normal_mod_DEPENDENCIES): Likewise. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Add `normal/color.c'. + (normal_mod_DEPENDENCIES): Likewise. + + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Add `normal/color.c'. + (normal_mod_DEPENDENCIES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add `normal/color.c'. + (normal_mod_DEPENDENCIES): Likewise. + + * normal/menu_entry.c (run): Rely on grub_wait_after_message() + for waiting after a message is printed. + * normal/main.c (read_config_file): Likewise. + (grub_normal_init): Register grub_env_write_color_normal() and + grub_env_write_color_highlight() hooks. Mark `color_normal' and + `color_highlight' variables as global. + + * normal/menu.c (grub_wait_after_message): New function. + (grub_color_menu_normal): New variable. Replaces ... + (GRUB_COLOR_MENU_NORMAL): ... this macro. + (grub_color_menu_highlight): New variable. Replaces ... + (GRUB_COLOR_MENU_HIGHLIGHT): ... this macro. + (draw_border): Set color state to `GRUB_TERM_COLOR_NORMAL' instead of + `GRUB_TERM_COLOR_STANDARD'. + (print_message): Use `grub_setcolorstate' to reload colors. Rename + `normal_code' and `highlight_code' to `old_color_normal' and + `old_color_highlight', respectively. + (grub_menu_init_page): Update colors when drawing the menu, based on + `menu_color_normal' and `menu_color_highlight' variables. + (grub_menu_run): Rely on grub_wait_after_message() for waiting after + a message is printed. + +2008-01-05 Robert Millan + + * kern/env.c (grub_env_context_open): Propagate hooks for global + variables to new context. + + * kern/main.c (grub_set_root_dev): Export `root' variable. + +2008-01-05 Robert Millan + + * util/biosdisk.c (get_os_disk): Check for devfs-style IDE and SCSI + discs unconditionally, since udev and others have options to provide + them. + +2008-01-05 Robert Millan + + * normal/completion.c (iterate_dir): Skip `.' and `..' directories. + +2008-01-04 Christian Franke + + * kern/i386/pc/init.c (grub_machine_init): Fix evaluation + of eisa_mmap. + +2008-01-03 Pavel Roskin + + * kern/i386/linuxbios/init.c: Put "void" to all function + declarations with no arguments. + * kern/powerpc/ieee1275/init.c: Likewise. + * term/i386/pc/at_keyboard.c: Likewise. + * term/i386/pc/vga_text.c: Likewise. + * util/grub-mkdevicemap.c: Likewise. + +2008-01-02 Robert Millan + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Improve error + message when loaded image is out of bounds. + (grub_multiboot_load_elf64): Likewise. + +2008-01-02 Pavel Roskin + + * util/grub.d/10_linux.in: Try version without ".old" when + looking for initrd. It's better to use initrd from the newer + kernel of the same version than no initrd at all. + +2008-01-01 Robert Millan + + * util/biosdisk.c (get_os_disk): Fix check for IDE or SCSI discs. + +2008-01-01 Vesa Jaaskelainen + + * include/grub/video.h: Added grub_video_unmap_color and + grub_video_get_active_render_target. + (grub_video_adapter): Added unmap_color and get_active_render_target. + + * video/video.c: Added grub_video_unmap_color and + grub_video_get_active_render_target. + (grub_video_get_info): Changed method to accept NULL pointer as an + argument to allow detection of active video adapter. + + * video/i386/pc/vbe.c: Renamed grub_video_vbe_unmap_color as + grub_video_vbe_unmap_color_int. + Added grub_video_vbe_unmap_color and + grub_video_vbe_get_active_render_target. + (grub_video_vbe_adapter): Added unmap_color and + get_active_render_target. + + * video/i386/pc/vbeblit.c: Replaced grub_video_vbe_unmap_color usage + with grub_video_vbe_unmap_color_int. + + * term/gfxterm.c (DEFAULT_STANDARD_COLOR): Added. + (DEFAULT_NORMAL_COLOR): Likewise. + (DEFAULT_HIGHLIGHT_COLOR) Likewise. + (DEFAULT_FG_COLOR): Removed. + (DEFAULT_BG_COLOR): Likewise. + (DEFAULT_CURSOR_COLOR): Changed value. + (grub_virtual_screen): Added standard_color_setting, + normal_color_setting, highlight_color_setting and term_color. + (grub_virtual_screen): Removed fg_color_setting and bg_color_setting. + (bitmap_width): Added. + (bitmap_height): Likewise. + (bitmap): Likewise. + (set_term_color): Likewise. + (grub_virtual_screen_setup): Changed to use new terminal coloring + settings. + (grub_gfxterm_init): Added init for bitmap. + (grub_gfxterm_fini): Added destroy for bitmap. + (redraw_screen_rect): Updated to use background bitmap and new + terminal coloring. + (scroll_up): Added optimization for case when there is no bitmap. + (grub_gfxterm_cls): Fixed to use correct background color. + (grub_virtual_screen_setcolorstate): Changed to use new terminal + coloring. + (grub_virtual_screen_setcolor): Likewise. + (grub_virtual_screen_getcolor): Added. + (grub_gfxterm_background_image_cmd): Likewise. + (grub_video_term): Added setcolor and getcolor. + (MOD_INIT): Added registration of background_image command. + (MOD_TERM): Added unregistration for background_image command. + +2007-12-30 Pavel Roskin + + * loader/multiboot_loader.c: Fix multiboot command + unregistration. Fix all typos in the word "multiboot". + +2007-12-29 Pavel Roskin + + * util/grub.d/10_linux.in: Refactor search for initrd. Add + support for initrd names used in Fedora. + +2007-12-26 Bean + + * conf/common.rmk (pkgdata_MODULES): Add cpio.mod. + (cpio_mod_SOURCES): New variable. + (cpio_mod_CFLAGS): Likewise. + (cpio_mod_LDFLAGS): Likewise. + + * fs/cpio.c: New file. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add cpio.c. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + +2007-12-25 Robert Millan + + * include/grub/term.h (struct grub_term): Add `getcolor' function. + (grub_getcolor): New function. + + * kern/term.c (grub_getcolor): New function. + * normal/menu.c (GRUB_COLOR_MENU_NORMAL): New macro. + (GRUB_COLOR_MENU_HIGHLIGHT): New macro. + (print_entry): Set normal and highlight colors to + `GRUB_COLOR_MENU_NORMAL' and `GRUB_COLOR_MENU_HIGHLIGHT', + respectively, before printing and restore them to old + values afterwards. + (grub_menu_init_page): Likewise. Fill an additional colored space + that would otherwise be left blank. + + * term/efi/console.c (grub_console_getcolor): New function. + (struct grub_console_term.getcolor): New variable. + * term/i386/pc/console.c (grub_console_getcolor): New function. + (struct grub_console_term.getcolor): New variable. + * term/ieee1275/ofconsole.c (grub_ofconsole_getcolor): New function. + (struct grub_console_term.getcolor): New variable. + + * term/i386/pc/serial.c (grub_serial_setcolor): Remove function. + (struct grub_console_term.setcolor): Remove variable. + * term/i386/pc/vesafb.c (grub_virtual_screen_setcolor): Remove function. + (struct grub_console_term.setcolor): Remove variable. + * term/i386/pc/vga.c (grub_vga_setcolor): Remove function. + (struct grub_console_term.setcolor): Remove variable. + * term/gfxterm.c (grub_virtual_screen_setcolor): Remove function. + (struct grub_console_term.setcolor): Remove variable. + +2007-12-25 Robert Millan + + * configure.ac: Search for possible unifont.hex locations, and + define UNIFONT_HEX if found. + + * Makefile.in (UNIFONT_HEX): Define variable. + (DATA): Rename to ... + (PKGLIB): ... this. Update all users. + (PKGDATA): New variable. + (pkgdata_IMAGES): Rename to ... + (pkglib_IMAGES): ... this. Update all users. + (pkgdata_MODULES): Rename to ... + (pkglib_MODULES): ... this. Update all users. + (pkgdata_PROGRAMS): Rename to ... + (pkglib_PROGRAMS): ... this. Update all users. + (pkgdata_DATA): Rename to ... + (pkglib_DATA): ... this. Update all users. + (CLEANFILES): Redefine to `$(pkglib_DATA) $(pkgdata_DATA)'. + (unicode.pff, ascii.pff): New rules. + (all-local): Add `$(PKGDATA)' dependency. + (install-local): Process `$(PKGDATA)'. + + * util/update-grub_lib.in (font_path): Search for *.pff files in + a few more locations, including `${pkgdata}'. + +2007-12-23 Robert Millan + + Patch from Bean : + * disk/loopback.c (grub_loopback_read): Add missing bit shift to + `size'. + +2007-12-21 Bean + + * conf/common.rmk (pkgdata_MODULES): Add ntfscomp.mod. + (ntfscomp_mod_SOURCES): New variable. + (ntfscomp_mod_CFLAGS): Likewise. + (ntfscomp_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/ntfscomp.c. + (grub_probe_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + + * conf/i386-efi.rmk (grub_probe_SOURCES): Add fs/ntfscomp.c. + (grub_emu_SOURCES): Likewise. + + * conf/i386-linuxbios.rmk (grub_probe_SOURCES): Add fs/ntfscomp.c. + (grub_emu_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_probe_SOURCES): Add fs/ntfscomp.c. + (grub_emu_SOURCES): Likewise. + + * fs/ntfs.c (grub_ntfscomp_func): New variable. + (read_run_list): Renamed to grub_ntfs_read_run_list. + (decomp_nextvcn): Moved to ntfscomp.c. + (decomp_getch): Likewise. + (decomp_get16): Likewise. + (decomp_block): Likewise. + (read_block): Likewise. + (read_data): Partially moved to ntfscomp.c. + (fixup): Change unsigned to grub_uint16_t. + (read_mft): Change unsigned long to grub_uint32_t. + (read_attr): Likewise. + (read_data): Likewise. + (read_run_data): Likewise. + (read_run_list): Likewise. + (read_mft): Likewise. + + * fs/ntfscomp.c: New file. + + * include/grub/ntfs.h: New file. + +2007-12-16 Robert Millan + + * util/grub-mkdevicemap.c (make_device_map): Iterate up to 20 for + IDE disk check, since Linux is known to support 20 IDE disks. + Reported by Colin Watson. + +2007-12-15 Bean + + * conf/i386-pc.rmk (pkgdata_IMAGES): Add lnxboot.img. + (lnxboot_img_SOURCES): New variable. + (lnxboot_img_ASFLAGS): Likewise. + (lnxboot_img_LDFLAGS): Likewise. + + * boot/i386/pc/lnxboot.S: New file. + +2007-11-24 Pavel Roskin + + * configure.ac: Test if '--build-id=none' is supported by the + linker. If yes, add it to TARGET_LDFLAGS. Build ID causes + objcopy to generate incorrect binary files (binutils + 2.17.50.0.18-1 as shipped by Fedora 8). + * aclocal.m4 (grub_PROG_OBJCOPY_ABSOLUTE): Use LDFLAGS when + linking, so that build ID doesn't break the test. + +2007-11-24 Pavel Roskin + + * include/grub/i386/time.h: use "void" in the argument list + of grub_cpu_idle(). + * include/grub/powerpc/time.h: Likewise. + * include/grub/sparc64/time.h: Likewise. + +2007-11-18 Christian Franke + + * util/console.c (grub_ncurses_getkey): Change curses KEY_* mapping, + now return control chars instead of GRUB_CONSOLE_KEY_* constants. + This fixes the problem that function keys did not work in grub-emu. + +2007-11-18 Christian Franke + + * disk/host.c (grub_host_open): Remove attribute unused from + name parameter. Add check for "host". This fixes the problem + that grub-emu does not find partitions. + +2007-11-18 Christian Franke + + * util/hostfs.c (is_dir): New function. + (grub_hostfs_dir): Handle missing dirent.d_type case. + (grub_hostfs_read): Add missing fseek(). + (grub_hostfs_label): Clear label pointer. This fixes a crash + of grub-emu on "ls (host)". + +2007-11-18 Christian Franke + + * include/grub/i386/pc/init.h (struct grub_machine_mmap_entry): + Add attribute packed, gcc 3.4.4 on Cygwin aligns this + to 64 bit boundary by default. + +2007-11-18 Bean + + * conf/common.rmk (pkgdata_MODULES): Add hexdump.mod. + (hexdump_mod_SOURCES): New variable. + (hexdump_mod_CFLAGS): Likewise. + (hexdump_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add command/hexdump.c. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Add command/hexdump.c. + + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Add command/hexdump.c. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add command/hexdump.c. + + * include/grub/hexdump.h: New file. + + * commands/hexdump.c: New file. + +2007-11-10 Robert Millan + + * commands/i386/pc/play.c (beep_off): Switch order of arguments + in grub_outb() calls. + (beep_on): Likewise. + +2007-11-10 Christian Franke + + * normal/menu.c (run_menu): Check for empty menu to avoid crash. + (grub_menu_run): Likewise. + +2007-11-10 Robert Millan + + * include/grub/i386/efi/machine.h: New file. + * include/grub/i386/linuxbios/machine.h: Likewise. + * include/grub/i386/pc/machine.h: Likewise. + * include/grub/powerpc/ieee1275/machine.h: Likewise. + * include/grub/sparc64/ieee1275/machine.h: Likewise. + + * term/i386/pc/serial.c: Include . + (serial_hw_io_addr): New variable. + (serial_hw_get_port): Obtain port address from `serial_hw_io_addr' + instead of `(unsigned short *) 0x400'. + +2007-11-10 Bean + + * fs/ntfs.c (read_block): Fix a bug caused by adjacent blocks. + +2007-11-10 Vesa Jaaskelainen + + * conf/i386-pc.rmk (pkgdata_MODULES): Added vga.mod. + (vga_mod_SOURCES): Added. + (vga_mod_CFLAGS): Likewise. + (vga_mod_LDFLAGS): Likewise. + + * term/i386/pc/vga.c (get_map_mask): Switch order of arguments in + grub_outb() calls. + (set_map_mask): Likewise. + (set_read_map): Likewise. + (set_read_address): Likewise. + (vga_font): Removed variable. + (get_vga_glyph): Removed function. + (invalidate_char): Likewise. + (write_char): Changed to use grub_font_get_glyph() for font + information. + (grub_vga_putchar): Likewise. + (grub_vga_getcharwidth): Likewise. + +2007-11-10 Vesa Jaaskelainen + + * conf/i386-pc.rmk (boot_img_LDFLAGS): Use COMMON_LDFLAGS for target + flags. + (pxeboot_img_LDFLAGS): Likewise. + (diskboot_img_LDFLAGS): Likewise. + (kernel_img_LDFLAGS): Likewise. + +2007-11-06 Robert Millan + + * term/i386/pc/serial.c (serial_hw_put): Switch order of arguments + in grub_outb() calls. + (serial_hw_init): Likewise. + +2007-11-05 Robert Millan + + * util/update-grub.in: Allow files in ${update_grub_dir} to contain + spaces. Skip non-regular files. + +2007-11-05 Robert Millan + + * kern/disk.c (grub_disk_firmware_fini) + (grub_disk_firmware_is_tainted): New variables. + + * include/grub/disk.h (grub_disk_firmware_fini) + (grub_disk_firmware_is_tainted): Likewise. + + * disk/i386/pc/biosdisk.c (GRUB_MOD_FINI(biosdisk)): Moved from here ... + (grub_disk_biosdisk_fini): ... to here. + (GRUB_MOD_FINI(biosdisk)): Implement using grub_disk_biosdisk_fini(). + (GRUB_MOD_INIT(biosdisk)): Abort when `grub_disk_firmware_is_tainted' + is set. Register grub_disk_biosdisk_fini() in + `grub_disk_firmware_fini'. + + * disk/ata.c: Remove `'. + (GRUB_MOD_INIT(ata)): Remove grub_biosdisk_fini() call. + Use `grub_disk_firmware_is_tainted' and `grub_disk_firmware_fini' + to finish existing firmware disk interface. + + * conf/i386-linuxbios.rmk (pkgdata_MODULES): Add `ata.mod'. + (ata_mod_SOURCES): New variable. + (ata_mod_CFLAGS): Likewise. + (ata_mod_LDFLAGS): Likewise. + +2007-11-05 Robert Millan + + * disk/ata.c: Remove `'. Include `'. + (grub_ata_wait): Reimplement using grub_millisleep(). + + * include/grub/misc.h (grub_div_roundup): Fix parenthesization. + * include/grub/i386/time.h (grub_cpu_idle): Disable `hlt' instruction. + +2007-11-03 Marco Gerards + + * term/i386/pc/vga_text.c: Include . + (CRTC_ADDR_PORT): New macro. + (CRTC_DATA_PORT): Likewise. + (CRTC_CURSOR): Likewise. + (CRTC_CURSOR_ADDR_HIGH): Likewise. + (CRTC_CURSOR_ADDR_LOW): Likewise. + (update_cursor): New function. + (grub_console_real_putchar): Call `update_cursor'. + (grub_console_gotoxy): Likewise. + (grub_console_cls): Set the default color when clearing the + screen. + (grub_console_setcursor): Implemented. + +2007-11-03 Marco Gerards + + * disk/ata.c (grub_ata_pio_read): Don't wait for the command to + become activate. + (grub_ata_pio_write): Likewise. + + (grub_atapi_identify): Wait after issuing an ATA command. + (grub_atapi_packet): Likewise. + (grub_ata_identify): Likewise. + (grub_ata_readwrite): Likewise. + +2007-11-03 Marco Gerards + + * disk/ata.c (grub_ata_pio_read): Detect and return the error code. + (grub_ata_pio_write): Likewise. + (grub_ata_readwrite): Use `grub_error', instead of + returning `grub_errno'. + +2007-11-03 Marco Gerards + + * disk/ata.c (grub_ata_readwrite): Call grub_ata_pio_read and + grub_ata_pio_write once for every single sector, instead of for + multiple sectors. + +2007-10-31 Robert Millan + + * configure.ac: Add `i386-linuxbios' to the list of supported targets. + + * conf/i386-linuxbios.rmk: New file. + + * kern/i386/pc/hardware.c: Likewise. + * term/i386/pc/at_keyboard.c: Likewise. + * term/i386/pc/vga_text.c: Likewise. + + * include/grub/i386/linuxbios/boot.h: Likewise. + * include/grub/i386/linuxbios/console.h: Likewise. + * include/grub/i386/linuxbios/init.h: Likewise. + * include/grub/i386/linuxbios/kernel.h: Likewise. + * include/grub/i386/linuxbios/loader.h: Likewise. + * include/grub/i386/linuxbios/memory.h: Likewise. + * include/grub/i386/linuxbios/serial.h: Likewise. + * include/grub/i386/linuxbios/time.h: Likewise. + + * kern/i386/linuxbios/init.c: Likewise. + * kern/i386/linuxbios/startup.S: Likewise. + * kern/i386/linuxbios/table.c: Likewise. + +2007-10-31 Marco Gerards + + * conf/i386-pc.rmk (pkgdata_MODULES): Add `ata.mod'. + (ata_mod_SOURCES): New variable. + (ata_mod_CFLAGS): Likewise. + (ata_mod_LDFLAGS): Likewise. + + * disk/ata.c: New file. + + * include/grub/disk.h (grub_disk_dev_id): Add + `GRUB_DISK_DEV_ATA_ID'. + +2007-10-31 Robert Millan + + * include/grub/i386/pc/init.h (grub_lower_mem): Moved from here ... + * include/grub/i386/pc/memory.h (grub_lower_mem): ... to here. + + * include/grub/i386/pc/init.h (grub_upper_mem): Moved from here ... + * include/grub/i386/pc/memory.h (grub_upper_mem): ... to here. + + * include/grub/i386/pc/memory.h: Include `' and + `'. + + * loader/i386/pc/multiboot.c: Include `'. + +2007-10-27 Robert Millan + + * include/grub/types.h (ULONG_MAX): Define macro. + +2007-10-22 Robert Millan + + * kern/i386/pc/startup.S: Remove `"kern/i386/realmode.S"'. Include + `"../realmode.S"'. + Remove `"kern/i386/loader.S"'. Include `"../loader.S"'. + +2007-10-22 Robert Millan + + * conf/i386-pc.rmk (kernel_img_SOURCES): Remove `disk/i386/pc/biosdisk.c'. + (pkgdata_MODULES): Add `biosdisk.mod'. + (biosdisk_mod_SOURCES, biosdisk_mod_CFLAGS, biosdisk_mod_LDFLAGS): New + variables. + + * disk/i386/pc/biosdisk.c: Include `'. + (grub_biosdisk_init): Replace with ... + (GRUB_MOD_INIT(biosdisk)): ... this. + (grub_biosdisk_fini): Replace with ... + (GRUB_MOD_FINI(biosdisk)): ... this. + + * kern/i386/pc/init.c: Remove `'. + (grub_machine_init): Remove call to grub_biosdisk_init(). + (grub_machine_fini): Remove call to grub_machine_fini(). + + * util/i386/pc/grub-install.in (modules): Add `biosdisk'. + +2007-10-22 Robert Millan + + * include/grub/time.h: New file. + * include/grub/i386/time.h: Likewise. + * include/grub/powerpc/time.h: Likewise. + * include/grub/sparc64/time.h: Likewise. + + * include/grub/i386/pc/time.h (KERNEL_TIME_HEADER): Rename all + instances to ... + (KERNEL_MACHINE_TIME_HEADER): ... this. + * include/grub/powerpc/ieee1275/time.h (KERNEL_TIME_HEADER): Rename all + instances to ... + (KERNEL_MACHINE_TIME_HEADER): ... this. + * include/grub/sparc64/ieee1275/time.h (KERNEL_TIME_HEADER): Rename all + instances to ... + (KERNEL_MACHINE_TIME_HEADER): ... this. + + * kern/i386/efi/init.c: Include `'. + (grub_millisleep): New function. + * kern/i386/pc/init.c: Include `'. + (grub_millisleep): New function. + * kern/powerpc/ieee1275/init.c: Include `'. + Remove `grub/machine/time.h' include. + (grub_millisleep): New function. + * kern/sparc64/ieee1275/init.c: Include `'. + Remove `grub/machine/time.h' include. + (grub_millisleep): New function. + + * include/grub/misc.h (grub_div_roundup): New function. + + * kern/misc.c: Include `'. + (grub_millisleep_generic): New function. + + * conf/i386-efi.rmk (kernel_mod_HEADERS): Remove `i386/efi/time.h'. + Add `time.h'. + * conf/i386-pc.rmk (kernel_img_HEADERS): Remove `machine/time.h'. + Add `time.h'. + * conf/powerpc-ieee1275.rmk (kernel_elf_HEADERS): Remove + `machine/time.h'. Add `time.h'. + * conf/sparc64-ieee1275.rmk (kernel_elf_HEADERS): Likewise. + +2007-10-21 Robert Millan + + * include/grub/misc.h (grub_max): New function. + +2007-10-21 Robert Millan + + * util/misc.c (grub_util_info): Call fflush() before returning. + +2007-10-20 Robert Millan + + * genmk.rb (Image): Copy `extra_flags' from here ... + (PModule): ... to here. Use it in `#{obj}: #{src}' rule. + + * commands/i386/cpuid.c (grub_cmd_cpuid): Add __attribute__ ((unused)) + to `argc' and `args' arguments. + +2007-10-17 Robert Millan + + * kern/i386/loader.S: New file. + + * kern/i386/pc/startup.S (grub_linux_prot_size): Moved from here ... + * kern/i386/loader.S (grub_linux_prot_size)... to here. + * kern/i386/pc/startup.S (grub_linux_tmp_addr): Moved from here ... + * kern/i386/loader.S (grub_linux_tmp_addr)... to here. + * kern/i386/pc/startup.S (grub_linux_real_addr): Moved from here ... + * kern/i386/loader.S (grub_linux_real_addr)... to here. + * kern/i386/pc/startup.S (grub_linux_boot_zimage): Moved from here ... + * kern/i386/loader.S (grub_linux_boot_zimage)... to here. + * kern/i386/pc/startup.S (grub_linux_boot_bzimage): Moved from here ... + * kern/i386/loader.S (grub_linux_boot_bzimage)... to here. + * kern/i386/pc/startup.S (grub_multiboot_real_boot): Moved from here ... + * kern/i386/loader.S (grub_multiboot_real_boot)... to here. + * kern/i386/pc/startup.S (grub_multiboot2_real_boot): Moved from here ... + * kern/i386/loader.S (grub_multiboot2_real_boot)... to here. + + * kern/i386/realmode.S: New file. + + * kern/i386/pc/startup.S (protstack): Moved from here ... + * kern/i386/realmode.S (protstack)... to here. + * kern/i386/pc/startup.S (gdt): Moved from here ... + * kern/i386/realmode.S (gdt)... to here. + * kern/i386/pc/startup.S (prot_to_real): Moved from here ... + * kern/i386/realmode.S (prot_to_real)... to here. + + * kern/i386/pc/startup.S: Include `kern/i386/loader.S' and + `kern/i386/realmode.S'. + +2007-10-17 Robert Millan + + * include/grub/i386/loader.h: New file. + + * include/grub/i386/pc/loader.h (grub_linux_prot_size) + (grub_linux_tmp_addr, grub_linux_real_addr, grub_os_area_addr) + (grub_os_area_size, grub_linux_boot_zimage, grub_linux_boot_bzimage) + (grub_multiboot_real_boot, grub_multiboot2_real_boot) + (grub_rescue_cmd_linux, grub_rescue_cmd_initrd): Moved from here ... + * include/grub/i386/loader.h (grub_linux_prot_size) + (grub_linux_tmp_addr, grub_linux_real_addr, grub_os_area_addr) + (grub_os_area_size, grub_linux_boot_zimage, grub_linux_boot_bzimage) + (grub_multiboot_real_boot, grub_multiboot2_real_boot) + (grub_rescue_cmd_linux, grub_rescue_cmd_initrd): ... to here. + + * include/grub/i386/pc/loader.h: Include `grub/cpu/loader.h'. + +2007-10-15 Robert Millan + + * normal/misc.c (grub_normal_print_device_info): Do not probe for + filesystem when dev->disk is unset. + Do probe for filesystem even when dev->disk->has_partitions is set. + In case a filesystem is found, always report it. + In case it isn't, if dev->disk->has_partitions is set, report that + a partition table was found instead of reporting that no filesystem + could be identified. + +2007-10-12 Robert Millan + + * conf/powerpc-ieee1275.rmk (grub_mkimage_SOURCES): Replace reference + to util/powerpc/ieee1275/grub-mkimage.c with util/elf/grub-mkimage.c. + + * include/grub/types.h (grub_host_to_target16): New macro. + (grub_host_to_target32): Likewise. + (grub_host_to_target64): Likewise. + (grub_target_to_host16): Likewise. + (grub_target_to_host32): Likewise. + (grub_target_to_host64): Likewise. + + * include/grub/powerpc/ieee1275/kernel.h (GRUB_IEEE1275_MOD_ALIGN): + Renamed from to ... + (GRUB_MOD_ALIGN): ...this. Update all users. + + * util/elf/grub-mkimage.c (load_note): Replace grub_cpu_to_be32 with + grub_host_to_target32. + Replace grub_be_to_cpu32 with grub_target_to_host32. + (load_modules): Likewise. + (add_segments): Replace grub_be_to_cpu16 with grub_target_to_host16. + Replace grub_be_to_cpu32 with grub_target_to_host32. + Replace grub_cpu_to_be16 with grub_host_to_target16. + Replace grub_cpu_to_be32 grub_host_to_target32. + +2007-10-12 Robert Millan + + * util/powerpc/ieee1275/grub-mkimage.c: Moved to ... + * util/elf/grub-mkimage.c: ... here. + + * DISTLIST: Add `util/elf/grub-mkimage.c'. Remove + `util/powerpc/ieee1275/grub-mkimage.c'. + +2007-10-07 Robert Millan + + * kern/powerpc/ieee1275/init.c: Rename HEAP_LIMIT to HEAP_MAX_ADDR, + and make it easier to figure out. + Add HEAP_MIN_SIZE and HEAP_MAX_ADDR definitions. + (grub_claim_heap): Use HEAP_MAX_ADDR rather than taking a parameter. + Do not avoid claiming a region above HEAP_MAX_ADDR if that would + leave us with less than HEAP_MIN_SIZE total heap. + Avoid our total amount of heap to surpass HEAP_MAX_SIZE. + +2007-10-03 Robert Millan + + * include/grub/i386/io.h: New file. + * commands/i386/pc/play.c (inb): Removed. + (outb): Removed. + Include grub/cpu/io.h. Replace inb() with grub_inb() and outb() + with grub_outb(). + * term/i386/pc/serial.c (inb): Removed. + (outb): Removed. + Include grub/cpu/io.h. Replace inb() with grub_inb() and outb() + with grub_outb(). + * term/i386/pc/vga.c (inb): Removed. + (outb): Removed. + Include grub/cpu/io.h. Replace inb() with grub_inb() and outb() + with grub_outb(). + +2007-10-02 Robert Millan + + * conf/i386-efi.rmk (grub_emu_SOURCES): Add util/hostfs.c. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + Reported by Marcin Kurek. + +2007-09-07 Robert Millan + + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_test_flag): Detect + SmartFirmware version updates (as released by Sven Luther), and avoid + setting GRUB_IEEE1275_FLAG_NO_PARTITION_0 or + GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS unless the running version is + known broken. + +2007-09-03 Yoshinori K. Okuji + + From Hitoshi Ozeki: + * kern/i386/pc/init.c (compact_mem_regions): Decrease NUM_REGIONS + when merging two regions. + +2007-09-03 Yoshinori K. Okuji + + * kern/rescue.c (grub_enter_rescue_mode): Free ARGS. + * normal/completion.c (grub_normal_do_completion): Likewise. + Reported by Hitoshi Ozeki. + +2007-09-03 Yoshinori K. Okuji + + Do not use devices at boot in chainloading. + + * loader/i386/pc/chainloader.c (boot_drive): New variable. + (boot_part_addr): Likewise. + (grub_chainloader_boot): Simply call grub_chainloader_real_boot + with BOOT_DRIVE and BOOT_PART_ADDR. + (grub_chainloader_cmd): Set BOOT_DRIVE and BOOT_PART_ADDR. + Reported by Hitoshi Ozeki . + +2007-08-29 Robert Millan + + Patch from Simon Peter : + * genmk.rb (Utility): Append $(#{src}_DEPENDENCIES) to #{obj} targets. + * conf/i386-pc.rmk: Replace grub-probe_DEPENDENCIES with + util/grub-probe.c_DEPENDENCIES. Replace grub-setup_DEPENDENCIES with + util/i386/pc/grub-setup.c_DEPENDENCIES. + * conf/i386-efi.rmk: Replace grub-probe_DEPENDENCIES with + util/grub-probe.c_DEPENDENCIES. + * conf/powerpc-ieee1275.rmk: Likewise. + +2007-08-28 Robert Millan + + * util/i386/get_disk_name.c: New. Implement grub_util_get_disk_name() + to tell grub-mkdevicemap how to name devices. + * util/ieee1275/get_disk_name.c: Likewise (using "ofpathname -a" + feature). + + * conf/i386-efi.rmk (grub_mkdevicemap_SOURCES): Add + util/i386/get_disk_name.c. + * conf/i386-pc.rmk (grub_mkdevicemap_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_mkdevicemap_SOURCES): Add + util/ieee1275/get_disk_name.c. + + * include/grub/util/misc.h: grub_util_get_disk_name() declaration. + + * DISTLIST: Add util/i386/get_disk_name.c and + util/ieee1275/get_disk_name.c. + + * util/grub-mkdevicemap.c: Replace device naming logic with + grub_util_get_disk_name() calls. + +2007-08-20 Robert Millan + + * normal/menu.c (run_menu): Refer to seconds as "s" not "seconds" + (so that it works for both plural and singular quantities). + +2007-08-05 Robert Millan + + * util/grub.d/10_linux.in (test_gt): Strip out vmlinu[xz]- prefix + so that [xz] isn't taken into account when determining order. + +2007-08-02 Marco Gerards + + * DISTLIST: Add `disk/host.c', `fs/ntfs.c', `include/multiboot.h', + `include/multiboot2.h', `include/grub/elfload.h', + `include/multiboot.h', `include/grub/multiboot.h', + `include/grub/multiboot_loader.h', `include/grub/multiboot2.h', + `include/grub/i386/pc/biosdisk.h', `include/grub/util/biosdisk.h', + `kern/elf.c', `loader/multiboot_loader.c', + `loader/multiboot_loader_normal.c', `loader/multiboot2.c', + `loader/i386/pc/multiboot2.c', + `loader/powerpc/ieee1275/multiboot2.c', `util/hostfs.c' and + `util/i386/pc/grub-mkrescue.in'. Remove + `include/grub/biosdisk.h', `include/grub/i386/pc/multiboot.h', + `include/grub/i386/pc/util/biosdisk.h' and + `include/grub/powerpc/ieee1275/multiboot.h'. + +2007-08-02 Bean + + * conf/common.rmk (pkgdata_MODULES): Add ntfs.mod. + (ntfs_mod_SOURCES): New variable. + (ntfs_mod_CFLAGS): Likewise. + (ntfs_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/ntfs.c. + (grub_probe_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + + * conf/i386-efi.rmk (grub_probe_SOURCES): Add fs/ntfs.c. + (grub_emu_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_probe_SOURCES): Add fs/ntfs.c. + (grub_emu_SOURCES): Likewise. + + * conf/misc.c (grub_utf16_to_utf8): Fix unicode conversion bug. + + * fs/ntfs.c: New file. + +2007-08-02 Bean + + * disk.h (grub_disk): Use NESTED_FUNC_ATTR. + + * file.h (grub_file): Likewise. + + * fshelp.h (grub_fshelp_read_file): Likewise. + + * util/i386/pc/grub-setup.c (setup): Likewise. + (save_first_sector): Likewise. + (save_blocklists): Likewise. + + * fs/affs.c (grub_affs_read_file): Likewise. + + * fs/ext2.c (grub_ext2_read_file): Likewise. + + * fs/fat.c (grub_fat_read_data): Likewise. + + * fs/fshelp.c (grub_fshelp_read_file): Likewise. + + * fs/hfs.c (grub_hfs_read_file): Likewise. + + * fs/hfsplus.c (grub_hfsplus_read_file): Likewise. + + * fs/jfs.c (grub_jfs_read_file): Likewise. + + * fs/minix.c (grub_minix_read_file): Likewise. + + * fs/sfs.c (grub_sfs_read_file): Likewise. + + * fs/ufs.c (grub_ufs_read_file): Likewise. + + * fs/xfs.c (grub_xfs_read_file): Likewise. + + * command/blocklist.c (read_blocklist): Likewise. + (print_blocklist): Likewise. + +2007-08-02 Marco Gerards + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `disk/host.c' and + `util/hostfs.c'. + + * disk/host.c: New file. + + * util/hostfs.c: Likewise. + + * fs/hfsplus.c (grub_hfsplus_mount): When reading out of disk, + return `GRUB_ERR_BAD_FS'. + * fs/sfs.c (grub_sfs_mount): Likewise. + * fs/xfs.c (grub_xfs_mount): Likewise. + + * include/grub/disk.h (enum grub_disk_dev_id): Add + `GRUB_DISK_DEVICE_HOST_ID'. + + * util/grub-emu.c (main): Initialize and de-initialize hostfs. + +2007-07-24 Jerone Young + + * conf/i386-pc.rmk: Add Multiboot loader and multiboot 2 to multiboot + modules for compilation. + * conf/powerpc-ieee1275.rmk: Likewise. + + * include/multiboot.h: Move multiboot definitions to one file. Rename + many definitions to not get grub specific. + * include/multiboot2.h: Create header with multiboot 2 definitions. + * include/grub/multiboot.h: Header for grub specific function + prototypes and definitions. + * include/grub/multiboot2.h: Likewise. + * include/grub/multiboot_loader.h: Likewise. + * include/grub/i386/pc/multiboot.h: Removed. + * include/grub/powerpc/ieee1275/multiboot.h: Removed. + + * loader/multiboot_loader.c: Created to act as a proxy for multiboot 1 + and 2 to allow for one multiboot and module commands. + * loader/multiboot2.c: Add multiboot2 functionality. + * loader/i386/pc/multiboot.c: Modify for new multiboot header location + and definition names. + * loader/i386/pc/multiboot2.c: Created to add i386 specific multiboot + 2 functions. + * loader/powerpc/ieee1275/multiboot2.c: Created to add powerpc + ieee1275 specific multiboot2 code. + + * kern/i386/pc/startup.S: Change headers and definition names for + multiboot. Add function grub_multiboot2_real_boot for multiboot 2. + +2007-07-22 Robert Millan + + * geninitheader.sh: Process file specified in first parameter rather + than hardcoding grub_modules_init.lst. + * geninit.sh: Likewise. Also, construct header name dynamically rather + than hardcoding grub_modules_init.h. + + * conf/common.rmk: Rename grub_modules_init.[ch] files associated with + grub-emu to grub_emu_init.[ch]. Add rules to build analogous + grub_probe_init.[ch] and grub_setup_init.[ch]. + + * conf/powerpc-ieee1275.rmk (grub_emu_DEPENDENCIES): Replace + grub_modules_init.h with grub_emu_init.h. + (grub_probe_DEPENDENCIES, grub_probe_SOURCES): Add new + grub_probe_init.[ch] files. + * conf/i386-efi.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + (grub_setup_DEPENDENCIES, grub_setup_SOURCES): Add new + grub_setup_init.[ch] files. + + * util/grub-emu.c: Replace grub_modules_init.h with grub_emu_init.h. + * util/grub-probe.c: Include grub_probe_init.h. Use grub_init_all() + to initialize modules rather than a list of hardcoded functions. + * util/i386/pc/grub-setup.c: Include grub_setup_init.h. Use + grub_init_all() to initialize modules rather than a list of hardcoded + functions. + +2007-07-22 Robert Millan + + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_find_options): Set + GRUB_IEEE1275_FLAG_NO_PARTITION_0 flag when running on SmartFirmware. + +2007-07-22 Robert Millan + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): Add + GRUB_IEEE1275_FLAG_BROKEN_OUTPUT flag. + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_find_options): Set this + flag when running on SmartFirmware. + * term/ieee1275/ofconsole.c (grub_ofconsole_init): Avoid running + "output-device output" command when GRUB_IEEE1275_FLAG_BROKEN_OUTPUT + was set. + + * kern/powerpc/ieee1275/openfw.c (grub_ieee1275_encode_devname): + Increase partno when GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS flag is set, + rather than decreasing it. + + * util/i386/pc/grub-setup.c (setup): When embedding is required, but + there's not enough space to do it, fail in the same way as when it + can't be done because there are no partitions. + + * util/powerpc/ieee1275/grub-install.in: Improve error message shown + when nvsetenv failed. + +2007-07-22 Yoshinori K. Okuji + + * conf/i386-pc.rmk (CLEANFILES): Removed for grub-mkrescue, + because this rule is automatically generated. + (grub-mkrescue): Removed for the same reason as above. + +2007-07-22 Yoshinori K. Okuji + + Migrate to GNU General Public License Version 3. + + * COPYING: Replaced with the plain text version of GPLv3. + + * config.guess: Updated from gnulib. + * config.sub: Likewise. + + * geninit.sh: Output a GPLv3 copyright notice. + * geninitheader.sh: Likewise. + * genmodsrc.sh: Likewise. + * gensymlist.sh.in: Likewise. + + * boot/i386/pc/boot.S: Upgraded to GPLv3. + * boot/i386/pc/diskboot.S: Likewise. + * boot/i386/pc/pxeboot.S: Likewise. + * commands/blocklist.c: Likewise. + * commands/boot.c: Likewise. + * commands/cat.c: Likewise. + * commands/cmp.c: Likewise. + * commands/configfile.c: Likewise. + * commands/echo.c: Likewise. + * commands/help.c: Likewise. + * commands/ls.c: Likewise. + * commands/search.c: Likewise. + * commands/terminal.c: Likewise. + * commands/test.c: Likewise. + * commands/videotest.c: Likewise. + * commands/i386/cpuid.c: Likewise. + * commands/i386/pc/halt.c: Likewise. + * commands/i386/pc/play.c: Likewise. + * commands/i386/pc/reboot.c: Likewise. + * commands/i386/pc/vbeinfo.c: Likewise. + * commands/i386/pc/vbetest.c: Likewise. + * commands/ieee1275/halt.c: Likewise. + * commands/ieee1275/reboot.c: Likewise. + * commands/ieee1275/suspend.c: Likewise. + * disk/loopback.c: Likewise. + * disk/lvm.c: Likewise. + * disk/raid.c: Likewise. + * disk/efi/efidisk.c: Likewise. + * disk/i386/pc/biosdisk.c: Likewise. + * disk/ieee1275/ofdisk.c: Likewise. + * font/manager.c: Likewise. + * fs/affs.c: Likewise. + * fs/ext2.c: Likewise. + * fs/fat.c: Likewise. + * fs/fshelp.c: Likewise. + * fs/hfs.c: Likewise. + * fs/hfsplus.c: Likewise. + * fs/iso9660.c: Likewise. + * fs/jfs.c: Likewise. + * fs/minix.c: Likewise. + * fs/sfs.c: Likewise. + * fs/ufs.c: Likewise. + * fs/xfs.c: Likewise. + * hello/hello.c: Likewise. + * include/grub/acorn_filecore.h: Likewise. + * include/grub/arg.h: Likewise. + * include/grub/bitmap.h: Likewise. + * include/grub/boot.h: Likewise. + * include/grub/cache.h: Likewise. + * include/grub/device.h: Likewise. + * include/grub/disk.h: Likewise. + * include/grub/dl.h: Likewise. + * include/grub/elfload.h: Likewise. + * include/grub/env.h: Likewise. + * include/grub/err.h: Likewise. + * include/grub/file.h: Likewise. + * include/grub/font.h: Likewise. + * include/grub/fs.h: Likewise. + * include/grub/fshelp.h: Likewise. + * include/grub/gzio.h: Likewise. + * include/grub/hfs.h: Likewise. + * include/grub/kernel.h: Likewise. + * include/grub/loader.h: Likewise. + * include/grub/lvm.h: Likewise. + * include/grub/misc.h: Likewise. + * include/grub/mm.h: Likewise. + * include/grub/net.h: Likewise. + * include/grub/normal.h: Likewise. + * include/grub/parser.h: Likewise. + * include/grub/partition.h: Likewise. + * include/grub/pc_partition.h: Likewise. + * include/grub/raid.h: Likewise. + * include/grub/rescue.h: Likewise. + * include/grub/script.h: Likewise. + * include/grub/setjmp.h: Likewise. + * include/grub/symbol.h: Likewise. + * include/grub/term.h: Likewise. + * include/grub/terminfo.h: Likewise. + * include/grub/tparm.h: Likewise. + * include/grub/types.h: Likewise. + * include/grub/video.h: Likewise. + * include/grub/efi/api.h: Likewise. + * include/grub/efi/chainloader.h: Likewise. + * include/grub/efi/console.h: Likewise. + * include/grub/efi/console_control.h: Likewise. + * include/grub/efi/disk.h: Likewise. + * include/grub/efi/efi.h: Likewise. + * include/grub/efi/pe32.h: Likewise. + * include/grub/efi/time.h: Likewise. + * include/grub/i386/linux.h: Likewise. + * include/grub/i386/setjmp.h: Likewise. + * include/grub/i386/types.h: Likewise. + * include/grub/i386/efi/kernel.h: Likewise. + * include/grub/i386/efi/loader.h: Likewise. + * include/grub/i386/efi/time.h: Likewise. + * include/grub/i386/pc/biosdisk.h: Likewise. + * include/grub/i386/pc/boot.h: Likewise. + * include/grub/i386/pc/chainloader.h: Likewise. + * include/grub/i386/pc/console.h: Likewise. + * include/grub/i386/pc/init.h: Likewise. + * include/grub/i386/pc/kernel.h: Likewise. + * include/grub/i386/pc/loader.h: Likewise. + * include/grub/i386/pc/memory.h: Likewise. + * include/grub/i386/pc/multiboot.h: Likewise. + * include/grub/i386/pc/serial.h: Likewise. + * include/grub/i386/pc/time.h: Likewise. + * include/grub/i386/pc/vbe.h: Likewise. + * include/grub/i386/pc/vbeblit.h: Likewise. + * include/grub/i386/pc/vbefill.h: Likewise. + * include/grub/i386/pc/vbeutil.h: Likewise. + * include/grub/i386/pc/vga.h: Likewise. + * include/grub/ieee1275/ieee1275.h: Likewise. + * include/grub/ieee1275/ofdisk.h: Likewise. + * include/grub/powerpc/libgcc.h: Likewise. + * include/grub/powerpc/setjmp.h: Likewise. + * include/grub/powerpc/types.h: Likewise. + * include/grub/powerpc/ieee1275/biosdisk.h: Likewise. + * include/grub/powerpc/ieee1275/console.h: Likewise. + * include/grub/powerpc/ieee1275/ieee1275.h: Likewise. + * include/grub/powerpc/ieee1275/kernel.h: Likewise. + * include/grub/powerpc/ieee1275/loader.h: Likewise. + * include/grub/powerpc/ieee1275/multiboot.h: Likewise. + * include/grub/powerpc/ieee1275/time.h: Likewise. + * include/grub/powerpc/ieee1275/util/biosdisk.h: Likewise. + * include/grub/sparc64/libgcc.h: Likewise. + * include/grub/sparc64/setjmp.h: Likewise. + * include/grub/sparc64/types.h: Likewise. + * include/grub/sparc64/ieee1275/console.h: Likewise. + * include/grub/sparc64/ieee1275/ieee1275.h: Likewise. + * include/grub/sparc64/ieee1275/kernel.h: Likewise. + * include/grub/sparc64/ieee1275/time.h: Likewise. + * include/grub/util/biosdisk.h: Likewise. + * include/grub/util/getroot.h: Likewise. + * include/grub/util/lvm.h: Likewise. + * include/grub/util/misc.h: Likewise. + * include/grub/util/raid.h: Likewise. + * include/grub/util/resolve.h: Likewise. + * io/gzio.c: Likewise. + * kern/device.c: Likewise. + * kern/disk.c: Likewise. + * kern/dl.c: Likewise. + * kern/elf.c: Likewise. + * kern/env.c: Likewise. + * kern/err.c: Likewise. + * kern/file.c: Likewise. + * kern/fs.c: Likewise. + * kern/loader.c: Likewise. + * kern/main.c: Likewise. + * kern/misc.c: Likewise. + * kern/mm.c: Likewise. + * kern/parser.c: Likewise. + * kern/partition.c: Likewise. + * kern/rescue.c: Likewise. + * kern/term.c: Likewise. + * kern/efi/efi.c: Likewise. + * kern/efi/init.c: Likewise. + * kern/efi/mm.c: Likewise. + * kern/i386/dl.c: Likewise. + * kern/i386/efi/init.c: Likewise. + * kern/i386/efi/startup.S: Likewise. + * kern/i386/pc/init.c: Likewise. + * kern/i386/pc/lzo1x.S: Likewise. + * kern/i386/pc/startup.S: Likewise. + * kern/ieee1275/ieee1275.c: Likewise. + * kern/powerpc/cache.S: Likewise. + * kern/powerpc/dl.c: Likewise. + * kern/powerpc/ieee1275/cmain.c: Likewise. + * kern/powerpc/ieee1275/crt0.S: Likewise. + * kern/powerpc/ieee1275/init.c: Likewise. + * kern/powerpc/ieee1275/openfw.c: Likewise. + * kern/sparc64/cache.S: Likewise. + * kern/sparc64/dl.c: Likewise. + * kern/sparc64/ieee1275/init.c: Likewise. + * kern/sparc64/ieee1275/openfw.c: Likewise. + * loader/efi/chainloader.c: Likewise. + * loader/efi/chainloader_normal.c: Likewise. + * loader/i386/efi/linux.c: Likewise. + * loader/i386/efi/linux_normal.c: Likewise. + * loader/i386/pc/chainloader.c: Likewise. + * loader/i386/pc/chainloader_normal.c: Likewise. + * loader/i386/pc/linux.c: Likewise. + * loader/i386/pc/linux_normal.c: Likewise. + * loader/i386/pc/multiboot.c: Likewise. + * loader/i386/pc/multiboot_normal.c: Likewise. + * loader/powerpc/ieee1275/linux.c: Likewise. + * loader/powerpc/ieee1275/linux_normal.c: Likewise. + * normal/arg.c: Likewise. + * normal/cmdline.c: Likewise. + * normal/command.c: Likewise. + * normal/completion.c: Likewise. + * normal/execute.c: Likewise. + * normal/function.c: Likewise. + * normal/lexer.c: Likewise. + * normal/main.c: Likewise. + * normal/menu.c: Likewise. + * normal/menu_entry.c: Likewise. + * normal/misc.c: Likewise. + * normal/parser.y: Likewise. + * normal/script.c: Likewise. + * normal/i386/setjmp.S: Likewise. + * normal/powerpc/setjmp.S: Likewise. + * normal/sparc64/setjmp.S: Likewise. + * partmap/acorn.c: Likewise. + * partmap/amiga.c: Likewise. + * partmap/apple.c: Likewise. + * partmap/gpt.c: Likewise. + * partmap/pc.c: Likewise. + * partmap/sun.c: Likewise. + * term/gfxterm.c: Likewise. + * term/terminfo.c: Likewise. + * term/efi/console.c: Likewise. + * term/i386/pc/console.c: Likewise. + * term/i386/pc/serial.c: Likewise. + * term/i386/pc/vesafb.c: Likewise. + * term/i386/pc/vga.c: Likewise. + * term/ieee1275/ofconsole.c: Likewise. + * util/biosdisk.c: Likewise. + * util/console.c: Likewise. + * util/genmoddep.c: Likewise. + * util/getroot.c: Likewise. + * util/grub-emu.c: Likewise. + * util/grub-mkdevicemap.c: Likewise. + * util/grub-probe.c: Likewise. + * util/lvm.c: Likewise. + * util/misc.c: Likewise. + * util/raid.c: Likewise. + * util/resolve.c: Likewise. + * util/update-grub.in: Likewise. + * util/update-grub_lib.in: Likewise. + * util/grub.d/00_header.in: Likewise. + * util/grub.d/10_hurd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. + * util/i386/efi/grub-install.in: Likewise. + * util/i386/efi/grub-mkimage.c: Likewise. + * util/i386/pc/grub-install.in: Likewise. + * util/i386/pc/grub-mkimage.c: Likewise. + * util/i386/pc/grub-mkrescue.in: Likewise. + * util/i386/pc/grub-setup.c: Likewise. + * util/i386/pc/misc.c: Likewise. + * util/powerpc/ieee1275/grub-install.in: Likewise. + * util/powerpc/ieee1275/grub-mkimage.c: Likewise. + * util/powerpc/ieee1275/misc.c: Likewise. + * video/bitmap.c: Likewise. + * video/video.c: Likewise. + * video/i386/pc/vbe.c: Likewise. + * video/i386/pc/vbeblit.c: Likewise. + * video/i386/pc/vbefill.c: Likewise. + * video/i386/pc/vbeutil.c: Likewise. + * video/readers/tga.c: Likewise. + +2007-07-02 Robert Millan + + * conf/i386-efi.rmk: Replace obsolete reference to + util/i386/pc/biosdisk.c with util/biosdisk.c, and util/i386/pc/getroot.c + with util/getroot.c. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + + * util/grub-emu.c (main): Fix unchecked pointer handling. + +2007-07-02 Robert Millan + + * util/i386/efi/grub-install.in: Allow `grub_probe --target=partmap' + invocation to fail, in order to support partition-less media. + + * util/i386/pc/grub-install.in: Likewise. + + * util/powerpc/ieee1275/grub-install.in: Use grub-probe to determine + which fs or partmap modules are needed (akin to its sister scripts). + + Also use grub-probe to get rid of unportable /proc/mounts check. + + Print the same informational message that the other scripts do, before + exiting. + +2007-06-23 Robert Millan + + * util/update-grub_lib.in (font_path): New function. Determine whether + a font file can be found and, if so, echo the GRUB path to it. + + * util/update-grub.in: Handle multiple terminals depending on user + input, platform availability and font file presence. Propagate + variables of our findings to /etc/grub.d/ children. + + * util/grub.d/00_header.in: Handle multiple terminals, based on + environment setup by update-grub. + +2007-06-23 Robert Millan + + * conf/i386-pc.rmk (pkgdata_MODULES): Add serial.mod. + +2007-06-21 Robert Millan + + * include/grub/i386/pc/kernel.h: Define GRUB_KERNEL_MACHINE_DATA_END to + indicate end of data section in kernel image. + * include/grub/i386/efi/kernel.h: Define GRUB_KERNEL_MACHINE_PREFIX and + GRUB_KERNEL_MACHINE_DATA_END. + + * kern/i386/pc/startup.S: Do not initialize grub_prefix, only reserve + space for it. + * kern/i386/efi/startup.S: Likewise. + + * util/i386/pc/grub-mkimage.c: Initialize grub_prefix to /boot/grub + during image generation. Implement --prefix option to override this + patch. + * util/i386/efi/grub-mkimage.c: Likewise. + + * util/update-grub_lib.in (convert_system_path_to_grub_path): Split + code to make path relative to its root into a separate function. + + * util/i386/pc/grub-install.in: Use newly provided + make_system_path_relative_to_its_root() to convert ${grubdir}, then + pass the result to grub-install --prefix. + +2007-06-13 Robert Millan + + * include/grub/util/misc.h: Define DEFAULT_DIRECTORY and + DEFAULT_DEVICE_MAP. + * util/grub-emu.c: Use above definitions from misc.h instead of + defining them. + * util/grub-mkdevicemap.c: Likewise. + * util/i386/pc/grub-setup.c: Likewise. + * util/grub-probe.c: Likewise. + (probe): Abort with grub_util_error() when either + grub_guess_root_device or grub_util_get_grub_dev fails. + +2007-06-12 Robert Millan + + * normal/command.c (grub_command_execute): Use NULL rather than 0 for + "pager" assignment. + * util/biosdisk.c (grub_util_biosdisk_get_grub_dev): Likewise for + "pcdata". + * util/grub-probe.c (probe): Likewise for "drive_name". + +2007-06-11 Robert Millan + + * util/i386/pc/grub-mkrescue.in: Pad both floppy images with zeroes, + not just the cdrom one. + +2007-06-11 Robert Millan + + * util/i386/pc/grub-mkrescue.in: Add "set -e". + Add --pkglibdir=DIR option to override pkglibdir. + Mention --image-type=TYPE in help output. + Fix --grub-mkimage (it was a no-op). + Abort gracefully when no parameter is given. + +2007-06-11 Robert Millan + + * util/i386/pc/grub-mkrescue.in: New file. + * conf/i386-pc.rmk: Add its build declarations. Put it in bin_SCRIPTS. + * Makefile.in: Handle bin_SCRIPTS. + +2007-06-10 Vesa Jaaskelainen + + * term/gfxterm.c (grub_gfxterm_init): Added support for specifying + list of video modes. + +2007-06-06 Robert Millan + + * util/update-grub_lib.in (convert_system_path_to_grub_path): Abort if + file doesn't exist, or if it is in a filesystem grub can't read. + + * util/update-grub.in: Set fallback for GRUB_FS check to "unknown". Do + not abort if GRUB_DRIVE could not be defined. Rearrange generated + header comment to fit in 80 columns when the variables are resolved. + + * util/grub.d/00_header.in: Only set root variable when GRUB_DRIVE + could be identified by update-grub. Remove redundant check for + unifont.pff existence (since convert_system_path_to_grub_path now + handles that). + +2007-06-04 Robert Millan + + * conf/i386-efi.rmk (grub_probe_SOURCES): Add partmap/apple.c. + + * conf/i386-pc.rmk (grub_probe_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_probe_SOURCES): Add partmap/pc.c. + +2007-06-04 Robert Millan + + * conf/powerpc-ieee1275.rmk: Enable grub-mkdevicemap and grub-probe. + + * include/grub/partition.h: Declare grub_apple_partition_map_init and + grub_apple_partition_map_fini. + + * util/biosdisk.c + (grub_util_biosdisk_open): Replace BLKGETSIZE with BLKGETSIZE64 (needed + to access >2 TiB disks). + + Print disk->total_sectors with %llu instead of %lu, since this + variable is always 64-bit (prevents wrong disk size from being displayed + on either >2 TiB disk or big-endian CPU). + + (grub_util_biosdisk_get_grub_dev): Convert gpt_partition_map handling + into a generic case that supports all (sane) partition maps. + + Stop using grub_cpu_to_le32() on dos_part / bsd_part since it actually + breaks big-endian. + + * util/grub-probe.c: Call grub_apple_partition_map_init() before probe() + and grub_apple_partition_map_fini() after that. + +2007-06-01 Robert Millan + + * util/update-grub.in: Export GRUB_CMDLINE_LINUX. + + * util/grub.d/00_header.in: Only enable gfxterm when + convert_system_path_to_grub_path() succeeds. + +2007-05-20 Robert Millan + + * util/update-grub_lib.in: New file. + * DISTLIST: Add update-grub_lib.in. + * conf/common.rmk: Generate update-grub_lib and install it in + $(lib_DATA). + * Makefile.in: Add install routine for $(lib_DATA). + + * util/grub.d/00_header.in: Use convert_system_path_to_grub_path() + function provided by update-grub_lib to support arbitrary paths of + unifont.pff. + * util/update-grub.in: Use convert_system_path_to_grub_path() to + initialize GRUB_DRIVE_BOOT and GRUB_DRIVE_BOOT_GRUB variables. + +2007-05-19 Robert Millan + + * commands/i386/cpuid.c: New module. + * DISTLIST: Add it. + * conf/i386-efi.rmk: Enable cpuid.mod. + * conf/i386-pc.rmk: Likewise. + +2007-05-18 Jeroen Dekkers + + * kern/disk.c (grub_disk_read): Check return value of + grub_realloc(). + +2007-05-18 Jeroen Dekkers + + * util/getroot.c (grub_util_get_grub_dev): Support partitionable + arrays. + * disk/raid.c (grub_raid_open): Likewise. + +2007-05-17 Jeroen Dekkers + + * util/biosdisk.c (linux_find_partition): Allocate real_dev on the + stack instead of on the heap. + + * kern/disk.c (grub_disk_read): Make sure tmp_buf is big enough + before doing a read on it. + + * configure.ac: Only use -fno-stack-protector for the target + environment. + +2007-05-17 Jeroen Dekkers + + * video/i386/pc/vbe.c (grub_video_vbe_create_render_target): Add + __attribute_ ((unused)) to mode_type argument. + + * util/getroot.c (grub_guess_root_device): Fix #endif. + + * kern/misc.c (memcmp): Fix prototype. + + * include/grub/partition.h [GRUB_UTIL] + (grub_gpt_partition_map_init): Add prototype. + (grub_gpt_partition_map_fini): Likewise. + + * fs/jfs.c (struct grub_jfs_inode): Put __attribute__ ((packed) + at the right place. + + * fs/fat.c (grub_fat_mount): Replace ~0UL with ~0U. + (grub_fat_read_data): Likewise. + (grub_fat_find_dir): Likewise. + + * font/manager.c (find_glyph): Make table a const. + (grub_font_get_glyph): Remove bitmap from if statement. + +2007-05-16 Jeroen Dekkers + + * util/getroot.c (grub_guess_root_device): Remove RAID and LVM + code, first search for device in /dev/mapper, then in /dev. + (grub_util_get_grub_dev): New function. + * include/grub/util/getroot.h (grub_util_get_grub_dev): Add + prototype. + * util/grub-probe.c (probe): Remove check for RAID, call + grub_util_get_grub_dev() instead of + grub_util_biosdisk_get_grub_dev(). + * util/grub-emu.c (main): Call grub_util_get_grub_dev() instead of + grub_util_biosdisk_get_grub_dev(). + * util/i386/pc/grub-setup.c (main): Likewise. + +2007-05-16 Robert Millan + + * DISTLIST: Update for the latest changes. + * conf/i386-pc.rmk: Use the new paths for util/getroot.c, + util/grub-mkdevicemap.c, util/grub-probe.c and util/biosdisk.c. + * util/grub-emu.c: Replace grub/i386/pc/util/biosdisk.h with + grub/util/biosdisk.h. + * util/i386/pc/grub-setup.c: Replace grub/machine/util/biosdisk.h with + grub/util/biosdisk.h. + +2007-05-16 Robert Millan + + * util/grub.d/00_header.in: Set default gfxmode to `640x480'. + +2007-05-16 Robert Millan + + * util/i386/efi/grub-install.in: New. + * conf/i386-efi.rmk: Enable grub-mkdevicemap, grub-probe and the + newly added grub-install. + * util/biosdisk.c: Remove unnecessary grub/machine/biosdisk.h + include. + * util/getroot.c: Replace grub/i386/pc/util/biosdisk.h with + grub/util/biosdisk.h. + * util/grub-probe.c: Replace grub/machine/util/biosdisk.h with + grub/util/biosdisk.h. + +2007-05-16 Robert Millan + + * include/grub/i386/pc/util/biosdisk.h: Moved to ... + * include/grub/util/biosdisk.h: ... here. + * util/i386/pc/biosdisk.c: Moved to ... + * util/biosdisk.c: ... here. + * util/i386/pc/getroot.c: Moved to ... + * util/getroot.c: ... here. + * util/i386/pc/grub-mkdevicemap.c: Moved to ... + * util/grub-mkdevicemap.c: ... here. + * util/i386/pc/grub-probe.c: Moved to ... + * util/grub-probe.c: ... here. + +2007-05-15 Robert Millan + + * util/update-grub.in: Remove duplicated line in grub.cfg header + message. + +2007-05-13 Robert Millan + + * util/update-grub.in: Fix a few assumptions about the devices holding + /, /boot and /boot/grub being the same. + * util/grub.d/00_header.in: Likewise. + * util/grub.d/10_hurd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. + + * util/grub.d/10_linux.in: Implement Linux image sorting with arbitrary + patterns. Use that to define the `.old' suffix as older than `'. + + * util/grub.d/00_header.in: Set default gfxmode to `800x600x16'. + + * util/update-grub.in: Add a reference to ${sysconfdir}/default/grub in + the grub.cfg header message. + +2007-05-11 Robert Millan + + * util/update-grub.in: Create device.map if it doesn't already exist, + before attempting to run grub-probe. + Check for grub-probe and grub-mkdevicemap with the same code + grub-install is using. + Remove test mode. + +2007-05-09 Jeroen Dekkers + + * Makefile.in: Add the datarootdir autoconf variable. + +2007-05-09 Robert Millan + + * util/i386/pc/grub-probe.c (probe): When detecting partition map, + fail gracefully if dev->disk->partition == NULL. + +2007-05-07 Robert Millan + + * util/i386/pc/grub-probe.c: Add `grub-probe -t partmap' parameter to + determine partition map module. + * util/i386/pc/grub-install.in: Use this feature to decide which + partition module to load, instead of hardcoding pc and gpt. + +2007-05-07 Robert Millan + + * Makefile.in: Fix assumption that $(srcdir) has a trailing slash when + source directory differs from build directory. + +2007-05-05 Robert Millan + + * util/powerpc/ieee1275/grub-install.in: Fix syntax error in pkglibdir + initialisation. + +2007-05-05 Robert Millan + + * util/update-grub.in: Create ${grub_prefix} if it doesn't exist. + +2007-05-05 Robert Millan + + * util/grub.d/10_linux.in: Allow the administrator to insert Linux + command-line arguments via ${GRUB_CMDLINE_LINUX}. + +2007-05-05 Robert Millan + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add partmap/gpt.c. + (grub_probe_SOURCES): Likewise. + * util/i386/pc/biosdisk.c (grub_util_biosdisk_get_grub_dev): Detect + GPT and initialize dos_part and bsd_part accordingly. + * util/i386/pc/grub-setup.c (setup): Ditto for install_dos_part and + install_bsd_part. + (main): Activate gpt module for use during partition identification, + and deactivate it afterwards. + * util/i386/pc/grub-install.in: Add gpt module to core.img. + * util/i386/pc/grub-probe.c (main): Activate gpt module for use during + partition identification, and deactivate it afterwards. + +2007-05-05 Robert Millan + + * term/i386/pc/console.c (grub_console_fini): Call + grub_term_set_current() before grub_term_unregister(). + +2007-05-04 Robert Millan + + * DISTLIST: Add util/update-grub.in, util/grub.d/00_header.in, + util/grub.d/10_hurd.in, util/grub.d/10_linux.in and util/grub.d/README. + * Makefile.in: Build update-grub_SCRIPTS. Install update-grub_SCRIPTS + and update-grub_DATA. + * conf/common.rmk: Build and install update-grub components. + * conf/common.mk: Regenerate. + * util/update-grub.in: New. Core of update-grub. + * util/grub.d/00_header.in: New. Generates grub.cfg header. + * util/grub.d/10_hurd.in: New. Generates boot entries for the Hurd. + * util/grub.d/10_linux.in: New. Generates boot entries for Linux. + * util/grub.d/README: New. Document grub.d directory layout. + +2007-05-01 Robert Millan + + * util/grub-emu.c: Move initialization functions + grub_util_biosdisk_init() and grub_init_all() before + grub_util_biosdisk_get_grub_dev(), which relies on them. + +2007-04-19 Robert Millan + + * util/powerpc/ieee1275/grub-install.in: Initialize ${bindir}, since + it is used later. + +2007-04-18 Jerone Young + + * kernel/elf.c: Add missing parenthesis for conditional statement + stanza. + +2007-04-10 Jerone Young + + * util/i386/pc/getroot.c: Update so that if root device is /dev/root , + continue on and look for device node with real device name. + +2007-04-10 Jerone Young + + * configure.ac: Add argument for autoconf to use transformation + ability. + * Makefile.in: Add autoconf package transformation code. + * util/i386/pc/grub-install.in: Likewise. + * util/powerpc/ieee1275/grub-install.in: Likewise. + +2007-03-19 Yoshinori K. Okuji + + * fs/ext2.c (EXT2_GOOD_OLD_REVISION): New macro. + (EXT2_GOOD_OLD_INODE_SIZE): Likewise. + (EXT2_REVISION): Likewise. + (EXT2_INODE_SIZE): Likewise. + (struct grub_ext2_block_group): Added a missing member + "used_dirs". + (grub_ext2_read_inode): Divide by the inode size in a superblock + instead of 128 to obtain INODES_PER_BLOCK. + Use the macro EXT2_INODE_SIZE instead of directly using + SBLOCK->INODE_SIZE. + +2007-03-18 Yoshinori K. Okuji + + * fs/ext2.c (grub_ext2_read_inode): Use the inode size in a + superblock instead of the structure size to compute an + offset. This fixes the problem that GRUB could not read a + filesystem when inode size is different from 128-byte. + +2007-03-05 Marco Gerards + + * normal/main.c (read_config_file): When "menu" is not set, create + an initial context. + +2007-02-21 Hollis Blanchard + + * kern/powerpc/ieee1275/init.c (HEAP_SIZE): Removed. + (HEAP_LIMIT): New macro. + (grub_claim_heap): Claim memory up to `heaplimit'. + +2007-02-21 Hollis Blanchard + + * conf/powerpc-ieee1275.rmk (kernel_elf_LDFLAGS): Link at 64KB. + * kern/powerpc/ieee1275/init.c (_end): Add declaration. + (_start): Likewise. + (grub_arch_modules_addr): Return address after `_end'. + * util/powerpc/ieee1275/grub-mkimage.c: Include grub/misc.h. + (load_modules): Use new parameter as `p_paddr' and `p_vaddr'. + (add_segments): Calculate `_end' from phdr size and location. + (ALIGN_UP): Moved to ... + * include/grub/misc.h: here. + * include/grub/powerpc/ieee1275/kernel.h (GRUB_IEEE1275_MOD_ALIGN): + New macro. + (GRUB_IEEE1275_MODULE_BASE): Removed. + +2007-02-20 Hollis Blanchard + + * kern/powerpc/ieee1275/openfw.c (grub_available_iterate): Correct + loop boundary. + +2007-02-20 Hollis Blanchard + + * include/grub/elfload.h (grub_elf32_load_hook_t): Return grub_err_t. + All users updated. + (grub_elf64_load_hook_t): Likewise. + * kern/elf.c: Call `grub_error_push' before `grub_error'. Improve + debug output. + +2007-02-20 Hollis Blanchard + + * kern/mm.c: Update copyright. + (grub_mm_debug): Correct syntax error. + (grub_mm_dump_free): New function. + (grub_debug_free): Call `grub_free'. + * include/grub/mm.h: Update copyright. + (grub_mm_dump_free): Add declaration. + +2007-02-12 Hollis Blanchard + + * include/grub/ieee1275/ieee1275.h: Update copyright. + * kern/powerpc/ieee1275/init.c: Likewise. + * kern/powerpc/ieee1275/openfw.c: Likewise. + + * loader/powerpc/ieee1275/linux.c: Likewise. + * include/grub/elfload.h: Likewise. + * kern/elf.c: Likewise. + (grub_elf32_load): Pass `base' and `size' parameters. Update all + callers. + (grub_elf64_load): Likewise. + (grub_elf32_load_segment): Move to a nested function. + (grub_elf64_load_segment): Likewise. + +2007-02-12 Hollis Blanchard + + * include/grub/ieee1275/ieee1275.h (grub_available_iterate): New + prototype. + * kern/powerpc/ieee1275/init.c (grub_heap_start): Removed. + (grub_heap_len): Likewise. + (HEAP_SIZE): New macro. + (grub_claim_heap): New function. + (grub_machine_init): Don't claim heap directly. Call + `grub_claim_heap'. + * kern/powerpc/ieee1275/openfw.c: Include alloca.h. + (grub_available_iterate): New function. + +2007-02-03 Thomas Schwinge + + * aclocal.m4 (grub_CHECK_STACK_PROTECTOR): New definition. + * configure.ac: Use it for testing the HOST and TARGET compilers. + +2006-12-13 Thomas Schwinge + + * Makefile.in (enable_grub_emu): New variable. + * configure.ac (--enable-grub-emu): New option. + Do the checks for (n)curses only if `--enable-grub-emu' is requested. + * conf/i386-efi.rmk (sbin_UTILITIES): Add `grub-emu' only if requested. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk (bin_UTILITIES): Likewise. + +2006-12-12 Marco Gerards + + * include/grub/err.h (grub_err_t): Add `GRUB_ERR_MENU'. + + * kern/env.c (grub_env_unset): Don't free the member `value' when + the type is GRUB_ENV_VAR_DATA, in this case it's a user defined + pointer. + + * normal/main.c (current_menu): Removed. + (free_menu): Unset the `menu' environment variable. + (grub_normal_menu_addentry): Make use of the environment variable + `menu', instead of using the global `current_menu'. Allocate + memory for the sourcecode of this entry. + (read_config_file): New argument `nested', changed all callers. + Only in the case of a new context, initialize a new menu. Set the + `menu' environment variable. + (grub_normal_execute): Don't set and unset the environment + variable `menu' here anymore. Only free the menu when leaving the + context. + + * util/i386/pc/biosdisk.c (linux_find_partition): Fixed a memory + leak. + +2006-12-11 Marco Gerards + + * normal/menu_entry.c (run): Fix off by one bug so the last line + is executed. Move the loader check to outside the loop. + +2006-12-08 Hollis Blanchard + + * kern/powerpc/ieee1275/cmain.c (cmain): Mark r3 and r4 as `UNUSED'. + +2006-11-25 Yoshinori K. Okuji + + * util/i386/pc/grub-mkimage.c (generate_image): Fix the offset of + the number of sectors. Reported by Andrey Shuvikov + . + +2006-11-11 Jeroen Dekkers + + * kern/disk.c (grub_disk_read): When there is a read error, always + try to read only the necessary data. + + * conf/i386-pc.rmk (grub_probe_SOURCES): Add disk/lvm.c and + disk/raid.c. + * include/grub/disk.h [GRUB_UTIL] (grub_raid_init): New + prototype. + [GRUB_UTIL] (grub_raid_fini): Likewise. + [GRUB_UTIL] (grub_lvm_init): Likewise. + [GRUB_UTIL] (grub_lvm_fini): Likewise. + * util/i386/pc/grub-probe.c (probe): Check whether DEVICE_NAME is + RAID device and copy DEVICE_NAME to DRIVE_NAME in that case. + (main): Call grub_raid_init(), grub_lvm_init(), grub_lvm_fini() + and grub_raid_fini(). + +2006-11-09 Jeroen Dekkers + + * include/grub/types.h (__unused): Rename to UNUSED. + * kern/elf.c (grub_elf32_size): Use UNUSED instead of __unused. + (grub_elf64_size): Likewise. + +2006-11-03 Hollis Blanchard + + * kern/elf.c (grub_elf_file): Call grub_file_seek. Call + grub_error_push and grub_error_pop in the error-handling path. + (grub_elf32_load_segment): Only call grub_file_read with non-zero + length. + +2006-11-03 Hollis Blanchard + + * conf/i386-efi.rmk (grub_emu_SOURCES): Add kern/elf.c. + * conf/i386-pc.rmk (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + (kernel_elf_SOURCES): Likewise. + * conf/i386-efi.rmk (kernel_mod_HEADERS): Add elfload.h and cache.h. + * conf/i386-pc.rmk (kernel_mod_HEADERS): Likewise. + * conf/powerpc-ieee1275.rmk (kernel_elf_HEADERS): Likewise. + * conf/sparc64-ieee1275.rmk (kernel_elf_HEADERS): Likewise. + * conf/common.rmk (pkgdata_MODULES): Add elf.mod. + (elf_mod_SOURCES): New variable. + (elf_mod_CFLAGS): Likewise. + (elf_mod_LDFLAGS): Likewise. + * include/grub/types.h (__unused): New macro. + * include/grub/elfload.h: New file. + * kern/elf.c: Likewise. + * loader/powerpc/ieee1275/linux.c: Include elfload.h. + (ELF32_LOADMASK): New macro. + (ELF64_LOADMASK): Likewise. + (vmlinux): Removed. + (grub_linux_load32): New function. + (grub_linux_load64): Likewise. + (grub_rescue_cmd_linux): Call grub_linux_load32 or grub_linux_load64. + Use grub_elf_t instead of grub_file_t. + +2006-11-02 Hollis Blanchard + + * kern/ieee1275/ieee1275.c (grub_ieee1275_set_color): Add + `catch_result' to struct set_color_args. + +2006-10-28 Yoshinori K. Okuji + + * normal/menu.c: Include grub/script.h. + * normal/menu_entry.c: Likewise. + * include/grub/normal.h: Do not include grub/script.h. + +2006-10-27 Hollis Blanchard + + * kern/disk.c (grub_disk_read): Correct debug printf formatting. + +2006-10-27 Hollis Blanchard + + * kern/disk.c (grub_disk_open): Print debug messages when opening a + disk. + (grub_disk_close): Print debug messages when closing a disk. + (grub_disk_read): Print debug messages when disk read fails. + * kern/fs.c (grub_fs_probe): Print debug messages when detecting + filesystem type. + * kern/partition.c: Include misc.h. + (grub_partition_iterate): Print debug messages when detecting + partition type. + +2006-10-27 Hollis Blanchard + + * disk/ieee1275/ofdisk.c (grub_ofdisk_read): Return error if `status' + is negative. + * kern/ieee1275/ieee1275.c (IEEE1275_IHANDLE_INVALID): Change to 0. + +2006-10-26 Hollis Blanchard + + * kern/powerpc/ieee1275/openfw.c (grub_ieee1275_encode_devname): + Reverse GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS test. + +2006-10-25 Jeroen Dekkers + + * disk/lvm.c (grub_lvm_scan_device): Malloc sizeof(*lv) bytes + instead of sizeof(lv). Patch by Michael Guntsche. + +2006-10-18 Jeroen Dekkers + + * disk/lvm.c: Rename VGS to VG_LIST. + (grub_lvm_iterate): Change VGS->LV to VG-LV. + (grub_lvm_open): Likewise. + Thanks to Michael Guntsche for finding this bug. + +2006-10-15 Yoshinori K. Okuji + + * configure.ac (AC_INIT): Bumped to 1.95. + +2006-10-14 Robert Millan + + * util/i386/pc/getroot.c (grub_guess_root_device): Don't compare os_dev + with "/dev/.static/dev/md". + +2006-10-14 Yoshinori K. Okuji + + * util/i386/pc/grub-probe.c (probe): Print DEVICE_NAME instead of + DRIVE_NAME when grub_util_biosdisk_get_grub_dev fails. Open + DRIVE_NAME instead of DEVICE_NAME. Make sure that DEVICE_NAME and + DRIVE_NAME are always freed. + + * util/i386/pc/biosdisk.c (make_device_name): Add one into + DOS_PART, as a DOS partition is counted from one instead of zero + now. Reported by Robert Millan. + +2006-10-14 Robert Millan + + * util/i386/pc/getroot.c (grub_guess_root_device): Stop using + grub_util_biosdisk_get_grub_dev to convert system device to GRUB device. + * util/grub-emu.c (main): Use grub_util_biosdisk_get_grub_dev with the + string returned by grub_guess_root_device. + * util/i386/pc/grub-setup.c: Likewise. + * util/i386/pc/grub-probefs.c: Likewise. + + * util/i386/pc/grub-probefs.c: Rename to ... + * util/i386/pc/grub-probe.c: ... this. + * DISTLIST: Remove grub-probefs, add grub-probe. + * conf/i386-efi.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * util/i386/pc/grub-install.in: Likewise. + + * util/i386/pc/grub-probe.c: Add --target=(fs|device|drive) option to + choose which information we want to print. + +2006-10-14 Yoshinori K. Okuji + + * DISTLIST: Added commands/echo.c, disk/lvm.c, disk/raid.c, + include/grub/bitmap.h, include/grub/lvm.h, include/grub/raid.h, + include/grub/i386/pc/vbeutil.h, include/grub/util/lvm.h, + include/grub/util/raid.h, util/lvm.c, util/raid.c, video/bitmap.c, + video/readers/tga.c and video/i386/pc/vbeutil.c. + +2006-10-14 Jeroen Dekkers + + Added support for RAID and LVM. + + * disk/lvm.c: New file. + * disk/raid.c: Likewise. + * include/grub/lvm.h: Likewise. + * include/grub/raid.h: Likewise. + * include/grub/util/lvm.h: Likewise. + * include/grub/util/raid.h: Likewise. + * util/lvm.c: Likewise. + * util/raid.c: Likewise. + + * include/grub/disk.h (grub_disk_dev_id): Add + GRUB_DISK_DEVICE_RAID_ID and GRUB_DISK_DEVICE_LVM_ID. + (grub_disk_get_size): New prototype. + * kern/disk.c (grub_disk_open): Check whether grub_partition_probe() + returns a partition. + (grub_disk_get_size): New function. + + * kern/i386/pc/init.c (make_install_device): Copy the prefix + verbatim if grub_install_dos_part is -2. + + * util/i386/pc/getroot.c (grub_guess_root_device): Support RAID + and LVM devices. + + * util/i386/pc/grub-setup.c (setup): New argument + MUST_EMBED. Force embedding of GRUB when the argument is + true. Close FILE before returning. + (main): Add support for RAID and LVM. + + * conf/common.rmk: Add RAID and LVM modules. + * conf/i386-pc.rmk (grub_setup_SOURCES): Add util/raid.c and + util/lvm.c. + (grub_emu_SOURCES): Add disk/raid.c and disk/lvm.c. + + * kern/misc.c (grub_strstr): New function. + * include/grub/misc.h (grub_strstr): New prototype. + +2006-10-10 Tristan Gingold + + * include/grub/efi/api.h (GRUB_EFI_ERROR_CODE): Long constant. + +2006-10-05 Tristan Gingold + + * kern/misc.c (grub_strtoull): Guess the base only if not + specified. + +2006-10-01 Hollis Blanchard + + * kern/powerpc/ieee1275/cmain.c (cmain): Remove incomplete Old World + PowerMac support. + +2006-10-01 Hollis Blanchard + + * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Cast `size' to long. + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_next_property): + Remove `flags' argument. All callers changed. + * kern/ieee1275/ieee1275.c (IEEE1275_PHANDLE_ROOT): Removed. + (IEEE1275_IHANDLE_INVALID): New variable. + (IEEE1275_CELL_INVALID): New variable. + (grub_ieee1275_finddevice, grub_ieee1275_get_property, + grub_ieee1275_get_property_length, grub_ieee1275_instance_to_package, + grub_ieee1275_package_to_path, grub_ieee1275_instance_to_path, + grub_ieee1275_peer, grub_ieee1275_child, grub_ieee1275_open, + grub_ieee1275_claim, grub_ieee1275_set_property): Error-check return + codes from Open Firmware. All callers updated. + (grub_ieee1275_next_property): Directly return Open Firmware return + code. + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_find_options): + Standardize error checking from `grub_ieee1275_get_property'. + * kern/powerpc/ieee1275/openfw.c (grub_devalias_iterate): Rename + `devalias' to `aliases'. Correct comments. Consolidate error paths. + +2006-10-01 Hollis Blanchard + + * kern/ieee1275/ieee1275.c (grub_ieee1275_instance_to_path): Rename + `instance_to_package_args' to `instance_to_path_args'. + + * kern/powerpc/ieee1275/init.c (grub_machine_init): Use + `grub_ieee1275_chosen'. + + * term/ieee1275/ofconsole.c (grub_ofconsole_init): Call + `grub_ieee1275_interpret'. + +2006-09-25 Hollis Blanchard + + * util/powerpc/ieee1275/grub-mkimage.c: Include config.h. + +2006-09-25 Hollis Blanchard + + * include/grub/powerpc/libgcc.h (__floatdisf): New prototype. + (__cmpdi): Likewise. + + * kern/powerpc/ieee1275/openfw.c (grub_devalias_iterate): Pass 0 as + `flags' to `grub_ieee1275_next_property'. Change `pathlen' to type + `grub_ssize_t'. + + * kern/powerpc/ieee1275/cmain.c: Include grub/misc.h. + + * loader/powerpc/ieee1275/linux.c (grub_linux_boot): Change `actual' + to type `grub_ssize_t'. + (grub_rescue_cmd_linux): Cast -1 to `grub_off_t'. + +2006-09-22 Marco Gerards + + * normal/script.c (grub_script_create_cmdmenu): Skip leading + newlines. + +2006-09-22 Marco Gerards + + * commands/echo.c: New file. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `commands/echo.c'. + + * conf/common.rmk (echo_mod_SOURCES): New variable. + (echo_mod_CFLAGS): Likewise. + (echo_mod_LDFLAGS): Likewise. + +2006-09-22 Marco Gerards + + * normal/main.c (get_line): Malloc memory instead of using + preallocated memory. Removed the arguments `cmdline' and + `max_len'. Updated all callers. + +2006-09-22 Marco Gerards + + * conf/i386-efi.rmk (grub_emu_DEPENDENCIES): New variable. + (normal_mod_DEPENDENCIES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_DEPENDENCIES): Likewise. + (normal_mod_DEPENDENCIES): Likewise. + + * conf/sparc64-ieee1275.rmk (normal_mod_DEPENDENCIES): Likewise. + +2006-09-22 Johan Rydberg + + * genmk.rb: Add DEPENDENCIES variables to modules, utilities, and + programs. + * conf/i386-pc.rmk (grub_emu_DEPENDENCIES): Declare. + (normal_mod_DEPENDENCIES): Likewise. + * conf/i386-pc.mk: Regenerate. + * conf/i386-efi.mk: Likewise + * conf/common.mk: Likewise. + * conf/powerpc-ieee1275.mk: Likewise. + * conf/sparc64-ieee1275.mk: Likewise. + +2006-09-22 Robert Millan + + Sync with i386 version. + * conf/powerpc-ieee1275.rmk (bin_UTILITIES): Remove grub-emu, add grub-mkimage. + * conf/powerpc-ieee1275.rmk (sbin_UTILITIES): Remove grub-mkimage, add grub-emu. + +2006-09-21 Robert Millan + + Import from GRUB Legacy (lib/device.c): + * util/i386/pc/grub-mkdevicemap.c (get_i2o_disk_name): New function. + (init_device_map) [__linux__]: Add support for I2O devices. + +2006-09-14 Marco Gerards + + * conf/i386-pc.rmk (COMMON_LDFLAGS): Use `-m32' instead of + `-melf_i386'. + +2006-09-14 Robert Millan + + * util/i386/pc/grub-install.in: Skip menu.lst when removing + /boot/grub/*.lst. + + * util/i386/pc/getroot.c: Don't recurse into dotdirs (e.g. ".static"). + + * util/i386/pc/grub-mkdevicemap.c: Make sure the floppy device exists + before adding it to device.map. + +2006-08-15 Johan Rydberg + + * genmk.rb: Let GCC generate dependencies the first time it + compiles a file; using the -MD option. + * conf/common.mk: Regenerate. + * conf/i386-pc.mk: Likewise. + * conf/i386-efi.mk: Likewise. + * conf/powerpc-ieee1275.mk: Likewise. + * conf/sparc64-ieee1275.mk: Likewise. + +2006-08-04 Yoshinori K. Okuji + + Move the prototypes of grub_setjmp and grub_longjmp to + cpu/setjmp.h, so that each architecture may specify different + attributes. + + * include/grub/i386/setjmp.h (grub_setjmp): New prototype. + (grub_longjmp): Likewise. + * include/grub/powerpc/setjmp.h (grub_setjmp): Likewise.. + (grub_longjmp): Likewise. + * include/grub/sparc64/setjmp.h (grub_setjmp): Likewise.. + (grub_longjmp): Likewise. + + * include/grub/setjmp.h [!GRUB_UTIL] (grub_setjmp): Removed. + [!GRUB_UTIL] (grub_longjmp): Removed. + +2006-08-01 Pelletier Vincent + + * kern/ieee1275/ieee1275.c (grub_ieee1275_set_color): IEEE1275 + "color!" method does not return any value. + +2006-07-29 Vesa Jaaskelainen + + * include/grub/bitmap.h: New file. + + * include/grub/i386/pc/vbeutil.h: Likewise. + + * video/bitmap.c: Likewise. + + * video/readers/tga.c: Likewise. + + * video/i386/pc/vbeutil.c: Likewise. + + * commands/videotest.c: Code cleanup and updated to reflect to new + video API. + + * term/gfxterm.c: Likewise. + + * video/video.c: Likewise. + + * conf/i386-pc.rmk (pkgdata_MODULES): Added tga.mod and bitmap.mod. + (vbe_mod_SOURCES): Added video/i386/pc/vbeutil.c. + (bitmap_mod_SOURCES): New entry. + (bitmap_mod_CFLAGS): Likewise. + (bitmap_mod_LDFLAGS): Likewise. + (tga_mod_SOURCES): Likewise. + (tga_mod_CFLAGS): Likewise. + (tga_mod_LDFLAGS): Likewise. + + * include/grub/video.h (grub_video_blit_operators): New enum type. + (grub_video_render_target): Changed as forward declaration and moved + actual definition to be video driver specific. + (grub_video_adapter.blit_bitmap): Added blitting operator. + (grub_video_adapter.blit_render_target): Likewise. + (grub_video_blit_bitmap): Likewise. + (grub_video_blit_render_target): Likewise. + + * include/grub/i386/pc/vbe.h (grub_video_render_target): Added + driver specific render target definition. + (grub_video_vbe_map_rgba): Added driver internal helper. + (grub_video_vbe_unmap_color): Updated to use + grub_video_i386_vbeblit_info. + (grub_video_vbe_get_video_ptr): Likewise. + + * include/grub/i386/pc/vbeblit.h + (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8): Updated to use + grub_video_i386_vbeblit_info. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8A8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8A8): Likewise. + (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8): Likewise. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8): Likewise. + (grub_video_i386_vbeblit_index_index): Likewise. + (grub_video_i386_vbeblit_R8G8B8X8_R8G8B8X8): New blitter function. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_blend): Added generic blitter for blend + operator. + (grub_video_i386_vbeblit_replace): Added generic blitter for replace + operator. + + * video/i386/pc/vbeblit.c: Updated to reflect changes on + include/grub/i386/pc/vbeblit.h. + + * include/grub/i386/pc/vbefill.h (grub_video_i386_vbefill_R8G8B8A8): + Updated to use grub_video_i386_vbeblit_info. + (grub_video_i386_vbefill_R8G8B8): Likewise. + (grub_video_i386_vbefill_index): Likewise. + (grub_video_i386_vbefill): Added generic filler. + + * video/i386/pc/vbefill.c: Updated to reflect changes on + include/grub/i386/pc/vbefill.h. + + * video/i386/pc/vbe.c (grub_video_vbe_get_video_ptr): Updated to use + grub_video_i386_vbeblit_info. + (grub_video_vbe_unmap_color): Likewise. + (grub_video_vbe_blit_glyph): Likewise. + (grub_video_vbe_scroll): Likewise. + (grub_video_vbe_draw_pixel): Removed function. + (grub_video_vbe_get_pixel): Likewise. + (grub_video_vbe_fill_rect): Moved all blitters to vbefill.c and + updated code to use it. + (common_blitter): Added common blitter for render target and bitmap. + (grub_video_vbe_blit_bitmap): Updated to use common_blitter. + (grub_video_vbe_blit_render_target): Likewise. + +2006-07-30 Johan Rydberg + + * kern/efi/efi.c (grub_efi_set_text_mode): Assume console already + is in text mode if there is no console control protocol instance + available. + +2006-07-29 Vesa Jaaskelainen + + * include/grub/video.h: Code cleanup. + + * include/grub/i386/pc/vbe.h: Likewise. + + * video/i386/pc/vbe.c: Likewise. + + * video/i386/pc/vbeblit.c: Likewise. + + * video/i386/pc/vbefill.c: Likewise. + + * video/video.c: Likewise. Also added more comments. + +2006-07-29 Vesa Jaaskelainen + + * disk/i386/pc/biosdisk.c (struct grub_biosdisk_drp): Moved to ... + (struct grub_biosdisk_dap): Likewise. + + * include/grub/i386/pc/biosdisk.h: ... to here. Also corrected + linkage settings for all functions. + +2006-07-12 Marco Gerards + + * configure.ac (--enable-mm-debug): Fix typo. + + * genkernsyms.sh.in: Use proper quoting for `CC'. + +2006-07-02 Jeroen Dekkers + + * conf/i386-pc.rmk (COMMON_ASFLAGS): Add "-m32". + (normal_mod_ASFLAGS): Remove "-m32". + +2006-06-14 Yoshinori K. Okuji + + * util/misc.c: Include config.h. + [!HAVE_MEMALIGN]: Do not include malloc.h. + (grub_memalign): Use posix_memalign, if present. Then, use + memalign, if present. Otherwise, emit an error. + + * util/grub-emu.c: Do not include malloc.h. + + * include/grub/util/misc.h: Include unistd.h. This is required for + FreeBSD, because off_t is defined in unistd.h. Reported by Harley + D. Eades III . + + * configure.ac (AC_GNU_SOURCE): Added. + (AC_CHECK_FUNCS): Check posix_memalign and memalign for the host + type. + +2006-06-09 Yoshinori K. Okuji + + * loader/i386/pc/linux.c (grub_rescue_cmd_initrd): Make sure that + ADDR_MAX does not exceed GRUB_LINUX_INITRD_MAX_ADDRESS. + +2006-06-07 Jeroen Dekkers + + * include/grub/types.h (grub_host_addr_t): Rename to + grub_target_addr_t. + (grub_host_off_t): Rename to grub_target_off_t. + (grub_host_size_t): Rename to grub_target_size_t. + (grub_host_ssize_t): Rename to grub_target_ssize_t. + Refer to GRUB_TARGET_SIZEOF_VOID_P to define those variables. + + * include/grub/kernel.h (struct grub_module_header): Change type + of OFFSET to grub_target_off_t and type of SIZE to grub_target_size_t. + (grub_module_info): Likewise. + +2006-06-05 Yoshinori K. Okuji + + * loader/i386/pc/linux.c (grub_rescue_cmd_initrd): The conditional + of checking LINUX_MEM_SIZE was reverse. Reported by Jesus + Velazquez . + +2006-06-05 Yoshinori K. Okuji + + Count partitions from 1 instead of 0 in the string representation + of partitions. Still use 0-based internally. + + * partmap/sun.c (grub_sun_is_valid): A cosmetic change. + (sun_partition_map_iterate): Use grub_partition_t instead of + struct grub_partition *. Cast DESC->START_CYLINDER to + grub_uint64_t after converting the endian. + (sun_partition_map_probe): Subtract 1 for PARTNUM. + (sun_partition_map_get_name): Add 1 to P->INDEX. + + * partmap/pc.c (grub_partition_parse): Subtract 1 for + PCDATA->DOS_PART. + (pc_partition_map_get_name): Add 1 into PCDATA->DOS_PART. + + * partmap/gpt.c (gpt_partition_map_iterate): Initialize PARTNO to + zero instead of one. + (gpt_partition_map_probe): Subtract 1 for PARTNUM. + (gpt_partition_map_get_name): Add 1 into P->INDEX. + + * partmap/apple.c (apple_partition_map_iterate): Change the type + of POS to unsigned. + (apple_partition_map_probe): Subtract 1 for PARTNUM. + (apple_partition_map_get_name): Add 1 into P->INDEX. + + * partmap/amiga.c (amiga_partition_map_iterate): Change the type + of POS to unsigned. + (amiga_partition_map_iterate): Cast NEXT to grub_off_t to + calculate the offset of a partition. + (amiga_partition_map_probe): Subtract 1 for PARTNUM. + (amiga_partition_map_get_name): Add 1 into P->INDEX. + + * partmap/acorn.c (acorn_partition_map_find): Change the type of + SECTOR to grub_disk_addr_t. + (acorn_partition_map_iterate): Likewise. + (acorn_partition_map_probe): Subtract 1 for PARTNUM. + Change the type of SECTOR to grub_disk_addr_t. Declare P on the + top. + (acorn_partition_map_get_name): Add 1 into P->INDEX. + + * kern/i386/pc/init.c (make_install_device): Add 1 into + GRUB_INSTALL_DOS_PART. + + * fs/iso9660.c (grub_iso9660_mount): Fixed a reversed + conditional. + +2006-06-04 Yoshinori K. Okuji + + Clean up the code to support 64-bit addressing in disks and + files. This change is not enough for filesystems yet. + + * util/i386/pc/grub-setup.c (struct boot_blocklist): Change the + type of "start" to grub_uint64_t. + (setup): Change the types of KERNEL_SECTOR and FIRST_SECTOR to + grub_disk_addr_t * and grub_disk_addr_t. Fix the format string in + save_first_sector and save_blocklists. Use grub_le_to_cpu64 to + convert addresses. + + * util/i386/pc/biosdisk.c (open_device): Change the type of SECTOR + to grub_disk_addr_t. + + * partmap/gpt.c (gpt_partition_map_iterate): Fix the format + string. + + * partmap/pc.c (pc_partition_map_iterate): Likewise. + + * partmap/amiga.c (amiga_partition_map_iterate): Cast RDSK.MAGIC + to char *. + + * normal/script.c (grub_script_parse): Remove unused MEMFREE. + + * normal/parser.y (YYLTYPE_IS_TRIVIAL): New macro. + + * normal/lexer.c (grub_script_yyerror): Specify unused to LEX. + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf64): Cast -1 + to grub_off_t, to detect an error from grub_file_seek. + (grub_multiboot_load_elf32): Likewise. + + * kern/misc.c (grub_strtoul): Use grub_strtoull. Return the + maximum unsigned long value when an overflow is detected. + (grub_strtoull): New function. + (grub_divmod64): Likewise. + (grub_lltoa): use grub_divmod64. + + * kern/fs.c (struct grub_fs_block): Change the type of "offset" to + grub_disk_addr_t. + (grub_fs_blocklist_open): Increase P if P is not NULL to advance + the pointer to next character. Use grub_strtoull instead of + grub_strtoul. + (grub_fs_blocklist_read): Change the types of SECTOR, OFFSET and + SIZE to grub_disk_addr_t, grub_off_t and grub_size_t, + respectively. + + * kern/file.c (grub_file_read): Prevent an overflow of LEN, as the + return value is signed. + (grub_file_seek): Change the type of OLD to grub_off_t. Do not + test if OFFSET is less than zero, as OFFSET is unsigned now. + + * kern/disk.c (struct grub_disk_cache): Change the type of + "sector" to grub_disk_addr_t. + (grub_disk_cache_get_index): Change the type of SECTOR to + grub_disk_addr_t. Calculate the hash with SECTOR casted to + unsigned after shifting. + (grub_disk_cache_invalidate): Change the type of SECTOR to + grub_disk_addr_t. + (grub_disk_cache_unlock): Likewise. + (grub_disk_cache_store): Likewise. + (grub_disk_check_range): Change the types of SECTOR, OFFSET, SIZE, + START and LEN to grub_disk_addr_t *, grub_off_t *, grub_size_t, + grub_disk_addr_t and grub_uint64_t, respectively. + (grub_disk_read): Use an unsigned variable REAL_OFFSET for the + body, as the value of OFFSET is tweaked by + grub_disk_check_range. Change the types of START_SECTOR, LEN and + POS to grub_disk_addr_t, grub_size_t and grub_size_t, + respectively. + (grub_disk_write): Use an unsigned variable REAL_OFFSET for the + body, as the value of OFFSET is tweaked by + grub_disk_check_range. Change the types of LEN and N to + grub_size_t. + + * io/gzio.c (struct grub_gzio): Change the types of "data_offset" + and "saved_offset" to grub_off_t. + (test_header): Cast BUF to char *. + (get_byte): Cast GZIO->DATA_OFFSET to grub_off_t. Cast GZIO->INBUF + to char *. + (grub_gzio_read): Change the types of OFFSET and SIZE to + grub_off_t and grub_size_t, respectively. + + * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_FORCE_LBA): + Removed. + (GRUB_BOOT_MACHINE_BOOT_DRIVE): Changed to 0x4c. + (GRUB_BOOT_MACHINE_KERNEL_ADDRESS): Changed to 0x40. + (GRUB_BOOT_MACHINE_KERNEL_SEGMENT): Changed to 0x42. + (GRUB_BOOT_MACHINE_DRIVE_CHECK): Changed to 0x4e. + (GRUB_BOOT_MACHINE_LIST_SIZE): Increased to 12. + + * include/grub/types.h (grub_off_t): Unconditionally set to + grub_uint64_t. + (grub_disk_addr_t): Changed to grub_uint64_t. + + * include/grub/partition.h (struct grub_partition): Change the + types of "start", "len" and "offset" to grub_disk_addr_t, + grub_uint64_t and grub_disk_addr_t, respectively. + (grub_partition_get_start): Return grub_disk_addr_t. + (grub_partition_get_len): Return grub_uint64_t. + + * include/grub/misc.h (grub_strtoull): New prototype. + (grub_divmod64): Likewise. + + * include/grub/fshelp.h (grub_fshelp_read_file): Change the types + of SECTOR, LEN and FILESIZE to grub_disk_addr_t, grub_size_t and + grub_off_t, respectively. + All callers and references changed. + + * include/grub/fs.h (struct grub_fs): Change the type of LEN to + grub_size_t in "read". + All callers and references changed. + + * include/grub/file.h (struct grub_file): Change the types of + "offset" and "size" to grub_off_t and grub_off_t, + respectively. Change the type of SECTOR to grub_disk_addr_t in + "read_hook". + (grub_file_read): Change the type of LEN to grub_size_t. + (grub_file_seek): Return grub_off_t. Change the type of OFFSET to + grub_off_t. + (grub_file_size): Return grub_off_t. + (grub_file_tell): Likewise. + All callers and references changed. + + * include/grub/disk.h (struct grub_disk_dev): Change the types of + SECTOR and SIZE to grub_disk_addr_t and grub_size_t in "read" and + "write". + (struct grub_disk): Change the type of "total_sectors" to + grub_uint64_t. Change the type of SECTOR to grub_disk_addr_t in + "read_hook". + (grub_disk_read): Change the types of SECTOR, OFFSET and SIZE to + grub_disk_addr_t, grub_off_t and grub_size_t, respectively. + (grub_disk_write): Likewise. + All callers and references changed. + + * fs/iso9660.c (grub_iso9660_susp_iterate): Cast parameters to + char * for grub_strncmp to silence gcc. + (grub_iso9660_mount): Likewise. + (grub_iso9660_mount): Likewise. + (grub_iso9660_read_symlink): Likewise. Also, remove the nonsense + return statement. + (grub_iso9660_iterate_dir): Likewise. + (grub_iso9660_label): Cast DATA->VOLDESC.VOLNAME to char *. + + * fs/hfs.c (grub_hfs_read_file): Change the types of SECTOR and + LEN to grub_disk_addr_t and grub_size_t, respectively. + + * fs/hfsplus.c (grub_hfsplus_read_file): Likewise. + + * fs/jfs.c (grub_jfs_read_file): Likewise. + + * fs/minix.c (grub_jfs_read_file): Likewise. + + * fs/sfs.c (grub_jfs_read_file): Likewise. + + * fs/ufs.c (grub_jfs_read_file): Likewise. + + * fs/xfs.c (grub_jfs_read_file): Likewise. + + * fs/fat.c (grub_fat_read_data): Change the types of SECTOR, LEN + and SIZE to grub_disk_addr_t, grub_size_t and grub_size_t, + respectively. + + * fs/ext2.c (grub_ext2_read_block): When an error happens, set + BLKNR to -1 instead of returning GRUB_ERRNO. + (grub_ext2_read_file): Change the types of SECTOR and + LEN to grub_disk_addr_t and grub_size_t, respectively. + + * fs/affs.c (grub_affs_read_file): Change the types of SECTOR and + LEN to grub_disk_addr_t and grub_size_t, respectively. + + * font/manager.c (grub_font_get_glyph): Cast BITMAP to char * for + grub_file_read. + + * disk/ieee1275/ofdisk.c (grub_ofdisk_read): Fix the format + string. Do not cast SECTOR explicitly. + + * disk/i386/pc/biosdisk.c (grub_biosdisk_open): Change the type of + TOTAL_SECTORS to grub_uint64_t. Do not mask DRP->TOTAL_SECTORS. + (grub_biosdisk_rw): Change the types of SECTOR and SIZE to + grub_disk_addr_t and grub_size_t, respectively. If the sector is + over 2TB and LBA mode is not supported, raise an error. + (get_safe_sectors): New function. + (grub_biosdisk_read): Use get_safe_sectors. + (grub_biosdisk_write): Likewise. + + * disk/efi/efidisk.c (grub_efidisk_read): Fix the format string. + (grub_efidisk_write): Likewise. + + * disk/loopback.c (delete_loopback): Cosmetic changes. + (grub_cmd_loopback): Likewise. Also, test NEWDEV->FILENAME + correctly. + (grub_loopback_open): Likewise. + (grub_loopback_read): Likewise. Also, change the type of POS to + grub_off_t, and fix the usage of grub_memset. + + * commands/i386/pc/play.c: Include grub/machine/time.h. + + * commands/ls.c (grub_ls_list_files): Use "llu" instead of "d" to + print FILE->SIZE. + + * commands/configfile.c: Include grub/env.h. + + * commands/cmp.c (grub_cmd_cmp): Do not use ERR, but use + GRUB_ERRNO directly instead. Change the type of POS to + grub_off_t. Follow the coding standard. + + * commands/blocklist.c: Include grub/partition.h. + (grub_cmd_blocklist): Return an error if the underlying device is + not a disk. Take the starting sector of a partition into account, + if a partition is used. + + * boot/i386/pc/diskboot.S (bootloop): Adapted to the new offset of + a length field. + (lba_mode): Support 64-bit addresses. + (chs_mode): Likewise. + (copy_buffer): Adapted to the new offsets of a length field and a + segment field. + (blocklist_default_start): Allocate 64-bit space. + + * boot/i386/pc/boot.S (force_lba): Removed. + (boot_drive): Moved to under KERNEL_SECTOR. + (kernel_sector): Moved to under KERNEL_SEGMENT. Allocate 64-bit + space. + (real_start): Set %si earlier. Remove code for FORCE_LBA, since it + is useless. + (lba_mode): Refactored to support a 64-bit address. More size + optimization. + (setup_sectors): Likewise. + +2006-06-04 Yoshinori K. Okuji + + * DISTLIST: Added include/grub/i386/linux.h. Removed + include/grub/i386/pc/linux.h + + * configure.ac (AC_INIT): Bumped to 1.94. + + * config.guess: Updated from gnulib. + * config.sub: Likewise. + * install-sh: Likewise. + * mkinstalldirs: Likewise. + +2006-06-02 Yoshinori K. Okuji + + * conf/common.rmk (grub_modules_init.lst): Depended on + grub_emu_SOURCES, excluding grub_emu_init.c, instead of + MODSRCFILES. + + * genmk.rb (PModule::rule): Reverted the previous change. + +2006-06-02 Yoshinori K. Okuji + + * conf/common.rmk (grub_modules_init.lst): Depends on + $(MODSRCFILES). Grep only the files in $(MODSRCFILES). Make sure + that the target does not exist before producing. + (grub_modules_init.h): Remove the target before generating. + (grub_emu_init.c): Likewise. + + * genmk.rb (PModule::rule): Add source files into MODSRCFILES. + +2006-05-31 Jeroen Dekkers + + * configure.ac: Don't set host_m32 for x86_64. Also reset LIBS + for the target-specific tests. Make sure that we also have the + up-to-date target variables for those tests. + +2006-05-31 Yoshinori K. Okuji + + * genmk.rb (Image::rule): Prefix CFLAGS or ASFLAGS with TARGET_. + (PModule::rule): Likewise. + +2006-05-31 Yoshinori K. Okuji + + * genmk.rb (Image::rule): Set FLAG to CFLAGS or ASFLAGS instead of + TARGET_CFLAGS or TARGET_ASFLAGS. There is no reason why + target-specific flags should be prefixed. + (PModule::rule): Likewise. + +2006-05-30 Yoshinori K. Okuji + + * configure.ac (CMP): Check if cmp is available explicitly. + +2006-05-29 Yoshinori K. Okuji + + * util/powerpc/ieee1275/grub-install.in (host_cpu): Removed. + (target_cpu): New variable. + (pkglibdir): Use target_cpu instead of host_cpu. + + * util/i386/pc/grub-install.in (host_cpu): Removed. + (target_cpu): New variable. + (pkglibdir): Use target_cpu instead of host_cpu. + + * util/genmoddep.c: Removed. + + * kern/efi/mm.c (filter_memory_map): Use GRUB_CPU_SIZEOF_VOID_P + instead of GRUB_HOST_SIZEOF_VOID_P. + * kern/dl.c: Likewise. + + * include/grub/i386/types.h (GRUB_HOST_SIZEOF_VOID_P): Renamed to + ... + (GRUB_TARGET_SIZEOF_VOID_P): ... this. + (GRUB_HOST_SIZEOF_LONG): Renamed to ... + (GRUB_TARGET_SIZEOF_LONG): ... this. + (GRUB_HOST_WORDS_BIGENDIAN): Renamed to ... + (GRUB_TARGET_WORDS_BIGENDIAN): ... this. + * include/grub/powerpc/types.h (GRUB_HOST_SIZEOF_VOID_P): Renamed + to ... + (GRUB_TARGET_SIZEOF_VOID_P): ... this. + (GRUB_HOST_SIZEOF_LONG): Renamed to ... + (GRUB_TARGET_SIZEOF_LONG): ... this. + (GRUB_HOST_WORDS_BIGENDIAN): Renamed to ... + (GRUB_TARGET_WORDS_BIGENDIAN): ... this. + * include/grub/sparc64/types.h (GRUB_HOST_SIZEOF_VOID_P): Renamed + to ... + (GRUB_TARGET_SIZEOF_VOID_P): ... this. + (GRUB_HOST_SIZEOF_LONG): Renamed to ... + (GRUB_TARGET_SIZEOF_LONG): ... this. + (GRUB_HOST_WORDS_BIGENDIAN): Renamed to ... + (GRUB_TARGET_WORDS_BIGENDIAN): ... this. + + * include/grub/types.h [!GRUB_UTIL] (GRUB_CPU_SIZEOF_VOID_P): Use + GRUB_TARGET_SIZEOF_VOID_P instead of GRUB_HOST_SIZEOF_VOID_P. + [!GRUB_UTIL] (GRUB_CPU_SIZEOF_LONG): Use GRUB_TARGET_SIZEOF_LONG + instead of GRUB_HOST_SIZEOF_LONG. + [!GRUB_UTIL]: Refer to GRUB_TARGET_WORDS_BIGENDIAN instead of + GRUB_HOST_WORDS_BIGENDIAN to define or undefine + GRUB_CPU_WORDS_BIGENDIAN. + Refer to SIZEOF_VOID_P instead of GRUB_HOST_SIZEOF_VOID_P to + define grub_host_addr_t, grub_host_off_t, grub_host_size_t and + grub_host_ssize_t. + + * conf/i386-efi.rmk (noinst_UTILITIES): Removed. + (genmoddep_SOURCES): Likewise. + * conf/i386-pc.rmk (noinst_UTILITIES): Likewise. + (genmoddep_SOURCES): Likewise. + * conf/conf/powerpc-ieee1275.rmk (noinst_UTILITIES): Likewise. + (genmoddep_SOURCES): Likewise. + * conf/conf/conf/sparc64-ieee1275.rmk (noinst_UTILITIES): + Likewise. + (genmoddep_SOURCES): Likewise. + + * genmoddep.awk: New file. + + * genmk.rb (Image::rule): Use TARGET_CC, TARGET_CPPFLAGS, + TARGET_CFLAGS, TARGET_ASFLAGS and TARGET_LDFLAGS instead of CC, + CPPFLAGS, CFLAGS, ASFLAGS and LDFLAGS, respectively. + (PModule::rule): Likewise. + (Program::rule): Likewise. + (Utility::rule): Use CC, CPPFLAGS, CFLAGS and LDFLAGS instead of + BUILD_CC, BUILD_CPPFLAGS, BUILD_CFLAGS and BUILD_LDFLAGS, + respectively. + + * configure.ac: Rewritten intensively to use host and target + instead of build and host, respectively. + + * Makefile.in (pkglibdir): Use target_cpu instead of host_cpu. + (host_cpu): Removed. + (target_cpu): New variable. + (CPPFLAGS): Added @CPPFLAGS@ and -DGRUB_LIBDIR=\"$(pkglibdir)\". + (BUILD_CC): Removed. + (BUILD_CFLAGS): Likewise. + (BUILD_CPPFLAGS): Likewise. + (TARGET_CC): New variable. + (TARGET_CFLAGS): Likewise. + (TARGET_CPPFLAGS): Likewise. + (TARGET_LDFLAGS): Likewise. + (AWK): Likewise. + (include): Use target_cpu instead of host_cpu. + (moddep.lst:): Use genmoddep.awk instead of genmoddep. + + * DISTLIST: Added genmoddep.awk. Removed util/genmoddep.c. + +2006-05-29 Vesa Jaaskelainen + + * include/grub/script.h (grub_script_cmdif): Renamed field 'bool' to + 'exec_to_evaluate'. Renamed field 'true' to 'exec_on_true'. Renamed + field 'false' to 'exec_on_false'. + (grub_script_create_cmdif): Renamed argument names to reflect above + changes. + + * normal/execute.c (grub_script_execute_cmdif): Likewise. + + * normal/script.c (grub_script_create_cmdif): Likewise. + +2006-05-28 Yoshinori K. Okuji + + * fs/hfsplus.c (grub_hfsplus_btree_recoffset): Moved to near the + top. + (grub_hfsplus_btree_recptr): Likewise. + (grub_hfsplus_find_block): Do not take RETRY any longer. Use + FILEBLOCK both to pass a block number and store next block + number. + (grub_hfsplus_read_block): Rewritten heavily to support an extent + overflow file correctly. Specify errors appropriately, because + fshelp expects that GRUB_ERRNO is set when fails. Reuse + grub_hfsplus_btree_recptr to get the pointer to a found key. + (grub_hfsplus_btree_search): Return 1 instead of 0 when no match + is found. + + * conf/i386-efi.rmk (pkgdata_MODULES): Added _linux.mod and + linux.mod. + (_linux_mod_SOURCES): New variable. + (_linux_mod_CFLAGS): Likewise. + (_linux_mod_LDFLAGS): Likewise. + (linux_mod_SOURCES): Likewise. + (linux_mod_CFLAGS): Likewise. + (linux_mod_LDFLAGS): Likewise. + + * DISTLIST: Added loader/i386/efi/linux.c, + loader/i386/efi/linux_normal.c and + include/grub/i386/efi/loader.h. + + * loader/i386/efi/linux.c: New file. + * loader/i386/efi/linux_normal.c: Likewise. + * include/grub/i386/efi/loader.h: Likewise. + +2006-05-27 Yoshinori K. Okuji + + * commands/blocklist.c: New file. + + * DISTLIST: Added commands/blocklist.c. + + * term/efi/console.c (grub_console_highlight_color): Use a lighter + color for the background, and a darker color for the foreground. + (grub_console_checkkey): Return READ_KEY. + (grub_console_cls): Set the background to + GRUB_EFI_BACKGROUND_BLACK temporarily to clean out the screen. + + * kern/efi/efi.c (grub_efi_exit_boot_services): New function. + + * include/grub/i386/linux.h (struct linux_kernel_params): Fixed + the size of "padding5", "hd0_drive_info" and "hd1_drive_info". + + * include/grub/efi/efi.h (grub_efi_exit_boot_services): New + prototype. + + * include/grub/efi/api.h (GRUB_EFI_TEXT_ATTR): Do not shift + BG. The spec is wrong again. + + * include/grub/normal.h [GRUB_UTIL] (grub_blocklist_init): New + prototype. + [GRUB_UTIL] (grub_blocklist_fini): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Added + commands/blocklist.c. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * conf/common.rmk (pkgdata_MODULES): Added blocklist.mod. + (blocklist_mod_SOURCES): New variable. + (blocklist_mod_CFLAGS): Likewise. + (blocklist_mod_LDFLAGS): Likewise. + +2006-05-20 Yoshinori K. Okuji + + * boot/i386/pc/boot.S (real_start): Set %si earlier to eliminate + duplication. + (lba_mode): Use %eax more intensively to reduce the code size. + +2006-05-20 Marco Gerards + + * normal/lexer.c (grub_script_yylex): Don't filter out newlines. + + * normal/parser.y (commandblock): Defined as . A subroutine + for `menuentry'. + (script): Accept leading newlines. + (newlines): New rule to describe 0 or more newlines. + (commands): Accept `command' with trailing newline. Fixed the + order in which arguments were passed to `grub_script_add_cmd'. + Accept commands separated by newlines. + (function): Changed to accept newlines. + (menuentry) Rewritten. + + * normal/script.c (grub_script_create_cmdmenu): Add new entries in + front of the list, instead of to the end. + +2006-05-19 Yoshinori K. Okuji + + * util/i386/pc/grub-install.in (bindir): New variable. + (grub_mkimage): Use BINDIR instead of SBINDIR. Reported by Lee + Shaver . + +2006-05-14 Yoshinori K. Okuji + + * kern/i386/pc/startup.S: Include grub/cpu/linux.h instead of + grub/machine/linux.h + * loader/i386/pc/linux.c: Likewise. + + * include/grub/i386/pc/linux.h: Moved to ... + * include/grub/i386/linux.h: ... here. + + * include/grub/i386/linux.h (struct linux_kernel_params): New + struct. + +2006-05-09 Vesa Jaaskelainen + + * video/i386/pc/vbe.c (grub_video_vbe_fill_rect): Corrected bounds + checking. + (grub_video_vbe_blit_glyph): Likewise. + (grub_video_vbe_blit_bitmap): Likewise. + (grub_video_vbe_blit_render_target): Likewise. + +2006-05-09 Yoshinori K. Okuji + + * configure.ac (--with-platform): Properly quote the square + brackets. + +2006-05-08 Marco Gerards + + * conf/powerpc-ieee1275.rmk (grubof_HEADERS): Renamed from + this... + (kernel_elf_HEADERS): ...to this. Updated all users. + (grubof_symlist.c): Renamed from this... + (kernel_elf_symlist.c): ...to this. Updated all users. + (pkgdata_PROGRAMS): Changed `grubof' to `kernel.elf'. + (grubof_SOURCES): Renamed from this... + (kernel_elf_SOURCES): ...to this. + (grubof_HEADERS): Renamed from this... + (kernel_elf_HEADERS): ...to this. + (grubof_CFLAGS): Renamed from this... + (kernel_elf_CFLAGS): ...to this. + (grubof_ASFLAGS): Renamed from this... + (kernel_elf_ASFLAGS): ...to this. + (grubof_LDFLAGS): Renamed from this... + (kernel_elf_LDFLAGS): ...to this. + + * conf/sparc64-ieee1275.rmk (grubof_HEADERS): Renamed from + this... + (kernel_elf_HEADERS): ...to this. Updated all users. + (grubof_symlist.c): Renamed from this... + (kernel_elf_symlist.c): ...to this. Updated all users. + (pkgdata_PROGRAMS): Changed `grubof' to `kernel.elf'. + (grubof_SOURCES): Renamed from this... + (kernel_elf_SOURCES): ...to this. + (grubof_HEADERS): Renamed from this... + (kernel_elf_HEADERS): ...to this. + (grubof_CFLAGS): Renamed from this... + (kernel_elf_CFLAGS): ...to this. + (grubof_ASFLAGS): Renamed from this... + (kernel_elf_ASFLAGS): ...to this. + (grubof_LDFLAGS): Renamed from this... + (kernel_elf_LDFLAGS): ...to this. + + * util/powerpc/ieee1275/grub-mkimage.c (add_segments): Use + `kernel.elf' instead of `grubof'. + +2006-05-08 Yoshinori K. Okuji + + Add --with-platform to configure. Use pkglibdir instead of + pkgdatadir. This is reported by Roger Leigh. + + * util/powerpc/ieee1275/grub-install.in (datadir): Removed. + (host_vendor): Likewise. + (host_os): Likewise. + (pkgdatadir): Likewise. + (platform): New variable. + (pkglibdir): Likewise. + Use PKGLIBDIR instead of PKGDATADIR. + + * util/i386/pc/grub-install.in (datadir): Removed. + (host_vendor): Likewise. + (host_os): Likewise. + (pkgdatadir): Likewise. + (platform): New variable. + (pkglibdir): Likewise. + Use PKGLIBDIR instead of PKGDATADIR. + + * util/powerpc/ieee1275/grub-mkimage.c (usage): Use GRUB_LIBDIR + instead of GRUB_DATADIR. + (main): Likewise. + * util/i386/pc/grub-mkimage.c (usage): Likewise. + (main): Likewise. + * util/i386/efi/grub-mkimage.c (usage): Likewise. + (main): Likewise. + + * configure.ac (--with-platform): New option. + Use PLATFORM instead of HOST_VENDOR to specify a platform. + + * Makefile.in: Include a makefile based on PLATFORM instead of + HOST_VENDOR. + (pkgdatadir): Not appended by the machine type. + (pkglibdir): Appended by the machine type. + (host_vendor): Removed. + (platform): New variable. + (BUILD_CPPFLAGS): Specify GRUB_LIBDIR instead of GRUB_DATADIR. + (install-local): Use PKGLIBDIR instead of PKGDATADIR. + (uninstall): Likewise. + +2006-05-07 Yoshinori K. Okuji + + Use the environment context in the menu. Remove the commands + "default" and "timeout", and use variables instead. + + * normal/menu.c: Include grub/env.h. + (print_entry): Cast TITLE to silence gcc. + (get_timeout): New function. + (set_timeout): Likewise. + (get_entry_number): Likewise. + (run_menu): Use a default entry, a fallback entry and a timeout + in the environment variables "default", "fallback" and + "timeout". Also, tweak the default entry if it is not within the + current menu entries. + (grub_menu_run): Use a fallback entry in the environment variable + "fallback". + + * normal/main.c (read_config_file): Do not initialize + NEWMENU->DEFAULT_ENTRY, NEWMENU->FALLBACK_ENTRY or + NEWMENU->TIMEOUT. + (grub_normal_execute): Use a data slot to store the menu. + + * include/grub/normal.h (struct grub_menu): Removed default_entry, + fallback_entry and timeout. + (struct grub_menu_list): Removed. + (grub_menu_list_t): Likewise. + (struct grub_context): Likewise. + (grub_context_t): Likewise. + (grub_context_get): Likewise. + (grub_context_get_current_menu): Likewise. + (grub_context_push_menu): Likewise. + (grub_context_pop_menu): Likewise. + (grub_default_init): Likewise. + (grub_default_fini): Likewise. + (grub_timeout_init): Likewise. + (grub_timeout_fini): Likewise. + + * conf/sparc64-ieee1275.rmk (pkgdata_MODULES): Removed default.mod + and timeout.mod. + (normal_mod_SOURCES): Removed normal/context.c. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Removed + commands/default.c, commands/timeout.c and normal/context.c. + (normal_mod_SOURCES): Removed normal/context.c. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Removed commands/default.c, + commands/timeout.c and normal/context.c. + (normal_mod_SOURCES): Removed normal/context.c. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Removed + commands/default.c, commands/timeout.c and normal/context.c. + (normal_mod_SOURCES): Removed normal/context.c. + + * conf/common.rmk (pkgdata_MODULES): Removed default.mod and + timeout.mod. + (default_mod_SOURCES): Removed. + (default_mod_CFLAGS): Likewise. + (default_mod_LDFLAGS): Likewise. + (timeout_mod_SOURCES): Removed. + (timeout_mod_CFLAGS): Likewise. + (timeout_mod_LDFLAGS): Likewise. + + * DISTLIST: Removed commands/default.c, commands/timeout.c and + normal/context.c. + + * commands/default.c: Removed. + * commands/timeout.c: Likewise. + * normal/context.c: Likewise. + +2006-05-07 Vesa Jaaskelainen + + * kern/i386/pc/startup.S (grub_exit): Added missing .code32 tag. + +2006-05-02 Yoshinori K. Okuji + + * kern/env.c (struct grub_env_context): Removed "sorted". Renamed + "next" to "prev" for readability. + (struct grub_env_sorted_var): New struct. + (grub_env_context): Renamed to ... + (initial_context): ... this. + (grub_env_var_context): Renamed to ... + (current_context): ... this. + (grub_env_find): Look only at CURRENT_CONTEXT. + (grub_env_context_open): Rewritten to copy exported variables from + previous context. + (grub_env_context_close): Rewritten according to the new + scheme. Also, add an assertion to prevent the initial context from + removed. + (grub_env_insert): Removed the code for the sorted list. + (grub_env_remove): Likewise. + (grub_env_export): Simply mark the variable with + GRUB_ENV_VAR_GLOBAL. + (grub_env_set): A cosmetic change for naming consistency. + (grub_env_get): Likewise. + (grub_env_unset): Likewise. + (grub_env_iterate): Rewritten to sort variables within this + function. + (grub_register_variable_hook): Fixed for naming consistency. Call + grub_env_find again, only if NAME is not found at the first time. + (mangle_data_slot_name): New function. + (grub_env_set_data_slot): Likewise. + (grub_env_get_data_slot): Likewise. + (grub_env_unset_data_slot): Likewise. + + * include/grub/env.h (grub_env_var_type): New enum. + (GRUB_ENV_VAR_LOCAL): New constant. + (GRUB_ENV_VAR_GLOBAL): Likewise. + (GRUB_ENV_VAR_DATA): Likewise. + (struct grub_env_var): Removed "sort_next" and "sort_prevp". Added + "type". + (grub_env_set): Replace VAR with NAME for consistency. + (grub_register_variable_hook): Likewise. + (grub_env_export): Specify the name of the argument. + (grub_env_set_data_slot): New prototype. + (grub_env_get_data_slot): Likewise. + (grub_env_unset_data_slot): Likewise. + +2006-04-30 Yoshinori K. Okuji + + Extend the loader so that GRUB can accept a loader which comes + back to GRUB when a loaded image exits. Also, this change adds + support for a chainloader on EFI. + + * term/efi/console.c: Include grub/misc.h. + (grub_console_checkkey): Display a scan code on the top for + debugging. This will be removed once the EFI port gets stable. + Correct the scan code mapping. + + * kern/efi/mm.c (sort_memory_map): Sort in a descending order to + allocate memory from larger regions, in order to reduce the number + of allocated regions. Otherwise, the MacOSX loader panics. + (filter_memory_map): Avoid less than 1MB for compatibility with + other loaders. + (add_memory_regions): Allocate from the tail of a region, if + possible, to avoid allocating a region near to 1MB, for the MacOSX + loader. + + * kern/efi/init.c (grub_efi_set_prefix): Specify + GRUB_EFI_IMAGE_HANDLE to grub_efi_get_loaded_image. + + * kern/efi/efi.c (grub_efi_get_loaded_image): Accept a new + argument IMAGE_HANDLE and specify it to get a loaded image. + (grub_arch_modules_addr): Specify GRUB_EFI_IMAGE_HANDLE to + grub_efi_get_loaded_image. + (grub_efi_get_filename): Divide the length by the size of + grub_efi_char16_t. + (grub_efi_get_device_path): New function. + (grub_efi_print_device_path): Print End Device Path nodes. Divide + the length by the size of grub_efi_char16_t for a file path device + path node. + + * kern/loader.c (grub_loader_noreturn): New variable. + (grub_loader_set): Accept a new argument NORETURN. Set + GRUB_LOADER_NORETURN to NORETURN. + All callers changed. + (grub_loader_boot): If GRUB_LOADER_NORETURN is false, do not call + grub_machine_fini. + + * include/grub/efi/efi.h (grub_efi_get_device_path): New + prototype. + (grub_efi_get_loaded_image): Take an argument to specify an image + handle. + + * include/grub/loader.h (grub_loader_set): Added one more argument + NORETURN. + + * disk/efi/efidisk.c (make_devices): Use grub_efi_get_device_path + instead of grub_efi_open_protocol. + (grub_efidisk_get_device_name): Likewise. + (grub_efidisk_close): Print a newline. + (grub_efidisk_get_device_handle): Fixed to use + GRUB_EFI_DEVICE_PATH_SUBTYPE instead of + GRUB_EFI_DEVICE_PATH_TYPE. + + * disk/efi/efidisk.c (device_path_guid): Moved to ... + * kern/efi/efi.c (device_path_guid): ... here. + + * conf/i386-efi.rmk (pkgdata_MODULES): Added _chain.mod and + chain.mod. + (kernel_mod_HEADERS): Added efi/disk.h. + (_chain_mod_SOURCES): New variable. + (_chain_mod_CFLAGS): Likewise. + (_chain_mod_LDFLAGS): Likewise. + (chain_mod_SOURCES): Likewise. + (chain_mod_CFLAGS): Likewise. + (chain_mod_LDFLAGS): Likewise. + + * DISTLIST: Added include/grub/efi/chainloader.h, + loader/efi/chainloader.c and loader/efi/chainloader_normal.c. + + * include/grub/efi/chainloader.h: New file. + * loader/efi/chainloader.c: Likewise. + * loader/efi/chainloader_normal.c: Likewise. + +2006-04-30 Marco Gerards + + * commands/configfile.c (grub_cmd_source): New function. + (GRUB_MOD_INIT): Register the commands `source' and `.'. + (GRUB_MOD_FINI): De-register the commands `source' and `.'. + +2006-04-30 Marco Gerards + + * normal/execute.c (grub_script_execute_cmd): Change the return + type to `grub_err_t'. Correctly return the error. + (grub_script_execute_cmdline): In case a command line is not a + command or a function, try to interpret it as an assignment. + +2006-04-30 Yoshinori K. Okuji + + * fs/hfsplus.c (grub_hfsplus_read_block): Fixed a memory leak. + (grub_hfsplus_iterate_dir): Reordered to skip unknown nodes. Also, + skip a node whose name is obviously invalid as UTF-16, + i.e. contains a NUL character. Stop the iteration when the last + directory entry is found. Instead of using the return value of + grub_hfsplus_btree_iterate_node, store the value in RET and use + it, because the iterator can be stopped by the last directory + entry. + +2006-04-30 Marco Gerards + + * include/grub/env.h (grub_env_export): New prototype. Reported + by Jan C. Kleinsorge . + +2006-04-30 Marco Gerards + + * fs/hfsplus.c (grub_hfsplus_iterate_dir): Correctly calculate the + size of the extents in a catalog file record. + +2006-04-29 Marco Gerards + + * commands/configfile.c (grub_cmd_configfile): Execute the + configfile within its own context. + + * include/grub/env.h (grub_env_context_open): New prototype. + (grub_env_context_close): Likewise. + + * kern/env.c (grub_env): Removed. + (grub_env_sorted): Likewise. + (grub_env_context): New variable. + (grub_env_var_context): Likewise. + (grub_env_find): Search both the active context and the global + context. + (grub_env_context_open): New function. + (grub_env_context_close): Likewise. + (grub_env_insert): Likewise. + (grub_env_remove): Likewise. + (grub_env_export): Likewise. + (grub_env_set): Changed to use helper functions to avoid code + duplication. + (grub_env_iterate): Rewritten so both the current context and the + global context are being used. + + * normal/command.c (export_command): New function. + (grub_command_init): Register the `export' function. + +2006-04-26 Yoshinori K. Okuji + + * util/i386/pc/grub-mkimage.c (compress_kernel): Cast arguments + explicitly to suppress gcc's warnings. + * fs/fat.c (grub_fat_find_dir): Likewise. + (grub_fat_label): Likewise. + * fs/xfs.c (grub_xfs_read_inode): Likewise. + (grub_xfs_mount): Likewise. + (grub_xfs_label): Likewise. + * fs/affs.c (grub_affs_mount): Likewise. + (grub_affs_label): Likewise. + (grub_affs_iterate_dir): Likewise. + * fs/sfs.c (grub_sfs_mount): Likewise. + (grub_sfs_iterate_dir): Likewise. + * fs/ufs.c (grub_ufs_lookup_symlink): Likewise. + * fs/hfs.c (grub_hfs_mount): Likewise. + (grub_hfs_cmp_catkeys): Likewise. + (grub_hfs_find_dir): Likewise. + (grub_hfs_dir): Likewise. + (grub_hfs_label): Likewise. + * fs/jfs.c (grub_jfs_mount): Likewise. + (grub_jfs_opendir): Likewise. + (grub_jfs_getent): Likewise. + (grub_jfs_lookup_symlink): Likewise. + (grub_jfs_label): Likewise. + * fs/hfsplus.c (grub_hfsplus_cmp_catkey): Likewise. + (grub_hfsplus_iterate_dir): Likewise. + (grub_hfsplus_btree_iterate_node): Made static. + + * util/grub-emu.c (prefix): New variable. + (grub_machine_set_prefix): New function. + (main): Do not set the environment variable "prefix" here. Only + set PREFIX, which is used later by grub_machine_set_prefix. + + * include/grub/video.h: Do not include grub/symbol.h. + (grub_video_register): Not exported. This symbol is not defined in + the kernel. + (grub_video_unregister): Likewise. + (grub_video_iterate): Likewise. + (grub_video_setup): Likewise. + (grub_video_restore): Likewise. + (grub_video_get_info): Likewise. + (grub_video_get_blit_format): Likewise. + (grub_video_set_palette): Likewise. + (grub_video_get_palette): Likewise. + (grub_video_set_viewport): Likewise. + (grub_video_get_viewport): Likewise. + (grub_video_map_color): Likewise. + (grub_video_map_rgb): Likewise. + (grub_video_map_rgba): Likewise. + (grub_video_fill_rect): Likewise. + (grub_video_blit_glyph): Likewise. + (grub_video_blit_bitmap): Likewise. + (grub_video_blit_render_target): Likewise. + (grub_video_scroll): Likewise. + (grub_video_swap_buffers): Likewise. + (grub_video_create_render_target): Likewise. + (grub_video_delete_render_target): Likewise. + (grub_video_set_active_render_target): Likewise. + + * include/grub/symbol.h [GRUB_SYMBOL_GENERATOR] (EXPORT_FUNC): + Undefined. + [GRUB_SYMBOL_GENERATOR] (EXPORT_VAR): Likewise. + + * conf/sparc64-ieee1275.rmk (grubof_symlist.c): Depended on + config.h. Use gensymlist.sh instead of $(srcdir)/gensymlist.sh. + (kernel_syms.lst): Depended on config.h. Use genkernsyms.sh + instead of $(srcdir)/genkernsyms.sh. + + * conf/powerpc-ieee1275.rmk (grubof_symlist.c): Depended on + config.h. Use gensymlist.sh instead of $(srcdir)/gensymlist.sh. + (kernel_syms.lst): Depended on config.h. Use genkernsyms.sh + instead of $(srcdir)/genkernsyms.sh. + + * conf/i386-pc.rmk (symlist.c): Depended on config.h. Use + gensymlist.sh instead of $(srcdir)/gensymlist.sh. + (kernel_syms.lst): Depended on config.h. Use genkernsyms.sh + instead of $(srcdir)/genkernsyms.sh. + + * conf/i386-efi.rmk (symlist.c): Depended on config.h. Use + gensymlist.sh instead of $(srcdir)/gensymlist.sh. + (kernel_syms.lst): Depended on config.h. Use genkernsyms.sh + instead of $(srcdir)/genkernsyms.sh. + + * configure.ac (AC_CONFIG_FILES): Added gensymlist.sh and + genkernsyms.sh. + + * Makefile.in (DISTCLEANFILES): Added gensymlist.sh and + genkernsyms.sh. + (gensymlist.sh): New target. + (genkernsyms.sh): Likewise. + + * DISTLIST: Removed genkernsyms.sh and gensymlist.sh. Added + genkernsyms.sh.in and gensymlist.sh.in. + + * genkernsyms.sh: Removed. + * gensymlist.sh: Likewise. + + * genkernsyms.sh.in: New file. + * gensymlist.sh.in: Likewise. + +2006-04-25 Hollis Blanchard + + * kern/powerpc/ieee1275/init.c (grub_machine_set_prefix): Do not + clobber "prefix", since we may have already set it manually. + +2006-04-25 Hollis Blanchard + + * kern/misc.c (abort): New alias for grub_abort. + +2006-04-25 Yoshinori K. Okuji + + A new machine-specific function "grub_machine_set_prefix" is + defined. This is called after loading modules, so that a prefix + initialization can use modules. Also, this change adds an + intensive debugging feature for the memory manager via the + configure option "--enable-mm-debug". + + * partmap/gpt.c (gpt_partition_map_iterate): Add one more into + PART.LEN. + + * kern/sparc64/ieee1275/init.c (abort): Removed. + (grub_stop): Likewise. + (grub_exit): New function. + (grub_set_prefix): Renamed to ... + (grub_machine_set_prefix): ... this. + (grub_machine_init): Do not call grub_set_prefix. + + * kern/powerpc/ieee1275/init.c (grub_set_prefix): Renamed to ... + (grub_machine_set_prefix): ... this. + (grub_machine_init): Do not call grub_set_prefix. + + * kern/i386/pc/init.c (grub_machine_set_prefix): New function. + (grub_machine_init): Do not set the prefix here. + + * kern/i386/efi/init.c (grub_machine_set_prefix): New function. + + * kern/efi/init.c: Include grub/mm.h. + (grub_efi_set_prefix): New function. + + * kern/efi/efi.c (grub_exit): Call grub_efi_fini. + (grub_efi_get_filename): New function. + (grub_print_device_path): Renamed to ... + (grub_efi_print_device_path): ... this. + + * kern/mm.c [MM_DEBUG] (grub_malloc): Undefined. + [MM_DEBUG] (grub_realloc): Likewise. + [MM_DEBUG] (grub_free): Likewise. + [MM_DEBUG] (grub_memalign): Likewise. + [MM_DEBUG] (grub_mm_debug): New variable. + [MM_DEBUG] (grub_debug_malloc): New function. + [MM_DEBUG] (grub_debug_free): New function. + [MM_DEBUG] (grub_debug_realloc): New function. + [MM_DEBUG] (grub_debug_memalign): New function. + + * kern/misc.c (grub_abort): Print a newline to distinguish + the message. + + * kern/main.c (grub_main): Call grub_machine_set_prefix and + grub_set_root_dev after loading modules. This is necessary when + setting a prefix depends on modules. + + * include/grub/efi/efi.h (grub_print_device_path): Renamed to ... + (grub_efi_print_device_path): ... this. + (grub_efi_get_filename): New prototype. + (grub_efi_set_prefix): Likewise. + + * include/grub/efi/disk.h: Include grub/efi/api.h, grub/symbol.h + and grub/disk.h. + (grub_efidisk_get_device_handle): New prototype. + (grub_efidisk_get_device_name): Likewise. + + * include/grub/mm.h: Include config.h. + (MM_DEBUG): Removed. + [MM_DEBUG && !GRUB_UTIL] (grub_mm_debug): New prototype. + [MM_DEBUG && !GRUB_UTIL] (grub_malloc): New macro. + [MM_DEBUG && !GRUB_UTIL] (grub_realloc): Likewise. + [MM_DEBUG && !GRUB_UTIL] (grub_memalign): Likewise. + [MM_DEBUG && !GRUB_UTIL] (grub_free): Likewise. + [MM_DEBUG && !GRUB_UTIL] (grub_debug_malloc): New prototype. + [MM_DEBUG && !GRUB_UTIL] (grub_debug_realloc): New prototype. + [MM_DEBUG && !GRUB_UTIL] (grub_debug_memalign): New prototype. + [MM_DEBUG && !GRUB_UTIL] (grub_debug_free): New prototype. + + * include/grub/kernel.h (grub_machine_set_prefix): New prototype. + + * disk/efi/efidisk.c: Include grub/partition.h. + (iterate_child_devices): New function. + (add_device): First, compare only last device path nodes, so that + devices are sorted by the types. + (grub_efidisk_get_device_handle): New function. + (grub_efidisk_get_device_name): Likewise. + + * configure.ac (--enable-mm-debug): New option to enable the + memory manager debugging feature. This makes the binary much + bigger, so is disabled by default. + +2006-04-23 Yoshinori K. Okuji + + Use grub_abort instead of grub_stop, and grub_exit must be + define in each architecture now. Also, this change adds support + for EFI disks. + + * util/i386/pc/grub-probefs.c: Include grub/term.h. + (grub_getkey): New function. + (grub_term_get_current): Likewise. + + * util/i386/pc/grub-setup.c: Include grub/term.h. + (grub_getkey): New function. + (grub_term_get_current): Likewise. + + * util/misc.c (grub_stop): Renamed to ... + (grub_exit): ... this. + + * kern/powerpc/ieee1275/init.c (abort): Renamed to ... + (grub_exit): ... this. + (grub_machine_init): Use grub_abort instead of abort. + (grub_stop): Removed. + + * kern/powerpc/ieee1275/cmain.c (cmain): Use grub_abort instead of + abort. + + * kern/i386/pc/startup.S (grub_exit): New function. + (cold_reboot): New label. + + * kern/efi/init.c: Include grub/efi/disk.h and grub/env.h. + (grub_efi_init): Call grub_efidisk_init. + (grub_efi_fini): Call grub_efidisk_fini. + + * kern/efi/efi.c: Include grub/mm.h. + (grub_efi_console_control_guid): Renamed to ... + (console_control_guid): ... this. + (grub_efi_loaded_image_guid): Renamed to ... + (loaded_image_guid): ... this. + (grub_efi_locate_handle): New function. + (grub_efi_open_protocol): Likewise. + (grub_efi_set_text_mode): Use CONSOLE_CONTROL_GUID instead of + GRUB_EFI_CONSOLE_CONTROL_GUID. + (grub_efi_exit): Removed. + (grub_stop): Likewise. + (grub_efi_get_loaded_image): Use grub_efi_open_protocol. + (grub_exit): New function. + (grub_print_device_path): Likewise. + + * kern/rescue.c (grub_rescue_cmd_exit): New function. + (grub_enter_rescue_mode): Register "exit". + + * kern/misc.c (grub_real_dprintf): A cosmetic change. + (grub_abort): New function. + + * kern/err.c (grub_fatal): Use grub_abort instead of grub_stop. + + * include/grub/sparc64/ieee1275/kernel.h (abort): Removed. + + * include/grub/powerpc/ieee1275/kernel.h (abort): Removed. + + * include/grub/efi/efi.h (grub_efi_exit): Removed. + (grub_print_device_path): New prototype. + (grub_efi_locate_handle): Likewise. + (grub_efi_open_protocol): Likewise. + + * include/grub/efi/disk.h (grub_efidisk_fini): New file. + * disk/efi/efidisk.c: Likewise. + + * DISTLIST: Added disk/efi/efidisk.c and include/grub/efi/disk.h. + + * include/grub/efi/console_control.h + (GRUB_EFI_CONSOLE_CONTROL_GUID): Use an array for the last 8 bytes. + + * include/grub/efi/api.h (GRUB_EFI_LOADED_IMAGE_GUID): Specify the + last 8 bytes as an array. + (GRUB_EFI_DISK_IO_GUID): New macro. + (GRUB_EFI_BLOCK_IO_GUID): Likewise. + (GRUB_EFI_DEVICE_PATH_GUID): Likewise. + (grub_efi_ipv6_address_t): Change the type to grub_uint16_t from + grub_uint8_t. + (struct grub_efi_guid): Use an array to specify the last 8 bytes. + (struct grub_efi_device_path): Rename the member "sub_type" to + "subtype". + (GRUB_EFI_DEVICE_PATH_TYPE): New macro. + (GRUB_EFI_DEVICE_PATH_SUBTYPE): Likewise. + (GRUB_EFI_DEVICE_PATH_LENGTH): Likewise. + (GRUB_EFI_END_DEVICE_PATH_TYPE): Likewise. + (GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE): Likewise. + (GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE): Likewise. + (GRUB_EFI_END_ENTIRE_DEVICE_PATH): Likewise. + (GRUB_EFI_NEXT_DEVICE_PATH): Likewise. + (GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE): Likewise. + (GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE): Likewise. + (struct grub_efi_pci_device_path): New structure. + (grub_efi_pci_device_path_t): New type. + (GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_pccard_device_path): New structure. + (grub_efi_pccard_device_path_t): New type. + (GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_memory_mapped_device_path): New structure. + (grub_efi_memory_mapped_device_path_t): New type. + (GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_vendor_device_path): New structure. + (grub_efi_vendor_device_path_t): New type. + (GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_controller_device_path): New structure. + (grub_efi_controller_device_path_t): New type. + (GRUB_EFI_ACPI_DEVICE_PATH_TYPE): New macro. + (GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE): Likewise. + (struct grub_efi_acpi_device_path): New structure. + (grub_efi_acpi_device_path_t): New type. + (GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_expanded_acpi_device_path): New structure. + (grub_efi_expanded_acpi_device_path_t): New type. + (GRUB_EFI_EXPANDED_ACPI_HIDSTR): New macro. + (GRUB_EFI_EXPANDED_ACPI_UIDSTR): Likewise. + (GRUB_EFI_EXPANDED_ACPI_CIDSTR): Likewise. + (GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE): Likewise. + (GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE): Likewise. + (struct grub_efi_atapi_device_path): New structure. + (grub_efi_atapi_device_path_t): New type. + (GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_fibre_channel_device_path): New structure. + (grub_efi_fibre_channel_device_path_t): New type. + (GRUB_EFI_1394_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_1394_device_path): New structure. + (grub_efi_1394_device_path_t): New type. + (GRUB_EFI_USB_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_usb_device_path): New structure. + (grub_efi_usb_device_path_t): New type. + (GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_usb_class_device_path): New structure. + (grub_efi_usb_class_device_path_t): New type. + (GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_i2o_device_path): New structure. + (grub_efi_i2o_device_path_t): New type. + (GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_mac_address_device_path): New structure. + (grub_efi_mac_address_device_path_t): New type. + (GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_ipv4_device_path): New structure. + (grub_efi_ipv4_device_path_t): New type. + (GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_ipv6_device_path): New structure. + (grub_efi_ipv6_device_path_t): New type. + (GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_infiniband_device_path): New structure. + (grub_efi_infiniband_device_path_t): New type. + (GRUB_EFI_UART_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_uart_device_path): New structure. + (grub_efi_uart_device_path_t): New type. + (GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_vendor_messaging_device_path): New structure. + (grub_efi_vendor_messaging_device_path_t): New type. + (GRUB_EFI_MEDIA_DEVICE_PATH_TYPE): New macro. + (GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE): Likewise. + (struct grub_efi_hard_drive_device_path): New structure. + (grub_efi_hard_drive_device_path_t): New type. + (GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_cdrom_device_path): New structure. + (grub_efi_cdrom_device_path_t): New type. + (GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_vendor_media_device_path): New structure. + (grub_efi_vendor_media_device_path_t): New type. + (GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_file_path_device_path): New structure. + (grub_efi_file_path_device_path_t): New type. + (GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_protocol_device_path): New structure. + (grub_efi_protocol_device_path_t): New type. + (GRUB_EFI_BIOS_DEVICE_PATH_TYPE): New macro. + (GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE): Likewise. + (struct grub_efi_bios_device_path): New structure. + (grub_efi_bios_device_path_t): New type. + (struct grub_efi_disk_io): New structure. + (grub_efi_disk_io_t): New type. + (struct grub_efi_block_io_media): New structure. + (grub_efi_block_io_media_t): New type. + (struct grub_efi_block_io): New structure. + (grub_efi_block_io_t): New type. + + * include/grub/misc.h (grub_stop): Removed. + (grub_exit): New prototype. + (grub_abort): Likewise. + + * include/grub/disk.h (enum grub_disk_dev_id): Added + GRUB_DISK_DEVICE_EFIDISK_ID. + + * conf/i386-efi.rmk (kernel_mod_SOURCES): Added + disk/efi/efidisk.c. + (kernel_syms.lst): Remove the target if an error occurs. + +2006-04-22 Yoshinori K. Okuji + + * kern/misc.c (grub_lltoa): Rewritten the decimal conversion part, + as it was simply too buggy. + +2006-04-21 Yoshinori K. Okuji + + * kern/misc.c (grub_lltoa): New function. + (grub_vsprintf): Added support for the long long suffix, + i.e. "ll". + +2006-04-20 Hollis Blanchard + + * Makefile.in (LDFLAGS): Add variable. + (LD): Remove variable. + * configure.ac: Add -m32 to LDFLAGS. + * genmk.rb (PModule#rule): Use $(CC) instead of $(LD). + * conf/powerpc-ieee1275.rmk (COMMON_LDFLAGS): Add variable. + (grubof_LDFLAGS): Use $(COMMON_LDFLAGS). + (_linux_mod_LDFLAGS, linux_mod_LDFLAGS, normal_mod_LDFLAGS, + suspend_mod_LDFLAGS, reboot_mod_LDFLAGS, halt_mod_LDFLAGS): New + variables. + * conf/sparc64-ieee1275.rmk (COMMON_LDFLAGS): Add -nostdlib. + * conf/i386-pc.rmk (COMMON_LDFLAGS): Add -nostdlib. + * conf/i386-efi.rmk (COMMON_LDFLAGS): Add -nostdlib. + +2006-04-20 Vesa Jaaskelainen + + * term/gfxterm.c (grub_gfxterm_getcharwidth): Fixed character + length for unknown glyph. + +2006-04-20 Yoshinori K. Okuji + + Add support for pre-loaded modules into the EFI port. + + * util/i386/efi/grub-mkimage.c (make_mods_section): Rewritten + completely. Accept one more argument DIR. The caller has changed. + + * kern/i386/efi/init.c (grub_arch_modules_addr): Removed. + + * kern/efi/efi.c: Include grub/efi/pe32.h and grub/kernel.h. + (grub_efi_loaded_image_guid): New variable. + (grub_efi_get_loaded_image): New function. + (grub_arch_modules_addr): Likewise. + + * include/grub/efi/efi.h (grub_efi_get_loaded_image): New + prototype. + + * include/grub/efi/api.h (GRUB_EFI_LOADED_IMAGE_GUID): New macro. + (struct grub_efi_loaded_image): New structure. + (grub_efi_loaded_image_t): New type. + +2006-04-20 Yoshinori K. Okuji + + * loader/i386/pc/linux.c (grub_rescue_cmd_linux): Compare the file + size with GRUB_OS_AREA_SIZE as grub_size_t instead of + grub_ssize_t. Reported by Jeff Chua . + +2006-04-19 Roger Leigh + + * DISTLIST: Added `util/powerpc/ieee1275/grub-install.in'. + +2006-04-19 Yoshinori K. Okuji + + * DISTLIST: Added include/grub/efi/console.h, + include/grub/efi/time.h, include/grub/i386/efi/kernel.h, + kern/efi/init.c, kern/efi/mm.c, and term/efi/console.c. + + * include/grub/efi/console.h: New file. + * include/grub/efi/time.h: Likewise. + * include/grub/i386/efi/kernel.h: Likewise. + * kern/efi/init.c: Likewise. + * kern/efi/mm.c: Likewise. + * term/efi/console.c: Likewise. + + * kern/i386/efi/init.c: Do not include grub/machine/time.h. + (grub_stop): Removed. + (grub_get_rtc): Likewise. + (grub_machine_init): Simply call grub_efi_init. + (grub_machine_fini): Call grub_efi_fini. + + * kern/efi/efi.c: Include grub/machine/time.h and grub/term.h. + (grub_efi_output_string): Removed. + (grub_efi_stall): New function. + (grub_stop): Likewise. + (grub_get_rtc): Likewise. + + * include/grub/efi/efi.h (grub_efi_output_string): Removed. + (grub_efi_stall): New prototype. + (grub_efi_allocate_pages): Likewise. + (grub_efi_free_pages): Likewise. + (grub_efi_get_memory_map): Likewise. + (grub_efi_mm_init): Likewise. + (grub_efi_mm_fini): Likewise. + (grub_efi_init): Likewise. + (grub_efi_fini): Likewise. + + * include/grub/i386/efi/time.h: Do not include + grub/symbol.h. Include grub/efi/time.h. + (GRUB_TICKS_PER_SECOND): Removed. + (grub_get_rtc): Likewise. + + * include/grub/efi/api.h (struct grub_efi_memory_descriptor): + Added padding. The EFI spec is buggy. + (GRUB_EFI_BLACK): New macro. + (GRUB_EFI_BLUE): Likewise. + (GRUB_EFI_GREEN): Likewise. + (GRUB_EFI_CYAN): Likewise. + (GRUB_EFI_RED): Likewise. + (GRUB_EFI_MAGENTA): Likewise. + (GRUB_EFI_BROWN): Likewise. + (GRUB_EFI_LIGHTGRAY): Likewise. + (GRUB_EFI_BRIGHT): Likewise. + (GRUB_EFI_DARKGRAY): Likewise. + (GRUB_EFI_LIGHTBLUE): Likewise. + (GRUB_EFI_LIGHTGREEN): Likewise. + (GRUB_EFI_LIGHTCYAN): Likewise. + (GRUB_EFI_LIGHTRED): Likewise. + (GRUB_EFI_LIGHTMAGENTA): Likewise. + (GRUB_EFI_YELLOW): Likewise. + (GRUB_EFI_WHITE): Likewise. + (GRUB_EFI_BACKGROUND_BLACK): Likewise. + (GRUB_EFI_BACKGROUND_BLUE): Likewise. + (GRUB_EFI_BACKGROUND_GREEN): Likewise. + (GRUB_EFI_BACKGROUND_CYAN): Likewise. + (GRUB_EFI_BACKGROUND_RED): Likewise. + (GRUB_EFI_BACKGROUND_MAGENTA): Likewise. + (GRUB_EFI_BACKGROUND_BROWN): Likewise. + (GRUB_EFI_BACKGROUND_LIGHTGRAY): Likewise. + (GRUB_EFI_TEXT_ATTR): Likewise. + + * conf/i386-efi.rmk (kernel_mod_SOURCES): Added kern/efi/efi.c, + kern/efi/init.c, kern/efi/mm.c, and term/efi/console.c. + (kernel_mod_HEADERS): Added efi/time.h. + +2006-04-18 Yoshinori K. Okuji + + * DISTLIST: Added conf/i386-efi.mk, conf/i386-efi.rmk, + include/grub/efi/api.h, include/grub/efi/console_control.h, + include/grub/efi/efi.h, include/grub/efi/pe32.h, + include/grub/i386/efi/time.h, kern/efi/efi.c, + kern/i386/efi/init.c, kern/i386/efi/startup.S, + and util/i386/efi/grub-mkimage.c. + + * Makefile.in (RMKFILES): Added i386-efi.rmk. + + * genmk.rb (PModule#rule): Do not export symbols if + #{prefix}_EXPORTS is set to "no". + + * conf/i386-efi.mk: New file. + * conf/i386-efi.rmk: Likewise. + * include/grub/efi/api.h: Likewise. + * include/grub/efi/console_control.h: Likewise. + * include/grub/efi/efi.h: Likewise. + * include/grub/efi/pe32.h: Likewise. + * include/grub/i386/efi/time.h: Likewise. + * kern/efi/efi.c: Likewise. + * kern/i386/efi/init.c: Likewise. + * kern/i386/efi/startup.S: Likewise. + * util/i386/efi/grub-mkimage.c: Likewise. + +2006-04-17 Marco Gerards + + * include/grub/script.h: Include and + "grub_script.tab.h". + (struct grub_lexer_param): New struct. + (struct grub_parser_param): Likewise. + (grub_script_create_arglist): Pass the state in an argument. + (grub_script_add_arglist): Likewise. + (grub_script_create_cmdline): Likewise. + (grub_script_create_cmdblock): Likewise. + (grub_script_create_cmdif): Likewise. + (grub_script_create_cmdmenu): Likewise. + (grub_script_add_cmd): Likewise. + (grub_script_arg_add): Likewise. + (grub_script_lexer_ref): Likewise. + (grub_script_lexer_deref): Likewise. + (grub_script_lexer_record_start): Likewise. + (grub_script_lexer_record_stop): Likewise. + (grub_script_mem_record): Likewise. + (grub_script_mem_record_stop): Likewise. + (grub_script_malloc): Likewise. + (grub_script_yylex): Likewise. + (grub_script_yyparse): Likewise. + (grub_script_yyerror): Likewise. + (grub_script_yylex): Likewise. + (grub_script_lexer_init): Return the state. + + * normal/lexer.c (grub_script_lexer_state): Removed variable. + (grub_script_lexer_done): Likewise. + (grub_script_lexer_getline): Likewise. + (grub_script_lexer_refs): Likewise. + (script): Likewise. + (newscript): Likewise. + (record): Likewise. + (recording): Likewise. + (recordpos): Likewise. + (recordlen): Likewise. + (grub_script_lexer_init): Return the state instead of setting + global variables. + (grub_script_lexer_ref): Use the newly added argument for state + instead of globals. + (grub_script_lexer_deref): Likewise. + (grub_script_lexer_record_start): Likewise. + (grub_script_lexer_record_stop): Likewise. + (recordchar): Likewise. + (nextchar): Likewise. + (grub_script_yylex2): Likewise. + (grub_script_yylex): Likewise. + (grub_script_yyerror): Likewise. + + * normal/parser.y (func_mem): Removed variable. + (menu_entry): Likewise. + (err): Likewise. + (%lex-param): New parser option. + (%parse-param): Likewise. + (script): Always return the AST. + (argument): Pass the state around. + (arguments): Likewise. + (grubcmd): Likewise. + (commands): Likewise. + (function): Likewise. + (menuentry): Likewise. + (if_statement): Likewise. + (if): Likewise. + + * normal/script.c (grub_script_memused): Removed variable. + (grub_script_parsed): Likewise. + (grub_script_malloc): Added a state argument. Use that instead of + global variables. + (grub_script_mem_record): Likewise. + (grub_script_mem_record_stop): Likewise. + (grub_script_arg_add): Likewise. + (grub_script_add_arglist): Likewise. + (grub_script_create_cmdline): Likewise. + (grub_script_create_cmdif): Likewise. + (grub_script_create_cmdmenu): Likewise. + (grub_script_add_cmd): Likewise. + (grub_script_parse): Setup the state before calling the parser. + +2006-04-16 Marco Gerards + + * normal/command.c (grub_command_init): Remove the title command. + + * normal/lexer.c (grub_script_yylex): Renamed from this... + (grub_script_yylex2): ... to this. + (grub_script_yylex): New function. Temporary + introduced to filter some tokens. + (grub_script_yyerror): Print a newline. + + * normal/main.c (read_config_file): Output information about the + lines that contain errors. Wait for a key after all lines have + been processed. Don't return an empty menu. + + * normal/parser.y (func_mem): Don't initialize. + (menu_entry): Likewise. + (err): New variable. + (script): Don't return anything when an error was encountered. + (ws, returns): Removed rules. + (argument): Disabled concatenated variable support. + (arguments): Remove explicit separators. + (grubcmd): Likewise. + (function): Likewise. + (menuentry): Likewise. + (if): Likewise. + (commands): Likewise. Add error handling. + + * normal/script.c (grub_script_create_cmdline): If + `grub_script_parsed' is 0, assume the parser encountered an error. + +2006-04-02 Yoshinori K. Okuji + + * configure.ac: Add support for EFI. Fix the typo + BUILD_LDDFLAGS. Restore the LDFLAGS after testing. + +2006-04-01 Vesa Jaaskelainen + + * util/unifont2pff.rb: Removed unnecessary byte ordering. Now + foreign multibyte characters should be shown correctly. + +2006-04-01 Vesa Jaaskelainen + + * normal/main.c (grub_normal_menu_addentry): Fixed menu size + calculation. + (read_config_file): Made it to close file before returning. + +2006-03-31 Vesa Jaaskelainen + + * DISTLIST: Added include/grub/i386/pc/vbeblit.h, + include/grub/i386/pc/vbefill.h, video/i386/pc/vbeblit.c, + video/i386/pc/vbefill.c. + + * conf/i386-pc.rmk (vbe_mod_SOURCES): Added video/i386/pc/vbeblit.c, + video/i386/pc/vbefill.c. + + * include/grub/video.h (grub_video_blit_format): New enum. + (grub_video_mode_info): Added new member blit_format. + (grub_video_get_blit_format): New function prototype. + + * include/grub/i386/pc/vbe.h (grub_video_vbe_get_video_ptr): New + function prototype. + (grub_video_vbe_map_rgb): Likewise. + (grub_video_vbe_unmap_color): Likewise. + + * include/grub/i386/pc/vbeblit.h: New file. + + * include/grub/i386/pc/vbefill.h: New file. + + * video/video.c (grub_video_get_blit_format): New function. + (grub_video_vbe_get_video_ptr): Re-declared as non-static. + (grub_video_vbe_map_rgb): Likewise. + (grub_video_vbe_unmap_color): Likewise. + + * video/i386/pc/vbe.c (grub_video_vbe_fill_rect): Changed to use more + optimized fills. + (grub_video_vbe_blit_render_target): Changed to use more optimized + blits. + (grub_video_vbe_setup): Added detection for optimized settings. + (grub_video_vbe_create_render_target): Likewise. + + * video/i386/pc/vbeblit.c: New file. + + * video/i386/pc/vbefill.c: New file. + +2006-03-30 Vesa Jaaskelainen + + * font/manager.c (grub_font_get_glyph): Removed font fixup from + here... + + * util/unifont2pff.rb: ... and moved it to here. Improved argument + parsing to support both hex and dec ranges. If filename was missing + show usage information. + +2006-03-14 Vesa Jaaskelainen + + * DISTLIST: Added include/grub/video.h, term/gfxterm.c, + video/video.c, commands/videotest.c. Removed term/i386/pc/vesafb.c. + + * conf/i386-pc.rmk (pkgdata_MODULES): Added video.mod, + gfxterm.mod, videotest.mod. Removed vga.mod, vesafb.mod. + (video_mod_SOURCES): Added. + (video_mod_CFLAGS): Likewise. + (video_mod_LDFLAGS): Likewise. + (gfxterm_mod_SOURCES): Likewise. + (gfxterm_mod_CFLAGS): Likewise. + (gfxterm_mod_LDFLAGS): Likewise. + (videotest_mod_SOURCES): Likewise. + (videotest_mod_CFLAGS): Likewise. + (videotest_mod_LDFLAGS): Likewise. + (vesafb_mod_SOURCES): Removed. + (vesafb_mod_CFLAGS): Likewise. + (vesafb_mod_LDFLAGS): Likewise. + (vga_mod_SOURCES): Likewise. + (vga_mod_CFLAGS): Likewise. + (vga_mod_LDFLAGS): Likewise. + + * commands/videotest.c: New file. + + * font/manager.c (fill_with_default_glyph): Modified to use + grub_font_glyph. + (grub_font_get_glyph): Likewise. + (fontmanager): Renamed from this... + (font_manager): ... to this. + + * include/grub/font.h (grub_font_glyph): Added new structure. + (grub_font_get_glyph): Modified to use grub_font_glyph. + + * include/grub/misc.h (grub_abs): Added as inline function. + + * include/grub/video.h: New file. + + * include/grub/i386/pc/vbe.h (GRUB_VBE_STATUS_OK): New macro. + (GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL): Likewise. + (GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR): Likewise. + (grub_vbe_get_controller_info): Renamed from this... + (grub_vbe_bios_get_controller_info): ... to this. + (grub_vbe_get_mode_info): Renamed from this... + (grub_vbe_bios_get_mode_info): ... to this. + (grub_vbe_set_mode): Renamed from this... + (grub_vbe_bios_set_mode): ... to this. + (grub_vbe_get_mode): Renamed from this... + (grub_vbe_bios_get_mode): ... to this. + (grub_vbe_set_memory_window): Renamed from this... + (grub_vbe_bios_set_memory_window): ... to this. + (grub_vbe_get_memory_window): Renamed from this... + (grub_vbe_bios_get_memory_window): ... to this. + (grub_vbe_set_scanline_length): Renamed from this... + (grub_vbe_set_scanline_length): ... to this. + (grub_vbe_get_scanline_length): Renamed from this... + (grub_vbe_bios_get_scanline_length): ... to this. + (grub_vbe_set_display_start): Renamed from this... + (grub_vbe_bios_set_display_start): ... to this. + (grub_vbe_get_display_start): Renamed from this... + (grub_vbe_bios_get_display_start): ... to this. + (grub_vbe_set_palette_data): Renamed from this... + (grub_vbe_bios_set_palette_data): ... to this. + (grub_vbe_set_pixel_rgb): Removed. + (grub_vbe_set_pixel_index): Likewise. + + * kern/i386/pc/startup.S (grub_vbe_get_controller_info): Renamed + from this... + (grub_vbe_bios_get_controller_info): ... to this. + (grub_vbe_get_mode_info): Renamed from this... + (grub_vbe_bios_get_mode_info): ... to this. + (grub_vbe_set_mode): Renamed from this... + (grub_vbe_bios_set_mode): ... to this. + (grub_vbe_get_mode): Renamed from this... + (grub_vbe_bios_get_mode): ... to this. + (grub_vbe_set_memory_window): Renamed from this... + (grub_vbe_bios_set_memory_window): ... to this. + (grub_vbe_get_memory_window): Renamed from this... + (grub_vbe_bios_get_memory_window): ... to this. + (grub_vbe_set_scanline_length): Renamed from this... + (grub_vbe_set_scanline_length): ... to this. + (grub_vbe_get_scanline_length): Renamed from this... + (grub_vbe_bios_get_scanline_length): ... to this. + (grub_vbe_set_display_start): Renamed from this... + (grub_vbe_bios_set_display_start): ... to this. + (grub_vbe_get_display_start): Renamed from this... + (grub_vbe_bios_get_display_start): ... to this. + (grub_vbe_set_palette_data): Renamed from this... + (grub_vbe_bios_set_palette_data): ... to this. + (grub_vbe_bios_get_controller_info): Fixed problem with registers + getting corrupted after calling it. Added more pushes and pops. + (grub_vbe_bios_set_mode): Likewise. + (grub_vbe_bios_get_mode): Likewise. + (grub_vbe_bios_get_memory_window): Likewise. + (grub_vbe_bios_set_scanline_length): Likewise. + (grub_vbe_bios_get_scanline_length): Likewise. + (grub_vbe_bios_get_display_start): Likewise. + (grub_vbe_bios_set_palette_data): Likewise. + + * normal/cmdline.c (cl_set_pos): Refresh the screen. + (cl_insert): Likewise. + (cl_delete): Likewise. + + * term/gfxterm.c: New file. + + * term/i386/pc/vesafb.c: Removed file. + + * video/video.c: New file. + + * video/i386/pc/vbe.c (real2pm): Added new function. + (grub_video_vbe_draw_pixel): Likewise. + (grub_video_vbe_get_video_ptr): Likewise. + (grub_video_vbe_get_pixel): Likewise + (grub_video_vbe_init): Likewise. + (grub_video_vbe_fini): Likewise. + (grub_video_vbe_setup): Likewise. + (grub_video_vbe_get_info): Likewise. + (grub_video_vbe_set_palette): Likewise. + (grub_video_vbe_get_palette): Likewise. + (grub_video_vbe_set_viewport): Likewise. + (grub_video_vbe_get_viewport): Likewise. + (grub_video_vbe_map_color): Likewise. + (grub_video_vbe_map_rgb): Likewise. + (grub_video_vbe_map_rgba): Likewise. + (grub_video_vbe_unmap_color): Likewise. + (grub_video_vbe_fill_rect): Likewise. + (grub_video_vbe_blit_glyph): Likewise. + (grub_video_vbe_blit_bitmap): Likewise. + (grub_video_vbe_blit_render_target): Likewise. + (grub_video_vbe_scroll): Likewise. + (grub_video_vbe_swap_buffers): Likewise. + (grub_video_vbe_create_render_target): Likewise. + (grub_video_vbe_delete_render_target): Likewise. + (grub_video_vbe_set_active_render_target): Likewise. + (grub_vbe_set_pixel_rgb): Remove function. + (grub_vbe_set_pixel_index): Likewise. + (index_color_mode): Remove static variable. + (active_mode): Likewise. + (framebuffer): Likewise. + (bytes_per_scan_line): Likewise. + (grub_video_vbe_adapter): Added new static variable. + (framebuffer): Likewise. + (render_target): Likewise. + (initial_mode): Likewise. + (mode_in_use): Likewise. + (mode_list): Likewise. + +2006-03-10 Marco Gerards + + * configure.ac (AC_INIT): Bumped to 1.93. + + * DISTLIST: Added `include/grub/hfs.h'. + +2006-02-01 Yoshinori K. Okuji + + * boot/i386/pc/boot.S (general_error): Before looping, try INT + 18H, which might help the BIOS falling back to next boot media. + +2006-01-25 Yoshinori K. Okuji + + * util/i386/pc/grub-install.in: Escape a backslash. Reported by + Poe Chen . + +2006-01-17 Marco Gerards + + * include/grub/normal.h: Include . + (grub_command_list): Removed struct. + (grub_command_list_t): Removed type. + (grub_menu_entry): Remove members `num' and `command_list'. Add + members `commands' and `sourcecode'. + * include/grub/script.h: Add inclusion guards. + (grub_script_cmd_menuentry): New struct. + (grub_script_execute_menuentry): New prototype. + (grub_script_lexer_record_start): Likewise. + (grub_script_lexer_record_stop): Likewise. + * normal/execute.c (grub_script_execute_menuentry): New function. + * normal/lexer.c (record, recording, recordpos, recordlen): New + variables. + (grub_script_lexer_record_start): New function. + (grub_script_lexer_record_stop): Likewise. + (recordchar): Likewise. + (nextchar): Likewise. + (grub_script_yylex): Use `nextchar' to fetch new characters. Use + 2048 as the buffer size. Add the tokens `menuentry' and `@'. + * normal/main.c: Include and + (current_menu): New variable. + (free_menu): Mainly rewritten. + (grub_normal_menu_addentry): New function. + (read_config_file): Rewritten. + * normal/menu.c (run_menu_entry): Mainly rewritten. + * normal/menu_entry.c (make_screen): Rewritten the code to insert + the menu entry. + (run): Mainly rewritten. + * normal/parser.y (menu_entry): New variable. + (GRUB_PARSER_TOKEN_MENUENTRY): New token. + (menuentry): New rule. + (command): Add `menuentry'. + (if_statement): Allow additional returns before `fi'. + * normal/script.c (grub_script_create_cmdmenu): New function. + +2006-01-03 Marco Gerards + + * INSTALL: GNU Bison is required. + * configure.ac: Rewritten the test to detect Bison. + * Makefile.in (YACC): New variable. Reported by Xun Sun + . + +2006-01-03 Marco Gerards + + * fs/hfsplus.c (grub_hfsplus_read_block): Convert the offset of + the HFS+ filesystem to filesystem blocks. + (grub_hfsplus_iterate_dir): Cast the `fileinfo' assignment so a + GCC warning is silenced. + +2006-01-03 Marco Gerards + + * partmap/apple.c (apple_partition_map_iterate): Convert the data + read from disk from big endian to host byte order. + +2006-01-03 Hollis Blanchard + + * fs/hfs.c: Include . Added reference to the official + documentation. + (GRUB_HFS_EMBED_HFSPLUS_SIG): New macro. + (grub_hfs_mount): Grammar fix in error. Make sure this is not an + embedded HFS+ filesystem. + (GRUB_HFS_MAGIC, grub_hfs_extent, grub_hfs_datarecord_t) + (grub_hfs_sblock): Move from here... + * include/grub/hfs.h: To here... New file. + * fs/hfsplus.c: Include . Added reference to the official + documentation. + (GRUB_HFSPLUS_MAGIC, GRUB_HFSPLUSX_MAGIC, GRUB_HFSPLUS_SBLOCK): + New macros. + (grub_hfsplus_volheader): Change type of member `magic' to + `grub_uint16_t'. + (grub_hfsplus_data): Add new member `embedded_offset'. + (grub_hfsplus_read_block): Add the HFS+ wrapper offset to the + returned block. + (grub_hfsplus_mount): Read the HFS+ wrapper if it exists. + Calculate the offset. + +2005-12-25 Yoshinori K. Okuji + + * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_DRP_ADDR): + Removed. + (GRUB_BOOT_MACHINE_DRP_SIZE): Likewise. + +2005-12-25 Yoshinori K. Okuji + + * kern/env.c (grub_env_set): Check if ENV->VALUE instead of + ENV->NAME is NULL after allocating ENV->VALUE. + +2005-12-25 Marco Gerards + + * kern/env.c (grub_env_set): Rewritten the error handling code. + +2005-12-25 Yoshinori K. Okuji + + * geninit.sh: Made more robust, and more portable. + +2005-12-25 Marco Gerards + + Add support for Apple HFS+ filesystems. + + * fs/hfsplus.c: New file. + + * DISTLIST: Added `fs/hfsplus.c'. + + * conf/common.rmk (pkgdata_MODULES): Add `hfsplus.mod'. + (hfsplus_mod_SOURCES): New variable. + (hfsplus_mod_CFLAGS): Likewise. + (hfsplus_mod_LDFLAGS): Likewise. + * conf/i386-pc.rmk (grub_setup_SOURCES): Add `fs/hfsplus.c'. + (grub_setup_SOURCES): Likewise. + (grub_mkdevicemap_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * fs/fshelp.c (grub_fshelp_log2blksize): New function. + + * include/grub/fshelp.h (grub_fshelp_log2blksize): new prototype. + +2005-12-25 Yoshinori K. Okuji + + * DISTLIST: Added geninitheader.sh, geninit.sh, commands/test.c, + commands/i386/pc/play.c, conf/common.mk, conf/common.rmk, + include/grub/parser.h, include/grub/script.h, kern/parser.c, + kern/sparc64/cache.S, normal/execute.c, normal/function.c, + normal/lexer.c, normal/parser.y, normal/script.c, and + partmap/gpt.c. + Removed kern/sparc64/cache.c. + + * conf/common.rmk (DISTCLEANFILES): Added grub_script.tab.c, + grub_script.tab.h, grub_modules_init.lst, grub_modules_init.h, + grub_emu_init.c. + + * configure.ac (AC_INIT): Bumped to 1.92. + +2005-12-24 Vesa Jaaskelainen + + * kern/err.c (grub_error_push): Added new function to support error + stacks. + (grub_error_pop): Likewise. + (grub_error_stack_items): New local variable to support error stacks. + (grub_error_stack_pos): Likewise. + (grub_error_stack_assert): Likewise. + (GRUB_ERROR_STACK_SIZE): Added new define to configure maximum error + stack depth. + (grub_print_error): Added support to print errors from error stack. + + * include/grub/err.h (grub_error_push): Added function prototype. + (grub_error_pop): Likewise. + +2005-12-09 Hollis Blanchard + + * configure.ac: Accept `powerpc64' as host_cpu. + (amd64): Rename to `biarch32'. + + * kern/powerpc/cache.S (grub_arch_sync_caches): Handle + non-cacheline-aligned addresses. + + * kern/dl.c (grub_dl_load_core): Add grub_dprintf messages. + (grub_dl_flush_cache): Likewise. Only call `grub_arch_sync_caches' + if `size' is non-zero. + +2005-12-03 Marco Gerards + + * conf/common.rmk (grub_modules_init.lst): Use `-printf "%P\n"' + and `cd' to make sure the filename is not prefixed with a + directory name. + (pkgdata_MODULES): Add `gpt.mod'. + (gpt_mod_SOURCES): New variable. + (gpt_mod_CFLAGS): Likewise. + (gpt_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `partmap/gpt.c'. + + * include/grub/pc_partition.h (GRUB_PC_PARTITION_TYPE_GPT_DISK): + New macro. + + * partmap/gpt.c: New file. + + * partmap/pc.c (pc_partition_map_iterate): Don't continue when a + GPT partition map is detected. + +2005-12-03 Vincent Pelletier + + * commands/i386/pc/play.c: New file. + * conf/i386-pc.rmk (pkgdata_MODULES): Added play.mod. + (play_mod_SOURCES, play_mod_CFLAGS, play_mod_LDFLAGS): New + macros. + +2005-11-27 Marco Gerards + + * include/grub/dl.h (GRUB_MOD_INIT): Use `__attribute__ + ((unused))' to silence gcc warning. + +2005-11-26 Hollis Blanchard + + * configure.ac: Correct `AC_PROG_YACC' test. + +2005-11-22 Hollis Blanchard + + * util/powerpc/ieee1275/grub-install.in: Run the mount point + check before installing files. + +2005-11-22 Mike Small + + * util/powerpc/ieee1275/grub-install.in (grubdir): Fixed partition + number regex so multidigit numbers are recognized correctly. + +2005-11-22 Mike Small + + * loader/powerpc/ieee1275/linux.c (grub_rescue_cmd_linux): Add a + debugging message before attempting to claim memory. + (grub_rescue_cmd_initrd): Add a claim debugging message and try + multiple addresses in case of failure. + +2005-11-22 Hollis Blanchard + + * term/tparm.c (get_space): Remove empty `if' statement. + + * fs/ufs.c (grub_ufs_find_file): Remove `grub_le_to_cpu32'. + + * kern/parser.c (check_varstate): Rename `state' to 's'. + +2005-11-22 Hollis Blanchard + + * partmap/acorn.c: Change `unsigned' to `unsigned int'. Move all + variable definitions to the beginning of each function. Sort stack + variables by size. + (find): Rename to `acorn_partition_map_find'. Cast `grub_disk_read' + `buf' argument to `char *'. + +2005-11-22 Hollis Blanchard + + * conf/powerpc-ieee1275.rmk: Include conf/common.mk. + (pkgdata_MODULES): Removed fshelp.mod, fat.mod, ext2.mod, ufs.mod, + minix.mod, hfs.mod, jfs.mod, xfs.mod, affs.mod, sfs.mod, + hello.mod, boot.mod, terminal.mod, ls.mod, cmp.mod, cat.mod, + help.mod, font.mod, terminfo.mod, amiga.mod, apple.mod, pc.mod, + sun.mod, acorn.mod, loopback.mod, default.mod, timeout.mod, + configfile.mod, search.mod, gzio.mod and test.mod. + (symlist.c, grub_script.tab.c, grub_script.tab.h, kernel_syms.lst) + (grub_modules_init.lst, grub_modules_init.h, grub_emu_init.c) + (fshelp_mod_SOURCES, fshelp_mod_CFLAGS, fshelp_mod_LDFLAGS) + (fat_mod_SOURCES, fat_mod_CFLAGS, fat_mod_LDFLAGS) + (ext2_mod_SOURCES, ext2_mod_CFLAGS, ext2_mod_LDFLAGS) + (ufs_mod_SOURCES, ufs_mod_CFLAGS, ufs_mod_LDFLAGS) + (minix_mod_SOURCES, minix_mod_CFLAGS, minix_mod_LDFLAGS) + (hfs_mod_SOURCES, hfs_mod_CFLAGS, hfs_mod_LDFLAGS, jfs_mod_SOURCES) + (jfs_mod_CFLAGS, jfs_mod_LDFLAGS, iso9660_mod_SOURCES) + (iso9660_mod_CFLAGS, iso9660_mod_LDFLAGS, xfs_mod_SOURCES) + (xfs_mod_CFLAGS, xfs_mod_LDFLAGS, affs_mod_SOURCES) + (affs_mod_CFLAGS, affs_mod_LDFLAGS, sfs_mod_SOURCES) + (sfs_mod_CFLAGS, sfs_mod_LDFLAGS, hello_mod_SOURCES) + (hello_mod_CFLAGS, hello_mod_LDFLAGS, boot_mod_SOURCES) + (boot_mod_CFLAGS, boot_mod_LDFLAGS, terminal_mod_SOURCES) + (terminal_mod_CFLAGS, terminal_mod_LDFLAGS, ls_mod_SOURCES) + (ls_mod_CFLAGS, ls_mod_LDFLAGS, cmp_mod_SOURCES, cmp_mod_CFLAGS) + (cmp_mod_LDFLAGS, cat_mod_SOURCES, cat_mod_CFLAGS, cat_mod_LDFLAGS) + (help_mod_SOURCES, help_mod_CFLAGS, help_mod_LDFLAGS) + (font_mod_SOURCES, font_mod_CFLAGS, font_mod_LDFLAGS) + (terminfo_mod_SOURCES, terminfo_mod_CFLAGS, terminfo_mod_LDFLAGS) + (amiga_mod_SOURCES, amiga_mod_CFLAGS, amiga_mod_LDFLAGS) + (apple_mod_SOURCES, apple_mod_CFLAGS, apple_mod_LDFLAG): Removed. + + * conf/common.mk (grub_modules_init.lst): Use `find' instead of + `grep --include'. + (pkgdata_MODULES): Add test.mod. + +2005-11-18 Timothy Baldwin + + * genmk.rb: Fixed list rules moved to Makefile.in. Recognise + appending to variables with "+=". + (PModule): Use full pathname to generate *.lst filenames. + + * Makefile.in: Fixed list rules moved from genmk.rb. + (.DELETE_ON_ERROR): New special target. + (RMKFILES): Add common.rmk and sparc64-ieee1275.rmk. + + * conf/i386-pc.rmk: Include conf/common.mk. + (pkgdata_MODULES): Removed fshelp.mod, fat.mod, ext2.mod, ufs.mod, + minix.mod, hfs.mod, jfs.mod, xfs.mod, affs.mod, sfs.mod, + hello.mod, boot.mod, terminal.mod, ls.mod, cmp.mod, cat.mod, + help.mod, font.mod, terminfo.mod, amiga.mod, apple.mod, pc.mod, + sun.mod, acorn.mod, loopback.mod, default.mod, timeout.mod, + configfile.mod, search.mod, gzio.mod and test.mod. + (symlist.c, grub_script.tab.c, grub_script.tab.h, kernel_syms.lst) + (grub_modules_init.lst, grub_modules_init.h, grub_emu_init.c) + (fshelp_mod_SOURCES, fshelp_mod_CFLAGS, fshelp_mod_LDFLAGS) + (fat_mod_SOURCES, fat_mod_CFLAGS, fat_mod_LDFLAGS) + (ext2_mod_SOURCES, ext2_mod_CFLAGS, ext2_mod_LDFLAGS) + (ufs_mod_SOURCES, ufs_mod_CFLAGS, ufs_mod_LDFLAGS) + (minix_mod_SOURCES, minix_mod_CFLAGS, minix_mod_LDFLAGS) + (hfs_mod_SOURCES, hfs_mod_CFLAGS, hfs_mod_LDFLAGS, jfs_mod_SOURCES) + (jfs_mod_CFLAGS, jfs_mod_LDFLAGS, iso9660_mod_SOURCES) + (iso9660_mod_CFLAGS, iso9660_mod_LDFLAGS, xfs_mod_SOURCES) + (xfs_mod_CFLAGS, xfs_mod_LDFLAGS, affs_mod_SOURCES) + (affs_mod_CFLAGS, affs_mod_LDFLAGS, sfs_mod_SOURCES) + (sfs_mod_CFLAGS, sfs_mod_LDFLAGS, hello_mod_SOURCES) + (hello_mod_CFLAGS, hello_mod_LDFLAGS, boot_mod_SOURCES) + (boot_mod_CFLAGS, boot_mod_LDFLAGS, terminal_mod_SOURCES) + (terminal_mod_CFLAGS, terminal_mod_LDFLAGS, ls_mod_SOURCES) + (ls_mod_CFLAGS, ls_mod_LDFLAGS, cmp_mod_SOURCES, cmp_mod_CFLAGS) + (cmp_mod_LDFLAGS, cat_mod_SOURCES, cat_mod_CFLAGS, cat_mod_LDFLAGS) + (help_mod_SOURCES, help_mod_CFLAGS, help_mod_LDFLAGS) + (font_mod_SOURCES, font_mod_CFLAGS, font_mod_LDFLAGS) + (terminfo_mod_SOURCES, terminfo_mod_CFLAGS, terminfo_mod_LDFLAGS) + (amiga_mod_SOURCES, amiga_mod_CFLAGS, amiga_mod_LDFLAGS) + (apple_mod_SOURCES, apple_mod_CFLAGS, apple_mod_LDFLAG): Move from + here... + * conf/common.rmk: ... to here. New file. + + * conf/common.mk: New file. + +2005-11-18 Yoshinori K. Okuji + + * conf/powerpc-ieee1275.rmk (grub_script.tab.h): Unified to ... + (grub_script.tab.c): ... here. + + * conf/sparc64-ieee1275.rmk (grub_script.tab.h): Unified to ... + (grub_script.tab.c): ... here. + + * conf/i386-pc.rmk (grub_script.tab.h): Unified to ... + (grub_script.tab.c): ... here. + + * normal/command.c (grub_command_find): Fixed a memory leak of + MODULE_NAME. Reported by Mike Small . + +2005-11-13 Timothy Baldwin + + * include/grub/symbol.h: (FUNCTION): Use double quotes instead of + "@" which marks the start of a comment on ARM. + (VARIABLE): Likewise. + +2005-11-13 Timothy Baldwin + + Add support for Linux/ADFS partition tables. + + * partmap/acorn.c: New file. + + * include/grub/acorn_filecore.h: Likewise. + + * DISTLIST: Added `partmap/acorn.c' and + `include/grub/acorn_filecore.h'. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add + `partmap/acorn.c'. + (pkgdata_MODULES): Add `acorn.mod'. + (acorn_mod_SOURCES): New variable. + (acorn_mod_CFLAGS): Likewise. + + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Add + `partmap/acorn.c'. + (pkgdata_MODULES): Add `acorn.mod'. + (acorn_mod_SOURCES): New variable. + (acorn_mod_CFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `partmap/acorn.c'. + (pkgdata_MODULES): Add `acorn.mod'. + (acorn_mod_SOURCES): New variable. + (acorn_mod_CFLAGS): Likewise. + (acorn_mod_LDFLAGS): Likewise. + + * include/types.h (grub_disk_addr_t): New typedef. + +2005-11-13 Marco Gerards + + * geninit.sh: New file. + + * geninitheader.sh: Likewise. + + * commands/boot.c (grub_boot_init, grub_boot_fini): Removed. + * commands/cat.c (grub_cat_init, grub_cat_fini): Likewise. + * commands/cmp.c (grub_cmp_init, grub_cmp_fini): Likewise. + * commands/configfile.c (grub_configfile_init) + (grub_configfile_fini): Likewise. + * commands/default.c (grub_default_init, grub_default_fini): + Likewise. + * commands/help.c (grub_help_init, grub_help_fini): Likewise. + * commands/ls.c (grub_ls_init, grub_ls_fini): Likewise. + * commands/search.c (grub_search_init, grub_search_fini): Likewise. + * commands/terminal.c (grub_terminal_init, grub_terminal_fini): + Likewise. + * commands/test.c (grub_test_init, grub_test_fini): Likewise. + * commands/timeout.c (grub_timeout_init, grub_timeout_fini): + Likewise. + * commands/i386/pc/halt.c (grub_halt_init, grub_halt_fini): Likewise. + * commands/ieee1275/halt.c (grub_halt_init, grub_halt_fini): + Likewise. + * commands/i386/pc/reboot.c (grub_reboot_init, grub_reboot_fini): + Likewise. + * commands/ieee1275/reboot.c (grub_reboot_init, grub_reboot_fini): + Likewise. + * disk/loopback.c (grub_loop_init, grub_loop_fini): Likewise. + * fs/affs.c (grub_affs_init, grub_affs_fini): Likewise. + * fs/ext2.c (grub_ext2_init, grub_ext2_fini): Likewise. + * fs/fat.c (grub_fat_init, grub_fat_fini): Likewise. + * fs/hfs.c (grub_hfs_init, grub_hfs_fini): Likewise. + * fs/iso9660.c (grub_iso9660_init, grub_iso9660_fini): Likewise. + * fs/jfs.c (grub_jfs_init, grub_jfs_fini): Likewise. + * fs/minix.c (grub_minix_init, grub_minix_fini): Likewise. + * fs/sfs.c (grub_sfs_init, grub_sfs_fini): Likewise. + * fs/ufs.c (grub_ufs_init, grub_ufs_fini): Likewise. + * fs/xfs.c (grub_xfs_init, grub_xfs_fini): Likewise. + * normal/main.c (grub_normal_init, grub_normal_fini): Likewise. + * partmap/amiga.c (grub_amiga_partition_map_init) + (grub_amiga_partition_map_fini): Likewise. + * partmap/apple.c (grub_apple_partition_map_init) + (grub_apple_partition_map_fini): Likewise. + * partmap/pc.c (grub_pc_partition_map_init) + (grub_pc_partition_map_fini): Likewise. + * partmap/sun.c (grub_sun_partition_map_init, + grub_sun_partition_map_fini): Likewise. + * term/terminfo.c (grub_terminal_init, grub_terminal_fini): + Likewise. + + * util/grub-emu.c: Include . + (main): Don't initialize and de-initialize any modules directly, + use `grub_init_all' and `grub_fini_all' instead. + + * term/i386/pc/vesafb.c (grub_vesafb_init): Renamed to + `grub_vesafb_mod_init'. + (grub_vesafb_fini): Renamed to `grub_vesafb_mod_fini'. Updated + all users. + * term/i386/pc/vga.c (grub_vga_init): Renamed to + `grub_vga_mod_init'. Updated all users. + (grub_vga_fini): Renamed to `grub_vga_mod_fini'. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `grub_emu_init.c'. + (grub_modules_init.lst, grub_modules_init.h, grub_emu_init.c): New + rules. + + * include/grub/dl.h (GRUB_MOD_INIT): Add argument `name'. + Generate a function to initialize the module in utilities. + Updated all callers. + (GRUB_MOD_FINI): Add argument `name'. Generate a function to + initialize the module in utilities. Updated all callers. + +2005-11-09 Hollis Blanchard + + * term/ieee1275/ofconsole.c (grub_ofconsole_cls): Use both the ANSI + escape sequence and a literal ^L to clear the screen. + + * commands/ieee1275/suspend.c (grub_cmd_suspend): Clear the screen + when returning from Open Firmware. + +2005-11-09 Hollis Blanchard + + * term/ieee1275/ofconsole.c (grub_ofconsole_width): New variable. + (grub_ofconsole_height): Likewise. + (grub_ofconsole_putchar): If `grub_curr_x' exceeds console width, + manually insert a '\n'. + (grub_ofconsole_getwh): Set and return `grub_ofconsole_width' and + `grub_ofconsole_height'. Return early if these are already set. + +2005-11-07 Vincent Pelletier + + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Add + `commands/test.c', `fs/affs.c', `fs/sfs.c', `fs/xfs.c', + `normal/execute.c', `normal/lexer.c', `io/gzio.c', + `kern/parser.c', `grub_script.tab.c', `normal/function.c' + and `normal/script.c'. + (normal_mod_SOURCES): `normal/execute.c', `normal/lexer.c', + `grub_script.tab.c', `normal/function.c' and `normal/script.c'. + (test_mod_SOURCES): New variable. + (test_mod_CFLAGS): Likewise. + (test_mod_LDFLAGS): Likewise. + (pkgdata_MODULES): Add `test.mod'. + (grub_script.tab.c): New rule. + (grub_script.tab.h): Likewise. + +2005-11-07 Marco Gerards + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add + `commands/test.c', `normal/execute.c', `normal/lexer.c', + `grub_script.tab.c', `normal/function.c' and `normal/script.c'. + (normal_mod_SOURCES): `normal/execute.c', `normal/lexer.c', + `grub_script.tab.c', `normal/function.c' and `normal/script.c'. + (test_mod_SOURCES): New variable. + (test_mod_CFLAGS): Likewise. + (pkgdata_MODULES): Add `test.mod'. + (grub_script.tab.c): New rule. + (grub_script.tab.h): Likewise. + +2005-11-06 Marco Gerards + + Add initial scripting support. + + * commands/test.c: New file. + * include/grub/script.h: Likewise. + * normal/execute.c: Likewise. + * normal/function.c: Likewise. + * normal/lexer.c: Likewise. + * normal/parser.y: Likewise. + * normal/script.c: Likewise. + + * configure.ac: Add `AC_PROG_YACC' test. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `commands/test.c', + `normal/execute.c', `normal/lexer.c', `grub_script.tab.c', + `normal/function.c' and `normal/script.c'. + (normal_mod_SOURCES): `normal/execute.c', `normal/lexer.c', + `grub_script.tab.c', `normal/function.c' and `normal/script.c'. + (test_mod_SOURCES, test_mod_CFLAGS, test_mod_LDFLAGS): New + variables. + (pkgdata_MODULES): Add `test.mod'. + (grub_script.tab.c): New rule. + (grub_script.tab.h): Likewise. + + * include/grub/err.h (grub_err_t): Add `GRUB_ERR_TEST_FAILURE'. + + * include/grub/normal.h (grub_test_init): New prototype. + (grub_test_fini): Likewise. + + * normal/command.c: Include . + (grub_command_execute): Rewritten. + + * util/grub-emu.c (main): Call `grub_test_init' and + `grub_test_fini'. + +2005-11-03 Hollis Blanchard + + * kern/powerpc/ieee1275/init.c (grub_get_rtc): Initialize `msecs' + to 0. + * term/ieee1275/ofconsole.c (grub_ofconsole_checkkey): Return -1 if + there are no pending characters. + +2005-11-03 Hollis Blanchard + + * kern/powerpc/ieee1275/openfw.c (grub_ieee1275_get_devname): Use + `grub_strndup' to drop device arguments. Replace unnecessary + `grub_strndup' with `grub_strdup'. + +2005-11-03 Hollis Blanchard + + * kern/term.c (grub_cls): Do not call grub_cur_term->cls() if the + `debug' environment variable has been set. + +2005-11-02 Hollis Blanchard + + * Makefile.in (install-local): Use $(DATA). + (uninstall): Likewise. + * conf/powerpc-ieee1275.rmk (bin_UTILITIES): Move grub-mkimage... + (sbin_UTILITIES): ... to here. + (sbin_SCRIPTS): New variable. + (grub_install_SOURCES): New variable. + * util/powerpc/ieee1275/grub-install.in: New file. + * util/powerpc/ieee1275/grub-mkimage.c (kernel_path): Remove + variable. + (add_segments): Call `grub_util_get_path'. + +2005-10-28 Yoshinori K. Okuji + + From Timothy Baldwin: + * commands/ls.c (grub_ls_list_files): Close FILE with + grub_file_close. + * kern/misc.c (grub_vsprintf): Terminate the string S with NUL. + +2005-10-24 Marco Gerards + + * include/grub/parser.h: New file. + + * kern/parser.c: Likewise. + + * conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/parser.c'. + (grub_setup_SOURCES): Likewise. + (grub_probefs_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + (kernel_img_HEADERS): Add `parser.h'. + + * conf/powerpc-ieee1275.rmk (grubof_HEADERS): Add `parser.h'. + (grub_emu_SOURCES): Add `kern/parser.c'. + (grubof_SOURCES): Likewise. + + * conf/sparc64-ieee1275.rmk (grubof_HEADERS): Add `parser.h'. + (grubof_SOURCES): Add `kern/parser.c'. + + * include/grub/misc.h (grub_split_cmdline): Removed prototype. + + * kern/misc.c (grub_split_cmdline): Removed function. + + * kern/rescue.c: Include . + (grub_enter_rescue_mode): Use `grub_parser_split_cmdline' instead + of `grub_split_cmdline'. + + * normal/command.c: Include . + (grub_command_execute): Use `grub_parser_split_cmdline' instead + of `grub_split_cmdline'. + + * normal/completion.c: Include . + (cmdline_state): New variable. + (iterate_dir): End the filename with a quote depending on the + command line state. + (get_state): new function. + (grub_normal_do_completion): Use `grub_parser_split_cmdline' to + split the arguments and determine the current argument. When the + argument string is not quoted, escape all spaces. + +2005-10-23 Vincent Pelletier + + * normal/sparc64/setjmp.S: New file. + +2005-10-23 Vincent Pelletier + + * include/grub/sparc64/libgcc.h: New file. + * conf/sparc64-ieee1275.rmk (COMMON_ASFLAGS): Remove -Av9. + (normal_mod_SOURCES): Use normal/sparc64/setjmp.S instead of + normal/sparc64/setjmp.c. + +2005-10-23 Vincent Pelletier + + * kern/sparc64/dl.c: Rewritten for SPARCV9 ELF. + * kern/sparc64/cache.S: New file. + * kern/sparc64/cache.c: Removed. + * conf/sparc64-ieee1275.rmk (COMMON_ASFLAGS): Add -Av9. + (COMMON_CFLAGS): Add -mno-app-regs. Remove -mcpu=v9 and + -mtune=ultrasparc. + (COMMON_LDFLAGS): Add -melf64_sparc. + (grubof_HEADERS): Add sparc64/libgcc.h and machine/kernel.h. + (grubof_SOURCES): Use cache.S instead of cache.c. + (grubof_LDFLAGS): Add -mno-app-regs. Replace "-Xlinker + --oformat -Xlinker elf64-sparc" by "-Bstatic,-melf64_sparc". + (pkgdata_MODULES): Uncomment. Leave linux.mod and _linux.mod + commented though. + (normal_mod_SOURCES): Add normal/completion.c and normal/misc.c. + (_linux_mod_SOURCES, _linux_mod_CFLAGS, linux_mod_SOURCES) + (linux_mod_CFLAGS): Commented out. + (_linux_mod_LDFLAGS, linux_mod_LDFLAGS): New macro, commented + out because module isn't built. + (fshelp_mod_LDFLAGS, fat_mod_LDFLAGS, ext2_mod_LDFLAGS) + (ufs_mod_LDFLAGS, minix_mod_LDFLAGS, hfs_mod_LDFLAGS) + (jfs_mod_LDFLAGS, iso9660_mod_LDFLAGS, normal_mod_LDFLAGS) + (hello_mod_LDFLAGS, boot_mod_LDFLAGS, terminal_mod_LDFLAGS) + (ls_mod_LDFLAGS, cmp_mod_LDFLAGS, cat_mod_LDFLAGS) + (font_mod_LDFLAGS, amiga_mod_LDFLAGS, apple_mod_LDFLAGS) + (pc_mod_LDFLAGS, sun_mod_LDFLAGS, loopback_mod_LDFLAGS) + (suspend_mod_LDFLAGS, reboot_mod_LDFLAGS, halt_mod_LDFLAGS) + (help_mod_LDFLAGS, default_mod_LDFLAGS, timeout_mod_LDFLAGS) + (configfile_mod_LDFLAGS, search_mod_LDFLAGS, xfs_mod_SOURCES) + (xfs_mod_CFLAGS, xfs_mod_LDFLAGS, affs_mod_SOURCES) + (affs_mod_CFLAGS, affs_mod_LDFLAGS, sfs_mod_SOURCES) + (sfs_mod_CFLAGS, sfs_mod_LDFLAGS, gzio_mod_SOURCES) + (gzio_mod_CFLAGS, gzio_mod_LDFLAGS): New macro. + +2005-10-20 Yoshinori K. Okuji + + * util/i386/pc/grub-probefs.c (main): Call grub_xfs_init and + grub_xfs_fini. Do not call grub_hfs_init or grub_hfs_fini any + longer, because HFS should not be used on PC. + +2005-10-20 Timothy Baldwin + + * io/gzio.c (grub_gzio_read): Use OFFSET instead of FILE->OFFSET + consistently within the loop. + +2005-10-15 Marco Gerards + + * fs/xfs.c (grub_xfs_iterate_dir): Detect an error if part of a + directory can not be read. + +2005-10-15 Yoshinori K. Okuji + + * configure.ac (AC_INIT): Increase the version number to 1.91. + + * DISTLIST: Added include/grub/terminfo.h, include/grub/tparm.h, + include/grub/i386/pc/serial.h, term/terminfo.c, term/tparm.c and + term/i386/pc/serial.c. + +2005-10-15 Yoshinori K. Okuji + + * kern/file.c (grub_file_seek): Seeking to an offset equal to a + file size must be permitted. + + * kern/i386/pc/startup.S (multiboot_trampoline): Fix a mistake + between %ah and %al. + +2005-10-15 Yoshinori K. Okuji + + * fs/xfs.c (grub_xfs_iterate_dir): Change the type of BLK to + grub_uint64_t. + Call the hook with a NUL-terminated filename. + (grub_xfs_mount): Use grub_be_to_cpu32 instead of + grub_cpu_to_be32. + + * kern/term.c (cursor_state): New variable. + (grub_term_set_current): Reset the cursor state on a new + terminal. + (grub_setcursor): Rewritten to use CURSOR_STATE. + (grub_getcursor): New function. + + * include/grub/term.h (grub_getcursor): New prototype. + + * io/gzio.c (test_header): Align BUF for accessing it as 32-bit + integers on ARM. Reported by Timothy Baldwin + . + +2005-10-11 Marco Gerards + + * fs/sfs.c (grub_sfs_open): Don't free `data->label' if it is not + allocated. + (grub_sfs_dir): Likewise. + +2005-10-09 Marco Gerards + + Add support for the SFS filesystem. + + * fs/sfs.c: New file. + + * DISTLIST: Added `fs/sfs.c'. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add `fs/sfs.c'. + (grub_probefs_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add `sfs.mod'. + (sfs_mod_SOURCES): New variable. + (sfs_mod_CFLAGS): Likewise. + (sfs_mod_LDFLAGS): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add `fs/sfs.c'. + (pkgdata_MODULES): Add `sfs.mod'. + (sfs_mod_SOURCES): New variable. + (sfs_mod_CFLAGS): Likewise. + + * util/grub-emu.c (main): Call `grub_sfs_init' and + `grub_sfs_fini'. + + * include/grub/fs.h (grub_sfs_init): New prototype. + (grub_sfs_fini): Likewise. + +2005-10-07 Marco Gerards + + Add support for the AFFS filesystem. + + * fs/affs.c: New file. + + * DISTLIST: Added `fs/affs.c'. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add `fs/affs.c'. + (grub_probefs_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add `affs.mod'. + (affs_mod_SOURCES): New variable. + (affs_mod_CFLAGS): Likewise. + (affs_mod_LDFLAGS): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add `fs/affs.c'. + (pkgdata_MODULES): Add `affs.mod'. + (affs_mod_SOURCES): New variable. + (affs_mod_CFLAGS): Likewise. + + * util/grub-emu.c (main): Call `grub_affs_init' and + `grub_affs_fini'. + + * include/grub/fs.h (grub_affs_init): New prototype. + (grub_affs_fini): Likewise. + +2005-10-01 Marco Gerards + + * fs/xfs.c (grub_xfs_iterate_dir): Add parentheses. + +2005-10-01 Marco Gerards + + * configure.ac: Accept `x86_64' as host_cpu. In that case add + `-m32' to CFLAGS. + + * genmk.rb (class PModule): Always use `$(#{prefix}_LDFLAGS)' when + linking. + + * conf/i386-pc.rmk (COMMON_CFLAGS): Add `-m32'. + (COMMON_LDFLAGS): New variable. + (kernel_img_LDFLAGS): Include `COMMON_FLAGS'. + (_chain_mod_LDFLAGS, fshelp_mod_LDFLAGS, fat_mod_LDFLAGS) + (ext2_mod_LDFLAGS, ufs_mod_LDFLAGS, minix_mod_LDFLAGS) + (hfs_mod_LDFLAGS, jfs_mod_LDFLAGS, iso9660_mod_LDFLAGS) + (xfs_mod_LDFLAGS, _linux_mod_LDFLAGS, linux_mod_LDFLAGS) + (normal_mod_LDFLAGS, hello_mod_LDFLAGS, boot_mod_LDFLAGS) + (terminal_mod_LDFLAGS, ls_mod_LDFLAGS, cmp_mod_LDFLAGS) + (cat_mod_LDFLAGS, help_mod_LDFLAGS, reboot_mod_LDFLAGS) + (halt_mod_LDFLAGS, vga_mod_LDFLAGS, font_mod_LDFLAGS) + (terminfo_mod_LDFLAGS, serial_mod_LDFLAGS, _multiboot_mod_LDFLAGS) + (multiboot_mod_LDFLAGS, amiga_mod_LDFLAGS, apple_mod_LDFLAGS) + (pc_mod_LDFLAGS, sun_mod_LDFLAGS, loopback_mod_LDFLAGS) + (default_mod_LDFLAGS, timeout_mod_LDFLAGS, configfile_mod_LDFLAGS) + (vbe_mod_LDFLAGS, vesafb_mod_LDFLAGS, vbeinfo_mod_LDFLAGS) + (vbetest_mod_LDFLAGS, search_mod_LDFLAGS, gzio_mod_LDFLAGS): New + variables. + (normal_mod_ASFLAGS): Add `-m32'. + + * include/grub/types.h (grub_host_addr_t, grub_host_off_t) + (grub_host_size_t, grub_host_ssize_t): New types. + (grub_addr_t, grub_off_t, grub_size_t, grub_ssize_t): Make type + dependent of `GRUB_CPU_SIZEOF_VOID_P' instead on + `GRUB_HOST_SIZEOF_VOID_P'. + + * include/grub/kernel.h (struct grub_module_header): Type of + member offset changed to `grub_host_off_t'. Type of member size + changed to `grub_host_size_t'. + (struct grub_module_info): Type of member offset changed to + `grub_host_off_t'. Type of member size changed to + `grub_host_size_t'. + +2005-09-29 Yoshinori K. Okuji + + Make GRUB's kernel compliant to Multiboot Specification. + + * kern/i386/pc/startup.S (multiboot_header): New label. + (multiboot_entry): Likewise. + (multiboot_trampoline): Likewise. + + * include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE): + Increased to 0x4A0. + + * fs/xfs.c (grub_xfs_iterate_dir): Fix a syntax error. You may not + put parentheses after a question mark. + [!GRUB_UTIL] (my_mod): New variable. + + * util/grub-emu.c (main): Call grub_xfs_init and grub_xfs_fini. + +2005-09-28 Marco Gerards + + Adds support for the XFS filesystem. Btrees are not supported + yet. + + * fs/xfs.c: New file. + + * DISTLIST: Added `fs/xfs.c'. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add `fs/xfs.c'. + (grub_probefs_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add `xfs.mod'. + (xfs_mod_SOURCES): New variable. + (xfs_mod_CFLAGS): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add `fs/xfs.c'. + (pkgdata_MODULES): Add `xfs.mod'. + (xfs_mod_SOURCES): New variable. + (xfs_mod_CFLAGS): Likewise. + + * util/grub-emu.c (main): Call `grub_xfs_init' and + `grub_xfs_fini'. + + * include/grub/fs.h (grub_xfs_init): New prototype. + (grub_xfs_fini): Likewise. + + +2005-09-18 Vesa Jaaskelainen + + * video/i386/pc/vbe.c (grub_vbe_set_video_mode): In indexed + color modes, allow greater than 16 colors to be configured as + a default palette. + +2005-09-03 Yoshinori K. Okuji + + * normal/completion.c (complete_arguments): Add the qualifier + const into OPTIONS. + + From Omniflux : + * include/grub/terminfo.h: New file. + * include/grub/tparm.h: Likewise. + * include/grub/i386/pc/serial.h: Likewise. + * term/terminfo.c: Likewise. + * term/tparm.c: Likewise. + * term/i386/pc/serial.c: Likewise. + * conf/i386-pc.rmk (pkgdata_MODULES): Added terminfo.mod and + serial.mod. + (terminfo_mod_SOURCES): New variable. + (terminfo_mod_CFLAGS): Likewise. + (serial_mod_SOURCES): Likewise. + (serial_mod_CFLAGS): Likewise. + +2005-08-31 Yoshinori K. Okuji + + * DISTLIST: Replaced boot/powerpc/ieee1275/crt0.S and + boot/powerpc/ieee1275/cmain.c with kern/powerpc/ieee1275/crt0.S + and kern/powerpc/ieee1275/cmain.c, respectively. + + * boot/powerpc/ieee1275/crt0.S: Moved to ... + * kern/powerpc/ieee1275/crt0.S: ... here. + + * boot/powerpc/ieee1275/cmain.c: Moved to ... + * kern/powerpc/ieee1275/cmain.c: ... here. + + * conf/powerpc-ieee1275.rmk (grubof_SOURCES): Use + kern/powerpc/ieee1275/crt0.S and kern/powerpc/ieee1275/cmain.c + instead of boot/powerpc/ieee1275/crt0.S and + boot/powerpc/ieee1275/cmain.c, respectively. + + * boot/i386/pc/boot.S (lba_mode): Do not store the total number of + sectors. It was not used anyway. + +2005-08-30 Hollis Blanchard + + * term/ieee1275/ofconsole.c (grub_ofconsole_getcharwidth): Fix + `unused parameter' warning. + +2005-08-30 Hollis Blanchard + + * term/ieee1275/ofconsole.c (grub_ofconsole_getcharwidth): New + function. + (grub_ofconsole_term): Specify grub_ofconsole_getcharwidth as + getcharwidth. + +2005-08-28 Marco Gerards + + * include/grub/normal.h (enum grub_completion_type): Added + `GRUB_COMPLETION_TYPE_ARGUMENT'. + + * normal/cmdline.c (print_completion): Handle + the `GRUB_COMPLETION_TYPE_ARGUMENT' type. + * normal/menu_entry.c (store_completion): Likewise. + + * normal/completion.c (complete_arguments): New function. + (grub_normal_do_completion): Call `complete_arguments' when the + current words start with a dash. + +2005-08-27 Marco Gerards + + * conf/powerpc-ieee1275.rmk (pkgdata_MODULES): Fix typo (use + `gzio.mod' instead of `io.mod'). + +2005-08-22 Yoshinori K. Okuji + + * gendistlist.sh (EXTRA_DISTFILES): Added genfslist.sh. + (DISTDIRS): Added io and video. + Rewrite the search routine to make an output consistently. + + * DISTLIST: Added conf/sparc64-ieee1275.mk, + conf/sparc64-ieee1275.rmk, include/grub/gzio.h, + include/grub/ieee1275/ieee1275.h, include/grub/ieee1275/ofdisk.h, + io/gzio.c, kern/sparc64/cache.c, kern/sparc64/dl.c, + kern/sparc64/ieee1275/init.c, kern/sparc64/ieee1275/openfw.c and + util/powerpc/ieee1275/misc.c. + + * include/grub/gzio.h: New file. + * io/gzio.c: Likewise. + + * kern/file.c (grub_file_close): Call grub_device_close only if + FILE->DEVICE is not NULL. + + * include/grub/mm.h [!NULL] (NULL): New macro. + + * include/grub/err.h (GRUB_ERR_BAD_GZIP_DATA): New constant. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Added io/gzip.c. + (pkgdata_MODULES): Added gzio.mod. + (gzio_mod_SOURCES): New variable. + (gzio_mod_CFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Added io/gzip.c. + (pkgdata_MODULES): Added gzio.mod. + (gzio_mod_SOURCES): New variable. + (gzio_mod_CFLAGS): Likewise. + + * commands/cat.c: Include grub/gzio.h. + (grub_cmd_cat): Use grub_gzfile_open instead of + grub_file_open. + + * commands/cmp.c: Include grub/gzio.h. + (grub_cmd_cmp): Use grub_gzfile_open instead of + grub_file_open. + + * loader/i386/pc/multiboot.c: Include grub/gzio.h. + (grub_rescue_cmd_multiboot): Use grub_gzfile_open instead of + grub_file_open. + (grub_rescue_cmd_module): Likewise. + +2005-08-21 Vincent Pelletier + + * conf/sparc64-ieee1275.rmk (grubof_SOURCES): The first file must be + kern/sparc64/ieee1275/init.c because it contains _start. + * conf/sparc64-ieee1275.mk: Generated from conf/sparc64-ieee1275.rmk. + +2005-08-21 Vincent Pelletier + + * configure.ac: Add support for sparc64 host with ieee1275 + firmware. + * configure: Generated from configure.ac. + * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Use grub_ssize_t + instead of int. + (grub_ofdisk_read): Likewise. + (grub_ofdisk_open): Use %p to print pointer values, and cast the + pointers as (void *) to remove a warning. + (grub_ofdisk_close): Likewise. + (grub_ofdisk_read): Likewise. + * kern/ieee1275/ieee1275.c (grub_ieee1275_exit): This never + returns, so make it return void to remove a warning. + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_exit): + Corresponding prototype change. + * kern/mm.c (grub_mm_init_region): Use %p to print pointer + values, and cast the pointers as (void *) to remove a warning. + (grub_mm_dump): Likewise. + * conf/sparc64-ieee1275.mk: New file. + * conf/sparc64-ieee1275.rmk: Likewise. + * include/grub/sparc64/setjmp.h: Likewise. + * include/grub/sparc64/types.h: Likewise. + * include/grub/sparc64/ieee1275/console.h: Likewise. + * include/grub/sparc64/ieee1275/ieee1275.h: Likewise. + * include/grub/sparc64/ieee1275/kernel.h: Likewise. + * include/grub/sparc64/ieee1275/time.h: Likewise. + * kern/sparc64/cache.c: Likewise. + * kern/sparc64/dl.c: Likewise. + * kern/sparc64/ieee1275/init.c: Likewise. + * kern/sparc64/ieee1275/openfw.c: Likewise. + +2005-08-21 Yoshinori K. Okuji + + * util/console.c (grub_ncurses_putchar): If C is greater than + 0x7f, set C to a question mark. + (grub_ncurses_getcharwidth): New function. + (grub_ncurses_term): Specify grub_ncurses_getcharwidth as + getcharwidth. + + * normal/menu.c (print_entry): Made aware of Unicode. First, + convert TITLE to UCS-4, and predict the cursor position by + grub_getcharwidth. + + * include/grub/misc.h (grub_utf8_to_ucs4): Specify the qualifier + const to SRC. + * kern/misc.c (grub_utf16_to_utf8): Likewise. + +2005-08-20 Yoshinori K. Okuji + + * loader/powerpc/ieee1275/linux.c (grub_rescue_cmd_linux): Specify + the boot file by the option BOOT_IMAGE. Use grub_stpcpy instead of + grub_strcat. + + * loader/i386/pc/linux.c (grub_rescue_cmd_linux): Specify the boot + file by the option BOOT_IMAGE. Use grub_stpcpy instead of + grub_strcpy and grub_strlen. Take it into account that a space + character is inserted as a delimiter. + +2005-08-20 Yoshinori K. Okuji + + * partmap/pc.c (pc_partition_map_iterate): Include the value of an + invalid magic in the error. + + * commands/search.c: New file. + + * util/grub-emu.c (main): Call grub_search_init and + grub_search_fini. + + * kern/rescue.c (grub_rescue_print_disks): Removed. + (grub_rescue_print_devices): New function. + (grub_rescue_cmd_ls): Use grub_device_iterate with + grub_rescue_print_devices instead of grub_disk_dev_iterate with + grub_rescue_print_disks. + + * kern/partition.c (grub_partition_iterate): Return the result of + PARTMAP->ITERATE instead of GRUB_ERRNO. + + * kern/device.c: Include grub/partition.h. + (grub_device_iterate): New function. + + * include/grub/partition.h (grub_partition_iterate): Return int + instead of grub_err_t. + + * include/grub/normal.h [GRUB_UTIL] (grub_search_init): New + prototype. + [GRUB_UTIL] (grub_search_fini): Likewise. + + * include/grub/device.h (grub_device_iterate): New prototype. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Added + commands/search.c. + (pkgdata_MODULES): Added search.mod. + (search_mod_SOURCES): New variable. + (search_mod_CFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Added commands/search.c. + (pkgdata_MODULES): Added search.mod. + (search_mod_SOURCES): New variable. + (search_mod_CFLAGS): Likewise. + + * commands/ls.c (grub_ls_list_disks): Renamed to ... + (grub_ls_list_devices): ... this, and use grub_device_iterate. + All callers changed. + + * DISTLIST: Added commands/search.c. + +2005-08-20 Yoshinori K. Okuji + + * kern/term.c (grub_putchar): Use grub_utf8_to_ucs4 for the + conversion. + (grub_getcharwidth): New function. + + * kern/misc.c (grub_utf8_to_ucs4): New function. + + * include/grub/term.h (struct grub_term): Added a new member + "getcharwidth". + (grub_getcharwidth): New prototype. + + * include/grub/misc.h (grub_utf8_to_ucs4): New prototype. + + * term/i386/pc/console.c (map_char): New function. Segregated from + grub_console_putchar. + (grub_console_putchar): Use map_char. + (grub_console_getcharwidth): New function. + (grub_console_term): Specified grub_console_getcharwidth as + getcharwidth. + + * term/i386/pc/vga.c (grub_vga_getcharwidth): New function. + (grub_vga_term): Specified grub_vga_getcharwidth as getcharwidth. + + * term/i386/pc/vesafb.c (grub_virtual_screen_setup): Return + GRUB_ERRNO. + (grub_vesafb_init): Do not use RC. Instead, use GRUB_ERRNO. Rely + on grub_strtoul completely. + (write_char): Declare local variables in the beginning of the + function. + (grub_vesafb_getcharwidth): New function. + (grub_vesafb_term): Specified grub_vesafb_getcharwidth as + getcharwidth. + +2005-08-19 Yoshinori K. Okuji + + * DISTLIST: Replace commands/i386/pc/vbe_list_modes.c and + commands/i386/pc/vbe_test.c with commands/i386/pc/vbeinfo.c and + commands/i386/pc/vbetest.c. + + * video/i386/pc/vbe.c (grub_vbe_probe): If INFOBLOCK is not NULL, + call grub_vbe_get_controller_info again, because the returned + information is volatile. + (grub_vbe_set_video_mode): Mostly rewritten. + (grub_vbe_get_video_mode): Use grub_vbe_probe and use + grub_vbe_status_t correctly. + (grub_vbe_get_video_mode_info): Likewise. + (grub_vbe_set_pixel_rgb): Use a switch statement rather than + several if statements. + + * commands/i386/pc/vbe_list_modes.c: Renamed to ... + * commands/i386/pc/vbeinfo.c: ... this. + + * commands/i386/pc/vbe_test.c: Renamed to ... + * commands/i386/pc/vbetest.c: ... this. + + * commands/i386/pc/vbeinfo.c (grub_cmd_vbe_list_modes): Renamed to + ... + (grub_cmd_vbeinfo): ... this. Save video modes before + iterating. Skip a video mode, if it is not available, not enough + information is given or it is monochrome. Show the memory + model. Leave the interpretation of MODEVAR to grub_strtoul + completely. + (GRUB_MOD_INIT): Rename vbe_list_modes to vbeinfo. + (GRUB_MOD_FINI): Likewise. + + * commands/i386/pc/vbetest.c (grub_cmd_vbe_test): Renamed to ... + (grub_cmd_vbetest): ... this. Don't print unnecessarily. Use + grub_err_t instead of grub_uint32_t. Don't use SPTR. Remove a + duplicated grub_env_get. Leave the interpretation of MODEVAR to + grub_strtoul completely. + (real2pm): Removed. + (GRUB_MOD_INIT): Rename vbe_test to vbetest. + (GRUB_MOD_FINI): Likewise. + + * normal/misc.c: Include grub/mm.h. + + * conf/i386-pc.rmk (pkgdata_MODULES): Replaced vbe_test.mod and + vbe_list_modes with vbetest.mod and vbeinfo.mod. + (vbe_list_modes_mod_SOURCES): Removed. + (vbe_list_modes_mod_CFLAGS): Likewise. + (vbe_test_mod_SOURCES): Likewise. + (vbe_test_mod_CFLAGS): Likewise. + (vbeinfo_mod_SOURCES): New variable. + (vbeinfo_mod_CFLAGS): Likewise. + (vbetest_mod_SOURCES): Likewise. + (vbetest_mod_CFLAGS): Likewise. + +2005-08-18 Yoshinori K. Okuji + + * normal/misc.c: New file. + + * DISTLIST: Added normal/misc.c. + + * partmap/amiga.c (amiga_partition_map_iterate): Add an argument + DISK to HOOK. Call HOOK with DISK. + * partmap/apple.c (apple_partition_map_iterate): Likewise. + * partmap/pc.c (pc_partition_map_iterate): Likewise. + * partmap/sun.c (sun_partition_map_iterate): Likewise. + + * normal/menu_entry.c (struct screen): Added a new member + "completion_shown". + (completion_buffer): New global variable. + (make_screen): Set SCREEN->COMPLETION_SHOWN to zero. + (store_completion): New function. + (complete): Likewise. + (clear_completions): Likewise. + (grub_menu_entry_run): If SCREEN->COMPLETION_SHOWN is non-zero, + call clear_completions and reset SCREEN->COMPLETION_SHOWN. If C is + a tab, call complete. + + * normal/completion.c (disk_dev): Removed. + (print_simple_completion): Likewise. + (print_partition_completion): Likewise. + (print_func): New global variable. + (add_completion): Do not take the arguments WHAT or PRINT any + longer. Added a new argument TYPE. Instead of printing directly, + call PRINT_FUNC if not NULL. + All callers changed. + (complete_device): Use a local variable DEV instead of + DISK_DEV. Do not move CURRENT_WORD to the end of a device name. + (grub_normal_do_completion): Take a new argument HOOK. Do not + initialize DISK_DEV. Initialize PRINT_FUNC to HOOK. If RET is an + empty string, return NULL instead. + All callers changed. + + * normal/cmdline.c (print_completion): New function. + + * kern/partition.c (grub_partition_iterate): Add an argument DISK + to HOOK. + All callers changed. + + * kern/disk.c (grub_print_partinfo): Removed. + + * include/grub/partition.h (struct grub_partition_map): Add a new + argument DISK into HOOK of ITERATE. + (grub_partition_iterate): Add a new argument DISK to HOOK. + + * include/grub/normal.h (enum grub_completion_type): New enum. + (grub_completion_type_t): New type. + (GRUB_COMPLETION_TYPE_COMMAND): New constant. + (GRUB_COMPLETION_TYPE_DEVICE): Likewise. + (GRUB_COMPLETION_TYPE_PARTITION): Likewise. + (GRUB_COMPLETION_TYPE_FILE): Likewise. + (grub_normal_do_completion): Added a new argument HOOK. + (grub_normal_print_device_info): New prototype. + + * include/grub/disk.h (grub_print_partinfo): Removed. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Added normal/misc.c. + (normal_mod_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + + * commands/ls.c (grub_ls_list_disks): Use + grub_normal_print_device_info instead of grub_print_partinfo. Free + PNAME. + (grub_ls_list_files): Use grub_normal_print_device_info instead of + duplicating the code. + +2005-08-16 Vesa Jaaskelainen + + * commands/i386/pc/vbe_list_modes.c: Update source formatting to + follow GCS more precisely. + * commands/i386/pc/vbe_test.c: Likewise. + * include/grub/i386/pc/vbe.h: Likewise. + * term/i386/pc/vesafb.c: Likewise. + * video/i386/pc/vbe.c: Likewise. + +2005-08-16 Vesa Jaaskelainen + + * DISTLIST: Added term/i386/pc/vesafb.c + DISTLIST: Added video/i386/pc/vbe.c + DISTLIST: Added commands/i386/pc/vbe_list_modes.c. + DISTLIST: Added commands/i386/pc/vbe_test.c. + * commands/i386/pc/vbe_list_modes.c: New file. + * commands/i386/pc/vbe_test.c: Likewise. + * term/i386/pc/vesafb.c: Likewise. + * video/i386/pc/vbe.c: Likewise. + * include/grub/i386/pc/vbe.h (GRUB_VBE_DEFAULT_VIDEO_MODE): Added define. + (grub_vbe_probe) Added prototype. + (grub_vbe_set_video_mode) Likewise. + (grub_vbe_get_video_mode) Likewise. + (grub_vbe_get_video_mode_info) Likewise. + (grub_vbe_set_pixel_rgb) Likewise. + (grub_vbe_set_pixel_index) Likewise. + * conf/i386-pc.rmk (pkgdata_MODULES): Added vbe.mod. + (pkgdata_MODULES): Added vesafb.mod. + (pkgdata_MODULES): Added vbe_list_modes.mod. + (pkgdata_MODULES): Added vbe_test.mod. + (vbe_mod_SOURCES): Added. + (vbe_mod_CFLAGS): Likewise. + (vesafb_mod_SOURCES): Likewise. + (vesafb_mod_CFLAGS): Likewise. + (vbe_list_modes_mod_SOURCES): Likewise. + (vbe_list_modes_mod_CFLAGS): Likewise. + (vbe_test_mod_SOURCES): Likewise. + (vbe_test_mod_CFLAGS): Likewise. + +2005-08-14 Yoshinori K. Okuji + + * normal/command.c (grub_command_execute): If INTERACTIVE is + false and GRUB_COMMAND_FLAG_NO_ECHO is not specified, print + CMDLINE. Disable the pager if INTERACTIVE is true. + All callers are changed. + + * normal/main.c (grub_normal_execute): Read command.lst and fs.lst + before reading a config file. + * normal/main.c (read_config_file): Even if a command is not + found, register it if it is within an entry. + + * util/grub-emu.c: Include sys/types.h and unistd.h. + (options): Added --hold. + (struct arguments): Added a new member "hold". + (parse_opt): If KEY is 'H', set ARGS->HOLD to ARG or -1 if ARG is + missing. + (main): Initialize ARGS.HOLD to zero. Wait until ARGS.HOLD is + cleared by a debugger, if it is not zero. + + * include/grub/normal.h (grub_command_execute): Add an argument + INTERACTIVE. + +2005-08-14 Vesa Jaaskelainen + + * DISTLIST: Added include/grub/i386/pc/vbe.h. + +2005-08-13 Yoshinori K. Okuji + + * aclocal.m4 (grub_I386_CHECK_REGPARM_BUG): Replace the test + program with another one, because the old one didn't detect a bug + in gcc-3.4. Always use regparm 2, because the new test is still + not enough for gcc-4.0. Someone must investigate a simple test + case which detects a bug in gcc-4.0. + +2005-08-12 Yoshinori K. Okuji + + * DISTLIST: Added normal/completion.c. + + * normal/completion.c: New file. + + * term/i386/pc/console.c (grub_console_getwh): New function. + (grub_console_term): Assign grub_console_getwh to getwh. + + * normal/cmdline.c (grub_tab_complete): Removed. Now the same + function is defined in normal/completion.c as + grub_normal_do_completion. + (grub_cmdline_get): Use grub_normal_do_completion instead of + grub_tab_complete. + + * kern/partition.c (grub_partition_map_iterate): Return 1 if HOOK + returns non-zero, otherwise return 0. + (grub_partition_iterate): First, probe the partition map. Then, + call ITERATE only for this partition map. + + * kern/misc.c (grub_strncmp): Rewritten. + + * kern/disk.c (grub_disk_dev_iterate): Return 1 if P->ITERATE + returns non-zero. Otherwise return 0. + + * include/grub/partition.h (grub_partition_map_iterate): Return + int instead of void. + + * include/grub/normal.h (grub_normal_do_completion): New prototype. + + * include/grub/misc.h (grub_strncmp): Change the type of N to + grub_size_t. + + * include/grub/disk.h (grub_disk_dev_iterate): Return int instead + of void. + + * normal/menu.c (draw_border): Cast GRUB_TERM_BORDER_WIDTH to + unsigned explicitly before comparing it with I. + + * kern/main.c (grub_env_write_root): Add the attribute unused into + VAR. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Added + normal/completion.c. + (normal_mod_SOURCES): Likewise. + * conf/i386-pc.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + + * normal/command.c (grub_iterate_commands): If ITERATE returns + non-zero, return one immediately. + +2005-08-09 Vesa Jaaskelainen + + * conf/i386-pc.rmk (kernel_img_HEADERS): Added machine/vbe.h. + * kern/i386/pc/startup.S: Updated Global Descriptor table's + descriptions. + (grub_vbe_get_controller_info): New function. + (grub_vbe_get_mode_info): Likewise. + (grub_vbe_set_mode): Likewise. + (grub_vbe_get_mode): Likewise. + (grub_vbe_set_memory_window): Likewise. + (grub_vbe_get_memory_window): Likewise. + (grub_vbe_set_scanline_length): Likewise. + (grub_vbe_get_scanline_length): Likewise. + (grub_vbe_set_display_start): Likewise. + (grub_vbe_get_display_start): Likewise. + (grub_vbe_set_palette_data): Likewise. + * include/grub/i386/pc/vbe.h: New file. + +2005-08-08 Hollis Blanchard + + * conf/powerpc-ieee1275.rmk (grubof_SOURCES): Replaced + kern/ieee1275/of.c with kern/ieee1275/ieee1275.c. + * DISTLIST: Likewise. + * kern/ieee1275/of.c: Moved to ... + * kern/ieee1275/ieee1275.c: ... here. + +2005-08-08 Hollis Blanchard + + * term/ieee1275/ofconsole.c: Include . + (grub_ofconsole_getwh): Cast -1 to type grub_ieee1275_ihandle_t. + Pass 0 as `end' parameter to grub_strtoul(). + +2005-08-08 Hollis Blanchard + + * include/grub/powerpc/ieee1275/console.h: Do not include + . Do not include . Remove ASM_FILE + ifdef. + (grub_console_cur_color): Remove i386-specific prototype. + (grub_console_real_putchar): Likewise. + (grub_console_checkkey): Likewise. + (grub_console_getkey): Likewise. + (grub_console_getxy): Likewise. + (grub_console_gotoxy): Likewise. + (grub_console_cls): Likewise. + (grub_console_setcursor): Likewise. + * kern/powerpc/ieee1275/init.c: Don't include . + Include . + * term/ieee1275/ofconsole.c: Likewise. + +2005-08-08 Yoshinori K. Okuji + + * Makefile.in (LIBLZO): New variable. + + * configure.ac: Check for LZO version 2. + + * util/i386/pc/grub-mkimage.c [HAVE_LZO_LZO1X_H]: Include + lzo/lzo1x.h instead of lzo1x.h. + + * conf/i386-pc.rmk (grub_mkimage_LDFLAGS): Use $(LIBLZO) instead + of -llzo. + + * util/i386/pc/grub-setup.c (main): Do not free PREFIX + twice. Reported by Vladimir Serbinenko . + + * partmap/pc.c (pc_partition_map_probe): Restore P->DATA after + copying the data from PARTITION to P. + +2005-08-07 Yoshinori K. Okuji + + * kern/rescue.c (grub_rescue_cmd_rmmod): If the reference count is + negative, unload the module. + + * util/i386/pc/grub-setup.c (setup): The name of the PC partition + map is "pc_partition_map" but not "pc". + (usage): Fix the description. The options are --boot-image and + --core-image but not --boot-file or --core-file. + (main): If not specified explicitly, make BOOT_FILE and CORE_FILE + based on DEFAULT_BOOT_FILE and DEFAULT_CORE_FILE with DIR or + DEFAULT_DIRECTORY. + + * util/i386/pc/grub-install.in: Do not specify --boot-file or + --core-file. Specify INSTALL_DEVICE as an argument. + + * util/console.c: Include config.h. + [HAVE_NCURSeS_CURSES_H]: Include ncurses/curses.h. + [HAVE_NCURSES_H]: Include ncurses.h. + [HAVE_CURSES_H]: Include curses.h. + [!A_NORMAL] (A_NORMAL): Defined as zero. + [!A_STANDOUT] (A_STANDOUT): Likewise. + + * conf/i386-pc.rmk (grub_emu_LDFLAGS): Use $(LIBCURSES) instead of + -lncurses. + * conf/powerpc-ieee1275.rmk (grub_emu_LDFLAGS): Likewise. + + * configure.ac: Check for curses libraries and headers. + + * Makefile.in (LIBCURSES): New variable. + + * genmk.rb (Script::rule): Set the executable bits. + + * util/i386/pc/biosdisk.c (grub_util_biosdisk_get_grub_dev): The + name of the PC partition map is "pc_partition_map" but not "pc". + +2005-08-07 Yoshinori K. Okuji + + * util/i386/pc/grub-install.in (grub_probefs): New variable. + (modules): Likewise. + (usage): Added descriptions for --modules and --grub-probefs. + Handle --modules and --grub-probefs. Save the arguments in MODULES + and GRUB_PROBEFS, respectively. + Auto-detect a filesystem module against GRUBDIR. If the result is + empty and modules are not specified explicitly, abort the + installation. Add the result to MODULES. + + * DISTLIST: Removed boot/powerpc/ieee1275/ieee1275.c, + disk/powerpc/ieee1275/ofdisk.c, + include/grub/powerpc/ieee1275/init.h and + term/powerpc/ieee1275/ofconsole.c. + Added disk/ieee1275/ofdisk.c, kern/ieee1275/of.c and + term/ieee1275/ofconsole.c. + + * include/grub/powerpc/ieee1275/console.h: Resurrected. + + * COPYING: Upgraded to the latest version. Only the address of the + FSF office has changed. + +2005-08-07 Yoshinori K. Okuji + + * conf/powerpc-ieee1275.rmk (grubof_SOURCES): Replaced + kern/ieee1275.c with kern/ieee1275/of.c. + + * kern/ieee1275.c: Moved to ... + * kern/ieee1275/of.c: ... here. + +2005-08-06 Yoshinori K. Okuji + + * conf/i386-pc.rmk (kernel_img_HEADERS): Reordered for + readability. + + * config.guess: Updated to the latest version from gnulib. + * config.sub: Likewise. + * install.sh: Likewise. + * mkinstalldirs: Likewise. + + * include/grub/console.h: Removed. This file is arch-specific. Do + not put this in include/grub. + + * include/grub/i386/pc/console.h: Resurrected. + + * util/console.c: Include grub/machine/console.h instead of + grub/console.h. + * util/grub-emu.c: Likewise. + +2005-08-04 Marco Gerards + + * kern/term.c (grub_putcode): Use `grub_getwh' instead of + hardcoded value. + + From Vincent Pelletier + * include/grub/term.h (GRUB_TERM_WIDTH, GRUB_TERM_HEIGHT): + Redefined to use grub_getwh. + (grub_term): New member named getwh. + (grub_getwh): New prototype. + * kern/term.c (grub_getwh): New function. + * term/i386/pc/console.c (grub_console_getwh): New function. + (grub_console_term): New member `getwh'. + * term/i386/pc/vga.c (grub_vga_getwh): New function. + (grub_vga_term): New member `getwh'. + * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Use + grub_ssize_t. + (grub_ofconsole_getw): New function. + (grub_ofconsole_init): Use grub_ssize_t and unsigned char. + (grub_ofconsole_term): New field named getwh and new initial + value. + +2005-08-03 Hollis Blanchard + + * include/grub/powerpc/ieee1275/ieee1275.h: Move ... + * include/grub/ieee1275/ieee1275.h: ... to here. All users updated. + Move `abort', `grub_reboot', and `grub_halt' prototypes ... + * include/grub/powerpc/ieee1275/kernel.h: ... to here. + * commands/ieee1275/halt.c: Include instead + of . + * commands/ieee1275/reboot.c: Likewise. + * boot/powerpc/ieee1275/ieee1275.c: Move ... + * kern/ieee1275.c: ... to here. All users updated. Change all + parameter structs to use new type `grub_ieee1275_cell_t'. + * term/powerpc/ieee1275/ofconsole.c: Move ... + * term/ieee1275/ofconsole.c: ... to here. All users updated. + * disk/powerpc/ieee1275/ofdisk.c: Move ... + * disk/ieee1275/ofdisk.c: ... to here. All users updated. + * boot/powerpc/ieee1275/cmain.c: Change `grub_ieee1275_entry_fn' type + to return int. + * include/grub/i386/pc/console.h: Move to include/grub/console.h. + Remove unused prototypes. All users updated. + * include/grub/powerpc/ieee1275/console.h: Removed. + * include/grub/powerpc/ieee1275/ieee1275.h: Define + `grub_ieee1275_cell_t'. + * kern/powerpc/ieee1275/openfw.c: Include . + Cast comparisons with -1 to the correct type. + * loader/powerpc/ieee1275/linux.c (kernel_entry_t): Change parameter + type to match `grub_ieee1275_entry_fn'. + +2005-08-01 Yoshinori K. Okuji + + * DISTLIST: Added util/i386/pc/grub-probefs.c. + + * conf/i386-pc.rmk (sbin_UTILITIES): Added grub-probefs. + (grub_setup_SOURCES): Removed partmap/amiga.c, partmap/apple.c and + partmap/sun.c. + (grub_probefs_SOURCES): New variable. + + * util/i386/pc/grub-probefs.c: New file. + + * util/i386/pc/grub-setup.c (main): Call + grub_pc_partition_map_init, grub_ufs_init, grub_minix_init, + grub_hfs_init and grub_jfs_init to initialize the system. Call + grub_ufs_fini, grub_minix_fini, grub_hfs_fini, grub_jfs_init and + grub_pc_partition_map_fini to finish the system. + +2005-07-31 Yoshinori K. Okuji + + * loader/i386/pc/multiboot.c (grub_multiboot_is_elf32): New + function. + (grub_multiboot_load_elf32): Likewise. + (grub_multiboot_is_elf64): Likewise. + (grub_multiboot_load_elf64): Likewise. + (grub_multiboot_load_elf): Likewise. + (grub_rescue_cmd_multiboot): Call grub_multiboot_load_elf to load + an ELF32 or ELF64 file. + This is based on a patch from Ruslan Nikolaev . + + From Serbinenko Vladimir : + * kern/disk.c (grub_print_partinfo): Check if FS->LABEL is not + NULL before calling FS->LABEL. + * fs/fat.c (grub_fat_dir): Initialize DIRNAME to NULL. + * commands/ls.c (grub_ls_list_files): Show labels, if possible. + (grub_ls_list_disks): Check if FS and FS->LABEL are not NULL + before calling FS->LABEL. + +2005-07-26 Yoshinori K. Okuji + + * util/i386/pc/grub-install.in (datadir): New variable. + (libdir): Removed. + (pkgdatadir): New variable. + (pkglibdir): Removed. + +2005-07-24 Yoshinori K. Okuji + + * DISTLIST: Added util/i386/pc/grub-install.in. + + * util/i386/pc/grub-install.in: New file. + + * conf/i386-pc.rmk (sbin_SCRIPTS): New variable. + (grub_install_SOURCES): Likewise. + + * genmk.rb: Added support for scripts. + (Script): New class. + (scripts): New variable. + + * Makefile.in (install-local): Install sbin_SCRIPTS by + INSTALL_SCRIPT. + (uninstall): Remove sbin_SCRIPTS. + + * util/i386/pc/grub-setup.c (main): If the argument is not a GRUB + device, try to get a GRUB device by + grub_util_biosdisk_get_grub_dev. + Free DEST_DEV. + + * util/i386/pc/grub-mkdevicemap.c (usage): Remove a duplicated + description for --device-map. + +2005-07-20 Yoshinori K. Okuji + + Change the semantics of variable hooks. They now return strings + instead of error values. + + * util/i386/pc/grub-setup.c: Include grub/env.h. + (setup): Use grub_device_set_root instead of grub_env_set. + + * kern/rescue.c (grub_rescue_cmd_root): Use grub_env_set and + grub_env_get instead of grub_device_set_root and + grub_device_get_root, respectively. + + * kern/main.c (grub_env_write_root): New function. + (grub_set_root_dev): Register grub_env_write_hook for "root". Use + grub_env_set instead of grub_device_set_root. + + * kern/env.c (HASHSZ): Reduced to 13, because GRUB does not need + many variables. + (grub_env_set): Set ENV->VALUE to the result of ENV->WRITE_HOOK + rather than calling ENV->WRITE_HOOK afterwards. + (grub_env_get): Return the result of ENV->READ_HOOK rather than + passing a pointer of a pointer. + (grub_register_variable_hook): Change the types of "read_hook" and + "write_hook" to grub_env_read_hook_t and grub_env_write_hook_t, + respectively. + Allocate the default empty string on the heap, because this string + may be freed later. + + * kern/device.c: Include grub/env.h. + (grub_device_set_root): Removed. + (grub_device_get_root): Likewise. + (grub_device_open): Use grub_env_get instead of + grub_device_get_root. + + * include/grub/env.h (grub_env_read_hook_t): New type. + (grub_env_write_hook_t): Likewise. + (grub_env_var): Change the types of "read_hook" and "write_hook" + to grub_env_read_hook_t and grub_env_write_hook_t, respectively. + (grub_register_variable_hook): Likewise. + + * include/grub/device.h (grub_device_set_root): Removed. + (grub_device_set_root): Likewise. + + * fs/fat.c (grub_fat_dir): Make a copy of PATH in DIRNAME, and + make sure that DIRNAME terminates with '/', so that + grub_fat_find_dir will fail if PATH is not a directory. + + * commands/ls.c (grub_ls_list_files): Remove the qualifier const + from DIRNAME. + Use the qualifier auto for print_files and print_files_long. + If FS->DIR sets GRUB_ERRNO to GRUB_ERR_BAD_FILE_TYPE, try DIRNAME + as a regular file. + Put a newline only if there is no error. + (grub_cmd_ls): Remove grub_ls_print_files, because this is not + used. + +2005-07-20 Yoshinori K. Okuji + + * kern/partition.c (grub_partition_probe): Initialize PART to + NULL. Otherwise, when no partition map is registered, this returns + a garbage. + +2005-07-19 Yoshinori K. Okuji + + * partmap/apple.c (apple_partition_map_iterate): Check if POS + equals GRUB_DISK_SECTOR_SIZE to see if the partition table is + valid. + +2005-07-18 Yoshinori K. Okuji + + * commands/ls.c (grub_ls_list_disks): Print the filesystem + information on each device, if it does not have partitions. Print + "Device" instead of "Disk", because this function is not specific + to disk devices. + + * normal/main.c (grub_rescue_cmd_normal): Make the variable CONFIG + static to ensure that it is put on the memory rather than a + register. + +2005-07-17 Yoshinori Okuji + + * commands/cat.c (GRUB_MOD_INIT): Use better documentation. + (grub_cat_init): Likewise. + * loader/i386/pc/chainloader_normal.c (GRUB_MOD_INIT): Likewise. + (options): Likewise. + * commands/configfile.c (GRUB_MOD_INIT): Likewise. + (grub_configfile_init): Likewise. + * font/manager.c (GRUB_MOD_INIT): Likewise. + * commands/help.c (GRUB_MOD_INIT): Likewise. + (grub_help_init): Likewise. + * normal/command.c (grub_command_init): Likewise. + * loader/i386/pc/linux_normal.c (GRUB_MOD_INIT): Likewise. + * disk/loopback.c (grub_loop_init): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/ls.c (grub_ls_init): Likewise. + (GRUB_MOD_INIT): Likewise. + (options): Likewise. + * commands/boot.c (grub_boot_init): Likewise. + (GRUB_MOD_INIT): Likewise. + * loader/i386/pc/multiboot_normal.c (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/reboot.c (grub_reboot_init): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/cmp.c (grub_cmp_init): Likewise. + (GRUB_MOD_INIT): Likewise. + + * normal/arg.c: Use <> instead of "" to include header files. + (SHORT_ARG_HELP): New macro. + (SHORT_ARG_USAGE): Likewise. + (help_options): Specify SHORT_ARG_HELP and SHORT_ARG_USAGE instead + of 'h' and 'u' for help and usage, respectively. Use more GNU-like + descriptions. + (find_short): Check if C is 'h' or 'u' explicitly. + (grub_arg_show_help): Use space characters instead of tabs. Treat + SHORT_ARG_HELP and SHORT_ARG_USAGE exceptionally so that -h and -u + are shown with --help and --usage only if they are not used for + the command itself. + (parse_option): Use SHORT_ARG_HELP and SHORT_ARG_USAGE instead of + 'h' and 'u'. + + * include/grub/arg.h (struct grub_arg_option): Add the qualifier + const into "longarg". Change the type of "shortarg" to int. + +2005-07-17 Yoshinori Okuji + + * boot/i386/pc/boot.S (boot_drive_check): New label. + + * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_DRIVE_CHECK): New + macro. + + * util/i386/pc/grub-setup.c (setup): Added a workaround for BIOSes + which do not pass a boot drive correctly. Copied from GRUB Legacy. + +2005-07-17 Yoshinori Okuji + + * kern/i386/pc/startup.S (gate_a20_try_system_control_port_a): + When turning off Gate A20, skip the check and return immediately, + because this is not fatal usually. + +2005-07-17 Yoshinori Okuji + + * conf/i386-pc.rmk (pxeboot_img_LDFLAGS): The text address should + be 0x7C00 instead of 0x8000. + + * boot/i386/pc/pxeboot.S: Rewritten. + + * kern/i386/pc/startup.S (gate_a20_try_bios): No need to specify + EXT_C. + (gate_a20_check_state): Read a byte from 0x108000. Invert the + result. + +2005-07-16 Yoshinori K. Okuji + + * kern/i386/pc/startup.S (grub_gate_a20): Rewritten for + robustness. This routine now supports a BIOS call and System + Control Port A to modify the gate A20. + + * include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE): + Increased to 0x440. + +2005-07-12 Hollis Blanchard + + * disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_open): dprintf the + device path and resulting ihandle. + (grub_ofdisk_close): dprintf the ihandle being closed. + (grub_ofdisk_read): dprintf function parameters. + * kern/mm.c (grub_mm_init_region): Likewise. + * loader/powerpc/ieee1275/linux.c: Remove extra whitespace. + (grub_linux_boot): dprintf the Linux entry point, initrd address and + size, and boot arguments. + (grub_rescue_cmd_linux): dprintf each ELF segment's address and size + before loading into memory. + (grub_rescue_cmd_initrd): dprintf the initrd's address and size + before loading into memory. + +2005-07-12 Yoshinori K. Okuji + + * kern/mm.c: Added much documentation. + (GRUB_MM_ALIGN_LOG2): When GRUB_CPU_SIZEOF_VOID_P is + 8, set to 5 instead of 8. + +2005-07-10 Yoshinori Okuji + + * DISTLIST: Added util/i386/pc/grub-mkimage.c. + + * conf/i386-pc.rmk (sbin_UTILITIES): Added grub-mkdevicemap. + (grub_mkdevicemap_SOURCES): New variable. + + * util/i386/pc/grub-mkdevicemap.c: New file. Mostly copied from + lib/device.c of GRUB Legacy. + +2005-07-10 Yoshinori Okuji + + * commands/ls.c (grub_ls_list_files): Check if *PATH is NUL + instead of PATH is NULL. + +2005-07-09 Vincent Pelletier + + * commands/cmp.c (BUFFER_SIZE): New macro. + (grub_cmd_cmp): Close the right file at the right time. Compare + only data just read. Don't report files of different size as + identical. Dynamically allocate buffers. Move variable + declarations at the beginning of function. + +2005-07-09 Yoshinori Okuji + + * aclocal.m4 (grub_I386_CHECK_REGPARM_BUG): The return value was + reverse. + +2004-07-04 Vincent Pelletier + + * normal/cmdline.c (grub_cmdline_get): Don't fallback on ctrl-d + when backspace is pressed at beginning of line. + +2005-07-03 Yoshinori Okuji + + * DISTLIST: Added genfslist.sh. + + * normal/main.c (fs_module_list): New variable. + (autoload_fs_module): New function. + (read_fs_list): Likewise. + (grub_normal_execute): Call read_fs_list. + + * kern/fs.c (grub_fs_autoload_hook): New variable. + (grub_fs_probe): Added support for auto-loading. + + * include/grub/normal.h (struct grub_fs_module_list): New struct. + (grub_fs_module_list_t): New type. + + * include/grub/fs.h (grub_fs_autoload_hook_t): New type. + (grub_fs_autoload_hook): New prototype. + + * genfslist.sh: New file. + + * genmk.rb: Added a rule to generate a filesystem list. + +2005-06-30 Marco Gerards + + * configure.ac: Fix the test for cross-compiling. + + * genmk.rb (Program): Use `$(CC)' instead of `$(BUILD_CC)'. Don't + define GRUB_UTIL anymore. + + * util/powerpc/ieee1275/grub-mkimage.c (load_note): Endian fixes + so this function works on other systems than just big endian. + (load_modules): Likewise. + (add_segments): Likewise. + +2005-06-23 Hollis Blanchard + + * kern/misc.c (grub_vsprintf): Add `longfmt'. If format string + contains `l' modifier, get a long from va_arg(). + +2005-06-23 Yoshinori K. Okuji + + * kern/mm.c (grub_free): If the next free block which is being + merged is the first free block, set the first block to the block + being freed. + Reported by Vincent Guffens . + +2005-05-08 Hollis Blanchard + + * boot/powerpc/ieee1275/cmain.c (cmain): Initialize + `grub_ieee1275_chosen'. + +2005-05-08 Hollis Blanchard + + * boot/powerpc/ieee1275/cmain.c (module_info): Remove definition. + (grub_ieee1275_chosen): New variable. + (cmain): Initialize and use `grub_ieee1275_chosen' instead of + `chosen'. + * boot/powerpc/ieee1275/crt0.S (init_stack): Remove stack space. + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_get_property): + Rename first argument to `phandle' for consistency. + (grub_ieee1275_get_property_length): Likewise. + (grub_ieee1275_next_property): Likewise. Change type of first argument + to grub_ieee1275_phandle_t. + * include/grub/powerpc/ieee1275/ieee1275.h (grub_ieee1275_entry_fn): + Move export next to declaration. + (grub_ieee1275_chosen): New variable. + * include/grub/powerpc/ieee1275/kernel.h (GRUB_IEEE1275_MODULE_BASE): + Correct cosmetic typo. + * kern/powerpc/ieee1275/init.c (grub_set_prefix): Use + `grub_ieee1275_chosen'. + * kern/powerpc/ieee1275/openfw.c (grub_map): Likewise. + * loader/powerpc/ieee1275/linux.c (grub_linux_boot): Likewise. + (grub_rescue_cmd_linux): Set `initrd_addr' to 0. + * term/powerpc/ieee1275/ofconsole.c (grub_ofconsole_refresh): Use + `grub_ieee1275_chosen'. + +2005-05-10 Hollis Blanchard + + * boot/powerpc/ieee1275/cmain.c (cmain): Remove code to parse + /chosen/bootargs. + * kern/powerpc/ieee1275/init.c (grub_machine_init): Parse + /chosen/bootargs as "variable=value" pairs. + +2005-05-08 Vincent Pelletier + + * include/grub/misc.h (grub_dprintf): New macro. + (grub_real_dprintf): New prototype. + (grub_strword): Likewise. + (grub_iswordseparator): Likewise. + * kern/misc.c (grub_real_dprintf): New function. + (grub_strword): Likewise. + (grub_iswordseparator): Likewise. + +2005-04-30 Hollis Blanchard + + * boot/powerpc/ieee1275/cmain.c: Don't include grub/machine/init.h. + (roundup): Remove macro. + (grub_ieee1275_flags): Make static. + (grub_ieee1275_realmode): Remove. + (grub_ieee1275_test_flag): New function. + (grub_ieee1275_set_flag): Likewise. + (find_options): Rename to `grub_ieee1275_find_options'; update + callers. Set GRUB_IEEE1275_FLAG_REAL_MODE and + GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS. + (cmain): New prototype. + (cmain): Use `grub_ieee1275_set_flag' instead of accessing + `grub_ieee1275_flags' directly. + * conf/powerpc-ieee1275.rmk (grubof_HEADERS): Remove + machine/biosdisk.h. + * disk/powerpc/ieee1275/ofdisk.c: Include grub/machine/ofdisk.h. + Don't include grub/machine/init.h. + (grub_ofdisk_open): Call `grub_ieee1275_test_flag'. + * include/grub/powerpc/ieee1275/ieee1275.h (grub_ieee1275_flags): + Remove prototype. + (grub_ieee1275_realmode): Likewise. + (grub_ieee1275_flag): New enum. + (grub_ieee1275_test_flag): New prototype. + (grub_ieee1275_set_flag): New prototype. + * include/grub/powerpc/ieee1275/init.h: Remove file. + * include/grub/powerpc/ieee1275/ofdisk.h: New file. + * kern/powerpc/ieee1275/init.c: Don't include grub/machine/init.h. + Include grub/machine/console.h. Include grub/machine/ofdisk.h. + (grub_machine_fini): Don't call `grub_ieee1275_release'. Remove + comment. + * kern/powerpc/ieee1275/openfw.c (grub_claimmap): Call + `grub_ieee1275_test_flag'. + (grub_ieee1275_encode_devname): Likewise. + +2005-04-21 Hollis Blanchard + + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_ieee1275_encode_devname): New prototype. + (grub_ieee1275_get_filename): Likewise. + * kern/powerpc/ieee1275/init.c (grub_translate_ieee175_path): New + function. + (grub_set_prefix): Likewise. + (grub_machine_init): Call grub_set_prefix. + * kern/powerpc/ieee1275/openfw.c: Fix typos. + (grub_parse_type): New enum. + (grub_ieee1275_get_devargs): New function. + (grub_ieee1275_get_devname): Likewise. + (grub_ieee1275_parse_args): Likewise. + (grub_ieee1275_get_filename): Likewise. + (grub_ieee1275_encode_devname): Likewise. + +2005-03-30 Marco Gerards + + * kern/powerpc/ieee1275/init.c (grub_machine_fini): Don't call + `grub_loader_unset'. + +2005-03-26 Hollis Blanchard + + * commands/ieee1275/halt.c (grub_cmd_halt): Call grub_halt + instead of grub_ieee1275_interpret. + (grub_halt_init): New function. + (grub_halt_fini): Likewise. + (GRUB_MOD_INIT): Correct message grammar. + * commands/ieee1275/reboot.c (grub_cmd_reboot): Call grub_reboot + instead of grub_ieee1275_interpret. + (grub_reboot_init): New function. + (grub_reboot_fini): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Replace + commands/i386/pc/halt.c, commands/i386/pc/reboot.c, and + util/i386/pc/misc.c with commands/ieee1275/halt.c, + commands/ieee1275/reboot.c, and util/powerpc/ieee1275/misc.c. + * disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_fini): New + function. + * include/grub/powerpc/ieee1275/console.h (grub_console_fini): + Add prototype. + * include/grub/powerpc/ieee1275/ieee1275.h (grub_reboot): Add + prototype. + (grub_halt): Likewise. + * include/grub/powerpc/ieee1275/init.h: Remove inaccurate comment. + (cmain): Remove __attribute__((unused)). + * kern/powerpc/ieee1275/init.c (grub_heap_start): New variable. + (grub_heap_len): Likewise. + (grub_machine_fini): New function. + * kern/powerpc/ieee1275/openfw.c (grub_reboot): New function. + (grub_halt): Likewise. + * term/powerpc/ieee1275/ofconsole.c (grub_console_fini): New + function. + * util/powerpc/ieee1275/misc.c: New file. + +2005-03-19 Yoshinori K. Okuji + + * DISTLIST: New file. + * gendistlist.sh: Likewise. + + * Makefile.in (COMMON_DISTFILES): Removed. + (BOOT_DISTFILES): Likewise. + (CONF_DISTFILES): Likewise. + (DISK_DISTFILES): Likewise. + (FS_DISTFILES): Likewise. + (INCLUDE_DISTFILES): Likewise. + (KERN_DISTFILES): Likewise. + (LOADER_DISTFILES): Likewise. + (TERM_DISTFILES): Likewise. + (UTIL_DISTFILES): Likewise. + (DISTFILES): Likewise. + (uninstall): Uninstall files in $(pkgdata_DATA). + (DISTLIST): New target. + (distdir): Use the contents of the file DISTLIST to get a list of + distributed files. + +2005-03-18 Yoshinori K. Okuji + + * fs/fat.c (grub_fat_mount): Ignore the 3rd bit of a media + descriptor. This is ported from GRUB Legacy. + + * gencmdlist.sh: Added an extra semicolon to make it work with + old sed versions. Reported by Robert Bihlmeyer + . + +2005-03-08 Yoshinori Okuji + + Automatic loading of commands is supported. + + * normal/main.c (read_command_list): New function. + (grub_normal_execute): Call read_command_list. + + * normal/command.c (grub_register_command): Return zero or CMD. + Allocate CMD->NAME from the heap. + Initialize CMD->MODULE_NAME to zero. + Find the same name as well. If the same command is found and it is + a dummy command, overwrite members. If it is not a dummy command, + return zero. + (grub_unregister_command): Free Q->NAME and Q->MODULE_NAME. + (grub_command_find): If a dummy command is found, load a module + and retry to find a command only once. + + * normal/cmdline.c (grub_tab_complete): Call grub_command_find to + make sure that each command is loaded. + + * include/grub/normal.h (GRUB_COMMAND_FLAG_NOT_LOADED): New + macro. + (struct grub_command): Remove const from the member `name'. + Add a new member `module_name'. + (grub_register_command): Return grub_command_t. + + * commands/help.c (grub_cmd_help): Call grub_command_find to make + sure that each command is loaded. + + * genmk.rb (PModule::rule): Specify a module name without the + suffix ".mod" to gencmdlist.sh. + +2005-03-02 Yoshinori K. Okuji + + * gencmdlist.sh: New file. + + * genmk.rb (PModule::rule): Generate a rule for a command list. + Clean command.lst. + Generate command.lst from $(COMMANDFILES). + + * Makefile.in (COMMON_DISTFILES): Added gencmdlist.sh. + (DATA): Added $(pkgdata_DATA). + (install-local): Install files in $(pkgdata_DATA). + +2005-03-02 Yoshinori K. Okuji + + * term/i386/pc/vga.c (debug_command): Removed. + (GRUB_MOD_INIT): Do not register the command "debug". + + From Hollis Blanchard: + * commands/configfile.c: New file. + * conf/i386-pc.rmk (grub_emu_SOURCES): Added + commands/configfile.c. + (pkgdata_MODULES): Added configfile.mod. + (configfile_mod_SOURCES): New variable. + (configfile_mod_CFLAGS): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Added + commands/configfile.c. + (pkgdata_MODULES): Added configfile.mod. + (configfile_mod_SOURCES): New variable. + (configfile_mod_CFLAGS): Likewise. + * util/grub-emu.c (main): Call grub_configfile_init and + grub_configfile_fini. + * include/grub/normal.h [GRUB_UTIL] (grub_configfile_init): New + prototype. + [GRUB_UTIL] (grub_configfile_fini): Likewise. + +2005-02-27 Yoshinori K. Okuji + + * normal/arg.c (grub_arg_show_help): Do not show the bug report + address. + + * commands/help.c (grub_cmd_help): Do not print newlines after + the last command in print_command_help. + +2005-02-27 Yoshinori K. Okuji + + * commands/default.h: New file. + * commands/timeout.h: Likewise. + * normal/context.c: Likewise. + + * util/misc.c: Do not include sys/times.h. + Include sys/time.h and grub/machine/time.h. + (grub_get_rtc): Rewritten with gettimeofday. + + * util/grub-emu.c (main): Call grub_default_init and + grub_timeout_init before grub_normal_init, and call + grub_timeout_fini and grub_default_fini after grub_main. + + * util/console.c (grub_ncurses_checkkey): Return the read + character or -1. + + * normal/menu.c (run_menu): Set MENU->TIMEOUT to -1 once it + timeouts. + + * normal/main.c (read_config_file): Push MENU. If this fails, + print an error and wait for a user input. + Print an error only if GRUB_ERRNO is not GRUB_ERR_NONE. + If a menu is empty or an error occurs, pop MENU. + (grub_normal_execute): Pop and free MENU after grub_menu_run + returns. + + * kern/loader.c (grub_loader_boot): Call grub_machine_fini. + + * include/grub/powerpc/ieee1275/time.h [GRUB_UTIL]: Do not + include time.h. + [GRUB_UTIL] (GRUB_TICKS_PER_SECOND): Use the same definition as + without GRUB_UTIL. + * include/grub/i386/pc/time.h [GRUB_UTIL]: Do not include + time.h. + [GRUB_UTIL] (GRUB_TICKS_PER_SECOND): Use the same definition as + without GRUB_UTIL. + + * include/grub/normal.h (struct grub_menu_list): New struct. + (grub_menu_list_t): New type. + (struct grub_context): New struct. + (grub_context_t): New type. + (grub_register_command): Got rid of EXPORT_FUNC. + (grub_unregister_command): Likewise. + (grub_context_get): New prototype. + (grub_context_get_current_menu): Likewise. + (grub_context_push_menu): Likewise. + (grub_context_pop_menu): Likewise. + [GRUB_UTIL] (grub_default_init): Likewise. + [GRUB_UTIL] (grub_default_fini): Likewise. + [GRUB_UTIL] (grub_timeout_init): Likewise. + [GRUB_UTIL] (grub_timeout_fini): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Added commands/default.c, + commands/timeout.c and normal/context.c. + (pkgdata_MODULES): Added default.mod and timeout.mod. + (normal_mod_SOURCES): Added normal/context.c. + (default_mod_SOURCES): New variable. + (default_mod_CFLAGS): Likewise. + (timeout_mod_SOURCES): Likewise. + (timeout_mod_CFLAGS): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Copied from + conf/i386-pc.rmk. + (pkgdata_MODULES): Added default.mod and timeout.mod. + (normal_mod_SOURCES): Added normal/context.c. + (default_mod_SOURCES): New variable. + (default_mod_CFLAGS): Likewise. + (timeout_mod_SOURCES): Likewise. + (timeout_mod_CFLAGS): Likewise. + + * Makefile.in (all-local): Added $(MKFILES). + +2005-02-21 Vincent Pelletier + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add `partmap/sun.c'. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add `sun.mod'. + (sun_mod_SOURCES, sun_mod_CFLAGS): New variables. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add + `partmap/sun.c'. + (pkgdata_MODULES): Add `sun.mod'. + (sun_mod_SOURCES, sun_mod_CFLAGS): New variables. + * include/grub/partition.h (grub_sun_partition_map_init): New + prototype. + (grub_sun_partition_map_fini): Likewise. + * partmap/sun.c: New file. + * util/grub-emu.c (main): Initialize and de-initialize the sun + partitionmap support. + +2005-02-19 Yoshinori K. Okuji + + This implements an Emacs-like menu entry editor. + + * normal/menu_entry.c: New file. + + * util/console.c (grub_ncurses_putchar): Translate some Unicode + characters to ASCII. + (saved_char): New variable. + (grub_ncurses_checkkey): Rewritten completely. + (grub_ncurses_getkey): Likewise. + (grub_ncurses_init): Call raw instead of cbreak. + + * normal/menu.c (print_entry): Do not put a space. + (init_page): Renamed to ... + (grub_menu_init_page): ... this. All callers changed. + (edit_menu_entry): Removed. + (run_menu): Call grub_menu_entry_run instead of edit_menu_entry. + + * normal/cmdline.c (grub_cmdline_run): Call grub_setcursor. + + * kern/misc.c (grub_vprintf): Call grub_refresh. + + * normal/menu.c (DISP_LEFT): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_LEFT): ... this. + * normal/menu.c (DISP_UP): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_UP): ... this. + * normal/menu.c (DISP_RIGHT): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_RIGHT): ... this. + * normal/menu.c (DISP_DOWN): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_DOWN): ... this. + * normal/menu.c (DISP_HLINE): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_HLINE): ... this. + * normal/menu.c (DISP_VLINE): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_VLINE): ... this. + * normal/menu.c (DISP_UL): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_UL): ... this. + * normal/menu.c (DISP_UR): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_UR): ... this. + * normal/menu.c (DISP_LL): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_LL): ... this. + * normal/menu.c (DISP_LR): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_LR): ... this. + * normal/menu.c (TERM_WIDTH): Renamed to ... + * include/grub/term.h (GRUB_TERM_WIDTH): ... this. + * normal/menu.c (TERM_HEIGHT): Renamed to ... + * include/grub/term.h (GRUB_TERM_HEIGHT): ... this. + * normal/menu.c (TERM_INFO_HEIGHT): Renamed to ... + * include/grub/term.h (GRUB_TERM_INFO_HEIGHT): ... this. + * normal/menu.c (TERM_MARGIN): Renamed to ... + * include/grub/term.h (GRUB_TERM_MARGIN): ... this. + * normal/menu.c (TERM_SCROLL_WIDTH): Renamed to ... + * include/grub/term.h (GRUB_TERM_SCROLL_WIDTH): ... this. + * normal/menu.c (TERM_TOP_BORDER_Y): Renamed to ... + * include/grub/term.h (GRUB_TERM_TOP_BORDER_Y): ... this. + * normal/menu.c (TERM_LEFT_BORDER_X): Renamed to ... + * include/grub/term.h (GRUB_TERM_LEFT_BORDER_X): ... this. + * normal/menu.c (TERM_BORDER_WIDTH): Renamed to ... + * include/grub/term.h (GRUB_TERM_BORDER_WIDTH): ... this. + * normal/menu.c (TERM_MESSAGE_HEIGHT): Renamed to ... + * include/grub/term.h (GRUB_TERM_MESSAGE_HEIGHT): ... this. + * normal/menu.c (TERM_BORDER_HEIGHT): Renamed to ... + * include/grub/term.h (GRUB_TERM_BORDER_HEIGHT): ... this. + * normal/menu.c (TERM_NUM_ENTRIES): Renamed to ... + * include/grub/term.h (GRUB_TERM_NUM_ENTRIES): ... this. + * normal/menu.c (TERM_FIRST_ENTRY_Y): Renamed to ... + * include/grub/term.h (GRUB_TERM_FIRST_ENTRY_Y): ... this. + * normal/menu.c (TERM_ENTRY_WIDTH): Renamed to ... + * include/grub/term.h (GRUB_TERM_ENTRY_WIDTH): ... this. + * normal/menu.c (TERM_CURSOR_X): Renamed to ... + * include/grub/term.h (GRUB_TERM_CURSOR_X): ... this. + All callers changed. + + * include/grub/normal.h: New prototype. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Added + normal/menu_entry.c. + (normal_mod_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + +2005-02-15 Yoshinori K. Okuji + + * include/grub/normal.h (grub_halt_init): New prototype. + (grub_halt_fini): Likewise. + (grub_reboot_init): Likewise. + (grub_reboot_fini): Likewise. + + * util/grub-emu.c: Include signal.h. + (main_env): New global variable. + (grub_machine_init): Ignore SIGINT. Otherwise grub-emu cannot + catch C-c. + (grub_machine_fini): New function. + (main): Call grub_halt_init and grub_reboot_init before + grub_main, and grub_reboot_fini and grub_halt_fini after it. + Call setjmp with MAIN_ENV to go back afterwards. + Call grub_machine_fini right before return. + + * include/grub/util/misc.h: Include setjmp.h. + (main_env): New prototype. + + * include/grub/kernel.h (grub_machine_fini): New prototype. + * include/grub/i386/pc/biosdisk.h (grub_biosdisk_fini): Likewise. + * include/grub/i386/pc/console.h (grub_console_fini): Likewise. + + * disk/i386/pc/biosdisk.c (grub_biosdisk_fini): New function. + * kern/i386/pc/init.c (grub_machine_fini): Likewise. + * term/i386/pc/console.c (grub_console_fini): Likewise. + + * util/i386/pc/misc.c: New file. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Added + util/i386/pc/misc.c, commands/i386/pc/halt.c and + commands/i386/pc/reboot.c. + +2005-02-14 Guillem Jover + + * include/grub/dl.h (grub_dl_check_header): New prototype. + (grub_arch_dl_check_header): Change return type to grub_err_t, + remove size parameter and export function. Update all callers. + * kern/dl.c (grub_dl_check_header): New function. + (grub_dl_load_core): Use `grub_dl_check_header' instead of + `grub_arch_dl_check_header'. Check ELF type. Check if sections + are inside the core. + * kern/i386/dl.c (grub_arch_dl_check_header): Remove arch + independent ELF header checks. + * kern/powerpc/dl.c (grub_arch_dl_check_header): Likewise. + * loader/i386/pc/multiboot.c (grub_rescue_cmd_multiboot): Use + `grub_dl_check_header' instead of explicit checks. Check for the + ELF type. + * loader/powerpc/ieee1275/linux.c (grub_rescue_cmd_linux): Use + `grub_dl_check_header' instead of explicit checks. Remove arch + specific ELF header checks. + + * util/grub-emu.c (grub_arch_dl_check_header): Remove the + argument SIZE. + +2005-02-13 Hollis Blanchard + + * conf/powerpc-ieee1275.rmk (pkgdata_MODULES): Add ls.mod. + * include/grub/powerpc/libgcc.h (__mulsf3): New prototype. + +2005-02-12 Hollis Blanchard + + * kern/partition.c (grub_partition_probe): Clear `grub_errno' and + return 0 if `grub_errno' is GRUB_ERR_BAD_PART_TABLE. + (part_map_iterate): Clear `grub_errno' and return 0 if + `partmap->iterate' returns GRUB_ERR_BAD_PART_TABLE. + * partmap/amiga.c (amiga_partition_map_iterate): Return + GRUB_ERR_BAD_PART_TABLE if no partition map magic is found. + * partmap/apple.c (apple_partition_map_iterate): Likewise. + +2005-02-01 Guillem Jover + + * loader/i386/pc/multiboot_normal.c (GRUB_MOD_INIT): Fix module + help info. + +2005-01-31 Marco Gerards + + * include/grub/powerpc/ieee1275/loader.h (grub_load_linux): + Removed prototype. + (grub_rescue_cmd_linux): New prototype. + (grub_rescue_cmd_initrd): Likewise. + * powerpc/ieee1275/linux.c (grub_linux_boot): Remove struct + `bi_rec'. + (grub_linux_release_mem): Release the memory for the initrd. + (grub_load_linux): Renamed from this... + (grub_rescue_cmd_linux): ...To this. Changed all callers. + Changed `entry' not to be static. Loop over memory regions to + find another one when the default fails. + (grub_rescue_cmd_initrd): New function. + (grub_linux_init): Remove function. + (grub_linux_fini): Likewise. + (GRUB_MOD_INIT): Register `initrd'. + (GRUB_MOD_FINI): Unregister `initrd'. + * powerpc/ieee1275/linux_normal.c (grub_linux_normal_init): + Function removed. + (grub_linux_normal_fini): Likewise. + (GRUB_MOD_INIT): Register `initrd'. + (GRUB_MOD_FINI): Unregister `initrd'. + +2005-01-31 Marco Gerards + + * commands/help.c: New file. + * normal/arg.c (show_help): Renamed to... + (grub_arg_show_help): ... this. + * commands/i386/pc/halt.c: New file. + * commands/i386/pc/reboot.c: Likewise. + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `commands/help.c'. + (pkgdata_MODULES): Add `reboot.mod', `halt.mod' and `help.mod'. + (help_mod_SOURCES, help_mod_CFLAGS, reboot_mod_SOURCES) + (reboot_mod_CFLAGS, halt_mod_SOURCES, halt_mod_CFLAGS): New + variables. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add + `commands/help.c'. + (pkgdata_MODULES): Add `help.mod'. + (help_mod_SOURCES, help_mod_CFLAGS): New variables. + * grub/i386/pc/init.h (grub_reboot): New prototype. + (grub_halt): Likewise. + * include/grub/normal.h (grub_arg_show_help): New prototype. + (grub_help_init): Likewise. + (grub_help_fini): Likewise. + * util/grub-emu.c (main): Initialize and deinitialize the help + command. + + * normal/cmdline.c (grub_cmdline_get): Doc fix. + + * normal/command.c (grub_command_init): Fixed the description of + the `set' and `unset' commands. + +2005-01-31 Marco Gerards + + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_interpret): New + function. + * commands/ieee1275/halt.c: New file. + * commands/ieee1275/reboot.c: Likewise. + * commands/ieee1275/suspend.c (grub_cmd_suspend): Use + `__attribute__ ((unused))'. Some GCS related fixed. + (grub_suspend_init) [GRUB_UTIL]: Function removed. + (grub_suspend_fini): Likewise. + * conf/powerpc-ieee1275.rmk (pkgdata_MODULES): Add `reboot.mod' + and `halt.mod'. + (reboot_mod_SOURCES, reboot_mod_CFLAGS, halt_mod_SOURCES) + (halt_mod_CFLAGS): New variables. + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_ieee1275_interpret): New prototype. + +2005-01-29 Yoshinori K. Okuji + + * include/grub/misc.h (memmove): New prototype. + (memcpy): Likewise. + +2005-01-22 Hollis Blanchard + + * disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_open): Don't initialize + `devpath' to 0. Use `name' instead of `devpath' with `grub_strndup'. + +2005-01-22 Marco Gerards + + * kern/misc.c (grub_strndup): Function rewritten. + +2005-01-22 Vincent Pelletier + + * normal/menu.c (TERM_WIDTH): Macro redefined. + (TERM_TOP_BORDER_Y): Likewise. + (draw_border): Replaced while-loop by a for-loop. Make the number + of lines consistent with the number of lines displayed in + print_entries. Added a margin below the rectangle. + (print_entry): Make the entry fit in the rectangle. + (print_entries): Display the scroll arrows next to the right + border. + +2005-01-21 Marco Gerards + + * fs/minix.c (grub_minix_find_file): Reserve more space for + `fpath' so the \0 can be stored. Use `grub_strcpy' instead of + `grub_strncpy' to copy `path' into it. + +2005-01-21 Marco Gerards + + Add the loopback device, a device via which files can be accessed + as devices. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `disk/loopback.c'. + (pkgdata_MODULES): Add loopback.mod. + (loopback_mod_SOURCES): New variable. + (loopback_mod_CFLAGS): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add + `disk/loopback.c'. + (pkgdata_MODULES): Add loopback.mod. + (loopback_mod_SOURCES): New variable. + (loopback_mod_CFLAGS): Likewise. + * disk/loopback.c: new file. + * include/grub/normal.h (grub_loop_init): New prototype. + (grub_loop_fini): New prototype. + * util/grub-emu.c (main): Initialize and de-initialize loopback + support. + * include/grub/disk.h (grub_disk_dev_id): Add + `GRUB_DISK_DEVICE_LOOPBACK_ID'. + +2005-01-20 Hollis Blanchard + + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_enter): New + function. + * conf/powerpc-ieee1275.rmk (pkgdata_MODULES): Add suspend.mod. + (suspend_mod_SOURCES): New variable. + (suspend_mod_CFLAGS): Likewise. + * include/grub/powerpc/ieee1275/ieee1275.h (grub_ieee1275_enter): + New prototype. + * commands/ieee1275/suspend.c: New file. + +2005-01-20 Timothy Baldwin + + * include/grub/dl.h (GRUB_MOD_INIT): Changed `__attribute__ + ((unused))' to `__attribute__ ((used))'. + (GRUB_MOD_FINI): Likewise. + * kern/dl.c (grub_dl_load_file): Fix null pointer dereference. + * genmk.rb (PModule): Assign space to common symbols when linking + modules. + +2005-01-20 Marco Gerards + + * include/grub/mm.h (grub_mm_init_region): Change the type of the + `unsigned' arguments to `grub_size_t'. + (grub_malloc): Likewise. + (grub_realloc): Likewise. + (grub_memalign): Likewise. + * kern/i386/dl.c (grub_arch_dl_check_header): Likewise. + * kern/powerpc/dl.c (grub_arch_dl_check_header): Likewise. + * util/misc.c (grub_malloc): Likewise. + (grub_realloc): Likewise. + * kern/mm.c (get_header_from_pointer): Change the casts to + `unsigned' into a cast to `grub_size_t'. + + * fs/fshelp.c (grub_fshelp_find_file): The `oldnode' should always + point to `currnode' when `currnode' is changed. + + * util/grub-emu.c (main): Initialize `progname'. Reported by Nico + Schottelius . + +2005-01-09 Hollis Blanchard + + * util/powerpc/ieee1275/grub-mkimage.c: Include . + (note_path): Remove variable. + (GRUB_IEEE1275_NOTE_NAME): New macro. + (GRUB_IEEE1275_NOTE_TYPE): Likewise. + (grub_ieee1275_note_hdr): New structure. + (grub_ieee1275_note_desc): Likewise. + (grub_ieee1275_note): Likewise. + (load_note): Remove `dir' argument. All callers updated. Remove + `note_img' and `path'. Do not load a file from `note_path'. + Initialize a struct grub_ieee1275_note and write that to `out'. + Use GRUB_IEEE1275_MODULE_BASE instead of MODULE_BASE. + +2005-01-05 Marco Gerards + + * util/misc.c (grub_util_read_image): Revert last change. It + called `grub_util_read_at', which seeks from the beginning of the + file. + +2005-01-04 Hollis Blanchard + + * TODO: Add note about endianness in grub-mkimage. + * boot/powerpc/ieee1275/crt0.S (note): Remove unused .note + section. + * conf/powerpc-ieee1275.rmk (bin_UTILITIES): Add grub-mkimage. + (grub_mkimage_SOURCES): New target. + * include/grub/kernel.h (grub_start_addr): Remove variable. + (grub_end_addr): Likewise. + (grub_total_module_size): Likewise. + (grub_kernel_image_size): Likewise. + (GRUB_MODULE_MAGIC): New constant. + (grub_module_info): New structure. + (grub_arch_modules_addr): New prototype. + (grub_get_end_addr): Remove prototype. + * include/grub/i386/pc/kernel.h (grub_end_addr): New prototype. + * include/grub/powerpc/ieee1275/kernel.h: New file. + * include/grub/util/misc.h (grub_util_get_fp_size): New + prototype. + (grub_util_read_at): Likewise. + (grub_util_write_image_at): Likewise. + * kern/main.c (grub_get_end_addr): Remove function. + (grub_load_modules): Call grub_arch_modules_addr instead of using + grub_end_addr. Look for a grub_module_info struct in memory. Use + the grub_module_info fields instead of calling grub_get_end_addr + as loop conditions. Move grub_add_unused_region code here. + (grub_add_unused_region): Remove function. + * kern/i386/pc/init.c: Include grub/cache.h. + (grub_machine_init): Remove call to grub_get_end_addr. Remove + one call to add_mem_region. + (grub_arch_modules_addr): New function. + * kern/powerpc/ieee1275/init.c (grub_end_addr): Remove variable. + (grub_total_module_size): Likewise. + Include grub/machine/kernel.h. + (grub_arch_modules_addr): New function. + * util/grub-emu.c (grub_end_addr): Remove variable. + (grub_total_module_size): Likewise. + (grub_arch_modules_addr): New function. + * util/misc.c: Include unistd.h. + (grub_util_get_fp_size): New function. + (grub_util_read_at): Likewise. + (grub_util_write_image_at): Likewise. + (grub_util_read_image): Call grub_util_read_at. + (grub_util_write_image): Call grub_util_write_image_at. + * util/i386/pc/grub-mkimage.c (generate_image): Allocate + additional memory in kernel_img for a struct grub_module_info. + Fill in that grub_module_info. + * util/powerpc/ieee1275/grub-mkimage.c: New file. + +2005-01-03 Hollis Blanchard + + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_milliseconds): + New function. + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_ieee1275_milliseconds): New prototype. + * include/grub/powerpc/ieee1275/time.h (GRUB_TICKS_PER_SECOND): + Change to 1000. + * kern/powerpc/ieee1275/init.c (grub_get_rtc): Call + grub_ieee1275_milliseconds. + +2005-01-03 Hollis Blanchard + + * boot/powerpc/ieee1275/cmain.c (grub_ieee1275_realmode): New + variable. + (find_options): New function. + (cmain): Call find_options. + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_ieee1275_realmode): New extern variable. + * kern/powerpc/ieee1275/openfw.c (grub_claimmap): Only call + grub_map if grub_ieee1275_realmode is false. + +2004-12-29 Marco Gerards + + * normal/cmdline.c (grub_cmdline_get): Redone logic so no empty + lines are inserted and make it work like readline. Reported by + Vincent Pelletier . + +2004-12-28 Marco Gerards + + * boot/powerpc/ieee1275/crt0.S (_start): Don't set up the stack. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCE): Remove + `kern/powerpc/cache.S'. + +2004-12-27 Marco Gerards + + * genmk.rb: Handle the `Program' class in the main loop. Written + by Johan Rydberg . + (Program): New class. + (programs): New variable. + * boot/powerpc/ieee1275/cmain.c: Include + instead of "grub/machine/ieee1275.h". Include + instead of "grub/kernel.h". Include . + (help_arch): Function removed. + * conf/powerpc-ieee1275.rmk (grubof_HEADERS): Add + `powerpc/libgcc.h' and `loader.h'. + (pkgdata_PROGRAMS): New variable. + (sbin_UTILITIES): Variable removed. + (grub_emu_SOURCES): Added kern/powerpc/cache.S. + (grubof_SOURCES): Variable re-defined so it only includes the + core functionality. + (grubof_CFLAGS): Remove `-DGRUBOF'. + (pkgdata_MODULES, fshelp_mod_SOURCES, fshelp_mod_CFLAGS, + (fat_mod_SOURCES, fat_mod_CFLAGS, ext2_mod_SOURCES) + (ext2_mod_CFLAGS, ufs_mod_SOURCES, ufs_mod_CFLAGS) + (minix_mod_SOURCES, minix_mod_CFLAGS, hfs_mod_SOURCES) + (hfs_mod_CFLAGS, jfs_mod_SOURCES, jfs_mod_CFLAGS) + (iso9660_mod_SOURCES, iso9660_mod_CFLAGS, _linux_mod_SOURCES) + (_linux_mod_CFLAGS, linux_mod_SOURCES, linux_mod_CFLAGS) + (normal_mod_SOURCES, normal_mod_CFLAGS, normal_mod_ASFLAGS) + (hello_mod_SOURCES, hello_mod_CFLAGS, boot_mod_SOURCES) + (boot_mod_CFLAGS, terminal_mod_SOURCES, terminal_mod_CFLAGS) + (ls_mod_SOURCES, ls_mod_CFLAGS, cmp_mod_SOURCES, cmp_mod_CFLAGS) + (cat_mod_SOURCES, cat_mod_CFLAGS, font_mod_SOURCES) + (font_mod_CFLAGS, amiga_mod_SOURCES, amiga_mod_CFLAGS) + (apple_mod_SOURCES, apple_mod_CFLAGS, pc_mod_SOURCES) + (pc_mod_CFLAGS): New variables. + * disk/powerpc/ieee1275/ofdisk.c: Include . + (grub_ofdisk_iterate): Add a prototype for `dev_iterate'. + * include/grub/dl.h (grub_arch_dl_sync_caches): New prototype. + * include/grub/loader.h (grub_os_area_addr, grub_os_area_size): + Moved from here... + * include/grub/i386/pc/init.h (grub_os_area_addr) + (rub_os_area_size): ... to here. + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_ieee1275_entry_fn): Export symbol. + * include/grub/powerpc/ieee1275/init.h: New file. + * include/grub/powerpc/libgcc.h: Likewise. + * include/grub/cache.h: Likewise. + * kern/powerpc/cache.S: Likewise. Written by Hollis Blanchard + . + * kern/dl.c: Include . + (grub_dl_flush_cache): New function. + (grub_dl_load_core): Call `grub_dl_flush_cache' to flush the cache + for this module. + * kern/powerpc/ieee1275/init.c (grub_ofdisk_init) + (grub_console_init): Removed prototypes. + (grub_machine_init): Don't initialize the modules anymore. + * kern/powerpc/ieee1275/openfw.c (grub_map): Make the function + static. + * include/grub/powerpc/types.h (GRUB_HOST_WORDS_LITTLEENDIAN): + Macro undef removed. + (GRUB_HOST_WORDS_BIGENDIAN): New macro. + * kern/powerpc/dl.c (grub_arch_dl_relocate_symbols): Add + relocation `R_PPC_REL32'. Return an error when the relocation is + unknown. + * Makefile.in (DATA): Add `$(pkgdata_PROGRAMS)'. + * kern/i386/pc/init.c (grub_arch_sync_caches): New function. + * util/misc.c (grub_arch_sync_caches): Likewise. + +2004-12-19 Marco Gerards + + * conf/powerpc-ieee1275.rmk (MOSTLYCLEANFILES): Remove + `symlist.c', add `grubof_symlist.c'. + (symlist.c): Variable removed. + (grubof_HEADERS): Variable added. + (grubof_symlist.c): New target. + (kernel_syms.lst): Use `grubof_HEADERS' instead of + `kernel_img_HEADERS'. + (grubof_SOURCES): Add `kern/powerpc/dl.c' and `grubof_symlist.c'. + * kern/powerpc/dl.c: New file. + * kern/powerpc/ieee1275/init.c (grub_arch_dl_check_header): + Function removed. + (grub_arch_dl_relocate_symbols): Likewise. + (grub_register_exported_symbols): Likewise. + +2004-12-13 Marco Gerards + + * fs/ext2.c (grub_ext2_open): Don't use data after freeing it. + (grub_ext2_dir): Likewise. Don't return in case of an error, jump + to fail instead. Reported by Vincent Pelletier + . + + * fs/fshelp.c (grub_fshelp_find_file): Don't free `oldnode' when + it is not allocated. Reported by Vincent Pelletier + . + + * normal/cmdline.c (grub_tab_complete): Add a blank line to the + output so the output looks better. + +2004-12-04 Marco Gerards + + Modulize the partition map support and add support for the amiga + partition map. + + * commands/ls.c: Include instead of + . + * kern/disk.c: Likewise. + * kern/rescue.c: Likewise. + * loader/i386/pc/chainloader.c: Likewise. + * normal/cmdline.c: Likewise. + * kern/powerpc/ieee1275/init.c: Likewise. + (grub_machine_init): Call `grub_pc_partition_map_init', + `grub_amiga_partition_map_init' and + `grub_apple_partition_map_init'. + * conf/i386-pc.rmk (kernel_img_SOURCES): Remove + `disk/i386/pc/partition.c'. Add `kern/partition.c'. + (kernel_img_HEADERS): Remove `machine/partition.h'. Add + `partition.h' and `pc_partition.h'. + (grub_setup_SOURCES): Remove + `disk/i386/pc/partition.c'. Add `kern/partition.c', + `partmap/amiga.c', `partmap/apple.c' and `partmap/pc.c'. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add `amiga.mod', `apple.mod' and `pc.mod'. + (amiga_mod_SOURCES, amiga_mod_CFLAGS, apple_mod_SOURCES) + (apple_mod_CFLAGS, pc_mod_SOURCES, pc_mod_CFLAGS): New variables. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Remove + `disk/powerpc/ieee1275/partition.c'. Add `kern/partition.c', + `partmap/amiga.c', `partmap/apple.c' and `partmap/pc.c'. + (grubof_SOURCES): Likewise. + * disk/i386/pc/partition.c: File removed. + * disk/powerpc/ieee1275/partition.c: Likewise. + * include/grub/powerpc/ieee1275/partition.h: Likewise. + * include/grub/i386/pc/partition.h: Likewise. + * kern/partition.c: New file. + * partmap/amiga.c: Likewise. + * partmap/apple.c: Likewise. + * partmap/pc.c: Likewise. + * include/grub/partition.h: Likewise.. + * include/grub/pc_partition.h: Likewise. + * util/grub-emu.c: Include instead of + . + (main): Call `grub_pc_partition_map_init', + `grub_amiga_partition_map_init' and + `grub_apple_partition_map_init' and deinitialize afterwards. + * util/i386/pc/biosdisk.c: Include `#include + ' and `include ' instead of + `'. + * util/i386/pc/grub-setup.c: Likewise. + * util/i386/pc/biosdisk.c: Likewise. + (grub_util_biosdisk_get_grub_dev): Only access the PC specific + partition information in case of a PC partition. + * util/i386/pc/grub-setup.c: Include `#include + ' and `include ' instead of + `'. + (setup): Only access the PC specific partition information in case + of a PC partition. + +2004-11-17 Hollis Blanchard + + * kern/powerpc/ieee1275/init.c (grub_setjmp): Remove function. + (grub_longjmp): Likewise. + * include/grub/powerpc/setjmp.h (grub_jmp_buf): Set array size to + 20. + * normal/powerpc/setjmp.S: New file. + * conf/powerpc-ieee1275.rmk (grubof_SOURCES): Add + `normal/powerpc/setjmp.S'. + (grubof_CFLAGS): Add `-DGRUBOF'. + * include/grub/setjmp.h [GRUB_UTIL]: Changed condition to + [GRUB_UTIL && !GRUBOF]. + +2004-11-16 Marco Gerards + + * kern/powerpc/ieee1275/openfw.c (grub_devalias_iterate): Skip any + property named `name'. Correctly handle the error returned by + `grub_ieee1275_finddevice' if a device can not be opened. + +2004-11-02 Hollis Blanchard + + * term/powerpc/ieee1275/ofconsole.c (grub_ofconsole_readkey): Test + `actual' for negativity. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Remove + kern/fshelp.c. + +2004-11-01 Marco Gerards + + * term/i386/pc/vga.c (VGA_HEIGHT): Changed to 350. + (PAGE_OFFSET): New macro. + (CRTC_ADDR_PORT): Likewise. + (CRTC_DATA_PORT): Likewise. + (START_ADDR_HIGH_REGISTER): Likewise. + (START_ADDR_LOW_REGISTER): Likewise. + (GRAPHICS_ADDR_PORT): Likewise. + (GRAPHICS_DATA_PORT): Likewise. + (READ_MAP_REGISTER): Likewise. + (INPUT_STATUS1_REGISTER): Likewise. + (INPUT_STATUS1_VERTR_BIT): Likewise. + (page): New variable. + (wait_vretrace): New function. + (set_read_map): Likewise. + (set_start_address): Likewise. + (grub_vga_init): Use mode 0x10 instead of mode 0x12. Switch to + the right page. + (check_vga_mem): Take the page into account. + (write_char): Likewise. + (write_cursor): Likewise. + (scroll_up): Likewise. Copy the page to the page that is not + shown and switch between both pages. + (grub_vga_putchar): Fix off by one error. + (grub_vga_cls): Wait for the vertical retrace. Take the page into + account. + +2004-11-01 Marco Gerards + + Add support for iso9660 (including rockridge). + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add fs/iso9660.c. + (iso9660_mod_SOURCES): New variable. + (iso9660_mod_CFLAGS): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add fs/iso9660.c. + * include/grub/fs.h (grub_iso9660_init): New prototype. + * util/grub-emu.c (main): Call `grub_iso9660_init'. + * fs/iso9660.c: New file. + + * include/grub/misc.h (grub_strncat): New prototype. + * kern/misc.c (grub_strncat): New function. + + * fs/hfs.c (grub_hfs_mount): Translate the error + `GRUB_ERR_OUT_OF_RANGE' to `GRUB_ERR_BAD_FS'. + * fs/jfs.c (grub_jfs_mount): Likewise. + * fs/ufs.c (grub_ufs_mount): Likewise. + +2004-10-28 Hollis Blanchard + + * boot/powerpc/ieee1275/cmain.c (cmain): Remove asm statements + which initialized BAT registers. + * boot/powerpc/ieee1275/ieee1275.c (IEEE1275_CALL_ENTRY_FN, + grub_ieee1275_common_hdr, INIT_IEEE1275_COMMON): + Move from here... + * include/grub/powerpc/ieee1275/ieee1275.h (IEEE1275_CALL_ENTRY_FN, + grub_ieee1275_common_hdr, INIT_IEEE1275_COMMON): + ... to here. + * kern/powerpc/ieee1275/openfw.c (grub_map): New function. + (grub_mapclaim): Likewise. + * loader/powerpc/ieee1275/linux.c (grub_load_linux): Use + grub_mapclaim instead of grub_ieee1275_claim. Assign linux_addr by + hand. + +2004-10-19 Hollis Blanchard + + * conf/powerpc-ieee1275.rmk (COMMON_ASFLAGS): Remove -fno-builtin. + (COMMON_CFLAGS): Remove -fno-builtin and -D__ASSEMBLY__. Add + -ffreestanding and -msoft-float. + +2004-10-15 Hollis Blanchard + + * disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_open): Do not + append ":0" to devpath if the GRUB_IEEE1275_NO_PARTITION_0 flag is + set in grub_ieee1275_flags. + +2004-10-14 Hollis Blanchard + + * include/grub/powerpc/ieee1275/ieee1275.h (abort): Add function + prototype. + * kern/powerpc/ieee1275/init.c (grub_machine_init): Call + grub_console_init first. + Change the memory range used for grub_ieee1275_claim and + grub_mm_init_region. + Print an error message if the claim fails. + Include . + +2004-10-13 Hollis Blanchard + + * disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_iterate): + Call grub_children_iterate for device nodes of type `scsi', + `ide', or `ata'. + (grub_ofdisk_open): Remove manual device alias resolution. + Fix memory leak when device cannot be opened. + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_children_iterate): New prototype. + * kern/powerpc/ieee1275/openfw.c (grub_children_iterate): + New function. + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_get_property): + Return -1 if args.size was -1. + +2004-10-11 Hollis Blanchard + + * boot/powerpc/ieee1275/cmain.c (grub_ieee1275_flags): New global. + (cmain): Accept 3 parameters. Test for 0xdeadbeef, indicating Old + World Macintosh. If Old Wold, set flag in grub_ieee1275_flags; claim + Open Firmware's memory for it; claim memory from _start to _end. + * boot/powerpc/ieee1275/crt0.S (__bss_start): New extern. + (_end): New extern. + (_start): Zero BSS from __bss_start to _end. + * include/grub/powerpc/ieee1275/ieee1275.h (grub_ieee1275_flags): + New extern. + (GRUB_IEEE1275_NO_PARTITION_0): New #define. + +2004-10-11 Hollis Blanchard + + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_claim): Return + -1 if args.base was -1. + +2004-10-08 Hollis Blanchard + + * term/powerpc/ieee1275/ieee1275.c (grub_ofconsole_cls): Use an ANSI + escape sequence instead of a literal ^L. Also call + grub_ofconsole_gotoxy. + +2004-10-03 Hollis Blanchard + + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_claim): change + void * arguments to grub_addr_t. All callers updated. Also make + the `result' argument optional. + (grub_ieee1275_release): change void * arguments to grub_addr_t. + All callers updated. + +2004-09-22 Hollis Blanchard + + * commands/ls.c (grub_ls_list_files): Use the string following the + initial ')', if present, as the filesystem path. + * kern/rescue.c (grub_rescue_cmd_ls): Likewise. + + * conf/powerpc-ieee1275.rmk (grubof_SOURCES): List crt0.S first. + +2004-09-18 Yoshinori K. Okuji + + Make the source code of the menu interface more readable. + + * normal/menu.c: Include grub/mm.h. + (TERM_WIDTH): New macro. + (TERM_HEIGHT): Likewise. + (TERM_INFO_HEIGHT): Likewise. + (TERM_MARGIN): Likewise. + (TERM_SCROLL_WIDTH): Likewise. + (TERM_TOP_BORDER_Y): Likewise. + (TERM_LEFT_BORDER_X): Likewise. + (TERM_BORDER_WIDTH): Likewise. + (TERM_MESSAGE_HEIGHT): Likewise. + (TERM_BORDER_HEIGHT): Likewise. + (TERM_NUM_ENTRIES): Likewise. + (TERM_FIRST_ENTRY_Y): Likewise. + (TERM_ENTRY_WIDTH): Likewise. + (TERM_CURSOR_X): Likewise. + (draw_border): Use macros instead of magic numbers. + (print_entry): Likewise. + (print_entries): Likewise. + (run_menu): Likewise. Also, handle the key 'e'. + (run_menu_entry): Ignore empty command lines. + (print_message): Added a new argument EDIT. If EDIT is true, + print a different message. + (init_page): Likewise. + (edit_menu_entry): New function. Not implemented yet. + +2004-09-17 Marco Gerards + + Add `linux.mod' and `multiboot.mod' so linux and multiboot kernels + can be loaded from normal mode. + + * conf/i386-pc.rmk (pkgdata_MODULES): Add `linux.mod' and + `multiboot.mod'. + (linux_mod_SOURCES, linux_mod_CFLAGS, multiboot_mod_SOURCES) + (multiboot_mod_CFLAGS): New variables. + * loader/i386/pc/linux_normal.c: New file. + * loader/i386/pc/multiboot_normal.c: Likewise. + + * loader/i386/pc/linux.c (grub_rescue_cmd_initrd): Don't use the + attribute `unused'. + + * fs/ext2.c (grub_ext2_iterate_dir): Fix typos in inode type. Use + `fdiro' to read the mode information from instead of `diro'. + + * fs/fshelp.c (grub_fshelp_find_file): Set type to foundtype after + looking up a symlink. + + * include/grub/normal.h (GRUB_COMMAND_FLAG_NO_ARG_PARSE): New + macro. + * normal/command.c (grub_command_execute): Don't parse the + arguments when `GRUB_COMMAND_FLAG_NO_ARG_PARSE' is set in the + flags of the command. + + * normal/menu.c (grub_menu_run): Fix typo. + +2004-09-14 Hollis Blanchard + + * kern/powerpc/ieee1275/init.c (abort): Trap into Open Firmware. + + * term/powerpc/ieee1275/ofconsole.c (grub_ofconsole_gotoxy): Use + `y + 1' instead of `y - 1'. + + * conf/powerpc-ieee1275.rmk (grubof_LDFLAGS): Add `-N' and `-S'. + +2004-09-14 Yoshinori K. Okuji + + From Hollis Blanchard : + * kern/misc.c (memmove): New alias for grub_memmove. + (memcmp): New alias for grub_memcmp. + (memset): New alias for grub_memset. + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_get_property): + Change "int handle" to "grub_ieee1275_phandle_t handle". + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_ieee1275_get_property): Likewise. + +2004-09-12 Tomas Ebenlendr + + Added normal mode command `chainloader' as module chain.mod, which + depends on normal.mod and _chain.mod. + + * conf/i386-pc.rmk (pkgdata_MODULES): Add `chain.mod'. + (chain_mod_SOURCES, chain_mod_CFLAGS): Variables added. + * include/grub/i386/pc/loader.h (grub_rescue_cmd_chainloader): + Deleted prototype. + * loader/i386/pc/chainloader.c (grub_rescue_cmd_chainloader): All + but arguments parsing moved to ... + (grub_chainloader_cmd): ... here. New function. + * include/grub/i386/pc/chainloader.h: New file. + * loader/i386/pc/chainloader_normal.c: Likewise. + +2004-09-11 Marco Gerards + + * conf/i386-pc.rmk (kernel_img_SOURCES): Added kern/fshelp.c. + (grub_mkimage_LDFLAGS): Likewise. + (grub_emu_SOURCES): Likewise. + (kernel_img_HEADERS): Added fshelp.h. + * fs/ext2.c: Include . + (FILETYPE_REG): New macro. + (FILETYPE_INO_REG): Likewise. + (grub_ext_sblock): Renamed to `grub_ext2_sblock'. + Changed all users. + (ext2_block_group): Renamed to `grub_ext2_block_group'. Changed + all users. + (grub_fshelp_node): New struct. + (grub_ext2_data): Added member `diropen'. Changed member `inode' + to a pointer. + (grub_ext2_get_file_block): Removed function. + (grub_ext2_read_block): New function. + (grub_ext2_read_file): Replaced parameter `data' by `node'. + This function was written. + (grub_ext2_mount): Read the root inode. Create a diropen struct. + (grub_ext2_find_file): Removed function. + (grub_ext2_read_symlink): New function. + (grub_ext2_iterate_dir): Likewise. + (grub_ext2_open): Rewritten. + (grub_ext2_dir): Rewritten. + * include/grub/fshelp.h: New file. + * fs/fshelp.c: Likewise. + +2004-09-10 Yoshinori K. Okuji + + * normal/menu.c: Include grub/loader.h and grub/machine/time.h. + (print_message): Add a missing newline. + (run_menu): Added timeout support. + (run_menu_entry): New local function. + (grub_menu_run): Added support for booting. + + * kern/loader.c (grub_loader_is_loaded): New function. + + * include/grub/powerpc/ieee1275/time.h: Include grub/symbol.h. + (grub_get_rtc): Exported. + + * include/grub/i386/pc/time.h: Include grub/symbol.h. + (grub_get_rtc): Exported. + + * include/grub/normal.h (struct grub_command_list): Remove + constant from the member `command'. + + * include/grub/loader.h (grub_loader_is_loaded): Declared. + + * include/grub/err.h (GRUB_ERR_INVALID_COMMAND): New constant. + + * conf/i386-pc.rmk (kernel_img_HEADERS): Added machine/time.h. + +2004-08-28 Marco Gerards + + Add support for the JFS filesystem. + + * fs/jfs.c: New file. + * include/grub/fs.h (grub_jfs_init): New prototype. + (grub_jfs_fini): New prototype. + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/jfs.c. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add jfs.mod. + (jfs_mod_SOURCES): New variable. + (jfs_mod_CFLAGS): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add fs.jfs.c. + (grubof_SOURCES): Likewise. + * util/grub-emu.c (main): Initialize and deinitialize JFS support. + + * fs/fat.c (grub_fat_find_dir): Convert the filename little + endian to the host endian. + (grub_fat_utf16_to_utf8): Move function from there... + * kern/misc.c (grub_utf16_to_utf8): ...to here. Do not convert + the endianness of the source string anymore. + * include/grub/misc.h (grub_utf16_to_utf8): New prototype. + +2004-08-24 Marco Gerards + + * commands/boot.c (grub_boot_init) [GRUB_UTIL]: Make conditional. + (grub_boot_fini) [GRUB_UTIL]: Likewise. + (GRUB_MOD_INIT) [!GRUB_UTIL]: Likewise. + (GRUB_MOD_FINI) [!GRUB_UTIL]: Likewise. + + * fs/hfs.c (grub_hfs_find_node): Add a prototype for `node_found'. + (grub_hfs_iterate_dir): Make the function static. Add prototypes + for `node_found' and `it_dir'. + (grub_hfs_dir): Add prototype for `dir_hook'. + + * fs/minix.c (grub_minix_get_file_block): Add prototype for + `grub_get_indir'. Rename `indir' in two blocks to `indir16' + and `indir32' to silence a gcc warning. + + * include/grub/fs.h (grub_hfs_init): New prototype. + (grub_hfs_fini): Likewise. + + +2004-08-21 Yoshinori K. Okuji + + Each disk device has its own id now. This is useful to make use + of multiple disk devices. + + * include/grub/disk.h (grub_disk_dev_id): New enum. + (GRUB_DISK_DEVICE_BIOSDISK_ID): New constant. + (GRUB_DISK_DEVICE_OFDISK_ID): Likewise. + + * disk/i386/pc/biosdisk.c (grub_biosdisk_dev): Specify + GRUB_DISK_DEVICE_BIOSDISK_ID as an id. + + * disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_dev): Specify + GRUB_DISK_DEVICE_OFDISK_ID as an id. + + * util/i386/pc/biosdisk.c (grub_util_biosdisk_dev): Specify + GRUB_DISK_DEVICE_BIOSDISK_ID as an id. + + * include/grub/disk.h (struct grub_disk_dev): Added a new member + "id" which is used by the cache manager. + + * normal/main.c (grub_normal_init_page): Use "GNU GRUB" instead + of just "GRUB". + +2004-08-18 Marco Gerards + + * fs/hfs.c: New file. + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/hfs.c. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add hfs.mod. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add fs/hfs.c. + (grubof_SOURCES): Likewise. + * util/grub-emu.c (main): Initialize and deinitialize HFS support. + + * include/grub/misc.h (grub_strncasecmp): Add prototype. + * kern/misc.c (grub_strncasecmp): Add function. + +2004-08-14 Marco Gerards + + * include/grub/arg.h (GRUB_ARG_OPTION_OPTIONAL): Surround macro + with parentheses. + + * fs/ext2.c (FILETYPE_UNKNOWN): New macro. + (grub_ext2_dir): In case the directory entry type is unknown, read + it from the inode. + +2004-08-02 Peter Bruin + + * loader/powerpc/ieee1275/linux.c (grub_linux_init): Pass + grub_load_linux instead of grub_rescue_cmd_linux as second + argument of grub_rescue_register_command. + + * Makefile.in (RMKFILES): Add conf/powerpc-ieee1275.rmk. + +2004-07-27 Marco Gerards + + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_release): New + function. + * commands/boot.c: Remove the check for `GRUB_UTIL'. + * conf/powerpc-ieee1275.rmk (grubof_SOURCES): Add + `loader/powerpc/ieee1275/linux.c', + `loader/powerpc/ieee1275/linux_normal.c' and `commands/boot.c'. + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_ieee1275_release): New prototype. + * include/grub/powerpc/ieee1275/loader.h: Rewritten. + * kern/powerpc/ieee1275/init.c (grub_machine_init): Initialize + normal, boot, linux and linux_normal. + * loader/powerpc/ieee1275/linux.c: New file. + * loader/powerpc/ieee1275/linux_normal.c: Likewise. + +2004-07-12 Marco Gerards + + * normal/arg.c (grub_arg_parse): Correct error handling after + reallocating the argumentlist (check if `argl' is not null instead + of checking if `args' is not null). + * kern/mm.c (grub_realloc): Return the same pointer when using the + same region, instead of returning the header address. + +2004-07-11 Marco Gerards + + * disk/powerpc/ieee1275/partition.c (grub_partition_iterate): Skip + one block instead of two when looking for the initial partition. + (grub_partition_probe): Initialize the local variable `p' with 0. + Use base 10 for the grub_strtoul call. + * kern/misc.c (grub_strncpy): Fix off by one bug. Eliminated the + need for one local variable. + (grub_strtoul): Don't add the new value to `num', instead of that + just assign it. + +2004-07-11 Marco Gerards + + * conf/i386-pc.rmk (pkgdata_IMAGE): Add pxeboot.img. + (pxeboot_img_SOURCES): New variable. + (pxeboot_img_ASFLAGS): Likewise. + (pxeboot_img_LDFLAGS): Likewise. + * boot/i386/pc/pxeboot.S: New file. Based on pxeloader.S from + GRUB Legacy and boot.S. Adopted for GRUB 2 by lode leroy + . + +2004-06-27 Tomas Ebenlendr + + * kern/rescue.c (grub_enter_rescue_mode): Don't continue when + there was no input. + +2004-06-27 Tomas Ebenlendr + + * normal/cmdline.c (grub_set_history): Fix off by one bug. Fixed + the history buffer logic. + +2004-06-27 Tomas Ebenlendr + + * fs/ext2.c (FILETYPE_INO_MASK, FILETYPE_INO_DIRECTORY) + (FILETYPE_INO_SYMLINK): New macros. + (grub_ext2_find_file): Check if the node is a directory using the + inode stat information instead of using the filetype in the + dirent. Exclude the first character of an absolute symlink. + (grub_ext2_dir): Mask out the filetype part of the mode member of + the inode. + +2004-05-24 Marco Gerards + + Add support for UFS version 1 and 2. Add support for the minix + filesystem version 1 and 2, both the variants with 14 and 30 long + filenames. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/ufs.c and + fs/minix.c. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add ufs.mod and minix.mod. + (ufs_mod_SOURCES): New variable. + (ufs_mod_CFLAGS): Likewise. + (minix_mod_SOURCES): Likewise. + (minix_mod_CFLAGS): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add fs/ufs.c and + fs/minix.c. + (grubof_SOURCES): Likewise. + * fs/ufs.c: New file. + * fs/minix.c: New file. + * include/grub/fs.h (grub_ufs_init): New prototype. + (grub_ufs_fini): Likewise. + (grub_minix_init): Likewise. + (grub_minix_fini): Likewise. + * util/grub-emu.c (main): Initialize and deinitialize UFS and + minix fs. + +2004-04-30 Jeroen Dekkers + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add normal/arg.c, + commands/ls.c, commands/terminal.c, commands/boot.c, + commands/cmp.c and commands/cat.c. + (grubof_LDFLAGS): Add -nostdlib -static-libgcc -lgcc. + + * kern/powerpc/ieee1275/init.c: Include "grub/env.h" instead of + "env.h" + +2004-04-04 Yoshinori K. Okuji + + All symbols prefixed with PUPA_ and pupa_ are renamed to GRUB_ + and grub_, respectively. Because the conversion is trivial and + mechanical, I omit the details here. Please refer to the CVS + if you need more information. + +2004-04-04 Yoshinori K. Okuji + + * include/pupa: Renamed to ... + * include/grub: ... this. + * util/i386/pc/pupa-mkimage.c: Renamed to ... + * util/i386/pc/grub-mkimage.c: ... this. + * util/i386/pc/pupa-setup.c: Renamed to ... + * util/i386/pc/grub-setup.c: ... this. + * util/pupa-emu.c: Renamed to ... + * util/grub-emu.c: ... this. + +2004-03-29 Marco Gerards + + Add support for the newworld apple macintosh (PPC). This has been + tested on the powerbook 2000 only. It only adds support for + generic ieee1275 functions, console and disk support. This should + be easy to port to other architectures with support for Open + Firmware. + + * configure.ac: Accept the powerpc as host_cpu. In the case of + the powerpc cpu set the host_vendor to ieee1275. Make sure the i386 + specific tests are only executed while building for the i386. + Inverse test for crosscompile. + * genmk.rb (Utility): Allow assembler files. + * normal/cmdline.c (pupa_tab_complete): Reset pupa_errno. + * conf/powerpc-ieee1275.rmk: New file. + * disk/powerpc/ieee1275/ofdisk.c: Likewise. + * disk/powerpc/ieee1275/partition.c: Likewise. + * include/pupa/powerpc/ieee1275/biosdisk.h: Likewise. + * include/pupa/powerpc/ieee1275/console.h: Likewise. + * include/pupa/powerpc/ieee1275/partition.h: Likewise. + * include/pupa/powerpc/ieee1275/time.h: Likewise. + * include/pupa/powerpc/ieee1275/util/biosdisk.h: Likewise. + * include/pupa/powerpc/ieee1275/multiboot.h: Likewise. + * include/pupa/powerpc/ieee1275/loader.h + * include/pupa/powerpc/setjmp.h: Likewise. + * include/pupa/powerpc/types.h: Likewise. + * kern/powerpc/ieee1275/init.c: Likewise. + * kern/powerpc/ieee1275/openfw.c: Likewise. + * term/powerpc/ieee1275/ofconsole.c: Likewise. + + These files were written by Johan Rydberg + (jrydberg@night.trouble.net) and I only modified them slightly. + + * boot/powerpc/ieee1275/cmain.c: New file. + * boot/powerpc/ieee1275/crt0.S: Likewise. + * boot/powerpc/ieee1275/ieee1275.c: Likewise. + * include/pupa/powerpc/ieee1275/ieee1275.h: Likewise. + +2004-03-14 Jeroen Dekkers + + * Makefile.in: Update copyright. + * genmodsrc.sh: Likewise. + * gensymlist.sh: Likewise. + * term/i386/pc/vga.c: Indent correctly. + + * util/i386/pc/pupa-mkimage.c (usage): Use PACKAGE_BUGREPORT as + bugreporting address. + * util/i386/pc/pupa-setup.c (usage): Likewise, + (main): Call pupa_ext2_init and pupa_ext2_fini. + + * fs/fat.c (log2): Renamed to ... + (fat_log2): ... this. + All callers changed. + * kern/misc.c (memcpy): Alias to pupa_memmove. + * loader/i386/pc/multiboot.c (pupa_rescue_cmd_multiboot): Fix + lvalue cast. + * util/console.c (pupa_ncurses_fini): Return 0. + + * util/i386/pc/biosdisk.c (pupa_util_biosdisk_open)[__linux__]: + Move fail label here. + [__GNU__]: Don't warn when using stat. + (open_device)[!__linux__]: Check if FD < 0 instead of !FD. + (pupa_util_biosdisk_get_pupa_dev)[__GNU__]: Change type of N to + long int. Use strtol instead of strtoul. + +2004-03-14 Marco Gerards + + * commands/boot.c: New file. + * commands/cat.c: Likewise. + * commands/cmp.c: Likewise. + * commands/ls.c: Likewise. + * commands/terminal.c: Likewise. + * normal/command.c: Include and . + (pupa_register_command): Changed interface to match the new + argument parser. + (pupa_command_execute): Changed (almost rewritten) so it uses + pupa_split_command. Added support for setting variables using the + syntax `foo=bar'. + (rescue_command): Changed to work with the new argument parser. + (terminal_command): Moved from here to commands/terminal.c. + (set_command): New function. + (unset_command): New function. + (insmod_command): New function. + (rmmod_command): New function. + (lsmod_command): New function. + (pupa_command_init): Don't initialize the command terminal + anymore. Initialize the commands set, unset, insmod, rmmod and + lsmod. + * conf/i386-pc.rmk (kernel_img_SOURCES): Add kern/env.c. + (kernel_img_HEADERS): Add arg.h and env.h. + (pupa_mkimage_LDFLAGS): Add kern/env.c. + (pupa_emu_SOURCES): Add kern/env.c, commands/ls.c, + commands/terminal.c commands/boot.c commands/cmp.c commands/cat.c, + normal/arg.c. + (pkgdata_MODULES): Add ls.mod, boot.mod, cmp.mod, cat.mod and + terminal.mod. + (normal_mod_SOURCES): Add normal/arg.c and normal/arg.c. + (boot_mod_SOURCES): New variable. + (terminal_mod_SOURCES): Likewise. + (ls_mod_SOURCES): Likewise. + (cmp_mod_SOURCES): Likewise. + (cat_mod_SOURCES): Likewise. + + * normal/arg.c: New file. + * kern/env.c: Likewise. + * include/pupa/arg.h: Likewise. + * include/pupa/env.h: Likewise. + * font/manager.c (font_command): Changed to match argument parsing + interface changes. + (PUPA_MOD_INIT): Likewise. + * hello/hello.c (pupa_cmd_hello): Likewise. + (PUPA_MOD_INIT): Likewise. + * include/pupa/disk.h: Include . + (pupa_print_partinfo): New prototype. + * include/pupa/dl.h (pupa_dl_set_prefix): Prototype removed. + (pupa_dl_get_prefix): Likewise. + * include/pupa/misc.h: Include . + (pupa_isgraph): New prototype. + (pupa_isdigit): Likewise. + (pupa_split_cmdline): Likewise. + * include/pupa/normal.h: Include . + (pupa_command): Changed the prototype of the member `func' to + match the argument parsing interface. Added member `options'. + (pupa_register_command): Updated to match function. + (pupa_arg_parse): New prototype. + (pupa_hello_init) [PUPA_UTIL]: New prototype. + (pupa_hello_fini) [PUPA_UTIL]: Likewise. + (pupa_ls_init) [PUPA_UTIL]: Likewise. + (pupa_ls_fini) [PUPA_UTIL]: Likewise. + (pupa_cat_init) [PUPA_UTIL]: Likewise. + (pupa_cat_fini) [PUPA_UTIL]: Likewise. + (pupa_boot_init) [PUPA_UTIL]: Likewise. + (pupa_boot_fini) [PUPA_UTIL]: Likewise. + (pupa_cmp_init) [PUPA_UTIL]: Likewise. + (pupa_cmp_fini) [PUPA_UTIL]: Likewise. + (pupa_terminal_init) [PUPA_UTIL]: Likewise. + (pupa_terminal_fini) [PUPA_UTIL]: Likewise. + * kern/disk.c: Include . + (pupa_print_partinfo): New function. + * kern/dl.c: Include . + (pupa_dl_dir): Variable removed. + (pupa_dl_load): Use the environment variable `prefix' instead of + the variable pupa_dl_dir. + (pupa_dl_set_prefix): Function removed. + (pupa_dl_get_prefix): Likewise. + * kern/i386/pc/init.c: Include . + (pupa_machine_init): Use the environment variable `prefix' instead of + using pupa_dl_set_prefix to set the prefix. + * kern/main.c: Include . + (pupa_set_root_dev): Use the environment variable `prefix' instead of + using pupa_dl_get_prefix to get the prefix. + * kern/misc.c: Include . + (pupa_isdigit): New function. + (pupa_isgraph): Likewise. + (pupa_ftoa): Likewise. + (pupa_vsprintf): Added support for printing values of the type + `double'. Make it possible to format variable output when using + formatting like `%1.2%f'. + (pupa_split_cmdline): New function. + * kern/rescue.c: Include . + (next_word): Removed function. + (pupa_rescue_cmd_prefix): Likewise. + (pupa_rescue_cmd_set): New function. + (pupa_rescue_cmd_unset): New function. + (pupa_enter_rescue_mode): Use the `pupa_split_cmdline' function to + split the command line instead of splitting it here. Added + support for setting variables using the syntax `foo=bar'. Don't + initialize the prefix command anymore. Initialized the set and + unset commands. + * normal/cmdline.c: Include . + (pupa_tab_complete): Added prototypes for print_simple_completion, + print_partition_completion, add_completion, iterate_commands, + iterate_dev, iterate_part and iterate_dir. Moved code to print + partition information from here to kern/disk.c. + (pupa_cmdline_run): Don't check if the function exists anymore. + * normal/main.c: Include . + (pupa_rescue_cmd_normal): Use the environment variable `prefix' + instead of using pupa_dl_get_prefix to get the prefix. + * term/i386/pc/vga.c: Include . + (check_vga_mem): Cast pointers to `void *' to silence a gcc + warning. + (pupa_vga_putchar) [! DEBUG_VGA]: Removed for this case. + (pupa_vga_setcolor): Declare unused variables with `__attribute__ + ((unused))' to silence a gcc warning. + (pupa_vga_setcolor): Likewise. + (debug_command): Changed to match argument parsing + interface changes. + * util/pupa-emu.c: Include . + (options): Added 0's for unused fields to silence a gcc warning. + (argp): Likewise. + (main): Use the environment variable `prefix' instead of using + pupa_dl_set_prefix to set the prefix. Initialize the commands ls, + boot, cmp, cat and terminal. Finish the commands boot, cmp, cat + and terminal. + + * util/i386/pc/getroot.c: Include . + * util/misc.c: Include . + (pupa_malloc): Rewritten so errors are correctly reported. + (pupa_realloc): Likewise. + (pupa_memalign): Likewise. + (pupa_mm_init_region): Declare unused variables with + `__attribute__ ((unused))' to silence a gcc warning. + * normal/i386/setjmp.S: Remove tab at the end of the file to + silence a gcc warning. + * loader/i386/pc/linux.c (pupa_rescue_cmd_initrd): Declare unused + variables with `__attribute__ ((unused))' to silence a gcc + warning. + * loader/i386/pc/multiboot.c (pupa_multiboot_unload): Make the + local variable i unsigned to silence a gcc warning. + + * kern/term.c: Include . + (pupa_more_lines): New variable. + (pupa_more): Likewise. + (pupa_putcode): When the pager is active pause at the end of every + screen. + (pupa_set_more): New function. + * include/pupa/term.h (pupa_set_more): New prototype. + + +2004-03-07 Yoshinori K. Okuji + + Now this project is GRUB 2 rather than PUPA. The location of + the CVS repository was moved to GRUB's. + + * configure.ac: Use bug-grub as the reporting address. + Use GRUB instead of PUPA. + Change the version number to 1.90. + +2004-02-24 Yoshinori K. Okuji + + * genkernsyms.sh: Updated copyright information. + * genmk.rb: Likewise. + * genmodsrc.sh: Likewise. + * gensymlist.sh: Likewise. + * boot/i386/pc/boot.S: Likewise. + * boot/i386/pc/diskboot.S: Likewise. + * disk/i386/pc/biosdisk.c: Likewise. + * disk/i386/pc/partition.c: Likewise. + * font/manager.c: Likewise. + * fs/ext2.c: Likewise. + * fs/fat.c: Likewise. + * include/pupa/boot.h: Likewise. + * include/pupa/device.h: Likewise. + * include/pupa/disk.h: Likewise. + * include/pupa/dl.h: Likewise. + * include/pupa/elf.h: Likewise. + * include/pupa/err.h: Likewise. + * include/pupa/file.h: Likewise. + * include/pupa/font.h: Likewise. + * include/pupa/fs.h: Likewise. + * include/pupa/kernel.h: Likewise. + * include/pupa/loader.h: Likewise. + * include/pupa/misc.h: Likewise. + * include/pupa/mm.h: Likewise. + * include/pupa/net.h: Likewise. + * include/pupa/normal.h: Likewise. + * include/pupa/rescue.h: Likewise. + * include/pupa/setjmp.h: Likewise. + * include/pupa/symbol.h: Likewise. + * include/pupa/term.h: Likewise. + * include/pupa/types.h: Likewise. + * include/pupa/i386/setjmp.h: Likewise. + * include/pupa/i386/types.h: Likewise. + * include/pupa/i386/pc/biosdisk.h: Likewise. + * include/pupa/i386/pc/boot.h: Likewise. + * include/pupa/i386/pc/console.h: Likewise. + * include/pupa/i386/pc/init.h: Likewise. + * include/pupa/i386/pc/kernel.h: Likewise. + * include/pupa/i386/pc/linux.h: Likewise. + * include/pupa/i386/pc/loader.h: Likewise. + * include/pupa/i386/pc/memory.h: Likewise. + * include/pupa/i386/pc/multiboot.h: Likewise. + * include/pupa/i386/pc/partition.h: Likewise. + * include/pupa/i386/pc/time.h: Likewise. + * include/pupa/i386/pc/vga.h: Likewise. + * include/pupa/i386/pc/util/biosdisk.h: Likewise. + * include/pupa/util/getroot.h: Likewise. + * include/pupa/util/misc.h: Likewise. + * include/pupa/util/resolve.h: Likewise. + * kern/device.c: Likewise. + * kern/disk.c: Likewise. + * kern/dl.c: Likewise. + * kern/err.c: Likewise. + * kern/file.c: Likewise. + * kern/fs.c: Likewise. + * kern/loader.c: Likewise. + * kern/main.c: Likewise. + * kern/misc.c: Likewise. + * kern/mm.c: Likewise. + * kern/rescue.c: Likewise. + * kern/term.c: Likewise. + * kern/i386/dl.c: Likewise. + * kern/i386/pc/init.c: Likewise. + * kern/i386/pc/lzo1x.S: Likewise. + * kern/i386/pc/startup.S: Likewise. + * loader/i386/pc/chainloader.c: Likewise. + * loader/i386/pc/linux.c: Likewise. + * loader/i386/pc/multiboot.c: Likewise. + * normal/cmdline.c: Likewise. + * normal/command.c: Likewise. + * normal/main.c: Likewise. + * normal/menu.c: Likewise. + * normal/i386/setjmp.S: Likewise. + * term/i386/pc/console.c: Likewise. + * term/i386/pc/vga.c: Likewise. + * util/console.c: Likewise. + * util/genmoddep.c: Likewise. + * util/misc.c: Likewise. + * util/pupa-emu.c: Likewise. + * util/resolve.c: Likewise. + * util/unifont2pff.rb: Likewise. + * util/i386/pc/biosdisk.c: Likewise. + * util/i386/pc/getroot.c: Likewise. + * util/i386/pc/pupa-mkimage.c: Likewise. + * util/i386/pc/pupa-setup.c: Likewise. + +2004-02-15 Jeroen Dekkers + + * fs/ext2.c (pupa_ext2_read_file): Correct the value of BLOCKEND + when it is EXT2_BLOCK_SIZE (data). New argument READ_HOOK, all + callers changed. Set DATA->DISK->READ_HOOK to READ_HOOK before + reading and reset it after reading. + (pupa_ext2_close): Return PUPA_ERR_NONE. + + * include/pupa/i386/pc/linux.h (PUPA_LINUX_INITRD_MAX_ADDRESS): + Correct value. + (struct linux_kernel_header): Add kernel_version and + initrd_addr_max. + * loader/i386/pc/linux.c (pupa_rescue_cmd_linux): Check whether + pupa_file_read succeeds. + (pupa_rescue_cmd_initrd): Implement. + +2003-12-03 Marco Gerards + + * fs/ext2.c (pupa_ext2_label): New function. + (pupa_ext2_fs): Added label. + * fs/fat.c (pupa_fat_label): New function. + (pupa_fat_fs): Added label. + * include/pupa/fs.h (struct pupa_fs): Added prototype label. + + * kern/misc.c (pupa_strndup): New function. + * include/pupa/misc.h (pupa_strndup): New prototype. + + * include/pupa/normal.h: Include . + (pupa_set_history): New prototype. + (pupa_iterate_commands): New prototype. + * normal/cmdline.c: Include , + , . + (hist_size): New variable. + (hist_lines): Likewise. + (hist_end): Likewise. + (hist_used): Likewise. + (pupa_set_history): New function. + (pupa_history_get): Likewise. + (pupa_history_add): Likewise. + (pupa_history_replace): Likewise. + (pupa_tab_complete): Likewise. + (pupa_cmdline_run): Added tab completion and history buffer. Tab + completion shows partitionnames while completing partitions, this + feature was suggested by Jeff Bailey. + * normal/command.c (pupa_iterate_commands): New function. + * normal/main.c (PUPA_DEFAULT_HISTORY_SIZE): New macro. + (pupa_normal_init): Initialize history buffer. + (PUPA_MOD_INIT): Likewise. + (pupa_normal_fini): Free the history buffer. + (PUPA_MOD_FINI): Likewise. + + * util/console.c (pupa_ncurses_getkey): Accept 127 as backspace + key. + + * aclocal.m4 (pupa_I386_CHECK_REGPARM_BUG): New DEFUN. + * configure.ac [i386]: Check for regparam bug. + (NESTED_FUNC_ATTR) [! i386]: Defined. + +2003-11-17 Marco Gerards + + * conf/i386-pc.rmk (sbin_UTILITIES): Added pupa-emu. + (pupa_setup_SOURCES): Added util/i386/pc/getroot.c. + (pupa_emu_SOURCES): New variable. + (pupa_emu_LDFLAGS): Likewise. + * include/pupa/fs.h (pupa_ext2_init) [PUPA_UTIL]: New prototype. + (pupa_ext2_fini) [PUPA_UTIL]: Likewise. + * include/pupa/normal.h (pupa_normal_init) [PUPA_UTIL]: Likewise. + (pupa_normal_fini) [PUPA_UTIL]: Likewise. + * include/pupa/setjmp.h [PUPA_UTIL]: Include . + (pupa_jmp_buf): New typedef. + (pupa_setjmp) [PUPA_UTIL]: New macro. + (pupa_longjmp) [PUPA_UTIL]: Likewise. + * include/pupa/term.h (struct pupa_term): New member `refresh'. + (pupa_refresh): New prototype. + * include/pupa/util/getroot.h: New file. + * kern/misc.c (pupa_vsprintf): Refresh the screen after updating + it. + * kern/rescue.c (pupa_rescue_get_command_line): Likewise. + (pupa_rescue_cmd_cat): Likewise. + (pupa_rescue_cmd_ls): Likewise. + (pupa_rescue_cmd_testload): Likewise. + (pupa_rescue_cmd_lsmod): Likewise. + * normal/cmdline.c (pupa_cmdline_get): Likewise. + * normal/menu.c (run_menu): Likewise. + * kern/term.c (pupa_cls): Likewise. + (pupa_refresh): New function. + * normal/normal.c (pupa_normal_init) [PUPA_UTIL]: New function. + (pupa_normal_fini) [PUPA_UTIL]: Likewise. + * util/console.c: New file. + + * util/i386/pc/getroot.c: New file. + * util/i386/pc/pupa-setup.c: Include . + (pupa_putchar): New function. + (pupa_refresh): Likewise. + (xgetcwd): Function moved to ... + (strip_extra_slashes): Likewise. + (get_prefix): Likewise. + * util/i386/pc/getroot.c: ... here. + (find_root_device): Function moved and renamed to... + * util/i386/pc/getroot.c (pupa_find_root_device): ... here. + Changed all callers. + * util/i386/pc/pupa-setup.c (guess_root_device): Function moved + and renamed to... + * util/i386/pc/getroot.c (pupa_guess_root_device): ... here. + Changed all callers. + * util/misc.c (pupa_memalign): New function. + (pupa_mm_init_region): Likewise. + (pupa_register_exported_symbols): Likewise. + (pupa_putchar): Function removed. + * util/pupa-emu.c: New file. + +2003-11-16 Jeroen Dekkers + + * conf/i386-pc.rmk (pkgdata_MODULES): Add _multiboot.mod. + (_multiboot_mod_SOURCES): New variable. + (_multiboot_mod_CFLAGS): Likewise. + * loader/i386/pc/multiboot.c: New file. + * include/pupa/i386/pc/multiboot.h: Likewise. + * kern/i386/pc/startup.S: Include pupa/machine/multiboot.h. + (pupa_multiboot_real_boot): New function. + * include/pupa/i386/pc/loader.h: Include pupa/machine/multiboot.h. + (pupa_multiboot_real_boot): New prototype. + (pupa_rescue_cmd_multiboot): Likewise + (pupa_rescue_cmd_module): Likewise. + + * kern/loader.c (pupa_loader_set): Continue when + pupa_loader_unload_func() fails. + (pupa_loader_unset): New function. + * include/pupa/loader.h (pupa_loader_unset): New prototype. + + * kern/misc.c (pupa_stpcpy): New function. + * include/pupa/misc.h (pupa_stpcpy): New prototype. + +2003-11-12 Marco Gerards + + * disk/i386/pc/biosdisk.c (pupa_biosdisk_open): Correctly check + for available extensions. + + * include/pupa/i386/pc/time.h: New file. + * kern/disk.c: Include . + (PUPA_CACHE_TIMEOUT): New macro. + (pupa_last_time): New variable. + (pupa_disk_open): Flush the cache when there was a timeout. + (pupa_disk_close): Reset the timer. + * kern/i386/pc/startup.S (pupa_get_rtc): Renamed from + pupa_currticks. + * util/misc.c: Include + (pupa_get_rtc): New function. + +2003-11-09 Jeroen Dekkers + + * fs/ext2.c (struct pupa_ext2_inode): Declare struct datablocks + as blocks. + (pupa_ext2_get_file_block): Use blocks member. + + * fs/ext2.c (pupa_ext2_read_file): Only set skipfirst for the + first block. Return -1 instead of pupa_errno on error. + +2003-10-27 Marco Gerards + + * README: In the pupa-mkimage example use _chain instead of chain + and ext2 instead of fat. + * TODO: Replace ext2fs with jfs as an example. Add an item for + adding journal playback for ext2fs. + * conf/i386-pc.rmk (pupa_setup_SOURCES): Added fs/ext2.c. + (pkgdata_MODULES): Added ext2.mod. + (ext2_mod_SOURCES): New variable. + (ext2_mod_CFLAGS): Likewise. + * include/pupa/err.h (pupa_err_t): Added PUPA_ERR_SYMLINK_LOOP. + * include/pupa/misc.h (pupa_strncpy): New prototype. + (pupa_strcat): Likewise. + (pupa_strncmp): Likewise. + * kern/misc.c (pupa_strcat): Enable function. + (pupa_strncpy): New function. + (pupa_strncmp): Likewise. + * fs/ext2.c: New file. + + * kern/disk.c (pupa_disk_read): Set pupa_errno to PUPA_ERR_NONE + when the read failed before retrying. + * util/i386/pc/biosdisk.c (_LARGEFILE_SOURCE): Removed. + (_FILE_OFFSET_BITS): Likewise. + * configure.ac: Added AC_SYS_LARGEFILE. + +2003-09-25 Yoshinori K. Okuji + + * genmk.rb (PModule#rule): Make sure to get only symbol names + from the output of nm. + Reported by Robert Millan . + +2003-09-25 Yoshinori K. Okuji + + I forgot to check in these changes for a long time. This adds + incomplete support for VGA console, and this is still very + buggy. Also, a lot of consideration is required for I18N, + UNICODE, and VGA font issues. Therefore, assume that this is + such that "better than nothing". + + * font/manager.c: New file. + * include/pupa/font.h: Likewise. + * include/pupa/i386/pc/vga.h: Likewise. + * term/i386/pc/vga.c: Likewise. + * util/unifont2pff.rb: Likewise. + + * conf/i386-pc.rmk (kernel_img_HEADERS): Added machine/vga.h. + (pkgdata_MODULES): Added vga.mod and font.mod. + (vga_mod_SOURCES): New variables. + (vga_mod_CFLAGS): Likewise. + (font_mod_SOURCES): Likewise. + (font_mod_CFLAGS): Likewise. + + * include/pupa/err.h (PUPA_ERR_BAD_FONT): New constant. + + * include/pupa/term.h: Include pupa/err.h. + (struct pupa_term): Added init and fini. + Changed the argument of putchar to pupa_uint32_t. + + * include/pupa/i386/pc/console.h: Include pupa/symbol.h. + (pupa_console_real_putchar): New prototype. + (pupa_console_putchar): Removed. + (pupa_console_checkkey): Exported. + (pupa_console_getkey): Likewise. + + * kern/misc.c (pupa_vsprintf): Add support for UNICODE + characters. + + * kern/term.c (pupa_term_set_current): Rewritten. + (pupa_putchar): Likewise. + (pupa_putcode): New function. + + * kern/i386/pc/startup.S (pupa_console_putchar): Renamed to ... + (pupa_console_real_putchar): ... this. + (pupa_vga_set_mode): New function. + (pupa_vga_get_font): Likewise. + + * normal/command.c: Include pupa/term.h. + (terminal_command): New function. + (pupa_command_init): Register the command "terminal". + + * normal/menu.c (DISP_LEFT): Changed to a UNICODE value. + (DISP_UP): Likewise. + (DISP_RIGHT): Likewise. + (DISP_DOWN): Likewise. + (DISP_HLINE): Likewise. + (DISP_VLINE): Likewise. + (DISP_UL): Likewise. + (DISP_UR): Likewise. + (DISP_LL): Likewise. + (DISP_LR): Likewise. + + * term/i386/pc/console.c (pupa_console_putchar): New function. + +2003-02-08 NIIBE Yutaka + + * util/resolve.c (pupa_util_resolve_dependencies): BUG + FIX. Reverse the path_list. + + * include/pupa/normal.h: Export pupa_register_command and + pupa_unregister_command. + + * hello/hello.c (pupa_cmd_hello): New module. + * conf/i386-pc.rmk: Added hello.mod. + +2003-01-31 Yoshinori K. Okuji + + * kern/i386/pc/lzo1x.S: New file. + + * util/i386/pc/pupa-mkimage.c: Include lzo1x.h. + (compress_kernel): New variable. + (generate_image): Heavily modified to support compressing a + large part of the core image. + + * util/misc.c (pupa_util_read_image): Fix a file descriptor + leak. + (pupa_util_load_image): New function. + + * kern/i386/pc/startup.S: Include pupa/machine/kernel.h. + (pupa_compressed_size): New variable. + (codestart): Enable Gate A20 here. + Decompress the compressed part of the core image. + Rearrange the code to put functions and variables which are + required for initialization in the non-compressed part. + Include lzo1x.S. + + * kern/i386/pc/init.c (pupa_machine_init): Don't enable Gate A20 + here. + + * include/pupa/util/misc.h (pupa_util_write_image): Declared. + + * include/pupa/i386/pc/kernel.h + (PUPA_KERNEL_MACHINE_COMPRESSED_SIZE): New macro. + (PUPA_KERNEL_MACHINE_INSTALL_DOS_PART): Increased by 4. + (PUPA_KERNEL_MACHINE_INSTALL_BSD_PART): Likewise. + (PUPA_KERNEL_MACHINE_PREFIX): Likewise. + (PUPA_KERNEL_MACHINE_RAW_SIZE): New macro. + + * conf/i386-pc.rmk (pupa_mkimage_LDFLAGS): New variable. + + * genmk.rb (Image#rule): Put LDFLAGS at the end of a line. + (Utility#rule): Likewise. + + * configure.ac: Check if LZO is available. + +2003-01-20 Yoshinori K. Okuji + + * include/pupa/normal.h: New file. + * include/pupa/setjmp.h: Likewise. + * include/pupa/i386/setjmp.h: Likewise. + * normal/cmdline.c: Likewise. + * normal/command.c: Likewise. + * normal/main.c: Likewise. + * normal/menu.c: Likewise. + * normal/i386/setjmp.S: Likewise. + + * loader/i386/pc/linux.c (pupa_rescue_cmd_linux): Made global. + (pupa_rescue_cmd_initrd): Likewise. + + * loader/i386/pc/chainloader.c (pupa_rescue_cmd_chainloader): + Likewise. + + * kern/i386/pc/startup.S (translation_table): New variable. + (translate_keycode): New function. + (pupa_console_getkey): Call translate_keycode. + + * kern/rescue.c (attempt_normal_mode): New function. + (pupa_enter_rescue_mode): Attempt to execute the normal mode. If + it failed, print a message. + + * kern/mm.c (pupa_real_malloc): Print more information when a + free magic is broken. + (pupa_free): If the first free header is not free actually, set + it to P. + + * kern/main.c (pupa_load_normal_mode): Just load the module + "normal". + (pupa_main): Don't print the message + "Entering into rescue mode..." here. + + * include/pupa/i386/pc/loader.h (pupa_rescue_cmd_initrd): + Declared. + (pupa_rescue_cmd_initrd): Likewise. + (pupa_rescue_cmd_initrd): Likewise. + + * include/pupa/symbol.h (FUNCTION): Specify the type. + (VARIABLE): Likewise. + + * include/pupa/err.h (pupa_err_t): Added + PUPA_ERR_UNKNOWN_COMMAND. + + * include/pupa/dl.h (pupa_dl_set_prefix): Exported. + (pupa_dl_get_prefix): Likewise. + + * conf/i386-pc.rmk (pkgdata_MODULES): Added normal.mod. + Added _chain.mod and _linux.mod instead of chain.mod and + linux.mod. + (chain_mod_SOURCES): Renamed to ... + (_chain_mod_SOURCES): ... this. + (chain_mod_CFLAGS): Renamed to ... + (_chain_mod_CFLAGS): ... this. + (linux_mod_SOURCES): Renamed to ... + (_linux_mod_SOURCES): ... this. + (linux_mod_CFLAGS): Renamed to ... + (_linux_mod_CFLAGS): ... this. + (normal_mod_SOURCES): New variable. + (normal_mod_CFLAGS): Likewise. + (normal_mod_ASFLAGS): Likewise. + +2003-01-18 Yoshinori K. Okuji + + * kern/rescue.c (pupa_rescue_cmd_rmmod): Call pupa_dl_unload, if + possible. + + * kern/dl.c (pupa_dl_ref): Refer depending modules + recursively. + (pupa_dl_unref): Unrefer depending modules recursively. + Don't call pupa_dl_unload implicitly, because PUPA can crash if + a module is unloaded before one depending on that module is + unloaded. + (pupa_dl_unload): Unload depending modules explicitly, + if possible. + +2003-01-17 Yoshinori K. Okuji + + * include/pupa/i386/pc/linux.h: New file. + * loader/i386/pc/linux.c: Likewise. + + * loader/i386/pc/chainloader.c (pupa_chainloader_boot_sector): + Removed. + (pupa_chainloader_unload): Return PUPA_ERR_NONE. + (pupa_rescue_cmd_chainloader): Read the image to 0x7C00 instead + of PUPA_CHAINLOADER_BOOT_SECTOR. + + * kern/i386/pc/startup.S: Include pupa/machine/linux.h. + (pupa_linux_prot_size): New variable. + (pupa_linux_tmp_addr): Likewise. + (pupa_linux_real_addr): Likewise. + (pupa_linux_boot_zimage): New function. + (pupa_linux_boot_bzimage): Likewise. + + * kern/i386/pc/init.c (struct mem_region): New structure. + (MAX_REGIONS): New macro. + (mem_regions): New variable. + (num_regions): Likewise. + (pupa_os_area_addr): Likewise. + (pupa_os_area_size): Likewise. + (pupa_lower_mem): Likewise. + (pupa_upper_mem): Likewise. + (add_mem_region): New function. + (compact_mem_regions): Likewise. + (pupa_machine_init): Set PUPA_LOWER_MEM and PUPA_UPPER_MEM to + the size of the conventional memory and that of so-called upper + memory (before the first memory hole). + Instead of adding each found region to free memory, use + add_mem_region and add them after removing overlaps. + Also, add only 1/4 of the upper memory to free memory. The rest + is used for loading OS images. Maybe this is ad hoc, but this + makes it much easier to relocate OS images when booting. + + * kern/rescue.c (pupa_rescue_cmd_module): Removed. + (pupa_enter_rescue_mode): Don't register initrd and module. + + * kern/mm.c: Include pupa/dl.h. + + * kern/main.c: Include pupa/file.h and pupa/device.h. + + * kern/loader.c (pupa_loader_load_module_func): Removed. + (pupa_loader_load_module): Likewise. + + * kern/dl.c (pupa_dl_load): Use the suffix ``.mod'' instead of + ``.o''. + + * include/pupa/i386/pc/loader.h (pupa_linux_prot_size): Declared. + (pupa_linux_tmp_addr): Likewise. + (pupa_linux_real_addr): Likewise. + (pupa_linux_boot_zimage): Likewise. + (pupa_linux_boot_bzimage): Likewise. + + * include/pupa/i386/pc/init.h (pupa_lower_mem): Declared. + (pupa_upper_mem): Likewise. + (pupa_gate_a20): Don't export, because turning off Gate A20 in a + module is too dangerous. + + * include/pupa/loader.h (pupa_os_area_addr): Declared. + (pupa_os_area_size): Likewise. + (pupa_loader_set): Remove the first argument. Loader doesn't + manage modules or initrd any longer. + (pupa_loader_load_module): Removed. + + * conf/i386-pc.rmk (pkgdata_MODULES): Added linux.mod. + (linux_mod_SOURCES): New variable. + (linux_mod_CFLAGS): Likewise. + +2003-01-07 Yoshinori K. Okuji + + * util/i386/pc/pupa-setup.c (setup): Convert the endianness of + the length of a blocklist correctly. + + * util/i386/pc/biosdisk.c (pupa_util_biosdisk_open) [__linux__]: + Use ioctl only if the OS file is a block device. + (pupa_util_biosdisk_open): Don't use ST.ST_BLOCKS, because it is + not very useful for normal files. + + * kern/main.c (pupa_set_root_dev): New function. + (pupa_load_normal_mode): Likewise. + (pupa_main): Call those above. + + * include/pupa/types.h (pupa_swap_bytes16): Cast the result to + pupa_uint16_t. + + * include/pupa/kernel.h (pupa_enter_normal_mode): Removed. + +2003-01-06 Yoshinori K. Okuji + + * util/i386/pc/pupa-setup.c: Include pupa/machine/kernel.h. + (setup): Configure the installed partition information and the + dl prefix. + + * loader/i386/pc/chainloader.c (my_mod): New variable. + (pupa_chainloader_unload): New function. + (pupa_rescue_cmd_chainloader): Refer itself. + (PUPA_MOD_INIT): Save its own module in MY_MOD. + + * kern/i386/pc/startup.S (install_partition): Removed. + (version_string): Likewise. + (config_file): Likewise. + (pupa_install_dos_part): New variable. + (pupa_install_bsd_part): Likewise. + (pupa_prefix): Likewise. + (pupa_chainloader_real_boot): Call pupa_dl_unload_all. + + * kern/i386/pc/init.c: Include pupa/machine/kernel.h, pupa/dl.h + and pupa/misc.h. + (make_install_device): New function. + (pupa_machine_init): Set the dl prefix. + + * kern/rescue.c: Include pupa/rescue.h and pupa/dl.h. + (buf): Renamed to ... + (linebuf): ... this. + (pupa_rescue_cmd_prefix): New function. + (pupa_rescue_cmd_insmod): Likewise. + (pupa_rescue_cmd_rmmod): Likewise. + (pupa_rescue_cmd_lsmod): Likewise. + (pupa_enter_rescue_mode): Register new commands: prefix, insmod, + rmmod and lsmod. + + * kern/mm.c (pupa_memalign): If failed even after invalidating + disk caches, unload unneeded modules and retry. + + * kern/misc.c (pupa_memmove): New function. + (pupa_memcpy): Removed. + (pupa_strcpy): New function. + (pupa_itoa): Made static. + + * kern/dl.c (pupa_dl_iterate): New function. + (pupa_dl_ref): Likewise. + (pupa_dl_unref): Likewise. + (pupa_dl_unload): Return if succeeded or not. + (pupa_dl_unload_unneeded): New function. + (pupa_dl_unload_all): Likewise. + (pupa_dl_init): Renamed to ... + (pupa_dl_set_prefix): ... this. + (pupa_dl_get_prefix): New function. + + * include/pupa/i386/pc/kernel.h: Include pupa/types.h. + (PUPA_KERNEL_MACHINE_INSTALL_DOS_PART): New macro. + (PUPA_KERNEL_MACHINE_INSTALL_BSD_PART): Likewise. + (PUPA_KERNEL_MACHINE_PREFIX): Likewise. + (pupa_install_dos_part): Declared. + (pupa_install_bsd_part): Likewise. + (pupa_prefix): Likewise. + (pupa_boot_drive): Likewise. + + * include/pupa/types.h: Fix a typo. + + * include/pupa/misc.h (pupa_memcpy): New macro. Just an alias to + pupa_memmove. + (pupa_memmove): Declared. + (pupa_strcpy): Likewise. + + * include/pupa/dl.h (PUPA_MOD_INIT): Change the prototype. Now + pupa_mod_init takes one argument, its own module. + (pupa_dl_unload_unneeded): Declared. + (pupa_dl_unload_all): Likewise. + (pupa_dl_ref): Likewise. + (pupa_dl_unref): Likewise. + (pupa_dl_iterate): Likewise. + (pupa_dl_init): Renamed to ... + (pupa_dl_set_prefix): ... this. + (pupa_dl_get_prefix): Declared. + + * fs/fat.c [!PUPA_UTIL] (my_mod): New variable. + (pupa_fat_dir) [!PUPA_UTIL]: Prevent the fat module from being + unloaded. + (pupa_fat_open) [!PUPA_UTIL]: Refer itself if succeeded. + (pupa_fat_close) [!PUPA_UTIL]: Unrefer itself. + + * configure.ac (tmp_CFLAGS): Added -Wshadow, -Wpointer-arith, + -Wmissing-prototypes, -Wundef and -Wstrict-prototypes. + +2003-01-03 Yoshinori K. Okuji + + * util/i386/pc/pupa-setup.c (setup): Define the internal + function find_first_partition_start at the top level, because GCC + 3.0.x cannot compile internal functions in deeper scopes + correctly. + (find_root_device): Use lstat instead of stat. + Don't follow symbolic links. + Fix the path-constructing code. + + * util/i386/pc/biosdisk.c [__linux__] (BLKFLSBUF): New macro. + (pupa_util_biosdisk_open) [__linux__]: Get the size of a device + by a BLKGETSIZE ioctl first, because block devices don't fill + the member st_mode of the structure stat on Linux. + [__linux__] (linux_find_partition): Use a temporary buffer + REAL_DEV for the working space. Copy it to DEV before returning. + (open_device) [__linux__]: Call ioctl with BLKFLSBUF to make the + buffer cache consistent. + (get_os_disk) [__linux__]: Use the length 5 instead of 4 for + strncmp. The previous value was merely wrong. + (pupa_util_biosdisk_get_pupa_dev): Use stat instead of lstat. + + * fs/fat.c (pupa_fat_read_data): Shift 4 instead of 12 when the + FAT size is 12. The previous value was merely wrong. + + * kern/main.c (pupa_main): Don't split the starting message from + newlines. + + * kern/term.c (pupa_putchar): Put CR after LF instead of before + LF, because BIOS goes crazy about character attributes in this + case. + +2003-01-03 Yoshinori K. Okuji + + * include/i386/pc/util/biosdisk.h: New file. + * util/i386/pc/biosdisk.c: Likewise. + * util/i386/pc/pupa-setup.c: Likewise. + + * Makefile.in (INCLUDE_DISTFILES): Added + include/pupa/i386/pc/util/biosdisk.h. + (UTIL_DISTFILES): Added biosdisk.c and pupa-setup.c under the + directory util/i386/pc. + (install-local): Added a rule for sbin_UTILITIES. + (uninstall): Likewise. + + * util/i386/pc/pupa-mkimage.c (usage): Fix a typo in the doc. + + * util/misc.c (xrealloc): New function. + (pupa_malloc): Likewise. + (pupa_free): Likewise. + (pupa_realloc): Likewise. + (pupa_stop): Likewise. + (pupa_putchar): Likewise. + + * kern/disk.c (pupa_disk_read): Prevent L from underflowing. + + * include/pupa/util/misc.h (xrealloc): Declared. + + * include/pupa/i386/pc/boot.h (PUPA_BOOT_MACHINE_BPB_START): New + macro. + (PUPA_BOOT_MACHINE_BPBEND): Renamed to ... + (PUPA_BOOT_MACHINE_BPB_END): ... this. + + * include/pupa/fs.h [PUPA_UTIL] (pupa_fat_init): Declared. + [PUPA_UTIL] (pupa_fat_fini): Likewise. + + * fs/fat.c [PUPA_UTIL] (pupa_fat_init): Defined. Maybe a better + way should be implemented. + [PUPA_UTIL] (pupa_fat_fini): Likewise. + + * disk/i386/pc/biosdisk.c (pupa_biosdisk_call_hook): Increase + the size of NAME for safety. + (pupa_biosdisk_iterate): Search hard disks to 0x90 instead of + 0x88. + + * conf/i386-pc.rmk (sbin_UTILITIES): New variable. + (pupa_setup_SOURCES): Likewise. + + * genmk.rb (Utility#rule): Add $(BUILD_CFLAGS) into the rules. + +2002-12-28 Yoshinori K. Okuji + + * kern/i386/pc/startup.S (push_get_mmap_entry): Revert to a + bunch of pushl's from pusha, because this destroys the return + value. + +2002-12-28 Yoshinori K. Okuji + + Use -mrtd and -mregparm=3 to reduce the generated code sizes. + This means that any missing prototypes could be fatal. Also, you + must take care when writing assembly code. See the comments at + the beginning of startup.S, for more details. + + * kern/i386/pc/startup.S (pupa_halt): Modified for the new + compilation mechanism. + (pupa_chainloader_real_boot): Likewise. + (pupa_biosdisk_rw_int13_extensions): Likewise. + (pupa_biosdisk_rw_standard): Likewise. + (pupa_biosdisk_check_int13_extensions): Likewise. + (pupa_biosdisk_get_diskinfo_int13_extensions): Likewise. + (pupa_biosdisk_get_diskinfo_standard): Likewise. + (pupa_get_memsize): Likewise. + (pupa_get_mmap_entry): Likewise. + (pupa_console_putchar): Likewise. + (pupa_console_setcursor): Likewise. + (pupa_getrtsecs): Use pushl instead of push. + + * kern/i386/pc/init.c (pupa_machine_init): Use the scratch + memory instead of the stack for a mmap entry, because some + BIOSes may ignore the maximum size and overflow. + + * conf/i386-pc.rmk (COMMON_CFLAGS): Added -mrtd and -mregparm=3. + + * genmk.rb (PModule#rule): Compile automatically generated + sources with module-specific CFLAGS as well as other sources. + +2002-12-27 Yoshinori K. Okuji + + * configure.ac: Check ld. + Replace CFLAGS and CPPFLAGS with BUILD_CFLAGS and BUILD_CPPFLAGS + respectively, before checking endianness and sizes. + + * Makefile.in (LD): New variable. + +2002-12-27 Yoshinori K. Okuji + + * Makefile.in (BUILD_CC): CC -> BUILD_CC. + +2002-12-27 Yoshinori K. Okuji + + * Changelog: New file. + diff --git a/INSTALL b/INSTALL index 724584c57..0dd408bcc 100644 --- a/INSTALL +++ b/INSTALL @@ -4,10 +4,6 @@ This is the GRUB. Welcome. This file contains instructions for compiling and installing the GRUB. -Where this document refers to packages names, they are named according to the -Debian 11 package repositories. These packages can be found by searching -https://packages.debian.org/. - The Requirements ================ @@ -15,95 +11,24 @@ GRUB depends on some software packages installed into your system. If you don't have any of them, please obtain and install them before configuring the GRUB. -* GCC 5.1.0 or later - Experimental support for clang 8.0.0 or later (results in much bigger binaries) - for i386, x86_64, arm (including thumb), arm64, mips(el), powerpc, sparc64 +* GCC 4.1.3 or later * GNU Make * GNU Bison 2.3 or later -* GNU gettext +* GNU gettext 0.17 or later * GNU binutils 2.9.1.0.23 or later -* Flex 2.5.35 or later -* pkg-config -* GNU patch * Other standard GNU/Unix tools -* a libc with large file support (e.g. glibc 2.1 or later) - -On GNU/Linux, you also need: - -* libdevmapper 1.02.34 or later (recommended) - -For optional grub-emu features, you need: - -* SDL (recommended) -* libpciaccess (optional) - -To build GRUB's graphical terminal (gfxterm), you need: - -* FreeType 2.1.5 or later -* GNU Unifont - -To build grub-mkfont the unicode fonts are required (xfonts-unifont package -on Debian). If you use a development snapshot or want to hack on GRUB you may need the following. -* Python 3 (NOTE: python 2.6 should still work, but it's not tested) -* Autoconf 2.64 or later -* Automake 1.14 or later - -Your distro may package cross-compiling toolchains such as the following -incomplete list on Debian: gcc-aarch64-linux-gnu, gcc-arm-linux-gnueabihf, -gcc-mips-linux-gnu, gcc-mipsel-linux-gnu, gcc-powerpc64-linux-gnu, -gcc-riscv64-linux-gnu, gcc-sparc64-linux-gnu, mingw-w64 and mingw-w64-tools. - -More cross compiling toolchains can be found at the following trusted sites: - -* https://mirrors.kernel.org/pub/tools/crosstool/ -* https://toolchains.bootlin.com/ +* Ruby 1.6 or later +* Python 2.5.2 or later +* Autoconf 2.60 or later +* Automake 1.10.1 or later Prerequisites for make-check: -* qemu, specifically the binary "qemu-system-ARCH" where ARCH is the - architecture GRUB has been built for; the "qemu-system" package on Debian - will install all needed qemu architectures -* OVMF, for EFI platforms (packages ovmf, ovmf-ia32, qemu-efi-arm, and - qemu-efi-aarch64) -* OpenBIOS, for ieee1275 platforms (packages openbios-ppc and openbios-sparc) -* xorriso 1.2.9 or later, for grub-mkrescue and grub-shell -* wamerican, for grub-fs-tester -* mtools, FAT tools for EFI platforms -* xfonts-unifont, for the functional tests -* swtpm-tools and tpm2-tools, for TPM2 key protector tests - -* If running a Linux kernel the following modules must be loaded: - - fuse, loop - - btrfs, erofs, ext4, f2fs, fat, hfs, hfsplus, jfs, mac-roman, minix, nilfs2, - reiserfs, udf, xfs - - On newer kernels, the exfat kernel modules may be used instead of the - exfat FUSE filesystem -* The following are Debian named packages required mostly for the full - suite of filesystem testing (but some are needed by other tests as well): - - btrfs-progs, dosfstools, e2fsprogs, erofs-utils, exfatprogs, exfat-fuse, - f2fs-tools, genromfs, hfsprogs, jfsutils, nilfs-tools, ntfs-3g, - reiserfsprogs, squashfs-tools, reiserfsprogs, udftools, xfsprogs, zfs-fuse - - exfat-fuse, if not using the exfat kernel module - - gzip, lzop, xz-utils - - attr, cpio, g++, gawk, parted, recode, tar, util-linux - -Note that `make check' will run and many tests may complete successfully -with only a subset of these prerequisites. However, some tests may be -skipped or fail due to missing prerequisites. - -To build the documentation you'll need: -* texinfo, for the info and html documentation -* texlive, for building the dvi and pdf documentation (optional) - -To use the gdb_grub GDB script you'll need: -* readelf (binutils package) -* objdump (binutils package) -* GNU Debugger > 7, built with python support (gdb package) -* Python >= 3.5 (python3 package) +* qemu, specifically the binary 'qemu-system-i386' Configuring the GRUB ==================== @@ -134,17 +59,9 @@ Building the GRUB The simplest way to compile this package is: - 1. `cd' to the directory containing the package's source code. - - 2. Skip this and following step if you use release tarball and proceed to - step 4. If you want translations type `./linguas.sh'. - - 3. Type `./bootstrap'. - - The autogen.sh (called by bootstrap) uses python. By default autodetect - it, but it can be overridden by setting the PYTHON variable. - - 4. Type `./configure' to configure the package for your system. + 1. `cd' to the directory containing the package's source code. If + you don't use a release tarball you have to type `./autogen.sh'. + Type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. @@ -152,19 +69,15 @@ The simplest way to compile this package is: Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. - 6. Type `make' to compile the package. + 2. Type `make' to compile the package. - 7. Optionally, type `make check' to run any self-tests that come with - the package. Note that many of the tests require root privileges in - order to run. + 3. Optionally, type `make check' to run any self-tests that come with + the package. - 8. Type `make install' to install the programs and any data files and + 4. Type `make install' to install the programs and any data files and documentation. - 9. Type `make html' or `make pdf' to generate the html or pdf - documentation. Note, these are not built by default. - - 10. You can remove the program binaries and object files from the + 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is @@ -173,108 +86,6 @@ The simplest way to compile this package is: all sorts of other programs in order to regenerate files that came with the distribution. -Cross-compiling the GRUB -======================== - -GRUB defines 3 platforms: - - - "Build" is the one which build systems runs on. - - "Host" is where you execute GRUB utils. - - "Target" is where GRUB itself runs. - -For grub-emu host and target must be the same but may differ from build. - -If build and host are different make check isn't available. - -If build and host are different man pages are not generated. - -As an example imagine you have a build system running on FreeBSD on sparc -which prepares packages for developers running amd64 GNU/Linux laptop and -they need to make images for ARM board running U-boot. In this case: - -build=sparc64-freebsd -host=amd64-linux-gnu -target=arm-uboot - -For this example the configure line might look like (more details below) -(some options are optional and included here for completeness but some rarely -used options are omitted): - - ./configure --build=sparc64-freebsd --host=x86_64-linux-gnu \ - --target=arm-linux-gnueabihf --with-platform=efi \ - BUILD_CC=gcc BUILD_PKG_CONFIG=pkg-config \ - HOST_CC=x86_64-linux-gnu-gcc HOST_CFLAGS='-g -O2' \ - PKG_CONFIG=x86_64-linux-gnu-pkg-config TARGET_CC=arm-linux-gnueabihf-gcc \ - TARGET_CFLAGS='-Os -march=armv8.3-a' TARGET_CCASFLAGS='-march=armv8.3-a' \ - TARGET_OBJCOPY=arm-linux-gnueabihf-objcopy \ - TARGET_STRIP=arm-linux-gnueabihf-strip TARGET_NM=arm-linux-gnueabihf-nm \ - TARGET_RANLIB=arm-linux-gnueabihf-ranlib LEX=flex - -Note, that the autoconf 2.65 manual states that when using the --host argument -to configure, the --build argument should be specified as well. Not sending ---build, enters a compatibility mode that will be removed in the future. - -Normally, for building a GRUB on amd64 with tools to run on amd64 to -generate images to run on ARM, using your Linux distribution's -packaged cross compiler, the following would suffice: - - ./configure --target=arm-linux-gnueabihf --with-platform=efi - -You need to use following options to specify tools and platforms. For minimum -version look at prerequisites. All tools not mentioned in this section under -corresponding platform are not needed for the platform in question. - - - For build - 1. --build= to autoconf name of build. - 2. BUILD_CC= to gcc able to compile for build. This is used, for - example, to compile build-gentrigtables which is then run to - generate sin and cos tables. - 3. BUILD_CFLAGS= for C options for build. - 4. BUILD_CPPFLAGS= for C preprocessor options for build. - 5. BUILD_LDFLAGS= for linker options for build. - 6. BUILD_PKG_CONFIG= for pkg-config for build (optional). - - - For host - 1. --host= to autoconf name of host. - 2. CC= for gcc able to compile for host. - 3. CFLAGS= for C options for host. - 4. HOST_CC= for gcc able to compile for host. - 5. HOST_CFLAGS= for C options for host. - 6. HOST_CPPFLAGS= for C preprocessor options for host. - 7. HOST_LDFLAGS= for linker options for host. - 8. PKG_CONFIG= for pkg-config for host (optional). - 9. Libdevmapper if any must be in standard linker folders (-ldevmapper) (optional). - 10. Libfuse if any must be in standard linker folders (-lfuse) (optional). - 11. Libzfs if any must be in standard linker folders (-lzfs) (optional). - 12. Liblzma if any must be in standard linker folders (-llzma) (optional). - Note: The HOST_* variables override not prefixed variables. - - - For target - 1. --target= to autoconf cpu name of target. - 2. --with-platform to choose firmware. - 3. TARGET_CC= for gcc able to compile for target. - 4. TARGET_CFLAGS= for C options for target. - 5. TARGET_CPPFLAGS= for C preprocessor options for target. - 6. TARGET_CCASFLAGS= for assembler options for target. - 7. TARGET_LDFLAGS= for linker options for target. - 8. TARGET_OBJCOPY= for objcopy for target. - 9. TARGET_STRIP= for strip for target. - 10. TARGET_NM= for nm for target. - 11. TARGET_RANLIB= for ranlib for target. - Note: If the TARGET_* variables are not specified then they will default - to be the same as the host variables. If host variables are not - specified then the TARGET_* variables will default to be the same - as not prefixed variables. - - - Additionally for emu, for host and target. - 1. SDL is looked for in standard linker directories (-lSDL) (optional) - 2. libpciaccess is looked for in standard linker directories (-lpciaccess) (optional) - - - Platform-agnostic tools and data. - 1. make is the tool you execute after ./configure. - 2. Bison is specified in YACC= variable - 3. Flex is specified in LEX= variable - 4. GNU unifont and Djvu sans are looked for in standard directories. Compiling For Multiple Architectures ==================================== diff --git a/MAINTAINERS b/MAINTAINERS deleted file mode 100644 index 45e870c78..000000000 --- a/MAINTAINERS +++ /dev/null @@ -1,35 +0,0 @@ -List of current GRUB maintainers and some basic information about the project -============================================================================= - -Here is the list of current GRUB maintainers: - - Daniel Kiper and , - - Alex Burmashev , - - Vladimir 'phcoder' Serbinenko . - -The maintainers drive and overlook the GRUB development. - -If you found a security vulnerability in the GRUB please check the SECURITY -file to get more information how to properly report this kind of bugs to -the maintainers. - -The GRUB development happens on the grub-devel mailing list [1]. The latest -GRUB source code is available at Savannah git repository [2]. - -Users can ask for help on the help-grub mailing list [3]. - - -List of past GRUB maintainers and people who strongly contributed to the project -================================================================================ - -Here is the list, sorted alphabetically, of past GRUB maintainers and people who -strongly contributed to the project: - - Andrei Borzenkov, - - Bryan Ford, - - Erich Stefan Boleyn, - - Gordon Matzigkeit, - - Yoshinori K. Okuji. - - -[1] https://lists.gnu.org/mailman/listinfo/grub-devel -[2] https://git.savannah.gnu.org/gitweb/?p=grub.git&view=view+git+repository -[3] https://lists.gnu.org/mailman/listinfo/help-grub diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 43635d5ff..000000000 --- a/Makefile.am +++ /dev/null @@ -1,494 +0,0 @@ -AUTOMAKE_OPTIONS = subdir-objects -Wno-portability - -DEPDIR = .deps-util -SUBDIRS = grub-core/lib/gnulib . -if COND_real_platform -SUBDIRS += grub-core -endif -SUBDIRS += po docs util/bash-completion.d - -include $(top_srcdir)/conf/Makefile.common -include $(top_srcdir)/conf/Makefile.extra-dist - -AM_CFLAGS = $(HOST_CFLAGS) -AM_LDFLAGS = $(HOST_LDFLAGS) -AM_CPPFLAGS = $(HOST_CPPFLAGS) $(CPPFLAGS_DEFAULT) -AM_CCASFLAGS = $(HOST_CCASFLAGS) $(CCASFLAGS_DEFAULT) - -ACLOCAL_AMFLAGS = -I m4 - -CFLAGS_PROGRAM += $(CFLAGS_GNULIB) -LDFLAGS_PROGRAM += $(LDFLAGS_GNULIB) -CPPFLAGS_PROGRAM += $(CPPFLAGS_GNULIB) -CCASFLAGS_PROGRAM += $(CCASFLAGS_GNULIB) - -include $(srcdir)/Makefile.util.am - -check_SCRIPTS = $(check_SCRIPTS_native) $(check_SCRIPTS_nonnative) -check_PROGRAMS = $(check_PROGRAMS_native) $(check_PROGRAMS_nonnative) -TESTS = $(check_SCRIPTS) $(check_PROGRAMS) - -check-native: - $(MAKE) TESTS="$(check_PROGRAMS_native) $(check_SCRIPTS_native)" check -check-nonnative: - $(MAKE) TESTS="$(check_PROGRAMS_nonnative) $(check_SCRIPTS_nonnative)" check - -# XXX Use Automake's LEX & YACC support -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 -grub_script.tab.c: grub_script.tab.h -CLEANFILES += grub_script.tab.c grub_script.tab.h - -# For the lexer. -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 -grub_script.yy.c: grub_script.yy.h -CLEANFILES += grub_script.yy.c grub_script.yy.h - -# For libgrub.a -libgrub.pp: config-util.h grub_script.tab.h grub_script.yy.h $(libgrubmods_a_SOURCES) $(libgrubkern_a_SOURCES) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgrubmods_a_CPPFLAGS) $(libgrubkern_a_CPPFLAGS) $(CPPFLAGS) \ - -D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1) -CLEANFILES += libgrub.pp - -libgrub_a_init.lst: libgrub.pp - cat $< | grep '^@MARKER@' | sed 's/@MARKER@\(.*\)@/\1/g' | sort -u > $@ || (rm -f $@; exit 1) -CLEANFILES += libgrub_a_init.lst - -libgrub_a_init.c: libgrub_a_init.lst $(top_srcdir)/geninit.sh - sh $(top_srcdir)/geninit.sh `cat $<` > $@ || (rm -f $@; exit 1) -CLEANFILES += libgrub_a_init.c - -# For grub-fstest -grub_fstest.pp: config-util.h $(grub_fstest_SOURCES) - $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(grub_fstest_CPPFLAGS) $(CPPFLAGS) \ - -D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1) -CLEANFILES += grub_fstest.pp - -grub_fstest_init.lst: libgrub.pp grub_fstest.pp - cat $^ | grep '^@MARKER@' | sed 's/@MARKER@\(.*\)@/\1/g' | sort -u > $@ || (rm -f $@; exit 1) -CLEANFILES += grub_fstest_init.lst - -grub_fstest_init.c: grub_fstest_init.lst $(top_srcdir)/geninit.sh - sh $(top_srcdir)/geninit.sh `cat $<` > $@ || (rm -f $@; exit 1) -CLEANFILES += grub_fstest_init.c - -if COND_HAVE_FONT_SOURCE -pkgdata_DATA += unicode.pf2 ascii.pf2 euro.pf2 ascii.h widthspec.h -endif - -starfield_theme_files = $(srcdir)/themes/starfield/blob_w.png $(srcdir)/themes/starfield/boot_menu_c.png $(srcdir)/themes/starfield/boot_menu_e.png $(srcdir)/themes/starfield/boot_menu_ne.png $(srcdir)/themes/starfield/boot_menu_n.png $(srcdir)/themes/starfield/boot_menu_nw.png $(srcdir)/themes/starfield/boot_menu_se.png $(srcdir)/themes/starfield/boot_menu_s.png $(srcdir)/themes/starfield/boot_menu_sw.png $(srcdir)/themes/starfield/boot_menu_w.png $(srcdir)/themes/starfield/slider_c.png $(srcdir)/themes/starfield/slider_n.png $(srcdir)/themes/starfield/slider_s.png $(srcdir)/themes/starfield/starfield.png $(srcdir)/themes/starfield/terminal_box_c.png $(srcdir)/themes/starfield/terminal_box_e.png $(srcdir)/themes/starfield/terminal_box_ne.png $(srcdir)/themes/starfield/terminal_box_n.png $(srcdir)/themes/starfield/terminal_box_nw.png $(srcdir)/themes/starfield/terminal_box_se.png $(srcdir)/themes/starfield/terminal_box_s.png $(srcdir)/themes/starfield/terminal_box_sw.png $(srcdir)/themes/starfield/terminal_box_w.png $(srcdir)/themes/starfield/theme.txt $(srcdir)/themes/starfield/README $(srcdir)/themes/starfield/COPYING.CC-BY-SA-3.0 - -build-grub-mkfont$(BUILD_EXEEXT): util/grub-mkfont.c grub-core/unidata.c grub-core/kern/emu/misc.c util/misc.c - $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-mkfont\" $^ $(BUILD_FREETYPE_CFLAGS) $(BUILD_FREETYPE_LIBS) -CLEANFILES += build-grub-mkfont$(BUILD_EXEEXT) - -garbage-gen$(BUILD_EXEEXT): util/garbage-gen.c - $(BUILD_CC) -o $@ $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) $^ -CLEANFILES += garbage-gen$(BUILD_EXEEXT) -EXTRA_DIST += util/garbage-gen.c - -build-grub-gen-asciih$(BUILD_EXEEXT): util/grub-gen-asciih.c - $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 $^ $(BUILD_FREETYPE_CFLAGS) $(BUILD_FREETYPE_LIBS) -Wall -Werror -CLEANFILES += build-grub-gen-asciih$(BUILD_EXEEXT) - -build-grub-gen-widthspec$(BUILD_EXEEXT): util/grub-gen-widthspec.c - $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 $^ $(BUILD_FREETYPE_CFLAGS) $(BUILD_FREETYPE_LIBS) -Wall -Werror -CLEANFILES += build-grub-gen-widthspec$(BUILD_EXEEXT) - -if COND_STARFIELD -starfield_DATA = dejavu_10.pf2 dejavu_12.pf2 dejavu_bold_14.pf2 dejavu_14.pf2 dejavu_16.pf2 $(starfield_theme_files) -dejavu_10.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT) - ./build-grub-mkfont$(BUILD_EXEEXT) -s 10 -o $@ $(DJVU_FONT_SOURCE) -CLEANFILES += dejavu_10.pf2 -dejavu_12.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT) - ./build-grub-mkfont$(BUILD_EXEEXT) -s 12 -o $@ $(DJVU_FONT_SOURCE) -CLEANFILES += dejavu_12.pf2 -dejavu_14.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT) - ./build-grub-mkfont$(BUILD_EXEEXT) -s 14 -o $@ $(DJVU_FONT_SOURCE) -CLEANFILES += dejavu_14.pf2 -dejavu_bold_14.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT) - ./build-grub-mkfont$(BUILD_EXEEXT) -b -s 14 -o $@ $(DJVU_FONT_SOURCE) -CLEANFILES += dejavu_bold_14.pf2 -dejavu_16.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT) - ./build-grub-mkfont$(BUILD_EXEEXT) -s 16 -o $@ $(DJVU_FONT_SOURCE) -CLEANFILES += dejavu_16.pf2 -else -starfield_DATA = -endif - -EXTRA_DIST += $(starfield_theme_files) -EXTRA_DIST += $(srcdir)/themes/starfield/src/slider_s.xcf $(srcdir)/themes/starfield/src/slider_n.xcf $(srcdir)/themes/starfield/src/slider_c.xcf $(srcdir)/themes/starfield/src/blob_nw.xcf $(srcdir)/themes/starfield/src/bootmenu/center.xcf $(srcdir)/themes/starfield/src/bootmenu/corner.xcf $(srcdir)/themes/starfield/src/bootmenu/side.xcf $(srcdir)/themes/starfield/src/terminalbox/side.xcf $(srcdir)/themes/starfield/src/terminalbox/corner.xcf $(srcdir)/themes/starfield/src/terminalbox/center.xcf - -unicode.pf2: $(FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT) - ./build-grub-mkfont$(BUILD_EXEEXT) -o $@ $(FONT_SOURCE) || (rm -f $@; exit 1) -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) build-grub-mkfont$(BUILD_EXEEXT) - ./build-grub-mkfont$(BUILD_EXEEXT) -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1) -CLEANFILES += ascii.pf2 - -euro.pf2: $(FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT) - ./build-grub-mkfont$(BUILD_EXEEXT) -o $@ $(FONT_SOURCE) -r 0x0-0x4ff,0x1e00-0x1fff,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1) -CLEANFILES += euro.pf2 - -ascii.h: $(FONT_SOURCE) build-grub-gen-asciih$(BUILD_EXEEXT) - ./build-grub-gen-asciih$(BUILD_EXEEXT) $(FONT_SOURCE) $@ || (rm -f $@; exit 1) -CLEANFILES += ascii.h - -widthspec.h: $(FONT_SOURCE) build-grub-gen-widthspec$(BUILD_EXEEXT) - ./build-grub-gen-widthspec$(BUILD_EXEEXT) $(FONT_SOURCE) $@ || (rm -f $@; exit 1) -CLEANFILES += widthspec.h - -# Install config.h into platformdir -nodist_platform_HEADERS = config.h - -pkgdata_DATA += grub-mkconfig_lib - - -if COND_real_platform - -if COND_i386_coreboot -QEMU32=qemu-system-i386 -MINIMUM_CPU_LINUX=pentium2 -endif - -if COND_i386_multiboot -QEMU32=qemu-system-i386 -MINIMUM_CPU_LINUX=pentium2 -endif - -if COND_i386_ieee1275 -QEMU32=qemu-system-i386 -MINIMUM_CPU_LINUX=pentium2 -endif - -if COND_i386_qemu -QEMU32=qemu-system-i386 -MINIMUM_CPU_LINUX=pentium2 -endif - -if COND_i386_pc -QEMU32=qemu-system-i386 -MINIMUM_CPU_LINUX=pentium2 -endif - -if COND_i386_efi -QEMU32=qemu-system-i386 -MINIMUM_CPU_LINUX=pentium2 -endif - -if COND_x86_64_efi -QEMU32=qemu-system-x86_64 -MINIMUM_CPU_LINUX=core2duo -endif - -linux.init.x86_64: $(srcdir)/grub-core/tests/boot/linux.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S - $(TARGET_CC) -o $@ $< -static -m64 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" - -linux.init.i386: $(srcdir)/grub-core/tests/boot/linux.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S - $(TARGET_CC) -o $@ $< -static -m32 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" - -linux.init.mips: $(srcdir)/grub-core/tests/boot/linux.init-mips.S - $(TARGET_CC) -o $@ $< -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" - -linux.init.ppc: $(srcdir)/grub-core/tests/boot/linux.init-ppc.S - $(TARGET_CC) -o $@ $< -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" - -linux.init.mipsel: $(srcdir)/grub-core/tests/boot/linux.init-mips.S - $(TARGET_CC) -o $@ $< -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" - -linux.init.loongson: $(srcdir)/grub-core/tests/boot/linux.init-mips.S - $(TARGET_CC) -o $@ $< -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -DREBOOT=1 - -multiboot.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S - $(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -static -ffreestanding -nostdlib -nostdinc -DTARGET_MULTIBOOT=1 -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include - -kfreebsd.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S - $(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -static -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include - -kfreebsd.aout: kfreebsd.elf - $(TARGET_OBJCOPY) -O a.out-i386-linux $< $@ -j .text - -pc-chainloader.elf: $(srcdir)/grub-core/tests/boot/kernel-8086.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S - $(TARGET_CC) -o $@ $< -static -DTARGET_CHAINLOADER=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x7c00 -m32 - -pc-chainloader.bin: pc-chainloader.elf - $(TARGET_OBJCOPY) -O binary --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn -R .note.gnu.gold-version $< $@; - -ntldr.elf: $(srcdir)/grub-core/tests/boot/kernel-8086.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S - $(TARGET_CC) -o $@ $< -DTARGET_NTLDR=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -static -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0 -m32 - -ntldr.bin: ntldr.elf - $(TARGET_OBJCOPY) -O binary --strip-unneeded -j .text $< $@; - -multiboot2.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S - $(TARGET_CC) -static -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include -DTARGET_MULTIBOOT2=1 - -kfreebsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kfreebsd.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S - $(TARGET_CC) -o $@ $< -m64 -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" && freebsd-brandelf -t FreeBSD $@ - -kfreebsd.init.i386: $(srcdir)/grub-core/tests/boot/kfreebsd.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S - $(TARGET_CC) -o $@ $< -m32 -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" && freebsd-brandelf -t FreeBSD $@ - -knetbsd.init.i386: $(srcdir)/grub-core/tests/boot/kbsd.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S - $(TARGET_CC) -o $@ $< -m32 -static -nostdlib -nostdinc -DTARGET_NETBSD=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" - -kopenbsd.init.i386: $(srcdir)/grub-core/tests/boot/kbsd.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S - $(TARGET_CC) -o $@ $< -m32 -static -nostdlib -nostdinc -DTARGET_OPENBSD=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" - -knetbsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kbsd.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S - $(TARGET_CC) -o $@ $< -m64 -DTARGET_NETBSD=1 -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" - -kopenbsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kbsd.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S - $(TARGET_CC) -o $@ $< -m64 -DTARGET_OPENBSD=1 -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" - -linux-initramfs.mips: linux.init.mips Makefile - TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio -R 0:0 --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR - -linux-initramfs.ppc: linux.init.ppc Makefile - TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio -R 0:0 --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR - -linux-initramfs.mipsel: linux.init.mipsel Makefile - TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio -R 0:0 --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR - -linux-initramfs.loongson: linux.init.loongson Makefile - TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio -R 0:0 --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR - -linux-initramfs.i386: linux.init.i386 Makefile - TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio -R 0:0 --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR - -linux-initramfs.x86_64: linux.init.x86_64 Makefile - TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && cp $< $$TDIR/init && (cd $$TDIR && echo ./init | cpio -R 0:0 --quiet --dereference -o -H newc) | gzip > $@ && rm -rf $$TDIR - -kfreebsd-mfsroot.i386.img: kfreebsd.init.i386 Makefile - TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -t ffs -s 30m -f 1000 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR - -knetbsd.image.i386: knetbsd.init.i386 $(srcdir)/grub-core/tests/boot/kbsd.spec.txt - TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 64k -f 10 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR - -kopenbsd.image.i386: kopenbsd.init.i386 $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt - TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 128k -f 10 -o minfree=0,version=1 $@ $$TDIR && bsdlabel -f -R $@ $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt && rm -rf $$TDIR || rm -f $@ - -kopenbsd.image.x86_64: kopenbsd.init.x86_64 $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt - TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 128k -f 10 -o minfree=0,version=1 $@ $$TDIR && bsdlabel -f -R $@ $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt && rm -rf $$TDIR || rm -f $@ - -knetbsd.miniroot-image.i386.img: knetbsd.image.i386 $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.i386 - $(TARGET_OBJCOPY) --add-section=miniroot=$< $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.i386 $@ - -kfreebsd-mfsroot.x86_64.img: kfreebsd.init.x86_64 Makefile - TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -t ffs -s 30m -f 1000 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR - -knetbsd.image.x86_64: knetbsd.init.x86_64 $(srcdir)/grub-core/tests/boot/kbsd.spec.txt - TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 64k -f 10 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR - -knetbsd.miniroot-image.x86_64.img: knetbsd.image.x86_64 $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.x86_64 - $(TARGET_OBJCOPY) --add-section=miniroot=$< $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.x86_64 $@ - -CLEANFILES += linux.init.i386 kfreebsd.init.i386 linux.init.x86_64 linux-initramfs.i386 linux-initramfs.x86_64 - -kfreebsd-mfsroot.i386.gz: kfreebsd-mfsroot.i386.img - gzip < $< > $@ - -bootcheck-kfreebsd-i386: kfreebsd-mfsroot.i386.gz $(GRUB_PAYLOADS_DIR)/kfreebsd.i386 $(GRUB_PAYLOADS_DIR)/kfreebsd_env.i386 $(srcdir)/grub-core/tests/boot/kfreebsd.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/mfsroot.gz=kfreebsd-mfsroot.i386.gz --files=/kfreebsd=$(GRUB_PAYLOADS_DIR)/kfreebsd.i386 --files=/kfreebsd_env=$(GRUB_PAYLOADS_DIR)/kfreebsd_env.i386 $(srcdir)/grub-core/tests/boot/kfreebsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -kfreebsd-mfsroot.x86_64.gz: kfreebsd-mfsroot.x86_64.img - gzip < $< > $@ - -bootcheck-kfreebsd-x86_64: kfreebsd-mfsroot.x86_64.gz $(GRUB_PAYLOADS_DIR)/kfreebsd.x86_64 $(GRUB_PAYLOADS_DIR)/kfreebsd_env.x86_64 $(srcdir)/grub-core/tests/boot/kfreebsd.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/mfsroot.gz=kfreebsd-mfsroot.x86_64.gz --files=/kfreebsd=$(GRUB_PAYLOADS_DIR)/kfreebsd.x86_64 --files=/kfreebsd_env=$(GRUB_PAYLOADS_DIR)/kfreebsd_env.x86_64 $(srcdir)/grub-core/tests/boot/kfreebsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -knetbsd.miniroot-image.i386.gz: knetbsd.miniroot-image.i386.img - gzip < $< > $@ - -bootcheck-knetbsd-i386: knetbsd.miniroot-image.i386.gz $(GRUB_PAYLOADS_DIR)/knetbsd.i386 $(srcdir)/grub-core/tests/boot/knetbsd.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/miniroot.gz=knetbsd.miniroot-image.i386.gz --files=/knetbsd=$(GRUB_PAYLOADS_DIR)/knetbsd.i386 $(srcdir)/grub-core/tests/boot/knetbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -bootcheck-kopenbsd-i386: kopenbsd.image.i386 $(GRUB_PAYLOADS_DIR)/kopenbsd.i386 $(srcdir)/grub-core/tests/boot/kopenbsd.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/ramdisk=kopenbsd.image.i386 --files=/kopenbsd=$(GRUB_PAYLOADS_DIR)/kopenbsd.i386 $(srcdir)/grub-core/tests/boot/kopenbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -bootcheck-kopenbsd-x86_64: kopenbsd.image.x86_64 $(GRUB_PAYLOADS_DIR)/kopenbsd.x86_64 $(srcdir)/grub-core/tests/boot/kopenbsd.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/ramdisk=kopenbsd.image.x86_64 --files=/kopenbsd=$(GRUB_PAYLOADS_DIR)/kopenbsd.x86_64 $(srcdir)/grub-core/tests/boot/kopenbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -knetbsd.miniroot-image.x86_64.gz: knetbsd.miniroot-image.x86_64.img - gzip < $< > $@ - -bootcheck-knetbsd-x86_64: knetbsd.miniroot-image.x86_64.gz $(GRUB_PAYLOADS_DIR)/knetbsd.x86_64 $(srcdir)/grub-core/tests/boot/knetbsd.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/miniroot.gz=knetbsd.miniroot-image.x86_64.gz --files=/knetbsd=$(GRUB_PAYLOADS_DIR)/knetbsd.x86_64 $(srcdir)/grub-core/tests/boot/knetbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -bootcheck-linux-i386: linux-initramfs.i386 $(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/initrd=linux-initramfs.i386 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/grub-core/tests/boot/linux.cfg --qemu-opts="-cpu $(MINIMUM_CPU_LINUX)" | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -bootcheck-linux-x86_64: linux-initramfs.x86_64 $(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/initrd=linux-initramfs.x86_64 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/grub-core/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -bootcheck-linux-mips: linux-initramfs.mips $(GRUB_PAYLOADS_DIR)/linux.mips $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --files=/initrd=linux-initramfs.mips --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.mips $(srcdir)/grub-core/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -bootcheck-linux-ppc: linux-initramfs.ppc $(GRUB_PAYLOADS_DIR)/linux.ppc $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --files=/initrd=linux-initramfs.ppc --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.ppc $(srcdir)/grub-core/tests/boot/linux-ppc.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -bootcheck-linux-mipsel: linux-initramfs.mipsel $(GRUB_PAYLOADS_DIR)/linux.mipsel $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --files=/initrd=linux-initramfs.mipsel --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.mipsel $(srcdir)/grub-core/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -bootcheck-linux-loongson: linux-initramfs.loongson $(GRUB_PAYLOADS_DIR)/linux.loongson $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --files=/initrd=linux-initramfs.loongson --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.loongson $(srcdir)/grub-core/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -bootcheck-linux16-i386: linux-initramfs.i386 $(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/initrd=linux-initramfs.i386 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/grub-core/tests/boot/linux16.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -bootcheck-linux16-x86_64: linux-initramfs.x86_64 $(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/initrd=linux-initramfs.x86_64 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/grub-core/tests/boot/linux16.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -bootcheck-multiboot: multiboot.elf $(srcdir)/grub-core/tests/boot/multiboot.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/multiboot.elf=multiboot.elf $(srcdir)/grub-core/tests/boot/multiboot.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -bootcheck-multiboot2: multiboot2.elf $(srcdir)/grub-core/tests/boot/multiboot2.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/multiboot2.elf=multiboot2.elf $(srcdir)/grub-core/tests/boot/multiboot2.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -bootcheck-kfreebsd-aout: kfreebsd.aout $(srcdir)/grub-core/tests/boot/kfreebsd-aout.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/kfreebsd.aout=kfreebsd.aout $(srcdir)/grub-core/tests/boot/kfreebsd-aout.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -bootcheck-pc-chainloader: pc-chainloader.bin $(srcdir)/grub-core/tests/boot/pc-chainloader.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/pc-chainloader.bin=pc-chainloader.bin $(srcdir)/grub-core/tests/boot/pc-chainloader.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -bootcheck-ntldr: ntldr.bin $(srcdir)/grub-core/tests/boot/ntldr.cfg grub-shell - ./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/ntldr.bin=ntldr.bin $(srcdir)/grub-core/tests/boot/ntldr.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null - -if COND_i386_efi -# NetBSD has no support for finding ACPI on EFI -BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-kfreebsd-x86_64 bootcheck-kfreebsd-i386 -endif - -if COND_x86_64_efi -# NetBSD has no support for finding ACPI on EFI -BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-kfreebsd-x86_64 bootcheck-kfreebsd-i386 -endif - -if COND_i386_multiboot -# *BSD requires ACPI -BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 -endif - - -if COND_i386_qemu -# *BSD requires ACPI -BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 -endif - -if COND_i386_coreboot -BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-knetbsd-x86_64 bootcheck-kfreebsd-x86_64 bootcheck-kfreebsd-i386 -endif - -if COND_i386_ieee1275 -# *BSD requires ACPI -#legacy protocol (linux16) makes early BIOS calls. -BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 -endif - -if COND_i386_pc -#pc chainloader by definition is only for i386-pc -#ntldr and bootmgr require BIOS. -#legacy protocol (linux16) makes early BIOS calls. -# 32-bit NetBSD crashes early on non-BIOS -BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-knetbsd-x86_64 bootcheck-kfreebsd-x86_64 bootcheck-kfreebsd-i386 bootcheck-pc-chainloader bootcheck-ntldr bootcheck-linux16-i386 bootcheck-linux16-x86_64 bootcheck-knetbsd-i386 -endif - -if COND_mips_loongson -BOOTCHECKS = bootcheck-linux-loongson -endif - -if COND_mipsel -if COND_mips_qemu_mips -BOOTCHECKS = bootcheck-linux-mipsel -endif -endif -if COND_mipseb -if COND_mips_qemu_mips -BOOTCHECKS = bootcheck-linux-mips -endif -endif - -if COND_powerpc_ieee1275 -BOOTCHECKS = bootcheck-linux-ppc -endif - -.PHONY: bootcheck-linux-i386 bootcheck-linux-x86_64 \ - bootcheck-kfreebsd-i386 bootcheck-kfreebsd-x86_64 \ - bootcheck-knetbsd-i386 bootcheck-knetbsd-x86_64 \ - bootcheck-linux-mips FORCE - -# Randomly generated -SUCCESSFUL_BOOT_STRING=3e49994fd5d82b7c9298d672d774080d -# tianocore cd access is very slow -BOOTCHECK_TIMEOUT=180 - -bootcheck: $(BOOTCHECKS) - -if COND_i386_coreboot -FS_PAYLOAD_MODULES ?= $(shell cat grub-core/fs.lst) -default_payload.elf: grub-mkstandalone grub-mkimage FORCE - test -f $@ && rm $@ || true - pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu $(FS_PAYLOAD_MODULES) password_pbkdf2 $(EXTRA_PAYLOAD_MODULES)' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg -endif - -endif - -EXTRA_DIST += grub-core/tests/boot/kbsd.init-i386.S grub-core/tests/boot/kbsd.init-x86_64.S grub-core/tests/boot/kbsd.spec.txt grub-core/tests/boot/kernel-8086.S grub-core/tests/boot/kernel-i386.S grub-core/tests/boot/kfreebsd-aout.cfg grub-core/tests/boot/kfreebsd.cfg grub-core/tests/boot/kfreebsd.init-i386.S grub-core/tests/boot/kfreebsd.init-x86_64.S grub-core/tests/boot/knetbsd.cfg grub-core/tests/boot/kopenbsd.cfg grub-core/tests/boot/kopenbsdlabel.txt grub-core/tests/boot/linux16.cfg grub-core/tests/boot/linux.cfg grub-core/tests/boot/linux.init-i386.S grub-core/tests/boot/linux.init-mips.S grub-core/tests/boot/linux.init-ppc.S grub-core/tests/boot/linux.init-x86_64.S grub-core/tests/boot/linux-ppc.cfg grub-core/tests/boot/multiboot2.cfg grub-core/tests/boot/multiboot.cfg grub-core/tests/boot/ntldr.cfg grub-core/tests/boot/pc-chainloader.cfg grub-core/tests/boot/qemu-shutdown-x86.S - -windowsdir=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows -windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA) - test -d $(windowsdir) && rm -rf $(windowsdir) || true - test -d $(windowsdir) || mkdir $(windowsdir) - $(MAKE) -C po $(AM_MAKEFLAGS) windowsdir - $(MAKE) -C grub-core $(AM_MAKEFLAGS) windowsdir - test -d $(windowsdir)/themes || mkdir $(windowsdir)/themes - test -d $(windowsdir)/themes/starfield || mkdir $(windowsdir)/themes/starfield - for x in $(PROGRAMS); do \ - if [ x$(STRIP) != x ]; then $(STRIP) $$x -o $(windowsdir)/$$x; \ - else cp -fp $$x $(windowsdir)/$$x; fi; \ - done - for x in $(pkgdata_DATA); do \ - cp -fp $$x $(windowsdir)/$$x; \ - done - for x in $(starfield_DATA); do \ - cp -fp $$x $(windowsdir)/themes/starfield/$$(basename $$x); \ - done - for x in $(GRUB_WINDOWS_EXTRA_DIST); do \ - cp -fp $$x $(windowsdir); \ - done - -windowszip=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows.zip -windowszip: windowsdir - test -f $(windowszip) && rm $(windowszip) || true - zip -r $(windowszip) $(windowsdir) - rm -rf $(windowsdir) - -EXTRA_DIST += linguas.sh - -changelog_start_date = 2015-01-23 -gitlog_to_changelog = $(top_srcdir)/build-aux/gitlog-to-changelog - -ChangeLog: FORCE - if test -d $(top_srcdir)/.git; then \ - $(gitlog_to_changelog) --srcdir=$(top_srcdir) --since=$(changelog_start_date) > '$@.tmp'; \ - rm -f '$@'; mv '$@.tmp' '$@'; \ - else \ - touch $@; \ - fi - -syslinux_test: $(top_builddir)/config.status tests/syslinux/ubuntu10.04_grub.cfg - -# Mimic simplify_filename from grub-core/lib/syslinux_parse.c, so that we -# can predict its behaviour in tests. We have to pre-substitute this before -# calling config.status, as config.status offers no reliable way to hook in -# a command between setting ac_abs_top_srcdir and emitting output files. -tests/syslinux/ubuntu10.04_grub.cfg: $(top_builddir)/config.status tests/syslinux/ubuntu10.04_grub.cfg.in - simplified_abs_top_srcdir=`echo "$(abs_top_srcdir)" | sed 's,//,/,g; s,/\./,/,g; :loop; s,/[^/][^/]*/\.\.\(/\|$$\),\1,; t loop'`; \ - sed "s,@simplified_abs_top_srcdir@,$$simplified_abs_top_srcdir,g" $(srcdir)/tests/syslinux/ubuntu10.04_grub.cfg.in | $(top_builddir)/config.status --file=$@:- -CLEANFILES += tests/syslinux/ubuntu10.04_grub.cfg diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 000000000..47584cdde --- /dev/null +++ b/Makefile.in @@ -0,0 +1,544 @@ +# -*- 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@ +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@ + +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) + +CC = @CC@ +CFLAGS = @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 = @TARGET_CFLAGS@ +TARGET_ASFLAGS = @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 = @TARGET_LDFLAGS@ +TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@ +TARGET_IMG_LDFLAGS = @TARGET_IMG_LDFLAGS@ +TARGET_IMG_CFLAGS = @TARGET_IMG_CFLAGS@ +TARGET_OBJ2ELF = @TARGET_OBJ2ELF@ +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@ +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 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 $(addprefix $(srcdir)/,$(MKFILES)) \ + $(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 + +### General targets. + +CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA) po/*.mo +pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst +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) $(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)'; 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)'; 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,.*/,,'`"; \ + echo rm -f $(DESTDIR)$(libdir)/$$dest; \ + 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) + +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 $@ -f $< --keyword=_ --keyword=N_ + cd $(srcdir) && $(XGETTEXT) -ctranslate --from-code=utf-8 -o $@ -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: diff --git a/Makefile.util.def b/Makefile.util.def deleted file mode 100644 index 038253b37..000000000 --- a/Makefile.util.def +++ /dev/null @@ -1,1470 +0,0 @@ -AutoGen definitions Makefile.tpl; - -library = { - name = libgrubkern.a; - cflags = '$(CFLAGS_GNULIB)'; - cppflags = '$(CPPFLAGS_GNULIB) -I$(srcdir)/grub-core/lib/json'; - - common = util/misc.c; - common = grub-core/kern/command.c; - common = grub-core/kern/device.c; - common = grub-core/kern/disk.c; - common = grub-core/lib/disk.c; - common = util/getroot.c; - common = grub-core/osdep/unix/getroot.c; - common = grub-core/osdep/getroot.c; - common = grub-core/osdep/devmapper/getroot.c; - common = grub-core/osdep/relpath.c; - extra_dist = grub-core/kern/disk_common.c; - extra_dist = grub-core/osdep/unix/relpath.c; - extra_dist = grub-core/osdep/aros/relpath.c; - extra_dist = grub-core/osdep/windows/relpath.c; - common = grub-core/kern/emu/hostdisk.c; - common = grub-core/osdep/devmapper/hostdisk.c; - common = grub-core/osdep/hostdisk.c; - common = grub-core/osdep/unix/hostdisk.c; - common = grub-core/osdep/exec.c; - common = grub-core/osdep/sleep.c; - common = grub-core/osdep/password.c; - common = grub-core/kern/emu/misc.c; - common = grub-core/kern/emu/mm.c; - common = grub-core/kern/env.c; - common = grub-core/kern/err.c; - common = grub-core/kern/file.c; - common = grub-core/kern/fs.c; - common = grub-core/kern/list.c; - common = grub-core/kern/misc.c; - common = grub-core/kern/partition.c; - common = grub-core/lib/crypto.c; - common = grub-core/lib/json/json.c; - common = grub-core/disk/luks.c; - common = grub-core/disk/luks2.c; - common = grub-core/disk/geli.c; - common = grub-core/disk/key_protector.c; - common = grub-core/disk/cryptodisk.c; - common = grub-core/disk/AFSplitter.c; - common = grub-core/lib/pbkdf2.c; - common = grub-core/commands/extcmd.c; - common = grub-core/lib/arg.c; - common = grub-core/disk/ldm.c; - common = grub-core/disk/diskfilter.c; - common = grub-core/partmap/gpt.c; - common = grub-core/partmap/msdos.c; - common = grub-core/fs/proc.c; - common = grub-core/fs/archelp.c; -}; - -library = { - name = libgrubmods.a; - cflags = '-fno-builtin -Wno-undef -Wno-unused-but-set-variable'; - cppflags = '-I$(srcdir)/grub-core/lib/minilzo -I$(srcdir)/grub-core/lib/xzembed -I$(srcdir)/grub-core/lib/zstd -DMINILZO_HAVE_CONFIG_H'; - - common_nodist = grub_script.tab.c; - common_nodist = grub_script.yy.c; - common_nodist = libgrub_a_init.c; - common_nodist = grub_script.yy.h; - common_nodist = grub_script.tab.h; - - common = grub-core/commands/blocklist.c; - common = grub-core/commands/macbless.c; - common = grub-core/commands/xnu_uuid.c; - common = grub-core/commands/testload.c; - common = grub-core/commands/ls.c; - common = grub-core/disk/dmraid_nvidia.c; - common = grub-core/disk/loopback.c; - common = grub-core/disk/lvm.c; - common = grub-core/disk/mdraid_linux.c; - common = grub-core/disk/mdraid_linux_be.c; - common = grub-core/disk/mdraid1x_linux.c; - common = grub-core/disk/raid5_recover.c; - common = grub-core/disk/raid6_recover.c; - common = grub-core/font/font.c; - common = grub-core/gfxmenu/font.c; - common = grub-core/normal/charset.c; - common = grub-core/video/fb/fbblit.c; - common = grub-core/video/fb/fbutil.c; - common = grub-core/video/fb/fbfill.c; - common = grub-core/video/fb/video_fb.c; - common = grub-core/video/video.c; - common = grub-core/video/capture.c; - common = grub-core/video/colors.c; - common = grub-core/unidata.c; - common = grub-core/io/bufio.c; - common = grub-core/fs/affs.c; - common = grub-core/fs/afs.c; - common = grub-core/fs/bfs.c; - common = grub-core/fs/btrfs.c; - common = grub-core/fs/cbfs.c; - common = grub-core/fs/cpio.c; - common = grub-core/fs/cpio_be.c; - common = grub-core/fs/odc.c; - common = grub-core/fs/newc.c; - common = grub-core/fs/erofs.c; - common = grub-core/fs/ext2.c; - common = grub-core/fs/fat.c; - common = grub-core/fs/exfat.c; - common = grub-core/fs/f2fs.c; - common = grub-core/fs/fshelp.c; - common = grub-core/fs/hfs.c; - common = grub-core/fs/hfsplus.c; - common = grub-core/fs/hfspluscomp.c; - common = grub-core/fs/iso9660.c; - common = grub-core/fs/jfs.c; - common = grub-core/fs/minix.c; - common = grub-core/fs/minix2.c; - common = grub-core/fs/minix3.c; - common = grub-core/fs/minix_be.c; - common = grub-core/fs/minix2_be.c; - common = grub-core/fs/minix3_be.c; - common = grub-core/fs/nilfs2.c; - common = grub-core/fs/ntfs.c; - common = grub-core/fs/ntfscomp.c; - common = grub-core/fs/reiserfs.c; - common = grub-core/fs/romfs.c; - common = grub-core/fs/sfs.c; - common = grub-core/fs/squash4.c; - common = grub-core/fs/tar.c; - common = grub-core/fs/udf.c; - common = grub-core/fs/ufs2.c; - common = grub-core/fs/ufs.c; - common = grub-core/fs/ufs_be.c; - common = grub-core/fs/xfs.c; - common = grub-core/fs/zfs/zfscrypt.c; - common = grub-core/fs/zfs/zfs.c; - common = grub-core/fs/zfs/zfsinfo.c; - common = grub-core/fs/zfs/zfs_lzjb.c; - common = grub-core/fs/zfs/zfs_lz4.c; - common = grub-core/fs/zfs/zfs_sha256.c; - common = grub-core/fs/zfs/zfs_fletcher.c; - common = grub-core/lib/envblk.c; - common = grub-core/lib/hexdump.c; - common = grub-core/lib/LzFind.c; - common = grub-core/lib/LzmaEnc.c; - common = grub-core/lib/crc.c; - common = grub-core/lib/adler32.c; - common = grub-core/lib/crc64.c; - common = grub-core/lib/datetime.c; - common = grub-core/normal/misc.c; - common = grub-core/partmap/acorn.c; - common = grub-core/partmap/amiga.c; - common = grub-core/partmap/apple.c; - common = grub-core/partmap/sun.c; - common = grub-core/partmap/plan.c; - common = grub-core/partmap/dvh.c; - common = grub-core/partmap/sunpc.c; - common = grub-core/partmap/bsdlabel.c; - common = grub-core/partmap/dfly.c; - common = grub-core/script/function.c; - common = grub-core/script/lexer.c; - common = grub-core/script/main.c; - common = grub-core/script/script.c; - common = grub-core/script/argv.c; - common = grub-core/io/gzio.c; - common = grub-core/io/xzio.c; - common = grub-core/io/lzopio.c; - common = grub-core/kern/ia64/dl_helper.c; - common = grub-core/kern/arm/dl_helper.c; - common = grub-core/kern/arm64/dl_helper.c; - common = grub-core/kern/loongarch64/dl_helper.c; - common = grub-core/lib/minilzo/minilzo.c; - common = grub-core/lib/xzembed/xz_dec_bcj.c; - common = grub-core/lib/xzembed/xz_dec_lzma2.c; - common = grub-core/lib/xzembed/xz_dec_stream.c; - common = grub-core/lib/zstd/debug.c; - common = grub-core/lib/zstd/entropy_common.c; - common = grub-core/lib/zstd/error_private.c; - common = grub-core/lib/zstd/fse_decompress.c; - common = grub-core/lib/zstd/huf_decompress.c; - common = grub-core/lib/zstd/module.c; - common = grub-core/lib/zstd/xxhash.c; - common = grub-core/lib/zstd/zstd_common.c; - common = grub-core/lib/zstd/zstd_decompress.c; -}; - -program = { - name = grub-mkimage; - mansection = 1; - - common = util/grub-mkimage.c; - common = util/mkimage.c; - common = util/grub-mkimage32.c; - common = util/grub-mkimage64.c; - common = util/resolve.c; - common = grub-core/kern/emu/argp_common.c; - common = grub-core/osdep/init.c; - common = grub-core/osdep/config.c; - extra_dist = grub-core/osdep/aros/config.c; - extra_dist = grub-core/osdep/windows/config.c; - extra_dist = grub-core/osdep/unix/config.c; - common = util/config.c; - - extra_dist = util/grub-mkimagexx.c; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBLZMA)'; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - name = grub-protect; - mansection = 1; - - common = grub-core/kern/emu/argp_common.c; - common = grub-core/osdep/init.c; - common = grub-core/lib/tss2/buffer.c; - common = grub-core/lib/tss2/tss2_mu.c; - common = grub-core/lib/tss2/tpm2_cmd.c; - common = grub-core/commands/tpm2_key_protector/args.c; - common = grub-core/commands/tpm2_key_protector/tpm2key_asn1_tab.c; - common = util/grub-protect.c; - common = util/probe.c; - - cflags = '-I$(srcdir)/grub-core/lib/tss2 -I$(srcdir)/grub-core/commands/tpm2_key_protector'; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBTASN1)'; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - - condition = COND_GRUB_PROTECT; -}; - -program = { - name = grub-mkrelpath; - mansection = 1; - - common = util/grub-mkrelpath.c; - common = grub-core/kern/emu/argp_common.c; - common = grub-core/osdep/init.c; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - name = grub-script-check; - mansection = 1; - - common = util/grub-script-check.c; - common = grub-core/kern/emu/argp_common.c; - common = grub-core/osdep/init.c; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - name = grub-editenv; - mansection = 1; - - common = util/grub-editenv.c; - common = util/editenv.c; - common = util/grub-install-common.c; - common = grub-core/osdep/init.c; - common = grub-core/osdep/compress.c; - extra_dist = grub-core/osdep/unix/compress.c; - extra_dist = grub-core/osdep/basic/compress.c; - common = util/mkimage.c; - common = util/grub-mkimage32.c; - common = util/grub-mkimage64.c; - common = grub-core/osdep/config.c; - common = util/config.c; - common = util/resolve.c; - - ldadd = '$(LIBLZMA)'; - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - name = grub-mkpasswd-pbkdf2; - mansection = 1; - - common = util/grub-mkpasswd-pbkdf2.c; - common = grub-core/kern/emu/argp_common.c; - common = grub-core/osdep/random.c; - common = grub-core/osdep/init.c; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - name = grub-macho2img; - mansection = 1; - common = util/grub-macho2img.c; - condition = COND_APPLE_LINKER; -}; - -program = { - name = grub-fstest; - mansection = 1; - common_nodist = grub_fstest_init.c; - common = util/grub-fstest.c; - common = grub-core/kern/emu/hostfs.c; - common = grub-core/disk/host.c; - common = grub-core/osdep/init.c; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - name = grub-mount; - mansection = 1; - common_nodist = grub_fstest_init.c; - common = util/grub-mount.c; - common = grub-core/kern/emu/hostfs.c; - common = grub-core/disk/host.c; - common = grub-core/osdep/init.c; - - cflags = '$(FUSE_CFLAGS)'; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM) $(FUSE_LIBS)'; - condition = COND_GRUB_MOUNT; -}; - -program = { - name = grub-mkfont; - mansection = 1; - common = util/grub-mkfont.c; - common = grub-core/kern/emu/argp_common.c; - common = grub-core/osdep/init.c; - - cflags = '$(FREETYPE_CFLAGS)'; - cppflags = '-DGRUB_MKFONT=1'; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(FREETYPE_LIBS)'; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - condition = COND_GRUB_MKFONT; -}; - -program = { - name = grub-probe; - installdir = sbin; - mansection = 8; - common = util/grub-probe.c; - common = util/probe.c; - common = grub-core/osdep/ofpath.c; - common = grub-core/kern/emu/argp_common.c; - common = grub-core/osdep/init.c; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - name = grub-bios-setup; - installdir = sbin; - mansection = 8; - common = util/grub-setup.c; - common = util/setup_bios.c; - extra_dist = util/setup.c; - common = grub-core/kern/emu/argp_common.c; - common = grub-core/lib/reed_solomon.c; - common = grub-core/osdep/blocklist.c; - extra_dist = grub-core/osdep/generic/blocklist.c; - extra_dist = grub-core/osdep/linux/blocklist.c; - extra_dist = grub-core/osdep/windows/blocklist.c; - common = grub-core/osdep/init.c; - - ldadd = libgrubmods.a; - ldadd = libgrubkern.a; - ldadd = libgrubgcry.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - cppflags = '-DGRUB_SETUP_FUNC=grub_util_bios_setup'; -}; - -program = { - name = grub-sparc64-setup; - installdir = sbin; - mansection = 8; - common = util/grub-setup.c; - common = util/setup_sparc.c; - common = grub-core/kern/emu/argp_common.c; - common = grub-core/lib/reed_solomon.c; - common = grub-core/osdep/ofpath.c; - common = grub-core/osdep/blocklist.c; - common = grub-core/osdep/init.c; - - ldadd = libgrubmods.a; - ldadd = libgrubkern.a; - ldadd = libgrubgcry.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - cppflags = '-DGRUB_SETUP_FUNC=grub_util_sparc_setup'; -}; - -program = { - name = grub-ofpathname; - installdir = sbin; - mansection = 8; - common = util/ieee1275/grub-ofpathname.c; - common = grub-core/osdep/ofpath.c; - common = grub-core/osdep/init.c; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - name = grub-mklayout; - mansection = 1; - - common = util/grub-mklayout.c; - common = grub-core/kern/emu/argp_common.c; - common = grub-core/osdep/init.c; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - name = grub-macbless; - installdir = sbin; - mansection = 8; - common = util/grub-macbless.c; - common = grub-core/osdep/init.c; - common = grub-core/kern/emu/argp_common.c; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -data = { - common = util/grub.d/README; - installdir = grubconf; -}; - -script = { - name = '00_header'; - common = util/grub.d/00_header.in; - installdir = grubconf; -}; - -script = { - name = '10_windows'; - common = util/grub.d/10_windows.in; - installdir = grubconf; - condition = COND_HOST_WINDOWS; -}; - -script = { - name = '10_hurd'; - common = util/grub.d/10_hurd.in; - installdir = grubconf; - condition = COND_HOST_HURD; -}; - -script = { - name = '10_kfreebsd'; - common = util/grub.d/10_kfreebsd.in; - installdir = grubconf; - condition = COND_HOST_KFREEBSD; -}; - -script = { - name = '10_illumos'; - common = util/grub.d/10_illumos.in; - installdir = grubconf; - condition = COND_HOST_ILLUMOS; -}; - -script = { - name = '10_netbsd'; - common = util/grub.d/10_netbsd.in; - installdir = grubconf; - condition = COND_HOST_NETBSD; -}; - -script = { - name = '10_linux'; - common = util/grub.d/10_linux.in; - installdir = grubconf; - condition = COND_HOST_LINUX; -}; - -script = { - name = '10_xnu'; - common = util/grub.d/10_xnu.in; - installdir = grubconf; - condition = COND_HOST_XNU; -}; - -script = { - name = '20_linux_xen'; - common = util/grub.d/20_linux_xen.in; - installdir = grubconf; - condition = COND_HOST_LINUX; -}; - -script = { - name = '25_bli'; - common = util/grub.d/25_bli.in; - installdir = grubconf; -}; - -script = { - name = '30_os-prober'; - common = util/grub.d/30_os-prober.in; - installdir = grubconf; -}; - -script = { - name = '30_uefi-firmware'; - common = util/grub.d/30_uefi-firmware.in; - installdir = grubconf; -}; - -script = { - name = '40_custom'; - common = util/grub.d/40_custom.in; - installdir = grubconf; -}; - -script = { - name = '41_custom'; - common = util/grub.d/41_custom.in; - installdir = grubconf; -}; - -program = { - mansection = 1; - name = grub-mkrescue; - - common = util/grub-mkrescue.c; - common = util/render-label.c; - common = util/glue-efi.c; - common = util/mkimage.c; - common = util/grub-mkimage32.c; - common = util/grub-mkimage64.c; - common = util/grub-install-common.c; - common = util/setup_bios.c; - common = util/setup_sparc.c; - common = grub-core/lib/reed_solomon.c; - common = grub-core/osdep/random.c; - common = grub-core/osdep/ofpath.c; - common = grub-core/osdep/platform.c; - common = grub-core/osdep/platform_unix.c; - common = grub-core/osdep/compress.c; - extra_dist = grub-core/osdep/unix/compress.c; - extra_dist = grub-core/osdep/basic/compress.c; - common = util/editenv.c; - common = grub-core/osdep/blocklist.c; - common = grub-core/osdep/config.c; - common = util/config.c; - - common = grub-core/kern/emu/hostfs.c; - common = grub-core/disk/host.c; - - common = util/resolve.c; - - common = grub-core/kern/emu/argp_common.c; - common = grub-core/osdep/init.c; - - ldadd = '$(LIBLZMA)'; - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - - condition = COND_HAVE_EXEC; -}; - -program = { - mansection = 1; - name = grub-mkstandalone; - common = util/grub-mkstandalone.c; - - common = util/render-label.c; - common = util/glue-efi.c; - common = util/mkimage.c; - common = util/grub-mkimage32.c; - common = util/grub-mkimage64.c; - common = util/grub-install-common.c; - common = util/setup_bios.c; - common = util/setup_sparc.c; - common = grub-core/lib/reed_solomon.c; - common = grub-core/osdep/random.c; - common = grub-core/osdep/ofpath.c; - common = grub-core/osdep/platform.c; - common = grub-core/osdep/platform_unix.c; - extra_dist = grub-core/osdep/linux/platform.c; - extra_dist = grub-core/osdep/windows/platform.c; - extra_dist = grub-core/osdep/basic/platform.c; - extra_dist = grub-core/osdep/basic/no_platform.c; - extra_dist = grub-core/osdep/unix/platform.c; - common = grub-core/osdep/compress.c; - common = util/editenv.c; - common = grub-core/osdep/blocklist.c; - common = grub-core/osdep/config.c; - common = util/config.c; - - common = grub-core/kern/emu/hostfs.c; - common = grub-core/disk/host.c; - - common = util/resolve.c; - - common = grub-core/kern/emu/argp_common.c; - common = grub-core/osdep/init.c; - - ldadd = '$(LIBLZMA)'; - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - mansection = 8; - installdir = sbin; - name = grub-install; - - common = util/grub-install.c; - common = util/probe.c; - common = util/mkimage.c; - common = util/grub-mkimage32.c; - common = util/grub-mkimage64.c; - common = util/grub-install-common.c; - common = util/setup_bios.c; - common = util/setup_sparc.c; - common = grub-core/lib/reed_solomon.c; - common = grub-core/osdep/random.c; - common = grub-core/osdep/ofpath.c; - common = grub-core/osdep/platform.c; - common = grub-core/osdep/platform_unix.c; - common = grub-core/osdep/compress.c; - common = util/editenv.c; - common = grub-core/osdep/blocklist.c; - common = grub-core/osdep/config.c; - common = util/config.c; - common = util/render-label.c; - common = grub-core/kern/emu/hostfs.c; - common = grub-core/disk/host.c; - - common = util/resolve.c; - common = grub-core/kern/emu/argp_common.c; - common = grub-core/osdep/init.c; - - ldadd = '$(LIBLZMA)'; - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - mansection = 1; - installdir = bin; - name = grub-mknetdir; - - common = util/grub-mknetdir.c; - - common = util/mkimage.c; - common = util/grub-mkimage32.c; - common = util/grub-mkimage64.c; - common = util/grub-install-common.c; - common = util/setup_bios.c; - common = util/setup_sparc.c; - common = grub-core/lib/reed_solomon.c; - common = grub-core/osdep/random.c; - common = grub-core/osdep/ofpath.c; - common = grub-core/osdep/platform.c; - common = grub-core/osdep/platform_unix.c; - common = grub-core/osdep/compress.c; - common = util/editenv.c; - common = grub-core/osdep/blocklist.c; - common = grub-core/osdep/config.c; - common = util/config.c; - - common = util/resolve.c; - common = grub-core/kern/emu/argp_common.c; - common = grub-core/osdep/init.c; - - ldadd = '$(LIBLZMA)'; - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -script = { - name = grub-mkconfig; - common = util/grub-mkconfig.in; - mansection = 8; - installdir = sbin; -}; - -script = { - name = grub-set-default; - common = util/grub-set-default.in; - mansection = 8; - installdir = sbin; -}; - -script = { - name = grub-reboot; - common = util/grub-reboot.in; - mansection = 8; - installdir = sbin; -}; - -script = { - name = grub-mkconfig_lib; - common = util/grub-mkconfig_lib.in; - installdir = noinst; -}; - -script = { - name = grub-kbdcomp; - common = util/grub-kbdcomp.in; - mansection = 1; -}; - -script = { - name = grub-shell; - common = tests/util/grub-shell.in; - installdir = noinst; -}; - -script = { - name = grub-shell-tester; - common = tests/util/grub-shell-tester.in; - installdir = noinst; -}; - -script = { - name = grub-shell-luks-tester; - common = tests/util/grub-shell-luks-tester.in; - installdir = noinst; -}; - -script = { - name = grub-fs-tester; - common = tests/util/grub-fs-tester.in; - installdir = noinst; - dependencies = 'garbage-gen$(BUILD_EXEEXT)'; -}; - -script = { - testcase = native; - name = erofs_test; - common = tests/erofs_test.in; -}; - -script = { - testcase = native; - name = ext234_test; - common = tests/ext234_test.in; -}; - -script = { - testcase = native; - name = squashfs_test; - common = tests/squashfs_test.in; -}; - -script = { - testcase = native; - name = iso9660_test; - common = tests/iso9660_test.in; -}; - -script = { - testcase = native; - name = hfsplus_test; - common = tests/hfsplus_test.in; -}; - -script = { - testcase = native; - name = ntfs_test; - common = tests/ntfs_test.in; -}; - -script = { - testcase = native; - name = reiserfs_test; - common = tests/reiserfs_test.in; -}; - -script = { - testcase = native; - name = fat_test; - common = tests/fat_test.in; -}; - -script = { - testcase = native; - name = minixfs_test; - common = tests/minixfs_test.in; -}; - -script = { - testcase = native; - name = xfs_test; - common = tests/xfs_test.in; -}; - -script = { - testcase = native; - name = f2fs_test; - common = tests/f2fs_test.in; -}; - -script = { - testcase = native; - name = nilfs2_test; - common = tests/nilfs2_test.in; -}; - -script = { - testcase = native; - name = romfs_test; - common = tests/romfs_test.in; -}; - -script = { - testcase = native; - name = exfat_test; - common = tests/exfat_test.in; -}; - -script = { - testcase = native; - name = tar_test; - common = tests/tar_test.in; -}; - -script = { - testcase = native; - name = udf_test; - common = tests/udf_test.in; -}; - -script = { - testcase = native; - name = hfs_test; - common = tests/hfs_test.in; -}; - -script = { - testcase = native; - name = jfs_test; - common = tests/jfs_test.in; -}; - -script = { - testcase = native; - name = btrfs_test; - common = tests/btrfs_test.in; -}; - -script = { - testcase = native; - name = zfs_test; - common = tests/zfs_test.in; -}; - -script = { - testcase = native; - name = cpio_test; - common = tests/cpio_test.in; -}; - -script = { - testcase = native; - name = example_scripted_test; - common = tests/example_scripted_test.in; -}; - -script = { - testcase = native; - name = gettext_strings_test; - common = tests/gettext_strings_test.in; - extra_dist = po/exclude.pot; -}; - -script = { - testcase = nonnative; - name = pata_test; - common = tests/pata_test.in; -}; - -script = { - testcase = nonnative; - name = ahci_test; - common = tests/ahci_test.in; -}; - -script = { - testcase = nonnative; - name = uhci_test; - common = tests/uhci_test.in; -}; - -script = { - testcase = nonnative; - name = ohci_test; - common = tests/ohci_test.in; -}; - -script = { - testcase = nonnative; - name = ehci_test; - common = tests/ehci_test.in; -}; - -script = { - testcase = nonnative; - name = example_grub_script_test; - common = tests/example_grub_script_test.in; -}; - -script = { - testcase = nonnative; - name = grub_script_eval; - common = tests/grub_script_eval.in; -}; - -script = { - testcase = nonnative; - name = grub_script_test; - common = tests/grub_script_test.in; -}; - -script = { - testcase = nonnative; - name = grub_script_echo1; - common = tests/grub_script_echo1.in; -}; - -script = { - testcase = nonnative; - name = grub_script_leading_whitespace; - common = tests/grub_script_leading_whitespace.in; -}; - -script = { - testcase = nonnative; - name = grub_script_echo_keywords; - common = tests/grub_script_echo_keywords.in; -}; - -script = { - testcase = nonnative; - name = grub_script_vars1; - common = tests/grub_script_vars1.in; -}; - -script = { - testcase = nonnative; - name = grub_script_for1; - common = tests/grub_script_for1.in; -}; - -script = { - testcase = nonnative; - name = grub_script_while1; - common = tests/grub_script_while1.in; -}; - -script = { - testcase = nonnative; - name = grub_script_if; - common = tests/grub_script_if.in; -}; - -script = { - testcase = native; - name = grub_script_blanklines; - common = tests/grub_script_blanklines.in; -}; - -script = { - testcase = native; - name = grub_script_final_semicolon; - common = tests/grub_script_final_semicolon.in; -}; - -script = { - testcase = native; - name = grub_script_dollar; - common = tests/grub_script_dollar.in; -}; - -script = { - testcase = nonnative; - name = grub_script_comments; - common = tests/grub_script_comments.in; -}; - -script = { - testcase = nonnative; - name = grub_script_functions; - common = tests/grub_script_functions.in; -}; - -script = { - testcase = nonnative; - name = grub_script_break; - common = tests/grub_script_break.in; -}; - -script = { - testcase = nonnative; - name = grub_script_continue; - common = tests/grub_script_continue.in; -}; - -script = { - testcase = nonnative; - name = grub_script_shift; - common = tests/grub_script_shift.in; -}; - -script = { - testcase = nonnative; - name = grub_script_blockarg; - common = tests/grub_script_blockarg.in; -}; - -script = { - testcase = nonnative; - name = grub_script_setparams; - common = tests/grub_script_setparams.in; -}; - -script = { - testcase = nonnative; - name = grub_script_return; - common = tests/grub_script_return.in; -}; - -script = { - testcase = nonnative; - name = grub_cmd_cryptomount; - common = tests/grub_cmd_cryptomount.in; -}; - -script = { - testcase = nonnative; - name = grub_cmd_regexp; - common = tests/grub_cmd_regexp.in; -}; - -script = { - testcase = nonnative; - name = grub_cmd_date; - common = tests/grub_cmd_date.in; -}; - -script = { - testcase = nonnative; - name = grub_cmd_set_date; - common = tests/grub_cmd_set_date.in; -}; - -script = { - testcase = nonnative; - name = grub_cmd_sleep; - common = tests/grub_cmd_sleep.in; -}; - -script = { - testcase = nonnative; - name = grub_script_expansion; - common = tests/grub_script_expansion.in; -}; - -script = { - testcase = nonnative; - name = grub_script_not; - common = tests/grub_script_not.in; -}; - -script = { - testcase = native; - name = grub_script_no_commands; - common = tests/grub_script_no_commands.in; -}; - -script = { - testcase = nonnative; - name = partmap_test; - common = tests/partmap_test.in; -}; - -script = { - testcase = nonnative; - name = hddboot_test; - common = tests/hddboot_test.in; -}; - -script = { - testcase = nonnative; - name = fddboot_test; - common = tests/fddboot_test.in; -}; - -script = { - testcase = nonnative; - name = cdboot_test; - common = tests/cdboot_test.in; -}; - -script = { - testcase = nonnative; - name = netboot_test; - common = tests/netboot_test.in; -}; - -script = { - testcase = nonnative; - name = serial_test; - common = tests/serial_test.in; -}; - -script = { - testcase = nonnative; - name = pseries_test; - common = tests/pseries_test.in; -}; - -script = { - testcase = nonnative; - name = core_compress_test; - common = tests/core_compress_test.in; -}; - -script = { - testcase = nonnative; - name = xzcompress_test; - common = tests/xzcompress_test.in; -}; - -script = { - testcase = nonnative; - name = gzcompress_test; - common = tests/gzcompress_test.in; -}; - -script = { - testcase = nonnative; - name = lzocompress_test; - common = tests/lzocompress_test.in; -}; - -script = { - testcase = nonnative; - name = grub_cmd_echo; - common = tests/grub_cmd_echo.in; -}; - -script = { - testcase = nonnative; - name = help_test; - common = tests/help_test.in; -}; - -script = { - testcase = nonnative; - name = grub_script_gettext; - common = tests/grub_script_gettext.in; -}; - -script = { - testcase = nonnative; - name = grub_script_escape_comma; - common = tests/grub_script_escape_comma.in; -}; - -script = { - testcase = nonnative; - name = grub_script_strcmp; - common = tests/grub_script_strcmp.in; -}; - -script = { - testcase = nonnative; - name = test_sha512sum; - common = tests/test_sha512sum.in; -}; - -script = { - testcase = nonnative; - name = test_unset; - common = tests/test_unset.in; -}; - -script = { - testcase = nonnative; - name = grub_func_test; - common = tests/grub_func_test.in; -}; - -script = { - testcase = nonnative; - name = grub_cmd_tr; - common = tests/grub_cmd_tr.in; -}; - -script = { - testcase = nonnative; - name = file_filter_test; - common = tests/file_filter_test.in; -}; - -script = { - testcase = nonnative; - name = grub_cmd_test; - common = tests/grub_cmd_test.in; -}; - -script = { - testcase = native; - name = syslinux_test; - common = tests/syslinux_test.in; -}; - -script = { - testcase = native; - name = luks1_test; - common = tests/luks1_test.in; -}; - -script = { - testcase = native; - name = luks2_test; - common = tests/luks2_test.in; -}; - -script = { - testcase = native; - name = asn1_test; - common = tests/asn1_test.in; -}; - -script = { - testcase = native; - name = tpm2_key_protector_test; - common = tests/tpm2_key_protector_test.in; -}; - -program = { - testcase = native; - name = example_unit_test; - common = tests/example_unit_test.c; - common = tests/lib/unit_test.c; - common = grub-core/kern/list.c; - common = grub-core/kern/misc.c; - common = grub-core/tests/lib/test.c; - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - testcase = native; - name = printf_test; - common = tests/printf_unit_test.c; - common = tests/lib/unit_test.c; - common = grub-core/kern/list.c; - common = grub-core/kern/misc.c; - common = grub-core/tests/lib/test.c; - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - testcase = native; - name = date_test; - common = tests/date_unit_test.c; - common = tests/lib/unit_test.c; - common = grub-core/kern/list.c; - common = grub-core/kern/misc.c; - common = grub-core/tests/lib/test.c; - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - testcase = native; - name = priority_queue_unit_test; - common = tests/priority_queue_unit_test.cc; - common = tests/lib/unit_test.c; - common = grub-core/kern/list.c; - common = grub-core/kern/misc.c; - common = grub-core/tests/lib/test.c; - common = grub-core/lib/priority_queue.c; - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - condition = COND_HAVE_CXX; -}; - -program = { - testcase = native; - name = cmp_test; - common = tests/cmp_unit_test.c; - common = tests/lib/unit_test.c; - common = grub-core/kern/list.c; - common = grub-core/kern/misc.c; - common = grub-core/tests/lib/test.c; - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - name = grub-menulst2cfg; - mansection = 1; - common = util/grub-menulst2cfg.c; - common = grub-core/lib/legacy_parse.c; - common = grub-core/lib/i386/pc/vesa_modes_table.c; - common = grub-core/osdep/init.c; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - name = grub-syslinux2cfg; - mansection = 1; - common = util/grub-syslinux2cfg.c; - common = grub-core/lib/syslinux_parse.c; - common = grub-core/lib/getline.c; - common = grub-core/osdep/init.c; - common = grub-core/kern/emu/hostfs.c; - common = grub-core/disk/host.c; - common = grub-core/kern/emu/argp_common.c; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - name = grub-glue-efi; - mansection = 1; - - common = util/grub-glue-efi.c; - common = util/glue-efi.c; - common = grub-core/kern/emu/argp_common.c; - common = grub-core/osdep/init.c; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - name = grub-render-label; - mansection = 1; - - common = util/grub-render-label.c; - common = util/render-label.c; - common = grub-core/kern/emu/argp_common.c; - common = grub-core/kern/emu/hostfs.c; - common = grub-core/disk/host.c; - common = grub-core/osdep/init.c; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - -program = { - name = grub-file; - mansection = 1; - - common = util/grub-file.c; - common = util/render-label.c; - common = grub-core/commands/file.c; - common = grub-core/commands/file32.c; - common = grub-core/commands/file64.c; - common = grub-core/loader/i386/xen_file.c; - common = grub-core/loader/i386/xen_file32.c; - common = grub-core/loader/i386/xen_file64.c; - common = grub-core/io/offset.c; - common = grub-core/kern/elf.c; - common = grub-core/loader/lzss.c; - common = grub-core/loader/macho.c; - common = grub-core/loader/macho32.c; - common = grub-core/loader/macho64.c; - common = grub-core/kern/emu/hostfs.c; - common = grub-core/disk/host.c; - common = grub-core/osdep/init.c; - - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; diff --git a/NEWS b/NEWS index 310130962..1e3334f18 100644 --- a/NEWS +++ b/NEWS @@ -1,492 +1,3 @@ -New in 2.12: - -* GCC 13 support. -* clang 14 support. -* binutils 2.38 support. -* Unification of EFI Linux kernel loader across architectures. -* Transition to EFI Linux kernel stub loader for x86 architecture. -* Initial support for Boot Loader Interface. -* Support for dynamic GRUB runtime memory addition using firmware calls. -* PCI and MMIO UARTs support. -* SDL2 support. -* LoongArch support. -* TPM driver fixes. -* Many filesystems fixes. -* Many CVE and Coverity fixes. -* Debugging support improvements. -* Tests improvements. -* Documentation improvements. -* ...and tons of other fixes and cleanups... - -New in 2.06: - -* GCC 10 support. -* clang 10 support. -* SBAT support. -* LUKS2 support. -* Drop small MBR gap support. -* Xen Security Modules (XSM/FLASK) support. -* The lockdown mechanism similar to the Linux kernel one. -* Disable the os-prober by default. -* Many backports of GRUB distros specific patches. -* BootHole and BootHole2 fixes. -* ...and tons of other fixes and cleanups... - -New in 2.04: - -* GCC 8 and 9 support. -* Gnulib integration overhaul. -* RISC-V support. -* Xen PVH support. -* Native UEFI secure boot support. -* UEFI TPM driver. -* New IEEE 1275 obdisk driver. -* Btrfs RAID 5 and RIAD 6 support. -* PARTUUID support. -* VLAN support. -* Native DHCP support. -* Many ARM and ARM64 fixes. -* Many SPARC fixes. -* Many IEEE 1275 fixes. -* ...and tons of other fixes and cleanups... - -New in 2.02: - -* New/improved filesystem and disk support: - * Big-endian UFS1. - * Experimental 64-bit ext2 support. - * Various fixes for non-512-byte sector devices. - * New `proc' filesystem framework, used by LUKS disks. - * Fix DM-RAID partition handling. - * New `nativedisk' command to switch from firmware to native disk drivers. - * Compressed HFS+. - * DragonFly BSD labels. - * CBFS (coreboot). - * Handle partitioned LVM properly. - * Use LVM UUIDs whenever possible. - * GPT PReP. - * New `progress' module that shows progress information while reading - files. - * ZFS features support. - * ZFS LZ4 support. - * XFS V5 format support. - * LVM RAID1 support. - -* New/improved terminal and video support: - * Monochrome text (matching `hercules' in GRUB Legacy). - * Morse code output using system speaker. - * `spkmodem' output (simple data protocol using system speaker). - * Handle Japanese special keys. - * coreboot framebuffer. - * Serial on ARC. - * Native vt100 handling for grub-emu, replacing the use of the curses - library. - * New gfxmenu options for terminal window positioning, theme background - image handling, and scrollbar padding, plus `item_pixmap_style' and - `highlight_overlay'. - * Support several more image types (paletted and greyscale). - -* Boot protocol improvements: - * Support Apple FAT binaries on non-Apple platforms. - * Improve FreeDOS direct loading support compatibility. - * Enable `linux16' on all x86 platforms, not just BIOS. - * New TrueCrypt ISO loader. - * multiboot2 boot-services EFI specification. - * multiboot2 EFI memory map specification. - * multiboot2 full-file specfication. - -* New/improved network support: - * New variables `net_default_*' containing properties of the default - interface. - * Autoload `http' and `tftp' modules if necessary. - * Improve TFTP robustness. - * Parse `nd' disk names in GRUB Legacy configuration files. - * Issue separate DNS queries for IPv4 and IPv6. - * Support IPv6 Router Advertisement to configure default router. - * New variable net__next_server containing next server - from BOOTP reply. - -* Coreboot improvements: - * CBFS support both in on-disk images (loopback) and flash. - * Ability to launch another payload from flash or disk - * Coreboot framebuffer - * CBMEMC support (both logging and inspecting logs) - * Command for inspecting coreboot timestamps (`coreboot_boottime'). - * Command for inspecting coreboot tables (`lscoreboot'). - * New target default_payload.elf. - * Increased maximal core size. - * Prefer pmtimer for TSC calibration. - -* New/improved platform support: - * New `efifwsetup' and `lsefi' commands on EFI platforms. - * New `cmosdump' and `cmosset' commands on platforms with CMOS support. - * New command `pcidump' for PCI platforms. - * Improve opcode parsing in ACPI halt implementation. - * Use the TSC as a possible time source on i386-ieee1275. - * Merge PowerPC grub-mkrescue implementation with the common one. - * Support grub-mkrescue on i386-ieee1275, sparc64, bootinfo machines such - as pSeries, and mips-arc. - * Make grub-mkrescue better support Apple Intel Macs on CD. - * Enable GRUB Legacy configuration file parsing on EFI. - * Support halt for Loongson 2E. - * ARM U-Boot and EFI ports. - * Reorganise platform-dependent code in utilities to avoid #ifdef mess. - * AROS and Haiku support for userspace utilities. - * Xen PV port. - * Fix EFI stack alignment. - * ARM64 EFI port. - * On Linux, read partition start offsets from sysfs if possible. - * New grub-macbless utility, and better integration with Mac firmware in - grub-install. - * Support Yeeloong 3A. - * Add `cpuid --pae' option to detect Physical Address Extension on x86. - * Support for USB debug dongles. - * Support for *-emu on all platforms (previously only i386/x86_64 worked). - * Support *-emu on Windows. - * New platform `none' which builds only user level utilities. This is now - default if target CPU is not supported. - * Support for booting little-endian Linux kernel on powerpc. - * Support network boot with Oracle sun4v vnet devices. - * Added SAS disks to the IEEE 1275 Open Firmware device list. - * Try multiple methods for TSC (timestamp counter) calibration - PIT, pmtimer, - EFI Stall. If everything fails, use hardcoded frequency 800MHz. - * Support Hyper-V Gen2 platforms which lack PIT for TSC calibration. - * Map UEFI Persistent Memory to E820 persistent memory. - * New Xen loader on ARM64. - * Respect alignment requirement for block device IO buffers on EFI. - -* Security: - * Add optional facility to enforce that all files read by the core image - from disk have a valid detached digital signature. - -* Performance: - * Avoid costly division operations in many places. - * New boot time analysis framework (`./configure --enable-boot-time'). - * Initialise USB ports in parallel. - * New `testspeed' command to test file read speed. - * Speed-up gfxterm by storing intermediate results in more compact format. - * Lazy LVM/mdraid scan. - * Disk hints. - -* Scripting: - * New `eval' and `tr' commands. - * grub-script-check fails on scripts containing no commands. - -* Installation and other utility improvements: - * Add option to compress files on installation or image creation. - * Using grub-reboot no longer requires setting `GRUB_DEFAULT=saved'. - * Support probing EFI System Partition (requires os-prober >= 1.58). - * Fix inconsistent use of `GRUB_CRYPTODISK_ENABLE' and - `GRUB_ENABLE_CRYPTODISK'; the latter is now used consistently. - * grub-mount handles symbolic links to directories. - * Support disabling submenus with `GRUB_DISABLE_SUBMENU' configuration key - for grub-mkconfig. - * grub-install, grub-mknetdir, grub-mkrescue, and grub-mkstandalone - rewritten in C. They should now work in supported non-Unix-like - environments. - * Native mingw support. - * Ability to install on EFI under windows. - * Reorganise timeout handling using new `timeout_style' environment - variable and `GRUB_TIMEOUT_STYLE' configuration key for grub-mkconfig. - Menu hotkeys pressed during a hidden timeout now boot the corresponding - menu entry immediately. - * New `file' command and grub-file utility to check file types. - * New syslinux configuration file parser. - * Set menu entry class to primary OS name returned by os-prober to display - OS specific icon. - * On Linux x86 detect EFI word size in grub-install and automatically select - correct platform (x86_64-efi or i386-efi) to install. Requires Linux kernel - 4.0 or higher. - -* Build system: - * Remove all uses of nested functions; GRUB no longer requires an - executable stack. - * Fix documentation build with Texinfo >= 5.1. - * More robust and documented cross-compiling support. - * Partial clang support for some platforms (experimental). - * Partial mingw64 x86_64-efi compile support (highly experimental). - * Partial mingw32 i386-* (other than already present i386-pc) - compile support (highly experimental). - * Support for grub-mkpasswd on Windows. - * Eliminate the use of AutoGen. This allowed some performance - improvements to the build system. - * Remove variable length arrays. - * OpenBSD compile and tools support (NetBSD and FreeBSD were already supported). - * Fix build with FreeType >= 2.5.1. - * Make gentpl.py compatible with Python 3. It now requires at least - Python 2.6. - * modinfo.sh contains build information now. - * Added many new tests to improve robustness. - * Target is built without libgcc now. Necessary builtins are reimplemented - directly. This removes requirement for target-specific runtime on build - system. - * emu libusb support removed (was broken and unmaintained). - * powerpc64le compile support. - * Use fixed timestamp when generating GRUB image for reproducible builds. - * Verify at build time that modules contain only supported relocations and their - structure matches what boot-time module loader expects. - * Do not require fonts on powerpc-ieee1275. - -* Revision control moved to git. - -New in 2.00: - -* Appearance: - * Official theme for gfxmenu (starfield) - * Menu is organised with submenus. - * Better default video mode selection using EDID. - -* New platforms: - * Itanium port. - * Fuloong2F support (including GRUB as firmware) - * Fuloong2E support (except GRUB as firmware) - * ARCS (SGI machines) port. - * qemu -M mips port. - -* grub-mount to mount filesystems using GRUB FS drivers and FUSE. - -* Changed security default so entries are locked by default if any superuser is - defined. - -* New drivers: - * EHCI. - * AHCI. - * ESCC serial. - * IEEE1275 serial. - * EFI serial. - * Network stack for BIOS, IEEE1275, EMU and EFI, including TFTP, HTTP and DNS. - -* New filesystem, filters and disks formats: - * DVH partition map. - * Plan9 partition map. - * Big-endian mdraid. - * Big-endian cpio. - * ODC and NEWC cpio. - * ExFAT. - * Minix3fs. - * Big-endian minixfs. - * RomFS. - * Squash4. - * Support non-512B disk blocks. - * LUKS and GELI support. - * LDM read support (no install yet). - * LZOP. - -* Improved filesystem and disks formats support: - * HFS+ label support. - * Improved reiserfs support. - * multidevice, mirrored and raidz(2,3) ZFS support. - * RAID LVM (internal RAIDing) support. - * ZFS crypto support. - * ZLE, LZ4 and GZIP on ZFS support. - * Support ZFS up to 33. - * HFS string is now treated like mac-roman and not UTF-8 - * HFS mtime support. - * Improved AFFS and SFS support. - * LZO-compressed btrfs support. - * cpio and tar symlinks support. - * Better FS detection to reduce false positives. - -* New boot protocols: - * Ability to load another coreboot payload when on coreboot. - * Plan9. - * Freedos. - * Ntldr/bootmgr (to load Windows bootloader). - * chainloader --bpb support to patch FAT or NTFS BPB in memory to correct - wrong partition offset. - * PXE chainloading support. - * Darwin 11 (Mac OS X Lion) protocol support. - -* Boot protocol improvements: - * Multiple initrd support. - * Basic illumos and xnu autoconfig. - -* Testing and debugging: - * New grub-fstest commands: cat, zfsinfo, testload xnu_uuid - * grub-fstest recursive directory compare for quickly checking that - a directory is read correctly. - * Backtace on crash (if gdb module is loaded, x86 only) - * Disk cache statistics gathering. - * GDB stub and GDB support script. - * "make check" and "make bootcheck" expanded to almost all platforms - (except i386-ieee1275, mips-arc, sparc64-ieee1275, ia64-efi and emu) - * New `time' command. - -* Performance: - * Lazy scanning to avoid accessing devices which aren't really used. - This avoids boot delay due to slow device scanning. - * Use CPU cache when accessing video memory. - * Search hints to first try the most likely device when searching for a - device with given UUID. This avoids slow scanning in most cases. - -* Internationalisation: - * Updated to Unicode 6.0. - * $"..." syntax for translation in grub scripting language. This allows easy - translation of grub.cfg at runtime. - * Translations to many languages included in official distribution. - -* Scripting: - * $grub_cpu and $grub_platform variables for conditioning grub.cfg on platform - at runtime. - * $feature_* variables to condition scripts on available features. - * Use of ids to identify menu entries. - * all_video module which is empty but depends on all video modules thus - allowing easy loading of all of them. - -* Installation: - * grub-mknetdir script for easy creation of netbootable GRUB directory. - * Itanium and mips support in grub-mkrescue. - * grub-install support for all platforms except emu. - * PreP partition install support. - * No files conflict between flavours (except grub-mkrescue for ppc). This - allows easy install of GRUB for several platforms. - * grub-mkstandalone script for easy creating of image including all modules - for platforms with generous limit on image size. - * program-transform-name now functions according to usual conventions. - Use --grubdir and --bootdir to get old behaviour. - -* ADLER32 and CRC64 support (for XZ and hashsum). - -* ofconsole renamed to console - -* Experimental support for compiling with Apple toolchain. - -* grub-mkdevicemap removed. Now all devices are detected on invocation of - any grub utility. - -New in 1.99: - -* Keyboard layouts support. - -* New `lsapm' command (i386-pc only). - -* Parser for GRUB Legacy configuration files. - -* Support RAID on virtio devices. - -* Remove deprecated `root' command. - -* New `euro.pf2' font which supports most European languages. - -* Avoid opening the same device twice on Open Firmware platforms. - -* Extend `vbeinfo' and `vbetest' commands to non-VBE graphics, as - `videoinfo' and `videotest'. - -* New `lsefisystab', `lssal', and `lsefimmap' commands on EFI platforms. - -* Support explicit user claim that a device is BIOS-visible. Devices - listed in device.map will be assumed to be readable using only BIOS - facilities, rather than anything more complex such as LVM or RAID. - -* New bash-completion script for GRUB utilities. - -* Use ACPI to shut down if possible. - -* New `lsacpi' command. - -* Btrfs support. - -* New `--boot-directory' option to `grub-install', `grub-reboot', and - `grub-set-default', with clearer semantics than the previous - `--root-directory' option. - -* Rename CD-ROM device to "cd" on BIOS platforms. - -* Transparent decompression filters. - -* Simpler PXE image generation. New `grub-mknetdir' utility to generate - netboot directory trees. - -* New relocator. Allows for more kernel support and more - straightforward loader writing. - -* Handle USB pendrives exposed as floppies. - -* New Automake-based build system. - -* Add `sendkey' command (i386-pc only). - -* ZFS support. - -* Support 1.x versions of mdadm metadata. - -* Fix corruption when reading Reiserfs directory entries. - -* Bidirectional text and diacritics support. - -* Skip LVM snapshots. - -* MIPS Yeeloong firmware port. - -* Change grub-mkdevicemap to emit /dev/disk/by-id/ names where possible - on GNU/Linux. - -* Add `grub-mkconfig' support for Xen with Linux. - -* Add `grub-mkconfig' support for initrd images on Fedora 13. - -* Support >3GiB and <16MiB RAM in i386-qemu. - -* Add support for Cirrus 5446 and Bochs video cards. - -* Load more appropriate video drivers automatically in `grub-mkconfig'. - -* USB improvements, including hotplugging/hotunplugging, hub support, - and USB serial support. - -* AMD Geode CS5536 support. - -* Extensive updates to the Texinfo documentation. - -* Handle symbolic links under /dev/mapper on GNU/Linux. - -* Handle installation across multiple partition table types. - -* Add `cmostest' command (i386/x86_64 only). - -* Add support for DM-RAID disk devices on GNU/Linux. - -* Remove `grub-mkisofs'. `grub-mkrescue' now uses GNU xorriso to build - CD images. - -* `grub-mkrescue' support for EFI, coreboot, and QEMU platforms. - -* Unify `grub-mkimage', `grub-setup', and `grub-install' source code - across platforms. - -* Fix VGA (as opposed to VBE) video driver, formerly a terminal driver. - -* Add menu hotkey support. - -* Add support for the nilfs2 filesystem. - -* `grub-probe' and `grub-mkconfig' support for NetBSD. - -* Support setting a background image in `grub-mkconfig'. - -* Support multiple terminals in `grub-mkconfig'. - -* Regexp support. - -* MIPS multiboot2 support. - -* Multiboot2 tag support. - -* sunpc partition table support. - -* Add a number of new language features to GRUB script: `for', `while', - `until', `elif', function parameters, `break', `continue', `shift', - multi-line quoted strings, positional parameters with `setparams', - `return', filename wildcard expansion, and `!'. - -* Support nested partition tables. GRUB now prefers to name partitions - in the form `(hd0,msdos1,bsd1)' rather than `(hd0,1,a)'. - -* Speed up consecutive hostdisk operations on the same device. - -* Compile parts of `grub-emu' as modules. - New in 1.98 - 2010-03-06: * Multiboot on EFI support. diff --git a/README b/README index 49ce15ea3..b6c7fd6d7 100644 --- a/README +++ b/README @@ -7,20 +7,8 @@ See the file NEWS for a description of recent changes to GRUB 2. See the file INSTALL for instructions on how to build and install the GRUB 2 data and program files. -See the file MAINTAINERS for information about the GRUB maintainers, etc. - -If you found a security vulnerability in the GRUB please check the SECURITY -file to get more information how to properly report this kind of bugs to -the maintainers. - Please visit the official web page of GRUB 2, for more information. The URL is . -More extensive documentation is available in the Info manual, -accessible using 'info grub' after building and installing GRUB 2. - -There are a number of important user-visible differences from the -first version of GRUB, now known as GRUB Legacy. For a summary, please -see: - - info grub Introduction 'Changes from GRUB Legacy' +For now, there is not much documentation yet. Please look at the GRUB +Wiki for testing procedures. diff --git a/SECURITY b/SECURITY deleted file mode 100644 index 1c3e8ef36..000000000 --- a/SECURITY +++ /dev/null @@ -1,60 +0,0 @@ -Security Policy -=============== - -To report a vulnerability see "Reporting a Vulnerability" below. - - -Security Incident Policy -======================== - -Security bug reports are treated with special attention and are handled -differently from normal bugs. In particular, security sensitive bugs are not -handled in public but in private. Information about the bug and access to it -is restricted to people in the security group, the individual engineers that -work on fixing it, and any other person who needs to be involved for organisational -reasons. The process is handled by the security team, which decides on the people -involved in order to fix the issue. It is also guaranteed that the person reporting -the issue has visibility into the process of fixing it. Any security issue gets -prioritized according to its security rating. The issue is opened up to the public -in coordination with the release schedule and the reporter. - - -Disclosure Policy -================= - -Everyone involved in the handling of a security issue - including the reporter - -is required to adhere to the following policy. Any information related to -a security issue must be treated as confidential and only shared with trusted -partners if necessary, for example to coordinate a release or manage exposure -of clients to the issue. No information must be disclosed to the public before -the embargo ends. The embargo time is agreed upon by all involved parties. It -should be as short as possible without putting any users at risk. - - -Supported Versions -================== - -Only the most recent version of the GRUB is supported. - - -Reporting a Vulnerability -========================= - -The security report should be encrypted with the PGP keys and sent to ALL email -addresses listed below. Every vulnerability report will be assessed within -72 hours of receiving it. If the outcome of the assessment is that the report -describes a security issue, the report will be transferred into an issue on the -internal vulnerability project for further processing. The reporter is updated -on each step of the process. - -While there's currently no bug bounty program we appreciate every report. - -* Contact: Daniel Kiper and - Daniel Kiper -* PGP Key Fingerprint: BE5C 2320 9ACD DACE B20D B0A2 8C81 89F1 988C 2166 - -* Contact: Alex Burmashev -* PGP Key Fingerprint: 50A4 EC06 EF7E B84D 67E0 3BB6 2AE2 C87E 28EF 2E6E - -* Contact: Vladimir 'phcoder' Serbinenko -* PGP Key Fingerprint: E53D 497F 3FA4 2AD8 C9B4 D1E8 35A9 3B74 E82E 4209 diff --git a/TODO b/TODO index a9b6d3523..6ec1521cd 100644 --- a/TODO +++ b/TODO @@ -7,3 +7,7 @@ glance. So write to first. For bug tracking, refer to: http://savannah.gnu.org/bugs/?group=grub + +Our wiki also lists some areas that need work: + + http://grub.enbug.org/ diff --git a/acinclude.m4 b/acinclude.m4 index fa7840f09..692404e20 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -19,8 +19,6 @@ AC_DEFUN([grub_PROG_TARGET_CC], AC_CACHE_VAL(grub_cv_prog_target_cc, [AC_LINK_IFELSE([AC_LANG_PROGRAM([[ asm (".globl start; start:"); -void __main (void); -void __main (void) {} int main (void); ]], [[]])], [grub_cv_prog_target_cc=yes], @@ -40,7 +38,6 @@ dnl Written by Pavel Roskin. Based on grub_ASM_EXT_C written by dnl Erich Boleyn and modified by Yoshinori K. Okuji. AC_DEFUN([grub_ASM_USCORE], [AC_REQUIRE([AC_PROG_CC]) -AC_REQUIRE([AC_PROG_EGREP]) AC_MSG_CHECKING([if C symbols get an underscore after compilation]) AC_CACHE_VAL(grub_cv_asm_uscore, [cat > conftest.c <<\EOF @@ -59,16 +56,19 @@ else AC_MSG_ERROR([${CC-cc} failed to produce assembly code]) fi -if $EGREP '(^|[^_[:alnum]])_func' conftest.s >/dev/null 2>&1; then - HAVE_ASM_USCORE=1 +if grep _func conftest.s >/dev/null 2>&1; then grub_cv_asm_uscore=yes else - HAVE_ASM_USCORE=0 grub_cv_asm_uscore=no fi rm -f conftest*]) +if test "x$grub_cv_asm_uscore" = xyes; then + AC_DEFINE_UNQUOTED([HAVE_ASM_USCORE], $grub_cv_asm_uscore, + [Define if C symbols get an underscore after compilation]) +fi + AC_MSG_RESULT([$grub_cv_asm_uscore]) ]) @@ -76,7 +76,7 @@ AC_MSG_RESULT([$grub_cv_asm_uscore]) dnl Some versions of `objcopy -O binary' vary their output depending dnl on the link address. AC_DEFUN([grub_PROG_OBJCOPY_ABSOLUTE], -[AC_MSG_CHECKING([whether ${TARGET_OBJCOPY} works for absolute addresses]) +[AC_MSG_CHECKING([whether ${OBJCOPY} works for absolute addresses]) AC_CACHE_VAL(grub_cv_prog_objcopy_absolute, [cat > conftest.c <<\EOF void cmain (void); @@ -93,13 +93,13 @@ else fi grub_cv_prog_objcopy_absolute=yes for link_addr in 0x2000 0x8000 0x7C00; do - if AC_TRY_COMMAND([${CC-cc} ${TARGET_CFLAGS} ${TARGET_LDFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} ${TARGET_IMG_BASE_LDOPT},$link_addr conftest.o -o conftest.exec]); then : + if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then : else AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr]) fi - if AC_TRY_COMMAND([${TARGET_OBJCOPY-objcopy} --only-section=.text -O binary conftest.exec conftest]); then : + if AC_TRY_COMMAND([${OBJCOPY-objcopy} --only-section=.text -O binary conftest.exec conftest]); then : else - AC_MSG_ERROR([${TARGET_OBJCOPY-objcopy} cannot create binary files]) + AC_MSG_ERROR([${OBJCOPY-objcopy} cannot create binary files]) fi if test ! -f conftest.old || AC_TRY_COMMAND([cmp -s conftest.old conftest]); then mv -f conftest conftest.old @@ -136,78 +136,142 @@ if test "x$grub_cv_prog_ld_build_id_none" = xyes; then fi ]) -dnl Check nm -AC_DEFUN([grub_PROG_NM_WORKS], -[AC_MSG_CHECKING([whether nm works]) -AC_CACHE_VAL(grub_cv_prog_nm_works, -[ -nm_works_tmp_dir="$(mktemp -d "./confXXXXXX")" -AC_LANG_CONFTEST([AC_LANG_PROGRAM([[]], [[]])]) -$TARGET_CC $TARGET_CFLAGS -c conftest.c -o "$nm_works_tmp_dir/ef" -if $TARGET_NM "$nm_works_tmp_dir/ef" > /dev/null; then - grub_cv_prog_nm_works=yes -else - grub_cv_prog_nm_minus_p=no -fi -rm "$nm_works_tmp_dir/ef" -rmdir "$nm_works_tmp_dir" -]) -AC_MSG_RESULT([$grub_cv_prog_nm_works]) -if test "x$grub_cv_prog_nm_works" != xyes; then - AC_MSG_ERROR([nm does not work]) +dnl Mass confusion! +dnl Older versions of GAS interpret `.code16' to mean ``generate 32-bit +dnl instructions, but implicitly insert addr32 and data32 bytes so +dnl that the code works in real mode''. +dnl +dnl Newer versions of GAS interpret `.code16' to mean ``generate 16-bit +dnl instructions,'' which seems right. This requires the programmer +dnl to explicitly insert addr32 and data32 instructions when they want +dnl them. +dnl +dnl We only support the newer versions, because the old versions cause +dnl major pain, by requiring manual assembly to get 16-bit instructions into +dnl asm files. +AC_DEFUN([grub_I386_ASM_ADDR32], +[AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([grub_I386_ASM_PREFIX_REQUIREMENT]) +AC_MSG_CHECKING([for .code16 addr32 assembler support]) +AC_CACHE_VAL(grub_cv_i386_asm_addr32, +[cat > conftest.s.in <<\EOF + .code16 +l1: @ADDR32@ movb %al, l1 +EOF + +if test "x$grub_cv_i386_asm_prefix_requirement" = xyes; then + sed -e s/@ADDR32@/addr32/ < conftest.s.in > conftest.s +else + sed -e s/@ADDR32@/addr32\;/ < conftest.s.in > conftest.s +fi + +if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then + grub_cv_i386_asm_addr32=yes +else + grub_cv_i386_asm_addr32=no +fi + +rm -f conftest*]) + +AC_MSG_RESULT([$grub_cv_i386_asm_addr32])]) + +dnl check if our compiler is apple cc +dnl because it requires numerous workarounds +AC_DEFUN([grub_apple_cc], +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING([whether our compiler is apple cc]) +AC_CACHE_VAL(grub_cv_apple_cc, +[if $CC -v 2>&1 | grep "Apple Inc." > /dev/null; then + grub_cv_apple_cc=yes +else + grub_cv_apple_cc=no fi ]) -dnl Supply -P to nm -AC_DEFUN([grub_PROG_NM_MINUS_P], -[AC_MSG_CHECKING([whether nm accepts -P]) -AC_CACHE_VAL(grub_cv_prog_nm_minus_p, -[ -nm_minus_p_tmp_dir="$(mktemp -d "./confXXXXXX")" -AC_LANG_CONFTEST([AC_LANG_PROGRAM([[]], [[]])]) -$TARGET_CC $TARGET_CFLAGS -c conftest.c -o "$nm_minus_p_tmp_dir/ef" -if $TARGET_NM -P "$nm_minus_p_tmp_dir/ef" 2>&1 > /dev/null; then - grub_cv_prog_nm_minus_p=yes -else - grub_cv_prog_nm_minus_p=no -fi -rm "$nm_minus_p_tmp_dir/ef" -rmdir "$nm_minus_p_tmp_dir" -]) -AC_MSG_RESULT([$grub_cv_prog_nm_minus_p]) +AC_MSG_RESULT([$grub_cv_apple_cc])]) -if test "x$grub_cv_prog_nm_minus_p" = xyes; then - TARGET_NMFLAGS_MINUS_P="-P" +dnl check if our target compiler is apple cc +dnl because it requires numerous workarounds +AC_DEFUN([grub_apple_target_cc], +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING([whether our target compiler is apple cc]) +AC_CACHE_VAL(grub_cv_apple_target_cc, +[if $CC -v 2>&1 | grep "Apple Inc." > /dev/null; then + grub_cv_apple_target_cc=yes else - TARGET_NMFLAGS_MINUS_P= + grub_cv_apple_target_cc=no fi ]) -dnl Supply --defined-only to nm -AC_DEFUN([grub_PROG_NM_DEFINED_ONLY], -[AC_MSG_CHECKING([whether nm accepts --defined-only]) -AC_CACHE_VAL(grub_cv_prog_nm_defined_only, -[ -nm_defined_only_tmp_dir="$(mktemp -d "./confXXXXXX")" -AC_LANG_CONFTEST([AC_LANG_PROGRAM([[]], [[]])]) -$TARGET_CC $TARGET_CFLAGS -c conftest.c -o "$nm_defined_only_tmp_dir/ef" -if $TARGET_NM --defined-only "$nm_defined_only_tmp_dir/ef" 2>&1 > /dev/null; then - grub_cv_prog_nm_defined_only=yes -else - grub_cv_prog_nm_defined_only=no -fi -rm "$nm_defined_only_tmp_dir/ef" -rmdir "$nm_defined_only_tmp_dir" -]) -AC_MSG_RESULT([$grub_cv_prog_nm_defined_only]) +AC_MSG_RESULT([$grub_cv_apple_target_cc])]) -if test "x$grub_cv_prog_nm_defined_only" = xyes; then - TARGET_NMFLAGS_DEFINED_ONLY=--defined-only + +dnl Later versions of GAS requires that addr32 and data32 prefixes +dnl appear in the same lines as the instructions they modify, while +dnl earlier versions requires that they appear in separate lines. +AC_DEFUN([grub_I386_ASM_PREFIX_REQUIREMENT], +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING(dnl +[whether addr32 must be in the same line as the instruction]) +AC_CACHE_VAL(grub_cv_i386_asm_prefix_requirement, +[cat > conftest.s <<\EOF + .code16 +l1: addr32 movb %al, l1 +EOF + +if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then + grub_cv_i386_asm_prefix_requirement=yes else - TARGET_NMFLAGS_DEFINED_ONLY= + grub_cv_i386_asm_prefix_requirement=no fi -]) + +rm -f conftest*]) + +if test "x$grub_cv_i386_asm_prefix_requirement" = xyes; then + grub_tmp_addr32="addr32" + grub_tmp_data32="data32" +else + grub_tmp_addr32="addr32;" + grub_tmp_data32="data32;" +fi + +AC_DEFINE_UNQUOTED([ADDR32], $grub_tmp_addr32, + [Define it to \"addr32\" or \"addr32;\" to make GAS happy]) +AC_DEFINE_UNQUOTED([DATA32], $grub_tmp_data32, + [Define it to \"data32\" or \"data32;\" to make GAS happy]) + +AC_MSG_RESULT([$grub_cv_i386_asm_prefix_requirement])]) + + +dnl Older versions of GAS require that absolute indirect calls/jumps are +dnl not prefixed with `*', while later versions warn if not prefixed. +AC_DEFUN([grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK], +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING(dnl +[whether an absolute indirect call/jump must not be prefixed with an asterisk]) +AC_CACHE_VAL(grub_cv_i386_asm_absolute_without_asterisk, +[cat > conftest.s <<\EOF + lcall *(offset) +offset: + .long 0 + .word 0 +EOF + +if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then + grub_cv_i386_asm_absolute_without_asterisk=no +else + grub_cv_i386_asm_absolute_without_asterisk=yes +fi + +rm -f conftest*]) + +if test "x$grub_cv_i386_asm_absolute_without_asterisk" = xyes; then + AC_DEFINE([ABSOLUTE_WITHOUT_ASTERISK], 1, + [Define it if GAS requires that absolute indirect calls/jumps are not prefixed with an asterisk]) +fi + +AC_MSG_RESULT([$grub_cv_i386_asm_absolute_without_asterisk])]) dnl Check what symbol is defined as a bss start symbol. @@ -216,12 +280,7 @@ AC_DEFUN([grub_CHECK_BSS_START_SYMBOL], [AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING([if __bss_start is defined by the compiler]) AC_CACHE_VAL(grub_cv_check_uscore_uscore_bss_start_symbol, -[AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -asm (".globl start; start:"); -void __main (void); -void __main (void) {} -int main (void); -]], +[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[asm ("incl __bss_start")]])], [grub_cv_check_uscore_uscore_bss_start_symbol=yes], [grub_cv_check_uscore_uscore_bss_start_symbol=no])]) @@ -230,11 +289,7 @@ AC_MSG_RESULT([$grub_cv_check_uscore_uscore_bss_start_symbol]) AC_MSG_CHECKING([if edata is defined by the compiler]) AC_CACHE_VAL(grub_cv_check_edata_symbol, -[AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -asm (".globl start; start:"); -void __main (void); -void __main (void) {} -int main (void);]], +[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[asm ("incl edata")]])], [grub_cv_check_edata_symbol=yes], [grub_cv_check_edata_symbol=no])]) @@ -243,23 +298,21 @@ AC_MSG_RESULT([$grub_cv_check_edata_symbol]) AC_MSG_CHECKING([if _edata is defined by the compiler]) AC_CACHE_VAL(grub_cv_check_uscore_edata_symbol, -[AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -asm (".globl start; start:"); -void __main (void); -void __main (void) {} -int main (void);]], +[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[asm ("incl _edata")]])], [grub_cv_check_uscore_edata_symbol=yes], [grub_cv_check_uscore_edata_symbol=no])]) AC_MSG_RESULT([$grub_cv_check_uscore_edata_symbol]) +AH_TEMPLATE([BSS_START_SYMBOL], [Define it to one of __bss_start, edata and _edata]) + if test "x$grub_cv_check_uscore_uscore_bss_start_symbol" = xyes; then - BSS_START_SYMBOL=__bss_start + AC_DEFINE([BSS_START_SYMBOL], [__bss_start]) elif test "x$grub_cv_check_edata_symbol" = xyes; then - BSS_START_SYMBOL=edata + AC_DEFINE([BSS_START_SYMBOL], [edata]) elif test "x$grub_cv_check_uscore_edata_symbol" = xyes; then - BSS_START_SYMBOL=_edata + AC_DEFINE([BSS_START_SYMBOL], [_edata]) else AC_MSG_ERROR([none of __bss_start, edata or _edata is defined]) fi @@ -271,11 +324,7 @@ AC_DEFUN([grub_CHECK_END_SYMBOL], [AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING([if end is defined by the compiler]) AC_CACHE_VAL(grub_cv_check_end_symbol, -[AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -asm (".globl start; start:"); -void __main (void); -void __main (void) {} -int main (void);]], +[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[asm ("incl end")]])], [grub_cv_check_end_symbol=yes], [grub_cv_check_end_symbol=no])]) @@ -284,36 +333,58 @@ AC_MSG_RESULT([$grub_cv_check_end_symbol]) AC_MSG_CHECKING([if _end is defined by the compiler]) AC_CACHE_VAL(grub_cv_check_uscore_end_symbol, -[AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -asm (".globl start; start:"); -void __main (void); -void __main (void) {} -int main (void);]], +[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[asm ("incl _end")]])], [grub_cv_check_uscore_end_symbol=yes], [grub_cv_check_uscore_end_symbol=no])]) AC_MSG_RESULT([$grub_cv_check_uscore_end_symbol]) +AH_TEMPLATE([END_SYMBOL], [Define it to either end or _end]) + if test "x$grub_cv_check_end_symbol" = xyes; then - END_SYMBOL=end + AC_DEFINE([END_SYMBOL], [end]) elif test "x$grub_cv_check_uscore_end_symbol" = xyes; then - END_SYMBOL=_end + AC_DEFINE([END_SYMBOL], [_end]) else AC_MSG_ERROR([neither end nor _end is defined]) fi ]) +dnl Check if the C compiler generates calls to `__enable_execute_stack()'. +AC_DEFUN([grub_CHECK_ENABLE_EXECUTE_STACK],[ +AC_MSG_CHECKING([whether `$CC' generates calls to `__enable_execute_stack()']) +AC_LANG_CONFTEST([[ +void f (int (*p) (void)); +void g (int i) +{ + int nestedfunc (void) { return i; } + f (nestedfunc); +} +]]) +if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -S conftest.c]) && test -s conftest.s; then + true +else + AC_MSG_ERROR([${CC-cc} failed to produce assembly code]) +fi +if grep __enable_execute_stack conftest.s >/dev/null 2>&1; then + AC_DEFINE([NEED_ENABLE_EXECUTE_STACK], 1, + [Define to 1 if GCC generates calls to __enable_execute_stack()]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi +rm -f conftest* +]) + -dnl Check if the C compiler supports the stack protector +dnl Check if the C compiler supports `-fstack-protector'. AC_DEFUN([grub_CHECK_STACK_PROTECTOR],[ -[# Stack smashing protector. +[# Smashing stack protector. ssp_possible=yes] AC_MSG_CHECKING([whether `$CC' accepts `-fstack-protector']) # Is this a reliable test case? -AC_LANG_CONFTEST([AC_LANG_SOURCE([[ -void foo (void) { volatile char a[8]; a[3]; } -]])]) +AC_LANG_CONFTEST([[void foo (void) { volatile char a[8]; a[3]; }]]) [# `$CC -c -o ...' might not be portable. But, oh, well... Is calling # `ac_compile' like this correct, after all? if eval "$ac_compile -S -fstack-protector -o conftest.s" 2> /dev/null; then] @@ -324,40 +395,6 @@ else ssp_possible=no] AC_MSG_RESULT([no]) [fi] -[# Strong stack smashing protector. -ssp_strong_possible=yes] -AC_MSG_CHECKING([whether `$CC' accepts `-fstack-protector-strong']) -# Is this a reliable test case? -AC_LANG_CONFTEST([AC_LANG_SOURCE([[ -void foo (void) { volatile char a[8]; a[3]; } -]])]) -[# `$CC -c -o ...' might not be portable. But, oh, well... Is calling -# `ac_compile' like this correct, after all? -if eval "$ac_compile -S -fstack-protector-strong -o conftest.s" 2> /dev/null; then] - AC_MSG_RESULT([yes]) - [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'? - rm -f conftest.s -else - ssp_strong_possible=no] - AC_MSG_RESULT([no]) -[fi] -[# Global stack smashing protector. -ssp_global_possible=yes] -AC_MSG_CHECKING([whether `$CC' accepts `-mstack-protector-guard=global']) -# Is this a reliable test case? -AC_LANG_CONFTEST([AC_LANG_SOURCE([[ -void foo (void) { volatile char a[8]; a[3]; } -]])]) -[# `$CC -c -o ...' might not be portable. But, oh, well... Is calling -# `ac_compile' like this correct, after all? -if eval "$ac_compile -S -fstack-protector -mstack-protector-guard=global -o conftest.s" 2> /dev/null; then] - AC_MSG_RESULT([yes]) - [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'? - rm -f conftest.s -else - ssp_global_possible=no] - AC_MSG_RESULT([no]) -[fi] ]) dnl Check if the C compiler supports `-mstack-arg-probe' (Cygwin). @@ -365,10 +402,8 @@ AC_DEFUN([grub_CHECK_STACK_ARG_PROBE],[ [# Smashing stack arg probe. sap_possible=yes] AC_MSG_CHECKING([whether `$CC' accepts `-mstack-arg-probe']) -AC_LANG_CONFTEST([AC_LANG_SOURCE([[ -void foo (void) { volatile char a[8]; a[3]; } -]])]) -[if eval "$ac_compile -S -mstack-arg-probe -Werror -o conftest.s" 2> /dev/null; then] +AC_LANG_CONFTEST([[void foo (void) { volatile char a[8]; a[3]; }]]) +[if eval "$ac_compile -S -mstack-arg-probe -o conftest.s" 2> /dev/null; then] AC_MSG_RESULT([yes]) [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'? rm -f conftest.s @@ -378,15 +413,15 @@ else [fi] ]) -dnl Check if ln -s can handle directories properly (mingw). +dnl Check if ln can handle directories properly (mingw). AC_DEFUN([grub_CHECK_LINK_DIR],[ -AC_MSG_CHECKING([whether ln -s can handle directories properly]) +AC_MSG_CHECKING([whether ln can handle directories properly]) [mkdir testdir 2>/dev/null case $srcdir in [\\/$]* | ?:[\\/]* ) reldir=$srcdir/include/grub/util ;; *) reldir=../$srcdir/include/grub/util ;; esac -if ln -s $reldir testdir/util 2>/dev/null && rm -f testdir/util 2>/dev/null ; then] +if ln -s $reldir testdir/util 2>/dev/null ; then] AC_MSG_RESULT([yes]) [link_dir=yes else @@ -402,7 +437,7 @@ AC_DEFUN([grub_CHECK_PIE],[ pie_possible=yes] AC_MSG_CHECKING([whether `$CC' has `-fPIE' as default]) # Is this a reliable test case? -AC_LANG_CONFTEST([AC_LANG_SOURCE([[ +AC_LANG_CONFTEST([[ #ifdef __PIE__ int main() { return 0; @@ -410,7 +445,7 @@ int main() { #else #error NO __PIE__ DEFINED #endif -]])]) +]]) [# `$CC -c -o ...' might not be portable. But, oh, well... Is calling # `ac_compile' like this correct, after all? @@ -423,89 +458,3 @@ else AC_MSG_RESULT([no]) [fi] ]) - -AC_DEFUN([grub_CHECK_LINK_PIE],[ -[# Position independent executable. -link_nopie_needed=no] -AC_MSG_CHECKING([whether linker needs disabling of PIE to work]) -AC_LANG_CONFTEST([AC_LANG_SOURCE([[]])]) - -[if eval "$ac_compile -Wl,-r -nostdlib -Werror -o conftest.o" 2> /dev/null; then] - AC_MSG_RESULT([no]) - [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'? - rm -f conftest.o -else - link_nopie_needed=yes] - AC_MSG_RESULT([yes]) -[fi] -]) - - -dnl Check if the Linker supports `-no-pie'. -AC_DEFUN([grub_CHECK_NO_PIE], -[AC_MSG_CHECKING([whether linker accepts -no-pie]) -AC_CACHE_VAL(grub_cv_cc_ld_no_pie, -[save_LDFLAGS="$LDFLAGS" -LDFLAGS="$LDFLAGS -no-pie -nostdlib -Werror" -AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_ld_no_pie=yes], - [grub_cv_cc_ld_no_pie=no]) -LDFLAGS="$save_LDFLAGS" -]) -AC_MSG_RESULT([$grub_cv_cc_ld_no_pie]) -nopie_possible=no -if test "x$grub_cv_cc_ld_no_pie" = xyes ; then - nopie_possible=yes -fi -]) - -AC_DEFUN([grub_CHECK_NO_PIE_ONEWORD], -[AC_MSG_CHECKING([whether linker accepts -nopie]) -AC_CACHE_VAL(grub_cv_cc_ld_no_pie_oneword, -[save_LDFLAGS="$LDFLAGS" -LDFLAGS="$LDFLAGS -nopie -nostdlib -Werror" -AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_ld_no_pie_oneword=yes], - [grub_cv_cc_ld_no_pie_oneword=no]) -LDFLAGS="$save_LDFLAGS" -]) -AC_MSG_RESULT([$grub_cv_cc_ld_no_pie_oneword]) -nopie_oneword_possible=no -if test "x$grub_cv_cc_ld_no_pie_oneword" = xyes ; then - nopie_oneword_possible=yes -fi -]) - -dnl Check if the C compiler supports `-fPIC'. -AC_DEFUN([grub_CHECK_PIC],[ -[# Position independent executable. -pic_possible=yes] -AC_MSG_CHECKING([whether `$CC' has `-fPIC' as default]) -# Is this a reliable test case? -AC_LANG_CONFTEST([AC_LANG_SOURCE([[ -#ifdef __PIC__ -int main() { - return 0; -} -#else -#error NO __PIC__ DEFINED -#endif -]])]) - -[# `$CC -c -o ...' might not be portable. But, oh, well... Is calling -# `ac_compile' like this correct, after all? -if eval "$ac_compile -S -o conftest.s" 2> /dev/null; then] - AC_MSG_RESULT([yes]) - [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'? - rm -f conftest.s -else - pic_possible=no] - AC_MSG_RESULT([no]) -[fi] -]) - -dnl Create an output variable with the transformed name of a GRUB utility -dnl program. -AC_DEFUN([grub_TRANSFORM],[dnl -AC_SUBST(AS_TR_SH([$1]), [`AS_ECHO([$1]) | sed "$program_transform_name"`])dnl -]) diff --git a/asm-tests/arm.S b/asm-tests/arm.S deleted file mode 100644 index 97c2546bf..000000000 --- a/asm-tests/arm.S +++ /dev/null @@ -1,20 +0,0 @@ -/* on arm clang doesn't support .arch directive */ - - .text - .syntax unified - -#if !defined (__thumb2__) - .arch armv7a - .arm -#else - .arch armv7 - .thumb -#endif - mcr p15, 0, r11, c7, c14, 2 - - /* clang restricts access to dsb/isb despite .arch */ - dsb - isb - - - diff --git a/asm-tests/i386-pc.S b/asm-tests/i386-pc.S deleted file mode 100644 index d037744f9..000000000 --- a/asm-tests/i386-pc.S +++ /dev/null @@ -1,18 +0,0 @@ -/* on x86 old clang doesn't support .code16 - newer clang supports it but creates 6-byte jumps instead of 3-byte ones - which makes us go over boot sector size. - Starting with 3.9 clang emits 3-byte jumps but still creates 8-bytes movl - instead of 5-bytes, so code overflows into data. */ - - .code16 - jmp far - .org 4 - jmp nearer - .org 6 - movl nearer, %ebx - .org 11 - .space 100 -nearer: - .space 200 -far: - .byte 0 diff --git a/asm-tests/i386.S b/asm-tests/i386.S deleted file mode 100644 index 30adc4fe2..000000000 --- a/asm-tests/i386.S +++ /dev/null @@ -1,4 +0,0 @@ -/* on x86 old clang doesn't support .code16 */ - - .code16 - movb %al, %bl diff --git a/asm-tests/mips.S b/asm-tests/mips.S deleted file mode 100644 index 1312d47d5..000000000 --- a/asm-tests/mips.S +++ /dev/null @@ -1,11 +0,0 @@ -/* on mips clang doesn't support privilegied instructions, doubleword store/load - and crashes with hand-written assembly - */ - - .set mips3 - sync - ld $t2, 0($t1) - -a: - addiu $t1, $s0, (b - a) -b: nop diff --git a/asm-tests/powerpc.S b/asm-tests/powerpc.S deleted file mode 100644 index 396a6cce9..000000000 --- a/asm-tests/powerpc.S +++ /dev/null @@ -1,8 +0,0 @@ -/* clang <= 3.3 doesn't handle most of ppc assembly, not even inline assembly - used by gcrypt */ -/* Cache invalidation loop is a fair test. */ - li 5, 0 -1: icbi 5, 3 - addi 5, 5, 32 - cmpw 5, 4 - blt 1b diff --git a/asm-tests/sparc64.S b/asm-tests/sparc64.S deleted file mode 100644 index 03c5fe02a..000000000 --- a/asm-tests/sparc64.S +++ /dev/null @@ -1,9 +0,0 @@ - .text -1: - /* A small list of examples of what clang doesn't support. */ - clr %o0 - lduw [%o4 + 4], %o4 - and %o6, ~0xff, %o6 - stw %o5, [%o3] - bne,pt %icc, 1b - nop diff --git a/autogen.sh b/autogen.sh index ebd614792..eb251f9f0 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,149 +1,23 @@ -#! /usr/bin/env bash +#! /bin/sh set -e -if [ ! -e grub-core/lib/gnulib/stdlib.in.h ]; then - echo "Gnulib not yet bootstrapped; run ./bootstrap instead." >&2 - exit 1 -fi +aclocal +autoconf +autoheader -# Detect python -if [ -z "$PYTHON" ]; then - for i in python3 python3.10 python; do - if command -v "$i" > /dev/null 2>&1; then - PYTHON="$i" - echo "Using $PYTHON..." - break - fi - done +# FIXME: automake doesn't like that there's no Makefile.am +automake -a -c -f || true - if [ -z "$PYTHON" ]; then - echo "python not found." >&2 - exit 1 - fi -fi - -export LC_COLLATE=C -unset LC_ALL - -find . -iname '*.[ch]' ! -ipath './grub-core/lib/libgcrypt-grub/*' ! -ipath './build-aux/*' ! -ipath './grub-core/lib/libgcrypt/src/misc.c' ! -ipath './grub-core/lib/libgcrypt/src/global.c' ! -ipath './grub-core/lib/libgcrypt/src/secmem.c' ! -ipath './util/grub-gen-widthspec.c' ! -ipath './util/grub-gen-asciih.c' ! -ipath './gnulib/*' ! -ipath './grub-core/lib/gnulib/*' |sort > po/POTFILES.in -find util -iname '*.in' ! -name Makefile.in |sort > po/POTFILES-shell.in - -echo "Importing unicode..." -${PYTHON} util/import_unicode.py unicode/UnicodeData.txt unicode/BidiMirroring.txt unicode/ArabicShaping.txt grub-core/unidata.c - -echo "Importing libgcrypt..." -${PYTHON} util/import_gcry.py grub-core/lib/libgcrypt/ grub-core -sed -n -f util/import_gcrypth.sed < grub-core/lib/libgcrypt/src/gcrypt.h.in > include/grub/gcrypt/gcrypt.h -if [ -f include/grub/gcrypt/g10lib.h ]; then - rm include/grub/gcrypt/g10lib.h -fi -if [ -d grub-core/lib/libgcrypt-grub/mpi/generic ]; then - rm -rf grub-core/lib/libgcrypt-grub/mpi/generic -fi -cp grub-core/lib/libgcrypt-grub/src/g10lib.h include/grub/gcrypt/g10lib.h -cp -R grub-core/lib/libgcrypt/mpi/generic grub-core/lib/libgcrypt-grub/mpi/generic - -for x in mpi-asm-defs.h mpih-add1.c mpih-sub1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c mpih-lshift.c mpih-rshift.c; do - if [ -h grub-core/lib/libgcrypt-grub/mpi/"$x" ] || [ -f grub-core/lib/libgcrypt-grub/mpi/"$x" ]; then - rm grub-core/lib/libgcrypt-grub/mpi/"$x" - fi - cp grub-core/lib/libgcrypt-grub/mpi/generic/"$x" grub-core/lib/libgcrypt-grub/mpi/"$x" -done - -echo "Importing libtasn1..." -if [ -d grub-core/lib/libtasn1-grub ]; then - rm -rf grub-core/lib/libtasn1-grub -fi - -mkdir -p grub-core/lib/libtasn1-grub/lib -cp grub-core/lib/libtasn1/lib/*.[ch] grub-core/lib/libtasn1-grub/lib -cp grub-core/lib/libtasn1/libtasn1.h grub-core/lib/libtasn1-grub/ - -if [ -d grub-core/tests/asn1/tests ]; then - rm -rf grub-core/tests/asn1/tests -fi - -mkdir grub-core/tests/asn1/tests -cp grub-core/lib/libtasn1/tests/*.[ch] grub-core/tests/asn1/tests - -for patch in \ - 0001-libtasn1-disable-code-not-needed-in-grub.patch \ - 0002-libtasn1-replace-strcat-with-strcpy-in-_asn1_str_cat.patch \ - 0003-libtasn1-replace-strcat-with-_asn1_str_cat.patch \ - 0004-libtasn1-adjust-the-header-paths-in-libtasn1.h.patch \ - 0005-libtasn1-Use-grub_divmod64-for-division.patch \ - 0006-libtasn1-fix-the-potential-buffer-overrun.patch \ - 0007-asn1_test-include-asn1_test.h-only.patch \ - 0008-asn1_test-rename-the-main-functions-to-the-test-name.patch \ - 0009-asn1_test-return-either-0-or-1-to-reflect-the-result.patch \ - 0010-asn1_test-remove-verbose-and-the-unnecessary-printf.patch \ - 0011-asn1_test-print-the-error-messages-with-grub_printf.patch \ - 0012-asn1_test-use-the-grub-specific-functions-and-types.patch \ - 0013-asn1_test-enable-the-testcase-only-when-GRUB_LONG_MA.patch ; do - patch -p1 -i grub-core/lib/libtasn1-patches/$patch -done - -echo "Generating Automake input..." - -# Automake doesn't like including files from a path outside the project. -rm -f contrib grub-core/contrib -if [ "x${GRUB_CONTRIB}" != x ]; then - [ "${GRUB_CONTRIB}" = contrib ] || ln -s "${GRUB_CONTRIB}" contrib - [ "${GRUB_CONTRIB}" = grub-core/contrib ] || ln -s ../contrib grub-core/contrib -fi - -UTIL_DEFS='Makefile.util.def Makefile.utilgcry.def' -CORE_DEFS='grub-core/Makefile.core.def grub-core/Makefile.gcry.def' - -for extra in contrib/*/Makefile.util.def; do - if test -e "$extra"; then - UTIL_DEFS="$UTIL_DEFS $extra" - fi -done - -for extra in contrib/*/Makefile.core.def; do - if test -e "$extra"; then - CORE_DEFS="$CORE_DEFS $extra" - fi -done - -${PYTHON} gentpl.py $UTIL_DEFS > Makefile.util.am -${PYTHON} gentpl.py $CORE_DEFS > grub-core/Makefile.core.am - -for extra in contrib/*/Makefile.common; do - if test -e "$extra"; then - echo "include $extra" >> Makefile.util.am - echo "include $extra" >> grub-core/Makefile.core.am - fi -done - -for extra in contrib/*/Makefile.util.common; do - if test -e "$extra"; then - echo "include $extra" >> Makefile.util.am - fi -done - -for extra in contrib/*/Makefile.core.common; do - if test -e "$extra"; then - echo "include $extra" >> grub-core/Makefile.core.am - fi -done - -echo "Saving timestamps..." echo timestamp > stamp-h.in -if [ -z "$FROM_BOOTSTRAP" ]; then - # Unaided autoreconf is likely to install older versions of many files - # than the ones provided by Gnulib, but in most cases this won't matter - # very much. This mode is provided so that you can run ./autogen.sh to - # regenerate the GRUB build system in an unpacked release tarball (perhaps - # after patching it), even on systems that don't have access to - # gnulib.git. - echo "Running autoreconf..." - cp -a INSTALL INSTALL.grub - autoreconf -vif - mv INSTALL.grub INSTALL -fi +python util/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 exit 0 diff --git a/grub-core/boot/i386/pc/boot.S b/boot/i386/pc/boot.S similarity index 81% rename from grub-core/boot/i386/pc/boot.S rename to boot/i386/pc/boot.S index 2bd0b2d28..257f9044e 100644 --- a/grub-core/boot/i386/pc/boot.S +++ b/boot/i386/pc/boot.S @@ -18,6 +18,7 @@ */ #include +#include #include /* @@ -26,87 +27,6 @@ /* Print message string */ #define MSG(x) movw $x, %si; call LOCAL(message) -#define ERR(x) movw $x, %si; jmp LOCAL(error_message) - - .macro floppy -part_start: - -LOCAL(probe_values): - .byte 36, 18, 15, 9, 0 - -LOCAL(floppy_probe): - pushw %dx -/* - * Perform floppy probe. - */ -#ifdef __APPLE__ - LOCAL(probe_values_minus_one) = LOCAL(probe_values) - 1 - movw MACRO_DOLLAR(LOCAL(probe_values_minus_one)), %si -#else - movw MACRO_DOLLAR(LOCAL(probe_values)) - 1, %si -#endif - -LOCAL(probe_loop): - /* reset floppy controller INT 13h AH=0 */ - xorw %ax, %ax - int MACRO_DOLLAR(0x13) - - incw %si - movb (%si), %cl - - /* if number of sectors is 0, display error and die */ - testb %cl, %cl - jnz 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 MACRO_DOLLAR(GRUB_BOOT_MACHINE_BUFFER_SEG), %bx - movw %bx, %es - xorw %bx, %bx - movw MACRO_DOLLAR(0x201), %ax - movb MACRO_DOLLAR(0), %ch - movb MACRO_DOLLAR(0), %dh - int MACRO_DOLLAR(0x13) - - /* if error, jump to "LOCAL(probe_loop)" */ - jc LOCAL(probe_loop) - - /* %cl is already the correct value! */ - movb MACRO_DOLLAR(1), %dh - movb MACRO_DOLLAR(79), %ch - - jmp LOCAL(final_init) - .endm - - .macro scratch - - /* 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... */ - .endm .file "boot.S" @@ -131,66 +51,47 @@ start: jmp LOCAL(after_BPB) nop /* do I care about this ??? */ -#ifdef HYBRID_BOOT - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - - nop - nop - nop - nop - nop - nop - nop - nop - - nop - nop - jmp LOCAL(after_BPB) -#else /* * This space is for the BIOS parameter block!!!! Don't change * the first jump, nor start the code anywhere but right after * this area. */ - .org GRUB_BOOT_MACHINE_BPB_START - .org 4 -#endif -#ifdef HYBRID_BOOT - floppy -#else - scratch -#endif + . = _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 - .org GRUB_BOOT_MACHINE_BPB_END /* * End of BIOS parameter block. */ -LOCAL(kernel_address): +kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR -#ifndef HYBRID_BOOT - .org GRUB_BOOT_MACHINE_KERNEL_SECTOR -LOCAL(kernel_sector): - .long 1 -LOCAL(kernel_sector_high): - .long 0 -#endif + . = _start + GRUB_BOOT_MACHINE_KERNEL_SECTOR +kernel_sector: + .long 1, 0 - .org GRUB_BOOT_MACHINE_BOOT_DRIVE + . = _start + GRUB_BOOT_MACHINE_BOOT_DRIVE boot_drive: .byte 0xff /* the disk to load kernel from */ /* 0xff means use the boot drive */ @@ -208,18 +109,14 @@ LOCAL(after_BPB): * possible boot drive. If GRUB is installed into a floppy, * this does nothing (only jump). */ - .org GRUB_BOOT_MACHINE_DRIVE_CHECK + . = _start + GRUB_BOOT_MACHINE_DRIVE_CHECK boot_drive_check: - jmp 3f /* grub-setup may overwrite this jump */ + jmp 1f /* grub-setup may overwrite this jump */ testb $0x80, %dl - jz 2f -3: - /* Ignore %dl different from 0-0x0f and 0x80-0x8f. */ - testb $0x70, %dl - jz 1f -2: + jnz 1f movb $0x80, %dl 1: + /* * ljmp to the next instruction because some bogus BIOSes * jump to 07C0:0000 instead of 0000:7C00. @@ -255,6 +152,10 @@ real_start: /* 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 @@ -275,7 +176,7 @@ real_start: andw $1, %cx jz LOCAL(chs_mode) -LOCAL(lba_mode): +lba_mode: xorw %ax, %ax movw %ax, 4(%si) @@ -290,9 +191,9 @@ LOCAL(lba_mode): movw $0x0010, (%si) /* the absolute address */ - movl LOCAL(kernel_sector), %ebx + movl kernel_sector, %ebx movl %ebx, 8(%si) - movl LOCAL(kernel_sector_high), %ebx + movl kernel_sector + 4, %ebx movl %ebx, 12(%si) /* the segment of buffer address */ @@ -325,15 +226,14 @@ LOCAL(chs_mode): int $0x13 jnc LOCAL(final_init) - popw %dx /* * The call failed, so maybe use the floppy probe instead. */ - testb %dl, %dl - jnb LOCAL(floppy_probe) + 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) + jmp LOCAL(hd_probe_error) LOCAL(final_init): /* set the mode to zero */ @@ -361,13 +261,13 @@ LOCAL(final_init): setup_sectors: /* load logical sector start (top half) */ - movl LOCAL(kernel_sector_high), %eax + movl kernel_sector + 4, %eax orl %eax, %eax jnz LOCAL(geometry_error) /* load logical sector start (bottom half) */ - movl LOCAL(kernel_sector), %eax + movl kernel_sector, %eax /* zero %edx */ xorl %edx, %edx @@ -452,7 +352,7 @@ LOCAL(copy_buffer): popa /* boot kernel */ - jmp *(LOCAL(kernel_address)) + jmp *(kernel_address) /* END OF MAIN LOOP */ @@ -460,15 +360,22 @@ LOCAL(copy_buffer): * BIOS Geometry translation error (past the end of the disk geometry!). */ LOCAL(geometry_error): - ERR(geometry_error_string) + MSG(geometry_error_string) + jmp LOCAL(general_error) + +/* + * Disk probe failure. + */ +LOCAL(hd_probe_error): + MSG(hd_probe_error_string) + jmp LOCAL(general_error) /* * Read error on the disk. */ LOCAL(read_error): - movw $read_error_string, %si -LOCAL(error_message): - call LOCAL(message) + MSG(read_error_string) + LOCAL(general_error): MSG(general_error_string) @@ -510,14 +417,7 @@ LOCAL(message): * number here. */ -#ifdef HYBRID_BOOT - .org 0x1b0 -LOCAL(kernel_sector): - .long 1 -LOCAL(kernel_sector_high): - .long 0 -#endif - .org GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC + . = _start + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC nt_magic: .long 0 .word 0 @@ -526,17 +426,60 @@ nt_magic: * 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? - */ + */ - .org GRUB_BOOT_MACHINE_PART_START + . = _start + GRUB_BOOT_MACHINE_PART_START +part_start: -#ifndef HYBRID_BOOT - floppy -#else - scratch -#endif +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 - .org 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/boot/i386/pc/cdboot.S similarity index 96% rename from grub-core/boot/i386/pc/cdboot.S rename to boot/i386/pc/cdboot.S index de4f80929..33569ce9d 100644 --- a/grub-core/boot/i386/pc/cdboot.S +++ b/boot/i386/pc/cdboot.S @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -43,7 +44,7 @@ _start: LOCAL(next): jmp 1f - .org 8 + . = start + 8 bi_pvd: .long 0 /* LBA of primary volume descriptor. */ @@ -93,12 +94,11 @@ LOCAL(read_cdrom): pushw $CDBLK_LENG /* Block number. */ - incl %esi pushl %eax pushl %esi /* Buffer address. */ - pushw $((DATA_ADDR - 0x200)>> 4) + pushw $((DATA_ADDR - 0x400)>> 4) pushl %eax pushw $0x10 @@ -168,6 +168,6 @@ err_noboot_msg: err_cdfail_msg: .ascii "cdrom read fails\0" - .org 0x7FF + . = start + 0x1FF .byte 0 diff --git a/grub-core/boot/i386/pc/diskboot.S b/boot/i386/pc/diskboot.S similarity index 97% rename from grub-core/boot/i386/pc/diskboot.S rename to boot/i386/pc/diskboot.S index c1addc0df..92f223f0d 100644 --- a/grub-core/boot/i386/pc/diskboot.S +++ b/boot/i386/pc/diskboot.S @@ -37,8 +37,8 @@ start: _start: /* - * _start is loaded at 0x8000 and is jumped to with - * CS:IP 0:0x8000 in kernel. + * _start is loaded at 0x2000 and is jumped to with + * CS:IP 0:0x2000 in kernel. */ /* @@ -56,7 +56,7 @@ _start: popw %si /* this sets up for the first run through "bootloop" */ - movw $LOCAL(firstlist), %di + movw $(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE), %di /* save the sector number of the second sector in %ebp */ movl (%di), %ebp @@ -362,8 +362,8 @@ LOCAL(message): .word 0 .word 0 - .org 0x200 - GRUB_BOOT_MACHINE_LIST_SIZE -LOCAL(firstlist): /* this label has to be before the first list entry!!! */ + . = _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 @@ -376,3 +376,5 @@ blocklist_default_len: 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/boot/i386/pc/lnxboot.S similarity index 89% rename from grub-core/boot/i386/pc/lnxboot.S rename to boot/i386/pc/lnxboot.S index 2dda0e06b..b4f0030b8 100644 --- a/grub-core/boot/i386/pc/lnxboot.S +++ b/boot/i386/pc/lnxboot.S @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -41,7 +42,7 @@ data_start: xorl %ebp, %ebp jmp LOCAL(linux_next) - .org 0x1F1 + . = data_start + 0x1F1 setup_sects: .byte CODE_SECTORS @@ -177,21 +178,15 @@ real_code_2: pushw %es popw %ds - movl $0x1000, %ecx - addl $0x200, %esi + movl $0x200, %ecx + addl %ecx, %esi movl $DATA_ADDR, %edi call LOCAL(move_memory) /* Check for multiboot signature. */ - movl $DATA_ADDR, %edi -3: - movl %ss:(%edi), %eax - cmpl $MULTIBOOT_HEADER_MAGIC, %eax + cmpl $MULTIBOOT_HEADER_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_DATA_END) jz 1f - addl $4, %edi - cmpl $(DATA_ADDR + 0x1000), %edi - jne 3b movl (ramdisk_image - start), %esi movl (ramdisk_size - start), %ecx @@ -200,16 +195,16 @@ real_code_2: 1: - movl $(DATA_ADDR + 0x1000), %edi - movl %ss:(DATA_ADDR + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE), %ecx - addl $GRUB_DECOMPRESSOR_I386_PC_MAX_DECOMPRESSOR_SIZE, %ecx + movl %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx + addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx 2: call LOCAL(move_memory) - movb %dh, %ss:(DATA_ADDR + GRUB_DECOMPRESSOR_I386_PC_BOOT_DEVICE + 2) - movb (reg_edx + 2 - start), %dh - movb %dh, %ss:(DATA_ADDR + GRUB_DECOMPRESSOR_I386_PC_BOOT_DEVICE + 1) + 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 @@ -292,4 +287,4 @@ LOCAL(fail): err_int15_msg: .ascii "move memory fails\0" - .org (CODE_SECTORS * 512 + 512) + . = _start + CODE_SECTORS * 512 diff --git a/grub-core/boot/i386/pc/pxeboot.S b/boot/i386/pc/pxeboot.S similarity index 96% rename from grub-core/boot/i386/pc/pxeboot.S rename to boot/i386/pc/pxeboot.S index b695b24d0..446bfc781 100644 --- a/grub-core/boot/i386/pc/pxeboot.S +++ b/boot/i386/pc/pxeboot.S @@ -38,5 +38,5 @@ start: /* 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. */ - .org 0x8200 - 0x7C00 - 0x200 - 1 + . = _start + 0x8200 - 0x7C00 - 0x200 - 1 .byte 0 diff --git a/grub-core/boot/i386/qemu/boot.S b/boot/i386/qemu/boot.S similarity index 79% rename from grub-core/boot/i386/qemu/boot.S rename to boot/i386/qemu/boot.S index 8c3a1db71..a93fe3943 100644 --- a/grub-core/boot/i386/qemu/boot.S +++ b/boot/i386/qemu/boot.S @@ -31,11 +31,14 @@ _start: jmp 1f - .org GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR + . = _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 @@ -48,17 +51,10 @@ VARIABLE(grub_core_entry_addr) /* Transition to protected mode. We use pushl to force generation of a flat return address. */ pushl $1f - jmp real_to_prot + DATA32 jmp real_to_prot .code32 1: - /* Ensure A20 is enabled. We're in qemu, so control port A works - and there is no need to wait since there is no real logic, it's - all emulated. */ - inb $0x92 - andb $(~0x03), %al - orb $0x02, %al - outb $0x92 - movl EXT_C(grub_core_entry_addr), %edx + movl grub_core_entry_addr, %edx jmp *%edx #include "../../../kern/i386/realmode.S" @@ -66,9 +62,6 @@ VARIABLE(grub_core_entry_addr) /* Intel, in its infinite wisdom, decided to put the i8086 entry point *right here* and this is why we need this kludge. */ - .org GRUB_BOOT_MACHINE_SIZE - 16 - - .code16 - + . = GRUB_BOOT_MACHINE_SIZE - 16 jmp _start - .org GRUB_BOOT_MACHINE_SIZE + . = GRUB_BOOT_MACHINE_SIZE diff --git a/grub-core/boot/sparc64/ieee1275/boot.S b/boot/sparc64/ieee1275/boot.S similarity index 58% rename from grub-core/boot/sparc64/ieee1275/boot.S rename to boot/sparc64/ieee1275/boot.S index ff8a79d3b..74f4ee014 100644 --- a/grub-core/boot/sparc64/ieee1275/boot.S +++ b/boot/sparc64/ieee1275/boot.S @@ -17,28 +17,11 @@ * along with GRUB. If not, see . */ +#include #include .text .align 4 - /* - * We're writing the a.out header ourselves as newer - * upstream versions of binutils no longer support - * the a.out format on sparc64. - * - * The boot loader fits into 512 bytes with 32 bytes - * used for the a.out header, hence the text segment - * size is 512 - 32. There is no data segment and no - * code relocation, thus those fields remain zero. - */ - .word 0x1030107 /* Magic number. */ - .word 512 - GRUB_BOOT_AOUT_HEADER_SIZE /* Size of text segment. */ - .word 0 /* Size of initialized data. */ - .word 0 /* Size of uninitialized data. */ - .word 0 /* Size of symbol table || checksum. */ - .word _start /* Entry point. */ - .word 0 /* Size of text relocation. */ - .word 0 /* Size of data relocation. */ .globl _start _start: /* OF CIF entry point arrives in %o4 */ @@ -46,9 +29,11 @@ pic_base: call boot_continue mov %o4, CIF_REG -#ifndef CDBOOT + . = _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/sparc64/ieee1275/boot.h, + * 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 @@ -58,27 +43,11 @@ pic_base: * * 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). - * - * Since this assembly code includes the 32 bytes long a.out header, - * we need to move the actual code entry point forward by the size - * of the a.out header, i.e. += GRUB_BOOT_AOUT_HEADER_SIZE. */ - .org GRUB_BOOT_MACHINE_BOOT_DEVPATH + GRUB_BOOT_AOUT_HEADER_SIZE boot_path: - .org GRUB_BOOT_MACHINE_KERNEL_BYTE + GRUB_BOOT_AOUT_HEADER_SIZE -boot_path_end: -kernel_byte: .xword (2 << 9) + . = _start + GRUB_BOOT_MACHINE_KERNEL_SECTOR +kernel_sector: .xword 2 kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR -#else -#define boot_path (_start + 512 + SCRATCH_PAD_BOOT_SIZE) -#define boot_path_end (_start + 1024) -#include - - .org 8 + GRUB_BOOT_AOUT_HEADER_SIZE -kernel_byte: .xword (2 << 9) -kernel_size: .word 512 -kernel_address: .word GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS -#endif prom_finddev_name: .asciz "finddevice" prom_chosen_path: .asciz "/chosen" @@ -91,10 +60,6 @@ prom_seek_name: .asciz "seek" prom_read_name: .asciz "read" prom_exit_name: .asciz "exit" grub_name: .asciz "GRUB " -#ifdef CDBOOT -prom_close_name: .asciz "close" -#endif - #define GRUB_NAME_LEN 5 .align 4 @@ -112,23 +77,11 @@ prom_error: /* %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_1_1: + mov 1, %g1 + ba prom_call + mov 1, %o5 -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 */ @@ -142,9 +95,8 @@ console_write: * %o2: input arg 2 * %o3: input arg 3 */ -prom_call_3_1: +prom_call_3_1: mov 3, %g1 -prom_call_x_1: mov 1, %o5 /* fallthru */ @@ -166,11 +118,7 @@ prom_call: boot_continue: mov %o7, PIC_REG /* PIC base */ -#ifndef CDBOOT - sethi %hi(SCRATCH_PAD_BOOT), %l1 /* OF argument slots */ -#else - GET_ABS(_start + 512, %l1) /* OF argument slots */ -#endif + sethi %hi(SCRATCH_PAD), %l1 /* OF argument slots */ /* Find the /chosen node so we can fetch the stdout handle, * and thus perform console output. @@ -178,17 +126,23 @@ boot_continue: * chosen_node = prom_finddevice("/chosen") */ GET_ABS(prom_finddev_name, %o0) - call prom_call_1_1_o2 - GET_ABS(prom_chosen_path, %o1) + GET_ABS(prom_chosen_path, %o1) + call prom_call_1_1 + clr %o2 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) + GET_ABS(prom_getprop_name, %o0) + mov 4, %g1 + mov 1, %o5 + mov CHOSEN_NODE_REG, %o1 + GET_ABS(prom_stdout_name, %o2) add %l1, 256, %o3 - call prom_call_getprop - mov 1024, %o4 + mov 1024, %o4 + call prom_call + stx %g1, [%l1 + 256] lduw [%l1 + 256], STDOUT_NODE_REG brz,pn STDOUT_NODE_REG, prom_error @@ -198,27 +152,15 @@ boot_continue: call console_write mov GRUB_NAME_LEN, %o3 - GET_ABS(boot_path, %o3) -#ifndef CDBOOT - ldub [%o3], %o1 - brnz,pn %o1, bootpath_known -#endif - - /* 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) + GET_ABS(boot_path, %o1) + call prom_call_1_1 + clr %o2 ldx [%l1 + 0x20], BOOTDEV_REG brz,pn BOOTDEV_REG, prom_open_error @@ -226,37 +168,29 @@ bootpath_known: /* 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) + * seek(bootdev, 0, *kernel_sector << 9) */ GET_ABS(prom_seek_name, %o0) + mov BOOTDEV_REG, %o1 clr %o2 - call prom_call_3_1_o1 - LDX_ABS(kernel_byte, 0x00, %o3) + LDX_ABS(kernel_sector, 0x00, %o3) + call prom_call_3_1 + sllx %o3, 9, %o3 /* read(bootdev, *kernel_address, 512) */ GET_ABS(prom_read_name, %o0) + mov BOOTDEV_REG, %o1 LDUW_ABS(kernel_address, 0x00, %o2) - call prom_call_3_1_o1 -#ifdef CDBOOT - LDUW_ABS(kernel_size, 0x00, %o3) - - GET_ABS(prom_close_name, %o0) - mov 1, %g1 - mov 0, %o5 - call prom_call - mov BOOTDEV_REG, %o1 -#else + call prom_call_3_1 mov 512, %o3 -#endif LDUW_ABS(kernel_address, 0x00, %o2) jmpl %o2, %o7 -#ifdef CDBOOT - mov CIF_REG, %o4 -#else nop -#endif - .org GRUB_BOOT_MACHINE_CODE_END + +1: ba,a 1b + + . = _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/boot/sparc64/ieee1275/diskboot.S similarity index 86% rename from grub-core/boot/sparc64/ieee1275/diskboot.S rename to boot/sparc64/ieee1275/diskboot.S index 35e02c1b6..68ed0eee0 100644 --- a/grub-core/boot/sparc64/ieee1275/diskboot.S +++ b/boot/sparc64/ieee1275/diskboot.S @@ -17,8 +17,8 @@ * along with GRUB. If not, see . */ +#include #include -#include .text .align 4 @@ -81,14 +81,14 @@ prom_call: after_info_block: - sethi %hi(SCRATCH_PAD_DISKBOOT), %l1 /* OF argument slots */ + sethi %hi(SCRATCH_PAD), %l1 /* OF argument slots */ GET_ABS(notification_string, %o2) call console_write mov NOTIFICATION_STRING_LEN, %o3 - GET_ABS(firstlist - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE, %l2) - set GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS, %l3 + GET_ABS(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE, %l2) + set GRUB_BOOT_MACHINE_IMAGE_ADDRESS, %l3 bootloop: lduw [%l2 + 0x08], %o0 brz %o0, bootit @@ -115,7 +115,7 @@ bootloop: mov NOTIFICATION_STEP_LEN, %o3 ba bootloop - sub %l2, GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE, %l2 + sub %l2, GRUB_BOOT_MACHINE_LIST_SIZE, %l2 bootit: GET_ABS(prom_close_name, %o0) @@ -127,16 +127,16 @@ bootit: GET_ABS(notification_done, %o2) call console_write mov NOTIFICATION_DONE_LEN, %o3 - sethi %hi(GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS), %o2 - jmpl %o2 + %lo(GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS), %o7 - mov CIF_REG, %o4 + sethi %hi(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o2 + jmpl %o2 + %lo(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o7 + mov CIF_REG, %o0 1: ba,a 1b lastlist: .word 0 .word 0 - .org (0x200 - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE) + . = _start + (0x200 - GRUB_BOOT_MACHINE_LIST_SIZE) blocklist_default_start: .word 0 .word 2 diff --git a/bootstrap b/bootstrap deleted file mode 100755 index dc2238f4a..000000000 --- a/bootstrap +++ /dev/null @@ -1,1118 +0,0 @@ -#! /bin/sh -# Print a version string. -scriptversion=2022-01-26.05; # UTC - -# Bootstrap this package from checked-out sources. - -# Copyright (C) 2003-2022 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 . - -# Originally written by Paul Eggert. The canonical version of this -# script is maintained as build-aux/bootstrap in gnulib, however, to -# be useful to your project, you should place a copy of it under -# version control in the top-level directory of your project. The -# intent is that all customization can be done with a bootstrap.conf -# file also maintained in your version control; gnulib comes with a -# template build-aux/bootstrap.conf to get you started. - -# Please report bugs or propose patches to bug-gnulib@gnu.org. - -nl=' -' - -# Ensure file names are sorted consistently across platforms. -LC_ALL=C -export LC_ALL - -# Ensure that CDPATH is not set. Otherwise, the output from cd -# would cause trouble in at least one use below. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -local_gl_dir=gl - -# Honor $PERL, but work even if there is none. -PERL="${PERL-perl}" - -me=$0 - -default_gnulib_url=https://git.savannah.gnu.org/git/gnulib.git - -usage() { - cat <&2 -} - -# warn_ WORD1... -warn_ () -{ - # If IFS does not start with ' ', set it and emit the warning in a subshell. - case $IFS in - ' '*) warnf_ '%s\n' "$*";; - *) (IFS=' '; warn_ "$@");; - esac -} - -# die WORD1... -die() { warn_ "$@"; exit 1; } - -# Configuration. - -# Name of the Makefile.am -gnulib_mk=gnulib.mk - -# List of gnulib modules needed. -gnulib_modules= - -# Any gnulib files needed that are not in modules. -gnulib_files= - -: ${AUTOPOINT=autopoint} -: ${AUTORECONF=autoreconf} - -# A function to be called for each unrecognized option. Returns 0 if -# the option in $1 has been processed by the function. Returns 1 if -# the option has not been processed by the function. Override it via -# your own definition in bootstrap.conf - -bootstrap_option_hook() { return 1; } - -# A function to be called in order to print the --help information -# corresponding to user-defined command-line options. - -bootstrap_print_option_usage_hook() { :; } - -# A function to be called right after gnulib-tool is run. -# Override it via your own definition in bootstrap.conf. -bootstrap_post_import_hook() { :; } - -# A function to be called after everything else in this script. -# Override it via your own definition in bootstrap.conf. -bootstrap_epilogue() { :; } - -# The command to download all .po files for a specified domain into a -# specified directory. Fill in the first %s with the destination -# directory and the second with the domain name. -po_download_command_format=\ -"wget --mirror --level=1 -nd -nv -A.po -P '%s' \ - https://translationproject.org/latest/%s/" - -# Prefer a non-empty tarname (4th argument of AC_INIT if given), else -# fall back to the package name (1st argument with munging). -extract_package_name=' - /^AC_INIT(\[*/{ - s/// - /^[^,]*,[^,]*,[^,]*,[ []*\([^][ ,)]\)/{ - s//\1/ - s/[],)].*// - p - q - } - s/[],)].*// - s/^GNU // - y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ - s/[^abcdefghijklmnopqrstuvwxyz0123456789_]/-/g - p - } -' -package=$(${AUTOCONF:-autoconf} --trace AC_INIT:\$4 configure.ac 2>/dev/null) -if test -z "$package"; then - package=$(sed -n "$extract_package_name" configure.ac) \ - || die 'cannot find package name in configure.ac' -fi -gnulib_name=lib$package - -build_aux=build-aux -source_base=lib -m4_base=m4 -doc_base=doc -tests_base=tests -gnulib_extra_files=" - build-aux/install-sh - build-aux/mdate-sh - build-aux/texinfo.tex - build-aux/depcomp - build-aux/config.guess - build-aux/config.sub - doc/INSTALL -" - -# Additional gnulib-tool options to use. Use "\newline" to break lines. -gnulib_tool_option_extras= - -# Other locale categories that need message catalogs. -EXTRA_LOCALE_CATEGORIES= - -# Additional xgettext options to use. Use "\\\newline" to break lines. -XGETTEXT_OPTIONS='\\\ - --flag=_:1:pass-c-format\\\ - --flag=N_:1:pass-c-format\\\ - --flag=error:3:c-format --flag=error_at_line:5:c-format\\\ -' - -# Package bug report address and copyright holder for gettext files -COPYRIGHT_HOLDER='Free Software Foundation, Inc.' -MSGID_BUGS_ADDRESS=bug-$package@gnu.org - -# Files we don't want to import. -excluded_files= - -# File that should exist in the top directory of a checked out hierarchy, -# but not in a distribution tarball. -checkout_only_file=README-hacking - -# Whether to use copies instead of symlinks. -copy=false - -# Set this to '.cvsignore .gitignore' in bootstrap.conf if you want -# those files to be generated in directories like lib/, m4/, and po/. -# Or set it to 'auto' to make this script select which to use based -# on which version control system (if any) is used in the source directory. -vc_ignore=auto - -# Set this to true in bootstrap.conf to enable --bootstrap-sync by -# default. -bootstrap_sync=false - -# Use git to update gnulib sources -use_git=true - -check_exists() { - if test "$1" = "--verbose"; then - ($2 --version /dev/null 2>&1 - if test $? -ge 126; then - # If not found, run with diagnostics as one may be - # presented with env variables to set to find the right version - ($2 --version /dev/null 2>&1 - fi - - test $? -lt 126 -} - -# find_tool ENVVAR NAMES... -# ------------------------- -# Search for a required program. Use the value of ENVVAR, if set, -# otherwise find the first of the NAMES that can be run. -# If found, set ENVVAR to the program name, die otherwise. -# -# FIXME: code duplication, see also gnu-web-doc-update. -find_tool () -{ - find_tool_envvar=$1 - shift - find_tool_names=$@ - eval "find_tool_res=\$$find_tool_envvar" - if test x"$find_tool_res" = x; then - for i; do - if check_exists $i; then - find_tool_res=$i - break - fi - done - fi - if test x"$find_tool_res" = x; then - warn_ "one of these is required: $find_tool_names;" - die "alternatively set $find_tool_envvar to a compatible tool" - fi - eval "$find_tool_envvar=\$find_tool_res" - eval "export $find_tool_envvar" -} - -# Strip blank and comment lines to leave significant entries. -gitignore_entries() { - sed '/^#/d; /^$/d' "$@" -} - -# If $STR is not already on a line by itself in $FILE, insert it at the start. -# Entries are inserted at the start of the ignore list to ensure existing -# entries starting with ! are not overridden. Such entries support -# whitelisting exceptions after a more generic blacklist pattern. -insert_if_absent() { - file=$1 - str=$2 - test -f $file || touch $file - test -r $file || die "Error: failed to read ignore file: $file" - duplicate_entries=$(gitignore_entries $file | sort | uniq -d) - if [ "$duplicate_entries" ] ; then - die "Error: Duplicate entries in $file: " $duplicate_entries - fi - linesold=$(gitignore_entries $file | wc -l) - linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l) - if [ $linesold != $linesnew ] ; then - { echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \ - || die "insert_if_absent $file $str: failed" - fi -} - -# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with -# insert_if_absent. -insert_vc_ignore() { - vc_ignore_file="$1" - pattern="$2" - case $vc_ignore_file in - *.gitignore) - # A .gitignore entry that does not start with '/' applies - # recursively to subdirectories, so prepend '/' to every - # .gitignore entry. - pattern=$(echo "$pattern" | sed s,^,/,);; - esac - insert_if_absent "$vc_ignore_file" "$pattern" -} - -symlink_to_dir() -{ - src=$1/$2 - dst=${3-$2} - - test -f "$src" && { - - # If the destination directory doesn't exist, create it. - # This is required at least for "lib/uniwidth/cjk.h". - dst_dir=$(dirname "$dst") - if ! test -d "$dst_dir"; then - mkdir -p "$dst_dir" - - # If we've just created a directory like lib/uniwidth, - # tell version control system(s) it's ignorable. - # FIXME: for now, this does only one level - parent=$(dirname "$dst_dir") - for dot_ig in x $vc_ignore; do - test $dot_ig = x && continue - ig=$parent/$dot_ig - insert_vc_ignore $ig "${dst_dir##*/}" - done - fi - - if $copy; then - { - test ! -h "$dst" || { - echo "$me: rm -f $dst" && - rm -f "$dst" - } - } && - test -f "$dst" && - cmp -s "$src" "$dst" || { - echo "$me: cp -fp $src $dst" && - cp -fp "$src" "$dst" - } - else - # Leave any existing symlink alone, if it already points to the source, - # so that broken build tools that care about symlink times - # aren't confused into doing unnecessary builds. Conversely, if the - # existing symlink's timestamp is older than the source, make it afresh, - # so that broken tools aren't confused into skipping needed builds. See - # . - test -h "$dst" && - src_ls=$(ls -diL "$src" 2>/dev/null) && set $src_ls && src_i=$1 && - dst_ls=$(ls -diL "$dst" 2>/dev/null) && set $dst_ls && dst_i=$1 && - test "$src_i" = "$dst_i" && - both_ls=$(ls -dt "$src" "$dst") && - test "X$both_ls" = "X$dst$nl$src" || { - dot_dots= - case $src in - /*) ;; - *) - case /$dst/ in - *//* | */../* | */./* | /*/*/*/*/*/) - die "invalid symlink calculation: $src -> $dst";; - /*/*/*/*/) dot_dots=../../../;; - /*/*/*/) dot_dots=../../;; - /*/*/) dot_dots=../;; - esac;; - esac - - echo "$me: ln -fs $dot_dots$src $dst" && - ln -fs "$dot_dots$src" "$dst" - } - fi - } -} - -# Override the default configuration, if necessary. -# Make sure that bootstrap.conf is sourced from the current directory -# if we were invoked as "sh bootstrap". -case "$0" in - */*) test -r "$0.conf" && . "$0.conf" ;; - *) test -r "$0.conf" && . ./"$0.conf" ;; -esac - -if test "$vc_ignore" = auto; then - vc_ignore= - test -d .git && vc_ignore=.gitignore - test -d CVS && vc_ignore="$vc_ignore .cvsignore" -fi - -if test x"$gnulib_modules$gnulib_files$gnulib_extra_files" = x; then - use_gnulib=false -else - use_gnulib=true -fi - -# Translate configuration into internal form. - -# Parse options. - -for option -do - case $option in - --help) - usage - exit;; - --version) - set -e - echo "bootstrap $scriptversion" - echo "$copyright" - exit 0 - ;; - --gnulib-srcdir=*) - GNULIB_SRCDIR=${option#--gnulib-srcdir=};; - --skip-po) - SKIP_PO=t;; - --force) - checkout_only_file=;; - --copy) - copy=true;; - --bootstrap-sync) - bootstrap_sync=true;; - --no-bootstrap-sync) - bootstrap_sync=false;; - --no-git) - use_git=false;; - *) - bootstrap_option_hook $option || die "$option: unknown option";; - esac -done - -$use_git || test -d "$GNULIB_SRCDIR" \ - || die "Error: --no-git requires --gnulib-srcdir" - -if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then - die "Bootstrapping from a non-checked-out distribution is risky." -fi - -# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac. -found_aux_dir=no -grep '^[ ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'\])' configure.ac \ - >/dev/null && found_aux_dir=yes -grep '^[ ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \ - >/dev/null && found_aux_dir=yes -test $found_aux_dir = yes \ - || die "configure.ac lacks 'AC_CONFIG_AUX_DIR([$build_aux])'; add it" - -# If $build_aux doesn't exist, create it now, otherwise some bits -# below will malfunction. If creating it, also mark it as ignored. -if test ! -d $build_aux; then - mkdir $build_aux - for dot_ig in x $vc_ignore; do - test $dot_ig = x && continue - insert_vc_ignore $dot_ig $build_aux - done -fi - -# Note this deviates from the version comparison in automake -# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a -# but this should suffice as we won't be specifying old -# version formats or redundant trailing .0 in bootstrap.conf. -# If we did want full compatibility then we should probably -# use m4_version_compare from autoconf. -sort_ver() { # sort -V is not generally available - ver1="$1" - ver2="$2" - - # split on '.' and compare each component - i=1 - while : ; do - p1=$(echo "$ver1" | cut -d. -f$i) - p2=$(echo "$ver2" | cut -d. -f$i) - if [ ! "$p1" ]; then - echo "$1 $2" - break - elif [ ! "$p2" ]; then - echo "$2 $1" - break - elif [ ! "$p1" = "$p2" ]; then - if [ "$p1" -gt "$p2" ] 2>/dev/null; then # numeric comparison - echo "$2 $1" - elif [ "$p2" -gt "$p1" ] 2>/dev/null; then # numeric comparison - echo "$1 $2" - else # numeric, then lexicographic comparison - lp=$(printf "$p1\n$p2\n" | LANG=C sort -n | tail -n1) - if [ "$lp" = "$p2" ]; then - echo "$1 $2" - else - echo "$2 $1" - fi - fi - break - fi - i=$(($i+1)) - done -} - -get_version_sed=' -# Move version to start of line. -s/.*[v ]\([0-9]\)/\1/ - -# Skip lines that do not start with version. -/^[0-9]/!d - -# Remove characters after the version. -s/[^.a-z0-9-].*// - -# The first component must be digits only. -s/^\([0-9]*\)[a-z-].*/\1/ - -#the following essentially does s/5.005/5.5/ -s/\.0*\([1-9]\)/.\1/g -p -q' - -get_version() { - app=$1 - - $app --version >/dev/null 2>&1 || { $app --version; return 1; } - - $app --version 2>&1 | sed -n "$get_version_sed" -} - -check_versions() { - ret=0 - - while read app req_ver; do - # We only need libtoolize from the libtool package. - if test "$app" = libtool; then - app=libtoolize - fi - # Exempt git if --no-git is in effect. - if test "$app" = git; then - $use_git || continue - fi - # Honor $APP variables ($TAR, $AUTOCONF, etc.) - appvar=$(echo $app | LC_ALL=C tr '[a-z]-' '[A-Z]_') - test "$appvar" = TAR && appvar=AMTAR - case $appvar in - GZIP) ;; # Do not use $GZIP: it contains gzip options. - PERL::*) ;; # Keep perl modules as-is - *) eval "app=\${$appvar-$app}" ;; - esac - - # Handle the still-experimental Automake-NG programs specially. - # They remain named as the mainstream Automake programs ("automake", - # and "aclocal") to avoid gratuitous incompatibilities with - # pre-existing usages (by, say, autoreconf, or custom autogen.sh - # scripts), but correctly identify themselves (as being part of - # "GNU automake-ng") when asked their version. - case $app in - automake-ng|aclocal-ng) - app=${app%-ng} - ($app --version | grep '(GNU automake-ng)') >/dev/null 2>&1 || { - warn_ "Error: '$app' not found or not from Automake-NG" - ret=1 - continue - } ;; - # Another check is for perl modules. These can be written as - # e.g. perl::XML::XPath in case of XML::XPath module, etc. - perl::*) - # Extract module name - app="${app#perl::}" - if ! $PERL -m"$app" -e 'exit 0' >/dev/null 2>&1; then - warn_ "Error: perl module '$app' not found" - ret=1 - fi - continue - ;; - esac - if [ "$req_ver" = "-" ]; then - # Merely require app to exist; not all prereq apps are well-behaved - # so we have to rely on $? rather than get_version. - if ! check_exists --verbose $app; then - warn_ "Error: '$app' not found" - ret=1 - fi - else - # Require app to produce a new enough version string. - inst_ver=$(get_version $app) - if [ ! "$inst_ver" ]; then - warn_ "Error: '$app' not found" - ret=1 - else - latest_ver=$(sort_ver $req_ver $inst_ver | cut -d' ' -f2) - if [ ! "$latest_ver" = "$inst_ver" ]; then - warnf_ '%s\n' \ - "Error: '$app' version == $inst_ver is too old" \ - " '$app' version >= $req_ver is required" - ret=1 - fi - fi - fi - done - - return $ret -} - -print_versions() { - echo "Program Min_version" - echo "----------------------" - printf %s "$buildreq" - echo "----------------------" - # can't depend on column -t -} - -# Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6. -# Also find the compatible sha1 utility on the BSDs -if test x"$SKIP_PO" = x; then - find_tool SHA1SUM sha1sum gsha1sum shasum sha1 -fi - -use_libtool=0 -# We'd like to use grep -E, to see if any of LT_INIT, -# AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac, -# but that's not portable enough (e.g., for Solaris). -grep '^[ ]*A[CM]_PROG_LIBTOOL' configure.ac >/dev/null \ - && use_libtool=1 -grep '^[ ]*LT_INIT' configure.ac >/dev/null \ - && use_libtool=1 -if test $use_libtool = 1; then - find_tool LIBTOOLIZE glibtoolize libtoolize -fi - -# gnulib-tool requires at least automake and autoconf. -# If either is not listed, add it (with minimum version) as a prerequisite. -case $buildreq in - *automake*) ;; - *) buildreq="automake 1.9 -$buildreq" ;; -esac -case $buildreq in - *autoconf*) ;; - *) buildreq="autoconf 2.59 -$buildreq" ;; -esac - -# When we can deduce that gnulib-tool will require patch, -# and when patch is not already listed as a prerequisite, add it, too. -if test -d "$local_gl_dir" \ - && ! find "$local_gl_dir" -name '*.diff' -exec false {} +; then - case $buildreq in - *patch*) ;; - *) buildreq="patch - -$buildreq" ;; - esac -fi - -if ! printf "$buildreq" | check_versions; then - echo >&2 - if test -f README-prereq; then - die "See README-prereq for how to get the prerequisite programs" - else - die "Please install the prerequisite programs" - fi -fi - -# Warn the user if autom4te appears to be broken; this causes known -# issues with at least gettext 0.18.3. -probe=$(echo 'm4_quote([hi])' | autom4te -l M4sugar -t 'm4_quote:$%' -) -if test "x$probe" != xhi; then - warn_ "WARNING: your autom4te wrapper eats stdin;" - warn_ "if bootstrap fails, consider upgrading your autotools" -fi - -echo "$0: Bootstrapping from checked-out $package sources..." - -# See if we can use gnulib's git-merge-changelog merge driver. -if $use_git && test -d .git && check_exists git; then - if git config merge.merge-changelog.driver >/dev/null ; then - : - elif check_exists git-merge-changelog; then - echo "$0: initializing git-merge-changelog driver" - git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver' - git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B' - else - echo "$0: consider installing git-merge-changelog from gnulib" - fi -fi - - -cleanup_gnulib() { - status=$? - rm -fr "$gnulib_path" - exit $status -} - -git_modules_config () { - test -f .gitmodules && git config --file .gitmodules "$@" -} - -if $use_gnulib; then - if $use_git; then - gnulib_path=$(git_modules_config submodule.gnulib.path) - test -z "$gnulib_path" && gnulib_path=gnulib - fi - - # Get gnulib files. Populate $GNULIB_SRCDIR, possibly updating a - # submodule, for use in the rest of the script. - - case ${GNULIB_SRCDIR--} in - -) - # Note that $use_git is necessarily true in this case. - if git_modules_config submodule.gnulib.url >/dev/null; then - echo "$0: getting gnulib files..." - git submodule init -- "$gnulib_path" || exit $? - git submodule update -- "$gnulib_path" || exit $? - - elif [ ! -d "$gnulib_path" ]; then - echo "$0: getting gnulib files..." - - trap cleanup_gnulib 1 2 13 15 - - shallow= - if test -z "$GNULIB_REVISION"; then - git clone -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2' - git clone $shallow ${GNULIB_URL:-$default_gnulib_url} "$gnulib_path" \ - || cleanup_gnulib - else - git fetch -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2' - mkdir -p "$gnulib_path" - # Only want a shallow checkout of $GNULIB_REVISION, but git does not - # support cloning by commit hash. So attempt a shallow fetch by commit - # hash to minimize the amount of data downloaded and changes needed to - # be processed, which can drastically reduce download and processing - # time for checkout. If the fetch by commit fails, a shallow fetch can - # not be performed because we do not know what the depth of the commit - # is without fetching all commits. So fallback to fetching all commits. - git -C "$gnulib_path" init - git -C "$gnulib_path" remote add origin ${GNULIB_URL:-$default_gnulib_url} - git -C "$gnulib_path" fetch $shallow origin "$GNULIB_REVISION" \ - || git -C "$gnulib_path" fetch origin \ - || cleanup_gnulib - git -C "$gnulib_path" reset --hard FETCH_HEAD - fi - - trap - 1 2 13 15 - fi - GNULIB_SRCDIR=$gnulib_path - ;; - *) - # Use GNULIB_SRCDIR directly or as a reference. - if $use_git && test -d "$GNULIB_SRCDIR"/.git && \ - git_modules_config submodule.gnulib.url >/dev/null; then - echo "$0: getting gnulib files..." - if git submodule -h|grep -- --reference > /dev/null; then - # Prefer the one-liner available in git 1.6.4 or newer. - git submodule update --init --reference "$GNULIB_SRCDIR" \ - "$gnulib_path" || exit $? - else - # This fallback allows at least git 1.5.5. - if test -f "$gnulib_path"/gnulib-tool; then - # Since file already exists, assume submodule init already complete. - git submodule update -- "$gnulib_path" || exit $? - else - # Older git can't clone into an empty directory. - rmdir "$gnulib_path" 2>/dev/null - git clone --reference "$GNULIB_SRCDIR" \ - "$(git_modules_config submodule.gnulib.url)" "$gnulib_path" \ - && git submodule init -- "$gnulib_path" \ - && git submodule update -- "$gnulib_path" \ - || exit $? - fi - fi - GNULIB_SRCDIR=$gnulib_path - fi - ;; - esac - - if test -d "$GNULIB_SRCDIR"/.git && test -n "$GNULIB_REVISION" \ - && ! git_modules_config submodule.gnulib.url >/dev/null; then - (cd "$GNULIB_SRCDIR" && git checkout "$GNULIB_REVISION") || cleanup_gnulib - fi - - # $GNULIB_SRCDIR now points to the version of gnulib to use, and - # we no longer need to use git or $gnulib_path below here. - - if $bootstrap_sync; then - cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || { - echo "$0: updating bootstrap and restarting..." - case $(sh -c 'echo "$1"' -- a) in - a) ignored=--;; - *) ignored=ignored;; - esac - exec sh -c \ - 'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \ - $ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \ - "$0" "$@" --no-bootstrap-sync - } - fi - - gnulib_tool=$GNULIB_SRCDIR/gnulib-tool - <$gnulib_tool || exit $? -fi - -# Get translations. - -download_po_files() { - subdir=$1 - domain=$2 - echo "$me: getting translations into $subdir for $domain..." - cmd=$(printf "$po_download_command_format" "$subdir" "$domain") - eval "$cmd" -} - -# Mirror .po files to $po_dir/.reference and copy only the new -# or modified ones into $po_dir. Also update $po_dir/LINGUAS. -# Note po files that exist locally only are left in $po_dir but will -# not be included in LINGUAS and hence will not be distributed. -update_po_files() { - # Directory containing primary .po files. - # Overwrite them only when we're sure a .po file is new. - po_dir=$1 - domain=$2 - - # Mirror *.po files into this dir. - # Usually contains *.s1 checksum files. - ref_po_dir="$po_dir/.reference" - - test -d $ref_po_dir || mkdir $ref_po_dir || return - download_po_files $ref_po_dir $domain \ - && ls "$ref_po_dir"/*.po 2>/dev/null | - sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return - - langs=$(cd $ref_po_dir && echo *.po | sed 's/\.po//g') - test "$langs" = '*' && langs=x - for po in $langs; do - case $po in x) continue;; esac - new_po="$ref_po_dir/$po.po" - cksum_file="$ref_po_dir/$po.s1" - if ! test -f "$cksum_file" || - ! test -f "$po_dir/$po.po" || - ! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then - echo "$me: updated $po_dir/$po.po..." - cp "$new_po" "$po_dir/$po.po" \ - && $SHA1SUM < "$new_po" > "$cksum_file" || return - fi - done -} - -case $SKIP_PO in -'') - if test -d po; then - update_po_files po $package || exit - fi - - if test -d runtime-po; then - update_po_files runtime-po $package-runtime || exit - fi;; -esac - -version_controlled_file() { - parent=$1 - file=$2 - if test -d .git; then - git rm -n "$file" > /dev/null 2>&1 - elif test -d .svn; then - svn log -r HEAD "$file" > /dev/null 2>&1 - elif test -d CVS; then - grep -F "/${file##*/}/" "$parent/CVS/Entries" 2>/dev/null | - grep '^/[^/]*/[0-9]' > /dev/null - else - warn_ "no version control for $file?" - false - fi -} - -# NOTE: we have to be careful to run both autopoint and libtoolize -# before gnulib-tool, since gnulib-tool is likely to provide newer -# versions of files "installed" by these two programs. -# Then, *after* gnulib-tool (see below), we have to be careful to -# run autoreconf in such a way that it does not run either of these -# two just-pre-run programs. - -# Import from gettext. -with_gettext=yes -grep '^[ ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \ - with_gettext=no - -if test $with_gettext = yes || test $use_libtool = 1; then - - tempbase=.bootstrap$$ - trap "rm -f $tempbase.0 $tempbase.1" 1 2 13 15 - - > $tempbase.0 > $tempbase.1 && - find . ! -type d -print | sort > $tempbase.0 || exit - - if test $with_gettext = yes; then - # Released autopoint has the tendency to install macros that have been - # obsoleted in current gnulib, so run this before gnulib-tool. - echo "$0: $AUTOPOINT --force" - $AUTOPOINT --force || exit - fi - - # Autoreconf runs aclocal before libtoolize, which causes spurious - # warnings if the initial aclocal is confused by the libtoolized - # (or worse out-of-date) macro directory. - # libtoolize 1.9b added the --install option; but we support back - # to libtoolize 1.5.22, where the install action was default. - if test $use_libtool = 1; then - install= - case $($LIBTOOLIZE --help) in - *--install*) install=--install ;; - esac - echo "running: $LIBTOOLIZE $install --copy" - $LIBTOOLIZE $install --copy - fi - - find . ! -type d -print | sort >$tempbase.1 - old_IFS=$IFS - IFS=$nl - for file in $(comm -13 $tempbase.0 $tempbase.1); do - IFS=$old_IFS - parent=${file%/*} - version_controlled_file "$parent" "$file" || { - for dot_ig in x $vc_ignore; do - test $dot_ig = x && continue - ig=$parent/$dot_ig - insert_vc_ignore "$ig" "${file##*/}" - done - } - done - IFS=$old_IFS - - rm -f $tempbase.0 $tempbase.1 - trap - 1 2 13 15 -fi - -# Import from gnulib. - -if $use_gnulib; then - gnulib_tool_options="\ - --no-changelog\ - --aux-dir=$build_aux\ - --doc-base=$doc_base\ - --lib=$gnulib_name\ - --m4-base=$m4_base/\ - --source-base=$source_base/\ - --tests-base=$tests_base\ - --local-dir=$local_gl_dir\ - $gnulib_tool_option_extras\ - " - if test $use_libtool = 1; then - case "$gnulib_tool_options " in - *' --libtool '*) ;; - *) gnulib_tool_options="$gnulib_tool_options --libtool" ;; - esac - fi - echo "$0: $gnulib_tool $gnulib_tool_options --import ..." - $gnulib_tool $gnulib_tool_options --import $gnulib_modules \ - || die "gnulib-tool failed" - - for file in $gnulib_files; do - symlink_to_dir "$GNULIB_SRCDIR" $file \ - || die "failed to symlink $file" - done -fi - -bootstrap_post_import_hook \ - || die "bootstrap_post_import_hook failed" - -# Don't proceed if there are uninitialized submodules. In particular, -# the next step will remove dangling links, which might be links into -# uninitialized submodules. -# -# Uninitialized submodules are listed with an initial dash. -if $use_git && git submodule | grep '^-' >/dev/null; then - die "some git submodules are not initialized. " \ - "Run 'git submodule update --init' and bootstrap again." -fi - -# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some -# gnulib-populated directories. Such .m4 files would cause aclocal to fail. -# The following requires GNU find 4.2.3 or newer. Considering the usual -# portability constraints of this script, that may seem a very demanding -# requirement, but it should be ok. Ignore any failure, which is fine, -# since this is only a convenience to help developers avoid the relatively -# unusual case in which a symlinked-to .m4 file is git-removed from gnulib -# between successive runs of this script. -find "$m4_base" "$source_base" \ - -depth \( -name '*.m4' -o -name '*.[ch]' \) \ - -type l -xtype l -delete > /dev/null 2>&1 - -# Invoke autoreconf with --force --install to ensure upgrades of tools -# such as ylwrap. -AUTORECONFFLAGS="--verbose --install --force -I $m4_base $ACLOCAL_FLAGS" - -# Some systems (RHEL 5) are using ancient autotools, for which the -# --no-recursive option had not been invented. Detect that lack and -# omit the option when it's not supported. FIXME in 2017: remove this -# hack when RHEL 5 autotools are updated, or when they become irrelevant. -case $($AUTORECONF --help) in - *--no-recursive*) AUTORECONFFLAGS="$AUTORECONFFLAGS --no-recursive";; -esac - -# Tell autoreconf not to invoke autopoint or libtoolize; they were run above. -echo "running: AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS" -AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS \ - || die "autoreconf failed" - -# Get some extra files from gnulib, overriding existing files. -for file in $gnulib_extra_files; do - case $file in - */INSTALL) dst=INSTALL;; - build-aux/*) dst=$build_aux/${file#build-aux/};; - *) dst=$file;; - esac - symlink_to_dir "$GNULIB_SRCDIR" $file $dst \ - || die "failed to symlink $file" -done - -if test $with_gettext = yes; then - # Create gettext configuration. - echo "$0: Creating po/Makevars from po/Makevars.template ..." - rm -f po/Makevars - sed ' - /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/ - /^COPYRIGHT_HOLDER *=/s/=.*/= '"$COPYRIGHT_HOLDER"'/ - /^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$MSGID_BUGS_ADDRESS"'| - /^XGETTEXT_OPTIONS *=/{ - s/$/ \\/ - a\ - '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+} - } - ' po/Makevars.template >po/Makevars \ - || die 'cannot generate po/Makevars' - - # If the 'gettext' module is in use, grab the latest Makefile.in.in. - # If only the 'gettext-h' module is in use, assume autopoint already - # put the correct version of this file into place. - case $gnulib_modules in - *gettext-h*) ;; - *gettext*) - cp $GNULIB_SRCDIR/build-aux/po/Makefile.in.in po/Makefile.in.in \ - || die "cannot create po/Makefile.in.in" - ;; - esac - - if test -d runtime-po; then - # Similarly for runtime-po/Makevars, but not quite the same. - rm -f runtime-po/Makevars - sed ' - /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/ - /^subdir *=.*/s/=.*/= runtime-po/ - /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/ - /^XGETTEXT_OPTIONS *=/{ - s/$/ \\/ - a\ - '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+} - } - ' po/Makevars.template >runtime-po/Makevars \ - || die 'cannot generate runtime-po/Makevars' - - # Copy identical files from po to runtime-po. - (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po) - fi -fi - -bootstrap_epilogue - -echo "$0: done. Now you can run './configure'." - -# Local Variables: -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC0" -# time-stamp-end: "; # UTC" -# End: diff --git a/bootstrap.conf b/bootstrap.conf deleted file mode 100644 index 3590aba99..000000000 --- a/bootstrap.conf +++ /dev/null @@ -1,110 +0,0 @@ -# Bootstrap configuration. - -# Copyright (C) 2006-2022 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 . - - -GNULIB_REVISION=9f48fb992a3d7e96610c4ce8be969cff2d61a01b - -# gnulib modules used by this package. -# mbswidth is used by fix-width.diff's changes to argp rather than directly. -gnulib_modules=" - argp - base64 - error - fnmatch - getdelim - getline - gettext-h - gitlog-to-changelog - mbswidth - progname - realloc-gnu - regex - save-cwd - stdbool -" - -gnulib_tool_option_extras="\ - --no-conditional-dependencies \ - --no-vc-files \ -" - -gnulib_name=libgnu -source_base=grub-core/lib/gnulib -gnulib_extra_files=" - build-aux/install-sh - build-aux/mdate-sh - build-aux/texinfo.tex - build-aux/depcomp - build-aux/config.guess - build-aux/config.sub -" - -# Additional xgettext options to use. Use "\\\newline" to break lines. -XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\ - --from-code=UTF-8\\\ -' - -checkout_only_file= -copy=true -vc_ignore= - -SKIP_PO=t - -# Build prerequisites -buildreq="\ -autoconf 2.64 -automake 1.14 -gettext - -git 1.5.5 -patch - -tar - -" - -# bootstrap doesn't give us a reasonable way to stop Automake from -# overwriting this, so we just copy our version aside and put it back later. -cp -a INSTALL INSTALL.grub - -bootstrap_post_import_hook () { - set -e - - # Instead of patching our gnulib and therefore maintaining a fork, submit - # changes to gnulib and update the hash above when they've merged. Do not - # add new patches here. - for patchname in fix-width \ - fix-regcomp-resource-leak \ - fix-regexec-resource-leak \ - fix-gcc-15-compile \ - fix-unused-value; do - patch -d grub-core/lib/gnulib -p2 \ - < "grub-core/lib/gnulib-patches/$patchname.patch" - done - - for patchname in \ - 0001-Support-POTFILES-shell \ - 0002-Handle-gettext_printf-shell-function \ - 0003-Make-msgfmt-output-in-little-endian \ - 0004-Use-SHELL-rather-than-bin-sh; do - patch -d po -p3 \ - < "po/gettext-patches/$patchname.patch" - done - FROM_BOOTSTRAP=1 ./autogen.sh - set +e # bootstrap expects this -} - -bootstrap_epilogue () { - mv INSTALL.grub INSTALL -} diff --git a/bus/bonito.c b/bus/bonito.c new file mode 100644 index 000000000..3f794c45a --- /dev/null +++ b/bus/bonito.c @@ -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 . + */ + +#include +#include + +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 new file mode 100644 index 000000000..a08e53446 --- /dev/null +++ b/bus/pci.c @@ -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 . + */ + +#include +#include + +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 new file mode 100644 index 000000000..6d185bc7f --- /dev/null +++ b/bus/usb/ohci.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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); +} + + + +/* 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); +} + + + +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; +} + + + +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 new file mode 100644 index 000000000..947f2367b --- /dev/null +++ b/bus/usb/uhci.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} + + +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 new file mode 100644 index 000000000..8289185da --- /dev/null +++ b/bus/usb/usb.c @@ -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 . + */ + +#include +#include +#include +#include + +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 + + +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 new file mode 100644 index 000000000..523abf93e --- /dev/null +++ b/bus/usb/usbhub.c @@ -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 . + */ + +#include +#include +#include +#include + +/* 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; +} + + +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 new file mode 100644 index 000000000..09e7af83e --- /dev/null +++ b/bus/usb/usbtrans.c @@ -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 . + */ + +#include +#include +#include +#include +#include + +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/commands/acpi.c similarity index 67% rename from grub-core/commands/acpi.c rename to commands/acpi.c index f72a19c03..5bbfd008b 100644 --- a/grub-core/commands/acpi.c +++ b/commands/acpi.c @@ -23,43 +23,26 @@ #include #include #include +#include #include #include +#include #include #include -#include #ifdef GRUB_MACHINE_EFI #include #include #endif -#pragma GCC diagnostic ignored "-Wcast-align" - -GRUB_MOD_LICENSE ("GPLv3+"); - -enum - { - OPTION_EXCLUDE = 0, - OPTION_LOAD_ONLY, - OPTION_V1, - OPTION_V2, - OPTION_OEMID, - OPTION_OEMTABLE, - OPTION_OEMTABLEREV, - OPTION_OEMTABLECREATOR, - OPTION_OEMTABLECREATORREV, - OPTION_NO_EBDA - }; - 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_("Export version 1 tables to the OS."), 0, ARG_TYPE_NONE}, - {"v2", '2', 0, N_("Export version 2 and version 3 tables to the OS."), 0, ARG_TYPE_NONE}, + {"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}, @@ -69,13 +52,24 @@ static const struct grub_arg_option options[] = { 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}, - /* TRANSLATORS: "hangs" here is a noun, not a verb. */ - {"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."), + {"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; @@ -134,8 +128,6 @@ grub_acpi_get_rsdpv1 (void) return grub_machine_acpi_get_rsdpv1 (); } -#if defined (__i386__) || defined (__x86_64__) - static inline int iszero (grub_uint8_t *reg, int size) { @@ -146,62 +138,50 @@ iszero (grub_uint8_t *reg, int size) return 1; } -/* Context for grub_acpi_create_ebda. */ -struct grub_acpi_create_ebda_ctx { - int ebda_len; - grub_uint64_t highestlow; -}; - -/* Helper for grub_acpi_create_ebda. */ -static int -find_hook (grub_uint64_t start, grub_uint64_t size, grub_memory_type_t type, - void *data) -{ - struct grub_acpi_create_ebda_ctx *ctx = data; - grub_uint64_t end = start + size; - if (type != GRUB_MEMORY_AVAILABLE) - return 0; - if (end > 0x100000) - end = 0x100000; - if (end > start + ctx->ebda_len - && ctx->highestlow < ((end - ctx->ebda_len) & (~0xf)) ) - ctx->highestlow = (end - ctx->ebda_len) & (~0xf); - return 0; -} - grub_err_t grub_acpi_create_ebda (void) { - struct grub_acpi_create_ebda_ctx ctx = { - .highestlow = 0 - }; - int ebda_kb_len = 0; + 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 *) (grub_addr_t) ((*((grub_uint16_t *) grub_absolute_pointer (0x40e))) << 4); - grub_dprintf ("acpi", "EBDA @%p\n", ebda); - if (ebda) - ebda_kb_len = *(grub_uint16_t *) ebda; - grub_dprintf ("acpi", "EBDA length 0x%x\n", ebda_kb_len); - if (ebda_kb_len > 16) + 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; - ctx.ebda_len = (ebda_kb_len + 1) << 10; + ebda_len = (ebda_kb_len + 1) << 10; /* FIXME: use low-memory mm allocation once it's available. */ - grub_mmap_iterate (find_hook, &ctx); - targetebda = (grub_uint8_t *) (grub_addr_t) ctx.highestlow; + grub_mmap_iterate (find_hook); + targetebda = (grub_uint8_t *) UINT_TO_PTR (highestlow); grub_dprintf ("acpi", "creating ebda @%llx\n", - (unsigned long long) ctx.highestlow); - if (! ctx.highestlow) + (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 ((grub_addr_t) targetebda, ctx.ebda_len, - GRUB_MEMORY_RESERVED); + mmapregion = grub_mmap_register (PTR_TO_UINT64 (targetebda), ebda_len, + GRUB_MACHINE_MEMORY_RESERVED); if (! mmapregion) return grub_errno; @@ -223,7 +203,7 @@ grub_acpi_create_ebda (void) { grub_dprintf ("acpi", "Scanning EBDA for old rsdpv2\n"); for (; target < targetebda + 0x400 - v2->length; target += 0x10) - if (grub_memcmp (target, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 + 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 @@ -233,7 +213,7 @@ grub_acpi_create_ebda (void) grub_dprintf ("acpi", "Copying rsdpv2 to %p\n", target); v2inebda = target; target += v2->length; - target = (grub_uint8_t *) ALIGN_UP((grub_addr_t) target, 16); + target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1); v2 = 0; break; } @@ -244,7 +224,7 @@ grub_acpi_create_ebda (void) 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, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 + if (grub_memcmp (target, "RSD PTR ", 8) == 0 && grub_byte_checksum (target, sizeof (struct grub_acpi_rsdp_v10)) == 0) { @@ -252,7 +232,7 @@ grub_acpi_create_ebda (void) grub_dprintf ("acpi", "Copying rsdpv1 to %p\n", target); v1inebda = target; target += sizeof (struct grub_acpi_rsdp_v10); - target = (grub_uint8_t *) ALIGN_UP((grub_addr_t) target, 16); + target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1); v1 = 0; break; } @@ -271,7 +251,7 @@ grub_acpi_create_ebda (void) grub_memcpy (target, v2, v2->length); v2inebda = target; target += v2->length; - target = (grub_uint8_t *) ALIGN_UP((grub_addr_t) target, 16); + target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1); v2 = 0; break; } @@ -288,7 +268,7 @@ grub_acpi_create_ebda (void) grub_memcpy (target, v1, sizeof (struct grub_acpi_rsdp_v10)); v1inebda = target; target += sizeof (struct grub_acpi_rsdp_v10); - target = (grub_uint8_t *) ALIGN_UP((grub_addr_t) target, 16); + target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1); v1 = 0; break; } @@ -305,19 +285,18 @@ grub_acpi_create_ebda (void) for (target = targetebda; target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10); target += 0x10) - if (grub_memcmp (target, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 + 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 *) grub_absolute_pointer (0x40e))) = ((grub_addr_t) targetebda) >> 4; + (*((grub_uint16_t *) 0x40e)) = ((long)targetebda) >> 4; grub_dprintf ("acpi", "EBDA switched\n"); return GRUB_ERR_NONE; } -#endif /* Create tables common to ACPIv1 and ACPIv2+ */ static void @@ -346,16 +325,15 @@ setup_common_tables (void) /* If it's FADT correct DSDT and FACS addresses. */ fadt = (struct grub_acpi_fadt *) cur->addr; - if (grub_memcmp (fadt->hdr.signature, GRUB_ACPI_FADT_SIGNATURE, - sizeof (fadt->hdr.signature)) == 0) + if (grub_memcmp (fadt->hdr.signature, "FACP", 4) == 0) { - fadt->dsdt_addr = (grub_addr_t) table_dsdt; + 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 = (grub_addr_t) table_dsdt; + fadt->dsdt_xaddr = PTR_TO_UINT64 (table_dsdt); fadt->facs_xaddr = facs_addr; } @@ -371,22 +349,22 @@ setup_common_tables (void) numoftables++; rsdt_addr = rsdt = (struct grub_acpi_table_header *) playground_ptr; - playground_ptr += sizeof (struct grub_acpi_table_header) + sizeof (grub_uint32_t) * numoftables; + playground_ptr += sizeof (struct grub_acpi_table_header) + 4 * numoftables; - rsdt_entry = (grub_uint32_t *) (rsdt + 1); + rsdt_entry = (grub_uint32_t *)(rsdt + 1); /* Fill RSDT header. */ grub_memcpy (&(rsdt->signature), "RSDT", 4); - rsdt->length = sizeof (struct grub_acpi_table_header) + sizeof (grub_uint32_t) * numoftables; + rsdt->length = sizeof (struct grub_acpi_table_header) + 4 * numoftables; rsdt->revision = 1; - grub_memcpy (&(rsdt->oemid), root_oemid, sizeof (rsdt->oemid)); - grub_memcpy (&(rsdt->oemtable), root_oemtable, sizeof (rsdt->oemtable)); + 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, sizeof (rsdt->creator_id)); + 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++) = (grub_addr_t) cur->addr; + *(rsdt_entry++) = PTR_TO_UINT32 (cur->addr); /* Recompute checksum. */ rsdt->checksum = 0; @@ -400,11 +378,10 @@ 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), GRUB_RSDP_SIGNATURE, - sizeof (rsdpv1_new->signature)); + 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 = (grub_addr_t) rsdt_addr; + 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)); @@ -425,13 +402,13 @@ setv2table (void) /* Create XSDT. */ xsdt = (struct grub_acpi_table_header *) playground_ptr; - playground_ptr += sizeof (struct grub_acpi_table_header) + sizeof (grub_uint64_t) * numoftables; + 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++) = (grub_addr_t) cur->addr; + *(xsdt_entry++) = PTR_TO_UINT64 (cur->addr); grub_memcpy (&(xsdt->signature), "XSDT", 4); - xsdt->length = sizeof (struct grub_acpi_table_header) + sizeof (grub_uint64_t) * numoftables; + 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)); @@ -444,17 +421,17 @@ setv2table (void) /* 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), GRUB_RSDP_SIGNATURE, + 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 = (grub_addr_t) rsdt_addr; + 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 = (grub_addr_t) xsdt; + rsdpv2_new->xsdt_addr = PTR_TO_UINT64 (xsdt); rsdpv2_new->checksum = 0; rsdpv2_new->checksum = 1 + ~grub_byte_checksum (rsdpv2_new, rsdpv2_new->length); @@ -479,11 +456,13 @@ free_tables (void) } static grub_err_t -grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) +grub_cmd_acpi (struct grub_extcmd *cmd, + int argc, char **args) { - struct grub_arg_list *state = ctxt->state; + 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; @@ -500,25 +479,23 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) if (! rsdp) rsdp = grub_machine_acpi_get_rsdpv1 (); - grub_dprintf ("acpi", "RSDP @%p\n", rsdp); - if (rsdp) { - grub_uint8_t *entry_ptr; + grub_uint32_t *entry_ptr; char *exclude = 0; char *load_only = 0; char *ptr; - grub_size_t tbl_addr_size; - struct grub_acpi_table_header *table_head; + /* RSDT consists of header and an array of 32-bit pointers. */ + struct grub_acpi_table_header *rsdt; - exclude = state[OPTION_EXCLUDE].set ? grub_strdup (state[OPTION_EXCLUDE].arg) : 0; + exclude = state[0].set ? grub_strdup (state[0].arg) : 0; if (exclude) { for (ptr = exclude; *ptr; ptr++) *ptr = grub_tolower (*ptr); } - load_only = state[OPTION_LOAD_ONLY].set ? grub_strdup (state[OPTION_LOAD_ONLY].arg) : 0; + load_only = state[1].set ? grub_strdup (state[1].arg) : 0; if (load_only) { for (ptr = load_only; *ptr; ptr++) @@ -528,32 +505,17 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) /* Set revision variables to replicate the same version as host. */ rev1 = ! rsdp->revision; rev2 = rsdp->revision; - if (rev2 && ((struct grub_acpi_table_header *) (grub_addr_t) ((struct grub_acpi_rsdp_v20 *) rsdp)->xsdt_addr) != NULL) - { - /* XSDT consists of header and an array of 64-bit pointers. */ - table_head = (struct grub_acpi_table_header *) (grub_addr_t) ((struct grub_acpi_rsdp_v20 *) rsdp)->xsdt_addr; - tbl_addr_size = sizeof (((struct grub_acpi_rsdp_v20 *) rsdp)->xsdt_addr); - } - else - { - /* RSDT consists of header and an array of 32-bit pointers. */ - table_head = (struct grub_acpi_table_header *) (grub_addr_t) rsdp->rsdt_addr; - tbl_addr_size = sizeof (rsdp->rsdt_addr); - } - + rsdt = (struct grub_acpi_table_header *) UINT_TO_PTR (rsdp->rsdt_addr); /* Load host tables. */ - for (entry_ptr = (grub_uint8_t *) (table_head + 1); - entry_ptr < (grub_uint8_t *) (((grub_uint8_t *) table_head) + table_head->length); - entry_ptr += tbl_addr_size) + 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; - if (tbl_addr_size == sizeof (rsdp->rsdt_addr)) - curtable = (struct grub_acpi_table_header *) (grub_addr_t) *((grub_uint32_t *) entry_ptr); - else - curtable = (struct grub_acpi_table_header *) (grub_addr_t) *((grub_uint64_t *) entry_ptr); - + 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]); @@ -565,7 +527,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) struct grub_acpi_fadt *fadt = (struct grub_acpi_fadt *) curtable; /* Set root header variables to the same values - as FADT by default. */ + as FACP by default. */ grub_memcpy (&root_oemid, &(fadt->hdr.oemid), sizeof (root_oemid)); grub_memcpy (&root_oemtable, &(fadt->hdr.oemtable), @@ -577,7 +539,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) /* Load DSDT if not excluded. */ dsdt = (struct grub_acpi_table_header *) - (grub_addr_t) fadt->dsdt_addr; + UINT_TO_PTR (fadt->dsdt_addr); if (dsdt && (! exclude || ! grub_strword (exclude, "dsdt")) && (! load_only || grub_strword (load_only, "dsdt")) && dsdt->length >= sizeof (*dsdt)) @@ -589,7 +551,8 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) free_tables (); grub_free (exclude); grub_free (load_only); - return grub_errno; + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't allocate table"); } grub_memcpy (table_dsdt, dsdt, dsdt->length); } @@ -615,7 +578,8 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) free_tables (); grub_free (exclude); grub_free (load_only); - return grub_errno; + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't allocate table structure"); } table->size = curtable->length; table->addr = grub_malloc (table->size); @@ -623,10 +587,8 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) if (! table->addr) { free_tables (); - grub_free (exclude); - grub_free (load_only); - grub_free (table); - return grub_errno; + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't allocate table"); } table->next = acpi_tables; acpi_tables = table; @@ -637,26 +599,26 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) } /* Does user specify versions to generate? */ - if (state[OPTION_V1].set || state[OPTION_V2].set) + if (state[2].set || state[3].set) { - rev1 = state[OPTION_V1].set; - if (state[OPTION_V2].set) + rev1 = state[2].set; + if (state[3].set) rev2 = rev2 ? : 2; else rev2 = 0; } /* Does user override root header information? */ - if (state[OPTION_OEMID].set) - grub_strncpy (root_oemid, state[OPTION_OEMID].arg, sizeof (root_oemid)); - if (state[OPTION_OEMTABLE].set) - grub_strncpy (root_oemtable, state[OPTION_OEMTABLE].arg, sizeof (root_oemtable)); - if (state[OPTION_OEMTABLEREV].set) - root_oemrev = grub_strtoul (state[OPTION_OEMTABLEREV].arg, 0, 0); - if (state[OPTION_OEMTABLECREATOR].set) - grub_strncpy (root_creator_id, state[OPTION_OEMTABLECREATOR].arg, sizeof (root_creator_id)); - if (state[OPTION_OEMTABLECREATORREV].set) - root_creator_rev = grub_strtoul (state[OPTION_OEMTABLECREATORREV].arg, 0, 0); + 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++) @@ -665,11 +627,11 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) grub_size_t size; char *buf; - file = grub_file_open (args[i], GRUB_FILE_TYPE_ACPI_TABLE); + file = grub_gzfile_open (args[i], 1); if (! file) { free_tables (); - return grub_errno; + return grub_error (GRUB_ERR_BAD_OS, "couldn't open file %s", args[i]); } size = grub_file_size (file); @@ -677,8 +639,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) { grub_file_close (file); free_tables (); - return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - args[i]); + return grub_error (GRUB_ERR_BAD_OS, "file %s is too small", args[i]); } buf = (char *) grub_malloc (size); @@ -686,17 +647,15 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) { grub_file_close (file); free_tables (); - return grub_errno; + 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 (); - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - args[i]); - return grub_errno; + return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[i]); } grub_file_close (file); @@ -715,7 +674,8 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) if (! table) { free_tables (); - return grub_errno; + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't allocate table structure"); } table->size = size; @@ -734,17 +694,17 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) /* DSDT. */ playground_size += dsdt_size; /* RSDT. */ - playground_size += sizeof (struct grub_acpi_table_header) + sizeof (grub_uint32_t) * numoftables; + 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) + sizeof (grub_uint64_t) * numoftables; + 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_MEMORY_ACPI, 0); + GRUB_MACHINE_MEMORY_ACPI, 0); if (! playground) { @@ -771,30 +731,23 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) } acpi_tables = 0; -#if defined (__i386__) || defined (__x86_64__) - if (! state[OPTION_NO_EBDA].set) + if (! state[9].set && (err = grub_acpi_create_ebda ())) { - grub_err_t err; - err = grub_acpi_create_ebda (); - if (err) - { - rsdpv1_new = 0; - rsdpv2_new = 0; - grub_mmap_free_and_unregister (mmapregion); - return err; - } + rsdpv1_new = 0; + rsdpv2_new = 0; + grub_mmap_free_and_unregister (mmapregion); + return err; } -#endif #ifdef GRUB_MACHINE_EFI { - static grub_guid_t acpi = GRUB_EFI_ACPI_TABLE_GUID; - static grub_guid_t acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID; + 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 ()); + 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 @@ -805,13 +758,14 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(acpi) { - cmd = grub_register_extcmd_lockdown ("acpi", grub_cmd_acpi, 0, - N_("[-1|-2] [--exclude=TABLE1,TABLE2|" - "--load-only=TABLE1,TABLE2] FILE1" - " [FILE2] [...]"), - N_("Load host ACPI tables and tables " - "specified by arguments."), - options); + 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) diff --git a/commands/blocklist.c b/commands/blocklist.c new file mode 100644 index 000000000..fec59a828 --- /dev/null +++ b/commands/blocklist.c @@ -0,0 +1,120 @@ +/* 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +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"); + + if (file->device->disk->partition) + 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; + +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/commands/boot.c similarity index 62% rename from grub-core/commands/boot.c rename to commands/boot.c index 61514788e..1ec1e6f77 100644 --- a/grub-core/commands/boot.c +++ b/commands/boot.c @@ -25,58 +25,23 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); +static grub_err_t (*grub_loader_boot_func) (void); +static grub_err_t (*grub_loader_unload_func) (void); +static int grub_loader_noreturn; -static grub_err_t (*grub_loader_boot_func) (void *context); -static grub_err_t (*grub_loader_unload_func) (void *context); -static void *grub_loader_context; -static int grub_loader_flags; - -struct grub_simple_loader_hooks -{ - grub_err_t (*boot) (void); - grub_err_t (*unload) (void); -}; - -/* Don't heap allocate this to avoid making grub_loader_set() fallible. */ -static struct grub_simple_loader_hooks simple_loader_hooks; - -struct grub_preboot +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 *next; - struct grub_preboot *prev; + struct grub_preboot_t *next; + struct grub_preboot_t *prev; }; static int grub_loader_loaded; -static struct grub_preboot *preboots_head = 0, +static struct grub_preboot_t *preboots_head = 0, *preboots_tail = 0; -static grub_err_t -grub_simple_boot_hook (void *context) -{ - struct grub_simple_loader_hooks *hooks; - - hooks = (struct grub_simple_loader_hooks *) context; - return hooks->boot (); -} - -static grub_err_t -grub_simple_unload_hook (void *context) -{ - struct grub_simple_loader_hooks *hooks; - grub_err_t ret; - - hooks = (struct grub_simple_loader_hooks *) context; - - ret = hooks->unload (); - grub_memset (hooks, 0, sizeof (*hooks)); - - return ret; -} - int grub_loader_is_loaded (void) { @@ -84,20 +49,23 @@ grub_loader_is_loaded (void) } /* Register a preboot hook. */ -struct grub_preboot * -grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int flags), +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 *cur, *new_preboot; + struct grub_preboot_t *cur, *new_preboot; if (! preboot_func && ! preboot_rest_func) return 0; - new_preboot = (struct grub_preboot *) - grub_malloc (sizeof (struct grub_preboot)); + new_preboot = (struct grub_preboot_t *) + grub_malloc (sizeof (struct grub_preboot_t)); if (! new_preboot) - return 0; + { + 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; @@ -126,9 +94,9 @@ grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int flags), } void -grub_loader_unregister_preboot_hook (struct grub_preboot *hnd) +grub_loader_unregister_preboot_hook (void *hnd) { - struct grub_preboot *preb = hnd; + struct grub_preboot_t *preb = hnd; if (preb->next) preb->next->prev = preb->prev; @@ -143,45 +111,28 @@ grub_loader_unregister_preboot_hook (struct grub_preboot *hnd) } void -grub_loader_set_ex (grub_err_t (*boot) (void *context), - grub_err_t (*unload) (void *context), - void *context, - int flags) +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_context); + grub_loader_unload_func (); grub_loader_boot_func = boot; grub_loader_unload_func = unload; - grub_loader_context = context; - grub_loader_flags = flags; + grub_loader_noreturn = noreturn; grub_loader_loaded = 1; } -void -grub_loader_set (grub_err_t (*boot) (void), - grub_err_t (*unload) (void), - int flags) -{ - grub_loader_set_ex (grub_simple_boot_hook, - grub_simple_unload_hook, - &simple_loader_hooks, - flags); - - simple_loader_hooks.boot = boot; - simple_loader_hooks.unload = unload; -} - void grub_loader_unset(void) { if (grub_loader_loaded && grub_loader_unload_func) - grub_loader_unload_func (grub_loader_context); + grub_loader_unload_func (); grub_loader_boot_func = 0; grub_loader_unload_func = 0; - grub_loader_context = 0; grub_loader_loaded = 0; } @@ -190,17 +141,17 @@ grub_err_t grub_loader_boot (void) { grub_err_t err = GRUB_ERR_NONE; - struct grub_preboot *cur; + struct grub_preboot_t *cur; if (! grub_loader_loaded) - return grub_error (GRUB_ERR_NO_KERNEL, - N_("you need to load the kernel first")); + return grub_error (GRUB_ERR_NO_KERNEL, "no loaded kernel"); - grub_machine_fini (grub_loader_flags); + if (grub_loader_noreturn) + grub_machine_fini (); for (cur = preboots_head; cur; cur = cur->next) { - err = cur->preboot_func (grub_loader_flags); + err = cur->preboot_func (grub_loader_noreturn); if (err) { for (cur = cur->prev; cur; cur = cur->prev) @@ -208,7 +159,7 @@ grub_loader_boot (void) return err; } } - err = (grub_loader_boot_func) (grub_loader_context); + err = (grub_loader_boot_func) (); for (cur = preboots_tail; cur; cur = cur->prev) if (! err) diff --git a/commands/cat.c b/commands/cat.c new file mode 100644 index 000000000..3bdafc4c6 --- /dev/null +++ b/commands/cat.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +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; + +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/commands/cmp.c similarity index 56% rename from grub-core/commands/cmp.c rename to commands/cmp.c index 46185fbbc..626e1d022 100644 --- a/grub-core/commands/cmp.c +++ b/commands/cmp.c @@ -21,22 +21,14 @@ #include #include #include +#include #include -#include #include -GRUB_MOD_LICENSE ("GPLv3+"); - #define BUFFER_SIZE 512 -static const struct grub_arg_option options[] = - { - {0, 'v', 0, N_("Enable verbose output"), 0, 0}, - {0, 0, 0, 0, 0, 0} - }; - static grub_err_t -grub_cmd_cmp (grub_extcmd_context_t ctxt, +grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { grub_ssize_t rd1, rd2; @@ -45,23 +37,22 @@ grub_cmd_cmp (grub_extcmd_context_t ctxt, grub_file_t file2 = 0; char *buf1 = 0; char *buf2 = 0; - grub_err_t err = GRUB_ERR_TEST_FAILURE; if (argc != 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required"); - if (ctxt->state[0].set) - grub_printf_ (N_("Compare file `%s' with `%s':\n"), args[0], args[1]); + grub_printf ("Compare file `%s' with `%s':\n", args[0], + args[1]); - file1 = grub_file_open (args[0], GRUB_FILE_TYPE_CMP); - file2 = grub_file_open (args[1], GRUB_FILE_TYPE_CMP); + file1 = grub_gzfile_open (args[0], 1); + file2 = grub_gzfile_open (args[1], 1); if (! file1 || ! file2) goto cleanup; - if (ctxt->state[0].set && (grub_file_size (file1) != grub_file_size (file2))) - grub_printf_ (N_("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]); + 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; @@ -86,10 +77,9 @@ grub_cmd_cmp (grub_extcmd_context_t ctxt, { if (buf1[i] != buf2[i]) { - if (ctxt->state[0].set) - grub_printf_ (N_("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]); + 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; } } @@ -98,34 +88,32 @@ grub_cmd_cmp (grub_extcmd_context_t ctxt, } while (rd2); - /* TRANSLATORS: it's always exactly 2 files. */ - if (ctxt->state[0].set) - grub_printf_ (N_("The files are identical.\n")); - err = GRUB_ERR_NONE; + grub_printf ("The files are identical.\n"); } cleanup: - grub_free (buf1); - grub_free (buf2); + if (buf1) + grub_free (buf1); + if (buf2) + grub_free (buf2); if (file1) grub_file_close (file1); if (file2) grub_file_close (file2); - return err; + return grub_errno; } -static grub_extcmd_t cmd; +static grub_command_t cmd; GRUB_MOD_INIT(cmp) { - cmd = grub_register_extcmd ("cmp", grub_cmd_cmp, 0, - N_("FILE1 FILE2"), N_("Compare two files."), - options); + cmd = grub_register_command ("cmp", grub_cmd_cmp, + N_("FILE1 FILE2"), N_("Compare two files.")); } GRUB_MOD_FINI(cmp) { - grub_unregister_extcmd (cmd); + grub_unregister_command (cmd); } diff --git a/grub-core/commands/configfile.c b/commands/configfile.c similarity index 63% rename from grub-core/commands/configfile.c rename to commands/configfile.c index f2d2abb5f..469447711 100644 --- a/grub-core/commands/configfile.c +++ b/commands/configfile.c @@ -24,39 +24,31 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - static grub_err_t grub_cmd_source (grub_command_t cmd, int argc, char **args) { - int new_env, extractor; + int new_env; if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); - extractor = (cmd->name[0] == 'e'); - new_env = (cmd->name[extractor ? sizeof ("extract_entries_") - 1 : 0] == 'c'); + new_env = (cmd->name[0] == 'c'); if (new_env) - grub_cls (); - - if (new_env && !extractor) - grub_env_context_open (); - if (extractor) - grub_env_extractor_open (!new_env); + { + grub_cls (); + grub_env_context_open (1); + } grub_normal_execute (args[0], 1, ! new_env); - if (new_env && !extractor) + if (new_env) grub_env_context_close (); - if (extractor) - grub_env_extractor_close (!new_env); return 0; } static grub_command_t cmd_configfile, cmd_source, cmd_dot; -static grub_command_t cmd_extractor_source, cmd_extractor_configfile; GRUB_MOD_INIT(configfile) { @@ -68,19 +60,6 @@ GRUB_MOD_INIT(configfile) N_("FILE"), N_("Load another config file without changing context.") ); - - cmd_extractor_source = - grub_register_command ("extract_entries_source", grub_cmd_source, - N_("FILE"), - N_("Load another config file without changing context but take only menu entries.") - ); - - cmd_extractor_configfile = - grub_register_command ("extract_entries_configfile", grub_cmd_source, - N_("FILE"), - N_("Load another config file but take only menu entries.") - ); - cmd_dot = grub_register_command (".", grub_cmd_source, N_("FILE"), @@ -92,7 +71,5 @@ GRUB_MOD_FINI(configfile) { grub_unregister_command (cmd_configfile); grub_unregister_command (cmd_source); - grub_unregister_command (cmd_extractor_configfile); - grub_unregister_command (cmd_extractor_source); grub_unregister_command (cmd_dot); } diff --git a/commands/crc.c b/commands/crc.c new file mode 100644 index 000000000..1c1a690aa --- /dev/null +++ b/commands/crc.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +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/commands/date.c similarity index 97% rename from grub-core/commands/date.c rename to commands/date.c index 5cb4fafd4..623db4943 100644 --- a/grub-core/commands/date.c +++ b/commands/date.c @@ -24,8 +24,6 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - #define GRUB_DATETIME_SET_YEAR 1 #define GRUB_DATETIME_SET_MONTH 2 #define GRUB_DATETIME_SET_DAY 4 @@ -59,8 +57,7 @@ grub_cmd_date (grub_command_t cmd __attribute__ ((unused)), for (; argc; argc--, args++) { - const char *p; - char c; + char *p, c; int m1, ofs, n, cur_mask; p = args[0]; @@ -140,7 +137,7 @@ GRUB_MOD_INIT(date) cmd = grub_register_command ("date", grub_cmd_date, N_("[[year-]month-day] [hour:minute[:second]]"), - N_("Display/set current datetime.")); + N_("Command to display/set current datetime.")); } GRUB_MOD_FINI(date) diff --git a/grub-core/commands/echo.c b/commands/echo.c similarity index 72% rename from grub-core/commands/echo.c rename to commands/echo.c index f95877285..4fea091cb 100644 --- a/grub-core/commands/echo.c +++ b/commands/echo.c @@ -1,7 +1,7 @@ /* echo.c - Command to display a line of text */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2010 Free Software Foundation, Inc. + * 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 @@ -21,9 +21,6 @@ #include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); static const struct grub_arg_option options[] = { @@ -33,9 +30,9 @@ static const struct grub_arg_option options[] = }; static grub_err_t -grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args) +grub_cmd_echo (grub_extcmd_t cmd, int argc, char **args) { - struct grub_arg_list *state = ctxt->state; + struct grub_arg_list *state = cmd->state; int newline = 1; int i; @@ -46,14 +43,8 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args) for (i = 0; i < argc; i++) { char *arg = *args; - /* Unescaping results in a string no longer than the original. */ - char *unescaped = grub_malloc (grub_strlen (arg) + 1); - char *p = unescaped; args++; - if (!unescaped) - return grub_errno; - while (*arg) { /* In case `-e' is used, parse backslashes. */ @@ -66,11 +57,11 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args) switch (*arg) { case '\\': - *p++ = '\\'; + grub_printf ("\\"); break; case 'a': - *p++ = '\a'; + grub_printf ("\a"); break; case 'c': @@ -78,23 +69,23 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args) break; case 'f': - *p++ = '\f'; + grub_printf ("\f"); break; case 'n': - *p++ = '\n'; + grub_printf ("\n"); break; case 'r': - *p++ = '\r'; + grub_printf ("\r"); break; case 't': - *p++ = '\t'; + grub_printf ("\t"); break; case 'v': - *p++ = '\v'; + grub_printf ("\v"); break; } arg++; @@ -103,14 +94,10 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args) /* This was not an escaped character, or escaping is not enabled. */ - *p++ = *arg; + grub_printf ("%c", *arg); arg++; } - *p = '\0'; - grub_xputs (unescaped); - grub_free (unescaped); - /* If another argument follows, insert a space. */ if (i != argc - 1) grub_printf (" " ); @@ -119,8 +106,6 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args) if (newline) grub_printf ("\n"); - grub_refresh (); - return 0; } @@ -128,9 +113,7 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(echo) { - cmd = grub_register_extcmd ("echo", grub_cmd_echo, - GRUB_COMMAND_ACCEPT_DASH - | GRUB_COMMAND_OPTIONS_AT_START, + cmd = grub_register_extcmd ("echo", grub_cmd_echo, GRUB_COMMAND_FLAG_BOTH, N_("[-e|-n] STRING"), N_("Display a line of text."), options); } diff --git a/grub-core/kern/efi/acpi.c b/commands/efi/acpi.c similarity index 51% rename from grub-core/kern/efi/acpi.c rename to commands/efi/acpi.c index 828e6dbb2..93a560d9c 100644 --- a/grub-core/kern/efi/acpi.c +++ b/commands/efi/acpi.c @@ -18,20 +18,42 @@ */ #include +#include #include +#include struct grub_acpi_rsdp_v10 * grub_machine_acpi_get_rsdpv1 (void) { - static grub_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID; + unsigned i; + static grub_efi_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID; - return (struct grub_acpi_rsdp_v10 *) grub_efi_find_configuration_table (&acpi_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) { - static grub_guid_t acpi20_guid = GRUB_EFI_ACPI_20_TABLE_GUID; + unsigned i; + static grub_efi_guid_t acpi20_guid = GRUB_EFI_ACPI_20_TABLE_GUID; - return (struct grub_acpi_rsdp_v20 *) grub_efi_find_configuration_table (&acpi20_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/commands/efi/fixvideo.c similarity index 81% rename from grub-core/commands/efi/fixvideo.c rename to commands/efi/fixvideo.c index d9d54a2e8..6430be5e3 100644 --- a/grub-core/commands/efi/fixvideo.c +++ b/commands/efi/fixvideo.c @@ -23,9 +23,6 @@ #include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); static struct grub_video_patch { @@ -41,9 +38,8 @@ static struct grub_video_patch {0, 0, 0, 0, 0} }; -static int -scan_card (grub_pci_device_t dev, grub_pci_id_t pciid, - void *data __attribute__ ((unused))) +static int NESTED_FUNC_ATTR +scan_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_pci_address_t addr; @@ -56,26 +52,26 @@ scan_card (grub_pci_device_t dev, grub_pci_id_t pciid, { if (p->pci_id == pciid) { - grub_addr_t base; + grub_target_addr_t base; - grub_dprintf ("fixvideo", "Found graphic card: %s\n", p->name); + 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_dprintf ("fixvideo", "Invalid MMIO bar %d\n", p->mmio_bar); + 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_dprintf ("fixvideo", "Old value doesn't match\n"); + grub_printf ("Old value don't match\n"); else { *((volatile grub_uint32_t *) base) = 0; if (*((volatile grub_uint32_t *) base)) - grub_dprintf ("fixvideo", "Setting MMIO fails\n"); + grub_printf ("Set MMIO fails\n"); } } @@ -84,7 +80,7 @@ scan_card (grub_pci_device_t dev, grub_pci_id_t pciid, p++; } - grub_dprintf ("fixvideo", "Unknown graphic card: %x\n", pciid); + grub_printf ("Unknown graphic card: %x\n", pciid); } return 0; @@ -95,7 +91,7 @@ grub_cmd_fixvideo (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused))) { - grub_pci_iterate (scan_card, NULL); + grub_pci_iterate (scan_card); return 0; } diff --git a/grub-core/commands/efi/loadbios.c b/commands/efi/loadbios.c similarity index 69% rename from grub-core/commands/efi/loadbios.c rename to commands/efi/loadbios.c index 8e042095a..8c7c25abd 100644 --- a/grub-core/commands/efi/loadbios.c +++ b/commands/efi/loadbios.c @@ -25,11 +25,9 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID; -static grub_guid_t acpi2_guid = GRUB_EFI_ACPI_20_TABLE_GUID; -static grub_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID; +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 @@ -46,10 +44,10 @@ enable_rom_area (void) grub_uint32_t *rom_ptr; grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0}; - rom_ptr = grub_absolute_pointer (VBIOS_ADDR); + rom_ptr = (grub_uint32_t *) VBIOS_ADDR; if (*rom_ptr != BLANK_MEM) { - grub_puts_ (N_("ROM image is present.")); + grub_printf ("ROM image is present.\n"); return 0; } @@ -67,7 +65,7 @@ enable_rom_area (void) *rom_ptr = 0; if (*rom_ptr != 0) { - grub_puts_ (N_("Can\'t enable ROM area.")); + grub_printf ("Can\'t enable ROM area.\n"); return 0; } @@ -92,29 +90,47 @@ lock_rom_area (void) 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_absolute_pointer (EBDA_SEG_ADDR); - low_mem_ptr = grub_absolute_pointer (LOW_MEM_ADDR); + 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 = grub_efi_find_configuration_table (&acpi2_guid); - grub_dprintf ("efi", "ACPI2: %p\n", acpi); - if (!acpi) { - acpi = grub_efi_find_configuration_table (&acpi_guid); - grub_dprintf ("efi", "ACPI: %p\n", acpi); - } + 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; - smbios = grub_efi_find_configuration_table (&smbios_guid); - grub_dprintf ("efi", "SMBIOS: %p\n", smbios); + 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; */ - *((grub_uint16_t *) (grub_absolute_pointer (FAKE_EBDA_SEG << 4))) = 640 - *low_mem_ptr; + *((grub_uint16_t *) (FAKE_EBDA_SEG << 4)) = 640 - *low_mem_ptr; if (acpi) grub_memcpy ((char *) ((FAKE_EBDA_SEG << 4) + 16), acpi, 1024 - 16); @@ -147,11 +163,11 @@ grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)), int size; if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no ROM image specified"); if (argc > 1) { - file = grub_file_open (argv[1], GRUB_FILE_TYPE_VBE_DUMP); + file = grub_file_open (argv[1]); if (! file) return grub_errno; @@ -165,7 +181,7 @@ grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)), return grub_errno; } - file = grub_file_open (argv[0], GRUB_FILE_TYPE_VBE_DUMP); + file = grub_file_open (argv[0]); if (! file) return grub_errno; @@ -187,14 +203,12 @@ static grub_command_t cmd_fakebios, cmd_loadbios; GRUB_MOD_INIT(loadbios) { - cmd_fakebios = grub_register_command_lockdown ("fakebios", grub_cmd_fakebios, - 0, N_("Create BIOS-like structures for" - " backward compatibility with" - " existing OS.")); + cmd_fakebios = grub_register_command ("fakebios", grub_cmd_fakebios, + 0, N_("Fake BIOS.")); - cmd_loadbios = grub_register_command_lockdown ("loadbios", grub_cmd_loadbios, - N_("BIOS_DUMP [INT10_DUMP]"), - N_("Load BIOS dump.")); + cmd_loadbios = grub_register_command ("loadbios", grub_cmd_loadbios, + "BIOS_DUMP [INT10_DUMP]", + N_("Load BIOS dump.")); } GRUB_MOD_FINI(loadbios) diff --git a/commands/extcmd.c b/commands/extcmd.c new file mode 100644 index 000000000..16796febf --- /dev/null +++ b/commands/extcmd.c @@ -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 . + */ + +#include +#include +#include +#include + +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/commands/gptsync.c similarity index 86% rename from grub-core/commands/gptsync.c rename to commands/gptsync.c index 444e24874..d217b5d5c 100644 --- a/grub-core/commands/gptsync.c +++ b/commands/gptsync.c @@ -29,19 +29,17 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - /* 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 (grub_uint32_t lba, grub_uint8_t *cl, grub_uint8_t *ch, +lba_to_chs (int lba, grub_uint8_t *cl, grub_uint8_t *ch, grub_uint8_t *dh) { - grub_uint32_t cylinder, head, sector; - grub_uint32_t sectors = 63, heads = 255, cylinders = 1024; + int cylinder, head, sector; + int sectors = 63, heads = 255, cylinders = 1024; sector = lba % sectors + 1; head = (lba / sectors) % heads; @@ -67,7 +65,6 @@ grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)), struct grub_partition *partition; grub_disk_addr_t first_sector; int numactive = 0; - int i; if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); @@ -101,22 +98,20 @@ grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)), } /* Check if it is valid. */ - if (mbr.signature != grub_cpu_to_le16_compile_time (GRUB_PC_PARTITION_SIGNATURE)) + 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. */ - for (i = 0; i < 4; i++) - if (mbr.entries[i].type == GRUB_PC_PARTITION_TYPE_GPT_DISK) - break; - if (i == 4) + 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++) { @@ -136,16 +131,15 @@ grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)), if (! partition) { grub_device_close (dev); - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - N_("no such partition")); + 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 residing in the first 2TB " - "can be present in hybrid MBR"); + "only partitions resding in the first 2TB " + "can be presen in hybrid MBR"); } @@ -216,7 +210,7 @@ grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)), 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_compile_time (1); + mbr.entries[0].start = grub_cpu_to_le32 (1); lba_to_chs (1, &(mbr.entries[0].start_sector), &(mbr.entries[0].start_cylinder), @@ -227,7 +221,7 @@ grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)), &(mbr.entries[0].end_head)); mbr.entries[0].length = grub_cpu_to_le32 (first_sector); - mbr.signature = grub_cpu_to_le16_compile_time (GRUB_PC_PARTITION_SIGNATURE); + mbr.signature = grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE); if (grub_disk_write (dev->disk, 0, 0, sizeof (mbr), &mbr)) { @@ -235,9 +229,7 @@ grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)), return grub_errno; } - grub_device_close (dev); - - grub_printf_ (N_("New MBR is written to `%s'\n"), args[0]); + grub_printf ("New MBR is written to '%s'\n", args[0]); return GRUB_ERR_NONE; } @@ -250,11 +242,9 @@ GRUB_MOD_INIT(gptsync) (void) mod; /* To stop warning. */ cmd = grub_register_command ("gptsync", grub_cmd_gptsync, N_("DEVICE [PARTITION[+/-[TYPE]]] ..."), - /* TRANSLATORS: MBR type is one-byte partition - type id. */ N_("Fill hybrid MBR of GPT drive DEVICE. " - "Specified partitions will be a part " - "of hybrid MBR. Up to 3 partitions are " + "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.")); diff --git a/grub-core/commands/halt.c b/commands/halt.c similarity index 90% rename from grub-core/commands/halt.c rename to commands/halt.c index 8f2e88040..3400115a0 100644 --- a/grub-core/commands/halt.c +++ b/commands/halt.c @@ -22,14 +22,13 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t __attribute__ ((noreturn)) +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; @@ -37,7 +36,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(halt) { cmd = grub_register_command ("halt", grub_cmd_halt, - 0, N_("Halts the computer. This command does" + 0, N_("Halts the computer. This command does" " not work on all firmware implementations.")); } diff --git a/commands/handler.c b/commands/handler.c new file mode 100644 index 000000000..f9270972b --- /dev/null +++ b/commands/handler.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +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/commands/hashsum.c similarity index 55% rename from grub-core/commands/hashsum.c rename to commands/hashsum.c index d56b5b0bb..951479fa7 100644 --- a/grub-core/commands/hashsum.c +++ b/commands/hashsum.c @@ -24,28 +24,21 @@ #include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); 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 hashes of files with hash list FILE."), - N_("FILE"), ARG_TYPE_STRING}, - {"prefix", 'p', 0, N_("Base directory for hash list."), N_("DIR"), + {"hash", 'h', 0, "Specify hash to use.", "HASH", ARG_TYPE_STRING}, + {"check", 'c', 0, "Check hash list file.", "FILE", ARG_TYPE_STRING}, + {"prefix", 'p', 0, "Base directory for hash list.", "DIRECTORY", ARG_TYPE_STRING}, - {"keep-going", 'k', 0, N_("Don't stop after first error."), 0, 0}, - {"uncompress", 'u', 0, N_("Uncompress file before checksumming."), 0, 0}, + {"keep-going", 'k', 0, "Don't stop after first error.", 0, 0}, {0, 0, 0, 0, 0, 0} }; -static struct { const char *name; const char *hashname; } aliases[] = +struct { const char *name; const char *hashname; } aliases[] = { {"sha256sum", "sha256"}, {"sha512sum", "sha512"}, - {"sha1sum", "sha1"}, {"md5sum", "md5"}, - {"crc", "crc32"}, }; static inline int @@ -63,23 +56,17 @@ hextoval (char c) static grub_err_t hash_file (grub_file_t file, const gcry_md_spec_t *hash, void *result) { - void *context; - grub_uint8_t *readbuf; -#define BUF_SIZE 4096 - readbuf = grub_malloc (BUF_SIZE); - if (!readbuf) - return grub_errno; - context = grub_zalloc (hash->contextsize); - if (!readbuf || !context) - goto fail; + 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, BUF_SIZE); + r = grub_file_read (file, readbuf, sizeof (readbuf)); if (r < 0) - goto fail; + return grub_errno; if (r == 0) break; hash->write (context, readbuf, r); @@ -87,78 +74,51 @@ hash_file (grub_file_t file, const gcry_md_spec_t *hash, void *result) hash->final (context); grub_memcpy (result, hash->read (context), hash->mdlen); - grub_free (readbuf); - grub_free (context); - return GRUB_ERR_NONE; - - fail: - grub_free (readbuf); - grub_free (context); - return grub_errno; } static grub_err_t check_list (const gcry_md_spec_t *hash, const char *hashfilename, - const char *prefix, int keep, int uncompress) + const char *prefix, int keep) { grub_file_t hashlist, file; char *buf = NULL; - grub_uint8_t expected[GRUB_CRYPTO_MAX_MDLEN]; - grub_uint8_t actual[GRUB_CRYPTO_MAX_MDLEN]; + grub_uint8_t expected[hash->mdlen]; + grub_uint8_t actual[hash->mdlen]; grub_err_t err; unsigned i; unsigned unread = 0, mismatch = 0; - if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN) - return grub_error (GRUB_ERR_BUG, "mdlen is too long"); - - hashlist = grub_file_open (hashfilename, GRUB_FILE_TYPE_HASHLIST); + hashlist = grub_file_open (hashfilename); if (!hashlist) return grub_errno; - + while (grub_free (buf), (buf = grub_file_getline (hashlist))) { const char *p = buf; - while (grub_isspace (p[0])) - p++; for (i = 0; i < hash->mdlen; i++) { int high, low; high = hextoval (*p++); low = hextoval (*p++); if (high < 0 || low < 0) - { - grub_free (buf); - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); - } + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); expected[i] = (high << 4) | low; } - if ((p[0] != ' ' && p[0] != '\t') || (p[1] != ' ' && p[1] != '\t')) - { - grub_free (buf); - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); - } - p += 2; + 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) - { - grub_free (buf); - return grub_errno; - } - file = grub_file_open (filename, GRUB_FILE_TYPE_TO_HASH - | (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS - : GRUB_FILE_TYPE_NONE)); + return grub_errno; + file = grub_file_open (filename); grub_free (filename); } else - file = grub_file_open (p, GRUB_FILE_TYPE_TO_HASH - | (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS - : GRUB_FILE_TYPE_NONE)); + file = grub_file_open (p); if (!file) { grub_file_close (hashlist); @@ -169,7 +129,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, grub_file_close (file); if (err) { - grub_printf_ (N_("%s: READ ERROR\n"), p); + grub_printf ("%s: READ ERROR\n", p); if (!keep) { grub_file_close (hashlist); @@ -183,7 +143,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, } if (grub_crypto_memcmp (expected, actual, hash->mdlen) != 0) { - grub_printf_ (N_("%s: HASH MISMATCH\n"), p); + grub_printf ("%s: HASH MISMATCH\n", p); if (!keep) { grub_file_close (hashlist); @@ -192,9 +152,9 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, "hash of '%s' mismatches", p); } mismatch++; - continue; + continue; } - grub_printf_ (N_("%s: OK\n"), p); + grub_printf ("%s: OK\n", p); } if (mismatch || unread) return grub_error (GRUB_ERR_TEST_FAILURE, @@ -204,20 +164,19 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, } static grub_err_t -grub_cmd_hashsum (struct grub_extcmd_context *ctxt, +grub_cmd_hashsum (struct grub_extcmd *cmd, int argc, char **args) { - struct grub_arg_list *state = ctxt->state; + 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; - int uncompress = state[4].set; unsigned unread = 0; for (i = 0; i < ARRAY_SIZE (aliases); i++) - if (grub_strcmp (ctxt->extcmd->cmd->name, aliases[i].name) == 0) + if (grub_strcmp (cmd->cmd->name, aliases[i].name) == 0) hashname = aliases[i].hashname; if (state[0].set) hashname = state[0].arg; @@ -229,9 +188,6 @@ grub_cmd_hashsum (struct grub_extcmd_context *ctxt, if (!hash) return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown hash"); - if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN) - return grub_error (GRUB_ERR_BUG, "mdlen is too long"); - if (state[2].set) prefix = state[2].arg; @@ -240,18 +196,16 @@ grub_cmd_hashsum (struct grub_extcmd_context *ctxt, 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, uncompress); + return check_list (hash, state[1].arg, prefix, keep); } for (i = 0; i < (unsigned) argc; i++) { - GRUB_PROPERLY_ALIGNED_ARRAY (result, GRUB_CRYPTO_MAX_MDLEN); + grub_uint8_t result[hash->mdlen]; grub_file_t file; grub_err_t err; unsigned j; - file = grub_file_open (args[i], GRUB_FILE_TYPE_TO_HASH - | (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS - : GRUB_FILE_TYPE_NONE)); + file = grub_file_open (args[i]); if (!file) { if (!keep) @@ -273,53 +227,43 @@ grub_cmd_hashsum (struct grub_extcmd_context *ctxt, continue; } for (j = 0; j < hash->mdlen; j++) - grub_printf ("%02x", ((grub_uint8_t *) result)[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", + 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_sha1, cmd_sha256, cmd_sha512, cmd_crc; +static grub_extcmd_t cmd, cmd_md5, cmd_sha256, cmd_sha512; GRUB_MOD_INIT(hashsum) { - cmd = grub_register_extcmd ("hashsum", grub_cmd_hashsum, 0, - N_("-h HASH [-c FILE [-p PREFIX]] " - "[FILE1 [FILE2 ...]]"), - /* TRANSLATORS: "hash checksum" is just to - be a bit more precise, you can treat it as - just "hash". */ - N_("Compute or check hash checksum."), + 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, 0, - N_("[-c FILE [-p PREFIX]] " - "[FILE1 [FILE2 ...]]"), - N_("Compute or check hash checksum."), + cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum, + GRUB_COMMAND_FLAG_BOTH, + "md5sum [-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]", + "Compute or check hash checksum.", options); - cmd_sha1 = grub_register_extcmd ("sha1sum", grub_cmd_hashsum, 0, - N_("[-c FILE [-p PREFIX]] " - "[FILE1 [FILE2 ...]]"), - N_("Compute or check hash checksum."), - options); - cmd_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum, 0, - N_("[-c FILE [-p PREFIX]] " - "[FILE1 [FILE2 ...]]"), - N_("Compute or check hash checksum."), + cmd_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum, + GRUB_COMMAND_FLAG_BOTH, + "sha256sum [-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]", + "Compute or check hash checksum.", options); - cmd_sha512 = grub_register_extcmd ("sha512sum", grub_cmd_hashsum, 0, - N_("[-c FILE [-p PREFIX]] " - "[FILE1 [FILE2 ...]]"), - N_("Compute or check hash checksum."), - options); - - cmd_crc = grub_register_extcmd ("crc", grub_cmd_hashsum, 0, - N_("[-c FILE [-p PREFIX]] " - "[FILE1 [FILE2 ...]]"), - N_("Compute or check hash checksum."), + cmd_sha512 = grub_register_extcmd ("sha512sum", grub_cmd_hashsum, + GRUB_COMMAND_FLAG_BOTH, + "sha512sum [-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]", + "Compute or check hash checksum.", options); } @@ -327,8 +271,6 @@ GRUB_MOD_FINI(hashsum) { grub_unregister_extcmd (cmd); grub_unregister_extcmd (cmd_md5); - grub_unregister_extcmd (cmd_sha1); grub_unregister_extcmd (cmd_sha256); grub_unregister_extcmd (cmd_sha512); - grub_unregister_extcmd (cmd_crc); } diff --git a/grub-core/commands/hdparm.c b/commands/hdparm.c similarity index 70% rename from grub-core/commands/hdparm.c rename to commands/hdparm.c index 96f2336f3..a3f8bbff0 100644 --- a/grub-core/commands/hdparm.c +++ b/commands/hdparm.c @@ -18,7 +18,6 @@ */ #include -#include #include #include #include @@ -27,16 +26,14 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - 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_("Display power mode."), 0, ARG_TYPE_NONE}, + {"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_("Display SMART health status."), 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}, @@ -47,7 +44,7 @@ static const struct grub_arg_option options[] = { {"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_("Show raw contents of ATA IDENTIFY sector."), + {"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}, @@ -64,64 +61,60 @@ enum grub_ata_smart_commands static int quiet = 0; static grub_err_t -grub_hdparm_do_ata_cmd (grub_ata_t ata, grub_uint8_t cmd, +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.cmd = cmd; - apt.taskfile.features = features; - apt.taskfile.sectors = sectors; - apt.taskfile.disk = 0xE0; - + 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 (ata->dev->readwrite (ata, &apt, 0)) + if (grub_disk_ata_pass_through (disk, &apt)) return grub_errno; return GRUB_ERR_NONE; } static int -grub_hdparm_do_check_powermode_cmd (grub_ata_t ata) +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.cmd = GRUB_ATA_CMD_CHECK_POWER_MODE; - apt.taskfile.disk = 0xE0; + apt.taskfile[GRUB_ATA_REG_CMD] = GRUB_ATA_CMD_CHECK_POWER_MODE; - if (ata->dev->readwrite (ata, &apt, 0)) + if (grub_disk_ata_pass_through (disk, &apt)) return -1; - return apt.taskfile.sectors; + return apt.taskfile[GRUB_ATA_REG_SECTORS]; } static int -grub_hdparm_do_smart_cmd (grub_ata_t ata, grub_uint8_t features) +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.cmd = GRUB_ATA_CMD_SMART; - apt.taskfile.features = features; - apt.taskfile.lba_mid = 0x4f; - apt.taskfile.lba_high = 0xc2; - apt.taskfile.disk = 0xE0; + 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 (ata->dev->readwrite (ata, &apt, 0)) + if (grub_disk_ata_pass_through (disk, &apt)) return -1; if (features == GRUB_ATA_FEAT_SMART_STATUS) { - if ( apt.taskfile.lba_mid == 0x4f - && apt.taskfile.lba_high == 0xc2) + if ( apt.taskfile[GRUB_ATA_REG_LBAMID] == 0x4f + && apt.taskfile[GRUB_ATA_REG_LBAHIGH] == 0xc2) return 0; /* Good SMART status. */ - else if ( apt.taskfile.lba_mid == 0xf4 - && apt.taskfile.lba_high == 0x2c) + else if ( apt.taskfile[GRUB_ATA_REG_LBAMID] == 0xf4 + && apt.taskfile[GRUB_ATA_REG_LBAHIGH] == 0x2c) return 1; /* Bad SMART status. */ else return -1; @@ -131,12 +124,12 @@ grub_hdparm_do_smart_cmd (grub_ata_t ata, grub_uint8_t features) static grub_err_t grub_hdparm_simple_cmd (const char * msg, - grub_ata_t ata, grub_uint8_t cmd) + grub_disk_t disk, grub_uint8_t cmd) { if (! quiet && msg) grub_printf ("%s", msg); - grub_err_t err = grub_hdparm_do_ata_cmd (ata, cmd, 0, 0, NULL, 0); + 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"); @@ -145,7 +138,7 @@ grub_hdparm_simple_cmd (const char * msg, static grub_err_t grub_hdparm_set_val_cmd (const char * msg, int val, - grub_ata_t ata, grub_uint8_t cmd, + grub_disk_t disk, grub_uint8_t cmd, grub_uint8_t features, grub_uint8_t sectors) { if (! quiet && msg && *msg) @@ -156,7 +149,7 @@ grub_hdparm_set_val_cmd (const char * msg, int val, grub_printf ("Disable %s", msg); } - grub_err_t err = grub_hdparm_do_ata_cmd (ata, cmd, features, sectors, + grub_err_t err = grub_hdparm_do_ata_cmd (disk, cmd, features, sectors, NULL, 0); if (! quiet && msg) @@ -165,20 +158,22 @@ grub_hdparm_set_val_cmd (const char * msg, int val, } static const char * -le16_to_char (grub_uint16_t *dest, const grub_uint16_t * src16, unsigned bytes) +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++) - dest[i] = grub_swap_bytes16 (src16[i]); - dest[i] = 0; - return (char *) dest; + dest16[i] = grub_be_to_cpu16 (src16[i]); + return dest; } static void -grub_hdparm_print_identify (const grub_uint16_t * idw) +grub_hdparm_print_identify (const char * idbuf) { + const grub_uint16_t * idw = (const grub_uint16_t *) idbuf; + /* Print identity strings. */ - grub_uint16_t tmp[21]; + 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)); @@ -275,25 +270,21 @@ static int get_int_arg (const struct grub_arg_list *state) } static grub_err_t -grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) +grub_cmd_hdparm (grub_extcmd_t cmd, int argc, char **args) // state???? { - struct grub_arg_list *state = ctxt->state; - struct grub_ata *ata; - const char *diskname; + struct grub_arg_list *state = cmd->state; /* Check command line. */ if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing device name argument"); - if (args[0][0] == '(') - { - grub_size_t len = grub_strlen (args[0]); - if (args[0][len - 1] == ')') - args[0][len - 1] = 0; - diskname = &args[0][1]; - } - else - diskname = &args[0][0]; + 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++]); @@ -310,43 +301,25 @@ grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) quiet = state[i++].set; /* Open disk. */ - grub_disk_t disk = grub_disk_open (diskname); + grub_disk_t disk = grub_disk_open (&args[0][1]); if (! disk) return grub_errno; - switch (disk->dev->id) + if (disk->partition) { - case GRUB_DISK_DEVICE_ATA_ID: - ata = disk->data; - break; - case GRUB_DISK_DEVICE_SCSI_ID: - if (((disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xFF) - == GRUB_SCSI_SUBSYSTEM_PATA - || (((disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xFF) - == GRUB_SCSI_SUBSYSTEM_AHCI)) - { - ata = ((struct grub_scsi *) disk->data)->data; - break; - } - /* FALLTHROUGH */ - default: grub_disk_close (disk); - return grub_error (GRUB_ERR_IO, "not an ATA device"); + 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), - ata, GRUB_ATA_CMD_SET_FEATURES, - (aam ? 0x42 : 0xc2), aam); + 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), ata, - GRUB_ATA_CMD_SET_FEATURES, - (apm != 255 ? 0x05 : 0x85), - (apm != 255 ? apm : 0)); + (apm != 255 ? apm : -1), disk, GRUB_ATA_CMD_SET_FEATURES, + (apm != 255 ? 0x05 : 0x85), (apm != 255 ? apm : 0)); if (standby_tout >= 0) { @@ -357,28 +330,28 @@ grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) grub_printf (")"); } /* The IDLE cmd sets disk to idle mode and configures standby timer. */ - grub_hdparm_set_val_cmd ("", -1, ata, GRUB_ATA_CMD_IDLE, 0, standby_tout); + 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 (ata, (enable_smart ? + 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", ata, + grub_hdparm_simple_cmd ("Freeze security settings", disk, GRUB_ATA_CMD_SECURITY_FREEZE_LOCK); /* Print/dump IDENTIFY. */ if (ident || dumpid) { - grub_uint16_t buf[GRUB_DISK_SECTOR_SIZE / 2]; - if (grub_hdparm_do_ata_cmd (ata, GRUB_ATA_CMD_IDENTIFY_DEVICE, + 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 @@ -386,7 +359,7 @@ grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) if (ident) grub_hdparm_print_identify (buf); if (dumpid) - hexdump (0, (char *) buf, sizeof (buf)); + hexdump (0, buf, sizeof (buf)); } } @@ -394,7 +367,7 @@ grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) if (power) { grub_printf ("Disk power mode is: "); - int mode = grub_hdparm_do_check_powermode_cmd (ata); + int mode = grub_hdparm_do_check_powermode_cmd (disk); if (mode < 0) grub_printf ("unknown\n"); else @@ -410,7 +383,7 @@ grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) { if (! quiet) grub_printf ("SMART status is: "); - int err = grub_hdparm_do_smart_cmd (ata, GRUB_ATA_FEAT_SMART_STATUS); + 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*")); @@ -419,11 +392,11 @@ grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) /* Change power mode. */ if (standby_now) - grub_hdparm_simple_cmd ("Set disk to standby mode", ata, + 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", ata, + grub_hdparm_simple_cmd ("Set disk to sleep mode", disk, GRUB_ATA_CMD_SLEEP); grub_disk_close (disk); @@ -436,9 +409,10 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(hdparm) { - cmd = grub_register_extcmd_lockdown ("hdparm", grub_cmd_hdparm, 0, - N_("[OPTIONS] DISK"), - N_("Get/set ATA disk parameters."), options); + 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) diff --git a/commands/help.c b/commands/help.c new file mode 100644 index 000000000..1181c3bfb --- /dev/null +++ b/commands/help.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +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\b", _("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; + +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/commands/hexdump.c similarity index 81% rename from grub-core/commands/hexdump.c rename to commands/hexdump.c index d6f61d98a..c1d4ecba9 100644 --- a/grub-core/commands/hexdump.c +++ b/commands/hexdump.c @@ -21,12 +21,10 @@ #include #include #include +#include #include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); static const struct grub_arg_option options[] = { {"skip", 's', 0, N_("Skip offset bytes from the beginning of file."), 0, @@ -36,27 +34,23 @@ static const struct grub_arg_option options[] = { }; static grub_err_t -grub_cmd_hexdump (grub_extcmd_context_t ctxt, int argc, char **args) +grub_cmd_hexdump (grub_extcmd_t cmd, int argc, char **args) { - struct grub_arg_list *state = ctxt->state; + 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, N_("filename expected")); + 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)")) - { - if (grub_is_lockdown() == GRUB_LOCKDOWN_ENABLED) - return grub_error (GRUB_ERR_ACCESS_DENIED, N_("memory reading is disabled in lockdown mode")); - hexdump (skip, (char *) (grub_addr_t) skip, length); - } + hexdump (skip, (char *) (grub_addr_t) skip, length); else if ((args[0][0] == '(') && (args[0][namelen - 1] == ')')) { grub_disk_t disk; @@ -95,7 +89,7 @@ grub_cmd_hexdump (grub_extcmd_context_t ctxt, int argc, char **args) { grub_file_t file; - file = grub_file_open (args[0], GRUB_FILE_TYPE_HEXCAT); + file = grub_gzfile_open (args[0], 1); if (! file) return 0; @@ -126,9 +120,10 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT (hexdump) { - cmd = grub_register_extcmd ("hexdump", grub_cmd_hexdump, 0, + cmd = grub_register_extcmd ("hexdump", grub_cmd_hexdump, + GRUB_COMMAND_FLAG_BOTH, N_("[OPTIONS] FILE_OR_DEVICE"), - N_("Show raw contents of a file or memory."), + N_("Dump the contents of a file or memory."), options); } diff --git a/grub-core/commands/i386/cpuid.c b/commands/i386/cpuid.c similarity index 63% rename from grub-core/commands/i386/cpuid.c rename to commands/i386/cpuid.c index 42b984154..6eebf91a1 100644 --- a/grub-core/commands/i386/cpuid.c +++ b/commands/i386/cpuid.c @@ -27,48 +27,28 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); +#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[] = { - /* TRANSLATORS: "(default)" at the end means that this option is used if - no argument is specified. */ - {"long-mode", 'l', 0, N_("Check if CPU supports 64-bit (long) mode (default)."), 0, 0}, - {"pae", 'p', 0, N_("Check if CPU supports Physical Address Extension."), 0, 0}, + {"long-mode", 'l', 0, N_("Check for long mode flag (default)."), 0, 0}, {0, 0, 0, 0, 0, 0} }; -enum - { - MODE_LM = 0, - MODE_PAE = 1 - }; +#define bit_LM (1 << 29) -enum - { - bit_PAE = (1 << 6), - }; -enum - { - bit_LM = (1 << 29) - }; - -unsigned char grub_cpuid_has_longmode = 0, grub_cpuid_has_pae = 0; +unsigned char grub_cpuid_has_longmode = 0; static grub_err_t -grub_cmd_cpuid (grub_extcmd_context_t ctxt, +grub_cmd_cpuid (grub_extcmd_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - int val = 0; - if (ctxt->state[MODE_PAE].set) - val = grub_cpuid_has_pae; - else - val = grub_cpuid_has_longmode; - return val ? GRUB_ERR_NONE - /* TRANSLATORS: it's a standalone boolean value, - opposite of "true". */ - : grub_error (GRUB_ERR_TEST_FAILURE, N_("false")); + return grub_cpuid_has_longmode ? GRUB_ERR_NONE + : grub_error (GRUB_ERR_TEST_FAILURE, "false"); } static grub_extcmd_t cmd; @@ -78,7 +58,6 @@ GRUB_MOD_INIT(cpuid) #ifdef __x86_64__ /* grub-emu */ grub_cpuid_has_longmode = 1; - grub_cpuid_has_pae = 1; #else unsigned int eax, ebx, ecx, edx; unsigned int max_level; @@ -93,29 +72,23 @@ GRUB_MOD_INIT(cpuid) goto done; /* Check the highest input value for eax. */ - grub_cpuid (0, eax, ebx, ecx, edx); + cpuid (0, eax, ebx, ecx, edx); /* We only look at the first four characters. */ max_level = eax; if (max_level == 0) goto done; - if (max_level >= 1) - { - grub_cpuid (1, eax, ebx, ecx, edx); - grub_cpuid_has_pae = !!(edx & bit_PAE); - } - - grub_cpuid (0x80000000, eax, ebx, ecx, edx); + cpuid (0x80000000, eax, ebx, ecx, edx); ext_level = eax; if (ext_level < 0x80000000) goto done; - grub_cpuid (0x80000001, eax, ebx, ecx, edx); + cpuid (0x80000001, eax, ebx, ecx, edx); grub_cpuid_has_longmode = !!(edx & bit_LM); done: #endif - cmd = grub_register_extcmd ("cpuid", grub_cmd_cpuid, 0, + cmd = grub_register_extcmd ("cpuid", grub_cmd_cpuid, GRUB_COMMAND_FLAG_BOTH, "[-l]", N_("Check for CPU features."), options); } diff --git a/grub-core/kern/i386/pc/acpi.c b/commands/i386/pc/acpi.c similarity index 79% rename from grub-core/kern/i386/pc/acpi.c rename to commands/i386/pc/acpi.c index 0a69eba7b..88e4f55cf 100644 --- a/grub-core/kern/i386/pc/acpi.c +++ b/commands/i386/pc/acpi.c @@ -27,21 +27,20 @@ grub_machine_acpi_get_rsdpv1 (void) grub_uint8_t *ebda, *ptr; grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n"); - ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) grub_absolute_pointer (0x40e))) << 4); + ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4); ebda_len = * (grub_uint16_t *) ebda; - if (! ebda_len) /* FIXME do we really need this check? */ - goto scan_bios; + if (! ebda_len) + return 0; for (ptr = ebda; ptr < ebda + 0x400; ptr += 16) - if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 + 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; -scan_bios: 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, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 + 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; @@ -55,12 +54,12 @@ grub_machine_acpi_get_rsdpv2 (void) grub_uint8_t *ebda, *ptr; grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n"); - ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) grub_absolute_pointer (0x40e))) << 4); + ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4); ebda_len = * (grub_uint16_t *) ebda; - if (! ebda_len) /* FIXME do we really need this check? */ - goto scan_bios; + if (! ebda_len) + return 0; for (ptr = ebda; ptr < ebda + 0x400; ptr += 16) - if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 + 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 @@ -68,11 +67,10 @@ grub_machine_acpi_get_rsdpv2 (void) == 0) return (struct grub_acpi_rsdp_v20 *) ptr; -scan_bios: 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, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 + 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 diff --git a/grub-core/commands/i386/pc/drivemap.c b/commands/i386/pc/drivemap.c similarity index 87% rename from grub-core/commands/i386/pc/drivemap.c rename to commands/i386/pc/drivemap.c index a7ee4c9bd..3baacba49 100644 --- a/grub-core/commands/i386/pc/drivemap.c +++ b/commands/i386/pc/drivemap.c @@ -24,19 +24,16 @@ #include #include #include +#include #include #include -#include -#include -GRUB_MOD_LICENSE ("GPLv3+"); + +/* 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[] = { - /* TRANSLATORS: In this file "mapping" refers to a change GRUB makes so if - your language doesn't have an equivalent of "mapping" you can - use the word like "rerouting". - */ {"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}, @@ -71,7 +68,7 @@ typedef struct drivemap_node grub_uint8_t redirto; } drivemap_node_t; -typedef struct GRUB_PACKED int13map_node +typedef struct __attribute__ ((packed)) int13map_node { grub_uint8_t disknum; grub_uint8_t mapto; @@ -108,7 +105,8 @@ drivemap_set (grub_uint8_t newdrive, grub_uint8_t redirto) { mapping = grub_malloc (sizeof (drivemap_node_t)); if (! mapping) - return grub_errno; + 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; @@ -178,14 +176,11 @@ list_mappings (void) /* Show: list mappings. */ if (! map_head) { - grub_puts_ (N_("No drives have been remapped")); + grub_printf ("No drives have been remapped\n"); return GRUB_ERR_NONE; } - /* TRANSLATORS: This is the header of mapping list. - On the left is how OS will see the disks and - on the right current GRUB vision. */ - grub_puts_ (N_("OS disk #num ------> GRUB/BIOS device")); + grub_printf ("OS disk #num ------> GRUB/BIOS device\n"); drivemap_node_t *curnode = map_head; while (curnode) { @@ -201,13 +196,13 @@ list_mappings (void) } static grub_err_t -grub_cmd_drivemap (struct grub_extcmd_context *ctxt, int argc, char **args) +grub_cmd_drivemap (struct grub_extcmd *cmd, int argc, char **args) { - if (ctxt->state[OPTIDX_LIST].set) + if (cmd->state[OPTIDX_LIST].set) { return list_mappings (); } - else if (ctxt->state[OPTIDX_RESET].set) + else if (cmd->state[OPTIDX_RESET].set) { /* Reset: just delete all mappings, freeing their memory. */ drivemap_node_t *curnode = map_head; @@ -221,7 +216,7 @@ grub_cmd_drivemap (struct grub_extcmd_context *ctxt, int argc, char **args) map_head = 0; return GRUB_ERR_NONE; } - else if (!ctxt->state[OPTIDX_SWAP].set && argc == 0) + else if (!cmd->state[OPTIDX_SWAP].set && argc == 0) { /* No arguments */ return list_mappings (); @@ -233,7 +228,7 @@ grub_cmd_drivemap (struct grub_extcmd_context *ctxt, int argc, char **args) grub_err_t err; if (argc != 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required"); err = tryparse_diskstring (args[0], &mapfrom); if (err != GRUB_ERR_NONE) @@ -253,11 +248,11 @@ grub_cmd_drivemap (struct grub_extcmd_context *ctxt, int argc, char **args) } /* Set the mapping for the disk (overwrites any existing mapping). */ grub_dprintf ("drivemap", "%s %s (%02x) = %s (%02x)\n", - ctxt->state[OPTIDX_SWAP].set ? "Swapping" : "Mapping", + 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 (ctxt->state[OPTIDX_SWAP].set && err == GRUB_ERR_NONE) + if (cmd->state[OPTIDX_SWAP].set && err == GRUB_ERR_NONE) err = drivemap_set (mapfrom, mapto); return err; } @@ -277,8 +272,6 @@ install_int13_handler (int noret __attribute__ ((unused))) grub_uint8_t *handler_base = 0; /* Address of the map within the deployed bundle. */ int13map_node_t *handler_map; - /* Real mode IVT slot (seg:off far pointer) for interrupt 0x13. */ - grub_uint32_t *int13slot = (grub_uint32_t *) grub_absolute_pointer (4 * 0x13); int i; int entries = 0; @@ -311,9 +304,9 @@ install_int13_handler (int noret __attribute__ ((unused))) 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, ALIGN_UP (total_size, 16), + handler_base = grub_mmap_malign_and_register (16, total_size, &drivemap_mmap, - GRUB_MEMORY_RESERVED, + GRUB_MACHINE_MEMORY_RESERVED, GRUB_MMAP_MALLOC_LOW); if (! handler_base) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't reserve " @@ -353,9 +346,6 @@ install_int13_handler (int noret __attribute__ ((unused))) static grub_err_t uninstall_int13_handler (void) { - /* Real mode IVT slot (seg:off far pointer) for interrupt 0x13. */ - grub_uint32_t *int13slot = (grub_uint32_t *) grub_absolute_pointer (4 * 0x13); - if (! grub_drivemap_oldhandler) return GRUB_ERR_NONE; @@ -371,7 +361,7 @@ uninstall_int13_handler (void) static int grub_get_root_biosnumber_drivemap (void) { - const char *biosnum; + char *biosnum; int ret = -1; grub_device_t dev; @@ -411,10 +401,12 @@ 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, 0, - N_("-l | -r | [-s] grubdev osdisk."), - N_("Manage the BIOS drive mappings."), - options); + cmd = grub_register_extcmd ("drivemap", grub_cmd_drivemap, + GRUB_COMMAND_FLAG_BOTH, + "drivemap" + 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, diff --git a/grub-core/commands/i386/pc/drivemap_int13h.S b/commands/i386/pc/drivemap_int13h.S similarity index 80% rename from grub-core/commands/i386/pc/drivemap_int13h.S rename to commands/i386/pc/drivemap_int13h.S index 3c87521b6..440349685 100644 --- a/grub-core/commands/i386/pc/drivemap_int13h.S +++ b/commands/i386/pc/drivemap_int13h.S @@ -19,7 +19,7 @@ #include -#define INT13H_OFFSET(x) ((x) - LOCAL (base)) +#define INT13H_OFFSET(x) ((x) - EXT_C(grub_drivemap_handler)) .code16 @@ -27,7 +27,6 @@ /* 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. */ @@ -36,11 +35,11 @@ LOCAL (base): /* Map the drive number (always in DL). */ push %ax push %bx -#ifdef __APPLE__ - LOCAL(mapstart_offset) = INT13H_OFFSET(LOCAL (mapstart)) - movw $LOCAL(mapstart_offset), %bx +#ifdef APPLE_CC + grub_drivemap_mapstart_ofs = INT13H_OFFSET(EXT_C(grub_drivemap_mapstart)) + movw $grub_drivemap_mapstart_ofs, %bx #else - movw $INT13H_OFFSET(LOCAL (mapstart)), %bx + movw $INT13H_OFFSET(EXT_C(grub_drivemap_mapstart)), %bx #endif more_remaining: @@ -67,11 +66,11 @@ not_found: popf pushf -#ifdef __APPLE__ - LOCAL(oldhandler_offset) = INT13H_OFFSET (LOCAL (oldhandler)) - lcall *%cs:LOCAL(oldhandler_offset) +#ifdef APPLE_CC + grub_drivemap_oldhandler_ofs = INT13H_OFFSET (EXT_C (grub_drivemap_oldhandler)) + lcall *%cs:grub_drivemap_oldhandler_ofs #else - lcall *%cs:INT13H_OFFSET (LOCAL (oldhandler)) + lcall *%cs:INT13H_OFFSET (EXT_C (grub_drivemap_oldhandler)) #endif push %bp @@ -95,10 +94,10 @@ norestore: popf pushf -#ifdef __APPLE__ - lcall *%cs:LOCAL(oldhandler_offset) +#ifdef APPLE_CC + lcall *%cs:grub_drivemap_oldhandler_ofs #else - lcall *%cs:INT13H_OFFSET (LOCAL (oldhandler)) + lcall *%cs:INT13H_OFFSET (EXT_C (grub_drivemap_oldhandler)) #endif push %bp @@ -112,13 +111,9 @@ norestore: /* 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 - +.align 2 VARIABLE(grub_drivemap_mapstart) -LOCAL (mapstart): - .byte 0 diff --git a/grub-core/tests/test_blockarg.c b/commands/i386/pc/halt.c similarity index 52% rename from grub-core/tests/test_blockarg.c rename to commands/i386/pc/halt.c index 88bd968f3..4c39612ae 100644 --- a/grub-core/tests/test_blockarg.c +++ b/commands/i386/pc/halt.c @@ -1,7 +1,7 @@ -/* test_blockarg.c - print and execute block argument */ +/* halt.c - command to halt the computer. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010 Free Software Foundation, Inc. + * 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 @@ -18,38 +18,41 @@ */ #include -#include #include -#include #include -#include +#include -GRUB_MOD_LICENSE ("GPLv3+"); +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 -test_blockarg (grub_extcmd_context_t ctxt, int argc, char **args) -{ - if (! ctxt->script) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no block parameter"); +grub_cmd_halt (grub_extcmd_t cmd, + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) - grub_printf ("%s\n", args[argc - 1]); - grub_script_execute (ctxt->script); - return GRUB_ERR_NONE; +{ + 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; - -GRUB_MOD_INIT(test_blockarg) + +GRUB_MOD_INIT(halt) { - cmd = grub_register_extcmd ("test_blockarg", test_blockarg, - GRUB_COMMAND_FLAG_BLOCKS, - N_("BLOCK"), - /* TRANSLATORS: this is the BLOCK-argument, not - environment block. */ - N_("Print and execute block argument."), 0); + 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(test_blockarg) +GRUB_MOD_FINI(halt) { grub_unregister_extcmd (cmd); } diff --git a/commands/i386/pc/play.c b/commands/i386/pc/play.c new file mode 100644 index 000000000..44d98a1f0 --- /dev/null +++ b/commands/i386/pc/play.c @@ -0,0 +1,269 @@ +/* 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 . + */ + +/* Lots of this file is borrowed from GNU/Hurd generic-speaker driver. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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) +{ + grub_file_t file; + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name or tempo and notes required"); + + file = grub_file_open (args[0]); + if (file) + { + struct note buf; + grub_uint32_t tempo; + + 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, ¬e)) + break; + } + } + + beep_off (); + + while (grub_checkkey () > 0) + grub_getkey (); + + return 0; +} + +static grub_command_t cmd; + +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/arc/lsdev.c b/commands/i386/pc/pxecmd.c similarity index 56% rename from grub-core/commands/arc/lsdev.c rename to commands/i386/pc/pxecmd.c index 27ed0a248..b576a8ea4 100644 --- a/grub-core/commands/arc/lsdev.c +++ b/commands/i386/pc/pxecmd.c @@ -1,6 +1,7 @@ +/* pxe.c - command to control the pxe driver */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. + * 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 @@ -17,41 +18,35 @@ */ #include +#include #include +#include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* Helper for grub_cmd_lsdev. */ -static int -grub_cmd_lsdev_iter (const char *name, - const struct grub_arc_component *comp __attribute__ ((unused)), - void *data __attribute__ ((unused))) -{ - grub_printf ("%s\n", name); - return 0; -} static grub_err_t -grub_cmd_lsdev (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) +grub_cmd_pxe_unload (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) { - grub_arc_iterate_devs (grub_cmd_lsdev_iter, 0, 0); + 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(lsdev) +GRUB_MOD_INIT(pxecmd) { - cmd = grub_register_command ("lsdev", grub_cmd_lsdev, "", - N_("List devices.")); + cmd = grub_register_command ("pxe_unload", grub_cmd_pxe_unload, + 0, + N_("Unload PXE environment.")); } -GRUB_MOD_FINI(lsdev) +GRUB_MOD_FINI(pxecmd) { grub_unregister_command (cmd); } diff --git a/commands/i386/pc/vbeinfo.c b/commands/i386/pc/vbeinfo.c new file mode 100644 index 000000000..c266bbfcb --- /dev/null +++ b/commands/i386/pc/vbeinfo.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +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 new file mode 100644 index 000000000..d2921c09d --- /dev/null +++ b/commands/i386/pc/vbetest.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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/commands/ieee1275/suspend.c similarity index 91% rename from grub-core/commands/ieee1275/suspend.c rename to commands/ieee1275/suspend.c index b50548574..f096cc9ba 100644 --- a/grub-core/commands/ieee1275/suspend.c +++ b/commands/ieee1275/suspend.c @@ -24,14 +24,12 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - static grub_err_t grub_cmd_suspend (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - grub_puts_ (N_("Run `go' to resume GRUB.")); + grub_printf ("Run 'go' to resume GRUB.\n"); grub_ieee1275_enter (); grub_cls (); return 0; @@ -42,7 +40,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(ieee1275_suspend) { cmd = grub_register_command ("suspend", grub_cmd_suspend, - 0, N_("Return to IEEE1275 prompt.")); + 0, N_("Return to Open Firmware prompt.")); } GRUB_MOD_FINI(ieee1275_suspend) diff --git a/grub-core/commands/keystatus.c b/commands/keystatus.c similarity index 72% rename from grub-core/commands/keystatus.c rename to commands/keystatus.c index ff3f58781..838792889 100644 --- a/grub-core/commands/keystatus.c +++ b/commands/keystatus.c @@ -23,33 +23,31 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - static const struct grub_arg_option options[] = { - /* TRANSLATORS: "Check" in a sense that if this key is pressed then - "true" is returned, otherwise "false". */ {"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_context_t ctxt, +grub_cmd_keystatus (grub_extcmd_t cmd, int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - struct grub_arg_list *state = ctxt->state; + struct grub_arg_list *state = cmd->state; int expect_mods = 0; int mods; if (state[0].set) - expect_mods |= (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT); + expect_mods |= GRUB_TERM_STATUS_SHIFT; if (state[1].set) - expect_mods |= (GRUB_TERM_STATUS_LCTRL | GRUB_TERM_STATUS_RCTRL); + expect_mods |= GRUB_TERM_STATUS_CTRL; if (state[2].set) - expect_mods |= (GRUB_TERM_STATUS_LALT | GRUB_TERM_STATUS_RALT); + expect_mods |= GRUB_TERM_STATUS_ALT; grub_dprintf ("keystatus", "expect_mods: %d\n", expect_mods); @@ -62,11 +60,11 @@ grub_cmd_keystatus (grub_extcmd_context_t ctxt, FOR_ACTIVE_TERM_INPUTS (term) if (!term->getkeystatus) - return grub_error (GRUB_ERR_TEST_FAILURE, N_("false")); + return grub_error (GRUB_ERR_TEST_FAILURE, "false"); else nterms++; if (!nterms) - return grub_error (GRUB_ERR_TEST_FAILURE, N_("false")); + return grub_error (GRUB_ERR_TEST_FAILURE, "false"); return 0; } @@ -75,16 +73,16 @@ grub_cmd_keystatus (grub_extcmd_context_t ctxt, if (mods >= 0 && (mods & expect_mods) != 0) return 0; else - return grub_error (GRUB_ERR_TEST_FAILURE, N_("false")); + return grub_error (GRUB_ERR_TEST_FAILURE, "false"); } static grub_extcmd_t cmd; GRUB_MOD_INIT(keystatus) { - cmd = grub_register_extcmd ("keystatus", grub_cmd_keystatus, 0, - "[--shift] [--ctrl] [--alt]", - /* TRANSLATORS: there are 3 modifiers. */ + cmd = grub_register_extcmd ("keystatus", grub_cmd_keystatus, + GRUB_COMMAND_FLAG_BOTH, + N_("[--shift] [--ctrl] [--alt]"), N_("Check key modifier status."), options); } diff --git a/grub-core/commands/loadenv.c b/commands/loadenv.c similarity index 55% rename from grub-core/commands/loadenv.c rename to commands/loadenv.c index 166445849..51b88cbc9 100644 --- a/grub-core/commands/loadenv.c +++ b/commands/loadenv.c @@ -28,55 +28,46 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - static const struct grub_arg_option options[] = { - /* TRANSLATORS: This option is used to override default filename - for loading and storing environment. */ {"file", 'f', 0, N_("Specify filename."), 0, ARG_TYPE_PATHNAME}, - {"skip-sig", 's', 0, - N_("Skip signature-checking of the environment file."), 0, ARG_TYPE_NONE}, {0, 0, 0, 0, 0, 0} }; -/* Opens 'filename' with compression filters disabled. Optionally disables the - PUBKEY filter (that insists upon properly signed files) as well. PUBKEY - filter is restored before the function returns. */ static grub_file_t -open_envblk_file (char *filename, - enum grub_file_type type) +open_envblk_file (char *filename) { grub_file_t file; - char *buf = 0; if (! filename) { - const char *prefix; - int len; + char *prefix; prefix = grub_env_get ("prefix"); - if (! prefix) + if (prefix) { - grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "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; } - - len = grub_strlen (prefix); - buf = grub_malloc (len + 1 + sizeof (GRUB_ENVBLK_DEFCFG)); - if (! buf) - return 0; - filename = buf; - - grub_strcpy (filename, prefix); - filename[len] = '/'; - grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG); } - file = grub_file_open (filename, type); - - grub_free (buf); - return file; + return grub_file_open (filename); } static grub_envblk_t @@ -98,6 +89,8 @@ read_envblk_file (grub_file_t file) 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; } @@ -117,59 +110,23 @@ read_envblk_file (grub_file_t file) return envblk; } -struct grub_env_whitelist -{ - grub_size_t len; - char **list; -}; -typedef struct grub_env_whitelist grub_env_whitelist_t; - -static int -test_whitelist_membership (const char* name, - const grub_env_whitelist_t* whitelist) -{ - grub_size_t i; - - for (i = 0; i < whitelist->len; i++) - if (grub_strcmp (name, whitelist->list[i]) == 0) - return 1; /* found it */ - - return 0; /* not found */ -} - -/* Helper for grub_cmd_load_env. */ -static int -set_var (const char *name, const char *value, void *whitelist) -{ - if (! whitelist) - { - grub_env_set (name, value); - return 0; - } - - if (test_whitelist_membership (name, - (const grub_env_whitelist_t *) whitelist)) - grub_env_set (name, value); - - return 0; -} - static grub_err_t -grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc, char **args) +grub_cmd_load_env (grub_extcmd_t cmd, + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) { - struct grub_arg_list *state = ctxt->state; + struct grub_arg_list *state = cmd->state; grub_file_t file; grub_envblk_t envblk; - grub_env_whitelist_t whitelist; - whitelist.len = argc; - whitelist.list = args; + 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; + } - /* state[0] is the -f flag; state[1] is the --skip-sig flag */ - file = open_envblk_file ((state[0].set) ? state[0].arg : 0, - GRUB_FILE_TYPE_LOADENV - | (state[1].set - ? GRUB_FILE_TYPE_SKIP_SIGNATURE : GRUB_FILE_TYPE_NONE)); + file = open_envblk_file ((state[0].set) ? state[0].arg : 0); if (! file) return grub_errno; @@ -177,8 +134,7 @@ grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc, char **args) if (! envblk) goto fail; - /* argc > 0 indicates caller provided a whitelist of variables to read. */ - grub_envblk_iterate (envblk, argc > 0 ? &whitelist : 0, set_var); + grub_envblk_iterate (envblk, set_var); grub_envblk_close (envblk); fail: @@ -186,28 +142,24 @@ grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc, char **args) return grub_errno; } -/* Print all variables in current context. */ -static int -print_var (const char *name, const char *value, - void *hook_data __attribute__ ((unused))) -{ - grub_printf ("%s=%s\n", name, value); - return 0; -} - static grub_err_t -grub_cmd_list_env (grub_extcmd_context_t ctxt, +grub_cmd_list_env (grub_extcmd_t cmd, int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - struct grub_arg_list *state = ctxt->state; + struct grub_arg_list *state = cmd->state; grub_file_t file; grub_envblk_t envblk; - file = open_envblk_file ((state[0].set) ? state[0].arg : 0, - GRUB_FILE_TYPE_LOADENV - | (state[1].set - ? GRUB_FILE_TYPE_SKIP_SIGNATURE : GRUB_FILE_TYPE_NONE)); + /* 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; @@ -215,7 +167,7 @@ grub_cmd_list_env (grub_extcmd_context_t ctxt, if (! envblk) goto fail; - grub_envblk_iterate (envblk, NULL, print_var); + grub_envblk_iterate (envblk, print_var); grub_envblk_close (envblk); fail: @@ -260,19 +212,10 @@ check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, for (p = blocklists; p; p = p->next) { struct blocklist *q; - /* Check if any pair of blocks overlap. */ for (q = p->next; q; q = q->next) { - grub_disk_addr_t s1, s2; - grub_disk_addr_t e1, e2; - - s1 = p->sector; - e1 = s1 + ((p->length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); - - s2 = q->sector; - e2 = s2 + ((q->length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); - - if (s1 < e2 && s2 < e1) + /* 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. */ @@ -292,22 +235,15 @@ check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, /* 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); + if (disk->partition) + part_start = grub_partition_get_start (disk->partition); + else + part_start = 0; buf = grub_envblk_buffer (envblk); - char *blockbuf = NULL; - grub_size_t blockbuf_len = 0; for (p = blocklists, index = 0; p; index += p->length, p = p->next) { - if (p->length > blockbuf_len) - { - grub_free (blockbuf); - blockbuf_len = 2 * p->length; - blockbuf = grub_malloc (blockbuf_len); - if (!blockbuf) - return grub_errno; - } + char blockbuf[GRUB_DISK_SECTOR_SIZE]; if (grub_disk_read (disk, p->sector - part_start, p->offset, p->length, blockbuf)) @@ -332,7 +268,10 @@ write_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, buf = grub_envblk_buffer (envblk); disk = file->device->disk; - part_start = grub_partition_get_start (disk->partition); + if (disk->partition) + part_start = grub_partition_get_start (disk->partition); + else + part_start = 0; index = 0; for (p = blocklists; p; index += p->length, p = p->next) @@ -345,56 +284,49 @@ write_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, return 1; } -/* Context for grub_cmd_save_env. */ -struct grub_cmd_save_env_ctx -{ - struct blocklist *head, *tail; -}; - -/* Store blocklists in a linked list. */ static grub_err_t -save_env_read_hook (grub_disk_addr_t sector, unsigned offset, unsigned length, - char *buf __attribute__ ((unused)), void *data) +grub_cmd_save_env (grub_extcmd_t cmd, int argc, char **args) { - struct grub_cmd_save_env_ctx *ctx = data; - struct blocklist *block; - - block = grub_malloc (sizeof (*block)); - if (! block) - return GRUB_ERR_NONE; - - block->sector = sector; - block->offset = offset; - block->length = length; - - /* Slightly complicated, because the list should be FIFO. */ - block->next = 0; - if (ctx->tail) - ctx->tail->next = block; - ctx->tail = block; - if (! ctx->head) - ctx->head = block; - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_arg_list *state = ctxt->state; + struct grub_arg_list *state = cmd->state; grub_file_t file; grub_envblk_t envblk; - struct grub_cmd_save_env_ctx ctx = { - .head = 0, - .tail = 0 - }; + 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, - GRUB_FILE_TYPE_SAVEENV - | GRUB_FILE_TYPE_SKIP_SIGNATURE); + file = open_envblk_file ((state[0].set) ? state[0].arg : 0); if (! file) return grub_errno; @@ -404,19 +336,18 @@ grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args) return grub_error (GRUB_ERR_BAD_DEVICE, "disk device required"); } - file->read_hook = save_env_read_hook; - file->read_hook_data = &ctx; + file->read_hook = read_hook; envblk = read_envblk_file (file); file->read_hook = 0; if (! envblk) goto fail; - if (check_blocklists (envblk, ctx.head, file)) + if (check_blocklists (envblk, head, file)) goto fail; while (argc) { - const char *value; + char *value; value = grub_env_get (args[0]); if (value) @@ -427,19 +358,17 @@ grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args) goto fail; } } - else - grub_envblk_delete (envblk, args[0]); argc--; args++; } - write_blocklists (envblk, ctx.head, file); + write_blocklists (envblk, head, file); fail: if (envblk) grub_envblk_close (envblk); - free_blocklists (ctx.head); + free_blocklists (head); grub_file_close (file); return grub_errno; } @@ -449,16 +378,20 @@ 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, 0, - N_("[-f FILE] [-s|--skip-sig] [variable_name_to_whitelist] [...]"), + 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, 0, N_("[-f FILE]"), + 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, 0, + 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); diff --git a/commands/ls.c b/commands/ls.c new file mode 100644 index 000000000..eb1049617 --- /dev/null +++ b/commands/ls.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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/i386/cmosdump.c b/commands/lsmmap.c similarity index 53% rename from grub-core/commands/i386/cmosdump.c rename to commands/lsmmap.c index 626485ccb..d5eef1ce9 100644 --- a/grub-core/commands/i386/cmosdump.c +++ b/commands/lsmmap.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009,2013 Free Software Foundation, Inc. + * 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 @@ -16,49 +16,38 @@ * along with GRUB. If not, see . */ +#include #include -#include #include -#include +#include #include -GRUB_MOD_LICENSE ("GPLv3+"); - static grub_err_t -grub_cmd_cmosdump (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused))) +grub_cmd_lsmmap (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) + { - int i; - - for (i = 0; i < 256; i++) + 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_err_t err; - grub_uint8_t value; - if ((i & 0xf) == 0) - grub_printf ("%02x: ", i); - - err = grub_cmos_read (i, &value); - if (err) - return err; - - grub_printf ("%02x ", value); - if ((i & 0xf) == 0xf) - grub_printf ("\n"); + grub_printf ("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n", + (long long) addr, (long long) size, type); + return 0; } - return GRUB_ERR_NONE; + grub_machine_mmap_iterate (hook); + + return 0; } static grub_command_t cmd; - -GRUB_MOD_INIT(cmosdump) +GRUB_MOD_INIT(lsmmap) { - cmd = grub_register_command ("cmosdump", grub_cmd_cmosdump, - 0, - N_("Show raw dump of the CMOS contents.")); + cmd = grub_register_command ("lsmmap", grub_cmd_lsmmap, + 0, N_("List memory map provided by firmware.")); } -GRUB_MOD_FINI(cmosdump) +GRUB_MOD_FINI(lsmmap) { grub_unregister_command (cmd); } diff --git a/grub-core/commands/lspci.c b/commands/lspci.c similarity index 93% rename from grub-core/commands/lspci.c rename to commands/lspci.c index b3cdab1b3..a69bb35ad 100644 --- a/grub-core/commands/lspci.c +++ b/commands/lspci.c @@ -22,15 +22,12 @@ #include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); struct grub_pci_classname { int class; int subclass; - const char *desc; + char *desc; }; static const struct grub_pci_classname grub_pci_classes[] = @@ -127,9 +124,8 @@ static const struct grub_arg_option options[] = static int iospace; -static int -grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, - void *data __attribute__ ((unused))) +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; @@ -171,7 +167,7 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, if (space == 0) continue; - + switch (space & GRUB_PCI_ADDR_SPACE_MASK) { case GRUB_PCI_ADDR_SPACE_IO: @@ -195,13 +191,13 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, (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) + (unsigned long long) (space & GRUB_PCI_ADDR_MEM_MASK), space & GRUB_PCI_ADDR_MEM_PREFETCH ? "prefetchable" : "non-prefetchable"); @@ -215,12 +211,12 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, } static grub_err_t -grub_cmd_lspci (grub_extcmd_context_t ctxt, +grub_cmd_lspci (grub_extcmd_t cmd, int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - iospace = ctxt->state[0].set; - grub_pci_iterate (grub_lspci_iter, NULL); + iospace = cmd->state[0].set; + grub_pci_iterate (grub_lspci_iter); return GRUB_ERR_NONE; } @@ -228,8 +224,8 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(lspci) { - cmd = grub_register_extcmd ("lspci", grub_cmd_lspci, 0, "[-i]", - N_("List PCI devices."), options); + cmd = grub_register_extcmd ("lspci", grub_cmd_lspci, GRUB_COMMAND_FLAG_BOTH, + "[-i]", N_("List PCI devices."), options); } GRUB_MOD_FINI(lspci) diff --git a/grub-core/commands/memrw.c b/commands/memrw.c similarity index 64% rename from grub-core/commands/memrw.c rename to commands/memrw.c index 3542683d1..6a4d43be2 100644 --- a/grub-core/commands/memrw.c +++ b/commands/memrw.c @@ -22,9 +22,6 @@ #include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); 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; @@ -32,23 +29,23 @@ 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}, + "VARNAME", ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} }; static grub_err_t -grub_cmd_read (grub_extcmd_context_t ctxt, int argc, char **argv) +grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv) { - grub_addr_t addr; + grub_target_addr_t addr; grub_uint32_t value = 0; char buf[sizeof ("XXXXXXXX")]; if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid number of arguments"); addr = grub_strtoul (argv[0], 0, 0); - switch (ctxt->extcmd->cmd->name[sizeof ("read_") - 1]) + switch (cmd->cmd->name[sizeof ("read_") - 1]) { case 'd': value = *((volatile grub_uint32_t *) addr); @@ -63,10 +60,10 @@ grub_cmd_read (grub_extcmd_context_t ctxt, int argc, char **argv) break; } - if (ctxt->state[0].set) + if (cmd->state[0].set) { grub_snprintf (buf, sizeof (buf), "%x", value); - grub_env_set (ctxt->state[0].arg, buf); + grub_env_set (cmd->state[0].arg, buf); } else grub_printf ("0x%x\n", value); @@ -77,12 +74,12 @@ grub_cmd_read (grub_extcmd_context_t ctxt, int argc, char **argv) static grub_err_t grub_cmd_write (grub_command_t cmd, int argc, char **argv) { - grub_addr_t addr; + 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, N_("two arguments expected")); + 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); @@ -122,32 +119,23 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv) GRUB_MOD_INIT(memrw) { cmd_read_byte = - grub_register_extcmd_lockdown ("read_byte", grub_cmd_read, 0, - N_("ADDR"), - N_("Read 8-bit value from ADDR."), - options); + 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_lockdown ("read_word", grub_cmd_read, 0, - N_("ADDR"), - N_("Read 16-bit value from ADDR."), - options); + 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_lockdown ("read_dword", grub_cmd_read, 0, - N_("ADDR"), - N_("Read 32-bit value from ADDR."), - options); + 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_lockdown ("write_byte", grub_cmd_write, - N_("ADDR VALUE [MASK]"), - N_("Write 8-bit VALUE to ADDR.")); + grub_register_command ("write_byte", grub_cmd_write, + N_("ADDR VALUE [MASK]"), N_("Write byte VALUE to ADDR.")); cmd_write_word = - grub_register_command_lockdown ("write_word", grub_cmd_write, - N_("ADDR VALUE [MASK]"), - N_("Write 16-bit VALUE to ADDR.")); + grub_register_command ("write_word", grub_cmd_write, + N_("ADDR VALUE [MASK]"), N_("Write word VALUE to ADDR.")); cmd_write_dword = - grub_register_command_lockdown ("write_dword", grub_cmd_write, - N_("ADDR VALUE [MASK]"), - N_("Write 32-bit VALUE to ADDR.")); + grub_register_command ("write_dword", grub_cmd_write, + N_("ADDR VALUE [MASK]"), N_("Write dword VALUE to ADDR.")); } GRUB_MOD_FINI(memrw) diff --git a/commands/minicmd.c b/commands/minicmd.c new file mode 100644 index 000000000..4ea9efead --- /dev/null +++ b/commands/minicmd.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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/commands/parttool.c similarity index 75% rename from grub-core/commands/parttool.c rename to commands/parttool.c index ff45c65e6..5ad6133ca 100644 --- a/grub-core/commands/parttool.c +++ b/commands/parttool.c @@ -31,15 +31,13 @@ #include #include -GRUB_MOD_LICENSE ("GPLv2+"); - static struct grub_parttool *parts = 0; static int curhandle = 0; static grub_dl_t mymod; static char helpmsg[] = - N_("Perform COMMANDS on partition.\n" - "Use `parttool PARTITION help' for the list " - "of available commands."); + "Perform COMMANDS on partition.\n" + "Use \"parttool PARTITION help\" for the list " + "of available commands."; int grub_parttool_register(const char *part_name, @@ -59,13 +57,7 @@ grub_parttool_register(const char *part_name, for (nargs = 0; args[nargs].name != 0; nargs++); cur->nargs = nargs; cur->args = (struct grub_parttool_argdesc *) - grub_calloc (nargs + 1, sizeof (struct grub_parttool_argdesc)); - if (!cur->args) - { - grub_free (cur); - curhandle--; - return -1; - } + grub_malloc ((nargs + 1) * sizeof (struct grub_parttool_argdesc)); grub_memcpy (cur->args, args, (nargs + 1) * sizeof (struct grub_parttool_argdesc)); @@ -100,50 +92,6 @@ grub_parttool_unregister (int handle) grub_dl_unref (mymod); } -static grub_err_t -show_help (grub_device_t dev) -{ - int found = 0; - struct grub_parttool *cur; - - 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_xputs (_("=VAL")); - spacing -= 4; - break; - - case GRUB_PARTTOOL_ARG_END: - break; - } - while (spacing-- > 0) - grub_printf (" "); - grub_puts_ (curarg->desc); - } - } - if (! found) - grub_printf_ (N_("Sorry, no parttool is available for %s\n"), - dev->disk->partition->partmap->name); - return GRUB_ERR_NONE; -} - static grub_err_t grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) @@ -154,9 +102,51 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), 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_puts_ (helpmsg); + grub_printf ("%s\n", helpmsg); return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few arguments"); } @@ -185,7 +175,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), } /* Load modules. */ - if (! grub_no_modules) +#ifndef GRUB_UTIL { const char *prefix; prefix = grub_env_get ("prefix"); @@ -193,13 +183,12 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), { char *filename; - filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM - "/parttool.lst", prefix); + filename = grub_xasprintf ("%s/parttool.lst", prefix); if (filename) { grub_file_t file; - file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE_LIST); + file = grub_file_open (filename); if (file) { char *buf = 0; @@ -213,8 +202,6 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), break; name = buf; - while (grub_isspace (name[0])) - name++; if (! grub_isgraph (name[0])) continue; @@ -224,9 +211,8 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), continue; *p = '\0'; - p++; - while (*p == ' ' || *p == '\t') - p++; + while (*++p == ' ') + ; if (! grub_isgraph (*p)) continue; @@ -247,23 +233,16 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), /* Ignore errors. */ grub_errno = GRUB_ERR_NONE; } +#endif if (argc == 1) - { - err = show_help (dev); - grub_device_close (dev); - return err; - } + return show_help (); for (i = 1; i < argc; i++) if (grub_strcmp (args[i], "help") == 0) - { - err = show_help (dev); - grub_device_close (dev); - return err; - } + return show_help (); - parsed = (int *) grub_calloc (argc, sizeof (int)); + parsed = (int *) grub_zalloc (argc * sizeof (int)); for (i = 1; i < argc; i++) if (! parsed[i]) @@ -288,20 +267,16 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), break; } if (! cur) - { - grub_free (parsed); - grub_device_close (dev); - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unknown argument `%s'"), + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unrecognised argument %s", args[i]); - } ptool = cur; pargs = (struct grub_parttool_args *) - grub_calloc (ptool->nargs, sizeof (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[j], + if (grub_strncmp (curarg->name, args[i], grub_strlen (curarg->name)) == 0 && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL && (args[j][grub_strlen (curarg->name)] == '+' @@ -315,7 +290,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), switch (curarg->type) { case GRUB_PARTTOOL_ARG_BOOL: - pargs[curarg - ptool->args].b + pargs[curarg - ptool->args].bool = (args[j][grub_strlen (curarg->name)] != '-'); break; diff --git a/grub-core/commands/password.c b/commands/password.c similarity index 83% rename from grub-core/commands/password.c rename to commands/password.c index 6d42c9b02..04285254e 100644 --- a/grub-core/commands/password.c +++ b/commands/password.c @@ -26,8 +26,6 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - static grub_dl_t my_mod; static grub_err_t @@ -42,22 +40,26 @@ check_password (const char *user, const char *entered, return GRUB_ERR_NONE; } -grub_err_t -grub_normal_set_password (const char *user, const char *password) +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 (password); + copylen = grub_strlen (args[1]); if (copylen >= GRUB_AUTH_MAX_PASSLEN) copylen = GRUB_AUTH_MAX_PASSLEN - 1; - grub_memcpy (pass, password, copylen); + grub_memcpy (pass, args[1], copylen); - err = grub_auth_register_authentication (user, check_password, pass); + err = grub_auth_register_authentication (args[0], check_password, pass); if (err) { grub_free (pass); @@ -67,15 +69,6 @@ grub_normal_set_password (const char *user, const char *password) return GRUB_ERR_NONE; } -static grub_err_t -grub_cmd_password (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) -{ - if (argc != 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); - return grub_normal_set_password (args[0], args[1]); -} - static grub_command_t cmd; GRUB_MOD_INIT(password) diff --git a/grub-core/commands/password_pbkdf2.c b/commands/password_pbkdf2.c similarity index 78% rename from grub-core/commands/password_pbkdf2.c rename to commands/password_pbkdf2.c index bcb902f97..51c8ea794 100644 --- a/grub-core/commands/password_pbkdf2.c +++ b/commands/password_pbkdf2.c @@ -24,9 +24,6 @@ #include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); static grub_dl_t my_mod; @@ -45,7 +42,6 @@ check_password (const char *user, const char *entered, void *pin) grub_uint8_t *buf; struct pbkdf2_password *pass = pin; gcry_err_code_t err; - grub_err_t ret; buf = grub_malloc (pass->buflen); if (!buf) @@ -56,17 +52,17 @@ check_password (const char *user, const char *entered, void *pin) pass->salt, pass->saltlen, pass->c, buf, pass->buflen); if (err) - ret = grub_crypto_gcry_error (err); - else if (grub_crypto_memcmp (buf, pass->expected, pass->buflen) != 0) - ret = GRUB_ACCESS_DENIED; - else { - grub_auth_authenticate (user); - ret = GRUB_ERR_NONE; + grub_free (buf); + return grub_crypto_gcry_error (err); } - grub_free (buf); - return ret; + 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 @@ -86,16 +82,16 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { grub_err_t err; - const char *ptr, *ptr2; + char *ptr, *ptr2; grub_uint8_t *ptro; struct pbkdf2_password *pass; if (argc != 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); + 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, N_("invalid PBKDF2 password")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Incorrect PBKDF2 password."); ptr = args[1] + sizeof ("grub.pbkdf2.sha512.") - 1; @@ -104,15 +100,10 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)), return grub_errno; pass->c = grub_strtoul (ptr, &ptr, 0); - if (grub_errno) - { - grub_free (pass); - return grub_errno; - } if (*ptr != '.') { grub_free (pass); - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid PBKDF2 password")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Incorrect PBKDF2 password."); } ptr++; @@ -120,7 +111,7 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)), if (!ptr2 || ((ptr2 - ptr) & 1) || grub_strlen (ptr2 + 1) & 1) { grub_free (pass); - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid PBKDF2 password")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Incorrect PBKDF2 password."); } pass->saltlen = (ptr2 - ptr) >> 1; @@ -143,11 +134,7 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)), grub_free (pass->salt); grub_free (pass); return grub_error (GRUB_ERR_BAD_ARGUMENT, - /* TRANSLATORS: it means that the string which - was supposed to be a password hash doesn't - have a correct format, not to password - mismatch. */ - N_("invalid PBKDF2 password")); + "Incorrect PBKDF2 password."); } *ptro = (hex1 << 4) | hex2; @@ -162,7 +149,7 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)), return grub_errno; } ptr = ptr2 + 1; - ptr2 += grub_strlen (ptr2); + ptr2 += grub_strlen (ptr2); while (ptr < ptr2) { int hex1, hex2; @@ -176,7 +163,7 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)), grub_free (pass->salt); grub_free (pass); return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("invalid PBKDF2 password")); + "Incorrect PBKDF2 password."); } *ptro = (hex1 << 4) | hex2; @@ -199,8 +186,8 @@ 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). ")); + "password_pbkdf2 USER PBKDF2_PASSWORD", + "Set user password (PBKDF2). "); } GRUB_MOD_FINI(password_pbkdf2) diff --git a/grub-core/commands/probe.c b/commands/probe.c similarity index 50% rename from grub-core/commands/probe.c rename to commands/probe.c index be9637f33..c2cc599e9 100644 --- a/grub-core/commands/probe.c +++ b/commands/probe.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -32,29 +31,23 @@ #include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); static const struct grub_arg_option options[] = { - {"set", 's', 0, - N_("Set a variable to return value."), N_("VARNAME"), ARG_TYPE_STRING}, - /* TRANSLATORS: It's a driver that is currently in use to access - the diven disk. */ + {"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}, - {"part-uuid", 0, 0, N_("Determine partition UUID."), 0, 0}, {0, 0, 0, 0, 0, 0} }; static grub_err_t -grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args) +grub_cmd_probe (grub_extcmd_t cmd, int argc, char **args) { - struct grub_arg_list *state = ctxt->state; + struct grub_arg_list *state = cmd->state; grub_device_t dev; grub_fs_t fs; char *ptr; @@ -73,20 +66,19 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args) else dev = grub_device_open (args[0]); if (! dev) - return grub_errno; + 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->protocol->name; + 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); - grub_device_close (dev); return GRUB_ERR_NONE; } if (state[2].set) @@ -98,141 +90,59 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args) grub_env_set (state[0].arg, val); else grub_printf ("%s", val); - grub_device_close (dev); - return GRUB_ERR_NONE; - } - if (state[6].set) - { - /* AAAABBBB-CCCC-DDDD-EEEE-FFFFFFFFFFFF + null terminator */ - char val[37] = "none"; - if (dev->disk && dev->disk->partition) - { - struct grub_partition *p = dev->disk->partition; - grub_disk_t disk = grub_disk_open(dev->disk->name); - - if (!disk) - { - grub_device_close (dev); - return grub_errno; - } - - if (grub_strcmp(dev->disk->partition->partmap->name, "gpt") == 0) - { - struct grub_gpt_partentry entry; - grub_guid_t *guid; - - if (grub_disk_read(disk, p->offset, p->index, sizeof(entry), &entry)) - { - grub_error_push (); - grub_disk_close (disk); - grub_device_close (dev); - grub_error_pop (); - return grub_errno; - } - guid = &entry.guid; - guid->data1 = grub_le_to_cpu32 (guid->data1); - guid->data2 = grub_le_to_cpu16 (guid->data2); - guid->data3 = grub_le_to_cpu16 (guid->data3); - grub_snprintf (val, sizeof(val), "%pG", guid); - } - else if (grub_strcmp(dev->disk->partition->partmap->name, "msdos") == 0) - { - grub_uint32_t nt_disk_sig; - - if (grub_disk_read(disk, 0, GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, - sizeof(nt_disk_sig), &nt_disk_sig) == 0) - grub_snprintf (val, sizeof(val), "%08x-%02x", - grub_le_to_cpu32(nt_disk_sig), 1 + p->number); - } - grub_disk_close(disk); - } - if (state[0].set) - grub_env_set (state[0].arg, val); - else - grub_printf ("%s", val); - grub_device_close (dev); return GRUB_ERR_NONE; } fs = grub_fs_probe (dev); if (! fs) - { - grub_error_push (); - grub_device_close (dev); - grub_error_pop (); - return grub_errno; - } + 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); - grub_device_close (dev); return GRUB_ERR_NONE; } if (state[4].set) { char *uuid; - if (! fs->fs_uuid) - { - grub_device_close (dev); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("%s does not support UUIDs"), fs->name); - } - err = fs->fs_uuid (dev, &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) - { - grub_device_close (dev); - return err; - } + return err; if (! uuid) - { - grub_device_close (dev); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("%s does not support UUIDs"), fs->name); - } + 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); - grub_device_close (dev); return GRUB_ERR_NONE; } if (state[5].set) { char *label; - if (! fs->fs_label) - { - grub_device_close (dev); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("filesystem `%s' does not support labels"), - fs->name); - } - err = fs->fs_label (dev, &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) - { - grub_device_close (dev); - return err; - } + return err; if (! label) - { - grub_device_close (dev); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("filesystem `%s' does not support labels"), - fs->name); - } + 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); - grub_device_close (dev); return GRUB_ERR_NONE; } - grub_device_close (dev); return grub_error (GRUB_ERR_BAD_ARGUMENT, "unrecognised target"); } @@ -240,7 +150,8 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT (probe) { - cmd = grub_register_extcmd ("probe", grub_cmd_probe, 0, N_("DEVICE"), + cmd = grub_register_extcmd ("probe", grub_cmd_probe, GRUB_COMMAND_FLAG_BOTH, + N_("[DEVICE]"), N_("Retrieve device info."), options); } diff --git a/grub-core/commands/read.c b/commands/read.c similarity index 55% rename from grub-core/commands/read.c rename to commands/read.c index 8d72e45c9..8a7c4a01f 100644 --- a/grub-core/commands/read.c +++ b/commands/read.c @@ -23,29 +23,19 @@ #include #include #include -#include +#include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static const struct grub_arg_option options[] = - { - {"silent", 's', 0, N_("Do not echo input"), 0, 0}, - {0, 0, 0, 0, 0, 0} - }; static char * -grub_getline (int silent) +grub_getline (void) { - grub_size_t i; + int i; char *line; char *tmp; - int c; - grub_size_t alloc_size; + char c; i = 0; - line = grub_malloc (1 + sizeof('\0')); + line = grub_malloc (1 + i + sizeof('\0')); if (! line) return NULL; @@ -55,23 +45,11 @@ grub_getline (int silent) if ((c == '\n') || (c == '\r')) break; - if (!grub_isprint (c)) - continue; - - line[i] = (char) c; - if (!silent) - grub_printf ("%c", c); - if (grub_add (i, 1, &i)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); - return NULL; - } - if (grub_add (i, 1 + sizeof('\0'), &alloc_size)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); - return NULL; - } - tmp = grub_realloc (line, alloc_size); + line[i] = c; + if (grub_isprint (c)) + grub_putchar (c); + i++; + tmp = grub_realloc (line, 1 + i + sizeof('\0')); if (! tmp) { grub_free (line); @@ -85,11 +63,9 @@ grub_getline (int silent) } static grub_err_t -grub_cmd_read (grub_extcmd_context_t ctxt, int argc, char **args) +grub_cmd_read (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { - struct grub_arg_list *state = ctxt->state; - char *line = grub_getline (state[0].set); - + char *line = grub_getline (); if (! line) return grub_errno; if (argc > 0) @@ -99,16 +75,16 @@ grub_cmd_read (grub_extcmd_context_t ctxt, int argc, char **args) return 0; } -static grub_extcmd_t cmd; +static grub_command_t cmd; GRUB_MOD_INIT(read) { - cmd = grub_register_extcmd ("read", grub_cmd_read, 0, - N_("[-s] [ENVVAR]"), - N_("Set variable with user input."), options); + cmd = grub_register_command ("read", grub_cmd_read, + N_("[ENVVAR]"), + N_("Set variable with user input.")); } GRUB_MOD_FINI(read) { - grub_unregister_extcmd (cmd); + grub_unregister_command (cmd); } diff --git a/grub-core/commands/reboot.c b/commands/reboot.c similarity index 94% rename from grub-core/commands/reboot.c rename to commands/reboot.c index 46d364c99..eedd53c91 100644 --- a/grub-core/commands/reboot.c +++ b/commands/reboot.c @@ -22,14 +22,13 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t __attribute__ ((noreturn)) +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; diff --git a/commands/search.c b/commands/search.c new file mode 100644 index 000000000..afb2e98e8 --- /dev/null +++ b/commands/search.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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_file) +#elif defined (DO_SEARCH_FS_UUID) +GRUB_MOD_INIT(search_fs_uuid) +#else +GRUB_MOD_INIT(search_fs_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_file) +#elif defined (DO_SEARCH_FS_UUID) +GRUB_MOD_FINI(search_fs_uuid) +#else +GRUB_MOD_FINI(search_fs_label) +#endif +{ + grub_unregister_command (cmd); +} diff --git a/grub-core/commands/search_file.c b/commands/search_file.c similarity index 89% rename from grub-core/commands/search_file.c rename to commands/search_file.c index cc2a5f939..73ce89ccc 100644 --- a/grub-core/commands/search_file.c +++ b/commands/search_file.c @@ -1,5 +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/commands/search_label.c similarity index 85% rename from grub-core/commands/search_label.c rename to commands/search_label.c index 12e7c1831..ee9c792be 100644 --- a/grub-core/commands/search_label.c +++ b/commands/search_label.c @@ -1,5 +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/commands/search_uuid.c similarity index 86% rename from grub-core/commands/search_uuid.c rename to commands/search_uuid.c index 541bcf54b..52f83812c 100644 --- a/grub-core/commands/search_uuid.c +++ b/commands/search_uuid.c @@ -1,5 +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/commands/search_wrap.c b/commands/search_wrap.c new file mode 100644 index 000000000..2891d85d7 --- /dev/null +++ b/commands/search_wrap.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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/commands/setpci.c similarity index 75% rename from grub-core/commands/setpci.c rename to commands/setpci.c index 5917625f8..f780547a2 100644 --- a/grub-core/commands/setpci.c +++ b/commands/setpci.c @@ -23,9 +23,6 @@ #include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); struct pci_register { @@ -34,7 +31,7 @@ struct pci_register unsigned size; }; -static struct pci_register pci_registers[] = +struct pci_register pci_registers[] = { {"VENDOR_ID", GRUB_PCI_REG_VENDOR , 2}, {"DEVICE_ID", GRUB_PCI_REG_DEVICE , 2}, @@ -66,12 +63,12 @@ static struct pci_register pci_registers[] = static const struct grub_arg_option options[] = { - {0, 'd', 0, N_("Select device by vendor and device IDs."), - N_("[vendor]:[device]"), ARG_TYPE_STRING}, - {0, 's', 0, N_("Select device by its position on the bus."), - N_("[bus]:[slot][.func]"), ARG_TYPE_STRING}, - {0, 'v', 0, N_("Save read value into variable VARNAME."), - N_("VARNAME"), ARG_TYPE_STRING}, + {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} }; @@ -83,9 +80,8 @@ static int regsize; static grub_uint16_t regaddr; static const char *varname; -static int -grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, - void *data __attribute__ ((unused))) +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; @@ -99,7 +95,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, if (check_device && grub_pci_get_device (dev) != device) return 0; - if (check_function && grub_pci_get_function (dev) != function) + if (check_function && grub_pci_get_function (dev) != device) return 0; addr = grub_pci_make_address (dev, regaddr); @@ -129,7 +125,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, if (!write_mask) { - grub_printf (_("Register %x of %x:%02x.%x is %x\n"), regaddr, + 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), @@ -158,7 +154,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, } static grub_err_t -grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) +grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv) { const char *ptr; unsigned i; @@ -166,23 +162,24 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) pciid_check_value = 0; pciid_check_mask = 0; - if (ctxt->state[0].set) + if (cmd->state[0].set) { - ptr = ctxt->state[0].arg; - pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff); + 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 = ctxt->state[0].arg; + 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, N_("missing `%c' symbol"), ':'); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Colon expected."); ptr++; - pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff) << 16; + pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff) + << 16; if (grub_errno == GRUB_ERR_BAD_NUMBER) grub_errno = GRUB_ERR_NONE; else @@ -193,13 +190,13 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) check_bus = check_device = check_function = 0; - if (ctxt->state[1].set) + if (cmd->state[1].set) { const char *optr; - - ptr = ctxt->state[1].arg; + + ptr = cmd->state[1].arg; optr = ptr; - bus = grub_strtoul (ptr, &ptr, 16); + bus = grub_strtoul (ptr, (char **) &ptr, 16); if (grub_errno == GRUB_ERR_BAD_NUMBER) { grub_errno = GRUB_ERR_NONE; @@ -210,10 +207,10 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) if (grub_errno) return grub_errno; if (*ptr != ':') - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':'); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Colon expected."); ptr++; optr = ptr; - device = grub_strtoul (ptr, &ptr, 16); + device = grub_strtoul (ptr, (char **) &ptr, 16); if (grub_errno == GRUB_ERR_BAD_NUMBER) { grub_errno = GRUB_ERR_NONE; @@ -224,22 +221,25 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) if (*ptr == '.') { ptr++; - function = grub_strtoul (ptr, &ptr, 16); + function = grub_strtoul (ptr, (char **) &ptr, 16); if (grub_errno) return grub_errno; check_function = 1; } } - if (ctxt->state[2].set) - varname = ctxt->state[2].arg; + if (cmd->state[2].set) + varname = cmd->state[2].arg; else varname = NULL; write_mask = 0; - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + 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]; @@ -252,9 +252,9 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) if (i == ARRAY_SIZE (pci_registers)) { regsize = 0; - regaddr = grub_strtoul (ptr, &ptr, 16); + regaddr = grub_strtoul (ptr, (char **) &ptr, 16); if (grub_errno) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown register"); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown register"); } else { @@ -269,7 +269,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) if (*ptr == '+') { ptr++; - regaddr += grub_strtoul (ptr, &ptr, 16); + regaddr += grub_strtoul (ptr, (char **) &ptr, 16); if (grub_errno) return grub_errno; } @@ -295,31 +295,32 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) if (!regsize) return grub_error (GRUB_ERR_BAD_ARGUMENT, - "unknown register size"); + "Unknown register size."); write_mask = 0; if (*ptr == '=') { ptr++; - regwrite = grub_strtoul (ptr, &ptr, 16); + regwrite = grub_strtoul (ptr, (char **) &ptr, 16); if (grub_errno) return grub_errno; write_mask = 0xffffffff; if (*ptr == ':') { ptr++; - write_mask = grub_strtoul (ptr, &ptr, 16); + 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"); + "Option -v isn't valid for writes."); - grub_pci_iterate (grub_setpci_iter, NULL); + grub_pci_iterate (grub_setpci_iter); return GRUB_ERR_NONE; } @@ -327,10 +328,10 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(setpci) { - cmd = grub_register_extcmd_lockdown ("setpci", grub_cmd_setpci, 0, - N_("[-s POSITION] [-d DEVICE] [-v VAR] " - "REGISTER[=VALUE[:MASK]]"), - N_("Manipulate PCI devices."), options); + cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, GRUB_COMMAND_FLAG_BOTH, + "setpci [-s POSITION] [-d DEVICE] [-v VAR] " + "[REGISTER][=VALUE[:MASK]]", + "Manipulate PCI devices.", options); } GRUB_MOD_FINI(setpci) diff --git a/grub-core/commands/sleep.c b/commands/sleep.c similarity index 82% rename from grub-core/commands/sleep.c rename to commands/sleep.c index a1370b710..012181fa2 100644 --- a/grub-core/commands/sleep.c +++ b/commands/sleep.c @@ -22,19 +22,18 @@ #include #include #include +#include #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - static const struct grub_arg_option options[] = { {"verbose", 'v', 0, N_("Verbose countdown."), 0, 0}, - {"interruptible", 'i', 0, N_("Allow to interrupt with ESC."), 0, 0}, + {"interruptible", 'i', 0, N_("Interruptible with ESC."), 0, 0}, {0, 0, 0, 0, 0, 0} }; -static struct grub_term_coordinate *pos; +static grub_uint16_t *pos; static void do_print (int n) @@ -43,7 +42,6 @@ do_print (int n) /* NOTE: Do not remove the trailing space characters. They are required to clear the line. */ grub_printf ("%d ", n); - grub_refresh (); } /* Based on grub_millisleep() from kern/generic/millisleep.c. */ @@ -55,20 +53,21 @@ grub_interruptible_millisleep (grub_uint32_t ms) start = grub_get_time_ms (); while (grub_get_time_ms () - start < ms) - if (grub_key_is_interrupt (grub_getkey_noblock ())) + 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_context_t ctxt, int argc, char **args) +grub_cmd_sleep (grub_extcmd_t cmd, int argc, char **args) { - struct grub_arg_list *state = ctxt->state; + struct grub_arg_list *state = cmd->state; int n; if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing operand"); n = grub_strtoul (args[0], 0, 10); @@ -78,8 +77,6 @@ grub_cmd_sleep (grub_extcmd_context_t ctxt, int argc, char **args) return 0; } - grub_refresh (); - pos = grub_term_save_pos (); for (; n; n--) @@ -105,7 +102,7 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(sleep) { - cmd = grub_register_extcmd ("sleep", grub_cmd_sleep, 0, + 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); diff --git a/commands/terminal.c b/commands/terminal.c new file mode 100644 index 000000000..e725123b8 --- /dev/null +++ b/commands/terminal.c @@ -0,0 +1,368 @@ +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +struct grub_term_autoload *grub_term_input_autoload = NULL; +struct grub_term_autoload *grub_term_output_autoload = NULL; + +static grub_err_t +grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + int i; + grub_term_input_t term; + struct grub_term_autoload *aut; + + if (argc == 0) + { + grub_puts_ (N_ ("Active input terminals:")); + FOR_ACTIVE_TERM_INPUTS(term) + grub_printf ("%s ", term->name); + grub_printf ("\n"); + grub_puts_ (N_ ("Available input terminals:")); + FOR_DISABLED_TERM_INPUTS(term) + grub_printf ("%s ", term->name); + /* This is quadratic but we don't expect mode than 30 terminal + modules ever. */ + for (aut = grub_term_input_autoload; aut; aut = aut->next) + { + FOR_DISABLED_TERM_INPUTS(term) + if (grub_strcmp (term->name, aut->name) == 0) + break; + if (!term) + FOR_ACTIVE_TERM_INPUTS(term) + 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_DISABLED_TERM_INPUTS(term) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term == 0) + FOR_ACTIVE_TERM_INPUTS(term) + 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 = grub_term_input_autoload; 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_DISABLED_TERM_INPUTS(term) + 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 (&(grub_term_inputs_disabled)), + GRUB_AS_LIST (term)); + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), + GRUB_AS_LIST (term)); + } + } + return GRUB_ERR_NONE; + } + + if (grub_strcmp (args[0], "--remove") == 0) + { + for (i = 1; i < argc; i++) + { + FOR_ACTIVE_TERM_INPUTS(term) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + { + if (!term->next && term == grub_term_inputs) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "can't remove the last terminal"); + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)), + GRUB_AS_LIST (term)); + if (term->fini) + term->fini (); + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), + GRUB_AS_LIST (term)); + } + } + return GRUB_ERR_NONE; + } + for (i = 0; i < argc; i++) + { + FOR_DISABLED_TERM_INPUTS(term) + 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 (&(grub_term_inputs_disabled)), + GRUB_AS_LIST (term)); + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), + GRUB_AS_LIST (term)); + } + } + + FOR_ACTIVE_TERM_INPUTS(term) + { + for (i = 0; i < argc; i++) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (i == argc) + { + if (!term->next && term == grub_term_inputs) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "can't remove the last terminal"); + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)), + GRUB_AS_LIST (term)); + if (term->fini) + term->fini (); + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), + GRUB_AS_LIST (term)); + } + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + int i; + grub_term_output_t term; + struct grub_term_autoload *aut; + + if (argc == 0) + { + grub_puts_ (N_ ("Active output terminals:")); + FOR_ACTIVE_TERM_OUTPUTS(term) + grub_printf ("%s ", term->name); + grub_printf ("\n"); + grub_puts_ (N_ ("Available output terminals:")); + FOR_DISABLED_TERM_OUTPUTS(term) + grub_printf ("%s ", term->name); + /* This is quadratic but we don't expect mode than 30 terminal + modules ever. */ + for (aut = grub_term_output_autoload; aut; aut = aut->next) + { + FOR_DISABLED_TERM_OUTPUTS(term) + if (grub_strcmp (term->name, aut->name) == 0) + break; + if (!term) + FOR_ACTIVE_TERM_OUTPUTS(term) + 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_DISABLED_TERM_OUTPUTS(term) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term == 0) + FOR_ACTIVE_TERM_OUTPUTS(term) + 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 = grub_term_output_autoload; 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_DISABLED_TERM_OUTPUTS(term) + 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 (&(grub_term_outputs_disabled)), + GRUB_AS_LIST (term)); + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), + GRUB_AS_LIST (term)); + } + } + return GRUB_ERR_NONE; + } + + if (grub_strcmp (args[0], "--remove") == 0) + { + for (i = 1; i < argc; i++) + { + FOR_ACTIVE_TERM_OUTPUTS(term) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + { + if (!term->next && term == grub_term_outputs) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "can't remove the last terminal"); + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)), + GRUB_AS_LIST (term)); + if (term->fini) + term->fini (); + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled), + GRUB_AS_LIST (term)); + } + } + return GRUB_ERR_NONE; + } + + for (i = 0; i < argc; i++) + { + FOR_DISABLED_TERM_OUTPUTS(term) + 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 (&(grub_term_outputs_disabled)), + GRUB_AS_LIST (term)); + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), + GRUB_AS_LIST (term)); + } + } + + FOR_ACTIVE_TERM_OUTPUTS(term) + { + for (i = 0; i < argc; i++) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (i == argc) + { + if (!term->next && term == grub_term_outputs) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "can't remove the last terminal"); + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)), + GRUB_AS_LIST (term)); + if (term->fini) + term->fini (); + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled), + GRUB_AS_LIST (term)); + } + } + + return GRUB_ERR_NONE; +} + +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, + "[--append|--remove] " + "[TERMINAL1] [TERMINAL2] ...", + "List or select an input terminal."); + cmd_terminal_output = + grub_register_command ("terminal_output", grub_cmd_terminal_output, + "[--append|--remove] " + "[TERMINAL1] [TERMINAL2] ...", + "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/commands/test.c similarity index 57% rename from grub-core/commands/test.c rename to commands/test.c index b585c3d70..6995165cf 100644 --- a/grub-core/commands/test.c +++ b/commands/test.c @@ -27,139 +27,123 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - -/* Set a limit on recursion to avoid stack overflow. */ -#define MAX_TEST_RECURSION_DEPTH 100 - /* A simple implementation for signed numbers. */ static int -grub_strtosl (char *arg, const char ** const end, int base) +grub_strtosl (char *arg, char **end, int base) { if (arg[0] == '-') return -grub_strtoul (arg + 1, end, base); return grub_strtoul (arg, end, base); } -/* Context for test_parse. */ -struct test_parse_ctx -{ - int invert; - int or, and; - int file_exists; - struct grub_dirhook_info file_info; - char *filename; -}; - -/* Take care of discarding and inverting. */ -static void -update_val (int val, struct test_parse_ctx *ctx) -{ - ctx->and = ctx->and && (ctx->invert ? ! val : val); - ctx->invert = 0; -} - -/* A hook for iterating directories. */ -static int -find_file (const char *cur_filename, const struct grub_dirhook_info *info, - void *data) -{ - struct test_parse_ctx *ctx = data; - - if ((info->case_insensitive ? grub_strcasecmp (cur_filename, ctx->filename) - : grub_strcmp (cur_filename, ctx->filename)) == 0) - { - ctx->file_info = *info; - ctx->file_exists = 1; - return 1; - } - return 0; -} - -/* Check if file exists and fetch its information. */ -static void -get_fileinfo (char *path, struct test_parse_ctx *ctx) -{ - char *pathname; - char *device_name; - grub_fs_t fs; - grub_device_t dev; - - ctx->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. */ - ctx->filename = grub_strrchr (pathname, '/'); - if (! ctx->filename) - { - path = grub_strdup ("/"); - ctx->filename = pathname; - } - else - { - ctx->filename++; - path = grub_strdup (pathname); - path[ctx->filename - pathname] = 0; - } - - /* It's the whole device. */ - if (! *pathname) - { - ctx->file_exists = 1; - grub_memset (&ctx->file_info, 0, sizeof (ctx->file_info)); - /* Root is always a directory. */ - ctx->file_info.dir = 1; - - /* Fetch writing time. */ - ctx->file_info.mtimeset = 0; - if (fs->fs_mtime) - { - if (! fs->fs_mtime (dev, &ctx->file_info.mtime)) - ctx->file_info.mtimeset = 1; - grub_errno = GRUB_ERR_NONE; - } - } - else - (fs->fs_dir) (dev, path, find_file, ctx); - - grub_device_close (dev); - grub_free (path); - grub_free (device_name); -} - /* Parse a test expression starting from *argn. */ static int -test_parse (char **args, int *argn, int argc, int *depth) +test_parse (char **args, int *argn, int argc) { - struct test_parse_ctx ctx = { - .and = 1, - .or = 0, - .invert = 0 - }; + 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) @@ -171,16 +155,14 @@ test_parse (char **args, int *argn, int argc, int *depth) if (grub_strcmp (args[*argn + 1], "=") == 0 || grub_strcmp (args[*argn + 1], "==") == 0) { - update_val (grub_strcmp (args[*argn], args[*argn + 2]) == 0, - &ctx); + 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, - &ctx); + update_val (grub_strcmp (args[*argn], args[*argn + 2]) != 0); (*argn) += 3; continue; } @@ -188,32 +170,28 @@ test_parse (char **args, int *argn, int argc, int *depth) /* GRUB extension: lexicographical sorting. */ if (grub_strcmp (args[*argn + 1], "<") == 0) { - update_val (grub_strcmp (args[*argn], args[*argn + 2]) < 0, - &ctx); + 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, - &ctx); + 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, - &ctx); + 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, - &ctx); + update_val (grub_strcmp (args[*argn], args[*argn + 2]) >= 0); (*argn) += 3; continue; } @@ -222,7 +200,7 @@ test_parse (char **args, int *argn, int argc, int *depth) if (grub_strcmp (args[*argn + 1], "-eq") == 0) { update_val (grub_strtosl (args[*argn], 0, 0) - == grub_strtosl (args[*argn + 2], 0, 0), &ctx); + == grub_strtosl (args[*argn + 2], 0, 0)); (*argn) += 3; continue; } @@ -230,7 +208,7 @@ test_parse (char **args, int *argn, int argc, int *depth) if (grub_strcmp (args[*argn + 1], "-ge") == 0) { update_val (grub_strtosl (args[*argn], 0, 0) - >= grub_strtosl (args[*argn + 2], 0, 0), &ctx); + >= grub_strtosl (args[*argn + 2], 0, 0)); (*argn) += 3; continue; } @@ -238,7 +216,7 @@ test_parse (char **args, int *argn, int argc, int *depth) if (grub_strcmp (args[*argn + 1], "-gt") == 0) { update_val (grub_strtosl (args[*argn], 0, 0) - > grub_strtosl (args[*argn + 2], 0, 0), &ctx); + > grub_strtosl (args[*argn + 2], 0, 0)); (*argn) += 3; continue; } @@ -246,7 +224,7 @@ test_parse (char **args, int *argn, int argc, int *depth) if (grub_strcmp (args[*argn + 1], "-le") == 0) { update_val (grub_strtosl (args[*argn], 0, 0) - <= grub_strtosl (args[*argn + 2], 0, 0), &ctx); + <= grub_strtosl (args[*argn + 2], 0, 0)); (*argn) += 3; continue; } @@ -254,7 +232,7 @@ test_parse (char **args, int *argn, int argc, int *depth) if (grub_strcmp (args[*argn + 1], "-lt") == 0) { update_val (grub_strtosl (args[*argn], 0, 0) - < grub_strtosl (args[*argn + 2], 0, 0), &ctx); + < grub_strtosl (args[*argn + 2], 0, 0)); (*argn) += 3; continue; } @@ -262,7 +240,7 @@ test_parse (char **args, int *argn, int argc, int *depth) if (grub_strcmp (args[*argn + 1], "-ne") == 0) { update_val (grub_strtosl (args[*argn], 0, 0) - != grub_strtosl (args[*argn + 2], 0, 0), &ctx); + != grub_strtosl (args[*argn + 2], 0, 0)); (*argn) += 3; continue; } @@ -285,10 +263,10 @@ test_parse (char **args, int *argn, int argc, int *depth) 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), &ctx); + > 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), &ctx); + < grub_strtoul (args[*argn + 2] + i, 0, 0)); (*argn) += 3; continue; } @@ -303,24 +281,22 @@ test_parse (char **args, int *argn, int argc, int *depth) int bias = 0; /* Fetch fileinfo. */ - get_fileinfo (args[*argn], &ctx); - file1 = ctx.file_info; - file1exists = ctx.file_exists; - get_fileinfo (args[*argn + 2], &ctx); + 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 && ! ctx.file_exists) - || (file1.mtimeset && ctx.file_info.mtimeset - && file1.mtime + bias > ctx.file_info.mtime), - &ctx); + update_val ((file1exists && ! file_exists) + || (file1.mtimeset && file_info.mtimeset + && file1.mtime + bias > file_info.mtime)); else - update_val ((! file1exists && ctx.file_exists) - || (file1.mtimeset && ctx.file_info.mtimeset - && file1.mtime + bias < ctx.file_info.mtime), - &ctx); + update_val ((! file1exists && file_exists) + || (file1.mtimeset && file_info.mtimeset + && file1.mtime + bias < file_info.mtime)); (*argn) += 3; continue; } @@ -332,53 +308,52 @@ test_parse (char **args, int *argn, int argc, int *depth) /* File tests. */ if (grub_strcmp (args[*argn], "-d") == 0) { - get_fileinfo (args[*argn + 1], &ctx); - update_val (ctx.file_exists && ctx.file_info.dir, &ctx); + get_fileinfo (args[*argn + 1]); + update_val (file_exists && file_info.dir); (*argn) += 2; - continue; + return ret; } if (grub_strcmp (args[*argn], "-e") == 0) { - get_fileinfo (args[*argn + 1], &ctx); - update_val (ctx.file_exists, &ctx); + get_fileinfo (args[*argn + 1]); + update_val (file_exists); (*argn) += 2; - continue; + return ret; } if (grub_strcmp (args[*argn], "-f") == 0) { - get_fileinfo (args[*argn + 1], &ctx); + get_fileinfo (args[*argn + 1]); /* FIXME: check for other types. */ - update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx); + update_val (file_exists && ! file_info.dir); (*argn) += 2; - continue; + return ret; } if (grub_strcmp (args[*argn], "-s") == 0) { grub_file_t file; - file = grub_file_open (args[*argn + 1], GRUB_FILE_TYPE_GET_SIZE - | GRUB_FILE_TYPE_NO_DECOMPRESS); - update_val (file && (grub_file_size (file) != 0), &ctx); + 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; - continue; + return ret; } /* String tests. */ if (grub_strcmp (args[*argn], "-n") == 0) { - update_val (args[*argn + 1][0], &ctx); + update_val (args[*argn + 1][0]); (*argn) += 2; continue; } if (grub_strcmp (args[*argn], "-z") == 0) { - update_val (! args[*argn + 1][0], &ctx); + update_val (! args[*argn + 1][0]); (*argn) += 2; continue; } @@ -390,51 +365,42 @@ test_parse (char **args, int *argn, int argc, int *depth) if (grub_strcmp (args[*argn], ")") == 0) { (*argn)++; - if (*depth > 0) - (*depth)--; - - return ctx.or || ctx.and; + return ret; } /* Recursively invoke if parenthesis. */ if (grub_strcmp (args[*argn], "(") == 0) { (*argn)++; - - if (++(*depth) > MAX_TEST_RECURSION_DEPTH) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("max recursion depth exceeded")); - depth--; - return ctx.or || ctx.and; - } - - update_val (test_parse (args, argn, argc, depth), &ctx); + update_val (test_parse (args, argn, argc)); continue; } if (grub_strcmp (args[*argn], "!") == 0) { - ctx.invert = ! ctx.invert; + 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) { - ctx.or = ctx.or || ctx.and; - ctx.and = 1; + /* 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], &ctx); + update_val (args[*argn][0]); (*argn)++; } - return ctx.or || ctx.and; + return ret; } static grub_err_t @@ -442,13 +408,12 @@ grub_cmd_test (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { int argn = 0; - int depth = 0; if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0) argc--; - return test_parse (args, &argn, argc, &depth) ? GRUB_ERR_NONE - : grub_error (GRUB_ERR_TEST_FAILURE, N_("false")); + return test_parse (args, &argn, argc) ? GRUB_ERR_NONE + : grub_error (GRUB_ERR_TEST_FAILURE, "false"); } static grub_command_t cmd_1, cmd_2; @@ -457,10 +422,8 @@ GRUB_MOD_INIT(test) { cmd_1 = grub_register_command ("[", grub_cmd_test, N_("EXPRESSION ]"), N_("Evaluate an expression.")); - cmd_1->flags |= GRUB_COMMAND_FLAG_EXTRACTOR; cmd_2 = grub_register_command ("test", grub_cmd_test, N_("EXPRESSION"), N_("Evaluate an expression.")); - cmd_2->flags |= GRUB_COMMAND_FLAG_EXTRACTOR; } GRUB_MOD_FINI(test) diff --git a/grub-core/commands/true.c b/commands/true.c similarity index 89% rename from grub-core/commands/true.c rename to commands/true.c index 8cbba6583..aa8125853 100644 --- a/grub-core/commands/true.c +++ b/commands/true.c @@ -21,8 +21,6 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - static grub_err_t grub_cmd_true (struct grub_command *cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), @@ -36,7 +34,7 @@ grub_cmd_false (struct grub_command *cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused))) { - return grub_error (GRUB_ERR_TEST_FAILURE, N_("false")); + return grub_error (GRUB_ERR_TEST_FAILURE, "false"); } static grub_command_t cmd_true, cmd_false; @@ -46,11 +44,9 @@ GRUB_MOD_INIT(true) { cmd_true = grub_register_command ("true", grub_cmd_true, - /* TRANSLATORS: it's a command description. */ 0, N_("Do nothing, successfully.")); cmd_false = grub_register_command ("false", grub_cmd_false, - /* TRANSLATORS: it's a command description. */ 0, N_("Do nothing, unsuccessfully.")); } diff --git a/grub-core/commands/usbtest.c b/commands/usbtest.c similarity index 78% rename from grub-core/commands/usbtest.c rename to commands/usbtest.c index 2c6d93fe6..b884a93f1 100644 --- a/grub-core/commands/usbtest.c +++ b/commands/usbtest.c @@ -27,15 +27,13 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - static const char *usb_classes[] = { - "Unknown", + "", "Audio", "Communication Interface", "HID", - "Unknown", + "", "Physical", "Image", "Printer", @@ -63,11 +61,6 @@ static const char *usb_devspeed[] = "High" }; -#if __GNUC__ >= 9 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Waddress-of-packed-member" -#endif - static grub_usb_err_t grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid, char **string) @@ -90,37 +83,24 @@ grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid, 0x06, (3 << 8) | index, langid, descstr.length, (char *) descstrp); - if (descstrp->length == 0) - { - grub_free (descstrp); - *string = grub_strdup (""); - if (! *string) - return GRUB_USB_ERR_INTERNAL; - return GRUB_USB_ERR_NONE; - } - - *string = grub_malloc (descstr.length * 2 + 1); + *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) = 0; + 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; } -#if __GNUC__ >= 9 -#pragma GCC diagnostic pop -#endif - static void usb_print_str (const char *description, grub_usb_device_t dev, int idx) { - char *name = NULL; + char *name; grub_usb_err_t err; /* XXX: LANGID */ @@ -138,7 +118,7 @@ usb_print_str (const char *description, grub_usb_device_t dev, int idx) } static int -usb_iterate (grub_usb_device_t dev, void *data __attribute__ ((unused))) +usb_iterate (grub_usb_device_t dev) { struct grub_usb_desc_device *descdev; int i; @@ -149,10 +129,10 @@ usb_iterate (grub_usb_device_t dev, void *data __attribute__ ((unused))) usb_print_str ("Vendor", dev, descdev->strvendor); usb_print_str ("Serial", dev, descdev->strserial); - grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n", - descdev->class, descdev->class < ARRAY_SIZE (usb_classes) - ? usb_classes[descdev->class] : "Unknown", - descdev->subclass, descdev->protocol); + 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); @@ -175,10 +155,10 @@ usb_iterate (grub_usb_device_t dev, void *data __attribute__ ((unused))) grub_printf ("Interface #%d: #Endpoints: %d ", i, interf->endpointcnt); - grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n", - interf->class, interf->class < ARRAY_SIZE (usb_classes) - ? usb_classes[interf->class] : "Unknown", - interf->subclass, interf->protocol); + 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); @@ -205,10 +185,8 @@ grub_cmd_usbtest (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - grub_usb_poll_devices (1); - grub_printf ("USB devices:\n\n"); - grub_usb_iterate (usb_iterate, NULL); + grub_usb_iterate (usb_iterate); return 0; } diff --git a/commands/videotest.c b/commands/videotest.c new file mode 100644 index 000000000..390811a71 --- /dev/null +++ b/commands/videotest.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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/commands/xnu_uuid.c similarity index 77% rename from grub-core/commands/xnu_uuid.c rename to commands/xnu_uuid.c index ae4b3a415..382d3196b 100644 --- a/grub-core/commands/xnu_uuid.c +++ b/commands/xnu_uuid.c @@ -34,8 +34,6 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - /* This prefix is used by xnu and boot-132 to hash together with volume serial. */ static grub_uint8_t hash_prefix[16] @@ -50,29 +48,18 @@ grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)), grub_uint8_t *xnu_uuid; char uuid_string[sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]; char *ptr; - void *ctx; - int low = 0; + grub_uint8_t ctx[GRUB_MD_MD5->contextsize]; if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "UUID required"); - if (argc > 1 && grub_strcmp (args[0], "-l") == 0) - { - low = 1; - argc--; - args++; - } - serial = grub_cpu_to_be64 (grub_strtoull (args[0], 0, 16)); - ctx = grub_zalloc (GRUB_MD_MD5->contextsize); - if (!ctx) - return grub_errno; - 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_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", @@ -86,16 +73,13 @@ grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)), (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]); - if (!low) - for (ptr = uuid_string; *ptr; ptr++) - *ptr = grub_toupper (*ptr); + for (ptr = uuid_string; *ptr; ptr++) + *ptr = grub_toupper (*ptr); if (argc == 1) - grub_printf ("%s\n", uuid_string); + grub_printf ("%s", uuid_string); if (argc > 1) grub_env_set (args[1], uuid_string); - grub_free (ctx); - return GRUB_ERR_NONE; } @@ -105,12 +89,9 @@ static grub_command_t cmd; GRUB_MOD_INIT (xnu_uuid) { cmd = grub_register_command ("xnu_uuid", grub_cmd_xnu_uuid, - /* TRANSLATORS: GRUBUUID stands for "filesystem - UUID as used in GRUB". */ - N_("[-l] GRUBUUID [VARNAME]"), + N_("GRUBUUID [VARNAME]"), N_("Transform 64-bit UUID to format " - "suitable for XNU. If -l is given keep " - "it lowercase as done by blkid.")); + "suitable for XNU.")); } GRUB_MOD_FINI (xnu_uuid) diff --git a/conf/Makefile.common b/conf/Makefile.common deleted file mode 100644 index c60f55386..000000000 --- a/conf/Makefile.common +++ /dev/null @@ -1,152 +0,0 @@ -# -*- makefile -*- - -CFLAGS_PLATFORM= - -export LC_COLLATE := C -unexport LC_ALL - -# Platform specific options -if COND_sparc64_ieee1275 - LDFLAGS_PLATFORM = -Wl,-melf64_sparc -endif -if COND_arm -if !COND_emu - LDFLAGS_PLATFORM = -Wl,--wrap=__clear_cache -endif -endif -if COND_arm64 - CFLAGS_PLATFORM += -mcmodel=large -endif -if COND_powerpc_ieee1275 - CFLAGS_PLATFORM += -mcpu=powerpc -endif -if COND_HAVE_PCI - CFLAGS_PLATFORM += -DGRUB_HAS_PCI -endif - -# Other options - -CPPFLAGS_DEFAULT = -DGRUB_FILE=\"$(subst $(srcdir)/,,$<)\" -CPPFLAGS_DEFAULT += -I$(builddir) -CPPFLAGS_DEFAULT += -I$(srcdir) -CPPFLAGS_DEFAULT += -I$(top_builddir) -CPPFLAGS_DEFAULT += -I$(top_srcdir) -CPPFLAGS_DEFAULT += -I$(top_srcdir)/include -CPPFLAGS_DEFAULT += -I$(top_builddir)/include -CPPFLAGS_DEFAULT += -I$(top_srcdir)/grub-core/lib/libgcrypt-grub/src/ -CCASFLAGS_DEFAULT = $(CPPFLAGS_DEFAULT) -DASM_FILE=1 -BUILD_CPPFLAGS += $(CPPFLAGS_DEFAULT) - -CFLAGS_KERNEL = $(CFLAGS_PLATFORM) -ffreestanding -LDFLAGS_KERNEL = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -DGRUB_KERNEL=1 -CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) -STRIPFLAGS_KERNEL = -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx -if !COND_emu -if COND_HAVE_ASM_USCORE - LDFLAGS_KERNEL += -Wl,--defsym=_malloc=_grub_malloc -Wl,--defsym=_free=_grub_free -else - LDFLAGS_KERNEL += -Wl,--defsym=malloc=grub_malloc -Wl,--defsym=free=grub_free -endif -endif - -CFLAGS_MODULE = $(CFLAGS_PLATFORM) -ffreestanding -LDFLAGS_MODULE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r -CPPFLAGS_MODULE = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -CCASFLAGS_MODULE = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) - -CFLAGS_IMAGE = $(CFLAGS_PLATFORM) -fno-builtin -LDFLAGS_IMAGE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-S -CPPFLAGS_IMAGE = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -CCASFLAGS_IMAGE = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) - -CFLAGS_PROGRAM = -LDFLAGS_PROGRAM = -CPPFLAGS_PROGRAM = -CCASFLAGS_PROGRAM = - -CFLAGS_LIBRARY = -CPPFLAGS_LIBRARY = -CCASFLAGS_LIBRARY = - -# Other variables - -grubconfdir = $(sysconfdir)/grub.d -platformdir = $(pkglibdir)/$(target_cpu)-$(platform) -starfielddir = $(pkgdatadir)/themes/starfield - -CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion -Wno-error=attributes -CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/lib/gnulib -I$(top_srcdir)/grub-core/lib/gnulib - -CFLAGS_POSIX = -fno-builtin -CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap - -CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers -Wno-redundant-decls -Wno-undef $(CFLAGS_POSIX) -CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap $(CPPFLAGS_POSIX) -D_GCRYPT_IN_LIBGCRYPT=1 -I$(top_srcdir)/include/grub/gcrypt - -CPPFLAGS_EFIEMU = -I$(top_srcdir)/grub-core/efiemu/runtime - -# List file macros for recognizing /interesting/ modules -CPPFLAGS_FS_LIST = -Dgrub_fs_register=FS_LIST_MARKER -CPPFLAGS_VIDEO_LIST= -Dgrub_video_register=VIDEO_LIST_MARKER -CPPFLAGS_PARTMAP_LIST = -Dgrub_partition_map_register=PARTMAP_LIST_MARKER -CPPFLAGS_PARTTOOL_LIST = -Dgrub_parttool_register=PARTTOOL_LIST_MARKER -CPPFLAGS_TERMINAL_LIST = '-Dgrub_term_register_input(...)=INPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)' -CPPFLAGS_TERMINAL_LIST += '-Dgrub_term_register_output(...)=OUTPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)' -CPPFLAGS_COMMAND_LIST = '-Dgrub_register_command(...)=COMMAND_LIST_MARKER(__VA_ARGS__)' -CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_lockdown(...)=COMMAND_LOCKDOWN_LIST_MARKER(__VA_ARGS__)' -CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd(...)=EXTCOMMAND_LIST_MARKER(__VA_ARGS__)' -CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd_lockdown(...)=EXTCOMMAND_LOCKDOWN_LIST_MARKER(__VA_ARGS__)' -CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_p1(...)=P1COMMAND_LIST_MARKER(__VA_ARGS__)' -CPPFLAGS_FDT_LIST := '-Dgrub_fdtbus_register(...)=FDT_DRIVER_LIST_MARKER(__VA_ARGS__)' -CPPFLAGS_MARKER = $(CPPFLAGS_FS_LIST) $(CPPFLAGS_VIDEO_LIST) \ - $(CPPFLAGS_PARTTOOL_LIST) $(CPPFLAGS_PARTMAP_LIST) \ - $(CPPFLAGS_TERMINAL_LIST) $(CPPFLAGS_COMMAND_LIST) \ - $(CPPFLAGS_FDT_LIST) - -# Define these variables to calm down automake - -IMG_FILES = -MOD_FILES = -MODULE_FILES = -MARKER_FILES = -KERNEL_HEADER_FILES = -EXTRA_DEPS = - -bin_SCRIPTS = -bin_PROGRAMS = -check_SCRIPTS_native = -check_SCRIPTS_nonnative = -check_PROGRAMS_native = -check_PROGRAMS_nonnative = -dist_grubconf_DATA = -dist_noinst_DATA = -grubconf_SCRIPTS = -man_MANS = -noinst_DATA = -noinst_SCRIPTS = -noinst_PROGRAMS = -noinst_LIBRARIES = -pkgdata_DATA = -platform_DATA = -platform_SCRIPTS = -platform_PROGRAMS = -sbin_SCRIPTS = -sbin_PROGRAMS = - -EXTRA_DIST = -CLEANFILES = -BUILT_SOURCES = - -# Rules for Automake input - -.PRECIOUS: $(top_srcdir)/Makefile.util.am -$(top_srcdir)/Makefile.util.am: $(top_srcdir)/gentpl.py $(top_srcdir)/Makefile.util.def $(top_srcdir)/Makefile.utilgcry.def - $(PYTHON) $^ > $@.new || (rm -f $@.new; exit 1) - mv $@.new $@ - -.PRECIOUS: $(top_srcdir)/grub-core/Makefile.core.am -$(top_srcdir)/grub-core/Makefile.core.am: $(top_srcdir)/gentpl.py $(top_srcdir)/grub-core/Makefile.core.def $(top_srcdir)/grub-core/Makefile.gcry.def - if [ "x$$GRUB_CONTRIB" != x ]; then echo "You need to run ./bootstrap manually." >&2; exit 1; fi - $(PYTHON) $^ > $@.new || (rm -f $@.new; exit 1) - mv $@.new $@ diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist deleted file mode 100644 index f4e3c5fba..000000000 --- a/conf/Makefile.extra-dist +++ /dev/null @@ -1,159 +0,0 @@ -EXTRA_DIST += autogen.sh -EXTRA_DIST += geninit.sh - -EXTRA_DIST += gentpl.py -EXTRA_DIST += Makefile.util.def -EXTRA_DIST += Makefile.utilgcry.def - -EXTRA_DIST += asm-tests -EXTRA_DIST += unicode - -EXTRA_DIST += util/import_gcry.py -EXTRA_DIST += util/import_unicode.py - -EXTRA_DIST += docs/man -EXTRA_DIST += docs/autoiso.cfg -EXTRA_DIST += docs/grub.cfg -EXTRA_DIST += docs/osdetect.cfg - -EXTRA_DIST += conf/i386-cygwin-img-ld.sc - -EXTRA_DIST += grub-core/Makefile.core.def -EXTRA_DIST += grub-core/Makefile.gcry.def - -EXTRA_DIST += grub-core/genmoddep.awk -EXTRA_DIST += grub-core/genmod.sh.in -EXTRA_DIST += grub-core/gensyminfo.sh.in -EXTRA_DIST += grub-core/gensymlist.sh -EXTRA_DIST += grub-core/genemuinit.sh -EXTRA_DIST += grub-core/genemuinitheader.sh - -EXTRA_DIST += grub-core/lib/gnulib-patches/fix-width.patch -EXTRA_DIST += grub-core/lib/gnulib-patches/fix-regcomp-resource-leak.patch -EXTRA_DIST += grub-core/lib/gnulib-patches/fix-regexec-resource-leak.patch -EXTRA_DIST += grub-core/lib/gnulib-patches/fix-gcc-15-compile.patch -EXTRA_DIST += grub-core/lib/gnulib-patches/fix-unused-value.patch - -EXTRA_DIST += grub-core/lib/libgcrypt -EXTRA_DIST += grub-core/lib/libgcrypt-grub/mpi/generic -EXTRA_DIST += $(shell find $(top_srcdir)/include -name '*.h') -EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib -name '*.h') -EXTRA_DIST += grub-core/efiemu/runtime/config.h -EXTRA_DIST += grub-core/tests/asn1/asn1_test.h -EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/tests/asn1/tests -name '*.h') -EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/commands/tpm2_key_protector -name '*.h') - -EXTRA_DIST += grub-core/lib/LzmaDec.c - -EXTRA_DIST += grub-core/fs/cpio_common.c - -EXTRA_DIST += BUGS -EXTRA_DIST += util/i386/efi/grub-dumpdevtree -EXTRA_DIST += util/spkmodem-recv.c -EXTRA_DIST += util/import_gcrypth.sed -EXTRA_DIST += util/bin2h.c -EXTRA_DIST += util/grub-gen-asciih.c -EXTRA_DIST += util/grub-gen-widthspec.c -EXTRA_DIST += util/grub-module-verifier.c -EXTRA_DIST += util/grub-module-verifier32.c -EXTRA_DIST += util/grub-module-verifier64.c -EXTRA_DIST += util/grub-module-verifierXX.c -EXTRA_DIST += util/grub-pe2elf.c - - -EXTRA_DIST += m4/gnulib-cache.m4 -EXTRA_DIST += m4/glibc2.m4 -EXTRA_DIST += m4/gnulib-tool.m4 -EXTRA_DIST += m4/intdiv0.m4 -EXTRA_DIST += m4/intl.m4 -EXTRA_DIST += m4/intldir.m4 -EXTRA_DIST += m4/intmax.m4 -EXTRA_DIST += m4/inttypes-pri.m4 -EXTRA_DIST += m4/lcmessage.m4 -EXTRA_DIST += m4/lock.m4 -EXTRA_DIST += m4/printf-posix.m4 -EXTRA_DIST += m4/threadlib.m4 -EXTRA_DIST += m4/uintmax_t.m4 -EXTRA_DIST += m4/visibility.m4 -EXTRA_DIST += m4/math_h.m4 - -EXTRA_DIST += grub-core/osdep/apple/hostdisk.c -EXTRA_DIST += grub-core/osdep/aros/hostdisk.c -EXTRA_DIST += grub-core/osdep/basic/hostdisk.c -EXTRA_DIST += grub-core/osdep/bsd/hostdisk.c -EXTRA_DIST += grub-core/osdep/freebsd/hostdisk.c -EXTRA_DIST += grub-core/osdep/hurd/hostdisk.c -EXTRA_DIST += grub-core/osdep/linux/hostdisk.c -EXTRA_DIST += grub-core/osdep/windows/hostdisk.c -EXTRA_DIST += grub-core/osdep/sun/hostdisk.c -EXTRA_DIST += grub-core/osdep/haiku/hostdisk.c - -EXTRA_DIST += grub-core/osdep/basic/init.c -EXTRA_DIST += grub-core/osdep/windows/init.c - -EXTRA_DIST += grub-core/osdep/apple/getroot.c -EXTRA_DIST += grub-core/osdep/aros/getroot.c -EXTRA_DIST += grub-core/osdep/basic/getroot.c -EXTRA_DIST += grub-core/osdep/bsd/getroot.c -EXTRA_DIST += grub-core/osdep/windows/getroot.c -EXTRA_DIST += grub-core/osdep/freebsd/getroot.c -EXTRA_DIST += grub-core/osdep/hurd/getroot.c -EXTRA_DIST += grub-core/osdep/linux/getroot.c -EXTRA_DIST += grub-core/osdep/sun/getroot.c -EXTRA_DIST += grub-core/osdep/haiku/getroot.c - -EXTRA_DIST += grub-core/osdep/basic/random.c -EXTRA_DIST += grub-core/osdep/basic/ofpath.c - -EXTRA_DIST += grub-core/osdep/unix/password.c -EXTRA_DIST += grub-core/osdep/unix/random.c -EXTRA_DIST += grub-core/osdep/unix/sleep.c - -EXTRA_DIST += grub-core/osdep/linux/ofpath.c - -EXTRA_DIST += grub-core/osdep/windows/password.c -EXTRA_DIST += grub-core/osdep/windows/random.c -EXTRA_DIST += grub-core/osdep/windows/sleep.c - -EXTRA_DIST += po/gettext-patches/0001-Support-POTFILES-shell.patch -EXTRA_DIST += po/gettext-patches/0002-Handle-gettext_printf-shell-function.patch -EXTRA_DIST += po/gettext-patches/0003-Make-msgfmt-output-in-little-endian.patch -EXTRA_DIST += po/gettext-patches/0004-Use-SHELL-rather-than-bin-sh.patch - -EXTRA_DIST += po/POTFILES-shell.in -EXTRA_DIST += po/README -EXTRA_DIST += po/Rules-translit -EXTRA_DIST += po/Rules-windowsdir -EXTRA_DIST += po/arabic.sed -EXTRA_DIST += po/cyrillic.sed -EXTRA_DIST += po/greek.sed -EXTRA_DIST += po/grub.d.sed -EXTRA_DIST += po/hebrew.sed - -EXTRA_DIST += tests/dfly-mbr-mbexample.mbr.img.gz -EXTRA_DIST += tests/dfly-mbr-mbexample.dfly.img.gz - -EXTRA_DIST += coreboot.cfg - -EXTRA_DIST += tests/file_filter/file -EXTRA_DIST += tests/file_filter/file.gz -EXTRA_DIST += tests/file_filter/file.gz.sig -EXTRA_DIST += tests/file_filter/file.lzop -EXTRA_DIST += tests/file_filter/file.lzop.sig -EXTRA_DIST += tests/file_filter/file.xz -EXTRA_DIST += tests/file_filter/file.xz.sig -EXTRA_DIST += tests/file_filter/keys -EXTRA_DIST += tests/file_filter/keys.pub -EXTRA_DIST += tests/file_filter/test.cfg -EXTRA_DIST += tests/syslinux/ubuntu10.04/isolinux/prompt.cfg -EXTRA_DIST += tests/syslinux/ubuntu10.04/isolinux/gfxboot.cfg -EXTRA_DIST += tests/syslinux/ubuntu10.04/isolinux/adtxt.cfg -EXTRA_DIST += tests/syslinux/ubuntu10.04/isolinux/isolinux.cfg -EXTRA_DIST += tests/syslinux/ubuntu10.04/isolinux/exithelp.cfg -EXTRA_DIST += tests/syslinux/ubuntu10.04/isolinux/txt.cfg -EXTRA_DIST += tests/syslinux/ubuntu10.04/isolinux/menu.cfg -EXTRA_DIST += tests/syslinux/ubuntu10.04/isolinux/stdmenu.cfg -EXTRA_DIST += tests/syslinux/ubuntu10.04/isolinux/dtmenu.cfg -EXTRA_DIST += tests/syslinux/ubuntu10.04/isolinux/po4a.cfg -EXTRA_DIST += tests/syslinux/ubuntu10.04/isolinux/rqtxt.cfg -EXTRA_DIST += tests/syslinux/ubuntu10.04_grub.cfg.in diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk new file mode 100644 index 000000000..ff0d69c41 --- /dev/null +++ b/conf/any-emu.rmk @@ -0,0 +1,129 @@ +# -*- makefile -*- + +# Used by various components. These rules need to precede them. +script/lexer.c_DEPENDENCIES = grub_script.tab.h + +sbin_UTILITIES += grub-emu +util/grub-emu.c_DEPENDENCIES = grub_emu_init.h +grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ + commands/configfile.c commands/echo.c commands/help.c \ + commands/handler.c commands/ls.c commands/test.c \ + commands/search_wrap.c commands/search_file.c \ + commands/search_label.c commands/search_uuid.c \ + commands/blocklist.c commands/hexdump.c \ + lib/hexdump.c commands/halt.c commands/reboot.c \ + lib/envblk.c commands/loadenv.c \ + commands/gptsync.c commands/probe.c commands/xnu_uuid.c \ + commands/password.c commands/keystatus.c \ + disk/host.c disk/loopback.c disk/scsi.c \ + fs/fshelp.c \ + \ + io/gzio.c \ + kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ + kern/err.c kern/list.c kern/handler.c \ + kern/command.c kern/corecmd.c commands/extcmd.c kern/file.c \ + kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c \ + kern/partition.c kern/term.c \ + kern/rescue_reader.c kern/rescue_parser.c \ + lib/arg.c normal/cmdline.c normal/datetime.c normal/misc.c \ + normal/handler.c normal/auth.c lib/crypto.c normal/autofs.c \ + normal/completion.c normal/main.c normal/color.c \ + normal/menu.c normal/menu_entry.c \ + normal/menu_text.c normal/crypto.c normal/term.c \ + commands/terminal.c normal/context.c lib/charset.c \ + script/main.c script/execute.c script/function.c \ + script/lexer.c script/script.c grub_script.tab.c \ + partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \ + partmap/acorn.c partmap/gpt.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/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 \ + \ + video/video.c video/fb/video_fb.c video/fb/fbblit.c \ + video/fb/fbfill.c video/fb/fbutil.c commands/videotest.c \ + video/bitmap.c video/bitmap_scale.c video/readers/tga.c \ + video/readers/jpeg.c video/readers/png.c font/font_cmd.c \ + font/font.c term/gfxterm.c io/bufio.c \ + \ + 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 trigtables.c \ + \ + util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ + util/hostdisk.c util/getroot.c \ + \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + commands/parttool.c parttool/msdospart.c \ + lib/libgcrypt-grub/cipher/md5.c \ + grub_emu_init.c gnulib/progname.c +grub_emu_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap + + +ifeq ($(target_cpu), i386) +grub_emu_SOURCES += commands/i386/cpuid.c +endif + +grub_emu_LDFLAGS = $(LIBCURSES) + +ifeq ($(enable_grub_emu_usb), yes) +grub_emu_SOURCES += disk/usbms.c util/usb.c bus/usb/usb.c \ + commands/usbtest.c +grub_emu_LDFLAGS += $(LIBCURSES) $(LIBUSB) +endif + +ifeq ($(enable_grub_emu_sdl), yes) +grub_emu_SOURCES += util/sdl.c +grub_emu_LDFLAGS += $(LIBSDL) +endif + +ifeq ($(enable_grub_emu_pci), yes) +grub_emu_SOURCES += util/pci.c commands/lspci.c +grub_emu_LDFLAGS += $(LIBPCIACCESS) +endif + +grub_emu_init.lst: geninit.sh $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) + rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ +DISTCLEANFILES += grub_emu_init.lst + +grub_emu_init.h: grub_emu_init.lst $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) geninitheader.sh + rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@ +DISTCLEANFILES += grub_emu_init.h + +grub_emu_init.c: grub_emu_init.lst $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) geninit.sh grub_emu_init.h + rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@ +DISTCLEANFILES += grub_emu_init.c + + + + +# FIXME: this could be shared with common.rmk + +trigtables.c: gentrigtables + ./gentrigtables > $@ +DISTCLEANFILES += trigtables.c +gentrigtables: gentrigtables.c + $(CC) -o $@ $^ $(CPPFLAGS) -lm +DISTCLEANFILES += gentrigtables + +# 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 + +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 + +bin_UTILITIES += grub-bin2h +grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c diff --git a/conf/common.rmk b/conf/common.rmk new file mode 100644 index 000000000..7effa8af3 --- /dev/null +++ b/conf/common.rmk @@ -0,0 +1,782 @@ +# -*- makefile -*- + +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 \ + kern/device.c kern/disk.c kern/err.c kern/misc.c \ + kern/parser.c kern/partition.c kern/file.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/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/apple.c partmap/sun.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 + +# 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 \ + 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/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/apple.c partmap/sun.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 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 \ + 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 + +# 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 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 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) + +# 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 +sh_mod_CFLAGS = $(COMMON_CFLAGS) +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 += 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) + +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 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 new file mode 100644 index 000000000..9563c0b2b --- /dev/null +++ b/conf/i386-coreboot.rmk @@ -0,0 +1,200 @@ +# -*- makefile -*- + +COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 +COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32 +COMMON_LDFLAGS = -m32 -nostdlib + +# Used by various components. These rules need to precede them. +script/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Images. + +GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 + +ifeq ($(platform), coreboot) + +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_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 \ + machine/boot.h machine/console.h machine/init.h \ + machine/memory.h machine/loader.h list.h handler.h command.h i18n.h \ + env_private.h +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 + +endif + +ifeq ($(platform), qemu) + +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_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 \ + machine/boot.h machine/console.h machine/init.h \ + machine/memory.h machine/loader.h list.h handler.h command.h i18n.h \ + env_private.h +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 +endif + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +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) + +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 play.mod serial.mod \ + memdisk.mod pci.mod lspci.mod reboot.mod \ + halt.mod datetime.mod date.mod datehook.mod \ + lsmmap.mod mmap.mod + +# For boot.mod. +pkglib_MODULES += boot.mod +boot_mod_SOURCES = commands/boot.c +boot_mod_CFLAGS = $(COMMON_CFLAGS) +boot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# 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 reboot.mod. +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For serial.mod. +serial_mod_SOURCES = term/serial.c +serial_mod_CFLAGS = $(COMMON_CFLAGS) +serial_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 play.mod. +play_mod_SOURCES = commands/i386/pc/play.c +play_mod_CFLAGS = $(COMMON_CFLAGS) +play_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pci_mod_SOURCES = bus/pci.c +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_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 date.mod +date_mod_SOURCES = commands/date.c +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_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 new file mode 100644 index 000000000..c03abb429 --- /dev/null +++ b/conf/i386-efi.rmk @@ -0,0 +1,166 @@ +# -*- makefile -*- + +COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 +COMMON_CFLAGS = -fno-builtin -m32 +COMMON_LDFLAGS = -melf_i386 -nostdlib + +# Used by various components. These rules need to precede them. +script/lexer.c_DEPENDENCIES = grub_script.tab.h + +# 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 + +# For grub-setup. +#grub_setup_SOURCES = 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 fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \ +# fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c \ +# fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \ +# kern/fs.c kern/env.c fs/fshelp.c + +# 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 reboot.mod pci.mod lspci.mod \ + datetime.mod date.mod datehook.mod loadbios.mod \ + fixvideo.mod mmap.mod acpi.mod + +# For kernel.img. +kernel_img_RELOCATABLE = yes +kernel_img_SOURCES = kern/i386/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 +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 \ + efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h \ + i18n.h env_private.h +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) + +MOSTLYCLEANFILES += symlist.c +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +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 boot.mod. +pkglib_MODULES += boot.mod +boot_mod_SOURCES = commands/boot.c +boot_mod_CFLAGS = $(COMMON_CFLAGS) +boot_mod_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. +linux_mod_SOURCES = loader/i386/efi/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 reboot.mod. +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pci_mod_SOURCES = bus/pci.c +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_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 date.mod +date_mod_SOURCES = commands/date.c +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_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/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk new file mode 100644 index 000000000..e19f6e9a1 --- /dev/null +++ b/conf/i386-ieee1275.rmk @@ -0,0 +1,145 @@ +# -*- makefile -*- + +COMMON_ASFLAGS = -m32 -nostdinc -fno-builtin +COMMON_CFLAGS = -ffreestanding -mrtd -mregparm=3 +COMMON_LDFLAGS = -nostdlib + +# Used by various components. These rules need to precede them. +script/lexer.c_DEPENDENCIES = grub_script.tab.h + +# 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 = 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 \ + ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h \ + list.h handler.h command.h i18n.h env_private.h +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +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) + +# Scripts. +sbin_SCRIPTS = grub-install + +# For grub-install. +grub_install_SOURCES = util/ieee1275/grub-install.in + +# Modules. +pkglib_MODULES = halt.mod reboot.mod suspend.mod \ + aout.mod serial.mod linux.mod \ + nand.mod memdisk.mod pci.mod lspci.mod datetime.mod \ + date.mod datehook.mod lsmmap.mod mmap.mod + +# For boot.mod. +pkglib_MODULES += boot.mod +boot_mod_SOURCES = commands/boot.c +boot_mod_CFLAGS = $(COMMON_CFLAGS) +boot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# 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 reboot.mod +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For serial.mod. +serial_mod_SOURCES = term/serial.c +serial_mod_CFLAGS = $(COMMON_CFLAGS) +serial_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 memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pci_mod_SOURCES = bus/pci.c +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_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 date.mod +date_mod_SOURCES = commands/date.c +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/i386.mk +include $(srcdir)/conf/common.mk diff --git a/conf/i386-cygwin-img-ld.sc b/conf/i386-pc-cygwin-img-ld.sc similarity index 76% rename from conf/i386-cygwin-img-ld.sc rename to conf/i386-pc-cygwin-img-ld.sc index 578da91b0..a41cac75e 100644 --- a/conf/i386-cygwin-img-ld.sc +++ b/conf/i386-pc-cygwin-img-ld.sc @@ -5,8 +5,6 @@ SECTIONS .text : { start = . ; - _start = . ; - __start = . ; *(.text) etext = . ; } @@ -14,16 +12,18 @@ SECTIONS { __data_start__ = . ; *(.data) - /* Do not discard this section. */ - . = . ; __data_end__ = . ; + } + .rdata : + { __rdata_start__ = . ; *(.rdata) __rdata_end__ = . ; + } + .pdata : + { *(.pdata) edata = . ; - _edata = . ; - __edata = . ; } .bss : { @@ -36,11 +36,7 @@ SECTIONS .edata : { *(.edata) - /* Do not discard this section. */ - . = . ; end = . ; - _end = . ; - __end = . ; } .stab : { diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk new file mode 100644 index 000000000..580bfea0a --- /dev/null +++ b/conf/i386-pc.rmk @@ -0,0 +1,373 @@ +# -*- makefile -*- + +GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 + +COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 +COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32 +COMMON_LDFLAGS = -m32 -nostdlib + +# Used by various components. These rules need to precede them. +script/lexer.c_DEPENDENCIES = grub_script.tab.h + +# 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 = 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 \ + machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \ + machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \ + machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h \ + i18n.h env_private.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 + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +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) + +# 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 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/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/gpt.c \ + \ + disk/raid.c disk/mdraid_linux.c disk/lvm.c \ + util/raid.c util/lvm.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 \ + reboot.mod halt.mod \ + vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod \ + vga.mod memdisk.mod pci.mod lspci.mod \ + aout.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \ + datehook.mod lsmmap.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 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) + +# 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 reboot.mod. +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +halt_mod_SOURCES = commands/i386/pc/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For serial.mod. +serial_mod_SOURCES = term/serial.c +serial_mod_CFLAGS = $(COMMON_CFLAGS) +serial_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 play.mod. +play_mod_SOURCES = commands/i386/pc/play.c +play_mod_CFLAGS = $(COMMON_CFLAGS) +play_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 memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pci_mod_SOURCES = bus/pci.c +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_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 date.mod +date_mod_SOURCES = commands/date.c +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_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 new file mode 100644 index 000000000..573a5d0f3 --- /dev/null +++ b/conf/i386-qemu.rmk @@ -0,0 +1,2 @@ +# -*- makefile -*- +include $(srcdir)/conf/i386-coreboot.mk diff --git a/conf/i386.rmk b/conf/i386.rmk new file mode 100644 index 000000000..d240858fe --- /dev/null +++ b/conf/i386.rmk @@ -0,0 +1,49 @@ +# -*- 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/i386/multiboot.c \ + loader/i386/multiboot_mbi.c \ + loader/multiboot_loader.c +multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) +multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS) + +pkglib_MODULES += multiboot2.mod +multiboot2_mod_SOURCES = loader/i386/multiboot.c \ + loader/i386/multiboot_mbi.c \ + loader/multiboot_loader.c +multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2 +multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS) +multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/conf/mips-qemu-mips.rmk b/conf/mips-qemu-mips.rmk new file mode 100644 index 000000000..e06370122 --- /dev/null +++ b/conf/mips-qemu-mips.rmk @@ -0,0 +1,23 @@ +# -*- 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) -static-libgcc -lgcc \ + -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic +kernel_img_FORMAT = binary diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk new file mode 100644 index 000000000..9977f7881 --- /dev/null +++ b/conf/mips-yeeloong.rmk @@ -0,0 +1,87 @@ +# -*- makefile -*- +LINK_BASE = 0x80200000 +target_machine=yeeloong +COMMON_CFLAGS += -march=mips3 +COMMON_ASFLAGS += -march=mips3 + +kernel_img_HEADERS += 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) -static-libgcc -lgcc \ + -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) + +# 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) + +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 new file mode 100644 index 000000000..536d35cac --- /dev/null +++ b/conf/mips.rmk @@ -0,0 +1,76 @@ + +# -*- makefile -*- + +COMMON_ASFLAGS += -nostdinc +COMMON_CFLAGS += -ffreestanding -mexplicit-relocs -mflush-func=grub_cpu_flush_cache +COMMON_LDFLAGS += -nostdlib + +# Used by various components. These rules need to precede them. +script/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Images. + +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 misc.h mm.h net.h parser.h reader.h \ + symbol.h term.h time.h types.h loader.h partition.h \ + msdos_partition.h machine/kernel.h handler.h list.h \ + command.h machine/memory.h cpu/libgcc.h cpu/cache.h i18n.h env_private.h + +ifeq ($(platform), yeeloong) +kernel_img_HEADERS += pci.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) + +# 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 + +# Modules. +pkglib_MODULES = memdisk.mod \ + lsmmap.mod + +# 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) + +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# 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) + +include $(srcdir)/conf/common.mk diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk new file mode 100644 index 000000000..23bd2d620 --- /dev/null +++ b/conf/powerpc-ieee1275.rmk @@ -0,0 +1,103 @@ + +# -*- makefile -*- + +COMMON_ASFLAGS = -nostdinc -D__ASSEMBLY__ +COMMON_CFLAGS = -ffreestanding +COMMON_LDFLAGS += -nostdlib + +# Used by various components. These rules need to precede them. +script/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Images. + +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 misc.h mm.h net.h parser.h reader.h \ + symbol.h term.h time.h types.h powerpc/libgcc.h loader.h partition.h \ + msdos_partition.h ieee1275/ieee1275.h machine/kernel.h handler.h list.h \ + command.h i18n.h env_private.h + +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) + +# 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) -static-libgcc -lgcc \ + -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 = halt.mod \ + linux.mod \ + reboot.mod \ + suspend.mod \ + memdisk.mod \ + lsmmap.mod + +# 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) + +# For linux.mod. +linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_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 reboot.mod +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/common.mk diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk new file mode 100644 index 000000000..befc7dce5 --- /dev/null +++ b/conf/sparc64-ieee1275.rmk @@ -0,0 +1,136 @@ + +# -*- makefile -*- + +COMMON_ASFLAGS = -nostdinc -m64 +COMMON_CFLAGS = -ffreestanding -m64 -mno-app-regs +COMMON_LDFLAGS = -melf64_sparc -nostdlib -mno-relax + +# Used by various components. These rules need to precede them. +script/lexer.c_DEPENDENCIES = grub_script.tab.h + +# 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 + +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 \ + sparc64/libgcc.h ieee1275/ieee1275.h machine/kernel.h \ + sparc64/ieee1275/ieee1275.h env_private.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,0x200000,-Bstatic,-melf64_sparc -static-libgcc -lgcc +kernel_img_FORMAT = binary + +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) + +# Utilities. +bin_UTILITIES = grub-mkimage +sbin_UTILITIES = grub-setup grub-ofpathname + +# For grub-mkimage. +grub_mkimage_SOURCES = util/sparc64/ieee1275/grub-mkimage.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/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 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/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/sun.c partmap/acorn.c \ + \ + disk/raid.c disk/mdraid_linux.c disk/lvm.c \ + util/raid.c util/lvm.c gnulib/progname.c \ + grub_setup_init.c + +# For grub-ofpathname. +grub_ofpathname_SOURCES = util/sparc64/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 = halt.mod \ + linux.mod \ + reboot.mod \ + memdisk.mod \ + lsmmap.mod + +# 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) + +# For linux.mod. +linux_mod_SOURCES = loader/sparc64/ieee1275/linux.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod. +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/common.mk diff --git a/conf/tests.rmk b/conf/tests.rmk new file mode 100644 index 000000000..18b23ff5a --- /dev/null +++ b/conf/tests.rmk @@ -0,0 +1,50 @@ +# -*- 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 + + +# 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 + +# dependencies between tests and testing-tools +$(SCRIPTED_TESTS): grub-shell grub-shell-tester +$(FUNCTIONAL_TESTS): functional_test.mod + diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk new file mode 100644 index 000000000..d5c3c24cb --- /dev/null +++ b/conf/x86_64-efi.rmk @@ -0,0 +1,166 @@ +# -*- makefile -*- + +COMMON_ASFLAGS = -nostdinc -fno-builtin -m64 +COMMON_CFLAGS = -fno-builtin -m64 +COMMON_LDFLAGS = -melf_x86_64 -nostdlib + +# Used by various components. These rules need to precede them. +script/lexer.c_DEPENDENCIES = grub_script.tab.h + +# 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 + +# For grub-setup. +#grub_setup_SOURCES = 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 fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \ +# fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c \ +# fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \ +# kern/fs.c kern/env.c fs/fshelp.c + +# 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 \ + halt.mod reboot.mod linux.mod pci.mod lspci.mod \ + datetime.mod date.mod datehook.mod loadbios.mod \ + fixvideo.mod mmap.mod acpi.mod + +# For kernel.img. +kernel_img_RELOCATABLE = yes +kernel_img_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.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 \ + 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/millisleep.c kern/generic/rtc_get_time_ms.c \ + term/efi/console.c disk/efi/efidisk.c +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 \ + efi/efi.h efi/time.h efi/disk.h machine/loader.h i386/pit.h list.h \ + handler.h command.h i18n.h env_private.h +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) + +MOSTLYCLEANFILES += symlist.c +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +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 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) + +# 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. +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) + +# For halt.mod. +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod. +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pci_mod_SOURCES = bus/pci.c +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_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 date.mod +date_mod_SOURCES = commands/date.c +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_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/config.h.in b/config.h.in deleted file mode 100644 index 9b1d39971..000000000 --- a/config.h.in +++ /dev/null @@ -1,149 +0,0 @@ -#undef _LARGEFILE_SOURCE -#undef _FILE_OFFSET_BITS -#define _LARGEFILE_SOURCE -#define _FILE_OFFSET_BITS 64 -#if defined(__PPC__) && !defined(__powerpc__) -#define __powerpc__ 1 -#endif - -#define GCRYPT_NO_DEPRECATED 1 -#define HAVE_MEMMOVE 1 - -#if @MM_DEBUG@ -#define MM_DEBUG @MM_DEBUG@ -#endif - -/* Define to 1 to enable disk cache statistics. */ -#define DISK_CACHE_STATS @DISK_CACHE_STATS@ -#define BOOT_TIME_STATS @BOOT_TIME_STATS@ - -/* We don't need those. */ -#define MINILZO_CFG_SKIP_LZO_PTR 1 -#define MINILZO_CFG_SKIP_LZO_UTIL 1 -#define MINILZO_CFG_SKIP_LZO_STRING 1 -#define MINILZO_CFG_SKIP_LZO_INIT 1 -#define MINILZO_CFG_SKIP_LZO1X_1_COMPRESS 1 -#define MINILZO_CFG_SKIP_LZO1X_DECOMPRESS 1 - -#if defined (GRUB_BUILD) -# undef ENABLE_NLS -# define BUILD_SIZEOF_LONG @BUILD_SIZEOF_LONG@ -# define BUILD_SIZEOF_VOID_P @BUILD_SIZEOF_VOID_P@ -# if defined __APPLE__ -# if defined __BIG_ENDIAN__ -# define BUILD_WORDS_BIGENDIAN 1 -# else -# define BUILD_WORDS_BIGENDIAN 0 -# endif -# else /* !defined __APPLE__ */ -# define BUILD_WORDS_BIGENDIAN @BUILD_WORDS_BIGENDIAN@ -# endif /* !defined __APPLE__ */ -#elif defined (GRUB_UTIL) || !defined (GRUB_MACHINE) -# include -#else /* !defined GRUB_UTIL && defined GRUB_MACHINE */ -# define HAVE_FONT_SOURCE @HAVE_FONT_SOURCE@ -/* Define if C symbols get an underscore after compilation. */ -# define HAVE_ASM_USCORE @HAVE_ASM_USCORE@ -/* Define it to one of __bss_start, edata and _edata. */ -# define BSS_START_SYMBOL @BSS_START_SYMBOL@ -/* Define it to either end or _end. */ -# define END_SYMBOL @END_SYMBOL@ -/* Name of package. */ -# define PACKAGE "@PACKAGE@" -/* Version number of package. */ -# define VERSION "@VERSION@" -/* Define to the full name and version of this package. */ -# define PACKAGE_STRING "@PACKAGE_STRING@" -/* Define to the version of this package. */ -# define PACKAGE_VERSION "@PACKAGE_VERSION@" -/* Define to the full name of this package. */ -# define PACKAGE_NAME "@PACKAGE_NAME@" -/* Define to the address where bug reports for this package should be sent. */ -# define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" - -# define GRUB_TARGET_CPU "@GRUB_TARGET_CPU@" -# define GRUB_PLATFORM "@GRUB_PLATFORM@" - -# define GRUB_STACK_PROTECTOR_INIT @GRUB_STACK_PROTECTOR_INIT@ - -# define RE_ENABLE_I18N 1 - -# define _GNU_SOURCE 1 - -# ifndef _GL_INLINE_HEADER_BEGIN -/* - * gnulib gets configured against the host, not the target, and the rest of - * our buildsystem works around that. This is difficult to avoid as gnulib's - * detection requires a more capable system than our target. Instead, we - * reach in and set values appropriately - intentionally setting more than the - * bare minimum. If, when updating gnulib, something breaks, there's probably - * a change needed here or in grub-core/Makefile.core.def. - */ -# define SIZE_MAX ((size_t) -1) -# define _GL_ATTRIBUTE_ALLOC_SIZE(args) \ - __attribute__ ((__alloc_size__ args)) -# define _GL_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__)) -# define _GL_ATTRIBUTE_ARTIFICIAL __attribute__ ((__artificial__)) -# define _GL_ATTRIBUTE_COLD __attribute__ ((cold)) -# define _GL_ATTRIBUTE_CONST __attribute__ ((const)) -# define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute ((__malloc__ (f, i))) -# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (free, 1) -# define _GL_ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__)) -# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__error__ (msg))) -# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE \ - __attribute__ ((externally_visible)) -# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) -# define _GL_ATTRIBUTE_LEAF __attribute__ ((__leaf__)) -# define _GL_ATTRIBUTE_MALLOC __attribute__ ((malloc)) -# define _GL_ATTRIBUTE_MAYBE_UNUSED _GL_ATTRIBUTE_UNUSED -# define _GL_ATTRIBUTE_MAY_ALIAS __attribute__ ((__may_alias__)) -# define _GL_ATTRIBUTE_NODISCARD __attribute__ ((__warn_unused_result__)) -# define _GL_ATTRIBUTE_NOINLINE __attribute__ ((__noinline__)) -# define _GL_ATTRIBUTE_NONNULL(args) __attribute__ ((__nonnull__ args)) -# define _GL_ATTRIBUTE_NONSTRING __attribute__ ((__nonstring__)) -# define _GL_ATTRIBUTE_PACKED __attribute__ ((__packed__)) -# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) -# define _GL_ATTRIBUTE_RETURNS_NONNULL \ - __attribute__ ((__returns_nonnull__)) -# define _GL_ATTRIBUTE_SENTINEL(pos) __attribute__ ((__sentinel__ pos)) -# define _GL_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__warning__ (msg))) -# define _GL_CMP(n1, n2) (((n1) > (n2)) - ((n1) < (n2))) -# define _GL_GNUC_PREREQ GNUC_PREREQ -# define _GL_INLINE inline -# define _GL_UNUSED_LABEL _GL_ATTRIBUTE_UNUSED - -/* We can't use __has_attribute for these because gcc-5.1 is too old for - * that. Everything above is present in that version, though. */ -# if __GNUC__ >= 7 -# define _GL_ATTRIBUTE_FALLTHROUGH __attribute__ ((fallthrough)) -# else -# define _GL_ATTRIBUTE_FALLTHROUGH /* empty */ -# endif - -# ifndef ASM_FILE -typedef __INT_FAST32_TYPE__ int_fast32_t; -typedef __UINT_FAST32_TYPE__ uint_fast32_t; -# endif - -/* Ensure ialloc nests static/non-static inline properly. */ -# define IALLOC_INLINE static inline - -/* - * gnulib uses these for blocking out warnings they can't/won't fix. gnulib - * also makes the decision about whether to provide a declaration for - * reallocarray() at compile-time, so this is a convenient place to override - - * it's used by the ialloc module, which is used by base64. - */ -# define _GL_INLINE_HEADER_BEGIN _Pragma ("GCC diagnostic push") \ - void * \ - reallocarray (void *ptr, unsigned int nmemb, unsigned int size); -# define _GL_INLINE_HEADER_END _Pragma ("GCC diagnostic pop") -# endif /* !_GL_INLINE_HEADER_BEGIN */ - -/* gnulib doesn't build cleanly with older compilers. */ -# if __GNUC__ < 11 -_Pragma ("GCC diagnostic ignored \"-Wtype-limits\"") -# endif - -#endif diff --git a/config.rpath b/config.rpath new file mode 100755 index 000000000..85c2f209b --- /dev/null +++ b/config.rpath @@ -0,0 +1,672 @@ +#! /bin/sh +# Output a system dependent set of variables, describing how to set the +# run time search path of shared libraries in an executable. +# +# Copyright 1996-2008 Free Software Foundation, Inc. +# Taken from GNU libtool, 2001 +# Originally by Gordon Matzigkeit , 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld +# should be set by the caller. +# +# The set of defined variables is at the end of this script. + +# Known limitations: +# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer +# than 256 bytes, otherwise the compiler driver will dump core. The only +# known workaround is to choose shorter directory names for the build +# directory and/or the installation directory. + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +shrext=.so + +host="$1" +host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +# Code taken from libtool.m4's _LT_CC_BASENAME. + +for cc_temp in $CC""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` + +# Code taken from libtool.m4's _LT_COMPILER_PIC. + +wl= +if test "$GCC" = yes; then + wl='-Wl,' +else + case "$host_os" in + aix*) + wl='-Wl,' + ;; + darwin*) + case $cc_basename in + xlc*) + wl='-Wl,' + ;; + esac + ;; + mingw* | cygwin* | pw32* | os2* | cegcc*) + ;; + hpux9* | hpux10* | hpux11*) + wl='-Wl,' + ;; + irix5* | irix6* | nonstopux*) + wl='-Wl,' + ;; + newsos6) + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + ecc*) + wl='-Wl,' + ;; + icc* | ifort*) + wl='-Wl,' + ;; + lf95*) + wl='-Wl,' + ;; + pgcc | pgf77 | pgf90) + wl='-Wl,' + ;; + ccc*) + wl='-Wl,' + ;; + como) + wl='-lopt=' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + wl='-Wl,' + ;; + esac + ;; + esac + ;; + osf3* | osf4* | osf5*) + wl='-Wl,' + ;; + rdos*) + ;; + solaris*) + wl='-Wl,' + ;; + sunos4*) + wl='-Qoption ld ' + ;; + sysv4 | sysv4.2uw2* | sysv4.3*) + wl='-Wl,' + ;; + sysv4*MP*) + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + wl='-Wl,' + ;; + unicos*) + wl='-Wl,' + ;; + uts4*) + ;; + esac +fi + +# Code taken from libtool.m4's _LT_LINKER_SHLIBS. + +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no + +case "$host_os" in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + # Unlike libtool, we use -rpath here, not --rpath, since the documented + # option of GNU ld is called -rpath, not --rpath. + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + case "$host_os" in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + fi + ;; + amigaos*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we cannot use + # them. + ld_shlibs=no + ;; + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + cygwin* | mingw* | pw32* | cegcc*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + interix[3-9]*) + hardcode_direct=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + gnu* | linux* | k*bsd*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + netbsd*) + ;; + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + else + ld_shlibs=no + fi + ;; + esac + ;; + sunos4*) + hardcode_direct=yes + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + esac + if test "$ld_shlibs" = no; then + hardcode_libdir_flag_spec= + fi +else + case "$host_os" in + aix3*) + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + else + aix_use_runtimelinking=no + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + fi + hardcode_direct=yes + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + fi + # Begin _LT_AC_SYS_LIBPATH_AIX. + echo 'int main () { return 0; }' > conftest.c + ${CC} ${LDFLAGS} conftest.c -o conftest + aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + fi + if test -z "$aix_libpath"; then + aix_libpath="/usr/lib:/lib" + fi + rm -f conftest.c conftest + # End _LT_AC_SYS_LIBPATH_AIX. + if test "$aix_use_runtimelinking" = yes; then + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + else + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + fi + fi + ;; + amigaos*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + bsdi[45]*) + ;; + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + libext=lib + ;; + darwin* | rhapsody*) + hardcode_direct=no + if test "$GCC" = yes ; then + : + else + case $cc_basename in + xlc*) + ;; + *) + ld_shlibs=no + ;; + esac + fi + ;; + dgux*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + freebsd1*) + ld_shlibs=no + ;; + freebsd2.2*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + freebsd2*) + hardcode_direct=yes + hardcode_minus_L=yes + ;; + freebsd* | dragonfly*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + hpux9*) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + hpux10*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + hpux11*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + ;; + *) + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + irix5* | irix6* | nonstopux*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + netbsd*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + newsos6) + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + osf3*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + osf4* | osf5*) + if test "$GCC" = yes; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + # Both cc and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + solaris*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + sunos4*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + ;; + sysv4) + case $host_vendor in + sni) + hardcode_direct=yes # is this really true??? + ;; + siemens) + hardcode_direct=no + ;; + motorola) + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + ;; + sysv4.3*) + ;; + sysv4*MP*) + if test -d /usr/nec; then + ld_shlibs=yes + fi + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + ;; + sysv5* | sco3.2v5* | sco5v6*) + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + ;; + uts4*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + *) + ld_shlibs=no + ;; + esac +fi + +# Check dynamic linker characteristics +# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. +# Unlike libtool.m4, here we don't care about _all_ names of the library, but +# only about the one the linker finds when passed -lNAME. This is the last +# element of library_names_spec in libtool.m4, or possibly two of them if the +# linker has special search rules. +library_names_spec= # the last element of library_names_spec in libtool.m4 +libname_spec='lib$name' +case "$host_os" in + aix3*) + library_names_spec='$libname.a' + ;; + aix[4-9]*) + library_names_spec='$libname$shrext' + ;; + amigaos*) + library_names_spec='$libname.a' + ;; + beos*) + library_names_spec='$libname$shrext' + ;; + bsdi[45]*) + library_names_spec='$libname$shrext' + ;; + cygwin* | mingw* | pw32* | cegcc*) + shrext=.dll + library_names_spec='$libname.dll.a $libname.lib' + ;; + darwin* | rhapsody*) + shrext=.dylib + library_names_spec='$libname$shrext' + ;; + dgux*) + library_names_spec='$libname$shrext' + ;; + freebsd1*) + ;; + freebsd* | dragonfly*) + case "$host_os" in + freebsd[123]*) + library_names_spec='$libname$shrext$versuffix' ;; + *) + library_names_spec='$libname$shrext' ;; + esac + ;; + gnu*) + library_names_spec='$libname$shrext' + ;; + hpux9* | hpux10* | hpux11*) + case $host_cpu in + ia64*) + shrext=.so + ;; + hppa*64*) + shrext=.sl + ;; + *) + shrext=.sl + ;; + esac + library_names_spec='$libname$shrext' + ;; + interix[3-9]*) + library_names_spec='$libname$shrext' + ;; + irix5* | irix6* | nonstopux*) + library_names_spec='$libname$shrext' + case "$host_os" in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; + *) libsuff= shlibsuff= ;; + esac + ;; + esac + ;; + linux*oldld* | linux*aout* | linux*coff*) + ;; + linux* | k*bsd*-gnu) + library_names_spec='$libname$shrext' + ;; + knetbsd*-gnu) + library_names_spec='$libname$shrext' + ;; + netbsd*) + library_names_spec='$libname$shrext' + ;; + newsos6) + library_names_spec='$libname$shrext' + ;; + nto-qnx*) + library_names_spec='$libname$shrext' + ;; + openbsd*) + library_names_spec='$libname$shrext$versuffix' + ;; + os2*) + libname_spec='$name' + shrext=.dll + library_names_spec='$libname.a' + ;; + osf3* | osf4* | osf5*) + library_names_spec='$libname$shrext' + ;; + rdos*) + ;; + solaris*) + library_names_spec='$libname$shrext' + ;; + sunos4*) + library_names_spec='$libname$shrext$versuffix' + ;; + sysv4 | sysv4.3*) + library_names_spec='$libname$shrext' + ;; + sysv4*MP*) + library_names_spec='$libname$shrext' + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + library_names_spec='$libname$shrext' + ;; + uts4*) + library_names_spec='$libname$shrext' + ;; +esac + +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` +shlibext=`echo "$shrext" | sed -e 's,^\.,,'` +escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` + +LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <]) - ;; -esac - -case "$host_os" in - cygwin | windows* | mingw32* | aros*) - ;; - *) - AC_CHECK_SIZEOF(off_t) - if test x"$ac_cv_sizeof_off_t" != x8 ; then - AC_CHECK_SIZEOF(off64_t) - test x"$ac_cv_sizeof_off64_t" = x8 || AC_MSG_ERROR([Large file support is required]) - fi;; -esac - -if test x$USE_NLS = xno; then - HOST_CFLAGS="$HOST_CFLAGS -fno-builtin-gettext" +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 @@ -428,108 +214,15 @@ else AC_PATH_PROG(HELP2MAN, help2man) fi -# Check for functions and headers. -AC_CHECK_FUNCS(posix_memalign memalign getextmntent atexit) -AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/mnttab.h limits.h) +# Check for functions. +AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf) -# glibc 2.25 still includes sys/sysmacros.h in sys/types.h but emits deprecation -# warning which causes compilation failure later with -Werror. So use -Werror here -# as well to force proper sys/sysmacros.h detection. Used in include/grub/osdep/major.h. -SAVED_CFLAGS="$CFLAGS" -CFLAGS="$HOST_CFLAGS -Werror" +# For grub-mkisofs AC_HEADER_MAJOR -CFLAGS="$SAVED_CFLAGS" - -AC_CHECK_MEMBERS([struct statfs.f_fstypename],,,[$ac_includes_default -#include -#include ]) - -AC_CHECK_MEMBERS([struct statfs.f_mntfromname],,,[$ac_includes_default -#include -#include ]) - -# 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]) - -AC_CACHE_CHECK([whether -Wtrampolines work], [grub_cv_host_cc_wtrampolines], [ - SAVED_CFLAGS="$CFLAGS" - CFLAGS="$HOST_CFLAGS -Wtrampolines -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include -int va_arg_func (int fixed, va_list args);]], [[]])], - [grub_cv_host_cc_wtrampolines=yes], - [grub_cv_host_cc_wtrampolines=no]) - CFLAGS="$SAVED_CFLAGS" -]) - -if test x"$grub_host_cv_cc_wtrampolines" = xyes ; then - HOST_CFLAGS="$HOST_CFLAGS -Wtrampolines" -fi - -# -# Check for host and build compilers. -# -HOST_CC=$CC -AC_CHECK_PROGS(BUILD_CC, [gcc egcs cc]) -test -z "$BUILD_CC" && AC_MSG_ERROR([none of gcc, egcs and cc is found. set BUILD_CC manually.]) -BUILD_CPP="$BUILD_CC -E" - -case "$build_os" in - haiku*) BUILD_LIBM= ;; - *) BUILD_LIBM=-lm ;; -esac - -dnl FIXME proper test seems to require too deep dive into Autoconf internals. -dnl For now just list known platforms that we support. - -case "$build_os" in - cygwin*|mingw32*|mingw64*) BUILD_EXEEXT=.exe ;; - *) BUILD_EXEEXT= ;; -esac -AC_SUBST(BUILD_EXEEXT) - -# In some build environments like termux /bin/sh is not a valid -# shebang. Use $SHELL instead if it's executable and /bin/sh isn't -BUILD_SHEBANG=/bin/sh -for she in /bin/sh "$SHELL"; do - if test -x "$she" ; then - BUILD_SHEBANG="$she" - fi -done -AC_SUBST(BUILD_SHEBANG) - -# For gnulib. -gl_INIT - -WARN_FLAGS="-Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes" -EXTRA_WARN_FLAGS="-Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign -Wmissing-include-dirs -Wmissing-prototypes -Wmissing-declarations -Wformat=2" - -HOST_CFLAGS="$HOST_CFLAGS $WARN_FLAGS -Wcast-align" - -AC_CACHE_CHECK([which extra warnings work], [grub_cv_cc_w_extra_flags], [ - SAVED_CFLAGS="$CFLAGS" - grub_cv_cc_w_extra_flags= - for x in $EXTRA_WARN_FLAGS; do - CFLAGS="$HOST_CFLAGS $x -Werror" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [flag=1], [flag=0]) - if test x$flag = x1 ; then - grub_cv_cc_w_extra_flags="$grub_cv_cc_w_extra_flags $x" - fi - done - CFLAGS="$SAVED_CFLAGS" -]) - -HOST_CFLAGS="$HOST_CFLAGS $grub_cv_cc_w_extra_flags" +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) # # Check for target programs. @@ -542,32 +235,21 @@ if test "x$target_alias" != x && test "x$host_alias" != "x$target_alias"; then 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(TARGET_OBJCOPY, objcopy) - AC_CHECK_TOOL(TARGET_STRIP, strip) - AC_CHECK_TOOL(TARGET_NM, nm) - AC_CHECK_TOOL(TARGET_RANLIB, ranlib) + 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(TARGET_OBJCOPY, objcopy) - AC_CHECK_TOOL(TARGET_STRIP, strip) - AC_CHECK_TOOL(TARGET_NM, nm) - AC_CHECK_TOOL(TARGET_RANLIB, ranlib) + 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(BUILD_CFLAGS) -AC_SUBST(BUILD_CPPFLAGS) -AC_SUBST(BUILD_LDFLAGS) AC_SUBST(TARGET_CC) -AC_SUBST(TARGET_NM) -AC_SUBST(TARGET_RANLIB) -AC_SUBST(TARGET_STRIP) -AC_SUBST(TARGET_OBJCOPY) + # Test the C compiler for the target environment. tmp_CC="$CC" @@ -581,493 +263,28 @@ CPPFLAGS="$TARGET_CPPFLAGS" LDFLAGS="$TARGET_LDFLAGS" LIBS="" -if test "x$target_m32" = x1; then - # Force 32-bit mode. - TARGET_CFLAGS="$TARGET_CFLAGS -m32" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m32" - TARGET_CPPFLAGS="$TARGET_CPPFLAGS -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_CPPFLAGS="$TARGET_CPPFLAGS -m64" - TARGET_LDFLAGS="$TARGET_LDFLAGS -m64" - TARGET_MODULE_FORMAT="elf64" -fi - # debug flags. -TARGET_CFLAGS="$TARGET_CFLAGS $WARN_FLAGS -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations" -TARGET_CCASFLAGS="$TARGET_CCASFLAGS -g" - -if test "x$target_cpu" != xi386 && test "x$target_cpu" != xx86_64; then -TARGET_CFLAGS="$TARGET_CFLAGS -Wcast-align" -fi - -TARGET_CC_VERSION="$(LC_ALL=C $TARGET_CC --version | head -n1)" - -AC_CACHE_CHECK([which extra warnings work], [grub_cv_target_cc_w_extra_flags], [ - LDFLAGS="$TARGET_LDFLAGS -nostdlib -static" - - grub_cv_target_cc_w_extra_flags= - for x in $EXTRA_WARN_FLAGS; do - CFLAGS="$TARGET_CFLAGS $x -Werror" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -asm (".globl start; start:"); -void __main (void); -void __main (void) {} -int main (void); -]], [[]])], [flag=1], [flag=0]) - if test x$flag = x1 ; then - grub_cv_target_cc_w_extra_flags="$grub_cv_target_cc_w_extra_flags $x" - fi - done -]) - -TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_w_extra_flags" - -AC_CACHE_CHECK([if compiling with clang], [grub_cv_cc_target_clang], -[ -CFLAGS="$TARGET_CFLAGS" -AC_COMPILE_IFELSE( -[AC_LANG_PROGRAM([], [[ -#ifdef __clang__ -#error "is clang" -#endif -]])], -[grub_cv_cc_target_clang=no], [grub_cv_cc_target_clang=yes])]) - -if test x$target_cpu = xpowerpc -o x$target_cpu = xmips; then - AC_CACHE_CHECK([for options to get big-endian compilation], grub_cv_target_cc_big_endian, [ - grub_cv_target_cc_big_endian=no - for cand in "-target $target_cpu -Wl,-EB" "-target $target_cpu" \ - "-target $target_cpu-linux-gnu -Wl,-EB" "-target $target_cpu-linux-gnu" \ - "-EB" "-mbig-endian"; do - if test x"$grub_cv_target_cc_big_endian" != xno ; then - break - fi - CFLAGS="$TARGET_CFLAGS $cand -Werror" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__ORDER_BIG_ENDIAN__ != __BYTE_ORDER__) -#error still little endian -#endif -asm (".globl start; start:"); -asm (".globl _start; _start:"); -asm (".globl __start; __start:"); -void __main (void); -void __main (void) {} -int main (void); -]], [[]])], - [grub_cv_target_cc_big_endian="$cand"], []) - done - ]) - - if test x"$grub_cv_target_cc_big_endian" = xno ; then - AC_MSG_ERROR([could not force big-endian]) - fi - - skip_linkflags="$(echo "$grub_cv_target_cc_big_endian"|sed 's@-Wl,-EB@@')" - - TARGET_CFLAGS="$TARGET_CFLAGS $skip_linkflags" - TARGET_CPPFLAGS="$TARGET_CPPFLAGS $skip_linkflags" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS $skip_linkflags" - TARGET_LDFLAGS="$TARGET_LDFLAGS $grub_cv_target_cc_big_endian" -elif test x$target_cpu = xmipsel; then - AC_CACHE_CHECK([for options to get little-endian compilation], grub_cv_target_cc_little_endian, [ - grub_cv_target_cc_little_endian=no - for cand in "-target $target_cpu -Wl,-EL" "-target $target_cpu" \ - "-target $target_cpu-linux-gnu -Wl,-EL" "-target $target_cpu-linux-gnu" \ - "-EL"; do - if test x"$grub_cv_target_cc_little_endian" != xno ; then - break - fi - CFLAGS="$TARGET_CFLAGS $cand -Werror" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__ORDER_BIG_ENDIAN__ == __BYTE_ORDER__) -#error still big endian -#endif -asm (".globl start; start:"); -asm (".globl _start; _start:"); -asm (".globl __start; __start:"); -void __main (void); -void __main (void) {} -int main (void); -]], [[]])], - [grub_cv_target_cc_little_endian="$cand"], []) - done - ]) - - if test x"$grub_cv_target_cc_little_endian" = xno ; then - AC_MSG_ERROR([could not force little-endian]) - fi - - skip_linkflags="$(echo "$grub_cv_target_cc_little_endian"|sed 's@-Wl,-EL@@')" - - TARGET_CFLAGS="$TARGET_CFLAGS $skip_linkflags" - TARGET_CPPFLAGS="$TARGET_CPPFLAGS $skip_linkflags" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS $skip_linkflags" - TARGET_LDFLAGS="$TARGET_LDFLAGS $grub_cv_target_cc_little_endian" -fi - -# GRUB code is N32-compliant but it's experimental and we would prefer to -# avoid having too much variety when it doesn't result in any real improvement. -# Moreover N64 isn't supported. -if test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ; then - AC_CACHE_CHECK([for options to force MIPS o32 ABI], grub_cv_target_cc_mips_o32_abi, [ - grub_cv_target_cc_mips_o32_abi=no - for arg in "" "-mabi=32" "-target $target_cpu -mabi=32" ; do - if test x"$grub_cv_target_cc_mips_o32_abi" != xno ; then - break - fi - CFLAGS="$TARGET_CFLAGS $arg -Werror" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -#if !defined(_ABIO32) || !defined(_MIPS_SIM) || (_MIPS_SIM != _ABIO32) -#error not o32 ABI -#endif -asm (".globl start; start:"); -asm (".globl _start; _start:"); -asm (".globl __start; __start:"); -void __main (void); -void __main (void) {} -int main (void); -]], [[]])], - [grub_cv_target_cc_mips_o32_abi="$arg"], []) - done - ]) - - if test x"$grub_cv_target_cc_mips_o32_abi" = xno ; then - AC_MSG_ERROR([could not force MIPS o32 ABI]) - fi - - TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mips_o32_abi" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_mips_o32_abi" -fi - -AC_CACHE_CHECK([for options to compile assembly], [grub_cv_cc_target_asm_compile], [ -test_program= -case "x$target_cpu-$platform" in - xmips-* | xmipsel-*) - test_program=mips - ;; - xi386-pc) - test_program=i386-pc - ;; - xi386-* | xx86_64-*) - test_program=i386 - ;; - xpowerpc-* | xsparc64-* | xarm-*) - test_program=$target_cpu - ;; -esac -if test x"$test_program" = x ; then - grub_cv_cc_target_asm_compile= -else - found=no - for arg in "" "-no-integrated-as"; do - cmdline="$TARGET_CC -c -o /dev/null $TARGET_CCASFLAGS $arg $TARGET_CPPFLAGS $srcdir/asm-tests/$test_program.S" - echo "Running $cmdline" >&AS_MESSAGE_LOG_FD - if $cmdline >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then - grub_cv_cc_target_asm_compile="$arg" - found=yes - break - fi - done - if test x"$found" = xno ; then - AC_MSG_ERROR([could not compile assembly]) - fi -fi -]) - -TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_cc_target_asm_compile" - -if test "x$target_cpu" = xi386 && test "x$platform" != xemu; then - TARGET_CFLAGS="$TARGET_CFLAGS -march=i386" -fi - -if test "x$grub_cv_cc_target_clang" = xno && test "x$target_cpu" = xi386 && test "x$platform" != xemu && test "x$platform" != xefi; then - TARGET_CFLAGS="$TARGET_CFLAGS -mrtd -mregparm=3" -fi - -# on mips redirect cache flushing function to non-existant one. -if test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ; then - AC_CACHE_CHECK([whether -mflush-func=grub_red_herring works], [grub_cv_cc_mflush_func], [ - CFLAGS="$TARGET_CFLAGS -mflush-func=grub_red_herring -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_mflush_func=yes], - [grub_cv_cc_mflush_func=no]) - ]) - - if test "x$grub_cv_cc_mflush_func" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -mflush-func=grub_red_herring" - fi - - AC_CACHE_CHECK([whether -mno-gpopt works], [grub_cv_cc_mno_gpopt], [ - CFLAGS="$TARGET_CFLAGS -mno-gpopt -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_mno_gpopt=yes], - [grub_cv_cc_mno_gpopt=no]) - ]) - - if test "x$grub_cv_cc_mno_gpopt" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -mno-gpopt" - fi -fi - +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 - TARGET_CFLAGS="$TARGET_CFLAGS -falign-functions=1" - AC_CACHE_CHECK([whether -falign-loops works], [grub_cv_cc_falign_loop], [ - CFLAGS="$TARGET_CFLAGS -falign-loops=1 -Werror" + 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-loops=1" + 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 - AC_CACHE_CHECK([whether -falign-jumps works], [grub_cv_cc_falign_jumps], [ - CFLAGS="$TARGET_CFLAGS -falign-jumps=1 -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_falign_jumps=yes], - [grub_cv_cc_falign_jumps=no]) - ]) - - if test "x$grub_cv_cc_falign_jumps" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -falign-jumps=1" - fi -fi - -AC_CACHE_CHECK([whether -freg-struct-return works], [grub_cv_cc_freg_struct_return], [ - CFLAGS="$TARGET_CFLAGS -freg-struct-return -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_freg_struct_return=yes], - [grub_cv_cc_freg_struct_return=no]) -]) - -if test "x$grub_cv_cc_freg_struct_return" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -freg-struct-return" -fi - -if ( test "x$target_cpu" = xi386 || test "x$target_cpu" = xx86_64 ) && test "x$platform" != xemu; then # 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-sse3 -mno-3dnow" -fi - -if ( test "x$target_cpu" = xi386 || test "x$target_cpu" = xx86_64 ); then - AC_CACHE_CHECK([whether -Wa,-mx86-used-note works], [grub_cv_cc_mx86_used_note], [ - CFLAGS="$TARGET_CFLAGS -Wa,-mx86-used-note=no -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_mx86_used_note=yes], - [grub_cv_cc_mx86_used_note=no]) - ]) - - if test "x$grub_cv_cc_mx86_used_note" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -Wa,-mx86-used-note=no" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS -Wa,-mx86-used-note=no" - fi -fi - -if test "x$target_cpu" = xloongarch64; then - AC_CACHE_CHECK([whether _mno_explicit_relocs works], [grub_cv_cc_mno_explicit_relocs], [ - CFLAGS="$TARGET_CFLAGS -mno-explicit-relocs -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_mno_explicit_relocs=yes], - [grub_cv_cc_mno_explicit_relocs=no]) - ]) - if test "x$grub_cv_cc_mno_explicit_relocs" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -mno-explicit-relocs -fno-plt" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS -mno-explicit-relocs -fno-plt" - fi - - AC_CACHE_CHECK([for no-relax options], grub_cv_target_cc_mno_relax, [ - grub_cv_target_cc_mno_relax=no - for cand in "-mno-relax" "-Wa,-mno-relax"; do - if test x"$grub_cv_target_cc_mno_relax" != xno ; then - break - fi - CFLAGS="$TARGET_CFLAGS $cand -Werror" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - asm (".globl start; start:"); - void __main (void); - void __main (void) {} - int main (void); - ]], [[]])], [grub_cv_target_cc_mno_relax="$cand"], []) - done - ]) - CFLAGS="$TARGET_CFLAGS" - - if test x"$grub_cv_target_cc_mno_relax" != xno ; then - TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mno_relax" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_mno_relax" - fi - - TARGET_CFLAGS="$TARGET_CFLAGS -Wa,-mla-global-with-abs" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS -Wa,-mla-global-with-abs" -fi - -if test "x$target_cpu" = xriscv64 || test "x$target_cpu" = xriscv32; then - AC_CACHE_CHECK([for no-relax options], grub_cv_target_cc_mno_relax, [ - grub_cv_target_cc_mno_relax=no - for cand in "-mno-relax" "-Wa,-mno-relax"; do - if test x"$grub_cv_target_cc_mno_relax" != xno ; then - break - fi - CFLAGS="$TARGET_CFLAGS $cand -Werror" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - asm (".globl start; start:"); - void __main (void); - void __main (void) {} - int main (void); - ]], [[]])], [grub_cv_target_cc_mno_relax="$cand"], []) - done - ]) - - CFLAGS="$TARGET_CFLAGS" - - if test x"$grub_cv_target_cc_mno_relax" != xno ; then - TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mno_relax" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_mno_relax" - fi -fi - -# GRUB doesn't use float or doubles at all. Yet some toolchains may decide -# that floats are a good fit to run instead of what's written in the code. -# Given that floating point unit is disabled (if present to begin with) -# when GRUB is running which may result in various hard crashes. -if test x"$platform" != xemu ; then - AC_CACHE_CHECK([for options to get soft-float], grub_cv_target_cc_soft_float, [ - grub_cv_target_cc_soft_float=no - if test "x$target_cpu" = xarm64; then - CFLAGS="$TARGET_CFLAGS -mgeneral-regs-only -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_target_cc_soft_float="-mgeneral-regs-only"], []) - fi - if test "x$target_cpu" = xriscv32; then - CFLAGS="$TARGET_CFLAGS -march=rv32imac -mabi=ilp32 -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_target_cc_soft_float="-march=rv32imac -mabi=ilp32"], []) - # ISA spec version 20191213 factored out extensions Zicsr and Zifencei - CFLAGS="$TARGET_CFLAGS -march=rv32imac_zicsr_zifencei -mabi=ilp32 -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_target_cc_soft_float="-march=rv32imac_zicsr_zifencei -mabi=ilp32"], []) - fi - if test "x$target_cpu" = xriscv64; then - CFLAGS="$TARGET_CFLAGS -march=rv64imac -mabi=lp64 -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_target_cc_soft_float="-march=rv64imac -mabi=lp64"], []) - # ISA spec version 20191213 factored out extensions Zicsr and Zifencei - CFLAGS="$TARGET_CFLAGS -march=rv64imac_zicsr_zifencei -mabi=lp64 -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_target_cc_soft_float="-march=rv64imac_zicsr_zifencei -mabi=lp64"], []) - fi - if test "x$target_cpu" = xia64; then - CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_target_cc_soft_float="-mno-inline-float-divide -mno-inline-sqrt"], []) - fi - if test "x$target_cpu" = xsh4; then - CFLAGS="$TARGET_CFLAGS -m4-nofpu -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_target_cc_soft_float="-m4-nofpu"], []) - fi - for cand in "-msoft-float -Xclang -msoft-float -Xclang -no-implicit-float" \ - "-Xclang -msoft-float -Xclang -no-implicit-float" \ - "-Xclang -msoft-float" "-msoft-float"; do - if test x"$grub_cv_target_cc_soft_float" != xno ; then - break - fi - CFLAGS="$TARGET_CFLAGS $cand -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_target_cc_soft_float="$cand"], []) - done - ]) - - if test x"$grub_cv_target_cc_soft_float" = xno ; then - AC_MSG_ERROR([could not force soft-float]) - fi - - case x"$grub_cv_target_cc_soft_float" in - x*"-Xclang"*) - # A trick so that clang doesn't see it on link stаge - TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_soft_float" - ;; - *) - TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_soft_float" - ;; - esac - TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_soft_float" - -fi - -if test x"$target_cpu" = xsparc64 ; then - AC_CACHE_CHECK([for options to reserve application registers], grub_cv_target_cc_mno_app_regs, [ - grub_cv_target_cc_mno_app_regs=no - for cand in "-mllvm -sparc-reserve-app-registers" \ - "-mno-app-regs"; do - if test x"$grub_cv_target_cc_mno_app_regs" != xno ; then - break - fi - CFLAGS="$TARGET_CFLAGS $cand -Werror" - CPPFLAGS="$TARGET_CPPFLAGS" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_target_cc_mno_app_regs="$cand"], []) - done - ]) - - if test x"$grub_cv_target_cc_mno_app_regs" = xno ; then - AC_MSG_ERROR([could not reserve application registers]) - fi - if test x"$grub_cv_target_cc_mno_app_regs" = x"-mllvm -sparc-reserve-app-registers" ; then - # A trick so that clang doesn't see it on link stаge - TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_mno_app_regs" - else - TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mno_app_regs" - fi - - AC_CACHE_CHECK([for no-relax options], grub_cv_target_cc_mno_relax, [ - grub_cv_target_cc_mno_relax=no - for cand in "-mno-relax" "-Wl,--no-relax"; do - if test x"$grub_cv_target_cc_mno_relax" != xno ; then - break - fi - LDFLAGS="$TARGET_LDFLAGS $cand -nostdlib -static" - CFLAGS="$TARGET_CFLAGS -Werror" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - asm (".globl start; start:"); - void __main (void); - void __main (void) {} - int main (void); - ]], [[]])], [grub_cv_target_cc_mno_relax="$cand"], []) - done - ]) - LDFLAGS="$TARGET_LDFLAGS" - CFLAGS="$TARGET_CFLAGS" - - if test x"$grub_cv_target_cc_mno_relax" = xno ; then - AC_MSG_ERROR([could not find no-relax options]) - fi - TARGET_LDFLAGS="$TARGET_LDFLAGS $grub_cv_target_cc_mno_relax" -fi - -# The backtrace module relies on frame pointers and the default optimization -# level, -Os, omits them. Make sure they are enabled. -AC_CACHE_CHECK([whether -fno-omit-frame-pointer works], [grub_cv_cc_fno_omit_frame_pointer], [ - CFLAGS="$TARGET_CFLAGS -fno-omit-frame-pointer" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_fno_omit_frame_pointer=yes], - [grub_cv_cc_fno_omit_frame_pointer=no]) -]) - -if test "x$grub_cv_cc_fno_omit_frame_pointer" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -fno-omit-frame-pointer" + TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-3dnow" fi # By default, GCC 4.4 generates .eh_frame sections containing unwind @@ -1075,262 +292,98 @@ fi # 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], [ - CFLAGS="$TARGET_CFLAGS -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 -if test x"$target_os" = xcygwin; then - AC_CACHE_CHECK([whether option -fno-reorder-functions works], grub_cv_cc_no_reorder_functions, [ - CFLAGS="$TARGET_CFLAGS -fno-reorder-functions" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_no_reorder_functions=yes], - [grub_cv_cc_no_reorder_functions=no]) - ]) -fi - -if test x"$target_os" = xcygwin && test "x$grub_cv_cc_no_reorder_functions" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -fno-reorder-functions" -fi - -AC_CACHE_CHECK([whether -mno-stack-arg-probe works], [grub_cv_cc_mno_stack_arg_probe], [ - CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_mno_stack_arg_probe=yes], - [grub_cv_cc_mno_stack_arg_probe=no]) -]) - -if test "x$grub_cv_cc_mno_stack_arg_probe" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe" -fi - - -# By default, GCC 4.6 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-asynchronous-unwind-tables works], [grub_cv_cc_fno_asynchronous_unwind_tables], [ - CFLAGS="$TARGET_CFLAGS -fno-asynchronous-unwind-tables" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_fno_asynchronous_unwind_tables=yes], - [grub_cv_cc_fno_asynchronous_unwind_tables=no]) -]) - -if test "x$grub_cv_cc_fno_asynchronous_unwind_tables" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -fno-asynchronous-unwind-tables" -fi - -AC_CACHE_CHECK([whether -fno-unwind-tables works], [grub_cv_cc_fno_unwind_tables], [ - CFLAGS="$TARGET_CFLAGS -fno-unwind-tables" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_fno_unwind_tables=yes], - [grub_cv_cc_fno_unwind_tables=no]) -]) - -if test "x$grub_cv_cc_fno_unwind_tables" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -fno-unwind-tables" -fi - -# Do not generate .ident sections. -AC_CACHE_CHECK([whether -fno-ident works], [grub_cv_cc_fno_ident], [ - CFLAGS="$TARGET_CFLAGS -fno-ident" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_fno_ident=yes], - [grub_cv_cc_fno_ident=no]) -]) - -if test "x$grub_cv_cc_fno_ident" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -fno-ident" -fi - -CFLAGS="$TARGET_CFLAGS" - - -if test x"$platform" = xemu ; then - TARGET_OBJ2ELF= - grub_cv_target_cc_link_format= - case "$host_os" in - *darwin* | *mac*) - grub_cv_target_cc_link_format="-arch,${target_cpu}" - TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,$grub_cv_target_cc_link_format" - ;; - *windows* | *cygwin* | *mingw*) - if test x${target_cpu} = xi386 ; then - grub_cv_target_cc_link_format=-mi386pe - TARGET_OBJ2ELF='./build-grub-pe2elf$(BUILD_EXEEXT)' - fi - if test x${target_cpu} = xx86_64 ; then - grub_cv_target_cc_link_format=-mi386pep - TARGET_OBJ2ELF='./build-grub-pep2elf$(BUILD_EXEEXT)' - fi - TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,$grub_cv_target_cc_link_format" - ;; - esac -elif test x"$target_cpu" = xi386 || test x"$target_cpu" = xx86_64; then - AC_CACHE_CHECK([for target linking format], [grub_cv_target_cc_link_format], [ - grub_cv_target_cc_link_format=unknown - for format in -melf_${target_cpu} -melf_${target_cpu}_fbsd -melf_${target_cpu}_obsd -melf_${target_cpu}_haiku -mi386pe -mi386pep -arch,${target_cpu}; do - if test x${target_cpu} != xi386 && test x$format = x-mi386pe; then - continue - fi - if test x${target_cpu} != xx86_64 && test x$format = x-mi386pep; then - continue - fi - CFLAGS="$TARGET_CFLAGS" - LDFLAGS="$TARGET_LDFLAGS -Wl,$format -nostdlib -static" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - asm (".globl start; start:"); - asm (".globl _start; _start:"); - asm (".globl __start; __start:"); - void __main (void); - void __main (void) {} - ]], [[]])], [flag=1], [flag=0]) - if test x"$flag" = x1; then - grub_cv_target_cc_link_format="$format" - break - fi - done]) - if test x"$grub_cv_target_cc_link_format" = xunknown; then - AC_MSG_ERROR([no suitable link format found]) +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 - TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,$grub_cv_target_cc_link_format" - if test x"$grub_cv_target_cc_link_format" = x-mi386pe ; then - TARGET_OBJ2ELF='./build-grub-pe2elf$(BUILD_EXEEXT)' + if test "x$OBJCONV" = x ; then + AC_MSG_ERROR([objconv not found which is required when building with apple compiler]) fi - if test x"$grub_cv_target_cc_link_format" = x-mi386pep ; then - TARGET_OBJ2ELF='./build-grub-pep2elf$(BUILD_EXEEXT)' - fi -fi - -if test x$grub_cv_target_cc_link_format = x-arch,i386 || test x$grub_cv_target_cc_link_format = x-arch,x86_64; then - TARGET_APPLE_LINKER=1 - AC_CHECK_PROG([TARGET_OBJCONV], [objconv], [objconv], []) - if test "x$TARGET_OBJCONV" = x ; then - AC_CHECK_PROG([TARGET_OBJCONV], [objconv], [./objconv], [], [.]) - fi - if test "x$TARGET_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' - TARGET_IMG_LDFLAGS_AC='-nostdlib -static -Wl,-preload -Wl,-segalign,20' - TARGET_IMG_BASE_LDOPT="-Wl,-image_base" - TARGET_LDFLAGS_OLDMAGIC="" -elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_cc_link_format = x-mi386pep ; then - TARGET_APPLE_LINKER=0 - TARGET_LDFLAGS_OLDMAGIC="-Wl,-N" - TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-cygwin-img-ld.sc" - TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}" - TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/i386-cygwin-img-ld.sc" - TARGET_IMG_BASE_LDOPT="-Wl,-Ttext" - TARGET_IMG_CFLAGS= -else - TARGET_APPLE_LINKER=0 - TARGET_LDFLAGS_OLDMAGIC="-Wl,-N" TARGET_IMG_LDSCRIPT= - TARGET_IMG_LDFLAGS='-Wl,-N' - TARGET_IMG_LDFLAGS_AC='-Wl,-N' - TARGET_IMG_BASE_LDOPT="-Wl,-Ttext" - TARGET_IMG_CFLAGS= -fi - -CFLAGS="$TARGET_CFLAGS" - -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"$grub_cv_target_cc_link_format" = x-mi386pe || test x"$grub_cv_target_cc_link_format" = x-mi386pep ; then - efiemu_excuse="not available on cygwin" -fi -if test x"$target_cpu" != xi386 ; then - efiemu_excuse="only available on i386" -fi -if test x"$platform" = xefi ; then - efiemu_excuse="not available on efi" -fi - -if test x"$efiemu_excuse" = x ; then - AC_CACHE_CHECK([whether options required for efiemu work], grub_cv_cc_efiemu, [ - CFLAGS="-m64 -nostdlib -O2 -mcmodel=large -mno-red-zone" - 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"$efiemu_excuse" = x ; then - AC_CACHE_CHECK([for efiemu64 linking format], [grub_cv_target_cc_efiemu64_link_format], [ - grub_cv_target_cc_efiemu64_link_format=unknown - for format in -melf_x86_64 -melf_x86_64_fbsd -melf_x86_64_obsd -melf_x86_64_haiku -arch,x86_64; do - CFLAGS="-m64 -nostdlib -O2 -mcmodel=large -mno-red-zone" - LDFLAGS="-m64 -Wl,$format -nostdlib -static" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - asm (".globl start; start:"); - asm (".globl _start; _start:"); - asm (".globl __start; __start:"); - void __main (void); - void __main (void) {} - ]], [[]])], [flag=1], [flag=0]) - if test x"$flag" = x1; then - grub_cv_target_cc_efiemu64_link_format="$format" - break - fi - done]) - if test x"$grub_cv_target_cc_efiemu64_link_format" = xunknown; then - efiemu_excuse="no suitable link format for efiemu64 found" - else - EFIEMU64_LINK_FORMAT="-Wl,$grub_cv_target_cc_efiemu64_link_format" - 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 ($efiemu_excuse)]) -fi -if test x"$efiemu_excuse" = x ; then -enable_efiemu=yes + 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 -enable_efiemu=no + 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" +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([enable_efiemu]) -AC_SUBST([EFIEMU64_LINK_FORMAT]) -CFLAGS="$TARGET_CFLAGS" +AC_SUBST(TARGET_IMG_LDSCRIPT) +AC_SUBST(TARGET_IMG_LDFLAGS) +AC_SUBST(TARGET_IMG_CFLAGS) -AC_SUBST(TARGET_LDFLAGS_OLDMAGIC) +# 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' ;; + *) ;; +esac +AC_SUBST(TARGET_OBJ2ELF) +AC_MSG_RESULT([$TARGET_OBJ2ELF]) -LDFLAGS="$TARGET_LDFLAGS" +if test "x$target_m32" = x1; then + # Force 32-bit mode. + TARGET_CFLAGS="$TARGET_CFLAGS -m32" + TARGET_LDFLAGS="$TARGET_LDFLAGS -m32" + TARGET_MODULE_FORMAT="elf32" +fi -if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64 ; then +if test "x$target_m64" = x1; then + # Force 64-bit mode. + TARGET_CFLAGS="$TARGET_CFLAGS -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, [ - CFLAGS="$TARGET_CFLAGS -mcmodel=large" + 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" = xyes; then + if test "x$grub_cv_cc_mcmodel" = xno; then + CFLAGS="$SAVED_CFLAGS -m64 -DMCMODEL_SMALL=1" + TARGET_CFLAGS="$TARGET_CFLAGS -DMCMODEL_SMALL=1" + AC_MSG_WARN([-mcmodel=large not supported. You won't be able to use the memory over 4GiB. Upgrade your gcc]) + else TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large" - elif test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64; then - TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=medany" fi -fi -if test "$target_cpu"-"$platform" = x86_64-efi; then # 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="$TARGET_CFLAGS -mno-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]) @@ -1342,165 +395,28 @@ if test "$target_cpu"-"$platform" = x86_64-efi; then TARGET_CFLAGS="$TARGET_CFLAGS -mno-red-zone" fi -if test "x$target_cpu" = xarm; then - AC_CACHE_CHECK([for options to disable movt and movw], grub_cv_target_cc_mno_movt, [ - grub_cv_target_cc_mno_movt=no - for cand in "-mno-movt" \ - "-mllvm -arm-use-movt=0" \ - "-mword-relocations"; do - if test x"$grub_cv_target_cc_mno_movt" != xno ; then - break - fi - CFLAGS="$TARGET_CFLAGS $cand -Werror" - CPPFLAGS="$TARGET_CPPFLAGS" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_target_cc_mno_movt="$cand"], []) - done - ]) - - if test x"$grub_cv_target_cc_mno_movt" != xno ; then - # A trick so that clang doesn't see it on link stage - TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_mno_movt" - fi - AC_CACHE_CHECK([whether option -mthumb-interwork works], grub_cv_cc_mthumb_interwork, [ - CFLAGS="$TARGET_CFLAGS -mthumb-interwork -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_cc_mthumb_interwork=yes], - [grub_cv_cc_mthumb_interwork=no]) - ]) - if test "x$grub_cv_cc_mthumb_interwork" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -mthumb-interwork" - # Clang defaults to thumb interworking - elif test "x$grub_cv_cc_target_clang" = xno ; then - AC_MSG_ERROR([your compiler doesn't support -mthumb-interwork]) - fi -fi - -AC_CACHE_CHECK([whether option -Qn works], grub_cv_target_cc_qn, [ - CFLAGS="$TARGET_CFLAGS -Qn -Qunused-arguments -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], - [grub_cv_target_cc_qn=yes], - [grub_cv_target_cc_qn=no])]) -if test "x$grub_cv_target_cc_qn" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -Qn -Qunused-arguments" -fi - # # Compiler features. # -CFLAGS="$TARGET_CFLAGS" +# Need __enable_execute_stack() for nested function trampolines? +grub_CHECK_ENABLE_EXECUTE_STACK # Position independent executable. grub_CHECK_PIE -grub_CHECK_NO_PIE -grub_CHECK_NO_PIE_ONEWORD -grub_CHECK_LINK_PIE [# Need that, because some distributions ship compilers that include -# `-fPIE' or '-fpie' and '-pie' in the default specs. +# `-fPIE' in the default specs. if [ x"$pie_possible" = xyes ]; then - TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE -fno-pie" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS -fno-PIE -fno-pie" -fi - -if [ x"$link_nopie_needed" = xyes ] || [ x"$pie_possible" = xyes ]; then - if [ x"$nopie_possible" = xyes ]; then - TARGET_LDFLAGS="$TARGET_LDFLAGS -no-pie" - fi - if [ x"$nopie_oneword_possible" = xyes ]; then - TARGET_LDFLAGS="$TARGET_LDFLAGS -nopie" - fi + TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE" fi] -CFLAGS="$TARGET_CFLAGS" -LDFLAGS="$TARGET_LDFLAGS" - -# Position independent executable. -grub_CHECK_PIC -[# On most platforms we don't want PIC as it only makes relocations harder -# and code less efficient. On mips we want to have one got table per module -# and reload $gp in every function. -# GCC implements it using symbol __gnu_local_gp in non-PIC as well. -# However with clang we need PIC for this reloading to happen. -# With arm64 we need relocations that are in some way representable in -# PE as we need to support arm64-efi. Without -fPIC clang generates -# movk's which aren't representable. -# Since default varies across dictributions use either -fPIC or -fno-PIC -# explicitly. -if ( test x$target_cpu = xmips || test x$target_cpu = xmipsel || test x$target_cpu = xarm64 ) && test "x$grub_cv_cc_target_clang" = xyes ; then - TARGET_CFLAGS="$TARGET_CFLAGS -fPIC" -elif [ x"$pic_possible" = xyes ]; then - TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIC" -fi] - -CFLAGS="$TARGET_CFLAGS" - -# Stack smashing protector. +# Smashing stack protector. grub_CHECK_STACK_PROTECTOR -AC_ARG_ENABLE([stack-protector], - AS_HELP_STRING([--enable-stack-protector], - [enable the stack protector]), - [], - [enable_stack_protector=no]) -if test "x$enable_stack_protector" = xno; then - if test "x$ssp_possible" = xyes; then - # Need that, because some distributions ship compilers that include - # `-fstack-protector' in the default specs. - TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector" - fi -elif test "x$platform" != xefi; then - if test "$ERROR_PLATFORM_NOT_SUPPORT_SSP" = "yes"; then - AC_MSG_ERROR([--enable-stack-protector is only supported on EFI platforms]) - else - AC_MSG_WARN([--enable-stack-protector is only supported on EFI platforms]) - fi - enable_stack_protector=no -elif test "x$ssp_global_possible" != xyes; then - AC_MSG_ERROR([--enable-stack-protector is not supported (compiler doesn't support -mstack-protector-guard=global)]) -else - TARGET_CFLAGS="$TARGET_CFLAGS -mstack-protector-guard=global" - if test "x$enable_stack_protector" = xyes; then - if test "x$ssp_possible" != xyes; then - AC_MSG_ERROR([--enable-stack-protector is not supported (compiler doesn't support -fstack-protector)]) - fi - TARGET_CFLAGS="$TARGET_CFLAGS -fstack-protector" - elif test "x$enable_stack_protector" = xstrong; then - if test "x$ssp_strong_possible" != xyes; then - AC_MSG_ERROR([--enable-stack-protector=strong is not supported (compiler doesn't support -fstack-protector-strong)]) - fi - TARGET_CFLAGS="$TARGET_CFLAGS -fstack-protector-strong" - else - # Note, -fstack-protector-all requires that the protector is disabled for - # functions that appear in the call stack when the canary is initialized. - AC_MSG_ERROR([invalid value $enable_stack_protector for --enable-stack-protector]) - fi - TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DGRUB_STACK_PROTECTOR=1" - - if test -n "$SOURCE_DATE_EPOCH"; then - GRUB_STACK_PROTECTOR_INIT="0x00f2b7e2$(printf "%x" "$SOURCE_DATE_EPOCH" | sed 's/.*\(........\)$/\1/')" - elif test -r /dev/urandom; then - # Generate the 8 byte stack protector canary at build time if /dev/urandom - # is able to be read. The first byte should be NUL to filter out string - # buffer overflow attacks. - GRUB_STACK_PROTECTOR_INIT="$($PYTHON -c 'import codecs; rf=open("/dev/urandom", "rb"); print("0x00"+codecs.encode(rf.read(7), "hex").decode("ascii"))')" - else - # Some hosts may not have a urandom, e.g. Windows, so use statically - # generated random bytes - GRUB_STACK_PROTECTOR_INIT="0x00f2b7e2f193b25c" - fi - - if test x"$target_m32" = x1 ; then - # Make sure that the canary default value is 24-bits by only using the - # lower 3 bytes on 32 bit systems. This allows the upper byte to be NUL - # to filter out string buffer overflow attacks. - GRUB_STACK_PROTECTOR_INIT="0x00$(echo "$GRUB_STACK_PROTECTOR_INIT" | sed 's/.*\(......\)$/\1/')" - fi - - AC_SUBST([GRUB_STACK_PROTECTOR_INIT]) +# 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 - -CFLAGS="$TARGET_CFLAGS" - grub_CHECK_STACK_ARG_PROBE # Cygwin's GCC uses alloca() to probe the stackframe on static # stack allocations above some threshold. @@ -1508,108 +424,111 @@ if test x"$sap_possible" = xyes; then TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe" fi -CFLAGS="$TARGET_CFLAGS" - -# -mno-unaligned-access -mstrict-align -if test "$target_cpu" = arm; then - AC_CACHE_CHECK([for compile options to get strict alignment], [grub_cv_target_cc_strict_align], [ - grub_cv_target_cc_strict_align= - for arg in -mno-unaligned-access "-Xclang -mstrict-align" -mstrict-align; do - CFLAGS="$TARGET_CFLAGS $arg -Werror" - LDFLAGS="$TARGET_LDFLAGS" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [flag=1], [flag=0]) - if test x"$flag" = x1; then - grub_cv_target_cc_strict_align="$arg" - break - fi - done]) - - TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_strict_align" - if test x"$grub_cv_target_cc_strict_align" = x"-Xclang -mstrict-align"; then - TARGET_LDFLAGS="$TARGET_LDFLAGS -Qunused-arguments" - fi - AC_CACHE_CHECK([if compiler generates unaligned accesses], [grub_cv_cc_target_emits_unaligned], - [CFLAGS="$TARGET_CFLAGS" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ -#ifdef __ARM_FEATURE_UNALIGNED -#error "unaligned" -#endif - ]])], - [grub_cv_cc_target_emits_unaligned=no], [grub_cv_cc_target_emits_unaligned=yes])]) - if test x$grub_cv_cc_target_emits_unaligned = xyes; then - AC_MSG_ERROR([compiler generates unaligned accesses]) - 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 -Wl,--defsym,abort=main -Wno-error" +fi CPPFLAGS="$TARGET_CPPFLAGS" +LDFLAGS="$TARGET_LDFLAGS" +LIBS=-lgcc # Check for libgcc symbols -if test x"$platform" = xemu; then -CFLAGS="$TARGET_CFLAGS -Wno-error" -AC_CHECK_FUNCS(__udivsi3 __umodsi3 __divsi3 __modsi3 __divdi3 __moddi3 __udivdi3 __umoddi3 __ctzdi2 __ctzsi2 __clzdi2 __aeabi_uidiv __aeabi_uidivmod __aeabi_idiv __aeabi_idivmod __aeabi_ulcmp __muldi3 __aeabi_lmul __aeabi_memcpy __aeabi_memcpy4 __aeabi_memcpy8 __aeabi_memclr __aeabi_memclr4 __aeabi_memclr8 __aeabi_memset __aeabi_lasr __aeabi_llsl __aeabi_llsr _restgpr_14_x __ucmpdi2 __ashldi3 __ashrdi3 __lshrdi3 __bswapsi2 __bswapdi2 __bzero __register_frame_info __deregister_frame_info ___chkstk_ms __chkstk_ms) -fi +AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x) -if test "x$TARGET_APPLE_LINKER" = x1 ; then -CFLAGS="$TARGET_CFLAGS -nostdlib -static" -else +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 acinclude.m4. -grub_ASM_USCORE +# Defined in aclocal.m4. grub_PROG_TARGET_CC -if test "x$TARGET_APPLE_LINKER" != x1 ; then +if test "x$TARGET_APPLE_CC" != x1 ; then grub_PROG_OBJCOPY_ABSOLUTE fi grub_PROG_LD_BUILD_ID_NONE +grub_ASM_USCORE if test "x$target_cpu" = xi386; then - if test "$platform" != emu && test "x$TARGET_APPLE_LINKER" != x1 ; then - if test ! -z "$TARGET_IMG_LDSCRIPT"; then - # Check symbols provided by linker script. - CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC} ${TARGET_IMG_BASE_LDOPT},0x8000" - fi + if test ! -z "$TARGET_IMG_LDSCRIPT"; then + # Check symbols provided by linker script. + CFLAGS="$TARGET_CFLAGS -nostdlib $TARGET_IMG_LDFLAGS_AC -Wl,-Ttext,8000,--defsym,___main=0x8100" + fi + if test "x$TARGET_APPLE_CC" != x1 ; then 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 -grub_PROG_NM_WORKS -grub_PROG_NM_MINUS_P -grub_PROG_NM_DEFINED_ONLY -AC_SUBST(TARGET_NMFLAGS_MINUS_P) -AC_SUBST(TARGET_NMFLAGS_DEFINED_ONLY) +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 -nostdlib -nostdinc -isystem `$TARGET_CC -print-file-name=include`" + CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -isystem `$TARGET_CC -print-file-name=include`" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include -#include 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 - -AC_CACHE_CHECK([whether -Wtrampolines work], [grub_cv_cc_wtrampolines], [ - CFLAGS="$TARGET_CFLAGS -Wtrampolines -Werror" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include -int va_arg_func (int fixed, va_list args);]], [[]])], - [grub_cv_cc_wtrampolines=yes], - [grub_cv_cc_wtrampolines=no]) -]) - -if test x"$grub_cv_cc_wtrampolines" = xyes ; then - TARGET_CFLAGS="$TARGET_CFLAGS -Wtrampolines" +if test x"$grub_cv_cc_isystem" = xyes ; then + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -isystem `$TARGET_CC -print-file-name=include`" fi # Restore the flags. @@ -1626,40 +545,13 @@ LIBS="$tmp_LIBS" # Memory manager debugging. AC_ARG_ENABLE([mm-debug], AS_HELP_STRING([--enable-mm-debug], - [include memory manager debugging])) -if test x$enable_mm_debug = xyes; then - MM_DEBUG=1 -else - MM_DEBUG=0 -fi -AC_SUBST([MM_DEBUG]) -AM_CONDITIONAL([COND_MM_DEBUG], [test x$MM_DEBUG = x1]) + [include memory manager debugging]), + [AC_DEFINE([MM_DEBUG], [1], + [Define to 1 if you enable memory manager debugging.])]) -AC_ARG_ENABLE([cache-stats], - AS_HELP_STRING([--enable-cache-stats], - [enable disk cache statistics collection])) - -if test x$enable_cache_stats = xyes; then - DISK_CACHE_STATS=1 -else - DISK_CACHE_STATS=0 -fi -AC_SUBST([DISK_CACHE_STATS]) - -AC_ARG_ENABLE([boot-time], - AS_HELP_STRING([--enable-boot-time], - [enable boot time statistics collection])) - -if test x$enable_boot_time = xyes; then - BOOT_TIME_STATS=1 -else - BOOT_TIME_STATS=0 -fi -AC_SUBST([BOOT_TIME_STATS]) - -AC_ARG_ENABLE([grub-emu-sdl2], - [AS_HELP_STRING([--enable-grub-emu-sdl2], - [build and install the `grub-emu' debugging utility with SDL2 support (default=guessed)])]) +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], @@ -1670,88 +562,121 @@ AC_ARG_ENABLE([grub-emu-pci], [build and install the `grub-emu' debugging utility with PCI support (potentially dangerous) (default=no)])]) if test "$platform" = emu; then - if test x"$enable_grub_emu_sdl2" = xno ; then - grub_emu_sdl2_excuse="explicitly disabled" - fi - [if [ x"$grub_emu_sdl2_excuse" = x ]; then - # Check for libSDL libraries.] - PKG_CHECK_MODULES([SDL2], [sdl2], [ - AC_DEFINE([HAVE_SDL2], [1], [Define to 1 if you have SDL2 library.]) - AC_SUBST(HAVE_SDL2)], - [grub_emu_sdl2_excuse="libSDL2 libraries are required to build \`grub-emu' with SDL2 support"]) - [fi] - if test x"$enable_grub_emu_sdl2" = xyes && test x"$grub_emu_sdl2_excuse" != x ; then - AC_MSG_ERROR([SDL2 support for grub-emu was explicitly requested but can't be compiled ($grub_emu_sdl2_excuse)]) - fi - if test x"$grub_emu_sdl2_excuse" = x ; then - enable_grub_emu_sdl2=yes - else - enable_grub_emu_sdl2=no - fi - if test x"$enable_grub_emu_sdl2" = xyes ; then - grub_emu_sdl_excuse="disabled by sdl2" - fi + 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_sdl" = xno ; then - grub_emu_sdl_excuse="explicitly disabled" - fi - [if [ x"$grub_emu_sdl_excuse" = x ]; then +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] +[fi] - [if [ x"$grub_emu_sdl_excuse" = x ]; then +[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] +[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 explicitly requested but can't be compiled ($grub_emu_sdl_excuse)]) - 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_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_pci" != xyes ; then + grub_emu_pci_excuse="not enabled" +fi - [if [ x"$grub_emu_pci_excuse" = x ]; then - # Check for libpci libraries.] - AC_CHECK_LIB([pciaccess], [pci_system_init], [LIBPCIACCESS="-lpciaccess"], +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 +[fi] +[if [ x"$grub_emu_pci_excuse" = x ]; then # Check for headers.] - AC_CHECK_HEADERS([pciaccess.h], [], + 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_sdl2]) - AC_SUBST([enable_grub_emu_sdl]) - AC_SUBST([enable_grub_emu_pci]) +[fi] +if test x"$grub_emu_pci_excuse" = x ; then +enable_grub_emu_pci=yes else - # Ignore --enable-emu-* if platform is not emu - enable_grub_emu_sdl2=no - enable_grub_emu_sdl=no - enable_grub_emu_pci=no +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)])]) @@ -1759,559 +684,67 @@ if test x"$enable_grub_mkfont" = xno ; then grub_mkfont_excuse="explicitly disabled" fi -unset ac_cv_header_ft2build_h +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. - PKG_CHECK_MODULES([FREETYPE], [freetype2], [ - SAVED_CPPFLAGS="$CPPFLAGS" - SAVED_LIBS="$LIBS" - CPPFLAGS="$CPPFLAGS $FREETYPE_CFLAGS" - LIBS="$LIBS $FREETYPE_LIBS" - AC_CHECK_HEADERS([ft2build.h], [], - [grub_mkfont_excuse=["need freetype2 headers"]]) - AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [], - [grub_mkfont_excuse=["freetype2 library unusable"]]) - CPPFLAGS="$SAVED_CPPFLAGS" - LIBS="$SAVED_LIBS" - ], [grub_mkfont_excuse=["need freetype2 library"]]) - if test x"$grub_mkfont_excuse" = x && test x"$host_kernel" = xnetbsd ; then - FREETYPE_LIBS="$FREETYPE_LIBS -Wl,-R,/usr/pkg/lib" ; - fi + 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 ($grub_mkfont_excuse)]) + 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 +enable_grub_mkfont=yes else - enable_grub_mkfont=no +enable_grub_mkfont=no fi AC_SUBST([enable_grub_mkfont]) +AC_SUBST([freetype_cflags]) +AC_SUBST([freetype_libs]) -SAVED_CC="$CC" -SAVED_CPP="$CPP" -SAVED_CFLAGS="$CFLAGS" -SAVED_CPPFLAGS="$CPPFLAGS" -SAVED_LDFLAGS="$LDFLAGS" -CC="$BUILD_CC" -CPP="$BUILD_CPP" -CFLAGS="$BUILD_CFLAGS" -CPPFLAGS="$BUILD_CPPFLAGS" -LDFLAGS="$BUILD_LDFLAGS" - -unset ac_cv_c_bigendian -unset ac_cv_header_ft2build_h - -AC_COMPUTE_INT([BUILD_SIZEOF_VOID_P], [sizeof (void *)]) -AC_COMPUTE_INT([BUILD_SIZEOF_LONG], [sizeof (long)]) -AC_C_BIGENDIAN([BUILD_WORDS_BIGENDIAN=1], [BUILD_WORDS_BIGENDIAN=0], [BUILD_WORDS_BIGENDIAN=err], [BUILD_WORDS_BIGENDIAN=err]) - -if test x$BUILD_WORDS_BIGENDIAN = xerr ; then - AC_MSG_ERROR([couldnt determine build endianness]) -fi - -AC_SUBST([BUILD_SIZEOF_LONG]) -AC_SUBST([BUILD_SIZEOF_VOID_P]) -AC_SUBST([BUILD_WORDS_BIGENDIAN]) - -if test x"$grub_build_mkfont_excuse" = x ; then - # Check for freetype libraries. - SAVED_PKG_CONFIG="$PKG_CONFIG" - test -z "$BUILD_PKG_CONFIG" || PKG_CONFIG="$BUILD_PKG_CONFIG" - PKG_CHECK_MODULES([BUILD_FREETYPE], [freetype2], [ - SAVED_CPPFLAGS_2="$CPPFLAGS" - SAVED_LIBS="$LIBS" - CPPFLAGS="$CPPFLAGS $BUILD_FREETYPE_CFLAGS" - LIBS="$LIBS $BUILD_FREETYPE_LIBS" - AC_CHECK_HEADERS([ft2build.h], [], - [grub_build_mkfont_excuse=["need freetype2 headers"]]) - AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [], - [grub_build_mkfont_excuse=["freetype2 library unusable"]]) - LIBS="$SAVED_LIBS" - CPPFLAGS="$SAVED_CPPFLAGS_2" - ], [grub_build_mkfont_excuse=["need freetype2 library"]]) - if test x"$grub_build_mkfont_excuse" = x ; then - case x"$build_os" in - xnetbsd*) BUILD_FREETYPE_LIBS="$BUILD_FREETYPE_LIBS -Wl,-R,/usr/pkg/lib" ;; - esac - fi - PKG_CONFIG="$SAVED_PKG_CONFIG" -fi - -if test x"$enable_build_grub_mkfont" = xyes && test x"$grub_build_mkfont_excuse" != x ; then - AC_MSG_ERROR([build-grub-mkfont was explicitly requested but can't be compiled ($grub_build_mkfont_excuse)]) -fi -if test x"$grub_build_mkfont_excuse" = x ; then - enable_build_grub_mkfont=yes -else - enable_build_grub_mkfont=no -fi -if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then - if test x"$grub_build_mkfont_excuse" = x ; then - AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont]) - else - AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont ($grub_build_mkfont_excuse)]) - fi -fi - -CC="$SAVED_CC" -CPP="$SAVED_CPP" -CFLAGS="$SAVED_CFLAGS" -CPPFLAGS="$SAVED_CPPFLAGS" -LDFLAGS="$SAVED_LDFLAGS" - - -starfield_excuse= - -AC_ARG_ENABLE([grub-themes], - [AS_HELP_STRING([--enable-grub-themes], - [build and install GRUB themes (default=guessed)])]) -if test x"$enable_grub_themes" = xno ; then - starfield_excuse="explicitly disabled" -fi - -if test x"$starfield_excuse" = x && test x"$enable_build_grub_mkfont" = xno ; then - starfield_excuse="No build-time grub-mkfont" -fi - -AC_ARG_WITH([dejavufont], - AS_HELP_STRING([--with-dejavufont=FILE], - [set the DejeVu source [[guessed]]])) - -if test "x$with_dejavufont" = x; then - # search in well-known directories - if test x"$starfield_excuse" = x; then - for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do - for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/truetype/ttf-dejavu /usr/share/fonts/dejavu /usr/share/fonts/truetype /usr/pkg/share/fonts/X11/TTF /usr/local/share/fonts/dejavu /usr/X11R6/lib/X11/fonts/TTF /usr/share/fonts/dejavu-sans-fonts /usr/share/fonts/truetype/dejavu; do - if test -f "$dir/DejaVuSans.$ext"; then - DJVU_FONT_SOURCE="$dir/DejaVuSans.$ext" - break 2 - fi - done - done - - if test "x$DJVU_FONT_SOURCE" = x; then - starfield_excuse="No DejaVu found" - fi - fi -else - DJVU_FONT_SOURCE="$with_dejavufont" -fi - -if test x"$enable_grub_themes" = xyes && test x"$starfield_excuse" != x; then - AC_MSG_ERROR([themes were explicitly requested but requirements are not satisfied ($starfield_excuse)]) -fi - -AC_SUBST([DJVU_FONT_SOURCE]) - -AC_ARG_WITH([unifont], - AS_HELP_STRING([--with-unifont=FILE], - [set the unifont source [[guessed]]])) - -if test "x$with_unifont" = x; then - # search in well-known directories - for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz otf otf.gz; do - for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont /usr/share/fonts/uni /usr/share/fonts/truetype/unifont /usr/share/fonts/misc /usr/pkg/share/fonts/X11/misc /usr/local/share/fonts/gnu-unifont /usr/local/share/fonts/unifont; do - if test -f "$dir/unifont.$ext"; then - md5="$(md5sum "$dir/unifont.$ext"|awk '{ print $1; }')" - # PCF and BDF from version 6.3 isn't hanled properly by libfreetype. - if test "$md5" = 0a54834d2788c83886a3e1785a6a1e61 || test "$md5" = 28f2565c7a41d8d407e2551159385edb || test "$md5" = dae5e588461b3b92b87b6ffee734f936 || test "$md5" = 4a3d687aa5bb329ed05f4263a1016791 ; then - continue - fi - FONT_SOURCE="$dir/unifont.$ext" - break 2 - fi - done - done -else - FONT_SOURCE="$with_unifont" -fi - -if test x"$enable_build_grub_mkfont" = xno ; then - FONT_SOURCE= -fi - -if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then - if test x"$grub_build_mkfont_excuse" = x ; then - AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont]) - else - AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont ($grub_build_mkfont_excuse)]) - fi -fi - -AC_SUBST([FONT_SOURCE]) - -if test x"$FONT_SOURCE" = x && test x"$DJVU_FONT_SOURCE" = x && test x"$grub_build_mkfont_excuse" = x; then - grub_build_mkfont_excuse="no fonts" -fi - - -AC_ARG_ENABLE([grub-mount], - [AS_HELP_STRING([--enable-grub-mount], - [build and install the `grub-mount' utility (default=guessed)])]) -if test x"$enable_grub_mount" = xno ; then - grub_mount_excuse="explicitly disabled" -fi - -if test x"$grub_mount_excuse" = x ; then - PKG_CHECK_MODULES([FUSE], [fuse3], [FUSE_CFLAGS="$FUSE_CFLAGS -DFUSE_USE_VERSION=32"], [ - PKG_CHECK_MODULES([FUSE], [fuse], [FUSE_CFLAGS="$FUSE_CFLAGS -DFUSE_USE_VERSION=26"], [ - grub_mount_excuse="need fuse or fuse3 libraries" - ]) - ]) -fi - -if test x"$enable_grub_mount" = xyes && test x"$grub_mount_excuse" != x ; then - AC_MSG_ERROR([grub-mount was explicitly requested but can't be compiled ($grub_mount_excuse)]) -fi -if test x"$grub_mount_excuse" = x ; then -enable_grub_mount=yes -else -enable_grub_mount=no -fi -AC_SUBST([enable_grub_mount]) - -AC_ARG_ENABLE([device-mapper], - [AS_HELP_STRING([--enable-device-mapper], - [enable Linux device-mapper support (default=guessed)])]) -if test x"$enable_device_mapper" = xno ; then - device_mapper_excuse="explicitly disabled" -fi - -if test x"$device_mapper_excuse" = x ; then - # Check for device-mapper header. - AC_CHECK_HEADER([libdevmapper.h], [], - [device_mapper_excuse="need libdevmapper header"]) -fi - -if test x"$device_mapper_excuse" = x ; then - # Check for device-mapper library. - AC_CHECK_LIB([devmapper], [dm_task_create], [], - [device_mapper_excuse="need devmapper library"]) -fi - -if test x"$device_mapper_excuse" = x ; then - # Check for device-mapper library. - AC_CHECK_LIB([devmapper], [dm_log_with_errno_init], - [], - [device_mapper_excuse="need devmapper library"]) -fi - -if test x"$device_mapper_excuse" = x ; then - LIBDEVMAPPER="-ldevmapper" - AC_DEFINE([HAVE_DEVICE_MAPPER], [1], - [Define to 1 if you have the devmapper library.]) -fi - -AC_SUBST([LIBDEVMAPPER]) - -LIBGEOM= -if test x$host_kernel = xkfreebsd; then - AC_CHECK_LIB([geom], [geom_gettree], [], - [AC_MSG_ERROR([Your platform requires libgeom])]) - LIBGEOM="-lgeom" -fi - -AC_SUBST([LIBGEOM]) - -AC_ARG_ENABLE([liblzma], - [AS_HELP_STRING([--enable-liblzma], - [enable liblzma integration (default=guessed)])]) -if test x"$enable_liblzma" = xno ; then - liblzma_excuse="explicitly disabled" -fi - -if test x"$liblzma_excuse" = x ; then -AC_CHECK_LIB([lzma], [lzma_code], - [],[liblzma_excuse="need lzma library"]) -fi -if test x"$liblzma_excuse" = x ; then -AC_CHECK_HEADER([lzma.h], [], [liblzma_excuse="need lzma header"]) -fi - -if test x"$enable_liblzma" = xyes && test x"$liblzma_excuse" != x ; then - AC_MSG_ERROR([liblzma support was explicitly requested but requirements are not satisfied ($liblzma_excuse)]) -fi - - -if test x"$liblzma_excuse" = x ; then - LIBLZMA="-llzma" - AC_DEFINE([USE_LIBLZMA], [1], - [Define to 1 if you have the LZMA library.]) -fi - -AC_SUBST([LIBLZMA]) - -AC_ARG_ENABLE([libzfs], - [AS_HELP_STRING([--enable-libzfs], - [enable libzfs integration (default=guessed)])]) -if test x"$enable_libzfs" = xno ; then - libzfs_excuse="explicitly disabled" -fi - -if test x"$libzfs_excuse" = x ; then - # Only check for system headers if libzfs support has not been disabled. - AC_CHECK_HEADERS(libzfs.h libnvpair.h) -fi - -if test x"$libzfs_excuse" = x ; then - AC_CHECK_LIB([zfs], [libzfs_init], - [], - [libzfs_excuse="need zfs library"]) -fi - -if test x"$libzfs_excuse" = x ; then - AC_CHECK_LIB([nvpair], [nvlist_lookup_string], - [have_normal_nvpair=yes], - [have_normal_nvpair=no]) - if test x"$have_normal_nvpair" = xno ; then - AC_CHECK_LIB([nvpair], [opensolaris_nvlist_lookup_string], - [have_prefixed_nvpair=yes], - [have_prefixed_nvpair=no]) - if test x"$have_prefixed_nvpair" = xyes ; then - AC_DEFINE([GRUB_UTIL_NVPAIR_IS_PREFIXED], [1], - [Define to 1 if libnvpair symbols are prefixed with opensolaris_.]) - else - libzfs_excuse="need nvpair library" - fi - fi -fi - -if test x"$enable_libzfs" = xyes && test x"$libzfs_excuse" != x ; then - AC_MSG_ERROR([libzfs support was explicitly requested but requirements are not satisfied ($libzfs_excuse)]) -fi - -if test x"$libzfs_excuse" = x ; then - # We need both libzfs and libnvpair for a successful build. - LIBZFS="-lzfs" - LIBNVPAIR="-lnvpair" - AC_DEFINE([USE_LIBZFS], [1], - [Define to 1 if ZFS library should be used.]) -fi - -AC_SUBST([LIBZFS]) -AC_SUBST([LIBNVPAIR]) - -AC_ARG_ENABLE([grub-protect], - [AS_HELP_STRING([--enable-grub-protect], - [build and install the `grub-protect' utility (default=guessed)])]) -if test x"$enable_grub_protect" = xno ; then - grub_protect_excuse="explicitly disabled" -fi - -LIBTASN1= -if test x"$grub_protect_excuse" = x ; then - AC_CHECK_LIB([tasn1], [asn1_write_value], [LIBTASN1="-ltasn1"], [grub_protect_excuse="need libtasn1 library"]) -fi -AC_SUBST([LIBTASN1]) - -if test x"$enable_grub_protect" = xyes && test x"$grub_protect_excuse" != x ; then - AC_MSG_ERROR([grub-protect was explicitly requested but can't be compiled ($grub_protect_excuse)]) -fi -if test x"$grub_protect_excuse" = x ; then -enable_grub_protect=yes -else -enable_grub_protect=no -fi -AC_SUBST([enable_grub_protect]) - -LIBS="" - -AC_SUBST([FONT_SOURCE]) -AS_IF([test x$target_cpu = xi386 -a x$platform = xqemu], - [AC_SUBST([GRUB_BOOT_MACHINE_LINK_ADDR], 0xffe00)]) - -AC_SUBST(HAVE_ASM_USCORE) -AC_SUBST(BSS_START_SYMBOL) -AC_SUBST(END_SYMBOL) -AC_SUBST(PACKAGE) -AC_SUBST(VERSION) - -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" - HOST_CFLAGS="$HOST_CFLAGS -Werror" - if test "x$grub_cv_cc_target_clang" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -Wno-error=vla" - HOST_CFLAGS="$HOST_CFLAGS -Wno-error=vla" - fi -fi - -TARGET_CPP="$TARGET_CC -E" -TARGET_CCAS=$TARGET_CC - -# Includes which include make-time substitutions. They must come last -# as to avoid executing top_builddir in shell. -HOST_CPPFLAGS="$HOST_CPPFLAGS -I\$(top_builddir)/include" -TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_srcdir)/include" -TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_builddir)/include" - -GRUB_TARGET_CPU="${target_cpu}" -GRUB_PLATFORM="${platform}" - -AC_SUBST(GRUB_TARGET_CPU) -AC_SUBST(GRUB_PLATFORM) - -AC_SUBST(TARGET_OBJCONV) -AC_SUBST(TARGET_CPP) -AC_SUBST(TARGET_CCAS) -AC_SUBST(TARGET_OBJ2ELF) -AC_SUBST(TARGET_MODULE_FORMAT) -AC_SUBST(TARGET_CC_VERSION) - -AC_SUBST(TARGET_CFLAGS) -AC_SUBST(TARGET_LDFLAGS) -AC_SUBST(TARGET_CPPFLAGS) -AC_SUBST(TARGET_CCASFLAGS) - -AC_SUBST(TARGET_IMG_LDFLAGS) -AC_SUBST(TARGET_IMG_CFLAGS) -AC_SUBST(TARGET_IMG_BASE_LDOPT) -AC_SUBST(TARGET_APPLE_LINKER) - -AC_SUBST(HOST_CFLAGS) -AC_SUBST(HOST_LDFLAGS) -AC_SUBST(HOST_CPPFLAGS) -AC_SUBST(HOST_CCASFLAGS) - -AC_SUBST(BUILD_LIBM) - -# -# Automake conditionals -# - -AM_CONDITIONAL([COND_real_platform], [test x$platform != xnone]) -AM_CONDITIONAL([COND_emu], [test x$platform = xemu]) -AM_CONDITIONAL([COND_arm], [test x$target_cpu = xarm ]) -AM_CONDITIONAL([COND_arm_uboot], [test x$target_cpu = xarm -a x$platform = xuboot]) -AM_CONDITIONAL([COND_arm_coreboot], [test x$target_cpu = xarm -a x$platform = xcoreboot]) -AM_CONDITIONAL([COND_arm_efi], [test x$target_cpu = xarm -a x$platform = xefi]) -AM_CONDITIONAL([COND_arm64], [test x$target_cpu = xarm64 ]) -AM_CONDITIONAL([COND_arm64_efi], [test x$target_cpu = xarm64 -a x$platform = xefi]) -AM_CONDITIONAL([COND_ia64_efi], [test x$target_cpu = xia64 -a x$platform = xefi]) -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_qemu], [test x$target_cpu = xi386 -a x$platform = xqemu]) -AM_CONDITIONAL([COND_i386_ieee1275], [test x$target_cpu = xi386 -a x$platform = xieee1275]) -AM_CONDITIONAL([COND_i386_coreboot], [test x$target_cpu = xi386 -a x$platform = xcoreboot]) -AM_CONDITIONAL([COND_i386_multiboot], [test x$target_cpu = xi386 -a x$platform = xmultiboot]) -AM_CONDITIONAL([COND_i386_xen], [test x$target_cpu = xi386 -a x$platform = xxen]) -AM_CONDITIONAL([COND_i386_xen_pvh], [test x$target_cpu = xi386 -a x$platform = xxen_pvh]) -AM_CONDITIONAL([COND_loongarch64], [test x$target_cpu = xloongarch64]) -AM_CONDITIONAL([COND_loongarch64_efi], [test x$target_cpu = xloongarch64 -a x$platform = xefi]) -AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips -o x$target_cpu = xmipsel]) -AM_CONDITIONAL([COND_mips_arc], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xarc]) -AM_CONDITIONAL([COND_mips_loongson], [test x$target_cpu = xmipsel -a x$platform = xloongson]) -AM_CONDITIONAL([COND_mips_qemu_mips], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xqemu_mips]) -AM_CONDITIONAL([COND_mipsel], [test x$target_cpu = xmipsel]) -AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips]) -AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275]) -AM_CONDITIONAL([COND_riscv32], [test x$target_cpu = xriscv32 ]) -AM_CONDITIONAL([COND_riscv64], [test x$target_cpu = xriscv64 ]) -AM_CONDITIONAL([COND_riscv32_efi], [test x$target_cpu = xriscv32 -a x$platform = xefi]) -AM_CONDITIONAL([COND_riscv64_efi], [test x$target_cpu = xriscv64 -a x$platform = xefi]) -AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275]) -AM_CONDITIONAL([COND_sparc64_emu], [test x$target_cpu = xsparc64 -a x$platform = xemu]) -AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi]) -AM_CONDITIONAL([COND_x86_64_xen], [test x$target_cpu = xx86_64 -a x$platform = xxen]) - -AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd]) -AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux]) -AM_CONDITIONAL([COND_HOST_NETBSD], [test x$host_kernel = xnetbsd]) -AM_CONDITIONAL([COND_HOST_WINDOWS], [test x$host_kernel = xwindows]) -AM_CONDITIONAL([COND_HOST_KFREEBSD], [test x$host_kernel = xkfreebsd]) -AM_CONDITIONAL([COND_HOST_XNU], [test x$host_kernel = xxnu]) -AM_CONDITIONAL([COND_HOST_ILLUMOS], [test x$host_kernel = xillumos]) - -AM_CONDITIONAL([COND_MAN_PAGES], [test x$cross_compiling = xno -a x$HELP2MAN != x]) -AM_CONDITIONAL([COND_GRUB_EMU_SDL2], [test x$enable_grub_emu_sdl2 = 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_GRUB_MOUNT], [test x$enable_grub_mount = xyes]) -AM_CONDITIONAL([COND_GRUB_PROTECT], [test x$enable_grub_protect = xyes]) -AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x]) -if test x$FONT_SOURCE != x ; then - HAVE_FONT_SOURCE=1 -else - HAVE_FONT_SOURCE=0 -fi -AC_SUBST(HAVE_FONT_SOURCE) -AM_CONDITIONAL([COND_APPLE_LINKER], [test x$TARGET_APPLE_LINKER = x1]) -AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes]) -AM_CONDITIONAL([COND_ENABLE_CACHE_STATS], [test x$DISK_CACHE_STATS = x1]) -AM_CONDITIONAL([COND_ENABLE_BOOT_TIME_STATS], [test x$BOOT_TIME_STATS = x1]) - -AM_CONDITIONAL([COND_HAVE_CXX], [test x$HAVE_CXX = xyes]) - -AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1]) -AM_CONDITIONAL([COND_STARFIELD], [test "x$starfield_excuse" = x]) -AM_CONDITIONAL([COND_HAVE_EXEC], [test "x$have_exec" = xy]) -AM_CONDITIONAL([COND_HAVE_PCI], [test "x$have_pci" = xy]) - -test "x$prefix" = xNONE && prefix="$ac_default_prefix" -test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" -datarootdir="$(eval echo "$datarootdir")" -grub_libdir="$(eval echo "$libdir")" -grub_localedir="$(eval echo "$localedir")" -grub_datadir="$(eval echo "$datadir")" -grub_sysconfdir="$(eval echo "$sysconfdir")" -AC_DEFINE_UNQUOTED(LOCALEDIR, "$grub_localedir", [Locale dir]) -AC_DEFINE_UNQUOTED(GRUB_LIBDIR, "$grub_libdir", [Library dir]) -AC_DEFINE_UNQUOTED(GRUB_DATADIR, "$grub_datadir", [Data dir]) -AC_DEFINE_UNQUOTED(GRUB_SYSCONFDIR, "$grub_sysconfdir", [Configuration dir]) - +AC_SUBST(ASFLAGS) # Output files. -if test "$platform" != none; then - cpudir="${target_cpu}" - if test x${cpudir} = xmipsel; then - cpudir=mips; - fi - grub_CHECK_LINK_DIR - if test x"$link_dir" = xyes ; then - AC_CONFIG_LINKS([include/grub/cpu:include/grub/$cpudir]) - if test "$platform" != emu ; then - AC_CONFIG_LINKS([include/grub/machine:include/grub/$cpudir/$platform]) - fi - else - mkdir -p include/grub 2>/dev/null - rm -rf include/grub/cpu - cp -rp $srcdir/include/grub/$cpudir include/grub/cpu 2>/dev/null - if test "$platform" != emu ; then - rm -rf include/grub/machine - cp -rp $srcdir/include/grub/$cpudir/$platform include/grub/machine 2>/dev/null - fi +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 - # Just enough to stop the compiler failing with -I$(srcdir)/include. - mkdir -p include 2>/dev/null - rm -rf include/grub/cpu include/grub/machine + 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([grub-core/Makefile]) -AC_CONFIG_FILES([grub-core/lib/gnulib/Makefile]) -AC_CONFIG_FILES([po/Makefile.in]) -AC_CONFIG_FILES([docs/Makefile]) -AC_CONFIG_FILES([util/bash-completion.d/Makefile]) +AC_CONFIG_FILES([Makefile gensymlist.sh genkernsyms.sh]) AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h]) -AC_CONFIG_FILES([config.h]) - AC_OUTPUT [ echo "*******************************************************" echo GRUB2 will be compiled with following components: echo Platform: "$target_cpu"-"$platform" if [ x"$platform" = xemu ]; then -if [ x"$grub_emu_sdl2_excuse" = x ]; then -echo SDL2 support for grub-emu: Yes +if [ x"$grub_emu_usb_excuse" = x ]; then +echo USB support for grub-emu: Yes else -echo SDL2 support for grub-emu: No "($grub_emu_sdl2_excuse)" +echo USB support for grub-emu: No "($grub_emu_usb_excuse)" fi if [ x"$grub_emu_sdl_excuse" = x ]; then echo SDL support for grub-emu: Yes @@ -2324,79 +757,25 @@ else echo PCI support for grub-emu: No "($grub_emu_pci_excuse)" fi fi -if test x"$device_mapper_excuse" = x ; then -echo With devmapper support: Yes -else -echo With devmapper support: No "($device_mapper_excuse)" -fi if [ x"$enable_mm_debug" = xyes ]; then echo With memory debugging: Yes else echo With memory debugging: No fi -if [ x"$enable_cache_stats" = xyes ]; then -echo With disk cache statistics: Yes -else -echo With disk cache statistics: No -fi - -if [ x"$enable_boot_time" = xyes ]; then -echo With boot time statistics: Yes -else -echo With boot time statistics: No -fi - if [ x"$efiemu_excuse" = x ]; then echo efiemu runtime: Yes else echo efiemu runtime: No "($efiemu_excuse)" fi +if [ x"$grub_fstest_excuse" = x ]; then +echo grub-fstest: Yes +else +echo grub-fstest: No "($grub_fstest_excuse)" +fi if [ x"$grub_mkfont_excuse" = x ]; then echo grub-mkfont: Yes else echo grub-mkfont: No "($grub_mkfont_excuse)" fi -if [ x"$grub_mount_excuse" = x ]; then -echo grub-mount: Yes -else -echo grub-mount: No "($grub_mount_excuse)" -fi -if [ x"$grub_protect_excuse" = x ]; then -echo grub-protect: Yes -else -echo grub-protect: No "($grub_protect_excuse)" -fi -if [ x"$starfield_excuse" = x ]; then -echo starfield theme: Yes -echo With DejaVuSans font from $DJVU_FONT_SOURCE -else -echo starfield theme: No "($starfield_excuse)" -fi -if [ x"$libzfs_excuse" = x ]; then -echo With libzfs support: Yes -else -echo With libzfs support: No "($libzfs_excuse)" -fi -if [ x"$grub_build_mkfont_excuse" = x ]; then - echo Build-time grub-mkfont: Yes - if test "x$FONT_SOURCE" = x ; then - echo "Without unifont" - else - echo "With unifont from $FONT_SOURCE" - fi -else - echo Build-time grub-mkfont: No "($grub_build_mkfont_excuse)" - echo "Without unifont (no build-time grub-mkfont)" -fi -if test x"$liblzma_excuse" != x ; then -echo "Without liblzma (no support for XZ-compressed mips images) ($liblzma_excuse)" -else -echo "With liblzma from $LIBLZMA (support for XZ-compressed mips images)" -fi -if test "x$enable_stack_protector" != xno; then -echo "With stack smashing protector: Yes" -else -echo "With stack smashing protector: No" -fi echo "*******************************************************" ] diff --git a/coreboot.cfg b/coreboot.cfg deleted file mode 100644 index 188090d3a..000000000 --- a/coreboot.cfg +++ /dev/null @@ -1,3 +0,0 @@ -if test -f (cbfsdisk)/etc/grub.cfg; then - source (cbfsdisk)/etc/grub.cfg -fi diff --git a/disk/ata.c b/disk/ata.c new file mode 100644 index 000000000..687ed9378 --- /dev/null +++ b/disk/ata.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +/* 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; +} + + + +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 + }; + + + +/* 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 + }; + + + +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 new file mode 100644 index 000000000..f52725a49 --- /dev/null +++ b/disk/ata_pthru.c @@ -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 . + */ + +#include +#include +#include +#include + + +/* 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; +} + + + +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/disk/dmraid_nvidia.c similarity index 65% rename from grub-core/disk/dmraid_nvidia.c rename to disk/dmraid_nvidia.c index 6372663e6..c4e3922cf 100644 --- a/grub-core/disk/dmraid_nvidia.c +++ b/disk/dmraid_nvidia.c @@ -22,9 +22,7 @@ #include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); +#include #define NV_SIGNATURES 4 @@ -88,97 +86,68 @@ struct grub_nv_super 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 */ -} GRUB_PACKED; +} __attribute__ ((packed)); -static struct grub_diskfilter_vg * -grub_dmraid_nv_detect (grub_disk_t disk, - struct grub_diskfilter_pv_id *id, - grub_disk_addr_t *start_sector) +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; - int level; - grub_uint64_t disk_size; - grub_uint32_t capacity; - grub_uint8_t total_volumes; - char *uuid; if (disk->partition) - /* Skip partition. */ - return NULL; + return grub_error (GRUB_ERR_OUT_OF_RANGE, "skip partition"); + + sector = grub_disk_get_size (disk) - 2; - sector = grub_disk_native_sectors (disk); - if (sector == GRUB_DISK_SIZE_UNKNOWN) - /* Not raid. */ - return NULL; - sector -= 2; if (grub_disk_read (disk, sector, 0, sizeof (sb), &sb)) - return NULL; + return grub_errno; if (grub_memcmp (sb.vendor, NV_ID_STRING, 6)) - /* Not raid. */ - return NULL; + return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid"); if (sb.version != NV_VERSION) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unknown version: %d.%d", sb.version >> 8, sb.version & 0xFF); - return NULL; - } - - capacity = grub_le_to_cpu32 (sb.capacity); - total_volumes = sb.array.total_volumes; + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "unknown version: %d.%d", sb.version); switch (sb.array.raid_level) { case NV_LEVEL_0: - level = 0; - if (total_volumes == 0) - /* Not RAID. */ - return NULL; - disk_size = capacity / total_volumes; + array->level = 0; + array->disk_size = sb.capacity / sb.array.total_volumes; break; case NV_LEVEL_1: - level = 1; - disk_size = sb.capacity; + array->level = 1; + array->disk_size = sb.capacity; break; case NV_LEVEL_5: - level = 5; - if (total_volumes == 0 || total_volumes == 1) - /* Not RAID. */ - return NULL; - disk_size = capacity / (total_volumes - 1); + array->level = 5; + array->layout = GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC; + array->disk_size = sb.capacity / (sb.array.total_volumes - 1); break; default: - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported RAID level: %d", sb.array.raid_level); - return NULL; + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "unsupported RAID level: %d", sb.array.raid_level); } - uuid = grub_malloc (sizeof (sb.array.signature)); - if (! uuid) - return NULL; + 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 (uuid, (char *) &sb.array.signature, + grub_memcpy (array->uuid, (char *) &sb.array.signature, sizeof (sb.array.signature)); - id->uuidlen = 0; - id->id = sb.unit_number; - - *start_sector = 0; - - return grub_diskfilter_make_raid (sizeof (sb.array.signature), - uuid, sb.array.total_volumes, - "nv", disk_size, - sb.array.stripe_block_size, - GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC, - level); + return 0; } -static struct grub_diskfilter grub_dmraid_nv_dev = +static struct grub_raid grub_dmraid_nv_dev = { .name = "dmraid_nv", .detect = grub_dmraid_nv_detect, @@ -187,10 +156,10 @@ static struct grub_diskfilter grub_dmraid_nv_dev = GRUB_MOD_INIT(dm_nv) { - grub_diskfilter_register_front (&grub_dmraid_nv_dev); + grub_raid_register (&grub_dmraid_nv_dev); } GRUB_MOD_FINI(dm_nv) { - grub_diskfilter_unregister (&grub_dmraid_nv_dev); + grub_raid_unregister (&grub_dmraid_nv_dev); } diff --git a/disk/efi/efidisk.c b/disk/efi/efidisk.c new file mode 100644 index 000000000..f9c6f3153 --- /dev/null +++ b/disk/efi/efidisk.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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/disk/host.c similarity index 83% rename from grub-core/disk/host.c rename to disk/host.c index f34529f86..c4f3e7150 100644 --- a/grub-core/disk/host.c +++ b/disk/host.c @@ -20,24 +20,16 @@ /* When using the disk, make a reference to this module. Otherwise the user will end up with a useless module :-). */ -#include -#include - #include #include #include -#include int grub_disk_host_i_want_a_reference; static int -grub_host_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) +grub_host_iterate (int (*hook) (const char *name)) { - if (pull != GRUB_DISK_PULL_NONE) - return 0; - - if (hook ("host", hook_data)) + if (hook ("host")) return 1; return 0; } @@ -49,8 +41,9 @@ grub_host_open (const char *name, grub_disk_t disk) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a host disk"); disk->total_sectors = 0; - disk->id = 0; + disk->id = (unsigned long) "host"; + disk->has_partitions = 0; disk->data = 0; return GRUB_ERR_NONE; @@ -84,11 +77,11 @@ static struct grub_disk_dev grub_host_dev = /* The only important line in this file :-) */ .name = "host", .id = GRUB_DISK_DEVICE_HOST_ID, - .disk_iterate = grub_host_iterate, - .disk_open = grub_host_open, - .disk_close = grub_host_close, - .disk_read = grub_host_read, - .disk_write = grub_host_write, + .iterate = grub_host_iterate, + .open = grub_host_open, + .close = grub_host_close, + .read = grub_host_read, + .write = grub_host_write, .next = 0 }; diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c new file mode 100644 index 000000000..94d0e3708 --- /dev/null +++ b/disk/i386/pc/biosdisk.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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/disk/ieee1275/nand.c similarity index 77% rename from grub-core/disk/ieee1275/nand.c rename to disk/ieee1275/nand.c index bcf3a06f4..df2ee81f3 100644 --- a/grub-core/disk/ieee1275/nand.c +++ b/disk/ieee1275/nand.c @@ -22,9 +22,6 @@ #include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); struct grub_nand_data { @@ -33,32 +30,21 @@ struct grub_nand_data }; static int -grub_nand_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) +grub_nand_iterate (int (*hook) (const char *name)) { - static int have_nand = -1; - - if (pull != GRUB_DISK_PULL_NONE) - return 0; - - if (have_nand == -1) + auto int dev_iterate (struct grub_ieee1275_devalias *alias); + int dev_iterate (struct grub_ieee1275_devalias *alias) { - struct grub_ieee1275_devalias alias; + if (! grub_strcmp (alias->name, "nand")) + { + hook (alias->name); + return 1; + } - have_nand = 0; - FOR_IEEE1275_DEVALIASES(alias) - if (grub_strcmp (alias.name, "nand") == 0) - { - have_nand = 1; - break; - } - grub_ieee1275_devalias_free (&alias); + return 0; } - if (have_nand) - return hook ("nand", hook_data); - - return 0; + return grub_devalias_iterate (dev_iterate); } static grub_err_t @@ -70,7 +56,6 @@ grub_nand_open (const char *name, grub_disk_t disk) { grub_ieee1275_ihandle_t dev_ihandle = 0; struct grub_nand_data *data = 0; - const char *devname; struct size_args { struct grub_ieee1275_common_hdr common; @@ -81,18 +66,14 @@ grub_nand_open (const char *name, grub_disk_t disk) grub_ieee1275_cell_t size2; } args; - if (grub_memcmp (name, "nand/", sizeof ("nand/") - 1) == 0) - devname = name + sizeof ("nand/") - 1; - else if (grub_strcmp (name, "nand") == 0) - devname = name; - else - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a NAND device"); + 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 (devname, &dev_ihandle); + grub_ieee1275_open (name, &dev_ihandle); if (! dev_ihandle) { grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); @@ -113,11 +94,6 @@ grub_nand_open (const char *name, grub_disk_t disk) } data->block_size = (args.size1 >> GRUB_DISK_SECTOR_BITS); - if (!data->block_size) - { - grub_error (GRUB_ERR_UNKNOWN_DEVICE, "invalid block size"); - goto fail; - } INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3); args.method = (grub_ieee1275_cell_t) "size"; @@ -137,6 +113,7 @@ grub_nand_open (const char *name, grub_disk_t disk) disk->id = dev_ihandle; + disk->has_partitions = 0; disk->data = data; return 0; @@ -195,10 +172,7 @@ grub_nand_read (grub_disk_t disk, grub_disk_addr_t sector, args.result = 1; if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result)) - return grub_error (GRUB_ERR_READ_ERROR, N_("failure reading sector 0x%llx " - "from `%s'"), - (unsigned long long) sector, - disk->name); + return grub_error (GRUB_ERR_READ_ERROR, "read error"); ofs = 0; size -= len; @@ -215,19 +189,18 @@ grub_nand_write (grub_disk_t disk __attribute ((unused)), grub_size_t size __attribute ((unused)), const char *buf __attribute ((unused))) { - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "nand write is not supported"); + return GRUB_ERR_NOT_IMPLEMENTED_YET; } static struct grub_disk_dev grub_nand_dev = { .name = "nand", .id = GRUB_DISK_DEVICE_NAND_ID, - .disk_iterate = grub_nand_iterate, - .disk_open = grub_nand_open, - .disk_close = grub_nand_close, - .disk_read = grub_nand_read, - .disk_write = grub_nand_write, + .iterate = grub_nand_iterate, + .open = grub_nand_open, + .close = grub_nand_close, + .read = grub_nand_read, + .write = grub_nand_write, .next = 0 }; diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c new file mode 100644 index 000000000..e5a4a67fa --- /dev/null +++ b/disk/ieee1275/ofdisk.c @@ -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 . + */ + +#include +#include +#include +#include +#include + +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/disk/loopback.c similarity index 61% rename from grub-core/disk/loopback.c rename to disk/loopback.c index 2bea4e922..a8b7cf5d7 100644 --- a/grub-core/disk/loopback.c +++ b/disk/loopback.c @@ -24,28 +24,21 @@ #include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); struct grub_loopback { char *devname; - grub_file_t file; + char *filename; + int has_partitions; struct grub_loopback *next; - unsigned long id; - grub_uint64_t refcnt; }; static struct grub_loopback *loopback_list; -static unsigned long last_id = 0; static const struct grub_arg_option options[] = { - /* TRANSLATORS: The disk is simply removed from the list of available ones, - not wiped, avoid to scare user. */ - {"delete", 'd', 0, N_("Delete the specified loopback drive."), 0, 0}, - {"decompress", 'D', 0, N_("Transparently decompress backing file."), 0, 0}, + {"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} }; @@ -66,13 +59,11 @@ delete_loopback (const char *name) if (! dev) return grub_error (GRUB_ERR_BAD_DEVICE, "device not found"); - if (dev->refcnt > 0) - return grub_error (GRUB_ERR_STILL_REFERENCED, "device still referenced"); /* Remove the device from the list. */ *prev = dev->next; grub_free (dev->devname); - grub_file_close (dev->file); + grub_free (dev->filename); grub_free (dev); return 0; @@ -80,75 +71,87 @@ delete_loopback (const char *name) /* The command to add and remove loopback devices. */ static grub_err_t -grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args) +grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args) { - struct grub_arg_list *state = ctxt->state; + struct grub_arg_list *state = state = cmd->state; grub_file_t file; - enum grub_file_type type = GRUB_FILE_TYPE_LOOPBACK; struct grub_loopback *newdev; - grub_err_t ret; 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 (!state[1].set) - type |= GRUB_FILE_TYPE_NO_DECOMPRESS; + return delete_loopback (args[0]); if (argc < 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); - /* Check that a device with requested name does not already exist. */ - for (newdev = loopback_list; newdev; newdev = newdev->next) - if (grub_strcmp (newdev->devname, args[0]) == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name already exists"); - - file = grub_file_open (args[1], type); + 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) - goto fail; + return grub_errno; newdev->devname = grub_strdup (args[0]); if (! newdev->devname) { grub_free (newdev); - goto fail; + return grub_errno; } - newdev->file = file; - newdev->id = last_id++; - newdev->refcnt = 0; + 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; - -fail: - ret = grub_errno; - grub_file_close (file); - return ret; } static int -grub_loopback_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) +grub_loopback_iterate (int (*hook) (const char *name)) { struct grub_loopback *d; - if (pull != GRUB_DISK_PULL_NONE) - return 0; for (d = loopback_list; d; d = d->next) { - if (hook (d->devname, hook_data)) + if (hook (d->devname)) return 1; } return 0; @@ -157,6 +160,7 @@ grub_loopback_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, 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) @@ -166,22 +170,17 @@ grub_loopback_open (const char *name, grub_disk_t disk) if (! dev) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); - if (grub_add (dev->refcnt, 1, &dev->refcnt)) - grub_fatal ("Reference count overflow"); + file = grub_file_open (dev->filename); + if (! file) + return grub_errno; /* Use the filesize for the disk size, round up to a complete sector. */ - if (dev->file->size != GRUB_FILE_SIZE_UNKNOWN) - disk->total_sectors = ((dev->file->size + GRUB_DISK_SECTOR_SIZE - 1) - / GRUB_DISK_SECTOR_SIZE); - else - disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN; - /* Avoid reading more than 512M. */ - disk->max_agglomerate = 1 << (29 - GRUB_DISK_SECTOR_BITS - - GRUB_DISK_CACHE_BITS); + disk->total_sectors = ((file->size + GRUB_DISK_SECTOR_SIZE - 1) + / GRUB_DISK_SECTOR_SIZE); + disk->id = (unsigned long) dev; - disk->id = dev->id; - - disk->data = dev; + disk->has_partitions = dev->has_partitions; + disk->data = file; return 0; } @@ -189,17 +188,16 @@ grub_loopback_open (const char *name, grub_disk_t disk) static void grub_loopback_close (grub_disk_t disk) { - struct grub_loopback *dev = disk->data; + grub_file_t file = (grub_file_t) disk->data; - if (grub_sub (dev->refcnt, 1, &dev->refcnt)) - grub_fatal ("Reference count underflow"); + 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 = ((struct grub_loopback *) disk->data)->file; + grub_file_t file = (grub_file_t) disk->data; grub_off_t pos; grub_file_seek (file, sector << GRUB_DISK_SECTOR_BITS); @@ -227,35 +225,33 @@ grub_loopback_write (grub_disk_t disk __attribute ((unused)), grub_size_t size __attribute ((unused)), const char *buf __attribute ((unused))) { - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "loopback write is not supported"); + return GRUB_ERR_NOT_IMPLEMENTED_YET; } static struct grub_disk_dev grub_loopback_dev = { .name = "loopback", .id = GRUB_DISK_DEVICE_LOOPBACK_ID, - .disk_iterate = grub_loopback_iterate, - .disk_open = grub_loopback_open, - .disk_close = grub_loopback_close, - .disk_read = grub_loopback_read, - .disk_write = grub_loopback_write, + .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) +GRUB_MOD_INIT(loop) { - cmd = grub_register_extcmd ("loopback", grub_cmd_loopback, 0, - N_("[-d] [-D] DEVICENAME FILE."), - /* TRANSLATORS: The file itself is not destroyed - or transformed into drive. */ - N_("Make a virtual drive from a file."), options); + 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_MOD_FINI(loop) { grub_unregister_extcmd (cmd); grub_disk_dev_unregister (&grub_loopback_dev); diff --git a/disk/lvm.c b/disk/lvm.c new file mode 100644 index 000000000..2c54ca3b3 --- /dev/null +++ b/disk/lvm.c @@ -0,0 +1,617 @@ +/* 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 . + */ + +#include +#include +#include +#include +#include +#include + +static struct grub_lvm_vg *vg_list; +static int lv_count; + + +/* 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) + { + 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 + }; + + +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/disk/mdraid_linux.c similarity index 59% rename from grub-core/disk/mdraid_linux.c rename to disk/mdraid_linux.c index e40216f51..306c66a8b 100644 --- a/grub-core/disk/mdraid_linux.c +++ b/disk/mdraid_linux.c @@ -1,7 +1,7 @@ -/* mdraid_linux.c - module to handle Linux Software RAID. */ +/* mdraid_linux.c - module to handle linux softraid. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. + * 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 @@ -22,29 +22,11 @@ #include #include #include -#include +#include /* Linux RAID on disk structures and constants, copied from include/linux/raid/md_p.h. */ -GRUB_MOD_LICENSE ("GPLv3+"); - -#ifdef MODE_BIGENDIAN -#define grub_md_to_cpu64 grub_be_to_cpu64 -#define grub_md_to_cpu32 grub_be_to_cpu32 -#define grub_md_to_cpu16 grub_be_to_cpu16 -#define grub_cpu_to_md64_compile_time grub_cpu_to_be64_compile_time -#define grub_cpu_to_md32_compile_time grub_cpu_to_be32_compile_time -#define grub_cpu_to_md16_compile_time grub_cpu_to_be16_compile_time -#else -#define grub_md_to_cpu64 grub_le_to_cpu64 -#define grub_md_to_cpu32 grub_le_to_cpu32 -#define grub_md_to_cpu16 grub_le_to_cpu16 -#define grub_cpu_to_md64_compile_time grub_cpu_to_le64_compile_time -#define grub_cpu_to_md32_compile_time grub_cpu_to_le32_compile_time -#define grub_cpu_to_md16_compile_time grub_cpu_to_le16_compile_time -#endif - #define RESERVED_BYTES (64 * 1024) #define RESERVED_SECTORS (RESERVED_BYTES / 512) @@ -175,124 +157,77 @@ struct grub_raid_super_09 * Active descriptor */ struct grub_raid_disk_09 this_disk; -} GRUB_PACKED; +} __attribute__ ((packed)); -static struct grub_diskfilter_vg * -grub_mdraid_detect (grub_disk_t disk, - struct grub_diskfilter_pv_id *id, - grub_disk_addr_t *start_sector) +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 = NULL; + struct grub_raid_super_09 sb; grub_uint32_t *uuid; - grub_uint32_t level; - struct grub_diskfilter_vg *ret; - /* The sector where the mdraid 0.90 superblock is stored, if available. */ - size = grub_disk_native_sectors (disk); - if (size == GRUB_DISK_SIZE_UNKNOWN) - /* not 0.9x raid. */ - return NULL; + /* The sector where the RAID superblock is stored, if available. */ + size = grub_disk_get_size (disk); sector = NEW_SIZE_SECTORS (size); - sb = grub_malloc (sizeof (*sb)); - if (!sb) - return NULL; + if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb)) + return grub_errno; - if (grub_disk_read (disk, sector, 0, SB_BYTES, sb)) - goto fail; + /* Look whether there is a RAID superblock. */ + if (sb.md_magic != SB_MAGIC) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid"); - /* Look whether there is a mdraid 0.90 superblock. */ - if (sb->md_magic != grub_cpu_to_md32_compile_time (SB_MAGIC)) - /* not 0.9x raid. */ - goto fail; + /* 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); - if (sb->major_version != grub_cpu_to_md32_compile_time (0) - || sb->minor_version != grub_cpu_to_md32_compile_time (90)) - /* Unsupported version. */ - goto fail; + /* FIXME: Check the checksum. */ - /* No need for explicit check that sb->size is 0 (unspecified) since - 0 >= non-0 is false. */ - if (((grub_disk_addr_t) grub_md_to_cpu32 (sb->size)) * 2 >= size) - goto fail; - - /* FIXME: Check the checksum. */ - - level = grub_md_to_cpu32 (sb->level); /* Multipath. */ - if ((int) level == -4) - level = 1; + if ((int) sb.level == -4) + sb.level = 1; - if (level != 0 && level != 1 && level != 4 && - level != 5 && level != 6 && level != 10) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported RAID level: %d", level); - goto fail; - } - if (grub_md_to_cpu32 (sb->this_disk.number) == 0xffff - || grub_md_to_cpu32 (sb->this_disk.number) == 0xfffe) - /* Spares aren't implemented. */ - goto fail; + 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); - uuid = grub_malloc (16); - if (!uuid) - goto fail; + 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[0] = grub_swap_bytes32 (sb->set_uuid0); - uuid[1] = grub_swap_bytes32 (sb->set_uuid1); - uuid[2] = grub_swap_bytes32 (sb->set_uuid2); - uuid[3] = grub_swap_bytes32 (sb->set_uuid3); + 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; - *start_sector = 0; - - id->uuidlen = 0; - id->id = grub_md_to_cpu32 (sb->this_disk.number); - - char buf[32]; - grub_snprintf (buf, sizeof (buf), "md%d", grub_md_to_cpu32 (sb->md_minor)); - ret = grub_diskfilter_make_raid (16, (char *) uuid, - grub_md_to_cpu32 (sb->raid_disks), buf, - (sb->size) ? ((grub_disk_addr_t) - grub_md_to_cpu32 (sb->size)) * 2 - : sector, - grub_md_to_cpu32 (sb->chunk_size) >> 9, - grub_md_to_cpu32 (sb->layout), - level); - grub_free (sb); - return ret; - - fail: - grub_free (sb); - return NULL; + return 0; } -static struct grub_diskfilter grub_mdraid_dev = { -#ifdef MODE_BIGENDIAN - .name = "mdraid09_be", -#else - .name = "mdraid09", -#endif +static struct grub_raid grub_mdraid_dev = { + .name = "mdraid", .detect = grub_mdraid_detect, .next = 0 }; -#ifdef MODE_BIGENDIAN -GRUB_MOD_INIT (mdraid09_be) -#else -GRUB_MOD_INIT (mdraid09) -#endif +GRUB_MOD_INIT (mdraid) { - grub_diskfilter_register_front (&grub_mdraid_dev); + grub_raid_register (&grub_mdraid_dev); } -#ifdef MODE_BIGENDIAN -GRUB_MOD_FINI (mdraid09_be) -#else -GRUB_MOD_FINI (mdraid09) -#endif +GRUB_MOD_FINI (mdraid) { - grub_diskfilter_unregister (&grub_mdraid_dev); + grub_raid_unregister (&grub_mdraid_dev); } diff --git a/grub-core/disk/memdisk.c b/disk/memdisk.c similarity index 63% rename from grub-core/disk/memdisk.c rename to disk/memdisk.c index 2d7afaea3..4a0470837 100644 --- a/grub-core/disk/memdisk.c +++ b/disk/memdisk.c @@ -23,21 +23,15 @@ #include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); +#include static char *memdisk_addr; static grub_off_t memdisk_size = 0; static int -grub_memdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) +grub_memdisk_iterate (int (*hook) (const char *name)) { - if (pull != GRUB_DISK_PULL_NONE) - return 0; - - return hook ("memdisk", hook_data); + return hook ("memdisk"); } static grub_err_t @@ -47,8 +41,8 @@ grub_memdisk_open (const char *name, grub_disk_t disk) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a memdisk"); disk->total_sectors = memdisk_size / GRUB_DISK_SECTOR_SIZE; - disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE; - disk->id = 0; + disk->id = (unsigned long) "mdsk"; + disk->has_partitions = 0; return GRUB_ERR_NONE; } @@ -78,40 +72,40 @@ static struct grub_disk_dev grub_memdisk_dev = { .name = "memdisk", .id = GRUB_DISK_DEVICE_MEMDISK_ID, - .disk_iterate = grub_memdisk_iterate, - .disk_open = grub_memdisk_open, - .disk_close = grub_memdisk_close, - .disk_read = grub_memdisk_read, - .disk_write = grub_memdisk_write, + .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) { - struct grub_module_header *header; - FOR_MODULES (header) - if (header->type == OBJ_TYPE_MEMDISK) - { - char *memdisk_orig_addr; - memdisk_orig_addr = (char *) header + sizeof (struct grub_module_header); + 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); + grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr); - if (grub_sub (header->size, sizeof (struct grub_module_header), &memdisk_size)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "underflow detected while obtaining memdisk size"); - return; - } - memdisk_addr = grub_malloc (memdisk_size); - if (memdisk_addr == NULL) - return; + 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_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); - break; - } + grub_disk_dev_register (&grub_memdisk_dev); + return 1; + } + + return 0; + } + + grub_module_iterate (hook); } GRUB_MOD_FINI(memdisk) diff --git a/disk/raid.c b/disk/raid.c new file mode 100644 index 000000000..2d544afdc --- /dev/null +++ b/disk/raid.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include + +/* 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; + + +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 + }; + + +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/disk/raid5_recover.c similarity index 76% rename from grub-core/disk/raid5_recover.c rename to disk/raid5_recover.c index 4ace9172e..31cef88b1 100644 --- a/grub-core/disk/raid5_recover.c +++ b/disk/raid5_recover.c @@ -22,14 +22,11 @@ #include #include #include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); +#include static grub_err_t -grub_raid5_recover (struct grub_diskfilter_segment *array, int disknr, - char *buf, grub_disk_addr_t sector, grub_size_t size) +grub_raid5_recover (struct grub_raid_array *array, int disknr, + char *buf, grub_disk_addr_t sector, int size) { char *buf2; int i; @@ -41,15 +38,14 @@ grub_raid5_recover (struct grub_diskfilter_segment *array, int disknr, grub_memset (buf, 0, size); - for (i = 0; i < (int) array->node_count; i++) + for (i = 0; i < (int) array->total_devs; i++) { grub_err_t err; if (i == disknr) continue; - err = grub_diskfilter_read_node (&array->nodes[i], sector, - size >> GRUB_DISK_SECTOR_BITS, buf2); + err = grub_disk_read (array->device[i], sector, 0, size, buf2); if (err) { @@ -57,7 +53,7 @@ grub_raid5_recover (struct grub_diskfilter_segment *array, int disknr, return err; } - grub_crypto_xor (buf, buf, buf2, size); + grub_raid_block_xor (buf, buf2, size); } grub_free (buf2); diff --git a/disk/raid6_recover.c b/disk/raid6_recover.c new file mode 100644 index 000000000..550968ceb --- /dev/null +++ b/disk/raid6_recover.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include + +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 new file mode 100644 index 000000000..eba237287 --- /dev/null +++ b/disk/scsi.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +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; + } +} + + +/* 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 + + +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, §or_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 new file mode 100644 index 000000000..8554b224f --- /dev/null +++ b/disk/usbms.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include + +#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); +} + + + +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 deleted file mode 100644 index 93eb39627..000000000 --- a/docs/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -AUTOMAKE_OPTIONS = subdir-objects - -# AM_MAKEINFOFLAGS = --no-split --no-validate -info_TEXINFOS = grub.texi grub-dev.texi -grub_TEXINFOS = fdl.texi - -EXTRA_DIST = font_char_metrics.png font_char_metrics.txt - - diff --git a/docs/autoiso.cfg b/docs/autoiso.cfg deleted file mode 100644 index 9ce51c692..000000000 --- a/docs/autoiso.cfg +++ /dev/null @@ -1,244 +0,0 @@ -# Sample GRUB script to autodetect operating systems -# -# 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 . - -function pathname { regexp -s 2:"$2" '^(\(.*\))?(/.*)$' "$1"; } -function devname { regexp -s "$2" '^(\(.*\)).*$' "$1"; } - -function loopback_iso_entry { - realdev="$1" - isopath="$2" - loopdev="$3" - - if test -f /boot/grub/loopback.cfg; then - cfgpath=/boot/grub/loopback.cfg - elif test -f /grub/loopback.cfg; then - cfgpath=/grub/loopback.cfg - else - return 1; - fi - - echo loopback.cfg $isopath: yes - menuentry "Boot GRUB Loopback Config from ${realdev}${isopath}" "$realdev" "$isopath" "$cfgpath" { - set device="$2" - set iso_path="$3" - set cfg_path="$4" - - export iso_path - loopback loopdev_cfg "${device}${iso_path}" - set root=(loopdev_cfg) - configfile $cfg_path - loopback -d loopdev_cfg - } - return 0 -} - -function grml_iso_entry { - realdev="$1" - isopath="$2" - loopdev="$3" - - result=1 - for dir in /boot/grml /boot/grmlsmall /boot/grmlmedium; do - if ! test -f ${dir}/linux26 -a -f ${dir}/initrd.gz; then continue; fi - - echo grml $isopath: yes - result=0 - menuentry "GRML Linux from ${realdev}${isopath}" \ - "$realdev" "$isopath" "$dir" { - set device="$2" - set isopath="$3" - set grmldir="$4" - - loopback loopdev_grml "${device}${isopath}" - set root=(loopdev_grml) - linux $grmldir/linux26 findiso="$isopath" apm=power-off quiet \ - boot=live nomce - initrd $grmldir/initrd.gz - loopback -d loopdev_grml - } - done - return $result -} - -function pmagic_iso_entry { - realdev="$1" - isopath="$2" - loopdev="$3" - - if ! test -f /pmagic/bzImage -a -f /pmagic/initramfs; then return 1; fi - - echo pmagic $isopath: yes - menuentry "Parted Magic from ${realdev}${isopath}" "$realdev" "$isopath" { - set device="$2" - set isopath="$3" - - loopback loopdev_pmagic "${device}${isopath}" - set root=(loopdev_pmagic) - linux /pmagic/bzImage iso_filename="$isopath" edd=off noapic \ - load_ramdisk=1 prompt_ramdisk=0 rw sleep=10 loglevel=0 \ - keymap=$langcode - initrd /pmagic/initramfs - loopback -d loopdev_pmagic - } - return 0 -} - -function sidux_iso_entry { - realdev="$1" - isopath="$2" - loopdev="$3" - - result=1 - for kernel in /boot/vmlinuz-*-sidux-*; do - if ! test -f "$kernel"; then continue; fi - regexp -s 1:v1 -s 2:v2 '/boot/vmlinuz-(.*)-sidux-(.*)' "$kernel" - - initrd="/boot/initrd.img-$v1-sidux-$v2" - if ! test -f "$initrd"; then continue; fi - - result=0 - echo sidux $isopath: yes - menuentry "Sidux vmlinux-$v1-sidux-$v2 from ${realdev}${isopath}" "$realdev" "$isopath" "$kernel" "$initrd" { - set device="$2" - set isopath="$3" - set kernel="$4" - set initrd="$5" - - loopback loopdev_sidux "${device}${isopath}" - set root=(loopdev_sidux) - linux $kernel fromiso=$isopath boot=fll quiet - initrd $initrd - loopback -d loopdev_sidux - } - done - return $result -} - -function slax_iso_entry { - realdev="$1" - isopath="$2" - loopdev="$3" - - if ! test -f /boot/vmlinuz -a -f /boot/initrd.gz; then return 1; fi - - echo slax $isopath: yes - menuentry "Slax Linux from ${realdev}${isopath}" "$realdev" "$isopath" { - set device="$2" - set isopath="$3" - - loopback loopdev_slax "${device}${isopath}" - set root=(loopdev_slax) - linux /boot/vmlinuz from=$isopath ramdisk_size=6666 root=/dev/ram0 rw - initrd /boot/initrd.gz - loopback -d loopdev_slax - } - return 0 -} - -function tinycore_iso_entry { - realpath="$1" - isopath="$2" - loopdev="$3" - - if ! test -f /boot/bzImage -a -f /boot/tinycore.gz; then return 1; fi - - echo tinycore $isopath: yes - menuentry "Tinycore Linux from ${realdev}${isopath}" "$realdev" "$isopath" { - set device="$2" - set isopath="$3" - - loopback loopdev_tiny "${device}${isopath}" - set root=(loopdev_tiny) - linux /boot/bzImage - initrd /boot/tinycore.gz - loopback -d loopdev_tiny - } - return 0 -} - -function casper_iso_entry { - realpath="$1" - isopath="$2" - loopdev="$3" - - if ! test -f /casper/vmlinuz; then return 1; fi - initrd= - for f in /casper/initrd.*z; do - if ! test -f "$f"; then continue; fi - pathname "$f" initrd - done - if test -z "$initrd"; then return 1; fi - - echo casper $isopath: yes - menuentry "Casper based Linux from ${realdev}${isopath}" "$realdev" "$isopath" "$initrd" { - set device="$2" - set isopath="$3" - set initrd="$4" - - loopback loopdev_casper "${device}${isopath}" - set root=(loopdev_casper) - linux /casper/vmlinuz boot=casper iso-scan/filename="$isopath" quiet splash noprompt keyb="$langcode" \ - debian-installer/language="$langcode" console-setup/layoutcode?="$langcode" -- - initrd $initrd - loopback -d loopdev_casper - } - return 0 -} - -function scan_isos { - isodirs="$1" - - for dev in (*); do - for dir in $isodirs; do - for file in ${dev}${dir}/*.iso ${dev}${dir}/*.ISO; do - if ! test -f "$file"; then continue; fi - - pathname $file isopath - if test -z "$dev" -o -z "$isopath"; then continue; fi - - if ! loopback loopdev_scan "$file"; then continue; fi - saved_root=$root - set root=(loopdev_scan) - - if loopback_iso_entry $dev $isopath (loopdev_scan); then true; - elif grml_iso_entry $dev $isopath (loopdev_scan); then true; - elif pmagic_iso_entry $dev $isopath (loopdev_scan); then true; - elif sidux_iso_entry $dev $isopath (loopdev_scan); then true; - elif slax_iso_entry $dev $isopath (loopdev_scan); then true; - elif tinycore_iso_entry $dev $isopath (loopdev_scan); then true; - elif casper_iso_entry $dev $isopath (loopdev_scan); then true; - else true; fi - - set root=$saved_root - loopback -d loopdev_scan - done - done - done - return 0 -} - -# XXX Remove later -insmod serial -serial -terminal_output --append serial -# terminal_input --append serial - -langcode="$lang" - -insmod regexp -scan_isos /iso /boot/iso - diff --git a/docs/font_char_metrics.png b/docs/font_char_metrics.png deleted file mode 100644 index 8d10d1f64..000000000 Binary files a/docs/font_char_metrics.png and /dev/null differ diff --git a/docs/font_char_metrics.txt b/docs/font_char_metrics.txt deleted file mode 100644 index 92f1371fd..000000000 --- a/docs/font_char_metrics.txt +++ /dev/null @@ -1 +0,0 @@ -Please fill this in. diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi deleted file mode 100644 index f4367f895..000000000 --- a/docs/grub-dev.texi +++ /dev/null @@ -1,2448 +0,0 @@ -\input texinfo -@c -*-texinfo-*- -@c %**start of header -@setfilename grub-dev.info -@include version-dev.texi -@settitle GNU GRUB Developers Manual @value{VERSION} -@c Unify all our little indices for now. -@syncodeindex fn cp -@syncodeindex vr cp -@syncodeindex ky cp -@syncodeindex pg cp -@syncodeindex tp cp -@c %**end of header - -@footnotestyle separate -@paragraphindent 3 -@finalout - -@copying -This developer manual is for GNU GRUB (version @value{VERSION}, -@value{UPDATED}). - -Copyright @copyright{} 1999,2000,2001,2002,2004,2005,2006,2008,2009,2010,2011 Free Software Foundation, Inc. - -@quotation -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.2 or -any later version published by the Free Software Foundation; with no -Invariant Sections. -@end quotation -@end copying - -@dircategory Kernel -@direntry -* grub-dev: (grub-dev). The GRand Unified Bootloader Dev -@end direntry - -@setchapternewpage odd - -@titlepage -@sp 10 -@title the GNU GRUB developer manual -@subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}. -@author Yoshinori K. Okuji -@author Colin D Bennett -@author Vesa Jääskeläinen -@author Colin Watson -@author Robert Millan -@author Carles Pina -@c The following two commands start the copyright page. -@page -@vskip 0pt plus 1filll -@insertcopying -@end titlepage - -@c Output the table of contents at the beginning. -@contents - -@finalout -@headings double - -@ifnottex -@node Top -@top GNU GRUB developer manual - -This is the developer documentation of GNU GRUB, the GRand Unified Bootloader, -a flexible and powerful boot loader program for a wide range of -architectures. - -This edition documents version @value{VERSION}. - -@insertcopying -@end ifnottex - -@menu -* Getting the source code:: -* Coding style:: -* Finding your way around:: -* Contributing Changes:: -* Setting up and running test suite:: -* Updating External Code:: -* Debugging:: -* Porting:: -* Error Handling:: -* Stack and heap size:: -* BIOS port memory map:: -* Video Subsystem:: -* PFF2 Font File Format:: -* Graphical Menu Software Design:: -* Verifiers framework:: -* Lockdown framework:: -* Copying This Manual:: Copying This Manual -* Index:: -@end menu - - -@node Getting the source code -@chapter Getting the source code - -GRUB is maintained using the @uref{https://git-scm.com/book/en/v2, -GIT revision control system}. To fetch: - -@example -git clone git://git.sv.gnu.org/grub.git -@end example - -Web access is available under -@example -http://git.savannah.gnu.org/cgit/grub.git/ -@end example - -The branches available are: - -@table @samp -@item master - Main development branch. -@item grub-legacy - GRUB 0.97 codebase. Kept for reference and legal reasons -@item multiboot - Multiboot specfication -@item multiboot2 - Multiboot2 specfication -@item developer branches - Prefixed with developer name. Every developer of a team manages his own branches. - Developer branches do not need changelog entries. -@end table - -Once you have used @kbd{git clone} to fetch an initial copy of a branch, you -can use @kbd{git pull} to keep it up to date. If you have modified your -local version, you may need to resolve conflicts when pulling. - -@node Coding style -@chapter Coding style -@c By YoshinoriOkuji, VesaJääskeläinen and ColinBennett - -Basically we follow the @uref{http://www.gnu.org/prep/standards_toc.html, GNU Coding Standards}. We define additional conventions for GRUB here. - -@menu -* Naming Conventions:: -* Functions:: -* Variables:: -* Types:: -* Macros:: -* Comments:: -* Multi-Line Comments:: -@end menu - -@node Naming Conventions -@section Naming Conventions - -All global symbols (i.e. functions, variables, types, and macros) must have the prefix grub_ or GRUB_. The all capital form is used only by macros. - -@node Functions -@section Functions - -If a function is global, its name must be prefixed with grub_ and must consist of only small letters. If the function belongs to a specific function module, the name must also be prefixed with the module name. For example, if a function is for file systems, its name is prefixed with grub_fs_. If a function is for FAT file system but not for all file systems, its name is prefixed with grub_fs_fat_. The hierarchy is noted this way. - -After a prefix, a function name must start with a verb (such as get or is). It must not be a noun. Some kind of abbreviation is permitted, as long as it wouldn't make code less readable (e.g. init). - -If a function is local, its name may not start with any prefix. It must start with a verb. - -@node Variables -@section Variables - -The rule is mostly the same as functions, as noted above. If a variable is global, its name must be prefixed with grub_ and must consist of only small letters. If the variable belongs to a specific function module, the name must also be prefixed with the module name. For example, if a function is for dynamic loading, its name is prefixed with grub_dl_. If a variable is for ELF but not for all dynamic loading systems, its name is prefixed with grub_dl_elf_. - -After a prefix, a variable name must start with a noun or an adjective (such as name or long) and it should end with a noun. Some kind of abbreviation is permitted, as long as it wouldn't make code less readable (e.g. i18n). - -If a variable is global in the scope of a single file (i.e. it is declared with static), its name may not start with any prefix. It must start with a noun or an adjective. - -If a variable is local, you may choose any shorter name, as long as it wouldn't make code less readable (e.g. i). - -@node Types -@section Types - -The name of a type must be prefixed with grub_ and must consist of only small letters. If the type belongs to a specific function module, the name must also be prefixed with the module name. For example, if a type is for OS loaders, its name is prefixed with grub_loader_. If a type is for Multiboot but not for all OS loaders, its name is prefixed with grub_loader_linux_. - -The name must be suffixed with _t, to emphasize the fact that it is a type but not a variable or a function. - -@node Macros -@section Macros - -If a macro is global, its name must be prefixed with GRUB_ and must consist of only large letters. Other rules are the same as functions or variables, depending on whether a macro is used like a function or a variable. - -@node Comments -@section Comments - -All comments shall be C-style comments, of the form @samp{/* @dots{} */}. -A comment can be placed immediately preceding the entity it describes or it -can be placed together with code, variable declarations, or other non-comment -entities. However, it is recommended to not mix various forms especially in -types/structs descriptions. - -Acceptable: -@example -/* The page # that is the front buffer. */ -int displayed_page; -@end example - -@example -int render_page; /* The page # that is the back buffer. */ -@end example - -@node Multi-Line Comments -@section Multi-Line Comments - -Comments spanning multiple lines shall be formatted with all lines after the -first aligned with the first line. Asterisk characters should be repeated at -the start of each subsequent line. - -Acceptable: -@example -/* - * This is a comment - * which spans multiple lines. - * It is long. - */ -@end example - -Unacceptable: -@example -/* This is a comment - which spans multiple lines. - It is long. */ -@end example - -@example -/* - * This is a comment - * which spans multiple lines. - * It is long. */ -@end example - -@example -/* This is a comment - * which spans multiple lines. - * It is long. - */ -@end example - -In particular first unacceptable form makes comment difficult to distinguish -from the code itself. Especially if it contains the code snippets and/or is -long. So, its usage is disallowed. - -@node Finding your way around -@chapter Finding your way around - -Here is a brief map of the GRUB code base. - -GRUB uses Autoconf and Automake, with most of the Automake input generated -by a Python script. The top-level build rules are in @file{configure.ac}, -@file{grub-core/Makefile.core.def}, and @file{Makefile.util.def}. Each -block in a @file{*.def} file represents a build target, and specifies the -source files used to build it on various platforms. The @file{*.def} files -are processed into Automake input by @file{gentpl.py} (which you only need -to look at if you are extending the build system). If you are adding a new -module which follows an existing pattern, such as a new command or a new -filesystem implementation, it is usually easiest to grep -@file{grub-core/Makefile.core.def} and @file{Makefile.util.def} for an -existing example of that pattern to find out where it should be added. - -In general, code that may be run at boot time is in a subdirectory of -@file{grub-core}, while code that is only run from within a full operating -system is in a subdirectory of the top level. - -Low-level boot code, such as the MBR implementation on PC BIOS systems, is -in the @file{grub-core/boot/} directory. - -The GRUB kernel is in @file{grub-core/kern/}. This contains core facilities -such as the device, disk, and file frameworks, environment variable -handling, list processing, and so on. The kernel should contain enough to -get up to a rescue prompt. Header files for kernel facilities, among -others, are in @file{include/}. - -Terminal implementations are in @file{grub-core/term/}. - -Disk access code is spread across @file{grub-core/disk/} (for accessing the -disk devices themselves), @file{grub-core/partmap/} (for interpreting -partition table data), and @file{grub-core/fs/} (for accessing filesystems). -Note that, with the odd specialised exception, GRUB only contains code to -@emph{read} from filesystems and tries to avoid containing any code to -@emph{write} to filesystems; this lets us confidently assure users that GRUB -cannot be responsible for filesystem corruption. - -PCI and USB bus handling is in @file{grub-core/bus/}. - -Video handling code is in @file{grub-core/video/}. The graphical menu -system uses this heavily, but is in a separate directory, -@file{grub-core/gfxmenu/}. - -Most commands are implemented by files in @file{grub-core/commands/}, with -the following exceptions: - -@itemize -@item -A few core commands live in @file{grub-core/kern/corecmd.c}. - -@item -Commands related to normal mode live under @file{grub-core/normal/}. - -@item -Commands that load and boot kernels live under @file{grub-core/loader/}. - -@item -The @samp{loopback} command is really a disk device, and so lives in -@file{grub-core/disk/loopback.c}. - -@item -The @samp{gettext} command lives under @file{grub-core/gettext/}. - -@item -The @samp{loadfont} and @samp{lsfonts} commands live under -@file{grub-core/font/}. - -@item -The @samp{serial}, @samp{terminfo}, and @samp{background_image} commands -live under @file{grub-core/term/}. - -@item -The @samp{efiemu_*} commands live under @file{grub-core/efiemu/}. - -@item -OS-dependent code should be under @file{grub-core/osdep/} - -@item -Utility programs meant to be run from a full operating system -(except OS-dependent code mentioned previously) are in @file{util/}. - -@end itemize - -There are a few other special-purpose exceptions; grep for them if they -matter to you. - -@node Contributing Changes -@chapter Contributing changes -@c By YoshinoriOkuji, VesaJääskeläinen, ColinWatson - -Contributing changes to GRUB 2 is welcomed activity. However we have a -bit of control what kind of changes will be accepted to GRUB 2. -Therefore it is important to discuss your changes on grub-devel mailing list -(see MailingLists). On this page there are some basic details on the -development process and activities. - -First of all you should come up with the idea yourself what you want to -contribute. If you do not have that beforehand you are advised to study this -manual and try GRUB 2 out to see what you think is missing from there. - -Here are additional pointers: -@itemize -@item @uref{https://savannah.gnu.org/task/?group=grub, GRUB's Task Tracker} -@item @uref{https://savannah.gnu.org/bugs/?group=grub, GRUB's Bug Tracker} -@end itemize - -If you intended to make changes to GRUB Legacy (<=0.97) those are not accepted -anymore. - -@menu -* Getting started:: -* Typical Developer Experience:: -* When you are approved for write access to project's files:: -@end menu - -@node Getting started -@section Getting started - -@itemize -@item Always use latest GRUB 2 source code. So get that first. - -For developers it is recommended always to use the newest development version of GRUB 2. If development takes a long period of time, please remember to keep in sync with newest developments regularly so it is much easier to integrate your change in the future. GRUB 2 is being developed in a GIT repository. - -Please check Savannah's GRUB project page for details how to get newest git: -@uref{https://savannah.gnu.org/git/?group=grub, GRUB 2 git Repository} - -@item Compile it and try it out. - -It is always good idea to first see that things work somehow and after that -to start to implement new features or develop fixes to bugs. - -@item Study the code. - -There are sometimes odd ways to do things in GRUB 2 code base. -This is mainly related to limited environment where GRUB 2 is being executed. -You usually do not need to understand it all so it is better to only try to -look at places that relates to your work. Please do not hesitate to ask for -help if there is something that you do not understand. - -@item Develop a new feature. - -Now that you know what to do and how it should work in GRUB 2 code base, please -be free to develop it. If you have not so far announced your idea on grub-devel -mailing list, please do it now. This is to make sure you are not wasting your -time working on the solution that will not be integrated to GRUB 2 code base. - -You might want to study our coding style before starting development so you -do not need to change much of the code when your patch is being reviewed. -(see @ref{Coding style}) - -For every accepted patch there has to exist a ChangeLog entry. Our ChangeLog -consist of changes within source code and are not describing about what the -change logically does. Please see examples from previous entries. - -Also remember that GRUB 2 is licensed under GPLv3 license and that usually -means that you are not allowed to copy pieces of code from other projects. -Even if the source project's license would be compatible with GPLv3, please -discuss it beforehand on grub-devel mailing list. - -@item Test your change. - -Test that your change works properly. Try it out a couple of times, preferably on different systems, and try to find problems with it. - -@item Publish your change. - -When you are happy with your change, first make sure it is compilable with -latest development version of GRUB 2. After that please send a patch to -grub-devel for review. Please describe in your email why you made the change, -what it changes and so on. Please be prepared to receive even discouraging -comments about your patch. There is usually at least something that needs -to be improved in every patch. - -Please use unified diff to make your patch (good match of arguments for diff is @samp{-pruN}). - -@item Respond to received feedback. - -If you are asked to modify your patch, please do that and resubmit it for -review. If your change is large you are required to submit a copyright -agreement to FSF. Please keep in mind that if you are asked to submit -for copyright agreement, process can take some time and is mandatory -in order to get your changes integrated. - -If you are not on grub-devel to respond to questions, most likely your patch -will not be accepted. Also if problems arise from your changes later on, -it would be preferable that you also fix the problem. So stay around -for a while. - -@item Your patch is accepted. - -Good job! Your patch will now be integrated into GRUB 2 mainline, and if it didn't break anything it will be publicly available in the next release. - -Now you are welcome to do further improvements :) -@end itemize - -@node Typical Developer Experience -@section Typical Developer Experience - -The typical experience for a developer in this project is the following: - -@enumerate -@item You find yourself wanting to do something (e.g. fixing a bug). -@item You show some result in the mailing list or the IRC. -@item You are getting to be known to other developers. -@item You accumulate significant amount of contribution, so copyright assignment is processed. -@item You are free to check in your changes on your own, legally speaking. -@end enumerate - -At this point, it is rather annoying that you ought to ask somebody else every -change to be checked in. For efficiency, it is far better, if you can commit -it yourself. Therefore, our policy is to give you the write permission to our -official repository, once you have shown your skill and will, -and the FSF clerks have dealt with your copyright assignment. - -@node When you are approved for write access to project's files -@section When you are approved for write access to project's files - -As you might know, GRUB is hosted on -@uref{https://savannah.gnu.org/projects/grub, Savannah}, thus the membership -is managed by Savannah. This means that, if you want to be a member of this -project: - -@enumerate -@item You need to create your own account on Savannah. -@item You can submit ``Request for Inclusion'' from ``My Groups'' on Savannah. -@end enumerate - -Then, one of the admins can approve your request, and you will be a member. -If you don't want to use the Savannah interface to submit a request, you can -simply notify the admins by email or something else, alternatively. But you -still need to create an account beforehand. - -NOTE: we sometimes receive a ``Request for Inclusion'' from an unknown person. -In this case, the request would be just discarded, since it is too dangerous -to allow a stranger to be a member, which automatically gives him a commit -right to the repository, both for a legal reason and for a technical reason. - -If your intention is to just get started, please do not submit a inclusion -request. Instead, please subscribe to the mailing list, and communicate first -(e.g. sending a patch, asking a question, commenting on another message...). - -@node Setting up and running test suite -@chapter Setting up and running test suite - -GRUB is basically a tiny operating system with read support for many file -systems and which has been ported to a variety of architectures. As such, its -test suite has quite a few dependencies required to fully run the suite. -These dependencies are currently documented in the -@uref{https://git.savannah.gnu.org/cgit/grub.git/tree/INSTALL, INSTALL} -file in the source repository. Once installed, the test suite can be started -by running the @command{make check} command from the GRUB build directory. - -@node Updating External Code -@chapter Updating external code - -GRUB includes some code from other projects, and it is sometimes necessary -to update it. - -@menu -* Gnulib:: -* jsmn:: -* minilzo:: -* libtasn1:: -@end menu - -@node Gnulib -@section Gnulib - -Gnulib is a source code library that provides basic functionality to -programs and libraries. Many software packages make use of Gnulib -to avoid reinventing the portability wheel. - -GRUB imports Gnulib using its @command{bootstrap} utility, identifying a -particular Git commit in @file{bootstrap.conf}. To upgrade to a new Gnulib -commit, set @code{GNULIB_REVISION} in @file{bootstrap.conf} to the new commit -ID, then run @kbd{./bootstrap} and whatever else you need to make sure it -works. Check for changes to Gnulib's @file{NEWS} file between the old and new -commits; in some cases it will be necessary to adjust GRUB to match. You may -also need to update the patches in @file{grub-core/lib/gnulib-patches/}. - -To add a new Gnulib module or remove one that is no longer needed, change -@code{gnulib_modules} in @file{bootstrap.conf}. Again, run @kbd{./bootstrap} -and whatever else you need to make sure it works. - -Bootstrapping from an older distribution containing gettext version < 0.18.3, -will require a patch similar to this to be applied first before running the -@command{./bootstrap} utility: - -@example -diff --git a/bootstrap.conf b/bootstrap.conf -index 988dda0..a3193a9 100644 ---- a/bootstrap.conf -+++ b/bootstrap.conf -@@ -67,7 +67,7 @@ SKIP_PO=t -buildreq="\ -autoconf 2.63 -automake 1.11 --gettext 0.18.3 -+gettext 0.17 -git 1.5.5 -tar - -" -diff --git a/configure.ac b/configure.ac -index 08b518f..99f5b36 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -362,7 +362,7 @@ AC_CHECK_PROG(HAVE_CXX, $CXX, yes, no) - -AC_GNU_SOURCE -AM_GNU_GETTEXT([external]) --AM_GNU_GETTEXT_VERSION([0.18.3]) -+AM_GNU_GETTEXT_VERSION([0.17]) -AC_SYS_LARGEFILE - -# Identify characteristics of the host architecture. - -@end example - -It will also be necessary to adjust the patches in -@file{po/gettext-patches/} to apply to an older version of gettext. - -@node jsmn -@section jsmn - -jsmn is a minimalistic JSON parser which is implemented in a single header file -@file{jsmn.h}. To import a different version of the jsmn parser, you may simply -download the @file{jsmn.h} header from the desired tag or commit to the target -directory: - -@example -curl -L https://raw.githubusercontent.com/zserge/jsmn/v1.1.0/jsmn.h \ - -o grub-core/lib/json/jsmn.h -@end example - -@node minilzo -@section minilzo - -miniLZO is a very lightweight subset of the LZO library intended for easy -inclusion in other projects. It is generated automatically from the LZO -source code and contains the most important LZO functions. - -To upgrade to a new version of the miniLZO library, download the release -tarball and copy the files into the target directory: - -@example -curl -L -O https://www.oberhumer.com/opensource/lzo/download/minilzo-2.10.tar.gz -tar -zxf minilzo-2.10.tar.gz -rm minilzo-2.10/testmini.c -rm -r grub-core/lib/minilzo/* -cp minilzo-2.10/*.[hc] grub-core/lib/minilzo -rm -r minilzo-2.10* -@end example - -@node libtasn1 -@section libtasn1 - -libtasn1 is a library providing Abstract Syntax Notation One (ASN.1, as -specified by the X.680 ITU-T recommendation) parsing and structures management, -and Distinguished Encoding Rules (DER, as per X.690) encoding and decoding -functions. - -To upgrade to a new version of the libtasn1 library, download the release -tarball and copy the files into the target directory: - -@example -curl -L -O https://ftp.gnu.org/gnu/libtasn1/libtasn1-4.19.0.tar.gz -tar xvzf libtasn1-4.19.0.tar.gz -rm -rf grub-core/lib/libtasn1 -mkdir -p grub-core/lib/libtasn1/lib -mkdir -p grub-core/lib/libtasn1/tests -cp libtasn1-4.19.0/@{README.md,COPYING@} grub-core/lib/libtasn1 -cp libtasn1-4.19.0/lib/@{coding.c,decoding.c,element.c,element.h,errors.c,gstr.c,gstr.h,int.h,parser_aux.c,parser_aux.h,structure.c,structure.h@} grub-core/lib/libtasn1/lib -cp libtasn1-4.19.0/lib/includes/libtasn1.h grub-core/lib/libtasn1 -cp libtasn1-4.19.0/tests/@{CVE-2018-1000654-1_asn1_tab.h,CVE-2018-1000654-2_asn1_tab.h,CVE-2018-1000654.c,object-id-decoding.c,object-id-encoding.c,octet-string.c,reproducers.c,Test_overflow.c,Test_simple.c,Test_strings.c@} grub-core/lib/libtasn1/tests -rm -rf libtasn1-4.19.0* -@end example - -After upgrading the library, it may be necessary to apply the patches in -@file{grub-core/lib/libtasn1-patches/} to adjust the code to be compatible with -GRUB. These patches were needed to use the current version of libtasn1. The -existing patches may not apply cleanly, apply at all, or even be needed for a -newer version of the library, and other patches may be needed due to changes in -the newer version. If existing patches need to be refreshed to apply cleanly, -please include updated patches as part of the a patch set sent to the list. -If new patches are needed or existing patches are not needed, also please send -additions or removals as part of any patch set upgrading libtasn1. - -@node Debugging -@chapter Debugging - -GRUB2 can be difficult to debug because it runs on the bare-metal and thus -does not have the debugging facilities normally provided by an operating -system. This chapter aims to provide useful information on some ways to -debug GRUB2 for some architectures. It by no means intends to be exhaustive. -The focus will be one x86_64 and i386 architectures. Luckily for some issues -virtual machines have made the ability to debug GRUB2 much easier, and this -chapter will focus debugging via the QEMU virtual machine. We will not be -going over debugging of the userland tools (eg. grub-install), there are -many tutorials on debugging programs in userland. - -You will need GDB and the QEMU binaries for your system, on Debian these -can be installed with the @samp{gdb} and @samp{qemu-system-x86} packages. -Also it is assumed that you have already successfully compiled GRUB2 from -source for the target specified in the section below and have some -familiarity with GDB. When GRUB2 is built it will create many different -binaries. The ones of concern will be in the @file{grub-core} -directory of the GRUB2 build dir. To aide in debugging we will want the -debugging symbols generated during the build because these symbols are not -kept in the binaries which get installed to the boot location. The build -process outputs two sets of binaries, one without symbols which gets executed -at boot, and another set of ELF images with debugging symbols. The built -images with debugging symbols will have a @file{.image} suffix, and the ones -without a @file{.img} suffix. Similarly, loadable modules with debugging -symbols will have a @file{.module} suffix, and ones without a @file{.mod} -suffix. In the case of the kernel the binary with symbols is named -@file{kernel.exec}. - -In the following sections, information will be provided on debugging on -various targets using @command{gdb} and the @samp{gdb_grub} GDB script. - -@menu -* i386-pc:: -* x86_64-efi:: -@end menu - -@node i386-pc -@section i386-pc - -The i386-pc target is a good place to start when first debugging GRUB2 -because in some respects it's easier than EFI platforms. The reason being -that the initial load address is always known in advance. To start -debugging GRUB2 first QEMU must be started in GDB stub mode. The following -command is a simple illustration: - -@example -qemu-system-i386 -drive file=disk.img,format=raw \ - -device virtio-scsi-pci,id=scsi0 -S -s -@end example - -This will start a QEMU instance booting from @file{disk.img}. It will pause -at start waiting for a GDB instance to attach to it. You should change -@file{disk.img} to something more appropriate. A block device can be used, -but you may need to run QEMU as a privileged user. - -To connect to this QEMU instance with GDB, the @code{target remote} GDB -command must be used. We also need to load a binary image, preferably with -symbols. This can be done using the GDB command @code{file kernel.exec}, if -GDB is started from the @file{grub-core} directory in the GRUB2 build -directory. GRUB2 developers have made this more simple by including a GDB -script which does much of the setup. This file is at @file{grub-core/gdb_grub} -in the build directory and is also installed via @command{make install}. -When using a pre-built GRUB, the distribution may have a package which installs -this GDB script along with debug symbol binaries, such as Debian's -@samp{grub-pc-dbg} package. The GDB script is intended to be used -like so, assuming that @samp{/path/to/script} is the path to the directory -containing the gdb_grub script and debug symbol files: - -@example -cd $(dirname /path/to/script/gdb_grub) -gdb -x gdb_grub -@end example - -Once GDB has been started with the @file{gdb_grub} script it will -automatically connect to the QEMU instance. You can then do things you -normally would in GDB like set a break point on @var{grub_main}. - -Setting breakpoints in modules is trickier since they haven't been loaded -yet and are loaded at addresses determined at runtime. The module could be -loaded to different addresses in different QEMU instances. The debug symbols -in the modules @file{.module} binary, thus are always wrong, and GDB needs -to be told where to load the symbols to. But this must happen at runtime -after GRUB2 has determined where the module will get loaded. Luckily the -@file{gdb_grub} script takes care of this with the @command{runtime_load_module} -command, which configures GDB to watch for GRUB2 module loading and when -it does add the module symbols with the appropriate offset. - -@node x86_64-efi -@section x86_64-efi - -Using GDB to debug GRUB2 for the x86_64-efi target has some similarities with -the i386-pc target. Please read and familiarize yourself with the @ref{i386-pc} -section when reading this one. Extra care must be used to run QEMU such that it -boots a UEFI firmware. This usually involves either using the @samp{-bios} -option with a UEFI firmware blob (eg. @file{OVMF.fd}) or loading the firmware -via pflash. This document will not go further into how to do this as there are -ample resource on the web. - -Like all EFI implementations, on x86_64-efi the (U)EFI firmware that loads -the GRUB2 EFI application determines at runtime where the application will -be loaded. This means that we do not know where to tell GDB to load the -symbols for the GRUB2 core until the (U)EFI firmware determines it. There are -two good ways of figuring this out when running in QEMU: use a @ref{OVMF debug log, -debug build of OVMF} and check the debug log, or have GRUB2 say where it is -loaded. Neither of these are ideal because they both generally give the -information after GRUB2 is already running, which makes debugging early boot -infeasible. Technically, the first method does give the load address before -GRUB2 is run, but without debugging the EFI firmware with symbols, the author -currently does not know how to cause the OVMF firmware to pause at that point -to use the load address before GRUB2 is run. - -Even after getting the application load address, the loading of core symbols -is complicated by the fact that the debugging symbols for the kernel are in -an ELF binary named @file{kernel.exec} while what is in memory are sections -for the PE32+ EFI binary. When @command{grub-mkimage} creates the PE32+ -binary it condenses several segments from the ELF kernel binary into one -.data section in the PE32+ binary. This must be taken into account to -properly load the other non-text sections. Otherwise, GDB will work as -expected when breaking on functions, but, for instance, global variables -will point to the wrong address in memory and thus give incorrect values -(which can be difficult to debug). - -Calculating the correct offsets for sections is taken care of automatically -when loading the kernel symbols via the user-defined GDB command -@command{dynamic_load_kernel_exec_symbols}, which takes one argument, the -address where the text section is loaded as determined by one of the methods -above. Alternatively, the command @command{dynamic_load_symbols} with the text -section address as an agrument can be called to load the kernel symbols and set -up loading the module symbols as they are loaded at runtime. - -In the author's experience, when debugging with QEMU and OVMF, to have -debugging symbols loaded at the start of GRUB2 execution the GRUB2 EFI -application must be run via QEMU at least once prior in order to get the -load address. Two methods for obtaining the load address are described in -two subsections below. Generally speaking, the load address does not change -between QEMU runs. There are exceptions to this, namely that different -GRUB2 EFI applications can be run at different addresses. Also, it has been -observed that after running the EFI application for the first time, the -second run will sometimes have a different load address, but subsequent -runs of the same EFI application will have the same load address as the -second run. And it's a near certainty that if the GRUB EFI binary has changed, -eg. been recompiled, the load address will also be different. - -This ability to predict what the load address will be allows one to assume -the load address on subsequent runs and thus load the symbols before GRUB2 -starts. The following command illustrates this, assuming that QEMU is -running and waiting for a debugger connection and the current working -directory is where @file{gdb_grub} resides: - -@example -gdb -x gdb_grub -ex 'dynamic_load_symbols @var{address of .text section}' -@end example - -If you load the symbols in this manner and, after continuing execution, do -not see output showing the module symbols loading, then it is very likely -that the load address was incorrect. - -Another thing to be aware of is how the loading of the GRUB image by the -firmware affects previously set software breakpoints. On x86 platforms, -software breakpoints are implemented by GDB by writing a special processor -instruction at the location of the desired breakpoint. This special instruction -when executed will stop the program execution and hand control to the -debugger, GDB. GDB will first save the instruction bytes that are -overwritten at the breakpoint and will put them back when the breakpoint -is hit. If GRUB is being run for the first time in QEMU, the firmware will -be loading the GRUB image into memory where every byte is already set to 0. -This means that if a breakpoint is set before GRUB is loaded, GDB will save -the 0-byte(s) where the the special instruction will go. Then when the firmware -loads the GRUB image and because it is unaware of the debugger, it will -write the GRUB image to memory, overwriting anything that was there previously --- -notably in this case the instruction that implements the software breakpoint. -This will be confusing for the person using GDB because GDB will show the -breakpoint as set, but the brekapoint will never be hit. Furthermore, GDB -then becomes confused, such that even deleting an recreating the breakpoint -will not create usable breakpoints. The @file{gdb_grub} script takes care of -this by saving the breakpoints just before they are overwritten, and then -restores them at the start of GRUB execution. So breakpoints for GRUB can be -set before GRUB is loaded, but be mindful of this effect if you are confused -as to why breakpoints are not getting hit. - -Also note, that hardware breakpoints do not suffer this problem. They are -implemented by having the breakpoint address in special debug registers on -the CPU. So they can always be set freely without regard to whether GRUB has -been loaded or not. The reason that hardware breakpoints aren't always used -is because there are a limited number of them, usually around 4 on various -CPUs, and specifically exactly 4 for x86 CPUs. The @file{gdb_grub} script goes -out of its way to avoid using hardware breakpoints internally and uses them as -briefly as possible when needed, thus allowing the user to have a maximal -number at their disposal. - -@menu -* OVMF debug log:: -* Using the gdbinfo command:: -@end menu - -@node OVMF debug log -@subsection OVMF debug log - -In order to get the GRUB2 load address from OVMF, first, a debug build -of OVMF must be obtained (@uref{https://github.com/retrage/edk2-nightly/raw/master/bin/DEBUGX64_OVMF.fd, -here is one} which is not officially recommended). OVMF will output debug -messages to a special serial device, which we must add to QEMU. The following -QEMU command will run the debug OVMF and write the debug messages to a -file named @file{debug.log}. It is assumed that @file{disk.img} is a disk -image or block device that is set up to boot GRUB2 EFI. - -@example -qemu-system-x86_64 -bios /path/to/debug/OVMF.fd \ - -drive file=disk.img,format=raw \ - -device virtio-scsi-pci,id=scsi0 \ - -debugcon file:debug.log -global isa-debugcon.iobase=0x402 -@end example - -If GRUB2 was started by the (U)EFI firmware, then in the @file{debug.log} -file one of the last lines should be a log message like: -@samp{Loading driver at 0x00006AEE000 EntryPoint=0x00006AEE756}. This -means that the GRUB2 EFI application was loaded at @samp{0x00006AEE000} and -its .text section is at @samp{0x00006AEE756}. - -@node Using the gdbinfo command -@subsection Using the gdbinfo command - -On EFI platforms the command @command{gdbinfo} will output a string that -is to be run in a GDB session running with the @file{gdb_grub} GDB script. - - -@node Porting -@chapter Porting - -GRUB2 is designed to be easily portable accross platforms. But because of the -nature of bootloader every new port must be done separately. Here is how I did -MIPS (loongson and ARC) and Xen ports. Note than this is more of suggestions, -not absolute truth. - -First of all grab any architecture specifications you can find in public -(please avoid NDA). - -First stage is ``Hello world''. I've done it outside of GRUB for simplicity. -Your task is to have a small program which is loadable as bootloader and -clearly shows its presence to you. If you have easily accessible console -you can just print a message. If you have a mapped framebuffer you know address -of, you can draw a square. If you have a debug facility, just hanging without -crashing might be enough. For the first stage you can choose to load the -bootloader across the network since format for network image is often easier -than for local boot and it skips the need of small intermediary stages and -nvram handling. Additionally you can often have a good idea of the needed -format by running ``file'' on any netbootable executable for given platform. - -This program should probably have 2 parts: an assembler and C one. Assembler one -handles BSS cleaning and other needed setup (on some platforms you may need -to switch modes or copy the executable to its definitive position). So your code -may look like (x86 assembly for illustration purposes) - -@example - .globl _start -_start: - movl $_bss_start, %edi - movl $_end, %ecx - subl %edi, %ecx - xorl %eax, %eax - cld - rep - stosb - call main -@end example - -@example - -static const char msg[] = "Hello, world"; - -void -putchar (int c) -@{ - ... -@} - -void -main (void) -@{ - const char *ptr = msg; - while (*ptr) - putchar (*ptr++); - while (1); -@} -@end example - -Sometimes you need a third file: assembly stubs for ABI-compatibility. - -Once this file is functional it's time to move it into GRUB2. The startup -assembly file goes to grub-core/kern/$cpu/$platform/startup.S. You should also -include grub/symbol.h and replace call to entry point with call to -EXT_C(grub_main). The C file goes to grub-core/kern/$cpu/$platform/init.c -and its entry point is renamed to void grub_machine_init (void). Keep final -infinite loop for now. Stubs file if any goes to -grub-core/kern/$cpu/$platform/callwrap.S. Sometimes either $cpu or $platform -is dropped if file is used on several cpus respectivelyplatforms. -Check those locations if they already have what you're looking for. - -Then modify in configure.ac the following parts: - -CPU names: - -@example -case "$target_cpu" in - i[[3456]]86) target_cpu=i386 ;; - amd64) target_cpu=x86_64 ;; - sparc) target_cpu=sparc64 ;; - s390x) target_cpu=s390 ;; - ... -esac -@end example - -Sometimes CPU have additional architecture names which don't influence booting. -You might want to have some canonical name to avoid having bunch of identical -platforms with different names. - -NOTE: it doesn't influence compile optimisations which depend solely on -chosen compiler and compile options. - -@example -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 ;; - ... - esac -else - ... -fi -@end example - -This part deals with guessing the platform from CPU and vendor. Sometimes you -need to use 32-bit mode for booting even if OS runs in 64-bit one. If so add -your platform to: - -@example -case "$target_cpu"-"$platform" in - x86_64-efi) ;; - x86_64-emu) ;; - x86_64-*) target_cpu=i386 ;; - powerpc64-ieee1275) target_cpu=powerpc ;; -esac -@end example - -Add your platform to the list of supported ones: - -@example -case "$target_cpu"-"$platform" in - i386-efi) ;; - x86_64-efi) ;; - i386-pc) ;; - i386-multiboot) ;; - i386-coreboot) ;; - ... -esac -@end example - -If explicit -m32 or -m64 is needed add it to: - -@example -case "$target_cpu" in - i386 | powerpc) target_m32=1 ;; - x86_64 | sparc64) target_m64=1 ;; -esac -@end example - -Finally you need to add a conditional to the following block: - -@example -AM_CONDITIONAL([COND_mips_arc], [test x$target_cpu = xmips -a x$platform = xarc]) -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]) -@end example - -Next stop is gentpl.py. You need to add your platform to the list of supported -ones (sorry that this list is duplicated): - -@example -GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", - "i386_multiboot", "i386_ieee1275", "x86_64_efi", - "mips_loongson", "sparc64_ieee1275", - "powerpc_ieee1275", "mips_arc", "ia64_efi", - "mips_qemu_mips", "s390_mainframe" ] -@end example - -You may also want already to add new platform to one or several of available -groups. In particular we always have a group for each CPU even when only -one platform for given CPU is available. - -Then comes grub-core/Makefile.core.def. In the block ``kernel'' you'll need -to define ldflags for your platform ($cpu_$platform_ldflags). You also need to -declare startup asm file ($cpu_$platform_startup) as well as any other files -(e.g. init.c and callwrap.S) (e.g. $cpu_$platform = kern/$cpu/$platform/init.c). -At this stage you will also need to add dummy dl.c and cache.S with functions -grub_err_t grub_arch_dl_check_header (void *ehdr), grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) (dl.c) and -void grub_arch_sync_caches (void *address, grub_size_t len) (cache.S). They -won't be used for now. - -You will need to create directory include/$cpu/$platform and a file -include/$cpu/types.h. The latter following this template: - -@example -#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 - -/* mycpu is big-endian. */ -#define GRUB_TARGET_WORDS_BIGENDIAN 1 -/* Alternatively: mycpu is little-endian. */ -#undef GRUB_TARGET_WORDS_BIGENDIAN - -#endif /* ! GRUB_TYPES_CPU_HEADER */ -@end example - -You will also need to add a dummy file to datetime and setjmp modules to -avoid any of it having no files. It can be just completely empty at this stage. - -You'll need to make grub-mkimage.c (util/grub_mkimage.c) aware of the needed -format. For most commonly used formats like ELF, PE, aout or raw the support -is already present and you'll need to make it follow the existant code paths -for your platform adding adjustments if necessary. When done compile: - -@example -./bootstrap -./configure --target=$cpu --with-platform=$platform TARGET_CC=.. OBJCOPY=... STRIP=... -make > /dev/null -@end example - -And create image - -@example -./grub-mkimage -d grub-core -O $format_id -o test.img -@end example - -And it's time to test your test.img. - -If it works next stage is to have heap, console and timer. - -To have the heap working you need to determine which regions are suitable for -heap usage, allocate them from firmware and map (if applicable). Then call -grub_mm_init_region (void *start, grub_size_t s) for every of this region. -As a shortcut for early port you can allocate right after _end or have -a big static array for heap. If you do you'll probably need to come back to -this later. As for output console you should distinguish between an array of -text, terminfo or graphics-based console. Many of real-world examples don't -fit perfectly into any of these categories but one of the models is easier -to be used as base. In second and third case you should add your platform to -terminfokernel respectively videoinkernel group. A good example of array of -text is i386-pc (kern/i386/pc/init.c and term/i386/pc/console.c). -Of terminfo is ieee1275 (kern/ieee1275/init.c and term/ieee1275/console.c). -Of video is loongson (kern/mips/loongson/init.c). Note that terminfo has -to be inited in 2 stages: one before (to get at least rudimentary console -as early as possible) and another after the heap (to get full-featured console). -For the input there are string of keys, terminfo and direct hardware. For string -of keys look at i386-pc (same files), for terminfo ieee1275 (same files) and for -hardware loongson (kern/mips/loongson/init.c and term/at_keyboard.c). - -For the timer you'll need to call grub_install_get_time_ms (...) with as sole -argument a function returning a grub_uint64_t of a number of milliseconds -elapsed since arbitrary point in the past. - -Once these steps accomplished you can remove the inifinite loop and you should -be able to get to the minimal console. Next step is to have module loading -working. For this you'll need to fill kern/$cpu/dl.c and kern/$cpu/cache.S -with real handling of relocations and respectively the real sync of I and D -caches. Also you'll need to decide where in the image to store the modules. -Usual way is to have it concatenated at the end. In this case you'll need to -modify startup.S to copy modules out of bss to let's say ALIGN_UP (_end, 8) -before cleaning out bss. You'll probably find useful to add total_module_size -field to startup.S. In init.c you need to set grub_modbase to the address -where modules can be found. You may need grub_modules_get_end () to avoid -declaring the space occupied by modules as usable for heap. You can test modules -with: - -@example -./grub-mkimage -d grub-core -O $format_id -o test.img hello -@end example - -and then running ``hello'' in the shell. - -Once this works, you should think of implementing disk access. Look around -disk/ for examples. - -Then, very importantly, you probably need to implement the actual loader -(examples available in loader/) - -Last step to have minimally usable port is to add support to grub-install to -put GRUB in a place where firmware or platform will pick it up. - -Next steps are: filling datetime.c, setjmp.S, network (net/drivers), -video (video/), halt (lib/), reboot (lib/). - -Please add your platform to Platform limitations and Supported kernels chapter -in user documentation and mention any steps you skipped which result in reduced -features or performance. Here is the quick checklist of features. Some of them -are less important than others and skipping them is completely ok, just needs -to be mentioned in user documentation. - -Checklist: -@itemize -@item Is heap big enough? -@item Which charset is supported by console? -@item Does platform have disk driver? -@item Do you have network card support? -@item Are you able to retrieve datetime (with date)? -@item Are you able to set datetime (with date)? -@item Is serial supported? -@item Do you have direct disk support? -@item Do you have direct keyboard support? -@item Do you have USB support? -@item Do you support loading through network? -@item Do you support loading from disk? -@item Do you support chainloading? -@item Do you support network chainloading? -@item Does cpuid command supports checking all -CPU features that the user might want conditionalise on -(64-bit mode, hypervisor,...) -@item Do you support hints? How reliable are they? -@item Does platform have ACPI? If so do ``acpi'' and ``lsacpi'' modules work? -@item Do any of platform-specific operations mentioned in the relevant section of -user manual makes sense on your platform? -@item Does your platform support PCI? If so is there an appropriate driver for -GRUB? -@item Do you support badram? -@end itemize - -@node Error Handling -@chapter Error Handling - -Error handling in GRUB 2 is based on exception handling model. As C language -doesn't directly support exceptions, exception handling behavior is emulated -in software. - -When exception is raised, function must return to calling function. If calling -function does not provide handling of the exception it must return back to its -calling function and so on, until exception is handled. If exception is not -handled before prompt is displayed, error message will be shown to user. - -Exception information is stored on @code{grub_errno} global variable. If -@code{grub_errno} variable contains value @code{GRUB_ERR_NONE}, there is no active -exception and application can continue normal processing. When @code{grub_errno} has -other value, it is required that application code either handles this error or -returns instantly to caller. If function is with return type @code{grub_err_t} is -about to return @code{GRUB_ERR_NONE}, it should not set @code{grub_errno} to that -value. Only set @code{grub_errno} in cases where there is error situation. - -Simple exception forwarder. -@example -grub_err_t -forwarding_example (void) -@{ - /* Call function that might cause exception. */ - foobar (); - - /* No special exception handler, just forward possible exceptions. */ - if (grub_errno != GRUB_ERR_NONE) - @{ - return grub_errno; - @} - - /* All is OK, do more processing. */ - - /* Return OK signal, to caller. */ - return GRUB_ERR_NONE; -@} -@end example - -Error reporting has two components, the actual error code (of type -@code{grub_err_t}) and textual message that will be displayed to user. List of -valid error codes is listed in header file @file{include/grub/err.h}. Textual -error message can contain any textual data. At time of writing, error message -can contain up to 256 characters (including terminating NUL). To ease error -reporting there is a helper function @code{grub_error} that allows easier -formatting of error messages and should be used instead of writing directly to -global variables. - -Example of error reporting. -@example -grub_err_t -failing_example () -@{ - return grub_error (GRUB_ERR_FILE_NOT_FOUND, - "Failed to read %s, tried %d times.", - "test.txt", - 10); -@} -@end example - -If there is a special reason that error code does not need to be taken account, -@code{grub_errno} can be zeroed back to @code{GRUB_ERR_NONE}. In cases like this all -previous error codes should have been handled correctly. This makes sure that -there are no unhandled exceptions. - -Example of zeroing @code{grub_errno}. -@example -grub_err_t -probe_example () -@{ - /* Try to probe device type 1. */ - probe_for_device (); - if (grub_errno == GRUB_ERR_NONE) - @{ - /* Device type 1 was found on system. */ - register_device (); - return GRUB_ERR_NONE; - @} - /* Zero out error code. */ - grub_errno = GRUB_ERR_NONE; - - /* No device type 1 found, try to probe device type 2. */ - probe_for_device2 (); - if (grub_errno == GRUB_ERR_NONE) - @{ - /* Device type 2 was found on system. */ - register_device2 (); - return GRUB_ERR_NONE; - @} - /* Zero out error code. */ - grub_errno = GRUB_ERR_NONE; - - /* Return custom error message. */ - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No device type 1 or 2 found."); -@} -@end example - -Some times there is a need to continue processing even if there is a error -state in application. In situations like this, there is a needed to save old -error state and then call other functions that might fail. To aid in this, -there is a error stack implemented. Error state can be pushed to error stack -by calling function @code{grub_error_push ()}. When processing has been completed, -@code{grub_error_pop ()} can be used to pop error state from stack. Error stack -contains predefined amount of error stack items. Error stack is protected for -overflow and marks these situations so overflow error does not get unseen. -If there is no space available to store error message, it is simply discarded -and overflow will be marked as happened. When overflow happens, it most likely -will corrupt error stack consistency as for pushed error there is no matching -pop, but overflow message will be shown to inform user about the situation. -Overflow message will be shown at time when prompt is about to be drawn. - -Example usage of error stack. -@example -/* Save possible old error message. */ -grub_error_push (); - -/* Do your stuff here. */ -call_possibly_failing_function (); - -if (grub_errno != GRUB_ERR_NONE) - @{ - /* Inform rest of the code that there is error (grub_errno - is set). There is no pop here as we want both error states - to be displayed. */ - return; - @} - -/* Restore old error state by popping previous item from stack. */ -grub_error_pop (); -@end example - -@node Stack and heap size -@chapter Stack and heap size - -On emu stack and heap are just normal host OS stack and heap. Stack is typically -8 MiB although it's OS-dependent. - -On i386-pc, i386-coreboot, i386-qemu and i386-multiboot the stack is 60KiB. -All available space between 1MiB and 4GiB marks is part of heap. - -On *-xen stack is 4MiB. If compiled for x86-64 with GCC 4.4 or later addressable -space is unlimited. When compiled for x86-64 with older GCC version addressable -space is limited to 2GiB. When compiling for i386 addressable space is limited -to 4GiB. All addressable pages except the ones for stack, GRUB binary, special -pages and page table are in the heap. - -On *-efi GRUB uses same stack as EFI. If compiled for x86-64 with GCC 4.4 or -later addressable space is unlimited. When compiled for x86-64 with older GCC -version addressable space is limited to 2GiB. For all other platforms addressable -space is limited to 4GiB. GRUB allocates pages from EFI for its heap, at most -1.6 GiB. - -On i386-ieee1275 and powerpc-ieee1275 GRUB uses same stack as IEEE1275. - -On i386-ieee1275 and powerpc-ieee1275, GRUB will allocate 32MiB for its heap on -startup. It may allocate more at runtime, as long as at least 128MiB remain free -in OpenFirmware. - -On sparc64-ieee1275 stack is 256KiB and heap is 2MiB. - -On mips(el)-qemu_mips and mipsel-loongson stack is 2MiB (everything below -GRUB image) and everything above GRUB image (from 2MiB + kernel size) -until 256MiB is part of heap. - -On mips-arc stack is 2MiB (everything below GRUB image) and everything above -GRUB image(from 2MiB + kernel size) until 128MiB is part of heap. - -On mipsel-arc stack is 2MiB (everything below GRUB image which is not part -of ARC) and everything above GRUB image (from 7MiB + kernel size) -until 256MiB is part of heap. - -On arm-uboot stack is 256KiB and heap is 2MiB. - -In short: - -@multitable @columnfractions .15 .25 .5 -@headitem Platform @tab Stack @tab Heap -@item emu @tab 8 MiB @tab ? -@item i386-pc @tab 60 KiB @tab < 4 GiB -@item i386-coreboot @tab 60 KiB @tab < 4 GiB -@item i386-multiboot @tab 60 KiB @tab < 4 GiB -@item i386-qemu @tab 60 KiB @tab < 4 GiB -@item *-efi @tab ? @tab < 1.6 GiB -@item i386-ieee1275 @tab ? @tab < 32 MiB -@item powerpc-ieee1275 @tab ? @tab available memory - 128MiB -@item sparc64-ieee1275 @tab 256KiB @tab 2 MiB -@item arm-uboot @tab 256KiB @tab 2 MiB -@item mips(el)-qemu_mips @tab 2MiB @tab 253 MiB -@item mipsel-loongson @tab 2MiB @tab 253 MiB -@item mips-arc @tab 2MiB @tab 125 MiB -@item mipsel-arc @tab 2MiB @tab 248 MiB -@item x86_64-xen (GCC >= 4.4) @tab 4MiB @tab unlimited -@item x86_64-xen (GCC < 4.4) @tab 4MiB @tab < 2GiB -@item i386-xen @tab 4MiB @tab < 4GiB -@end multitable - - -@node BIOS port memory map -@chapter BIOS port memory map -@c By Yoshinori K Okuji - -@multitable @columnfractions .15 .25 .5 -@headitem Start @tab End @tab Usage -@item 0 @tab 0x1000 - 1 @tab BIOS and real mode interrupts -@item 0x07BE @tab 0x07FF @tab Partition table passed to another boot loader -@item ? @tab 0x2000 - 1 @tab Real mode stack -@item 0x7C00 @tab 0x7D00 - 1 @tab Boot sector -@item 0x8000 @tab ? @tab GRUB kernel -@item 0x68000 @tab 0x71000 - 1 @tab Disk buffer -@item ? @tab 0x80000 - 1 @tab Protected mode stack -@item ? @tab 0xA0000 - 1 @tab Extended BIOS Data Area -@item 0xA0000 @tab 0xC0000 - 1 @tab Video RAM -@item 0xC0000 @tab 0x100000 - 1 @tab BIOS -@item 0x100000 @tab ? @tab Heap and module code -@end multitable - -@node Video Subsystem -@chapter Video Subsystem -@c By VesaJääskeläinen -This document contains specification for Video Subsystem for GRUB2. -Currently only the usage interface is described in this document. -Internal structure of how video drivers are registering and how video -driver manager works are not included here. - -@menu -* Video API:: -* Example usage of Video API:: -* Bitmap API:: -@end menu - -@node Video API -@section Video API - -@subsection grub_video_setup - -@itemize -@item Prototype: -@example -grub_err_t -grub_video_setup (unsigned int width, unsigned int height, unsigned int mode_type); -@end example -@item Description: - -Driver will use information provided to it to select best possible video mode and switch to it. Supported values for @code{mode_type} are @code{GRUB_VIDEO_MODE_TYPE_INDEX_COLOR} for index color modes, @code{GRUB_VIDEO_MODE_TYPE_RGB} for direct RGB color modes and @code{GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED} for double buffering. When requesting RGB mode, highest bits per pixel mode will be selected. When requesting Index color mode, mode with highest number of colors will be selected. If all parameters are specified as zero, video adapter will try to figure out best possible mode and initialize it, platform specific differences are allowed here. If there is no mode matching request, error X will be returned. If there are no problems, function returns @code{GRUB_ERR_NONE}. - -This function also performs following task upon succesful mode switch. Active rendering target is changed to screen and viewport is maximized to allow whole screen to be used when performing graphics operations. In RGB modes, emulated palette gets 16 entries containing default values for VGA palette, other colors are defined as black. When switching to Indexed Color mode, driver may set default VGA palette to screen if the video card allows the operation. - -@end itemize - -@subsection grub_video_restore -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_restore (void); -@end example -@item Description: - -Video subsystem will deinitialize activated video driver to restore old state of video device. This can be used to switch back to text mode. -@end itemize - -@subsection grub_video_get_info -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_get_info (struct grub_video_mode_info *mode_info); -@end example -@example -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; -@}; -@end example -@item Description: - -Software developer can use this function to query properties of active rendering taget. Information provided here can be used by other parts of GRUB, like image loaders to convert loaded images to correct screen format to allow more optimized blitters to be used. If there there is no configured video driver with active screen, error @code{GRUB_ERR_BAD_DEVICE} is returned, otherwise @code{mode_info} is filled with valid information and @code{GRUB_ERR_NONE} is returned. -@end itemize - -@subsection grub_video_get_blit_format -@itemize -@item Prototype: - -@example -enum grub_video_blit_format -grub_video_get_blit_format (struct grub_video_mode_info *mode_info); -@end example -@example -enum grub_video_blit_format - @{ - /* Follow exactly field & mask information. */ - GRUB_VIDEO_BLIT_FORMAT_RGBA, - /* Make optimization assumption. */ - GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8, - /* Follow exactly field & mask information. */ - GRUB_VIDEO_BLIT_FORMAT_RGB, - /* Make optimization assumption. */ - GRUB_VIDEO_BLIT_FORMAT_R8G8B8, - /* When needed, decode color or just use value as is. */ - GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR - @}; -@end example -@item Description: - -Used to query how data could be optimized to suit specified video mode. Returns exact video format type, or a generic one if there is no definition for the type. For generic formats, use @code{grub_video_get_info} to query video color coding settings. -@end itemize - -@subsection grub_video_set_palette -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_set_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data); -@end example -@example -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). */ -@}; -@end example -@item Description: - -Used to setup indexed color palettes. If mode is RGB mode, colors will be set to emulated palette data. In Indexed Color modes, palettes will be set to hardware. Color values will be converted to suit requirements of the video mode. @code{start} will tell what hardware color index (or emulated color index) will be set to according information in first indice of @code{palette_data}, after that both hardware color index and @code{palette_data} index will be incremented until @code{count} number of colors have been set. -@end itemize - -@subsection grub_video_get_palette -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_get_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data); -@end example -@example -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). */ -@}; -@end example -@item Description: - -Used to query indexed color palettes. If mode is RGB mode, colors will be copied from emulated palette data. In Indexed Color modes, palettes will be read from hardware. Color values will be converted to suit structure format. @code{start} will tell what hardware color index (or emulated color index) will be used as a source for first indice of @code{palette_data}, after that both hardware color index and @code{palette_data} index will be incremented until @code{count} number of colors have been read. -@end itemize - -@subsection grub_video_set_area_status -@itemize - -@item Prototype: -@example -grub_err_t -grub_video_set_area_status (grub_video_area_status_t area_status); -@end example -@example -enum grub_video_area_status_t - @{ - GRUB_VIDEO_AREA_DISABLED, - GRUB_VIDEO_AREA_ENABLED - @}; -@end example - -@item Description: - -Used to set area drawing mode for redrawing the specified region. Draw commands -are performed in the intersection of the viewport and the region called area. -Coordinates remain related to the viewport. If draw commands try to draw over -the area, they are clipped. -Set status to DISABLED if you need to draw everything. -Set status to ENABLED and region to the desired rectangle to redraw everything -inside the region leaving everything else intact. -Should be used for redrawing of active elements. -@end itemize - -@subsection grub_video_get_area_status -@itemize - -@item Prototype: -@example -grub_err_r -grub_video_get_area_status (grub_video_area_status_t *area_status); -@end example - -@item Description: -Used to query the area status. -@end itemize - -@subsection grub_video_set_viewport -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_set_viewport (unsigned int x, unsigned int y, unsigned int width, unsigned int height); -@end example -@item Description: - -Used to specify viewport where draw commands are performed. When viewport is set, all draw commands coordinates relate to those specified by @code{x} and @code{y}. If draw commands try to draw over viewport, they are clipped. If developer requests larger than possible viewport, width and height will be clamped to fit screen. If @code{x} and @code{y} are out of bounds, all functions drawing to screen will not be displayed. In order to maximize viewport, use @code{grub_video_get_info} to query actual screen dimensions and provide that information to this function. -@end itemize - -@subsection grub_video_get_viewport -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_get_viewport (unsigned int *x, unsigned int *y, unsigned int *width, unsigned int *height); -@end example -@item Description: - -Used to query current viewport dimensions. Software developer can use this to choose best way to render contents of the viewport. -@end itemize - -@subsection grub_video_set_region -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_set_region (unsigned int x, unsigned int y, unsigned int width, unsigned int height); -@end example -@item Description: - -Used to specify the region of the screen which should be redrawn. Use absolute -values. When the region is set and area status is ENABLE all draw commands will -be performed inside the interseption of region and viewport named area. -If draw commands try to draw over viewport, they are clipped. If developer -requests larger than possible region, width and height will be clamped to fit -screen. Should be used for redrawing of active elements. -@end itemize - -@subsection grub_video_get_region -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_get_region (unsigned int *x, unsigned int *y, unsigned int *width, unsigned int *height); -@end example -@item Description: - -Used to query current region dimensions. -@end itemize - -@subsection grub_video_map_color -@itemize -@item Prototype: - -@example -grub_video_color_t -grub_video_map_color (grub_uint32_t color_name); -@end example -@item Description: - -Map color can be used to support color themes in GRUB. There will be collection of color names that can be used to query actual screen mapped color data. Examples could be @code{GRUB_COLOR_CONSOLE_BACKGROUND}, @code{GRUB_COLOR_CONSOLE_TEXT}. The actual color defines are not specified at this point. -@end itemize - -@subsection grub_video_map_rgb -@itemize -@item Prototype: - -@example -grub_video_color_t -grub_video_map_rgb (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue); -@end example -@item Description: - -Map RGB values to compatible screen color data. Values are expected to be in range 0-255 and in RGB modes they will be converted to screen color data. In index color modes, index color palette will be searched for specified color and then index is returned. -@end itemize - -@subsection grub_video_map_rgba -@itemize -@item Prototype: - -@example -grub_video_color_t -grub_video_map_rgba (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue, grub_uint8_t alpha); -@end example -@item Description: - -Map RGBA values to compatible screen color data. Values are expected to be in range 0-255. In RGBA modes they will be converted to screen color data. In index color modes, index color palette will be searched for best matching color and its index is returned. -@end itemize - -@subsection grub_video_unmap_color -@itemize -@item Prototype: - -@example -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); -@end example -@item Description: - -Unmap color value from @code{color} to color channels in @code{red}, @code{green}, @code{blue} and @code{alpha}. Values will be in range 0-255. Active rendering target will be used for color domain. In case alpha information is not available in rendering target, it is assumed to be opaque (having value 255). -@end itemize - -@subsection grub_video_fill_rect -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_fill_rect (grub_video_color_t color, int x, int y, unsigned int width, unsigned int height); -@end example -@item Description: - -Fill specified area limited by given coordinates within specified viewport. Negative coordinates are accepted in order to allow easy moving of rectangle within viewport. If coordinates are negative, area of the rectangle will be shrinken to follow size limits of the viewport. - -Software developer should use either @code{grub_video_map_color}, @code{grub_video_map_rgb} or @code{grub_video_map_rgba} to map requested color to @code{color} parameter. -@end itemize - -@subsection grub_video_blit_glyph -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_blit_glyph (struct grub_font_glyph *glyph, grub_video_color_t color, int x, int y); -@end example -@example -struct grub_font_glyph @{ - /* TBD. */ -@}; -@end example -@item Description: - -Used to blit glyph to viewport in specified coodinates. If glyph is at edge of viewport, pixels outside of viewport will be clipped out. Software developer should use either @code{grub_video_map_rgb} or @code{grub_video_map_rgba} to map requested color to @code{color} parameter. -@end itemize - -@subsection grub_video_blit_bitmap -@itemize -@item Prototype: - -@example -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); -@end example -@example -struct grub_video_bitmap -@{ - /* TBD. */ -@}; - -enum grub_video_blit_operators - @{ - GRUB_VIDEO_BLIT_REPLACE, - GRUB_VIDEO_BLIT_BLEND - @}; -@end example -@item Description: - -Used to blit bitmap to viewport in specified coordinates. If part of bitmap is outside of viewport region, it will be clipped out. Offsets affect bitmap position where data will be copied from. Negative values for both viewport coordinates and bitmap offset coordinates are allowed. If data is looked out of bounds of bitmap, color value will be assumed to be transparent. If viewport coordinates are negative, area of the blitted rectangle will be shrinken to follow size limits of the viewport and bitmap. Blitting operator @code{oper} specifies should source pixel replace data in screen or blend with pixel alpha value. - -Software developer should use @code{grub_video_bitmap_create} or @code{grub_video_bitmap_load} to create or load bitmap data. -@end itemize - -@subsection grub_video_blit_render_target -@itemize -@item Prototype: - -@example -grub_err_t -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); -@end example -@example -struct grub_video_render_target @{ - /* This is private data for video driver. Should not be accessed from elsewhere directly. */ -@}; - -enum grub_video_blit_operators - @{ - GRUB_VIDEO_BLIT_REPLACE, - GRUB_VIDEO_BLIT_BLEND - @}; -@end example -@item Description: - -Used to blit source render target to viewport in specified coordinates. If part of source render target is outside of viewport region, it will be clipped out. If blitting operator is specified and source contains alpha values, resulting pixel color components will be calculated using formula ((src_color * src_alpha) + (dst_color * (255 - src_alpha)) / 255, if target buffer has alpha, it will be set to src_alpha. Offsets affect render target position where data will be copied from. If data is looked out of bounds of render target, color value will be assumed to be transparent. Blitting operator @code{oper} specifies should source pixel replace data in screen or blend with pixel alpha value. -@end itemize - -@subsection grub_video_scroll -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_scroll (grub_video_color_t color, int dx, int dy); -@end example -@item Description: - -Used to scroll viewport to specified direction. New areas are filled with specified color. This function is used when screen is scroller up in video terminal. -@end itemize - -@subsection grub_video_swap_buffers -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_swap_buffers (void); -@end example -@item Description: - -If double buffering is enabled, this swaps frontbuffer and backbuffer, in order to show values drawn to back buffer. Video driver is free to choose how this operation is techincally done. -@end itemize - -@subsection grub_video_create_render_target -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_create_render_target (struct grub_video_render_target **result, unsigned int width, unsigned int height, unsigned int mode_type); -@end example -@example -struct grub_video_render_target @{ - /* This is private data for video driver. Should not be accessed from elsewhere directly. */ -@}; -@end example -@item Description: - -Driver will use information provided to it to create best fitting render target. @code{mode_type} will be used to guide on selecting what features are wanted for render target. Supported values for @code{mode_type} are @code{GRUB_VIDEO_MODE_TYPE_INDEX_COLOR} for index color modes, @code{GRUB_VIDEO_MODE_TYPE_RGB} for direct RGB color modes and @code{GRUB_VIDEO_MODE_TYPE_ALPHA} for alpha component. -@end itemize - -@subsection grub_video_delete_render_target -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_delete_render_target (struct grub_video_render_target *target); -@end example -@item Description: - -Used to delete previously created render target. If @code{target} contains @code{NULL} pointer, nothing will be done. If render target is correctly destroyed, GRUB_ERR_NONE is returned. -@end itemize - -@subsection grub_video_set_active_render_target -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_set_active_render_target (struct grub_video_render_target *target); -@end example -@item Description: - -Sets active render target. If this comand is successful all drawing commands will be done to specified @code{target}. There is also special values for target, @code{GRUB_VIDEO_RENDER_TARGET_DISPLAY} used to reference screen's front buffer, @code{GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER} used to reference screen's front buffer (alias for @code{GRUB_VIDEO_RENDER_TARGET_DISPLAY}) and @code{GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER} used to reference back buffer (if double buffering is enabled). If render target is correclty switched GRUB_ERR_NONE is returned. In no any event shall there be non drawable active render target. - -@end itemize -@subsection grub_video_get_active_render_target -@itemize -@item Prototype: - -@example -grub_err_t -grub_video_get_active_render_target (struct grub_video_render_target **target); -@end example -@item Description: - -Returns currently active render target. It returns value in @code{target} that can be subsequently issued back to @code{grub_video_set_active_render_target}. -@end itemize - -@node Example usage of Video API -@section Example usage of Video API -@subsection Example of screen setup -@example -grub_err_t rc; -/* Try to initialize video mode 1024 x 768 with direct RGB. */ -rc = grub_video_setup (1024, 768, GRUB_VIDEO_MODE_TYPE_RGB); -if (rc != GRUB_ERR_NONE) -@{ - /* Fall back to standard VGA Index Color mode. */ - rc = grub_video_setup (640, 480, GRUB_VIDEO_MODE_TYPE_INDEX); - if (rc != GRUB_ERR_NONE) - @{ - /* Handle error. */ - @} -@} -@end example -@subsection Example of setting up console viewport -@example -grub_uint32_t x, y, width, height; -grub_video_color_t color; -struct grub_font_glyph glyph; -grub_err_t rc; -/* Query existing viewport. */ -grub_video_get_viewport (&x, &y, &width, &height); -/* Fill background. */ -color = grub_video_map_color (GRUB_COLOR_BACKGROUND); -grub_video_fill_rect (color, 0, 0, width, height); -/* Setup console viewport. */ -grub_video_set_viewport (x + 10, y + 10, width - 20, height - 20); -grub_video_get_viewport (&x, &y, &width, &height); -color = grub_video_map_color (GRUB_COLOR_CONSOLE_BACKGROUND); -grub_video_fill_rect (color, 0, 0, width, height); -/* Draw text to viewport. */ -color = grub_video_map_color (GRUB_COLOR_CONSOLE_TEXT); -grub_font_get_glyph ('X', &glyph); -grub_video_blit_glyph (&glyph, color, 0, 0); -@end example - -@node Bitmap API -@section Bitmap API -@subsection grub_video_bitmap_create -@itemize -@item Prototype: -@example -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) -@end example - -@item Description: - -Creates a new bitmap with given dimensions and blitting format. Allocated bitmap data can then be modified freely and finally blitted with @code{grub_video_blit_bitmap} to rendering target. -@end itemize - -@subsection grub_video_bitmap_destroy -@itemize -@item Prototype: -@example -grub_err_t grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap); -@end example - -@item Description: - -When bitmap is no longer needed, it can be freed from memory using this command. @code{bitmap} is previously allocated bitmap with @code{grub_video_bitmap_create} or loaded with @code{grub_video_bitmap_load}. -@end itemize - -@subsection grub_video_bitmap_load -@itemize -@item Prototype: -@example -grub_err_t grub_video_bitmap_load (struct grub_video_bitmap **bitmap, const char *filename); -@end example - -@item Description: - -Tries to load given bitmap (@code{filename}) using registered bitmap loaders. In case bitmap format is not recognized or supported error @code{GRUB_ERR_BAD_FILE_TYPE} is returned. -@end itemize - -@subsection grub_video_bitmap_get_width -@itemize -@item Prototype: -@example -unsigned int grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap); -@end example - -@item Description: - -Returns bitmap width. -@end itemize - -@subsection grub_video_bitmap_get_height -@itemize -@item Prototype: -@example -unsigned int grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap); -@end example - -@item Description: - -Return bitmap height. -@end itemize - -@subsection grub_video_bitmap_get_mode_info -@itemize -@item Prototype: -@example -void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap, struct grub_video_mode_info *mode_info); -@end example - -@item Description: - -Returns bitmap format details in form of @code{grub_video_mode_info}. -@end itemize - -@subsection grub_video_bitmap_get_data -@itemize -@item Prototype: -@example -void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap); -@end example - -@item Description: - -Return pointer to bitmap data. Contents of the pointed data can be freely modified. There is no extra protection against going off the bounds so you have to be carefull how to access the data. -@end itemize - -@node PFF2 Font File Format -@chapter PFF2 Font File Format - -@c Author: Colin D. Bennett -@c Date: 8 January 2009 - -@menu -* Introduction:: -* File Structure:: -* Font Metrics:: -@end menu - - -@node Introduction -@section Introduction - -The goal of this format is to provide a bitmap font format that is simple to -use, compact, and cleanly supports Unicode. - - -@subsection Goals of the GRUB Font Format - -@itemize -@item Simple to read and use. -Since GRUB will only be reading the font files, -we are more concerned with making the code to read the font simple than we -are with writing the font. - -@item Compact storage. -The fonts will generally be stored in a small boot -partition where GRUB is located, and this may be on a removable storage -device such as a CD or USB flash drive where space is more limited than it -is on most hard drives. - -@item Unicode. -GRUB should not have to deal with multiple character -encodings. The font should always use Unicode character codes for simple -internationalization. -@end itemize - -@subsection Why Another Font Format? - -There are many existing bitmap font formats that GRUB could use. However, -there are aspects of these formats that may make them less than suitable for -use in GRUB at this time: - -@table @samp -@item BDF -Inefficient storage; uses ASCII to describe properties and -hexadecimal numbers in ASCII for the bitmap rows. -@item PCF -Many format variations such as byte order and bitmap padding (rows -padded to byte, word, etc.) would result in more complex code to -handle the font format. -@end table - -@node File Structure -@section File Structure - -A file @strong{section} consists of a 4-byte name, a 32-bit big-endian length (not -including the name or length), and then @var{length} more section-type-specific -bytes. - -The standard file extension for PFF2 font files is @file{.pf2}. - - -@subsection Section Types - -@table @samp -@item FILE -@strong{File type ID} (ASCII string). This must be the first section in the file. It has length 4 -and the contents are the four bytes of the ASCII string @samp{PFF2}. - -@item NAME -@strong{Font name} (ASCII string). This is the full font name including family, -weight, style, and point size. For instance, "Helvetica Bold Italic 14". - -@item FAMI -@strong{Font family name} (ASCII string). For instance, "Helvetica". This should -be included so that intelligent font substitution can take place. - -@item WEIG -@strong{Font weight} (ASCII string). Valid values are @samp{bold} and @samp{normal}. -This should be included so that intelligent font substitution can take -place. - -@item SLAN -@strong{Font slant} (ASCII string). Valid values are @samp{italic} and @samp{normal}. -This should be included so that intelligent font substitution can take -place. - -@item PTSZ -@strong{Font point size} (uint16be). - -@item MAXW -@strong{Maximum character width in pixels} (uint16be). - -@item MAXH -@strong{Maximum character height in pixels} (uint16be). - -@item ASCE -@strong{Ascent in pixels} (uint16be). @xref{Font Metrics}, for details. - -@item DESC -@strong{Descent in pixels} (uint16be). @xref{Font Metrics}, for details. - -@item CHIX -@strong{Character index.} -The character index begins with a 32-bit big-endian unsigned integer -indicating the total size of the section, not including this size value. -For each character, there is an instance of the following entry structure: - -@itemize -@item @strong{Unicode code point.} (32-bit big-endian integer.) - -@item @strong{Storage flags.} (byte.) - -@itemize -@item Bits 2..0: - -If equal to 000 binary, then the character data is stored -uncompressed beginning at the offset indicated by the character's -@strong{offset} value. - -If equal to 001 binary, then the character data is stored within a -compressed character definition block that begins at the offset -within the file indicated by the character's @strong{offset} value. -@end itemize - -@item @strong{Offset.} (32-bit big-endian integer.) - -A marker that indicates the remainder of the file is data accessed via -the character index (CHIX) section. When reading this font file, the rest -of the file can be ignored when scanning the sections. The length should -be set to -1 (0xFFFFFFFF). - -Supported data structures: - -Character definition -Each character definition consists of: - -@itemize -@item @strong{Width.} -Width of the bitmap in pixels. The bitmap's extents -represent the glyph's bounding box. @code{uint16be}. - -@item @strong{Height.} -Height of the bitmap in pixels. The bitmap's extents -represent the glyph's bounding box. @code{uint16be}. - -@item @strong{X offset.} -The number of pixels to shift the bitmap by -horizontally before drawing the character. @code{int16be}. - -@item @strong{Y offset.} -The number of pixels to shift the bitmap by -vertically before drawing the character. @code{int16be}. - -@item @strong{Device width.} -The number of pixels to advance horizontally from -this character's origin to the origin of the next character. -@code{int16be}. - -@item @strong{Bitmap data.} -This is encoded as a string of bits. It is -organized as a row-major, top-down, left-to-right bitmap. The most -significant bit of each byte is taken to be the leftmost or uppermost -bit in the byte. For the sake of compact storage, rows are not padded -to byte boundaries (i.e., a single byte may contain bits belonging to -multiple rows). The last byte of the bitmap @strong{is} padded with zero -bits in the bits positions to the right of the last used bit if the -bitmap data does not fill the last byte. - -The length of the @strong{bitmap data} field is (@var{width} * @var{height} + 7) / 8 -using integer arithmetic, which is equivalent to ceil(@var{width} * -@var{height} / 8) using real number arithmetic. - -It remains to be determined whether bitmap fonts usually make all -glyph bitmaps the same height, or if smaller glyphs are stored with -bitmaps having a lesser height. In the latter case, the baseline -would have to be used to calculate the location the bitmap should be -anchored at on screen. -@end itemize - -@end itemize -@end table - -@node Font Metrics -@section Font Metrics - -@itemize -@item Ascent. -The distance from the baseline to the top of most characters. -Note that in some cases characters may extend above the ascent. - -@item Descent. -The distance from the baseline to the bottom of most characters. Note that -in some cases characters may extend below the descent. - -@item Leading. -The amount of space, in pixels, to leave between the descent of one line of -text and the ascent of the next line. This metrics is not specified in the -current file format; instead, the font rendering engine calculates a -reasonable leading value based on the other font metrics. - -@item Horizonal leading. -The amount of space, in pixels, to leave horizontally between the left and -right edges of two adjacent glyphs. The @strong{device width} field determines -the effective leading value that is used to render the font. - -@end itemize -@ifnottex -@image{font_char_metrics,,,,.png} -@end ifnottex - -An illustration of how the various font metrics apply to characters. - - - -@node Graphical Menu Software Design -@chapter Graphical Menu Software Design - -@c By Colin D. Bennett -@c Date: 17 August 2008 - -@menu -* Introduction_2:: -* Startup Sequence:: -* GUI Components:: -* Command Line Window:: -@end menu - -@node Introduction_2 -@section Introduction - -The @samp{gfxmenu} module provides a graphical menu interface for GRUB 2. It -functions as an alternative to the menu interface provided by the @samp{normal} -module, which uses the grub terminal interface to display a menu on a -character-oriented terminal. - -The graphical menu uses the GRUB video API, which is currently for the VESA -BIOS extensions (VBE) 2.0+. This is supported on the i386-pc platform. -However, the graphical menu itself does not depend on using VBE, so if another -GRUB video driver were implemented, the @samp{gfxmenu} graphical menu would work -on the new video driver as well. - - -@node Startup Sequence -@section Startup Sequence - -@itemize -@item grub_enter_normal_mode [normal/main.c] -@item grub_normal_execute [normal/main.c] -@item read_config_file [normal/main.c] -@item (When @file{gfxmenu.mod} is loaded with @command{insmod}, it will call @code{grub_menu_viewer_register()} to register itself.) -@item GRUB_MOD_INIT (gfxmenu) [gfxmenu/gfxmenu.c] -@item grub_menu_viewer_register [kern/menu_viewer.c] -@item grub_menu_viewer_show_menu [kern/menu_viewer.c] -@item get_current_menu_viewer() [kern/menu_viewer.c] -@item show_menu() [gfxmenu/gfxmenu.c] -@item grub_gfxmenu_model_new [gfxmenu/model.c] -@item grub_gfxmenu_view_new [gfxmenu/view.c] -@item set_graphics_mode [gfxmenu/view.c] -@item grub_gfxmenu_view_load_theme [gfxmenu/theme_loader.c] -@end itemize - - -@node GUI Components -@section GUI Components - -The graphical menu implements a GUI component system that supports a -container-based layout system. Components can be added to containers, and -containers (which are a type of component) can then be added to other -containers, to form a tree of components. Currently, the root component of -this tree is a @samp{canvas} component, which allows manual layout of its child -components. - -Components (non-container): - -@itemize -@item label -@item image -@item progress_bar -@item circular_progress -@item list (currently hard coded to be a boot menu list) -@end itemize - -Containers: - -@itemize -@item canvas -@item hbox -@item vbox -@end itemize - -The GUI component instances are created by the theme loader in -@file{gfxmenu/theme_loader.c} when a theme is loaded. Theme files specify -statements such as @samp{+vbox@{ +label @{ text="Hello" @} +label@{ text="World" @} @}} -to add components to the component tree root. By nesting the component -creation statements in the theme file, the instantiated components are nested -the same way. - -When a component is added to a container, that new child is considered @strong{owned} -by the container. Great care should be taken if the caller retains a -reference to the child component, since it will be destroyed if its parent -container is destroyed. A better choice instead of storing a pointer to the -child component is to use the component ID to find the desired component. -Component IDs do not have to be unique (it is often useful to have multiple -components with an ID of "__timeout__", for instance). - -In order to access and use components in the component tree, there are two -functions (defined in @file{gfxmenu/gui_util.c}) that are particularly useful: - -@itemize - -@item @code{grub_gui_find_by_id (root, id, callback, userdata)}: - -This function recursively traverses the component tree rooted at @var{root}, and -for every component that has an ID equal to @var{id}, calls the function pointed -to by @var{callback} with the matching component and the void pointer @var{userdata} -as arguments. The callback function can do whatever is desired to use the -component passed in. - -@item @code{grub_gui_iterate_recursively (root, callback, userdata)}: - -This function calls the function pointed to by @var{callback} for every -component that is a descendant of @var{root} in the component tree. When the -callback function is called, the component and the void pointer @var{userdata} -as arguments. The callback function can do whatever is desired to use the -component passed in. -@end itemize - -@node Command Line Window -@section Command Line Window - -The terminal window used to provide command line access within the graphical -menu is managed by @file{gfxmenu/view.c}. The @samp{gfxterm} terminal is used, and -it has been modified to allow rendering to an offscreen render target to allow -it to be composed into the double buffering system that the graphical menu -view uses. This is bad for performance, however, so it would probably be a -good idea to make it possible to temporarily disable double buffering as long -as the terminal window is visible. There are still unresolved problems that -occur when commands are executed from the terminal window that change the -graphics mode. It's possible that making @code{grub_video_restore()} return to -the graphics mode that was in use before @code{grub_video_setup()} was called -might fix some of the problems. - - -@node Verifiers framework -@chapter Verifiers framework - -To register your own verifier call @samp{grub_verifier_register} with a structure -pointing to your functions. - -The interface is inspired by the hash interface with @samp{init}/@samp{write}/@samp{fini}. - -There are essentially 2 ways of using it, hashing and whole-file verification. - -With the hashing approach: -During @samp{init} you decide whether you want to check the given file and init context. -In @samp{write} you update your hashing state. -In @samp{fini} you check that the hash matches the expected value/passes some check/... - -With whole-file verification: -During @samp{init} you decide whether you want to check the given file and init context. -In @samp{write} you verify the file and return an error if it fails. -You don't have @samp{fini}. - -Additional @samp{verify_string} receives various strings like kernel parameters -to verify. Returning no error means successful verification and an error stops -the current action. - -Detailed description of the API: - -Every time a file is opened your @samp{init} function is called with file descriptor -and file type. Your function can have the following outcomes: - -@itemize - -@item returning no error and setting @samp{*flags} to @samp{GRUB_VERIFY_FLAGS_DEFER_AUTH}. -In this case verification is deferred to other active verifiers. Verification -fails if nobody cares or selected verifier fails. - -@item returning no error and setting @samp{*flags} to @samp{GRUB_VERIFY_FLAGS_SKIP_VERIFICATION}. -In this case your verifier will not be called anymore and it is assumed to have -skipped verification. - -@item returning no error and not setting @samp{*flags} to @samp{GRUB_VERIFY_FLAGS_SKIP_VERIFICATION} -In this case verification is done as described in the following section. - -@item returning an error. Then opening of the file will fail due to failed verification. - -@end itemize - -In the third case your @samp{write} will be called with chunks of the file. If -you need the whole file in a single chunk then during @samp{init} set the bit -@samp{GRUB_VERIFY_FLAGS_SINGLE_CHUNK} in @samp{*flags}. During @samp{init} you -may set @samp{*context} if you need additional context. At every iteration you -may return an error and the file will be considered as having failed the -verification. If you return no error then verification continues. - -Optionally at the end of the file @samp{fini}, if it exists, is called with just -the context. If you return no error during any of @samp{init}, @samp{write} and -@samp{fini} then the file is considered as having succeded verification. - -@node Lockdown framework -@chapter Lockdown framework - -The GRUB can be locked down, which is a restricted mode where some operations -are not allowed. For instance, some commands cannot be used when the GRUB is -locked down. - -The function -@code{grub_lockdown()} is used to lockdown GRUB and the function -@code{grub_is_lockdown()} function can be used to check whether lockdown is -enabled or not. When enabled, the function returns @samp{GRUB_LOCKDOWN_ENABLED} -and @samp{GRUB_LOCKDOWN_DISABLED} when is not enabled. - -The following functions can be used to register the commands that can only be -used when lockdown is disabled: - -@itemize - -@item @code{grub_cmd_lockdown()} registers command which should not run when the -GRUB is in lockdown mode. - -@item @code{grub_cmd_lockdown()} registers extended command which should not run -when the GRUB is in lockdown mode. - -@end itemize - -@node Copying This Manual -@appendix Copying This Manual - -@menu -* GNU Free Documentation License:: License for copying this manual. -@end menu - -@include fdl.texi - - -@node Index -@unnumbered Index - -@c Currently, we use only the Concept Index. -@printindex cp - -@bye diff --git a/docs/grub.cfg b/docs/grub.cfg index dc184d7d9..e14cdb776 100644 --- a/docs/grub.cfg +++ b/docs/grub.cfg @@ -5,22 +5,15 @@ # Boot automatically after 30 secs. set timeout=30 -# By default, boot the GNU/Linux -set default=gnulinux +# By default, boot the first entry. +set default=0 -# Fallback to GNU/Hurd. -set fallback=gnuhurd - -# For booting GNU/Linux -menuentry "GNU/Linux" --id gnulinux { - set root=(hd0,msdos1) - linux /vmlinuz root=/dev/sda1 - initrd /initrd.img -} +# Fallback to the second entry. +set fallback=1 # For booting GNU/Hurd -menuentry "GNU (aka GNU/Hurd)" --id gnuhurd { - set root=(hd0,msdos1) +menuentry "GNU (aka GNU/Hurd)" { + set root=(hd0,1) multiboot /boot/gnumach.gz root=device:hd0s1 module /hurd/ext2fs.static ext2fs --readonly \ --multiboot-command-line='${kernel-command-line}' \ @@ -31,35 +24,41 @@ menuentry "GNU (aka GNU/Hurd)" --id gnuhurd { module /lib/ld.so.1 exec /hurd/exec '$(exec-task=task-create)' } +# For booting GNU/Linux +menuentry "GNU/Linux" { + set root=(hd0,1) + linux /vmlinuz root=/dev/sda1 + initrd /initrd.img +} + # For booting FreeBSD menuentry "FreeBSD (or GNU/kFreeBSD), direct boot" { - set root=(hd0,msdos1,bsd1) + set root=(hd0,1,a) kfreebsd /boot/kernel/kernel kfreebsd_loadenv /boot/device.hints kfreebsd_module /boot/splash.bmp type=splash_image_data set kFreeBSD.vfs.root.mountfrom=ufs:ad0s1a } - menuentry "FreeBSD (or GNU/kFreeBSD), via /boot/loader" { - set root=(hd0,msdos1,bsd1) + set root=(hd0,1,a) kfreebsd /boot/loader } # For booting NetBSD menuentry "NetBSD" { - set root=(hd0,netbsd1) + set root=(hd0,1,a) knetbsd /netbsd } # For booting OpenBSD menuentry "OpenBSD" { - set root=(hd0,openbsd1) + set root=(hd0,1,a) kopenbsd /bsd } # For booting Microsoft Windows menuentry "Microsoft Windows" { - set root=(hd0,msdos1) + set root=(hd0,1) chainloader +1 } diff --git a/docs/grub.texi b/docs/grub.texi index 34b3484dc..f8a9bc414 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -20,7 +20,7 @@ This manual is for GNU GRUB (version @value{VERSION}, @value{UPDATED}). -Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. +Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document @@ -34,13 +34,9 @@ Invariant Sections. @direntry * GRUB: (grub). The GRand Unified Bootloader * grub-install: (grub)Invoking grub-install. Install GRUB on your drive -* grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration -* grub-mkpasswd-pbkdf2: (grub)Invoking grub-mkpasswd-pbkdf2. -* grub-mkrelpath: (grub)Invoking grub-mkrelpath. -* grub-mkrescue: (grub)Invoking grub-mkrescue. Make a GRUB rescue image -* grub-mount: (grub)Invoking grub-mount. Mount a file system using GRUB -* grub-probe: (grub)Invoking grub-probe. Probe device information -* grub-script-check: (grub)Invoking grub-script-check. +* grub-terminfo: (grub)Invoking grub-terminfo. Generate a terminfo + command from a + terminfo name @end direntry @setchapternewpage odd @@ -51,8 +47,6 @@ Invariant Sections. @subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}. @author Gordon Matzigkeit @author Yoshinori K. Okuji -@author Colin Watson -@author Colin D. Bennett @c The following two commands start the copyright page. @page @vskip 0pt plus 1filll @@ -81,33 +75,24 @@ This edition documents version @value{VERSION}. @menu * Introduction:: Capturing the spirit of GRUB * Naming convention:: Names of your drives in GRUB -* OS-specific notes about grub tools:: - Some notes about OS-specific behaviour of GRUB - tools * Installation:: Installing GRUB on your drive * Booting:: How to boot different operating systems * Configuration:: Writing your own configuration file -* Theme file format:: Format of GRUB theme files * Network:: Downloading OS images from a network * Serial terminal:: Using GRUB via a serial line -* Vendor power-on keys:: Changing GRUB behaviour on vendor power-on keys +* Preset Menu:: Embedding a configuration file into GRUB * Images:: GRUB image files -* Core image size limitation:: GRUB image files size limitations * Filesystem:: Filesystem syntax and semantics * Interface:: The menu and the command-line -* Environment:: GRUB environment variables -* Modules:: Available modules -* Commands:: Available builtin commands -* Internationalisation:: Topics relating to language support -* Security:: Authentication, authorisation, and signatures -* Platform limitations:: Platform-specific limitations -* Platform-specific operations:: Platform-specific operations -* Supported kernels:: Supported kernels +* Commands:: The list of available builtin commands * Troubleshooting:: Error messages produced by GRUB -* User-space utilities:: Usage of user-space utilities +* Invoking the grub shell:: How to use the grub shell +* Invoking grub-install:: How to use the GRUB installer +* Invoking grub-terminfo:: How to generate a terminfo command * Obtaining and Building GRUB:: How to obtain and build GRUB * Reporting bugs:: Where you should send a bug report * Future:: Some future plans on GRUB +* Internals:: Hacking GRUB * Copying This Manual:: Copying This Manual * Index:: @end menu @@ -119,7 +104,6 @@ This edition documents version @value{VERSION}. @menu * Overview:: What exactly GRUB is and how to use it * History:: From maggot to house fly -* Changes from GRUB Legacy:: Differences from previous versions * Features:: GRUB features * Role of a boot loader:: The role of a boot loader @end menu @@ -188,91 +172,6 @@ official GNU package, and opened its development by making the latest sources available via anonymous CVS. @xref{Obtaining and Building GRUB}, for more information. -Over the next few years, GRUB was extended to meet many needs, but it -quickly became clear that its design was not keeping up with the extensions -being made to it, and we reached the point where it was very difficult to -make any further changes without breaking existing features. Around 2002, -Yoshinori K. Okuji started work on PUPA (Preliminary Universal Programming -Architecture for GNU GRUB), aiming to rewrite the core of GRUB to make it -cleaner, safer, more robust, and more powerful. PUPA was eventually renamed -to GRUB 2, and the original version of GRUB was renamed to GRUB Legacy. -Small amounts of maintenance continued to be done on GRUB Legacy, but the -last release (0.97) was made in 2005 and at the time of writing it seems -unlikely that there will be another. - -By around 2007, GNU/Linux distributions started to use GRUB 2 to limited -extents, and by the end of 2009 multiple major distributions were installing -it by default. - - -@node Changes from GRUB Legacy -@section Differences from previous versions - -GRUB 2 is a rewrite of GRUB (@pxref{History}), although it shares many -characteristics with the previous version, now known as GRUB Legacy. Users -of GRUB Legacy may need some guidance to find their way around this new -version. - -@itemize @bullet -@item -The configuration file has a new name (@file{grub.cfg} rather than -@file{menu.lst} or @file{grub.conf}), new syntax (@pxref{Configuration}) and -many new commands (@pxref{Commands}). Configuration cannot be copied over -directly, although most GRUB Legacy users should not find the syntax too -surprising. - -@item -@file{grub.cfg} is typically automatically generated by -@command{grub-mkconfig} (@pxref{Simple configuration}). This makes it -easier to handle versioned kernel upgrades. - -@item -Partition numbers in GRUB device names now start at 1, not 0 (@pxref{Naming -convention}). - -@item -The configuration file is now written in something closer to a full -scripting language: variables, conditionals, and loops are available. - -@item -A small amount of persistent storage is available across reboots, using the -@command{save_env} and @command{load_env} commands in GRUB and the -@command{grub-editenv} utility. This is not available in all configurations -(@pxref{Environment block}). - -@item -GRUB 2 has more reliable ways to find its own files and those of target -kernels on multiple-disk systems, and has commands (@pxref{search}) to find -devices using file system labels or Universally Unique Identifiers (UUIDs). - -@item -GRUB 2 is available for several other types of system in addition to the PC -BIOS systems supported by GRUB Legacy: PC EFI, PC coreboot, PowerPC, SPARC, -and MIPS Lemote Yeeloong are all supported. - -@item -Many more file systems are supported, including but not limited to ext4, -HFS+, and NTFS. - -@item -GRUB 2 can read files directly from LVM and RAID devices. - -@item -A graphical terminal and a graphical menu system are available. - -@item -GRUB 2's interface can be translated, including menu entry names. - -@item -The image files (@pxref{Images}) that make up GRUB have been reorganised; -Stage 1, Stage 1.5, and Stage 2 are no more. - -@item -GRUB 2 puts many facilities in dynamically loaded modules, allowing the core -image to be smaller, and allowing the core image to be built in more -flexible ways. -@end itemize - @node Features @section GRUB features @@ -314,10 +213,8 @@ tables are also loaded. @item Support non-Multiboot kernels Support many of the various free 32-bit kernels that lack Multiboot -compliance (primarily FreeBSD, NetBSD@footnote{The NetBSD/i386 kernel -is Multiboot-compliant, but lacks support for Multiboot modules.}, -OpenBSD, and Linux). Chain-loading of other boot loaders is also -supported. +compliance (primarily FreeBSD, NetBSD, OpenBSD, and +Linux). Chain-loading of other boot loaders is also supported. @item Load multiples modules Fully support the Multiboot feature of loading multiple modules. @@ -349,29 +246,15 @@ devices, partitions, and files in a directory depending on context. @item Support multiple filesystem types Support multiple filesystem types transparently, plus a useful explicit -blocklist notation. The currently supported filesystem types are @dfn{Amiga -Fast FileSystem (AFFS)}, @dfn{AtheOS fs}, @dfn{BeFS}, -@dfn{BtrFS} (including raid0, raid1, raid10, gzip and lzo), -@dfn{cpio} (little- and big-endian bin, odc and newc variants), -@dfn{EROFS} (only uncompressed support for now), -@dfn{Linux ext2/ext3/ext4}, @dfn{DOS FAT12/FAT16/FAT32}, -@dfn{exFAT}, @dfn{F2FS}, @dfn{HFS}, @dfn{HFS+}, -@dfn{ISO9660} (including Joliet, Rock-ridge and multi-chunk files), -@dfn{JFS}, @dfn{Minix fs} (versions 1, 2 and 3), @dfn{nilfs2}, -@dfn{NTFS} (including compression), @dfn{ReiserFS}, @dfn{ROMFS}, -@dfn{Amiga Smart FileSystem (SFS)}, @dfn{Squash4}, @dfn{tar}, @dfn{UDF}, -@dfn{BSD UFS/UFS2}, @dfn{XFS}, and @dfn{ZFS} (including lzjb, gzip, -zle, mirror, stripe, raidz1/2/3 and encryption in AES-CCM and AES-GCM). -@xref{Filesystem}, for more information. -Note: Only a subset of filesystems are supported in lockdown mode (such -as when secure boot is enabled, @pxref{Lockdown} for more information). +blocklist notation. The currently supported filesystem types are +@dfn{BSD FFS}, @dfn{DOS FAT16 and FAT32}, @dfn{Minix fs}, @dfn{Linux +ext2fs}, @dfn{ReiserFS}, @dfn{JFS}, @dfn{XFS}, and @dfn{VSTa +fs}. @xref{Filesystem}, for more information. @item Support automatic decompression -Can decompress files which were compressed by @command{gzip} or -@command{xz}@footnote{Only CRC32 data integrity check is supported (xz default -is CRC64 so one should use --check=crc32 option). LZMA BCJ filters are -supported.}. This function is both automatic and transparent to the user -(i.e. all functions operate upon the uncompressed contents of the specified +Can decompress files which were compressed by @command{gzip}. This +function is both automatic and transparent to the user (i.e. all +functions operate upon the uncompressed contents of the specified files). This greatly reduces a file size and loading time, a particularly great benefit for floppies.@footnote{There are a few pathological cases where loading a very badly organized ELF kernel might @@ -473,13 +356,12 @@ disk. The number @samp{0} is the drive number, which is counted from disk. @example -(hd0,msdos2) +(hd0,2) @end example Here, @samp{hd} means it is a hard disk drive. The first integer -@samp{0} indicates the drive number, that is, the first hard disk, -the string @samp{msdos} indicates the partition scheme, while -the second integer, @samp{2}, indicates the partition number (or the +@samp{0} indicates the drive number, that is, the first hard disk, while +the second integer, @samp{1}, indicates the partition number (or the @sc{pc} slice number in the BSD terminology). The partition numbers are counted from @emph{one}, not from zero (as was the case in previous versions of GRUB). This expression means the second partition of the @@ -487,7 +369,7 @@ first hard disk drive. In this case, GRUB uses one partition of the disk, instead of the whole disk. @example -(hd0,msdos5) +(hd0,5) @end example This specifies the first @dfn{extended partition} of the first hard disk @@ -496,21 +378,24 @@ counted from @samp{5}, regardless of the actual number of primary partitions on your hard disk. @example -(hd1,msdos1,bsd1) +(hd1,a) @end example -This means the BSD @samp{a} partition on first @sc{pc} slice number -of the second hard disk. +This means the BSD @samp{a} partition of the second hard disk. If you +need to specify which @sc{pc} slice number should be used, use something +like this: @samp{(hd1,1,a)}. If the @sc{pc} slice number is omitted, +GRUB searches for the first @sc{pc} slice which has a BSD @samp{a} +partition. Of course, to actually access the disks or partitions with GRUB, you -need to use the device specification in a command, like @samp{set -root=(fd0)} or @samp{parttool (hd0,msdos3) hidden-}. To help you find out -which number specifies a partition you want, the GRUB command-line +need to use the device specification in a command, like @samp{root +(fd0)} or @samp{unhide (hd0,3)}. To help you find out which number +specifies a partition you want, the GRUB command-line (@pxref{Command-line interface}) options have argument completion. This means that, for example, you only need to type @example -set root=( +root ( @end example followed by a @key{TAB}, and GRUB will display the list of drives, @@ -528,7 +413,7 @@ Now the question is, how to specify a file? Again, consider an example: @example -(hd0,msdos1)/vmlinuz +(hd0,1)/vmlinuz @end example This specifies the file named @samp{vmlinuz}, found on the first @@ -538,75 +423,6 @@ completion works with file names, too. That was easy, admit it. Now read the next chapter, to find out how to actually install GRUB on your drive. -@node OS-specific notes about grub tools -@chapter OS-specific notes about grub tools - -On OS which have device nodes similar to Unix-like OS GRUB tools use the -OS name. E.g. for GNU/Linux: - -@example -# @kbd{grub-install /dev/sda} -@end example - -On AROS we use another syntax. For volumes: - -@example -//: -@end example - -E.g. - -@example -//:DH0 -@end example - -For disks we use syntax: -@example -//:/unit/flags -@end example - -E.g. - -@example -# @kbd{grub-install //:ata.device/0/0} -@end example - -On Windows we use UNC path. For volumes it's typically - -@example -\\?\Volume@{@} -\\?\: -@end example - -E.g. - -@example -\\?\Volume@{17f34d50-cf64-4b02-800e-51d79c3aa2ff@} -\\?\C: -@end example - - -For disks it's - -@example -\\?\PhysicalDrive -@end example - -E.g. - -@example -# @kbd{grub-install \\?\PhysicalDrive0} -@end example - -Beware that you may need to further escape the backslashes depending on your -shell. - -When compiled with cygwin support then cygwin drive names are automatically -when needed. E.g. - -@example -# @kbd{grub-install /dev/sda} -@end example @node Installation @chapter Installation @@ -617,43 +433,52 @@ system (@pxref{Obtaining and Building GRUB}). You can do this either from the source tarball, or as a package for your OS. After you have done that, you need to install the boot loader on a -drive (floppy or hard disk) by using the utility -@command{grub-install} (@pxref{Invoking grub-install}) on a UNIX-like OS. +drive (floppy or hard disk). There are two ways of doing that - either +using the utility @command{grub-install} (@pxref{Invoking +grub-install}) on a UNIX-like OS, or by running GRUB itself from a +floppy. These are quite similar, however the utility might probe a +wrong BIOS drive, so you should be careful. + +Also, if you install GRUB on a UNIX-like OS, please make sure that you +have an emergency boot disk ready, so that you can rescue your computer +if, by any chance, your hard drive becomes unusable (unbootable). GRUB comes with boot images, which are normally put in the directory -@file{/usr/lib/grub/-} (for BIOS-based machines -@file{/usr/lib/grub/i386-pc}). Hereafter, the directory where GRUB images are -initially placed (normally @file{/usr/lib/grub/-}) will be +@file{/usr/lib/grub/i386-pc}. Hereafter, the directory where GRUB images are +initially placed (normally @file{/usr/lib/grub/i386-pc}) will be called the @dfn{image directory}, and the directory where the boot -loader needs to find them (usually @file{/boot}) will be called +loader needs to find them (usually @file{/boot/grub}) will be called the @dfn{boot directory}. @menu * Installing GRUB using grub-install:: -* Making a GRUB bootable CD-ROM:: -* Device map:: -* BIOS installation:: @end menu @node Installing GRUB using grub-install @section Installing GRUB using grub-install -For information on where GRUB should be installed on PC BIOS platforms, -@pxref{BIOS installation}. +@strong{Caution:} This procedure is definitely less safe, because +there are several ways in which your computer can become +unbootable. For example, most operating systems don't tell GRUB how to +map BIOS drives to OS devices correctly---GRUB merely @dfn{guesses} +the mapping. This will succeed in most cases, but not +always. Therefore, GRUB provides you with a map file called the +@dfn{device map}, which you must fix if it is wrong. @xref{Device +map}, for more details. -In order to install GRUB under a UNIX-like OS (such +If you still do want to install GRUB under a UNIX-like OS (such as @sc{gnu}), invoke the program @command{grub-install} (@pxref{Invoking grub-install}) as the superuser (@dfn{root}). The usage is basically very simple. You only need to specify one argument to the program, namely, where to install the boot loader. The -argument has to be either a device file (like @samp{/dev/hda}). -For example, under Linux the following will install GRUB into the MBR -of the first IDE disk: +argument can be either a device file (like @samp{/dev/hda}) or a +partition specified in GRUB's notation. For example, under Linux the +following will install GRUB into the MBR of the first IDE disk: @example -# @kbd{grub-install /dev/sda} +# @kbd{grub-install /dev/hda} @end example Likewise, under GNU/Hurd, this has the same effect: @@ -662,54 +487,56 @@ Likewise, under GNU/Hurd, this has the same effect: # @kbd{grub-install /dev/hd0} @end example -But all the above examples assume that GRUB should put images under -the @file{/boot} directory. If you want GRUB to put images under a directory -other than @file{/boot}, you need to specify the option -@option{--boot-directory}. The typical usage is that you create a GRUB +If it is the first BIOS drive, this is the same as well: + +@example +# @kbd{grub-install '(hd0)'} +@end example + +Or you can omit the parentheses: + +@example +# @kbd{grub-install hd0} +@end example + +But all the above examples assume that GRUB should use images under +the root directory. If you want GRUB to use images under a directory +other than the root directory, you need to specify the option +@option{--root-directory}. The typical usage is that you create a GRUB boot floppy with a filesystem. Here is an example: @example @group # @kbd{mke2fs /dev/fd0} # @kbd{mount -t ext2 /dev/fd0 /mnt} -# @kbd{mkdir /mnt/boot} -# @kbd{grub-install --boot-directory=/mnt/boot /dev/fd0} +# @kbd{grub-install --root-directory=/mnt fd0} # @kbd{umount /mnt} @end group @end example -Some BIOSes have a bug of exposing the first partition of a USB drive as a -floppy instead of exposing the USB drive as a hard disk (they call it -``USB-FDD'' boot). In such cases, you need to install like this: +Another example is when you have a separate boot partition +which is mounted at @file{/boot}. Since GRUB is a boot loader, it +doesn't know anything about mountpoints at all. Thus, you need to run +@command{grub-install} like this: @example -# @kbd{losetup /dev/loop0 /dev/sdb1} -# @kbd{mount /dev/loop0 /mnt/usb} -# @kbd{grub-install --boot-directory=/mnt/usb/bugbios --force --allow-floppy /dev/loop0} +# @kbd{grub-install --root-directory=/boot /dev/hda} @end example -This install doesn't conflict with standard install as long as they are in -separate directories. +By the way, as noted above, it is quite difficult to guess BIOS drives +correctly under a UNIX-like OS. Thus, @command{grub-install} will prompt +you to check if it could really guess the correct mappings, after the +installation. The format is defined in @ref{Device map}. Please be +quite careful. If the output is wrong, it is unlikely that your +computer will be able to boot with no problem. -On EFI systems for fixed disk install you have to mount EFI System Partition. -If you mount it at @file{/boot/efi} then you don't need any special arguments: +Note that @command{grub-install} is actually just a shell script and the +real task is done by the grub shell @command{grub} (@pxref{Invoking the +grub shell}). Therefore, you may run @command{grub} directly to install +GRUB, without using @command{grub-install}. Don't do that, however, +unless you are very familiar with the internals of GRUB. Installing a +boot loader on a running OS may be extremely dangerous. -@example -# @kbd{grub-install} -@end example - -Otherwise you need to specify where your EFI System partition is mounted: - -@example -# @kbd{grub-install --efi-directory=/mnt/efi} -@end example - -For removable installs you have to use @option{--removable} and specify both -@option{--boot-directory} and @option{--efi-directory}: - -@example -# @kbd{grub-install --efi-directory=/mnt/usb --boot-directory=/mnt/usb/boot --removable} -@end example @node Making a GRUB bootable CD-ROM @section Making a GRUB bootable CD-ROM @@ -720,22 +547,15 @@ using BIOS functions.}. This means that you can use the whole CD-ROM from GRUB and you don't have to make a floppy or hard disk image file, which can cause compatibility problems. -For booting from a CD-ROM, GRUB uses a special image called -@file{cdboot.img}, which is concatenated with @file{core.img}. The -@file{core.img} used for this should be built with at least the -@samp{iso9660} and @samp{biosdisk} modules. Your bootable CD-ROM will -usually also need to include a configuration file @file{grub.cfg} and some -other GRUB modules. +For booting from a CD-ROM, GRUB uses a special Stage 2 called +@file{stage2_eltorito}. The only GRUB files you need to have in your +bootable CD-ROM are this @file{stage2_eltorito} and optionally a config file +@file{grub.cfg}. You don't need to use @file{stage1} or @file{stage2}, +because El Torito is quite different from the standard boot process. -To make a simple generic GRUB rescue CD, you can use the -@command{grub-mkrescue} program (@pxref{Invoking grub-mkrescue}): - -@example -$ @kbd{grub-mkrescue -o grub.iso} -@end example - -You will often need to include other files in your image. To do this, first -make a top directory for the bootable image, say, @samp{iso}: +Here is an example of procedures to make a bootable CD-ROM +image. First, make a top directory for the bootable image, say, +@samp{iso}: @example $ @kbd{mkdir iso} @@ -747,160 +567,33 @@ Make a directory for GRUB: $ @kbd{mkdir -p iso/boot/grub} @end example +Copy the file @file{stage2_eltorito}: + +@example +$ @kbd{cp /usr/lib/grub/i386-pc/stage2_eltorito iso/boot/grub} +@end example + If desired, make the config file @file{grub.cfg} under @file{iso/boot/grub} (@pxref{Configuration}), and copy any files and directories for the disc to the directory @file{iso/}. -Finally, make the image: +Finally, make a ISO9660 image file like this: @example -$ @kbd{grub-mkrescue -o grub.iso iso} +$ @kbd{mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot \ + -boot-load-size 4 -boot-info-table -o grub.iso iso} @end example This produces a file named @file{grub.iso}, which then can be burned -into a CD (or a DVD), or written to a USB mass storage device. +into a CD (or a DVD). @kbd{mkisofs} has already set up the disc to boot +from the @kbd{boot/grub/stage2_eltorito} file, so there is no need to +setup GRUB on the disc. (Note that the @kbd{-boot-load-size 4} bit is +required for compatibility with the BIOS on many older machines.) -The root device will be set up appropriately on entering your -@file{grub.cfg} configuration file, so you can refer to file names on the CD -without needing to use an explicit device name. This makes it easier to -produce rescue images that will work on both optical drives and USB mass -storage devices. - - -@node Device map -@section The map between BIOS drives and OS devices - -If the device map file exists, the GRUB utilities (@command{grub-probe}, -etc.) read it to map BIOS drives to OS devices. This file consists of lines -like this: - -@example -(@var{device}) @var{file} -@end example - -@var{device} is a drive specified in the GRUB syntax (@pxref{Device -syntax}), and @var{file} is an OS file, which is normally a device file. - -Historically, the device map file was used because GRUB device names had to -be used in the configuration file, and they were derived from BIOS drive -numbers. The map between BIOS drives and OS devices cannot always be -guessed correctly: for example, GRUB will get the order wrong if you -exchange the boot sequence between IDE and SCSI in your BIOS. - -Unfortunately, even OS device names are not always stable. Modern versions -of the Linux kernel may probe drives in a different order from boot to boot, -and the prefix (@file{/dev/hd*} versus @file{/dev/sd*}) may change depending -on the driver subsystem in use. As a result, the device map file required -frequent editing on some systems. - -GRUB avoids this problem nowadays by using UUIDs or file system labels when -generating @file{grub.cfg}, and we advise that you do the same for any -custom menu entries you write. If the device map file does not exist, then -the GRUB utilities will assume a temporary device map on the fly. This is -often good enough, particularly in the common case of single-disk systems. - -However, the device map file is not entirely obsolete yet, and it is -used for overriding when current environment is different from the one on boot. -Most common case is if you use a partition or logical volume as a disk for -virtual machine. You can put any comments in the file if needed, -as the GRUB utilities assume that a line is just a comment if -the first character is @samp{#}. - - -@node BIOS installation -@section BIOS installation - -@heading MBR - -The partition table format traditionally used on PC BIOS platforms is called -the Master Boot Record (MBR) format; this is the format that allows up to -four primary partitions and additional logical partitions. With this -partition table format, there are two ways to install GRUB: it can be -embedded in the area between the MBR and the first partition (called by -various names, such as the "boot track", "MBR gap", or "embedding area", and -which is usually at least 1000 KiB), or the core image can be installed in a -file system and a list of the blocks that make it up can be stored in the -first sector of that partition. - -Modern tools usually leave MBR gap of at least 1023 KiB. This amount is -sufficient to cover most configurations. Hence this value is recommended -by the GRUB team. - -Historically many tools left only 31 KiB of space. This is not enough to -parse reliably difficult structures like Btrfs, ZFS, RAID or LVM, or to -use difficult disk access methods like ahci. Hence GRUB will warn if attempted -to install into small MBR gap except in a small number of configurations -that were grandfathered. The grandfathered config must: - -@itemize @bullet -@item -use biosdisk as disk access module for @file{/boot} - -@item -not use any additional partition maps to access @file{/boot} - -@item -@file{/boot} must be on one of following filesystems: - AFFS, AFS, BFS, cpio, newc, odc, ext2/3/4, FAT, exFAT, - F2FS, HFS, uncompressed HFS+, ISO9660, JFS, Minix, Minix2, Minix3, NILFS2, - NTFS, ReiserFS, ROMFS, SFS, tar, UDF, UFS1, UFS2, XFS -@end itemize -Note: Only a subset of filesystems are supported in lockdown mode (such -as when secure boot is enabled, @pxref{Lockdown} for more information). - -MBR gap has few technical problems. There is no way to reserve space in -the embedding area with complete safety, and some proprietary software is -known to use it to make it difficult for users to work around licensing -restrictions. GRUB works around it by detecting sectors by other software and -avoiding them and protecting its own sectors using Reed-Solomon encoding. - -GRUB team recommends having MBR gap of at least 1000 KiB. - -Should it not be possible, GRUB has support for a fallback solution which is -heavily recommended against. Installing to a filesystem means that GRUB is -vulnerable to its blocks being moved around by filesystem features such as -tail packing, or even by aggressive fsck implementations, so this approach -is quite fragile; and this approach can only be used if the @file{/boot} -filesystem is on the same disk that the BIOS boots from, so that GRUB does -not have to rely on guessing BIOS drive numbers. - -The GRUB development team generally recommends embedding GRUB before the -first partition, unless you have special requirements. You must ensure that -the first partition starts at least 1000 KiB (2000 sectors) from the start of -the disk; on modern disks, it is often a performance advantage to align -partitions on larger boundaries anyway, so the first partition might start 1 -MiB from the start of the disk. - -@heading GPT - -Some newer systems use the GUID Partition Table (GPT) format. This was -specified as part of the Extensible Firmware Interface (EFI), but it can -also be used on BIOS platforms if system software supports it; for example, -GRUB and GNU/Linux can be used in this configuration. With this format, it -is possible to reserve a whole partition for GRUB, called the BIOS Boot -Partition. GRUB can then be embedded into that partition without the risk -of being overwritten by other software and without being contained in a -filesystem which might move its blocks around. - -When creating a BIOS Boot Partition on a GPT system, you should make sure -that it is at least 31 KiB in size. (GPT-formatted disks are not usually -particularly small, so we recommend that you make it larger than the bare -minimum, such as 1 MiB, to allow plenty of room for growth.) You must also -make sure that it has the proper partition type. Using GNU Parted, you can -set this using a command such as the following: - -@example -# @kbd{parted /dev/@var{disk} set @var{partition-number} bios_grub on} -@end example - -If you are using gdisk, set the partition type to @samp{0xEF02}. With -partitioning programs that require setting the GUID directly, it should be -@samp{21686148-6449-6e6f-744e656564454649}. - -@strong{Caution:} Be very careful which partition you select! When GRUB -finds a BIOS Boot Partition during installation, it will automatically -overwrite part of it. Make sure that the partition does not contain any -other data. +You can use the device @samp{(cd)} to access a CD-ROM in your +config file. This is not required; GRUB automatically sets the root device +to @samp{(cd)} when booted from a CD-ROM. It is only necessary to refer to +@samp{(cd)} if you want to access other drives as well. @node Booting @@ -912,8 +605,6 @@ magic. @menu * General boot methods:: How to boot OSes with GRUB generally -* Loopback booting:: Notes on booting from loopbacks -* LVM cache booting:: Notes on booting from LVM cache logical volume * OS-specific notes:: Notes on some operating systems @end menu @@ -921,17 +612,17 @@ magic. @node General boot methods @section How to boot operating systems -GRUB has three distinct boot methods: loading an operating system -directly, using kexec from userspace, and chainloading another -bootloader. Generally speaking, the first two are more desirable -because you don't need to install or maintain other boot loaders and -GRUB is flexible enough to load an operating system from an arbitrary -disk/partition. However, chainloading is sometimes required, as GRUB -doesn't support all existing operating systems natively. +GRUB has two distinct boot methods. One of the two is to load an +operating system directly, and the other is to chain-load another boot +loader which then will load an operating system actually. Generally +speaking, the former is more desirable, because you don't need to +install or maintain other boot loaders and GRUB is flexible enough to +load an operating system from an arbitrary disk/partition. However, +the latter is sometimes required, since GRUB doesn't support all the +existing operating systems natively. @menu * Loading an operating system directly:: -* Kexec:: * Chain-loading:: @end menu @@ -957,95 +648,6 @@ use more complicated instructions. @xref{DOS/Windows}, for more information. -@node Kexec -@subsection Kexec with grub2-emu - -GRUB can be run in userspace by invoking the grub2-emu tool. It will -read all configuration scripts as if booting directly (see @ref{Loading -an operating system directly}). With the @code{--kexec} flag, and -kexec(8) support from the operating system, the @command{linux} command -will directly boot the target image. For systems that lack working -systemctl(1) support for kexec, passing the @code{--kexec} flag twice -will fallback to invoking kexec(8) directly; note however that this -fallback may be unsafe outside read-only environments, as it does not -invoke shutdown machinery. - - -@node Chain-loading -@subsection Chain-loading an OS - -Operating systems that do not support Multiboot and do not have specific -support in GRUB (specific support is available for Linux, FreeBSD, NetBSD -and OpenBSD) must be chain-loaded, which involves loading another boot -loader and jumping to it in real mode or via the firmware. - -The @command{chainloader} command (@pxref{chainloader}) is used to set this -up. It is normally also necessary to load some GRUB modules and set the -appropriate root device. Putting this together, we get something like this, -for a Windows system on the first partition of the first hard disk: - -@verbatim -menuentry "Windows" { - insmod chain - insmod ntfs - set root=(hd0,1) - chainloader +1 -} -@end verbatim -@c FIXME: document UUIDs. - -On systems with multiple hard disks, an additional workaround may be -required. @xref{DOS/Windows}. - -Chain-loading is only supported on PC BIOS and EFI platforms. - -@node Loopback booting -@section Loopback booting -GRUB is able to read from an image (be it one of CD or HDD) stored on -any of its accessible storages (refer to @pxref{loopback} command). -However the OS itself should be able to find its root. This usually -involves running a userspace program running before the real root -is discovered. This is achieved by GRUB loading a specially made -small image and passing it as ramdisk to the kernel. This is achieved -by commands @command{kfreebsd_module}, @command{knetbsd_module_elf}, -@command{kopenbsd_ramdisk}, @command{initrd} (@pxref{initrd}), -@command{initrd16} (@pxref{initrd16}), @command{multiboot_module}, -@command{multiboot2_module} or @command{xnu_ramdisk} -depending on the loader. Note that for knetbsd the image must be put -inside miniroot.kmod and the whole miniroot.kmod has to be loaded. In -kopenbsd payload this is disabled by default. Additionally, behaviour of -initial ramdisk depends on command line options. Several distributors provide -the image for this purpose or it's integrated in their standard ramdisk and -activated by special option. Consult your kernel and distribution manual for -more details. Other loaders like @command{appleloader}, @command{chainloader} -(BIOS, EFI, coreboot), @command{freedos}, @command{ntldr}, @command{plan9} -and @command{truecrypt} provide no possibility of loading initial ramdisk and -as far as author is aware the payloads in question don't support either initial -ramdisk or discovering loopback boot in other way and as such not bootable this -way. Please consider alternative boot methods like copying all files -from the image to actual partition. Consult your OS documentation for -more details. - -@node LVM cache booting -@section Booting from LVM cache logical volume - -The LVM cache logical volume is the logical volume consisting of the original -and the cache pool logical volume. The original is usually on a larger and -slower storage device while the cache pool is on a smaller and faster one. The -performance of the original volume can be improved by storing the frequently -used data on the cache pool to utilize the greater performance of faster -device. - -GRUB boots from LVM cache logical volume merely by reading it's original -logical volume so that dirty data in cache pool volume is disregarded. This is -not a problem for "writethrough" cache mode as it ensures that any data written -will be stored both on the cache and the origin LV. For the other cache mode -"writeback", which delays writing from the cache pool back to the origin LV to -boost performance, GRUB may fail to boot in the wake of accidental power outage -due to it's inability to assemble the cache device for reading the required -dirty data left behind. The situation will be improved after adding full -support to the LVM cache logical volume in the future. - @node OS-specific notes @section Some caveats on OS-specific issues @@ -1054,8 +656,6 @@ Here, we describe some caveats on several operating systems. @menu * GNU/Hurd:: * GNU/Linux:: -* NetBSD:: -* DOS/Windows:: @end menu @@ -1066,30 +666,11 @@ Since GNU/Hurd is Multiboot-compliant, it is easy to boot it; there is nothing special about it. But do not forget that you have to specify a root partition to the kernel. +FIXME: this section is incomplete. + @enumerate @item -Set GRUB's root device to the same drive as GNU/Hurd's. The command -@code{search --set=root --file /boot/gnumach.gz} or similar may help you -(@pxref{search}). - -@item -Load the kernel and the modules, like this: - -@example -@group -grub> @kbd{multiboot /boot/gnumach.gz root=device:hd0s1} -grub> @kbd{module /hurd/ext2fs.static ext2fs --readonly \ - --multiboot-command-line='$@{kernel-command-line@}' \ - --host-priv-port='$@{host-port@}' \ - --device-master-port='$@{device-port@}' \ - --exec-server-task='$@{exec-task@}' -T typed '$@{root@}' \ - '$(task-create)' '$(task-resume)'} -grub> @kbd{module /lib/ld.so.1 exec /hurd/exec '$(exec-task=task-create)'} -@end group -@end example - -@item -Finally, run the command @command{boot} (@pxref{boot}). +Run the command @command{boot} (@pxref{boot}). @end enumerate @@ -1099,1598 +680,21 @@ Finally, run the command @command{boot} (@pxref{boot}). It is relatively easy to boot GNU/Linux from GRUB, because it somewhat resembles to boot a Multiboot-compliant OS. +FIXME: this section is incomplete. + @enumerate @item -Set GRUB's root device to the same drive as GNU/Linux's. The command -@code{search --set=root --file /vmlinuz} or similar may help you -(@pxref{search}). - -@item -Load the kernel using the command @command{linux} (@pxref{linux}): - -@example -grub> @kbd{linux /vmlinuz root=/dev/sda1} -@end example - -If you need to specify some kernel parameters, just append them to the -command. For example, to set @option{acpi} to @samp{off}, do this: - -@example -grub> @kbd{linux /vmlinuz root=/dev/sda1 acpi=off} -@end example - -See the documentation in the Linux source tree for complete information on -the available options. - -With @command{linux} GRUB uses 32-bit protocol. Some BIOS services like APM -or EDD aren't available with this protocol. In this case you need to use -@command{linux16} - -@example -grub> @kbd{linux16 /vmlinuz root=/dev/sda1 acpi=off} -@end example - -@item -If you use an initrd, execute the command @command{initrd} (@pxref{initrd}) -after @command{linux}: - -@example -grub> @kbd{initrd /initrd} -@end example - -If you used @command{linux16} you need to use @command{initrd16}: - -@example -grub> @kbd{initrd16 /initrd} -@end example +Set GRUB's root device to the same drive as GNU/Linux's. @item Finally, run the command @command{boot} (@pxref{boot}). @end enumerate - -@node NetBSD -@subsection NetBSD - -Booting a NetBSD kernel from GRUB is also relatively easy: first set -GRUB's root device, then load the kernel and the modules, and finally -run @command{boot}. - -@enumerate -@item -Set GRUB's root device to the partition holding the NetBSD root file -system. For a disk with a NetBSD disk label, this is usually the first -partition (a:). In that case, and assuming that the partition is on the -first hard disk, set GRUB's root device as follows: - -@example -grub> @kbd{insmod part_bsd} -grub> @kbd{set root=(hd0,netbsd1)} -@end example - -For a disk with a GUID Partition Table (GPT), and assuming that the -NetBSD root partition is the third GPT partition, do this: - -@example -grub> @kbd{insmod part_gpt} -grub> @kbd{set root=(hd0,gpt3)} -@end example - -@item -Load the kernel using the command @command{knetbsd}: - -@example -grub> @kbd{knetbsd /netbsd} -@end example - -Various options may be given to @command{knetbsd}. These options are, -for the most part, the same as in the NetBSD boot loader. For instance, -to boot the system in single-user mode and with verbose messages, do -this: - -@example -grub> @kbd{knetbsd /netbsd -s -v} -@end example - -@item -If needed, load kernel modules with the command -@command{knetbsd_module_elf}. A typical example is the module for the -root file system: - -@example -grub> @kbd{knetbsd_module_elf /stand/amd64/6.0/modules/ffs/ffs.kmod} -@end example - -@item -Finally, run the command @command{boot} (@pxref{boot}). -@end enumerate - - -@node DOS/Windows -@subsection DOS/Windows - -GRUB cannot boot DOS or Windows directly, so you must chain-load them -(@pxref{Chain-loading}). However, their boot loaders have some critical -deficiencies, so it may not work to just chain-load them. To overcome -the problems, GRUB provides you with two helper functions. - -If you have installed DOS (or Windows) on a non-first hard disk, you -have to use the disk swapping technique, because that OS cannot boot -from any disks but the first one. The workaround used in GRUB is the -command @command{drivemap} (@pxref{drivemap}), like this: - -@example -drivemap -s (hd0) (hd1) -@end example - -This performs a @dfn{virtual} swap between your first and second hard -drive. - -@strong{Caution:} This is effective only if DOS (or Windows) uses BIOS -to access the swapped disks. If that OS uses a special driver for the -disks, this probably won't work. - -Another problem arises if you installed more than one set of DOS/Windows -onto one disk, because they could be confused if there are more than one -primary partitions for DOS/Windows. Certainly you should avoid doing -this, but there is a solution if you do want to do so. Use the partition -hiding/unhiding technique. - -If GRUB @dfn{hides} a DOS (or Windows) partition (@pxref{parttool}), DOS (or -Windows) will ignore the partition. If GRUB @dfn{unhides} a DOS (or Windows) -partition, DOS (or Windows) will detect the partition. Thus, if you have -installed DOS (or Windows) on the first and the second partition of the -first hard disk, and you want to boot the copy on the first partition, do -the following: - -@example -@group -parttool (hd0,1) hidden- -parttool (hd0,2) hidden+ -set root=(hd0,1) -chainloader +1 -parttool @verb{'${root}'} boot+ -boot -@end group -@end example - - -@node Configuration -@chapter Writing your own configuration file - -GRUB is configured using @file{grub.cfg}, usually located under -@file{/boot/grub}. This file is quite flexible, but most users will not -need to write the whole thing by hand. - -@menu -* Simple configuration:: Recommended for most users -* Root Identification Heuristics:: Summary on how the root file system is identified. -* Shell-like scripting:: For power users and developers -* Multi-boot manual config:: For non-standard multi-OS scenarios -* Embedded configuration:: Embedding a configuration file into GRUB -@end menu - - -@node Simple configuration -@section Simple configuration handling - -The program @command{grub-mkconfig} (@pxref{Invoking grub-mkconfig}) -generates @file{grub.cfg} files suitable for most cases. It is suitable for -use when upgrading a distribution, and will discover available kernels and -attempt to generate menu entries for them. - -@command{grub-mkconfig} does have some limitations. While adding extra -custom menu entries to the end of the list can be done by editing -@file{/etc/grub.d/40_custom} or creating @file{/boot/grub/custom.cfg}, -changing the order of menu entries or changing their titles may require -making complex changes to shell scripts stored in @file{/etc/grub.d/}. This -may be improved in the future. In the meantime, those who feel that it -would be easier to write @file{grub.cfg} directly are encouraged to do so -(@pxref{Booting}, and @ref{Shell-like scripting}), and to disable any system -provided by their distribution to automatically run @command{grub-mkconfig}. - -The file @file{/etc/default/grub} controls the operation of -@command{grub-mkconfig}. It is sourced by a shell script, and so must be -valid POSIX shell input; normally, it will just be a sequence of -@samp{KEY=value} lines, but if the value contains spaces or other special -characters then it must be quoted. For example: - -@example -GRUB_TERMINAL_INPUT="console serial" -@end example - -Valid keys in @file{/etc/default/grub} are as follows: - -@table @samp -@item GRUB_DEFAULT -The default menu entry. This may be a number, in which case it identifies -the Nth entry in the generated menu counted from zero, or the title of a -menu entry, or the special string @samp{saved}. Using the id may be -useful if you want to set a menu entry as the default even though there may -be a variable number of entries before it. - -For example, if you have: - -@verbatim -menuentry 'Example GNU/Linux distribution' --class gnu-linux --id example-gnu-linux { - ... -} -@end verbatim - -then you can make this the default using: - -@example -GRUB_DEFAULT=example-gnu-linux -@end example - -Previously it was documented the way to use entry title. While this still -works it's not recommended since titles often contain unstable device names -and may be translated - -If you set this to @samp{saved}, then the default menu entry will be that -saved by @samp{GRUB_SAVEDEFAULT} or @command{grub-set-default}. This relies on -the environment block, which may not be available in all situations -(@pxref{Environment block}). - -The default is @samp{0}. - -@item GRUB_SAVEDEFAULT -If this option is set to @samp{true}, then, when an entry is selected, save -it as a new default entry for use by future runs of GRUB. This is only -useful if @samp{GRUB_DEFAULT=saved}; it is a separate option because -@samp{GRUB_DEFAULT=saved} is useful without this option, in conjunction with -@command{grub-set-default}. Unset by default. -This option relies on the environment block, which may not be available in -all situations (@pxref{Environment block}). - -@item GRUB_TIMEOUT -Boot the default entry this many seconds after the menu is displayed, unless -a key is pressed. The default is @samp{5}. Set to @samp{0} to boot -immediately without displaying the menu, or to @samp{-1} to wait -indefinitely. - -If @samp{GRUB_TIMEOUT_STYLE} is set to @samp{countdown} or @samp{hidden}, -the timeout is instead counted before the menu is displayed. - -@item GRUB_TIMEOUT_STYLE -If this option is unset or set to @samp{menu}, then GRUB will display the -menu and then wait for the timeout set by @samp{GRUB_TIMEOUT} to expire -before booting the default entry. Pressing a key interrupts the timeout. - -If this option is set to @samp{countdown} or @samp{hidden}, then, before -displaying the menu, GRUB will wait for the timeout set by @samp{GRUB_TIMEOUT} -to expire. If @key{ESC} or @key{F4} are pressed, or @key{SHIFT} is held down -during that time, it will display the menu and wait for input. If a hotkey -associated with a menu entry is pressed, it will boot the associated menu entry -immediately. If the timeout expires before either of these happens, it will -boot the default entry. In the @samp{countdown} case, it will show a one-line -indication of the remaining time. - -@item GRUB_DEFAULT_BUTTON -@itemx GRUB_TIMEOUT_BUTTON -@itemx GRUB_TIMEOUT_STYLE_BUTTON -@itemx GRUB_BUTTON_CMOS_ADDRESS -Variants of the corresponding variables without the @samp{_BUTTON} suffix, -used to support vendor-specific power buttons. @xref{Vendor power-on keys}. - -@item GRUB_DISTRIBUTOR -Set by distributors of GRUB to their identifying name. This is used to -generate more informative menu entry titles. - -@item GRUB_TERMINAL_INPUT -Select the terminal input device. You may select multiple devices here, -separated by spaces. - -Valid terminal input names depend on the platform, but may include -@samp{console} (native platform console), @samp{serial} (serial terminal), -@samp{serial_} (serial terminal with explicit port selection), -@samp{at_keyboard} (PC AT keyboard), or @samp{usb_keyboard} (USB keyboard -using the HID Boot Protocol, for cases where the firmware does not handle -this). - -The default is to use the platform's native terminal input. - -@item GRUB_TERMINAL_OUTPUT -Select the terminal output device. You may select multiple devices here, -separated by spaces. - -Valid terminal output names depend on the platform, but may include -@samp{console} (native platform console), @samp{serial} (serial terminal), -@samp{serial_} (serial terminal with explicit port selection), -@samp{gfxterm} (graphics-mode output), @samp{vga_text} (VGA text output), -@samp{mda_text} (MDA text output), @samp{morse} (Morse-coding using system -beeper) or @samp{spkmodem} (simple data protocol using system speaker). - -@samp{spkmodem} is useful when no serial port is available. Connect the output -of sending system (where GRUB is running) to line-in of receiving system -(usually developer machine). -On receiving system compile @samp{spkmodem-recv} from -@samp{util/spkmodem-recv.c} and run: - -@example -parecord --channels=1 --rate=48000 --format=s16le | ./spkmodem-recv -@end example - -The default is to use the platform's native terminal output. - -@item GRUB_TERMINAL -If this option is set, it overrides both @samp{GRUB_TERMINAL_INPUT} and -@samp{GRUB_TERMINAL_OUTPUT} to the same value. - -@item GRUB_SERIAL_COMMAND -A command to configure the serial port when using the serial console. -@xref{serial}. Defaults to @samp{serial}. - -@item GRUB_CMDLINE_LINUX -Command-line arguments to add to menu entries for the Linux kernel. - -@item GRUB_CMDLINE_LINUX_DEFAULT -Unless @samp{GRUB_DISABLE_RECOVERY} is set to @samp{true}, two menu -entries will be generated for each Linux kernel: one default entry and one -entry for recovery mode. This option lists command-line arguments to add -only to the default menu entry, after those listed in -@samp{GRUB_CMDLINE_LINUX}. - -@item GRUB_CMDLINE_LINUX_RECOVERY -Unless @samp{GRUB_DISABLE_RECOVERY} is set to @samp{true}, two menu -entries will be generated for each Linux kernel: one default entry and one -entry for recovery mode. This option lists command-line arguments to add -only to the recovery menu entry, before those listed in @samp{GRUB_CMDLINE_LINUX}. -The default is @samp{single}. - -@item GRUB_CMDLINE_NETBSD -@itemx GRUB_CMDLINE_NETBSD_DEFAULT -As @samp{GRUB_CMDLINE_LINUX} and @samp{GRUB_CMDLINE_LINUX_DEFAULT}, but for -NetBSD. - -@item GRUB_CMDLINE_GNUMACH -As @samp{GRUB_CMDLINE_LINUX}, but for GNU Mach. - -@item GRUB_CMDLINE_XEN -@itemx GRUB_CMDLINE_XEN_DEFAULT -The values of these options are passed to Xen hypervisor Xen menu entries, -for all respectively normal entries. - -@item GRUB_CMDLINE_LINUX_XEN_REPLACE -@item GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT -The values of these options replace the values of @samp{GRUB_CMDLINE_LINUX} -and @samp{GRUB_CMDLINE_LINUX_DEFAULT} for Linux and Xen menu entries. - -@item GRUB_TOP_LEVEL -@item GRUB_TOP_LEVEL_XEN -This option should be an absolute path to a kernel image. If provided, the -image specified will be made the top-level entry if it is found in the scan. - -@item GRUB_TOP_LEVEL_OS_PROBER -This option should be a line of output from @command{os-prober}. As -@samp{GRUB_TOP_LEVEL}, if provided, the image specified will be made the -top-level entry if it is found in the scan. - -@item GRUB_EARLY_INITRD_LINUX_CUSTOM -@itemx GRUB_EARLY_INITRD_LINUX_STOCK -List of space-separated early initrd images to be loaded from @samp{/boot}. -This is for loading things like CPU microcode, firmware, ACPI tables, crypto -keys, and so on. These early images will be loaded in the order declared, -and all will be loaded before the actual functional initrd image. - -@samp{GRUB_EARLY_INITRD_LINUX_STOCK} is for your distribution to declare -images that are provided by the distribution. It should not be modified -without understanding the consequences. They will be loaded first. - -@samp{GRUB_EARLY_INITRD_LINUX_CUSTOM} is for your custom created images. - -The default stock images are as follows, though they may be overridden by -your distribution: -@example -intel-uc.img intel-ucode.img amd-uc.img amd-ucode.img early_ucode.cpio microcode.cpio -@end example - -@item GRUB_DISABLE_LINUX_UUID -Normally, @command{grub-mkconfig} will generate menu entries that use -universally-unique identifiers (UUIDs) to identify the root filesystem to -the Linux kernel, using a @samp{root=UUID=...} kernel parameter. This is -usually more reliable, but in some cases it may not be appropriate. To -disable the use of UUIDs, set this option to @samp{true}. - -@item GRUB_DISABLE_LINUX_PARTUUID -If @command{grub-mkconfig} cannot identify the root filesystem via its -universally-unique indentifier (UUID), @command{grub-mkconfig} can use the UUID -of the partition containing the filesystem to identify the root filesystem to -the Linux kernel via a @samp{root=PARTUUID=...} kernel parameter. This is not -as reliable as using the filesystem UUID, but is more reliable than using the -Linux device names. When @samp{GRUB_DISABLE_LINUX_PARTUUID} is set to -@samp{false}, the Linux kernel version must be 2.6.37 (3.10 for systems using -the MSDOS partition scheme) or newer. This option defaults to @samp{true}. To -enable the use of partition UUIDs, set this option to @samp{false}. - -@item GRUB_DISABLE_RECOVERY -If this option is set to @samp{true}, disable the generation of recovery -mode menu entries. - -@item GRUB_DISABLE_UUID -Normally, @command{grub-mkconfig} will generate menu entries that use -universally-unique identifiers (UUIDs) to identify various filesystems to -search for files. This is usually more reliable, but in some cases it may -not be appropriate. To disable this use of UUIDs, set this option to -@samp{true}. Setting this option to @samp{true}, will also set the options -@samp{GRUB_DISABLE_LINUX_UUID} and @samp{GRUB_DISABLE_LINUX_PARTUUID} to -@samp{true}, unless they have been explicitly set to @samp{false}. - -@item GRUB_VIDEO_BACKEND -If graphical video support is required, either because the @samp{gfxterm} -graphical terminal is in use or because @samp{GRUB_GFXPAYLOAD_LINUX} is set, -then @command{grub-mkconfig} will normally load all available GRUB video -drivers and use the one most appropriate for your hardware. If you need to -override this for some reason, then you can set this option. - -After @command{grub-install} has been run, the available video drivers are -listed in @file{/boot/grub/video.lst}. - -@item GRUB_GFXMODE -Set the resolution used on the @samp{gfxterm} graphical terminal. Note that -you can only use modes which your graphics card supports via VESA BIOS -Extensions (VBE), so for example native LCD panel resolutions may not be -available. The default is @samp{auto}, which tries to select a preferred -resolution. @xref{gfxmode}. - -@item GRUB_BACKGROUND -Set a background image for use with the @samp{gfxterm} graphical terminal. -The value of this option must be a file readable by GRUB at boot time, and -it must end with @file{.png}, @file{.tga}, @file{.jpg}, or @file{.jpeg}. -The image will be scaled if necessary to fit the screen. Image height and -width will be restricted by an artificial limit of 16384. - -@item GRUB_THEME -Set a theme for use with the @samp{gfxterm} graphical terminal. - -@item GRUB_GFXPAYLOAD_LINUX -Set to @samp{text} to force the Linux kernel to boot in normal text mode, -@samp{keep} to preserve the graphics mode set using @samp{GRUB_GFXMODE}, -@samp{@var{width}x@var{height}}[@samp{x@var{depth}}] to set a particular -graphics mode, or a sequence of these separated by commas or semicolons to -try several modes in sequence. @xref{gfxpayload}. - -Depending on your kernel, your distribution, your graphics card, and the -phase of the moon, note that using this option may cause GNU/Linux to suffer -from various display problems, particularly during the early part of the -boot sequence. If you have problems, set this option to @samp{text} and -GRUB will tell Linux to boot in normal text mode. - -@item GRUB_DISABLE_OS_PROBER -The @command{grub-mkconfig} has a feature to use the external -@command{os-prober} program to discover other operating systems installed on -the same machine and generate appropriate menu entries for them. It is disabled -by default since automatic and silent execution of @command{os-prober}, and -creating boot entries based on that data, is a potential attack vector. Set -this option to @samp{false} to enable this feature in the -@command{grub-mkconfig} command. - -@item GRUB_OS_PROBER_SKIP_LIST -List of space-separated case insensitive UUIDs of filesystems to be ignored -from os-prober output. For EFI chainloaders it's @@. For -backward compatibility with previous behaviour, @@/dev/* is also accepted -for non-EFI chainloaders even if the device does not match, and comma and -semicolon are also accepted as separator. - -@item GRUB_DISABLE_SUBMENU -Normally, @command{grub-mkconfig} will generate top level menu entry for -the kernel with highest version number and put all other found kernels -or alternative menu entries for recovery mode in submenu. For entries returned -by @command{os-prober} first entry will be put on top level and all others -in submenu. If this option is set to @samp{true}, flat menu with all entries -on top level will be generated instead. Changing this option will require -changing existing values of @samp{GRUB_DEFAULT}, @samp{fallback} (@pxref{fallback}) -and @samp{default} (@pxref{default}) environment variables as well as saved -default entry using @command{grub-set-default} and value used with -@command{grub-reboot}. - -@item GRUB_ENABLE_CRYPTODISK -If set to @samp{y}, @command{grub-mkconfig} and @command{grub-install} will -check for encrypted disks and generate additional commands needed to access -them during boot. Note that in this case unattended boot is not possible -because GRUB will wait for passphrase to unlock encrypted container. - -@item GRUB_INIT_TUNE -Play a tune on the speaker when GRUB starts. This is particularly useful -for users unable to see the screen. The value of this option is passed -directly to @ref{play}. - -@item GRUB_BADRAM -If this option is set, GRUB will issue a @ref{badram} command to filter -out specified regions of RAM. - -@item GRUB_PRELOAD_MODULES -This option may be set to a list of GRUB module names separated by spaces. -Each module will be loaded as early as possible, at the start of -@file{grub.cfg}. - -@end table - -The following options are still accepted for compatibility with existing -configurations, but have better replacements: - -@table @samp -@item GRUB_HIDDEN_TIMEOUT -Wait this many seconds before displaying the menu. If @key{ESC} or @key{F4} are -pressed, or @key{SHIFT} is held down during that time, display the menu and wait -for input according to @samp{GRUB_TIMEOUT}. If a hotkey associated with a menu -entry is pressed, boot the associated menu entry immediately. If the timeout -expires before either of these happens, display the menu for the number of -seconds specified in @samp{GRUB_TIMEOUT} before booting the default entry. - -If you set @samp{GRUB_HIDDEN_TIMEOUT}, you should also set -@samp{GRUB_TIMEOUT=0} so that the menu is not displayed at all unless -@key{ESC} or @key{F4} are pressed, or @key{SHIFT} is held down. - -This option is unset by default, and is deprecated in favour of the less -confusing @samp{GRUB_TIMEOUT_STYLE=countdown} or -@samp{GRUB_TIMEOUT_STYLE=hidden}. - -@item GRUB_HIDDEN_TIMEOUT_QUIET -In conjunction with @samp{GRUB_HIDDEN_TIMEOUT}, set this to @samp{true} to -suppress the verbose countdown while waiting for a key to be pressed before -displaying the menu. - -This option is unset by default, and is deprecated in favour of the less -confusing @samp{GRUB_TIMEOUT_STYLE=countdown}. - -@item GRUB_HIDDEN_TIMEOUT_BUTTON -Variant of @samp{GRUB_HIDDEN_TIMEOUT}, used to support vendor-specific power -buttons. @xref{Vendor power-on keys}. - -This option is unset by default, and is deprecated in favour of the less -confusing @samp{GRUB_TIMEOUT_STYLE=countdown} or -@samp{GRUB_TIMEOUT_STYLE=hidden}. - -@end table - -For more detailed customisation of @command{grub-mkconfig}'s output, you may -edit the scripts in @file{/etc/grub.d} directly. -@file{/etc/grub.d/40_custom} is particularly useful for adding entire custom -menu entries; simply type the menu entries you want to add at the end of -that file, making sure to leave at least the first two lines intact. - -@node Root Identification Heuristics -@section Root Identification Heuristics -If the target operating system uses the Linux kernel, @command{grub-mkconfig} -attempts to identify the root file system via a heuristic algoirthm. This -algorithm selects the identification method of the root file system by -considering three factors. The first is if an initrd for the target operating -system is also present. The second is @samp{GRUB_DISABLE_LINUX_UUID} and if set -to @samp{true}, prevents @command{grub-mkconfig} from identifying the root file -system by its UUID. The third is @samp{GRUB_DISABLE_LINUX_PARTUUID} and if set -to @samp{true}, prevents @command{grub-mkconfig} from identifying the root file -system via the UUID of its enclosing partition. If the variables are assigned -any other value, that value is considered equivalent to @samp{false}. The -variables are also considered to be set to @samp{false} if they are not set. - -When booting, the Linux kernel will delegate the task of mounting the root -filesystem to the initrd. Most initrd images determine the root file system by -checking the Linux kernel's command-line for the @samp{root} key and use its -value as the identification method of the root file system. To improve the -reliability of booting, most initrd images also allow the root file system to be -identified by its UUID. Because of this behavior, the @command{grub-mkconfig} -command will set @samp{root} to @samp{root=UUID=...} to provide the initrd with -the filesystem UUID of the root file system. - -If no initrd is detected or @samp{GRUB_DISABLE_LINUX_UUID} is set to @samp{true} -then @command{grub-command} will identify the root filesystem by setting the -kernel command-line variable @samp{root} to @samp{root=PARTUUID=...} unless -@samp{GRUB_DISABLE_LINUX_PARTUUID} is also set to @samp{true}. If -@samp{GRUB_DISABLE_LINUX_PARTUUID} is also set to @samp{true}, -@command{grub-command} will identify by its Linux device name. - -The following table summarizes the behavior of the @command{grub-mkconfig} -command. - -@multitable {detected} {GRUB_DISABLE_LINUX_PARTUUID} {GRUB_DISABLE_LINUX_UUID} {Linux Root} -@headitem Initrd detected @tab GRUB_DISABLE_LINUX_PARTUUID Set To @tab GRUB_DISABLE_LINUX_UUID Set To @tab Linux Root ID Method -@item false @tab false @tab false @tab part UUID -@item false @tab false @tab true @tab part UUID -@item false @tab true @tab false @tab dev name -@item false @tab true @tab true @tab dev name -@item true @tab false @tab false @tab fs UUID -@item true @tab false @tab true @tab part UUID -@item true @tab true @tab false @tab fs UUID -@item true @tab true @tab true @tab dev name -@end multitable - -Remember, @samp{GRUB_DISABLE_LINUX_PARTUUID} and @samp{GRUB_DISABLE_LINUX_UUID} -are also considered to be set to @samp{true} and @samp{false}, respectively, -when they are unset. - -@node Shell-like scripting -@section Writing full configuration files directly - -@c Some of this section is derived from the GNU Bash manual page, also -@c copyrighted by the FSF. - -@file{grub.cfg} is written in GRUB's built-in scripting language, which has -a syntax quite similar to that of GNU Bash and other Bourne shell -derivatives. - -@heading Words - -A @dfn{word} is a sequence of characters considered as a single unit by -GRUB. Words are separated by @dfn{metacharacters}, which are the following -plus space, tab, and newline: - -@example -@{ @} | & $ ; < > -@end example - -Quoting may be used to include metacharacters in words; see below. - -@heading Reserved words - -Reserved words have a special meaning to GRUB. The following words are -recognised as reserved when unquoted and either the first word of a simple -command or the third word of a @code{for} command: - -@example -! [[ ]] @{ @} -case do done elif else esac fi for function -if in menuentry select then time until while -@end example - -Not all of these reserved words have a useful purpose yet; some are reserved -for future expansion. - -@heading Quoting - -Quoting is used to remove the special meaning of certain characters or -words. It can be used to treat metacharacters as part of a word, to prevent -reserved words from being recognised as such, and to prevent variable -expansion. - -There are three quoting mechanisms: the escape character, single quotes, and -double quotes. - -A non-quoted backslash (\) is the @dfn{escape character}. It preserves the -literal value of the next character that follows, with the exception of -newline. - -Enclosing characters in single quotes preserves the literal value of each -character within the quotes. A single quote may not occur between single -quotes, even when preceded by a backslash. - -Enclosing characters in double quotes preserves the literal value of all -characters within the quotes, with the exception of @samp{$} and @samp{\}. -The @samp{$} character retains its special meaning within double quotes. -The backslash retains its special meaning only when followed by one of the -following characters: @samp{$}, @samp{"}, @samp{\}, or newline. A -backslash-newline pair is treated as a line continuation (that is, it is -removed from the input stream and effectively ignored@footnote{Currently a -backslash-newline pair within a variable name is not handled properly, so -use this feature with some care.}). A double quote may be quoted within -double quotes by preceding it with a backslash. - -@heading Variable expansion - -The @samp{$} character introduces variable expansion. The variable name to -be expanded may be enclosed in braces, which are optional but serve to -protect the variable to be expanded from characters immediately following it -which could be interpreted as part of the name. - -Normal variable names begin with an alphabetic character, followed by zero -or more alphanumeric characters. These names refer to entries in the GRUB -environment (@pxref{Environment}). - -Positional variable names consist of one or more digits. They represent -parameters passed to function calls, with @samp{$1} representing the first -parameter, and so on. - -The special variable name @samp{?} expands to the exit status of the most -recently executed command. When positional variable names are active, other -special variable names @samp{@@}, @samp{*} and @samp{#} are defined and they -expand to all positional parameters with necessary quoting, positional -parameters without any quoting, and positional parameter count respectively. - -@heading Comments - -A word beginning with @samp{#} causes that word and all remaining characters -on that line to be ignored. - -@heading Simple commands - -A @dfn{simple command} is a sequence of words separated by spaces or tabs -and terminated by a semicolon or a newline. The first word specifies the -command to be executed. The remaining words are passed as arguments to the -invoked command. - -The return value of a simple command is its exit status. If the reserved -word @code{!} precedes the command, then the return value is instead the -logical negation of the command's exit status. - -@heading Compound commands - -A @dfn{compound command} is one of the following: - -@table @asis -@item for @var{name} in @var{word} @dots{}; do @var{list}; done -The list of words following @code{in} is expanded, generating a list of -items. The variable @var{name} is set to each element of this list in turn, -and @var{list} is executed each time. The return value is the exit status -of the last command that executes. If the expansion of the items following -@code{in} results in an empty list, no commands are executed, and the return -status is 0. - -@item if @var{list}; then @var{list}; [elif @var{list}; then @var{list};] @dots{} [else @var{list};] fi -The @code{if} @var{list} is executed, where @var{list} is a series of -@dfn{simple command}s separated by a ";". If its exit status of the last -command is zero, the @code{then} @var{list} is executed. Otherwise, each -@code{elif} @var{list} is executed in turn, and if its last command's exit -status is zero, the corresponding @code{then} @var{list} is executed and the -command completes. Otherwise, the @code{else} @var{list} is executed, if -present. The exit status is the exit status of the last command executed, or -zero if no condition tested true. - -@item while @var{cond}; do @var{list}; done -@itemx until @var{cond}; do @var{list}; done -The @code{while} command continuously executes the @code{do} @var{list} as -long as the last command in @var{cond} returns an exit status of zero, where -@var{cond} is a list of @dfn{simple command}s separated by a ";". The -@code{until} command is identical to the @code{while} command, except that -the test is negated; the @code{do} @var{list} is executed as long as the -last command in @var{cond} returns a non-zero exit status. The exit status -of the @code{while} and @code{until} commands is the exit status of the last -@code{do} @var{list} command executed, or zero if none was executed. - -@item function @var{name} @{ @var{command}; @dots{} @} -This defines a function named @var{name}. The @dfn{body} of the function is -the list of commands within braces, each of which must be terminated with a -semicolon or a newline. This list of commands will be executed whenever -@var{name} is specified as the name of a simple command. Function -definitions do not affect the exit status in @code{$?}. When executed, the -exit status of a function is the exit status of the last command executed in -the body. - -@item menuentry @var{title} [@option{--class=class} @dots{}] [@option{--users=users}] [@option{--unrestricted}] [@option{--hotkey=key}] [@option{--id=id}] @{ @var{command}; @dots{} @} -@xref{menuentry}. -@end table - -@heading Built-in Commands - -Some built-in commands are also provided by GRUB script to help script -writers perform actions that are otherwise not possible. For example, these -include commands to jump out of a loop without fully completing it, etc. - -@table @asis -@item break [@code{n}] -Exit from within a @code{for}, @code{while}, or @code{until} loop. If -@code{n} is specified, break @code{n} levels. @code{n} must be greater than -or equal to 1. If @code{n} is greater than the number of enclosing loops, -all enclosing loops are exited. The return value is 0 unless @code{n} is -not greater than or equal to 1. - -@item continue [@code{n}] -Resume the next iteration of the enclosing @code{for}, @code{while} or -@code{until} loop. If @code{n} is specified, resume at the @code{n}th -enclosing loop. @code{n} must be greater than or equal to 1. If @code{n} -is greater than the number of enclosing loops, the last enclosing loop (the -@dfn{top-level} loop) is resumed. The return value is 0 unless @code{n} is -not greater than or equal to 1. - -@item return [@code{n}] -Causes a function to exit with the return value specified by @code{n}. If -@code{n} is omitted, the return status is that of the last command executed -in the function body. If used outside a function the return status is -false. - -@item setparams [@code{arg}] @dots{} -Replace positional parameters starting with @code{$1} with arguments to -@command{setparams}. - -@item shift [@code{n}] -The positional parameters from @code{n}+1 @dots{} are renamed to -@code{$1}@dots{}. Parameters represented by the numbers @code{$#} down to -@code{$#}-@code{n}+1 are unset. @code{n} must be a non-negative number less -than or equal to @code{$#}. If @code{n} is 0, no parameters are changed. -If @code{n} is not given, it is assumed to be 1. If @code{n} is greater -than @code{$#}, the positional parameters are not changed. The return -status is greater than zero if @code{n} is greater than @code{$#} or less -than zero; otherwise 0. - -@end table - -@node Multi-boot manual config -@section Multi-boot manual config - -Currently autogenerating config files for multi-boot environments depends on -os-prober and has several shortcomings. Due to that it is disabled by default. -It is advised to use the power of GRUB syntax and do it yourself. A possible -configuration is detailed here, feel free to adjust to your needs. - -First create a separate GRUB partition, big enough to hold GRUB. Some of the -following entries show how to load OS installer images from this same partition, -for that you obviously need to make the partition large enough to hold those -images as well. -Mount this partition on/mnt/boot and disable GRUB in all OSes and manually -install self-compiled latest GRUB with: - -@code{grub-install --boot-directory=/mnt/boot /dev/sda} - -In all the OSes install GRUB tools but disable installing GRUB in bootsector, -so you'll have menu.lst and grub.cfg available for use. Also disable os-prober -use by setting: - -@code{GRUB_DISABLE_OS_PROBER=true} - -in /etc/default/grub - -Then write a grub.cfg (/mnt/boot/grub/grub.cfg): - -@example - -menuentry "OS using grub2" @{ - insmod xfs - search --set=root --label OS1 --hint hd0,msdos8 - configfile /boot/grub/grub.cfg -@} - -menuentry "OS using grub2-legacy" @{ - insmod ext2 - search --set=root --label OS2 --hint hd0,msdos6 - legacy_configfile /boot/grub/menu.lst -@} - -menuentry "Windows XP" @{ - insmod ntfs - search --set=root --label WINDOWS_XP --hint hd0,msdos1 - ntldr /ntldr -@} - -menuentry "Windows 7" @{ - insmod ntfs - search --set=root --label WINDOWS_7 --hint hd0,msdos2 - ntldr /bootmgr -@} - -menuentry "FreeBSD" @{ - insmod zfs - search --set=root --label freepool --hint hd0,msdos7 - kfreebsd /freebsd@@/boot/kernel/kernel - kfreebsd_module_elf /freebsd@@/boot/kernel/opensolaris.ko - kfreebsd_module_elf /freebsd@@/boot/kernel/zfs.ko - kfreebsd_module /freebsd@@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache - set kFreeBSD.vfs.root.mountfrom=zfs:freepool/freebsd - set kFreeBSD.hw.psm.synaptics_support=1 -@} - -menuentry "experimental GRUB" @{ - search --set=root --label GRUB --hint hd0,msdos5 - multiboot /experimental/grub/i386-pc/core.img -@} - -menuentry "Fedora 16 installer" @{ - search --set=root --label GRUB --hint hd0,msdos5 - linux /fedora/vmlinuz lang=en_US keymap=sg resolution=1280x800 - initrd /fedora/initrd.img -@} - -menuentry "Fedora rawhide installer" @{ - search --set=root --label GRUB --hint hd0,msdos5 - linux /fedora/vmlinuz repo=ftp://mirror.switch.ch/mirror/fedora/linux/development/rawhide/x86_64 lang=en_US keymap=sg resolution=1280x800 - initrd /fedora/initrd.img -@} - -menuentry "Debian sid installer" @{ - search --set=root --label GRUB --hint hd0,msdos5 - linux /debian/dists/sid/main/installer-amd64/current/images/hd-media/vmlinuz - initrd /debian/dists/sid/main/installer-amd64/current/images/hd-media/initrd.gz -@} - -@end example - -Notes: -@itemize -@item Argument to search after --label is FS LABEL. You can also use UUIDs with --fs-uuid UUID instead of --label LABEL. You could also use direct @code{root=hd0,msdosX} but this is not recommended due to device name instability. -@end itemize - -@node Embedded configuration -@section Embedding a configuration file into GRUB - -GRUB supports embedding a configuration file directly into the core image, -so that it is loaded before entering normal mode. This is useful, for -example, when it is not straightforward to find the real configuration file, -or when you need to debug problems with loading that file. -@command{grub-install} uses this feature when it is not using BIOS disk -functions or when installing to a different disk from the one containing -@file{/boot/grub}, in which case it needs to use the @command{search} -command (@pxref{search}) to find @file{/boot/grub}. - -To embed a configuration file, use the @option{-c} option to -@command{grub-mkimage}. The file is copied into the core image, so it may -reside anywhere on the file system, and may be removed after running -@command{grub-mkimage}. - -After the embedded configuration file (if any) is executed, GRUB will load -the @samp{normal} module (@pxref{normal}), which will then read the real -configuration file from @file{$prefix/grub.cfg}. By this point, the -@code{root} variable will also have been set to the root device name. For -example, @code{prefix} might be set to @samp{(hd0,1)/boot/grub}, and -@code{root} might be set to @samp{hd0,1}. Thus, in most cases, the embedded -configuration file only needs to set the @code{prefix} and @code{root} -variables, and then drop through to GRUB's normal processing. A typical -example of this might look like this: - -@example -@group -search.fs_uuid 01234567-89ab-cdef-0123-456789abcdef root -set prefix=($root)/boot/grub -@end group -@end example - -(The @samp{search_fs_uuid} module must be included in the core image for this -example to work.) - -In more complex cases, it may be useful to read other configuration files -directly from the embedded configuration file. This allows such things as -reading files not called @file{grub.cfg}, or reading files from a directory -other than that where GRUB's loadable modules are installed. To do this, -include the @samp{configfile} and @samp{normal} modules in the core image, -and embed a configuration file that uses the @command{configfile} command to -load another file. The following example of this also requires the -@command{echo}, @command{search_label}, and @command{test} modules to be -included in the core image: - -@example -@group -search.fs_label grub root -if [ -e /boot/grub/example/test1.cfg ]; then - set prefix=($root)/boot/grub - configfile /boot/grub/example/test1.cfg -else - if [ -e /boot/grub/example/test2.cfg ]; then - set prefix=($root)/boot/grub - configfile /boot/grub/example/test2.cfg - else - echo "Could not find an example configuration file!" - fi -fi -@end group -@end example - -The embedded configuration file may not contain menu entries directly, but -may only read them from elsewhere using @command{configfile}. - -@node Theme file format -@chapter Theme file format -@section Introduction -The GRUB graphical menu supports themes that can customize the layout and -appearance of the GRUB boot menu. The theme is configured through a plain -text file that specifies the layout of the various GUI components (including -the boot menu, timeout progress bar, and text messages) as well as the -appearance using colors, fonts, and images. Example is available in docs/example_theme.txt - -@section Theme Elements -@subsection Colors - -Colors can be specified in several ways: - -@itemize -@item HTML-style ``#RRGGBB'' or ``#RGB'' format, where *R*, *G*, and *B* are hexadecimal digits (e.g., ``#8899FF'') -@item as comma-separated decimal RGB values (e.g., ``128, 128, 255'') -@item with ``SVG 1.0 color names'' (e.g., ``cornflowerblue'') which must be specified in lowercase. -@end itemize -@subsection Fonts -The fonts GRUB uses ``PFF2 font format'' bitmap fonts. Fonts are specified -with full font names. Currently there is no -provision for a preference list of fonts, or deriving one font from another. -Fonts are loaded with the ``loadfont'' command in GRUB (@ref{loadfont}). To see the list of -loaded fonts, execute the ``lsfonts'' command (@ref{lsfonts}). If there are too many fonts to -fit on screen, do ``set pager=1'' before executing ``lsfonts''. - - -@subsection Progress Bar - -@float Figure, Pixmap-styled progress bar -@c @image{Theme_progress_bar,,,,png} -@end float - -@float Figure, Plain progress bar, drawn with solid color. -@c @image{Theme_progress_bar_filled,,,,png} -@end float - -Progress bars are used to display the remaining time before GRUB boots the -default menu entry. To create a progress bar that will display the remaining -time before automatic boot, simply create a ``progress_bar'' component with -the id ``__timeout__''. This indicates to GRUB that the progress bar should -be updated as time passes, and it should be made invisible if the countdown to -automatic boot is interrupted by the user. - -Progress bars may optionally have text displayed on them. This text is -controlled by variable ``text'' which contains a printf template with the -only argument %d is the number of seconds remaining. Additionally special -values ``@@TIMEOUT_NOTIFICATION_SHORT@@'', ``@@TIMEOUT_NOTIFICATION_MIDDLE@@'', -``@@TIMEOUT_NOTIFICATION_LONG@@'' are replaced with standard and translated -templates. - -@subsection Circular Progress Indicator - -@c @image{Theme_circular_progress,,,,.png} - -The circular progress indicator functions similarly to the progress bar. When -given an id of ``__timeout__'', GRUB updates the circular progress indicator's -value to indicate the time remaining. For the circular progress indicator, -there are two images used to render it: the *center* image, and the *tick* -image. The center image is rendered in the center of the component, while the -tick image is used to render each mark along the circumference of the -indicator. - - -@subsection Labels - -Text labels can be placed on the boot screen. The font, color, and horizontal -alignment can be specified for labels. If a label is given the id -``__timeout__'', then the ``text'' property for that label is also updated -with a message informing the user of the number of seconds remaining until -automatic boot. This is useful in case you want the text displayed somewhere -else instead of directly on the progress bar. - - -@subsection Boot Menu - -@c @image{Theme_boot_menu,,,,.png} - -The boot menu where GRUB displays the menu entries from the ``grub.cfg'' file. -It is a list of items, where each item has a title and an optional icon. The -icon is selected based on the *classes* specified for the menu entry. If -there is a PNG file named ``myclass.png'' in the ``grub/themes/icons'' -directory, it will be displayed for items which have the class *myclass*. The -boot menu can be customized in several ways, such as the font and color used -for the menu entry title, and by specifying styled boxes for the menu itself -and for the selected item highlight. - - -@subsection Styled Boxes - -One of the most important features for customizing the layout is the use of - *styled boxes*. A styled box is composed of 9 rectangular (and potentially -empty) regions, which are used to seamlessly draw the styled box on screen: - -@multitable @columnfractions 0.3 0.3 0.3 -@item Northwest (nw) @tab North (n) @tab Northeast (ne) -@item West (w) @tab Center (c) @tab East (e) -@item Southwest (sw) @tab South (s) @tab Southeast (se) -@end multitable - -To support any size of box on screen, the center slice and the slices for the -top, bottom, and sides are all scaled to the correct size for the component on -screen, using the following rules: - -@enumerate -@item The edge slices (north, south, east, and west) are scaled in the direction of the edge they are adjacent to. For instance, the west slice is scaled vertically. -@item The corner slices (northwest, northeast, southeast, and southwest) are not scaled. -@item The center slice is scaled to fill the remaining space in the middle. -@end enumerate - -As an example of how an image might be sliced up, consider the styled box -used for a terminal view. - -@float Figure, An example of the slices (in red) used for a terminal window. This drawing was created and sliced in Inkscape_, as the next section explains. -@c @image{Box_slice_example_terminal,,,,.png} -@end float - -@subsection Creating Styled Box Images - -The Inkscape_ scalable vector graphics editor is a very useful tool for -creating styled box images. One process that works well for slicing a drawing -into the necessary image slices is: - -@enumerate -@item Create or open the drawing you'd like use. -@item Create a new layer on the top of the layer stack. Make it visible. Select this layer as the current layer. -@item Draw 9 rectangles on your drawing where you'd like the slices to be. Clear the fill option, and set the stroke to 1 pixel wide solid stroke. The corners of the slices must meet precisely; if it is off by a single pixel, it will probably be evident when the styled box is rendered in the GRUB menu. You should probably go to File | Document Properties | Grids and enable a grid or create a guide (click on one of the rulers next to the drawing and drag over the drawing; release the mouse button to place the guide) to help place the rectangles precisely. -@item Right click on the center slice rectangle and choose Object Properties. Change the "Id" to ``slice_c`` and click Set. Repeat this for the remaining 8 rectangles, giving them Id values of ``slice_n``, ``slice_ne``, ``slice_e``, and so on according to the location. -@item Save the drawing. -@item Select all the slice rectangles. With the slice layer selected, you can simply press Ctrl+A to select all rectangles. The status bar should indicate that 9 rectangles are selected. -@item Click the layer hide icon for the slice layer in the layer palette. The rectangles will remain selected, even though they are hidden. -@item Choose File | Export Bitmap and check the *Batch export 9 selected objects* box. Make sure that *Hide all except selected* is unchecked. click *Export*. This will create PNG files in the same directory as the drawing, named after the slices. These can now be used for a styled box in a GRUB theme. -@end enumerate - -@section Theme File Manual - -The theme file is a plain text file. Lines that begin with ``#`` are ignored -and considered comments. (Note: This may not be the case if the previous line -ended where a value was expected.) - -The theme file contains two types of statements: -@enumerate -@item Global properties. -@item Component construction. -@end enumerate - -@subsection Global Properties - -@subsection Format - -Global properties are specified with the simple format: -@itemize -@item name1: value1 -@item name2: "value which may contain spaces" -@item name3: #88F -@end itemize - -In this example, name3 is assigned a color value. - - -@subsection Global Property List - -@multitable @columnfractions 0.3 0.6 -@item title-text - @tab Specifies the text to display at the top center of the screen as a title. -@item title-font - @tab Defines the font used for the title message at the top of the screen. -@item title-color - @tab Defines the color of the title message. -@item message-font - @tab Currently unused. Left for backward compatibility. -@item message-color - @tab Currently unused. Left for backward compatibility. -@item message-bg-color - @tab Currently unused. Left for backward compatibility. -@item desktop-image - @tab Specifies the image to use as the background. It will be scaled - to fit the screen size or proportionally scaled depending on the scale - method. -@item desktop-image-scale-method - @tab Specifies the scaling method for the *desktop-image*. Options are - ``stretch``, ``crop``, ``padding``, ``fitwidth``, ``fitheight``. - ``stretch`` for fitting the screen size. Otherwise it is proportional - scaling of a part of *desktop-image* to the part of the screen. - ``crop`` part of the *desktop-image* will be proportionally scaled to - fit the screen sizes. ``padding`` the entire *desktop-image* will be - contained on the screen. ``fitwidth`` for fitting the *desktop-image*'s - width with screen width. ``fitheight`` for fitting the *desktop-image*'s - height with the screen height. Default is ``stretch``. -@item desktop-image-h-align - @tab Specifies the horizontal alignment of the *desktop-image* if - *desktop-image-scale-method* isn't equeal to ``stretch``. Options are - ``left``, ``center``, ``right``. Default is ``center``. -@item desktop-image-v-align - @tab Specifies the vertical alignment of the *desktop-image* if - *desktop-image-scale-method* isn't equeal to ``stretch``. Options are - ``top``, ``center``, ``bottom``. Default is ``center``. -@item desktop-color - @tab Specifies the color for the background if *desktop-image* is not - specified. -@item terminal-box - @tab Specifies the file name pattern for the styled box slices used for the - command line terminal window. For example, ``terminal-box: terminal_*.png`` - will use the images ``terminal_c.png`` as the center area, ``terminal_n.png`` - as the north (top) edge, ``terminal_nw.png`` as the northwest (upper left) - corner, and so on. If the image for any slice is not found, it will simply - be left empty. -@item terminal-border - @tab Specifies the border width of the terminal window. -@item terminal-left - @tab Specifies the left coordinate of the terminal window. -@item terminal-top - @tab Specifies the top coordinate of the terminal window. -@item terminal-width - @tab Specifies the width of the terminal window. -@item terminal-height - @tab Specifies the height of the terminal window. -@end multitable - - -@subsection Component Construction - -Greater customizability comes is provided by components. A tree of components -forms the user interface. *Containers* are components that can contain other -components, and there is always a single root component which is an instance -of a *canvas* container. - -Components are created in the theme file by prefixing the type of component -with a '+' sign: - -@code{ + label @{ text="GRUB" font="aqui 11" color="#8FF" @} } - -properties of a component are specified as "name = value" (whitespace -surrounding tokens is optional and is ignored) where *value* may be: -@itemize -@item a single word (e.g., ``align = center``, ``color = #FF8080``), -@item a quoted string (e.g., ``text = "Hello, World!"``), or -@item a tuple (e.g., ``preferred_size = (120, 80)``). -@end itemize - -@subsection Component List - -The following is a list of the components and the properties they support. - -@itemize -@item label - A label displays a line of text. - - Properties: - @multitable @columnfractions 0.2 0.7 - @item id - @tab Set to ``__timeout__`` to display the time elapsed to an automatical - boot of the default entry. - @item text - @tab The text to display. If ``id`` is set to ``__timeout__`` and no - ``text`` property is set then the amount of seconds will be shown. - If set to ``@@KEYMAP_SHORT@@``, ``@@KEYMAP_MIDDLE@@`` or - ``@@KEYMAP_LONG@@`` then predefined hotkey information will be shown. - @item font - @tab The font to use for text display. - @item color - @tab The color of the text. - @item align - @tab The horizontal alignment of the text within the component. - Options are ``left``, ``center`` and ``right``. - @item visible - @tab Set to ``false`` to hide the label. - @end multitable - -@item image - A component that displays an image. The image is scaled to fit - the component. - - Properties: - - @multitable @columnfractions 0.2 0.7 - @item file - @tab The full path to the image file to load. - @end multitable - -@item progress_bar - Displays a horizontally oriented progress bar. It can be rendered using - simple solid filled rectangles, or using a pair of pixmap styled boxes. - - Properties: - - @multitable @columnfractions 0.2 0.7 - @item id - @tab Set to ``__timeout__`` to display the time elapsed to an automatical - boot of the default entry. - @item fg_color - @tab The foreground color for plain solid color rendering. - @item bg_color - @tab The background color for plain solid color rendering. - @item border_color - @tab The border color for plain solid color rendering. - @item text_color - @tab The text color. - @item bar_style - @tab The styled box specification for the frame of the progress bar. - Example: ``progress_frame_*.png`` - If the value is equal to ``highlight_style`` then no styled boxes - will be shown. - @item highlight_style - @tab The styled box specification for the highlighted region of the - progress bar. This box will be used to paint just the highlighted region - of the bar, and will be increased in size as the bar nears completion. - Example: ``progress_hl_*.png``. - If the value is equal to ``bar_style`` then no styled boxes - will be shown. - @item highlight_overlay - @tab If this option is set to ``true`` then the highlight box - side slices (every slice except the center slice) will overlay the - frame box side slices. And the center slice of the highlight box - can move all the way (from top to bottom), being drawn on the center - slice of the frame box. That way we can make a progress bar with - round-shaped edges so there won't be a free space from the highlight to - the frame in top and bottom scrollbar positions. Default is ``false``. - @item font - @tab The font to use for progress bar. - @item text - @tab The text to display on the progress bar. If the progress bar's ID - is set to ``__timeout__`` and the value of this property is set to - ``@@TIMEOUT_NOTIFICATION_SHORT@@``, ``@@TIMEOUT_NOTIFICATION_MIDDLE@@`` - or ``@@TIMEOUT_NOTIFICATION_LONG@@``, then GRUB will update this - property with an informative message as the timeout approaches. - @end multitable - -@item circular_progress - Displays a circular progress indicator. The appearance of this component - is determined by two images: the *center* image and the *tick* image. The - center image is generally larger and will be drawn in the center of the - component. Around the circumference of a circle within the component, the - tick image will be drawn a certain number of times, depending on the - properties of the component. - - Properties: - - @multitable @columnfractions 0.3 0.6 - @item id - @tab Set to ``__timeout__`` to display the time elapsed to an automatical - boot of the default entry. - @item center_bitmap - @tab The file name of the image to draw in the center of the component. - @item tick_bitmap - @tab The file name of the image to draw for the tick marks. - @item num_ticks - @tab The number of ticks that make up a full circle. - @item ticks_disappear - @tab Boolean value indicating whether tick marks should progressively appear, - or progressively disappear as *value* approaches *end*. Specify - ``true`` or ``false``. Default is ``false``. - @item start_angle - @tab The position of the first tick mark to appear or disappear. - Measured in "parrots", 1 "parrot" = 1 / 256 of the full circle. - Use values ``xxx deg`` or ``xxx \xc2\xb0`` to set the angle in degrees. - @end multitable - -@item boot_menu - Displays the GRUB boot menu. It allows selecting items and executing them. - - Properties: - - @multitable @columnfractions 0.4 0.5 - @item item_font - @tab The font to use for the menu item titles. - @item selected_item_font - @tab The font to use for the selected menu item, or ``inherit`` (the default) - to use ``item_font`` for the selected menu item as well. - @item item_color - @tab The color to use for the menu item titles. - @item selected_item_color - @tab The color to use for the selected menu item, or ``inherit`` (the default) - to use ``item_color`` for the selected menu item as well. - @item icon_width - @tab The width of menu item icons. Icons are scaled to the specified size. - @item icon_height - @tab The height of menu item icons. - @item item_height - @tab The height of each menu item in pixels. - @item item_padding - @tab The amount of space in pixels to leave on each side of the menu item - contents. - @item item_icon_space - @tab The space between an item's icon and the title text, in pixels. - @item item_spacing - @tab The amount of space to leave between menu items, in pixels. - @item menu_pixmap_style - @tab The image file pattern for the menu frame styled box. - Example: ``menu_*.png`` (this will use images such as ``menu_c.png``, - ``menu_w.png``, `menu_nw.png``, etc.) - @item item_pixmap_style - @tab The image file pattern for the item styled box. - @item selected_item_pixmap_style - @tab The image file pattern for the selected item highlight styled box. - @item scrollbar - @tab Boolean value indicating whether the scroll bar should be drawn if the - frame and thumb styled boxes are configured. - @item scrollbar_frame - @tab The image file pattern for the entire scroll bar. - Example: ``scrollbar_*.png`` - @item scrollbar_thumb - @tab The image file pattern for the scroll bar thumb (the part of the scroll - bar that moves as scrolling occurs). - Example: ``scrollbar_thumb_*.png`` - @item scrollbar_thumb_overlay - @tab If this option is set to ``true`` then the scrollbar thumb - side slices (every slice except the center slice) will overlay the - scrollbar frame side slices. And the center slice of the scrollbar_thumb - can move all the way (from top to bottom), being drawn on the center - slice of the scrollbar frame. That way we can make a scrollbar with - round-shaped edges so there won't be a free space from the thumb to - the frame in top and bottom scrollbar positions. Default is ``false``. - @item scrollbar_slice - @tab The menu frame styled box's slice in which the scrollbar will be - drawn. Possible values are ``west``, ``center``, ``east`` (default). - ``west`` - the scrollbar will be drawn in the west slice (right-aligned). - ``east`` - the scrollbar will be drawn in the east slice (left-aligned). - ``center`` - the scrollbar will be drawn in the center slice. - Note: in case of ``center`` slice: - a) If the scrollbar should be drawn then boot menu entry's width is - decreased by the scrollbar's width and the scrollbar is drawn at the - right side of the center slice. - b) If the scrollbar won't be drawn then the boot menu entry's width - is the width of the center slice. - c) We don't necessary need the menu pixmap box to display the scrollbar. - @item scrollbar_left_pad - @tab The left scrollbar padding in pixels. - Unused if ``scrollbar_slice`` is ``west``. - @item scrollbar_right_pad - @tab The right scrollbar padding in pixels. - Unused if ``scrollbar_slice`` is ``east``. - @item scrollbar_top_pad - @tab The top scrollbar padding in pixels. - @item scrollbar_bottom_pad - @tab The bottom scrollbar padding in pixels. - @item visible - @tab Set to ``false`` to hide the boot menu. - @end multitable - -@item canvas - Canvas is a container that allows manual placement of components within it. - It does not alter the positions of its child components. It assigns all - child components their preferred sizes. - -@item hbox - The *hbox* container lays out its children from left to right, giving each - one its preferred width. The height of each child is set to the maximum of - the preferred heights of all children. - -@item vbox - The *vbox* container lays out its children from top to bottom, giving each - one its preferred height. The width of each child is set to the maximum of - the preferred widths of all children. -@end itemize - - -@subsection Common properties - -The following properties are supported by all components: -@table @samp -@item left - The distance from the left border of container to left border of the object in either of three formats: - @multitable @columnfractions 0.2 0.7 - @item x @tab Value in pixels - @item p% @tab Percentage - @item p%+x @tab mixture of both - @end multitable -@item top - The distance from the left border of container to left border of the object in same format. -@item width - The width of object in same format. -@item height - The height of object in same format. -@item id - The identifier for the component. This can be any arbitrary string. - The ID can be used by scripts to refer to various components in the GUI - component tree. Currently, there is one special ID value that GRUB - recognizes: - - @multitable @columnfractions 0.2 0.7 - @item ``__timeout__`` - @tab Component with this ID will be updated by GRUB and will indicate - time elapsed to an automatical boot of the default entry. - Affected components: ``label``, ``circular_progress``, ``progress_bar``. - @end multitable -@end table - - - -@node Network -@chapter Booting GRUB from the network - -The following instructions don't work for *-emu, i386-qemu, i386-coreboot, -i386-multiboot, mips_loongson, mips-arc and mips_qemu_mips - -To generate a netbootable directory, run: - -@example -@group -grub-mknetdir --net-directory=/srv/tftp --subdir=/boot/grub -d /usr/lib/grub/ -@end group -@end example - -E.g. for i386-pc: - -@example -@group -grub-mknetdir --net-directory=/srv/tftp --subdir=/boot/grub -d /usr/lib/grub/i386-pc -@end group -@end example - -Then follow instructions printed out by grub-mknetdir on configuring your DHCP -server. - -The grub.cfg file is placed in the same directory as the path output by -grub-mknetdir hereafter referred to as FWPATH. GRUB will search for its -configuration files in order using the following rules where the appended -value corresponds to a value on the client machine. - -@example -@group -@samp{(FWPATH)}/grub.cfg-@samp{(UUID OF MACHINE)} -@samp{(FWPATH)}/grub.cfg-01-@samp{(MAC ADDRESS OF NIC)} -@samp{(FWPATH)}/grub.cfg-@samp{(IPv4 OR IPv6 ADDRESS)} -@samp{(FWPATH)}/grub.cfg -@end group -@end example - -The UUID is the Client Machine Identifier Option Definition as specified in -RFC 4578. The client will only attempt to look up a UUID config file if it -was provided by the DHCP server. - -The client will only attempt to look up an IPv6 address config once, however, -it will try the IPv4 multiple times. The concrete example below shows what -would happen under the IPv4 case. - -@example -@group -UUID: 7726a678-7fc0-4853-a4f6-c85ac36a120a -MAC: 52:54:00:ec:33:81 -IPV4: 10.0.0.130 (0A000082) -@end group -@end example - -@example -@group -@samp{(FWPATH)}/grub.cfg-7726a678-7fc0-4853-a4f6-c85ac36a120a -@samp{(FWPATH)}/grub.cfg-01-52-54-00-ec-33-81 -@samp{(FWPATH)}/grub.cfg-0A000082 -@samp{(FWPATH)}/grub.cfg-0A00008 -@samp{(FWPATH)}/grub.cfg-0A0000 -@samp{(FWPATH)}/grub.cfg-0A000 -@samp{(FWPATH)}/grub.cfg-0A00 -@samp{(FWPATH)}/grub.cfg-0A0 -@samp{(FWPATH)}/grub.cfg-0A -@samp{(FWPATH)}/grub.cfg-0 -@samp{(FWPATH)}/grub.cfg -@end group -@end example - -This feature is enabled by default but it can be disabled by setting the -@samp{feature_net_search_cfg} to @samp{n}. Since this happens before the -configuration file is read by GRUB, this option has to be disabled in an -embedded configuration file (@pxref{Embedded configuration}). - -After GRUB has started, files on the TFTP server will be accessible via the -@samp{(tftp)} device. - -The server IP address can be controlled by changing the -@samp{(tftp)} device name to @samp{(tftp,@var{server-ip})}. Note that -this should be changed both in the prefix and in any references to the -device name in the configuration file. - -GRUB provides several environment variables which may be used to inspect or -change the behaviour of the PXE device. In the following description -@var{} is placeholder for the name of network interface (platform -dependent): - -@table @samp -@item net_@var{}_ip -The network interface's IP address. Read-only. - -@item net_@var{}_mac -The network interface's MAC address. Read-only. - -@item net_@var{}_clientid -The client id provided by DHCP. Read-only. - -@item net_@var{}_clientuuid -The client uuid provided by DHCP. Read-only. - -@item net_@var{}_hostname -The client host name provided by DHCP. Read-only. - -@item net_@var{}_domain -The client domain name provided by DHCP. Read-only. - -@item net_@var{}_rootpath -The path to the client's root disk provided by DHCP. Read-only. - -@item net_@var{}_extensionspath -The path to additional DHCP vendor extensions provided by DHCP. Read-only. - -@item net_@var{}_boot_file -The boot file name provided by DHCP. Read-only. - -@item net_@var{}_dhcp_server_name -The name of the DHCP server responsible for these boot parameters. -Read-only. - -@item net_@var{}_next_server -The IP address of the next (usually, TFTP) server provided by DHCP. -Read-only. - -@item net_default_interface -Initially set to name of network interface that was used to load grub. -Read-write, although setting it affects only interpretation of -@samp{net_default_ip} and @samp{net_default_mac} - -@item net_default_ip -The IP address of default interface. Read-only. This is alias for the -@samp{net_$@{net_default_interface@}_ip}. - -@item net_default_mac -The default interface's MAC address. Read-only. This is alias for the -@samp{net_$@{net_default_interface@}_mac}. - -@item net_default_server -The default server used by network drives (@pxref{Device syntax}). Read-write, -although setting this is only useful before opening a network device. - -@item pxe_default_server -This performs the same function as @samp{net_default_server}. - -@end table +@strong{Caution:} If you use an initrd and specify the @samp{mem=} +option to the kernel to let it use less than actual memory size, you +will also have to specify the same memory size to GRUB. To let GRUB know +the size, run the command @command{uppermem} @emph{before} loading the +kernel. @xref{uppermem}, for more information. @node Serial terminal @@ -2708,265 +712,42 @@ minicom. Refer to a manual of your operating system, for more information. As for GRUB, the instruction to set up a serial terminal is quite -simple. Here is an example: +simple. First of all, make sure that you haven't specified the option +@option{--disable-serial} to the configure script when you built your +GRUB images. If you get them in binary form, probably they have serial +terminal support already. + +Then, initialize your serial terminal after GRUB starts up. Here is an +example: @example @group grub> @kbd{serial --unit=0 --speed=9600} -grub> @kbd{terminal_input serial; terminal_output serial} +grub> @kbd{terminal serial} @end group @end example The command @command{serial} initializes the serial unit 0 with the speed 9600bps. The serial unit 0 is usually called @samp{COM1}, so, if you want to use COM2, you must specify @samp{--unit=1} instead. This -command accepts many other options, @pxref{serial} for more details. +command accepts many other options, so please refer to @ref{serial}, +for more details. -Without argument or with @samp{--port=auto}, GRUB will attempt to use -ACPI when available to auto-detect the default serial port and its -configuration. - -The commands @command{terminal_input} (@pxref{terminal_input}) and -@command{terminal_output} (@pxref{terminal_output}) choose which type of +The command @command{terminal} (@pxref{terminal}) chooses which type of terminal you want to use. In the case above, the terminal will be a serial terminal, but you can also pass @code{console} to the command, -as @samp{terminal_input serial console}. In this case, a terminal in which -you press any key will be selected as a GRUB terminal. In the example above, -note that you need to put both commands on the same command line, as you -will lose the ability to type commands on the console after the first -command. +as @samp{terminal serial console}. In this case, a terminal in which +you press any key will be selected as a GRUB terminal. However, note that GRUB assumes that your terminal emulator is compatible with VT100 by default. This is true for most terminal -emulators nowadays. However if your terminal emulator is not VT100-compatible -or implements few VT100 escape sequences, you shoud tell GRUB that the -terminal is dumb using the @command{terminfo} (@pxref{terminfo}) command. -This will have GRUB provide you with an alternative menu interface, because -the normal menu requires several fancy features of your terminal. +emulators nowadays, but you should pass the option @option{--dumb} to +the command if your terminal emulator is not VT100-compatible or +implements few VT100 escape sequences. If you specify this option then +GRUB provides you with an alternative menu interface, because the normal +menu requires several fancy features of your terminal. -@node Vendor power-on keys -@chapter Using GRUB with vendor power-on keys - -Some laptop vendors provide an additional power-on button which boots -another OS. GRUB supports such buttons with the @samp{GRUB_TIMEOUT_BUTTON}, -@samp{GRUB_TIMEOUT_STYLE_BUTTON}, @samp{GRUB_DEFAULT_BUTTON}, and -@samp{GRUB_BUTTON_CMOS_ADDRESS} variables in default/grub (@pxref{Simple -configuration}). @samp{GRUB_TIMEOUT_BUTTON}, -@samp{GRUB_TIMEOUT_STYLE_BUTTON}, and @samp{GRUB_DEFAULT_BUTTON} are used -instead of the corresponding variables without the @samp{_BUTTON} suffix -when powered on using the special button. @samp{GRUB_BUTTON_CMOS_ADDRESS} -is vendor-specific and partially model-specific. Values known to the GRUB -team are: - -@table @key -@item Dell XPS M1330M -121:3 -@item Dell XPS M1530 -85:3 -@item Dell Latitude E4300 -85:3 -@item Asus EeePC 1005PE -84:1 (unconfirmed) -@item LENOVO ThinkPad T410s (2912W1C) -101:3 -@end table - -To take full advantage of this function, install GRUB into the MBR -(@pxref{Installing GRUB using grub-install}). - -If you have a laptop which has a similar feature and not in the above list -could you figure your address and contribute? -To discover the address do the following: -@itemize -@item boot normally -@item -@example -sudo modprobe nvram -sudo cat /dev/nvram | xxd > normal_button.txt -@end example -@item boot using vendor button -@item -@example -sudo modprobe nvram -sudo cat /dev/nvram | xxd > normal_vendor.txt -@end example -@end itemize - -Then compare these text files and find where a bit was toggled. E.g. in -case of Dell XPS it was: -@example -byte 0x47: 20 --> 28 -@end example -It's a bit number 3 as seen from following table: -@multitable @columnfractions .2 .2 -@item 0 @tab 01 -@item 1 @tab 02 -@item 2 @tab 04 -@item 3 @tab 08 -@item 4 @tab 10 -@item 5 @tab 20 -@item 6 @tab 40 -@item 7 @tab 80 -@end multitable - -0x47 is decimal 71. Linux nvram implementation cuts first 14 bytes of -CMOS. So the real byte address in CMOS is 71+14=85 -So complete address is 85:3 - -@node Images -@chapter GRUB image files - -@c FIXME: parts of this section are specific to PC BIOS right now. - -GRUB consists of several images: a variety of bootstrap images for starting -GRUB in various ways, a kernel image, and a set of modules which are -combined with the kernel image to form a core image. Here is a short -overview of them. - -@table @file -@item boot.img -On PC BIOS systems, this image is the first part of GRUB to start. It is -written to a master boot record (MBR) or to the boot sector of a partition. -Because a PC boot sector is 512 bytes, the size of this image is exactly 512 -bytes. - -The sole function of @file{boot.img} is to read the first sector of the core -image from a local disk and jump to it. Because of the size restriction, -@file{boot.img} cannot understand any file system structure, so -@command{grub-install} hardcodes the location of the first sector of the -core image into @file{boot.img} when installing GRUB. - -@item diskboot.img -This image is used as the first sector of the core image when booting from a -hard disk. It reads the rest of the core image into memory and starts the -kernel. Since file system handling is not yet available, it encodes the -location of the core image using a block list format. - -@item cdboot.img -This image is used as the first sector of the core image when booting from a -CD-ROM drive. It performs a similar function to @file{diskboot.img}. - -@item pxeboot.img -This image is used as the start of the core image when booting from the -network using PXE. @xref{Network}. - -@item lnxboot.img -This image may be placed at the start of the core image in order to make -GRUB look enough like a Linux kernel that it can be booted by LILO using an -@samp{image=} section. - -@item kernel.img -This image contains GRUB's basic run-time facilities: frameworks for device -and file handling, environment variables, the rescue mode command-line -parser, and so on. It is rarely used directly, but is built into all core -images. - -@item core.img -This is the core image of GRUB. It is built dynamically from the kernel -image and an arbitrary list of modules by the @command{grub-mkimage} -program. Usually, it contains enough modules to access @file{/boot/grub}, -and loads everything else (including menu handling, the ability to load -target operating systems, and so on) from the file system at run-time. The -modular design allows the core image to be kept small, since the areas of -disk where it must be installed are often as small as 32KB. - -@xref{BIOS installation}, for details on where the core image can be -installed on PC systems. - -@item *.mod -Everything else in GRUB resides in dynamically loadable modules. These are -often loaded automatically, or built into the core image if they are -essential, but may also be loaded manually using the @command{insmod} -command (@pxref{insmod}). -@end table - -@heading For GRUB Legacy users - -GRUB 2 has a different design from GRUB Legacy, and so correspondences with -the images it used cannot be exact. Nevertheless, GRUB Legacy users often -ask questions in the terms they are familiar with, and so here is a brief -guide to how GRUB 2's images relate to that. - -@table @file -@item stage1 -Stage 1 from GRUB Legacy was very similar to @file{boot.img} in GRUB 2, and -they serve the same function. - -@item *_stage1_5 -In GRUB Legacy, Stage 1.5's function was to include enough filesystem code -to allow the much larger Stage 2 to be read from an ordinary filesystem. In -this respect, its function was similar to @file{core.img} in GRUB 2. -However, @file{core.img} is much more capable than Stage 1.5 was; since it -offers a rescue shell, it is sometimes possible to recover manually in the -event that it is unable to load any other modules, for example if partition -numbers have changed. @file{core.img} is built in a more flexible way, -allowing GRUB 2 to support reading modules from advanced disk types such as -LVM and RAID. - -GRUB Legacy could run with only Stage 1 and Stage 2 in some limited -configurations, while GRUB 2 requires @file{core.img} and cannot work -without it. - -@item stage2 -GRUB 2 has no single Stage 2 image. Instead, it loads modules from -@file{/boot/grub} at run-time. - -@item stage2_eltorito -In GRUB 2, images for booting from CD-ROM drives are now constructed using -@file{cdboot.img} and @file{core.img}, making sure that the core image -contains the @samp{iso9660} module. It is usually best to use the -@command{grub-mkrescue} program for this. - -@item nbgrub -There is as yet no equivalent for @file{nbgrub} in GRUB 2; it was used by -Etherboot and some other network boot loaders. - -@item pxegrub -In GRUB 2, images for PXE network booting are now constructed using -@file{pxeboot.img} and @file{core.img}, making sure that the core image -contains the @samp{pxe} and @samp{pxecmd} modules. @xref{Network}. -@end table - -@node Core image size limitation -@chapter Core image size limitation - -Heavily limited platforms: -@itemize -@item i386-pc (normal and PXE): the core image size (compressed) is limited by 458240 bytes. - kernel.img (.text + .data + .bss, uncompressed) is limited by 392704 bytes. - module size (uncompressed) + kernel.img (.text + .data, uncompressed) is limited by the size of contiguous chunk at 1M address. -@item sparc64-ieee1275: kernel.img (.text + .data + .bss) + modules + 256K (stack) + 2M (heap) is limited by space available at 0x4400. On most platforms it's just 3 or 4M since ieee1275 maps only so much. -@item i386-ieee1275: kernel.img (.text + .data + .bss) + modules is limited by memory available at 0x10000, at most 596K -@end itemize - -Lightly limited platforms: - -@itemize -@item *-xen: limited only by adress space and RAM size. -@item i386-qemu: kernel.img (.text + .data + .bss) is limited by 392704 bytes. - (core.img would be limited by ROM size but it's unlimited on qemu -@item All EFI platforms: limited by contiguous RAM size and possibly firmware bugs -@item Coreboot and multiboot. kernel.img (.text + .data + .bss) is limited by 392704 bytes. - module size is limited by the size of contiguous chunk at 1M address. -@item mipsel-loongson (ELF), mips(el)-qemu_mips (ELF): if uncompressed: - kernel.img (.text + .data) + modules is limited by the space from 80200000 forward - if compressed: - kernel.img (.text + .data, uncompressed) + modules (uncompressed) - + (modules + kernel.img (.text + .data)) (compressed) - + decompressor is limited by the space from 80200000 forward -@item mipsel-loongson (Flash), mips(el)-qemu_mips (Flash): kernel.img (.text + .data) + modules is limited by the space from 80200000 forward - core.img (final) is limited by flash size (512K on yeeloong and fulooong) -@item mips-arc: if uncompressed: - kernel.img (.text + .data) is limited by the space from 8bd00000 forward - modules + dummy decompressor is limited by the space from 8bd00000 backward - if compressed: - kernel.img (.text + .data, uncompressed) is limited by the space from 8bd00000 forward - modules (uncompressed) + (modules + kernel.img (.text + .data)) (compressed, aligned to 1M) - + 1M (decompressor + scratch space) is limited by the space from 8bd00000 backward -@item powerpc-ieee1275: kernel.img (.text + .data + .bss) + modules is limited by space available at 0x200000 -@end itemize - @node Filesystem @chapter Filesystem syntax and semantics @@ -2974,8 +755,8 @@ GRUB uses a special syntax for specifying disk drives which can be accessed by BIOS. Because of BIOS limitations, GRUB cannot distinguish between IDE, ESDI, SCSI, or others. You must know yourself which BIOS device is equivalent to which OS device. Normally, that will be clear if -you see the files in a device or use the command @command{search} -(@pxref{search}). +you see the files in a device or use the command @command{find} +(@pxref{find}). @menu * Device syntax:: How to specify devices @@ -2990,87 +771,42 @@ you see the files in a device or use the command @command{search} The device syntax is like this: @example -@code{(@var{device}[,@var{partmap-name1}@var{part-num1}[,@var{partmap-name2}@var{part-num2}[,...]]])} +@code{(@var{device}[,@var{part-num}][,@var{bsd-subpart-letter}])} @end example -@samp{[]} means the parameter is optional. @var{device} depends on the disk -driver in use. BIOS and EFI disks use either @samp{fd} or @samp{hd} followed -by a digit, like @samp{fd0}, or @samp{cd}. -AHCI, PATA (ata), crypto, USB use the name of driver followed by a number. -Memdisk and host are limited to one disk and so it's referred just by driver -name. -RAID (md), ofdisk (ieee1275 and nand), LVM (lvm), LDM, virtio (vdsk) -and arcdisk (arc) use intrinsic name of disk prefixed by driver name. -Additionally just ``nand'' refers to the disk aliased as ``nand''. -Conflicts are solved by suffixing a number if necessary. -Commas need to be escaped. -Loopback uses whatever name specified to @command{loopback} command. -Hostdisk uses names specified in device.map as long as it's of the form -[fhc]d[0-9]* or hostdisk/. -For crypto and RAID (md) additionally you can use the syntax -uuid/. For LVM additionally you can use the syntax -lvmid//. +@samp{[]} means the parameter is optional. @var{device} should be +either @samp{fd} or @samp{hd} followed by a digit, like @samp{fd0}. +But you can also set @var{device} to a hexadecimal or a decimal number +which is a BIOS drive number, so the following are equivalent: @example -(fd0) (hd0) -(cd) -(ahci0) -(ata0) -(crypto0) -(usb0) -(cryptouuid/123456789abcdef0123456789abcdef0) -(mduuid/123456789abcdef0123456789abcdef0) -(lvm/system-root) -(lvmid/F1ikgD-2RES-306G-il9M-7iwa-4NKW-EbV1NV/eLGuCQ-L4Ka-XUgR-sjtJ-ffch-bajr-fCNfz5) -(md/myraid) -(md/0) -(ieee1275/disk2) -(ieee1275//pci@@1f\,0/ide@@d/disk@@2) -(nand) -(memdisk) -(host) -(myloop) -(hostdisk//dev/sda) +(0x80) +(128) @end example @var{part-num} represents the partition number of @var{device}, starting -from one. @var{partname} is optional but is recommended since disk may have -several top-level partmaps. Specifying third and later component you can access -to subpartitions. +from one for primary partitions and from five for extended partitions, +and @var{bsd-subpart-letter} represents the BSD disklabel subpartition, +such as @samp{a} or @samp{e}. + +A shortcut for specifying BSD subpartitions is +@code{(@var{device},@var{bsd-subpart-letter})}, in this case, GRUB +searches for the first PC partition containing a BSD disklabel, then +finds the subpartition @var{bsd-subpart-letter}. Here is an example: + +@example +(hd0,a) +@end example The syntax @samp{(hd0)} represents using the entire disk (or the MBR when installing GRUB), while the syntax @samp{(hd0,1)} represents using the first partition of the disk (or the boot sector of the partition when installing GRUB). -@example -(hd0,msdos1) -(hd0,msdos1,msdos5) -(hd0,msdos1,bsd3) -(hd0,netbsd1) -(hd0,gpt1) -(hd0,1,3) -@end example - -If you enabled the network support, the special drives -@code{(@var{protocol}[,@var{server}])} are also available. Supported protocols -are @samp{http} and @samp{tftp}. If @var{server} is omitted, value of -environment variable @samp{net_default_server} is used. -Before using the network drive, you must initialize the network. -@xref{Network}, for more information. - -When using @samp{http} or @samp{tftp}, ports other than @samp{80} can be -specified using a colon (@samp{:}) after the address. To avoid parsing -conflicts, when using IPv6 addresses with custom ports, the addresses -must be enclosed with square brackets (@samp{[]}), as is standard -practice. - -@example -(http,grub.example.com:31337) -(http,192.0.2.1:339) -(http,[2001:db8::1]:11235) -@end example +If you enabled the network support, the special drive, @samp{(nd)}, is +also available. Before using the network drive, you must initialize the +network. @xref{Network}, for more information. If you boot GRUB from a CD-ROM, @samp{(cd)} is available. @xref{Making a GRUB bootable CD-ROM}, for details. @@ -3088,15 +824,8 @@ example is @samp{(hd0,1)/boot/grub/grub.cfg}. This means the file @file{/boot/grub/grub.cfg} in the first partition of the first hard disk. If you omit the device name in an absolute file name, GRUB uses GRUB's @dfn{root device} implicitly. So if you set the root device to, -say, @samp{(hd1,1)} by the command @samp{set root=(hd1,1)} (@pxref{set}), -then @code{/boot/kernel} is the same as @code{(hd1,1)/boot/kernel}. - -On ZFS filesystem the first path component must be -@var{volume}@samp{@@}[@var{snapshot}]. -So @samp{/rootvol@@snap-129/boot/grub/grub.cfg} refers to file -@samp{/boot/grub/grub.cfg} in snapshot of volume @samp{rootvol} with name -@samp{snap-129}. Trailing @samp{@@} after volume name is mandatory even if -snapshot name is omitted. +say, @samp{(hd1,1)} by the command @command{root} (@pxref{root}), then +@code{/boot/kernel} is the same as @code{(hd1,1)/boot/kernel}. @node Block list syntax @@ -3104,18 +833,16 @@ snapshot name is omitted. A block list is used for specifying a file that doesn't appear in the filesystem, like a chainloader. The syntax is -@code{[@var{offset}]+[@var{length}][,[@var{offset}]+[@var{length}]]@dots{}}. +@code{[@var{offset}]+@var{length}[,[@var{offset}]+@var{length}]@dots{}}. Here is an example: @example -@code{0+100,200+1,300+300,800+} +@code{0+100,200+1,300+300} @end example This represents that GRUB should read blocks 0 through 99, block 200, -blocks 300 through 599, and blocks 800 until the end of the device. -If you omit an offset, then GRUB assumes the offset is zero. If the -length is omitted, then GRUB assumes the block list extends until the -end of the device. +and blocks 300 through 599. If you omit an offset, then GRUB assumes +the offset is zero. Like the file name syntax (@pxref{File name syntax}), if a blocklist does not contain a device name, then GRUB uses GRUB's @dfn{root @@ -3139,7 +866,6 @@ the command-line interface. @menu * Command-line interface:: The flexible command-line interface * Menu interface:: The simple menu interface -* Menu entry editor:: Editing a menu entry @end menu @@ -3150,8 +876,9 @@ The command-line interface provides a prompt and after it an editable text area much like a command-line in Unix or DOS. Each command is immediately executed after it is entered@footnote{However, this behavior will be changed in the future version, in a user-invisible -way.}. The commands (@pxref{Commands}) are a subset of those available -in the configuration file, used with exactly the same syntax. +way.}. The commands (@pxref{Command-line and menu entry commands}) are a +subset of those available in the configuration file, used with exactly +the same syntax. Cursor movement and editing of the text on the line can be done via a subset of the functions available in the Bash shell: @@ -3233,9 +960,6 @@ If you protect the menu interface with a password (@pxref{Security}), all you can do is choose an entry by pressing @key{RET}, or press @key{p} to enter the password. -Pressing @key{Ctrl-l} will refresh the menu, which can be useful when -connecting via serial after the menu has been drawn. - @node Menu entry editor @section Editing a menu entry @@ -3247,2735 +971,23 @@ of entry names. If an @key{ESC} is pressed in the editor, it aborts all the changes made to the configuration entry and returns to the main menu interface. -Each line in the menu entry can be edited freely, and you can add new lines -by pressing @key{RET} at the end of a line. To boot the edited entry, press -@key{Ctrl-x}. +When a particular line is selected, the editor places the user in a +special version of the GRUB command-line to edit that line. When the +user hits @key{RET}, GRUB replaces the line in question in the boot +entry with the changes (unless it was aborted via @key{ESC}, +in which case the changes are thrown away). -Although GRUB unfortunately does not support @dfn{undo}, you can do almost -the same thing by just returning to the main menu using @key{ESC}. +If you want to add a new line to the menu entry, press @key{o} if adding +a line after the current line or press @key{O} if before the current +line. +To delete a line, hit the key @key{d}. Although GRUB unfortunately +does not support @dfn{undo}, you can do almost the same thing by just +returning to the main menu. -@node Environment -@chapter GRUB environment variables - -GRUB supports environment variables which are rather like those offered by -all Unix-like systems. Environment variables have a name, which is unique -and is usually a short identifier, and a value, which is an arbitrary string -of characters. They may be set (@pxref{set}), unset (@pxref{unset}), or -looked up (@pxref{Shell-like scripting}) by name. - -A number of environment variables have special meanings to various parts of -GRUB. Others may be used freely in GRUB configuration files. - - -@menu -* Special environment variables:: -* Environment block:: -@end menu - - -@node Special environment variables -@section Special environment variables - -These variables have special meaning to GRUB. - -@menu -* biosnum:: -* check_signatures:: -* chosen:: -* cmdpath:: -* color_highlight:: -* color_normal:: -* config_directory:: -* config_file:: -* cryptodisk_passphrase_tries:: -* debug:: -* default:: -* fallback:: -* gfxmode:: -* gfxpayload:: -* gfxterm_font:: -* grub_cpu:: -* grub_platform:: -* icondir:: -* lang:: -* locale_dir:: -* lockdown:: -* menu_color_highlight:: -* menu_color_normal:: -* net_@var{}_boot_file:: -* net_@var{}_clientid:: -* net_@var{}_clientuuid:: -* net_@var{}_dhcp_server_name:: -* net_@var{}_domain:: -* net_@var{}_extensionspath:: -* net_@var{}_hostname:: -* net_@var{}_ip:: -* net_@var{}_mac:: -* net_@var{}_next_server:: -* net_@var{}_rootpath:: -* net_default_interface:: -* net_default_ip:: -* net_default_mac:: -* net_default_server:: -* pager:: -* prefix:: -* pxe_default_server:: -* root:: -* shim_lock:: -* superusers:: -* theme:: -* timeout:: -* timeout_style:: -* tpm_fail_fatal:: -@end menu - - -@node biosnum -@subsection biosnum - -When chain-loading another boot loader (@pxref{Chain-loading}), GRUB may -need to know what BIOS drive number corresponds to the root device -(@pxref{root}) so that it can set up registers properly. If the -@var{biosnum} variable is set, it overrides GRUB's own means of guessing -this. - -For an alternative approach which also changes BIOS drive mappings for the -chain-loaded system, @pxref{drivemap}. - - -@node check_signatures -@subsection check_signatures - -This variable controls whether GRUB enforces digital signature -validation on loaded files. @xref{Using digital signatures}. - -@node chosen -@subsection chosen - -When executing a menu entry, GRUB sets the @var{chosen} variable to the -title of the entry being executed. - -If the menu entry is in one or more submenus, then @var{chosen} is set to -the titles of each of the submenus starting from the top level followed by -the title of the menu entry itself, separated by @samp{>}. - - -@node cmdpath -@subsection cmdpath - -The location from which @file{core.img} was loaded as an absolute -directory name (@pxref{File name syntax}). This is set by GRUB at -startup based on information returned by platform firmware. Not every -platform provides this information and some may return only device -without path name. - - -@node color_highlight -@subsection color_highlight - -This variable contains the ``highlight'' foreground and background terminal -colors, separated by a slash (@samp{/}). Setting this variable changes -those colors. For the available color names, @pxref{color_normal}. - -The default is @samp{black/light-gray}. - - -@node color_normal -@subsection color_normal - -This variable contains the ``normal'' foreground and background terminal -colors, separated by a slash (@samp{/}). Setting this variable changes -those colors. Each color must be a name from the following list: - -@itemize @bullet -@item black -@item blue -@item green -@item cyan -@item red -@item magenta -@item brown -@item light-gray -@item dark-gray -@item light-blue -@item light-green -@item light-cyan -@item light-red -@item light-magenta -@item yellow -@item white -@end itemize - -The default is @samp{light-gray/black}. - -The color support support varies from terminal to terminal. - -@samp{morse} has no color support at all. - -@samp{mda_text} color support is limited to highlighting by -black/white reversal. - -@samp{console} on ARC, EMU and IEEE1275, @samp{serial_*} and -@samp{spkmodem} are governed by terminfo and support -only 8 colors if in modes @samp{vt100-color} (default for console on emu), -@samp{arc} (default for console on ARC), @samp{ieee1275} (default -for console on IEEE1275). When in mode @samp{vt100} -then the color support is limited to highlighting by black/white -reversal. When in mode @samp{dumb} there is no color support. - -When console supports no colors this setting is ignored. -When console supports 8 colors, then the colors from the -second half of the previous list are mapped to the -matching colors of first half. - -@samp{console} on EFI and BIOS and @samp{vga_text} support all 16 colors. - -@samp{gfxterm} supports all 16 colors and would be theoretically extendable -to support whole rgb24 palette but currently there is no compelling reason -to go beyond the current 16 colors. - - -@node config_directory -@subsection config_directory - -This variable is automatically set by GRUB to the directory part of -current configuration file name (@pxref{config_file}). - - -@node config_file -@subsection config_file - -This variable is automatically set by GRUB to the name of configuration file that is being -processed by commands @command{configfile} (@pxref{configfile}) or @command{normal} -(@pxref{normal}). It is restored to the previous value when command completes. - - -@node cryptodisk_passphrase_tries -@subsection cryptodisk_passphrase_tries - -When prompting the user for a cryptodisk passphrase, allow this many attempts -before giving up. Defaults to @samp{3} if unset or set to an invalid value. -(The user can give up early by entering an empty passphrase.) - - -@node debug -@subsection debug - -This variable may be set to enable debugging output from various components -of GRUB. The value is an ordered list of debug facility names separated by -whitespace or @samp{,}. If the special facility named @samp{all} is present -then debugging output of all facility names is enabled at the start of -processing the value of this variable. A facility's debug output can then be -disabled by prefixing its name with a @samp{-}. The last occurence facility -name with or without a leading @samp{-} takes precendent over any previous -occurence. This allows the easy enabling or disabling of facilities by -appending a @samp{,} and then the facility name with or without the leading -@samp{-}, which will preserve the state of the rest of the facilities. -The facility names are the first argument to grub_dprintf. Consult the -source for more details. - - -@node default -@subsection default - -If this variable is set, it identifies a menu entry that should be -selected by default, possibly after a timeout (@pxref{timeout}). The -entry may be identified by number (starting from 0 at each level of -the hierarchy), by title, or by id. - -For example, if you have: - -@verbatim -menuentry 'Example GNU/Linux distribution' --class gnu-linux --id example-gnu-linux { - ... -} -@end verbatim - -then you can make this the default using: - -@example -default=example-gnu-linux -@end example - -If the entry is in a submenu, then it must be identified using the -number, title, or id of each of the submenus starting from the top -level, followed by the number, title, or id of the menu entry itself, -with each element separated by @samp{>}. For example, take the -following menu structure: - -@example -GNU/Hurd --id gnu-hurd - Standard Boot --id=gnu-hurd-std - Rescue shell --id=gnu-hurd-rescue -Other platforms --id=other - Minix --id=minix - Version 3.4.0 --id=minix-3.4.0 - Version 3.3.0 --id=minix-3.3.0 - GRUB Invaders --id=grub-invaders -@end example - -The more recent release of Minix would then be identified as -@samp{Other platforms>Minix>Version 3.4.0}, or as @samp{1>0>0}, or as -@samp{other>minix>minix-3.4.0}. - -This variable is often set by @samp{GRUB_DEFAULT} (@pxref{Simple -configuration}), @command{grub-set-default}, or @command{grub-reboot}. - - -@node fallback -@subsection fallback - -If this variable is set, it identifies a menu entry that should be selected -if the default menu entry fails to boot. Entries are identified in the same -way as for @samp{default} (@pxref{default}). - - -@node gfxmode -@subsection gfxmode - -If this variable is set, it sets the resolution used on the @samp{gfxterm} -graphical terminal. Note that you can only use modes which your graphics -card supports via VESA BIOS Extensions (VBE), so for example native LCD -panel resolutions may not be available. The default is @samp{auto}, which -selects a platform-specific default that should look reasonable. Supported -modes can be listed by @samp{videoinfo} command in GRUB. - -The resolution may be specified as a sequence of one or more modes, -separated by commas (@samp{,}) or semicolons (@samp{;}); each will be tried -in turn until one is found. Each mode should be either @samp{auto}, -@samp{@var{width}x@var{height}}, or -@samp{@var{width}x@var{height}x@var{depth}}. - - -@node gfxpayload -@subsection gfxpayload - -If this variable is set, it controls the video mode in which the Linux -kernel starts up, replacing the @samp{vga=} boot option (@pxref{linux}). It -may be set to @samp{text} to force the Linux kernel to boot in normal text -mode, @samp{keep} to preserve the graphics mode set using @samp{gfxmode}, or -any of the permitted values for @samp{gfxmode} to set a particular graphics -mode (@pxref{gfxmode}). - -Depending on your kernel, your distribution, your graphics card, and the -phase of the moon, note that using this option may cause GNU/Linux to suffer -from various display problems, particularly during the early part of the -boot sequence. If you have problems, set this variable to @samp{text} and -GRUB will tell Linux to boot in normal text mode. - -The default is platform-specific. On platforms with a native text mode -(such as PC BIOS platforms), the default is @samp{text}. Otherwise the -default may be @samp{auto} or a specific video mode. - -This variable is often set by @samp{GRUB_GFXPAYLOAD_LINUX} (@pxref{Simple -configuration}). - - -@node gfxterm_font -@subsection gfxterm_font - -If this variable is set, it names a font to use for text on the -@samp{gfxterm} graphical terminal. Otherwise, @samp{gfxterm} may use any -available font. - - -@node grub_cpu -@subsection grub_cpu - -In normal mode (@pxref{normal}), GRUB sets the @samp{grub_cpu} variable to -the CPU type for which GRUB was built (e.g. @samp{i386} or @samp{powerpc}). - - -@node grub_platform -@subsection grub_platform - -In normal mode (@pxref{normal}), GRUB sets the @samp{grub_platform} variable -to the platform for which GRUB was built (e.g. @samp{pc} or @samp{efi}). - - -@node icondir -@subsection icondir - -If this variable is set, it names a directory in which the GRUB graphical -menu should look for icons after looking in the theme's @samp{icons} -directory. @xref{Theme file format}. - - -@node lang -@subsection lang - -If this variable is set, it names the language code that the -@command{gettext} command (@pxref{gettext}) uses to translate strings. For -example, French would be named as @samp{fr}, and Simplified Chinese as -@samp{zh_CN}. - -@command{grub-mkconfig} (@pxref{Simple configuration}) will try to set a -reasonable default for this variable based on the system locale. - - -@node locale_dir -@subsection locale_dir - -If this variable is set, it names the directory where translation files may -be found (@pxref{gettext}), usually @file{/boot/grub/locale}. Otherwise, -internationalization is disabled. - -@command{grub-mkconfig} (@pxref{Simple configuration}) will set a reasonable -default for this variable if internationalization is needed and any -translation files are available. - - -@node lockdown -@subsection lockdown - -If this variable is set to @samp{y}, it means that GRUB has entered -@pxref{Lockdown} mode. - - -@node menu_color_highlight -@subsection menu_color_highlight - -This variable contains the foreground and background colors to be used for -the highlighted menu entry, separated by a slash (@samp{/}). Setting this -variable changes those colors. For the available color names, -@pxref{color_normal}. - -The default is the value of @samp{color_highlight} -(@pxref{color_highlight}). - - -@node menu_color_normal -@subsection menu_color_normal - -This variable contains the foreground and background colors to be used for -non-highlighted menu entries, separated by a slash (@samp{/}). Setting this -variable changes those colors. For the available color names, -@pxref{color_normal}. - -The default is the value of @samp{color_normal} (@pxref{color_normal}). - - -@node net_@var{}_boot_file -@subsection net_@var{}_boot_file - -@xref{Network}. - - -@node net_@var{}_clientid -@subsection net_@var{}_clientid - -@xref{Network}. - - -@node net_@var{}_clientuuid -@subsection net_@var{}_clientuuid - -@xref{Network}. - - -@node net_@var{}_dhcp_server_name -@subsection net_@var{}_dhcp_server_name - -@xref{Network}. - - -@node net_@var{}_domain -@subsection net_@var{}_domain - -@xref{Network}. - - -@node net_@var{}_extensionspath -@subsection net_@var{}_extensionspath - -@xref{Network}. - - -@node net_@var{}_hostname -@subsection net_@var{}_hostname - -@xref{Network}. - - -@node net_@var{}_ip -@subsection net_@var{}_ip - -@xref{Network}. - - -@node net_@var{}_mac -@subsection net_@var{}_mac - -@xref{Network}. - - -@node net_@var{}_next_server -@subsection net_@var{}_next_server - -@xref{Network}. - - -@node net_@var{}_rootpath -@subsection net_@var{}_rootpath - -@xref{Network}. - - -@node net_default_interface -@subsection net_default_interface - -@xref{Network}. - - -@node net_default_ip -@subsection net_default_ip - -@xref{Network}. - - -@node net_default_mac -@subsection net_default_mac - -@xref{Network}. - - -@node net_default_server -@subsection net_default_server - -@xref{Network}. - - -@node pager -@subsection pager - -If set to @samp{1}, pause output after each screenful and wait for keyboard -input. The default is not to pause output. - - -@node prefix -@subsection prefix - -The location of the @samp{/boot/grub} directory as an absolute file name -(@pxref{File name syntax}). This is normally set by GRUB at startup based -on information provided by @command{grub-install}. GRUB modules are -dynamically loaded from this directory, so it must be set correctly in order -for many parts of GRUB to work. - - -@node pxe_default_server -@subsection pxe_default_server - -@xref{Network}. - - -@node root -@subsection root - -The root device name (@pxref{Device syntax}). Any file names that do not -specify an explicit device name are read from this device. The default is -normally set by GRUB at startup based on the value of @samp{prefix} -(@pxref{prefix}). - -For example, if GRUB was installed to the first partition of the first hard -disk, then @samp{prefix} might be set to @samp{(hd0,msdos1)/boot/grub} and -@samp{root} to @samp{hd0,msdos1}. - - -@node shim_lock -@subsection shim_lock - -If this variable is set to @samp{y}, it means that the shim_lock verifier -is registered (see @pxref{UEFI secure boot and shim}). - - -@node superusers -@subsection superusers - -This variable may be set to a list of superuser names to enable -authentication support. @xref{Security}. - - -@node theme -@subsection theme - -This variable may be set to a directory containing a GRUB graphical menu -theme. @xref{Theme file format}. - -This variable is often set by @samp{GRUB_THEME} (@pxref{Simple -configuration}). - - -@node timeout -@subsection timeout - -If this variable is set, it specifies the time in seconds to wait for -keyboard input before booting the default menu entry. A timeout of @samp{0} -means to boot the default entry immediately without displaying the menu; a -timeout of @samp{-1} (or unset) means to wait indefinitely. - -If @samp{timeout_style} (@pxref{timeout_style}) is set to @samp{countdown} -or @samp{hidden}, the timeout is instead counted before the menu is -displayed. - -This variable is often set by @samp{GRUB_TIMEOUT} (@pxref{Simple -configuration}). - - -@node timeout_style -@subsection timeout_style - -This variable may be set to @samp{menu}, @samp{countdown}, or @samp{hidden} -to control the way in which the timeout (@pxref{timeout}) interacts with -displaying the menu. See the documentation of @samp{GRUB_TIMEOUT_STYLE} -(@pxref{Simple configuration}) for details. - - -@node tpm_fail_fatal -@subsection tpm_fail_fatal - -If this variable is set and true (i.e., not set to ``0'', ``false'', -``disable'', or ``no''), TPM measurements that fail will be treated as -fatal. Otherwise, they will merely be debug-logged and boot will -continue. - -Call to EFI firmware, like hash_log_extend_event(), can return an unknown -error, i.e. due to bug present in firmware. When this variable is set and -true (same values as with TPM measurements) this situation will be considered -to be fatal and error-logged as ``unknown TPM error''. If not set, booting -the OS will be enabled. - -@node Environment block -@section The GRUB environment block - -It is often useful to be able to remember a small amount of information from -one boot to the next. For example, you might want to set the default menu -entry based on what was selected the last time. GRUB deliberately does not -implement support for writing files in order to minimise the possibility of -the boot loader being responsible for file system corruption, so a GRUB -configuration file cannot just create a file in the ordinary way. However, -GRUB provides an ``environment block'' which can be used to save a small -amount of state. - -The environment block is a preallocated 1024-byte file, which normally lives -in @file{/boot/grub/grubenv} (although you should not assume this). At boot -time, the @command{load_env} command (@pxref{load_env}) loads environment -variables from it, and the @command{save_env} (@pxref{save_env}) command -saves environment variables to it. From a running system, the -@command{grub-editenv} utility can be used to edit the environment block. - -For safety reasons, this storage is only available when installed on a plain -disk (no LVM or RAID), using a non-checksumming filesystem (no ZFS), and -using BIOS or EFI functions (no ATA, USB or IEEE1275). - -@command{grub-mkconfig} uses this facility to implement -@samp{GRUB_SAVEDEFAULT} (@pxref{Simple configuration}). - -@node Modules -@chapter Modules - -In this chapter, we list all modules that are available in GRUB. - -Modules can be loaded via the @command{insmod} (@pxref{insmod}) command. - -@menu -* acpi_module:: -* adler32_module:: -* affs_module:: -* afs_module:: -* afsplitter_module:: -* ahci_module:: -* all_video_module:: -* aout_module:: -* appleldr_module:: -* archelp_module:: -* at_keyboard_module:: -* ata_module:: -* backtrace_module:: -* bfs_module:: -* biosdisk_module:: -* bitmap_module:: -* bitmap_scale_module:: -* bli_module:: -* blocklist_module:: -* boot_module:: -* boottime_module:: -* bsd_module:: -* bswap_test_module:: -* btrfs_module:: -* bufio_module:: -* cacheinfo_module:: -* cat_module:: -* cbfs_module:: -* cbls_module:: -* cbmemc_module:: -* cbtable_module:: -* cbtime_module:: -* chain_module:: -* cmdline_cat_test_module:: -* cmosdump_module:: -* cmostest_module:: -* cmp_module:: -* cmp_test_module:: -* configfile_module:: -* cpio_module:: -* cpio_be_module:: -* cpuid_module:: -* crc64_module:: -* crypto_module:: -* cryptodisk_module:: -* cs5536_module:: -* ctz_test_module:: -* date_module:: -* datehook_module:: -* datetime_module:: -* disk_module:: -* diskfilter_module:: -* div_module:: -* div_test_module:: -* dm_nv_module:: -* drivemap_module:: -* echo_module:: -* efi_gop_module:: -* efi_uga_module:: -* efiemu_module:: -* efifwsetup_module:: -* efinet_module:: -* efitextmode_module:: -* ehci_module:: -* elf_module:: -* emunet_module:: -* emupci_module:: -* erofs_module:: -* escc_module:: -* eval_module:: -* exfat_module:: -* exfctest_module:: -* ext2_module:: -* extcmd_module:: -* f2fs_module:: -* fat_module:: -* fdt_module:: -* file_module:: -* fixvideo_module:: -* font_module:: -* freedos_module:: -* fshelp_module:: -* functional_test_module:: -* gcry_arcfour_module:: -* gcry_blowfish_module:: -* gcry_camellia_module:: -* gcry_cast5_module:: -* gcry_crc_module:: -* gcry_des_module:: -* gcry_dsa_module:: -* gcry_idea_module:: -* gcry_md4_module:: -* gcry_md5_module:: -* gcry_rfc2268_module:: -* gcry_rijndael_module:: -* gcry_rmd160_module:: -* gcry_rsa_module:: -* gcry_seed_module:: -* gcry_serpent_module:: -* gcry_sha1_module:: -* gcry_sha256_module:: -* gcry_sha512_module:: -* gcry_tiger_module:: -* gcry_twofish_module:: -* gcry_whirlpool_module:: -* gdb_module:: -* geli_module:: -* gettext_module:: -* gfxmenu_module:: -* gfxterm_module:: -* gfxterm_background_module:: -* gfxterm_menu_module:: -* gptsync_module:: -* gzio_module:: -* halt_module:: -* hashsum_module:: -* hdparm_module:: -* hello_module:: -* help_module:: -* hexdump_module:: -* hfs_module:: -* hfsplus_module:: -* hfspluscomp_module:: -* http_module:: -* ieee1275_fb_module:: -* iorw_module:: -* iso9660_module:: -* jfs_module:: -* jpeg_module:: -* json_module:: -* keylayouts_module:: -* keystatus_module:: -* ldm_module:: -* legacy_password_test_module:: -* legacycfg_module:: -* linux_module:: -* linux16_module:: -* loadbios_module:: -* loadenv_module:: -* loopback_module:: -* ls_module:: -* lsacpi_module:: -* lsapm_module:: -* lsdev_module:: -* lsefi_module:: -* lsefimmap_module:: -* lsefisystab_module:: -* lsmmap_module:: -* lspci_module:: -* lssal_module:: -* lsspd_module:: -* lsxen_module:: -* luks_module:: -* luks2_module:: -* lvm_module:: -* lzopio_module:: -* macbless_module:: -* macho_module:: -* mda_text_module:: -* mdraid09_module:: -* mdraid09_be_module:: -* mdraid1x_module:: -* memdisk_module:: -* memrw_module:: -* memtools_module:: -* minicmd_module:: -* minix_module:: -* minix2_module:: -* minix2_be_module:: -* minix3_module:: -* minix3_be_module:: -* minix_be_module:: -* mmap_module:: -* morse_module:: -* mpi_module:: -* msdospart_module:: -* mul_test_module:: -* multiboot_module:: -* multiboot2_module:: -* nand_module:: -* nativedisk_module:: -* net_module:: -* newc_module:: -* nilfs2_module:: -* normal_module:: -* ntfs_module:: -* ntfscomp_module:: -* ntldr_module:: -* odc_module:: -* offsetio_module:: -* ofnet_module:: -* ohci_module:: -* part_acorn_module:: -* part_amiga_module:: -* part_apple_module:: -* part_bsd_module:: -* part_dfly_module:: -* part_dvh_module:: -* part_gpt_module:: -* part_msdos_module:: -* part_plan_module:: -* part_sun_module:: -* part_sunpc_module:: -* parttool_module:: -* password_module:: -* password_pbkdf2_module:: -* pata_module:: -* pbkdf2_module:: -* pbkdf2_test_module:: -* pci_module:: -* pcidump_module:: -* pgp_module:: -* plainmount_module:: -* plan9_module:: -* play_module:: -* png_module:: -* priority_queue_module:: -* probe_module:: -* procfs_module:: -* progress_module:: -* pxe_module:: -* pxechain_module:: -* raid5rec_module:: -* raid6rec_module:: -* random_module:: -* rdmsr_module:: -* read_module:: -* reboot_module:: -* regexp_module:: -* reiserfs_module:: -* relocator_module:: -* romfs_module:: -* scsi_module:: -* sdl_module:: -* search_module:: -* search_fs_file_module:: -* search_fs_uuid_module:: -* search_label_module:: -* sendkey_module:: -* serial_module:: -* setjmp_module:: -* setjmp_test_module:: -* setpci_module:: -* sfs_module:: -* shift_test_module:: -* signature_test_module:: -* sleep_module:: -* sleep_test_module:: -* smbios_module:: -* spkmodem_module:: -* squash4_module:: -* strtoull_test_module:: -* suspend_module:: -* syslinuxcfg_module:: -* tar_module:: -* terminal_module:: -* terminfo_module:: -* test_module:: -* test_blockarg_module:: -* testload_module:: -* testspeed_module:: -* tftp_module:: -* tga_module:: -* time_module:: -* tpm_module:: -* tr_module:: -* trig_module:: -* true_module:: -* truecrypt_module:: -* ubootnet_module:: -* udf_module:: -* ufs1_module:: -* ufs1_be_module:: -* ufs2_module:: -* uhci_module:: -* usb_module:: -* usb_keyboard_module:: -* usbms_module:: -* usbserial_common_module:: -* usbserial_ftdi_module:: -* usbserial_pl2303_module:: -* usbserial_usbdebug_module:: -* usbtest_module:: -* vbe_module:: -* verifiers_module:: -* vga_module:: -* vga_text_module:: -* video_module:: -* video_bochs_module:: -* video_cirrus_module:: -* video_colors_module:: -* video_fb_module:: -* videoinfo_module:: -* videotest_module:: -* videotest_checksum_module:: -* wrmsr_module:: -* xen_boot_module:: -* xfs_module:: -* xnu_module:: -* xnu_uuid_module:: -* xnu_uuid_test_module:: -* xzio_module:: -* zfs_module:: -* zfscrypt_module:: -* zfsinfo_module:: -* zstd_module:: - -@end menu - -@node acpi_module -@section acpi -This module provides the command @command{acpi} for loading / replacing Advanced -Configuration and Power Interface (ACPI) tables. Please @pxref{acpi} for more -information. - -@node adler32_module -@section adler32 -This module provides the library implementation for the adler32 checksum. -This is used as part of LZO decompression / compression. - -@node affs_module -@section affs -This module provides support for the Amiga Fast FileSystem (AFFS). -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node afs_module -@section afs -This module provides support for the AtheOS File System (AFS). -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node afsplitter_module -@section afsplitter -This module provides library support for the Anti forensic information splitter -(AFS) operation @code{AF_merge}. This is used by LUKS and LUKS2. - -@node ahci_module -@section ahci -This module provides support for the Advanced Host Controller Interface protocol -to access disks supporting this standard. AHCI is often an option for Serial -ATA (SATA) controllers (meant to replace the older IDE protocol). - -@node all_video_module -@section all_video -This is a "dummy module" with no actual function except to load all other video -modules as dependencies (a convenient way to load all video modules). - -@node aout_module -@section aout -This module provides support for loading files packaged in the "a.out" format. -The "a.out" format is considered to be an older format than some alternatives -such as "ELF", for example support for the "a.out" format was removed from the -Linux kernel in 5.18. - -@node appleldr_module -@section appleldr -This module provides support for loading files on a BIOS / EFI based Apple Mac -computer (Intel based Macs). - -@node archelp_module -@section archelp -This module provides Archive Helper functions for archive based file systems -such as TAR and CPIO archives. - -@node at_keyboard_module -@section at_keyboard -This module provides support for the AT keyboard input for the GRUB terminal. - -@node ata_module -@section ata -This modules provides support for direct ATA and ATAPI access to compatible -disks. - -@node backtrace_module -@section backtrace -This module provides the command @command{backtrace} for printing a backtrace -to the terminal for the current call stack. - -@node bfs_module -@section bfs -This module provides support for the BeOS "Be File System" (BFS). -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node biosdisk_module -@section biosdisk -This module provides support for booting from a bootable removable disk such -as a CD-ROM, BD-ROM, etc. - -@node bitmap_module -@section bitmap -This module provides support for reading and interacting with bitmap image -files. - -@node bitmap_scale_module -@section bitmap_scale -This module provides support for scaling bitmap image files. - -@node bli_module -@section bli -This module provides basic support for the Boot Loader Interface. The Boot -Loader Interface specifies a set of EFI variables that are used to communicate -boot-time information between the bootloader and the operating system. - -The following variables are placed under the vendor UUID -@code{4a67b082-0a4c-41cf-b6c7-440b29bb8c4f} when the module is loaded: - -The GPT partition UUID of the EFI System Partition used during boot is -published via the @code{LoaderDevicePartUUID} variable. The Boot Loader -Interface specification requires GPT formatted drives. The bli module -ignores drives/partitions in any other format. If GRUB is loaded from -a non-GPT partition, e.g. from an MSDOS formatted drive or network, -this variable will not be set. - -A string identifying GRUB as the active bootloader including the version -number is stored in @code{LoaderInfo}. - -This module is only available on UEFI platforms. - -@node blocklist_module -@section blocklist -This module provides support for the command @command{blocklist} to list -blocks for a given file. Please @pxref{blocklist} for more information. - -@node boot_module -@section boot -This module provides support for the command @command{boot} to boot an -operating system. Please @pxref{boot} for more information. - -@node boottime_module -@section boottime -This module provides support for the command @command{boottime} to display -time taken to perform various GRUB operations. This module is only available -when GRUB is built with the conditional compile option @code{BOOT_TIME_STATS}. - -@node bsd_module -@section bsd -This module provides support for loading BSD operating system images via -commands such as: @command{kfreebsd_loadenv}, @command{kfreebsd_module_elf}, -@command{kfreebsd_module}, @command{kfreebsd}, @command{knetbsd_module_elf}, -@command{knetbsd_module}, @command{knetbsd}, @command{kopenbsd}, and -@command{kopenbsd_ramdisk}. Please @pxref{Loader commands} for more info. - -@node bswap_test_module -@section bswap_test -This module is intended for performing a functional test of the byte swapping -functionality of GRUB. - -@node btrfs_module -@section btrfs -This module provides support for the B-Tree File System (BTRFS). - -@node bufio_module -@section bufio -This module is a library module for support buffered I/O of files to support -file reads performed in other modules. - -@node cacheinfo_module -@section cacheinfo -This module provides support for the command @command{cacheinfo} which provides -statistics on disk cache accesses. This module is only built if -@code{DISK_CACHE_STATS} is enabled. - -@node cat_module -@section cat -This module provides support for the command @command{cat} which outputs the -content of a file to the terminal. Please @pxref{cat} for more info. - -@node cbfs_module -@section cbfs -This module provides support for the Coreboot File System (CBFS) which is an -archive based file system. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node cbls_module -@section cbls -This module provides support for the command @command{lscoreboot} to list the -Coreboot tables. - -@node cbmemc_module -@section cbmemc -This module provides support for the command @command{cbmemc} to show the -content of the Coreboot Memory console. - -@node cbtable_module -@section cbtable -This module provides support for accessing the Coreboot tables. - -@node cbtime_module -@section cbtime -This module provides support for the command @command{coreboot_boottime} to show -the Coreboot boot time statistics. - -@node chain_module -@section chain -This module provides support for the command @command{chainloader} to boot -another bootloader. Please @pxref{chainloader} for more information. - -@node cmdline_cat_test_module -@section cmdline_cat_test -This module is intended for performing a functional test of the @command{cat} -command of GRUB. - -@node cmosdump_module -@section cmosdump -This module provides support for the command @command{cmosdump} to show a raw -dump of the CMOS contents. Please @pxref{cmosdump} for more information. - -@node cmostest_module -@section cmostest -This module provides support for the commands @command{cmostest}, -@command{cmosclean}, and @command{cmosset} to interact with a CMOS. -@xref{cmostest} / @pxref{cmosclean} for more information. - -@node cmp_module -@section cmp -This module provides support for the command @command{cmp} to compare the -content of two files. @xref{cmp} for more information. - -@node cmp_test_module -@section cmp_test -This module is intended for performing a functional test of relational -operations in GRUB. Note that this module is *not* associated with the -@command{cmp} command and does not test the @command{cmp} command. - -@node configfile_module -@section configfile -This module provides support for the commands: @command{configfile}, -@command{source}, @command{extract_entries_source}, -@command{extract_entries_configfile}, @command{.} (dot command). -@xref{configfile} / @pxref{source}. - -@node cpio_module -@section cpio -This module provides support for the CPIO archive file format. This module is -for the "bin" version of CPIO (default of GNU CPIO) supporting around 2GB. - -@node cpio_be_module -@section cpio_be -This module provides support for the CPIO archive file format in big-endian -format. This module is for the "bin" version of CPIO (default of GNU CPIO) -supporting around 2GB. - -@node cpuid_module -@section cpuid -This module provides support for the command @command{cpuid} to test for -various CPU features. @xref{cpuid} for more information. - -@node crc64_module -@section crc64 -This module provides support for the CRC64 operation. - -@node crypto_module -@section crypto -This module provides library support for various base cryptography operations -in GRUB. - -@node cryptodisk_module -@section cryptodisk -This module provides support for the command @command{cryptomount} to interact -with encrypted file systems. @xref{cryptomount} for more information. - -@node cs5536_module -@section cs5536 -This module provides support for the AMD Geode CS5536 companion device. - -@node ctz_test_module -@section ctz_test -This module is intended for performing a functional test of the ctz functions -in GRUB used to Count Trailing Zeros. - -@node date_module -@section date -This module provides support for the command @command{date} to get the date/time -or set the date/time. @xref{date} for more information. - -@node datehook_module -@section datehook -This module provides support for populating / providing the environment -variables @code{YEAR}, @code{MONTH}, @code{DAY}, @code{HOUR}, @code{MINUTE}, -@code{SECOND}, @code{WEEKDAY}. - -@node datetime_module -@section datetime -This module provides library support for getting and setting the date / time -from / to a hardware clock device. - -@node disk_module -@section disk -This module provides library support for writing to a storage disk. - -@node diskfilter_module -@section diskfilter -This module provides library support for reading a disk RAID array. -It also provides support for the command @command{cryptocheck}. -@xref{cryptocheck} for more information. - -@node div_module -@section div -This module provides library support for some operations such as divmod. - -@node div_test_module -@section div_test -This module is intended for performing a functional test of the divmod function -in GRUB. - -@node dm_nv_module -@section dm_nv -This module provides support for handling some Nvidia "fakeraid" disk devices. - -@node drivemap_module -@section drivemap -This module provides support for the @command{drivemap} to manage BIOS drive -mappings. @xref{drivemap} for more information. - -@node echo_module -@section echo -This module provides support for the @command{echo} to display a line of text. -@xref{echo} for more information. - -@node efi_gop_module -@section efi_gop -This module provides support for the UEFI video output protocol "Graphics -Output Protocol" (GOP). - -@node efi_uga_module -@section efi_uga -This module provides support for the EFI video protocol "Universal Graphic -Adapter" (UGA). - -@node efiemu_module -@section efiemu -This module provides support for the commands @command{efiemu_loadcore}, -@command{efiemu_prepare}, and @command{efiemu_unload}. This provides an EFI -emulation. - -@node efifwsetup_module -@section efifwsetup -This modules provides support for the command @command{fwsetup} to reboot into -the firmware setup menu. @xref{fwsetup} for more information. - -@node efinet_module -@section efinet -This module provides support for UEFI Network Booting for loading images and -data from the network. - -@node efitextmode_module -@section efitextmode -This module provides support for command @command{efitextmode} to get and set -output mode resolution. @xref{efitextmode} for more information. - -@node ehci_module -@section ehci -This module provides support for the USB Enhanced Host Controller Interface -(EHCI) specification (USB 2.0). - -@node elf_module -@section elf -This module provides support for loading Executable and Linkable Format (ELF) -files. - -@node emunet_module -@section emunet -This module provides support for networking in GRUB on the emu platform. - -@node emupci_module -@section emupci -This module provides support for accessing the PCI bus in GRUB on the emu -platform. - -@node erofs_module -@section erofs -This module provides support for the Enhanced Read Only File System (EROFS). - -@node escc_module -@section escc -This module provides support for the "mac-io" terminal device on PowerPC. - -@node eval_module -@section eval -This module provides support for command @command{eval} to evaluate the provided -input as a sequence of GRUB commands. @xref{eval} for more information. - -@node exfat_module -@section exfat -This module provides support for the Extensible File Allocation Table (exFAT) -file system in GRUB. - -@node exfctest_module -@section exfctest -This module is intended to provide an Example Functional Test of GRUB functions -to use as a template for developing other GRUB functional tests. - -@node ext2_module -@section ext2 -This module provides support for the Extended File System versions 2, 3, and 4 -(ext2, ext3, and ext4) file systems in GRUB. - -@node extcmd_module -@section extcmd -This module is a support module to provide wrapper functions for registering -other module commands depending on the state of the lockdown variable. - -@node f2fs_module -@section f2fs -This module provides support for the Flash-Friendly File System (F2FS) in GRUB. - -@node fat_module -@section fat -This module provides support for the File Allocation Table 12-bit, 16-bit, and -32-bit (FAT12, FAT16, and FAT32) file systems in GRUB. - -@node fdt_module -@section fdt -This module provides support for the commands @command{fdtdump} and -@command{devicetree} to dump the contents of a device tree blob (.dtb) to the -console and to load a device tree blob (.dtb) from a filesystem, for -later use by a Linux kernel, respectively. @xref{devicetree} and -@pxref{fdtdump} for more information. - -@node file_module -@section file -This module provides support for the command @command{file} to test if the -provided filename is of the specified type. @xref{file} for more information. - -@node fixvideo_module -@section fixvideo -This module provides support for the command @command{fix_video} to fix video -problems in specific PCIe video devices by "patching" specific device register -settings. Currently supports Intel 945GM (PCI ID @code{0x27a28086}) and Intel -965GM (PCI ID @code{0x2a028086}). - -@node font_module -@section font -This module provides support for the commands @command{loadfont} and -@command{lsfonts} to load a given font or list the loaded fonts. @xref{loadfont} -and @pxref{lsfonts} for more information. - -@node freedos_module -@section freedos -This module provides support for command @command{freedos} for loading a FreeDOS -kernel. - -@node fshelp_module -@section fshelp -This module provides support functions (helper functions) for file systems. - -@node functional_test_module -@section functional_test -This module provides support for running the GRUB functional tests using -commands @command{functional_test} and @command{all_functional_test}. - -@node gcry_arcfour_module -@section gcry_arcfour -This module provides support for the arcfour stream cipher also known as RC4. -If security is a concern, RC4 / arcfour cipher is consider broken (multiple -known vulnerabilities make this insecure). -This GRUB module is based on libgcrypt. - -@node gcry_blowfish_module -@section gcry_blowfish -This module provides support for the Blowfish cipher. -This GRUB module is based on libgcrypt. - -@node gcry_camellia_module -@section gcry_camellia -This module provides support for the Camellia cipher. -This GRUB module is based on libgcrypt. - -@node gcry_cast5_module -@section gcry_cast5 -This module provides support for the CAST5 (RFC2144, also known as CAST-128) -cipher. This GRUB module is based on libgcrypt. - -@node gcry_crc_module -@section gcry_crc -This module provides support for the CRC32, CRC32 RFC1510, and CRC24 RFC2440 -cyclic redundancy checks. -This GRUB module is based on libgcrypt. - -@node gcry_des_module -@section gcry_des -This module provides support for the Data Encryption Standard (DES) and -Triple-DES ciphers. -If security is a concern, DES has known vulnerabilities and is not recommended, -and Triple-DES is no longer recommended by NIST. -This GRUB module is based on libgcrypt. - -@node gcry_dsa_module -@section gcry_dsa -This module provides support for the Digital Signature Algorithm (DSA) cipher. -This GRUB module is based on libgcrypt. - -@node gcry_idea_module -@section gcry_idea -This module provides support for the International Data Encryption Algorithm -(IDEA) cipher. -This GRUB module is based on libgcrypt. - -@node gcry_md4_module -@section gcry_md4 -This module provides support for the Message Digest 4 (MD4) message digest. -If security is a concern, MD4 has known vulnerabilities and is not recommended. -This GRUB module is based on libgcrypt. - -@node gcry_md5_module -@section gcry_md5 -This module provides support for the Message Digest 5 (MD5) message digest. -If security is a concern, MD5 has known vulnerabilities and is not recommended. -This GRUB module is based on libgcrypt. - -@node gcry_rfc2268_module -@section gcry_rfc2268 -This module provides support for the RFC2268 (RC2 / Ron's Cipher 2) cipher. -If security is a concern, RC2 has known vulnerabilities and is not recommended. -This GRUB module is based on libgcrypt. - -@node gcry_rijndael_module -@section gcry_rijndael -This module provides support for the Advanced Encryption Standard (AES-128, -AES-192, and AES-256) ciphers. -This GRUB module is based on libgcrypt. - -@node gcry_rmd160_module -@section gcry_rmd160 -This module provides support for the RIPEMD-160 message digest. -This GRUB module is based on libgcrypt. - -@node gcry_rsa_module -@section gcry_rsa -This module provides support for the Rivest–Shamir–Adleman (RSA) cipher. -This GRUB module is based on libgcrypt. - -@node gcry_seed_module -@section gcry_seed -This module provides support for the SEED cipher. -This GRUB module is based on libgcrypt. - -@node gcry_serpent_module -@section gcry_serpent -This module provides support for the Serpent (128, 192, and 256) ciphers. -This GRUB module is based on libgcrypt. - -@node gcry_sha1_module -@section gcry_sha1 -This module provides support for the Secure Hash Algorithm 1 (SHA-1) message -digest. -If security is a concern, SHA-1 has known vulnerabilities and is not -recommended. -This GRUB module is based on libgcrypt. - -@node gcry_sha256_module -@section gcry_sha256 -This module provides support for the Secure Hash Algorithm 2 (224 and 256 bit) -(SHA-224 / SHA-256) message digests. -This GRUB module is based on libgcrypt. - -@node gcry_sha512_module -@section gcry_sha512 -This module provides support for the Secure Hash Algorithm 2 (384 and 512 bit) -(SHA-384 / SHA-512) message digests. -This GRUB module is based on libgcrypt. - -@node gcry_tiger_module -@section gcry_tiger -This module provides support for the Tiger, Tiger 1, and Tiger 2 message -digests. -This GRUB module is based on libgcrypt. - -@node gcry_twofish_module -@section gcry_twofish -This module provides support for the Twofish (128 and 256) ciphers. -This GRUB module is based on libgcrypt. - -@node gcry_whirlpool_module -@section gcry_whirlpool -This module provides support for the Whirlpool message digest. -This GRUB module is based on libgcrypt. - -@node gdb_module -@section gdb -This module provides support for remotely debugging GRUB using the GNU -Debugger (GDB) over serial. This is typically done when troubleshooting GRUB -during development and not required for normal GRUB operation. This module adds -support for commands required by the GDB remote debug function including -@command{gdbstub} to start GDB stub on given serial port, -@command{gdbstub_break} to break into GDB, @command{gdbstub_stop} to stop the -GDB stub. - -@node geli_module -@section geli -This module provides support for the GEOM ELI (GELI) disk encryption / -decryption protocol used by FreeBSD. This module supports the following ciphers -using the associated "gcry" modules: DES, Triple-DES, Blowfish, CAST5, AES, and -Camellia 128. - -@node gettext_module -@section gettext -This module provides support for the @command{gettext} command to support -translating information displayed / output by GRUB. @xref{gettext} for more -information. - -@node gfxmenu_module -@section gfxmenu -This module provides support for displaying a graphical menu / user interface -from GRUB. This includes features such as graphical font support, theme support, -image support, and icon support. - -@node gfxterm_module -@section gfxterm -This module provides support for displaying a terminal and menu interface from -GRUB using graphics mode. - -@node gfxterm_background_module -@section gfxterm_background -This module provides support for setting the gfxterm background color and -background image using commands @command{background_color} and -@command{background_image}. @xref{background_color} and @pxref{background_image} -for more information. - -@node gfxterm_menu_module -@section gfxterm_menu -This module is intended for performing a functional test of the gfxmenu function -in GRUB. - -@node gptsync_module -@section gptsync -This module provides support for the @command{gptsync} command.. @xref{gptsync} -for more information. - -@node gzio_module -@section gzio -This module provides support for decompression (inflate) of files compressed -with the GZ compression algorithm. This supports only the "DEFLATE" method for -GZIP. Unsupported flags (will result in failure to inflate) include: -@code{GRUB_GZ_CONTINUATION}, @code{GRUB_GZ_ENCRYPTED}, -@code{GRUB_GZ_RESERVED}, and @code{GRUB_GZ_EXTRA_FIELD}. - -@node halt_module -@section halt -This module provides support for the @command{halt} command to shutdown / halt -the system. @xref{halt} for more information. - -@node hashsum_module -@section hashsum -This module provide support for the commands @command{hashsum}, -@command{md5sum}, @command{sha1sum}, @command{sha256sum}, @command{sha512sum}, -and @command{crc} to calculate or check hashes of files using various methods. -@xref{hashsum}, @pxref{md5sum} @pxref{sha1sum}, @pxref{sha256sum}, -@pxref{sha512sum}, and @pxref{crc}. - -@node hdparm_module -@section hdparm -This module provides support for the @command{hdparm} command to get or set -various ATA disk parameters. This includes controlling Advanced Power Management -(APM), displaying power mode, freezing ATA security settings until reset, -displaying SMART status, controlling automatic acoustic management, setting -standby timeout, setting the drive to standby mode, setting the drive to sleep -mode, displaying the drive identification and settings, and enable/disable -SMART. - -@node hello_module -@section hello -This provides support for the @command{hello} command to simply output -"Hello World". This is intended for testing GRUB module loading / functionality. - -@node help_module -@section help -This module provides support for the @command{help} command to output help -text. @xref{help} for more information. - -@node hexdump_module -@section hexdump -This module provides support for the @command{hexdump} command to dump the -contents of a file in hexadecimal. @xref{hexdump} for more information. - -@node hfs_module -@section hfs -This module provides support for the Hierarchical File System (HFS) file system -in GRUB. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node hfsplus_module -@section hfsplus -This module provides support for the Hierarchical File System Plus (HFS+) file -system in GRUB. - -@node hfspluscomp_module -@section hfspluscomp -This module provides support for the Hierarchical File System Plus Compressed -(HFS+ Compressed) file system in GRUB. - -@node http_module -@section http -This module provides support for getting data over the HTTP network protocol in -GRUB (using the HTTP GET method). This may be used, for example, to obtain -an operating system over HTTP (network boot). - -@node ieee1275_fb_module -@section ieee1275_fb -This module provides support for the IEEE1275 video driver output for PowerPC -with a IEEE-1275 platform. - -@node iorw_module -@section iorw -This module provides support for commands @command{inb}, @command{inw}, -@command{inl}, @command{outb}, @command{outw}, and @command{outl} to read / -write data to physical I/O ports. The "in" commands accept one -parameter to specify the source port. The "out" commands require either two -or three parameters, with the order: port, value, . - -@node iso9660_module -@section iso9660 -This module provides support for the ISO9660 file system (often associated with -optical disks such as CD-ROMs and DVD-ROMs, with extensions: -System Use Sharing Protocol (SUSP), Rock Ridge (UNIX style permissions and -longer names) - -@node jfs_module -@section jfs -This module provides support for the Journaled File System (JFS) file system. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node jpeg_module -@section jpeg -This module provides support for reading JPEG image files in GRUB, such as -to support displaying a JPEG image as a background image of the gfxmenu. - -@node json_module -@section json -This module provides library support for parsing / processing JavaScript Object -Notation (JSON) formatted data. This is used, for example, to support LUKS2 -disk encryption / decryption as metadata is encoded in JSON. - -@node keylayouts_module -@section keylayouts -This module provides support for the @command{keymap} command. This command -accepts one parameter to specify either the @var{layout_name} or the -@var{filename}. -When specifying the @var{layout_name}, this command will attempt to open the -GRUB keymap file based on the following logic: - -Get the "prefix" from environment variable @var{prefix} - -Open keymap file @var{prefix}/layouts/@var{layout_name}.gkb - -When specifying the @var{filename}, the full path to the ".gkb" file should be -provided. The ".gkb" file can be generated by grub-kbdcomp. - -@node keystatus_module -@section keystatus -This module provides support for the @command{keystatus} command to check key -modifier status. @xref{keystatus} for more information. - -@node ldm_module -@section ldm -This module provides support for the Logical Disk Manager (LDM) disk format. -LDM is used to add support for logical volumes most often with Microsoft -Windows systems. A logical volume can be defined to span more than one physical -disk. - -@node legacy_password_test_module -@section legacy_password_test -This module is intended for performing a functional test of the legacy password -function in GRUB. - -@node legacycfg_module -@section legacycfg -This module provides support for commands @command{legacy_source}, -@command{legacy_configfile}, @command{extract_legacy_entries_source}, -@command{extract_legacy_entries_configfile}, @command{legacy_kernel}, -@command{legacy_initrd}, @command{legacy_initrd_nounzip}, -@command{legacy_password}, and @command{legacy_check_password}. For new uses / -configurations of GRUB other commands / modules offer the modern equivalents. - -@node linux_module -@section linux -This module provides support for the commands @command{linux} and -@command{initrd} to load Linux and an Initial RAM Disk respectively. -@xref{linux} and @pxref{initrd} for more information. - -@node linux16_module -@section linux16 -This module provides support for the commands @command{linux16} and -@command{initrd16} to load Linux in 16-bit mode and an Initial RAM Disk -in 16-bit mode respectively. -@xref{linux16} and @pxref{initrd16} for more information. - -@node loadbios_module -@section loadbios -This module provides support for the commands @command{fakebios} and -@command{loadbios}. These commands may only be useful on platforms with -issues requiring work-arounds. Command @command{fakebios} is used to create -BIOS-like structures for backward compatibility with existing OS. Command -@command{loadbios} is used to load a BIOS dump. - -@node loadenv_module -@section loadenv -This module provides support for commands @command{load_env}, -@command{list_env}, and @command{save_env}. These commands can be used to -load environment variables from a file, list environment variables in a file, -and save environment variables to a file. @xref{load_env}, @pxref{list_env}, and -@pxref{save_env}. - -@node loopback_module -@section loopback -This module provides support for the @command{loopback} command. -@xref{loopback} for more information. - -@node ls_module -@section ls -This module provides support for the @command{ls} command. -@xref{ls} for more information. - -@node lsacpi_module -@section lsacpi -This module provides support for the @command{lsacpi} command. This command -can be used to display Advanced Configuration and Power Interface (ACPI) tables. - -@node lsapm_module -@section lsapm -This module provides support for the @command{lsapm} command. This command -can be used to display Advanced power management (APM) information. - -@node lsdev_module -@section lsdev -This module provides support for the @command{lsdev} command. This command -can be used on MIPS Advanced RISC Computing (ARC) platforms to display devices. - -@node lsefi_module -@section lsefi -This module provides support for the @command{lsefi} command. This command -can be used on EFI platforms to display EFI handles. - -@node lsefimmap_module -@section lsefimmap -This module provides support for the @command{lsefimmap} command. This command -can be used on EFI platforms to display the EFI memory map. - -@node lsefisystab_module -@section lsefisystab -This module provides support for the @command{lsefisystab} command. This -command can be used on EFI platforms to display the EFI system tables. - -@node lsmmap_module -@section lsmmap -This module provides support for the @command{lsmmap} command. This -command can be used to display the memory map provided by firmware. - -@node lspci_module -@section lspci -This module provides support for the @command{lspci} command. This -command can be used to display the PCI / PCIe devices. - -@node lssal_module -@section lssal -This module provides support for the @command{lsefisystab} command. This -command can be used on Itanium (IA-64) EFI platforms to display the EFI -System Abstraction Layer system table. - -@node lsspd_module -@section lsspd -This module provides support for the @command{lsspd} command. This -command can be used on MIPS Loongson platforms to display the DDR RAM Serial -Presence Detect (SPD) EEPROM data. - -@node lsxen_module -@section lsxen -This module provides support for the commands @command{xen_ls} and -@command{xen_cat} on Xen platforms to list Xen storage. - -@node luks_module -@section luks -This module provides support for the Linux Unified Key Setup (LUKS) (version 1) -disk encryption / decryption protocol. - -@node luks2_module -@section luks2 -This module provides support for the Linux Unified Key Setup 2 (LUKS2) -disk encryption / decryption protocol. - -@node lvm_module -@section lvm -This module provides support for reading Logical Volume Management "logical" -disks. For example, a single "logical" disk may be mapped to span more than one -physical disk. This would be used when booting from a LVM formatted disk as may -be setup in Linux. - -@node lzopio_module -@section lzopio -This module provides support for decompressing LZO / LZOP compressed files / -archives. - -@node macbless_module -@section macbless -This module provides support for commands @command{mactelbless} and -@command{macppcbless} for "blessing" a bootloader on Intel / PPC based MACs -using the HFS or HFS+ file system. On HFS / HFS+ - "blessing" makes a file -run as the bootloader. - -@node macho_module -@section macho -This module provides support for Mach Object (Mach-O) object / executable files -in GRUB often used in MacOS. - -@node mda_text_module -@section mda_text -This module provides support for the Monochrome Display Adapter (MDA) terminal -output device. MDA is a predecessor to VGA. - -@node mdraid09_module -@section mdraid09 -This module provides support for handling Linux compatible "version 0.9" -software-based RAID disks in little-endian format. The "version 0.9" format -was largely replaced around the year 2009 with the "version 1.x" format -(@pxref{mdraid1x_module} for more information). - -@node mdraid09_be_module -@section mdraid09_be -This module provides support for handling Linux compatible "version 0.9" -software-based RAID disks in bid-endian format. The "version 0.9" format -was largely replaced around the year 2009 with the "version 1.x" format -(@pxref{mdraid1x_module} for more information). - -@node mdraid1x_module -@section mdraid1x -This module provides support for handling Linux compatible "version 1.x" -software-based RAID disks. This includes the current version used by Linux -at the time of writing. - -@node memdisk_module -@section memdisk -This module provides support for a memdisk device. A memdisk is a memory mapped -emulated disk. - -@node memrw_module -@section memrw -This module provides support for commands @command{read_byte}, -@command{read_word}, @command{read_dword}, @command{write_byte}, -@command{write_word}, and @command{write_dword} to read / -write data to physical memory (addresses). The "read" commands accept one -parameter to specify the source address. The "write" commands require either two -or three parameters, with the order: address, value, . -Note: The commands provided by this module are not allowed when lockdown is -enforced (@pxref{Lockdown}). - -@node memtools_module -@section memtools -This module provides support for GRUB development / debugging commands -@command{lsmem}, @command{lsfreemem}, and @command{stress_big_allocs}. - -@node minicmd_module -@section minicmd -This module provides support for a subset of commands for GRUB rescue mode -including: @command{cat}, @command{help}, @command{dump}, @command{rmmod}, -@command{lsmod}, and @command{exit}. The version of the commands in this module -are similar to their full-fledged counterparts implemented in other GRUB -modules. -Note: The @command{dump} command is not allowed when lockdown is enforced -(@pxref{Lockdown}). - -@node minix_module -@section minix -This module provides support for the Minix filesystem, version 1. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node minix2_module -@section minix2 -This module provides support for the Minix filesystem, version 2. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node minix2_be_module -@section minix2_be -This module provides support for the Minix filesystem, version 2 big-endian. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node minix3_module -@section minix3 -This module provides support for the Minix filesystem, version 3. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node minix3_be_module -@section minix3_be -This module provides support for the Minix filesystem, version 3 big-endian. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node minix_be_module -@section minix_be -This module provides support for the Minix filesystem, version 1 big-endian. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node mmap_module -@section mmap -This module provides support for mapping or unmapping devices or files into -memory as well as commands @command{badram} and @command{cutmem}. -@xref{badram} and @ref{cutmem}. - -@node morse_module -@section morse -This module provides support for outputting terminal output via Morse code -to an audio speaker output. - -@node mpi_module -@section mpi -This module provides support for multi-precision-integers (MPIs) in GRUB. MPIs -are used by the crypto functions as many depend on mathematics of large numbers. -This GRUB module is based on libgcrypt. - -@node msdospart_module -@section msdospart -This module provides support for modifying MSDOS formatted disk partitions -through the separate @command{parttool} command. - -@node mul_test_module -@section mul_test -This module is intended for performing a functional test of the multiplication -operations in GRUB. - -@node multiboot_module -@section multiboot -This module provides support for commands @command{multiboot} and -@command{module} to load a multiboot kernel and load a multiboot module, -respectively. @xref{multiboot} and @ref{module} for more information. This -is for loading data formatted per the GNU Multiboot specification. - -@node multiboot2_module -@section multiboot2 -This module provides support for commands @command{multiboot2} and -@command{module2} to load a multiboot kernel and load a multiboot module, -respectively. This is for loading data formatted per the GNU Multiboot -specification. - -@node nand_module -@section nand -This module provides support for accessing an IEEE-1275 compliant NAND disk -from GRUB. - -@node nativedisk_module -@section nativedisk -This module provides support for the @command{nativedisk} command. -@xref{nativedisk} for more information. - -@node net_module -@section net -This module provides support for networking protocols including ARP, BOOTP, -DNS, Ethernet, ICMPv6, ICMP, IP, TCP, and UDP. Support is included for both -IPv4 and IPv6. -This includes the following commands: -@itemize @bullet -@item -@command{net_bootp} - @pxref{net_bootp} - -@item -@command{net_dhcp} - @pxref{net_dhcp} - -@item -@command{net_get_dhcp_option} - @pxref{net_get_dhcp_option} - -@item -@command{net_nslookup} - @pxref{net_nslookup} - -@item -@command{net_add_dns} - @pxref{net_add_dns} - -@item -@command{net_del_dns} - @pxref{net_del_dns} - -@item -@command{net_ls_dns} - @pxref{net_ls_dns} - -@item -@command{net_add_addr} - @pxref{net_add_addr} - -@item -@command{net_ipv6_autoconf} - @pxref{net_ipv6_autoconf} - -@item -@command{net_del_addr} - @pxref{net_del_addr} - -@item -@command{net_add_route} - @pxref{net_add_route} - -@item -@command{net_del_route} - @pxref{net_del_route} - -@item -@command{net_set_vlan} - @pxref{net_set_vlan} - -@item -@command{net_ls_routes} - @pxref{net_ls_routes} - -@item -@command{net_ls_cards} - @pxref{net_ls_cards} - -@item -@command{net_ls_addr} - @pxref{net_ls_addr} - -@end itemize - -@node newc_module -@section newc -This module provides support for accessing a CPIO archive as a file system -from GRUB. This module is for the following newer variants of the CPIO archive -supported by GNU CPIO (but GNU CPIO defaults to the "bin" format which is -handled by the module @ref{cpio_module}). - -These are the variants supported by this module: - -@itemize @bullet -@item -"newc" - SVR4 portable format without CRC. GNU file utility will identify these -as something like "ASCII cpio archive (SVR4 with no CRC)" - -@item -‘crc’ - SVR4 portable format with CRC. GNU file utility will identify these as -something like "ASCII cpio archive (SVR4 with CRC)" - -@end itemize - -@node nilfs2_module -@section nilfs2 -This module provides support for the New Implementation of Log filesystem -(nilfs2). -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node normal_module -@section normal -This module provides support for the normal mode in GRUB. @xref{normal} for -more information. - -@node ntfs_module -@section ntfs -This module provides support for the New Technology File System (NTFS) in GRUB. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node ntfscomp_module -@section ntfscomp -This module provides support for compression with the New Technology File -System (NTFS) in GRUB. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node ntldr_module -@section ntldr -This module provides support for the @command{ntldr} command. This is may be -used to boot a Windows boot loader such as NTLDR or BootMGR. - -@node odc_module -@section odc -This module provides support for accessing a CPIO archive as a file system -from GRUB. This module is for "odc" variant of the CPIO archive -supported by GNU CPIO (but GNU CPIO defaults to the "bin" format which is -handled by the module @ref{cpio_module}). - -GNU file utility will identify these as something like "ASCII cpio archive -(pre-SVR4 or odc)" - -@node offsetio_module -@section offsetio -This module provides support for reading from a file / archive at specified -offsets in GRUB. - -@node ofnet_module -@section ofnet -This module provides support for the Open Firmware (IEEE-1275) network device -support in GRUB. - -@node ohci_module -@section ohci -This module provides support for the Open Host Controller Interface (OHCI) for -USB 1 / USB 1.1 support in GRUB. - -@node part_acorn_module -@section part_acorn -This module provides support for reading from disks partitioned with the -Acorn Disc Filing System (ADFS) used on RiscOS. - -@node part_amiga_module -@section part_amiga -This module provides support for reading from disks partitioned with the -Amiga partition table. - -@node part_apple_module -@section part_apple -This module provides support for reading from disks partitioned with the -Macintosh partition table. - -@node part_bsd_module -@section part_bsd -This module provides support for reading from disks partitioned with BSD -style partition tables. - -@node part_dfly_module -@section part_dfly -This module provides support for reading from disks partitioned with the -DragonFly BSD partition table. - -@node part_dvh_module -@section part_dvh -This module provides support for reading from disks partitioned with the -SGI Disk Volume Header partition table. - -@node part_gpt_module -@section part_gpt -This module provides support for reading from disks partitioned with the -GUID Partition Tables (GPT) partition table. - -@node part_msdos_module -@section part_msdos -This module provides support for reading from disks partitioned with the -MSDOS (Master Boot Record / MBR) style partition tables. - -@node part_plan_module -@section part_plan -This module provides support for reading from disk partitioned with the -Plan9 style partition table. - -@node part_sun_module -@section part_sun -This module provides support for reading from disk partitioned with the -Sun style partition table. - -@node part_sunpc_module -@section part_sunpc -This module provides support for reading from disk partitioned with the -Sun PC style partition table. - -@node parttool_module -@section parttool -This module provides support for the @command{parttool} command. @xref{parttool} -for more information. - -@node password_module -@section password -This module provides support for the @command{password} command. Please note -that this uses the password in plain text, if security is a concern consider -using @ref{password_pbkdf2_module} instead. @xref{password} for more -information. - -@node password_pbkdf2_module -@section password_pbkdf2 -This module provides support for the @command{password_pbkdf2} command. -@xref{password_pbkdf2} for more information. - -@node pata_module -@section pata -This module provides support for Parallel ATA (PATA) disk device interfaces. - -@node pbkdf2_module -@section pbkdf2 -This module provides support for the Password-Based Key Derivation Function 2 -(PBKDF2) / PKCS#5 PBKDF2 as per RFC 2898. - -@node pbkdf2_test_module -@section pbkdf2_test -This module is intended for performing a functional test of the PBKDF2 -operation in GRUB. - -@node pci_module -@section pci -This module provides support for generic Peripheral Component Interconnect (PCI) -bus in GRUB. - -@node pcidump_module -@section pcidump -This module provides support for the @command{pcidump} command in GRUB to dump -the PCI configuration registers in hexadecimal of a specified PCI device -(vendor / device ID) or by position on the bus. - -@node pgp_module -@section pgp -This module provides support for the commands: @command{verify_detached}, -@command{trust}, @command{list_trusted}, @command{distrust} associated with -digital signature checking via the "Open Pretty Good Privacy" (PGP) protocol / -RFC 4880 using a provided public key. This module also uses / sets -environment variable @code{check_signatures}. @xref{verify_detached}, -@ref{trust}, @ref{list_trusted}, @ref{distrust}, and @ref{check_signatures}. - -@node plainmount_module -@section plainmount -This module provides support for accessing / mounting partitions encrypted -by "cryptsetup" operating in "plain mode". @xref{plainmount} for more -information. - -@node plan9_module -@section plan9 -This module provides support for the @command{plan9} command to load a Plan9 -kernel. - -@node play_module -@section play -This module provides support for the @command{play} command to play a tune -through the PC speaker. @xref{play} for more information. - -@node png_module -@section png -This module provides support for reading Portable Network Graphics (PNG) image -files in GRUB. - -@node priority_queue_module -@section priority_queue -This module provides support for a priority queue function within GRUB such as -to support networking functions. - -@node probe_module -@section probe -This module provides support for the @command{probe} command to retrieve device -information. @xref{probe} for more information. - -@node procfs_module -@section procfs -This module provides support for a Proc File System to provide a file system -like interface to some GRUB internal data. - -@node progress_module -@section progress -This module provides support for showing file loading progress to the terminal. - -@node pxe_module -@section pxe -This module provides support for Preboot Execution Environment (PXE) network -boot services as a file system driver for other GRUB modules. - -@node pxechain_module -@section pxechain -This module provides support for the @command{pxechainloader} command to load -another bootloader by PXE. - -@node raid5rec_module -@section raid5rec -This module provides support for recovering from faulty RAID4/5 disk arrays - -@node raid6rec_module -@section raid6rec -This module provides support for recovering from faulty RAID6 disk arrays. - -@node random_module -@section random -This module provides support for library functions to get random data via -the hardware ACPI Power Management Timer and the TSC time source (Timestamp -Counter). - -@node rdmsr_module -@section rdmsr -This module provides support for the @command{rdmsr} command to read CPU -Model Specific Registers. @xref{rdmsr} for more information. - -@node read_module -@section read -This module provides support for the @command{read} command for getting user -input. @xref{read} for more information. - -@node reboot_module -@section reboot -This module provides support for the @command{reboot} command to reboot the -computer. @xref{reboot} for more information. - -@node regexp_module -@section regexp -This module provides support for the @command{regexp} command to check if a -regular expression matches a string. This module also provides support for the -GRUB script wildcard translator. @xref{regexp} for more information. - -@node reiserfs_module -@section reiserfs -This module provides support for the ReiserFS File System in GRUB. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node relocator_module -@section relocator -This module provides support for relocating the image / executable being loaded -to the expected memory location(s) and jumping to (invoking) the executable. - -@node romfs_module -@section romfs -This module provides support for the Read-Only Memory File System (ROMFS). -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node scsi_module -@section scsi -This module provides support for the Small Computer System Interface (SCSI) -protocol used for some types of disk communication include some modern ones -such as USB Mass Storage Devices supporting "USB Attached SCSI" (UAS). - -@node sdl_module -@section sdl -This module provides support for Simple DirectMedia Layer (SDL) video / image -output from the grub-emu tool used to preview the GRUB menu from a running -Operating System such as Linux (useful to test GRUB menu configuration changes -without rebooting). When available in the compilation target environment, SDL2 -will be used instead of SDL1. - -@node search_module -@section search -This module provides support for the @command{search} command to search devices -by file, filesystem label, or filesystem UUID. @xref{search} for more -information. - -@node search_fs_file_module -@section search_fs_file -This module provides support for the @command{search.file} command which -is an alias for the corresponding @command{search} command. @xref{search} for -more information. - -@node search_fs_uuid_module -@section search_fs_uuid -This module provides support for the @command{search.fs_uuid} command which -is an alias for the corresponding @command{search} command. @xref{search} for -more information. - -@node search_label_module -@section search_label -This module provides support for the @command{search.fs_label} command which -is an alias for the corresponding @command{search} command. @xref{search} for -more information. - -@node sendkey_module -@section sendkey -This module provides support for the @command{sendkey} command to send -emulated keystrokes. @xref{sendkey} for more information. - -@node serial_module -@section serial -This module provides support for the @command{serial} command and associated -driver support for communication over a serial interface from GRUB. -@xref{serial} for more information. - -@node setjmp_module -@section setjmp -This module provides support for the @code{setjmp} and @code{longjmp} functions -used within GRUB. - -@node setjmp_test_module -@section setjmp_test -This module is intended for performing a functional test of the @code{setjmp} -and @code{longjmp} functions in GRUB. - -@node setpci_module -@section setpci -This module provides support for the @command{setpci} command to get / set -values from / to specified PCI / PCIe devices. - -@node sfs_module -@section sfs -This module provides support for the Amiga Smart File System (SFS) in GRUB. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node shift_test_module -@section shift_test -This module is intended for performing a functional test of the bit-wise shift -operations in GRUB. - -@node signature_test_module -@section signature_test -This module is intended for performing a functional test of the digital -signature verification functions in GRUB. - -@node sleep_module -@section sleep -This module provides support for the @command{sleep} command to wait a specified -number of seconds in GRUB. @xref{sleep} for more information. - -@node sleep_test_module -@section sleep_test -This module is intended for performing a functional test of the sleep function -in GRUB. - -@node smbios_module -@section smbios -This module provides support for the @command{smbios} command to retrieve SMBIOS -information in GRUB. @xref{smbios} for more information. - -@node spkmodem_module -@section spkmodem -This module provides support for outputting GRUB console information over an -audio output. This output can be fed into another computer's sound input -and decoded using the @code{spkmodem_recv} utility. Note that this will slow -down GRUB's performance. - -@node squash4_module -@section squash4 -This module provides support for the SquashFS compressed read-only file system -in GRUB. - -@node strtoull_test_module -@section strtoull_test -This module is intended for performing a functional test of the strtoull -function in GRUB. - -@node suspend_module -@section suspend -This module provides support for the @command{suspend} command in GRUB to -return to IEEE1275 prompt on "Open Firmware" systems. - -@node syslinuxcfg_module -@section syslinuxcfg -This module provides support for commands @command{syslinux_source}, -@command{syslinux_configfile}, @command{extract_syslinux_entries_source}, -and @command{extract_syslinux_entries_configfile} in GRUB. These commands -can be used to parse and display GRUB menu entries based on a Syslinux based -configuration (used for SYSLINUX, ISOLINUX, and PXELINUX). It can also -be used to execute the Syslinux loader from GRUB. - -@node tar_module -@section tar -This module provides support for the GNU Tar and POSIX Tar file archives as a -file system in GRUB. - -@node terminal_module -@section terminal -This module provides support for the commands @command{terminal_input} and -@command{terminal_output} in GRUB. @xref{terminal_input} and -@ref{terminal_output} for more information. - -@node terminfo_module -@section terminfo -This module provides support for the @command{terminfo} command in GRUB to -set various terminal modes / options. @xref{terminfo} for more information. - -@node test_module -@section test -This module provides support for the commands @command{test} and @command{[}. -These commands can be used to evaluate (test) an expression. @xref{test} for -more information. - -@node test_blockarg_module -@section test_blockarg -This module is intended for performing a functional test of the "block" command -argument function in GRUB internal functions via a test command -@command{test_blockarg}. - -@node testload_module -@section testload -This module is intended for performing a functional test of some file reading / -seeking functions in GRUB internals via a test command @command{testload}. - -@node testspeed_module -@section testspeed -This module provides support for the @command{testspeed} command to test and -print file read speed of a specified file. - -@node tftp_module -@section tftp -This module provides support for the Trivial File Transfer Protocol (TFTP) for -receiving files via the network to GRUB. TFTP may be used along with PXE for -network booting for example. - -@node tga_module -@section tga -This module provides support for reading Truevision Graphics Adapter (TGA) -image files in GRUB. - -@node time_module -@section time -This module provides support for the @command{time} command to measure the -time taken by a given command and output it to the terminal. - -@node tpm_module -@section tpm -This module provides support for interacting with a Trusted Platform Module -(TPM) with GRUB to perform Measured Boot. @xref{Measured Boot} for more -information. - -@node tr_module -@section tr -This module provides support for the @command{tr} command in GRUB. This can be -used to translate characters in a string according to the provided arguments. -For example this can be used to convert upper-case to lower-case and visa-versa. - -@node trig_module -@section trig -This module provides support for internal trig functions @code{grub_cos} and -@code{grub_sin} using lookup based computation. Currently these trig functions -are used by the gfxmenu circular progress bar. - -@node true_module -@section true -This module provides support for the commands @command{true} and -@command{false}. @xref{true} and @ref{false} for more information. - -@node truecrypt_module -@section truecrypt -This module provides support for the @command{truecrypt} command. This can be -used to load a Truecrypt ISO image. - -@node ubootnet_module -@section ubootnet -This module provides support for configuring network interfaces in GRUB using -information provided by a U-Boot bootloader. - -@node udf_module -@section udf -This module provides support for the Universal Disk Format (UDF) used on some -newer optical disks. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node ufs1_module -@section ufs1 -This module provides support for the Unix File System version 1 in GRUB. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node ufs1_be_module -@section ufs1_be -This module provides support for the Unix File System version 1 (big-endian) in -GRUB. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node ufs2_module -@section ufs2 -This module provides support for the Unix File System version 2 in GRUB. -Note: This module is not allowed in lockdown mode, @pxref{Lockdown} for more -information. - -@node uhci_module -@section uhci -This module provides support for the Universal Host Controller Interface (UHCI) -for USB 1.x. - -@node usb_module -@section usb -This module provides support for USB interfaces, USB hubs, and USB transfers -in GRUB. - -@node usb_keyboard_module -@section usb_keyboard -This module provides support for a USB keyboard in GRUB. - -@node usbms_module -@section usbms -This module provides support for USB Mass Storage devices in GRUB. - -@node usbserial_common_module -@section usbserial_common -This module provides support for common operations needed to support USB Serial -port adapters in GRUB (to support a model / type specific USB to serial -adapter defined in another module). - -@node usbserial_ftdi_module -@section usbserial_ftdi -This module provides support for USB to serial adapters with vendor ID 0x0403 -and product ID 0x6001 (often associated with FTDI devices). - -@node usbserial_pl2303_module -@section usbserial_pl2303 -This module provides support for USB to serial adapters with vendor ID 0x067b -and product ID 0x2303 (PL2303 USB to Serial adapter). - -@node usbserial_usbdebug_module -@section usbserial_usbdebug -This module provides support for debugging GRUB via a "USB 2.0 Debug Cable". -The USB 2.0 specification includes a "USB2 Debug Device Functional -Specification" that this driver is intended to support for GRUB. This may -integrate with GDB server function in GRUB (@pxref{gdb_module}). - -@node usbtest_module -@section usbtest -This module provides support for the @command{usb} command in GRUB to test USB -functionality by iterating through all connected USB devices and printing -information for each to the terminal. - -@node vbe_module -@section vbe -This module provides support for the VESA BIOS Extension (VBE) Video Driver in -GRUB. - -@node verifiers_module -@section verifiers -This module is a built-in kernel module to provide a framework for GRUB file -verifiers and string verifiers. - -@node vga_module -@section vga -This module provides support for the Video Graphics Array (VGA) Video Driver in -GRUB. - -@node vga_text_module -@section vga_text -This module provides support for the Video Graphics Array (VGA) terminal -output device. - -@node video_module -@section video -This module provides support for video output support functions within GRUB. - -@node video_bochs_module -@section video_bochs -This module provides support for the Bochs PCI Video Driver (also known as -Bochs Graphics Adapter / BGA) in GRUB. - -@node video_cirrus_module -@section video_cirrus -This module provides support for the Cirrus CLGD 5446 PCI Video Driver (Cirrus -Video) in GRUB. - -@node video_colors_module -@section video_colors -This module provides support for interpreting named colors and parsing RBG -hexadecimal values. - -@node video_fb_module -@section video_fb -This module provides support for video frame buffer (FB) support in GRUB. - -@node videoinfo_module -@section videoinfo -This module provides support for the @command{videoinfo} command and (depending -on architecture) the @command{vbeinfo} command. @xref{videoinfo} for more -information. - -@node videotest_module -@section videotest -This module provides support for the @command{videotest} command and (depending -on architecture) the @command{vbetest} to test the video subsystem in the -specified width and height. - -@node videotest_checksum_module -@section videotest_checksum -This module is intended for performing a functional test of the video -functions in GRUB by displaying a test image and capturing a checksum. - -@node wrmsr_module -@section wrmsr -This module provides support for the @command{wrmsr} command to write to CPU -model-specific registers. @xref{wrmsr} for more information. - -@node xen_boot_module -@section xen_boot -This module provides support for the commands @command{xen_hypervisor} and -@command{xen_module} to load a XEN hypervisor and module respectively. - -@node xfs_module -@section xfs -This module provides support for the XFS file system in GRUB. - -@node xnu_module -@section xnu -This module provides support for the commands: @command{xnu_devprop_load}, -@command{xnu_kernel}, @command{xnu_kernel64}, @command{xnu_mkext}, -@command{xnu_kext}, @command{xnu_kextdir}, @command{xnu_ramdisk}, -@command{xnu_splash}, and @command{xnu_resume} (only for emulated machine). -These commands support loading and interacting with a XNU (MacOS / Apple) based -system / kernel. - -@node xnu_uuid_module -@section xnu_uuid -This module provides support for the @command{xnu_uuid} command to transform -a 64-bit UUID to a format suitable for XNU. - -@node xnu_uuid_test_module -@section xnu_uuid_test -This module is intended for performing a functional test of the XNU UUID -conversion function. - -@node xzio_module -@section xzio -This module provides support for decompression of XZ compressed data. - -@node zfs_module -@section zfs -This module provides support for the ZFS file system in GRUB. - -@node zfscrypt_module -@section zfscrypt -This module provides support for the @command{zfskey} to import a decryption -key as well as decryption support for encrypted ZFS file systems. - -@node zfsinfo_module -@section zfsinfo -This module provides support for the commands @command{zfsinfo} to output ZFS -info about a device and @command{zfs-bootfs} to output ZFS-BOOTFSOBJ or store -it into a variable. - -@node zstd_module -@section zstd -This module provides support for the Zstandard (zstd) decompression algorithm -in GRUB. @node Commands -@chapter Available commands +@chapter The list of available commands In this chapter, we list all commands that are available in GRUB. @@ -5984,28 +996,22 @@ the global section of the configuration file (or ``menu''); most of them can be entered on the command-line and can be used either anywhere in the menu or specifically in the menu entries. -In rescue mode, only the @command{insmod} (@pxref{insmod}), @command{ls} -(@pxref{ls}), @command{set} (@pxref{set}), and @command{unset} -(@pxref{unset}) commands are normally available. If you end up in rescue -mode and do not know what to do, then @pxref{GRUB only offers a rescue -shell}. - @menu * Menu-specific commands:: -* Loader commands:: * General commands:: -* Command-line commands:: -* Networking commands:: -* Undocumented commands:: +* Command-line and menu entry commands:: @end menu @node Menu-specific commands -@section Commands for the menu only +@section The list of commands for the menu only The semantics used in parsing the configuration file are the following: @itemize @bullet +@item +The menu-specific commands have to be used before any others. + @item The files @emph{must} be in plain-text format. @@ -6019,496 +1025,114 @@ Options are separated by spaces. @item All numbers can be either decimal or hexadecimal. A hexadecimal number must be preceded by @samp{0x}, and is case-insensitive. + +@item +Extra options or text at the end of the line are ignored unless otherwise +specified. + +@item +Unrecognized commands are added to the current entry, except before entries +start, where they are ignored. @end itemize These commands can only be used in the menu: @menu * menuentry:: Start a menu entry -* submenu:: Group menu entries @end menu @node menuentry @subsection menuentry -@deffn Command menuentry @var{title} @ - [@option{--class=class} @dots{}] [@option{--users=users}] @ - [@option{--unrestricted}] [@option{--hotkey=key}] [@option{--id=id}] @ - [@var{arg} @dots{}] @{ @var{command}; @dots{} @} -This defines a GRUB menu entry named @var{title}. When this entry is -selected from the menu, GRUB will set the @var{chosen} environment variable -to value of @option{--id} if @option{--id} is given, execute the list of -commands given within braces, and if the last command in the list returned -successfully and a kernel was loaded it will execute the @command{boot} command. - -The @option{--class} option may be used any number of times to group menu -entries into classes. Menu themes may display different classes using -different styles. - -The @option{--users} option grants specific users access to specific menu -entries. @xref{Security}. - -The @option{--unrestricted} option grants all users access to specific menu -entries. @xref{Security}. - -The @option{--hotkey} option associates a hotkey with a menu entry. -@var{key} may be a single letter, or one of the aliases @samp{backspace}, -@samp{tab}, or @samp{delete}. - -The @option{--id} may be used to associate unique identifier with a menu entry. -@var{id} is string of ASCII aphanumeric characters, underscore and hyphen -and should not start with a digit. - -All other arguments including @var{title} are passed as positional parameters -when list of commands is executed with @var{title} always assigned to @code{$1}. -@end deffn - - -@node submenu -@subsection submenu - -@deffn Command submenu @var{title} @ - [@option{--class=class} @dots{}] [@option{--users=users}] @ - [@option{--unrestricted}] [@option{--hotkey=key}] [@option{--id=id}] @ - @{ @var{menu entries} @dots{} @} -This defines a submenu. An entry called @var{title} will be added to the -menu; when that entry is selected, a new menu will be displayed showing all -the entries within this submenu. - -All options are the same as in the @command{menuentry} command -(@pxref{menuentry}). -@end deffn - - -@node Loader commands -@section Various loader commands - -These commands are used to load necessary components to boot desired OS. -Many of the loader commands are not sufficiently documented. The following is -a list of commands that could use more documentation: - -@itemize @bullet -@item @command{appleloader} - Boot BIOS-based system. -@item @command{freedos} - Load FreeDOS kernel.sys. -@item @command{kfreebsd_loadenv} - Load FreeBSD env. -@item @command{kfreebsd_module_elf} - Load FreeBSD kernel module (ELF). -@item @command{kfreebsd_module} - Load FreeBSD kernel module. -@item @command{kfreebsd} - Load kernel of FreeBSD. -@item @command{knetbsd_module_elf} - Load NetBSD kernel module (ELF). -@item @command{knetbsd_module} - Load NetBSD kernel module. -@item @command{knetbsd} - Load kernel of NetBSD. -@item @command{kopenbsd} - Load kernel of OpenBSD. -@item @command{kopenbsd_ramdisk} - Load kOpenBSD ramdisk. -@item @command{legacy_initrd_nounzip} - Simulate grub-legacy `modulenounzip' command -@item @command{legacy_initrd} - Simulate grub-legacy `initrd' command -@item @command{legacy_kernel} - Simulate grub-legacy `kernel' command -@item @command{module2} - Load a multiboot 2 module. -@item @command{module} - Load a multiboot module. -@item @command{multiboot2} - Load a multiboot 2 kernel. -@item @command{multiboot} - Load a multiboot kernel. -@item @command{ntldr} - Load NTLDR or BootMGR. -@item @command{plan9} - Load Plan9 kernel. -@item @command{pxechainloader} - Load a PXE image. -@item @command{truecrypt} - Load Truecrypt ISO. -@item @command{xnu_kernel64} - Load 64-bit XNU image. -@item @command{xnu_kernel} - Load XNU image. -@item @command{xnu_kextdir} - Load XNU extension directory. -@item @command{xnu_kext} - Load XNU extension. -@item @command{xnu_mkext} - Load XNU extension package. -@item @command{xnu_ramdisk} - Load XNU ramdisk. It will be available in OS as md0. -@item @command{xnu_resume} - Load an image of hibernated XNU. -@item @command{xnu_splash} - Load a splash image for XNU. -@end itemize - - -@menu -* chainloader:: Chain-load another boot loader -* initrd:: Load a Linux initrd -* initrd16:: Load a Linux initrd (16-bit mode) -* linux:: Load a Linux kernel -* linux16:: Load a Linux kernel (16-bit mode) -@comment * xen_*:: Xen boot commands for AArch64 -* xen_hypervisor:: Load xen hypervisor binary (only on AArch64) -* xen_module:: Load xen modules for xen hypervisor (only on AArch64) -@end menu - - -@node chainloader -@subsection chainloader - -@deffn Command chainloader [@option{--force}] file [args...] -Load @var{file} as a chain-loader. Like any other file loaded by the -filesystem code, it can use the blocklist notation (@pxref{Block list -syntax}) to grab the first sector of the current partition with @samp{+1}. -On EFI platforms, any arguments after @var{file} will be sent to the loaded -image. - -If you specify the option @option{--force}, then load @var{file} forcibly, -whether it has a correct signature or not. This is required when you want to -load a defective boot loader, such as SCO UnixWare 7.1. -@end deffn - - -@node initrd -@subsection initrd - -@deffn Command initrd file [file @dots{}] -Load, in order, all initrds for a Linux kernel image, and set the -appropriate parameters in the Linux setup area in memory. This may only -be used after the @command{linux} command (@pxref{linux}) has been run. -See @ref{GNU/Linux} for more info on booting GNU/Linux. For more -information on initrds see the GNU/Linux kernel -@uref{https://docs.kernel.org/filesystems/ramfs-rootfs-initramfs.html, -documentation}. - -A new-style initrd (for kernels newer than 2.6) containing one file -with leading path components can also be generated at run time. This -can be done by prefixing an argument with @code{newc:} followed by the -path of the file in the new initrd, a @code{:}, and then the GRUB file -path to the file data to be be included. - -For example: -@example -initrd newc:/etc/ssh/config:(hd0,2)/home/user/.ssh/config \ - newc:/etc/ssh/ssh_host_rsa_key:/etc/ssh/ssh_host_rsa_key \ - /boot/initrd.gz \ - newc:/init:/home/user/init.fixed -@end example - -This command will generate two new-style initrds on the fly. The first -contains the path @samp{/etc/ssh/config} with the contents of -@samp{(hd0,2)/home/user/.ssh/config} and the path -@samp{/etc/ssh/ssh_host_rsa_key} with the contents of -@samp{/etc/ssh/ssh_host_rsa_key} on the @var{root} device. Parent directory -paths will automatically be generated as needed. This first generated initrd -will then have @samp{/boot/initrd.gz} concatenated after it. Next, another -new-style archive will be generated with the contents of @samp{/home/user/init.fixed} -in the path @samp{/init} and appended to the previous concatenation. Finally, -the result will be sent to the kernel when booted. - -Keep in mind that paths that come later will take precedence. So in the -example above, the generated path @samp{/init} will overwrite any @samp{/init} -in @samp{/boot/initrd.gz}. This can be useful when changing the main initrd -is undesirable or difficult. -@end deffn - - -@node initrd16 -@subsection initrd16 - -@deffn Command initrd16 file [file @dots{}] -Load, in order, all initrds for a Linux kernel image to be booted in -16-bit mode, and set the appropriate parameters in the Linux setup area in -memory. This may only be used after the @command{linux16} command -(@pxref{linux16}) has been run. See also @ref{GNU/Linux} and the @command{initrd} -command (@pxref{initrd}) for more details on arguments. - -This command is only available on the pc platform for x86 systems. -@end deffn - - -@node linux -@subsection linux - -@deffn Command linux file @dots{} -Load a Linux kernel image from @var{file}. The rest of the line is passed -verbatim as the @dfn{kernel command-line}. Any initrd must be reloaded -after using this command (@pxref{initrd}). - -On x86 systems, the kernel will be booted using the 32-bit boot protocol. -Note that this means that the @samp{vga=} boot option will not work; if you -want to set a special video mode, you will need to use GRUB commands such as -@samp{set gfxpayload=1024x768} or @samp{set gfxpayload=keep} (to keep the -same mode as used in GRUB) instead. GRUB can automatically detect some uses -of @samp{vga=} and translate them to appropriate settings of -@samp{gfxpayload}. The @command{linux16} command (@pxref{linux16}) avoids -this restriction. -@end deffn - - -@node linux16 -@subsection linux16 - -@deffn Command linux16 file @dots{} -Load a Linux kernel image from @var{file} in 16-bit mode. The rest of the -line is passed verbatim as the @dfn{kernel command-line}. Any initrd must -be reloaded after using this command (@pxref{initrd16}). - -The kernel will be booted using the traditional 16-bit boot protocol. As -well as bypassing problems with @samp{vga=} described in @ref{linux}, this -permits booting some other programs that implement the Linux boot protocol -for the sake of convenience. - -This command is only available on x86 systems. -@end deffn - - -@node xen_hypervisor -@subsection xen_hypervisor - -@deffn Command xen_hypervisor file [arguments] @dots{} -Load a Xen hypervisor binary from @var{file}. The rest of the line is passed -verbatim as the @dfn{kernel command-line}. Any other binaries must be -reloaded after using this command. -This command is only available on AArch64 systems. -@end deffn - - -@node xen_module -@subsection xen_module - -@deffn Command xen_module [--nounzip] file [arguments] -Load a module for xen hypervisor at the booting process of xen. -The rest of the line is passed verbatim as the module command line. -Modules should be loaded in the following order: - - dom0 kernel image - - dom0 ramdisk if present - - XSM policy if present -This command is only available on AArch64 systems. +@deffn Command title name @dots{} +Start a new boot entry, and set its name to the contents of the rest of +the line, starting with the first non-space character. @end deffn @node General commands -@section General commands +@section The list of general commands Commands usable anywhere in the menu and in the command-line. @menu * serial:: Set up a serial device -* terminal_input:: Manage input terminals -* terminal_output:: Manage output terminals -* terminfo:: Define terminal type +* terminfo:: Define escape sequences for a terminal @end menu @node serial @subsection serial -@deffn Command serial [@option{--unit=unit}] [@option{--port=port}] [@option{--speed=speed}] [@option{--word=word}] [@option{--parity=parity}] [@option{--stop=stop}] +@deffn Command serial [@option{--unit=unit}] [@option{--port=port}] [@option{--speed=speed}] [@option{--word=word}] [@option{--parity=parity}] [@option{--stop=stop}] [@option{--device=dev}] Initialize a serial device. @var{unit} is a number in the range 0-3 specifying which serial port to use; default is 0, which corresponds to -the port often called COM1. - -@var{port} is the I/O port where the UART is to be found or, if prefixed -with @samp{mmio,}, the MMIO address of the UART. If specified it takes -precedence over @var{unit}. - -Additionally, an MMIO address can be suffixed with: -@itemize @bullet -@item -@samp{.b} for bytes access (default) -@item -@samp{.w} for 16-bit word access -@item -@samp{.l} for 32-bit long word access or -@item -@samp{.q} for 64-bit long long word access -@end itemize - -Also, @var{port} can be of the form @samp{pci,XX:XX.X} to indicate a serial -device exposed on the PCI bus. - +the port often called COM1. @var{port} is the I/O port where the UART +is to be found; if specified it takes precedence over @var{unit}. @var{speed} is the transmission speed; default is 9600. @var{word} and @var{stop} are the number of data bits and stop bits. Data bits must be in the range 5-8 and stop bits must be 1 or 2. Default is 8 data bits and one stop bit. @var{parity} is one of @samp{no}, @samp{odd}, -@samp{even} and defaults to @samp{no}. - -If passed no @var{unit} nor @var{port}, or if @var{port} is set to -@samp{auto} then GRUB will attempt to use ACPI to automatically detect -the system default serial port and its configuration. If this information -is not available, it will default to @var{unit} 0. +@samp{even} and defaults to @samp{no}. The option @option{--device} +can only be used in the grub shell and is used to specify the +tty device to be used in the host operating system (@pxref{Invoking the +grub shell}). The serial port is not used as a communication channel unless the -@command{terminal_input} or @command{terminal_output} command is used -(@pxref{terminal_input}, @pxref{terminal_output}). +@command{terminal} command is used (@pxref{terminal}). -Note, valid @var{port} values, excluding IO port addresses, can be found -by listing terminals with @command{terminal_output}, selecting all names -prefixed by @samp{serial_} and removing that prefix. - -Examples: -@example -serial --port=0x3f8 --speed=9600 -serial --port=mmio,fefb0000.l --speed=115200 -serial --port=pci,00:16.3 --speed=115200 -@end example - -See also @ref{Serial terminal}. -@end deffn - - -@node terminal_input -@subsection terminal_input - -@deffn Command terminal_input [@option{--append}|@option{--remove}] @ - [terminal1] [terminal2] @dots{} -List or select an input terminal. - -With no arguments, list the active and available input terminals. - -With @option{--append}, add the named terminals to the list of active input -terminals; any of these may be used to provide input to GRUB. - -With @option{--remove}, remove the named terminals from the active list. - -With no options but a list of terminal names, make only the listed terminal -names active. -@end deffn - - -@node terminal_output -@subsection terminal_output - -@deffn Command terminal_output [@option{--append}|@option{--remove}] @ - [terminal1] [terminal2] @dots{} -List or select an output terminal. - -With no arguments, list the active and available output terminals. - -With @option{--append}, add the named terminals to the list of active output -terminals; all of these will receive output from GRUB. - -With @option{--remove}, remove the named terminals from the active list. - -With no options but a list of terminal names, make only the listed terminal -names active. +This command is only available if GRUB is compiled with serial +support. See also @ref{Serial terminal}. @end deffn @node terminfo @subsection terminfo -@deffn Command terminfo [@option{-a}|@option{-u}|@option{-v}] [@option{-g WxH}] [term] [type] -Define the capabilities of your terminal by giving the name of an entry in -the terminfo database, which should correspond roughly to a @samp{TERM} -environment variable in Unix. +@deffn Command terminfo @option{--name=name} @option{--cursor-address=seq} [@option{--clear-screen=seq}] [@option{--enter-standout-mode=seq}] [@option{--exit-standout-mode=seq}] +Define the capabilities of your terminal. Use this command to define +escape sequences, if it is not vt100-compatible. You may use @samp{\e} +for @key{ESC} and @samp{^X} for a control character. -The currently available terminal types are @samp{vt100}, @samp{vt100-color}, -@samp{ieee1275}, and @samp{dumb}. If you need other terminal types, please -contact us to discuss the best way to include support for these in GRUB. +You can use the utility @command{grub-terminfo} to generate +appropriate arguments to this command. @xref{Invoking grub-terminfo}. -The @option{-a} (@option{--ascii}), @option{-u} (@option{--utf8}), and -@option{-v} (@option{--visual-utf8}) options control how non-ASCII text is -displayed. @option{-a} specifies an ASCII-only terminal; @option{-u} -specifies logically-ordered UTF-8; and @option{-v} specifies -"visually-ordered UTF-8" (in other words, arranged such that a terminal -emulator without bidirectional text support will display right-to-left text -in the proper order; this is not really proper UTF-8, but a workaround). - -The @option{-g} (@option{--geometry}) can be used to specify terminal geometry. - -If no option or terminal type is specified, the current terminal type is -printed. +If no option is specified, the current settings are printed. @end deffn -@node Command-line commands -@section Command-line commands +@node Command-line and menu entry commands +@section The list of command-line and menu entry commands These commands are usable in the command-line and in menu entries. If you forget a command, you can run the command @command{help} (@pxref{help}). @menu -* [:: Check file types and compare values * acpi:: Load ACPI tables -* authenticate:: Check whether user is in user list -* background_color:: Set background color for active terminal -* background_image:: Load background image for active terminal -* badram:: Filter out bad regions of RAM * blocklist:: Print a block list * boot:: Start up your operating system * cat:: Show the contents of a file -* clear:: Clear the screen -* cmosclean:: Clear bit in CMOS -* cmosdump:: Dump CMOS contents -* cmostest:: Test bit in CMOS +* chainloader:: Chain-load another boot loader * cmp:: Compare two files * configfile:: Load a configuration file -* cpuid:: Check for CPU features -* crc:: Compute or check CRC32 checksums -* cryptocheck:: Check if a device is encrypted -* cryptomount:: Mount a crypto device -* cutmem:: Remove memory regions +* crc:: Calculate CRC32 checksums * date:: Display or set current date and time -* devicetree:: Load a device tree blob -* distrust:: Remove a pubkey from trusted keys -* drivemap:: Map a drive to another * echo:: Display a line of text -* efitextmode:: Set/Get text output mode resolution -* eval:: Evaluate agruments as GRUB commands * export:: Export an environment variable -* false:: Do nothing, unsuccessfully -* fdtdump:: Retrieve device tree information -* file:: Test the provided file against a type -* fwsetup:: Reboot into the firmware setup menu -* gdbinfo:: Provide info for debugging with GDB -* gettext:: Translate a string -* gptsync:: Fill an MBR based on GPT entries * halt:: Shut down your computer -* hashsum:: Compute or check hash checksum * help:: Show help messages -* hexdump:: Show raw contents of a file or memory * insmod:: Insert a module * keystatus:: Check key modifier status -* list_env:: List variables in environment block -* list_trusted:: List trusted public keys -* load_env:: Load variables from environment block -* loadfont:: Load font files -* loopback:: Make a device from a filesystem image * ls:: List devices or files -* lsfonts:: List loaded fonts -* lsmod:: Show loaded modules -* md5sum:: Compute or check MD5 hash -* module:: Load module for multiboot kernel -* multiboot:: Load multiboot compliant kernel -* nativedisk:: Switch to native disk drivers -* normal:: Enter normal mode -* normal_exit:: Exit from normal mode -* parttool:: Modify partition table entries -* password:: Set a clear-text password -* password_pbkdf2:: Set a hashed password -* plainmount:: Open device encrypted in plain mode * play:: Play a tune -* probe:: Retrieve device info -* rdmsr:: Read values from model-specific registers -* read:: Read user input * reboot:: Reboot your computer -* regexp:: Test if regular expression matches string -* rmmod:: Remove a module -* save_env:: Save variables to environment block -* search:: Search devices by file, label, or UUID -* sendkey:: Emulate keystrokes * set:: Set an environment variable -* sha1sum:: Compute or check SHA1 hash -* sha256sum:: Compute or check SHA256 hash -* sha512sum:: Compute or check SHA512 hash -* sleep:: Wait for a specified number of seconds -* smbios:: Retrieve SMBIOS information -* source:: Read a configuration file in same context -* test:: Check file types and compare values -* tpm2_key_protector_init:: Initialize the TPM2 key protector -* tpm2_key_protector_clear:: Clear the TPM2 key protector -* tpm2_dump_pcr:: Dump TPM2 PCRs -* true:: Do nothing, successfully -* trust:: Add public key to list of trusted keys * unset:: Unset an environment variable -@comment * vbeinfo:: List available video modes -* verify_detached:: Verify detached digital signature -* videoinfo:: List available video modes -* wrmsr:: Write values to model-specific registers @end menu -@node [ -@subsection [ -@deffn Command @code{[} expression @code{]} -Alias for @code{test @var{expression}} (@pxref{test}). -@end deffn - - @node acpi @subsection acpi @@ -6528,77 +1152,9 @@ Normally, this command will replace the Root System Description Pointer (RSDP) in the Extended BIOS Data Area to point to the new tables. If the @option{--no-ebda} option is used, the new tables will be known only to GRUB, but may be used by GRUB's EFI emulation. - -Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). - Otherwise an attacker can instruct the GRUB to load an SSDT table to - overwrite the kernel lockdown configuration and later load and execute - unsigned code. @end deffn -@node authenticate -@subsection authenticate -@deffn Command authenticate [userlist] -Check whether user is in @var{userlist} or listed in the value of variable -@samp{superusers}. See @pxref{superusers} for valid user list format. -If @samp{superusers} is empty, this command returns true. @xref{Security}. -@end deffn - - -@node background_color -@subsection background_color - -@deffn Command background_color color -Set background color for active terminal. For valid color specifications see -@pxref{Theme file format, ,Colors}. Background color can be changed only when -using @samp{gfxterm} for terminal output. - -This command sets color of empty areas without text. Text background color -is controlled by environment variables @var{color_normal}, @var{color_highlight}, -@var{menu_color_normal}, @var{menu_color_highlight}. @xref{Special environment variables}. -@end deffn - - -@node background_image -@subsection background_image - -@deffn Command background_image [[@option{--mode} @samp{stretch}|@samp{normal}] file] -Load background image for active terminal from @var{file}. Image is stretched -to fill up entire screen unless option @option{--mode} @samp{normal} is given. -Without arguments remove currently loaded background image. Background image -can be changed only when using @samp{gfxterm} for terminal output. - -@end deffn - - -@node badram -@subsection badram - -@deffn Command badram addr,mask[,addr,mask...] -Filter out bad RAM. - -This command notifies the memory manager that specified regions of -RAM ought to be filtered out (usually, because they're damaged). This -remains in effect after a payload kernel has been loaded by GRUB, as -long as the loaded kernel obtains its memory map from GRUB. Kernels that -support this include Linux, GNU Mach, the kernel of FreeBSD and Multiboot -kernels in general. - -Syntax is the same as provided by the @uref{http://www.memtest.org/, -Memtest86+ utility}: a list of address/mask pairs. Given a page-aligned -address and a base address / mask pair, if all the bits of the page-aligned -address that are enabled by the mask match with the base address, it means -this page is to be filtered. This syntax makes it easy to represent patterns -that are often result of memory damage, due to physical distribution of memory -cells. - -The command is similar to @command{cutmem} command. - -Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). - This prevents removing EFI memory regions to potentially subvert the - security mechanisms provided by the UEFI secure boot. -@end deffn - @node blocklist @subsection blocklist @@ -6620,75 +1176,35 @@ a menu entry). @node cat @subsection cat -@deffn Command cat [@option{--dos}] file +@deffn Command cat file Display the contents of the file @var{file}. This command may be useful to remind you of your OS's root partition: @example grub> @kbd{cat /etc/fstab} @end example - -If the @option{--dos} option is used, then carriage return / new line pairs -will be displayed as a simple new line. Otherwise, the carriage return will -be displayed as a control character (@samp{}) to make it easier to see -when boot problems are caused by a file formatted using DOS-style line -endings. - -Note: @command{cat} can be used to view the contents of devices using the -block list syntax (@pxref{Block list syntax}). However, it is not advised -to view binary data because it will try to decode UTF-8 strings, which can -lead to some bytes missing or added in the output. Instead, use the -@command{hexdump} command (@pxref{hexdump}). @end deffn -@node clear -@subsection clear +@node chainloader +@subsection chainloader -@deffn Command clear -Clear the screen. -@end deffn - - -@node cmosclean -@subsection cmosclean - -@deffn Command cmosclean byte:bit -Clear value of bit in CMOS at location @var{byte}:@var{bit}. This command -is available only on platforms that support CMOS. -@end deffn - - -@node cmosdump -@subsection cmosdump - -@deffn Dump CMOS contents -Dump full CMOS contents as hexadecimal values. This command is available only -on platforms that support CMOS. -@end deffn - - -@node cmostest -@subsection cmostest - -@deffn Command cmostest byte:bit -Test value of bit in CMOS at location @var{byte}:@var{bit}. Exit status -is zero if bit is set, non zero otherwise. This command is available only -on platforms that support CMOS. +@deffn Command chainloader [@option{--force}] file +Load @var{file} as a chain-loader. Like any other file loaded by the +filesystem code, it can use the blocklist notation to grab the first +sector of the current partition with @samp{+1}. If you specify the +option @option{--force}, then load @var{file} forcibly, whether it has a +correct signature or not. This is required when you want to load a +defective boot loader, such as SCO UnixWare 7.1 (@pxref{SCO UnixWare}). @end deffn @node cmp @subsection cmp -@deffn Command cmp [@option{-v}] file1 file2 -Compare the file @var{file1} with the file @var{file2}. If they are completely -identical, @code{$?} will be set to 0. Otherwise, if the files are not identical, -@code{$?} will be set to a nonzero value. - -By default nothing will be output. If the @option{-v} is used, verbose mode is -enabled. In this mode when when the files differ in size, print the sizes like -this: +@deffn Command cmp file1 file2 +Compare the file @var{file1} with the file @var{file2}. If they differ +in size, print the sizes like this: @example Differ in size: 0x1234 [foo], 0x4321 [bar] @@ -6701,6 +1217,7 @@ bytes like this: Differ at the offset 777: 0xbe [foo], 0xef [bar] @end example +If they are completely identical, nothing will be printed. @end deffn @@ -6708,113 +1225,17 @@ Differ at the offset 777: 0xbe [foo], 0xef [bar] @subsection configfile @deffn Command configfile file -Load @var{file} as a configuration file. If @var{file} defines any menu -entries, then show a menu containing them immediately. Any environment -variable changes made by the commands in @var{file} will not be preserved -after @command{configfile} returns. -@end deffn - - -@node cpuid -@subsection cpuid - -@deffn Command cpuid [-l] [-p] -Check for CPU features. This command is only available on x86 systems. - -With the @option{-l} option, return true if the CPU supports long mode -(64-bit). - -With the @option{-p} option, return true if the CPU supports Physical -Address Extension (PAE). - -If invoked without options, this command currently behaves as if it had been -invoked with @option{-l}. This may change in the future. +Load @var{file} as a configuration file. @end deffn @node crc @subsection crc -@deffn Command crc arg @dots{} -Alias for @code{hashsum --hash crc32 arg @dots{}}. See command @command{hashsum} -(@pxref{hashsum}) for full description. +@deffn Command crc file +Display the CRC32 checksum of @var{file}. @end deffn -@node cryptocheck -@subsection cryptocheck - -@deffn Command cryptocheck [ @option{--quiet} ] device -Check if a given diskfilter device is backed by encrypted devices -(@pxref{cryptomount} for additional information). - -The command examines all backing devices, physical volumes, of a specified -logical volume, like LVM2, and fails when at least one of them is unencrypted. - -The option @option{--quiet} can be given to suppress the output. -@end deffn - -@node cryptomount -@subsection cryptomount - -@deffn Command cryptomount [ [@option{-p} password] | [@option{-k} keyfile [@option{-O} keyoffset] [@option{-S} keysize] ] | [@option{-P} protector] ] [@option{-H} file] device|@option{-u} uuid|@option{-a}|@option{-b} -Setup access to encrypted device. A passphrase will be requested interactively, -if neither the @option{-p} nor @option{-k} options are given. The option -@option{-p} can be used to supply a passphrase (useful for scripts). -Alternatively the @option{-k} option can be used to supply a keyfile with -options @option{-O} and @option{-S} optionally supplying the offset and size, -respectively, of the key data in the given key file. Besides the keyfile, -the key can be stored in a key protector, and option @option{-P} configures -specific key protector, e.g. tpm2, to retrieve the key from. -The @option{-H} options can be used to supply cryptomount backends with an -alternative header file (aka detached header). Not all backends have headers -nor support alternative header files (currently only LUKS1 and LUKS2 support them). -Argument @var{device} configures specific grub device -(@pxref{Naming convention}); option @option{-u} @var{uuid} configures device -with specified @var{uuid}; option @option{-a} configures all detected encrypted -devices; option @option{-b} configures all geli containers that have boot flag set. - -Devices are not allowed to be given as key files nor as detached header files. -However, this limitation can be worked around by using blocklist syntax. So -for instance, @code{(hd1,gpt2)} can not be used, but @code{(hd1,gpt2)0+} will -achieve the desired result. - -GRUB supports devices encrypted using LUKS, LUKS2 and geli. Note that necessary -modules (@var{luks}, @var{luks2} and @var{geli}) have to be loaded manually -before this command can be used. For LUKS2 only the PBKDF2 key derivation -function is supported, as Argon2 is not yet supported. - -Successfully decrypted disks are named as (cryptoX) and have increasing numeration -suffix for each new decrypted disk. If the encrypted disk hosts some higher level -of abstraction (like LVM2 or MDRAID) it will be created under a separate device -namespace in addition to the cryptodisk namespace. - -Support for plain encryption mode (plain dm-crypt) is provided via separate -@command{@pxref{plainmount}} command. - -On the EFI platform, GRUB tries to erase master keys from memory when the cryptodisk -module is unloaded or the command @command{exit} is executed. All secrets remain in -memory when the command @command{chainloader} is issued, because execution can -return to GRUB on the EFI platform. -@end deffn - -@node cutmem -@subsection cutmem - -@deffn Command cutmem from[K|M|G] to[K|M|G] -Remove any memory regions in specified range. - -This command notifies the memory manager that specified regions of RAM ought to -be filtered out. This remains in effect after a payload kernel has been loaded -by GRUB, as long as the loaded kernel obtains its memory map from GRUB. Kernels -that support this include Linux, GNU Mach, the kernel of FreeBSD and Multiboot -kernels in general. - -The command is similar to @command{badram} command. - -Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). - This prevents removing EFI memory regions to potentially subvert the - security mechanisms provided by the UEFI secure boot. -@end deffn @node date @subsection date @@ -6829,62 +1250,6 @@ hour, minute, and second unchanged. @end deffn -@node devicetree -@subsection devicetree - -@deffn Command devicetree file -Load a device tree blob (.dtb) from a filesystem, for later use by a Linux -kernel. Does not perform merging with any device tree supplied by firmware, -but rather replaces it completely. - -Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). - This is done to prevent subverting various security mechanisms. -@end deffn - -@node distrust -@subsection distrust - -@deffn Command distrust pubkey_id -Remove public key @var{pubkey_id} from GRUB's keyring of trusted keys. -@var{pubkey_id} is the last four bytes (eight hexadecimal digits) of -the GPG v4 key id, which is also the output of @command{list_trusted} -(@pxref{list_trusted}). Outside of GRUB, the key id can be obtained -using @code{gpg --fingerprint}). -These keys are used to validate signatures when environment variable -@code{check_signatures} is set to @code{enforce} -(@pxref{check_signatures}), and by some invocations of -@command{verify_detached} (@pxref{verify_detached}). @xref{Using -digital signatures}, for more information. -@end deffn - -@node drivemap -@subsection drivemap - -@deffn Command drivemap @option{-l}|@option{-r}|[@option{-s}] @ - from_drive to_drive -Without options, map the drive @var{from_drive} to the drive @var{to_drive}. -This is necessary when you chain-load some operating systems, such as DOS, -if such an OS resides at a non-first drive. For convenience, any partition -suffix on the drive is ignored, so you can safely use @verb{'${root}'} as a -drive specification. - -With the @option{-s} option, perform the reverse mapping as well, swapping -the two drives. - -With the @option{-l} option, list the current mappings. - -With the @option{-r} option, reset all mappings to the default values. - -For example: - -@example -drivemap -s (hd0) (hd1) -@end example - -NOTE: Only available on i386-pc. -@end deffn - - @node echo @subsection echo @@ -6928,56 +1293,6 @@ character will print that character. @end deffn -@node efitextmode -@subsection efitextmode - -@deffn Command efitextmode [min | max | | ] -When used with no arguments displays all available text output modes. The -set mode determines the columns and rows of the text display when in -text mode. An asterisk, @samp{*}, will be at the end of the line of the -currently set mode. - -If given a single parameter, it must be @samp{min}, @samp{max}, or a mode -number given by the listing when run with no arguments. These arguments set -the mode to the minimum, maximum, and particular mode respectively. - -Otherwise, the command must be given two numerical arguments specifying the -columns and rows of the desired mode. Specifying a columns and rows -combination that corresponds to no supported mode, will return error, but -otherwise have no effect. - -By default GRUB will start in whatever mode the EFI firmware defaults to. -There are firmwares known to set up the default mode such that output -behaves strangely, for example the cursor in the GRUB shell never reaches -the bottom of the screen or, when typing characters at the prompt, -characters from previous command output are overwritten. Setting the mode -may fix this. - -The EFI specification says that mode 0 must be available and have -columns and rows of 80 and 25 respectively. Mode 1 may be defined and if -so must have columns and rows of 80 and 50 respectively. Any other modes -may have columns and rows arbitrarily defined by the firmware. This means -that a mode with columns and rows of 100 and 31 on one firmware may be -a different mode number on a different firmware or not exist at all. -Likewise, mode number 2 on one firmware may have a different number of -columns and rows than mode 2 on a different firmware. So one should not -rely on a particular mode number or a mode of a certain number of columns -and rows existing on all firmwares, except for mode 0. - -Note: This command is only available on EFI platforms and is similar to -EFI shell "mode" command. -@end deffn - - -@node eval -@subsection eval - -@deffn Command eval string ... -Concatenate arguments together using single space as separator and evaluate -result as sequence of GRUB commands. -@end deffn - - @node export @subsection export @@ -6987,245 +1302,28 @@ to subsidiary configuration files loaded using @command{configfile}. @end deffn -@node false -@subsection false - -@deffn Command false -Do nothing, unsuccessfully. This is mainly useful in control constructs -such as @code{if} and @code{while} (@pxref{Shell-like scripting}). -@end deffn - - -@node fdtdump -@subsection fdtdump - -@deffn Command fdtdump @ - [@option{--prop} @var{prop}] @ - [@option{--set} @var{variable}] -Retrieve device tree information. - -The @command{fdtdump} command returns the value of a property in the device -tree provided by the firmware. The @option{--prop} option determines which -property to select. - -The default action is to print the value of the requested field to the console, -but a variable name can be specified with @option{--set} to store the value -instead of printing it. - -For example, this will store and then display the model string. - -@example -fdtdump --prop model --set machine_model -echo $machine_model -@end example -@end deffn - - -@node file -@subsection file - -@deffn Command file is_file_type filename - -The @command{file} command tests whether the provided @var{filename} is the -type provided by @var{is_file_type}. When the @command{file} is of type -@var{is_file_type} this command will return 0, otherwise it will return -non-zero (no output is provided to the terminal). - -@var{is_file_type} may be one of the following options: -@itemize @bullet -@item -@option{--is-i386-xen-pae-domu} Check if @var{filename} can be booted as i386 -PAE Xen unprivileged guest kernel -@item -@option{--is-x86_64-xen-domu} Check if @var{filename} can be booted as x86_64 -Xen unprivileged guest kernel -@item -@option{--is-x86-xen-dom0} Check if @var{filename} can be used as Xen x86 -privileged guest kernel -@item -@option{--is-x86-multiboot} Check if @var{filename} can be used as x86 -multiboot kernel -@item -@option{--is-x86-multiboot2} Check if @var{filename} can be used as x86 -multiboot2 kernel -@item -@option{--is-arm-linux} Check if @var{filename} is ARM Linux -@item -@option{--is-arm64-linux} Check if @var{filename} is ARM64 Linux -@item -@option{--is-ia64-linux} Check if @var{filename} is IA64 Linux -@item -@option{--is-mips-linux} Check if @var{filename} is MIPS Linux -@item -@option{--is-mipsel-linux} Check if @var{filename} is MIPSEL Linux -@item -@option{--is-sparc64-linux} Check if @var{filename} is SPARC64 Linux -@item -@option{--is-powerpc-linux} Check if @var{filename} is POWERPC Linux -@item -@option{--is-x86-linux} Check if @var{filename} is x86 Linux -@item -@option{--is-x86-linux32} Check if @var{filename} is x86 Linux supporting -32-bit protocol -@item -@option{--is-x86-kfreebsd} Check if @var{filename} is x86 kFreeBSD -@item -@option{--is-i386-kfreebsd} Check if @var{filename} is i386 kFreeBSD -@item -@option{--is-x86_64-kfreebsd} Check if @var{filename} is x86_64 kFreeBSD -@item -@option{--is-x86-knetbsd} Check if @var{filename} is x86 kNetBSD -@item -@option{--is-i386-knetbsd} Check if @var{filename} is i386 kNetBSD -@item -@option{--is-x86_64-knetbsd} Check if @var{filename} is x86_64 kNetBSD -@item -@option{--is-i386-efi} Check if @var{filename} is i386 EFI file -@item -@option{--is-x86_64-efi} Check if @var{filename} is x86_64 EFI file -@item -@option{--is-ia64-efi} Check if @var{filename} is IA64 EFI file -@item -@option{--is-arm64-efi} Check if @var{filename} is ARM64 EFI file -@item -@option{--is-arm-efi} Check if @var{filename} is ARM EFI file -@item -@option{--is-riscv32-efi} Check if @var{filename} is RISC-V 32bit EFI file -@item -@option{--is-riscv64-efi} Check if @var{filename} is RISC-V 64bit EFI file -@item -@option{--is-hibernated-hiberfil} Check if @var{filename} is hiberfil.sys in -hibernated state -@item -@option{--is-x86_64-xnu} Check if @var{filename} is x86_64 XNU (Mac OS X kernel) -@item -@option{--is-i386-xnu} Check if @var{filename} is i386 XNU (Mac OS X kernel) -@item -@option{--is-xnu-hibr} Check if @var{filename} is XNU (Mac OS X kernel) -hibernated image -@item -@option{--is-x86-bios-bootsector} Check if @var{filename} is BIOS bootsector -@end itemize -@end deffn - - -@node fwsetup -@subsection fwsetup - -@deffn Command fwsetup [@option{--is-supported}] -Reboot into the firmware setup menu. If @option{--is-supported} option is -specified, instead check whether the firmware supports a setup menu and -exit successfully if so. -@end deffn - - -@node gdbinfo -@subsection gdbinfo - -@deffn Command gdbinfo -Output text to be used as a GDB command for a GDB session using the gdb_grub -script and attached to a running GRUB instance. The GDB command that is -output will tell GDB how to load debugging symbols to their proper runtime -address. Currently this is only available for EFI platforms. See the Debugging -in the developer documentation for more information. -@end deffn - - -@node gettext -@subsection gettext - -@deffn Command gettext string -Translate @var{string} into the current language. - -The current language code is stored in the @samp{lang} variable in GRUB's -environment (@pxref{lang}). Translation files in MO format are read from -@samp{locale_dir} (@pxref{locale_dir}), usually @file{/boot/grub/locale}. -@end deffn - - -@node gptsync -@subsection gptsync - -@deffn Command gptsync device [partition[+/-[type]]] @dots{} -Disks using the GUID Partition Table (GPT) also have a legacy Master Boot -Record (MBR) partition table for compatibility with the BIOS and with older -operating systems. The legacy MBR can only represent a limited subset of -GPT partition entries. - -This command populates the legacy MBR with the specified @var{partition} -entries on @var{device}. Up to three partitions may be used. - -@var{type} is an MBR partition type code; prefix with @samp{0x} if you want -to enter this in hexadecimal. The separator between @var{partition} and -@var{type} may be @samp{+} to make the partition active, or @samp{-} to make -it inactive; only one partition may be active. If both the separator and -type are omitted, then the partition will be inactive. -@end deffn - - @node halt @subsection halt -@deffn Command halt [@option{--no-apm}] -The command halts the computer. On the i386-pc target, the @option{--no-apm} -option, or short @option{-n}, is specified, no APM BIOS call is performed. -Otherwise, the computer is shut down using APM on that target. -@end deffn - - -@node hashsum -@subsection hashsum - -@deffn Command hashsum @option{--hash} hash @option{--keep-going} @option{--uncompress} @option{--check} file [@option{--prefix} dir]|file @dots{} -Compute or verify file hashes. Hash type is selected with option @option{--hash}. -Supported hashes are: @samp{adler32}, @samp{crc64}, @samp{crc32}, -@samp{crc32rfc1510}, @samp{crc24rfc2440}, @samp{md4}, @samp{md5}, -@samp{ripemd160}, @samp{sha1}, @samp{sha224}, @samp{sha256}, @samp{sha512}, -@samp{sha384}, @samp{tiger192}, @samp{tiger}, @samp{tiger2}, @samp{whirlpool}. -Option @option{--uncompress} uncompresses files before computing hash. - -When list of files is given, hash of each file is computed and printed, -followed by file name, each file on a new line. - -When option @option{--check} is given, it points to a file that contains -list of @var{hash name} pairs in the same format as used by UNIX -@command{md5sum} command. Option @option{--prefix} -may be used to give directory where files are located. Hash verification -stops after the first mismatch was found unless option @option{--keep-going} -was given. The exit code @code{$?} is set to 0 if hash verification -is successful. If it fails, @code{$?} is set to a nonzero value. +@deffn Command halt @option{--no-apm} +The command halts the computer. If the @option{--no-apm} option +is specified, no APM BIOS call is performed. Otherwise, the computer +is shut down using APM. @end deffn @node help @subsection help -@deffn Command help [pattern @dots{}] +@deffn Command help @option{--all} [pattern @dots{}] Display helpful information about builtin commands. If you do not -specify @var{pattern}, this command shows short descriptions of all -available commands. +specify @var{pattern}, this command shows short descriptions of most of +available commands. If you specify the option @option{--all} to this +command, short descriptions of rarely used commands (such as +@ref{testload}) are displayed as well. If you specify any @var{patterns}, it displays longer information -about each of the commands whose names begin with those @var{patterns}. -@end deffn - - -@node hexdump -@subsection hexdump - -@deffn Command hexdump [--skip offset] [--length len] FILE_OR_DEVICE -Show raw contents of a file or memory. When option @option{--skip} is given, -@samp{offset} number of bytes are skipped from the start of the device or -file given. And @option{--length} allows specifying a maximum number of bytes -to be shown. - -If given the special device named @samp{(mem)}, then the @samp{offset} given to -@option{--skip} is treated as the address of a memory location to dump from. - -Note: The dumping of RAM memory (by the (mem) argument) is not allowed when -when lockdown is enforced (@pxref{Lockdown}). The dumping of disk or file -data is allowed when lockdown is enforced. - +about each of the commands which match those @var{patterns}. @end deffn @@ -7251,331 +1349,26 @@ only if checking key modifier status is supported. @end deffn -@node list_env -@subsection list_env - -@deffn Command list_env [@option{--file} file] -List all variables in the environment block file. @xref{Environment block}. - -The @option{--file} option overrides the default location of the -environment block. -@end deffn - -@node list_trusted -@subsection list_trusted - -@deffn Command list_trusted -List all public keys trusted by GRUB for validating signatures. -The output is in GPG's v4 key fingerprint format (i.e., the output of -@code{gpg --fingerprint}). The least significant four bytes (last -eight hexadecimal digits) can be used as an argument to -@command{distrust} (@pxref{distrust}). -@xref{Using digital signatures}, for more information about uses for -these keys. -@end deffn - -@node load_env -@subsection load_env - -@deffn Command load_env [@option{--file} file] [@option{--skip-sig}] [whitelisted_variable_name] @dots{} -Load all variables from the environment block file into the environment. -@xref{Environment block}. - -The @option{--file} option overrides the default location of the environment -block. - -The @option{--skip-sig} option skips signature checking even when the -value of environment variable @code{check_signatures} is set to -@code{enforce} (@pxref{check_signatures}). - -If one or more variable names are provided as arguments, they are -interpreted as a whitelist of variables to load from the environment -block file. Variables set in the file but not present in the -whitelist are ignored. - -The @option{--skip-sig} option should be used with care, and should -always be used in concert with a whitelist of acceptable variables -whose values should be set. Failure to employ a carefully constructed -whitelist could result in reading a malicious value into critical -environment variables from the file, such as setting -@code{check_signatures=no}, modifying @code{prefix} to boot from an -unexpected location or not at all, etc. - -When used with care, @option{--skip-sig} and the whitelist enable an -administrator to configure a system to boot only signed -configurations, but to allow the user to select from among multiple -configurations, and to enable ``one-shot'' boot attempts and -``savedefault'' behavior. @xref{Using digital signatures}, for more -information. -@end deffn - - -@node loadfont -@subsection loadfont - -@deffn Command loadfont file @dots{} -Load specified font files. Unless absolute pathname is given, @var{file} -is assumed to be in directory @samp{$prefix/fonts} with -suffix @samp{.pf2} appended. @xref{Theme file format,,Fonts}. -@end deffn - - -@node loopback -@subsection loopback - -@deffn Command loopback [@option{-d}] [@option{-D}] device file -Make the device named @var{device} correspond to the contents of the -filesystem image in @var{file}. For example: - -@example -loopback loop0 /path/to/image -ls (loop0)/ -@end example - -Specifying the @option{-D} option allows the loopback file to be tranparently -decompressed if there is an appropriate decompressor loaded. - -With the @option{-d} option, delete a device previously created using this -command. -@end deffn - - @node ls @subsection ls -@deffn Command ls [arg @dots{}] +@deffn Command ls [arg] List devices or files. With no arguments, print all devices known to GRUB. If the argument is a device name enclosed in parentheses (@pxref{Device -syntax}), then print the name of the filesystem of that device. +syntax}), then list all files at the root directory of that device. If the argument is a directory given as an absolute file name (@pxref{File name syntax}), then list the contents of that directory. @end deffn -@node lsfonts -@subsection lsfonts - -@deffn Command lsfonts -List loaded fonts. -@end deffn - - -@node lsmod -@subsection lsmod - -@deffn Command lsmod -Show list of loaded modules. -@end deffn - -@node md5sum -@subsection md5sum - -@deffn Command md5sum arg @dots{} -Alias for @code{hashsum --hash md5 arg @dots{}}. See command @command{hashsum} -(@pxref{hashsum}) for full description. -@end deffn - -@node module -@subsection module - -@deffn Command module [--nounzip] file [arguments] -Load a module for multiboot kernel image. The rest of the -line is passed verbatim as the module command line. -@end deffn - -@node multiboot -@subsection multiboot - -@deffn Command multiboot [--quirk-bad-kludge] [--quirk-modules-after-kernel] file @dots{} -Load a multiboot kernel image from @var{file}. The rest of the -line is passed verbatim as the @dfn{kernel command-line}. Any module must -be reloaded after using this command (@pxref{module}). - -Some kernels have known problems. You need to specify --quirk-* for those. ---quirk-bad-kludge is a problem seen in several products that they include -loading kludge information with invalid data in ELF file. GRUB prior to 0.97 -and some custom builds preferred ELF information while 0.97 and GRUB 2 -use kludge. Use this option to ignore kludge. -Known affected systems: old Solaris, SkyOS. - ---quirk-modules-after-kernel is needed for kernels which load at relatively -high address e.g. 16MiB mark and can't cope with modules stuffed between -1MiB mark and beginning of the kernel. -Known afftected systems: VMWare. -@end deffn - -@node nativedisk -@subsection nativedisk - -@deffn Command nativedisk -Switch from firmware disk drivers to native ones. -Really useful only on platforms where both -firmware and native disk drives are available. -Currently i386-pc, i386-efi, i386-ieee1275 and -x86_64-efi. -@end deffn - -@node normal -@subsection normal - -@deffn Command normal [file] -Enter normal mode and display the GRUB menu. - -In normal mode, commands, filesystem modules, and cryptography modules are -automatically loaded, and the full GRUB script parser is available. Other -modules may be explicitly loaded using @command{insmod} (@pxref{insmod}). - -If a @var{file} is given, then commands will be read from that file. -Otherwise, they will be read from @file{$prefix/grub.cfg} if it exists. - -@command{normal} may be called from within normal mode, creating a nested -environment. It is more usual to use @command{configfile} -(@pxref{configfile}) for this. -@end deffn - - -@node normal_exit -@subsection normal_exit - -@deffn Command normal_exit -Exit normal mode (@pxref{normal}). If this instance of normal mode was not -nested within another one, then return to rescue mode. -@end deffn - - -@node parttool -@subsection parttool - -@deffn Command parttool partition commands -Make various modifications to partition table entries. - -Each @var{command} is either a boolean option, in which case it must be -followed with @samp{+} or @samp{-} (with no intervening space) to enable or -disable that option, or else it takes a value in the form -@samp{@var{command}=@var{value}}. - -Currently, @command{parttool} is only useful on DOS partition tables (also -known as Master Boot Record, or MBR). On these partition tables, the -following commands are available: - -@table @asis -@item @samp{boot} (boolean) -When enabled, this makes the selected partition be the active (bootable) -partition on its disk, clearing the active flag on all other partitions. -This command is limited to @emph{primary} partitions. - -@item @samp{type} (value) -Change the type of an existing partition. The value must be a number in the -range 0-0xFF (prefix with @samp{0x} to enter it in hexadecimal). - -@item @samp{hidden} (boolean) -When enabled, this hides the selected partition by setting the @dfn{hidden} -bit in its partition type code; when disabled, unhides the selected -partition by clearing this bit. This is useful only when booting DOS or -Windows and multiple primary FAT partitions exist in one disk. See also -@ref{DOS/Windows}. -@end table -@end deffn - - -@node password -@subsection password - -@deffn Command password user clear-password -Define a user named @var{user} with password @var{clear-password}. -@xref{Security}. -@end deffn - - -@node password_pbkdf2 -@subsection password_pbkdf2 - -@deffn Command password_pbkdf2 user hashed-password -Define a user named @var{user} with password hash @var{hashed-password}. -Use @command{grub-mkpasswd-pbkdf2} (@pxref{Invoking grub-mkpasswd-pbkdf2}) -to generate password hashes. @xref{Security}. -@end deffn - - -@node plainmount -@subsection plainmount - -@deffn Command plainmount device @option{-c} cipher @option{-s} key size [@option{-h} hash] -[@option{-S} sector size] [@option{-p} password] [@option{-u} uuid] -[[@option{-d} keyfile] [@option{-O} keyfile offset]] - - -Setup access to the encrypted device in plain mode. Offset of the encrypted -data at the device is specified in terms of 512 byte sectors using the blocklist -syntax and loopback device. The following example shows how to specify 1MiB -offset: - -@example -loopback node (hd0,gpt1)2048+ -plainmount node @var{...} -@end example - -The @command{plainmount} command can be used to open LUKS encrypted volume -if its master key and parameters (key size, cipher, offset, etc) are known. - -There are two ways to specify a password: a keyfile and a secret passphrase. -The keyfile path parameter has higher priority than the secret passphrase -parameter and is specified with the option @option{-d}. Password data obtained -from keyfiles is not hashed and is used directly as a cipher key. An optional -offset of password data in the keyfile can be specified with the option -@option{-O} or directly with the option @option{-d} and GRUB blocklist syntax, -if the keyfile data can be accessed from a device and is 512 byte aligned. -The following example shows both methods to specify password data in the -keyfile at offset 1MiB: - -@example -plainmount -d (hd0,gpt1)2048+ @var{...} -plainmount -d (hd0,gpt1)+ -O 1048576 @var{...} -@end example - -If no keyfile is specified then the password is set to the string specified -by option @option{-p} or is requested interactively from the console. In both -cases the provided password is hashed with the algorithm specified by the -option @option{-h}. This option is mandatory if no keyfile is specified, but -it can be set to @samp{plain} which means that no hashing is done and such -password is used directly as a key. - -Cipher @option{-c} and keysize @option{-s} options specify the cipher algorithm -and the key size respectively and are mandatory options. Cipher must be specified -with the mode separated by a dash (for example, @samp{aes-xts-plain64}). Key size -option @option{-s} is the key size of the cipher in bits, not to be confused with -the offset of the key data in a keyfile specified with the @option{-O} option. It -must not exceed 1024 bits, so a 32 byte key would be specified as 256 bits - -The optional parameter @option{-S} specifies encrypted device sector size. It -must be at least 512 bytes long (default value) and a power of 2. @footnote{Current -implementation of cryptsetup supports only 512/1024/2048/4096 byte sectors}. -Disk sector size is configured when creating the encrypted volume. Attempting -to decrypt volumes with a different sector size than it was created with will -not result in an error, but will decrypt to random bytes and thus prevent -accessing the volume (in some cases the filesystem driver can detect the presence -of a filesystem, but nevertheless will refuse to mount it). - -By default new plainmount devices will be given a UUID starting with -'109fea84-a6b7-34a8-4bd1-1c506305a401' where the last digits are incremented -by one for each plainmounted device beyond the first up to 2^10 devices. - -All encryption arguments (cipher, hash, key size, disk offset and disk sector -size) must match the parameters used to create the volume. If any of them does -not match the actual arguments used during the initial encryption, plainmount -will create virtual device with the garbage data and GRUB will report unknown -filesystem for such device. -@end deffn - - @node play @subsection play -@deffn Command play file | tempo [pitch1 duration1] [pitch2 duration2] @dots{} +@deffn Command play file | tempo [pitch1 duration1] [pitch2 duration2] ... Plays a tune If the argument is a file name (@pxref{File name syntax}), play the tune @@ -7586,48 +1379,7 @@ pitch and duration pairs. If the arguments are a series of numbers, play the inline tune. The tempo is the base for all note durations. 60 gives a 1-second base, 120 -gives a half-second base, etc. Pitches are Hz. Set pitch to 0 to produce -a rest. -@end deffn - - -@node probe -@subsection probe - -@deffn Command probe [@option{--set} var] @option{--driver}|@option{--partmap}|@option{--fs}|@option{--fs-uuid}|@option{--label}|@option{--part-uuid} device -Retrieve device information. If option @option{--set} is given, assign result -to variable @var{var}, otherwise print information on the screen. - -The option @option{--part-uuid} is currently only implemented for MSDOS and GPT formatted disks. -@end deffn - - -@node rdmsr -@subsection rdmsr - -@deffn Command: rdmsr 0xADDR [-v VARNAME] -Read a model-specific register at address 0xADDR. If the parameter -@option{-v} is used and an environment variable @var{VARNAME} is -given, set that environment variable to the value that was read. - -Please note that on SMP systems, reading from a MSR that has a -scope per hardware thread, implies that the value that is returned -only applies to the particular cpu/core/thread that runs the command. - -Also, if you specify a reserved or unimplemented MSR address, it will -cause a general protection exception (which is not currently being handled) -and the system will reboot. -@end deffn - - -@node read -@subsection read - -@deffn Command read [-s] [var] -Read a line of input from the user. If an environment variable @var{var} is -given, set that environment variable to the line of input that was read, -with no terminating newline. If the parameter @option{-s} is used, enable -silent mode where input is not printed to the terminal. +gives a half-second base, etc. Pitches are Hz. @end deffn @@ -7639,536 +1391,12 @@ Reboot the computer. @end deffn -@node regexp -@subsection regexp - -@deffn Command regexp [@option{--set} [number:]var] regexp string -Test if regular expression @var{regexp} matches @var{string}. Supported -regular expressions are POSIX.2 Extended Regular Expressions. If option -@option{--set} is given, store @var{number}th matched subexpression in -variable @var{var}. Subexpressions are numbered in order of their opening -parentheses starting from @samp{1}. @var{number} defaults to @samp{1}. -@end deffn - - -@node rmmod -@subsection rmmod - -@deffn Command rmmod module -Remove a loaded @var{module}. -@end deffn - - -@node save_env -@subsection save_env - -@deffn Command save_env [@option{--file} file] var @dots{} -Save the named variables from the environment to the environment block file. -@xref{Environment block}. - -The @option{--file} option overrides the default location of the environment -block. - -This command will operate successfully even when environment variable -@code{check_signatures} is set to @code{enforce} -(@pxref{check_signatures}), since it writes to disk and does not alter -the behavior of GRUB based on any contents of disk that have been -read. It is possible to modify a digitally signed environment block -file from within GRUB using this command, such that its signature will -no longer be valid on subsequent boots. Care should be taken in such -advanced configurations to avoid rendering the system -unbootable. @xref{Using digital signatures}, for more information. -@end deffn - - -@node search -@subsection search - -@deffn Command search @ - [@option{--file}|@option{--label}|@option{--fs-uuid}] @ - [@option{--set} [var]] [@option{--no-floppy}|@option{--efidisk-only}|@option{--cryptodisk-only}] @ - name -Search devices by file (@option{-f}, @option{--file}), filesystem label -(@option{-l}, @option{--label}), or filesystem UUID (@option{-u}, -@option{--fs-uuid}). - -If the (@option{-s}, @option{--set}) option is used, the first device found is -set as the value of environment variable @var{var}. The default variable is -@samp{root}. - -The (@option{-n}, @option{--no-floppy}) option prevents searching floppy -devices, which can be slow. - -The (@option{--efidisk-only}) option prevents searching any other devices then -EFI disks. This is typically used when chainloading to local EFI partition. - -The (@option{--cryptodisk-only}) option prevents searching any devices other -than encrypted disks. This is typically used when booting from an encrypted -file system to ensure that no code gets executed from an unencrypted device -having the same filesystem UUID or label. - -This option implicitly invokes the command @command{cryptocheck}, if it is -available (@pxref{cryptocheck} for additional information). - -The @samp{search.file}, @samp{search.fs_label}, and @samp{search.fs_uuid} -commands are aliases for @samp{search --file}, @samp{search --label}, and -@samp{search --fs-uuid} respectively. - -Also hints as to which device may be the most likely to contain the item -searched for may be given via the (@option{-h}, @option{--hint}) option with -a device name as an argument. If the argument ends with a comma, then partitions -on the device are also searched. Furthermore, platform specific hints may be -given via the options @option{--hint-ieee1275}, @option{--hint-bios}, -@option{--hint-baremetal}, @option{--hint-efi}, and @option{--hint-arc}. When -specified, these options take an argument and operate like @option{--hint}, but -only on the specified platform. -@end deffn - - -@node sendkey -@subsection sendkey - -@deffn Command sendkey @ - [@option{--num}|@option{--caps}|@option{--scroll}|@option{--insert}|@ -@option{--pause}|@option{--left-shift}|@option{--right-shift}|@ -@option{--sysrq}|@option{--numkey}|@option{--capskey}|@option{--scrollkey}|@ -@option{--insertkey}|@option{--left-alt}|@option{--right-alt}|@ -@option{--left-ctrl}|@option{--right-ctrl} @ - @samp{on}|@samp{off}]@dots{} @ - [@option{no-led}] @ - keystroke -Insert keystrokes into the keyboard buffer when booting. Sometimes an -operating system or chainloaded boot loader requires particular keys to be -pressed: for example, one might need to press a particular key to enter -"safe mode", or when chainloading another boot loader one might send -keystrokes to it to navigate its menu. - -Note: This command is currently only available on the i386-pc target. - -You may provide up to 16 keystrokes (the length of the BIOS keyboard -buffer). Keystroke names may be upper-case or lower-case letters, digits, -or taken from the following table: - -@c Please keep this table in the same order as in -@c commands/i386/pc/sendkey.c, for ease of maintenance. -@c Exception: The function and numeric keys are sorted, for aesthetics. - -@multitable @columnfractions .4 .5 -@headitem Name @tab Key -@item escape @tab Escape -@item exclam @tab ! -@item at @tab @@ -@item numbersign @tab # -@item dollar @tab $ -@item percent @tab % -@item caret @tab ^ -@item ampersand @tab & -@item asterisk @tab * -@item parenleft @tab ( -@item parenright @tab ) -@item minus @tab - -@item underscore @tab _ -@item equal @tab = -@item plus @tab + -@item backspace @tab Backspace -@item tab @tab Tab -@item bracketleft @tab [ -@item braceleft @tab @{ -@item bracketright @tab ] -@item braceright @tab @} -@item enter @tab Enter -@item control @tab press and release Control -@item semicolon @tab ; -@item colon @tab : -@item quote @tab ' -@item doublequote @tab " -@item backquote @tab ` -@item tilde @tab ~ -@item shift @tab press and release left Shift -@item backslash @tab \ -@item bar @tab | -@item comma @tab , -@item less @tab < -@item period @tab . -@item greater @tab > -@item slash @tab / -@item question @tab ? -@item rshift @tab press and release right Shift -@item alt @tab press and release Alt -@item space @tab space bar -@item capslock @tab Caps Lock -@item F1 @tab F1 -@item F2 @tab F2 -@item F3 @tab F3 -@item F4 @tab F4 -@item F5 @tab F5 -@item F6 @tab F6 -@item F7 @tab F7 -@item F8 @tab F8 -@item F9 @tab F9 -@item F10 @tab F10 -@item F11 @tab F11 -@item F12 @tab F12 -@item num1 @tab 1 (numeric keypad) -@item num2 @tab 2 (numeric keypad) -@item num3 @tab 3 (numeric keypad) -@item num4 @tab 4 (numeric keypad) -@item num5 @tab 5 (numeric keypad) -@item num6 @tab 6 (numeric keypad) -@item num7 @tab 7 (numeric keypad) -@item num8 @tab 8 (numeric keypad) -@item num9 @tab 9 (numeric keypad) -@item num0 @tab 0 (numeric keypad) -@item numperiod @tab . (numeric keypad) -@item numend @tab End (numeric keypad) -@item numdown @tab Down (numeric keypad) -@item numpgdown @tab Page Down (numeric keypad) -@item numleft @tab Left (numeric keypad) -@item numcenter @tab 5 with Num Lock inactive (numeric keypad) -@item numright @tab Right (numeric keypad) -@item numhome @tab Home (numeric keypad) -@item numup @tab Up (numeric keypad) -@item numpgup @tab Page Up (numeric keypad) -@item numinsert @tab Insert (numeric keypad) -@item numdelete @tab Delete (numeric keypad) -@item numasterisk @tab * (numeric keypad) -@item numminus @tab - (numeric keypad) -@item numplus @tab + (numeric keypad) -@item numslash @tab / (numeric keypad) -@item numenter @tab Enter (numeric keypad) -@item delete @tab Delete -@item insert @tab Insert -@item home @tab Home -@item end @tab End -@item pgdown @tab Page Down -@item pgup @tab Page Up -@item down @tab Down -@item up @tab Up -@item left @tab Left -@item right @tab Right -@end multitable - -As well as keystrokes, the @command{sendkey} command takes various options -that affect the BIOS keyboard status flags. These options take an @samp{on} -or @samp{off} parameter, specifying that the corresponding status flag be -set or unset; omitting the option for a given status flag will leave that -flag at its initial state at boot. The @option{--num}, @option{--caps}, -@option{--scroll}, and @option{--insert} options emulate setting the -corresponding mode, while the @option{--numkey}, @option{--capskey}, -@option{--scrollkey}, and @option{--insertkey} options emulate pressing and -holding the corresponding key. The other status flag options are -self-explanatory. - -If the @option{--no-led} option is given, the status flag options will have -no effect on keyboard LEDs. - -If the @command{sendkey} command is given multiple times, then only the last -invocation has any effect. - -Since @command{sendkey} manipulates the BIOS keyboard buffer, it may cause -hangs, reboots, or other misbehaviour on some systems. If the operating -system or boot loader that runs after GRUB uses its own keyboard driver -rather than the BIOS keyboard functions, then @command{sendkey} will have no -effect. - -This command is only available on PC BIOS systems. -@end deffn - - @node set @subsection set @deffn Command set [envvar=value] Set the environment variable @var{envvar} to @var{value}. If invoked with no -arguments, print all environment variables with their values. For the list of -environment variables currently used by GRUB itself see the relevant section -@pxref{Environment}. -@end deffn - - -@node sha1sum -@subsection sha1sum - -@deffn Command sha1sum arg @dots{} -Alias for @code{hashsum --hash sha1 arg @dots{}}. See command @command{hashsum} -(@pxref{hashsum}) for full description. -@end deffn - - -@node sha256sum -@subsection sha256sum - -@deffn Command sha256sum arg @dots{} -Alias for @code{hashsum --hash sha256 arg @dots{}}. See command @command{hashsum} -(@pxref{hashsum}) for full description. -@end deffn - - -@node sha512sum -@subsection sha512sum - -@deffn Command sha512sum arg @dots{} -Alias for @code{hashsum --hash sha512 arg @dots{}}. See command @command{hashsum} -(@pxref{hashsum}) for full description. -@end deffn - - -@node sleep -@subsection sleep - -@deffn Command sleep [@option{--verbose}] [@option{--interruptible}] count -Sleep for @var{count} seconds. If option @option{--interruptible} is given, -allow pressing @key{ESC}, @key{F4} or holding down @key{SHIFT} to interrupt -sleep. With @option{--verbose} show countdown of remaining seconds. Exit code -is set to 0 if timeout expired and to 1 if timeout was interrupted using any -of the mentioned keys. -@end deffn - - -@node smbios -@subsection smbios - -@deffn Command smbios @ - [@option{--type} @var{type}] @ - [@option{--handle} @var{handle}] @ - [@option{--match} @var{match}] @ - (@option{--get-byte} | @option{--get-word} | @option{--get-dword} | @ - @option{--get-qword} | @option{--get-string} | @option{--get-uuid}) @ - @var{offset} @ - [@option{--set} @var{variable}] -Retrieve SMBIOS information. - -The @command{smbios} command returns the value of a field in an SMBIOS -structure. The following options determine which structure to select. - -@itemize @bullet -@item -Specifying @option{--type} will select structures with a matching -@var{type}. The type can be any integer from 0 to 255. -@item -Specifying @option{--handle} will select structures with a matching -@var{handle}. The handle can be any integer from 0 to 65535. -@item -Specifying @option{--match} will select structure number @var{match} in the -filtered list of structures; e.g. @code{smbios --type 4 --match 2} will select -the second Process Information (Type 4) structure. The list is always ordered -the same as the hardware's SMBIOS table. The match number must be a positive -integer. If unspecified, the first matching structure will be selected. -@end itemize - -The remaining options determine which field in the selected SMBIOS structure to -return. Only one of these options may be specified at a time. - -@itemize @bullet -@item -When given @option{--get-byte}, return the value of the byte -at @var{offset} bytes into the selected SMBIOS structure. -It will be formatted as an unsigned decimal integer. -@item -When given @option{--get-word}, return the value of the word (two bytes) -at @var{offset} bytes into the selected SMBIOS structure. -It will be formatted as an unsigned decimal integer. -@item -When given @option{--get-dword}, return the value of the dword (four bytes) -at @var{offset} bytes into the selected SMBIOS structure. -It will be formatted as an unsigned decimal integer. -@item -When given @option{--get-qword}, return the value of the qword (eight bytes) -at @var{offset} bytes into the selected SMBIOS structure. -It will be formatted as an unsigned decimal integer. -@item -When given @option{--get-string}, return the string with its index found -at @var{offset} bytes into the selected SMBIOS structure. -@item -When given @option{--get-uuid}, return the value of the UUID (sixteen bytes) -at @var{offset} bytes into the selected SMBIOS structure. -It will be formatted as lower-case hyphenated hexadecimal digits, with the -first three fields as little-endian, and the rest printed byte-by-byte. -@end itemize - -The default action is to print the value of the requested field to the console, -but a variable name can be specified with @option{--set} to store the value -instead of printing it. - -For example, this will store and then display the system manufacturer's name. - -@example -smbios --type 1 --get-string 4 --set system_manufacturer -echo $system_manufacturer -@end example -@end deffn - - -@node source -@subsection source - -@deffn Command source file -Read @var{file} as a configuration file, as if its contents had been -incorporated directly into the sourcing file. Unlike @command{configfile} -(@pxref{configfile}), this executes the contents of @var{file} without -changing context: any environment variable changes made by the commands in -@var{file} will be preserved after @command{source} returns, and the menu -will not be shown immediately. -@end deffn - - -@node test -@subsection test - -@deffn Command test expression -Evaluate @var{expression} and return zero exit status if result is true, -non zero status otherwise. - -@var{expression} is one of: - -@table @asis -@item @var{string1} @code{==} @var{string2} -the strings are equal -@item @var{string1} @code{!=} @var{string2} -the strings are not equal -@item @var{string1} @code{<} @var{string2} -@var{string1} is lexicographically less than @var{string2} -@item @var{string1} @code{<=} @var{string2} -@var{string1} is lexicographically less or equal than @var{string2} -@item @var{string1} @code{>} @var{string2} -@var{string1} is lexicographically greater than @var{string2} -@item @var{string1} @code{>=} @var{string2} -@var{string1} is lexicographically greater or equal than @var{string2} -@item @var{integer1} @code{-eq} @var{integer2} -@var{integer1} is equal to @var{integer2} -@item @var{integer1} @code{-ge} @var{integer2} -@var{integer1} is greater than or equal to @var{integer2} -@item @var{integer1} @code{-gt} @var{integer2} -@var{integer1} is greater than @var{integer2} -@item @var{integer1} @code{-le} @var{integer2} -@var{integer1} is less than or equal to @var{integer2} -@item @var{integer1} @code{-lt} @var{integer2} -@var{integer1} is less than @var{integer2} -@item @var{integer1} @code{-ne} @var{integer2} -@var{integer1} is not equal to @var{integer2} -@item @var{prefix}@var{integer1} @code{-pgt} @var{prefix}@var{integer2} -@var{integer1} is greater than @var{integer2} after stripping off common non-numeric @var{prefix}. -@item @var{prefix}@var{integer1} @code{-plt} @var{prefix}@var{integer2} -@var{integer1} is less than @var{integer2} after stripping off common non-numeric @var{prefix}. -@item @var{file1} @code{-nt} @var{file2} -@var{file1} is newer than @var{file2} (modification time). Optionally numeric @var{bias} may be directly appended to @code{-nt} in which case it is added to the first file modification time. -@item @var{file1} @code{-ot} @var{file2} -@var{file1} is older than @var{file2} (modification time). Optionally numeric @var{bias} may be directly appended to @code{-ot} in which case it is added to the first file modification time. -@item @code{-d} @var{file} -@var{file} exists and is a directory -@item @code{-e} @var{file} -@var{file} exists -@item @code{-f} @var{file} -@var{file} exists and is not a directory -@item @code{-s} @var{file} -@var{file} exists and has a size greater than zero -@item @code{-n} @var{string} -the length of @var{string} is nonzero -@item @var{string} -@var{string} is equivalent to @code{-n @var{string}} -@item @code{-z} @var{string} -the length of @var{string} is zero -@item @code{(} @var{expression} @code{)} -@var{expression} is true -@item @code{!} @var{expression} -@var{expression} is false -@item @var{expression1} @code{-a} @var{expression2} -both @var{expression1} and @var{expression2} are true -@item @var{expression1} @var{expression2} -both @var{expression1} and @var{expression2} are true. This syntax is not POSIX-compliant and is not recommended. -@item @var{expression1} @code{-o} @var{expression2} -either @var{expression1} or @var{expression2} is true -@end table -@end deffn - -@node tpm2_key_protector_init -@subsection tpm2_key_protector_init - -@deffn Command tpm2_key_protector_init [@option{--mode} | @option{-m} mode] | [@option{--pcrs} | @option{-p} pcrlist] | [@option{--bank} | @option{-b} pcrbank] | [ [@option{--tpm2key} | @option{-T} tpm2key_file] | [@option{--keyfile} | @option{-k} keyfile] ] | [@option{--srk} | @option{-s} handle] | [@option{--asymmetric} | @option{-a} srk_type] | [@option{--nvindex} | @option{-n} nv_index] -Initialize the TPM2 key protector to unseal the key for the @command{cryptomount} -(@pxref{cryptomount}) command. There are two supported modes, -SRK(@kbd{srk}) and NV index(@kbd{nv}), to be specified by the option -@option{-m}. The default mode is SRK. The main difference between SRK mode -and NV index mode is the storage of the sealed key. For SRK mode, the sealed -key is stored in a file while NV index mode stores the sealed key in the -non-volatile memory inside TPM with a given NV index. - -The @option{-p} and @option{-b} options are used to supply the PCR list and -bank that the key is sealed with. The PCR list is a comma-separated list, e.g., -'0,2,4,7,9', to represent the involved PCRs, and the default is '7'. The PCR -bank is chosen by selecting a hash algorithm. The current supported PCR banks -are SHA1, SHA256, SHA384, and SHA512, and the default is SHA256. - -Some options are only available for the specific mode. The SRK-specific -options are @option{-T}, @option{-k}, @option{-a}, and @option{-s}. On the -other hand, the NV index-specific option is @option{-n}. - -The key file for SRK mode can be supplied with either @option{-T} or -@option{-k}. Those two options were used to distinguish the file formats but -are same now. There are two supported file formats: raw format and TPM 2.0 -Key File format. When using the key file in the raw format, the @option{-p} -and @option{-b} options are necessary for the non-default PCR list or bank. -On the other hand, when using the key file in TPM 2.0 Key File format, the -the parameters for the TPM commands are written in the file, and there is no -need to set the PCR list(@option{-p}) and bank(@option{-b}). In general, -TPM 2.0 Key File format is preferred due to the simplified GRUB command -options and the authorized policy support - -Besides the key file, there are two options, @option{-a} and @option{-s}, to -tweak the TPM Storage Root Key (SRK). The SRK can be either created at -runtime or stored in the non-volatile memory. When creating SRK at runtime, -GRUB provides the SRK template to the TPM to create the key. There are two SRK -templates for the @option{-a} option, ECC and RSA, and the default is ECC. -If the SRK is stored in a specific handle, e.g. @code{0x81000001}, the -@option{-s} option can be used to set the handle to notify GRUB to load -the SRK from the given handle. - -The only NV index-specific option is the @option{-n} option which is used to -set the NV index containing the sealed key. Then GRUB can load the sealed -key and unseal it with the given PCR list and bank. -@end deffn - -@node tpm2_key_protector_clear -@subsection tpm2_key_protector_clear - -@deffn Command tpm2_key_protector_clear -Clear the TPM2 key protector if previously initialized. -@end deffn - -@node tpm2_dump_pcr -@subsection tpm2_dump_pcr - -@deffn Command tpm2_dump_pcr [@var{bank}] -Print all PCRs of the specified TPM 2.0 @var{bank}. The supported banks are -@samp{sha1}, @samp{sha256}, @samp{sha384}, and @samp{sha512}. If @var{bank} -is not specified, @samp{sha256} is chosen by default. - -Since GRUB measures every command into PCR 8, invoking @command{tpm2_dump_pcr} -also extends PCR 8, so PCR 8 will not be a stable value in GRUB shell. -@end deffn - -@node true -@subsection true - -@deffn Command true -Do nothing, successfully. This is mainly useful in control constructs such -as @code{if} and @code{while} (@pxref{Shell-like scripting}). -@end deffn - -@node trust -@subsection trust - -@deffn Command trust [@option{--skip-sig}] pubkey_file -Read public key from @var{pubkey_file} and add it to GRUB's internal -list of trusted public keys. These keys are used to validate digital -signatures when environment variable @code{check_signatures} is set to -@code{enforce}. Note that if @code{check_signatures} is set to -@code{enforce} when @command{trust} executes, then @var{pubkey_file} -must itself be properly signed. The @option{--skip-sig} option can be -used to disable signature-checking when reading @var{pubkey_file} -itself. It is expected that @option{--skip-sig} is useful for testing -and manual booting. @xref{Using digital signatures}, for more -information. +arguments, print all environment variables with their values. @end deffn @@ -8180,1640 +1408,11 @@ Unset the environment variable @var{envvar}. @end deffn -@ignore -@node vbeinfo -@subsection vbeinfo - -@deffn Command vbeinfo [[WxH]xD] -Alias for command @command{videoinfo} (@pxref{videoinfo}). It is available -only on PC BIOS platforms. -@end deffn -@end ignore - - -@node verify_detached -@subsection verify_detached - -@deffn Command verify_detached [@option{--skip-sig}] file signature_file [pubkey_file] -Verifies a GPG-style detached signature, where the signed file is -@var{file}, and the signature itself is in file @var{signature_file}. -Optionally, a specific public key to use can be specified using -@var{pubkey_file}. When environment variable @code{check_signatures} -is set to @code{enforce}, then @var{pubkey_file} must itself be -properly signed by an already-trusted key. An unsigned -@var{pubkey_file} can be loaded by specifying @option{--skip-sig}. -If @var{pubkey_file} is omitted, then public keys from GRUB's trusted keys -(@pxref{list_trusted}, @pxref{trust}, and @pxref{distrust}) are -tried. - -Exit code @code{$?} is set to 0 if the signature validates -successfully. If validation fails, it is set to a non-zero value. -@xref{Using digital signatures}, for more information. -@end deffn - -@node videoinfo -@subsection videoinfo - -@deffn Command videoinfo [[WxH]xD] -List available video modes. If resolution is given, show only matching modes. -@end deffn - -@node wrmsr -@subsection wrmsr - -@deffn Command: wrmsr 0xADDR 0xVALUE -Write a 0xVALUE to a model-specific register at address 0xADDR. - -Please note that on SMP systems, writing to a MSR that has a scope -per hardware thread, implies that the value that is written -only applies to the particular cpu/core/thread that runs the command. - -Also, if you specify a reserved or unimplemented MSR address, it will -cause a general protection exception (which is not currently being handled) -and the system will reboot. - -Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). - This is done to prevent subverting various security mechanisms. -@end deffn - -@node Networking commands -@section Networking commands - -@menu -* net_add_addr:: Add a network address -* net_add_dns:: Add a DNS server -* net_add_route:: Add routing entry -* net_bootp:: Perform a bootp/DHCP autoconfiguration -* net_del_addr:: Remove IP address from interface -* net_del_dns:: Remove a DNS server -* net_del_route:: Remove a route entry -* net_dhcp:: Perform a DHCP autoconfiguration -* net_get_dhcp_option:: Retrieve DHCP options -* net_ipv6_autoconf:: Perform IPv6 autoconfiguration -* net_ls_addr:: List interfaces -* net_ls_cards:: List network cards -* net_ls_dns:: List DNS servers -* net_ls_routes:: List routing entries -* net_nslookup:: Perform a DNS lookup -* net_set_vlan:: Set vlan id on an interface -@end menu - - -@node net_add_addr -@subsection net_add_addr - -@deffn Command net_add_addr @var{interface} @var{card} @var{address} -Configure additional network @var{interface} with @var{address} on a -network @var{card}. @var{address} can be either IP in dotted decimal notation, -or symbolic name which is resolved using DNS lookup. If successful, this command -also adds local link routing entry to the default subnet of @var{address} -with name @var{interface}@samp{:local} via @var{interface}. -@end deffn - - -@node net_add_dns -@subsection net_add_dns - -@deffn Command net_add_dns @var{server} -Resolve @var{server} IP address and add to the list of DNS servers used during -name lookup. -@end deffn - - -@node net_add_route -@subsection net_add_route - -@deffn Command net_add_route @var{shortname} @var{ip}[/@var{prefix}] [@var{interface} | @samp{gw} @var{gateway}] -Add route to network with address @var{ip} as modified by @var{prefix} via -either local @var{interface} or @var{gateway}. @var{prefix} is optional and -defaults to 32 for IPv4 address and 128 for IPv6 address. Route is identified -by @var{shortname} which can be used to remove it (@pxref{net_del_route}). -@end deffn - - -@node net_bootp -@subsection net_bootp - -@deffn Command net_bootp [@var{card}] -Alias for net_dhcp, for compatibility with older Grub versions. Will perform -the same DHCP handshake with potential fallback to BOOTP as the net_dhcp -command (@pxref{net_dhcp}). - -@end deffn - - -@node net_del_addr -@subsection net_del_addr - -@deffn Command net_del_addr @var{interface} -Remove configured @var{interface} with associated address. -@end deffn - - -@node net_del_dns -@subsection net_del_dns - -@deffn Command net_del_dns @var{address} -Remove @var{address} from list of servers used during name lookup. -@end deffn - - -@node net_del_route -@subsection net_del_route - -@deffn Command net_del_route @var{shortname} -Remove route entry identified by @var{shortname}. -@end deffn - - -@node net_dhcp -@subsection net_dhcp - -@deffn Command net_dhcp [@var{card}] -Perform configuration of @var{card} using DHCP protocol. If no card name -is specified, try to configure all existing cards. -Falls back to the BOOTP protocol, if needed. If configuration was -successful, interface with name @var{card}@samp{:dhcp} and configured -address is added to @var{card}. -@comment If server provided gateway information in -@comment DHCP ACK packet, it is added as route entry with the name @var{card}@samp{:dhcp:gw}. -Additionally the following DHCP options are recognized and processed: - -@table @samp -@item 1 (Subnet Mask) -Used to calculate network local routing entry for interface @var{card}@samp{:dhcp}. -@item 3 (Router) -Adds default route entry with the name @var{card}@samp{:dhcp:default} via gateway -from DHCP option. Note that only option with single route is accepted. -@item 6 (Domain Name Server) -Adds all servers from option value to the list of servers used during name resolution. -@item 12 (Host Name) -Sets environment variable @samp{net_}@var{}@samp{_dhcp_hostname} -(@pxref{net_@var{}_hostname}) to the value of option. -@item 15 (Domain Name) -Sets environment variable @samp{net_}@var{}@samp{_dhcp_domain} -(@pxref{net_@var{}_domain}) to the value of option. -@item 17 (Root Path) -Sets environment variable @samp{net_}@var{}@samp{_dhcp_rootpath} -(@pxref{net_@var{}_rootpath}) to the value of option. -@item 18 (Extensions Path) -Sets environment variable @samp{net_}@var{}@samp{_dhcp_extensionspath} -(@pxref{net_@var{}_extensionspath}) to the value of option. -@item 66 (TFTP Server Name) -Sets environment variable @samp{net_}@var{}@samp{_dhcp_server_name} -(@pxref{net_@var{}_dhcp_server_name}) to the value of option. -@item 67 (Filename) -Sets environment variable @samp{net_}@var{}@samp{_boot_file} -(@pxref{net_@var{}_boot_file}) to the value of option. -@end table - -@end deffn - - -@node net_get_dhcp_option -@subsection net_get_dhcp_option - -@deffn Command net_get_dhcp_option @var{var} @var{interface} @var{number} @var{type} -Request DHCP option @var{number} of @var{type} via @var{interface}. @var{type} -can be one of @samp{string}, @samp{number} or @samp{hex}. If option is found, -assign its value to variable @var{var}. Values of types @samp{number} and @samp{hex} -are converted to string representation. -@end deffn - - -@node net_ipv6_autoconf -@subsection net_ipv6_autoconf - -@deffn Command net_ipv6_autoconf [@var{card}] -Perform IPv6 autoconfiguration by adding to the @var{card} interface with name -@var{card}@samp{:link} and link local MAC-based address. If no card is specified, -perform autoconfiguration for all existing cards. -@end deffn - - -@node net_ls_addr -@subsection net_ls_addr - -@deffn Command net_ls_addr -List all configured interfaces with their MAC and IP addresses. -@end deffn - - -@node net_ls_cards -@subsection net_ls_cards - -@deffn Command net_ls_cards -List all detected network cards with their MAC address. -@end deffn - - -@node net_ls_dns -@subsection net_ls_dns - -@deffn Command net_ls_dns -List addresses of DNS servers used during name lookup. -@end deffn - - -@node net_ls_routes -@subsection net_ls_routes - -@deffn Command net_ls_routes -List routing entries. -@end deffn - - -@node net_nslookup -@subsection net_nslookup - -@deffn Command net_nslookup @var{name} [@var{server}] -Resolve address of @var{name} using DNS server @var{server}. If no server -is given, use default list of servers. -@end deffn - - -@node net_set_vlan -@subsection net_set_vlan - -@deffn Command net_set_vlan @var{interface} @var{vlanid} -Set the 802.1Q VLAN identifier on @var{interface} to @var{vlanid}. For example, -to set the VLAN identifier on interface @samp{efinet1} to @samp{100}: - -@example -net_set_vlan efinet1 100 -@end example - -The VLAN identifier can be removed by setting it to @samp{0}: - -@example -net_set_vlan efinet1 0 -@end example -@end deffn - - -@node Undocumented commands -@section Commands currently undocumented -Unfortunately, not all GRUB commands are documented at this time due to -developer resource constraints. One way to contribute back to the GRUB -project would be to help document these commands, and submit patches or -ideas to the mailing list. The following is a (most likely incomplete) -list of undocumented or poorly documented commands and not all of them -are allowed for all platforms. Running the command help from within the -GRUB shell may provide more information on parameters and usage. - -@itemize @bullet -@item @command{all_functional_test} - Run all functional tests. -@item @command{backtrace} - Print backtrace. -@item @command{boottime} - Show boot time statistics. -@item @command{cacheinfo} - Get disk cache info. -@item @command{cbmemc} - Show CBMEM console content. -@item @command{cmosset} - Set bit at BYTE:BIT in CMOS. -@item @command{coreboot_boottime} - Show coreboot boot time statistics. -@item @command{dump} - Show memory contents. -@item @command{efiemu_loadcore} - Load and initialize EFI emulator. -@item @command{efiemu_prepare} - Finalize loading of EFI emulator. -@item @command{efiemu_unload} - Unload EFI emulator. -@item @command{exit} - Exit from GRUB. -@item @command{extract_entries_configfile} - Load another config file but take only menu entries. -@item @command{extract_entries_source} - Load another config file without changing context but take only menu entries. -@item @command{extract_legacy_entries_configfile} - Parse legacy config in new context taking only menu entries -@item @command{extract_legacy_entries_source} - Parse legacy config in same context taking only menu entries -@item @command{extract_syslinux_entries_configfile} - Execute syslinux config in new context taking only menu entries -@item @command{extract_syslinux_entries_source} - Execute syslinux config in same context taking only menu entries -@item @command{fakebios} - Create BIOS-like structures for backward compatibility with existing OS. -@item @command{fix_video} - Fix video problem. -@item @command{fpswa} - Display FPSWA version. -@item @command{functional_test} - Run all loaded functional tests. -@item @command{gdbstub_break} - Break into GDB -@item @command{gdbstub} - Start GDB stub on given port -@item @command{gdbstub_stop} - Stop GDB stub -@item @command{hdparm} - Get/set ATA disk parameters. -@item @command{hexdump_random} - Hexdump random data. -@item @command{inb} - Read 8-bit value from PORT. -@item @command{inl} - Read 32-bit value from PORT. -@item @command{inw} - Read 16-bit value from PORT. -@item @command{jpegtest} - Tests loading of JPEG bitmap. -@item @command{keymap} - Load a keyboard layout. -@item @command{legacy_check_password} - Simulate grub-legacy `password' command in menu entry mode -@item @command{legacy_configfile} - Parse legacy config in new context -@item @command{legacy_password} - Simulate grub-legacy `password' command -@item @command{legacy_source} - Parse legacy config in same context -@item @command{loadbios} - Load BIOS dump. -@item @command{lsacpi} - Show ACPI information. -@item @command{lsapm} - Show APM information. -@item @command{lscoreboot} - List coreboot tables. -@item @command{lsdev} - List devices. -@item @command{lsefi} - Display EFI handles. -@item @command{lsefimmap} - Display EFI memory map. -@item @command{lsefisystab} - Display EFI system tables. -@item @command{lsmmap} - List memory map provided by firmware. -@item @command{lspci} - List PCI devices. -@item @command{lssal} - Display SAL system table. -@item @command{lsspd} - Print Memory information. -@item @command{macppcbless} - Bless DIR of HFS or HFS+ partition for PPC macs. -@item @command{mactelbless} - Bless FILE of HFS or HFS+ partition for intel macs. -@item @command{net_set_vlan} - Set an interface's vlan id. -@item @command{outb} - Write 8-bit VALUE to PORT. -@item @command{outl} - Write 32-bit VALUE to PORT. -@item @command{outw} - Write 16-bit VALUE to PORT. -@item @command{pcidump} - Show raw dump of the PCI configuration space. -@item @command{pngtest} - Tests loading of PNG bitmap. -@item @command{read_byte} - Read 8-bit value from ADDR. -@item @command{read_dword} - Read 32-bit value from ADDR. -@item @command{read_word} - Read 16-bit value from ADDR. -@item @command{setpci} - Manipulate PCI devices. -@item @command{suspend} - Return to IEEE1275 prompt. -@item @command{syslinux_configfile} - Execute syslinux config in new context -@item @command{syslinux_source} - Execute syslinux config in same context -@item @command{test_blockarg} - Print and execute block argument., 0 -@item @command{testload} - Load the same file in multiple ways. -@item @command{testspeed} - Test file read speed. -@item @command{tgatest} - Tests loading of TGA bitmap. -@item @command{time} - Measure time used by COMMAND -@item @command{tr} - Translate SET1 characters to SET2 in STRING. -@item @command{usb} - Test USB support. -@item @command{vbeinfo} - List available video modes. If resolution is given show only modes matching it. -@item @command{vbetest} - Test video subsystem. -@item @command{videotest} - Test video subsystem in mode WxH. -@item @command{write_byte} - Write 8-bit VALUE to ADDR. -@item @command{write_dword} - Write 32-bit VALUE to ADDR. -@item @command{write_word} - Write 16-bit VALUE to ADDR. -@item @command{xen_cat} - List Xen storage. -@item @command{xen_ls} - List Xen storage. -@item @command{xnu_devprop_load} - Load `device-properties' dump. -@item @command{xnu_uuid} - Transform 64-bit UUID to format suitable for XNU. If -l is given keep it lowercase as done by blkid. -@item @command{zfs-bootfs} - Print ZFS-BOOTFSOBJ or store it into VARIABLE -@item @command{zfsinfo} - Print ZFS info about DEVICE. -@item @command{zfskey} - Import ZFS wrapping key stored in FILE. -@end itemize - - -@node Internationalisation -@chapter Internationalisation - -@section Charset -GRUB uses UTF-8 internally other than in rendering where some GRUB-specific -appropriate representation is used. All text files (including config) are -assumed to be encoded in UTF-8. - -@section Filesystems -NTFS, JFS, UDF, HFS+, exFAT, long filenames in FAT, Joliet part of -ISO9660 are treated as UTF-16 as per specification. AFS and BFS are read -as UTF-8, again according to specification. BtrFS, cpio, tar, squash4, minix, -minix2, minix3, ROMFS, ReiserFS, XFS, EROFS, ext2, ext3, ext4, FAT (short names), -F2FS, RockRidge part of ISO9660, nilfs2, UFS1, UFS2 and ZFS are assumed -to be UTF-8. This might be false on systems configured with legacy charset -but as long as the charset used is superset of ASCII you should be able to -access ASCII-named files. And it's recommended to configure your system to use -UTF-8 to access the filesystem, convmv may help with migration. ISO9660 (plain) -filenames are specified as being ASCII or being described with unspecified -escape sequences. GRUB assumes that the ISO9660 names are UTF-8 (since -any ASCII is valid UTF-8). There are some old CD-ROMs which use CP437 -in non-compliant way. You're still able to access files with names containing -only ASCII characters on such filesystems though. You're also able to access -any file if the filesystem contains valid Joliet (UTF-16) or RockRidge (UTF-8). -AFFS, SFS and HFS never use unicode and GRUB assumes them to be in Latin1, -Latin1 and MacRoman respectively. GRUB handles filesystem case-insensitivity -however no attempt is performed at case conversion of international characters -so e.g. a file named lowercase greek alpha is treated as different from -the one named as uppercase alpha. The filesystems in questions are -NTFS (except POSIX namespace), HFS+ (configurable at mkfs time, default -insensitive), SFS (configurable at mkfs time, default insensitive), -JFS (configurable at mkfs time, default sensitive), HFS, AFFS, FAT, exFAT -and ZFS (configurable on per-subvolume basis by property ``casesensitivity'', -default sensitive). On ZFS subvolumes marked as case insensitive files -containing lowercase international characters are inaccessible. -Also like all supported filesystems except HFS+ and ZFS (configurable on -per-subvolume basis by property ``normalization'', default none) GRUB makes -no attempt at check of canonical equivalence so a file name u-diaresis is -treated as distinct from u+combining diaresis. This however means that in -order to access file on HFS+ its name must be specified in normalisation form D. -On normalized ZFS subvolumes filenames out of normalisation are inaccessible. - -@section Output terminal -Firmware output console ``console'' on ARC and IEEE1275 are limited to ASCII. - -BIOS firmware console and VGA text are limited to ASCII and some pseudographics. - -None of above mentioned is appropriate for displaying international and any -unsupported character is replaced with question mark except pseudographics -which we attempt to approximate with ASCII. - -EFI console on the other hand nominally supports UTF-16 but actual language -coverage depends on firmware and may be very limited. - -The encoding used on serial can be chosen with @command{terminfo} as -either ASCII, UTF-8 or ``visual UTF-8''. Last one is against the specification -but results in correct rendering of right-to-left on some readers which don't -have own bidi implementation. - -On emu GRUB checks if charset is UTF-8 and uses it if so and uses ASCII -otherwise. - -When using gfxterm or gfxmenu GRUB itself is responsible for rendering the -text. In this case GRUB is limited by loaded fonts. If fonts contain all -required characters then bidirectional text, cursive variants and combining -marks other than enclosing, half (e.g. left half tilde or combining overline) -and double ones. Ligatures aren't supported though. This should cover European, -Middle Eastern (if you don't mind lack of lam-alif ligature in Arabic) and -East Asian scripts. Notable unsupported scripts are Brahmic family and -derived as well as Mongolian, Tifinagh, Korean Jamo (precomposed characters -have no problem) and tonal writing (2e5-2e9). GRUB also ignores deprecated -(as specified in Unicode) characters (e.g. tags). GRUB also doesn't handle so -called ``annotation characters'' If you can complete either of -two lists or, better, propose a patch to improve rendering, please contact -developer team. - -@section Input terminal -Firmware console on BIOS, IEEE1275 and ARC doesn't allow you to enter non-ASCII -characters. EFI specification allows for such but author is unaware of any -actual implementations. Serial input is currently limited for latin1 (unlikely -to change). Own keyboard implementations (at_keyboard and usb_keyboard) -supports any key but work on one-char-per-keystroke. -So no dead keys or advanced input method. Also there is no keymap change hotkey. -In practice it makes difficult to enter any text using non-Latin alphabet. -Moreover all current input consumers are limited to ASCII. - -@section Gettext -GRUB supports being translated. For this you need to have language *.mo files in $prefix/locale, load gettext module and set ``lang'' variable. - -@section Regexp -Regexps work on unicode characters, however no attempt at checking canonical -equivalence has been made. Moreover the classes like [:alpha:] match only -ASCII subset. - -@section Other -Currently GRUB always uses YEAR-MONTH-DAY HOUR:MINUTE:SECOND [WEEKDAY] 24-hour -datetime format but weekdays are translated. -GRUB always uses the decimal number format with [0-9] as digits and . as -descimal separator and no group separator. -IEEE1275 aliases are matched case-insensitively except non-ASCII which is -matched as binary. Similar behaviour is for matching OSBundleRequired. -Since IEEE1275 aliases and OSBundleRequired don't contain any non-ASCII it -should never be a problem in practice. -Case-sensitive identifiers are matched as raw strings, no canonical -equivalence check is performed. Case-insensitive identifiers are matched -as RAW but additionally [a-z] is equivalent to [A-Z]. GRUB-defined -identifiers use only ASCII and so should user-defined ones. -Identifiers containing non-ASCII may work but aren't supported. -Only the ASCII space characters (space U+0020, tab U+000b, CR U+000d and -LF U+000a) are recognised. Other unicode space characters aren't a valid -field separator. -@command{test} (@pxref{test}) tests <, >, <=, >=, -pgt and -plt compare the strings in the -lexicographical order of unicode codepoints, replicating the behaviour of -test from coreutils. -environment variables and commands are listed in the same order. - -@node Security -@chapter Security - -@menu -* Authentication and authorisation:: Users and access control -* Using digital signatures:: Booting digitally signed code -* UEFI secure boot and shim:: Booting digitally signed PE files -* Secure Boot Advanced Targeting:: Embedded information for generation number based revocation -* Measured Boot:: Measuring boot components -* Lockdown:: Lockdown when booting on a secure setup -* TPM2 key protector:: Managing disk key with TPM2 key protector -@end menu - -@node Authentication and authorisation -@section Authentication and authorisation in GRUB - -By default, the boot loader interface is accessible to anyone with physical -access to the console: anyone can select and edit any menu entry, and anyone -can get direct access to a GRUB shell prompt. For most systems, this is -reasonable since anyone with direct physical access has a variety of other -ways to gain full access, and requiring authentication at the boot loader -level would only serve to make it difficult to recover broken systems. - -However, in some environments, such as kiosks, it may be appropriate to lock -down the boot loader to require authentication before performing certain -operations. - -The @samp{password} (@pxref{password}) and @samp{password_pbkdf2} -(@pxref{password_pbkdf2}) commands can be used to define users, each of -which has an associated password. @samp{password} sets the password in -plain text, requiring @file{grub.cfg} to be secure; @samp{password_pbkdf2} -sets the password hashed using the Password-Based Key Derivation Function -(RFC 2898), requiring the use of @command{grub-mkpasswd-pbkdf2} -(@pxref{Invoking grub-mkpasswd-pbkdf2}) to generate password hashes. - -In order to enable authentication support, the @samp{superusers} environment -variable must be set to a list of usernames, separated by any of spaces, -commas, semicolons, pipes, or ampersands. Superusers are permitted to use -the GRUB command line, edit menu entries, and execute any menu entry. If -@samp{superusers} is set, then use of the command line and editing of menu -entries are automatically restricted to superusers. Setting @samp{superusers} -to empty string effectively disables both access to CLI and editing of menu -entries. Building a grub image with @samp{--disable-cli} option will also -disable access to CLI and editing of menu entries, as well as disabling rescue -mode. Note: The environment variable needs to be exported to also affect the -section defined by the @samp{submenu} command (@pxref{submenu}). - -Other users may be allowed to execute specific menu entries by giving a list of -usernames (as above) using the @option{--users} option to the -@samp{menuentry} command (@pxref{menuentry}). If the @option{--unrestricted} -option is used for a menu entry, then that entry is unrestricted. -If the @option{--users} option is not used for a menu entry, then that -only superusers are able to use it. - -Putting this together, a typical @file{grub.cfg} fragment might look like -this: - -@example -@group -set superusers="root" -password_pbkdf2 root grub.pbkdf2.sha512.10000.biglongstring -password user1 insecure - -menuentry "May be run by any user" --unrestricted @{ - set root=(hd0,1) - linux /vmlinuz -@} - -menuentry "Superusers only" --users "" @{ - set root=(hd0,1) - linux /vmlinuz single -@} - -menuentry "May be run by user1 or a superuser" --users user1 @{ - set root=(hd0,2) - chainloader +1 -@} -@end group -@end example - -The @command{grub-mkconfig} program does not yet have built-in support for -generating configuration files with authentication. You can use -@file{/etc/grub.d/40_custom} to add simple superuser authentication, by -adding @kbd{set superusers=} and @kbd{password} or @kbd{password_pbkdf2} -commands. - -@node Using digital signatures -@section Using digital signatures in GRUB - -GRUB's @file{core.img} can optionally provide enforcement that all files -subsequently read from disk are covered by a valid digital signature. -This document does @strong{not} cover how to ensure that your -platform's firmware (e.g., Coreboot) validates @file{core.img}. - -If environment variable @code{check_signatures} -(@pxref{check_signatures}) is set to @code{enforce}, then every -attempt by the GRUB @file{core.img} to load another file @file{foo} -implicitly invokes @code{verify_detached foo foo.sig} -(@pxref{verify_detached}). @code{foo.sig} must contain a valid -digital signature over the contents of @code{foo}, which can be -verified with a public key currently trusted by GRUB -(@pxref{list_trusted}, @pxref{trust}, and @pxref{distrust}). If -validation fails, then file @file{foo} cannot be opened. This failure -may halt or otherwise impact the boot process. - -An initial trusted public key can be embedded within the GRUB @file{core.img} -using the @code{--pubkey} option to @command{grub-install} -(@pxref{Invoking grub-install}). - -GRUB uses GPG-style detached signatures (meaning that a file -@file{foo.sig} will be produced when file @file{foo} is signed), and -currently supports the DSA and RSA signing algorithms. A signing key -can be generated as follows: - -@example -gpg --gen-key -@end example - -An individual file can be signed as follows: - -@example -gpg --detach-sign /path/to/file -@end example - -For successful validation of all of GRUB's subcomponents and the -loaded OS kernel, they must all be signed. One way to accomplish this -is the following (after having already produced the desired -@file{grub.cfg} file, e.g., by running @command{grub-mkconfig} -(@pxref{Invoking grub-mkconfig}): - -@example -@group -# Edit /dev/shm/passphrase.txt to contain your signing key's passphrase -for i in `find /boot -name "*.cfg" -or -name "*.lst" -or \ - -name "*.mod" -or -name "vmlinuz*" -or -name "initrd*" -or \ - -name "grubenv"`; -do - gpg --batch --detach-sign --passphrase-fd 0 $i < \ - /dev/shm/passphrase.txt -done -shred /dev/shm/passphrase.txt -@end group -@end example - -See also: @ref{check_signatures}, @ref{verify_detached}, @ref{trust}, -@ref{list_trusted}, @ref{distrust}, @ref{load_env}, @ref{save_env}. - -Note that internally signature enforcement is controlled by setting -the environment variable @code{check_signatures} equal to -@code{enforce}. Passing one or more @code{--pubkey} options to -@command{grub-mkimage} implicitly defines @code{check_signatures} -equal to @code{enforce} in @file{core.img} prior to processing any -configuration files. - -Note that signature checking does @strong{not} prevent an attacker -with (serial, physical, ...) console access from dropping manually to -the GRUB console and executing: - -@example -set check_signatures=no -@end example - -To prevent this, password-protection (@pxref{Authentication and -authorisation}) is essential. Note that even with GRUB password -protection, GRUB itself cannot prevent someone with physical access to -the machine from altering that machine's firmware (e.g., Coreboot -or BIOS) configuration to cause the machine to boot from a different -(attacker-controlled) device. GRUB is at best only one link in a -secure boot chain. - -@node UEFI secure boot and shim -@section UEFI secure boot and shim support - -The GRUB works with UEFI secure boot and the shim. This functionality is -provided by the shim_lock verifier. It is built into the @file{core.img} and is -registered if the UEFI secure boot is enabled. The @samp{shim_lock} variable is -set to @samp{y} when shim_lock verifier is registered. If it is desired to use -UEFI secure boot without shim, one can disable shim_lock by disabling shim -verification with MokSbState UEFI variable or by building grub image with -@samp{--disable-shim-lock} option. - -All GRUB modules not stored in the @file{core.img}, OS kernels, ACPI tables, -Device Trees, etc. have to be signed, e.g, using PGP. Additionally, the commands -that can be used to subvert the UEFI secure boot mechanism, such as @command{iorw} -and @command{memrw} will not be available when the UEFI secure boot is enabled. -This is done for security reasons and are enforced by the GRUB Lockdown mechanism -(@pxref{Lockdown}). - -@node Secure Boot Advanced Targeting -@section Embedded information for generation number based revocation - -The Secure Boot Advanced Targeting (SBAT) is a mechanism to allow the revocation -of components in the boot path by using generation numbers embedded into the EFI -binaries. The SBAT metadata is located in an .sbat data section that has set of -UTF-8 strings as comma-separated values (CSV). See -@uref{https://github.com/rhboot/shim/blob/main/SBAT.md} for more details. - -To add a data section containing the SBAT information into the binary, the -@option{--sbat} option of @command{grub-mkimage} command should be used. The content -of a CSV file, encoded with UTF-8, is copied as is to the .sbat data section into -the generated EFI binary. The CSV file can be stored anywhere on the file system. - -@example -grub-mkimage -O x86_64-efi -o grubx64.efi -p '(tftp)/grub' --sbat sbat.csv efinet tftp -@end example - -@node Measured Boot -@section Measuring boot components - -If the tpm module is loaded and the platform has a Trusted Platform Module -installed, GRUB will log each command executed and each file loaded into the -TPM event log and extend the PCR values in the TPM correspondingly. All events -will be logged into the PCR described below with a type of EV_IPL and an -event description as described below. - -@multitable @columnfractions 0.3 0.1 0.6 -@headitem Event type @tab PCR @tab Description -@item Command -@tab 8 -@tab All executed commands (including those from configuration files) will be -logged and measured as entered with a prefix of ``grub_cmd: `` -@item Kernel command line -@tab 8 -@tab Any command line passed to a kernel will be logged and measured as entered -with a prefix of ``kernel_cmdline: '' -@item Module command line -@tab 8 -@tab Any command line passed to a kernel module will be logged and measured as -entered with a prefix of ``module_cmdline: `` -@item Files -@tab 9 -@tab Any file read by GRUB will be logged and measured with a descriptive text -corresponding to the filename. -@end multitable - -GRUB will not measure its own @file{core.img} - it is expected that firmware -will carry this out. GRUB will also not perform any measurements until the -tpm module is loaded. As such it is recommended that the tpm module be built -into @file{core.img} in order to avoid a potential gap in measurement between -@file{core.img} being loaded and the tpm module being loaded. - -Measured boot is currently only supported on EFI and IBM IEEE1275 PowerPC -platforms. - -@node Lockdown -@section Lockdown when booting on a secure setup - -The GRUB can be locked down when booted on a secure boot environment, for example -if the UEFI secure boot is enabled. On a locked down configuration, the GRUB will -be restricted and some operations/commands cannot be executed. This also includes -limiting which filesystems are supported to those thought to be more robust and -widely used within GRUB. - -The filesystems currently allowed in lockdown mode include: -@itemize @bullet -@item BtrFS -@item cpio -@item exFAT -@item Enhanced Read-Only File System (EROFS) -@item Linux ext2/ext3/ext4 -@item F2FS -@item DOS FAT12/FAT16/FAT32 -@item HFS+ -@item ISO9660 -@item Squash4 -@item tar -@item XFS -@item ZFS -@end itemize - -The filesystems currently not allowed in lockdown mode include: -@itemize @bullet -@item Amiga Fast FileSystem (AFFS) -@item AtheOS File System (AFS) -@item Bee File System (BFS) -@item Coreboot File System (CBFS) -@item Hierarchical File System (HFS) -@item Journaled File System (JFS) -@item Minix filesystem -@item New Implementation of Log filesystem (nilfs2) -@item Windows New Technology File System (NTFS) -@item ReiserFS -@item Read-Only Memory File System (ROMFS) -@item Amiga Smart File System (SFS) -@item Universal Disk Format (UDF) -@item Unix File System (UFS) -@end itemize - -The @samp{lockdown} variable is set to @samp{y} when the GRUB is locked down. -Otherwise it does not exist. - -@node TPM2 key protector -@section TPM2 key protector in GRUB - -TPM2 key protector extends measured boot to unlock the encrypted partition -without user intervention. It uses the TPM Storage Root Key (SRK) to seal -the disk key with a given set of PCR values. If the system state matches, -i.e. PCR values match the sealed PCR set, TPM2 key protector unseals the -disk key for @command{cryptomount} (@pxref{cryptomount}) to unlock the -encrypted partition. In case the unsealed key fails to unlock the -partition, @command{cryptomount} falls back to the passphrase prompt. - -Please note that TPM2 key protector uses the SRK in the owner hierarchy -@emph{without} authorization. If the owner hierarchy is password-protected, -TPM2 key protector may fail to unseal the key due to the absence of the -password. For the systems that already enable the password protection for the -owner hierarchy, the following command removes the password protection with -the existing password. - -@example -# @kbd{tpm2_changeauth -c owner -p password} -@end example - -There are two supported modes to store the sealed key, SRK and NV index. -The details will be addressed in later sections. - -TPM2 key protector is currently only supported on EFI and EMU platforms. - -@subsection TPM PCR usage - -Since TPM2 key protector relies on PCRs to check the system state, it is -important to decide which PCRs to seal the key with. The following table -lists uses of PCRs and the measured objects on EFI platforms. - -@multitable @columnfractions 0.1 0.2 0.7 -@headitem PCR @tab Used by @tab Measured Objects -@item 0 -@tab Firmware -@tab Core system firmware executable code -@item 1 -@tab Firmware -@tab Core system firmware data/host platform configuration; typically -contains serial and model numbers -@item 2 -@tab Firmware -@tab Extended or pluggable executable code; includes option ROMs on -pluggable hardware -@item 3 -@tab Firmware -@tab Extended or pluggable firmware data; includes information about -pluggable hardware -@item 4 -@tab Firmware -@tab Boot loader and additional drivers; binaries and extensions loaded -by the boot loader -@item 5 -@tab Firmware -@tab GPT/Partition table -@item 7 -@tab Firmware -@tab SecureBoot state -@item 8 -@tab GRUB -@tab Commands and kernel command line -@item 9 -@tab GRUB -@tab All files read (including kernel image) -@item 9 -@tab Linux Kernel -@tab All passed initrds (when the new LOAD_FILE2 initrd protocol is used) -@item 10 -@tab Linux Kernel -@tab Protection of the IMA measurement log -@item 14 -@tab shim -@tab “MOK†certificates and hashes -@end multitable - -PCR 0, 2, 4, and 7 can be used to check the integrity of the firmware code -and bootloaders. PCR 8 and 9 are useful to check the file and data processed -by GRUB. PCRs 10, 11, 12, 13, and 15 are controlled by the operating system, -so those PCRs are usually still in the initial state when GRUB is running. - -In general, it is nice to include PCR 0, 2, 4, and 7 to ensure the integrity -of the firmware and bootloaders. For PCR 8 and 9, a sophisticated tool is -required to examine the GRUB configuration files and the files to be loaded -to calculate the correct PCR values. - -Please note that PCRs are sensitive to any change, so an update of a component -could invalidate the sealed key, due to the so-called PCR brittleness. For the -bootloader update, PCR 4 may be affected. This can be mitigated by extracting -the events from the TPM event log and predict the value with the updated -bootloader binary. On the other hand, it is difficult to predict PCR 0~7 after -a firmware update since the content of the code and the order of drivers may -not follow the TPM event log from the previous firmware version, so it is -necessary to reboot the system to update the measurement results of PCR 0~7 -and seal or sign the sealed key again. - -Reference: @url{https://uapi-group.org/specifications/specs/linux_tpm_pcr_registry/, Linux TPM PCR Registry} - -@subsection Setting up the extra disk key - -Instead of using the existing password, it is recommended to seal a new -random disk key and use the existing password for recovery. - -Here are the sample commands to create a 128 random bytes key file and -enroll the key into the target partition (sda2). - -@example -# @kbd{dd if=/dev/urandom of=luks.key bs=1 count=128} -# @kbd{cryptsetup luksAddKey /dev/sda2 luks.key --pbkdf=pbkdf2 --hash=sha512} -@end example - -@subsection SRK mode - -To unlock the partition with SRK mode, assume that the sealed key is in -@file{(hd0,gpt1)/efi/grub/sealed.tpm}, the following GRUB commands -unseal the disk key with SRK mode and supply it to @command{cryptomount}. - -@example -grub> @kbd{tpm2_key_protector_init -T (hd0,gpt1)/efi/grub/sealed.tpm} -grub> @kbd{cryptomount -u -P tpm2} -@end example - -There are two programs to create the sealed key for SRK mode: @command{grub-protect} -and @command{pcr-oracle} (@url{https://github.com/okirch/pcr-oracle}). - -The following sample command uses @command{grub-protect} to seal the random -key, @file{luks.key}, with PCR 0, 2, 4 and 7 in TPM 2.0 Key File format. - -@example -@group -# @kbd{grub-protect --action=add \ - --protector=tpm2 \ - --tpm2-pcrs=0,2,4,7 \ - --tpm2key \ - --tpm2-keyfile=luks.key \ - --tpm2-outfile=/boot/efi/efi/grub/sealed.tpm} -@end group -@end example - -@command{grub-protect} only seals the key with the current PCR values. -Therefore, when a boot component, such as shim or GRUB, is updated, it is -necessary to reboot the system to update the measurement results and seal -the key again. That means the random disk key has to be stored in cleartext -for the next key sealing. Besides this, the measurement result of some PCRs -may differ between boot time and OS runtime. For example, PCR 9 measures the -files loaded by GRUB including the Linux kernel and initrd. To unlock the disk -containing the kernel and initrd, the key has to be sealed with PCR 9 value -before loading the kernel and initrd. However, PCR 9 changes after GRUB -loading the kernel and initrd, so PCR 9 at OS runtime cannot be used directly -for key sealing. - -To solve these problems, @command{pcr-oracle} takes a different approach. It -reads the TPM eventlog and predicts the PCR values. Besides, -@command{pcr-oracle} also supports ``authorized policy'' which allows the -PCR policy to be updated with a valid signature, so that the user only seals -the random disk key once. If at some later time the PCR values change due to -an update of the system firmware, bootloader, or config file, the user just -needs to update the signature of the PCR policy. - -To seal the key with the authorized policy, the first thing is to generate -the RSA policy key, @file{policy-key.pem}, and the authorized policy file, -@file{authorized.policy}. In this example, PCR 0, 2, 4, 7 and 9 are chosen -for key sealing. - -@example -@group -# @kbd{pcr-oracle --rsa-generate-key \ - --private-key policy-key.pem \ - --auth authorized.policy \ - create-authorized-policy 0,2,4,7,9} -@end group -@end example - -Then, we seal the random disk key, @file{luks.key}, with the authorized -policy file and save the sealed key in @file{sealed.key}. - -@example -@group -# @kbd{pcr-oracle --key-format tpm2.0 \ - --auth authorized.policy \ - --input luks.key \ - --output sealed.key \ - seal-secret} -@end group -@end example - -Since we now have the sealed key, we can remove the random disk key file -@file{luks.key}. - -The last step is to sign the predicted PCR policy and save the final key -file, @file{sealed.tpm}. - -@example -@group -# @kbd{pcr-oracle --key-format tpm2.0 \ - --private-key policy-key.pem \ - --from eventlog \ - --stop-event "grub-file=grub.cfg" \ - --after \ - --input sealed.key \ - --output /boot/efi/efi/grub/sealed.tpm \ - sign 0,2,4,7,9} -@end group -@end example - -Here we also set a stop event for the prediction. With -@kbd{--stop-event grub-file=grub.cfg --after}, @command{pcr-oracle} stops -the calculation of PCR values right after GRUB loads @file{grub.cfg}. - -When/After the shim or GRUB are updated, it only requires to run the last -@command{pcr-oracle} command to update the predicted PCR policy. - -@subsection NV index mode - -Instead of storing the sealed key in a file, NV index mode uses the TPM -non-volatile memory to store the sealed key and could be useful when accessing -the file is not possible. - -However, the Linux root user must be careful who she/he gives access to the -TPM (tss group) since those users will also be able to modify the NV index -that's holding the key. - -There are two types of TPM handles supported by NV index mode: persistent -handle and NV index handle. - -@subsubsection Persistent handle - -The range of persistent handles is from @kbd{0x81000000} to @kbd{0x81FFFFFF}. -The persistent handle is designed to make TPM objects persistent through -power cycles, and only TPM objects, such as RSA or EC keys, are accepted. -Thus, only the raw format is supported by persistent handles. The following -shows the @command{grub-protect} command to seal the disk key @file{luks.key} -into the persistent handle @kbd{0x81000000} with the PCRs @kbd{0,2,4,7}. - -@example -@group -# @kbd{grub-protect \ - --protector=tpm2 \ - --action=add \ - --tpm2-bank=sha256 \ - --tpm2-pcrs=0,2,4,7 \ - --tpm2-keyfile=luks.key \ - --tpm2-nvindex=0x81000000} -@end group -@end example - -To unseal the key, we have to specify the mode @kbd{nv}, the persistent handle -@kbd{0x81000000}, and the PCRs @kbd{0,2,4,7} for the @command{tpm2_key_protector_init} -command. - -@example -grub> @kbd{tpm2_key_protector_init --mode=nv --nvindex=0x81000000 --pcrs=0,2,4,7} -grub> @kbd{cryptomount -u --protector tpm2} -@end example - -If the key in the persistent handle becomes unwanted, the following -@command{grub-protect} command removes the specified persistent handle -@kbd{0x81000000}. - -@example -@group -# @kbd{grub-protect \ - --protector=tpm2 \ - --action=remove \ - --tpm2-evict \ - --tpm2-nvindex=0x81000000} -@end group -@end example - -@subsubsection NV index handle - -The range of NV index handles is from @kbd{0x1000000} to @kbd{0x1FFFFFF}. -Unlike the persistent handle, the NV index handle allows user-defined data, -so it can easily support both the TPM 2.0 Key File format as well as the raw -format. - -The following @kbd{grub-protect} command seals the disk key @file{luks.key} -into the NV index handle @kbd{0x1000000} with the PCRs @kbd{0,2,4,7} while -using the TPM 2.0 Key File format. - -@example -@group -# @kbd{grub-protect \ - --protector=tpm2 \ - --action=add \ - --tpm2key \ - --tpm2-bank=sha256 \ - --tpm2-pcrs=0,2,4,7 \ - --tpm2-keyfile=luks.key \ - --tpm2-nvindex=0x1000000} -@end group -@end example - -Furthermore, it is also possible to insert an existing key file, -@file{sealed.tpm}, into a specific NV index handle using the following -tpm2-tools (@url{https://github.com/tpm2-software/tpm2-tools}) commands. - -@example -@group -# @kbd{tpm2_nvdefine -C o \ - -a "ownerread|ownerwrite" \ - -s $(stat -c %s sealed.tpm) \ - 0x1000000} -@end group -# @kbd{tpm2_nvwrite -C o -i sealed.tpm 0x1000000} -@end example - -When unsealing the key in TPM 2.0 Key File format, only the mode @kbd{nv} -and the NV index handle @kbd{0x1000000} have to be specified for the -@command{tpm2_key_protector_init} command. - -@example -grub> @kbd{tpm2_key_protector_init --mode=nv --nvindex=0x1000000} -grub> @kbd{cryptomount -u --protector tpm2} -@end example - -The following @command{grub-protect} command allows to remove the specified -NV index handle @kbd{0x1000000}. - -@example -@group -# @kbd{grub-protect \ - --protector=tpm2 \ - --action=remove \ - --tpm2-evict \ - --tpm2-nvindex=0x1000000} -@end group -@end example - -@subsection Setting up software TPM for EMU platform - -In order to test TPM2 key protector and TPM2 Software Stack (TSS2), it is -useful to set up a software TPM (swtpm) instance and run the commands on the -EMU platform. - -Here are the commands to start a swtpm instance which provides a character -device interface. To store the TPM states, the directory, @file{swtpm-state}, -is created before the @command{swtpm} command. All the messages are stored -in @file{swtpm.log} including the name of the character device. - -@example -# @kbd{mkdir swtpm-state} -@group -# @kbd{swtpm chardev --vtpm-proxy --tpmstate dir=swtpm-state \ - --tpm2 --ctrl type=unixio,path="swtpm-state/ctrl" \ - --flags startup-clear --daemon > swtpm.log} -@end group -@end example - -Then, we extract the name of the character device from @file{swtpm.log} and -save it to the variable, @samp{tpm2dev}. - -@example -# @kbd{tpm2dev=$(grep "New TPM device" swtpm.log | cut -d' ' -f 4)} -@end example - -Now we can start @kbd{grub-emu} with @kbd{--tpm-device $tpm2dev} to interact -with the swtpm instance. - -@example -# @kbd{grub-emu --tpm-device $tpm2dev} -@end example - -On the host, the tpm2-tools commands can interact with the swtpm instance by -setting @samp{TPM2TOOLS_TCTI}. - -@example -# @kbd{export TPM2TOOLS_TCTI="device:$tpm2dev"} -@end example - -When the test is done, use @kbd{swtpm_ioctl} to send the shutdown -command through the swtpm control channel. - -@example -# @kbd{swtpm_ioctl -s --unix swtpm-state/ctrl} -@end example - -@subsection Command line and menuentry editor protection - -The TPM key protector provides full disk encryption support on servers or -virtual machine images, meanwhile keeping the boot process unattended. This -prevents service disruptions by eliminating the need for manual password input -during startup, improving system uptime and continuity. It is achieved by TPM, -which verifies the integrity of boot components by checking cryptographic -hashes against securely stored values, to confirm the disks are unlocked in a -trusted state. - -However, for users to access the system interactively, some form of -authentication is still required, as the disks are not unlocked by an -authorized user. This raised concerns about using an unprotected -@samp{command-line interface} (@pxref{Command-line interface}), as anyone could -execute commands to access decrypted data. To address this issue, the LUKS -password is used to ensure that only authorized users are granted access to the -interface. Additionally, the @samp{menu entry editor} (@pxref{Menu entry -editor}) is also safeguarded by the LUKS password, as modifying a boot entry is -effectively the same as altering the @file{grub.cfg} file read from encrypted -files. - -It is worth mentioning that the built-in password support, as described in -@samp{Authentication and Authorization in GRUB} (@pxref{Authentication and -authorisation}), can also be used to protect the command-line interface from -unauthorized access. However, it is not recommended to rely on this approach as -it is an optional step. Setting it up requires additional manual intervention, -which increases the risk of password leakage during the process. Moreover, the -superuser list must be well maintained, and the password used cannot be -synchronized with LUKS key rotation. - -@node Platform limitations -@chapter Platform limitations - -GRUB2 is designed to be portable and is actually ported across platforms. We -try to keep all platforms at the level. Unfortunately some platforms are better -supported than others. This is detailed in current and 2 following sections. - -All platforms have an artificially GRUB imposed disk size restriction of 1 EiB. -In some cases, larger disk sizes can be used, but access will not be allowed -beyond 1 EiB. - -LUKS2 devices with size larger than 16 EiB are currently not supported. They -can not be created as crypto devices by cryptomount, so can not even be -partially read from. LUKS have no limitations other than those imposed by the -format. - -ARC platform is unable to change datetime (firmware doesn't seem to provide a -function for it). -EMU has similar limitation. - -On EMU platform no serial port is available. - -Console charset refers only to firmware-assisted console. gfxterm is always -Unicode (see Internationalisation section for its limitations). Serial is -configurable to UTF-8 or ASCII (see Internationalisation). In case of qemu -and coreboot ports the referred console is vga_text. Loongson always uses -gfxterm. - -Most limited one is ASCII. CP437 provides additionally pseudographics. -GRUB2 doesn't use any language characters from CP437 as often CP437 is replaced -by national encoding compatible only in pseudographics. -Unicode is the most versatile charset which supports many languages. However -the actual console may be much more limited depending on firmware - -On BIOS, network is supported only if the image is loaded through network. -On sparc64, GRUB is unable to determine which server it was booted from. - -Direct ATA/AHCI support allows to circumvent various firmware limitations but -isn't needed for normal operation except on baremetal ports. - -AT keyboard support allows keyboard layout remapping and support for keys not -available through firmware. It isn't needed for normal operation except -baremetal ports. - -Speaker allows morse and spkmodem communication. - -USB support provides benefits similar to ATA (for USB disks) or AT (for USB -keyboards). In addition it allows USBserial. - -Chainloading refers to the ability to load another bootloader through the same protocol -and on some platforms, like EFI, allow that bootloader to return to the GRUB. - -Hints allow faster disk discovery by already knowing in advance which is the disk in -question. On some platforms hints are correct unless you move the disk between boots. -On other platforms it's just an educated guess. -Note that hint failure results in just reduced performance, not a failure - -BadRAM is the ability to mark some of the RAM as ``bad''. Note: due to protocol -limitations mips-loongson (with Linux protocol) -and mips-qemu_mips can use only memory up to first hole. - -Bootlocation is ability of GRUB to automatically detect where it boots from. -``disk'' means the detection is limited to detecting the disk with partition -being discovered on install time. ``partition'' means that disk and partiton -can be automatically discovered. ``file'' means that boot image file name as -well as disk and partition can be discovered. For consistency, default install ignores -partition and relies solely on disk detection. If no bootlocation discovery is available -or boot and grub-root disks are different, UUID is used instead. On ARC if no device -to install to is specified, UUID is used instead as well. - - -@multitable @columnfractions .20 .20 .20 .20 .20 -@item @tab BIOS @tab Coreboot @tab Multiboot @tab Qemu -@item video @tab yes @tab yes @tab yes @tab yes -@item console charset @tab CP437 @tab CP437 @tab CP437 @tab CP437 -@item network @tab yes (*) @tab no @tab no @tab no -@item ATA/AHCI @tab yes @tab yes @tab yes @tab yes -@item AT keyboard @tab yes @tab yes @tab yes @tab yes -@item Speaker @tab yes @tab yes @tab yes @tab yes -@item USB @tab yes @tab yes @tab yes @tab yes -@item chainloader @tab local @tab yes @tab yes @tab no -@item cpuid @tab partial @tab partial @tab partial @tab partial -@item rdmsr @tab partial @tab partial @tab partial @tab partial -@item wrmsr @tab partial @tab partial @tab partial @tab partial -@item hints @tab guess @tab guess @tab guess @tab guess -@item PCI @tab yes @tab yes @tab yes @tab yes -@item badram @tab yes @tab yes @tab yes @tab yes -@item compression @tab always @tab pointless @tab no @tab no -@item exit @tab yes @tab no @tab no @tab no -@item bootlocation @tab disk @tab no @tab no @tab no -@end multitable - -@multitable @columnfractions .20 .20 .20 .20 .20 -@item @tab ia32 EFI @tab amd64 EFI @tab ia32 IEEE1275 @tab Itanium -@item video @tab yes @tab yes @tab no @tab no -@item console charset @tab Unicode @tab Unicode @tab ASCII @tab Unicode -@item network @tab yes @tab yes @tab yes @tab yes -@item ATA/AHCI @tab yes @tab yes @tab yes @tab no -@item AT keyboard @tab yes @tab yes @tab yes @tab no -@item Speaker @tab yes @tab yes @tab yes @tab no -@item USB @tab yes @tab yes @tab yes @tab no -@item chainloader @tab local @tab local @tab no @tab local -@item cpuid @tab partial @tab partial @tab partial @tab no -@item rdmsr @tab partial @tab partial @tab partial @tab no -@item wrmsr @tab partial @tab partial @tab partial @tab no -@item hints @tab guess @tab guess @tab good @tab guess -@item PCI @tab yes @tab yes @tab yes @tab no -@item badram @tab yes @tab yes @tab no @tab yes -@item compression @tab no @tab no @tab no @tab no -@item exit @tab yes @tab yes @tab yes @tab yes -@item bootlocation @tab file @tab file @tab file, ignored @tab file -@end multitable - -@multitable @columnfractions .20 .20 .20 .20 .20 -@item @tab Loongson @tab sparc64 @tab Powerpc @tab ARC -@item video @tab yes @tab no @tab yes @tab no -@item console charset @tab N/A @tab ASCII @tab ASCII @tab ASCII -@item network @tab no @tab yes (*) @tab yes @tab no -@item ATA/AHCI @tab yes @tab no @tab no @tab no -@item AT keyboard @tab yes @tab no @tab no @tab no -@item Speaker @tab no @tab no @tab no @tab no -@item USB @tab yes @tab no @tab no @tab no -@item chainloader @tab yes @tab no @tab no @tab no -@item cpuid @tab no @tab no @tab no @tab no -@item rdmsr @tab no @tab no @tab no @tab no -@item wrmsr @tab no @tab no @tab no @tab no -@item hints @tab good @tab good @tab good @tab no -@item PCI @tab yes @tab no @tab no @tab no -@item badram @tab yes (*) @tab no @tab no @tab no -@item compression @tab configurable @tab no @tab no @tab configurable -@item exit @tab no @tab yes @tab yes @tab yes -@item bootlocation @tab no @tab partition @tab file @tab file (*) -@end multitable - -@multitable @columnfractions .20 .20 .20 .20 .20 -@item @tab MIPS qemu @tab emu @tab xen -@item video @tab no @tab yes @tab no -@item console charset @tab CP437 @tab Unicode (*) @tab ASCII -@item network @tab no @tab yes @tab no -@item ATA/AHCI @tab yes @tab no @tab no -@item AT keyboard @tab yes @tab no @tab no -@item Speaker @tab no @tab no @tab no -@item USB @tab N/A @tab yes @tab no -@item chainloader @tab yes @tab no @tab yes -@item cpuid @tab no @tab no @tab yes -@item rdmsr @tab no @tab no @tab yes -@item wrmsr @tab no @tab no @tab yes -@item hints @tab guess @tab no @tab no -@item PCI @tab no @tab no @tab no -@item badram @tab yes (*) @tab no @tab no -@item compression @tab configurable @tab no @tab no -@item exit @tab no @tab yes @tab no -@item bootlocation @tab no @tab file @tab no -@end multitable - -@node Platform-specific operations -@chapter Outline - -Some platforms have features which allows to implement -some commands useless or not implementable on others. - -Quick summary: - -Information retrieval: - -@itemize -@item mipsel-loongson: lsspd -@item mips-arc: lsdev -@item efi: lsefisystab, lssal, lsefimmap, lsefi -@item i386-pc: lsapm -@item i386-coreboot: lscoreboot, coreboot_boottime, cbmemc -@item acpi-enabled (i386-pc, i386-coreboot, i386-multiboot, *-efi): lsacpi -@end itemize - -Workarounds for platform-specific issues: -@itemize -@item i386-efi/x86_64-efi: loadbios, fakebios, fix_video -@item acpi-enabled (i386-pc, i386-coreboot, i386-multiboot, *-efi): - acpi (override ACPI tables) -@item i386-pc: drivemap -@item i386-pc: sendkey -@end itemize - -Advanced operations for power users: -@itemize -@item x86: iorw (direct access to I/O ports) -@end itemize - -Miscellaneous: -@itemize -@item cmos (x86-*, ieee1275, mips-qemu_mips, mips-loongson): cmostest - (used on some laptops to check for special power-on key), cmosclean -@item i386-pc: play -@end itemize - -@node Supported kernels -@chapter Supported boot targets - -X86 support is summarised in the following table. ``Yes'' means that the kernel works on the given platform, ``crashes'' means an early kernel crash which we hope will be fixed by concerned kernel developers. ``no'' means GRUB doesn't load the given kernel on a given platform. ``headless'' means that the kernel works but lacks console drivers (you can still use serial or network console). In case of ``no'' and ``crashes'' the reason is given in footnote. -@multitable @columnfractions .50 .22 .22 -@item @tab BIOS @tab Coreboot -@item BIOS chainloading @tab yes @tab no (1) -@item NTLDR @tab yes @tab no (1) -@item Plan9 @tab yes @tab no (1) -@item Freedos @tab yes @tab no (1) -@item FreeBSD bootloader @tab yes @tab crashes (1) -@item 32-bit kFreeBSD @tab yes @tab crashes (5) -@item 64-bit kFreeBSD @tab yes @tab crashes (5) -@item 32-bit kNetBSD @tab yes @tab crashes (1) -@item 64-bit kNetBSD @tab yes @tab crashes -@item 32-bit kOpenBSD @tab yes @tab yes -@item 64-bit kOpenBSD @tab yes @tab yes -@item Multiboot @tab yes @tab yes -@item Multiboot2 @tab yes @tab yes -@item 32-bit Linux (legacy protocol) @tab yes @tab no (1) -@item 64-bit Linux (legacy protocol) @tab yes @tab no (1) -@item 32-bit Linux (modern protocol) @tab yes @tab yes -@item 64-bit Linux (modern protocol) @tab yes @tab yes -@item 32-bit XNU @tab yes @tab ? -@item 64-bit XNU @tab yes @tab ? -@item 32-bit EFI chainloader @tab no (2) @tab no (2) -@item 64-bit EFI chainloader @tab no (2) @tab no (2) -@item Appleloader @tab no (2) @tab no (2) -@end multitable - -@multitable @columnfractions .50 .22 .22 -@item @tab Multiboot @tab Qemu -@item BIOS chainloading @tab no (1) @tab no (1) -@item NTLDR @tab no (1) @tab no (1) -@item Plan9 @tab no (1) @tab no (1) -@item FreeDOS @tab no (1) @tab no (1) -@item FreeBSD bootloader @tab crashes (1) @tab crashes (1) -@item 32-bit kFreeBSD @tab crashes (5) @tab crashes (5) -@item 64-bit kFreeBSD @tab crashes (5) @tab crashes (5) -@item 32-bit kNetBSD @tab crashes (1) @tab crashes (1) -@item 64-bit kNetBSD @tab yes @tab yes -@item 32-bit kOpenBSD @tab yes @tab yes -@item 64-bit kOpenBSD @tab yes @tab yes -@item Multiboot @tab yes @tab yes -@item Multiboot2 @tab yes @tab yes -@item 32-bit Linux (legacy protocol) @tab no (1) @tab no (1) -@item 64-bit Linux (legacy protocol) @tab no (1) @tab no (1) -@item 32-bit Linux (modern protocol) @tab yes @tab yes -@item 64-bit Linux (modern protocol) @tab yes @tab yes -@item 32-bit XNU @tab ? @tab ? -@item 64-bit XNU @tab ? @tab ? -@item 32-bit EFI chainloader @tab no (2) @tab no (2) -@item 64-bit EFI chainloader @tab no (2) @tab no (2) -@item Appleloader @tab no (2) @tab no (2) -@end multitable - -@multitable @columnfractions .50 .22 .22 -@item @tab ia32 EFI @tab amd64 EFI -@item BIOS chainloading @tab no (1) @tab no (1) -@item NTLDR @tab no (1) @tab no (1) -@item Plan9 @tab no (1) @tab no (1) -@item FreeDOS @tab no (1) @tab no (1) -@item FreeBSD bootloader @tab crashes (1) @tab crashes (1) -@item 32-bit kFreeBSD @tab headless @tab headless -@item 64-bit kFreeBSD @tab headless @tab headless -@item 32-bit kNetBSD @tab crashes (1) @tab crashes (1) -@item 64-bit kNetBSD @tab yes @tab yes -@item 32-bit kOpenBSD @tab headless @tab headless -@item 64-bit kOpenBSD @tab headless @tab headless -@item Multiboot @tab yes @tab yes -@item Multiboot2 @tab yes @tab yes -@item 32-bit Linux (legacy protocol) @tab no (1) @tab no (1) -@item 64-bit Linux (legacy protocol) @tab no (1) @tab no (1) -@item 32-bit Linux (modern protocol) @tab yes @tab yes -@item 64-bit Linux (modern protocol) @tab yes @tab yes -@item 32-bit XNU @tab yes @tab yes -@item 64-bit XNU @tab yes (4) @tab yes -@item 32-bit EFI chainloader @tab yes @tab no (3) -@item 64-bit EFI chainloader @tab no (3) @tab yes -@item Appleloader @tab yes @tab yes -@end multitable - -@multitable @columnfractions .50 .22 .22 -@item @tab ia32 IEEE1275 -@item BIOS chainloading @tab no (1) -@item NTLDR @tab no (1) -@item Plan9 @tab no (1) -@item FreeDOS @tab no (1) -@item FreeBSD bootloader @tab crashes (1) -@item 32-bit kFreeBSD @tab crashes (5) -@item 64-bit kFreeBSD @tab crashes (5) -@item 32-bit kNetBSD @tab crashes (1) -@item 64-bit kNetBSD @tab ? -@item 32-bit kOpenBSD @tab ? -@item 64-bit kOpenBSD @tab ? -@item Multiboot @tab ? -@item Multiboot2 @tab ? -@item 32-bit Linux (legacy protocol) @tab no (1) -@item 64-bit Linux (legacy protocol) @tab no (1) -@item 32-bit Linux (modern protocol) @tab ? -@item 64-bit Linux (modern protocol) @tab ? -@item 32-bit XNU @tab ? -@item 64-bit XNU @tab ? -@item 32-bit EFI chainloader @tab no (2) -@item 64-bit EFI chainloader @tab no (2) -@item Appleloader @tab no (2) -@end multitable - -@enumerate -@item Requires BIOS -@item EFI only -@item 32-bit and 64-bit EFI have different structures and work in different CPU modes so it's not possible to chainload 32-bit bootloader on 64-bit platform and vice-versa -@item Some modules may need to be disabled -@item Requires ACPI -@end enumerate - -PowerPC, IA64 and Sparc64 ports support only Linux. MIPS port supports Linux -and multiboot2. - -@section Boot tests - -As you have seen in previous chapter the support matrix is pretty big and some of the configurations are only rarely used. To ensure the quality bootchecks are available for all x86 targets except EFI chainloader, Appleloader and XNU. All x86 platforms have bootcheck facility except ieee1275. Multiboot, multiboot2, BIOS chainloader, ntldr and freebsd-bootloader boot targets are tested only with a fake kernel images. Only Linux is tested among the payloads using Linux protocols. - -Following variables must be defined: - -@multitable @columnfractions .30 .65 -@item GRUB_PAYLOADS_DIR @tab directory containing the required kernels -@item GRUB_CBFSTOOL @tab cbfstool from Coreboot package (for coreboot platform only) -@item GRUB_COREBOOT_ROM @tab empty Coreboot ROM -@item GRUB_QEMU_OPTS @tab additional options to be supplied to QEMU -@end multitable - -Required files are: - -@multitable @columnfractions .40 .55 -@item kfreebsd_env.i386 @tab 32-bit kFreeBSD device hints -@item kfreebsd.i386 @tab 32-bit FreeBSD kernel image -@item kfreebsd.x86_64, kfreebsd_env.x86_64 @tab same from 64-bit kFreeBSD -@item knetbsd.i386 @tab 32-bit NetBSD kernel image -@item knetbsd.miniroot.i386 @tab 32-bit kNetBSD miniroot.kmod. -@item knetbsd.x86_64, knetbsd.miniroot.x86_64 @tab same from 64-bit kNetBSD -@item kopenbsd.i386 @tab 32-bit OpenBSD kernel bsd.rd image -@item kopenbsd.x86_64 @tab same from 64-bit kOpenBSD -@item linux.i386 @tab 32-bit Linux -@item linux.x86_64 @tab 64-bit Linux -@end multitable - -@node Troubleshooting -@chapter Error messages produced by GRUB - -@menu -* GRUB only offers a rescue shell:: -* Firmware stalls instead of booting GRUB:: -@end menu - - -@node GRUB only offers a rescue shell -@section GRUB only offers a rescue shell - -GRUB's normal start-up procedure involves setting the @samp{prefix} -environment variable to a value set in the core image by -@command{grub-install}, setting the @samp{root} variable to match, loading -the @samp{normal} module from the prefix, and running the @samp{normal} -command (@pxref{normal}). This command is responsible for reading -@file{/boot/grub/grub.cfg}, running the menu, and doing all the useful -things GRUB is supposed to do. - -If, instead, you only get a rescue shell, this usually means that GRUB -failed to load the @samp{normal} module for some reason. It may be possible -to work around this temporarily: for instance, if the reason for the failure -is that @samp{prefix} is wrong (perhaps it refers to the wrong device, or -perhaps the path to @file{/boot/grub} was not correctly made relative to the -device), then you can correct this and enter normal mode manually: - -@example -@group -# Inspect the current prefix (and other preset variables): -set -# Find out which devices are available: -ls -# Set to the correct value, which might be something like this: -set prefix=(hd0,1)/grub -set root=(hd0,1) -insmod normal -normal -@end group -@end example - -However, any problem that leaves you in the rescue shell probably means that -GRUB was not correctly installed. It may be more useful to try to reinstall -it properly using @kbd{grub-install @var{device}} (@pxref{Invoking -grub-install}). When doing this, there are a few things to remember: - -@itemize @bullet{} -@item -Drive ordering in your operating system may not be the same as the boot -drive ordering used by your firmware. Do not assume that your first hard -drive (e.g. @samp{/dev/sda}) is the one that your firmware will boot from. -@file{device.map} (@pxref{Device map}) can be used to override this, but it -is usually better to use UUIDs or file system labels and avoid depending on -drive ordering entirely. - -@item -At least on BIOS systems, if you tell @command{grub-install} to install GRUB -to a partition but GRUB has already been installed in the master boot -record, then the GRUB installation in the partition will be ignored. - -@item -If possible, it is generally best to avoid installing GRUB to a partition -(unless it is a special partition for the use of GRUB alone, such as the -BIOS Boot Partition used on GPT). Doing this means that GRUB may stop being -able to read its core image due to a file system moving blocks around, such -as while defragmenting, running checks, or even during normal operation. -Installing to the whole disk device is normally more robust. - -@item -Check that GRUB actually knows how to read from the device and file system -containing @file{/boot/grub}. It will not be able to read from encrypted -devices with unsupported encryption scheme, nor from file systems for which -support has not yet been added to GRUB. -@end itemize - - -@node Firmware stalls instead of booting GRUB -@section Firmware stalls instead of booting GRUB - -The EFI implementation of some older MacBook laptops stalls when it gets -presented a grub-mkrescue ISO image for x86_64-efi target on an USB stick. -Affected are models of year 2010 or earlier. Workaround is to zeroize the -bytes 446 to 461 of the EFI partition, where mformat has put a partition table -entry which claims partition start at block 0. This change will not hamper -bootability on other machines. - - -@node User-space utilities -@chapter User-space utilities - -@menu -* Invoking grub-install:: How to use the GRUB installer -* Invoking grub-mkconfig:: Generate a GRUB configuration file -* Invoking grub-mkpasswd-pbkdf2:: - Generate GRUB password hashes -* Invoking grub-mkrelpath:: Make system path relative to its root -* Invoking grub-mkrescue:: Make a GRUB rescue image -* Invoking grub-mount:: Mount a file system using GRUB -* Invoking grub-probe:: Probe device information for GRUB -* Invoking grub-protect:: Protect a disk key with a key protector -* Invoking grub-script-check:: Check GRUB script file for syntax errors -@end menu - - @node Invoking grub-install -@section Invoking grub-install +@chapter Invoking grub-install -The program @command{grub-install} generates a GRUB core image using -@command{grub-mkimage} and installs it on your system. You must specify the +The program @command{grub-install} installs GRUB on your drive using the +grub shell (@pxref{Invoking the grub shell}). You must specify the device name on which you want to install GRUB, like this: @example @@ -9832,620 +1431,21 @@ Print a summary of the command-line options and exit. @item --version Print the version number of GRUB and exit. -@item --boot-directory=@var{dir} -Install GRUB images under the directory @file{@var{dir}/grub/} -This option is useful when you want to install GRUB into a -separate partition or a removable disk. -If this option is not specified then it defaults to @file{/boot}, so +@item --root-directory=@var{dir} +Install GRUB images under the directory @var{dir} instead of the root +directory. This option is useful when you want to install GRUB into a +separate partition or a removable disk. Here is an example in which +you have a separate @dfn{boot} partition which is mounted on +@file{/boot}: @example -@kbd{grub-install /dev/sda} -@end example - -is equivalent to - -@example -@kbd{grub-install --boot-directory=/boot/ /dev/sda} -@end example - -Here is an example in which you have a separate @dfn{boot} partition which is -mounted on -@file{/mnt/boot}: - -@example -@kbd{grub-install --boot-directory=/mnt/boot /dev/sdb} +@kbd{grub-install --root-directory=/boot hd0} @end example @item --recheck Recheck the device map, even if @file{/boot/grub/device.map} already exists. You should use this option whenever you add/remove a disk into/from your computer. - -@item --no-rs-codes -By default on x86 BIOS systems, @command{grub-install} will use some -extra space in the bootloader embedding area for Reed-Solomon -error-correcting codes. This enables GRUB to still boot successfully -if some blocks are corrupted. The exact amount of protection offered -is dependent on available space in the embedding area. R sectors of -redundancy can tolerate up to R/2 corrupted sectors. This -redundancy may be cumbersome if attempting to cryptographically -validate the contents of the bootloader embedding area, or in more -modern systems with GPT-style partition tables (@pxref{BIOS -installation}) where GRUB does not reside in any unpartitioned space -outside of the MBR. Disable the Reed-Solomon codes with this option. -@end table - -@node Invoking grub-mkconfig -@section Invoking grub-mkconfig - -The program @command{grub-mkconfig} generates a configuration file for GRUB -(@pxref{Simple configuration}). - -@example -grub-mkconfig -o /boot/grub/grub.cfg -@end example - -@command{grub-mkconfig} accepts the following options: - -@table @option -@item --help -Print a summary of the command-line options and exit. - -@item --version -Print the version number of GRUB and exit. - -@item -o @var{file} -@itemx --output=@var{file} -Send the generated configuration file to @var{file}. The default is to send -it to standard output. -@end table - - -@node Invoking grub-mkpasswd-pbkdf2 -@section Invoking grub-mkpasswd-pbkdf2 - -The program @command{grub-mkpasswd-pbkdf2} generates password hashes for -GRUB (@pxref{Security}). - -@example -grub-mkpasswd-pbkdf2 -@end example - -@command{grub-mkpasswd-pbkdf2} accepts the following options: - -@table @option -@item -c @var{number} -@itemx --iteration-count=@var{number} -Number of iterations of the underlying pseudo-random function. Defaults to -10000. - -@item -l @var{number} -@itemx --buflen=@var{number} -Length of the generated hash. Defaults to 64. - -@item -s @var{number} -@itemx --salt=@var{number} -Length of the salt. Defaults to 64. -@end table - - -@node Invoking grub-mkrelpath -@section Invoking grub-mkrelpath - -The program @command{grub-mkrelpath} makes a file system path relative to -the root of its containing file system. For instance, if @file{/usr} is a -mount point, then: - -@example -$ @kbd{grub-mkrelpath /usr/share/grub/unicode.pf2} -@samp{/share/grub/unicode.pf2} -@end example - -This is mainly used internally by other GRUB utilities such as -@command{grub-mkconfig} (@pxref{Invoking grub-mkconfig}), but may -occasionally also be useful for debugging. - -@command{grub-mkrelpath} accepts the following options: - -@table @option -@item --help -Print a summary of the command-line options and exit. - -@item --version -Print the version number of GRUB and exit. -@end table - - -@node Invoking grub-mkrescue -@section Invoking grub-mkrescue - -The program @command{grub-mkrescue} generates a bootable GRUB rescue image -(@pxref{Making a GRUB bootable CD-ROM}). - -@example -grub-mkrescue -o grub.iso -@end example - -All arguments not explicitly listed as @command{grub-mkrescue} options are -passed on directly to @command{xorriso} in @command{mkisofs} emulation mode. -Options passed to @command{xorriso} will normally be interpreted as -@command{mkisofs} options; if the option @samp{--} is used, then anything -after that will be interpreted as native @command{xorriso} options. - -Non-option arguments specify additional source directories. This is -commonly used to add extra files to the image: - -@example -mkdir -p disk/boot/grub -@r{(add extra files to @file{disk/boot/grub})} -grub-mkrescue -o grub.iso disk -@end example - -@command{grub-mkrescue} accepts the following options: - -@table @option -@item --help -Print a summary of the command-line options and exit. - -@item --version -Print the version number of GRUB and exit. - -@item -o @var{file} -@itemx --output=@var{file} -Save output in @var{file}. This "option" is required. - -@item --modules=@var{modules} -Pre-load the named GRUB modules in the image. Multiple entries in -@var{modules} should be separated by whitespace (so you will probably need -to quote this for your shell). - -@item --rom-directory=@var{dir} -If generating images for the QEMU or Coreboot platforms, copy the resulting -@file{qemu.img} or @file{coreboot.elf} files respectively to the @var{dir} -directory as well as including them in the image. - -@item --xorriso=@var{file} -Use @var{file} as the @command{xorriso} program, rather than the built-in -default. - -@item --grub-mkimage=@var{file} -Use @var{file} as the @command{grub-mkimage} program, rather than the -built-in default. -@end table - - -@node Invoking grub-mount -@section Invoking grub-mount - -The program @command{grub-mount} performs a read-only mount of any file -system or file system image that GRUB understands, using GRUB's file system -drivers via FUSE. (It is only available if FUSE development files were -present when GRUB was built.) This has a number of uses: - -@itemize @bullet -@item -It provides a convenient way to check how GRUB will view a file system at -boot time. You can use normal command-line tools to compare that view with -that of your operating system, making it easy to find bugs. - -@item -It offers true read-only mounts. Linux does not have these for journalling -file systems, because it will always attempt to replay the journal at mount -time; while you can temporarily mark the block device read-only to avoid -this, that causes the mount to fail. Since GRUB intentionally contains no -code for writing to file systems, it can easily provide a guaranteed -read-only mount mechanism. - -@item -It allows you to examine any file system that GRUB understands without -needing to load additional modules into your running kernel, which may be -useful in constrained environments such as installers. - -@item -Since it can examine file system images (contained in regular files) just as -easily as file systems on block devices, you can use it to inspect any file -system image that GRUB understands with only enough privileges to use FUSE, -even if nobody has yet written a FUSE module specifically for that file -system type. -@end itemize - -Using @command{grub-mount} is normally as simple as: - -@example -grub-mount /dev/sda1 /mnt -@end example - -@command{grub-mount} must be given one or more images and a mount point as -non-option arguments (if it is given more than one image, it will treat them -as a RAID set), and also accepts the following options: - -@table @option -@item --help -Print a summary of the command-line options and exit. - -@item --version -Print the version number of GRUB and exit. - -@item -C -@itemx --crypto -Mount encrypted devices, prompting for a passphrase if necessary. - -@item -d @var{string} -@itemx --debug=@var{string} -Show debugging output for conditions matching @var{string}. - -@item -K prompt|@var{file} -@itemx --zfs-key=prompt|@var{file} -Load a ZFS encryption key. If you use @samp{prompt} as the argument, -@command{grub-mount} will read a passphrase from the terminal; otherwise, it -will read key material from the specified file. - -@item -r @var{device} -@itemx --root=@var{device} -Set the GRUB root device to @var{device}. You do not normally need to set -this; @command{grub-mount} will automatically set the root device to the -root of the supplied file system. - -If @var{device} is just a number, then it will be treated as a partition -number within the supplied image. This means that, if you have an image of -an entire disk in @file{disk.img}, then you can use this command to mount -its second partition: - -@example -grub-mount -r 2 disk.img mount-point -@end example - -@item -v -@itemx --verbose -Print verbose messages. -@end table - - -@node Invoking grub-probe -@section Invoking grub-probe - -The program @command{grub-probe} probes device information for a given path -or device. - -@example -grub-probe --target=fs /boot/grub -grub-probe --target=drive --device /dev/sda1 -@end example - -@command{grub-probe} must be given a path or device as a non-option -argument, and also accepts the following options: - -@table @option -@item --help -Print a summary of the command-line options and exit. - -@item --version -Print the version number of GRUB and exit. - -@item -d -@itemx --device -If this option is given, then the non-option argument is a system device -name (such as @samp{/dev/sda1}), and @command{grub-probe} will print -information about that device. If it is not given, then the non-option -argument is a filesystem path (such as @samp{/boot/grub}), and -@command{grub-probe} will print information about the device containing that -part of the filesystem. - -@item -m @var{file} -@itemx --device-map=@var{file} -Use @var{file} as the device map (@pxref{Device map}) rather than the -default, usually @samp{/boot/grub/device.map}. - -@item -t @var{target} -@itemx --target=@var{target} -Print information about the given path or device as defined by @var{target}. -The available targets and their meanings are: - -@table @samp -@item fs -GRUB filesystem module. -@item fs_uuid -Filesystem Universally Unique Identifier (UUID). -@item fs_label -Filesystem label. -@item drive -GRUB device name. -@item device -System device name. -@item partmap -GRUB partition map module. -@item abstraction -GRUB abstraction module (e.g. @samp{lvm}). -@item cryptodisk_uuid -Crypto device UUID. -@item msdos_parttype -MBR partition type code (two hexadecimal digits). -@item hints_string -A string of platform search hints suitable for passing to the -@command{search} command (@pxref{search}). -@item bios_hints -Search hints for the PC BIOS platform. -@item ieee1275_hints -Search hints for the IEEE1275 platform. -@item baremetal_hints -Search hints for platforms where disks are addressed directly rather than -via firmware. -@item efi_hints -Search hints for the EFI platform. -@item arc_hints -Search hints for the ARC platform. -@item compatibility_hint -A guess at a reasonable GRUB drive name for this device, which may be -used as a fallback if the @command{search} command fails. -@item disk -System device name for the whole disk. -@end table - -@item -v -@itemx --verbose -Print verbose messages. -@end table - - -@node Invoking grub-protect -@section Invoking grub-protect - -The program @command{grub-protect} protects a disk encryption key with -a specified key protector. - -@table @option -@item --help -Print a summary of the command-line options and exit. - -@item --version -Print the version number of GRUB and exit. - -@item -a add|remove -@itemx --action=add|remove -Add or remove a key protector to or from a key. - -@item -p @var{protector} -@itemx --protector=@var{protector} -Set the key protector. Currently, @samp{tpm2} is the only supported key -protector. - -@item --tpm2-asymmetric=@var{type} -Choose the the type of SRK. The valid options are @samp{RSA} (@samp{RSA2048}) -and @samp{ECC} (@samp{ECC_NIST_P256}).(default: @samp{ECC}) - -@item --tpm2-bank=@var{alg} -Choose bank of PCRs used to authorize key release: @samp{SHA1}, @samp{SHA256}, -@samp{SHA384}, or @samp{SHA512}. (default: @samp{SHA256}) - -@item --tpm2-device=@var{device} -Set the path to the TPM2 device. (default: @samp{/dev/tpm0}) - -@item --tpm2-evict -Evict a previously persisted SRK from the TPM, if any. - -@item --tpm2-keyfile=@var{file} -Set the path to a file that contains the cleartext key to protect. - -@item --tpm2-outfile=@var{file} -Set the path to the file that will contain the key after sealing -(must be accessible to GRUB during boot). - -@item --tpm2-pcrs=@var{pcrs} -Set a comma-separated list of PCRs used to authorize key release e.g., @samp{7,11}. -Please be aware that PCR 0~7 are used by the firmware and the measurement result -may change after a firmware update (for baremetal systems) or a package -(OVMF/SLOF) update in the VM host. This may lead to the failure of key -unsealing. (default: @samp{7}) - -@item --tpm2-srk=@var{handle} -Set the SRK handle, e.g. @samp{0x81000000}, if the SRK is to be made persistent. - -@item --tpm2-nvindex=@var{handle} -Set the handle, e.g. @samp{0x81000000} or @samp{0x1000000}, for NV index mode. - -@item --tpm2key -Use TPM 2.0 Key File format. - -@end table - -@subsection 'Add' action - -Before sealing the key, please check the TPM PCR usage -(@pxref{TPM2 key protector, TPM PCR usage}) to choose a proper set of PCRs. - -Assume that there is a key file, @file{luks.key}, to be sealed with PCR 0, 2, -4, and 7, and here is the @command{grub-protect} command to create the sealed -key file: - -@example -@group -# @kbd{grub-protect --action=add \ - --protector=tpm2 \ - --tpm2-pcrs=0,2,4,7 \ - --tpm2key \ - --tpm2-keyfile=luks.key \ - --tpm2-outfile=/boot/efi/efi/grub/sealed.tpm} -@end group -@end example - -Then, GRUB can unlock the target partition with the following commands: - -@example -grub> @kbd{tpm2_key_protector_init -T (hd0,gpt1)/efi/grub/sealed.tpm} -grub> @kbd{cryptomount -u -P tpm2} -@end example - -Besides writing the PCR-sealed key into a file, @command{grub-protect} can -write the sealed key into TPM non-volatile memory. Here is the -@command{grub-protect} command to write the sealed key into the NV index -handle @samp{0x1000000}. - -@example -@group -# @kbd{grub-protect --action=add \ - --protector=tpm2 \ - --tpm2-pcrs=0,2,4,7 \ - --tpm2key \ - --tpm2-keyfile=luks.key \ - --tpm2-nvindex=0x1000000} -@end group -@end example - -Later, GRUB can fetch the key from @samp{0x1000000}. - -@example -grub> @kbd{tpm2_key_protector_init --mode=nv --nvindex=0x1000000} -grub> @kbd{cryptomount -u -P tpm2} -@end example - -In most of cases, the user only needs to create the key with the `add' action. -If auto-unlocking is unwanted, just remove the file and the -@command{tpm2_key_protector_init} command and invoke the @command{cryptomount} -command without @kbd{-P tpm2}. - -@subsection 'Remove' action - -The `remove' action is used to remove the handles for NV index mode and the -persistent SRK. - -@subsubsection Handles for NV index mode - -There are two types of TPM handles supported by NV index mode: persistent -handles and NV index handles, and @command{tpm2_getcap} can be used to -check the existing handles. - -To display the list of existing persistent handles: - -@example -@group -# @kbd{tpm2_getcap handles-persistent} -- 0x81000000 -@end group -@end example - -Similarly, to display the list of existing NV index handles: - -@example -@group -# @kbd{tpm2_getcap handles-nv-index} -- 0x1000000 -@end group -@end example - -If the sealed key at an NV index handle is not needed anymore, the user can -remove the handle with @kbd{--tpm2-nvindex} and @kbd{--tpm2-evict}. For -example, this command removes the data from NV index @samp{0x1000000}: - -@example -@group -# @kbd{grub-protect --action=remove \ - --protector=tpm2 \ - --tpm2-evict \ - --tpm2-nvindex 0x1000000} \ -@end group -@end example - -@subsubsection Persistent SRK - -There are two supported SRKs in @command{grub-protect}: @samp{RSA} and @samp{ECC}. -Due to slower key generation, some users of the @samp{RSA} SRK may prefer -making it persistent so that the TPM can skip the SRK generation when GRUB tries -to unseal the key. - -The available persistent handles can be checked with @command{tpm2_getcap}. - -@example -@group -# @kbd{tpm2_getcap properties-variable} -... -TPM2_PT_HR_PERSISTENT: 0x0 -TPM2_PT_HR_PERSISTENT_AVAIL: 0x41 -... -@end group -@end example - -In this system, there is no persistent handle. A TPM handle is an unsigned -32-bit integer, and the persistent handles starts with @samp{0x81}. Here -we choose the well-known persistent handle: @samp{0x81000000}. - -@example -@group -# @kbd{grub-protect --action=add \ - --protector=tpm2 \ - --tpm2-pcrs=0,2,4,7 \ - --tpm2-asymmetric=RSA \ - --tpm2-srk=0x81000000 \ - --tpm2key \ - --tpm2-keyfile=luks.key \ - --tpm2-outfile=/boot/efi/efi/grub/sealed.tpm} -@end group -@end example - -The additional @kbd{--tpm2-asymmetric=RSA} and @kbd{--tpm2-srk=0x81000000} -options are used to make the key sealed with the RSA SRK and store the SRK -in @samp{0x81000000}. - -For the @command{tpm2_key_protector_init} command, the additional @kbd{-s 0x81000000} -informs the TPM2 key protector to fetch the SRK from @samp{0x81000000}. - -@example -grub> @kbd{tpm2_key_protector_init -s 0x81000000 -T (hd0,gpt1)/efi/grub/sealed.tpm} -grub> @kbd{cryptomount -u -P tpm2} -@end example - -After making the SRK handle persistent, we can check the status of the -persistent handles with @command{tpm2_getcap}. - -@example -@group -# @kbd{tpm2_getcap properties-variable} -... -TPM2_PT_HR_PERSISTENT: 0x1 -TPM2_PT_HR_PERSISTENT_AVAIL: 0x40 -... -# @kbd{tpm2_getcap handles-persistent} -- 0x81000000 -@end group -@end example - -The sealed key can be removed once the user does not want to use the TPM2 key -protector anymore. Here is the command to remove the persistent SRK handle -(@samp{0x81000000}) with @kbd{--tpm2-srk} and @kbd{--tpm2-evict}. - -@example -@group -# @kbd{grub-protect --action=remove \ - --protector=tpm2 \ - --tpm2-srk 0x81000000 \ - --tpm2-evict} -@end group -@end example - - -@node Invoking grub-script-check -@section Invoking grub-script-check - -The program @command{grub-script-check} takes a GRUB script file -(@pxref{Shell-like scripting}) and checks it for syntax errors, similar to -commands such as @command{sh -n}. It may take a @var{path} as a non-option -argument; if none is supplied, it will read from standard input. - -@example -grub-script-check /boot/grub/grub.cfg -@end example - -@command{grub-script-check} accepts the following options: - -@table @option -@item --help -Print a summary of the command-line options and exit. - -@item --version -Print the version number of GRUB and exit. - -@item -v -@itemx --verbose -Print each line of input after reading it. @end table @@ -10461,11 +1461,11 @@ how to get the latest version. @end quotation GRUB is available from the GNU alpha archive site -@uref{ftp://ftp.gnu.org/gnu/grub} or any of its mirrors. The file +@uref{ftp://alpha.gnu.org/gnu/grub} or any of its mirrors. The file will be named grub-version.tar.gz. The current version is @value{VERSION}, so the file you should grab is: -@uref{ftp://ftp.gnu.org/gnu/grub/grub-@value{VERSION}.tar.gz} +@uref{ftp://alpha.gnu.org/gnu/grub/grub-@value{VERSION}.tar.gz} To unbundle GRUB use the instruction: @@ -10486,9 +1486,8 @@ just do: @end group @end example -Also, the latest version is available using Git. See -@uref{http://www.gnu.org/software/grub/grub-download.html} for more -information. +Also, the latest version is available from the SVN. See +@uref{http://savannah.gnu.org/svn/?group=grub} for more information. @node Reporting bugs @appendix Reporting bugs @@ -10540,7 +1539,7 @@ for. @item Write down anything that you think might be related. Please understand -that we often need to reproduce the same problem you encountered in our +that we often need to reproduce the same problem you encounterred in our environment. So your information should be sufficient for us to do the same thing---Don't forget that we cannot see your computer directly. If you are not sure whether to state a fact or leave it out, state it! @@ -10560,13 +1559,12 @@ Once we get your report, we will try to fix the bugs. @node Future @appendix Where GRUB will go -GRUB 2 is now quite stable and used in many production systems. We are -currently working towards a 2.0 release. - -If you are interested in the development of GRUB 2, take a look at -@uref{http://www.gnu.org/software/grub/grub.html, the homepage}. - - +We started the next generation of GRUB, GRUB 2. GRUB 2 includes +internationalization, dynamic module loading, real memory management, +multiple architecture support, a scripting language, and many other +nice feature. If you are interested in the development of GRUB 2, take +a look at @uref{http://www.gnu.org/software/grub/grub.html, the +homepage}. diff --git a/docs/man/grub-bios-setup.h2m b/docs/man/grub-bios-setup.h2m deleted file mode 100644 index ac6ede362..000000000 --- a/docs/man/grub-bios-setup.h2m +++ /dev/null @@ -1,6 +0,0 @@ -[NAME] -grub-bios-setup \- set up a device to boot using GRUB -[SEE ALSO] -.BR grub-install (8), -.BR grub-mkimage (1), -.BR grub-mkrescue (1) diff --git a/docs/man/grub-editenv.h2m b/docs/man/grub-editenv.h2m deleted file mode 100644 index 3859d3d4c..000000000 --- a/docs/man/grub-editenv.h2m +++ /dev/null @@ -1,5 +0,0 @@ -[NAME] -grub-editenv \- edit GRUB environment block -[SEE ALSO] -.BR grub-reboot (8), -.BR grub-set-default (8) diff --git a/docs/man/grub-emu.h2m b/docs/man/grub-emu.h2m deleted file mode 100644 index ef1c00065..000000000 --- a/docs/man/grub-emu.h2m +++ /dev/null @@ -1,6 +0,0 @@ -[NAME] -grub-emu \- GRUB emulator -[SEE ALSO] -If you are trying to install GRUB, then you should use -.BR grub-install (8) -rather than this program. diff --git a/docs/man/grub-file.h2m b/docs/man/grub-file.h2m deleted file mode 100644 index e09bb4d31..000000000 --- a/docs/man/grub-file.h2m +++ /dev/null @@ -1,2 +0,0 @@ -[NAME] -grub-file \- check file type diff --git a/docs/man/grub-fstest.h2m b/docs/man/grub-fstest.h2m deleted file mode 100644 index 9676b159a..000000000 --- a/docs/man/grub-fstest.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-fstest \- debug tool for GRUB filesystem drivers -[SEE ALSO] -.BR grub-probe (8) diff --git a/docs/man/grub-glue-efi.h2m b/docs/man/grub-glue-efi.h2m deleted file mode 100644 index c1c6ded49..000000000 --- a/docs/man/grub-glue-efi.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-glue-efi \- generate a fat binary for EFI -[DESCRIPTION] -grub-glue-efi processes ia32 and amd64 EFI images and glues them according to Apple format. diff --git a/docs/man/grub-install.h2m b/docs/man/grub-install.h2m deleted file mode 100644 index 8cbbc87a0..000000000 --- a/docs/man/grub-install.h2m +++ /dev/null @@ -1,6 +0,0 @@ -[NAME] -grub-install \- install GRUB to a device -[SEE ALSO] -.BR grub-mkconfig (8), -.BR grub-mkimage (1), -.BR grub-mkrescue (1) diff --git a/docs/man/grub-kbdcomp.h2m b/docs/man/grub-kbdcomp.h2m deleted file mode 100644 index d81f9157e..000000000 --- a/docs/man/grub-kbdcomp.h2m +++ /dev/null @@ -1,10 +0,0 @@ -[NAME] -grub-kbdcomp \- generate a GRUB keyboard layout file -[DESCRIPTION] -grub-kbdcomp processes a X keyboard layout description in -.BR keymaps (5) -format into a format that can be used by GRUB's -.B keymap -command. -[SEE ALSO] -.BR grub-mklayout (8) diff --git a/docs/man/grub-macbless.h2m b/docs/man/grub-macbless.h2m deleted file mode 100644 index 0197c0087..000000000 --- a/docs/man/grub-macbless.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-macbless \- bless a mac file/directory -[SEE ALSO] -.BR grub-install (1) diff --git a/docs/man/grub-macho2img.h2m b/docs/man/grub-macho2img.h2m deleted file mode 100644 index d79aaeed8..000000000 --- a/docs/man/grub-macho2img.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-macho2img \- convert Mach-O to raw image -[SEE ALSO] -.BR grub-mkimage (1) diff --git a/docs/man/grub-menulst2cfg.h2m b/docs/man/grub-menulst2cfg.h2m deleted file mode 100644 index c2e0055ed..000000000 --- a/docs/man/grub-menulst2cfg.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-menulst2cfg \- transform legacy menu.lst into grub.cfg -[SEE ALSO] -.BR grub-mkconfig (8) diff --git a/docs/man/grub-mkconfig.h2m b/docs/man/grub-mkconfig.h2m deleted file mode 100644 index 9b42f8130..000000000 --- a/docs/man/grub-mkconfig.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-mkconfig \- generate a GRUB configuration file -[SEE ALSO] -.BR grub-install (8) diff --git a/docs/man/grub-mkfont.h2m b/docs/man/grub-mkfont.h2m deleted file mode 100644 index d46fe600e..000000000 --- a/docs/man/grub-mkfont.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-mkfont \- make GRUB font files -[SEE ALSO] -.BR grub-mkconfig (8) diff --git a/docs/man/grub-mkimage.h2m b/docs/man/grub-mkimage.h2m deleted file mode 100644 index f0fbc2bb1..000000000 --- a/docs/man/grub-mkimage.h2m +++ /dev/null @@ -1,6 +0,0 @@ -[NAME] -grub-mkimage \- make a bootable image of GRUB -[SEE ALSO] -.BR grub-install (8), -.BR grub-mkrescue (1), -.BR grub-mknetdir (8) diff --git a/docs/man/grub-mklayout.h2m b/docs/man/grub-mklayout.h2m deleted file mode 100644 index 1e43409c0..000000000 --- a/docs/man/grub-mklayout.h2m +++ /dev/null @@ -1,10 +0,0 @@ -[NAME] -grub-mklayout \- generate a GRUB keyboard layout file -[DESCRIPTION] -grub-mklayout processes a keyboard layout description in -.BR keymaps (5) -format into a format that can be used by GRUB's -.B keymap -command. -[SEE ALSO] -.BR grub-mkconfig (8) diff --git a/docs/man/grub-mknetdir.h2m b/docs/man/grub-mknetdir.h2m deleted file mode 100644 index a2ef13ec1..000000000 --- a/docs/man/grub-mknetdir.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-mknetdir \- prepare a GRUB netboot directory. -[SEE ALSO] -.BR grub-mkimage (1) diff --git a/docs/man/grub-mkpasswd-pbkdf2.h2m b/docs/man/grub-mkpasswd-pbkdf2.h2m deleted file mode 100644 index 4d202f3da..000000000 --- a/docs/man/grub-mkpasswd-pbkdf2.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-mkpasswd-pbkdf2 \- generate hashed password for GRUB -[SEE ALSO] -.BR grub-mkconfig (8) diff --git a/docs/man/grub-mkrelpath.h2m b/docs/man/grub-mkrelpath.h2m deleted file mode 100644 index d01f3961e..000000000 --- a/docs/man/grub-mkrelpath.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-mkrelpath \- make a system path relative to its root -[SEE ALSO] -.BR grub-probe (8) diff --git a/docs/man/grub-mkrescue.h2m b/docs/man/grub-mkrescue.h2m deleted file mode 100644 index a427f02e3..000000000 --- a/docs/man/grub-mkrescue.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-mkrescue \- make a GRUB rescue image -[SEE ALSO] -.BR grub-mkimage (1) diff --git a/docs/man/grub-mkstandalone.h2m b/docs/man/grub-mkstandalone.h2m deleted file mode 100644 index c77313978..000000000 --- a/docs/man/grub-mkstandalone.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-mkstandalone \- make a memdisk-based GRUB image -[SEE ALSO] -.BR grub-mkimage (1) diff --git a/docs/man/grub-mount.h2m b/docs/man/grub-mount.h2m deleted file mode 100644 index 8d168982d..000000000 --- a/docs/man/grub-mount.h2m +++ /dev/null @@ -1,2 +0,0 @@ -[NAME] -grub-mount \- export GRUB filesystem with FUSE diff --git a/docs/man/grub-ofpathname.h2m b/docs/man/grub-ofpathname.h2m deleted file mode 100644 index 74b43eea0..000000000 --- a/docs/man/grub-ofpathname.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-ofpathname \- find OpenBOOT path for a device -[SEE ALSO] -.BR grub-probe (8) diff --git a/docs/man/grub-pe2elf.h2m b/docs/man/grub-pe2elf.h2m deleted file mode 100644 index 7ca29bd70..000000000 --- a/docs/man/grub-pe2elf.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-pe2elf \- convert PE image to ELF -[SEE ALSO] -.BR grub-mkimage (1) diff --git a/docs/man/grub-probe.h2m b/docs/man/grub-probe.h2m deleted file mode 100644 index 6e1ffdcf9..000000000 --- a/docs/man/grub-probe.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-probe \- probe device information for GRUB -[SEE ALSO] -.BR grub-fstest (1) diff --git a/docs/man/grub-protect.h2m b/docs/man/grub-protect.h2m deleted file mode 100644 index ecf1c9eab..000000000 --- a/docs/man/grub-protect.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-protect \- protect a disk key with a key protector -[DESCRIPTION] -grub-protect helps to protect a disk encryption key with a specified key protector. diff --git a/docs/man/grub-reboot.h2m b/docs/man/grub-reboot.h2m deleted file mode 100644 index e4acace65..000000000 --- a/docs/man/grub-reboot.h2m +++ /dev/null @@ -1,5 +0,0 @@ -[NAME] -grub-reboot \- set the default boot entry for GRUB, for the next boot only -[SEE ALSO] -.BR grub-set-default (8), -.BR grub-editenv (1) diff --git a/docs/man/grub-render-label.h2m b/docs/man/grub-render-label.h2m deleted file mode 100644 index 50ae5247c..000000000 --- a/docs/man/grub-render-label.h2m +++ /dev/null @@ -1,3 +0,0 @@ -[NAME] -grub-render-label \- generate a .disk_label for Apple Macs. - diff --git a/docs/man/grub-script-check.h2m b/docs/man/grub-script-check.h2m deleted file mode 100644 index 365368267..000000000 --- a/docs/man/grub-script-check.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-script-check \- check grub.cfg for syntax errors -[SEE ALSO] -.BR grub-mkconfig (8) diff --git a/docs/man/grub-set-default.h2m b/docs/man/grub-set-default.h2m deleted file mode 100644 index 7945001c1..000000000 --- a/docs/man/grub-set-default.h2m +++ /dev/null @@ -1,5 +0,0 @@ -[NAME] -grub-set-default \- set the saved default boot entry for GRUB -[SEE ALSO] -.BR grub-reboot (8), -.BR grub-editenv (1) diff --git a/docs/man/grub-sparc64-setup.h2m b/docs/man/grub-sparc64-setup.h2m deleted file mode 100644 index 18f803a50..000000000 --- a/docs/man/grub-sparc64-setup.h2m +++ /dev/null @@ -1,6 +0,0 @@ -[NAME] -grub-sparc64-setup \- set up a device to boot using GRUB -[SEE ALSO] -.BR grub-install (8), -.BR grub-mkimage (1), -.BR grub-mkrescue (1) diff --git a/docs/man/grub-syslinux2cfg.h2m b/docs/man/grub-syslinux2cfg.h2m deleted file mode 100644 index ad25c8ab7..000000000 --- a/docs/man/grub-syslinux2cfg.h2m +++ /dev/null @@ -1,4 +0,0 @@ -[NAME] -grub-syslinux2cfg \- transform syslinux config into grub.cfg -[SEE ALSO] -.BR grub-menulst2cfg (8) diff --git a/docs/osdetect.cfg b/docs/osdetect.cfg deleted file mode 100644 index 47455601d..000000000 --- a/docs/osdetect.cfg +++ /dev/null @@ -1,331 +0,0 @@ -# Sample GRUB script to autodetect operating systems -# -# 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 . - -set saved_root=$root - -function freebsd_ufs_variants { - set device=$1 - set fstype=$2 - set uuid=$3 - - menuentry "FreeBSD (on $fstype $device)" $device $uuid { - set root=$2 - set uuid=$3 - - freebsd /boot/kernel/kernel - set FreeBSD.acpi_load=YES - set FreeBSD.hint.acpi.0.disabled=0 - set FreeBSD.vfs.root.mountfrom=ufs:ufsid/$uuid - frebsd_loadenv /boot/device.hints - } - - menuentry "FreeBSD (on $fstype $device) (single)" $device $uuid { - set root=$2 - set uuid=$3 - - freebsd /boot/kernel/kernel --single - set FreeBSD.acpi_load=YES - set FreeBSD.hint.acpi.0.disabled=0 - set FreeBSD.vfs.root.mountfrom=ufs:ufsid/$uuid - frebsd_loadenv /boot/device.hints - } - - menuentry "FreeBSD (on $fstype $device) (verbose)" $device $uuid { - set root=$2 - set uuid=$3 - - freebsd /boot/kernel/kernel --verbose - set FreeBSD.acpi_load=YES - set FreeBSD.hint.acpi.0.disabled=0 - set FreeBSD.vfs.root.mountfrom=ufs:ufsid/$uuid - frebsd_loadenv /boot/device.hints - } - - menuentry "FreeBSD (on $fstype $device) (without ACPI)" $device $uuid { - set root=$2 - set uuid=$3 - - freebsd /boot/kernel/kernel --verbose - unset FreeBSD.acpi_load - set FreeBSD.hint.acpi.0.disabled=1 - set FreeBSD.loader.acpi_disabled_by_user=1 - set FreeBSD.vfs.root.mountfrom=ufs:ufsid/$uuid - frebsd_loadenv /boot/device.hints - } - - menuentry "FreeBSD (on $fstype $device) (safe mode)" $device $uuid { - set root=$2 - set uuid=$3 - - freebsd /boot/kernel/kernel --verbose - unset FreeBSD.acpi_load - set FreeBSD.hint.acpi.0.disabled=1 - set FreeBSD.loader.acpi_disabled_by_user=1 - set FreeBSD.hint.apic.0.disabled=1 - set FreeBSD.hw.ata.ata_dma=0 - set FreeBSD.hw.ata.atapi_dma=0 - set FreeBSD.hw.ata.wc=0 - set FreeBSD.hw.eisa_slots=0 - set FreeBSD.hint.kbdmux.0.disabled=1 - set FreeBSD.vfs.root.mountfrom=ufs:ufsid/$uuid - frebsd_loadenv /boot/device.hints - } -} - -function freebsd_zfs_variants { - set device=$1 - set fstype=zfs - - menuentry "FreeBSD (on $fstype $device)" $device { - set root=$2 - - freebsd /@/boot/kernel/kernel - set FreeBSD.acpi_load=YES - set FreeBSD.hint.acpi.0.disabled=0 - freebsd_module_elf /@/boot/kernel/opensolaris.ko - freebsd_module_elf /@/boot/kernel/zfs.ko - freebsd_module /@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache - probe -l -s name $root - set FreeBSD.vfs.root.mountfrom=zfs:$name - freebsd_loadenv /@/boot/device.hints - } - - menuentry "FreeBSD (on $fstype $device) (single)" $device { - set root=$2 - - freebsd /@/boot/kernel/kernel --single - set FreeBSD.acpi_load=YES - set FreeBSD.hint.acpi.0.disabled=0 - freebsd_module_elf /@/boot/kernel/opensolaris.ko - freebsd_module_elf /@/boot/kernel/zfs.ko - freebsd_module /@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache - probe -l -s name $root - set FreeBSD.vfs.root.mountfrom=zfs:$name - freebsd_loadenv /@/boot/device.hints - } - - menuentry "FreeBSD (on $fstype $device) (verbose)" $device { - set root=$2 - - freebsd /@/boot/kernel/kernel --verbose - set FreeBSD.acpi_load=YES - set FreeBSD.hint.acpi.0.disabled=0 - freebsd_module_elf /@/boot/kernel/opensolaris.ko - freebsd_module_elf /@/boot/kernel/zfs.ko - freebsd_module /@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache - probe -l -s name $root - set FreeBSD.vfs.root.mountfrom=zfs:$name - freebsd_loadenv /@/boot/device.hints - } - - menuentry "FreeBSD (on $fstype $device) (without ACPI)" $device { - set root=$2 - - freebsd /@/boot/kernel/kernel --verbose - unset FreeBSD.acpi_load - set FreeBSD.hint.acpi.0.disabled=1 - set FreeBSD.loader.acpi_disabled_by_user=1 - freebsd_module_elf /@/boot/kernel/opensolaris.ko - freebsd_module_elf /@/boot/kernel/zfs.ko - freebsd_module /@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache - probe -l -s name $root - set FreeBSD.vfs.root.mountfrom=zfs:$name - freebsd_loadenv /@/boot/device.hints - } - - menuentry "FreeBSD (on $fstype $device) (safe mode)" $device { - set root=$2 - - freebsd /@/boot/kernel/kernel --verbose - unset FreeBSD.acpi_load - set FreeBSD.hint.acpi.0.disabled=1 - set FreeBSD.loader.acpi_disabled_by_user=1 - set FreeBSD.hint.apic.0.disabled=1 - set FreeBSD.hw.ata.ata_dma=0 - set FreeBSD.hw.ata.atapi_dma=0 - set FreeBSD.hw.ata.wc=0 - set FreeBSD.hw.eisa_slots=0 - set FreeBSD.hint.kbdmux.0.disabled=1 - freebsd_module_elf /@/boot/kernel/opensolaris.ko - freebsd_module_elf /@/boot/kernel/zfs.ko - freebsd_module /@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache - probe -l -s name $root - set FreeBSD.vfs.root.mountfrom=zfs:$name - freebsd_loadenv /@/boot/device.hints - } -} - -insmod regexp -for dev in (*); do - # $device: parenthesis removed from $dev - regexp -s device '\((.*)\)' $dev - # $fstype: filesystem type identified - probe -s fstype -f $dev - # uuid: filesystem UUID - probe -s uuid -u $dev - - if test -f ($device)/isolinux/isolinux.cfg ; then - menuentry "ISOLINUX config (on $device)" $device { - set root=$2 - syslinux_configfile -i /isolinux/isolinux.cfg - } - fi - if test -f ($device)/bootmgr -a -f ($device)/boot/bcd; then - menuentry "Windows Vista bootmgr (on $device)" $device { - set root=$2 - chainloader +1 - } - elif test -f ($device)/ntldr -a \ - -e ($device)/ntdetect.com -a -f ($device)/boot.ini; then - menuentry "Windows NT/2000/XP loader (on $device)" $device { - set root=$2 - regexp -s devnum 'hd([0-9]+)' $root - if test "$devnum" != "0"; then - drivemap -s hd0 $root - fi - chainloader +1 - } - elif test -f ($device)/windows/win.com; then - menuentry "Windows 98/ME (on $device)" $device { - set root=$2 - regexp -s devnum 'hd([0-9]+)' $root - if test "$devnum" != "0"; then - drivemap -s hd0 $root - fi - chainloader +1 - } - elif test -f ($device)/io.sys -a -f ($device)/command.com; then - menuentry "MS-DOS (on $device)" $device { - set root=$2 - regexp -s devnum 'hd([0-9]+)' $root - if test "$devnum" != "0"; then - drivemap -s hd0 $root - fi - chainloader +1 - } - elif test -f ($device)/kernel.sys; then - menuentry "FreeDOS (on $device)" $device { - set root=$2 - regexp -s type '([fh])d[0-9]+' $root - regexp -s devnum '[fh]d([0-9]+)' $root - if test $type = 'h' -a "$devnum" != "0"; then - drivemap -s hd0 $root - fi - chainloader +1 - } - elif test "$fstype" = ufs1 -o "$fstype" = ufs2 -a \ - -e ($device)/boot/kernel/kernel -a \ - -e ($device)/boot/device.hints; then - - freebsd_ufs_variants $device $fstype $uuid - - elif test "$fstype" = zfs -a \ - -e ($device)/@/boot/kernel/kernel -a \ - -e ($device)/@/boot/device.hints; then - - freebsd_zfs_variants $device - - elif test "$fstype" = hfsplus -a -f ($device)/mach_kernel; then - menuentry "Mac OS X/Darwin" $device $uuid { - set root=$2 - set uuid=$3 - - insmod vbe - do_resume=0 - if [ /var/vm/sleepimage -nt10 / ]; then - if xnu_resume /var/vm/sleepimage; then - do_resume=1 - fi - fi - if [ $do_resume = 1 ]; then - xnu_uuid $uuid uuid - if [ -f /Extra/DSDT.aml ]; then - acpi -e /Extra/DSDT.aml - fi - xnu_kernel /mach_kernel boot-uuid=${uuid} rd=*uuid - if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then - xnu_mkext /System/Library/Extensions.mkext - else - xnu_mkext /System/Library/Extensions - fi - if [ -f /Extra/Extensions.mkext ]; then - xnu_mkext /Extra/Extensions.mkext - fi - if [ -d /Extra/Extensions ]; then - xnu_kextdir /Extra/Extensions - fi - if [ -f /Extra/devtree.txt ]; then - xnu_devtree /Extra/devtree.txt - fi - if [ -f /Extra/splash.jpg ]; then - insmod jpeg - xnu_splash /Extra/splash.jpg - fi - if [ -f /Extra/splash.png ]; then - insmod png - xnu_splash /Extra/splash.png - fi - if [ -f /Extra/splash.tga ]; then - insmod tga - xnu_splash /Extra/splash.tga - fi - fi - } - else - set root=$device - for file in /boot/vmlinuz-* /boot/linux-*; do - if test -f $file; then - regexp -s version '/boot/vmlinuz-(.*)' $file - regexp -s version '/boot/linux-(.*)' $file - - menuentry "Linux $file" $device $uuid $file $version { - set root=$2 - set uuid=$3 - set kernel=$4 - set version=$5 - - linux $kernel root=UUID=$uuid ro - if test -f /boot/initrd-$version.img; then - initrd /boot/initrd-$version.img - elif test -f /boot/initrd.img-$version; then - initrd /boot/initrd.img-$version - elif test -f /boot/initrd-$version; then - initrd /boot/initrd-$version - fi - } - - menuentry "Linux $file (single)" $device $uuid $file $version { - set root=$2 - set uuid=$3 - set kernel=$4 - set version=$5 - - linux $kernel root=UUID=$uuid ro single - if test -f /boot/initrd-$version.img; then - initrd /boot/initrd-$version.img - elif test -f /boot/initrd.img-$version; then - initrd /boot/initrd.img-$version - elif test -f /boot/initrd-$version; then - initrd /boot/initrd-$version - fi - } - fi - done - fi -done - -set root=$saved_root diff --git a/efiemu/i386/coredetect.c b/efiemu/i386/coredetect.c new file mode 100644 index 000000000..828508dee --- /dev/null +++ b/efiemu/i386/coredetect.c @@ -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 . + */ + +#include +#include +#include + +#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/efiemu/i386/loadcore32.c similarity index 82% rename from grub-core/efiemu/i386/loadcore32.c rename to efiemu/i386/loadcore32.c index e746df8df..24b63ec98 100644 --- a/grub-core/efiemu/i386/loadcore32.c +++ b/efiemu/i386/loadcore32.c @@ -23,7 +23,6 @@ #include #include #include -#include /* Check if EHDR is a valid ELF header. */ int @@ -87,29 +86,23 @@ grub_arch_efiemu_relocate_symbols32 (grub_efiemu_segment_t segs, switch (ELF32_R_TYPE (rel->r_info)) { case R_386_32: - err = grub_efiemu_write_value (addr, sym.off + *addr, - sym.handle, 0, - seg->ptv_rel_needed, - sizeof (grub_uint32_t)); - if (err) + 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: - 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)); - if (err) + 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_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - ELF_R_TYPE (rel->r_info)); + return grub_error (GRUB_ERR_BAD_OS, + "unrecognised relocation"); } } } diff --git a/grub-core/efiemu/i386/loadcore64.c b/efiemu/i386/loadcore64.c similarity index 74% rename from grub-core/efiemu/i386/loadcore64.c rename to efiemu/i386/loadcore64.c index ae476ef2c..a69279077 100644 --- a/grub-core/efiemu/i386/loadcore64.c +++ b/efiemu/i386/loadcore64.c @@ -23,7 +23,6 @@ #include #include #include -#include /* Check if EHDR is a valid ELF header. */ int @@ -88,47 +87,30 @@ grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs, switch (ELF64_R_TYPE (rel->r_info)) { case R_X86_64_64: - err = grub_efiemu_write_value (addr, - *addr64 + rel->r_addend - + sym.off, sym.handle, - 0, seg->ptv_rel_needed, - sizeof (grub_uint64_t)); - if (err) + 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: - case R_X86_64_PLT32: - 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)); - if (err) + 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: - err = grub_efiemu_write_value (addr, - *addr32 + rel->r_addend - + sym.off, sym.handle, - 0, seg->ptv_rel_needed, - sizeof (grub_uint32_t)); - if (err) + 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: - { - char rel_info[17]; /* log16(2^64) = 16, plus NUL. */ - - grub_snprintf (rel_info, sizeof (rel_info) - 1, "%" PRIxGRUB_UINT64_T, - ELF_R_TYPE (rel->r_info)); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%s is not implemented yet"), rel_info); - } + return grub_error (GRUB_ERR_BAD_OS, + "unrecognised relocation"); } } } diff --git a/grub-core/efiemu/i386/pc/cfgtables.c b/efiemu/i386/pc/cfgtables.c similarity index 71% rename from grub-core/efiemu/i386/pc/cfgtables.c rename to efiemu/i386/pc/cfgtables.c index 056ec0bc9..9c6b4e55e 100644 --- a/grub-core/efiemu/i386/pc/cfgtables.c +++ b/efiemu/i386/pc/cfgtables.c @@ -19,19 +19,20 @@ #include #include +#include #include #include #include -#include grub_err_t -grub_machine_efiemu_init_tables (void) +grub_machine_efiemu_init_tables () { + grub_uint8_t *ptr; void *table; grub_err_t err; - static grub_guid_t smbios = GRUB_EFI_SMBIOS_TABLE_GUID; - static grub_guid_t acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID; - static grub_guid_t acpi = GRUB_EFI_ACPI_TABLE_GUID; + 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) @@ -57,11 +58,17 @@ grub_machine_efiemu_init_tables (void) if (err) return err; } - table = grub_smbios_get_eps (); - if (table) + + 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) { - err = grub_efiemu_register_configuration_table (smbios, 0, 0, table); - if (err) + grub_dprintf ("efiemu", "Registering SMBIOS\n"); + if ((err = grub_efiemu_register_configuration_table (smbios, 0, 0, ptr))) return err; } diff --git a/grub-core/efiemu/loadcore.c b/efiemu/loadcore.c similarity index 83% rename from grub-core/efiemu/loadcore.c rename to efiemu/loadcore.c index 2b924623f..4bf26ee44 100644 --- a/grub-core/efiemu/loadcore.c +++ b/efiemu/loadcore.c @@ -22,8 +22,8 @@ #include #include #include +#include #include -#include /* ELF symbols and their values */ static struct grub_efiemu_elf_sym *grub_efiemu_elfsyms = 0; @@ -120,9 +120,9 @@ 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); + for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff); i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + 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; @@ -135,9 +135,9 @@ 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); + for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff); i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize)) { if (s->sh_flags & SHF_ALLOC) { @@ -154,10 +154,7 @@ grub_efiemu_init_segments (grub_efiemu_segment_t *segs, const Elf_Ehdr *e) s->sh_flags & SHF_EXECINSTR ? GRUB_EFI_RUNTIME_SERVICES_CODE : GRUB_EFI_RUNTIME_SERVICES_DATA); if (seg->handle < 0) - { - grub_free (seg); - return grub_errno; - } + return grub_errno; seg->off = 0; } @@ -197,11 +194,11 @@ grub_efiemu_count_symbols (const Elf_Ehdr *e) break; if (i == e->e_shnum) - return grub_error (GRUB_ERR_BAD_OS, N_("no symbol table")); + 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_calloc (grub_efiemu_nelfsyms, sizeof (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); @@ -234,7 +231,7 @@ grub_efiemu_resolve_symbols (grub_efiemu_segment_t segs, Elf_Ehdr *e) break; if (i == e->e_shnum) - return grub_error (GRUB_ERR_BAD_OS, N_("no symbol table")); + return grub_error (GRUB_ERR_BAD_OS, "no symbol table"); sym = (Elf_Sym *) ((char *) e + s->sh_offset); size = s->sh_size; @@ -260,8 +257,7 @@ grub_efiemu_resolve_symbols (grub_efiemu_segment_t segs, Elf_Ehdr *e) /* Resolve a global symbol. */ if (sym->st_name != 0 && sym->st_shndx == 0) { - err = grub_efiemu_resolve_symbol (name, &handle, &off); - if (err) + if ((err = grub_efiemu_resolve_symbol (name, &handle, &off))) return err; grub_efiemu_elfsyms[i].handle = handle; grub_efiemu_elfsyms[i].off = off; @@ -271,43 +267,34 @@ grub_efiemu_resolve_symbols (grub_efiemu_segment_t segs, Elf_Ehdr *e) break; case STT_OBJECT: - err = grub_efiemu_get_section_addr (segs, sym->st_shndx, - &handle, &off); - if (err) + if ((err = grub_efiemu_get_section_addr + (segs, sym->st_shndx, &handle, &off))) return err; off += sym->st_value; if (bind != STB_LOCAL) - { - err = grub_efiemu_register_symbol (name, handle, off); - if (err) - return err; - } + 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: - err = grub_efiemu_get_section_addr (segs, sym->st_shndx, - &handle, &off); - if (err) + if ((err = grub_efiemu_get_section_addr + (segs, sym->st_shndx, &handle, &off))) return err; off += sym->st_value; if (bind != STB_LOCAL) - { - err = grub_efiemu_register_symbol (name, handle, off); - if (err) - return err; - } + 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: - err = grub_efiemu_get_section_addr (segs, sym->st_shndx, - &handle, &off); - if (err) + 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; @@ -335,26 +322,22 @@ grub_efiemu_resolve_symbols (grub_efiemu_segment_t segs, Elf_Ehdr *e) /* Load runtime to the memory and request memory for definitive location*/ grub_err_t -SUFFIX (grub_efiemu_loadcore_init) (void *core, const char *filename, - grub_size_t core_size, +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, N_("this ELF file is not of the right type")); + 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 + (grub_uint32_t) e->e_shentsize * e->e_shnum) - return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); + 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"); - err = grub_efiemu_init_segments (segments, core); - if (err) + if ((err = grub_efiemu_init_segments (segments, core))) return err; - err = grub_efiemu_count_symbols (core); - if (err) + if ((err = grub_efiemu_count_symbols (core))) return err; grub_efiemu_request_symbols (1); diff --git a/grub-core/efiemu/loadcore32.c b/efiemu/loadcore32.c similarity index 100% rename from grub-core/efiemu/loadcore32.c rename to efiemu/loadcore32.c diff --git a/grub-core/efiemu/loadcore64.c b/efiemu/loadcore64.c similarity index 100% rename from grub-core/efiemu/loadcore64.c rename to efiemu/loadcore64.c diff --git a/grub-core/efiemu/loadcore_common.c b/efiemu/loadcore_common.c similarity index 84% rename from grub-core/efiemu/loadcore_common.c rename to efiemu/loadcore_common.c index 64d79608f..a4db0ee9b 100644 --- a/grub-core/efiemu/loadcore_common.c +++ b/efiemu/loadcore_common.c @@ -111,8 +111,7 @@ grub_efiemu_loadcore_unload(void) /* Load runtime file and do some initial preparations */ grub_err_t -grub_efiemu_loadcore_init (grub_file_t file, - const char *filename) +grub_efiemu_loadcore_init (grub_file_t file) { grub_err_t err; @@ -141,10 +140,8 @@ grub_efiemu_loadcore_init (grub_file_t file, switch (grub_efiemu_mode) { case GRUB_EFIEMU32: - err = grub_efiemu_loadcore_init32 (efiemu_core, filename, - efiemu_core_size, - &efiemu_segments); - if (err) + if ((err = grub_efiemu_loadcore_init32 (efiemu_core, efiemu_core_size, + &efiemu_segments))) { grub_free (efiemu_core); efiemu_core = 0; @@ -154,10 +151,8 @@ grub_efiemu_loadcore_init (grub_file_t file, break; case GRUB_EFIEMU64: - err = grub_efiemu_loadcore_init64 (efiemu_core, filename, - efiemu_core_size, - &efiemu_segments); - if (err) + if ((err = grub_efiemu_loadcore_init64 (efiemu_core, efiemu_core_size, + &efiemu_segments))) { grub_free (efiemu_core); efiemu_core = 0; @@ -167,7 +162,7 @@ grub_efiemu_loadcore_init (grub_file_t file, break; default: - return grub_error (GRUB_ERR_BUG, "unknown EFI runtime"); + return grub_error (GRUB_ERR_BAD_OS, "unknown EFI runtime"); } return GRUB_ERR_NONE; } @@ -179,18 +174,16 @@ grub_efiemu_loadcore_load (void) switch (grub_efiemu_mode) { case GRUB_EFIEMU32: - err = grub_efiemu_loadcore_load32 (efiemu_core, efiemu_core_size, - efiemu_segments); - if (err) - grub_efiemu_loadcore_unload (); + if ((err = grub_efiemu_loadcore_load32 (efiemu_core, efiemu_core_size, + efiemu_segments))) + grub_efiemu_loadcore_unload (); return err; case GRUB_EFIEMU64: - err = grub_efiemu_loadcore_load64 (efiemu_core, efiemu_core_size, - efiemu_segments); - if (err) - grub_efiemu_loadcore_unload (); + 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_BUG, "unknown EFI runtime"); + return grub_error (GRUB_ERR_BAD_OS, "unknown EFI runtime"); } } diff --git a/grub-core/efiemu/main.c b/efiemu/main.c similarity index 82% rename from grub-core/efiemu/main.c rename to efiemu/main.c index e7037f4ed..9480bfc4d 100644 --- a/grub-core/efiemu/main.c +++ b/efiemu/main.c @@ -29,10 +29,8 @@ #include #include #include +#include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); /* System table. Two version depending on mode */ grub_efi_system_table32_t *grub_efiemu_system_table32 = 0; @@ -80,7 +78,7 @@ grub_efiemu_unload (void) /* Remove previously registered table from the list */ grub_err_t -grub_efiemu_unregister_configuration_table (grub_guid_t guid) +grub_efiemu_unregister_configuration_table (grub_efi_guid_t guid) { struct grub_efiemu_configuration_table *cur, *prev; @@ -121,9 +119,11 @@ grub_efiemu_register_prepare_hook (grub_err_t (*hook) (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_errno; + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't prepare hook"); nhook->hook = hook; nhook->unload = unload; nhook->data = data; @@ -136,7 +136,7 @@ grub_efiemu_register_prepare_hook (grub_err_t (*hook) (void *data), or with a hook */ grub_err_t -grub_efiemu_register_configuration_table (grub_guid_t guid, +grub_efiemu_register_configuration_table (grub_efi_guid_t guid, void * (*get_table) (void *data), void (*unload) (void *data), void *data) @@ -144,13 +144,15 @@ grub_efiemu_register_configuration_table (grub_guid_t guid, struct grub_efiemu_configuration_table *tbl; grub_err_t err; - err = grub_efiemu_unregister_configuration_table (guid); - if (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_errno; + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't register table"); tbl->guid = guid; tbl->get_table = get_table; @@ -180,6 +182,22 @@ grub_cmd_efiemu_prepare (grub_command_t cmd __attribute__ ((unused)), + +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) @@ -187,21 +205,21 @@ grub_efiemu_load_file (const char *filename) grub_file_t file; grub_err_t err; - file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE); + file = grub_file_open (filename); if (! file) - return grub_errno; + return 0; err = grub_efiemu_mm_init (); if (err) { grub_file_close (file); grub_efiemu_unload (); - return err; + return grub_error (grub_errno, "couldn't init memory management"); } grub_dprintf ("efiemu", "mm initialized\n"); - err = grub_efiemu_loadcore_init (file, filename); + err = grub_efiemu_loadcore_init (file); if (err) { grub_file_close (file); @@ -222,7 +240,7 @@ grub_efiemu_autocore (void) { const char *prefix; char *filename; - const char *suffix; + char *suffix; grub_err_t err; if (grub_efiemu_sizeof_uintn_t () != 0) @@ -232,20 +250,22 @@ grub_efiemu_autocore (void) if (! prefix) return grub_error (GRUB_ERR_FILE_NOT_FOUND, - N_("variable `%s' isn't set"), "prefix"); + "couldn't find efiemu core because prefix " + "isn't set"); suffix = grub_efiemu_get_default_core_name (); - filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM "/%s", - prefix, suffix); + filename = grub_xasprintf ("%s/%s", prefix, suffix); if (! filename) - return grub_errno; + 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 +#ifndef GRUB_UTIL err = grub_machine_efiemu_init_tables (); if (err) return err; @@ -262,13 +282,11 @@ grub_efiemu_prepare (void) if (prepared) return GRUB_ERR_NONE; - err = grub_efiemu_autocore (); - if (err) - return err; - grub_dprintf ("efiemu", "Preparing %d-bit efiemu\n", 8 * grub_efiemu_sizeof_uintn_t ()); + err = grub_efiemu_autocore (); + /* Create NVRAM. */ grub_efiemu_pnvram (); @@ -290,12 +308,12 @@ grub_cmd_efiemu_load (grub_command_t cmd __attribute__ ((unused)), grub_efiemu_unload (); if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "filename required"); err = grub_efiemu_load_file (args[0]); if (err) return err; -#ifndef GRUB_MACHINE_EMU +#ifndef GRUB_UTIL err = grub_machine_efiemu_init_tables (); if (err) return err; @@ -309,15 +327,15 @@ GRUB_MOD_INIT(efiemu) { cmd_loadcore = grub_register_command ("efiemu_loadcore", grub_cmd_efiemu_load, - N_("FILE"), - N_("Load and initialize EFI emulator.")); + "FILE", + "Load and initialize EFI emulator."); cmd_prepare = grub_register_command ("efiemu_prepare", grub_cmd_efiemu_prepare, 0, - N_("Finalize loading of EFI emulator.")); + "Finalize loading of EFI emulator."); cmd_unload = grub_register_command ("efiemu_unload", grub_cmd_efiemu_unload, 0, - N_("Unload EFI emulator.")); + "Unload EFI emulator."); } GRUB_MOD_FINI(efiemu) diff --git a/grub-core/efiemu/mm.c b/efiemu/mm.c similarity index 81% rename from grub-core/efiemu/mm.c rename to efiemu/mm.c index 9b8e0d0ad..6099a14ee 100644 --- a/grub-core/efiemu/mm.c +++ b/efiemu/mm.c @@ -29,8 +29,8 @@ #include #include #include +#include #include -#include struct grub_efiemu_memrequest { @@ -62,17 +62,12 @@ grub_efiemu_add_to_mmap (grub_uint64_t start, grub_uint64_t size, /* Extend map if necessary*/ if (mmap_num >= mmap_reserved_size) { - void *old; - mmap_reserved_size = 2 * (mmap_reserved_size + 1); - old = efiemu_mmap; efiemu_mmap = (grub_efi_memory_descriptor_t *) - grub_realloc (efiemu_mmap, mmap_reserved_size + grub_realloc (efiemu_mmap, (++mmap_reserved_size) * sizeof (grub_efi_memory_descriptor_t)); if (!efiemu_mmap) - { - grub_free (old); - return grub_errno; - } + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "not enough space for memory map"); } /* Fill slot*/ @@ -99,8 +94,7 @@ grub_efiemu_request_memalign (grub_size_t align, grub_size_t size, grub_size_t align_overhead; struct grub_efiemu_memrequest *ret, *cur, *prev; /* Check that the request is correct */ - if (type <= GRUB_EFI_LOADER_CODE || type == GRUB_EFI_PERSISTENT_MEMORY || - type >= GRUB_EFI_MAX_MEMORY_TYPE) + if (type >= GRUB_EFI_MAX_MEMORY_TYPE || type <= GRUB_EFI_LOADER_CODE) return -2; /* Add new size to requested size */ @@ -167,13 +161,6 @@ efiemu_alloc_requests (void) GRUB_EFI_MEMORY_MAPPED_IO, GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE, GRUB_EFI_PAL_CODE - - /* - * These are not allocatable: - * GRUB_EFI_RESERVED_MEMORY_TYPE - * GRUB_EFI_PERSISTENT_MEMORY - * >= GRUB_EFI_MAX_MEMORY_TYPE - */ }; /* Compute total memory needed */ @@ -189,7 +176,8 @@ efiemu_alloc_requests (void) /* Allocate the whole memory in one block */ resident_memory = grub_memalign (GRUB_EFIEMU_PAGESIZE, total_alloc); if (!resident_memory) - return grub_errno; + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't allocate resident memory"); /* Split the memory into blocks by type */ curptr = resident_memory; @@ -213,10 +201,10 @@ efiemu_alloc_requests (void) - (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE); if (align_overhead == GRUB_EFIEMU_PAGESIZE) align_overhead = 0; - curptr = ((grub_uint8_t *) curptr) + align_overhead; + curptr = ((grub_uint8_t *)curptr) + align_overhead; /* Add the region to memory map */ - grub_efiemu_add_to_mmap ((grub_addr_t) typestart, + grub_efiemu_add_to_mmap (PTR_TO_UINT64 (typestart), curptr - typestart, reqorder[i]); } @@ -276,26 +264,25 @@ grub_efiemu_mm_return_request (int handle) } } -/* Helper for grub_efiemu_mmap_init. */ -static int -bounds_hook (grub_uint64_t addr __attribute__ ((unused)), - grub_uint64_t size __attribute__ ((unused)), - grub_memory_type_t type __attribute__ ((unused)), - void *data __attribute__ ((unused))) -{ - mmap_reserved_size++; - return 0; -} - /* 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, NULL); +#ifndef GRUB_UTIL + grub_machine_mmap_iterate (bounds_hook); #endif return GRUB_ERR_NONE; @@ -336,25 +323,6 @@ grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size, return 1; } -grub_err_t -grub_efiemu_finish_boot_services (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) -{ - int val = grub_efiemu_get_memory_map (memory_map_size, - memory_map, map_key, - descriptor_size, - descriptor_version); - if (val == 1) - return GRUB_ERR_NONE; - if (val == -1) - return grub_errno; - return grub_error (GRUB_ERR_IO, "memory map buffer is too small"); -} - - /* Free everything */ grub_err_t grub_efiemu_mm_unload (void) @@ -391,52 +359,52 @@ grub_efiemu_mm_init (void) return GRUB_ERR_NONE; } -/* Helper for grub_efiemu_mmap_fill. */ -static int -fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, - void *data __attribute__ ((unused))) - { - switch (type) - { - case GRUB_MEMORY_AVAILABLE: - return grub_efiemu_add_to_mmap (addr, size, - GRUB_EFI_CONVENTIONAL_MEMORY); - - case GRUB_MEMORY_ACPI: - return grub_efiemu_add_to_mmap (addr, size, - GRUB_EFI_ACPI_RECLAIM_MEMORY); - - case GRUB_MEMORY_NVS: - return grub_efiemu_add_to_mmap (addr, size, - GRUB_EFI_ACPI_MEMORY_NVS); - - case GRUB_MEMORY_PERSISTENT: - case GRUB_MEMORY_PERSISTENT_LEGACY: - return grub_efiemu_add_to_mmap (addr, size, - GRUB_EFI_PERSISTENT_MEMORY); - default: - grub_dprintf ("efiemu", - "Unknown memory type %d. Assuming unusable\n", type); - /* FALLTHROUGH */ - case GRUB_MEMORY_RESERVED: - return grub_efiemu_add_to_mmap (addr, size, - GRUB_EFI_UNUSABLE_MEMORY); - } - } - /* Copy host memory map */ static grub_err_t grub_efiemu_mmap_fill (void) { -#ifndef GRUB_MACHINE_EMU - grub_machine_mmap_iterate (fill_hook, NULL); + 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_UTIL + grub_machine_mmap_iterate (fill_hook); #endif return GRUB_ERR_NONE; } grub_err_t -grub_efiemu_mmap_iterate (grub_memory_hook_t hook, void *hook_data) +grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, + grub_uint64_t, + grub_uint32_t)) { unsigned i; @@ -445,22 +413,18 @@ grub_efiemu_mmap_iterate (grub_memory_hook_t hook, void *hook_data) { case GRUB_EFI_RUNTIME_SERVICES_CODE: hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, - GRUB_MEMORY_CODE, hook_data); - break; - - case GRUB_EFI_UNUSABLE_MEMORY: - hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, - GRUB_MEMORY_BADRAM, hook_data); + 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: - default: + case GRUB_EFI_MAX_MEMORY_TYPE: hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, - GRUB_MEMORY_RESERVED, hook_data); + GRUB_EFIEMU_MEMORY_RESERVED); break; case GRUB_EFI_LOADER_CODE: @@ -469,24 +433,18 @@ grub_efiemu_mmap_iterate (grub_memory_hook_t hook, void *hook_data) case GRUB_EFI_BOOT_SERVICES_DATA: case GRUB_EFI_CONVENTIONAL_MEMORY: hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, - GRUB_MEMORY_AVAILABLE, hook_data); + GRUB_EFIEMU_MEMORY_AVAILABLE); break; case GRUB_EFI_ACPI_RECLAIM_MEMORY: hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, - GRUB_MEMORY_ACPI, hook_data); + GRUB_EFIEMU_MEMORY_ACPI); break; case GRUB_EFI_ACPI_MEMORY_NVS: hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, - GRUB_MEMORY_NVS, hook_data); + GRUB_EFIEMU_MEMORY_NVS); break; - - case GRUB_EFI_PERSISTENT_MEMORY: - hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, - GRUB_MEMORY_PERSISTENT, hook_data); - break; - } return 0; @@ -522,8 +480,7 @@ grub_efiemu_mmap_sort_and_uniq (void) [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, - [GRUB_EFI_PERSISTENT_MEMORY] = 4 + [GRUB_EFI_PAL_CODE] = 4 }; int i, j, k, done; @@ -554,16 +511,17 @@ grub_efiemu_mmap_sort_and_uniq (void) /* Initialize variables*/ grub_memset (present, 0, sizeof (int) * GRUB_EFI_MAX_MEMORY_TYPE); scanline_events = (struct grub_efiemu_mmap_scan *) - grub_calloc (mmap_num, sizeof (struct grub_efiemu_mmap_scan) * 2); + 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_calloc (mmap_num, sizeof (grub_efi_memory_descriptor_t) * 2); + grub_malloc (sizeof (grub_efi_memory_descriptor_t) * 2 * mmap_num); if (!result || !scanline_events) { grub_free (result); grub_free (scanline_events); - return grub_errno; + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't allocate space for new memory map"); } /* Register scanline events */ @@ -660,18 +618,16 @@ grub_efiemu_mm_do_alloc (void) /* Preallocate mmap */ efiemu_mmap = (grub_efi_memory_descriptor_t *) - grub_calloc (mmap_reserved_size, sizeof (grub_efi_memory_descriptor_t)); + grub_malloc (mmap_reserved_size * sizeof (grub_efi_memory_descriptor_t)); if (!efiemu_mmap) { grub_efiemu_unload (); - return grub_errno; + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't initialize mmap"); } - err = efiemu_alloc_requests (); - if (err) + if ((err = efiemu_alloc_requests ())) return err; - err = grub_efiemu_mmap_fill (); - if (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/efiemu/pnvram.c similarity index 91% rename from grub-core/efiemu/pnvram.c rename to efiemu/pnvram.c index dd42bc691..e58fce84e 100644 --- a/grub-core/efiemu/pnvram.c +++ b/efiemu/pnvram.c @@ -39,7 +39,7 @@ static grub_size_t nvramsize; /* Parse signed value */ static int -grub_strtosl (const char *arg, const char ** const end, int base) +grub_strtosl (const char *arg, char **end, int base) { if (arg[0] == '-') return -grub_strtoul (arg + 1, end, base); @@ -102,7 +102,98 @@ nvram_set (void * data __attribute__ ((unused))) grub_uint32_t *accuracy = grub_efiemu_mm_obtain_request (accuracy_handle); char *nvramptr; - struct grub_env_var *var; + + 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"); @@ -118,89 +209,9 @@ nvram_set (void * data __attribute__ ((unused))) nvramptr = nvram; grub_memset (nvram, 0, nvramsize); - FOR_SORTED_ENV (var) - { - const char *guid; - char *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) - continue; - - guid = var->name + sizeof ("EfiEmu.pnvram.") - 1; - - attr = grub_strchr (guid, '.'); - if (!attr) - continue; - attr++; - - name = grub_strchr (attr, '.'); - if (!name) - continue; - name++; - - efivar = (struct efi_variable *) nvramptr; - if (nvramptr - nvram + sizeof (struct efi_variable) > nvramsize) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "too many NVRAM variables for reserved variable space." - " Try increasing EfiEmu.pnvram.size"); - - nvramptr += sizeof (struct efi_variable); - - efivar->guid.data1 = grub_cpu_to_le32 (grub_strtoul (guid, &guid, 16)); - if (*guid != '-') - continue; - guid++; - - efivar->guid.data2 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16)); - if (*guid != '-') - continue; - guid++; - - efivar->guid.data3 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16)); - if (*guid != '-') - continue; - 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 grub_errno; - - if (unescape (name, varname, varname + grub_strlen (name) + 1, &len)) - break; - - len = grub_utf8_to_utf16 ((grub_uint16_t *) nvramptr, - (nvramsize - (nvramptr - nvram)) / 2, - (grub_uint8_t *) varname, len, NULL); - - 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; - break; - } - - nvramptr += len; - - efivar->size = len; - } + grub_env_iterate (iterate_env); if (grub_errno) return grub_errno; - *nvramsize_def = nvramsize; /* Register symbols */ diff --git a/grub-core/efiemu/prepare.c b/efiemu/prepare.c similarity index 81% rename from grub-core/efiemu/prepare.c rename to efiemu/prepare.c index 99ddb5abb..620260049 100644 --- a/grub-core/efiemu/prepare.c +++ b/efiemu/prepare.c @@ -20,10 +20,9 @@ #include #include -#include #include #include -#include +#include grub_err_t SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks, @@ -83,16 +82,10 @@ SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks, ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off); /* Put pointer to the list of configuration tables in system table */ - err = grub_efiemu_write_value - (&(SUFFIX (grub_efiemu_system_table)->configuration_table), 0, - conftable_handle, 0, 1, - sizeof (SUFFIX (grub_efiemu_system_table)->configuration_table)); - if (err) - { - grub_efiemu_unload (); - return err; - } - + 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 */ @@ -104,9 +97,10 @@ SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks, grub_memcpy (&(conftables[i].vendor_guid), &(cur->guid), sizeof (cur->guid)); if (cur->get_table) - conftables[i].vendor_table = (grub_addr_t) cur->get_table (cur->data); + conftables[i].vendor_table + = PTR_TO_UINT64 (cur->get_table (cur->data)); else - conftables[i].vendor_table = (grub_addr_t) cur->data; + conftables[i].vendor_table = PTR_TO_UINT64 (cur->data); } err = SUFFIX (grub_efiemu_crc) (); @@ -129,10 +123,6 @@ SUFFIX (grub_efiemu_crc) (void) int handle; grub_off_t off; struct SUFFIX (grub_efiemu_runtime_services) *runtime_services; - grub_uint32_t crc32_val; - - if (GRUB_MD_CRC32->mdlen != 4) - return grub_error (GRUB_ERR_BUG, "incorrect mdlen"); /* compute CRC32 of runtime_services */ err = grub_efiemu_resolve_symbol ("efiemu_runtime_services", @@ -142,13 +132,9 @@ SUFFIX (grub_efiemu_crc) (void) runtime_services = (struct SUFFIX (grub_efiemu_runtime_services) *) ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off); - runtime_services->hdr.crc32 = 0; - - grub_crypto_hash (GRUB_MD_CRC32, &crc32_val, - runtime_services, runtime_services->hdr.header_size); - runtime_services->hdr.crc32 = - grub_be_to_cpu32(crc32_val); + 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) @@ -156,11 +142,9 @@ SUFFIX (grub_efiemu_crc) (void) /* compute CRC32 of system table */ SUFFIX (grub_efiemu_system_table)->hdr.crc32 = 0; - grub_crypto_hash (GRUB_MD_CRC32, &crc32_val, - SUFFIX (grub_efiemu_system_table), - SUFFIX (grub_efiemu_system_table)->hdr.header_size); - SUFFIX (grub_efiemu_system_table)->hdr.crc32 = - grub_be_to_cpu32(crc32_val); + 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); diff --git a/grub-core/efiemu/prepare32.c b/efiemu/prepare32.c similarity index 100% rename from grub-core/efiemu/prepare32.c rename to efiemu/prepare32.c diff --git a/grub-core/efiemu/prepare64.c b/efiemu/prepare64.c similarity index 100% rename from grub-core/efiemu/prepare64.c rename to efiemu/prepare64.c diff --git a/grub-core/efiemu/runtime/config.h b/efiemu/runtime/config.h similarity index 93% rename from grub-core/efiemu/runtime/config.h rename to efiemu/runtime/config.h index c9fe02716..26fb2ff08 100644 --- a/grub-core/efiemu/runtime/config.h +++ b/efiemu/runtime/config.h @@ -19,18 +19,16 @@ #define GRUB_TYPES_CPU_HEADER 1 -#ifdef __i386__ +#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 -#elif defined (__x86_64__) +#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 -#else -#error "Unknown architecture" #endif diff --git a/grub-core/efiemu/runtime/efiemu.S b/efiemu/runtime/efiemu.S similarity index 100% rename from grub-core/efiemu/runtime/efiemu.S rename to efiemu/runtime/efiemu.S diff --git a/grub-core/efiemu/runtime/efiemu.c b/efiemu/runtime/efiemu.c similarity index 83% rename from grub-core/efiemu/runtime/efiemu.c rename to efiemu/runtime/efiemu.c index 51dc02114..73893414a 100644 --- a/grub-core/efiemu/runtime/efiemu.c +++ b/efiemu/runtime/efiemu.c @@ -21,82 +21,76 @@ As it emulates only runtime serviceit isn't able to chainload EFI bootloader on non-EFI system (TODO) */ -#ifdef __i386__ -#include -#else -#include -#endif - #include #include #include #include -grub_efi_status_t __grub_efi_api +grub_efi_status_t efiemu_get_time (grub_efi_time_t *time, grub_efi_time_capabilities_t *capabilities); -grub_efi_status_t __grub_efi_api +grub_efi_status_t efiemu_set_time (grub_efi_time_t *time); -grub_efi_status_t __grub_efi_api +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 __grub_efi_api +grub_efi_status_t efiemu_set_wakeup_time (grub_efi_boolean_t enabled, grub_efi_time_t *time); -#ifdef __APPLE__ +#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 __grub_efi_api +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 __grub_efi_api +grub_efi_status_t efiemu_convert_pointer (grub_efi_uintn_t debug_disposition, void **address) PHYSICAL_ATTRIBUTE; -grub_efi_status_t __grub_efi_api +grub_efi_status_t efiemu_get_variable (grub_efi_char16_t *variable_name, - const grub_packed_guid_t *vendor_guid, + grub_efi_guid_t *vendor_guid, grub_efi_uint32_t *attributes, grub_efi_uintn_t *data_size, void *data); -grub_efi_status_t __grub_efi_api +grub_efi_status_t efiemu_get_next_variable_name (grub_efi_uintn_t *variable_name_size, grub_efi_char16_t *variable_name, - grub_packed_guid_t *vendor_guid); + grub_efi_guid_t *vendor_guid); -grub_efi_status_t __grub_efi_api +grub_efi_status_t efiemu_set_variable (grub_efi_char16_t *variable_name, - const grub_packed_guid_t *vendor_guid, + grub_efi_guid_t *vendor_guid, grub_efi_uint32_t attributes, grub_efi_uintn_t data_size, void *data); -grub_efi_status_t __grub_efi_api +grub_efi_status_t efiemu_get_next_high_monotonic_count (grub_efi_uint32_t *high_count); -void __grub_efi_api +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 __grub_efi_api +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 __grub_efi_api +grub_efi_status_t EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition, void **address) PHYSICAL_ATTRIBUTE; @@ -131,11 +125,11 @@ extern grub_uint32_t efiemu_time_accuracy; /* Some standard functions because we need to be standalone */ static void -efiemu_memcpy (void *to, const void *from, int count) +efiemu_memcpy (void *to, void *from, int count) { int i; for (i = 0; i < count; i++) - ((grub_uint8_t *) to)[i] = ((const grub_uint8_t *) from)[i]; + ((grub_uint8_t *) to)[i] = ((grub_uint8_t *) from)[i]; } static int @@ -155,7 +149,7 @@ efiemu_str16len (grub_uint16_t *a) } static int -efiemu_memequal (const void *a, const void *b, grub_size_t n) +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; @@ -174,17 +168,17 @@ efiemu_memset (grub_uint8_t *a, grub_uint8_t b, grub_size_t n) 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)); + __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)); + __asm__ __volatile__ ("outb %%al, $0x70\n" + "inb $0x71, %%al": "=a"(ret) :"a" (addr)); return ret; } @@ -202,7 +196,7 @@ bcd_to_hex (grub_uint8_t in) return 10 * ((in & 0xf0) >> 4) + (in & 0x0f); } -grub_efi_status_t __grub_efi_api +grub_efi_status_t EFI_FUNC (efiemu_get_time) (grub_efi_time_t *time, grub_efi_time_capabilities_t *capabilities) { @@ -246,7 +240,7 @@ EFI_FUNC (efiemu_get_time) (grub_efi_time_t *time, return GRUB_EFI_SUCCESS; } -grub_efi_status_t __grub_efi_api +grub_efi_status_t EFI_FUNC (efiemu_set_time) (grub_efi_time_t *time) { LOG ('b'); @@ -265,7 +259,7 @@ EFI_FUNC (efiemu_set_time) (grub_efi_time_t *time) } /* Following 2 functions are vendor specific. So announce it as unsupported */ -grub_efi_status_t __grub_efi_api +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) @@ -274,7 +268,7 @@ EFI_FUNC (efiemu_get_wakeup_time) (grub_efi_boolean_t *enabled, return GRUB_EFI_UNSUPPORTED; } -grub_efi_status_t __grub_efi_api +grub_efi_status_t EFI_FUNC (efiemu_set_wakeup_time) (grub_efi_boolean_t enabled, grub_efi_time_t *time) { @@ -337,7 +331,7 @@ efiemu_getcrc32 (grub_uint32_t crc, void *buf, int size) } -grub_efi_status_t __grub_efi_api EFI_FUNC +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, @@ -375,16 +369,16 @@ grub_efi_status_t __grub_efi_api EFI_FUNC switch (cur_relloc->size) { case 8: - *((grub_uint64_t *) (grub_addr_t) cur_relloc->addr) += corr; + *((grub_uint64_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; break; case 4: - *((grub_uint32_t *) (grub_addr_t) cur_relloc->addr) += corr; + *((grub_uint32_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; break; case 2: - *((grub_uint16_t *) (grub_addr_t) cur_relloc->addr) += corr; + *((grub_uint16_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; break; case 1: - *((grub_uint8_t *) (grub_addr_t) cur_relloc->addr) += corr; + *((grub_uint8_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; break; } } @@ -403,7 +397,7 @@ grub_efi_status_t __grub_efi_api EFI_FUNC /* since efiemu_set_virtual_address_map corrects all the pointers we don't need efiemu_convert_pointer */ -grub_efi_status_t __grub_efi_api +grub_efi_status_t EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition, void **address) { @@ -416,7 +410,7 @@ EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition, /* Find variable by name and GUID. */ static struct efi_variable * -find_variable (const grub_packed_guid_t *vendor_guid, +find_variable (grub_efi_guid_t *vendor_guid, grub_efi_char16_t *variable_name) { grub_uint8_t *ptr; @@ -436,12 +430,12 @@ find_variable (const grub_packed_guid_t *vendor_guid, return 0; } -grub_efi_status_t __grub_efi_api +grub_efi_status_t EFI_FUNC (efiemu_get_variable) (grub_efi_char16_t *variable_name, - const grub_packed_guid_t *vendor_guid, - grub_efi_uint32_t *attributes, - grub_efi_uintn_t *data_size, - void *data) + 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'); @@ -461,10 +455,10 @@ EFI_FUNC (efiemu_get_variable) (grub_efi_char16_t *variable_name, return GRUB_EFI_SUCCESS; } -grub_efi_status_t __grub_efi_api EFI_FUNC +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_packed_guid_t *vendor_guid) + grub_efi_guid_t *vendor_guid) { struct efi_variable *efivar; LOG ('l'); @@ -501,12 +495,12 @@ grub_efi_status_t __grub_efi_api EFI_FUNC return GRUB_EFI_SUCCESS; } -grub_efi_status_t __grub_efi_api +grub_efi_status_t EFI_FUNC (efiemu_set_variable) (grub_efi_char16_t *variable_name, - const grub_packed_guid_t *vendor_guid, - grub_efi_uint32_t attributes, - grub_efi_uintn_t data_size, - void *data) + 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; @@ -556,7 +550,7 @@ EFI_FUNC (efiemu_set_variable) (grub_efi_char16_t *variable_name, return GRUB_EFI_SUCCESS; } -grub_efi_status_t __grub_efi_api EFI_FUNC +grub_efi_status_t EFI_FUNC (efiemu_get_next_high_monotonic_count) (grub_efi_uint32_t *high_count) { LOG ('j'); @@ -570,7 +564,7 @@ grub_efi_status_t __grub_efi_api EFI_FUNC Besides EFI specification says that this function shouldn't be used on systems supporting ACPI */ -void __grub_efi_api +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, @@ -597,30 +591,9 @@ struct grub_efi_runtime_services efiemu_runtime_services = .set_virtual_address_map = efiemu_set_virtual_address_map, .convert_pointer = efiemu_convert_pointer, - /* - The code is structured in a way to accept unaligned inputs - in most cases and supply 4-byte aligned outputs. - - Efiemu case is a bit ugly because there inputs and outputs are - reversed and so we need careful casts to account for this - inversion. - */ - .get_variable = (grub_efi_status_t - (__grub_efi_api *) (grub_efi_char16_t *variable_name, - const grub_guid_t *vendor_guid, - grub_efi_uint32_t *attributes, - grub_efi_uintn_t *data_size, - void *data)) efiemu_get_variable, - .get_next_variable_name = (grub_efi_status_t - (__grub_efi_api *) (grub_efi_uintn_t *variable_name_size, - grub_efi_char16_t *variable_name, - grub_guid_t *vendor_guid)) efiemu_get_next_variable_name, - .set_variable = (grub_efi_status_t - (__grub_efi_api *) (grub_efi_char16_t *variable_name, - const grub_guid_t *vendor_guid, - grub_efi_uint32_t attributes, - grub_efi_uintn_t data_size, - void *data)) efiemu_set_variable, + .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 diff --git a/efiemu/runtime/efiemu.sh b/efiemu/runtime/efiemu.sh new file mode 100644 index 000000000..5a492dc2f --- /dev/null +++ b/efiemu/runtime/efiemu.sh @@ -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/efiemu/symbols.c similarity index 89% rename from grub-core/efiemu/symbols.c rename to efiemu/symbols.c index cc148552d..4fc546b59 100644 --- a/grub-core/efiemu/symbols.c +++ b/efiemu/symbols.c @@ -22,7 +22,6 @@ #include #include #include -#include static int ptv_written = 0; static int ptv_alloc = 0; @@ -70,7 +69,7 @@ grub_efiemu_request_symbols (int num) return grub_error (GRUB_ERR_BAD_ARGUMENT, "symbols have already been allocated"); if (num < 0) - return grub_error (GRUB_ERR_BUG, + return grub_error (GRUB_ERR_BAD_ARGUMENT, "can't request negative symbols"); ptv_requested += num; return GRUB_ERR_NONE; @@ -89,7 +88,7 @@ grub_efiemu_resolve_symbol (const char *name, int *handle, grub_off_t *off) return GRUB_ERR_NONE; } grub_dprintf ("efiemu", "%s not found\n", name); - return grub_error (GRUB_ERR_BAD_OS, N_("symbol `%s' not found"), 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 */ @@ -100,7 +99,7 @@ grub_efiemu_register_symbol (const char *name, int handle, grub_off_t off) cur = (struct grub_efiemu_sym *) grub_malloc (sizeof (*cur)); grub_dprintf ("efiemu", "registering symbol '%s'\n", name); if (!cur) - return grub_errno; + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't register symbol"); cur->name = grub_strdup (name); cur->next = efiemu_syms; cur->handle = handle; @@ -154,7 +153,7 @@ grub_efiemu_write_value (void *addr, grub_uint32_t value, int plus_handle, = grub_efiemu_mm_obtain_request (ptv_handle); if (ptv_needed && ptv_written >= ptv_alloc) - return grub_error (GRUB_ERR_BUG, + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "your module didn't declare efiemu " " relocators correctly"); @@ -170,7 +169,7 @@ grub_efiemu_write_value (void *addr, grub_uint32_t value, int plus_handle, else ptv_rels[ptv_written].plustype = 0; - ptv_rels[ptv_written].addr = (grub_addr_t) addr; + ptv_rels[ptv_written].addr = PTR_TO_UINT64 (addr); ptv_rels[ptv_written].size = size; ptv_written++; @@ -180,10 +179,10 @@ grub_efiemu_write_value (void *addr, grub_uint32_t value, int plus_handle, /* Compute the value */ if (minus_handle) - value -= (grub_addr_t) grub_efiemu_mm_obtain_request (minus_handle); + value -= PTR_TO_UINT32 (grub_efiemu_mm_obtain_request (minus_handle)); if (plus_handle) - value += (grub_addr_t) grub_efiemu_mm_obtain_request (plus_handle); + value += PTR_TO_UINT32 (grub_efiemu_mm_obtain_request (plus_handle)); /* Write the value */ switch (size) @@ -201,7 +200,7 @@ grub_efiemu_write_value (void *addr, grub_uint32_t value, int plus_handle, *((grub_uint8_t *) addr) = value; break; default: - return grub_error (GRUB_ERR_BUG, "wrong symbol size"); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "wrong symbol size"); } return GRUB_ERR_NONE; @@ -223,7 +222,7 @@ grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size, /* Ensure that we are called only once */ if (*ptv_relocated) - return grub_error (GRUB_ERR_BUG, "EfiEmu is already relocated"); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "EfiEmu is already relocated"); *ptv_relocated = 1; /* Correct addresses using information supplied by grub */ @@ -249,16 +248,16 @@ grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size, switch (cur_relloc->size) { case 8: - *((grub_uint64_t *) (grub_addr_t) cur_relloc->addr) += corr; + *((grub_uint64_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; break; case 4: - *((grub_uint32_t *) (grub_addr_t) cur_relloc->addr) += corr; + *((grub_uint32_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; break; case 2: - *((grub_uint16_t *) (grub_addr_t) cur_relloc->addr) += corr; + *((grub_uint16_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; break; case 1: - *((grub_uint8_t *) (grub_addr_t) cur_relloc->addr) += corr; + *((grub_uint8_t *) UINT_TO_PTR (cur_relloc->addr)) += corr; break; } } diff --git a/font/font.c b/font/font.c new file mode 100644 index 000000000..1b3dc6387 --- /dev/null +++ b/font/font.c @@ -0,0 +1,1128 @@ +/* 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 = ""; + 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, §ion) != 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, §ion) != 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 (§ion); + 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 (§ion, &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 (§ion); + 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 (§ion, &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 (§ion, &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 (§ion, &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 (§ion, &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/font/font_cmd.c similarity index 74% rename from grub-core/font/font_cmd.c rename to font/font_cmd.c index f3b36f2d6..98216ae44 100644 --- a/grub-core/font/font_cmd.c +++ b/font/font_cmd.c @@ -21,7 +21,6 @@ #include #include #include -#include static grub_err_t loadfont_command (grub_command_t cmd __attribute__ ((unused)), @@ -29,15 +28,11 @@ loadfont_command (grub_command_t cmd __attribute__ ((unused)), char **args) { if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no font specified"); while (argc--) - if (grub_font_load (*args++) == 0) - { - if (!grub_errno) - return grub_error (GRUB_ERR_BAD_FONT, "invalid font"); - return grub_errno; - } + if (grub_font_load (*args++) != 0) + return GRUB_ERR_BAD_FONT; return GRUB_ERR_NONE; } @@ -49,7 +44,7 @@ lsfonts_command (grub_command_t cmd __attribute__ ((unused)), { struct grub_font_node *node; - grub_puts_ (N_("Loaded fonts:")); + grub_printf ("Loaded fonts:\n"); for (node = grub_font_list; node; node = node->next) { grub_font_t font = node->value; @@ -61,28 +56,20 @@ lsfonts_command (grub_command_t cmd __attribute__ ((unused)), static grub_command_t cmd_loadfont, cmd_lsfonts; -#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_COREBOOT) -void grub_font_init (void) -#else -GRUB_MOD_INIT(font) -#endif +GRUB_MOD_INIT(font_manager) { grub_font_loader_init (); cmd_loadfont = grub_register_command ("loadfont", loadfont_command, - N_("FILE..."), - N_("Specify one or more font files to load.")); + "FILE...", + "Specify one or more font files to load."); cmd_lsfonts = grub_register_command ("lsfonts", lsfonts_command, - 0, N_("List the loaded fonts.")); + 0, "List the loaded fonts."); } -#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_COREBOOT) -void grub_font_fini (void) -#else -GRUB_MOD_FINI(font) -#endif +GRUB_MOD_FINI(font_manager) { /* TODO: Determine way to free allocated resources. Warning: possible pointer references could be in use. */ diff --git a/fs/affs.c b/fs/affs.c new file mode 100644 index 000000000..3dc80752d --- /dev/null +++ b/fs/affs.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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 + + +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; + + +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; +} + + +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 new file mode 100644 index 000000000..cd61f4db9 --- /dev/null +++ b/fs/afs.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#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/ufs_be.c b/fs/afs_be.c similarity index 59% rename from grub-core/fs/ufs_be.c rename to fs/afs_be.c index a58f75a99..1f1f48fbb 100644 --- a/grub-core/fs/ufs_be.c +++ b/fs/afs_be.c @@ -1,2 +1,2 @@ #define MODE_BIGENDIAN 1 -#include "ufs.c" +#include "afs.c" diff --git a/fs/befs.c b/fs/befs.c new file mode 100644 index 000000000..c54d8e1cc --- /dev/null +++ b/fs/befs.c @@ -0,0 +1,3 @@ +/* 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 new file mode 100644 index 000000000..f6e8179f4 --- /dev/null +++ b/fs/befs_be.c @@ -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/fs/cpio.c b/fs/cpio.c new file mode 100644 index 000000000..c087b4f90 --- /dev/null +++ b/fs/cpio.c @@ -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 . + */ + +#include +#include +#include +#include +#include + +#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/fs/ext2.c similarity index 59% rename from grub-core/fs/ext2.c rename to fs/ext2.c index 2f262dc34..f2fec828a 100644 --- a/grub-core/fs/ext2.c +++ b/fs/ext2.c @@ -21,6 +21,10 @@ #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 @@ -46,9 +50,6 @@ #include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); /* Log2 size of ext2 block in 512 blocks. */ #define LOG2_EXT2_BLOCK_SIZE(data) \ @@ -59,15 +60,14 @@ GRUB_MOD_LICENSE ("GPLv3+"); (grub_le_to_cpu32 (data->sblock.log2_block_size) + 10) /* The size of an ext2 block in bytes. */ -#define EXT2_BLOCK_SIZE(data) (1U << LOG2_BLOCK_SIZE (data)) +#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) \ - (data->sblock.revision_level \ - == grub_cpu_to_le32_compile_time (EXT2_GOOD_OLD_REVISION) \ + (EXT2_REVISION (data) == EXT2_GOOD_OLD_REVISION \ ? EXT2_GOOD_OLD_INODE_SIZE \ : grub_le_to_cpu16 (data->sblock.inode_size)) @@ -101,46 +101,22 @@ GRUB_MOD_LICENSE ("GPLv3+"); #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_MMP 0x0100 #define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 -#define EXT4_FEATURE_INCOMPAT_CSUM_SEED 0x2000 -#define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3 level htree */ -#define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 /* 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 \ - | EXT2_FEATURE_INCOMPAT_META_BG \ - | EXT4_FEATURE_INCOMPAT_64BIT \ - | EXT4_FEATURE_INCOMPAT_ENCRYPT) + | 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. - * mmp: Not really back-incompatible - was added as such to - * avoid multiple read-write mounts. Safe to ignore for this - * RO driver. - * checksum seed: Not really back-incompatible - was added to allow tools - * such as tune2fs to change the UUID on a mounted metadata - * checksummed filesystem. Safe to ignore for now since the - * driver doesn't support checksum verification. However, it - * has to be removed from this list if the support is added later. - * large_dir: Not back-incompatible given that the GRUB ext2 driver does - * not implement EXT2_FEATURE_COMPAT_DIR_INDEX. If the GRUB - * eventually supports the htree feature (aka dir_index) - * it should support 3 level htrees and then move - * EXT4_FEATURE_INCOMPAT_LARGEDIR to - * EXT2_DRIVER_SUPPORTED_INCOMPAT. - */ -#define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER \ - | EXT4_FEATURE_INCOMPAT_MMP \ - | EXT4_FEATURE_INCOMPAT_CSUM_SEED \ - | EXT4_FEATURE_INCOMPAT_LARGEDIR) + * 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 @@ -155,7 +131,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define EXT3_JOURNAL_FLAG_DELETED 4 #define EXT3_JOURNAL_FLAG_LAST_TAG 8 -#define EXT4_ENCRYPT_FLAG 0x800 #define EXT4_EXTENTS_FLAG 0x80000 /* The ext2 superblock. */ @@ -206,7 +181,7 @@ struct grub_ext2_sblock grub_uint32_t hash_seed[4]; grub_uint8_t def_hash_version; grub_uint8_t jnl_backup_type; - grub_uint16_t group_desc_size; + grub_uint16_t reserved_word_pad; grub_uint32_t default_mount_opts; grub_uint32_t first_meta_bg; grub_uint32_t mkfs_time; @@ -224,14 +199,6 @@ struct grub_ext2_block_group grub_uint16_t used_dirs; grub_uint16_t pad; grub_uint32_t reserved[3]; - grub_uint32_t block_id_hi; - grub_uint32_t inode_id_hi; - grub_uint32_t inode_table_id_hi; - grub_uint16_t free_blocks_hi; - grub_uint16_t free_inodes_hi; - grub_uint16_t used_dirs_hi; - grub_uint16_t pad2; - grub_uint32_t reserved2[3]; }; /* The ext2 inode. */ @@ -262,7 +229,7 @@ struct grub_ext2_inode }; grub_uint32_t version; grub_uint32_t acl; - grub_uint32_t size_high; + grub_uint32_t dir_acl; grub_uint32_t fragment_addr; grub_uint32_t osd2[3]; }; @@ -272,7 +239,6 @@ struct ext2_dirent { grub_uint32_t inode; grub_uint16_t direntlen; -#define MAX_NAMELEN 255 grub_uint8_t namelen; grub_uint8_t filetype; }; @@ -346,7 +312,6 @@ struct grub_fshelp_node struct grub_ext2_data { struct grub_ext2_sblock sblock; - int log_group_desc_size; grub_disk_t disk; struct grub_ext2_inode *inode; struct grub_fshelp_node diropen; @@ -356,80 +321,25 @@ static grub_dl_t my_mod; -/* Check is a = b^x for some x. */ -static inline int -is_power_of (grub_uint64_t a, grub_uint32_t b) -{ - grub_uint64_t c; - /* Prevent overflow assuming b < 8. */ - if (a >= (1LL << 60)) - return 0; - for (c = 1; c <= a; c *= b); - return (c == a); -} - - -static inline int -group_has_super_block (struct grub_ext2_data *data, grub_uint64_t group) -{ - if (!(data->sblock.feature_ro_compat - & grub_cpu_to_le32_compile_time(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))) - return 1; - /* Algorithm looked up in Linux source. */ - if (group <= 1) - return 1; - /* Even number is never a power of odd number. */ - if (!(group & 1)) - return 0; - return (is_power_of(group, 7) || is_power_of(group, 5) || - is_power_of(group, 3)); -} - /* 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, grub_uint64_t group, +grub_ext2_blockgroup (struct grub_ext2_data *data, int group, struct grub_ext2_block_group *blkgrp) { - grub_uint64_t full_offset = (group << data->log_group_desc_size); - grub_uint64_t block, offset; - block = (full_offset >> LOG2_BLOCK_SIZE (data)); - offset = (full_offset & ((1 << LOG2_BLOCK_SIZE (data)) - 1)); - if ((data->sblock.feature_incompat - & grub_cpu_to_le32_compile_time (EXT2_FEATURE_INCOMPAT_META_BG)) - && block >= grub_le_to_cpu32(data->sblock.first_meta_bg)) - { - grub_uint64_t first_block_group; - /* Find the first block group for which a descriptor - is stored in given block. */ - first_block_group = (block << (LOG2_BLOCK_SIZE (data) - - data->log_group_desc_size)); - - block = (first_block_group - * grub_le_to_cpu32(data->sblock.blocks_per_group)); - - if (group_has_super_block (data, first_block_group)) - block++; - } - else - /* Superblock. */ - block++; return grub_disk_read (data->disk, - ((grub_le_to_cpu32 (data->sblock.first_data_block) - + block) - << LOG2_EXT2_BLOCK_SIZE (data)), offset, + ((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 grub_err_t -grub_ext4_find_leaf (struct grub_ext2_data *data, +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_header **leaf) + grub_uint32_t fileblock) { struct grub_ext4_extent_idx *index; - void *buf = NULL; - *leaf = NULL; while (1) { @@ -438,14 +348,11 @@ grub_ext4_find_leaf (struct grub_ext2_data *data, index = (struct grub_ext4_extent_idx *) (ext_block + 1); - if (ext_block->magic != grub_cpu_to_le16_compile_time (EXT4_EXT_MAGIC)) - goto fail; + if (grub_le_to_cpu16(ext_block->magic) != EXT4_EXT_MAGIC) + return 0; if (ext_block->depth == 0) - { - *leaf = ext_block; - return GRUB_ERR_NONE; - } + return ext_block; for (i = 0; i < grub_le_to_cpu16 (ext_block->entries); i++) { @@ -454,27 +361,17 @@ grub_ext4_find_leaf (struct grub_ext2_data *data, } if (--i < 0) - { - grub_free (buf); - return GRUB_ERR_NONE; - } + return 0; block = grub_le_to_cpu16 (index[i].leaf_hi); - block = (block << 32) | grub_le_to_cpu32 (index[i].leaf); - if (!buf) - buf = grub_malloc (EXT2_BLOCK_SIZE(data)); - if (!buf) - goto fail; + 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)) - goto fail; + return 0; - ext_block = buf; + ext_block = (struct grub_ext4_extent_header *) buf; } - fail: - grub_free (buf); - return GRUB_ERR_BAD_FS; } static grub_disk_addr_t @@ -482,54 +379,28 @@ 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); - grub_disk_addr_t blksz_quarter = blksz / 4; int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data); - int log_perblock = log2_blksz + 9 - 2; - grub_uint32_t indir; - int shift; - if (inode->flags & grub_cpu_to_le32_compile_time (EXT4_EXTENTS_FLAG)) + 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; - grub_disk_addr_t ret; - grub_uint16_t nent; - /* Maximum number of extent entries in the inode's inline extent area. */ - const grub_uint16_t max_inline_ext = sizeof (inode->blocks) / sizeof (*ext) - 1; /* Minus 1 extent header. */ - /* Maximum number of extent entries in the external extent block. */ - const grub_uint16_t max_external_ext = EXT2_BLOCK_SIZE (data) / sizeof (*ext) - 1; /* Minus 1 extent header. */ - if (grub_ext4_find_leaf (data, (struct grub_ext4_extent_header *) inode->blocks.dir_blocks, - fileblock, &leaf) != GRUB_ERR_NONE) + 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; } - if (leaf == NULL) - /* Leaf for the given block is absent (i.e. sparse) */ - return 0; - ext = (struct grub_ext4_extent *) (leaf + 1); - - nent = grub_le_to_cpu16 (leaf->entries); - - /* - * Determine the effective number of extent entries (nent) to process. - * If the extent header (leaf) is stored inline in the inode’s block - * area, i.e. at inode->blocks.dir_blocks, then only max_inline_ext - * entries can fit. Otherwise, if the header was read from an external - * extent block use the larger limit, max_external_ext, based on the - * full block size. - */ - if (leaf == (struct grub_ext4_extent_header *) inode->blocks.dir_blocks) - nent = grub_min (nent, max_inline_ext); - else - nent = grub_min (nent, max_external_ext); - - for (i = 0; i < nent; i++) + for (i = 0; i < grub_le_to_cpu16 (leaf->entries); i++) { if (fileblock < grub_le_to_cpu32 (ext[i].block)) break; @@ -539,7 +410,7 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) { fileblock -= grub_le_to_cpu32 (ext[i].block); if (fileblock >= grub_le_to_cpu16 (ext[i].len)) - ret = 0; + return 0; else { grub_disk_addr_t start; @@ -547,84 +418,79 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) start = grub_le_to_cpu16 (ext[i].start_hi); start = (start << 32) + grub_le_to_cpu32 (ext[i].start); - ret = fileblock + start; + return fileblock + start; } } else { grub_error (GRUB_ERR_BAD_FS, "something wrong with extent"); - ret = -1; + return -1; } - - if (leaf != (struct grub_ext4_extent_header *) inode->blocks.dir_blocks) - grub_free (leaf); - - return ret; } - /* Direct blocks. */ if (fileblock < INDIRECT_BLOCKS) - return grub_le_to_cpu32 (inode->blocks.dir_blocks[fileblock]); - fileblock -= INDIRECT_BLOCKS; + blknr = grub_le_to_cpu32 (inode->blocks.dir_blocks[fileblock]); /* Indirect. */ - if (fileblock < blksz_quarter) + else if (fileblock < INDIRECT_BLOCKS + blksz / 4) { - indir = inode->blocks.indir_block; - shift = 0; - goto indirect; + 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]); } - fileblock -= blksz_quarter; /* Double indirect. */ - if (fileblock < blksz_quarter * blksz_quarter) + else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * (blksz / 4 + 1)) { - indir = inode->blocks.double_indir_block; - shift = 1; - goto indirect; + 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]); } - fileblock -= blksz_quarter * blksz_quarter; - /* Triple indirect. */ - if (fileblock < blksz_quarter * blksz_quarter * (blksz_quarter + 1)) + /* triple indirect. */ + else { - indir = inode->blocks.triple_indir_block; - shift = 2; - goto indirect; + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "ext2fs doesn't support triple indirect blocks"); } - grub_error (GRUB_ERR_BAD_FS, - "ext2fs doesn't support quadruple indirect blocks"); - return -1; -indirect: - do { - /* If the indirect block is zero, all child blocks are absent - (i.e. filled with zeros.) */ - if (indir == 0) - return 0; - if (grub_disk_read (data->disk, - ((grub_disk_addr_t) grub_le_to_cpu32 (indir)) - << log2_blksz, - ((fileblock >> (log_perblock * shift)) - & ((1 << log_perblock) - 1)) - * sizeof (indir), - sizeof (indir), &indir)) - return -1; - } while (shift--); - - return grub_le_to_cpu32 (indir); + 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, - grub_disk_read_hook_t read_hook, void *read_hook_data, - grub_off_t pos, grub_size_t len, char *buf) + 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, read_hook_data, + return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_ext2_read_block, - grub_cpu_to_le32 (node->inode.size) - | (((grub_off_t) grub_cpu_to_le32 (node->inode.size_high)) << 32), - LOG2_EXT2_BLOCK_SIZE (node->data), 0); + node->inode.size, + LOG2_EXT2_BLOCK_SIZE (node->data)); } @@ -639,7 +505,6 @@ grub_ext2_read_inode (struct grub_ext2_data *data, int inodes_per_block; unsigned int blkno; unsigned int blkoff; - grub_disk_addr_t base; /* It is easier to calculate if the first inode is 0. */ ino--; @@ -656,14 +521,10 @@ grub_ext2_read_inode (struct grub_ext2_data *data, blkoff = (ino % grub_le_to_cpu32 (sblock->inodes_per_group)) % inodes_per_block; - base = grub_le_to_cpu32 (blkgrp.inode_table_id); - if (data->log_group_desc_size >= 6) - base |= (((grub_disk_addr_t) grub_le_to_cpu32 (blkgrp.inode_table_id_hi)) - << 32); - /* Read the inode. */ if (grub_disk_read (data->disk, - ((base + blkno) << LOG2_EXT2_BLOCK_SIZE (data)), + ((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; @@ -687,42 +548,20 @@ grub_ext2_mount (grub_disk_t disk) goto fail; /* Make sure this is an ext2 filesystem. */ - if (data->sblock.magic != grub_cpu_to_le16_compile_time (EXT2_MAGIC) - || grub_le_to_cpu32 (data->sblock.log2_block_size) >= 16 - || data->sblock.inodes_per_group == 0 - /* 20 already means 1GiB blocks. We don't want to deal with blocks overflowing int32. */ - || grub_le_to_cpu32 (data->sblock.log2_block_size) > 20 - || EXT2_INODE_SIZE (data) == 0 - || EXT2_BLOCK_SIZE (data) / EXT2_INODE_SIZE (data) == 0) + 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 (data->sblock.revision_level != grub_cpu_to_le32_compile_time (EXT2_GOOD_OLD_REVISION) - && (data->sblock.feature_incompat - & grub_cpu_to_le32_compile_time (~(EXT2_DRIVER_SUPPORTED_INCOMPAT - | EXT2_DRIVER_IGNORED_INCOMPAT)))) + 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; } - if (data->sblock.revision_level != grub_cpu_to_le32_compile_time (EXT2_GOOD_OLD_REVISION) - && (data->sblock.feature_incompat - & grub_cpu_to_le32_compile_time (EXT4_FEATURE_INCOMPAT_64BIT)) - && data->sblock.group_desc_size != 0 - && ((data->sblock.group_desc_size & (data->sblock.group_desc_size - 1)) - == 0) - && (data->sblock.group_desc_size & grub_cpu_to_le16_compile_time (0x1fe0))) - { - grub_uint16_t b = grub_le_to_cpu16 (data->sblock.group_desc_size); - for (data->log_group_desc_size = 0; b != (1 << data->log_group_desc_size); - data->log_group_desc_size++); - } - else - data->log_group_desc_size = 5; data->disk = disk; @@ -751,42 +590,28 @@ grub_ext2_read_symlink (grub_fshelp_node_t node) { char *symlink; struct grub_fshelp_node *diro = node; - grub_size_t sz; if (! diro->inode_read) { grub_ext2_read_inode (diro->data, diro->ino, &diro->inode); if (grub_errno) return 0; - - if (diro->inode.flags & grub_cpu_to_le32_compile_time (EXT4_ENCRYPT_FLAG)) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "symlink is encrypted"); - return 0; - } } - if (grub_add (grub_le_to_cpu32 (diro->inode.size), 1, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); - return NULL; - } - - symlink = grub_malloc (sz); + symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1); if (! symlink) return 0; - /* - * If the filesize of the symlink is equal to or 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) < sizeof (diro->inode.symlink)) - grub_memcpy (symlink, - diro->inode.symlink, - grub_le_to_cpu32 (diro->inode.size)); + /* 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, 0, + grub_ext2_read_file (diro, 0, 0, grub_le_to_cpu32 (diro->inode.size), symlink); if (grub_errno) @@ -802,7 +627,10 @@ grub_ext2_read_symlink (grub_fshelp_node_t node) static int grub_ext2_iterate_dir (grub_fshelp_node_t dir, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data) + 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; @@ -814,18 +642,12 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir, return 0; } - if (diro->inode.flags & grub_cpu_to_le32_compile_time (EXT4_ENCRYPT_FLAG)) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "directory is encrypted"); - return 0; - } - /* Search the file. */ while (fpos < grub_le_to_cpu32 (diro->inode.size)) { struct ext2_dirent dirent; - grub_ext2_read_file (diro, 0, 0, fpos, sizeof (struct ext2_dirent), + grub_ext2_read_file (diro, 0, fpos, sizeof (struct ext2_dirent), (char *) &dirent); if (grub_errno) return 0; @@ -833,13 +655,13 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir, if (dirent.direntlen == 0) return 0; - if (dirent.inode != 0 && dirent.namelen != 0) + if (dirent.namelen != 0) { - char filename[MAX_NAMELEN + 1]; + char filename[dirent.namelen + 1]; struct grub_fshelp_node *fdiro; enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; - grub_ext2_read_file (diro, 0, 0, fpos + sizeof (struct ext2_dirent), + grub_ext2_read_file (diro, 0, fpos + sizeof (struct ext2_dirent), dirent.namelen, filename); if (grub_errno) return 0; @@ -890,7 +712,7 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir, type = GRUB_FSHELP_REG; } - if (hook (filename, type, fdiro, hook_data)) + if (hook (filename, type, fdiro)) return 1; } @@ -906,41 +728,29 @@ grub_ext2_open (struct grub_file *file, const char *name) { struct grub_ext2_data *data; struct grub_fshelp_node *fdiro = 0; - grub_err_t err; grub_dl_ref (my_mod); data = grub_ext2_mount (file->device->disk); if (! data) - { - err = grub_errno; - goto fail; - } + goto fail; - err = grub_fshelp_find_file (name, &data->diropen, &fdiro, - grub_ext2_iterate_dir, - grub_ext2_read_symlink, GRUB_FSHELP_REG); - if (err) + 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) { - err = grub_ext2_read_inode (data, fdiro->ino, &fdiro->inode); - if (err) + grub_ext2_read_inode (data, fdiro->ino, &fdiro->inode); + if (grub_errno) goto fail; } - if (fdiro->inode.flags & grub_cpu_to_le32_compile_time (EXT4_ENCRYPT_FLAG)) - { - err = grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "file is encrypted"); - 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->size |= ((grub_off_t) grub_le_to_cpu32 (data->inode->size_high)) << 32; file->data = data; file->offset = 0; @@ -953,7 +763,7 @@ grub_ext2_open (struct grub_file *file, const char *name) grub_dl_unref (my_mod); - return err; + return grub_errno; } static grub_err_t @@ -972,75 +782,64 @@ 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->read_hook_data, + return grub_ext2_read_file (&data->diropen, file->read_hook, file->offset, len, buf); } -/* Context for grub_ext2_dir. */ -struct grub_ext2_dir_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; - struct grub_ext2_data *data; -}; - -/* Helper for grub_ext2_dir. */ -static int -grub_ext2_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, void *data) -{ - struct grub_ext2_dir_ctx *ctx = data; - struct grub_dirhook_info info; - - grub_memset (&info, 0, sizeof (info)); - if (! node->inode_read) - { - grub_ext2_read_inode (ctx->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 ctx->hook (filename, &info, ctx->hook_data); -} - static grub_err_t -grub_ext2_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, - void *hook_data) +grub_ext2_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, + const struct grub_dirhook_info *info)) { - struct grub_ext2_dir_ctx ctx = { - .hook = hook, - .hook_data = hook_data - }; + 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); - ctx.data = grub_ext2_mount (device->disk); - if (! ctx.data) + data = grub_ext2_mount (device->disk); + if (! data) goto fail; - grub_fshelp_find_file (path, &ctx.data->diropen, &fdiro, - grub_ext2_iterate_dir, grub_ext2_read_symlink, - GRUB_FSHELP_DIR); + 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, grub_ext2_dir_iter, &ctx); + grub_ext2_iterate_dir (fdiro, iterate); fail: - if (fdiro != &ctx.data->diropen) + if (fdiro != &data->diropen) grub_free (fdiro); - grub_free (ctx.data); + grub_free (data); grub_dl_unref (my_mod); @@ -1057,8 +856,7 @@ grub_ext2_label (grub_device_t device, char **label) data = grub_ext2_mount (disk); if (data) - *label = grub_strndup (data->sblock.volume_name, - sizeof (data->sblock.volume_name)); + *label = grub_strndup (data->sblock.volume_name, 14); else *label = NULL; @@ -1102,7 +900,7 @@ grub_ext2_uuid (grub_device_t device, char **uuid) /* Get mtime. */ static grub_err_t -grub_ext2_mtime (grub_device_t device, grub_int64_t *tm) +grub_ext2_mtime (grub_device_t device, grub_int32_t *tm) { struct grub_ext2_data *data; grub_disk_t disk = device->disk; @@ -1128,23 +926,21 @@ grub_ext2_mtime (grub_device_t device, grub_int64_t *tm) static struct grub_fs grub_ext2_fs = { .name = "ext2", - .fs_dir = grub_ext2_dir, - .fs_open = grub_ext2_open, - .fs_read = grub_ext2_read, - .fs_close = grub_ext2_close, - .fs_label = grub_ext2_label, - .fs_uuid = grub_ext2_uuid, - .fs_mtime = grub_ext2_mtime, + .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, - .blocklist_install = 1, #endif .next = 0 }; GRUB_MOD_INIT(ext2) { - grub_ext2_fs.mod = mod; grub_fs_register (&grub_ext2_fs); my_mod = mod; } diff --git a/fs/fat.c b/fs/fat.c new file mode 100644 index 000000000..89050943c --- /dev/null +++ b/fs/fat.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 new file mode 100644 index 000000000..d0b1e493e --- /dev/null +++ b/fs/fshelp.c @@ -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 . + */ + +#include +#include +#include +#include +#include + + +/* 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/fs/hfs.c similarity index 54% rename from grub-core/fs/hfs.c rename to fs/hfs.c index ce7581dd5..cef856326 100644 --- a/grub-core/fs/hfs.c +++ b/fs/hfs.c @@ -28,11 +28,6 @@ #include #include #include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); #define GRUB_HFS_SBLOCK 2 #define GRUB_HFS_EMBED_HFSPLUS_SIG 0x482B @@ -67,7 +62,7 @@ struct grub_hfs_node grub_uint8_t level; grub_uint16_t reccnt; grub_uint16_t unused; -} GRUB_PACKED; +} __attribute__ ((packed)); /* The head of the B*-Tree. */ struct grub_hfs_treeheader @@ -83,7 +78,7 @@ struct grub_hfs_treeheader grub_uint32_t nodes; grub_uint32_t free_nodes; grub_uint8_t unused[76]; -} GRUB_PACKED; +} __attribute__ ((packed)); /* The state of a mounted HFS filesystem. */ struct grub_hfs_data @@ -114,7 +109,7 @@ struct grub_hfs_catalog_key /* Filename. */ grub_uint8_t str[31]; -} GRUB_PACKED; +} __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 @@ -127,7 +122,7 @@ struct grub_hfs_extent_key grub_uint8_t forktype; grub_uint32_t fileid; grub_uint16_t first_block; -} GRUB_PACKED; +} __attribute__ ((packed)); /* A directory record. This is used to find out the directory ID. */ struct grub_hfs_dirrec @@ -136,9 +131,7 @@ struct grub_hfs_dirrec grub_uint8_t type; grub_uint8_t unused[5]; grub_uint32_t dirid; - grub_uint32_t ctime; - grub_uint32_t mtime; -} GRUB_PACKED; +} __attribute__ ((packed)); /* Information about a file. */ struct grub_hfs_filerec @@ -149,29 +142,27 @@ struct grub_hfs_filerec grub_uint32_t fileid; grub_uint8_t unused2[2]; grub_uint32_t size; - grub_uint8_t unused3[18]; - grub_uint32_t mtime; - grub_uint8_t unused4[22]; + 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; -} GRUB_PACKED; +} __attribute__ ((packed)); /* A record descriptor, both key and data, used to pass to call back functions. */ struct grub_hfs_record { void *key; - grub_size_t keylen; + int keylen; void *data; - grub_size_t datalen; + int datalen; }; static grub_dl_t my_mod; static int grub_hfs_find_node (struct grub_hfs_data *, char *, - grub_uint32_t, int, char *, grub_size_t); + 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, @@ -245,26 +236,24 @@ grub_hfs_block (struct grub_hfs_data *data, grub_hfs_datarecord_t dat, POS. Return the amount of read bytes in READ. */ static grub_ssize_t grub_hfs_read_file (struct grub_hfs_data *data, - grub_disk_read_hook_t read_hook, void *read_hook_data, - grub_uint32_t pos, grub_size_t len, char *buf) + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + int pos, grub_size_t len, char *buf) { - grub_off_t i; - grub_off_t blockcnt; + int i; + int blockcnt; - /* Files are at most 2G/4G - 1 bytes on hfs. Avoid 64-bit division. - Moreover len > 0 as checked in upper layer. */ - blockcnt = (len + pos - 1) / data->blksz + 1; + blockcnt = ((len + pos) + + data->blksz - 1) / data->blksz; for (i = pos / data->blksz; i < blockcnt; i++) { - grub_disk_addr_t blknr; - grub_off_t blockoff; - grub_off_t blockend = data->blksz; + int blknr; + int blockoff = pos % data->blksz; + int blockend = data->blksz; int skipfirst = 0; - blockoff = pos % data->blksz; - blknr = grub_hfs_block (data, data->extents, data->fileid, i, 1); if (grub_errno) return -1; @@ -291,7 +280,6 @@ grub_hfs_read_file (struct grub_hfs_data *data, if (blknr) { data->disk->read_hook = read_hook; - data->disk->read_hook_data = read_hook_data; grub_disk_read (data->disk, blknr, skipfirst, blockend, buf); data->disk->read_hook = 0; @@ -331,9 +319,7 @@ grub_hfs_mount (grub_disk_t disk) goto fail; /* Check if this is a HFS filesystem. */ - if (grub_be_to_cpu16 (data->sblock.magic) != GRUB_HFS_MAGIC - || data->sblock.blksz == 0 - || (data->sblock.blksz & grub_cpu_to_be32_compile_time (0xc00001ff))) + if (grub_be_to_cpu16 (data->sblock.magic) != GRUB_HFS_MAGIC) { grub_error (GRUB_ERR_BAD_FS, "not an HFS filesystem"); goto fail; @@ -370,16 +356,11 @@ grub_hfs_mount (grub_disk_t disk) data->cat_root = grub_be_to_cpu32 (treehead.head.root_node); data->cat_size = grub_be_to_cpu16 (treehead.head.node_size); - if (data->cat_size == 0 - || data->blksz < data->cat_size - || data->blksz < data->ext_size) - goto fail; - /* Lookup the root directory node in the catalog tree using the volume name. */ - key.parent_dir = grub_cpu_to_be32_compile_time (1); + key.parent_dir = grub_cpu_to_be32 (1); key.strlen = data->sblock.volname[0]; - grub_strlcpy ((char *) key.str, (char *) (data->sblock.volname + 1), sizeof (key.str)); + 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) @@ -405,8 +386,8 @@ grub_hfs_mount (grub_disk_t disk) /* Compare the K1 and K2 catalog file keys using HFS character ordering. */ static int -grub_hfs_cmp_catkeys (const struct grub_hfs_catalog_key *k1, - const struct grub_hfs_catalog_key *k2) +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] = { @@ -649,8 +630,8 @@ grub_hfs_cmp_catkeys (const struct grub_hfs_catalog_key *k1, /* Compare the K1 and K2 extent overflow file keys. */ static int -grub_hfs_cmp_extkeys (const struct grub_hfs_extent_key *k1, - const struct grub_hfs_extent_key *k2) +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) @@ -669,32 +650,22 @@ grub_hfs_cmp_extkeys (const struct grub_hfs_extent_key *k1, 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 *, - void *hook_arg), - void *hook_arg) + struct grub_hfs_record *)) { - grub_size_t nodesize = type == 0 ? data->cat_size : data->ext_size; + int nodesize = type == 0 ? data->cat_size : data->ext_size; - union node_union + union { struct grub_hfs_node node; - char rawnode[0]; - grub_uint16_t offsets[0]; - } *node; - - if (nodesize < sizeof (struct grub_hfs_node)) - nodesize = sizeof (struct grub_hfs_node); - - node = grub_malloc (nodesize); - if (!node) - return grub_errno; + char rawnode[nodesize]; + grub_uint16_t offsets[nodesize / 2]; + } node; do { int i; struct grub_hfs_extent *dat; int blk; - grub_uint16_t reccnt; dat = (struct grub_hfs_extent *) (type == 0 ? (&data->sblock.catalog_recs) @@ -705,101 +676,40 @@ grub_hfs_iterate_records (struct grub_hfs_data *data, int type, int idx, (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_errno || grub_disk_read (data->disk, blk, 0, - nodesize, node)) - { - grub_free (node); - return grub_errno; - } - - reccnt = grub_be_to_cpu16 (node->node.reccnt); - if (reccnt > (nodesize >> 1)) - reccnt = (nodesize >> 1); + 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 < reccnt; i++) + 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; - } GRUB_PACKED *pnt; - grub_uint16_t off = grub_be_to_cpu16 (node->offsets[pos]); - if (off > nodesize - sizeof(*pnt)) - continue; - pnt = (struct pointer *) (off + node->rawnode); - if (nodesize < (grub_size_t) off + pnt->keylen + 1) - continue; + } __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 - off - pnt->keylen - 1 + nodesize - grub_be_to_cpu16 (node.offsets[pos]) + - pnt->keylen - 1 }; - if (node_hook (&node->node, &rec, hook_arg)) - { - grub_free (node); - return 0; - } + if (node_hook (&node.node, &rec)) + return 0; } - idx = grub_be_to_cpu32 (node->node.next); + idx = grub_be_to_cpu32 (node.node.next); } while (idx && this); - grub_free (node); - return 0; -} - -struct grub_hfs_find_node_node_found_ctx -{ - int found; - int isleaf; - int done; - int type; - const char *key; - char *datar; - grub_size_t datalen; -}; - -static int -grub_hfs_find_node_node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec, - void *hook_arg) -{ - struct grub_hfs_find_node_node_found_ctx *ctx = hook_arg; - int cmp = 1; - - if (ctx->type == 0) - cmp = grub_hfs_cmp_catkeys (rec->key, (const void *) ctx->key); - else - cmp = grub_hfs_cmp_extkeys (rec->key, (const void *) ctx->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) - ctx->found = grub_be_to_cpu32 (grub_get_unaligned32 (rec->data)); - 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) - { - ctx->isleaf = 1; - - /* Found it!!!! */ - if (cmp == 0) - { - ctx->done = 1; - - grub_memcpy (ctx->datar, rec->data, - rec->datalen < ctx->datalen ? rec->datalen : ctx->datalen); - return 1; - } - } return 0; } @@ -811,84 +721,67 @@ grub_hfs_find_node_node_found (struct grub_hfs_node *hnd, struct grub_hfs_record 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, grub_size_t datalen) + grub_uint32_t idx, int type, char *datar, int datalen) { - struct grub_hfs_find_node_node_found_ctx ctx = + 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) { - .found = -1, - .isleaf = 0, - .done = 0, - .type = type, - .key = key, - .datar = datar, - .datalen = datalen - }; + 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 { - ctx.found = -1; + found = -1; - if (grub_hfs_iterate_records (data, type, idx, 0, grub_hfs_find_node_node_found, &ctx)) + if (grub_hfs_iterate_records (data, type, idx, 0, node_found)) return 0; - if (ctx.found == -1) + if (found == -1) return 0; - idx = ctx.found; - } while (! ctx.isleaf); + idx = found; + } while (! isleaf); - return ctx.done; -} - -struct grub_hfs_iterate_dir_node_found_ctx -{ - grub_uint32_t dir_be; - int found; - int isleaf; - grub_uint32_t next; - int (*hook) (struct grub_hfs_record *, void *hook_arg); - void *hook_arg; -}; - -static int -grub_hfs_iterate_dir_node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec, - void *hook_arg) -{ - struct grub_hfs_iterate_dir_node_found_ctx *ctx = hook_arg; - struct grub_hfs_catalog_key *ckey = rec->key; - - /* The lowest key possible with DIR as root directory. */ - const struct grub_hfs_catalog_key key = {0, ctx->dir_be, 0, ""}; - - if (grub_hfs_cmp_catkeys (rec->key, &key) <= 0) - ctx->found = grub_be_to_cpu32 (grub_get_unaligned32 (rec->data)); - - if (hnd->type == 0xFF && ckey->strlen > 0) - { - ctx->isleaf = 1; - ctx->next = grub_be_to_cpu32 (hnd->next); - - /* An entry was found. */ - if (ckey->parent_dir == ctx->dir_be) - return ctx->hook (rec, ctx->hook_arg); - } - - return 0; -} - -static int -grub_hfs_iterate_dir_it_dir (struct grub_hfs_node *hnd __attribute ((unused)), - struct grub_hfs_record *rec, - void *hook_arg) -{ - struct grub_hfs_catalog_key *ckey = rec->key; - struct grub_hfs_iterate_dir_node_found_ctx *ctx = hook_arg; - - /* Stop when the entries do not match anymore. */ - if (ckey->parent_dir != ctx->dir_be) - return 1; - - return ctx->hook (rec, ctx->hook_arg); + return done; } @@ -897,375 +790,185 @@ grub_hfs_iterate_dir_it_dir (struct grub_hfs_node *hnd __attribute ((unused)), call HOOK. */ static grub_err_t grub_hfs_iterate_dir (struct grub_hfs_data *data, grub_uint32_t root_idx, - grub_uint32_t dir, int (*hook) (struct grub_hfs_record *, void *hook_arg), - void *hook_arg) + unsigned int dir, int (*hook) (struct grub_hfs_record *)) { - struct grub_hfs_iterate_dir_node_found_ctx ctx = - { - .dir_be = grub_cpu_to_be32 (dir), - .found = -1, - .isleaf = 0, - .next = 0, - .hook = hook, - .hook_arg = hook_arg - }; + 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 { - ctx.found = -1; + found = -1; - if (grub_hfs_iterate_records (data, 0, root_idx, 0, grub_hfs_iterate_dir_node_found, &ctx)) + if (grub_hfs_iterate_records (data, 0, root_idx, 0, node_found)) return grub_errno; - if (ctx.found == -1) + if (found == -1) return 0; - root_idx = ctx.found; - } while (! ctx.isleaf); + 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, ctx.next, 1, grub_hfs_iterate_dir_it_dir, &ctx); + grub_hfs_iterate_records (data, 0, next, 1, it_dir); return grub_errno; } -#define MAX_UTF8_PER_MAC_ROMAN 3 - -static const char macroman[0x80][MAX_UTF8_PER_MAC_ROMAN + 1] = - { - /* 80 */ "\xc3\x84", - /* 81 */ "\xc3\x85", - /* 82 */ "\xc3\x87", - /* 83 */ "\xc3\x89", - /* 84 */ "\xc3\x91", - /* 85 */ "\xc3\x96", - /* 86 */ "\xc3\x9c", - /* 87 */ "\xc3\xa1", - /* 88 */ "\xc3\xa0", - /* 89 */ "\xc3\xa2", - /* 8A */ "\xc3\xa4", - /* 8B */ "\xc3\xa3", - /* 8C */ "\xc3\xa5", - /* 8D */ "\xc3\xa7", - /* 8E */ "\xc3\xa9", - /* 8F */ "\xc3\xa8", - /* 90 */ "\xc3\xaa", - /* 91 */ "\xc3\xab", - /* 92 */ "\xc3\xad", - /* 93 */ "\xc3\xac", - /* 94 */ "\xc3\xae", - /* 95 */ "\xc3\xaf", - /* 96 */ "\xc3\xb1", - /* 97 */ "\xc3\xb3", - /* 98 */ "\xc3\xb2", - /* 99 */ "\xc3\xb4", - /* 9A */ "\xc3\xb6", - /* 9B */ "\xc3\xb5", - /* 9C */ "\xc3\xba", - /* 9D */ "\xc3\xb9", - /* 9E */ "\xc3\xbb", - /* 9F */ "\xc3\xbc", - /* A0 */ "\xe2\x80\xa0", - /* A1 */ "\xc2\xb0", - /* A2 */ "\xc2\xa2", - /* A3 */ "\xc2\xa3", - /* A4 */ "\xc2\xa7", - /* A5 */ "\xe2\x80\xa2", - /* A6 */ "\xc2\xb6", - /* A7 */ "\xc3\x9f", - /* A8 */ "\xc2\xae", - /* A9 */ "\xc2\xa9", - /* AA */ "\xe2\x84\xa2", - /* AB */ "\xc2\xb4", - /* AC */ "\xc2\xa8", - /* AD */ "\xe2\x89\xa0", - /* AE */ "\xc3\x86", - /* AF */ "\xc3\x98", - /* B0 */ "\xe2\x88\x9e", - /* B1 */ "\xc2\xb1", - /* B2 */ "\xe2\x89\xa4", - /* B3 */ "\xe2\x89\xa5", - /* B4 */ "\xc2\xa5", - /* B5 */ "\xc2\xb5", - /* B6 */ "\xe2\x88\x82", - /* B7 */ "\xe2\x88\x91", - /* B8 */ "\xe2\x88\x8f", - /* B9 */ "\xcf\x80", - /* BA */ "\xe2\x88\xab", - /* BB */ "\xc2\xaa", - /* BC */ "\xc2\xba", - /* BD */ "\xce\xa9", - /* BE */ "\xc3\xa6", - /* BF */ "\xc3\xb8", - /* C0 */ "\xc2\xbf", - /* C1 */ "\xc2\xa1", - /* C2 */ "\xc2\xac", - /* C3 */ "\xe2\x88\x9a", - /* C4 */ "\xc6\x92", - /* C5 */ "\xe2\x89\x88", - /* C6 */ "\xe2\x88\x86", - /* C7 */ "\xc2\xab", - /* C8 */ "\xc2\xbb", - /* C9 */ "\xe2\x80\xa6", - /* CA */ "\xc2\xa0", - /* CB */ "\xc3\x80", - /* CC */ "\xc3\x83", - /* CD */ "\xc3\x95", - /* CE */ "\xc5\x92", - /* CF */ "\xc5\x93", - /* D0 */ "\xe2\x80\x93", - /* D1 */ "\xe2\x80\x94", - /* D2 */ "\xe2\x80\x9c", - /* D3 */ "\xe2\x80\x9d", - /* D4 */ "\xe2\x80\x98", - /* D5 */ "\xe2\x80\x99", - /* D6 */ "\xc3\xb7", - /* D7 */ "\xe2\x97\x8a", - /* D8 */ "\xc3\xbf", - /* D9 */ "\xc5\xb8", - /* DA */ "\xe2\x81\x84", - /* DB */ "\xe2\x82\xac", - /* DC */ "\xe2\x80\xb9", - /* DD */ "\xe2\x80\xba", - /* DE */ "\xef\xac\x81", - /* DF */ "\xef\xac\x82", - /* E0 */ "\xe2\x80\xa1", - /* E1 */ "\xc2\xb7", - /* E2 */ "\xe2\x80\x9a", - /* E3 */ "\xe2\x80\x9e", - /* E4 */ "\xe2\x80\xb0", - /* E5 */ "\xc3\x82", - /* E6 */ "\xc3\x8a", - /* E7 */ "\xc3\x81", - /* E8 */ "\xc3\x8b", - /* E9 */ "\xc3\x88", - /* EA */ "\xc3\x8d", - /* EB */ "\xc3\x8e", - /* EC */ "\xc3\x8f", - /* ED */ "\xc3\x8c", - /* EE */ "\xc3\x93", - /* EF */ "\xc3\x94", - /* F0 */ "\xef\xa3\xbf", - /* F1 */ "\xc3\x92", - /* F2 */ "\xc3\x9a", - /* F3 */ "\xc3\x9b", - /* F4 */ "\xc3\x99", - /* F5 */ "\xc4\xb1", - /* F6 */ "\xcb\x86", - /* F7 */ "\xcb\x9c", - /* F8 */ "\xc2\xaf", - /* F9 */ "\xcb\x98", - /* FA */ "\xcb\x99", - /* FB */ "\xcb\x9a", - /* FC */ "\xc2\xb8", - /* FD */ "\xcb\x9d", - /* FE */ "\xcb\x9b", - /* FF */ "\xcb\x87", - }; - -static void -macroman_to_utf8 (char *to, const grub_uint8_t *from, grub_size_t len, - int translate_slash) -{ - char *optr = to; - const grub_uint8_t *iptr; - - for (iptr = from; iptr < from + len && *iptr; iptr++) - { - /* Translate '/' to ':' as per HFS spec. */ - if (*iptr == '/' && translate_slash) - { - *optr++ = ':'; - continue; - } - if (!(*iptr & 0x80)) - { - *optr++ = *iptr; - continue; - } - optr = grub_stpcpy (optr, macroman[*iptr & 0x7f]); - } - *optr = 0; -} - -static grub_ssize_t -utf8_to_macroman (grub_uint8_t *to, const char *from) -{ - grub_uint8_t *end = to + 31; - grub_uint8_t *optr = to; - const char *iptr = from; - - while (*iptr && optr < end) - { - int i, clen; - /* Translate ':' to '/' as per HFS spec. */ - if (*iptr == ':') - { - *optr++ = '/'; - iptr++; - continue; - } - if (!(*iptr & 0x80)) - { - *optr++ = *iptr++; - continue; - } - clen = 2; - if ((*iptr & 0xf0) == 0xe0) - clen++; - for (i = 0; i < 0x80; i++) - if (grub_memcmp (macroman[i], iptr, clen) == 0) - break; - if (i == 0x80) - break; - *optr++ = i | 0x80; - iptr += clen; - } - /* Too long or not encodable. */ - if (*iptr) - return -1; - return optr - to; -} - -union grub_hfs_anyrec { - struct grub_hfs_filerec frec; - struct grub_hfs_dirrec dir; -}; - -struct grub_fshelp_node -{ - struct grub_hfs_data *data; - union grub_hfs_anyrec fdrec; - grub_uint32_t inode; -}; - -static grub_err_t -lookup_file (grub_fshelp_node_t dir, - const char *name, - grub_fshelp_node_t *foundnode, - enum grub_fshelp_filetype *foundtype) -{ - struct grub_hfs_catalog_key key; - grub_ssize_t slen; - union grub_hfs_anyrec fdrec; - - key.parent_dir = grub_cpu_to_be32 (dir->inode); - slen = utf8_to_macroman (key.str, name); - if (slen < 0) - /* Not found */ - return GRUB_ERR_NONE; - key.strlen = slen; - - /* Lookup this node. */ - if (! grub_hfs_find_node (dir->data, (char *) &key, dir->data->cat_root, - 0, (char *) &fdrec.frec, sizeof (fdrec.frec))) - /* Not found */ - return GRUB_ERR_NONE; - - *foundnode = grub_malloc (sizeof (struct grub_fshelp_node)); - if (!*foundnode) - return grub_errno; - - (*foundnode)->inode = grub_be_to_cpu32 (fdrec.dir.dirid); - (*foundnode)->fdrec = fdrec; - (*foundnode)->data = dir->data; - *foundtype = (fdrec.frec.type == GRUB_HFS_FILETYPE_DIR) ? GRUB_FSHELP_DIR : GRUB_FSHELP_REG; - return GRUB_ERR_NONE; -} /* 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, - grub_fshelp_node_t *found, - enum grub_fshelp_filetype exptype) + struct grub_hfs_filerec *retdata, int *retinode) { - struct grub_fshelp_node root = { - .data = data, - .inode = data->rootdir, - .fdrec = { - .frec = { - .type = GRUB_HFS_FILETYPE_DIR - } - } - }; - grub_err_t err; + int inode = data->rootdir; + char *next; + char *origpath; + union { + struct grub_hfs_filerec frec; + struct grub_hfs_dirrec dir; + } fdrec; - err = grub_fshelp_find_file_lookup (path, &root, found, lookup_file, NULL, exptype); + fdrec.frec.type = GRUB_HFS_FILETYPE_DIR; - if (&root == *found) + if (path[0] != '/') { - *found = grub_malloc (sizeof (root)); - if (!*found) - return grub_errno; - grub_memcpy (*found, &root, sizeof (root)); + grub_error (GRUB_ERR_BAD_FILENAME, "bad filename"); + return 0; } - return err; + + 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; } -struct grub_hfs_dir_hook_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; -}; - -static int -grub_hfs_dir_hook (struct grub_hfs_record *rec, void *hook_arg) -{ - struct grub_hfs_dir_hook_ctx *ctx = hook_arg; - struct grub_hfs_dirrec *drec = rec->data; - struct grub_hfs_filerec *frec = rec->data; - struct grub_hfs_catalog_key *ckey = rec->key; - char fname[sizeof (ckey->str) * MAX_UTF8_PER_MAC_ROMAN + 1]; - struct grub_dirhook_info info; - grub_size_t len; - - grub_memset (fname, 0, sizeof (fname)); - - grub_memset (&info, 0, sizeof (info)); - - len = ckey->strlen; - if (len > sizeof (ckey->str)) - len = sizeof (ckey->str); - macroman_to_utf8 (fname, ckey->str, len, 1); - - info.case_insensitive = 1; - - if (drec->type == GRUB_HFS_FILETYPE_DIR) - { - info.dir = 1; - info.mtimeset = 1; - info.inodeset = 1; - info.mtime = grub_be_to_cpu32 (drec->mtime) - 2082844800; - info.inode = grub_be_to_cpu32 (drec->dirid); - return ctx->hook (fname, &info, ctx->hook_data); - } - if (frec->type == GRUB_HFS_FILETYPE_FILE) - { - info.dir = 0; - info.mtimeset = 1; - info.inodeset = 1; - info.mtime = grub_be_to_cpu32 (frec->mtime) - 2082844800; - info.inode = grub_be_to_cpu32 (frec->fileid); - return ctx->hook (fname, &info, ctx->hook_data); - } - - return 0; -} static grub_err_t -grub_hfs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, - void *hook_data) +grub_hfs_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, + const struct grub_dirhook_info *info)) { - struct grub_hfs_data *data; - struct grub_hfs_dir_hook_ctx ctx = + int inode; + + auto int dir_hook (struct grub_hfs_record *rec); + + int dir_hook (struct grub_hfs_record *rec) { - .hook = hook, - .hook_data = hook_data - }; - grub_fshelp_node_t found = NULL; + 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); @@ -1274,13 +977,18 @@ grub_hfs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, goto fail; /* First the directory ID for the directory. */ - if (grub_hfs_find_dir (data, path, &found, GRUB_FSHELP_DIR)) + if (grub_hfs_find_dir (data, path, &frec, &inode)) goto fail; - grub_hfs_iterate_dir (data, data->cat_root, found->inode, grub_hfs_dir_hook, &ctx); + 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 (found); grub_free (data); grub_dl_unref (my_mod); @@ -1294,36 +1002,35 @@ static grub_err_t grub_hfs_open (struct grub_file *file, const char *name) { struct grub_hfs_data *data; - grub_fshelp_node_t found = NULL; + struct grub_hfs_filerec frec; grub_dl_ref (my_mod); data = grub_hfs_mount (file->device->disk); - if (!data) - { - grub_dl_unref (my_mod); - return grub_errno; - } - - if (grub_hfs_find_dir (data, name, &found, GRUB_FSHELP_REG)) + if (grub_hfs_find_dir (data, name, &frec, 0)) { grub_free (data); - grub_free (found); grub_dl_unref (my_mod); return grub_errno; } - grub_memcpy (data->extents, found->fdrec.frec.extents, sizeof (grub_hfs_datarecord_t)); - file->size = grub_be_to_cpu32 (found->fdrec.frec.size); - data->size = grub_be_to_cpu32 (found->fdrec.frec.size); - data->fileid = grub_be_to_cpu32 (found->fdrec.frec.fileid); + 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; - grub_free (found); - return 0; } @@ -1333,8 +1040,7 @@ 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->read_hook_data, - file->offset, len, buf); + return grub_hfs_read_file (data, file->read_hook, file->offset, len, buf); } @@ -1357,15 +1063,8 @@ grub_hfs_label (grub_device_t device, char **label) data = grub_hfs_mount (device->disk); if (data) - { - grub_size_t len = data->sblock.volname[0]; - if (len > sizeof (data->sblock.volname) - 1) - len = sizeof (data->sblock.volname) - 1; - *label = grub_calloc (MAX_UTF8_PER_MAC_ROMAN + 1, len); - if (*label) - macroman_to_utf8 (*label, data->sblock.volname + 1, - len + 1, 0); - } + *label = grub_strndup ((char *) (data->sblock.volname + 1), + *data->sblock.volname); else *label = 0; @@ -1373,22 +1072,6 @@ grub_hfs_label (grub_device_t device, char **label) return grub_errno; } -static grub_err_t -grub_hfs_mtime (grub_device_t device, grub_int64_t *tm) -{ - struct grub_hfs_data *data; - - data = grub_hfs_mount (device->disk); - - if (data) - *tm = grub_be_to_cpu32 (data->sblock.mtime) - 2082844800; - else - *tm = 0; - - grub_free (data); - return grub_errno; -} - static grub_err_t grub_hfs_uuid (grub_device_t device, char **uuid) { @@ -1418,30 +1101,22 @@ grub_hfs_uuid (grub_device_t device, char **uuid) static struct grub_fs grub_hfs_fs = { .name = "hfs", - .fs_dir = grub_hfs_dir, - .fs_open = grub_hfs_open, - .fs_read = grub_hfs_read, - .fs_close = grub_hfs_close, - .fs_label = grub_hfs_label, - .fs_uuid = grub_hfs_uuid, - .fs_mtime = grub_hfs_mtime, -#ifdef GRUB_UTIL - .reserved_first_sector = 1, - .blocklist_install = 1, -#endif + .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_hfs_fs.mod = mod; - if (!grub_is_lockdown ()) - grub_fs_register (&grub_hfs_fs); + grub_fs_register (&grub_hfs_fs); my_mod = mod; } GRUB_MOD_FINI(hfs) { - if (!grub_is_lockdown()) - grub_fs_unregister (&grub_hfs_fs); + grub_fs_unregister (&grub_hfs_fs); } diff --git a/grub-core/fs/hfsplus.c b/fs/hfsplus.c similarity index 50% rename from grub-core/fs/hfsplus.c rename to fs/hfsplus.c index 3f203abcc..bcb8e9584 100644 --- a/grub-core/fs/hfsplus.c +++ b/fs/hfsplus.c @@ -19,7 +19,6 @@ /* HFS+ is documented at http://developer.apple.com/technotes/tn/tn1150.html */ -#define grub_fshelp_node grub_hfsplus_file #include #include #include @@ -30,10 +29,47 @@ #include #include #include -#include -#include -GRUB_MOD_LICENSE ("GPLv3+"); +#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 @@ -44,6 +80,16 @@ enum grub_hfsplus_btnode_type 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 { @@ -61,13 +107,42 @@ struct grub_hfsplus_btheader grub_uint8_t btree_type; grub_uint8_t key_compare; grub_uint32_t attributes; -} GRUB_PACKED; +} __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 parentid; /* Thread only. */ + grub_uint32_t reserved; grub_uint32_t fileid; grub_uint8_t unused1[4]; grub_uint32_t mtime; @@ -76,7 +151,7 @@ struct grub_hfsplus_catfile grub_uint8_t unused3[44]; struct grub_hfsplus_forkdata data; struct grub_hfsplus_forkdata resource; -} GRUB_PACKED; +} __attribute__ ((packed)); /* Filetype information as used in inodes. */ #define GRUB_HFSPLUS_FILEMODE_MASK 0170000 @@ -84,20 +159,10 @@ struct grub_hfsplus_catfile #define GRUB_HFSPLUS_FILEMODE_DIRECTORY 0040000 #define GRUB_HFSPLUS_FILEMODE_SYMLINK 0120000 -#define HFSPLUS_BTNODE_MINSZ (1 << 9) -#define HFSPLUS_BTNODE_MAXSZ (1 << 15) - -#define HFSPLUS_CATKEY_MIN_LEN 6 -#define HFSPLUS_CATKEY_MAX_LEN 516 - /* Some pre-defined file IDs. */ -enum - { - GRUB_HFSPLUS_FILEID_ROOTDIR = 2, - GRUB_HFSPLUS_FILEID_OVERFLOW = 3, - GRUB_HFSPLUS_FILEID_CATALOG = 4, - GRUB_HFSPLUS_FILEID_ATTR = 8 - }; +#define GRUB_HFSPLUS_FILEID_ROOTDIR 2 +#define GRUB_HFSPLUS_FILEID_OVERFLOW 3 +#define GRUB_HFSPLUS_FILEID_CATALOG 4 enum grub_hfsplus_filetype { @@ -110,25 +175,107 @@ enum grub_hfsplus_filetype #define GRUB_HFSPLUSX_BINARYCOMPARE 0xBC #define GRUB_HFSPLUSX_CASEFOLDING 0xCF -static grub_dl_t my_mod; +/* 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; + }; +}; -grub_err_t (*grub_hfsplus_open_compressed) (struct grub_fshelp_node *node); -grub_ssize_t (*grub_hfsplus_read_compressed) (struct grub_hfsplus_file *node, - grub_off_t pos, - grub_size_t len, - char *buf); +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; + + +/* 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 grub_disk_addr_t +static int grub_hfsplus_find_block (struct grub_hfsplus_extent *extent, - grub_disk_addr_t *fileblock) + int *fileblock) { int i; - grub_disk_addr_t blksleft = *fileblock; + grub_size_t blksleft = *fileblock; /* First lookup the file in the given extents. */ for (i = 0; i < 8; i++) @@ -139,9 +286,16 @@ grub_hfsplus_find_block (struct grub_hfsplus_extent *extent, } *fileblock = blksleft; - return 0xffffffffffffffffULL; + 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); @@ -151,16 +305,15 @@ 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; - grub_disk_addr_t blksleft = fileblock; - struct grub_hfsplus_extent *extents = node->compressed - ? &node->resource_extents[0] : &node->extents[0]; + int blksleft = fileblock; + struct grub_hfsplus_extent *extents = &node->extents[0]; while (1) { struct grub_hfsplus_extkey *key; - struct grub_hfsplus_key_internal extoverflow; - grub_disk_addr_t blk; - grub_off_t ptr; + 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); @@ -170,8 +323,10 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) grub_free (nnode); nnode = 0; - if (blk != 0xffffffffffffffffULL) - return blk; + 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 @@ -183,30 +338,16 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) break; } - /* - * If the extent overflow tree isn't ready yet, we can't look - * in it. This can happen where the catalog file is corrupted. - */ - if (!node->data->extoverflow_tree_ready) - { - grub_error (GRUB_ERR_BAD_FS, - "attempted to read extent overflow tree before loading"); - break; - } - /* Set up the key to look for in the extent overflow file. */ - extoverflow.extkey.fileid = node->fileid; - extoverflow.extkey.type = 0; - extoverflow.extkey.start = fileblock - blksleft; - extoverflow.extkey.type = node->compressed ? 0xff : 0; + extoverflow.fileid = node->fileid; + extoverflow.start = fileblock - blksleft; + if (grub_hfsplus_btree_search (&node->data->extoverflow_tree, - &extoverflow, - grub_hfsplus_cmp_extkey, &nnode, &ptr) - || !nnode) + (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%" PRIuGRUB_UINT64_T, + "no block found for the file id 0x%x and the block offset 0x%x", node->fileid, fileblock); break; } @@ -229,17 +370,16 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) /* Read LEN bytes from the file described by DATA starting with byte POS. Return the amount of read bytes in READ. */ -grub_ssize_t +static grub_ssize_t grub_hfsplus_read_file (grub_fshelp_node_t node, - grub_disk_read_hook_t read_hook, void *read_hook_data, - grub_off_t pos, grub_size_t len, char *buf) + 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, read_hook_data, + 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, - node->data->embedded_offset); + node->data->log2blksize - GRUB_DISK_SECTOR_BITS); } static struct grub_hfsplus_data * @@ -259,7 +399,6 @@ grub_hfsplus_mount (grub_disk_t disk) return 0; data->disk = disk; - data->extoverflow_tree_ready = 0; /* Read the bootblock. */ grub_disk_read (disk, GRUB_HFSPLUS_SBLOCK, 0, sizeof (volheader), @@ -270,9 +409,9 @@ grub_hfsplus_mount (grub_disk_t disk) data->embedded_offset = 0; if (grub_be_to_cpu16 (volheader.hfs.magic) == GRUB_HFS_MAGIC) { - grub_disk_addr_t extent_start; - grub_disk_addr_t ablk_size; - grub_disk_addr_t ablk_start; + 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) @@ -298,46 +437,31 @@ grub_hfsplus_mount (grub_disk_t disk) /* 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)) - || volheader.hfsplus.blksize == 0 - || ((volheader.hfsplus.blksize & (volheader.hfsplus.blksize - 1)) != 0) - || grub_be_to_cpu32 (volheader.hfsplus.blksize) < GRUB_DISK_SECTOR_SIZE) + 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)); + sizeof (volheader.hfsplus)); - for (data->log2blksize = 0; - (1U << data->log2blksize) < grub_be_to_cpu32 (data->volheader.blksize); - data->log2blksize++); + 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; - data->catalog_tree.file.compressed = 0; 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); - data->attr_tree.file.data = data; - data->attr_tree.file.fileid = GRUB_HFSPLUS_FILEID_ATTR; - grub_memcpy (&data->attr_tree.file.extents, - data->volheader.attr_file.extents, - sizeof data->volheader.attr_file.extents); - - data->attr_tree.file.size = - grub_be_to_cpu64 (data->volheader.attr_file.size); - data->attr_tree.file.compressed = 0; - /* Make a new node for the extent overflow file. */ data->extoverflow_tree.file.data = data; data->extoverflow_tree.file.fileid = GRUB_HFSPLUS_FILEID_OVERFLOW; - data->extoverflow_tree.file.compressed = 0; grub_memcpy (&data->extoverflow_tree.file.extents, data->volheader.extents_file.extents, sizeof data->volheader.catalog_file.extents); @@ -346,7 +470,7 @@ grub_hfsplus_mount (grub_disk_t disk) 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, 0, + if (grub_hfsplus_read_file (&data->catalog_tree.file, 0, sizeof (struct grub_hfsplus_btnode), sizeof (header), (char *) &header) <= 0) goto fail; @@ -356,48 +480,20 @@ grub_hfsplus_mount (grub_disk_t disk) data->case_sensitive = ((magic == GRUB_HFSPLUSX_MAGIC) && (header.key_compare == GRUB_HFSPLUSX_BINARYCOMPARE)); - if (data->catalog_tree.nodesize < 2) - { - grub_error (GRUB_ERR_BAD_FS, "invalid catalog node size"); - goto fail; - } - - if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0, + 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, 0, + 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); - if (data->extoverflow_tree.nodesize < 2) - { - grub_error (GRUB_ERR_BAD_FS, "invalid extents overflow node size"); - goto fail; - } - - data->extoverflow_tree_ready = 1; - - if (grub_hfsplus_read_file (&data->attr_tree.file, 0, 0, - sizeof (struct grub_hfsplus_btnode), - sizeof (header), (char *) &header) <= 0) - { - grub_errno = 0; - data->attr_tree.root = 0; - data->attr_tree.nodesize = 0; - } - else - { - data->attr_tree.root = grub_be_to_cpu32 (header.root); - data->attr_tree.nodesize = grub_be_to_cpu16 (header.nodesize); - } - data->dirroot.data = data; data->dirroot.fileid = GRUB_HFSPLUS_FILEID_ROOTDIR; @@ -405,7 +501,7 @@ grub_hfsplus_mount (grub_disk_t disk) fail: - if (grub_errno == GRUB_ERR_OUT_OF_RANGE || grub_errno == GRUB_ERR_NONE) + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem"); grub_free (data); @@ -420,48 +516,37 @@ grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya, { struct grub_hfsplus_catkey *catkey_a = &keya->catkey; struct grub_hfsplus_catkey_internal *catkey_b = &keyb->catkey; + char *filename; + int i; int diff; - grub_size_t len; - /* Safe unsigned comparison */ - grub_uint32_t aparent = grub_be_to_cpu32 (catkey_a->parent); - if (aparent > catkey_b->parent) - return 1; - if (aparent < catkey_b->parent) - return -1; + diff = grub_be_to_cpu32 (catkey_a->parent) - catkey_b->parent; + if (diff) + return diff; - len = grub_be_to_cpu16 (catkey_a->namelen); - if (len > catkey_b->namelen) - len = catkey_b->namelen; - /* Since it's big-endian memcmp gives the same result as manually comparing - uint16_t but may be faster. */ - diff = grub_memcmp (catkey_a->name, catkey_b->name, - len * sizeof (catkey_a->name[0])); - if (diff == 0) - diff = grub_be_to_cpu16 (catkey_a->namelen) - catkey_b->namelen; + /* 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 catalog key KEYA with the catalog key we are - looking for (KEYB). */ -static int -grub_hfsplus_cmp_catkey_id (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; - - /* Safe unsigned comparison */ - grub_uint32_t aparent = grub_be_to_cpu32 (catkey_a->parent); - if (aparent > catkey_b->parent) - return 1; - if (aparent < catkey_b->parent) - return -1; - - return 0; -} - /* Compare the on disk extent overflow key KEYA with the extent overflow key we are looking for (KEYB). */ static int @@ -470,32 +555,15 @@ grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya, { struct grub_hfsplus_extkey *extkey_a = &keya->extkey; struct grub_hfsplus_extkey_internal *extkey_b = &keyb->extkey; - grub_uint32_t akey; + int diff; - /* Safe unsigned comparison */ - akey = grub_be_to_cpu32 (extkey_a->fileid); - if (akey > extkey_b->fileid) - return 1; - if (akey < extkey_b->fileid) - return -1; + diff = grub_be_to_cpu32 (extkey_a->fileid) - extkey_b->fileid; - if (extkey_a->type > extkey_b->type) - return 1; - if (extkey_a->type < extkey_b->type) - return -1; + if (diff) + return diff; - if (extkey_a->type > extkey_b->type) - return +1; - - if (extkey_a->type < extkey_b->type) - return -1; - - akey = grub_be_to_cpu32 (extkey_a->start); - if (akey > extkey_b->start) - return 1; - if (akey < extkey_b->start) - return -1; - return 0; + diff = grub_be_to_cpu32 (extkey_a->start) - extkey_b->start; + return diff; } static char * @@ -503,16 +571,12 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node) { char *symlink; grub_ssize_t numread; - grub_size_t sz = node->size; - if (grub_add (sz, 1, &sz)) - return NULL; - - symlink = grub_malloc (sz); + symlink = grub_malloc (node->size + 1); if (!symlink) return 0; - numread = grub_hfsplus_read_file (node, 0, 0, 0, node->size, symlink); + numread = grub_hfsplus_read_file (node, 0, 0, node->size, symlink); if (numread != (grub_ssize_t) node->size) { grub_free (symlink); @@ -526,13 +590,10 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node) static int grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree, struct grub_hfsplus_btnode *first_node, - grub_disk_addr_t first_rec, - int (*hook) (void *record, void *hook_arg), - void *hook_arg) + int first_rec, + int (*hook) (void *record)) { - grub_disk_addr_t rec; - grub_uint64_t saved_node = -1; - grub_uint64_t node_count = 0; + int rec; for (;;) { @@ -541,25 +602,15 @@ grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree, /* 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), hook_arg)) + if (hook (grub_hfsplus_btree_recptr (btree, first_node, rec))) return 1; } if (! first_node->next) break; - if (node_count && first_node->next == saved_node) - { - grub_error (GRUB_ERR_BAD_FS, "HFS+ btree loop"); - return 0; - } - if (!(node_count & (node_count - 1))) - saved_node = first_node->next; - node_count++; - - if (grub_hfsplus_read_file (&btree->file, 0, 0, - (((grub_disk_addr_t) - grub_be_to_cpu32 (first_node->next)) + if (grub_hfsplus_read_file (&btree->file, 0, + (grub_be_to_cpu32 (first_node->next) * btree->nodesize), btree->nodesize, cnode) <= 0) return 1; @@ -575,54 +626,30 @@ grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree, 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. */ -grub_err_t +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, - grub_off_t *keyoffset) + struct grub_hfsplus_btnode **matchnode, int *keyoffset) { grub_uint64_t currnode; char *node; struct grub_hfsplus_btnode *nodedesc; - grub_disk_addr_t rec; - grub_uint64_t save_node; - grub_uint64_t node_count = 0; - - if (!btree->nodesize) - { - *matchnode = 0; - return 0; - } - - if (btree->nodesize < HFSPLUS_BTNODE_MINSZ || - btree->nodesize > HFSPLUS_BTNODE_MAXSZ) - return grub_error (GRUB_ERR_BAD_FS, "invalid HFS+ btree node size"); + int rec; node = grub_malloc (btree->nodesize); if (! node) return grub_errno; currnode = btree->root; - save_node = currnode - 1; while (1) { int match = 0; - if (save_node == currnode) - { - grub_free (node); - return grub_error (GRUB_ERR_BAD_FS, "HFS+ btree loop"); - } - if (!(node_count & (node_count - 1))) - save_node = currnode; - node_count++; - /* Read a node. */ - if (grub_hfsplus_read_file (&btree->file, 0, 0, - (grub_disk_addr_t) currnode - * (grub_disk_addr_t) btree->nodesize, + if (grub_hfsplus_read_file (&btree->file, 0, + (long)currnode * (long)btree->nodesize, btree->nodesize, (char *) node) <= 0) { grub_free (node); @@ -651,7 +678,7 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, } else if (nodedesc->type == GRUB_HFSPLUS_BTNODE_TYPE_INDEX) { - void *pointer; + grub_uint32_t *pointer; /* The place where the key could have been found didn't contain the key. This means that the previous match @@ -663,17 +690,10 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, that we are looking for. The last match that is found will be used to locate the child which can contain the record. */ - pointer = ((char *) currkey - + grub_be_to_cpu16 (currkey->keylen) - + 2); - - if ((char *) pointer > node + btree->nodesize - 2) - { - grub_free (node); - return grub_error (GRUB_ERR_BAD_FS, "HFS+ key beyond end of node"); - } - - currnode = grub_be_to_cpu32 (grub_get_unaligned32 (pointer)); + pointer = (grub_uint32_t *) ((char *) currkey + + grub_be_to_cpu16 (currkey->keylen) + + 2); + currnode = grub_be_to_cpu32 (*pointer); match = 1; } } @@ -684,198 +704,134 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, { *matchnode = 0; grub_free (node); - return 0; + return 1; } } } -struct list_nodes_ctx -{ - int ret; - grub_fshelp_node_t dir; - grub_fshelp_iterate_dir_hook_t hook; - void *hook_data; -}; - -static int -list_nodes (void *record, void *hook_arg) -{ - struct grub_hfsplus_catkey *catkey; - char *filename; - int i; - struct grub_fshelp_node *node; - grub_uint16_t *keyname; - struct grub_hfsplus_catfile *fileinfo; - enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; - struct list_nodes_ctx *ctx = hook_arg; - - catkey = (struct grub_hfsplus_catkey *) record; - - if (grub_be_to_cpu16 (catkey->keylen) < HFSPLUS_CATKEY_MIN_LEN || - grub_be_to_cpu16 (catkey->keylen) > HFSPLUS_CATKEY_MAX_LEN) - { - grub_error (GRUB_ERR_BAD_FS, "catalog key length is out of range"); - return 1; - } - - 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) != ctx->dir->fileid) - return 1; - - /* Determine the type of the node that is found. */ - switch (fileinfo->type) - { - case grub_cpu_to_be16_compile_time (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; - break; - } - case grub_cpu_to_be16_compile_time (GRUB_HFSPLUS_FILETYPE_DIR): - type = GRUB_FSHELP_DIR; - break; - case grub_cpu_to_be16_compile_time (GRUB_HFSPLUS_FILETYPE_DIR_THREAD): - if (ctx->dir->fileid == 2) - return 0; - node = grub_malloc (sizeof (*node)); - if (!node) - return 1; - node->data = ctx->dir->data; - node->mtime = 0; - node->size = 0; - node->fileid = grub_be_to_cpu32 (fileinfo->parentid); - - ctx->ret = ctx->hook ("..", GRUB_FSHELP_DIR, node, ctx->hook_data); - return ctx->ret; - } - - if (type == GRUB_FSHELP_UNKNOWN) - return 0; - - filename = grub_calloc (grub_be_to_cpu16 (catkey->namelen), - GRUB_MAX_UTF8_PER_UTF16 + 1); - if (! filename) - return 0; - - keyname = grub_calloc (grub_be_to_cpu16 (catkey->namelen), sizeof (*keyname)); - if (!keyname) - { - grub_free (filename); - return 0; - } - - /* Make sure the byte order of the UTF16 string is correct. */ - for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++) - { - keyname[i] = grub_be_to_cpu16 (catkey->name[i]); - - if (keyname[i] == '/') - keyname[i] = ':'; - - /* If the name is obviously invalid, skip this node. */ - if (keyname[i] == 0) - { - grub_free (keyname); - grub_free (filename); - return 0; - } - } - - *grub_utf16_to_utf8 ((grub_uint8_t *) filename, keyname, - grub_be_to_cpu16 (catkey->namelen)) = '\0'; - - grub_free (keyname); - - /* hfs+ is case insensitive. */ - if (! ctx->dir->data->case_sensitive) - type |= GRUB_FSHELP_CASE_INSENSITIVE; - - /* A valid node is found; setup the node and call the - callback function. */ - node = grub_malloc (sizeof (*node)); - if (!node) - { - grub_free (filename); - return 1; - } - node->data = ctx->dir->data; - node->compressed = 0; - node->cbuf = 0; - node->compress_index = 0; - - grub_memcpy (node->extents, fileinfo->data.extents, - sizeof (node->extents)); - grub_memcpy (node->resource_extents, fileinfo->resource.extents, - sizeof (node->resource_extents)); - node->mtime = grub_be_to_cpu32 (fileinfo->mtime) - 2082844800; - node->size = grub_be_to_cpu64 (fileinfo->data.size); - node->resource_size = grub_be_to_cpu64 (fileinfo->resource.size); - node->fileid = grub_be_to_cpu32 (fileinfo->fileid); - - ctx->ret = ctx->hook (filename, type, node, ctx->hook_data); - - grub_free (filename); - - return ctx->ret; -} - static int grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data) + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) { - struct list_nodes_ctx ctx = - { - .ret = 0, - .dir = dir, - .hook = hook, - .hook_data = hook_data - }; + 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 = NULL; - grub_disk_addr_t ptr = 0; - - { - struct grub_fshelp_node *fsnode; - fsnode = grub_malloc (sizeof (*fsnode)); - if (!fsnode) - return 1; - *fsnode = *dir; - if (hook (".", GRUB_FSHELP_DIR, fsnode, hook_data)) - return 1; - } + 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 = 0; - intern.catkey.namelen = 0; + intern.catkey.name = ""; /* First lookup the first entry. */ if (grub_hfsplus_btree_search (&dir->data->catalog_tree, &intern, - grub_hfsplus_cmp_catkey, &node, &ptr) - || !node) + 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, &ctx); + list_nodes); grub_free (node); - return ctx.ret; + return ret; } /* Open a file named NAME and initialize FILE. */ @@ -897,14 +853,6 @@ grub_hfsplus_open (struct grub_file *file, const char *name) if (grub_errno) goto fail; - if (grub_hfsplus_open_compressed) - { - grub_err_t err; - err = grub_hfsplus_open_compressed (fdiro); - if (err) - goto fail; - } - file->size = fdiro->size; data->opened_file = *fdiro; grub_free (fdiro); @@ -928,19 +876,14 @@ grub_hfsplus_open (struct grub_file *file, const char *name) static grub_err_t grub_hfsplus_close (grub_file_t file) { - struct grub_hfsplus_data *data = - (struct grub_hfsplus_data *) file->data; - - grub_free (data->opened_file.cbuf); - grub_free (data->opened_file.compress_index); - - grub_free (data); + 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) @@ -948,52 +891,39 @@ grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len) struct grub_hfsplus_data *data = (struct grub_hfsplus_data *) file->data; - data->opened_file.file = file; + int size = grub_hfsplus_read_file (&data->opened_file, file->read_hook, + file->offset, len, buf); - if (grub_hfsplus_read_compressed && data->opened_file.compressed) - return grub_hfsplus_read_compressed (&data->opened_file, - file->offset, len, buf); - - return grub_hfsplus_read_file (&data->opened_file, - file->read_hook, file->read_hook_data, - file->offset, len, buf); + return size; } -/* Context for grub_hfsplus_dir. */ -struct grub_hfsplus_dir_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; -}; - -/* Helper for grub_hfsplus_dir. */ -static int -grub_hfsplus_dir_iter (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, void *data) -{ - struct grub_hfsplus_dir_ctx *ctx = data; - 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.inodeset = 1; - info.inode = node->fileid; - info.case_insensitive = !! (filetype & GRUB_FSHELP_CASE_INSENSITIVE); - grub_free (node); - return ctx->hook (filename, &info, ctx->hook_data); -} static grub_err_t grub_hfsplus_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) + int (*hook) (const char *filename, + const struct grub_dirhook_info *info)) { - struct grub_hfsplus_dir_ctx ctx = { hook, hook_data }; 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); @@ -1008,7 +938,7 @@ grub_hfsplus_dir (grub_device_t device, const char *path, goto fail; /* Iterate over all entries in this directory. */ - grub_hfsplus_iterate_dir (fdiro, grub_hfsplus_dir_iter, &ctx); + grub_hfsplus_iterate_dir (fdiro, iterate); fail: if (data && fdiro != &data->dirroot) @@ -1022,94 +952,18 @@ grub_hfsplus_dir (grub_device_t device, const char *path, static grub_err_t -grub_hfsplus_label (grub_device_t device, char **label) +grub_hfsplus_label (grub_device_t device __attribute__((unused)) + , char **label __attribute__((unused))) { - struct grub_hfsplus_data *data; - grub_disk_t disk = device->disk; - struct grub_hfsplus_catkey *catkey; - int i, label_len; - grub_uint16_t *label_name; - struct grub_hfsplus_key_internal intern; - struct grub_hfsplus_btnode *node = NULL; - grub_disk_addr_t ptr = 0; - - *label = 0; - - data = grub_hfsplus_mount (disk); - if (!data) - return grub_errno; - - /* Create a key that points to the label. */ - intern.catkey.parent = 1; - intern.catkey.name = 0; - intern.catkey.namelen = 0; - - /* First lookup the first entry. */ - if (grub_hfsplus_btree_search (&data->catalog_tree, &intern, - grub_hfsplus_cmp_catkey_id, &node, &ptr) - || !node) - { - grub_free (data); - return 0; - } - - catkey = (struct grub_hfsplus_catkey *) - grub_hfsplus_btree_recptr (&data->catalog_tree, node, ptr); - - label_len = grub_be_to_cpu16 (catkey->namelen); - - /* Ensure that the length is >= 0. */ - if (label_len < 0) - label_len = 0; - - /* Ensure label length is at most 255 Unicode characters. */ - if (label_len > 255) - label_len = 255; - - label_name = grub_calloc (label_len, sizeof (*label_name)); - if (!label_name) - { - grub_free (node); - grub_free (data); - return grub_errno; - } - - for (i = 0; i < label_len; i++) - { - label_name[i] = grub_be_to_cpu16 (catkey->name[i]); - - /* If the name is obviously invalid, skip this node. */ - if (label_name[i] == 0) - { - grub_free (label_name); - grub_free (node); - grub_free (data); - return 0; - } - } - - *label = grub_calloc (label_len, GRUB_MAX_UTF8_PER_UTF16 + 1); - if (! *label) - { - grub_free (label_name); - grub_free (node); - grub_free (data); - return grub_errno; - } - - *grub_utf16_to_utf8 ((grub_uint8_t *) (*label), label_name, - label_len) = '\0'; - - grub_free (label_name); - grub_free (node); - grub_free (data); - - return GRUB_ERR_NONE; + /* 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_int64_t *tm) +grub_hfsplus_mtime (grub_device_t device, grub_int32_t *tm) { struct grub_hfsplus_data *data; grub_disk_t disk = device->disk; @@ -1160,23 +1014,21 @@ grub_hfsplus_uuid (grub_device_t device, char **uuid) static struct grub_fs grub_hfsplus_fs = { .name = "hfsplus", - .fs_dir = grub_hfsplus_dir, - .fs_open = grub_hfsplus_open, - .fs_read = grub_hfsplus_read, - .fs_close = grub_hfsplus_close, - .fs_label = grub_hfsplus_label, - .fs_mtime = grub_hfsplus_mtime, - .fs_uuid = grub_hfsplus_uuid, + .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, - .blocklist_install = 1, #endif .next = 0 }; GRUB_MOD_INIT(hfsplus) { - grub_hfsplus_fs.mod = mod; grub_fs_register (&grub_hfsplus_fs); my_mod = mod; } diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c new file mode 100644 index 000000000..82d8ee583 --- /dev/null +++ b/fs/i386/pc/pxe.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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 new file mode 100644 index 000000000..6dc465f25 --- /dev/null +++ b/fs/iso9660.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; + + +/* 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; isig, "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; +} + + + +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; +} + + + +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/fs/jfs.c similarity index 58% rename from grub-core/fs/jfs.c rename to fs/jfs.c index 03be9ef4c..c9839a22f 100644 --- a/grub-core/fs/jfs.c +++ b/fs/jfs.c @@ -25,10 +25,6 @@ #include #include #include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); #define GRUB_JFS_MAX_SYMLNK_CNT 8 #define GRUB_JFS_FILETYPE_MASK 0170000 @@ -42,13 +38,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define GRUB_JFS_TREE_LEAF 2 -/* - * Define max entries stored in-line in an inode. - * https://jfs.sourceforge.net/project/pub/jfslayout.pdf - */ -#define GRUB_JFS_INODE_INLINE_ENTRIES 8 -#define GRUB_JFS_DIR_MAX_SLOTS 128 - struct grub_jfs_sblock { /* The magic for JFS. It should contain the string "JFS1". */ @@ -60,13 +49,11 @@ struct grub_jfs_sblock 4096 was tested. */ grub_uint32_t blksz; grub_uint16_t log2_blksz; - grub_uint8_t unused[14]; - grub_uint32_t flags; - grub_uint8_t unused3[61]; - char volname[11]; - grub_uint8_t unused2[24]; + + grub_uint8_t unused[71]; + grub_uint8_t volname[11]; + grub_uint8_t unused2[32]; grub_uint8_t uuid[16]; - char volname2[16]; }; struct grub_jfs_extent @@ -78,16 +65,13 @@ struct grub_jfs_extent /* The physical offset of the first block on the disk. */ grub_uint8_t blk1; grub_uint32_t blk2; -} GRUB_PACKED; - -#define GRUB_JFS_IAG_INODES_OFFSET 3072 -#define GRUB_JFS_IAG_INODES_COUNT 128 +} __attribute__ ((packed)); struct grub_jfs_iag { - grub_uint8_t unused[GRUB_JFS_IAG_INODES_OFFSET]; - struct grub_jfs_extent inodes[GRUB_JFS_IAG_INODES_COUNT]; -} GRUB_PACKED; + grub_uint8_t unused[3072]; + struct grub_jfs_extent inodes[128]; +} __attribute__ ((packed)); /* The head of the tree used to find extents. */ @@ -102,7 +86,7 @@ struct grub_jfs_treehead grub_uint16_t count; grub_uint16_t max; grub_uint8_t unused2[10]; -} GRUB_PACKED; +} __attribute__ ((packed)); /* A node in the extent tree. */ struct grub_jfs_tree_extent @@ -115,7 +99,7 @@ struct grub_jfs_tree_extent grub_uint32_t offset2; struct grub_jfs_extent extent; -} GRUB_PACKED; +} __attribute__ ((packed)); /* The tree of directory entries. */ struct grub_jfs_tree_dir @@ -136,7 +120,7 @@ struct grub_jfs_tree_dir /* The location of the sorted array of pointers to dirents. */ grub_uint8_t sindex; grub_uint8_t unused[10]; -} GRUB_PACKED; +} __attribute__ ((packed)); /* An internal node in the dirents tree. */ struct grub_jfs_internal_dirent @@ -145,7 +129,7 @@ struct grub_jfs_internal_dirent grub_uint8_t next; grub_uint8_t len; grub_uint16_t namepart[11]; -} GRUB_PACKED; +} __attribute__ ((packed)); /* A leaf node in the dirents tree. */ struct grub_jfs_leaf_dirent @@ -158,7 +142,7 @@ struct grub_jfs_leaf_dirent grub_uint8_t len; grub_uint16_t namepart[11]; grub_uint32_t index; -} GRUB_PACKED; +} __attribute__ ((packed)); /* A leaf in the dirents tree. This one is used if the previously dirent was not big enough to store the name. */ @@ -167,13 +151,7 @@ struct grub_jfs_leaf_next_dirent grub_uint8_t next; grub_uint8_t len; grub_uint16_t namepart[15]; -} GRUB_PACKED; - -struct grub_jfs_time -{ - grub_int32_t sec; - grub_int32_t nanosec; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_jfs_inode { @@ -184,16 +162,13 @@ struct grub_jfs_inode grub_uint64_t size; grub_uint8_t unused2[20]; grub_uint32_t mode; - struct grub_jfs_time atime; - struct grub_jfs_time ctime; - struct grub_jfs_time mtime; - grub_uint8_t unused3[48]; + grub_uint8_t unused3[72]; grub_uint8_t unused4[96]; union { /* The tree describing the extents of the file. */ - struct GRUB_PACKED + struct __attribute__ ((packed)) { struct grub_jfs_treehead tree; struct grub_jfs_tree_extent extents[16]; @@ -211,18 +186,18 @@ struct grub_jfs_inode grub_uint8_t freecnt; grub_uint8_t freelist; grub_uint32_t idotdot; - grub_uint8_t sorted[GRUB_JFS_INODE_INLINE_ENTRIES]; + grub_uint8_t sorted[8]; } header; - struct grub_jfs_leaf_dirent dirents[GRUB_JFS_INODE_INLINE_ENTRIES]; - } GRUB_PACKED dir; + struct grub_jfs_leaf_dirent dirents[8]; + } dir __attribute__ ((packed)); /* Fast symlink. */ struct { grub_uint8_t unused[32]; - grub_uint8_t path[256]; + grub_uint8_t path[128]; } symlink; - } GRUB_PACKED; -} GRUB_PACKED; + } __attribute__ ((packed)); +} __attribute__ ((packed)); struct grub_jfs_data { @@ -230,11 +205,9 @@ struct grub_jfs_data grub_disk_t disk; struct grub_jfs_inode fileset; struct grub_jfs_inode currinode; - int caseins; int pos; int linknest; - int namecomponentlen; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_jfs_diropen { @@ -244,130 +217,92 @@ struct grub_jfs_diropen struct grub_jfs_tree_dir header; struct grub_jfs_leaf_dirent dirent[0]; struct grub_jfs_leaf_next_dirent next_dirent[0]; - grub_uint8_t sorted[0]; - } GRUB_PACKED *dirpage; + char sorted[0]; + } *dirpage __attribute__ ((packed)); struct grub_jfs_data *data; struct grub_jfs_inode *inode; int count; - grub_uint8_t *sorted; + 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. */ - /* On-disk name is at most 255 UTF-16 codepoints. - Every UTF-16 codepoint is at most 4 UTF-8 bytes. - */ - char name[256 * GRUB_MAX_UTF8_PER_UTF16 + 1]; + char name[255]; grub_uint32_t ino; -} GRUB_PACKED; +} __attribute__ ((packed)); static grub_dl_t my_mod; -static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino); - -/* - * An extent's offset, physical and logical, is represented as a 40-bit value. - * This 40-bit value is split into two parts: - * - offset1: the most signficant 8 bits of the offset, - * - offset2: the least significant 32 bits of the offset. - * - * This function calculates and returns the 64-bit offset of an extent. - */ -static grub_uint64_t -get_ext_offset (grub_uint8_t offset1, grub_uint32_t offset2) -{ - return (((grub_uint64_t) offset1 << 32) | grub_le_to_cpu32 (offset2)); -} - -static grub_uint64_t -getblk (struct grub_jfs_treehead *treehead, - struct grub_jfs_tree_extent *extents, - int max_extents, - struct grub_jfs_data *data, - grub_uint64_t blk) -{ - int found = -1; - int i; - grub_uint64_t ext_offset, ext_blk; - - grub_errno = GRUB_ERR_NONE; - - for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2 && - i < max_extents; i++) - { - ext_offset = get_ext_offset (extents[i].offset1, extents[i].offset2); - ext_blk = get_ext_offset (extents[i].extent.blk1, extents[i].extent.blk2); - - if (treehead->flags & GRUB_JFS_TREE_LEAF) - { - /* Read the leafnode. */ - if (ext_offset <= blk - && ((grub_le_to_cpu16 (extents[i].extent.length)) - + (extents[i].extent.length2 << 16) - + ext_offset) > blk) - return (blk - ext_offset + ext_blk); - } - else - if (blk >= ext_offset) - found = i; - } - - if (found != -1) - { - grub_uint64_t ret = 0; - struct - { - struct grub_jfs_treehead treehead; - struct grub_jfs_tree_extent extents[254]; - } *tree; - - tree = grub_zalloc (sizeof (*tree)); - if (!tree) - return 0; - - if (!grub_disk_read (data->disk, - (grub_disk_addr_t) ext_blk - << (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS), - 0, sizeof (*tree), (char *) tree)) - { - if (grub_memcmp (&tree->treehead, treehead, sizeof (struct grub_jfs_treehead)) || - grub_memcmp (&tree->extents, extents, 254 * sizeof (struct grub_jfs_tree_extent))) - ret = getblk (&tree->treehead, &tree->extents[0], 254, data, blk); - else - { - grub_error (GRUB_ERR_BAD_FS, "jfs: infinite recursion detected"); - ret = 0; - } - } - grub_free (tree); - return ret; - } - - grub_error (GRUB_ERR_READ_ERROR, "jfs: block %" PRIuGRUB_UINT64_T " not found", blk); - return 0; -} +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 grub_uint64_t +static int grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, - grub_uint64_t blk) + unsigned int blk) { - return getblk (&inode->file.tree, &inode->file.extents[0], 16, data, 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, grub_uint32_t ino, +grub_jfs_read_inode (struct grub_jfs_data *data, int ino, struct grub_jfs_inode *inode) { - struct grub_jfs_extent iag_inodes[GRUB_JFS_IAG_INODES_COUNT]; - grub_uint32_t iagnum = ino / 4096; - unsigned inoext = (ino % 4096) / 32; - unsigned inonum = (ino % 4096) % 32; - grub_uint64_t iagblk; - grub_uint64_t inoblk; + 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) @@ -376,12 +311,11 @@ grub_jfs_read_inode (struct grub_jfs_data *data, grub_uint32_t ino, /* Read in the IAG. */ if (grub_disk_read (data->disk, iagblk << (grub_le_to_cpu16 (data->sblock.log2_blksz) - - GRUB_DISK_SECTOR_BITS), - GRUB_JFS_IAG_INODES_OFFSET, - sizeof (iag_inodes), &iag_inodes)) + - GRUB_DISK_SECTOR_BITS), 0, + sizeof (struct grub_jfs_iag), &iag)) return grub_errno; - inoblk = get_ext_offset (iag_inodes[inoext].blk1, iag_inodes[inoext].blk2); + inoblk = grub_le_to_cpu32 (iag.inodes[inoext].blk2); inoblk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS); inoblk += inonum; @@ -414,15 +348,6 @@ grub_jfs_mount (grub_disk_t disk) goto fail; } - if (data->sblock.blksz == 0 - || grub_le_to_cpu32 (data->sblock.blksz) - != (1U << grub_le_to_cpu16 (data->sblock.log2_blksz)) - || grub_le_to_cpu16 (data->sblock.log2_blksz) < GRUB_DISK_SECTOR_BITS) - { - grub_error (GRUB_ERR_BAD_FS, "not a JFS filesystem"); - goto fail; - } - data->disk = disk; data->pos = 0; data->linknest = 0; @@ -432,16 +357,6 @@ grub_jfs_mount (grub_disk_t disk) sizeof (struct grub_jfs_inode), &data->fileset)) goto fail; - if (data->sblock.flags & grub_cpu_to_le32_compile_time (0x00200000)) - data->namecomponentlen = 11; - else - data->namecomponentlen = 13; - - if (data->sblock.flags & grub_cpu_to_le32_compile_time (0x40000000)) - data->caseins = 1; - else - data->caseins = 0; - return data; fail: @@ -459,14 +374,14 @@ grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode) { struct grub_jfs_internal_dirent *de; struct grub_jfs_diropen *diro; - grub_disk_addr_t blk; + 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, N_("not a directory")); + grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); return 0; } @@ -480,16 +395,9 @@ grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode) /* Check if the entire tree is contained within the inode. */ if (inode->file.tree.flags & GRUB_JFS_TREE_LEAF) { - if (inode->dir.header.count > GRUB_JFS_INODE_INLINE_ENTRIES) - { - grub_free (diro); - grub_error (GRUB_ERR_BAD_FS, N_("invalid JFS inode")); - return 0; - } - diro->leaf = inode->dir.dirents; diro->next_leaf = (struct grub_jfs_leaf_next_dirent *) de; - diro->sorted = inode->dir.header.sorted; + diro->sorted = (char *) (inode->dir.header.sorted); diro->count = inode->dir.header.count; return diro; @@ -502,16 +410,7 @@ grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode) return 0; } - if (inode->dir.header.sorted[0] >= GRUB_JFS_DIR_MAX_SLOTS) - { - grub_error (GRUB_ERR_BAD_FS, N_("invalid directory slot index")); - grub_free (diro->dirpage); - grub_free (diro); - return 0; - } - - blk = get_ext_offset (de[inode->dir.header.sorted[0]].ex.blk1, - de[inode->dir.header.sorted[0]].ex.blk2); + 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. */ @@ -529,7 +428,7 @@ grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode) de = (struct grub_jfs_internal_dirent *) diro->dirpage->dirent; index = diro->dirpage->sorted[diro->dirpage->header.sindex * 32]; - blk = (get_ext_offset (de[index].ex.blk1, de[index].ex.blk2) + 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)); @@ -552,17 +451,6 @@ grub_jfs_closedir (struct grub_jfs_diropen *diro) grub_free (diro); } -static void -le_to_cpu16_copy (grub_uint16_t *out, grub_uint16_t *in, grub_size_t len) -{ - while (len--) - *out++ = grub_le_to_cpu16 (*in++); -} - -#if __GNUC__ >= 9 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Waddress-of-packed-member" -#endif /* Read in the next dirent from the directory described by DIRO. */ static grub_err_t @@ -573,12 +461,21 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) struct grub_jfs_leaf_next_dirent *next_leaf; int len; int nextent; - grub_uint16_t filename[256]; + 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) { - grub_disk_addr_t next; + unsigned int next; /* If the inode contains the entry tree or if this was the last node, there is nothing to read. */ @@ -602,7 +499,7 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) diro->index = 0; } - leaf = &diro->leaf[diro->sorted[diro->index]]; + leaf = &diro->leaf[(int) diro->sorted[diro->index]]; next_leaf = &diro->next_leaf[diro->index]; len = leaf->len; @@ -612,21 +509,17 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) return grub_jfs_getent (diro); } - le_to_cpu16_copy (filename + strpos, leaf->namepart, len < diro->data->namecomponentlen ? len - : diro->data->namecomponentlen); - strpos += len < diro->data->namecomponentlen ? len - : diro->data->namecomponentlen; + addstr (leaf->namepart, len < 11 ? len : 11); diro->ino = grub_le_to_cpu32 (leaf->inode); - len -= diro->data->namecomponentlen; + len -= 11; /* Move down to the leaf level. */ nextent = leaf->next; - if (leaf->next != 255 && len > 0) + if (leaf->next != 255) do { next_leaf = &diro->next_leaf[nextent]; - le_to_cpu16_copy (filename + strpos, next_leaf->namepart, len < 15 ? len : 15); - strpos += len < 15 ? len : 15; + addstr (next_leaf->namepart, len < 15 ? len : 15 ); len -= 15; nextent = next_leaf->next; @@ -640,30 +533,28 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) return 0; } -#if __GNUC__ >= 9 -#pragma GCC diagnostic pop -#endif /* 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, - grub_disk_read_hook_t read_hook, void *read_hook_data, - grub_off_t pos, grub_size_t len, char *buf) + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + int pos, grub_size_t len, char *buf) { - grub_off_t i; - grub_off_t blockcnt; + int i; + int blockcnt; - blockcnt = (len + pos + grub_le_to_cpu32 (data->sblock.blksz) - 1) - >> grub_le_to_cpu16 (data->sblock.log2_blksz); + blockcnt = ((len + pos + grub_le_to_cpu32 (data->sblock.blksz) - 1) + / grub_le_to_cpu32 (data->sblock.blksz)); - for (i = pos >> grub_le_to_cpu16 (data->sblock.log2_blksz); i < blockcnt; i++) + for (i = pos / grub_le_to_cpu32 (data->sblock.blksz); i < blockcnt; i++) { - grub_disk_addr_t blknr; - grub_uint32_t blockoff = pos & (grub_le_to_cpu32 (data->sblock.blksz) - 1); - grub_uint32_t blockend = grub_le_to_cpu32 (data->sblock.blksz); + int blknr; + int blockoff = pos % grub_le_to_cpu32 (data->sblock.blksz); + int blockend = grub_le_to_cpu32 (data->sblock.blksz); - grub_uint64_t skipfirst = 0; + int skipfirst = 0; blknr = grub_jfs_blkno (data, &data->currinode, i); if (grub_errno) @@ -672,21 +563,20 @@ grub_jfs_read_file (struct grub_jfs_data *data, /* Last block. */ if (i == blockcnt - 1) { - blockend = (len + pos) & (grub_le_to_cpu32 (data->sblock.blksz) - 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 >> grub_le_to_cpu16 (data->sblock.log2_blksz))) + if (i == (pos / (int) grub_le_to_cpu32 (data->sblock.blksz))) { skipfirst = blockoff; blockend -= skipfirst; } data->disk->read_hook = read_hook; - data->disk->read_hook_data = read_hook_data; grub_disk_read (data->disk, blknr << (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS), @@ -706,98 +596,112 @@ grub_jfs_read_file (struct grub_jfs_data *data, /* 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, - grub_uint32_t start_ino) +grub_jfs_find_file (struct grub_jfs_data *data, const char *path) { - const char *name; - const char *next = path; - struct grub_jfs_diropen *diro = NULL; + char fpath[grub_strlen (path)]; + char *name = fpath; + char *next; + unsigned int pos = 0; + struct grub_jfs_diropen *diro; - if (grub_jfs_read_inode (data, start_ino, &data->currinode)) + grub_strncpy (fpath, path, grub_strlen (path) + 1); + + if (grub_jfs_read_inode (data, GRUB_JFS_AGGR_INODE, &data->currinode)) return grub_errno; - while (1) + /* Skip the first slashes. */ + while (*name == '/') { - name = next; - while (*name == '/') - name++; - if (name[0] == 0) - return GRUB_ERR_NONE; - for (next = name; *next && *next != '/'; next++); + name++; + if (!*name) + return 0; + } - if (name[0] == '.' && name + 1 == next) - continue; - - if (name[0] == '.' && name[1] == '.' && name + 2 == next) + /* Extract the actual part from the pathname. */ + next = grub_strchr (name, '/'); + if (next) + { + while (*next == '/') { - grub_uint32_t ino = grub_le_to_cpu32 (data->currinode.dir.header.idotdot); + 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; } - - diro = grub_jfs_opendir (data, &data->currinode); - if (!diro) - return grub_errno; - - for (;;) - { - if (grub_jfs_getent (diro) == GRUB_ERR_OUT_OF_RANGE) - { - grub_jfs_closedir (diro); - return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path); - } - - /* Check if the current direntry matches the current part of the - pathname. */ - if ((data->caseins ? grub_strncasecmp (name, diro->name, next - name) == 0 - : grub_strncmp (name, diro->name, next - name) == 0) && !diro->name[next - name]) - { - grub_uint32_t ino = diro->ino; - grub_uint32_t dirino = grub_le_to_cpu32 (data->currinode.inode); - - grub_jfs_closedir (diro); - - 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; - } - - break; - } - } } + + 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, grub_uint32_t ino) +grub_jfs_lookup_symlink (struct grub_jfs_data *data, int ino) { - grub_size_t size = grub_le_to_cpu64 (data->currinode.size); - char *symlink; + 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, N_("too deep nesting of symlinks")); + return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks"); - symlink = grub_malloc (size + 1); - if (!symlink) + 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; - if (size <= sizeof (data->currinode.symlink.path)) - grub_memcpy (symlink, (char *) (data->currinode.symlink.path), size); - else if (grub_jfs_read_file (data, 0, 0, 0, size, symlink) < 0) - { - grub_free (symlink); - return grub_errno; - } symlink[size] = '\0'; @@ -805,9 +709,13 @@ grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino) if (symlink[0] == '/') ino = 2; - grub_jfs_find_file (data, symlink, ino); + /* Now load in the old inode. */ + if (grub_jfs_read_inode (data, ino, &data->currinode)) + return grub_errno; - grub_free (symlink); + grub_jfs_find_file (data, symlink); + if (grub_errno) + grub_error (grub_errno, "cannot follow symlink `%s'", symlink); return grub_errno; } @@ -815,7 +723,8 @@ grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino) static grub_err_t grub_jfs_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) + int (*hook) (const char *filename, + const struct grub_dirhook_info *info)) { struct grub_jfs_data *data = 0; struct grub_jfs_diropen *diro = 0; @@ -826,7 +735,7 @@ grub_jfs_dir (grub_device_t device, const char *path, if (!data) goto fail; - if (grub_jfs_find_file (data, path, GRUB_JFS_AGGR_INODE)) + if (grub_jfs_find_file (data, path)) goto fail; diro = grub_jfs_opendir (data, &data->currinode); @@ -845,9 +754,7 @@ grub_jfs_dir (grub_device_t device, const char *path, info.dir = (grub_le_to_cpu32 (inode.mode) & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR; - info.mtimeset = 1; - info.mtime = grub_le_to_cpu32 (inode.mtime.sec); - if (hook (diro->name, &info, hook_data)) + if (hook (diro->name, &info)) goto fail; } @@ -877,7 +784,7 @@ grub_jfs_open (struct grub_file *file, const char *name) if (!data) goto fail; - grub_jfs_find_file (data, name, GRUB_JFS_AGGR_INODE); + grub_jfs_find_file (data, name); if (grub_errno) goto fail; @@ -885,7 +792,7 @@ grub_jfs_open (struct grub_file *file, const char *name) if (! ((grub_le_to_cpu32 (data->currinode.mode) & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_REG)) { - grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file")); + grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file"); goto fail; } @@ -910,8 +817,7 @@ 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->read_hook_data, - file->offset, len, buf); + return grub_jfs_read_file (data, file->read_hook, file->offset, len, buf); } @@ -964,25 +870,10 @@ grub_jfs_label (grub_device_t device, char **label) data = grub_jfs_mount (device->disk); if (data) - { - if (data->sblock.volname2[0] < ' ') - { - char *ptr; - ptr = data->sblock.volname + sizeof (data->sblock.volname) - 1; - while (ptr >= data->sblock.volname && *ptr == ' ') - ptr--; - *label = grub_strndup (data->sblock.volname, - ptr - data->sblock.volname + 1); - } - else - *label = grub_strndup (data->sblock.volname2, - sizeof (data->sblock.volname2)); - } + *label = grub_strndup ((char *) (data->sblock.volname), 11); else *label = 0; - grub_free (data); - return grub_errno; } @@ -990,31 +881,22 @@ grub_jfs_label (grub_device_t device, char **label) static struct grub_fs grub_jfs_fs = { .name = "jfs", - .fs_dir = grub_jfs_dir, - .fs_open = grub_jfs_open, - .fs_read = grub_jfs_read, - .fs_close = grub_jfs_close, - .fs_label = grub_jfs_label, - .fs_uuid = grub_jfs_uuid, -#ifdef GRUB_UTIL - .reserved_first_sector = 1, - .blocklist_install = 1, -#endif + .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) { - if (!grub_is_lockdown ()) - { - grub_jfs_fs.mod = mod; - grub_fs_register (&grub_jfs_fs); - } + grub_fs_register (&grub_jfs_fs); my_mod = mod; } GRUB_MOD_FINI(jfs) { - if (!grub_is_lockdown ()) - grub_fs_unregister (&grub_jfs_fs); + grub_fs_unregister (&grub_jfs_fs); } diff --git a/fs/minix.c b/fs/minix.c new file mode 100644 index 000000000..a856e38c4 --- /dev/null +++ b/fs/minix.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +#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; + +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; +} + +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; +} + + +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/ntfs.c b/fs/ntfs.c new file mode 100644 index 000000000..dd041e23a --- /dev/null +++ b/fs/ntfs.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +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/fs/ntfscomp.c similarity index 51% rename from grub-core/fs/ntfscomp.c rename to fs/ntfscomp.c index b68bf5e40..c29979edc 100644 --- a/grub-core/fs/ntfscomp.c +++ b/fs/ntfscomp.c @@ -21,46 +21,43 @@ #include #include #include +#include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); 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 overflow"); + return grub_error (GRUB_ERR_BAD_FS, "compression block overflown"); if (grub_disk_read (cc->disk, - (cc->comp_table[cc->comp_head].next_lcn - - (cc->comp_table[cc->comp_head].next_vcn - cc->cbuf_vcn)) << cc->log_spc, - 0, - 1 << (cc->log_spc + GRUB_NTFS_BLK_SHR), cc->cbuf)) + (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].next_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, grub_uint8_t *res) +decomp_getch (struct grub_ntfs_comp *cc, unsigned char *res) { - if (cc->cbuf_ofs >= (1U << (cc->log_spc + GRUB_NTFS_BLK_SHR))) + if (cc->cbuf_ofs >= (cc->spc << BLK_SHR)) { if (decomp_nextvcn (cc)) return grub_errno; } - *res = cc->cbuf[cc->cbuf_ofs++]; + *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) { - grub_uint8_t c1 = 0, c2 = 0; + unsigned char c1 = 0, c2 = 0; if ((decomp_getch (cc, &c1)) || (decomp_getch (cc, &c2))) return grub_errno; @@ -70,7 +67,7 @@ decomp_get16 (struct grub_ntfs_comp *cc, grub_uint16_t * res) /* Decompress a block (4096 bytes) */ static grub_err_t -decomp_block (struct grub_ntfs_comp *cc, grub_uint8_t *dest) +decomp_block (struct grub_ntfs_comp *cc, char *dest) { grub_uint16_t flg, cnt; @@ -82,13 +79,13 @@ decomp_block (struct grub_ntfs_comp *cc, grub_uint8_t *dest) { if (flg & 0x8000) { - grub_uint8_t tag; + unsigned char tag; grub_uint32_t bits, copied; bits = copied = tag = 0; while (cnt > 0) { - if (copied > GRUB_NTFS_COM_LEN) + if (copied > COM_LEN) return grub_error (GRUB_ERR_BAD_FS, "compression block too large"); @@ -105,7 +102,7 @@ decomp_block (struct grub_ntfs_comp *cc, grub_uint8_t *dest) if (tag & 1) { grub_uint32_t i, len, delta, code, lmask, dshift; - grub_uint16_t word = 0; + grub_uint16_t word; if (decomp_get16 (cc, &word)) return grub_errno; @@ -137,7 +134,7 @@ decomp_block (struct grub_ntfs_comp *cc, grub_uint8_t *dest) } else { - grub_uint8_t ch = 0; + unsigned char ch = 0; if (decomp_getch (cc, &ch)) return grub_errno; @@ -151,7 +148,7 @@ decomp_block (struct grub_ntfs_comp *cc, grub_uint8_t *dest) } else { - if (cnt != GRUB_NTFS_COM_LEN) + if (cnt != COM_LEN) return grub_error (GRUB_ERR_BAD_FS, "invalid compression block size"); } @@ -161,7 +158,7 @@ decomp_block (struct grub_ntfs_comp *cc, grub_uint8_t *dest) { int n; - n = (1 << (cc->log_spc + GRUB_NTFS_BLK_SHR)) - cc->cbuf_ofs; + n = (cc->spc << BLK_SHR) - cc->cbuf_ofs; if (n > cnt) n = cnt; if ((dest) && (n)) @@ -178,23 +175,22 @@ decomp_block (struct grub_ntfs_comp *cc, grub_uint8_t *dest) } static grub_err_t -read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num) +read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) { - int log_cpb = GRUB_NTFS_LOG_COM_SEC - ctx->comp.log_spc; + int cpb = COM_SEC / ctx->comp.spc; while (num) { - grub_size_t nn; + int nn; if ((ctx->target_vcn & 0xF) == 0) { - if (ctx->comp.comp_head != ctx->comp.comp_tail - && !(ctx->flags & GRUB_NTFS_RF_BLNK)) + 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 = (1 << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR)); + ctx->comp.cbuf_ofs = (ctx->comp.spc << BLK_SHR); if (ctx->target_vcn >= ctx->next_vcn) { if (grub_ntfs_read_run_list (ctx)) @@ -202,10 +198,10 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num) } while (ctx->target_vcn + 16 > ctx->next_vcn) { - if (ctx->flags & GRUB_NTFS_RF_BLNK) + if (ctx->flags & RF_BLNK) break; - ctx->comp.comp_table[ctx->comp.comp_tail].next_vcn = ctx->next_vcn; - ctx->comp.comp_table[ctx->comp.comp_tail].next_lcn = + 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)) @@ -213,23 +209,20 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num) } } - nn = (16 - (unsigned) (ctx->target_vcn & 0xF)) >> log_cpb; + nn = (16 - (unsigned) (ctx->target_vcn & 0xF)) / cpb; if (nn > num) nn = num; num -= nn; - if (ctx->flags & GRUB_NTFS_RF_BLNK) + if (ctx->flags & RF_BLNK) { - ctx->target_vcn += nn << log_cpb; + ctx->target_vcn += nn * cpb; if (ctx->comp.comp_tail == 0) { if (buf) { - grub_memset (buf, 0, nn * GRUB_NTFS_COM_LEN); - buf += nn * GRUB_NTFS_COM_LEN; - if (grub_file_progress_hook && ctx->file) - grub_file_progress_hook (0, 0, nn * GRUB_NTFS_COM_LEN, NULL, - ctx->file); + grub_memset (buf, 0, nn * COM_LEN); + buf += nn * COM_LEN; } } else @@ -239,23 +232,20 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num) if (decomp_block (&ctx->comp, buf)) return grub_errno; if (buf) - buf += GRUB_NTFS_COM_LEN; - if (grub_file_progress_hook && ctx->file) - grub_file_progress_hook (0, 0, GRUB_NTFS_COM_LEN, NULL, - ctx->file); + buf += COM_LEN; nn--; } } } else { - nn <<= log_cpb; + nn *= cpb; while ((ctx->comp.comp_head < ctx->comp.comp_tail) && (nn)) { - grub_disk_addr_t tt; + int tt; tt = - ctx->comp.comp_table[ctx->comp.comp_head].next_vcn - + ctx->comp.comp_table[ctx->comp.comp_head][0] - ctx->target_vcn; if (tt > nn) tt = nn; @@ -264,21 +254,16 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num) { if (grub_disk_read (ctx->comp.disk, - (ctx->comp.comp_table[ctx->comp.comp_head].next_lcn - - (ctx->comp.comp_table[ctx->comp.comp_head].next_vcn - - ctx->target_vcn)) << ctx->comp.log_spc, 0, - tt << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR), buf)) + (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; - if (grub_file_progress_hook && ctx->file) - grub_file_progress_hook (0, 0, - tt << (ctx->comp.log_spc - + GRUB_NTFS_BLK_SHR), NULL, - ctx->file); - buf += tt << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR); + buf += tt * (ctx->comp.spc << BLK_SHR); } nn -= tt; if (ctx->target_vcn >= - ctx->comp.comp_table[ctx->comp.comp_head].next_vcn) + ctx->comp.comp_table[ctx->comp.comp_head][0]) ctx->comp.comp_head++; } if (nn) @@ -288,15 +273,10 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num) if (grub_disk_read (ctx->comp.disk, (ctx->target_vcn - ctx->curr_vcn + - ctx->curr_lcn) << ctx->comp.log_spc, 0, - nn << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR), buf)) + ctx->curr_lcn) * ctx->comp.spc, 0, + nn * (ctx->comp.spc << BLK_SHR), buf)) return grub_errno; - buf += nn << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR); - if (grub_file_progress_hook && ctx->file) - grub_file_progress_hook (0, 0, - nn << (ctx->comp.log_spc - + GRUB_NTFS_BLK_SHR), NULL, - ctx->file); + buf += nn * (ctx->comp.spc << BLK_SHR); } ctx->target_vcn += nn; } @@ -306,130 +286,74 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num) } static grub_err_t -ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs, - grub_size_t len, struct grub_ntfs_rlst *ctx) +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; - grub_disk_addr_t vcn; - int log_sz; - - if (ctx->attr->sbuf) - { - if ((ofs & (~(GRUB_NTFS_COM_LEN - 1))) == ctx->attr->save_pos) - { - grub_disk_addr_t n; - - n = GRUB_NTFS_COM_LEN - (ofs - ctx->attr->save_pos); - if (n > len) - n = len; - - grub_memcpy (dest, ctx->attr->sbuf + ofs - ctx->attr->save_pos, n); - if (grub_file_progress_hook && ctx->file) - grub_file_progress_hook (0, 0, n, NULL, ctx->file); - if (n == len) - return 0; - - dest += n; - len -= n; - ofs += n; - } - } - else - { - ctx->attr->sbuf = grub_malloc (GRUB_NTFS_COM_LEN); - if (ctx->attr->sbuf == NULL) - return grub_errno; - ctx->attr->save_pos = 1; - } - - vcn = ctx->target_vcn = (ofs >> GRUB_NTFS_COM_LOG_LEN) * (GRUB_NTFS_COM_SEC >> ctx->comp.log_spc); - ctx->target_vcn &= ~0xFULL; - while (ctx->next_vcn <= ctx->target_vcn) - { - if (grub_ntfs_read_run_list (ctx)) - return grub_errno; - } ctx->comp.comp_head = ctx->comp.comp_tail = 0; - if (grub_add (ctx->comp.log_spc, GRUB_NTFS_BLK_SHR, &log_sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("compression buffer size overflow")); - return 0; - } - ctx->comp.cbuf = grub_malloc (1 << log_sz); + 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; - //ctx->comp.disk->read_hook_data = read_hook_data; if ((vcn > ctx->target_vcn) && (read_block - (ctx, NULL, (vcn - ctx->target_vcn) >> (GRUB_NTFS_LOG_COM_SEC - ctx->comp.log_spc)))) + (ctx, NULL, ((vcn - ctx->target_vcn) * ctx->comp.spc) / COM_SEC))) { ret = grub_errno; goto quit; } - if (ofs % GRUB_NTFS_COM_LEN) + if (ofs % COM_LEN) { grub_uint32_t t, n, o; - void *file = ctx->file; - ctx->file = 0; - - t = ctx->target_vcn << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR); - if (read_block (ctx, ctx->attr->sbuf, 1)) + t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR); + if (read_block (ctx, at->sbuf, 1)) { ret = grub_errno; goto quit; } - ctx->file = file; + at->save_pos = t; - ctx->attr->save_pos = t; - - o = ofs % GRUB_NTFS_COM_LEN; - n = GRUB_NTFS_COM_LEN - o; + o = ofs % COM_LEN; + n = COM_LEN - o; if (n > len) n = len; - grub_memcpy (dest, &ctx->attr->sbuf[o], n); - if (grub_file_progress_hook && ctx->file) - grub_file_progress_hook (0, 0, n, NULL, ctx->file); + grub_memcpy (dest, &at->sbuf[o], n); if (n == len) goto quit; dest += n; len -= n; } - if (read_block (ctx, dest, len / GRUB_NTFS_COM_LEN)) + if (read_block (ctx, dest, len / COM_LEN)) { ret = grub_errno; goto quit; } - dest += (len / GRUB_NTFS_COM_LEN) * GRUB_NTFS_COM_LEN; - len = len % GRUB_NTFS_COM_LEN; + dest += (len / COM_LEN) * COM_LEN; + len = len % COM_LEN; if (len) { grub_uint32_t t; - void *file = ctx->file; - ctx->file = 0; - t = ctx->target_vcn << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR); - if (read_block (ctx, ctx->attr->sbuf, 1)) + t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR); + if (read_block (ctx, at->sbuf, 1)) { ret = grub_errno; goto quit; } - ctx->attr->save_pos = t; + at->save_pos = t; - grub_memcpy (dest, ctx->attr->sbuf, len); - if (grub_file_progress_hook && file) - grub_file_progress_hook (0, 0, len, NULL, file); + grub_memcpy (dest, at->sbuf, len); } quit: diff --git a/grub-core/fs/reiserfs.c b/fs/reiserfs.c similarity index 64% rename from grub-core/fs/reiserfs.c rename to fs/reiserfs.c index 5d3c85950..c3db52f60 100644 --- a/grub-core/fs/reiserfs.c +++ b/fs/reiserfs.c @@ -38,10 +38,6 @@ #include #include #include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); #define MIN(a, b) \ ({ typeof (a) _a = (a); \ @@ -59,12 +55,14 @@ GRUB_MOD_LICENSE ("GPLv3+"); #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__) +#define assert(boolean) real_assert (boolean, __FILE__, __LINE__) static inline void real_assert (int boolean, const char *file, const int line) { @@ -109,15 +107,14 @@ struct grub_reiserfs_superblock grub_uint32_t inode_generation; grub_uint8_t unused[4]; grub_uint16_t uuid[8]; - char label[16]; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_reiserfs_journal_header { grub_uint32_t last_flush_uid; grub_uint32_t unflushed_offset; grub_uint32_t mount_id; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_reiserfs_description_block { @@ -125,14 +122,14 @@ struct grub_reiserfs_description_block grub_uint32_t len; grub_uint32_t mount_id; grub_uint32_t real_blocks[0]; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_reiserfs_commit_block { grub_uint32_t id; grub_uint32_t len; grub_uint32_t real_blocks[0]; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_reiserfs_stat_item_v1 { @@ -146,7 +143,7 @@ struct grub_reiserfs_stat_item_v1 grub_uint32_t ctime; grub_uint32_t rdev; grub_uint32_t first_direct_byte; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_reiserfs_stat_item_v2 { @@ -161,7 +158,7 @@ struct grub_reiserfs_stat_item_v2 grub_uint32_t ctime; grub_uint32_t blocks; grub_uint32_t first_direct_byte; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_reiserfs_key { @@ -173,13 +170,13 @@ struct grub_reiserfs_key { grub_uint32_t offset; grub_uint32_t type; - } GRUB_PACKED v1; + } v1 __attribute__ ((packed)); struct { grub_uint64_t offset_type; - } GRUB_PACKED v2; + } v2 __attribute__ ((packed)); } u; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_reiserfs_item_header { @@ -188,11 +185,11 @@ struct grub_reiserfs_item_header { grub_uint16_t free_space; grub_uint16_t entry_count; - } GRUB_PACKED u; + } u __attribute__ ((packed)); grub_uint16_t item_size; grub_uint16_t item_location; grub_uint16_t version; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_reiserfs_block_header { @@ -201,14 +198,14 @@ struct grub_reiserfs_block_header grub_uint16_t free_space; grub_uint16_t reserved; struct grub_reiserfs_key block_right_delimiting_key; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_reiserfs_disk_child { grub_uint32_t block_number; grub_uint16_t size; grub_uint16_t reserved; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_reiserfs_directory_header { @@ -217,7 +214,7 @@ struct grub_reiserfs_directory_header grub_uint32_t object_id; grub_uint16_t location; grub_uint16_t state; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_fshelp_node { @@ -225,8 +222,6 @@ struct grub_fshelp_node grub_uint32_t block_number; /* 0 if node is not found. */ grub_uint16_t block_position; grub_uint64_t next_offset; - grub_int32_t mtime; - grub_off_t size; enum grub_reiserfs_item_type type; /* To know how to read the header. */ struct grub_reiserfs_item_header header; }; @@ -238,12 +233,6 @@ struct grub_reiserfs_data grub_disk_t disk; }; -static grub_ssize_t -grub_reiserfs_read_real (struct grub_fshelp_node *node, - grub_off_t off, char *buf, grub_size_t len, - grub_disk_read_hook_t read_hook, - void *read_hook_data); - /* Internal-only functions. Not to be used outside of this file. */ /* Return the type of given v2 key. */ @@ -366,7 +355,7 @@ grub_reiserfs_set_key_offset (struct grub_reiserfs_key *key, key->u.v1.offset = grub_cpu_to_le32 (value); else key->u.v2.offset_type \ - = ((key->u.v2.offset_type & grub_cpu_to_le64_compile_time (15ULL << 60)) + = ((key->u.v2.offset_type & grub_cpu_to_le64 (15ULL << 60)) | grub_cpu_to_le64 (value & (~0ULL >> 4))); } @@ -413,7 +402,7 @@ grub_reiserfs_set_key_type (struct grub_reiserfs_key *key, key->u.v1.type = grub_cpu_to_le32 (type); else key->u.v2.offset_type - = ((key->u.v2.offset_type & grub_cpu_to_le64_compile_time (~0ULL >> 4)) + = ((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); @@ -476,7 +465,7 @@ grub_reiserfs_compare_keys (const struct grub_reiserfs_key *key1, static grub_err_t grub_reiserfs_get_item (struct grub_reiserfs_data *data, const struct grub_reiserfs_key *key, - struct grub_fshelp_node *item, int exact) + struct grub_fshelp_node *item) { grub_uint32_t block_number; struct grub_reiserfs_block_header *block_header = 0; @@ -486,25 +475,23 @@ grub_reiserfs_get_item (struct grub_reiserfs_data *data, grub_uint16_t previous_level = ~0; struct grub_reiserfs_item_header *item_headers = 0; -#if 0 if (! data) { - grub_error (GRUB_ERR_BAD_FS, "data is NULL"); + grub_error (GRUB_ERR_TEST_FAILURE, "data is NULL"); goto fail; } if (! key) { - grub_error (GRUB_ERR_BAD_FS, "key is NULL"); + grub_error (GRUB_ERR_TEST_FAILURE, "key is NULL"); goto fail; } if (! item) { - grub_error (GRUB_ERR_BAD_FS, "item is NULL"); + grub_error (GRUB_ERR_TEST_FAILURE, "item is NULL"); goto fail; } -#endif block_size = grub_le_to_cpu16 (data->superblock.block_size); block_number = grub_le_to_cpu32 (data->superblock.root_block); @@ -531,7 +518,7 @@ grub_reiserfs_get_item (struct grub_reiserfs_data *data, if (current_level >= previous_level) { grub_dprintf ("reiserfs_tree", "level loop detected, aborting\n"); - grub_error (GRUB_ERR_BAD_FS, "level loop"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "level loop"); goto fail; } previous_level = current_level; @@ -589,47 +576,30 @@ grub_reiserfs_get_item (struct grub_reiserfs_data *data, item_headers = (struct grub_reiserfs_item_header *) (block_header + 1); for (i = 0; - i < item_count; + i < item_count + && (grub_reiserfs_compare_keys (key, &(item_headers[i].key)) + != 0); i++) - { - int val; - val = grub_reiserfs_compare_keys (key, &(item_headers[i].key)); - if (val == 0) - { - block_key = &(item_headers[i].key); - break; - } - if (val < 0 && exact) - break; - if (val < 0) - { - if (i == 0) - { - grub_error (GRUB_ERR_READ_ERROR, "unexpected btree node"); - goto fail; - } - i--; - block_key = &(item_headers[i].key); - break; - } - } - if (!exact && i == item_count) - { - if (i == 0) - { - grub_error (GRUB_ERR_READ_ERROR, "unexpected btree node"); - goto fail; - } - i--; - block_key = &(item_headers[i].key); - } + { +#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 (!block_key) + if (i == item_count || grub_reiserfs_compare_keys (key, block_key)) { item->block_number = 0; item->block_position = 0; @@ -667,22 +637,43 @@ static char * grub_reiserfs_read_symlink (grub_fshelp_node_t node) { char *symlink_buffer = 0; - grub_size_t len = node->size; - grub_ssize_t ret; + 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) - return 0; + goto fail; - ret = grub_reiserfs_read_real (node, 0, symlink_buffer, len, 0, 0); - if (ret < 0) - { - grub_free (symlink_buffer); - return 0; - } + grub_disk_read (node->data->disk, block, offset, len, symlink_buffer); + if (grub_errno) + goto fail; - symlink_buffer[ret] = 0; + symlink_buffer[len] = 0; return symlink_buffer; + + fail: + grub_free (symlink_buffer); + return 0; } /* Fill the mounted filesystem structure and return it. */ @@ -718,8 +709,10 @@ grub_reiserfs_mount (grub_disk_t disk) /* Call HOOK for each file in directory ITEM. */ static int grub_reiserfs_iterate_dir (grub_fshelp_node_t item, - grub_fshelp_iterate_dir_hook_t hook, - void *hook_data) + 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; @@ -730,11 +723,12 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item, if (item->type != GRUB_REISERFS_DIRECTORY) { - grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a 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 + 1); + block_header = grub_malloc (block_size); if (! block_header) goto fail; block_number = item->block_number; @@ -755,12 +749,10 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item, if (grub_errno) goto fail; - ((char *) block_header)[block_size] = 0; - #if 0 if (grub_le_to_cpu16 (block_header->level) != 1) { - grub_error (GRUB_ERR_BAD_FS, + grub_error (GRUB_ERR_TEST_FAILURE, "reiserfs: block %d is not a leaf block", block_number); goto fail; @@ -780,203 +772,178 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item, = &directory_headers[entry_number]; grub_uint16_t entry_state = grub_le_to_cpu16 (directory_header->state); - grub_fshelp_node_t entry_item; - struct grub_reiserfs_key entry_key; - enum grub_fshelp_filetype entry_type; - char *entry_name; - char *entry_name_end = 0; - char c; - if (!(entry_state & GRUB_REISERFS_VISIBLE_MASK)) - continue; + 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)); - if (entry_number == 0) - { - entry_name_end = (char *) block_header - + grub_le_to_cpu16 (item_headers[block_position].item_location) - + grub_le_to_cpu16 (item_headers[block_position].item_size); - } - else - { - entry_name_end = (((char *) directory_headers) - + grub_le_to_cpu16 (directory_headers[entry_number - 1].location)); - } - if (entry_name_end < entry_name || entry_name_end > (char *) block_header + block_size) - { - entry_name_end = (char *) block_header + block_size; - } + 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_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; - 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 (grub_reiserfs_get_item (data, &entry_key, entry_item, 1) - != 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->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, 1) - != 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 (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", - "%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); + "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 - entry_item->mtime = grub_le_to_cpu32 (entry_v1_stat.mtime); - if ((grub_le_to_cpu16 (entry_v1_stat.mode) & S_IFLNK) - == S_IFLNK) - entry_type = GRUB_FSHELP_SYMLINK; - else - entry_type = GRUB_FSHELP_REG; - entry_item->size = (grub_off_t) grub_le_to_cpu32 (entry_v1_stat.size); - } - 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 (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 %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); + 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 - entry_item->mtime = grub_le_to_cpu32 (entry_v2_stat.mtime); - entry_item->size = (grub_off_t) grub_le_to_cpu64 (entry_v2_stat.size); - 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 (entry_name_end == entry_name + 2 && grub_memcmp (entry_name, "..", 2) != 0) - grub_dprintf ("reiserfs", - "Warning : %s has no stat block !\n", - entry_name); - grub_free (entry_item); - goto next; - } - } + 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; + } - c = *entry_name_end; - *entry_name_end = 0; - if (hook (entry_name, entry_type, entry_item, hook_data)) - { - *entry_name_end = c; - grub_dprintf ("reiserfs", "Found : %s, type=%d\n", - entry_name, entry_type); - ret = 1; - goto found; - } - *entry_name_end = c; - - next: - ; + *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) @@ -985,7 +952,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item, 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, 1) != GRUB_ERR_NONE) + &directory_item) != GRUB_ERR_NONE) goto fail; block_number = directory_item.block_number; block_position = directory_item.block_position; @@ -1012,19 +979,22 @@ 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; + 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; - key.directory_id = grub_cpu_to_le32_compile_time (1); - key.object_id = grub_cpu_to_le32_compile_time (2); + 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, 1) != GRUB_ERR_NONE) + if (grub_reiserfs_get_item (data, &key, &root) != GRUB_ERR_NONE) goto fail; if (root.block_number == 0) { @@ -1036,8 +1006,46 @@ grub_reiserfs_open (struct grub_file *file, const char *name) grub_reiserfs_read_symlink, GRUB_FSHELP_REG); if (grub_errno) goto fail; - file->size = found->size; - + 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); @@ -1047,20 +1055,18 @@ grub_reiserfs_open (struct grub_file *file, const char *name) fail: assert (grub_errno != GRUB_ERR_NONE); - if (found != &root) - grub_free (found); + grub_free (found); grub_free (data); grub_dl_unref (my_mod); return grub_errno; } static grub_ssize_t -grub_reiserfs_read_real (struct grub_fshelp_node *node, - grub_off_t off, char *buf, grub_size_t len, - grub_disk_read_hook_t read_hook, void *read_hook_data) +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); @@ -1075,36 +1081,20 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node, 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 = off; + initial_position = file->offset; current_position = 0; - final_position = MIN (len + initial_position, node->size); + 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); - - grub_reiserfs_set_key_offset (&key, initial_position + 1); - - if (grub_reiserfs_get_item (data, &key, &found, 0) != GRUB_ERR_NONE) - goto fail; - - if (found.block_number == 0) - { - grub_error (GRUB_ERR_READ_ERROR, "offset %lld not found", - (unsigned long long) initial_position); - goto fail; - } - - current_key_offset = grub_reiserfs_get_key_offset (&found.header.key); - current_position = current_key_offset - 1; - while (current_position < final_position) { grub_reiserfs_set_key_offset (&key, current_key_offset); - if (grub_reiserfs_get_item (data, &key, &found, 1) != GRUB_ERR_NONE) + if (grub_reiserfs_get_item (data, &key, &found) != GRUB_ERR_NONE) goto fail; if (found.block_number == 0) goto fail; @@ -1112,7 +1102,7 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node, switch (found.type) { case GRUB_REISERFS_DIRECT: - block = ((grub_disk_addr_t) found.block_number) * (block_size >> GRUB_DISK_SECTOR_BITS); + 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) { @@ -1123,8 +1113,7 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node, "Reading direct block %u from %u to %u...\n", (unsigned) block, (unsigned) offset, (unsigned) (offset + length)); - found.data->disk->read_hook = read_hook; - found.data->disk->read_hook_data = read_hook_data; + found.data->disk->read_hook = file->read_hook; grub_disk_read (found.data->disk, block, offset @@ -1150,8 +1139,7 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node, item_size, indirect_block_ptr); if (grub_errno) goto fail; - found.data->disk->read_hook = read_hook; - found.data->disk->read_hook_data = read_hook_data; + found.data->disk->read_hook = file->read_hook; for (indirect_block = 0; indirect_block < indirect_block_count && current_position < final_position; @@ -1250,14 +1238,7 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node, fail: grub_free (indirect_block_ptr); - return -1; -} - -static grub_ssize_t -grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len) -{ - return grub_reiserfs_read_real (file->data, file->offset, buf, len, - file->read_hook, file->read_hook_data); + return 0; } /* Close the file FILE. */ @@ -1273,50 +1254,40 @@ grub_reiserfs_close (grub_file_t file) return GRUB_ERR_NONE; } -/* Context for grub_reiserfs_dir. */ -struct grub_reiserfs_dir_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; -}; - -/* Helper for grub_reiserfs_dir. */ -static int -grub_reiserfs_dir_iter (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, void *data) -{ - struct grub_reiserfs_dir_ctx *ctx = data; - 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; - grub_free (node); - return ctx->hook (filename, &info, ctx->hook_data); -} - /* Call HOOK with each file under DIR. */ static grub_err_t grub_reiserfs_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) + int (*hook) (const char *filename, + const struct grub_dirhook_info *info)) { - struct grub_reiserfs_dir_ctx ctx = { hook, hook_data }; 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_compile_time (1); - root_key.object_id = grub_cpu_to_le32_compile_time (2); + 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, 1) != GRUB_ERR_NONE) + if (grub_reiserfs_get_item (data, &root_key, &root) != GRUB_ERR_NONE) goto fail; if (root.block_number == 0) { @@ -1327,7 +1298,7 @@ grub_reiserfs_dir (grub_device_t device, const char *path, grub_reiserfs_read_symlink, GRUB_FSHELP_DIR); if (grub_errno) goto fail; - grub_reiserfs_iterate_dir (found, grub_reiserfs_dir_iter, &ctx); + grub_reiserfs_iterate_dir (found, iterate); grub_free (data); grub_dl_unref (my_mod); return GRUB_ERR_NONE; @@ -1344,24 +1315,14 @@ grub_reiserfs_dir (grub_device_t device, const char *path, static grub_err_t grub_reiserfs_label (grub_device_t device, char **label) { - struct grub_reiserfs_data *data; - grub_disk_t disk = device->disk; - - grub_dl_ref (my_mod); - - data = grub_reiserfs_mount (disk); - if (data) + *label = grub_malloc (REISERFS_MAX_LABEL_LENGTH); + if (*label) { - *label = grub_strndup (data->superblock.label, - sizeof (data->superblock.label)); + grub_disk_read (device->disk, + REISERFS_SUPER_BLOCK_OFFSET / GRUB_DISK_SECTOR_SIZE, + REISERFS_LABEL_OFFSET, REISERFS_MAX_LABEL_LENGTH, + *label); } - else - *label = NULL; - - grub_dl_unref (my_mod); - - grub_free (data); - return grub_errno; } @@ -1373,25 +1334,21 @@ grub_reiserfs_uuid (grub_device_t device, char **uuid) grub_dl_ref (my_mod); - *uuid = NULL; data = grub_reiserfs_mount (disk); if (data) { - unsigned i; - for (i = 0; i < ARRAY_SIZE (data->superblock.uuid); i++) - if (data->superblock.uuid[i]) - break; - if (i < ARRAY_SIZE (data->superblock.uuid)) - *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])); + *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); @@ -1403,31 +1360,22 @@ grub_reiserfs_uuid (grub_device_t device, char **uuid) static struct grub_fs grub_reiserfs_fs = { .name = "reiserfs", - .fs_dir = grub_reiserfs_dir, - .fs_open = grub_reiserfs_open, - .fs_read = grub_reiserfs_read, - .fs_close = grub_reiserfs_close, - .fs_label = grub_reiserfs_label, - .fs_uuid = grub_reiserfs_uuid, -#ifdef GRUB_UTIL - .reserved_first_sector = 1, - .blocklist_install = 1, -#endif + .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) { - if (!grub_is_lockdown ()) - { - grub_reiserfs_fs.mod = mod; - grub_fs_register (&grub_reiserfs_fs); - } + grub_fs_register (&grub_reiserfs_fs); my_mod = mod; } GRUB_MOD_FINI(reiserfs) { - if (!grub_is_lockdown ()) - grub_fs_unregister (&grub_reiserfs_fs); + grub_fs_unregister (&grub_reiserfs_fs); } diff --git a/grub-core/fs/sfs.c b/fs/sfs.c similarity index 52% rename from grub-core/fs/sfs.c rename to fs/sfs.c index bad4ae8d1..68f8b3a6e 100644 --- a/grub-core/fs/sfs.c +++ b/fs/sfs.c @@ -25,11 +25,6 @@ #include #include #include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); /* The common header for a block. */ struct grub_sfs_bheader @@ -37,27 +32,20 @@ struct grub_sfs_bheader grub_uint8_t magic[4]; grub_uint32_t chksum; grub_uint32_t ipointtomyself; -} GRUB_PACKED; +} __attribute__ ((packed)); /* The sfs rootblock. */ struct grub_sfs_rblock { struct grub_sfs_bheader header; grub_uint32_t version; - grub_uint32_t createtime; - grub_uint8_t flags; - grub_uint8_t unused1[31]; + 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; -} GRUB_PACKED; - -enum - { - FLAGS_CASE_SENSITIVE = 0x80 - }; +} __attribute__ ((packed)); /* A SFS object container. */ struct grub_sfs_obj @@ -71,18 +59,18 @@ struct grub_sfs_obj { grub_uint32_t first_block; grub_uint32_t size; - } GRUB_PACKED file; + } file __attribute__ ((packed)); struct { grub_uint32_t hashtable; grub_uint32_t dir_objc; - } GRUB_PACKED dir; + } dir __attribute__ ((packed)); } file_dir; - grub_uint32_t mtime; + grub_uint8_t unused3[4]; grub_uint8_t type; grub_uint8_t filename[1]; grub_uint8_t comment[1]; -} GRUB_PACKED; +} __attribute__ ((packed)); #define GRUB_SFS_TYPE_DELETED 32 #define GRUB_SFS_TYPE_SYMLINK 64 @@ -97,13 +85,13 @@ struct grub_sfs_objc grub_uint32_t prev; /* The amount of objects depends on the blocksize. */ struct grub_sfs_obj objects[1]; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_sfs_btree_node { grub_uint32_t key; grub_uint32_t data; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_sfs_btree_extent { @@ -111,7 +99,7 @@ struct grub_sfs_btree_extent grub_uint32_t next; grub_uint32_t prev; grub_uint16_t size; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_sfs_btree { @@ -122,27 +110,15 @@ struct grub_sfs_btree /* Normally this can be kind of node, but just extents are supported. */ struct grub_sfs_btree_node node[1]; -} GRUB_PACKED; +} __attribute__ ((packed)); -struct cache_entry -{ - grub_uint32_t off; - grub_uint32_t block; -}; - struct grub_fshelp_node { struct grub_sfs_data *data; - grub_uint32_t block; - grub_uint32_t size; - grub_uint32_t mtime; - grub_uint32_t cache_off; - grub_uint32_t next_extent; - grub_size_t cache_allocated; - grub_size_t cache_size; - struct cache_entry *cache; + int block; + int size; }; /* Information about a "mounted" sfs filesystem. */ @@ -152,10 +128,8 @@ struct grub_sfs_data struct grub_fshelp_node diropen; grub_disk_t disk; - /* Log of blocksize in sectors. */ - int log_blocksize; - - int fshelp_flags; + /* Blocksize in sectors. */ + unsigned int blocksize; /* Label of the filesystem. */ char *label; @@ -169,17 +143,17 @@ static grub_dl_t my_mod; in NEXTEXT. */ static grub_err_t grub_sfs_read_extent (struct grub_sfs_data *data, unsigned int block, - grub_uint32_t *size, grub_uint32_t *nextext) + int *size, int *nextext) { char *treeblock; struct grub_sfs_btree *tree; int i; - grub_uint32_t next; - grub_size_t blocksize = GRUB_DISK_SECTOR_SIZE << data->log_blocksize; + int next; + int prev; - treeblock = grub_malloc (blocksize); - if (!treeblock) - return grub_errno; + treeblock = grub_malloc (data->blocksize); + if (!block) + return 0; next = grub_be_to_cpu32 (data->rblock.btree); tree = (struct grub_sfs_btree *) treeblock; @@ -187,21 +161,16 @@ grub_sfs_read_extent (struct grub_sfs_data *data, unsigned int block, /* Handle this level in the btree. */ do { - grub_uint16_t nnodes; - grub_disk_read (data->disk, - ((grub_disk_addr_t) next) << data->log_blocksize, - 0, blocksize, treeblock); + prev = 0; + + grub_disk_read (data->disk, next, 0, data->blocksize, treeblock); if (grub_errno) { grub_free (treeblock); return grub_errno; } - nnodes = grub_be_to_cpu16 (tree->nodes); - if (nnodes * (grub_uint32_t) (tree)->nodesize > blocksize) - break; - - for (i = (int) nnodes - 1; i >= 0; i--) + for (i = grub_be_to_cpu16 (tree->nodes) - 1; i >= 0; i--) { #define EXTNODE(tree, index) \ @@ -243,105 +212,27 @@ grub_sfs_read_extent (struct grub_sfs_data *data, unsigned int block, static grub_disk_addr_t grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) { - grub_uint32_t blk; - grub_uint32_t size = 0; - grub_uint32_t next = 0; - grub_disk_addr_t off; - struct grub_sfs_data *data = node->data; - - /* In case of the first block we don't have to lookup the - extent, the minimum size is always 1. */ - if (fileblock == 0) - return node->block; - - if (!node->cache) - { - grub_size_t cache_size; - /* Assume half-max extents (32768 sectors). */ - cache_size = ((node->size >> (data->log_blocksize + GRUB_DISK_SECTOR_BITS - + 15)) - + 3); - if (cache_size < 8) - cache_size = 8; - - node->cache_off = 0; - node->next_extent = node->block; - node->cache_size = 0; - - node->cache = grub_calloc (cache_size, sizeof (node->cache[0])); - if (!node->cache) - { - grub_errno = 0; - node->cache_allocated = 0; - } - else - { - node->cache_allocated = cache_size; - node->cache[0].off = 0; - node->cache[0].block = node->block; - } - } - - if (fileblock < node->cache_off) - { - unsigned int i = 0; - int j, lg; - for (lg = 0; node->cache_size >> lg; lg++); - - for (j = lg - 1; j >= 0; j--) - if ((i | (1 << j)) < node->cache_size - && node->cache[(i | (1 << j))].off <= fileblock) - i |= (1 << j); - return node->cache[i].block + fileblock - node->cache[i].off; - } - - off = node->cache_off; - blk = node->next_extent; + 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 (node->cache && node->cache_size >= node->cache_allocated) - { - struct cache_entry *e = node->cache; - grub_size_t sz; + if (fileblock < (unsigned int) size) + return fileblock + blk; - if (grub_mul (node->cache_allocated, 2 * sizeof (e[0]), &sz)) - goto fail; - - e = grub_realloc (node->cache, sz); - if (!e) - { - fail: - grub_errno = 0; - grub_free (node->cache); - node->cache = 0; - } - else - { - node->cache_allocated *= 2; - node->cache = e; - } - } - - if (node->cache) - { - node->cache_off = off + size; - node->next_extent = next; - node->cache[node->cache_size].off = off; - node->cache[node->cache_size].block = blk; - node->cache_size++; - } - - if (fileblock - off < size) - return fileblock - off + blk; - - off += size; + fileblock -= size; blk = next; } @@ -357,13 +248,13 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) POS. Return the amount of read bytes in READ. */ static grub_ssize_t grub_sfs_read_file (grub_fshelp_node_t node, - grub_disk_read_hook_t read_hook, void *read_hook_data, - grub_off_t pos, grub_size_t len, char *buf) + 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, read_hook_data, + return grub_fshelp_read_file (node->data->disk, node, read_hook, pos, len, buf, grub_sfs_read_block, - node->size, node->data->log_blocksize, 0); + node->size, 0); } @@ -373,8 +264,7 @@ grub_sfs_mount (grub_disk_t disk) struct grub_sfs_data *data; struct grub_sfs_objc *rootobjc; char *rootobjc_data = 0; - grub_uint32_t blk; - unsigned int max_len; + unsigned int blk; data = grub_malloc (sizeof (*data)); if (!data) @@ -387,31 +277,20 @@ grub_sfs_mount (grub_disk_t disk) goto fail; /* Make sure this is a sfs filesystem. */ - if (grub_strncmp ((char *) (data->rblock.header.magic), "SFS", 4) - || data->rblock.blocksize == 0 - || (data->rblock.blocksize & (data->rblock.blocksize - 1)) != 0 - || (data->rblock.blocksize & grub_cpu_to_be32_compile_time (0xf00001ff))) + if (grub_strncmp ((char *) (data->rblock.header.magic), "SFS", 4)) { grub_error (GRUB_ERR_BAD_FS, "not a SFS filesystem"); goto fail; } - for (data->log_blocksize = 9; - (1U << data->log_blocksize) < grub_be_to_cpu32 (data->rblock.blocksize); - data->log_blocksize++); - data->log_blocksize -= GRUB_DISK_SECTOR_BITS; - if (data->rblock.flags & FLAGS_CASE_SENSITIVE) - data->fshelp_flags = 0; - else - data->fshelp_flags = GRUB_FSHELP_CASE_INSENSITIVE; - rootobjc_data = grub_malloc (GRUB_DISK_SECTOR_SIZE << data->log_blocksize); + 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_disk_addr_t) grub_be_to_cpu32 (data->rblock.rootobject)) - << data->log_blocksize, 0, - GRUB_DISK_SECTOR_SIZE << data->log_blocksize, rootobjc_data); + grub_disk_read (disk, grub_be_to_cpu32 (data->rblock.rootobject), 0, + data->blocksize, rootobjc_data); if (grub_errno) goto fail; @@ -421,20 +300,9 @@ grub_sfs_mount (grub_disk_t disk) data->diropen.size = 0; data->diropen.block = blk; data->diropen.data = data; - data->diropen.cache = 0; data->disk = disk; + data->label = grub_strdup ((char *) (rootobjc->objects[0].filename)); - /* We only read 1 block of data, so truncate the name if needed. */ - max_len = ((GRUB_DISK_SECTOR_SIZE << data->log_blocksize) - - 24 /* offsetof (struct grub_sfs_objc, objects) */ - - 25); /* offsetof (struct grub_sfs_obj, filename) */ - data->label = grub_zalloc (max_len + 1); - if (data->label == NULL) - goto fail; - - grub_strncpy (data->label, (char *) rootobjc->objects[0].filename, max_len); - - grub_free (rootobjc_data); return data; fail: @@ -454,13 +322,11 @@ grub_sfs_read_symlink (grub_fshelp_node_t node) char *symlink; char *block; - block = grub_malloc (GRUB_DISK_SECTOR_SIZE << data->log_blocksize); + block = grub_malloc (data->blocksize); if (!block) return 0; - grub_disk_read (data->disk, ((grub_disk_addr_t) node->block) - << data->log_blocksize, - 0, GRUB_DISK_SECTOR_SIZE << data->log_blocksize, block); + grub_disk_read (data->disk, node->block, 0, data->blocksize, block); if (grub_errno) { grub_free (block); @@ -469,76 +335,46 @@ grub_sfs_read_symlink (grub_fshelp_node_t node) /* 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_malloc (((GRUB_DISK_SECTOR_SIZE << data->log_blocksize) - - 24) * GRUB_MAX_UTF8_PER_LATIN1 + 1); - if (!symlink) - { - grub_free (block); - return 0; - } - *grub_latin1_to_utf8 ((grub_uint8_t *) symlink, (grub_uint8_t *) &block[24], - (GRUB_DISK_SECTOR_SIZE << data->log_blocksize) - 24) = '\0'; + symlink = grub_strdup (&block[24]); grub_free (block); + if (!symlink) + return 0; + return symlink; } -/* Helper for grub_sfs_iterate_dir. */ -static int -grub_sfs_create_node (struct grub_fshelp_node **node, - struct grub_sfs_data *data, - const char *name, - grub_uint32_t block, grub_uint32_t size, int type, - grub_uint32_t mtime, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data) -{ - grub_size_t len = grub_strlen (name); - grub_uint8_t *name_u8; - int ret; - grub_size_t sz; - - if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) || - grub_add (sz, 1, &sz)) - return 1; - - *node = grub_malloc (sizeof (**node)); - if (!*node) - return 1; - name_u8 = grub_malloc (sz); - if (!name_u8) - { - grub_free (*node); - return 1; - } - - (*node)->data = data; - (*node)->size = size; - (*node)->block = block; - (*node)->mtime = mtime; - (*node)->cache = 0; - (*node)->cache_off = 0; - (*node)->next_extent = block; - (*node)->cache_size = 0; - (*node)->cache_allocated = 0; - - *grub_latin1_to_utf8 (name_u8, (const grub_uint8_t *) name, len) = '\0'; - - ret = hook ((char *) name_u8, type | data->fshelp_flags, *node, hook_data); - grub_free (name_u8); - return ret; -} - static int grub_sfs_iterate_dir (grub_fshelp_node_t dir, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data) + 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; - grub_uint32_t pos; + int pos; - objc_data = grub_malloc (GRUB_DISK_SECTOR_SIZE << data->log_blocksize); + 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; @@ -546,9 +382,7 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir, every block. */ while (next) { - grub_disk_read (data->disk, ((grub_disk_addr_t) next) - << data->log_blocksize, 0, - GRUB_DISK_SECTOR_SIZE << data->log_blocksize, objc_data); + grub_disk_read (data->disk, next, 0, data->blocksize, objc_data); if (grub_errno) goto fail; @@ -557,15 +391,14 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir, pos = (char *) &objc->objects[0] - (char *) objc; /* Iterate over all entries in this block. */ - while (pos + sizeof (struct grub_sfs_obj) - < (1U << (GRUB_DISK_SECTOR_BITS + data->log_blocksize))) + while (pos + sizeof (struct grub_sfs_obj) < data->blocksize) { struct grub_sfs_obj *obj; obj = (struct grub_sfs_obj *) ((char *) objc + pos); - const char *filename = (const char *) obj->filename; - grub_size_t len; + char *filename = (char *) (obj->filename); + int len; enum grub_fshelp_filetype type; - grub_uint32_t block; + unsigned int block; /* The filename and comment dynamically increase the size of the object. */ @@ -576,7 +409,7 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir, /* Round up to a multiple of two bytes. */ pos = ((pos + 1) >> 1) << 1; - if (filename[0] == 0) + if (grub_strlen (filename) == 0) continue; /* First check if the file was not deleted. */ @@ -594,10 +427,9 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir, else block = grub_be_to_cpu32 (obj->file_dir.file.first_block); - if (grub_sfs_create_node (&node, data, filename, block, + if (grub_sfs_create_node (filename, block, grub_be_to_cpu32 (obj->file_dir.file.size), - type, grub_be_to_cpu32 (obj->mtime), - hook, hook_data)) + type)) { grub_free (objc_data); return 1; @@ -656,11 +488,7 @@ grub_sfs_open (struct grub_file *file, const char *name) static grub_err_t grub_sfs_close (grub_file_t file) { - struct grub_sfs_data *data = (struct grub_sfs_data *) file->data; - - grub_free (data->diropen.cache); - grub_free (data->label); - grub_free (data); + grub_free (file->data); grub_dl_unref (my_mod); @@ -674,44 +502,36 @@ grub_sfs_read (grub_file_t file, char *buf, grub_size_t len) { struct grub_sfs_data *data = (struct grub_sfs_data *) file->data; - return grub_sfs_read_file (&data->diropen, - file->read_hook, file->read_hook_data, - file->offset, len, buf); + int size = grub_sfs_read_file (&data->diropen, file->read_hook, + file->offset, len, buf); + + return size; } -/* Context for grub_sfs_dir. */ -struct grub_sfs_dir_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; -}; - -/* Helper for grub_sfs_dir. */ -static int -grub_sfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, void *data) -{ - struct grub_sfs_dir_ctx *ctx = data; - struct grub_dirhook_info info; - - grub_memset (&info, 0, sizeof (info)); - info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); - info.mtime = node->mtime + 8 * 365 * 86400 + 86400 * 2; - info.mtimeset = 1; - grub_free (node->cache); - grub_free (node); - return ctx->hook (filename, &info, ctx->hook_data); -} - static grub_err_t grub_sfs_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) + int (*hook) (const char *filename, + const struct grub_dirhook_info *info)) { - struct grub_sfs_dir_ctx ctx = { hook, hook_data }; 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); @@ -723,7 +543,7 @@ grub_sfs_dir (grub_device_t device, const char *path, if (grub_errno) goto fail; - grub_sfs_iterate_dir (fdiro, grub_sfs_dir_iter, &ctx); + grub_sfs_iterate_dir (fdiro, iterate); fail: if (data && fdiro != &data->diropen) @@ -746,20 +566,8 @@ grub_sfs_label (grub_device_t device, char **label) data = grub_sfs_mount (disk); if (data) - { - grub_size_t sz, len = grub_strlen (data->label); + *label = data->label; - if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) || - grub_add (sz, 1, &sz)) - return GRUB_ERR_OUT_OF_RANGE; - - *label = grub_malloc (sz); - if (*label) - *grub_latin1_to_utf8 ((grub_uint8_t *) *label, - (const grub_uint8_t *) data->label, - len) = '\0'; - grub_free (data->label); - } grub_free (data); return grub_errno; @@ -769,30 +577,21 @@ grub_sfs_label (grub_device_t device, char **label) static struct grub_fs grub_sfs_fs = { .name = "sfs", - .fs_dir = grub_sfs_dir, - .fs_open = grub_sfs_open, - .fs_read = grub_sfs_read, - .fs_close = grub_sfs_close, - .fs_label = grub_sfs_label, -#ifdef GRUB_UTIL - .reserved_first_sector = 0, - .blocklist_install = 1, -#endif + .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) { - if (!grub_is_lockdown ()) - { - grub_sfs_fs.mod = mod; - grub_fs_register (&grub_sfs_fs); - } + grub_fs_register (&grub_sfs_fs); my_mod = mod; } GRUB_MOD_FINI(sfs) { - if (!grub_is_lockdown ()) - grub_fs_unregister (&grub_sfs_fs); + grub_fs_unregister (&grub_sfs_fs); } diff --git a/fs/tar.c b/fs/tar.c new file mode 100644 index 000000000..6ab62bca7 --- /dev/null +++ b/fs/tar.c @@ -0,0 +1,2 @@ +#define MODE_USTAR 1 +#include "cpio.c" diff --git a/fs/udf.c b/fs/udf.c new file mode 100644 index 000000000..cecb6eb78 --- /dev/null +++ b/fs/udf.c @@ -0,0 +1,916 @@ +/* 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#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; + char filename[dirent.file_ident_length + 1]; + + 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, filename)) + != dirent.file_ident_length) + return 0; + + filename[dirent.file_ident_length] = 0; + if (hook (&filename[1], 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/fs/ufs.c similarity index 54% rename from grub-core/fs/ufs.c rename to fs/ufs.c index 8b5adbd48..40cf068e6 100644 --- a/grub-core/fs/ufs.c +++ b/fs/ufs.c @@ -24,10 +24,6 @@ #include #include #include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); #ifdef MODE_UFS2 #define GRUB_UFS_MAGIC 0x19540119 @@ -50,50 +46,24 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define GRUB_UFS_VOLNAME_LEN 32 -#ifdef MODE_BIGENDIAN -#define grub_ufs_to_cpu16 grub_be_to_cpu16 -#define grub_ufs_to_cpu32 grub_be_to_cpu32 -#define grub_ufs_to_cpu64 grub_be_to_cpu64 -#define grub_cpu_to_ufs32_compile_time grub_cpu_to_be32_compile_time -#else -#define grub_ufs_to_cpu16 grub_le_to_cpu16 -#define grub_ufs_to_cpu32 grub_le_to_cpu32 -#define grub_ufs_to_cpu64 grub_le_to_cpu64 -#define grub_cpu_to_ufs32_compile_time grub_cpu_to_le32_compile_time -#endif - -#ifdef MODE_UFS2 -typedef grub_uint64_t grub_ufs_blk_t; -static inline grub_disk_addr_t -grub_ufs_to_cpu_blk (grub_ufs_blk_t blk) -{ - return grub_ufs_to_cpu64 (blk); -} -#else -typedef grub_uint32_t grub_ufs_blk_t; -static inline grub_disk_addr_t -grub_ufs_to_cpu_blk (grub_ufs_blk_t blk) -{ - return grub_ufs_to_cpu32 (blk); -} -#endif - /* Calculate in which group the inode can be found. */ -#define UFS_BLKSZ(sblock) (grub_ufs_to_cpu32 (sblock->bsize)) -#define UFS_LOG_BLKSZ(sblock) (data->log2_blksz) +#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_ufs_to_cpu##bits2 (data->inode.field) +#define INODE_ENDIAN(data,field,bits1,bits2) grub_le_to_cpu##bits2 (data->inode.field) #else -#define INODE_ENDIAN(data,field,bits1,bits2) grub_ufs_to_cpu##bits1 (data->inode.field) +#define INODE_ENDIAN(data,field,bits1,bits2) grub_le_to_cpu##bits1 (data->inode.field) #endif -#define INODE_SIZE(data) grub_ufs_to_cpu64 (data->inode.size) -#define INODE_MODE(data) grub_ufs_to_cpu16 (data->inode.mode) +#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 LOG_INODE_BLKSZ 3 +#define INODE_BLKSZ 8 #else -#define LOG_INODE_BLKSZ 2 +#define INODE_BLKSZ 4 #endif #ifdef MODE_UFS2 #define UFS_INODE_PER_BLOCK 2 @@ -162,15 +132,15 @@ struct grub_ufs_inode grub_uint32_t uid; grub_uint32_t gid; grub_uint32_t blocksize; - grub_uint64_t size; + 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_usec; - grub_uint32_t mtime_usec; - grub_uint32_t ctime_usec; + 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; @@ -188,7 +158,7 @@ struct grub_ufs_inode }; grub_uint8_t unused[24]; -} GRUB_PACKED; +} __attribute__ ((packed)); #else /* UFS inode. */ struct grub_ufs_inode @@ -197,13 +167,10 @@ struct grub_ufs_inode grub_uint16_t nlinks; grub_uint16_t uid; grub_uint16_t gid; - grub_uint64_t size; - grub_uint32_t atime; - grub_uint32_t atime_usec; - grub_uint32_t mtime; - grub_uint32_t mtime_usec; - grub_uint32_t ctime; - grub_uint32_t ctime_usec; + grub_int64_t size; + grub_uint64_t atime; + grub_uint64_t mtime; + grub_uint64_t ctime; union { struct @@ -218,7 +185,7 @@ struct grub_ufs_inode grub_uint32_t gen; grub_uint32_t unused; grub_uint8_t pad[12]; -} GRUB_PACKED; +} __attribute__ ((packed)); #endif /* Directory entry. */ @@ -235,7 +202,7 @@ struct grub_ufs_dirent grub_uint8_t namelen_bsd; }; }; -} GRUB_PACKED; +} __attribute__ ((packed)); /* Information about a "mounted" ufs filesystem. */ struct grub_ufs_data @@ -245,7 +212,6 @@ struct grub_ufs_data struct grub_ufs_inode inode; int ino; int linknest; - int log2_blksz; }; static grub_dl_t my_mod; @@ -256,80 +222,57 @@ static grub_err_t grub_ufs_find_file (struct grub_ufs_data *data, static grub_disk_addr_t -grub_ufs_get_file_block (struct grub_ufs_data *data, grub_disk_addr_t blk) +grub_ufs_get_file_block (struct grub_ufs_data *data, unsigned int blk) { - unsigned long indirsz; - int log2_blksz, log_indirsz; + 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_ufs_to_cpu32 (data->sblock.log2_blksz); + log2_blksz = grub_le_to_cpu32 (data->sblock.log2_blksz); blk -= GRUB_UFS_DIRBLKS; - log_indirsz = data->log2_blksz - LOG_INODE_BLKSZ; - indirsz = 1 << log_indirsz; - + indirsz = UFS_BLKSZ (sblock) / INODE_BLKSZ; /* Single indirect block. */ if (blk < indirsz) { - grub_ufs_blk_t indir; - grub_disk_read (data->disk, - ((grub_disk_addr_t) INODE_INDIRBLOCKS (data, 0)) - << log2_blksz, - blk * sizeof (indir), sizeof (indir), &indir); - return indir; +#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 < (grub_disk_addr_t) indirsz * (grub_disk_addr_t) indirsz) + if (blk < indirsz * indirsz) { - grub_ufs_blk_t indir; +#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, - ((grub_disk_addr_t) INODE_INDIRBLOCKS (data, 1)) + (indir [blk / indirsz]) << log2_blksz, - (blk >> log_indirsz) * sizeof (indir), - sizeof (indir), &indir); - grub_disk_read (data->disk, - grub_ufs_to_cpu_blk (indir) << log2_blksz, - (blk & ((1 << log_indirsz) - 1)) * sizeof (indir), - sizeof (indir), &indir); + 0, sizeof (indir), indir); - return indir; + return indir[blk % indirsz]; } - blk -= (grub_disk_addr_t) indirsz * (grub_disk_addr_t) indirsz; - /* Triple indirect block. */ - if (!(blk >> (3 * log_indirsz))) - { - grub_ufs_blk_t indir; - - grub_disk_read (data->disk, - ((grub_disk_addr_t) INODE_INDIRBLOCKS (data, 2)) - << log2_blksz, - (blk >> (2 * log_indirsz)) * sizeof (indir), - sizeof (indir), &indir); - grub_disk_read (data->disk, - grub_ufs_to_cpu_blk (indir) << log2_blksz, - ((blk >> log_indirsz) - & ((1 << log_indirsz) - 1)) * sizeof (indir), - sizeof (indir), &indir); - - grub_disk_read (data->disk, - grub_ufs_to_cpu_blk (indir) << log2_blksz, - (blk & ((1 << log_indirsz) - 1)) * sizeof (indir), - sizeof (indir), &indir); - - return indir; - } - - grub_error (GRUB_ERR_BAD_FS, - "ufs does not support quadruple indirect blocks"); + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "ufs does not support triple indirect blocks"); return 0; } @@ -338,29 +281,28 @@ grub_ufs_get_file_block (struct grub_ufs_data *data, grub_disk_addr_t blk) POS. Return the amount of read bytes in READ. */ static grub_ssize_t grub_ufs_read_file (struct grub_ufs_data *data, - grub_disk_read_hook_t read_hook, void *read_hook_data, - grub_off_t pos, grub_size_t len, char *buf) + 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; - grub_off_t i; - grub_off_t blockcnt; + 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_LOG_BLKSZ (sblock); + blockcnt = (len + pos + UFS_BLKSZ (sblock) - 1) / UFS_BLKSZ (sblock); - for (i = pos >> UFS_LOG_BLKSZ (sblock); i < blockcnt; i++) + for (i = pos / UFS_BLKSZ (sblock); i < blockcnt; i++) { - grub_disk_addr_t blknr; - grub_off_t blockoff; - grub_off_t blockend = UFS_BLKSZ (sblock); + int blknr; + int blockoff = pos % UFS_BLKSZ (sblock); + int blockend = UFS_BLKSZ (sblock); int skipfirst = 0; - blockoff = pos & (UFS_BLKSZ (sblock) - 1); - blknr = grub_ufs_get_file_block (data, i); if (grub_errno) return -1; @@ -368,14 +310,14 @@ grub_ufs_read_file (struct grub_ufs_data *data, /* Last block. */ if (i == blockcnt - 1) { - blockend = (len + pos) & (UFS_BLKSZ (sblock) - 1); + blockend = (len + pos) % UFS_BLKSZ (sblock); if (!blockend) blockend = UFS_BLKSZ (sblock); } /* First block. */ - if (i == (pos >> UFS_LOG_BLKSZ (sblock))) + if (i == (pos / (int) UFS_BLKSZ (sblock))) { skipfirst = blockoff; blockend -= skipfirst; @@ -386,16 +328,15 @@ grub_ufs_read_file (struct grub_ufs_data *data, if (blknr) { data->disk->read_hook = read_hook; - data->disk->read_hook_data = read_hook_data; grub_disk_read (data->disk, - blknr << grub_ufs_to_cpu32 (data->sblock.log2_blksz), + 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, 0, blockend); + grub_memset (buf, UFS_BLKSZ (sblock) - skipfirst, 0); buf += UFS_BLKSZ (sblock) - skipfirst; } @@ -411,17 +352,17 @@ 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_ufs_to_cpu32 (sblock->ino_per_group); + int group = ino / grub_le_to_cpu32 (sblock->ino_per_group); /* Determine the inode within the group. */ - int grpino = ino % grub_ufs_to_cpu32 (sblock->ino_per_group); + int grpino = ino % grub_le_to_cpu32 (sblock->ino_per_group); /* The first block of the group. */ - int grpblk = group * (grub_ufs_to_cpu32 (sblock->frags_per_group)); + int grpblk = group * (grub_le_to_cpu32 (sblock->frags_per_group)); #ifndef MODE_UFS2 - grpblk += grub_ufs_to_cpu32 (sblock->cylg_offset) - * (group & (~grub_ufs_to_cpu32 (sblock->cylg_mask))); + grpblk += grub_le_to_cpu32 (sblock->cylg_offset) + * (group & (~grub_le_to_cpu32 (sblock->cylg_mask))); #endif if (!inode) @@ -431,8 +372,8 @@ grub_ufs_read_inode (struct grub_ufs_data *data, int ino, char *inode) } grub_disk_read (data->disk, - ((grub_ufs_to_cpu32 (sblock->inoblk_offs) + grpblk) - << grub_ufs_to_cpu32 (data->sblock.log2_blksz)) + ((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), @@ -448,32 +389,21 @@ grub_ufs_read_inode (struct grub_ufs_data *data, int ino, char *inode) static grub_err_t grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino) { - char *symlink; - grub_size_t sz = INODE_SIZE (data); + char symlink[INODE_SIZE (data)]; if (++data->linknest > GRUB_UFS_MAX_SYMLNK_CNT) - return grub_error (GRUB_ERR_SYMLINK_LOOP, N_("too deep nesting of symlinks")); + return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks"); - symlink = grub_malloc (sz + 1); - if (!symlink) - return grub_errno; - /* Normally we should just check that data->inode.nblocks == 0. - However old Linux doesn't maintain nblocks correctly and so it's always - 0. If size is bigger than inline space then the symlink is surely not - inline. */ - /* Check against zero is paylindromic, no need to swap. */ - if (data->inode.nblocks == 0 - && INODE_SIZE (data) <= sizeof (data->inode.symlink)) - grub_strlcpy (symlink, (char *) data->inode.symlink, sz); + if (INODE_NBLOCKS (data) == 0) + grub_strcpy (symlink, (char *) INODE (data, symlink)); else { - if (grub_ufs_read_file (data, 0, 0, 0, sz, symlink) < 0) - { - grub_free(symlink); - return grub_errno; - } + 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'; } - symlink[sz] = '\0'; /* The symlink is an absolute path, go back to the root inode. */ if (symlink[0] == '/') @@ -481,14 +411,11 @@ grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino) /* Now load in the old inode. */ if (grub_ufs_read_inode (data, ino, 0)) - { - grub_free (symlink); - return grub_errno; - } + return grub_errno; grub_ufs_find_file (data, symlink); - - grub_free (symlink); + if (grub_errno) + grub_error (grub_errno, "cannot follow symlink `%s'", symlink); return grub_errno; } @@ -499,91 +426,93 @@ grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino) static grub_err_t grub_ufs_find_file (struct grub_ufs_data *data, const char *path) { - const char *name; - const char *next = path; + char fpath[grub_strlen (path) + 1]; + char *name = fpath; + char *next; unsigned int pos = 0; int dirino; - char *filename; - /* We reject filenames longer than the one we're looking - for without reading, so this allocation is enough. */ - filename = grub_malloc (grub_strlen (path) + 2); - if (!filename) - return grub_errno; + grub_strcpy (fpath, path); - while (1) + /* 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; - name = next; - /* Skip the first slash. */ - while (*name == '/') - name++; - if (*name == 0) - { - grub_free (filename); - return GRUB_ERR_NONE; - } + if (grub_strlen (name) == 0) + return GRUB_ERR_NONE; - if ((INODE_MODE(data) & GRUB_UFS_ATTR_TYPE) - != GRUB_UFS_ATTR_DIR) - { - grub_error (GRUB_ERR_BAD_FILE_TYPE, - N_("not a directory")); - goto fail; - } - - /* Extract the actual part from the pathname. */ - for (next = name; *next && *next != '/'; next++); - for (pos = 0; ; pos += grub_ufs_to_cpu16 (dirent.direntlen)) - { - int namelen; - - if (pos >= INODE_SIZE (data)) - { - grub_error (GRUB_ERR_FILE_NOT_FOUND, - N_("file `%s' not found"), - path); - goto fail; - } - - if (grub_ufs_read_file (data, 0, 0, pos, sizeof (dirent), - (char *) &dirent) < 0) - goto fail; + if (grub_ufs_read_file (data, 0, pos, sizeof (dirent), + (char *) &dirent) < 0) + return grub_errno; #ifdef MODE_UFS2 - namelen = dirent.namelen_bsd; + namelen = dirent.namelen_bsd; #else - namelen = grub_ufs_to_cpu16 (dirent.namelen); + namelen = grub_le_to_cpu16 (dirent.namelen); #endif - if (namelen < next - name) + { + 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; + } + } - if (grub_ufs_read_file (data, 0, 0, pos + sizeof (dirent), - next - name + (namelen != next - name), - filename) < 0) - goto fail; + pos += grub_le_to_cpu16 (dirent.direntlen); + } while (pos < INODE_SIZE (data)); - if (grub_strncmp (name, filename, next - name) == 0 - && (namelen == next - name || filename[next - name] == '\0')) - { - dirino = data->ino; - grub_ufs_read_inode (data, grub_ufs_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) - goto fail; - } - - break; - } - } - } - fail: - grub_free (filename); + grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); return grub_errno; } @@ -607,17 +536,8 @@ grub_ufs_mount (grub_disk_t disk) if (grub_errno) goto fail; - /* No need to byteswap bsize in this check. It works the same on both - endiannesses. */ - if (data->sblock.magic == grub_cpu_to_ufs32_compile_time (GRUB_UFS_MAGIC) - && data->sblock.bsize != 0 - && ((data->sblock.bsize & (data->sblock.bsize - 1)) == 0) - && data->sblock.ino_per_group != 0) + if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC) { - for (data->log2_blksz = 0; - (1U << data->log2_blksz) < grub_ufs_to_cpu32 (data->sblock.bsize); - data->log2_blksz++); - data->disk = disk; data->linknest = 0; return data; @@ -644,9 +564,11 @@ grub_ufs_mount (grub_disk_t disk) static grub_err_t grub_ufs_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) + 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); @@ -657,9 +579,11 @@ grub_ufs_dir (grub_device_t device, const char *path, if (grub_errno) return grub_errno; + sblock = &data->sblock; + if (!path || path[0] != '/') { - grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid file name `%s'"), path); + grub_error (GRUB_ERR_BAD_FILENAME, "bad filename"); return grub_errno; } @@ -669,7 +593,7 @@ grub_ufs_dir (grub_device_t device, const char *path, if ((INODE_MODE (data) & GRUB_UFS_ATTR_TYPE) != GRUB_UFS_ATTR_DIR) { - grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); + grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); goto fail; } @@ -678,56 +602,40 @@ grub_ufs_dir (grub_device_t device, const char *path, struct grub_ufs_dirent dirent; int namelen; - if (grub_ufs_read_file (data, 0, 0, pos, sizeof (dirent), + if (grub_ufs_read_file (data, 0, pos, sizeof (dirent), (char *) &dirent) < 0) break; - if (dirent.direntlen == 0) - break; - #ifdef MODE_UFS2 namelen = dirent.namelen_bsd; #else - namelen = grub_ufs_to_cpu16 (dirent.namelen); + namelen = grub_le_to_cpu16 (dirent.namelen); #endif - char *filename = grub_malloc (namelen + 1); - if (!filename) - goto fail; - struct grub_dirhook_info info; - struct grub_ufs_inode inode; + { + char filename[namelen + 1]; + struct grub_dirhook_info info; + struct grub_ufs_inode inode; - grub_memset (&info, 0, sizeof (info)); + grub_memset (&info, 0, sizeof (info)); - if (grub_ufs_read_file (data, 0, 0, pos + sizeof (dirent), - namelen, filename) < 0) - { - grub_free (filename); + if (grub_ufs_read_file (data, 0, pos + sizeof (dirent), + namelen, filename) < 0) break; - } - filename[namelen] = '\0'; - grub_ufs_read_inode (data, grub_ufs_to_cpu32 (dirent.ino), - (char *) &inode); + filename[namelen] = '\0'; + grub_ufs_read_inode (data, dirent.ino, (char *) &inode); - info.dir = ((grub_ufs_to_cpu16 (inode.mode) & GRUB_UFS_ATTR_TYPE) - == GRUB_UFS_ATTR_DIR); -#ifdef MODE_UFS2 - info.mtime = grub_ufs_to_cpu64 (inode.mtime); -#else - info.mtime = grub_ufs_to_cpu32 (inode.mtime); -#endif - info.mtimeset = 1; + 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, hook_data)) - { - grub_free (filename); + if (hook (filename, &info)) break; - } + } - grub_free (filename); - - pos += grub_ufs_to_cpu16 (dirent.direntlen); + pos += grub_le_to_cpu16 (dirent.direntlen); } fail: @@ -755,7 +663,7 @@ grub_ufs_open (struct grub_file *file, const char *name) if (!name || name[0] != '/') { - grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid file name `%s'"), name); + grub_error (GRUB_ERR_BAD_FILENAME, "bad filename"); return grub_errno; } @@ -779,8 +687,7 @@ 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->read_hook_data, - file->offset, len, buf); + return grub_ufs_read_file (data, file->read_hook, file->offset, len, buf); } @@ -792,6 +699,8 @@ grub_ufs_close (grub_file_t file) return GRUB_ERR_NONE; } + +#ifdef MODE_UFS2 static grub_err_t grub_ufs_label (grub_device_t device, char **label) { @@ -811,6 +720,7 @@ grub_ufs_label (grub_device_t device, char **label) return grub_errno; } +#endif static grub_err_t grub_ufs_uuid (grub_device_t device, char **uuid) @@ -823,8 +733,8 @@ grub_ufs_uuid (grub_device_t device, char **uuid) data = grub_ufs_mount (disk); if (data && (data->sblock.uuidhi != 0 || data->sblock.uuidlow != 0)) *uuid = grub_xasprintf ("%08x%08x", - (unsigned) grub_ufs_to_cpu32 (data->sblock.uuidhi), - (unsigned) grub_ufs_to_cpu32 (data->sblock.uuidlow)); + (unsigned) grub_le_to_cpu32 (data->sblock.uuidhi), + (unsigned) grub_le_to_cpu32 (data->sblock.uuidlow)); else *uuid = NULL; @@ -838,7 +748,7 @@ grub_ufs_uuid (grub_device_t device, char **uuid) /* Get mtime. */ static grub_err_t -grub_ufs_mtime (grub_device_t device, grub_int64_t *tm) +grub_ufs_mtime (grub_device_t device, grub_int32_t *tm) { struct grub_ufs_data *data = 0; @@ -848,13 +758,11 @@ grub_ufs_mtime (grub_device_t device, grub_int64_t *tm) if (!data) *tm = 0; else - { - *tm = grub_ufs_to_cpu32 (data->sblock.mtime); #ifdef MODE_UFS2 - if (*tm < (grub_int64_t) grub_ufs_to_cpu64 (data->sblock.mtime2)) - *tm = grub_ufs_to_cpu64 (data->sblock.mtime2); + *tm = grub_le_to_cpu64 (data->sblock.mtime2); +#else + *tm = grub_le_to_cpu32 (data->sblock.mtime); #endif - } grub_dl_unref (my_mod); @@ -869,56 +777,37 @@ static struct grub_fs grub_ufs_fs = { #ifdef MODE_UFS2 .name = "ufs2", -#else -#ifdef MODE_BIGENDIAN - .name = "ufs1_be", #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 - .fs_dir = grub_ufs_dir, - .fs_open = grub_ufs_open, - .fs_read = grub_ufs_read, - .fs_close = grub_ufs_close, - .fs_label = grub_ufs_label, - .fs_uuid = grub_ufs_uuid, - .fs_mtime = grub_ufs_mtime, - /* FIXME: set reserved_first_sector. */ -#ifdef GRUB_UTIL - .blocklist_install = 1, -#endif + .uuid = grub_ufs_uuid, + .mtime = grub_ufs_mtime, .next = 0 }; #ifdef MODE_UFS2 GRUB_MOD_INIT(ufs2) #else -#ifdef MODE_BIGENDIAN -GRUB_MOD_INIT(ufs1_be) -#else GRUB_MOD_INIT(ufs1) #endif -#endif { - if (!grub_is_lockdown ()) - { - grub_ufs_fs.mod = mod; - grub_fs_register (&grub_ufs_fs); - } + grub_fs_register (&grub_ufs_fs); my_mod = mod; } #ifdef MODE_UFS2 GRUB_MOD_FINI(ufs2) #else -#ifdef MODE_BIGENDIAN -GRUB_MOD_FINI(ufs1_be) -#else GRUB_MOD_FINI(ufs1) #endif -#endif { - if (!grub_is_lockdown ()) - grub_fs_unregister (&grub_ufs_fs); + grub_fs_unregister (&grub_ufs_fs); } diff --git a/grub-core/fs/ufs2.c b/fs/ufs2.c similarity index 100% rename from grub-core/fs/ufs2.c rename to fs/ufs2.c diff --git a/fs/xfs.c b/fs/xfs.c new file mode 100644 index 000000000..9dffe31d1 --- /dev/null +++ b/fs/xfs.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#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; + + + +/* 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) + +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; +} + + +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; +} + + + +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 new file mode 100644 index 000000000..ed5965f07 --- /dev/null +++ b/gencmdlist.sh @@ -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/gendistlist.sh b/gendistlist.sh new file mode 100755 index 000000000..102c0c11c --- /dev/null +++ b/gendistlist.sh @@ -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/genfslist.sh b/genfslist.sh new file mode 100644 index 000000000..6fa7e927d --- /dev/null +++ b/genfslist.sh @@ -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/genhandlerlist.sh b/genhandlerlist.sh new file mode 100644 index 000000000..e4cb0d9de --- /dev/null +++ b/genhandlerlist.sh @@ -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/geninit.sh b/geninit.sh index f0810120f..43d2d1640 100644 --- a/geninit.sh +++ b/geninit.sh @@ -11,6 +11,11 @@ # 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 <. */ -#include +#include <$header> EOF -for mod in "$@"; do - echo "extern void grub_${mod}_init (void);" - echo "extern void grub_${mod}_fini (void);" -done - cat </dev/null; then + echo $line | sed -e 's/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/ grub_\1_init ();/' + fi +done < ${lst} cat </dev/null; then + echo $line | sed -e 's/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/ grub_\1_fini ();/' + fi +done < ${lst} cat < /dev/null; then - echo "void grub_${line%%.*}_init (void);" - fi - if ${nm} --defined-only -P -p ${line} | grep grub_mod_fini > /dev/null; then - echo "void grub_${line%%.*}_fini (void);" - fi -done +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 new file mode 100644 index 000000000..c5c63b2d5 --- /dev/null +++ b/genkernsyms.sh.in @@ -0,0 +1,27 @@ +#! /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 new file mode 100644 index 000000000..efea16412 --- /dev/null +++ b/genmk.rb @@ -0,0 +1,461 @@ +#! /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}) -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} + +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 + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ +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 -nu -nd $@.bin $@ + -rm -f $@.bin +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) -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}) -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) -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 rule(sources) + prefix = @name.to_var + 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(' '); + + "CLEANFILES += #{@name} #{objs_str} +MOSTLYCLEANFILES += #{deps_str} + +ifeq ($(#{prefix}_RELOCATABLE),yes) +#{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str} + $(TARGET_CC) -Wl,-r,-d -o $@ #{objs_str} $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) + $(STRIP) --strip-unneeded -K start -R .note -R .comment $@ +else +#{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str} + $(TARGET_CC) -o $@ #{objs_str} $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) + $(STRIP) -R .rel.dyn -R .reginfo -R .note -R .comment $@ +endif + +" + 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}) -MD -c -o $@ $< + +-include #{dep} + +" + 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()} + diff --git a/genmoddep.awk b/genmoddep.awk new file mode 100644 index 000000000..19ac80c71 --- /dev/null +++ b/genmoddep.awk @@ -0,0 +1,62 @@ +#! /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++; + exit; + } +} + +# 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/genemuinit.sh b/genmodsrc.sh similarity index 60% rename from grub-core/genemuinit.sh rename to genmodsrc.sh index 8c6bb1c18..2d420550a 100644 --- a/grub-core/genemuinit.sh +++ b/genmodsrc.sh @@ -1,8 +1,8 @@ #! /bin/sh # -# Copyright (C) 2002,2005,2007 Free Software Foundation, Inc. +# Copyright (C) 2002,2007 Free Software Foundation, Inc. # -# This gensymlist.sh is free software; the author +# 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. # @@ -11,14 +11,16 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -nm="$1" -shift +set -e + +mod_name="$1" +deps="$2" cat <. */ -#include "grub_emu_init.h" +#include EOF -cat < /dev/null; then - echo "grub_${line%%.*}_init ();" - fi +for mod in `grep "^${mod_name}:" ${deps} | sed 's/^[^:]*://'`; do + echo "GRUB_MOD_DEP(${mod});" done - -cat < /dev/null; then - echo "grub_${line%%.*}_fini ();" - fi -done - -cat </dev/null 2>&1; then + echo $module +fi diff --git a/genparttoollist.sh b/genparttoollist.sh new file mode 100644 index 000000000..48a0efe55 --- /dev/null +++ b/genparttoollist.sh @@ -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/gensymlist.sh.in similarity index 76% rename from grub-core/gensymlist.sh rename to gensymlist.sh.in index 5074ef6aa..7cd3b48e3 100644 --- a/grub-core/gensymlist.sh +++ b/gensymlist.sh.in @@ -1,6 +1,6 @@ #! /bin/sh # -# Copyright (C) 2002,2006,2007,2008,2009,2010 Free Software Foundation, Inc. +# 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, @@ -11,11 +11,17 @@ # 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 <. */ -#include <../config-util.h> EOF for i in $*; do @@ -42,33 +47,31 @@ cat < sizeof (tab[0])); for (p = tab; p->name; p++) - grub_dl_register_symbol (p->name, p->addr, p->isfunc, 0); + grub_dl_register_symbol (p->name, p->addr, 0); } EOF diff --git a/genterminallist.sh b/genterminallist.sh new file mode 100644 index 000000000..60f5b9105 --- /dev/null +++ b/genterminallist.sh @@ -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/gentpl.py b/gentpl.py deleted file mode 100644 index d8c6965d8..000000000 --- a/gentpl.py +++ /dev/null @@ -1,915 +0,0 @@ -#! /usr/bin/python -# GRUB -- GRand Unified Bootloader -# Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc. -# -# GRUB is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# GRUB is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GRUB. If not, see . - -from __future__ import print_function - -__metaclass__ = type - -from optparse import OptionParser -import re - -# -# This is the python script used to generate Makefile.*.am -# - -GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", - "i386_multiboot", "i386_ieee1275", "x86_64_efi", - "i386_xen", "x86_64_xen", "i386_xen_pvh", - "mips_loongson", "sparc64_ieee1275", - "powerpc_ieee1275", "mips_arc", "ia64_efi", - "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi", - "arm_coreboot", "loongarch64_efi", "riscv32_efi", "riscv64_efi" ] - -GROUPS = {} - -GROUPS["common"] = GRUB_PLATFORMS[:] - -# Groups based on CPU -GROUPS["i386"] = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275" ] -GROUPS["x86_64"] = [ "x86_64_efi" ] -GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"] -GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ] -GROUPS["sparc64"] = [ "sparc64_ieee1275" ] -GROUPS["powerpc"] = [ "powerpc_ieee1275" ] -GROUPS["arm"] = [ "arm_uboot", "arm_efi", "arm_coreboot" ] -GROUPS["arm64"] = [ "arm64_efi" ] -GROUPS["loongarch64"] = [ "loongarch64_efi" ] -GROUPS["riscv32"] = [ "riscv32_efi" ] -GROUPS["riscv64"] = [ "riscv64_efi" ] - -# Groups based on firmware -GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi", - "loongarch64_efi", "riscv32_efi", "riscv64_efi" ] -GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ] -GROUPS["uboot"] = [ "arm_uboot" ] -GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ] -GROUPS["coreboot"] = [ "i386_coreboot", "arm_coreboot" ] - -# emu is a special case so many core functionality isn't needed on this platform -GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu") - -# Groups based on hardware features -GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_loongson", "mips_qemu_mips", - "sparc64_ieee1275", "powerpc_ieee1275"] -GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi"); -GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"] -GROUPS["usb"] = GROUPS["pci"] + ["arm_coreboot"] - -# If gfxterm is main output console integrate it into kernel -GROUPS["videoinkernel"] = ["mips_loongson", "i386_coreboot", "arm_coreboot" ] -GROUPS["videomodules"] = GRUB_PLATFORMS[:]; -for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i) - -# Similar for terminfo -GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips", "i386_xen_pvh" ] + GROUPS["xen"] + GROUPS["ieee1275"] + GROUPS["uboot"]; -GROUPS["terminfomodule"] = GRUB_PLATFORMS[:]; -for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i) - -# Flattened Device Trees (FDT) -GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "loongarch64_efi", "riscv32_efi", "riscv64_efi" ] - -# Needs software helpers for division -# Must match GRUB_DIVISION_IN_SOFTWARE in misc.h -GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"] + GROUPS["riscv32"] -GROUPS["no_softdiv"] = GRUB_PLATFORMS[:] -for i in GROUPS["softdiv"]: GROUPS["no_softdiv"].remove(i) - -# Miscellaneous groups scheduled to disappear in future -GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"] -GROUPS["nopc"] = GRUB_PLATFORMS[:]; GROUPS["nopc"].remove("i386_pc") - -# -# 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 - -# -# Input -# - -# We support a subset of the AutoGen definitions file syntax. Specifically, -# compound names are disallowed; some preprocessing directives are -# disallowed (though #if/#endif are allowed; note that, like AutoGen, #if -# skips everything to the next #endif regardless of the value of the -# conditional); and shell-generated strings, Scheme-generated strings, and -# here strings are disallowed. - -class AutogenToken: - (autogen, definitions, eof, var_name, other_name, string, number, - semicolon, equals, comma, lbrace, rbrace, lbracket, rbracket) = range(14) - -class AutogenState: - (init, need_def, need_tpl, need_semi, need_name, have_name, need_value, - need_idx, need_rbracket, indx_name, have_value, done) = range(12) - -class AutogenParseError(Exception): - def __init__(self, message, path, line): - super(AutogenParseError, self).__init__(message) - self.path = path - self.line = line - - def __str__(self): - return ( - super(AutogenParseError, self).__str__() + - " at file %s line %d" % (self.path, self.line)) - -class AutogenDefinition(list): - def __getitem__(self, key): - try: - return super(AutogenDefinition, self).__getitem__(key) - except TypeError: - for name, value in self: - if name == key: - return value - - def __contains__(self, key): - for name, value in self: - if name == key: - return True - return False - - def get(self, key, default): - for name, value in self: - if name == key: - return value - else: - return default - - def find_all(self, key): - for name, value in self: - if name == key: - yield value - -class AutogenParser: - def __init__(self): - self.definitions = AutogenDefinition() - self.def_stack = [("", self.definitions)] - self.curdef = None - self.new_name = None - self.cur_path = None - self.cur_line = 0 - - @staticmethod - def is_unquotable_char(c): - return (ord(c) in range(ord("!"), ord("~") + 1) and - c not in "#,;<=>[\\]`{}?*'\"()") - - @staticmethod - def is_value_name_char(c): - return c in ":^-_" or c.isalnum() - - def error(self, message): - raise AutogenParseError(message, self.cur_file, self.cur_line) - - def read_tokens(self, f): - data = f.read() - end = len(data) - offset = 0 - while offset < end: - while offset < end and data[offset].isspace(): - if data[offset] == "\n": - self.cur_line += 1 - offset += 1 - if offset >= end: - break - c = data[offset] - if c == "#": - offset += 1 - try: - end_directive = data.index("\n", offset) - directive = data[offset:end_directive] - offset = end_directive - except ValueError: - directive = data[offset:] - offset = end - name, value = directive.split(None, 1) - if name == "if": - try: - end_if = data.index("\n#endif", offset) - new_offset = end_if + len("\n#endif") - self.cur_line += data[offset:new_offset].count("\n") - offset = new_offset - except ValueError: - self.error("#if without matching #endif") - else: - self.error("Unhandled directive '#%s'" % name) - elif c == "{": - yield AutogenToken.lbrace, c - offset += 1 - elif c == "=": - yield AutogenToken.equals, c - offset += 1 - elif c == "}": - yield AutogenToken.rbrace, c - offset += 1 - elif c == "[": - yield AutogenToken.lbracket, c - offset += 1 - elif c == "]": - yield AutogenToken.rbracket, c - offset += 1 - elif c == ";": - yield AutogenToken.semicolon, c - offset += 1 - elif c == ",": - yield AutogenToken.comma, c - offset += 1 - elif c in ("'", '"'): - s = [] - while True: - offset += 1 - if offset >= end: - self.error("EOF in quoted string") - if data[offset] == "\n": - self.cur_line += 1 - if data[offset] == "\\": - offset += 1 - if offset >= end: - self.error("EOF in quoted string") - if data[offset] == "\n": - self.cur_line += 1 - # Proper escaping unimplemented; this can be filled - # out if needed. - s.append("\\") - s.append(data[offset]) - elif data[offset] == c: - offset += 1 - break - else: - s.append(data[offset]) - yield AutogenToken.string, "".join(s) - elif c == "/": - offset += 1 - if data[offset] == "*": - offset += 1 - try: - end_comment = data.index("*/", offset) - new_offset = end_comment + len("*/") - self.cur_line += data[offset:new_offset].count("\n") - offset = new_offset - except ValueError: - self.error("/* without matching */") - elif data[offset] == "/": - try: - offset = data.index("\n", offset) - except ValueError: - pass - elif (c.isdigit() or - (c == "-" and offset < end - 1 and - data[offset + 1].isdigit())): - end_number = offset + 1 - while end_number < end and data[end_number].isdigit(): - end_number += 1 - yield AutogenToken.number, data[offset:end_number] - offset = end_number - elif self.is_unquotable_char(c): - end_name = offset - while (end_name < end and - self.is_value_name_char(data[end_name])): - end_name += 1 - if end_name < end and self.is_unquotable_char(data[end_name]): - while (end_name < end and - self.is_unquotable_char(data[end_name])): - end_name += 1 - yield AutogenToken.other_name, data[offset:end_name] - offset = end_name - else: - s = data[offset:end_name] - if s.lower() == "autogen": - yield AutogenToken.autogen, s - elif s.lower() == "definitions": - yield AutogenToken.definitions, s - else: - yield AutogenToken.var_name, s - offset = end_name - else: - self.error("Invalid input character '%s'" % c) - yield AutogenToken.eof, None - - def do_need_name_end(self, token): - if len(self.def_stack) > 1: - self.error("Definition blocks were left open") - - def do_need_name_var_name(self, token): - self.new_name = token - - def do_end_block(self, token): - if len(self.def_stack) <= 1: - self.error("Too many close braces") - new_name, parent_def = self.def_stack.pop() - parent_def.append((new_name, self.curdef)) - self.curdef = parent_def - - def do_empty_val(self, token): - self.curdef.append((self.new_name, "")) - - def do_str_value(self, token): - self.curdef.append((self.new_name, token)) - - def do_start_block(self, token): - self.def_stack.append((self.new_name, self.curdef)) - self.curdef = AutogenDefinition() - - def do_indexed_name(self, token): - self.new_name = token - - def read_definitions_file(self, f): - self.curdef = self.definitions - self.cur_line = 0 - state = AutogenState.init - - # The following transition table was reduced from the Autogen - # documentation: - # info -f autogen -n 'Full Syntax' - transitions = { - AutogenState.init: { - AutogenToken.autogen: (AutogenState.need_def, None), - }, - AutogenState.need_def: { - AutogenToken.definitions: (AutogenState.need_tpl, None), - }, - AutogenState.need_tpl: { - AutogenToken.var_name: (AutogenState.need_semi, None), - AutogenToken.other_name: (AutogenState.need_semi, None), - AutogenToken.string: (AutogenState.need_semi, None), - }, - AutogenState.need_semi: { - AutogenToken.semicolon: (AutogenState.need_name, None), - }, - AutogenState.need_name: { - AutogenToken.autogen: (AutogenState.need_def, None), - AutogenToken.eof: (AutogenState.done, self.do_need_name_end), - AutogenToken.var_name: ( - AutogenState.have_name, self.do_need_name_var_name), - AutogenToken.rbrace: ( - AutogenState.have_value, self.do_end_block), - }, - AutogenState.have_name: { - AutogenToken.semicolon: ( - AutogenState.need_name, self.do_empty_val), - AutogenToken.equals: (AutogenState.need_value, None), - AutogenToken.lbracket: (AutogenState.need_idx, None), - }, - AutogenState.need_value: { - AutogenToken.var_name: ( - AutogenState.have_value, self.do_str_value), - AutogenToken.other_name: ( - AutogenState.have_value, self.do_str_value), - AutogenToken.string: ( - AutogenState.have_value, self.do_str_value), - AutogenToken.number: ( - AutogenState.have_value, self.do_str_value), - AutogenToken.lbrace: ( - AutogenState.need_name, self.do_start_block), - }, - AutogenState.need_idx: { - AutogenToken.var_name: ( - AutogenState.need_rbracket, self.do_indexed_name), - AutogenToken.number: ( - AutogenState.need_rbracket, self.do_indexed_name), - }, - AutogenState.need_rbracket: { - AutogenToken.rbracket: (AutogenState.indx_name, None), - }, - AutogenState.indx_name: { - AutogenToken.semicolon: ( - AutogenState.need_name, self.do_empty_val), - AutogenToken.equals: (AutogenState.need_value, None), - }, - AutogenState.have_value: { - AutogenToken.semicolon: (AutogenState.need_name, None), - AutogenToken.comma: (AutogenState.need_value, None), - }, - } - - for code, token in self.read_tokens(f): - if code in transitions[state]: - state, handler = transitions[state][code] - if handler is not None: - handler(token) - else: - self.error( - "Parse error in state %s: unexpected token '%s'" % ( - state, token)) - if state == AutogenState.done: - break - - def read_definitions(self, path): - self.cur_file = path - with open(path) as f: - self.read_definitions_file(f) - -defparser = AutogenParser() - -# -# Output -# - -outputs = {} - -def output(s, section=''): - if s == "": - return - outputs.setdefault(section, []) - outputs[section].append(s) - -def write_output(section=''): - for s in outputs.get(section, []): - print(s, end='') - -# -# Global variables -# - -def gvar_add(var, value): - output(var + " += " + value + "\n") - -# -# Per PROGRAM/SCRIPT variables -# - -seen_vars = set() - -def vars_init(defn, *var_list): - name = defn['name'] - - if name not in seen_target and name not in seen_vars: - for var in var_list: - output(var + " = \n", section='decl') - seen_vars.add(name) - -def var_set(var, value): - output(var + " = " + value + "\n") - -def var_add(var, value): - output(var + " += " + value + "\n") - -# -# Variable names and rules -# - -canonical_name_re = re.compile(r'[^0-9A-Za-z@_]') -canonical_name_suffix = "" - -def set_canonical_name_suffix(suffix): - global canonical_name_suffix - canonical_name_suffix = suffix - -def cname(defn): - return canonical_name_re.sub('_', defn['name'] + canonical_name_suffix) - -def rule(target, source, cmd): - if cmd[0] == "\n": - output("\n" + target + ": " + source + cmd.replace("\n", "\n\t") + "\n") - else: - output("\n" + target + ": " + source + "\n\t" + cmd.replace("\n", "\n\t") + "\n") - -# -# Handle keys with platform names as values, for example: -# -# kernel = { -# nostrip = emu; -# ... -# } -# -def platform_tagged(defn, platform, tag): - for value in defn.find_all(tag): - for group in RMAP[platform]: - if value == group: - return True - return False - -def if_platform_tagged(defn, platform, tag, snippet_if, snippet_else=None): - if platform_tagged(defn, platform, tag): - return snippet_if - elif snippet_else is not None: - return snippet_else - -# -# Handle tagged values -# -# module = { -# extra_dist = ... -# extra_dist = ... -# ... -# }; -# -def foreach_value(defn, tag, closure): - r = [] - for value in defn.find_all(tag): - r.append(closure(value)) - return ''.join(r) - -# -# Handle best matched values for a platform, for example: -# -# module = { -# cflags = '-Wall'; -# emu_cflags = '-Wall -DGRUB_EMU=1'; -# ... -# } -# -def foreach_platform_specific_value(defn, platform, suffix, nonetag, closure): - r = [] - for group in RMAP[platform]: - values = list(defn.find_all(group + suffix)) - if values: - for value in values: - r.append(closure(value)) - break - else: - for value in defn.find_all(nonetag): - r.append(closure(value)) - return ''.join(r) - -# -# Handle values from sum of all groups for a platform, for example: -# -# module = { -# common = kern/misc.c; -# emu = kern/emu/misc.c; -# ... -# } -# -def foreach_platform_value(defn, platform, suffix, closure): - r = [] - for group in RMAP[platform]: - for value in defn.find_all(group + suffix): - r.append(closure(value)) - r.sort() - return ''.join(r) - -def platform_conditional(platform, closure): - output("\nif COND_" + platform + "\n") - closure(platform) - output("endif\n") - -# -# Handle guarding with platform-specific "enable" keys, for example: -# -# module = { -# name = pci; -# noemu = bus/pci.c; -# emu = bus/emu/pci.c; -# emu = commands/lspci.c; -# -# enable = emu; -# enable = i386_pc; -# enable = x86_efi; -# enable = i386_ieee1275; -# enable = i386_coreboot; -# }; -# -def foreach_enabled_platform(defn, closure): - if 'enable' in defn: - for platform in GRUB_PLATFORMS: - if platform_tagged(defn, platform, "enable"): - platform_conditional(platform, closure) - else: - for platform in GRUB_PLATFORMS: - platform_conditional(platform, closure) - -# -# Handle guarding with platform-specific automake conditionals, for example: -# -# module = { -# name = usb; -# common = bus/usb/usb.c; -# noemu = bus/usb/usbtrans.c; -# noemu = bus/usb/usbhub.c; -# enable = emu; -# enable = i386; -# enable = mips_loongson; -# emu_condition = COND_GRUB_EMU_SDL; -# }; -# -def under_platform_specific_conditionals(defn, platform, closure): - output(foreach_platform_specific_value(defn, platform, "_condition", "condition", lambda cond: "if " + cond + "\n")) - closure(defn, platform) - output(foreach_platform_specific_value(defn, platform, "_condition", "condition", lambda cond: "endif " + cond + "\n")) - -def platform_specific_values(defn, platform, suffix, nonetag): - return foreach_platform_specific_value(defn, platform, suffix, nonetag, - lambda value: value + " ") - -def platform_values(defn, platform, suffix): - return foreach_platform_value(defn, platform, suffix, lambda value: value + " ") - -def extra_dist(defn): - return foreach_value(defn, "extra_dist", lambda value: value + " ") - -def extra_dep(defn): - return foreach_value(defn, "depends", lambda value: value + " ") - -def platform_sources(defn, p): return platform_values(defn, p, "_head") + platform_values(defn, p, "") -def platform_nodist_sources(defn, p): return platform_values(defn, p, "_nodist") - -def platform_startup(defn, p): return platform_specific_values(defn, p, "_startup", "startup") -def platform_ldadd(defn, p): return platform_specific_values(defn, p, "_ldadd", "ldadd") -def platform_dependencies(defn, p): return platform_specific_values(defn, p, "_dependencies", "dependencies") -def platform_cflags(defn, p): return platform_specific_values(defn, p, "_cflags", "cflags") -def platform_ldflags(defn, p): return platform_specific_values(defn, p, "_ldflags", "ldflags") -def platform_cppflags(defn, p): return platform_specific_values(defn, p, "_cppflags", "cppflags") -def platform_ccasflags(defn, p): return platform_specific_values(defn, p, "_ccasflags", "ccasflags") -def platform_stripflags(defn, p): return platform_specific_values(defn, p, "_stripflags", "stripflags") -def platform_objcopyflags(defn, p): return platform_specific_values(defn, p, "_objcopyflags", "objcopyflags") - -# -# Emit snippet only the first time through for the current name. -# -seen_target = set() - -def first_time(defn, snippet): - if defn['name'] not in seen_target: - return snippet - return '' - -def is_platform_independent(defn): - if 'enable' in defn: - return False - for suffix in [ "", "_head", "_nodist" ]: - template = platform_values(defn, GRUB_PLATFORMS[0], suffix) - for platform in GRUB_PLATFORMS[1:]: - if template != platform_values(defn, platform, suffix): - return False - - for suffix in [ "startup", "ldadd", "dependencies", "cflags", "ldflags", "cppflags", "ccasflags", "stripflags", "objcopyflags", "condition" ]: - template = platform_specific_values(defn, GRUB_PLATFORMS[0], "_" + suffix, suffix) - for platform in GRUB_PLATFORMS[1:]: - if template != platform_specific_values(defn, platform, "_" + suffix, suffix): - return False - for tag in [ "nostrip" ]: - template = platform_tagged(defn, GRUB_PLATFORMS[0], tag) - for platform in GRUB_PLATFORMS[1:]: - if template != platform_tagged(defn, platform, tag): - return False - - return True - -def module(defn, platform): - name = defn['name'] - set_canonical_name_suffix(".module") - - gvar_add("platform_PROGRAMS", name + ".module") - gvar_add("MODULE_FILES", name + ".module$(EXEEXT)") - - var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform) + " ## platform sources") - var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + " ## platform nodist sources") - var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) - var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_MODULE) " + platform_cflags(defn, platform)) - var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_MODULE) " + platform_ldflags(defn, platform)) - var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_MODULE) " + platform_cppflags(defn, platform)) - var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_MODULE) " + platform_ccasflags(defn, platform)) - var_set(cname(defn) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF) " + platform_dependencies(defn, platform)) - - gvar_add("dist_noinst_DATA", extra_dist(defn)) - gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") - gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") - - gvar_add("MOD_FILES", name + ".mod") - gvar_add("MARKER_FILES", name + ".marker") - gvar_add("CLEANFILES", name + ".marker") - - for dep in defn.find_all("depends"): - gvar_add("EXTRA_DEPS", "depends " + name + " " + dep + ":") - - output(""" -""" + name + """.marker: $(""" + cname(defn) + """_SOURCES) $(nodist_""" + cname(defn) + """_SOURCES) - $(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname(defn) + """_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1) - grep 'MARKER' $@.new | grep -v '^#' > $@; rm -f $@.new -""") - -def kernel(defn, platform): - name = defn['name'] - set_canonical_name_suffix(".exec") - gvar_add("platform_PROGRAMS", name + ".exec") - var_set(cname(defn) + "_SOURCES", platform_startup(defn, platform)) - var_add(cname(defn) + "_SOURCES", platform_sources(defn, platform)) - var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + " ## platform nodist sources") - var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) - var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_KERNEL) " + platform_cflags(defn, platform)) - var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_KERNEL) " + platform_ldflags(defn, platform)) - var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) " + platform_cppflags(defn, platform)) - var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_KERNEL) " + platform_ccasflags(defn, platform)) - var_set(cname(defn) + "_STRIPFLAGS", "$(AM_STRIPFLAGS) $(STRIPFLAGS_KERNEL) " + platform_stripflags(defn, platform)) - var_set(cname(defn) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF)") - - gvar_add("dist_noinst_DATA", extra_dist(defn)) - gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") - gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") - - gvar_add("platform_DATA", name + ".img") - gvar_add("CLEANFILES", name + ".img") - rule(name + ".img", name + ".exec$(EXEEXT)", - if_platform_tagged(defn, platform, "nostrip", -"""if test x$(TARGET_APPLE_LINKER) = x1; then \ - $(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -wd1106 -nu -nd $< $@; \ - elif test ! -z '$(TARGET_OBJ2ELF)'; then \ - $(TARGET_OBJ2ELF) $< $@ || (rm -f $@; exit 1); \ - else cp $< $@; fi""", -"""if test x$(TARGET_APPLE_LINKER) = x1; then \ - $(TARGET_STRIP) -S -x $(""" + cname(defn) + """) -o $@.bin $<; \ - $(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -ed2016 -wd1106 -nu -nd $@.bin $@; \ - rm -f $@.bin; \ - elif test ! -z '$(TARGET_OBJ2ELF)'; then \ - """ + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@.bin $< && \ - $(TARGET_OBJ2ELF) $@.bin $@ || (rm -f $@; rm -f $@.bin; exit 1); \ - rm -f $@.bin; \ -else """ + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@ $<; \ -fi""")) - -def image(defn, platform): - name = defn['name'] - set_canonical_name_suffix(".image") - gvar_add("platform_PROGRAMS", name + ".image") - var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform)) - var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + "## platform nodist sources") - var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) - var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_IMAGE) " + platform_cflags(defn, platform)) - var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_IMAGE) " + platform_ldflags(defn, platform)) - var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_IMAGE) " + platform_cppflags(defn, platform)) - var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_IMAGE) " + platform_ccasflags(defn, platform)) - var_set(cname(defn) + "_OBJCOPYFLAGS", "$(OBJCOPYFLAGS_IMAGE) " + platform_objcopyflags(defn, platform)) - # var_set(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform)) - - gvar_add("dist_noinst_DATA", extra_dist(defn)) - gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") - gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") - - gvar_add("platform_DATA", name + ".img") - gvar_add("CLEANFILES", name + ".img") - rule(name + ".img", name + ".image$(EXEEXT)", """ -if test x$(TARGET_APPLE_LINKER) = x1; then \ - $(MACHO2IMG) $< $@; \ -else \ - $(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .note.gnu.property -R .ARM.exidx -R .interp $< $@; \ -fi -""") - -def library(defn, platform): - name = defn['name'] - set_canonical_name_suffix("") - - vars_init(defn, - cname(defn) + "_SOURCES", - "nodist_" + cname(defn) + "_SOURCES", - cname(defn) + "_CFLAGS", - cname(defn) + "_CPPFLAGS", - cname(defn) + "_CCASFLAGS") - # cname(defn) + "_DEPENDENCIES") - - if name not in seen_target: - gvar_add("noinst_LIBRARIES", name) - var_add(cname(defn) + "_SOURCES", platform_sources(defn, platform)) - var_add("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform)) - var_add(cname(defn) + "_CFLAGS", first_time(defn, "$(AM_CFLAGS) $(CFLAGS_LIBRARY) ") + platform_cflags(defn, platform)) - var_add(cname(defn) + "_CPPFLAGS", first_time(defn, "$(AM_CPPFLAGS) $(CPPFLAGS_LIBRARY) ") + platform_cppflags(defn, platform)) - var_add(cname(defn) + "_CCASFLAGS", first_time(defn, "$(AM_CCASFLAGS) $(CCASFLAGS_LIBRARY) ") + platform_ccasflags(defn, platform)) - # var_add(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform)) - - gvar_add("dist_noinst_DATA", extra_dist(defn)) - if name not in seen_target: - gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") - gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") - -def installdir(defn, default="bin"): - return defn.get('installdir', default) - -def manpage(defn, adddeps): - name = defn['name'] - mansection = defn['mansection'] - - output("if COND_MAN_PAGES\n") - gvar_add("man_MANS", name + "." + mansection) - rule(name + "." + mansection, name + " " + adddeps, """ -chmod a+x """ + name + """ -PATH=$(builddir):$$PATH pkgdatadir=$(builddir) $(HELP2MAN) --section=""" + mansection + """ -i $(top_srcdir)/docs/man/""" + name + """.h2m -o $@ """ + name + """ -""") - gvar_add("CLEANFILES", name + "." + mansection) - output("endif\n") - -def program(defn, platform, test=False): - name = defn['name'] - set_canonical_name_suffix("") - - if 'testcase' in defn: - gvar_add("check_PROGRAMS_" + defn['testcase'], name) - else: - var_add(installdir(defn) + "_PROGRAMS", name) - if 'mansection' in defn: - manpage(defn, "") - - var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform)) - var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform)) - var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) - var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_PROGRAM) " + platform_cflags(defn, platform)) - var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_PROGRAM) " + platform_ldflags(defn, platform)) - var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_PROGRAM) " + platform_cppflags(defn, platform)) - var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_PROGRAM) " + platform_ccasflags(defn, platform)) - # var_set(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform)) - - gvar_add("dist_noinst_DATA", extra_dist(defn)) - gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") - gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") - -def data(defn, platform): - var_add("dist_" + installdir(defn) + "_DATA", platform_sources(defn, platform)) - gvar_add("dist_noinst_DATA", extra_dist(defn)) - -def transform_data(defn, platform): - name = defn['name'] - - var_add(installdir(defn) + "_DATA", name) - - rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """ -(for x in """ + platform_sources(defn, platform) + """; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:- -chmod a+x """ + name + """ -""") - - gvar_add("CLEANFILES", name) - gvar_add("EXTRA_DIST", extra_dist(defn)) - gvar_add("dist_noinst_DATA", platform_sources(defn, platform)) - -def script(defn, platform): - name = defn['name'] - - if 'testcase' in defn: - gvar_add("check_SCRIPTS_" + defn['testcase'], name) - else: - var_add(installdir(defn) + "_SCRIPTS", name) - if 'mansection' in defn: - manpage(defn, "grub-mkconfig_lib") - - rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """ -(for x in """ + platform_sources(defn, platform) + """; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:- -chmod a+x """ + name + """ -""") - - gvar_add("CLEANFILES", name) - gvar_add("EXTRA_DIST", extra_dist(defn)) - gvar_add("dist_noinst_DATA", platform_sources(defn, platform)) - -def rules(target, closure): - seen_target.clear() - seen_vars.clear() - - for defn in defparser.definitions.find_all(target): - if is_platform_independent(defn): - under_platform_specific_conditionals(defn, GRUB_PLATFORMS[0], closure) - else: - foreach_enabled_platform( - defn, - lambda p: under_platform_specific_conditionals(defn, p, closure)) - # Remember that we've seen this target. - seen_target.add(defn['name']) - -parser = OptionParser(usage="%prog DEFINITION-FILES") -_, args = parser.parse_args() - -for arg in args: - defparser.read_definitions(arg) - -rules("module", module) -rules("kernel", kernel) -rules("image", image) -rules("library", library) -rules("program", program) -rules("script", script) -rules("data", data) -rules("transform_data", transform_data) - -write_output(section='decl') -write_output() diff --git a/grub-core/gentrigtables.c b/gentrigtables.c similarity index 70% rename from grub-core/gentrigtables.c rename to gentrigtables.c index fface6efc..772cd6224 100644 --- a/grub-core/gentrigtables.c +++ b/gentrigtables.c @@ -24,23 +24,14 @@ #include int -main (int argc __attribute__ ((unused)), - char **argv __attribute__ ((unused))) +main () { int i; printf ("#include \n"); - printf ("#include \n"); - printf ("\n"); - - printf ("/* Under copyright legislature such automated output isn't\n"); - printf ("covered by any copyright. Hence it's public domain. Public\n"); - printf ("domain works can be dual-licenced with any license. */\n"); - printf ("GRUB_MOD_LICENSE (\"GPLv3+\");"); - printf ("GRUB_MOD_DUAL_LICENSE (\"Public Domain\");"); #define TAB(op) \ - printf ("const grub_int16_t grub_trig_" #op "tab[] =\n{"); \ + 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; \ diff --git a/genvideolist.sh b/genvideolist.sh new file mode 100644 index 000000000..b208fa25c --- /dev/null +++ b/genvideolist.sh @@ -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/gettext/gettext.c b/gettext/gettext.c new file mode 100644 index 000000000..0aa8decbd --- /dev/null +++ b/gettext/gettext.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + .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/gfxmenu/gfxmenu.c similarity index 74% rename from grub-core/gfxmenu/gfxmenu.c rename to gfxmenu/gfxmenu.c index 72b39f90f..a2e765156 100644 --- a/grub-core/gfxmenu/gfxmenu.c +++ b/gfxmenu/gfxmenu.c @@ -36,13 +36,10 @@ #include #include #include -#include -GRUB_MOD_LICENSE ("GPLv3+"); +grub_gfxmenu_view_t cached_view; -static grub_gfxmenu_view_t cached_view; - -static void +static void grub_gfxmenu_viewer_fini (void *data __attribute__ ((unused))) { } @@ -53,49 +50,53 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) { grub_gfxmenu_view_t view = NULL; const char *theme_path; - char *full_theme_path = 0; 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) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), - "theme"); - - err = grub_video_get_info (&mode_info); - if (err) - return err; + { + 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) - return grub_errno; - - if (theme_path[0] != '/' && theme_path[0] != '(') { - const char *prefix; - prefix = grub_env_get ("prefix"); - full_theme_path = grub_xasprintf ("%s/themes/%s", - prefix, - theme_path); + grub_error_push (); + grub_gfxterm_fullscreen (); + grub_error_pop (); + return grub_errno; } - if (!cached_view || grub_strcmp (cached_view->theme_path, - full_theme_path ? : theme_path) != 0 + 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_gfxmenu_view_destroy (cached_view); + grub_free (cached_view); /* Create the view. */ - cached_view = grub_gfxmenu_view_new (full_theme_path ? : theme_path, - mode_info.width, + cached_view = grub_gfxmenu_view_new (theme_path, mode_info.width, mode_info.height); } - grub_free (full_theme_path); if (! cached_view) { grub_free (instance); + grub_error_push (); + grub_gfxterm_fullscreen (); + grub_error_pop (); return grub_errno; } @@ -109,13 +110,6 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) view->nested = nested; view->first_timeout = -1; - grub_video_set_viewport (0, 0, mode_info.width, mode_info.height); - if (view->double_repaint) - { - grub_video_swap_buffers (); - grub_video_set_viewport (0, 0, mode_info.width, mode_info.height); - } - grub_gfxmenu_view_draw (view); instance->data = view; @@ -134,9 +128,9 @@ GRUB_MOD_INIT (gfxmenu) struct grub_term_output *term; FOR_ACTIVE_TERM_OUTPUTS(term) - if (grub_gfxmenu_try_hook && term->fullscreen) + if (grub_gfxmenu_try_hook && grub_strcmp (term->name, "gfxterm") == 0) { - term->fullscreen (); + grub_gfxterm_fullscreen (); break; } diff --git a/grub-core/gfxmenu/gui_box.c b/gfxmenu/gui_box.c similarity index 95% rename from grub-core/gfxmenu/gui_box.c rename to gfxmenu/gui_box.c index 37bab3fbb..38b15f96d 100644 --- a/grub-core/gfxmenu/gui_box.c +++ b/gfxmenu/gui_box.c @@ -234,30 +234,14 @@ 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_video_area_status_t box_area_status; - grub_video_get_area_status (&box_area_status); - 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; - grub_video_rect_t r; - comp->ops->get_bounds(comp, &r); - - if (!grub_video_have_common_points (region, &r)) - continue; - - /* Paint the child. */ - if (box_area_status == GRUB_VIDEO_AREA_ENABLED - && grub_video_bounds_inside_region (&r, region)) - grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED); comp->ops->paint (comp, region); - if (box_area_status == GRUB_VIDEO_AREA_ENABLED) - grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED); } grub_gui_restore_viewport (&vpsave); } diff --git a/grub-core/gfxmenu/gui_canvas.c b/gfxmenu/gui_canvas.c similarity index 92% rename from grub-core/gfxmenu/gui_canvas.c rename to gfxmenu/gui_canvas.c index a05491242..b3919c2d3 100644 --- a/grub-core/gfxmenu/gui_canvas.c +++ b/gfxmenu/gui_canvas.c @@ -80,13 +80,9 @@ 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_video_area_status_t canvas_area_status; - grub_video_get_area_status (&canvas_area_status); - grub_gui_set_viewport (&self->bounds, &vpsave); for (cur = self->components.next; cur; cur = cur->next) { @@ -139,16 +135,9 @@ canvas_paint (void *vself, const grub_video_rect_t *region) r.height = h; comp->ops->set_bounds (comp, &r); - if (!grub_video_have_common_points (region, &r)) - continue; - /* Paint the child. */ - if (canvas_area_status == GRUB_VIDEO_AREA_ENABLED - && grub_video_bounds_inside_region (&r, region)) - grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED); - comp->ops->paint (comp, region); - if (canvas_area_status == GRUB_VIDEO_AREA_ENABLED) - grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED); + if (grub_video_have_common_points (region, &r)) + comp->ops->paint (comp, region); } grub_gui_restore_viewport (&vpsave); } diff --git a/grub-core/gfxmenu/gui_circular_progress.c b/gfxmenu/gui_circular_progress.c similarity index 74% rename from grub-core/gfxmenu/gui_circular_progress.c rename to gfxmenu/gui_circular_progress.c index db1edb8f4..9a859ee2e 100644 --- a/grub-core/gfxmenu/gui_circular_progress.c +++ b/gfxmenu/gui_circular_progress.c @@ -37,7 +37,7 @@ struct grub_gui_circular_progress int start; int end; int value; - unsigned num_ticks; + int num_ticks; int start_angle; int ticks_disappear; char *theme_dir; @@ -54,7 +54,6 @@ static void circprog_destroy (void *vself) { circular_progress_t self = vself; - grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self); } @@ -138,53 +137,49 @@ circprog_paint (void *vself, const grub_video_rect_t *region) (height - center_height) / 2, 0, 0, center_width, center_height); - if (self->num_ticks) + 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) { - int radius = grub_min (height, width) / 2 - grub_max (tick_height, tick_width) / 2 - 1; - unsigned nticks; - unsigned tick_begin; - unsigned tick_end; - if (self->end <= self->start - || self->value <= self->start) - nticks = 0; - else - nticks = ((unsigned) (self->num_ticks - * (self->value - self->start))) - / ((unsigned) (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; - } - else - { - tick_begin = 0; - tick_end = nticks; - } - - unsigned 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); - } + 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); } @@ -216,47 +211,17 @@ circprog_get_bounds (void *vself, grub_video_rect_t *bounds) *bounds = self->bounds; } -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 int -parse_angle (const char *value) -{ - const char *ptr; - int angle; - - angle = grub_strtol (value, &ptr, 10); - if (grub_errno) - return 0; - while (grub_isspace (*ptr)) - ptr++; - if (grub_strcmp (ptr, "deg") == 0 - /* Unicode symbol of degrees (a circle, U+b0). Put here in UTF-8 to - avoid potential problem with text file reesncoding */ - || grub_strcmp (ptr, "\xc2\xb0") == 0) - angle = grub_divide_round (angle * 64, 90); - return angle; -} - 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_strtoul (value, 0, 10); + self->num_ticks = grub_strtol (value, 0, 10); } else if (grub_strcmp (name, "start_angle") == 0) { - self->start_angle = parse_angle (value); + self->start_angle = grub_strtol (value, 0, 10); } else if (grub_strcmp (name, "ticks_disappear") == 0) { @@ -282,20 +247,26 @@ circprog_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "id") == 0) { - grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->id); if (value) self->id = grub_strdup (value); else self->id = 0; - if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID) - == 0) - grub_gfxmenu_timeout_register ((grub_gui_component_t) self, - circprog_set_state); } 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, diff --git a/grub-core/gfxmenu/gui_image.c b/gfxmenu/gui_image.c similarity index 89% rename from grub-core/gfxmenu/gui_image.c rename to gfxmenu/gui_image.c index eed4b6b87..3988f4ba8 100644 --- a/grub-core/gfxmenu/gui_image.c +++ b/gfxmenu/gui_image.c @@ -101,9 +101,6 @@ image_get_parent (void *vself) static grub_err_t rescale_image (grub_gui_image_t self) { - signed width; - signed height; - if (! self->raw_bitmap) { if (self->bitmap) @@ -114,12 +111,12 @@ rescale_image (grub_gui_image_t self) return grub_errno; } - width = self->bounds.width; - height = self->bounds.height; + unsigned width = self->bounds.width; + unsigned height = self->bounds.height; if (self->bitmap - && ((signed) grub_video_bitmap_get_width (self->bitmap) == width) - && ((signed) grub_video_bitmap_get_height (self->bitmap) == height)) + && (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; @@ -134,15 +131,15 @@ rescale_image (grub_gui_image_t self) /* Create a scaled bitmap, unless the requested size is the same as the raw size -- in that case a reference is made. */ - if ((signed) grub_video_bitmap_get_width (self->raw_bitmap) == width - && (signed) grub_video_bitmap_get_height (self->raw_bitmap) == height) + 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) + if (width == 0 || height == 0) return grub_errno; /* Create the scaled bitmap. */ @@ -151,6 +148,11 @@ rescale_image (grub_gui_image_t self) 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; } @@ -199,12 +201,6 @@ load_image (grub_gui_image_t self, const char *path) if (self->raw_bitmap) grub_video_bitmap_destroy (self->raw_bitmap); - /* - * Either self->bitmap is being freed or it shares memory with - * self->raw_bitmap which is being freed. To ensure self->bitmap doesn't - * point to memory that has been freed, we can set it to NULL. - */ - self->bitmap = NULL; self->raw_bitmap = bitmap; return rescale_image (self); } @@ -225,7 +221,7 @@ image_set_property (void *vself, const char *name, const char *value) /* Resolve to an absolute path. */ if (! self->theme_dir) - return grub_error (GRUB_ERR_BUG, "unspecified 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; diff --git a/grub-core/gfxmenu/gui_label.c b/gfxmenu/gui_label.c similarity index 71% rename from grub-core/gfxmenu/gui_label.c rename to gfxmenu/gui_label.c index ffd50223c..a9dd575ac 100644 --- a/grub-core/gfxmenu/gui_label.c +++ b/gfxmenu/gui_label.c @@ -22,8 +22,6 @@ #include #include #include -#include -#include static const char *align_options[] = { @@ -48,10 +46,8 @@ struct grub_gui_label char *id; int visible; char *text; - char *template; grub_font_t font; - grub_video_rgba_color_t color; - int value; + grub_gui_color_t color; enum align_mode align; }; @@ -61,9 +57,7 @@ static void label_destroy (void *vself) { grub_gui_label_t self = vself; - grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->text); - grub_free (self->template); grub_free (self); } @@ -96,22 +90,20 @@ label_paint (void *vself, const grub_video_rect_t *region) 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; + 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. */ - if (left_x < 0 || left_x > (int) self->bounds.width) - left_x = 0; - grub_video_rect_t vpsave; grub_gui_set_viewport (&self->bounds, &vpsave); grub_font_draw_string (self->text, self->font, - grub_video_map_rgba_color (self->color), + grub_gui_map_color (self->color), left_x, grub_font_get_ascent (self->font)); grub_gui_restore_viewport (&vpsave); @@ -154,19 +146,6 @@ label_get_minimal_size (void *vself, unsigned *width, unsigned *height) + grub_font_get_descent (self->font)); } -#pragma GCC diagnostic ignored "-Wformat-nonliteral" - -static void -label_set_state (void *vself, int visible, int start __attribute__ ((unused)), - int current, int end __attribute__ ((unused))) -{ - grub_gui_label_t self = vself; - self->value = -current; - self->visible = visible; - grub_free (self->text); - self->text = grub_xasprintf (self->template ? : "%d", self->value); -} - static grub_err_t label_set_property (void *vself, const char *name, const char *value) { @@ -174,32 +153,9 @@ label_set_property (void *vself, const char *name, const char *value) if (grub_strcmp (name, "text") == 0) { grub_free (self->text); - grub_free (self->template); if (! value) - { - self->template = NULL; - self->text = grub_strdup (""); - } - else - { - if (grub_strcmp (value, "@KEYMAP_LONG@") == 0) - value = _("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."); - else if (grub_strcmp (value, "@KEYMAP_MIDDLE@") == 0) - value = _("Press enter to boot the selected OS, " - "`e' to edit the commands before booting " - "or `c' for a command-line."); - else if (grub_strcmp (value, "@KEYMAP_SHORT@") == 0) - value = _("enter: boot, `e': options, `c': cmd-line"); - /* FIXME: Add more templates here if needed. */ - - if (grub_printf_fmt_check(value, "%d") != GRUB_ERR_NONE) - value = ""; /* Unsupported format. */ - - self->template = grub_strdup (value); - self->text = grub_xasprintf (value, self->value); - } + value = ""; + self->text = grub_strdup (value); } else if (grub_strcmp (name, "font") == 0) { @@ -207,7 +163,7 @@ label_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "color") == 0) { - grub_video_parse_color (value, &self->color); + grub_gui_parse_color (value, &self->color); } else if (grub_strcmp (name, "align") == 0) { @@ -227,22 +183,15 @@ label_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "id") == 0) { - grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->id); if (value) self->id = grub_strdup (value); else self->id = 0; - if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID) - == 0) - grub_gfxmenu_timeout_register ((grub_gui_component_t) self, - label_set_state); } return GRUB_ERR_NONE; } -#pragma GCC diagnostic error "-Wformat-nonliteral" - static struct grub_gui_component_ops label_ops = { .destroy = label_destroy, diff --git a/gfxmenu/gui_list.c b/gfxmenu/gui_list.c new file mode 100644 index 000000000..0d771413f --- /dev/null +++ b/gfxmenu/gui_list.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include + +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/gfxmenu/gui_progress_bar.c similarity index 70% rename from grub-core/gfxmenu/gui_progress_bar.c rename to gfxmenu/gui_progress_bar.c index c4cd1859b..d786aae31 100644 --- a/grub-core/gfxmenu/gui_progress_bar.c +++ b/gfxmenu/gui_progress_bar.c @@ -25,7 +25,6 @@ #include #include #include -#include struct grub_gui_progress_bar { @@ -38,12 +37,13 @@ struct grub_gui_progress_bar int start; int end; int value; + int show_text; char *template; grub_font_t font; - grub_video_rgba_color_t text_color; - grub_video_rgba_color_t border_color; - grub_video_rgba_color_t bg_color; - grub_video_rgba_color_t fg_color; + 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; @@ -52,7 +52,6 @@ struct grub_gui_progress_bar char *highlight_pattern; grub_gfxmenu_box_t bar_box; grub_gfxmenu_box_t highlight_box; - int highlight_overlay; }; typedef struct grub_gui_progress_bar *grub_gui_progress_bar_t; @@ -61,10 +60,6 @@ static void progress_bar_destroy (void *vself) { grub_gui_progress_bar_t self = vself; - grub_free (self->theme_dir); - grub_free (self->template); - grub_free (self->id); - grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self); } @@ -113,26 +108,20 @@ draw_filled_rect_bar (grub_gui_progress_bar_t self) f.height = self->bounds.height - 2; /* Border. */ - grub_video_fill_rect (grub_video_map_rgba_color (self->border_color), + 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. */ - unsigned barwidth; - - if (self->end <= self->start - || self->value <= self->start) - barwidth = 0; - else - barwidth = (f.width - * (self->value - self->start) - / (self->end - self->start)); - grub_video_fill_rect (grub_video_map_rgba_color (self->bg_color), + 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_video_map_rgba_color (self->fg_color), + grub_video_fill_rect (grub_gui_map_color (self->fg_color), f.x, f.y, barwidth, f.height); } @@ -150,55 +139,28 @@ draw_pixmap_bar (grub_gui_progress_bar_t self) 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 hl_l_pad = hl->get_left_pad (hl); - int hl_r_pad = hl->get_right_pad (hl); - int hl_t_pad = hl->get_top_pad (hl); - int hl_b_pad = hl->get_bottom_pad (hl); - int hl_h_pad = hl_l_pad + hl_r_pad; - int hl_v_pad = hl_t_pad + hl_b_pad; int tracklen = w - bar_h_pad; int trackheight = h - bar_v_pad; int barwidth; - int hlheight = trackheight; - int hlx = bar_l_pad; - int hly = bar_t_pad; 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); - - if (self->highlight_overlay) - { - tracklen += hl_h_pad; - hlx -= hl_l_pad; - hly -= hl_t_pad; - } - else - hlheight -= hl_v_pad; - - if (self->value <= self->start - || self->end <= self->start) - barwidth = 0; - else - barwidth = ((unsigned) (tracklen * (self->value - self->start)) - / ((unsigned) (self->end - self->start))); - - if (barwidth >= hl_h_pad) - { - hl->set_content_size (hl, barwidth - hl_h_pad, hlheight); - hl->draw (hl, hlx, hly); - } + hl->draw (hl, bar_l_pad, bar_t_pad); } -#pragma GCC diagnostic ignored "-Wformat-nonliteral" - 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_video_map_rgba_color (self->text_color); + 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; @@ -216,12 +178,9 @@ draw_text (grub_gui_progress_bar_t self) 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); - grub_free (text); } } -#pragma GCC diagnostic error "-Wformat-nonliteral" - static void progress_bar_paint (void *vself, const grub_video_rect_t *region) { @@ -280,47 +239,29 @@ static void progress_bar_get_minimal_size (void *vself, unsigned *width, unsigned *height) { - unsigned min_width = 0; - unsigned min_height = 0; + unsigned text_width = 0, text_height = 0; grub_gui_progress_bar_t self = vself; if (self->template) { - min_width = grub_font_get_string_width (self->font, self->template); - min_width += grub_font_get_string_width (self->font, "XXXXXXXXXX"); - min_height = grub_font_get_descent (self->font) - + grub_font_get_ascent (self->font); - } - if (check_pixmaps (self)) - { - grub_gfxmenu_box_t bar = self->bar_box; - grub_gfxmenu_box_t hl = self->highlight_box; - min_width += bar->get_left_pad (bar) + bar->get_right_pad (bar); - min_height += bar->get_top_pad (bar) + bar->get_bottom_pad (bar); - if (!self->highlight_overlay) - { - min_width += hl->get_left_pad (hl) + hl->get_right_pad (hl); - min_height += hl->get_top_pad (hl) + hl->get_bottom_pad (hl); - } - } - else - { - min_height += 2; - min_width += 2; + 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 < min_width) - *width = min_width; + if (*width < text_width) + *width = text_width; *height = 28; - if (*height < min_height) - *height = min_height; + 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; + grub_gui_progress_bar_t self = vself; self->visible = visible; self->start = start; self->value = current; @@ -335,7 +276,7 @@ progress_bar_set_property (void *vself, const char *name, const char *value) { grub_free (self->template); if (grub_strcmp (value, "@TIMEOUT_NOTIFICATION_LONG@") == 0) - value + value = _("The highlighted entry will be executed automatically in %ds."); else if (grub_strcmp (value, "@TIMEOUT_NOTIFICATION_MIDDLE@") == 0) /* TRANSLATORS: 's' stands for seconds. @@ -348,9 +289,6 @@ progress_bar_set_property (void *vself, const char *name, const char *value) Please use the shortest form available in you language. */ value = _("%ds"); - if (grub_printf_fmt_check(value, "%d") != GRUB_ERR_NONE) - value = ""; /* Unsupported format. */ - self->template = grub_strdup (value); } else if (grub_strcmp (name, "font") == 0) @@ -359,19 +297,19 @@ progress_bar_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "text_color") == 0) { - grub_video_parse_color (value, &self->text_color); + grub_gui_parse_color (value, &self->text_color); } else if (grub_strcmp (name, "border_color") == 0) { - grub_video_parse_color (value, &self->border_color); + grub_gui_parse_color (value, &self->border_color); } else if (grub_strcmp (name, "bg_color") == 0) { - grub_video_parse_color (value, &self->bg_color); + grub_gui_parse_color (value, &self->bg_color); } else if (grub_strcmp (name, "fg_color") == 0) { - grub_video_parse_color (value, &self->fg_color); + grub_gui_parse_color (value, &self->fg_color); } else if (grub_strcmp (name, "bar_style") == 0) { @@ -387,10 +325,6 @@ progress_bar_set_property (void *vself, const char *name, const char *value) grub_free (self->highlight_pattern); self->highlight_pattern = value ? grub_strdup (value) : 0; } - else if (grub_strcmp (name, "highlight_overlay") == 0) - { - self->highlight_overlay = grub_strcmp (value, "true") == 0; - } else if (grub_strcmp (name, "theme_dir") == 0) { self->need_to_recreate_pixmaps = 1; @@ -399,16 +333,11 @@ progress_bar_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "id") == 0) { - grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->id); if (value) self->id = grub_strdup (value); else self->id = 0; - if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID) - == 0) - grub_gfxmenu_timeout_register ((grub_gui_component_t) self, - progress_bar_set_state); } return grub_errno; } @@ -439,19 +368,17 @@ grub_gui_progress_bar_new (void) 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_video_rgba_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 }; - grub_video_rgba_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 }; - grub_video_rgba_color_t lightgray = { .red = 200, .green = 200, .blue = 200, .alpha = 255 }; + 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; - self->highlight_overlay = 0; return (grub_gui_component_t) self; } diff --git a/grub-core/gfxmenu/gui_string_util.c b/gfxmenu/gui_string_util.c similarity index 62% rename from grub-core/gfxmenu/gui_string_util.c rename to gfxmenu/gui_string_util.c index ba1e1eab3..8c51e396a 100644 --- a/grub-core/gfxmenu/gui_string_util.c +++ b/gfxmenu/gui_string_util.c @@ -55,7 +55,7 @@ canonicalize_path (const char *path) if (*p == '/') components++; - char **path_array = grub_calloc (components, sizeof (*path_array)); + char **path_array = grub_malloc (components * sizeof (*path_array)); if (! path_array) return 0; @@ -204,3 +204,124 @@ grub_get_dirname (const char *file_path) 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/gfxmenu/gui_util.c similarity index 100% rename from grub-core/gfxmenu/gui_util.c rename to gfxmenu/gui_util.c diff --git a/grub-core/gfxmenu/icon_manager.c b/gfxmenu/icon_manager.c similarity index 93% rename from grub-core/gfxmenu/icon_manager.c rename to gfxmenu/icon_manager.c index 1894682ef..0c304ede0 100644 --- a/grub-core/gfxmenu/icon_manager.c +++ b/gfxmenu/icon_manager.c @@ -106,10 +106,8 @@ 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) - return; - if (mgr->theme_path == 0 || path == 0 - || grub_strcmp (mgr->theme_path, path) != 0) + 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); @@ -139,19 +137,23 @@ static struct grub_video_bitmap * try_loading_icon (grub_gfxmenu_icon_manager_t mgr, const char *dir, const char *class_name) { - char *path, *ptr; + char *path; + int l; path = grub_malloc (grub_strlen (dir) + grub_strlen (class_name) + grub_strlen (icon_extension) + 3); if (! path) return 0; - ptr = grub_stpcpy (path, dir); - if (path == ptr || ptr[-1] != '/') - *ptr++ = '/'; - ptr = grub_stpcpy (ptr, class_name); - ptr = grub_stpcpy (ptr, icon_extension); - *ptr = '\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); @@ -167,7 +169,11 @@ try_loading_icon (grub_gfxmenu_icon_manager_t mgr, GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); grub_video_bitmap_destroy (raw_bitmap); if (! scaled_bitmap) - return 0; + { + grub_error_push (); + grub_error (grub_errno, "failed to scale icon"); + return 0; + } return scaled_bitmap; } @@ -251,7 +257,7 @@ grub_gfxmenu_icon_manager_get_icon (grub_gfxmenu_icon_manager_t mgr, /* Try each class in succession. */ icon = 0; - for (c = entry->classes; c && ! icon; c = c->next) + 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/lib/libgcrypt/mpi/powerpc64/distfiles b/gfxmenu/model.c similarity index 100% rename from grub-core/lib/libgcrypt/mpi/powerpc64/distfiles rename to gfxmenu/model.c diff --git a/grub-core/video/colors.c b/gfxmenu/named_colors.c similarity index 70% rename from grub-core/video/colors.c rename to gfxmenu/named_colors.c index 485ebb4ab..eedbc47fb 100644 --- a/grub-core/video/colors.c +++ b/gfxmenu/named_colors.c @@ -21,16 +21,11 @@ #include #include #include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); struct named_color { const char *name; - grub_video_rgba_color_t color; + grub_gui_color_t color; }; /* @@ -198,8 +193,8 @@ static struct named_color named_colors[] = stores the color into *COLOR. If the color was not found, returns 0 and does not modify *COLOR. */ int -grub_video_get_named_color (const char *name, - grub_video_rgba_color_t *color) +grub_gui_get_named_color (const char *name, + grub_gui_color_t *color) { int i; for (i = 0; named_colors[i].name; i++) @@ -212,122 +207,3 @@ grub_video_get_named_color (const char *name, } return 0; } - -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_video_parse_color (const char *s, grub_video_rgba_color_t *color) -{ - grub_video_rgba_color_t c; - const char *s0; - - /* Skip whitespace. */ - while (*s && grub_isspace (*s)) - s++; - - s0 = 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 (grub_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, - N_("invalid color specification `%s'"), s0); - } - else if (grub_isdigit (*s)) - { - /* Comma separated decimal values. */ - c.red = grub_strtoul (s, 0, 0); - s = grub_strchr (s, ','); - if (!s) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("invalid color specification `%s'"), s0); - s++; - c.green = grub_strtoul (s, 0, 0); - s = grub_strchr (s, ','); - if (!s) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("invalid color specification `%s'"), s0); - s++; - c.blue = grub_strtoul (s, 0, 0); - s = grub_strchr (s, ','); - if (!s) - c.alpha = 255; - else - { - s++; - c.alpha = grub_strtoul (s, 0, 0); - } - } - else - { - if (! grub_video_get_named_color (s, &c)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("invalid color specification `%s'"), s0); - } - - if (grub_errno == GRUB_ERR_NONE) - *color = c; - return grub_errno; -} diff --git a/grub-core/gfxmenu/theme_loader.c b/gfxmenu/theme_loader.c similarity index 77% rename from grub-core/gfxmenu/theme_loader.c rename to gfxmenu/theme_loader.c index 9eabf501a..3854c6c53 100644 --- a/grub-core/gfxmenu/theme_loader.c +++ b/gfxmenu/theme_loader.c @@ -30,10 +30,6 @@ #include #include #include -#include - -static grub_err_t -parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *prop); /* Construct a new box widget using ABSPATTERN to find the pixmap files for it, storing the new box instance at *BOXPTR. @@ -116,24 +112,6 @@ grub_gui_recreate_box (grub_gfxmenu_box_t *boxptr, return grub_errno; } -static grub_err_t -theme_get_unsigned_int_from_proportional (const char *value, - unsigned absolute_value, - unsigned int *parsed_value) -{ - grub_err_t err; - grub_fixed_signed_t frac; - signed pixels; - err = parse_proportional_spec (value, &pixels, &frac); - if (err != GRUB_ERR_NONE) - return err; - int result = grub_fixed_sfs_multiply (absolute_value, frac) + pixels; - if (result < 0) - result = 0; - *parsed_value = result; - return GRUB_ERR_NONE; -} - /* 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 @@ -157,14 +135,15 @@ theme_set_string (grub_gfxmenu_view_t view, return grub_errno; } else if (! grub_strcmp ("title-color", name)) - grub_video_parse_color (value, &view->title_color); + grub_gui_parse_color (value, &view->title_color); else if (! grub_strcmp ("message-color", name)) - grub_video_parse_color (value, &view->message_color); + grub_gui_parse_color (value, &view->message_color); else if (! grub_strcmp ("message-bg-color", name)) - grub_video_parse_color (value, &view->message_bg_color); + 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) @@ -175,59 +154,23 @@ theme_set_string (grub_gfxmenu_view_t view, return grub_errno; } grub_free(path); - grub_video_bitmap_destroy (view->raw_desktop_image); - view->raw_desktop_image = raw_bitmap; - } - else if (! grub_strcmp ("desktop-image-scale-method", name)) - { - if (! value || ! grub_strcmp ("stretch", value)) - view->desktop_image_scale_method = - GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH; - else if (! grub_strcmp ("crop", value)) - view->desktop_image_scale_method = - GRUB_VIDEO_BITMAP_SELECTION_METHOD_CROP; - else if (! grub_strcmp ("padding", value)) - view->desktop_image_scale_method = - GRUB_VIDEO_BITMAP_SELECTION_METHOD_PADDING; - else if (! grub_strcmp ("fitwidth", value)) - view->desktop_image_scale_method = - GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITWIDTH; - else if (! grub_strcmp ("fitheight", value)) - view->desktop_image_scale_method = - GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITHEIGHT; - else - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "Unsupported scale method: %s", - value); - } - else if (! grub_strcmp ("desktop-image-h-align", name)) - { - if (! grub_strcmp ("left", value)) - view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_LEFT; - else if (! grub_strcmp ("center", value)) - view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_CENTER; - else if (! grub_strcmp ("right", value)) - view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_RIGHT; - else - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "Unsupported horizontal align method: %s", - value); - } - else if (! grub_strcmp ("desktop-image-v-align", name)) - { - if (! grub_strcmp ("top", value)) - view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_TOP; - else if (! grub_strcmp ("center", value)) - view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_CENTER; - else if (! grub_strcmp ("bottom", value)) - view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_BOTTOM; - else - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "Unsupported vertical align method: %s", - value); + 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_video_parse_color (value, &view->desktop_color); + grub_gui_parse_color (value, &view->desktop_color); else if (! grub_strcmp ("terminal-box", name)) { grub_err_t err; @@ -235,52 +178,6 @@ theme_set_string (grub_gfxmenu_view_t view, if (err != GRUB_ERR_NONE) return err; } - else if (! grub_strcmp ("terminal-border", name)) - { - view->terminal_border = grub_strtoul (value, 0, 10); - if (grub_errno) - return grub_errno; - } - else if (! grub_strcmp ("terminal-left", name)) - { - unsigned int tmp; - int err = theme_get_unsigned_int_from_proportional (value, - view->screen.width, - &tmp); - if (err != GRUB_ERR_NONE) - return err; - view->terminal_rect.x = tmp; - } - else if (! grub_strcmp ("terminal-top", name)) - { - unsigned int tmp; - int err = theme_get_unsigned_int_from_proportional (value, - view->screen.height, - &tmp); - if (err != GRUB_ERR_NONE) - return err; - view->terminal_rect.y = tmp; - } - else if (! grub_strcmp ("terminal-width", name)) - { - unsigned int tmp; - int err = theme_get_unsigned_int_from_proportional (value, - view->screen.width, - &tmp); - if (err != GRUB_ERR_NONE) - return err; - view->terminal_rect.width = tmp; - } - else if (! grub_strcmp ("terminal-height", name)) - { - unsigned int tmp; - int err = theme_get_unsigned_int_from_proportional (value, - view->screen.height, - &tmp); - if (err != GRUB_ERR_NONE) - return err; - view->terminal_rect.height = tmp; - } else if (! grub_strcmp ("title-text", name)) { grub_free (view->title_text); @@ -419,7 +316,7 @@ read_expression (struct parsebuf *p) skip_whitespace (p); if (peek_char (p) == '"') { - /* Read as a quoted string. + /* Read as a quoted string. The quotation marks are not included in the expression value. */ /* Skip opening quotation mark. */ read_char (p); @@ -465,10 +362,10 @@ read_expression (struct parsebuf *p) } static grub_err_t -parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *prop) +parse_proportional_spec (char *value, signed *abs, grub_fixed_signed_t *prop) { signed num; - const char *ptr; + char *ptr; int sig = 0; *abs = 0; *prop = 0; @@ -743,7 +640,7 @@ grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path) p.view = view; p.theme_dir = grub_get_dirname (theme_path); - file = grub_file_open (theme_path, GRUB_FILE_TYPE_THEME); + file = grub_file_open (theme_path); if (! file) { grub_free (p.theme_dir); @@ -774,8 +671,6 @@ grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path) view->canvas->component.ops->destroy (view->canvas); view->canvas = grub_gui_canvas_new (); - if (!view->canvas) - goto fail; ((grub_gui_component_t) view->canvas) ->ops->set_bounds ((grub_gui_component_t) view->canvas, &view->screen); diff --git a/grub-core/gfxmenu/view.c b/gfxmenu/view.c similarity index 50% rename from grub-core/gfxmenu/view.c rename to gfxmenu/view.c index e02eba8b0..bf637a96d 100644 --- a/grub-core/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -36,12 +36,14 @@ #include #include #include -#include + +/* 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 void -init_background (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 @@ -52,38 +54,21 @@ grub_gfxmenu_view_new (const char *theme_path, { grub_gfxmenu_view_t view; grub_font_t default_font; - grub_video_rgba_color_t default_fg_color; - grub_video_rgba_color_t default_bg_color; + grub_gui_color_t default_fg_color; + grub_gui_color_t default_bg_color; view = grub_malloc (sizeof (*view)); if (! view) return 0; - while (grub_gfxmenu_timeout_notifications) - { - struct grub_gfxmenu_timeout_notify *p; - p = grub_gfxmenu_timeout_notifications; - grub_gfxmenu_timeout_notifications = grub_gfxmenu_timeout_notifications->next; - grub_free (p); - } - view->screen.x = 0; view->screen.y = 0; view->screen.width = width; view->screen.height = height; - view->need_to_check_sanity = 1; - view->terminal_border = 3; - view->terminal_rect.width = view->screen.width * 7 / 10; - view->terminal_rect.height = view->screen.height * 7 / 10; - view->terminal_rect.x = view->screen.x + (view->screen.width - - view->terminal_rect.width) / 2; - view->terminal_rect.y = view->screen.y + (view->screen.height - - view->terminal_rect.height) / 2; - default_font = grub_font_get ("Unknown Regular 16"); - default_fg_color = grub_video_rgba_color_rgb (0, 0, 0); - default_bg_color = grub_video_rgba_color_rgb (255, 255, 255); + default_fg_color = grub_gui_color_rgb (0, 0, 0); + default_bg_color = grub_gui_color_rgb (255, 255, 255); view->canvas = 0; @@ -93,14 +78,10 @@ grub_gfxmenu_view_new (const char *theme_path, view->title_color = default_fg_color; view->message_color = default_bg_color; view->message_bg_color = default_fg_color; - view->raw_desktop_image = 0; - view->scaled_desktop_image = 0; - view->desktop_image_scale_method = GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH; - view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_CENTER; - view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_CENTER; + 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->title_text = grub_strdup ("GRUB Boot Menu"); view->progress_message_text = 0; view->theme_path = 0; @@ -127,15 +108,7 @@ grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view) { if (!view) return; - while (grub_gfxmenu_timeout_notifications) - { - struct grub_gfxmenu_timeout_notify *p; - p = grub_gfxmenu_timeout_notifications; - grub_gfxmenu_timeout_notifications = grub_gfxmenu_timeout_notifications->next; - grub_free (p); - } - grub_video_bitmap_destroy (view->raw_desktop_image); - grub_video_bitmap_destroy (view->scaled_desktop_image); + grub_video_bitmap_destroy (view->desktop_image); if (view->terminal_box) view->terminal_box->destroy (view->terminal_box); grub_free (view->terminal_font_name); @@ -151,9 +124,9 @@ static void redraw_background (grub_gfxmenu_view_t view, const grub_video_rect_t *bounds) { - if (view->scaled_desktop_image) + if (view->desktop_image) { - struct grub_video_bitmap *img = view->scaled_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, @@ -162,7 +135,7 @@ redraw_background (grub_gfxmenu_view_t view, } else { - grub_video_fill_rect (grub_video_map_rgba_color (view->desktop_color), + grub_video_fill_rect (grub_gui_map_color (view->desktop_color), bounds->x, bounds->y, bounds->width, bounds->height); } @@ -181,7 +154,7 @@ draw_title (grub_gfxmenu_view_t view) int y = 40 + grub_font_get_ascent (view->title_font); grub_font_draw_string (view->title_text, view->title_font, - grub_video_map_rgba_color (view->title_color), + grub_gui_map_color (view->title_color), x, y); } @@ -193,56 +166,84 @@ struct progress_value_data int value; }; -struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications; - static void -update_timeouts (int visible, int start, int value, int end) +update_timeout_visit (grub_gui_component_t component, + void *userdata) { - struct grub_gfxmenu_timeout_notify *cur; + struct progress_value_data *pv; + pv = (struct progress_value_data *) userdata; - for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next) - cur->set_state (cur->self, visible, start, value, end); + ((struct grub_gui_progress *) component)->ops + ->set_state ((struct grub_gui_progress *) component, + pv->visible, pv->start, pv->value, pv->end); } -static void -redraw_timeouts (struct grub_gfxmenu_view *view) -{ - struct grub_gfxmenu_timeout_notify *cur; - - for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next) - { - grub_video_rect_t bounds; - cur->self->ops->get_bounds (cur->self, &bounds); - grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED); - grub_gfxmenu_view_redraw (view, &bounds); - } -} - -void +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; - update_timeouts (1, -view->first_timeout, -timeout, 0); - redraw_timeouts (view); + 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) - redraw_timeouts (view); + grub_gui_find_by_id ((grub_gui_component_t) view->canvas, + TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); } -void +void grub_gfxmenu_clear_timeout (void *data) { + struct progress_value_data pv; struct grub_gfxmenu_view *view = data; - update_timeouts (0, 1, 0, 0); - redraw_timeouts (view); + 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) - redraw_timeouts (view); + grub_gui_find_by_id ((grub_gui_component_t) view->canvas, + TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); } static void @@ -267,27 +268,6 @@ update_menu_components (grub_gfxmenu_view_t view) update_menu_visit, view); } -static void -refresh_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->refresh_list (list, view); - } -} - -/* Refresh list information (useful for submenus) */ -static void -refresh_menu_components (grub_gfxmenu_view_t view) -{ - grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas, - refresh_menu_visit, view); -} - static void draw_message (grub_gfxmenu_view_t view) { @@ -297,13 +277,13 @@ draw_message (grub_gfxmenu_view_t view) return; grub_font_t font = view->message_font; - grub_video_color_t color = grub_video_map_rgba_color (view->message_color); + 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_video_map_rgba_color (view->message_bg_color), + grub_video_fill_rect (grub_gui_map_color (view->message_bg_color), f.x, f.y, f.width, f.height); /* Center the text. */ @@ -318,15 +298,10 @@ void grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view, const grub_video_rect_t *region) { - if (grub_video_have_common_points (&view->terminal_rect, 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); - grub_video_area_status_t area_status; - grub_video_get_area_status (&area_status); - if (area_status == GRUB_VIDEO_AREA_ENABLED) - grub_video_set_region (region->x, region->y, - region->width, region->height); redraw_background (view, region); if (view->canvas) @@ -334,9 +309,6 @@ grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view, draw_title (view); if (grub_video_have_common_points (&view->progress_message_frame, region)) draw_message (view); - - if (area_status == GRUB_VIDEO_AREA_ENABLED) - grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED); } void @@ -344,8 +316,6 @@ grub_gfxmenu_view_draw (grub_gfxmenu_view_t view) { init_terminal (view); - init_background (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, @@ -356,18 +326,12 @@ grub_gfxmenu_view_draw (grub_gfxmenu_view_t view) view->screen.x, view->screen.y, view->screen.width, view->screen.height); - refresh_menu_components (view); update_menu_components (view); - grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED); grub_gfxmenu_view_redraw (view, &view->screen); grub_video_swap_buffers (); if (view->double_repaint) - { - grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED); - grub_gfxmenu_view_redraw (view, &view->screen); - } - + grub_gfxmenu_view_redraw (view, &view->screen); } static void @@ -378,10 +342,11 @@ redraw_menu_visit (grub_gui_component_t component, 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_video_set_area_status (GRUB_VIDEO_AREA_ENABLED); grub_gfxmenu_view_redraw (view, &bounds); } } @@ -401,7 +366,7 @@ grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view) } } -void +void grub_gfxmenu_set_chosen_entry (int entry, void *data) { grub_gfxmenu_view_t view = data; @@ -418,175 +383,41 @@ grub_gfxmenu_draw_terminal_box (void) term_box = term_view->terminal_box; if (!term_box) return; - - grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED); - - term_box->set_content_size (term_box, term_view->terminal_rect.width, - term_view->terminal_rect.height); - + + term_box->set_content_size (term_box, term_rect.width, + term_rect.height); + term_box->draw (term_box, - term_view->terminal_rect.x - term_box->get_left_pad (term_box), - term_view->terminal_rect.y - term_box->get_top_pad (term_box)); -} - -static void -get_min_terminal (grub_font_t terminal_font, - unsigned int border_width, - unsigned int *min_terminal_width, - unsigned int *min_terminal_height) -{ - struct grub_font_glyph *glyph; - glyph = grub_font_get_glyph (terminal_font, 'M'); - *min_terminal_width = (glyph? glyph->device_width : 8) * 80 - + 2 * border_width; - *min_terminal_height = grub_font_get_max_char_height (terminal_font) * 24 - + 2 * border_width; -} - -static void -terminal_sanity_check (grub_gfxmenu_view_t view) -{ - if (!view->need_to_check_sanity) - return; - - /* terminal_font was checked before in the init_terminal function. */ - grub_font_t terminal_font = grub_font_get (view->terminal_font_name); - - /* Non-negative numbers below. */ - int scr_x = view->screen.x; - int scr_y = view->screen.y; - int scr_width = view->screen.width; - int scr_height = view->screen.height; - int term_x = view->terminal_rect.x; - int term_y = view->terminal_rect.y; - int term_width = view->terminal_rect.width; - int term_height = view->terminal_rect.height; - - /* Check that border_width isn't too big. */ - unsigned int border_width = view->terminal_border; - unsigned int min_terminal_width; - unsigned int min_terminal_height; - get_min_terminal (terminal_font, border_width, - &min_terminal_width, &min_terminal_height); - if (border_width > 3 && ((int) min_terminal_width >= scr_width - || (int) min_terminal_height >= scr_height)) - { - border_width = 3; - get_min_terminal (terminal_font, border_width, - &min_terminal_width, &min_terminal_height); - } - - /* Sanity checks. */ - if (term_width > scr_width) - term_width = scr_width; - if (term_height > scr_height) - term_height = scr_height; - - if (scr_width <= (int) min_terminal_width - || scr_height <= (int) min_terminal_height) - { - /* The screen resulution is too low. Use all space, except a small border - to show the user, that it is a window. Then center the window. */ - term_width = scr_width - 6 * border_width; - term_height = scr_height - 6 * border_width; - term_x = scr_x + (scr_width - term_width) / 2; - term_y = scr_y + (scr_height - term_height) / 2; - } - else if (term_width < (int) min_terminal_width - || term_height < (int) min_terminal_height) - { - /* The screen resolution is big enough. Make sure, that terminal screen - dimensions aren't less than minimal values. Then center the window. */ - term_width = (int) min_terminal_width; - term_height = (int) min_terminal_height; - term_x = scr_x + (scr_width - term_width) / 2; - term_y = scr_y + (scr_height - term_height) / 2; - } - - /* At this point w and h are satisfying. */ - if (term_x + term_width > scr_width) - term_x = scr_width - term_width; - if (term_y + term_height > scr_height) - term_y = scr_height - term_height; - - /* Write down corrected data. */ - view->terminal_rect.x = (unsigned int) term_x; - view->terminal_rect.y = (unsigned int) term_y; - view->terminal_rect.width = (unsigned int) term_width; - view->terminal_rect.height = (unsigned int) term_height; - view->terminal_border = border_width; - - view->need_to_check_sanity = 0; + 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) { - grub_font_t terminal_font; + term_rect.width = view->screen.width * 7 / 10; + term_rect.height = view->screen.height * 7 / 10; - terminal_font = grub_font_get (view->terminal_font_name); - if (!terminal_font) - { - grub_error (GRUB_ERR_BAD_FONT, "no font loaded"); - return; - } - - /* Check that terminal window size and position are sane. */ - terminal_sanity_check (view); + 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, - view->terminal_rect.x, - view->terminal_rect.y, - view->terminal_rect.width, - view->terminal_rect.height, - view->double_repaint, - terminal_font, - view->terminal_border); + 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; } -static void -init_background (grub_gfxmenu_view_t view) -{ - struct grub_video_bitmap *scaled_bitmap; - - /* - * You don't have to scale a raw image if it's not present. This prevents - * setting grub_errno and disrupting a command execution. - */ - if (view->raw_desktop_image == NULL) - return; - - if (view->scaled_desktop_image) - return; - - if (view->desktop_image_scale_method == - GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH) - grub_video_bitmap_create_scaled (&scaled_bitmap, - view->screen.width, - view->screen.height, - view->raw_desktop_image, - GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); - else - grub_video_bitmap_scale_proportional (&scaled_bitmap, - view->screen.width, - view->screen.height, - view->raw_desktop_image, - GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST, - view->desktop_image_scale_method, - view->desktop_image_v_align, - view->desktop_image_h_align); - if (! scaled_bitmap) - return; - view->scaled_desktop_image = scaled_bitmap; - -} - /* FIXME: previously notifications were displayed in special case. Is it necessary? */ diff --git a/grub-core/gfxmenu/widget-box.c b/gfxmenu/widget-box.c similarity index 80% rename from grub-core/gfxmenu/widget-box.c rename to gfxmenu/widget-box.c index 470597ded..079fd66d4 100644 --- a/grub-core/gfxmenu/widget-box.c +++ b/gfxmenu/widget-box.c @@ -79,26 +79,22 @@ 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; - int tmp; - /* Count maximum height of NW, N, NE. */ - height_n = get_height (self->scaled_pixmaps[BOX_PIXMAP_NW]); - tmp = get_height (self->scaled_pixmaps[BOX_PIXMAP_N]); - if (tmp > height_n) - height_n = tmp; - tmp = get_height (self->scaled_pixmaps[BOX_PIXMAP_NE]); - if (tmp > height_n) - height_n = tmp; - - /* Count maximum width of NW, W, SW. */ - width_w = get_width (self->scaled_pixmaps[BOX_PIXMAP_NW]); - tmp = get_width (self->scaled_pixmaps[BOX_PIXMAP_W]); - if (tmp > width_w) - width_w = tmp; - tmp = get_width (self->scaled_pixmaps[BOX_PIXMAP_SW]); - if (tmp > width_w) - width_w = tmp; + 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); @@ -146,6 +142,12 @@ scale_pixmap (grub_gfxmenu_box_t self, int i, int w, int h) 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; @@ -188,75 +190,28 @@ set_content_size (grub_gfxmenu_box_t self, return; } -static int -get_border_width (grub_gfxmenu_box_t self) -{ - return (get_width (self->raw_pixmaps[BOX_PIXMAP_E]) - + get_width (self->raw_pixmaps[BOX_PIXMAP_W])); -} - static int get_left_pad (grub_gfxmenu_box_t self) { - int v, c; - - v = get_width (self->raw_pixmaps[BOX_PIXMAP_W]); - c = get_width (self->raw_pixmaps[BOX_PIXMAP_NW]); - if (c > v) - v = c; - c = get_width (self->raw_pixmaps[BOX_PIXMAP_SW]); - if (c > v) - v = c; - - return v; + return get_width (self->raw_pixmaps[BOX_PIXMAP_W]); } static int get_top_pad (grub_gfxmenu_box_t self) { - int v, c; - - v = get_height (self->raw_pixmaps[BOX_PIXMAP_N]); - c = get_height (self->raw_pixmaps[BOX_PIXMAP_NW]); - if (c > v) - v = c; - c = get_height (self->raw_pixmaps[BOX_PIXMAP_NE]); - if (c > v) - v = c; - - return v; + return get_height (self->raw_pixmaps[BOX_PIXMAP_N]); } static int get_right_pad (grub_gfxmenu_box_t self) { - int v, c; - - v = get_width (self->raw_pixmaps[BOX_PIXMAP_E]); - c = get_width (self->raw_pixmaps[BOX_PIXMAP_NE]); - if (c > v) - v = c; - c = get_width (self->raw_pixmaps[BOX_PIXMAP_SE]); - if (c > v) - v = c; - - return v; + return get_width (self->raw_pixmaps[BOX_PIXMAP_E]); } static int get_bottom_pad (grub_gfxmenu_box_t self) { - int v, c; - - v = get_height (self->raw_pixmaps[BOX_PIXMAP_S]); - c = get_height (self->raw_pixmaps[BOX_PIXMAP_SW]); - if (c > v) - v = c; - c = get_height (self->raw_pixmaps[BOX_PIXMAP_SE]); - if (c > v) - v = c; - - return v; + return get_height (self->raw_pixmaps[BOX_PIXMAP_S]); } static void @@ -303,10 +258,10 @@ grub_gfxmenu_create_box (const char *pixmaps_prefix, box->content_height = 0; box->raw_pixmaps = (struct grub_video_bitmap **) - grub_calloc (BOX_NUM_PIXMAPS, sizeof (struct grub_video_bitmap *)); + grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *)); box->scaled_pixmaps = (struct grub_video_bitmap **) - grub_calloc (BOX_NUM_PIXMAPS, sizeof (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. */ @@ -345,8 +300,6 @@ grub_gfxmenu_create_box (const char *pixmaps_prefix, box->draw = draw; box->set_content_size = set_content_size; - box->get_border_width = get_border_width; - box->get_left_pad = get_left_pad; box->get_top_pad = get_top_pad; box->get_right_pad = get_right_pad; diff --git a/gnulib/alloca.h b/gnulib/alloca.h new file mode 100644 index 000000000..5d16e08b7 --- /dev/null +++ b/gnulib/alloca.h @@ -0,0 +1,56 @@ +/* Memory allocation on the stack. + + Copyright (C) 1995, 1999, 2001-2004, 2006-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 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 +# define alloca _alloca +# elif defined __DECC && defined __VMS +# define alloca __ALLOCA +# else +# include +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +#endif + +#endif /* _GL_ALLOCA_H */ diff --git a/gnulib/error.c b/gnulib/error.c new file mode 100644 index 000000000..af2287b27 --- /dev/null +++ b/gnulib/error.c @@ -0,0 +1,352 @@ +/* Error handler for noninteractive utilities + Copyright (C) 1990-1998, 2000-2007, 2009 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 . */ + +/* Written by David MacKenzie . */ + +#if !_LIBC +# include +#endif + +#include "error.h" + +#include +#include +#include +#include + +#if !_LIBC && ENABLE_NLS +# include "gettext.h" +# define _(msgid) gettext (msgid) +#endif + +#ifdef _LIBC +# include +# include +# include +# include +# 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 +# include +# include + +/* 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 +# define fflush(s) INTUSE(_IO_fflush) (s) +# undef putc +# define putc(c, fp) INTUSE(_IO_putc) (c, fp) + +# include + +#else /* not _LIBC */ + +# include + +# 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 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 + +#if !_LIBC && defined F_GETFL + /* 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 <= fcntl (1, F_GETFL)) +#endif + fflush (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 +} + +/* 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 + +#if !_LIBC && defined F_GETFL + /* 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 <= fcntl (1, F_GETFL)) +#endif + fflush (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 new file mode 100644 index 000000000..6d4968114 --- /dev/null +++ b/gnulib/error.h @@ -0,0 +1,65 @@ +/* Declaration for error-reporting function + Copyright (C) 1995, 1996, 1997, 2003, 2006, 2008 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 . */ + +#ifndef _ERROR_H +#define _ERROR_H 1 + +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) +# define __attribute__(Spec) /* empty */ +# endif +/* The __-protected variants of `format' and `printf' attributes + are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) +# define __format__ format +# define __printf__ printf +# 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 new file mode 100644 index 000000000..48bc8b5d2 --- /dev/null +++ b/gnulib/fnmatch.c @@ -0,0 +1,354 @@ +/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,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 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 +#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 + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +# include +#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 + +# 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 new file mode 100644 index 000000000..b086b45aa --- /dev/null +++ b/gnulib/fnmatch.h @@ -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 . */ +#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 new file mode 100644 index 000000000..c2182ffb0 --- /dev/null +++ b/gnulib/fnmatch_loop.c @@ -0,0 +1,1211 @@ +/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006 + 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 +# else +# include +# 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]; + int32_t idx2; + const UCHAR *np = (const UCHAR *) n; + + idx2 = findidx (&np); + if (idx2 != 0 && len == weights[idx2]) + { + int cnt = 0; + + 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; \ + \ + assert (p > startp); \ + plen = (opt == L_('?') || opt == L_('@') \ + ? pattern_len \ + : (unsigned) (p - startp) + 1); \ + 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 new file mode 100644 index 000000000..85818b565 --- /dev/null +++ b/gnulib/getdelim.c @@ -0,0 +1,134 @@ +/* getdelim.c --- Implementation of replacement getdelim function. + Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006, 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 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 + +#include + +#include +#include +#include +#include +#include + +#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 new file mode 100644 index 000000000..eb8f055a8 --- /dev/null +++ b/gnulib/getline.c @@ -0,0 +1,30 @@ +/* getline.c --- Implementation of replacement getline function. + Copyright (C) 2005, 2006, 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 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 + +#include +#include + +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 new file mode 100644 index 000000000..f1e6d1f7c --- /dev/null +++ b/gnulib/getopt.c @@ -0,0 +1,1186 @@ +/* Getopt for GNU. + NOTE: getopt is now 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,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004,2006,2008 + 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 . */ + +#ifndef _LIBC +# include +#endif + +#include "getopt.h" + +#include +#include +#include +#include + +#ifdef _LIBC +# include +#else +# include "gettext.h" +# define _(msgid) gettext (msgid) +#endif + +#if defined _LIBC && defined USE_IN_LIBIO +# include +#endif + +#ifndef attribute_hidden +# define attribute_hidden +#endif + +/* Unlike standard Unix `getopt', functions like `getopt_long' + let the user 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 application's 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; + + +#if defined HAVE_DECL_GETENV && !HAVE_DECL_GETENV +extern char *getenv (); +#endif + +#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, char **argv, const char *optstring, + int posixly_correct, struct _getopt_data *d) +{ + /* 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; +} + +/* 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. + + 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. + + If POSIXLY_CORRECT is nonzero, behave as if the POSIXLY_CORRECT + environment variable were set. */ + +int +_getopt_internal_r (int argc, char **argv, const char *optstring, + const struct option *longopts, int *longind, + int long_only, int posixly_correct, struct _getopt_data *d) +{ + 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, + posixly_correct, d); + 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 (d->__posixly_correct) + { + /* 1003.2 specifies the format of this message. */ +#if defined _LIBC && defined USE_IN_LIBIO + n = __asprintf (&buf, _("%s: illegal option -- %c\n"), + argv[0], c); +#else + fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); +#endif + } + else + { +#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) + { + /* 1003.2 specifies the format of this message. */ +#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) + { + /* 1003.2 specifies the format of this message. */ +#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, posixly_correct, &getopt_data); + + 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, NULL, NULL, 0, + POSIXLY_CORRECT); +} + + +#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 new file mode 100644 index 000000000..d2d3e6e63 --- /dev/null +++ b/gnulib/getopt.h @@ -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 . */ + +#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 +# include +# include +# 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 , but + that does not exist if we are standalone. So: if __GNU_LIBRARY__ is + not defined, include , which will pull in 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 +#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 new file mode 100644 index 000000000..d6a3ecf4e --- /dev/null +++ b/gnulib/getopt1.c @@ -0,0 +1,170 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004,2006 + 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 . */ + +#ifdef _LIBC +# include +#else +# include +# include "getopt.h" +#endif +#include "getopt_int.h" + +#include + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include +#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, 0, d); +} + +/* 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, 0, d); +} + + +#ifdef TEST + +#include + +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 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 new file mode 100644 index 000000000..3c6628bb9 --- /dev/null +++ b/gnulib/getopt_int.h @@ -0,0 +1,130 @@ +/* Internal declarations for getopt. + Copyright (C) 1989-1994,1996-1999,2001,2003,2004 + 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 . */ + +#ifndef _GETOPT_INT_H +#define _GETOPT_INT_H 1 + +extern int _getopt_internal (int ___argc, char **___argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only, int __posixly_correct); + + +/* 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, int __posixly_correct, + struct _getopt_data *__data); + +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 new file mode 100644 index 000000000..9d76ec9af --- /dev/null +++ b/gnulib/gettext.h @@ -0,0 +1,270 @@ +/* Convenience header for conditional use of GNU . + Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, 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 + +/* 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 a NOP. We don't include + as well because people using "gettext.h" will not include , + and also including would fail on SunOS 4, whereas + is OK. */ +#if defined(__sun) +# include +#endif + +/* Many header files from the libstdc++ coming with g++ 3.3 or newer include + , which chokes if dcgettext is defined as a macro. So include + it now, to make later inclusions of a NOP. */ +#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) +# include +# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H +# include +# 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". */ +# define gettext(Msgid) ((const char *) (Msgid)) +# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) +# define dcgettext(Domainname, Msgid, Category) \ + ((void) (Category), dgettext (Domainname, Msgid)) +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 \ + ? ((void) (Msgid2), (const char *) (Msgid1)) \ + : ((void) (Msgid1), (const char *) (Msgid2))) +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N)) +# define textdomain(Domainname) ((const char *) (Domainname)) +# define bindtextdomain(Domainname, Dirname) \ + ((void) (Domainname), (const char *) (Dirname)) +# 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 + +#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \ + (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \ + /* || __STDC_VERSION__ >= 199901L */ ) + +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS +#include +#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 new file mode 100644 index 000000000..bfa374a52 --- /dev/null +++ b/gnulib/progname.c @@ -0,0 +1,78 @@ +/* Program name management. + Copyright (C) 2001-2003, 2005-2009 Free Software Foundation, Inc. + Written by Bruno Haible , 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 . */ + + +#include + +/* Specification. */ +#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */ +#include "progname.h" + +#include /* get program_invocation_name declaration */ +#include + + +/* 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]. */ +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 "/.libs/" or "/.libs/lt-" prefix here. */ + const char *slash; + const char *base; + + 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 / 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 new file mode 100644 index 000000000..82615c6bc --- /dev/null +++ b/gnulib/progname.h @@ -0,0 +1,60 @@ +/* Program name management. + Copyright (C) 2001-2004, 2006 Free Software Foundation, Inc. + Written by Bruno Haible , 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 . */ + +#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]. */ +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/Makefile.am b/grub-core/Makefile.am deleted file mode 100644 index e50db8106..000000000 --- a/grub-core/Makefile.am +++ /dev/null @@ -1,522 +0,0 @@ -AUTOMAKE_OPTIONS = subdir-objects -Wno-portability - -DEPDIR=.deps-core - -include $(top_srcdir)/conf/Makefile.common - -CC=$(TARGET_CC) -CPP=$(TARGET_CC) -CCAS=$(TARGET_CC) -RANLIB=$(TARGET_RANLIB) -STRIP=$(TARGET_STRIP) - -MACHO2IMG=$(top_builddir)/grub-macho2img - -AM_CFLAGS = $(TARGET_CFLAGS) -AM_LDFLAGS = $(TARGET_LDFLAGS) -AM_CPPFLAGS = $(TARGET_CPPFLAGS) $(CPPFLAGS_DEFAULT) -AM_CCASFLAGS = $(TARGET_CCASFLAGS) $(CCASFLAGS_DEFAULT) - -CFLAGS_PROGRAM += $(CFLAGS_PLATFORM) -LDFLAGS_PROGRAM += $(LDFLAGS_PLATFORM) -CPPFLAGS_PROGRAM += $(CPPFLAGS_PLATFORM) -CCASFLAGS_PROGRAM += $(CCASFLAGS_PLATFORM) - -CFLAGS_LIBRARY += $(CFLAGS_PLATFORM) -fno-builtin -CPPFLAGS_LIBRARY += $(CPPFLAGS_PLATFORM) -CCASFLAGS_LIBRARY += $(CCASFLAGS_PLATFORM) - -build-grub-pep2elf$(BUILD_EXEEXT): $(top_srcdir)/util/grub-pe2elf.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c - $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_TARGET_WORDSIZE=64 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-pep2elf\" $^ -CLEANFILES += build-grub-pep2elf$(BUILD_EXEEXT) - -build-grub-pe2elf$(BUILD_EXEEXT): $(top_srcdir)/util/grub-pe2elf.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c - $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_TARGET_WORDSIZE=32 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-pe2elf\" $^ -CLEANFILES += build-grub-pe2elf$(BUILD_EXEEXT) - -# gentrigtables -gentrigtables$(BUILD_EXEEXT): gentrigtables.c - $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) $< $(BUILD_LIBM) -CLEANFILES += gentrigtables$(BUILD_EXEEXT) - -build-grub-module-verifier$(BUILD_EXEEXT): $(top_srcdir)/util/grub-module-verifier.c $(top_srcdir)/util/grub-module-verifier32.c $(top_srcdir)/util/grub-module-verifier64.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c - $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-module-verifier\" $^ -CLEANFILES += build-grub-module-verifier$(BUILD_EXEEXT) - -# trigtables.c -trigtables.c: gentrigtables$(BUILD_EXEEXT) gentrigtables.c $(top_srcdir)/configure.ac - ./gentrigtables$(BUILD_EXEEXT) > $@ -CLEANFILES += trigtables.c - -# XXX Use Automake's LEX & YACC support -grub_script.tab.h: script/parser.y - $(YACC) -d -p grub_script_yy -b grub_script $< -grub_script.tab.c: grub_script.tab.h -CLEANFILES += grub_script.tab.c grub_script.tab.h - -# For the lexer. -grub_script.yy.h: script/yylex.l - $(LEX) -o grub_script.yy.c --header-file=grub_script.yy.h $< -grub_script.yy.c: grub_script.yy.h - -rs_decoder.h: $(srcdir)/lib/reed_solomon.c - $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Os -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3 -ffreestanding - -CLEANFILES += grub_script.yy.c grub_script.yy.h - -include $(srcdir)/Makefile.core.am - -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cache.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/command.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/device.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/disk.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dl.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/sb.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env_private.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/err.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/file.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lockdown.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h -if COND_emu -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt-emu.h -else -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt.h -endif -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/key_protector.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/stack_protector.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/verify.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h - -if COND_i386_pc -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h -endif - -if COND_i386_xen_pvh -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h -endif - -if COND_i386_efi -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h -endif - -if COND_i386_coreboot -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/coreboot/lbio.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h -endif - -if COND_i386_multiboot -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h -endif - -if COND_i386_qemu -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h -endif - -if COND_i386_ieee1275 -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/alloc.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h -endif - -if COND_i386_xen -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h -endif - -if COND_x86_64_xen -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/x86_64/xen/hypercall.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h -endif - -if COND_x86_64_efi -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h -endif - -if COND_ia64_efi -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h -endif - -if COND_mips -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/kernel.h -endif - -if COND_mips_arc -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arc/arc.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h -endif - -if COND_mips_qemu_mips -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/serial.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h -endif - -if COND_mips_loongson -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/time.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cs5536.h -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pci.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/serial.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h -endif - -if COND_mips_qemu_mips -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h -endif - -if COND_powerpc_ieee1275 -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/alloc.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h -endif - -if COND_sparc64_ieee1275 -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h -endif - -if COND_arm_uboot -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/uboot.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/disk.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h -endif - -if COND_arm_coreboot -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdt.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dma.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/coreboot/kernel.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdtbus.h -endif - -if COND_arm_efi -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h -endif - -if COND_arm64_efi -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h -endif - -if COND_loongarch64_efi -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h -endif - -if COND_riscv32_efi -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h -endif - -if COND_riscv64_efi -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h -endif - -if COND_emu -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/net.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostdisk.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostfile.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/exec.h -if COND_GRUB_EMU_SDL -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h -endif -if COND_GRUB_EMU_SDL2 -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h -endif -if COND_GRUB_EMU_PCI -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libpciaccess.h -endif -endif - -symlist.h: $(top_builddir)/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 | $(SHELL) $(srcdir)/gensymlist.sh $(top_builddir)/config.h $(KERNEL_HEADER_FILES) >$@ || (rm -f $@; exit 1) - rm -f symlist.p -CLEANFILES += symlist.c -BUILT_SOURCES += symlist.c - -if COND_HAVE_ASM_USCORE -ASM_PREFIX=_ -else -ASM_PREFIX= -endif - -noinst_DATA += kernel_syms.lst - -kernel_syms.lst: $(KERNEL_HEADER_FILES) $(top_builddir)/config.h - $(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_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \ - -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;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 $(MODULE_FILES) - rm -f $@; echo $(MODULE_FILES) | sh $(srcdir)/genemuinitheader.sh $(TARGET_NM) > $@ -CLEANFILES += grub_emu_init.h - -grub_emu_init.c: grub_emu_init.h genemuinit.sh $(MODULE_FILES) - rm -f $@; echo $(MODULE_FILES) | sh $(srcdir)/genemuinit.sh $(TARGET_NM) > $@ -CLEANFILES += grub_emu_init.c -endif - -# List files - -fs.lst: $(MARKER_FILES) - (for pp in $^; do \ - b=`basename $$pp .marker`; \ - if grep 'FS_LIST_MARKER' $$pp >/dev/null 2>&1; then \ - echo $$b; \ - fi; \ - done) | sort -u > $@ -platform_DATA += fs.lst -CLEANFILES += fs.lst - -command.lst: $(MARKER_FILES) - (for pp in $^; do \ - b=`basename $$pp .marker`; \ - sed -n \ - -e "/EXTCOMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ - -e "/EXTCOMMAND_LOCKDOWN_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ - -e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ - -e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" \ - -e "/COMMAND_LOCKDOWN_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \ - done) | sort -u > $@ -platform_DATA += command.lst -CLEANFILES += command.lst - -partmap.lst: $(MARKER_FILES) - (for pp in $^; do \ - b=`basename $$pp .marker`; \ - if grep 'PARTMAP_LIST_MARKER' $$pp >/dev/null 2>&1; then \ - echo $$b; \ - fi; \ - done) | sort -u > $@ -platform_DATA += partmap.lst -CLEANFILES += partmap.lst - -terminal.lst: $(MARKER_FILES) - (for pp in $^; do \ - b=`basename $$pp .marker`; \ - sed -n \ - -e "/INPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \ - -e "/OUTPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \ - done) | sort -u > $@ -platform_DATA += terminal.lst -CLEANFILES += terminal.lst - -fdt.lst: $(MARKER_FILES) - (for pp in $^; do \ - b=`basename $$pp .marker`; \ - sed -n \ - -e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \ - -e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \ - done) | sort -u > $@ -platform_DATA += fdt.lst -CLEANFILES += fdt.lst - -parttool.lst: $(MARKER_FILES) - (for pp in $^; do \ - b=`basename $$pp .marker`; \ - sed -n \ - -e "/PARTTOOL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \ - done) | sort -u > $@ -platform_DATA += parttool.lst -CLEANFILES += parttool.lst - -video.lst: $(MARKER_FILES) - (for pp in $^; do \ - b=`basename $$pp .marker`; \ - if grep 'VIDEO_LIST_MARKER' $$pp >/dev/null 2>&1; then \ - echo $$b; \ - fi; \ - done) | sort -u > $@ -platform_DATA += video.lst -CLEANFILES += video.lst - -# but, crypto.lst is simply copied -crypto.lst: $(srcdir)/lib/libgcrypt-grub/cipher/crypto.lst - cp $^ $@ -platform_DATA += crypto.lst -CLEANFILES += crypto.lst - -extra_deps.lst: - @echo $(EXTRA_DEPS) | sed "s/\s*:\s*/\n/g" > $@ - -syminfo.lst: gensyminfo.sh kernel_syms.lst extra_deps.lst $(MODULE_FILES) - cat kernel_syms.lst extra_deps.lst > $@.new - for m in $(MODULE_FILES); do \ - sh $< $$m >> $@.new || exit 1; \ - done - mv $@.new $@ - -# generate global module dependencies list -moddep.lst: syminfo.lst genmoddep.awk video.lst - cat $< | sort | $(AWK) -f $(srcdir)/genmoddep.awk > $@ || (rm -f $@; exit 1) -platform_DATA += moddep.lst -CLEANFILES += config.log syminfo.lst moddep.lst extra_deps.lst - -$(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT) build-grub-module-verifier$(BUILD_EXEEXT) - TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@ -platform_DATA += $(MOD_FILES) -platform_DATA += modinfo.sh -CLEANFILES += $(MOD_FILES) - -if COND_ENABLE_EFIEMU -efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF) - -rm -f $@ - -rm -f $@.bin - $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m32 -Wall -Werror -nostdlib -static -O2 -c -o $@.bin $< - if test "x$(TARGET_APPLE_LINKER)" = x1; then \ - $(TARGET_OBJCONV) -felf32 -nu -nd $@.bin $@ || exit 1; \ - rm -f $@.bin ; \ - elif test ! -z "$(TARGET_OBJ2ELF)"; then \ - $(TARGET_OBJ2ELF) $@.bin || (rm -f $@.bin; exit 1); \ - mv $@.bin $@ ; \ - else \ - mv $@.bin $@ ; \ - fi - -# Link format -arch,x86_64 means Apple linker -efiemu64_c.o: efiemu/runtime/efiemu.c - $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -nostdlib -Wall -Werror -O2 -mcmodel=large -mno-red-zone -c -o $@ $< - -efiemu64_s.o: efiemu/runtime/efiemu.S - $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -Wall -Werror -nostdlib -O2 -mcmodel=large -mno-red-zone -c -o $@ $< - -efiemu64.o: efiemu64_c.o efiemu64_s.o $(TARGET_OBJ2ELEF) - -rm -f $@ - -rm -f $@.bin - $(TARGET_CC) -m64 $(EFIEMU64_LINK_FORMAT) -nostdlib -static -Wl,-r -o $@.bin $^ - if test "x$(EFIEMU64_LINK_FORMAT)" = x-arch,x86_64; then \ - $(TARGET_OBJCONV) -felf64 -nu -nd $@.bin $@ || exit 1; \ - rm -f $@.bin; \ - else \ - mv $@.bin $@ ; \ - fi - -platform_DATA += efiemu32.o efiemu64.o -CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o -endif - -windowsdir=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows -windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA) - test -d $(windowsdir)/$(target_cpu)-$(platform) || mkdir $(windowsdir)/$(target_cpu)-$(platform) - for x in $(platform_DATA); do \ - cp -fp $$x $(windowsdir)/$(target_cpu)-$(platform)/$$x; \ - done diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def deleted file mode 100644 index 24e8c8437..000000000 --- a/grub-core/Makefile.core.def +++ /dev/null @@ -1,2676 +0,0 @@ -AutoGen definitions Makefile.tpl; - -transform_data = { - installdir = noinst; - name = gensyminfo.sh; - common = gensyminfo.sh.in; -}; - -transform_data = { - installdir = noinst; - name = genmod.sh; - common = genmod.sh.in; -}; - -transform_data = { - installdir = noinst; - name = modinfo.sh; - common = modinfo.sh.in; -}; - -transform_data = { - installdir = platform; - name = gdb_helper.py; - common = gdb_helper.py.in; -}; - -transform_data = { - installdir = platform; - name = gdb_grub; - common = gdb_grub.in; -}; - -transform_data = { - installdir = platform; - name = grub.chrp; - common = boot/powerpc/grub.chrp.in; - enable = powerpc_ieee1275; -}; - -transform_data = { - installdir = platform; - name = bootinfo.txt; - common = boot/powerpc/bootinfo.txt.in; - enable = powerpc_ieee1275; -}; - -kernel = { - name = kernel; - - nostrip = emu; - - emu_ldflags = '-Wl,-r'; - i386_efi_cflags = '-fshort-wchar'; - i386_efi_ldflags = '-Wl,-r'; - i386_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; - x86_64_efi_cflags = '-fshort-wchar'; - x86_64_efi_ldflags = '-Wl,-r'; - x86_64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; - - ia64_efi_cflags = '-fshort-wchar -fno-builtin -fpic -minline-int-divide-max-throughput'; - ia64_efi_ldflags = '-Wl,-r'; - ia64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; - - arm_efi_cflags = '-fshort-wchar'; - arm_efi_ldflags = '-Wl,-r'; - arm_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; - - arm64_efi_cflags = '-fshort-wchar'; - arm64_efi_ldflags = '-Wl,-r'; - arm64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame'; - - loongarch64_efi_cflags = '-fshort-wchar'; - loongarch64_efi_ldflags = '-Wl,-r'; - loongarch64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame'; - - riscv32_efi_cflags = '-fshort-wchar'; - riscv32_efi_ldflags = '-Wl,-r'; - riscv32_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame'; - - riscv64_efi_cflags = '-fshort-wchar'; - riscv64_efi_ldflags = '-Wl,-r'; - riscv64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame'; - - i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000'; - i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000'; - i386_coreboot_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_coreboot_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000'; - i386_multiboot_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_multiboot_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000'; - i386_ieee1275_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_ieee1275_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x10000'; - i386_xen_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_xen_ldflags = '$(TARGET_IMG_BASE_LDOPT),0'; - x86_64_xen_ldflags = '$(TARGET_IMG_LDFLAGS)'; - x86_64_xen_ldflags = '$(TARGET_IMG_BASE_LDOPT),0'; - i386_xen_pvh_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_xen_pvh_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x100000'; - - mips_loongson_ldflags = '-Wl,-Ttext,0x80200000'; - powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000'; - sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400'; - mips_arc_ldflags = '-Wl,-Ttext,$(TARGET_LINK_ADDR)'; - mips_qemu_mips_ldflags = '-Wl,-Ttext,0x80200000'; - - mips_arc_cppflags = '-DGRUB_DECOMPRESSOR_LINK_ADDR=$(TARGET_DECOMPRESSOR_LINK_ADDR)'; - i386_qemu_cppflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)'; - emu_cflags = '$(CFLAGS_GNULIB)'; - emu_cppflags = '$(CPPFLAGS_GNULIB)'; - arm_uboot_ldflags = '-Wl,-r'; - arm_uboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; - arm_coreboot_ldflags = '-Wl,-r'; - arm_coreboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; - - i386_pc_startup = kern/i386/pc/startup.S; - i386_efi_startup = kern/i386/efi/startup.S; - x86_64_efi_startup = kern/x86_64/efi/startup.S; - i386_xen_startup = kern/i386/xen/startup.S; - x86_64_xen_startup = kern/x86_64/xen/startup.S; - i386_xen_pvh_startup = kern/i386/xen/startup_pvh.S; - i386_qemu_startup = kern/i386/qemu/startup.S; - i386_ieee1275_startup = kern/i386/ieee1275/startup.S; - i386_coreboot_startup = kern/i386/coreboot/startup.S; - i386_multiboot_startup = kern/i386/coreboot/startup.S; - mips_startup = kern/mips/startup.S; - sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S; - powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S; - arm_uboot_startup = kern/arm/startup.S; - arm_coreboot_startup = kern/arm/startup.S; - arm_efi_startup = kern/arm/efi/startup.S; - arm64_efi_startup = kern/arm64/efi/startup.S; - loongarch64_efi_startup = kern/loongarch64/efi/startup.S; - riscv32_efi_startup = kern/riscv/efi/startup.S; - riscv64_efi_startup = kern/riscv/efi/startup.S; - - common = kern/buffer.c; - common = kern/command.c; - common = kern/corecmd.c; - common = kern/device.c; - common = kern/disk.c; - common = kern/dl.c; - common = kern/env.c; - common = kern/err.c; - common = kern/file.c; - common = kern/fs.c; - common = kern/list.c; - common = kern/main.c; - common = kern/misc.c; - common = kern/parser.c; - common = kern/partition.c; - common = kern/rescue_parser.c; - common = kern/rescue_reader.c; - common = kern/term.c; - common = kern/verifiers.c; - - noemu = kern/compiler-rt.c; - noemu = kern/mm.c; - noemu = kern/time.c; - noemu = kern/generic/millisleep.c; - - noemu_nodist = symlist.c; - - mips = kern/generic/rtc_get_time_ms.c; - - ieee1275 = disk/ieee1275/ofdisk.c; - ieee1275 = kern/ieee1275/cmain.c; - ieee1275 = kern/ieee1275/ieee1275.c; - ieee1275 = kern/ieee1275/mmap.c; - ieee1275 = kern/ieee1275/openfw.c; - ieee1275 = term/ieee1275/console.c; - ieee1275 = kern/ieee1275/init.c; - - uboot = disk/uboot/ubootdisk.c; - uboot = kern/uboot/uboot.c; - uboot = kern/uboot/init.c; - uboot = kern/uboot/hw.c; - uboot = term/uboot/console.c; - arm_uboot = kern/arm/uboot/init.c; - arm_uboot = kern/arm/uboot/uboot.S; - - arm_coreboot = kern/arm/coreboot/init.c; - arm_coreboot = kern/arm/coreboot/timer.c; - arm_coreboot = kern/arm/coreboot/coreboot.S; - arm_coreboot = lib/fdt.c; - arm_coreboot = bus/fdt.c; - arm_coreboot = term/ps2.c; - arm_coreboot = term/arm/pl050.c; - arm_coreboot = term/arm/cros.c; - arm_coreboot = term/arm/cros_ec.c; - arm_coreboot = bus/spi/rk3288_spi.c; - arm_coreboot = commands/keylayouts.c; - arm_coreboot = kern/arm/coreboot/dma.c; - - terminfoinkernel = term/terminfo.c; - terminfoinkernel = term/tparm.c; - terminfoinkernel = commands/extcmd.c; - terminfoinkernel = lib/arg.c; - - softdiv = lib/division.c; - - i386 = kern/i386/dl.c; - i386_xen = kern/i386/dl.c; - i386_xen_pvh = kern/i386/dl.c; - - i386_coreboot = kern/i386/coreboot/init.c; - i386_multiboot = kern/i386/coreboot/init.c; - i386_qemu = kern/i386/qemu/init.c; - i386_coreboot_multiboot_qemu = term/i386/pc/vga_text.c; - coreboot = video/coreboot/cbfb.c; - - efi = disk/efi/efidisk.c; - efi = kern/efi/efi.c; - efi = kern/efi/debug.c; - efi = kern/efi/init.c; - efi = kern/efi/mm.c; - efi = term/efi/console.c; - efi = kern/acpi.c; - efi = kern/efi/acpi.c; - efi = kern/efi/sb.c; - efi = kern/lockdown.c; - i386_coreboot = kern/i386/pc/acpi.c; - i386_multiboot = kern/i386/pc/acpi.c; - i386_coreboot = kern/acpi.c; - i386_multiboot = kern/acpi.c; - - x86 = kern/i386/tsc.c; - x86 = kern/i386/tsc_pit.c; - i386_efi = kern/i386/efi/tsc.c; - x86_64_efi = kern/i386/efi/tsc.c; - i386_efi = kern/i386/tsc_pmtimer.c; - i386_coreboot = kern/i386/tsc_pmtimer.c; - x86_64_efi = kern/i386/tsc_pmtimer.c; - - i386_efi = kern/i386/efi/init.c; - i386_efi = bus/pci.c; - - x86_64 = kern/x86_64/dl.c; - x86_64_xen = kern/x86_64/dl.c; - x86_64_efi = kern/i386/efi/init.c; - x86_64_efi = bus/pci.c; - - xen = kern/i386/tsc.c; - xen = kern/i386/xen/tsc.c; - x86_64_xen = kern/x86_64/xen/hypercall.S; - i386_xen = kern/i386/xen/hypercall.S; - xen = kern/xen/init.c; - xen = term/xen/console.c; - xen = disk/xen/xendisk.c; - xen = commands/boot.c; - - i386_xen_pvh = commands/boot.c; - i386_xen_pvh = disk/xen/xendisk.c; - i386_xen_pvh = kern/i386/tsc.c; - i386_xen_pvh = kern/i386/xen/tsc.c; - i386_xen_pvh = kern/i386/xen/pvh.c; - i386_xen_pvh = kern/xen/init.c; - i386_xen_pvh = term/xen/console.c; - - ia64_efi = kern/ia64/efi/startup.S; - ia64_efi = kern/ia64/efi/init.c; - ia64_efi = kern/ia64/dl.c; - ia64_efi = kern/ia64/dl_helper.c; - ia64_efi = kern/ia64/cache.c; - - arm_efi = kern/arm/efi/init.c; - arm_efi = kern/efi/fdt.c; - - arm64_efi = kern/arm64/efi/init.c; - arm64_efi = kern/efi/fdt.c; - - loongarch64_efi = kern/loongarch64/efi/init.c; - loongarch64_efi = kern/efi/fdt.c; - - riscv32_efi = kern/riscv/efi/init.c; - riscv32_efi = kern/efi/fdt.c; - - riscv64_efi = kern/riscv/efi/init.c; - riscv64_efi = kern/efi/fdt.c; - - i386_pc = kern/i386/pc/init.c; - i386_pc = kern/i386/pc/mmap.c; - i386_pc = term/i386/pc/console.c; - - i386_qemu = bus/pci.c; - i386_qemu = kern/vga_init.c; - i386_qemu = kern/i386/qemu/mmap.c; - - coreboot = kern/coreboot/mmap.c; - i386_coreboot = kern/i386/coreboot/cbtable.c; - coreboot = kern/coreboot/cbtable.c; - arm_coreboot = kern/arm/coreboot/cbtable.c; - - i386_multiboot = kern/i386/multiboot_mmap.c; - - mips = kern/mips/cache.S; - mips = kern/mips/dl.c; - mips = kern/mips/init.c; - - mips_qemu_mips = kern/mips/qemu_mips/init.c; - mips_qemu_mips = term/ns8250.c; - mips_qemu_mips = term/serial.c; - mips_qemu_mips = term/at_keyboard.c; - mips_qemu_mips = term/ps2.c; - mips_qemu_mips = commands/boot.c; - mips_qemu_mips = commands/keylayouts.c; - mips_qemu_mips = term/i386/pc/vga_text.c; - mips_qemu_mips = kern/vga_init.c; - - mips_arc = kern/mips/arc/init.c; - mips_arc = term/arc/console.c; - mips_arc = disk/arc/arcdisk.c; - - mips_loongson = term/ns8250.c; - mips_loongson = bus/bonito.c; - mips_loongson = bus/cs5536.c; - mips_loongson = bus/pci.c; - mips_loongson = kern/mips/loongson/init.c; - mips_loongson = term/at_keyboard.c; - mips_loongson = term/ps2.c; - mips_loongson = commands/boot.c; - mips_loongson = term/serial.c; - mips_loongson = video/sm712.c; - mips_loongson = video/sis315pro.c; - mips_loongson = video/radeon_fuloong2e.c; - mips_loongson = video/radeon_yeeloong3a.c; - extra_dist = video/sm712_init.c; - extra_dist = video/sis315_init.c; - mips_loongson = commands/keylayouts.c; - - powerpc_ieee1275 = kern/powerpc/cache.S; - powerpc_ieee1275 = kern/powerpc/dl.c; - powerpc_ieee1275 = kern/powerpc/compiler-rt.S; - - sparc64_ieee1275 = kern/sparc64/cache.S; - sparc64_ieee1275 = kern/sparc64/dl.c; - sparc64_ieee1275 = kern/sparc64/ieee1275/ieee1275.c; - sparc64_ieee1275 = disk/ieee1275/obdisk.c; - - arm = kern/arm/dl.c; - arm = kern/arm/dl_helper.c; - arm = kern/arm/cache_armv6.S; - arm = kern/arm/cache_armv7.S; - extra_dist = kern/arm/cache.S; - arm = kern/arm/cache.c; - arm = kern/arm/compiler-rt.S; - - arm64 = kern/arm64/cache.c; - arm64 = kern/arm64/cache_flush.S; - arm64 = kern/arm64/dl.c; - arm64 = kern/arm64/dl_helper.c; - - loongarch64 = kern/loongarch64/cache.c; - loongarch64 = kern/loongarch64/cache_flush.S; - loongarch64 = kern/loongarch64/dl.c; - loongarch64 = kern/loongarch64/dl_helper.c; - - riscv32 = kern/riscv/cache.c; - riscv32 = kern/riscv/cache_flush.S; - riscv32 = kern/riscv/dl.c; - - riscv64 = kern/riscv/cache.c; - riscv64 = kern/riscv/cache_flush.S; - riscv64 = kern/riscv/dl.c; - - emu = disk/host.c; - emu = kern/emu/cache_s.S; - emu = kern/emu/hostdisk.c; - emu = osdep/unix/hostdisk.c; - emu = osdep/exec.c; - extra_dist = osdep/unix/exec.c; - emu = osdep/devmapper/hostdisk.c; - emu = osdep/hostdisk.c; - emu = kern/emu/hostfs.c; - emu = kern/emu/main.c; - emu = kern/emu/argp_common.c; - emu = kern/emu/misc.c; - emu = kern/emu/mm.c; - emu = kern/emu/time.c; - emu = kern/emu/cache.c; - emu = osdep/emuconsole.c; - extra_dist = osdep/unix/emuconsole.c; - extra_dist = osdep/windows/emuconsole.c; - emu = osdep/dl.c; - extra_dist = osdep/unix/dl.c; - extra_dist = osdep/windows/dl.c; - emu = osdep/sleep.c; - emu = osdep/init.c; - emu = osdep/emunet.c; - extra_dist = osdep/linux/emunet.c; - extra_dist = osdep/basic/emunet.c; - emu = osdep/cputime.c; - extra_dist = osdep/unix/cputime.c; - extra_dist = osdep/windows/cputime.c; - - videoinkernel = term/gfxterm.c; - videoinkernel = font/font.c; - videoinkernel = font/font_cmd.c; - videoinkernel = io/bufio.c; - videoinkernel = video/fb/fbblit.c; - videoinkernel = video/fb/fbfill.c; - videoinkernel = video/fb/fbutil.c; - videoinkernel = video/fb/video_fb.c; - videoinkernel = video/video.c; - - extra_dist = kern/i386/int.S; - extra_dist = kern/i386/realmode.S; - extra_dist = boot/i386/pc/lzma_decode.S; - extra_dist = kern/mips/cache_flush.S; -}; - -program = { - name = grub-emu; - mansection = 1; - - emu = kern/emu/full.c; - emu_nodist = grub_emu_init.c; - - ldadd = 'kernel.exec$(EXEEXT)'; - ldadd = '$(MODULE_FILES)'; - ldadd = 'lib/gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(SDL2_LIBS) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - - enable = emu; -}; - -program = { - name = grub-emu-lite; - - emu = kern/emu/lite.c; - emu_nodist = symlist.c; - - ldadd = 'kernel.exec$(EXEEXT)'; - ldadd = 'lib/gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(SDL2_LIBS) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - - enable = emu; -}; - -image = { - name = boot; - i386_pc = boot/i386/pc/boot.S; - i386_qemu = boot/i386/qemu/boot.S; - sparc64_ieee1275 = boot/sparc64/ieee1275/boot.S; - - i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00'; - - i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),$(GRUB_BOOT_MACHINE_LINK_ADDR)'; - i386_qemu_ccasflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)'; - - /* The entry point for a.out binaries on sparc64 starts - at 0x4000. Since we are writing the 32 bytes long a.out - header in the assembly code ourselves, we need to tell - the linker to adjust the start of the text segment to - 0x4000 - 0x20 = 0x3fe0. - */ - sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x3fe0'; - sparc64_ieee1275_objcopyflags = '-O binary'; - - objcopyflags = '-O binary'; - enable = i386_pc; - enable = i386_qemu; - enable = sparc64_ieee1275; -}; - -image = { - name = boot_hybrid; - i386_pc = boot/i386/pc/boot.S; - - cppflags = '-DHYBRID_BOOT=1'; - - i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00'; - - objcopyflags = '-O binary'; - enable = i386_pc; -}; - -image = { - name = cdboot; - - i386_pc = boot/i386/pc/cdboot.S; - i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00'; - - sparc64_ieee1275 = boot/sparc64/ieee1275/boot.S; - - /* See comment for sparc64_ieee1275_ldflags above. */ - sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x3fe0'; - sparc64_ieee1275_objcopyflags = '-O binary'; - sparc64_ieee1275_cppflags = '-DCDBOOT=1'; - - objcopyflags = '-O binary'; - - enable = sparc64_ieee1275; - enable = i386_pc; -}; - -image = { - name = pxeboot; - i386_pc = boot/i386/pc/pxeboot.S; - - i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00'; - - objcopyflags = '-O binary'; - enable = i386_pc; -}; - -image = { - name = diskboot; - i386_pc = boot/i386/pc/diskboot.S; - - i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8000'; - - sparc64_ieee1275 = boot/sparc64/ieee1275/diskboot.S; - sparc64_ieee1275_ldflags = '-Wl,-Ttext=0x4200'; - - objcopyflags = '-O binary'; - - enable = i386_pc; - enable = sparc64_ieee1275; -}; - -image = { - name = lnxboot; - i386_pc = boot/i386/pc/lnxboot.S; - - i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x6000'; - - objcopyflags = '-O binary'; - enable = i386_pc; -}; - -image = { - name = xz_decompress; - mips_head = boot/mips/startup_raw.S; - common = boot/decompressor/minilib.c; - common = boot/decompressor/xz.c; - common = lib/xzembed/xz_dec_bcj.c; - common = lib/xzembed/xz_dec_lzma2.c; - common = lib/xzembed/xz_dec_stream.c; - common = kern/compiler-rt.c; - - cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1'; - - objcopyflags = '-O binary'; - mips_ldflags = '-Wl,-Ttext,$(TARGET_DECOMPRESSOR_LINK_ADDR)'; - cflags = '-Wno-unreachable-code'; - enable = mips; -}; - -image = { - name = none_decompress; - mips_head = boot/mips/startup_raw.S; - common = boot/decompressor/none.c; - - cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1'; - - objcopyflags = '-O binary'; - mips_ldflags = '-Wl,-Ttext,$(TARGET_DECOMPRESSOR_LINK_ADDR)'; - enable = mips; -}; - -image = { - name = lzma_decompress; - i386_pc = boot/i386/pc/startup_raw.S; - i386_pc_nodist = rs_decoder.h; - - objcopyflags = '-O binary'; - ldflags = '$(TARGET_IMG_LDFLAGS) $(TARGET_IMG_BASE_LDOPT),0x8200'; - enable = i386_pc; -}; - -image = { - name = fwstart; - mips_loongson = boot/mips/loongson/fwstart.S; - objcopyflags = '-O binary'; - ldflags = '-Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic'; - enable = mips_loongson; -}; - -image = { - name = fwstart_fuloong2f; - mips_loongson = boot/mips/loongson/fuloong2f.S; - objcopyflags = '-O binary'; - ldflags = '-Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic'; - enable = mips_loongson; -}; - -module = { - name = disk; - common = lib/disk.c; - extra_dist = kern/disk_common.c; -}; - -module = { - name = trig; - common_nodist = trigtables.c; - extra_dist = gentrigtables.c; -}; - -module = { - name = cs5536; - x86 = bus/cs5536.c; - enable = x86; -}; - -module = { - name = lsspd; - mips_loongson = commands/mips/loongson/lsspd.c; - enable = mips_loongson; -}; - -module = { - name = usb; - common = bus/usb/usb.c; - common = bus/usb/usbtrans.c; - common = bus/usb/usbhub.c; - enable = usb; -}; - -module = { - name = usbserial_common; - common = bus/usb/serial/common.c; - enable = usb; -}; - -module = { - name = usbserial_pl2303; - common = bus/usb/serial/pl2303.c; - enable = usb; -}; - -module = { - name = usbserial_ftdi; - common = bus/usb/serial/ftdi.c; - enable = usb; -}; - -module = { - name = usbserial_usbdebug; - common = bus/usb/serial/usbdebug_late.c; - enable = usb; -}; - -module = { - name = uhci; - common = bus/usb/uhci.c; - enable = pci; -}; - -module = { - name = ohci; - common = bus/usb/ohci.c; - enable = pci; -}; - -module = { - name = ehci; - common = bus/usb/ehci.c; - arm_coreboot = bus/usb/ehci-fdt.c; - pci = bus/usb/ehci-pci.c; - enable = pci; - enable = arm_coreboot; -}; - -module = { - name = pci; - common = bus/pci.c; - i386_ieee1275 = bus/i386/ieee1275/pci.c; - - enable = i386_pc; - enable = i386_ieee1275; - enable = i386_coreboot; - enable = i386_multiboot; -}; - -module = { - name = nativedisk; - common = commands/nativedisk.c; - - enable = x86; - enable = mips_loongson; - enable = mips_qemu_mips; -}; - -module = { - name = emupci; - common = bus/emu/pci.c; - common = commands/lspci.c; - - enable = emu; - condition = COND_GRUB_EMU_PCI; -}; - -module = { - name = lsdev; - common = commands/arc/lsdev.c; - - enable = mips_arc; -}; - -module = { - name = lsxen; - common = commands/xen/lsxen.c; - - enable = xen; -}; - -module = { - name = cmostest; - common = commands/i386/cmostest.c; - enable = cmos; - enable = i386_efi; - enable = x86_64_efi; -}; - -module = { - name = cmosdump; - common = commands/i386/cmosdump.c; - enable = cmos; - enable = i386_efi; - enable = x86_64_efi; -}; - -module = { - name = iorw; - common = commands/iorw.c; - enable = x86; -}; - -module = { - name = cbtable; - common = kern/i386/coreboot/cbtable.c; - common = kern/coreboot/cbtable.c; - enable = i386_pc; - enable = i386_efi; - enable = i386_qemu; - enable = i386_multiboot; - enable = i386_ieee1275; - enable = x86_64_efi; -}; - -module = { - name = cbtime; - common = commands/i386/coreboot/cb_timestamps.c; - enable = x86; -}; - -module = { - name = cbls; - common = commands/i386/coreboot/cbls.c; - enable = x86; -}; - -module = { - name = cbmemc; - common = term/i386/coreboot/cbmemc.c; - enable = x86; -}; - -module = { - name = regexp; - common = commands/regexp.c; - common = commands/wildcard.c; - common = lib/gnulib/malloc/dynarray_finalize.c; - common = lib/gnulib/malloc/dynarray_emplace_enlarge.c; - common = lib/gnulib/malloc/dynarray_resize.c; - common = lib/gnulib/regex.c; - cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)'; - cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)'; -}; - -module = { - name = acpi; - - common = commands/acpi.c; - i386_pc = kern/acpi.c; - i386_pc = kern/i386/pc/acpi.c; - - enable = efi; - enable = i386_pc; - enable = i386_coreboot; - enable = i386_multiboot; -}; - -module = { - name = lsacpi; - - common = commands/lsacpi.c; - - enable = efi; - enable = i386_pc; - enable = i386_coreboot; - enable = i386_multiboot; -}; - -module = { - name = lsefisystab; - - common = commands/efi/lsefisystab.c; - - enable = efi; -}; - -module = { - name = lssal; - - common = commands/efi/lssal.c; - - enable = efi; -}; - -module = { - name = lsefimmap; - - common = commands/efi/lsefimmap.c; - - enable = efi; -}; - -module = { - name = lsefi; - common = commands/efi/lsefi.c; - enable = efi; -}; - -module = { - name = efifwsetup; - efi = commands/efi/efifwsetup.c; - enable = efi; -}; - -module = { - name = efitextmode; - efi = commands/efi/efitextmode.c; - enable = efi; -}; - -module = { - name = blocklist; - common = commands/blocklist.c; -}; - -module = { - name = boot; - common = commands/boot.c; - i386_pc = lib/i386/pc/biosnum.c; - enable = x86; - enable = emu; - enable = sparc64_ieee1275; - enable = powerpc_ieee1275; - enable = mips_arc; - enable = ia64_efi; - enable = arm_efi; - enable = arm64_efi; - enable = arm_uboot; - enable = arm_coreboot; - enable = loongarch64_efi; - enable = riscv32_efi; - enable = riscv64_efi; -}; - -module = { - name = cat; - common = commands/cat.c; -}; - -module = { - name = cmp; - common = commands/cmp.c; -}; - -module = { - name = configfile; - common = commands/configfile.c; -}; - -module = { - name = cpuid; - common = commands/i386/cpuid.c; - enable = x86; - enable = i386_xen_pvh; - enable = i386_xen; - enable = x86_64_xen; -}; - -module = { - name = date; - common = commands/date.c; -}; - -module = { - name = drivemap; - - i386_pc = commands/i386/pc/drivemap.c; - i386_pc = commands/i386/pc/drivemap_int13h.S; - enable = i386_pc; -}; - -module = { - name = echo; - common = commands/echo.c; -}; - -module = { - name = eval; - common = commands/eval.c; -}; - -module = { - name = extcmd; - common = commands/extcmd.c; - common = lib/arg.c; - enable = terminfomodule; -}; - -module = { - name = fixvideo; - common = commands/efi/fixvideo.c; - enable = i386_efi; - enable = x86_64_efi; -}; - -module = { - name = gptsync; - common = commands/gptsync.c; -}; - -module = { - name = halt; - nopc = commands/halt.c; - i386_pc = commands/i386/pc/halt.c; - i386_pc = commands/acpihalt.c; - i386_coreboot = commands/acpihalt.c; - i386_multiboot = commands/acpihalt.c; - i386_efi = commands/acpihalt.c; - x86_64_efi = commands/acpihalt.c; - i386_multiboot = lib/i386/halt.c; - i386_coreboot = lib/i386/halt.c; - i386_qemu = lib/i386/halt.c; - xen = lib/xen/halt.c; - i386_xen_pvh = lib/xen/halt.c; - efi = lib/efi/halt.c; - ieee1275 = lib/ieee1275/halt.c; - emu = lib/emu/halt.c; - uboot = lib/dummy/halt.c; - arm_coreboot = lib/dummy/halt.c; -}; - -module = { - name = reboot; - i386 = lib/i386/reboot.c; - i386 = lib/i386/reboot_trampoline.S; - powerpc_ieee1275 = lib/ieee1275/reboot.c; - sparc64_ieee1275 = lib/ieee1275/reboot.c; - mips_arc = lib/mips/arc/reboot.c; - mips_loongson = lib/mips/loongson/reboot.c; - mips_qemu_mips = lib/mips/qemu_mips/reboot.c; - xen = lib/xen/reboot.c; - i386_xen_pvh = lib/xen/reboot.c; - uboot = lib/uboot/reboot.c; - arm_coreboot = lib/dummy/reboot.c; - common = commands/reboot.c; -}; - -module = { - name = hashsum; - common = commands/hashsum.c; -}; - -module = { - name = pgp; - common = commands/pgp.c; - cflags = '$(CFLAGS_POSIX)'; - cppflags = '-I$(srcdir)/lib/posix_wrap'; -}; - -module = { - name = hdparm; - common = commands/hdparm.c; - enable = pci; - enable = mips_qemu_mips; -}; - -module = { - name = help; - common = commands/help.c; -}; - -module = { - name = hexdump; - common = commands/hexdump.c; - common = lib/hexdump.c; -}; - -module = { - name = keystatus; - common = commands/keystatus.c; -}; - -module = { - name = loadbios; - common = commands/efi/loadbios.c; - enable = i386_efi; - enable = x86_64_efi; -}; - -module = { - name = loadenv; - common = commands/loadenv.c; - common = lib/envblk.c; -}; - -module = { - name = ls; - common = commands/ls.c; -}; - -module = { - name = lsmmap; - common = commands/lsmmap.c; -}; - -module = { - name = lspci; - common = commands/lspci.c; - - enable = pci; -}; - -module = { - name = memrw; - common = commands/memrw.c; -}; - -module = { - name = minicmd; - common = commands/minicmd.c; -}; - -module = { - name = parttool; - common = commands/parttool.c; -}; - -module = { - name = password; - common = commands/password.c; -}; - -module = { - name = password_pbkdf2; - common = commands/password_pbkdf2.c; -}; - -module = { - name = play; - x86 = commands/i386/pc/play.c; - enable = x86; -}; - -module = { - name = spkmodem; - x86 = term/spkmodem.c; - enable = x86; -}; - -module = { - name = morse; - x86 = term/morse.c; - enable = x86; -}; - -module = { - name = probe; - common = commands/probe.c; -}; - -module = { - name = read; - common = commands/read.c; -}; - -module = { - name = search; - common = commands/search_wrap.c; - extra_dist = commands/search.c; -}; - -module = { - name = search_fs_file; - common = commands/search_file.c; -}; - -module = { - name = search_fs_uuid; - common = commands/search_uuid.c; -}; - -module = { - name = search_label; - common = commands/search_label.c; -}; - -module = { - name = setpci; - common = commands/setpci.c; - enable = pci; -}; - -module = { - name = pcidump; - common = commands/pcidump.c; - enable = pci; -}; - -module = { - name = sleep; - common = commands/sleep.c; -}; - -module = { - name = smbios; - - common = commands/smbios.c; - efi = commands/efi/smbios.c; - i386_pc = commands/i386/pc/smbios.c; - i386_coreboot = commands/i386/pc/smbios.c; - i386_multiboot = commands/i386/pc/smbios.c; - - enable = efi; - enable = i386_pc; - enable = i386_coreboot; - enable = i386_multiboot; -}; - -module = { - name = suspend; - ieee1275 = commands/ieee1275/suspend.c; - enable = i386_ieee1275; - enable = powerpc_ieee1275; -}; - -module = { - name = escc; - ieee1275 = term/ieee1275/escc.c; - enable = powerpc_ieee1275; -}; - -module = { - name = tpm; - common = commands/tpm.c; - ieee1275 = commands/ieee1275/ibmvtpm.c; - enable = powerpc_ieee1275; -}; - -module = { - name = terminal; - common = commands/terminal.c; -}; - -module = { - name = test; - common = commands/test.c; -}; - -module = { - name = true; - common = commands/true.c; -}; - -module = { - name = usbtest; - common = commands/usbtest.c; - enable = usb; -}; - -module = { - name = videoinfo; - common = commands/videoinfo.c; -}; - -module = { - name = videotest; - common = commands/videotest.c; -}; - -module = { - name = xnu_uuid; - common = commands/xnu_uuid.c; -}; - -module = { - name = dm_nv; - common = disk/dmraid_nvidia.c; -}; - -module = { - name = loopback; - common = disk/loopback.c; -}; - -module = { - name = cryptodisk; - common = disk/cryptodisk.c; -}; - -module = { - name = plainmount; - common = disk/plainmount.c; -}; - -module = { - name = json; - common = lib/json/json.c; -}; - -module = { - name = afsplitter; - common = disk/AFSplitter.c; -}; - -module = { - name = luks; - common = disk/luks.c; -}; - -module = { - name = luks2; - common = disk/luks2.c; - common = lib/gnulib/base64.c; - cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)'; - cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB) -I$(srcdir)/lib/json'; -}; - -module = { - name = geli; - common = disk/geli.c; -}; - -module = { - name = lvm; - common = disk/lvm.c; -}; - -module = { - name = ldm; - common = disk/ldm.c; -}; - -module = { - name = mdraid09; - common = disk/mdraid_linux.c; -}; - -module = { - name = mdraid09_be; - common = disk/mdraid_linux_be.c; -}; - -module = { - name = mdraid1x; - common = disk/mdraid1x_linux.c; -}; - -module = { - name = diskfilter; - common = disk/diskfilter.c; -}; - -module = { - name = raid5rec; - common = disk/raid5_recover.c; -}; - -module = { - name = raid6rec; - common = disk/raid6_recover.c; -}; - -module = { - name = key_protector; - common = disk/key_protector.c; -}; - -module = { - name = scsi; - common = disk/scsi.c; -}; - -module = { - name = memdisk; - common = disk/memdisk.c; -}; - -module = { - name = ata; - common = disk/ata.c; - enable = pci; - enable = mips_qemu_mips; -}; - -module = { - name = ahci; - common = disk/ahci.c; - enable = pci; -}; - -module = { - name = pata; - common = disk/pata.c; - enable = pci; - enable = mips_qemu_mips; -}; - -module = { - name = biosdisk; - i386_pc = disk/i386/pc/biosdisk.c; - enable = i386_pc; -}; - -module = { - name = usbms; - common = disk/usbms.c; - enable = usb; -}; - -module = { - name = nand; - ieee1275 = disk/ieee1275/nand.c; - enable = i386_ieee1275; -}; - -module = { - name = efiemu; - common = efiemu/main.c; - common = efiemu/i386/loadcore32.c; - common = efiemu/i386/loadcore64.c; - i386_pc = efiemu/i386/pc/cfgtables.c; - i386_coreboot = efiemu/i386/pc/cfgtables.c; - i386_multiboot = efiemu/i386/pc/cfgtables.c; - i386_ieee1275 = efiemu/i386/nocfgtables.c; - i386_qemu = efiemu/i386/nocfgtables.c; - common = efiemu/mm.c; - common = efiemu/loadcore_common.c; - common = efiemu/symbols.c; - common = efiemu/loadcore32.c; - common = efiemu/loadcore64.c; - common = efiemu/prepare32.c; - common = efiemu/prepare64.c; - common = efiemu/pnvram.c; - common = efiemu/i386/coredetect.c; - - extra_dist = efiemu/prepare.c; - extra_dist = efiemu/loadcore.c; - extra_dist = efiemu/runtime/efiemu.S; - extra_dist = efiemu/runtime/efiemu.c; - - enable = i386_pc; - enable = i386_coreboot; - enable = i386_ieee1275; - enable = i386_multiboot; - enable = i386_qemu; -}; - -module = { - name = font; - common = font/font.c; - common = font/font_cmd.c; - enable = videomodules; -}; - -module = { - name = procfs; - common = fs/proc.c; -}; - -module = { - name = affs; - common = fs/affs.c; -}; - -module = { - name = afs; - common = fs/afs.c; -}; - -module = { - name = bfs; - common = fs/bfs.c; -}; - -module = { - name = zstd; - common = lib/zstd/debug.c; - common = lib/zstd/entropy_common.c; - common = lib/zstd/error_private.c; - common = lib/zstd/fse_decompress.c; - common = lib/zstd/huf_decompress.c; - common = lib/zstd/module.c; - common = lib/zstd/xxhash.c; - common = lib/zstd/zstd_common.c; - common = lib/zstd/zstd_decompress.c; - cflags = '$(CFLAGS_POSIX) -Wno-undef'; - cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/zstd'; -}; - -module = { - name = btrfs; - common = fs/btrfs.c; - common = lib/crc.c; - cflags = '$(CFLAGS_POSIX) -Wno-undef'; - cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -I$(srcdir)/lib/zstd -DMINILZO_HAVE_CONFIG_H'; -}; - -module = { - name = archelp; - common = fs/archelp.c; -}; - -module = { - name = cbfs; - common = fs/cbfs.c; -}; - -module = { - name = cpio; - common = fs/cpio.c; -}; - -module = { - name = cpio_be; - common = fs/cpio_be.c; -}; - -module = { - name = newc; - common = fs/newc.c; -}; - -module = { - name = odc; - common = fs/odc.c; -}; - -module = { - name = erofs; - common = fs/erofs.c; -}; - -module = { - name = ext2; - common = fs/ext2.c; -}; - -module = { - name = fat; - common = fs/fat.c; -}; - -module = { - name = exfat; - common = fs/exfat.c; -}; - -module = { - name = f2fs; - common = fs/f2fs.c; -}; - -module = { - name = fshelp; - common = fs/fshelp.c; -}; - -module = { - name = hfs; - common = fs/hfs.c; -}; - -module = { - name = hfsplus; - common = fs/hfsplus.c; -}; - -module = { - name = hfspluscomp; - common = fs/hfspluscomp.c; -}; - -module = { - name = iso9660; - common = fs/iso9660.c; -}; - -module = { - name = jfs; - common = fs/jfs.c; -}; - -module = { - name = minix; - common = fs/minix.c; -}; - -module = { - name = minix2; - common = fs/minix2.c; -}; - -module = { - name = minix3; - common = fs/minix3.c; -}; - -module = { - name = minix_be; - common = fs/minix_be.c; -}; - -module = { - name = minix2_be; - common = fs/minix2_be.c; -}; - -module = { - name = minix3_be; - common = fs/minix3_be.c; -}; - -module = { - name = nilfs2; - common = fs/nilfs2.c; -}; - -module = { - name = ntfs; - common = fs/ntfs.c; -}; - -module = { - name = ntfscomp; - common = fs/ntfscomp.c; -}; - -module = { - name = reiserfs; - common = fs/reiserfs.c; -}; - -module = { - name = romfs; - common = fs/romfs.c; -}; - -module = { - name = sfs; - common = fs/sfs.c; -}; - -module = { - name = squash4; - common = fs/squash4.c; - cflags = '$(CFLAGS_POSIX) -Wno-undef'; - cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; -}; - -module = { - name = tar; - common = fs/tar.c; -}; - -module = { - name = udf; - common = fs/udf.c; -}; - -module = { - name = ufs1; - common = fs/ufs.c; -}; - -module = { - name = ufs1_be; - common = fs/ufs_be.c; -}; - -module = { - name = ufs2; - common = fs/ufs2.c; -}; - -module = { - name = xfs; - common = fs/xfs.c; -}; - -module = { - name = zfs; - common = fs/zfs/zfs.c; - common = fs/zfs/zfs_lzjb.c; - common = fs/zfs/zfs_lz4.c; - common = fs/zfs/zfs_sha256.c; - common = fs/zfs/zfs_fletcher.c; - cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/zstd'; -}; - -module = { - name = zfscrypt; - common = fs/zfs/zfscrypt.c; -}; - -module = { - name = zfsinfo; - common = fs/zfs/zfsinfo.c; -}; - -module = { - name = macbless; - common = commands/macbless.c; -}; - -module = { - name = pxe; - i386_pc = net/drivers/i386/pc/pxe.c; - enable = i386_pc; -}; - -module = { - name = gettext; - common = gettext/gettext.c; -}; - -module = { - name = gfxmenu; - common = gfxmenu/gfxmenu.c; - common = gfxmenu/view.c; - common = gfxmenu/font.c; - common = gfxmenu/icon_manager.c; - common = gfxmenu/theme_loader.c; - common = gfxmenu/widget-box.c; - common = gfxmenu/gui_canvas.c; - common = gfxmenu/gui_circular_progress.c; - common = gfxmenu/gui_box.c; - common = gfxmenu/gui_label.c; - common = gfxmenu/gui_list.c; - common = gfxmenu/gui_image.c; - common = gfxmenu/gui_progress_bar.c; - common = gfxmenu/gui_util.c; - common = gfxmenu/gui_string_util.c; -}; - -module = { - name = hello; - common = hello/hello.c; -}; - -module = { - name = gzio; - common = io/gzio.c; -}; - -module = { - name = offsetio; - common = io/offset.c; -}; - -module = { - name = bufio; - common = io/bufio.c; - enable = videomodules; -}; - -module = { - name = elf; - common = kern/elf.c; - - extra_dist = kern/elfXX.c; -}; - -module = { - name = crypto; - common = lib/crypto.c; - - extra_dist = lib/libgcrypt-grub/cipher/crypto.lst; -}; - -module = { - name = pbkdf2; - common = lib/pbkdf2.c; -}; - -module = { - name = relocator; - common = lib/relocator.c; - x86 = lib/i386/relocator16.S; - x86 = lib/i386/relocator32.S; - x86 = lib/i386/relocator64.S; - i386_xen_pvh = lib/i386/relocator16.S; - i386_xen_pvh = lib/i386/relocator32.S; - i386_xen_pvh = lib/i386/relocator64.S; - i386 = lib/i386/relocator_asm.S; - i386_xen_pvh = lib/i386/relocator_asm.S; - x86_64 = lib/x86_64/relocator_asm.S; - i386_xen = lib/i386/relocator_asm.S; - x86_64_xen = lib/x86_64/relocator_asm.S; - x86 = lib/i386/relocator.c; - x86 = lib/i386/relocator_common_c.c; - i386_xen_pvh = lib/i386/relocator.c; - i386_xen_pvh = lib/i386/relocator_common_c.c; - ieee1275 = lib/ieee1275/relocator.c; - efi = lib/efi/relocator.c; - mips = lib/mips/relocator_asm.S; - mips = lib/mips/relocator.c; - powerpc = lib/powerpc/relocator_asm.S; - powerpc = lib/powerpc/relocator.c; - xen = lib/xen/relocator.c; - i386_xen = lib/i386/xen/relocator.S; - x86_64_xen = lib/x86_64/xen/relocator.S; - xen = lib/i386/relocator_common_c.c; - x86_64_efi = lib/x86_64/efi/relocator.c; - - extra_dist = lib/i386/relocator_common.S; - extra_dist = kern/powerpc/cache_flush.S; - - enable = mips; - enable = powerpc; - enable = x86; - enable = i386_xen_pvh; - enable = xen; -}; - -module = { - name = datetime; - common = lib/datetime.c; - cmos = lib/cmos_datetime.c; - efi = lib/efi/datetime.c; - uboot = lib/dummy/datetime.c; - arm_coreboot = lib/dummy/datetime.c; - sparc64_ieee1275 = lib/ieee1275/datetime.c; - powerpc_ieee1275 = lib/ieee1275/datetime.c; - sparc64_ieee1275 = lib/ieee1275/cmos.c; - powerpc_ieee1275 = lib/ieee1275/cmos.c; - xen = lib/xen/datetime.c; - i386_xen_pvh = lib/xen/datetime.c; - - mips_arc = lib/arc/datetime.c; -}; - -module = { - name = setjmp; - common = lib/setjmp.S; - extra_dist = lib/i386/setjmp.S; - extra_dist = lib/mips/setjmp.S; - extra_dist = lib/x86_64/setjmp.S; - extra_dist = lib/sparc64/setjmp.S; - extra_dist = lib/powerpc/setjmp.S; - extra_dist = lib/ia64/setjmp.S; - extra_dist = lib/ia64/longjmp.S; - extra_dist = lib/arm/setjmp.S; - extra_dist = lib/arm64/setjmp.S; - extra_dist = lib/riscv/setjmp.S; - extra_dist = lib/loongarch64/setjmp.S; -}; - -module = { - name = aout; - common = loader/aout.c; - enable = x86; -}; - -module = { - name = bsd; - x86 = loader/i386/bsd.c; - x86 = loader/i386/bsd32.c; - x86 = loader/i386/bsd64.c; - - extra_dist = loader/i386/bsdXX.c; - extra_dist = loader/i386/bsd_pagetable.c; - - enable = x86; -}; - -module = { - name = plan9; - i386_pc = loader/i386/pc/plan9.c; - enable = i386_pc; -}; - - -module = { - name = linux16; - common = loader/i386/pc/linux.c; - enable = x86; -}; - -module = { - name = ntldr; - i386_pc = loader/i386/pc/ntldr.c; - enable = i386_pc; -}; - - -module = { - name = truecrypt; - i386_pc = loader/i386/pc/truecrypt.c; - enable = i386_pc; -}; - - -module = { - name = freedos; - i386_pc = loader/i386/pc/freedos.c; - enable = i386_pc; -}; - -module = { - name = pxechain; - i386_pc = loader/i386/pc/pxechainloader.c; - enable = i386_pc; -}; - -module = { - name = multiboot2; - cppflags = "-DGRUB_USE_MULTIBOOT2"; - - common = loader/multiboot.c; - common = loader/multiboot_mbi2.c; - enable = x86; - enable = i386_xen_pvh; - enable = mips; -}; - -module = { - name = multiboot; - common = loader/multiboot.c; - x86 = loader/i386/multiboot_mbi.c; - i386_xen_pvh = loader/i386/multiboot_mbi.c; - extra_dist = loader/multiboot_elfxx.c; - enable = x86; - enable = i386_xen_pvh; -}; - -module = { - name = xen_boot; - arm64 = loader/arm64/xen_boot.c; - enable = arm64; -}; - -module = { - name = linux; - x86 = loader/i386/linux.c; - i386_xen_pvh = loader/i386/linux.c; - xen = loader/i386/xen.c; - i386_pc = lib/i386/pc/vesa_modes_table.c; - i386_xen_pvh = lib/i386/pc/vesa_modes_table.c; - mips = loader/mips/linux.c; - powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c; - sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c; - ia64_efi = loader/ia64/efi/linux.c; - arm_coreboot = loader/arm/linux.c; - arm_efi = loader/efi/linux.c; - arm_uboot = loader/arm/linux.c; - arm64 = loader/efi/linux.c; - loongarch64 = loader/efi/linux.c; - riscv32 = loader/efi/linux.c; - riscv64 = loader/efi/linux.c; - i386_efi = loader/efi/linux.c; - x86_64_efi = loader/efi/linux.c; - emu = loader/emu/linux.c; - common = loader/linux.c; - common = lib/cmdline.c; -}; - -module = { - name = fdt; - efi = loader/efi/fdt.c; - common = lib/fdt.c; - enable = fdt; -}; - -module = { - name = xnu; - x86 = loader/xnu_resume.c; - x86 = loader/i386/xnu.c; - x86 = loader/xnu.c; - - /* Code is pretty generic but relies on RNG which - is available only on few platforms. It's not a - big deal as xnu needs ACPI anyway and we have - RNG on all platforms with ACPI. - */ - enable = i386_multiboot; - enable = i386_coreboot; - enable = i386_pc; - enable = i386_efi; - enable = x86_64_efi; -}; - -module = { - name = random; - x86 = lib/i386/random.c; - common = lib/random.c; - - i386_multiboot = kern/i386/tsc_pmtimer.c; - i386_coreboot = kern/i386/tsc_pmtimer.c; - i386_pc = kern/i386/tsc_pmtimer.c; - - enable = i386_multiboot; - enable = i386_coreboot; - enable = i386_pc; - enable = i386_efi; - enable = x86_64_efi; -}; - -module = { - name = macho; - - common = loader/macho.c; - common = loader/macho32.c; - common = loader/macho64.c; - common = loader/lzss.c; - extra_dist = loader/machoXX.c; -}; - -module = { - name = appleldr; - common = loader/efi/appleloader.c; - enable = i386_efi; - enable = x86_64_efi; -}; - -module = { - name = chain; - efi = loader/efi/chainloader.c; - i386_pc = loader/i386/pc/chainloader.c; - i386_coreboot = loader/i386/coreboot/chainloader.c; - i386_coreboot = lib/LzmaDec.c; - enable = i386_pc; - enable = i386_coreboot; - enable = efi; -}; - -module = { - name = mmap; - common = mmap/mmap.c; - x86 = mmap/i386/uppermem.c; - x86 = mmap/i386/mmap.c; - i386_xen_pvh = mmap/i386/uppermem.c; - i386_xen_pvh = mmap/i386/mmap.c; - - i386_pc = mmap/i386/pc/mmap.c; - i386_pc = mmap/i386/pc/mmap_helper.S; - - efi = mmap/efi/mmap.c; - - mips = mmap/mips/uppermem.c; - - enable = x86; - enable = i386_xen_pvh; - enable = ia64_efi; - enable = arm_efi; - enable = arm64_efi; - enable = loongarch64_efi; - enable = riscv32_efi; - enable = riscv64_efi; - enable = mips; -}; - -module = { - name = normal; - common = normal/main.c; - common = normal/cmdline.c; - common = normal/dyncmd.c; - common = normal/auth.c; - common = normal/autofs.c; - common = normal/color.c; - common = normal/completion.c; - common = normal/menu.c; - common = normal/menu_entry.c; - common = normal/menu_text.c; - common = normal/misc.c; - common = normal/crypto.c; - common = normal/term.c; - common = normal/context.c; - common = normal/charset.c; - common = lib/getline.c; - - common = script/main.c; - common = script/script.c; - common = script/execute.c; - common = script/function.c; - common = script/lexer.c; - common = script/argv.c; - - common = commands/menuentry.c; - - common = unidata.c; - common_nodist = grub_script.tab.c; - common_nodist = grub_script.yy.c; - common_nodist = grub_script.tab.h; - common_nodist = grub_script.yy.h; - - extra_dist = script/yylex.l; - extra_dist = script/parser.y; - - cflags = '$(CFLAGS_POSIX) -Wno-redundant-decls -Wno-unused-but-set-variable'; - cppflags = '$(CPPFLAGS_POSIX)'; -}; - -module = { - name = part_acorn; - common = partmap/acorn.c; -}; - -module = { - name = part_amiga; - common = partmap/amiga.c; -}; - -module = { - name = part_apple; - common = partmap/apple.c; -}; - -module = { - name = part_gpt; - common = partmap/gpt.c; -}; - -module = { - name = part_msdos; - common = partmap/msdos.c; -}; - -module = { - name = part_sun; - common = partmap/sun.c; -}; - -module = { - name = part_plan; - common = partmap/plan.c; -}; - -module = { - name = part_dvh; - common = partmap/dvh.c; -}; - -module = { - name = part_bsd; - common = partmap/bsdlabel.c; -}; - -module = { - name = part_sunpc; - common = partmap/sunpc.c; -}; - -module = { - name = part_dfly; - common = partmap/dfly.c; -}; - -module = { - name = msdospart; - common = parttool/msdospart.c; -}; - -module = { - name = at_keyboard; - common = term/at_keyboard.c; - common = term/ps2.c; - enable = x86; -}; - -module = { - name = gfxterm; - common = term/gfxterm.c; - enable = videomodules; -}; - -module = { - name = gfxterm_background; - common = term/gfxterm_background.c; -}; - -module = { - name = serial; - common = term/serial.c; - x86 = term/ns8250.c; - x86 = term/ns8250-spcr.c; - ieee1275 = term/ieee1275/serial.c; - mips_arc = term/arc/serial.c; - efi = term/efi/serial.c; - x86 = term/pci/serial.c; - - enable = terminfomodule; - enable = ieee1275; - enable = mips_arc; -}; - -module = { - name = sendkey; - i386_pc = commands/i386/pc/sendkey.c; - enable = i386_pc; -}; - -module = { - name = terminfo; - common = term/terminfo.c; - common = term/tparm.c; - enable = terminfomodule; -}; - -module = { - name = usb_keyboard; - common = term/usb_keyboard.c; - enable = usb; -}; - -module = { - name = vga; - common = video/i386/pc/vga.c; - enable = i386_pc; -}; - -module = { - name = vga_text; - common = term/i386/pc/vga_text.c; - enable = i386_pc; -}; - -module = { - name = mda_text; - common = term/i386/pc/mda_text.c; - enable = i386_pc; - enable = i386_coreboot_multiboot_qemu; -}; - -module = { - name = video_cirrus; - x86 = video/cirrus.c; - enable = x86; -}; - -module = { - name = video_bochs; - x86 = video/bochs.c; - enable = x86; -}; - -module = { - name = functional_test; - common = tests/lib/functional_test.c; - common = tests/lib/test.c; - common = tests/checksums.h; - common = tests/video_checksum.c; - common = tests/fake_input.c; - common = video/capture.c; -}; - -module = { - name = exfctest; - common = tests/example_functional_test.c; -}; - -module = { - name = strtoull_test; - common = tests/strtoull_test.c; -}; - -module = { - name = setjmp_test; - common = tests/setjmp_test.c; -}; - -module = { - name = signature_test; - common = tests/signature_test.c; - common = tests/signatures.h; -}; - -module = { - name = sleep_test; - common = tests/sleep_test.c; -}; - -module = { - name = xnu_uuid_test; - common = tests/xnu_uuid_test.c; -}; - -module = { - name = pbkdf2_test; - common = tests/pbkdf2_test.c; -}; - -module = { - name = legacy_password_test; - common = tests/legacy_password_test.c; - enable = i386_pc; - enable = i386_xen_pvh; - enable = i386_efi; - enable = x86_64_efi; - enable = emu; - enable = xen; -}; - -module = { - name = div; - common = lib/division.c; - enable = no_softdiv; -}; - -module = { - name = div_test; - common = tests/div_test.c; -}; - -module = { - name = mul_test; - common = tests/mul_test.c; -}; - -module = { - name = shift_test; - common = tests/shift_test.c; -}; - -module = { - name = cmp_test; - common = tests/cmp_test.c; -}; - -module = { - name = ctz_test; - common = tests/ctz_test.c; -}; - -module = { - name = bswap_test; - common = tests/bswap_test.c; -}; - -module = { - name = videotest_checksum; - common = tests/videotest_checksum.c; -}; - -/* - * These tests fail depending on the version of unifont. As we don't distribute - * our own unifont it fails for most users. Disable them so that they don't mask - * real failures. They can be reinstated once we solve unifont problem. -module = { - name = gfxterm_menu; - common = tests/gfxterm_menu.c; -}; - -module = { - name = cmdline_cat_test; - common = tests/cmdline_cat_test.c; -}; - */ - -module = { - name = bitmap; - common = video/bitmap.c; -}; - -module = { - name = bitmap_scale; - common = video/bitmap_scale.c; -}; - -module = { - name = efi_gop; - efi = video/efi_gop.c; - enable = efi; -}; - -module = { - name = efi_uga; - efi = video/efi_uga.c; - enable = i386_efi; - enable = x86_64_efi; -}; - -module = { - name = jpeg; - common = video/readers/jpeg.c; -}; - -module = { - name = png; - common = video/readers/png.c; -}; - -module = { - name = tga; - common = video/readers/tga.c; -}; - -module = { - name = vbe; - common = video/i386/pc/vbe.c; - enable = i386_pc; -}; - -module = { - name = video_fb; - common = video/fb/video_fb.c; - common = video/fb/fbblit.c; - common = video/fb/fbfill.c; - common = video/fb/fbutil.c; - enable = videomodules; -}; - -module = { - name = video; - common = video/video.c; - enable = videomodules; -}; - -module = { - name = video_colors; - common = video/colors.c; -}; - -module = { - name = ieee1275_fb; - ieee1275 = video/ieee1275.c; - enable = powerpc_ieee1275; -}; - -module = { - name = sdl; - emu = video/emu/sdl.c; - enable = emu; - condition = COND_GRUB_EMU_SDL; -}; - -module = { - name = sdl; - emu = video/emu/sdl.c; - enable = emu; - condition = COND_GRUB_EMU_SDL2; - cflags = '$(SDL2_CFLAGS)'; -}; - -module = { - name = datehook; - common = hook/datehook.c; -}; - -module = { - name = net; - common = net/net.c; - common = net/dns.c; - common = net/bootp.c; - common = net/ip.c; - common = net/udp.c; - common = net/tcp.c; - common = net/icmp.c; - common = net/icmp6.c; - common = net/ethernet.c; - common = net/arp.c; - common = net/netbuff.c; -}; - -module = { - name = tftp; - common = net/tftp.c; -}; - -module = { - name = http; - common = net/http.c; -}; - -module = { - name = ofnet; - common = net/drivers/ieee1275/ofnet.c; - enable = ieee1275; -}; - -module = { - name = ubootnet; - common = net/drivers/uboot/ubootnet.c; - enable = uboot; -}; - -module = { - name = efinet; - common = net/drivers/efi/efinet.c; - enable = efi; -}; - -module = { - name = emunet; - emu = net/drivers/emu/emunet.c; - enable = emu; -}; - -module = { - name = legacycfg; - common = commands/legacycfg.c; - common = lib/legacy_parse.c; - emu = lib/i386/pc/vesa_modes_table.c; - i386_efi = lib/i386/pc/vesa_modes_table.c; - x86_64_efi = lib/i386/pc/vesa_modes_table.c; - xen = lib/i386/pc/vesa_modes_table.c; - - enable = i386_pc; - enable = i386_xen_pvh; - enable = i386_efi; - enable = x86_64_efi; - enable = emu; - enable = xen; -}; - -module = { - name = syslinuxcfg; - common = lib/syslinux_parse.c; - common = commands/syslinuxcfg.c; -}; - -module = { - name = test_blockarg; - common = tests/test_blockarg.c; -}; - -module = { - name = xzio; - common = io/xzio.c; - common = lib/xzembed/xz_dec_bcj.c; - common = lib/xzembed/xz_dec_lzma2.c; - common = lib/xzembed/xz_dec_stream.c; - cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed'; - cflags='-Wno-unreachable-code'; -}; - -module = { - name = lzopio; - common = io/lzopio.c; - common = lib/minilzo/minilzo.c; - cflags = '$(CFLAGS_POSIX) -Wno-undef -Wno-redundant-decls -Wno-error'; - cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; -}; - -module = { - name = testload; - common = commands/testload.c; -}; - -module = { - name = backtrace; - x86 = lib/i386/backtrace.c; - i386_xen_pvh = lib/i386/backtrace.c; - i386_xen = lib/i386/backtrace.c; - x86_64_xen = lib/i386/backtrace.c; - common = lib/backtrace.c; - enable = x86; - enable = i386_xen_pvh; - enable = i386_xen; - enable = x86_64_xen; -}; - -module = { - name = lsapm; - common = commands/i386/pc/lsapm.c; - enable = i386_pc; -}; - -module = { - name = keylayouts; - common = commands/keylayouts.c; - enable = x86; -}; - -module = { - name = priority_queue; - common = lib/priority_queue.c; -}; - -module = { - name = time; - common = commands/time.c; -}; - -module = { - name = cacheinfo; - common = commands/cacheinfo.c; - condition = COND_ENABLE_CACHE_STATS; -}; - -module = { - name = boottime; - common = commands/boottime.c; - condition = COND_ENABLE_BOOT_TIME_STATS; -}; - -module = { - name = adler32; - common = lib/adler32.c; -}; - -module = { - name = crc64; - common = lib/crc64.c; -}; - -module = { - name = mpi; - common = lib/libgcrypt-grub/mpi/mpiutil.c; - common = lib/libgcrypt-grub/mpi/mpi-bit.c; - common = lib/libgcrypt-grub/mpi/mpi-add.c; - common = lib/libgcrypt-grub/mpi/mpi-mul.c; - common = lib/libgcrypt-grub/mpi/mpi-mod.c; - common = lib/libgcrypt-grub/mpi/mpi-gcd.c; - common = lib/libgcrypt-grub/mpi/mpi-div.c; - common = lib/libgcrypt-grub/mpi/mpi-cmp.c; - common = lib/libgcrypt-grub/mpi/mpi-inv.c; - common = lib/libgcrypt-grub/mpi/mpi-pow.c; - common = lib/libgcrypt-grub/mpi/mpi-mpow.c; - common = lib/libgcrypt-grub/mpi/mpih-lshift.c; - common = lib/libgcrypt-grub/mpi/mpih-mul.c; - common = lib/libgcrypt-grub/mpi/mpih-mul1.c; - common = lib/libgcrypt-grub/mpi/mpih-mul2.c; - common = lib/libgcrypt-grub/mpi/mpih-mul3.c; - common = lib/libgcrypt-grub/mpi/mpih-add1.c; - common = lib/libgcrypt-grub/mpi/mpih-sub1.c; - common = lib/libgcrypt-grub/mpi/mpih-div.c; - common = lib/libgcrypt-grub/mpi/mpicoder.c; - common = lib/libgcrypt-grub/mpi/mpih-rshift.c; - common = lib/libgcrypt-grub/mpi/mpi-inline.c; - common = lib/libgcrypt_wrap/mem.c; - - cflags = '$(CFLAGS_GCRY) -Wno-redundant-decls -Wno-sign-compare'; - cppflags = '$(CPPFLAGS_GCRY)'; -}; - -module = { - name = all_video; - common = lib/fake_module.c; -}; - -module = { - name = gdb; - common = gdb/cstub.c; - common = gdb/gdb.c; - i386 = gdb/i386/idt.c; - i386 = gdb/i386/machdep.S; - i386 = gdb/i386/signal.c; - enable = i386; -}; - -module = { - name = testspeed; - common = commands/testspeed.c; -}; - -module = { - name = tpm; - common = commands/tpm.c; - efi = commands/efi/tpm.c; - enable = efi; -}; - -module = { - name = tss2; - common = lib/tss2/buffer.c; - common = lib/tss2/tss2_mu.c; - common = lib/tss2/tpm2_cmd.c; - common = lib/tss2/tss2.c; - efi = lib/efi/tcg2.c; - emu = lib/tss2/tcg2_emu.c; - powerpc_ieee1275 = lib/ieee1275/tcg2.c; - enable = efi; - enable = emu; - enable = powerpc_ieee1275; - cppflags = '-I$(srcdir)/lib/tss2'; -}; - -module = { - name = tpm2_key_protector; - common = commands/tpm2_key_protector/args.c; - common = commands/tpm2_key_protector/module.c; - common = commands/tpm2_key_protector/tpm2key.c; - common = commands/tpm2_key_protector/tpm2key_asn1_tab.c; - /* The plaform support of tpm2_key_protector depends on the tcg2 implementation in tss2. */ - enable = efi; - enable = emu; - enable = powerpc_ieee1275; - cppflags = '-I$(srcdir)/lib/tss2 -I$(srcdir)/lib/libtasn1-grub'; -}; - -module = { - name = tr; - common = commands/tr.c; -}; - -module = { - name = progress; - common = lib/progress.c; -}; - -module = { - name = file; - common = commands/file.c; - common = commands/file32.c; - common = commands/file64.c; - extra_dist = commands/fileXX.c; - common = loader/i386/xen_file.c; - common = loader/i386/xen_file32.c; - common = loader/i386/xen_file64.c; - extra_dist = loader/i386/xen_fileXX.c; -}; -module = { - name = rdmsr; - common = commands/i386/rdmsr.c; - enable = x86; -}; -module = { - name = wrmsr; - common = commands/i386/wrmsr.c; - enable = x86; -}; - -module = { - name = memtools; - common = commands/memtools.c; - condition = COND_MM_DEBUG; -}; - -module = { - name = bli; - efi = commands/bli.c; - enable = efi; - depends = part_gpt; -}; - -module = { - name = asn1; - common = lib/libtasn1-grub/lib/decoding.c; - common = lib/libtasn1-grub/lib/coding.c; - common = lib/libtasn1-grub/lib/element.c; - common = lib/libtasn1-grub/lib/structure.c; - common = lib/libtasn1-grub/lib/parser_aux.c; - common = lib/libtasn1-grub/lib/gstr.c; - common = lib/libtasn1-grub/lib/errors.c; - common = lib/libtasn1_wrap/wrap.c; - cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)'; - /* -Wno-type-limits comes from configure.ac of libtasn1 */ - cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB) -I$(srcdir)/lib/libtasn1-grub -I$(srcdir)/lib/libtasn1-grub/lib -Wno-type-limits'; -}; - -module = { - name = asn1_test; - common = tests/asn1/tests/CVE-2018-1000654.c; - common = tests/asn1/tests/object-id-decoding.c; - common = tests/asn1/tests/object-id-encoding.c; - common = tests/asn1/tests/octet-string.c; - common = tests/asn1/tests/reproducers.c; - common = tests/asn1/tests/Test_overflow.c; - common = tests/asn1/tests/Test_simple.c; - common = tests/asn1/tests/Test_strings.c; - common = tests/asn1/asn1_test.c; - cflags = '-Wno-uninitialized'; - cppflags = '-I$(srcdir)/lib/libtasn1-grub -I$(srcdir)/tests/asn1/'; -}; diff --git a/grub-core/boot/decompressor/minilib.c b/grub-core/boot/decompressor/minilib.c deleted file mode 100644 index fc46ee07b..000000000 --- a/grub-core/boot/decompressor/minilib.c +++ /dev/null @@ -1,93 +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 . - */ - -#include -#include -#include - -void * -grub_memset (void *s, int c, grub_size_t len) -{ - grub_uint8_t *ptr; - for (ptr = s; len; ptr++, len--) - *ptr = c; - return s; -} - -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; -} - -int -grub_memcmp (const void *s1, const void *s2, grub_size_t n) -{ - const unsigned char *t1 = s1; - const unsigned char *t2 = s2; - - while (n--) - { - if (*t1 != *t2) - return (int) *t1 - (int) *t2; - - t1++; - t2++; - } - - return 0; -} - -void *grub_decompressor_scratch; - -void -find_scratch (void *src, void *dst, unsigned long srcsize, - unsigned long dstsize) -{ -#ifdef _mips - /* Decoding from ROM. */ - if (((grub_addr_t) src & 0x10000000)) - { - grub_decompressor_scratch = (void *) ALIGN_UP((grub_addr_t) dst + dstsize, - 256); - return; - } -#endif - if ((char *) src + srcsize > (char *) dst + dstsize) - grub_decompressor_scratch = (void *) ALIGN_UP ((grub_addr_t) src + srcsize, - 256); - else - grub_decompressor_scratch = (void *) ALIGN_UP ((grub_addr_t) dst + dstsize, - 256); - return; -} diff --git a/grub-core/boot/decompressor/none.c b/grub-core/boot/decompressor/none.c deleted file mode 100644 index 911e861e3..000000000 --- a/grub-core/boot/decompressor/none.c +++ /dev/null @@ -1,42 +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 . - */ - -#include - -void -grub_decompress_core (void *src, void *dest, unsigned long n, - unsigned long dstsize __attribute__ ((unused))) -{ - char *d = (char *) dest; - const char *s = (const char *) src; - - if (d == s) - return; - - if (d < s) - while (n--) - *d++ = *s++; - else - { - d += n; - s += n; - - while (n--) - *--d = *--s; - } -} diff --git a/grub-core/boot/decompressor/xz.c b/grub-core/boot/decompressor/xz.c deleted file mode 100644 index 2279118e1..000000000 --- a/grub-core/boot/decompressor/xz.c +++ /dev/null @@ -1,60 +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 . - */ - -#include -#include -#include - -#include "xz.h" -#include "xz_stream.h" - -void -grub_decompress_core (void *src, void *dst, unsigned long srcsize, - unsigned long dstsize) -{ - struct xz_dec *dec; - struct xz_buf buf; - - find_scratch (src, dst, srcsize, dstsize); - - dec = xz_dec_init (GRUB_DECOMPRESSOR_DICT_SIZE); - - buf.in = src; - buf.in_pos = 0; - buf.in_size = srcsize; - buf.out = dst; - buf.out_pos = 0; - buf.out_size = dstsize; - - while (buf.in_pos != buf.in_size) - { - enum xz_ret xzret; - xzret = xz_dec_run (dec, &buf); - switch (xzret) - { - case XZ_MEMLIMIT_ERROR: - case XZ_FORMAT_ERROR: - case XZ_OPTIONS_ERROR: - case XZ_DATA_ERROR: - case XZ_BUF_ERROR: - return; - default: - break; - } - } -} diff --git a/grub-core/boot/i386/pc/startup_raw.S b/grub-core/boot/i386/pc/startup_raw.S deleted file mode 100644 index 28974821e..000000000 --- a/grub-core/boot/i386/pc/startup_raw.S +++ /dev/null @@ -1,369 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#define ABS(x) ((x) - LOCAL (base) + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200) - - .file "startup_raw.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 - - /* - * This is a special data area. - */ - - .org GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE -LOCAL(compressed_size): - .long 0 - .org GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE -LOCAL(uncompressed_size): - .long 0 - - .org GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY -reed_solomon_redundancy: - .long 0 - .org GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH - .short (LOCAL(reed_solomon_part) - _start) - -/* - * This is the area for all of the special variables. - */ - .org GRUB_DECOMPRESSOR_I386_PC_BOOT_DEVICE -LOCAL(boot_dev): - .byte 0xFF, 0xFF, 0xFF -LOCAL(boot_drive): - .byte 0x00 - -/* 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 */ - movb %dl, LOCAL(boot_drive) - - /* reset disk system (%ah = 0) */ - int $0x13 - - /* transition to protected mode */ - calll real_to_prot - - /* The ".code32" directive takes GAS out of 16-bit mode. */ - .code32 - - cld - call grub_gate_a20 - - movl LOCAL(compressed_size), %edx -#ifdef __APPLE__ - addl $decompressor_end, %edx - subl $(LOCAL(reed_solomon_part)), %edx -#else - addl $(LOCAL(decompressor_end) - LOCAL(reed_solomon_part)), %edx -#endif - movl reed_solomon_redundancy, %ecx - leal LOCAL(reed_solomon_part), %eax - cld - call EXT_C (grub_reed_solomon_recover) - jmp post_reed_solomon - -#include "../../../kern/i386/realmode.S" - -/* - * - * This is a workaround for clang adding a section containing only .addrsig - * Since clang itself is unable to assemble this pseudo-opcode, just replace - * it with .text - * - */ -#define addrsig text -#include -#undef addrsig - - .text - -/* - * grub_gate_a20(void) - * - * 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. :-( - */ - -grub_gate_a20: -gate_a20_test_current_state: - /* first of all, test if already in a good state */ - call gate_a20_check_state - testb %al, %al - jnz gate_a20_try_bios - ret - -gate_a20_try_bios: - /* second, try a BIOS call */ - pushl %ebp - call prot_to_real - - .code16 - movw $0x2401, %ax - int $0x15 - - calll real_to_prot - .code32 - - popl %ebp - call gate_a20_check_state - testb %al, %al - 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 - orb $0x02, %al - outb $0x92 - - call gate_a20_check_state - testb %al, %al - jnz gate_a20_try_keyboard_controller - 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 $0xdf, %al - 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 - testb %al, %al - /* 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 - testb %al, %al - 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 0 if A20 is on or 1 if it is off */ - subb %ch, %al - /* restore the original */ - popl %ebx - movb %cl, (%ebx) - popl %ecx - popl %ebx - ret - -LOCAL(reed_solomon_part): - -/* - * 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 */ -#ifdef __APPLE__ - LOCAL(compressed_size_offset) = LOCAL(compressed_size) - LOCAL(base) - movl $0x200, %ecx - addl $decompressor_end, %ecx - subl $LOCAL(base), %ecx - addl LOCAL(compressed_size_offset) + 0x100000 + 0x200, %ecx -#else - movl $(LOCAL(decompressor_end) - _start + 0x200), %ecx - addl LOCAL(compressed_size) - _start + 0x100000 + 0x200, %ecx -#endif - 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, LOCAL(boot_dev) - shrl $24, %edx - /* enter the usual booting */ - call prot_to_real - .code16 - jmp LOCAL (codestart) - .code32 - -post_reed_solomon: - -#ifdef ENABLE_LZMA - movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi -#ifdef __APPLE__ - movl $decompressor_end, %esi -#else - movl $LOCAL(decompressor_end), %esi -#endif - pushl %edi - movl LOCAL (uncompressed_size), %ecx - leal (%edi, %ecx), %ebx - /* Don't remove this push: it's an argument. */ - push %ecx - call _LzmaDecodeA - pop %ecx - /* _LzmaDecodeA clears DF, so no need to run cld */ - popl %esi -#endif - - movl LOCAL(boot_dev), %edx - movl $prot_to_real, %edi - movl $real_to_prot, %ecx - movl $LOCAL(realidt), %eax - jmp *%esi - -#ifdef ENABLE_LZMA -#include "lzma_decode.S" -#endif - - .p2align 4 - -#ifdef __APPLE__ - .zerofill __DATA, __aa_before_bss, decompressor_end, 10, 0 -#else - .bss -LOCAL(decompressor_end): -#endif diff --git a/grub-core/boot/mips/loongson/fuloong2f.S b/grub-core/boot/mips/loongson/fuloong2f.S deleted file mode 100644 index a88c81efe..000000000 --- a/grub-core/boot/mips/loongson/fuloong2f.S +++ /dev/null @@ -1,2 +0,0 @@ -#define FULOONG2F 1 -#include "fwstart.S" diff --git a/grub-core/boot/mips/loongson/fwstart.S b/grub-core/boot/mips/loongson/fwstart.S deleted file mode 100644 index 28c634614..000000000 --- a/grub-core/boot/mips/loongson/fwstart.S +++ /dev/null @@ -1,756 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef FULOONG2F -#include -#define GRUB_SM712_REG_BASE 0x700000 -#define GRUB_SM712_PCIID 0x0712126f -#endif - -#ifdef FULOONG2F -#define GRUB_MACHINE_SERIAL_PORT GRUB_MACHINE_SERIAL_PORT2 -#define GRUB_MACHINE_SERIAL_DIVISOR_115200 GRUB_MACHINE_SERIAL_PORT2_DIVISOR_115200 -#else -#define GRUB_MACHINE_SERIAL_PORT GRUB_MACHINE_SERIAL_PORT0 -#define GRUB_MACHINE_SERIAL_DIVISOR_115200 GRUB_MACHINE_SERIAL_PORT0_DIVISOR_115200 -#endif - - .set noreorder - .set noat - .set nomacro - .set mips3 - - .global start,_start,__start -start: -_start: -__start: - /* Put serial init as soon as possible. But on Fuloong2f serial is past - Geode, so on Fuloong2f we need Geode first. - */ -#ifndef FULOONG2F - bal serial_hw_init - nop -#endif - - /* Find CS5536 controller. */ - /* $t4 chooses device in priority encoding. */ - /* Resulting value is kept in GRUB_MACHINE_PCI_CONF_CTRL_REG. - This way we don't need to sacrifice a register for it. */ -retry_cs5536: - /* We have only one bus (0). Function is 0. */ - lui $t0, %hi(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR_2F) - lui $t1, %hi(GRUB_MACHINE_PCI_CONFSPACE_2F) - lui $t3, %hi(GRUB_CS5536_PCIID) - addiu $t3, $t3, %lo(GRUB_CS5536_PCIID) - ori $t4, $zero, 1 -1: - andi $t4, $t4, ((1 << GRUB_PCI_NUM_DEVICES_2F) - 1) - /* In case of failure try again. CS5536 may be slow to come up. */ - beql $t4, $zero, retry_cs5536 - nop - sw $t4, %lo(GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR_2F) ($t0) - lw $t2, (%lo(GRUB_MACHINE_PCI_CONFSPACE_2F) + GRUB_PCI_REG_PCI_ID) ($t1) - bnel $t2, $t3, 1b - sll $t4, $t4, 1 - -#ifndef FULOONG2F - lui $a0, %hi(cs5536_found) - bal message - addiu $a0, $a0, %lo(cs5536_found) - bal printhex - move $a0, $t4 -#endif - - lui $t0, %hi(GRUB_MACHINE_PCI_CONFSPACE_2F) - li $t1, GRUB_CS5536_MSR_MAILBOX_CONFIG_ENABLED - sw $t1, (%lo(GRUB_MACHINE_PCI_CONFSPACE_2F) + GRUB_CS5536_MSR_MAILBOX_CONFIG) ($t0) - - /* Set GPIO LBAR. */ - lui $a0, %hi(GRUB_CS5536_MSR_GPIO_BAR) - addiu $a0, $a0, %lo(GRUB_CS5536_MSR_GPIO_BAR) - ori $a1, $zero, GRUB_CS5536_LBAR_GPIO - /* Set mask to 0xf and enabled bit to 1. */ - bal wrmsr - ori $a2, $zero, ((GRUB_CS5536_LBAR_MASK_MASK \ - | GRUB_CS5536_LBAR_ENABLE) >> 32) - - bal gpio_init - nop - -#ifdef FULOONG2F - bal serial_hw_init - nop -#endif - - /* Initialise SMBus controller. */ - /* Set SMBUS LBAR. */ - lui $a0, %hi(GRUB_CS5536_MSR_SMB_BAR) - addiu $a0, $a0, %lo(GRUB_CS5536_MSR_SMB_BAR) - ori $a1, $zero, GRUB_CS5536_LBAR_SMBUS - /* Set mask to 0xf and enabled bit to 1. */ - bal wrmsr - ori $a2, $zero, ((GRUB_CS5536_LBAR_MASK_MASK \ - | GRUB_CS5536_LBAR_ENABLE) >> 32) - - lui $a0, %hi(smbus_enabled) - bal message - addiu $a0, $a0, %lo(smbus_enabled) - - lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE_2F + GRUB_CS5536_LBAR_SMBUS) - - /* Disable SMB. */ - sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE_2F + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0) - - /* Disable interrupts. */ - sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE_2F + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1) ($t0) - - /* Set as master. */ - sb $zero, %lo(GRUB_MACHINE_PCI_IO_BASE_2F + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_ADDR) ($t0) - - /* Launch SMBus controller at slowest speed possible. */ - ori $t1, $zero, 0xff - sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE_2F + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL3) ($t0) - sb $t1, %lo(GRUB_MACHINE_PCI_IO_BASE_2F + GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL2) ($t0) - - /* Yeeloong and Fuloong2f have only one memory slot. */ - /* Output first byte on serial for debugging. */ - ori $a1, $zero, GRUB_SMB_RAM_START_ADDR - bal read_spd - move $a0, $zero - bal printhex - move $a0, $v0 - - bal read_spd - ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_TYPE_ADDR - ori $t0, $zero, GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2 - lui $a0, %hi(unimplemented_memory_type) - bne $t0, $v0, fatal - addiu $a0, $a0, %lo(unimplemented_memory_type) - - /* And here is our goal: DDR2 controller initialisation. */ - lui $t0, %hi(GRUB_CPU_LOONGSON_CORECFG) - ld $t1, %lo(GRUB_CPU_LOONGSON_CORECFG) ($t0) - /* Use addiu for sign-extension. */ - addiu $t2, $zero, ~(GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE|GRUB_CPU_LOONGSON_CORECFG_BUFFER_CPU) - and $t1, $t1, $t2 - sd $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0) - - b continue - - .org GRUB_CPU_LOONGSON_FLASH_TLB_REFILL - GRUB_CPU_LOONGSON_FLASH_START -tlb_refill: - mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC - mfc0 $s2, GRUB_CPU_LOONGSON_COP0_BADVADDR - move $s3, $ra - lui $a0, %hi(epc) - bal message - addiu $a0, $a0, %lo(epc) - - bal printhex - move $a0, $s1 - - lui $a0, %hi(badvaddr) - bal message - addiu $a0, $a0, %lo(badvaddr) - - bal printhex - move $a0, $s2 - - lui $a0, %hi(return_msg) - bal message - addiu $a0, $a0, %lo(return_msg) - - bal printhex - move $a0, $s3 - - lui $a0, %hi(newline) - bal message - addiu $a0, $a0, %lo(newline) - - lui $a0, %hi(unhandled_tlb_refill) - b fatal - addiu $a0, $a0, %lo(unhandled_tlb_refill) - - .org GRUB_CPU_LOONGSON_FLASH_CACHE_ERROR - GRUB_CPU_LOONGSON_FLASH_START -cache_error: - lui $a0, %hi(unhandled_cache_error) - b fatal - addiu $a0, $a0, %lo(unhandled_cache_error) - - .org GRUB_CPU_LOONGSON_FLASH_OTHER_EXCEPTION - GRUB_CPU_LOONGSON_FLASH_START -other_exception: - mfc0 $s0, GRUB_CPU_LOONGSON_COP0_CAUSE - mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC - mfc0 $s2, GRUB_CPU_LOONGSON_COP0_BADVADDR - lui $a0, %hi(cause) - bal message - addiu $a0, $a0, %lo(cause) - - bal printhex - move $a0, $s0 - - lui $a0, %hi(epc) - bal message - addiu $a0, $a0, %lo(epc) - - bal printhex - move $a0, $s1 - - lui $a0, %hi(badvaddr) - bal message - addiu $a0, $a0, %lo(badvaddr) - - bal printhex - move $a0, $s2 - - lui $a0, %hi(newline) - bal message - addiu $a0, $a0, %lo(newline) - - lui $a0, %hi(unhandled_exception) - b fatal - addiu $a0, $a0, %lo(unhandled_exception) - -gpio_init: - lui $t0, %hi(GRUB_MACHINE_PCI_IO_BASE_2F + GRUB_CS5536_LBAR_GPIO) - addiu $t0, $t0, %lo(GRUB_MACHINE_PCI_IO_BASE_2F + GRUB_CS5536_LBAR_GPIO) - lui $t1, %hi (gpio_dump) - addiu $t1, $t1, %lo (gpio_dump) - -1: - lw $t2, 0($t1) - sw $t2, 0($t0) - addiu $t0, $t0, 4 - addiu $t1, $t1, 4 - lui $t2, %hi (gpio_dump_end) - addiu $t2, $t2, %lo (gpio_dump_end) - bne $t1, $t2, 1b - nop - jr $ra - nop - - /* Same as similarly named C function but in asm since - we need it early. */ - /* In: none. Out: none. Clobbered: $t0, $t1, $t2, $a0, $a1, $a2. */ -serial_hw_init: - move $t2, $ra -#ifdef FULOONG2F - lui $a0, %hi(GRUB_CS5536_MSR_DIVIL_LEG_IO) - addiu $a0, $a0, %lo(GRUB_CS5536_MSR_DIVIL_LEG_IO) - lui $a1, %hi (GRUB_CS5536_MSR_DIVIL_LEG_IO_UART2_COM3 \ - | GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP \ - | GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 \ - | GRUB_CS5536_MSR_DIVIL_LEG_IO_UART1_COM1) - ori $a1, $a1, (GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 \ - | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1) - bal wrmsr - move $a2, $zero - - lui $a0, %hi(GRUB_CS5536_MSR_DIVIL_UART1_CONF) - addiu $a0, $a0, %lo(GRUB_CS5536_MSR_DIVIL_UART1_CONF) - li $a1, 2 - bal wrmsr - move $a2, $zero - - lui $a0, %hi(GRUB_CS5536_MSR_DIVIL_UART2_CONF) - addiu $a0, $a0, %lo(GRUB_CS5536_MSR_DIVIL_UART2_CONF) - li $a1, 2 - bal wrmsr - move $a2, $zero -#endif - - lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT) - - /* Turn off the interrupt. */ - sb $zero, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_IER)($t0) - - /* Set DLAB. */ - ori $t1, $zero, UART_DLAB - sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LCR)($t0) - - /* Set the baud rate 115200. */ - ori $t1, $zero, GRUB_MACHINE_SERIAL_DIVISOR_115200 - sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_DLL)($t0) - sb $zero, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_DLH)($t0) - - /* Set the line status. */ - ori $t1, $zero, (UART_NO_PARITY | UART_8BITS_WORD | UART_1_STOP_BIT) - sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LCR)($t0) - - /* Enable the FIFO. */ - ori $t1, $zero, UART_ENABLE_FIFO_TRIGGER1 - sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_FCR)($t0) - - /* Turn on DTR and RTS. */ - ori $t1, $zero, UART_ENABLE_DTRRTS - sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_MCR)($t0) - - /* Let message return to original caller. */ - lui $a0, %hi(notification_string) - addiu $a0, $a0, %lo(notification_string) - move $ra, $t2 - - /* Print message on serial console. */ - /* In: $a0 = asciiz message. Out: none. Clobbered: $t0, $t1, $a0. */ -message: - lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT) -1: - lb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LSR)($t0) - andi $t1, $t1, UART_EMPTY_TRANSMITTER - beq $t1, $zero, 1b - nop - lb $t1, 0($a0) - sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_TX)($t0) - bne $t1, $zero, 1b - addiu $a0, $a0, 1 - jr $ra - nop - - /* Print 32-bit hexadecimal on serial. - In: $a0. Out: None. Clobbered: $a0, $t0, $t1, $t2 - */ -printhex: - lui $t0, %hi (GRUB_MACHINE_SERIAL_PORT) - ori $t2, $zero, 8 -1: - lb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_LSR)($t0) - andi $t1, $t1, UART_EMPTY_TRANSMITTER - beq $t1, $zero, 1b - nop - srl $t1, $a0, 28 - addiu $t1, $t1, -10 - bltz $t1, 2f - sll $a0, $a0, 4 - addiu $t1, $t1, 'A'-10-'0' -2: addiu $t1, $t1, '0'+10 - sb $t1, (%lo (GRUB_MACHINE_SERIAL_PORT) + UART_TX)($t0) - addiu $t2, $t2, -1 - bne $t2, $zero, 1b - nop - jr $ra - nop - -fatal: - bal message - nop -self: - b self - nop - - /* Write CS5536 MSR. - In: $a0 address, $a1 lower word, $a2 upper word. - Out: None - Clobbered: $t0 - */ -wrmsr: - lui $t0, %hi(GRUB_MACHINE_PCI_CONFSPACE_2F) - sw $a0, (%lo(GRUB_MACHINE_PCI_CONFSPACE_2F) + GRUB_CS5536_MSR_MAILBOX_ADDR) ($t0) - sw $a1, (%lo(GRUB_MACHINE_PCI_CONFSPACE_2F) + GRUB_CS5536_MSR_MAILBOX_DATA0) ($t0) - jr $ra - sw $a2, (%lo(GRUB_MACHINE_PCI_CONFSPACE_2F) + GRUB_CS5536_MSR_MAILBOX_DATA1) ($t0) - - /* Wait for SMBus data or empty transmitter. */ - /* In: $a0 = exception handler. Out: none. Clobbered: $t0, $t1 */ -smbus_wait: -1: - lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_STATUS + GRUB_MACHINE_PCI_IO_BASE_2F) - lb $t0, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_STATUS + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) - andi $t1, $t0, GRUB_CS5536_SMB_REG_STATUS_SDAST - bne $t1, $zero, return - nop - andi $t1, $t0, (GRUB_CS5536_SMB_REG_STATUS_BER | GRUB_CS5536_SMB_REG_STATUS_NACK) - beq $t1, $zero, 1b - nop - jr $a0 - nop -return: - jr $ra - nop - - /* Read SPD byte. In: $a0 byte, $a1 device. Out: $v0 read byte (0x100 on failure). - Clobbered: $t0, $t1, $t2, $t3, $a0. */ -read_spd: - move $t2, $a0 - move $t3, $ra - lui $a0, %hi(read_spd_fail) - addiu $a0, $a0, %lo(read_spd_fail) - - /* Send START. */ - lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) - lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) - ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_START - bal smbus_wait - sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) - - /* Send device address. */ - lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) - sll $t1, $a1, 1 - bal smbus_wait - sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) - - /* Send ACK. */ - lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) - lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) - ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_ACK - sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) - - /* Send byte address. */ - lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) - bal smbus_wait - sb $t2, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) - - /* Send START. */ - lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) - lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) - ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_START - bal smbus_wait - sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) - - /* Send device address. */ - lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) - sll $t1, $a1, 1 - ori $t1, $t1, 1 - bal smbus_wait - sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) - - /* Send STOP. */ - lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) - lb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) - ori $t1, $t1, GRUB_CS5536_SMB_REG_CTRL1_STOP - bal smbus_wait - sb $t1, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_CTRL1 + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) - - lui $t0, %hi(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) - lb $v0, %lo(GRUB_CS5536_LBAR_SMBUS + GRUB_CS5536_SMB_REG_DATA + GRUB_MACHINE_PCI_IO_BASE_2F) ($t0) - jr $t3 - andi $v0, $v0, 0xff -read_spd_fail: - jr $t3 - ori $v0, $v0, 0x100 - -notification_string: .asciz "GRUB " -cs5536_found: .asciz "CS5536 at " -sm_failed: .asciz "SM transaction failed.\n\r" -unhandled_tlb_refill: .asciz "Unhandled TLB refill.\n\r" -unhandled_cache_error: .asciz "Unhandled cache error.\n\r" -unhandled_exception: .asciz "Unhandled exception.\n\r" -smbus_enabled: .asciz "SMBus controller enabled.\n\r" -unimplemented_memory_type: .asciz "non-DDR2 memory isn't supported.\n\r" -no_cas_latency: .asciz "Couldn't determine CAS latency.\n\r" -cause: .asciz "Cause: " -epc: .asciz "\n\rEPC: " -badvaddr: .asciz "\n\rBadVaddr: " -newline: .asciz "\n\r" -return_msg: .asciz "\n\rReturn address: " -caches_enabled: .asciz "Caches enabled\n\r" - - .p2align 3 - -regdump: - .quad 0x0100010000000101 /* 0 */ - .quad 0x0100010100000000 /* 2 */ - .quad 0x0101000001000000 /* 3 */ - .quad 0x0100020200010101 /* 4 */ - .quad 0x0a04030603050203 /* 6 */ - .quad 0x0f0e040000010a0b /* 7 */ -#ifdef FULOONG2F - .quad 0x0000000100000001 /* 8 */ -#else - .quad 0x0000010200000102 /* 8 */ -#endif - .quad 0x0000060c00000000 /* 9 */ - .quad 0x2323233f3f1f0200 /* a */ - .quad 0x5f7f232323232323 /* b */ - .quad 0x002a3c0615000000 /* c */ - .quad 0x002a002a002a002a /* d */ - .quad 0x002a002a002a002a /* e */ -#ifdef FULOONG2F - .quad 0x00b40020005b0004 /* f */ -#else - .quad 0x00b40020006d0004 /* f */ -#endif - .quad 0x070007ff00000087 /* 10 */ - .quad 0x000000000016101f /* 11 */ - .quad 0x001c000000000000 /* 12 */ - .quad 0x28e1000200c8006b /* 13 */ - .quad 0x0000204200c8002f /* 14 */ - .quad 0x0000000000030d40 /* 15 */ - .quad 0 /* 16 */ - .quad 0 /* 17 */ - .quad 0 /* 18 */ - .quad 0 /* 19 */ - .quad 0 /* 1a */ - .quad 0 /* 1b */ - .quad 0 /* 1c */ - -/* Dump of GPIO connections. FIXME: Remove useless and macroify. */ -gpio_dump: -#ifdef FULOONG2F - .long 0xffff0000, 0x2eefd110, 0xffff0000, 0xffff0000 - .long 0x2eefd110, 0xffff0000, 0x1000efff, 0xefff1000 - .long 0x3df3c20c, 0xffff0000, 0xffff0000, 0xffff0000 - .long 0x7df3820c, 0x3df3c20c, 0xffff0000, 0x00000000 - .long 0xffff0000, 0xffff0000, 0x3de3c21c, 0x3d83c27c - .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 - .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 - .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 - .long 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000 - .long 0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000 - .long 0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000 - .long 0xefff1000, 0xefff1000, 0xffff0000, 0x00000000 - .long 0xffff0000, 0xffff0000, 0xefff1000, 0xefff1000 - .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 - .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 - .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 -#else - .long 0xffff0000, 0x2ffdd002, 0xffff0000, 0xffff0000 - .long 0x2fffd000, 0xffff0000, 0x1000efff, 0xefff1000 - .long 0x3ffbc004, 0xffff0000, 0xffff0000, 0xffff0000 - .long 0x3ffbc004, 0x3ffbc004, 0xffff0000, 0x00000000 - .long 0xffff0000, 0xffff0000, 0x3ffbc004, 0x3f9bc064 - .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 - .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 - .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 - .long 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000 - .long 0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000 - .long 0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000 - .long 0xefff1000, 0xefff1000, 0xffff0000, 0x00000000 - .long 0xffff0000, 0xffff0000, 0xefff1000, 0xffff0000 - .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 - .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 - .long 0x00000000, 0x50000000, 0x00000000, 0x00000000 -#endif -gpio_dump_end: - - .p2align 3 - -write_dumpreg: - ld $t2, 0($t6) - sd $t2, 0($t4) - addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP - jr $ra - addiu $t6, $t6, GRUB_CPU_LOONGSON_DDR2_REG_SIZE - -continue: - lui $t4, %hi(GRUB_CPU_LOONGSON_DDR2_BASE) - addiu $t4, $t4, %lo(GRUB_CPU_LOONGSON_DDR2_BASE) - lui $t6, %hi(regdump) - - /* 0 */ - bal write_dumpreg - addiu $t6, $t6, %lo(regdump) - - /* 1 */ - ori $a1, $a1, GRUB_SMB_RAM_START_ADDR - move $t8, $zero - lui $t5, 0x0001 - bal read_spd - ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_BANKS_ADDR - ori $t7, $zero, 8 - bne $v0, $t7, 1f - ori $t5, $t5, 0x0001 - ori $t8, $t8, GRUB_CPU_LOONGSON_DDR2_REG1_HI_8BANKS -1: - dsll $t8, $t8, 32 - or $t5, $t5, $t8 - sd $t5, 0 ($t4) - addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP - - /* 2 */ - bal write_dumpreg - nop - - /* 3 */ - bal write_dumpreg - nop - - /* 4 */ - bal write_dumpreg - nop - - /* 5 */ - /* FIXME: figure termination resistance. */ - ori $t5, $zero, 0x2 - bal read_spd - ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_ROWS_ADDR - /* $v0 = 15 - $v0. */ - xori $v0, $v0, 0xf - andi $v0, $v0, 0x7 - sll $v0, $v0, 8 - or $t5, $t5, $v0 - - /* Find the fastest supported CAS latency. */ - bal read_spd - ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_ADDR - ori $t0, $zero, GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE - ori $t1, $zero, (1 << GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE) -2: - and $t2, $t1, $v0 - bne $t2, $zero, 1f - ori $t3, $zero, 8 - lui $a0, %hi(no_cas_latency) - beq $t0, $t3, fatal - addiu $a0, $a0, %lo(no_cas_latency) - addiu $t0, $t0, 1 - b 2b - sll $t1, $t1, 1 -1: - sll $t0, $t0, 16 - or $t5, $t5, $t0 - - bal read_spd - ori $a0, $zero, GRUB_SMBUS_SPD_MEMORY_NUM_COLUMNS_ADDR - /* $v0 = 15 - ($v0 + 1) = 14 - $v0. */ - addiu $v0, $v0, 1 - xori $v0, $v0, 0xf - andi $v0, $v0, 0x7 - sll $v0, 24 - or $t5, $t5, $v0 - sd $t5, 0 ($t4) - - addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP - - ori $t7, $zero, 0x16 - -1: - ld $t2, 0($t6) - sd $t2, 0($t4) - addiu $t4, $t4, GRUB_CPU_LOONGSON_DDR2_REG_STEP - addiu $t7, $t7, -1 - bne $t7, $zero, 1b - addiu $t6, $t6, GRUB_CPU_LOONGSON_DDR2_REG_SIZE - - lui $t4, %hi(GRUB_CPU_LOONGSON_DDR2_BASE) - ld $t5, (%lo(GRUB_CPU_LOONGSON_DDR2_BASE) + 0x30) ($t4) - ori $t0, $zero, 1 - dsll $t0, $t0, 40 - or $t5, $t5, $t0 - sd $t5, (%lo(GRUB_CPU_LOONGSON_DDR2_BASE) + 0x30) ($t4) - - /* Desactivate DDR2 registers. */ - lui $t0, %hi (GRUB_CPU_LOONGSON_CORECFG) - ld $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0) - ori $t1, $t1, GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE - sd $t1, %lo (GRUB_CPU_LOONGSON_CORECFG) ($t0) - - /* Enable cache. */ - mfc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG - addiu $t1, $zero, ~GRUB_CPU_LOONGSON_CACHE_TYPE_MASK - and $t0, $t1, $t1 - /* Set line size to 32 bytes and disabled cache. */ - ori $t0, $t0, (GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_ILINESIZE \ - | GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_DLINESIZE \ - | GRUB_CPU_LOONGSON_CACHE_ACCELERATED) - mtc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG - - /* Invalidate all I-cache entries. */ - srl $t1, $t0, GRUB_CPU_LOONGSON_COP0_CACHE_ISIZE_SHIFT - andi $t1, $t1, GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK - ori $t2, $zero, (1 << (GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \ - - GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \ - - GRUB_CPU_LOONGSON_I_CACHE_LOG_WAYS)) - sll $t1, $t2, $t1 - lui $t2, 0x8000 - -1: - cache GRUB_CPU_LOONGSON_COP0_I_INDEX_INVALIDATE, 0($t2) - addiu $t1, $t1, -1 - bne $t1, $zero, 1b - addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_I_INDEX_BIT_OFFSET) - - /* Invalidate all D-cache entries. */ - srl $t1, $t0, GRUB_CPU_LOONGSON_COP0_CACHE_DSIZE_SHIFT - andi $t1, $t1, GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK - ori $t2, $zero, (1 << (GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \ - - GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \ - - GRUB_CPU_LOONGSON_D_CACHE_LOG_WAYS)) - sll $t1, $t2, $t1 - lui $t2, 0x8000 - mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO - mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI -1: - /* All four ways. */ - cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 0($t2) - cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 1($t2) - cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 2($t2) - cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 3($t2) - addiu $t1, $t1, -1 - bne $t1, $zero, 1b - addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET) - - /* Invalidate all S-cache entries. */ - ori $t1, $zero, (1 << (GRUB_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE \ - - GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \ - - GRUB_CPU_LOONGSON_S_CACHE_LOG_WAYS)) - lui $t2, 0x8000 - mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO - mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI -1: - /* All four ways. */ - cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 0($t2) - cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 1($t2) - cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 2($t2) - cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 3($t2) - addiu $t1, $t1, -1 - bne $t1, $zero, 1b - addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET) - - /* Finally enable cache. */ - mfc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG - addiu $t1, $zero, ~GRUB_CPU_LOONGSON_CACHE_TYPE_MASK - and $t0, $t1, $t1 - ori $t0, $t0, GRUB_CPU_LOONGSON_CACHE_CACHED - mtc0 $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG - - lui $a0, %hi(caches_enabled) - bal message - addiu $a0, $a0, %lo(caches_enabled) - - /* Set ROM delay cycles to 1. */ - lui $t0, %hi(GRUB_CPU_LOONGSON_LIOCFG) - lw $t1, %lo(GRUB_CPU_LOONGSON_LIOCFG) ($t0) - addiu $t2, $zero, ~(GRUB_CPU_LOONGSON_ROM_DELAY_MASK \ - << GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET) - and $t1, $t1, $t2 - ori $t1, $t1, (1 << GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET) - sw $t1, %lo(GRUB_CPU_LOONGSON_LIOCFG) ($t0) - - addiu $a0, $zero, -1 - addiu $a1, $zero, -1 - - /* Take advantage of cache. */ - lui $t0, %hi(cached_continue - 0x20000000) - addiu $t0, $t0, %lo(cached_continue - 0x20000000) - jr $t0 -#ifdef FULOONG2F - addiu $a2, $zero, -(1 + GRUB_ARCH_MACHINE_FULOONG2F) -#else - addiu $a2, $zero, -(1 + GRUB_ARCH_MACHINE_YEELOONG) -#endif - -cached_continue: diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S deleted file mode 100644 index 6a81b3733..000000000 --- a/grub-core/boot/mips/startup_raw.S +++ /dev/null @@ -1,300 +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 . - */ - -#include -#include -#include -#include -#include -#include - -#define BASE_ADDR 8 - -.extern __bss_start -.extern _end -.extern _edata - - .globl __start, _start, start - .set noreorder - .set nomacro -__start: -_start: -start: - - bal codestart - nop -base: - .org GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE -compressed_size: - .long 0 - .org GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE -uncompressed_size: - .long 0 - .org GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR -uncompressed_addr: - .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_QEMU_MIPS - lui $t0, %hi (((16 << 20) - 264 + 4) | 0x80000000) - lw $t1, %lo (((16 << 20) - 264 + 4) | 0x80000000) ($t0) - - lui $t2, 0x1234 - ori $t2, 0x5678 - - bne $t1, $t2, 1f - nop - - lui $t0, %hi (((16 << 20) - 264) | 0x80000000) - b 2f - lw $s4, %lo (((16 << 20) - 264) | 0x80000000) ($t0) - -1: - li $s4, 0 -2: -#endif - -#ifdef GRUB_MACHINE_MIPS_LOONGSON - move $s2, $zero - move $s3, $zero - move $s4, $zero - move $s5, $zero - move $s7, $zero - - /* $a2 has the environment. */ - addiu $t0, $zero, -0x10 - and $t1, $a2, $t0 - beq $t0, $t1, argfw - nop - move $t0, $a2 -argcont: - lw $t1, 0($t0) - beq $t1, $zero, argdone - nop -#define DO_PARSE(str, reg) \ - addiu $t2, $s0, (str-base);\ - bal parsestr;\ - nop ;\ - beq $v0, $zero, 1f;\ - nop ;\ - b 2f;\ - move reg, $v0; \ -1: -#define DO_CHECKT1(str, val) \ - move $t6, $t1 ;\ - addiu $t7, $s0, (str - base);\ - bal do_check ;\ - li $t2, val - - DO_PARSE (busclockstr, $s2) - DO_PARSE (cpuclockstr, $s3) - DO_PARSE (memsizestr, $s4) - DO_PARSE (highmemsizestr, $s5) - DO_CHECKT1 (pmon_yeeloong_verstr, GRUB_ARCH_MACHINE_YEELOONG) - DO_CHECKT1 (pmon_fuloong2f_verstr, GRUB_ARCH_MACHINE_FULOONG2F) -2: - b argcont - addiu $t0, $t0, 4 -parsestr: - move $v0, $zero - move $t3, $t1 -3: - lb GRUB_ASM_T4, 0($t2) - lb GRUB_ASM_T5, 0($t3) - addiu $t2, $t2, 1 - addiu $t3, $t3, 1 - beq GRUB_ASM_T5, $zero, 1f - nop - beq GRUB_ASM_T5, GRUB_ASM_T4, 3b - nop - bne GRUB_ASM_T4, $zero, 1f - nop - - addiu $t3, $t3, 0xffff -digcont: - lb GRUB_ASM_T5, 0($t3) - /* Substract '0' from digit. */ - addiu GRUB_ASM_T5, GRUB_ASM_T5, 0xffd0 - bltz GRUB_ASM_T5, 1f - nop - addiu GRUB_ASM_T4, GRUB_ASM_T5, 0xfff7 - bgtz GRUB_ASM_T4, 1f - nop - /* Multiply $v0 by 10 with bitshifts. */ - sll $v0, $v0, 1 - sll GRUB_ASM_T4, $v0, 2 - addu $v0, $v0, GRUB_ASM_T4 - addu $v0, $v0, GRUB_ASM_T5 - addiu $t3, $t3, 1 - b digcont - nop -1: - jr $ra - nop -busclockstr: .asciz "busclock=" -cpuclockstr: .asciz "cpuclock=" -memsizestr: .asciz "memsize=" -highmemsizestr: .asciz "highmemsize=" -machtype_yeeloong_str1: .asciz "machtype=8.9" -machtype_yeeloong_str2: .asciz "machtype=lemote-yeeloong-" -machtype_fuloong2f_str: .asciz "machtype=lemote-fuloong-2f" -machtype_fuloong2e_str: .asciz "machtype=lemote-fuloong-2e" -pmon_yeeloong_str: .asciz "PMON_VER=LM8" -pmon_fuloong2f_str: .asciz "PMON_VER=LM6" -pmon_yeeloong_verstr: .asciz "Version=LM8" -pmon_fuloong2f_verstr: .asciz "Version=LM6" - .p2align 2 - -argdone: - beq $a0, $zero, cmdlinedone - nop -#define DO_CHECKA1(str, val) \ - lw $t6, 0($a1) ;\ - addiu $t7, $s0, (str - base);\ - bal do_check ;\ - li $t2, val - DO_CHECKA1 (machtype_yeeloong_str1, GRUB_ARCH_MACHINE_YEELOONG) - DO_CHECKA1 (machtype_yeeloong_str2, GRUB_ARCH_MACHINE_YEELOONG) - DO_CHECKA1 (pmon_yeeloong_str, GRUB_ARCH_MACHINE_YEELOONG) - DO_CHECKA1 (machtype_fuloong2f_str, GRUB_ARCH_MACHINE_FULOONG2F) - DO_CHECKA1 (machtype_fuloong2e_str, GRUB_ARCH_MACHINE_FULOONG2E) - DO_CHECKA1 (pmon_fuloong2f_str, GRUB_ARCH_MACHINE_FULOONG2F) - addiu $a0, $a0, -1 - b argdone - addiu $a1, $a1, 4 -do_check: - lb GRUB_ASM_T4, 0($t7) - beq GRUB_ASM_T4, $zero, 1f - lb $t3, 0($t6) - bne $t3, GRUB_ASM_T4, 2f - addiu $t6, $t6, 1 - b do_check - addiu $t7, $t7, 1 -1: - move $s7, $t2 -2: - jr $ra - nop -argfw: - not $s7, $a2 -cmdlinedone: -#endif -#ifdef GRUB_MACHINE_ARC - lui $t0, %hi(_start - 256) - addiu $t0, $t0, %lo(_start - 256) - addiu $t3, $t0, 255 - lw $t1, 0($a1) -1: - bne $t0, $t3, 2f - lb $t2, 0($t1) - move $t2, $zero -2: - sb $t2, 0($t0) - addiu $t0, $t0, 1 - bnez $t2, 1b - addiu $t1, $t1, 1 -#endif - /* Copy the decompressor. */ - lui $t1, %hi(base) - addiu $t1, $t1, %lo(base) - lui $t3, %hi(__bss_start) - addiu $t3, $t3, %lo(__bss_start) - move $t2, $s0 - -1: - beq $t1, $t3, 2f - lb GRUB_ASM_T4, 0($t2) - sb GRUB_ASM_T4, 0($t1) - addiu $t1, $t1, 1 - b 1b - addiu $t2, $t2, 1 -2: - /* Clean out its BSS. */ - lui $t1, %hi(__bss_start) - addiu $t1, $t1, %lo(__bss_start) - lui $t2, %hi(_end) - addiu $t2, $t2, %lo(_end) -1: - beq $t1, $t2, 2f - nop - sb $zero, 0($t1) - b 1b - addiu $t1, $t1, 1 -2: - lui $a0, %hi(base) - addiu $a0, $a0, %lo(base) - lui $a1, %hi(_end) - addiu $a1, %lo(_end) - subu $a1,$a1,$a0 - -#include "../../kern/mips/cache_flush.S" - - /* Decompress the payload. */ - lui $a0, %hi(_edata) - addiu $a0, $a0, %lo(_edata) - - lui $t0, %hi(base) - addiu $t0, $t0, %lo(base) - subu $a0, $a0, $t0 - addu $a0, $a0, $s0 - - lw $a1, (GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR - BASE_ADDR)($s0) - lw $a2, (GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0) - lw $a3, (GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE - BASE_ADDR)($s0) - move $s1, $a1 - - /* $a0 contains source compressed address, $a1 is destination, - $a2 is compressed size, $a3 is uncompressed size. - */ - move $s6, $a3 - - lui $t9, %hi(EXT_C(grub_decompress_core)) - addiu $t9, $t9, %lo(EXT_C(grub_decompress_core)) - -#ifdef GRUB_MACHINE_ARC - lui $sp, %hi(_start - 512) - jalr $t9 - addiu $sp, $sp, %lo(_start - 512) -#else - lui $sp, %hi(_start - 256) - jalr $t9 - addiu $sp, $sp, %lo(_start - 256) -#endif - move $a0, $s1 - move $a1, $s6 - -#include "../../kern/mips/cache_flush.S" - - lui $t1, %hi(GRUB_MACHINE_LINK_ADDR) - addiu $t1, %lo(GRUB_MACHINE_LINK_ADDR) - - jr $t1 - nop - /* Ensure that .data section is created. In code we suppose that _edata - is first location not in decompressor image. Strictly speaking it's - _edata only when .data is present and _etext otherwise. But checking - for .data presence would cost more in code than it is to ensure that - .data is created. - */ - .data - .long 0 diff --git a/grub-core/boot/powerpc/bootinfo.txt.in b/grub-core/boot/powerpc/bootinfo.txt.in deleted file mode 100644 index bc831daa9..000000000 --- a/grub-core/boot/powerpc/bootinfo.txt.in +++ /dev/null @@ -1,73 +0,0 @@ - -@PACKAGE@ @VERSION@ -@PACKAGE@ @VERSION@ -boot &device;:\boot\grub\powerpc.elf - - -FF FF FF FF FF FF FF FF FF FF 92 6D 6D 6D 6D 6D 6D 6D 6D 6D DB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF B6 92 6D 92 92 92 DB FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF DB 6D 92 DB FF FF FF FF FF DB B6 FF FF 92 6D FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 92 DB FF FF FF FF FF B6 6D 92 DB FF FF FF FF FF FF FF -FF FF FF FF FF FF 49 92 FF FF B6 B6 24 00 24 00 00 00 00 49 6D DB 6D 92 DB B6 DB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF B6 6D DB 92 6D 24 49 92 6D 6D FF FF FF 92 6D FF FF FF FF FF FF -FF FF FF FF B6 49 DB FF FF 24 00 00 00 92 92 B6 FF DB DB FF DB B6 FF DB 92 49 DB FF FF FF FF FF FF FF FF FF FF FF FF FF DB 49 6D B6 FF 6D B6 6D 6D 92 24 24 00 00 24 6D FF FF 49 DB FF FF FF FF -FF FF FF B6 49 FF DB 49 24 00 49 6D B6 FF B6 92 6D 6D 6D 92 DB DB DB B6 6D 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 6D DB FF FF FF FF DB B6 B6 B6 FF DB 24 00 00 92 B6 FF 49 FF FF FF FF -FF FF DB 49 FF FF 49 00 00 24 FF FF 6D 49 92 DB FF FF FF DB 92 92 92 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 92 92 6D 6D B6 DB DB B6 6D 6D FF FF 24 00 00 DB FF 49 FF FF FF -FF FF 49 FF FF 49 00 00 6D DB DB 49 DB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 B6 B6 24 00 24 DB DB 6D FF FF -FF B6 92 FF B6 00 00 24 FF DB 6D FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 B6 FF 00 00 49 FF 92 B6 FF -FF 6D FF FF 92 00 00 49 FF 6D FF FF FF FF FF FF FF FF FF FF FF FF FF B6 92 92 6D 6D 6D 6D DB FF FF FF FF FF FF B6 92 92 92 92 92 FF FF FF FF FF FF FF FF FF FF FF FF 6D FF 24 00 24 FF FF 6D FF -DB 92 FF DB 00 00 49 FF 92 DB FF FF FF FF FF FF FF FF FF FF FF DB 6D B6 FF FF FF FF FF FF 92 6D FF FF FF FF 6D B6 FF FF FF FF FF B6 B6 FF FF FF FF FF FF FF FF FF FF FF 92 DB 00 00 92 FF 92 DB -92 FF FF B6 00 00 6D FF 6D FF FF FF FF FF FF FF FF FF FF FF DB 6D FF FF FF 92 49 49 49 92 FF FF 49 DB DB 24 DB FF B6 49 49 92 FF FF DB 92 FF FF FF FF FF FF FF FF FF FF 92 FF 00 00 6D FF DB 92 -6D FF FF FF 00 00 49 92 DB FF FF FF FF FF FF FF FF FF FF DB 6D FF FF 6D 00 00 00 00 00 00 00 B6 FF 49 00 24 24 49 24 00 00 00 00 6D FF DB 92 FF FF FF FF FF FF FF FF FF DB B6 00 00 92 FF FF 6D -6D FF FF 24 00 00 DB 6D FF FF FF FF FF FF FF FF FF FF DB 6D FF DB 00 00 00 00 00 00 00 00 00 00 B6 FF DB B6 49 92 24 24 00 00 00 00 24 FF DB 92 FF FF FF FF FF FF FF FF FF 92 6D 00 00 DB FF 6D -6D FF FF 24 00 00 FF 6D FF FF FF FF FF FF FF FF FF FF 49 FF B6 00 00 00 00 00 00 00 00 00 00 00 00 92 FF FF 92 DB DB 24 24 00 00 00 00 24 FF 92 DB FF FF FF FF FF FF FF FF 92 92 00 00 FF FF 6D -6D FF FF B6 00 00 92 6D FF FF FF FF FF FF FF FF FF 49 FF DB 00 00 00 00 00 00 00 00 00 00 00 00 00 92 FF FF B6 B6 FF 92 24 00 00 00 00 00 49 FF 6D FF FF FF FF FF FF FF FF 92 24 00 49 FF FF 6D -6D FF FF 00 00 00 DB 6D FF FF FF FF FF FF FF FF 6D DB DB 00 00 00 00 00 00 00 00 00 00 00 00 00 00 92 FF FF DB B6 FF B6 49 00 00 00 00 00 00 6D FF 6D FF FF FF FF FF FF FF 92 92 00 00 DB FF 6D -6D FF FF DB 00 00 B6 6D FF FF FF FF FF FF FF 6D B6 FF 24 00 00 00 00 00 00 00 00 00 00 00 24 B6 DB 6D FF FF FF FF FF 6D 49 24 00 00 00 00 00 00 B6 DB B6 FF FF FF FF FF B6 DB 24 00 92 FF FF 6D -6D FF FF 6D 00 00 24 DB 92 FF FF FF FF FF 92 92 FF 49 00 00 00 00 00 49 B6 FF FF DB B6 DB FF FF FF B6 92 FF FF DB 92 FF FF FF 49 6D 92 24 00 00 00 DB B6 DB FF FF FF FF 6D FF 00 00 00 DB FF 6D -6D FF FF 92 24 00 49 FF 6D B6 FF FF FF 6D 92 FF 49 00 00 49 DB FF FF FF FF FF FF B6 FF FF FF FF FF FF B6 6D 92 92 FF FF FF FF 6D FF FF FF DB 24 00 24 FF 92 B6 FF FF 92 B6 FF 00 00 B6 FF FF 6D -92 FF FF FF 00 00 24 92 FF 92 6D 92 49 B6 DB 24 00 24 DB FF FF FF FF FF DB 92 24 00 FF FF FF FF 6D 6D FF FF FF 6D 6D FF FF B6 DB 6D FF FF FF FF 00 00 24 DB B6 6D 6D B6 DB 00 00 00 6D FF FF 6D -DB 92 FF DB 49 00 00 00 B6 FF FF DB FF 6D 00 00 6D FF FF FF FF FF FF FF 24 92 00 49 FF FF FF FF FF 6D B6 FF FF 6D 6D FF 6D 00 DB DB 92 FF FF FF DB 00 00 00 6D FF FF DB 6D 00 00 24 FF FF 92 DB -FF 49 FF FF 6D 00 00 00 24 49 B6 FF 24 00 00 6D FF FF FF FF FF FF FF 49 92 B6 00 DB FF FF DB DB FF FF B6 FF FF FF FF FF 00 49 DB FF 92 FF FF FF FF 92 00 00 00 24 6D 00 00 00 00 24 DB FF 49 FF -FF 92 B6 FF 92 49 00 00 00 00 00 24 00 00 00 FF FF FF FF FF FF FF 92 6D FF B6 DB FF DB B6 DB B6 B6 FF FF B6 FF FF FF DB 00 B6 DB FF 92 FF FF FF FF FF 24 00 00 00 00 00 00 00 00 B6 FF 92 B6 FF -FF FF 49 FF FF 49 24 00 00 00 00 00 00 00 B6 FF FF FF FF FF FF FF B6 FF FF FF FF FF FF FF FF FF 6D FF FF 6D FF FF FF DB 24 FF FF FF 92 FF FF FF FF FF 6D 00 00 00 00 00 00 00 DB FF FF 6D FF FF -FF FF DB 6D FF FF 6D 49 00 00 00 00 00 24 FF FF FF FF FF FF FF FF FF FF FF FF FF DB 6D 49 24 24 24 FF FF DB FF FF FF FF 24 24 00 00 92 FF FF FF FF FF DB 00 00 00 00 00 00 FF DB FF 6D FF FF FF -FF FF FF 92 B6 FF FF DB 49 24 00 00 00 92 FF FF FF FF FF FF FF FF FF DB FF FF FF 49 49 24 00 24 FF FF FF FF FF FF FF FF 49 6D 00 24 49 FF FF FF FF FF FF 49 00 24 6D 6D B6 FF FF 6D B6 FF FF FF -FF FF FF FF 6D B6 FF FF DB 92 B6 49 00 FF FF FF FF FF FF FF FF FF FF B6 FF FF FF 92 DB 92 00 24 FF FF FF FF FF FF FF FF FF 00 00 6D FF FF FF FF FF FF FF DB 00 6D DB FF FF FF 6D B6 FF FF FF FF -FF FF FF FF FF 92 6D FF FF FF FF B6 49 FF FF FF FF FF FF FF FF FF FF 6D FF FF FF FF B6 92 92 B6 B6 DB FF FF FF FF FF FF FF B6 6D 49 6D FF FF FF FF FF FF FF 92 24 FF FF B6 6D DB FF FF FF FF FF -FF FF FF FF FF FF DB 49 6D B6 FF 6D 92 FF FF FF FF FF FF FF FF FF DB 6D FF FF FF FF FF FF FF FF FF 92 FF FF FF FF FF FF FF FF 6D DB 92 FF FF FF FF FF FF FF FF 6D 49 6D DB FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF DB 92 49 00 FF FF FF FF FF FF FF FF FF FF 6D 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 92 6D FF FF FF FF FF FF FF DB 92 FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF 49 FF FF FF FF FF FF FF FF FF DB 00 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 B6 92 6D B6 FF FF FF FF FF FF 49 DB FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF 24 FF FF FF FF FF FF FF FF FF 49 DB 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 6D 6D FF 92 49 92 FF FF FF FF DB 49 DB FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF B6 49 FF FF FF FF FF FF FF FF 6D 92 FF 92 FF FF FF FF FF FF FF FF FF FF B6 6D 49 6D DB FF FF FF FF FF 6D 49 FF FF FF DB 6D 6D 92 92 6D 49 FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF 24 FF FF FF FF FF FF FF FF 6D 92 FF FF FF DB FF FF FF FF FF FF FF FF 6D 6D FF FF FF 92 6D FF FF FF FF FF 49 92 B6 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF DB 6D FF FF FF FF FF FF DB 24 92 FF FF FF FF FF FF FF FF FF FF FF FF FF 49 49 6D DB FF FF DB 6D B6 FF FF FF FF B6 B6 DB 49 FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF 24 B6 FF FF FF FF B6 49 49 24 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF 00 49 FF DB DB FF FF FF B6 92 FF FF FF FF FF FF 92 DB FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF 24 B6 FF FF B6 24 00 6D DB FF 6D 92 FF FF FF FF FF FF FF FF FF FF FF FF FF 6D DB DB 00 00 24 FF FF FF FF B6 FF FF FF FF FF B6 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF B6 B6 DB B6 6D 49 49 92 FF FF FF B6 6D FF FF FF FF FF FF FF 92 92 FF FF FF FF FF FF FF 49 92 DB 49 FF FF FF FF FF FF FF FF FF 92 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF 92 24 49 49 6D FF 6D 92 FF FF FF B6 6D FF FF FF FF FF FF FF FF FF FF DB FF FF FF FF FF FF FF FF B6 FF FF FF FF FF FF FF FF FF 49 FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF 6D 92 FF FF FF B6 6D FF FF FF FF FF FF FF FF FF FF B6 DB DB FF FF FF FF FF FF FF DB FF FF FF FF FF FF FF 6D 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF 6D 92 FF FF FF FF 24 92 FF FF FF FF FF FF FF FF FF FF 6D B6 FF FF FF FF FF FF FF FF FF FF FF FF FF DB 49 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF 6D B6 FF FF FF FF B6 6D FF FF FF FF FF FF FF FF FF FF B6 92 FF FF FF FF FF FF FF FF FF FF FF DB 6D 00 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF 6D 92 FF FF FF FF DB 49 FF FF FF FF FF FF FF FF FF FF FF 49 FF FF FF FF FF FF FF FF FF FF FF FF FF DB 49 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF 92 6D FF FF FF FF FF 00 24 DB FF FF FF FF FF FF FF FF FF DB 6D FF FF FF FF FF FF FF FF FF FF FF FF FF FF 49 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF B6 49 FF FF FF FF FF FF 92 6D FF FF FF FF FF FF FF FF FF FF 6D B6 FF FF FF FF FF FF FF FF FF FF FF FF B6 49 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00 FF FF FF FF FF FF FF 49 00 DB FF FF FF FF FF FF FF FF FF 6D 6D B6 DB DB DB 92 49 00 00 00 00 00 49 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF 49 DB FF FF FF FF FF FF FF 24 FF FF FF FF FF FF FF FF FF FF FF DB 6D 49 49 6D B6 DB FF FF FF B6 6D FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 92 FF FF FF FF FF FF B6 6D FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 6D FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 24 FF FF FF FF FF FF DB 00 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF DB 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 B6 FF FF FF FF FF FF DB 6D 00 49 FF FF FF FF FF FF FF FF FF FF FF FF DB B6 92 6D 6D 6D 49 DB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 49 FF FF FF FF FF FF FF FF 49 00 92 FF FF FF FF FF FF FF FF 49 00 00 00 00 00 49 B6 DB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF DB 6D FF FF FF FF FF FF FF FF 6D 6D FF B6 B6 FF FF FF FF FF FF 92 92 FF FF 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 B6 FF FF FF FF FF FF DB 00 DB 6D 00 B6 FF FF FF FF FF FF FF FF FF FF 24 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 DB FF FF FF FF FF 92 00 FF 24 00 00 49 FF FF FF FF FF FF FF FF FF B6 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 FF FF FF FF FF FF 49 24 24 00 00 6D FF FF FF FF FF FF FF DB FF DB 6D FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF B6 FF FF FF FF FF FF 6D 00 24 24 24 FF FF FF FF FF FF DB B6 DB 49 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF B6 00 B6 00 49 DB FF FF FF DB 24 6D 24 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00 B6 6D 00 00 DB FF 6D 00 00 00 DB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF DB 00 6D FF FF 00 00 DB 49 00 00 00 00 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 DB FF FF 6D 00 00 92 24 00 00 00 00 00 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF B6 FF FF 00 6D 00 00 24 00 00 00 00 00 00 24 92 DB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 6D DB 00 00 00 00 00 00 00 00 00 00 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF DB 00 24 00 00 6D 00 00 00 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF -FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF DB 49 92 6D 6D DB B6 92 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF - - - diff --git a/grub-core/boot/powerpc/grub.chrp.in b/grub-core/boot/powerpc/grub.chrp.in deleted file mode 100644 index 9b2218352..000000000 --- a/grub-core/boot/powerpc/grub.chrp.in +++ /dev/null @@ -1,172 +0,0 @@ - - -MacRISC MacRISC3 MacRISC4 - - -@PACKAGE@ @VERSION@ - - -3434 -00000000000000F781FB8181818181FBFAF500000000000000000000000000000000000000F6FAFAFAFA81F9F600000000000000 -0000000000F8FBF9F500F95656FCFB5656FBF800000000000000000000000000000000F5FAF9F5F7F600F6F6F9FAF70000000000 -000000F5FBFA0056FDFEFEFDFDFAAC81FB56568181560000000000000000000000F9F9F9F7FCFDFEFEFEFFFC81F656FA00000000 -0000F5AC2BF7FBFEFEFD2BF6568181F9F7F6F6F8FBF50000000000000000000000FAF700F600F5F7F7F6F7FEFFACF82BFB000000 -0000FC2BF5FEFFFFF5F7FC81F70000F7F9FAFAF8000000000000000000000000000056F9F9FAF9F7F7FA812BF7FFFF56F7FA0000 -005656F5FEFFAC2BF9FA000000000000000000000000000000000000000000000000000000000000000000FA56FAFEFEF8F9F700 -00FB00F7FFFF56F9F800000000000000000000F656FAFA56F50000000000F5F8F9F8F5000000000000000000F9F7FCFFFB00FB00 -F8F800ACFFACF6FA000000000000000000F6FA562BF5F5F781FA000000F9FA2B00F556F9F5000000000000000081F8FFFEF6562B -810000FFFFF9FAF500000000000000002B8100F5F9FCACFBF82BFBF6FCFAF6FAFC81F600FA2B000000000000002BF8FEFFF8F5FA -FA00F5FEFFFA8100000000000000002B8100F9FEFFFFFFFFFFFBF6FDFEACFDFEFFFFFFFBF581F600000000000000F9FEFFF700FA -FA00FBFFFEF6F900000000000000F6FB00FCFFFFFFFFFFFFFFFFFCF600FCF7ACFEFFFFFFFDF6810000000000000056F9FFAC00FA -FA00F6FFFFF856000000000000F5FBF5ACFFFFFFFFFFFFFFFFFFFF2B002BF8F5ACFFFFFFFFFDF6FA000000000000F9FCFF560081 -FA0081FFFFF8F9000000000000FBF6FBFFFFFFFFFFFFFFFFFFFFFFF800F55600FCFFFFFFFFFF81F8F80000000000F981FFAC0081 -FA0000FEFEF8FB0000000000812BFAFFFFFFFFFFFFFEFFFFFDF92BFA0000F6F981ACFEFFFFFFFF56F9F600000000F9FDFF2B0081 -FA00FAFFFF81812B000000FAF8F9FFFFFEACFBF80000F500000000F9F900562B0000FCF7F9ACFFFF2BF9F50000F9F6FEFFFB0081 -810000FCFFFBF6FB56F7FBF8F9FFFE5600000000F5FAAC000000F82BF6FAFBF800F556F80000F9FFFE2BFAFAFAF8FAFFFEF60081 -FAF6F5ACFFFFAC00F856F7ACFFFCF500000000FAFCFFFC00000056AC00F581F92BFEF9FAF6000081FFFFFBF6F62BFFFFACF6F6FA -F6FA00FAFFFFFFACFA56FFFFAC0000000000F6FD2BFEF6F5565600F5F800F60081FEF7F656000000FDFFFFFDFDFFFFFFAC0081F5 -0081F52BFDFFFFFFFFFFFFFFF60000000000FBF6F6F5F656F52BF900FA000000FCFAF5F656000000F7FFFFFFFFFFFFFDF7F68100 -00F6FB00F8FDFFFFFFFFFF810000000000F6F5000000F52B56F9FC00F7F70000FCF881FCF500000000FEFFFFFFFFAC5600FBF500 -000056F900F8ACFDFFFFFFF5000000000000002B0000FDFEFFFE560000F60000F9ACFFFE810000000081FFFEFDFAF800FAF70000 -000000FAF9002B56FAFDFC0000000000000000F80000FBF5FEFEF5000000000000ACFFFA2B0000000000FEFB2BF5008156000000 -00000000F9FBF600F6FBF800000000000000F7F8000000F9F9F9F82B0000000000F6ACACF70000000000F7FD2BFA812B00000000 -0000000000F681FCFBFD0000000000000000FBF6000000000000F52B000000000000F92B810000000000008181F6000000000000 -0000000000000000F6FC00000000000000F6FF0000000000000000000000000000000081FBFB2B00000000F7F900000000000000 -000000000000000000FC00000000000000FCFAF600000000000000000000000000000056ACF581FBF700000081FB000000000000 -0000000000000000FAF90000000000008156F5F8000000000000002BFBFCFBF800000000FD2B000056FB8181FBF8000000000000 -0000000000000000AC0000000000F5FBF90000F6000000000000F5AC56F6005681F50000F6ACFCFBF70000000000000000000000 -00000000000000F881000000F5FAFDFD00000000000000000000F7FEFA2B0000F581F70000000000810000000000000000000000 -000000000000F9FCF500FAFDACFAF5FD00000000000000000000F5ACF5FDFEFA0000F82B00000000810000000000000000000000 -000000000000FCF8F9AC81FD000000FD000000000000FAF7000000F50081F9FAF800000000000000FB0000000000000000000000 -000000000000FC81F956F5FD000000FD0000000000000000F800F5000000000056000000000000F7FB0000000000000000000000 -00000000000000000000F5AC000000ACF800000000000000F5FAF80000000000F50000000000F8ACF50000000000000000000000 -00000000000000000000F5AC000000F5AC000000000000000056F9000000000000000000F7ACFCF5000000000000000000000000 -00000000000000000000F5FD00000000AC000000000000000000FB0000000000000000F5F6F5FCF6000000000000000000000000 -0000000000000000000000FD00000000FBFDF600000000000000F8F900000000000000000000F5FB000000000000000000000000 -0000000000000000000000FDF500000000F9ACF800000000000000815600000000F656818181AC56000000000000000000000000 -000000000000000000000081F80000000000F9FC0000000000000000F9ACACACFCFBFAFA81FD2B00000000000000000000000000 -0000000000000000000000F7FB0000000000FBF70000000000000000000000000000000000FB0000000000000000000000000000 -000000000000000000000000ACF500000000F9FD56F5000000000000000000000000000000FB0000000000000000000000000000 -000000000000000000000000F8FA0000000000F6FEFEF5000000000000F55681FCACFDACFC560000000000000000000000000000 -00000000000000000000000000FBF600000000002BFCFA00F700000000F9FDFDFAFEF90000000000000000000000000000000000 -00000000000000000000000000F5FB0000000000F5FEF7ACAC0000000000000000FCF50000000000000000000000000000000000 -0000000000000000000000000000F6FA000000002BFF2BFFFFAC00000000000000F7FA0000000000000000000000000000000000 -000000000000000000000000000000F65600000000FAFEFFFFAC0000000000F800F6810000000000000000000000000000000000 -00000000000000000000000000000000F52B00000000F8FEFBFF5600000000FCFAACF60000000000000000000000000000000000 -0000000000000000000000000000000000000000000000F9FCFCFFFB00F8FEFFFDF5000000000000000000000000000000000000 -00000000000000000000000000000000000000000000F9FDF7F5FFFD56FFFFFFFD00000000000000000000000000000000000000 -00000000000000000000000000000000000000000000810000FBFFFFFBFFFFFFFFACF9F5F5000000000000000000000000000000 -0000000000000000000000000000000000000000000000F600FC81FFFEFFFFFFFFFFFE8100000000000000000000000000000000 -00000000000000000000000000000000000000000000000000F7F6FDFFFFFFFEFFFFACF500000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000F5FC81FC81FAFBF9F500000000000000000000000000000000 - -00000000000000F781FB8181818181FBFAF500000000000000000000000000000000000000F6FAFAFAFA81F9F600000000000000 -0000000000F8FBF9F500F95656FCFB5656FBF800000000000000000000000000000000F5FAF9F5F7F600F6F6F9FAF70000000000 -000000F5FBFA0056FDFEFEFDFDFAAC81FB56568181560000000000000000000000F9F9F9F7FCFDFEFEFEFFFC81F656FA00000000 -0000F5AC2BF7FBFEFEFD2BF6568181F9F7F6F6F8FBF50000000000000000000000FAF700F600F5F7F7F6F7FEFFACF82BFB000000 -0000FC2BF5FEFFFFF5F7FC81F70000F7F9FAFAF8000000000000000000000000000056F9F9FAF9F7F7FA812BF7FFFF56F7FA0000 -005656F5FEFFAC2BF9FA000000000000000000000000000000000000000000000000000000000000000000FA56FAFEFEF8F9F700 -00FB00F7FFFF56F9F800000000000000000000F656FAFA56F50000000000F5F8F9F8F5000000000000000000F9F7FCFFFB00FB00 -F8F800ACFFACF6FA000000000000000000F6FA562BF5F5F781FA000000F9FA2B00F556F9F5000000000000000081F8FFFEF6562B -810000FFFFF9FAF500000000000000002B8100F5F9FCACFBF82BFBF6FCFAF6FAFC81F600FA2B000000000000002BF8FEFFF8F5FA -FA00F5FEFFFA8100000000000000002B8100F9FEFFFFFFFFFFFBF6FDFEACFDFEFFFFFFFBF581F600000000000000F9FEFFF700FA -FA00FBFFFEF6F900000000000000F6FB00FCFFFFFFFFFFFFFFFFFCF600FCF7ACFEFFFFFFFDF6810000000000000056F9FFAC00FA -FA00F6FFFFF856000000000000F5FBF5ACFFFFFFFFFFFFFFFFFFFF2B002BF8F5ACFFFFFFFFFDF6FA000000000000F9FCFF560081 -FA0081FFFFF8F9000000000000FBF6FBFFFFFFFFFFFFFFFFFFFFFFF800F55600FCFFFFFFFFFF81F8F80000000000F981FFAC0081 -FA0000FEFEF8FB0000000000812BFAFFFFFFFFFFFFFEFFFFFDF92BFA0000F6F981ACFEFFFFFFFF56F9F600000000F9FDFF2B0081 -FA00FAFFFF81812B000000FAF8F9FFFFFEACFBF80000F500000000F9F900562B0000FCF7F9ACFFFF2BF9F50000F9F6FEFFFB0081 -810000FCFFFBF6FB56F7FBF8F9FFFE5600000000F5FAAC000000F82BF6FAFBF800F556F80000F9FFFE2BFAFAFAF8FAFFFEF60081 -FAF6F5ACFFFFAC00F856F7ACFFFCF500000000FAFCFFFC00000056AC00F581F92BFEF9FAF6000081FFFFFBF6F62BFFFFACF6F6FA -F6FA00FAFFFFFFACFA56FFFFAC0000000000F6FD2BFEF6F5565600F5F800F60081FEF7F656000000FDFFFFFDFDFFFFFFAC0081F5 -0081F52BFDFFFFFFFFFFFFFFF60000000000FBF6F6F5F656F52BF900FA000000FCFAF5F656000000F7FFFFFFFFFFFFFDF7F68100 -00F6FB00F8FDFFFFFFFFFF810000000000F6F5000000F52B56F9FC00F7F70000FCF881FCF500000000FEFFFFFFFFAC5600FBF500 -000056F900F8ACFDFFFFFFF5000000000000002B0000FDFEFFFE560000F60000F9ACFFFE810000000081FFFEFDFAF800FAF70000 -000000FAF9002B56FAFDFC0000000000000000F80000FBF5FEFEF5000000000000ACFFFA2B0000000000FEFB2BF5008156000000 -00000000F9FBF600F6FBF800000000000000F7F8000000F9F9F9F82B0000000000F6ACACF70000000000F7FD2BFA812B00000000 -0000000000F681FCFBFD0000000000000000FBF6000000000000F52B000000000000F92B810000000000008181F6000000000000 -0000000000000000F6FC00000000000000F6FF0000000000000000000000000000000081FBFB2B00000000F7F900000000000000 -000000000000000000FC00000000000000FCFAF600000000000000000000000000000056ACF581FBF700000081FB000000000000 -0000000000000000FAF90000000000008156F5F8000000000000002BFBFCFBF800000000FD2B000056FB8181FBF8000000000000 -0000000000000000AC0000000000F5FBF90000F6000000000000F5AC56F6005681F50000F6ACFCFBF70000000000000000000000 -00000000000000F881000000F5FAFDFD00000000000000000000F7FEFA2B0000F581F70000000000810000000000000000000000 -000000000000F9FCF500FAFDACFAF5FD00000000000000000000F5ACF5FDFEFA0000F82B00000000810000000000000000000000 -000000000000FCF8F9AC81FD000000FD000000000000FAF7000000F50081F9FAF800000000000000FB0000000000000000000000 -000000000000FC81F956F5FD000000FD0000000000000000F800F5000000000056000000000000F7FB0000000000000000000000 -00000000000000000000F5AC000000ACF800000000000000F5FAF80000000000F50000000000F8ACF50000000000000000000000 -00000000000000000000F5AC000000F5AC000000000000000056F9000000000000000000F7ACFCF5000000000000000000000000 -00000000000000000000F5FD00000000AC000000000000000000FB0000000000000000F5F6F5FCF6000000000000000000000000 -0000000000000000000000FD00000000FBFDF600000000000000F8F900000000000000000000F5FB000000000000000000000000 -0000000000000000000000FDF500000000F9ACF800000000000000815600000000F656818181AC56000000000000000000000000 -000000000000000000000081F80000000000F9FC0000000000000000F9ACACACFCFBFAFA81FD2B00000000000000000000000000 -0000000000000000000000F7FB0000000000FBF70000000000000000000000000000000000FB0000000000000000000000000000 -000000000000000000000000ACF500000000F9FD56F5000000000000000000000000000000FB0000000000000000000000000000 -000000000000000000000000F8FA0000000000F6FEFEF5000000000000F55681FCACFDACFC560000000000000000000000000000 -00000000000000000000000000FBF600000000002BFCFA00F700000000F9FDFDFAFEF90000000000000000000000000000000000 -00000000000000000000000000F5FB0000000000F5FEF7ACAC0000000000000000FCF50000000000000000000000000000000000 -0000000000000000000000000000F6FA000000002BFF2BFFFFAC00000000000000F7FA0000000000000000000000000000000000 -000000000000000000000000000000F65600000000FAFEFFFFAC0000000000F800F6810000000000000000000000000000000000 -00000000000000000000000000000000F52B00000000F8FEFBFF5600000000FCFAACF60000000000000000000000000000000000 -0000000000000000000000000000000000000000000000F9FCFCFFFB00F8FEFFFDF5000000000000000000000000000000000000 -00000000000000000000000000000000000000000000F9FDF7F5FFFD56FFFFFFFD00000000000000000000000000000000000000 -00000000000000000000000000000000000000000000810000FBFFFFFBFFFFFFFFACF9F5F5000000000000000000000000000000 -0000000000000000000000000000000000000000000000F600FC81FFFEFFFFFFFFFFFE8100000000000000000000000000000000 -00000000000000000000000000000000000000000000000000F7F6FDFFFFFFFEFFFFACF500000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000F5FC81FC81FAFBF9F500000000000000000000000000000000 - -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - - -boot &device;:&partition;,\System\Library\CoreServices\grub.elf - - diff --git a/grub-core/bus/bonito.c b/grub-core/bus/bonito.c deleted file mode 100644 index 23b9a9915..000000000 --- a/grub-core/bus/bonito.c +++ /dev/null @@ -1,176 +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 . - */ - -#include -#include - -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}; - -grub_bonito_type_t grub_bonito_type; - -static volatile void * -config_addr (grub_pci_address_t addr) -{ - if (grub_bonito_type == GRUB_BONITO_2F) - { - GRUB_MACHINE_PCI_CONF_CTRL_REG_2F = 1 << ((addr >> 11) & 0xf); - return (volatile void *) (GRUB_MACHINE_PCI_CONFSPACE_2F - | (addr & 0x07ff)); - } - else - { - - if (addr >> 16) - return (volatile void *) (GRUB_MACHINE_PCI_CONFSPACE_3A_EXT | addr); - else - return (volatile void *) (GRUB_MACHINE_PCI_CONFSPACE_3A | addr); - } -} - -grub_uint32_t -grub_pci_read (grub_pci_address_t addr) -{ - return *(volatile grub_uint32_t *) config_addr (addr); -} - -grub_uint16_t -grub_pci_read_word (grub_pci_address_t addr) -{ - return *(volatile grub_uint16_t *) config_addr (addr); -} - -grub_uint8_t -grub_pci_read_byte (grub_pci_address_t addr) -{ - return *(volatile grub_uint8_t *) config_addr (addr); -} - -void -grub_pci_write (grub_pci_address_t addr, grub_uint32_t data) -{ - *(volatile grub_uint32_t *) config_addr (addr) = data; -} - -void -grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data) -{ - *(volatile grub_uint16_t *) config_addr (addr) = data; -} - -void -grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) -{ - *(volatile grub_uint8_t *) config_addr (addr) = data; -} - - -static inline void -write_bases_2f (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_2F = reg; -} - -volatile void * -grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), - grub_addr_t base, grub_size_t size) -{ - if (grub_bonito_type == GRUB_BONITO_2F) - { - 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_2f (); - return (void *) - (addr_win[i] | (base & GRUB_MACHINE_PCI_WIN_OFFSET_MASK)); - } - grub_fatal ("Out of PCI windows."); - } - else - { - int region = 0; - if (base >= 0x10000000 - && base + size <= 0x18000000) - region = 1; - if (base >= 0x1c000000 - && base + size <= 0x1f000000) - region = 2; - if (region == 0) - grub_fatal ("Attempt to map out of regions"); - return (void *) (0xa0000000 | base); - } -} - -void * -grub_pci_device_map_range_cached (grub_pci_device_t dev, - grub_addr_t base, grub_size_t size) -{ - return (void *) (((grub_addr_t) grub_pci_device_map_range (dev, base, size)) - & ~0x20000000); -} - -void -grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), - volatile void *mem, - grub_size_t size __attribute__ ((unused))) -{ - if (grub_bonito_type == GRUB_BONITO_2F) - { - int i; - for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) - if (usage_win[i] && addr_win[i] - == (((grub_addr_t) mem | 0x20000000) - & ~GRUB_MACHINE_PCI_WIN_OFFSET_MASK)) - { - usage_win[i]--; - return; - } - grub_fatal ("Tried to unmap not mapped region"); - } -} diff --git a/grub-core/bus/cs5536.c b/grub-core/bus/cs5536.c deleted file mode 100644 index cd0a45e58..000000000 --- a/grub-core/bus/cs5536.c +++ /dev/null @@ -1,382 +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 . - */ - -#include -#include -#include -#include -#include -#ifdef GRUB_MACHINE_MIPS_LOONGSON -#include -#endif - -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* Context for grub_cs5536_find. */ -struct grub_cs5536_find_ctx -{ - grub_pci_device_t *devp; - int found; -}; - -/* Helper for grub_cs5536_find. */ -static int -grub_cs5536_find_iter (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) -{ - struct grub_cs5536_find_ctx *ctx = data; - - if (pciid == GRUB_CS5536_PCIID) - { - *ctx->devp = dev; - ctx->found = 1; - return 1; - } - return 0; -} - -int -grub_cs5536_find (grub_pci_device_t *devp) -{ - struct grub_cs5536_find_ctx ctx = { - .devp = devp, - .found = 0 - }; - - grub_pci_iterate (grub_cs5536_find_iter, &ctx); - - return ctx.found; -} - -grub_uint64_t -grub_cs5536_read_msr (grub_pci_device_t dev, grub_uint32_t addr) -{ - grub_uint64_t ret = 0; - grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_ADDR), - addr); - ret = (grub_uint64_t) - grub_pci_read (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA0)); - ret |= (((grub_uint64_t) - grub_pci_read (grub_pci_make_address (dev, - GRUB_CS5536_MSR_MAILBOX_DATA1))) - << 32); - return ret; -} - -void -grub_cs5536_write_msr (grub_pci_device_t dev, grub_uint32_t addr, - grub_uint64_t val) -{ - grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_ADDR), - addr); - grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA0), - val & 0xffffffff); - grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA1), - val >> 32); -} - -grub_err_t -grub_cs5536_smbus_wait (grub_port_t smbbase) -{ - grub_uint64_t start = grub_get_time_ms (); - while (1) - { - grub_uint8_t status; - status = grub_inb (smbbase + GRUB_CS5536_SMB_REG_STATUS); - if (status & GRUB_CS5536_SMB_REG_STATUS_SDAST) - return GRUB_ERR_NONE; - if (status & GRUB_CS5536_SMB_REG_STATUS_BER) - return grub_error (GRUB_ERR_IO, "SM bus error"); - if (status & GRUB_CS5536_SMB_REG_STATUS_NACK) - return grub_error (GRUB_ERR_IO, "NACK received"); - if (grub_get_time_ms () > start + 40) - return grub_error (GRUB_ERR_IO, "SM stalled"); - } -} - -grub_err_t -grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev, - grub_uint8_t addr, grub_uint8_t *res) -{ - grub_err_t err; - - /* Send START. */ - grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) - | GRUB_CS5536_SMB_REG_CTRL1_START, - smbbase + GRUB_CS5536_SMB_REG_CTRL1); - - /* Send device address. */ - err = grub_cs5536_smbus_wait (smbbase); - if (err) - return err; - grub_outb (dev << 1, smbbase + GRUB_CS5536_SMB_REG_DATA); - - /* Send ACK. */ - err = grub_cs5536_smbus_wait (smbbase); - if (err) - return err; - grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) - | GRUB_CS5536_SMB_REG_CTRL1_ACK, - smbbase + GRUB_CS5536_SMB_REG_CTRL1); - - /* Send byte address. */ - grub_outb (addr, smbbase + GRUB_CS5536_SMB_REG_DATA); - - /* Send START. */ - err = grub_cs5536_smbus_wait (smbbase); - if (err) - return err; - grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) - | GRUB_CS5536_SMB_REG_CTRL1_START, - smbbase + GRUB_CS5536_SMB_REG_CTRL1); - - /* Send device address. */ - err = grub_cs5536_smbus_wait (smbbase); - if (err) - return err; - grub_outb ((dev << 1) | 1, smbbase + GRUB_CS5536_SMB_REG_DATA); - - /* Send STOP. */ - err = grub_cs5536_smbus_wait (smbbase); - if (err) - return err; - grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) - | GRUB_CS5536_SMB_REG_CTRL1_STOP, - smbbase + GRUB_CS5536_SMB_REG_CTRL1); - - err = grub_cs5536_smbus_wait (smbbase); - if (err) - return err; - *res = grub_inb (smbbase + GRUB_CS5536_SMB_REG_DATA); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_cs5536_init_smbus (grub_pci_device_t dev, grub_uint16_t divisor, - grub_port_t *smbbase) -{ - grub_uint64_t smbbar; - - smbbar = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_SMB_BAR); - - /* FIXME */ - if (!(smbbar & GRUB_CS5536_LBAR_ENABLE)) - return grub_error(GRUB_ERR_IO, "SMB controller not enabled\n"); - *smbbase = (smbbar & GRUB_CS5536_LBAR_ADDR_MASK) + GRUB_MACHINE_PCI_IO_BASE; - - if (divisor < 8) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid divisor"); - - /* Disable SMB. */ - grub_outb (0, *smbbase + GRUB_CS5536_SMB_REG_CTRL2); - - /* Disable interrupts. */ - grub_outb (0, *smbbase + GRUB_CS5536_SMB_REG_CTRL1); - - /* Set as master. */ - grub_outb (GRUB_CS5536_SMB_REG_ADDR_MASTER, - *smbbase + GRUB_CS5536_SMB_REG_ADDR); - - /* Launch. */ - grub_outb (((divisor >> 7) & 0xff), *smbbase + GRUB_CS5536_SMB_REG_CTRL3); - grub_outb (((divisor << 1) & 0xfe) | GRUB_CS5536_SMB_REG_CTRL2_ENABLE, - *smbbase + GRUB_CS5536_SMB_REG_CTRL2); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev, - struct grub_smbus_spd *res) -{ - grub_err_t err; - grub_size_t size; - grub_uint8_t b; - grub_size_t ptr; - - err = grub_cs5536_read_spd_byte (smbbase, dev, 0, &b); - if (err) - return err; - if (b == 0) - return grub_error (GRUB_ERR_IO, "no SPD found"); - size = b; - - ((grub_uint8_t *) res)[0] = b; - for (ptr = 1; ptr < size; ptr++) - { - err = grub_cs5536_read_spd_byte (smbbase, dev, ptr, - &((grub_uint8_t *) res)[ptr]); - if (err) - return err; - } - return GRUB_ERR_NONE; -} - -static inline void -set_io_space (grub_pci_device_t dev, int num, grub_uint16_t start, - grub_uint16_t len) -{ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_REGIONS_START + num, - ((((grub_uint64_t) start + len - 4) - << GRUB_CS5536_MSR_GL_REGION_IO_TOP_SHIFT) - & GRUB_CS5536_MSR_GL_REGION_TOP_MASK) - | (((grub_uint64_t) start - << GRUB_CS5536_MSR_GL_REGION_IO_BASE_SHIFT) - & GRUB_CS5536_MSR_GL_REGION_BASE_MASK) - | GRUB_CS5536_MSR_GL_REGION_IO - | GRUB_CS5536_MSR_GL_REGION_ENABLE); -} - -static inline void -set_iod (grub_pci_device_t dev, int num, int dest, int start, int mask) -{ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_IOD_START + num, - ((grub_uint64_t) dest << GRUB_CS5536_IOD_DEST_SHIFT) - | (((grub_uint64_t) start & GRUB_CS5536_IOD_ADDR_MASK) - << GRUB_CS5536_IOD_BASE_SHIFT) - | ((mask & GRUB_CS5536_IOD_ADDR_MASK) - << GRUB_CS5536_IOD_MASK_SHIFT)); -} - -static inline void -set_p2d (grub_pci_device_t dev, int num, int dest, grub_uint32_t start) -{ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_P2D_START + num, - (((grub_uint64_t) dest) << GRUB_CS5536_P2D_DEST_SHIFT) - | ((grub_uint64_t) (start >> GRUB_CS5536_P2D_LOG_ALIGN) - << GRUB_CS5536_P2D_BASE_SHIFT) - | (((1 << (32 - GRUB_CS5536_P2D_LOG_ALIGN)) - 1) - << GRUB_CS5536_P2D_MASK_SHIFT)); -} - -void -grub_cs5536_init_geode (grub_pci_device_t dev) -{ - /* Enable more BARs. */ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IRQ_MAP_BAR, - GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_IRQ_MAP); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_MFGPT_BAR, - GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_MFGPT); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_ACPI_BAR, - GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_ACPI); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_PM_BAR, - GRUB_CS5536_LBAR_TURN_ON | GRUB_CS5536_LBAR_PM); - - /* Setup DIVIL. */ -#ifdef GRUB_MACHINE_MIPS_LOONGSON - switch (grub_arch_machine) - { - case GRUB_ARCH_MACHINE_YEELOONG: - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LEG_IO, - GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 - | GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP - | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 - | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1); - break; - case GRUB_ARCH_MACHINE_FULOONG2F: - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LEG_IO, - GRUB_CS5536_MSR_DIVIL_LEG_IO_UART2_COM3 - | GRUB_CS5536_MSR_DIVIL_LEG_IO_UART1_COM1 - | GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 - | GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP - | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 - | GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1); - break; - } -#endif - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK, - (~GRUB_CS5536_DIVIL_LPC_INTERRUPTS) & 0xffff); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK, - GRUB_CS5536_DIVIL_LPC_INTERRUPTS); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL, - GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL_ENABLE); - - /* Initialise USB controller. */ - /* FIXME: assign adresses dynamically. */ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE, - GRUB_CS5536_MSR_USB_BASE_BUS_MASTER - | GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE - | 0x05024000); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE, - GRUB_CS5536_MSR_USB_BASE_BUS_MASTER - | GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE - | (0x20ULL << GRUB_CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT) - | 0x05023000); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_CONTROLLER_BASE, - GRUB_CS5536_MSR_USB_BASE_BUS_MASTER - | GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE | 0x05020000); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OPTION_CONTROLLER_BASE, - GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE | 0x05022000); - set_p2d (dev, 0, GRUB_CS5536_DESTINATION_USB, 0x05020000); - set_p2d (dev, 1, GRUB_CS5536_DESTINATION_USB, 0x05022000); - set_p2d (dev, 5, GRUB_CS5536_DESTINATION_USB, 0x05024000); - set_p2d (dev, 6, GRUB_CS5536_DESTINATION_USB, 0x05023000); - - { - volatile grub_uint32_t *oc; - - oc = grub_absolute_pointer (grub_pci_device_map_range (dev, 0x05022000, - GRUB_CS5536_USB_OPTION_REGS_SIZE)); - - oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX] = - (oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX] - & ~GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_MASK) - | GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_HC; - grub_pci_device_unmap_range (dev, oc, GRUB_CS5536_USB_OPTION_REGS_SIZE); - } - - /* Setup IDE controller. */ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_IO_BAR, - GRUB_CS5536_LBAR_IDE - | GRUB_CS5536_MSR_IDE_IO_BAR_UNITS); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_CFG, - GRUB_CS5536_MSR_IDE_CFG_CHANNEL_ENABLE); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_TIMING, - (GRUB_CS5536_MSR_IDE_TIMING_PIO0 - << GRUB_CS5536_MSR_IDE_TIMING_DRIVE0_SHIFT) - | (GRUB_CS5536_MSR_IDE_TIMING_PIO0 - << GRUB_CS5536_MSR_IDE_TIMING_DRIVE1_SHIFT)); - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_IDE_CAS_TIMING, - (GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_PIO0 - << GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_SHIFT) - | (GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 - << GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE0_SHIFT) - | (GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 - << GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE1_SHIFT)); - - /* Setup Geodelink PCI. */ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_GL_PCI_CTRL, - (4ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_OUT_THR_SHIFT) - | (4ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_IN_THR_SHIFT) - | (8ULL << GRUB_CS5536_MSR_GL_PCI_CTRL_LATENCY_SHIFT) - | GRUB_CS5536_MSR_GL_PCI_CTRL_IO_ENABLE - | GRUB_CS5536_MSR_GL_PCI_CTRL_MEMORY_ENABLE); - - /* Setup windows. */ - set_io_space (dev, 0, GRUB_CS5536_LBAR_SMBUS, GRUB_CS5536_SMBUS_REGS_SIZE); - set_io_space (dev, 1, GRUB_CS5536_LBAR_GPIO, GRUB_CS5536_GPIO_REGS_SIZE); - set_io_space (dev, 2, GRUB_CS5536_LBAR_MFGPT, GRUB_CS5536_MFGPT_REGS_SIZE); - set_io_space (dev, 3, GRUB_CS5536_LBAR_IRQ_MAP, GRUB_CS5536_IRQ_MAP_REGS_SIZE); - set_io_space (dev, 4, GRUB_CS5536_LBAR_PM, GRUB_CS5536_PM_REGS_SIZE); - set_io_space (dev, 5, GRUB_CS5536_LBAR_ACPI, GRUB_CS5536_ACPI_REGS_SIZE); - set_iod (dev, 0, GRUB_CS5536_DESTINATION_IDE, GRUB_ATA_CH0_PORT1, 0xffff8); - set_iod (dev, 1, GRUB_CS5536_DESTINATION_ACC, GRUB_CS5536_LBAR_ACC, 0xfff80); - set_iod (dev, 2, GRUB_CS5536_DESTINATION_IDE, GRUB_CS5536_LBAR_IDE, 0xffff0); -} diff --git a/grub-core/bus/fdt.c b/grub-core/bus/fdt.c deleted file mode 100644 index 135da497b..000000000 --- a/grub-core/bus/fdt.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2016 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -static const void *dtb; -static grub_size_t root_address_cells, root_size_cells; -/* Pointer to this symbol signals invalid mapping. */ -char grub_fdtbus_invalid_mapping[1]; - -struct grub_fdtbus_dev *devs; -struct grub_fdtbus_driver *drivers; - -int -grub_fdtbus_is_compatible (const char *compat_string, - const struct grub_fdtbus_dev *dev) -{ - grub_size_t compatible_size; - const char *compatible = grub_fdt_get_prop (dtb, dev->node, "compatible", - &compatible_size); - if (!compatible) - return 0; - const char *compatible_end = compatible + compatible_size; - while (compatible < compatible_end) - { - if (grub_strcmp (compat_string, compatible) == 0) - return 1; - compatible += grub_strlen (compatible) + 1; - } - return 0; -} - -static void -fdtbus_scan (struct grub_fdtbus_dev *parent) -{ - int node; - for (node = grub_fdt_first_node (dtb, parent ? parent->node : 0); node >= 0; - node = grub_fdt_next_node (dtb, node)) - { - struct grub_fdtbus_dev *dev; - struct grub_fdtbus_driver *driver; - dev = grub_zalloc (sizeof (*dev)); - if (!dev) - { - grub_print_error (); - return; - } - dev->node = node; - dev->next = devs; - dev->parent = parent; - devs = dev; - FOR_LIST_ELEMENTS(driver, drivers) - if (!dev->driver && grub_fdtbus_is_compatible (driver->compatible, dev)) - { - grub_dprintf ("fdtbus", "Attaching %s\n", driver->compatible); - if (driver->attach (dev) == GRUB_ERR_NONE) - { - grub_dprintf ("fdtbus", "Attached %s\n", driver->compatible); - dev->driver = driver; - break; - } - grub_print_error (); - } - fdtbus_scan (dev); - } -} - -void -grub_fdtbus_register (struct grub_fdtbus_driver *driver) -{ - struct grub_fdtbus_dev *dev; - grub_dprintf ("fdtbus", "Registering %s\n", driver->compatible); - grub_list_push (GRUB_AS_LIST_P (&drivers), - GRUB_AS_LIST (driver)); - for (dev = devs; dev; dev = dev->next) - if (!dev->driver && grub_fdtbus_is_compatible (driver->compatible, dev)) - { - grub_dprintf ("fdtbus", "Attaching %s (%p)\n", driver->compatible, dev); - if (driver->attach (dev) == GRUB_ERR_NONE) - { - grub_dprintf ("fdtbus", "Attached %s\n", driver->compatible); - dev->driver = driver; - } - grub_print_error (); - } -} - -void -grub_fdtbus_unregister (struct grub_fdtbus_driver *driver) -{ - grub_list_remove (GRUB_AS_LIST (driver)); - struct grub_fdtbus_dev *dev; - for (dev = devs; dev; dev = dev->next) - if (dev->driver == driver) - { - if (driver->detach) - driver->detach(dev); - dev->driver = 0; - } -} - -void -grub_fdtbus_init (const void *dtb_in, grub_size_t size) -{ - if (!dtb_in || grub_fdt_check_header (dtb_in, size) < 0) - grub_fatal ("invalid FDT"); - dtb = dtb_in; - const grub_uint32_t *prop = grub_fdt_get_prop (dtb, 0, "#address-cells", 0); - if (prop) - root_address_cells = grub_be_to_cpu32 (*prop); - else - root_address_cells = 1; - - prop = grub_fdt_get_prop (dtb, 0, "#size-cells", 0); - if (prop) - root_size_cells = grub_be_to_cpu32 (*prop); - else - root_size_cells = 1; - - fdtbus_scan (0); -} - -static int -get_address_cells (const struct grub_fdtbus_dev *dev) -{ - const grub_uint32_t *prop; - if (!dev) - return root_address_cells; - prop = grub_fdt_get_prop (dtb, dev->node, "#address-cells", 0); - if (prop) - return grub_be_to_cpu32 (*prop); - return 1; -} - -static int -get_size_cells (const struct grub_fdtbus_dev *dev) -{ - const grub_uint32_t *prop; - if (!dev) - return root_size_cells; - prop = grub_fdt_get_prop (dtb, dev->node, "#size-cells", 0); - if (prop) - return grub_be_to_cpu32 (*prop); - return 1; -} - -static grub_uint64_t -get64 (const grub_uint32_t *reg, grub_size_t cells) -{ - grub_uint64_t val = 0; - if (cells >= 1) - val = grub_be_to_cpu32 (reg[cells - 1]); - if (cells >= 2) - val |= ((grub_uint64_t) grub_be_to_cpu32 (reg[cells - 2])) << 32; - return val; -} - -static volatile void * -translate (const struct grub_fdtbus_dev *dev, const grub_uint32_t *reg) -{ - volatile void *ret; - const grub_uint32_t *ranges; - grub_size_t ranges_size, cells_per_mapping; - grub_size_t parent_address_cells, child_address_cells, child_size_cells; - grub_size_t nmappings, i; - if (dev == 0) - { - grub_uint64_t val; - val = get64 (reg, root_address_cells); - if (sizeof (void *) == 4 && (val >> 32)) - return grub_fdtbus_invalid_mapping; - return (void *) (grub_addr_t) val; - } - ranges = grub_fdt_get_prop (dtb, dev->node, "ranges", &ranges_size); - if (!ranges) - return grub_fdtbus_invalid_mapping; - if (ranges_size == 0) - return translate (dev->parent, reg); - parent_address_cells = get_address_cells (dev->parent); - child_address_cells = get_address_cells (dev); - child_size_cells = get_size_cells (dev); - cells_per_mapping = parent_address_cells + child_address_cells + child_size_cells; - nmappings = ranges_size / 4 / cells_per_mapping; - for (i = 0; i < nmappings; i++) - { - const grub_uint32_t *child_addr = &ranges[i * cells_per_mapping]; - const grub_uint32_t *parent_addr = child_addr + child_address_cells; - grub_uint64_t child_size = get64 (parent_addr + parent_address_cells, child_size_cells); - - if (child_address_cells > 2 && grub_memcmp (reg, child_addr, (child_address_cells - 2) * 4) != 0) - continue; - if (get64 (reg, child_address_cells) < get64 (child_addr, child_address_cells)) - continue; - - grub_uint64_t offset = get64 (reg, child_address_cells) - get64 (child_addr, child_address_cells); - if (offset >= child_size) - continue; - - ret = translate (dev->parent, parent_addr); - if (grub_fdtbus_is_mapping_valid (ret)) - ret = (volatile char *) ret + offset; - return ret; - } - return grub_fdtbus_invalid_mapping; -} - -volatile void * -grub_fdtbus_map_reg (const struct grub_fdtbus_dev *dev, int regno, grub_size_t *size) -{ - grub_size_t address_cells, size_cells; - address_cells = get_address_cells (dev->parent); - size_cells = get_size_cells (dev->parent); - const grub_uint32_t *reg = grub_fdt_get_prop (dtb, dev->node, "reg", 0); - if (size && size_cells) - *size = reg[(address_cells + size_cells) * regno + address_cells]; - if (size && !size_cells) - *size = 0; - return translate (dev->parent, reg + (address_cells + size_cells) * regno); -} - -const char * -grub_fdtbus_get_name (const struct grub_fdtbus_dev *dev) -{ - return grub_fdt_get_nodename (dtb, dev->node); -} - -const void * -grub_fdtbus_get_prop (const struct grub_fdtbus_dev *dev, - const char *name, - grub_uint32_t *len) -{ - return grub_fdt_get_prop (dtb, dev->node, name, len); -} - -const void * -grub_fdtbus_get_fdt (void) -{ - return dtb; -} diff --git a/grub-core/bus/i386/ieee1275/pci.c b/grub-core/bus/i386/ieee1275/pci.c deleted file mode 100644 index 1fd3b5610..000000000 --- a/grub-core/bus/i386/ieee1275/pci.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include - -volatile void * -grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), - grub_addr_t base, - grub_size_t size) -{ - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_REAL_MODE)) - return (volatile void *) base; - if (grub_ieee1275_map (base, base, size, 7)) - grub_fatal ("couldn't map 0x%lx", base); - return (volatile void *) base; -} - -void -grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), - volatile void *mem __attribute__ ((unused)), - grub_size_t size __attribute__ ((unused))) -{ -} diff --git a/grub-core/bus/pci.c b/grub-core/bus/pci.c deleted file mode 100644 index c1ee9dc58..000000000 --- a/grub-core/bus/pci.c +++ /dev/null @@ -1,173 +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 . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* FIXME: correctly support 64-bit architectures. */ -/* #if GRUB_TARGET_SIZEOF_VOID_P == 4 */ -struct grub_pci_dma_chunk * -grub_memalign_dma32 (grub_size_t align, grub_size_t size) -{ - void *ret; - if (align < 64) - align = 64; - size = ALIGN_UP (size, align); - ret = grub_memalign (align, size); -#if GRUB_CPU_SIZEOF_VOID_P == 8 - if ((grub_addr_t) ret >> 32) - { - /* Shouldn't happend since the only platform in this case is - x86_64-efi and it skips any regions > 4GiB because - of EFI bugs anyway. */ - grub_error (GRUB_ERR_BUG, "allocation outside 32-bit range"); - return 0; - } -#endif - if (!ret) - return 0; - grub_arch_sync_dma_caches (ret, size); - return ret; -} - -/* FIXME: evil. */ -void -grub_dma_free (struct grub_pci_dma_chunk *ch) -{ - grub_size_t size = (((struct grub_mm_header *) ch) - 1)->size * GRUB_MM_ALIGN; - grub_arch_sync_dma_caches (ch, size); - grub_free (ch); -} -/* #endif */ - -#ifdef GRUB_MACHINE_MIPS_LOONGSON -volatile void * -grub_dma_get_virt (struct grub_pci_dma_chunk *ch) -{ - return (void *) ((((grub_uint32_t) ch) & 0x1fffffff) | 0xa0000000); -} - -grub_uint32_t -grub_dma_get_phys (struct grub_pci_dma_chunk *ch) -{ - return (((grub_uint32_t) ch) & 0x1fffffff) | 0x80000000; -} -#else - -volatile void * -grub_dma_get_virt (struct grub_pci_dma_chunk *ch) -{ - return (void *) ch; -} - -grub_uint32_t -grub_dma_get_phys (struct grub_pci_dma_chunk *ch) -{ - return (grub_uint32_t) (grub_addr_t) ch; -} - -#endif - -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, void *hook_data) -{ - 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) - { - if (dev.function == 0) - /* Devices are required to implement function 0, so if - it's missing then there is no device here. */ - break; - else - continue; - } - - if (hook (dev, id, hook_data)) - 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; - } - } - } - } -} - -grub_uint8_t -grub_pci_find_capability (grub_pci_device_t dev, grub_uint8_t cap) -{ - grub_uint8_t pos = 0x34; - int ttl = 48; - - while (ttl--) - { - grub_uint8_t id; - grub_pci_address_t addr; - - addr = grub_pci_make_address (dev, pos); - pos = grub_pci_read_byte (addr); - if (pos < 0x40) - break; - - pos &= ~3; - - addr = grub_pci_make_address (dev, pos); - id = grub_pci_read_byte (addr); - - if (id == 0xff) - break; - - if (id == cap) - return pos; - pos++; - } - return 0; -} diff --git a/grub-core/bus/spi/rk3288_spi.c b/grub-core/bus/spi/rk3288_spi.c deleted file mode 100644 index aacb79ffe..000000000 --- a/grub-core/bus/spi/rk3288_spi.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * - * Copyright (C) 2012 Google Inc. - * Copyright (C) 2016 Free Software Foundation, Inc. - * - * This is based on depthcharge code. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include - -static grub_err_t -spi_send (const struct grub_fdtbus_dev *dev, const void *data, grub_size_t sz) -{ - const grub_uint8_t *ptr = data, *end = ptr + sz; - volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0); - spi[2] = 0; - spi[1] = sz - 1; - spi[0] = ((1 << 18) | spi[0]) & ~(1 << 19); - spi[2] = 1; - while (ptr < end) - { - while (spi[9] & 2); - spi[256] = *ptr++; - } - while (spi[9] & 1); - return GRUB_ERR_NONE; -} - -static grub_err_t -spi_receive (const struct grub_fdtbus_dev *dev, void *data, grub_size_t sz) -{ - grub_uint8_t *ptr = data, *end = ptr + sz; - volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0); - spi[2] = 0; - spi[1] = sz - 1; - spi[0] = ((1 << 19) | spi[0]) & ~(1 << 18); - spi[2] = 1; - while (ptr < end) - { - while (spi[9] & 8); - *ptr++ = spi[512]; - } - while (spi[9] & 1); - return GRUB_ERR_NONE; -} - -static grub_err_t -spi_start (const struct grub_fdtbus_dev *dev) -{ - volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0); - spi[3] = 1; - return GRUB_ERR_NONE; -} - -static void -spi_stop (const struct grub_fdtbus_dev *dev) -{ - volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0); - spi[3] = 0; -} - -static grub_err_t -spi_attach(const struct grub_fdtbus_dev *dev) -{ - if (!grub_fdtbus_is_mapping_valid (grub_fdtbus_map_reg (dev, 0, 0))) - return GRUB_ERR_IO; - - return GRUB_ERR_NONE; -} - -static struct grub_fdtbus_driver spi = -{ - .compatible = "rockchip,rk3288-spi", - .attach = spi_attach, - .send = spi_send, - .receive = spi_receive, - .start = spi_start, - .stop = spi_stop, -}; - -void -grub_rk3288_spi_init (void) -{ - grub_fdtbus_register (&spi); -} diff --git a/grub-core/bus/usb/ehci-pci.c b/grub-core/bus/usb/ehci-pci.c deleted file mode 100644 index aa04988fd..000000000 --- a/grub-core/bus/usb/ehci-pci.c +++ /dev/null @@ -1,208 +0,0 @@ -/* ehci.c - EHCI Support. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -#define GRUB_EHCI_PCI_SBRN_REG 0x60 -#define GRUB_EHCI_ADDR_MEM_MASK (~0xff) - -/* USBLEGSUP bits and related OS OWNED byte offset */ -enum -{ - GRUB_EHCI_BIOS_OWNED = (1 << 16), - GRUB_EHCI_OS_OWNED = (1 << 24) -}; - -/* PCI iteration function... */ -static int -grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, - void *data __attribute__ ((unused))) -{ - volatile grub_uint32_t *regs; - grub_uint32_t base, base_h; - grub_uint32_t eecp_offset; - grub_uint32_t usblegsup = 0; - grub_uint64_t maxtime; - grub_uint32_t interf; - grub_uint32_t subclass; - grub_uint32_t class; - grub_uint8_t release; - grub_uint32_t class_code; - - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: begin\n"); - - if (pciid == GRUB_CS5536_PCIID) - { - grub_uint64_t basereg; - - basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE); - if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE)) - { - /* Shouldn't happen. */ - grub_dprintf ("ehci", "No EHCI address is assigned\n"); - return 0; - } - base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK); - basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER; - basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED; - basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS; - basereg &= ~GRUB_CS5536_MSR_USB_BASE_SMI_ENABLE; - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE, basereg); - } - else - { - grub_pci_address_t addr; - 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 EHCI controller, just return. */ - if (class != 0x0c || subclass != 0x03 || interf != 0x20) - return 0; - - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: class OK\n"); - - /* Check Serial Bus Release Number */ - addr = grub_pci_make_address (dev, GRUB_EHCI_PCI_SBRN_REG); - release = grub_pci_read_byte (addr); - if (release != 0x20) - { - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: Wrong SBRN: %0x\n", - release); - return 0; - } - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: bus rev. num. OK\n"); - - /* Determine EHCI EHCC registers base address. */ - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - base = grub_pci_read (addr); - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1); - base_h = grub_pci_read (addr); - /* Stop if registers are mapped above 4G - GRUB does not currently - * work with registers mapped above 4G */ - if (((base & GRUB_PCI_ADDR_MEM_TYPE_MASK) != GRUB_PCI_ADDR_MEM_TYPE_32) - && (base_h != 0)) - { - grub_dprintf ("ehci", - "EHCI grub_ehci_pci_iter: registers above 4G are not supported\n"); - return 0; - } - base &= GRUB_PCI_ADDR_MEM_MASK; - if (!base) - { - grub_dprintf ("ehci", - "EHCI: EHCI is not mapped\n"); - return 0; - } - - /* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */ - addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write_word(addr, - GRUB_PCI_COMMAND_MEM_ENABLED - | GRUB_PCI_COMMAND_BUS_MASTER - | grub_pci_read_word(addr)); - - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: 32-bit EHCI OK\n"); - } - - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: iobase of EHCC: %08x\n", - (base & GRUB_EHCI_ADDR_MEM_MASK)); - - regs = grub_pci_device_map_range (dev, - (base & GRUB_EHCI_ADDR_MEM_MASK), - 0x100); - - /* Is there EECP ? */ - eecp_offset = (grub_le_to_cpu32 (regs[2]) >> 8) & 0xff; - - /* Determine and change ownership. */ - /* EECP offset valid in HCCPARAMS */ - /* Ownership can be changed via EECP only */ - if (pciid != GRUB_CS5536_PCIID && eecp_offset >= 0x40) - { - grub_pci_address_t pciaddr_eecp; - pciaddr_eecp = grub_pci_make_address (dev, eecp_offset); - - usblegsup = grub_pci_read (pciaddr_eecp); - if (usblegsup & GRUB_EHCI_BIOS_OWNED) - { - grub_boot_time ("Taking ownership of EHCI controller"); - grub_dprintf ("ehci", - "EHCI grub_ehci_pci_iter: EHCI owned by: BIOS\n"); - /* Ownership change - set OS_OWNED bit */ - grub_pci_write (pciaddr_eecp, usblegsup | GRUB_EHCI_OS_OWNED); - /* Ensure PCI register is written */ - grub_pci_read (pciaddr_eecp); - - /* Wait for finish of ownership change, EHCI specification - * doesn't say how long it can take... */ - maxtime = grub_get_time_ms () + 1000; - while ((grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED) - && (grub_get_time_ms () < maxtime)); - if (grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED) - { - grub_dprintf ("ehci", - "EHCI grub_ehci_pci_iter: EHCI change ownership timeout"); - /* Change ownership in "hard way" - reset BIOS ownership */ - grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED); - /* Ensure PCI register is written */ - grub_pci_read (pciaddr_eecp); - } - } - else if (usblegsup & GRUB_EHCI_OS_OWNED) - /* XXX: What to do in this case - nothing ? Can it happen ? */ - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: EHCI owned by: OS\n"); - else - { - grub_dprintf ("ehci", - "EHCI grub_ehci_pci_iter: EHCI owned by: NONE\n"); - /* XXX: What to do in this case ? Can it happen ? - * Is code below correct ? */ - /* Ownership change - set OS_OWNED bit */ - grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED); - /* Ensure PCI register is written */ - grub_pci_read (pciaddr_eecp); - } - - /* Disable SMI, just to be sure. */ - pciaddr_eecp = grub_pci_make_address (dev, eecp_offset + 4); - grub_pci_write (pciaddr_eecp, 0); - /* Ensure PCI register is written */ - grub_pci_read (pciaddr_eecp); - } - - grub_dprintf ("ehci", "inithw: EHCI grub_ehci_pci_iter: ownership OK\n"); - - grub_ehci_init_device (regs); - return 0; -} - -void -grub_ehci_pci_scan (void) -{ - grub_pci_iterate (grub_ehci_pci_iter, NULL); -} diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c deleted file mode 100644 index 2db07c7c0..000000000 --- a/grub-core/bus/usb/ehci.c +++ /dev/null @@ -1,1839 +0,0 @@ -/* ehci.c - EHCI Support. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* This simple GRUB implementation of EHCI driver: - * - assumes no IRQ - * - is not supporting isochronous transfers (iTD, siTD) - * - is not supporting interrupt transfers - */ - -/* Capability registers offsets */ -enum -{ - GRUB_EHCI_EHCC_CAPLEN = 0x00, /* byte */ - GRUB_EHCI_EHCC_VERSION = 0x02, /* word */ - GRUB_EHCI_EHCC_SPARAMS = 0x04, /* dword */ - GRUB_EHCI_EHCC_CPARAMS = 0x08, /* dword */ - GRUB_EHCI_EHCC_PROUTE = 0x0c, /* 60 bits */ -}; - -#define GRUB_EHCI_EECP_MASK (0xff << 8) -#define GRUB_EHCI_EECP_SHIFT 8 - -#define GRUB_EHCI_POINTER_MASK (~0x1f) - -/* Capability register SPARAMS bits */ -enum -{ - GRUB_EHCI_SPARAMS_N_PORTS = (0xf << 0), - GRUB_EHCI_SPARAMS_PPC = (1 << 4), /* Power port control */ - GRUB_EHCI_SPARAMS_PRR = (1 << 7), /* Port routing rules */ - GRUB_EHCI_SPARAMS_N_PCC = (0xf << 8), /* No of ports per comp. */ - GRUB_EHCI_SPARAMS_NCC = (0xf << 12), /* No of com. controllers */ - GRUB_EHCI_SPARAMS_P_IND = (1 << 16), /* Port indicators present */ - GRUB_EHCI_SPARAMS_DEBUG_P = (0xf << 20) /* Debug port */ -}; - -#define GRUB_EHCI_MAX_N_PORTS 15 /* Max. number of ports */ - -/* Capability register CPARAMS bits */ -enum -{ - GRUB_EHCI_CPARAMS_64BIT = (1 << 0), - GRUB_EHCI_CPARAMS_PROG_FRAMELIST = (1 << 1), - GRUB_EHCI_CPARAMS_PARK_CAP = (1 << 2) -}; - -#define GRUB_EHCI_N_FRAMELIST 1024 -#define GRUB_EHCI_N_QH 256 -#define GRUB_EHCI_N_TD 640 - -#define GRUB_EHCI_QH_EMPTY 1 - -/* Operational registers offsets */ -enum -{ - GRUB_EHCI_COMMAND = 0x00, - GRUB_EHCI_STATUS = 0x04, - GRUB_EHCI_INTERRUPT = 0x08, - GRUB_EHCI_FRAME_INDEX = 0x0c, - GRUB_EHCI_64BIT_SEL = 0x10, - GRUB_EHCI_FL_BASE = 0x14, - GRUB_EHCI_CUR_AL_ADDR = 0x18, - GRUB_EHCI_CONFIG_FLAG = 0x40, - GRUB_EHCI_PORT_STAT_CMD = 0x44 -}; - -/* Operational register COMMAND bits */ -enum -{ - GRUB_EHCI_CMD_RUNSTOP = (1 << 0), - GRUB_EHCI_CMD_HC_RESET = (1 << 1), - GRUB_EHCI_CMD_FL_SIZE = (3 << 2), - GRUB_EHCI_CMD_PS_ENABL = (1 << 4), - GRUB_EHCI_CMD_AS_ENABL = (1 << 5), - GRUB_EHCI_CMD_AS_ADV_D = (1 << 6), - GRUB_EHCI_CMD_L_HC_RES = (1 << 7), - GRUB_EHCI_CMD_AS_PARKM = (3 << 8), - GRUB_EHCI_CMD_AS_PARKE = (1 << 11), - GRUB_EHCI_CMD_INT_THRS = (0xff << 16) -}; - -/* Operational register STATUS bits */ -enum -{ - GRUB_EHCI_ST_INTERRUPT = (1 << 0), - GRUB_EHCI_ST_ERROR_INT = (1 << 1), - GRUB_EHCI_ST_PORT_CHG = (1 << 2), - GRUB_EHCI_ST_FL_ROLLOVR = (1 << 3), - GRUB_EHCI_ST_HS_ERROR = (1 << 4), - GRUB_EHCI_ST_AS_ADVANCE = (1 << 5), - GRUB_EHCI_ST_HC_HALTED = (1 << 12), - GRUB_EHCI_ST_RECLAM = (1 << 13), - GRUB_EHCI_ST_PS_STATUS = (1 << 14), - GRUB_EHCI_ST_AS_STATUS = (1 << 15) -}; - -/* Operational register PORT_STAT_CMD bits */ -enum -{ - GRUB_EHCI_PORT_CONNECT = (1 << 0), - GRUB_EHCI_PORT_CONNECT_CH = (1 << 1), - GRUB_EHCI_PORT_ENABLED = (1 << 2), - GRUB_EHCI_PORT_ENABLED_CH = (1 << 3), - GRUB_EHCI_PORT_OVERCUR = (1 << 4), - GRUB_EHCI_PORT_OVERCUR_CH = (1 << 5), - GRUB_EHCI_PORT_RESUME = (1 << 6), - GRUB_EHCI_PORT_SUSPEND = (1 << 7), - GRUB_EHCI_PORT_RESET = (1 << 8), - GRUB_EHCI_PORT_LINE_STAT = (3 << 10), - GRUB_EHCI_PORT_POWER = (1 << 12), - GRUB_EHCI_PORT_OWNER = (1 << 13), - GRUB_EHCI_PORT_INDICATOR = (3 << 14), - GRUB_EHCI_PORT_TEST = (0xf << 16), - GRUB_EHCI_PORT_WON_CONN_E = (1 << 20), - GRUB_EHCI_PORT_WON_DISC_E = (1 << 21), - GRUB_EHCI_PORT_WON_OVER_E = (1 << 22), - - GRUB_EHCI_PORT_LINE_SE0 = (0 << 10), - GRUB_EHCI_PORT_LINE_K = (1 << 10), - GRUB_EHCI_PORT_LINE_J = (2 << 10), - GRUB_EHCI_PORT_LINE_UNDEF = (3 << 10), - GRUB_EHCI_PORT_LINE_LOWSP = GRUB_EHCI_PORT_LINE_K, /* K state means low speed */ - GRUB_EHCI_PORT_WMASK = ~(GRUB_EHCI_PORT_CONNECT_CH - | GRUB_EHCI_PORT_ENABLED_CH - | GRUB_EHCI_PORT_OVERCUR_CH) -}; - -/* Operational register CONFIGFLAGS bits */ -enum -{ - GRUB_EHCI_CF_EHCI_OWNER = (1 << 0) -}; - -/* Queue Head & Transfer Descriptor constants */ -#define GRUB_EHCI_HPTR_OFF 5 /* Horiz. pointer bit offset */ -enum -{ - GRUB_EHCI_HPTR_TYPE_MASK = (3 << 1), - GRUB_EHCI_HPTR_TYPE_ITD = (0 << 1), - GRUB_EHCI_HPTR_TYPE_QH = (1 << 1), - GRUB_EHCI_HPTR_TYPE_SITD = (2 << 1), - GRUB_EHCI_HPTR_TYPE_FSTN = (3 << 1) -}; - -enum -{ - GRUB_EHCI_C = (1 << 27), - GRUB_EHCI_MAXPLEN_MASK = (0x7ff << 16), - GRUB_EHCI_H = (1 << 15), - GRUB_EHCI_DTC = (1 << 14), - GRUB_EHCI_SPEED_MASK = (3 << 12), - GRUB_EHCI_SPEED_FULL = (0 << 12), - GRUB_EHCI_SPEED_LOW = (1 << 12), - GRUB_EHCI_SPEED_HIGH = (2 << 12), - GRUB_EHCI_SPEED_RESERVED = (3 << 12), - GRUB_EHCI_EP_NUM_MASK = (0xf << 8), - GRUB_EHCI_DEVADDR_MASK = 0x7f, - GRUB_EHCI_TARGET_MASK = (GRUB_EHCI_EP_NUM_MASK | GRUB_EHCI_DEVADDR_MASK) -}; - -enum -{ - GRUB_EHCI_MAXPLEN_OFF = 16, - GRUB_EHCI_SPEED_OFF = 12, - GRUB_EHCI_EP_NUM_OFF = 8 -}; - -enum -{ - GRUB_EHCI_MULT_MASK = (3 << 30), - GRUB_EHCI_MULT_RESERVED = (0 << 30), - GRUB_EHCI_MULT_ONE = (1 << 30), - GRUB_EHCI_MULT_TWO = (2 << 30), - GRUB_EHCI_MULT_THREE = (3 << 30), - GRUB_EHCI_DEVPORT_MASK = (0x7f << 23), - GRUB_EHCI_HUBADDR_MASK = (0x7f << 16), - GRUB_EHCI_CMASK_MASK = (0xff << 8), - GRUB_EHCI_SMASK_MASK = (0xff << 0), -}; - -enum -{ - GRUB_EHCI_MULT_OFF = 30, - GRUB_EHCI_DEVPORT_OFF = 23, - GRUB_EHCI_HUBADDR_OFF = 16, - GRUB_EHCI_CMASK_OFF = 8, - GRUB_EHCI_SMASK_OFF = 0, -}; - -#define GRUB_EHCI_TERMINATE (1<<0) - -#define GRUB_EHCI_TOGGLE ((grub_uint32_t) 1<<31) - -enum -{ - GRUB_EHCI_TOTAL_MASK = (0x7fff << 16), - GRUB_EHCI_CERR_MASK = (3 << 10), - GRUB_EHCI_CERR_0 = (0 << 10), - GRUB_EHCI_CERR_1 = (1 << 10), - GRUB_EHCI_CERR_2 = (2 << 10), - GRUB_EHCI_CERR_3 = (3 << 10), - GRUB_EHCI_PIDCODE_OUT = (0 << 8), - GRUB_EHCI_PIDCODE_IN = (1 << 8), - GRUB_EHCI_PIDCODE_SETUP = (2 << 8), - GRUB_EHCI_STATUS_MASK = 0xff, - GRUB_EHCI_STATUS_ACTIVE = (1 << 7), - GRUB_EHCI_STATUS_HALTED = (1 << 6), - GRUB_EHCI_STATUS_BUFERR = (1 << 5), - GRUB_EHCI_STATUS_BABBLE = (1 << 4), - GRUB_EHCI_STATUS_TRANERR = (1 << 3), - GRUB_EHCI_STATUS_MISSDMF = (1 << 2), - GRUB_EHCI_STATUS_SPLITST = (1 << 1), - GRUB_EHCI_STATUS_PINGERR = (1 << 0) -}; - -enum -{ - GRUB_EHCI_TOTAL_OFF = 16, - GRUB_EHCI_CERR_OFF = 10 -}; - -#define GRUB_EHCI_BUFPTR_MASK (0xfffff<<12) -#define GRUB_EHCI_QHTDPTR_MASK 0xffffffe0 - -#define GRUB_EHCI_TD_BUF_PAGES 5 - -#define GRUB_EHCI_BUFPAGELEN 0x1000 -#define GRUB_EHCI_MAXBUFLEN 0x5000 - -struct grub_ehci_td; -struct grub_ehci_qh; -typedef volatile struct grub_ehci_td *grub_ehci_td_t; -typedef volatile struct grub_ehci_qh *grub_ehci_qh_t; - -/* EHCI Isochronous Transfer Descriptor */ -/* Currently not supported */ - -/* EHCI Split Transaction Isochronous Transfer Descriptor */ -/* Currently not supported */ - -/* EHCI Queue Element Transfer Descriptor (qTD) */ -/* Align to 32-byte boundaries */ -struct grub_ehci_td -{ - /* EHCI HW part */ - grub_uint32_t next_td; /* Pointer to next qTD */ - grub_uint32_t alt_next_td; /* Pointer to alternate next qTD */ - grub_uint32_t token; /* Toggle, Len, Interrupt, Page, Error, PID, Status */ - grub_uint32_t buffer_page[GRUB_EHCI_TD_BUF_PAGES]; /* Buffer pointer (+ cur. offset in page 0 */ - /* 64-bits part */ - grub_uint32_t buffer_page_high[GRUB_EHCI_TD_BUF_PAGES]; - /* EHCI driver part */ - grub_uint32_t link_td; /* pointer to next free/chained TD */ - grub_uint32_t size; - grub_uint32_t pad[1]; /* padding to some multiple of 32 bytes */ -}; - -/* EHCI Queue Head */ -/* Align to 32-byte boundaries */ -/* QH allocation is made in the similar/same way as in OHCI driver, - * because unlninking QH from the Asynchronous list is not so - * trivial as on UHCI (at least it is time consuming) */ -struct grub_ehci_qh -{ - /* EHCI HW part */ - grub_uint32_t qh_hptr; /* Horiz. pointer & Terminate */ - grub_uint32_t ep_char; /* EP characteristics */ - grub_uint32_t ep_cap; /* EP capabilities */ - grub_uint32_t td_current; /* current TD link pointer */ - struct grub_ehci_td td_overlay; /* TD overlay area = 64 bytes */ - /* EHCI driver part */ - grub_uint32_t pad[4]; /* padding to some multiple of 32 bytes */ -}; - -/* EHCI Periodic Frame Span Traversal Node */ -/* Currently not supported */ - -struct grub_ehci -{ - volatile grub_uint32_t *iobase_ehcc; /* Capability registers */ - volatile grub_uint32_t *iobase; /* Operational registers */ - struct grub_pci_dma_chunk *framelist_chunk; /* Currently not used */ - volatile grub_uint32_t *framelist_virt; - grub_uint32_t framelist_phys; - struct grub_pci_dma_chunk *qh_chunk; /* GRUB_EHCI_N_QH Queue Heads */ - grub_ehci_qh_t qh_virt; - grub_uint32_t qh_phys; - struct grub_pci_dma_chunk *td_chunk; /* GRUB_EHCI_N_TD Transfer Descriptors */ - grub_ehci_td_t td_virt; - grub_uint32_t td_phys; - grub_ehci_td_t tdfree_virt; /* Free Transfer Descriptors */ - int flag64; - grub_uint32_t reset; /* bits 1-15 are flags if port was reset from connected time or not */ - struct grub_ehci *next; -}; - -static struct grub_ehci *ehci; - -static void -sync_all_caches (struct grub_ehci *e) -{ - if (!e) - return; - if (e->td_virt) - grub_arch_sync_dma_caches (e->td_virt, sizeof (struct grub_ehci_td) * - GRUB_EHCI_N_TD); - if (e->qh_virt) - grub_arch_sync_dma_caches (e->qh_virt, sizeof (struct grub_ehci_qh) * - GRUB_EHCI_N_QH); - if (e->framelist_virt) - grub_arch_sync_dma_caches (e->framelist_virt, 4096); -} - -/* EHCC registers access functions */ -static inline grub_uint32_t -grub_ehci_ehcc_read32 (struct grub_ehci *e, grub_uint32_t addr) -{ - return - grub_le_to_cpu32 (*((volatile grub_uint32_t *) e->iobase_ehcc + - (addr / sizeof (grub_uint32_t)))); -} - -static inline grub_uint16_t -grub_ehci_ehcc_read16 (struct grub_ehci *e, grub_uint32_t addr) -{ - return - grub_le_to_cpu16 (*((volatile grub_uint16_t *) e->iobase_ehcc + - (addr / sizeof (grub_uint16_t)))); -} - -static inline grub_uint8_t -grub_ehci_ehcc_read8 (struct grub_ehci *e, grub_uint32_t addr) -{ - return *((volatile grub_uint8_t *) e->iobase_ehcc + addr); -} - -/* Operational registers access functions */ -static inline grub_uint32_t -grub_ehci_oper_read32 (struct grub_ehci *e, grub_uint32_t addr) -{ - return - grub_le_to_cpu32 (* - ((volatile grub_uint32_t *) e->iobase + - (addr / sizeof (grub_uint32_t)))); -} - -static inline void -grub_ehci_oper_write32 (struct grub_ehci *e, grub_uint32_t addr, - grub_uint32_t value) -{ - *((volatile grub_uint32_t *) e->iobase + (addr / sizeof (grub_uint32_t))) = - grub_cpu_to_le32 (value); -} - -static inline grub_uint32_t -grub_ehci_port_read (struct grub_ehci *e, grub_uint32_t port) -{ - return grub_ehci_oper_read32 (e, GRUB_EHCI_PORT_STAT_CMD + port * 4); -} - -static inline void -grub_ehci_port_resbits (struct grub_ehci *e, grub_uint32_t port, - grub_uint32_t bits) -{ - grub_ehci_oper_write32 (e, GRUB_EHCI_PORT_STAT_CMD + port * 4, - grub_ehci_port_read (e, - port) & GRUB_EHCI_PORT_WMASK & - ~(bits)); - grub_ehci_port_read (e, port); -} - -static inline void -grub_ehci_port_setbits (struct grub_ehci *e, grub_uint32_t port, - grub_uint32_t bits) -{ - grub_ehci_oper_write32 (e, GRUB_EHCI_PORT_STAT_CMD + port * 4, - (grub_ehci_port_read (e, port) & - GRUB_EHCI_PORT_WMASK) | bits); - grub_ehci_port_read (e, port); -} - -/* Halt if EHCI HC not halted */ -static grub_usb_err_t -grub_ehci_halt (struct grub_ehci *e) -{ - grub_uint64_t maxtime; - - if ((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS) & GRUB_EHCI_ST_HC_HALTED) == 0) /* EHCI is not halted */ - { - /* Halt EHCI */ - grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, - ~GRUB_EHCI_CMD_RUNSTOP - & grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); - /* Ensure command is written */ - grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND); - maxtime = grub_get_time_ms () + 1000; /* Fix: Should be 2ms ! */ - while (((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS) - & GRUB_EHCI_ST_HC_HALTED) == 0) - && (grub_get_time_ms () < maxtime)); - if ((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS) - & GRUB_EHCI_ST_HC_HALTED) == 0) - return GRUB_USB_ERR_TIMEOUT; - } - - return GRUB_USB_ERR_NONE; -} - -/* EHCI HC reset */ -static grub_usb_err_t -grub_ehci_reset (struct grub_ehci *e) -{ - grub_uint64_t maxtime; - - sync_all_caches (e); - - grub_dprintf ("ehci", "reset\n"); - - grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, - GRUB_EHCI_CMD_HC_RESET); - /* Ensure command is written */ - grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND); - /* XXX: How long time could take reset of HC ? */ - maxtime = grub_get_time_ms () + 1000; - while (((grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND) - & GRUB_EHCI_CMD_HC_RESET) != 0) - && (grub_get_time_ms () < maxtime)); - if ((grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND) - & GRUB_EHCI_CMD_HC_RESET) != 0) - return GRUB_USB_ERR_TIMEOUT; - - return GRUB_USB_ERR_NONE; -} - -/* PCI iteration function... */ -void -grub_ehci_init_device (volatile void *regs) -{ - struct grub_ehci *e; - grub_uint32_t fp; - int i; - grub_uint32_t n_ports; - grub_uint8_t caplen; - - /* Allocate memory for the controller and fill basic values. */ - e = grub_zalloc (sizeof (*e)); - if (!e) - return; - e->framelist_chunk = NULL; - e->td_chunk = NULL; - e->qh_chunk = NULL; - e->iobase_ehcc = regs; - - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CAPLEN: %02x\n", - grub_ehci_ehcc_read8 (e, GRUB_EHCI_EHCC_CAPLEN)); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: VERSION: %04x\n", - grub_ehci_ehcc_read16 (e, GRUB_EHCI_EHCC_VERSION)); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: SPARAMS: %08x\n", - grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_SPARAMS)); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CPARAMS: %08x\n", - grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_CPARAMS)); - - /* Determine base address of EHCI operational registers */ - caplen = grub_ehci_ehcc_read8 (e, GRUB_EHCI_EHCC_CAPLEN); -#ifndef GRUB_HAVE_UNALIGNED_ACCESS - if (caplen & (sizeof (grub_uint32_t) - 1)) - { - grub_dprintf ("ehci", "Unaligned caplen\n"); - return; - } - e->iobase = ((volatile grub_uint32_t *) e->iobase_ehcc - + (caplen / sizeof (grub_uint32_t))); -#else - e->iobase = (volatile grub_uint32_t *) - ((grub_uint8_t *) e->iobase_ehcc + caplen); -#endif - - grub_dprintf ("ehci", - "EHCI grub_ehci_pci_iter: iobase of oper. regs: %08llxx\n", - (unsigned long long) (grub_addr_t) e->iobase_ehcc + caplen); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: COMMAND: %08x\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: STATUS: %08x\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS)); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: INTERRUPT: %08x\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_INTERRUPT)); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: FRAME_INDEX: %08x\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_FRAME_INDEX)); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: FL_BASE: %08x\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_FL_BASE)); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CUR_AL_ADDR: %08x\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_CUR_AL_ADDR)); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CONFIG_FLAG: %08x\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_CONFIG_FLAG)); - - /* Check format of data structures requested by EHCI */ - /* XXX: In fact it is not used at any place, it is prepared for future - * This implementation uses 32-bits pointers only */ - e->flag64 = ((grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_CPARAMS) - & GRUB_EHCI_CPARAMS_64BIT) != 0); - - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: flag64=%d\n", e->flag64); - - /* Reserve a page for the frame list - it is accurate for max. - * possible size of framelist. But currently it is not used. */ - e->framelist_chunk = grub_memalign_dma32 (4096, 4096); - if (!e->framelist_chunk) - goto fail; - e->framelist_virt = grub_dma_get_virt (e->framelist_chunk); - e->framelist_phys = grub_dma_get_phys (e->framelist_chunk); - grub_memset ((void *) e->framelist_virt, 0, 4096); - - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: framelist mem=%p. OK\n", - e->framelist_virt); - - /* Allocate memory for the QHs and register it in "e". */ - e->qh_chunk = grub_memalign_dma32 (4096, - sizeof (struct grub_ehci_qh) * - GRUB_EHCI_N_QH); - if (!e->qh_chunk) - goto fail; - e->qh_virt = (grub_ehci_qh_t) grub_dma_get_virt (e->qh_chunk); - e->qh_phys = grub_dma_get_phys (e->qh_chunk); - grub_memset ((void *) e->qh_virt, 0, - sizeof (struct grub_ehci_qh) * GRUB_EHCI_N_QH); - - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: QH mem=%p. OK\n", - e->qh_virt); - - /* Allocate memory for the TDs and register it in "e". */ - e->td_chunk = grub_memalign_dma32 (4096, - sizeof (struct grub_ehci_td) * - GRUB_EHCI_N_TD); - if (!e->td_chunk) - goto fail; - e->td_virt = (grub_ehci_td_t) grub_dma_get_virt (e->td_chunk); - e->td_phys = grub_dma_get_phys (e->td_chunk); - grub_memset ((void *) e->td_virt, 0, - sizeof (struct grub_ehci_td) * GRUB_EHCI_N_TD); - - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: TD mem=%p. OK\n", - e->td_virt); - - /* Setup all frame list pointers. Since no isochronous transfers - are supported, they all point to the (same!) queue - head with index 0. */ - fp = grub_cpu_to_le32 ((e->qh_phys & GRUB_EHCI_POINTER_MASK) - | GRUB_EHCI_HPTR_TYPE_QH); - for (i = 0; i < GRUB_EHCI_N_FRAMELIST; i++) - e->framelist_virt[i] = fp; - /* Prepare chain of all TDs and set Terminate in all TDs */ - for (i = 0; i < (GRUB_EHCI_N_TD - 1); i++) - { - e->td_virt[i].link_td = e->td_phys + (i + 1) * sizeof (struct grub_ehci_td); - e->td_virt[i].next_td = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE); - e->td_virt[i].alt_next_td = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE); - } - e->td_virt[GRUB_EHCI_N_TD - 1].next_td = - grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE); - e->td_virt[GRUB_EHCI_N_TD - 1].alt_next_td = - grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE); - e->tdfree_virt = e->td_virt; - /* Set Terminate in first QH, which is used in framelist */ - e->qh_virt[0].qh_hptr = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE | GRUB_EHCI_HPTR_TYPE_QH); - e->qh_virt[0].td_overlay.next_td = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE); - e->qh_virt[0].td_overlay.alt_next_td = - grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE); - /* Also set Halted bit in token */ - e->qh_virt[0].td_overlay.token = grub_cpu_to_le32_compile_time (GRUB_EHCI_STATUS_HALTED); - /* Set the H bit in first QH used for AL */ - e->qh_virt[1].ep_char = grub_cpu_to_le32_compile_time (GRUB_EHCI_H); - /* Set Terminate into TD in rest of QHs and set horizontal link - * pointer to itself - these QHs will be used for asynchronous - * schedule and they should have valid value in horiz. link */ - for (i = 1; i < GRUB_EHCI_N_QH; i++) - { - e->qh_virt[i].qh_hptr = - grub_cpu_to_le32 ((grub_dma_virt2phys (&e->qh_virt[i], - e->qh_chunk) & - GRUB_EHCI_POINTER_MASK) | GRUB_EHCI_HPTR_TYPE_QH); - e->qh_virt[i].td_overlay.next_td = - grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE); - e->qh_virt[i].td_overlay.alt_next_td = - grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE); - /* Also set Halted bit in token */ - e->qh_virt[i].td_overlay.token = - grub_cpu_to_le32_compile_time (GRUB_EHCI_STATUS_HALTED); - } - - /* Note: QH 0 and QH 1 are reserved and must not be used anywhere. - * QH 0 is used as empty QH for framelist - * QH 1 is used as starting empty QH for asynchronous schedule - * QH 1 must exist at any time because at least one QH linked to - * itself must exist in asynchronous schedule - * QH 1 has the H flag set to one */ - - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: QH/TD init. OK\n"); - - /* Now we can setup EHCI (maybe...) */ - - /* Check if EHCI is halted and halt it if not */ - if (grub_ehci_halt (e) != GRUB_USB_ERR_NONE) - { - grub_error (GRUB_ERR_TIMEOUT, - "EHCI grub_ehci_pci_iter: EHCI halt timeout"); - goto fail; - } - - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: halted OK\n"); - - /* Reset EHCI */ - if (grub_ehci_reset (e) != GRUB_USB_ERR_NONE) - { - grub_error (GRUB_ERR_TIMEOUT, - "EHCI grub_ehci_pci_iter: EHCI reset timeout"); - goto fail; - } - - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: reset OK\n"); - - /* Setup list address registers */ - grub_ehci_oper_write32 (e, GRUB_EHCI_FL_BASE, e->framelist_phys); - grub_ehci_oper_write32 (e, GRUB_EHCI_CUR_AL_ADDR, - grub_dma_virt2phys (&e->qh_virt[1], - e->qh_chunk)); - - /* Set ownership of root hub ports to EHCI */ - grub_ehci_oper_write32 (e, GRUB_EHCI_CONFIG_FLAG, GRUB_EHCI_CF_EHCI_OWNER); - - /* Enable both lists */ - grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, - GRUB_EHCI_CMD_AS_ENABL - | GRUB_EHCI_CMD_PS_ENABL - | grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); - - /* Now should be possible to power-up and enumerate ports etc. */ - if ((grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_SPARAMS) - & GRUB_EHCI_SPARAMS_PPC) != 0) - { /* EHCI has port powering control */ - /* Power on all ports */ - n_ports = grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_SPARAMS) - & GRUB_EHCI_SPARAMS_N_PORTS; - for (i = 0; i < (int) n_ports; i++) - grub_ehci_oper_write32 (e, GRUB_EHCI_PORT_STAT_CMD + i * 4, - GRUB_EHCI_PORT_POWER - | grub_ehci_oper_read32 (e, - GRUB_EHCI_PORT_STAT_CMD - + i * 4)); - } - - /* Ensure all commands are written */ - grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND); - - /* Enable EHCI */ - grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, - GRUB_EHCI_CMD_RUNSTOP - | grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); - - /* Ensure command is written */ - grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND); - - /* Link to ehci now that initialisation is successful. */ - e->next = ehci; - ehci = e; - - sync_all_caches (e); - - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: OK at all\n"); - - grub_dprintf ("ehci", - "EHCI grub_ehci_pci_iter: iobase of oper. regs: %08llx\n", - (unsigned long long) (grub_addr_t) regs); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: COMMAND: %08x\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: STATUS: %08x\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS)); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: INTERRUPT: %08x\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_INTERRUPT)); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: FRAME_INDEX: %08x\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_FRAME_INDEX)); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: FL_BASE: %08x\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_FL_BASE)); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CUR_AL_ADDR: %08x\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_CUR_AL_ADDR)); - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CONFIG_FLAG: %08x\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_CONFIG_FLAG)); - - return; - -fail: - if (e) - { - if (e->td_chunk) - grub_dma_free ((void *) e->td_chunk); - if (e->qh_chunk) - grub_dma_free ((void *) e->qh_chunk); - if (e->framelist_chunk) - grub_dma_free (e->framelist_chunk); - } - grub_free (e); - - return; -} - -static int -grub_ehci_iterate (grub_usb_controller_iterate_hook_t hook, void *hook_data) -{ - struct grub_ehci *e; - struct grub_usb_controller dev; - - for (e = ehci; e; e = e->next) - { - dev.data = e; - if (hook (&dev, hook_data)) - return 1; - } - - return 0; -} - -static void -grub_ehci_setup_qh (grub_ehci_qh_t qh, grub_usb_transfer_t transfer) -{ - grub_uint32_t ep_char = 0; - grub_uint32_t ep_cap = 0; - - /* Note: Another part of code is responsible to this QH is - * Halted ! But it can be linked in AL, so we cannot erase or - * change qh_hptr ! */ - /* We will not change any TD field because they should/must be - * in safe state from previous use. */ - - /* EP characteristic setup */ - /* Currently not used NAK counter (RL=0), - * C bit set if EP is not HIGH speed and is control, - * Max Packet Length is taken from transfer structure, - * H bit = 0 (because QH[1] has this bit set), - * DTC bit set to 1 because we are using our own toggle bit control, - * SPEED is selected according to value from transfer structure, - * EP number is taken from transfer structure - * "I" bit must not be set, - * Device Address is taken from transfer structure - * */ - if ((transfer->dev->speed != GRUB_USB_SPEED_HIGH) - && (transfer->type == GRUB_USB_TRANSACTION_TYPE_CONTROL)) - ep_char |= GRUB_EHCI_C; - ep_char |= (transfer->max << GRUB_EHCI_MAXPLEN_OFF) - & GRUB_EHCI_MAXPLEN_MASK; - ep_char |= GRUB_EHCI_DTC; - switch (transfer->dev->speed) - { - case GRUB_USB_SPEED_LOW: - ep_char |= GRUB_EHCI_SPEED_LOW; - break; - case GRUB_USB_SPEED_FULL: - ep_char |= GRUB_EHCI_SPEED_FULL; - break; - case GRUB_USB_SPEED_HIGH: - default: - ep_char |= GRUB_EHCI_SPEED_HIGH; - /* XXX: How we will handle unknown value of speed? */ - } - ep_char |= (transfer->endpoint << GRUB_EHCI_EP_NUM_OFF) - & GRUB_EHCI_EP_NUM_MASK; - ep_char |= transfer->devaddr & GRUB_EHCI_DEVADDR_MASK; - qh->ep_char = grub_cpu_to_le32 (ep_char); - /* EP capabilities setup */ - /* MULT field - we try to use max. number - * PortNumber - included now in device structure referenced - * inside transfer structure - * HubAddress - included now in device structure referenced - * inside transfer structure - * SplitCompletionMask - AFAIK it is ignored in asynchronous list, - * InterruptScheduleMask - AFAIK it should be zero in async. list */ - ep_cap |= GRUB_EHCI_MULT_THREE; - ep_cap |= (transfer->dev->split_hubport << GRUB_EHCI_DEVPORT_OFF) - & GRUB_EHCI_DEVPORT_MASK; - ep_cap |= (transfer->dev->split_hubaddr << GRUB_EHCI_HUBADDR_OFF) - & GRUB_EHCI_HUBADDR_MASK; - if (transfer->dev->speed == GRUB_USB_SPEED_LOW - && transfer->type != GRUB_USB_TRANSACTION_TYPE_CONTROL) - { - ep_cap |= (1<<0) << GRUB_EHCI_SMASK_OFF; - ep_cap |= (7<<2) << GRUB_EHCI_CMASK_OFF; - } - qh->ep_cap = grub_cpu_to_le32 (ep_cap); - - grub_dprintf ("ehci", "setup_qh: qh=%p, not changed: qh_hptr=%08x\n", - qh, grub_le_to_cpu32 (qh->qh_hptr)); - grub_dprintf ("ehci", "setup_qh: ep_char=%08x, ep_cap=%08x\n", - ep_char, ep_cap); - grub_dprintf ("ehci", "setup_qh: end\n"); - grub_dprintf ("ehci", "setup_qh: not changed: td_current=%08x\n", - grub_le_to_cpu32 (qh->td_current)); - grub_dprintf ("ehci", "setup_qh: not changed: next_td=%08x\n", - grub_le_to_cpu32 (qh->td_overlay.next_td)); - grub_dprintf ("ehci", "setup_qh: not changed: alt_next_td=%08x\n", - grub_le_to_cpu32 (qh->td_overlay.alt_next_td)); - grub_dprintf ("ehci", "setup_qh: not changed: token=%08x\n", - grub_le_to_cpu32 (qh->td_overlay.token)); -} - -static grub_ehci_qh_t -grub_ehci_find_qh (struct grub_ehci *e, grub_usb_transfer_t transfer) -{ - grub_uint32_t target, mask; - int i; - grub_ehci_qh_t qh = e->qh_virt; - grub_ehci_qh_t head; - grub_uint32_t qh_phys; - grub_uint32_t qh_terminate = - GRUB_EHCI_TERMINATE | GRUB_EHCI_HPTR_TYPE_QH; - grub_ehci_qh_t qh_iter; - - /* Prepare part of EP Characteristic to find existing QH */ - target = ((transfer->endpoint << GRUB_EHCI_EP_NUM_OFF) | - transfer->devaddr) & GRUB_EHCI_TARGET_MASK; - target = grub_cpu_to_le32 (target); - mask = grub_cpu_to_le32_compile_time (GRUB_EHCI_TARGET_MASK); - - /* low speed interrupt transfers are linked to the periodic */ - /* schedule, everything else to the asynchronous schedule */ - if (transfer->dev->speed == GRUB_USB_SPEED_LOW - && transfer->type != GRUB_USB_TRANSACTION_TYPE_CONTROL) - head = &qh[0]; - else - head = &qh[1]; - - /* First try to find existing QH with proper target in proper list */ - qh_phys = grub_le_to_cpu32( head->qh_hptr ); - if (qh_phys != qh_terminate) - qh_iter = grub_dma_phys2virt ( qh_phys & GRUB_EHCI_QHTDPTR_MASK, - e->qh_chunk ); - else - qh_iter = NULL; - - for ( - i = 0; - (qh_phys != qh_terminate) && (qh_iter != NULL) && - (qh_iter != head) && (i < GRUB_EHCI_N_QH); - i++ ) - { - if (target == (qh_iter->ep_char & mask)) - { - /* Found proper existing (and linked) QH, do setup of QH */ - grub_dprintf ("ehci", "find_qh: found, QH=%p\n", qh_iter); - grub_ehci_setup_qh (qh_iter, transfer); - sync_all_caches (e); - return qh_iter; - } - - qh_phys = grub_le_to_cpu32( qh_iter->qh_hptr ); - if (qh_phys != qh_terminate) - qh_iter = grub_dma_phys2virt ( qh_phys & GRUB_EHCI_QHTDPTR_MASK, - e->qh_chunk ); - else - qh_iter = NULL; - } - - /* variable "i" should be never equal to GRUB_EHCI_N_QH here */ - if (i >= GRUB_EHCI_N_QH) - { /* Something very bad happened in QH list(s) ! */ - grub_dprintf ("ehci", "find_qh: Mismatch in QH list! head=%p\n", - head); - } - - /* QH with target_addr does not exist, we have to find and add it */ - for (i = 2; i < GRUB_EHCI_N_QH; i++) /* We ignore zero and first QH */ - { - if (!qh[i].ep_char) - break; /* Found first not-allocated QH, finish */ - } - - /* Have we any free QH in array ? */ - if (i >= GRUB_EHCI_N_QH) /* No. */ - { - grub_dprintf ("ehci", "find_qh: end - no free QH\n"); - return NULL; - } - grub_dprintf ("ehci", "find_qh: new, i=%d, QH=%p\n", - i, &qh[i]); - /* Currently we simply take next (current) QH in array, no allocation - * function is used. It should be no problem until we will need to - * de-allocate QHs of unplugged devices. */ - /* We should preset new QH and link it into AL */ - grub_ehci_setup_qh (&qh[i], transfer); - - /* Linking - this new (last) QH will copy the QH from the head QH */ - qh[i].qh_hptr = head->qh_hptr; - /* Linking - the head QH will point to this new QH */ - head->qh_hptr = grub_cpu_to_le32 (GRUB_EHCI_HPTR_TYPE_QH - | grub_dma_virt2phys (&qh[i], - e->qh_chunk)); - - return &qh[i]; -} - -static grub_ehci_td_t -grub_ehci_alloc_td (struct grub_ehci *e) -{ - grub_ehci_td_t ret; - - /* Check if there is a Transfer Descriptor available. */ - if (!e->tdfree_virt) - { - grub_dprintf ("ehci", "alloc_td: end - no free TD\n"); - return NULL; - } - - ret = e->tdfree_virt; /* Take current free TD */ - /* Advance to next free TD in chain */ - if (ret->link_td) - e->tdfree_virt = grub_dma_phys2virt (ret->link_td, e->td_chunk); - else - e->tdfree_virt = NULL; - ret->link_td = 0; /* Reset link_td in allocated TD */ - return ret; -} - -static void -grub_ehci_free_td (struct grub_ehci *e, grub_ehci_td_t td) -{ - /* Chain new free TD & rest */ - if (e->tdfree_virt) - td->link_td = grub_dma_virt2phys (e->tdfree_virt, e->td_chunk); - else - td->link_td = 0; - e->tdfree_virt = td; /* Change address of first free TD */ -} - -static void -grub_ehci_free_tds (struct grub_ehci *e, grub_ehci_td_t td, - grub_usb_transfer_t transfer, grub_size_t * actual) -{ - int i; /* Index of TD in transfer */ - grub_uint32_t token, to_transfer; - - /* Note: Another part of code is responsible to this QH is - * INACTIVE ! */ - *actual = 0; - - /* Free the TDs in this queue and set last_trans. */ - for (i = 0; td; i++) - { - grub_ehci_td_t tdprev; - - token = grub_le_to_cpu32 (td->token); - to_transfer = (token & GRUB_EHCI_TOTAL_MASK) >> GRUB_EHCI_TOTAL_OFF; - - /* Check state of TD - if it did not transfer - * whole data then set last_trans - it should be last executed TD - * in case when something went wrong. */ - if (transfer && (td->size != to_transfer)) - transfer->last_trans = i; - - *actual += td->size - to_transfer; - - /* Unlink the TD */ - tdprev = td; - if (td->link_td) - td = grub_dma_phys2virt (td->link_td, e->td_chunk); - else - td = NULL; - - /* Free the TD. */ - grub_ehci_free_td (e, tdprev); - } - - /* Check if last_trans was set. If not and something was - * transferred (it should be all data in this case), set it - * to index of last TD, i.e. i-1 */ - if (transfer && (transfer->last_trans < 0) && (*actual != 0)) - transfer->last_trans = i - 1; - - /* XXX: Fix it: last_trans may be set to bad index. - * Probably we should test more error flags to distinguish - * if TD was at least partialy executed or not at all. - * Generaly, we still could have problem with toggling because - * EHCI can probably split transactions into smaller parts then - * we defined in transaction even if we did not exceed MaxFrame - * length - it probably could happen at the end of microframe (?) - * and if the buffer is crossing page boundary (?). */ -} - -static grub_ehci_td_t -grub_ehci_transaction (struct grub_ehci *e, - grub_transfer_type_t type, - unsigned int toggle, grub_size_t size, - grub_uint32_t data, grub_ehci_td_t td_alt) -{ - grub_ehci_td_t td; - grub_uint32_t token; - grub_uint32_t bufadr; - int i; - - /* Test of transfer size, it can be: - * <= GRUB_EHCI_MAXBUFLEN if data aligned to page boundary - * <= GRUB_EHCI_MAXBUFLEN - GRUB_EHCI_BUFPAGELEN if not aligned - * (worst case) - */ - if ((((data % GRUB_EHCI_BUFPAGELEN) == 0) - && (size > GRUB_EHCI_MAXBUFLEN)) - || - (((data % GRUB_EHCI_BUFPAGELEN) != 0) - && (size > (GRUB_EHCI_MAXBUFLEN - GRUB_EHCI_BUFPAGELEN)))) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, - "too long data buffer for EHCI transaction"); - return 0; - } - - /* Grab a free Transfer Descriptor and initialize it. */ - td = grub_ehci_alloc_td (e); - if (!td) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, - "no transfer descriptors available for EHCI transfer"); - return 0; - } - - grub_dprintf ("ehci", - "transaction: type=%d, toggle=%d, size=%lu data=0x%x td=%p\n", - type, toggle, (unsigned long) size, data, td); - - /* Fill whole TD by zeros */ - grub_memset ((void *) td, 0, sizeof (struct grub_ehci_td)); - - /* Don't point to any TD yet, just terminate. */ - td->next_td = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE); - /* Set alternate pointer. When short packet occurs, alternate TD - * will not be really fetched because it is not active. But don't - * forget, EHCI will try to fetch alternate TD every scan of AL - * until QH is halted. */ - td->alt_next_td = grub_cpu_to_le32 (grub_dma_virt2phys (td_alt, - e->td_chunk)); - /* token: - * TOGGLE - according to toggle - * TOTAL SIZE = size - * Interrupt On Complete = FALSE, we don't need IRQ - * Current Page = 0 - * Error Counter = max. value = 3 - * PID Code - according to type - * STATUS: - * ACTIVE bit should be set to one - * SPLIT TRANS. STATE bit should be zero. It is ignored - * in HIGH speed transaction, and should be zero for LOW/FULL - * speed to indicate state Do Split Transaction */ - token = toggle ? GRUB_EHCI_TOGGLE : 0; - token |= (size << GRUB_EHCI_TOTAL_OFF) & GRUB_EHCI_TOTAL_MASK; - token |= GRUB_EHCI_CERR_3; - switch (type) - { - case GRUB_USB_TRANSFER_TYPE_IN: - token |= GRUB_EHCI_PIDCODE_IN; - break; - case GRUB_USB_TRANSFER_TYPE_OUT: - token |= GRUB_EHCI_PIDCODE_OUT; - break; - case GRUB_USB_TRANSFER_TYPE_SETUP: - token |= GRUB_EHCI_PIDCODE_SETUP; - break; - default: /* XXX: Should not happen, but what to do if it does ? */ - break; - } - token |= GRUB_EHCI_STATUS_ACTIVE; - td->token = grub_cpu_to_le32 (token); - - /* Fill buffer pointers according to size */ - bufadr = data; - td->buffer_page[0] = grub_cpu_to_le32 (bufadr); - bufadr = ((bufadr / GRUB_EHCI_BUFPAGELEN) + 1) * GRUB_EHCI_BUFPAGELEN; - for (i = 1; ((bufadr - data) < size) && (i < GRUB_EHCI_TD_BUF_PAGES); i++) - { - td->buffer_page[i] = grub_cpu_to_le32 (bufadr & GRUB_EHCI_BUFPTR_MASK); - bufadr = ((bufadr / GRUB_EHCI_BUFPAGELEN) + 1) * GRUB_EHCI_BUFPAGELEN; - } - - /* Remember data size for future use... */ - td->size = (grub_uint32_t) size; - - grub_dprintf ("ehci", "td=%p\n", td); - grub_dprintf ("ehci", "HW: next_td=%08x, alt_next_td=%08x\n", - grub_le_to_cpu32 (td->next_td), - grub_le_to_cpu32 (td->alt_next_td)); - grub_dprintf ("ehci", "HW: token=%08x, buffer[0]=%08x\n", - grub_le_to_cpu32 (td->token), - grub_le_to_cpu32 (td->buffer_page[0])); - grub_dprintf ("ehci", "HW: buffer[1]=%08x, buffer[2]=%08x\n", - grub_le_to_cpu32 (td->buffer_page[1]), - grub_le_to_cpu32 (td->buffer_page[2])); - grub_dprintf ("ehci", "HW: buffer[3]=%08x, buffer[4]=%08x\n", - grub_le_to_cpu32 (td->buffer_page[3]), - grub_le_to_cpu32 (td->buffer_page[4])); - grub_dprintf ("ehci", "link_td=%08x, size=%08x\n", - td->link_td, td->size); - - return td; -} - -struct grub_ehci_transfer_controller_data -{ - grub_ehci_qh_t qh_virt; - grub_ehci_td_t td_first_virt; - grub_ehci_td_t td_alt_virt; - grub_ehci_td_t td_last_virt; - grub_uint32_t td_last_phys; -}; - -static grub_usb_err_t -grub_ehci_setup_transfer (grub_usb_controller_t dev, - grub_usb_transfer_t transfer) -{ - struct grub_ehci *e = (struct grub_ehci *) dev->data; - grub_ehci_td_t td = NULL; - grub_ehci_td_t td_prev = NULL; - int i; - struct grub_ehci_transfer_controller_data *cdata; - grub_uint32_t status; - - sync_all_caches (e); - - /* Check if EHCI is running and AL is enabled */ - status = grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS); - if ((status & GRUB_EHCI_ST_HC_HALTED) != 0) - /* XXX: Fix it: Currently we don't do anything to restart EHCI */ - { - grub_dprintf ("ehci", "setup_transfer: halted, status = 0x%x\n", - status); - return GRUB_USB_ERR_INTERNAL; - } - status = grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS); - if ((status - & (GRUB_EHCI_ST_AS_STATUS | GRUB_EHCI_ST_PS_STATUS)) == 0) - /* XXX: Fix it: Currently we don't do anything to restart EHCI */ - { - grub_dprintf ("ehci", "setup_transfer: no AS/PS, status = 0x%x\n", - status); - return GRUB_USB_ERR_INTERNAL; - } - - /* Allocate memory for controller transfer data. */ - cdata = grub_malloc (sizeof (*cdata)); - if (!cdata) - return GRUB_USB_ERR_INTERNAL; - cdata->td_first_virt = NULL; - - /* Allocate a queue head for the transfer queue. */ - cdata->qh_virt = grub_ehci_find_qh (e, transfer); - if (!cdata->qh_virt) - { - grub_dprintf ("ehci", "setup_transfer: no QH\n"); - grub_free (cdata); - return GRUB_USB_ERR_INTERNAL; - } - - /* To detect short packet we need some additional "alternate" TD, - * allocate it first. */ - cdata->td_alt_virt = grub_ehci_alloc_td (e); - if (!cdata->td_alt_virt) - { - grub_dprintf ("ehci", "setup_transfer: no TDs\n"); - grub_free (cdata); - return GRUB_USB_ERR_INTERNAL; - } - /* Fill whole alternate TD by zeros (= inactive) and set - * Terminate bits and Halt bit */ - grub_memset ((void *) cdata->td_alt_virt, 0, sizeof (struct grub_ehci_td)); - cdata->td_alt_virt->next_td = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE); - cdata->td_alt_virt->alt_next_td = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE); - cdata->td_alt_virt->token = grub_cpu_to_le32_compile_time (GRUB_EHCI_STATUS_HALTED); - - /* Allocate appropriate number of TDs and set */ - for (i = 0; i < transfer->transcnt; i++) - { - grub_usb_transaction_t tr = &transfer->transactions[i]; - - td = grub_ehci_transaction (e, tr->pid, tr->toggle, tr->size, - tr->data, cdata->td_alt_virt); - - if (!td) /* de-allocate and free all */ - { - grub_size_t actual = 0; - - if (cdata->td_first_virt) - grub_ehci_free_tds (e, cdata->td_first_virt, NULL, &actual); - - grub_free (cdata); - grub_dprintf ("ehci", "setup_transfer: no TD\n"); - return GRUB_USB_ERR_INTERNAL; - } - - /* Register new TD in cdata or previous TD */ - if (!cdata->td_first_virt) - cdata->td_first_virt = td; - else - { - td_prev->link_td = grub_dma_virt2phys (td, e->td_chunk); - td_prev->next_td = - grub_cpu_to_le32 (grub_dma_virt2phys (td, e->td_chunk)); - } - td_prev = td; - } - - /* Remember last TD */ - cdata->td_last_virt = td; - cdata->td_last_phys = grub_dma_virt2phys (td, e->td_chunk); - /* Last TD should not have set alternate TD */ - cdata->td_last_virt->alt_next_td = grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE); - - grub_dprintf ("ehci", "setup_transfer: cdata=%p, qh=%p\n", - cdata,cdata->qh_virt); - grub_dprintf ("ehci", "setup_transfer: td_first=%p, td_alt=%p\n", - cdata->td_first_virt, - cdata->td_alt_virt); - grub_dprintf ("ehci", "setup_transfer: td_last=%p\n", - cdata->td_last_virt); - - /* Start transfer: */ - /* Unlink possible alternate pointer in QH */ - cdata->qh_virt->td_overlay.alt_next_td = - grub_cpu_to_le32_compile_time (GRUB_EHCI_TERMINATE); - /* Link new TDs with QH via next_td */ - cdata->qh_virt->td_overlay.next_td = - grub_cpu_to_le32 (grub_dma_virt2phys - (cdata->td_first_virt, e->td_chunk)); - /* Reset Active and Halted bits in QH to activate Advance Queue, - * i.e. reset token */ - cdata->qh_virt->td_overlay.token = grub_cpu_to_le32_compile_time (0); - - sync_all_caches (e); - - /* Finito */ - transfer->controller_data = cdata; - - return GRUB_USB_ERR_NONE; -} - -/* This function expects QH is not active. - * Function set Halt bit in QH TD overlay and possibly prints - * necessary debug information. */ -static void -grub_ehci_pre_finish_transfer (grub_usb_transfer_t transfer) -{ - struct grub_ehci_transfer_controller_data *cdata = - transfer->controller_data; - - /* Collect debug data here if necessary */ - - /* Set Halt bit in not active QH. AL will not attempt to do - * Advance Queue on QH with Halt bit set, i.e., we can then - * safely manipulate with QH TD part. */ - cdata->qh_virt->td_overlay.token = (cdata->qh_virt->td_overlay.token - | - grub_cpu_to_le32_compile_time - (GRUB_EHCI_STATUS_HALTED)) & - grub_cpu_to_le32_compile_time (~GRUB_EHCI_STATUS_ACTIVE); - - /* Print debug data here if necessary */ - -} - -static grub_usb_err_t -grub_ehci_parse_notrun (grub_usb_controller_t dev, - grub_usb_transfer_t transfer, grub_size_t * actual) -{ - struct grub_ehci *e = dev->data; - struct grub_ehci_transfer_controller_data *cdata = - transfer->controller_data; - - grub_dprintf ("ehci", "parse_notrun: info\n"); - - /* QH can be in any state in this case. */ - /* But EHCI or AL is not running, so QH is surely not active - * even if it has Active bit set... */ - grub_ehci_pre_finish_transfer (transfer); - grub_ehci_free_tds (e, cdata->td_first_virt, transfer, actual); - grub_ehci_free_td (e, cdata->td_alt_virt); - grub_free (cdata); - - sync_all_caches (e); - - /* Additionally, do something with EHCI to make it running (what?) */ - /* Try enable EHCI and AL */ - grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, - GRUB_EHCI_CMD_RUNSTOP | GRUB_EHCI_CMD_AS_ENABL - | GRUB_EHCI_CMD_PS_ENABL - | grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); - /* Ensure command is written */ - grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND); - - return GRUB_USB_ERR_UNRECOVERABLE; -} - -static grub_usb_err_t -grub_ehci_parse_halt (grub_usb_controller_t dev, - grub_usb_transfer_t transfer, grub_size_t * actual) -{ - struct grub_ehci *e = dev->data; - struct grub_ehci_transfer_controller_data *cdata = - transfer->controller_data; - grub_uint32_t token; - grub_usb_err_t err = GRUB_USB_ERR_NAK; - - /* QH should be halted and not active in this case. */ - - grub_dprintf ("ehci", "parse_halt: info\n"); - - /* Remember token before call pre-finish function */ - token = grub_le_to_cpu32 (cdata->qh_virt->td_overlay.token); - - /* Do things like in normal finish */ - grub_ehci_pre_finish_transfer (transfer); - grub_ehci_free_tds (e, cdata->td_first_virt, transfer, actual); - grub_ehci_free_td (e, cdata->td_alt_virt); - grub_free (cdata); - - sync_all_caches (e); - - /* Evaluation of error code - currently we don't have GRUB USB error - * codes for some EHCI states, GRUB_USB_ERR_DATA is used for them. - * Order of evaluation is critical, specially bubble/stall. */ - if ((token & GRUB_EHCI_STATUS_BABBLE) != 0) - err = GRUB_USB_ERR_BABBLE; - else if ((token & GRUB_EHCI_CERR_MASK) != 0) - err = GRUB_USB_ERR_STALL; - else if ((token & GRUB_EHCI_STATUS_TRANERR) != 0) - err = GRUB_USB_ERR_DATA; - else if ((token & GRUB_EHCI_STATUS_BUFERR) != 0) - err = GRUB_USB_ERR_DATA; - else if ((token & GRUB_EHCI_STATUS_MISSDMF) != 0) - err = GRUB_USB_ERR_DATA; - - return err; -} - -static grub_usb_err_t -grub_ehci_parse_success (grub_usb_controller_t dev, - grub_usb_transfer_t transfer, grub_size_t * actual) -{ - struct grub_ehci *e = dev->data; - struct grub_ehci_transfer_controller_data *cdata = - transfer->controller_data; - - grub_dprintf ("ehci", "parse_success: info\n"); - - /* QH should be not active in this case, but it is not halted. */ - grub_ehci_pre_finish_transfer (transfer); - grub_ehci_free_tds (e, cdata->td_first_virt, transfer, actual); - grub_ehci_free_td (e, cdata->td_alt_virt); - grub_free (cdata); - - sync_all_caches (e); - - return GRUB_USB_ERR_NONE; -} - - -static grub_usb_err_t -grub_ehci_check_transfer (grub_usb_controller_t dev, - grub_usb_transfer_t transfer, grub_size_t * actual) -{ - struct grub_ehci *e = dev->data; - struct grub_ehci_transfer_controller_data *cdata = - transfer->controller_data; - grub_uint32_t token, token_ftd; - - sync_all_caches (e); - - grub_dprintf ("ehci", - "check_transfer: EHCI STATUS=%08x, cdata=%p, qh=%p\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS), - cdata, cdata->qh_virt); - grub_dprintf ("ehci", "check_transfer: qh_hptr=%08x, ep_char=%08x\n", - grub_le_to_cpu32 (cdata->qh_virt->qh_hptr), - grub_le_to_cpu32 (cdata->qh_virt->ep_char)); - grub_dprintf ("ehci", "check_transfer: ep_cap=%08x, td_current=%08x\n", - grub_le_to_cpu32 (cdata->qh_virt->ep_cap), - grub_le_to_cpu32 (cdata->qh_virt->td_current)); - grub_dprintf ("ehci", "check_transfer: next_td=%08x, alt_next_td=%08x\n", - grub_le_to_cpu32 (cdata->qh_virt->td_overlay.next_td), - grub_le_to_cpu32 (cdata->qh_virt->td_overlay.alt_next_td)); - grub_dprintf ("ehci", "check_transfer: token=%08x, buffer[0]=%08x\n", - grub_le_to_cpu32 (cdata->qh_virt->td_overlay.token), - grub_le_to_cpu32 (cdata->qh_virt->td_overlay.buffer_page[0])); - - /* Check if EHCI is running and AL is enabled */ - if ((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS) - & GRUB_EHCI_ST_HC_HALTED) != 0) - return grub_ehci_parse_notrun (dev, transfer, actual); - if ((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS) - & (GRUB_EHCI_ST_AS_STATUS | GRUB_EHCI_ST_PS_STATUS)) == 0) - return grub_ehci_parse_notrun (dev, transfer, actual); - - token = grub_le_to_cpu32 (cdata->qh_virt->td_overlay.token); - /* If the transfer consist from only one TD, we should check */ - /* if the TD was really executed and deactivated - to prevent */ - /* false detection of transfer finish. */ - token_ftd = grub_le_to_cpu32 (cdata->td_first_virt->token); - - /* Detect QH halted */ - if ((token & GRUB_EHCI_STATUS_HALTED) != 0) - return grub_ehci_parse_halt (dev, transfer, actual); - - /* Detect QH not active - QH is not active and no next TD */ - if (token && ((token & GRUB_EHCI_STATUS_ACTIVE) == 0) - && ((token_ftd & GRUB_EHCI_STATUS_ACTIVE) == 0)) - { - /* It could be finish at all or short packet condition */ - if ((grub_le_to_cpu32 (cdata->qh_virt->td_overlay.next_td) - & GRUB_EHCI_TERMINATE) && - ((grub_le_to_cpu32 (cdata->qh_virt->td_current) - & GRUB_EHCI_QHTDPTR_MASK) == cdata->td_last_phys)) - /* Normal finish */ - return grub_ehci_parse_success (dev, transfer, actual); - else if ((token & GRUB_EHCI_TOTAL_MASK) != 0) - /* Short packet condition */ - /* But currently we don't handle it - higher level will do it */ - return grub_ehci_parse_success (dev, transfer, actual); - } - - return GRUB_USB_ERR_WAIT; -} - -static grub_usb_err_t -grub_ehci_cancel_transfer (grub_usb_controller_t dev, - grub_usb_transfer_t transfer) -{ - struct grub_ehci *e = dev->data; - struct grub_ehci_transfer_controller_data *cdata = - transfer->controller_data; - grub_size_t actual; - int i; - grub_uint64_t maxtime; - grub_uint32_t qh_phys; - - sync_all_caches (e); - - grub_uint32_t interrupt = - cdata->qh_virt->ep_cap & GRUB_EHCI_SMASK_MASK; - - /* QH can be active and should be de-activated and halted */ - - grub_dprintf ("ehci", "cancel_transfer: begin\n"); - - /* First check if EHCI is running - if not, there is no problem */ - /* to cancel any transfer. Or, if transfer is asynchronous, check */ - /* if AL is enabled - if not, transfer can be canceled also. */ - if (((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS) & - GRUB_EHCI_ST_HC_HALTED) != 0) || - (!interrupt && ((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS) & - (GRUB_EHCI_ST_AS_STATUS | GRUB_EHCI_ST_PS_STATUS)) == 0))) - { - grub_ehci_pre_finish_transfer (transfer); - grub_ehci_free_tds (e, cdata->td_first_virt, transfer, &actual); - grub_ehci_free_td (e, cdata->td_alt_virt); - grub_free (cdata); - sync_all_caches (e); - grub_dprintf ("ehci", "cancel_transfer: end - EHCI not running\n"); - return GRUB_USB_ERR_NONE; - } - - /* EHCI and (AL or SL) are running. What to do? */ - /* Try to Halt QH via de-scheduling QH. */ - /* Find index of previous QH */ - qh_phys = grub_dma_virt2phys(cdata->qh_virt, e->qh_chunk); - for (i = 0; i < GRUB_EHCI_N_QH; i++) - { - if ((grub_le_to_cpu32(e->qh_virt[i].qh_hptr) - & GRUB_EHCI_QHTDPTR_MASK) == qh_phys) - break; - } - if (i == GRUB_EHCI_N_QH) - { - grub_printf ("%s: prev not found, queues are corrupt\n", __func__); - return GRUB_USB_ERR_UNRECOVERABLE; - } - /* Unlink QH from AL */ - e->qh_virt[i].qh_hptr = cdata->qh_virt->qh_hptr; - - sync_all_caches (e); - - /* If this is an interrupt transfer, we just wait for the periodic - * schedule to advance a few times and then assume that the EHCI - * controller has read the updated QH. */ - if (cdata->qh_virt->ep_cap & GRUB_EHCI_SMASK_MASK) - { - grub_millisleep(20); - } - else - { - /* For the asynchronous schedule we use the advance doorbell to find - * out when the EHCI controller has read the updated QH. */ - - /* Ring the doorbell */ - grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, - GRUB_EHCI_CMD_AS_ADV_D - | grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); - /* Ensure command is written */ - grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND); - /* Wait answer with timeout */ - maxtime = grub_get_time_ms () + 2; - while (((grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS) - & GRUB_EHCI_ST_AS_ADVANCE) == 0) - && (grub_get_time_ms () < maxtime)); - - /* We do not detect the timeout because if timeout occurs, it most - * probably means something wrong with EHCI - maybe stopped etc. */ - - /* Shut up the doorbell */ - grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, - ~GRUB_EHCI_CMD_AS_ADV_D - & grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); - grub_ehci_oper_write32 (e, GRUB_EHCI_STATUS, - GRUB_EHCI_ST_AS_ADVANCE - | grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS)); - /* Ensure command is written */ - grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS); - } - - /* Now is QH out of AL and we can do anything with it... */ - grub_ehci_pre_finish_transfer (transfer); - grub_ehci_free_tds (e, cdata->td_first_virt, transfer, &actual); - grub_ehci_free_td (e, cdata->td_alt_virt); - - /* "Free" the QH - link it to itself */ - cdata->qh_virt->ep_char = 0; - cdata->qh_virt->qh_hptr = - grub_cpu_to_le32 ((grub_dma_virt2phys (cdata->qh_virt, - e->qh_chunk) - & GRUB_EHCI_POINTER_MASK) | GRUB_EHCI_HPTR_TYPE_QH); - - grub_free (cdata); - - grub_dprintf ("ehci", "cancel_transfer: end\n"); - - sync_all_caches (e); - - return GRUB_USB_ERR_NONE; -} - -static int -grub_ehci_hubports (grub_usb_controller_t dev) -{ - struct grub_ehci *e = (struct grub_ehci *) dev->data; - grub_uint32_t portinfo; - - portinfo = grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_SPARAMS) - & GRUB_EHCI_SPARAMS_N_PORTS; - grub_dprintf ("ehci", "root hub ports=%d\n", portinfo); - return portinfo; -} - -static grub_usb_err_t -grub_ehci_portstatus (grub_usb_controller_t dev, - unsigned int port, unsigned int enable) -{ - struct grub_ehci *e = (struct grub_ehci *) dev->data; - grub_uint64_t endtime; - - grub_dprintf ("ehci", "portstatus: EHCI STATUS: %08x\n", - grub_ehci_oper_read32 (e, GRUB_EHCI_STATUS)); - grub_dprintf ("ehci", - "portstatus: begin, iobase=%p, port=%d, status=0x%02x\n", - e->iobase, port, grub_ehci_port_read (e, port)); - - /* In any case we need to disable port: - * - if enable==false - we should disable port - * - if enable==true we will do the reset and the specification says - * PortEnable should be FALSE in such case */ - /* Disable the port and wait for it. */ - grub_ehci_port_resbits (e, port, GRUB_EHCI_PORT_ENABLED); - endtime = grub_get_time_ms () + 1000; - while (grub_ehci_port_read (e, port) & GRUB_EHCI_PORT_ENABLED) - if (grub_get_time_ms () > endtime) - return GRUB_USB_ERR_TIMEOUT; - - if (!enable) /* We don't need reset port */ - { - grub_dprintf ("ehci", "portstatus: Disabled.\n"); - grub_dprintf ("ehci", "portstatus: end, status=0x%02x\n", - grub_ehci_port_read (e, port)); - return GRUB_USB_ERR_NONE; - } - - grub_dprintf ("ehci", "portstatus: enable\n"); - - grub_boot_time ("Resetting port %d", port); - - /* Now we will do reset - if HIGH speed device connected, it will - * result in Enabled state, otherwise port remains disabled. */ - /* Set RESET bit for 50ms */ - grub_ehci_port_setbits (e, port, GRUB_EHCI_PORT_RESET); - grub_millisleep (50); - - /* Reset RESET bit and wait for the end of reset */ - grub_ehci_port_resbits (e, port, GRUB_EHCI_PORT_RESET); - endtime = grub_get_time_ms () + 1000; - while (grub_ehci_port_read (e, port) & GRUB_EHCI_PORT_RESET) - if (grub_get_time_ms () > endtime) - return GRUB_USB_ERR_TIMEOUT; - grub_boot_time ("Port %d reset", port); - /* Remember "we did the reset" - needed by detect_dev */ - e->reset |= (1 << port); - /* Test if port enabled, i.e. HIGH speed device connected */ - if ((grub_ehci_port_read (e, port) & GRUB_EHCI_PORT_ENABLED) != 0) /* yes! */ - { - grub_dprintf ("ehci", "portstatus: Enabled!\n"); - /* "Reset recovery time" (USB spec.) */ - grub_millisleep (10); - } - else /* no... */ - { - /* FULL speed device connected - change port ownership. - * It results in disconnected state of this EHCI port. */ - grub_ehci_port_setbits (e, port, GRUB_EHCI_PORT_OWNER); - return GRUB_USB_ERR_BADDEVICE; - } - - /* XXX: Fix it! There is possible problem - we can say to calling - * function that we lost device if it is FULL speed onlu via - * return value <> GRUB_ERR_NONE. It (maybe) displays also error - * message on screen - but this situation is not error, it is normal - * state! */ - - grub_dprintf ("ehci", "portstatus: end, status=0x%02x\n", - grub_ehci_port_read (e, port)); - - return GRUB_USB_ERR_NONE; -} - -static grub_usb_speed_t -grub_ehci_detect_dev (grub_usb_controller_t dev, int port, int *changed) -{ - struct grub_ehci *e = (struct grub_ehci *) dev->data; - grub_uint32_t status, line_state; - - status = grub_ehci_port_read (e, port); - - /* Connect Status Change bit - it detects change of connection */ - if (status & GRUB_EHCI_PORT_CONNECT_CH) - { - *changed = 1; - /* Reset bit Connect Status Change */ - grub_ehci_port_setbits (e, port, GRUB_EHCI_PORT_CONNECT_CH); - } - else - *changed = 0; - - if (!(status & GRUB_EHCI_PORT_CONNECT)) - { /* We should reset related "reset" flag in not connected state */ - e->reset &= ~(1 << port); - return GRUB_USB_SPEED_NONE; - } - /* Detected connected state, so we should return speed. - * But we can detect only LOW speed device and only at connection - * time when PortEnabled=FALSE. FULL / HIGH speed detection is made - * later by EHCI-specific reset procedure. - * Another thing - if detected speed is LOW at connection time, - * we should change port ownership to companion controller. - * So: - * 1. If we detect connected and enabled and EHCI-owned port, - * we can say it is HIGH speed. - * 2. If we detect connected and not EHCI-owned port, we can say - * NONE speed, because such devices are not handled by EHCI. - * 3. If we detect connected, not enabled but reset port, we can say - * NONE speed, because it means FULL device connected to port and - * such devices are not handled by EHCI. - * 4. If we detect connected, not enabled and not reset port, which - * has line state != "K", we will say HIGH - it could be FULL or HIGH - * device, we will see it later after end of EHCI-specific reset - * procedure. - * 5. If we detect connected, not enabled and not reset port, which - * has line state == "K", we can say NONE speed, because LOW speed - * device is connected and we should change port ownership. */ - if ((status & GRUB_EHCI_PORT_ENABLED) != 0) /* Port already enabled, return high speed. */ - return GRUB_USB_SPEED_HIGH; - if ((status & GRUB_EHCI_PORT_OWNER) != 0) /* EHCI is not port owner */ - return GRUB_USB_SPEED_NONE; /* EHCI driver is ignoring this port. */ - if ((e->reset & (1 << port)) != 0) /* Port reset was done = FULL speed */ - return GRUB_USB_SPEED_NONE; /* EHCI driver is ignoring this port. */ - else /* Port connected but not enabled - test port speed. */ - { - line_state = status & GRUB_EHCI_PORT_LINE_STAT; - if (line_state != GRUB_EHCI_PORT_LINE_LOWSP) - return GRUB_USB_SPEED_HIGH; - /* Detected LOW speed device, we should change - * port ownership. - * XXX: Fix it!: There should be test if related companion - * controler is available ! And what to do if it does not exist ? */ - grub_ehci_port_setbits (e, port, GRUB_EHCI_PORT_OWNER); - return GRUB_USB_SPEED_NONE; /* Ignore this port */ - /* Note: Reset of PORT_OWNER bit is done by EHCI HW when - * device is really disconnected from port. - * Don't do PORT_OWNER bit reset by SW when not connected signal - * is detected in port register ! */ - } -} - -static grub_err_t -grub_ehci_restore_hw (void) -{ - struct grub_ehci *e; - grub_uint32_t n_ports; - int i; - - /* We should re-enable all EHCI HW similarly as on inithw */ - for (e = ehci; e; e = e->next) - { - /* Check if EHCI is halted and halt it if not */ - if (grub_ehci_halt (e) != GRUB_USB_ERR_NONE) - grub_error (GRUB_ERR_TIMEOUT, "restore_hw: EHCI halt timeout"); - - /* Reset EHCI */ - if (grub_ehci_reset (e) != GRUB_USB_ERR_NONE) - grub_error (GRUB_ERR_TIMEOUT, "restore_hw: EHCI reset timeout"); - - /* Setup some EHCI registers and enable EHCI */ - grub_ehci_oper_write32 (e, GRUB_EHCI_FL_BASE, e->framelist_phys); - grub_ehci_oper_write32 (e, GRUB_EHCI_CUR_AL_ADDR, - grub_dma_virt2phys (&e->qh_virt[1], - e->qh_chunk)); - grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, - GRUB_EHCI_CMD_RUNSTOP | - grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); - - /* Set ownership of root hub ports to EHCI */ - grub_ehci_oper_write32 (e, GRUB_EHCI_CONFIG_FLAG, - GRUB_EHCI_CF_EHCI_OWNER); - - /* Enable asynchronous list */ - grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, - GRUB_EHCI_CMD_AS_ENABL - | GRUB_EHCI_CMD_PS_ENABL - | grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); - - /* Now should be possible to power-up and enumerate ports etc. */ - if ((grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_SPARAMS) - & GRUB_EHCI_SPARAMS_PPC) != 0) - { /* EHCI has port powering control */ - /* Power on all ports */ - n_ports = grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_SPARAMS) - & GRUB_EHCI_SPARAMS_N_PORTS; - for (i = 0; i < (int) n_ports; i++) - grub_ehci_oper_write32 (e, GRUB_EHCI_PORT_STAT_CMD + i * 4, - GRUB_EHCI_PORT_POWER - | grub_ehci_oper_read32 (e, - GRUB_EHCI_PORT_STAT_CMD - + i * 4)); - } - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_ehci_fini_hw (int noreturn __attribute__ ((unused))) -{ - struct grub_ehci *e; - - /* We should disable all EHCI HW to prevent any DMA access etc. */ - for (e = ehci; e; e = e->next) - { - /* Disable both lists */ - grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, - ~(GRUB_EHCI_CMD_AS_ENABL | GRUB_EHCI_CMD_PS_ENABL) - & grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); - - /* Check if EHCI is halted and halt it if not */ - grub_ehci_halt (e); - - /* Reset EHCI */ - grub_ehci_reset (e); - } - - return GRUB_ERR_NONE; -} - -static struct grub_usb_controller_dev usb_controller = { - .name = "ehci", - .iterate = grub_ehci_iterate, - .setup_transfer = grub_ehci_setup_transfer, - .check_transfer = grub_ehci_check_transfer, - .cancel_transfer = grub_ehci_cancel_transfer, - .hubports = grub_ehci_hubports, - .portstatus = grub_ehci_portstatus, - .detect_dev = grub_ehci_detect_dev, - /* estimated max. count of TDs for one bulk transfer */ - .max_bulk_tds = GRUB_EHCI_N_TD * 3 / 4 -}; - -GRUB_MOD_INIT (ehci) -{ - COMPILE_TIME_ASSERT (sizeof (struct grub_ehci_td) == 64); - COMPILE_TIME_ASSERT (sizeof (struct grub_ehci_qh) == 96); - - grub_stop_disk_firmware (); - - grub_boot_time ("Initing EHCI hardware"); - grub_ehci_pci_scan (); - grub_boot_time ("Registering EHCI driver"); - grub_usb_controller_dev_register (&usb_controller); - grub_boot_time ("EHCI driver registered"); - grub_loader_register_preboot_hook (grub_ehci_fini_hw, grub_ehci_restore_hw, - GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); -} - -GRUB_MOD_FINI (ehci) -{ - grub_ehci_fini_hw (0); - grub_usb_controller_dev_unregister (&usb_controller); -} diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c deleted file mode 100644 index 5363a61f6..000000000 --- a/grub-core/bus/usb/ohci.c +++ /dev/null @@ -1,1468 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -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]; -} GRUB_PACKED; - -/* OHCI General Transfer Descriptor */ -struct grub_ohci_td -{ - /* Information used to construct the TOKEN packet. */ - grub_uint32_t token; - grub_uint32_t buffer; /* LittleEndian physical address */ - grub_uint32_t next_td; /* LittleEndian physical address */ - grub_uint32_t buffer_end; /* LittleEndian physical address */ - /* next values are not for OHCI HW */ - volatile struct grub_ohci_td *link_td; /* pointer to next free/chained TD - * pointer as uint32 */ - grub_uint32_t prev_td_phys; /* we need it to find previous TD - * physical address in CPU endian */ - grub_uint32_t tr_index; /* index of TD in transfer */ - grub_uint8_t pad[8 - sizeof (volatile struct grub_ohci_td *)]; /* padding to 32 bytes */ -} GRUB_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; -} GRUB_PACKED; - -typedef volatile struct grub_ohci_td *grub_ohci_td_t; -typedef volatile struct grub_ohci_ed *grub_ohci_ed_t; - -/* Experimental change of ED/TD allocation */ -/* Little bit similar as in UHCI */ -/* Implementation assumes: - * 32-bits architecture - XXX: fix for 64-bits - * memory allocated by grub_memalign_dma32 must be continuous - * in virtual and also in physical memory */ -struct grub_ohci -{ - volatile grub_uint32_t *iobase; - volatile struct grub_ohci_hcca *hcca; - grub_uint32_t hcca_addr; - struct grub_pci_dma_chunk *hcca_chunk; - grub_ohci_ed_t ed_ctrl; /* EDs for CONTROL */ - grub_uint32_t ed_ctrl_addr; - struct grub_pci_dma_chunk *ed_ctrl_chunk; - grub_ohci_ed_t ed_bulk; /* EDs for BULK */ - grub_uint32_t ed_bulk_addr; - struct grub_pci_dma_chunk *ed_bulk_chunk; - grub_ohci_td_t td; /* TDs */ - grub_uint32_t td_addr; - struct grub_pci_dma_chunk *td_chunk; - struct grub_ohci *next; - grub_ohci_td_t td_free; /* Pointer to first free TD */ -}; - -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_PERIODIC_START = 16, - GRUB_OHCI_REG_RHUBA = 18, - GRUB_OHCI_REG_RHUBPORT = 21, - GRUB_OHCI_REG_LEGACY_CONTROL = 0x100, - GRUB_OHCI_REG_LEGACY_INPUT = 0x104, - GRUB_OHCI_REG_LEGACY_OUTPUT = 0x108, - GRUB_OHCI_REG_LEGACY_STATUS = 0x10c -} grub_ohci_reg_t; - -#define GRUB_OHCI_RHUB_PORT_POWER_MASK 0x300 -#define GRUB_OHCI_RHUB_PORT_ALL_POWERED 0x200 - -#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK 0x8fff0000 -#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT 16 -#define GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT 0 - -/* XXX: Is this choice of timings sane? */ -#define GRUB_OHCI_FSMPS 0x2778 -#define GRUB_OHCI_PERIODIC_START 0x257f -#define GRUB_OHCI_FRAME_INTERVAL 0x2edf - -#define GRUB_OHCI_SET_PORT_ENABLE (1 << 1) -#define GRUB_OHCI_CLEAR_PORT_ENABLE (1 << 0) -#define GRUB_OHCI_SET_PORT_RESET (1 << 4) -#define GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE (1 << 20) - -#define GRUB_OHCI_REG_CONTROL_BULK_ENABLE (1 << 5) -#define GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE (1 << 4) - -#define GRUB_OHCI_RESET_CONNECT_CHANGE (1 << 16) -#define GRUB_OHCI_CTRL_EDS 256 -#define GRUB_OHCI_BULK_EDS 510 -#define GRUB_OHCI_TDS 640 - -#define GRUB_OHCI_ED_ADDR_MASK 0x7ff - -static inline grub_ohci_ed_t -grub_ohci_ed_phys2virt (struct grub_ohci *o, int bulk, grub_uint32_t x) -{ - if (!x) - return NULL; - if (bulk) - return (grub_ohci_ed_t) (x - o->ed_bulk_addr - + (grub_uint8_t *) o->ed_bulk); - return (grub_ohci_ed_t) (x - o->ed_ctrl_addr - + (grub_uint8_t *) o->ed_ctrl); -} - -static grub_uint32_t -grub_ohci_virt_to_phys (struct grub_ohci *o, int bulk, grub_ohci_ed_t x) -{ - if (!x) - return 0; - - if (bulk) - return (grub_uint8_t *) x - (grub_uint8_t *) o->ed_bulk + o->ed_bulk_addr; - return (grub_uint8_t *) x - (grub_uint8_t *) o->ed_ctrl + o->ed_ctrl_addr; -} - -static inline grub_ohci_td_t -grub_ohci_td_phys2virt (struct grub_ohci *o, grub_uint32_t x) -{ - if (!x) - return NULL; - return (grub_ohci_td_t) (x - o->td_addr + (grub_uint8_t *) o->td); -} - -static grub_uint32_t -grub_ohci_td_virt2phys (struct grub_ohci *o, grub_ohci_td_t x) -{ - if (!x) - return 0; - return (grub_uint8_t *)x - (grub_uint8_t *)o->td + o->td_addr; -} - - -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); -} - - - -/* Iterate over all PCI devices. Determine if a device is an OHCI - controller. If this is the case, initialize it. */ -static int -grub_ohci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, - void *data __attribute__ ((unused))) -{ - grub_uint32_t interf; - grub_uint32_t base; - grub_pci_address_t addr; - struct grub_ohci *o; - grub_uint32_t revision; - int j; - - /* Determine IO base address. */ - grub_dprintf ("ohci", "pciid = %x\n", pciid); - - if (pciid == GRUB_CS5536_PCIID) - { - grub_uint64_t basereg; - - basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE); - if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE)) - { - /* Shouldn't happen. */ - grub_dprintf ("ohci", "No OHCI address is assigned\n"); - return 0; - } - base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK); - basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER; - basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED; - basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS; - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE, basereg); - } - else - { - grub_uint32_t class_code; - grub_uint32_t class; - grub_uint32_t subclass; - - 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; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - base = grub_pci_read (addr); - - base &= GRUB_PCI_ADDR_MEM_MASK; - if (!base) - { - grub_dprintf ("ehci", - "EHCI: EHCI is not mapper\n"); - return 0; - } - - /* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */ - addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write_word(addr, - GRUB_PCI_COMMAND_MEM_ENABLED - | GRUB_PCI_COMMAND_BUS_MASTER - | grub_pci_read_word(addr)); - - grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x\n", - class, subclass, interf); - } - - /* Allocate memory for the controller and register it. */ - o = grub_malloc (sizeof (*o)); - if (! o) - return 1; - grub_memset ((void*)o, 0, sizeof (*o)); - o->iobase = grub_pci_device_map_range (dev, base, 0x800); - - grub_dprintf ("ohci", "base=%p\n", o->iobase); - - /* Reserve memory for the HCCA. */ - o->hcca_chunk = grub_memalign_dma32 (256, 256); - if (! o->hcca_chunk) - goto fail; - o->hcca = grub_dma_get_virt (o->hcca_chunk); - o->hcca_addr = grub_dma_get_phys (o->hcca_chunk); - grub_memset ((void*)o->hcca, 0, sizeof(*o->hcca)); - grub_dprintf ("ohci", "hcca: chunk=%p, virt=%p, phys=0x%02x\n", - o->hcca_chunk, o->hcca, o->hcca_addr); - - /* Reserve memory for ctrl EDs. */ - o->ed_ctrl_chunk = grub_memalign_dma32 (16, sizeof(struct grub_ohci_ed) - * GRUB_OHCI_CTRL_EDS); - if (! o->ed_ctrl_chunk) - goto fail; - o->ed_ctrl = grub_dma_get_virt (o->ed_ctrl_chunk); - o->ed_ctrl_addr = grub_dma_get_phys (o->ed_ctrl_chunk); - /* Preset EDs */ - grub_memset ((void *) o->ed_ctrl, 0, sizeof (struct grub_ohci_ed) - * GRUB_OHCI_CTRL_EDS); - for (j=0; j < GRUB_OHCI_CTRL_EDS; j++) - o->ed_ctrl[j].target = grub_cpu_to_le32_compile_time (1 << 14); /* skip */ - - grub_dprintf ("ohci", "EDs-C: chunk=%p, virt=%p, phys=0x%02x\n", - o->ed_ctrl_chunk, o->ed_ctrl, o->ed_ctrl_addr); - - /* Reserve memory for bulk EDs. */ - o->ed_bulk_chunk = grub_memalign_dma32 (16, sizeof (struct grub_ohci_ed) - * GRUB_OHCI_BULK_EDS); - if (! o->ed_bulk_chunk) - goto fail; - o->ed_bulk = grub_dma_get_virt (o->ed_bulk_chunk); - o->ed_bulk_addr = grub_dma_get_phys (o->ed_bulk_chunk); - /* Preset EDs */ - grub_memset ((void*)o->ed_bulk, 0, sizeof(struct grub_ohci_ed) * GRUB_OHCI_BULK_EDS); - for (j=0; j < GRUB_OHCI_BULK_EDS; j++) - o->ed_bulk[j].target = grub_cpu_to_le32_compile_time (1 << 14); /* skip */ - - grub_dprintf ("ohci", "EDs-B: chunk=%p, virt=%p, phys=0x%02x\n", - o->ed_bulk_chunk, o->ed_bulk, o->ed_bulk_addr); - - /* Reserve memory for TDs. */ - o->td_chunk = grub_memalign_dma32 (32, sizeof(struct grub_ohci_td)*GRUB_OHCI_TDS); - /* Why is it aligned on 32 boundary if spec. says 16 ? - * We have structure 32 bytes long and we don't want cross - * 4K boundary inside structure. */ - if (! o->td_chunk) - goto fail; - o->td_free = o->td = grub_dma_get_virt (o->td_chunk); - o->td_addr = grub_dma_get_phys (o->td_chunk); - /* Preset free TDs chain in TDs */ - grub_memset ((void*)o->td, 0, sizeof(struct grub_ohci_td) * GRUB_OHCI_TDS); - for (j=0; j < (GRUB_OHCI_TDS-1); j++) - o->td[j].link_td = &o->td[j+1]; - - grub_dprintf ("ohci", "TDs: chunk=%p, virt=%p, phys=0x%02x\n", - o->td_chunk, o->td, o->td_addr); - - /* 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; - - { - grub_uint32_t control; - /* Check SMM/BIOS ownership of OHCI (SMM = USB Legacy Support driver for BIOS) */ - control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); - if ((control & 0x100) != 0) - { - unsigned i; - grub_dprintf("ohci", "OHCI is owned by SMM\n"); - /* Do change of ownership */ - /* Ownership change request */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, (1<<3)); /* XXX: Magic. */ - /* Waiting for SMM deactivation */ - for (i=0; i < 10; i++) - { - if ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & 0x100) == 0) - { - grub_dprintf("ohci", "Ownership changed normally.\n"); - break; - } - grub_millisleep (100); - } - if (i >= 10) - { - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & ~0x100); - grub_dprintf("ohci", "Ownership changing timeout, change forced !\n"); - } - } - else if (((control & 0x100) == 0) && - ((control & 0xc0) != 0)) /* Not owned by SMM nor reset */ - { - grub_dprintf("ohci", "OHCI is owned by BIOS\n"); - /* Do change of ownership - not implemented yet... */ - /* In fact we probably need to do nothing ...? */ - } - else - { - grub_dprintf("ohci", "OHCI is not owned by SMM nor BIOS\n"); - /* We can setup OHCI. */ - } - } - - /* 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"); - - grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, - (GRUB_OHCI_FSMPS - << GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT) - | (GRUB_OHCI_FRAME_INTERVAL - << GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT)); - - grub_ohci_writereg32 (o, GRUB_OHCI_REG_PERIODIC_START, - GRUB_OHCI_PERIODIC_START); - - /* Setup the HCCA. */ - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr); - grub_dprintf ("ohci", "OHCI HCCA\n"); - - /* Misc. pre-sets. */ - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ - /* We don't want modify CONTROL/BULK HEAD registers. - * So we assign to HEAD registers zero ED from related array - * and we will not use this ED, it will be always skipped. - * It should not produce notable performance penalty (I hope). */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, o->ed_ctrl_addr); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, o->ed_bulk_addr); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); - - /* Check OHCI Legacy Support */ - if ((revision & 0x100) != 0) - { - grub_dprintf ("ohci", "Legacy Support registers detected\n"); - grub_dprintf ("ohci", "Current state of legacy control reg.: 0x%04x\n", - grub_ohci_readreg32 (o, GRUB_OHCI_REG_LEGACY_CONTROL)); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_LEGACY_CONTROL, - (grub_ohci_readreg32 (o, GRUB_OHCI_REG_LEGACY_CONTROL)) & ~1); - grub_dprintf ("ohci", "OHCI Legacy Support disabled.\n"); - } - - /* Enable the OHCI + enable CONTROL and BULK LIST. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, - (2 << 6) - | GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE - | GRUB_OHCI_REG_CONTROL_BULK_ENABLE ); - grub_dprintf ("ohci", "OHCI enable: 0x%02x\n", - (grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) >> 6) & 3); - - /* Power on all ports */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBA, - (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) - & ~GRUB_OHCI_RHUB_PORT_POWER_MASK) - | GRUB_OHCI_RHUB_PORT_ALL_POWERED); -#if 0 /* We don't need it at all, handled via hotplugging */ - /* Now we have hot-plugging, we need to wait for stable power only */ - grub_millisleep (100); -#endif - - /* Link to ohci now that initialisation is successful. */ - o->next = ohci; - ohci = o; - - return 0; - - fail: - if (o) - { - grub_dma_free (o->td_chunk); - grub_dma_free (o->ed_bulk_chunk); - grub_dma_free (o->ed_ctrl_chunk); - grub_dma_free (o->hcca_chunk); - } - grub_free (o); - - return 0; -} - - -static void -grub_ohci_inithw (void) -{ - grub_pci_iterate (grub_ohci_pci_iter, NULL); -} - - - -static int -grub_ohci_iterate (grub_usb_controller_iterate_hook_t hook, void *hook_data) -{ - struct grub_ohci *o; - struct grub_usb_controller dev; - - for (o = ohci; o; o = o->next) - { - dev.data = o; - if (hook (&dev, hook_data)) - return 1; - } - - return 0; -} - -static grub_ohci_ed_t -grub_ohci_find_ed (struct grub_ohci *o, int bulk, grub_uint32_t target) -{ - grub_ohci_ed_t ed, ed_next; - grub_uint32_t target_addr = target & GRUB_OHCI_ED_ADDR_MASK; - int count; - int i; - - /* Use proper values and structures. */ - if (bulk) - { - count = GRUB_OHCI_BULK_EDS; - ed = o->ed_bulk; - ed_next = grub_ohci_ed_phys2virt(o, bulk, - grub_le_to_cpu32 (ed->next_ed) ); - } - else - { - count = GRUB_OHCI_CTRL_EDS; - ed = o->ed_ctrl; - ed_next = grub_ohci_ed_phys2virt(o, bulk, - grub_le_to_cpu32 (ed->next_ed) ); - } - - /* First try to find existing ED with proper target address */ - for (i = 0; ; ) - { - if (i && /* We ignore zero ED */ - ((ed->target & GRUB_OHCI_ED_ADDR_MASK) == target_addr)) - return ed; /* Found proper existing ED */ - i++; - if (ed_next && (i < count)) - { - ed = ed_next; - ed_next = grub_ohci_ed_phys2virt(o, bulk, - grub_le_to_cpu32 (ed->next_ed) ); - continue; - } - break; - } - /* ED with target_addr does not exist, we have to add it */ - /* Have we any free ED in array ? */ - if (i >= count) /* No. */ - return NULL; - /* Currently we simply take next ED in array, no allocation - * function is used. It should be no problem until hot-plugging - * will be implemented, i.e. until we will need to de-allocate EDs - * of unplugged devices. */ - /* We can link new ED to previous ED safely as the new ED should - * still have set skip bit. */ - ed->next_ed = grub_cpu_to_le32 ( grub_ohci_virt_to_phys (o, - bulk, &ed[1])); - return &ed[1]; -} - -static grub_ohci_td_t -grub_ohci_alloc_td (struct grub_ohci *o) -{ - grub_ohci_td_t ret; - - /* Check if there is a Transfer Descriptor available. */ - if (! o->td_free) - return NULL; - - ret = o->td_free; /* Take current free TD */ - o->td_free = (grub_ohci_td_t)ret->link_td; /* Advance to next free TD in chain */ - ret->link_td = 0; /* Reset link_td in allocated TD */ - return ret; -} - -static void -grub_ohci_free_td (struct grub_ohci *o, grub_ohci_td_t td) -{ - grub_memset ( (void*)td, 0, sizeof(struct grub_ohci_td) ); - td->link_td = o->td_free; /* Cahin new free TD & rest */ - o->td_free = td; /* Change address of first free TD */ -} - -static void -grub_ohci_free_tds (struct grub_ohci *o, grub_ohci_td_t td) -{ - if (!td) - return; - - /* Unchain first TD from previous TD if it is chained */ - if (td->prev_td_phys) - { - grub_ohci_td_t td_prev_virt = grub_ohci_td_phys2virt(o, - td->prev_td_phys); - - if (td == (grub_ohci_td_t) td_prev_virt->link_td) - td_prev_virt->link_td = 0; - } - - /* Free all TDs from td (chained by link_td) */ - while (td) - { - grub_ohci_td_t tdprev; - - /* Unlink the queue. */ - tdprev = td; - td = (grub_ohci_td_t) td->link_td; - - /* Free the TD. */ - grub_ohci_free_td (o, tdprev); - } -} - -static void -grub_ohci_transaction (grub_ohci_td_t td, - grub_transfer_type_t type, unsigned int toggle, - grub_size_t size, grub_uint32_t 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=%lu\n", - td, type, toggle, (unsigned long) 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; - } - - /* Set the token */ - token |= ( 7 << 21); /* Never generate interrupt */ - token |= toggle << 24; - token |= 1 << 25; - - /* Set "Not accessed" error code */ - token |= 15 << 28; - - buffer = data; - buffer_end = buffer + size - 1; - - /* Set correct buffer values in TD if zero transfer occurs */ - if (size) - { - buffer = (grub_uint32_t) data; - buffer_end = buffer + size - 1; - td->buffer = grub_cpu_to_le32 (buffer); - td->buffer_end = grub_cpu_to_le32 (buffer_end); - } - else - { - td->buffer = 0; - td->buffer_end = 0; - } - - /* Set the rest of TD */ - td->token = grub_cpu_to_le32 (token); - td->next_td = 0; -} - -struct grub_ohci_transfer_controller_data -{ - grub_uint32_t tderr_phys; - grub_uint32_t td_last_phys; - grub_ohci_ed_t ed_virt; - grub_ohci_td_t td_current_virt; - grub_ohci_td_t td_head_virt; -}; - -static grub_usb_err_t -grub_ohci_setup_transfer (grub_usb_controller_t dev, - grub_usb_transfer_t transfer) -{ - struct grub_ohci *o = (struct grub_ohci *) dev->data; - int bulk = 0; - grub_ohci_td_t td_next_virt; - grub_uint32_t target; - grub_uint32_t td_head_phys; - grub_uint32_t td_tail_phys; - int i; - struct grub_ohci_transfer_controller_data *cdata; - - cdata = grub_zalloc (sizeof (*cdata)); - if (!cdata) - return GRUB_USB_ERR_INTERNAL; - - /* Pre-set target for ED - we need it to find proper ED */ - /* Set the device address. */ - target = transfer->devaddr; - /* Set the endpoint. It should be masked, we need 4 bits only. */ - target |= (transfer->endpoint & 15) << 7; - /* Set the device speed. */ - target |= (transfer->dev->speed == GRUB_USB_SPEED_LOW) << 13; - /* Set the maximum packet size. */ - target |= transfer->max << 16; - - /* Determine if transfer type is bulk - we need to select proper ED */ - switch (transfer->type) - { - case GRUB_USB_TRANSACTION_TYPE_BULK: - bulk = 1; - break; - - case GRUB_USB_TRANSACTION_TYPE_CONTROL: - break; - - default: - grub_free (cdata); - return GRUB_USB_ERR_INTERNAL; - } - - /* Find proper ED or add new ED */ - cdata->ed_virt = grub_ohci_find_ed (o, bulk, target); - if (!cdata->ed_virt) - { - grub_dprintf ("ohci","Fatal: No free ED !\n"); - grub_free (cdata); - return GRUB_USB_ERR_INTERNAL; - } - - /* Take pointer to first TD from ED */ - td_head_phys = grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf; - td_tail_phys = grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf; - - /* Sanity check - td_head should be equal to td_tail */ - if (td_head_phys != td_tail_phys) /* Should never happen ! */ - { - grub_dprintf ("ohci", "Fatal: HEAD is not equal to TAIL !\n"); - grub_dprintf ("ohci", "HEAD = 0x%02x, TAIL = 0x%02x\n", - td_head_phys, td_tail_phys); - /* XXX: Fix: What to do ? */ - grub_free (cdata); - return GRUB_USB_ERR_INTERNAL; - } - - /* Now we should handle first TD. If ED is newly allocated, - * we must allocate the first TD. */ - if (!td_head_phys) - { - cdata->td_head_virt = grub_ohci_alloc_td (o); - if (!cdata->td_head_virt) - { - grub_free (cdata); - return GRUB_USB_ERR_INTERNAL; /* We don't need de-allocate ED */ - } - /* We can set td_head only when ED is not active, i.e. - * when it is newly allocated. */ - cdata->ed_virt->td_head - = grub_cpu_to_le32 (grub_ohci_td_virt2phys (o, cdata->td_head_virt)); - cdata->ed_virt->td_tail = cdata->ed_virt->td_head; - } - else - cdata->td_head_virt = grub_ohci_td_phys2virt ( o, td_head_phys ); - - /* Set TDs */ - cdata->td_last_phys = td_head_phys; /* initial value to make compiler happy... */ - for (i = 0, cdata->td_current_virt = cdata->td_head_virt; - i < transfer->transcnt; i++) - { - grub_usb_transaction_t tr = &transfer->transactions[i]; - - grub_ohci_transaction (cdata->td_current_virt, tr->pid, tr->toggle, - tr->size, tr->data); - - /* Set index of TD in transfer */ - cdata->td_current_virt->tr_index = (grub_uint32_t) i; - - /* Remember last used (processed) TD phys. addr. */ - cdata->td_last_phys = grub_ohci_td_virt2phys (o, cdata->td_current_virt); - - /* Allocate next TD */ - td_next_virt = grub_ohci_alloc_td (o); - if (!td_next_virt) /* No free TD, cancel transfer and free TDs except head TD */ - { - if (i) /* if i==0 we have nothing to free... */ - grub_ohci_free_tds (o, grub_ohci_td_phys2virt(o, - grub_le_to_cpu32 (cdata->td_head_virt->next_td))); - /* Reset head TD */ - grub_memset ( (void*)cdata->td_head_virt, 0, - sizeof(struct grub_ohci_td) ); - grub_dprintf ("ohci", "Fatal: No free TD !"); - grub_free (cdata); - return GRUB_USB_ERR_INTERNAL; - } - - /* Chain TDs */ - - cdata->td_current_virt->link_td = td_next_virt; - cdata->td_current_virt->next_td = grub_cpu_to_le32 ( - grub_ohci_td_virt2phys (o, - td_next_virt) ); - td_next_virt->prev_td_phys = grub_ohci_td_virt2phys (o, - cdata->td_current_virt); - cdata->td_current_virt = td_next_virt; - } - - grub_dprintf ("ohci", "Tail TD (not processed) = %p\n", - cdata->td_current_virt); - - /* Setup the Endpoint Descriptor for transfer. */ - /* First set necessary fields in TARGET but keep (or set) skip bit */ - /* Note: It could be simpler if speed, format and max. packet - * size never change after first allocation of ED. - * But unfortunately max. packet size may change during initial - * setup sequence and we must handle it. */ - cdata->ed_virt->target = grub_cpu_to_le32 (target | (1 << 14)); - /* Set td_tail */ - cdata->ed_virt->td_tail - = grub_cpu_to_le32 (grub_ohci_td_virt2phys (o, cdata->td_current_virt)); - /* Now reset skip bit */ - cdata->ed_virt->target = grub_cpu_to_le32 (target); - /* ed_virt->td_head = grub_cpu_to_le32 (td_head); Must not be changed, it is maintained by OHCI */ - /* ed_virt->next_ed = grub_cpu_to_le32 (0); Handled by grub_ohci_find_ed, do not change ! */ - - grub_dprintf ("ohci", "program OHCI\n"); - - /* Program the OHCI to actually transfer. */ - switch (transfer->type) - { - case GRUB_USB_TRANSACTION_TYPE_BULK: - { - grub_dprintf ("ohci", "BULK list filled\n"); - /* Set BulkListFilled. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1 << 2); - /* Read back of register should ensure it is really written */ - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); - break; - } - - case GRUB_USB_TRANSACTION_TYPE_CONTROL: - { - grub_dprintf ("ohci", "CONTROL list filled\n"); - /* Set ControlListFilled. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1 << 1); - /* Read back of register should ensure it is really written */ - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); - break; - } - } - - transfer->controller_data = cdata; - - return GRUB_USB_ERR_NONE; -} - -static void -pre_finish_transfer (grub_usb_controller_t dev, - grub_usb_transfer_t transfer) -{ - struct grub_ohci *o = dev->data; - struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data; - grub_uint32_t target; - grub_uint32_t status; - grub_uint32_t control; - grub_uint32_t intstatus; - - /* There are many ways how the loop above can finish: - * - normally without any error via INTSTATUS WDH bit - * : tderr_phys == td_last_phys, td_head == td_tail - * - normally with error via HALT bit in ED TD HEAD - * : td_head = next TD after TD with error - * : tderr_phys = last processed and retired TD with error, - * i.e. should be != 0 - * : if bad_OHCI == TRUE, tderr_phys will be probably invalid - * - unrecoverable error - I never seen it but it could be - * : err_unrec == TRUE, other values can contain anything... - * - timeout, it can be caused by: - * -- bad USB device - some devices have some bugs, see Linux source - * and related links - * -- bad OHCI controller - e.g. lost interrupts or does not set - * proper bits in INTSTATUS when real IRQ not enabled etc., - * see Linux source and related links - * One known bug is handled - if transfer finished - * successfully (i.e. HEAD==TAIL, last transfer TD is retired, - * HALT bit is not set) and WDH bit is not set in INTSTATUS - in - * this case we set o->bad_OHCI=TRUE and do alternate loop - * and error handling - but there is problem how to find retired - * TD with error code if HALT occurs and if DONEHEAD is not - * working - we need to find TD previous to current ED HEAD - * -- bad code of this driver or some unknown reasons - :-( - * it can be e.g. bad handling of EDs/TDs/toggle bit... - */ - - /* Remember target for debug and set skip flag in ED */ - /* It should be normaly not necessary but we need it at least - * in case of timeout */ - target = grub_le_to_cpu32 ( cdata->ed_virt->target ); - cdata->ed_virt->target = grub_cpu_to_le32 (target | (1 << 14)); - /* Read registers for debug - they should be read now because - * debug prints case unwanted delays, so something can happen - * in the meantime... */ - control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); - status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); - intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - /* Now print debug values - to have full info what happened */ - grub_dprintf ("ohci", "loop finished: control=0x%02x status=0x%02x\n", - control, status); - grub_dprintf ("ohci", "intstatus=0x%02x, td_last_phys=0x%02x\n", - intstatus, cdata->td_last_phys); - grub_dprintf ("ohci", "TARGET=0x%02x, HEAD=0x%02x, TAIL=0x%02x\n", - target, - grub_le_to_cpu32 (cdata->ed_virt->td_head), - grub_le_to_cpu32 (cdata->ed_virt->td_tail) ); - -} - -static void -finish_transfer (grub_usb_controller_t dev, - grub_usb_transfer_t transfer) -{ - struct grub_ohci *o = dev->data; - struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data; - - /* Set empty ED - set HEAD = TAIL = last (not processed) TD */ - cdata->ed_virt->td_head = grub_cpu_to_le32 (grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf); - - /* At this point always should be: - * ED has skip bit set and halted or empty or after next SOF, - * i.e. it is safe to free all TDs except last not processed - * ED HEAD == TAIL == phys. addr. of td_current_virt */ - - /* Un-chainig of last TD */ - if (cdata->td_current_virt->prev_td_phys) - { - grub_ohci_td_t td_prev_virt - = grub_ohci_td_phys2virt (o, cdata->td_current_virt->prev_td_phys); - - if (cdata->td_current_virt == (grub_ohci_td_t) td_prev_virt->link_td) - td_prev_virt->link_td = 0; - - cdata->td_current_virt->prev_td_phys = 0; - } - - grub_dprintf ("ohci", "OHCI finished, freeing\n"); - grub_ohci_free_tds (o, cdata->td_head_virt); - grub_free (cdata); -} - -static grub_usb_err_t -parse_halt (grub_usb_controller_t dev, - grub_usb_transfer_t transfer, - grub_size_t *actual) -{ - struct grub_ohci *o = dev->data; - struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data; - grub_uint8_t errcode = 0; - grub_usb_err_t err = GRUB_USB_ERR_NAK; - grub_ohci_td_t tderr_virt = NULL; - - *actual = 0; - - pre_finish_transfer (dev, transfer); - - /* First we must get proper tderr_phys value */ - /* Retired TD with error should be previous TD to ED->td_head */ - cdata->tderr_phys = grub_ohci_td_phys2virt (o, - grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf ) - ->prev_td_phys; - - /* Prepare pointer to last processed TD and get error code */ - tderr_virt = grub_ohci_td_phys2virt (o, cdata->tderr_phys); - /* Set index of last processed TD */ - if (tderr_virt) - { - errcode = grub_le_to_cpu32 (tderr_virt->token) >> 28; - transfer->last_trans = tderr_virt->tr_index; - } - else - transfer->last_trans = -1; - - /* Evaluation of error code */ - grub_dprintf ("ohci", "OHCI tderr_phys=0x%02x, errcode=0x%02x\n", - cdata->tderr_phys, errcode); - switch (errcode) - { - case 0: - /* XXX: Should not happen! */ - grub_error (GRUB_ERR_IO, "OHCI failed 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; - grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n", - tderr_virt, tderr_virt->tr_index); - break; - - case 9: - /* XXX: Data underrun error. */ - grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n", - tderr_virt, tderr_virt->tr_index); - if (transfer->last_trans == -1) - break; - *actual = transfer->transactions[transfer->last_trans].size - - (grub_le_to_cpu32 (tderr_virt->buffer_end) - - grub_le_to_cpu32 (tderr_virt->buffer)) - + transfer->transactions[transfer->last_trans].preceding; - err = GRUB_USB_ERR_NONE; - 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; - } - - finish_transfer (dev, transfer); - - return err; -} - -static grub_usb_err_t -parse_success (grub_usb_controller_t dev, - grub_usb_transfer_t transfer, - grub_size_t *actual) -{ - struct grub_ohci *o = dev->data; - struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data; - grub_ohci_td_t tderr_virt = NULL; - - pre_finish_transfer (dev, transfer); - - /* I hope we can do it as transfer (most probably) finished OK */ - cdata->tderr_phys = cdata->td_last_phys; - - /* Prepare pointer to last processed TD */ - tderr_virt = grub_ohci_td_phys2virt (o, cdata->tderr_phys); - - /* Set index of last processed TD */ - if (tderr_virt) - transfer->last_trans = tderr_virt->tr_index; - else - transfer->last_trans = -1; - *actual = transfer->size + 1; - - finish_transfer (dev, transfer); - - return GRUB_USB_ERR_NONE; -} - -static grub_usb_err_t -parse_unrec (grub_usb_controller_t dev, - grub_usb_transfer_t transfer, - grub_size_t *actual) -{ - struct grub_ohci *o = dev->data; - - *actual = 0; - - pre_finish_transfer (dev, transfer); - - /* Don't try to get error code and last processed TD for proper - * toggle bit value - anything can be invalid */ - grub_dprintf("ohci", "Unrecoverable error!"); - - /* Do OHCI reset in case of unrecoverable error - maybe we will need - * do more - re-enumerate bus etc. (?) */ - - /* Suspend the OHCI by issuing a reset. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */ - /* Read back of register should ensure it is really written */ - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); - grub_millisleep (1); - grub_dprintf ("ohci", "Unrecoverable error - OHCI reset\n"); - - /* Misc. resets. */ - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, o->ed_ctrl_addr); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, o->ed_bulk_addr); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); - /* Read back of register should ensure it is really written */ - grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - - /* Enable the OHCI. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, - (2 << 6) - | GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE - | GRUB_OHCI_REG_CONTROL_BULK_ENABLE ); - finish_transfer (dev, transfer); - - return GRUB_USB_ERR_UNRECOVERABLE; -} - -static grub_usb_err_t -grub_ohci_check_transfer (grub_usb_controller_t dev, - grub_usb_transfer_t transfer, - grub_size_t *actual) -{ - struct grub_ohci *o = dev->data; - struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data; - grub_uint32_t intstatus; - - /* Check transfer status */ - intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - - if ((intstatus & 0x10) != 0) - /* Unrecoverable error - only reset can help...! */ - return parse_unrec (dev, transfer, actual); - - /* Detected a HALT. */ - if ((grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1)) - return parse_halt (dev, transfer, actual); - - /* Finished ED detection */ - if ( (grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xfU) == - (grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xfU) ) /* Empty ED */ - { - /* Check the HALT bit */ - /* It looks like nonsense - it was tested previously... - * but it can change because OHCI is working - * simultaneously via DMA... */ - if (grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1) - return parse_halt (dev, transfer, actual); - else - return parse_success (dev, transfer, actual); - } - - return GRUB_USB_ERR_WAIT; -} - -static grub_usb_err_t -grub_ohci_cancel_transfer (grub_usb_controller_t dev, - grub_usb_transfer_t transfer) -{ - struct grub_ohci *o = dev->data; - struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data; - grub_ohci_td_t tderr_virt = NULL; - - pre_finish_transfer (dev, transfer); - - grub_dprintf("ohci", "Timeout !\n"); - - /* We should wait for next SOF to be sure that ED is unaccessed - * by OHCI */ - /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); - /* Wait for new SOF */ - while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0); - - /* Possible retired TD with error should be previous TD to ED->td_head */ - cdata->tderr_phys - = grub_ohci_td_phys2virt (o, grub_le_to_cpu32 (cdata->ed_virt->td_head) - & ~0xf)->prev_td_phys; - - tderr_virt = grub_ohci_td_phys2virt (o,cdata-> tderr_phys); - - grub_dprintf ("ohci", "Cancel: tderr_phys=0x%x, tderr_virt=%p\n", - cdata->tderr_phys, tderr_virt); - - if (tderr_virt) - transfer->last_trans = tderr_virt->tr_index; - else - transfer->last_trans = -1; - - finish_transfer (dev, transfer); - - return GRUB_USB_ERR_NONE; -} - -static grub_usb_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_uint64_t endtime; - int i; - - grub_dprintf ("ohci", "begin of portstatus=0x%02x\n", - grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)); - - if (!enable) /* We don't need reset port */ - { - /* Disable the port and wait for it. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, - GRUB_OHCI_CLEAR_PORT_ENABLE); - endtime = grub_get_time_ms () + 1000; - while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port) - & (1 << 1))) - if (grub_get_time_ms () > endtime) - return GRUB_USB_ERR_TIMEOUT; - - grub_dprintf ("ohci", "end of portstatus=0x%02x\n", - grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)); - return GRUB_USB_ERR_NONE; - } - - /* OHCI does one reset signal 10ms long but USB spec. - * requests 50ms for root hub (no need to be continuous). - * So, we do reset 5 times... */ - for (i = 0; i < 5; i++) - { - /* Reset the port - timing of reset is done by OHCI */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, - GRUB_OHCI_SET_PORT_RESET); - - /* Wait for reset completion */ - endtime = grub_get_time_ms () + 1000; - while (! (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port) - & GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE)) - if (grub_get_time_ms () > endtime) - return GRUB_USB_ERR_TIMEOUT; - - /* End the reset signaling - reset the reset status change */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, - GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE); - grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); - } - - /* Enable port */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, - GRUB_OHCI_SET_PORT_ENABLE); - grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); - - /* Wait for signal enabled */ - endtime = grub_get_time_ms () + 1000; - while (! (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port) - & (1 << 1))) - if (grub_get_time_ms () > endtime) - return GRUB_USB_ERR_TIMEOUT; - - /* Reset bit Connect Status Change */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, - GRUB_OHCI_RESET_CONNECT_CHANGE); - - /* "Reset recovery time" (USB spec.) */ - grub_millisleep (10); - - grub_dprintf ("ohci", "end of portstatus=0x%02x\n", - grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)); - - return GRUB_USB_ERR_NONE; -} - -static grub_usb_speed_t -grub_ohci_detect_dev (grub_usb_controller_t dev, int port, int *changed) -{ - 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); - - /* Connect Status Change bit - it detects change of connection */ - if (status & GRUB_OHCI_RESET_CONNECT_CHANGE) - { - *changed = 1; - /* Reset bit Connect Status Change */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, - GRUB_OHCI_RESET_CONNECT_CHANGE); - } - else - *changed = 0; - - 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); - - return portinfo & 0xFF; -} - -static grub_err_t -grub_ohci_fini_hw (int noreturn __attribute__ ((unused))) -{ - struct grub_ohci *o; - - for (o = ohci; o; o = o->next) - { - int i, nports = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) & 0xff; - grub_uint64_t maxtime; - - /* Set skip in all EDs */ - if (o->ed_bulk) - for (i=0; i < GRUB_OHCI_BULK_EDS; i++) - o->ed_bulk[i].target |= grub_cpu_to_le32_compile_time (1 << 14); /* skip */ - if (o->ed_ctrl) - for (i=0; i < GRUB_OHCI_CTRL_EDS; i++) - o->ed_ctrl[i].target |= grub_cpu_to_le32_compile_time (1 << 14); /* skip */ - - /* We should wait for next SOF to be sure that all EDs are - * unaccessed by OHCI. But OHCI can be non-functional, so - * more than 1ms timeout have to be applied. */ - /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); - maxtime = grub_get_time_ms () + 2; - /* Wait for new SOF or timeout */ - while ( ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) - == 0) || (grub_get_time_ms () >= maxtime) ); - - for (i = 0; i < nports; i++) - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + i, - GRUB_OHCI_CLEAR_PORT_ENABLE); - - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); - grub_millisleep (1); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_DONEHEAD, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, 0); - /* Read back of register should ensure it is really written */ - grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - -#if 0 /* Is this necessary before booting? Probably not .(?) - * But it must be done if module is removed ! (Or not ?) - * How to do it ? - Probably grub_ohci_restore_hw should be more - * complicated. (?) - * (If we do it, we need to reallocate EDs and TDs in function - * grub_ohci_restore_hw ! */ - - /* Free allocated EDs and TDs */ - grub_dma_free (o->td_chunk); - grub_dma_free (o->ed_bulk_chunk); - grub_dma_free (o->ed_ctrl_chunk); - grub_dma_free (o->hcca_chunk); -#endif - } - grub_millisleep (10); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_ohci_restore_hw (void) -{ - struct grub_ohci *o; - - for (o = ohci; o; o = o->next) - { - grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr); - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, o->ed_ctrl_addr); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, o->ed_bulk_addr); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); - /* Read back of register should ensure it is really written */ - grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); - - /* Enable the OHCI. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, - (2 << 6) - | GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE - | GRUB_OHCI_REG_CONTROL_BULK_ENABLE ); - } - - return GRUB_ERR_NONE; -} - - -static struct grub_usb_controller_dev usb_controller = -{ - .name = "ohci", - .iterate = grub_ohci_iterate, - .setup_transfer = grub_ohci_setup_transfer, - .check_transfer = grub_ohci_check_transfer, - .cancel_transfer = grub_ohci_cancel_transfer, - .hubports = grub_ohci_hubports, - .portstatus = grub_ohci_portstatus, - .detect_dev = grub_ohci_detect_dev, - /* estimated max. count of TDs for one bulk transfer */ - .max_bulk_tds = GRUB_OHCI_TDS * 3 / 4 -}; - -static struct grub_preboot *fini_hnd; - -GRUB_MOD_INIT(ohci) -{ - COMPILE_TIME_ASSERT (sizeof (struct grub_ohci_td) == 32); - COMPILE_TIME_ASSERT (sizeof (struct grub_ohci_ed) == 16); - - grub_stop_disk_firmware (); - - grub_ohci_inithw (); - grub_usb_controller_dev_register (&usb_controller); - fini_hnd = grub_loader_register_preboot_hook (grub_ohci_fini_hw, - grub_ohci_restore_hw, - GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); -} - -GRUB_MOD_FINI(ohci) -{ - grub_ohci_fini_hw (0); - grub_loader_unregister_preboot_hook (fini_hnd); - grub_usb_controller_dev_unregister (&usb_controller); -} diff --git a/grub-core/bus/usb/serial/common.c b/grub-core/bus/usb/serial/common.c deleted file mode 100644 index e9c995a0a..000000000 --- a/grub-core/bus/usb/serial/common.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 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 . - */ - -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -void -grub_usbserial_fini (struct grub_serial_port *port) -{ - port->usbdev->config[port->configno].interf[port->interfno].detach_hook = 0; - port->usbdev->config[port->configno].interf[port->interfno].attached = 0; -} - -void -grub_usbserial_detach (grub_usb_device_t usbdev, int configno, int interfno) -{ - static struct grub_serial_port *port; - port = usbdev->config[configno].interf[interfno].detach_data; - - grub_serial_unregister (port); -} - -static int usbnum = 0; - -int -grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno, - struct grub_serial_driver *driver, int in_endp, - int out_endp) -{ - struct grub_serial_port *port; - int j; - struct grub_usb_desc_if *interf; - grub_usb_err_t err = GRUB_USB_ERR_NONE; - - interf = usbdev->config[configno].interf[interfno].descif; - - port = grub_zalloc (sizeof (*port)); - if (!port) - { - grub_print_error (); - return 0; - } - - port->name = grub_xasprintf ("usb%d", usbnum++); - if (!port->name) - { - grub_free (port); - grub_print_error (); - return 0; - } - - port->usbdev = usbdev; - port->driver = driver; - for (j = 0; j < interf->endpointcnt; j++) - { - struct grub_usb_desc_endp *endp; - endp = &usbdev->config[0].interf[interfno].descendp[j]; - - if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2 - && (in_endp == GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING - || in_endp == endp->endp_addr)) - { - /* Bulk IN endpoint. */ - port->in_endp = endp; - } - else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2 - && (out_endp == GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING - || out_endp == endp->endp_addr)) - { - /* Bulk OUT endpoint. */ - port->out_endp = endp; - } - } - - /* Configure device */ - if (port->out_endp && port->in_endp) - err = grub_usb_set_configuration (usbdev, configno + 1); - - if (!port->out_endp || !port->in_endp || err) - { - grub_free (port->name); - grub_free (port); - return 0; - } - - port->configno = configno; - port->interfno = interfno; - - grub_serial_config_defaults (port); - grub_serial_register (port); - - port->usbdev->config[port->configno].interf[port->interfno].detach_hook - = grub_usbserial_detach; - port->usbdev->config[port->configno].interf[port->interfno].detach_data - = port; - - return 1; -} - -int -grub_usbserial_fetch (struct grub_serial_port *port, grub_size_t header_size) -{ - grub_usb_err_t err; - grub_size_t actual; - - if (port->bufstart < port->bufend) - return port->buf[port->bufstart++]; - - err = grub_usb_bulk_read_extended (port->usbdev, port->in_endp, - sizeof (port->buf), port->buf, 10, - &actual); - if (err != GRUB_USB_ERR_NONE) - return -1; - - port->bufstart = header_size; - port->bufend = actual; - if (port->bufstart >= port->bufend) - return -1; - - return port->buf[port->bufstart++]; -} diff --git a/grub-core/bus/usb/serial/ftdi.c b/grub-core/bus/usb/serial/ftdi.c deleted file mode 100644 index 3c1388ed2..000000000 --- a/grub-core/bus/usb/serial/ftdi.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -enum - { - GRUB_FTDI_MODEM_CTRL = 0x01, - GRUB_FTDI_FLOW_CTRL = 0x02, - GRUB_FTDI_SPEED_CTRL = 0x03, - GRUB_FTDI_DATA_CTRL = 0x04 - }; - -#define GRUB_FTDI_MODEM_CTRL_DTRRTS 3 -#define GRUB_FTDI_FLOW_CTRL_DTRRTS 3 - -/* Convert speed to divisor. */ -static grub_uint32_t -get_divisor (unsigned int speed) -{ - unsigned int i; - - /* The structure for speed vs. divisor. */ - struct divisor - { - unsigned int speed; - grub_uint32_t div; - }; - - /* The table which lists common configurations. */ - /* Computed with a division formula with 3MHz as base frequency. */ - static struct divisor divisor_tab[] = - { - { 2400, 0x04e2 }, - { 4800, 0x0271 }, - { 9600, 0x4138 }, - { 19200, 0x809c }, - { 38400, 0xc04e }, - { 57600, 0xc034 }, - { 115200, 0x001a } - }; - - /* Set the baud rate. */ - for (i = 0; i < ARRAY_SIZE (divisor_tab); i++) - if (divisor_tab[i].speed == speed) - return divisor_tab[i].div; - return 0; -} - -static void -real_config (struct grub_serial_port *port) -{ - grub_uint32_t divisor; - const grub_uint16_t parities[] = { - [GRUB_SERIAL_PARITY_NONE] = 0x0000, - [GRUB_SERIAL_PARITY_ODD] = 0x0100, - [GRUB_SERIAL_PARITY_EVEN] = 0x0200 - }; - const grub_uint16_t stop_bits[] = { - [GRUB_SERIAL_STOP_BITS_1] = 0x0000, - [GRUB_SERIAL_STOP_BITS_1_5] = 0x0800, - [GRUB_SERIAL_STOP_BITS_2] = 0x1000, - }; - - if (port->configured) - return; - - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, - GRUB_FTDI_MODEM_CTRL, - port->config.rtscts ? GRUB_FTDI_MODEM_CTRL_DTRRTS : 0, - 0, 0, 0); - - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, - GRUB_FTDI_FLOW_CTRL, - port->config.rtscts ? GRUB_FTDI_FLOW_CTRL_DTRRTS : 0, - 0, 0, 0); - - divisor = get_divisor (port->config.speed); - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, - GRUB_FTDI_SPEED_CTRL, - divisor & 0xffff, divisor >> 16, 0, 0); - - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, - GRUB_FTDI_DATA_CTRL, - parities[port->config.parity] - | stop_bits[port->config.stop_bits] - | port->config.word_len, 0, 0, 0); - - port->configured = 1; -} - -/* Fetch a key. */ -static int -ftdi_hw_fetch (struct grub_serial_port *port) -{ - real_config (port); - - return grub_usbserial_fetch (port, 2); -} - -/* Put a character. */ -static void -ftdi_hw_put (struct grub_serial_port *port, const int c) -{ - char cc = c; - - real_config (port); - - grub_usb_bulk_write (port->usbdev, port->out_endp, 1, &cc); -} - -static grub_err_t -ftdi_hw_configure (struct grub_serial_port *port, - struct grub_serial_config *config) -{ - grub_uint16_t divisor; - - divisor = get_divisor (config->speed); - if (divisor == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port speed")); - - if (config->parity != GRUB_SERIAL_PARITY_NONE - && config->parity != GRUB_SERIAL_PARITY_ODD - && config->parity != GRUB_SERIAL_PARITY_EVEN) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port parity")); - - if (config->stop_bits != GRUB_SERIAL_STOP_BITS_1 - && config->stop_bits != GRUB_SERIAL_STOP_BITS_1_5 - && config->stop_bits != GRUB_SERIAL_STOP_BITS_2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port stop bits number")); - - if (config->word_len < 5 || config->word_len > 8) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port word length")); - - port->config = *config; - port->configured = 0; - - return GRUB_ERR_NONE; -} - -static struct grub_serial_driver grub_ftdi_driver = - { - .configure = ftdi_hw_configure, - .fetch = ftdi_hw_fetch, - .put = ftdi_hw_put, - .fini = grub_usbserial_fini - }; - -static const struct -{ - grub_uint16_t vendor, product; -} products[] = - { - {0x0403, 0x6001} /* QEMU virtual USBserial. */ - }; - -static int -grub_ftdi_attach (grub_usb_device_t usbdev, int configno, int interfno) -{ - unsigned j; - - for (j = 0; j < ARRAY_SIZE (products); j++) - if (usbdev->descdev.vendorid == products[j].vendor - && usbdev->descdev.prodid == products[j].product) - break; - if (j == ARRAY_SIZE (products)) - return 0; - - return grub_usbserial_attach (usbdev, configno, interfno, - &grub_ftdi_driver, - GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING, - GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING); -} - -static struct grub_usb_attach_desc attach_hook = -{ - .class = 0xff, - .hook = grub_ftdi_attach -}; - -GRUB_MOD_INIT(usbserial_ftdi) -{ - grub_usb_register_attach_hook_class (&attach_hook); -} - -GRUB_MOD_FINI(usbserial_ftdi) -{ - grub_serial_unregister_driver (&grub_ftdi_driver); - grub_usb_unregister_attach_hook_class (&attach_hook); -} diff --git a/grub-core/bus/usb/serial/pl2303.c b/grub-core/bus/usb/serial/pl2303.c deleted file mode 100644 index 8576c4611..000000000 --- a/grub-core/bus/usb/serial/pl2303.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* Convert speed to divisor. */ -static grub_uint32_t -is_speed_supported (unsigned int speed) -{ - unsigned int i; - unsigned int supported[] = { 2400, 4800, 9600, 19200, 38400, 57600, 115200}; - - for (i = 0; i < ARRAY_SIZE (supported); i++) - if (supported[i] == speed) - return 1; - return 0; -} - -#define GRUB_PL2303_REQUEST_SET_CONFIG 0x20 -#define GRUB_PL2303_STOP_BITS_1 0x0 -#define GRUB_PL2303_STOP_BITS_1_5 0x1 -#define GRUB_PL2303_STOP_BITS_2 0x2 - -#define GRUB_PL2303_PARITY_NONE 0 -#define GRUB_PL2303_PARITY_ODD 1 -#define GRUB_PL2303_PARITY_EVEN 2 - -struct grub_pl2303_config -{ - grub_uint32_t speed; - grub_uint8_t stop_bits; - grub_uint8_t parity; - grub_uint8_t word_len; -} GRUB_PACKED; - -static void -real_config (struct grub_serial_port *port) -{ - struct grub_pl2303_config config_pl2303; - char xx; - - if (port->configured) - return; - - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_IN, - 1, 0x8484, 0, 1, &xx); - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, - 1, 0x0404, 0, 0, 0); - - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_IN, - 1, 0x8484, 0, 1, &xx); - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_IN, - 1, 0x8383, 0, 1, &xx); - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_IN, - 1, 0x8484, 0, 1, &xx); - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, - 1, 0x0404, 1, 0, 0); - - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_IN, - 1, 0x8484, 0, 1, &xx); - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_IN, - 1, 0x8383, 0, 1, &xx); - - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, - 1, 0, 1, 0, 0); - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, - 1, 1, 0, 0, 0); - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, - 1, 2, 0x44, 0, 0); - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, - 1, 8, 0, 0, 0); - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, - 1, 9, 0, 0, 0); - - if (port->config.stop_bits == GRUB_SERIAL_STOP_BITS_2) - config_pl2303.stop_bits = GRUB_PL2303_STOP_BITS_2; - else if (port->config.stop_bits == GRUB_SERIAL_STOP_BITS_1_5) - config_pl2303.stop_bits = GRUB_PL2303_STOP_BITS_1_5; - else - config_pl2303.stop_bits = GRUB_PL2303_STOP_BITS_1; - - switch (port->config.parity) - { - case GRUB_SERIAL_PARITY_NONE: - config_pl2303.parity = GRUB_PL2303_PARITY_NONE; - break; - case GRUB_SERIAL_PARITY_ODD: - config_pl2303.parity = GRUB_PL2303_PARITY_ODD; - break; - case GRUB_SERIAL_PARITY_EVEN: - config_pl2303.parity = GRUB_PL2303_PARITY_EVEN; - break; - } - - config_pl2303.word_len = port->config.word_len; - config_pl2303.speed = port->config.speed; - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT, - GRUB_PL2303_REQUEST_SET_CONFIG, 0, 0, - sizeof (config_pl2303), (char *) &config_pl2303); - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT, - 0x22, 3, 0, 0, 0); - - grub_usb_control_msg (port->usbdev, GRUB_USB_REQTYPE_VENDOR_OUT, - 1, 0, port->config.rtscts ? 0x61 : 0, 0, 0); - port->configured = 1; -} - -/* Fetch a key. */ -static int -pl2303_hw_fetch (struct grub_serial_port *port) -{ - real_config (port); - - return grub_usbserial_fetch (port, 0); -} - -/* Put a character. */ -static void -pl2303_hw_put (struct grub_serial_port *port, const int c) -{ - char cc = c; - - real_config (port); - - grub_usb_bulk_write (port->usbdev, port->out_endp, 1, &cc); -} - -static grub_err_t -pl2303_hw_configure (struct grub_serial_port *port, - struct grub_serial_config *config) -{ - if (!is_speed_supported (config->speed)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port speed")); - - if (config->parity != GRUB_SERIAL_PARITY_NONE - && config->parity != GRUB_SERIAL_PARITY_ODD - && config->parity != GRUB_SERIAL_PARITY_EVEN) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port parity")); - - if (config->stop_bits != GRUB_SERIAL_STOP_BITS_1 - && config->stop_bits != GRUB_SERIAL_STOP_BITS_1_5 - && config->stop_bits != GRUB_SERIAL_STOP_BITS_2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port stop bits number")); - - if (config->word_len < 5 || config->word_len > 8) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port word length")); - - port->config = *config; - port->configured = 0; - - return GRUB_ERR_NONE; -} - -static struct grub_serial_driver grub_pl2303_driver = - { - .configure = pl2303_hw_configure, - .fetch = pl2303_hw_fetch, - .put = pl2303_hw_put, - .fini = grub_usbserial_fini - }; - -static const struct -{ - grub_uint16_t vendor, product; -} products[] = - { - {0x067b, 0x2303} - }; - -static int -grub_pl2303_attach (grub_usb_device_t usbdev, int configno, int interfno) -{ - unsigned j; - - for (j = 0; j < ARRAY_SIZE (products); j++) - if (usbdev->descdev.vendorid == products[j].vendor - && usbdev->descdev.prodid == products[j].product) - break; - if (j == ARRAY_SIZE (products)) - return 0; - - return grub_usbserial_attach (usbdev, configno, interfno, - &grub_pl2303_driver, - GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING, - GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING); -} - -static struct grub_usb_attach_desc attach_hook = -{ - .class = 0xff, - .hook = grub_pl2303_attach -}; - -GRUB_MOD_INIT(usbserial_pl2303) -{ - grub_usb_register_attach_hook_class (&attach_hook); -} - -GRUB_MOD_FINI(usbserial_pl2303) -{ - grub_serial_unregister_driver (&grub_pl2303_driver); - grub_usb_unregister_attach_hook_class (&attach_hook); -} diff --git a/grub-core/bus/usb/serial/usbdebug_late.c b/grub-core/bus/usb/serial/usbdebug_late.c deleted file mode 100644 index e88ba130e..000000000 --- a/grub-core/bus/usb/serial/usbdebug_late.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - - -/* Fetch a key. */ -static int -usbdebug_late_hw_fetch (struct grub_serial_port *port) -{ - return grub_usbserial_fetch (port, 0); -} - -/* Put a character. */ -static void -usbdebug_late_hw_put (struct grub_serial_port *port, const int c) -{ - char cc = c; - - grub_usb_bulk_write (port->usbdev, port->out_endp, 1, &cc); -} - -static grub_err_t -usbdebug_late_hw_configure (struct grub_serial_port *port __attribute__ ((unused)), - struct grub_serial_config *config __attribute__ ((unused))) -{ - return GRUB_ERR_NONE; -} - -static struct grub_serial_driver grub_usbdebug_late_driver = - { - .configure = usbdebug_late_hw_configure, - .fetch = usbdebug_late_hw_fetch, - .put = usbdebug_late_hw_put, - .fini = grub_usbserial_fini - }; - -static int -grub_usbdebug_late_attach (grub_usb_device_t usbdev, int configno, int interfno) -{ - grub_usb_err_t err; - struct grub_usb_desc_debug debugdesc; - - err = grub_usb_get_descriptor (usbdev, GRUB_USB_DESCRIPTOR_DEBUG, configno, - sizeof (debugdesc), (char *) &debugdesc); - if (err) - return 0; - - return grub_usbserial_attach (usbdev, configno, interfno, - &grub_usbdebug_late_driver, - debugdesc.in_endp, debugdesc.out_endp); -} - -static struct grub_usb_attach_desc attach_hook = -{ - .class = 0xff, - .hook = grub_usbdebug_late_attach -}; - -GRUB_MOD_INIT(usbserial_usbdebug_late) -{ - grub_usb_register_attach_hook_class (&attach_hook); -} - -GRUB_MOD_FINI(usbserial_usbdebug_late) -{ - grub_serial_unregister_driver (&grub_usbdebug_late_driver); - grub_usb_unregister_attach_hook_class (&attach_hook); -} diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c deleted file mode 100644 index 0fdea4c1e..000000000 --- a/grub-core/bus/usb/uhci.c +++ /dev/null @@ -1,871 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define GRUB_UHCI_IOMASK (0x7FF << 5) - -#define N_QH 256 -#define N_TD 640 - -typedef enum - { - GRUB_UHCI_REG_USBCMD = 0x00, - GRUB_UHCI_REG_USBINTR = 0x04, - GRUB_UHCI_REG_FLBASEADD = 0x08, - GRUB_UHCI_REG_PORTSC1 = 0x10, - GRUB_UHCI_REG_PORTSC2 = 0x12, - GRUB_UHCI_REG_USBLEGSUP = 0xc0 - } grub_uhci_reg_t; - -enum - { - GRUB_UHCI_DETECT_CHANGED = (1 << 1), - GRUB_UHCI_DETECT_HAVE_DEVICE = 1, - GRUB_UHCI_DETECT_LOW_SPEED = (1 << 8) - }; - -/* R/WC legacy support bits */ -enum - { - GRUB_UHCI_LEGSUP_END_A20GATE = (1 << 15), - GRUB_UHCI_TRAP_BY_64H_WSTAT = (1 << 11), - GRUB_UHCI_TRAP_BY_64H_RSTAT = (1 << 10), - GRUB_UHCI_TRAP_BY_60H_WSTAT = (1 << 9), - GRUB_UHCI_TRAP_BY_60H_RSTAT = (1 << 8) - }; - -/* Reset all legacy support - clear all R/WC bits and all R/W bits */ -#define GRUB_UHCI_RESET_LEGSUP_SMI ( GRUB_UHCI_LEGSUP_END_A20GATE \ - | GRUB_UHCI_TRAP_BY_64H_WSTAT \ - | GRUB_UHCI_TRAP_BY_64H_RSTAT \ - | GRUB_UHCI_TRAP_BY_60H_WSTAT \ - | GRUB_UHCI_TRAP_BY_60H_RSTAT ) - -/* Some UHCI commands */ -#define GRUB_UHCI_CMD_RUN_STOP (1 << 0) -#define GRUB_UHCI_CMD_HCRESET (1 << 1) -#define GRUB_UHCI_CMD_MAXP (1 << 7) - -/* Important bits in structures */ -#define GRUB_UHCI_LINK_TERMINATE 1 -#define GRUB_UHCI_LINK_QUEUE_HEAD 2 - -enum - { - GRUB_UHCI_REG_PORTSC_CONNECT_CHANGED = 0x0002, - GRUB_UHCI_REG_PORTSC_PORT_ENABLED = 0x0004, - GRUB_UHCI_REG_PORTSC_RESUME = 0x0040, - GRUB_UHCI_REG_PORTSC_RESET = 0x0200, - GRUB_UHCI_REG_PORTSC_SUSPEND = 0x1000, - GRUB_UHCI_REG_PORTSC_RW = GRUB_UHCI_REG_PORTSC_PORT_ENABLED - | GRUB_UHCI_REG_PORTSC_RESUME | GRUB_UHCI_REG_PORTSC_RESET - | GRUB_UHCI_REG_PORTSC_SUSPEND, - /* These bits should not be written as 1 unless we really need it */ - GRUB_UHCI_PORTSC_RWC = ((1 << 1) | (1 << 3) | (1 << 11) | (3 << 13)) - }; - -/* 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]; -} GRUB_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]; -} GRUB_PACKED; - -typedef volatile struct grub_uhci_td *grub_uhci_td_t; -typedef volatile struct grub_uhci_qh *grub_uhci_qh_t; - -struct grub_uhci -{ - grub_port_t iobase; - volatile grub_uint32_t *framelist_virt; - grub_uint32_t framelist_phys; - struct grub_pci_dma_chunk *framelist_chunk; - - /* N_QH Queue Heads. */ - struct grub_pci_dma_chunk *qh_chunk; - volatile grub_uhci_qh_t qh_virt; - grub_uint32_t qh_phys; - - /* N_TD Transfer Descriptors. */ - struct grub_pci_dma_chunk *td_chunk; - volatile grub_uhci_td_t td_virt; - grub_uint32_t td_phys; - - /* Free Transfer Descriptors. */ - grub_uhci_td_t tdfree; - - int qh_busy[N_QH]; - - 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); -} - -/* Iterate over all PCI devices. Determine if a device is an UHCI - controller. If this is the case, initialize it. */ -static int -grub_uhci_pci_iter (grub_pci_device_t dev, - grub_pci_id_t pciid __attribute__((unused)), - void *data __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 & GRUB_PCI_ADDR_SPACE_MASK) != GRUB_PCI_ADDR_SPACE_IO) - return 0; - - if ((base & GRUB_UHCI_IOMASK) == 0) - return 0; - - /* Set bus master - needed for coreboot or broken BIOSes */ - addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write_word(addr, GRUB_PCI_COMMAND_IO_ENABLED - | GRUB_PCI_COMMAND_BUS_MASTER - | GRUB_PCI_COMMAND_MEM_ENABLED - | grub_pci_read_word (addr)); - - grub_dprintf ("uhci", "base = %x\n", base); - - /* Allocate memory for the controller and register it. */ - u = grub_zalloc (sizeof (*u)); - if (! u) - return 1; - - u->iobase = (base & GRUB_UHCI_IOMASK) + GRUB_MACHINE_PCI_IO_BASE; - - /* Reset PIRQ and SMI */ - addr = grub_pci_make_address (dev, GRUB_UHCI_REG_USBLEGSUP); - grub_pci_write_word(addr, GRUB_UHCI_RESET_LEGSUP_SMI); - /* Reset the HC */ - grub_uhci_writereg16(u, GRUB_UHCI_REG_USBCMD, GRUB_UHCI_CMD_HCRESET); - grub_millisleep(5); - /* Disable interrupts and commands (just to be safe) */ - grub_uhci_writereg16(u, GRUB_UHCI_REG_USBINTR, 0); - /* Finish HC reset, HC remains disabled */ - grub_uhci_writereg16(u, GRUB_UHCI_REG_USBCMD, 0); - /* Read back to be sure PCI write is done */ - grub_uhci_readreg16(u, GRUB_UHCI_REG_USBCMD); - - /* Reserve a page for the frame list. */ - u->framelist_chunk = grub_memalign_dma32 (4096, 4096); - if (! u->framelist_chunk) - goto fail; - u->framelist_virt = grub_dma_get_virt (u->framelist_chunk); - u->framelist_phys = grub_dma_get_phys (u->framelist_chunk); - - grub_dprintf ("uhci", - "class=0x%02x 0x%02x interface 0x%02x base=0x%x framelist=%p\n", - class, subclass, interf, u->iobase, u->framelist_virt); - - /* The QH pointer of UHCI is only 32 bits, make sure this - code works on on 64 bits architectures. */ - u->qh_chunk = grub_memalign_dma32 (4096, sizeof(struct grub_uhci_qh) * N_QH); - if (! u->qh_chunk) - goto fail; - u->qh_virt = grub_dma_get_virt (u->qh_chunk); - u->qh_phys = grub_dma_get_phys (u->qh_chunk); - - /* The TD pointer of UHCI is only 32 bits, make sure this - code works on on 64 bits architectures. */ - u->td_chunk = grub_memalign_dma32 (4096, sizeof(struct grub_uhci_td) * N_TD); - if (! u->td_chunk) - goto fail; - u->td_virt = grub_dma_get_virt (u->td_chunk); - u->td_phys = grub_dma_get_phys (u->td_chunk); - - grub_dprintf ("uhci", "QH=%p, TD=%p\n", - u->qh_virt, u->td_virt); - - /* Link all Transfer Descriptors in a list of available Transfer - Descriptors. */ - for (i = 0; i < N_TD; i++) - u->td_virt[i].linkptr = u->td_phys + (i + 1) * sizeof(struct grub_uhci_td); - u->td_virt[N_TD - 2].linkptr = 0; - u->tdfree = u->td_virt; - - /* Setup the frame list pointers. Since no isochronous transfers - are and will be supported, they all point to the (same!) queue - head. */ - fp = u->qh_phys & (~15); - /* Mark this as a queue head. */ - fp |= 2; - for (i = 0; i < 1024; i++) - u->framelist_virt[i] = fp; - /* Program the framelist address into the UHCI controller. */ - grub_uhci_writereg32 (u, GRUB_UHCI_REG_FLBASEADD, u->framelist_phys); - - /* Make the Queue Heads point to each other. */ - for (i = 0; i < N_QH; i++) - { - /* Point to the next QH. */ - u->qh_virt[i].linkptr = ((u->qh_phys - + (i + 1) * sizeof(struct grub_uhci_qh)) - & (~15)); - - /* This is a QH. */ - u->qh_virt[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_virt[i].elinkptr = 1; - } - - /* The last Queue Head should terminate. */ - u->qh_virt[N_QH - 1].linkptr = 1; - - /* Enable UHCI again. */ - grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, - GRUB_UHCI_CMD_RUN_STOP | GRUB_UHCI_CMD_MAXP); - - /* 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_dma_free (u->qh_chunk); - grub_dma_free (u->framelist_chunk); - } - grub_free (u); - - return 1; -} - -static void -grub_uhci_inithw (void) -{ - grub_pci_iterate (grub_uhci_pci_iter, NULL); -} - -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_dma_phys2virt (u->tdfree->linkptr, u->td_chunk); - - return ret; -} - -static void -grub_free_td (struct grub_uhci *u, grub_uhci_td_t td) -{ - td->linkptr = grub_dma_virt2phys (u->tdfree, u->td_chunk); - u->tdfree = td; -} - -static void -grub_free_queue (struct grub_uhci *u, grub_uhci_qh_t qh, grub_uhci_td_t td, - grub_usb_transfer_t transfer, grub_size_t *actual) -{ - int i; /* Index of TD in transfer */ - - u->qh_busy[qh - u->qh_virt] = 0; - - *actual = 0; - - /* Free the TDs in this queue and set last_trans. */ - for (i=0; td; i++) - { - grub_uhci_td_t tdprev; - - grub_dprintf ("uhci", "Freeing %p\n", td); - /* Check state of TD and possibly set last_trans */ - if (transfer && (td->linkptr & 1)) - transfer->last_trans = i; - - *actual += (td->ctrl_status + 1) & 0x7ff; - - /* Unlink the queue. */ - tdprev = td; - if (!td->linkptr2) - td = 0; - else - td = grub_dma_phys2virt (td->linkptr2, u->td_chunk); - - /* 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 < N_QH; i++) - { - if (!u->qh_busy[i]) - break; - } - qh = &u->qh_virt[i]; - if (i == N_QH) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, - "no free queue heads available"); - return NULL; - } - - u->qh_busy[qh - u->qh_virt] = 1; - - 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, - grub_uint32_t data, grub_usb_speed_t speed) -{ - 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=%lu data=0x%x td=%p\n", - endp, type, addr, toggle, (unsigned long) 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) | - ((speed == GRUB_USB_SPEED_LOW) ? (1 << 26) : 0); - - /* 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 = data; - - return td; -} - -struct grub_uhci_transfer_controller_data -{ - grub_uhci_qh_t qh; - grub_uhci_td_t td_first; -}; - -static grub_usb_err_t -grub_uhci_setup_transfer (grub_usb_controller_t dev, - grub_usb_transfer_t transfer) -{ - struct grub_uhci *u = (struct grub_uhci *) dev->data; - grub_uhci_td_t td; - grub_uhci_td_t td_prev = NULL; - int i; - struct grub_uhci_transfer_controller_data *cdata; - - cdata = grub_malloc (sizeof (*cdata)); - if (!cdata) - return GRUB_USB_ERR_INTERNAL; - - cdata->td_first = NULL; - - /* Allocate a queue head for the transfer queue. */ - cdata->qh = grub_alloc_qh (u, GRUB_USB_TRANSACTION_TYPE_CONTROL); - if (! cdata->qh) - { - grub_free (cdata); - return GRUB_USB_ERR_INTERNAL; - } - - grub_dprintf ("uhci", "transfer, iobase:%08x\n", u->iobase); - - for (i = 0; i < transfer->transcnt; i++) - { - grub_usb_transaction_t tr = &transfer->transactions[i]; - - td = grub_uhci_transaction (u, transfer->endpoint & 15, tr->pid, - transfer->devaddr, tr->toggle, - tr->size, tr->data, - transfer->dev->speed); - if (! td) - { - grub_size_t actual = 0; - /* Terminate and free. */ - if (td_prev) - { - td_prev->linkptr2 = 0; - td_prev->linkptr = 1; - } - - if (cdata->td_first) - grub_free_queue (u, cdata->qh, cdata->td_first, NULL, &actual); - - grub_free (cdata); - return GRUB_USB_ERR_INTERNAL; - } - - if (! cdata->td_first) - cdata->td_first = td; - else - { - td_prev->linkptr2 = grub_dma_virt2phys (td, u->td_chunk); - td_prev->linkptr = grub_dma_virt2phys (td, u->td_chunk); - 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. */ - cdata->qh->elinkptr = grub_dma_virt2phys (cdata->td_first, u->td_chunk); - - grub_dprintf ("uhci", "initiate transaction\n"); - - transfer->controller_data = cdata; - - return GRUB_USB_ERR_NONE; -} - -static grub_usb_err_t -grub_uhci_check_transfer (grub_usb_controller_t dev, - grub_usb_transfer_t transfer, - grub_size_t *actual) -{ - struct grub_uhci *u = (struct grub_uhci *) dev->data; - grub_uhci_td_t errtd; - struct grub_uhci_transfer_controller_data *cdata = transfer->controller_data; - - *actual = 0; - - if (cdata->qh->elinkptr & ~0x0f) - errtd = grub_dma_phys2virt (cdata->qh->elinkptr & ~0x0f, u->qh_chunk); - else - errtd = 0; - - if (errtd) - { - grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p, %x\n", - errtd->ctrl_status, errtd->buffer & (~15), errtd, - cdata->qh->elinkptr); - } - - /* Check if the transaction completed. */ - if (cdata->qh->elinkptr & 1) - { - grub_dprintf ("uhci", "transaction complete\n"); - - /* Place the QH back in the free list and deallocate the associated - TDs. */ - cdata->qh->elinkptr = 1; - grub_free_queue (u, cdata->qh, cdata->td_first, transfer, actual); - grub_free (cdata); - return GRUB_USB_ERR_NONE; - } - - if (errtd && !(errtd->ctrl_status & (1 << 23))) - { - grub_usb_err_t err = GRUB_USB_ERR_NONE; - - /* 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. */ - else if (errtd->ctrl_status & (1 << 21)) - err = GRUB_USB_ERR_DATA; - - /* Check if a babble error occurred. */ - else if (errtd->ctrl_status & (1 << 20)) - err = GRUB_USB_ERR_BABBLE; - - /* Check if a NAK occurred. */ - else if (errtd->ctrl_status & (1 << 19)) - err = GRUB_USB_ERR_NAK; - - /* Check if a timeout occurred. */ - else if (errtd->ctrl_status & (1 << 18)) - err = GRUB_USB_ERR_TIMEOUT; - - /* Check if a bitstuff error occurred. */ - else if (errtd->ctrl_status & (1 << 17)) - err = GRUB_USB_ERR_BITSTUFF; - - if (err) - { - grub_dprintf ("uhci", "transaction failed\n"); - - /* Place the QH back in the free list and deallocate the associated - TDs. */ - cdata->qh->elinkptr = 1; - grub_free_queue (u, cdata->qh, cdata->td_first, transfer, actual); - grub_free (cdata); - - return err; - } - } - - /* Fall through, no errors occurred, so the QH might be - updated. */ - grub_dprintf ("uhci", "transaction fallthrough\n"); - - return GRUB_USB_ERR_WAIT; -} - -static grub_usb_err_t -grub_uhci_cancel_transfer (grub_usb_controller_t dev, - grub_usb_transfer_t transfer) -{ - struct grub_uhci *u = (struct grub_uhci *) dev->data; - grub_size_t actual; - struct grub_uhci_transfer_controller_data *cdata = transfer->controller_data; - - grub_dprintf ("uhci", "transaction cancel\n"); - - /* Place the QH back in the free list and deallocate the associated - TDs. */ - cdata->qh->elinkptr = 1; - grub_free_queue (u, cdata->qh, cdata->td_first, transfer, &actual); - grub_free (cdata); - - return GRUB_USB_ERR_NONE; -} - -static int -grub_uhci_iterate (grub_usb_controller_iterate_hook_t hook, void *hook_data) -{ - struct grub_uhci *u; - struct grub_usb_controller dev; - - for (u = uhci; u; u = u->next) - { - dev.data = u; - if (hook (&dev, hook_data)) - return 1; - } - - return 0; -} - -static grub_usb_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", "portstatus, iobase:%08x\n", u->iobase); - - 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_USB_ERR_INTERNAL; - - status = grub_uhci_readreg16 (u, reg); - grub_dprintf ("uhci", "detect=0x%02x\n", status); - - if (!enable) /* We don't need reset port */ - { - /* Disable the port. */ - grub_uhci_writereg16 (u, reg, 0 << 2); - grub_dprintf ("uhci", "waiting for the port to be disabled\n"); - endtime = grub_get_time_ms () + 1000; - while ((grub_uhci_readreg16 (u, reg) & (1 << 2))) - if (grub_get_time_ms () > endtime) - return GRUB_USB_ERR_TIMEOUT; - - status = grub_uhci_readreg16 (u, reg); - grub_dprintf ("uhci", ">3detect=0x%02x\n", status); - return GRUB_USB_ERR_NONE; - } - - /* Reset the port. */ - status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_RWC; - grub_uhci_writereg16 (u, reg, status | (1 << 9)); - grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */ - - /* Wait for the reset to complete. XXX: How long exactly? */ - grub_millisleep (50); /* For root hub should be nominaly 50ms */ - status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_RWC; - grub_uhci_writereg16 (u, reg, status & ~(1 << 9)); - grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */ - - /* Note: some debug prints were removed because they affected reset/enable timing. */ - - grub_millisleep (1); /* Probably not needed at all or only few microsecs. */ - - /* Reset bits Connect & Enable Status Change */ - status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_RWC; - grub_uhci_writereg16 (u, reg, status | (1 << 3) | GRUB_UHCI_REG_PORTSC_CONNECT_CHANGED); - grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */ - - /* Enable the port. */ - status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_RWC; - grub_uhci_writereg16 (u, reg, status | (1 << 2)); - grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */ - - endtime = grub_get_time_ms () + 1000; - while (! ((status = grub_uhci_readreg16 (u, reg)) & (1 << 2))) - if (grub_get_time_ms () > endtime) - return GRUB_USB_ERR_TIMEOUT; - - /* Reset recovery time */ - grub_millisleep (10); - - /* Read final port status */ - status = grub_uhci_readreg16 (u, reg); - grub_dprintf ("uhci", ">3detect=0x%02x\n", status); - - - return GRUB_USB_ERR_NONE; -} - -static grub_usb_speed_t -grub_uhci_detect_dev (grub_usb_controller_t dev, int port, int *changed) -{ - struct grub_uhci *u = (struct grub_uhci *) dev->data; - int reg; - unsigned int status; - - grub_dprintf ("uhci", "detect_dev, iobase:%08x\n", u->iobase); - - if (port == 0) - reg = GRUB_UHCI_REG_PORTSC1; - else if (port == 1) - reg = GRUB_UHCI_REG_PORTSC2; - else - return GRUB_USB_SPEED_NONE; - - status = grub_uhci_readreg16 (u, reg); - - grub_dprintf ("uhci", "detect=0x%02x port=%d\n", status, port); - - /* Connect Status Change bit - it detects change of connection */ - if (status & GRUB_UHCI_DETECT_CHANGED) - { - *changed = 1; - /* Reset bit Connect Status Change */ - grub_uhci_writereg16 (u, reg, (status & GRUB_UHCI_REG_PORTSC_RW) - | GRUB_UHCI_REG_PORTSC_CONNECT_CHANGED); - } - else - *changed = 0; - - if (! (status & GRUB_UHCI_DETECT_HAVE_DEVICE)) - return GRUB_USB_SPEED_NONE; - else if (status & GRUB_UHCI_DETECT_LOW_SPEED) - 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; -} - - -static struct grub_usb_controller_dev usb_controller = -{ - .name = "uhci", - .iterate = grub_uhci_iterate, - .setup_transfer = grub_uhci_setup_transfer, - .check_transfer = grub_uhci_check_transfer, - .cancel_transfer = grub_uhci_cancel_transfer, - .hubports = grub_uhci_hubports, - .portstatus = grub_uhci_portstatus, - .detect_dev = grub_uhci_detect_dev, - /* estimated max. count of TDs for one bulk transfer */ - .max_bulk_tds = N_TD * 3 / 4 -}; - -GRUB_MOD_INIT(uhci) -{ - grub_stop_disk_firmware (); - - 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 deleted file mode 100644 index 7bd49d201..000000000 --- a/grub-core/bus/usb/usb.c +++ /dev/null @@ -1,346 +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 . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static struct grub_usb_attach_desc *attach_hooks; - -#if 0 -/* Context for grub_usb_controller_iterate. */ -struct grub_usb_controller_iterate_ctx -{ - grub_usb_controller_iterate_hook_t hook; - void *hook_data; - grub_usb_controller_dev_t p; -}; - -/* Helper for grub_usb_controller_iterate. */ -static int -grub_usb_controller_iterate_iter (grub_usb_controller_t dev, void *data) -{ - struct grub_usb_controller_iterate_ctx *ctx = data; - - dev->dev = ctx->p; - if (ctx->hook (dev, ctx->hook_data)) - return 1; - return 0; -} - -int -grub_usb_controller_iterate (grub_usb_controller_iterate_hook_t hook, - void *hook_data) -{ - struct grub_usb_controller_iterate_ctx ctx = { - .hook = hook, - .hook_data = hook_data - }; - - /* Iterate over all controller drivers. */ - for (ctx.p = grub_usb_list; ctx.p; ctx.p = ctx.p->next) - { - /* Iterate over the busses of the controllers. XXX: Actually, a - hub driver should do this. */ - if (ctx.p->iterate (grub_usb_controller_iterate_iter, &ctx)) - return 1; - } - - return 0; -} -#endif - - -grub_usb_err_t -grub_usb_clear_halt (grub_usb_device_t dev, int endpoint) -{ - if (endpoint >= GRUB_USB_MAX_TOGGLE) - return GRUB_USB_ERR_BADDEVICE; - - 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) -{ - grub_memset (dev->toggle, 0, sizeof (dev->toggle)); - - 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); -} - -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; - - /* First we have to read first 8 bytes only and determine - * max. size of packet */ - dev->descdev.maxsize0 = 0; /* invalidating, for safety only, can be removed if it is sure it is zero here */ - err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE, - 0, 8, (char *) &dev->descdev); - if (err) - return err; - - /* Now we have valid value in dev->descdev.maxsize0, - * so we can read whole device descriptor */ - 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 < GRUB_USB_MAX_CONF; i++) - dev->config[i].descconf = NULL; - - if (descdev->configcnt == 0 || descdev->configcnt > GRUB_USB_MAX_CONF) - { - err = GRUB_USB_ERR_BADDEVICE; - goto fail; - } - - for (i = 0; i < descdev->configcnt; i++) - { - int pos; - int currif; - char *data; - struct grub_usb_desc *desc; - - /* 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 = dev->config[i].descconf->length; - - if (dev->config[i].descconf->numif > GRUB_USB_MAX_IF) - { - err = GRUB_USB_ERR_BADDEVICE; - goto fail; - } - - /* Read all interfaces. */ - for (currif = 0; currif < dev->config[i].descconf->numif; currif++) - { - while (pos < config.totallen) - { - desc = (struct grub_usb_desc *)&data[pos]; - if (desc->type == GRUB_USB_DESCRIPTOR_INTERFACE) - break; - if (!desc->length) - { - err = GRUB_USB_ERR_BADDEVICE; - goto fail; - } - pos += desc->length; - } - - dev->config[i].interf[currif].descif - = (struct grub_usb_desc_if *) &data[pos]; - pos += dev->config[i].interf[currif].descif->length; - - while (pos < config.totallen) - { - desc = (struct grub_usb_desc *)&data[pos]; - if (desc->type == GRUB_USB_DESCRIPTOR_ENDPOINT) - break; - if (!desc->length) - { - err = GRUB_USB_ERR_BADDEVICE; - goto fail; - } - pos += desc->length; - } - - /* 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 < GRUB_USB_MAX_CONF; i++) - grub_free (dev->config[i].descconf); - - return err; -} - -void grub_usb_device_attach (grub_usb_device_t dev) -{ - int i; - - /* XXX: Just check configuration 0 for now. */ - for (i = 0; i < dev->config[0].descconf->numif; i++) - { - struct grub_usb_desc_if *interf; - struct grub_usb_attach_desc *desc; - - interf = dev->config[0].interf[i].descif; - - grub_dprintf ("usb", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n", - i, interf->class, interf->subclass, interf->protocol); - - if (dev->config[0].interf[i].attached) - continue; - - for (desc = attach_hooks; desc; desc = desc->next) - if (interf->class == desc->class) - { - grub_boot_time ("Probing USB device driver class %x", desc->class); - if (desc->hook (dev, 0, i)) - dev->config[0].interf[i].attached = 1; - grub_boot_time ("Probed USB device driver class %x", desc->class); - } - - if (dev->config[0].interf[i].attached) - continue; - - switch (interf->class) - { - case GRUB_USB_CLASS_MASS_STORAGE: - grub_dl_load ("usbms"); - grub_print_error (); - break; - case GRUB_USB_CLASS_HID: - grub_dl_load ("usb_keyboard"); - grub_print_error (); - break; - case 0xff: - /* FIXME: don't load useless modules. */ - grub_dl_load ("usbserial_ftdi"); - grub_print_error (); - grub_dl_load ("usbserial_pl2303"); - grub_print_error (); - grub_dl_load ("usbserial_usbdebug"); - grub_print_error (); - break; - } - } -} - -/* Helper for grub_usb_register_attach_hook_class. */ -static int -grub_usb_register_attach_hook_class_iter (grub_usb_device_t usbdev, void *data) -{ - struct grub_usb_attach_desc *desc = data; - struct grub_usb_desc_device *descdev = &usbdev->descdev; - int i; - - if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0 - || descdev->configcnt == 0) - return 0; - - /* XXX: Just check configuration 0 for now. */ - for (i = 0; i < usbdev->config[0].descconf->numif; i++) - { - struct grub_usb_desc_if *interf; - - interf = usbdev->config[0].interf[i].descif; - - grub_dprintf ("usb", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n", - i, interf->class, interf->subclass, interf->protocol); - - if (usbdev->config[0].interf[i].attached) - continue; - - if (interf->class != desc->class) - continue; - if (desc->hook (usbdev, 0, i)) - usbdev->config[0].interf[i].attached = 1; - } - - return 0; -} - -void -grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc) -{ - desc->next = attach_hooks; - attach_hooks = desc; - - grub_usb_iterate (grub_usb_register_attach_hook_class_iter, desc); -} - -void -grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc) -{ - grub_list_remove (GRUB_AS_LIST (desc)); -} - - -GRUB_MOD_INIT(usb) -{ - grub_term_poll_usb = grub_usb_poll_devices; -} - -GRUB_MOD_FINI(usb) -{ - grub_term_poll_usb = NULL; -} diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c deleted file mode 100644 index f5608e330..000000000 --- a/grub-core/bus/usb/usbhub.c +++ /dev/null @@ -1,756 +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 . - */ - -#include -#include -#include -#include -#include - -#define GRUB_USBHUB_MAX_DEVICES 128 - -/* USB Supports 127 devices, with device 0 as special case. */ -static struct grub_usb_device *grub_usb_devs[GRUB_USBHUB_MAX_DEVICES]; - -static int rescan = 0; -static int npending = 0; - -struct grub_usb_hub -{ - struct grub_usb_hub *next; - grub_usb_controller_t controller; - int nports; - struct grub_usb_device **devices; - struct grub_usb_hub_port *ports; - grub_usb_device_t dev; -}; - -static struct grub_usb_hub *hubs; -static grub_usb_controller_dev_t grub_usb_list; - -/* 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, - int split_hubport, int split_hubaddr) -{ - grub_usb_device_t dev; - int i; - grub_usb_err_t err; - - grub_boot_time ("Attaching USB device"); - - dev = grub_zalloc (sizeof (struct grub_usb_device)); - if (! dev) - return NULL; - - dev->controller = *controller; - dev->speed = speed; - dev->split_hubport = split_hubport; - dev->split_hubaddr = split_hubaddr; - - err = grub_usb_device_initialize (dev); - if (err) - { - grub_free (dev); - return NULL; - } - - /* Assign a new address to the device. */ - for (i = 1; i < GRUB_USBHUB_MAX_DEVICES; i++) - { - if (! grub_usb_devs[i]) - break; - } - if (i == GRUB_USBHUB_MAX_DEVICES) - { - grub_error (GRUB_ERR_IO, "can't assign address to USB device"); - for (i = 0; i < GRUB_USB_MAX_CONF; i++) - grub_free (dev->config[i].descconf); - grub_free (dev); - return NULL; - } - - err = 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); - if (err) - { - for (i = 0; i < GRUB_USB_MAX_CONF; i++) - grub_free (dev->config[i].descconf); - grub_free (dev); - return NULL; - } - - dev->addr = i; - dev->initialized = 1; - grub_usb_devs[i] = dev; - - grub_dprintf ("usb", "Added new usb device: %p, addr=%d\n", - dev, i); - grub_dprintf ("usb", "speed=%d, split_hubport=%d, split_hubaddr=%d\n", - speed, split_hubport, split_hubaddr); - - /* Wait "recovery interval", spec. says 2ms */ - grub_millisleep (2); - - grub_boot_time ("Probing USB device driver"); - - grub_usb_device_attach (dev); - - grub_boot_time ("Attached USB device"); - - return dev; -} - - -static grub_usb_err_t -grub_usb_add_hub (grub_usb_device_t dev) -{ - struct grub_usb_usb_hubdesc hubdesc; - grub_usb_err_t err; - int i; - - err = 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); - if (err) - return err; - grub_dprintf ("usb", "Hub descriptor:\n\t\t len:%d, typ:0x%02x, cnt:%d, char:0x%02x, pwg:%d, curr:%d\n", - hubdesc.length, hubdesc.type, hubdesc.portcnt, - hubdesc.characteristics, hubdesc.pwdgood, - hubdesc.current); - - /* Activate the first configuration. Hubs should have only one conf. */ - grub_dprintf ("usb", "Hub set configuration\n"); - grub_usb_set_configuration (dev, 1); - - dev->nports = hubdesc.portcnt; - dev->children = grub_calloc (hubdesc.portcnt, sizeof (dev->children[0])); - dev->ports = grub_calloc (dev->nports, sizeof (dev->ports[0])); - if (!dev->children || !dev->ports) - { - grub_free (dev->children); - grub_free (dev->ports); - return GRUB_USB_ERR_INTERNAL; - } - - /* Power on all Hub ports. */ - for (i = 1; i <= hubdesc.portcnt; i++) - { - grub_dprintf ("usb", "Power on - port %d\n", i); - /* Power on the port and wait for possible device connect */ - grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_SET_FEATURE, - GRUB_USB_HUB_FEATURE_PORT_POWER, - i, 0, NULL); - } - - /* Rest will be done on next usb poll. */ - for (i = 0; i < dev->config[0].interf[0].descif->endpointcnt; - i++) - { - struct grub_usb_desc_endp *endp = NULL; - endp = &dev->config[0].interf[0].descendp[i]; - - if ((endp->endp_addr & 128) && grub_usb_get_ep_type(endp) - == GRUB_USB_EP_INTERRUPT) - { - grub_size_t len; - dev->hub_endpoint = endp; - len = endp->maxpacket; - if (len > sizeof (dev->statuschange)) - len = sizeof (dev->statuschange); - dev->hub_transfer - = grub_usb_bulk_read_background (dev, endp, len, - (char *) &dev->statuschange); - break; - } - } - - rescan = 1; - - return GRUB_USB_ERR_NONE; -} - -static void -attach_root_port (struct grub_usb_hub *hub, int portno, - grub_usb_speed_t speed) -{ - grub_usb_device_t dev; - grub_usb_err_t err; - - grub_boot_time ("After detect_dev"); - - /* Enable the port. */ - err = hub->controller->dev->portstatus (hub->controller, portno, 1); - if (err) - return; - hub->controller->dev->pending_reset = grub_get_time_ms () + 5000; - npending++; - - grub_millisleep (10); - - grub_boot_time ("Port enabled"); - - /* Enable the port and create a device. */ - /* High speed device needs not transaction translation - and full/low speed device cannot be connected to EHCI root hub - and full/low speed device connected to OHCI/UHCI needs not - transaction translation - e.g. hubport and hubaddr should be - always none (zero) for any device connected to any root hub. */ - dev = grub_usb_hub_add_dev (hub->controller, speed, 0, 0); - hub->controller->dev->pending_reset = 0; - npending--; - if (! dev) - return; - - hub->devices[portno] = dev; - - /* If the device is a Hub, scan it for more devices. */ - if (dev->descdev.class == 0x09) - grub_usb_add_hub (dev); - - grub_boot_time ("Attached root port"); -} - -/* Iterate over all controllers found by the driver. */ -static int -grub_usb_controller_dev_register_iter (grub_usb_controller_t controller, void *data) -{ - grub_usb_controller_dev_t usb = data; - struct grub_usb_hub *hub; - - controller->dev = usb; - - grub_boot_time ("Registering USB root hub"); - - hub = grub_malloc (sizeof (*hub)); - if (!hub) - return GRUB_USB_ERR_INTERNAL; - - hub->next = hubs; - hubs = hub; - hub->controller = grub_malloc (sizeof (*controller)); - if (!hub->controller) - { - grub_free (hub); - return GRUB_USB_ERR_INTERNAL; - } - - grub_memcpy (hub->controller, controller, sizeof (*controller)); - hub->dev = 0; - - /* Query the number of ports the root Hub has. */ - hub->nports = controller->dev->hubports (controller); - hub->devices = grub_calloc (hub->nports, sizeof (hub->devices[0])); - hub->ports = grub_calloc (hub->nports, sizeof (hub->ports[0])); - if (!hub->devices || !hub->ports) - { - grub_free (hub->devices); - grub_free (hub->ports); - grub_free (hub->controller); - grub_free (hub); - grub_print_error (); - return 0; - } - - return 0; -} - -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; - } -} - -void -grub_usb_controller_dev_register (grub_usb_controller_dev_t usb) -{ - int portno; - int continue_waiting = 0; - struct grub_usb_hub *hub; - - usb->next = grub_usb_list; - grub_usb_list = usb; - - if (usb->iterate) - usb->iterate (grub_usb_controller_dev_register_iter, usb); - - grub_boot_time ("waiting for stable power on USB root\n"); - - while (1) - { - for (hub = hubs; hub; hub = hub->next) - if (hub->controller->dev == usb) - { - /* Wait for completion of insertion and stable power (USB spec.) - * Should be at least 100ms, some devices requires more... - * There is also another thing - some devices have worse contacts - * and connected signal is unstable for some time - we should handle - * it - but prevent deadlock in case when device is too faulty... */ - for (portno = 0; portno < hub->nports; portno++) - { - grub_usb_speed_t speed; - int changed = 0; - - speed = hub->controller->dev->detect_dev (hub->controller, portno, - &changed); - - if (hub->ports[portno].state == PORT_STATE_NORMAL - && speed != GRUB_USB_SPEED_NONE) - { - hub->ports[portno].soft_limit_time = grub_get_time_ms () + 250; - hub->ports[portno].hard_limit_time = hub->ports[portno].soft_limit_time + 1750; - hub->ports[portno].state = PORT_STATE_WAITING_FOR_STABLE_POWER; - grub_boot_time ("Scheduling stable power wait for port %p:%d", - usb, portno); - continue_waiting++; - continue; - } - - if (hub->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER - && speed == GRUB_USB_SPEED_NONE) - { - hub->ports[portno].soft_limit_time = grub_get_time_ms () + 250; - continue; - } - if (hub->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER - && grub_get_time_ms () > hub->ports[portno].soft_limit_time) - { - hub->ports[portno].state = PORT_STATE_STABLE_POWER; - grub_boot_time ("Got stable power wait for port %p:%d", - usb, portno); - continue_waiting--; - continue; - } - if (hub->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER - && grub_get_time_ms () > hub->ports[portno].hard_limit_time) - { - hub->ports[portno].state = PORT_STATE_FAILED_DEVICE; - continue_waiting--; - continue; - } - } - } - if (!continue_waiting) - break; - grub_millisleep (1); - } - - grub_boot_time ("After the stable power wait on USB root"); - - for (hub = hubs; hub; hub = hub->next) - if (hub->controller->dev == usb) - for (portno = 0; portno < hub->nports; portno++) - if (hub->ports[portno].state == PORT_STATE_STABLE_POWER) - { - grub_usb_speed_t speed; - int changed = 0; - hub->ports[portno].state = PORT_STATE_NORMAL; - speed = hub->controller->dev->detect_dev (hub->controller, portno, &changed); - attach_root_port (hub, portno, speed); - } - - grub_boot_time ("USB root hub registered"); -} - -static void detach_device (grub_usb_device_t dev); - -static void -detach_device (grub_usb_device_t dev) -{ - unsigned i; - int k; - if (!dev) - return; - if (dev->descdev.class == GRUB_USB_CLASS_HUB) - { - if (dev->hub_transfer) - grub_usb_cancel_transfer (dev->hub_transfer); - - for (i = 0; i < dev->nports; i++) - detach_device (dev->children[i]); - grub_free (dev->children); - } - for (i = 0; i < ARRAY_SIZE (dev->config); i++) - if (dev->config[i].descconf) - for (k = 0; k < dev->config[i].descconf->numif; k++) - { - struct grub_usb_interface *inter = &dev->config[i].interf[k]; - if (inter && inter->detach_hook) - inter->detach_hook (dev, i, k); - } - grub_usb_devs[dev->addr] = 0; -} - -static int -wait_power_nonroot_hub (grub_usb_device_t dev) -{ - grub_usb_err_t err; - int continue_waiting = 0; - unsigned i; - - for (i = 1; i <= dev->nports; i++) - if (dev->ports[i - 1].state == PORT_STATE_WAITING_FOR_STABLE_POWER) - { - grub_uint64_t tm; - grub_uint32_t current_status = 0; - - /* 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_GET_STATUS, - 0, i, - sizeof (current_status), - (char *) ¤t_status); - if (err) - { - dev->ports[i - 1].state = PORT_STATE_FAILED_DEVICE; - continue; - } - tm = grub_get_time_ms (); - if (!(current_status & GRUB_USB_HUB_STATUS_PORT_CONNECTED)) - dev->ports[i - 1].soft_limit_time = tm + 250; - if (tm >= dev->ports[i - 1].soft_limit_time) - { - if (dev->controller.dev->pending_reset) - continue; - /* Now do reset of port. */ - grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_SET_FEATURE, - GRUB_USB_HUB_FEATURE_PORT_RESET, - i, 0, 0); - dev->ports[i - 1].state = PORT_STATE_NORMAL; - grub_boot_time ("Resetting port %p:%d", dev, i - 1); - - rescan = 1; - /* We cannot reset more than one device at the same time ! - * Resetting more devices together results in very bad - * situation: more than one device has default address 0 - * at the same time !!! - * Additionaly, we cannot perform another reset - * anywhere on the same OHCI controller until - * we will finish addressing of reseted device ! */ - dev->controller.dev->pending_reset = grub_get_time_ms () + 5000; - npending++; - continue; - } - if (tm >= dev->ports[i - 1].hard_limit_time) - { - dev->ports[i - 1].state = PORT_STATE_FAILED_DEVICE; - continue; - } - continue_waiting = 1; - } - return continue_waiting && dev->controller.dev->pending_reset == 0; -} - -static void -poll_nonroot_hub (grub_usb_device_t dev) -{ - grub_usb_err_t err; - unsigned i; - grub_uint32_t changed; - grub_size_t actual, len; - - if (!dev->hub_transfer) - return; - - err = grub_usb_check_transfer (dev->hub_transfer, &actual); - - if (err == GRUB_USB_ERR_WAIT) - return; - - changed = dev->statuschange; - - len = dev->hub_endpoint->maxpacket; - if (len > sizeof (dev->statuschange)) - len = sizeof (dev->statuschange); - dev->hub_transfer - = grub_usb_bulk_read_background (dev, dev->hub_endpoint, len, - (char *) &dev->statuschange); - - if (err || actual == 0 || changed == 0) - return; - - /* Iterate over the Hub ports. */ - for (i = 1; i <= dev->nports; i++) - { - grub_uint32_t status; - - if (!(changed & (1 << i)) - || dev->ports[i - 1].state == PORT_STATE_WAITING_FOR_STABLE_POWER) - continue; - - /* 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_GET_STATUS, - 0, i, sizeof (status), (char *) &status); - - grub_dprintf ("usb", "dev = %p, i = %d, status = %08x\n", - dev, i, status); - - if (err) - continue; - - /* FIXME: properly handle these conditions. */ - if (status & GRUB_USB_HUB_STATUS_C_PORT_ENABLED) - grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_CLEAR_FEATURE, - GRUB_USB_HUB_FEATURE_C_PORT_ENABLED, i, 0, 0); - - if (status & GRUB_USB_HUB_STATUS_C_PORT_SUSPEND) - grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_CLEAR_FEATURE, - GRUB_USB_HUB_FEATURE_C_PORT_SUSPEND, i, 0, 0); - - if (status & GRUB_USB_HUB_STATUS_C_PORT_OVERCURRENT) - grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_CLEAR_FEATURE, - GRUB_USB_HUB_FEATURE_C_PORT_OVERCURRENT, i, 0, 0); - - if (!dev->controller.dev->pending_reset && - (status & GRUB_USB_HUB_STATUS_C_PORT_CONNECTED)) - { - grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_CLEAR_FEATURE, - GRUB_USB_HUB_FEATURE_C_PORT_CONNECTED, i, 0, 0); - - detach_device (dev->children[i - 1]); - dev->children[i - 1] = NULL; - - /* Connected and status of connection changed ? */ - if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED) - { - grub_boot_time ("Before the stable power wait portno=%d", i); - /* A device is actually connected to this port. */ - /* Wait for completion of insertion and stable power (USB spec.) - * Should be at least 100ms, some devices requires more... - * There is also another thing - some devices have worse contacts - * and connected signal is unstable for some time - we should handle - * it - but prevent deadlock in case when device is too faulty... */ - dev->ports[i - 1].soft_limit_time = grub_get_time_ms () + 250; - dev->ports[i - 1].hard_limit_time = dev->ports[i - 1].soft_limit_time + 1750; - dev->ports[i - 1].state = PORT_STATE_WAITING_FOR_STABLE_POWER; - grub_boot_time ("Scheduling stable power wait for port %p:%d", - dev, i - 1); - continue; - } - } - - if (status & GRUB_USB_HUB_STATUS_C_PORT_RESET) - { - grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT - | GRUB_USB_REQTYPE_CLASS - | GRUB_USB_REQTYPE_TARGET_OTHER), - GRUB_USB_REQ_CLEAR_FEATURE, - GRUB_USB_HUB_FEATURE_C_PORT_RESET, i, 0, 0); - - grub_boot_time ("Port %d reset", i); - - if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED) - { - grub_usb_speed_t speed; - grub_usb_device_t next_dev; - int split_hubport = 0; - int split_hubaddr = 0; - - /* Determine the device speed. */ - if (status & GRUB_USB_HUB_STATUS_PORT_LOWSPEED) - speed = GRUB_USB_SPEED_LOW; - else - { - if (status & GRUB_USB_HUB_STATUS_PORT_HIGHSPEED) - speed = GRUB_USB_SPEED_HIGH; - else - speed = GRUB_USB_SPEED_FULL; - } - - /* Wait a recovery time after reset, spec. says 10ms */ - grub_millisleep (10); - - /* Find correct values for SPLIT hubport and hubaddr */ - if (speed == GRUB_USB_SPEED_HIGH) - { - /* HIGH speed device needs not transaction translation */ - split_hubport = 0; - split_hubaddr = 0; - } - else - /* FULL/LOW device needs hub port and hub address - for transaction translation (if connected to EHCI) */ - if (dev->speed == GRUB_USB_SPEED_HIGH) - { - /* This port is the first FULL/LOW speed port - in the chain from root hub. Attached device - should use its port number and hub address */ - split_hubport = i; - split_hubaddr = dev->addr; - } - else - { - /* This port is NOT the first FULL/LOW speed port - in the chain from root hub. Attached device - should use values inherited from some parent - HIGH speed hub - if any. */ - split_hubport = dev->split_hubport; - split_hubaddr = dev->split_hubaddr; - } - - /* Add the device and assign a device address to it. */ - next_dev = grub_usb_hub_add_dev (&dev->controller, speed, - split_hubport, split_hubaddr); - if (dev->controller.dev->pending_reset) - { - dev->controller.dev->pending_reset = 0; - npending--; - } - if (! next_dev) - continue; - - dev->children[i - 1] = next_dev; - - /* If the device is a Hub, scan it for more devices. */ - if (next_dev->descdev.class == 0x09) - grub_usb_add_hub (next_dev); - } - } - } -} - -void -grub_usb_poll_devices (int wait_for_completion) -{ - struct grub_usb_hub *hub; - int i; - - for (hub = hubs; hub; hub = hub->next) - { - /* Do we have to recheck number of ports? */ - /* No, it should be never changed, it should be constant. */ - for (i = 0; i < hub->nports; i++) - { - grub_usb_speed_t speed = GRUB_USB_SPEED_NONE; - int changed = 0; - - if (hub->controller->dev->pending_reset) - { - /* Check for possible timeout */ - if (grub_get_time_ms () > hub->controller->dev->pending_reset) - { - /* Something went wrong, reset device was not - * addressed properly, timeout happened */ - hub->controller->dev->pending_reset = 0; - npending--; - } - } - if (!hub->controller->dev->pending_reset) - speed = hub->controller->dev->detect_dev (hub->controller, - i, &changed); - - if (changed) - { - detach_device (hub->devices[i]); - hub->devices[i] = NULL; - if (speed != GRUB_USB_SPEED_NONE) - attach_root_port (hub, i, speed); - } - } - } - - while (1) - { - rescan = 0; - - /* We should check changes of non-root hubs too. */ - for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++) - { - grub_usb_device_t dev = grub_usb_devs[i]; - - if (dev && dev->descdev.class == 0x09) - poll_nonroot_hub (dev); - } - - while (1) - { - int continue_waiting = 0; - for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++) - { - grub_usb_device_t dev = grub_usb_devs[i]; - - if (dev && dev->descdev.class == 0x09) - continue_waiting = continue_waiting || wait_power_nonroot_hub (dev); - } - if (!continue_waiting) - break; - grub_millisleep (1); - } - - if (!(rescan || (npending && wait_for_completion))) - break; - grub_millisleep (25); - } -} - -int -grub_usb_iterate (grub_usb_iterate_hook_t hook, void *hook_data) -{ - int i; - - for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++) - { - if (grub_usb_devs[i]) - { - if (hook (grub_usb_devs[i], hook_data)) - return 1; - } - } - - return 0; -} diff --git a/grub-core/bus/usb/usbtrans.c b/grub-core/bus/usb/usbtrans.c deleted file mode 100644 index c5680b33a..000000000 --- a/grub-core/bus/usb/usbtrans.c +++ /dev/null @@ -1,462 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -static inline unsigned int -grub_usb_bulk_maxpacket (grub_usb_device_t dev, - struct grub_usb_desc_endp *endpoint) -{ - /* Use the maximum packet size given in the endpoint descriptor. */ - if (dev->initialized && endpoint && (unsigned int) endpoint->maxpacket) - return endpoint->maxpacket; - - return 64; -} - - -static grub_usb_err_t -grub_usb_execute_and_wait_transfer (grub_usb_device_t dev, - grub_usb_transfer_t transfer, - int timeout, grub_size_t *actual) -{ - grub_usb_err_t err; - grub_uint64_t endtime; - - err = dev->controller.dev->setup_transfer (&dev->controller, transfer); - if (err) - return err; - /* endtime moved behind setup transfer to prevent false timeouts - * while debugging... */ - endtime = grub_get_time_ms () + timeout; - while (1) - { - err = dev->controller.dev->check_transfer (&dev->controller, transfer, - actual); - if (!err) - return GRUB_USB_ERR_NONE; - if (err != GRUB_USB_ERR_WAIT) - return err; - if (grub_get_time_ms () > endtime) - { - err = dev->controller.dev->cancel_transfer (&dev->controller, - transfer); - if (err) - return err; - return GRUB_USB_ERR_TIMEOUT; - } - grub_cpu_idle (); - } -} - -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 size0, char *data_in) -{ - int i; - grub_usb_transfer_t transfer; - int datablocks; - volatile struct grub_usb_packet_setup *setupdata; - grub_uint32_t setupdata_addr; - grub_usb_err_t err; - unsigned int max; - struct grub_pci_dma_chunk *data_chunk, *setupdata_chunk; - volatile char *data; - grub_uint32_t data_addr; - grub_size_t size = size0; - grub_size_t actual; - - /* FIXME: avoid allocation any kind of buffer in a first place. */ - data_chunk = grub_memalign_dma32 (128, size ? : 16); - if (!data_chunk) - return GRUB_USB_ERR_INTERNAL; - data = grub_dma_get_virt (data_chunk); - data_addr = grub_dma_get_phys (data_chunk); - grub_memcpy ((char *) data, data_in, size); - - grub_arch_sync_dma_caches (data, size); - - grub_dprintf ("usb", - "control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%lu\n", - reqtype, request, value, index, (unsigned long)size); - - /* Create a transfer. */ - transfer = grub_malloc (sizeof (*transfer)); - if (! transfer) - { - grub_dma_free (data_chunk); - return GRUB_USB_ERR_INTERNAL; - } - - setupdata_chunk = grub_memalign_dma32 (32, sizeof (*setupdata)); - if (! setupdata_chunk) - { - grub_free (transfer); - grub_dma_free (data_chunk); - return GRUB_USB_ERR_INTERNAL; - } - - setupdata = grub_dma_get_virt (setupdata_chunk); - setupdata_addr = grub_dma_get_phys (setupdata_chunk); - - /* Determine the maximum packet size. */ - if (dev->descdev.maxsize0) - max = dev->descdev.maxsize0; - else - max = 64; - - grub_dprintf ("usb", "control: transfer = %p, dev = %p\n", transfer, dev); - - 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); - grub_dma_free (setupdata_chunk); - grub_dma_free (data_chunk); - return GRUB_USB_ERR_INTERNAL; - } - - /* Build a Setup packet. XXX: Endianness. */ - setupdata->reqtype = reqtype; - setupdata->request = request; - setupdata->value = value; - setupdata->index = index; - setupdata->length = size; - grub_arch_sync_dma_caches (setupdata, sizeof (*setupdata)); - - transfer->transactions[0].size = sizeof (*setupdata); - transfer->transactions[0].pid = GRUB_USB_TRANSFER_TYPE_SETUP; - transfer->transactions[0].data = setupdata_addr; - 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_addr + i * max; - tr->preceding = i * max; - size -= max; - } - - /* End with an empty OUT transaction. */ - transfer->transactions[datablocks + 1].size = 0; - transfer->transactions[datablocks + 1].data = 0; - if ((reqtype & 128) && datablocks) - 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 = grub_usb_execute_and_wait_transfer (dev, transfer, 1000, &actual); - - grub_dprintf ("usb", "control: err=%d\n", err); - - grub_free (transfer->transactions); - - grub_free (transfer); - grub_dma_free (setupdata_chunk); - - grub_arch_sync_dma_caches (data, size0); - grub_memcpy (data_in, (char *) data, size0); - - grub_dma_free (data_chunk); - - return err; -} - -static grub_usb_transfer_t -grub_usb_bulk_setup_readwrite (grub_usb_device_t dev, - struct grub_usb_desc_endp *endpoint, - grub_size_t size0, char *data_in, - grub_transfer_type_t type) -{ - int i; - grub_usb_transfer_t transfer; - int datablocks; - unsigned int max; - volatile char *data; - grub_uint32_t data_addr; - struct grub_pci_dma_chunk *data_chunk; - grub_size_t size = size0; - int toggle = dev->toggle[endpoint->endp_addr]; - - grub_dprintf ("usb", "bulk: size=0x%02lx type=%d\n", (unsigned long) size, - type); - - /* FIXME: avoid allocation any kind of buffer in a first place. */ - data_chunk = grub_memalign_dma32 (128, size); - if (!data_chunk) - return NULL; - data = grub_dma_get_virt (data_chunk); - data_addr = grub_dma_get_phys (data_chunk); - if (type == GRUB_USB_TRANSFER_TYPE_OUT) - { - grub_memcpy ((char *) data, data_in, size); - grub_arch_sync_dma_caches (data, size); - } - - /* Create a transfer. */ - transfer = grub_malloc (sizeof (struct grub_usb_transfer)); - if (! transfer) - { - grub_dma_free (data_chunk); - return NULL; - } - - max = grub_usb_bulk_maxpacket (dev, endpoint); - - datablocks = ((size + max - 1) / max); - transfer->transcnt = datablocks; - transfer->size = size - 1; - transfer->endpoint = endpoint->endp_addr; - transfer->devaddr = dev->addr; - transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK; - transfer->dir = type; - transfer->max = max; - transfer->dev = dev; - transfer->last_trans = -1; /* Reset index of last processed transaction (TD) */ - transfer->data_chunk = data_chunk; - transfer->data = data_in; - - /* Allocate an array of transfer data structures. */ - transfer->transactions = grub_malloc (transfer->transcnt - * sizeof (struct grub_usb_transfer)); - if (! transfer->transactions) - { - grub_free (transfer); - grub_dma_free (data_chunk); - return NULL; - } - - /* 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_addr + i * max; - tr->preceding = i * max; - size -= tr->size; - } - return transfer; -} - -static void -grub_usb_bulk_finish_readwrite (grub_usb_transfer_t transfer) -{ - grub_usb_device_t dev = transfer->dev; - int toggle = dev->toggle[transfer->endpoint]; - - /* We must remember proper toggle value even if some transactions - * were not processed - correct value should be inversion of last - * processed transaction (TD). */ - if (transfer->last_trans >= 0) - toggle = transfer->transactions[transfer->last_trans].toggle ? 0 : 1; - else - toggle = dev->toggle[transfer->endpoint]; /* Nothing done, take original */ - grub_dprintf ("usb", "bulk: toggle=%d\n", toggle); - dev->toggle[transfer->endpoint] = toggle; - - if (transfer->dir == GRUB_USB_TRANSFER_TYPE_IN) - { - grub_arch_sync_dma_caches (grub_dma_get_virt (transfer->data_chunk), - transfer->size + 1); - grub_memcpy (transfer->data, (void *) - grub_dma_get_virt (transfer->data_chunk), - transfer->size + 1); - } - - grub_free (transfer->transactions); - grub_dma_free (transfer->data_chunk); - grub_free (transfer); -} - -static grub_usb_err_t -grub_usb_bulk_readwrite (grub_usb_device_t dev, - struct grub_usb_desc_endp *endpoint, - grub_size_t size0, char *data_in, - grub_transfer_type_t type, int timeout, - grub_size_t *actual) -{ - grub_usb_err_t err; - grub_usb_transfer_t transfer; - - transfer = grub_usb_bulk_setup_readwrite (dev, endpoint, size0, - data_in, type); - if (!transfer) - return GRUB_USB_ERR_INTERNAL; - err = grub_usb_execute_and_wait_transfer (dev, transfer, timeout, actual); - - grub_usb_bulk_finish_readwrite (transfer); - - return err; -} - -static grub_usb_err_t -grub_usb_bulk_readwrite_packetize (grub_usb_device_t dev, - struct grub_usb_desc_endp *endpoint, - grub_transfer_type_t type, - grub_size_t size, char *data) -{ - grub_size_t actual, transferred; - grub_usb_err_t err = GRUB_USB_ERR_NONE; - grub_size_t current_size, position; - grub_size_t max_bulk_transfer_len = MAX_USB_TRANSFER_LEN; - grub_size_t max; - - if (dev->controller.dev->max_bulk_tds) - { - max = grub_usb_bulk_maxpacket (dev, endpoint); - - /* Calculate max. possible length of bulk transfer */ - max_bulk_transfer_len = dev->controller.dev->max_bulk_tds * max; - } - - for (position = 0, transferred = 0; - position < size; position += max_bulk_transfer_len) - { - current_size = size - position; - if (current_size >= max_bulk_transfer_len) - current_size = max_bulk_transfer_len; - err = grub_usb_bulk_readwrite (dev, endpoint, current_size, - &data[position], type, 1000, &actual); - transferred += actual; - if (err || (current_size != actual)) break; - } - - if (!err && transferred != size) - err = GRUB_USB_ERR_DATA; - return err; -} - -grub_usb_err_t -grub_usb_bulk_write (grub_usb_device_t dev, - struct grub_usb_desc_endp *endpoint, - grub_size_t size, char *data) -{ - return grub_usb_bulk_readwrite_packetize (dev, endpoint, - GRUB_USB_TRANSFER_TYPE_OUT, - size, data); -} - -grub_usb_err_t -grub_usb_bulk_read (grub_usb_device_t dev, - struct grub_usb_desc_endp *endpoint, - grub_size_t size, char *data) -{ - return grub_usb_bulk_readwrite_packetize (dev, endpoint, - GRUB_USB_TRANSFER_TYPE_IN, - size, data); -} - -grub_usb_err_t -grub_usb_check_transfer (grub_usb_transfer_t transfer, grub_size_t *actual) -{ - grub_usb_err_t err; - grub_usb_device_t dev = transfer->dev; - - err = dev->controller.dev->check_transfer (&dev->controller, transfer, - actual); - if (err == GRUB_USB_ERR_WAIT) - return err; - - grub_usb_bulk_finish_readwrite (transfer); - - return err; -} - -grub_usb_transfer_t -grub_usb_bulk_read_background (grub_usb_device_t dev, - struct grub_usb_desc_endp *endpoint, - grub_size_t size, void *data) -{ - grub_usb_err_t err; - grub_usb_transfer_t transfer; - - transfer = grub_usb_bulk_setup_readwrite (dev, endpoint, size, - data, GRUB_USB_TRANSFER_TYPE_IN); - if (!transfer) - return NULL; - - err = dev->controller.dev->setup_transfer (&dev->controller, transfer); - if (err) - return NULL; - - return transfer; -} - -void -grub_usb_cancel_transfer (grub_usb_transfer_t transfer) -{ - grub_usb_device_t dev = transfer->dev; - dev->controller.dev->cancel_transfer (&dev->controller, transfer); - grub_errno = GRUB_ERR_NONE; -} - -grub_usb_err_t -grub_usb_bulk_read_extended (grub_usb_device_t dev, - struct grub_usb_desc_endp *endpoint, - grub_size_t size, char *data, - int timeout, grub_size_t *actual) -{ - return grub_usb_bulk_readwrite (dev, endpoint, size, data, - GRUB_USB_TRANSFER_TYPE_IN, timeout, actual); -} diff --git a/grub-core/commands/acpihalt.c b/grub-core/commands/acpihalt.c deleted file mode 100644 index 9a5e22155..000000000 --- a/grub-core/commands/acpihalt.c +++ /dev/null @@ -1,454 +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 . - */ - -#ifdef GRUB_DSDT_TEST -#include -#include -#include -#include -#include -#include - -#define grub_dprintf(cond, args...) printf ( args ) -#define grub_printf printf -#define grub_util_fopen fopen -#define grub_memcmp memcmp -typedef uint64_t grub_uint64_t; -typedef uint32_t grub_uint32_t; -typedef uint16_t grub_uint16_t; -typedef uint8_t grub_uint8_t; - -#endif - -#include -#ifndef GRUB_DSDT_TEST -#include -#else -#define _(x) x -#define N_(x) x -#endif - -#ifndef GRUB_DSDT_TEST -#include -#include -#include -#include -#endif - -static inline grub_uint32_t -decode_length (const grub_uint8_t *ptr, int *numlen) -{ - int num_bytes, i; - grub_uint32_t ret; - if (*ptr < 64) - { - if (numlen) - *numlen = 1; - return *ptr; - } - num_bytes = *ptr >> 6; - if (numlen) - *numlen = num_bytes + 1; - ret = *ptr & 0xf; - ptr++; - for (i = 0; i < num_bytes; i++) - { - ret |= *ptr << (8 * i + 4); - ptr++; - } - return ret; -} - -static inline grub_uint32_t -skip_name_string (const grub_uint8_t *ptr, const grub_uint8_t *end) -{ - const grub_uint8_t *ptr0 = ptr; - - while (ptr < end && (*ptr == '^' || *ptr == '\\')) - ptr++; - switch (*ptr) - { - case '.': - ptr++; - ptr += 8; - break; - case '/': - ptr++; - ptr += 1 + (*ptr) * 4; - break; - case 0: - ptr++; - break; - default: - ptr += 4; - break; - } - return ptr - ptr0; -} - -static inline grub_uint32_t -skip_data_ref_object (const grub_uint8_t *ptr, const grub_uint8_t *end) -{ - grub_dprintf ("acpi", "data type = 0x%x\n", *ptr); - switch (*ptr) - { - case GRUB_ACPI_OPCODE_PACKAGE: - case GRUB_ACPI_OPCODE_BUFFER: - return 1 + decode_length (ptr + 1, 0); - case GRUB_ACPI_OPCODE_ZERO: - case GRUB_ACPI_OPCODE_ONES: - case GRUB_ACPI_OPCODE_ONE: - return 1; - case GRUB_ACPI_OPCODE_BYTE_CONST: - return 2; - case GRUB_ACPI_OPCODE_WORD_CONST: - return 3; - case GRUB_ACPI_OPCODE_DWORD_CONST: - return 5; - case GRUB_ACPI_OPCODE_STRING_CONST: - { - const grub_uint8_t *ptr0 = ptr; - for (ptr++; ptr < end && *ptr; ptr++); - if (ptr == end) - return 0; - return ptr - ptr0 + 1; - } - default: - if (*ptr == '^' || *ptr == '\\' || *ptr == '_' - || (*ptr >= 'A' && *ptr <= 'Z')) - return skip_name_string (ptr, end); - grub_printf ("Unknown opcode 0x%x\n", *ptr); - return 0; - } -} - -static inline grub_uint32_t -skip_term (const grub_uint8_t *ptr, const grub_uint8_t *end) -{ - grub_uint32_t add; - const grub_uint8_t *ptr0 = ptr; - - switch(*ptr) - { - case GRUB_ACPI_OPCODE_ADD: - case GRUB_ACPI_OPCODE_AND: - case GRUB_ACPI_OPCODE_CONCAT: - case GRUB_ACPI_OPCODE_CONCATRES: - case GRUB_ACPI_OPCODE_DIVIDE: - case GRUB_ACPI_OPCODE_INDEX: - case GRUB_ACPI_OPCODE_LSHIFT: - case GRUB_ACPI_OPCODE_MOD: - case GRUB_ACPI_OPCODE_MULTIPLY: - case GRUB_ACPI_OPCODE_NAND: - case GRUB_ACPI_OPCODE_NOR: - case GRUB_ACPI_OPCODE_OR: - case GRUB_ACPI_OPCODE_RSHIFT: - case GRUB_ACPI_OPCODE_SUBTRACT: - case GRUB_ACPI_OPCODE_TOSTRING: - case GRUB_ACPI_OPCODE_XOR: - /* - * Parameters for these opcodes: TermArg, TermArg Target, see ACPI - * spec r5.0, page 828f. - */ - ptr++; - ptr += add = skip_term (ptr, end); - if (!add) - return 0; - ptr += add = skip_term (ptr, end); - if (!add) - return 0; - ptr += skip_name_string (ptr, end); - break; - default: - return skip_data_ref_object (ptr, end); - } - return ptr - ptr0; -} - -static inline grub_uint32_t -skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end) -{ - const grub_uint8_t *ptr0 = ptr; - int add; - grub_dprintf ("acpi", "Extended opcode: 0x%x\n", *ptr); - switch (*ptr) - { - case GRUB_ACPI_EXTOPCODE_MUTEX: - ptr++; - ptr += skip_name_string (ptr, end); - ptr++; - break; - case GRUB_ACPI_EXTOPCODE_EVENT_OP: - ptr++; - ptr += skip_name_string (ptr, end); - break; - case GRUB_ACPI_EXTOPCODE_OPERATION_REGION: - ptr++; - ptr += skip_name_string (ptr, end); - ptr++; - ptr += add = skip_term (ptr, end); - if (!add) - return 0; - ptr += add = skip_term (ptr, end); - if (!add) - return 0; - break; - case GRUB_ACPI_EXTOPCODE_FIELD_OP: - case GRUB_ACPI_EXTOPCODE_DEVICE_OP: - case GRUB_ACPI_EXTOPCODE_PROCESSOR_OP: - case GRUB_ACPI_EXTOPCODE_POWER_RES_OP: - case GRUB_ACPI_EXTOPCODE_THERMAL_ZONE_OP: - case GRUB_ACPI_EXTOPCODE_INDEX_FIELD_OP: - case GRUB_ACPI_EXTOPCODE_BANK_FIELD_OP: - ptr++; - ptr += decode_length (ptr, 0); - break; - default: - grub_printf ("Unexpected extended opcode: 0x%x\n", *ptr); - return 0; - } - return ptr - ptr0; -} - - -static int -get_sleep_type (grub_uint8_t *table, grub_uint8_t *ptr, grub_uint8_t *end, - grub_uint8_t *scope, int scope_len) -{ - grub_uint8_t *prev = table; - - if (!ptr) - ptr = table + sizeof (struct grub_acpi_table_header); - while (ptr < end && prev < ptr) - { - int add; - prev = ptr; - grub_dprintf ("acpi", "Opcode 0x%x\n", *ptr); - grub_dprintf ("acpi", "Tell %x\n", (unsigned) (ptr - table)); - switch (*ptr) - { - case GRUB_ACPI_OPCODE_EXTOP: - ptr++; - ptr += add = skip_ext_op (ptr, end); - if (!add) - return -1; - break; - case GRUB_ACPI_OPCODE_CREATE_DWORD_FIELD: - case GRUB_ACPI_OPCODE_CREATE_WORD_FIELD: - case GRUB_ACPI_OPCODE_CREATE_BYTE_FIELD: - { - ptr += 5; - ptr += add = skip_data_ref_object (ptr, end); - if (!add) - return -1; - ptr += 4; - break; - } - case GRUB_ACPI_OPCODE_NAME: - ptr++; - if ((!scope || grub_memcmp (scope, "\\", scope_len) == 0) && - (grub_memcmp (ptr, "_S5_", 4) == 0 || grub_memcmp (ptr, "\\_S5_", 4) == 0)) - { - int ll; - grub_uint8_t *ptr2 = ptr; - grub_dprintf ("acpi", "S5 found\n"); - ptr2 += skip_name_string (ptr, end); - if (*ptr2 != 0x12) - { - grub_printf ("Unknown opcode in _S5: 0x%x\n", *ptr2); - return -1; - } - ptr2++; - decode_length (ptr2, &ll); - ptr2 += ll; - ptr2++; - switch (*ptr2) - { - case GRUB_ACPI_OPCODE_ZERO: - return 0; - case GRUB_ACPI_OPCODE_ONE: - return 1; - case GRUB_ACPI_OPCODE_BYTE_CONST: - return ptr2[1]; - default: - grub_printf ("Unknown data type in _S5: 0x%x\n", *ptr2); - return -1; - } - } - ptr += add = skip_name_string (ptr, end); - if (!add) - return -1; - ptr += add = skip_data_ref_object (ptr, end); - if (!add) - return -1; - break; - case GRUB_ACPI_OPCODE_ALIAS: - ptr++; - /* We need to skip two name strings */ - ptr += add = skip_name_string (ptr, end); - if (!add) - return -1; - ptr += add = skip_name_string (ptr, end); - if (!add) - return -1; - break; - - case GRUB_ACPI_OPCODE_SCOPE: - { - int scope_sleep_type; - int ll; - grub_uint8_t *name; - int name_len; - - ptr++; - add = decode_length (ptr, &ll); - name = ptr + ll; - name_len = skip_name_string (name, ptr + add); - if (!name_len) - return -1; - scope_sleep_type = get_sleep_type (table, name + name_len, - ptr + add, name, name_len); - if (scope_sleep_type != -2) - return scope_sleep_type; - ptr += add; - break; - } - case GRUB_ACPI_OPCODE_IF: - case GRUB_ACPI_OPCODE_METHOD: - { - ptr++; - ptr += decode_length (ptr, 0); - break; - } - default: - grub_printf ("Unknown opcode 0x%x\n", *ptr); - return -1; - } - } - - return -2; -} - -#ifdef GRUB_DSDT_TEST -int -main (int argc, char **argv) -{ - FILE *f; - size_t len; - unsigned char *buf; - if (argc < 2) - printf ("Usage: %s FILE\n", argv[0]); - f = grub_util_fopen (argv[1], "rb"); - if (!f) - { - printf ("Couldn't open file\n"); - return 1; - } - fseek (f, 0, SEEK_END); - len = ftell (f); - fseek (f, 0, SEEK_SET); - buf = malloc (len); - if (!buf) - { - printf (_("error: %s.\n"), _("out of memory")); - fclose (f); - return 2; - } - if (fread (buf, 1, len, f) != len) - { - printf (_("cannot read `%s': %s"), argv[1], strerror (errno)); - free (buf); - fclose (f); - return 2; - } - - printf ("Sleep type = %d\n", get_sleep_type (buf, NULL, buf + len, NULL, 0)); - free (buf); - fclose (f); - return 0; -} - -#else - -void -grub_acpi_halt (void) -{ - struct grub_acpi_rsdp_v20 *rsdp2; - struct grub_acpi_rsdp_v10 *rsdp1; - struct grub_acpi_table_header *rsdt; - grub_uint32_t *entry_ptr; - grub_uint32_t port = 0; - int sleep_type = -1; - - rsdp2 = grub_acpi_get_rsdpv2 (); - if (rsdp2) - rsdp1 = &(rsdp2->rsdpv1); - else - rsdp1 = grub_acpi_get_rsdpv1 (); - grub_dprintf ("acpi", "rsdp1=%p\n", rsdp1); - if (!rsdp1) - return; - - rsdt = (struct grub_acpi_table_header *) (grub_addr_t) rsdp1->rsdt_addr; - for (entry_ptr = (grub_uint32_t *) (rsdt + 1); - entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt) - + rsdt->length); - entry_ptr++) - { - if (grub_memcmp ((void *) (grub_addr_t) *entry_ptr, "FACP", 4) == 0) - { - struct grub_acpi_fadt *fadt - = ((struct grub_acpi_fadt *) (grub_addr_t) *entry_ptr); - struct grub_acpi_table_header *dsdt - = (struct grub_acpi_table_header *) (grub_addr_t) fadt->dsdt_addr; - grub_uint8_t *buf = (grub_uint8_t *) dsdt; - - port = fadt->pm1a; - - grub_dprintf ("acpi", "PM1a port=%x\n", port); - - if (grub_memcmp (dsdt->signature, "DSDT", - sizeof (dsdt->signature)) == 0 - && sleep_type < 0) - sleep_type = get_sleep_type (buf, NULL, buf + dsdt->length, - NULL, 0); - } - else if (grub_memcmp ((void *) (grub_addr_t) *entry_ptr, "SSDT", 4) == 0 - && sleep_type < 0) - { - struct grub_acpi_table_header *ssdt - = (struct grub_acpi_table_header *) (grub_addr_t) *entry_ptr; - grub_uint8_t *buf = (grub_uint8_t *) ssdt; - - grub_dprintf ("acpi", "SSDT = %p\n", ssdt); - - sleep_type = get_sleep_type (buf, NULL, buf + ssdt->length, NULL, 0); - } - } - - grub_dprintf ("acpi", "SLP_TYP = %d, port = 0x%x\n", sleep_type, port); - if (port && sleep_type >= 0 && sleep_type < 8) - grub_outw (GRUB_ACPI_SLP_EN | (sleep_type << GRUB_ACPI_SLP_TYP_OFFSET), - port & 0xffff); - - grub_millisleep (1500); - - /* TRANSLATORS: It's computer shutdown using ACPI, not disabling ACPI. */ - grub_puts_ (N_("ACPI shutdown failed")); -} -#endif diff --git a/grub-core/commands/bli.c b/grub-core/commands/bli.c deleted file mode 100644 index 298c5f70a..000000000 --- a/grub-core/commands/bli.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - * - * Implementation of the Boot Loader Interface. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define MODNAME "bli" - -static const grub_guid_t bli_vendor_guid = GRUB_EFI_VENDOR_BOOT_LOADER_INTERFACE_GUID; - -static grub_err_t -get_part_uuid (const char *device_name, char **part_uuid) -{ - grub_device_t device; - grub_err_t status = GRUB_ERR_NONE; - grub_disk_t disk = NULL; - struct grub_gpt_partentry entry; - - device = grub_device_open (device_name); - if (device == NULL) - return grub_error (grub_errno, N_("cannot open device: %s"), device_name); - - if (device->disk == NULL) - { - grub_dprintf ("bli", "%s is not a disk device, partuuid skipped\n", device_name); - *part_uuid = NULL; - grub_device_close (device); - return GRUB_ERR_NONE; - } - - if (device->disk->partition == NULL) - { - grub_dprintf ("bli", "%s has no partition, partuuid skipped\n", device_name); - *part_uuid = NULL; - grub_device_close (device); - return GRUB_ERR_NONE; - } - - disk = grub_disk_open (device->disk->name); - if (disk == NULL) - { - status = grub_error (grub_errno, N_("cannot open disk: %s"), device_name); - grub_device_close (device); - return status; - } - - if (grub_strcmp (device->disk->partition->partmap->name, "gpt") != 0) - { - status = grub_error (GRUB_ERR_BAD_PART_TABLE, - N_("this is not a GPT partition table: %s"), device_name); - goto fail; - } - - if (grub_disk_read (disk, device->disk->partition->offset, - device->disk->partition->index, sizeof (entry), &entry) != GRUB_ERR_NONE) - { - status = grub_error (grub_errno, N_("read error: %s"), device_name); - goto fail; - } - - *part_uuid = grub_xasprintf ("%pG", &entry.guid); - if (*part_uuid == NULL) - status = grub_errno; - - fail: - grub_disk_close (disk); - grub_device_close (device); - - return status; -} - -static grub_err_t -set_loader_device_part_uuid (void) -{ - grub_efi_loaded_image_t *image; - char *device_name; - grub_err_t status = GRUB_ERR_NONE; - char *part_uuid = NULL; - - image = grub_efi_get_loaded_image (grub_efi_image_handle); - if (image == NULL) - return grub_error (GRUB_ERR_BAD_DEVICE, N_("unable to find boot device")); - - device_name = grub_efidisk_get_device_name (image->device_handle); - if (device_name == NULL) - return grub_error (GRUB_ERR_BAD_DEVICE, N_("unable to find boot device")); - - status = get_part_uuid (device_name, &part_uuid); - - if (status == GRUB_ERR_NONE && part_uuid) - status = grub_efi_set_variable_to_string ("LoaderDevicePartUUID", &bli_vendor_guid, part_uuid, - GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | - GRUB_EFI_VARIABLE_RUNTIME_ACCESS); - else - grub_error (status, N_("unable to determine partition UUID of boot device")); - - grub_free (part_uuid); - grub_free (device_name); - return status; -} - -GRUB_MOD_INIT (bli) -{ - grub_efi_set_variable_to_string ("LoaderInfo", &bli_vendor_guid, PACKAGE_STRING, - GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | - GRUB_EFI_VARIABLE_RUNTIME_ACCESS); - set_loader_device_part_uuid (); - /* No error here is critical, other than being logged */ - grub_print_error (); -} diff --git a/grub-core/commands/blocklist.c b/grub-core/commands/blocklist.c deleted file mode 100644 index 48fd85a33..000000000 --- a/grub-core/commands/blocklist.c +++ /dev/null @@ -1,162 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* Context for grub_cmd_blocklist. */ -struct blocklist_ctx -{ - unsigned long start_sector; - unsigned num_sectors; - int num_entries; - grub_disk_addr_t part_start; -}; - -/* Helper for grub_cmd_blocklist. */ -static void -print_blocklist (grub_disk_addr_t sector, unsigned num, - unsigned offset, unsigned length, struct blocklist_ctx *ctx) -{ - if (ctx->num_entries++) - grub_printf (","); - - grub_printf ("%llu", (unsigned long long) (sector - ctx->part_start)); - if (num > 0) - grub_printf ("+%u", num); - if (offset != 0 || length != 0) - grub_printf ("[%u-%u]", offset, offset + length); -} - -/* Helper for grub_cmd_blocklist. */ -static grub_err_t -read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length, - char *buf __attribute__ ((unused)), void *data) -{ - struct blocklist_ctx *ctx = data; - - if (ctx->num_sectors > 0) - { - if (ctx->start_sector + ctx->num_sectors == sector - && offset == 0 && length >= GRUB_DISK_SECTOR_SIZE) - { - ctx->num_sectors += length >> GRUB_DISK_SECTOR_BITS; - sector += length >> GRUB_DISK_SECTOR_BITS; - length &= (GRUB_DISK_SECTOR_SIZE - 1); - } - - if (!length) - return GRUB_ERR_NONE; - print_blocklist (ctx->start_sector, ctx->num_sectors, 0, 0, ctx); - ctx->num_sectors = 0; - } - - if (offset) - { - unsigned l = length + offset; - l &= (GRUB_DISK_SECTOR_SIZE - 1); - l -= offset; - print_blocklist (sector, 0, offset, l, ctx); - length -= l; - sector++; - offset = 0; - } - - if (!length) - return GRUB_ERR_NONE; - - if (length & (GRUB_DISK_SECTOR_SIZE - 1)) - { - if (length >> GRUB_DISK_SECTOR_BITS) - { - print_blocklist (sector, length >> GRUB_DISK_SECTOR_BITS, 0, 0, ctx); - sector += length >> GRUB_DISK_SECTOR_BITS; - } - print_blocklist (sector, 0, 0, length & (GRUB_DISK_SECTOR_SIZE - 1), ctx); - } - else - { - ctx->start_sector = sector; - ctx->num_sectors = length >> GRUB_DISK_SECTOR_BITS; - } - - return GRUB_ERR_NONE; -} - -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]; - struct blocklist_ctx ctx = { - .start_sector = 0, - .num_sectors = 0, - .num_entries = 0, - .part_start = 0 - }; - - if (argc < 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - file = grub_file_open (args[0], GRUB_FILE_TYPE_PRINT_BLOCKLIST - | GRUB_FILE_TYPE_NO_DECOMPRESS); - if (! file) - return grub_errno; - - if (! file->device->disk) - return grub_error (GRUB_ERR_BAD_DEVICE, - "this command is available only for disk devices"); - - ctx.part_start = grub_partition_get_start (file->device->disk->partition); - - file->read_hook = read_blocklist; - file->read_hook_data = &ctx; - - while (grub_file_read (file, buf, sizeof (buf)) > 0) - ; - - if (ctx.num_sectors > 0) - print_blocklist (ctx.start_sector, ctx.num_sectors, 0, 0, &ctx); - - grub_file_close (file); - - return grub_errno; -} - -static grub_command_t cmd; - -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/boottime.c b/grub-core/commands/boottime.c deleted file mode 100644 index 424412851..000000000 --- a/grub-core/commands/boottime.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - - -static grub_err_t -grub_cmd_boottime (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char *argv[] __attribute__ ((unused))) -{ - struct grub_boot_time *cur; - grub_uint64_t last_time = 0, start_time = 0; - if (!grub_boot_time_head) - { - grub_puts_ (N_("No boot time statistics is available\n")); - return 0; - } - start_time = last_time = grub_boot_time_head->tp; - for (cur = grub_boot_time_head; cur; cur = cur->next) - { - grub_uint32_t tmabs = cur->tp - start_time; - grub_uint32_t tmrel = cur->tp - last_time; - last_time = cur->tp; - - grub_printf ("%3d.%03ds %2d.%03ds %s:%d %s\n", - tmabs / 1000, tmabs % 1000, tmrel / 1000, tmrel % 1000, cur->file, cur->line, - cur->msg); - } - return 0; -} - -static grub_command_t cmd_boottime; - -GRUB_MOD_INIT(boottime) -{ - cmd_boottime = - grub_register_command ("boottime", grub_cmd_boottime, - 0, N_("Show boot time statistics.")); -} - -GRUB_MOD_FINI(boottime) -{ - grub_unregister_command (cmd_boottime); -} diff --git a/grub-core/commands/cacheinfo.c b/grub-core/commands/cacheinfo.c deleted file mode 100644 index e8ee05b85..000000000 --- a/grub-core/commands/cacheinfo.c +++ /dev/null @@ -1,62 +0,0 @@ -/* cacheinfo.c - disk cache statistics */ -/* - * 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 . - */ - -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -grub_rescue_cmd_info (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char *argv[] __attribute__ ((unused))) -{ - unsigned long hits, misses; - - grub_disk_cache_get_performance (&hits, &misses); - if (hits + misses) - { - unsigned long ratio = hits * 10000 / (hits + misses); - grub_printf ("(%lu.%lu%%)\n", ratio / 100, ratio % 100); - grub_printf_ (N_("Disk cache statistics: hits = %lu (%lu.%02lu%%)," - " misses = %lu\n"), ratio / 100, ratio % 100, - hits, misses); - } - else - grub_printf ("%s\n", _("No disk cache statistics available\n")); - - return 0; -} - -static grub_command_t cmd_cacheinfo; - -GRUB_MOD_INIT(cacheinfo) -{ - cmd_cacheinfo = - grub_register_command ("cacheinfo", grub_rescue_cmd_info, - 0, N_("Get disk cache info.")); -} - -GRUB_MOD_FINI(cacheinfo) -{ - grub_unregister_command (cmd_cacheinfo); -} diff --git a/grub-core/commands/cat.c b/grub-core/commands/cat.c deleted file mode 100644 index 2b67c1c7f..000000000 --- a/grub-core/commands/cat.c +++ /dev/null @@ -1,170 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static const struct grub_arg_option options[] = - { - {"dos", -1, 0, N_("Accept DOS-style CR/NL line endings."), 0, 0}, - {0, 0, 0, 0, 0, 0} - }; - -static grub_err_t -grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_arg_list *state = ctxt->state; - int dos = 0; - grub_file_t file; - unsigned char buf[GRUB_DISK_SECTOR_SIZE]; - grub_ssize_t size; - int key = GRUB_TERM_NO_KEY; - grub_uint32_t code = 0; - int count = 0; - unsigned char utbuf[GRUB_MAX_UTF8_PER_CODEPOINT + 1]; - int utcount = 0; - int is_0d = 0; - int j; - - if (state[0].set) - dos = 1; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - file = grub_file_open (args[0], GRUB_FILE_TYPE_CAT); - 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++) - { - utbuf[utcount++] = buf[i]; - - if (is_0d && buf[i] != '\n') - { - grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); - grub_printf ("<%x>", (int) '\r'); - grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); - } - - is_0d = 0; - - if (!grub_utf8_process (buf[i], &code, &count)) - { - grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); - for (j = 0; j < utcount - 1; j++) - grub_printf ("<%x>", (unsigned int) utbuf[j]); - code = 0; - count = 0; - if (utcount == 1 || !grub_utf8_process (buf[i], &code, &count)) - { - grub_printf ("<%x>", (unsigned int) buf[i]); - code = 0; - count = 0; - utcount = 0; - grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); - continue; - } - grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); - utcount = 1; - } - if (count) - continue; - - if ((code >= 0xa1 || grub_isprint (code) - || grub_isspace (code)) && code != '\r') - { - grub_printf ("%C", code); - count = 0; - code = 0; - utcount = 0; - continue; - } - - if (dos && code == '\r') - { - is_0d = 1; - count = 0; - code = 0; - utcount = 0; - continue; - } - - grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); - for (j = 0; j < utcount; j++) - grub_printf ("<%x>", (unsigned int) utbuf[j]); - grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); - count = 0; - code = 0; - utcount = 0; - } - - do - key = grub_getkey_noblock (); - while (key != GRUB_TERM_ESC && key != GRUB_TERM_NO_KEY); - } - - if (is_0d) - { - grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); - grub_printf ("<%x>", (unsigned int) '\r'); - grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); - } - - if (utcount) - { - grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); - for (j = 0; j < utcount; j++) - grub_printf ("<%x>", (unsigned int) utbuf[j]); - grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); - } - - grub_xputs ("\n"); - grub_refresh (); - grub_file_close (file); - - return 0; -} - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT(cat) -{ - cmd = grub_register_extcmd ("cat", grub_cmd_cat, 0, - N_("FILE"), N_("Show the contents of a file."), - options); -} - -GRUB_MOD_FINI(cat) -{ - grub_unregister_extcmd (cmd); -} diff --git a/grub-core/commands/efi/efifwsetup.c b/grub-core/commands/efi/efifwsetup.c deleted file mode 100644 index 704f9d352..000000000 --- a/grub-core/commands/efi/efifwsetup.c +++ /dev/null @@ -1,102 +0,0 @@ -/* fwsetup.c - Reboot into firmware setup menu. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2012 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_efi_boolean_t efifwsetup_is_supported (void); - -static grub_err_t -grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - grub_efi_uint64_t *old_os_indications; - grub_efi_uint64_t os_indications = GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI; - grub_err_t status; - grub_size_t oi_size; - static grub_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; - - if (argc >= 1 && grub_strcmp(args[0], "--is-supported") == 0) - return !efifwsetup_is_supported (); - - if (!efifwsetup_is_supported ()) - return grub_error (GRUB_ERR_INVALID_COMMAND, - N_("reboot to firmware setup is not supported by the current firmware")); - - grub_efi_get_variable ("OsIndications", &global, &oi_size, - (void **) &old_os_indications); - - if (old_os_indications != NULL && oi_size == sizeof (os_indications)) - os_indications |= *old_os_indications; - - grub_free (old_os_indications); - - status = grub_efi_set_variable ("OsIndications", &global, &os_indications, - sizeof (os_indications)); - if (status != GRUB_ERR_NONE) - return status; - - grub_reboot (); - - return GRUB_ERR_BUG; -} - -static grub_command_t cmd = NULL; - -static grub_efi_boolean_t -efifwsetup_is_supported (void) -{ - grub_efi_uint64_t *os_indications_supported = NULL; - grub_size_t oi_size = 0; - static grub_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; - grub_efi_boolean_t ret = 0; - - grub_efi_get_variable ("OsIndicationsSupported", &global, &oi_size, - (void **) &os_indications_supported); - - if (!os_indications_supported) - goto done; - - if (*os_indications_supported & GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI) - ret = 1; - - done: - grub_free (os_indications_supported); - return ret; -} - -GRUB_MOD_INIT (efifwsetup) -{ - cmd = grub_register_command ("fwsetup", grub_cmd_fwsetup, NULL, - N_("Reboot into firmware setup menu.")); -} - -GRUB_MOD_FINI (efifwsetup) -{ - if (cmd) - grub_unregister_command (cmd); -} diff --git a/grub-core/commands/efi/efitextmode.c b/grub-core/commands/efi/efitextmode.c deleted file mode 100644 index 198bc694d..000000000 --- a/grub-core/commands/efi/efitextmode.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - * - * Set/Get UEFI text output mode resolution. - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -grub_efi_set_mode (grub_efi_simple_text_output_interface_t *o, - grub_efi_int32_t mode) -{ - grub_efi_status_t status; - - if (mode != o->mode->mode) - { - status = o->set_mode (o, mode); - if (status == GRUB_EFI_SUCCESS) - ; - else if (status == GRUB_EFI_DEVICE_ERROR) - return grub_error (GRUB_ERR_BAD_DEVICE, - N_("device error: could not set requested mode")); - else if (status == GRUB_EFI_UNSUPPORTED) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("invalid mode: number not valid")); - else - return grub_error (GRUB_ERR_BAD_FIRMWARE, - N_("unexpected EFI error number: `%u'"), - (unsigned) status); - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_efitextmode (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) -{ - grub_efi_simple_text_output_interface_t *o = grub_efi_system_table->con_out; - unsigned long mode; - const char *p = NULL; - grub_err_t err; - grub_efi_uintn_t columns, rows; - grub_efi_int32_t i; - - if (o == NULL) - return grub_error (GRUB_ERR_BAD_DEVICE, N_("no UEFI output console interface")); - - if (o->mode == NULL) - return grub_error (GRUB_ERR_BUG, N_("no mode struct for UEFI output console")); - - if (argc > 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("at most two arguments expected")); - - if (argc == 0) - { - grub_printf_ (N_("Available modes for console output device.\n")); - - for (i = 0; i < o->mode->max_mode; i++) - if (GRUB_EFI_SUCCESS == o->query_mode (o, i, &columns, &rows)) - grub_printf_ (N_(" [%" PRIuGRUB_EFI_UINT32_T "] Col %5" - PRIuGRUB_EFI_UINTN_T " Row %5" PRIuGRUB_EFI_UINTN_T - " %c\n"), - i, columns, rows, (i == o->mode->mode) ? '*' : ' '); - } - else if (argc == 1) - { - if (grub_strcmp (args[0], "min") == 0) - mode = 0; - else if (grub_strcmp (args[0], "max") == 0) - mode = o->mode->max_mode - 1; - else - { - mode = grub_strtoul (args[0], &p, 0); - - if (*args[0] == '\0' || *p != '\0') - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("non-numeric or invalid mode `%s'"), args[0]); - } - - if (mode < (unsigned long) o->mode->max_mode) - { - err = grub_efi_set_mode (o, (grub_efi_int32_t) mode); - if (err != GRUB_ERR_NONE) - return err; - } - else - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("invalid mode: `%lu' is greater than maximum mode `%lu'"), - mode, (unsigned long) o->mode->max_mode); - } - else if (argc == 2) - { - grub_efi_uintn_t u_columns, u_rows; - - u_columns = (grub_efi_uintn_t) grub_strtoul (args[0], &p, 0); - - if (*args[0] == '\0' || *p != '\0') - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("non-numeric or invalid columns number `%s'"), args[0]); - - u_rows = (grub_efi_uintn_t) grub_strtoul (args[1], &p, 0); - - if (*args[1] == '\0' || *p != '\0') - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("non-numeric or invalid rows number `%s'"), args[1]); - - for (i = 0; i < o->mode->max_mode; i++) - if (GRUB_EFI_SUCCESS == o->query_mode (o, i, &columns, &rows)) - if (u_columns == columns && u_rows == rows) - return grub_efi_set_mode (o, (grub_efi_int32_t) i); - - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("no mode found with requested columns and rows")); - } - - return GRUB_ERR_NONE; -} - -static grub_command_t cmd; -GRUB_MOD_INIT (efitextmode) -{ - cmd = grub_register_command ("efitextmode", grub_cmd_efitextmode, - N_("[min | max | | ]"), - N_("Get or set EFI text mode.")); -} - -GRUB_MOD_FINI (efitextmode) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/commands/efi/lsefi.c b/grub-core/commands/efi/lsefi.c deleted file mode 100644 index 7b8316d41..000000000 --- a/grub-core/commands/efi/lsefi.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2012 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static struct known_protocol -{ - grub_guid_t guid; - const char *name; -} known_protocols[] = - { - { GRUB_EFI_DISK_IO_GUID, "disk" }, - { GRUB_EFI_BLOCK_IO_GUID, "block" }, - { GRUB_EFI_SERIAL_IO_GUID, "serial" }, - { GRUB_EFI_SIMPLE_NETWORK_GUID, "network" }, - { GRUB_EFI_PXE_GUID, "pxe" }, - { GRUB_EFI_DEVICE_PATH_GUID, "device path" }, - { GRUB_EFI_PCI_IO_GUID, "PCI" }, - { GRUB_EFI_PCI_ROOT_IO_GUID, "PCI root" }, - { GRUB_EFI_EDID_ACTIVE_GUID, "active EDID" }, - { GRUB_EFI_EDID_DISCOVERED_GUID, "discovered EDID" }, - { GRUB_EFI_EDID_OVERRIDE_GUID, "override EDID" }, - { GRUB_EFI_GOP_GUID, "GOP" }, - { GRUB_EFI_UGA_DRAW_GUID, "UGA draw" }, - { GRUB_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID, "simple text output" }, - { GRUB_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID, "simple text input" }, - { GRUB_EFI_SIMPLE_POINTER_PROTOCOL_GUID, "simple pointer" }, - { GRUB_EFI_CONSOLE_CONTROL_GUID, "console control" }, - { GRUB_EFI_ABSOLUTE_POINTER_PROTOCOL_GUID, "absolute pointer" }, - { GRUB_EFI_DRIVER_BINDING_PROTOCOL_GUID, "EFI driver binding" }, - { GRUB_EFI_LOAD_FILE_PROTOCOL_GUID, "load file" }, - { GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID, "load file2" }, - { GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, "simple FS" }, - { GRUB_EFI_TAPE_IO_PROTOCOL_GUID, "tape I/O" }, - { GRUB_EFI_UNICODE_COLLATION_PROTOCOL_GUID, "unicode collation" }, - { GRUB_EFI_SCSI_IO_PROTOCOL_GUID, "SCSI I/O" }, - { GRUB_EFI_USB2_HC_PROTOCOL_GUID, "USB host" }, - { GRUB_EFI_DEBUG_SUPPORT_PROTOCOL_GUID, "debug support" }, - { GRUB_EFI_DEBUGPORT_PROTOCOL_GUID, "debug port" }, - { GRUB_EFI_DECOMPRESS_PROTOCOL_GUID, "decompress" }, - { GRUB_EFI_LOADED_IMAGE_PROTOCOL_GUID, "loaded image" }, - { GRUB_EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID, "device path to text" }, - { GRUB_EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID, "device path utilities" }, - { GRUB_EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID, "device path from text" }, - { GRUB_EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID, "HII config routing" }, - { GRUB_EFI_HII_DATABASE_PROTOCOL_GUID, "HII database" }, - { GRUB_EFI_HII_STRING_PROTOCOL_GUID, "HII string" }, - { GRUB_EFI_HII_IMAGE_PROTOCOL_GUID, "HII image" }, - { GRUB_EFI_HII_FONT_PROTOCOL_GUID, "HII font" }, - { GRUB_EFI_COMPONENT_NAME2_PROTOCOL_GUID, "component name 2" }, - { GRUB_EFI_HII_CONFIGURATION_ACCESS_PROTOCOL_GUID, - "HII configuration access" }, - { GRUB_EFI_USB_IO_PROTOCOL_GUID, "USB I/O" }, - }; - -static grub_err_t -grub_cmd_lsefi (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - grub_efi_handle_t *handles; - grub_efi_uintn_t num_handles; - unsigned i, j, k; - - handles = grub_efi_locate_handle (GRUB_EFI_ALL_HANDLES, - NULL, NULL, &num_handles); - - for (i = 0; i < num_handles; i++) - { - grub_efi_handle_t handle = handles[i]; - grub_efi_status_t status; - grub_efi_uintn_t num_protocols; - grub_packed_guid_t **protocols; - grub_efi_device_path_t *dp; - - grub_printf ("Handle %p\n", handle); - - dp = grub_efi_get_device_path (handle); - if (dp) - { - grub_printf (" "); - grub_efi_print_device_path (dp); - } - - status = grub_efi_system_table->boot_services->protocols_per_handle (handle, - &protocols, - &num_protocols); - if (status != GRUB_EFI_SUCCESS) { - grub_printf ("Unable to retrieve protocols\n"); - continue; - } - for (j = 0; j < num_protocols; j++) - { - for (k = 0; k < ARRAY_SIZE (known_protocols); k++) - if (grub_memcmp (protocols[j], &known_protocols[k].guid, - sizeof (known_protocols[k].guid)) == 0) - break; - if (k < ARRAY_SIZE (known_protocols)) - grub_printf (" %s\n", known_protocols[k].name); - else - grub_printf (" %pG\n", protocols[j]); - } - - } - - return 0; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(lsefi) -{ - cmd = grub_register_command ("lsefi", grub_cmd_lsefi, - NULL, "Display EFI handles."); -} - -GRUB_MOD_FINI(lsefi) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/commands/efi/lsefimmap.c b/grub-core/commands/efi/lsefimmap.c deleted file mode 100644 index d0885d72f..000000000 --- a/grub-core/commands/efi/lsefimmap.c +++ /dev/null @@ -1,160 +0,0 @@ -/* lsefimemmap.c - Display memory map. */ -/* - * 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 . - */ -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define ADD_MEMORY_DESCRIPTOR(desc, size) \ - ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) - -static grub_err_t -grub_cmd_lsefimmap (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - grub_efi_uintn_t map_size; - grub_efi_memory_descriptor_t *memory_map; - grub_efi_memory_descriptor_t *memory_map_end; - grub_efi_memory_descriptor_t *desc; - grub_efi_uintn_t desc_size; - - map_size = 0; - if (grub_efi_get_memory_map (&map_size, NULL, NULL, &desc_size, 0) < 0) - return 0; - - memory_map = grub_malloc (map_size); - if (memory_map == NULL) - return grub_errno; - if (grub_efi_get_memory_map (&map_size, memory_map, NULL, &desc_size, 0) <= 0) - goto fail; - - grub_printf - ("Type Physical start - end #Pages " - " Size Attributes\n"); - memory_map_end = ADD_MEMORY_DESCRIPTOR (memory_map, map_size); - for (desc = memory_map; - desc < memory_map_end; - desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) - { - grub_efi_uint64_t size; - grub_efi_uint64_t attr; - static const char types_str[][9] = - { - "reserved", - "ldr-code", - "ldr-data", - "BS-code ", - "BS-data ", - "RT-code ", - "RT-data ", - "conv-mem", - "unusable", - "ACPI-rec", - "ACPI-nvs", - "MMIO ", - "IO-ports", - "PAL-code", - "persist ", - }; - if (desc->type < ARRAY_SIZE (types_str)) - grub_printf ("%s ", types_str[desc->type]); - else - grub_printf ("Unk %02x ", desc->type); - - grub_printf (" %016" PRIxGRUB_UINT64_T "-%016" PRIxGRUB_UINT64_T - " %08" PRIxGRUB_UINT64_T, - desc->physical_start, - desc->physical_start + (desc->num_pages << 12) - 1, - desc->num_pages); - - size = desc->num_pages << 12; /* 4 KiB page size */ - /* - * Since size is a multiple of 4 KiB, no need to handle units - * of just Bytes (which would use a mask of 0x3ff). - * - * 14 characters would support the largest possible number of 4 KiB - * pages that are not a multiple of larger units (e.g., MiB): - * 17592186044415 (0xffffff_fffff000), but that uses a lot of - * whitespace for a rare case. 6 characters usually suffices; - * columns will be off if not, but this is preferable to rounding. - */ - if (size & 0xfffff) - grub_printf (" %6" PRIuGRUB_UINT64_T "KiB", size >> 10); - else if (size & 0x3fffffff) - grub_printf (" %6" PRIuGRUB_UINT64_T "MiB", size >> 20); - else if (size & 0xffffffffff) - grub_printf (" %6" PRIuGRUB_UINT64_T "GiB", size >> 30); - else if (size & 0x3ffffffffffff) - grub_printf (" %6" PRIuGRUB_UINT64_T "TiB", size >> 40); - else if (size & 0xfffffffffffffff) - grub_printf (" %6" PRIuGRUB_UINT64_T "PiB", size >> 50); - else - grub_printf (" %6" PRIuGRUB_UINT64_T "EiB", size >> 60); - - attr = desc->attribute; - if (attr & GRUB_EFI_MEMORY_RUNTIME) - grub_printf (" RT"); - if (attr & GRUB_EFI_MEMORY_UC) - grub_printf (" UC"); - if (attr & GRUB_EFI_MEMORY_WC) - grub_printf (" WC"); - if (attr & GRUB_EFI_MEMORY_WT) - grub_printf (" WT"); - if (attr & GRUB_EFI_MEMORY_WB) - grub_printf (" WB"); - if (attr & GRUB_EFI_MEMORY_UCE) - grub_printf (" UCE"); - if (attr & GRUB_EFI_MEMORY_WP) - grub_printf (" WP"); - if (attr & GRUB_EFI_MEMORY_RP) - grub_printf (" RP"); - if (attr & GRUB_EFI_MEMORY_XP) - grub_printf (" XP"); - if (attr & GRUB_EFI_MEMORY_NV) - grub_printf (" NV"); - if (attr & GRUB_EFI_MEMORY_MORE_RELIABLE) - grub_printf (" MR"); - if (attr & GRUB_EFI_MEMORY_RO) - grub_printf (" RO"); - - grub_printf ("\n"); - } - - fail: - grub_free (memory_map); - return 0; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(lsefimmap) -{ - cmd = grub_register_command ("lsefimmap", grub_cmd_lsefimmap, - "", "Display EFI memory map."); -} - -GRUB_MOD_FINI(lsefimmap) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/commands/efi/lsefisystab.c b/grub-core/commands/efi/lsefisystab.c deleted file mode 100644 index ffb24fc3b..000000000 --- a/grub-core/commands/efi/lsefisystab.c +++ /dev/null @@ -1,129 +0,0 @@ -/* lsefisystab.c - Display EFI systab. */ -/* - * 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 . - */ -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct guid_mapping -{ - grub_guid_t guid; - const char *name; -}; - -static const struct guid_mapping guid_mappings[] = - { - { GRUB_EFI_ACPI_20_TABLE_GUID, "ACPI-2.0"}, - { GRUB_EFI_ACPI_TABLE_GUID, "ACPI-1.0"}, - { GRUB_EFI_CONFORMANCE_PROFILES_TABLE_GUID, "CONFORMANCE PROFILES"}, - { GRUB_EFI_CRC32_GUIDED_SECTION_EXTRACTION_GUID, - "CRC32 GUIDED SECTION EXTRACTION"}, - { GRUB_EFI_DEBUG_IMAGE_INFO_TABLE_GUID, "DEBUG IMAGE INFO"}, - { GRUB_EFI_DEVICE_TREE_GUID, "DEVICE TREE"}, - { GRUB_EFI_DXE_SERVICES_TABLE_GUID, "DXE SERVICES"}, - { GRUB_EFI_HCDP_TABLE_GUID, "HCDP"}, - { GRUB_EFI_HOB_LIST_GUID, "HOB LIST"}, - { GRUB_EFI_IMAGE_SECURITY_DATABASE_GUID, "IMAGE EXECUTION INFORMATION"}, - { GRUB_EFI_LZMA_CUSTOM_DECOMPRESS_GUID, "LZMA CUSTOM DECOMPRESS"}, - { GRUB_EFI_MEMORY_TYPE_INFORMATION_GUID, "MEMORY TYPE INFO"}, - { GRUB_EFI_MPS_TABLE_GUID, "MPS"}, - { GRUB_EFI_RT_PROPERTIES_TABLE_GUID, "RT PROPERTIES"}, - { GRUB_EFI_SAL_TABLE_GUID, "SAL"}, - { GRUB_EFI_SMBIOS_TABLE_GUID, "SMBIOS"}, - { GRUB_EFI_SMBIOS3_TABLE_GUID, "SMBIOS3"}, - { GRUB_EFI_SYSTEM_RESOURCE_TABLE_GUID, "SYSTEM RESOURCE TABLE"}, - { GRUB_EFI_TIANO_CUSTOM_DECOMPRESS_GUID, "TIANO CUSTOM DECOMPRESS"}, - { GRUB_EFI_TSC_FREQUENCY_GUID, "TSC FREQUENCY"}, - }; - -static grub_err_t -grub_cmd_lsefisystab (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - const grub_efi_system_table_t *st = grub_efi_system_table; - const grub_efi_uint32_t major_rev = st->hdr.revision >> 16; - const grub_efi_uint32_t minor_rev_upper = (st->hdr.revision & 0xffff) / 10; - const grub_efi_uint32_t minor_rev_lower = (st->hdr.revision & 0xffff) % 10; - grub_efi_configuration_table_t *t; - unsigned int i; - - grub_printf ("Address: %p\n", st); - grub_printf ("Signature: %016" PRIxGRUB_UINT64_T " revision: %u.%u", - st->hdr.signature, major_rev, minor_rev_upper); - if (minor_rev_lower) - grub_printf (".%u", minor_rev_lower); - grub_printf ("\n"); - { - char *vendor; - grub_uint16_t *vendor_utf16; - grub_printf ("Vendor: "); - - for (vendor_utf16 = st->firmware_vendor; *vendor_utf16; vendor_utf16++); - /* Allocate extra 3 bytes to simplify math. */ - vendor = grub_calloc (4, vendor_utf16 - st->firmware_vendor + 1); - if (!vendor) - return grub_errno; - *grub_utf16_to_utf8 ((grub_uint8_t *) vendor, st->firmware_vendor, - vendor_utf16 - st->firmware_vendor) = 0; - grub_printf ("%s", vendor); - grub_free (vendor); - } - - grub_printf (", Version=%x\n", st->firmware_revision); - - grub_printf ("%lld tables:\n", (long long) st->num_table_entries); - t = st->configuration_table; - for (i = 0; i < st->num_table_entries; i++) - { - unsigned int j; - - grub_printf ("%p ", t->vendor_table); - - grub_printf ("%pG", &t->vendor_guid); - - for (j = 0; j < ARRAY_SIZE (guid_mappings); j++) - if (grub_memcmp (&guid_mappings[j].guid, &t->vendor_guid, - sizeof (grub_guid_t)) == 0) - grub_printf (" %s", guid_mappings[j].name); - - grub_printf ("\n"); - t++; - } - return GRUB_ERR_NONE; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(lsefisystab) -{ - cmd = grub_register_command ("lsefisystab", grub_cmd_lsefisystab, - "", "Display EFI system tables."); -} - -GRUB_MOD_FINI(lsefisystab) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/commands/efi/lssal.c b/grub-core/commands/efi/lssal.c deleted file mode 100644 index 7248bdc29..000000000 --- a/grub-core/commands/efi/lssal.c +++ /dev/null @@ -1,163 +0,0 @@ -/* lssal.c - Display EFI SAL systab. */ -/* - * 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 . - */ -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static void -disp_sal (void *table) -{ - struct grub_efi_sal_system_table *t = table; - void *desc; - grub_uint32_t len, l, i; - - grub_printf ("SAL rev: %02x, signature: %x, len:%x\n", - t->sal_rev, t->signature, t->total_table_len); - grub_printf ("nbr entry: %d, chksum: %02x, SAL version A: %02x B: %02x\n", - t->entry_count, t->checksum, - t->sal_a_version, t->sal_b_version); - grub_printf ("OEM-ID: %-32s\n", t->oem_id); - grub_printf ("Product-ID: %-32s\n", t->product_id); - - desc = t->entries; - len = t->total_table_len - sizeof (struct grub_efi_sal_system_table); - if (t->total_table_len <= sizeof (struct grub_efi_sal_system_table)) - return; - for (i = 0; i < t->entry_count; i++) - { - switch (*(grub_uint8_t *) desc) - { - case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_ENTRYPOINT_DESCRIPTOR: - { - struct grub_efi_sal_system_table_entrypoint_descriptor *c = desc; - l = sizeof (*c); - grub_printf (" Entry point: PAL=%016" PRIxGRUB_UINT64_T - " SAL=%016" PRIxGRUB_UINT64_T " GP=%016" - PRIxGRUB_UINT64_T "\n", - c->pal_proc_addr, c->sal_proc_addr, - c->global_data_ptr); - } - break; - case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_MEMORY_DESCRIPTOR: - { - struct grub_efi_sal_system_table_memory_descriptor *c = desc; - l = sizeof (*c); - grub_printf (" Memory descriptor entry addr=%016" PRIxGRUB_UINT64_T - " len=%" PRIuGRUB_UINT64_T "KB\n", - c->addr, c->len * 4); - grub_printf (" sal_used=%d attr=%x AR=%x attr_mask=%x " - "type=%x usage=%x\n", - c->sal_used, c->attr, c->ar, c->attr_mask, c->mem_type, - c->usage); - } - break; - case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PLATFORM_FEATURES: - { - struct grub_efi_sal_system_table_platform_features *c = desc; - l = sizeof (*c); - grub_printf (" Platform features: %02x", c->flags); - if (c->flags & GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_BUSLOCK) - grub_printf (" BusLock"); - if (c->flags & GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IRQREDIRECT) - grub_printf (" IrqRedirect"); - if (c->flags & GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IPIREDIRECT) - - grub_printf (" IPIRedirect"); - if (c->flags & GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_ITCDRIFT) - - grub_printf (" ITCDrift"); - grub_printf ("\n"); - } - break; - case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_TRANSLATION_REGISTER_DESCRIPTOR: - { - struct grub_efi_sal_system_table_translation_register_descriptor *c - = desc; - l = sizeof (*c); - grub_printf (" TR type=%d num=%d va=%016" PRIxGRUB_UINT64_T - " pte=%016" PRIxGRUB_UINT64_T "\n", - c->register_type, c->register_number, - c->addr, c->page_size); - } - break; - case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PURGE_TRANSLATION_COHERENCE: - { - struct grub_efi_sal_system_table_purge_translation_coherence *c - = desc; - l = sizeof (*c); - grub_printf (" PTC coherence nbr=%d addr=%016" PRIxGRUB_UINT64_T "\n", - c->ndomains, c->coherence); - } - break; - case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_AP_WAKEUP: - { - struct grub_efi_sal_system_table_ap_wakeup *c = desc; - l = sizeof (*c); - grub_printf (" AP wake-up: mec=%d vect=%" PRIxGRUB_UINT64_T "\n", - c->mechanism, c->vector); - } - break; - default: - grub_printf (" unknown entry 0x%x\n", *(grub_uint8_t *)desc); - return; - } - desc = (grub_uint8_t *)desc + l; - if (len <= l) - return; - len -= l; - } -} - -static grub_err_t -grub_cmd_lssal (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - static grub_guid_t guid = GRUB_EFI_SAL_TABLE_GUID; - void *table = grub_efi_find_configuration_table (&guid); - - if (table == NULL) - { - grub_printf ("SAL not found\n"); - return GRUB_ERR_NONE; - } - - disp_sal (table); - return GRUB_ERR_NONE; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(lssal) -{ - cmd = grub_register_command ("lssal", grub_cmd_lssal, "", - "Display SAL system table."); -} - -GRUB_MOD_FINI(lssal) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/commands/efi/smbios.c b/grub-core/commands/efi/smbios.c deleted file mode 100644 index 717e5fc1d..000000000 --- a/grub-core/commands/efi/smbios.c +++ /dev/null @@ -1,37 +0,0 @@ -/* smbios.c - get smbios tables. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2019 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -struct grub_smbios_eps * -grub_machine_smbios_get_eps (void) -{ - static grub_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID; - - return (struct grub_smbios_eps *) grub_efi_find_configuration_table (&smbios_guid); -} - -struct grub_smbios_eps3 * -grub_machine_smbios_get_eps3 (void) -{ - static grub_guid_t smbios3_guid = GRUB_EFI_SMBIOS3_TABLE_GUID; - - return (struct grub_smbios_eps3 *) grub_efi_find_configuration_table (&smbios3_guid); -} diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c deleted file mode 100644 index cbac69866..000000000 --- a/grub-core/commands/efi/tpm.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - * - * EFI TPM support code. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef TCG_PCR_EVENT grub_tpm_event_t; - -static grub_guid_t tpm_guid = EFI_TPM_GUID; -static grub_guid_t tpm2_guid = EFI_TPM2_GUID; -static grub_guid_t cc_measurement_guid = GRUB_EFI_CC_MEASUREMENT_PROTOCOL_GUID; - -static grub_efi_handle_t *grub_tpm_handle; -static grub_uint8_t grub_tpm_version; - -static grub_int8_t tpm1_present = -1; -static grub_int8_t tpm2_present = -1; - -static grub_efi_boolean_t -grub_tpm1_present (grub_efi_tpm_protocol_t *tpm) -{ - grub_efi_status_t status; - TCG_EFI_BOOT_SERVICE_CAPABILITY caps; - grub_uint32_t flags; - grub_efi_physical_address_t eventlog, lastevent; - - if (tpm1_present != -1) - return (grub_efi_boolean_t) tpm1_present; - - caps.Size = (grub_uint8_t) sizeof (caps); - - status = tpm->status_check (tpm, &caps, &flags, &eventlog, &lastevent); - - if (status != GRUB_EFI_SUCCESS || caps.TPMDeactivatedFlag - || !caps.TPMPresentFlag) - tpm1_present = 0; - else - tpm1_present = 1; - - grub_dprintf ("tpm", "tpm1%s present\n", tpm1_present ? "" : " NOT"); - - return (grub_efi_boolean_t) tpm1_present; -} - -static grub_efi_boolean_t -grub_tpm2_present (grub_efi_tpm2_protocol_t *tpm) -{ - grub_efi_status_t status; - EFI_TCG2_BOOT_SERVICE_CAPABILITY caps; - - caps.Size = (grub_uint8_t) sizeof (caps); - - if (tpm2_present != -1) - return (grub_efi_boolean_t) tpm2_present; - - status = tpm->get_capability (tpm, &caps); - - if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag) - tpm2_present = 0; - else - tpm2_present = 1; - - grub_dprintf ("tpm", "tpm2%s present\n", tpm2_present ? "" : " NOT"); - - return (grub_efi_boolean_t) tpm2_present; -} - -static grub_efi_boolean_t -grub_tpm_handle_find (grub_efi_handle_t *tpm_handle, - grub_efi_uint8_t *protocol_version) -{ - grub_efi_handle_t *handles; - grub_efi_uintn_t num_handles; - - if (grub_tpm_handle != NULL) - { - *tpm_handle = grub_tpm_handle; - *protocol_version = grub_tpm_version; - return 1; - } - - handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm_guid, NULL, - &num_handles); - if (handles && num_handles > 0) - { - grub_tpm_handle = handles[0]; - *tpm_handle = handles[0]; - grub_tpm_version = 1; - *protocol_version = 1; - grub_dprintf ("tpm", "TPM handle Found, version: 1\n"); - return 1; - } - - handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL, - &num_handles); - if (handles && num_handles > 0) - { - grub_tpm_handle = handles[0]; - *tpm_handle = handles[0]; - grub_tpm_version = 2; - *protocol_version = 2; - grub_dprintf ("tpm", "TPM handle Found, version: 2\n"); - return 1; - } - - return 0; -} - -static grub_err_t -grub_efi_log_event_status (grub_efi_status_t status) -{ - switch (status) - { - case GRUB_EFI_SUCCESS: - return GRUB_ERR_NONE; - case GRUB_EFI_DEVICE_ERROR: - return grub_error (GRUB_ERR_IO, N_("command failed")); - case GRUB_EFI_INVALID_PARAMETER: - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid parameter")); - case GRUB_EFI_BUFFER_TOO_SMALL: - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("output buffer too small")); - case GRUB_EFI_NOT_FOUND: - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); - default: - return grub_error (grub_is_tpm_fail_fatal () ? GRUB_ERR_UNKNOWN_DEVICE : GRUB_ERR_NONE, N_("unknown TPM error")); - } -} - -static grub_err_t -grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, - grub_size_t size, grub_uint8_t pcr, - const char *description) -{ - grub_tpm_event_t *event; - grub_efi_status_t status; - grub_efi_tpm_protocol_t *tpm; - grub_efi_physical_address_t lastevent; - grub_uint32_t algorithm; - grub_uint32_t eventnum = 0; - - tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - - if (!grub_tpm1_present (tpm)) - return 0; - - event = grub_zalloc (sizeof (*event) + grub_strlen (description) + 1); - if (!event) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - N_("cannot allocate TPM event buffer")); - - event->PCRIndex = pcr; - event->EventType = EV_IPL; - event->EventSize = grub_strlen (description) + 1; - grub_strcpy ((char *) event->Event, description); - - algorithm = TCG_ALG_SHA; - status = tpm->log_extend_event (tpm, (grub_addr_t) buf, (grub_uint64_t) size, - algorithm, event, &eventnum, &lastevent); - grub_free (event); - - return grub_efi_log_event_status (status); -} - -static grub_err_t -grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, - grub_size_t size, grub_uint8_t pcr, - const char *description) -{ - EFI_TCG2_EVENT *event; - grub_efi_status_t status; - grub_efi_tpm2_protocol_t *tpm; - - tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - - if (!grub_tpm2_present (tpm)) - return 0; - - event = - grub_zalloc (sizeof (EFI_TCG2_EVENT) + grub_strlen (description) + 1); - if (!event) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - N_("cannot allocate TPM event buffer")); - - event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER); - event->Header.HeaderVersion = 1; - event->Header.PCRIndex = pcr; - event->Header.EventType = EV_IPL; - event->Size = - sizeof (*event) - sizeof (event->Event) + grub_strlen (description) + 1; - grub_strcpy ((char *) event->Event, description); - - status = tpm->hash_log_extend_event (tpm, 0, (grub_addr_t) buf, - (grub_uint64_t) size, event); - grub_free (event); - - return grub_efi_log_event_status (status); -} - -static void -grub_cc_log_event (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, - const char *description) -{ - grub_efi_cc_event_t *event; - grub_efi_status_t status; - grub_efi_cc_protocol_t *cc; - grub_efi_cc_mr_index_t mr; - - cc = grub_efi_locate_protocol (&cc_measurement_guid, NULL); - if (cc == NULL) - return; - - status = cc->map_pcr_to_mr_index (cc, pcr, &mr); - if (status != GRUB_EFI_SUCCESS) - { - grub_efi_log_event_status (status); - return; - } - - event = grub_zalloc (sizeof (grub_efi_cc_event_t) + - grub_strlen (description) + 1); - if (event == NULL) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate CC event buffer")); - return; - } - - event->Header.HeaderSize = sizeof (grub_efi_cc_event_header_t); - event->Header.HeaderVersion = GRUB_EFI_CC_EVENT_HEADER_VERSION; - event->Header.MrIndex = mr; - event->Header.EventType = EV_IPL; - event->Size = sizeof (*event) + grub_strlen (description) + 1; - grub_strcpy ((char *) event->Event, description); - - status = cc->hash_log_extend_event (cc, 0, - (grub_efi_physical_address_t)(grub_addr_t) buf, - (grub_efi_uint64_t) size, event); - grub_free (event); - - if (status != GRUB_EFI_SUCCESS) - grub_efi_log_event_status (status); -} - -grub_err_t -grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, - const char *description) -{ - grub_efi_handle_t tpm_handle; - grub_efi_uint8_t protocol_version; - - grub_cc_log_event(buf, size, pcr, description); - - if (!grub_tpm_handle_find (&tpm_handle, &protocol_version)) - return 0; - - grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n", - pcr, size, description); - - if (protocol_version == 1) - return grub_tpm1_log_event (tpm_handle, buf, size, pcr, description); - else - return grub_tpm2_log_event (tpm_handle, buf, size, pcr, description); -} - -int -grub_tpm_present (void) -{ - grub_efi_handle_t tpm_handle; - grub_efi_uint8_t protocol_version; - grub_efi_cc_protocol_t *cc; - - /* - * When confidential computing measurement protocol is enabled - * we assume the TPM is present. - */ - cc = grub_efi_locate_protocol (&cc_measurement_guid, NULL); - if (cc != NULL) - return 1; - - if (!grub_tpm_handle_find (&tpm_handle, &protocol_version)) - return 0; - - if (protocol_version == 1) - { - grub_efi_tpm_protocol_t *tpm; - - tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (!tpm) - { - grub_dprintf ("tpm", "Cannot open TPM protocol\n"); - return 0; - } - return grub_tpm1_present (tpm); - } - else - { - grub_efi_tpm2_protocol_t *tpm; - - tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (!tpm) - { - grub_dprintf ("tpm", "Cannot open TPM protocol\n"); - return 0; - } - return grub_tpm2_present (tpm); - } -} diff --git a/grub-core/commands/eval.c b/grub-core/commands/eval.c deleted file mode 100644 index f826a4f22..000000000 --- a/grub-core/commands/eval.c +++ /dev/null @@ -1,71 +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 . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -grub_cmd_eval (grub_command_t cmd __attribute__((__unused__)), - int argc, char *argv[]) -{ - int i; - grub_size_t size = argc; /* +1 for final zero */ - char *str, *p; - grub_err_t ret; - - if (argc == 0) - return GRUB_ERR_NONE; - - for (i = 0; i < argc; i++) - size += grub_strlen (argv[i]); - - str = p = grub_malloc (size); - if (!str) - return grub_errno; - - for (i = 0; i < argc; i++) - { - p = grub_stpcpy (p, argv[i]); - *p++ = ' '; - } - *--p = '\0'; - - ret = grub_script_execute_sourcecode (str); - grub_free (str); - return ret; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(eval) -{ - cmd = grub_register_command ("eval", grub_cmd_eval, N_("STRING ..."), - N_("Evaluate arguments as GRUB commands")); -} - -GRUB_MOD_FINI(eval) -{ - grub_unregister_command (cmd); -} - diff --git a/grub-core/commands/extcmd.c b/grub-core/commands/extcmd.c deleted file mode 100644 index c236be13a..000000000 --- a/grub-core/commands/extcmd.c +++ /dev/null @@ -1,144 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -grub_err_t -grub_extcmd_dispatcher (struct grub_command *cmd, int argc, char **args, - struct grub_script *script) -{ - int new_argc; - char **new_args; - struct grub_arg_list *state; - struct grub_extcmd_context context; - grub_err_t ret; - grub_extcmd_t ext = cmd->data; - - context.state = 0; - context.extcmd = ext; - context.script = script; - - if (! ext->options) - { - ret = (ext->func) (&context, argc, args); - return ret; - } - - state = grub_arg_list_alloc (ext, argc, args); - if (state == NULL) - return grub_errno; - - if (grub_arg_parse (ext, argc, args, state, &new_args, &new_argc)) - { - context.state = state; - ret = (ext->func) (&context, new_argc, new_args); - grub_free (new_args); - grub_free (state); - return ret; - } - - grub_free (state); - return grub_errno; -} - -static grub_err_t -grub_extcmd_dispatch (struct grub_command *cmd, int argc, char **args) -{ - return grub_extcmd_dispatcher (cmd, argc, args, 0); -} - -grub_extcmd_t -grub_register_extcmd_prio (const char *name, grub_extcmd_func_t func, - grub_command_flags_t flags, const char *summary, - const char *description, - const struct grub_arg_option *parser, - int prio) -{ - 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_dispatch, - summary, description, prio); - 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; -} - -grub_extcmd_t -grub_register_extcmd (const char *name, grub_extcmd_func_t func, - grub_command_flags_t flags, const char *summary, - const char *description, - const struct grub_arg_option *parser) -{ - return grub_register_extcmd_prio (name, func, flags, - summary, description, parser, 1); -} - -static grub_err_t -grub_extcmd_lockdown (grub_extcmd_context_t ctxt __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **argv __attribute__ ((unused))) -{ - return grub_error (GRUB_ERR_ACCESS_DENIED, - N_("%s: the command is not allowed when lockdown is enforced"), - ctxt->extcmd->cmd->name); -} - -grub_extcmd_t -grub_register_extcmd_lockdown (const char *name, grub_extcmd_func_t func, - grub_command_flags_t flags, const char *summary, - const char *description, - const struct grub_arg_option *parser) -{ - if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED) - func = grub_extcmd_lockdown; - - return grub_register_extcmd (name, func, flags, summary, description, parser); -} - -void -grub_unregister_extcmd (grub_extcmd_t ext) -{ - grub_unregister_command (ext->cmd); - grub_free (ext); -} diff --git a/grub-core/commands/file.c b/grub-core/commands/file.c deleted file mode 100644 index 19602d757..000000000 --- a/grub-core/commands/file.c +++ /dev/null @@ -1,707 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static const struct grub_arg_option options[] = { - {"is-i386-xen-pae-domu", 0, 0, - N_("Check if FILE can be booted as i386 PAE Xen unprivileged guest kernel"), - 0, 0}, - {"is-x86_64-xen-domu", 0, 0, - N_("Check if FILE can be booted as x86_64 Xen unprivileged guest kernel"), 0, 0}, - {"is-x86-xen-dom0", 0, 0, - N_("Check if FILE can be used as Xen x86 privileged guest kernel"), 0, 0}, - {"is-x86-multiboot", 0, 0, - N_("Check if FILE can be used as x86 multiboot kernel"), 0, 0}, - {"is-x86-multiboot2", 0, 0, - N_("Check if FILE can be used as x86 multiboot2 kernel"), 0, 0}, - {"is-arm-linux", 0, 0, - N_("Check if FILE is ARM Linux"), 0, 0}, - {"is-arm64-linux", 0, 0, - N_("Check if FILE is ARM64 Linux"), 0, 0}, - {"is-ia64-linux", 0, 0, - N_("Check if FILE is IA64 Linux"), 0, 0}, - {"is-mips-linux", 0, 0, - N_("Check if FILE is MIPS Linux"), 0, 0}, - {"is-mipsel-linux", 0, 0, - N_("Check if FILE is MIPSEL Linux"), 0, 0}, - {"is-sparc64-linux", 0, 0, - N_("Check if FILE is SPARC64 Linux"), 0, 0}, - {"is-powerpc-linux", 0, 0, - N_("Check if FILE is POWERPC Linux"), 0, 0}, - {"is-x86-linux", 0, 0, - N_("Check if FILE is x86 Linux"), 0, 0}, - {"is-x86-linux32", 0, 0, - N_("Check if FILE is x86 Linux supporting 32-bit protocol"), 0, 0}, - {"is-x86-kfreebsd", 0, 0, - N_("Check if FILE is x86 kFreeBSD"), 0, 0}, - {"is-i386-kfreebsd", 0, 0, - N_("Check if FILE is i386 kFreeBSD"), 0, 0}, - {"is-x86_64-kfreebsd", 0, 0, - N_("Check if FILE is x86_64 kFreeBSD"), 0, 0}, - - {"is-x86-knetbsd", 0, 0, - N_("Check if FILE is x86 kNetBSD"), 0, 0}, - {"is-i386-knetbsd", 0, 0, - N_("Check if FILE is i386 kNetBSD"), 0, 0}, - {"is-x86_64-knetbsd", 0, 0, - N_("Check if FILE is x86_64 kNetBSD"), 0, 0}, - - {"is-i386-efi", 0, 0, - N_("Check if FILE is i386 EFI file"), 0, 0}, - {"is-x86_64-efi", 0, 0, - N_("Check if FILE is x86_64 EFI file"), 0, 0}, - {"is-ia64-efi", 0, 0, - N_("Check if FILE is IA64 EFI file"), 0, 0}, - {"is-arm64-efi", 0, 0, - N_("Check if FILE is ARM64 EFI file"), 0, 0}, - {"is-arm-efi", 0, 0, - N_("Check if FILE is ARM EFI file"), 0, 0}, - {"is-riscv32-efi", 0, 0, - N_("Check if FILE is RISC-V 32bit EFI file"), 0, 0}, - {"is-riscv64-efi", 0, 0, - N_("Check if FILE is RISC-V 64bit EFI file"), 0, 0}, - {"is-hibernated-hiberfil", 0, 0, - N_("Check if FILE is hiberfil.sys in hibernated state"), 0, 0}, - {"is-x86_64-xnu", 0, 0, - N_("Check if FILE is x86_64 XNU (Mac OS X kernel)"), 0, 0}, - {"is-i386-xnu", 0, 0, - N_("Check if FILE is i386 XNU (Mac OS X kernel)"), 0, 0}, - {"is-xnu-hibr", 0, 0, - N_("Check if FILE is XNU (Mac OS X kernel) hibernated image"), 0, 0}, - {"is-x86-bios-bootsector", 0, 0, - N_("Check if FILE is BIOS bootsector"), 0, 0}, - {0, 0, 0, 0, 0, 0} -}; - -enum -{ - IS_PAE_DOMU, - IS_64_DOMU, - IS_DOM0, - IS_MULTIBOOT, - IS_MULTIBOOT2, - IS_ARM_LINUX, - IS_ARM64_LINUX, - IS_IA64_LINUX, - IS_MIPS_LINUX, - IS_MIPSEL_LINUX, - IS_SPARC64_LINUX, - IS_POWERPC_LINUX, - IS_X86_LINUX, - IS_X86_LINUX32, - IS_X86_KFREEBSD, - IS_X86_KFREEBSD32, - IS_X86_KFREEBSD64, - IS_X86_KNETBSD, - IS_X86_KNETBSD32, - IS_X86_KNETBSD64, - IS_32_EFI, - IS_64_EFI, - IS_IA_EFI, - IS_ARM64_EFI, - IS_ARM_EFI, - IS_RISCV32_EFI, - IS_RISCV64_EFI, - IS_HIBERNATED, - IS_XNU64, - IS_XNU32, - IS_XNU_HIBR, - IS_BIOS_BOOTSECTOR, - OPT_TYPE_MIN = IS_PAE_DOMU, - OPT_TYPE_MAX = IS_BIOS_BOOTSECTOR -}; - - -static grub_err_t -grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args) -{ - grub_file_t file = 0; - grub_elf_t elf = 0; - grub_err_t err; - int type = -1, i; - int ret = 0; - grub_macho_t macho = 0; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - for (i = OPT_TYPE_MIN; i <= OPT_TYPE_MAX; i++) - if (ctxt->state[i].set) - { - if (type == -1) - { - type = i; - continue; - } - return grub_error (GRUB_ERR_BAD_ARGUMENT, "multiple types specified"); - } - if (type == -1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no type specified"); - - file = grub_file_open (args[0], GRUB_FILE_TYPE_XNU_KERNEL); - if (!file) - return grub_errno; - switch (type) - { - case IS_BIOS_BOOTSECTOR: - { - grub_uint16_t sig; - if (grub_file_size (file) != 512) - break; - if (grub_file_seek (file, 510) == (grub_size_t) -1) - break; - if (grub_file_read (file, &sig, 2) != 2) - break; - if (sig != grub_cpu_to_le16_compile_time (0xaa55)) - break; - ret = 1; - break; - } - case IS_IA64_LINUX: - { - Elf64_Ehdr ehdr; - - if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr)) - break; - - 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_ident[EI_VERSION] != EV_CURRENT - || ehdr.e_version != EV_CURRENT) - break; - - if (ehdr.e_ident[EI_CLASS] != ELFCLASS64 - || ehdr.e_ident[EI_DATA] != ELFDATA2LSB - || ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_IA_64)) - break; - - ret = 1; - - break; - } - - case IS_SPARC64_LINUX: - { - Elf64_Ehdr ehdr; - - if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr)) - break; - - 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_ident[EI_VERSION] != EV_CURRENT - || ehdr.e_version != EV_CURRENT) - break; - - if (ehdr.e_ident[EI_CLASS] != ELFCLASS64 - || ehdr.e_ident[EI_DATA] != ELFDATA2MSB) - break; - - if (ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_SPARCV9) - || ehdr.e_type != grub_cpu_to_be16_compile_time (ET_EXEC)) - break; - - ret = 1; - - break; - } - - case IS_POWERPC_LINUX: - { - Elf32_Ehdr ehdr; - - if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr)) - break; - - 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_ident[EI_VERSION] != EV_CURRENT - || ehdr.e_version != EV_CURRENT) - break; - - if (ehdr.e_ident[EI_DATA] != ELFDATA2MSB - || (ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_PPC) - && ehdr.e_machine != - grub_cpu_to_le16_compile_time (EM_PPC64))) - break; - - if (ehdr.e_type != grub_cpu_to_be16_compile_time (ET_EXEC) - && ehdr.e_type != grub_cpu_to_be16_compile_time (ET_DYN)) - break; - - ret = 1; - - break; - } - - case IS_MIPS_LINUX: - { - Elf32_Ehdr ehdr; - - if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr)) - break; - - 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_ident[EI_VERSION] != EV_CURRENT - || ehdr.e_version != EV_CURRENT) - break; - - if (ehdr.e_ident[EI_DATA] != ELFDATA2MSB - || ehdr.e_machine != grub_cpu_to_be16_compile_time (EM_MIPS) - || ehdr.e_type != grub_cpu_to_be16_compile_time (ET_EXEC)) - break; - - ret = 1; - - break; - } - - case IS_X86_KNETBSD: - case IS_X86_KNETBSD32: - case IS_X86_KNETBSD64: - { - int is32, is64; - - elf = grub_elf_file (file, file->name); - - if (elf == NULL) - break; - if (elf->ehdr.ehdr32.e_type != grub_cpu_to_le16_compile_time (ET_EXEC) - || elf->ehdr.ehdr32.e_ident[EI_DATA] != ELFDATA2LSB) - break; - - is32 = grub_elf_is_elf32 (elf); - is64 = grub_elf_is_elf64 (elf); - if (!is32 && !is64) - break; - if (!is32 && type == IS_X86_KNETBSD32) - break; - if (!is64 && type == IS_X86_KNETBSD64) - break; - if (is64) - ret = grub_file_check_netbsd64 (elf); - if (is32) - ret = grub_file_check_netbsd32 (elf); - break; - } - - case IS_X86_KFREEBSD: - case IS_X86_KFREEBSD32: - case IS_X86_KFREEBSD64: - { - Elf32_Ehdr ehdr; - int is32, is64; - - if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr)) - break; - - 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_ident[EI_VERSION] != EV_CURRENT - || ehdr.e_version != EV_CURRENT) - break; - - if (ehdr.e_type != grub_cpu_to_le16_compile_time (ET_EXEC) - || ehdr.e_ident[EI_DATA] != ELFDATA2LSB) - break; - - if (ehdr.e_ident[EI_OSABI] != ELFOSABI_FREEBSD) - break; - - is32 = (ehdr.e_machine == grub_cpu_to_le16_compile_time (EM_386) - && ehdr.e_ident[EI_CLASS] == ELFCLASS32); - is64 = (ehdr.e_machine == grub_cpu_to_le16_compile_time (EM_X86_64) - && ehdr.e_ident[EI_CLASS] == ELFCLASS64); - if (!is32 && !is64) - break; - if (!is32 && (type == IS_X86_KFREEBSD32 || type == IS_X86_KNETBSD32)) - break; - if (!is64 && (type == IS_X86_KFREEBSD64 || type == IS_X86_KNETBSD64)) - break; - ret = 1; - - break; - } - - - case IS_MIPSEL_LINUX: - { - Elf32_Ehdr ehdr; - - if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr)) - break; - - 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_ident[EI_VERSION] != EV_CURRENT - || ehdr.e_version != EV_CURRENT) - break; - - if (ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_MIPS) - || ehdr.e_type != grub_cpu_to_le16_compile_time (ET_EXEC)) - break; - - ret = 1; - - break; - } - case IS_ARM_LINUX: - { - struct linux_arch_kernel_header lh; - - if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) - break; - /* Short forward branch in A32 state (for Raspberry pi kernels). */ - if (lh.code0 == grub_cpu_to_le32_compile_time (0xea000006)) - { - ret = 1; - break; - } - - if (lh.magic == - grub_cpu_to_le32_compile_time (GRUB_LINUX_ARM_MAGIC_SIGNATURE)) - { - ret = 1; - break; - } - break; - } - case IS_ARM64_LINUX: - { - struct linux_arch_kernel_header lh; - - if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) - break; - - /* - * The PE/COFF header can be anywhere in the file. Load it from the correct - * offset if it is not where it is expected. - */ - if ((grub_uint8_t *) &lh + lh.hdr_offset != (grub_uint8_t *) &lh.pe_image_header) - { - if (grub_file_seek (file, lh.hdr_offset) == (grub_off_t) -1 - || grub_file_read (file, &lh.pe_image_header, sizeof (struct grub_pe_image_header)) - != sizeof (struct grub_pe_image_header)) - return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image header"); - } - - if (lh.pe_image_header.coff_header.machine == grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_ARM64)) - { - ret = 1; - break; - } - break; - } - case IS_PAE_DOMU ... IS_DOM0: - { - struct grub_xen_file_info xen_inf; - elf = grub_xen_file (file); - if (!elf) - break; - err = grub_xen_get_info (elf, &xen_inf); - if (err) - break; - /* Unfortuntely no way to check if kernel supports dom0. */ - if (type == IS_DOM0) - ret = 1; - if (type == IS_PAE_DOMU) - ret = (xen_inf.arch == GRUB_XEN_FILE_I386_PAE - || xen_inf.arch == GRUB_XEN_FILE_I386_PAE_BIMODE); - if (type == IS_64_DOMU) - ret = (xen_inf.arch == GRUB_XEN_FILE_X86_64); - break; - } - case IS_MULTIBOOT: - case IS_MULTIBOOT2: - { - grub_uint32_t *buffer; - grub_ssize_t len; - grub_size_t search_size; - grub_uint32_t *header; - grub_uint32_t magic; - grub_size_t step; - - if (type == IS_MULTIBOOT2) - { - search_size = 32768; - magic = grub_cpu_to_le32_compile_time (0xe85250d6); - step = 2; - } - else - { - search_size = 8192; - magic = grub_cpu_to_le32_compile_time (0x1BADB002); - step = 1; - } - - buffer = grub_malloc (search_size); - if (!buffer) - break; - - len = grub_file_read (file, buffer, search_size); - if (len < 32) - { - grub_free (buffer); - break; - } - - /* 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 = buffer; - ((char *) header <= - (char *) buffer + len - (type == IS_MULTIBOOT2 ? 16 : 12)); - header += step) - { - if (header[0] == magic - && !(grub_le_to_cpu32 (header[0]) - + grub_le_to_cpu32 (header[1]) - + grub_le_to_cpu32 (header[2]) - + (type == IS_MULTIBOOT2 - ? grub_le_to_cpu32 (header[3]) : 0))) - { - ret = 1; - break; - } - } - - grub_free (buffer); - break; - } - case IS_X86_LINUX32: - case IS_X86_LINUX: - { - struct linux_i386_kernel_header lh; - if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) - break; - if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55)) - break; - - if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) - break; - - /* FIXME: some really old kernels (< 1.3.73) will fail this. */ - if (lh.header != - grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) - || grub_le_to_cpu16 (lh.version) < 0x0200) - break; - - if (type == IS_X86_LINUX) - { - ret = 1; - break; - } - - /* 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_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) - || grub_le_to_cpu16 (lh.version) < 0x0203) - break; - - if (!(lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL)) - break; - ret = 1; - break; - } - case IS_HIBERNATED: - { - grub_uint8_t hibr_file_magic[4]; - if (grub_file_read (file, &hibr_file_magic, sizeof (hibr_file_magic)) - != sizeof (hibr_file_magic)) - break; - if (grub_memcmp ("hibr", hibr_file_magic, sizeof (hibr_file_magic)) == - 0 - || grub_memcmp ("HIBR", hibr_file_magic, - sizeof (hibr_file_magic)) == 0) - ret = 1; - break; - } - case IS_XNU64: - case IS_XNU32: - { - macho = grub_macho_open (args[0], GRUB_FILE_TYPE_XNU_KERNEL, - (type == IS_XNU64)); - if (!macho) - break; - /* FIXME: more checks? */ - ret = 1; - break; - } - case IS_XNU_HIBR: - { - struct grub_xnu_hibernate_header hibhead; - if (grub_file_read (file, &hibhead, sizeof (hibhead)) - != sizeof (hibhead)) - break; - if (hibhead.magic != - grub_cpu_to_le32_compile_time (GRUB_XNU_HIBERNATE_MAGIC)) - break; - ret = 1; - break; - } - case IS_32_EFI: - case IS_64_EFI: - case IS_IA_EFI: - case IS_ARM64_EFI: - case IS_ARM_EFI: - case IS_RISCV32_EFI: - case IS_RISCV64_EFI: - { - char signature[4]; - grub_uint32_t pe_offset; - struct grub_pe32_coff_header coff_head; - - if (grub_file_read (file, signature, 2) != 2) - break; - if (signature[0] != 'M' || signature[1] != 'Z') - break; - if ((grub_ssize_t) grub_file_seek (file, 0x3c) == -1) - break; - if (grub_file_read (file, &pe_offset, 4) != 4) - break; - if ((grub_ssize_t) grub_file_seek (file, grub_le_to_cpu32 (pe_offset)) - == -1) - break; - if (grub_file_read (file, signature, 4) != 4) - break; - if (signature[0] != 'P' || signature[1] != 'E' - || signature[2] != '\0' || signature[3] != '\0') - break; - - if (grub_file_read (file, &coff_head, sizeof (coff_head)) - != sizeof (coff_head)) - break; - if (type == IS_32_EFI - && coff_head.machine != - grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_I386)) - break; - if (type == IS_64_EFI - && coff_head.machine != - grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_X86_64)) - break; - if (type == IS_IA_EFI - && coff_head.machine != - grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_IA64)) - break; - if (type == IS_ARM64_EFI - && coff_head.machine != - grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_ARM64)) - break; - if (type == IS_ARM_EFI - && coff_head.machine != - grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_ARMTHUMB_MIXED)) - break; - if ((type == IS_RISCV32_EFI || type == IS_RISCV64_EFI) - && coff_head.machine != - grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_RISCV64)) - /* TODO: Determine bitness dynamically */ - break; - if (type == IS_IA_EFI || type == IS_64_EFI || type == IS_ARM64_EFI || - type == IS_RISCV32_EFI || type == IS_RISCV64_EFI) - { - struct grub_pe64_optional_header o64; - if (grub_file_read (file, &o64, sizeof (o64)) != sizeof (o64)) - break; - if (o64.magic != - grub_cpu_to_le16_compile_time (GRUB_PE32_PE64_MAGIC)) - break; - if (o64.subsystem != - grub_cpu_to_le16_compile_time - (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION)) - break; - ret = 1; - break; - } - if (type == IS_32_EFI || type == IS_ARM_EFI) - { - struct grub_pe32_optional_header o32; - if (grub_file_read (file, &o32, sizeof (o32)) != sizeof (o32)) - break; - if (o32.magic != - grub_cpu_to_le16_compile_time (GRUB_PE32_PE32_MAGIC)) - break; - if (o32.subsystem != - grub_cpu_to_le16_compile_time - (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION)) - break; - ret = 1; - break; - } - break; - } - } - - if (elf) - grub_elf_close (elf); - else if (macho) - grub_macho_close (macho); - else if (file) - grub_file_close (file); - - if (!ret && (grub_errno == GRUB_ERR_BAD_OS || grub_errno == GRUB_ERR_NONE)) - /* TRANSLATORS: it's a standalone boolean value, - opposite of "true". */ - grub_error (GRUB_ERR_TEST_FAILURE, N_("false")); - return grub_errno; -} - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT(file) -{ - cmd = grub_register_extcmd ("file", grub_cmd_file, 0, - N_("OPTIONS FILE"), - N_("Check if FILE is of specified type."), - options); -} - -GRUB_MOD_FINI(file) -{ - grub_unregister_extcmd (cmd); -} diff --git a/grub-core/commands/file32.c b/grub-core/commands/file32.c deleted file mode 100644 index 0861c458d..000000000 --- a/grub-core/commands/file32.c +++ /dev/null @@ -1,5 +0,0 @@ -#define GRUB_TARGET_WORDSIZE 32 -#define XX 32 -#define ehdrXX ehdr32 -#define grub_file_check_netbsdXX grub_file_check_netbsd32 -#include "fileXX.c" diff --git a/grub-core/commands/file64.c b/grub-core/commands/file64.c deleted file mode 100644 index 90890d481..000000000 --- a/grub-core/commands/file64.c +++ /dev/null @@ -1,5 +0,0 @@ -#define GRUB_TARGET_WORDSIZE 64 -#define XX 64 -#define ehdrXX ehdr64 -#define grub_file_check_netbsdXX grub_file_check_netbsd64 -#include "fileXX.c" diff --git a/grub-core/commands/fileXX.c b/grub-core/commands/fileXX.c deleted file mode 100644 index c17d26ce6..000000000 --- a/grub-core/commands/fileXX.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -#pragma GCC diagnostic ignored "-Wcast-align" - -int -grub_file_check_netbsdXX (grub_elf_t elf) -{ - Elf_Shdr *s, *s0; - - grub_size_t shnum = elf->ehdr.ehdrXX.e_shnum; - grub_size_t shentsize = elf->ehdr.ehdrXX.e_shentsize; - grub_size_t shsize = shnum * shentsize; - grub_off_t stroff; - - if (!shnum || !shentsize) - return 0; - - s0 = grub_malloc (shsize); - if (!s0) - return 0; - - if (grub_file_seek (elf->file, elf->ehdr.ehdrXX.e_shoff) == (grub_off_t) -1) - goto fail; - - if (grub_file_read (elf->file, s0, shsize) != (grub_ssize_t) shsize) - goto fail; - - s = (Elf_Shdr *) ((char *) s0 + elf->ehdr.ehdrXX.e_shstrndx * shentsize); - stroff = s->sh_offset; - - for (s = s0; s < (Elf_Shdr *) ((char *) s0 + shnum * shentsize); - s = (Elf_Shdr *) ((char *) s + shentsize)) - { - char name[sizeof(".note.netbsd.ident")]; - grub_memset (name, 0, sizeof (name)); - if (grub_file_seek (elf->file, stroff + s->sh_name) == (grub_off_t) -1) - goto fail; - - if (grub_file_read (elf->file, name, sizeof (name)) != (grub_ssize_t) sizeof (name)) - { - if (grub_errno) - goto fail; - continue; - } - if (grub_memcmp (name, ".note.netbsd.ident", - sizeof(".note.netbsd.ident")) != 0) - continue; - grub_free (s0); - return 1; - } - fail: - grub_free (s0); - return 0; -} diff --git a/grub-core/commands/help.c b/grub-core/commands/help.c deleted file mode 100644 index 113d0d0ca..000000000 --- a/grub-core/commands/help.c +++ /dev/null @@ -1,155 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -grub_cmd_help (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc, - char **args) -{ - int cnt = 0; - char *currarg; - - if (argc == 0) - { - grub_command_t cmd; - FOR_COMMANDS(cmd) - { - if ((cmd->prio & GRUB_COMMAND_FLAG_ACTIVE)) - { - 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) - break; - - 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)) - { - struct grub_unicode_glyph glyph; - unicode_last_screen_position - += grub_unicode_aglomerate_comb (unicode_last_screen_position, - unicode_last_position - - unicode_last_screen_position, - &glyph); - - stringwidth - += grub_term_getcharwidth (term, &glyph); - } - - grub_print_ucs4 (unicode_command_help, - unicode_last_screen_position, 0, 0, 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); - } - } - if (!(cnt % 2)) - grub_printf ("\n"); - } - else - { - int i; - grub_command_t cmd_iter, cmd, cmd_next; - - for (i = 0; i < argc; i++) - { - currarg = args[i]; - - FOR_COMMANDS_SAFE (cmd_iter, cmd_next) - { - if (!(cmd_iter->prio & GRUB_COMMAND_FLAG_ACTIVE)) - continue; - - if (grub_strncmp (cmd_iter->name, currarg, - grub_strlen (currarg)) != 0) - continue; - if (cmd_iter->flags & GRUB_COMMAND_FLAG_DYNCMD) - cmd = grub_dyncmd_get_cmd (cmd_iter); - else - cmd = cmd_iter; - if (!cmd) - { - grub_print_error (); - continue; - } - if (cnt++ > 0) - grub_printf ("\n\n"); - - if ((cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) && - ! (cmd->flags & GRUB_COMMAND_FLAG_DYNCMD)) - 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)); - } - } - } - - grub_printf ("\n\nTo enable less(1)-like paging, \"set pager=1\".\n"); - - return 0; -} - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT(help) -{ - cmd = grub_register_extcmd ("help", grub_cmd_help, 0, - N_("[PATTERN ...]"), - N_("Show a help message."), 0); -} - -GRUB_MOD_FINI(help) -{ - grub_unregister_extcmd (cmd); -} diff --git a/grub-core/commands/i386/cmostest.c b/grub-core/commands/i386/cmostest.c deleted file mode 100644 index 1f0c5341d..000000000 --- a/grub-core/commands/i386/cmostest.c +++ /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 . - */ - -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -parse_args (int argc, char *argv[], int *byte, int *bit) -{ - const char *rest; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "address required"); - - *byte = grub_strtoul (argv[0], &rest, 0); - if (*rest != ':') - return grub_error (GRUB_ERR_BAD_ARGUMENT, "address required"); - - *bit = grub_strtoul (rest + 1, 0, 0); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - int byte = 0, bit = 0; - grub_err_t err; - grub_uint8_t value; - - err = parse_args (argc, argv, &byte, &bit); - if (err) - return err; - - err = grub_cmos_read (byte, &value); - if (err) - return err; - - if (value & (1 << bit)) - return GRUB_ERR_NONE; - - return grub_error (GRUB_ERR_TEST_FAILURE, N_("false")); -} - -static grub_err_t -grub_cmd_cmosclean (struct grub_command *cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - int byte = 0, bit = 0; - grub_err_t err; - grub_uint8_t value; - - err = parse_args (argc, argv, &byte, &bit); - if (err) - return err; - err = grub_cmos_read (byte, &value); - if (err) - return err; - - return grub_cmos_write (byte, value & (~(1 << bit))); -} - -static grub_err_t -grub_cmd_cmosset (struct grub_command *cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - int byte = 0, bit = 0; - grub_err_t err; - grub_uint8_t value; - - err = parse_args (argc, argv, &byte, &bit); - if (err) - return err; - err = grub_cmos_read (byte, &value); - if (err) - return err; - - return grub_cmos_write (byte, value | (1 << bit)); -} - -static grub_command_t cmd, cmd_clean, cmd_set; - - -GRUB_MOD_INIT(cmostest) -{ - cmd = grub_register_command_lockdown ("cmostest", grub_cmd_cmostest, - N_("BYTE:BIT"), - N_("Test bit at BYTE:BIT in CMOS.")); - cmd_clean = grub_register_command_lockdown ("cmosclean", grub_cmd_cmosclean, - N_("BYTE:BIT"), - N_("Clear bit at BYTE:BIT in CMOS.")); - cmd_set = grub_register_command_lockdown ("cmosset", grub_cmd_cmosset, - N_("BYTE:BIT"), - /* TRANSLATORS: A bit may be either set (1) or clear (0). */ - N_("Set bit at BYTE:BIT in CMOS.")); -} - -GRUB_MOD_FINI(cmostest) -{ - grub_unregister_command (cmd); - grub_unregister_command (cmd_clean); - grub_unregister_command (cmd_set); -} diff --git a/grub-core/commands/i386/coreboot/cb_timestamps.c b/grub-core/commands/i386/coreboot/cb_timestamps.c deleted file mode 100644 index c44abb3fa..000000000 --- a/grub-core/commands/i386/coreboot/cb_timestamps.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_uint32_t -tsc2ms (grub_uint64_t tsc) -{ - grub_uint64_t ah = tsc >> 32; - grub_uint64_t al = tsc & 0xffffffff; - - return ((al * grub_tsc_rate) >> 32) + ah * grub_tsc_rate; -} - -static const char *descs[] = { - [1] = "romstage", - [2] = "before RAM init", - [3] = "after RAM init", - [4] = "end of romstage", - [5] = "start of verified boot", - [6] = "end of verified boot", - [8] = "start of RAM copy", - [9] = "end of RAM copy", - [10] = "start of ramstage", - [11] = "start of bootblock", - [12] = "end of bootblock", - [13] = "starting to load romstage", - [14] = "finished loading romstage", - [15] = "starting LZMA decompress (ignore for x86)", - [16] = "finished LZMA decompress (ignore for x86)", - [30] = "device enumerate", - [40] = "device configure", - [50] = "device enable", - [60] = "device initialize", - [70] = "device done", - [75] = "CBMEM POST", - [80] = "writing tables", - [90] = "loading payload", - [98] = "wake jump", - [99] = "selfboot jump", -}; - -static int -iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, - void *data) -{ - int *available = data; - grub_uint64_t last_tsc = 0; - struct grub_linuxbios_timestamp_table *ts_table; - unsigned i; - - if (table_item->tag != GRUB_LINUXBIOS_MEMBER_TIMESTAMPS) - return 0; - - *available = 1; - ts_table = (struct grub_linuxbios_timestamp_table *) (grub_addr_t) - *(grub_uint64_t *) (table_item + 1); - - for (i = 0; i < ts_table->used; i++) - { - grub_uint32_t tmabs = tsc2ms (ts_table->entries[i].tsc); - grub_uint32_t tmrel = tsc2ms (ts_table->entries[i].tsc - last_tsc); - last_tsc = ts_table->entries[i].tsc; - - grub_printf ("%3d.%03ds %2d.%03ds %02d %s\n", - tmabs / 1000, tmabs % 1000, tmrel / 1000, tmrel % 1000, - ts_table->entries[i].id, - (ts_table->entries[i].id < ARRAY_SIZE (descs) - && descs[ts_table->entries[i].id]) - ? descs[ts_table->entries[i].id] : ""); - } - return 1; -} - - -static grub_err_t -grub_cmd_coreboot_boottime (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char *argv[] __attribute__ ((unused))) -{ - int available = 0; - - grub_linuxbios_table_iterate (iterate_linuxbios_table, &available); - if (!available) - { - grub_puts_ (N_("No boot time statistics is available\n")); - return 0; - } - return 0; -} - -static grub_command_t cmd_boottime; - -GRUB_MOD_INIT(cbtime) -{ - cmd_boottime = - grub_register_command ("coreboot_boottime", grub_cmd_coreboot_boottime, - 0, N_("Show coreboot boot time statistics.")); -} - -GRUB_MOD_FINI(cbtime) -{ - grub_unregister_command (cmd_boottime); -} diff --git a/grub-core/commands/i386/coreboot/cbls.c b/grub-core/commands/i386/coreboot/cbls.c deleted file mode 100644 index 50b7b8750..000000000 --- a/grub-core/commands/i386/coreboot/cbls.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static const char *console_descs[] = { - "8250 UART", - "VGA", - "BTEXT", - "log buffer console", - "SROM", - "EHCI debug", - "memory-mapped 8250 UART" -}; - -static const char *descs[] = { - [GRUB_LINUXBIOS_MEMBER_MEMORY] = "memory map (`lsmmap' to list)", - [GRUB_LINUXBIOS_MEMBER_MAINBOARD] = "mainboard", - [4] = "version", - [5] = "extra version", - [6] = "build", - [7] = "compile time", - [8] = "compile by", - [9] = "compile host", - [0xa] = "compile domain", - [0xb] = "compiler", - [0xc] = "linker", - [0xd] = "assembler", - [0xf] = "serial", - [GRUB_LINUXBIOS_MEMBER_CONSOLE] = "console", - [GRUB_LINUXBIOS_MEMBER_FRAMEBUFFER] = "framebuffer", - [0x13] = "GPIO", - [0x15] = "VDAT", - [GRUB_LINUXBIOS_MEMBER_TIMESTAMPS] = "timestamps (`coreboot_boottime' to list)", - [GRUB_LINUXBIOS_MEMBER_CBMEMC] = "CBMEM console (`cbmemc' to list)", - [0x18] = "MRC cache", - [0x19] = "VBNV", - [0xc8] = "CMOS option table", - [0xc9] = "CMOS option", - [0xca] = "CMOS option enum", - [0xcb] = "CMOS option defaults", - [0xcc] = "CMOS checksum", -}; - -static int -iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, - void *data __attribute__ ((unused))) -{ - if (table_item->tag < ARRAY_SIZE (descs) && descs[table_item->tag]) - grub_printf ("tag=%02x size=%02x %s", - table_item->tag, table_item->size, descs[table_item->tag]); - else - grub_printf ("tag=%02x size=%02x", - table_item->tag, table_item->size); - - switch (table_item->tag) - { - case GRUB_LINUXBIOS_MEMBER_FRAMEBUFFER: - { - struct grub_linuxbios_table_framebuffer *fb; - fb = (struct grub_linuxbios_table_framebuffer *) (table_item + 1); - - grub_printf (": %dx%dx%d pitch=%d lfb=0x%llx %d/%d/%d/%d %d/%d/%d/%d", - fb->width, fb->height, - fb->bpp, fb->pitch, - (unsigned long long) fb->lfb, - fb->red_mask_size, fb->green_mask_size, - fb->blue_mask_size, fb->reserved_mask_size, - fb->red_field_pos, fb->green_field_pos, - fb->blue_field_pos, fb->reserved_field_pos); - break; - } - case GRUB_LINUXBIOS_MEMBER_MAINBOARD: - { - struct grub_linuxbios_mainboard *mb; - mb = (struct grub_linuxbios_mainboard *) (table_item + 1); - grub_printf (": vendor=`%s' part_number=`%s'", - mb->strings + mb->vendor, - mb->strings + mb->part_number); - break; - } - case 0x04 ... 0x0d: - grub_printf (": `%s'", (char *) (table_item + 1)); - break; - case GRUB_LINUXBIOS_MEMBER_CONSOLE: - { - grub_uint16_t *val = (grub_uint16_t *) (table_item + 1); - grub_printf (": id=%d", *val); - if (*val < ARRAY_SIZE (console_descs) - && console_descs[*val]) - grub_printf (" %s", console_descs[*val]); - } - } - grub_printf ("\n"); - - return 0; -} - - -static grub_err_t -grub_cmd_lscoreboot (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char *argv[] __attribute__ ((unused))) -{ - grub_linuxbios_table_iterate (iterate_linuxbios_table, 0); - return 0; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(cbls) -{ - cmd = - grub_register_command ("lscoreboot", grub_cmd_lscoreboot, - 0, N_("List coreboot tables.")); -} - -GRUB_MOD_FINI(cbls) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/commands/i386/pc/halt.c b/grub-core/commands/i386/pc/halt.c deleted file mode 100644 index e87e8dccd..000000000 --- a/grub-core/commands/i386/pc/halt.c +++ /dev/null @@ -1,126 +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 . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -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 inline void __attribute__ ((noreturn)) -stop (void) -{ - while (1) - { - asm volatile ("hlt"); - } -} -/* - * Halt the system, using APM if possible. If NO_APM is true, don't use - * APM even if it is available. - */ -void __attribute__ ((noreturn)) -grub_halt (int no_apm) -{ - struct grub_bios_int_registers regs; - - grub_acpi_halt (); - - if (no_apm) - stop (); - - /* detect APM */ - regs.eax = 0x5300; - regs.ebx = 0; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x15, ®s); - - if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY) - stop (); - - /* disconnect APM first */ - regs.eax = 0x5304; - regs.ebx = 0; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x15, ®s); - - /* connect APM */ - regs.eax = 0x5301; - regs.ebx = 0; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x15, ®s); - if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY) - stop (); - - /* set APM protocol level - 1.1 or bust. (this covers APM 1.2 also) */ - regs.eax = 0x530E; - regs.ebx = 0; - regs.ecx = 0x0101; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x15, ®s); - if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY) - stop (); - - /* set the power state to off */ - regs.eax = 0x5307; - regs.ebx = 1; - regs.ecx = 3; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x15, ®s); - - /* shouldn't reach here */ - stop (); -} - -static grub_err_t __attribute__ ((noreturn)) -grub_cmd_halt (grub_extcmd_context_t ctxt, - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) - -{ - struct grub_arg_list *state = ctxt->state; - int no_apm = 0; - - if (state[0].set) - no_apm = 1; - grub_halt (no_apm); -} - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT(halt) -{ - cmd = grub_register_extcmd ("halt", grub_cmd_halt, 0, "[-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/lsapm.c b/grub-core/commands/i386/pc/lsapm.c deleted file mode 100644 index 8f49880da..000000000 --- a/grub-core/commands/i386/pc/lsapm.c +++ /dev/null @@ -1,115 +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 . - */ - -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -int -grub_apm_get_info (struct grub_apm_info *info) -{ - struct grub_bios_int_registers regs; - - /* detect APM */ - regs.eax = 0x5300; - regs.ebx = 0; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x15, ®s); - - if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY) - return 0; - info->version = regs.eax & 0xffff; - info->flags = regs.ecx & 0xffff; - - /* disconnect APM first */ - regs.eax = 0x5304; - regs.ebx = 0; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x15, ®s); - - /* connect APM */ - regs.eax = 0x5303; - regs.ebx = 0; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x15, ®s); - - if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY) - return 0; - - info->cseg = regs.eax & 0xffff; - info->offset = regs.ebx; - info->cseg_16 = regs.ecx & 0xffff; - info->dseg = regs.edx & 0xffff; - info->cseg_len = regs.esi >> 16; - info->cseg_16_len = regs.esi & 0xffff; - info->dseg_len = regs.edi; - - return 1; -} - -static grub_err_t -grub_cmd_lsapm (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) -{ - struct grub_apm_info info; - if (!grub_apm_get_info (&info)) - return grub_error (GRUB_ERR_IO, N_("no APM found")); - - grub_printf_ (N_("Version %u.%u\n" - "32-bit CS = 0x%x, len = 0x%x, offset = 0x%x\n" - "16-bit CS = 0x%x, len = 0x%x\n" - "DS = 0x%x, len = 0x%x\n"), - info.version >> 8, info.version & 0xff, - info.cseg, info.cseg_len, info.offset, - info.cseg_16, info.cseg_16_len, - info.dseg, info.dseg_len); - grub_xputs (info.flags & GRUB_APM_FLAGS_16BITPROTECTED_SUPPORTED - ? _("16-bit protected interface supported\n") - : _("16-bit protected interface unsupported\n")); - grub_xputs (info.flags & GRUB_APM_FLAGS_32BITPROTECTED_SUPPORTED - ? _("32-bit protected interface supported\n") - : _("32-bit protected interface unsupported\n")); - grub_xputs (info.flags & GRUB_APM_FLAGS_CPUIDLE_SLOWS_DOWN - ? _("CPU Idle slows down processor\n") - : _("CPU Idle doesn't slow down processor\n")); - grub_xputs (info.flags & GRUB_APM_FLAGS_DISABLED - ? _("APM disabled\n") : _("APM enabled\n")); - grub_xputs (info.flags & GRUB_APM_FLAGS_DISENGAGED - ? _("APM disengaged\n") : _("APM engaged\n")); - - return GRUB_ERR_NONE; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(lsapm) -{ - cmd = grub_register_command ("lsapm", grub_cmd_lsapm, 0, - N_("Show APM information.")); -} - -GRUB_MOD_FINI(lsapm) -{ - grub_unregister_command (cmd); -} - - diff --git a/grub-core/commands/i386/pc/play.c b/grub-core/commands/i386/pc/play.c deleted file mode 100644 index 7ff8cd633..000000000 --- a/grub-core/commands/i386/pc/play.c +++ /dev/null @@ -1,197 +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 . - */ - -/* Lots of this file is borrowed from GNU/Hurd generic-speaker driver. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define BASE_TEMPO (60 * 1000) - - -#define T_REST ((grub_uint16_t) 0) -#define T_FINE ((grub_uint16_t) -1) - -struct note -{ - grub_uint16_t pitch; - grub_uint16_t duration; -}; - -/* Returns whether playing should continue. */ -static int -play (unsigned tempo, struct note *note) -{ - grub_uint64_t to; - - if (note->pitch == T_FINE || grub_getkey_noblock () != GRUB_TERM_NO_KEY) - return 1; - - grub_dprintf ("play", "pitch = %d, duration = %d\n", note->pitch, - note->duration); - - switch (note->pitch) - { - case T_REST: - grub_speaker_beep_off (); - break; - - default: - grub_speaker_beep_on (note->pitch); - break; - } - - to = grub_get_time_ms () + BASE_TEMPO * note->duration / tempo; - while ((grub_get_time_ms () <= to) - && (grub_getkey_noblock () == GRUB_TERM_NO_KEY)); - - 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, - /* TRANSLATORS: It's musical notes, not the notes - you take. Play command expects arguments which can - be either a filename or tempo+notes. - This error happens if none is specified. */ - N_("filename or tempo and notes expected")); - - if (argc == 1) - { - struct note buf; - grub_uint32_t tempo; - grub_file_t file; - - file = grub_file_open (args[0], GRUB_FILE_TYPE_AUDIO); - - if (! file) - return grub_errno; - - if (grub_file_read (file, &tempo, sizeof (tempo)) != sizeof (tempo)) - { - grub_file_close (file); - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - args[0]); - return grub_errno; - } - - if (!tempo) - { - grub_file_close (file); - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid tempo in %s"), - args[0]); - return grub_errno; - } - - 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 - { - const char *end; - unsigned tempo; - struct note note; - int i; - - tempo = grub_strtoul (args[0], &end, 0); - - if (!tempo) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid tempo in %s"), - args[0]); - return grub_errno; - } - - if (*end) - /* Was not a number either, assume it was supposed to be a file name. */ - return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), args[0]); - - grub_dprintf ("play","tempo = %d\n", tempo); - - for (i = 1; i + 1 < argc; i += 2) - { - note.pitch = grub_strtoul (args[i], &end, 0); - if (grub_errno) - break; - if (*end) - { - grub_error (GRUB_ERR_BAD_NUMBER, N_("unrecognized number")); - break; - } - - note.duration = grub_strtoul (args[i + 1], &end, 0); - if (grub_errno) - break; - if (*end) - { - grub_error (GRUB_ERR_BAD_NUMBER, N_("unrecognized number")); - break; - } - - if (play (tempo, ¬e)) - break; - } - } - - grub_speaker_beep_off (); - - return 0; -} - -static grub_command_t cmd; - -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/sendkey.c b/grub-core/commands/i386/pc/sendkey.c deleted file mode 100644 index 282bb5d42..000000000 --- a/grub-core/commands/i386/pc/sendkey.c +++ /dev/null @@ -1,387 +0,0 @@ -/* sendkey.c - fake keystroke. */ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv2+"); - -static char sendkey[0x20]; -/* Length of sendkey. */ -static int keylen = 0; -static int noled = 0; -static const struct grub_arg_option options[] = - { - {"num", 'n', 0, N_("set numlock mode"), "[on|off]", ARG_TYPE_STRING}, - {"caps", 'c', 0, N_("set capslock mode"), "[on|off]", ARG_TYPE_STRING}, - {"scroll", 's', 0, N_("set scrolllock mode"), "[on|off]", ARG_TYPE_STRING}, - {"insert", 0, 0, N_("set insert mode"), "[on|off]", ARG_TYPE_STRING}, - {"pause", 0, 0, N_("set pause mode"), "[on|off]", ARG_TYPE_STRING}, - {"left-shift", 0, 0, N_("press left shift"), "[on|off]", ARG_TYPE_STRING}, - {"right-shift", 0, 0, N_("press right shift"), "[on|off]", ARG_TYPE_STRING}, - {"sysrq", 0, 0, N_("press SysRq"), "[on|off]", ARG_TYPE_STRING}, - {"numkey", 0, 0, N_("press NumLock key"), "[on|off]", ARG_TYPE_STRING}, - {"capskey", 0, 0, N_("press CapsLock key"), "[on|off]", ARG_TYPE_STRING}, - {"scrollkey", 0, 0, N_("press ScrollLock key"), "[on|off]", ARG_TYPE_STRING}, - {"insertkey", 0, 0, N_("press Insert key"), "[on|off]", ARG_TYPE_STRING}, - {"left-alt", 0, 0, N_("press left alt"), "[on|off]", ARG_TYPE_STRING}, - {"right-alt", 0, 0, N_("press right alt"), "[on|off]", ARG_TYPE_STRING}, - {"left-ctrl", 0, 0, N_("press left ctrl"), "[on|off]", ARG_TYPE_STRING}, - {"right-ctrl", 0, 0, N_("press right ctrl"), "[on|off]", ARG_TYPE_STRING}, - {"no-led", 0, 0, N_("don't update LED state"), 0, 0}, - {0, 0, 0, 0, 0, 0} - }; -static int simple_flag_offsets[] -= {5, 6, 4, 7, 11, 1, 0, 10, 13, 14, 12, 15, 9, 3, 8, 2}; - -static grub_uint32_t andmask = 0xffffffff, ormask = 0; - -struct -keysym -{ - const char *unshifted_name; /* the name in unshifted state */ - const char *shifted_name; /* the name in shifted state */ - unsigned char unshifted_ascii; /* the ascii code in unshifted state */ - unsigned char shifted_ascii; /* the ascii code in shifted state */ - unsigned char keycode; /* keyboard scancode */ -}; - -/* The table for key symbols. If the "shifted" member of an entry is - NULL, the entry does not have shifted state. Copied from GRUB Legacy setkey fuction */ -static struct keysym keysym_table[] = -{ - {"escape", 0, 0x1b, 0, 0x01}, - {"1", "exclam", '1', '!', 0x02}, - {"2", "at", '2', '@', 0x03}, - {"3", "numbersign", '3', '#', 0x04}, - {"4", "dollar", '4', '$', 0x05}, - {"5", "percent", '5', '%', 0x06}, - {"6", "caret", '6', '^', 0x07}, - {"7", "ampersand", '7', '&', 0x08}, - {"8", "asterisk", '8', '*', 0x09}, - {"9", "parenleft", '9', '(', 0x0a}, - {"0", "parenright", '0', ')', 0x0b}, - {"minus", "underscore", '-', '_', 0x0c}, - {"equal", "plus", '=', '+', 0x0d}, - {"backspace", 0, '\b', 0, 0x0e}, - {"tab", 0, '\t', 0, 0x0f}, - {"q", "Q", 'q', 'Q', 0x10}, - {"w", "W", 'w', 'W', 0x11}, - {"e", "E", 'e', 'E', 0x12}, - {"r", "R", 'r', 'R', 0x13}, - {"t", "T", 't', 'T', 0x14}, - {"y", "Y", 'y', 'Y', 0x15}, - {"u", "U", 'u', 'U', 0x16}, - {"i", "I", 'i', 'I', 0x17}, - {"o", "O", 'o', 'O', 0x18}, - {"p", "P", 'p', 'P', 0x19}, - {"bracketleft", "braceleft", '[', '{', 0x1a}, - {"bracketright", "braceright", ']', '}', 0x1b}, - {"enter", 0, '\r', 0, 0x1c}, - {"control", 0, 0, 0, 0x1d}, - {"a", "A", 'a', 'A', 0x1e}, - {"s", "S", 's', 'S', 0x1f}, - {"d", "D", 'd', 'D', 0x20}, - {"f", "F", 'f', 'F', 0x21}, - {"g", "G", 'g', 'G', 0x22}, - {"h", "H", 'h', 'H', 0x23}, - {"j", "J", 'j', 'J', 0x24}, - {"k", "K", 'k', 'K', 0x25}, - {"l", "L", 'l', 'L', 0x26}, - {"semicolon", "colon", ';', ':', 0x27}, - {"quote", "doublequote", '\'', '"', 0x28}, - {"backquote", "tilde", '`', '~', 0x29}, - {"shift", 0, 0, 0, 0x2a}, - {"backslash", "bar", '\\', '|', 0x2b}, - {"z", "Z", 'z', 'Z', 0x2c}, - {"x", "X", 'x', 'X', 0x2d}, - {"c", "C", 'c', 'C', 0x2e}, - {"v", "V", 'v', 'V', 0x2f}, - {"b", "B", 'b', 'B', 0x30}, - {"n", "N", 'n', 'N', 0x31}, - {"m", "M", 'm', 'M', 0x32}, - {"comma", "less", ',', '<', 0x33}, - {"period", "greater", '.', '>', 0x34}, - {"slash", "question", '/', '?', 0x35}, - {"rshift", 0, 0, 0, 0x36}, - {"numasterisk", 0, '*', 0, 0x37}, - {"alt", 0, 0, 0, 0x38}, - {"space", 0, ' ', 0, 0x39}, - {"capslock", 0, 0, 0, 0x3a}, - {"F1", 0, 0, 0, 0x3b}, - {"F2", 0, 0, 0, 0x3c}, - {"F3", 0, 0, 0, 0x3d}, - {"F4", 0, 0, 0, 0x3e}, - {"F5", 0, 0, 0, 0x3f}, - {"F6", 0, 0, 0, 0x40}, - {"F7", 0, 0, 0, 0x41}, - {"F8", 0, 0, 0, 0x42}, - {"F9", 0, 0, 0, 0x43}, - {"F10", 0, 0, 0, 0x44}, - {"num7", "numhome", '7', 0, 0x47}, - {"num8", "numup", '8', 0, 0x48}, - {"num9", "numpgup", '9', 0, 0x49}, - {"numminus", 0, '-', 0, 0x4a}, - {"num4", "numleft", '4', 0, 0x4b}, - {"num5", "numcenter", '5', 0, 0x4c}, - {"num6", "numright", '6', 0, 0x4d}, - {"numplus", 0, '-', 0, 0x4e}, - {"num1", "numend", '1', 0, 0x4f}, - {"num2", "numdown", '2', 0, 0x50}, - {"num3", "numpgdown", '3', 0, 0x51}, - {"num0", "numinsert", '0', 0, 0x52}, - {"numperiod", "numdelete", 0, 0x7f, 0x53}, - {"F11", 0, 0, 0, 0x57}, - {"F12", 0, 0, 0, 0x58}, - {"numenter", 0, '\r', 0, 0xe0}, - {"numslash", 0, '/', 0, 0xe0}, - {"delete", 0, 0x7f, 0, 0xe0}, - {"insert", 0, 0xe0, 0, 0x52}, - {"home", 0, 0xe0, 0, 0x47}, - {"end", 0, 0xe0, 0, 0x4f}, - {"pgdown", 0, 0xe0, 0, 0x51}, - {"pgup", 0, 0xe0, 0, 0x49}, - {"down", 0, 0xe0, 0, 0x50}, - {"up", 0, 0xe0, 0, 0x48}, - {"left", 0, 0xe0, 0, 0x4b}, - {"right", 0, 0xe0, 0, 0x4d} -}; - -/* Set a simple flag in flags variable - OUTOFFSET - offset of flag in FLAGS, - OP - action id -*/ -static void -grub_sendkey_set_simple_flag (int outoffset, int op) -{ - if (op == 2) - { - andmask |= (1 << outoffset); - ormask &= ~(1 << outoffset); - } - else - { - andmask &= (~(1 << outoffset)); - if (op == 1) - ormask |= (1 << outoffset); - else - ormask &= ~(1 << outoffset); - } -} - -static int -grub_sendkey_parse_op (struct grub_arg_list state) -{ - if (! state.set) - return 2; - - if (grub_strcmp (state.arg, "off") == 0 || grub_strcmp (state.arg, "0") == 0 - || grub_strcmp (state.arg, "unpress") == 0) - return 0; - - if (grub_strcmp (state.arg, "on") == 0 || grub_strcmp (state.arg, "1") == 0 - || grub_strcmp (state.arg, "press") == 0) - return 1; - - return 2; -} - -static grub_uint32_t oldflags; - -static grub_err_t -grub_sendkey_postboot (void) -{ - /* For convention: pointer to flags. */ - grub_uint32_t *flags = grub_absolute_pointer (0x417); - - *flags = oldflags; - - *((volatile char *) grub_absolute_pointer (0x41a)) = 0x1e; - *((volatile char *) grub_absolute_pointer (0x41c)) = 0x1e; - - return GRUB_ERR_NONE; -} - -/* Set keyboard buffer to our sendkey */ -static grub_err_t -grub_sendkey_preboot (int noret __attribute__ ((unused))) -{ - /* For convention: pointer to flags. */ - grub_uint32_t *flags = grub_absolute_pointer (0x417); - - oldflags = *flags; - - /* Set the sendkey. */ - *((volatile char *) grub_absolute_pointer (0x41a)) = 0x1e; - *((volatile char *) grub_absolute_pointer (0x41c)) = keylen + 0x1e; - grub_memcpy ((char *) 0x41e, sendkey, 0x20); - - /* Transform "any ctrl" to "right ctrl" flag. */ - if (*flags & (1 << 8)) - *flags &= ~(1 << 2); - - /* Transform "any alt" to "right alt" flag. */ - if (*flags & (1 << 9)) - *flags &= ~(1 << 3); - - *flags = (*flags & andmask) | ormask; - - /* Transform "right ctrl" to "any ctrl" flag. */ - if (*flags & (1 << 8)) - *flags |= (1 << 2); - - /* Transform "right alt" to "any alt" flag. */ - if (*flags & (1 << 9)) - *flags |= (1 << 3); - - /* Write new LED state */ - if (!noled) - { - int value = 0; - int failed; - /* Try 5 times */ - for (failed = 0; failed < 5; failed++) - { - value = 0; - /* Send command change LEDs */ - grub_outb (0xed, 0x60); - - /* Wait */ - do - value = grub_inb (0x60); - while ((value != 0xfa) && (value != 0xfe)); - - if (value == 0xfa) - { - /* Set new LEDs*/ - grub_outb ((*flags >> 4) & 7, 0x60); - break; - } - } - } - return GRUB_ERR_NONE; -} - -/* Helper for grub_cmd_sendkey. */ -static int -find_key_code (char *key) -{ - unsigned i; - - for (i = 0; i < ARRAY_SIZE(keysym_table); i++) - { - if (keysym_table[i].unshifted_name - && grub_strcmp (key, keysym_table[i].unshifted_name) == 0) - return keysym_table[i].keycode; - else if (keysym_table[i].shifted_name - && grub_strcmp (key, keysym_table[i].shifted_name) == 0) - return keysym_table[i].keycode; - } - - return 0; -} - -/* Helper for grub_cmd_sendkey. */ -static int -find_ascii_code (char *key) -{ - unsigned i; - - for (i = 0; i < ARRAY_SIZE(keysym_table); i++) - { - if (keysym_table[i].unshifted_name - && grub_strcmp (key, keysym_table[i].unshifted_name) == 0) - return keysym_table[i].unshifted_ascii; - else if (keysym_table[i].shifted_name - && grub_strcmp (key, keysym_table[i].shifted_name) == 0) - return keysym_table[i].shifted_ascii; - } - - return 0; -} - -static grub_err_t -grub_cmd_sendkey (grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_arg_list *state = ctxt->state; - - andmask = 0xffffffff; - ormask = 0; - - { - int i; - - keylen = 0; - - for (i = 0; i < argc && keylen < 0x20; i++) - { - int key_code; - - key_code = find_key_code (args[i]); - if (key_code) - { - sendkey[keylen++] = find_ascii_code (args[i]); - sendkey[keylen++] = key_code; - } - } - } - - { - unsigned i; - for (i = 0; i < ARRAY_SIZE(simple_flag_offsets); i++) - grub_sendkey_set_simple_flag (simple_flag_offsets[i], - grub_sendkey_parse_op(state[i])); - } - - /* Set noled. */ - noled = (state[ARRAY_SIZE(simple_flag_offsets)].set); - - return GRUB_ERR_NONE; -} - -static grub_extcmd_t cmd; -static struct grub_preboot *preboot_hook; - -GRUB_MOD_INIT (sendkey) -{ - cmd = grub_register_extcmd ("sendkey", grub_cmd_sendkey, 0, - N_("[KEYSTROKE1] [KEYSTROKE2] ..."), - /* TRANSLATORS: It can emulate multiple - keypresses. */ - N_("Emulate a keystroke sequence"), options); - - preboot_hook - = grub_loader_register_preboot_hook (grub_sendkey_preboot, - grub_sendkey_postboot, - GRUB_LOADER_PREBOOT_HOOK_PRIO_CONSOLE); -} - -GRUB_MOD_FINI (sendkey) -{ - grub_unregister_extcmd (cmd); - grub_loader_unregister_preboot_hook (preboot_hook); -} diff --git a/grub-core/commands/i386/pc/smbios.c b/grub-core/commands/i386/pc/smbios.c deleted file mode 100644 index 069d66367..000000000 --- a/grub-core/commands/i386/pc/smbios.c +++ /dev/null @@ -1,52 +0,0 @@ -/* smbios.c - get smbios tables. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2019 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -struct grub_smbios_eps * -grub_machine_smbios_get_eps (void) -{ - grub_uint8_t *ptr; - - grub_dprintf ("smbios", "Looking for SMBIOS EPS. Scanning BIOS\n"); - - for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16) - if (grub_memcmp (ptr, "_SM_", 4) == 0 - && grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps)) == 0) - return (struct grub_smbios_eps *) ptr; - - return 0; -} - -struct grub_smbios_eps3 * -grub_machine_smbios_get_eps3 (void) -{ - grub_uint8_t *ptr; - - grub_dprintf ("smbios", "Looking for SMBIOS3 EPS. Scanning BIOS\n"); - - for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16) - if (grub_memcmp (ptr, "_SM3_", 5) == 0 - && grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps3)) == 0) - return (struct grub_smbios_eps3 *) ptr; - - return 0; -} diff --git a/grub-core/commands/i386/rdmsr.c b/grub-core/commands/i386/rdmsr.c deleted file mode 100644 index 2e42f6197..000000000 --- a/grub-core/commands/i386/rdmsr.c +++ /dev/null @@ -1,91 +0,0 @@ -/* rdmsr.c - Read CPU model-specific registers. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2019 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE("GPLv3+"); - -static grub_extcmd_t cmd_read; - -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_msr_read (grub_extcmd_context_t ctxt, int argc, char **argv) -{ - grub_err_t err; - grub_uint32_t addr; - grub_uint64_t value; - const char *ptr; - char buf[sizeof("1122334455667788")]; - - err = grub_cpu_is_msr_supported (); - - if (err != GRUB_ERR_NONE) - return grub_error (err, N_("RDMSR is unsupported")); - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - - grub_errno = GRUB_ERR_NONE; - ptr = argv[0]; - addr = grub_strtoul (ptr, &ptr, 0); - - if (grub_errno != GRUB_ERR_NONE) - return grub_errno; - if (*ptr != '\0') - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument")); - - value = grub_rdmsr (addr); - - if (ctxt->state[0].set) - { - grub_snprintf (buf, sizeof(buf), "%llx", (unsigned long long) value); - grub_env_set (ctxt->state[0].arg, buf); - } - else - grub_printf ("0x%llx\n", (unsigned long long) value); - - return GRUB_ERR_NONE; -} - -GRUB_MOD_INIT(rdmsr) -{ - cmd_read = grub_register_extcmd ("rdmsr", grub_cmd_msr_read, 0, N_("ADDR"), - N_("Read a CPU model specific register."), - options); -} - -GRUB_MOD_FINI(rdmsr) -{ - grub_unregister_extcmd (cmd_read); -} diff --git a/grub-core/commands/i386/wrmsr.c b/grub-core/commands/i386/wrmsr.c deleted file mode 100644 index 7fbedaed9..000000000 --- a/grub-core/commands/i386/wrmsr.c +++ /dev/null @@ -1,83 +0,0 @@ -/* wrmsr.c - Write CPU model-specific registers. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2019 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE("GPLv3+"); - -static grub_command_t cmd_write; - -static grub_err_t -grub_cmd_msr_write (grub_command_t cmd __attribute__ ((unused)), int argc, char **argv) -{ - grub_err_t err; - grub_uint32_t addr; - grub_uint64_t value; - const char *ptr; - - err = grub_cpu_is_msr_supported (); - - if (err != GRUB_ERR_NONE) - return grub_error (err, N_("WRMSR is unsupported")); - - if (argc != 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); - - grub_errno = GRUB_ERR_NONE; - ptr = argv[0]; - addr = grub_strtoul (ptr, &ptr, 0); - - if (grub_errno != GRUB_ERR_NONE) - return grub_errno; - if (*ptr != '\0') - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument")); - - ptr = argv[1]; - value = grub_strtoull (ptr, &ptr, 0); - - if (grub_errno != GRUB_ERR_NONE) - return grub_errno; - if (*ptr != '\0') - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument")); - - grub_wrmsr (addr, value); - - return GRUB_ERR_NONE; -} - -GRUB_MOD_INIT(wrmsr) -{ - cmd_write = grub_register_command_lockdown ("wrmsr", grub_cmd_msr_write, N_("ADDR VALUE"), - N_("Write a value to a CPU model specific register.")); -} - -GRUB_MOD_FINI(wrmsr) -{ - grub_unregister_command (cmd_write); -} diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c deleted file mode 100644 index 4958b04a9..000000000 --- a/grub-core/commands/ieee1275/ibmvtpm.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Free Software Foundation, Inc. - * Copyright (C) 2022 IBM Corporation - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - * - * IBM vTPM support code. - */ - -#include -#include -#include -#include -#include -#include -#include - -static int -ibmvtpm_2hash_ext_log (grub_uint8_t pcrindex, - grub_uint32_t eventtype, - const char *description, - grub_size_t description_size, - void *buf, grub_size_t size) -{ - struct tpm_2hash_ext_log - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t method; - grub_ieee1275_cell_t ihandle; - grub_ieee1275_cell_t size; - grub_ieee1275_cell_t buf; - grub_ieee1275_cell_t description_size; - grub_ieee1275_cell_t description; - grub_ieee1275_cell_t eventtype; - grub_ieee1275_cell_t pcrindex; - grub_ieee1275_cell_t catch_result; - grub_ieee1275_cell_t rc; - }; - struct tpm_2hash_ext_log args; - - INIT_IEEE1275_COMMON (&args.common, "call-method", 8, 2); - args.method = (grub_ieee1275_cell_t) "2hash-ext-log"; - args.ihandle = grub_ieee1275_tpm_ihandle; - args.pcrindex = pcrindex; - args.eventtype = eventtype; - args.description = (grub_ieee1275_cell_t) description; - args.description_size = description_size; - args.buf = (grub_ieee1275_cell_t) buf; - args.size = (grub_ieee1275_cell_t) size; - - if (IEEE1275_CALL_ENTRY_FN (&args) == -1) - return -1; - - /* - * catch_result is set if firmware does not support 2hash-ext-log - * rc is GRUB_IEEE1275_CELL_FALSE (0) on failure - */ - if ((args.catch_result) || args.rc == GRUB_IEEE1275_CELL_FALSE) - return -1; - - return 0; -} - -static grub_err_t -tpm2_log_event (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, - const char *description) -{ - static int error_displayed = 0; - int rc; - - rc = ibmvtpm_2hash_ext_log (pcr, EV_IPL, - description, grub_strlen(description) + 1, - buf, size); - if (rc && !error_displayed) - { - error_displayed++; - return grub_error (GRUB_ERR_BAD_DEVICE, - "2HASH-EXT-LOG failed: Firmware is likely too old.\n"); - } - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, - const char *description) -{ - grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n", - pcr, size, description); - - if (grub_ieee1275_tpm_ihandle != GRUB_IEEE1275_IHANDLE_INVALID) - return tpm2_log_event (buf, size, pcr, description); - - return GRUB_ERR_NONE; -} - -int -grub_tpm_present (void) -{ - /* - * Call tpm_init() "late" rather than from GRUB_MOD_INIT() so that device nodes - * can be found. - */ - return grub_ieee1275_tpm_init() == GRUB_ERR_NONE; -} diff --git a/grub-core/commands/iorw.c b/grub-core/commands/iorw.c deleted file mode 100644 index 584baec8f..000000000 --- a/grub-core/commands/iorw.c +++ /dev/null @@ -1,156 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -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_context_t ctxt, int argc, char **argv) -{ - grub_port_t addr; - grub_uint32_t value = 0; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - - addr = grub_strtoul (argv[0], 0, 0); - switch (ctxt->extcmd->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 (ctxt->state[0].set) - { - char buf[sizeof ("XXXXXXXX")]; - grub_snprintf (buf, sizeof (buf), "%x", value); - grub_env_set (ctxt->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_port_t addr; - grub_uint32_t value; - grub_uint32_t mask = 0xffffffff; - - if (argc != 2 && argc != 3) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); - - 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, 0, - N_("PORT"), N_("Read 8-bit value from PORT."), - options); - cmd_read_word = - grub_register_extcmd ("inw", grub_cmd_read, 0, - N_("PORT"), N_("Read 16-bit value from PORT."), - options); - cmd_read_dword = - grub_register_extcmd ("inl", grub_cmd_read, 0, - N_("PORT"), N_("Read 32-bit value from PORT."), - options); - cmd_write_byte = - grub_register_command_lockdown ("outb", grub_cmd_write, - N_("PORT VALUE [MASK]"), - N_("Write 8-bit VALUE to PORT.")); - cmd_write_word = - grub_register_command_lockdown ("outw", grub_cmd_write, - N_("PORT VALUE [MASK]"), - N_("Write 16-bit VALUE to PORT.")); - cmd_write_dword = - grub_register_command_lockdown ("outl", grub_cmd_write, - N_("ADDR VALUE [MASK]"), - N_("Write 32-bit 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/keylayouts.c b/grub-core/commands/keylayouts.c deleted file mode 100644 index aa3ba34f2..000000000 --- a/grub-core/commands/keylayouts.c +++ /dev/null @@ -1,307 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static struct grub_keyboard_layout layout_us = { - .keyboard_map = { - /* Keyboard errors. Handled by driver. */ - /* 0x00 */ 0, 0, 0, 0, - - /* 0x04 */ 'a', 'b', 'c', 'd', - /* 0x08 */ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - /* 0x10 */ 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - /* 0x18 */ 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', - /* 0x20 */ '3', '4', '5', '6', '7', '8', '9', '0', - /* 0x28 */ '\n', GRUB_TERM_ESC, GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, ' ', '-', '=', '[', - /* According to usage table 0x31 should be mapped to '/' - but testing with real keyboard shows that 0x32 is remapped to '/'. - Map 0x31 to 0. - */ - /* 0x30 */ ']', 0, '\\', ';', '\'', '`', ',', '.', - /* 0x39 is CapsLock. Handled by driver. */ - /* 0x38 */ '/', 0, GRUB_TERM_KEY_F1, GRUB_TERM_KEY_F2, - /* 0x3c */ GRUB_TERM_KEY_F3, GRUB_TERM_KEY_F4, - /* 0x3e */ GRUB_TERM_KEY_F5, GRUB_TERM_KEY_F6, - /* 0x40 */ GRUB_TERM_KEY_F7, GRUB_TERM_KEY_F8, - /* 0x42 */ GRUB_TERM_KEY_F9, GRUB_TERM_KEY_F10, - /* 0x44 */ GRUB_TERM_KEY_F11, GRUB_TERM_KEY_F12, - /* PrtScr and ScrollLock. Not handled yet. */ - /* 0x46 */ 0, 0, - /* 0x48 is Pause. Not handled yet. */ - /* 0x48 */ 0, GRUB_TERM_KEY_INSERT, - /* 0x4a */ GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_PPAGE, - /* 0x4c */ GRUB_TERM_KEY_DC, GRUB_TERM_KEY_END, - /* 0x4e */ GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_RIGHT, - /* 0x50 */ GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_DOWN, - /* 0x53 is NumLock. Handled by driver. */ - /* 0x52 */ GRUB_TERM_KEY_UP, 0, - /* 0x54 */ '/', '*', - /* 0x56 */ '-', '+', - /* 0x58 */ '\n', GRUB_TERM_KEY_END, - /* 0x5a */ GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_NPAGE, - /* 0x5c */ GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_CENTER, - /* 0x5e */ GRUB_TERM_KEY_RIGHT, GRUB_TERM_KEY_HOME, - /* 0x60 */ GRUB_TERM_KEY_UP, GRUB_TERM_KEY_PPAGE, - /* 0x62 */ GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC, - /* 0x64 */ '\\' - }, - .keyboard_map_shift = { - /* Keyboard errors. Handled by driver. */ - /* 0x00 */ 0, 0, 0, 0, - - /* 0x04 */ 'A', 'B', 'C', 'D', - /* 0x08 */ 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - /* 0x10 */ 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - /* 0x18 */ 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', - /* 0x20 */ '#', '$', '%', '^', '&', '*', '(', ')', - /* 0x28 */ '\n' | GRUB_TERM_SHIFT, GRUB_TERM_ESC | GRUB_TERM_SHIFT, - /* 0x2a */ GRUB_TERM_BACKSPACE | GRUB_TERM_SHIFT, GRUB_TERM_TAB | GRUB_TERM_SHIFT, - /* 0x2c */ ' ' | GRUB_TERM_SHIFT, '_', '+', '{', - /* According to usage table 0x31 should be mapped to '/' - but testing with real keyboard shows that 0x32 is remapped to '/'. - Map 0x31 to 0. - */ - /* 0x30 */ '}', 0, '|', ':', '"', '~', '<', '>', - /* 0x39 is CapsLock. Handled by driver. */ - /* 0x38 */ '?', 0, - /* 0x3a */ GRUB_TERM_KEY_F1 | GRUB_TERM_SHIFT, - /* 0x3b */ GRUB_TERM_KEY_F2 | GRUB_TERM_SHIFT, - /* 0x3c */ GRUB_TERM_KEY_F3 | GRUB_TERM_SHIFT, - /* 0x3d */ GRUB_TERM_KEY_F4 | GRUB_TERM_SHIFT, - /* 0x3e */ GRUB_TERM_KEY_F5 | GRUB_TERM_SHIFT, - /* 0x3f */ GRUB_TERM_KEY_F6 | GRUB_TERM_SHIFT, - /* 0x40 */ GRUB_TERM_KEY_F7 | GRUB_TERM_SHIFT, - /* 0x41 */ GRUB_TERM_KEY_F8 | GRUB_TERM_SHIFT, - /* 0x42 */ GRUB_TERM_KEY_F9 | GRUB_TERM_SHIFT, - /* 0x43 */ GRUB_TERM_KEY_F10 | GRUB_TERM_SHIFT, - /* 0x44 */ GRUB_TERM_KEY_F11 | GRUB_TERM_SHIFT, - /* 0x45 */ GRUB_TERM_KEY_F12 | GRUB_TERM_SHIFT, - /* PrtScr and ScrollLock. Not handled yet. */ - /* 0x46 */ 0, 0, - /* 0x48 is Pause. Not handled yet. */ - /* 0x48 */ 0, GRUB_TERM_KEY_INSERT | GRUB_TERM_SHIFT, - /* 0x4a */ GRUB_TERM_KEY_HOME | GRUB_TERM_SHIFT, - /* 0x4b */ GRUB_TERM_KEY_PPAGE | GRUB_TERM_SHIFT, - /* 0x4c */ GRUB_TERM_KEY_DC | GRUB_TERM_SHIFT, - /* 0x4d */ GRUB_TERM_KEY_END | GRUB_TERM_SHIFT, - /* 0x4e */ GRUB_TERM_KEY_NPAGE | GRUB_TERM_SHIFT, - /* 0x4f */ GRUB_TERM_KEY_RIGHT | GRUB_TERM_SHIFT, - /* 0x50 */ GRUB_TERM_KEY_LEFT | GRUB_TERM_SHIFT, - /* 0x51 */ GRUB_TERM_KEY_DOWN | GRUB_TERM_SHIFT, - /* 0x53 is NumLock. Handled by driver. */ - /* 0x52 */ GRUB_TERM_KEY_UP | GRUB_TERM_SHIFT, 0, - /* 0x54 */ '/', '*', - /* 0x56 */ '-', '+', - /* 0x58 */ '\n' | GRUB_TERM_SHIFT, '1', '2', '3', '4', '5','6', '7', - /* 0x60 */ '8', '9', '0', '.', '|' - } -}; - -static struct grub_keyboard_layout *grub_current_layout = &layout_us; - -static int -map_key_core (int code, int status, int *alt_gr_consumed) -{ - *alt_gr_consumed = 0; - - if (code >= GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) - return 0; - - if (status & GRUB_TERM_STATUS_RALT) - { - if (status & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT)) - { - if (grub_current_layout->keyboard_map_shift_l3[code]) - { - *alt_gr_consumed = 1; - return grub_current_layout->keyboard_map_shift_l3[code]; - } - } - else if (grub_current_layout->keyboard_map_l3[code]) - { - *alt_gr_consumed = 1; - return grub_current_layout->keyboard_map_l3[code]; - } - } - if (status & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT)) - return grub_current_layout->keyboard_map_shift[code]; - else - return grub_current_layout->keyboard_map[code]; -} - -unsigned -grub_term_map_key (grub_keyboard_key_t code, int status) -{ - int alt_gr_consumed = 0; - int key; - - if (code >= 0x59 && code <= 0x63 && (status & GRUB_TERM_STATUS_NUM)) - { - if (status & (GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT)) - status &= ~(GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT); - else - status |= GRUB_TERM_STATUS_RSHIFT; - } - - key = map_key_core (code, status, &alt_gr_consumed); - - if (key == 0 || key == GRUB_TERM_SHIFT) { - grub_printf ("Unknown key 0x%x detected\n", code); - return GRUB_TERM_NO_KEY; - } - - if (status & GRUB_TERM_STATUS_CAPS) - { - if ((key >= 'a') && (key <= 'z')) - key += 'A' - 'a'; - else if ((key >= 'A') && (key <= 'Z')) - key += 'a' - 'A'; - } - - if ((status & GRUB_TERM_STATUS_LALT) || - ((status & GRUB_TERM_STATUS_RALT) && !alt_gr_consumed)) - key |= GRUB_TERM_ALT; - if (status & (GRUB_TERM_STATUS_LCTRL | GRUB_TERM_STATUS_RCTRL)) - key |= GRUB_TERM_CTRL; - - return key; -} - -static grub_err_t -grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - char *filename; - grub_file_t file; - grub_uint32_t version; - grub_uint8_t magic[GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE]; - struct grub_keyboard_layout *newmap = NULL; - unsigned i; - - if (argc < 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "file or layout name required"); - if (argv[0][0] != '(' && argv[0][0] != '/' && argv[0][0] != '+') - { - const char *prefix = grub_env_get ("prefix"); - if (!prefix) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("variable `%s' isn't set"), "prefix"); - filename = grub_xasprintf ("%s/layouts/%s.gkb", prefix, argv[0]); - if (!filename) - return grub_errno; - } - else - filename = argv[0]; - - file = grub_file_open (filename, GRUB_FILE_TYPE_KEYBOARD_LAYOUT); - if (! file) - goto fail; - - if (grub_file_read (file, magic, sizeof (magic)) != sizeof (magic)) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("premature end of file %s"), - filename); - goto fail; - } - - if (grub_memcmp (magic, GRUB_KEYBOARD_LAYOUTS_FILEMAGIC, - GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE) != 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid magic"); - goto fail; - } - - if (grub_file_read (file, &version, sizeof (version)) != sizeof (version)) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("premature end of file %s"), - filename); - goto fail; - } - - if (version != grub_cpu_to_le32_compile_time (GRUB_KEYBOARD_LAYOUTS_VERSION)) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid version"); - goto fail; - } - - newmap = grub_malloc (sizeof (*newmap)); - if (!newmap) - goto fail; - - if (grub_file_read (file, newmap, sizeof (*newmap)) != sizeof (*newmap)) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("premature end of file %s"), - filename); - goto fail; - } - - for (i = 0; i < ARRAY_SIZE (newmap->keyboard_map); i++) - newmap->keyboard_map[i] = grub_le_to_cpu32(newmap->keyboard_map[i]); - - for (i = 0; i < ARRAY_SIZE (newmap->keyboard_map_shift); i++) - newmap->keyboard_map_shift[i] - = grub_le_to_cpu32(newmap->keyboard_map_shift[i]); - - for (i = 0; i < ARRAY_SIZE (newmap->keyboard_map_l3); i++) - newmap->keyboard_map_l3[i] - = grub_le_to_cpu32(newmap->keyboard_map_l3[i]); - - for (i = 0; i < ARRAY_SIZE (newmap->keyboard_map_shift_l3); i++) - newmap->keyboard_map_shift_l3[i] - = grub_le_to_cpu32(newmap->keyboard_map_shift_l3[i]); - - grub_current_layout = newmap; - - return GRUB_ERR_NONE; - - fail: - if (filename != argv[0]) - grub_free (filename); - grub_free (newmap); - if (file) - grub_file_close (file); - return grub_errno; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(keylayouts) -{ - cmd = grub_register_command ("keymap", grub_cmd_keymap, - 0, N_("Load a keyboard layout.")); -} - -GRUB_MOD_FINI(keylayouts) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c deleted file mode 100644 index 3bf9fe2e4..000000000 --- a/grub-core/commands/legacycfg.c +++ /dev/null @@ -1,911 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000, 2001, 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* Helper for legacy_file. */ -static grub_err_t -legacy_file_getline (char **line, int cont __attribute__ ((unused)), - void *data __attribute__ ((unused))) -{ - *line = 0; - return GRUB_ERR_NONE; -} - -static grub_err_t -legacy_file (const char *filename) -{ - grub_file_t file; - char *entryname = NULL, *entrysrc = NULL; - grub_menu_t menu; - char *suffix = grub_strdup (""); - - if (!suffix) - return grub_errno; - - file = grub_file_open (filename, GRUB_FILE_TYPE_CONFIG); - if (! file) - { - grub_free (suffix); - return grub_errno; - } - - menu = grub_env_get_menu (); - if (! menu) - { - menu = grub_zalloc (sizeof (*menu)); - if (! menu) - { - grub_free (suffix); - return grub_errno; - } - - grub_env_set_menu (menu); - } - - while (1) - { - char *buf = grub_file_getline (file); - char *parsed = NULL; - - if (!buf && grub_errno) - { - grub_file_close (file); - grub_free (suffix); - return grub_errno; - } - - if (!buf) - break; - - { - char *oldname = NULL; - char *newsuffix; - char *ptr; - - for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); - - oldname = entryname; - parsed = grub_legacy_parse (ptr, &entryname, &newsuffix); - grub_free (buf); - buf = NULL; - if (newsuffix) - { - char *t; - grub_size_t sz; - - if (grub_add (grub_strlen (suffix), grub_strlen (newsuffix), &sz) || - grub_add (sz, 1, &sz)) - { - grub_errno = GRUB_ERR_OUT_OF_RANGE; - goto fail_0; - } - - t = suffix; - suffix = grub_realloc (suffix, sz); - if (!suffix) - { - grub_free (t); - - fail_0: - grub_free (entrysrc); - grub_free (parsed); - grub_free (newsuffix); - grub_free (suffix); - return grub_errno; - } - grub_memcpy (suffix + grub_strlen (suffix), newsuffix, - grub_strlen (newsuffix) + 1); - grub_free (newsuffix); - newsuffix = NULL; - } - if (oldname != entryname && oldname) - { - const char **args = grub_malloc (sizeof (args[0])); - if (!args) - { - grub_file_close (file); - return grub_errno; - } - args[0] = oldname; - grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy", - NULL, NULL, - entrysrc, 0); - grub_free (args); - entrysrc[0] = 0; - grub_free (oldname); - } - } - - if (parsed && !entryname) - { - grub_normal_parse_line (parsed, legacy_file_getline, NULL); - grub_print_error (); - grub_free (parsed); - parsed = NULL; - } - else if (parsed) - { - if (!entrysrc) - entrysrc = parsed; - else - { - char *t; - grub_size_t sz; - - if (grub_add (grub_strlen (entrysrc), grub_strlen (parsed), &sz) || - grub_add (sz, 1, &sz)) - { - grub_errno = GRUB_ERR_OUT_OF_RANGE; - goto fail_1; - } - - t = entrysrc; - entrysrc = grub_realloc (entrysrc, sz); - if (!entrysrc) - { - grub_free (t); - - fail_1: - grub_free (parsed); - grub_free (suffix); - return grub_errno; - } - grub_memcpy (entrysrc + grub_strlen (entrysrc), parsed, - grub_strlen (parsed) + 1); - grub_free (parsed); - parsed = NULL; - } - } - } - grub_file_close (file); - - if (entryname) - { - const char **args = grub_malloc (sizeof (args[0])); - if (!args) - { - grub_free (suffix); - grub_free (entrysrc); - return grub_errno; - } - args[0] = entryname; - grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, - NULL, NULL, entrysrc, 0); - grub_free (args); - } - - grub_normal_parse_line (suffix, legacy_file_getline, NULL); - grub_print_error (); - grub_free (suffix); - grub_free (entrysrc); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_legacy_source (struct grub_command *cmd, - int argc, char **args) -{ - int new_env, extractor; - grub_err_t ret; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - extractor = (cmd->name[0] == 'e'); - new_env = (cmd->name[extractor ? (sizeof ("extract_legacy_entries_") - 1) - : (sizeof ("legacy_") - 1)] == 'c'); - - if (new_env) - grub_cls (); - - if (new_env && !extractor) - grub_env_context_open (); - if (extractor) - grub_env_extractor_open (!new_env); - - ret = legacy_file (args[0]); - - if (new_env) - { - grub_menu_t menu; - menu = grub_env_get_menu (); - if (menu && menu->size) - grub_show_menu (menu, 1, 0); - if (!extractor) - grub_env_context_close (); - } - if (extractor) - grub_env_extractor_close (!new_env); - - return ret; -} - -static enum - { - GUESS_IT, LINUX, MULTIBOOT, KFREEBSD, KNETBSD, KOPENBSD - } kernel_type; - -static grub_err_t -grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), - int argc, char **args) -{ - int i; -#ifdef TODO - int no_mem_option = 0; -#endif - struct grub_command *cmd; - char **cutargs; - int cutargc; - grub_err_t err = GRUB_ERR_NONE; - - for (i = 0; i < 2; i++) - { - /* FIXME: really support this. */ - if (argc >= 1 && grub_strcmp (args[0], "--no-mem-option") == 0) - { -#ifdef TODO - no_mem_option = 1; -#endif - argc--; - args++; - continue; - } - - /* linux16 handles both zImages and bzImages. */ - if (argc >= 1 && (grub_strcmp (args[0], "--type=linux") == 0 - || grub_strcmp (args[0], "--type=biglinux") == 0)) - { - kernel_type = LINUX; - argc--; - args++; - continue; - } - - if (argc >= 1 && grub_strcmp (args[0], "--type=multiboot") == 0) - { - kernel_type = MULTIBOOT; - argc--; - args++; - continue; - } - - if (argc >= 1 && grub_strcmp (args[0], "--type=freebsd") == 0) - { - kernel_type = KFREEBSD; - argc--; - args++; - continue; - } - - if (argc >= 1 && grub_strcmp (args[0], "--type=openbsd") == 0) - { - kernel_type = KOPENBSD; - argc--; - args++; - continue; - } - - if (argc >= 1 && grub_strcmp (args[0], "--type=netbsd") == 0) - { - kernel_type = KNETBSD; - argc--; - args++; - continue; - } - } - - if (argc < 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - cutargs = grub_calloc (argc - 1, sizeof (cutargs[0])); - if (!cutargs) - return grub_errno; - cutargc = argc - 1; - grub_memcpy (cutargs + 1, args + 2, sizeof (cutargs[0]) * (argc - 2)); - cutargs[0] = args[0]; - - do - { - /* First try Linux. */ - if (kernel_type == GUESS_IT || kernel_type == LINUX) - { -#ifdef GRUB_MACHINE_PCBIOS - cmd = grub_command_find ("linux16"); -#else - cmd = grub_command_find ("linux"); -#endif - if (cmd) - { - if (!(cmd->func) (cmd, cutargc, cutargs)) - { - kernel_type = LINUX; - goto out; - } - } - grub_errno = GRUB_ERR_NONE; - } - - /* Then multiboot. */ - if (kernel_type == GUESS_IT || kernel_type == MULTIBOOT) - { - cmd = grub_command_find ("multiboot"); - if (cmd) - { - if (!(cmd->func) (cmd, argc, args)) - { - kernel_type = MULTIBOOT; - goto out; - } - } - grub_errno = GRUB_ERR_NONE; - } - - { - int bsd_device = -1; - int bsd_slice = -1; - int bsd_part = -1; - { - grub_device_t dev; - const char *hdbiasstr; - int hdbias = 0; - hdbiasstr = grub_env_get ("legacy_hdbias"); - if (hdbiasstr) - { - hdbias = grub_strtoul (hdbiasstr, 0, 0); - grub_errno = GRUB_ERR_NONE; - } - dev = grub_device_open (0); - if (dev && dev->disk - && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID - && dev->disk->id >= 0x80 && dev->disk->id <= 0x90) - { - struct grub_partition *part = dev->disk->partition; - bsd_device = dev->disk->id - 0x80 - hdbias; - if (part && (grub_strcmp (part->partmap->name, "netbsd") == 0 - || grub_strcmp (part->partmap->name, "openbsd") == 0 - || grub_strcmp (part->partmap->name, "bsd") == 0)) - { - bsd_part = part->number; - part = part->parent; - } - if (part && grub_strcmp (part->partmap->name, "msdos") == 0) - bsd_slice = part->number; - } - if (dev) - grub_device_close (dev); - } - - /* k*BSD didn't really work well with grub-legacy. */ - if (kernel_type == GUESS_IT || kernel_type == KFREEBSD) - { - char buf[sizeof("adXXXXXXXXXXXXsXXXXXXXXXXXXYYY")]; - if (bsd_device != -1) - { - if (bsd_slice != -1 && bsd_part != -1) - grub_snprintf(buf, sizeof(buf), "ad%ds%d%c", bsd_device, - bsd_slice, 'a' + bsd_part); - else if (bsd_slice != -1) - grub_snprintf(buf, sizeof(buf), "ad%ds%d", bsd_device, - bsd_slice); - else - grub_snprintf(buf, sizeof(buf), "ad%d", bsd_device); - grub_env_set ("kFreeBSD.vfs.root.mountfrom", buf); - } - else - grub_env_unset ("kFreeBSD.vfs.root.mountfrom"); - cmd = grub_command_find ("kfreebsd"); - if (cmd) - { - if (!(cmd->func) (cmd, cutargc, cutargs)) - { - kernel_type = KFREEBSD; - goto out; - } - } - grub_errno = GRUB_ERR_NONE; - } - { - char **bsdargs; - int bsdargc; - char bsddevname[sizeof ("wdXXXXXXXXXXXXY")]; - int found = 0; - - if (bsd_device == -1) - { - bsdargs = cutargs; - bsdargc = cutargc; - } - else - { - char rbuf[3] = "-r"; - bsdargc = cutargc + 2; - bsdargs = grub_calloc (bsdargc, sizeof (bsdargs[0])); - if (!bsdargs) - { - err = grub_errno; - goto out; - } - grub_memcpy (bsdargs, args, argc * sizeof (bsdargs[0])); - bsdargs[argc] = rbuf; - bsdargs[argc + 1] = bsddevname; - grub_snprintf (bsddevname, sizeof (bsddevname), - "wd%d%c", bsd_device, - bsd_part != -1 ? bsd_part + 'a' : 'c'); - } - if (kernel_type == GUESS_IT || kernel_type == KNETBSD) - { - cmd = grub_command_find ("knetbsd"); - if (cmd) - { - if (!(cmd->func) (cmd, bsdargc, bsdargs)) - { - kernel_type = KNETBSD; - found = 1; - goto free_bsdargs; - } - } - grub_errno = GRUB_ERR_NONE; - } - if (kernel_type == GUESS_IT || kernel_type == KOPENBSD) - { - cmd = grub_command_find ("kopenbsd"); - if (cmd) - { - if (!(cmd->func) (cmd, bsdargc, bsdargs)) - { - kernel_type = KOPENBSD; - found = 1; - goto free_bsdargs; - } - } - grub_errno = GRUB_ERR_NONE; - } - -free_bsdargs: - if (bsdargs != cutargs) - grub_free (bsdargs); - if (found) - goto out; - } - } - } - while (0); - - err = grub_error (GRUB_ERR_BAD_OS, "couldn't load file %s", - args[0]); -out: - grub_free (cutargs); - return err; -} - -static grub_err_t -grub_cmd_legacy_initrd (struct grub_command *mycmd __attribute__ ((unused)), - int argc, char **args) -{ - struct grub_command *cmd; - - if (kernel_type == LINUX) - { -#ifdef GRUB_MACHINE_PCBIOS - cmd = grub_command_find ("initrd16"); -#else - cmd = grub_command_find ("initrd"); -#endif - if (!cmd) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"), -#ifdef GRUB_MACHINE_PCBIOS - "initrd16" -#else - "initrd" -#endif - ); - - return cmd->func (cmd, argc ? 1 : 0, args); - } - if (kernel_type == MULTIBOOT) - { - cmd = grub_command_find ("module"); - if (!cmd) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"), - "module"); - - return cmd->func (cmd, argc, args); - } - - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("you need to load the kernel first")); -} - -static grub_err_t -grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused)), - int argc, char **args) -{ - struct grub_command *cmd; - - if (kernel_type == LINUX) - { - cmd = grub_command_find ("initrd16"); - if (!cmd) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"), - "initrd16"); - - return cmd->func (cmd, argc, args); - } - if (kernel_type == MULTIBOOT) - { - char **newargs; - grub_err_t err; - char nounzipbuf[10] = "--nounzip"; - - cmd = grub_command_find ("module"); - if (!cmd) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"), - "module"); - - newargs = grub_calloc (argc + 1, sizeof (newargs[0])); - if (!newargs) - return grub_errno; - grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0])); - newargs[0] = nounzipbuf; - - err = cmd->func (cmd, argc + 1, newargs); - grub_free (newargs); - return err; - } - - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("you need to load the kernel first")); -} - -static grub_err_t -check_password_deny (const char *user __attribute__ ((unused)), - const char *entered __attribute__ ((unused)), - void *password __attribute__ ((unused))) -{ - return GRUB_ACCESS_DENIED; -} - -#define MD5_HASHLEN 16 - -struct legacy_md5_password -{ - grub_uint8_t *salt; - int saltlen; - grub_uint8_t hash[MD5_HASHLEN]; -}; - -static int -check_password_md5_real (const char *entered, - struct legacy_md5_password *pw) -{ - grub_size_t enteredlen = grub_strlen (entered); - unsigned char alt_result[MD5_HASHLEN]; - unsigned char *digest; - grub_uint8_t *ctx; - grub_size_t i; - int ret; - - ctx = grub_zalloc (GRUB_MD_MD5->contextsize); - if (!ctx) - return 0; - - GRUB_MD_MD5->init (ctx); - GRUB_MD_MD5->write (ctx, entered, enteredlen); - GRUB_MD_MD5->write (ctx, pw->salt + 3, pw->saltlen - 3); - GRUB_MD_MD5->write (ctx, entered, enteredlen); - digest = GRUB_MD_MD5->read (ctx); - GRUB_MD_MD5->final (ctx); - grub_memcpy (alt_result, digest, MD5_HASHLEN); - - GRUB_MD_MD5->init (ctx); - GRUB_MD_MD5->write (ctx, entered, enteredlen); - GRUB_MD_MD5->write (ctx, pw->salt, pw->saltlen); /* include the $1$ header */ - for (i = enteredlen; i > 16; i -= 16) - GRUB_MD_MD5->write (ctx, alt_result, 16); - GRUB_MD_MD5->write (ctx, alt_result, i); - - for (i = enteredlen; i > 0; i >>= 1) - GRUB_MD_MD5->write (ctx, entered + ((i & 1) ? enteredlen : 0), 1); - digest = GRUB_MD_MD5->read (ctx); - GRUB_MD_MD5->final (ctx); - - for (i = 0; i < 1000; i++) - { - grub_memcpy (alt_result, digest, 16); - - GRUB_MD_MD5->init (ctx); - if ((i & 1) != 0) - GRUB_MD_MD5->write (ctx, entered, enteredlen); - else - GRUB_MD_MD5->write (ctx, alt_result, 16); - - if (i % 3 != 0) - GRUB_MD_MD5->write (ctx, pw->salt + 3, pw->saltlen - 3); - - if (i % 7 != 0) - GRUB_MD_MD5->write (ctx, entered, enteredlen); - - if ((i & 1) != 0) - GRUB_MD_MD5->write (ctx, alt_result, 16); - else - GRUB_MD_MD5->write (ctx, entered, enteredlen); - digest = GRUB_MD_MD5->read (ctx); - GRUB_MD_MD5->final (ctx); - } - - ret = (grub_crypto_memcmp (digest, pw->hash, MD5_HASHLEN) == 0); - grub_free (ctx); - return ret; -} - -static grub_err_t -check_password_md5 (const char *user, - const char *entered, - void *password) -{ - if (!check_password_md5_real (entered, password)) - return GRUB_ACCESS_DENIED; - - grub_auth_authenticate (user); - - return GRUB_ERR_NONE; -} - -static inline int -ib64t (char c) -{ - if (c == '.') - return 0; - if (c == '/') - return 1; - if (c >= '0' && c <= '9') - return c - '0' + 2; - if (c >= 'A' && c <= 'Z') - return c - 'A' + 12; - if (c >= 'a' && c <= 'z') - return c - 'a' + 38; - return -1; -} - -static struct legacy_md5_password * -parse_legacy_md5 (int argc, char **args) -{ - const char *salt, *saltend; - struct legacy_md5_password *pw = NULL; - int i; - const char *p; - - if (grub_memcmp (args[0], "--md5", sizeof ("--md5")) != 0) - goto fail; - if (argc == 1) - goto fail; - if (grub_strlen(args[1]) <= 3) - goto fail; - salt = args[1]; - saltend = grub_strchr (salt + 3, '$'); - if (!saltend) - goto fail; - pw = grub_malloc (sizeof (*pw)); - if (!pw) - goto fail; - - p = saltend + 1; - for (i = 0; i < 5; i++) - { - int n; - grub_uint32_t w = 0; - - for (n = 0; n < 4; n++) - { - int ww = ib64t(*p++); - if (ww == -1) - goto fail; - w |= ww << (n * 6); - } - pw->hash[i == 4 ? 5 : 12+i] = w & 0xff; - pw->hash[6+i] = (w >> 8) & 0xff; - pw->hash[i] = (w >> 16) & 0xff; - } - { - int n; - grub_uint32_t w = 0; - for (n = 0; n < 2; n++) - { - int ww = ib64t(*p++); - if (ww == -1) - goto fail; - w |= ww << (6 * n); - } - if (w >= 0x100) - goto fail; - pw->hash[11] = w; - } - - pw->saltlen = saltend - salt; - pw->salt = (grub_uint8_t *) grub_strndup (salt, pw->saltlen); - if (!pw->salt) - goto fail; - - return pw; - - fail: - grub_free (pw); - return NULL; -} - -static grub_err_t -grub_cmd_legacy_password (struct grub_command *mycmd __attribute__ ((unused)), - int argc, char **args) -{ - struct legacy_md5_password *pw = NULL; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - if (args[0][0] != '-' || args[0][1] != '-') - return grub_normal_set_password ("legacy", args[0]); - - pw = parse_legacy_md5 (argc, args); - - if (pw) - return grub_auth_register_authentication ("legacy", check_password_md5, pw); - else - /* This is to imitate minor difference between grub-legacy in GRUB2. - If 2 password commands are executed in a row and second one fails - on GRUB2 the password of first one is used, whereas in grub-legacy - authenthication is denied. In case of no password command was executed - early both versions deny any access. */ - return grub_auth_register_authentication ("legacy", check_password_deny, - NULL); -} - -int -grub_legacy_check_md5_password (int argc, char **args, - char *entered) -{ - struct legacy_md5_password *pw = NULL; - int ret; - - if (args[0][0] != '-' || args[0][1] != '-') - { - char correct[GRUB_AUTH_MAX_PASSLEN]; - - grub_memset (correct, 0, sizeof (correct)); - grub_strncpy (correct, args[0], sizeof (correct)); - - return grub_crypto_memcmp (entered, correct, GRUB_AUTH_MAX_PASSLEN) == 0; - } - - pw = parse_legacy_md5 (argc, args); - - if (!pw) - return 0; - - ret = check_password_md5_real (entered, pw); - grub_free (pw); - return ret; -} - -static grub_err_t -grub_cmd_legacy_check_password (struct grub_command *mycmd __attribute__ ((unused)), - int argc, char **args) -{ - char entered[GRUB_AUTH_MAX_PASSLEN]; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - grub_puts_ (N_("Enter password: ")); - if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN)) - return GRUB_ACCESS_DENIED; - - if (!grub_legacy_check_md5_password (argc, args, - entered)) - return GRUB_ACCESS_DENIED; - - return GRUB_ERR_NONE; -} - -static grub_command_t cmd_source, cmd_configfile; -static grub_command_t cmd_source_extract, cmd_configfile_extract; -static grub_command_t cmd_kernel, cmd_initrd, cmd_initrdnounzip; -static grub_command_t cmd_password, cmd_check_password; - -GRUB_MOD_INIT(legacycfg) -{ - cmd_source - = grub_register_command ("legacy_source", - grub_cmd_legacy_source, - N_("FILE"), - /* TRANSLATORS: "legacy config" means - "config as used by grub-legacy". */ - N_("Parse legacy config in same context")); - cmd_configfile - = grub_register_command ("legacy_configfile", - grub_cmd_legacy_source, - N_("FILE"), - N_("Parse legacy config in new context")); - cmd_source_extract - = grub_register_command ("extract_legacy_entries_source", - grub_cmd_legacy_source, - N_("FILE"), - N_("Parse legacy config in same context taking only menu entries")); - cmd_configfile_extract - = grub_register_command ("extract_legacy_entries_configfile", - grub_cmd_legacy_source, - N_("FILE"), - N_("Parse legacy config in new context taking only menu entries")); - - cmd_kernel = grub_register_command ("legacy_kernel", - grub_cmd_legacy_kernel, - N_("[--no-mem-option] [--type=TYPE] FILE [ARG ...]"), - N_("Simulate grub-legacy `kernel' command")); - - cmd_initrd = grub_register_command ("legacy_initrd", - grub_cmd_legacy_initrd, - N_("FILE [ARG ...]"), - N_("Simulate grub-legacy `initrd' command")); - cmd_initrdnounzip = grub_register_command ("legacy_initrd_nounzip", - grub_cmd_legacy_initrdnounzip, - N_("FILE [ARG ...]"), - N_("Simulate grub-legacy `modulenounzip' command")); - - cmd_password = grub_register_command ("legacy_password", - grub_cmd_legacy_password, - N_("[--md5] PASSWD [FILE]"), - N_("Simulate grub-legacy `password' command")); - - cmd_check_password = grub_register_command ("legacy_check_password", - grub_cmd_legacy_check_password, - N_("[--md5] PASSWD [FILE]"), - N_("Simulate grub-legacy `password' command in menu entry mode")); - -} - -GRUB_MOD_FINI(legacycfg) -{ - grub_unregister_command (cmd_source); - grub_unregister_command (cmd_configfile); - grub_unregister_command (cmd_source_extract); - grub_unregister_command (cmd_configfile_extract); - - grub_unregister_command (cmd_kernel); - grub_unregister_command (cmd_initrd); - grub_unregister_command (cmd_initrdnounzip); - - grub_unregister_command (cmd_password); - grub_unregister_command (cmd_check_password); -} diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c deleted file mode 100644 index c3bcb089a..000000000 --- a/grub-core/commands/ls.c +++ /dev/null @@ -1,311 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -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} - }; - -/* Helper for grub_ls_list_devices. */ -static int -grub_ls_print_devices (const char *name, void *data) -{ - int *longlist = data; - - if (*longlist) - grub_normal_print_device_info (name); - else - grub_printf ("(%s) ", name); - - return 0; -} - -static grub_err_t -grub_ls_list_devices (int longlist) -{ - grub_device_iterate (grub_ls_print_devices, &longlist); - grub_xputs ("\n"); - -#if 0 - { - grub_net_app_level_t proto; - int first = 1; - FOR_NET_APP_LEVEL (proto) - { - if (first) - grub_puts_ (N_("Network protocols:")); - first = 0; - grub_printf ("%s ", proto->name); - } - grub_xputs ("\n"); - } -#endif - - grub_refresh (); - - return 0; -} - -/* Context for grub_ls_list_files. */ -struct grub_ls_list_files_ctx -{ - char *dirname; - char *filename; - int all; - int human; - int longlist; - int print_dirhdr; -}; - -/* Helper for grub_ls_list_files. */ -static int -print_file (const char *filename, const struct grub_dirhook_info *info, - void *data) -{ - char *pathname = NULL; - struct grub_ls_list_files_ctx *ctx = data; - - if ((! ctx->all) && (filename[0] == '.')) - return 0; - - if ((ctx->filename != NULL) && (grub_strcmp (filename, ctx->filename) != 0)) - return 0; - - if (ctx->print_dirhdr) - { - grub_printf ("%s:\n", ctx->dirname); - ctx->print_dirhdr = 0; - } - - if (! ctx->longlist) - { - if (ctx->filename != NULL) - grub_xputs (ctx->dirname); - grub_printf ("%s%s ", filename, info->dir ? "/" : ""); - return 0; - } - - if (! info->dir) - { - grub_file_t file; - - if (ctx->dirname[grub_strlen (ctx->dirname) - 1] == '/') - pathname = grub_xasprintf ("%s%s", ctx->dirname, filename); - else - pathname = grub_xasprintf ("%s/%s", ctx->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, GRUB_FILE_TYPE_GET_SIZE - | GRUB_FILE_TYPE_NO_DECOMPRESS); - if (file) - { - if (! ctx->human) - grub_printf ("%-12llu", (unsigned long long) file->size); - else - grub_printf ("%-12s", grub_get_human_size (file->size, - GRUB_HUMAN_SIZE_SHORT)); - grub_file_close (file); - } - else - grub_xputs ("????????????"); - - grub_errno = GRUB_ERR_NONE; - } - else - grub_printf ("%-12s", _("DIR")); - - if (info->mtimeset) - { - struct grub_datetime datetime; - grub_unixtime2datetime (info->mtime, &datetime); - if (ctx->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); - } - /* - * Only print the full path when listing a file path given as an argument - * to ls, i.e. when ctx->filename != NULL. File listings that are printed - * due to showing the contents of a directory do not need a full path because - * the full path to the directory will have already been printed. - */ - grub_printf ("%s%s\n", (ctx->filename != NULL) ? pathname : filename, - info->dir ? "/" : ""); - - grub_free (pathname); - - return 0; -} - -static grub_err_t -grub_ls_list_files (char *dirname, int longlist, int all, int human, int dirhdr) -{ - char *device_name; - grub_fs_t fs; - const char *path; - grub_device_t dev; - - 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 && device_name) - { - if (grub_errno == GRUB_ERR_UNKNOWN_FS) - grub_errno = GRUB_ERR_NONE; - -#ifdef GRUB_MACHINE_IEEE1275 - /* - * Close device to prevent a double open in grub_normal_print_device_info(). - * Otherwise it may lead to hangs on some IEEE 1275 platforms. - */ - grub_device_close (dev); - dev = NULL; -#endif - - grub_normal_print_device_info (device_name); - } - else if (fs) - { - struct grub_ls_list_files_ctx ctx = { - .dirname = dirname, - .filename = NULL, - .all = all, - .human = human, - .longlist = longlist, - .print_dirhdr = dirhdr - }; - - (fs->fs_dir) (dev, path, print_file, &ctx); - - if (grub_errno == GRUB_ERR_BAD_FILE_TYPE - && path[grub_strlen (path) - 1] != '/') - { - /* - * Reset errno as it is currently set, but will cause subsequent code - * to think there is an error. - */ - grub_errno = GRUB_ERR_NONE; - - /* PATH might be a regular file. */ - ctx.print_dirhdr = 0; - ctx.filename = grub_strrchr (dirname, '/'); - if (ctx.filename == NULL) - goto fail; - ++(ctx.filename); - - ctx.dirname = grub_strndup (dirname, ctx.filename - dirname); - if (ctx.dirname == NULL) - goto fail; - - (fs->fs_dir) (dev, ctx.dirname + (path - dirname), print_file, &ctx); - - grub_free (ctx.dirname); - } - - if (grub_errno == GRUB_ERR_NONE) - grub_xputs ("\n"); - - grub_refresh (); - } - - fail: - if (dev) - grub_device_close (dev); - - grub_free (device_name); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_ls (grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_arg_list *state = ctxt->state; - int i; - - if (argc == 0) - grub_ls_list_devices (state[0].set); - else - for (i = 0; i < argc; i++) - grub_ls_list_files (args[i], state[0].set, state[2].set, state[1].set, - argc > 1); - - return GRUB_ERR_NONE; -} - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT(ls) -{ - cmd = grub_register_extcmd ("ls", grub_cmd_ls, 0, - 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/lsacpi.c b/grub-core/commands/lsacpi.c deleted file mode 100644 index f7a1a1b05..000000000 --- a/grub-core/commands/lsacpi.c +++ /dev/null @@ -1,314 +0,0 @@ -/* acpi.c - Display acpi tables. */ -/* - * 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 . - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#pragma GCC diagnostic ignored "-Wcast-align" - -GRUB_MOD_LICENSE ("GPLv3+"); - -static void -print_strn (grub_uint8_t *str, grub_size_t len) -{ - for (; *str && len; str++, len--) - grub_printf ("%c", *str); - for (len++; len; len--) - grub_printf (" "); -} - -#define print_field(x) print_strn(x, sizeof (x)) - -static void -disp_acpi_table (struct grub_acpi_table_header *t) -{ - print_field (t->signature); - grub_printf ("%4" PRIuGRUB_UINT32_T "B rev=%u chksum=0x%02x (%s) OEM=", t->length, t->revision, t->checksum, - grub_byte_checksum (t, t->length) == 0 ? "valid" : "invalid"); - print_field (t->oemid); - print_field (t->oemtable); - grub_printf ("OEMrev=%08" PRIxGRUB_UINT32_T " ", t->oemrev); - print_field (t->creator_id); - grub_printf (" %08" PRIxGRUB_UINT32_T "\n", t->creator_rev); -} - -static void -disp_madt_table (struct grub_acpi_madt *t) -{ - struct grub_acpi_madt_entry_header *d; - grub_uint32_t len; - - disp_acpi_table (&t->hdr); - grub_printf ("Local APIC=%08" PRIxGRUB_UINT32_T " Flags=%08" - PRIxGRUB_UINT32_T "\n", - t->lapic_addr, t->flags); - len = t->hdr.length - sizeof (struct grub_acpi_madt); - d = t->entries; - for (;len > 0; len -= d->len, d = (void *) ((grub_uint8_t *) d + d->len)) - { - switch (d->type) - { - case GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC: - { - struct grub_acpi_madt_entry_lapic *dt = (void *) d; - grub_printf (" LAPIC ACPI_ID=%02x APIC_ID=%02x Flags=%08x\n", - dt->acpiid, dt->apicid, dt->flags); - if (dt->hdr.len != sizeof (*dt)) - grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, - (int) sizeof (*dt)); - break; - } - - case GRUB_ACPI_MADT_ENTRY_TYPE_IOAPIC: - { - struct grub_acpi_madt_entry_ioapic *dt = (void *) d; - grub_printf (" IOAPIC ID=%02x address=%08x GSI=%08x\n", - dt->id, dt->address, dt->global_sys_interrupt); - if (dt->hdr.len != sizeof (*dt)) - grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, - (int) sizeof (*dt)); - if (dt->pad) - grub_printf (" non-zero pad: %02x\n", dt->pad); - break; - } - - case GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE: - { - struct grub_acpi_madt_entry_interrupt_override *dt = (void *) d; - grub_printf (" Int Override bus=%x src=%x GSI=%08x Flags=%04x\n", - dt->bus, dt->source, dt->global_sys_interrupt, - dt->flags); - if (dt->hdr.len != sizeof (*dt)) - grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, - (int) sizeof (*dt)); - } - break; - - case GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC_NMI: - { - struct grub_acpi_madt_entry_lapic_nmi *dt = (void *) d; - grub_printf (" LAPIC_NMI ACPI_ID=%02x Flags=%04x lint=%02x\n", - dt->acpiid, dt->flags, dt->lint); - if (dt->hdr.len != sizeof (*dt)) - grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, - (int) sizeof (*dt)); - break; - } - - case GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC: - { - struct grub_acpi_madt_entry_sapic *dt = (void *) d; - grub_printf (" IOSAPIC Id=%02x GSI=%08x Addr=%016" PRIxGRUB_UINT64_T - "\n", - dt->id, dt->global_sys_interrupt_base, - dt->addr); - if (dt->hdr.len != sizeof (*dt)) - grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, - (int) sizeof (*dt)); - if (dt->pad) - grub_printf (" non-zero pad: %02x\n", dt->pad); - - } - break; - case GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC: - { - struct grub_acpi_madt_entry_lsapic *dt = (void *) d; - grub_printf (" LSAPIC ProcId=%02x ID=%02x EID=%02x Flags=%x", - dt->cpu_id, dt->id, dt->eid, dt->flags); - if (dt->flags & GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED) - grub_printf (" Enabled\n"); - else - grub_printf (" Disabled\n"); - if (d->len > sizeof (struct grub_acpi_madt_entry_sapic)) - grub_printf (" UID val=%08x, Str=%s\n", dt->cpu_uid, - dt->cpu_uid_str); - if (dt->hdr.len != sizeof (*dt) + grub_strlen ((char *) dt->cpu_uid_str) + 1) - grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, - (int) sizeof (*dt)); - if (dt->pad[0] || dt->pad[1] || dt->pad[2]) - grub_printf (" non-zero pad: %02x%02x%02x\n", dt->pad[0], dt->pad[1], dt->pad[2]); - } - break; - case GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE: - { - struct grub_acpi_madt_entry_platform_int_source *dt = (void *) d; - static const char * const platint_type[] = - {"Nul", "PMI", "INIT", "CPEI"}; - - grub_printf (" Platform INT flags=%04x type=%02x (%s)" - " ID=%02x EID=%02x\n", - dt->flags, dt->inttype, - (dt->inttype < ARRAY_SIZE (platint_type)) - ? platint_type[dt->inttype] : "??", dt->cpu_id, - dt->cpu_eid); - grub_printf (" IOSAPIC Vec=%02x GSI=%08x source flags=%08x\n", - dt->sapic_vector, dt->global_sys_int, dt->src_flags); - } - break; - default: - grub_printf (" type=%x l=%u ", d->type, d->len); - grub_printf (" ??\n"); - } - } -} - -static void -disp_acpi_xsdt_table (struct grub_acpi_table_header *t) -{ - grub_uint32_t len; - grub_uint64_t *desc; - - disp_acpi_table (t); - len = t->length - sizeof (*t); - desc = (grub_uint64_t *) (t + 1); - for (; len >= sizeof (*desc); desc++, len -= sizeof (*desc)) - { -#if GRUB_CPU_SIZEOF_VOID_P == 4 - if (*desc >= (1ULL << 32)) - { - grub_printf ("Unreachable table\n"); - continue; - } -#endif - t = (struct grub_acpi_table_header *) (grub_addr_t) *desc; - - if (t == NULL) - continue; - - if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE, - sizeof (t->signature)) == 0) - disp_madt_table ((struct grub_acpi_madt *) t); - else - disp_acpi_table (t); - } -} - -static void -disp_acpi_rsdt_table (struct grub_acpi_table_header *t) -{ - grub_uint32_t len; - grub_uint32_t *desc; - - disp_acpi_table (t); - len = t->length - sizeof (*t); - desc = (grub_uint32_t *) (t + 1); - for (; len >= sizeof (*desc); desc++, len -= sizeof (*desc)) - { - t = (struct grub_acpi_table_header *) (grub_addr_t) *desc; - - if (t == NULL) - continue; - - if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE, - sizeof (t->signature)) == 0) - disp_madt_table ((struct grub_acpi_madt *) t); - else - disp_acpi_table (t); - } -} - -static void -disp_acpi_rsdpv1 (struct grub_acpi_rsdp_v10 *rsdp) -{ - print_field (rsdp->signature); - grub_printf ("chksum:%02x (%s), OEM-ID: ", rsdp->checksum, grub_byte_checksum (rsdp, sizeof (*rsdp)) == 0 ? "valid" : "invalid"); - print_field (rsdp->oemid); - grub_printf ("rev=%d\n", rsdp->revision); - grub_printf ("RSDT=%08" PRIxGRUB_UINT32_T "\n", rsdp->rsdt_addr); -} - -static void -disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20 *rsdp) -{ - disp_acpi_rsdpv1 (&rsdp->rsdpv1); - grub_printf ("len=%d chksum=%02x (%s) XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length, rsdp->checksum, grub_byte_checksum (rsdp, rsdp->length) == 0 ? "valid" : "invalid", - rsdp->xsdt_addr); - if (rsdp->length != sizeof (*rsdp)) - grub_printf (" length mismatch %d != %d\n", rsdp->length, - (int) sizeof (*rsdp)); - if (rsdp->reserved[0] || rsdp->reserved[1] || rsdp->reserved[2]) - grub_printf (" non-zero reserved %02x%02x%02x\n", rsdp->reserved[0], rsdp->reserved[1], rsdp->reserved[2]); -} - -static const struct grub_arg_option options[] = { - {"v1", '1', 0, N_("Show version 1 tables only."), 0, ARG_TYPE_NONE}, - {"v2", '2', 0, N_("Show version 2 and version 3 tables only."), 0, ARG_TYPE_NONE}, - {0, 0, 0, 0, 0, 0} -}; - -static grub_err_t -grub_cmd_lsacpi (struct grub_extcmd_context *ctxt, - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - if (!ctxt->state[1].set) - { - struct grub_acpi_rsdp_v10 *rsdp1 = grub_acpi_get_rsdpv1 (); - if (!rsdp1) - grub_printf ("No RSDPv1\n"); - else - { - grub_printf ("RSDPv1 signature:"); - disp_acpi_rsdpv1 (rsdp1); - disp_acpi_rsdt_table ((void *) (grub_addr_t) rsdp1->rsdt_addr); - } - } - - if (!ctxt->state[0].set) - { - struct grub_acpi_rsdp_v20 *rsdp2 = grub_acpi_get_rsdpv2 (); - if (!rsdp2) - grub_printf ("No RSDPv2\n"); - else - { -#if GRUB_CPU_SIZEOF_VOID_P == 4 - if (rsdp2->xsdt_addr >= (1ULL << 32)) - grub_printf ("Unreachable RSDPv2\n"); - else -#endif - { - grub_printf ("RSDPv2 signature:"); - disp_acpi_rsdpv2 (rsdp2); - disp_acpi_xsdt_table ((void *) (grub_addr_t) rsdp2->xsdt_addr); - grub_printf ("\n"); - } - } - } - return GRUB_ERR_NONE; -} - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT(lsapi) -{ - cmd = grub_register_extcmd ("lsacpi", grub_cmd_lsacpi, 0, "[-1|-2]", - N_("Show ACPI information."), options); -} - -GRUB_MOD_FINI(lsacpi) -{ - grub_unregister_extcmd (cmd); -} - - diff --git a/grub-core/commands/lsmmap.c b/grub-core/commands/lsmmap.c deleted file mode 100644 index 816ee47d1..000000000 --- a/grub-core/commands/lsmmap.c +++ /dev/null @@ -1,85 +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 . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#ifndef GRUB_MACHINE_EMU -static const char *names[] = - { - [GRUB_MEMORY_AVAILABLE] = N_("available RAM"), - [GRUB_MEMORY_RESERVED] = N_("reserved RAM"), - /* TRANSLATORS: this refers to memory where ACPI tables are stored - and which can be used by OS once it loads ACPI tables. */ - [GRUB_MEMORY_ACPI] = N_("ACPI reclaimable RAM"), - /* TRANSLATORS: this refers to memory which ACPI-compliant OS - is required to save accross hibernations. */ - [GRUB_MEMORY_NVS] = N_("ACPI non-volatile storage RAM"), - [GRUB_MEMORY_BADRAM] = N_("faulty RAM (BadRAM)"), - [GRUB_MEMORY_PERSISTENT] = N_("persistent RAM"), - [GRUB_MEMORY_PERSISTENT_LEGACY] = N_("persistent RAM (legacy)"), - [GRUB_MEMORY_COREBOOT_TABLES] = N_("RAM holding coreboot tables"), - [GRUB_MEMORY_CODE] = N_("RAM holding firmware code") - }; - -/* Helper for grub_cmd_lsmmap. */ -static int -lsmmap_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, - void *data __attribute__ ((unused))) -{ - if (type < (int) ARRAY_SIZE (names) && type >= 0 && names[type]) - grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, %s\n"), - (long long) addr, (long long) size, _(names[type])); - else - grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n"), - (long long) addr, (long long) size, type); - return 0; -} -#endif - -static grub_err_t -grub_cmd_lsmmap (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) - -{ -#ifndef GRUB_MACHINE_EMU - grub_machine_mmap_iterate (lsmmap_hook, NULL); -#endif - - return 0; -} - -static grub_command_t cmd; - -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/macbless.c b/grub-core/commands/macbless.c deleted file mode 100644 index 3d761452a..000000000 --- a/grub-core/commands/macbless.c +++ /dev/null @@ -1,233 +0,0 @@ -/* hfspbless.c - set the hfs+ boot directory. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2005,2007,2008,2009,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct find_node_context -{ - grub_uint64_t inode_found; - char *dirname; - enum - { FOUND_NONE, FOUND_FILE, FOUND_DIR } found; -}; - -static int -find_inode (const char *filename, - const struct grub_dirhook_info *info, void *data) -{ - struct find_node_context *ctx = data; - if (!info->inodeset) - return 0; - - if ((grub_strcmp (ctx->dirname, filename) == 0 - || (info->case_insensitive - && grub_strcasecmp (ctx->dirname, filename) == 0))) - { - ctx->inode_found = info->inode; - ctx->found = info->dir ? FOUND_DIR : FOUND_FILE; - } - return 0; -} - -grub_err_t -grub_mac_bless_inode (grub_device_t dev, grub_uint32_t inode, int is_dir, - int intel) -{ - grub_err_t err; - union - { - struct grub_hfs_sblock hfs; - struct grub_hfsplus_volheader hfsplus; - } volheader; - grub_disk_addr_t embedded_offset; - - if (intel && is_dir) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "can't bless a directory for mactel"); - if (!intel && !is_dir) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "can't bless a file for mac PPC"); - - /* Read the bootblock. */ - err = grub_disk_read (dev->disk, GRUB_HFSPLUS_SBLOCK, 0, sizeof (volheader), - (char *) &volheader); - if (err) - return err; - - 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) - { - if (intel) - volheader.hfs.intel_bootfile = grub_be_to_cpu32 (inode); - else - volheader.hfs.ppc_bootdir = grub_be_to_cpu32 (inode); - return GRUB_ERR_NONE; - } - - /* 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); - embedded_offset = (ablk_start - + ((grub_uint64_t) extent_start) - * (ablk_size >> GRUB_DISK_SECTOR_BITS)); - - err = - grub_disk_read (dev->disk, embedded_offset + GRUB_HFSPLUS_SBLOCK, 0, - sizeof (volheader), (char *) &volheader); - if (err) - return err; - } - - if ((grub_be_to_cpu16 (volheader.hfsplus.magic) != GRUB_HFSPLUS_MAGIC) - && (grub_be_to_cpu16 (volheader.hfsplus.magic) != GRUB_HFSPLUSX_MAGIC)) - return grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem"); - if (intel) - volheader.hfsplus.intel_bootfile = grub_be_to_cpu32 (inode); - else - volheader.hfsplus.ppc_bootdir = grub_be_to_cpu32 (inode); - - return grub_disk_write (dev->disk, embedded_offset + GRUB_HFSPLUS_SBLOCK, 0, - sizeof (volheader), (char *) &volheader); -} - -grub_err_t -grub_mac_bless_file (grub_device_t dev, const char *path_in, int intel) -{ - grub_fs_t fs; - - char *path, *tail; - struct find_node_context ctx; - - fs = grub_fs_probe (dev); - if (!fs || (grub_strcmp (fs->name, "hfsplus") != 0 - && grub_strcmp (fs->name, "hfs") != 0)) - return grub_error (GRUB_ERR_BAD_FS, "no suitable FS found"); - - path = grub_strdup (path_in); - if (!path) - return grub_errno; - - tail = path + grub_strlen (path) - 1; - - /* Remove trailing '/'. */ - while (tail != path && *tail == '/') - *(tail--) = 0; - - tail = grub_strrchr (path, '/'); - ctx.found = 0; - - if (tail) - { - *tail = 0; - ctx.dirname = tail + 1; - - (fs->fs_dir) (dev, *path == 0 ? "/" : path, find_inode, &ctx); - } - else - { - ctx.dirname = path + 1; - (fs->fs_dir) (dev, "/", find_inode, &ctx); - } - if (!ctx.found) - { - grub_free (path); - return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), - path_in); - } - grub_free (path); - - return grub_mac_bless_inode (dev, (grub_uint32_t) ctx.inode_found, - (ctx.found == FOUND_DIR), intel); -} - -static grub_err_t -grub_cmd_macbless (grub_command_t cmd, int argc, char **args) -{ - char *device_name; - char *path = 0; - grub_device_t dev = 0; - grub_err_t err; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - device_name = grub_file_get_device_name (args[0]); - dev = grub_device_open (device_name); - - path = grub_strchr (args[0], ')'); - if (!path) - path = args[0]; - else - path = path + 1; - - if (!path || *path == 0 || !dev) - { - if (dev) - grub_device_close (dev); - - grub_free (device_name); - - return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument"); - } - - err = grub_mac_bless_file (dev, path, cmd->name[3] == 't'); - - grub_device_close (dev); - grub_free (device_name); - return err; -} - -static grub_command_t cmd, cmd_ppc; - -GRUB_MOD_INIT(macbless) -{ - cmd = grub_register_command ("mactelbless", grub_cmd_macbless, - N_("FILE"), - N_("Bless FILE of HFS or HFS+ partition for intel macs.")); - cmd_ppc = - grub_register_command ("macppcbless", grub_cmd_macbless, N_("DIR"), - N_("Bless DIR of HFS or HFS+ partition for PPC macs.")); -} - -GRUB_MOD_FINI(macbless) -{ - grub_unregister_command (cmd); - grub_unregister_command (cmd_ppc); -} diff --git a/grub-core/commands/memtools.c b/grub-core/commands/memtools.c deleted file mode 100644 index ae0a9bec3..000000000 --- a/grub-core/commands/memtools.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Free Software Foundation, Inc. - * Copyright (C) 2022 IBM Corporation - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -grub_cmd_lsmem (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) - -{ -#ifndef GRUB_MACHINE_EMU - grub_mm_dump (0); -#endif - - return 0; -} - -static grub_err_t -grub_cmd_lsfreemem (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) - -{ -#ifndef GRUB_MACHINE_EMU - grub_mm_dump_free (); -#endif - - return 0; -} - - -static grub_err_t -grub_cmd_stress_big_allocs (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - int i, max_mb, blocks_alloced; - void *mem; - void **blocklist; - - grub_printf ("Test 1: increasingly sized allocs to 1GB block\n"); - for (i = 1; i < 1024; i++) - { - grub_printf ("%4d MB . ", i); - mem = grub_malloc (i * 1024 * 1024); - if (mem == NULL) - { - grub_printf ("failed\n"); - break; - } - else - grub_free (mem); - - if (i % 7 == 0) - grub_printf ("\n"); - } - - max_mb = i - 1; - grub_printf ("\nMax sized allocation we did was %d MB\n", max_mb); - - grub_printf ("\nTest 2: 1MB at a time, max 4GB\n"); - blocklist = grub_calloc (4096, sizeof (void *)); - for (i = 0; i < 4096; i++) - { - blocklist[i] = grub_malloc (1024 * 1024); - if (blocklist[i] == NULL) - { - grub_printf ("Ran out of memory at iteration %d\n", i); - break; - } - } - blocks_alloced = i; - for (i = 0; i < blocks_alloced; i++) - grub_free (blocklist[i]); - - grub_printf ("\nTest 3: 1MB aligned 900kB + 100kB\n"); - /* grub_mm_debug=1;*/ - for (i = 0; i < 4096; i += 2) - { - blocklist[i] = grub_memalign (1024 * 1024, 900 * 1024); - if (blocklist[i] == NULL) - { - grub_printf ("Failed big allocation, iteration %d\n", i); - blocks_alloced = i; - break; - } - - blocklist[i + 1] = grub_malloc (100 * 1024); - if (blocklist[i + 1] == NULL) - { - grub_printf ("Failed small allocation, iteration %d\n", i); - blocks_alloced = i + 1; - break; - } - grub_printf ("."); - } - for (i = 0; i < blocks_alloced; i++) - grub_free (blocklist[i]); - - grub_free (blocklist); - -#if defined(__powerpc__) - grub_printf ("\nA reboot may now be required.\n"); -#endif - - grub_errno = GRUB_ERR_NONE; - return GRUB_ERR_NONE; -} - -static grub_command_t cmd_lsmem, cmd_lsfreemem, cmd_sba; - -GRUB_MOD_INIT (memtools) -{ - cmd_lsmem = grub_register_command ("lsmem", grub_cmd_lsmem, - 0, N_("List free and allocated memory blocks.")); - cmd_lsfreemem = grub_register_command ("lsfreemem", grub_cmd_lsfreemem, - 0, N_("List free memory blocks.")); - cmd_sba = grub_register_command ("stress_big_allocs", grub_cmd_stress_big_allocs, - 0, N_("Stress test large allocations.")); -} - -GRUB_MOD_FINI (memtools) -{ - grub_unregister_command (cmd_lsmem); - grub_unregister_command (cmd_lsfreemem); - grub_unregister_command (cmd_sba); -} diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c deleted file mode 100644 index 720e6d8ea..000000000 --- a/grub-core/commands/menuentry.c +++ /dev/null @@ -1,337 +0,0 @@ -/* menuentry.c - menuentry command */ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -static const struct grub_arg_option options[] = - { - {"class", 1, GRUB_ARG_OPTION_REPEATABLE, - N_("Menu entry type."), N_("STRING"), ARG_TYPE_STRING}, - {"users", 2, 0, - N_("List of users allowed to boot this entry."), N_("USERNAME[,USERNAME]"), - ARG_TYPE_STRING}, - {"hotkey", 3, 0, - N_("Keyboard key to quickly boot this entry."), N_("KEYBOARD_KEY"), ARG_TYPE_STRING}, - {"source", 4, 0, - N_("Use STRING as menu entry body."), N_("STRING"), ARG_TYPE_STRING}, - {"id", 0, 0, N_("Menu entry identifier."), N_("STRING"), ARG_TYPE_STRING}, - /* TRANSLATORS: menu entry can either be bootable by anyone or only by - handful of users. By default when security is active only superusers can - boot a given menu entry. With --unrestricted (this option) - anyone can boot it. */ - {"unrestricted", 0, 0, N_("This entry can be booted by any user."), - 0, ARG_TYPE_NONE}, - {0, 0, 0, 0, 0, 0} - }; - -static struct -{ - const char *name; - int key; -} hotkey_aliases[] = - { - {"backspace", GRUB_TERM_BACKSPACE}, - {"tab", GRUB_TERM_TAB}, - {"delete", GRUB_TERM_KEY_DC}, - {"insert", GRUB_TERM_KEY_INSERT}, - {"f1", GRUB_TERM_KEY_F1}, - {"f2", GRUB_TERM_KEY_F2}, - {"f3", GRUB_TERM_KEY_F3}, - {"f4", GRUB_TERM_KEY_F4}, - {"f5", GRUB_TERM_KEY_F5}, - {"f6", GRUB_TERM_KEY_F6}, - {"f7", GRUB_TERM_KEY_F7}, - {"f8", GRUB_TERM_KEY_F8}, - {"f9", GRUB_TERM_KEY_F9}, - {"f10", GRUB_TERM_KEY_F10}, - {"f11", GRUB_TERM_KEY_F11}, - {"f12", GRUB_TERM_KEY_F12}, - }; - -/* 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, - char **classes, const char *id, - const char *users, const char *hotkey, - const char *prefix, const char *sourcecode, - int submenu) -{ - int menu_hotkey = 0; - char **menu_args = NULL; - char *menu_users = NULL; - char *menu_title = NULL; - char *menu_sourcecode = NULL; - char *menu_id = NULL; - struct grub_menu_entry_class *menu_classes = NULL; - - grub_menu_t menu; - grub_menu_entry_t *last; - - menu = grub_env_get_menu (); - if (! menu) - return grub_error (GRUB_ERR_MENU, "no menu context"); - - last = &menu->entry_list; - - menu_sourcecode = grub_xasprintf ("%s%s", prefix ?: "", sourcecode); - if (! menu_sourcecode) - return grub_errno; - - if (classes && classes[0]) - { - int i; - for (i = 0; classes[i]; i++); /* count # of menuentry classes */ - menu_classes = grub_zalloc (sizeof (struct grub_menu_entry_class) - * (i + 1)); - if (! menu_classes) - goto fail; - - for (i = 0; classes[i]; i++) - { - menu_classes[i].name = grub_strdup (classes[i]); - if (! menu_classes[i].name) - goto fail; - menu_classes[i].next = classes[i + 1] ? &menu_classes[i + 1] : NULL; - } - } - - if (users) - { - menu_users = grub_strdup (users); - if (! menu_users) - goto fail; - } - - if (hotkey) - { - unsigned i; - for (i = 0; i < ARRAY_SIZE (hotkey_aliases); i++) - if (grub_strcmp (hotkey, hotkey_aliases[i].name) == 0) - { - menu_hotkey = hotkey_aliases[i].key; - break; - } - if (i == ARRAY_SIZE (hotkey_aliases)) - menu_hotkey = hotkey[0]; - } - - if (! argc) - { - grub_error (GRUB_ERR_MENU, "menuentry is missing title"); - goto fail; - } - - menu_title = grub_strdup (args[0]); - if (! menu_title) - goto fail; - - menu_id = grub_strdup (id ? : menu_title); - if (! menu_id) - goto fail; - - /* Save argc, args to pass as parameters to block arg later. */ - menu_args = grub_calloc (argc + 1, sizeof (char *)); - if (! menu_args) - goto fail; - - { - int i; - for (i = 0; i < argc; i++) - { - menu_args[i] = grub_strdup (args[i]); - if (! menu_args[i]) - goto fail; - } - menu_args[argc] = NULL; - } - - /* Add the menu entry at the end of the list. */ - while (*last) - last = &(*last)->next; - - *last = grub_zalloc (sizeof (**last)); - if (! *last) - goto fail; - - (*last)->title = menu_title; - (*last)->id = menu_id; - (*last)->hotkey = menu_hotkey; - (*last)->classes = menu_classes; - if (menu_users) - (*last)->restricted = 1; - (*last)->users = menu_users; - (*last)->argc = argc; - (*last)->args = menu_args; - (*last)->sourcecode = menu_sourcecode; - (*last)->submenu = submenu; - - menu->size++; - return GRUB_ERR_NONE; - - fail: - - grub_free (menu_sourcecode); - { - int i; - for (i = 0; menu_classes && menu_classes[i].name; i++) - grub_free (menu_classes[i].name); - grub_free (menu_classes); - } - - { - int i; - for (i = 0; menu_args && menu_args[i]; i++) - grub_free (menu_args[i]); - grub_free (menu_args); - } - - grub_free (menu_users); - grub_free (menu_title); - grub_free (menu_id); - return grub_errno; -} - -static char * -setparams_prefix (int argc, char **args) -{ - int i; - int j; - char *p; - char *result; - grub_size_t len = 10; - - /* Count resulting string length */ - for (i = 0; i < argc; i++) - { - len += 3; /* 3 = 1 space + 2 quotes */ - p = args[i]; - while (*p) - len += (*p++ == '\'' ? 4 : 1); - } - - result = grub_malloc (len + 2); - if (! result) - return 0; - - grub_strcpy (result, "setparams"); - p = result + 9; - - for (j = 0; j < argc; j++) - { - *p++ = ' '; - *p++ = '\''; - p = grub_strchrsub (p, args[j], '\'', "'\\''"); - *p++ = '\''; - } - *p++ = '\n'; - *p = '\0'; - return result; -} - -static grub_err_t -grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) -{ - char ch; - char *src; - char *prefix; - unsigned len; - grub_err_t r; - const char *users; - - if (! argc) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing arguments"); - - if (ctxt->state[3].set && ctxt->script) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "multiple menuentry definitions"); - - if (! ctxt->state[3].set && ! ctxt->script) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menuentry definition"); - - if (ctxt->state[1].set) - users = ctxt->state[1].arg; - else if (ctxt->state[5].set) - users = NULL; - else - users = ""; - - if (! ctxt->script) - return grub_normal_add_menu_entry (argc, (const char **) args, - (ctxt->state[0].set ? ctxt->state[0].args - : NULL), - ctxt->state[4].arg, - users, - ctxt->state[2].arg, 0, - ctxt->state[3].arg, - ctxt->extcmd->cmd->name[0] == 's'); - - src = args[argc - 1]; - args[argc - 1] = NULL; - - len = grub_strlen(src); - ch = src[len - 1]; - src[len - 1] = '\0'; - - prefix = setparams_prefix (argc - 1, args); - if (! prefix) - return grub_errno; - - r = grub_normal_add_menu_entry (argc - 1, (const char **) args, - ctxt->state[0].args, ctxt->state[4].arg, - users, - ctxt->state[2].arg, prefix, src + 1, - ctxt->extcmd->cmd->name[0] == 's'); - - src[len - 1] = ch; - args[argc - 1] = src; - grub_free (prefix); - return r; -} - -static grub_extcmd_t cmd, cmd_sub; - -void -grub_menu_init (void) -{ - cmd = grub_register_extcmd ("menuentry", grub_cmd_menuentry, - GRUB_COMMAND_FLAG_BLOCKS - | GRUB_COMMAND_ACCEPT_DASH - | GRUB_COMMAND_FLAG_EXTRACTOR, - N_("BLOCK"), N_("Define a menu entry."), options); - cmd_sub = grub_register_extcmd ("submenu", grub_cmd_menuentry, - GRUB_COMMAND_FLAG_BLOCKS - | GRUB_COMMAND_ACCEPT_DASH - | GRUB_COMMAND_FLAG_EXTRACTOR, - N_("BLOCK"), N_("Define a submenu."), - options); -} - -void -grub_menu_fini (void) -{ - grub_unregister_extcmd (cmd); - grub_unregister_extcmd (cmd_sub); -} diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c deleted file mode 100644 index ff4ff021c..000000000 --- a/grub-core/commands/minicmd.c +++ /dev/null @@ -1,238 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef GRUB_MACHINE_EFI -#include -#endif - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* 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, N_("filename expected")); - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_CAT); - 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_printf ("%c", c); - else - { - grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); - grub_printf ("<%x>", (int) c); - grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); - } - } - } - - grub_xputs ("\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_COMMAND_PRIO_MASK, - (p->prio & GRUB_COMMAND_FLAG_ACTIVE) ? '+' : '-', - p->description); - - return 0; -} - -/* 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"); - -#if GRUB_CPU_SIZEOF_VOID_P == GRUB_CPU_SIZEOF_LONG -#define grub_strtoaddr grub_strtoul -#else -#define grub_strtoaddr grub_strtoull -#endif - - addr = (grub_uint8_t *) grub_strtoaddr (argv[0], 0, 0); - if (grub_errno) - return grub_errno; - - if (argc > 1) - size = (grub_size_t) grub_strtoaddr (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_is_persistent (mod)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "cannot unload persistent module"); - - if (grub_dl_ref_count (mod) > 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "cannot unload referenced module"); - - grub_dl_unref (mod); - 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))) -{ - grub_dl_t mod; - - /* TRANSLATORS: this is module list header. Name - is module name, Ref Count is a reference counter - (how many modules or open descriptors use it). - Dependencies are the other modules it uses. - */ - grub_printf_ (N_("Name\tRef Count\tDependencies\n")); - FOR_DL_MODULES (mod) - { - grub_dl_dep_t dep; - - grub_printf ("%s\t%" PRIuGRUB_UINT64_T "\t\t", mod->name, mod->ref_count); - for (dep = mod->dep; dep; dep = dep->next) - { - if (dep != mod->dep) - grub_xputs (","); - - grub_printf ("%s", dep->mod->name); - } - grub_xputs ("\n"); - } - - return 0; -} - -/* exit */ -static grub_err_t __attribute__ ((noreturn)) -grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char *argv[] __attribute__ ((unused))) -{ -#ifdef GRUB_MACHINE_EFI - /* - * The "exit" command is often used to launch the next boot application. - * So, erase the secrets. - */ - grub_cryptodisk_erasesecrets (); -#endif - grub_exit (); - /* Not reached. */ -} - -static grub_command_t cmd_cat, cmd_help; -static grub_command_t cmd_dump, cmd_rmmod, cmd_lsmod, cmd_exit; - -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_dump = - grub_register_command_lockdown ("dump", grub_mini_cmd_dump, - N_("ADDR [SIZE]"), N_("Show memory contents.")); - 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.")); -} - -GRUB_MOD_FINI(minicmd) -{ - grub_unregister_command (cmd_cat); - grub_unregister_command (cmd_help); - grub_unregister_command (cmd_dump); - grub_unregister_command (cmd_rmmod); - grub_unregister_command (cmd_lsmod); - grub_unregister_command (cmd_exit); -} diff --git a/grub-core/commands/mips/loongson/lsspd.c b/grub-core/commands/mips/loongson/lsspd.c deleted file mode 100644 index 97569816d..000000000 --- a/grub-core/commands/mips/loongson/lsspd.c +++ /dev/null @@ -1,103 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -grub_cmd_lsspd (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - grub_pci_device_t dev; - grub_port_t smbbase; - int i; - grub_err_t err; - - if (!grub_cs5536_find (&dev)) - { - grub_puts_ (N_("No CS5536 found")); - return GRUB_ERR_NONE; - } - grub_printf_ (N_("CS5536 at %d:%d.%d\n"), grub_pci_get_bus (dev), - grub_pci_get_device (dev), grub_pci_get_function (dev)); - - err = grub_cs5536_init_smbus (dev, 0x7fff, &smbbase); - if (err) - return err; - - /* TRANSLATORS: System management bus is often used to access components like - RAM (info only, not data) or batteries. I/O space is where in memory - its ports are. */ - grub_printf_ (N_("System management bus controller I/O space is at 0x%x\n"), - smbbase); - - for (i = GRUB_SMB_RAM_START_ADDR; - i < GRUB_SMB_RAM_START_ADDR + GRUB_SMB_RAM_NUM_MAX; i++) - { - struct grub_smbus_spd spd; - grub_memset (&spd, 0, sizeof (spd)); - /* TRANSLATORS: it's shown in a report in a way - like number 1: ... number 2: ... - */ - grub_printf_ (N_("RAM slot number %d\n"), i); - err = grub_cs5536_read_spd (smbbase, i, &spd); - if (err) - { - grub_print_error (); - continue; - } - grub_printf_ (N_("Written SPD bytes: %d B.\n"), spd.written_size); - grub_printf_ (N_("Total flash size: %d B.\n"), - 1 << spd.log_total_flash_size); - if (spd.memory_type == GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2) - { - char str[sizeof (spd.ddr2.part_number) + 1]; - grub_puts_ (N_("Memory type: DDR2.")); - grub_memcpy (str, spd.ddr2.part_number, - sizeof (spd.ddr2.part_number)); - str[sizeof (spd.ddr2.part_number)] = 0; - grub_printf_ (N_("Part no: %s.\n"), str); - } - else - grub_puts_ (N_("Memory type: Unknown.")); - } - - return GRUB_ERR_NONE; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(lsspd) -{ - cmd = grub_register_command ("lsspd", grub_cmd_lsspd, 0, - N_("Print Memory information.")); -} - -GRUB_MOD_FINI(lsspd) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/commands/nativedisk.c b/grub-core/commands/nativedisk.c deleted file mode 100644 index 580c8d3b0..000000000 --- a/grub-core/commands/nativedisk.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static const char *modnames_def[] = { - /* FIXME: autogenerate this. */ -#if defined (__i386__) || defined (__x86_64__) || defined (GRUB_MACHINE_MIPS_LOONGSON) - "pata", "ahci", "usbms", "ohci", "uhci", "ehci" -#elif defined (GRUB_MACHINE_MIPS_QEMU_MIPS) - "pata" -#else -#error "Fill this" -#endif - }; - -static grub_err_t -get_uuid (const char *name, char **uuid, int getnative) -{ - grub_device_t dev; - grub_fs_t fs = 0; - - *uuid = 0; - - dev = grub_device_open (name); - if (!dev) - return grub_errno; - - if (!dev->disk) - { - grub_dprintf ("nativedisk", "Skipping non-disk\n"); - grub_device_close (dev); - return 0; - } - - switch (dev->disk->dev->id) - { - /* Firmware disks. */ - case GRUB_DISK_DEVICE_BIOSDISK_ID: - case GRUB_DISK_DEVICE_OFDISK_ID: - case GRUB_DISK_DEVICE_OBDISK_ID: - case GRUB_DISK_DEVICE_EFIDISK_ID: - case GRUB_DISK_DEVICE_NAND_ID: - case GRUB_DISK_DEVICE_ARCDISK_ID: - case GRUB_DISK_DEVICE_HOSTDISK_ID: - case GRUB_DISK_DEVICE_UBOOTDISK_ID: - break; - - /* Native disks. */ - case GRUB_DISK_DEVICE_ATA_ID: - case GRUB_DISK_DEVICE_SCSI_ID: - case GRUB_DISK_DEVICE_XEN: - if (getnative) - break; - /* FALLTHROUGH */ - - /* Virtual disks. */ - /* GRUB dynamically generated files. */ - case GRUB_DISK_DEVICE_PROCFS_ID: - /* To access through host OS routines (grub-emu only). */ - case GRUB_DISK_DEVICE_HOST_ID: - /* To access coreboot roms. */ - case GRUB_DISK_DEVICE_CBFSDISK_ID: - /* GRUB-only memdisk. Can't match any of firmware devices. */ - case GRUB_DISK_DEVICE_MEMDISK_ID: - grub_dprintf ("nativedisk", "Skipping native disk %s\n", - dev->disk->name); - grub_device_close (dev); - return 0; - - /* FIXME: those probably need special handling. */ - case GRUB_DISK_DEVICE_LOOPBACK_ID: - case GRUB_DISK_DEVICE_DISKFILTER_ID: - case GRUB_DISK_DEVICE_CRYPTODISK_ID: - break; - } - if (dev) - fs = grub_fs_probe (dev); - if (!fs) - { - grub_device_close (dev); - return grub_errno; - } - if (!fs->fs_uuid || fs->fs_uuid (dev, uuid) || !*uuid) - { - grub_device_close (dev); - - if (!grub_errno) - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("%s does not support UUIDs"), fs->name); - - return grub_errno; - } - grub_device_close (dev); - return GRUB_ERR_NONE; -} - -struct search_ctx -{ - char *root_uuid; - char *prefix_uuid; - const char *prefix_path; - int prefix_found, root_found; -}; - -static int -iterate_device (const char *name, void *data) -{ - struct search_ctx *ctx = data; - char *cur_uuid; - - if (get_uuid (name, &cur_uuid, 1)) - { - if (grub_errno == GRUB_ERR_UNKNOWN_FS) - grub_errno = 0; - grub_print_error (); - return 0; - } - - grub_dprintf ("nativedisk", "checking %s: %s\n", name, - cur_uuid); - if (ctx->prefix_uuid && grub_strcasecmp (cur_uuid, ctx->prefix_uuid) == 0) - { - char *prefix; - prefix = grub_xasprintf ("(%s)/%s", name, ctx->prefix_path); - grub_env_set ("prefix", prefix); - grub_free (prefix); - ctx->prefix_found = 1; - } - if (ctx->root_uuid && grub_strcasecmp (cur_uuid, ctx->root_uuid) == 0) - { - grub_env_set ("root", name); - ctx->root_found = 1; - } - return ctx->prefix_found && ctx->root_found; -} - -static grub_err_t -grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args_in) -{ - char *uuid_root = 0, *uuid_prefix, *prefdev = 0; - const char *prefix = 0; - const char *path_prefix = 0; - int mods_loaded = 0; - grub_dl_t *mods; - const char **args; - int i; - - if (argc == 0) - { - argc = ARRAY_SIZE (modnames_def); - args = modnames_def; - } - else - args = (const char **) args_in; - - prefix = grub_env_get ("prefix"); - - if (! prefix) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix"); - - if (prefix) - path_prefix = (prefix[0] == '(') ? grub_strchr (prefix, ')') : NULL; - if (path_prefix) - path_prefix++; - else - path_prefix = prefix; - - mods = grub_calloc (argc, sizeof (mods[0])); - if (!mods) - return grub_errno; - - if (get_uuid (NULL, &uuid_root, 0)) - { - grub_free (mods); - return grub_errno; - } - - prefdev = grub_file_get_device_name (prefix); - if (grub_errno) - { - grub_print_error (); - prefdev = 0; - } - - if (get_uuid (prefdev, &uuid_prefix, 0)) - { - grub_free (uuid_root); - grub_free (prefdev); - grub_free (mods); - return grub_errno; - } - - grub_dprintf ("nativedisk", "uuid_prefix = %s, uuid_root = %s\n", - uuid_prefix, uuid_root); - - for (mods_loaded = 0; mods_loaded < argc; mods_loaded++) - { - char *filename; - grub_dl_t mod; - grub_file_t file = NULL; - grub_ssize_t size; - void *core = 0; - - mod = grub_dl_get (args[mods_loaded]); - if (mod) - { - mods[mods_loaded] = 0; - continue; - } - - filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM "/%s.mod", - prefix, args[mods_loaded]); - if (! filename) - goto fail; - - file = grub_file_open (filename, - GRUB_FILE_TYPE_GRUB_MODULE); - grub_free (filename); - if (! file) - goto fail; - - size = grub_file_size (file); - core = grub_malloc (size); - if (! core) - { - grub_file_close (file); - goto fail; - } - - if (grub_file_read (file, core, size) != (grub_ssize_t) size) - { - grub_file_close (file); - grub_free (core); - goto fail; - } - - grub_file_close (file); - - mods[mods_loaded] = grub_dl_load_core_noinit (core, size); - if (! mods[mods_loaded]) - goto fail; - } - - for (i = 0; i < argc; i++) - if (mods[i]) - grub_dl_init (mods[i]); - - if (uuid_prefix || uuid_root) - { - struct search_ctx ctx; - grub_fs_autoload_hook_t saved_autoload; - - /* No need to autoload FS since obviously we already have the necessary fs modules. */ - saved_autoload = grub_fs_autoload_hook; - grub_fs_autoload_hook = 0; - - ctx.root_uuid = uuid_root; - ctx.prefix_uuid = uuid_prefix; - ctx.prefix_path = path_prefix; - ctx.prefix_found = !uuid_prefix; - ctx.root_found = !uuid_root; - - /* FIXME: try to guess the correct values. */ - grub_device_iterate (iterate_device, &ctx); - - grub_fs_autoload_hook = saved_autoload; - } - grub_free (uuid_root); - grub_free (uuid_prefix); - grub_free (prefdev); - grub_free (mods); - - return GRUB_ERR_NONE; - - fail: - grub_free (uuid_root); - grub_free (uuid_prefix); - grub_free (prefdev); - - for (i = 0; i < mods_loaded; i++) - if (mods[i]) - { - mods[i]->fini = 0; - grub_dl_unload (mods[i]); - } - grub_free (mods); - - return grub_errno; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(nativedisk) -{ - cmd = grub_register_command ("nativedisk", grub_cmd_nativedisk, N_("[MODULE1 MODULE2 ...]"), - N_("Switch to native disk drivers. If no modules are specified default set (pata,ahci,usbms,ohci,uhci,ehci) is used")); -} - -GRUB_MOD_FINI(nativedisk) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/commands/pcidump.c b/grub-core/commands/pcidump.c deleted file mode 100644 index f72628fce..000000000 --- a/grub-core/commands/pcidump.c +++ /dev/null @@ -1,174 +0,0 @@ -/* lspci.c - List PCI devices. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct iter_cxt -{ - grub_uint32_t pciid_check_mask, pciid_check_value; - int bus, device, function; - int check_bus, check_device, check_function; -}; - -static const struct grub_arg_option options[] = - { - {0, 'd', 0, N_("Select device by vendor and device IDs."), - N_("[vendor]:[device]"), ARG_TYPE_STRING}, - {0, 's', 0, N_("Select device by its position on the bus."), - N_("[bus]:[slot][.func]"), ARG_TYPE_STRING}, - {0, 0, 0, 0, 0, 0} - }; - -static int -grub_pcidump_iter (grub_pci_device_t dev, grub_pci_id_t pciid, - void *data) -{ - struct iter_cxt *ctx = data; - grub_pci_address_t addr; - int i; - - if ((pciid & ctx->pciid_check_mask) != ctx->pciid_check_value) - return 0; - - if (ctx->check_bus && grub_pci_get_bus (dev) != ctx->bus) - return 0; - - if (ctx->check_device && grub_pci_get_device (dev) != ctx->device) - return 0; - - if (ctx->check_function && grub_pci_get_function (dev) != ctx->function) - return 0; - - for (i = 0; i < 256; i += 4) - { - addr = grub_pci_make_address (dev, i); - grub_printf ("%08x ", grub_pci_read (addr)); - if ((i & 0xc) == 0xc) - grub_printf ("\n"); - } - - return 0; -} - -static grub_err_t -grub_cmd_pcidump (grub_extcmd_context_t ctxt, - int argc __attribute__ ((unused)), - char **argv __attribute__ ((unused))) -{ - const char *ptr; - struct iter_cxt ctx = - { - .pciid_check_value = 0, - .pciid_check_mask = 0, - .check_bus = 0, - .check_device = 0, - .check_function = 0, - .bus = 0, - .function = 0, - .device = 0 - }; - - if (ctxt->state[0].set) - { - ptr = ctxt->state[0].arg; - ctx.pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff); - if (grub_errno == GRUB_ERR_BAD_NUMBER) - { - grub_errno = GRUB_ERR_NONE; - ptr = ctxt->state[0].arg; - } - else - ctx.pciid_check_mask |= 0xffff; - if (grub_errno) - return grub_errno; - if (*ptr != ':') - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':'); - ptr++; - ctx.pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff) << 16; - if (grub_errno == GRUB_ERR_BAD_NUMBER) - grub_errno = GRUB_ERR_NONE; - else - ctx.pciid_check_mask |= 0xffff0000; - } - - ctx.pciid_check_value &= ctx.pciid_check_mask; - - if (ctxt->state[1].set) - { - const char *optr; - - ptr = ctxt->state[1].arg; - optr = ptr; - ctx.bus = grub_strtoul (ptr, &ptr, 16); - if (grub_errno == GRUB_ERR_BAD_NUMBER) - { - grub_errno = GRUB_ERR_NONE; - ptr = optr; - } - else - ctx.check_bus = 1; - if (grub_errno) - return grub_errno; - if (*ptr != ':') - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':'); - ptr++; - optr = ptr; - ctx.device = grub_strtoul (ptr, &ptr, 16); - if (grub_errno == GRUB_ERR_BAD_NUMBER) - { - grub_errno = GRUB_ERR_NONE; - ptr = optr; - } - else - ctx.check_device = 1; - if (*ptr == '.') - { - ptr++; - ctx.function = grub_strtoul (ptr, &ptr, 16); - if (grub_errno) - return grub_errno; - ctx.check_function = 1; - } - } - - grub_pci_iterate (grub_pcidump_iter, &ctx); - return GRUB_ERR_NONE; -} - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT(pcidump) -{ - cmd = grub_register_extcmd ("pcidump", grub_cmd_pcidump, 0, - N_("[-s POSITION] [-d DEVICE]"), - N_("Show raw dump of the PCI configuration space."), options); -} - -GRUB_MOD_FINI(pcidump) -{ - grub_unregister_extcmd (cmd); -} diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c deleted file mode 100644 index 5fadc33c4..000000000 --- a/grub-core/commands/pgp.c +++ /dev/null @@ -1,1020 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -enum - { - OPTION_SKIP_SIG = 0 - }; - -static const struct grub_arg_option options[] = - { - {"skip-sig", 's', 0, - N_("Skip signature-checking of the public key file."), 0, ARG_TYPE_NONE}, - {0, 0, 0, 0, 0, 0} - }; - -static grub_err_t -read_packet_header (grub_file_t sig, grub_uint8_t *out_type, grub_size_t *len) -{ - grub_uint8_t type; - grub_uint8_t l; - grub_uint16_t l16; - grub_uint32_t l32; - - /* New format. */ - switch (grub_file_read (sig, &type, sizeof (type))) - { - case 1: - break; - case 0: - { - *out_type = 0xff; - return 0; - } - default: - if (grub_errno) - return grub_errno; - /* TRANSLATORS: it's about GNUPG signatures. */ - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - } - - if (type == 0) - { - *out_type = 0xfe; - return 0; - } - - if (!(type & 0x80)) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - if (type & 0x40) - { - *out_type = (type & 0x3f); - if (grub_file_read (sig, &l, sizeof (l)) != 1) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - if (l < 192) - { - *len = l; - return 0; - } - if (l < 224) - { - *len = (l - 192) << GRUB_CHAR_BIT; - if (grub_file_read (sig, &l, sizeof (l)) != 1) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - *len |= l; - return 0; - } - if (l == 255) - { - if (grub_file_read (sig, &l32, sizeof (l32)) != sizeof (l32)) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - *len = grub_be_to_cpu32 (l32); - return 0; - } - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - } - *out_type = ((type >> 2) & 0xf); - switch (type & 0x3) - { - case 0: - if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l)) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - *len = l; - return 0; - case 1: - if (grub_file_read (sig, &l16, sizeof (l16)) != sizeof (l16)) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - *len = grub_be_to_cpu16 (l16); - return 0; - case 2: - if (grub_file_read (sig, &l32, sizeof (l32)) != sizeof (l32)) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - *len = grub_be_to_cpu32 (l32); - return 0; - } - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); -} - -struct signature_v4_header -{ - grub_uint8_t type; - grub_uint8_t pkeyalgo; - grub_uint8_t hash; - grub_uint16_t hashed_sub; -} GRUB_PACKED; - -const char *hashes[] = { - [0x01] = "md5", - [0x02] = "sha1", - [0x03] = "ripemd160", - [0x08] = "sha256", - [0x09] = "sha384", - [0x0a] = "sha512", - [0x0b] = "sha224" -}; - -struct gcry_pk_spec *grub_crypto_pk_dsa; -struct gcry_pk_spec *grub_crypto_pk_ecdsa; -struct gcry_pk_spec *grub_crypto_pk_rsa; - -static int -dsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval, - const gcry_md_spec_t *hash, struct grub_public_subkey *sk); -static int -rsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval, - const gcry_md_spec_t *hash, struct grub_public_subkey *sk); - -struct -{ - const char *name; - grub_size_t nmpisig; - grub_size_t nmpipub; - struct gcry_pk_spec **algo; - int (*pad) (gcry_mpi_t *hmpi, grub_uint8_t *hval, - const gcry_md_spec_t *hash, struct grub_public_subkey *sk); - const char *module; -} pkalgos[] = - { - [1] = { "rsa", 1, 2, &grub_crypto_pk_rsa, rsa_pad, "gcry_rsa" }, - [3] = { "rsa", 1, 2, &grub_crypto_pk_rsa, rsa_pad, "gcry_rsa" }, - [17] = { "dsa", 2, 4, &grub_crypto_pk_dsa, dsa_pad, "gcry_dsa" }, - }; - -struct grub_public_key -{ - struct grub_public_key *next; - struct grub_public_subkey *subkeys; -}; - -struct grub_public_subkey -{ - struct grub_public_subkey *next; - grub_uint8_t type; - grub_uint32_t fingerprint[5]; - gcry_mpi_t mpis[10]; -}; - -static void -free_pk (struct grub_public_key *pk) -{ - struct grub_public_subkey *nsk, *sk; - for (sk = pk->subkeys; sk; sk = nsk) - { - grub_size_t i; - for (i = 0; i < ARRAY_SIZE (sk->mpis); i++) - if (sk->mpis[i]) - gcry_mpi_release (sk->mpis[i]); - nsk = sk->next; - grub_free (sk); - } - grub_free (pk); -} - -#define READBUF_SIZE 4096 - -struct grub_public_key * -grub_load_public_key (grub_file_t f) -{ - grub_err_t err; - struct grub_public_key *ret; - struct grub_public_subkey **last = 0; - void *fingerprint_context = NULL; - grub_uint8_t *buffer = NULL; - - ret = grub_zalloc (sizeof (*ret)); - if (!ret) - { - grub_free (fingerprint_context); - return NULL; - } - - buffer = grub_zalloc (READBUF_SIZE); - fingerprint_context = grub_zalloc (GRUB_MD_SHA1->contextsize); - - if (!buffer || !fingerprint_context) - goto fail; - - last = &ret->subkeys; - - while (1) - { - grub_uint8_t type; - grub_size_t len; - grub_uint8_t v, pk; - grub_uint32_t creation_time; - grub_off_t pend; - struct grub_public_subkey *sk; - grub_size_t i; - grub_uint16_t len_be; - - err = read_packet_header (f, &type, &len); - - if (err) - goto fail; - if (type == 0xfe) - continue; - if (type == 0xff) - { - grub_free (fingerprint_context); - grub_free (buffer); - return ret; - } - - grub_dprintf ("crypt", "len = %x\n", (int) len); - - pend = grub_file_tell (f) + len; - if (type != 6 && type != 14 - && type != 5 && type != 7) - { - grub_file_seek (f, pend); - continue; - } - - if (grub_file_read (f, &v, sizeof (v)) != sizeof (v)) - { - grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - goto fail; - } - - grub_dprintf ("crypt", "v = %x\n", v); - - if (v != 4) - { - grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - goto fail; - } - if (grub_file_read (f, &creation_time, sizeof (creation_time)) != sizeof (creation_time)) - { - grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - goto fail; - } - - grub_dprintf ("crypt", "time = %x\n", creation_time); - - if (grub_file_read (f, &pk, sizeof (pk)) != sizeof (pk)) - { - grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - goto fail; - } - - grub_dprintf ("crypt", "pk = %x\n", pk); - - if (pk >= ARRAY_SIZE (pkalgos) || pkalgos[pk].name == NULL) - { - grub_file_seek (f, pend); - continue; - } - - sk = grub_zalloc (sizeof (struct grub_public_subkey)); - if (!sk) - goto fail; - - grub_memset (fingerprint_context, 0, GRUB_MD_SHA1->contextsize); - GRUB_MD_SHA1->init (fingerprint_context); - GRUB_MD_SHA1->write (fingerprint_context, "\x99", 1); - len_be = grub_cpu_to_be16 (len); - GRUB_MD_SHA1->write (fingerprint_context, &len_be, sizeof (len_be)); - GRUB_MD_SHA1->write (fingerprint_context, &v, sizeof (v)); - GRUB_MD_SHA1->write (fingerprint_context, &creation_time, sizeof (creation_time)); - GRUB_MD_SHA1->write (fingerprint_context, &pk, sizeof (pk)); - - for (i = 0; i < pkalgos[pk].nmpipub; i++) - { - grub_uint16_t l; - grub_size_t lb; - if (grub_file_read (f, &l, sizeof (l)) != sizeof (l)) - { - grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - break; - } - - lb = (grub_be_to_cpu16 (l) + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT; - if (lb > READBUF_SIZE - sizeof (grub_uint16_t)) - { - grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - break; - } - if (grub_file_read (f, buffer + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb) - { - grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - break; - } - grub_memcpy (buffer, &l, sizeof (l)); - - GRUB_MD_SHA1->write (fingerprint_context, buffer, lb + sizeof (grub_uint16_t)); - - if (gcry_mpi_scan (&sk->mpis[i], GCRYMPI_FMT_PGP, - buffer, lb + sizeof (grub_uint16_t), 0)) - { - grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - break; - } - } - - if (i < pkalgos[pk].nmpipub) - { - grub_free (sk); - goto fail; - } - - GRUB_MD_SHA1->final (fingerprint_context); - - grub_memcpy (sk->fingerprint, GRUB_MD_SHA1->read (fingerprint_context), 20); - - *last = sk; - last = &sk->next; - - grub_dprintf ("crypt", "actual pos: %x, expected: %x\n", (int)grub_file_tell (f), (int)pend); - - grub_file_seek (f, pend); - } - fail: - free_pk (ret); - grub_free (fingerprint_context); - grub_free (buffer); - return NULL; -} - -struct grub_public_key *grub_pk_trusted; - -struct grub_public_subkey * -grub_crypto_pk_locate_subkey (grub_uint64_t keyid, struct grub_public_key *pkey) -{ - struct grub_public_subkey *sk; - for (sk = pkey->subkeys; sk; sk = sk->next) - if (grub_memcmp (sk->fingerprint + 3, &keyid, 8) == 0) - return sk; - return 0; -} - -struct grub_public_subkey * -grub_crypto_pk_locate_subkey_in_trustdb (grub_uint64_t keyid) -{ - struct grub_public_key *pkey; - struct grub_public_subkey *sk; - for (pkey = grub_pk_trusted; pkey; pkey = pkey->next) - { - sk = grub_crypto_pk_locate_subkey (keyid, pkey); - if (sk) - return sk; - } - return 0; -} - - -static int -dsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval, - const gcry_md_spec_t *hash, struct grub_public_subkey *sk) -{ - unsigned nbits = gcry_mpi_get_nbits (sk->mpis[1]); - grub_dprintf ("crypt", "must be %u bits got %d bits\n", nbits, - (int)(8 * hash->mdlen)); - return gcry_mpi_scan (hmpi, GCRYMPI_FMT_USG, hval, - nbits / 8 < (unsigned) hash->mdlen ? nbits / 8 - : (unsigned) hash->mdlen, 0); -} - -static int -rsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval, - const gcry_md_spec_t *hash, struct grub_public_subkey *sk) -{ - grub_size_t tlen, emlen, fflen; - grub_uint8_t *em, *emptr; - unsigned nbits = gcry_mpi_get_nbits (sk->mpis[0]); - int ret; - tlen = hash->mdlen + hash->asnlen; - emlen = (nbits + 7) / 8; - if (emlen < tlen + 11) - return 1; - - em = grub_malloc (emlen); - if (!em) - return 1; - - em[0] = 0x00; - em[1] = 0x01; - fflen = emlen - tlen - 3; - for (emptr = em + 2; emptr < em + 2 + fflen; emptr++) - *emptr = 0xff; - *emptr++ = 0x00; - grub_memcpy (emptr, hash->asnoid, hash->asnlen); - emptr += hash->asnlen; - grub_memcpy (emptr, hval, hash->mdlen); - - ret = gcry_mpi_scan (hmpi, GCRYMPI_FMT_USG, em, emlen, 0); - grub_free (em); - return ret; -} - -struct grub_pubkey_context -{ - grub_file_t sig; - struct signature_v4_header v4; - grub_uint8_t v; - const gcry_md_spec_t *hash; - void *hash_context; -}; - -static grub_err_t -grub_verify_signature_init (struct grub_pubkey_context *ctxt, grub_file_t sig) -{ - grub_size_t len; - grub_uint8_t h; - grub_uint8_t t; - grub_uint8_t pk; - grub_err_t err; - grub_uint8_t type = 0; - - grub_memset (ctxt, 0, sizeof (*ctxt)); - - err = read_packet_header (sig, &type, &len); - if (err) - return err; - - if (type != 0x2) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - - if (grub_file_read (sig, &ctxt->v, sizeof (ctxt->v)) != sizeof (ctxt->v)) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - - if (ctxt->v != 4) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - - if (grub_file_read (sig, &ctxt->v4, sizeof (ctxt->v4)) != sizeof (ctxt->v4)) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - - h = ctxt->v4.hash; - t = ctxt->v4.type; - pk = ctxt->v4.pkeyalgo; - - if (t != 0) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - - if (h >= ARRAY_SIZE (hashes) || hashes[h] == NULL) - return grub_error (GRUB_ERR_BAD_SIGNATURE, "unknown hash"); - - if (pk >= ARRAY_SIZE (pkalgos) || pkalgos[pk].name == NULL) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - - ctxt->hash = grub_crypto_lookup_md_by_name (hashes[h]); - if (!ctxt->hash) - return grub_error (GRUB_ERR_BAD_SIGNATURE, "hash `%s' not loaded", hashes[h]); - - grub_dprintf ("crypt", "alive\n"); - - ctxt->hash_context = grub_zalloc (ctxt->hash->contextsize); - if (!ctxt->hash_context) - return grub_errno; - - ctxt->hash->init (ctxt->hash_context); - ctxt->sig = sig; - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_pubkey_write (void *ctxt_, void *buf, grub_size_t size) -{ - struct grub_pubkey_context *ctxt = ctxt_; - ctxt->hash->write (ctxt->hash_context, buf, size); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_verify_signature_real (struct grub_pubkey_context *ctxt, - struct grub_public_key *pkey) -{ - gcry_mpi_t mpis[10]; - grub_uint8_t pk = ctxt->v4.pkeyalgo; - grub_size_t i; - grub_uint8_t *readbuf = NULL; - unsigned char *hval; - grub_ssize_t rem = grub_be_to_cpu16 (ctxt->v4.hashed_sub); - grub_uint32_t headlen = grub_cpu_to_be32 (rem + 6); - grub_uint8_t s; - grub_uint16_t unhashed_sub; - grub_ssize_t r; - grub_uint8_t hash_start[2]; - gcry_mpi_t hmpi; - grub_uint64_t keyid = 0; - struct grub_public_subkey *sk; - - readbuf = grub_malloc (READBUF_SIZE); - if (!readbuf) - goto fail; - - ctxt->hash->write (ctxt->hash_context, &ctxt->v, sizeof (ctxt->v)); - ctxt->hash->write (ctxt->hash_context, &ctxt->v4, sizeof (ctxt->v4)); - while (rem) - { - r = grub_file_read (ctxt->sig, readbuf, - rem < READBUF_SIZE ? rem : READBUF_SIZE); - if (r < 0) - goto fail; - if (r == 0) - break; - ctxt->hash->write (ctxt->hash_context, readbuf, r); - rem -= r; - } - ctxt->hash->write (ctxt->hash_context, &ctxt->v, sizeof (ctxt->v)); - s = 0xff; - ctxt->hash->write (ctxt->hash_context, &s, sizeof (s)); - ctxt->hash->write (ctxt->hash_context, &headlen, sizeof (headlen)); - r = grub_file_read (ctxt->sig, &unhashed_sub, sizeof (unhashed_sub)); - if (r != sizeof (unhashed_sub)) - goto fail; - { - grub_uint8_t *ptr; - grub_uint32_t l; - rem = grub_be_to_cpu16 (unhashed_sub); - if (rem > READBUF_SIZE) - goto fail; - r = grub_file_read (ctxt->sig, readbuf, rem); - if (r != rem) - goto fail; - for (ptr = readbuf; ptr < readbuf + rem; ptr += l) - { - if (*ptr < 192) - l = *ptr++; - else if (*ptr < 255) - { - if (ptr + 1 >= readbuf + rem) - break; - l = (((ptr[0] & ~192) << GRUB_CHAR_BIT) | ptr[1]) + 192; - ptr += 2; - } - else - { - if (ptr + 5 >= readbuf + rem) - break; - l = grub_be_to_cpu32 (grub_get_unaligned32 (ptr + 1)); - ptr += 5; - } - if (*ptr == 0x10 && l >= 8) - keyid = grub_get_unaligned64 (ptr + 1); - } - } - - ctxt->hash->final (ctxt->hash_context); - - grub_dprintf ("crypt", "alive\n"); - - hval = ctxt->hash->read (ctxt->hash_context); - - if (grub_file_read (ctxt->sig, hash_start, sizeof (hash_start)) != sizeof (hash_start)) - goto fail; - if (grub_memcmp (hval, hash_start, sizeof (hash_start)) != 0) - goto fail; - - grub_dprintf ("crypt", "@ %x\n", (int)grub_file_tell (ctxt->sig)); - - for (i = 0; i < pkalgos[pk].nmpisig; i++) - { - grub_uint16_t l; - grub_size_t lb; - grub_dprintf ("crypt", "alive\n"); - if (grub_file_read (ctxt->sig, &l, sizeof (l)) != sizeof (l)) - goto fail; - grub_dprintf ("crypt", "alive\n"); - lb = (grub_be_to_cpu16 (l) + 7) / 8; - grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l)); - if (lb > READBUF_SIZE - sizeof (grub_uint16_t)) - goto fail; - grub_dprintf ("crypt", "alive\n"); - if (grub_file_read (ctxt->sig, readbuf + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb) - goto fail; - grub_dprintf ("crypt", "alive\n"); - grub_memcpy (readbuf, &l, sizeof (l)); - grub_dprintf ("crypt", "alive\n"); - - if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP, - readbuf, lb + sizeof (grub_uint16_t), 0)) - goto fail; - grub_dprintf ("crypt", "alive\n"); - } - - if (pkey) - sk = grub_crypto_pk_locate_subkey (keyid, pkey); - else - sk = grub_crypto_pk_locate_subkey_in_trustdb (keyid); - if (!sk) - { - /* TRANSLATORS: %08x is 32-bit key id. */ - grub_error (GRUB_ERR_BAD_SIGNATURE, - N_("public key %08" PRIxGRUB_UINT64_T " not found"), keyid); - goto fail; - } - - if (pkalgos[pk].pad (&hmpi, hval, ctxt->hash, sk)) - goto fail; - if (!*pkalgos[pk].algo) - { - grub_dl_load (pkalgos[pk].module); - grub_errno = GRUB_ERR_NONE; - } - - if (!*pkalgos[pk].algo) - { - grub_error (GRUB_ERR_BAD_SIGNATURE, N_("module `%s' isn't loaded"), - pkalgos[pk].module); - goto fail; - } - if ((*pkalgos[pk].algo)->verify (0, hmpi, mpis, sk->mpis, 0, 0)) - goto fail; - - grub_free (readbuf); - - return GRUB_ERR_NONE; - - fail: - grub_free (readbuf); - if (!grub_errno) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - return grub_errno; -} - -static void -grub_pubkey_close_real (struct grub_pubkey_context *ctxt) -{ - if (ctxt->sig) - grub_file_close (ctxt->sig); - if (ctxt->hash_context) - grub_free (ctxt->hash_context); -} - -static void -grub_pubkey_close (void *ctxt) -{ - grub_pubkey_close_real (ctxt); - grub_free (ctxt); -} - -grub_err_t -grub_verify_signature (grub_file_t f, const char *fsig, - struct grub_public_key *pkey) -{ - grub_file_t sig; - grub_err_t err; - struct grub_pubkey_context ctxt; - grub_uint8_t *readbuf = NULL; - - sig = grub_file_open (fsig, - GRUB_FILE_TYPE_SIGNATURE - | GRUB_FILE_TYPE_NO_DECOMPRESS); - if (!sig) - return grub_errno; - - err = grub_verify_signature_init (&ctxt, sig); - if (err) - { - grub_file_close (sig); - return err; - } - - readbuf = grub_zalloc (READBUF_SIZE); - if (!readbuf) - goto fail; - - while (1) - { - grub_ssize_t r; - r = grub_file_read (f, readbuf, READBUF_SIZE); - if (r < 0) - goto fail; - if (r == 0) - break; - err = grub_pubkey_write (&ctxt, readbuf, r); - if (err) - return err; - } - - grub_verify_signature_real (&ctxt, pkey); - fail: - grub_pubkey_close_real (&ctxt); - return grub_errno; -} - -static grub_err_t -grub_cmd_trust (grub_extcmd_context_t ctxt, - int argc, char **args) -{ - grub_file_t pkf; - struct grub_public_key *pk = NULL; - - if (argc < 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - - pkf = grub_file_open (args[0], - GRUB_FILE_TYPE_PUBLIC_KEY_TRUST - | GRUB_FILE_TYPE_NO_DECOMPRESS - | (ctxt->state[OPTION_SKIP_SIG].set - ? GRUB_FILE_TYPE_SKIP_SIGNATURE - : GRUB_FILE_TYPE_NONE)); - if (!pkf) - return grub_errno; - pk = grub_load_public_key (pkf); - if (!pk) - { - grub_file_close (pkf); - return grub_errno; - } - grub_file_close (pkf); - - pk->next = grub_pk_trusted; - grub_pk_trusted = pk; - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_list (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - struct grub_public_key *pk = NULL; - struct grub_public_subkey *sk = NULL; - - for (pk = grub_pk_trusted; pk; pk = pk->next) - for (sk = pk->subkeys; sk; sk = sk->next) - { - unsigned i; - for (i = 0; i < 20; i += 2) - grub_printf ("%02x%02x ", ((grub_uint8_t *) sk->fingerprint)[i], - ((grub_uint8_t *) sk->fingerprint)[i + 1]); - grub_printf ("\n"); - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_distrust (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) -{ - grub_uint32_t keyid, keyid_be; - struct grub_public_key **pkey; - struct grub_public_subkey *sk; - - if (argc < 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - keyid = grub_strtoull (args[0], 0, 16); - if (grub_errno) - return grub_errno; - keyid_be = grub_cpu_to_be32 (keyid); - - for (pkey = &grub_pk_trusted; *pkey; pkey = &((*pkey)->next)) - { - struct grub_public_key *next; - for (sk = (*pkey)->subkeys; sk; sk = sk->next) - if (grub_memcmp (sk->fingerprint + 4, &keyid_be, 4) == 0) - break; - if (!sk) - continue; - next = (*pkey)->next; - free_pk (*pkey); - *pkey = next; - return GRUB_ERR_NONE; - } - /* TRANSLATORS: %08x is 32-bit key id. */ - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("public key %08x not found"), keyid); -} - -static grub_err_t -grub_cmd_verify_signature (grub_extcmd_context_t ctxt, - int argc, char **args) -{ - grub_file_t f = NULL; - grub_err_t err = GRUB_ERR_NONE; - struct grub_public_key *pk = NULL; - - grub_dprintf ("crypt", "alive\n"); - - if (argc < 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); - - grub_dprintf ("crypt", "alive\n"); - - if (argc > 2) - { - grub_file_t pkf; - pkf = grub_file_open (args[2], - GRUB_FILE_TYPE_PUBLIC_KEY - | GRUB_FILE_TYPE_NO_DECOMPRESS - | (ctxt->state[OPTION_SKIP_SIG].set - ? GRUB_FILE_TYPE_SKIP_SIGNATURE - : GRUB_FILE_TYPE_NONE)); - if (!pkf) - return grub_errno; - pk = grub_load_public_key (pkf); - if (!pk) - { - grub_file_close (pkf); - return grub_errno; - } - grub_file_close (pkf); - } - - f = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE); - if (!f) - { - err = grub_errno; - goto fail; - } - - err = grub_verify_signature (f, args[1], pk); - fail: - if (f) - grub_file_close (f); - if (pk) - free_pk (pk); - return err; -} - -static int sec = 0; - -static grub_err_t -grub_pubkey_init (grub_file_t io, enum grub_file_type type __attribute__ ((unused)), - void **context, enum grub_verify_flags *flags) -{ - grub_file_t sig; - char *fsuf, *ptr; - grub_err_t err; - struct grub_pubkey_context *ctxt; - - if (!sec) - { - *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; - return GRUB_ERR_NONE; - } - - fsuf = grub_malloc (grub_strlen (io->name) + sizeof (".sig")); - if (!fsuf) - return grub_errno; - ptr = grub_stpcpy (fsuf, io->name); - grub_memcpy (ptr, ".sig", sizeof (".sig")); - - sig = grub_file_open (fsuf, GRUB_FILE_TYPE_SIGNATURE); - grub_free (fsuf); - if (!sig) - return grub_errno; - - ctxt = grub_malloc (sizeof (*ctxt)); - if (!ctxt) - { - grub_file_close (sig); - return grub_errno; - } - err = grub_verify_signature_init (ctxt, sig); - if (err) - { - grub_free (ctxt); - grub_file_close (sig); - return err; - } - *context = ctxt; - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_pubkey_fini (void *ctxt) -{ - return grub_verify_signature_real (ctxt, NULL); -} - -static char * -grub_env_write_sec (struct grub_env_var *var __attribute__ ((unused)), - const char *val) -{ - sec = (*val == '1') || (*val == 'e'); - return grub_strdup (sec ? "enforce" : "no"); -} - -static grub_ssize_t -pseudo_read (struct grub_file *file, char *buf, grub_size_t len) -{ - grub_memcpy (buf, (grub_uint8_t *) file->data + file->offset, len); - return len; -} - - -/* Filesystem descriptor. */ -struct grub_fs pseudo_fs = - { - .name = "pseudo", - .fs_read = pseudo_read - }; - -struct grub_file_verifier grub_pubkey_verifier = - { - .name = "pgp", - .init = grub_pubkey_init, - .fini = grub_pubkey_fini, - .write = grub_pubkey_write, - .close = grub_pubkey_close, - }; - -static grub_extcmd_t cmd, cmd_trust; -static grub_command_t cmd_distrust, cmd_list; - -GRUB_MOD_INIT(pgp) -{ - const char *val; - struct grub_module_header *header; - - val = grub_env_get ("check_signatures"); - if (val && (val[0] == '1' || val[0] == 'e')) - sec = 1; - else - sec = 0; - - grub_register_variable_hook ("check_signatures", 0, grub_env_write_sec); - grub_env_export ("check_signatures"); - - grub_pk_trusted = 0; - FOR_MODULES (header) - { - struct grub_file pseudo_file; - struct grub_public_key *pk = NULL; - - grub_memset (&pseudo_file, 0, sizeof (pseudo_file)); - - /* Not an ELF module, skip. */ - if (header->type != OBJ_TYPE_PUBKEY) - continue; - - pseudo_file.fs = &pseudo_fs; - pseudo_file.size = (header->size - sizeof (struct grub_module_header)); - pseudo_file.data = (char *) header + sizeof (struct grub_module_header); - - pk = grub_load_public_key (&pseudo_file); - if (!pk) - grub_fatal ("error loading initial key: %s\n", grub_errmsg); - - pk->next = grub_pk_trusted; - grub_pk_trusted = pk; - } - - if (!val) - grub_env_set ("check_signatures", grub_pk_trusted ? "enforce" : "no"); - - cmd = grub_register_extcmd ("verify_detached", grub_cmd_verify_signature, 0, - N_("[-s|--skip-sig] FILE SIGNATURE_FILE [PUBKEY_FILE]"), - N_("Verify detached signature."), - options); - cmd_trust = grub_register_extcmd ("trust", grub_cmd_trust, 0, - N_("[-s|--skip-sig] PUBKEY_FILE"), - N_("Add PUBKEY_FILE to trusted keys."), - options); - cmd_list = grub_register_command ("list_trusted", grub_cmd_list, - 0, - N_("Show the list of trusted keys.")); - cmd_distrust = grub_register_command ("distrust", grub_cmd_distrust, - N_("PUBKEY_ID"), - N_("Remove PUBKEY_ID from trusted keys.")); - - grub_verifier_register (&grub_pubkey_verifier); -} - -GRUB_MOD_FINI(pgp) -{ - grub_register_variable_hook ("check_signatures", NULL, NULL); - grub_env_unset ("check_signatures"); - grub_verifier_unregister (&grub_pubkey_verifier); - grub_unregister_extcmd (cmd); - grub_unregister_extcmd (cmd_trust); - grub_unregister_command (cmd_list); - grub_unregister_command (cmd_distrust); -} diff --git a/grub-core/commands/regexp.c b/grub-core/commands/regexp.c deleted file mode 100644 index 246af39f0..000000000 --- a/grub-core/commands/regexp.c +++ /dev/null @@ -1,168 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static const struct grub_arg_option options[] = - { - { "set", 's', GRUB_ARG_OPTION_REPEATABLE, - /* TRANSLATORS: in regexp you can mark some - groups with parentheses. These groups are - then numbered and you can save some of - them in variables. In other programs - those components are often referenced with - back slash, e.g. \1. Compare - sed -e 's,\([a-z][a-z]*\),lowercase=\1,g' - The whole matching component is saved in VARNAME, not its number. - */ - N_("Store matched component NUMBER in VARNAME."), - N_("[NUMBER:]VARNAME"), ARG_TYPE_STRING }, - { 0, 0, 0, 0, 0, 0 } - }; - -static grub_err_t -setvar (char *str, char *v, regmatch_t *m) -{ - char ch; - grub_err_t err; - ch = str[m->rm_eo]; - str[m->rm_eo] = '\0'; - err = grub_env_set (v, str + m->rm_so); - str[m->rm_eo] = ch; - return err; -} - -static grub_err_t -set_matches (char **varnames, char *str, grub_size_t nmatches, - regmatch_t *matches) -{ - int i; - char *p; - const char * q; - grub_err_t err; - unsigned long j; - - for (i = 0; varnames && varnames[i]; i++) - { - err = GRUB_ERR_NONE; - p = grub_strchr (varnames[i], ':'); - if (! p) - { - /* varname w/o index defaults to 1 */ - if (nmatches < 2 || matches[1].rm_so == -1) - grub_env_unset (varnames[i]); - else - err = setvar (str, varnames[i], &matches[1]); - } - else - { - j = grub_strtoul (varnames[i], &q, 10); - if (q != p) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "invalid variable name format %s", varnames[i]); - - if (nmatches <= j || matches[j].rm_so == -1) - grub_env_unset (p + 1); - else - err = setvar (str, p + 1, &matches[j]); - } - - if (err != GRUB_ERR_NONE) - return err; - } - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_regexp (grub_extcmd_context_t ctxt, int argc, char **args) -{ - regex_t regex; - int ret; - grub_size_t s; - char *comperr; - grub_err_t err; - regmatch_t *matches = 0; - - if (argc != 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); - - ret = regcomp (®ex, args[0], REG_EXTENDED); - if (ret) - goto fail; - - matches = grub_calloc (regex.re_nsub + 1, sizeof (*matches)); - if (! matches) - goto fail; - - ret = regexec (®ex, args[1], regex.re_nsub + 1, matches, 0); - if (!ret) - { - err = set_matches (ctxt->state[0].args, args[1], - regex.re_nsub + 1, matches); - regfree (®ex); - grub_free (matches); - return err; - } - - fail: - grub_free (matches); - s = regerror (ret, ®ex, 0, 0); - comperr = grub_malloc (s); - if (!comperr) - { - regfree (®ex); - return grub_errno; - } - regerror (ret, ®ex, comperr, s); - err = grub_error (GRUB_ERR_TEST_FAILURE, "%s", comperr); - regfree (®ex); - grub_free (comperr); - return err; -} - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT(regexp) -{ - cmd = grub_register_extcmd ("regexp", grub_cmd_regexp, 0, - /* TRANSLATORS: This are two arguments. So it's - two separate units to translate and pay - attention not to reverse them. */ - N_("REGEXP STRING"), - N_("Test if REGEXP matches STRING."), options); - - /* Setup GRUB script wildcard translator. */ - grub_wildcard_translator = &grub_filename_translator; -} - -GRUB_MOD_FINI(regexp) -{ - grub_unregister_extcmd (cmd); - grub_wildcard_translator = 0; -} diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c deleted file mode 100644 index 49b679e80..000000000 --- a/grub-core/commands/search.c +++ /dev/null @@ -1,412 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct cache_entry -{ - struct cache_entry *next; - char *key; - char *value; -}; - -static struct cache_entry *cache; - -/* Context for FUNC_NAME. */ -struct search_ctx -{ - const char *key; - const char *var; - enum search_flags flags; - char **hints; - unsigned nhints; - int count; - int is_cache; -}; - -static bool -is_unencrypted_disk (grub_disk_t disk) -{ - grub_command_t cmd; - char *disk_str; - int disk_str_len; - int res; - - if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) - return false; /* This is (crypto) disk. */ - - if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID) - { - char opt[] = "--quiet"; - char *args[2]; - - cmd = grub_command_find ("cryptocheck"); - if (cmd == NULL) /* No diskfilter module loaded for some reason. */ - return true; - - disk_str_len = grub_strlen (disk->name) + 2 + 1; - disk_str = grub_malloc (disk_str_len); - if (disk_str == NULL) /* Something is wrong, better report as unencrypted. */ - return true; - - grub_snprintf (disk_str, disk_str_len, "(%s)", disk->name); - args[0] = opt; - args[1] = disk_str; - res = cmd->func (cmd, 2, args); - grub_free (disk_str); - return (res != GRUB_ERR_NONE) ? true : false; /* GRUB_ERR_NONE for encrypted. */ - } - return true; -} - -/* Helper for FUNC_NAME. */ -static int -iterate_device (const char *name, void *data) -{ - struct search_ctx *ctx = data; - int found = 0; - - /* Skip floppy drives when requested. */ - if (ctx->flags & SEARCH_FLAGS_NO_FLOPPY && - name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') - return 0; - - /* Limit to EFI disks when requested. */ - if (ctx->flags & SEARCH_FLAGS_EFIDISK_ONLY) - { - grub_device_t dev; - - dev = grub_device_open (name); - if (dev == NULL) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - if (dev->disk == NULL || dev->disk->dev->id != GRUB_DISK_DEVICE_EFIDISK_ID) - { - grub_device_close (dev); - grub_errno = GRUB_ERR_NONE; - return 0; - } - grub_device_close (dev); - } - - /* Limit to encrypted disks when requested. */ - if (ctx->flags & SEARCH_FLAGS_CRYPTODISK_ONLY) - { - grub_device_t dev; - - dev = grub_device_open (name); - if (dev == NULL) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - if (dev->disk == NULL || is_unencrypted_disk (dev->disk) == true) - { - grub_device_close (dev); - grub_errno = GRUB_ERR_NONE; - return 0; - } - grub_device_close (dev); - } - -#ifdef DO_SEARCH_FS_UUID -#define compare_fn grub_strcasecmp -#else -#define compare_fn grub_strcmp -#endif - -#ifdef DO_SEARCH_FILE - { - char *buf; - grub_file_t file; - - buf = grub_xasprintf ("(%s)%s", name, ctx->key); - if (! buf) - return 1; - - file = grub_file_open (buf, GRUB_FILE_TYPE_FS_SEARCH - | GRUB_FILE_TYPE_NO_DECOMPRESS); - 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 read_fn fs_uuid -#else -#define read_fn fs_label -#endif - - if (fs && fs->read_fn) - { - fs->read_fn (dev, &quid); - - if (grub_errno == GRUB_ERR_NONE && quid) - { - if (compare_fn (quid, ctx->key) == 0) - found = 1; - - grub_free (quid); - } - } - - grub_device_close (dev); - } - } -#endif - - if (!ctx->is_cache && found && ctx->count == 0) - { - struct cache_entry *cache_ent; - cache_ent = grub_malloc (sizeof (*cache_ent)); - if (cache_ent) - { - cache_ent->key = grub_strdup (ctx->key); - cache_ent->value = grub_strdup (name); - if (cache_ent->value && cache_ent->key) - { - cache_ent->next = cache; - cache = cache_ent; - } - else - { - grub_free (cache_ent->value); - grub_free (cache_ent->key); - grub_free (cache_ent); - grub_errno = GRUB_ERR_NONE; - } - } - else - grub_errno = GRUB_ERR_NONE; - } - - if (found) - { - ctx->count++; - if (ctx->var) - grub_env_set (ctx->var, name); - else - grub_printf (" %s", name); - } - - grub_errno = GRUB_ERR_NONE; - return (found && ctx->var); -} - -/* Helper for FUNC_NAME. */ -static int -part_hook (grub_disk_t disk, const grub_partition_t partition, void *data) -{ - struct search_ctx *ctx = data; - char *partition_name, *devname; - int ret; - - partition_name = grub_partition_get_name (partition); - if (! partition_name) - return 1; - - devname = grub_xasprintf ("%s,%s", disk->name, partition_name); - grub_free (partition_name); - if (!devname) - return 1; - ret = iterate_device (devname, ctx); - grub_free (devname); - - return ret; -} - -/* Helper for FUNC_NAME. */ -static void -try (struct search_ctx *ctx) -{ - unsigned i; - struct cache_entry **prev; - struct cache_entry *cache_ent; - - for (prev = &cache, cache_ent = *prev; cache_ent; - prev = &cache_ent->next, cache_ent = *prev) - if (compare_fn (cache_ent->key, ctx->key) == 0) - break; - if (cache_ent) - { - ctx->is_cache = 1; - if (iterate_device (cache_ent->value, ctx)) - { - ctx->is_cache = 0; - return; - } - ctx->is_cache = 0; - /* Cache entry was outdated. Remove it. */ - if (!ctx->count) - { - *prev = cache_ent->next; - grub_free (cache_ent->key); - grub_free (cache_ent->value); - grub_free (cache_ent); - } - } - - for (i = 0; i < ctx->nhints; i++) - { - char *end; - if (!ctx->hints[i][0]) - continue; - end = ctx->hints[i] + grub_strlen (ctx->hints[i]) - 1; - if (*end == ',') - *end = 0; - if (iterate_device (ctx->hints[i], ctx)) - { - if (!*end) - *end = ','; - return; - } - if (!*end) - { - grub_device_t dev; - int ret; - dev = grub_device_open (ctx->hints[i]); - if (!dev) - { - if (!*end) - *end = ','; - continue; - } - if (!dev->disk) - { - grub_device_close (dev); - if (!*end) - *end = ','; - continue; - } - ret = grub_partition_iterate (dev->disk, part_hook, ctx); - if (!*end) - *end = ','; - grub_device_close (dev); - if (ret) - return; - } - } - grub_device_iterate (iterate_device, ctx); -} - -void -FUNC_NAME (const char *key, const char *var, enum search_flags flags, - char **hints, unsigned nhints) -{ - struct search_ctx ctx = { - .key = key, - .var = var, - .flags = flags, - .hints = hints, - .nhints = nhints, - .count = 0, - .is_cache = 0 - }; - grub_fs_autoload_hook_t saved_autoload; - - /* First try without autoloading if we're setting variable. */ - if (var) - { - saved_autoload = grub_fs_autoload_hook; - grub_fs_autoload_hook = 0; - try (&ctx); - - /* Restore autoload hook. */ - grub_fs_autoload_hook = saved_autoload; - - /* Retry with autoload if nothing found. */ - if (grub_errno == GRUB_ERR_NONE && ctx.count == 0) - try (&ctx); - } - else - try (&ctx); - - if (grub_errno == GRUB_ERR_NONE && ctx.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, N_("one argument expected")); - - FUNC_NAME (args[0], argc == 1 ? 0 : args[1], 0, (args + 2), - argc > 2 ? argc - 2 : 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] [HINTS]"), - 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_wrap.c b/grub-core/commands/search_wrap.c deleted file mode 100644 index 5f536006c..000000000 --- a/grub-core/commands/search_wrap.c +++ /dev/null @@ -1,231 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -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."), N_("VARNAME"), - ARG_TYPE_STRING}, - {"no-floppy", 'n', 0, N_("Do not probe any floppy drive."), 0, 0}, - {"efidisk-only", 0, 0, N_("Only probe EFI disks."), 0, 0}, - {"cryptodisk-only", 0, 0, N_("Only probe encrypted disks."), 0, 0}, - {"hint", 'h', GRUB_ARG_OPTION_REPEATABLE, - N_("First try the device HINT. If HINT ends in comma, " - "also try subpartitions"), N_("HINT"), ARG_TYPE_STRING}, - {"hint-ieee1275", 0, GRUB_ARG_OPTION_REPEATABLE, - N_("First try the device HINT if currently running on IEEE1275. " - "If HINT ends in comma, also try subpartitions"), - N_("HINT"), ARG_TYPE_STRING}, - {"hint-bios", 0, GRUB_ARG_OPTION_REPEATABLE, - N_("First try the device HINT if currently running on BIOS. " - "If HINT ends in comma, also try subpartitions"), - N_("HINT"), ARG_TYPE_STRING}, - {"hint-baremetal", 0, GRUB_ARG_OPTION_REPEATABLE, - N_("First try the device HINT if direct hardware access is supported. " - "If HINT ends in comma, also try subpartitions"), - N_("HINT"), ARG_TYPE_STRING}, - {"hint-efi", 0, GRUB_ARG_OPTION_REPEATABLE, - N_("First try the device HINT if currently running on EFI. " - "If HINT ends in comma, also try subpartitions"), - N_("HINT"), ARG_TYPE_STRING}, - {"hint-arc", 0, GRUB_ARG_OPTION_REPEATABLE, - N_("First try the device HINT if currently running on ARC." - " If HINT ends in comma, also try subpartitions"), - N_("HINT"), ARG_TYPE_STRING}, - {0, 0, 0, 0, 0, 0} - }; - -enum options - { - SEARCH_FILE, - SEARCH_LABEL, - SEARCH_FS_UUID, - SEARCH_SET, - SEARCH_NO_FLOPPY, - SEARCH_EFIDISK_ONLY, - SEARCH_CRYPTODISK_ONLY, - SEARCH_HINT, - SEARCH_HINT_IEEE1275, - SEARCH_HINT_BIOS, - SEARCH_HINT_BAREMETAL, - SEARCH_HINT_EFI, - SEARCH_HINT_ARC, - }; - -static grub_err_t -grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_arg_list *state = ctxt->state; - const char *var = 0; - const char *id = 0; - int i = 0, j = 0, nhints = 0; - char **hints = NULL; - enum search_flags flags = SEARCH_FLAGS_NONE; - - if (state[SEARCH_HINT].set) - for (i = 0; state[SEARCH_HINT].args[i]; i++) - nhints++; - -#ifdef GRUB_MACHINE_IEEE1275 - if (state[SEARCH_HINT_IEEE1275].set) - for (i = 0; state[SEARCH_HINT_IEEE1275].args[i]; i++) - nhints++; -#endif - -#ifdef GRUB_MACHINE_EFI - if (state[SEARCH_HINT_EFI].set) - for (i = 0; state[SEARCH_HINT_EFI].args[i]; i++) - nhints++; -#endif - -#ifdef GRUB_MACHINE_PCBIOS - if (state[SEARCH_HINT_BIOS].set) - for (i = 0; state[SEARCH_HINT_BIOS].args[i]; i++) - nhints++; -#endif - -#ifdef GRUB_MACHINE_ARC - if (state[SEARCH_HINT_ARC].set) - for (i = 0; state[SEARCH_HINT_ARC].args[i]; i++) - nhints++; -#endif - - if (state[SEARCH_HINT_BAREMETAL].set) - for (i = 0; state[SEARCH_HINT_BAREMETAL].args[i]; i++) - nhints++; - - hints = grub_calloc (nhints, sizeof (hints[0])); - if (!hints) - return grub_errno; - j = 0; - - if (state[SEARCH_HINT].set) - for (i = 0; state[SEARCH_HINT].args[i]; i++) - hints[j++] = state[SEARCH_HINT].args[i]; - -#ifdef GRUB_MACHINE_IEEE1275 - if (state[SEARCH_HINT_IEEE1275].set) - for (i = 0; state[SEARCH_HINT_IEEE1275].args[i]; i++) - hints[j++] = state[SEARCH_HINT_IEEE1275].args[i]; -#endif - -#ifdef GRUB_MACHINE_EFI - if (state[SEARCH_HINT_EFI].set) - for (i = 0; state[SEARCH_HINT_EFI].args[i]; i++) - hints[j++] = state[SEARCH_HINT_EFI].args[i]; -#endif - -#ifdef GRUB_MACHINE_ARC - if (state[SEARCH_HINT_ARC].set) - for (i = 0; state[SEARCH_HINT_ARC].args[i]; i++) - hints[j++] = state[SEARCH_HINT_ARC].args[i]; -#endif - -#ifdef GRUB_MACHINE_PCBIOS - if (state[SEARCH_HINT_BIOS].set) - for (i = 0; state[SEARCH_HINT_BIOS].args[i]; i++) - hints[j++] = state[SEARCH_HINT_BIOS].args[i]; -#endif - - if (state[SEARCH_HINT_BAREMETAL].set) - for (i = 0; state[SEARCH_HINT_BAREMETAL].args[i]; i++) - hints[j++] = state[SEARCH_HINT_BAREMETAL].args[i]; - - /* Skip hints for future platforms. */ - for (j = 0; j < argc; j++) - if (grub_memcmp (args[j], "--hint-", sizeof ("--hint-") - 1) != 0) - break; - - if (state[SEARCH_SET].set) - var = state[SEARCH_SET].arg ? state[SEARCH_SET].arg : "root"; - - if (argc != j) - id = args[j]; - else if (state[SEARCH_SET].set && state[SEARCH_SET].arg) - { - id = state[SEARCH_SET].arg; - var = "root"; - } - else - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - goto out; - } - - if (state[SEARCH_NO_FLOPPY].set) - flags |= SEARCH_FLAGS_NO_FLOPPY; - - if (state[SEARCH_EFIDISK_ONLY].set) - flags |= SEARCH_FLAGS_EFIDISK_ONLY; - - if (state[SEARCH_CRYPTODISK_ONLY].set) - flags |= SEARCH_FLAGS_CRYPTODISK_ONLY; - - if (state[SEARCH_LABEL].set) - grub_search_label (id, var, flags, hints, nhints); - else if (state[SEARCH_FS_UUID].set) - grub_search_fs_uuid (id, var, flags, hints, nhints); - else if (state[SEARCH_FILE].set) - grub_search_fs_file (id, var, flags, hints, nhints); - else - grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type"); - -out: - grub_free (hints); - return grub_errno; -} - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT(search) -{ - cmd = - grub_register_extcmd ("search", grub_cmd_search, - GRUB_COMMAND_FLAG_EXTRACTOR | GRUB_COMMAND_ACCEPT_DASH, - N_("[-f|-l|-u|-s|-n] [--cryptodisk-only] [--hint HINT [--hint HINT] ...]" - " 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/smbios.c b/grub-core/commands/smbios.c deleted file mode 100644 index 1a9086ddd..000000000 --- a/grub-core/commands/smbios.c +++ /dev/null @@ -1,398 +0,0 @@ -/* smbios.c - retrieve smbios information. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2019 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* Abstract useful values found in either the SMBIOS3 or SMBIOS EPS. */ -static struct { - grub_addr_t start; - grub_addr_t end; - grub_uint16_t structures; -} table_desc; - -static grub_extcmd_t cmd; - -/* Locate the SMBIOS entry point structure depending on the hardware. */ -struct grub_smbios_eps * -grub_smbios_get_eps (void) -{ - static struct grub_smbios_eps *eps = NULL; - - if (eps != NULL) - return eps; - - eps = grub_machine_smbios_get_eps (); - - return eps; -} - -/* Locate the SMBIOS3 entry point structure depending on the hardware. */ -static struct grub_smbios_eps3 * -grub_smbios_get_eps3 (void) -{ - static struct grub_smbios_eps3 *eps = NULL; - - if (eps != NULL) - return eps; - - eps = grub_machine_smbios_get_eps3 (); - - return eps; -} - -static char * -linux_string (const char *value) -{ - char *out = grub_malloc( grub_strlen (value) + 1); - const char *src = value; - char *dst = out; - - for (; *src; src++) - if (*src > ' ' && *src < 127 && *src != ':') - *dst++ = *src; - - *dst = 0; - return out; -} - -/* - * These functions convert values from the various SMBIOS structure field types - * into a string formatted to be returned to the user. They expect that the - * structure and offset were already validated. When the requested data is - * successfully retrieved and formatted, the pointer to the string is returned; - * otherwise, NULL is returned on failure. Don't free the result. - */ - -static const char * -grub_smbios_format_byte (const grub_uint8_t *structure, grub_uint8_t offset) -{ - static char buffer[sizeof ("255")]; - - grub_snprintf (buffer, sizeof (buffer), "%u", structure[offset]); - - return (const char *)buffer; -} - -static const char * -grub_smbios_format_word (const grub_uint8_t *structure, grub_uint8_t offset) -{ - static char buffer[sizeof ("65535")]; - - grub_uint16_t value = grub_get_unaligned16 (structure + offset); - grub_snprintf (buffer, sizeof (buffer), "%u", value); - - return (const char *)buffer; -} - -static const char * -grub_smbios_format_dword (const grub_uint8_t *structure, grub_uint8_t offset) -{ - static char buffer[sizeof ("4294967295")]; - - grub_uint32_t value = grub_get_unaligned32 (structure + offset); - grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT32_T, value); - - return (const char *)buffer; -} - -static const char * -grub_smbios_format_qword (const grub_uint8_t *structure, grub_uint8_t offset) -{ - static char buffer[sizeof ("18446744073709551615")]; - - grub_uint64_t value = grub_get_unaligned64 (structure + offset); - grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT64_T, value); - - return (const char *)buffer; -} - -static const char * -grub_smbios_get_string (const grub_uint8_t *structure, grub_uint8_t offset) -{ - const grub_uint8_t *ptr = structure + structure[1]; - const grub_uint8_t *table_end = (const grub_uint8_t *)table_desc.end; - const grub_uint8_t referenced_string_number = structure[offset]; - grub_uint8_t i; - - /* A string referenced with zero is interpreted as unset. */ - if (referenced_string_number == 0) - return NULL; - - /* Search the string set. */ - for (i = 1; *ptr != 0 && ptr < table_end; i++) - if (i == referenced_string_number) - { - const char *str = (const char *)ptr; - while (*ptr++ != 0) - if (ptr >= table_end) - return NULL; /* The string isn't terminated. */ - return str; - } - else - while (*ptr++ != 0 && ptr < table_end); - - /* The string number is greater than the number of strings in the set. */ - return NULL; -} - -static const char * -grub_smbios_format_uuid (const grub_uint8_t *structure, grub_uint8_t offset) -{ - static char buffer[sizeof ("ffffffff-ffff-ffff-ffff-ffffffffffff")]; - const grub_uint8_t *f = structure + offset; /* little-endian fields */ - const grub_uint8_t *g = f + 8; /* byte-by-byte fields */ - - grub_snprintf (buffer, sizeof (buffer), - "%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x-%02x%02x%02x%02x%02x%02x", - f[3], f[2], f[1], f[0], f[5], f[4], f[7], f[6], - g[0], g[1], g[2], g[3], g[4], g[5], g[6], g[7]); - - return (const char *)buffer; -} - -/* List the field formatting functions and the number of bytes they need. */ -static const struct { - const char *(*format) (const grub_uint8_t *structure, grub_uint8_t offset); - grub_uint8_t field_length; -} field_extractors[] = { - {grub_smbios_format_byte, 1}, - {grub_smbios_format_word, 2}, - {grub_smbios_format_dword, 4}, - {grub_smbios_format_qword, 8}, - {grub_smbios_get_string, 1}, - {grub_smbios_format_uuid, 16} -}; - -/* List command options, with structure field getters ordered as above. */ -#define FIRST_GETTER_OPT (3) -#define SETTER_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors)) -#define LINUX_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors) + 1) - -static const struct grub_arg_option options[] = { - {"type", 't', 0, N_("Match structures with the given type."), - N_("type"), ARG_TYPE_INT}, - {"handle", 'h', 0, N_("Match structures with the given handle."), - N_("handle"), ARG_TYPE_INT}, - {"match", 'm', 0, N_("Select a structure when several match."), - N_("match"), ARG_TYPE_INT}, - {"get-byte", 'b', 0, N_("Get the byte's value at the given offset."), - N_("offset"), ARG_TYPE_INT}, - {"get-word", 'w', 0, N_("Get two bytes' value at the given offset."), - N_("offset"), ARG_TYPE_INT}, - {"get-dword", 'd', 0, N_("Get four bytes' value at the given offset."), - N_("offset"), ARG_TYPE_INT}, - {"get-qword", 'q', 0, N_("Get eight bytes' value at the given offset."), - N_("offset"), ARG_TYPE_INT}, - {"get-string", 's', 0, N_("Get the string specified at the given offset."), - N_("offset"), ARG_TYPE_INT}, - {"get-uuid", 'u', 0, N_("Get the UUID's value at the given offset."), - N_("offset"), ARG_TYPE_INT}, - {"set", '\0', 0, N_("Store the value in the given variable name."), - N_("variable"), ARG_TYPE_STRING}, - {"linux", '\0', 0, N_("Filter the result like linux does."), - N_("variable"), ARG_TYPE_NONE}, - {0, 0, 0, 0, 0, 0} -}; - -/* - * Return a matching SMBIOS structure. - * - * This method can use up to three criteria for selecting a structure: - * - The "type" field (use -1 to ignore) - * - The "handle" field (use -1 to ignore) - * - Which to return if several match (use 0 to ignore) - * - * The return value is a pointer to the first matching structure. If no - * structures match the given parameters, NULL is returned. - */ -static const grub_uint8_t * -grub_smbios_match_structure (const grub_int16_t type, - const grub_int32_t handle, - const grub_uint16_t match) -{ - const grub_uint8_t *ptr = (const grub_uint8_t *)table_desc.start; - const grub_uint8_t *table_end = (const grub_uint8_t *)table_desc.end; - grub_uint16_t structures = table_desc.structures; - grub_uint16_t structure_count = 0; - grub_uint16_t matches = 0; - - while (ptr < table_end - && ptr[1] >= 4 /* Valid structures include the 4-byte header. */ - && (structure_count++ < structures || structures == 0)) - { - grub_uint16_t structure_handle = grub_get_unaligned16 (ptr + 2); - grub_uint8_t structure_type = ptr[0]; - - if ((handle < 0 || handle == structure_handle) - && (type < 0 || type == structure_type) - && (match == 0 || match == ++matches)) - return ptr; - else - { - ptr += ptr[1]; - while ((*ptr++ != 0 || *ptr++ != 0) && ptr < table_end); - } - - if (structure_type == GRUB_SMBIOS_TYPE_END_OF_TABLE) - break; - } - - return NULL; -} - -static grub_err_t -grub_cmd_smbios (grub_extcmd_context_t ctxt, - int argc __attribute__ ((unused)), - char **argv __attribute__ ((unused))) -{ - struct grub_arg_list *state = ctxt->state; - - grub_int16_t type = -1; - grub_int32_t handle = -1; - grub_uint16_t match = 0; - grub_uint8_t offset = 0; - - const grub_uint8_t *structure; - const char *value; - char *modified_value = NULL; - grub_int32_t option; - grub_int8_t field_type = -1; - grub_uint8_t i; - - if (table_desc.start == 0) - return grub_error (GRUB_ERR_IO, - N_("the SMBIOS entry point structure was not found")); - - /* Read the given filtering options. */ - if (state[0].set) - { - option = grub_strtol (state[0].arg, NULL, 0); - if (option < 0 || option > 255) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("the type must be between 0 and 255")); - type = (grub_int16_t)option; - } - if (state[1].set) - { - option = grub_strtol (state[1].arg, NULL, 0); - if (option < 0 || option > 65535) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("the handle must be between 0 and 65535")); - handle = (grub_int32_t)option; - } - if (state[2].set) - { - option = grub_strtol (state[2].arg, NULL, 0); - if (option <= 0 || option > 65535) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("the match must be a positive integer")); - match = (grub_uint16_t)option; - } - - /* Determine the data type of the structure field to retrieve. */ - for (i = 0; i < ARRAY_SIZE(field_extractors); i++) - if (state[FIRST_GETTER_OPT + i].set) - { - if (field_type >= 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("only one --get option is usable at a time")); - field_type = i; - } - - /* Require a choice of a structure field to return. */ - if (field_type < 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("one of the --get options is required")); - - /* Locate a matching SMBIOS structure. */ - structure = grub_smbios_match_structure (type, handle, match); - if (structure == NULL) - return grub_error (GRUB_ERR_IO, - N_("no structure matched the given options")); - - /* Ensure the requested byte offset is inside the structure. */ - option = grub_strtol (state[FIRST_GETTER_OPT + field_type].arg, NULL, 0); - if (option < 0 || option >= structure[1]) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("the given offset is outside the structure")); - - /* Ensure the requested data type at the offset is inside the structure. */ - offset = (grub_uint8_t)option; - if (offset + field_extractors[field_type].field_length > structure[1]) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("the field ends outside the structure")); - - /* Format the requested structure field into a readable string. */ - value = field_extractors[field_type].format (structure, offset); - if (value == NULL) - return grub_error (GRUB_ERR_IO, - N_("failed to retrieve the structure field")); - - if (state[LINUX_OPT].set) - value = modified_value = linux_string (value); - - /* Store or print the formatted value. */ - if (state[SETTER_OPT].set) - grub_env_set (state[SETTER_OPT].arg, value); - else - grub_printf ("%s\n", value); - - grub_free(modified_value); - - return GRUB_ERR_NONE; -} - -GRUB_MOD_INIT(smbios) -{ - struct grub_smbios_eps3 *eps3; - struct grub_smbios_eps *eps; - - if ((eps3 = grub_smbios_get_eps3 ())) - { - table_desc.start = (grub_addr_t)eps3->table_address; - table_desc.end = table_desc.start + eps3->maximum_table_length; - table_desc.structures = 0; /* SMBIOS3 drops the structure count. */ - } - else if ((eps = grub_smbios_get_eps ())) - { - table_desc.start = (grub_addr_t)eps->intermediate.table_address; - table_desc.end = table_desc.start + eps->intermediate.table_length; - table_desc.structures = eps->intermediate.structures; - } - - cmd = grub_register_extcmd ("smbios", grub_cmd_smbios, 0, - N_("[-t type] [-h handle] [-m match] " - "(-b|-w|-d|-q|-s|-u) offset " - "[--set variable]"), - N_("Retrieve SMBIOS information."), options); -} - -GRUB_MOD_FINI(smbios) -{ - grub_unregister_extcmd (cmd); -} diff --git a/grub-core/commands/syslinuxcfg.c b/grub-core/commands/syslinuxcfg.c deleted file mode 100644 index 7be28fada..000000000 --- a/grub-core/commands/syslinuxcfg.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* Helper for syslinux_file. */ -static grub_err_t -syslinux_file_getline (char **line, int cont __attribute__ ((unused)), - void *data __attribute__ ((unused))) -{ - *line = 0; - return GRUB_ERR_NONE; -} - -static const struct grub_arg_option options[] = - { - {"root", 'r', 0, - N_("root directory of the syslinux disk [default=/]."), - N_("DIR"), ARG_TYPE_STRING}, - {"cwd", 'c', 0, - N_("current directory of syslinux [default is parent directory of input file]."), - N_("DIR"), ARG_TYPE_STRING}, - {"isolinux", 'i', 0, N_("assume input is an isolinux configuration file."), 0, 0}, - {"pxelinux", 'p', 0, N_("assume input is a pxelinux configuration file."), 0, 0}, - {"syslinux", 's', 0, N_("assume input is a syslinux configuration file."), 0, 0}, - {0, 0, 0, 0, 0, 0} - }; - -enum - { - OPTION_ROOT, - OPTION_CWD, - OPTION_ISOLINUX, - OPTION_PXELINUX, - OPTION_SYSLINUX - }; - -static grub_err_t -syslinux_file (grub_extcmd_context_t ctxt, const char *filename) -{ - char *result; - const char *root = ctxt->state[OPTION_ROOT].set ? ctxt->state[OPTION_ROOT].arg : "/"; - const char *cwd = ctxt->state[OPTION_CWD].set ? ctxt->state[OPTION_CWD].arg : NULL; - grub_syslinux_flavour_t flav = GRUB_SYSLINUX_UNKNOWN; - char *cwdf = NULL; - grub_menu_t menu; - - if (ctxt->state[OPTION_ISOLINUX].set) - flav = GRUB_SYSLINUX_ISOLINUX; - if (ctxt->state[OPTION_PXELINUX].set) - flav = GRUB_SYSLINUX_PXELINUX; - if (ctxt->state[OPTION_SYSLINUX].set) - flav = GRUB_SYSLINUX_SYSLINUX; - - if (!cwd) - { - char *p; - cwdf = grub_strdup (filename); - if (!cwdf) - return grub_errno; - p = grub_strrchr (cwdf, '/'); - if (!p) - { - grub_free (cwdf); - cwd = "/"; - cwdf = NULL; - } - else - { - *p = '\0'; - cwd = cwdf; - } - } - - grub_dprintf ("syslinux", - "transforming syslinux config %s, root = %s, cwd = %s\n", - filename, root, cwd); - - result = grub_syslinux_config_file (root, root, cwd, cwd, filename, flav); - if (!result) - return grub_errno; - - grub_dprintf ("syslinux", "syslinux config transformed\n"); - - menu = grub_env_get_menu (); - if (! menu) - { - menu = grub_zalloc (sizeof (*menu)); - if (! menu) - { - grub_free (result); - return grub_errno; - } - - grub_env_set_menu (menu); - } - - grub_normal_parse_line (result, syslinux_file_getline, NULL); - grub_print_error (); - grub_free (result); - grub_free (cwdf); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_syslinux_source (grub_extcmd_context_t ctxt, - int argc, char **args) -{ - int new_env, extractor; - grub_err_t ret; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - extractor = (ctxt->extcmd->cmd->name[0] == 'e'); - new_env = (ctxt->extcmd->cmd->name[extractor ? (sizeof ("extract_syslinux_entries_") - 1) - : (sizeof ("syslinux_") - 1)] == 'c'); - - if (new_env) - grub_cls (); - - if (new_env && !extractor) - grub_env_context_open (); - if (extractor) - grub_env_extractor_open (!new_env); - - ret = syslinux_file (ctxt, args[0]); - - if (new_env) - { - grub_menu_t menu; - menu = grub_env_get_menu (); - if (menu && menu->size) - grub_show_menu (menu, 1, 0); - if (!extractor) - grub_env_context_close (); - } - if (extractor) - grub_env_extractor_close (!new_env); - - return ret; -} - - -static grub_extcmd_t cmd_source, cmd_configfile; -static grub_extcmd_t cmd_source_extract, cmd_configfile_extract; - -GRUB_MOD_INIT(syslinuxcfg) -{ - cmd_source - = grub_register_extcmd ("syslinux_source", - grub_cmd_syslinux_source, 0, - N_("FILE"), - /* TRANSLATORS: "syslinux config" means - "config as used by syslinux". */ - N_("Execute syslinux config in same context"), - options); - cmd_configfile - = grub_register_extcmd ("syslinux_configfile", - grub_cmd_syslinux_source, 0, - N_("FILE"), - N_("Execute syslinux config in new context"), - options); - cmd_source_extract - = grub_register_extcmd ("extract_syslinux_entries_source", - grub_cmd_syslinux_source, 0, - N_("FILE"), - N_("Execute syslinux config in same context taking only menu entries"), - options); - cmd_configfile_extract - = grub_register_extcmd ("extract_syslinux_entries_configfile", - grub_cmd_syslinux_source, 0, - N_("FILE"), - N_("Execute syslinux config in new context taking only menu entries"), - options); -} - -GRUB_MOD_FINI(syslinuxcfg) -{ - grub_unregister_extcmd (cmd_source); - grub_unregister_extcmd (cmd_configfile); - grub_unregister_extcmd (cmd_source_extract); - grub_unregister_extcmd (cmd_configfile_extract); -} diff --git a/grub-core/commands/terminal.c b/grub-core/commands/terminal.c deleted file mode 100644 index 78a140099..000000000 --- a/grub-core/commands/terminal.c +++ /dev/null @@ -1,285 +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 . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -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; - struct abstract_terminal *prev; - const char *name; - grub_err_t (*init) (struct abstract_terminal *term); - grub_err_t (*fini) (struct abstract_terminal *term); -}; - -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 - || (aut->name[0] && aut->name[grub_strlen (aut->name) - 1] == '*' - && grub_memcmp (term->name, aut->name, - grub_strlen (aut->name) - 1) == 0)) - break; - if (!term) - for (term = *enabled; term; term = term->next) - if (grub_strcmp (term->name, aut->name) == 0 - || (aut->name[0] && aut->name[grub_strlen (aut->name) - 1] == '*' - && grub_memcmp (term->name, aut->name, - grub_strlen (aut->name) - 1) == 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 - || (grub_strcmp (args[i], "ofconsole") == 0 - && grub_strcmp ("console", term->name) == 0)) - break; - if (term == 0) - for (term = *enabled; term; term = term->next) - if (grub_strcmp (args[i], term->name) == 0 - || (grub_strcmp (args[i], "ofconsole") == 0 - && grub_strcmp ("console", term->name) == 0)) - break; - if (term) - break; - if (again) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("terminal `%s' isn't found"), - args[i]); - for (aut = autoloads; aut; aut = aut->next) - if (grub_strcmp (args[i], aut->name) == 0 - || (grub_strcmp (args[i], "ofconsole") == 0 - && grub_strcmp ("console", aut->name) == 0) - || (aut->name[0] && aut->name[grub_strlen (aut->name) - 1] == '*' - && grub_memcmp (args[i], aut->name, - grub_strlen (aut->name) - 1) == 0)) - { - grub_dl_t mod; - mod = grub_dl_load (aut->modname); - if (mod) - grub_dl_ref (mod); - grub_errno = GRUB_ERR_NONE; - break; - } - if (grub_memcmp (args[i], "serial_usb", - sizeof ("serial_usb") - 1) == 0 - && grub_term_poll_usb) - { - grub_term_poll_usb (1); - again = 1; - continue; - } - if (!aut) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("terminal `%s' isn't found"), - 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 - || (grub_strcmp (args[i], "ofconsole") == 0 - && grub_strcmp ("console", term->name) == 0)) - break; - if (term) - { - if (term->init && term->init (term) != GRUB_ERR_NONE) - return grub_errno; - - grub_list_remove (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 - || (grub_strcmp (args[i], "ofconsole") == 0 - && grub_strcmp ("console", 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 (term)); - if (term->fini) - term->fini (term); - 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 - || (grub_strcmp (args[i], "ofconsole") == 0 - && grub_strcmp ("console", term->name) == 0)) - break; - if (term) - { - if (term->init && term->init (term) != GRUB_ERR_NONE) - return grub_errno; - - grub_list_remove (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 - || (grub_strcmp (args[i], "ofconsole") == 0 - && grub_strcmp ("console", 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 (term)); - if (term->fini) - term->fini (term); - 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 *, prev); - (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 **) (void *) &grub_term_inputs, - (struct abstract_terminal **) (void *) &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 *, prev); - (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 **) (void *) &grub_term_outputs, - (struct abstract_terminal **) (void *) &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/testload.c b/grub-core/commands/testload.c deleted file mode 100644 index 76a8af94c..000000000 --- a/grub-core/commands/testload.c +++ /dev/null @@ -1,172 +0,0 @@ -/* testload.c - load the same file in multiple ways */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* Helper for grub_cmd_testload. */ -static grub_err_t -read_progress (grub_disk_addr_t sector __attribute__ ((unused)), - unsigned offset __attribute__ ((unused)), - unsigned len, - char *buf __attribute__ ((unused)), - void *data __attribute__ ((unused))) -{ - for (; len >= GRUB_DISK_SECTOR_SIZE; len -= GRUB_DISK_SECTOR_SIZE) - grub_xputs ("."); - if (len) - grub_xputs ("."); - grub_refresh (); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_file_t file; - char *buf; - grub_size_t size; - grub_off_t pos; - - if (argc < 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_TESTLOAD); - if (! file) - return grub_errno; - - size = grub_file_size (file) & ~(GRUB_DISK_SECTOR_SIZE - 1); - if (size == 0) - { - grub_file_close (file); - return GRUB_ERR_NONE; - } - - buf = grub_malloc (size); - if (! buf) - goto fail; - - grub_printf ("Reading %s sequentially", argv[0]); - file->read_hook = read_progress; - if (grub_file_read (file, buf, size) != (grub_ssize_t) size) - goto fail; - grub_printf (" Done.\n"); - - /* Read sequentially again. */ - grub_printf ("Reading %s sequentially again", argv[0]); - grub_file_seek (file, 0); - - for (pos = 0; pos < size;) - { - char sector[GRUB_DISK_SECTOR_SIZE]; - grub_size_t curlen = GRUB_DISK_SECTOR_SIZE; - - if (curlen > size - pos) - curlen = size - pos; - - if (grub_file_read (file, sector, curlen) - != (grub_ssize_t) curlen) - goto fail; - - if (grub_memcmp (sector, buf + pos, curlen) != 0) - { - grub_printf ("\nDiffers in %lld\n", (unsigned long long) pos); - goto fail; - } - pos += curlen; - } - 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]; - - if (pos >= GRUB_DISK_SECTOR_SIZE) - pos -= GRUB_DISK_SECTOR_SIZE; - else - pos = 0; - - grub_file_seek (file, pos); - - 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 %lld\n", (unsigned long long) pos); - - for (i = 0; i < GRUB_DISK_SECTOR_SIZE; i++) - { - grub_printf ("%02x ", buf[pos + i]); - if ((i & 15) == 15) - grub_printf ("\n"); - } - - if (i) - grub_refresh (); - - goto fail; - } - } - grub_printf (" Done.\n"); - - return GRUB_ERR_NONE; - - fail: - - grub_file_close (file); - grub_free (buf); - - if (!grub_errno) - grub_error (GRUB_ERR_IO, "bad read"); - return grub_errno; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(testload) -{ - cmd = - grub_register_command ("testload", grub_cmd_testload, - N_("FILE"), - N_("Load the same file in multiple ways.")); -} - -GRUB_MOD_FINI(testload) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/commands/testspeed.c b/grub-core/commands/testspeed.c deleted file mode 100644 index c13a9b8d8..000000000 --- a/grub-core/commands/testspeed.c +++ /dev/null @@ -1,115 +0,0 @@ -/* testspeed.c - Command to test file read speed */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2012 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define DEFAULT_BLOCK_SIZE 65536 - -static const struct grub_arg_option options[] = - { - {"size", 's', 0, N_("Specify size for each read operation"), 0, ARG_TYPE_INT}, - {0, 0, 0, 0, 0, 0} - }; - -static grub_err_t -grub_cmd_testspeed (grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_arg_list *state = ctxt->state; - grub_uint64_t start; - grub_uint64_t end; - grub_ssize_t block_size; - grub_disk_addr_t total_size; - char *buffer; - grub_file_t file; - grub_uint64_t whole, fraction; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - block_size = (state[0].set) ? - grub_strtoul (state[0].arg, 0, 0) : DEFAULT_BLOCK_SIZE; - - if (block_size <= 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid block size")); - - buffer = grub_malloc (block_size); - if (buffer == NULL) - return grub_errno; - - file = grub_file_open (args[0], GRUB_FILE_TYPE_TESTLOAD); - if (file == NULL) - goto quit; - - total_size = 0; - start = grub_get_time_ms (); - while (1) - { - grub_ssize_t size = grub_file_read (file, buffer, block_size); - if (size <= 0) - break; - total_size += size; - } - end = grub_get_time_ms (); - grub_file_close (file); - - grub_printf_ (N_("File size: %s\n"), - grub_get_human_size (total_size, GRUB_HUMAN_SIZE_NORMAL)); - whole = grub_divmod64 (end - start, 1000, &fraction); - grub_printf_ (N_("Elapsed time: %d.%03d s \n"), - (unsigned) whole, - (unsigned) fraction); - - if (end != start) - { - grub_uint64_t speed = - grub_divmod64 (total_size * 100ULL * 1000ULL, end - start, 0); - - grub_printf_ (N_("Speed: %s \n"), - grub_get_human_size (speed, - GRUB_HUMAN_SIZE_SPEED)); - } - - quit: - grub_free (buffer); - - return grub_errno; -} - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT(testspeed) -{ - cmd = grub_register_extcmd ("testspeed", grub_cmd_testspeed, 0, N_("[-s SIZE] FILENAME"), - N_("Test file read speed."), - options); -} - -GRUB_MOD_FINI(testspeed) -{ - grub_unregister_extcmd (cmd); -} diff --git a/grub-core/commands/time.c b/grub-core/commands/time.c deleted file mode 100644 index 40d496e7b..000000000 --- a/grub-core/commands/time.c +++ /dev/null @@ -1,68 +0,0 @@ -/* echo.c - Command to display a line of text */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - - -static grub_err_t -grub_cmd_time (grub_command_t ctxt __attribute__ ((unused)), - int argc, char **args) -{ - grub_command_t cmd; - grub_uint32_t start; - grub_uint32_t end; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("no command is specified")); - - cmd = grub_command_find (args[0]); - - if (!cmd) - return grub_error (GRUB_ERR_UNKNOWN_COMMAND, N_("can't find command `%s'"), - args[0]); - - start = grub_get_time_ms (); - (cmd->func) (cmd, argc - 1, &args[1]); - end = grub_get_time_ms (); - - grub_printf_ (N_("Elapsed time: %d.%03d seconds \n"), (end - start) / 1000, - (end - start) % 1000); - - return grub_errno; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(time) -{ - cmd = grub_register_command ("time", grub_cmd_time, - N_("COMMAND [ARGS]"), - N_("Measure time used by COMMAND")); -} - -GRUB_MOD_FINI(time) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/commands/tpm.c b/grub-core/commands/tpm.c deleted file mode 100644 index dde74ab83..000000000 --- a/grub-core/commands/tpm.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - * - * Core TPM support code. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -grub_tpm_verify_init (grub_file_t io, - enum grub_file_type type __attribute__ ((unused)), - void **context, enum grub_verify_flags *flags) -{ - *context = io->name; - *flags |= GRUB_VERIFY_FLAGS_SINGLE_CHUNK; - - /* - * The loopback image is mapped as a disk allowing it to function like - * a block device. However, we measure files read from the block device - * not the device itself. For example, we don't measure block devices like - * hd0 disk directly. This process is crucial to prevent out-of-memory - * errors as loopback images are inherently large. - */ - if ((type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_LOOPBACK) - *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_tpm_verify_write (void *context, void *buf, grub_size_t size) -{ - grub_err_t status = grub_tpm_measure (buf, size, GRUB_BINARY_PCR, context); - - if (status == GRUB_ERR_NONE) - return GRUB_ERR_NONE; - - grub_dprintf ("tpm", "Measuring buffer failed: %d\n", status); - return grub_is_tpm_fail_fatal () ? status : GRUB_ERR_NONE; -} - -static grub_err_t -grub_tpm_verify_string (char *str, enum grub_verify_string_type type) -{ - const char *prefix = NULL; - char *description; - grub_err_t status; - - switch (type) - { - case GRUB_VERIFY_KERNEL_CMDLINE: - prefix = "kernel_cmdline: "; - break; - case GRUB_VERIFY_MODULE_CMDLINE: - prefix = "module_cmdline: "; - break; - case GRUB_VERIFY_COMMAND: - prefix = "grub_cmd: "; - break; - } - description = grub_malloc (grub_strlen (str) + grub_strlen (prefix) + 1); - if (!description) - return grub_errno; - grub_memcpy (description, prefix, grub_strlen (prefix)); - grub_memcpy (description + grub_strlen (prefix), str, - grub_strlen (str) + 1); - status = - grub_tpm_measure ((unsigned char *) str, grub_strlen (str), - GRUB_STRING_PCR, description); - grub_free (description); - if (status == GRUB_ERR_NONE) - return GRUB_ERR_NONE; - - grub_dprintf ("tpm", "Measuring string %s failed: %d\n", str, status); - return grub_is_tpm_fail_fatal () ? status : GRUB_ERR_NONE; -} - -struct grub_file_verifier grub_tpm_verifier = { - .name = "tpm", - .init = grub_tpm_verify_init, - .write = grub_tpm_verify_write, - .verify_string = grub_tpm_verify_string, -}; - -GRUB_MOD_INIT (tpm) -{ - /* - * Even though this now calls ibmvtpm's grub_tpm_present() from GRUB_MOD_INIT(), - * it does seem to call it late enough in the initialization sequence so - * that whatever discovered "device nodes" before this GRUB_MOD_INIT() is - * called, enables the ibmvtpm driver to see the device nodes. - */ - if (!grub_tpm_present()) - return; - grub_verifier_register (&grub_tpm_verifier); -} - -GRUB_MOD_FINI (tpm) -{ - if (!grub_tpm_present()) - return; - grub_verifier_unregister (&grub_tpm_verifier); -} diff --git a/grub-core/commands/tpm2_key_protector/args.c b/grub-core/commands/tpm2_key_protector/args.c deleted file mode 100644 index 48c39de01..000000000 --- a/grub-core/commands/tpm2_key_protector/args.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -#include "tpm2_args.h" - -grub_err_t -grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs, - grub_uint8_t *pcr_count) -{ - char *current_pcr = value; - char *next_pcr; - const char *pcr_end; - grub_uint64_t pcr; - grub_uint8_t i; - - if (grub_strlen (value) == 0) - return GRUB_ERR_BAD_ARGUMENT; - - *pcr_count = 0; - for (i = 0; i < TPM_MAX_PCRS; i++) - { - next_pcr = grub_strchr (current_pcr, ','); - if (next_pcr == current_pcr) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("empty entry in PCR list")); - if (next_pcr != NULL) - *next_pcr = '\0'; - - pcr = grub_strtoul (current_pcr, &pcr_end, 10); - if (*current_pcr == '\0' || *pcr_end != '\0') - return grub_error (GRUB_ERR_BAD_NUMBER, N_("entry '%s' in PCR list is not a number"), current_pcr); - - if (pcr > TPM_MAX_PCRS - 1) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("entry %llu in PCR list is too large to be a PCR number, PCR numbers range from 0 to %u"), (unsigned long long)pcr, TPM_MAX_PCRS - 1); - - pcrs[i] = (grub_uint8_t) pcr; - ++(*pcr_count); - - if (next_pcr == NULL) - break; - - current_pcr = next_pcr + 1; - if (*current_pcr == '\0') - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("trailing comma at the end of PCR list")); - } - - if (i == TPM_MAX_PCRS) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("too many PCRs in PCR list, the maximum number of PCRs is %u"), TPM_MAX_PCRS); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_tpm2_protector_parse_asymmetric (const char *value, - grub_srk_type_t *srk_type) -{ - if (grub_strcasecmp (value, "ECC") == 0 || - grub_strcasecmp (value, "ECC_NIST_P256") == 0) - { - srk_type->type = TPM_ALG_ECC; - srk_type->detail.ecc_curve = TPM_ECC_NIST_P256; - } - else if (grub_strcasecmp (value, "RSA") == 0 || - grub_strcasecmp (value, "RSA2048") == 0) - { - srk_type->type = TPM_ALG_RSA; - srk_type->detail.rsa_bits = 2048; - } - else - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("value '%s' is not a valid asymmetric key type"), value); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID_t *bank) -{ - if (grub_strcasecmp (value, "SHA1") == 0) - *bank = TPM_ALG_SHA1; - else if (grub_strcasecmp (value, "SHA256") == 0) - *bank = TPM_ALG_SHA256; - else if (grub_strcasecmp (value, "SHA384") == 0) - *bank = TPM_ALG_SHA384; - else if (grub_strcasecmp (value, "SHA512") == 0) - *bank = TPM_ALG_SHA512; - else - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("value '%s' is not a valid PCR bank"), value); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE_t *handle) -{ - grub_uint64_t num; - const char *str_end; - - num = grub_strtoul (value, &str_end, 0); - if (*value == '\0' || *str_end != '\0') - return grub_error (GRUB_ERR_BAD_NUMBER, N_("TPM handle value '%s' is not a number"), value); - - if (num > GRUB_UINT_MAX) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("value %llu is too large to be a TPM handle, TPM handles are unsigned 32-bit integers"), (unsigned long long)num); - - *handle = (TPM_HANDLE_t) num; - - return GRUB_ERR_NONE; -} diff --git a/grub-core/commands/tpm2_key_protector/module.c b/grub-core/commands/tpm2_key_protector/module.c deleted file mode 100644 index b84c2234f..000000000 --- a/grub-core/commands/tpm2_key_protector/module.c +++ /dev/null @@ -1,1496 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "tpm2_args.h" -#include "tpm2.h" -#include "tpm2key.h" - -GRUB_MOD_LICENSE ("GPLv3+"); - -typedef enum tpm2_protector_mode -{ - TPM2_PROTECTOR_MODE_UNSET, - TPM2_PROTECTOR_MODE_SRK, - TPM2_PROTECTOR_MODE_NV -} tpm2_protector_mode_t; - -typedef enum tpm2_protector_options -{ - OPTION_MODE, - OPTION_PCRS, - OPTION_BANK, - OPTION_TPM2KEY, - OPTION_KEYFILE, - OPTION_SRK, - OPTION_ASYMMETRIC, - OPTION_NVINDEX -} tpm2_protector_options_t; - -typedef struct tpm2_protector_context -{ - tpm2_protector_mode_t mode; - grub_uint8_t pcrs[TPM_MAX_PCRS]; - grub_uint8_t pcr_count; - grub_srk_type_t srk_type; - TPM_ALG_ID_t bank; - const char *tpm2key; - const char *keyfile; - TPM_HANDLE_t srk; - TPM_HANDLE_t nv; -} tpm2_protector_context_t; - -static const struct grub_arg_option tpm2_protector_init_cmd_options[] = - { - /* Options for all modes */ - { - .longarg = "mode", - .shortarg = 'm', - .flags = 0, - .arg = NULL, - .type = ARG_TYPE_STRING, - .doc = - N_("Unseal key using SRK ('srk') (default) or retrieve it from an NV " - "Index ('nv')."), - }, - { - .longarg = "pcrs", - .shortarg = 'p', - .flags = 0, - .arg = NULL, - .type = ARG_TYPE_STRING, - .doc = - N_("Comma-separated list of PCRs used to authorize key release " - "e.g., '7,11'. (default: 7)"), - }, - { - .longarg = "bank", - .shortarg = 'b', - .flags = 0, - .arg = NULL, - .type = ARG_TYPE_STRING, - .doc = - N_("Bank of PCRs used to authorize key release: " - "SHA1, SHA256, SHA384 or SHA512. (default: SHA256)"), - }, - /* SRK-mode options */ - { - .longarg = "tpm2key", - .shortarg = 'T', - .flags = 0, - .arg = NULL, - .type = ARG_TYPE_STRING, - .doc = - N_("In SRK mode, path to the key file in the TPM 2.0 Key File format " - "to unseal using the TPM (e.g., (hd0,gpt1)/boot/grub2/sealed.tpm)."), - }, - { - .longarg = "keyfile", - .shortarg = 'k', - .flags = 0, - .arg = NULL, - .type = ARG_TYPE_STRING, - .doc = - N_("In SRK mode, path to the key file in the raw format to unseal " - "using the TPM (e.g., (hd0,gpt1)/boot/grub2/sealed.key). " - "(Mainly for backward compatibility. Please use '--tpm2key'.)"), - }, - { - .longarg = "srk", - .shortarg = 's', - .flags = 0, - .arg = NULL, - .type = ARG_TYPE_STRING, - .doc = - N_("In SRK mode, the SRK handle if the SRK is persistent."), - }, - { - .longarg = "asymmetric", - .shortarg = 'a', - .flags = 0, - .arg = NULL, - .type = ARG_TYPE_STRING, - .doc = - N_("In SRK mode, the type of SRK: RSA (RSA2048) and ECC (ECC_NIST_P256)" - "(default: ECC)"), - }, - /* NV Index-mode options */ - { - .longarg = "nvindex", - .shortarg = 'n', - .flags = 0, - .arg = NULL, - .type = ARG_TYPE_STRING, - .doc = - N_("Required in NV Index mode, the NV handle to read which must " - "readily exist on the TPM and which contains the key."), - }, - /* End of list */ - {0, 0, 0, 0, 0, 0} - }; - -static grub_extcmd_t tpm2_protector_init_cmd; -static grub_extcmd_t tpm2_protector_clear_cmd; -static tpm2_protector_context_t tpm2_protector_ctx = {0}; - -static grub_command_t tpm2_dump_pcr_cmd; - -static TPM_ALG_ID_t tpm2_dump_bank; - -static grub_err_t -tpm2_protector_srk_read_file (const char *filepath, void **buffer, grub_size_t *buffer_size) -{ - grub_file_t file; - grub_off_t file_size; - void *read_buffer; - grub_off_t read_n; - grub_err_t err; - - /* - * Using GRUB_FILE_TYPE_SIGNATURE ensures we do not hash the keyfile into PCR9 - * otherwise we'll never be able to predict the value of PCR9 at unseal time - */ - file = grub_file_open (filepath, GRUB_FILE_TYPE_SIGNATURE); - if (file == NULL) - { - /* Push errno from grub_file_open() into the error message stack */ - grub_error_push(); - err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("could not open file: %s"), filepath); - goto error; - } - - file_size = grub_file_size (file); - if (file_size == 0) - { - err = grub_error (GRUB_ERR_OUT_OF_RANGE, N_("could not read file size: %s"), filepath); - goto error; - } - - read_buffer = grub_malloc (file_size); - if (read_buffer == NULL) - { - err = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("could not allocate buffer for %s"), filepath); - goto error; - } - - read_n = grub_file_read (file, read_buffer, file_size); - if (read_n != file_size) - { - grub_free (read_buffer); - err = grub_error (GRUB_ERR_FILE_READ_ERROR, N_("could not retrieve file contents: %s"), filepath); - goto error; - } - - *buffer = read_buffer; - *buffer_size = file_size; - - err = GRUB_ERR_NONE; - - error: - if (file != NULL) - grub_file_close (file); - - return err; -} - -/* Check if the data is in TPM 2.0 Key File format */ -static bool -tpm2_protector_is_tpm2key (grub_uint8_t *buffer, grub_size_t buffer_size) -{ - /* id-sealedkey OID (2.23.133.10.1.5) in DER */ - const grub_uint8_t sealed_key_oid[] = {0x06, 0x06, 0x67, 0x81, 0x05, 0x0a}; - grub_size_t skip = 0; - - /* Need at least the first two bytes to check the tag and the length */ - if (buffer_size < 2) - return false; - - /* The first byte is always 0x30 (SEQUENCE). */ - if (buffer[0] != 0x30) - return false; - - /* - * Get the bytes of the length - * - * If the bit 8 of the second byte is 0, it is in the short form, so the second byte - * alone represents the length. Thus, the first two bytes are skipped. - * - * Otherwise, it is in the long form, and bits 1~7 indicate how many more bytes are in - * the length field, so we skip the first two bytes plus the bytes for the length. - */ - if ((buffer[1] & 0x80) == 0) - skip = 2; - else - skip = (buffer[1] & 0x7F) + 2; - - /* Make sure the buffer is large enough to contain id-sealedkey OID */ - if (buffer_size < skip + sizeof (sealed_key_oid)) - return false; - - /* Check id-sealedkey OID */ - if (grub_memcmp (buffer + skip, sealed_key_oid, sizeof (sealed_key_oid)) != 0) - return false; - - return true; -} - -static grub_err_t -tpm2_protector_unmarshal_raw (void *sealed_key, - grub_size_t sealed_key_size, - tpm2_sealed_key_t *sk) -{ - struct grub_tpm2_buffer buf; - - grub_tpm2_buffer_init (&buf); - if (sealed_key_size > buf.cap) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("sealed key larger than %llu bytes"), (unsigned long long)buf.cap); - - grub_memcpy (buf.data, sealed_key, sealed_key_size); - buf.size = sealed_key_size; - - grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (&buf, &sk->public); - grub_Tss2_MU_TPM2B_PRIVATE_Unmarshal (&buf, &sk->private); - - if (buf.error != 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("malformed TPM wire key file")); - - return GRUB_ERR_NONE; -} - -static grub_err_t -tpm2_protector_unmarshal_tpm2key (void *sealed_key, - grub_size_t sealed_key_size, - tpm2key_policy_t *policy_seq, - tpm2key_authpolicy_t *authpol_seq, - grub_uint8_t *rsaparent, - grub_uint32_t *parent, - tpm2_sealed_key_t *sk) -{ - asn1_node tpm2key = NULL; - grub_uint8_t rsaparent_tmp; - grub_uint32_t parent_tmp; - void *sealed_pub = NULL; - grub_size_t sealed_pub_size; - void *sealed_priv = NULL; - grub_size_t sealed_priv_size; - struct grub_tpm2_buffer buf; - grub_err_t err; - - /* - * Start to parse the tpm2key file - * TPMKey ::= SEQUENCE { - * type OBJECT IDENTIFIER, - * emptyAuth [0] EXPLICIT BOOLEAN OPTIONAL, - * policy [1] EXPLICIT SEQUENCE OF TPMPolicy OPTIONAL, - * secret [2] EXPLICIT OCTET STRING OPTIONAL, - * authPolicy [3] EXPLICIT SEQUENCE OF TPMAuthPolicy OPTIONAL, - * description [4] EXPLICIT UTF8String OPTIONAL, - * rsaParent [5] EXPLICIT BOOLEAN OPTIONAL, - * parent INTEGER, - * pubkey OCTET STRING, - * privkey OCTET STRING - * } - */ - err = grub_tpm2key_start_parsing (&tpm2key, sealed_key, sealed_key_size); - if (err != GRUB_ERR_NONE) - return err; - - /* - * Retrieve the policy sequence from 'policy' - * policy_seq will be NULL when 'policy' is not available - */ - err = grub_tpm2key_get_policy_seq (tpm2key, policy_seq); - if (err != GRUB_ERR_NONE) - goto error; - - /* - * Retrieve the authpolicy sequence from 'authPolicy' - * authpol_seq will be NULL when 'authPolicy' is not available - */ - err = grub_tpm2key_get_authpolicy_seq (tpm2key, authpol_seq); - if (err != GRUB_ERR_NONE) - goto error; - - /* Retrieve rsaParent */ - err = grub_tpm2key_get_rsaparent (tpm2key, &rsaparent_tmp); - if (err != GRUB_ERR_NONE) - goto error; - - *rsaparent = rsaparent_tmp; - - /* Retrieve the parent handle */ - err = grub_tpm2key_get_parent (tpm2key, &parent_tmp); - if (err != GRUB_ERR_NONE) - goto error; - - /* The parent handle should be either PERMANENT or PERSISTENT. */ - if (!TPM_HT_IS_PERMANENT (parent_tmp) && !TPM_HT_IS_PERSISTENT (parent_tmp)) - { - err = GRUB_ERR_OUT_OF_RANGE; - goto error; - } - - *parent = parent_tmp; - - /* Retrieve the public part of the sealed key */ - err = grub_tpm2key_get_pubkey (tpm2key, &sealed_pub, &sealed_pub_size); - if (err != GRUB_ERR_NONE) - goto error; - - /* Retrieve the private part of the sealed key */ - err = grub_tpm2key_get_privkey (tpm2key, &sealed_priv, &sealed_priv_size); - if (err != GRUB_ERR_NONE) - goto error; - - /* Unmarshal the sealed key */ - grub_tpm2_buffer_init (&buf); - if (sealed_pub_size + sealed_priv_size > buf.cap) - { - err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("sealed key larger than %llu bytes"), (unsigned long long)buf.cap); - goto error; - } - - grub_tpm2_buffer_pack (&buf, sealed_pub, sealed_pub_size); - grub_tpm2_buffer_pack (&buf, sealed_priv, sealed_priv_size); - - buf.offset = 0; - - grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (&buf, &sk->public); - grub_Tss2_MU_TPM2B_PRIVATE_Unmarshal (&buf, &sk->private); - - if (buf.error != 0) - { - err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("malformed TPM 2.0 key file")); - goto error; - } - - err = GRUB_ERR_NONE; - - error: - /* End the parsing */ - grub_tpm2key_end_parsing (tpm2key); - grub_free (sealed_pub); - grub_free (sealed_priv); - - return err; -} - -/* Check if the SRK exists in the specified handle */ -static grub_err_t -tpm2_protector_srk_check (const TPM_HANDLE_t srk_handle) -{ - TPM_RC_t rc; - TPM2B_PUBLIC_t public; - - /* Find SRK */ - rc = grub_tpm2_readpublic (srk_handle, NULL, &public); - if (rc == TPM_RC_SUCCESS) - return GRUB_ERR_NONE; - - return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to retrieve SRK from 0x%x (TPM2_ReadPublic: 0x%x)", srk_handle, rc); -} - -/* Get the SRK with the template */ -static grub_err_t -tpm2_protector_srk_get (const grub_srk_type_t srk_type, - const TPM_HANDLE_t parent, - TPM_HANDLE_t *srk_handle) -{ - TPM_RC_t rc; - TPMT_PUBLIC_PARMS_t parms = {0}; - TPMS_AUTH_COMMAND_t authCommand = {0}; - TPM2B_SENSITIVE_CREATE_t inSensitive = {0}; - TPM2B_PUBLIC_t inPublic = {0}; - TPM2B_DATA_t outsideInfo = {0}; - TPML_PCR_SELECTION_t creationPcr = {0}; - TPM2B_PUBLIC_t outPublic = {0}; - TPM2B_CREATION_DATA_t creationData = {0}; - TPM2B_DIGEST_t creationHash = {0}; - TPMT_TK_CREATION_t creationTicket = {0}; - TPM2B_NAME_t srkName = {0}; - TPM_HANDLE_t tmp_handle = 0; - - inPublic.publicArea.type = srk_type.type; - inPublic.publicArea.nameAlg = TPM_ALG_SHA256; - inPublic.publicArea.objectAttributes.restricted = 1; - inPublic.publicArea.objectAttributes.userWithAuth = 1; - inPublic.publicArea.objectAttributes.decrypt = 1; - inPublic.publicArea.objectAttributes.fixedTPM = 1; - inPublic.publicArea.objectAttributes.fixedParent = 1; - inPublic.publicArea.objectAttributes.sensitiveDataOrigin = 1; - inPublic.publicArea.objectAttributes.noDA = 1; - - if (srk_type.type == TPM_ALG_RSA) - { - inPublic.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES; - inPublic.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128; - inPublic.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_CFB; - inPublic.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL; - inPublic.publicArea.parameters.rsaDetail.keyBits = srk_type.detail.rsa_bits; - inPublic.publicArea.parameters.rsaDetail.exponent = 0; - } - else if (srk_type.type == TPM_ALG_ECC) - { - inPublic.publicArea.parameters.eccDetail.symmetric.algorithm = TPM_ALG_AES; - inPublic.publicArea.parameters.eccDetail.symmetric.keyBits.aes = 128; - inPublic.publicArea.parameters.eccDetail.symmetric.mode.aes = TPM_ALG_CFB; - inPublic.publicArea.parameters.eccDetail.scheme.scheme = TPM_ALG_NULL; - inPublic.publicArea.parameters.eccDetail.curveID = srk_type.detail.ecc_curve; - inPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM_ALG_NULL; - } - else - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown SRK algorithm"); - - /* Test the parameters before SRK generation */ - parms.type = srk_type.type; - grub_memcpy (&parms.parameters, &inPublic.publicArea.parameters, - sizeof (TPMU_PUBLIC_PARMS_t)); - - rc = grub_tpm2_testparms (&parms, NULL); - if (rc != TPM_RC_SUCCESS) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unsupported SRK template (TPM2_TestParms: 0x%x)", rc); - - /* Create SRK */ - authCommand.sessionHandle = TPM_RS_PW; - rc = grub_tpm2_createprimary (parent, &authCommand, &inSensitive, &inPublic, - &outsideInfo, &creationPcr, &tmp_handle, &outPublic, - &creationData, &creationHash, &creationTicket, - &srkName, NULL); - if (rc != TPM_RC_SUCCESS) - return grub_error (GRUB_ERR_BAD_DEVICE, "could not create SRK (TPM2_CreatePrimary: 0x%x)", rc); - - *srk_handle = tmp_handle; - - return GRUB_ERR_NONE; -} - -/* - * Load the SRK from the persistent handle or create one with a given type of - * template, and then associate the sealed key with the SRK - * Return values: - * - GRUB_ERR_NONE: Everything is fine. - * - GRUB_ERR_BAD_ARGUMENT: The SRK doesn't match. Try another one. - * - Other: Something went wrong. - */ -static grub_err_t -tpm2_protector_srk_load (const grub_srk_type_t srk_type, - const tpm2_sealed_key_t *sealed_key, - const TPM_HANDLE_t parent, - TPM_HANDLE_t *sealed_handle, - TPM_HANDLE_t *srk_handle) -{ - TPMS_AUTH_COMMAND_t authCmd = {0}; - TPM2B_NAME_t name = {0}; - TPM_RC_t rc; - grub_err_t err; - - if (srk_handle == NULL) - return GRUB_ERR_BUG; - - if (*srk_handle != 0) - { - err = tpm2_protector_srk_check (*srk_handle); - if (err != GRUB_ERR_NONE) - return err; - } - else - { - err = tpm2_protector_srk_get (srk_type, parent, srk_handle); - if (err != GRUB_ERR_NONE) - return err; - } - - /* Load the sealed key and associate it with the SRK */ - authCmd.sessionHandle = TPM_RS_PW; - rc = grub_tpm2_load (*srk_handle, &authCmd, &sealed_key->private, &sealed_key->public, - sealed_handle, &name, NULL); - /* - * If TPM2_Load returns (TPM_RC_INTEGRITY | TPM_RC_P | TPM_RC_1), then it - * implies the wrong SRK is used. - */ - if (rc == (TPM_RC_INTEGRITY | TPM_RC_P | TPM_RC_1)) - { - err = grub_error (GRUB_ERR_BAD_ARGUMENT, "SRK not matched"); - goto error; - } - else if (rc != TPM_RC_SUCCESS) - { - err = grub_error (GRUB_ERR_BAD_DEVICE, "failed to load sealed key (TPM2_Load: 0x%x)", rc); - goto error; - } - - return GRUB_ERR_NONE; - - error: - if (!TPM_HT_IS_PERSISTENT (*srk_handle)) - grub_tpm2_flushcontext (*srk_handle); - - return err; -} - -static const char * -srk_type_to_name (grub_srk_type_t srk_type) -{ - if (srk_type.type == TPM_ALG_ECC && srk_type.detail.ecc_curve == TPM_ECC_NIST_P256) - return "ECC_NIST_P256"; - else if (srk_type.type == TPM_ALG_RSA && srk_type.detail.rsa_bits == 2048) - return "RSA2048"; - - return "Unknown"; -} - -static grub_err_t -tpm2_protector_load_key (const tpm2_protector_context_t *ctx, - const tpm2_sealed_key_t *sealed_key, - const TPM_HANDLE_t parent_handle, - TPM_HANDLE_t *sealed_handle, - TPM_HANDLE_t *srk_handle) -{ - grub_err_t err; - int i; - grub_srk_type_t fallback_srks[] = { - { - .type = TPM_ALG_ECC, - .detail.ecc_curve = TPM_ECC_NIST_P256, - }, - { - .type = TPM_ALG_RSA, - .detail.rsa_bits = 2048, - }, - { - .type = TPM_ALG_ERROR, - } - }; - - /* Try the given persistent SRK if exists */ - if (*srk_handle != 0) - { - err = tpm2_protector_srk_load (ctx->srk_type, sealed_key, - parent_handle, sealed_handle, - srk_handle); - if (err != GRUB_ERR_BAD_ARGUMENT) - return err; - - grub_print_error (); - grub_printf ("Trying the specified SRK algorithm: %s\n", srk_type_to_name (ctx->srk_type)); - grub_errno = GRUB_ERR_NONE; - *srk_handle = 0; - } - - /* Try the specified algorithm for the SRK template */ - if (*srk_handle == 0) - { - err = tpm2_protector_srk_load (ctx->srk_type, sealed_key, - parent_handle, sealed_handle, - srk_handle); - if (err != GRUB_ERR_BAD_ARGUMENT) - return err; - - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - *srk_handle = 0; - } - - /* Try all the fallback SRK templates */ - for (i = 0; fallback_srks[i].type != TPM_ALG_ERROR; i++) - { - /* Skip the specified algorithm */ - if (fallback_srks[i].type == ctx->srk_type.type && - (fallback_srks[i].detail.rsa_bits == ctx->srk_type.detail.rsa_bits || - fallback_srks[i].detail.ecc_curve == ctx->srk_type.detail.ecc_curve)) - continue; - - grub_printf ("Trying fallback %s template\n", srk_type_to_name (fallback_srks[i])); - - *srk_handle = 0; - - err = tpm2_protector_srk_load (fallback_srks[i], sealed_key, - parent_handle, sealed_handle, - srk_handle); - if (err != GRUB_ERR_BAD_ARGUMENT) - return err; - - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - } - - return err; -} - -static grub_err_t -tpm2_protector_policypcr (TPMI_SH_AUTH_SESSION_t session, struct grub_tpm2_buffer *cmd_buf) -{ - TPM2B_DIGEST_t pcr_digest; - TPML_PCR_SELECTION_t pcr_sel; - TPM_RC_t rc; - - grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (cmd_buf, &pcr_digest); - grub_Tss2_MU_TPML_PCR_SELECTION_Unmarshal (cmd_buf, &pcr_sel); - if (cmd_buf->error != 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to unmarshal commandPolicy for TPM2_PolicyPCR"); - - /* Record the chosen PCR bank. */ - tpm2_dump_bank = pcr_sel.pcrSelections[0].hash; - - rc = grub_tpm2_policypcr (session, NULL, &pcr_digest, &pcr_sel, NULL); - if (rc != TPM_RC_SUCCESS) - return grub_error (GRUB_ERR_BAD_DEVICE, "failed to submit PCR policy (TPM2_PolicyPCR: 0x%x)", rc); - - return GRUB_ERR_NONE; -} - -static grub_err_t -tpm2_protector_policyauthorize (TPMI_SH_AUTH_SESSION_t session, struct grub_tpm2_buffer *cmd_buf) -{ - TPM2B_PUBLIC_t pubkey; - TPM2B_DIGEST_t policy_ref; - TPMT_SIGNATURE_t signature; - TPM2B_DIGEST_t pcr_policy; - TPM2B_DIGEST_t pcr_policy_hash; - TPMI_ALG_HASH_t sig_hash; - TPMT_TK_VERIFIED_t verification_ticket; - TPM_HANDLE_t pubkey_handle = 0; - TPM2B_NAME_t pubname; - TPM_RC_t rc; - grub_err_t err; - - grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (cmd_buf, &pubkey); - grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (cmd_buf, &policy_ref); - grub_Tss2_MU_TPMT_SIGNATURE_Unmarshal (cmd_buf, &signature); - if (cmd_buf->error != 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to unmarshal the buffer for TPM2_PolicyAuthorize"); - - /* Retrieve Policy Digest */ - rc = grub_tpm2_policygetdigest (session, NULL, &pcr_policy, NULL); - if (rc != TPM_RC_SUCCESS) - return grub_error (GRUB_ERR_BAD_DEVICE, "failed to get policy digest (TPM2_PolicyGetDigest: 0x%x).", rc); - - /* Calculate the digest of the polcy for VerifySignature */ - sig_hash = TPMT_SIGNATURE_get_hash_alg (&signature); - if (sig_hash == TPM_ALG_NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to get the hash algorithm of the signature"); - - rc = grub_tpm2_hash (NULL, (TPM2B_MAX_BUFFER_t *) &pcr_policy, sig_hash, - TPM_RH_NULL, &pcr_policy_hash, NULL, NULL); - if (rc != TPM_RC_SUCCESS) - return grub_error (GRUB_ERR_BAD_DEVICE, "failed to create PCR policy hash (TPM2_Hash: 0x%x)", rc); - - /* Load the public key */ - rc = grub_tpm2_loadexternal (NULL, NULL, &pubkey, TPM_RH_OWNER, &pubkey_handle, &pubname, NULL); - if (rc != TPM_RC_SUCCESS) - return grub_error (GRUB_ERR_BAD_DEVICE, "failed to load public key (TPM2_LoadExternal: 0x%x)", rc); - - /* Verify the signature against the public key and the policy digest */ - rc = grub_tpm2_verifysignature (pubkey_handle, NULL, &pcr_policy_hash, &signature, - &verification_ticket, NULL); - if (rc != TPM_RC_SUCCESS) - { - err = grub_error (GRUB_ERR_BAD_DEVICE, "failed to verify signature (TPM2_VerifySignature: 0x%x)", rc); - goto error; - } - - /* Authorize the signed policy with the public key and the verification ticket */ - rc = grub_tpm2_policyauthorize (session, NULL, &pcr_policy, &policy_ref, &pubname, - &verification_ticket, NULL); - if (rc != TPM_RC_SUCCESS) - { - err = grub_error (GRUB_ERR_BAD_DEVICE, "failed to authorize PCR policy (TPM2_PolicyAuthorize: 0x%x)", rc); - goto error; - } - - err = GRUB_ERR_NONE; - - error: - grub_tpm2_flushcontext (pubkey_handle); - - return err; -} - -static grub_err_t -tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION_t session) -{ - struct grub_tpm2_buffer buf; - grub_err_t err; - - grub_tpm2_buffer_init (&buf); - if (policy->cmd_policy_len > buf.cap) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "CommandPolicy larger than TPM buffer"); - - grub_memcpy (buf.data, policy->cmd_policy, policy->cmd_policy_len); - buf.size = policy->cmd_policy_len; - - switch (policy->cmd_code) - { - case TPM_CC_PolicyPCR: - err = tpm2_protector_policypcr (session, &buf); - break; - case TPM_CC_PolicyAuthorize: - err = tpm2_protector_policyauthorize (session, &buf); - break; - default: - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown TPM Command: 0x%x", policy->cmd_code); - } - - return err; -} - -static grub_err_t -tpm2_protector_enforce_policy_seq (tpm2key_policy_t policy_seq, TPMI_SH_AUTH_SESSION_t session) -{ - tpm2key_policy_t policy; - grub_err_t err; - - FOR_LIST_ELEMENTS (policy, policy_seq) - { - err = tpm2_protector_enforce_policy (policy, session); - if (err != GRUB_ERR_NONE) - return err; - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -tpm2_protector_simple_policy_seq (const tpm2_protector_context_t *ctx, - tpm2key_policy_t *policy_seq) -{ - tpm2key_policy_t policy = NULL; - struct grub_tpm2_buffer buf; - TPML_PCR_SELECTION_t pcr_sel = { - .count = 1, - .pcrSelections = { - { - .hash = ctx->bank, - .sizeOfSelect = 3, - .pcrSelect = {0} - }, - } - }; - grub_uint8_t i; - grub_err_t err; - - if (policy_seq == NULL) - return GRUB_ERR_BAD_ARGUMENT; - - grub_tpm2_buffer_init (&buf); - - for (i = 0; i < ctx->pcr_count; i++) - TPMS_PCR_SELECTION_SelectPCR (&pcr_sel.pcrSelections[0], ctx->pcrs[i]); - - grub_tpm2_buffer_pack_u16 (&buf, 0); - grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&buf, &pcr_sel); - - if (buf.error != 0) - return GRUB_ERR_BAD_ARGUMENT; - - policy = grub_malloc (sizeof(struct tpm2key_policy)); - if (policy == NULL) - { - err = GRUB_ERR_OUT_OF_MEMORY; - goto error; - } - policy->cmd_code = TPM_CC_PolicyPCR; - policy->cmd_policy = grub_malloc (buf.size); - if (policy->cmd_policy == NULL) - { - err = GRUB_ERR_OUT_OF_MEMORY; - goto error; - } - grub_memcpy (policy->cmd_policy, buf.data, buf.size); - policy->cmd_policy_len = buf.size; - - grub_list_push (GRUB_AS_LIST_P (policy_seq), GRUB_AS_LIST (policy)); - - return GRUB_ERR_NONE; - - error: - grub_free (policy); - - return err; -} - -static grub_err_t -tpm2_protector_unseal (tpm2key_policy_t policy_seq, TPM_HANDLE_t sealed_handle, - grub_uint8_t **key, grub_size_t *key_size, bool *dump_pcr) -{ - TPMS_AUTH_COMMAND_t authCmd = {0}; - TPM2B_SENSITIVE_DATA_t data; - TPM2B_NONCE_t nonceCaller = {0}; - TPMT_SYM_DEF_t symmetric = {0}; - TPMI_SH_AUTH_SESSION_t session; - grub_uint8_t *key_out; - TPM_RC_t rc; - grub_err_t err; - - *dump_pcr = false; - - /* Start Auth Session */ - nonceCaller.size = TPM_SHA256_DIGEST_SIZE; - symmetric.algorithm = TPM_ALG_NULL; - rc = grub_tpm2_startauthsession (TPM_RH_NULL, TPM_RH_NULL, NULL, &nonceCaller, NULL, - TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256, - &session, NULL, NULL); - if (rc != TPM_RC_SUCCESS) - return grub_error (GRUB_ERR_BAD_DEVICE, "failed to start auth session (TPM2_StartAuthSession: 0x%x)", rc); - - /* Enforce the policy command sequence */ - err = tpm2_protector_enforce_policy_seq (policy_seq, session); - if (err != GRUB_ERR_NONE) - goto error; - - /* Unseal Sealed Key */ - authCmd.sessionHandle = session; - rc = grub_tpm2_unseal (sealed_handle, &authCmd, &data, NULL); - if (rc != TPM_RC_SUCCESS) - { - /* - * Trigger PCR dump on policy fail - * TPM_RC_S (0x800) | TPM_RC_1 (0x100) | RC_FMT (0x80) | TPM_RC_POLICY_FAIL (0x1D) - */ - if (rc == 0x99D) - *dump_pcr = true; - - err = grub_error (GRUB_ERR_BAD_DEVICE, "failed to unseal sealed key (TPM2_Unseal: 0x%x)", rc); - goto error; - } - - /* Epilogue */ - key_out = grub_malloc (data.size); - if (key_out == NULL) - { - err = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("no memory left to allocate unlock key buffer")); - goto error; - } - - grub_memcpy (key_out, data.buffer, data.size); - - *key = key_out; - *key_size = data.size; - - err = GRUB_ERR_NONE; - - error: - grub_tpm2_flushcontext (session); - - return err; -} - -#define TPM_PCR_STR_SIZE (sizeof (TPMU_HA_t) * 2 + 1) - -static grub_err_t -tpm2_protector_get_pcr_str (const TPM_ALG_ID_t algo, grub_uint32_t index, char *pcr_str, grub_uint16_t buf_size) -{ - TPML_PCR_SELECTION_t pcr_sel = { - .count = 1, - .pcrSelections = { - { - .hash = algo, - .sizeOfSelect = 3, - .pcrSelect = {0} - }, - } - }; - TPML_DIGEST_t digest = {0}; - grub_uint16_t i; - TPM_RC_t rc; - - if (buf_size < TPM_PCR_STR_SIZE) - { - grub_snprintf (pcr_str, buf_size, "insufficient buffer"); - return GRUB_ERR_OUT_OF_MEMORY; - } - - TPMS_PCR_SELECTION_SelectPCR (&pcr_sel.pcrSelections[0], index); - - rc = grub_tpm2_pcr_read (NULL, &pcr_sel, NULL, NULL, &digest, NULL); - if (rc != TPM_RC_SUCCESS) - { - grub_snprintf (pcr_str, buf_size, "TPM2_PCR_Read: 0x%x", rc); - return GRUB_ERR_BAD_DEVICE; - } - - /* Check the returned digest number and size */ - if (digest.count != 1 || digest.digests[0].size > sizeof (TPMU_HA_t)) - { - grub_snprintf (pcr_str, buf_size, "invalid digest"); - return GRUB_ERR_BAD_DEVICE; - } - - /* Print the digest to the buffer */ - for (i = 0; i < digest.digests[0].size; i++) - grub_snprintf (pcr_str + 2 * i, buf_size - 2 * i, "%02x", digest.digests[0].buffer[i]); - - return GRUB_ERR_NONE; -} - -static void -tpm2_protector_dump_pcr (const TPM_ALG_ID_t bank) -{ - const char *algo_name; - char pcr_str[TPM_PCR_STR_SIZE]; - grub_uint8_t i; - grub_err_t err; - - if (bank == TPM_ALG_SHA1) - algo_name = "sha1"; - else if (bank == TPM_ALG_SHA256) - algo_name = "sha256"; - else if (bank == TPM_ALG_SHA384) - algo_name = "sha384"; - else if (bank == TPM_ALG_SHA512) - algo_name = "sha512"; - else - algo_name = "other"; - - /* Try to fetch PCR 0 */ - err = tpm2_protector_get_pcr_str (bank, 0, pcr_str, sizeof (pcr_str)); - if (err != GRUB_ERR_NONE) - { - grub_printf ("Unsupported PCR bank [%s]: %s\n", algo_name, pcr_str); - return; - } - - grub_printf ("TPM PCR [%s]:\n", algo_name); - - grub_printf (" %02d: %s\n", 0, pcr_str); - for (i = 1; i < TPM_MAX_PCRS; i++) - { - tpm2_protector_get_pcr_str (bank, i, pcr_str, sizeof (pcr_str)); - grub_printf (" %02d: %s\n", i, pcr_str); - } -} - -static grub_err_t -tpm2_protector_key_from_buffer (const tpm2_protector_context_t *ctx, - void *buffer, grub_size_t buf_size, - grub_uint8_t **key, grub_size_t *key_size) -{ - tpm2_sealed_key_t sealed_key = {0}; - grub_uint8_t rsaparent = 0; - TPM_HANDLE_t parent_handle = 0; - TPM_HANDLE_t srk_handle = 0; - TPM_HANDLE_t sealed_handle = 0; - tpm2key_policy_t policy_seq = NULL; - tpm2key_authpolicy_t authpol = NULL; - tpm2key_authpolicy_t authpol_seq = NULL; - bool dump_pcr = false; - grub_err_t err; - - /* - * Retrieve sealed key, parent handle, policy sequence, and authpolicy - * sequence from the buffer - */ - if (tpm2_protector_is_tpm2key (buffer, buf_size) == true) - { - err = tpm2_protector_unmarshal_tpm2key (buffer, - buf_size, - &policy_seq, - &authpol_seq, - &rsaparent, - &parent_handle, - &sealed_key); - if (err != GRUB_ERR_NONE) - goto exit1; - - if (rsaparent == 1) - { - tpm2_protector_context_t *ctx_w; - - /* Overwrite the SRK type as noted in the key */ - ctx_w = (tpm2_protector_context_t *)ctx; - ctx_w->srk_type.type = TPM_ALG_RSA; - ctx_w->srk_type.detail.rsa_bits = 2048; - } - } - else - { - parent_handle = TPM_RH_OWNER; - err = tpm2_protector_unmarshal_raw (buffer, buf_size, &sealed_key); - if (err != GRUB_ERR_NONE) - goto exit1; - } - - /* Set the SRK handle if it is specified with '--srk' or inside the key file */ - if (ctx->srk != 0) - srk_handle = ctx->srk; - else if (TPM_HT_IS_PERSISTENT (parent_handle)) - srk_handle = parent_handle; - - /* Load the sealed key into TPM and associate it with the SRK */ - err = tpm2_protector_load_key (ctx, &sealed_key, parent_handle, &sealed_handle, &srk_handle); - if (err != GRUB_ERR_NONE) - goto exit1; - - /* - * Set err to an error code to trigger the standalone policy sequence - * if there is no authpolicy sequence - */ - err = GRUB_ERR_READ_ERROR; - - /* Iterate the authpolicy sequence to find one that unseals the key */ - FOR_LIST_ELEMENTS (authpol, authpol_seq) - { - err = tpm2_protector_unseal (authpol->policy_seq, sealed_handle, key, key_size, &dump_pcr); - if (err == GRUB_ERR_NONE) - break; - - /* - * Push the error message into the grub_error stack - * Note: The grub_error stack may overflow if there are too many policy - * sequences. Anyway, we still can keep the error messages from - * the first few policy sequences which are usually most likely to - * unseal the key. - */ - grub_error_push(); - } - - /* Give the standalone policy sequence a try */ - if (err != GRUB_ERR_NONE) - { - /* - * Create a basic policy sequence based on the given PCR selection if the - * key file doesn't provide one - */ - if (policy_seq == NULL) - { - err = tpm2_protector_simple_policy_seq (ctx, &policy_seq); - if (err != GRUB_ERR_NONE) - goto exit2; - } - - err = tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size, &dump_pcr); - } - - /* Pop error messages on success */ - if (err == GRUB_ERR_NONE) - while (grub_error_pop ()); - - /* Dump PCRs if necessary */ - if (dump_pcr == true) - { - grub_printf ("PCR Mismatch! Check firmware and bootloader before typing passphrase!\n"); - tpm2_protector_dump_pcr (tpm2_dump_bank); - } - - exit2: - grub_tpm2_flushcontext (sealed_handle); - - if (!TPM_HT_IS_PERSISTENT (srk_handle)) - grub_tpm2_flushcontext (srk_handle); - - exit1: - grub_tpm2key_free_policy_seq (policy_seq); - grub_tpm2key_free_authpolicy_seq (authpol_seq); - return err; -} - -static grub_err_t -tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx, - grub_uint8_t **key, grub_size_t *key_size) -{ - const char *filepath; - void *file_bytes = NULL; - grub_size_t file_size = 0; - grub_err_t err; - - if (ctx->tpm2key != NULL) - filepath = ctx->tpm2key; - else if (ctx->keyfile != NULL) - filepath = ctx->keyfile; - else - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("key file not specified")); - - err = tpm2_protector_srk_read_file (filepath, &file_bytes, &file_size); - if (err != GRUB_ERR_NONE) - return err; - - err = tpm2_protector_key_from_buffer (ctx, file_bytes, file_size, key, key_size); - - grub_free (file_bytes); - return err; -} - -static grub_err_t -tpm2_protector_load_persistent (const tpm2_protector_context_t *ctx, TPM_HANDLE_t sealed_handle, - grub_uint8_t **key, grub_size_t *key_size) -{ - tpm2key_policy_t policy_seq = NULL; - bool dump_pcr = false; - grub_err_t err; - - /* Create a basic policy sequence based on the given PCR selection */ - err = tpm2_protector_simple_policy_seq (ctx, &policy_seq); - if (err != GRUB_ERR_NONE) - goto exit; - - err = tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size, &dump_pcr); - - /* Dump PCRs if necessary */ - if (dump_pcr == true) - { - grub_printf ("PCR Mismatch! Check firmware and bootloader before typing passphrase!\n"); - tpm2_protector_dump_pcr (tpm2_dump_bank); - } - - exit: - grub_tpm2_flushcontext (sealed_handle); - - grub_tpm2key_free_policy_seq (policy_seq); - - return err; -} - -static grub_err_t -tpm2_protector_key_from_nvindex (const tpm2_protector_context_t *ctx, TPM_HANDLE_t nvindex, - grub_uint8_t **key, grub_size_t *key_size) -{ - TPMS_AUTH_COMMAND_t authCmd = {0}; - TPM2B_NV_PUBLIC_t nv_public; - TPM2B_NAME_t nv_name; - grub_uint16_t data_size; - TPM2B_MAX_NV_BUFFER_t data; - TPM_RC_t rc; - - /* Get the data size in the NV index handle */ - rc = grub_tpm2_nv_readpublic (nvindex, NULL, &nv_public, &nv_name); - if (rc != TPM_RC_SUCCESS) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to retrieve info from 0x%x (TPM2_NV_ReadPublic: 0x%x)", nvindex, rc); - - data_size = nv_public.nvPublic.dataSize; - if (data_size > TPM_MAX_NV_BUFFER_SIZE) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "insufficient data buffer"); - - /* Read the data from the NV index handle */ - authCmd.sessionHandle = TPM_RS_PW; - rc = grub_tpm2_nv_read (TPM_RH_OWNER, nvindex, &authCmd, data_size, 0, &data); - if (rc != TPM_RC_SUCCESS) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to read data from 0x%x (TPM2_NV_Read: 0x%x)", nvindex, rc); - - return tpm2_protector_key_from_buffer (ctx, data.buffer, data_size, key, key_size); -} - -static grub_err_t -tpm2_protector_nv_recover (const tpm2_protector_context_t *ctx, - grub_uint8_t **key, grub_size_t *key_size) -{ - grub_err_t err; - - if (TPM_HT_IS_PERSISTENT (ctx->nv) == true) - err = tpm2_protector_load_persistent (ctx, ctx->nv, key, key_size); - else if (TPM_HT_IS_NVINDEX (ctx->nv) == true) - err = tpm2_protector_key_from_nvindex (ctx, ctx->nv, key, key_size); - else - err = GRUB_ERR_BAD_ARGUMENT; - - return err; -} - -static grub_err_t -tpm2_protector_recover (const tpm2_protector_context_t *ctx, - grub_uint8_t **key, grub_size_t *key_size) -{ - switch (ctx->mode) - { - case TPM2_PROTECTOR_MODE_SRK: - return tpm2_protector_srk_recover (ctx, key, key_size); - case TPM2_PROTECTOR_MODE_NV: - return tpm2_protector_nv_recover (ctx, key, key_size); - default: - return GRUB_ERR_BAD_ARGUMENT; - } -} - -static grub_err_t -tpm2_protector_recover_key (grub_uint8_t **key, grub_size_t *key_size) -{ - /* Expect a call to tpm2_protector_init before anybody tries to use us */ - if (tpm2_protector_ctx.mode == TPM2_PROTECTOR_MODE_UNSET) - return grub_error (GRUB_ERR_INVALID_COMMAND, N_("cannot use TPM2 key protector without initializing it, call tpm2_protector_init first")); - - if (key == NULL || key_size == NULL) - return GRUB_ERR_BAD_ARGUMENT; - - return tpm2_protector_recover (&tpm2_protector_ctx, key, key_size); -} - -static grub_err_t -tpm2_protector_check_args (tpm2_protector_context_t *ctx) -{ - if (ctx->mode == TPM2_PROTECTOR_MODE_UNSET) - ctx->mode = TPM2_PROTECTOR_MODE_SRK; - - /* Checks for SRK mode */ - if (ctx->mode == TPM2_PROTECTOR_MODE_SRK && - (ctx->keyfile == NULL && ctx->tpm2key == NULL)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in SRK mode, a key file must be specified: --tpm2key/-T or --keyfile/-k")); - - if (ctx->mode == TPM2_PROTECTOR_MODE_SRK && - (ctx->keyfile != NULL && ctx->tpm2key != NULL)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in SRK mode, please specify a key file with only --tpm2key/-T or --keyfile/-k")); - - if (ctx->mode == TPM2_PROTECTOR_MODE_SRK && ctx->nv != 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in SRK mode, an NV Index cannot be specified")); - - /* Checks for NV mode */ - if (ctx->mode == TPM2_PROTECTOR_MODE_NV && ctx->nv == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("in NV Index mode, an NV Index must be specified: --nvindex or -n")); - - if (ctx->mode == TPM2_PROTECTOR_MODE_NV && - (ctx->tpm2key != NULL || ctx->keyfile != NULL)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("a key file cannot be specified when using NV index mode")); - - if (ctx->mode == TPM2_PROTECTOR_MODE_NV && TPM_HT_IS_PERSISTENT (ctx->nv) == true && - (ctx->srk != 0 || ctx->srk_type.type != TPM_ALG_ERROR)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("an SRK cannot be specified when using NV index mode with a persistent handle")); - - if (ctx->mode == TPM2_PROTECTOR_MODE_NV && - (TPM_HT_IS_PERSISTENT (ctx->nv) == false && TPM_HT_IS_NVINDEX (ctx->nv) == false)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("an NV index must be either a persistent handle or an NV index handle when using NV index mode")); - - /* Defaults assignment */ - if (ctx->bank == TPM_ALG_ERROR) - ctx->bank = TPM_ALG_SHA256; - - tpm2_dump_bank = ctx->bank; - - if (ctx->pcr_count == 0) - { - ctx->pcrs[0] = 7; - ctx->pcr_count = 1; - } - - /* - * Set ECC_NIST_P256 as the default SRK when using SRK mode or NV mode with - * an NV index handle - */ - if (ctx->srk_type.type == TPM_ALG_ERROR && - (ctx->mode == TPM2_PROTECTOR_MODE_SRK || - (ctx->mode == TPM2_PROTECTOR_MODE_NV && TPM_HT_IS_NVINDEX (ctx->nv) == true))) - { - ctx->srk_type.type = TPM_ALG_ECC; - ctx->srk_type.detail.ecc_curve = TPM_ECC_NIST_P256; - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -tpm2_protector_parse_file (const char *value, const char **file) -{ - if (grub_strlen (value) == 0) - return GRUB_ERR_BAD_ARGUMENT; - - *file = grub_strdup (value); - if (*file == NULL) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("no memory to duplicate file path")); - - return GRUB_ERR_NONE; -} - -static grub_err_t -tpm2_protector_parse_mode (const char *value, tpm2_protector_mode_t *mode) -{ - if (grub_strcmp (value, "srk") == 0) - *mode = TPM2_PROTECTOR_MODE_SRK; - else if (grub_strcmp (value, "nv") == 0) - *mode = TPM2_PROTECTOR_MODE_NV; - else - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("value '%s' is not a valid TPM2 key protector mode"), value); - - return GRUB_ERR_NONE; -} - -static grub_err_t -tpm2_protector_init_cmd_handler (grub_extcmd_context_t ctxt, int argc, - char **args __attribute__ ((unused))) -{ - struct grub_arg_list *state = ctxt->state; - grub_err_t err; - - if (argc) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("the TPM2 key protector does not accept any non-option arguments (i.e., like -o and/or --option only)")); - - grub_free ((void *) tpm2_protector_ctx.keyfile); - grub_memset (&tpm2_protector_ctx, 0, sizeof (tpm2_protector_ctx)); - - if (state[OPTION_MODE].set) /* mode */ - { - err = tpm2_protector_parse_mode (state[OPTION_MODE].arg, &tpm2_protector_ctx.mode); - if (err != GRUB_ERR_NONE) - return err; - } - - if (state[OPTION_PCRS].set) /* pcrs */ - { - err = grub_tpm2_protector_parse_pcrs (state[OPTION_PCRS].arg, - tpm2_protector_ctx.pcrs, - &tpm2_protector_ctx.pcr_count); - if (err != GRUB_ERR_NONE) - return err; - } - - if (state[OPTION_BANK].set) /* bank */ - { - err = grub_tpm2_protector_parse_bank (state[OPTION_BANK].arg, - &tpm2_protector_ctx.bank); - if (err != GRUB_ERR_NONE) - return err; - } - - if (state[OPTION_TPM2KEY].set) /* tpm2key */ - { - err = tpm2_protector_parse_file (state[OPTION_TPM2KEY].arg, - &tpm2_protector_ctx.tpm2key); - if (err != GRUB_ERR_NONE) - return err; - } - - if (state[OPTION_KEYFILE].set) /* keyfile */ - { - err = tpm2_protector_parse_file (state[OPTION_KEYFILE].arg, - &tpm2_protector_ctx.keyfile); - if (err != GRUB_ERR_NONE) - return err; - } - - if (state[OPTION_SRK].set) /* srk */ - { - err = grub_tpm2_protector_parse_tpm_handle (state[OPTION_SRK].arg, - &tpm2_protector_ctx.srk); - if (err != GRUB_ERR_NONE) - return err; - } - - if (state[OPTION_ASYMMETRIC].set) /* asymmetric */ - { - err = grub_tpm2_protector_parse_asymmetric (state[OPTION_ASYMMETRIC].arg, - &tpm2_protector_ctx.srk_type); - if (err != GRUB_ERR_NONE) - return err; - } - - if (state[OPTION_NVINDEX].set) /* nvindex */ - { - err = grub_tpm2_protector_parse_tpm_handle (state[OPTION_NVINDEX].arg, - &tpm2_protector_ctx.nv); - if (err != GRUB_ERR_NONE) - return err; - } - - err = tpm2_protector_check_args (&tpm2_protector_ctx); - - /* This command only initializes the protector, so nothing else to do. */ - - return err; -} - -static grub_err_t -tpm2_protector_clear_cmd_handler (grub_extcmd_context_t ctxt __attribute__ ((unused)), - int argc, char **args __attribute__ ((unused))) -{ - if (argc != 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("tpm2_key_protector_clear accepts no arguments")); - - grub_free ((void *) tpm2_protector_ctx.keyfile); - grub_memset (&tpm2_protector_ctx, 0, sizeof (tpm2_protector_ctx)); - - return GRUB_ERR_NONE; -} - -static struct grub_key_protector tpm2_key_protector = - { - .name = "tpm2", - .recover_key = tpm2_protector_recover_key - }; - -static grub_err_t -tpm2_dump_pcr (grub_command_t cmd __attribute__((__unused__)), - int argc, char *argv[]) -{ - TPM_ALG_ID_t pcr_bank; - - if (argc == 0) - pcr_bank = TPM_ALG_SHA256; - else if (grub_strcmp (argv[0], "sha1") == 0) - pcr_bank = TPM_ALG_SHA1; - else if (grub_strcmp (argv[0], "sha256") == 0) - pcr_bank = TPM_ALG_SHA256; - else if (grub_strcmp (argv[0], "sha384") == 0) - pcr_bank = TPM_ALG_SHA384; - else if (grub_strcmp (argv[0], "sha512") == 0) - pcr_bank = TPM_ALG_SHA512; - else - { - grub_printf ("Unknown PCR bank\n"); - return GRUB_ERR_BAD_ARGUMENT; - } - - tpm2_protector_dump_pcr (pcr_bank); - - return GRUB_ERR_NONE; -} - -GRUB_MOD_INIT (tpm2_key_protector) -{ - tpm2_protector_init_cmd = - grub_register_extcmd ("tpm2_key_protector_init", - tpm2_protector_init_cmd_handler, 0, - N_("[-m mode] " - "[-p pcr_list] " - "[-b pcr_bank] " - "[-T tpm2_key_file_path] " - "[-k sealed_key_file_path] " - "[-s srk_handle] " - "[-a asymmetric_key_type] " - "[-n nv_index]"), - N_("Initialize the TPM2 key protector."), - tpm2_protector_init_cmd_options); - tpm2_protector_clear_cmd = - grub_register_extcmd ("tpm2_key_protector_clear", - tpm2_protector_clear_cmd_handler, 0, NULL, - N_("Clear the TPM2 key protector if previously initialized."), - NULL); - grub_key_protector_register (&tpm2_key_protector); - - tpm2_dump_pcr_cmd = - grub_register_command ("tpm2_dump_pcr", tpm2_dump_pcr, N_("Dump TPM2 PCRs"), - N_("Print all PCRs of the specified TPM 2.0 bank")); -} - -GRUB_MOD_FINI (tpm2_key_protector) -{ - grub_free ((void *) tpm2_protector_ctx.keyfile); - - grub_key_protector_unregister (&tpm2_key_protector); - grub_unregister_extcmd (tpm2_protector_clear_cmd); - grub_unregister_extcmd (tpm2_protector_init_cmd); - - grub_unregister_command (tpm2_dump_pcr_cmd); -} diff --git a/grub-core/commands/tpm2_key_protector/tpm2.h b/grub-core/commands/tpm2_key_protector/tpm2.h deleted file mode 100644 index 1c1d871b4..000000000 --- a/grub-core/commands/tpm2_key_protector/tpm2.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_TPM2_TPM2_HEADER -#define GRUB_TPM2_TPM2_HEADER 1 - -#include -#include -#include - -/* Well-Known Windows SRK handle */ -#define TPM2_SRK_HANDLE 0x81000001 - -struct tpm2_sealed_key { - TPM2B_PUBLIC_t public; - TPM2B_PRIVATE_t private; -}; -typedef struct tpm2_sealed_key tpm2_sealed_key_t; - -#endif /* ! GRUB_TPM2_TPM2_HEADER */ diff --git a/grub-core/commands/tpm2_key_protector/tpm2_args.h b/grub-core/commands/tpm2_key_protector/tpm2_args.h deleted file mode 100644 index bdbf9f373..000000000 --- a/grub-core/commands/tpm2_key_protector/tpm2_args.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_TPM2_INTERNAL_ARGS_HEADER -#define GRUB_TPM2_INTERNAL_ARGS_HEADER 1 - -#include - -#include "tpm2.h" - -struct grub_srk_type -{ - TPMI_ALG_PUBLIC_t type; - union { - TPM_KEY_BITS_t rsa_bits; - TPM_ECC_CURVE_t ecc_curve; - } detail; -}; -typedef struct grub_srk_type grub_srk_type_t; - -extern grub_err_t -grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs, grub_uint8_t *pcr_count); - -extern grub_err_t -grub_tpm2_protector_parse_asymmetric (const char *value, grub_srk_type_t *srk_type); - -extern grub_err_t -grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID_t *bank); - -extern grub_err_t -grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE_t *handle); - -#endif /* ! GRUB_TPM2_INTERNAL_ARGS_HEADER */ diff --git a/grub-core/commands/tpm2_key_protector/tpm2key.asn b/grub-core/commands/tpm2_key_protector/tpm2key.asn deleted file mode 100644 index e1fb51545..000000000 --- a/grub-core/commands/tpm2_key_protector/tpm2key.asn +++ /dev/null @@ -1,49 +0,0 @@ --- --- GRUB: GRand Unified Bootloader --- Copyright (C) 2024 Free Software Foundation, Inc. --- --- GRUB is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- GRUB is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with GRUB. If not, see . --- --- This file describes TPM 2.0 Key File format for libtasn1. --- To generate tpm2key_asn1_tab.c: asn1Parser tpm2key.asn --- -TPM2KEY {} -DEFINITIONS IMPLICIT TAGS ::= - -BEGIN - -TPMPolicy ::= SEQUENCE { - CommandCode [0] EXPLICIT INTEGER, - CommandPolicy [1] EXPLICIT OCTET STRING -} - -TPMAuthPolicy ::= SEQUENCE { - Name [0] EXPLICIT UTF8String OPTIONAL, - Policy [1] EXPLICIT SEQUENCE OF TPMPolicy -} - -TPMKey ::= SEQUENCE { - type OBJECT IDENTIFIER, - emptyAuth [0] EXPLICIT BOOLEAN OPTIONAL, - policy [1] EXPLICIT SEQUENCE OF TPMPolicy OPTIONAL, - secret [2] EXPLICIT OCTET STRING OPTIONAL, - authPolicy [3] EXPLICIT SEQUENCE OF TPMAuthPolicy OPTIONAL, - description [4] EXPLICIT UTF8String OPTIONAL, - rsaParent [5] EXPLICIT BOOLEAN OPTIONAL, - parent INTEGER, - pubkey OCTET STRING, - privkey OCTET STRING -} - -END diff --git a/grub-core/commands/tpm2_key_protector/tpm2key.c b/grub-core/commands/tpm2_key_protector/tpm2key.c deleted file mode 100644 index 3b6001d84..000000000 --- a/grub-core/commands/tpm2_key_protector/tpm2key.c +++ /dev/null @@ -1,499 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 SUSE LLC - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -#include - -#include "tpm2key.h" - -extern asn1_static_node tpm2key_asn1_tab[]; -const char *sealed_key_oid = "2.23.133.10.1.5"; - -static int -asn1_allocate_and_read (asn1_node node, const char *name, void **content, grub_size_t *content_size) -{ - grub_uint8_t *tmpstr = NULL; - int tmpstr_size = 0; - int ret; - - if (content == NULL) - return ASN1_MEM_ERROR; - - ret = asn1_read_value (node, name, NULL, &tmpstr_size); - if (ret != ASN1_MEM_ERROR) - return ret; - - tmpstr = grub_malloc (tmpstr_size); - if (tmpstr == NULL) - return ASN1_MEM_ERROR; - - ret = asn1_read_value (node, name, tmpstr, &tmpstr_size); - if (ret != ASN1_SUCCESS) - return ret; - - *content = tmpstr; - *content_size = tmpstr_size; - - return ASN1_SUCCESS; -} - -static int -asn1_read_uint32 (asn1_node node, const char *name, grub_uint32_t *out) -{ - grub_uint32_t tmp = 0; - grub_uint8_t *ptr; - void *data = NULL; - grub_size_t data_size; - int ret; - - ret = asn1_allocate_and_read (node, name, &data, &data_size); - if (ret != ASN1_SUCCESS) - return ret; - - /* - * ASN.1 INTEGER is encoded in the following format: - * - * TAG LENGTH OCTECTS - * - * The integer TAG is 02 and LENGTH is the number of followed OCTECTS in - * big endian. For example: - * - * 0x1: 02 01 01 - * 0xabcd: 02 02 ab cd - * - * To decribe 0x1, it only takes 1 octect, so LENGTH is 0x01 and the - * octect is 0x01. On the other hand, 0xabcd requires 2 octects: 'ab" and - * 'cd', so LENGTH is 0x02. - * - * This function only expects a uint32 integer, so it rejects any integer - * containing more than 4 octects. - */ - if (data_size > 4) - { - ret = ASN1_MEM_ERROR; - goto error; - } - - /* Copy the octects into 'tmp' to make it a big-endian uint32 */ - ptr = (grub_uint8_t *) &tmp + (4 - data_size); - grub_memcpy (ptr, data, data_size); - - /* Convert the big-endian integer to host uint32 */ - tmp = grub_be_to_cpu32 (tmp); - - *out = tmp; - error: - if (data) - grub_free (data); - return ret; -} - -grub_err_t -grub_tpm2key_start_parsing (asn1_node *parsed_tpm2key, void *data, grub_size_t size) -{ - asn1_node tpm2key; - asn1_node tpm2key_asn1 = NULL; - void *type_oid = NULL; - grub_size_t type_oid_size = 0; - void *empty_auth = NULL; - grub_size_t empty_auth_size = 0; - int tmp_size = 0; - int ret; - grub_err_t err; - - /* - * TPMKey ::= SEQUENCE { - * type OBJECT IDENTIFIER, - * emptyAuth [0] EXPLICIT BOOLEAN OPTIONAL, - * policy [1] EXPLICIT SEQUENCE OF TPMPolicy OPTIONAL, - * secret [2] EXPLICIT OCTET STRING OPTIONAL, - * authPolicy [3] EXPLICIT SEQUENCE OF TPMAuthPolicy OPTIONAL, - * description [4] EXPLICIT UTF8String OPTIONAL, - * rsaParent [5] EXPLICIT BOOLEAN OPTIONAL, - * parent INTEGER, - * pubkey OCTET STRING, - * privkey OCTET STRING - * } - */ - ret = asn1_array2tree (tpm2key_asn1_tab, &tpm2key_asn1, NULL); - if (ret != ASN1_SUCCESS) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to parse TPM2KEY ASN.1 array"); - - ret = asn1_create_element (tpm2key_asn1, "TPM2KEY.TPMKey", &tpm2key); - if (ret != ASN1_SUCCESS) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to create TPM2KEY.TPMKey"); - - ret = asn1_der_decoding (&tpm2key, data, size, NULL); - if (ret != ASN1_SUCCESS) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to decode TPM2KEY DER"); - - /* Check if 'type' is Sealed Key or not */ - ret = asn1_allocate_and_read (tpm2key, "type", &type_oid, &type_oid_size); - if (ret != ASN1_SUCCESS) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a valid TPM2KEY file"); - - if (grub_memcmp (sealed_key_oid, type_oid, type_oid_size) != 0) - { - err = grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a valid TPM2KEY file"); - goto error; - } - - /* 'emptyAuth' must be 'TRUE' since we don't support password authorization */ - ret = asn1_allocate_and_read (tpm2key, "emptyAuth", &empty_auth, &empty_auth_size); - if (ret != ASN1_SUCCESS || grub_strncmp ("TRUE", empty_auth, empty_auth_size) != 0) - { - err = grub_error (GRUB_ERR_BAD_ARGUMENT, "emptyAuth not TRUE"); - goto error; - } - - /* 'secret' should not be in a sealed key */ - ret = asn1_read_value (tpm2key, "secret", NULL, &tmp_size); - if (ret != ASN1_ELEMENT_NOT_FOUND) - { - err = grub_error (GRUB_ERR_BAD_ARGUMENT, "\"secret\" not allowed for Sealed Key"); - goto error; - } - - *parsed_tpm2key = tpm2key; - - err = GRUB_ERR_NONE; - - error: - grub_free (type_oid); - grub_free (empty_auth); - - return err; -} - -void -grub_tpm2key_end_parsing (asn1_node tpm2key) -{ - asn1_delete_structure (&tpm2key); - tpm2key = NULL; -} - -grub_err_t -grub_tpm2key_get_rsaparent (asn1_node tpm2key, grub_uint8_t *rsaparent) -{ - void *bool_str = NULL; - grub_size_t bool_str_size = 0; - int ret; - - if (rsaparent == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "NULL pointer detected"); - - if (tpm2key == NULL) - return grub_error (GRUB_ERR_READ_ERROR, "invalid parent node"); - - ret = asn1_allocate_and_read (tpm2key, "rsaParent", &bool_str, &bool_str_size); - if (ret == ASN1_SUCCESS) - { - if (grub_strncmp ("TRUE", bool_str, bool_str_size) == 0) - *rsaparent = 1; - else - *rsaparent = 0; - } - else if (ret == ASN1_ELEMENT_NOT_FOUND) - *rsaparent = 0; - else - return grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve rsaParent"); - - grub_free (bool_str); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_tpm2key_get_parent (asn1_node tpm2key, grub_uint32_t *parent) -{ - int ret; - - if (parent == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "NULL pointer detected"); - - if (tpm2key == NULL) - return grub_error (GRUB_ERR_READ_ERROR, "invalid parent node"); - - ret = asn1_read_uint32 (tpm2key, "parent", parent); - if (ret != ASN1_SUCCESS) - return grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve parent"); - - return GRUB_ERR_NONE; -} - -static grub_err_t -tpm2key_get_octstring (asn1_node tpm2key, const char *name, void **data, grub_size_t *size) -{ - int ret; - - if (name == NULL || data == NULL || size == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid parameter(s)"); - - if (tpm2key == NULL) - return grub_error (GRUB_ERR_READ_ERROR, "invalid %s node", name); - - ret = asn1_allocate_and_read (tpm2key, name, data, size); - if (ret != ASN1_SUCCESS) - return grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve %s", name); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_tpm2key_get_pubkey (asn1_node tpm2key, void **data, grub_size_t *size) -{ - return tpm2key_get_octstring (tpm2key, "pubkey", data, size); -} - -grub_err_t -grub_tpm2key_get_privkey (asn1_node tpm2key, void **data, grub_size_t *size) -{ - return tpm2key_get_octstring (tpm2key, "privkey", data, size); -} - -/* - * The maximum and minimum number of elements for 'policy' and 'authPolicy' sequences - * - * Although there is no limit for the number of sequences elements, we set the upper - * bound to 99 to make it easier to implement the code. - * - * Any 'policy' or 'authPolicy' contains more than 99 commands/policies would become - * extremely complex to manage so it is impractical to support such use case. - */ -#define TPM2KEY_ELEMENTS_MAX 99 -#define TPM2KEY_ELEMENTS_MIN 1 - -/* - * The string to fetch 'Policy' from 'authPolicy': - * authPolicy.?XX.Policy - */ -#define AUTHPOLICY_POL_MAX_STR "authPolicy.?XX.Policy" -#define AUTHPOLICY_POL_MAX (sizeof (AUTHPOLICY_POL_MAX_STR)) - -/* - * Expected strings for CommandCode and CommandPolicy: - * policy.?XX.CommandCode - * policy.?XX.CommandPolicy - * authPolicy.?XX.Policy.?YY.CommandCode - * authPolicy.?XX.Policy.?YY.CommandPolicy - */ -#define CMD_CODE_MAX_STR AUTHPOLICY_POL_MAX_STR".?YY.CommandCode" -#define CMD_POL_MAX_STR AUTHPOLICY_POL_MAX_STR".?YY.CommandPolicy" -#define CMD_CODE_MAX (sizeof (CMD_CODE_MAX_STR)) -#define CMD_POL_MAX (sizeof (CMD_POL_MAX_STR)) - -static int -tpm2key_get_policy_seq (asn1_node tpm2key, const char *prefix, - tpm2key_policy_t *policy_seq) -{ - tpm2key_policy_t tmp_seq = NULL; - tpm2key_policy_t policy = NULL; - int policy_n; - char cmd_code[CMD_CODE_MAX]; - char cmd_pol[CMD_POL_MAX]; - grub_size_t cmd_policy_len; - int i; - int ret; - - ret = asn1_number_of_elements (tpm2key, prefix, &policy_n); - if (ret != ASN1_SUCCESS) - return ret; - - /* - * Limit the number of policy commands to two digits (99) - * Although there is no upper bound for the number of policy commands, - * in practice, it takes one or two policy commands to unseal the key, - * so the 99 commands limit is more than enough. - */ - if (policy_n > TPM2KEY_ELEMENTS_MAX || policy_n < TPM2KEY_ELEMENTS_MIN) - return ASN1_VALUE_NOT_VALID; - - /* - * Iterate the policy commands backwards since grub_list_push() prepends - * the item into the list. - */ - for (i = policy_n; i >= 1; i--) { - policy = grub_zalloc (sizeof (struct tpm2key_policy)); - if (policy == NULL) - { - ret = ASN1_MEM_ALLOC_ERROR; - goto error; - } - grub_snprintf (cmd_code, CMD_CODE_MAX, "%s.?%d.CommandCode", prefix, i); - grub_snprintf (cmd_pol, CMD_POL_MAX, "%s.?%d.CommandPolicy", prefix, i); - - /* CommandCode [0] EXPLICIT INTEGER */ - ret = asn1_read_uint32 (tpm2key, cmd_code, &policy->cmd_code); - if (ret != ASN1_SUCCESS) - return ret; - - /* CommandPolicy [1] EXPLICIT OCTET STRING */ - ret = tpm2key_get_octstring (tpm2key, cmd_pol, &policy->cmd_policy, - &cmd_policy_len); - if (ret != ASN1_SUCCESS) - { - goto error; - } - else if (cmd_policy_len > GRUB_TPM2_BUFFER_CAPACITY) - { - /* - * CommandPolicy is the marshalled parameters for the TPM command so - * it should not be larger than the maximum TPM2 buffer. - */ - ret = ASN1_VALUE_NOT_VALID; - goto error; - } - policy->cmd_policy_len = (grub_uint16_t)cmd_policy_len; - - /* Prepend the policy command into the sequence */ - grub_list_push (GRUB_AS_LIST_P (&tmp_seq), GRUB_AS_LIST (policy)); - } - - *policy_seq = tmp_seq; - - return ASN1_SUCCESS; - - error: - if (policy != NULL) - { - grub_free (policy->cmd_policy); - grub_free (policy); - } - grub_tpm2key_free_policy_seq (tmp_seq); - - return ret; -} - -grub_err_t -grub_tpm2key_get_policy_seq (asn1_node tpm2key, tpm2key_policy_t *policy_seq) -{ - int ret; - - ret = tpm2key_get_policy_seq (tpm2key, "policy", policy_seq); - if (ret == ASN1_ELEMENT_NOT_FOUND) - { - /* "policy" is optional, so it may not be available */ - *policy_seq = NULL; - return GRUB_ERR_NONE; - } - else if (ret != ASN1_SUCCESS) - return grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve policy"); - - return GRUB_ERR_NONE; -} - -void -grub_tpm2key_free_policy_seq (tpm2key_policy_t policy_seq) -{ - tpm2key_policy_t policy; - tpm2key_policy_t next; - - if (policy_seq == NULL) - return; - - FOR_LIST_ELEMENTS_SAFE (policy, next, policy_seq) - { - grub_free (policy->cmd_policy); - grub_free (policy); - } -} - -grub_err_t -grub_tpm2key_get_authpolicy_seq (asn1_node tpm2key, tpm2key_authpolicy_t *authpol_seq) -{ - tpm2key_authpolicy_t tmp_seq = NULL; - tpm2key_authpolicy_t authpol = NULL; - int authpol_n; - char authpol_pol[AUTHPOLICY_POL_MAX]; - int i; - int ret; - grub_err_t err; - - ret = asn1_number_of_elements (tpm2key, "authPolicy", &authpol_n); - if (ret == ASN1_ELEMENT_NOT_FOUND) - { - /* "authPolicy" is optional, so it may not be available */ - *authpol_seq = NULL; - return GRUB_ERR_NONE; - } - else if (ret != ASN1_SUCCESS) - return grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve authPolicy"); - - /* Limit the number of authPolicy elements to two digits (99) */ - if (authpol_n > TPM2KEY_ELEMENTS_MAX || authpol_n < TPM2KEY_ELEMENTS_MIN) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid number of authPolicy elements"); - - /* - * Iterate the authPolicy elements backwards since grub_list_push() prepends - * the item into the list. - */ - for (i = authpol_n; i >= 1; i--) { - authpol = grub_zalloc (sizeof (struct tpm2key_authpolicy)); - if (authpol == NULL) - { - err = grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to allocate memory for authPolicy"); - goto error; - } - grub_snprintf (authpol_pol, AUTHPOLICY_POL_MAX, "authPolicy.?%d.Policy", i); - - ret = tpm2key_get_policy_seq (tpm2key, authpol_pol, &authpol->policy_seq); - if (ret != ASN1_SUCCESS) - { - err = grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve policy from authPolicy"); - goto error; - } - - /* Prepend the authPolicy element into the sequence */ - grub_list_push (GRUB_AS_LIST_P (&tmp_seq), GRUB_AS_LIST (authpol)); - } - - *authpol_seq = tmp_seq; - - return GRUB_ERR_NONE; - - error: - if (authpol != NULL) - { - grub_tpm2key_free_policy_seq (authpol->policy_seq); - grub_free (authpol); - } - - grub_tpm2key_free_authpolicy_seq (tmp_seq); - - return err; -} - -void -grub_tpm2key_free_authpolicy_seq (tpm2key_authpolicy_t authpol_seq) -{ - tpm2key_authpolicy_t authpol; - tpm2key_authpolicy_t next; - - if (authpol_seq == NULL) - return; - - FOR_LIST_ELEMENTS_SAFE (authpol, next, authpol_seq) - { - grub_tpm2key_free_policy_seq (authpol->policy_seq); - grub_free (authpol); - } -} diff --git a/grub-core/commands/tpm2_key_protector/tpm2key.h b/grub-core/commands/tpm2_key_protector/tpm2key.h deleted file mode 100644 index f749d62c2..000000000 --- a/grub-core/commands/tpm2_key_protector/tpm2key.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 SUSE LLC - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_TPM2_TPM2KEY_HEADER -#define GRUB_TPM2_TPM2KEY_HEADER 1 - -#include -#include - -/* - * TPMPolicy ::= SEQUENCE { - * CommandCode [0] EXPLICIT INTEGER, - * CommandPolicy [1] EXPLICIT OCTET STRING - * } - */ -struct tpm2key_policy { - struct tpm2key_policy *next; - struct tpm2key_policy **prev; - grub_uint32_t cmd_code; - void *cmd_policy; - grub_uint16_t cmd_policy_len; -}; -typedef struct tpm2key_policy *tpm2key_policy_t; - -/* - * TPMAuthPolicy ::= SEQUENCE { - * Name [0] EXPLICIT UTF8String OPTIONAL, - * Policy [1] EXPLICIT SEQUENCE OF TPMPolicy - * } - * - * Name is not a necessary part to unseal the key. Ignore it. - */ -struct tpm2key_authpolicy { - struct tpm2key_authpolicy *next; - struct tpm2key_authpolicy **prev; - /* char *name; */ - tpm2key_policy_t policy_seq; -}; -typedef struct tpm2key_authpolicy *tpm2key_authpolicy_t; - -extern grub_err_t -grub_tpm2key_start_parsing (asn1_node *parsed_tpm2key, void *data, grub_size_t size); - -extern void -grub_tpm2key_end_parsing (asn1_node tpm2key); - -extern grub_err_t -grub_tpm2key_get_rsaparent (asn1_node tpm2key, grub_uint8_t *rsaparent); - -extern grub_err_t -grub_tpm2key_get_parent (asn1_node tpm2key, grub_uint32_t *parent); - -extern grub_err_t -grub_tpm2key_get_pubkey (asn1_node tpm2key, void **data, grub_size_t *size); - -extern grub_err_t -grub_tpm2key_get_privkey (asn1_node tpm2key, void **data, grub_size_t *size); - -extern grub_err_t -grub_tpm2key_get_policy_seq (asn1_node tpm2key, tpm2key_policy_t *policy_seq); - -extern void -grub_tpm2key_free_policy_seq (tpm2key_policy_t policy_seq); - -extern grub_err_t -grub_tpm2key_get_authpolicy_seq (asn1_node tpm2key, tpm2key_authpolicy_t *authpol_seq); - -extern void -grub_tpm2key_free_authpolicy_seq (tpm2key_authpolicy_t authpol_seq); - -#endif /* GRUB_TPM2_TPM2KEY_HEADER */ diff --git a/grub-core/commands/tpm2_key_protector/tpm2key_asn1_tab.c b/grub-core/commands/tpm2_key_protector/tpm2key_asn1_tab.c deleted file mode 100644 index bebe108a3..000000000 --- a/grub-core/commands/tpm2_key_protector/tpm2key_asn1_tab.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -/* - * This file is generated by 'asn1Parser tpm2key.asn' and the '#include' - * headers are replaced with the ones in grub2. - * - 'grub/mm.h' for the definition of 'NULL' - * - 'libtasn1.h' for the definition of 'asn1_static_node' - */ - -#include -#include - -const asn1_static_node tpm2key_asn1_tab[] = { - { "TPM2KEY", 536875024, NULL }, - { NULL, 1073741836, NULL }, - { "TPMPolicy", 1610612741, NULL }, - { "CommandCode", 1610620931, NULL }, - { NULL, 2056, "0"}, - { "CommandPolicy", 536879111, NULL }, - { NULL, 2056, "1"}, - { "TPMAuthPolicy", 1610612741, NULL }, - { "Name", 1610637346, NULL }, - { NULL, 2056, "0"}, - { "Policy", 536879115, NULL }, - { NULL, 1073743880, "1"}, - { NULL, 2, "TPMPolicy"}, - { "TPMKey", 536870917, NULL }, - { "type", 1073741836, NULL }, - { "emptyAuth", 1610637316, NULL }, - { NULL, 2056, "0"}, - { "policy", 1610637323, NULL }, - { NULL, 1073743880, "1"}, - { NULL, 2, "TPMPolicy"}, - { "secret", 1610637319, NULL }, - { NULL, 2056, "2"}, - { "authPolicy", 1610637323, NULL }, - { NULL, 1073743880, "3"}, - { NULL, 2, "TPMAuthPolicy"}, - { "description", 1610637346, NULL }, - { NULL, 2056, "4"}, - { "rsaParent", 1610637316, NULL }, - { NULL, 2056, "5"}, - { "parent", 1073741827, NULL }, - { "pubkey", 1073741831, NULL }, - { "privkey", 7, NULL }, - { NULL, 0, NULL } -}; diff --git a/grub-core/commands/tr.c b/grub-core/commands/tr.c deleted file mode 100644 index ef72841a2..000000000 --- a/grub-core/commands/tr.c +++ /dev/null @@ -1,126 +0,0 @@ -/* tr.c -- The tr command. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static const struct grub_arg_option options[] = - { - { "set", 's', 0, N_("Set a variable to return value."), N_("VARNAME"), ARG_TYPE_STRING }, - { "upcase", 'U', 0, N_("Translate to upper case."), 0, 0 }, - { "downcase", 'D', 0, N_("Translate to lower case."), 0, 0 }, - { 0, 0, 0, 0, 0, 0 } - }; - -static const char *letters_lowercase = "abcdefghijklmnopqrstuvwxyz"; -static const char *letters_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -static grub_err_t -grub_cmd_tr (grub_extcmd_context_t ctxt, int argc, char **args) -{ - char *var = 0; - const char *input = 0; - char *output = 0, *optr; - const char *s1 = 0; - const char *s2 = 0; - const char *iptr; - - /* Select the defaults from options. */ - if (ctxt->state[0].set) { - var = ctxt->state[0].arg; - input = grub_env_get (var); - } - - if (ctxt->state[1].set) { - s1 = letters_lowercase; - s2 = letters_uppercase; - } - - if (ctxt->state[2].set) { - s1 = letters_uppercase; - s2 = letters_lowercase; - } - - /* Check for arguments and update the defaults. */ - if (argc == 1) - input = args[0]; - - else if (argc == 2) { - s1 = args[0]; - s2 = args[1]; - - } else if (argc == 3) { - s1 = args[0]; - s2 = args[1]; - input = args[2]; - - } else if (argc > 3) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters"); - - if (!s1 || !s2 || !input) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing parameters"); - - if (grub_strlen (s1) != grub_strlen (s2)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "set sizes did not match"); - - /* Translate input into output buffer. */ - - output = grub_malloc (grub_strlen (input) + 1); - if (! output) - return grub_errno; - - optr = output; - for (iptr = input; *iptr; iptr++) - { - char *p = grub_strchr (s1, *iptr); - if (p) - *optr++ = s2[p - s1]; - else - *optr++ = *iptr; - } - *optr = '\0'; - - if (ctxt->state[0].set) - grub_env_set (var, output); - else - grub_printf ("%s\n", output); - - grub_free (output); - return GRUB_ERR_NONE; -} - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT(tr) -{ - cmd = grub_register_extcmd ("tr", grub_cmd_tr, 0, N_("[OPTIONS] [SET1] [SET2] [STRING]"), - N_("Translate SET1 characters to SET2 in STRING."), options); -} - -GRUB_MOD_FINI(tr) -{ - grub_unregister_extcmd (cmd); -} diff --git a/grub-core/commands/videoinfo.c b/grub-core/commands/videoinfo.c deleted file mode 100644 index 205ba78c9..000000000 --- a/grub-core/commands/videoinfo.c +++ /dev/null @@ -1,267 +0,0 @@ -/* videoinfo.c - command to list video modes. */ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct hook_ctx -{ - unsigned height, width, depth; - struct grub_video_mode_info *current_mode; -}; - -static int -hook (const struct grub_video_mode_info *info, void *hook_arg) -{ - struct hook_ctx *ctx = hook_arg; - - if (ctx->height && ctx->width && (info->width != ctx->width || info->height != ctx->height)) - return 0; - - if (ctx->depth && info->bpp != ctx->depth) - return 0; - - if (info->mode_number == GRUB_VIDEO_MODE_NUMBER_INVALID) - grub_printf (" "); - else - { - if (ctx->current_mode && info->mode_number == ctx->current_mode->mode_number) - grub_printf ("*"); - else - grub_printf (" "); - grub_printf (" 0x%03x ", info->mode_number); - } - grub_printf ("%4d x %4d x %2d (%4d) ", info->width, info->height, info->bpp, - info->pitch); - - if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT) - grub_xputs (_("Text-only ")); - /* Show mask and position details for direct color modes. */ - if (info->mode_type & GRUB_VIDEO_MODE_TYPE_RGB) - /* TRANSLATORS: "Direct color" is a mode when the color components - are written dirrectly into memory. */ - grub_printf_ (N_("Direct color, mask: %d/%d/%d/%d pos: %d/%d/%d/%d"), - info->red_mask_size, - info->green_mask_size, - info->blue_mask_size, - info->reserved_mask_size, - info->red_field_pos, - info->green_field_pos, - info->blue_field_pos, - info->reserved_field_pos); - if (info->mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) - /* TRANSLATORS: In "paletted color" mode you write the index of the color - in the palette. Synonyms include "packed pixel". */ - grub_xputs (_("Paletted ")); - if (info->mode_type & GRUB_VIDEO_MODE_TYPE_YUV) - grub_xputs (_("YUV ")); - if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PLANAR) - /* TRANSLATORS: "Planar" is the video memory where you have to write - in several different banks "plans" to control the different color - components of the same pixel. */ - grub_xputs (_("Planar ")); - if (info->mode_type & GRUB_VIDEO_MODE_TYPE_HERCULES) - grub_xputs (_("Hercules ")); - if (info->mode_type & GRUB_VIDEO_MODE_TYPE_CGA) - grub_xputs (_("CGA ")); - if (info->mode_type & GRUB_VIDEO_MODE_TYPE_NONCHAIN4) - /* TRANSLATORS: Non-chain 4 is a 256-color planar - (unchained) video memory mode. */ - grub_xputs (_("Non-chain 4 ")); - if (info->mode_type & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) - grub_xputs (_("Monochrome ")); - if (info->mode_type & GRUB_VIDEO_MODE_TYPE_UNKNOWN) - grub_xputs (_("Unknown video mode ")); - - grub_xputs ("\n"); - - return 0; -} - -static void -print_edid (struct grub_video_edid_info *edid_info) -{ - unsigned int edid_width, edid_height; - - if (grub_video_edid_checksum (edid_info)) - { - grub_puts_ (N_(" EDID checksum invalid")); - grub_errno = GRUB_ERR_NONE; - return; - } - - grub_printf_ (N_(" EDID version: %u.%u\n"), - edid_info->version, edid_info->revision); - if (grub_video_edid_preferred_mode (edid_info, &edid_width, &edid_height) - == GRUB_ERR_NONE) - grub_printf_ (N_(" Preferred mode: %ux%u\n"), edid_width, edid_height); - else - { - grub_printf_ (N_(" No preferred mode available\n")); - grub_errno = GRUB_ERR_NONE; - } -} - -static grub_err_t -grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) -{ - grub_video_adapter_t adapter; - grub_video_driver_id_t id; - struct hook_ctx ctx; - - ctx.height = ctx.width = ctx.depth = 0; - if (argc) - { - const char *ptr; - ptr = args[0]; - ctx.width = grub_strtoul (ptr, &ptr, 0); - if (grub_errno) - return grub_errno; - if (*ptr != 'x') - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("invalid video mode specification `%s'"), - args[0]); - ptr++; - ctx.height = grub_strtoul (ptr, &ptr, 0); - if (grub_errno) - return grub_errno; - if (*ptr == 'x') - { - ptr++; - ctx.depth = grub_strtoul (ptr, &ptr, 0); - if (grub_errno) - return grub_errno; - } - } - -#ifdef GRUB_MACHINE_PCBIOS - if (grub_strcmp (cmd->name, "vbeinfo") == 0) - grub_dl_load ("vbe"); -#endif - - id = grub_video_get_driver_id (); - - grub_puts_ (N_("List of supported video modes:")); - grub_puts_ (N_("Legend: mask/position=red/green/blue/reserved")); - - FOR_VIDEO_ADAPTERS (adapter) - { - struct grub_video_mode_info info; - struct grub_video_edid_info edid_info; - - grub_printf_ (N_("Adapter `%s':\n"), adapter->name); - - if (!adapter->iterate) - { - grub_puts_ (N_(" No info available")); - continue; - } - - ctx.current_mode = NULL; - - if (adapter->id == id) - { - if (grub_video_get_info (&info) == GRUB_ERR_NONE) - ctx.current_mode = &info; - else - /* Don't worry about errors. */ - grub_errno = GRUB_ERR_NONE; - } - else if (id != GRUB_VIDEO_DRIVER_NONE) - { - grub_puts_ (N_(" A video driver is active, cannot initialize this driver until it is deactivated\n")); - continue; - } - else - { - if (adapter->init ()) - { - grub_puts_ (N_(" Failed to initialize video adapter")); - grub_errno = GRUB_ERR_NONE; - continue; - } - } - - if (adapter->print_adapter_specific_info) - adapter->print_adapter_specific_info (); - - adapter->iterate (hook, &ctx); - - if (adapter->get_edid && adapter->get_edid (&edid_info) == GRUB_ERR_NONE) - print_edid (&edid_info); - else - grub_errno = GRUB_ERR_NONE; - - ctx.current_mode = NULL; - - if (adapter->id != id) - { - if (adapter->fini ()) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - } - } - return GRUB_ERR_NONE; -} - -static grub_command_t cmd; -#ifdef GRUB_MACHINE_PCBIOS -static grub_command_t cmd_vbe; -#endif - -GRUB_MOD_INIT(videoinfo) -{ - cmd = grub_register_command ("videoinfo", grub_cmd_videoinfo, - /* TRANSLATORS: "x" has to be entered in, - like an identifier, so please don't - use better Unicode codepoints. */ - N_("[WxH[xD]]"), - N_("List available video modes. If " - "resolution is given show only modes" - " matching it.")); -#ifdef GRUB_MACHINE_PCBIOS - cmd_vbe = grub_register_command ("vbeinfo", grub_cmd_videoinfo, - /* TRANSLATORS: "x" has to be entered in, - like an identifier, so please don't - use better Unicode codepoints. */ - N_("[WxH[xD]]"), - N_("List available video modes. If " - "resolution is given show only modes" - " matching it.")); -#endif -} - -GRUB_MOD_FINI(videoinfo) -{ - grub_unregister_command (cmd); -#ifdef GRUB_MACHINE_PCBIOS - grub_unregister_command (cmd_vbe); -#endif -} - diff --git a/grub-core/commands/videotest.c b/grub-core/commands/videotest.c deleted file mode 100644 index ac145afc2..000000000 --- a/grub-core/commands/videotest.c +++ /dev/null @@ -1,241 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) -{ - grub_err_t err; - grub_video_color_t color; - unsigned int x; - unsigned int y; - unsigned int width; - unsigned int height; - int i; - struct grub_video_render_target *text_layer; - grub_video_color_t palette[16]; - const char *mode = NULL; - -#ifdef GRUB_MACHINE_PCBIOS - if (grub_strcmp (cmd->name, "vbetest") == 0) - grub_dl_load ("vbe"); -#endif - mode = grub_env_get ("gfxmode"); - if (argc) - mode = args[0]; - if (!mode) - mode = "auto"; - - err = grub_video_set_mode (mode, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); - if (err) - return err; - - grub_video_get_viewport (&x, &y, &width, &height); - - { - const char *str; - int texty; - grub_font_t sansbig; - grub_font_t sans; - grub_font_t sanssmall; - grub_font_t fixed; - struct grub_font_glyph *glyph; - - if (grub_video_create_render_target (&text_layer, width, height, - GRUB_VIDEO_MODE_TYPE_RGB - | GRUB_VIDEO_MODE_TYPE_ALPHA) - || !text_layer) - goto fail; - - grub_video_set_active_render_target (text_layer); - - color = grub_video_map_rgb (0, 255, 255); - 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); - - 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+2286 subset symbol E2 8A 86 - 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\x86\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++) - { - - if (i == 0 || i == 1) - { - 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, 0); - grub_video_fill_rect (color, 100, 0, 100, 100); - - color = grub_video_map_rgb (0, 0, 255); - grub_video_fill_rect (color, 200, 0, 100, 100); - - color = grub_video_map_rgb (0, 255, 255); - grub_video_fill_rect (color, 0, 100, 100, 100); - - color = grub_video_map_rgb (255, 0, 255); - grub_video_fill_rect (color, 100, 100, 100, 100); - - color = grub_video_map_rgb (255, 255, 0); - grub_video_fill_rect (color, 200, 100, 100, 100); - - 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); - } - - 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; - - fail: - grub_video_delete_render_target (text_layer); - grub_video_restore (); - return grub_errno; -} - -static grub_command_t cmd; -#ifdef GRUB_MACHINE_PCBIOS -static grub_command_t cmd_vbe; -#endif - -GRUB_MOD_INIT(videotest) -{ - cmd = grub_register_command ("videotest", grub_cmd_videotest, - /* TRANSLATORS: "x" has to be entered in, - like an identifier, so please don't - use better Unicode codepoints. */ - N_("[WxH]"), - /* TRANSLATORS: Here, on the other hand, it's - nicer to use unicode cross instead of x. */ - N_("Test video subsystem in mode WxH.")); -#ifdef GRUB_MACHINE_PCBIOS - cmd_vbe = grub_register_command ("vbetest", grub_cmd_videotest, - 0, N_("Test video subsystem.")); -#endif -} - -GRUB_MOD_FINI(videotest) -{ - grub_unregister_command (cmd); -#ifdef GRUB_MACHINE_PCBIOS - grub_unregister_command (cmd_vbe); -#endif -} diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c deleted file mode 100644 index ed6586505..000000000 --- a/grub-core/commands/wildcard.c +++ /dev/null @@ -1,652 +0,0 @@ -/* wildcard.c - Wildcard character expansion for GRUB script. */ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -static inline int isregexop (char ch); -static char ** merge (char **lhs, char **rhs); -static char *make_dir (const char *prefix, const char *start, const char *end); -static int make_regex (const char *regex_start, const char *regex_end, - regex_t *regexp); -static void split_path (const char *path, const char **suffix_end, const char **regex_end); -static char ** match_devices (const regex_t *regexp, int noparts); -static char ** match_files (const char *prefix, const char *suffix_start, - const char *suffix_end, const regex_t *regexp); - -static grub_err_t wildcard_expand (const char *s, char ***strs); - -struct grub_script_wildcard_translator grub_filename_translator = { - .expand = wildcard_expand, -}; - -static char ** -merge (char **dest, char **ps) -{ - int i; - int j; - char **p; - grub_size_t sz; - - if (! dest) - return ps; - - if (! ps) - return dest; - - for (i = 0; dest[i]; i++) - ; - for (j = 0; ps[j]; j++) - ; - - if (grub_add (i, j, &sz) || - grub_add (sz, 1, &sz) || - grub_mul (sz, sizeof (char *), &sz)) - return dest; - - p = grub_realloc (dest, sz); - if (! p) - { - grub_free (dest); - grub_free (ps); - return 0; - } - - dest = p; - for (j = 0; ps[j]; j++) - dest[i++] = ps[j]; - dest[i] = 0; - - grub_free (ps); - return dest; -} - -static inline int -isregexop (char ch) -{ - return grub_strchr ("*.\\|+{}[]?", ch) ? 1 : 0; -} - -static char * -make_dir (const char *prefix, const char *start, const char *end) -{ - char ch; - unsigned i; - unsigned n; - char *result; - - i = grub_strlen (prefix); - n = i + end - start; - - result = grub_malloc (n + 1); - if (! result) - return 0; - - grub_strcpy (result, prefix); - while (start < end && (ch = *start++)) - if (ch == '\\' && isregexop (*start)) - result[i++] = *start++; - else - result[i++] = ch; - - result[i] = '\0'; - return result; -} - -static int -make_regex (const char *start, const char *end, regex_t *regexp) -{ - char ch; - int i = 0; - unsigned len = end - start; - char *buffer; - grub_size_t sz; - - /* Worst case size is (len * 2 + 2 + 1). */ - if (grub_mul (len, 2, &sz) || - grub_add (sz, 3, &sz)) - return 1; - - buffer = grub_malloc (sz); - if (! buffer) - return 1; - - buffer[i++] = '^'; - while (start < end) - { - /* XXX Only * and ? expansion for now. */ - switch ((ch = *start++)) - { - case '\\': - buffer[i++] = ch; - if (*start != '\0') - buffer[i++] = *start++; - break; - - case '.': - case '(': - case ')': - case '@': - case '+': - case '|': - case '{': - case '}': - case '[': - case ']': - buffer[i++] = '\\'; - buffer[i++] = ch; - break; - - case '*': - buffer[i++] = '.'; - buffer[i++] = '*'; - break; - - case '?': - buffer[i++] = '.'; - break; - - default: - buffer[i++] = ch; - } - } - buffer[i++] = '$'; - buffer[i] = '\0'; - grub_dprintf ("expand", "Regexp is %s\n", buffer); - - if (regcomp (regexp, buffer, RE_SYNTAX_GNU_AWK)) - { - grub_free (buffer); - return 1; - } - - grub_free (buffer); - return 0; -} - -/* Split `str' into two parts: (1) dirname that is regexop free (2) - dirname that has a regexop. */ -static void -split_path (const char *str, const char **noregexop, const char **regexop) -{ - char ch = 0; - int regex = 0; - - const char *end; - const char *split; /* points till the end of dirnaname that doesn't - need expansion. */ - - split = end = str; - while ((ch = *end)) - { - if (ch == '\\' && end[1]) - end++; - - else if (ch == '*' || ch == '?') - regex = 1; - - else if (ch == '/' && ! regex) - split = end + 1; /* forward to next regexop-free dirname */ - - else if (ch == '/' && regex) - break; /* stop at the first dirname with a regexop */ - - end++; - } - - *regexop = end; - if (! regex) - *noregexop = end; - else - *noregexop = split; -} - -/* Context for match_devices. */ -struct match_devices_ctx -{ - const regex_t *regexp; - int noparts; - int ndev; - char **devs; -}; - -/* Helper for match_devices. */ -static int -match_devices_iter (const char *name, void *data) -{ - struct match_devices_ctx *ctx = data; - char **t; - char *buffer; - grub_size_t sz; - - /* skip partitions if asked to. */ - if (ctx->noparts && grub_strchr (name, ',')) - return 0; - - buffer = grub_xasprintf ("(%s)", name); - if (! buffer) - return 1; - - grub_dprintf ("expand", "matching: %s\n", buffer); - if (regexec (ctx->regexp, buffer, 0, 0, 0)) - { - grub_dprintf ("expand", "not matched\n"); - fail: - grub_free (buffer); - return 0; - } - - if (grub_add (ctx->ndev, 2, &sz) || - grub_mul (sz, sizeof (char *), &sz)) - goto fail; - - t = grub_realloc (ctx->devs, sz); - if (! t) - { - grub_free (buffer); - return 1; - } - - ctx->devs = t; - ctx->devs[ctx->ndev++] = buffer; - ctx->devs[ctx->ndev] = 0; - return 0; -} - -static char ** -match_devices (const regex_t *regexp, int noparts) -{ - struct match_devices_ctx ctx = { - .regexp = regexp, - .noparts = noparts, - .ndev = 0, - .devs = 0 - }; - int i; - - if (grub_device_iterate (match_devices_iter, &ctx)) - goto fail; - - return ctx.devs; - - fail: - - for (i = 0; ctx.devs && ctx.devs[i]; i++) - grub_free (ctx.devs[i]); - - grub_free (ctx.devs); - - return 0; -} - -/* Context for match_files. */ -struct match_files_ctx -{ - const regex_t *regexp; - char **files; - unsigned nfile; - char *dir; -}; - -/* Helper for match_files. */ -static int -match_files_iter (const char *name, - const struct grub_dirhook_info *info __attribute__((unused)), - void *data) -{ - struct match_files_ctx *ctx = data; - char **t; - char *buffer; - grub_size_t sz; - - /* skip . and .. names */ - if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0) - return 0; - - grub_dprintf ("expand", "matching: %s in %s\n", name, ctx->dir); - if (regexec (ctx->regexp, name, 0, 0, 0)) - return 0; - - grub_dprintf ("expand", "matched\n"); - - buffer = grub_xasprintf ("%s%s", ctx->dir, name); - if (! buffer) - return 1; - - if (grub_add (ctx->nfile, 2, &sz) || - grub_mul (sz, sizeof (char *), &sz)) - goto fail; - - t = grub_realloc (ctx->files, sz); - if (!t) - { - fail: - grub_free (buffer); - return 1; - } - - ctx->files = t; - ctx->files[ctx->nfile++] = buffer; - ctx->files[ctx->nfile] = 0; - return 0; -} - -static char ** -match_files (const char *prefix, const char *suffix, const char *end, - const regex_t *regexp) -{ - struct match_files_ctx ctx = { - .regexp = regexp, - .nfile = 0, - .files = 0 - }; - int i; - const char *path; - char *device_name; - grub_fs_t fs; - grub_device_t dev; - - dev = 0; - device_name = 0; - grub_error_push (); - - ctx.dir = make_dir (prefix, suffix, end); - if (! ctx.dir) - goto fail; - - device_name = grub_file_get_device_name (ctx.dir); - dev = grub_device_open (device_name); - if (! dev) - goto fail; - - fs = grub_fs_probe (dev); - if (! fs) - goto fail; - - if (ctx.dir[0] == '(') - { - path = grub_strchr (ctx.dir, ')'); - if (!path) - goto fail; - path++; - } - else - path = ctx.dir; - - if (fs->fs_dir (dev, path, match_files_iter, &ctx)) - goto fail; - - grub_free (ctx.dir); - grub_device_close (dev); - grub_free (device_name); - grub_error_pop (); - return ctx.files; - - fail: - - grub_free (ctx.dir); - - for (i = 0; ctx.files && ctx.files[i]; i++) - grub_free (ctx.files[i]); - - grub_free (ctx.files); - - if (dev) - grub_device_close (dev); - - grub_free (device_name); - - grub_error_pop (); - return 0; -} - -/* Context for check_file. */ -struct check_file_ctx -{ - const char *basename; - int found; -}; - -/* Helper for check_file. */ -static int -check_file_iter (const char *name, const struct grub_dirhook_info *info, - void *data) -{ - struct check_file_ctx *ctx = data; - - if (ctx->basename[0] == 0 - || (info->case_insensitive ? grub_strcasecmp (name, ctx->basename) == 0 - : grub_strcmp (name, ctx->basename) == 0)) - { - ctx->found = 1; - return 1; - } - - return 0; -} - -static int -check_file (const char *dir, const char *basename) -{ - struct check_file_ctx ctx = { - .basename = basename, - .found = 0 - }; - grub_fs_t fs; - grub_device_t dev; - const char *device_name, *path; - - device_name = grub_file_get_device_name (dir); - dev = grub_device_open (device_name); - if (! dev) - goto fail; - - fs = grub_fs_probe (dev); - if (! fs) - goto fail; - - if (dir[0] == '(') - { - path = grub_strchr (dir, ')'); - if (!path) - goto fail; - path++; - } - else - path = dir; - - fs->fs_dir (dev, path[0] ? path : "/", check_file_iter, &ctx); - if (grub_errno == 0 && basename[0] == 0) - ctx.found = 1; - - fail: - grub_errno = 0; - - return ctx.found; -} - -static void -unescape (char *out, const char *in, const char *end) -{ - char *optr; - const char *iptr; - - for (optr = out, iptr = in; iptr < end;) - { - if (*iptr == '\\' && iptr + 1 < end) - { - *optr++ = iptr[1]; - iptr += 2; - continue; - } - if (*iptr == '\\') - break; - *optr++ = *iptr++; - } - *optr = 0; -} - -static grub_err_t -wildcard_expand (const char *s, char ***strs) -{ - const char *start; - const char *regexop; - const char *noregexop; - char **paths = 0; - int had_regexp = 0; - - unsigned i; - regex_t regexp; - - *strs = 0; - if (s[0] != '/' && s[0] != '(' && s[0] != '*') - return 0; - - start = s; - while (*start) - { - split_path (start, &noregexop, ®exop); - - if (noregexop == regexop) - { - grub_dprintf ("expand", "no expansion needed\n"); - if (paths == 0) - { - paths = grub_malloc (sizeof (char *) * 2); - if (!paths) - goto fail; - paths[0] = grub_malloc (regexop - start + 1); - if (!paths[0]) - goto fail; - unescape (paths[0], start, regexop); - paths[1] = 0; - } - else - { - int j = 0; - for (i = 0; paths[i]; i++) - { - char *o, *oend; - char *n; - char *p; - o = paths[i]; - oend = o + grub_strlen (o); - n = grub_malloc ((oend - o) + (regexop - start) + 1); - if (!n) - goto fail; - grub_memcpy (n, o, oend - o); - - unescape (n + (oend - o), start, regexop); - if (had_regexp) - p = grub_strrchr (n, '/'); - else - p = 0; - if (!p) - { - grub_free (o); - paths[j++] = n; - continue; - } - *p = 0; - if (!check_file (n, p + 1)) - { - grub_dprintf ("expand", "file <%s> in <%s> not found\n", - p + 1, n); - grub_free (o); - grub_free (n); - continue; - } - *p = '/'; - grub_free (o); - paths[j++] = n; - } - if (j == 0) - { - grub_free (paths); - paths = 0; - goto done; - } - paths[j] = 0; - } - grub_dprintf ("expand", "paths[0] = `%s'\n", paths[0]); - start = regexop; - continue; - } - - if (make_regex (noregexop, regexop, ®exp)) - goto fail; - - had_regexp = 1; - - if (paths == 0) - { - if (start == noregexop) /* device part has regexop */ - paths = match_devices (®exp, *start != '('); - - else /* device part explicit wo regexop */ - paths = match_files ("", start, noregexop, ®exp); - } - else - { - char **r = 0; - - for (i = 0; paths[i]; i++) - { - char **p; - - p = match_files (paths[i], start, noregexop, ®exp); - grub_free (paths[i]); - if (! p) - continue; - - r = merge (r, p); - if (! r) - goto fail; - } - grub_free (paths); - paths = r; - } - - regfree (®exp); - if (! paths) - goto done; - - start = regexop; - } - - done: - - *strs = paths; - return 0; - - fail: - - for (i = 0; paths && paths[i]; i++) - grub_free (paths[i]); - grub_free (paths); - regfree (®exp); - return grub_errno; -} diff --git a/grub-core/commands/xen/lsxen.c b/grub-core/commands/xen/lsxen.c deleted file mode 100644 index 97713102c..000000000 --- a/grub-core/commands/xen/lsxen.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static int -hook (const char *dir, void *hook_data __attribute__ ((unused))) -{ - grub_printf ("%s\n", dir); - return 0; -} - -static grub_err_t -grub_cmd_lsxen (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) -{ - char *dir; - grub_err_t err; - char *buf; - - if (argc >= 1) - return grub_xenstore_dir (args[0], hook, NULL); - - buf = grub_xenstore_get_file ("domid", NULL); - if (!buf) - return grub_errno; - dir = grub_xasprintf ("/local/domain/%s", buf); - grub_free (buf); - err = grub_xenstore_dir (dir, hook, NULL); - grub_free (dir); - return err; -} - -static grub_err_t -grub_cmd_catxen (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) -{ - const char *dir = "domid"; - char *buf; - - if (argc >= 1) - dir = args[0]; - - buf = grub_xenstore_get_file (dir, NULL); - if (!buf) - return grub_errno; - grub_xputs (buf); - grub_xputs ("\n"); - grub_free (buf); - return GRUB_ERR_NONE; - -} - -static grub_command_t cmd_ls, cmd_cat; - -GRUB_MOD_INIT (lsxen) -{ - cmd_ls = grub_register_command ("xen_ls", grub_cmd_lsxen, N_("[DIR]"), - N_("List Xen storage.")); - cmd_cat = grub_register_command ("xen_cat", grub_cmd_catxen, N_("[DIR]"), - N_("List Xen storage.")); -} - -GRUB_MOD_FINI (lsxen) -{ - grub_unregister_command (cmd_ls); - grub_unregister_command (cmd_cat); -} diff --git a/grub-core/disk/AFSplitter.c b/grub-core/disk/AFSplitter.c deleted file mode 100644 index 249163ff0..000000000 --- a/grub-core/disk/AFSplitter.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * AFsplitter - Anti forensic information splitter - * Copyright 2004, Clemens Fruhwirth - * - * AFsplitter diffuses information over a large stripe of data, - * therefor supporting secure data destruction. - * - * This program is grub_free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the grub_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 Library 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 grub_free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv2+"); - -gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, - grub_uint8_t * dst, grub_size_t blocksize, - grub_size_t blocknumbers); - -static void -diffuse (const gcry_md_spec_t * hash, grub_uint8_t * src, - grub_uint8_t * dst, grub_size_t size) -{ - grub_size_t i; - grub_uint32_t IV; /* host byte order independend hash IV */ - - grub_size_t fullblocks = size / hash->mdlen; - int padding = size % hash->mdlen; - grub_uint8_t final[GRUB_CRYPTO_MAX_MDLEN]; - grub_uint8_t temp[sizeof (IV) + GRUB_CRYPTO_MAX_MDLEN]; - - /* hash block the whole data set with different IVs to produce - * more than just a single data block - */ - for (i = 0; i < fullblocks; i++) - { - IV = grub_cpu_to_be32 (i); - grub_memcpy (temp, &IV, sizeof (IV)); - grub_memcpy (temp + sizeof (IV), src + hash->mdlen * i, hash->mdlen); - grub_crypto_hash (hash, dst + hash->mdlen * i, temp, - sizeof (IV) + hash->mdlen); - } - - if (padding) - { - IV = grub_cpu_to_be32 (i); - grub_memcpy (temp, &IV, sizeof (IV)); - grub_memcpy (temp + sizeof (IV), src + hash->mdlen * i, padding); - grub_crypto_hash (hash, final, temp, sizeof (IV) + padding); - grub_memcpy (dst + hash->mdlen * i, final, padding); - } -} - -/** - * Merges the splitted master key stored on disk into the original key - */ -gcry_err_code_t -AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, grub_uint8_t * dst, - grub_size_t blocksize, grub_size_t blocknumbers) -{ - grub_size_t i; - grub_uint8_t *bufblock; - - if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN || hash->mdlen == 0) - return GPG_ERR_INV_ARG; - - bufblock = grub_zalloc (blocksize); - if (bufblock == NULL) - return GPG_ERR_OUT_OF_MEMORY; - - grub_memset (bufblock, 0, blocksize); - for (i = 0; i < blocknumbers - 1; i++) - { - grub_crypto_xor (bufblock, src + (blocksize * i), bufblock, blocksize); - diffuse (hash, bufblock, bufblock, blocksize); - } - grub_crypto_xor (dst, src + (i * blocksize), bufblock, blocksize); - - grub_free (bufblock); - return GPG_ERR_NO_ERROR; -} diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c deleted file mode 100644 index f3c968195..000000000 --- a/grub-core/disk/ahci.c +++ /dev/null @@ -1,1161 +0,0 @@ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct grub_ahci_cmd_head -{ - grub_uint32_t config; - grub_uint32_t transferred; - grub_uint64_t command_table_base; - grub_uint32_t unused[4]; -}; - -struct grub_ahci_prdt_entry -{ - grub_uint64_t data_base; - grub_uint32_t unused; - grub_uint32_t size; -}; - -struct grub_ahci_cmd_table -{ - grub_uint8_t cfis[0x40]; - grub_uint8_t command[0x10]; - grub_uint8_t reserved[0x30]; - struct grub_ahci_prdt_entry prdt[1]; -}; - -struct grub_ahci_hba_port -{ - grub_uint64_t command_list_base; - grub_uint64_t fis_base; - grub_uint32_t intstatus; - grub_uint32_t inten; - grub_uint32_t command; - grub_uint32_t unused1; - grub_uint32_t task_file_data; - grub_uint32_t sig; - grub_uint32_t status; - grub_uint32_t unused2; - grub_uint32_t sata_error; - grub_uint32_t sata_active; - grub_uint32_t command_issue; - grub_uint32_t unused3; - grub_uint32_t fbs; - grub_uint32_t unused4[15]; -}; - -enum grub_ahci_hba_port_command - { - GRUB_AHCI_HBA_PORT_CMD_ST = 0x01, - GRUB_AHCI_HBA_PORT_CMD_SPIN_UP = 0x02, - GRUB_AHCI_HBA_PORT_CMD_POWER_ON = 0x04, - GRUB_AHCI_HBA_PORT_CMD_FRE = 0x10, - GRUB_AHCI_HBA_PORT_CMD_CR = 0x8000, - GRUB_AHCI_HBA_PORT_CMD_FR = 0x4000, - }; - -enum grub_ahci_hba_port_int_status - { - GRUB_AHCI_HBA_PORT_IS_IFS = (1UL << 27), - GRUB_AHCI_HBA_PORT_IS_HBDS = (1UL << 28), - GRUB_AHCI_HBA_PORT_IS_HBFS = (1UL << 29), - GRUB_AHCI_HBA_PORT_IS_TFES = (1UL << 30), - }; - -#define GRUB_AHCI_HBA_PORT_IS_FATAL_MASK ( \ - GRUB_AHCI_HBA_PORT_IS_IFS | \ - GRUB_AHCI_HBA_PORT_IS_HBDS | \ - GRUB_AHCI_HBA_PORT_IS_HBFS | \ - GRUB_AHCI_HBA_PORT_IS_TFES) - -struct grub_ahci_hba -{ - grub_uint32_t cap; - grub_uint32_t global_control; - grub_uint32_t intr_status; - grub_uint32_t ports_implemented; - grub_uint32_t unused1[6]; - grub_uint32_t bios_handoff; - grub_uint32_t unused2[53]; - struct grub_ahci_hba_port ports[32]; -}; - -struct grub_ahci_received_fis -{ - char raw[4096]; -}; - -enum - { - GRUB_AHCI_HBA_CAP_NPORTS_MASK = 0x1f - }; - -enum - { - GRUB_AHCI_HBA_GLOBAL_CONTROL_RESET = 0x00000001, - GRUB_AHCI_HBA_GLOBAL_CONTROL_INTR_EN = 0x00000002, - GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN = 0x80000000, - }; - -enum - { - GRUB_AHCI_BIOS_HANDOFF_BIOS_OWNED = 1, - GRUB_AHCI_BIOS_HANDOFF_OS_OWNED = 2, - GRUB_AHCI_BIOS_HANDOFF_OS_OWNERSHIP_CHANGED = 8, - GRUB_AHCI_BIOS_HANDOFF_RWC = 8 - }; - - -struct grub_ahci_device -{ - struct grub_ahci_device *next; - struct grub_ahci_device **prev; - volatile struct grub_ahci_hba *hba; - int port; - int num; - struct grub_pci_dma_chunk *command_list_chunk; - volatile struct grub_ahci_cmd_head *command_list; - struct grub_pci_dma_chunk *command_table_chunk; - volatile struct grub_ahci_cmd_table *command_table; - struct grub_pci_dma_chunk *rfis; - int present; - int atapi; -}; - -static grub_err_t -grub_ahci_readwrite_real (struct grub_ahci_device *dev, - struct grub_disk_ata_pass_through_parms *parms, int reset); - - -enum - { - GRUB_AHCI_CONFIG_READ = 0, - GRUB_AHCI_CONFIG_CFIS_LENGTH_MASK = 0x1f, - GRUB_AHCI_CONFIG_ATAPI = 0x20, - GRUB_AHCI_CONFIG_WRITE = 0x40, - GRUB_AHCI_CONFIG_PREFETCH = 0x80, - GRUB_AHCI_CONFIG_RESET = 0x100, - GRUB_AHCI_CONFIG_BIST = 0x200, - GRUB_AHCI_CONFIG_CLEAR_R_OK = 0x400, - GRUB_AHCI_CONFIG_PMP_MASK = 0xf000, - GRUB_AHCI_CONFIG_PRDT_LENGTH_MASK = 0xffff0000, - }; -#define GRUB_AHCI_CONFIG_CFIS_LENGTH_SHIFT 0 -#define GRUB_AHCI_CONFIG_PMP_SHIFT 12 -#define GRUB_AHCI_CONFIG_PRDT_LENGTH_SHIFT 16 -#define GRUB_AHCI_INTERRUPT_ON_COMPLETE 0x80000000 - -#define GRUB_AHCI_PRDT_MAX_CHUNK_LENGTH 0x200000 - -static struct grub_ahci_device *grub_ahci_devices; -static int numdevs; - -static int -grub_ahci_pciinit (grub_pci_device_t dev, - grub_pci_id_t pciid __attribute__ ((unused)), - void *data __attribute__ ((unused))) -{ - grub_pci_address_t addr; - grub_uint32_t class; - grub_uint32_t bar; - unsigned i, nports; - volatile struct grub_ahci_hba *hba; - - /* Read class. */ - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - class = grub_pci_read (addr); - - /* Check if this class ID matches that of a PCI IDE Controller. */ - if (class >> 8 != 0x010601) - return 0; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG5); - - bar = grub_pci_read (addr); - - if ((bar & (GRUB_PCI_ADDR_SPACE_MASK | GRUB_PCI_ADDR_MEM_TYPE_MASK - | GRUB_PCI_ADDR_MEM_PREFETCH)) - != (GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32)) - return 0; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write_word (addr, grub_pci_read_word (addr) - | GRUB_PCI_COMMAND_MEM_ENABLED | GRUB_PCI_COMMAND_BUS_MASTER); - - hba = grub_pci_device_map_range (dev, bar & GRUB_PCI_ADDR_MEM_MASK, - sizeof (*hba)); - grub_dprintf ("ahci", "dev: %x:%x.%x\n", dev.bus, dev.device, dev.function); - - grub_dprintf ("ahci", "tfd[0]: %x\n", - hba->ports[0].task_file_data); - grub_dprintf ("ahci", "cmd[0]: %x\n", - hba->ports[0].command); - grub_dprintf ("ahci", "st[0]: %x\n", - hba->ports[0].status); - grub_dprintf ("ahci", "err[0]: %x\n", - hba->ports[0].sata_error); - - grub_dprintf ("ahci", "tfd[1]: %x\n", - hba->ports[1].task_file_data); - grub_dprintf ("ahci", "cmd[1]: %x\n", - hba->ports[1].command); - grub_dprintf ("ahci", "st[1]: %x\n", - hba->ports[1].status); - grub_dprintf ("ahci", "err[1]: %x\n", - hba->ports[1].sata_error); - - hba->ports[1].sata_error = hba->ports[1].sata_error; - - grub_dprintf ("ahci", "err[1]: %x\n", - hba->ports[1].sata_error); - - grub_dprintf ("ahci", "BH:%x\n", hba->bios_handoff); - - if (! (hba->bios_handoff & GRUB_AHCI_BIOS_HANDOFF_OS_OWNED)) - { - grub_uint64_t endtime; - - grub_dprintf ("ahci", "Requesting AHCI ownership\n"); - hba->bios_handoff = (hba->bios_handoff & ~GRUB_AHCI_BIOS_HANDOFF_RWC) - | GRUB_AHCI_BIOS_HANDOFF_OS_OWNED; - grub_dprintf ("ahci", "Waiting for BIOS to give up ownership\n"); - endtime = grub_get_time_ms () + 1000; - while ((hba->bios_handoff & GRUB_AHCI_BIOS_HANDOFF_BIOS_OWNED) - && grub_get_time_ms () < endtime); - if (hba->bios_handoff & GRUB_AHCI_BIOS_HANDOFF_BIOS_OWNED) - { - grub_dprintf ("ahci", "Forcibly taking ownership\n"); - hba->bios_handoff = GRUB_AHCI_BIOS_HANDOFF_OS_OWNED; - hba->bios_handoff |= GRUB_AHCI_BIOS_HANDOFF_OS_OWNERSHIP_CHANGED; - } - else - grub_dprintf ("ahci", "AHCI ownership obtained\n"); - } - else - grub_dprintf ("ahci", "AHCI is already in OS mode\n"); - - grub_dprintf ("ahci", "GLC:%x\n", hba->global_control); - - grub_dprintf ("ahci", "err[1]: %x\n", - hba->ports[1].sata_error); - - if (!(hba->global_control & GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN)) - grub_dprintf ("ahci", "AHCI is in compat mode. Switching\n"); - else - grub_dprintf ("ahci", "AHCI is in AHCI mode.\n"); - - grub_dprintf ("ahci", "err[1]: %x\n", - hba->ports[1].sata_error); - - grub_dprintf ("ahci", "GLC:%x\n", hba->global_control); - - /* { - grub_uint64_t endtime; - hba->global_control |= 1; - endtime = grub_get_time_ms () + 1000; - while (hba->global_control & 1) - if (grub_get_time_ms () > endtime) - { - grub_dprintf ("ahci", "couldn't reset AHCI\n"); - return 0; - } - }*/ - - grub_dprintf ("ahci", "GLC:%x\n", hba->global_control); - - grub_dprintf ("ahci", "err[1]: %x\n", - hba->ports[1].sata_error); - - for (i = 0; i < 5; i++) - { - hba->global_control |= GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN; - grub_millisleep (1); - if (hba->global_control & GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN) - break; - } - if (i == 5) - { - grub_dprintf ("ahci", "Couldn't put AHCI in AHCI mode\n"); - return 0; - } - - grub_dprintf ("ahci", "GLC:%x\n", hba->global_control); - - grub_dprintf ("ahci", "err[1]: %x\n", - hba->ports[1].sata_error); - - grub_dprintf ("ahci", "err[1]: %x\n", - hba->ports[1].sata_error); - - grub_dprintf ("ahci", "GLC:%x\n", hba->global_control); - - for (i = 0; i < 5; i++) - { - hba->global_control |= GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN; - grub_millisleep (1); - if (hba->global_control & GRUB_AHCI_HBA_GLOBAL_CONTROL_AHCI_EN) - break; - } - if (i == 5) - { - grub_dprintf ("ahci", "Couldn't put AHCI in AHCI mode\n"); - return 0; - } - - grub_dprintf ("ahci", "err[1]: %x\n", - hba->ports[1].sata_error); - - grub_dprintf ("ahci", "GLC:%x\n", hba->global_control); - - nports = (GRUB_AHCI_HBA_CAP_NPORTS_MASK) + 1; - - grub_dprintf ("ahci", "%d AHCI ports, PI = 0x%x\n", nports, - hba->ports_implemented); - - struct grub_ahci_device *adevs[GRUB_AHCI_HBA_CAP_NPORTS_MASK + 1]; - struct grub_ahci_device *failed_adevs[GRUB_AHCI_HBA_CAP_NPORTS_MASK + 1]; - grub_uint32_t fr_running = 0; - - for (i = 0; i < nports; i++) - failed_adevs[i] = 0; - for (i = 0; i < nports; i++) - { - if (!(hba->ports_implemented & (1 << i))) - { - adevs[i] = 0; - continue; - } - - adevs[i] = grub_zalloc (sizeof (*adevs[i])); - if (!adevs[i]) - return 1; - - adevs[i]->hba = hba; - adevs[i]->port = i; - adevs[i]->present = 1; - adevs[i]->num = numdevs++; - } - - for (i = 0; i < nports; i++) - if (adevs[i]) - { - adevs[i]->hba->ports[adevs[i]->port].sata_error = adevs[i]->hba->ports[adevs[i]->port].sata_error; - grub_dprintf ("ahci", "port: %d, err: %x\n", adevs[i]->port, - adevs[i]->hba->ports[adevs[i]->port].sata_error); - - adevs[i]->command_list_chunk = grub_memalign_dma32 (1024, sizeof (struct grub_ahci_cmd_head) * 32); - if (!adevs[i]->command_list_chunk) - { - adevs[i] = 0; - continue; - } - - adevs[i]->command_table_chunk = grub_memalign_dma32 (1024, - sizeof (struct grub_ahci_cmd_table)); - if (!adevs[i]->command_table_chunk) - { - grub_dma_free (adevs[i]->command_list_chunk); - adevs[i] = 0; - continue; - } - - adevs[i]->command_list = grub_dma_get_virt (adevs[i]->command_list_chunk); - adevs[i]->command_table = grub_dma_get_virt (adevs[i]->command_table_chunk); - - grub_memset ((void *) adevs[i]->command_list, 0, - sizeof (struct grub_ahci_cmd_table)); - grub_memset ((void *) adevs[i]->command_table, 0, - sizeof (struct grub_ahci_cmd_head) * 32); - - adevs[i]->command_list->command_table_base - = grub_dma_get_phys (adevs[i]->command_table_chunk); - - grub_dprintf ("ahci", "found device ahci%d (port %d), command_table = %p, command_list = %p\n", - adevs[i]->num, adevs[i]->port, grub_dma_get_virt (adevs[i]->command_table_chunk), - grub_dma_get_virt (adevs[i]->command_list_chunk)); - - adevs[i]->hba->ports[adevs[i]->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_FRE; - } - - grub_uint64_t endtime; - endtime = grub_get_time_ms () + 1000; - - while (grub_get_time_ms () < endtime) - { - for (i = 0; i < nports; i++) - if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].command & GRUB_AHCI_HBA_PORT_CMD_FR)) - break; - if (i == nports) - break; - } - - for (i = 0; i < nports; i++) - if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].command & GRUB_AHCI_HBA_PORT_CMD_FR)) - { - grub_dprintf ("ahci", "couldn't stop FR on port %d\n", i); - failed_adevs[i] = adevs[i]; - adevs[i] = 0; - } - - for (i = 0; i < nports; i++) - if (adevs[i]) - adevs[i]->hba->ports[adevs[i]->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_ST; - endtime = grub_get_time_ms () + 1000; - - while (grub_get_time_ms () < endtime) - { - for (i = 0; i < nports; i++) - if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)) - break; - if (i == nports) - break; - } - - for (i = 0; i < nports; i++) - if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)) - { - grub_dprintf ("ahci", "couldn't stop CR on port %d\n", i); - failed_adevs[i] = adevs[i]; - adevs[i] = 0; - } - for (i = 0; i < nports; i++) - if (adevs[i]) - { - adevs[i]->hba->ports[adevs[i]->port].inten = 0; - adevs[i]->hba->ports[adevs[i]->port].intstatus = ~0; - // adevs[i]->hba->ports[adevs[i]->port].fbs = 0; - - grub_dprintf ("ahci", "port: %d, err: %x\n", adevs[i]->port, - adevs[i]->hba->ports[adevs[i]->port].sata_error); - - adevs[i]->rfis = grub_memalign_dma32 (4096, - sizeof (struct grub_ahci_received_fis)); - grub_memset ((char *) grub_dma_get_virt (adevs[i]->rfis), 0, - sizeof (struct grub_ahci_received_fis)); - grub_memset ((char *) grub_dma_get_virt (adevs[i]->command_list_chunk), 0, - sizeof (struct grub_ahci_cmd_head)); - grub_memset ((char *) grub_dma_get_virt (adevs[i]->command_table_chunk), 0, - sizeof (struct grub_ahci_cmd_table)); - adevs[i]->hba->ports[adevs[i]->port].fis_base = grub_dma_get_phys (adevs[i]->rfis); - adevs[i]->hba->ports[adevs[i]->port].command_list_base - = grub_dma_get_phys (adevs[i]->command_list_chunk); - adevs[i]->hba->ports[adevs[i]->port].command_issue = 0; - adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_FRE; - } - - endtime = grub_get_time_ms () + 1000; - - while (grub_get_time_ms () < endtime) - { - for (i = 0; i < nports; i++) - if (adevs[i] && !(adevs[i]->hba->ports[adevs[i]->port].command & GRUB_AHCI_HBA_PORT_CMD_FR)) - break; - if (i == nports) - break; - } - - for (i = 0; i < nports; i++) - if (adevs[i] && !(adevs[i]->hba->ports[adevs[i]->port].command & GRUB_AHCI_HBA_PORT_CMD_FR)) - { - grub_dprintf ("ahci", "couldn't start FR on port %d\n", i); - failed_adevs[i] = adevs[i]; - adevs[i] = 0; - } - - for (i = 0; i < nports; i++) - if (adevs[i]) - { - grub_dprintf ("ahci", "port: %d, err: %x\n", adevs[i]->port, - adevs[i]->hba->ports[adevs[i]->port].sata_error); - fr_running |= (1 << i); - - adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_SPIN_UP; - adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_POWER_ON; - adevs[i]->hba->ports[adevs[i]->port].command |= 1 << 28; - - grub_dprintf ("ahci", "port: %d, err: %x\n", adevs[i]->port, - adevs[i]->hba->ports[adevs[i]->port].sata_error); - } - - /* 10ms should actually be enough. */ - endtime = grub_get_time_ms () + 100; - - while (grub_get_time_ms () < endtime) - { - for (i = 0; i < nports; i++) - if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].status & 7) != 3) - break; - if (i == nports) - break; - } - - for (i = 0; i < nports; i++) - if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].status & 7) != 3) - { - grub_dprintf ("ahci", "couldn't detect device on port %d\n", i); - failed_adevs[i] = adevs[i]; - adevs[i] = 0; - } - - for (i = 0; i < nports; i++) - if (adevs[i]) - { - grub_dprintf ("ahci", "port %d, err: %x\n", adevs[i]->port, - adevs[i]->hba->ports[adevs[i]->port].sata_error); - - adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_POWER_ON; - adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_SPIN_UP; - - grub_dprintf ("ahci", "port %d, err: %x\n", adevs[i]->port, - adevs[i]->hba->ports[adevs[i]->port].sata_error); - - adevs[i]->hba->ports[adevs[i]->port].sata_error = ~0; - grub_dprintf ("ahci", "port %d, err: %x\n", adevs[i]->port, - adevs[i]->hba->ports[adevs[i]->port].sata_error); - - grub_dprintf ("ahci", "port %d, offset: %x, tfd:%x, CMD: %x\n", adevs[i]->port, - (int) ((char *) &adevs[i]->hba->ports[adevs[i]->port].task_file_data - - (char *) adevs[i]->hba), - adevs[i]->hba->ports[adevs[i]->port].task_file_data, - adevs[i]->hba->ports[adevs[i]->port].command); - - grub_dprintf ("ahci", "port %d, err: %x\n", adevs[i]->port, - adevs[i]->hba->ports[adevs[i]->port].sata_error); - } - - - for (i = 0; i < nports; i++) - if (adevs[i]) - { - grub_dprintf ("ahci", "port %d, offset: %x, tfd:%x, CMD: %x\n", adevs[i]->port, - (int) ((char *) &adevs[i]->hba->ports[adevs[i]->port].task_file_data - - (char *) adevs[i]->hba), - adevs[i]->hba->ports[adevs[i]->port].task_file_data, - adevs[i]->hba->ports[adevs[i]->port].command); - - grub_dprintf ("ahci", "port: %d, err: %x\n", adevs[i]->port, - adevs[i]->hba->ports[adevs[i]->port].sata_error); - - adevs[i]->hba->ports[adevs[i]->port].command - = (adevs[i]->hba->ports[adevs[i]->port].command & 0x0fffffff) | (1 << 28) - | GRUB_AHCI_HBA_PORT_CMD_SPIN_UP - | GRUB_AHCI_HBA_PORT_CMD_POWER_ON; - - /* struct grub_disk_ata_pass_through_parms parms2; - grub_memset (&parms2, 0, sizeof (parms2)); - parms2.taskfile.cmd = 8; - grub_ahci_readwrite_real (dev, &parms2, 1);*/ - } - - endtime = grub_get_time_ms () + 32000; - - while (grub_get_time_ms () < endtime) - { - for (i = 0; i < nports; i++) - if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].task_file_data & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ))) - break; - if (i == nports) - break; - } - - for (i = 0; i < nports; i++) - if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].task_file_data & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ))) - { - grub_dprintf ("ahci", "port %d is busy\n", i); - failed_adevs[i] = adevs[i]; - adevs[i] = 0; - } - - for (i = 0; i < nports; i++) - if (adevs[i]) - adevs[i]->hba->ports[adevs[i]->port].command |= GRUB_AHCI_HBA_PORT_CMD_ST; - - endtime = grub_get_time_ms () + 1000; - - while (grub_get_time_ms () < endtime) - { - for (i = 0; i < nports; i++) - if (adevs[i] && !(adevs[i]->hba->ports[adevs[i]->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)) - break; - if (i == nports) - break; - } - - for (i = 0; i < nports; i++) - if (adevs[i] && !(adevs[i]->hba->ports[adevs[i]->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)) - { - grub_dprintf ("ahci", "couldn't start CR on port %d\n", i); - failed_adevs[i] = adevs[i]; - adevs[i] = 0; - } - - grub_dprintf ("ahci", "cleaning up failed devs\n"); - - for (i = 0; i < nports; i++) - if (failed_adevs[i] && (fr_running & (1 << i))) - failed_adevs[i]->hba->ports[failed_adevs[i]->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_FRE; - - endtime = grub_get_time_ms () + 1000; - while (grub_get_time_ms () < endtime) - { - for (i = 0; i < nports; i++) - if (failed_adevs[i] && (fr_running & (1 << i)) && (failed_adevs[i]->hba->ports[failed_adevs[i]->port].command & GRUB_AHCI_HBA_PORT_CMD_FR)) - break; - if (i == nports) - break; - } - for (i = 0; i < nports; i++) - if (failed_adevs[i]) - { - grub_dma_free (failed_adevs[i]->command_list_chunk); - grub_dma_free (failed_adevs[i]->command_table_chunk); - grub_dma_free (failed_adevs[i]->rfis); - } - - for (i = 0; i < nports; i++) - if (adevs[i] && (adevs[i]->hba->ports[adevs[i]->port].sig >> 16) == 0xeb14) - adevs[i]->atapi = 1; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write_word (addr, grub_pci_read_word (addr) - | GRUB_PCI_COMMAND_BUS_MASTER); - - for (i = 0; i < nports; i++) - if (adevs[i]) - { - grub_list_push (GRUB_AS_LIST_P (&grub_ahci_devices), - GRUB_AS_LIST (adevs[i])); - } - - return 0; -} - -static grub_err_t -grub_ahci_initialize (void) -{ - grub_pci_iterate (grub_ahci_pciinit, NULL); - return grub_errno; -} - -static grub_err_t -grub_ahci_fini_hw (int noreturn __attribute__ ((unused))) -{ - struct grub_ahci_device *dev; - - for (dev = grub_ahci_devices; dev; dev = dev->next) - { - grub_uint64_t endtime; - - dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_FRE; - endtime = grub_get_time_ms () + 1000; - while ((dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_FR)) - if (grub_get_time_ms () > endtime) - { - grub_dprintf ("ahci", "couldn't stop FR\n"); - break; - } - - dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_ST; - endtime = grub_get_time_ms () + 1000; - while ((dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)) - if (grub_get_time_ms () > endtime) - { - grub_dprintf ("ahci", "couldn't stop CR\n"); - break; - } - grub_dma_free (dev->command_list_chunk); - grub_dma_free (dev->command_table_chunk); - grub_dma_free (dev->rfis); - dev->command_list_chunk = NULL; - dev->command_table_chunk = NULL; - dev->rfis = NULL; - } - return GRUB_ERR_NONE; -} - -static int -reinit_port (struct grub_ahci_device *dev) -{ - struct grub_pci_dma_chunk *command_list; - struct grub_pci_dma_chunk *command_table; - grub_uint64_t endtime; - - command_list = grub_memalign_dma32 (1024, sizeof (struct grub_ahci_cmd_head)); - if (!command_list) - return 1; - - command_table = grub_memalign_dma32 (1024, - sizeof (struct grub_ahci_cmd_table)); - if (!command_table) - { - grub_dma_free (command_list); - return 1; - } - - grub_dprintf ("ahci", "found device ahci%d (port %d)\n", dev->num, dev->port); - - dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_FRE; - endtime = grub_get_time_ms () + 1000; - while ((dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_FR)) - if (grub_get_time_ms () > endtime) - { - grub_dprintf ("ahci", "couldn't stop FR\n"); - goto out; - } - - dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_ST; - endtime = grub_get_time_ms () + 1000; - while ((dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)) - if (grub_get_time_ms () > endtime) - { - grub_dprintf ("ahci", "couldn't stop CR\n"); - goto out; - } - - dev->hba->ports[dev->port].fbs = 2; - - dev->rfis = grub_memalign_dma32 (4096, - sizeof (struct grub_ahci_received_fis)); - grub_memset ((char *) grub_dma_get_virt (dev->rfis), 0, - sizeof (struct grub_ahci_received_fis)); - dev->hba->ports[dev->port].fis_base = grub_dma_get_phys (dev->rfis); - dev->hba->ports[dev->port].command_list_base - = grub_dma_get_phys (command_list); - dev->hba->ports[dev->port].command |= GRUB_AHCI_HBA_PORT_CMD_FRE; - while (!(dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_FR)) - if (grub_get_time_ms () > endtime) - { - grub_dprintf ("ahci", "couldn't start FR\n"); - dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_FRE; - goto out; - } - dev->hba->ports[dev->port].command |= GRUB_AHCI_HBA_PORT_CMD_ST; - while (!(dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)) - if (grub_get_time_ms () > endtime) - { - grub_dprintf ("ahci", "couldn't start CR\n"); - dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_CR; - goto out_stop_fr; - } - - dev->hba->ports[dev->port].command - = (dev->hba->ports[dev->port].command & 0x0fffffff) | (1 << 28) | 2 | 4; - - dev->command_list_chunk = command_list; - dev->command_list = grub_dma_get_virt (command_list); - dev->command_table_chunk = command_table; - dev->command_table = grub_dma_get_virt (command_table); - dev->command_list->command_table_base - = grub_dma_get_phys (command_table); - - return 0; - out_stop_fr: - dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_FRE; - endtime = grub_get_time_ms () + 1000; - while ((dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_FR)) - if (grub_get_time_ms () > endtime) - { - grub_dprintf ("ahci", "couldn't stop FR\n"); - break; - } - out: - grub_dma_free (command_list); - grub_dma_free (command_table); - grub_dma_free (dev->rfis); - return 1; -} - -static grub_err_t -grub_ahci_restore_hw (void) -{ - struct grub_ahci_device **pdev; - - for (pdev = &grub_ahci_devices; *pdev; pdev = &((*pdev)->next)) - if (reinit_port (*pdev)) - { - struct grub_ahci_device *odev; - odev = *pdev; - *pdev = (*pdev)->next; - grub_free (odev); - } - return GRUB_ERR_NONE; -} - - - - -static int -grub_ahci_iterate (grub_ata_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - struct grub_ahci_device *dev; - - if (pull != GRUB_DISK_PULL_NONE) - return 0; - - FOR_LIST_ELEMENTS(dev, grub_ahci_devices) - if (hook (GRUB_SCSI_SUBSYSTEM_AHCI, dev->num, hook_data)) - return 1; - - return 0; -} - -#if 0 -static int -find_free_cmd_slot (struct grub_ahci_device *dev) -{ - int i; - for (i = 0; i < 32; i++) - { - if (dev->hda->ports[dev->port].command_issue & (1 << i)) - continue; - if (dev->hda->ports[dev->port].sata_active & (1 << i)) - continue; - return i; - } - return -1; -} -#endif - -enum - { - GRUB_AHCI_FIS_REG_H2D = 0x27 - }; - -static const int register_map[11] = { 3 /* Features */, - 12 /* Sectors */, - 4 /* LBA low */, - 5 /* LBA mid */, - 6 /* LBA high */, - 7 /* Device */, - 2 /* CMD register */, - 13 /* Sectors 48 */, - 8 /* LBA48 low */, - 9 /* LBA48 mid */, - 10 /* LBA48 high */ }; - -static grub_err_t -grub_ahci_reset_port (struct grub_ahci_device *dev, int force) -{ - grub_uint64_t endtime; - - dev->hba->ports[dev->port].sata_error = dev->hba->ports[dev->port].sata_error; - - if (force || (dev->hba->ports[dev->port].command_issue & 1) - || (dev->hba->ports[dev->port].task_file_data & 0x80)) - { - struct grub_disk_ata_pass_through_parms parms2; - dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_ST; - dev->hba->ports[dev->port].command_issue = 0; - dev->command_list[0].config = 0; - dev->command_table[0].prdt[0].unused = 0; - dev->command_table[0].prdt[0].size = 0; - dev->command_table[0].prdt[0].data_base = 0; - - endtime = grub_get_time_ms () + 1000; - while ((dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)) - if (grub_get_time_ms () > endtime) - { - grub_dprintf ("ahci", "couldn't stop CR"); - return grub_error (GRUB_ERR_IO, "couldn't stop CR"); - } - dev->hba->ports[dev->port].command |= 8; - while (dev->hba->ports[dev->port].command & 8) - if (grub_get_time_ms () > endtime) - { - grub_dprintf ("ahci", "couldn't set CLO\n"); - dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_FRE; - return grub_error (GRUB_ERR_IO, "couldn't set CLO"); - } - - dev->hba->ports[dev->port].command |= GRUB_AHCI_HBA_PORT_CMD_ST; - while (!(dev->hba->ports[dev->port].command & GRUB_AHCI_HBA_PORT_CMD_CR)) - if (grub_get_time_ms () > endtime) - { - grub_dprintf ("ahci", "couldn't stop CR"); - dev->hba->ports[dev->port].command &= ~GRUB_AHCI_HBA_PORT_CMD_ST; - return grub_error (GRUB_ERR_IO, "couldn't stop CR"); - } - dev->hba->ports[dev->port].sata_error = dev->hba->ports[dev->port].sata_error; - grub_memset (&parms2, 0, sizeof (parms2)); - parms2.taskfile.cmd = 8; - return grub_ahci_readwrite_real (dev, &parms2, 1); - } - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_ahci_readwrite_real (struct grub_ahci_device *dev, - struct grub_disk_ata_pass_through_parms *parms, int reset) -{ - struct grub_pci_dma_chunk *bufc; - grub_uint64_t endtime; - unsigned i; - grub_err_t err = GRUB_ERR_NONE; - - grub_dprintf ("ahci", "AHCI tfd = %x\n", - dev->hba->ports[dev->port].task_file_data); - - if (!reset) - grub_ahci_reset_port (dev, 0); - - grub_dprintf ("ahci", "AHCI tfd = %x\n", - dev->hba->ports[dev->port].task_file_data); - dev->hba->ports[dev->port].task_file_data = 0; - dev->hba->ports[dev->port].command_issue = 0; - grub_dprintf ("ahci", "AHCI tfd = %x\n", - dev->hba->ports[dev->port].task_file_data); - - dev->hba->ports[dev->port].sata_error = dev->hba->ports[dev->port].sata_error; - - grub_dprintf("ahci", "grub_ahci_read (size=%llu, cmdsize = %llu)\n", - (unsigned long long) parms->size, - (unsigned long long) parms->cmdsize); - - if (parms->cmdsize != 0 && parms->cmdsize != 12 && parms->cmdsize != 16) - return grub_error (GRUB_ERR_BUG, "incorrect ATAPI command size"); - - if (parms->size > GRUB_AHCI_PRDT_MAX_CHUNK_LENGTH) - return grub_error (GRUB_ERR_BUG, "too big data buffer"); - - if (parms->size) - bufc = grub_memalign_dma32 (1024, parms->size + (parms->size & 1)); - else - bufc = grub_memalign_dma32 (1024, 512); - - grub_dprintf ("ahci", "AHCI tfd = %x, CL=%p\n", - dev->hba->ports[dev->port].task_file_data, - dev->command_list); - /* FIXME: support port multipliers. */ - dev->command_list[0].config - = (5 << GRUB_AHCI_CONFIG_CFIS_LENGTH_SHIFT) - // | GRUB_AHCI_CONFIG_CLEAR_R_OK - | (0 << GRUB_AHCI_CONFIG_PMP_SHIFT) - | ((parms->size ? 1 : 0) << GRUB_AHCI_CONFIG_PRDT_LENGTH_SHIFT) - | (parms->cmdsize ? GRUB_AHCI_CONFIG_ATAPI : 0) - | (parms->write ? GRUB_AHCI_CONFIG_WRITE : GRUB_AHCI_CONFIG_READ) - | (parms->taskfile.cmd == 8 ? (1 << 8) : 0); - grub_dprintf ("ahci", "AHCI tfd = %x\n", - dev->hba->ports[dev->port].task_file_data); - - dev->command_list[0].transferred = 0; - dev->command_list[0].command_table_base - = grub_dma_get_phys (dev->command_table_chunk); - - grub_memset ((char *) dev->command_list[0].unused, 0, - sizeof (dev->command_list[0].unused)); - - grub_memset ((char *) &dev->command_table[0], 0, - sizeof (dev->command_table[0])); - grub_dprintf ("ahci", "AHCI tfd = %x\n", - dev->hba->ports[dev->port].task_file_data); - - if (parms->cmdsize) - grub_memcpy ((char *) dev->command_table[0].command, parms->cmd, - parms->cmdsize); - - grub_dprintf ("ahci", "AHCI tfd = %x\n", - dev->hba->ports[dev->port].task_file_data); - - dev->command_table[0].cfis[0] = GRUB_AHCI_FIS_REG_H2D; - dev->command_table[0].cfis[1] = 0x80; - for (i = 0; i < sizeof (parms->taskfile.raw); i++) - dev->command_table[0].cfis[register_map[i]] = parms->taskfile.raw[i]; - - grub_dprintf ("ahci", "cfis: %02x %02x %02x %02x %02x %02x %02x %02x\n", - dev->command_table[0].cfis[0], dev->command_table[0].cfis[1], - dev->command_table[0].cfis[2], dev->command_table[0].cfis[3], - dev->command_table[0].cfis[4], dev->command_table[0].cfis[5], - dev->command_table[0].cfis[6], dev->command_table[0].cfis[7]); - grub_dprintf ("ahci", "cfis: %02x %02x %02x %02x %02x %02x %02x %02x\n", - dev->command_table[0].cfis[8], dev->command_table[0].cfis[9], - dev->command_table[0].cfis[10], dev->command_table[0].cfis[11], - dev->command_table[0].cfis[12], dev->command_table[0].cfis[13], - dev->command_table[0].cfis[14], dev->command_table[0].cfis[15]); - - dev->command_table[0].prdt[0].data_base = grub_dma_get_phys (bufc); - dev->command_table[0].prdt[0].unused = 0; - dev->command_table[0].prdt[0].size = (parms->size - 1); - - grub_dprintf ("ahci", "PRDT = %" PRIxGRUB_UINT64_T ", %x, %x (%" - PRIuGRUB_SIZE ")\n", - dev->command_table[0].prdt[0].data_base, - dev->command_table[0].prdt[0].unused, - dev->command_table[0].prdt[0].size, - (grub_size_t) ((char *) &dev->command_table[0].prdt[0] - - (char *) &dev->command_table[0])); - - if (parms->write) - grub_memcpy ((char *) grub_dma_get_virt (bufc), parms->buffer, parms->size); - - grub_dprintf ("ahci", "AHCI command scheduled\n"); - grub_dprintf ("ahci", "AHCI tfd = %x\n", - dev->hba->ports[dev->port].task_file_data); - grub_dprintf ("ahci", "AHCI inten = %x\n", - dev->hba->ports[dev->port].inten); - grub_dprintf ("ahci", "AHCI intstatus = %x\n", - dev->hba->ports[dev->port].intstatus); - - dev->hba->ports[dev->port].inten = 0xffffffff;//(1 << 2) | (1 << 5); - dev->hba->ports[dev->port].intstatus = 0xffffffff;//(1 << 2) | (1 << 5); - grub_dprintf ("ahci", "AHCI inten = %x\n", - dev->hba->ports[dev->port].inten); - grub_dprintf ("ahci", "AHCI tfd = %x\n", - dev->hba->ports[dev->port].task_file_data); - dev->hba->ports[dev->port].sata_active = 1; - dev->hba->ports[dev->port].command_issue = 1; - grub_dprintf ("ahci", "AHCI sig = %x\n", dev->hba->ports[dev->port].sig); - grub_dprintf ("ahci", "AHCI tfd = %x\n", - dev->hba->ports[dev->port].task_file_data); - - endtime = grub_get_time_ms () + 20000; - while ((dev->hba->ports[dev->port].command_issue & 1)) - if (grub_get_time_ms () > endtime || - (dev->hba->ports[dev->port].intstatus & GRUB_AHCI_HBA_PORT_IS_FATAL_MASK)) - { - grub_dprintf ("ahci", "AHCI status <%x %x %x %x>\n", - dev->hba->ports[dev->port].command_issue, - dev->hba->ports[dev->port].sata_active, - dev->hba->ports[dev->port].intstatus, - dev->hba->ports[dev->port].task_file_data); - dev->hba->ports[dev->port].command_issue = 0; - if (dev->hba->ports[dev->port].intstatus & GRUB_AHCI_HBA_PORT_IS_FATAL_MASK) - err = grub_error (GRUB_ERR_IO, "AHCI transfer error"); - else - err = grub_error (GRUB_ERR_IO, "AHCI transfer timed out"); - if (!reset) - grub_ahci_reset_port (dev, 1); - break; - } - - grub_dprintf ("ahci", "AHCI command completed <%x %x %x %x %x, %x %x>\n", - dev->hba->ports[dev->port].command_issue, - dev->hba->ports[dev->port].intstatus, - dev->hba->ports[dev->port].task_file_data, - dev->command_list[0].transferred, - dev->hba->ports[dev->port].sata_error, - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x00], - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x18]); - grub_dprintf ("ahci", - "last PIO FIS %08x %08x %08x %08x %08x %08x %08x %08x\n", - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x08], - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x09], - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x0a], - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x0b], - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x0c], - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x0d], - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x0e], - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x0f]); - grub_dprintf ("ahci", - "last REG FIS %08x %08x %08x %08x %08x %08x %08x %08x\n", - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x10], - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x11], - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x12], - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x13], - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x14], - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x15], - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x16], - ((grub_uint32_t *) grub_dma_get_virt (dev->rfis))[0x17]); - - if (!parms->write) - grub_memcpy (parms->buffer, (char *) grub_dma_get_virt (bufc), parms->size); - grub_dma_free (bufc); - - return err; -} - -static grub_err_t -grub_ahci_readwrite (grub_ata_t disk, - struct grub_disk_ata_pass_through_parms *parms, - int spinup __attribute__((__unused__))) -{ - return grub_ahci_readwrite_real (disk->data, parms, 0); -} - -static grub_err_t -grub_ahci_open (int id, int devnum, struct grub_ata *ata) -{ - struct grub_ahci_device *dev; - - if (id != GRUB_SCSI_SUBSYSTEM_AHCI) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an AHCI device"); - - FOR_LIST_ELEMENTS(dev, grub_ahci_devices) - if (dev->num == devnum) - break; - - if (! dev) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such AHCI device"); - - grub_dprintf ("ahci", "opening AHCI dev `ahci%d'\n", dev->num); - - ata->data = dev; - ata->dma = 1; - ata->atapi = dev->atapi; - ata->maxbuffer = GRUB_AHCI_PRDT_MAX_CHUNK_LENGTH; - ata->present = &dev->present; - - return GRUB_ERR_NONE; -} - -static struct grub_ata_dev grub_ahci_dev = - { - .iterate = grub_ahci_iterate, - .open = grub_ahci_open, - .readwrite = grub_ahci_readwrite, - }; - - - -static struct grub_preboot *fini_hnd; - -GRUB_MOD_INIT(ahci) -{ - grub_stop_disk_firmware (); - - /* AHCI initialization. */ - grub_ahci_initialize (); - - /* AHCI devices are handled by scsi.mod. */ - grub_ata_dev_register (&grub_ahci_dev); - - fini_hnd = grub_loader_register_preboot_hook (grub_ahci_fini_hw, - grub_ahci_restore_hw, - GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); -} - -GRUB_MOD_FINI(ahci) -{ - grub_ahci_fini_hw (0); - grub_loader_unregister_preboot_hook (fini_hnd); - - grub_ata_dev_unregister (&grub_ahci_dev); -} diff --git a/grub-core/disk/arc/arcdisk.c b/grub-core/disk/arc/arcdisk.c deleted file mode 100644 index c94039a3d..000000000 --- a/grub-core/disk/arc/arcdisk.c +++ /dev/null @@ -1,325 +0,0 @@ -/* ofdisk.c - Open Firmware disk access. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2004,2006,2007,2008,2009,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include - -static grub_arc_fileno_t last_handle = 0; -static char *last_path = NULL; -static int handle_writable = 0; - -static int lnum = 0; - -struct arcdisk_hash_ent -{ - char *devpath; - int num; - struct arcdisk_hash_ent *next; -}; - -#define ARCDISK_HASH_SZ 8 -static struct arcdisk_hash_ent *arcdisk_hash[ARCDISK_HASH_SZ]; - -static int -arcdisk_hash_fn (const char *devpath) -{ - int hash = 0; - while (*devpath) - hash ^= *devpath++; - return (hash & (ARCDISK_HASH_SZ - 1)); -} - -static struct arcdisk_hash_ent * -arcdisk_hash_find (const char *devpath) -{ - struct arcdisk_hash_ent *p = arcdisk_hash[arcdisk_hash_fn (devpath)]; - - while (p) - { - if (!grub_strcmp (p->devpath, devpath)) - break; - p = p->next; - } - return p; -} - -static struct arcdisk_hash_ent * -arcdisk_hash_add (char *devpath) -{ - struct arcdisk_hash_ent *p; - struct arcdisk_hash_ent **head = &arcdisk_hash[arcdisk_hash_fn(devpath)]; - - p = grub_malloc (sizeof (*p)); - if (!p) - return NULL; - - p->devpath = devpath; - p->next = *head; - p->num = lnum++; - *head = p; - return p; -} - - -/* Context for grub_arcdisk_iterate. */ -struct grub_arcdisk_iterate_ctx -{ - grub_disk_dev_iterate_hook_t hook; - void *hook_data; -}; - -/* Helper for grub_arcdisk_iterate. */ -static int -grub_arcdisk_iterate_iter (const char *name, - const struct grub_arc_component *comp, void *data) -{ - struct grub_arcdisk_iterate_ctx *ctx = data; - - if (!(comp->type == GRUB_ARC_COMPONENT_TYPE_DISK - || comp->type == GRUB_ARC_COMPONENT_TYPE_FLOPPY - || comp->type == GRUB_ARC_COMPONENT_TYPE_TAPE)) - return 0; - return ctx->hook (name, ctx->hook_data); -} - -static int -grub_arcdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - struct grub_arcdisk_iterate_ctx ctx = { hook, hook_data }; - - if (pull != GRUB_DISK_PULL_NONE) - return 0; - - return grub_arc_iterate_devs (grub_arcdisk_iterate_iter, &ctx, 1); -} - -#ifdef GRUB_CPU_MIPSEL -#define RAW_SUFFIX "partition(0)" -#else -#define RAW_SUFFIX "partition(10)" -#endif - -static grub_err_t -reopen (const char *name, int writable) -{ - grub_arc_fileno_t handle; - - if (last_path && grub_strcmp (last_path, name) == 0 - && (!writable || handle_writable)) - { - grub_dprintf ("arcdisk", "using already opened %s\n", name); - return GRUB_ERR_NONE; - } - if (last_path) - { - GRUB_ARC_FIRMWARE_VECTOR->close (last_handle); - grub_free (last_path); - last_path = NULL; - last_handle = 0; - handle_writable = 0; - } - if (GRUB_ARC_FIRMWARE_VECTOR->open (name, - writable ? GRUB_ARC_FILE_ACCESS_OPEN_RW - : GRUB_ARC_FILE_ACCESS_OPEN_RO, &handle)) - { - grub_dprintf ("arcdisk", "couldn't open %s\n", name); - return grub_error (GRUB_ERR_IO, "couldn't open %s", name); - } - handle_writable = writable; - last_path = grub_strdup (name); - if (!last_path) - return grub_errno; - last_handle = handle; - grub_dprintf ("arcdisk", "opened %s\n", name); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_arcdisk_open (const char *name, grub_disk_t disk) -{ - char *fullname; - grub_err_t err; - grub_arc_err_t r; - struct grub_arc_fileinfo info; - struct arcdisk_hash_ent *hash; - - if (grub_memcmp (name, "arc/", 4) != 0) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not arc device"); - fullname = grub_arc_alt_name_to_norm (name, RAW_SUFFIX); - disk->data = fullname; - grub_dprintf ("arcdisk", "opening %s\n", fullname); - - hash = arcdisk_hash_find (fullname); - if (!hash) - hash = arcdisk_hash_add (fullname); - if (!hash) - return grub_errno; - - err = reopen (fullname, 0); - if (err) - return err; - - r = GRUB_ARC_FIRMWARE_VECTOR->getfileinformation (last_handle, &info); - if (r) - { - grub_uint64_t res = 0; - int i; - - grub_dprintf ("arcdisk", "couldn't retrieve size: %ld\n", r); - for (i = 40; i >= 9; i--) - { - grub_uint64_t pos = res | (1ULL << i); - char buf[512]; - long unsigned count = 0; - grub_dprintf ("arcdisk", - "seek to 0x%" PRIxGRUB_UINT64_T "\n", pos); - if (GRUB_ARC_FIRMWARE_VECTOR->seek (last_handle, &pos, 0)) - continue; - if (GRUB_ARC_FIRMWARE_VECTOR->read (last_handle, buf, - 0x200, &count)) - continue; - if (count == 0) - continue; - res |= (1ULL << i); - } - grub_dprintf ("arcdisk", - "determined disk size 0x%" PRIxGRUB_UINT64_T "\n", res); - disk->total_sectors = (res + 0x200) >> 9; - } - else - disk->total_sectors = (info.end >> 9); - - disk->id = hash->num; - return GRUB_ERR_NONE; -} - -static void -grub_arcdisk_close (grub_disk_t disk) -{ - grub_free (disk->data); -} - -static grub_err_t -grub_arcdisk_read (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, char *buf) -{ - grub_err_t err; - grub_uint64_t pos = sector << 9; - unsigned long count; - grub_uint64_t totl = size << 9; - grub_arc_err_t r; - - err = reopen (disk->data, 0); - if (err) - return err; - r = GRUB_ARC_FIRMWARE_VECTOR->seek (last_handle, &pos, 0); - if (r) - { - grub_dprintf ("arcdisk", "seek to 0x%" PRIxGRUB_UINT64_T " failed: %ld\n", - pos, r); - return grub_error (GRUB_ERR_IO, "couldn't seek"); - } - - while (totl) - { - if (GRUB_ARC_FIRMWARE_VECTOR->read (last_handle, buf, - totl, &count)) - return grub_error (GRUB_ERR_READ_ERROR, - N_("failure reading sector 0x%llx " - "from `%s'"), - (unsigned long long) sector, - disk->name); - totl -= count; - buf += count; - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_arcdisk_write (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, const char *buf) -{ - grub_err_t err; - grub_uint64_t pos = sector << 9; - unsigned long count; - grub_uint64_t totl = size << 9; - grub_arc_err_t r; - - err = reopen (disk->data, 1); - if (err) - return err; - r = GRUB_ARC_FIRMWARE_VECTOR->seek (last_handle, &pos, 0); - if (r) - { - grub_dprintf ("arcdisk", "seek to 0x%" PRIxGRUB_UINT64_T " failed: %ld\n", - pos, r); - return grub_error (GRUB_ERR_IO, "couldn't seek"); - } - - while (totl) - { - if (GRUB_ARC_FIRMWARE_VECTOR->write (last_handle, buf, - totl, &count)) - return grub_error (GRUB_ERR_WRITE_ERROR, N_("failure writing sector 0x%llx " - "to `%s'"), - (unsigned long long) sector, - disk->name); - totl -= count; - buf += count; - } - - return GRUB_ERR_NONE; -} - -static struct grub_disk_dev grub_arcdisk_dev = - { - .name = "arcdisk", - .id = GRUB_DISK_DEVICE_ARCDISK_ID, - .disk_iterate = grub_arcdisk_iterate, - .disk_open = grub_arcdisk_open, - .disk_close = grub_arcdisk_close, - .disk_read = grub_arcdisk_read, - .disk_write = grub_arcdisk_write, - .next = 0 - }; - -void -grub_arcdisk_init (void) -{ - grub_disk_dev_register (&grub_arcdisk_dev); -} - -void -grub_arcdisk_fini (void) -{ - if (last_path) - { - GRUB_ARC_FIRMWARE_VECTOR->close (last_handle); - grub_free (last_path); - last_path = NULL; - last_handle = 0; - } - - grub_disk_dev_unregister (&grub_arcdisk_dev); -} diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c deleted file mode 100644 index a2433e29e..000000000 --- a/grub-core/disk/ata.c +++ /dev/null @@ -1,682 +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 . - */ - -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_ata_dev_t grub_ata_dev_list; - -/* Byteorder has to be changed before strings can be read. */ -static void -grub_ata_strncpy (grub_uint16_t *dst16, grub_uint16_t *src16, grub_size_t len) -{ - unsigned int i; - - for (i = 0; i < len / 2; i++) - *(dst16++) = grub_swap_bytes16 (*(src16++)); - *dst16 = 0; -} - -static void -grub_ata_dumpinfo (struct grub_ata *dev, grub_uint16_t *info) -{ - grub_uint16_t text[21]; - - /* The device information was read, dump it for debugging. */ - grub_ata_strncpy (text, info + 10, 20); - grub_dprintf ("ata", "Serial: %s\n", (char *) text); - grub_ata_strncpy (text, info + 23, 8); - grub_dprintf ("ata", "Firmware: %s\n", (char *) text); - grub_ata_strncpy (text, info + 27, 40); - grub_dprintf ("ata", "Model: %s\n", (char *) text); - - if (! dev->atapi) - { - grub_dprintf ("ata", "Addressing: %d\n", dev->addr); - grub_dprintf ("ata", "Sectors: %lld\n", (unsigned long long) dev->size); - grub_dprintf ("ata", "Sector size: %u\n", 1U << dev->log_sector_size); - } -} - -static grub_err_t -grub_atapi_identify (struct grub_ata *dev) -{ - struct grub_disk_ata_pass_through_parms parms; - grub_uint16_t *info; - grub_err_t err; - - info = grub_malloc (GRUB_DISK_SECTOR_SIZE); - if (! info) - return grub_errno; - - grub_memset (&parms, 0, sizeof (parms)); - parms.taskfile.disk = 0xE0; - parms.taskfile.cmd = GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE; - parms.size = GRUB_DISK_SECTOR_SIZE; - parms.buffer = info; - - err = dev->dev->readwrite (dev, &parms, *dev->present); - if (err) - { - *dev->present = 0; - return err; - } - - if (parms.size != GRUB_DISK_SECTOR_SIZE) - { - *dev->present = 0; - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "device cannot be identified"); - } - - dev->atapi = 1; - - grub_ata_dumpinfo (dev, info); - - grub_free (info); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_ata_identify (struct grub_ata *dev) -{ - struct grub_disk_ata_pass_through_parms parms; - grub_uint64_t *info64; - grub_uint32_t *info32; - grub_uint16_t *info16; - grub_err_t err; - - if (dev->atapi) - return grub_atapi_identify (dev); - - info64 = grub_malloc (GRUB_DISK_SECTOR_SIZE); - if (info64 == NULL) - return grub_errno; - info32 = (grub_uint32_t *) info64; - info16 = (grub_uint16_t *) info64; - - grub_memset (&parms, 0, sizeof (parms)); - parms.buffer = info16; - parms.size = GRUB_DISK_SECTOR_SIZE; - parms.taskfile.disk = 0xE0; - - parms.taskfile.cmd = GRUB_ATA_CMD_IDENTIFY_DEVICE; - - err = dev->dev->readwrite (dev, &parms, *dev->present); - - if (err || parms.size != GRUB_DISK_SECTOR_SIZE) - { - grub_uint8_t sts = parms.taskfile.status; - grub_free (info16); - grub_errno = GRUB_ERR_NONE; - if ((sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ - | GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_ERR - && (parms.taskfile.error & 0x04 /* ABRT */)) - /* Device without ATA IDENTIFY, try ATAPI. */ - return grub_atapi_identify (dev); - - else if (sts == 0x00) - { - *dev->present = 0; - /* No device, return error but don't print message. */ - return GRUB_ERR_UNKNOWN_DEVICE; - } - else - { - *dev->present = 0; - /* Other Error. */ - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "device cannot be identified"); - } - } - - /* 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] & grub_cpu_to_le16_compile_time ((1 << 9))) - { - /* Check if LBA48 is supported. */ - if (info16[83] & grub_cpu_to_le16_compile_time ((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 (info32[30]); - else - dev->size = grub_le_to_cpu64 (info64[25]); - - if (info16[106] & grub_cpu_to_le16_compile_time ((1 << 12))) - { - grub_uint32_t secsize; - secsize = grub_le_to_cpu32 (grub_get_unaligned32 (&info16[117])); - if (secsize & (secsize - 1) || !secsize - || secsize > 1048576) - secsize = 256; - dev->log_sector_size = grub_log2ull (secsize) + 1; - } - else - dev->log_sector_size = 9; - - /* Read CHS information. */ - dev->cylinders = grub_le_to_cpu16 (info16[1]); - dev->heads = grub_le_to_cpu16 (info16[3]); - dev->sectors_per_track = grub_le_to_cpu16 (info16[6]); - - grub_ata_dumpinfo (dev, info16); - - grub_free (info16); - - return 0; -} - -static grub_err_t -grub_ata_setaddress (struct grub_ata *dev, - struct grub_disk_ata_pass_through_parms *parms, - grub_disk_addr_t sector, - grub_size_t size, - grub_ata_addressing_t addressing) -{ - switch (addressing) - { - case GRUB_ATA_CHS: - { - unsigned int cylinder; - unsigned int head; - unsigned int sect; - - if (dev->sectors_per_track == 0 - || dev->heads == 0) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - "sector %" PRIxGRUB_UINT64_T " cannot be " - "addressed using CHS addressing", - sector); - - /* 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 %" PRIxGRUB_UINT64_T " cannot be " - "addressed using CHS addressing", - sector); - - parms->taskfile.disk = 0xE0 | head; - parms->taskfile.sectnum = sect; - parms->taskfile.cyllsb = cylinder & 0xFF; - parms->taskfile.cylmsb = cylinder >> 8; - - break; - } - - case GRUB_ATA_LBA: - if (size == 256) - size = 0; - parms->taskfile.disk = 0xE0 | ((sector >> 24) & 0x0F); - - parms->taskfile.sectors = size; - parms->taskfile.lba_low = sector & 0xFF; - parms->taskfile.lba_mid = (sector >> 8) & 0xFF; - parms->taskfile.lba_high = (sector >> 16) & 0xFF; - break; - - case GRUB_ATA_LBA48: - if (size == 65536) - size = 0; - - parms->taskfile.disk = 0xE0; - - /* Set "Previous". */ - parms->taskfile.sectors = size & 0xFF; - parms->taskfile.lba_low = sector & 0xFF; - parms->taskfile.lba_mid = (sector >> 8) & 0xFF; - parms->taskfile.lba_high = (sector >> 16) & 0xFF; - - /* Set "Current". */ - parms->taskfile.sectors48 = (size >> 8) & 0xFF; - parms->taskfile.lba48_low = (sector >> 24) & 0xFF; - parms->taskfile.lba48_mid = (sector >> 32) & 0xFF; - parms->taskfile.lba48_high = (sector >> 40) & 0xFF; - - 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 *ata = disk->data; - - grub_ata_addressing_t addressing = ata->addr; - grub_size_t batch; - int cmd, cmd_write; - grub_size_t nsectors = 0; - - grub_dprintf("ata", "grub_ata_readwrite (size=%llu, rw=%d)\n", - (unsigned long long) size, rw); - - if (addressing == GRUB_ATA_LBA48 && ((sector + size) >> 28) != 0) - { - if (ata->dma) - { - cmd = GRUB_ATA_CMD_READ_SECTORS_DMA_EXT; - cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_DMA_EXT; - } - else - { - 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; - if (ata->dma) - { - cmd = GRUB_ATA_CMD_READ_SECTORS_DMA; - cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_DMA; - } - else - { - cmd = GRUB_ATA_CMD_READ_SECTORS; - cmd_write = GRUB_ATA_CMD_WRITE_SECTORS; - } - } - - if (addressing != GRUB_ATA_CHS) - batch = 256; - else - batch = 1; - - while (nsectors < size) - { - struct grub_disk_ata_pass_through_parms parms; - grub_err_t err; - - 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); - grub_memset (&parms, 0, sizeof (parms)); - grub_ata_setaddress (ata, &parms, sector, batch, addressing); - parms.taskfile.cmd = (! rw ? cmd : cmd_write); - parms.buffer = buf; - parms.size = batch << ata->log_sector_size; - parms.write = rw; - if (ata->dma) - parms.dma = 1; - - err = ata->dev->readwrite (ata, &parms, 0); - if (err) - return err; - if (parms.size != batch << ata->log_sector_size) - return grub_error (GRUB_ERR_READ_ERROR, "incomplete read"); - buf += batch << ata->log_sector_size; - sector += batch; - nsectors += batch; - } - - return GRUB_ERR_NONE; -} - - - -static inline void -grub_ata_real_close (struct grub_ata *ata) -{ - if (ata->dev->close) - ata->dev->close (ata); -} - -static struct grub_ata * -grub_ata_real_open (int id, int bus) -{ - struct grub_ata *ata; - grub_ata_dev_t p; - - ata = grub_zalloc (sizeof (*ata)); - if (!ata) - return NULL; - for (p = grub_ata_dev_list; p; p = p->next) - { - grub_err_t err; - if (p->open (id, bus, ata)) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - ata->dev = p; - /* Use the IDENTIFY DEVICE command to query the device. */ - err = grub_ata_identify (ata); - if (err) - { - if (!grub_errno) - grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATA device"); - grub_free (ata); - return NULL; - } - return ata; - } - grub_free (ata); - grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATA device"); - return NULL; -} - -/* Context for grub_ata_iterate. */ -struct grub_ata_iterate_ctx -{ - grub_disk_dev_iterate_hook_t hook; - void *hook_data; -}; - -/* Helper for grub_ata_iterate. */ -static int -grub_ata_iterate_iter (int id, int bus, void *data) -{ - struct grub_ata_iterate_ctx *ctx = data; - struct grub_ata *ata; - int ret; - char devname[40]; - - ata = grub_ata_real_open (id, bus); - - if (!ata) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - if (ata->atapi) - { - grub_ata_real_close (ata); - return 0; - } - grub_snprintf (devname, sizeof (devname), - "%s%d", grub_scsi_names[id], bus); - ret = ctx->hook (devname, ctx->hook_data); - grub_ata_real_close (ata); - return ret; -} - -static int -grub_ata_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - struct grub_ata_iterate_ctx ctx = { hook, hook_data }; - grub_ata_dev_t p; - - for (p = grub_ata_dev_list; p; p = p->next) - if (p->iterate && p->iterate (grub_ata_iterate_iter, &ctx, pull)) - return 1; - return 0; -} - -static grub_err_t -grub_ata_open (const char *name, grub_disk_t disk) -{ - unsigned id, bus; - struct grub_ata *ata; - - for (id = 0; id < GRUB_SCSI_NUM_SUBSYSTEMS; id++) - if (grub_strncmp (grub_scsi_names[id], name, - grub_strlen (grub_scsi_names[id])) == 0 - && grub_isdigit (name[grub_strlen (grub_scsi_names[id])])) - break; - if (id == GRUB_SCSI_NUM_SUBSYSTEMS) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk"); - bus = grub_strtoul (name + grub_strlen (grub_scsi_names[id]), 0, 0); - ata = grub_ata_real_open (id, bus); - if (!ata) - return grub_errno; - - if (ata->atapi) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk"); - - disk->total_sectors = ata->size; - disk->max_agglomerate = (ata->maxbuffer >> (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS)); - if (disk->max_agglomerate > (256U >> (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS - ata->log_sector_size))) - disk->max_agglomerate = (256U >> (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS - ata->log_sector_size)); - - disk->log_sector_size = ata->log_sector_size; - - disk->id = grub_make_scsi_id (id, bus, 0); - - disk->data = ata; - - return 0; -} - -static void -grub_ata_close (grub_disk_t disk) -{ - struct grub_ata *ata = disk->data; - grub_ata_real_close (ata); -} - -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, - .disk_iterate = grub_ata_iterate, - .disk_open = grub_ata_open, - .disk_close = grub_ata_close, - .disk_read = grub_ata_read, - .disk_write = grub_ata_write, - .next = 0 - }; - - - -/* ATAPI code. */ - -static grub_err_t -grub_atapi_read (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, - grub_size_t size, char *buf) -{ - struct grub_ata *dev = scsi->data; - struct grub_disk_ata_pass_through_parms parms; - grub_err_t err; - - grub_dprintf("ata", "grub_atapi_read (size=%llu)\n", (unsigned long long) size); - grub_memset (&parms, 0, sizeof (parms)); - - parms.taskfile.disk = 0; - parms.taskfile.features = 0; - parms.taskfile.atapi_ireason = 0; - parms.taskfile.atapi_cnthigh = size >> 8; - parms.taskfile.atapi_cntlow = size & 0xff; - parms.taskfile.cmd = GRUB_ATA_CMD_PACKET; - parms.cmd = cmd; - parms.cmdsize = cmdsize; - - parms.size = size; - parms.buffer = buf; - - err = dev->dev->readwrite (dev, &parms, 0); - if (err) - return err; - - if (parms.size != size) - return grub_error (GRUB_ERR_READ_ERROR, "incomplete ATAPI read"); - 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)), - const 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 (int id, int bus, struct grub_scsi *scsi) -{ - struct grub_ata *ata; - - ata = grub_ata_real_open (id, bus); - if (!ata) - return grub_errno; - - if (! ata->atapi) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device"); - - scsi->data = ata; - scsi->luns = 1; - - return GRUB_ERR_NONE; -} - -/* Context for grub_atapi_iterate. */ -struct grub_atapi_iterate_ctx -{ - grub_scsi_dev_iterate_hook_t hook; - void *hook_data; -}; - -/* Helper for grub_atapi_iterate. */ -static int -grub_atapi_iterate_iter (int id, int bus, void *data) -{ - struct grub_atapi_iterate_ctx *ctx = data; - struct grub_ata *ata; - int ret; - - ata = grub_ata_real_open (id, bus); - - if (!ata) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - if (!ata->atapi) - { - grub_ata_real_close (ata); - return 0; - } - ret = ctx->hook (id, bus, 1, ctx->hook_data); - grub_ata_real_close (ata); - return ret; -} - -static int -grub_atapi_iterate (grub_scsi_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - struct grub_atapi_iterate_ctx ctx = { hook, hook_data }; - grub_ata_dev_t p; - - for (p = grub_ata_dev_list; p; p = p->next) - if (p->iterate && p->iterate (grub_atapi_iterate_iter, &ctx, pull)) - return 1; - return 0; -} - -static void -grub_atapi_close (grub_scsi_t disk) -{ - struct grub_ata *ata = disk->data; - grub_ata_real_close (ata); -} - - -void -grub_ata_dev_register (grub_ata_dev_t dev) -{ - dev->next = grub_ata_dev_list; - grub_ata_dev_list = dev; -} - -void -grub_ata_dev_unregister (grub_ata_dev_t dev) -{ - grub_ata_dev_t *p, q; - - for (p = &grub_ata_dev_list, q = *p; q; p = &(q->next), q = q->next) - if (q == dev) - { - *p = q->next; - break; - } -} - -static struct grub_scsi_dev grub_atapi_dev = - { - .iterate = grub_atapi_iterate, - .open = grub_atapi_open, - .close = grub_atapi_close, - .read = grub_atapi_read, - .write = grub_atapi_write, - .next = 0 - }; - - - -GRUB_MOD_INIT(ata) -{ - 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/cryptodisk.c b/grub-core/disk/cryptodisk.c deleted file mode 100644 index 7065bcdcb..000000000 --- a/grub-core/disk/cryptodisk.c +++ /dev/null @@ -1,1916 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2007,2010,2011,2019 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef GRUB_UTIL -#include -#endif - -GRUB_MOD_LICENSE ("GPLv3+"); - -grub_cryptodisk_dev_t grub_cryptodisk_list; - -enum - { - OPTION_UUID, - OPTION_ALL, - OPTION_BOOT, - OPTION_PASSWORD, - OPTION_KEYFILE, - OPTION_KEYFILE_OFFSET, - OPTION_KEYFILE_SIZE, - OPTION_HEADER, - OPTION_PROTECTOR - }; - -static const struct grub_arg_option options[] = - { - {"uuid", 'u', 0, N_("Mount by UUID."), 0, 0}, - /* TRANSLATORS: It's still restricted to cryptodisks only. */ - {"all", 'a', 0, N_("Mount all."), 0, 0}, - {"boot", 'b', 0, N_("Mount all volumes with `boot' flag set."), 0, 0}, - {"password", 'p', 0, N_("Password to open volumes."), 0, ARG_TYPE_STRING}, - {"key-file", 'k', 0, N_("Key file"), 0, ARG_TYPE_STRING}, - {"keyfile-offset", 'O', 0, N_("Key file offset (bytes)"), 0, ARG_TYPE_INT}, - {"keyfile-size", 'S', 0, N_("Key file data size (bytes)"), 0, ARG_TYPE_INT}, - {"header", 'H', 0, N_("Read header from file"), 0, ARG_TYPE_STRING}, - {"protector", 'P', GRUB_ARG_OPTION_REPEATABLE, - N_("Unlock volume(s) using key protector(s)."), 0, ARG_TYPE_STRING}, - {0, 0, 0, 0, 0, 0} - }; - -struct cryptodisk_read_hook_ctx -{ - grub_file_t hdr_file; - grub_disk_addr_t part_start; -}; -typedef struct cryptodisk_read_hook_ctx *cryptodisk_read_hook_ctx_t; - -/* Our irreducible polynom is x^128+x^7+x^2+x+1. Lowest byte of it is: */ -#define GF_POLYNOM 0x87 -static inline int GF_PER_SECTOR (const struct grub_cryptodisk *dev) -{ - return 1U << (dev->log_sector_size - GRUB_CRYPTODISK_GF_LOG_BYTES); -} - -static grub_cryptodisk_t cryptodisk_list = NULL; -static grub_uint8_t last_cryptodisk_id = 0; - -static void -gf_mul_x (grub_uint8_t *g) -{ - int over = 0, over2 = 0; - unsigned j; - - for (j = 0; j < GRUB_CRYPTODISK_GF_BYTES; j++) - { - over2 = !!(g[j] & 0x80); - g[j] <<= 1; - g[j] |= over; - over = over2; - } - if (over) - g[0] ^= GF_POLYNOM; -} - - -static void -gf_mul_x_be (grub_uint8_t *g) -{ - int over = 0, over2 = 0; - int j; - - for (j = (int) GRUB_CRYPTODISK_GF_BYTES - 1; j >= 0; j--) - { - over2 = !!(g[j] & 0x80); - g[j] <<= 1; - g[j] |= over; - over = over2; - } - if (over) - g[GRUB_CRYPTODISK_GF_BYTES - 1] ^= GF_POLYNOM; -} - -static void -gf_mul_be (grub_uint8_t *o, const grub_uint8_t *a, const grub_uint8_t *b) -{ - unsigned i; - grub_uint8_t t[GRUB_CRYPTODISK_GF_BYTES]; - grub_memset (o, 0, GRUB_CRYPTODISK_GF_BYTES); - grub_memcpy (t, b, GRUB_CRYPTODISK_GF_BYTES); - for (i = 0; i < GRUB_CRYPTODISK_GF_SIZE; i++) - { - if (((a[GRUB_CRYPTODISK_GF_BYTES - i / GRUB_CHAR_BIT - 1] >> (i % GRUB_CHAR_BIT))) & 1) - grub_crypto_xor (o, o, t, GRUB_CRYPTODISK_GF_BYTES); - gf_mul_x_be (t); - } -} - -static gcry_err_code_t -grub_crypto_pcbc_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[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE]; - grub_size_t blocksize; - if (!cipher->cipher->decrypt) - return GPG_ERR_NOT_SUPPORTED; - blocksize = cipher->cipher->blocksize; - if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0) - || ((size & (blocksize - 1)) != 0)) - return GPG_ERR_INV_ARG; - if (blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE) - return GPG_ERR_INV_ARG; - end = (grub_uint8_t *) in + size; - for (inptr = in, outptr = out; inptr < end; - inptr += blocksize, outptr += blocksize) - { - grub_memcpy (ivt, inptr, blocksize); - cipher->cipher->decrypt (cipher->ctx, outptr, inptr); - grub_crypto_xor (outptr, outptr, iv, blocksize); - grub_crypto_xor (iv, ivt, outptr, blocksize); - } - return GPG_ERR_NO_ERROR; -} - -static gcry_err_code_t -grub_crypto_pcbc_encrypt (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[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE]; - grub_size_t blocksize; - if (!cipher->cipher->encrypt) - return GPG_ERR_NOT_SUPPORTED; - blocksize = cipher->cipher->blocksize; - if (blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE) - return GPG_ERR_INV_ARG; - if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0) - || ((size & (blocksize - 1)) != 0)) - return GPG_ERR_INV_ARG; - end = (grub_uint8_t *) in + size; - for (inptr = in, outptr = out; inptr < end; - inptr += blocksize, outptr += blocksize) - { - grub_memcpy (ivt, inptr, blocksize); - grub_crypto_xor (outptr, outptr, iv, blocksize); - cipher->cipher->encrypt (cipher->ctx, outptr, inptr); - grub_crypto_xor (iv, ivt, outptr, blocksize); - } - return GPG_ERR_NO_ERROR; -} - -struct lrw_sector -{ - grub_uint8_t low[GRUB_CRYPTODISK_GF_BYTES]; - grub_uint8_t high[GRUB_CRYPTODISK_GF_BYTES]; - grub_uint8_t low_byte, low_byte_c; -}; - -static void -generate_lrw_sector (struct lrw_sector *sec, - const struct grub_cryptodisk *dev, - const grub_uint8_t *iv) -{ - grub_uint8_t idx[GRUB_CRYPTODISK_GF_BYTES]; - grub_uint16_t c; - int j; - grub_memcpy (idx, iv, GRUB_CRYPTODISK_GF_BYTES); - sec->low_byte = (idx[GRUB_CRYPTODISK_GF_BYTES - 1] - & (GF_PER_SECTOR (dev) - 1)); - sec->low_byte_c = (((GF_PER_SECTOR (dev) - 1) & ~sec->low_byte) + 1); - idx[GRUB_CRYPTODISK_GF_BYTES - 1] &= ~(GF_PER_SECTOR (dev) - 1); - gf_mul_be (sec->low, dev->lrw_key, idx); - if (!sec->low_byte) - return; - - c = idx[GRUB_CRYPTODISK_GF_BYTES - 1] + GF_PER_SECTOR (dev); - if (c & 0x100) - { - for (j = GRUB_CRYPTODISK_GF_BYTES - 2; j >= 0; j--) - { - idx[j]++; - if (idx[j] != 0) - break; - } - } - idx[GRUB_CRYPTODISK_GF_BYTES - 1] = c; - gf_mul_be (sec->high, dev->lrw_key, idx); -} - -static void __attribute__ ((unused)) -lrw_xor (const struct lrw_sector *sec, - const struct grub_cryptodisk *dev, - grub_uint8_t *b) -{ - unsigned i; - - for (i = 0; i < sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES; - i += GRUB_CRYPTODISK_GF_BYTES) - grub_crypto_xor (b + i, b + i, sec->low, GRUB_CRYPTODISK_GF_BYTES); - grub_crypto_xor (b, b, dev->lrw_precalc + GRUB_CRYPTODISK_GF_BYTES * sec->low_byte, - sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES); - if (!sec->low_byte) - return; - - for (i = sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES; - i < (1U << dev->log_sector_size); i += GRUB_CRYPTODISK_GF_BYTES) - grub_crypto_xor (b + i, b + i, sec->high, GRUB_CRYPTODISK_GF_BYTES); - grub_crypto_xor (b + sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES, - b + sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES, - dev->lrw_precalc, sec->low_byte * GRUB_CRYPTODISK_GF_BYTES); -} - -static gcry_err_code_t -grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev, - grub_uint8_t * data, grub_size_t len, - grub_disk_addr_t sector, grub_size_t log_sector_size, - int do_encrypt) -{ - grub_size_t i; - gcry_err_code_t err; - - if (dev->cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE) - return GPG_ERR_INV_ARG; - - /* The only mode without IV. */ - if (dev->mode == GRUB_CRYPTODISK_MODE_ECB && !dev->rekey) - return (do_encrypt ? grub_crypto_ecb_encrypt (dev->cipher, data, data, len) - : grub_crypto_ecb_decrypt (dev->cipher, data, data, len)); - - for (i = 0; i < len; i += ((grub_size_t) 1 << log_sector_size)) - { - grub_size_t sz = ((dev->cipher->cipher->blocksize - + sizeof (grub_uint32_t) - 1) - / sizeof (grub_uint32_t)); - grub_uint32_t iv[(GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE + 3) / 4]; - - if (dev->rekey) - { - grub_uint64_t zone = sector >> dev->rekey_shift; - if (zone != dev->last_rekey) - { - err = dev->rekey (dev, zone); - if (err) - return err; - dev->last_rekey = zone; - } - } - - grub_memset (iv, 0, sizeof (iv)); - switch (dev->mode_iv) - { - case GRUB_CRYPTODISK_MODE_IV_NULL: - break; - case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH: - { - grub_uint64_t tmp; - void *ctx; - - ctx = grub_zalloc (dev->iv_hash->contextsize); - if (!ctx) - return GPG_ERR_OUT_OF_MEMORY; - - tmp = grub_cpu_to_le64 (sector << log_sector_size); - dev->iv_hash->init (ctx); - dev->iv_hash->write (ctx, dev->iv_prefix, dev->iv_prefix_len); - dev->iv_hash->write (ctx, &tmp, sizeof (tmp)); - dev->iv_hash->final (ctx); - - grub_memcpy (iv, dev->iv_hash->read (ctx), sizeof (iv)); - grub_free (ctx); - } - break; - case GRUB_CRYPTODISK_MODE_IV_PLAIN64: - case GRUB_CRYPTODISK_MODE_IV_PLAIN: - /* - * The IV is a 32 or 64 bit value of the dm-crypt native sector - * number. If using 32 bit IV mode, zero out the most significant - * 32 bits. - */ - { - grub_uint64_t iv64; - - iv64 = grub_cpu_to_le64 (sector << (log_sector_size - - GRUB_CRYPTODISK_IV_LOG_SIZE)); - grub_set_unaligned64 (iv, iv64); - if (dev->mode_iv == GRUB_CRYPTODISK_MODE_IV_PLAIN) - iv[1] = 0; - } - break; - case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64: - /* The IV is the 64 bit byte offset of the sector. */ - iv[1] = grub_cpu_to_le32 (sector >> (GRUB_TYPE_BITS (iv[1]) - - log_sector_size)); - iv[0] = grub_cpu_to_le32 ((sector << log_sector_size) - & GRUB_TYPE_U_MAX (iv[0])); - break; - case GRUB_CRYPTODISK_MODE_IV_BENBI: - { - grub_uint64_t num = (sector << dev->benbi_log) + 1; - iv[sz - 2] = grub_cpu_to_be32 (num >> GRUB_TYPE_BITS (iv[0])); - iv[sz - 1] = grub_cpu_to_be32 (num & GRUB_TYPE_U_MAX (iv[0])); - } - break; - case GRUB_CRYPTODISK_MODE_IV_ESSIV: - iv[0] = grub_cpu_to_le32 (sector & GRUB_TYPE_U_MAX (iv[0])); - err = grub_crypto_ecb_encrypt (dev->essiv_cipher, iv, iv, - dev->cipher->cipher->blocksize); - if (err) - return err; - } - - switch (dev->mode) - { - case GRUB_CRYPTODISK_MODE_CBC: - if (do_encrypt) - err = grub_crypto_cbc_encrypt (dev->cipher, data + i, data + i, - ((grub_size_t) 1 << log_sector_size), iv); - else - err = grub_crypto_cbc_decrypt (dev->cipher, data + i, data + i, - ((grub_size_t) 1 << log_sector_size), iv); - if (err) - return err; - break; - - case GRUB_CRYPTODISK_MODE_PCBC: - if (do_encrypt) - err = grub_crypto_pcbc_encrypt (dev->cipher, data + i, data + i, - ((grub_size_t) 1 << log_sector_size), iv); - else - err = grub_crypto_pcbc_decrypt (dev->cipher, data + i, data + i, - ((grub_size_t) 1 << log_sector_size), iv); - if (err) - return err; - break; - case GRUB_CRYPTODISK_MODE_XTS: - { - unsigned j; - err = grub_crypto_ecb_encrypt (dev->secondary_cipher, iv, iv, - dev->cipher->cipher->blocksize); - if (err) - return err; - - for (j = 0; j < (1U << log_sector_size); - j += dev->cipher->cipher->blocksize) - { - grub_crypto_xor (data + i + j, data + i + j, iv, - dev->cipher->cipher->blocksize); - if (do_encrypt) - err = grub_crypto_ecb_encrypt (dev->cipher, data + i + j, - data + i + j, - dev->cipher->cipher->blocksize); - else - err = grub_crypto_ecb_decrypt (dev->cipher, data + i + j, - data + i + j, - dev->cipher->cipher->blocksize); - if (err) - return err; - grub_crypto_xor (data + i + j, data + i + j, iv, - dev->cipher->cipher->blocksize); - gf_mul_x ((grub_uint8_t *) iv); - } - } - break; - case GRUB_CRYPTODISK_MODE_LRW: - { - struct lrw_sector sec; - - generate_lrw_sector (&sec, dev, (grub_uint8_t *) iv); - lrw_xor (&sec, dev, data + i); - - if (do_encrypt) - err = grub_crypto_ecb_encrypt (dev->cipher, data + i, - data + i, - (1U << log_sector_size)); - else - err = grub_crypto_ecb_decrypt (dev->cipher, data + i, - data + i, - (1U << log_sector_size)); - if (err) - return err; - lrw_xor (&sec, dev, data + i); - } - break; - case GRUB_CRYPTODISK_MODE_ECB: - if (do_encrypt) - err = grub_crypto_ecb_encrypt (dev->cipher, data + i, data + i, - (1U << log_sector_size)); - else - err = grub_crypto_ecb_decrypt (dev->cipher, data + i, data + i, - (1U << log_sector_size)); - if (err) - return err; - break; - default: - return GPG_ERR_NOT_IMPLEMENTED; - } - sector++; - } - return GPG_ERR_NO_ERROR; -} - -gcry_err_code_t -grub_cryptodisk_decrypt (struct grub_cryptodisk *dev, - grub_uint8_t * data, grub_size_t len, - grub_disk_addr_t sector, grub_size_t log_sector_size) -{ - return grub_cryptodisk_endecrypt (dev, data, len, sector, log_sector_size, 0); -} - -grub_err_t -grub_cryptodisk_setcipher (grub_cryptodisk_t crypt, const char *ciphername, const char *ciphermode) -{ - const char *cipheriv = NULL; - grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL; - grub_crypto_cipher_handle_t essiv_cipher = NULL; - const gcry_md_spec_t *essiv_hash = NULL; - const struct gcry_cipher_spec *ciph; - grub_cryptodisk_mode_t mode; - grub_cryptodisk_mode_iv_t mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64; - int benbi_log = 0; - grub_err_t ret = GRUB_ERR_NONE; - - ciph = grub_crypto_lookup_cipher_by_name (ciphername); - if (!ciph) - { - ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available", - ciphername); - goto err; - } - - /* Configure the cipher used for the bulk data. */ - cipher = grub_crypto_cipher_open (ciph); - if (!cipher) - { - ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s could not be initialized", - ciphername); - goto err; - } - - /* Configure the cipher mode. */ - if (grub_strcmp (ciphermode, "ecb") == 0) - { - mode = GRUB_CRYPTODISK_MODE_ECB; - mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN; - cipheriv = NULL; - } - else if (grub_strcmp (ciphermode, "plain") == 0) - { - mode = GRUB_CRYPTODISK_MODE_CBC; - mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN; - cipheriv = NULL; - } - else if (grub_memcmp (ciphermode, "cbc-", sizeof ("cbc-") - 1) == 0) - { - mode = GRUB_CRYPTODISK_MODE_CBC; - cipheriv = ciphermode + sizeof ("cbc-") - 1; - } - else if (grub_memcmp (ciphermode, "pcbc-", sizeof ("pcbc-") - 1) == 0) - { - mode = GRUB_CRYPTODISK_MODE_PCBC; - cipheriv = ciphermode + sizeof ("pcbc-") - 1; - } - else if (grub_memcmp (ciphermode, "xts-", sizeof ("xts-") - 1) == 0) - { - mode = GRUB_CRYPTODISK_MODE_XTS; - cipheriv = ciphermode + sizeof ("xts-") - 1; - secondary_cipher = grub_crypto_cipher_open (ciph); - if (!secondary_cipher) - { - ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, - "Secondary cipher %s isn't available", ciphername); - goto err; - } - if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES) - { - ret = grub_error (GRUB_ERR_BAD_ARGUMENT, - "Unsupported XTS block size: %" PRIuGRUB_SIZE, - cipher->cipher->blocksize); - goto err; - } - if (secondary_cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES) - { - ret = grub_error (GRUB_ERR_BAD_ARGUMENT, - "Unsupported XTS block size: %" PRIuGRUB_SIZE, - secondary_cipher->cipher->blocksize); - goto err; - } - } - else if (grub_memcmp (ciphermode, "lrw-", sizeof ("lrw-") - 1) == 0) - { - mode = GRUB_CRYPTODISK_MODE_LRW; - cipheriv = ciphermode + sizeof ("lrw-") - 1; - if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES) - { - ret = grub_error (GRUB_ERR_BAD_ARGUMENT, - "Unsupported LRW block size: %" PRIuGRUB_SIZE, - cipher->cipher->blocksize); - goto err; - } - } - else - { - ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown cipher mode: %s", - ciphermode); - goto err; - } - - if (cipheriv == NULL) - ; - else if (grub_memcmp (cipheriv, "plain64", sizeof ("plain64") - 1) == 0) - mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64; - else if (grub_memcmp (cipheriv, "plain", sizeof ("plain") - 1) == 0) - mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN; - else if (grub_memcmp (cipheriv, "benbi", sizeof ("benbi") - 1) == 0) - { - if (cipher->cipher->blocksize & (cipher->cipher->blocksize - 1) - || cipher->cipher->blocksize == 0) - grub_error (GRUB_ERR_BAD_ARGUMENT, - "Unsupported benbi blocksize: %" PRIuGRUB_SIZE, - cipher->cipher->blocksize); - /* FIXME should we return an error here? */ - for (benbi_log = 0; - (cipher->cipher->blocksize << benbi_log) < GRUB_DISK_SECTOR_SIZE; - benbi_log++); - mode_iv = GRUB_CRYPTODISK_MODE_IV_BENBI; - } - else if (grub_memcmp (cipheriv, "null", sizeof ("null") - 1) == 0) - mode_iv = GRUB_CRYPTODISK_MODE_IV_NULL; - else if (grub_memcmp (cipheriv, "essiv:", sizeof ("essiv:") - 1) == 0) - { - const char *hash_str = cipheriv + 6; - - mode_iv = GRUB_CRYPTODISK_MODE_IV_ESSIV; - - /* Configure the hash and cipher used for ESSIV. */ - essiv_hash = grub_crypto_lookup_md_by_name (hash_str); - if (!essiv_hash) - { - ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, - "Couldn't load %s hash", hash_str); - goto err; - } - essiv_cipher = grub_crypto_cipher_open (ciph); - if (!essiv_cipher) - { - ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, - "Couldn't load %s cipher", ciphername); - goto err; - } - } - else - { - ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown IV mode: %s", - cipheriv); - goto err; - } - - crypt->cipher = cipher; - crypt->benbi_log = benbi_log; - crypt->mode = mode; - crypt->mode_iv = mode_iv; - crypt->secondary_cipher = secondary_cipher; - crypt->essiv_cipher = essiv_cipher; - crypt->essiv_hash = essiv_hash; - -err: - if (ret) - { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (secondary_cipher); - } - return ret; -} - -gcry_err_code_t -grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t keysize) -{ - gcry_err_code_t err; - int real_keysize; - - real_keysize = keysize; - if (dev->mode == GRUB_CRYPTODISK_MODE_XTS) - real_keysize /= 2; - if (dev->mode == GRUB_CRYPTODISK_MODE_LRW) - real_keysize -= dev->cipher->cipher->blocksize; - - /* Set the PBKDF2 output as the cipher key. */ - err = grub_crypto_cipher_set_key (dev->cipher, key, real_keysize); - if (err) - return err; - grub_memcpy (dev->key, key, keysize); - dev->keysize = keysize; - - /* Configure ESSIV if necessary. */ - if (dev->mode_iv == GRUB_CRYPTODISK_MODE_IV_ESSIV) - { - grub_size_t essiv_keysize = dev->essiv_hash->mdlen; - grub_uint8_t hashed_key[GRUB_CRYPTO_MAX_MDLEN]; - if (essiv_keysize > GRUB_CRYPTO_MAX_MDLEN) - return GPG_ERR_INV_ARG; - - grub_crypto_hash (dev->essiv_hash, hashed_key, key, keysize); - err = grub_crypto_cipher_set_key (dev->essiv_cipher, - hashed_key, essiv_keysize); - if (err) - return err; - } - if (dev->mode == GRUB_CRYPTODISK_MODE_XTS) - { - err = grub_crypto_cipher_set_key (dev->secondary_cipher, - key + real_keysize, - keysize / 2); - if (err) - return err; - } - - if (dev->mode == GRUB_CRYPTODISK_MODE_LRW) - { - unsigned i; - grub_uint8_t idx[GRUB_CRYPTODISK_GF_BYTES]; - - grub_free (dev->lrw_precalc); - grub_memcpy (dev->lrw_key, key + real_keysize, - dev->cipher->cipher->blocksize); - dev->lrw_precalc = grub_malloc ((1U << dev->log_sector_size)); - if (!dev->lrw_precalc) - return GPG_ERR_OUT_OF_MEMORY; - grub_memset (idx, 0, GRUB_CRYPTODISK_GF_BYTES); - for (i = 0; i < (1U << dev->log_sector_size); - i += GRUB_CRYPTODISK_GF_BYTES) - { - idx[GRUB_CRYPTODISK_GF_BYTES - 1] = i / GRUB_CRYPTODISK_GF_BYTES; - gf_mul_be (dev->lrw_precalc + i, idx, dev->lrw_key); - } - } - return GPG_ERR_NO_ERROR; -} - -static int -grub_cryptodisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - grub_cryptodisk_t i; - - if (pull != GRUB_DISK_PULL_NONE) - return 0; - - for (i = cryptodisk_list; i != NULL; i = i->next) - { - char buf[30]; - grub_snprintf (buf, sizeof (buf), "crypto%lu", i->id); - if (hook (buf, hook_data)) - return 1; - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cryptodisk_open (const char *name, grub_disk_t disk) -{ - grub_cryptodisk_t dev; - - if (grub_memcmp (name, "crypto", sizeof ("crypto") - 1) != 0) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); - - if (grub_memcmp (name, "cryptouuid/", sizeof ("cryptouuid/") - 1) == 0) - { - for (dev = cryptodisk_list; dev != NULL; dev = dev->next) - if (grub_uuidcasecmp (name + sizeof ("cryptouuid/") - 1, dev->uuid, sizeof (dev->uuid)) == 0) - break; - } - else - { - unsigned long id = grub_strtoul (name + sizeof ("crypto") - 1, 0, 0); - if (grub_errno) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); - /* Search for requested device in the list of CRYPTODISK devices. */ - for (dev = cryptodisk_list; dev != NULL; dev = dev->next) - if (dev->id == id) - break; - } - if (!dev) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); - -#ifdef GRUB_UTIL - if (dev->cheat) - { - grub_uint64_t cheat_dev_size; - unsigned int cheat_log_sector_size; - - if (!GRUB_UTIL_FD_IS_VALID (dev->cheat_fd)) - dev->cheat_fd = grub_util_fd_open (dev->cheat, GRUB_UTIL_FD_O_RDONLY); - if (!GRUB_UTIL_FD_IS_VALID (dev->cheat_fd)) - return grub_error (GRUB_ERR_IO, N_("cannot open `%s': %s"), - dev->cheat, grub_util_fd_strerror ()); - - /* Use the sector size and count of the cheat device. */ - cheat_dev_size = grub_util_get_fd_size (dev->cheat_fd, dev->cheat, &cheat_log_sector_size); - if (cheat_dev_size == -1) - { - const char *errmsg = grub_util_fd_strerror (); - grub_util_fd_close (dev->cheat_fd); - dev->cheat_fd = GRUB_UTIL_FD_INVALID; - return grub_error (GRUB_ERR_IO, N_("failed to query size of device `%s': %s"), - dev->cheat, errmsg); - } - - dev->log_sector_size = cheat_log_sector_size; - dev->total_sectors = cheat_dev_size >> cheat_log_sector_size; - } -#endif - - if (!dev->source_disk) - { - grub_dprintf ("cryptodisk", "Opening device %s\n", name); - /* Try to open the source disk and populate the requested disk. */ - dev->source_disk = grub_disk_open (dev->source); - if (!dev->source_disk) - return grub_errno; - } - - disk->data = dev; - disk->log_sector_size = dev->log_sector_size; - disk->total_sectors = dev->total_sectors; - disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE; - disk->id = dev->id; - dev->ref++; - return GRUB_ERR_NONE; -} - -static void -grub_cryptodisk_close (grub_disk_t disk) -{ - grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; - grub_dprintf ("cryptodisk", "Closing disk\n"); - - dev->ref--; - - if (dev->ref != 0) - return; -#ifdef GRUB_UTIL - if (dev->cheat) - { - grub_util_fd_close (dev->cheat_fd); - dev->cheat_fd = GRUB_UTIL_FD_INVALID; - } -#endif - grub_disk_close (dev->source_disk); - dev->source_disk = NULL; -} - -static grub_err_t -grub_cryptodisk_read (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, char *buf) -{ - grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; - grub_err_t err; - gcry_err_code_t gcry_err; - -#ifdef GRUB_UTIL - if (dev->cheat) - { - int r; - r = grub_util_fd_seek (dev->cheat_fd, sector << disk->log_sector_size); - if (r) - return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"), - dev->cheat, grub_util_fd_strerror ()); - if (grub_util_fd_read (dev->cheat_fd, buf, size << disk->log_sector_size) - != (ssize_t) (size << disk->log_sector_size)) - return grub_error (GRUB_ERR_READ_ERROR, N_("cannot read `%s': %s"), - dev->cheat, grub_util_fd_strerror ()); - return GRUB_ERR_NONE; - } -#endif - - grub_dprintf ("cryptodisk", - "Reading %" PRIuGRUB_SIZE " sectors from sector 0x%" - PRIxGRUB_UINT64_T " with offset of %" PRIuGRUB_UINT64_T "\n", - size, sector, dev->offset_sectors); - - err = grub_disk_read (dev->source_disk, - grub_disk_from_native_sector (disk, sector + dev->offset_sectors), - 0, size << disk->log_sector_size, buf); - if (err) - { - grub_dprintf ("cryptodisk", "grub_disk_read failed with error %d\n", err); - return err; - } - gcry_err = grub_cryptodisk_endecrypt (dev, (grub_uint8_t *) buf, - size << disk->log_sector_size, - sector, dev->log_sector_size, 0); - return grub_crypto_gcry_error (gcry_err); -} - -static grub_err_t -grub_cryptodisk_write (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, const char *buf) -{ - grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; - gcry_err_code_t gcry_err; - char *tmp; - grub_err_t err; - -#ifdef GRUB_UTIL - if (dev->cheat) - { - int r; - r = grub_util_fd_seek (dev->cheat_fd, sector << disk->log_sector_size); - if (r) - return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"), - dev->cheat, grub_util_fd_strerror ()); - if (grub_util_fd_write (dev->cheat_fd, buf, size << disk->log_sector_size) - != (ssize_t) (size << disk->log_sector_size)) - return grub_error (GRUB_ERR_READ_ERROR, N_("cannot read `%s': %s"), - dev->cheat, grub_util_fd_strerror ()); - return GRUB_ERR_NONE; - } -#endif - - tmp = grub_malloc (size << disk->log_sector_size); - if (!tmp) - return grub_errno; - grub_memcpy (tmp, buf, size << disk->log_sector_size); - - grub_dprintf ("cryptodisk", - "Writing %" PRIuGRUB_SIZE " sectors to sector 0x%" - PRIxGRUB_UINT64_T " with offset of %" PRIuGRUB_UINT64_T "\n", - size, sector, dev->offset_sectors); - - gcry_err = grub_cryptodisk_endecrypt (dev, (grub_uint8_t *) tmp, - size << disk->log_sector_size, - sector, disk->log_sector_size, 1); - if (gcry_err) - { - grub_free (tmp); - return grub_crypto_gcry_error (gcry_err); - } - - /* Since ->write was called so disk.mod is loaded but be paranoid */ - sector = sector + dev->offset_sectors; - if (grub_disk_write_weak) - err = grub_disk_write_weak (dev->source_disk, - grub_disk_from_native_sector (disk, sector), - 0, size << disk->log_sector_size, tmp); - else - err = grub_error (GRUB_ERR_BUG, "disk.mod not loaded"); - grub_free (tmp); - return err; -} - -#ifdef GRUB_UTIL -static grub_disk_memberlist_t -grub_cryptodisk_memberlist (grub_disk_t disk) -{ - grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; - grub_disk_memberlist_t list = NULL; - - list = grub_malloc (sizeof (*list)); - if (list) - { - list->disk = dev->source_disk; - list->next = NULL; - } - - return list; -} -#endif - -static void -cryptodisk_cleanup (void) -{ -#if 0 - grub_cryptodisk_t dev = cryptodisk_list; - grub_cryptodisk_t tmp; - - while (dev != NULL) - { - grub_free (dev->source); - grub_free (dev->cipher); - grub_free (dev->secondary_cipher); - grub_free (dev->essiv_cipher); - tmp = dev->next; - grub_free (dev); - dev = tmp; - } -#endif -} - -grub_err_t -grub_cryptodisk_insert (grub_cryptodisk_t newdev, const char *name, - grub_disk_t source) -{ - newdev->source = grub_strdup (name); - if (!newdev->source) - return grub_errno; - - newdev->id = last_cryptodisk_id++; - newdev->source_id = source->id; - newdev->source_dev_id = source->dev->id; - newdev->partition_start = grub_partition_get_start (source->partition); - newdev->next = cryptodisk_list; - cryptodisk_list = newdev; - - return GRUB_ERR_NONE; -} - -grub_cryptodisk_t -grub_cryptodisk_get_by_uuid (const char *uuid) -{ - grub_cryptodisk_t dev; - for (dev = cryptodisk_list; dev != NULL; dev = dev->next) - if (grub_uuidcasecmp (dev->uuid, uuid, sizeof (dev->uuid)) == 0) - return dev; - return NULL; -} - -grub_cryptodisk_t -grub_cryptodisk_get_by_source_disk (grub_disk_t disk) -{ - grub_cryptodisk_t dev; - for (dev = cryptodisk_list; dev != NULL; dev = dev->next) - if (dev->source_id == disk->id && dev->source_dev_id == disk->dev->id) - if ((disk->partition && grub_partition_get_start (disk->partition) == dev->partition_start) || - (!disk->partition && dev->partition_start == 0)) - return dev; - return NULL; -} - -#ifdef GRUB_UTIL -grub_err_t -grub_cryptodisk_cheat_insert (grub_cryptodisk_t newdev, const char *name, - grub_disk_t source, const char *cheat) -{ - newdev->cheat = grub_strdup (cheat); - newdev->source = grub_strdup (name); - if (!newdev->source || !newdev->cheat) - { - grub_free (newdev->source); - grub_free (newdev->cheat); - return grub_errno; - } - - newdev->cheat_fd = GRUB_UTIL_FD_INVALID; - newdev->source_id = source->id; - newdev->source_dev_id = source->dev->id; - newdev->partition_start = grub_partition_get_start (source->partition); - newdev->id = last_cryptodisk_id++; - newdev->next = cryptodisk_list; - cryptodisk_list = newdev; - - return GRUB_ERR_NONE; -} - -void -grub_util_cryptodisk_get_abstraction (grub_disk_t disk, - void (*cb) (const char *val, void *data), - void *data) -{ - grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; - - cb ("cryptodisk", data); - cb (dev->modname, data); - - if (dev->cipher) - cb (dev->cipher->cipher->modname, data); - if (dev->secondary_cipher) - cb (dev->secondary_cipher->cipher->modname, data); - if (dev->essiv_cipher) - cb (dev->essiv_cipher->cipher->modname, data); - if (dev->hash) - cb (dev->hash->modname, data); - if (dev->essiv_hash) - cb (dev->essiv_hash->modname, data); - if (dev->iv_hash) - cb (dev->iv_hash->modname, data); -} - -const char * -grub_util_cryptodisk_get_uuid (grub_disk_t disk) -{ - grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data; - return dev->uuid; -} - -#endif - -static void -cryptodisk_close (grub_cryptodisk_t dev) -{ - grub_crypto_cipher_close (dev->cipher); - grub_crypto_cipher_close (dev->secondary_cipher); - grub_crypto_cipher_close (dev->essiv_cipher); - grub_free (dev); -} - -static grub_err_t -cryptodisk_read_hook (grub_disk_addr_t sector, unsigned offset, - unsigned length, char *buf, void *data) -{ - cryptodisk_read_hook_ctx_t ctx = data; - - if (ctx->hdr_file == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("header file not found")); - - if (grub_file_seek (ctx->hdr_file, - ((sector - ctx->part_start) * GRUB_DISK_SECTOR_SIZE) + offset) - == (grub_off_t) -1) - return grub_errno; - - if (grub_file_read (ctx->hdr_file, buf, length) != (grub_ssize_t) length) - { - if (grub_errno == GRUB_ERR_NONE) - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("header file too small")); - return grub_errno; - } - - return GRUB_ERR_NONE; -} - -static grub_cryptodisk_t -grub_cryptodisk_scan_device_real (const char *name, - grub_disk_t source, - grub_cryptomount_args_t cargs) -{ - grub_err_t ret = GRUB_ERR_NONE; - grub_cryptodisk_t dev; - grub_cryptodisk_dev_t cr; - int i; - struct cryptodisk_read_hook_ctx read_hook_data = {0}; - int askpass = 0; - char *part = NULL; - - dev = grub_cryptodisk_get_by_source_disk (source); - - if (dev) - return dev; - - if (cargs->hdr_file != NULL) - { - /* - * Set read hook to read header from a file instead of the source disk. - * Disk read hooks are executed after the data has been read from the - * disk. This is okay, because the read hook is given the read buffer - * before its sent back to the caller. In this case, the hook can then - * overwrite the data read from the disk device with data from the - * header file sent in as the read hook data. This is transparent to the - * read caller. Since the callers of this function have just opened the - * source disk, there are no current read hooks, so there's no need to - * save/restore them nor consider if they should be called or not. - * - * This hook assumes that the header is at the start of the volume, which - * is not the case for some formats (eg. GELI). It also can only be used - * with formats where the detached header file can be written to the - * first blocks of the volume and the volume could still be unlocked. - * So the header file can not be formatted differently from the on-disk - * header. If these assumpts are not met, detached header file processing - * must be specially handled in the cryptodisk backend module. - * - * This hook needs only be set once and will be called potentially many - * times by a backend. This is fine because of the assumptions mentioned - * and the read hook reads from absolute offsets and is stateless. - */ - read_hook_data.part_start = grub_partition_get_start (source->partition); - read_hook_data.hdr_file = cargs->hdr_file; - source->read_hook = cryptodisk_read_hook; - source->read_hook_data = (void *) &read_hook_data; - } - - FOR_CRYPTODISK_DEVS (cr) - { - /* - * Loop through each cryptodisk backend that is registered (ie. loaded). - * If the scan returns NULL, then the backend being tested does not - * recognize the source disk, so move on to the next backend. - */ - dev = cr->scan (source, cargs); - if (grub_errno) - goto error_no_close; - if (!dev) - continue; - break; - } - - if (dev == NULL) - { - grub_error (GRUB_ERR_BAD_MODULE, - "no cryptodisk module can handle this device"); - goto error_no_close; - } - - if (cargs->protectors) - { - for (i = 0; cargs->protectors[i]; i++) - { - if (cargs->key_cache[i].invalid) - continue; - - if (cargs->key_cache[i].key == NULL) - { - ret = grub_key_protector_recover_key (cargs->protectors[i], - &cargs->key_cache[i].key, - &cargs->key_cache[i].key_len); - if (ret != GRUB_ERR_NONE) - { - if (grub_errno) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - } - - grub_dprintf ("cryptodisk", - "failed to recover a key from key protector " - "%s, will not try it again for any other " - "disks, if any, during this invocation of " - "cryptomount\n", - cargs->protectors[i]); - - cargs->key_cache[i].invalid = 1; - continue; - } - } - - cargs->key_data = cargs->key_cache[i].key; - cargs->key_len = cargs->key_cache[i].key_len; - - ret = cr->recover_key (source, dev, cargs); - if (ret != GRUB_ERR_NONE) - { - /* Reset key data to trigger the passphrase prompt later */ - cargs->key_data = NULL; - cargs->key_len = 0; - - part = grub_partition_get_name (source->partition); - grub_dprintf ("cryptodisk", - "recovered a key from key protector %s but it " - "failed to unlock %s%s%s (%s)\n", - cargs->protectors[i], source->name, - source->partition != NULL ? "," : "", - part != NULL ? part : N_("UNKNOWN"), dev->uuid); - grub_free (part); - continue; - } - else - { - ret = grub_cryptodisk_insert (dev, name, source); - if (ret != GRUB_ERR_NONE) - goto error; -#ifndef GRUB_UTIL - grub_cli_set_auth_needed (); -#endif - goto cleanup; - } - } - - part = grub_partition_get_name (source->partition); - grub_error (GRUB_ERR_ACCESS_DENIED, - N_("no key protector provided a usable key for %s%s%s (%s)"), - source->name, source->partition != NULL ? "," : "", - part != NULL ? part : N_("UNKNOWN"), dev->uuid); - grub_free (part); - } - - if (cargs->key_len) - { - ret = cr->recover_key (source, dev, cargs); - if (ret != GRUB_ERR_NONE) - goto error; - } - else - { - /* Get the passphrase from the user, if no key data. */ - unsigned long tries = 3; - const char *tries_env; - - /* - * Print the error from key protectors and clear grub_errno. - * - * Since '--protector' cannot coexist with '--password' and - * '--key-file', in case key protectors fail, only - * "cargs->key_len == 0" is expected, so cryptomount falls back - * here to request the passphrase. - * - * To avoid the error from key protectors stops the further code, - * print the error to notify the user why key protectors fail and - * clear grub_errno to have a fresh start. - */ - if (grub_errno != GRUB_ERR_NONE) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - } - - askpass = 1; - cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE); - if (cargs->key_data == NULL) - goto error_no_close; - - tries_env = grub_env_get ("cryptodisk_passphrase_tries"); - if (tries_env != NULL && tries_env[0] != '\0') - { - unsigned long tries_env_val; - const char *p; - - tries_env_val = grub_strtoul (tries_env, &p, 0); - if (*p == '\0' && tries_env_val != ~0UL) - tries = tries_env_val; - else - grub_printf_ (N_("Invalid cryptodisk_passphrase_tries value `%s'. Defaulting to %lu.\n"), - tries_env, - tries); - } - - for (; tries > 0; tries--) - { - part = grub_partition_get_name (source->partition); - grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, - source->partition != NULL ? "," : "", - part != NULL ? part : N_("UNKNOWN"), - dev->uuid); - grub_free (part); - - if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE)) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied"); - goto error; - } - cargs->key_len = grub_strlen ((char *) cargs->key_data); - - ret = cr->recover_key (source, dev, cargs); - if (ret == GRUB_ERR_NONE) - break; - if (ret != GRUB_ERR_ACCESS_DENIED || tries == 1) - goto error; - grub_puts_ (N_("Invalid passphrase.")); - - /* - * Since recover_key() calls a function that returns grub_errno, - * a leftover error value from a previously rejected passphrase - * will trigger a phantom failure. We therefore clear it before - * trying a new passphrase. - */ - grub_errno = GRUB_ERR_NONE; - } - } - - ret = grub_cryptodisk_insert (dev, name, source); - if (ret != GRUB_ERR_NONE) - goto error; - - goto cleanup; - - error: - cryptodisk_close (dev); - error_no_close: - dev = NULL; - - cleanup: - if (cargs->hdr_file != NULL) - source->read_hook = NULL; - - if (askpass) - { - grub_memset (cargs->key_data, 0, cargs->key_len); - cargs->key_len = 0; - grub_free (cargs->key_data); - } - return dev; -} - -#ifdef GRUB_UTIL -#include -grub_err_t -grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat) -{ - grub_err_t err; - grub_cryptodisk_t dev; - grub_cryptodisk_dev_t cr; - grub_disk_t source; - struct grub_cryptomount_args cargs = {0}; - - /* Try to open disk. */ - source = grub_disk_open (sourcedev); - if (!source) - return grub_errno; - - dev = grub_cryptodisk_get_by_source_disk (source); - - if (dev) - { - grub_disk_close (source); - return GRUB_ERR_NONE; - } - - FOR_CRYPTODISK_DEVS (cr) - { - dev = cr->scan (source, &cargs); - if (grub_errno) - return grub_errno; - if (!dev) - continue; - - grub_util_info ("cheatmounted %s (%s) at %s", sourcedev, dev->modname, - cheat); - err = grub_cryptodisk_cheat_insert (dev, sourcedev, source, cheat); - grub_disk_close (source); - if (err) - grub_free (dev); - - return GRUB_ERR_NONE; - } - - grub_disk_close (source); - - return GRUB_ERR_NONE; -} -#endif - -static int -grub_cryptodisk_scan_device (const char *name, - void *data) -{ - int ret = 0; - grub_disk_t source; - grub_cryptodisk_t dev; - grub_cryptomount_args_t cargs = data; - grub_errno = GRUB_ERR_NONE; - - /* Try to open disk. */ - source = grub_disk_open (name); - if (!source) - { - grub_print_error (); - return 0; - } - - dev = grub_cryptodisk_scan_device_real (name, source, cargs); - if (dev) - { - ret = (cargs->search_uuid != NULL - && grub_uuidcasecmp (cargs->search_uuid, dev->uuid, sizeof (dev->uuid)) == 0); - goto cleanup; - } - - /* - * Do not print error when err is GRUB_ERR_BAD_MODULE to avoid many unhelpful - * error messages. - */ - if (grub_errno == GRUB_ERR_BAD_MODULE) - grub_error_pop (); - - if (cargs->search_uuid != NULL) - /* Push error onto stack to save for cryptomount. */ - grub_error_push (); - else - grub_print_error (); - - cleanup: - grub_disk_close (source); - return ret; -} - -static void -grub_cryptodisk_clear_key_cache (struct grub_cryptomount_args *cargs) -{ - int i; - - if (cargs->key_cache == NULL || cargs->protectors == NULL) - return; - - for (i = 0; cargs->protectors[i]; i++) - { - if (cargs->key_cache[i].key) - grub_memset (cargs->key_cache[i].key, 0, cargs->key_cache[i].key_len); - grub_free (cargs->key_cache[i].key); - } - - grub_free (cargs->key_cache); -} - -static grub_err_t -grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_arg_list *state = ctxt->state; - struct grub_cryptomount_args cargs = {0}; - - if (argc < 1 && !state[OPTION_ALL].set && !state[OPTION_BOOT].set) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); - - if (grub_cryptodisk_list == NULL) - return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded"); - - if (state[OPTION_PASSWORD].set && state[OPTION_PROTECTOR].set) /* password and key protector */ - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "a password and a key protector cannot both be set"); - - if (state[OPTION_KEYFILE].set && state[OPTION_PROTECTOR].set) /* key file and key protector */ - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "a key file and a key protector cannot both be set"); - - if (state[OPTION_PASSWORD].set) /* password */ - { - cargs.key_data = (grub_uint8_t *) state[OPTION_PASSWORD].arg; - cargs.key_len = grub_strlen (state[OPTION_PASSWORD].arg); - } - - if (state[OPTION_KEYFILE].set) /* keyfile */ - { - const char *p = NULL; - grub_file_t keyfile; - unsigned long long keyfile_offset = 0, keyfile_size = 0; - - if (state[OPTION_KEYFILE_OFFSET].set) /* keyfile-offset */ - { - grub_errno = GRUB_ERR_NONE; - keyfile_offset = grub_strtoull (state[OPTION_KEYFILE_OFFSET].arg, &p, 0); - - if (state[OPTION_KEYFILE_OFFSET].arg[0] == '\0' || *p != '\0') - return grub_error (grub_errno, - N_("non-numeric or invalid keyfile offset `%s'"), - state[OPTION_KEYFILE_OFFSET].arg); - } - - if (state[OPTION_KEYFILE_SIZE].set) /* keyfile-size */ - { - grub_errno = GRUB_ERR_NONE; - keyfile_size = grub_strtoull (state[OPTION_KEYFILE_SIZE].arg, &p, 0); - - if (state[OPTION_KEYFILE_SIZE].arg[0] == '\0' || *p != '\0') - return grub_error (grub_errno, - N_("non-numeric or invalid keyfile size `%s'"), - state[OPTION_KEYFILE_SIZE].arg); - - if (keyfile_size == 0) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("key file size is 0")); - - if (keyfile_size > GRUB_CRYPTODISK_MAX_KEYFILE_SIZE) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("key file size exceeds maximum (%d)"), - GRUB_CRYPTODISK_MAX_KEYFILE_SIZE); - } - - keyfile = grub_file_open (state[OPTION_KEYFILE].arg, - GRUB_FILE_TYPE_CRYPTODISK_ENCRYPTION_KEY); - if (keyfile == NULL) - return grub_errno; - - if (keyfile_offset > keyfile->size) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("Keyfile offset, %llu, is greater than " - "keyfile size, %llu"), - keyfile_offset, (unsigned long long) keyfile->size); - - if (grub_file_seek (keyfile, (grub_off_t) keyfile_offset) == (grub_off_t) -1) - return grub_errno; - - if (keyfile_size != 0) - { - if (keyfile_size > (keyfile->size - keyfile_offset)) - return grub_error (GRUB_ERR_FILE_READ_ERROR, - N_("keyfile is too small: requested %llu bytes," - " but the file only has %" PRIuGRUB_UINT64_T - " bytes left at offset %llu"), - keyfile_size, - (grub_off_t) (keyfile->size - keyfile_offset), - keyfile_offset); - - cargs.key_len = keyfile_size; - } - else - cargs.key_len = keyfile->size - keyfile_offset; - - cargs.key_data = grub_malloc (cargs.key_len); - if (cargs.key_data == NULL) - return GRUB_ERR_OUT_OF_MEMORY; - - if (grub_file_read (keyfile, cargs.key_data, cargs.key_len) != (grub_ssize_t) cargs.key_len) - return grub_error (GRUB_ERR_FILE_READ_ERROR, (N_("failed to read key file"))); - } - - if (state[OPTION_HEADER].set) /* header */ - { - if (state[OPTION_UUID].set) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("cannot use UUID lookup with detached header")); - - cargs.hdr_file = grub_file_open (state[OPTION_HEADER].arg, - GRUB_FILE_TYPE_CRYPTODISK_DETACHED_HEADER); - if (cargs.hdr_file == NULL) - return grub_errno; - } - - if (state[OPTION_PROTECTOR].set) /* key protector(s) */ - { - cargs.key_cache = grub_calloc (state[OPTION_PROTECTOR].set, sizeof (*cargs.key_cache)); - if (cargs.key_cache == NULL) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "no memory for key protector key cache"); - cargs.protectors = state[OPTION_PROTECTOR].args; - } - - if (state[OPTION_UUID].set) /* uuid */ - { - int found_uuid; - grub_cryptodisk_t dev; - - dev = grub_cryptodisk_get_by_uuid (args[0]); - if (dev) - { - grub_cryptodisk_clear_key_cache (&cargs); - grub_dprintf ("cryptodisk", - "already mounted as crypto%lu\n", dev->id); - return GRUB_ERR_NONE; - } - - cargs.check_boot = state[OPTION_BOOT].set; - cargs.search_uuid = args[0]; - found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); - grub_cryptodisk_clear_key_cache (&cargs); - - if (found_uuid) - return GRUB_ERR_NONE; - else if (grub_errno == GRUB_ERR_NONE) - { - /* - * Try to pop the next error on the stack. If there is not one, then - * no device matched the given UUID. - */ - grub_error_pop (); - if (grub_errno == GRUB_ERR_NONE) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found, perhaps a needed disk or cryptodisk module is not loaded"); - } - return grub_errno; - } - else if (state[OPTION_ALL].set || (argc == 0 && state[OPTION_BOOT].set)) /* -a|-b */ - { - cargs.check_boot = state[OPTION_BOOT].set; - grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); - grub_cryptodisk_clear_key_cache (&cargs); - return GRUB_ERR_NONE; - } - else - { - grub_disk_t disk; - grub_cryptodisk_t dev; - char *diskname; - char *disklast = NULL; - grub_size_t len; - - cargs.check_boot = state[OPTION_BOOT].set; - diskname = args[0]; - len = grub_strlen (diskname); - if (len && diskname[0] == '(' && diskname[len - 1] == ')') - { - disklast = &diskname[len - 1]; - *disklast = '\0'; - diskname++; - } - - disk = grub_disk_open (diskname); - if (!disk) - { - grub_cryptodisk_clear_key_cache (&cargs); - if (disklast) - *disklast = ')'; - return grub_errno; - } - - dev = grub_cryptodisk_get_by_source_disk (disk); - if (dev) - { - grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id); - grub_disk_close (disk); - grub_cryptodisk_clear_key_cache (&cargs); - if (disklast) - *disklast = ')'; - return GRUB_ERR_NONE; - } - - dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs); - grub_cryptodisk_clear_key_cache (&cargs); - - grub_disk_close (disk); - if (disklast) - *disklast = ')'; - - return (dev == NULL) ? grub_errno : GRUB_ERR_NONE; - } -} - -static struct grub_disk_dev grub_cryptodisk_dev = { - .name = "cryptodisk", - .id = GRUB_DISK_DEVICE_CRYPTODISK_ID, - .disk_iterate = grub_cryptodisk_iterate, - .disk_open = grub_cryptodisk_open, - .disk_close = grub_cryptodisk_close, - .disk_read = grub_cryptodisk_read, - .disk_write = grub_cryptodisk_write, -#ifdef GRUB_UTIL - .disk_memberlist = grub_cryptodisk_memberlist, -#endif - .next = 0 -}; - -static char -hex (grub_uint8_t val) -{ - if (val < 10) - return '0' + val; - return 'a' + val - 10; -} - -/* Open a file named NAME and initialize FILE. */ -static char * -luks_script_get (grub_size_t *sz) -{ - grub_cryptodisk_t i; - grub_size_t size = 0, mul; - char *ptr, *ret; - - *sz = 0; - - for (i = cryptodisk_list; i != NULL; i = i->next) - if (grub_strcmp (i->modname, "luks") == 0 || - grub_strcmp (i->modname, "luks2") == 0) - { - /* - * Add space in the line for (in order) spaces, cipher mode, cipher IV - * mode, sector offset, sector size and the trailing newline. This is - * an upper bound on the size of this data. There are 15 extra bytes - * in an earlier version of this code that are unaccounted for. It is - * left in the calculations in case it is needed. At worst, its short- - * lived wasted space. - * - * 60 = 5 + 5 + 8 + 20 + 6 + 1 + 15 - */ - if (grub_add (size, grub_strlen (i->modname), &size) || - grub_add (size, sizeof ("_mount") + 60, &size) || - grub_add (size, grub_strlen (i->uuid), &size) || - grub_add (size, grub_strlen (i->cipher->cipher->name), &size) || - grub_mul (i->keysize, 2, &mul) || - grub_add (size, mul, &size)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while obtaining size of luks script"); - return 0; - } - if (i->essiv_hash) - { - if (grub_add (size, grub_strlen (i->essiv_hash->name), &size)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while obtaining size of luks script"); - return 0; - } - } - } - if (grub_add (size, 1, &size)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while obtaining size of luks script"); - return 0; - } - - ret = grub_malloc (size); - if (!ret) - return 0; - - ptr = ret; - - for (i = cryptodisk_list; i != NULL; i = i->next) - if (grub_strcmp (i->modname, "luks") == 0 || - grub_strcmp (i->modname, "luks2") == 0) - { - unsigned j; - const char *iptr; - ptr = grub_stpcpy (ptr, i->modname); - ptr = grub_stpcpy (ptr, "_mount "); - ptr = grub_stpcpy (ptr, i->uuid); - *ptr++ = ' '; - ptr += grub_snprintf (ptr, 21, "%" PRIxGRUB_OFFSET, i->offset_sectors); - *ptr++ = ' '; - ptr += grub_snprintf (ptr, 7, "%u", 1 << i->log_sector_size); - *ptr++ = ' '; - for (iptr = i->cipher->cipher->name; *iptr; iptr++) - *ptr++ = grub_tolower (*iptr); - switch (i->mode) - { - case GRUB_CRYPTODISK_MODE_ECB: - ptr = grub_stpcpy (ptr, "-ecb"); - break; - case GRUB_CRYPTODISK_MODE_CBC: - ptr = grub_stpcpy (ptr, "-cbc"); - break; - case GRUB_CRYPTODISK_MODE_PCBC: - ptr = grub_stpcpy (ptr, "-pcbc"); - break; - case GRUB_CRYPTODISK_MODE_XTS: - ptr = grub_stpcpy (ptr, "-xts"); - break; - case GRUB_CRYPTODISK_MODE_LRW: - ptr = grub_stpcpy (ptr, "-lrw"); - break; - } - - switch (i->mode_iv) - { - case GRUB_CRYPTODISK_MODE_IV_NULL: - ptr = grub_stpcpy (ptr, "-null"); - break; - case GRUB_CRYPTODISK_MODE_IV_PLAIN: - ptr = grub_stpcpy (ptr, "-plain"); - break; - case GRUB_CRYPTODISK_MODE_IV_PLAIN64: - ptr = grub_stpcpy (ptr, "-plain64"); - break; - case GRUB_CRYPTODISK_MODE_IV_BENBI: - ptr = grub_stpcpy (ptr, "-benbi"); - break; - case GRUB_CRYPTODISK_MODE_IV_ESSIV: - ptr = grub_stpcpy (ptr, "-essiv:"); - ptr = grub_stpcpy (ptr, i->essiv_hash->name); - break; - case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64: - case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH: - break; - } - *ptr++ = ' '; - for (j = 0; j < i->keysize; j++) - { - *ptr++ = hex (i->key[j] >> 4); - *ptr++ = hex (i->key[j] & 0xf); - } - *ptr++ = '\n'; - } - *ptr = '\0'; - *sz = ptr - ret; - return ret; -} - -#ifdef GRUB_MACHINE_EFI -grub_err_t -grub_cryptodisk_challenge_password (void) -{ - grub_cryptodisk_t cr_dev; - - for (cr_dev = cryptodisk_list; cr_dev != NULL; cr_dev = cr_dev->next) - { - grub_cryptodisk_dev_t cr; - grub_disk_t source = NULL; - grub_err_t ret = GRUB_ERR_NONE; - grub_cryptodisk_t dev = NULL; - char *part = NULL; - struct grub_cryptomount_args cargs = {0}; - - cargs.check_boot = 0; - cargs.search_uuid = cr_dev->uuid; - - source = grub_disk_open (cr_dev->source); - - if (source == NULL) - { - ret = grub_errno; - goto error_out; - } - - FOR_CRYPTODISK_DEVS (cr) - { - dev = cr->scan (source, &cargs); - if (grub_errno) - { - ret = grub_errno; - goto error_out; - } - if (dev == NULL) - continue; - break; - } - - if (dev == NULL) - { - ret = grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device"); - goto error_out; - } - - part = grub_partition_get_name (source->partition); - grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, - source->partition != NULL ? "," : "", - part != NULL ? part : N_("UNKNOWN"), cr_dev->uuid); - grub_free (part); - - cargs.key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE); - if (cargs.key_data == NULL) - { - ret = grub_errno; - goto error_out; - } - - if (!grub_password_get ((char *) cargs.key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE)) - { - ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied"); - goto error_out; - } - cargs.key_len = grub_strlen ((char *) cargs.key_data); - ret = cr->recover_key (source, dev, &cargs); - - error_out: - grub_disk_close (source); - if (dev != NULL) - cryptodisk_close (dev); - if (cargs.key_data) - { - grub_memset (cargs.key_data, 0, cargs.key_len); - grub_free (cargs.key_data); - } - - return ret; - } - - return GRUB_ERR_NONE; -} - -void -grub_cryptodisk_erasesecrets (void) -{ - grub_cryptodisk_t i; - grub_uint8_t *buf; - - buf = grub_zalloc (GRUB_CRYPTODISK_MAX_KEYLEN); - if (buf == NULL) - grub_fatal ("grub_cryptodisk_erasesecrets: cannot allocate memory"); - - for (i = cryptodisk_list; i != NULL; i = i->next) - if (grub_cryptodisk_setkey (i, buf, i->keysize)) - grub_fatal ("grub_cryptodisk_erasesecrets: cannot erase secrets for %s", i->source); - else - grub_printf ("Erased crypto secrets for %s\n", i->source); - /* - * Unfortunately, there is no way to "force unmount" a given disk, it may - * have mounted "child" disks as well, e.g., an LVM volume. So, this - * function MUST be called when there is no way back, e.g., when exiting. - * Otherwise, subsequent read calls for a cryptodisk will return garbage. - */ - - grub_free (buf); -} -#endif /* GRUB_MACHINE_EFI */ - -struct grub_procfs_entry luks_script = -{ - .name = "luks_script", - .get_contents = luks_script_get -}; - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT (cryptodisk) -{ - grub_disk_dev_register (&grub_cryptodisk_dev); - cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0, - N_("[ [-p password] | [-k keyfile" - " [-O keyoffset] [-S keysize] ] ] [-H file]" - " [-P protector [-P protector ...]]" - " "), - N_("Mount a crypto device."), options); - grub_procfs_register ("luks_script", &luks_script); -} - -GRUB_MOD_FINI (cryptodisk) -{ -#ifdef GRUB_MACHINE_EFI - grub_cryptodisk_erasesecrets (); -#endif - grub_disk_dev_unregister (&grub_cryptodisk_dev); - cryptodisk_cleanup (); - grub_unregister_extcmd (cmd); - grub_procfs_unregister (&luks_script); -} diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c deleted file mode 100644 index 3a26de60c..000000000 --- a/grub-core/disk/diskfilter.c +++ /dev/null @@ -1,1494 +0,0 @@ -/* diskfilter.c - module to read RAID arrays. */ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef GRUB_UTIL -#include -#include -#endif - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* Linked list of DISKFILTER arrays. */ -static struct grub_diskfilter_vg *array_list; -grub_raid5_recover_func_t grub_raid5_recover_func; -grub_raid6_recover_func_t grub_raid6_recover_func; -grub_diskfilter_t grub_diskfilter_list; -static int inscnt = 0; -static int lv_num = 0; - -static struct grub_diskfilter_lv * -find_lv (const char *name); -static int is_lv_readable (struct grub_diskfilter_lv *lv, int easily); - - - -static grub_err_t -is_node_readable (const struct grub_diskfilter_node *node, int easily) -{ - /* Check whether we actually know the physical volume we want to - read from. */ - if (node->pv) - return !!(node->pv->disk); - if (node->lv) - return is_lv_readable (node->lv, easily); - return 0; -} - -static int -is_lv_readable (struct grub_diskfilter_lv *lv, int easily) -{ - unsigned i, j; - if (!lv) - return 0; - for (i = 0; i < lv->segment_count; i++) - { - int need = lv->segments[i].node_count, have = 0; - switch (lv->segments[i].type) - { - case GRUB_DISKFILTER_RAID6: - if (!easily) - need--; - /* Fallthrough. */ - case GRUB_DISKFILTER_RAID4: - case GRUB_DISKFILTER_RAID5: - if (!easily) - need--; - /* Fallthrough. */ - case GRUB_DISKFILTER_STRIPED: - break; - - case GRUB_DISKFILTER_MIRROR: - need = 1; - break; - - case GRUB_DISKFILTER_RAID10: - { - unsigned int n; - n = lv->segments[i].layout & 0xFF; - if (n == 1) - n = (lv->segments[i].layout >> 8) & 0xFF; - need = lv->segments[i].node_count - n + 1; - } - break; - } - for (j = 0; j < lv->segments[i].node_count; j++) - { - if (is_node_readable (lv->segments[i].nodes + j, easily)) - have++; - if (have >= need) - break; - } - if (have < need) - return 0; - } - - return 1; -} - -static grub_err_t -insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id, - struct grub_diskfilter_vg *array, - grub_disk_addr_t start_sector, - grub_diskfilter_t diskfilter __attribute__ ((unused))); - -static int -is_valid_diskfilter_name (const char *name) -{ - return (grub_memcmp (name, "md", sizeof ("md") - 1) == 0 - || grub_memcmp (name, "lvm/", sizeof ("lvm/") - 1) == 0 - || grub_memcmp (name, "lvmid/", sizeof ("lvmid/") - 1) == 0 - || grub_memcmp (name, "ldm/", sizeof ("ldm/") - 1) == 0); -} - -/* Helper for scan_disk. */ -static int -scan_disk_partition_iter (grub_disk_t disk, grub_partition_t p, void *data) -{ - const char *name = data; - struct grub_diskfilter_vg *arr; - grub_disk_addr_t start_sector; - struct grub_diskfilter_pv_id id; - grub_diskfilter_t diskfilter; - - grub_dprintf ("diskfilter", "Scanning for DISKFILTER devices on disk %s\n", - name); -#ifdef GRUB_UTIL - grub_util_info ("Scanning for DISKFILTER devices on disk %s", name); -#endif - - disk->partition = p; - - for (arr = array_list; arr != NULL; arr = arr->next) - { - struct grub_diskfilter_pv *m; - for (m = arr->pvs; m; m = m->next) - if (m->disk && m->disk->id == disk->id - && m->disk->dev->id == disk->dev->id - && m->part_start == grub_partition_get_start (disk->partition) - && m->part_size == grub_disk_native_sectors (disk)) - return 0; - } - - for (diskfilter = grub_diskfilter_list; diskfilter; diskfilter = diskfilter->next) - { -#ifdef GRUB_UTIL - grub_util_info ("Scanning for %s devices on disk %s", - diskfilter->name, name); -#endif - id.uuid = 0; - id.uuidlen = 0; - arr = diskfilter->detect (disk, &id, &start_sector); - if (arr && - (! insert_array (disk, &id, arr, start_sector, diskfilter))) - { - if (id.uuidlen) - grub_free (id.uuid); - return 0; - } - if (arr && id.uuidlen) - grub_free (id.uuid); - - /* This error usually means it's not diskfilter, no need to display - it. */ - if (grub_errno != GRUB_ERR_OUT_OF_RANGE) - grub_print_error (); - - grub_errno = GRUB_ERR_NONE; - } - - return 0; -} - -static int -scan_disk (const char *name, int accept_diskfilter) -{ - grub_disk_t disk; - static int scan_depth = 0; - - if (!accept_diskfilter && is_valid_diskfilter_name (name)) - return 0; - - if (scan_depth > 100) - return 0; - - scan_depth++; - disk = grub_disk_open (name); - if (!disk) - { - grub_errno = GRUB_ERR_NONE; - scan_depth--; - return 0; - } - scan_disk_partition_iter (disk, 0, (void *) name); - grub_partition_iterate (disk, scan_disk_partition_iter, (void *) name); - grub_disk_close (disk); - scan_depth--; - return 0; -} - -static int -scan_disk_hook (const char *name, void *data __attribute__ ((unused))) -{ - return scan_disk (name, 0); -} - -static void -scan_devices (const char *arname) -{ - grub_disk_dev_t p; - grub_disk_pull_t pull; - struct grub_diskfilter_vg *vg; - struct grub_diskfilter_lv *lv = NULL; - int scan_depth; - int need_rescan; - - for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) - { - /* look up the crytodisk devices first */ - for (p = grub_disk_dev_list; p; p = p->next) - if (p->id == GRUB_DISK_DEVICE_CRYPTODISK_ID && p->disk_iterate) - { - if ((p->disk_iterate) (scan_disk_hook, NULL, pull)) - return; - if (arname && is_lv_readable (find_lv (arname), 1)) - return; - break; - } - - /* check the devices other than crytodisk */ - for (p = grub_disk_dev_list; p; p = p->next) - if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID && p->disk_iterate) - { - if ((p->disk_iterate) (scan_disk_hook, NULL, pull)) - return; - if (arname && is_lv_readable (find_lv (arname), 1)) - return; - } - } - - scan_depth = 0; - need_rescan = 1; - while (need_rescan && scan_depth++ < 100) - { - need_rescan = 0; - for (vg = array_list; vg; vg = vg->next) - { - if (vg->lvs) - for (lv = vg->lvs; lv; lv = lv->next) - if (!lv->scanned && lv->fullname && lv->became_readable_at) - { - scan_disk (lv->fullname, 1); - lv->scanned = 1; - need_rescan = 1; - } - } - } - - if (need_rescan) - grub_error (GRUB_ERR_UNKNOWN_DEVICE, "DISKFILTER scan depth exceeded"); -} - -static int -grub_diskfilter_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - struct grub_diskfilter_vg *array; - int islcnt = 0; - - if (pull == GRUB_DISK_PULL_RESCAN) - { - islcnt = inscnt + 1; - scan_devices (NULL); - } - - if (pull != GRUB_DISK_PULL_NONE && pull != GRUB_DISK_PULL_RESCAN) - return 0; - - for (array = array_list; array; array = array->next) - { - struct grub_diskfilter_lv *lv; - if (array->lvs) - for (lv = array->lvs; lv; lv = lv->next) - if (lv->visible && lv->fullname && lv->became_readable_at >= islcnt) - { - if (hook (lv->fullname, hook_data)) - return 1; - } - } - - return 0; -} - -#ifdef GRUB_UTIL -static grub_disk_memberlist_t -grub_diskfilter_memberlist (grub_disk_t disk) -{ - struct grub_diskfilter_lv *lv = disk->data; - grub_disk_memberlist_t list = NULL, tmp; - struct grub_diskfilter_pv *pv; - grub_disk_pull_t pull; - grub_disk_dev_t p; - struct grub_diskfilter_vg *vg; - struct grub_diskfilter_lv *lv2 = NULL; - struct grub_diskfilter_segment *seg; - unsigned int i, j; - - if (!lv->vg->pvs) - return NULL; - - pv = lv->vg->pvs; - while (pv && pv->disk) - pv = pv->next; - - for (pull = 0; pv && pull < GRUB_DISK_PULL_MAX; pull++) - for (p = grub_disk_dev_list; pv && p; p = p->next) - if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID - && p->disk_iterate) - { - (p->disk_iterate) (scan_disk_hook, NULL, pull); - while (pv && pv->disk) - pv = pv->next; - } - - for (vg = array_list; pv && vg; vg = vg->next) - { - if (vg->lvs) - for (lv2 = vg->lvs; pv && lv2; lv2 = lv2->next) - if (!lv2->scanned && lv2->fullname && lv2->became_readable_at) - { - scan_disk (lv2->fullname, 1); - lv2->scanned = 1; - while (pv && pv->disk) - pv = pv->next; - } - } - - for (i = 0, seg = lv->segments; i < lv->segment_count; i++, seg++) - for (j = 0; j < seg->node_count; ++j) - if (seg->nodes[j].pv != NULL) - { - pv = seg->nodes[j].pv; - - if (pv->disk == NULL) - { - /* - * TRANSLATORS: This message kicks in during the detection of - * which modules needs to be included in core image. This happens - * in the case of degraded RAID and means that autodetection may - * fail to include some of modules. It's an installation time - * message, not runtime message. - */ - grub_util_warn (_("Couldn't find physical volume `%s'." - " Some modules may be missing from core image."), - pv->name); - continue; - } - - for (tmp = list; tmp != NULL; tmp = tmp->next) - if (!grub_strcmp (tmp->disk->name, pv->disk->name)) - break; - if (tmp != NULL) - continue; - - tmp = grub_malloc (sizeof (*tmp)); - if (tmp == NULL) - goto fail; - tmp->disk = pv->disk; - tmp->next = list; - list = tmp; - } - - return list; - - fail: - while (list != NULL) - { - tmp = list; - list = list->next; - grub_free (tmp); - } - - return NULL; -} - -void -grub_diskfilter_get_partmap (grub_disk_t disk, - void (*cb) (const char *pm, void *data), - void *data) -{ - struct grub_diskfilter_lv *lv = disk->data; - struct grub_diskfilter_pv *pv; - - if (lv->vg->pvs) - for (pv = lv->vg->pvs; pv; pv = pv->next) - { - grub_size_t s; - if (!pv->disk) - { - /* TRANSLATORS: This message kicks in during the detection of - which modules needs to be included in core image. This happens - in the case of degraded RAID and means that autodetection may - fail to include some of modules. It's an installation time - message, not runtime message. */ - grub_util_warn (_("Couldn't find physical volume `%s'." - " Some modules may be missing from core image."), - pv->name); - continue; - } - for (s = 0; pv->partmaps[s]; s++) - cb (pv->partmaps[s], data); - } -} - -static const char * -grub_diskfilter_getname (struct grub_disk *disk) -{ - struct grub_diskfilter_lv *array = disk->data; - - return array->vg->driver->name; -} -#endif - -static inline char -hex2ascii (int c) -{ - if (c >= 10) - return 'a' + c - 10; - return c + '0'; -} - -static struct grub_diskfilter_lv * -find_lv (const char *name) -{ - struct grub_diskfilter_vg *vg; - struct grub_diskfilter_lv *lv = NULL; - - for (vg = array_list; vg; vg = vg->next) - { - if (vg->lvs) - for (lv = vg->lvs; lv; lv = lv->next) - if (((lv->fullname && grub_strcmp (lv->fullname, name) == 0) - || (lv->idname && grub_strcmp (lv->idname, name) == 0)) - && is_lv_readable (lv, 0)) - return lv; - } - return NULL; -} - -static grub_err_t -grub_diskfilter_open (const char *name, grub_disk_t disk) -{ - struct grub_diskfilter_lv *lv; - - if (!is_valid_diskfilter_name (name)) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown DISKFILTER device %s", - name); - - lv = find_lv (name); - - if (! lv) - { - scan_devices (name); - if (grub_errno) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - } - lv = find_lv (name); - } - - if (!lv) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown DISKFILTER device %s", - name); - - disk->id = lv->number; - disk->data = lv; - - disk->total_sectors = lv->size; - disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE; - return 0; -} - -static void -grub_diskfilter_close (grub_disk_t disk __attribute ((unused))) -{ - return; -} - -static grub_err_t -read_lv (struct grub_diskfilter_lv *lv, grub_disk_addr_t sector, - grub_size_t size, char *buf); - -grub_err_t -grub_diskfilter_read_node (const struct grub_diskfilter_node *node, - grub_disk_addr_t sector, - grub_size_t size, char *buf) -{ - /* Check whether we actually know the physical volume we want to - read from. */ - if (node->pv) - { - if (node->pv->disk) - return grub_disk_read (node->pv->disk, sector + node->start - + node->pv->start_sector, - 0, size << GRUB_DISK_SECTOR_BITS, buf); - else - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - N_("physical volume %s not found"), node->pv->name); - - } - if (node->lv) - return read_lv (node->lv, sector + node->start, size, buf); - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown node '%s'", node->name); -} - - -static grub_err_t -validate_segment (struct grub_diskfilter_segment *seg); - -static grub_err_t -validate_lv (struct grub_diskfilter_lv *lv) -{ - unsigned int i; - if (!lv) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown volume"); - - if (!lv->vg || lv->vg->extent_size == 0) - return grub_error (GRUB_ERR_READ_ERROR, "invalid volume"); - - for (i = 0; i < lv->segment_count; i++) - { - grub_err_t err; - err = validate_segment (&lv->segments[i]); - if (err) - return err; - } - return GRUB_ERR_NONE; -} - - -static grub_err_t -validate_node (const struct grub_diskfilter_node *node) -{ - /* Check whether we actually know the physical volume we want to - read from. */ - if (node->pv) - return GRUB_ERR_NONE; - if (node->lv) - return validate_lv (node->lv); - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown node '%s'", node->name); -} - -static grub_err_t -validate_segment (struct grub_diskfilter_segment *seg) -{ - grub_err_t err; - - if (seg->stripe_size == 0 || seg->node_count == 0) - return grub_error(GRUB_ERR_BAD_FS, "invalid segment"); - - switch (seg->type) - { - case GRUB_DISKFILTER_RAID10: - { - grub_uint8_t near, far; - near = seg->layout & 0xFF; - far = (seg->layout >> 8) & 0xFF; - if ((seg->layout >> 16) == 0 && far == 0) - return grub_error(GRUB_ERR_BAD_FS, "invalid segment"); - if (near > seg->node_count) - return grub_error(GRUB_ERR_BAD_FS, "invalid segment"); - break; - } - - case GRUB_DISKFILTER_STRIPED: - case GRUB_DISKFILTER_MIRROR: - break; - - case GRUB_DISKFILTER_RAID4: - case GRUB_DISKFILTER_RAID5: - if (seg->node_count <= 1) - return grub_error(GRUB_ERR_BAD_FS, "invalid segment"); - break; - - case GRUB_DISKFILTER_RAID6: - if (seg->node_count <= 2) - return grub_error(GRUB_ERR_BAD_FS, "invalid segment"); - break; - - default: - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported RAID level %d", seg->type); - } - - unsigned i; - for (i = 0; i < seg->node_count; i++) - { - err = validate_node (&seg->nodes[i]); - if (err) - return err; - } - return GRUB_ERR_NONE; - -} - -static grub_err_t -read_segment (struct grub_diskfilter_segment *seg, grub_disk_addr_t sector, - grub_size_t size, char *buf) -{ - grub_err_t err; - switch (seg->type) - { - case GRUB_DISKFILTER_STRIPED: - if (seg->node_count == 1) - return grub_diskfilter_read_node (&seg->nodes[0], - sector, size, buf); - /* Fallthrough. */ - case GRUB_DISKFILTER_MIRROR: - case GRUB_DISKFILTER_RAID10: - { - grub_disk_addr_t read_sector, far_ofs; - grub_uint64_t disknr, b, near, far, ofs; - unsigned int i, j; - - read_sector = grub_divmod64 (sector, seg->stripe_size, &b); - far = ofs = near = 1; - far_ofs = 0; - - if (seg->type == 1) - near = seg->node_count; - else if (seg->type == 10) - { - near = seg->layout & 0xFF; - far = (seg->layout >> 8) & 0xFF; - if (seg->layout >> 16) - { - ofs = far; - far_ofs = 1; - } - else - far_ofs = grub_divmod64 (seg->raid_member_size, - far * seg->stripe_size, 0); - - far_ofs *= seg->stripe_size; - } - - read_sector = grub_divmod64 (read_sector * near, - seg->node_count, - &disknr); - - ofs *= seg->stripe_size; - read_sector *= ofs; - - while (1) - { - grub_size_t read_size; - - read_size = seg->stripe_size - b; - if (read_size > size) - read_size = size; - - err = 0; - for (i = 0; i < near; i++) - { - unsigned int k; - - k = disknr; - err = 0; - for (j = 0; j < far; j++) - { - if (grub_errno == GRUB_ERR_READ_ERROR - || grub_errno == GRUB_ERR_UNKNOWN_DEVICE) - grub_errno = GRUB_ERR_NONE; - - err = grub_diskfilter_read_node (&seg->nodes[k], - read_sector - + j * far_ofs + b, - read_size, - buf); - if (! err) - break; - else if (err != GRUB_ERR_READ_ERROR - && err != GRUB_ERR_UNKNOWN_DEVICE) - return err; - k++; - if (k == seg->node_count) - k = 0; - } - - if (! err) - break; - - disknr++; - if (disknr == seg->node_count) - { - disknr = 0; - read_sector += ofs; - } - } - - if (err) - return err; - - buf += read_size << GRUB_DISK_SECTOR_BITS; - size -= read_size; - if (! size) - return GRUB_ERR_NONE; - - b = 0; - disknr += (near - i); - while (disknr >= seg->node_count) - { - disknr -= seg->node_count; - read_sector += ofs; - } - } - } - - case GRUB_DISKFILTER_RAID4: - case GRUB_DISKFILTER_RAID5: - case GRUB_DISKFILTER_RAID6: - { - grub_disk_addr_t read_sector; - grub_uint64_t b, p, n, disknr; - - /* n = 1 for level 4 and 5, 2 for level 6. */ - n = seg->type / 3; - - /* Find the first sector to read. */ - read_sector = grub_divmod64 (sector, seg->stripe_size, &b); - read_sector = grub_divmod64 (read_sector, seg->node_count - n, - &disknr); - if (seg->type >= 5) - { - grub_divmod64 (read_sector, seg->node_count, &p); - - if (! (seg->layout & GRUB_RAID_LAYOUT_RIGHT_MASK)) - p = seg->node_count - 1 - p; - - if (seg->layout & GRUB_RAID_LAYOUT_SYMMETRIC_MASK) - { - disknr += p + n; - } - else - { - grub_uint32_t q; - - q = p + (n - 1); - if (q >= seg->node_count) - q -= seg->node_count; - - if (disknr >= p) - disknr += n; - else if (disknr >= q) - disknr += q + 1; - } - - if (disknr >= seg->node_count) - disknr -= seg->node_count; - } - else - p = seg->node_count - n; - read_sector *= seg->stripe_size; - - while (1) - { - grub_size_t read_size; - int next_level; - - read_size = seg->stripe_size - b; - if (read_size > size) - read_size = size; - - /* Reset read error. */ - if (grub_errno == GRUB_ERR_READ_ERROR - || grub_errno == GRUB_ERR_UNKNOWN_DEVICE) - grub_errno = GRUB_ERR_NONE; - - err = grub_diskfilter_read_node (&seg->nodes[disknr], - read_sector + b, - read_size, - buf); - - if ((err) && (err != GRUB_ERR_READ_ERROR - && err != GRUB_ERR_UNKNOWN_DEVICE)) - return err; - - if (err) - { - grub_errno = GRUB_ERR_NONE; - if (seg->type == GRUB_DISKFILTER_RAID6) - { - err = ((grub_raid6_recover_func) ? - (*grub_raid6_recover_func) (seg, disknr, p, - buf, read_sector + b, - read_size) : - grub_error (GRUB_ERR_BAD_DEVICE, - N_("module `%s' isn't loaded"), - "raid6rec")); - } - else - { - err = ((grub_raid5_recover_func) ? - (*grub_raid5_recover_func) (seg, disknr, - buf, read_sector + b, - read_size) : - grub_error (GRUB_ERR_BAD_DEVICE, - N_("module `%s' isn't loaded"), - "raid5rec")); - } - - if (err) - return err; - } - - buf += read_size << GRUB_DISK_SECTOR_BITS; - size -= read_size; - sector += read_size; - if (! size) - break; - - b = 0; - disknr++; - - if (seg->layout & GRUB_RAID_LAYOUT_SYMMETRIC_MASK) - { - if (disknr == seg->node_count) - disknr = 0; - - next_level = (disknr == p); - } - else - { - if (disknr == p) - disknr += n; - - next_level = (disknr >= seg->node_count); - } - - if (next_level) - { - read_sector += seg->stripe_size; - - if (seg->type >= 5) - { - if (seg->layout & GRUB_RAID_LAYOUT_RIGHT_MASK) - p = (p == seg->node_count - 1) ? 0 : p + 1; - else - p = (p == 0) ? seg->node_count - 1 : p - 1; - - if (seg->layout & GRUB_RAID_LAYOUT_SYMMETRIC_MASK) - { - disknr = p + n; - if (disknr >= seg->node_count) - disknr -= seg->node_count; - } - else - { - disknr -= seg->node_count; - if ((disknr >= p && disknr < p + n) - || (disknr + seg->node_count >= p - && disknr + seg->node_count < p + n)) - disknr = p + n; - if (disknr >= seg->node_count) - disknr -= seg->node_count; - } - } - else - disknr = 0; - } - } - } - return GRUB_ERR_NONE; - default: - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported RAID level %d", seg->type); - } -} - -static grub_err_t -read_lv (struct grub_diskfilter_lv *lv, grub_disk_addr_t sector, - grub_size_t size, char *buf) -{ - if (!lv) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown volume"); - - while (size) - { - grub_err_t err = 0; - struct grub_diskfilter_vg *vg = lv->vg; - struct grub_diskfilter_segment *seg = lv->segments; - grub_uint64_t extent; - grub_uint64_t to_read; - - extent = grub_divmod64 (sector, vg->extent_size, NULL); - - /* Find the right segment. */ - { - unsigned int i; - for (i = 0; i < lv->segment_count; i++) - { - if ((seg->start_extent <= extent) - && ((seg->start_extent + seg->extent_count) > extent)) - break; - seg++; - } - if (i == lv->segment_count) - return grub_error (GRUB_ERR_READ_ERROR, "incorrect segment"); - } - to_read = ((seg->start_extent + seg->extent_count) - * vg->extent_size) - sector; - if (to_read > size) - to_read = size; - - err = read_segment (seg, sector - seg->start_extent * vg->extent_size, - to_read, buf); - if (err) - return err; - - size -= to_read; - sector += to_read; - buf += to_read << GRUB_DISK_SECTOR_BITS; - } - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_diskfilter_read (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, char *buf) -{ - return read_lv (disk->data, sector, size, buf); -} - -static grub_err_t -grub_diskfilter_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_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "diskfilter writes are not supported"); -} - -struct grub_diskfilter_vg * -grub_diskfilter_get_vg_by_uuid (grub_size_t uuidlen, char *uuid) -{ - struct grub_diskfilter_vg *p; - - for (p = array_list; p != NULL; p = p->next) - if ((p->uuid_len == uuidlen) && - (! grub_memcmp (p->uuid, uuid, p->uuid_len))) - return p; - return NULL; -} - -grub_err_t -grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg) -{ - struct grub_diskfilter_lv *lv, *p; - struct grub_diskfilter_vg *vgp; - unsigned i; - - grub_dprintf ("diskfilter", "Found array %s\n", vg->name); -#ifdef GRUB_UTIL - grub_util_info ("Found array %s", vg->name); -#endif - - for (lv = vg->lvs; lv; lv = lv->next) - { - /* RAID 1 and single-disk RAID 0 don't use a chunksize but code - assumes one so set one. */ - for (i = 0; i < lv->segment_count; i++) - { - if (lv->segments[i].type == 1) - lv->segments[i].stripe_size = 64; - if (lv->segments[i].type == GRUB_DISKFILTER_STRIPED - && lv->segments[i].node_count == 1 - && lv->segments[i].stripe_size == 0) - lv->segments[i].stripe_size = 64; - } - } - for (lv = vg->lvs; lv; lv = lv->next) - { - grub_err_t err; - - err = validate_lv(lv); - if (err) - return err; - lv->number = lv_num++; - - if (lv->fullname) - { - grub_size_t len; - int max_used_number = 0, need_new_name = 0; - len = grub_strlen (lv->fullname); - for (vgp = array_list; vgp; vgp = vgp->next) - for (p = vgp->lvs; p; p = p->next) - { - int cur_num; - char *num; - const char *end; - if (!p->fullname) - continue; - if (grub_strncmp (p->fullname, lv->fullname, len) != 0) - continue; - if (p->fullname[len] == 0) - { - need_new_name = 1; - continue; - } - num = p->fullname + len + 1; - if (!grub_isdigit (num[0])) - continue; - cur_num = grub_strtoul (num, &end, 10); - if (end[0]) - continue; - if (cur_num > max_used_number) - max_used_number = cur_num; - } - if (need_new_name) - { - char *tmp; - tmp = grub_xasprintf ("%s_%d", lv->fullname, max_used_number + 1); - if (!tmp) - return grub_errno; - grub_free (lv->fullname); - lv->fullname = tmp; - } - } - } - /* Add our new array to the list. */ - vg->next = array_list; - array_list = vg; - return GRUB_ERR_NONE; -} - -struct grub_diskfilter_vg * -grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb, - const char *name, grub_uint64_t disk_size, - grub_uint64_t stripe_size, - int layout, int level) -{ - struct grub_diskfilter_vg *array; - int i; - grub_size_t j, sz; - grub_uint64_t totsize; - struct grub_diskfilter_pv *pv; - grub_err_t err; - - /* We choose not to support more than the specified number of disks. */ - if (nmemb < 1 || nmemb > GRUB_MDRAID_MAX_DISKS) - { - grub_free (uuid); - return NULL; - } - - switch (level) - { - case 1: - totsize = disk_size; - break; - - case 10: - { - int n; - n = layout & 0xFF; - if (n == 1) - n = (layout >> 8) & 0xFF; - if (n == 0) - { - grub_free (uuid); - return NULL; - } - - totsize = grub_divmod64 (nmemb * disk_size, n, 0); - } - break; - - case 0: - case 4: - case 5: - case 6: - totsize = (nmemb - ((unsigned) level / 3U)) * disk_size; - break; - - default: - grub_free (uuid); - return NULL; - } - - array = grub_diskfilter_get_vg_by_uuid (uuidlen, uuid); - if (array) - { - if (array->lvs && array->lvs->size < totsize) - { - array->lvs->size = totsize; - if (array->lvs->segments) - array->lvs->segments->extent_count = totsize; - } - - if (array->lvs && array->lvs->segments - && array->lvs->segments->raid_member_size > disk_size) - array->lvs->segments->raid_member_size = disk_size; - - grub_free (uuid); - return array; - } - array = grub_zalloc (sizeof (*array)); - if (!array) - { - grub_free (uuid); - return NULL; - } - array->uuid = uuid; - array->uuid_len = uuidlen; - if (name) - { - /* Strip off the homehost if present. */ - char *colon = grub_strchr (name, ':'); - char *new_name = grub_xasprintf ("md/%s", - colon ? colon + 1 : name); - - if (! new_name) - goto fail; - - array->name = new_name; - } - - array->extent_size = 1; - array->lvs = grub_zalloc (sizeof (*array->lvs)); - if (!array->lvs) - goto fail; - array->lvs->segment_count = 1; - array->lvs->visible = 1; - if (array->name) - { - array->lvs->name = grub_strdup (array->name); - if (!array->lvs->name) - goto fail; - array->lvs->fullname = grub_strdup (array->name); - if (!array->lvs->fullname) - goto fail; - } - array->lvs->vg = array; - - if (grub_mul (uuidlen, 2, &sz) || - grub_add (sz, sizeof ("mduuid/"), &sz)) - goto fail; - - array->lvs->idname = grub_malloc (sz); - if (!array->lvs->idname) - goto fail; - - grub_memcpy (array->lvs->idname, "mduuid/", sizeof ("mduuid/") - 1); - for (j = 0; j < uuidlen; j++) - { - array->lvs->idname[sizeof ("mduuid/") - 1 + 2 * j] - = hex2ascii (((unsigned char) uuid[j] >> 4)); - array->lvs->idname[sizeof ("mduuid/") - 1 + 2 * j + 1] - = hex2ascii (((unsigned char) uuid[j] & 0xf)); - } - array->lvs->idname[sizeof ("mduuid/") - 1 + 2 * uuidlen] = '\0'; - - array->lvs->size = totsize; - - array->lvs->segments = grub_zalloc (sizeof (*array->lvs->segments)); - if (!array->lvs->segments) - goto fail; - array->lvs->segments->stripe_size = stripe_size; - array->lvs->segments->layout = layout; - array->lvs->segments->start_extent = 0; - array->lvs->segments->extent_count = totsize; - array->lvs->segments->type = level; - array->lvs->segments->node_count = nmemb; - array->lvs->segments->raid_member_size = disk_size; - array->lvs->segments->nodes - = grub_calloc (nmemb, sizeof (array->lvs->segments->nodes[0])); - if (array->lvs->segments->nodes == NULL) - goto fail; - - array->lvs->segments->stripe_size = stripe_size; - for (i = 0; i < nmemb; i++) - { - pv = grub_zalloc (sizeof (*pv)); - if (!pv) - goto fail; - pv->id.uuidlen = 0; - pv->id.id = i; - pv->next = array->pvs; - array->pvs = pv; - array->lvs->segments->nodes[i].pv = pv; - } - - err = grub_diskfilter_vg_register (array); - if (err) - goto fail; - - return array; - - fail: - if (array->lvs) - { - grub_free (array->lvs->name); - grub_free (array->lvs->fullname); - grub_free (array->lvs->idname); - if (array->lvs->segments) - { - grub_free (array->lvs->segments->nodes); - grub_free (array->lvs->segments); - } - grub_free (array->lvs); - } - while (array->pvs) - { - pv = array->pvs->next; - grub_free (array->pvs); - array->pvs = pv; - } - grub_free (array->name); - grub_free (array->uuid); - grub_free (array); - return NULL; -} - -static grub_err_t -insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id, - struct grub_diskfilter_vg *array, - grub_disk_addr_t start_sector, - grub_diskfilter_t diskfilter __attribute__ ((unused))) -{ - struct grub_diskfilter_pv *pv; - - grub_dprintf ("diskfilter", "Inserting %s (+%lld,%lld) into %s (%s)\n", disk->name, - (unsigned long long) grub_partition_get_start (disk->partition), - (unsigned long long) grub_disk_native_sectors (disk), - array->name, diskfilter->name); -#ifdef GRUB_UTIL - grub_util_info ("Inserting %s (+%" GRUB_HOST_PRIuLONG_LONG ",%" - GRUB_HOST_PRIuLONG_LONG ") into %s (%s)\n", disk->name, - (unsigned long long) grub_partition_get_start (disk->partition), - (unsigned long long) grub_disk_native_sectors (disk), - array->name, diskfilter->name); - array->driver = diskfilter; -#endif - - for (pv = array->pvs; pv; pv = pv->next) - if (id->uuidlen == pv->id.uuidlen - && id->uuidlen - ? (grub_memcmp (pv->id.uuid, id->uuid, id->uuidlen) == 0) - : (pv->id.id == id->id)) - { - struct grub_diskfilter_lv *lv; - /* FIXME: Check whether the update time of the superblocks are - the same. */ - if (pv->disk && grub_disk_native_sectors (disk) >= pv->part_size) - return GRUB_ERR_NONE; - pv->disk = grub_disk_open (disk->name); - if (!pv->disk) - return grub_errno; - /* This could happen to LVM on RAID, pv->disk points to the - raid device, we shouldn't change it. */ - pv->start_sector -= pv->part_start; - pv->part_start = grub_partition_get_start (disk->partition); - pv->part_size = grub_disk_native_sectors (disk); - -#ifdef GRUB_UTIL - { - grub_size_t s = 1; - grub_partition_t p; - for (p = disk->partition; p; p = p->parent) - s++; - pv->partmaps = xcalloc (s, sizeof (pv->partmaps[0])); - s = 0; - for (p = disk->partition; p; p = p->parent) - pv->partmaps[s++] = xstrdup (p->partmap->name); - pv->partmaps[s++] = 0; - } -#endif - if (start_sector != (grub_uint64_t)-1) - pv->start_sector = start_sector; - pv->start_sector += pv->part_start; - /* Add the device to the array. */ - for (lv = array->lvs; lv; lv = lv->next) - if (!lv->became_readable_at && lv->fullname && is_lv_readable (lv, 0)) - lv->became_readable_at = ++inscnt; - break; - } - - return 0; -} - -static void -free_array (void) -{ - while (array_list) - { - struct grub_diskfilter_vg *vg; - struct grub_diskfilter_pv *pv; - struct grub_diskfilter_lv *lv; - - vg = array_list; - array_list = array_list->next; - - while ((pv = vg->pvs)) - { - vg->pvs = pv->next; - grub_free (pv->name); - if (pv->disk) - grub_disk_close (pv->disk); - if (pv->id.uuidlen) - grub_free (pv->id.uuid); -#ifdef GRUB_UTIL - grub_free (pv->partmaps); -#endif - grub_free (pv->internal_id); - grub_free (pv); - } - - while ((lv = vg->lvs)) - { - unsigned i; - vg->lvs = lv->next; - grub_free (lv->fullname); - grub_free (lv->name); - grub_free (lv->idname); - for (i = 0; i < lv->segment_count; i++) - grub_free (lv->segments[i].nodes); - grub_free (lv->segments); - grub_free (lv->internal_id); - grub_free (lv); - } - - grub_free (vg->uuid); - grub_free (vg->name); - grub_free (vg); - } - - array_list = 0; -} - -#ifdef GRUB_UTIL -struct grub_diskfilter_pv * -grub_diskfilter_get_pv_from_disk (grub_disk_t disk, - struct grub_diskfilter_vg **vg_out) -{ - struct grub_diskfilter_pv *pv; - struct grub_diskfilter_vg *vg; - - scan_disk (disk->name, 1); - for (vg = array_list; vg; vg = vg->next) - for (pv = vg->pvs; pv; pv = pv->next) - { - if (pv->disk && pv->disk->id == disk->id - && pv->disk->dev->id == disk->dev->id - && pv->part_start == grub_partition_get_start (disk->partition) - && pv->part_size == grub_disk_native_sectors (disk)) - { - if (vg_out) - *vg_out = vg; - return pv; - } - } - return NULL; -} -#endif - -static int -grub_diskfilter_check_pvs_encrypted (grub_disk_t disk, int *pvs_cnt) -{ - struct grub_diskfilter_lv *lv = disk->data; - struct grub_diskfilter_pv *pv; - - *pvs_cnt = 0; - - if (lv->vg->pvs) - for (pv = lv->vg->pvs; pv; pv = pv->next) - { - (*pvs_cnt)++; - - if (pv->disk == NULL) - { - /* Can be a partially activated VG, bail out. */ - return GRUB_ERR_TEST_FAILURE; - } - - if (pv->disk->dev->id != GRUB_DISK_DEVICE_CRYPTODISK_ID) - { - /* All backing devices must be cryptodisks, stop. */ - return GRUB_ERR_TEST_FAILURE; - } - } - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_cryptocheck (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) -{ - grub_disk_t disk; - int check_pvs_res; - int namelen; - int pvs_cnt; - int opt_quiet = 0; - - if (argc == 2) - { - if (grub_strcmp (args[0], "--quiet") == 0) - { - opt_quiet = 1; - argc--; - args++; - } - else - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unrecognized option: %s"), args[0]); - } - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("disk name expected")); - - namelen = grub_strlen (args[0]); - if (namelen > 2 && (args[0][0] == '(') && (args[0][namelen - 1] == ')')) - args[0][namelen - 1] = 0; - else - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("invalid disk: %s"), - args[0]); - - if (!is_valid_diskfilter_name (&args[0][1])) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("unrecognized disk: %s"), - &args[0][1]); - - disk = grub_disk_open (&args[0][1]); - if (disk == NULL) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("no such disk: %s"), - &args[0][1]); - - check_pvs_res = grub_diskfilter_check_pvs_encrypted (disk, &pvs_cnt); - grub_disk_close (disk); - if (!opt_quiet) - grub_printf ("%s is %sencrypted (%d pv%s examined)\n", &args[0][1], - (check_pvs_res == GRUB_ERR_NONE) ? "" : "un", - pvs_cnt, - (pvs_cnt > 1) ? "s" : ""); - - return check_pvs_res; -} - -static struct grub_disk_dev grub_diskfilter_dev = - { - .name = "diskfilter", - .id = GRUB_DISK_DEVICE_DISKFILTER_ID, - .disk_iterate = grub_diskfilter_iterate, - .disk_open = grub_diskfilter_open, - .disk_close = grub_diskfilter_close, - .disk_read = grub_diskfilter_read, - .disk_write = grub_diskfilter_write, -#ifdef GRUB_UTIL - .disk_memberlist = grub_diskfilter_memberlist, - .disk_raidname = grub_diskfilter_getname, -#endif - .next = 0 - }; - -static grub_command_t cmd; - - -GRUB_MOD_INIT(diskfilter) -{ - grub_disk_dev_register (&grub_diskfilter_dev); - cmd = grub_register_command ("cryptocheck", grub_cmd_cryptocheck, - N_("[--quiet] DEVICE"), - N_("Check if a logical volume resides on encrypted disks.")); -} - -GRUB_MOD_FINI(diskfilter) -{ - grub_disk_dev_unregister (&grub_diskfilter_dev); - if (cmd != NULL) - grub_unregister_command (cmd); - free_array (); -} diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c deleted file mode 100644 index 3b5ed5691..000000000 --- a/grub-core/disk/efi/efidisk.c +++ /dev/null @@ -1,912 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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; - struct grub_efidisk_data *next; -}; - -/* GUID. */ -static grub_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; - -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, &block_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; - - dp = grub_efi_get_device_path (*handle); - if (! dp) - continue; - - ldp = grub_efi_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); - if (! bio) - /* This should not happen... Why? */ - continue; - - /* iPXE adds stub Block IO protocol to loaded image device handle. It is - completely non-functional and simply returns an error for every method. - So attempt to detect and skip it. Magic number is literal "iPXE" and - check block size as well */ - /* FIXME: shoud we close it? We do not do it elsewhere */ - if (bio->media && bio->media->media_id == 0x69505845U && - bio->media->block_size == 1) - continue; - - d = grub_malloc (sizeof (*d)); - if (! d) - { - /* Uggh. */ - grub_free (handles); - while (devices) - { - d = devices->next; - grub_free (devices); - devices = d; - } - return 0; - } - - d->handle = *handle; - d->device_path = dp; - d->last_device_path = ldp; - d->block_io = bio; - 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 = grub_efi_duplicate_device_path (d->device_path); - if (! dp) - return 0; - - ldp = grub_efi_find_last_device_path (dp); - if (! ldp) - return 0; - - ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; - ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; - ldp->length = sizeof (*ldp); - - for (parent = devices; parent; parent = parent->next) - { - /* Ignore itself. */ - if (parent == d) - continue; - - if (grub_efi_compare_device_paths (parent->device_path, dp) == 0) - break; - } - - grub_free (dp); - return parent; -} - -static int -is_child (struct grub_efidisk_data *child, - struct grub_efidisk_data *parent) -{ - grub_efi_device_path_t *dp, *ldp; - int ret; - - dp = grub_efi_duplicate_device_path (child->device_path); - if (! dp) - return 0; - - ldp = grub_efi_find_last_device_path (dp); - if (! ldp) - return 0; - - ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; - ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; - ldp->length = sizeof (*ldp); - - ret = (grub_efi_compare_device_paths (dp, parent->device_path) == 0); - grub_free (dp); - return ret; -} - -#define FOR_CHILDREN(p, dev) for (p = dev; p; p = p->next) if (is_child (p, d)) - -/* 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 = grub_efi_compare_device_paths (grub_efi_find_last_device_path ((*p)->device_path), - grub_efi_find_last_device_path (d->device_path)); - if (ret == 0) - ret = grub_efi_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; - /* Intentionally fall through. */ - case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE: - { - struct grub_efidisk_data *parent, *parent2; - - parent = find_parent_device (devices, d); - if (!parent) - { -#ifdef DEBUG_NAMES - grub_printf ("skipping orphaned partition: "); - grub_efi_print_device_path (d->device_path); -#endif - break; - } - parent2 = find_parent_device (devices, parent); - if (parent2) - { -#ifdef DEBUG_NAMES - grub_printf ("skipping subpartition: "); - grub_efi_print_device_path (d->device_path); -#endif - /* Mark itself as used. */ - d->last_device_path = 0; - break; - } - if (!parent->last_device_path) - { - d->last_device_path = 0; - break; - } - if (is_hard_drive) - { -#ifdef DEBUG_NAMES - grub_printf ("adding a hard drive by a partition: "); - grub_efi_print_device_path (parent->device_path); -#endif - add_device (&hd_devices, parent); - } - else - { -#ifdef DEBUG_NAMES - grub_printf ("adding a cdrom by a partition: "); - grub_efi_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: -#ifdef DEBUG_NAMES - grub_printf ("skipping other type: "); - grub_efi_print_device_path (d->device_path); -#endif - /* For now, ignore the others. */ - break; - } - } - else - { -#ifdef DEBUG_NAMES - grub_printf ("skipping non-media: "); - grub_efi_print_device_path (d->device_path); -#endif - } - } - - /* 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; - int is_floppy = 0; - - dp = d->last_device_path; - if (! dp) - continue; - - /* Ghosts proudly presented by Apple. */ - if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE - && GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) - == GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE) - { - grub_efi_vendor_device_path_t *vendor = (grub_efi_vendor_device_path_t *) dp; - static const grub_guid_t apple = GRUB_EFI_VENDOR_APPLE_GUID; - - if (vendor->header.length == sizeof (*vendor) - && grub_memcmp (&vendor->vendor_guid, &apple, - sizeof (vendor->vendor_guid)) == 0 - && find_parent_device (devices, d)) - continue; - } - - m = d->block_io->media; - if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_ACPI_DEVICE_PATH_TYPE - && GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) - == GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE) - { - grub_efi_acpi_device_path_t *acpi - = (grub_efi_acpi_device_path_t *) dp; - /* Floppy EISA ID. */ - if (acpi->hid == 0x60441d0 || acpi->hid == 0x70041d0 - || acpi->hid == 0x70141d1) - is_floppy = 1; - } - if (is_floppy) - { -#ifdef DEBUG_NAMES - grub_printf ("adding a floppy: "); - grub_efi_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. */ -#ifdef DEBUG_NAMES - grub_printf ("adding a cdrom by guessing: "); - grub_efi_print_device_path (d->device_path); -#endif - add_device (&cd_devices, d); - } - else - { - /* The default is a hard drive. */ -#ifdef DEBUG_NAMES - grub_printf ("adding a hard drive by guessing: "); - grub_efi_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 (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - struct grub_efidisk_data *d; - char buf[16]; - int count; - - switch (pull) - { - case GRUB_DISK_PULL_NONE: - 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, hook_data)) - return 1; - } - break; - case GRUB_DISK_PULL_REMOVABLE: - 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, hook_data)) - 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, hook_data)) - return 1; - } - break; - default: - return 0; - } - - 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': - d = get_device (fd_devices, num); - break; - case 'c': - d = get_device (cd_devices, num); - break; - case 'h': - 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 << GRUB_CHAR_BIT) | 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, io align = %x\n", - m, (unsigned long long) m->last_block, m->block_size, - m->io_align); - - /* Ensure required buffer alignment is a power of two (or is zero). */ - if (m->io_align & (m->io_align - 1)) - return grub_error (GRUB_ERR_IO, "invalid buffer alignment %d", m->io_align); - - disk->total_sectors = m->last_block + 1; - /* Don't increase this value due to bug in some EFI. */ - disk->max_agglomerate = 0xa0000 >> (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS); - if (m->block_size & (m->block_size - 1) || !m->block_size) - return grub_error (GRUB_ERR_IO, "invalid sector size %d", - m->block_size); - disk->log_sector_size = grub_log2ull (m->block_size); - 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_efi_status_t -grub_efidisk_readwrite (struct grub_disk *disk, grub_disk_addr_t sector, - grub_size_t size, char *buf, int wr) -{ - struct grub_efidisk_data *d; - grub_efi_block_io_t *bio; - grub_efi_status_t status; - grub_size_t io_align, num_bytes; - char *aligned_buf; - - d = disk->data; - bio = d->block_io; - - /* - * If IoAlign is > 1, it should represent the required alignment. However, - * some UEFI implementations seem to report IoAlign=2 but require 2^IoAlign. - * Some implementation seem to require alignment despite not reporting any - * specific requirements. - * - * Make sure to use buffers which are at least aligned to block size. - */ - if (bio->media->io_align < bio->media->block_size) - io_align = bio->media->block_size; - else - io_align = bio->media->io_align; - - num_bytes = size << disk->log_sector_size; - - if ((grub_addr_t) buf & (io_align - 1)) - { - aligned_buf = grub_memalign (io_align, num_bytes); - if (! aligned_buf) - return GRUB_EFI_OUT_OF_RESOURCES; - if (wr) - grub_memcpy (aligned_buf, buf, num_bytes); - } - else - { - aligned_buf = buf; - } - - status = (wr ? bio->write_blocks : bio->read_blocks) (bio, bio->media->media_id, - (grub_efi_uint64_t) sector, - (grub_efi_uintn_t) num_bytes, - aligned_buf); - - if ((grub_addr_t) buf & (io_align - 1)) - { - if (!wr) - grub_memcpy (buf, aligned_buf, num_bytes); - grub_free (aligned_buf); - } - - return status; -} - -static grub_err_t -grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector, - grub_size_t size, char *buf) -{ - grub_efi_status_t status; - - 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 = grub_efidisk_readwrite (disk, sector, size, buf, 0); - - if (status == GRUB_EFI_NO_MEDIA) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("no media in `%s'"), disk->name); - else if (status != GRUB_EFI_SUCCESS) - return grub_error (GRUB_ERR_READ_ERROR, - N_("failure reading sector 0x%llx from `%s'"), - (unsigned long long) sector, - disk->name); - - 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) -{ - grub_efi_status_t status; - - 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 = grub_efidisk_readwrite (disk, sector, size, (char *) buf, 1); - - if (status == GRUB_EFI_NO_MEDIA) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("no media in `%s'"), disk->name); - else if (status != GRUB_EFI_SUCCESS) - return grub_error (GRUB_ERR_WRITE_ERROR, - N_("failure writing sector 0x%llx to `%s'"), - (unsigned long long) sector, disk->name); - - return GRUB_ERR_NONE; -} - -static struct grub_disk_dev grub_efidisk_dev = - { - .name = "efidisk", - .id = GRUB_DISK_DEVICE_EFIDISK_ID, - .disk_iterate = grub_efidisk_iterate, - .disk_open = grub_efidisk_open, - .disk_close = grub_efidisk_close, - .disk_read = grub_efidisk_read, - .disk_write = grub_efidisk_write, - .next = 0 - }; - -void -grub_efidisk_fini (void) -{ - free_devices (fd_devices); - free_devices (hd_devices); - free_devices (cd_devices); - fd_devices = 0; - hd_devices = 0; - cd_devices = 0; - grub_disk_dev_unregister (&grub_efidisk_dev); -} - -void -grub_efidisk_init (void) -{ - grub_disk_firmware_fini = grub_efidisk_fini; - - enumerate_disks (); - grub_disk_dev_register (&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; - struct grub_efidisk_data *c; - - devices = make_devices (); - FOR_CHILDREN (c, devices) - { - grub_efi_hard_drive_device_path_t *hd; - - hd = (grub_efi_hard_drive_device_path_t *) c->last_device_path; - - 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 << (disk->log_sector_size - - GRUB_DISK_SECTOR_BITS))) - && (grub_partition_get_len (disk->partition) - == (hd->partition_size << (disk->log_sector_size - - GRUB_DISK_SECTOR_BITS)))) - { - handle = c->handle; - break; - } - } - - free_devices (devices); - - if (handle != 0) - return handle; - } - break; - - default: - break; - } - - return 0; -} - -#define NEEDED_BUFLEN sizeof ("XdXXXXXXXXXX") -static inline int -get_diskname_from_path_real (const grub_efi_device_path_t *path, - struct grub_efidisk_data *head, - char *buf) -{ - int count = 0; - struct grub_efidisk_data *d; - for (d = head, count = 0; d; d = d->next, count++) - if (grub_efi_compare_device_paths (d->device_path, path) == 0) - { - grub_snprintf (buf, NEEDED_BUFLEN - 1, "d%d", count); - return 1; - } - return 0; -} - -static inline int -get_diskname_from_path (const grub_efi_device_path_t *path, - char *buf) -{ - if (get_diskname_from_path_real (path, hd_devices, buf + 1)) - { - buf[0] = 'h'; - return 1; - } - - if (get_diskname_from_path_real (path, fd_devices, buf + 1)) - { - buf[0] = 'f'; - return 1; - } - - if (get_diskname_from_path_real (path, cd_devices, buf + 1)) - { - buf[0] = 'c'; - return 1; - } - return 0; -} - -/* Context for grub_efidisk_get_device_name. */ -struct grub_efidisk_get_device_name_ctx -{ - char *partition_name; - grub_efi_hard_drive_device_path_t *hd; -}; - -/* Helper for grub_efidisk_get_device_name. - Find the identical partition. */ -static int -grub_efidisk_get_device_name_iter (grub_disk_t disk, - const grub_partition_t part, void *data) -{ - struct grub_efidisk_get_device_name_ctx *ctx = data; - - if (grub_partition_get_start (part) - == (ctx->hd->partition_start << (disk->log_sector_size - - GRUB_DISK_SECTOR_BITS)) - && grub_partition_get_len (part) - == (ctx->hd->partition_size << (disk->log_sector_size - - GRUB_DISK_SECTOR_BITS))) - { - ctx->partition_name = grub_partition_get_name (part); - return 1; - } - - return 0; -} - -char * -grub_efidisk_get_device_name (grub_efi_handle_t *handle) -{ - grub_efi_device_path_t *dp, *ldp; - char device_name[NEEDED_BUFLEN]; - - dp = grub_efi_get_device_path (handle); - if (! dp) - return 0; - - ldp = grub_efi_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_CDROM_DEVICE_PATH_SUBTYPE - || GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)) - { - struct grub_efidisk_get_device_name_ctx ctx; - char *dev_name; - grub_efi_device_path_t *dup_dp; - grub_disk_t parent = 0; - - /* It is necessary to duplicate the device path so that GRUB - can overwrite it. */ - dup_dp = grub_efi_duplicate_device_path (dp); - if (! dup_dp) - return 0; - - while (1) - { - grub_efi_device_path_t *dup_ldp; - dup_ldp = grub_efi_find_last_device_path (dup_dp); - if (! dup_ldp) - break; - - if (!(GRUB_EFI_DEVICE_PATH_TYPE (dup_ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE - && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE - || GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))) - break; - - dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; - dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; - dup_ldp->length = sizeof (*dup_ldp); - } - - if (!get_diskname_from_path (dup_dp, device_name)) - { - grub_free (dup_dp); - return 0; - } - - parent = grub_disk_open (device_name); - grub_free (dup_dp); - - if (! parent) - return 0; - - /* Find a partition which matches the hard drive device path. */ - ctx.partition_name = NULL; - ctx.hd = (grub_efi_hard_drive_device_path_t *) ldp; - if (ctx.hd->partition_start == 0 - && (ctx.hd->partition_size << (parent->log_sector_size - - GRUB_DISK_SECTOR_BITS)) - == grub_disk_native_sectors (parent)) - { - dev_name = grub_strdup (parent->name); - } - else - { - grub_partition_iterate (parent, grub_efidisk_get_device_name_iter, - &ctx); - - if (! ctx.partition_name) - { - /* No partition found. In most cases partition is embed in - the root path anyway, so this is not critical. - This happens only if partition is on partmap that GRUB - doesn't need to access root. - */ - grub_disk_close (parent); - return grub_strdup (device_name); - } - - dev_name = grub_xasprintf ("%s,%s", parent->name, - ctx.partition_name); - grub_free (ctx.partition_name); - } - grub_disk_close (parent); - - return dev_name; - } - /* This may be guessed device - floppy, cdrom or entire disk. */ - if (!get_diskname_from_path (dp, device_name)) - return 0; - return grub_strdup (device_name); -} diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c deleted file mode 100644 index 722910d64..000000000 --- a/grub-core/disk/geli.c +++ /dev/null @@ -1,584 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2007,2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -/* This file is loosely based on FreeBSD geli implementation - (but no code was directly copied). FreeBSD geli is distributed under - following terms: */ -/*- - * Copyright (c) 2005-2006 Pawel Jakub Dawidek - * 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 AUTHORS 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 AUTHORS 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* Dirty trick to solve circular dependency. */ -#ifdef GRUB_UTIL - -#include - -#undef GRUB_MD_SHA256 -#undef GRUB_MD_SHA512 - -static const gcry_md_spec_t * -grub_md_sha256_real (void) -{ - const gcry_md_spec_t *ret; - ret = grub_crypto_lookup_md_by_name ("sha256"); - if (!ret) - grub_util_error ("%s", _("Couldn't load sha256")); - return ret; -} - -static const gcry_md_spec_t * -grub_md_sha512_real (void) -{ - const gcry_md_spec_t *ret; - ret = grub_crypto_lookup_md_by_name ("sha512"); - if (!ret) - grub_util_error ("%s", _("Couldn't load sha512")); - return ret; -} - -#define GRUB_MD_SHA256 grub_md_sha256_real() -#define GRUB_MD_SHA512 grub_md_sha512_real() -#endif - -struct grub_geli_key -{ - grub_uint8_t iv_key[64]; - grub_uint8_t cipher_key[64]; - grub_uint8_t hmac[64]; -} GRUB_PACKED; - -struct grub_geli_phdr -{ - grub_uint8_t magic[16]; -#define GELI_MAGIC "GEOM::ELI" - grub_uint32_t version; - grub_uint32_t flags; - grub_uint16_t alg; - grub_uint16_t keylen; - grub_uint16_t unused3[5]; - grub_uint32_t sector_size; - grub_uint8_t keys_used; - grub_uint32_t niter; - grub_uint8_t salt[64]; - struct grub_geli_key keys[2]; -} GRUB_PACKED; - -enum - { - GRUB_GELI_FLAGS_ONETIME = 1, - GRUB_GELI_FLAGS_BOOT = 2, - }; - -/* FIXME: support version 0. */ -/* FIXME: support big-endian pre-version-4 volumes. */ -/* FIXME: support for keyfiles. */ -/* FIXME: support for HMAC. */ -const char *algorithms[] = { - [0x01] = "des", - [0x02] = "3des", - [0x03] = "blowfish", - [0x04] = "cast5", - /* FIXME: 0x05 is skipjack, but we don't have it. */ - [0x0b] = "aes", - /* FIXME: 0x10 is null. */ - [0x15] = "camellia128", - [0x16] = "aes" -}; - -static gcry_err_code_t -geli_rekey (struct grub_cryptodisk *dev, grub_uint64_t zoneno) -{ - gcry_err_code_t gcry_err; - const struct { - char magic[4]; - grub_uint64_t zone; - } GRUB_PACKED tohash - = { {'e', 'k', 'e', 'y'}, grub_cpu_to_le64 (zoneno) }; - GRUB_PROPERLY_ALIGNED_ARRAY (key, GRUB_CRYPTO_MAX_MDLEN); - - if (dev->hash->mdlen > GRUB_CRYPTO_MAX_MDLEN) - return GPG_ERR_INV_ARG; - - grub_dprintf ("geli", "rekeying %" PRIuGRUB_UINT64_T " keysize=%d\n", - zoneno, dev->rekey_derived_size); - gcry_err = grub_crypto_hmac_buffer (dev->hash, dev->rekey_key, 64, - &tohash, sizeof (tohash), key); - if (gcry_err) - return gcry_err; - - return grub_cryptodisk_setkey (dev, (grub_uint8_t *) key, - dev->rekey_derived_size); -} - -static inline gcry_err_code_t -make_uuid (const struct grub_geli_phdr *header, - char *uuid) -{ - grub_uint8_t uuidbin[GRUB_CRYPTODISK_MAX_UUID_LENGTH]; - gcry_err_code_t err; - grub_uint8_t *iptr; - char *optr; - - if (2 * GRUB_MD_SHA256->mdlen + 1 > GRUB_CRYPTODISK_MAX_UUID_LENGTH) - return GPG_ERR_TOO_LARGE; - err = grub_crypto_hmac_buffer (GRUB_MD_SHA256, - header->salt, sizeof (header->salt), - "uuid", sizeof ("uuid") - 1, uuidbin); - if (err) - return err; - - optr = uuid; - for (iptr = uuidbin; iptr < &uuidbin[GRUB_MD_SHA256->mdlen]; iptr++) - { - grub_snprintf (optr, 3, "%02x", *iptr); - optr += 2; - } - *optr = 0; - return GPG_ERR_NO_ERROR; -} - -#ifdef GRUB_UTIL - -#include -#include - -char * -grub_util_get_geli_uuid (const char *dev) -{ - grub_util_fd_t fd; - grub_uint64_t s; - unsigned log_secsize; - grub_uint8_t hdr[512]; - struct grub_geli_phdr *header; - char *uuid; - gcry_err_code_t err; - - fd = grub_util_fd_open (dev, GRUB_UTIL_FD_O_RDONLY); - - if (!GRUB_UTIL_FD_IS_VALID (fd)) - return NULL; - - s = grub_util_get_fd_size (fd, dev, &log_secsize); - s >>= log_secsize; - if (grub_util_fd_seek (fd, (s << log_secsize) - 512) < 0) - grub_util_error ("%s", _("couldn't read ELI metadata")); - - uuid = xmalloc (GRUB_MD_SHA256->mdlen * 2 + 1); - if (grub_util_fd_read (fd, (void *) &hdr, 512) < 0) - grub_util_error ("%s", _("couldn't read ELI metadata")); - - grub_util_fd_close (fd); - - COMPILE_TIME_ASSERT (sizeof (header) <= 512); - header = (void *) &hdr; - - /* Look for GELI magic sequence. */ - if (grub_memcmp (header->magic, GELI_MAGIC, sizeof (GELI_MAGIC)) - || grub_le_to_cpu32 (header->version) > 7 - || grub_le_to_cpu32 (header->version) < 1) - grub_util_error ("%s", _("wrong ELI magic or version")); - - err = make_uuid ((void *) &hdr, uuid); - if (err) - { - grub_free (uuid); - return NULL; - } - - return uuid; -} -#endif - -static grub_cryptodisk_t -geli_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) -{ - grub_cryptodisk_t newdev; - struct grub_geli_phdr header; - grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL; - const struct gcry_cipher_spec *ciph; - const char *ciphername = NULL; - gcry_err_code_t gcry_err; - char uuid[GRUB_CRYPTODISK_MAX_UUID_LENGTH]; - grub_disk_addr_t sector; - grub_err_t err; - - /* Detached headers are not implemented yet */ - if (cargs->hdr_file != NULL) - return NULL; - - if (2 * GRUB_MD_SHA256->mdlen + 1 > GRUB_CRYPTODISK_MAX_UUID_LENGTH) - return NULL; - - sector = grub_disk_native_sectors (disk); - if (sector == GRUB_DISK_SIZE_UNKNOWN || sector == 0) - return NULL; - - /* Read the GELI header. */ - err = grub_disk_read (disk, sector - 1, 0, sizeof (header), &header); - if (err) - return NULL; - - /* Look for GELI magic sequence. */ - if (grub_memcmp (header.magic, GELI_MAGIC, sizeof (GELI_MAGIC)) - || grub_le_to_cpu32 (header.version) > 7 - || grub_le_to_cpu32 (header.version) < 1) - { - grub_dprintf ("geli", "wrong magic %02x\n", header.magic[0]); - return NULL; - } - - if ((grub_le_to_cpu32 (header.sector_size) - & (grub_le_to_cpu32 (header.sector_size) - 1)) - || grub_le_to_cpu32 (header.sector_size) == 0) - { - grub_dprintf ("geli", "incorrect sector size %d\n", - grub_le_to_cpu32 (header.sector_size)); - return NULL; - } - - if (grub_le_to_cpu32 (header.flags) & GRUB_GELI_FLAGS_ONETIME) - { - grub_dprintf ("geli", "skipping one-time volume\n"); - return NULL; - } - - if (cargs->check_boot && !(grub_le_to_cpu32 (header.flags) & GRUB_GELI_FLAGS_BOOT)) - { - grub_dprintf ("geli", "not a boot volume\n"); - return NULL; - } - - gcry_err = make_uuid (&header, uuid); - if (gcry_err) - { - grub_crypto_gcry_error (gcry_err); - return NULL; - } - - if (cargs->search_uuid != NULL && grub_uuidcasecmp (cargs->search_uuid, uuid, sizeof (uuid)) != 0) - { - grub_dprintf ("geli", "%s != %s\n", uuid, cargs->search_uuid); - return NULL; - } - - if (grub_le_to_cpu16 (header.alg) >= ARRAY_SIZE (algorithms) - || algorithms[grub_le_to_cpu16 (header.alg)] == NULL) - { - grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher 0x%x unknown", - grub_le_to_cpu16 (header.alg)); - return NULL; - } - - ciphername = algorithms[grub_le_to_cpu16 (header.alg)]; - ciph = grub_crypto_lookup_cipher_by_name (ciphername); - if (!ciph) - { - grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available", - ciphername); - return NULL; - } - - /* Configure the cipher used for the bulk data. */ - cipher = grub_crypto_cipher_open (ciph); - if (!cipher) - return NULL; - - if (grub_le_to_cpu16 (header.alg) == 0x16) - { - secondary_cipher = grub_crypto_cipher_open (ciph); - if (!secondary_cipher) - { - grub_crypto_cipher_close (cipher); - return NULL; - } - - } - - if (grub_le_to_cpu16 (header.keylen) > 1024) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d", - grub_le_to_cpu16 (header.keylen)); - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (secondary_cipher); - return NULL; - } - - newdev = grub_zalloc (sizeof (struct grub_cryptodisk)); - if (!newdev) - { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (secondary_cipher); - return NULL; - } - newdev->cipher = cipher; - newdev->secondary_cipher = secondary_cipher; - newdev->offset_sectors = 0; - newdev->source_disk = NULL; - newdev->benbi_log = 0; - if (grub_le_to_cpu16 (header.alg) == 0x16) - { - newdev->mode = GRUB_CRYPTODISK_MODE_XTS; - newdev->mode_iv = GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64; - } - else - { - newdev->mode = GRUB_CRYPTODISK_MODE_CBC; - newdev->mode_iv = GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH; - } - newdev->essiv_cipher = NULL; - newdev->essiv_hash = NULL; - newdev->hash = GRUB_MD_SHA512; - newdev->iv_hash = GRUB_MD_SHA256; - - newdev->log_sector_size = grub_log2ull (grub_le_to_cpu32 (header.sector_size)); - - if (grub_le_to_cpu32 (header.version) >= 5) - { - newdev->rekey = geli_rekey; - newdev->rekey_shift = 20; - } - - newdev->modname = "geli"; - - newdev->total_sectors = grub_disk_native_sectors (disk) - 1; - grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); - COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= 32 * 2 + 1); - return newdev; -} - -static grub_err_t -geli_recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs) -{ - grub_size_t keysize; - grub_uint8_t digest[GRUB_CRYPTO_MAX_MDLEN]; - grub_uint8_t geomkey[GRUB_CRYPTO_MAX_MDLEN]; - grub_uint8_t verify_key[GRUB_CRYPTO_MAX_MDLEN]; - grub_uint8_t zero[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE]; - grub_uint8_t geli_cipher_key[64]; - unsigned i; - gcry_err_code_t gcry_err; - struct grub_geli_phdr header; - grub_disk_addr_t sector; - grub_err_t err; - - if (cargs->key_data == NULL || cargs->key_len == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data"); - - if (dev->cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE) - return grub_error (GRUB_ERR_BUG, "cipher block is too long"); - - if (dev->hash->mdlen > GRUB_CRYPTO_MAX_MDLEN) - return grub_error (GRUB_ERR_BUG, "mdlen is too long"); - - sector = grub_disk_native_sectors (source); - if (sector == GRUB_DISK_SIZE_UNKNOWN || sector == 0) - return grub_error (GRUB_ERR_BUG, "not a geli"); - - /* Read the GELI header. */ - err = grub_disk_read (source, sector - 1, 0, sizeof (header), &header); - if (err) - return err; - - keysize = grub_le_to_cpu16 (header.keylen) / GRUB_CHAR_BIT; - grub_memset (zero, 0, sizeof (zero)); - - grub_puts_ (N_("Attempting to decrypt master key...")); - - /* Calculate the PBKDF2 of the user supplied passphrase. */ - if (grub_le_to_cpu32 (header.niter) != 0) - { - grub_uint8_t pbkdf_key[64]; - gcry_err = grub_crypto_pbkdf2 (dev->hash, cargs->key_data, - cargs->key_len, - header.salt, - sizeof (header.salt), - grub_le_to_cpu32 (header.niter), - pbkdf_key, sizeof (pbkdf_key)); - - if (gcry_err) - return grub_crypto_gcry_error (gcry_err); - - gcry_err = grub_crypto_hmac_buffer (dev->hash, NULL, 0, pbkdf_key, - sizeof (pbkdf_key), geomkey); - if (gcry_err) - return grub_crypto_gcry_error (gcry_err); - } - else - { - struct grub_crypto_hmac_handle *hnd; - - hnd = grub_crypto_hmac_init (dev->hash, NULL, 0); - if (!hnd) - return grub_crypto_gcry_error (GPG_ERR_OUT_OF_MEMORY); - - grub_crypto_hmac_write (hnd, header.salt, sizeof (header.salt)); - grub_crypto_hmac_write (hnd, cargs->key_data, cargs->key_len); - - gcry_err = grub_crypto_hmac_fini (hnd, geomkey); - if (gcry_err) - return grub_crypto_gcry_error (gcry_err); - } - - gcry_err = grub_crypto_hmac_buffer (dev->hash, geomkey, - dev->hash->mdlen, "\1", 1, digest); - if (gcry_err) - return grub_crypto_gcry_error (gcry_err); - - gcry_err = grub_crypto_hmac_buffer (dev->hash, geomkey, - dev->hash->mdlen, "\0", 1, verify_key); - if (gcry_err) - return grub_crypto_gcry_error (gcry_err); - - grub_dprintf ("geli", "keylen = %" PRIuGRUB_SIZE "\n", keysize); - - /* Try to recover master key from each active keyslot. */ - for (i = 0; i < ARRAY_SIZE (header.keys); i++) - { - struct grub_geli_key candidate_key; - grub_uint8_t key_hmac[GRUB_CRYPTO_MAX_MDLEN]; - - /* Check if keyslot is enabled. */ - if (! (header.keys_used & (1 << i))) - continue; - - grub_dprintf ("geli", "Trying keyslot %d\n", i); - - gcry_err = grub_crypto_cipher_set_key (dev->cipher, - digest, keysize); - if (gcry_err) - return grub_crypto_gcry_error (gcry_err); - - gcry_err = grub_crypto_cbc_decrypt (dev->cipher, &candidate_key, - &header.keys[i], - sizeof (candidate_key), - zero); - if (gcry_err) - return grub_crypto_gcry_error (gcry_err); - - gcry_err = grub_crypto_hmac_buffer (dev->hash, verify_key, - dev->hash->mdlen, - &candidate_key, - (sizeof (candidate_key) - - sizeof (candidate_key.hmac)), - key_hmac); - if (gcry_err) - return grub_crypto_gcry_error (gcry_err); - - if (grub_memcmp (candidate_key.hmac, key_hmac, dev->hash->mdlen) != 0) - continue; - grub_printf_ (N_("Slot %d opened\n"), i); - - if (grub_le_to_cpu32 (header.version) >= 7) - { - /* GELI >=7 uses the cipher_key */ - grub_memcpy (geli_cipher_key, candidate_key.cipher_key, - sizeof (candidate_key.cipher_key)); - } - else - { - /* GELI <=6 uses the iv_key */ - grub_memcpy (geli_cipher_key, candidate_key.iv_key, - sizeof (candidate_key.iv_key)); - } - - /* Set the master key. */ - if (!dev->rekey) - { - grub_size_t real_keysize = keysize; - if (grub_le_to_cpu16 (header.alg) == 0x16) - real_keysize *= 2; - gcry_err = grub_cryptodisk_setkey (dev, candidate_key.cipher_key, - real_keysize); - if (gcry_err) - return grub_crypto_gcry_error (gcry_err); - } - else - { - grub_size_t real_keysize = keysize; - if (grub_le_to_cpu16 (header.alg) == 0x16) - real_keysize *= 2; - - grub_memcpy (dev->rekey_key, geli_cipher_key, - sizeof (geli_cipher_key)); - dev->rekey_derived_size = real_keysize; - dev->last_rekey = -1; - COMPILE_TIME_ASSERT (sizeof (dev->rekey_key) - >= sizeof (geli_cipher_key)); - } - - dev->iv_prefix_len = sizeof (candidate_key.iv_key); - grub_memcpy (dev->iv_prefix, candidate_key.iv_key, - sizeof (candidate_key.iv_key)); - - COMPILE_TIME_ASSERT (sizeof (dev->iv_prefix) >= sizeof (candidate_key.iv_key)); - - return GRUB_ERR_NONE; - } - - return GRUB_ACCESS_DENIED; -} - -struct grub_cryptodisk_dev geli_crypto = { - .scan = geli_scan, - .recover_key = geli_recover_key -}; - -GRUB_MOD_INIT (geli) -{ - grub_cryptodisk_dev_register (&geli_crypto); -} - -GRUB_MOD_FINI (geli) -{ - grub_cryptodisk_dev_unregister (&geli_crypto); -} diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c deleted file mode 100644 index 1d6788950..000000000 --- a/grub-core/disk/i386/pc/biosdisk.c +++ /dev/null @@ -1,687 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static int cd_drive = 0; -static int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap); - -static int grub_biosdisk_get_num_floppies (void) -{ - struct grub_bios_int_registers regs; - int drive; - - /* reset the disk system first */ - regs.eax = 0; - regs.edx = 0; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - - grub_bios_interrupt (0x13, ®s); - - for (drive = 0; drive < 2; drive++) - { - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT | GRUB_CPU_INT_FLAGS_CARRY; - regs.edx = drive; - - /* call GET DISK TYPE */ - regs.eax = 0x1500; - grub_bios_interrupt (0x13, ®s); - if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY) - break; - - /* check if this drive exists */ - if (!(regs.eax & 0x300)) - break; - } - - return drive; -} - -/* - * 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. - */ - -static int -grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap) -{ - struct grub_bios_int_registers regs; - regs.eax = ah << 8; - /* compute the address of disk_address_packet */ - regs.ds = (((grub_addr_t) dap) & 0xffff0000) >> 4; - regs.esi = (((grub_addr_t) dap) & 0xffff); - regs.edx = drive; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - - grub_bios_interrupt (0x13, ®s); - return (regs.eax >> 8) & 0xff; -} - -/* - * 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. - */ -static int -grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff, - int soff, int nsec, int segment) -{ - int ret, i; - - /* Try 3 times. */ - for (i = 0; i < 3; i++) - { - struct grub_bios_int_registers regs; - - /* set up CHS information */ - /* set %ch to low eight bits of cylinder */ - regs.ecx = (coff << 8) & 0xff00; - /* set bits 6-7 of %cl to high two bits of cylinder */ - regs.ecx |= (coff >> 2) & 0xc0; - /* set bits 0-5 of %cl to sector */ - regs.ecx |= soff & 0x3f; - - /* set %dh to head and %dl to drive */ - regs.edx = (drive & 0xff) | ((hoff << 8) & 0xff00); - /* set %ah to AH */ - regs.eax = (ah << 8) & 0xff00; - /* set %al to NSEC */ - regs.eax |= nsec & 0xff; - - regs.ebx = 0; - regs.es = segment; - - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - - grub_bios_interrupt (0x13, ®s); - /* check if successful */ - if (!(regs.flags & GRUB_CPU_INT_FLAGS_CARRY)) - return 0; - - /* save return value */ - ret = regs.eax >> 8; - - /* if fail, reset the disk system */ - regs.eax = 0; - regs.edx = (drive & 0xff); - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x13, ®s); - } - return ret; -} - -/* - * Check if LBA is supported for DRIVE. If it is supported, then return - * the major version of extensions, otherwise zero. - */ -static int -grub_biosdisk_check_int13_extensions (int drive) -{ - struct grub_bios_int_registers regs; - - regs.edx = drive & 0xff; - regs.eax = 0x4100; - regs.ebx = 0x55aa; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x13, ®s); - - if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY) - return 0; - - if ((regs.ebx & 0xffff) != 0xaa55) - return 0; - - /* check if AH=0x42 is supported */ - if (!(regs.ecx & 1)) - return 0; - - return (regs.eax >> 8) & 0xff; -} - -/* - * Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an - * error occurs, then return non-zero, otherwise zero. - */ -static int -grub_biosdisk_get_diskinfo_standard (int drive, - unsigned long *cylinders, - unsigned long *heads, - unsigned long *sectors) -{ - struct grub_bios_int_registers regs; - - regs.eax = 0x0800; - regs.edx = drive & 0xff; - - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x13, ®s); - - /* Check if unsuccessful. Ignore return value if carry isn't set to - workaround some buggy BIOSes. */ - if ((regs.flags & GRUB_CPU_INT_FLAGS_CARRY) && ((regs.eax & 0xff00) != 0)) - return (regs.eax & 0xff00) >> 8; - - /* bogus BIOSes may not return an error number */ - /* 0 sectors means no disk */ - if (!(regs.ecx & 0x3f)) - /* XXX 0x60 is one of the unused error numbers */ - return 0x60; - - /* the number of heads is counted from zero */ - *heads = ((regs.edx >> 8) & 0xff) + 1; - *cylinders = (((regs.ecx >> 8) & 0xff) | ((regs.ecx << 2) & 0x0300)) + 1; - *sectors = regs.ecx & 0x3f; - return 0; -} - -static int -grub_biosdisk_get_diskinfo_real (int drive, void *drp, grub_uint16_t ax) -{ - struct grub_bios_int_registers regs; - - regs.eax = ax; - - /* compute the address of drive parameters */ - regs.esi = ((grub_addr_t) drp) & 0xf; - regs.ds = ((grub_addr_t) drp) >> 4; - regs.edx = drive & 0xff; - - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x13, ®s); - - /* Check if unsuccessful. Ignore return value if carry isn't set to - workaround some buggy BIOSes. */ - if ((regs.flags & GRUB_CPU_INT_FLAGS_CARRY) && ((regs.eax & 0xff00) != 0)) - return (regs.eax & 0xff00) >> 8; - - return 0; -} - -/* - * Return the cdrom information of DRIVE in CDRP. If an error occurs, - * then return non-zero, otherwise zero. - */ -static int -grub_biosdisk_get_cdinfo_int13_extensions (int drive, void *cdrp) -{ - return grub_biosdisk_get_diskinfo_real (drive, cdrp, 0x4b01); -} - -/* - * Return the geometry of DRIVE in a drive parameters, DRP. If an error - * occurs, then return non-zero, otherwise zero. - */ -static int -grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp) -{ - return grub_biosdisk_get_diskinfo_real (drive, drp, 0x4800); -} - -static int -grub_biosdisk_get_drive (const char *name) -{ - unsigned long drive; - - if (name[0] == 'c' && name[1] == 'd' && name[2] == 0 && cd_drive) - return cd_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 (grub_disk_dev_iterate_hook_t hook, void *hook_data, - int drive) -{ - char name[10]; - - if (cd_drive && drive == cd_drive) - return hook ("cd", hook_data); - - grub_snprintf (name, sizeof (name), - (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80)); - return hook (name, hook_data); -} - -static int -grub_biosdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - int num_floppies; - int drive; - - /* For hard disks, attempt to read the MBR. */ - switch (pull) - { - case GRUB_DISK_PULL_NONE: - 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, hook_data, drive)) - return 1; - } - return 0; - - case GRUB_DISK_PULL_REMOVABLE: - if (cd_drive) - { - if (grub_biosdisk_call_hook (hook, hook_data, 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, hook_data, drive)) - return 1; - return 0; - default: - return 0; - } - 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->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 = 8; - disk->log_sector_size = 11; - /* TODO: get the correct size. */ - total_sectors = GRUB_DISK_SIZE_UNKNOWN; - } - else - { - /* HDD */ - int version; - - disk->log_sector_size = 9; - - version = grub_biosdisk_check_int13_extensions (drive); - if (version) - { - struct grub_biosdisk_drp *drp - = (struct grub_biosdisk_drp *) grub_absolute_pointer (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 = ((grub_uint64_t) drp->cylinders) - * drp->heads * drp->sectors; - if (drp->bytes_per_sector - && !(drp->bytes_per_sector & (drp->bytes_per_sector - 1)) - && drp->bytes_per_sector >= 512 - && drp->bytes_per_sector <= 16384) - disk->log_sector_size = grub_log2ull (drp->bytes_per_sector); - } - } - } - - 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 (data->sectors == 0) - data->sectors = 63; - if (data->heads == 0) - data->heads = 255; - - if (! total_sectors) - total_sectors = ((grub_uint64_t) data->cylinders) - * data->heads * data->sectors; - } - - disk->total_sectors = total_sectors; - /* Limit the max to 0x7f because of Phoenix EDD. */ - disk->max_agglomerate = 0x7f >> GRUB_DISK_CACHE_BITS; - COMPILE_TIME_ASSERT ((0x7f >> GRUB_DISK_CACHE_BITS - << (GRUB_DISK_SECTOR_BITS + GRUB_DISK_CACHE_BITS)) - + sizeof (struct grub_biosdisk_dap) - < GRUB_MEMORY_MACHINE_SCRATCH_SIZE); - - 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; - - /* VirtualBox fails with sectors above 2T on CDs. - Since even BD-ROMS are never that big anyway, return error. */ - if ((data->flags & GRUB_BIOSDISK_FLAG_CDROM) - && (sector >> 32)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("attempt to read or write outside of disk `%s'"), - disk->name); - - if (data->flags & GRUB_BIOSDISK_FLAG_LBA) - { - struct grub_biosdisk_dap *dap; - - dap = (struct grub_biosdisk_dap *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR - + (GRUB_DISK_MAX_LBA_SECTORS - << disk->log_sector_size)); - 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, N_("cannot write to CD-ROM")); - - 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, N_("failure reading sector 0x%llx " - "from `%s'"), - (unsigned long long) sector, - disk->name); - } - 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, - N_("attempt to read or write outside of disk `%s'"), - 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, - N_("attempt to read or write outside of disk `%s'"), - 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, N_("failure reading sector 0x%llx " - "from `%s'"), - (unsigned long long) sector, - disk->name); - case GRUB_BIOSDISK_WRITE: - return grub_error (GRUB_ERR_WRITE_ERROR, N_("failure writing sector 0x%llx " - "to `%s'"), - (unsigned long long) sector, - 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_t disk, grub_disk_addr_t sector) -{ - grub_size_t size; - grub_uint64_t offset; - struct grub_biosdisk_data *data = disk->data; - grub_uint32_t sectors = data->sectors; - - if (data->flags & GRUB_BIOSDISK_FLAG_LBA) - sectors = GRUB_DISK_MAX_LBA_SECTORS; - - /* OFFSET = SECTOR % SECTORS */ - grub_divmod64 (sector, sectors, &offset); - - size = sectors - offset; - - return size; -} - -static grub_err_t -grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, char *buf) -{ - while (size) - { - grub_size_t len; - - len = get_safe_sectors (disk, sector); - - 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, - len << disk->log_sector_size); - - buf += len << disk->log_sector_size; - 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, N_("cannot write to CD-ROM")); - - while (size) - { - grub_size_t len; - - len = get_safe_sectors (disk, sector); - if (len > size) - len = size; - - grub_memcpy ((void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, buf, - len << disk->log_sector_size); - - if (grub_biosdisk_rw (GRUB_BIOSDISK_WRITE, disk, sector, len, - GRUB_MEMORY_MACHINE_SCRATCH_SEG)) - return grub_errno; - - buf += len << disk->log_sector_size; - sector += len; - size -= len; - } - - return grub_errno; -} - -static struct grub_disk_dev grub_biosdisk_dev = - { - .name = "biosdisk", - .id = GRUB_DISK_DEVICE_BIOSDISK_ID, - .disk_iterate = grub_biosdisk_iterate, - .disk_open = grub_biosdisk_open, - .disk_close = grub_biosdisk_close, - .disk_read = grub_biosdisk_read, - .disk_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_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); - grub_uint8_t boot_drive; - - if (grub_disk_firmware_is_tainted) - { - grub_puts_ (N_("Native disk drivers are in use. " - "Refusing to use firmware disk interface.")); - return; - } - grub_disk_firmware_fini = grub_disk_biosdisk_fini; - - grub_memset (cdrp, 0, sizeof (*cdrp)); - cdrp->size = sizeof (*cdrp); - cdrp->media_type = 0xFF; - boot_drive = (grub_boot_device >> 24); - if ((! grub_biosdisk_get_cdinfo_int13_extensions (boot_drive, cdrp)) - && ((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK) - == GRUB_BIOSDISK_CDTYPE_NO_EMUL)) - cd_drive = cdrp->drive_no; - /* Since diskboot.S rejects devices over 0x90 it must be a CD booted with - cdboot.S - */ - if (boot_drive >= 0x90) - cd_drive = boot_drive; - - grub_disk_dev_register (&grub_biosdisk_dev); -} - -GRUB_MOD_FINI(biosdisk) -{ - grub_disk_biosdisk_fini (); -} diff --git a/grub-core/disk/ieee1275/obdisk.c b/grub-core/disk/ieee1275/obdisk.c deleted file mode 100644 index fcc39e0a2..000000000 --- a/grub-core/disk/ieee1275/obdisk.c +++ /dev/null @@ -1,1109 +0,0 @@ -/* obdisk.c - Open Boot disk access. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2019 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IEEE1275_DEV "ieee1275/" -#define IEEE1275_DISK_ALIAS "/disk@" - -struct disk_dev -{ - struct disk_dev *next; - struct disk_dev **prev; - char *name; - char *raw_name; - char *grub_devpath; - char *grub_alias_devpath; - grub_ieee1275_ihandle_t ihandle; - grub_uint32_t block_size; - grub_uint64_t num_blocks; - unsigned int log_sector_size; - grub_uint32_t opened; - grub_uint32_t valid; - grub_uint32_t boot_dev; -}; - -struct parent_dev -{ - struct parent_dev *next; - struct parent_dev **prev; - char *name; - char *type; - grub_ieee1275_ihandle_t ihandle; - grub_uint32_t address_cells; -}; - -static struct grub_scsi_test_unit_ready tur = -{ - .opcode = grub_scsi_cmd_test_unit_ready, - .lun = 0, - .reserved1 = 0, - .reserved2 = 0, - .reserved3 = 0, - .control = 0, -}; - -static int disks_enumerated; -static struct disk_dev *disk_devs; -static struct parent_dev *parent_devs; - -static const char *block_blacklist[] = { - /* Requires additional work in grub before being able to be used. */ - "/iscsi-hba", - /* This block device should never be used by grub. */ - "/reboot-memory@0", - 0 -}; - -#define STRCMP(a, b) ((a) && (b) && (grub_strcmp (a, b) == 0)) - -static char * -strip_ob_partition (char *path) -{ - char *sptr; - - sptr = grub_strstr (path, ":"); - - if (sptr != NULL) - *sptr = '\0'; - - return path; -} - -static void -escape_commas (const char *src, char *dest) -{ - const char *iptr; - - for (iptr = src; *iptr; ) - { - if (*iptr == ',') - *dest++ ='\\'; - - *dest++ = *iptr++; - } - - *dest = '\0'; -} - -static int -count_commas (const char *src) -{ - int count = 0; - - for ( ; *src; src++) - if (*src == ',') - count++; - - return count; -} - - -static char * -decode_grub_devname (const char *name) -{ - char *devpath; - char *p, c; - grub_size_t sz; - - if (grub_add (grub_strlen (name), 1, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of device name")); - return NULL; - } - - devpath = grub_malloc (sz); - if (devpath == NULL) - return NULL; - - /* Un-escape commas. */ - p = devpath; - while ((c = *name++) != '\0') - { - if (c == '\\' && *name == ',') - { - *p++ = ','; - name++; - } - else - *p++ = c; - } - - *p++ = '\0'; - - return devpath; -} - -static char * -encode_grub_devname (const char *path) -{ - char *encoding, *optr; - grub_size_t sz; - - if (path == NULL) - return NULL; - - if (grub_add (sizeof (IEEE1275_DEV) + 1, count_commas (path), &sz) || - grub_add (sz, grub_strlen (path), &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining encoding size")); - grub_print_error (); - return NULL; - } - - encoding = grub_malloc (sz); - - if (encoding == NULL) - { - grub_print_error (); - return NULL; - } - - optr = grub_stpcpy (encoding, IEEE1275_DEV); - escape_commas (path, optr); - return encoding; -} - -static char * -get_parent_devname (const char *devname) -{ - char *parent, *pptr; - - parent = grub_strdup (devname); - - if (parent == NULL) - { - grub_print_error (); - return NULL; - } - - pptr = grub_strstr (parent, IEEE1275_DISK_ALIAS); - - if (pptr != NULL) - *pptr = '\0'; - - return parent; -} - -static void -free_parent_dev (struct parent_dev *parent) -{ - if (parent != NULL) - { - grub_free (parent->name); - grub_free (parent->type); - grub_free (parent); - } -} - -static struct parent_dev * -init_parent (const char *parent) -{ - struct parent_dev *op; - - op = grub_zalloc (sizeof (struct parent_dev)); - - if (op == NULL) - { - grub_print_error (); - return NULL; - } - - op->name = grub_strdup (parent); - op->type = grub_malloc (IEEE1275_MAX_PROP_LEN); - - if ((op->name == NULL) || (op->type == NULL)) - { - grub_print_error (); - free_parent_dev (op); - return NULL; - } - - return op; -} - -static struct parent_dev * -open_new_parent (const char *parent) -{ - struct parent_dev *op = init_parent(parent); - grub_ieee1275_ihandle_t ihandle; - grub_ieee1275_phandle_t phandle; - grub_uint32_t address_cells = 2; - - if (op == NULL) - return NULL; - - grub_ieee1275_open (parent, &ihandle); - - if (ihandle == 0) - { - grub_error (GRUB_ERR_BAD_DEVICE, "unable to open %s", parent); - grub_print_error (); - free_parent_dev (op); - return NULL; - } - - if (grub_ieee1275_instance_to_package (ihandle, &phandle)) - { - grub_error (GRUB_ERR_BAD_DEVICE, "unable to get parent %s", parent); - grub_print_error (); - free_parent_dev (op); - return NULL; - } - - /* - * IEEE Std 1275-1994 page 110: A missing "address-cells" property - * signifies that the number of address cells is two. So ignore on error. - */ - if (grub_ieee1275_get_integer_property (phandle, "#address-cells", - &address_cells, - sizeof (address_cells), 0) != 0) - address_cells = 2; - - grub_ieee1275_get_property (phandle, "device_type", op->type, - IEEE1275_MAX_PROP_LEN, NULL); - - op->ihandle = ihandle; - op->address_cells = address_cells; - return op; -} - -static struct parent_dev * -open_parent (const char *parent) -{ - struct parent_dev *op; - - op = grub_named_list_find (GRUB_AS_NAMED_LIST (parent_devs), parent); - - if (op == NULL) - { - op = open_new_parent (parent); - - if (op != NULL) - grub_list_push (GRUB_AS_LIST_P (&parent_devs), GRUB_AS_LIST (op)); - } - - return op; -} - -static void -display_parents (void) -{ - struct parent_dev *parent; - - grub_printf ("-------------------- PARENTS --------------------\n"); - - FOR_LIST_ELEMENTS (parent, parent_devs) - { - grub_printf ("name: %s\n", parent->name); - grub_printf ("type: %s\n", parent->type); - grub_printf ("address_cells %x\n", parent->address_cells); - } - - grub_printf ("-------------------------------------------------\n"); -} - -static char * -canonicalise_4cell_ua (grub_ieee1275_ihandle_t ihandle, char *unit_address) -{ - grub_uint32_t phy_lo, phy_hi, lun_lo, lun_hi; - int valid_phy = 0; - grub_size_t size; - char *canon = NULL; - - valid_phy = grub_ieee1275_decode_unit4 (ihandle, unit_address, - grub_strlen (unit_address), &phy_lo, - &phy_hi, &lun_lo, &lun_hi); - - if ((valid_phy == 0) && (phy_hi != 0xffffffff)) - canon = grub_ieee1275_encode_uint4 (ihandle, phy_lo, phy_hi, - lun_lo, lun_hi, &size); - - return canon; -} - -static char * -canonicalise_disk (const char *devname) -{ - char *canon, *parent; - struct parent_dev *op; - - canon = grub_ieee1275_canonicalise_devname (devname); - - if (canon == NULL) - { - /* This should not happen. */ - grub_error (GRUB_ERR_BAD_DEVICE, "canonicalise devname failed"); - grub_print_error (); - return NULL; - } - - /* Don't try to open the parent of a virtual device. */ - if (grub_strstr (canon, "virtual-devices")) - return canon; - - parent = get_parent_devname (canon); - - if (parent == NULL) - return NULL; - - op = open_parent (parent); - - /* - * Devices with 4 address cells can have many different types of addressing - * (phy, wwn, and target lun). Use the parents encode-unit / decode-unit - * to find the true canonical name. - */ - if ((op) && (op->address_cells == 4)) - { - char *unit_address, *real_unit_address, *real_canon; - grub_size_t real_unit_str_len; - - unit_address = grub_strstr (canon, IEEE1275_DISK_ALIAS); - unit_address += grub_strlen (IEEE1275_DISK_ALIAS); - - if (unit_address == NULL) - { - /* - * This should not be possible, but return the canonical name for - * the non-disk block device. - */ - grub_free (parent); - return (canon); - } - - real_unit_address = canonicalise_4cell_ua (op->ihandle, unit_address); - - if (real_unit_address == NULL) - { - /* - * This is not an error, since this function could be called with a devalias - * containing a drive that isn't installed in the system. - */ - grub_free (parent); - return NULL; - } - - real_unit_str_len = grub_strlen (op->name) + sizeof (IEEE1275_DISK_ALIAS) - + grub_strlen (real_unit_address); - if (grub_add (grub_strlen (op->name), sizeof (IEEE1275_DISK_ALIAS), &real_unit_str_len) || - grub_add (real_unit_str_len, grub_strlen (real_unit_address), &real_unit_str_len)) - { - grub_free (parent); - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of canonical name")); - grub_print_error (); - return NULL; - } - - real_canon = grub_malloc (real_unit_str_len); - if (real_canon == NULL) - { - grub_free (parent); - grub_print_error (); - return NULL; - } - - grub_snprintf (real_canon, real_unit_str_len, "%s/disk@%s", - op->name, real_unit_address); - - grub_free (canon); - canon = real_canon; - } - - grub_free (parent); - return (canon); -} - -static struct disk_dev * -add_canon_disk (const char *cname) -{ - grub_size_t sz; - struct disk_dev *dev; - - dev = grub_zalloc (sizeof (struct disk_dev)); - - if (dev == NULL) - goto failed; - - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_RAW_DEVNAMES)) - { - /* - * Append :nolabel to the end of all SPARC disks. - * nolabel is mutually exclusive with all other - * arguments and allows a client program to open - * the entire (raw) disk. Any disk label is ignored. - */ - if (grub_add (grub_strlen (cname), sizeof (":nolabel"), &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while appending :nolabel to end of canonical name"); - goto failed; - } - - dev->raw_name = grub_malloc (sz); - - if (dev->raw_name == NULL) - goto failed; - - grub_snprintf (dev->raw_name, sz, "%s:nolabel", cname); - } - - /* - * Don't use grub_ieee1275_encode_devname here, the devpath in grub.cfg doesn't - * understand device aliases, which the layer above sometimes sends us. - */ - dev->grub_devpath = encode_grub_devname(cname); - - if (dev->grub_devpath == NULL) - goto failed; - - dev->name = grub_strdup (cname); - - if (dev->name == NULL) - goto failed; - - dev->valid = 1; - grub_list_push (GRUB_AS_LIST_P (&disk_devs), GRUB_AS_LIST (dev)); - return dev; - - failed: - grub_print_error (); - - if (dev != NULL) - { - grub_free (dev->name); - grub_free (dev->grub_devpath); - grub_free (dev->raw_name); - } - - grub_free (dev); - return NULL; -} - -static grub_err_t -add_disk (const char *path) -{ - grub_err_t ret = GRUB_ERR_NONE; - struct disk_dev *dev; - char *canon; - - canon = canonicalise_disk (path); - dev = grub_named_list_find (GRUB_AS_NAMED_LIST (disk_devs), canon); - - if ((canon != NULL) && (dev == NULL)) - { - struct disk_dev *ob_device; - - ob_device = add_canon_disk (canon); - - if (ob_device == NULL) - ret = grub_error (GRUB_ERR_OUT_OF_MEMORY, "failure to add disk"); - } - else if (dev != NULL) - dev->valid = 1; - - grub_free (canon); - return (ret); -} - -static grub_err_t -grub_obdisk_read (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, char *dest) -{ - grub_err_t ret = GRUB_ERR_NONE; - struct disk_dev *dev; - unsigned long long pos; - grub_ssize_t result = 0; - - if (disk->data == NULL) - return grub_error (GRUB_ERR_BAD_DEVICE, "invalid disk data"); - - dev = (struct disk_dev *)disk->data; - pos = sector << disk->log_sector_size; - grub_ieee1275_seek (dev->ihandle, pos, &result); - - if (result < 0) - { - dev->opened = 0; - return grub_error (GRUB_ERR_READ_ERROR, "seek error, can't seek block %llu", - (long long) sector); - } - - grub_ieee1275_read (dev->ihandle, dest, size << disk->log_sector_size, - &result); - - if (result != (grub_ssize_t) (size << disk->log_sector_size)) - { - dev->opened = 0; - return grub_error (GRUB_ERR_READ_ERROR, N_("failure reading sector 0x%llx " - "from `%s'"), - (unsigned long long) sector, - disk->name); - } - return ret; -} - -static void -grub_obdisk_close (grub_disk_t disk) -{ - grub_memset (disk, 0, sizeof (*disk)); -} - -static void -scan_usb_disk (const char *parent) -{ - struct parent_dev *op; - grub_ssize_t result; - - op = open_parent (parent); - - if (op == NULL) - { - grub_error (GRUB_ERR_BAD_DEVICE, "unable to open %s", parent); - grub_print_error (); - return; - } - - if ((grub_ieee1275_set_address (op->ihandle, 0, 0) == 0) && - (grub_ieee1275_no_data_command (op->ihandle, &tur, &result) == 0) && - (result == 0)) - { - char *buf; - - buf = grub_malloc (IEEE1275_MAX_PATH_LEN); - - if (buf == NULL) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "disk scan failure"); - grub_print_error (); - return; - } - - grub_snprintf (buf, IEEE1275_MAX_PATH_LEN, "%s/disk@0", parent); - add_disk (buf); - grub_free (buf); - } -} - -static void -scan_nvme_disk (const char *path) -{ - char *buf; - - buf = grub_malloc (IEEE1275_MAX_PATH_LEN); - - if (buf == NULL) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "disk scan failure"); - grub_print_error (); - return; - } - - grub_snprintf (buf, IEEE1275_MAX_PATH_LEN, "%s/disk@1", path); - add_disk (buf); - grub_free (buf); -} - -static void -scan_sparc_sas_2cell (struct parent_dev *op) -{ - grub_ssize_t result; - grub_uint8_t tgt; - char *buf; - - buf = grub_malloc (IEEE1275_MAX_PATH_LEN); - - if (buf == NULL) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "disk scan failure"); - grub_print_error (); - return; - } - - for (tgt = 0; tgt < 0xf; tgt++) - { - - if ((grub_ieee1275_set_address(op->ihandle, tgt, 0) == 0) && - (grub_ieee1275_no_data_command (op->ihandle, &tur, &result) == 0) && - (result == 0)) - { - - grub_snprintf (buf, IEEE1275_MAX_PATH_LEN, "%s/disk@%" - PRIxGRUB_UINT32_T, op->name, tgt); - - add_disk (buf); - } - } -} - -static void -scan_sparc_sas_4cell (struct parent_dev *op) -{ - grub_uint16_t exp; - grub_uint8_t phy; - char *buf; - - buf = grub_malloc (IEEE1275_MAX_PATH_LEN); - - if (buf == NULL) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "disk scan failure"); - grub_print_error (); - return; - } - - /* - * Cycle thru the potential for dual ported SAS disks - * behind a SAS expander. - */ - for (exp = 0; exp <= 0x100; exp+=0x100) - - /* The current limit is 32 disks on a phy. */ - for (phy = 0; phy < 0x20; phy++) - { - char *canon = NULL; - - grub_snprintf (buf, IEEE1275_MAX_PATH_LEN, "p%" PRIxGRUB_UINT32_T ",0", - exp | phy); - - canon = canonicalise_4cell_ua (op->ihandle, buf); - - if (canon != NULL) - { - grub_snprintf (buf, IEEE1275_MAX_PATH_LEN, "%s/disk@%s", - op->name, canon); - - add_disk (buf); - grub_free (canon); - } - } - - grub_free (buf); -} - -static void -scan_sparc_sas_disk (const char *parent) -{ - struct parent_dev *op; - - op = open_parent (parent); - - if ((op != NULL) && (op->address_cells == 4)) - scan_sparc_sas_4cell (op); - else if ((op != NULL) && (op->address_cells == 2)) - scan_sparc_sas_2cell (op); -} - -static void -iterate_devtree (const struct grub_ieee1275_devalias *alias) -{ - struct grub_ieee1275_devalias child; - - if ((grub_strcmp (alias->type, "scsi-2") == 0) || - (grub_strcmp (alias->type, "scsi-sas") == 0)) - return scan_sparc_sas_disk (alias->path); - - else if (grub_strcmp (alias->type, "nvme") == 0) - return scan_nvme_disk (alias->path); - - else if (grub_strcmp (alias->type, "scsi-usb") == 0) - return scan_usb_disk (alias->path); - - else if (grub_strcmp (alias->type, "block") == 0) - { - const char **bl = block_blacklist; - - while (*bl != NULL) - { - if (grub_strstr (alias->path, *bl)) - return; - bl++; - } - - add_disk (alias->path); - return; - } - - FOR_IEEE1275_DEVCHILDREN (alias->path, child) - iterate_devtree (&child); -} - -static void -enumerate_disks (void) -{ - struct grub_ieee1275_devalias alias; - - FOR_IEEE1275_DEVCHILDREN("/", alias) - iterate_devtree (&alias); -} - -static grub_err_t -add_bootpath (void) -{ - struct disk_dev *ob_device; - grub_err_t ret = GRUB_ERR_NONE; - char *dev, *alias; - char *type; - - dev = grub_ieee1275_get_boot_dev (); - - if (dev == NULL) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "failure adding boot device"); - - type = grub_ieee1275_get_device_type (dev); - - if (type == NULL) - { - grub_free (dev); - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "failure adding boot device"); - } - - alias = NULL; - - if (grub_strcmp (type, "network") != 0) - { - dev = strip_ob_partition (dev); - ob_device = add_canon_disk (dev); - - if (ob_device == NULL) - ret = grub_error (GRUB_ERR_OUT_OF_MEMORY, "failure adding boot device"); - - ob_device->valid = 1; - - alias = grub_ieee1275_get_devname (dev); - - if (alias && grub_strcmp (alias, dev) != 0) - ob_device->grub_alias_devpath = grub_ieee1275_encode_devname (dev); - - ob_device->boot_dev = 1; - } - - grub_free (type); - grub_free (dev); - grub_free (alias); - return ret; -} - -static void -enumerate_aliases (void) -{ - struct grub_ieee1275_devalias alias; - - /* - * Some block device aliases are not in canonical form - * - * For example: - * - * disk3 /pci@301/pci@1/scsi@0/disk@p3 - * disk2 /pci@301/pci@1/scsi@0/disk@p2 - * disk1 /pci@301/pci@1/scsi@0/disk@p1 - * disk /pci@301/pci@1/scsi@0/disk@p0 - * disk0 /pci@301/pci@1/scsi@0/disk@p0 - * - * None of these devices are in canonical form. - * - * Also, just because there is a devalias, doesn't mean there is a disk - * at that location. And a valid boot block device doesn't have to have - * a devalias at all. - * - * At this point, all valid disks have been found in the system - * and devaliases that point to canonical names are stored in the - * disk_devs list already. - */ - FOR_IEEE1275_DEVALIASES (alias) - { - struct disk_dev *dev; - char *canon; - - if (grub_strcmp (alias.type, "block") != 0) - continue; - - canon = canonicalise_disk (alias.name); - - if (canon == NULL) - /* This is not an error, a devalias could point to a nonexistent disk. */ - continue; - - dev = grub_named_list_find (GRUB_AS_NAMED_LIST (disk_devs), canon); - - if (dev != NULL) - { - /* - * If more than one alias points to the same device, - * remove the previous one unless it is the boot dev, - * since the upper level will use the first one. The reason - * all the others are redone is in the case of hot-plugging - * a disk. If the boot disk gets hot-plugged, it will come - * thru here with a different name without the boot_dev flag - * set. - */ - if ((dev->boot_dev) && (dev->grub_alias_devpath)) - continue; - - grub_free (dev->grub_alias_devpath); - dev->grub_alias_devpath = grub_ieee1275_encode_devname (alias.path); - } - grub_free (canon); - } -} - -static void -display_disks (void) -{ - struct disk_dev *dev; - - grub_printf ("--------------------- DISKS ---------------------\n"); - - FOR_LIST_ELEMENTS (dev, disk_devs) - { - grub_printf ("name: %s\n", dev->name); - grub_printf ("grub_devpath: %s\n", dev->grub_devpath); - grub_printf ("grub_alias_devpath: %s\n", dev->grub_alias_devpath); - grub_printf ("valid: %s\n", (dev->valid) ? "yes" : "no"); - grub_printf ("boot_dev: %s\n", (dev->boot_dev) ? "yes" : "no"); - grub_printf ("opened: %s\n", (dev->ihandle) ? "yes" : "no"); - grub_printf ("block size: %" PRIuGRUB_UINT32_T "\n", - dev->block_size); - grub_printf ("num blocks: %" PRIuGRUB_UINT64_T "\n", - dev->num_blocks); - grub_printf ("log sector size: %" PRIuGRUB_UINT32_T "\n", - dev->log_sector_size); - grub_printf ("\n"); - } - - grub_printf ("-------------------------------------------------\n"); -} - -static void -display_stats (void) -{ - const char *debug = grub_env_get ("debug"); - - if (debug == NULL) - return; - - if (grub_strword (debug, "all") || grub_strword (debug, "obdisk")) - { - display_parents (); - display_disks (); - } -} - -static void -invalidate_all_disks (void) -{ - struct disk_dev *dev = NULL; - - if (disks_enumerated != 0) - FOR_LIST_ELEMENTS (dev, disk_devs) - dev->valid = 0; -} - -static struct disk_dev * -find_legacy_grub_devpath (const char *name) -{ - struct disk_dev *dev = NULL; - char *canon, *devpath = NULL; - - devpath = decode_grub_devname (name + sizeof ("ieee1275")); - canon = canonicalise_disk (devpath); - - if (canon != NULL) - dev = grub_named_list_find (GRUB_AS_NAMED_LIST (disk_devs), canon); - - grub_free (devpath); - grub_free (canon); - return dev; -} - -static void -enumerate_devices (void) -{ - invalidate_all_disks (); - enumerate_disks (); - enumerate_aliases (); - disks_enumerated = 1; - display_stats (); -} - -static struct disk_dev * -find_grub_devpath_real (const char *name) -{ - struct disk_dev *dev = NULL; - - FOR_LIST_ELEMENTS (dev, disk_devs) - { - if ((STRCMP (dev->grub_devpath, name)) - || (STRCMP (dev->grub_alias_devpath, name))) - break; - } - - return dev; -} - -static struct disk_dev * -find_grub_devpath (const char *name) -{ - struct disk_dev *dev = NULL; - int enumerated; - - do { - enumerated = disks_enumerated; - dev = find_grub_devpath_real (name); - - if (dev != NULL) - break; - - dev = find_legacy_grub_devpath (name); - - if (dev != NULL) - break; - - enumerate_devices (); - } while (enumerated == 0); - - return dev; -} - -static int -grub_obdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - struct disk_dev *dev; - const char *name; - - if (pull != GRUB_DISK_PULL_NONE) - return 0; - - enumerate_devices (); - - FOR_LIST_ELEMENTS (dev, disk_devs) - { - if (dev->valid == 1) - { - if (dev->grub_alias_devpath) - name = dev->grub_alias_devpath; - else - name = dev->grub_devpath; - - if (hook (name, hook_data)) - return 1; - } - } - - return 0; -} - -static grub_err_t -grub_obdisk_open (const char *name, grub_disk_t disk) -{ - grub_ieee1275_ihandle_t ihandle = 0; - struct disk_dev *dev = NULL; - - if (grub_strncmp (name, IEEE1275_DEV, sizeof (IEEE1275_DEV) - 1) != 0) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not IEEE1275 device"); - - dev = find_grub_devpath (name); - - if (dev == NULL) - { - grub_printf ("UNKNOWN DEVICE: %s\n", name); - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "%s", name); - } - - if (dev->opened == 0) - { - if (dev->raw_name != NULL) - grub_ieee1275_open (dev->raw_name, &ihandle); - else - grub_ieee1275_open (dev->name, &ihandle); - - if (ihandle == 0) - { - grub_printf ("Can't open device %s\n", name); - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device %s", name); - } - - dev->block_size = grub_ieee1275_get_block_size (ihandle); - dev->num_blocks = grub_ieee1275_num_blocks (ihandle); - - if (dev->num_blocks == 0) - dev->num_blocks = grub_ieee1275_num_blocks64 (ihandle); - - if (dev->num_blocks == 0) - dev->num_blocks = GRUB_DISK_SIZE_UNKNOWN; - - if (dev->block_size != 0) - dev->log_sector_size = grub_log2ull (dev->block_size); - else - dev->log_sector_size = 9; - - dev->ihandle = ihandle; - dev->opened = 1; - } - - disk->total_sectors = dev->num_blocks; - disk->id = dev->ihandle; - disk->data = dev; - disk->log_sector_size = dev->log_sector_size; - return GRUB_ERR_NONE; -} - - -static struct grub_disk_dev grub_obdisk_dev = - { - .name = "obdisk", - .id = GRUB_DISK_DEVICE_OBDISK_ID, - .disk_iterate = grub_obdisk_iterate, - .disk_open = grub_obdisk_open, - .disk_close = grub_obdisk_close, - .disk_read = grub_obdisk_read, - }; - -void -grub_obdisk_init (void) -{ - grub_disk_firmware_fini = grub_obdisk_fini; - add_bootpath (); - grub_disk_dev_register (&grub_obdisk_dev); -} - -void -grub_obdisk_fini (void) -{ - struct disk_dev *dev; - - FOR_LIST_ELEMENTS (dev, disk_devs) - { - if (dev->opened != 0) - grub_ieee1275_close (dev->ihandle); - } - - grub_disk_dev_unregister (&grub_obdisk_dev); -} diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c deleted file mode 100644 index dbc0f1aba..000000000 --- a/grub-core/disk/ieee1275/ofdisk.c +++ /dev/null @@ -1,783 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static char *last_devpath; -static grub_ieee1275_ihandle_t last_ihandle; - -struct ofdisk_hash_ent -{ - char *devpath; - char *open_path; - char *grub_devpath; - int is_boot; - int is_removable; - int block_size_fails; - /* Pointer to shortest available name on nodes representing canonical names, - otherwise NULL. */ - const char *shortest; - const char *grub_shortest; - struct ofdisk_hash_ent *next; -}; - -static grub_err_t -grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size, - struct ofdisk_hash_ent *op); - -#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_real (char *devpath) -{ - struct ofdisk_hash_ent *p; - struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)]; - const char *iptr; - char *optr; - grub_size_t sz; - - p = grub_zalloc (sizeof (*p)); - if (!p) - return NULL; - - p->devpath = devpath; - - if (grub_mul (grub_strlen (p->devpath), 2, &sz) || - grub_add (sz, sizeof ("ieee1275/"), &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of device path")); - return NULL; - } - - p->grub_devpath = grub_malloc (sz); - - if (!p->grub_devpath) - { - grub_free (p); - return NULL; - } - - if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0)) - { - if (grub_add (grub_strlen (p->devpath), 3, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of an open path")); - return NULL; - } - - p->open_path = grub_malloc (sz); - if (!p->open_path) - { - grub_free (p->grub_devpath); - grub_free (p); - return NULL; - } - optr = grub_stpcpy (p->open_path, p->devpath); - *optr++ = ':'; - *optr++ = '0'; - *optr = '\0'; - } - else - p->open_path = p->devpath; - - optr = grub_stpcpy (p->grub_devpath, "ieee1275/"); - for (iptr = p->devpath; *iptr; ) - { - if (*iptr == ',') - *optr++ = '\\'; - *optr++ = *iptr++; - } - *optr = 0; - - p->next = *head; - *head = p; - return p; -} - -static int -check_string_removable (const char *str) -{ - const char *ptr = grub_strrchr (str, '/'); - - if (ptr) - ptr++; - else - ptr = str; - return (grub_strncmp (ptr, "cdrom", 5) == 0 || grub_strncmp (ptr, "fd", 2) == 0); -} - -static struct ofdisk_hash_ent * -ofdisk_hash_add (char *devpath, char *curcan) -{ - struct ofdisk_hash_ent *p, *pcan; - - p = ofdisk_hash_add_real (devpath); - - grub_dprintf ("disk", "devpath = %s, canonical = %s\n", devpath, curcan); - - if (!curcan) - { - p->shortest = p->devpath; - p->grub_shortest = p->grub_devpath; - if (check_string_removable (devpath)) - p->is_removable = 1; - return p; - } - - pcan = ofdisk_hash_find (curcan); - if (!pcan) - pcan = ofdisk_hash_add_real (curcan); - else - grub_free (curcan); - - if (check_string_removable (devpath) || check_string_removable (curcan)) - pcan->is_removable = 1; - - if (!pcan) - grub_errno = GRUB_ERR_NONE; - else - { - if (!pcan->shortest - || grub_strlen (pcan->shortest) > grub_strlen (devpath)) - { - pcan->shortest = p->devpath; - pcan->grub_shortest = p->grub_devpath; - } - } - - return p; -} - -static void -dev_iterate_real (const char *name, const char *path) -{ - struct ofdisk_hash_ent *op; - - grub_dprintf ("disk", "disk name = %s, path = %s\n", name, - path); - - op = ofdisk_hash_find (path); - if (!op) - { - char *name_dup = grub_strdup (name); - char *can = grub_strdup (path); - if (!name_dup || !can) - { - grub_errno = GRUB_ERR_NONE; - grub_free (name_dup); - grub_free (can); - return; - } - op = ofdisk_hash_add (name_dup, can); - } - return; -} - -static void -dev_iterate (const struct grub_ieee1275_devalias *alias) -{ - if (grub_strcmp (alias->type, "vscsi") == 0) - { - static grub_ieee1275_ihandle_t ihandle; - struct set_color_args - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t method; - grub_ieee1275_cell_t ihandle; - grub_ieee1275_cell_t catch_result; - grub_ieee1275_cell_t nentries; - grub_ieee1275_cell_t table; - } - args; - char *buf, *bufptr; - unsigned i; - grub_size_t sz; - - if (grub_ieee1275_open (alias->path, &ihandle)) - return; - - /* This method doesn't need memory allocation for the table. Open - firmware takes care of all memory management and the result table - stays in memory and is never freed. */ - INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3); - args.method = (grub_ieee1275_cell_t) "vscsi-report-luns"; - args.ihandle = ihandle; - args.table = 0; - args.nentries = 0; - - if (IEEE1275_CALL_ENTRY_FN (&args) == -1 || args.catch_result) - { - grub_ieee1275_close (ihandle); - return; - } - - if (grub_add (grub_strlen (alias->path), 32, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while creating buffer for vscsi"); - grub_ieee1275_close (ihandle); - return; - } - - buf = grub_malloc (sz); - if (!buf) - { - grub_ieee1275_close (ihandle); - return; - } - bufptr = grub_stpcpy (buf, alias->path); - - for (i = 0; i < args.nentries; i++) - { - grub_uint64_t *ptr; - - ptr = *(grub_uint64_t **) (args.table + 4 + 8 * i); - while (*ptr) - { - grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T, *ptr++); - dev_iterate_real (buf, buf); - } - } - grub_ieee1275_close (ihandle); - grub_free (buf); - return; - } - else if (grub_strcmp (alias->type, "sas_ioa") == 0) - { - /* The method returns the number of disks and a table where - * each ID is 64-bit long. Example of sas paths: - * /pci@80000002000001f/pci1014,034A@0/sas/disk@c05db70800 - * /pci@80000002000001f/pci1014,034A@0/sas/disk@a05db70800 - * /pci@80000002000001f/pci1014,034A@0/sas/disk@805db70800 */ - - struct sas_children - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t method; - grub_ieee1275_cell_t ihandle; - grub_ieee1275_cell_t max; - grub_ieee1275_cell_t table; - grub_ieee1275_cell_t catch_result; - grub_ieee1275_cell_t nentries; - } - args; - char *buf, *bufptr; - unsigned i; - grub_uint64_t *table; - grub_uint16_t table_size; - grub_ieee1275_ihandle_t ihandle; - grub_size_t sz; - - if (grub_add (grub_strlen (alias->path), sizeof ("/disk@7766554433221100"), &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while creating buffer for sas_ioa"); - return; - } - - buf = grub_malloc (sz); - if (!buf) - return; - bufptr = grub_stpcpy (buf, alias->path); - - /* Power machines documentation specify 672 as maximum SAS disks in - one system. Using a slightly larger value to be safe. */ - table_size = 768; - table = grub_calloc (table_size, sizeof (grub_uint64_t)); - - if (!table) - { - grub_free (buf); - return; - } - - if (grub_ieee1275_open (alias->path, &ihandle)) - { - grub_free (buf); - grub_free (table); - return; - } - - INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 2); - args.method = (grub_ieee1275_cell_t) "get-sas-children"; - args.ihandle = ihandle; - args.max = table_size; - args.table = (grub_ieee1275_cell_t) table; - args.catch_result = 0; - args.nentries = 0; - - if (IEEE1275_CALL_ENTRY_FN (&args) == -1) - { - grub_ieee1275_close (ihandle); - grub_free (table); - grub_free (buf); - return; - } - - for (i = 0; i < args.nentries; i++) - { - grub_snprintf (bufptr, sizeof ("/disk@7766554433221100"), - "/disk@%" PRIxGRUB_UINT64_T, table[i]); - dev_iterate_real (buf, buf); - } - - grub_ieee1275_close (ihandle); - grub_free (table); - grub_free (buf); - } - - if (!grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS) - && grub_strcmp (alias->type, "block") == 0) - { - dev_iterate_real (alias->path, alias->path); - return; - } - - { - struct grub_ieee1275_devalias child; - - FOR_IEEE1275_DEVCHILDREN(alias->path, child) - dev_iterate (&child); - } -} - -static void -scan (void) -{ - struct grub_ieee1275_devalias alias; - FOR_IEEE1275_DEVALIASES(alias) - { - if (grub_strcmp (alias.type, "block") != 0) - continue; - dev_iterate_real (alias.name, alias.path); - } - - FOR_IEEE1275_DEVCHILDREN("/", alias) - dev_iterate (&alias); -} - -static int -grub_ofdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - unsigned i; - - if (pull != GRUB_DISK_PULL_NONE) - return 0; - - scan (); - - for (i = 0; i < ARRAY_SIZE (ofdisk_hash); i++) - { - static struct ofdisk_hash_ent *ent; - for (ent = ofdisk_hash[i]; ent; ent = ent->next) - { - if (!ent->shortest) - continue; - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY)) - { - grub_ieee1275_phandle_t dev; - char tmp[8]; - - if (grub_ieee1275_finddevice (ent->devpath, &dev)) - { - grub_dprintf ("disk", "finddevice (%s) failed\n", - ent->devpath); - continue; - } - - if (grub_ieee1275_get_property (dev, "iconname", tmp, - sizeof tmp, 0)) - { - grub_dprintf ("disk", "get iconname failed\n"); - continue; - } - - if (grub_strcmp (tmp, "sdmmc") != 0) - { - grub_dprintf ("disk", "device is not an SD card\n"); - continue; - } - } - - if (!ent->is_boot && ent->is_removable) - continue; - - if (hook (ent->grub_shortest, hook_data)) - return 1; - } - } - return 0; -} - -static char * -compute_dev_path (const char *name) -{ - char *devpath; - char *p, c; - grub_size_t sz; - - if (grub_add (grub_strlen (name), 3, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of device path")); - return NULL; - } - - devpath = grub_malloc (sz); - if (!devpath) - return NULL; - - /* Un-escape commas. */ - p = devpath; - while ((c = *name++) != '\0') - { - if (c == '\\' && *name == ',') - { - *p++ = ','; - name++; - } - else - *p++ = c; - } - - *p++ = '\0'; - - return devpath; -} - -static grub_err_t -grub_ofdisk_open (const char *name, grub_disk_t disk) -{ - grub_ieee1275_phandle_t dev; - char *devpath; - /* XXX: This should be large enough for any possible case. */ - char prop[64]; - grub_ssize_t actual; - grub_uint32_t block_size = 0; - grub_err_t err; - - if (grub_strncmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) != 0) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "not IEEE1275 device"); - devpath = compute_dev_path (name + sizeof ("ieee1275/") - 1); - if (! devpath) - return grub_errno; - - grub_dprintf ("disk", "Opening `%s'.\n", devpath); - - if (grub_ieee1275_finddevice (devpath, &dev)) - { - grub_free (devpath); - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "can't read device properties"); - } - - if (grub_ieee1275_get_property (dev, "device_type", prop, sizeof (prop), - &actual)) - { - grub_free (devpath); - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read the device type"); - } - - if (grub_strcmp (prop, "block")) - { - grub_free (devpath); - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a block device"); - } - - /* 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 = GRUB_DISK_SIZE_UNKNOWN; - - { - struct ofdisk_hash_ent *op; - op = ofdisk_hash_find (devpath); - if (!op) - op = ofdisk_hash_add (devpath, NULL); - if (!op) - { - grub_free (devpath); - return grub_errno; - } - disk->id = (unsigned long) op; - disk->data = op->open_path; - - err = grub_ofdisk_get_block_size (devpath, &block_size, op); - if (err) - { - grub_free (devpath); - return err; - } - if (block_size != 0) - disk->log_sector_size = grub_log2ull (block_size); - else - disk->log_sector_size = 9; - } - - grub_free (devpath); - return 0; -} - -static void -grub_ofdisk_close (grub_disk_t disk) -{ - if (disk->data == last_devpath) - { - if (last_ihandle) - grub_ieee1275_close (last_ihandle); - last_ihandle = 0; - last_devpath = NULL; - } - disk->data = 0; -} - -static grub_err_t -grub_ofdisk_prepare (grub_disk_t disk, grub_disk_addr_t sector) -{ - grub_ssize_t status; - unsigned long long pos; - - if (disk->data != last_devpath) - { - if (last_ihandle) - grub_ieee1275_close (last_ihandle); - last_ihandle = 0; - last_devpath = NULL; - - grub_ieee1275_open (disk->data, &last_ihandle); - if (! last_ihandle) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); - last_devpath = disk->data; - } - - pos = sector << disk->log_sector_size; - - grub_ieee1275_seek (last_ihandle, pos, &status); - if (status < 0) - return grub_error (GRUB_ERR_READ_ERROR, - "seek error, can't seek block %llu", - (long long) sector); - return 0; -} - -static grub_err_t -grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, char *buf) -{ - grub_err_t err; - grub_ssize_t actual; - err = grub_ofdisk_prepare (disk, sector); - if (err) - return err; - grub_ieee1275_read (last_ihandle, buf, size << disk->log_sector_size, - &actual); - if (actual != (grub_ssize_t) (size << disk->log_sector_size)) - return grub_error (GRUB_ERR_READ_ERROR, N_("failure reading sector 0x%llx " - "from `%s'"), - (unsigned long long) sector, - disk->name); - - return 0; -} - -static grub_err_t -grub_ofdisk_write (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, const char *buf) -{ - grub_err_t err; - grub_ssize_t actual; - err = grub_ofdisk_prepare (disk, sector); - if (err) - return err; - grub_ieee1275_write (last_ihandle, buf, size << disk->log_sector_size, - &actual); - if (actual != (grub_ssize_t) (size << disk->log_sector_size)) - return grub_error (GRUB_ERR_WRITE_ERROR, N_("failure writing sector 0x%llx " - "to `%s'"), - (unsigned long long) sector, - disk->name); - - return 0; -} - -static struct grub_disk_dev grub_ofdisk_dev = - { - .name = "ofdisk", - .id = GRUB_DISK_DEVICE_OFDISK_ID, - .disk_iterate = grub_ofdisk_iterate, - .disk_open = grub_ofdisk_open, - .disk_close = grub_ofdisk_close, - .disk_read = grub_ofdisk_read, - .disk_write = grub_ofdisk_write, - .next = 0 - }; - -static void -insert_bootpath (void) -{ - char *bootpath; - grub_ssize_t bootpath_size; - char *type; - grub_size_t sz; - - if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath", - &bootpath_size) - || bootpath_size <= 0) - { - /* Should never happen. */ - grub_printf ("/chosen/bootpath property missing!\n"); - return; - } - - if (grub_add (bootpath_size, 64, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining bootpath size")); - return; - } - - bootpath = (char *) grub_malloc (sz); - if (! bootpath) - { - grub_print_error (); - return; - } - grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath, - (grub_size_t) bootpath_size + 1, 0); - bootpath[bootpath_size] = '\0'; - - /* Transform an OF device path to a GRUB path. */ - - type = grub_ieee1275_get_device_type (bootpath); - if (!(type && grub_strcmp (type, "network") == 0)) - { - struct ofdisk_hash_ent *op; - char *device = grub_ieee1275_get_devname (bootpath); - op = ofdisk_hash_add (device, NULL); - op->is_boot = 1; - } - grub_free (type); - grub_free (bootpath); -} - -void -grub_ofdisk_fini (void) -{ - if (last_ihandle) - grub_ieee1275_close (last_ihandle); - last_ihandle = 0; - last_devpath = NULL; - - grub_disk_dev_unregister (&grub_ofdisk_dev); -} - -void -grub_ofdisk_init (void) -{ - grub_disk_firmware_fini = grub_ofdisk_fini; - - insert_bootpath (); - - grub_disk_dev_register (&grub_ofdisk_dev); -} - -static grub_err_t -grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size, - struct ofdisk_hash_ent *op) -{ - struct size_args_ieee1275 - { - 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_ieee1275; - - if (last_ihandle) - grub_ieee1275_close (last_ihandle); - - last_ihandle = 0; - last_devpath = NULL; - - grub_ieee1275_open (device, &last_ihandle); - if (! last_ihandle) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); - - *block_size = 0; - - if (op->block_size_fails >= 2) - return GRUB_ERR_NONE; - - INIT_IEEE1275_COMMON (&args_ieee1275.common, "call-method", 2, 2); - args_ieee1275.method = (grub_ieee1275_cell_t) "block-size"; - args_ieee1275.ihandle = last_ihandle; - args_ieee1275.result = 1; - - if (IEEE1275_CALL_ENTRY_FN (&args_ieee1275) == -1) - { - grub_dprintf ("disk", "can't get block size: failed call-method\n"); - op->block_size_fails++; - } - else if (args_ieee1275.result) - { - grub_dprintf ("disk", "can't get block size: %lld\n", - (long long) args_ieee1275.result); - op->block_size_fails++; - } - else if (args_ieee1275.size1 - && !(args_ieee1275.size1 & (args_ieee1275.size1 - 1)) - && args_ieee1275.size1 >= 512 && args_ieee1275.size1 <= 16384) - { - op->block_size_fails = 0; - *block_size = args_ieee1275.size1; - } - - return 0; -} diff --git a/grub-core/disk/key_protector.c b/grub-core/disk/key_protector.c deleted file mode 100644 index 0d146c1c0..000000000 --- a/grub-core/disk/key_protector.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct grub_key_protector *grub_key_protectors = NULL; - -grub_err_t -grub_key_protector_register (struct grub_key_protector *protector) -{ - if (protector == NULL || protector->name == NULL || protector->name[0] == '\0') - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector for registration"); - - if (grub_key_protectors != NULL && - grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), protector->name) != NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Key protector '%s' already registered", protector->name); - - grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors), GRUB_AS_LIST (protector)); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_key_protector_unregister (struct grub_key_protector *protector) -{ - if (protector == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector for unregistration"); - - grub_list_remove (GRUB_AS_LIST (protector)); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_key_protector_recover_key (const char *protector, grub_uint8_t **key, - grub_size_t *key_size) -{ - struct grub_key_protector *kp = NULL; - - if (grub_key_protectors == NULL) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "No key protector registered"); - - if (protector == NULL || protector[0] == '\0') - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector"); - - kp = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), protector); - if (kp == NULL) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "Key protector '%s' not found", protector); - - return kp->recover_key (key, key_size); -} diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c deleted file mode 100644 index 0f4f22aaa..000000000 --- a/grub-core/disk/ldm.c +++ /dev/null @@ -1,1123 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2008,2009,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef GRUB_UTIL -#include -#include -#endif - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define LDM_GUID_STRLEN 64 -#define LDM_NAME_STRLEN 32 - -typedef grub_uint8_t *grub_ldm_id_t; - -enum { STRIPE = 1, SPANNED = 2, RAID5 = 3 }; - -#define LDM_LABEL_SECTOR 6 -struct grub_ldm_vblk { - char magic[4]; - grub_uint8_t unused1[12]; - grub_uint16_t update_status; - grub_uint8_t flags; - grub_uint8_t type; - grub_uint32_t unused2; - grub_uint8_t dynamic[104]; -} GRUB_PACKED; -#define LDM_VBLK_MAGIC "VBLK" - -enum - { - STATUS_CONSISTENT = 0, - STATUS_STILL_ACTIVE = 1, - STATUS_NOT_ACTIVE_YET = 2 - }; - -enum - { - ENTRY_COMPONENT = 0x32, - ENTRY_PARTITION = 0x33, - ENTRY_DISK = 0x34, - ENTRY_VOLUME = 0x51, - }; - -struct grub_ldm_label -{ - char magic[8]; - grub_uint32_t unused1; - grub_uint16_t ver_major; - grub_uint16_t ver_minor; - grub_uint8_t unused2[32]; - char disk_guid[LDM_GUID_STRLEN]; - char host_guid[LDM_GUID_STRLEN]; - char group_guid[LDM_GUID_STRLEN]; - char group_name[LDM_NAME_STRLEN]; - grub_uint8_t unused3[11]; - grub_uint64_t pv_start; - grub_uint64_t pv_size; - grub_uint64_t config_start; - grub_uint64_t config_size; -} GRUB_PACKED; - - -#define LDM_MAGIC "PRIVHEAD" - - - -static inline grub_uint64_t -read_int (grub_uint8_t *in, grub_size_t s) -{ - grub_uint8_t *ptr2; - grub_uint64_t ret; - ret = 0; - for (ptr2 = in; ptr2 < in + s; ptr2++) - { - ret <<= 8; - ret |= *ptr2; - } - return ret; -} - -static int -check_ldm_partition (grub_disk_t disk __attribute__ ((unused)), const grub_partition_t p, void *data) -{ - int *has_ldm = data; - - if (p->number >= 4) - return 1; - if (p->msdostype == GRUB_PC_PARTITION_TYPE_LDM) - { - *has_ldm = 1; - return 1; - } - return 0; -} - -static int -msdos_has_ldm_partition (grub_disk_t dsk) -{ - grub_err_t err; - int has_ldm = 0; - - err = grub_partition_msdos_iterate (dsk, check_ldm_partition, &has_ldm); - if (err) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - - return has_ldm; -} - -static const grub_guid_t ldm_type = GRUB_GPT_PARTITION_TYPE_LDM; - -/* Helper for gpt_ldm_sector. */ -static int -gpt_ldm_sector_iter (grub_disk_t disk, const grub_partition_t p, void *data) -{ - grub_disk_addr_t *sector = data; - struct grub_gpt_partentry gptdata; - grub_partition_t p2; - - p2 = disk->partition; - disk->partition = p->parent; - if (grub_disk_read (disk, p->offset, p->index, - sizeof (gptdata), &gptdata)) - { - disk->partition = p2; - return 0; - } - disk->partition = p2; - - if (! grub_memcmp (&gptdata.type, &ldm_type, 16)) - { - *sector = p->start + p->len - 1; - return 1; - } - return 0; -} - -static grub_disk_addr_t -gpt_ldm_sector (grub_disk_t dsk) -{ - grub_disk_addr_t sector = 0; - grub_err_t err; - - err = grub_gpt_partition_map_iterate (dsk, gpt_ldm_sector_iter, §or); - if (err) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - return sector; -} - -static void -free_pv (struct grub_diskfilter_pv *pv) -{ - if (pv == NULL) - return; - - grub_free (pv->internal_id); - grub_free (pv->id.uuid); - grub_free (pv); -} - -static void -free_lv (struct grub_diskfilter_lv *lv) -{ - if (lv == NULL) - return; - - grub_free (lv->internal_id); - grub_free (lv->name); - grub_free (lv->fullname); - if (lv->segments) - { - unsigned int i; - for (i = 0; i < lv->segment_count; i++) - grub_free (lv->segments[i].nodes); - grub_free (lv->segments); - } - grub_free (lv); -} - -static struct grub_diskfilter_vg * -make_vg (grub_disk_t disk, - const struct grub_ldm_label *label) -{ - grub_disk_addr_t startsec, endsec, cursec; - struct grub_diskfilter_vg *vg; - grub_err_t err; - - /* First time we see this volume group. We've to create the - whole volume group structure. */ - vg = grub_malloc (sizeof (*vg)); - if (! vg) - return NULL; - vg->extent_size = 1; - vg->name = grub_malloc (LDM_NAME_STRLEN + 1); - vg->uuid = grub_malloc (LDM_GUID_STRLEN + 1); - if (! vg->uuid || !vg->name) - goto fail1; - - grub_memcpy (vg->uuid, label->group_guid, LDM_GUID_STRLEN); - grub_memcpy (vg->name, label->group_name, LDM_NAME_STRLEN); - vg->name[LDM_NAME_STRLEN] = 0; - vg->uuid[LDM_GUID_STRLEN] = 0; - vg->uuid_len = grub_strlen (vg->uuid); - - vg->lvs = NULL; - vg->pvs = NULL; - - startsec = grub_be_to_cpu64 (label->config_start); - endsec = startsec + grub_be_to_cpu64 (label->config_size); - - /* First find disks. */ - for (cursec = startsec + 0x12; cursec < endsec; cursec++) - { - struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE - / sizeof (struct grub_ldm_vblk)]; - unsigned i; - grub_size_t sz; - err = grub_disk_read (disk, cursec, 0, - sizeof(vblk), &vblk); - if (err) - goto fail2; - - for (i = 0; i < ARRAY_SIZE (vblk); i++) - { - struct grub_diskfilter_pv *pv; - grub_uint8_t *ptr; - if (grub_memcmp (vblk[i].magic, LDM_VBLK_MAGIC, - sizeof (vblk[i].magic)) != 0) - continue; - if (grub_be_to_cpu16 (vblk[i].update_status) - != STATUS_CONSISTENT - && grub_be_to_cpu16 (vblk[i].update_status) - != STATUS_STILL_ACTIVE) - continue; - if (vblk[i].type != ENTRY_DISK) - continue; - pv = grub_zalloc (sizeof (*pv)); - if (!pv) - goto fail2; - - pv->disk = 0; - ptr = vblk[i].dynamic; - if (ptr + *ptr + 1 >= vblk[i].dynamic - + sizeof (vblk[i].dynamic)) - { - grub_free (pv); - goto fail2; - } - if (grub_add (ptr[0], 2, &sz)) - { - grub_free (pv); - goto fail2; - } - - pv->internal_id = grub_malloc (sz); - if (!pv->internal_id) - { - free_pv (pv); - goto fail2; - } - grub_memcpy (pv->internal_id, ptr, (grub_size_t) ptr[0] + 1); - pv->internal_id[(grub_size_t) ptr[0] + 1] = 0; - - ptr += *ptr + 1; - if (ptr + *ptr + 1 >= vblk[i].dynamic - + sizeof (vblk[i].dynamic)) - { - free_pv (pv); - goto fail2; - } - /* ptr = name. */ - ptr += *ptr + 1; - if (ptr + *ptr + 1 - >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - free_pv (pv); - goto fail2; - } - pv->id.uuidlen = *ptr; - - if (grub_add (pv->id.uuidlen, 1, &sz)) - { - free_pv (pv); - goto fail2; - } - - pv->id.uuid = grub_malloc (sz); - if (pv->id.uuid == NULL) - { - free_pv (pv); - goto fail2; - } - grub_memcpy (pv->id.uuid, ptr + 1, pv->id.uuidlen); - pv->id.uuid[pv->id.uuidlen] = 0; - - pv->next = vg->pvs; - vg->pvs = pv; - } - } - - /* Then find LVs. */ - for (cursec = startsec + 0x12; cursec < endsec; cursec++) - { - struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE - / sizeof (struct grub_ldm_vblk)]; - unsigned i; - grub_size_t sz; - err = grub_disk_read (disk, cursec, 0, - sizeof(vblk), &vblk); - if (err) - goto fail2; - - for (i = 0; i < ARRAY_SIZE (vblk); i++) - { - struct grub_diskfilter_lv *lv; - grub_uint8_t *ptr; - if (grub_memcmp (vblk[i].magic, LDM_VBLK_MAGIC, - sizeof (vblk[i].magic)) != 0) - continue; - if (grub_be_to_cpu16 (vblk[i].update_status) - != STATUS_CONSISTENT - && grub_be_to_cpu16 (vblk[i].update_status) - != STATUS_STILL_ACTIVE) - continue; - if (vblk[i].type != ENTRY_VOLUME) - continue; - lv = grub_zalloc (sizeof (*lv)); - if (!lv) - goto fail2; - - lv->vg = vg; - lv->segment_count = 1; - lv->segment_alloc = 1; - lv->visible = 1; - lv->segments = grub_zalloc (sizeof (*lv->segments)); - if (!lv->segments) - { - free_lv (lv); - goto fail2; - } - lv->segments->start_extent = 0; - lv->segments->type = GRUB_DISKFILTER_MIRROR; - lv->segments->node_count = 0; - lv->segments->node_alloc = 8; - lv->segments->nodes = grub_calloc (lv->segments->node_alloc, - sizeof (*lv->segments->nodes)); - if (!lv->segments->nodes) - { - free_lv (lv); - goto fail2; - } - ptr = vblk[i].dynamic; - if (ptr + *ptr + 1 >= vblk[i].dynamic - + sizeof (vblk[i].dynamic)) - { - free_lv (lv); - goto fail2; - } - if (grub_add (ptr[0], 2, &sz)) - { - free_lv (lv); - goto fail2; - } - lv->internal_id = grub_malloc (sz); - if (!lv->internal_id) - { - free_lv (lv); - goto fail2; - } - grub_memcpy (lv->internal_id, ptr, ptr[0] + 1); - lv->internal_id[ptr[0] + 1] = 0; - - ptr += *ptr + 1; - if (ptr + *ptr + 1 >= vblk[i].dynamic - + sizeof (vblk[i].dynamic)) - { - free_lv (lv); - goto fail2; - } - if (grub_add (*ptr, 1, &sz)) - { - free_lv (lv); - goto fail2; - } - lv->name = grub_malloc (sz); - if (!lv->name) - { - free_lv (lv); - goto fail2; - } - grub_memcpy (lv->name, ptr + 1, *ptr); - lv->name[*ptr] = 0; - lv->fullname = grub_xasprintf ("ldm/%s/%s", - vg->uuid, lv->name); - if (!lv->fullname) - { - free_lv (lv); - goto fail2; - } - ptr += *ptr + 1; - if (ptr + *ptr + 1 - >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - free_lv (lv); - goto fail2; - } - /* ptr = volume type. */ - ptr += *ptr + 1; - if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - free_lv (lv); - goto fail2; - } - /* ptr = flags. */ - ptr += *ptr + 1; - if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - free_lv (lv); - goto fail2; - } - - /* Skip state, type, unknown, volume number, zeros, flags. */ - ptr += 14 + 1 + 1 + 1 + 3 + 1; - /* ptr = number of children. */ - if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - free_lv (lv); - goto fail2; - } - ptr += *ptr + 1; - if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - free_lv (lv); - goto fail2; - } - - /* Skip 2 more fields. */ - ptr += 8 + 8; - if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic) - || ptr + *ptr + 1>= vblk[i].dynamic - + sizeof (vblk[i].dynamic)) - { - free_lv (lv); - goto fail2; - } - lv->size = read_int (ptr + 1, *ptr); - lv->segments->extent_count = lv->size; - - lv->next = vg->lvs; - vg->lvs = lv; - } - } - - /* Now the components. */ - for (cursec = startsec + 0x12; cursec < endsec; cursec++) - { - struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE - / sizeof (struct grub_ldm_vblk)]; - unsigned i; - grub_size_t sz; - err = grub_disk_read (disk, cursec, 0, - sizeof(vblk), &vblk); - if (err) - goto fail2; - - for (i = 0; i < ARRAY_SIZE (vblk); i++) - { - struct grub_diskfilter_lv *comp; - struct grub_diskfilter_lv *lv; - grub_uint8_t type; - - grub_uint8_t *ptr; - if (grub_memcmp (vblk[i].magic, LDM_VBLK_MAGIC, - sizeof (vblk[i].magic)) != 0) - continue; - if (grub_be_to_cpu16 (vblk[i].update_status) - != STATUS_CONSISTENT - && grub_be_to_cpu16 (vblk[i].update_status) - != STATUS_STILL_ACTIVE) - continue; - if (vblk[i].type != ENTRY_COMPONENT) - continue; - comp = grub_zalloc (sizeof (*comp)); - if (!comp) - goto fail2; - comp->visible = 0; - comp->name = 0; - comp->fullname = 0; - - ptr = vblk[i].dynamic; - if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - free_lv (comp); - goto fail2; - } - if (grub_add (ptr[0], 2, &sz)) - { - free_lv (comp); - goto fail2; - } - comp->internal_id = grub_malloc (sz); - if (!comp->internal_id) - { - free_lv (comp); - goto fail2; - } - grub_memcpy (comp->internal_id, ptr, ptr[0] + 1); - comp->internal_id[ptr[0] + 1] = 0; - - ptr += *ptr + 1; - if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - free_lv (comp); - goto fail2; - } - /* ptr = name. */ - ptr += *ptr + 1; - if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - free_lv (comp); - goto fail2; - } - /* ptr = state. */ - ptr += *ptr + 1; - type = *ptr++; - /* skip zeros. */ - ptr += 4; - if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - free_lv (comp); - goto fail2; - } - - /* ptr = number of children. */ - ptr += *ptr + 1; - if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - free_lv (comp); - goto fail2; - } - ptr += 8 + 8; - if (ptr + *ptr + 1 >= vblk[i].dynamic - + sizeof (vblk[i].dynamic)) - { - free_lv (comp); - goto fail2; - } - for (lv = vg->lvs; lv; lv = lv->next) - { - if (lv->internal_id[0] == ptr[0] - && grub_memcmp (lv->internal_id + 1, ptr + 1, ptr[0]) == 0) - break; - } - if (!lv) - { - free_lv (comp); - continue; - } - comp->size = lv->size; - if (type == SPANNED) - { - comp->segment_alloc = 8; - comp->segment_count = 0; - comp->segments = grub_calloc (comp->segment_alloc, - sizeof (*comp->segments)); - if (!comp->segments) - { - free_lv (comp); - goto fail2; - } - } - else - { - comp->segment_alloc = 1; - comp->segment_count = 1; - comp->segments = grub_malloc (sizeof (*comp->segments)); - if (!comp->segments) - { - free_lv (comp); - goto fail2; - } - comp->segments->start_extent = 0; - comp->segments->extent_count = lv->size; - comp->segments->layout = 0; - if (type == STRIPE) - comp->segments->type = GRUB_DISKFILTER_STRIPED; - else if (type == RAID5) - { - comp->segments->type = GRUB_DISKFILTER_RAID5; - comp->segments->layout = GRUB_RAID_LAYOUT_SYMMETRIC_MASK; - } - else - { - free_lv (comp); - goto fail2; - } - ptr += *ptr + 1; - ptr++; - if (!(vblk[i].flags & 0x10)) - { - free_lv (comp); - goto fail2; - } - if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic) - || ptr + *ptr + 1 >= vblk[i].dynamic - + sizeof (vblk[i].dynamic)) - { - free_lv (comp); - goto fail2; - } - comp->segments->stripe_size = read_int (ptr + 1, *ptr); - ptr += *ptr + 1; - if (ptr + *ptr + 1 >= vblk[i].dynamic - + sizeof (vblk[i].dynamic)) - { - free_lv (comp); - goto fail2; - } - comp->segments->node_count = read_int (ptr + 1, *ptr); - comp->segments->node_alloc = comp->segments->node_count; - comp->segments->nodes = grub_calloc (comp->segments->node_alloc, - sizeof (*comp->segments->nodes)); - if (comp->segments->nodes == NULL) - { - free_lv (comp); - goto fail2; - } - } - - if (lv->segments->node_alloc == lv->segments->node_count) - { - void *t; - - if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) || - grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz)) - { - free_lv (comp); - goto fail2; - } - - t = grub_realloc (lv->segments->nodes, sz); - if (!t) - { - free_lv (comp); - goto fail2; - } - lv->segments->nodes = t; - } - lv->segments->nodes[lv->segments->node_count].pv = 0; - lv->segments->nodes[lv->segments->node_count].start = 0; - lv->segments->nodes[lv->segments->node_count++].lv = comp; - comp->next = vg->lvs; - vg->lvs = comp; - } - } - /* Partitions. */ - for (cursec = startsec + 0x12; cursec < endsec; cursec++) - { - struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE - / sizeof (struct grub_ldm_vblk)]; - unsigned i; - err = grub_disk_read (disk, cursec, 0, - sizeof(vblk), &vblk); - if (err) - goto fail2; - - for (i = 0; i < ARRAY_SIZE (vblk); i++) - { - struct grub_diskfilter_lv *comp; - struct grub_diskfilter_node part; - grub_disk_addr_t start, size; - - grub_uint8_t *ptr; - part.name = 0; - if (grub_memcmp (vblk[i].magic, LDM_VBLK_MAGIC, - sizeof (vblk[i].magic)) != 0) - continue; - if (grub_be_to_cpu16 (vblk[i].update_status) - != STATUS_CONSISTENT - && grub_be_to_cpu16 (vblk[i].update_status) - != STATUS_STILL_ACTIVE) - continue; - if (vblk[i].type != ENTRY_PARTITION) - continue; - part.lv = 0; - part.pv = 0; - - ptr = vblk[i].dynamic; - if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - goto fail2; - } - /* ID */ - ptr += *ptr + 1; - if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - goto fail2; - } - /* ptr = name. */ - ptr += *ptr + 1; - if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - goto fail2; - } - - /* skip zeros and logcommit id. */ - ptr += 4 + 8; - if (ptr + 16 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - goto fail2; - } - part.start = read_int (ptr, 8); - start = read_int (ptr + 8, 8); - ptr += 16; - if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic) - || ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - goto fail2; - } - size = read_int (ptr + 1, *ptr); - ptr += *ptr + 1; - if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic) - || ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - goto fail2; - } - - for (comp = vg->lvs; comp; comp = comp->next) - if (comp->internal_id[0] == ptr[0] - && grub_memcmp (ptr + 1, comp->internal_id + 1, - comp->internal_id[0]) == 0) - goto out; - continue; - out: - if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic) - || ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { - goto fail2; - } - ptr += *ptr + 1; - struct grub_diskfilter_pv *pv; - for (pv = vg->pvs; pv; pv = pv->next) - if (pv->internal_id[0] == ptr[0] - && grub_memcmp (pv->internal_id + 1, ptr + 1, ptr[0]) == 0) - part.pv = pv; - - if (comp->segment_alloc == 1) - { - unsigned node_index; - ptr += *ptr + 1; - if (ptr + *ptr + 1 >= vblk[i].dynamic - + sizeof (vblk[i].dynamic)) - { - goto fail2; - } - node_index = read_int (ptr + 1, *ptr); - if (node_index < comp->segments->node_count) - comp->segments->nodes[node_index] = part; - } - else - { - if (comp->segment_alloc == comp->segment_count) - { - void *t; - grub_size_t sz; - - if (grub_mul (comp->segment_alloc, 2, &comp->segment_alloc) || - grub_mul (comp->segment_alloc, sizeof (*comp->segments), &sz)) - goto fail2; - - t = grub_realloc (comp->segments, sz); - if (!t) - goto fail2; - comp->segments = t; - } - comp->segments[comp->segment_count].start_extent = start; - comp->segments[comp->segment_count].extent_count = size; - comp->segments[comp->segment_count].type = GRUB_DISKFILTER_STRIPED; - comp->segments[comp->segment_count].node_count = 1; - comp->segments[comp->segment_count].node_alloc = 1; - comp->segments[comp->segment_count].nodes - = grub_malloc (sizeof (*comp->segments[comp->segment_count].nodes)); - if (!comp->segments[comp->segment_count].nodes) - { - grub_free (comp->segments); - goto fail2; - } - comp->segments[comp->segment_count].nodes[0] = part; - comp->segment_count++; - } - } - } - if (grub_diskfilter_vg_register (vg)) - goto fail2; - return vg; - fail2: - { - struct grub_diskfilter_lv *lv, *next_lv; - struct grub_diskfilter_pv *pv, *next_pv; - for (lv = vg->lvs; lv; lv = next_lv) - { - next_lv = lv->next; - free_lv (lv); - - } - for (pv = vg->pvs; pv; pv = next_pv) - { - next_pv = pv->next; - free_pv (pv); - } - } - fail1: - grub_free (vg->uuid); - grub_free (vg->name); - grub_free (vg); - return NULL; -} - -static struct grub_diskfilter_vg * -grub_ldm_detect (grub_disk_t disk, - struct grub_diskfilter_pv_id *id, - grub_disk_addr_t *start_sector) -{ - grub_err_t err; - struct grub_ldm_label label; - struct grub_diskfilter_vg *vg; - -#ifdef GRUB_UTIL - grub_util_info ("scanning %s for LDM", disk->name); -#endif - - { - int i; - int has_ldm = msdos_has_ldm_partition (disk); - for (i = 0; i < 3; i++) - { - grub_disk_addr_t sector = LDM_LABEL_SECTOR; - switch (i) - { - case 0: - if (!has_ldm) - continue; - sector = LDM_LABEL_SECTOR; - break; - case 1: - /* LDM is never inside a partition. */ - if (!has_ldm || disk->partition) - continue; - sector = grub_disk_native_sectors (disk); - if (sector == GRUB_DISK_SIZE_UNKNOWN) - continue; - sector--; - break; - /* FIXME: try the third copy. */ - case 2: - sector = gpt_ldm_sector (disk); - if (!sector) - continue; - break; - } - err = grub_disk_read (disk, sector, 0, - sizeof(label), &label); - if (err) - return NULL; - if (grub_memcmp (label.magic, LDM_MAGIC, sizeof (label.magic)) == 0 - && grub_be_to_cpu16 (label.ver_major) == 0x02 - && grub_be_to_cpu16 (label.ver_minor) >= 0x0b - && grub_be_to_cpu16 (label.ver_minor) <= 0x0c) - break; - } - - /* Return if we didn't find a label. */ - if (i == 3) - { -#ifdef GRUB_UTIL - grub_util_info ("no LDM signature found"); -#endif - return NULL; - } - } - - id->uuid = grub_malloc (LDM_GUID_STRLEN + 1); - if (!id->uuid) - return NULL; - grub_memcpy (id->uuid, label.disk_guid, LDM_GUID_STRLEN); - id->uuid[LDM_GUID_STRLEN] = 0; - id->uuidlen = grub_strlen ((char *) id->uuid); - *start_sector = grub_be_to_cpu64 (label.pv_start); - - { - grub_size_t s; - for (s = 0; s < LDM_GUID_STRLEN && label.group_guid[s]; s++); - vg = grub_diskfilter_get_vg_by_uuid (s, label.group_guid); - if (! vg) - vg = make_vg (disk, &label); - } - - if (!vg) - { - grub_free (id->uuid); - return NULL; - } - return vg; -} - -#ifdef GRUB_UTIL - -char * -grub_util_get_ldm (grub_disk_t disk, grub_disk_addr_t start) -{ - struct grub_diskfilter_pv *pv = NULL; - struct grub_diskfilter_vg *vg = NULL; - struct grub_diskfilter_lv *res = 0, *lv, *res_lv = 0; - - pv = grub_diskfilter_get_pv_from_disk (disk, &vg); - - if (!pv) - return NULL; - - for (lv = vg->lvs; lv; lv = lv->next) - if (lv->segment_count == 1 && lv->segments->node_count == 1 - && lv->segments->type == GRUB_DISKFILTER_STRIPED - && lv->segments->nodes->pv == pv - && lv->segments->nodes->start + pv->start_sector == start) - { - res_lv = lv; - break; - } - if (!res_lv) - return NULL; - for (lv = vg->lvs; lv; lv = lv->next) - if (lv->segment_count == 1 && lv->segments->node_count == 1 - && lv->segments->type == GRUB_DISKFILTER_MIRROR - && lv->segments->nodes->lv == res_lv) - { - res = lv; - break; - } - if (res && res->fullname) - return grub_strdup (res->fullname); - return NULL; -} - -int -grub_util_is_ldm (grub_disk_t disk) -{ - int i; - int has_ldm = msdos_has_ldm_partition (disk); - for (i = 0; i < 3; i++) - { - grub_disk_addr_t sector = LDM_LABEL_SECTOR; - grub_err_t err; - struct grub_ldm_label label; - - switch (i) - { - case 0: - if (!has_ldm) - continue; - sector = LDM_LABEL_SECTOR; - break; - case 1: - /* LDM is never inside a partition. */ - if (!has_ldm || disk->partition) - continue; - sector = grub_disk_native_sectors (disk); - if (sector == GRUB_DISK_SIZE_UNKNOWN) - continue; - sector--; - break; - /* FIXME: try the third copy. */ - case 2: - sector = gpt_ldm_sector (disk); - if (!sector) - continue; - break; - } - err = grub_disk_read (disk, sector, 0, sizeof(label), &label); - if (err) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - /* This check is more relaxed on purpose. */ - if (grub_memcmp (label.magic, LDM_MAGIC, sizeof (label.magic)) == 0) - return 1; - } - - return 0; -} - -grub_err_t -grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors, - unsigned int max_nsectors, - grub_embed_type_t embed_type, - grub_disk_addr_t **sectors) -{ - struct grub_diskfilter_pv *pv = NULL; - struct grub_diskfilter_vg *vg; - struct grub_diskfilter_lv *lv; - unsigned i; - - if (embed_type != GRUB_EMBED_PCBIOS) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "LDM currently supports only PC-BIOS embedding"); - if (disk->partition) - return grub_error (GRUB_ERR_BUG, "disk isn't LDM"); - pv = grub_diskfilter_get_pv_from_disk (disk, &vg); - if (!pv) - return grub_error (GRUB_ERR_BUG, "disk isn't LDM"); - for (lv = vg->lvs; lv; lv = lv->next) - { - struct grub_diskfilter_lv *comp; - - if (!lv->visible || !lv->fullname) - continue; - - if (lv->segment_count != 1) - continue; - if (lv->segments->type != GRUB_DISKFILTER_MIRROR - || lv->segments->node_count != 1 - || lv->segments->start_extent != 0 - || lv->segments->extent_count != lv->size) - continue; - - comp = lv->segments->nodes->lv; - if (!comp) - continue; - - if (comp->segment_count != 1 || comp->size != lv->size) - continue; - if (comp->segments->type != GRUB_DISKFILTER_STRIPED - || comp->segments->node_count != 1 - || comp->segments->start_extent != 0 - || comp->segments->extent_count != lv->size) - continue; - - /* How to implement proper check is to be discussed. */ -#if 1 - if (1) - continue; -#else - if (grub_strcmp (lv->name, "Volume5") != 0) - continue; -#endif - if (lv->size < *nsectors) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - /* TRANSLATORS: it's a partition for embedding, - not a partition embed into something. GRUB - install tools put core.img into a place - usable for bootloaders (called generically - "embedding zone") and this operation is - called "embedding". */ - N_("your LDM Embedding Partition is too small;" - " embedding won't be possible")); - *nsectors = lv->size; - if (*nsectors > max_nsectors) - *nsectors = max_nsectors; - *sectors = grub_calloc (*nsectors, sizeof (**sectors)); - if (!*sectors) - return grub_errno; - for (i = 0; i < *nsectors; i++) - (*sectors)[i] = (lv->segments->nodes->start - + comp->segments->nodes->start - + comp->segments->nodes->pv->start_sector + i); - return GRUB_ERR_NONE; - } - - return grub_error (GRUB_ERR_FILE_NOT_FOUND, - /* TRANSLATORS: it's a partition for embedding, - not a partition embed into something. */ - N_("this LDM has no Embedding Partition;" - " embedding won't be possible")); -} -#endif - -static struct grub_diskfilter grub_ldm_dev = { - .name = "ldm", - .detect = grub_ldm_detect, - .next = 0 -}; - -GRUB_MOD_INIT (ldm) -{ - grub_diskfilter_register_back (&grub_ldm_dev); -} - -GRUB_MOD_FINI (ldm) -{ - grub_diskfilter_unregister (&grub_ldm_dev); -} diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c deleted file mode 100644 index 9e1e6a5d9..000000000 --- a/grub-core/disk/luks.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2007,2010,2011,2019 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define LUKS_KEY_ENABLED 0x00AC71F3 - -/* On disk LUKS header */ -struct grub_luks_phdr -{ - grub_uint8_t magic[6]; -#define LUKS_MAGIC "LUKS\xBA\xBE" - grub_uint16_t version; - char cipherName[32]; - char cipherMode[32]; - char hashSpec[32]; - grub_uint32_t payloadOffset; - grub_uint32_t keyBytes; - grub_uint8_t mkDigest[20]; - grub_uint8_t mkDigestSalt[32]; - grub_uint32_t mkDigestIterations; - char uuid[40]; - struct - { - grub_uint32_t active; - grub_uint32_t passwordIterations; - grub_uint8_t passwordSalt[32]; - grub_uint32_t keyMaterialOffset; - grub_uint32_t stripes; - } keyblock[8]; -} GRUB_PACKED; - -typedef struct grub_luks_phdr *grub_luks_phdr_t; - -gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, - grub_uint8_t * dst, grub_size_t blocksize, - grub_size_t blocknumbers); - -static grub_cryptodisk_t -luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) -{ - grub_cryptodisk_t newdev; - struct grub_luks_phdr header; - char ciphername[sizeof (header.cipherName) + 1]; - char ciphermode[sizeof (header.cipherMode) + 1]; - char hashspec[sizeof (header.hashSpec) + 1]; - grub_err_t err; - - if (cargs->check_boot) - return NULL; - - /* Read the LUKS header. */ - err = grub_disk_read (disk, 0, 0, sizeof (header), &header); - if (err) - { - if (err == GRUB_ERR_OUT_OF_RANGE) - grub_errno = GRUB_ERR_NONE; - return NULL; - } - - /* Look for LUKS magic sequence. */ - if (grub_memcmp (header.magic, LUKS_MAGIC, sizeof (header.magic)) - || grub_be_to_cpu16 (header.version) != 1) - return NULL; - - if (cargs->search_uuid != NULL && grub_uuidcasecmp (cargs->search_uuid, header.uuid, sizeof (header.uuid)) != 0) - { - grub_dprintf ("luks", "%s != %s\n", header.uuid, cargs->search_uuid); - return NULL; - } - - /* Make sure that strings are null terminated. */ - grub_memcpy (ciphername, header.cipherName, sizeof (header.cipherName)); - ciphername[sizeof (header.cipherName)] = 0; - grub_memcpy (ciphermode, header.cipherMode, sizeof (header.cipherMode)); - ciphermode[sizeof (header.cipherMode)] = 0; - grub_memcpy (hashspec, header.hashSpec, sizeof (header.hashSpec)); - hashspec[sizeof (header.hashSpec)] = 0; - - newdev = grub_zalloc (sizeof (struct grub_cryptodisk)); - if (!newdev) - return NULL; - newdev->offset_sectors = grub_be_to_cpu32 (header.payloadOffset); - newdev->source_disk = NULL; - newdev->log_sector_size = GRUB_LUKS1_LOG_SECTOR_SIZE; - newdev->total_sectors = grub_disk_native_sectors (disk) - newdev->offset_sectors; - grub_memcpy (newdev->uuid, header.uuid, sizeof (header.uuid)); - newdev->modname = "luks"; - - /* Configure the hash used for the AF splitter and HMAC. */ - newdev->hash = grub_crypto_lookup_md_by_name (hashspec); - if (!newdev->hash) - { - grub_free (newdev); - grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", - hashspec); - return NULL; - } - - err = grub_cryptodisk_setcipher (newdev, ciphername, ciphermode); - if (err) - { - grub_free (newdev); - return NULL; - } - - COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (header.uuid)); - return newdev; -} - -static grub_err_t -luks_recover_key (grub_disk_t source, - grub_cryptodisk_t dev, - grub_cryptomount_args_t cargs) -{ - struct grub_luks_phdr header; - grub_size_t keysize; - grub_uint8_t *split_key = NULL; - grub_uint8_t candidate_digest[sizeof (header.mkDigest)]; - unsigned i; - grub_size_t length; - grub_err_t err; - grub_size_t max_stripes = 1; - - if (cargs->key_data == NULL || cargs->key_len == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data"); - - err = grub_disk_read (source, 0, 0, sizeof (header), &header); - if (err) - return err; - - grub_puts_ (N_("Attempting to decrypt master key...")); - keysize = grub_be_to_cpu32 (header.keyBytes); - if (keysize > GRUB_CRYPTODISK_MAX_KEYLEN) - return grub_error (GRUB_ERR_BAD_FS, "key is too long"); - - for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) - if (grub_be_to_cpu32 (header.keyblock[i].active) == LUKS_KEY_ENABLED - && grub_be_to_cpu32 (header.keyblock[i].stripes) > max_stripes) - max_stripes = grub_be_to_cpu32 (header.keyblock[i].stripes); - - split_key = grub_calloc (keysize, max_stripes); - if (!split_key) - return grub_errno; - - /* Try to recover master key from each active keyslot. */ - for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) - { - gcry_err_code_t gcry_err; - grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN]; - grub_uint8_t digest[GRUB_CRYPTODISK_MAX_KEYLEN]; - - /* Check if keyslot is enabled. */ - if (grub_be_to_cpu32 (header.keyblock[i].active) != LUKS_KEY_ENABLED) - continue; - - grub_dprintf ("luks", "Trying keyslot %d\n", i); - - /* Calculate the PBKDF2 of the user supplied passphrase. */ - gcry_err = grub_crypto_pbkdf2 (dev->hash, cargs->key_data, - cargs->key_len, - header.keyblock[i].passwordSalt, - sizeof (header.keyblock[i].passwordSalt), - grub_be_to_cpu32 (header.keyblock[i]. - passwordIterations), - digest, keysize); - - if (gcry_err) - { - grub_free (split_key); - return grub_crypto_gcry_error (gcry_err); - } - - grub_dprintf ("luks", "PBKDF2 done\n"); - - gcry_err = grub_cryptodisk_setkey (dev, digest, keysize); - if (gcry_err) - { - grub_free (split_key); - return grub_crypto_gcry_error (gcry_err); - } - - length = (keysize * grub_be_to_cpu32 (header.keyblock[i].stripes)); - - /* Read and decrypt the key material from the disk. */ - err = grub_disk_read (source, - grub_be_to_cpu32 (header.keyblock - [i].keyMaterialOffset), 0, - length, split_key); - if (err) - { - grub_free (split_key); - return err; - } - - gcry_err = grub_cryptodisk_decrypt (dev, split_key, length, 0, - GRUB_LUKS1_LOG_SECTOR_SIZE); - if (gcry_err) - { - grub_free (split_key); - return grub_crypto_gcry_error (gcry_err); - } - - /* Merge the decrypted key material to get the candidate master key. */ - gcry_err = AF_merge (dev->hash, split_key, candidate_key, keysize, - grub_be_to_cpu32 (header.keyblock[i].stripes)); - if (gcry_err) - { - grub_free (split_key); - return grub_crypto_gcry_error (gcry_err); - } - - grub_dprintf ("luks", "candidate key recovered\n"); - - /* Calculate the PBKDF2 of the candidate master key. */ - gcry_err = grub_crypto_pbkdf2 (dev->hash, candidate_key, - grub_be_to_cpu32 (header.keyBytes), - header.mkDigestSalt, - sizeof (header.mkDigestSalt), - grub_be_to_cpu32 - (header.mkDigestIterations), - candidate_digest, - sizeof (candidate_digest)); - if (gcry_err) - { - grub_free (split_key); - return grub_crypto_gcry_error (gcry_err); - } - - /* Compare the calculated PBKDF2 to the digest stored - in the header to see if it's correct. */ - if (grub_memcmp (candidate_digest, header.mkDigest, - sizeof (header.mkDigest)) != 0) - { - grub_dprintf ("luks", "bad digest\n"); - continue; - } - - /* TRANSLATORS: It's a cryptographic key slot: one element of an array - where each element is either empty or holds a key. */ - grub_printf_ (N_("Slot %d opened\n"), i); - - /* Set the master key. */ - gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize); - if (gcry_err) - { - grub_free (split_key); - return grub_crypto_gcry_error (gcry_err); - } - - grub_free (split_key); - - return GRUB_ERR_NONE; - } - - grub_free (split_key); - return GRUB_ACCESS_DENIED; -} - -struct grub_cryptodisk_dev luks_crypto = { - .scan = luks_scan, - .recover_key = luks_recover_key -}; - -GRUB_MOD_INIT (luks) -{ - COMPILE_TIME_ASSERT (sizeof (((struct grub_luks_phdr *) 0)->uuid) - < GRUB_CRYPTODISK_MAX_UUID_LENGTH); - grub_cryptodisk_dev_register (&luks_crypto); -} - -GRUB_MOD_FINI (luks) -{ - grub_cryptodisk_dev_unregister (&luks_crypto); -} diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c deleted file mode 100644 index b17cd2115..000000000 --- a/grub-core/disk/luks2.c +++ /dev/null @@ -1,810 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2019 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define LUKS_MAGIC_1ST "LUKS\xBA\xBE" -#define LUKS_MAGIC_2ND "SKUL\xBA\xBE" - -enum grub_luks2_kdf_type -{ - LUKS2_KDF_TYPE_ARGON2I, - LUKS2_KDF_TYPE_PBKDF2 -}; -typedef enum grub_luks2_kdf_type grub_luks2_kdf_type_t; - -/* On disk LUKS header */ -struct grub_luks2_header -{ - char magic[6]; - grub_uint16_t version; - grub_uint64_t hdr_size; - grub_uint64_t seqid; - char label[48]; - char csum_alg[32]; - grub_uint8_t salt[64]; - char uuid[40]; - char subsystem[48]; - grub_uint64_t hdr_offset; - char _padding[184]; - grub_uint8_t csum[64]; - char _padding4096[7*512]; -} GRUB_PACKED; -typedef struct grub_luks2_header grub_luks2_header_t; - -struct grub_luks2_keyslot -{ - /* The integer key to the associative array of keyslots. */ - grub_uint64_t idx; - grub_int64_t key_size; - grub_int64_t priority; - struct - { - const char *encryption; - grub_uint64_t offset; - grub_uint64_t size; - grub_int64_t key_size; - } area; - struct - { - const char *hash; - grub_int64_t stripes; - } af; - struct - { - grub_luks2_kdf_type_t type; - const char *salt; - union - { - struct - { - grub_int64_t time; - grub_int64_t memory; - grub_int64_t cpus; - } argon2i; - struct - { - const char *hash; - grub_int64_t iterations; - } pbkdf2; - } u; - } kdf; -}; -typedef struct grub_luks2_keyslot grub_luks2_keyslot_t; - -struct grub_luks2_segment -{ - grub_uint64_t idx; - grub_uint64_t offset; - const char *size; - const char *encryption; - grub_int64_t sector_size; -}; -typedef struct grub_luks2_segment grub_luks2_segment_t; - -struct grub_luks2_digest -{ - grub_uint64_t idx; - /* Both keyslots and segments are interpreted as bitfields here */ - grub_uint64_t keyslots; - grub_uint64_t segments; - const char *salt; - const char *digest; - const char *hash; - grub_int64_t iterations; -}; -typedef struct grub_luks2_digest grub_luks2_digest_t; - -gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, - grub_uint8_t * dst, grub_size_t blocksize, - grub_size_t blocknumbers); - -static grub_err_t -luks2_parse_keyslot (grub_luks2_keyslot_t *out, const grub_json_t *keyslot) -{ - grub_json_t area, af, kdf; - const char *type; - - if (grub_json_getstring (&type, keyslot, "type")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing or invalid keyslot"); - else if (grub_strcmp (type, "luks2")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported keyslot type %s", type); - else if (grub_json_getint64 (&out->key_size, keyslot, "key_size")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing keyslot information"); - if (grub_json_getint64 (&out->priority, keyslot, "priority")) - out->priority = 1; - - if (grub_json_getvalue (&area, keyslot, "area") || - grub_json_getstring (&type, &area, "type")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing or invalid key area"); - else if (grub_strcmp (type, "raw")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported key area type: %s", type); - else if (grub_json_getuint64 (&out->area.offset, &area, "offset") || - grub_json_getuint64 (&out->area.size, &area, "size") || - grub_json_getstring (&out->area.encryption, &area, "encryption") || - grub_json_getint64 (&out->area.key_size, &area, "key_size")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing key area information"); - - if (grub_json_getvalue (&kdf, keyslot, "kdf") || - grub_json_getstring (&type, &kdf, "type") || - grub_json_getstring (&out->kdf.salt, &kdf, "salt")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing or invalid KDF"); - else if (!grub_strcmp (type, "argon2i") || !grub_strcmp (type, "argon2id")) - { - out->kdf.type = LUKS2_KDF_TYPE_ARGON2I; - if (grub_json_getint64 (&out->kdf.u.argon2i.time, &kdf, "time") || - grub_json_getint64 (&out->kdf.u.argon2i.memory, &kdf, "memory") || - grub_json_getint64 (&out->kdf.u.argon2i.cpus, &kdf, "cpus")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing Argon2i parameters"); - } - else if (!grub_strcmp (type, "pbkdf2")) - { - out->kdf.type = LUKS2_KDF_TYPE_PBKDF2; - if (grub_json_getstring (&out->kdf.u.pbkdf2.hash, &kdf, "hash") || - grub_json_getint64 (&out->kdf.u.pbkdf2.iterations, &kdf, "iterations")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing PBKDF2 parameters"); - } - else - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported KDF type %s", type); - - if (grub_json_getvalue (&af, keyslot, "af") || - grub_json_getstring (&type, &af, "type")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing or invalid area"); - if (grub_strcmp (type, "luks1")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported AF type %s", type); - if (grub_json_getint64 (&out->af.stripes, &af, "stripes") || - grub_json_getstring (&out->af.hash, &af, "hash")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing AF parameters"); - - return GRUB_ERR_NONE; -} - -static grub_err_t -luks2_parse_segment (grub_luks2_segment_t *out, const grub_json_t *segment) -{ - const char *type; - - if (grub_json_getstring (&type, segment, "type")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid segment type"); - else if (grub_strcmp (type, "crypt")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported segment type %s", type); - - if (grub_json_getuint64 (&out->offset, segment, "offset") || - grub_json_getstring (&out->size, segment, "size") || - grub_json_getstring (&out->encryption, segment, "encryption") || - grub_json_getint64 (&out->sector_size, segment, "sector_size")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing segment parameters"); - - return GRUB_ERR_NONE; -} - -static grub_err_t -luks2_parse_digest (grub_luks2_digest_t *out, const grub_json_t *digest) -{ - grub_json_t segments, keyslots, o; - grub_size_t i, size; - grub_uint64_t bit; - const char *type; - - if (grub_json_getstring (&type, digest, "type")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid digest type"); - else if (grub_strcmp (type, "pbkdf2")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported digest type %s", type); - - if (grub_json_getvalue (&segments, digest, "segments") || - grub_json_getvalue (&keyslots, digest, "keyslots") || - grub_json_getstring (&out->salt, digest, "salt") || - grub_json_getstring (&out->digest, digest, "digest") || - grub_json_getstring (&out->hash, digest, "hash") || - grub_json_getint64 (&out->iterations, digest, "iterations")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing digest parameters"); - - if (grub_json_getsize (&size, &segments)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "Digest references no segments"); - - out->segments = 0; - for (i = 0; i < size; i++) - { - if (grub_json_getchild (&o, &segments, i) || - grub_json_getuint64 (&bit, &o, NULL)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid segment"); - out->segments |= (1 << bit); - } - - if (grub_json_getsize (&size, &keyslots)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "Digest references no keyslots"); - - out->keyslots = 0; - for (i = 0; i < size; i++) - { - if (grub_json_getchild (&o, &keyslots, i) || - grub_json_getuint64 (&bit, &o, NULL)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid keyslot"); - out->keyslots |= (1 << bit); - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -luks2_get_keyslot (grub_luks2_keyslot_t *k, grub_luks2_digest_t *d, grub_luks2_segment_t *s, - const grub_json_t *root, grub_size_t keyslot_json_idx) -{ - grub_json_t keyslots, keyslot, digests, digest, segments, segment; - grub_size_t json_idx, size; - - /* Get nth keyslot */ - if (grub_json_getvalue (&keyslots, root, "keyslots") || - grub_json_getchild (&keyslot, &keyslots, keyslot_json_idx) || - grub_json_getuint64 (&k->idx, &keyslot, NULL) || - grub_json_getchild (&keyslot, &keyslot, 0) || - luks2_parse_keyslot (k, &keyslot)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not parse keyslot index %" PRIuGRUB_SIZE, keyslot_json_idx); - - /* Get digest that matches the keyslot. */ - if (grub_json_getvalue (&digests, root, "digests") || - grub_json_getsize (&size, &digests)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not get digests"); - for (json_idx = 0; json_idx < size; json_idx++) - { - if (grub_json_getchild (&digest, &digests, json_idx) || - grub_json_getuint64 (&d->idx, &digest, NULL) || - grub_json_getchild (&digest, &digest, 0) || - luks2_parse_digest (d, &digest)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not parse digest index %" PRIuGRUB_SIZE, json_idx); - - if ((d->keyslots & (1 << k->idx))) - break; - } - if (json_idx == size) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No digest for keyslot \"%" PRIuGRUB_UINT64_T "\"", k->idx); - - /* Get segment that matches the digest. */ - if (grub_json_getvalue (&segments, root, "segments") || - grub_json_getsize (&size, &segments)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not get segments"); - for (json_idx = 0; json_idx < size; json_idx++) - { - if (grub_json_getchild (&segment, &segments, json_idx) || - grub_json_getuint64 (&s->idx, &segment, NULL) || - grub_json_getchild (&segment, &segment, 0) || - luks2_parse_segment (s, &segment)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not parse segment index %" PRIuGRUB_SIZE, json_idx); - - if ((d->segments & (1 << s->idx))) - break; - } - if (json_idx == size) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No segment for digest \"%" PRIuGRUB_UINT64_T "\"", d->idx); - - return GRUB_ERR_NONE; -} - -/* Determine whether to use primary or secondary header */ -static grub_err_t -luks2_read_header (grub_disk_t disk, grub_luks2_header_t *outhdr) -{ - grub_luks2_header_t primary, secondary, *header = &primary; - grub_err_t ret; - - /* Read the primary LUKS header. */ - ret = grub_disk_read (disk, 0, 0, sizeof (primary), &primary); - if (ret) - return ret; - - /* Look for LUKS magic sequence. */ - if (grub_memcmp (primary.magic, LUKS_MAGIC_1ST, sizeof (primary.magic)) || - grub_be_to_cpu16 (primary.version) != 2) - return GRUB_ERR_BAD_SIGNATURE; - - /* Read the secondary header. */ - ret = grub_disk_read (disk, 0, grub_be_to_cpu64 (primary.hdr_size), sizeof (secondary), &secondary); - if (ret) - return ret; - - /* Look for LUKS magic sequence. */ - if (grub_memcmp (secondary.magic, LUKS_MAGIC_2ND, sizeof (secondary.magic)) || - grub_be_to_cpu16 (secondary.version) != 2) - return GRUB_ERR_BAD_SIGNATURE; - - if (grub_be_to_cpu64 (primary.seqid) < grub_be_to_cpu64 (secondary.seqid)) - header = &secondary; - grub_memcpy (outhdr, header, sizeof (*header)); - - return GRUB_ERR_NONE; -} - -static grub_cryptodisk_t -luks2_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) -{ - grub_cryptodisk_t cryptodisk; - grub_luks2_header_t header; - - if (cargs->check_boot) - return NULL; - - if (luks2_read_header (disk, &header)) - { - grub_errno = GRUB_ERR_NONE; - return NULL; - } - - if (cargs->search_uuid != NULL && grub_uuidcasecmp (cargs->search_uuid, header.uuid, sizeof (header.uuid)) != 0) - { - grub_dprintf ("luks2", "%s != %s\n", header.uuid, cargs->search_uuid); - return NULL; - } - - cryptodisk = grub_zalloc (sizeof (*cryptodisk)); - if (!cryptodisk) - return NULL; - - COMPILE_TIME_ASSERT (sizeof (cryptodisk->uuid) >= sizeof (header.uuid)); - grub_memcpy (cryptodisk->uuid, header.uuid, sizeof (header.uuid)); - - cryptodisk->modname = "luks2"; - return cryptodisk; -} - -static grub_err_t -luks2_base64_decode (const char *in, grub_size_t inlen, grub_uint8_t *decoded, idx_t *decodedlen) -{ - grub_size_t unescaped_len = 0; - char *unescaped = NULL; - bool successful; - - if (grub_json_unescape (&unescaped, &unescaped_len, in, inlen) != GRUB_ERR_NONE) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("could not unescape Base64 string")); - - successful = base64_decode (unescaped, unescaped_len, (char *) decoded, decodedlen); - grub_free (unescaped); - if (!successful) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("could not decode Base64 string")); - - return GRUB_ERR_NONE; -} - -static grub_err_t -luks2_verify_key (grub_luks2_digest_t *d, grub_uint8_t *candidate_key, - grub_size_t candidate_key_len) -{ - grub_uint8_t candidate_digest[GRUB_CRYPTODISK_MAX_KEYLEN]; - grub_uint8_t digest[GRUB_CRYPTODISK_MAX_KEYLEN], salt[GRUB_CRYPTODISK_MAX_KEYLEN]; - idx_t saltlen = sizeof (salt), digestlen = sizeof (digest); - const gcry_md_spec_t *hash; - gcry_err_code_t gcry_ret; - - /* Decode both digest and salt */ - if (luks2_base64_decode (d->digest, grub_strlen (d->digest), - digest, &digestlen) != GRUB_ERR_NONE) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid digest"); - if (luks2_base64_decode (d->salt, grub_strlen (d->salt), - salt, &saltlen) != GRUB_ERR_NONE) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid digest salt"); - - /* Configure the hash used for the digest. */ - hash = grub_crypto_lookup_md_by_name (d->hash); - if (!hash) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", d->hash); - - /* Calculate the candidate key's digest */ - gcry_ret = grub_crypto_pbkdf2 (hash, - candidate_key, candidate_key_len, - salt, saltlen, - d->iterations, - candidate_digest, digestlen); - if (gcry_ret) - return grub_crypto_gcry_error (gcry_ret); - - if (grub_memcmp (candidate_digest, digest, digestlen) != 0) - return grub_error (GRUB_ERR_ACCESS_DENIED, "Mismatching digests"); - - return GRUB_ERR_NONE; -} - -static grub_err_t -luks2_decrypt_key (grub_uint8_t *out_key, - grub_disk_t source, grub_cryptodisk_t crypt, - grub_luks2_keyslot_t *k, - const grub_uint8_t *passphrase, grub_size_t passphraselen) -{ - grub_uint8_t area_key[GRUB_CRYPTODISK_MAX_KEYLEN]; - grub_uint8_t salt[GRUB_CRYPTODISK_MAX_KEYLEN]; - grub_uint8_t *split_key = NULL; - idx_t saltlen = sizeof (salt); - char cipher[32], *p; - const gcry_md_spec_t *hash; - gcry_err_code_t gcry_ret; - grub_err_t ret; - - if (luks2_base64_decode (k->kdf.salt, grub_strlen (k->kdf.salt), - salt, &saltlen) != GRUB_ERR_NONE) - { - ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid keyslot salt"); - goto err; - } - - /* Calculate the binary area key of the user supplied passphrase. */ - switch (k->kdf.type) - { - case LUKS2_KDF_TYPE_ARGON2I: - ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Argon2 not supported"); - goto err; - case LUKS2_KDF_TYPE_PBKDF2: - hash = grub_crypto_lookup_md_by_name (k->kdf.u.pbkdf2.hash); - if (!hash) - { - ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", - k->kdf.u.pbkdf2.hash); - goto err; - } - - gcry_ret = grub_crypto_pbkdf2 (hash, (grub_uint8_t *) passphrase, - passphraselen, - salt, saltlen, - k->kdf.u.pbkdf2.iterations, - area_key, k->area.key_size); - if (gcry_ret) - { - ret = grub_crypto_gcry_error (gcry_ret); - goto err; - } - - break; - } - - /* Set up disk encryption parameters for the key area */ - grub_strncpy (cipher, k->area.encryption, sizeof (cipher)); - p = grub_memchr (cipher, '-', grub_strlen (cipher)); - if (!p) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid encryption"); - *p = '\0'; - - ret = grub_cryptodisk_setcipher (crypt, cipher, p + 1); - if (ret) - return ret; - - gcry_ret = grub_cryptodisk_setkey (crypt, area_key, k->area.key_size); - if (gcry_ret) - { - ret = grub_crypto_gcry_error (gcry_ret); - goto err; - } - - /* Read and decrypt the binary key area with the area key. */ - split_key = grub_malloc (k->area.size); - if (!split_key) - { - ret = grub_errno; - goto err; - } - - grub_errno = GRUB_ERR_NONE; - ret = grub_disk_read (source, 0, k->area.offset, k->area.size, split_key); - if (ret) - { - grub_error (GRUB_ERR_IO, "Read error: %s\n", grub_errmsg); - goto err; - } - - /* - * The key slots area is always encrypted in 512-byte sectors, - * regardless of encrypted data sector size. - */ - gcry_ret = grub_cryptodisk_decrypt (crypt, split_key, k->area.size, 0, - GRUB_LUKS1_LOG_SECTOR_SIZE); - if (gcry_ret) - { - ret = grub_crypto_gcry_error (gcry_ret); - goto err; - } - - /* Configure the hash used for anti-forensic merging. */ - hash = grub_crypto_lookup_md_by_name (k->af.hash); - if (!hash) - { - ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", - k->af.hash); - goto err; - } - - /* Merge the decrypted key material to get the candidate master key. */ - gcry_ret = AF_merge (hash, split_key, out_key, k->key_size, k->af.stripes); - if (gcry_ret) - { - ret = grub_crypto_gcry_error (gcry_ret); - goto err; - } - - grub_dprintf ("luks2", "Candidate key recovered\n"); - - err: - grub_free (split_key); - return ret; -} - -static grub_err_t -luks2_recover_key (grub_disk_t source, - grub_cryptodisk_t crypt, - grub_cryptomount_args_t cargs) -{ - grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN]; - char cipher[32], *json_header = NULL, *ptr; - grub_size_t candidate_key_len = 0, json_idx, size; - grub_luks2_header_t header; - grub_luks2_keyslot_t keyslot; - grub_luks2_digest_t digest; - grub_luks2_segment_t segment; - gcry_err_code_t gcry_ret; - grub_json_t *json = NULL, keyslots; - grub_err_t ret; - grub_size_t sz; - - if (cargs->key_data == NULL || cargs->key_len == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data"); - - ret = luks2_read_header (source, &header); - if (ret) - return ret; - - grub_puts_ (N_("Attempting to decrypt master key...")); - - if (grub_sub (grub_be_to_cpu64 (header.hdr_size), sizeof (header), &sz)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "underflow detected while calculating json header size"); - - json_header = grub_zalloc (sz); - if (!json_header) - return GRUB_ERR_OUT_OF_MEMORY; - - /* Read the JSON area. */ - ret = grub_disk_read (source, 0, grub_be_to_cpu64 (header.hdr_offset) + sizeof (header), - grub_be_to_cpu64 (header.hdr_size) - sizeof (header), json_header); - if (ret) - goto err; - - ptr = grub_memchr (json_header, 0, grub_be_to_cpu64 (header.hdr_size) - sizeof (header)); - if (!ptr) - goto err; - - ret = grub_json_parse (&json, json_header, grub_be_to_cpu64 (header.hdr_size)); - if (ret) - { - ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid LUKS2 JSON header"); - goto err; - } - - if (grub_json_getvalue (&keyslots, json, "keyslots") || - grub_json_getsize (&size, &keyslots)) - { - ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not get keyslots"); - goto err; - } - - if (grub_disk_native_sectors (source) == GRUB_DISK_SIZE_UNKNOWN) - { - /* FIXME: Allow use of source disk, and maybe cause errors in read. */ - grub_dprintf ("luks2", "Source disk %s has an unknown size, " - "conservatively returning error\n", source->name); - ret = grub_error (GRUB_ERR_BUG, "Unknown size of luks2 source device"); - goto err; - } - - /* Try all keyslot */ - for (json_idx = 0; json_idx < size; json_idx++) - { - char indexstr[21]; /* log10(2^64) ~ 20, plus NUL character. */ - typeof (source->total_sectors) max_crypt_sectors = 0; - - grub_errno = GRUB_ERR_NONE; - ret = luks2_get_keyslot (&keyslot, &digest, &segment, json, json_idx); - if (ret) - { - /* - * luks2_get_keyslot() can fail for a variety of reasons that do not - * necessarily mean the next keyslot should not be tried (e.g. a new - * kdf type). So always try the next slot. - */ - grub_dprintf ("luks2", "Failed to get keyslot %" PRIuGRUB_UINT64_T "\n", keyslot.idx); - continue; - } - if (grub_errno != GRUB_ERR_NONE) - grub_dprintf ("luks2", "Ignoring unhandled error %d from luks2_get_keyslot\n", grub_errno); - - if (keyslot.priority == 0) - { - grub_dprintf ("luks2", "Ignoring keyslot \"%" PRIuGRUB_UINT64_T "\" due to priority\n", keyslot.idx); - continue; - } - - grub_dprintf ("luks2", "Trying keyslot \"%" PRIuGRUB_UINT64_T "\"\n", keyslot.idx); - - /* Sector size should be one of 512, 1024, 2048, or 4096. */ - if (!(segment.sector_size == 512 || segment.sector_size == 1024 || - segment.sector_size == 2048 || segment.sector_size == 4096)) - { - grub_dprintf ("luks2", "Segment \"%" PRIuGRUB_UINT64_T "\" sector" - " size %" PRIuGRUB_UINT64_T " is not one of" - " 512, 1024, 2048, or 4096\n", - segment.idx, segment.sector_size); - continue; - } - - /* Set up disk according to keyslot's segment. */ - crypt->offset_sectors = grub_divmod64 (segment.offset, segment.sector_size, NULL); - crypt->log_sector_size = grub_log2ull (segment.sector_size); - /* Set to the source disk/partition size, which is the maximum we allow. */ - max_crypt_sectors = grub_disk_native_sectors (source); - max_crypt_sectors = grub_convert_sector (max_crypt_sectors, GRUB_DISK_SECTOR_BITS, - crypt->log_sector_size); - - if (max_crypt_sectors < crypt->offset_sectors) - { - grub_dprintf ("luks2", "Segment \"%" PRIuGRUB_UINT64_T "\" has offset" - " %" PRIuGRUB_UINT64_T " which is greater than" - " source disk size %" PRIuGRUB_UINT64_T "," - " skipping\n", segment.idx, crypt->offset_sectors, - max_crypt_sectors); - continue; - } - - if (grub_strcmp (segment.size, "dynamic") == 0) - crypt->total_sectors = max_crypt_sectors - crypt->offset_sectors; - else - { - grub_errno = GRUB_ERR_NONE; - - /* Convert segment.size to sectors, rounding up to nearest sector */ - crypt->total_sectors = grub_strtoull (segment.size, NULL, 10); - - if (grub_errno == GRUB_ERR_NONE) - { - crypt->total_sectors = ALIGN_UP (crypt->total_sectors, - 1 << crypt->log_sector_size); - crypt->total_sectors >>= crypt->log_sector_size; - } - else if (grub_errno == GRUB_ERR_BAD_NUMBER) - { - grub_dprintf ("luks2", "Segment \"%" PRIuGRUB_UINT64_T "\" size" - " \"%s\" is not a parsable number," - " skipping keyslot\n", - segment.idx, segment.size); - continue; - } - else if (grub_errno == GRUB_ERR_OUT_OF_RANGE) - { - /* - * There was an overflow in parsing segment.size, so disk must - * be very large or the string is incorrect. - * - * TODO: Allow reading of at least up max_crypt_sectors. Really, - * its very unlikely one would be booting from such a large drive - * anyway. Use another smaller LUKS2 boot device. - */ - grub_dprintf ("luks2", "Segment \"%" PRIuGRUB_UINT64_T "\" size" - " %s overflowed 64-bit unsigned integer," - " skipping keyslot\n", segment.idx, segment.size); - continue; - } - } - - if (crypt->total_sectors == 0) - { - grub_dprintf ("luks2", "Segment \"%" PRIuGRUB_UINT64_T "\" has zero" - " sectors, skipping\n", segment.idx); - continue; - } - else if (max_crypt_sectors < (crypt->offset_sectors + crypt->total_sectors)) - { - grub_dprintf ("luks2", "Segment \"%" PRIuGRUB_UINT64_T "\" has last" - " data position greater than source disk size," - " the end of the crypto device will be" - " inaccessible\n", segment.idx); - - /* Allow decryption up to the end of the source disk. */ - crypt->total_sectors = max_crypt_sectors - crypt->offset_sectors; - } - - ret = luks2_decrypt_key (candidate_key, source, crypt, &keyslot, - cargs->key_data, cargs->key_len); - if (ret) - { - grub_dprintf ("luks2", "Decryption with keyslot \"%" PRIuGRUB_UINT64_T "\" failed: %s\n", - keyslot.idx, grub_errmsg); - continue; - } - - ret = luks2_verify_key (&digest, candidate_key, keyslot.key_size); - if (ret) - { - grub_dprintf ("luks2", "Could not open keyslot \"%" PRIuGRUB_UINT64_T "\": %s\n", - keyslot.idx, grub_errmsg); - continue; - } - - grub_snprintf (indexstr, sizeof (indexstr) - 1, "%" PRIuGRUB_UINT64_T, keyslot.idx); - /* - * TRANSLATORS: It's a cryptographic key slot: one element of an array - * where each element is either empty or holds a key. - */ - grub_printf_ (N_("Slot \"%s\" opened\n"), indexstr); - - candidate_key_len = keyslot.key_size; - break; - } - if (candidate_key_len == 0) - { - ret = grub_error (GRUB_ERR_ACCESS_DENIED, "Invalid passphrase"); - goto err; - } - - /* Set up disk cipher. */ - grub_strncpy (cipher, segment.encryption, sizeof (cipher)); - ptr = grub_memchr (cipher, '-', grub_strlen (cipher)); - if (!ptr) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid encryption"); - *ptr = '\0'; - - ret = grub_cryptodisk_setcipher (crypt, cipher, ptr + 1); - if (ret) - goto err; - - /* Set the master key. */ - gcry_ret = grub_cryptodisk_setkey (crypt, candidate_key, candidate_key_len); - if (gcry_ret) - { - ret = grub_crypto_gcry_error (gcry_ret); - goto err; - } - - err: - grub_free (json_header); - grub_json_free (json); - return ret; -} - -static struct grub_cryptodisk_dev luks2_crypto = { - .scan = luks2_scan, - .recover_key = luks2_recover_key -}; - -GRUB_MOD_INIT (luks2) -{ - grub_cryptodisk_dev_register (&luks2_crypto); -} - -GRUB_MOD_FINI (luks2) -{ - grub_cryptodisk_dev_unregister (&luks2_crypto); -} diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c deleted file mode 100644 index af6a8e93c..000000000 --- a/grub-core/disk/lvm.c +++ /dev/null @@ -1,1098 +0,0 @@ -/* lvm.c - module to read Logical Volumes. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2008,2009,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef GRUB_UTIL -#include -#include -#endif - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct ignored_feature_lv -{ - struct grub_diskfilter_lv *lv; - char *origin; - struct ignored_feature_lv *next; -}; - - -/* 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 grub_uint64_t -grub_lvm_getvalue (const char ** const p, const char *str) -{ - *p = grub_strstr (*p, str); - if (! *p) - return 0; - *p += grub_strlen (str); - return grub_strtoull (*p, p, 10); -} - -#if 0 -static int -grub_lvm_checkvalue (char **p, char *str, char *tmpl) -{ - int tmpllen = grub_strlen (tmpl); - *p = grub_strstr (*p, str); - if (! *p) - return 0; - *p += grub_strlen (str); - if (**p != '"') - return 0; - return (grub_memcmp (*p + 1, tmpl, tmpllen) == 0 && (*p)[tmpllen + 1] == '"'); -} -#endif - -static int -grub_lvm_check_flag (const char *p, const char *str, const char *flag) -{ - grub_size_t len_str = grub_strlen (str), len_flag = grub_strlen (flag); - while (1) - { - const char *q; - p = grub_strstr (p, str); - if (! p) - return 0; - p += len_str; - if (grub_memcmp (p, " = [", sizeof (" = [") - 1) != 0) - continue; - q = p + sizeof (" = [") - 1; - while (1) - { - while (grub_isspace (*q)) - q++; - if (*q != '"') - return 0; - q++; - if (grub_memcmp (q, flag, len_flag) == 0 && q[len_flag] == '"') - return 1; - while (*q != '"') - q++; - q++; - if (*q == ']') - return 0; - q++; - } - } -} - -static void -grub_lvm_free_ignored_feature_lvs (struct ignored_feature_lv *ignored_feature_lvs) -{ - struct ignored_feature_lv *ignored_feature; - - while ((ignored_feature = ignored_feature_lvs)) - { - ignored_feature_lvs = ignored_feature_lvs->next; - - if (ignored_feature->lv) - { - unsigned int i; - - for (i = 0; i < ignored_feature->lv->segment_count; ++i) - if (ignored_feature->lv->segments) - grub_free (ignored_feature->lv->segments[i].nodes); - grub_free (ignored_feature->lv->segments); - grub_free (ignored_feature->lv->fullname); - grub_free (ignored_feature->lv->idname); - grub_free (ignored_feature->lv->name); - } - grub_free (ignored_feature->lv); - grub_free (ignored_feature->origin); - grub_free (ignored_feature); - } -} - -static struct grub_diskfilter_vg * -grub_lvm_detect (grub_disk_t disk, - struct grub_diskfilter_pv_id *id, - grub_disk_addr_t *start_sector) -{ - grub_err_t err; - grub_uint64_t mda_offset, mda_size; - grub_size_t ptr; - char buf[GRUB_LVM_LABEL_SIZE]; - char vg_id[GRUB_LVM_ID_STRLEN+1]; - char pv_id[GRUB_LVM_ID_STRLEN+1]; - char *metadatabuf, *mda_end, *vgname; - const char *p, *q; - 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; - grub_size_t vgname_len; - struct grub_diskfilter_vg *vg; - struct grub_diskfilter_pv *pv; - - /* 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) - { -#ifdef GRUB_UTIL - grub_util_info ("no LVM signature found"); -#endif - goto fail; - } - - /* - * We read a grub_lvm_pv_header and then 2 grub_lvm_disk_locns that - * immediately follow the PV header. Make sure we have space for both. - */ - if (grub_le_to_cpu32 (lh->offset_xl) >= - GRUB_LVM_LABEL_SIZE - sizeof (struct grub_lvm_pv_header) - - 2 * sizeof (struct grub_lvm_disk_locn)) - { -#ifdef GRUB_UTIL - grub_util_info ("LVM PV header/disk locations are beyond the end of the block"); -#endif - 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; - - 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"); - -#ifdef GRUB_UTIL - grub_util_info ("we don't support multiple LVM data areas"); -#endif - 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_calloc (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"); -#ifdef GRUB_UTIL - grub_util_info ("unknown LVM metadata header"); -#endif - goto fail2; - } - - rlocn = mdah->raw_locns; - if (grub_le_to_cpu64 (rlocn->offset) >= grub_le_to_cpu64 (mda_size)) - { -#ifdef GRUB_UTIL - grub_util_info ("metadata offset is beyond end of metadata area"); -#endif - goto fail2; - } - - if (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) > - grub_le_to_cpu64 (mdah->size)) - { - if (2 * mda_size < GRUB_LVM_MDA_HEADER_SIZE || - (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) - - grub_le_to_cpu64 (mdah->size) > mda_size - GRUB_LVM_MDA_HEADER_SIZE)) - { -#ifdef GRUB_UTIL - grub_util_info ("cannot copy metadata wrap in circular buffer"); -#endif - goto fail2; - } - - /* 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)); - } - - if (grub_add ((grub_size_t)metadatabuf, - (grub_size_t)grub_le_to_cpu64 (rlocn->offset), - &ptr)) - { - error_parsing_metadata: -#ifdef GRUB_UTIL - grub_util_info ("error parsing metadata"); -#endif - goto fail2; - } - - p = q = (char *)ptr; - - if (grub_add (ptr, (grub_size_t) grub_le_to_cpu64 (rlocn->size), &ptr)) - goto error_parsing_metadata; - - mda_end = (char *)ptr; - - while (*q != ' ' && q < mda_end) - q++; - - if (q == mda_end) - goto error_parsing_metadata; - - 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) - { -#ifdef GRUB_UTIL - grub_util_info ("couldn't find ID"); -#endif - goto fail3; - } - p += sizeof ("id = \"") - 1; - grub_memcpy (vg_id, p, GRUB_LVM_ID_STRLEN); - vg_id[GRUB_LVM_ID_STRLEN] = '\0'; - - vg = grub_diskfilter_get_vg_by_uuid (GRUB_LVM_ID_STRLEN, vg_id); - - if (! vg) - { - struct ignored_feature_lv *ignored_feature_lvs = NULL; - - /* 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; - vg->uuid = grub_malloc (GRUB_LVM_ID_STRLEN); - if (! vg->uuid) - goto fail3; - grub_memcpy (vg->uuid, vg_id, GRUB_LVM_ID_STRLEN); - vg->uuid_len = GRUB_LVM_ID_STRLEN; - - vg->extent_size = grub_lvm_getvalue (&p, "extent_size = "); - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("unknown extent size"); -#endif - 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) - { - grub_ssize_t s; - while (grub_isspace (*p) && p < mda_end) - p++; - - if (p == mda_end) - goto fail4; - - if (*p == '}') - break; - - pv = grub_zalloc (sizeof (*pv)); - if (pv == NULL) - goto fail4; - q = p; - while (*q != ' ' && q < mda_end) - q++; - - if (q == mda_end) - goto pvs_fail_noname; - - s = q - p; - pv->name = grub_malloc (s + 1); - if (pv->name == NULL) - goto pvs_fail_noname; - 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; - - pv->id.uuid = grub_malloc (GRUB_LVM_ID_STRLEN); - if (!pv->id.uuid) - goto pvs_fail; - grub_memcpy (pv->id.uuid, p, GRUB_LVM_ID_STRLEN); - pv->id.uuidlen = GRUB_LVM_ID_STRLEN; - - pv->start_sector = grub_lvm_getvalue (&p, "pe_start = "); - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("unknown pe_start"); -#endif - goto pvs_fail; - } - - p = grub_strchr (p, '}'); - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("error parsing pe_start"); -#endif - goto pvs_fail; - } - p++; - - pv->disk = NULL; - pv->next = vg->pvs; - vg->pvs = pv; - - continue; - pvs_fail: - grub_free (pv->name); - pvs_fail_noname: - grub_free (pv); - goto fail4; - } - } - else - goto fail4; - - p = grub_strstr (p, "logical_volumes {"); - if (p) - { - p += sizeof ("logical_volumes {") - 1; - - /* And add all the lvs to the volume group. */ - while (1) - { - grub_ssize_t s; - int skip_lv = 0; - struct grub_diskfilter_lv *lv; - struct grub_diskfilter_segment *seg; - int is_pvmove; - - while (grub_isspace (*p) && p < mda_end) - p++; - - if (p == mda_end) - goto fail4; - - if (*p == '}') - break; - - lv = grub_zalloc (sizeof (*lv)); - if (lv == NULL) - goto fail4; - - q = p; - while (*q != ' ' && q < mda_end) - q++; - - if (q == mda_end) - goto lvs_fail; - - s = q - p; - lv->name = grub_strndup (p, s); - if (!lv->name) - goto lvs_fail; - - { - const char *iptr; - char *optr; - - /* - * This is kind of hard to read with our safe (but rather - * baroque) math primatives, but it boils down to: - * - * sz0 = vgname_len * 2 + 1 + - * s * 2 + 1 + - * sizeof ("lvm/") - 1; - */ - grub_size_t sz0 = vgname_len, sz1 = s; - - if (grub_mul (sz0, 2, &sz0) || - grub_add (sz0, 1, &sz0) || - grub_mul (sz1, 2, &sz1) || - grub_add (sz1, 1, &sz1) || - grub_add (sz0, sz1, &sz0) || - grub_add (sz0, sizeof ("lvm/") - 1, &sz0)) - goto lvs_fail; - - lv->fullname = grub_malloc (sz0); - if (!lv->fullname) - goto lvs_fail; - - grub_memcpy (lv->fullname, "lvm/", sizeof ("lvm/") - 1); - optr = lv->fullname + sizeof ("lvm/") - 1; - for (iptr = vgname; iptr < vgname + vgname_len; iptr++) - { - *optr++ = *iptr; - if (*iptr == '-') - *optr++ = '-'; - } - *optr++ = '-'; - for (iptr = p; iptr < p + s; iptr++) - { - *optr++ = *iptr; - if (*iptr == '-') - *optr++ = '-'; - } - *optr++ = 0; - lv->idname = grub_malloc (sizeof ("lvmid/") - + 2 * GRUB_LVM_ID_STRLEN + 1); - if (!lv->idname) - goto lvs_fail; - grub_memcpy (lv->idname, "lvmid/", - sizeof ("lvmid/") - 1); - grub_memcpy (lv->idname + sizeof ("lvmid/") - 1, - vg_id, GRUB_LVM_ID_STRLEN); - lv->idname[sizeof ("lvmid/") - 1 + GRUB_LVM_ID_STRLEN] = '/'; - - p = grub_strstr (q, "id = \""); - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("couldn't find ID"); -#endif - goto lvs_fail; - } - p += sizeof ("id = \"") - 1; - grub_memcpy (lv->idname + sizeof ("lvmid/") - 1 - + GRUB_LVM_ID_STRLEN + 1, - p, GRUB_LVM_ID_STRLEN); - lv->idname[sizeof ("lvmid/") - 1 + 2 * GRUB_LVM_ID_STRLEN + 1] = '\0'; - } - - lv->size = 0; - - lv->visible = grub_lvm_check_flag (p, "status", "VISIBLE"); - is_pvmove = grub_lvm_check_flag (p, "status", "PVMOVE"); - - lv->segment_count = grub_lvm_getvalue (&p, "segment_count = "); - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("unknown segment_count"); -#endif - goto lvs_fail; - } - lv->segments = grub_calloc (lv->segment_count, sizeof (*seg)); - if (lv->segments == NULL) - goto lvs_fail; - seg = lv->segments; - - for (i = 0; i < lv->segment_count; i++) - { - - p = grub_strstr (p, "segment"); - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("unknown segment"); -#endif - goto lvs_segment_fail; - } - - seg->start_extent = grub_lvm_getvalue (&p, "start_extent = "); - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("unknown start_extent"); -#endif - goto lvs_segment_fail; - } - seg->extent_count = grub_lvm_getvalue (&p, "extent_count = "); - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("unknown extent_count"); -#endif - goto lvs_segment_fail; - } - - p = grub_strstr (p, "type = \""); - if (p == NULL) - goto lvs_segment_fail; - p += sizeof("type = \"") - 1; - - lv->size += seg->extent_count * vg->extent_size; - - if (grub_memcmp (p, "striped\"", - sizeof ("striped\"") - 1) == 0) - { - struct grub_diskfilter_node *stripe; - - seg->type = GRUB_DISKFILTER_STRIPED; - seg->node_count = grub_lvm_getvalue (&p, "stripe_count = "); - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("unknown stripe_count"); -#endif - goto lvs_segment_fail; - } - - if (seg->node_count != 1) - { - seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("unknown stripe_size"); -#endif - goto lvs_segment_fail; - } - } - - seg->nodes = grub_calloc (seg->node_count, - sizeof (*stripe)); - if (seg->nodes == NULL) - goto lvs_segment_fail; - stripe = seg->nodes; - - p = grub_strstr (p, "stripes = ["); - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("unknown stripes"); -#endif - goto lvs_segment_fail2; - } - p += sizeof("stripes = [") - 1; - - for (j = 0; j < seg->node_count; j++) - { - p = grub_strchr (p, '"'); - if (p == NULL) - goto lvs_segment_fail2; - q = ++p; - while (q < mda_end && *q != '"') - q++; - - if (q == mda_end) - goto lvs_segment_fail2; - - s = q - p; - - stripe->name = grub_malloc (s + 1); - if (stripe->name == NULL) - goto lvs_segment_fail2; - - grub_memcpy (stripe->name, p, s); - stripe->name[s] = '\0'; - - p = q + 1; - - stripe->start = grub_lvm_getvalue (&p, ",") - * vg->extent_size; - if (p == NULL) - { - grub_free (stripe->name); - goto lvs_segment_fail2; - } - - stripe++; - } - } - else if (grub_memcmp (p, "mirror\"", sizeof ("mirror\"") - 1) - == 0) - { - seg->type = GRUB_DISKFILTER_MIRROR; - seg->node_count = grub_lvm_getvalue (&p, "mirror_count = "); - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("unknown mirror_count"); -#endif - goto lvs_segment_fail; - } - - seg->nodes = grub_calloc (seg->node_count, sizeof (seg->nodes[0])); - if (seg->nodes == NULL) - goto lvs_segment_fail; - - p = grub_strstr (p, "mirrors = ["); - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("unknown mirrors"); -#endif - goto lvs_segment_fail2; - } - p += sizeof("mirrors = [") - 1; - - for (j = 0; j < seg->node_count; j++) - { - char *lvname; - - p = grub_strchr (p, '"'); - if (p == NULL) - goto lvs_segment_fail2; - q = ++p; - while (q < mda_end && *q != '"') - q++; - - if (q == mda_end) - goto lvs_segment_fail2; - - s = q - p; - - lvname = grub_malloc (s + 1); - if (lvname == NULL) - goto lvs_segment_fail2; - - grub_memcpy (lvname, p, s); - lvname[s] = '\0'; - seg->nodes[j].name = lvname; - p = q + 1; - } - /* Only first (original) is ok with in progress pvmove. */ - if (is_pvmove) - seg->node_count = 1; - } - else if (grub_memcmp (p, "raid", sizeof ("raid") - 1) == 0 - && ((p[sizeof ("raid") - 1] >= '4' - && p[sizeof ("raid") - 1] <= '6') - || p[sizeof ("raid") - 1] == '1') - && p[sizeof ("raidX") - 1] == '"') - { - switch (p[sizeof ("raid") - 1]) - { - case '1': - seg->type = GRUB_DISKFILTER_MIRROR; - break; - case '4': - seg->type = GRUB_DISKFILTER_RAID4; - seg->layout = GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC; - break; - case '5': - seg->type = GRUB_DISKFILTER_RAID5; - seg->layout = GRUB_RAID_LAYOUT_LEFT_SYMMETRIC; - break; - case '6': - seg->type = GRUB_DISKFILTER_RAID6; - seg->layout = (GRUB_RAID_LAYOUT_RIGHT_ASYMMETRIC - | GRUB_RAID_LAYOUT_MUL_FROM_POS); - break; - } - seg->node_count = grub_lvm_getvalue (&p, "device_count = "); - - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("unknown device_count"); -#endif - goto lvs_segment_fail; - } - - if (seg->type != GRUB_DISKFILTER_MIRROR) - { - seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("unknown stripe_size"); -#endif - goto lvs_segment_fail; - } - } - - seg->nodes = grub_calloc (seg->node_count, sizeof (seg->nodes[0])); - if (seg->nodes == NULL) - goto lvs_segment_fail; - - p = grub_strstr (p, "raids = ["); - if (p == NULL) - { -#ifdef GRUB_UTIL - grub_util_info ("unknown raids"); -#endif - goto lvs_segment_fail2; - } - p += sizeof("raids = [") - 1; - - for (j = 0; j < seg->node_count; j++) - { - char *lvname; - - p = grub_strchr (p, '"'); - p = p ? grub_strchr (p + 1, '"') : 0; - p = p ? grub_strchr (p + 1, '"') : 0; - if (p == NULL) - goto lvs_segment_fail2; - q = ++p; - while (*q != '"') - q++; - - s = q - p; - - lvname = grub_malloc (s + 1); - if (lvname == NULL) - goto lvs_segment_fail2; - - grub_memcpy (lvname, p, s); - lvname[s] = '\0'; - seg->nodes[j].name = lvname; - p = q + 1; - } - if (seg->type == GRUB_DISKFILTER_RAID4) - { - char *tmp; - tmp = seg->nodes[0].name; - grub_memmove (seg->nodes, seg->nodes + 1, - sizeof (seg->nodes[0]) - * (seg->node_count - 1)); - seg->nodes[seg->node_count - 1].name = tmp; - } - } - /* - * Cache and integrity LVs have extra parts that - * we can ignore for our read-only access. - */ - else if (grub_strncmp (p, "cache\"", sizeof ("cache\"") - 1) == 0 || - grub_strncmp (p, "cache+CACHE_USES_CACHEVOL\"", sizeof ("cache+CACHE_USES_CACHEVOL\"") - 1) == 0 || - grub_strncmp (p, "integrity\"", sizeof ("integrity\"") - 1) == 0) - { - struct ignored_feature_lv *ignored_feature = NULL; - - char *p2, *p3; - grub_size_t sz; -#ifdef GRUB_UTIL - p2 = grub_strchr (p, '"'); - if (p2) - *p2 = '\0'; - grub_util_info ("Ignoring extra metadata type '%s' for %s", p, lv->name); - if (p2) - *p2 ='"'; -#endif - - ignored_feature = grub_zalloc (sizeof (*ignored_feature)); - if (!ignored_feature) - goto ignored_feature_lv_fail; - ignored_feature->lv = grub_zalloc (sizeof (*ignored_feature->lv)); - if (!ignored_feature->lv) - goto ignored_feature_lv_fail; - grub_memcpy (ignored_feature->lv, lv, sizeof (*ignored_feature->lv)); - - if (lv->fullname) - { - ignored_feature->lv->fullname = grub_strdup (lv->fullname); - if (!ignored_feature->lv->fullname) - goto ignored_feature_lv_fail; - } - if (lv->idname) - { - ignored_feature->lv->idname = grub_strdup (lv->idname); - if (!ignored_feature->lv->idname) - goto ignored_feature_lv_fail; - } - if (lv->name) - { - ignored_feature->lv->name = grub_strdup (lv->name); - if (!ignored_feature->lv->name) - goto ignored_feature_lv_fail; - } - - skip_lv = 1; - - - p2 = grub_strstr (p, "origin = \""); - if (!p2) - goto ignored_feature_lv_fail; - - p2 = grub_strchr (p2, '"'); - if (!p2) - goto ignored_feature_lv_fail; - - p3 = ++p2; - if (p3 == mda_end) - goto ignored_feature_lv_fail; - p3 = grub_strchr (p3, '"'); - if (!p3) - goto ignored_feature_lv_fail; - - sz = p3 - p2; - - ignored_feature->origin = grub_malloc (sz + 1); - if (!ignored_feature->origin) - goto ignored_feature_lv_fail; - grub_memcpy (ignored_feature->origin, p2, sz); - ignored_feature->origin[sz] = '\0'; - - ignored_feature->next = ignored_feature_lvs; - ignored_feature_lvs = ignored_feature; - break; - - ignored_feature_lv_fail: - if (ignored_feature) - { - grub_free (ignored_feature->origin); - if (ignored_feature->lv) - { - grub_free (ignored_feature->lv->fullname); - grub_free (ignored_feature->lv->idname); - grub_free (ignored_feature->lv->name); - } - grub_free (ignored_feature->lv); - grub_free (ignored_feature); - } - grub_lvm_free_ignored_feature_lvs (ignored_feature_lvs); - goto fail4; - } - else - { -#ifdef GRUB_UTIL - char *p2; - p2 = grub_strchr (p, '"'); - if (p2) - *p2 = '\0'; - grub_util_info ("unknown LVM type %s", p); - if (p2) - *p2 ='"'; -#endif - /* Found a non-supported type, give up and move on. */ - skip_lv = 1; - break; - } - - seg++; - - continue; - lvs_segment_fail2: - grub_free (seg->nodes); - lvs_segment_fail: - goto fail4; - } - - if (p != NULL) - p = grub_strchr (p, '}'); - if (p == NULL) - goto lvs_fail; - p += 3; - - if (skip_lv) - { - grub_free (lv->name); - grub_free (lv); - continue; - } - - lv->vg = vg; - lv->next = vg->lvs; - vg->lvs = lv; - - continue; - lvs_fail: - grub_free (lv->name); - grub_free (lv); - goto fail4; - } - } - - - { - struct ignored_feature_lv *ignored_feature; - - for (ignored_feature = ignored_feature_lvs; ignored_feature; ignored_feature = ignored_feature->next) - { - struct grub_diskfilter_lv *lv; - - for (lv = vg->lvs; lv; lv = lv->next) - if (grub_strcmp (lv->name, ignored_feature->origin) == 0) - break; - if (lv) - { - ignored_feature->lv->segments = grub_calloc (lv->segment_count, sizeof (*lv->segments)); - if (!ignored_feature->lv->segments) - { - grub_lvm_free_ignored_feature_lvs (ignored_feature_lvs); - goto fail4; - } - grub_memcpy (ignored_feature->lv->segments, lv->segments, lv->segment_count * sizeof (*lv->segments)); - - for (i = 0; i < lv->segment_count; ++i) - { - struct grub_diskfilter_node *nodes = lv->segments[i].nodes; - grub_size_t node_count = lv->segments[i].node_count; - - ignored_feature->lv->segments[i].nodes = grub_calloc (node_count, sizeof (*nodes)); - if (!ignored_feature->lv->segments[i].nodes) - { - for (j = 0; j < i; ++j) - grub_free (ignored_feature->lv->segments[j].nodes); - grub_free (ignored_feature->lv->segments); - ignored_feature->lv->segments = NULL; - grub_lvm_free_ignored_feature_lvs (ignored_feature_lvs); - goto fail4; - } - grub_memcpy (ignored_feature->lv->segments[i].nodes, nodes, node_count * sizeof (*nodes)); - } - - if (ignored_feature->lv->segments) - { - ignored_feature->lv->segment_count = lv->segment_count; - ignored_feature->lv->vg = vg; - ignored_feature->lv->next = vg->lvs; - vg->lvs = ignored_feature->lv; - ignored_feature->lv = NULL; - } - } - else - { -#ifdef GRUB_UTIL - grub_util_info ("Couldn't find LVM part of ignored feature on %s", ignored_feature->origin); -#endif - } - } - } - - /* Match LVs. Must be done after cache and integrity are found. */ - { - struct grub_diskfilter_lv *lv1; - struct grub_diskfilter_lv *lv2; - - for (lv1 = vg->lvs; lv1; lv1 = lv1->next) - for (i = 0; i < lv1->segment_count; i++) - for (j = 0; j < lv1->segments[i].node_count; j++) - { - if (vg->pvs) - for (pv = vg->pvs; pv; pv = pv->next) - { - if (! grub_strcmp (pv->name, - lv1->segments[i].nodes[j].name)) - { - lv1->segments[i].nodes[j].pv = pv; - break; - } - } - if (lv1->segments[i].nodes[j].pv == NULL) - for (lv2 = vg->lvs; lv2; lv2 = lv2->next) - { - if (lv1 == lv2) - continue; - if (grub_strcmp (lv2->name, - lv1->segments[i].nodes[j].name) == 0) - lv1->segments[i].nodes[j].lv = lv2; - } - } - } - - grub_lvm_free_ignored_feature_lvs (ignored_feature_lvs); - if (grub_diskfilter_vg_register (vg)) - goto fail4; - } - else - { - grub_free (vgname); - } - - id->uuid = grub_malloc (GRUB_LVM_ID_STRLEN); - if (!id->uuid) - goto fail4; - grub_memcpy (id->uuid, pv_id, GRUB_LVM_ID_STRLEN); - id->uuidlen = GRUB_LVM_ID_STRLEN; - grub_free (metadatabuf); - *start_sector = -1; - return vg; - - /* Failure path. */ - fail4: - grub_free (vg); - fail3: - grub_free (vgname); - - fail2: - grub_free (metadatabuf); - fail: - return NULL; -} - - - -static struct grub_diskfilter grub_lvm_dev = { - .name = "lvm", - .detect = grub_lvm_detect, - .next = 0 -}; - -GRUB_MOD_INIT (lvm) -{ - grub_diskfilter_register_back (&grub_lvm_dev); -} - -GRUB_MOD_FINI (lvm) -{ - grub_diskfilter_unregister (&grub_lvm_dev); -} diff --git a/grub-core/disk/mdraid1x_linux.c b/grub-core/disk/mdraid1x_linux.c deleted file mode 100644 index dd5d440a3..000000000 --- a/grub-core/disk/mdraid1x_linux.c +++ /dev/null @@ -1,311 +0,0 @@ -/* mdraid_linux.c - module to handle Linux Software RAID. */ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* Linux RAID on disk structures and constants, - copied from include/linux/raid/md_p.h. */ - -#define SB_MAGIC 0xa92b4efc - -/* - * The version-1 superblock : - * All numeric fields are little-endian. - * - * Total size: 256 bytes plus 2 per device. - * 1K allows 384 devices. - */ - -struct grub_raid_super_1x -{ - /* Constant array information - 128 bytes. */ - grub_uint32_t magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian. */ - grub_uint32_t major_version; /* 1. */ - grub_uint32_t feature_map; /* Bit 0 set if 'bitmap_offset' is meaningful. */ - grub_uint32_t pad0; /* Always set to 0 when writing. */ - - grub_uint8_t set_uuid[16]; /* User-space generated. */ - char set_name[32]; /* Set and interpreted by user-space. */ - - grub_uint64_t ctime; /* Lo 40 bits are seconds, top 24 are microseconds or 0. */ - grub_uint32_t level; /* -4 (multipath), -1 (linear), 0,1,4,5. */ - grub_uint32_t layout; /* only for raid5 and raid10 currently. */ - grub_uint64_t size; /* Used size of component devices, in 512byte sectors. */ - - grub_uint32_t chunksize; /* In 512byte sectors. */ - grub_uint32_t raid_disks; - grub_uint32_t bitmap_offset; /* Sectors after start of superblock that bitmap starts - * NOTE: signed, so bitmap can be before superblock - * only meaningful of feature_map[0] is set. - */ - - /* These are only valid with feature bit '4'. */ - grub_uint32_t new_level; /* New level we are reshaping to. */ - grub_uint64_t reshape_position; /* Next address in array-space for reshape. */ - grub_uint32_t delta_disks; /* Change in number of raid_disks. */ - grub_uint32_t new_layout; /* New layout. */ - grub_uint32_t new_chunk; /* New chunk size (512byte sectors). */ - grub_uint8_t pad1[128 - 124]; /* Set to 0 when written. */ - - /* Constant this-device information - 64 bytes. */ - grub_uint64_t data_offset; /* Sector start of data, often 0. */ - grub_uint64_t data_size; /* Sectors in this device that can be used for data. */ - grub_uint64_t super_offset; /* Sector start of this superblock. */ - grub_uint64_t recovery_offset; /* Sectors before this offset (from data_offset) have been recovered. */ - grub_uint32_t dev_number; /* Permanent identifier of this device - not role in raid. */ - grub_uint32_t cnt_corrected_read; /* Number of read errors that were corrected by re-writing. */ - grub_uint8_t device_uuid[16]; /* User-space setable, ignored by kernel. */ - grub_uint8_t devflags; /* Per-device flags. Only one defined... */ - grub_uint8_t pad2[64 - 57]; /* Set to 0 when writing. */ - - /* Array state information - 64 bytes. */ - grub_uint64_t utime; /* 40 bits second, 24 btes microseconds. */ - grub_uint64_t events; /* Incremented when superblock updated. */ - grub_uint64_t resync_offset; /* Data before this offset (from data_offset) known to be in sync. */ - grub_uint32_t sb_csum; /* Checksum upto devs[max_dev]. */ - grub_uint32_t max_dev; /* Size of devs[] array to consider. */ - grub_uint8_t pad3[64 - 32]; /* Set to 0 when writing. */ - - /* Device state information. Indexed by dev_number. - * 2 bytes per device. - * Note there are no per-device state flags. State information is rolled - * into the 'roles' value. If a device is spare or faulty, then it doesn't - * have a meaningful role. - */ - grub_uint16_t dev_roles[0]; /* Role in array, or 0xffff for a spare, or 0xfffe for faulty. */ -}; -/* Could be GRUB_PACKED, but since all members in this struct - are already appropriately aligned, we can omit this and avoid suboptimal - assembly in some cases. */ - -#define WriteMostly1 1 /* Mask for writemostly flag in above devflags. */ - -#define GRUB_MD_SECTOR_SHIFT 9 /* Follow Linux kernel v6.8. */ -#define GRUB_MD_SECTOR_SIZE (1 << GRUB_MD_SECTOR_SHIFT) - -static struct grub_diskfilter_vg * -grub_mdraid_detect (grub_disk_t disk, - struct grub_diskfilter_pv_id *id, - grub_disk_addr_t *start_sector) -{ - grub_uint64_t size; - grub_uint8_t minor_version; - - size = grub_disk_native_sectors (disk); - - /* Check for an 1.x superblock. - * It's always aligned to a 4K boundary - * and depending on the minor version it can be: - * 0: At least 8K, but less than 12K, from end of device - * 1: At start of device - * 2: 4K from start of device. - */ - - for (minor_version = 0; minor_version < 3; ++minor_version) - { - grub_disk_addr_t sector = 0; - struct grub_raid_super_1x sb; - grub_uint16_t role; - grub_uint32_t level; - struct grub_diskfilter_vg *array; - char *uuid; - grub_uint64_t sb_sz, data_end, sb_end; - - if (size == GRUB_DISK_SIZE_UNKNOWN && minor_version == 0) - continue; - - switch (minor_version) - { - case 0: - sector = (size - 8 * 2) & ~(4 * 2 - 1); - break; - case 1: - sector = 0; - break; - case 2: - sector = 4 * 2; - break; - } - - if (grub_disk_read (disk, sector, 0, sizeof (struct grub_raid_super_1x), - &sb)) - return NULL; - - if (sb.magic != grub_cpu_to_le32_compile_time (SB_MAGIC) - || grub_le_to_cpu64 (sb.super_offset) != sector) - continue; - - /* - * The first check follows the Linux kernel's data_size - * validation from v6.8-rc5. - */ - if (grub_le_to_cpu64 (sb.data_size) < 10 || - grub_le_to_cpu64 (sb.raid_disks) > GRUB_MDRAID_MAX_DISKS) - { - grub_dprintf ("mdraid1x", "Corrupted superblock\n"); - return NULL; - } - - /* - * Total size of superblock: 256 bytes plus 2 bytes per device - * in the array. - */ - sb_sz = sizeof (struct grub_raid_super_1x) + grub_le_to_cpu64 (sb.raid_disks) * 2; - - if (grub_add (grub_le_to_cpu64 (sb.super_offset), - (ALIGN_UP(sb_sz, GRUB_MD_SECTOR_SIZE) >> GRUB_MD_SECTOR_SHIFT), &sb_end)) - { - grub_dprintf ("mdraid1x", "Invalid superblock end.\n"); - return NULL; - } - - if (grub_add (grub_le_to_cpu64 (sb.data_offset), - grub_le_to_cpu64 (sb.data_size), &data_end)) - { - grub_dprintf ("mdraid1x", "Invalid data end.\n"); - return NULL; - } - - /* In minor versions 1 and 2, superblock is positioned before data. */ - if (minor_version) - { - if (grub_le_to_cpu64 (sb.data_offset) < sb_end) - { - grub_dprintf ("mdraid1x", - "The superblock either overlaps with the data " - "or is behind it.\n"); - return NULL; - } - - if (data_end > size) - { - grub_dprintf ("mdraid1x", - "The data region ends at %" PRIuGRUB_UINT64_T ", " - "past the end of the disk (%" PRIuGRUB_UINT64_T ")\n", - data_end, size); - return NULL; - } - } - else - { - /* In minor version 0, superblock is at the end of the device. */ - if (grub_le_to_cpu64 (sb.super_offset) < data_end) - { - grub_dprintf ("mdraid1x", - "The data either overlaps with the superblock " - "or is behind it.\n"); - return NULL; - } - - if (sb_end > size) - { - grub_dprintf ("mdraid1x", - "The superblock region ends at " - "%" PRIuGRUB_UINT64_T ", past the end of " - "the disk (%" PRIuGRUB_UINT64_T ")\n", - sb_end, size); - return NULL; - } - } - - if (sb.major_version != grub_cpu_to_le32_compile_time (1)) - /* Unsupported version. */ - return NULL; - - level = grub_le_to_cpu32 (sb.level); - - /* Multipath. */ - if ((int) level == -4) - level = 1; - - if (level != 0 && level != 1 && level != 4 && - level != 5 && level != 6 && level != 10) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Unsupported RAID level: %d", sb.level); - return NULL; - } - - if (grub_le_to_cpu32 (sb.dev_number) >= - grub_le_to_cpu32 (sb.max_dev)) - /* Spares aren't implemented. */ - return NULL; - - if (grub_disk_read (disk, sector, - (char *) (sb.dev_roles + grub_le_to_cpu32 (sb.dev_number)) - - (char *) &sb, - sizeof (role), &role)) - return NULL; - - if (grub_le_to_cpu16 (role) - >= grub_le_to_cpu32 (sb.raid_disks)) - /* Spares aren't implemented. */ - return NULL; - - id->uuidlen = 0; - id->id = grub_le_to_cpu16 (role); - - uuid = grub_malloc (16); - if (!uuid) - return NULL; - - grub_memcpy (uuid, sb.set_uuid, 16); - - *start_sector = grub_le_to_cpu64 (sb.data_offset); - - array = grub_diskfilter_make_raid (16, uuid, - grub_le_to_cpu32 (sb.raid_disks), - sb.set_name, - (sb.size) - ? grub_le_to_cpu64 (sb.size) - : grub_le_to_cpu64 (sb.data_size), - grub_le_to_cpu32 (sb.chunksize), - grub_le_to_cpu32 (sb.layout), - grub_le_to_cpu32 (sb.level)); - - return array; - } - - /* not 1.x raid. */ - return NULL; -} - -static struct grub_diskfilter grub_mdraid_dev = { - .name = "mdraid1x", - .detect = grub_mdraid_detect, - .next = 0 -}; - -GRUB_MOD_INIT (mdraid1x) -{ - grub_diskfilter_register_front (&grub_mdraid_dev); -} - -GRUB_MOD_FINI (mdraid1x) -{ - grub_diskfilter_unregister (&grub_mdraid_dev); -} diff --git a/grub-core/disk/mdraid_linux_be.c b/grub-core/disk/mdraid_linux_be.c deleted file mode 100644 index 539bcf469..000000000 --- a/grub-core/disk/mdraid_linux_be.c +++ /dev/null @@ -1,2 +0,0 @@ -#define MODE_BIGENDIAN 1 -#include "mdraid_linux.c" diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c deleted file mode 100644 index 0578a93e1..000000000 --- a/grub-core/disk/pata.c +++ /dev/null @@ -1,556 +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 . - */ - -#include -#include -#include -#include -#include -#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS -#include -#include -#else -#define GRUB_MACHINE_PCI_IO_BASE 0xb4000000 -#endif -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* At the moment, only two IDE ports are supported. */ -static const grub_port_t grub_pata_ioaddress[] = { GRUB_ATA_CH0_PORT1, - GRUB_ATA_CH1_PORT1 }; - -struct grub_pata_device -{ - /* IDE port to use. */ - int port; - - /* IO addresses on which the registers for this device can be - found. */ - grub_port_t ioaddress; - - /* 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; - - int present; - - struct grub_pata_device *next; -}; - -static struct grub_pata_device *grub_pata_devices; - -static inline void -grub_pata_regset (struct grub_pata_device *dev, int reg, int val) -{ - grub_outb (val, dev->ioaddress + reg); -} - -static inline grub_uint8_t -grub_pata_regget (struct grub_pata_device *dev, int reg) -{ - return grub_inb (dev->ioaddress + reg); -} - -/* Wait for !BSY. */ -static grub_err_t -grub_pata_wait_not_busy (struct grub_pata_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_pata_regget (dev, GRUB_ATA_REG_STATUS)) - & GRUB_ATA_STATUS_BUSY) - { - if (i >= milliseconds) - { - grub_dprintf ("pata", "timeout: %dms, status=0x%x\n", - milliseconds, sts); - return grub_error (GRUB_ERR_TIMEOUT, "PATA timeout"); - } - - grub_millisleep (1); - i++; - } - - return GRUB_ERR_NONE; -} - -static inline grub_err_t -grub_pata_check_ready (struct grub_pata_device *dev, int spinup) -{ - if (grub_pata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY) - return grub_pata_wait_not_busy (dev, spinup ? GRUB_ATA_TOUT_SPINUP - : GRUB_ATA_TOUT_STD); - - return GRUB_ERR_NONE; -} - -static inline void -grub_pata_wait (void) -{ - grub_millisleep (50); -} - -#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS -#define grub_ata_to_cpu16(x) ((grub_uint16_t) (x)) -#define grub_cpu_to_ata16(x) ((grub_uint16_t) (x)) -#else -#define grub_ata_to_cpu16 grub_le_to_cpu16 -#define grub_cpu_to_ata16 grub_cpu_to_le16 -#endif - -static void -grub_pata_pio_read (struct grub_pata_device *dev, char *buf, grub_size_t size) -{ - unsigned int i; - - /* Read in the data, word by word. */ - for (i = 0; i < size / 2; i++) - grub_set_unaligned16 (buf + 2 * i, - grub_ata_to_cpu16 (grub_inw(dev->ioaddress - + GRUB_ATA_REG_DATA))); - if (size & 1) - buf[size - 1] = (char) grub_ata_to_cpu16 (grub_inw (dev->ioaddress - + GRUB_ATA_REG_DATA)); -} - -static void -grub_pata_pio_write (struct grub_pata_device *dev, char *buf, grub_size_t size) -{ - unsigned int i; - - /* Write the data, word by word. */ - for (i = 0; i < size / 2; i++) - grub_outw(grub_cpu_to_ata16 (grub_get_unaligned16 (buf + 2 * i)), dev->ioaddress + GRUB_ATA_REG_DATA); -} - -/* ATA pass through support, used by hdparm.mod. */ -static grub_err_t -grub_pata_readwrite (struct grub_ata *disk, - struct grub_disk_ata_pass_through_parms *parms, - int spinup) -{ - struct grub_pata_device *dev = (struct grub_pata_device *) disk->data; - grub_size_t nread = 0; - int i; - - if (! (parms->cmdsize == 0 || parms->cmdsize == 12)) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "ATAPI non-12 byte commands not supported"); - - grub_dprintf ("pata", "pata_pass_through: cmd=0x%x, features=0x%x, sectors=0x%x\n", - parms->taskfile.cmd, - parms->taskfile.features, - parms->taskfile.sectors); - grub_dprintf ("pata", "lba_high=0x%x, lba_mid=0x%x, lba_low=0x%x, size=%" - PRIuGRUB_SIZE "\n", - parms->taskfile.lba_high, - parms->taskfile.lba_mid, - parms->taskfile.lba_low, parms->size); - - /* Set registers. */ - grub_pata_regset (dev, GRUB_ATA_REG_DISK, (dev->device << 4) - | (parms->taskfile.disk & 0xef)); - if (grub_pata_check_ready (dev, spinup)) - return grub_errno; - - for (i = GRUB_ATA_REG_SECTORS; i <= GRUB_ATA_REG_LBAHIGH; i++) - grub_pata_regset (dev, i, - parms->taskfile.raw[7 + (i - GRUB_ATA_REG_SECTORS)]); - for (i = GRUB_ATA_REG_FEATURES; i <= GRUB_ATA_REG_LBAHIGH; i++) - grub_pata_regset (dev, i, parms->taskfile.raw[i - GRUB_ATA_REG_FEATURES]); - - /* Start command. */ - grub_pata_regset (dev, GRUB_ATA_REG_CMD, parms->taskfile.cmd); - - /* Wait for !BSY. */ - if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) - return grub_errno; - - /* Check status. */ - grub_int8_t sts = grub_pata_regget (dev, GRUB_ATA_REG_STATUS); - grub_dprintf ("pata", "status=0x%x\n", sts); - - if (parms->cmdsize) - { - grub_uint8_t irs; - /* Wait for !BSY. */ - if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) - return grub_errno; - - irs = grub_pata_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) == GRUB_ATAPI_IREASON_CMD_OUT)) - return grub_error (GRUB_ERR_READ_ERROR, "ATAPI protocol error"); - /* Write the packet. */ - grub_pata_pio_write (dev, parms->cmd, parms->cmdsize); - } - - /* Transfer data. */ - while (nread < parms->size - && (sts & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) - == GRUB_ATA_STATUS_DRQ) - { - unsigned cnt; - - /* Wait for !BSY. */ - if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) - return grub_errno; - - if (parms->cmdsize) - { - if ((grub_pata_regget (dev, GRUB_ATAPI_REG_IREASON) - & GRUB_ATAPI_IREASON_MASK) != GRUB_ATAPI_IREASON_DATA_IN) - return grub_error (GRUB_ERR_READ_ERROR, "ATAPI protocol error"); - - cnt = grub_pata_regget (dev, GRUB_ATAPI_REG_CNTHIGH) << 8 - | grub_pata_regget (dev, GRUB_ATAPI_REG_CNTLOW); - grub_dprintf("pata", "DRQ count=%u\n", cnt); - - /* Count of last transfer may be uneven. */ - if (! (0 < cnt && cnt <= parms->size - nread - && (! (cnt & 1) || cnt == parms->size - nread))) - return grub_error (GRUB_ERR_READ_ERROR, - "invalid ATAPI transfer count"); - } - else - cnt = GRUB_DISK_SECTOR_SIZE; - if (cnt > parms->size - nread) - cnt = parms->size - nread; - - if (parms->write) - grub_pata_pio_write (dev, (char *) parms->buffer + nread, cnt); - else - grub_pata_pio_read (dev, (char *) parms->buffer + nread, cnt); - - nread += cnt; - } - if (parms->write) - { - /* Check for write error. */ - if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) - return grub_errno; - - if (grub_pata_regget (dev, GRUB_ATA_REG_STATUS) - & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) - return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error"); - } - parms->size = nread; - - /* Wait for !BSY. */ - if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) - return grub_errno; - - /* Return registers. */ - for (i = GRUB_ATA_REG_ERROR; i <= GRUB_ATA_REG_STATUS; i++) - parms->taskfile.raw[i - GRUB_ATA_REG_FEATURES] = grub_pata_regget (dev, i); - - grub_dprintf ("pata", "status=0x%x, error=0x%x, sectors=0x%x\n", - parms->taskfile.status, - parms->taskfile.error, - parms->taskfile.sectors); - - if (parms->taskfile.status - & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) - return grub_error (GRUB_ERR_READ_ERROR, "PATA passthrough failed"); - - return GRUB_ERR_NONE; -} - -static grub_err_t -check_device (struct grub_pata_device *dev) -{ - grub_pata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4); - grub_pata_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_pata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A); - grub_pata_wait (); - grub_uint8_t sec = grub_pata_regget (dev, GRUB_ATA_REG_SECTORS); - grub_dprintf ("ata", "sectors=0x%x\n", sec); - if (sec != 0x5A) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no device connected"); - - /* 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. */ - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_pata_device_initialize (int port, int device, int addr) -{ - struct grub_pata_device *dev; - struct grub_pata_device **devp; - grub_err_t err; - - grub_dprintf ("pata", "detecting device %d,%d (0x%x)\n", - port, device, addr); - - 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->present = 1; - dev->next = NULL; - - /* Register the device. */ - for (devp = &grub_pata_devices; *devp; devp = &(*devp)->next); - *devp = dev; - - err = check_device (dev); - if (err == GRUB_ERR_UNKNOWN_DEVICE) - { - grub_dprintf ("pata", "%s\n", grub_errmsg); - grub_error_pop (); - } - - if (err) - grub_print_error (); - - return 0; -} - -#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS -static int -grub_pata_pciinit (grub_pci_device_t dev, - grub_pci_id_t pciid, - void *data __attribute__ ((unused))) -{ - 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 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 == GRUB_CS5536_PCIID) - { - 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; - - /* If the channel is in compatibility mode, just assign the - default registers. */ - if (compat == 0 && !compat_use[i]) - { - rega = grub_pata_ioaddress[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) && (bar1 & ~3)) - { - rega = bar1 & ~3; - addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write_word (addr, grub_pci_read_word (addr) - | GRUB_PCI_COMMAND_IO_ENABLED - | GRUB_PCI_COMMAND_MEM_ENABLED - | GRUB_PCI_COMMAND_BUS_MASTER); - - } - } - - grub_dprintf ("pata", - "PCI dev (%d,%d,%d) compat=%d rega=0x%x\n", - grub_pci_get_bus (dev), grub_pci_get_device (dev), - grub_pci_get_function (dev), compat, rega); - - if (rega) - { - grub_errno = GRUB_ERR_NONE; - grub_pata_device_initialize (controller * 2 + i, 0, rega); - - /* 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_pata_device_initialize (controller * 2 + i, 1, rega); - - /* Likewise. */ - if (grub_errno) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - } - } - } - - controller++; - - return 0; -} - -static grub_err_t -grub_pata_initialize (void) -{ - grub_pci_iterate (grub_pata_pciinit, NULL); - return 0; -} -#else -static grub_err_t -grub_pata_initialize (void) -{ - int i; - for (i = 0; i < 2; i++) - { - grub_pata_device_initialize (i, 0, grub_pata_ioaddress[i]); - grub_pata_device_initialize (i, 1, grub_pata_ioaddress[i]); - } - return 0; -} -#endif - -static grub_err_t -grub_pata_open (int id, int devnum, struct grub_ata *ata) -{ - struct grub_pata_device *dev; - struct grub_pata_device *devfnd = 0; - grub_err_t err; - - if (id != GRUB_SCSI_SUBSYSTEM_PATA) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a PATA device"); - - for (dev = grub_pata_devices; dev; dev = dev->next) - { - if (dev->port * 2 + dev->device == devnum) - { - devfnd = dev; - break; - } - } - - grub_dprintf ("pata", "opening PATA dev `ata%d'\n", devnum); - - if (! devfnd) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such PATA device"); - - err = check_device (devfnd); - if (err) - return err; - - ata->data = devfnd; - ata->dma = 0; - ata->maxbuffer = 256 * 512; - ata->present = &devfnd->present; - - return GRUB_ERR_NONE; -} - -static int -grub_pata_iterate (grub_ata_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - struct grub_pata_device *dev; - - if (pull != GRUB_DISK_PULL_NONE) - return 0; - - for (dev = grub_pata_devices; dev; dev = dev->next) - if (hook (GRUB_SCSI_SUBSYSTEM_PATA, dev->port * 2 + dev->device, - hook_data)) - return 1; - - return 0; -} - - -static struct grub_ata_dev grub_pata_dev = - { - .iterate = grub_pata_iterate, - .open = grub_pata_open, - .readwrite = grub_pata_readwrite, - }; - - - - -GRUB_MOD_INIT(ata_pthru) -{ - grub_stop_disk_firmware (); - - /* ATA initialization. */ - grub_pata_initialize (); - - grub_ata_dev_register (&grub_pata_dev); -} - -GRUB_MOD_FINI(ata_pthru) -{ - grub_ata_dev_unregister (&grub_pata_dev); -} diff --git a/grub-core/disk/plainmount.c b/grub-core/disk/plainmount.c deleted file mode 100644 index 21ec4072c..000000000 --- a/grub-core/disk/plainmount.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -/* plaimount.c - Open device encrypted in plain mode. */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define PLAINMOUNT_DEFAULT_SECTOR_SIZE 512 -#define PLAINMOUNT_DEFAULT_UUID "109fea84-a6b7-34a8-4bd1-1c506305a400" - - -enum PLAINMOUNT_OPTION - { - OPTION_HASH, - OPTION_CIPHER, - OPTION_KEY_SIZE, - OPTION_SECTOR_SIZE, - OPTION_PASSWORD, - OPTION_KEYFILE, - OPTION_KEYFILE_OFFSET, - OPTION_UUID - }; - -static const struct grub_arg_option options[] = - { - /* TRANSLATORS: It's still restricted to this module only. */ - {"hash", 'h', 0, N_("Password hash"), 0, ARG_TYPE_STRING}, - {"cipher", 'c', 0, N_("Password cipher"), 0, ARG_TYPE_STRING}, - {"key-size", 's', 0, N_("Key size (in bits)"), 0, ARG_TYPE_INT}, - {"sector-size", 'S', 0, N_("Device sector size"), 0, ARG_TYPE_INT}, - {"password", 'p', 0, N_("Password (key)"), 0, ARG_TYPE_STRING}, - {"keyfile", 'd', 0, N_("Keyfile path"), 0, ARG_TYPE_STRING}, - {"keyfile-offset", 'O', 0, N_("Keyfile offset"), 0, ARG_TYPE_INT}, - {"uuid", 'u', 0, N_("Set device UUID"), 0, ARG_TYPE_STRING}, - {0, 0, 0, 0, 0, 0} - }; - -/* Cryptodisk setkey() function wrapper */ -static grub_err_t -plainmount_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, - grub_size_t size) -{ - gcry_err_code_t code = grub_cryptodisk_setkey (dev, key, size); - if (code != GPG_ERR_NO_ERROR) - { - grub_dprintf ("plainmount", "failed to set cipher key with code: %d\n", code); - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot set specified key")); - } - return GRUB_ERR_NONE; -} - -/* Configure cryptodisk uuid */ -static void plainmount_set_uuid (grub_cryptodisk_t dev, const char *user_uuid) -{ - grub_size_t pos = 0; - - /* Size of user_uuid is checked in main func */ - if (user_uuid != NULL) - grub_strcpy (dev->uuid, user_uuid); - else - { - /* - * Set default UUID. Last digits start from 1 and are incremented for - * each new plainmount device by snprintf(). - */ - grub_snprintf (dev->uuid, sizeof (dev->uuid) - 1, "%36lx", dev->id + 1); - while (dev->uuid[++pos] == ' '); - grub_memcpy (dev->uuid, PLAINMOUNT_DEFAULT_UUID, pos); - } - COMPILE_TIME_ASSERT (sizeof (dev->uuid) >= sizeof (PLAINMOUNT_DEFAULT_UUID)); -} - -/* Configure cryptodevice sector size (-S option) */ -static grub_err_t -plainmount_configure_sectors (grub_cryptodisk_t dev, grub_disk_t disk, - grub_size_t sector_size) -{ - dev->total_sectors = grub_disk_native_sectors (disk); - if (dev->total_sectors == GRUB_DISK_SIZE_UNKNOWN) - return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot determine disk %s size"), - disk->name); - - /* Convert size to sectors */ - dev->log_sector_size = grub_log2ull (sector_size); - dev->total_sectors = grub_convert_sector (dev->total_sectors, - GRUB_DISK_SECTOR_BITS, - dev->log_sector_size); - if (dev->total_sectors == 0) - return grub_error (GRUB_ERR_BAD_DEVICE, - N_("cannot set specified sector size on disk %s"), - disk->name); - - grub_dprintf ("plainmount", "log_sector_size=%d, total_sectors=%" - PRIuGRUB_UINT64_T"\n", dev->log_sector_size, dev->total_sectors); - return GRUB_ERR_NONE; -} - -/* Hashes a password into a key and stores it with the cipher. */ -static grub_err_t -plainmount_configure_password (grub_cryptodisk_t dev, const char *hash, - grub_uint8_t *key_data, grub_size_t key_size, - grub_size_t password_size) -{ - grub_uint8_t *derived_hash, *dh; - char *p; - unsigned int round, i, len, size; - grub_size_t alloc_size, sz; - grub_err_t err = GRUB_ERR_NONE; - - /* Support none (plain) hash */ - if (grub_strcmp (hash, "plain") == 0) - { - dev->hash = NULL; - return err; - } - - /* Hash argument was checked at main func */ - dev->hash = grub_crypto_lookup_md_by_name (hash); - len = dev->hash->mdlen; - - alloc_size = grub_max (password_size, key_size); - /* - * Allocate buffer for the password and for an added prefix character - * for each hash round ('alloc_size' may not be a multiple of 'len'). - */ - if (grub_add (alloc_size, (alloc_size / len), &sz) || - grub_add (sz, 1, &sz)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while allocating size of password buffer")); - - p = grub_zalloc (sz); - derived_hash = grub_zalloc (GRUB_CRYPTODISK_MAX_KEYLEN * 2); - if (p == NULL || derived_hash == NULL) - { - err = grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); - goto fail; - } - dh = derived_hash; - - /* - * Hash password. Adapted from cryptsetup. - * https://gitlab.com/cryptsetup/cryptsetup/-/blob/main/lib/crypt_plain.c - */ - for (round = 0, size = alloc_size; size; round++, dh += len, size -= len) - { - for (i = 0; i < round; i++) - p[i] = 'A'; - - grub_memcpy (p + i, (char*) key_data, password_size); - - if (len > size) - len = size; - - grub_crypto_hash (dev->hash, dh, p, password_size + round); - } - grub_memcpy (key_data, derived_hash, key_size); - - fail: - grub_free (p); - grub_free (derived_hash); - return err; -} - -/* Read key material from keyfile */ -static grub_err_t -plainmount_configure_keyfile (char *keyfile, grub_uint8_t *key_data, - grub_size_t key_size, grub_size_t keyfile_offset) -{ - grub_file_t g_keyfile = grub_file_open (keyfile, GRUB_FILE_TYPE_NONE); - if (g_keyfile == NULL) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("cannot open keyfile %s"), - keyfile); - - if (grub_file_seek (g_keyfile, keyfile_offset) == (grub_off_t) - 1) - return grub_error (GRUB_ERR_FILE_READ_ERROR, - N_("cannot seek keyfile at offset %"PRIuGRUB_SIZE), - keyfile_offset); - - if (key_size > (g_keyfile->size - keyfile_offset)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Specified key size (%" - PRIuGRUB_SIZE") is too small for keyfile size (%" - PRIuGRUB_UINT64_T") and offset (%"PRIuGRUB_SIZE")"), - key_size, g_keyfile->size, keyfile_offset); - - if (grub_file_read (g_keyfile, key_data, key_size) != (grub_ssize_t) key_size) - return grub_error (GRUB_ERR_FILE_READ_ERROR, N_("error reading key file")); - return GRUB_ERR_NONE; -} - -/* Plainmount command entry point */ -static grub_err_t -grub_cmd_plainmount (grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_arg_list *state = ctxt->state; - grub_cryptodisk_t dev = NULL; - grub_disk_t disk = NULL; - const gcry_md_spec_t *gcry_hash; - char *diskname, *disklast = NULL, *cipher, *mode, *hash, *keyfile, *uuid; - grub_size_t len, key_size, sector_size, keyfile_offset = 0, password_size = 0; - grub_err_t err; - const char *p; - grub_uint8_t *key_data; - - if (argc < 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("device name required")); - - /* Check whether required arguments are specified */ - if (!state[OPTION_CIPHER].set || !state[OPTION_KEY_SIZE].set) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "cipher and key size must be set"); - if (!state[OPTION_HASH].set && !state[OPTION_KEYFILE].set) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "hash algorithm must be set"); - - /* Check hash */ - if (!state[OPTION_KEYFILE].set) - { - gcry_hash = grub_crypto_lookup_md_by_name (state[OPTION_HASH].arg); - if (!gcry_hash) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("couldn't load hash %s"), - state[OPTION_HASH].arg); - - if (gcry_hash->mdlen > GRUB_CRYPTODISK_MAX_KEYLEN) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("hash length %"PRIuGRUB_SIZE" exceeds maximum %d bits"), - gcry_hash->mdlen * GRUB_CHAR_BIT, - GRUB_CRYPTODISK_MAX_KEYLEN * GRUB_CHAR_BIT); - } - - /* Check cipher mode */ - if (!grub_strchr (state[OPTION_CIPHER].arg,'-')) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("invalid cipher mode, must be of format cipher-mode")); - - /* Check password size */ - if (state[OPTION_PASSWORD].set && grub_strlen (state[OPTION_PASSWORD].arg) > - GRUB_CRYPTODISK_MAX_PASSPHRASE) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("password exceeds maximium size")); - - /* Check uuid length */ - if (state[OPTION_UUID].set && grub_strlen (state[OPTION_UUID].arg) > - GRUB_CRYPTODISK_MAX_UUID_LENGTH - 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("specified UUID exceeds maximum size")); - if (state[OPTION_UUID].set && grub_strlen (state[OPTION_UUID].arg) == 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("specified UUID too short")); - - /* Parse plainmount arguments */ - grub_errno = GRUB_ERR_NONE; - keyfile_offset = state[OPTION_KEYFILE_OFFSET].set ? - grub_strtoull (state[OPTION_KEYFILE_OFFSET].arg, &p, 0) : 0; - if (state[OPTION_KEYFILE_OFFSET].set && - (state[OPTION_KEYFILE_OFFSET].arg[0] == '\0' || *p != '\0' || - grub_errno != GRUB_ERR_NONE)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unrecognized keyfile offset")); - - sector_size = state[OPTION_SECTOR_SIZE].set ? - grub_strtoull (state[OPTION_SECTOR_SIZE].arg, &p, 0) : - PLAINMOUNT_DEFAULT_SECTOR_SIZE; - if (state[OPTION_SECTOR_SIZE].set && (state[OPTION_SECTOR_SIZE].arg[0] == '\0' || - *p != '\0' || grub_errno != GRUB_ERR_NONE)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unrecognized sector size")); - - /* Check key size */ - key_size = grub_strtoull (state[OPTION_KEY_SIZE].arg, &p, 0); - if (state[OPTION_KEY_SIZE].arg[0] == '\0' || *p != '\0' || - grub_errno != GRUB_ERR_NONE) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unrecognized key size")); - if ((key_size % GRUB_CHAR_BIT) != 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("key size is not multiple of %d bits"), GRUB_CHAR_BIT); - key_size = key_size / GRUB_CHAR_BIT; - if (key_size > GRUB_CRYPTODISK_MAX_KEYLEN) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("key size %"PRIuGRUB_SIZE" exceeds maximum %d bits"), - key_size * GRUB_CHAR_BIT, - GRUB_CRYPTODISK_MAX_KEYLEN * GRUB_CHAR_BIT); - - /* Check disk sector size */ - if (sector_size < GRUB_DISK_SECTOR_SIZE) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("sector size -S must be at least %d"), - GRUB_DISK_SECTOR_SIZE); - if ((sector_size & (sector_size - 1)) != 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("sector size -S %"PRIuGRUB_SIZE" is not power of 2"), - sector_size); - - /* Allocate all stuff here */ - hash = state[OPTION_HASH].set ? grub_strdup (state[OPTION_HASH].arg) : NULL; - cipher = grub_strdup (state[OPTION_CIPHER].arg); - keyfile = state[OPTION_KEYFILE].set ? - grub_strdup (state[OPTION_KEYFILE].arg) : NULL; - dev = grub_zalloc (sizeof *dev); - key_data = grub_zalloc (GRUB_CRYPTODISK_MAX_PASSPHRASE); - uuid = state[OPTION_UUID].set ? grub_strdup (state[OPTION_UUID].arg) : NULL; - if ((state[OPTION_HASH].set && hash == NULL) || cipher == NULL || dev == NULL || - (state[OPTION_KEYFILE].set && keyfile == NULL) || key_data == NULL || - (state[OPTION_UUID].set && uuid == NULL)) - { - err = grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); - goto fail; - } - - /* Copy user password from -p option */ - if (state[OPTION_PASSWORD].set) - { - /* - * Password from the '-p' option is limited to C-string. - * Arbitrary data keys are supported via keyfiles. - */ - password_size = grub_strlen (state[OPTION_PASSWORD].arg); - grub_strcpy ((char*) key_data, state[OPTION_PASSWORD].arg); - } - - /* Set cipher mode (tested above) */ - mode = grub_strchr (cipher,'-'); - *mode++ = '\0'; - - /* Check cipher */ - err = grub_cryptodisk_setcipher (dev, cipher, mode); - if (err != GRUB_ERR_NONE) - { - if (err == GRUB_ERR_FILE_NOT_FOUND) - err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid cipher %s"), cipher); - else if (err == GRUB_ERR_BAD_ARGUMENT) - err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid mode %s"), mode); - else - err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid cipher %s or mode %s"), - cipher, mode); - goto fail; - } - - /* Open SOURCE disk */ - diskname = args[0]; - len = grub_strlen (diskname); - if (len && diskname[0] == '(' && diskname[len - 1] == ')') - { - disklast = &diskname[len - 1]; - *disklast = '\0'; - diskname++; - } - disk = grub_disk_open (diskname); - if (disk == NULL) - { - if (disklast) - *disklast = ')'; - err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot open disk %s"), diskname); - goto fail; - } - - /* Get password from console */ - if (!state[OPTION_KEYFILE].set && key_data[0] == '\0') - { - char *part = grub_partition_get_name (disk->partition); - grub_printf_ (N_("Enter passphrase for %s%s%s: "), disk->name, - disk->partition != NULL ? "," : "", - part != NULL ? part : N_("UNKNOWN")); - grub_free (part); - - if (!grub_password_get ((char*) key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE - 1)) - { - err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("error reading password")); - goto fail; - } - /* - * Password from interactive console is limited to C-string. - * Arbitrary data keys are supported via keyfiles. - */ - password_size = grub_strlen ((char*) key_data); - } - - /* Warn if hash and keyfile are both provided */ - if (state[OPTION_KEYFILE].set && state[OPTION_HASH].arg) - grub_printf_ (N_("warning: hash is ignored if keyfile is specified\n")); - - /* Warn if -p option is specified with keyfile */ - if (state[OPTION_PASSWORD].set && state[OPTION_KEYFILE].set) - grub_printf_ (N_("warning: password specified with -p option " - "is ignored if keyfile is provided\n")); - - /* Warn of -O is provided without keyfile */ - if (state[OPTION_KEYFILE_OFFSET].set && !state[OPTION_KEYFILE].set) - grub_printf_ (N_("warning: keyfile offset option -O " - "specified without keyfile option -d\n")); - - grub_dprintf ("plainmount", "parameters: cipher=%s, hash=%s, key_size=%" - PRIuGRUB_SIZE ", keyfile=%s, keyfile offset=%" PRIuGRUB_SIZE "\n", - cipher, hash, key_size, keyfile, keyfile_offset); - - err = plainmount_configure_sectors (dev, disk, sector_size); - if (err != GRUB_ERR_NONE) - goto fail; - - /* Configure keyfile or password */ - if (state[OPTION_KEYFILE].set) - err = plainmount_configure_keyfile (keyfile, key_data, key_size, keyfile_offset); - else - err = plainmount_configure_password (dev, hash, key_data, key_size, password_size); - if (err != GRUB_ERR_NONE) - goto fail; - - err = plainmount_setkey (dev, key_data, key_size); - if (err != GRUB_ERR_NONE) - goto fail; - - err = grub_cryptodisk_insert (dev, diskname, disk); - if (err != GRUB_ERR_NONE) - goto fail; - - dev->modname = "plainmount"; - dev->source_disk = disk; - plainmount_set_uuid (dev, uuid); - - fail: - grub_free (hash); - grub_free (cipher); - grub_free (keyfile); - grub_free (key_data); - grub_free (uuid); - if (err != GRUB_ERR_NONE && disk != NULL) - grub_disk_close (disk); - if (err != GRUB_ERR_NONE) - grub_free (dev); - return err; -} - -static grub_extcmd_t cmd; -GRUB_MOD_INIT (plainmount) -{ - cmd = grub_register_extcmd ("plainmount", grub_cmd_plainmount, 0, - N_("-c cipher -s key-size [-h hash] [-S sector-size]" - " [-o offset] [-p password] [-u uuid] " - " [[-d keyfile] [-O keyfile offset]] "), - N_("Open partition encrypted in plain mode."), - options); -} - -GRUB_MOD_FINI (plainmount) -{ - grub_unregister_extcmd (cmd); -} diff --git a/grub-core/disk/raid6_recover.c b/grub-core/disk/raid6_recover.c deleted file mode 100644 index 75fe464a4..000000000 --- a/grub-core/disk/raid6_recover.c +++ /dev/null @@ -1,218 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* x**y. */ -static grub_uint8_t powx[255 * 2]; -/* Such an s that x**s = y */ -static unsigned powx_inv[256]; -static const grub_uint8_t poly = 0x1d; - -static void -grub_raid_block_mulx (unsigned mul, char *buf, grub_size_t size) -{ - grub_size_t i; - grub_uint8_t *p; - - p = (grub_uint8_t *) buf; - for (i = 0; i < size; i++, p++) - if (*p) - *p = powx[mul + powx_inv[*p]]; -} - -static void -grub_raid6_init_table (void) -{ - unsigned i; - - grub_uint8_t cur = 1; - for (i = 0; i < 255; i++) - { - powx[i] = cur; - powx[i + 255] = cur; - powx_inv[cur] = i; - if (cur & 0x80) - cur = (cur << 1) ^ poly; - else - cur <<= 1; - } -} - -static unsigned -mod_255 (unsigned x) -{ - while (x > 0xff) - x = (x >> 8) + (x & 0xff); - if (x == 0xff) - return 0; - return x; -} - -static grub_err_t -raid6_recover_read_node (void *data, int disknr, - grub_uint64_t sector, - void *buf, grub_size_t size) -{ - struct grub_diskfilter_segment *array = data; - - return grub_diskfilter_read_node (&array->nodes[disknr], - (grub_disk_addr_t)sector, - size >> GRUB_DISK_SECTOR_BITS, buf); -} - -grub_err_t -grub_raid6_recover_gen (void *data, grub_uint64_t nstripes, int disknr, int p, - char *buf, grub_uint64_t sector, grub_size_t size, - int layout, raid_recover_read_t read_func) -{ - int i, q, pos; - int bad1 = -1, bad2 = -1; - char *pbuf = 0, *qbuf = 0; - - pbuf = grub_zalloc (size); - if (!pbuf) - goto quit; - - qbuf = grub_zalloc (size); - if (!qbuf) - goto quit; - - q = p + 1; - if (q == (int) nstripes) - q = 0; - - pos = q + 1; - if (pos == (int) nstripes) - pos = 0; - - for (i = 0; i < (int) nstripes - 2; i++) - { - int c; - if (layout & GRUB_RAID_LAYOUT_MUL_FROM_POS) - c = pos; - else - c = i; - if (pos == disknr) - bad1 = c; - else - { - if (!read_func (data, pos, sector, buf, size)) - { - grub_crypto_xor (pbuf, pbuf, buf, size); - grub_raid_block_mulx (c, buf, size); - grub_crypto_xor (qbuf, qbuf, buf, size); - } - else - { - /* Too many bad devices */ - if (bad2 >= 0) - goto quit; - - bad2 = c; - grub_errno = GRUB_ERR_NONE; - } - } - - pos++; - if (pos == (int) nstripes) - pos = 0; - } - - /* Invalid disknr or p */ - if (bad1 < 0) - goto quit; - - if (bad2 < 0) - { - /* One bad device */ - if (!read_func (data, p, sector, buf, size)) - { - grub_crypto_xor (buf, buf, pbuf, size); - goto quit; - } - - grub_errno = GRUB_ERR_NONE; - if (read_func (data, q, sector, buf, size)) - goto quit; - - grub_crypto_xor (buf, buf, qbuf, size); - grub_raid_block_mulx (255 - bad1, buf, - size); - } - else - { - /* Two bad devices */ - unsigned c; - - if (read_func (data, p, sector, buf, size)) - goto quit; - - grub_crypto_xor (pbuf, pbuf, buf, size); - - if (read_func (data, q, sector, buf, size)) - goto quit; - - grub_crypto_xor (qbuf, qbuf, buf, size); - - c = mod_255((255 ^ bad1) - + (255 ^ powx_inv[(powx[bad2 + (bad1 ^ 255)] ^ 1)])); - grub_raid_block_mulx (c, qbuf, size); - - c = mod_255((unsigned) bad2 + c); - grub_raid_block_mulx (c, pbuf, size); - - grub_crypto_xor (pbuf, pbuf, qbuf, size); - grub_memcpy (buf, pbuf, size); - } - -quit: - grub_free (pbuf); - grub_free (qbuf); - - return grub_errno; -} - -static grub_err_t -grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p, - char *buf, grub_disk_addr_t sector, grub_size_t size) -{ - return grub_raid6_recover_gen (array, array->node_count, disknr, p, buf, - sector, size << GRUB_DISK_SECTOR_BITS, - array->layout, raid6_recover_read_node); -} - -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 deleted file mode 100644 index 1c3865fd2..000000000 --- a/grub-core/disk/scsi.c +++ /dev/null @@ -1,764 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - - -static grub_scsi_dev_t grub_scsi_dev_list; - -const char grub_scsi_names[GRUB_SCSI_NUM_SUBSYSTEMS][5] = { - [GRUB_SCSI_SUBSYSTEM_USBMS] = "usb", - [GRUB_SCSI_SUBSYSTEM_PATA] = "ata", - [GRUB_SCSI_SUBSYSTEM_AHCI] = "ahci" -}; - -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; - } -} - - -/* Check result of previous operation. */ -static grub_err_t -grub_scsi_request_sense (grub_scsi_t scsi) -{ - struct grub_scsi_request_sense rs; - struct grub_scsi_request_sense_data rsd; - grub_err_t err; - - rs.opcode = grub_scsi_cmd_request_sense; - rs.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; - rs.reserved1 = 0; - rs.reserved2 = 0; - rs.alloc_length = 0x12; /* XXX: Hardcoded for now */ - rs.control = 0; - grub_memset (rs.pad, 0, sizeof(rs.pad)); - - err = scsi->dev->read (scsi, sizeof (rs), (char *) &rs, - sizeof (rsd), (char *) &rsd); - if (err) - return err; - - return GRUB_ERR_NONE; -} -/* Self commenting... */ -static grub_err_t -grub_scsi_test_unit_ready (grub_scsi_t scsi) -{ - struct grub_scsi_test_unit_ready tur; - grub_err_t err; - grub_err_t err_sense; - - tur.opcode = grub_scsi_cmd_test_unit_ready; - tur.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; - tur.reserved1 = 0; - tur.reserved2 = 0; - tur.reserved3 = 0; - tur.control = 0; - grub_memset (tur.pad, 0, sizeof(tur.pad)); - - err = scsi->dev->read (scsi, sizeof (tur), (char *) &tur, - 0, NULL); - - /* Each SCSI command should be followed by Request Sense. - If not so, many devices STALLs or definitely freezes. */ - err_sense = grub_scsi_request_sense (scsi); - if (err_sense != GRUB_ERR_NONE) - grub_errno = err; - /* err_sense is ignored for now and Request Sense Data also... */ - - if (err) - return err; - - return GRUB_ERR_NONE; -} - -/* Determine if 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; - grub_err_t err_sense; - - iq.opcode = grub_scsi_cmd_inquiry; - iq.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; - iq.page = 0; - iq.reserved = 0; - iq.alloc_length = 0x24; /* XXX: Hardcoded for now */ - iq.control = 0; - grub_memset (iq.pad, 0, sizeof(iq.pad)); - - err = scsi->dev->read (scsi, sizeof (iq), (char *) &iq, - sizeof (iqd), (char *) &iqd); - - /* Each SCSI command should be followed by Request Sense. - If not so, many devices STALLs or definitely freezes. */ - err_sense = grub_scsi_request_sense (scsi); - if (err_sense != GRUB_ERR_NONE) - grub_errno = err; - /* err_sense is ignored for now and Request Sense Data also... */ - - 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_capacity10 (grub_scsi_t scsi) -{ - struct grub_scsi_read_capacity10 rc; - struct grub_scsi_read_capacity10_data rcd; - grub_err_t err; - grub_err_t err_sense; - - rc.opcode = grub_scsi_cmd_read_capacity10; - rc.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; - rc.logical_block_addr = 0; - rc.reserved1 = 0; - rc.reserved2 = 0; - rc.PMI = 0; - rc.control = 0; - rc.pad = 0; - - err = scsi->dev->read (scsi, sizeof (rc), (char *) &rc, - sizeof (rcd), (char *) &rcd); - - /* Each SCSI command should be followed by Request Sense. - If not so, many devices STALLs or definitely freezes. */ - err_sense = grub_scsi_request_sense (scsi); - if (err_sense != GRUB_ERR_NONE) - grub_errno = err; -/* err_sense is ignored for now and Request Sense Data also... */ - - if (err) - return err; - - scsi->last_block = grub_be_to_cpu32 (rcd.last_block); - scsi->blocksize = grub_be_to_cpu32 (rcd.blocksize); - - return GRUB_ERR_NONE; -} - -/* Read the capacity and block size of SCSI. */ -static grub_err_t -grub_scsi_read_capacity16 (grub_scsi_t scsi) -{ - struct grub_scsi_read_capacity16 rc; - struct grub_scsi_read_capacity16_data rcd; - grub_err_t err; - grub_err_t err_sense; - - rc.opcode = grub_scsi_cmd_read_capacity16; - rc.lun = (scsi->lun << GRUB_SCSI_LUN_SHIFT) | 0x10; - rc.logical_block_addr = 0; - rc.alloc_len = grub_cpu_to_be32_compile_time (sizeof (rcd)); - rc.PMI = 0; - rc.control = 0; - - err = scsi->dev->read (scsi, sizeof (rc), (char *) &rc, - sizeof (rcd), (char *) &rcd); - - /* Each SCSI command should be followed by Request Sense. - If not so, many devices STALLs or definitely freezes. */ - err_sense = grub_scsi_request_sense (scsi); - if (err_sense != GRUB_ERR_NONE) - grub_errno = err; -/* err_sense is ignored for now and Request Sense Data also... */ - - if (err) - return err; - - scsi->last_block = grub_be_to_cpu64 (rcd.last_block); - 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; - grub_err_t err; - grub_err_t err_sense; - - 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; - - err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); - - /* Each SCSI command should be followed by Request Sense. - If not so, many devices STALLs or definitely freezes. */ - err_sense = grub_scsi_request_sense (scsi); - if (err_sense != GRUB_ERR_NONE) - grub_errno = err; - /* err_sense is ignored for now and Request Sense Data also... */ - - return err; -} - -/* 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; - grub_err_t err; - grub_err_t err_sense; - - 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; - - err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); - - /* Each SCSI command should be followed by Request Sense. - If not so, many devices STALLs or definitely freezes. */ - err_sense = grub_scsi_request_sense (scsi); - if (err_sense != GRUB_ERR_NONE) - grub_errno = err; - /* err_sense is ignored for now and Request Sense Data also... */ - - return err; -} - -/* Send a SCSI request for DISK: read SIZE sectors starting with - sector SECTOR to BUF. */ -static grub_err_t -grub_scsi_read16 (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, char *buf) -{ - grub_scsi_t scsi; - struct grub_scsi_read16 rd; - grub_err_t err; - grub_err_t err_sense; - - scsi = disk->data; - - rd.opcode = grub_scsi_cmd_read16; - rd.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; - rd.lba = grub_cpu_to_be64 (sector); - rd.size = grub_cpu_to_be32 (size); - rd.reserved = 0; - rd.control = 0; - - err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); - - /* Each SCSI command should be followed by Request Sense. - If not so, many devices STALLs or definitely freezes. */ - err_sense = grub_scsi_request_sense (scsi); - if (err_sense != GRUB_ERR_NONE) - grub_errno = err; - /* err_sense is ignored for now and Request Sense Data also... */ - - return err; -} - -/* 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, const char *buf) -{ - grub_scsi_t scsi; - struct grub_scsi_write10 wr; - grub_err_t err; - grub_err_t err_sense; - - 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; - - err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); - - /* Each SCSI command should be followed by Request Sense. - If not so, many devices STALLs or definitely freezes. */ - err_sense = grub_scsi_request_sense (scsi); - if (err_sense != GRUB_ERR_NONE) - grub_errno = err; - /* err_sense is ignored for now and Request Sense Data also... */ - - return err; -} - -#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_write12 (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, char *buf) -{ - grub_scsi_t scsi; - struct grub_scsi_write12 wr; - grub_err_t err; - grub_err_t err_sense; - - 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.control = 0; - - err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); - - /* Each SCSI command should be followed by Request Sense. - If not so, many devices STALLs or definitely freezes. */ - err_sense = grub_scsi_request_sense (scsi); - if (err_sense != GRUB_ERR_NONE) - grub_errno = err; - /* err_sense is ignored for now and Request Sense Data also... */ - - return err; -} -#endif - -/* Send a SCSI request for DISK: write the data stored in BUF to SIZE - sectors starting with SECTOR. */ -static grub_err_t -grub_scsi_write16 (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, const char *buf) -{ - grub_scsi_t scsi; - struct grub_scsi_write16 wr; - grub_err_t err; - grub_err_t err_sense; - - scsi = disk->data; - - wr.opcode = grub_scsi_cmd_write16; - wr.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; - wr.lba = grub_cpu_to_be64 (sector); - wr.size = grub_cpu_to_be32 (size); - wr.reserved = 0; - wr.control = 0; - - err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); - - /* Each SCSI command should be followed by Request Sense. - If not so, many devices STALLs or definitely freezes. */ - err_sense = grub_scsi_request_sense (scsi); - if (err_sense != GRUB_ERR_NONE) - grub_errno = err; - /* err_sense is ignored for now and Request Sense Data also... */ - - return err; -} - - - -/* Context for grub_scsi_iterate. */ -struct grub_scsi_iterate_ctx -{ - grub_disk_dev_iterate_hook_t hook; - void *hook_data; -}; - -/* Helper for grub_scsi_iterate. */ -static int -scsi_iterate (int id, int bus, int luns, void *data) -{ - struct grub_scsi_iterate_ctx *ctx = data; - int i; - - /* In case of a single LUN, just return `usbX'. */ - if (luns == 1) - { - char *sname; - int ret; - sname = grub_xasprintf ("%s%d", grub_scsi_names[id], bus); - if (!sname) - return 1; - ret = ctx->hook (sname, ctx->hook_data); - grub_free (sname); - return ret; - } - - /* 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%d%c", grub_scsi_names[id], bus, 'a' + i); - if (!sname) - return 1; - ret = ctx->hook (sname, ctx->hook_data); - grub_free (sname); - if (ret) - return 1; - } - return 0; -} - -static int -grub_scsi_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - struct grub_scsi_iterate_ctx ctx = { hook, hook_data }; - grub_scsi_dev_t p; - - for (p = grub_scsi_dev_list; p; p = p->next) - if (p->iterate && (p->iterate) (scsi_iterate, &ctx, pull)) - 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 lun, bus; - grub_uint64_t maxtime; - const char *nameend; - unsigned id; - - nameend = name + grub_strlen (name) - 1; - /* Try to detect a LUN ('a'-'z'), otherwise just use the first - LUN. */ - if (nameend >= name && *nameend >= 'a' && *nameend <= 'z') - { - lun = *nameend - 'a'; - nameend--; - } - else - lun = 0; - - while (nameend >= name && grub_isdigit (*nameend)) - nameend--; - - if (!nameend[1] || !grub_isdigit (nameend[1])) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk"); - - bus = grub_strtoul (nameend + 1, 0, 0); - - scsi = grub_malloc (sizeof (*scsi)); - if (! scsi) - return grub_errno; - - for (id = 0; id < ARRAY_SIZE (grub_scsi_names); id++) - if (grub_strncmp (grub_scsi_names[id], name, nameend - name) == 0) - break; - - if (id == ARRAY_SIZE (grub_scsi_names)) - { - grub_free (scsi); - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk"); - } - - for (p = grub_scsi_dev_list; p; p = p->next) - { - if (p->open (id, bus, scsi)) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - - disk->id = grub_make_scsi_id (id, bus, lun); - disk->data = scsi; - scsi->dev = p; - scsi->lun = lun; - scsi->bus = bus; - - 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"); - } - - /* According to USB MS tests specification, issue Test Unit Ready - * until OK */ - maxtime = grub_get_time_ms () + 5000; /* It is safer value */ - do - { - /* Timeout is necessary - for example in case when we have - * universal card reader with more LUNs and we have only - * one card inserted (or none), so only one LUN (or none) - * will be ready - and we want not to hang... */ - if (grub_get_time_ms () > maxtime) - { - err = GRUB_ERR_READ_ERROR; - grub_free (scsi); - grub_dprintf ("scsi", "LUN is not ready - timeout\n"); - return err; - } - err = grub_scsi_test_unit_ready (scsi); - } - while (err == GRUB_ERR_READ_ERROR); - /* Reset grub_errno ! - * It is set to some error code in loop before... */ - grub_errno = GRUB_ERR_NONE; - - /* Read capacity of media */ - err = grub_scsi_read_capacity10 (scsi); - if (err) - { - grub_free (scsi); - grub_dprintf ("scsi", "READ CAPACITY10 failed\n"); - return err; - } - - if (scsi->last_block == 0xffffffff) - { - err = grub_scsi_read_capacity16 (scsi); - if (err) - { - grub_free (scsi); - grub_dprintf ("scsi", "READ CAPACITY16 failed\n"); - return err; - } - } - - disk->total_sectors = scsi->last_block + 1; - /* PATA doesn't support more than 32K reads. - Not sure about AHCI and USB. If it's confirmed that either of - them can do bigger reads reliably this value can be moved to 'scsi' - structure. */ - disk->max_agglomerate = 32768 >> (GRUB_DISK_SECTOR_BITS - + GRUB_DISK_CACHE_BITS); - - if (scsi->blocksize & (scsi->blocksize - 1) || !scsi->blocksize) - { - grub_error (GRUB_ERR_IO, "invalid sector size %d", - scsi->blocksize); - grub_free (scsi); - return grub_errno; - } - disk->log_sector_size = grub_log2ull (scsi->blocksize); - - grub_dprintf ("scsi", "last_block=%" PRIuGRUB_UINT64_T ", blocksize=%u\n", - scsi->last_block, scsi->blocksize); - grub_dprintf ("scsi", "Disk total sectors = %llu\n", - (unsigned long long) disk->total_sectors); - - 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; - if (scsi->dev->close) - 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; - - grub_err_t err; - /* Depending on the type, select a read function. */ - switch (scsi->devtype) - { - case grub_scsi_devtype_direct: - if (sector >> 32) - err = grub_scsi_read16 (disk, sector, size, buf); - else - err = grub_scsi_read10 (disk, sector, size, buf); - if (err) - return err; - break; - - case grub_scsi_devtype_cdrom: - if (sector >> 32) - err = grub_scsi_read16 (disk, sector, size, buf); - else - err = grub_scsi_read12 (disk, sector, size, buf); - if (err) - return err; - break; - } - - return GRUB_ERR_NONE; - -#if 0 /* Workaround - it works - but very slowly, from some reason - * unknown to me (specially on OHCI). Do not use it. */ - /* Split transfer requests to device sector size because */ - /* some devices are not able to transfer more than 512-1024 bytes */ - grub_err_t err = GRUB_ERR_NONE; - - for ( ; size; size--) - { - /* Depending on the type, select a read function. */ - switch (scsi->devtype) - { - case grub_scsi_devtype_direct: - err = grub_scsi_read10 (disk, sector, 1, buf); - break; - - case grub_scsi_devtype_cdrom: - err = grub_scsi_read12 (disk, sector, 1, buf); - break; - - default: /* This should not happen */ - return GRUB_ERR_READ_ERROR; - } - if (err) - return err; - sector++; - buf += scsi->blocksize; - } - - return err; -#endif -} - -static grub_err_t -grub_scsi_write (grub_disk_t disk, - grub_disk_addr_t sector, - grub_size_t size, - const char *buf) -{ - grub_scsi_t scsi; - - scsi = disk->data; - - if (scsi->devtype == grub_scsi_devtype_cdrom) - return grub_error (GRUB_ERR_IO, N_("cannot write to CD-ROM")); - - grub_err_t err; - /* Depending on the type, select a read function. */ - switch (scsi->devtype) - { - case grub_scsi_devtype_direct: - if (sector >> 32) - err = grub_scsi_write16 (disk, sector, size, buf); - else - err = grub_scsi_write10 (disk, sector, size, buf); - if (err) - return err; - break; - } - - return GRUB_ERR_NONE; -} - - -static struct grub_disk_dev grub_scsi_dev = - { - .name = "scsi", - .id = GRUB_DISK_DEVICE_SCSI_ID, - .disk_iterate = grub_scsi_iterate, - .disk_open = grub_scsi_open, - .disk_close = grub_scsi_close, - .disk_read = grub_scsi_read, - .disk_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/uboot/ubootdisk.c b/grub-core/disk/uboot/ubootdisk.c deleted file mode 100644 index 0e918d4d1..000000000 --- a/grub-core/disk/uboot/ubootdisk.c +++ /dev/null @@ -1,305 +0,0 @@ -/* ubootdisk.c - disk subsystem support for U-Boot platforms */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct ubootdisk_data *hd_devices; -static int hd_num; -static int hd_max; - -/* - * grub_ubootdisk_register(): - * Called for each disk device enumerated as part of U-Boot initialization - * code. - */ -grub_err_t -grub_ubootdisk_register (struct device_info *newdev) -{ - struct ubootdisk_data *d; - -#define STOR_TYPE(x) ((x) & 0x0ff0) - switch (STOR_TYPE (newdev->type)) - { - case DT_STOR_IDE: - case DT_STOR_SATA: - case DT_STOR_SCSI: - case DT_STOR_MMC: - case DT_STOR_USB: - /* hd */ - if (hd_num == hd_max) - { - int new_num; - new_num = (hd_max ? hd_max * 2 : 1); - d = grub_realloc(hd_devices, - sizeof (struct ubootdisk_data) * new_num); - if (!d) - return grub_errno; - hd_devices = d; - hd_max = new_num; - } - - d = &hd_devices[hd_num]; - hd_num++; - break; - default: - return GRUB_ERR_BAD_DEVICE; - break; - } - - d->dev = newdev; - d->cookie = newdev->cookie; - d->opencount = 0; - - return 0; -} - -/* - * uboot_disk_iterate(): - * Iterator over enumerated disk devices. - */ -static int -uboot_disk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - char buf[16]; - int count; - - switch (pull) - { - case GRUB_DISK_PULL_NONE: - /* "hd" - built-in mass-storage */ - for (count = 0 ; count < hd_num; count++) - { - grub_snprintf (buf, sizeof (buf) - 1, "hd%d", count); - grub_dprintf ("ubootdisk", "iterating %s\n", buf); - if (hook (buf, hook_data)) - return 1; - } - break; - default: - return 0; - } - - return 0; -} - -/* Helper function for uboot_disk_open. */ -static struct ubootdisk_data * -get_hd_device (int num) -{ - if (num < hd_num) - return &hd_devices[num]; - - return NULL; -} - -/* - * uboot_disk_open(): - * Opens a disk device already enumerated. - */ -static grub_err_t -uboot_disk_open (const char *name, struct grub_disk *disk) -{ - struct ubootdisk_data *d; - struct device_info *devinfo; - int num; - int retval; - - grub_dprintf ("ubootdisk", "Opening '%s'\n", name); - - num = grub_strtoul (name + 2, 0, 10); - if (grub_errno != GRUB_ERR_NONE) - { - grub_dprintf ("ubootdisk", "Opening '%s' failed, invalid number\n", - name); - goto fail; - } - - if (name[1] != 'd') - { - grub_dprintf ("ubootdisk", "Opening '%s' failed, invalid name\n", name); - goto fail; - } - - switch (name[0]) - { - case 'h': - d = get_hd_device (num); - break; - default: - goto fail; - } - - if (!d) - goto fail; - - /* - * Subsystems may call open on the same device recursively - but U-Boot - * does not deal with this. So simply keep track of number of calls and - * return success if already open. - */ - if (d->opencount > 0) - { - grub_dprintf ("ubootdisk", "(%s) already open\n", disk->name); - d->opencount++; - retval = 0; - } - else - { - retval = grub_uboot_dev_open (d->dev); - if (retval != 0) - goto fail; - d->opencount = 1; - } - - grub_dprintf ("ubootdisk", "cookie: 0x%08x\n", (grub_addr_t) d->cookie); - disk->id = (grub_addr_t) d->cookie; - - devinfo = d->dev; - - d->block_size = devinfo->di_stor.block_size; - if (d->block_size == 0) - return grub_error (GRUB_ERR_IO, "no block size"); - - disk->log_sector_size = grub_log2ull (d->block_size); - - grub_dprintf ("ubootdisk", "(%s) blocksize=%d, log_sector_size=%d\n", - disk->name, d->block_size, disk->log_sector_size); - - if (devinfo->di_stor.block_count) - disk->total_sectors = devinfo->di_stor.block_count; - else - disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN; - - disk->data = d; - - return GRUB_ERR_NONE; - -fail: - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such device"); -} - -static void -uboot_disk_close (struct grub_disk *disk) -{ - struct ubootdisk_data *d; - int retval; - - d = disk->data; - - /* - * In mirror of open function, keep track of number of calls to close and - * send on to U-Boot only when opencount would decrease to 0. - */ - if (d->opencount > 1) - { - grub_dprintf ("ubootdisk", "Closed (%s)\n", disk->name); - - d->opencount--; - } - else if (d->opencount == 1) - { - retval = grub_uboot_dev_close (d->dev); - d->opencount--; - grub_dprintf ("ubootdisk", "closed %s (%d)\n", disk->name, retval); - } - else - { - grub_dprintf ("ubootdisk", "device %s not open!\n", disk->name); - } -} - -/* - * uboot_disk_read(): - * Called from within disk subsystem to read a sequence of blocks into the - * disk cache. Maps directly on top of U-Boot API, only wrap in some error - * handling. - */ -static grub_err_t -uboot_disk_read (struct grub_disk *disk, - grub_disk_addr_t offset, grub_size_t numblocks, char *buf) -{ - struct ubootdisk_data *d; - grub_size_t real_size; - int retval; - - d = disk->data; - - retval = grub_uboot_dev_read (d->dev, buf, numblocks, offset, &real_size); - grub_dprintf ("ubootdisk", - "retval=%d, numblocks=%d, real_size=%llu, sector=%llu\n", - retval, numblocks, (grub_uint64_t) real_size, - (grub_uint64_t) offset); - if (retval != 0) - return grub_error (GRUB_ERR_IO, "U-Boot disk read error"); - - return GRUB_ERR_NONE; -} - -static grub_err_t -uboot_disk_write (struct grub_disk *disk, - grub_disk_addr_t offset, grub_size_t numblocks, const char *buf) -{ - struct ubootdisk_data *d; - int retval; - - d = disk->data; - - retval = grub_uboot_dev_write (d->dev, buf, numblocks, offset); - grub_dprintf ("ubootdisk", - "retval=%d, numblocks=%d, sector=%llu\n", - retval, numblocks, (grub_uint64_t) offset); - - if (retval != 0) - return grub_error (GRUB_ERR_IO, "U-Boot disk write error"); - - return GRUB_ERR_NONE; -} - -static struct grub_disk_dev grub_ubootdisk_dev = { - .name = "ubootdisk", - .id = GRUB_DISK_DEVICE_UBOOTDISK_ID, - .disk_iterate = uboot_disk_iterate, - .disk_open = uboot_disk_open, - .disk_close = uboot_disk_close, - .disk_read = uboot_disk_read, - .disk_write = uboot_disk_write, - .next = 0 -}; - -void -grub_ubootdisk_init (void) -{ - grub_disk_dev_register (&grub_ubootdisk_dev); -} - -void -grub_ubootdisk_fini (void) -{ - grub_disk_dev_unregister (&grub_ubootdisk_dev); -} diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c deleted file mode 100644 index b81e3ad9d..000000000 --- a/grub-core/disk/usbms.c +++ /dev/null @@ -1,660 +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 . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define GRUB_USBMS_DIRECTION_BIT 7 - -/* Length of CBI command should be always 12 bytes */ -#define GRUB_USBMS_CBI_CMD_SIZE 12 -/* CBI class-specific USB request ADSC - it sends CBI (scsi) command to - * device in DATA stage */ -#define GRUB_USBMS_CBI_ADSC_REQ 0x00 - -/* 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]; -} GRUB_PACKED; - -struct grub_usbms_csw -{ - grub_uint32_t signature; - grub_uint32_t tag; - grub_uint32_t residue; - grub_uint8_t status; -} GRUB_PACKED; - -struct grub_usbms_dev -{ - struct grub_usb_device *dev; - - int luns; - - int config; - int interface; - struct grub_usb_desc_endp *in; - struct grub_usb_desc_endp *out; - - int subclass; - int protocol; - struct grub_usb_desc_endp *intrpt; -}; -typedef struct grub_usbms_dev *grub_usbms_dev_t; - -/* FIXME: remove limit. */ -#define MAX_USBMS_DEVICES 128 -static grub_usbms_dev_t grub_usbms_devices[MAX_USBMS_DEVICES]; -static int first_available_slot = 0; - -static grub_usb_err_t -grub_usbms_cbi_cmd (grub_usb_device_t dev, int interface, - grub_uint8_t *cbicb) -{ - return grub_usb_control_msg (dev, - GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT, - GRUB_USBMS_CBI_ADSC_REQ, 0, interface, - GRUB_USBMS_CBI_CMD_SIZE, (char*)cbicb); -} - -static grub_usb_err_t -grub_usbms_cbi_reset (grub_usb_device_t dev, int interface) -{ - /* Prepare array with Command Block Reset (=CBR) */ - /* CBI specific communication reset command should be send to device - * via CBI USB class specific request ADCS */ - struct grub_cbi_reset - { - grub_uint8_t opcode; /* 0x1d = SEND DIAGNOSTIC */ - grub_uint8_t lun; /* 7-5 LUN, 4-0 flags - for CBR always = 0x04 */ - grub_uint8_t pad[10]; - /* XXX: There is collision between CBI and UFI specifications: - * CBI says 0xff, UFI says 0x00 ... probably it does - * not matter ... (?) */ - } cbicb = { 0x1d, 0x04, - { 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff } - }; - - return grub_usbms_cbi_cmd (dev, interface, (grub_uint8_t *)&cbicb); -} - -static grub_usb_err_t -grub_usbms_bo_reset (grub_usb_device_t dev, int interface) -{ - return grub_usb_control_msg (dev, 0x21, 255, 0, interface, 0, 0); -} - -static grub_usb_err_t -grub_usbms_reset (grub_usbms_dev_t dev) -{ - if (dev->protocol == GRUB_USBMS_PROTOCOL_BULK) - return grub_usbms_bo_reset (dev->dev, dev->interface); - else - return grub_usbms_cbi_reset (dev->dev, dev->interface); -} - -static void -grub_usbms_detach (grub_usb_device_t usbdev, int config, int interface) -{ - unsigned i; - for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++) - if (grub_usbms_devices[i] && grub_usbms_devices[i]->dev == usbdev - && grub_usbms_devices[i]->interface == interface - && grub_usbms_devices[i]->config == config) - { - grub_free (grub_usbms_devices[i]); - grub_usbms_devices[i] = 0; - } -} - -static int -grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno) -{ - struct grub_usb_desc_if *interf - = usbdev->config[configno].interf[interfno].descif; - int j; - grub_uint8_t luns = 0; - unsigned curnum; - grub_usb_err_t err = GRUB_USB_ERR_NONE; - - grub_boot_time ("Attaching USB mass storage"); - - if (first_available_slot == ARRAY_SIZE (grub_usbms_devices)) - return 0; - - curnum = first_available_slot; - first_available_slot++; - - interf = usbdev->config[configno].interf[interfno].descif; - - if ((interf->subclass != GRUB_USBMS_SUBCLASS_BULK - /* Experimental support of RBC, MMC-2, UFI, SFF-8070i devices */ - && interf->subclass != GRUB_USBMS_SUBCLASS_RBC - && interf->subclass != GRUB_USBMS_SUBCLASS_MMC2 - && interf->subclass != GRUB_USBMS_SUBCLASS_UFI - && interf->subclass != GRUB_USBMS_SUBCLASS_SFF8070 ) - || (interf->protocol != GRUB_USBMS_PROTOCOL_BULK - && interf->protocol != GRUB_USBMS_PROTOCOL_CBI - && interf->protocol != GRUB_USBMS_PROTOCOL_CB)) - return 0; - - grub_usbms_devices[curnum] = grub_zalloc (sizeof (struct grub_usbms_dev)); - if (! grub_usbms_devices[curnum]) - return 0; - - grub_usbms_devices[curnum]->dev = usbdev; - grub_usbms_devices[curnum]->interface = interfno; - grub_usbms_devices[curnum]->subclass = interf->subclass; - grub_usbms_devices[curnum]->protocol = interf->protocol; - - grub_dprintf ("usbms", "alive\n"); - - /* 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[interfno].descendp[j]; - - if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2) - /* Bulk IN endpoint. */ - grub_usbms_devices[curnum]->in = endp; - else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2) - /* Bulk OUT endpoint. */ - grub_usbms_devices[curnum]->out = endp; - else if ((endp->endp_addr & 128) && (endp->attrib & 3) == 3) - /* Interrupt (IN) endpoint. */ - grub_usbms_devices[curnum]->intrpt = endp; - } - - if (!grub_usbms_devices[curnum]->in || !grub_usbms_devices[curnum]->out - || ((grub_usbms_devices[curnum]->protocol == GRUB_USBMS_PROTOCOL_CBI) - && !grub_usbms_devices[curnum]->intrpt)) - { - grub_free (grub_usbms_devices[curnum]); - grub_usbms_devices[curnum] = 0; - return 0; - } - - grub_dprintf ("usbms", "alive\n"); - - /* XXX: Activate the first configuration. */ - grub_usb_set_configuration (usbdev, 1); - - /* Query the amount of LUNs. */ - if (grub_usbms_devices[curnum]->protocol == GRUB_USBMS_PROTOCOL_BULK) - { /* Only Bulk only devices support Get Max LUN command */ - err = grub_usb_control_msg (usbdev, 0xA1, 254, 0, interfno, 1, (char *) &luns); - - if (err) - { - /* In case of a stall, clear the stall. */ - if (err == GRUB_USB_ERR_STALL) - { - grub_usb_clear_halt (usbdev, grub_usbms_devices[curnum]->in->endp_addr); - grub_usb_clear_halt (usbdev, grub_usbms_devices[curnum]->out->endp_addr); - } - /* Just set the amount of LUNs to one. */ - grub_errno = GRUB_ERR_NONE; - grub_usbms_devices[curnum]->luns = 1; - } - else - /* luns = 0 means one LUN with ID 0 present ! */ - /* We get from device not number of LUNs but highest - * LUN number. LUNs are numbered from 0, - * i.e. number of LUNs is luns+1 ! */ - grub_usbms_devices[curnum]->luns = luns + 1; - } - else - /* XXX: Does CBI devices support multiple LUNs ? - * I.e., should we detect number of device's LUNs ? (How?) */ - grub_usbms_devices[curnum]->luns = 1; - - grub_dprintf ("usbms", "alive\n"); - - usbdev->config[configno].interf[interfno].detach_hook = grub_usbms_detach; - - grub_boot_time ("Attached USB mass storage"); - -#if 0 /* All this part should be probably deleted. - * This make trouble on some devices if they are not in - * Phase Error state - and there they should be not in such state... - * Bulk only mass storage reset procedure should be used only - * on place and in time when it is really necessary. */ - /* Reset recovery procedure */ - /* Bulk-Only Mass Storage Reset, after the reset commands - will be accepted. */ - grub_usbms_reset (usbdev, i); - grub_usb_clear_halt (usbdev, usbms->in->endp_addr); - grub_usb_clear_halt (usbdev, usbms->out->endp_addr); -#endif - - return 1; -} - - - -static int -grub_usbms_iterate (grub_scsi_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - unsigned i; - - if (pull != GRUB_DISK_PULL_NONE) - return 0; - - grub_usb_poll_devices (1); - - for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++) - if (grub_usbms_devices[i]) - { - if (hook (GRUB_SCSI_SUBSYSTEM_USBMS, i, grub_usbms_devices[i]->luns, - hook_data)) - return 1; - } - - return 0; -} - -static grub_err_t -grub_usbms_transfer_bo (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; - grub_usb_err_t errCSW = GRUB_USB_ERR_NONE; - int retrycnt = 3 + 1; - - tag++; - - 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_compile_time (0x43425355); - cbw.tag = tag; - cbw.transfer_length = grub_cpu_to_le32 (size); - cbw.flags = (!read_write) << GRUB_USBMS_DIRECTION_BIT; - cbw.lun = scsi->lun; /* In USB MS CBW are LUN bits on another place than in SCSI CDB, both should be set correctly. */ - cbw.length = cmdsize; - grub_memcpy (cbw.cbwcb, cmd, cmdsize); - - /* Debug print of CBW content. */ - grub_dprintf ("usb", "CBW: sign=0x%08x tag=0x%08x len=0x%08x\n", - cbw.signature, cbw.tag, cbw.transfer_length); - grub_dprintf ("usb", "CBW: flags=0x%02x lun=0x%02x CB_len=0x%02x\n", - cbw.flags, cbw.lun, cbw.length); - grub_dprintf ("usb", "CBW: cmd:\n %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - cbw.cbwcb[ 0], cbw.cbwcb[ 1], cbw.cbwcb[ 2], cbw.cbwcb[ 3], - cbw.cbwcb[ 4], cbw.cbwcb[ 5], cbw.cbwcb[ 6], cbw.cbwcb[ 7], - cbw.cbwcb[ 8], cbw.cbwcb[ 9], cbw.cbwcb[10], cbw.cbwcb[11], - cbw.cbwcb[12], cbw.cbwcb[13], cbw.cbwcb[14], cbw.cbwcb[15]); - - /* Write the request. - * XXX: Error recovery is maybe still not fully correct. */ - err = grub_usb_bulk_write (dev->dev, dev->out, - sizeof (cbw), (char *) &cbw); - if (err) - { - if (err == GRUB_USB_ERR_STALL) - { - grub_usb_clear_halt (dev->dev, dev->out->endp_addr); - goto CheckCSW; - } - goto retry; - } - - /* Read/write the data, (maybe) according to specification. */ - if (size && (read_write == 0)) - { - err = grub_usb_bulk_read (dev->dev, dev->in, 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 CheckCSW; - } - /* Debug print of received data. */ - grub_dprintf ("usb", "buf:\n"); - if (size <= 64) - { - unsigned i; - for (i = 0; i < size; i++) - grub_dprintf ("usb", "0x%02x: 0x%02x\n", i, buf[i]); - } - else - grub_dprintf ("usb", "Too much data for debug print...\n"); - } - else if (size) - { - err = grub_usb_bulk_write (dev->dev, dev->out, size, buf); - grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL); - grub_dprintf ("usb", "First 16 bytes of sent data:\n %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - buf[ 0], buf[ 1], buf[ 2], buf[ 3], - buf[ 4], buf[ 5], buf[ 6], buf[ 7], - buf[ 8], buf[ 9], buf[10], buf[11], - buf[12], buf[13], buf[14], buf[15]); - if (err) - { - if (err == GRUB_USB_ERR_STALL) - grub_usb_clear_halt (dev->dev, dev->out->endp_addr); - goto CheckCSW; - } - /* Debug print of sent data. */ - if (size <= 256) - { - unsigned i; - for (i=0; idev, dev->in, - sizeof (status), (char *) &status); - if (errCSW) - { - grub_usb_clear_halt (dev->dev, dev->in->endp_addr); - errCSW = grub_usb_bulk_read (dev->dev, dev->in, - sizeof (status), (char *) &status); - if (errCSW) - { /* Bulk-only reset device. */ - grub_dprintf ("usb", "Bulk-only reset device - errCSW\n"); - grub_usbms_reset (dev); - grub_usb_clear_halt (dev->dev, dev->in->endp_addr); - grub_usb_clear_halt (dev->dev, dev->out->endp_addr); - goto retry; - } - } - - /* Debug print of CSW content. */ - grub_dprintf ("usb", "CSW: sign=0x%08x tag=0x%08x resid=0x%08x\n", - status.signature, status.tag, status.residue); - grub_dprintf ("usb", "CSW: status=0x%02x\n", status.status); - - /* If phase error or not valid signature, do bulk-only reset device. */ - if ((status.status == 2) || - (status.signature != grub_cpu_to_le32_compile_time(0x53425355))) - { /* Bulk-only reset device. */ - grub_dprintf ("usb", "Bulk-only reset device - bad status\n"); - grub_usbms_reset (dev); - grub_usb_clear_halt (dev->dev, dev->in->endp_addr); - grub_usb_clear_halt (dev->dev, dev->out->endp_addr); - - goto retry; - } - - /* If "command failed" status or data transfer failed -> error */ - if ((status.status || err) && !read_write) - return grub_error (GRUB_ERR_READ_ERROR, - "error communication with USB Mass Storage device"); - else if ((status.status || err) && read_write) - return grub_error (GRUB_ERR_WRITE_ERROR, - "error communication with USB Mass Storage device"); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_usbms_transfer_cbi (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, - grub_size_t size, char *buf, int read_write) -{ - grub_usbms_dev_t dev = (grub_usbms_dev_t) scsi->data; - int retrycnt = 3 + 1; - grub_usb_err_t err = GRUB_USB_ERR_NONE; - grub_uint8_t cbicb[GRUB_USBMS_CBI_CMD_SIZE]; - grub_uint16_t status; - - retry: - retrycnt--; - if (retrycnt == 0) - return grub_error (GRUB_ERR_IO, "USB Mass Storage CBI failed"); - - /* Setup the request. */ - grub_memset (cbicb, 0, sizeof (cbicb)); - grub_memcpy (cbicb, cmd, - cmdsize >= GRUB_USBMS_CBI_CMD_SIZE - ? GRUB_USBMS_CBI_CMD_SIZE - : cmdsize); - - /* Debug print of CBIcb content. */ - grub_dprintf ("usb", "cbicb:\n %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - cbicb[ 0], cbicb[ 1], cbicb[ 2], cbicb[ 3], - cbicb[ 4], cbicb[ 5], cbicb[ 6], cbicb[ 7], - cbicb[ 8], cbicb[ 9], cbicb[10], cbicb[11]); - - /* Write the request. - * XXX: Error recovery is maybe not correct. */ - err = grub_usbms_cbi_cmd (dev->dev, dev->interface, cbicb); - if (err) - { - grub_dprintf ("usb", "CBI cmdcb setup err=%d\n", err); - if (err == GRUB_USB_ERR_STALL) - { - /* Stall in this place probably means bad or unsupported - * command, so we will not try it again. */ - return grub_error (GRUB_ERR_IO, "USB Mass Storage CBI request failed"); - } - else if (dev->protocol == GRUB_USBMS_PROTOCOL_CBI) - { - /* Try to get status from interrupt pipe */ - err = grub_usb_bulk_read (dev->dev, dev->intrpt, - 2, (char*)&status); - grub_dprintf ("usb", "CBI cmdcb setup status: err=%d, status=0x%x\n", err, status); - } - /* Any other error could be transport problem, try it again */ - goto retry; - } - - /* Read/write the data, (maybe) according to specification. */ - if (size && (read_write == 0)) - { - err = grub_usb_bulk_read (dev->dev, dev->in, size, buf); - grub_dprintf ("usb", "read: %d\n", err); - if (err) - { - if (err == GRUB_USB_ERR_STALL) - grub_usb_clear_halt (dev->dev, dev->in->endp_addr); - goto retry; - } - } - else if (size) - { - err = grub_usb_bulk_write (dev->dev, dev->out, size, buf); - grub_dprintf ("usb", "write: %d\n", err); - if (err) - { - if (err == GRUB_USB_ERR_STALL) - grub_usb_clear_halt (dev->dev, dev->out->endp_addr); - goto retry; - } - } - - /* XXX: It is not clear to me yet, how to check status of CBI - * data transfer on devices without interrupt pipe. - * AFAIK there is probably no status phase to indicate possibly - * bad transported data. - * Maybe we should do check on higher level, i.e. issue RequestSense - * command (we do it already in scsi.c) and check returned values - * (we do not it yet) - ? */ - if (dev->protocol == GRUB_USBMS_PROTOCOL_CBI) - { /* Check status in interrupt pipe */ - err = grub_usb_bulk_read (dev->dev, dev->intrpt, - 2, (char*)&status); - grub_dprintf ("usb", "read status: %d\n", err); - if (err) - { - /* Try to reset device, because it is probably not standard - * situation */ - grub_usbms_reset (dev); - grub_usb_clear_halt (dev->dev, dev->in->endp_addr); - grub_usb_clear_halt (dev->dev, dev->out->endp_addr); - grub_usb_clear_halt (dev->dev, dev->intrpt->endp_addr); - goto retry; - } - if (dev->subclass == GRUB_USBMS_SUBCLASS_UFI) - { - /* These devices should return bASC and bASCQ */ - if (status != 0) - /* Some error, currently we don't care what it is... */ - goto retry; - } - else if (dev->subclass == GRUB_USBMS_SUBCLASS_RBC) - { - /* XXX: I don't understand what returns RBC subclass devices, - * so I don't check it - maybe somebody helps ? */ - } - else - { - /* Any other device should return bType = 0 and some bValue */ - if (status & 0xff) - return grub_error (GRUB_ERR_IO, "USB Mass Storage CBI status type != 0"); - status = (status & 0x0300) >> 8; - switch (status) - { - case 0 : /* OK */ - break; - case 1 : /* Fail */ - goto retry; - break; - case 2 : /* Phase error */ - case 3 : /* Persistent Failure */ - grub_dprintf ("usb", "CBI reset device - phase error or persistent failure\n"); - grub_usbms_reset (dev); - grub_usb_clear_halt (dev->dev, dev->in->endp_addr); - grub_usb_clear_halt (dev->dev, dev->out->endp_addr); - grub_usb_clear_halt (dev->dev, dev->intrpt->endp_addr); - goto retry; - break; - } - } - } - - if (err) - return grub_error (GRUB_ERR_IO, "USB error %d", err); - - return GRUB_ERR_NONE; -} - - -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) -{ - grub_usbms_dev_t dev = (grub_usbms_dev_t) scsi->data; - - if (dev->protocol == GRUB_USBMS_PROTOCOL_BULK) - return grub_usbms_transfer_bo (scsi, cmdsize, cmd, size, buf, - read_write); - else - return grub_usbms_transfer_cbi (scsi, cmdsize, cmd, size, buf, - read_write); -} - -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, const char *buf) -{ - return grub_usbms_transfer (scsi, cmdsize, cmd, size, (char *) buf, 1); -} - -static grub_err_t -grub_usbms_open (int id, int devnum, struct grub_scsi *scsi) -{ - if (id != GRUB_SCSI_SUBSYSTEM_USBMS) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "not USB Mass Storage device"); - - if (!grub_usbms_devices[devnum]) - grub_usb_poll_devices (1); - - if (!grub_usbms_devices[devnum]) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "unknown USB Mass Storage device"); - - scsi->data = grub_usbms_devices[devnum]; - scsi->luns = grub_usbms_devices[devnum]->luns; - - return GRUB_ERR_NONE; -} - -static struct grub_scsi_dev grub_usbms_dev = - { - .iterate = grub_usbms_iterate, - .open = grub_usbms_open, - .read = grub_usbms_read, - .write = grub_usbms_write - }; - -static struct grub_usb_attach_desc attach_hook = -{ - .class = GRUB_USB_CLASS_MASS_STORAGE, - .hook = grub_usbms_attach -}; - -GRUB_MOD_INIT(usbms) -{ - grub_usb_register_attach_hook_class (&attach_hook); - grub_scsi_dev_register (&grub_usbms_dev); -} - -GRUB_MOD_FINI(usbms) -{ - unsigned i; - for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++) - { - grub_usbms_devices[i]->dev->config[grub_usbms_devices[i]->config] - .interf[grub_usbms_devices[i]->interface].detach_hook = 0; - grub_usbms_devices[i]->dev->config[grub_usbms_devices[i]->config] - .interf[grub_usbms_devices[i]->interface].attached = 0; - } - grub_usb_unregister_attach_hook_class (&attach_hook); - grub_scsi_dev_unregister (&grub_usbms_dev); -} diff --git a/grub-core/disk/xen/xendisk.c b/grub-core/disk/xen/xendisk.c deleted file mode 100644 index 496f1ea7b..000000000 --- a/grub-core/disk/xen/xendisk.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct virtdisk -{ - int handle; - char *fullname; - char *backend_dir; - char *frontend_dir; - struct blkif_sring *shared_page; - struct blkif_front_ring ring; - grub_xen_grant_t grant; - grub_xen_evtchn_t evtchn; - void *dma_page; - grub_xen_grant_t dma_grant; - struct virtdisk *compat_next; -}; - -#define xen_wmb() mb() -#define xen_mb() mb() - -static struct virtdisk *virtdisks; -static grub_size_t vdiskcnt; -struct virtdisk *compat_head; - -static int -grub_virtdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - grub_size_t i; - - if (pull != GRUB_DISK_PULL_NONE) - return 0; - - for (i = 0; i < vdiskcnt; i++) - if (hook (virtdisks[i].fullname, hook_data)) - return 1; - return 0; -} - -static grub_err_t -grub_virtdisk_open (const char *name, grub_disk_t disk) -{ - int i; - grub_uint32_t secsize; - char fdir[200]; - char *buf; - int num = -1; - struct virtdisk *vd; - - /* For compatibility with pv-grub legacy menu.lst accept hdX as disk name */ - if (name[0] == 'h' && name[1] == 'd' && name[2]) - { - num = grub_strtoul (name + 2, 0, 10); - if (grub_errno) - { - grub_errno = 0; - num = -1; - } - } - for (i = 0, vd = compat_head; vd; vd = vd->compat_next, i++) - if (i == num || grub_strcmp (name, vd->fullname) == 0) - break; - if (!vd) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a virtdisk"); - disk->data = vd; - disk->id = vd - virtdisks; - - grub_snprintf (fdir, sizeof (fdir), "%s/sectors", vd->backend_dir); - buf = grub_xenstore_get_file (fdir, NULL); - if (!buf) - return grub_errno; - disk->total_sectors = grub_strtoull (buf, 0, 10); - if (grub_errno) - return grub_errno; - - grub_snprintf (fdir, sizeof (fdir), "%s/sector-size", vd->backend_dir); - buf = grub_xenstore_get_file (fdir, NULL); - if (!buf) - return grub_errno; - secsize = grub_strtoull (buf, 0, 10); - if (grub_errno) - return grub_errno; - - if ((secsize & (secsize - 1)) || !secsize || secsize < 512 - || secsize > GRUB_XEN_PAGE_SIZE) - return grub_error (GRUB_ERR_IO, "unsupported sector size %d", secsize); - - disk->log_sector_size = grub_log2ull (secsize); - disk->total_sectors >>= disk->log_sector_size - 9; - - return GRUB_ERR_NONE; -} - -static void -grub_virtdisk_close (grub_disk_t disk __attribute__ ((unused))) -{ -} - -static grub_err_t -grub_virtdisk_read (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, char *buf) -{ - struct virtdisk *data = disk->data; - - while (size) - { - grub_size_t cur; - struct blkif_request *req; - struct blkif_response *resp; - int sta = 0; - struct evtchn_send send; - cur = size; - if (cur > (unsigned) (GRUB_XEN_PAGE_SIZE >> disk->log_sector_size)) - cur = GRUB_XEN_PAGE_SIZE >> disk->log_sector_size; - while (RING_FULL (&data->ring)) - grub_xen_sched_op (SCHEDOP_yield, 0); - req = RING_GET_REQUEST (&data->ring, data->ring.req_prod_pvt); - req->operation = BLKIF_OP_READ; - req->nr_segments = 1; - req->handle = data->handle; - req->id = 0; - req->sector_number = sector << (disk->log_sector_size - 9); - req->seg[0].gref = data->dma_grant; - req->seg[0].first_sect = 0; - req->seg[0].last_sect = (cur << (disk->log_sector_size - 9)) - 1; - data->ring.req_prod_pvt++; - RING_PUSH_REQUESTS (&data->ring); - mb (); - send.port = data->evtchn; - grub_xen_event_channel_op (EVTCHNOP_send, &send); - - while (!RING_HAS_UNCONSUMED_RESPONSES (&data->ring)) - { - grub_xen_sched_op (SCHEDOP_yield, 0); - mb (); - } - while (1) - { - int wtd; - RING_FINAL_CHECK_FOR_RESPONSES (&data->ring, wtd); - if (!wtd) - break; - resp = RING_GET_RESPONSE (&data->ring, data->ring.rsp_cons); - data->ring.rsp_cons++; - if (resp->status) - sta = resp->status; - } - if (sta) - return grub_error (GRUB_ERR_IO, "read failed"); - grub_memcpy (buf, data->dma_page, cur << disk->log_sector_size); - size -= cur; - sector += cur; - buf += cur << disk->log_sector_size; - } - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_virtdisk_write (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, const char *buf) -{ - struct virtdisk *data = disk->data; - - while (size) - { - grub_size_t cur; - struct blkif_request *req; - struct blkif_response *resp; - int sta = 0; - struct evtchn_send send; - cur = size; - if (cur > (unsigned) (GRUB_XEN_PAGE_SIZE >> disk->log_sector_size)) - cur = GRUB_XEN_PAGE_SIZE >> disk->log_sector_size; - - grub_memcpy (data->dma_page, buf, cur << disk->log_sector_size); - - while (RING_FULL (&data->ring)) - grub_xen_sched_op (SCHEDOP_yield, 0); - req = RING_GET_REQUEST (&data->ring, data->ring.req_prod_pvt); - req->operation = BLKIF_OP_WRITE; - req->nr_segments = 1; - req->handle = data->handle; - req->id = 0; - req->sector_number = sector << (disk->log_sector_size - 9); - req->seg[0].gref = data->dma_grant; - req->seg[0].first_sect = 0; - req->seg[0].last_sect = (cur << (disk->log_sector_size - 9)) - 1; - data->ring.req_prod_pvt++; - RING_PUSH_REQUESTS (&data->ring); - mb (); - send.port = data->evtchn; - grub_xen_event_channel_op (EVTCHNOP_send, &send); - - while (!RING_HAS_UNCONSUMED_RESPONSES (&data->ring)) - { - grub_xen_sched_op (SCHEDOP_yield, 0); - mb (); - } - while (1) - { - int wtd; - RING_FINAL_CHECK_FOR_RESPONSES (&data->ring, wtd); - if (!wtd) - break; - resp = RING_GET_RESPONSE (&data->ring, data->ring.rsp_cons); - data->ring.rsp_cons++; - if (resp->status) - sta = resp->status; - } - if (sta) - return grub_error (GRUB_ERR_IO, "write failed"); - size -= cur; - sector += cur; - buf += cur << disk->log_sector_size; - } - return GRUB_ERR_NONE; -} - -static struct grub_disk_dev grub_virtdisk_dev = { - .name = "xen", - .id = GRUB_DISK_DEVICE_XEN, - .disk_iterate = grub_virtdisk_iterate, - .disk_open = grub_virtdisk_open, - .disk_close = grub_virtdisk_close, - .disk_read = grub_virtdisk_read, - .disk_write = grub_virtdisk_write, - .next = 0 -}; - -static int -count (const char *dir __attribute__ ((unused)), void *data) -{ - grub_size_t *ctr = data; - (*ctr)++; - - return 0; -} - -static int -fill (const char *dir, void *data) -{ - grub_size_t *ctr = data; - domid_t dom; - /* "dir" is just a number, at most 19 characters. */ - char fdir[200]; - char num[20]; - grub_err_t err; - void *buf; - struct evtchn_alloc_unbound alloc_unbound; - struct virtdisk **prev = &compat_head, *vd = compat_head; - - /* Shouldn't happen unles some hotplug happened. */ - if (vdiskcnt >= *ctr) - return 1; - virtdisks[vdiskcnt].handle = grub_strtoul (dir, 0, 10); - if (grub_errno) - { - grub_errno = 0; - return 0; - } - virtdisks[vdiskcnt].fullname = 0; - virtdisks[vdiskcnt].backend_dir = 0; - - grub_snprintf (fdir, sizeof (fdir), "device/vbd/%s/backend", dir); - virtdisks[vdiskcnt].backend_dir = grub_xenstore_get_file (fdir, NULL); - if (!virtdisks[vdiskcnt].backend_dir) - goto out_fail_1; - - grub_snprintf (fdir, sizeof (fdir), "%s/dev", - virtdisks[vdiskcnt].backend_dir); - buf = grub_xenstore_get_file (fdir, NULL); - if (!buf) - { - grub_errno = 0; - virtdisks[vdiskcnt].fullname = grub_xasprintf ("xenid/%s", dir); - } - else - { - virtdisks[vdiskcnt].fullname = grub_xasprintf ("xen/%s", (char *) buf); - grub_free (buf); - } - if (!virtdisks[vdiskcnt].fullname) - goto out_fail_1; - - grub_snprintf (fdir, sizeof (fdir), "device/vbd/%s/backend-id", dir); - buf = grub_xenstore_get_file (fdir, NULL); - if (!buf) - goto out_fail_1; - - dom = grub_strtoul (buf, 0, 10); - grub_free (buf); - if (grub_errno) - goto out_fail_1; - - virtdisks[vdiskcnt].shared_page = - grub_xen_alloc_shared_page (dom, &virtdisks[vdiskcnt].grant); - if (!virtdisks[vdiskcnt].shared_page) - goto out_fail_1; - - virtdisks[vdiskcnt].dma_page = - grub_xen_alloc_shared_page (dom, &virtdisks[vdiskcnt].dma_grant); - if (!virtdisks[vdiskcnt].dma_page) - goto out_fail_2; - - alloc_unbound.dom = DOMID_SELF; - alloc_unbound.remote_dom = dom; - - grub_xen_event_channel_op (EVTCHNOP_alloc_unbound, &alloc_unbound); - virtdisks[vdiskcnt].evtchn = alloc_unbound.port; - - SHARED_RING_INIT (virtdisks[vdiskcnt].shared_page); - FRONT_RING_INIT (&virtdisks[vdiskcnt].ring, virtdisks[vdiskcnt].shared_page, - GRUB_XEN_PAGE_SIZE); - - grub_snprintf (fdir, sizeof (fdir), "device/vbd/%s/ring-ref", dir); - grub_snprintf (num, sizeof (num), "%u", virtdisks[vdiskcnt].grant); - err = grub_xenstore_write_file (fdir, num, grub_strlen (num)); - if (err) - goto out_fail_3; - - grub_snprintf (fdir, sizeof (fdir), "device/vbd/%s/event-channel", dir); - grub_snprintf (num, sizeof (num), "%u", virtdisks[vdiskcnt].evtchn); - err = grub_xenstore_write_file (fdir, num, grub_strlen (num)); - if (err) - goto out_fail_3; - - grub_snprintf (fdir, sizeof (fdir), "device/vbd/%s/protocol", dir); - err = grub_xenstore_write_file (fdir, XEN_IO_PROTO_ABI_NATIVE, - grub_strlen (XEN_IO_PROTO_ABI_NATIVE)); - if (err) - goto out_fail_3; - - struct gnttab_dump_table dt; - dt.dom = DOMID_SELF; - grub_xen_grant_table_op (GNTTABOP_dump_table, (void *) &dt, 1); - - grub_snprintf (fdir, sizeof (fdir), "device/vbd/%s/state", dir); - err = grub_xenstore_write_file (fdir, "3", 1); - if (err) - goto out_fail_3; - - while (1) - { - grub_snprintf (fdir, sizeof (fdir), "%s/state", - virtdisks[vdiskcnt].backend_dir); - buf = grub_xenstore_get_file (fdir, NULL); - if (!buf) - goto out_fail_3; - if (grub_strcmp (buf, "2") != 0) - break; - grub_free (buf); - grub_xen_sched_op (SCHEDOP_yield, 0); - } - grub_dprintf ("xen", "state=%s\n", (char *) buf); - grub_free (buf); - - grub_snprintf (fdir, sizeof (fdir), "device/vbd/%s", dir); - - virtdisks[vdiskcnt].frontend_dir = grub_strdup (fdir); - - /* For compatibility with pv-grub maintain linked list sorted by handle - value in increasing order. This allows mapping of (hdX) disk names - from legacy menu.lst */ - while (vd) - { - if (vd->handle > virtdisks[vdiskcnt].handle) - break; - prev = &vd->compat_next; - vd = vd->compat_next; - } - virtdisks[vdiskcnt].compat_next = vd; - *prev = &virtdisks[vdiskcnt]; - - vdiskcnt++; - return 0; - -out_fail_3: - grub_xen_free_shared_page (virtdisks[vdiskcnt].dma_page); -out_fail_2: - grub_xen_free_shared_page (virtdisks[vdiskcnt].shared_page); -out_fail_1: - grub_free (virtdisks[vdiskcnt].backend_dir); - grub_free (virtdisks[vdiskcnt].fullname); - - grub_errno = 0; - return 0; -} - -void -grub_xendisk_init (void) -{ - grub_size_t ctr = 0; - if (grub_xenstore_dir ("device/vbd", count, &ctr)) - grub_errno = 0; - - if (!ctr) - return; - - virtdisks = grub_calloc (ctr, sizeof (virtdisks[0])); - if (!virtdisks) - return; - if (grub_xenstore_dir ("device/vbd", fill, &ctr)) - grub_errno = 0; - - grub_disk_dev_register (&grub_virtdisk_dev); -} - -void -grub_xendisk_fini (void) -{ - char fdir[200]; - unsigned i; - - for (i = 0; i < vdiskcnt; i++) - { - char *buf; - struct evtchn_close close_op = {.port = virtdisks[i].evtchn }; - - grub_snprintf (fdir, sizeof (fdir), "%s/state", - virtdisks[i].frontend_dir); - grub_xenstore_write_file (fdir, "6", 1); - - while (1) - { - grub_snprintf (fdir, sizeof (fdir), "%s/state", - virtdisks[i].backend_dir); - buf = grub_xenstore_get_file (fdir, NULL); - grub_dprintf ("xen", "state=%s\n", (char *) buf); - - if (!buf || grub_strcmp (buf, "6") == 0) - break; - grub_free (buf); - grub_xen_sched_op (SCHEDOP_yield, 0); - } - grub_free (buf); - - grub_snprintf (fdir, sizeof (fdir), "%s/ring-ref", - virtdisks[i].frontend_dir); - grub_xenstore_write_file (fdir, NULL, 0); - - grub_snprintf (fdir, sizeof (fdir), "%s/event-channel", - virtdisks[i].frontend_dir); - grub_xenstore_write_file (fdir, NULL, 0); - - grub_xen_free_shared_page (virtdisks[i].dma_page); - grub_xen_free_shared_page (virtdisks[i].shared_page); - - grub_xen_event_channel_op (EVTCHNOP_close, &close_op); - - /* Prepare for handoff. */ - grub_snprintf (fdir, sizeof (fdir), "%s/state", - virtdisks[i].frontend_dir); - grub_xenstore_write_file (fdir, "1", 1); - } -} diff --git a/grub-core/font/font.c b/grub-core/font/font.c deleted file mode 100644 index 18de52562..000000000 --- a/grub-core/font/font.c +++ /dev/null @@ -1,1660 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#if HAVE_FONT_SOURCE -#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 - -/* 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; - -#if HAVE_FONT_SOURCE -static struct grub_font_glyph *ascii_font_glyph[0x80]; -#endif - -static struct grub_font_glyph * -ascii_glyph_lookup (grub_uint32_t code) -{ -#if HAVE_FONT_SOURCE - static int ascii_failback_initialized = 0; - - if (code >= 0x80) - return NULL; - - 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); - if (ascii_font_glyph[current] == NULL) - { - ascii_font_glyph[current] = unknown_glyph; - continue; - } - - 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; - ascii_font_glyph[current]->font = &null_font; - - grub_memcpy (ascii_font_glyph[current]->bitmap, - &ascii_bitmaps[current * ASCII_BITMAP_SIZE], - ASCII_BITMAP_SIZE); - } - - ascii_failback_initialized = 1; - } - - return ascii_font_glyph[code]; -#else - (void) code; - return NULL; -#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; - unknown_glyph->font = &null_font; - grub_memcpy (unknown_glyph->bitmap, - unknown_glyph_bitmap, sizeof (unknown_glyph_bitmap)); - - /* Initialize the null font. */ - font_init (&null_font); - /* FIXME: Fix this slightly improper cast. */ - null_font.name = (char *) ""; - 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) - { - /* Read error. */ - 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) - { - /* Read error. */ - 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_dprintf ("font", "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_calloc (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) - return 1; - - /* Init the BMP index array to 0xffff. */ - grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t)); - - -#if FONT_DEBUG >= 2 - grub_dprintf ("font", "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 && i < 0xffff) - 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_dprintf ("font", "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_size_t sz; - grub_ssize_t ret; - - if (grub_add (section->length, 1, &sz)) - return NULL; - - str = grub_malloc (sz); - 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; -} - -static grub_file_t -try_open_from_prefix (const char *prefix, const char *filename) -{ - grub_file_t file; - char *fullname, *ptr; - - fullname = grub_malloc (grub_strlen (prefix) + grub_strlen (filename) + 1 - + sizeof ("/fonts/") + sizeof (".pf2")); - if (!fullname) - return NULL; - ptr = grub_stpcpy (fullname, prefix); - ptr = grub_stpcpy (ptr, "/fonts/"); - ptr = grub_stpcpy (ptr, filename); - ptr = grub_stpcpy (ptr, ".pf2"); - *ptr = '\0'; - - file = grub_buffile_open (fullname, GRUB_FILE_TYPE_FONT, 1024); - grub_free (fullname); - return file; -} - -/* Load a font and add it to the beginning of the global font list. - Returns 0 upon success, nonzero upon failure. */ -grub_font_t -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_dprintf ("font", "add_font(%s)\n", filename); -#endif - - if (filename[0] == '(' || filename[0] == '/' || filename[0] == '+') - file = grub_buffile_open (filename, GRUB_FILE_TYPE_FONT, 1024); - else - { - file = try_open_from_prefix ("(memdisk)", filename); - if (!file) - { - const char *prefix = grub_env_get ("prefix"); - - if (!prefix) - { - grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix"); - goto fail; - } - file = try_open_from_prefix (prefix, filename); - } - } - if (!file) - goto fail; - -#if FONT_DEBUG >= 3 - grub_dprintf ("font", "file opened\n"); -#endif - - /* Read the FILE section. It indicates the file format. */ - if (open_section (file, §ion) != 0) - goto fail; - -#if FONT_DEBUG >= 3 - grub_dprintf ("font", "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_dprintf ("font", "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_dprintf ("font", "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_dprintf ("font", "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_dprintf ("font", "compare magic ok\n"); -#endif - - /* Allocate the font object. */ - font = (grub_font_t) grub_zalloc (sizeof (struct grub_font)); - if (!font) - goto fail; - - font_init (font); - font->file = file; - -#if FONT_DEBUG >= 3 - grub_dprintf ("font", "allocate font ok; loading font info\n"); -#endif - - /* Load the font information. */ - while (1) - { - if (open_section (file, §ion) != 0) - { - if (section.eof) - break; /* Done reading the font file. */ - else - goto fail; - } - -#if FONT_DEBUG >= 2 - grub_dprintf ("font", "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) - { - if (font->name != NULL) - { - grub_error (GRUB_ERR_BAD_FONT, "invalid font file: too many NAME sections"); - goto fail; - } - - font->name = read_section_as_string (§ion); - 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 (§ion, &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 (§ion); - 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 (§ion, &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 (§ion, &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 (§ion, &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 (§ion, &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_dprintf ("font", "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_dprintf ("font", "Font has no name.\n"); - font->name = grub_strdup ("Unknown"); - } - -#if FONT_DEBUG >= 1 - grub_dprintf ("font", "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 font; - -fail: - if (file) - grub_file_close (file); - if (font) - font->file = 0; - - free_font (font); - return 0; -} - -/* 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, *first, *end; - grub_size_t len; - - table = font->char_index; - if (table == NULL) - return NULL; - - /* Use BMP index if possible. */ - if (code < 0x10000 && font->bmp_idx) - { - if (font->bmp_idx[code] < 0xffff) - return &table[font->bmp_idx[code]]; - /* - * When we are here then lookup in BMP index result in miss, - * fallthough to binary-search. - */ - } - - /* - * Do a binary search in char_index which is ordered by code point. - * The code below is the same as libstdc++'s std::lower_bound(). - */ - first = table; - len = font->num_chars; - end = first + len; - - while (len > 0) - { - grub_size_t half = len >> 1; - struct char_index_entry *middle = first + half; - - if (middle->code < code) - { - first = middle + 1; - len = len - half - 1; - } - else - len = half; - } - - return (first < end && first->code == code) ? first : NULL; -} - -/* 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; - grub_ssize_t len; - grub_size_t sz; - - 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 - || width > font->max_char_width - || height > font->max_char_height) - { - remove_font (font); - return 0; - } - - /* Calculate real struct size of current glyph. */ - if (grub_video_bitmap_calc_1bpp_bufsz (width, height, &len) || - grub_add (sizeof (struct grub_font_glyph), len, &sz)) - { - remove_font (font); - return 0; - } - - /* Allocate and initialize the glyph struct. */ - glyph = grub_malloc (sz); - if (glyph == NULL) - { - 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); - grub_free (glyph); - 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->bmp_idx); - 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 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; -} - -/* FIXME: not correct for all fonts. */ -int -grub_font_get_xheight (grub_font_t font) -{ - return font->ascent / 2; -} - -/* 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 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 && !font) - return glyph; - if (glyph) - { - int d; - - d = get_font_diversity (curfont, font); - if (d < best_diversity) - { - best_diversity = d; - best_glyph = glyph; - } - } - } - - return best_glyph; -} - -/* FIXME: suboptimal. */ -static void -grub_font_blit_glyph (struct grub_font_glyph *target, - struct grub_font_glyph *src, unsigned dx, unsigned dy) -{ - grub_uint16_t max_x, max_y; - unsigned src_bit, tgt_bit, src_byte, tgt_byte; - unsigned i, j; - - /* Harden against out-of-bound writes. */ - if ((grub_add (dx, src->width, &max_x) || max_x > target->width) || - (grub_add (dy, src->height, &max_y) || max_y > target->height)) - return; - - for (i = 0; i < src->height; i++) - { - src_bit = (src->width * i) % 8; - src_byte = (src->width * i) / 8; - tgt_bit = (target->width * (dy + i) + dx) % 8; - tgt_byte = (target->width * (dy + i) + dx) / 8; - for (j = 0; j < src->width; j++) - { - target->bitmap[tgt_byte] |= ((src->bitmap[src_byte] << src_bit) - & 0x80) >> tgt_bit; - src_bit++; - tgt_bit++; - if (src_bit == 8) - { - src_byte++; - src_bit = 0; - } - if (tgt_bit == 8) - { - tgt_byte++; - tgt_bit = 0; - } - } - } -} - -static void -grub_font_blit_glyph_mirror (struct grub_font_glyph *target, - struct grub_font_glyph *src, - unsigned dx, unsigned dy) -{ - grub_uint16_t max_x, max_y; - unsigned tgt_bit, src_byte, tgt_byte; - signed src_bit; - unsigned i, j; - - /* Harden against out-of-bound writes. */ - if ((grub_add (dx, src->width, &max_x) || max_x > target->width) || - (grub_add (dy, src->height, &max_y) || max_y > target->height)) - return; - - for (i = 0; i < src->height; i++) - { - src_bit = (src->width * i + src->width - 1) % 8; - src_byte = (src->width * i + src->width - 1) / 8; - tgt_bit = (target->width * (dy + i) + dx) % 8; - tgt_byte = (target->width * (dy + i) + dx) / 8; - for (j = 0; j < src->width; j++) - { - target->bitmap[tgt_byte] |= ((src->bitmap[src_byte] << src_bit) - & 0x80) >> tgt_bit; - src_bit--; - tgt_bit++; - if (src_bit == -1) - { - src_byte--; - src_bit = 7; - } - if (tgt_bit == 8) - { - tgt_byte++; - tgt_bit = 0; - } - } - } -} - -/* Context for blit_comb. */ -struct blit_comb_ctx -{ - struct grub_font_glyph *glyph; - int *device_width; - struct grub_video_signed_rect bounds; -}; - -/* Helper for blit_comb. */ -static void -do_blit (struct grub_font_glyph *src, signed dx, signed dy, - struct blit_comb_ctx *ctx) -{ - if (ctx->glyph) - grub_font_blit_glyph (ctx->glyph, src, dx - ctx->glyph->offset_x, - (ctx->glyph->height + ctx->glyph->offset_y) + dy); - if (dx < ctx->bounds.x) - { - ctx->bounds.width += ctx->bounds.x - dx; - ctx->bounds.x = dx; - } - if (ctx->bounds.y > -src->height - dy) - { - ctx->bounds.height += ctx->bounds.y - (-src->height - dy); - ctx->bounds.y = (-src->height - dy); - } - if (dx + src->width - ctx->bounds.x >= (signed) ctx->bounds.width) - ctx->bounds.width = dx + src->width - ctx->bounds.x + 1; - if ((signed) ctx->bounds.height < src->height + (-src->height - dy) - - ctx->bounds.y) - ctx->bounds.height = src->height + (-src->height - dy) - ctx->bounds.y; -} - -/* Helper for blit_comb. */ -static inline void -add_device_width (int val, struct blit_comb_ctx *ctx) -{ - if (ctx->glyph) - ctx->glyph->device_width += val; - if (ctx->device_width) - *ctx->device_width += val; -} - -static void -blit_comb (const struct grub_unicode_glyph *glyph_id, - struct grub_font_glyph *glyph, - struct grub_video_signed_rect *bounds_out, - struct grub_font_glyph *main_glyph, - struct grub_font_glyph **combining_glyphs, int *device_width) -{ - struct blit_comb_ctx ctx = { - .glyph = glyph, - .device_width = device_width - }; - unsigned i; - signed above_rightx, above_righty; - signed above_leftx, above_lefty; - signed below_rightx, below_righty; - signed min_devwidth = 0; - const struct grub_unicode_combining *comb; - - if (glyph) - glyph->device_width = main_glyph->device_width; - if (device_width) - *device_width = main_glyph->device_width; - - ctx.bounds.x = main_glyph->offset_x; - ctx.bounds.y = main_glyph->offset_y; - ctx.bounds.width = main_glyph->width; - ctx.bounds.height = main_glyph->height; - - above_rightx = main_glyph->offset_x + main_glyph->width; - above_righty = ctx.bounds.y + (int) ctx.bounds.height; - - above_leftx = main_glyph->offset_x; - above_lefty = ctx.bounds.y + (int) ctx.bounds.height; - - below_rightx = ctx.bounds.x + (int) ctx.bounds.width; - below_righty = ctx.bounds.y; - - comb = grub_unicode_get_comb (glyph_id); - - for (i = 0; i < glyph_id->ncomb; i++) - { - grub_int16_t space = 0; - /* Center by default. */ - grub_int16_t targetx; - - if (!combining_glyphs[i]) - continue; - targetx = ((int) ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x; - /* CGJ is to avoid diacritics reordering. */ - if (comb[i].code - == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER) - continue; - switch (comb[i].type) - { - case GRUB_UNICODE_COMB_OVERLAY: - do_blit (combining_glyphs[i], - targetx, - ((int) ctx.bounds.height - combining_glyphs[i]->height) / 2 - - ((int) ctx.bounds.height + ctx.bounds.y), &ctx); - if (min_devwidth < combining_glyphs[i]->width) - min_devwidth = combining_glyphs[i]->width; - break; - - case GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT: - do_blit (combining_glyphs[i], above_rightx, -above_righty, &ctx); - above_rightx += combining_glyphs[i]->width; - break; - - case GRUB_UNICODE_COMB_ABOVE_RIGHT: - do_blit (combining_glyphs[i], above_rightx, - -(above_righty + combining_glyphs[i]->height), &ctx); - above_rightx += combining_glyphs[i]->width; - break; - - case GRUB_UNICODE_COMB_ABOVE_LEFT: - above_leftx -= combining_glyphs[i]->width; - do_blit (combining_glyphs[i], above_leftx, - -(above_lefty + combining_glyphs[i]->height), &ctx); - break; - - case GRUB_UNICODE_COMB_BELOW_RIGHT: - do_blit (combining_glyphs[i], below_rightx, below_righty, &ctx); - below_rightx += combining_glyphs[i]->width; - break; - - case GRUB_UNICODE_COMB_HEBREW_HOLAM: - if (glyph_id->base != GRUB_UNICODE_HEBREW_WAW) - targetx = - main_glyph->offset_x - combining_glyphs[i]->width - - (combining_glyphs[i]->width + 3) / 4; - goto above_on_main; - - case GRUB_UNICODE_COMB_HEBREW_SIN_DOT: - targetx = main_glyph->offset_x + combining_glyphs[i]->width / 4; - goto above_on_main; - - case GRUB_UNICODE_COMB_HEBREW_SHIN_DOT: - targetx = - main_glyph->width + main_glyph->offset_x - - combining_glyphs[i]->width; - above_on_main: - space = combining_glyphs[i]->offset_y - - grub_font_get_xheight (combining_glyphs[i]->font) - 1; - if (space <= 0) - space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8; - do_blit (combining_glyphs[i], targetx, - -(main_glyph->height + main_glyph->offset_y + space - + combining_glyphs[i]->height), &ctx); - if (min_devwidth < combining_glyphs[i]->width) - min_devwidth = combining_glyphs[i]->width; - break; - - /* TODO: Put dammah, fathah and alif nearer to shadda. */ - case GRUB_UNICODE_COMB_SYRIAC_SUPERSCRIPT_ALAPH: - case GRUB_UNICODE_COMB_ARABIC_DAMMAH: - case GRUB_UNICODE_COMB_ARABIC_DAMMATAN: - case GRUB_UNICODE_COMB_ARABIC_FATHATAN: - case GRUB_UNICODE_COMB_ARABIC_FATHAH: - case GRUB_UNICODE_COMB_ARABIC_SUPERSCRIPT_ALIF: - case GRUB_UNICODE_COMB_ARABIC_SUKUN: - case GRUB_UNICODE_COMB_ARABIC_SHADDA: - case GRUB_UNICODE_COMB_HEBREW_RAFE: - case GRUB_UNICODE_STACK_ABOVE: - stacked_above: - space = combining_glyphs[i]->offset_y - - grub_font_get_xheight (combining_glyphs[i]->font) - 1; - if (space <= 0) - space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8; - /* Fallthrough. */ - case GRUB_UNICODE_STACK_ATTACHED_ABOVE: - do_blit (combining_glyphs[i], targetx, - -((int) ctx.bounds.height + ctx.bounds.y + space - + combining_glyphs[i]->height), &ctx); - if (min_devwidth < combining_glyphs[i]->width) - min_devwidth = combining_glyphs[i]->width; - break; - - case GRUB_UNICODE_COMB_HEBREW_DAGESH: - do_blit (combining_glyphs[i], targetx, - -((int) ctx.bounds.height / 2 + ctx.bounds.y - + combining_glyphs[i]->height / 2), &ctx); - if (min_devwidth < combining_glyphs[i]->width) - min_devwidth = combining_glyphs[i]->width; - break; - - case GRUB_UNICODE_COMB_HEBREW_SHEVA: - case GRUB_UNICODE_COMB_HEBREW_HIRIQ: - case GRUB_UNICODE_COMB_HEBREW_QAMATS: - case GRUB_UNICODE_COMB_HEBREW_TSERE: - case GRUB_UNICODE_COMB_HEBREW_SEGOL: - /* TODO: placement in final kaf and under reish. */ - - case GRUB_UNICODE_COMB_HEBREW_HATAF_SEGOL: - case GRUB_UNICODE_COMB_HEBREW_HATAF_PATAH: - case GRUB_UNICODE_COMB_HEBREW_HATAF_QAMATS: - case GRUB_UNICODE_COMB_HEBREW_PATAH: - case GRUB_UNICODE_COMB_HEBREW_QUBUTS: - case GRUB_UNICODE_COMB_HEBREW_METEG: - /* TODO: Put kasra and kasratan under shadda. */ - case GRUB_UNICODE_COMB_ARABIC_KASRA: - case GRUB_UNICODE_COMB_ARABIC_KASRATAN: - /* I don't know how ypogegrammeni differs from subscript. */ - case GRUB_UNICODE_COMB_YPOGEGRAMMENI: - case GRUB_UNICODE_STACK_BELOW: - stacked_below: - space = -(combining_glyphs[i]->offset_y - + combining_glyphs[i]->height); - if (space <= 0) - space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8; - /* Fallthrough. */ - - case GRUB_UNICODE_STACK_ATTACHED_BELOW: - do_blit (combining_glyphs[i], targetx, -(ctx.bounds.y - space), - &ctx); - if (min_devwidth < combining_glyphs[i]->width) - min_devwidth = combining_glyphs[i]->width; - break; - - case GRUB_UNICODE_COMB_MN: - switch (comb[i].code) - { - case GRUB_UNICODE_THAANA_ABAFILI: - case GRUB_UNICODE_THAANA_AABAAFILI: - case GRUB_UNICODE_THAANA_UBUFILI: - case GRUB_UNICODE_THAANA_OOBOOFILI: - case GRUB_UNICODE_THAANA_EBEFILI: - case GRUB_UNICODE_THAANA_EYBEYFILI: - case GRUB_UNICODE_THAANA_OBOFILI: - case GRUB_UNICODE_THAANA_OABOAFILI: - case GRUB_UNICODE_THAANA_SUKUN: - goto stacked_above; - case GRUB_UNICODE_THAANA_IBIFILI: - case GRUB_UNICODE_THAANA_EEBEEFILI: - goto stacked_below; - } - /* Fall through. */ - default: - { - /* Default handling. Just draw combining character on top - of base character. - FIXME: support more unicode types correctly. - */ - do_blit (combining_glyphs[i], - main_glyph->device_width - + combining_glyphs[i]->offset_x, - -(combining_glyphs[i]->height - + combining_glyphs[i]->offset_y), &ctx); - add_device_width (combining_glyphs[i]->device_width, &ctx); - } - } - } - add_device_width ((above_rightx > - below_rightx ? above_rightx : below_rightx) - - (main_glyph->offset_x + main_glyph->width), &ctx); - add_device_width (above_leftx - main_glyph->offset_x, &ctx); - if (glyph && glyph->device_width < min_devwidth) - glyph->device_width = min_devwidth; - if (device_width && *device_width < min_devwidth) - *device_width = min_devwidth; - - if (bounds_out) - *bounds_out = ctx.bounds; -} - -static struct grub_font_glyph * -grub_font_construct_dry_run (grub_font_t hinted_font, - const struct grub_unicode_glyph *glyph_id, - struct grub_video_signed_rect *bounds, - struct grub_font_glyph **combining_glyphs, - int *device_width) -{ - struct grub_font_glyph *main_glyph = NULL; - grub_uint32_t desired_attributes = 0; - unsigned i; - grub_uint32_t base = glyph_id->base; - const struct grub_unicode_combining *comb; - - if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED) - desired_attributes |= GRUB_FONT_CODE_RIGHT_JOINED; - - if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED) - desired_attributes |= GRUB_FONT_CODE_LEFT_JOINED; - - comb = grub_unicode_get_comb (glyph_id); - - if (base == 'i' || base == 'j') - { - for (i = 0; i < glyph_id->ncomb; i++) - if (comb[i].type == GRUB_UNICODE_STACK_ABOVE) - break; - if (i < glyph_id->ncomb && base == 'i') - base = GRUB_UNICODE_DOTLESS_LOWERCASE_I; - if (i < glyph_id->ncomb && base == 'j') - base = GRUB_UNICODE_DOTLESS_LOWERCASE_J; - } - - main_glyph = grub_font_get_glyph_with_fallback (hinted_font, base - | desired_attributes); - - if (!main_glyph) - main_glyph = grub_font_get_glyph_with_fallback (hinted_font, - base); - - /* Glyph not available in any font. Use ASCII fallback. */ - if (!main_glyph) - main_glyph = ascii_glyph_lookup (base); - - /* Glyph not available in any font. Return unknown glyph. */ - if (!main_glyph) - return NULL; - - if (device_width) - *device_width = main_glyph->device_width; - - if (!glyph_id->ncomb && !glyph_id->attributes) - return main_glyph; - - if (glyph_id->ncomb && !combining_glyphs) - { - grub_errno = GRUB_ERR_NONE; - return main_glyph; - } - - for (i = 0; i < glyph_id->ncomb; i++) - combining_glyphs[i] - = grub_font_get_glyph_with_fallback (main_glyph->font, - comb[i].code); - - blit_comb (glyph_id, NULL, bounds, main_glyph, combining_glyphs, - device_width); - - return main_glyph; -} - -static struct grub_font_glyph **render_combining_glyphs = 0; -static grub_size_t render_max_comb_glyphs = 0; - -static void -ensure_comb_space (const struct grub_unicode_glyph *glyph_id) -{ - if (glyph_id->ncomb <= render_max_comb_glyphs) - return; - - if (grub_mul (glyph_id->ncomb, 2, &render_max_comb_glyphs)) - render_max_comb_glyphs = 0; - if (render_max_comb_glyphs > 0 && render_max_comb_glyphs < 8) - render_max_comb_glyphs = 8; - grub_free (render_combining_glyphs); - render_combining_glyphs = (render_max_comb_glyphs > 0) ? - grub_calloc (render_max_comb_glyphs, sizeof (render_combining_glyphs[0])) : NULL; - if (!render_combining_glyphs) - { - render_max_comb_glyphs = 0; - grub_errno = GRUB_ERR_NONE; - } -} - -int -grub_font_get_constructed_device_width (grub_font_t hinted_font, - const struct grub_unicode_glyph - *glyph_id) -{ - int ret; - struct grub_font_glyph *main_glyph; - - ensure_comb_space (glyph_id); - - main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id, NULL, - render_combining_glyphs, &ret); - if (!main_glyph) - return unknown_glyph->device_width; - return ret; -} - -struct grub_font_glyph * -grub_font_construct_glyph (grub_font_t hinted_font, - const struct grub_unicode_glyph *glyph_id) -{ - struct grub_font_glyph *main_glyph; - struct grub_video_signed_rect bounds; - static struct grub_font_glyph *glyph = 0; - static grub_size_t max_glyph_size = 0; - grub_size_t cur_glyph_size; - - ensure_comb_space (glyph_id); - - main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id, - &bounds, render_combining_glyphs, - NULL); - - if (!main_glyph) - return unknown_glyph; - - if (!render_combining_glyphs && glyph_id->ncomb) - return main_glyph; - - if (!glyph_id->ncomb && !glyph_id->attributes) - return main_glyph; - - if (grub_video_bitmap_calc_1bpp_bufsz (bounds.width, bounds.height, &cur_glyph_size) || - grub_add (sizeof (*glyph), cur_glyph_size, &cur_glyph_size)) - return main_glyph; - - if (max_glyph_size < cur_glyph_size) - { - grub_free (glyph); - if (grub_mul (cur_glyph_size, 2, &max_glyph_size)) - max_glyph_size = 0; - glyph = max_glyph_size > 0 ? grub_malloc (max_glyph_size) : NULL; - } - if (!glyph) - { - max_glyph_size = 0; - grub_errno = GRUB_ERR_NONE; - return main_glyph; - } - - grub_memset (glyph, 0, cur_glyph_size); - - glyph->font = main_glyph->font; - if (bounds.width == 0 || bounds.height == 0 || - grub_cast (bounds.width, &glyph->width) || - grub_cast (bounds.height, &glyph->height) || - grub_cast (bounds.x, &glyph->offset_x) || - grub_cast (bounds.y, &glyph->offset_y)) - return main_glyph; - - if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR) - grub_font_blit_glyph_mirror (glyph, main_glyph, - main_glyph->offset_x - glyph->offset_x, - (glyph->height + glyph->offset_y) - - (main_glyph->height + - main_glyph->offset_y)); - else - grub_font_blit_glyph (glyph, main_glyph, - main_glyph->offset_x - glyph->offset_x, - (glyph->height + glyph->offset_y) - - (main_glyph->height + main_glyph->offset_y)); - - blit_comb (glyph_id, glyph, NULL, main_glyph, render_combining_glyphs, NULL); - - return glyph; -} - -/* 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); -} diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c deleted file mode 100644 index 520a001c7..000000000 --- a/grub-core/fs/affs.c +++ /dev/null @@ -1,719 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* The affs bootblock. */ -struct grub_affs_bblock -{ - grub_uint8_t type[3]; - grub_uint8_t flags; - grub_uint32_t checksum; - grub_uint32_t rootblock; -} GRUB_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_uint32_t type; - grub_uint8_t unused1[8]; - grub_uint32_t htsize; - grub_uint32_t unused2; - grub_uint32_t checksum; - grub_uint32_t hashtable[1]; -} GRUB_PACKED; - -struct grub_affs_time -{ - grub_int32_t day; - grub_uint32_t min; - grub_uint32_t hz; -} GRUB_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[92]; - struct grub_affs_time mtime; - grub_uint8_t namelen; - grub_uint8_t name[30]; - grub_uint8_t unused3[5]; - grub_uint32_t hardlink; - grub_uint32_t unused4[6]; - grub_uint32_t next; - grub_uint32_t parent; - grub_uint32_t extension; - grub_uint32_t type; -} GRUB_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 - -enum - { - GRUB_AFFS_FILETYPE_DIR = 2, - GRUB_AFFS_FILETYPE_SYMLINK = 3, - GRUB_AFFS_FILETYPE_HARDLINK = 0xfffffffc, - GRUB_AFFS_FILETYPE_REG = 0xfffffffd - }; - -#define AFFS_MAX_LOG_BLOCK_SIZE 4 -#define AFFS_MAX_SUPERBLOCK 1 - - - -struct grub_fshelp_node -{ - struct grub_affs_data *data; - grub_uint32_t block; - struct grub_fshelp_node *parent; - struct grub_affs_file di; - grub_uint32_t *block_cache; - grub_uint32_t last_block_cache; -}; - -/* Information about a "mounted" affs filesystem. */ -struct grub_affs_data -{ - struct grub_affs_bblock bblock; - struct grub_fshelp_node diropen; - grub_disk_t disk; - - /* Log blocksize in sectors. */ - int log_blocksize; - - /* The number of entries in the hashtable. */ - unsigned int htsize; -}; - -static grub_dl_t my_mod; - - -static grub_disk_addr_t -grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) -{ - grub_uint32_t target, curblock; - grub_uint32_t pos; - struct grub_affs_file file; - struct grub_affs_data *data = node->data; - grub_uint64_t mod; - - if (!node->block_cache) - { - node->block_cache = grub_malloc (((grub_be_to_cpu32 (node->di.size) - >> (9 + node->data->log_blocksize)) - / data->htsize + 2) - * sizeof (node->block_cache[0])); - if (!node->block_cache) - return -1; - node->last_block_cache = 0; - node->block_cache[0] = node->block; - } - - /* Files are at most 2G on AFFS, so no need for 64-bit division. */ - target = (grub_uint32_t) fileblock / data->htsize; - mod = (grub_uint32_t) fileblock % data->htsize; - /* Find the block that points to the fileblock we are looking up by - following the chain until the right table is reached. */ - for (curblock = node->last_block_cache + 1; curblock < target + 1; curblock++) - { - grub_disk_read (data->disk, - (((grub_uint64_t) node->block_cache[curblock - 1] + 1) - << data->log_blocksize) - 1, - GRUB_DISK_SECTOR_SIZE - GRUB_AFFS_FILE_LOCATION, - sizeof (file), &file); - if (grub_errno) - return 0; - - node->block_cache[curblock] = grub_be_to_cpu32 (file.extension); - node->last_block_cache = curblock; - } - - /* Translate the fileblock to the block within the right table. */ - grub_disk_read (data->disk, (grub_uint64_t) node->block_cache[target] - << data->log_blocksize, - GRUB_AFFS_BLOCKPTR_OFFSET - + (data->htsize - mod - 1) * sizeof (pos), - sizeof (pos), &pos); - if (grub_errno) - return 0; - - return grub_be_to_cpu32 (pos); -} - -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 = 0; - int log_blocksize = 0; - int bsnum = 0; - - data = grub_zalloc (sizeof (struct grub_affs_data)); - if (!data) - return 0; - - for (bsnum = 0; bsnum < AFFS_MAX_SUPERBLOCK + 1; bsnum++) - { - /* Read the bootblock. */ - grub_disk_read (disk, bsnum, 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) != 0 - /* Test if the filesystem is a OFS filesystem. */ - || !(data->bblock.flags & GRUB_AFFS_FLAG_FFS)) - continue; - - /* 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. */ - if (!rootblock) - rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE - << AFFS_MAX_LOG_BLOCK_SIZE); - if (!rootblock) - goto fail; - - rblock = (struct grub_affs_rblock *) rootblock; - - /* The filesystem blocksize is not stored anywhere in the filesystem - itself. One way to determine it is try reading blocks for the - rootblock until the checksum is correct. */ - for (log_blocksize = 0; log_blocksize <= AFFS_MAX_LOG_BLOCK_SIZE; - log_blocksize++) - { - grub_uint32_t *currblock = rootblock; - unsigned int i; - grub_uint32_t checksum = 0; - - /* Read the rootblock. */ - grub_disk_read (disk, - (grub_uint64_t) grub_be_to_cpu32 (data->bblock.rootblock) - << log_blocksize, 0, - GRUB_DISK_SECTOR_SIZE << log_blocksize, rootblock); - if (grub_errno == GRUB_ERR_OUT_OF_RANGE) - { - grub_errno = 0; - break; - } - if (grub_errno) - goto fail; - - if (rblock->type != grub_cpu_to_be32_compile_time (2) - || rblock->htsize == 0 - || currblock[(GRUB_DISK_SECTOR_SIZE << log_blocksize) - / sizeof (*currblock) - 1] - != grub_cpu_to_be32_compile_time (1)) - continue; - - for (i = 0; i < (GRUB_DISK_SECTOR_SIZE << log_blocksize) - / sizeof (*currblock); - i++) - checksum += grub_be_to_cpu32 (currblock[i]); - - if (checksum == 0) - { - data->log_blocksize = log_blocksize; - data->disk = disk; - data->htsize = grub_be_to_cpu32 (rblock->htsize); - data->diropen.data = data; - data->diropen.block = grub_be_to_cpu32 (data->bblock.rootblock); - data->diropen.parent = NULL; - grub_memcpy (&data->diropen.di, rootblock, - sizeof (data->diropen.di)); - grub_free (rootblock); - - return data; - } - } - } - - fail: - if (grub_errno == GRUB_ERR_NONE || 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; - grub_uint8_t *latin1, *utf8; - const grub_size_t symlink_size = ((GRUB_DISK_SECTOR_SIZE - << data->log_blocksize) - GRUB_AFFS_SYMLINK_OFFSET); - - latin1 = grub_malloc (symlink_size + 1); - if (!latin1) - return 0; - - grub_disk_read (data->disk, - (grub_uint64_t) node->block << data->log_blocksize, - GRUB_AFFS_SYMLINK_OFFSET, - symlink_size, latin1); - if (grub_errno) - { - grub_free (latin1); - return 0; - } - latin1[symlink_size] = 0; - utf8 = grub_calloc (GRUB_MAX_UTF8_PER_LATIN1 + 1, symlink_size); - if (!utf8) - { - grub_free (latin1); - return 0; - } - *grub_latin1_to_utf8 (utf8, latin1, symlink_size) = '\0'; - grub_dprintf ("affs", "Symlink: `%s'\n", utf8); - grub_free (latin1); - if (utf8[0] == ':') - utf8[0] = '/'; - return (char *) utf8; -} - - -/* Helper for grub_affs_iterate_dir. */ -static int -grub_affs_create_node (grub_fshelp_node_t dir, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data, - struct grub_fshelp_node **node, - grub_uint32_t block, const struct grub_affs_file *fil) -{ - struct grub_affs_data *data = dir->data; - int type = GRUB_FSHELP_REG; - grub_uint8_t name_u8[sizeof (fil->name) * GRUB_MAX_UTF8_PER_LATIN1 + 1]; - grub_size_t len; - unsigned int nest; - - *node = grub_zalloc (sizeof (**node)); - if (!*node) - return 1; - - (*node)->data = data; - (*node)->block = block; - (*node)->parent = dir; - - len = fil->namelen; - if (len > sizeof (fil->name)) - len = sizeof (fil->name); - *grub_latin1_to_utf8 (name_u8, fil->name, len) = '\0'; - - (*node)->di = *fil; - for (nest = 0; nest < 8; nest++) - { - switch ((*node)->di.type) - { - case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_REG): - type = GRUB_FSHELP_REG; - break; - case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_DIR): - type = GRUB_FSHELP_DIR; - break; - case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_SYMLINK): - type = GRUB_FSHELP_SYMLINK; - break; - case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_HARDLINK): - { - grub_err_t err; - (*node)->block = grub_be_to_cpu32 ((*node)->di.hardlink); - err = grub_disk_read (data->disk, - (((grub_uint64_t) (*node)->block + 1) << data->log_blocksize) - - 1, - GRUB_DISK_SECTOR_SIZE - GRUB_AFFS_FILE_LOCATION, - sizeof ((*node)->di), (char *) &(*node)->di); - if (err) - { - grub_free (*node); - return 1; - } - continue; - } - default: - { - grub_free (*node); - return 0; - } - } - break; - } - - if (nest == 8) - { - grub_free (*node); - return 0; - } - - type |= GRUB_FSHELP_CASE_INSENSITIVE; - - if (hook ((char *) name_u8, type, *node, hook_data)) - { - *node = 0; - return 1; - } - *node = 0; - return 0; -} - -static int -grub_affs_iterate_dir (grub_fshelp_node_t dir, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data) -{ - unsigned int i; - struct grub_affs_file file; - struct grub_fshelp_node *node, *orig_node; - struct grub_affs_data *data = dir->data; - grub_uint32_t *hashtable; - - /* Create the directory entries for `.' and `..'. */ - node = orig_node = grub_zalloc (sizeof (*node)); - if (!node) - return 1; - - *node = *dir; - if (hook (".", GRUB_FSHELP_DIR, node, hook_data)) - return 1; - if (dir->parent) - { - *node = *dir->parent; - if (hook ("..", GRUB_FSHELP_DIR, node, hook_data)) - return 1; - } - - hashtable = grub_calloc (data->htsize, sizeof (*hashtable)); - if (!hashtable) - return 1; - - grub_disk_read (data->disk, - (grub_uint64_t) dir->block << data->log_blocksize, - GRUB_AFFS_HASHTABLE_OFFSET, - data->htsize * sizeof (*hashtable), (char *) hashtable); - if (grub_errno) - goto fail; - - for (i = 0; i < data->htsize; i++) - { - grub_uint32_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, - (((grub_uint64_t) next + 1) << data->log_blocksize) - - 1, - GRUB_DISK_SECTOR_SIZE - GRUB_AFFS_FILE_LOCATION, - sizeof (file), (char *) &file); - if (grub_errno) - goto fail; - - if (grub_affs_create_node (dir, hook, hook_data, &node, next, &file)) - { - /* Node has been replaced in function. */ - grub_free (orig_node); - grub_free (hashtable); - return 1; - } - - next = grub_be_to_cpu32 (file.next); - } - } - - fail: - grub_free (orig_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 = grub_be_to_cpu32 (fdiro->di.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) -{ - struct grub_affs_data *data = - (struct grub_affs_data *) file->data; - - grub_free (data->diropen.block_cache); - 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; - - return grub_fshelp_read_file (data->diropen.data->disk, &data->diropen, - file->read_hook, file->read_hook_data, - file->offset, len, buf, grub_affs_read_block, - grub_be_to_cpu32 (data->diropen.di.size), - data->log_blocksize, 0); -} - -static grub_int32_t -aftime2ctime (const struct grub_affs_time *t) -{ - return grub_be_to_cpu32 (t->day) * 86400 - + grub_be_to_cpu32 (t->min) * 60 - + grub_be_to_cpu32 (t->hz) / 50 - + 8 * 365 * 86400 + 86400 * 2; -} - -/* Context for grub_affs_dir. */ -struct grub_affs_dir_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; -}; - -/* Helper for grub_affs_dir. */ -static int -grub_affs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, void *data) -{ - struct grub_affs_dir_ctx *ctx = data; - 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 = aftime2ctime (&node->di.mtime); - grub_free (node); - return ctx->hook (filename, &info, ctx->hook_data); -} - -static grub_err_t -grub_affs_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_affs_dir_ctx ctx = { hook, hook_data }; - struct grub_affs_data *data = 0; - struct grub_fshelp_node *fdiro = 0; - - 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, grub_affs_dir_iter, &ctx); - - 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) - { - grub_size_t len; - /* The rootblock maps quite well on a file header block, it's - something we can use here. */ - grub_disk_read (data->disk, - (((grub_uint64_t) - grub_be_to_cpu32 (data->bblock.rootblock) + 1) - << data->log_blocksize) - 1, - GRUB_DISK_SECTOR_SIZE - GRUB_AFFS_FILE_LOCATION, - sizeof (file), &file); - if (grub_errno) - return grub_errno; - - len = file.namelen; - if (len > sizeof (file.name)) - len = sizeof (file.name); - *label = grub_calloc (GRUB_MAX_UTF8_PER_LATIN1 + 1, len); - if (*label) - *grub_latin1_to_utf8 ((grub_uint8_t *) *label, file.name, len) = '\0'; - } - else - *label = 0; - - grub_dl_unref (my_mod); - - grub_free (data); - - return grub_errno; -} - -static grub_err_t -grub_affs_mtime (grub_device_t device, grub_int64_t *t) -{ - struct grub_affs_data *data; - grub_disk_t disk = device->disk; - struct grub_affs_time af_time; - - *t = 0; - - grub_dl_ref (my_mod); - - data = grub_affs_mount (disk); - if (!data) - { - grub_dl_unref (my_mod); - return grub_errno; - } - - grub_disk_read (data->disk, - (((grub_uint64_t) - grub_be_to_cpu32 (data->bblock.rootblock) + 1) - << data->log_blocksize) - 1, - GRUB_DISK_SECTOR_SIZE - 40, - sizeof (af_time), &af_time); - if (grub_errno) - { - grub_dl_unref (my_mod); - grub_free (data); - return grub_errno; - } - - *t = aftime2ctime (&af_time); - grub_dl_unref (my_mod); - - grub_free (data); - - return GRUB_ERR_NONE; -} - - -static struct grub_fs grub_affs_fs = - { - .name = "affs", - .fs_dir = grub_affs_dir, - .fs_open = grub_affs_open, - .fs_read = grub_affs_read, - .fs_close = grub_affs_close, - .fs_label = grub_affs_label, - .fs_mtime = grub_affs_mtime, - -#ifdef GRUB_UTIL - .reserved_first_sector = 0, - .blocklist_install = 1, -#endif - .next = 0 - }; - -GRUB_MOD_INIT(affs) -{ - if (!grub_is_lockdown ()) - { - grub_affs_fs.mod = mod; - grub_fs_register (&grub_affs_fs); - } - my_mod = mod; -} - -GRUB_MOD_FINI(affs) -{ - if (!grub_is_lockdown ()) - grub_fs_unregister (&grub_affs_fs); -} diff --git a/grub-core/fs/afs.c b/grub-core/fs/afs.c deleted file mode 100644 index 00a5e3113..000000000 --- a/grub-core/fs/afs.c +++ /dev/null @@ -1,3 +0,0 @@ -#define MODE_AFS 1 -#include "bfs.c" - diff --git a/grub-core/fs/archelp.c b/grub-core/fs/archelp.c deleted file mode 100644 index 0816b28de..000000000 --- a/grub-core/fs/archelp.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007,2008,2009,2013 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 . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static inline void -canonicalize (char *name) -{ - char *iptr, *optr; - for (iptr = name, optr = name; *iptr; ) - { - while (*iptr == '/') - iptr++; - if (iptr[0] == '.' && (iptr[1] == '/' || iptr[1] == 0)) - { - iptr++; - continue; - } - if (iptr[0] == '.' && iptr[1] == '.' && (iptr[2] == '/' || iptr[2] == 0)) - { - iptr += 2; - if (optr == name) - continue; - for (optr -= 2; optr >= name && *optr != '/'; optr--); - optr++; - continue; - } - while (*iptr && *iptr != '/') - *optr++ = *iptr++; - if (*iptr) - *optr++ = *iptr++; - } - *optr = 0; -} - -static grub_err_t -handle_symlink (struct grub_archelp_data *data, - struct grub_archelp_ops *arcops, - const char *fn, char **name, - grub_uint32_t mode, int *restart) -{ - grub_size_t flen; - char *target; - char *ptr; - char *lastslash; - grub_size_t prefixlen; - char *rest; - char *linktarget; - grub_size_t linktarget_len; - grub_size_t sz; - - *restart = 0; - - if ((mode & GRUB_ARCHELP_ATTR_TYPE) != GRUB_ARCHELP_ATTR_LNK - || !arcops->get_link_target) - return GRUB_ERR_NONE; - flen = grub_strlen (fn); - if (grub_memcmp (*name, fn, flen) != 0 - || ((*name)[flen] != 0 && (*name)[flen] != '/')) - return GRUB_ERR_NONE; - rest = *name + flen; - lastslash = rest; - if (*rest) - rest++; - while (lastslash >= *name && *lastslash != '/') - lastslash--; - if (lastslash >= *name) - prefixlen = lastslash - *name; - else - prefixlen = 0; - - if (prefixlen) - prefixlen++; - - linktarget = arcops->get_link_target (data); - if (!linktarget) - return grub_errno; - if (linktarget[0] == '\0') - return GRUB_ERR_NONE; - linktarget_len = grub_strlen (linktarget); - - if (grub_add (linktarget_len, grub_strlen (*name), &sz) || - grub_add (sz, 2, &sz)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("link target length overflow")); - - target = grub_malloc (sz); - if (!target) - return grub_errno; - - grub_strcpy (target + prefixlen, linktarget); - grub_free (linktarget); - if (target[prefixlen] == '/') - { - ptr = grub_stpcpy (target, target + prefixlen); - ptr = grub_stpcpy (ptr, rest); - *ptr = 0; - grub_dprintf ("archelp", "symlink redirected %s to %s\n", - *name, target); - grub_free (*name); - - canonicalize (target); - *name = target; - *restart = 1; - return GRUB_ERR_NONE; - } - if (prefixlen) - { - grub_memcpy (target, *name, prefixlen); - target[prefixlen-1] = '/'; - } - grub_strcpy (target + prefixlen + linktarget_len, rest); - grub_dprintf ("archelp", "symlink redirected %s to %s\n", - *name, target); - grub_free (*name); - canonicalize (target); - *name = target; - *restart = 1; - return GRUB_ERR_NONE; -} - -grub_err_t -grub_archelp_dir (struct grub_archelp_data *data, - struct grub_archelp_ops *arcops, - const char *path_in, - grub_fs_dir_hook_t hook, void *hook_data) -{ - char *prev, *name, *path, *ptr; - grub_size_t len; - int symlinknest = 0; - - path = grub_strdup (path_in + 1); - if (!path) - return grub_errno; - canonicalize (path); - for (ptr = path + grub_strlen (path) - 1; ptr >= path && *ptr == '/'; ptr--) - *ptr = 0; - - prev = 0; - - len = grub_strlen (path); - while (1) - { - grub_int32_t mtime; - grub_uint32_t mode; - grub_err_t err; - - if (arcops->find_file (data, &name, &mtime, &mode)) - goto fail; - - if (mode == GRUB_ARCHELP_ATTR_END) - break; - - canonicalize (name); - - if (grub_memcmp (path, name, len) == 0 - && (name[len] == 0 || name[len] == '/' || len == 0)) - { - char *p, *n; - - n = name + len; - while (*n == '/') - n++; - - p = grub_strchr (n, '/'); - if (p) - *p = 0; - - if ((*n == 0) && ((mode & GRUB_ARCHELP_ATTR_TYPE) - != GRUB_ARCHELP_ATTR_DIR)) - { - grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); - grub_free (name); - goto fail; - } - - if (((!prev) || (grub_strcmp (prev, name) != 0)) && *n != 0) - { - struct grub_dirhook_info info; - grub_memset (&info, 0, sizeof (info)); - info.dir = (p != NULL) || ((mode & GRUB_ARCHELP_ATTR_TYPE) - == GRUB_ARCHELP_ATTR_DIR); - if (!(mode & GRUB_ARCHELP_ATTR_NOTIME)) - { - info.mtime = mtime; - info.mtimeset = 1; - } - if (hook (n, &info, hook_data)) - { - grub_free (name); - goto fail; - } - grub_free (prev); - prev = name; - } - else - { - int restart = 0; - err = handle_symlink (data, arcops, name, - &path, mode, &restart); - grub_free (name); - if (err) - goto fail; - if (restart) - { - len = grub_strlen (path); - if (++symlinknest == 8) - { - grub_error (GRUB_ERR_SYMLINK_LOOP, - N_("too deep nesting of symlinks")); - goto fail; - } - arcops->rewind (data); - } - } - } - else - grub_free (name); - } - -fail: - - grub_free (path); - grub_free (prev); - - return grub_errno; -} - -grub_err_t -grub_archelp_open (struct grub_archelp_data *data, - struct grub_archelp_ops *arcops, - const char *name_in) -{ - char *fn; - char *name = grub_strdup (name_in + 1); - int symlinknest = 0; - - if (!name) - return grub_errno; - - canonicalize (name); - - while (1) - { - grub_uint32_t mode; - grub_int32_t mtime; - int restart; - - if (arcops->find_file (data, &fn, &mtime, &mode)) - goto fail; - - if (mode == GRUB_ARCHELP_ATTR_END) - { - grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), name_in); - break; - } - - canonicalize (fn); - - if (handle_symlink (data, arcops, fn, &name, mode, &restart)) - { - grub_free (fn); - goto fail; - } - - if (restart) - { - arcops->rewind (data); - if (++symlinknest == 8) - { - grub_error (GRUB_ERR_SYMLINK_LOOP, - N_("too deep nesting of symlinks")); - goto fail; - } - goto no_match; - } - - if (grub_strcmp (name, fn) != 0) - goto no_match; - - grub_free (fn); - grub_free (name); - - return GRUB_ERR_NONE; - - no_match: - - grub_free (fn); - } - -fail: - grub_free (name); - - return grub_errno; -} diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c deleted file mode 100644 index 78aeb051f..000000000 --- a/grub-core/fs/bfs.c +++ /dev/null @@ -1,1125 +0,0 @@ -/* bfs.c - The Bee File System. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - Based on the book "Practical File System Design by Dominic Giampaolo - with corrections and completitions based on Haiku code. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#ifdef MODE_AFS -#define BTREE_ALIGN 4 -#define SUPERBLOCK 2 -#else -#define BTREE_ALIGN 8 -#define SUPERBLOCK 1 -#endif - -#define grub_bfs_to_cpu16 grub_le_to_cpu16 -#define grub_bfs_to_cpu32 grub_le_to_cpu32 -#define grub_bfs_to_cpu64 grub_le_to_cpu64 -#define grub_cpu_to_bfs32_compile_time grub_cpu_to_le32_compile_time - -#ifdef MODE_AFS -#define grub_bfs_to_cpu_treehead grub_bfs_to_cpu32 -#else -#define grub_bfs_to_cpu_treehead grub_bfs_to_cpu16 -#endif - -#ifdef MODE_AFS -#define SUPER_BLOCK_MAGIC1 0x41465331 -#else -#define SUPER_BLOCK_MAGIC1 0x42465331 -#endif -#define SUPER_BLOCK_MAGIC2 0xdd121031 -#define SUPER_BLOCK_MAGIC3 0x15b6830e -#define POINTER_INVALID 0xffffffffffffffffULL - -#define ATTR_TYPE 0160000 -#define ATTR_REG 0100000 -#define ATTR_DIR 0040000 -#define ATTR_LNK 0120000 - -#define DOUBLE_INDIRECT_SHIFT 2 - -#define LOG_EXTENT_SIZE 3 -struct grub_bfs_extent -{ - grub_uint32_t ag; - grub_uint16_t start; - grub_uint16_t len; -} GRUB_PACKED; - -struct grub_bfs_superblock -{ - char label[32]; - grub_uint32_t magic1; - grub_uint32_t unused1; - grub_uint32_t bsize; - grub_uint32_t log2_bsize; - grub_uint8_t unused[20]; - grub_uint32_t magic2; - grub_uint32_t unused2; - grub_uint32_t log2_ag_size; - grub_uint8_t unused3[32]; - grub_uint32_t magic3; - struct grub_bfs_extent root_dir; -} GRUB_PACKED; - -struct grub_bfs_inode -{ - grub_uint8_t unused[20]; - grub_uint32_t mode; - grub_uint32_t flags; -#ifdef MODE_AFS - grub_uint8_t unused2[12]; -#else - grub_uint8_t unused2[8]; -#endif - grub_uint64_t mtime; - grub_uint8_t unused3[8]; - struct grub_bfs_extent attr; - grub_uint8_t unused4[12]; - - union - { - struct - { - struct grub_bfs_extent direct[12]; - grub_uint64_t max_direct_range; - struct grub_bfs_extent indirect; - grub_uint64_t max_indirect_range; - struct grub_bfs_extent double_indirect; - grub_uint64_t max_double_indirect_range; - grub_uint64_t size; - grub_uint32_t pad[4]; - } GRUB_PACKED; - char inplace_link[144]; - } GRUB_PACKED; - grub_uint8_t small_data[0]; -} GRUB_PACKED; - -enum -{ - LONG_SYMLINK = 0x40 -}; - -struct grub_bfs_small_data_element_header -{ - grub_uint32_t type; - grub_uint16_t name_len; - grub_uint16_t value_len; -} GRUB_PACKED; - -struct grub_bfs_btree_header -{ - grub_uint32_t magic; -#ifdef MODE_AFS - grub_uint64_t root; - grub_uint32_t level; - grub_uint32_t node_size; - grub_uint32_t unused; -#else - grub_uint32_t node_size; - grub_uint32_t level; - grub_uint32_t unused; - grub_uint64_t root; -#endif - grub_uint32_t unused2[2]; -} GRUB_PACKED; - -struct grub_bfs_btree_node -{ - grub_uint64_t unused; - grub_uint64_t right; - grub_uint64_t overflow; -#ifdef MODE_AFS - grub_uint32_t count_keys; - grub_uint32_t total_key_len; -#else - grub_uint16_t count_keys; - grub_uint16_t total_key_len; -#endif -} GRUB_PACKED; - -struct grub_bfs_data -{ - struct grub_bfs_superblock sb; - struct grub_bfs_inode ino; -}; - -/* Context for grub_bfs_dir. */ -struct grub_bfs_dir_ctx -{ - grub_device_t device; - grub_fs_dir_hook_t hook; - void *hook_data; - struct grub_bfs_superblock sb; -}; - -static grub_err_t -read_extent (grub_disk_t disk, - const struct grub_bfs_superblock *sb, - const struct grub_bfs_extent *in, - grub_off_t off, grub_off_t byteoff, void *buf, grub_size_t len) -{ -#ifdef MODE_AFS - return grub_disk_read (disk, ((grub_bfs_to_cpu32 (in->ag) - << (grub_bfs_to_cpu32 (sb->log2_ag_size) - - GRUB_DISK_SECTOR_BITS)) - + ((grub_bfs_to_cpu16 (in->start) + off) - << (grub_bfs_to_cpu32 (sb->log2_bsize) - - GRUB_DISK_SECTOR_BITS))), - byteoff, len, buf); -#else - return grub_disk_read (disk, (((grub_bfs_to_cpu32 (in->ag) - << grub_bfs_to_cpu32 (sb->log2_ag_size)) - + grub_bfs_to_cpu16 (in->start) + off) - << (grub_bfs_to_cpu32 (sb->log2_bsize) - - GRUB_DISK_SECTOR_BITS)), - byteoff, len, buf); -#endif -} - -#ifdef MODE_AFS -#define RANGE_SHIFT grub_bfs_to_cpu32 (sb->log2_bsize) -#else -#define RANGE_SHIFT 0 -#endif - -static grub_err_t -read_bfs_file (grub_disk_t disk, - const struct grub_bfs_superblock *sb, - const struct grub_bfs_inode *ino, - grub_off_t off, void *buf, grub_size_t len, - grub_disk_read_hook_t read_hook, void *read_hook_data) -{ - if (len == 0) - return GRUB_ERR_NONE; - - if (off + len > grub_bfs_to_cpu64 (ino->size)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("attempt to read past the end of file")); - - if (off < (grub_bfs_to_cpu64 (ino->max_direct_range) << RANGE_SHIFT)) - { - unsigned i; - grub_uint64_t pos = 0; - for (i = 0; i < ARRAY_SIZE (ino->direct); i++) - { - grub_uint64_t newpos; - newpos = pos + (((grub_uint64_t) grub_bfs_to_cpu16 (ino->direct[i].len)) - << grub_bfs_to_cpu32 (sb->log2_bsize)); - if (newpos > off) - { - grub_size_t read_size; - grub_err_t err; - read_size = newpos - off; - if (read_size > len) - read_size = len; - disk->read_hook = read_hook; - disk->read_hook_data = read_hook_data; - err = read_extent (disk, sb, &ino->direct[i], 0, off - pos, - buf, read_size); - disk->read_hook = 0; - if (err) - return err; - off += read_size; - len -= read_size; - buf = (char *) buf + read_size; - if (len == 0) - return GRUB_ERR_NONE; - } - pos = newpos; - } - } - - if (off < (grub_bfs_to_cpu64 (ino->max_direct_range) << RANGE_SHIFT)) - return grub_error (GRUB_ERR_BAD_FS, "incorrect direct blocks"); - - if (off < (grub_bfs_to_cpu64 (ino->max_indirect_range) << RANGE_SHIFT)) - { - unsigned i; - struct grub_bfs_extent *entries; - grub_size_t nentries; - grub_err_t err; - grub_uint64_t pos = (grub_bfs_to_cpu64 (ino->max_direct_range) - << RANGE_SHIFT); - nentries = (((grub_size_t) grub_bfs_to_cpu16 (ino->indirect.len)) - << (grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE)); - entries = grub_malloc (nentries << LOG_EXTENT_SIZE); - if (!entries) - return grub_errno; - err = read_extent (disk, sb, &ino->indirect, 0, 0, - entries, nentries << LOG_EXTENT_SIZE); - for (i = 0; i < nentries; i++) - { - grub_uint64_t newpos; - newpos = pos + (((grub_uint64_t) grub_bfs_to_cpu16 (entries[i].len)) - << grub_bfs_to_cpu32 (sb->log2_bsize)); - if (newpos > off) - { - grub_size_t read_size; - read_size = newpos - off; - if (read_size > len) - read_size = len; - disk->read_hook = read_hook; - disk->read_hook_data = read_hook_data; - err = read_extent (disk, sb, &entries[i], 0, off - pos, - buf, read_size); - disk->read_hook = 0; - if (err) - { - grub_free (entries); - return err; - } - off += read_size; - len -= read_size; - buf = (char *) buf + read_size; - if (len == 0) - { - grub_free (entries); - return GRUB_ERR_NONE; - } - } - pos = newpos; - } - grub_free (entries); - } - - if (off < (grub_bfs_to_cpu64 (ino->max_indirect_range) << RANGE_SHIFT)) - return grub_error (GRUB_ERR_BAD_FS, "incorrect indirect blocks"); - - { - struct grub_bfs_extent *l1_entries, *l2_entries; - grub_size_t nl1_entries, nl2_entries; - grub_off_t last_l1n = ~0ULL; - grub_err_t err; - nl1_entries = (((grub_uint64_t) grub_bfs_to_cpu16 (ino->double_indirect.len)) - << (grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE)); - l1_entries = grub_malloc (nl1_entries << LOG_EXTENT_SIZE); - if (!l1_entries) - return grub_errno; - nl2_entries = 0; - l2_entries = grub_malloc (1 << (DOUBLE_INDIRECT_SHIFT - + grub_bfs_to_cpu32 (sb->log2_bsize))); - if (!l2_entries) - { - grub_free (l1_entries); - return grub_errno; - } - err = read_extent (disk, sb, &ino->double_indirect, 0, 0, - l1_entries, nl1_entries << LOG_EXTENT_SIZE); - if (err) - { - grub_free (l1_entries); - grub_free (l2_entries); - return err; - } - - while (len > 0) - { - grub_off_t boff, l2n, l1n; - grub_size_t read_size; - grub_off_t double_indirect_offset; - double_indirect_offset = off - - grub_bfs_to_cpu64 (ino->max_indirect_range); - boff = (double_indirect_offset - & ((1 << (grub_bfs_to_cpu32 (sb->log2_bsize) - + DOUBLE_INDIRECT_SHIFT)) - 1)); - l2n = ((double_indirect_offset >> (grub_bfs_to_cpu32 (sb->log2_bsize) - + DOUBLE_INDIRECT_SHIFT)) - & ((1 << (grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE - + DOUBLE_INDIRECT_SHIFT)) - 1)); - l1n = - (double_indirect_offset >> - (2 * grub_bfs_to_cpu32 (sb->log2_bsize) - LOG_EXTENT_SIZE + - 2 * DOUBLE_INDIRECT_SHIFT)); - if (l1n > nl1_entries) - { - grub_free (l1_entries); - grub_free (l2_entries); - return grub_error (GRUB_ERR_BAD_FS, - "incorrect double-indirect block"); - } - if (l1n != last_l1n) - { - nl2_entries = (((grub_uint64_t) grub_bfs_to_cpu16 (l1_entries[l1n].len)) - << (grub_bfs_to_cpu32 (sb->log2_bsize) - - LOG_EXTENT_SIZE)); - if (nl2_entries > (1U << (grub_bfs_to_cpu32 (sb->log2_bsize) - - LOG_EXTENT_SIZE - + DOUBLE_INDIRECT_SHIFT))) - nl2_entries = (1 << (grub_bfs_to_cpu32 (sb->log2_bsize) - - LOG_EXTENT_SIZE - + DOUBLE_INDIRECT_SHIFT)); - err = read_extent (disk, sb, &l1_entries[l1n], 0, 0, - l2_entries, nl2_entries << LOG_EXTENT_SIZE); - if (err) - { - grub_free (l1_entries); - grub_free (l2_entries); - return err; - } - last_l1n = l1n; - } - if (l2n > nl2_entries) - { - grub_free (l1_entries); - grub_free (l2_entries); - return grub_error (GRUB_ERR_BAD_FS, - "incorrect double-indirect block"); - } - - read_size = (1 << (grub_bfs_to_cpu32 (sb->log2_bsize) - + DOUBLE_INDIRECT_SHIFT)) - boff; - if (read_size > len) - read_size = len; - disk->read_hook = read_hook; - disk->read_hook_data = read_hook_data; - err = read_extent (disk, sb, &l2_entries[l2n], 0, boff, - buf, read_size); - disk->read_hook = 0; - if (err) - { - grub_free (l1_entries); - grub_free (l2_entries); - return err; - } - off += read_size; - len -= read_size; - buf = (char *) buf + read_size; - } - grub_free (l1_entries); - grub_free (l2_entries); - return GRUB_ERR_NONE; - } -} - -static grub_err_t -read_b_node (grub_disk_t disk, - const struct grub_bfs_superblock *sb, - const struct grub_bfs_inode *ino, - grub_uint64_t node_off, - struct grub_bfs_btree_node **node, - char **key_data, grub_uint16_t **keylen_idx, - grub_unaligned_uint64_t **key_values) -{ - void *ret; - struct grub_bfs_btree_node node_head; - grub_size_t total_size; - grub_err_t err; - - *node = NULL; - *key_data = NULL; - *keylen_idx = NULL; - *key_values = NULL; - - err = read_bfs_file (disk, sb, ino, node_off, &node_head, sizeof (node_head), - 0, 0); - if (err) - return err; - - total_size = ALIGN_UP (sizeof (node_head) + - grub_bfs_to_cpu_treehead - (node_head.total_key_len), - BTREE_ALIGN) + - grub_bfs_to_cpu_treehead (node_head.count_keys) * - sizeof (grub_uint16_t) - + grub_bfs_to_cpu_treehead (node_head.count_keys) * - sizeof (grub_uint64_t); - - ret = grub_malloc (total_size); - if (!ret) - return grub_errno; - - err = read_bfs_file (disk, sb, ino, node_off, ret, total_size, 0, 0); - if (err) - { - grub_free (ret); - return err; - } - - *node = ret; - *key_data = (char *) ret + sizeof (node_head); - *keylen_idx = (grub_uint16_t *) ret - + ALIGN_UP (sizeof (node_head) + - grub_bfs_to_cpu_treehead (node_head.total_key_len), - BTREE_ALIGN) / 2; - *key_values = (grub_unaligned_uint64_t *) - (*keylen_idx + - grub_bfs_to_cpu_treehead (node_head.count_keys)); - - return GRUB_ERR_NONE; -} - -static int -iterate_in_b_tree (grub_disk_t disk, - const struct grub_bfs_superblock *sb, - const struct grub_bfs_inode *ino, - int (*hook) (const char *name, grub_uint64_t value, - struct grub_bfs_dir_ctx *ctx), - struct grub_bfs_dir_ctx *ctx) -{ - struct grub_bfs_btree_header head; - grub_err_t err; - int level; - grub_uint64_t node_off; - - err = read_bfs_file (disk, sb, ino, 0, &head, sizeof (head), 0, 0); - if (err) - return 0; - node_off = grub_bfs_to_cpu64 (head.root); - - level = grub_bfs_to_cpu32 (head.level) - 1; - while (level--) - { - struct grub_bfs_btree_node node; - grub_uint64_t key_value; - err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), - 0, 0); - if (err) - return 0; - err = read_bfs_file (disk, sb, ino, node_off - + ALIGN_UP (sizeof (node) + - grub_bfs_to_cpu_treehead (node. - total_key_len), - BTREE_ALIGN) + - grub_bfs_to_cpu_treehead (node.count_keys) * - sizeof (grub_uint16_t), &key_value, - sizeof (grub_uint64_t), 0, 0); - if (err) - return 0; - - node_off = grub_bfs_to_cpu64 (key_value); - } - - while (1) - { - struct grub_bfs_btree_node *node; - char *key_data; - grub_uint16_t *keylen_idx; - grub_unaligned_uint64_t *key_values; - unsigned i; - grub_uint16_t start = 0, end = 0; - - err = read_b_node (disk, sb, ino, - node_off, - &node, - &key_data, - &keylen_idx, - &key_values); - - if (err) - return 0; - - for (i = 0; i < grub_bfs_to_cpu_treehead (node->count_keys); i++) - { - char c; - start = end; - end = grub_bfs_to_cpu16 (keylen_idx[i]); - if (grub_bfs_to_cpu_treehead (node->total_key_len) <= end) - end = grub_bfs_to_cpu_treehead (node->total_key_len); - c = key_data[end]; - key_data[end] = 0; - if (hook (key_data + start, grub_bfs_to_cpu64 (key_values[i].val), - ctx)) - { - grub_free (node); - return 1; - } - key_data[end] = c; - } - node_off = grub_bfs_to_cpu64 (node->right); - grub_free (node); - if (node_off == POINTER_INVALID) - return 0; - } -} - -static int -bfs_strcmp (const char *a, const char *b, grub_size_t alen) -{ - char ac, bc; - while (*b && alen) - { - if (*a != *b) - break; - - a++; - b++; - alen--; - } - - ac = alen ? *a : 0; - bc = *b; - -#ifdef MODE_AFS - return (int) (grub_int8_t) ac - (int) (grub_int8_t) bc; -#else - return (int) (grub_uint8_t) ac - (int) (grub_uint8_t) bc; -#endif -} - -static grub_err_t -find_in_b_tree (grub_disk_t disk, - const struct grub_bfs_superblock *sb, - const struct grub_bfs_inode *ino, const char *name, - grub_uint64_t * res) -{ - struct grub_bfs_btree_header head; - grub_err_t err; - int level; - grub_uint64_t node_off; - - err = read_bfs_file (disk, sb, ino, 0, &head, sizeof (head), 0, 0); - if (err) - return err; - node_off = grub_bfs_to_cpu64 (head.root); - - level = grub_bfs_to_cpu32 (head.level) - 1; - while (1) - { - struct grub_bfs_btree_node *node; - char *key_data; - grub_uint16_t *keylen_idx; - grub_unaligned_uint64_t *key_values; - int lg, j; - unsigned i; - - err = read_b_node (disk, sb, ino, node_off, &node, &key_data, &keylen_idx, &key_values); - if (err) - return err; - - if (node->count_keys == 0) - { - grub_free (node); - return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), - name); - } - - for (lg = 0; grub_bfs_to_cpu_treehead (node->count_keys) >> lg; lg++); - - i = 0; - - for (j = lg - 1; j >= 0; j--) - { - int cmp; - grub_uint16_t start = 0, end = 0; - if ((i | (1 << j)) >= grub_bfs_to_cpu_treehead (node->count_keys)) - continue; - start = grub_bfs_to_cpu16 (keylen_idx[(i | (1 << j)) - 1]); - end = grub_bfs_to_cpu16 (keylen_idx[(i | (1 << j))]); - if (grub_bfs_to_cpu_treehead (node->total_key_len) <= end) - end = grub_bfs_to_cpu_treehead (node->total_key_len); - cmp = bfs_strcmp (key_data + start, name, end - start); - if (cmp == 0 && level == 0) - { - *res = grub_bfs_to_cpu64 (key_values[i | (1 << j)].val); - grub_free (node); - return GRUB_ERR_NONE; - } -#ifdef MODE_AFS - if (cmp <= 0) -#else - if (cmp < 0) -#endif - i |= (1 << j); - } - if (i == 0) - { - grub_uint16_t end = 0; - int cmp; - end = grub_bfs_to_cpu16 (keylen_idx[0]); - if (grub_bfs_to_cpu_treehead (node->total_key_len) <= end) - end = grub_bfs_to_cpu_treehead (node->total_key_len); - cmp = bfs_strcmp (key_data, name, end); - if (cmp == 0 && level == 0) - { - *res = grub_bfs_to_cpu64 (key_values[0].val); - grub_free (node); - return GRUB_ERR_NONE; - } -#ifdef MODE_AFS - if (cmp > 0 && level != 0) -#else - if (cmp >= 0 && level != 0) -#endif - { - node_off = grub_bfs_to_cpu64 (key_values[0].val); - level--; - grub_free (node); - continue; - } - else if (level != 0 - && grub_bfs_to_cpu_treehead (node->count_keys) >= 2) - { - node_off = grub_bfs_to_cpu64 (key_values[1].val); - level--; - grub_free (node); - continue; - } - } - else if (level != 0 - && i + 1 < grub_bfs_to_cpu_treehead (node->count_keys)) - { - node_off = grub_bfs_to_cpu64 (key_values[i + 1].val); - level--; - grub_free (node); - continue; - } - if (node->overflow != POINTER_INVALID) - { - node_off = grub_bfs_to_cpu64 (node->overflow); - /* This level-- isn't specified but is needed. */ - level--; - grub_free (node); - continue; - } - grub_free (node); - return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), - name); - } -} - -struct grub_fshelp_node -{ - grub_disk_t disk; - const struct grub_bfs_superblock *sb; - struct grub_bfs_inode ino; -}; - -static grub_err_t -lookup_file (grub_fshelp_node_t dir, - const char *name, - grub_fshelp_node_t *foundnode, - enum grub_fshelp_filetype *foundtype) -{ - grub_err_t err; - struct grub_bfs_inode *new_ino; - grub_uint64_t res = 0; - - err = find_in_b_tree (dir->disk, dir->sb, &dir->ino, name, &res); - if (err) - return err; - - *foundnode = grub_malloc (sizeof (struct grub_fshelp_node)); - if (!*foundnode) - return grub_errno; - - (*foundnode)->disk = dir->disk; - (*foundnode)->sb = dir->sb; - new_ino = &(*foundnode)->ino; - - if (grub_disk_read (dir->disk, res - << (grub_bfs_to_cpu32 (dir->sb->log2_bsize) - - GRUB_DISK_SECTOR_BITS), 0, - sizeof (*new_ino), (char *) new_ino)) - { - grub_free (*foundnode); - return grub_errno; - } - switch (grub_bfs_to_cpu32 (new_ino->mode) & ATTR_TYPE) - { - default: - case ATTR_REG: - *foundtype = GRUB_FSHELP_REG; - break; - case ATTR_DIR: - *foundtype = GRUB_FSHELP_DIR; - break; - case ATTR_LNK: - *foundtype = GRUB_FSHELP_SYMLINK; - break; - } - return GRUB_ERR_NONE; -} - -static char * -read_symlink (grub_fshelp_node_t node) -{ - char *alloc = NULL; - grub_err_t err; - -#ifndef MODE_AFS - if (!(grub_bfs_to_cpu32 (node->ino.flags) & LONG_SYMLINK)) - { - alloc = grub_malloc (sizeof (node->ino.inplace_link) + 1); - if (!alloc) - { - return NULL; - } - grub_memcpy (alloc, node->ino.inplace_link, - sizeof (node->ino.inplace_link)); - alloc[sizeof (node->ino.inplace_link)] = 0; - } - else -#endif - { - grub_size_t symsize = grub_bfs_to_cpu64 (node->ino.size); - alloc = grub_malloc (symsize + 1); - if (!alloc) - return NULL; - err = read_bfs_file (node->disk, node->sb, &node->ino, 0, alloc, symsize, 0, 0); - if (err) - { - grub_free (alloc); - return NULL; - } - alloc[symsize] = 0; - } - - return alloc; -} - -static grub_err_t -find_file (const char *path, grub_disk_t disk, - const struct grub_bfs_superblock *sb, struct grub_bfs_inode *ino, - enum grub_fshelp_filetype exptype) -{ - grub_err_t err; - struct grub_fshelp_node root = { - .disk = disk, - .sb = sb, - }; - struct grub_fshelp_node *found = NULL; - - err = read_extent (disk, sb, &sb->root_dir, 0, 0, &root.ino, - sizeof (root.ino)); - if (err) - return err; - err = grub_fshelp_find_file_lookup (path, &root, &found, lookup_file, read_symlink, exptype); - if (!err) - grub_memcpy (ino, &found->ino, sizeof (*ino)); - - if (&root != found) - grub_free (found); - return err; -} - -static grub_err_t -mount (grub_disk_t disk, struct grub_bfs_superblock *sb) -{ - grub_err_t err; - err = grub_disk_read (disk, SUPERBLOCK, 0, sizeof (*sb), sb); - if (err == GRUB_ERR_OUT_OF_RANGE) - return grub_error (GRUB_ERR_BAD_FS, -#ifdef MODE_AFS - "not an AFS filesystem" -#else - "not a BFS filesystem" -#endif - ); - if (err) - return err; - if (sb->magic1 != grub_cpu_to_bfs32_compile_time (SUPER_BLOCK_MAGIC1) - || sb->magic2 != grub_cpu_to_bfs32_compile_time (SUPER_BLOCK_MAGIC2) - || sb->magic3 != grub_cpu_to_bfs32_compile_time (SUPER_BLOCK_MAGIC3) - || sb->bsize == 0 - || (grub_bfs_to_cpu32 (sb->bsize) - != (1U << grub_bfs_to_cpu32 (sb->log2_bsize))) - || grub_bfs_to_cpu32 (sb->log2_bsize) < GRUB_DISK_SECTOR_BITS) - return grub_error (GRUB_ERR_BAD_FS, -#ifdef MODE_AFS - "not an AFS filesystem" -#else - "not a BFS filesystem" -#endif - ); - return GRUB_ERR_NONE; -} - -/* Helper for grub_bfs_dir. */ -static int -grub_bfs_dir_iter (const char *name, grub_uint64_t value, - struct grub_bfs_dir_ctx *ctx) -{ - grub_err_t err2; - struct grub_bfs_inode ino; - struct grub_dirhook_info info; - - err2 = grub_disk_read (ctx->device->disk, value - << (grub_bfs_to_cpu32 (ctx->sb.log2_bsize) - - GRUB_DISK_SECTOR_BITS), 0, - sizeof (ino), (char *) &ino); - if (err2) - { - grub_print_error (); - return 0; - } - - info.mtimeset = 1; -#ifdef MODE_AFS - info.mtime = - grub_divmod64 (grub_bfs_to_cpu64 (ino.mtime), 1000000, 0); -#else - info.mtime = grub_bfs_to_cpu64 (ino.mtime) >> 16; -#endif - info.dir = ((grub_bfs_to_cpu32 (ino.mode) & ATTR_TYPE) == ATTR_DIR); - return ctx->hook (name, &info, ctx->hook_data); -} - -static grub_err_t -grub_bfs_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_bfs_dir_ctx ctx = { - .device = device, - .hook = hook, - .hook_data = hook_data - }; - grub_err_t err; - - err = mount (device->disk, &ctx.sb); - if (err) - return err; - - { - struct grub_bfs_inode ino; - err = find_file (path, device->disk, &ctx.sb, &ino, GRUB_FSHELP_DIR); - if (err) - return err; - iterate_in_b_tree (device->disk, &ctx.sb, &ino, grub_bfs_dir_iter, - &ctx); - } - - return grub_errno; -} - -static grub_err_t -grub_bfs_open (struct grub_file *file, const char *name) -{ - struct grub_bfs_superblock sb; - grub_err_t err; - - err = mount (file->device->disk, &sb); - if (err) - return err; - - { - struct grub_bfs_inode ino; - struct grub_bfs_data *data; - err = find_file (name, file->device->disk, &sb, &ino, GRUB_FSHELP_REG); - if (err) - return err; - - data = grub_zalloc (sizeof (struct grub_bfs_data)); - if (!data) - return grub_errno; - data->sb = sb; - grub_memcpy (&data->ino, &ino, sizeof (data->ino)); - file->data = data; - file->size = grub_bfs_to_cpu64 (ino.size); - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_bfs_close (grub_file_t file) -{ - grub_free (file->data); - - return GRUB_ERR_NONE; -} - -static grub_ssize_t -grub_bfs_read (grub_file_t file, char *buf, grub_size_t len) -{ - grub_err_t err; - struct grub_bfs_data *data = file->data; - - err = read_bfs_file (file->device->disk, &data->sb, - &data->ino, file->offset, buf, len, - file->read_hook, file->read_hook_data); - if (err) - return -1; - return len; -} - -static grub_err_t -grub_bfs_label (grub_device_t device, char **label) -{ - struct grub_bfs_superblock sb; - grub_err_t err; - - *label = 0; - - err = mount (device->disk, &sb); - if (err) - return err; - - *label = grub_strndup (sb.label, sizeof (sb.label)); - return GRUB_ERR_NONE; -} - -#ifndef MODE_AFS -static grub_ssize_t -read_bfs_attr (grub_disk_t disk, - const struct grub_bfs_superblock *sb, - struct grub_bfs_inode *ino, - const char *name, void *buf, grub_size_t len) -{ - grub_uint8_t *ptr = (grub_uint8_t *) ino->small_data; - grub_uint8_t *end = ((grub_uint8_t *) ino + grub_bfs_to_cpu32 (sb->bsize)); - - while (ptr + sizeof (struct grub_bfs_small_data_element_header) < end) - { - struct grub_bfs_small_data_element_header *el; - char *el_name; - grub_uint8_t *data; - el = (struct grub_bfs_small_data_element_header *) ptr; - if (el->name_len == 0) - break; - el_name = (char *) (el + 1); - data = (grub_uint8_t *) el_name + grub_bfs_to_cpu16 (el->name_len) + 3; - ptr = data + grub_bfs_to_cpu16 (el->value_len) + 1; - if (grub_memcmp (name, el_name, grub_bfs_to_cpu16 (el->name_len)) == 0 - && name[el->name_len] == 0) - { - grub_size_t copy; - copy = len; - if (grub_bfs_to_cpu16 (el->value_len) > copy) - copy = grub_bfs_to_cpu16 (el->value_len); - grub_memcpy (buf, data, copy); - return copy; - } - } - - if (ino->attr.len != 0) - { - grub_size_t read; - grub_err_t err; - grub_uint64_t res; - - err = read_extent (disk, sb, &ino->attr, 0, 0, ino, - grub_bfs_to_cpu32 (sb->bsize)); - if (err) - return -1; - - err = find_in_b_tree (disk, sb, ino, name, &res); - if (err) - return -1; - grub_disk_read (disk, res - << (grub_bfs_to_cpu32 (sb->log2_bsize) - - GRUB_DISK_SECTOR_BITS), 0, - grub_bfs_to_cpu32 (sb->bsize), (char *) ino); - read = grub_bfs_to_cpu64 (ino->size); - if (read > len) - read = len; - - err = read_bfs_file (disk, sb, ino, 0, buf, read, 0, 0); - if (err) - return -1; - return read; - } - return -1; -} - -static grub_err_t -grub_bfs_uuid (grub_device_t device, char **uuid) -{ - struct grub_bfs_superblock sb; - grub_err_t err; - struct grub_bfs_inode *ino; - grub_uint64_t vid; - - *uuid = 0; - - err = mount (device->disk, &sb); - if (err) - return err; - - ino = grub_malloc (grub_bfs_to_cpu32 (sb.bsize)); - if (!ino) - return grub_errno; - - err = read_extent (device->disk, &sb, &sb.root_dir, 0, 0, - ino, grub_bfs_to_cpu32 (sb.bsize)); - if (err) - { - grub_free (ino); - return err; - } - if (read_bfs_attr (device->disk, &sb, ino, "be:volume_id", - &vid, sizeof (vid)) == sizeof (vid)) - *uuid = - grub_xasprintf ("%016" PRIxGRUB_UINT64_T, grub_bfs_to_cpu64 (vid)); - - grub_free (ino); - - return GRUB_ERR_NONE; -} -#endif - -static struct grub_fs grub_bfs_fs = { -#ifdef MODE_AFS - .name = "afs", -#else - .name = "bfs", -#endif - .fs_dir = grub_bfs_dir, - .fs_open = grub_bfs_open, - .fs_read = grub_bfs_read, - .fs_close = grub_bfs_close, - .fs_label = grub_bfs_label, -#ifndef MODE_AFS - .fs_uuid = grub_bfs_uuid, -#endif -#ifdef GRUB_UTIL - .reserved_first_sector = 1, - .blocklist_install = 1, -#endif -}; - -#ifdef MODE_AFS -GRUB_MOD_INIT (afs) -#else -GRUB_MOD_INIT (bfs) -#endif -{ - COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE == - sizeof (struct grub_bfs_extent)); - if (!grub_is_lockdown ()) - { - grub_bfs_fs.mod = mod; - grub_fs_register (&grub_bfs_fs); - } -} - -#ifdef MODE_AFS -GRUB_MOD_FINI (afs) -#else -GRUB_MOD_FINI (bfs) -#endif -{ - if (!grub_is_lockdown ()) - grub_fs_unregister (&grub_bfs_fs); -} diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c deleted file mode 100644 index 7bf8d922f..000000000 --- a/grub-core/fs/btrfs.c +++ /dev/null @@ -1,2449 +0,0 @@ -/* btrfs.c - B-tree file system. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -/* - * Tell zstd to expose functions that aren't part of the stable API, which - * aren't safe to use when linking against a dynamic library. We vendor in a - * specific zstd version, so we know what we're getting. We need these unstable - * functions to provide our own allocator, which uses grub_malloc(), to zstd. - */ -#define ZSTD_STATIC_LINKING_ONLY - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define GRUB_BTRFS_SIGNATURE "_BHRfS_M" - -/* From http://www.oberhumer.com/opensource/lzo/lzofaq.php - * LZO will expand incompressible data by a little amount. I still haven't - * computed the exact values, but I suggest using these formulas for - * a worst-case expansion calculation: - * - * output_block_size = input_block_size + (input_block_size / 16) + 64 + 3 - * */ -#define GRUB_BTRFS_LZO_BLOCK_SIZE 4096 -#define GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE (GRUB_BTRFS_LZO_BLOCK_SIZE + \ - (GRUB_BTRFS_LZO_BLOCK_SIZE / 16) + 64 + 3) - -#define ZSTD_BTRFS_MAX_WINDOWLOG 17 -#define ZSTD_BTRFS_MAX_INPUT (1 << ZSTD_BTRFS_MAX_WINDOWLOG) - -typedef grub_uint8_t grub_btrfs_checksum_t[0x20]; -typedef grub_uint16_t grub_btrfs_uuid_t[8]; - -struct grub_btrfs_device -{ - grub_uint64_t device_id; - grub_uint64_t size; - grub_uint8_t dummy[0x62 - 0x10]; -} GRUB_PACKED; - -struct grub_btrfs_superblock -{ - grub_btrfs_checksum_t checksum; - grub_btrfs_uuid_t uuid; - grub_uint8_t dummy[0x10]; - grub_uint8_t signature[sizeof (GRUB_BTRFS_SIGNATURE) - 1]; - grub_uint64_t generation; - grub_uint64_t root_tree; - grub_uint64_t chunk_tree; - grub_uint8_t dummy2[0x20]; - grub_uint64_t root_dir_objectid; - grub_uint8_t dummy3[0x41]; - struct grub_btrfs_device this_device; - char label[0x100]; - grub_uint8_t dummy4[0x100]; - grub_uint8_t bootstrap_mapping[0x800]; -} GRUB_PACKED; - -struct btrfs_header -{ - grub_btrfs_checksum_t checksum; - grub_btrfs_uuid_t uuid; - grub_uint64_t bytenr; - grub_uint8_t dummy[0x28]; - grub_uint32_t nitems; - grub_uint8_t level; -} GRUB_PACKED; - -struct grub_btrfs_device_desc -{ - grub_device_t dev; - grub_uint64_t id; -}; - -struct grub_btrfs_data -{ - struct grub_btrfs_superblock sblock; - grub_uint64_t tree; - grub_uint64_t inode; - - struct grub_btrfs_device_desc *devices_attached; - unsigned n_devices_attached; - unsigned n_devices_allocated; - - /* Cached extent data. */ - grub_uint64_t extstart; - grub_uint64_t extend; - grub_uint64_t extino; - grub_uint64_t exttree; - grub_size_t extsize; - struct grub_btrfs_extent_data *extent; -}; - -struct grub_btrfs_chunk_item -{ - grub_uint64_t size; - grub_uint64_t dummy; - grub_uint64_t stripe_length; - grub_uint64_t type; -#define GRUB_BTRFS_CHUNK_TYPE_BITS_DONTCARE 0x07 -#define GRUB_BTRFS_CHUNK_TYPE_SINGLE 0x00 -#define GRUB_BTRFS_CHUNK_TYPE_RAID0 0x08 -#define GRUB_BTRFS_CHUNK_TYPE_RAID1 0x10 -#define GRUB_BTRFS_CHUNK_TYPE_DUPLICATED 0x20 -#define GRUB_BTRFS_CHUNK_TYPE_RAID10 0x40 -#define GRUB_BTRFS_CHUNK_TYPE_RAID5 0x80 -#define GRUB_BTRFS_CHUNK_TYPE_RAID6 0x100 -#define GRUB_BTRFS_CHUNK_TYPE_RAID1C3 0x200 -#define GRUB_BTRFS_CHUNK_TYPE_RAID1C4 0x400 - grub_uint8_t dummy2[0xc]; - grub_uint16_t nstripes; - grub_uint16_t nsubstripes; -} GRUB_PACKED; - -struct grub_btrfs_chunk_stripe -{ - grub_uint64_t device_id; - grub_uint64_t offset; - grub_btrfs_uuid_t device_uuid; -} GRUB_PACKED; - -struct grub_btrfs_leaf_node -{ - struct grub_btrfs_key key; - grub_uint32_t offset; - grub_uint32_t size; -} GRUB_PACKED; - -struct grub_btrfs_internal_node -{ - struct grub_btrfs_key key; - grub_uint64_t addr; - grub_uint64_t dummy; -} GRUB_PACKED; - -struct grub_btrfs_dir_item -{ - struct grub_btrfs_key key; - grub_uint8_t dummy[8]; - grub_uint16_t m; - grub_uint16_t n; -#define GRUB_BTRFS_DIR_ITEM_TYPE_REGULAR 1 -#define GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY 2 -#define GRUB_BTRFS_DIR_ITEM_TYPE_SYMLINK 7 - grub_uint8_t type; - char name[0]; -} GRUB_PACKED; - -struct grub_btrfs_leaf_descriptor -{ - unsigned depth; - unsigned allocated; - struct - { - grub_disk_addr_t addr; - unsigned iter; - unsigned maxiter; - int leaf; - } *data; -}; - -struct grub_btrfs_time -{ - grub_int64_t sec; - grub_uint32_t nanosec; -} GRUB_PACKED; - -struct grub_btrfs_inode -{ - grub_uint8_t dummy1[0x10]; - grub_uint64_t size; - grub_uint8_t dummy2[0x70]; - struct grub_btrfs_time mtime; -} GRUB_PACKED; - -struct grub_btrfs_extent_data -{ - grub_uint64_t dummy; - grub_uint64_t size; - grub_uint8_t compression; - grub_uint8_t encryption; - grub_uint16_t encoding; - grub_uint8_t type; - union - { - char inl[0]; - struct - { - grub_uint64_t laddr; - grub_uint64_t compressed_size; - grub_uint64_t offset; - grub_uint64_t filled; - }; - }; -} GRUB_PACKED; - -#define GRUB_BTRFS_EXTENT_INLINE 0 -#define GRUB_BTRFS_EXTENT_REGULAR 1 - -#define GRUB_BTRFS_COMPRESSION_NONE 0 -#define GRUB_BTRFS_COMPRESSION_ZLIB 1 -#define GRUB_BTRFS_COMPRESSION_LZO 2 -#define GRUB_BTRFS_COMPRESSION_ZSTD 3 - -#define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100 - -static grub_disk_addr_t superblock_sectors[] = { 64 * 2, 64 * 1024 * 2, - 256 * 1048576 * 2, 1048576ULL * 1048576ULL * 2 -}; - -static grub_err_t -grub_btrfs_read_logical (struct grub_btrfs_data *data, - grub_disk_addr_t addr, void *buf, grub_size_t size, - int recursion_depth); - -static grub_err_t -read_sblock (grub_disk_t disk, struct grub_btrfs_superblock *sb) -{ - struct grub_btrfs_superblock sblock; - unsigned i; - grub_err_t err = GRUB_ERR_NONE; - for (i = 0; i < ARRAY_SIZE (superblock_sectors); i++) - { - /* Don't try additional superblocks beyond device size. */ - if (i && (grub_le_to_cpu64 (sblock.this_device.size) - >> GRUB_DISK_SECTOR_BITS) <= superblock_sectors[i]) - break; - err = grub_disk_read (disk, superblock_sectors[i], 0, - sizeof (sblock), &sblock); - if (err == GRUB_ERR_OUT_OF_RANGE) - break; - - if (grub_memcmp ((char *) sblock.signature, GRUB_BTRFS_SIGNATURE, - sizeof (GRUB_BTRFS_SIGNATURE) - 1) != 0) - break; - if (i == 0 || grub_le_to_cpu64 (sblock.generation) - > grub_le_to_cpu64 (sb->generation)) - grub_memcpy (sb, &sblock, sizeof (sblock)); - } - - if ((err == GRUB_ERR_OUT_OF_RANGE || !err) && i == 0) - return grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem"); - - if (err == GRUB_ERR_OUT_OF_RANGE) - grub_errno = err = GRUB_ERR_NONE; - - return err; -} - -static int -key_cmp (const struct grub_btrfs_key *a, const struct grub_btrfs_key *b) -{ - if (grub_le_to_cpu64 (a->object_id) < grub_le_to_cpu64 (b->object_id)) - return -1; - if (grub_le_to_cpu64 (a->object_id) > grub_le_to_cpu64 (b->object_id)) - return +1; - - if (a->type < b->type) - return -1; - if (a->type > b->type) - return +1; - - if (grub_le_to_cpu64 (a->offset) < grub_le_to_cpu64 (b->offset)) - return -1; - if (grub_le_to_cpu64 (a->offset) > grub_le_to_cpu64 (b->offset)) - return +1; - return 0; -} - -static void -free_iterator (struct grub_btrfs_leaf_descriptor *desc) -{ - grub_free (desc->data); -} - -static grub_err_t -check_btrfs_header (struct grub_btrfs_data *data, struct btrfs_header *header, - grub_disk_addr_t addr) -{ - if (grub_le_to_cpu64 (header->bytenr) != addr) - { - grub_dprintf ("btrfs", "btrfs_header.bytenr is not equal node addr\n"); - return grub_error (GRUB_ERR_BAD_FS, - "header bytenr is not equal node addr"); - } - if (grub_memcmp (data->sblock.uuid, header->uuid, sizeof(grub_btrfs_uuid_t))) - { - grub_dprintf ("btrfs", "btrfs_header.uuid doesn't match sblock uuid\n"); - return grub_error (GRUB_ERR_BAD_FS, - "header uuid doesn't match sblock uuid"); - } - return GRUB_ERR_NONE; -} - -static grub_err_t -save_ref (struct grub_btrfs_leaf_descriptor *desc, - grub_disk_addr_t addr, unsigned i, unsigned m, int l) -{ - desc->depth++; - if (desc->allocated < desc->depth) - { - void *newdata; - grub_size_t sz; - - if (grub_mul (desc->allocated, 2, &desc->allocated) || - grub_mul (desc->allocated, sizeof (desc->data[0]), &sz)) - return GRUB_ERR_OUT_OF_RANGE; - - newdata = grub_realloc (desc->data, sz); - if (!newdata) - return grub_errno; - desc->data = newdata; - } - desc->data[desc->depth - 1].addr = addr; - desc->data[desc->depth - 1].iter = i; - desc->data[desc->depth - 1].maxiter = m; - desc->data[desc->depth - 1].leaf = l; - return GRUB_ERR_NONE; -} - -static int -next (struct grub_btrfs_data *data, - struct grub_btrfs_leaf_descriptor *desc, - grub_disk_addr_t * outaddr, grub_size_t * outsize, - struct grub_btrfs_key *key_out) -{ - grub_err_t err; - struct grub_btrfs_leaf_node leaf; - - for (; desc->depth > 0; desc->depth--) - { - desc->data[desc->depth - 1].iter++; - if (desc->data[desc->depth - 1].iter - < desc->data[desc->depth - 1].maxiter) - break; - } - if (desc->depth == 0) - return 0; - while (!desc->data[desc->depth - 1].leaf) - { - struct grub_btrfs_internal_node node; - struct btrfs_header head; - - err = grub_btrfs_read_logical (data, desc->data[desc->depth - 1].iter - * sizeof (node) - + sizeof (struct btrfs_header) - + desc->data[desc->depth - 1].addr, - &node, sizeof (node), 0); - if (err) - return -err; - - err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (node.addr), - &head, sizeof (head), 0); - if (err) - return -err; - check_btrfs_header (data, &head, grub_le_to_cpu64 (node.addr)); - - save_ref (desc, grub_le_to_cpu64 (node.addr), 0, - grub_le_to_cpu32 (head.nitems), !head.level); - } - err = grub_btrfs_read_logical (data, desc->data[desc->depth - 1].iter - * sizeof (leaf) - + sizeof (struct btrfs_header) - + desc->data[desc->depth - 1].addr, &leaf, - sizeof (leaf), 0); - if (err) - return -err; - *outsize = grub_le_to_cpu32 (leaf.size); - *outaddr = desc->data[desc->depth - 1].addr + sizeof (struct btrfs_header) - + grub_le_to_cpu32 (leaf.offset); - *key_out = leaf.key; - return 1; -} - -static grub_err_t -lower_bound (struct grub_btrfs_data *data, - const struct grub_btrfs_key *key_in, - struct grub_btrfs_key *key_out, - grub_uint64_t root, - grub_disk_addr_t *outaddr, grub_size_t *outsize, - struct grub_btrfs_leaf_descriptor *desc, - int recursion_depth) -{ - grub_disk_addr_t addr = grub_le_to_cpu64 (root); - int depth = -1; - - if (desc) - { - desc->allocated = 16; - desc->depth = 0; - desc->data = grub_calloc (desc->allocated, sizeof (desc->data[0])); - if (!desc->data) - return grub_errno; - } - - /* > 2 would work as well but be robust and allow a bit more just in case. - */ - if (recursion_depth > 10) - return grub_error (GRUB_ERR_BAD_FS, "too deep btrfs virtual nesting"); - - grub_dprintf ("btrfs", - "retrieving %" PRIxGRUB_UINT64_T - " %x %" PRIxGRUB_UINT64_T "\n", - key_in->object_id, key_in->type, key_in->offset); - - while (1) - { - grub_err_t err; - struct btrfs_header head; - - reiter: - depth++; - /* FIXME: preread few nodes into buffer. */ - err = grub_btrfs_read_logical (data, addr, &head, sizeof (head), - recursion_depth + 1); - if (err) - return err; - check_btrfs_header (data, &head, addr); - addr += sizeof (head); - if (head.level) - { - unsigned i; - struct grub_btrfs_internal_node node, node_last; - int have_last = 0; - grub_memset (&node_last, 0, sizeof (node_last)); - for (i = 0; i < grub_le_to_cpu32 (head.nitems); i++) - { - err = grub_btrfs_read_logical (data, addr + i * sizeof (node), - &node, sizeof (node), - recursion_depth + 1); - if (err) - return err; - - grub_dprintf ("btrfs", - "internal node (depth %d) %" PRIxGRUB_UINT64_T - " %x %" PRIxGRUB_UINT64_T "\n", depth, - node.key.object_id, node.key.type, - node.key.offset); - - if (key_cmp (&node.key, key_in) == 0) - { - err = GRUB_ERR_NONE; - if (desc) - err = save_ref (desc, addr - sizeof (head), i, - grub_le_to_cpu32 (head.nitems), 0); - if (err) - return err; - addr = grub_le_to_cpu64 (node.addr); - goto reiter; - } - if (key_cmp (&node.key, key_in) > 0) - break; - node_last = node; - have_last = 1; - } - if (have_last) - { - err = GRUB_ERR_NONE; - if (desc) - err = save_ref (desc, addr - sizeof (head), i - 1, - grub_le_to_cpu32 (head.nitems), 0); - if (err) - return err; - addr = grub_le_to_cpu64 (node_last.addr); - goto reiter; - } - *outsize = 0; - *outaddr = 0; - grub_memset (key_out, 0, sizeof (*key_out)); - if (desc) - return save_ref (desc, addr - sizeof (head), -1, - grub_le_to_cpu32 (head.nitems), 0); - return GRUB_ERR_NONE; - } - { - unsigned i; - struct grub_btrfs_leaf_node leaf, leaf_last; - int have_last = 0; - for (i = 0; i < grub_le_to_cpu32 (head.nitems); i++) - { - err = grub_btrfs_read_logical (data, addr + i * sizeof (leaf), - &leaf, sizeof (leaf), - recursion_depth + 1); - if (err) - return err; - - grub_dprintf ("btrfs", - "leaf (depth %d) %" PRIxGRUB_UINT64_T - " %x %" PRIxGRUB_UINT64_T "\n", depth, - leaf.key.object_id, leaf.key.type, leaf.key.offset); - - if (key_cmp (&leaf.key, key_in) == 0) - { - grub_memcpy (key_out, &leaf.key, sizeof (*key_out)); - *outsize = grub_le_to_cpu32 (leaf.size); - *outaddr = addr + grub_le_to_cpu32 (leaf.offset); - if (desc) - return save_ref (desc, addr - sizeof (head), i, - grub_le_to_cpu32 (head.nitems), 1); - return GRUB_ERR_NONE; - } - - if (key_cmp (&leaf.key, key_in) > 0) - break; - - have_last = 1; - leaf_last = leaf; - } - - if (have_last) - { - grub_memcpy (key_out, &leaf_last.key, sizeof (*key_out)); - *outsize = grub_le_to_cpu32 (leaf_last.size); - *outaddr = addr + grub_le_to_cpu32 (leaf_last.offset); - if (desc) - return save_ref (desc, addr - sizeof (head), i - 1, - grub_le_to_cpu32 (head.nitems), 1); - return GRUB_ERR_NONE; - } - *outsize = 0; - *outaddr = 0; - grub_memset (key_out, 0, sizeof (*key_out)); - if (desc) - return save_ref (desc, addr - sizeof (head), -1, - grub_le_to_cpu32 (head.nitems), 1); - return GRUB_ERR_NONE; - } - } -} - -/* Context for find_device. */ -struct find_device_ctx -{ - struct grub_btrfs_data *data; - grub_uint64_t id; - grub_device_t dev_found; -}; - -/* Helper for find_device. */ -static int -find_device_iter (const char *name, void *data) -{ - struct find_device_ctx *ctx = data; - grub_device_t dev; - grub_err_t err; - struct grub_btrfs_superblock sb; - - dev = grub_device_open (name); - if (!dev) - return 0; - if (!dev->disk) - { - grub_device_close (dev); - return 0; - } - err = read_sblock (dev->disk, &sb); - if (err == GRUB_ERR_BAD_FS) - { - grub_device_close (dev); - grub_errno = GRUB_ERR_NONE; - return 0; - } - if (err) - { - grub_device_close (dev); - grub_print_error (); - return 0; - } - if (grub_memcmp (ctx->data->sblock.uuid, sb.uuid, sizeof (sb.uuid)) != 0 - || sb.this_device.device_id != ctx->id) - { - grub_device_close (dev); - return 0; - } - - ctx->dev_found = dev; - return 1; -} - -static grub_device_t -find_device (struct grub_btrfs_data *data, grub_uint64_t id) -{ - struct find_device_ctx ctx = { - .data = data, - .id = id, - .dev_found = NULL - }; - unsigned i; - - for (i = 0; i < data->n_devices_attached; i++) - if (id == data->devices_attached[i].id) - return data->devices_attached[i].dev; - - grub_device_iterate (find_device_iter, &ctx); - - data->n_devices_attached++; - if (data->n_devices_attached > data->n_devices_allocated) - { - void *tmp; - grub_size_t sz; - - if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) || - grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) || - grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz)) - goto fail; - - data->devices_attached = grub_realloc (tmp = data->devices_attached, sz); - if (!data->devices_attached) - { - data->devices_attached = tmp; - - fail: - if (ctx.dev_found) - grub_device_close (ctx.dev_found); - return NULL; - } - } - data->devices_attached[data->n_devices_attached - 1].id = id; - data->devices_attached[data->n_devices_attached - 1].dev = ctx.dev_found; - return ctx.dev_found; -} - -static grub_err_t -btrfs_read_from_chunk (struct grub_btrfs_data *data, - struct grub_btrfs_chunk_item *chunk, - grub_uint64_t stripen, grub_uint64_t stripe_offset, - int redundancy, grub_uint64_t csize, - void *buf) -{ - struct grub_btrfs_chunk_stripe *stripe; - grub_disk_addr_t paddr; - grub_device_t dev; - grub_err_t err; - - stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1); - /* Right now the redundancy handling is easy. - With RAID5-like it will be more difficult. */ - stripe += stripen + redundancy; - - paddr = grub_le_to_cpu64 (stripe->offset) + stripe_offset; - - grub_dprintf ("btrfs", "stripe %" PRIxGRUB_UINT64_T - " maps to 0x%" PRIxGRUB_UINT64_T "\n" - "reading paddr 0x%" PRIxGRUB_UINT64_T "\n", - stripen, stripe->offset, paddr); - - dev = find_device (data, stripe->device_id); - if (!dev) - { - grub_dprintf ("btrfs", - "couldn't find a necessary member device " - "of multi-device filesystem\n"); - grub_errno = GRUB_ERR_NONE; - return GRUB_ERR_READ_ERROR; - } - - err = grub_disk_read (dev->disk, paddr >> GRUB_DISK_SECTOR_BITS, - paddr & (GRUB_DISK_SECTOR_SIZE - 1), - csize, buf); - return err; -} - -struct raid56_buffer { - void *buf; - int data_is_valid; -}; - -static void -rebuild_raid5 (char *dest, struct raid56_buffer *buffers, - grub_uint64_t nstripes, grub_uint64_t csize) -{ - grub_uint64_t i; - int first; - - for(i = 0; buffers[i].data_is_valid && i < nstripes; i++); - - if (i == nstripes) - { - grub_dprintf ("btrfs", "called rebuild_raid5(), but all disks are OK\n"); - return; - } - - grub_dprintf ("btrfs", "rebuilding RAID 5 stripe #%" PRIuGRUB_UINT64_T "\n", i); - - for (i = 0, first = 1; i < nstripes; i++) - { - if (!buffers[i].data_is_valid) - continue; - - if (first) { - grub_memcpy(dest, buffers[i].buf, csize); - first = 0; - } else - grub_crypto_xor (dest, dest, buffers[i].buf, csize); - } -} - -static grub_err_t -raid6_recover_read_buffer (void *data, int disk_nr, - grub_uint64_t addr __attribute__ ((unused)), - void *dest, grub_size_t size) -{ - struct raid56_buffer *buffers = data; - - if (!buffers[disk_nr].data_is_valid) - return grub_errno = GRUB_ERR_READ_ERROR; - - grub_memcpy(dest, buffers[disk_nr].buf, size); - - return grub_errno = GRUB_ERR_NONE; -} - -static void -rebuild_raid6 (struct raid56_buffer *buffers, grub_uint64_t nstripes, - grub_uint64_t csize, grub_uint64_t parities_pos, void *dest, - grub_uint64_t stripen) - -{ - grub_raid6_recover_gen (buffers, nstripes, stripen, parities_pos, - dest, 0, csize, 0, raid6_recover_read_buffer); -} - -static grub_err_t -raid56_read_retry (struct grub_btrfs_data *data, - struct grub_btrfs_chunk_item *chunk, - grub_uint64_t stripe_offset, grub_uint64_t stripen, - grub_uint64_t csize, void *buf, grub_uint64_t parities_pos) -{ - struct raid56_buffer *buffers; - grub_uint64_t nstripes = grub_le_to_cpu16 (chunk->nstripes); - grub_uint64_t chunk_type = grub_le_to_cpu64 (chunk->type); - grub_err_t ret = GRUB_ERR_OUT_OF_MEMORY; - grub_uint64_t i, failed_devices; - - buffers = grub_calloc (nstripes, sizeof (*buffers)); - if (!buffers) - goto cleanup; - - for (i = 0; i < nstripes; i++) - { - buffers[i].buf = grub_zalloc (csize); - if (!buffers[i].buf) - goto cleanup; - } - - for (failed_devices = 0, i = 0; i < nstripes; i++) - { - struct grub_btrfs_chunk_stripe *stripe; - grub_disk_addr_t paddr; - grub_device_t dev; - grub_err_t err; - - /* - * The struct grub_btrfs_chunk_stripe array lives - * behind struct grub_btrfs_chunk_item. - */ - stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1) + i; - - paddr = grub_le_to_cpu64 (stripe->offset) + stripe_offset; - grub_dprintf ("btrfs", "reading paddr %" PRIxGRUB_UINT64_T - " from stripe ID %" PRIxGRUB_UINT64_T "\n", - paddr, stripe->device_id); - - dev = find_device (data, stripe->device_id); - if (!dev) - { - grub_dprintf ("btrfs", "stripe %" PRIuGRUB_UINT64_T " FAILED (dev ID %" - PRIxGRUB_UINT64_T ")\n", i, stripe->device_id); - failed_devices++; - continue; - } - - err = grub_disk_read (dev->disk, paddr >> GRUB_DISK_SECTOR_BITS, - paddr & (GRUB_DISK_SECTOR_SIZE - 1), - csize, buffers[i].buf); - if (err == GRUB_ERR_NONE) - { - buffers[i].data_is_valid = 1; - grub_dprintf ("btrfs", "stripe %" PRIuGRUB_UINT64_T " OK (dev ID %" - PRIxGRUB_UINT64_T ")\n", i, stripe->device_id); - } - else - { - grub_dprintf ("btrfs", "stripe %" PRIuGRUB_UINT64_T - " READ FAILED (dev ID %" PRIxGRUB_UINT64_T ")\n", - i, stripe->device_id); - failed_devices++; - } - } - - if (failed_devices > 1 && (chunk_type & GRUB_BTRFS_CHUNK_TYPE_RAID5)) - { - grub_dprintf ("btrfs", "not enough disks for RAID 5: total %" PRIuGRUB_UINT64_T - ", missing %" PRIuGRUB_UINT64_T "\n", - nstripes, failed_devices); - ret = GRUB_ERR_READ_ERROR; - goto cleanup; - } - else if (failed_devices > 2 && (chunk_type & GRUB_BTRFS_CHUNK_TYPE_RAID6)) - { - grub_dprintf ("btrfs", "not enough disks for RAID 6: total %" PRIuGRUB_UINT64_T - ", missing %" PRIuGRUB_UINT64_T "\n", - nstripes, failed_devices); - ret = GRUB_ERR_READ_ERROR; - goto cleanup; - } - else - grub_dprintf ("btrfs", "enough disks for RAID 5: total %" - PRIuGRUB_UINT64_T ", missing %" PRIuGRUB_UINT64_T "\n", - nstripes, failed_devices); - - /* We have enough disks. So, rebuild the data. */ - if (chunk_type & GRUB_BTRFS_CHUNK_TYPE_RAID5) - rebuild_raid5 (buf, buffers, nstripes, csize); - else - rebuild_raid6 (buffers, nstripes, csize, parities_pos, buf, stripen); - - ret = GRUB_ERR_NONE; - cleanup: - if (buffers) - for (i = 0; i < nstripes; i++) - grub_free (buffers[i].buf); - grub_free (buffers); - - return ret; -} - -static grub_err_t -grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, - void *buf, grub_size_t size, int recursion_depth) -{ - while (size > 0) - { - grub_uint8_t *ptr; - struct grub_btrfs_key *key; - struct grub_btrfs_chunk_item *chunk; - grub_uint64_t csize; - grub_err_t err = 0; - struct grub_btrfs_key key_out; - int challoc = 0; - struct grub_btrfs_key key_in; - grub_size_t chsize; - grub_disk_addr_t chaddr; - - grub_dprintf ("btrfs", "searching for laddr %" PRIxGRUB_UINT64_T "\n", - addr); - for (ptr = data->sblock.bootstrap_mapping; - ptr < data->sblock.bootstrap_mapping - + sizeof (data->sblock.bootstrap_mapping) - - sizeof (struct grub_btrfs_key);) - { - key = (struct grub_btrfs_key *) ptr; - if (key->type != GRUB_BTRFS_ITEM_TYPE_CHUNK) - break; - chunk = (struct grub_btrfs_chunk_item *) (key + 1); - grub_dprintf ("btrfs", - "%" PRIxGRUB_UINT64_T " %" PRIxGRUB_UINT64_T " \n", - grub_le_to_cpu64 (key->offset), - grub_le_to_cpu64 (chunk->size)); - if (grub_le_to_cpu64 (key->offset) <= addr - && addr < grub_le_to_cpu64 (key->offset) - + grub_le_to_cpu64 (chunk->size)) - goto chunk_found; - ptr += sizeof (*key) + sizeof (*chunk) - + sizeof (struct grub_btrfs_chunk_stripe) - * grub_le_to_cpu16 (chunk->nstripes); - } - - key_in.object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); - key_in.type = GRUB_BTRFS_ITEM_TYPE_CHUNK; - key_in.offset = grub_cpu_to_le64 (addr); - err = lower_bound (data, &key_in, &key_out, - data->sblock.chunk_tree, - &chaddr, &chsize, NULL, recursion_depth); - if (err) - return err; - key = &key_out; - if (key->type != GRUB_BTRFS_ITEM_TYPE_CHUNK - || !(grub_le_to_cpu64 (key->offset) <= addr)) - return grub_error (GRUB_ERR_BAD_FS, - "couldn't find the chunk descriptor"); - - if (!chsize) - { - grub_dprintf ("btrfs", "zero-size chunk\n"); - return grub_error (GRUB_ERR_BAD_FS, - "got an invalid zero-size chunk"); - } - - /* - * The space being allocated for a chunk should at least be able to - * contain one chunk item. - */ - if (chsize < sizeof (struct grub_btrfs_chunk_item)) - { - grub_dprintf ("btrfs", "chunk-size too small\n"); - return grub_error (GRUB_ERR_BAD_FS, - "got an invalid chunk size"); - } - chunk = grub_malloc (chsize); - if (!chunk) - return grub_errno; - - challoc = 1; - err = grub_btrfs_read_logical (data, chaddr, chunk, chsize, - recursion_depth); - if (err) - { - grub_free (chunk); - return err; - } - - chunk_found: - { - grub_uint64_t stripen; - grub_uint64_t stripe_offset; - grub_uint64_t off = addr - grub_le_to_cpu64 (key->offset); - grub_uint64_t chunk_stripe_length; - grub_uint16_t nstripes; - unsigned redundancy = 1; - unsigned i, j; - int is_raid56; - grub_uint64_t parities_pos = 0; - - is_raid56 = !!(grub_le_to_cpu64 (chunk->type) & - (GRUB_BTRFS_CHUNK_TYPE_RAID5 | - GRUB_BTRFS_CHUNK_TYPE_RAID6)); - - if (grub_le_to_cpu64 (chunk->size) <= off) - { - grub_dprintf ("btrfs", "no chunk\n"); - return grub_error (GRUB_ERR_BAD_FS, - "couldn't find the chunk descriptor"); - } - - nstripes = grub_le_to_cpu16 (chunk->nstripes) ? : 1; - chunk_stripe_length = grub_le_to_cpu64 (chunk->stripe_length) ? : 512; - grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T - "+0x%" PRIxGRUB_UINT64_T - " (%d stripes (%d substripes) of %" - PRIxGRUB_UINT64_T ")\n", - grub_le_to_cpu64 (key->offset), - grub_le_to_cpu64 (chunk->size), - nstripes, - grub_le_to_cpu16 (chunk->nsubstripes), - chunk_stripe_length); - - switch (grub_le_to_cpu64 (chunk->type) - & ~GRUB_BTRFS_CHUNK_TYPE_BITS_DONTCARE) - { - case GRUB_BTRFS_CHUNK_TYPE_SINGLE: - { - grub_uint64_t stripe_length; - grub_dprintf ("btrfs", "single\n"); - stripe_length = grub_divmod64 (grub_le_to_cpu64 (chunk->size), - nstripes, - NULL); - - /* For single, there should be exactly 1 stripe. */ - if (grub_le_to_cpu16 (chunk->nstripes) != 1) - { - grub_dprintf ("btrfs", "invalid RAID_SINGLE: nstripes != 1 (%u)\n", - grub_le_to_cpu16 (chunk->nstripes)); - return grub_error (GRUB_ERR_BAD_FS, - "invalid RAID_SINGLE: nstripes != 1 (%u)", - grub_le_to_cpu16 (chunk->nstripes)); - } - if (stripe_length == 0) - stripe_length = 512; - stripen = grub_divmod64 (off, stripe_length, &stripe_offset); - csize = (stripen + 1) * stripe_length - off; - break; - } - case GRUB_BTRFS_CHUNK_TYPE_RAID1C4: - redundancy++; - /* fall through */ - case GRUB_BTRFS_CHUNK_TYPE_RAID1C3: - redundancy++; - /* fall through */ - case GRUB_BTRFS_CHUNK_TYPE_DUPLICATED: - case GRUB_BTRFS_CHUNK_TYPE_RAID1: - { - grub_dprintf ("btrfs", "RAID1 (copies: %d)\n", ++redundancy); - stripen = 0; - stripe_offset = off; - csize = grub_le_to_cpu64 (chunk->size) - off; - - /* - * Redundancy, and substripes only apply to RAID10, and there - * should be exactly 2 sub-stripes. - */ - if (grub_le_to_cpu16 (chunk->nstripes) != redundancy) - { - grub_dprintf ("btrfs", "invalid RAID1: nstripes != %u (%u)\n", - redundancy, grub_le_to_cpu16 (chunk->nstripes)); - return grub_error (GRUB_ERR_BAD_FS, - "invalid RAID1: nstripes != %u (%u)", - redundancy, grub_le_to_cpu16 (chunk->nstripes)); - } - break; - } - case GRUB_BTRFS_CHUNK_TYPE_RAID0: - { - grub_uint64_t middle, high; - grub_uint64_t low; - grub_dprintf ("btrfs", "RAID0\n"); - middle = grub_divmod64 (off, - chunk_stripe_length, - &low); - - high = grub_divmod64 (middle, nstripes, - &stripen); - stripe_offset = - low + chunk_stripe_length * high; - csize = chunk_stripe_length - low; - break; - } - case GRUB_BTRFS_CHUNK_TYPE_RAID10: - { - grub_uint64_t middle, high; - grub_uint64_t low; - grub_uint16_t nsubstripes; - nsubstripes = grub_le_to_cpu16 (chunk->nsubstripes) ? : 1; - middle = grub_divmod64 (off, - chunk_stripe_length, - &low); - - high = grub_divmod64 (middle, - nstripes / nsubstripes ? : 1, - &stripen); - stripen *= nsubstripes; - redundancy = nsubstripes; - stripe_offset = low + chunk_stripe_length - * high; - csize = chunk_stripe_length - low; - - /* - * Substripes only apply to RAID10, and there - * should be exactly 2 sub-stripes. - */ - if (grub_le_to_cpu16 (chunk->nsubstripes) != 2) - { - grub_dprintf ("btrfs", "invalid RAID10: nsubstripes != 2 (%u)", - grub_le_to_cpu16 (chunk->nsubstripes)); - return grub_error (GRUB_ERR_BAD_FS, - "invalid RAID10: nsubstripes != 2 (%u)", - grub_le_to_cpu16 (chunk->nsubstripes)); - } - - break; - } - case GRUB_BTRFS_CHUNK_TYPE_RAID5: - case GRUB_BTRFS_CHUNK_TYPE_RAID6: - { - grub_uint64_t nparities, stripe_nr, high, low; - - redundancy = 1; /* no redundancy for now */ - - if (grub_le_to_cpu64 (chunk->type) & GRUB_BTRFS_CHUNK_TYPE_RAID5) - { - grub_dprintf ("btrfs", "RAID5\n"); - nparities = 1; - } - else - { - grub_dprintf ("btrfs", "RAID6\n"); - nparities = 2; - } - - /* - * RAID 6 layout consists of several stripes spread over - * the disks, e.g.: - * - * Disk_0 Disk_1 Disk_2 Disk_3 - * A0 B0 P0 Q0 - * Q1 A1 B1 P1 - * P2 Q2 A2 B2 - * - * Note: placement of the parities depend on row number. - * - * Pay attention that the btrfs terminology may differ from - * terminology used in other RAID implementations, e.g. LVM, - * dm or md. The main difference is that btrfs calls contiguous - * block of data on a given disk, e.g. A0, stripe instead of chunk. - * - * The variables listed below have following meaning: - * - stripe_nr is the stripe number excluding the parities - * (A0 = 0, B0 = 1, A1 = 2, B1 = 3, etc.), - * - high is the row number (0 for A0...Q0, 1 for Q1...P1, etc.), - * - stripen is the disk number in a row (0 for A0, Q1, P2, - * 1 for B0, A1, Q2, etc.), - * - off is the logical address to read, - * - chunk_stripe_length is the size of a stripe (typically 64 KiB), - * - nstripes is the number of disks in a row, - * - low is the offset of the data inside a stripe, - * - stripe_offset is the data offset in an array, - * - csize is the "potential" data to read; it will be reduced - * to size if the latter is smaller, - * - nparities is the number of parities (1 for RAID 5, 2 for - * RAID 6); used only in RAID 5/6 code. - */ - stripe_nr = grub_divmod64 (off, chunk_stripe_length, &low); - - /* - * stripen is computed without the parities - * (0 for A0, A1, A2, 1 for B0, B1, B2, etc.). - */ - if (nparities >= nstripes) - return grub_error (GRUB_ERR_BAD_FS, - "invalid RAID5/6: nparities >= nstripes"); - high = grub_divmod64 (stripe_nr, nstripes - nparities, &stripen); - - /* - * The stripes are spread over the disks. Every each row their - * positions are shifted by 1 place. So, the real disks number - * change. Hence, we have to take into account current row number - * modulo nstripes (0 for A0, 1 for A1, 2 for A2, etc.). - */ - grub_divmod64 (high + stripen, nstripes, &stripen); - - /* - * parities_pos is equal to ((high - nparities) % nstripes) - * (see the diagram above). However, (high - nparities) can - * be negative, e.g. when high == 0, leading to an incorrect - * results. (high + nstripes - nparities) is always positive and - * modulo nstripes is equal to ((high - nparities) % nstripes). - */ - grub_divmod64 (high + nstripes - nparities, nstripes, &parities_pos); - - stripe_offset = chunk_stripe_length * high + low; - csize = chunk_stripe_length - low; - - break; - } - default: - grub_dprintf ("btrfs", "unsupported RAID\n"); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported RAID flags %" PRIxGRUB_UINT64_T, - grub_le_to_cpu64 (chunk->type)); - } - if (csize == 0) - return grub_error (GRUB_ERR_BUG, - "couldn't find the chunk descriptor"); - if (csize > (grub_uint64_t) size) - csize = size; - - /* - * The space for a chunk stripe is limited to the space provide in the super-block's - * bootstrap mapping with an initial btrfs key at the start of each chunk. - */ - grub_size_t avail_stripes = sizeof (data->sblock.bootstrap_mapping) / - (sizeof (struct grub_btrfs_key) + sizeof (struct grub_btrfs_chunk_stripe)); - - for (j = 0; j < 2; j++) - { - grub_size_t est_chunk_alloc = 0; - - grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T - "+0x%" PRIxGRUB_UINT64_T - " (%d stripes (%d substripes) of %" - PRIxGRUB_UINT64_T ")\n", - grub_le_to_cpu64 (key->offset), - grub_le_to_cpu64 (chunk->size), - grub_le_to_cpu16 (chunk->nstripes), - grub_le_to_cpu16 (chunk->nsubstripes), - grub_le_to_cpu64 (chunk->stripe_length)); - grub_dprintf ("btrfs", "reading laddr 0x%" PRIxGRUB_UINT64_T "\n", - addr); - - if (grub_mul (sizeof (struct grub_btrfs_chunk_stripe), - grub_le_to_cpu16 (chunk->nstripes), &est_chunk_alloc) || - grub_add (est_chunk_alloc, - sizeof (struct grub_btrfs_chunk_item), &est_chunk_alloc) || - est_chunk_alloc > chunk->size) - { - err = GRUB_ERR_BAD_FS; - break; - } - - if (grub_le_to_cpu16 (chunk->nstripes) > avail_stripes) - { - err = GRUB_ERR_BAD_FS; - break; - } - - if (is_raid56) - { - err = btrfs_read_from_chunk (data, chunk, stripen, - stripe_offset, - 0, /* no mirror */ - csize, buf); - grub_errno = GRUB_ERR_NONE; - if (err) - err = raid56_read_retry (data, chunk, stripe_offset, - stripen, csize, buf, parities_pos); - } - else - for (i = 0; i < redundancy; i++) - { - err = btrfs_read_from_chunk (data, chunk, stripen, - stripe_offset, - i, /* redundancy */ - csize, buf); - if (!err) - break; - grub_errno = GRUB_ERR_NONE; - } - if (!err) - break; - } - if (err) - return grub_errno = err; - } - size -= csize; - buf = (grub_uint8_t *) buf + csize; - addr += csize; - if (challoc) - grub_free (chunk); - } - return GRUB_ERR_NONE; -} - -static struct grub_btrfs_data * -grub_btrfs_mount (grub_device_t dev) -{ - struct grub_btrfs_data *data; - grub_err_t err; - - if (!dev->disk) - { - grub_error (GRUB_ERR_BAD_FS, "not BtrFS"); - return NULL; - } - - data = grub_zalloc (sizeof (*data)); - if (!data) - return NULL; - - err = read_sblock (dev->disk, &data->sblock); - if (err) - { - grub_free (data); - return NULL; - } - - data->n_devices_allocated = 16; - data->devices_attached = grub_calloc (data->n_devices_allocated, - sizeof (data->devices_attached[0])); - if (!data->devices_attached) - { - grub_free (data); - return NULL; - } - data->n_devices_attached = 1; - data->devices_attached[0].dev = dev; - data->devices_attached[0].id = data->sblock.this_device.device_id; - - return data; -} - -static void -grub_btrfs_unmount (struct grub_btrfs_data *data) -{ - unsigned i; - /* The device 0 is closed one layer upper. */ - for (i = 1; i < data->n_devices_attached; i++) - if (data->devices_attached[i].dev) - grub_device_close (data->devices_attached[i].dev); - grub_free (data->devices_attached); - grub_free (data->extent); - grub_free (data); -} - -static grub_err_t -grub_btrfs_read_inode (struct grub_btrfs_data *data, - struct grub_btrfs_inode *inode, grub_uint64_t num, - grub_uint64_t tree) -{ - struct grub_btrfs_key key_in, key_out; - grub_disk_addr_t elemaddr; - grub_size_t elemsize; - grub_err_t err; - - key_in.object_id = num; - key_in.type = GRUB_BTRFS_ITEM_TYPE_INODE_ITEM; - key_in.offset = 0; - - err = lower_bound (data, &key_in, &key_out, tree, &elemaddr, &elemsize, NULL, - 0); - if (err) - return err; - if (num != key_out.object_id - || key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_ITEM) - return grub_error (GRUB_ERR_BAD_FS, "inode not found"); - - return grub_btrfs_read_logical (data, elemaddr, inode, sizeof (*inode), 0); -} - -static void *grub_zstd_malloc (void *state __attribute__((unused)), size_t size) -{ - return grub_malloc (size); -} - -static void grub_zstd_free (void *state __attribute__((unused)), void *address) -{ - return grub_free (address); -} - -static ZSTD_customMem grub_zstd_allocator (void) -{ - ZSTD_customMem allocator; - - allocator.customAlloc = &grub_zstd_malloc; - allocator.customFree = &grub_zstd_free; - allocator.opaque = NULL; - - return allocator; -} - -static grub_ssize_t -grub_btrfs_zstd_decompress (char *ibuf, grub_size_t isize, grub_off_t off, - char *obuf, grub_size_t osize) -{ - void *allocated = NULL; - char *otmpbuf = obuf; - grub_size_t otmpsize = osize; - ZSTD_DCtx *dctx = NULL; - grub_size_t zstd_ret; - grub_ssize_t ret = -1; - - /* - * Zstd will fail if it can't fit the entire output in the destination - * buffer, so if osize isn't large enough, allocate a temporary buffer. - */ - if (otmpsize < ZSTD_BTRFS_MAX_INPUT) - { - allocated = grub_malloc (ZSTD_BTRFS_MAX_INPUT); - if (!allocated) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed allocate a zstd buffer"); - goto err; - } - otmpbuf = (char *) allocated; - otmpsize = ZSTD_BTRFS_MAX_INPUT; - } - - /* Create the ZSTD_DCtx. */ - dctx = ZSTD_createDCtx_advanced (grub_zstd_allocator ()); - if (!dctx) - { - /* ZSTD_createDCtx_advanced() only fails if it is out of memory. */ - grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to create a zstd context"); - goto err; - } - - /* - * Get the real input size, there may be junk at the - * end of the frame. - */ - isize = ZSTD_findFrameCompressedSize (ibuf, isize); - if (ZSTD_isError (isize)) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "zstd data corrupted"); - goto err; - } - - /* Decompress and check for errors. */ - zstd_ret = ZSTD_decompressDCtx (dctx, otmpbuf, otmpsize, ibuf, isize); - if (ZSTD_isError (zstd_ret)) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "zstd data corrupted"); - goto err; - } - - /* - * Move the requested data into the obuf. obuf may be equal - * to otmpbuf, which is why grub_memmove() is required. - */ - grub_memmove (obuf, otmpbuf + off, osize); - ret = osize; - -err: - grub_free (allocated); - ZSTD_freeDCtx (dctx); - - return ret; -} - -static grub_ssize_t -grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, - char *obuf, grub_size_t osize) -{ - grub_uint32_t total_size, cblock_size; - grub_size_t ret = 0; - char *ibuf0 = ibuf; - - total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); - ibuf += sizeof (total_size); - - if (isize < total_size) - return -1; - - /* Jump forward to first block with requested data. */ - while (off >= GRUB_BTRFS_LZO_BLOCK_SIZE) - { - /* Don't let following uint32_t cross the page boundary. */ - if (((ibuf - ibuf0) & 0xffc) == 0xffc) - ibuf = ((ibuf - ibuf0 + 3) & ~3) + ibuf0; - - cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); - ibuf += sizeof (cblock_size); - - if (cblock_size > GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE) - return -1; - - off -= GRUB_BTRFS_LZO_BLOCK_SIZE; - ibuf += cblock_size; - } - - while (osize > 0) - { - lzo_uint usize = GRUB_BTRFS_LZO_BLOCK_SIZE; - - /* Don't let following uint32_t cross the page boundary. */ - if (((ibuf - ibuf0) & 0xffc) == 0xffc) - ibuf = ((ibuf - ibuf0 + 3) & ~3) + ibuf0; - - cblock_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf)); - ibuf += sizeof (cblock_size); - - if (cblock_size > GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE) - return -1; - - /* Block partially filled with requested data. */ - if (off > 0 || osize < GRUB_BTRFS_LZO_BLOCK_SIZE) - { - grub_size_t to_copy = GRUB_BTRFS_LZO_BLOCK_SIZE - off; - grub_uint8_t *buf; - - if (to_copy > osize) - to_copy = osize; - - buf = grub_malloc (GRUB_BTRFS_LZO_BLOCK_SIZE); - if (!buf) - return -1; - - if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, buf, &usize, - NULL) != LZO_E_OK) - { - grub_free (buf); - return -1; - } - - if (to_copy > usize) - to_copy = usize; - grub_memcpy(obuf, buf + off, to_copy); - - osize -= to_copy; - ret += to_copy; - obuf += to_copy; - ibuf += cblock_size; - off = 0; - - grub_free (buf); - continue; - } - - /* Decompress whole block directly to output buffer. */ - if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, (lzo_bytep)obuf, - &usize, NULL) != LZO_E_OK) - return -1; - - osize -= usize; - ret += usize; - obuf += usize; - ibuf += cblock_size; - } - - return ret; -} - -static grub_ssize_t -grub_btrfs_extent_read (struct grub_btrfs_data *data, - grub_uint64_t ino, grub_uint64_t tree, - grub_off_t pos0, char *buf, grub_size_t len) -{ - grub_off_t pos = pos0; - while (len) - { - grub_size_t csize; - grub_err_t err; - grub_off_t extoff; - struct grub_btrfs_leaf_descriptor desc; - - if (!data->extent || data->extstart > pos || data->extino != ino - || data->exttree != tree || data->extend <= pos) - { - struct grub_btrfs_key key_in, key_out; - grub_disk_addr_t elemaddr; - grub_size_t elemsize; - - grub_free (data->extent); - key_in.object_id = ino; - key_in.type = GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM; - key_in.offset = grub_cpu_to_le64 (pos); - err = lower_bound (data, &key_in, &key_out, tree, - &elemaddr, &elemsize, &desc, 0); - if (err) - { - grub_free (desc.data); - return -1; - } - if (key_out.object_id != ino - || key_out.type != GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM) - { - grub_error (GRUB_ERR_BAD_FS, "extent not found"); - return -1; - } - if ((grub_ssize_t) elemsize < ((char *) &data->extent->inl - - (char *) data->extent)) - { - grub_error (GRUB_ERR_BAD_FS, "extent descriptor is too short"); - return -1; - } - data->extstart = grub_le_to_cpu64 (key_out.offset); - data->extsize = elemsize; - data->extent = grub_malloc (elemsize); - data->extino = ino; - data->exttree = tree; - if (!data->extent) - return grub_errno; - - err = grub_btrfs_read_logical (data, elemaddr, data->extent, - elemsize, 0); - if (err) - return err; - - data->extend = data->extstart + grub_le_to_cpu64 (data->extent->size); - if (data->extent->type == GRUB_BTRFS_EXTENT_REGULAR - && (char *) data->extent + elemsize - >= (char *) &data->extent->filled + sizeof (data->extent->filled)) - data->extend = - data->extstart + grub_le_to_cpu64 (data->extent->filled); - - grub_dprintf ("btrfs", "regular extent 0x%" PRIxGRUB_UINT64_T "+0x%" - PRIxGRUB_UINT64_T "\n", - grub_le_to_cpu64 (key_out.offset), - grub_le_to_cpu64 (data->extent->size)); - /* - * The way of extent item iteration is pretty bad, it completely - * requires all extents are contiguous, which is not ensured. - * - * Features like NO_HOLE and mixed inline/regular extents can cause - * gaps between file extent items. - * - * The correct way is to follow Linux kernel/U-boot to iterate item - * by item, without any assumption on the file offset continuity. - * - * Here we just manually skip to next item and re-do the verification. - * - * TODO: Rework the whole extent item iteration code, if not the - * whole btrfs implementation. - */ - if (data->extend <= pos) - { - err = next (data, &desc, &elemaddr, &elemsize, &key_out); - if (err < 0) - return -1; - /* No next item for the inode, we hit the end. */ - if (err == 0 || key_out.object_id != ino || - key_out.type != GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM) - return pos - pos0; - - csize = grub_le_to_cpu64 (key_out.offset) - pos; - if (csize > len) - csize = len; - - grub_memset (buf, 0, csize); - buf += csize; - pos += csize; - len -= csize; - continue; - } - } - csize = data->extend - pos; - extoff = pos - data->extstart; - if (csize > len) - csize = len; - - if (data->extent->encryption) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "encryption not supported"); - return -1; - } - - if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE - && data->extent->compression != GRUB_BTRFS_COMPRESSION_ZLIB - && data->extent->compression != GRUB_BTRFS_COMPRESSION_LZO - && data->extent->compression != GRUB_BTRFS_COMPRESSION_ZSTD) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "compression type 0x%x not supported", - data->extent->compression); - return -1; - } - - if (data->extent->encoding) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "encoding not supported"); - return -1; - } - - switch (data->extent->type) - { - case GRUB_BTRFS_EXTENT_INLINE: - if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZLIB) - { - if (grub_zlib_decompress (data->extent->inl, data->extsize - - ((grub_uint8_t *) data->extent->inl - - (grub_uint8_t *) data->extent), - extoff, buf, csize) - != (grub_ssize_t) csize) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, - "premature end of compressed"); - return -1; - } - } - else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) - { - if (grub_btrfs_lzo_decompress(data->extent->inl, data->extsize - - ((grub_uint8_t *) data->extent->inl - - (grub_uint8_t *) data->extent), - extoff, buf, csize) - != (grub_ssize_t) csize) - return -1; - } - else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZSTD) - { - if (grub_btrfs_zstd_decompress (data->extent->inl, data->extsize - - ((grub_uint8_t *) data->extent->inl - - (grub_uint8_t *) data->extent), - extoff, buf, csize) - != (grub_ssize_t) csize) - return -1; - } - else - grub_memcpy (buf, data->extent->inl + extoff, csize); - break; - case GRUB_BTRFS_EXTENT_REGULAR: - if (!data->extent->laddr) - { - grub_memset (buf, 0, csize); - break; - } - - if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE) - { - char *tmp; - grub_uint64_t zsize; - grub_ssize_t ret; - - zsize = grub_le_to_cpu64 (data->extent->compressed_size); - tmp = grub_malloc (zsize); - if (!tmp) - return -1; - err = grub_btrfs_read_logical (data, - grub_le_to_cpu64 (data->extent->laddr), - tmp, zsize, 0); - if (err) - { - grub_free (tmp); - return -1; - } - - if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZLIB) - ret = grub_zlib_decompress (tmp, zsize, extoff - + grub_le_to_cpu64 (data->extent->offset), - buf, csize); - else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO) - ret = grub_btrfs_lzo_decompress (tmp, zsize, extoff - + grub_le_to_cpu64 (data->extent->offset), - buf, csize); - else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZSTD) - ret = grub_btrfs_zstd_decompress (tmp, zsize, extoff - + grub_le_to_cpu64 (data->extent->offset), - buf, csize); - else - ret = -1; - - grub_free (tmp); - - if (ret != (grub_ssize_t) csize) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, - "premature end of compressed"); - return -1; - } - - break; - } - err = grub_btrfs_read_logical (data, - grub_le_to_cpu64 (data->extent->laddr) - + grub_le_to_cpu64 (data->extent->offset) - + extoff, buf, csize, 0); - if (err) - return -1; - break; - default: - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported extent type 0x%x", data->extent->type); - return -1; - } - buf += csize; - pos += csize; - len -= csize; - } - return pos - pos0; -} - -static grub_err_t -get_root (struct grub_btrfs_data *data, struct grub_btrfs_key *key, - grub_uint64_t *tree, grub_uint8_t *type) -{ - grub_err_t err; - grub_disk_addr_t elemaddr; - grub_size_t elemsize; - struct grub_btrfs_key key_out, key_in; - struct grub_btrfs_root_item ri; - - key_in.object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_ROOT_VOL_OBJECTID); - key_in.offset = 0; - key_in.type = GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM; - err = lower_bound (data, &key_in, &key_out, - data->sblock.root_tree, - &elemaddr, &elemsize, NULL, 0); - if (err) - return err; - if (key_in.object_id != key_out.object_id - || key_in.type != key_out.type - || key_in.offset != key_out.offset) - return grub_error (GRUB_ERR_BAD_FS, "no root"); - err = grub_btrfs_read_logical (data, elemaddr, &ri, - sizeof (ri), 0); - if (err) - return err; - key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; - key->offset = 0; - key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); - *tree = ri.tree; - *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; - return GRUB_ERR_NONE; -} - -static grub_err_t -find_path (struct grub_btrfs_data *data, - const char *path, struct grub_btrfs_key *key, - grub_uint64_t *tree, grub_uint8_t *type) -{ - const char *slash = path; - grub_err_t err; - grub_disk_addr_t elemaddr; - grub_size_t elemsize; - grub_size_t allocated = 0; - struct grub_btrfs_dir_item *direl = NULL; - struct grub_btrfs_key key_out; - const char *ctoken; - grub_size_t ctokenlen; - char *path_alloc = NULL; - char *origpath = NULL; - unsigned symlinks_max = 32; - grub_size_t sz; - - err = get_root (data, key, tree, type); - if (err) - return err; - - origpath = grub_strdup (path); - if (!origpath) - return grub_errno; - - while (1) - { - while (path[0] == '/') - path++; - if (!path[0]) - break; - slash = grub_strchr (path, '/'); - if (!slash) - slash = path + grub_strlen (path); - ctoken = path; - ctokenlen = slash - path; - - if (*type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) - { - grub_free (path_alloc); - grub_free (origpath); - return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); - } - - if (ctokenlen == 1 && ctoken[0] == '.') - { - path = slash; - continue; - } - if (ctokenlen == 2 && ctoken[0] == '.' && ctoken[1] == '.') - { - key->type = GRUB_BTRFS_ITEM_TYPE_INODE_REF; - key->offset = -1; - - err = lower_bound (data, key, &key_out, *tree, &elemaddr, &elemsize, - NULL, 0); - if (err) - { - grub_free (direl); - grub_free (path_alloc); - grub_free (origpath); - return err; - } - - if (key_out.type != key->type - || key->object_id != key_out.object_id) - { - grub_free (direl); - grub_free (path_alloc); - err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath); - grub_free (origpath); - return err; - } - - *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; - key->object_id = key_out.offset; - - path = slash; - - continue; - } - - key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; - key->offset = grub_cpu_to_le64 (~grub_getcrc32c (1, ctoken, ctokenlen)); - - err = lower_bound (data, key, &key_out, *tree, &elemaddr, &elemsize, - NULL, 0); - if (err) - { - grub_free (direl); - grub_free (path_alloc); - grub_free (origpath); - return err; - } - if (key_cmp (key, &key_out) != 0) - { - grub_free (direl); - grub_free (path_alloc); - err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath); - grub_free (origpath); - return err; - } - - struct grub_btrfs_dir_item *cdirel; - if (elemsize > allocated) - { - if (grub_mul (2, elemsize, &allocated) || - grub_add (allocated, 1, &sz)) - { - grub_free (path_alloc); - grub_free (origpath); - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory item size overflow")); - } - grub_free (direl); - direl = grub_malloc (sz); - if (!direl) - { - grub_free (path_alloc); - grub_free (origpath); - return grub_errno; - } - } - - err = grub_btrfs_read_logical (data, elemaddr, direl, elemsize, 0); - if (err) - { - grub_free (direl); - grub_free (path_alloc); - grub_free (origpath); - return err; - } - - for (cdirel = direl; - (grub_uint8_t *) cdirel - (grub_uint8_t *) direl - < (grub_ssize_t) elemsize; - cdirel = (void *) ((grub_uint8_t *) (direl + 1) - + grub_le_to_cpu16 (cdirel->n) - + grub_le_to_cpu16 (cdirel->m))) - { - if (ctokenlen == grub_le_to_cpu16 (cdirel->n) - && grub_memcmp (cdirel->name, ctoken, ctokenlen) == 0) - break; - } - if ((grub_uint8_t *) cdirel - (grub_uint8_t *) direl - >= (grub_ssize_t) elemsize) - { - grub_free (direl); - grub_free (path_alloc); - err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath); - grub_free (origpath); - return err; - } - - path = slash; - if (cdirel->type == GRUB_BTRFS_DIR_ITEM_TYPE_SYMLINK) - { - struct grub_btrfs_inode inode; - char *tmp; - if (--symlinks_max == 0) - { - grub_free (direl); - grub_free (path_alloc); - grub_free (origpath); - return grub_error (GRUB_ERR_SYMLINK_LOOP, - N_("too deep nesting of symlinks")); - } - - err = grub_btrfs_read_inode (data, &inode, - cdirel->key.object_id, *tree); - if (err) - { - grub_free (direl); - grub_free (path_alloc); - grub_free (origpath); - return err; - } - - if (grub_add (grub_le_to_cpu64 (inode.size), grub_strlen (path), &sz) || - grub_add (sz, 1, &sz)) - { - grub_free (direl); - grub_free (path_alloc); - grub_free (origpath); - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("buffer size overflow")); - } - tmp = grub_malloc (sz); - if (!tmp) - { - grub_free (direl); - grub_free (path_alloc); - grub_free (origpath); - return grub_errno; - } - - if (grub_btrfs_extent_read (data, cdirel->key.object_id, - *tree, 0, tmp, - grub_le_to_cpu64 (inode.size)) - != (grub_ssize_t) grub_le_to_cpu64 (inode.size)) - { - grub_free (direl); - grub_free (path_alloc); - grub_free (origpath); - grub_free (tmp); - return grub_errno; - } - grub_memcpy (tmp + grub_le_to_cpu64 (inode.size), path, - grub_strlen (path) + 1); - grub_free (path_alloc); - path = path_alloc = tmp; - if (path[0] == '/') - { - err = get_root (data, key, tree, type); - if (err) - { - grub_free (direl); - grub_free (path_alloc); - grub_free (origpath); - return err; - } - } - continue; - } - *type = cdirel->type; - - switch (cdirel->key.type) - { - case GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM: - { - struct grub_btrfs_root_item ri; - err = lower_bound (data, &cdirel->key, &key_out, - data->sblock.root_tree, - &elemaddr, &elemsize, NULL, 0); - if (err) - { - grub_free (direl); - grub_free (path_alloc); - grub_free (origpath); - return err; - } - if (cdirel->key.object_id != key_out.object_id - || cdirel->key.type != key_out.type) - { - grub_free (direl); - grub_free (path_alloc); - err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath); - grub_free (origpath); - return err; - } - err = grub_btrfs_read_logical (data, elemaddr, &ri, - sizeof (ri), 0); - if (err) - { - grub_free (direl); - grub_free (path_alloc); - grub_free (origpath); - return err; - } - key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; - key->offset = 0; - key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); - *tree = ri.tree; - break; - } - case GRUB_BTRFS_ITEM_TYPE_INODE_ITEM: - if (*slash && *type == GRUB_BTRFS_DIR_ITEM_TYPE_REGULAR) - { - grub_free (direl); - grub_free (path_alloc); - err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), origpath); - grub_free (origpath); - return err; - } - *key = cdirel->key; - if (*type == GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) - key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; - break; - default: - grub_free (path_alloc); - grub_free (origpath); - grub_free (direl); - return grub_error (GRUB_ERR_BAD_FS, "unrecognised object type 0x%x", - cdirel->key.type); - } - } - - grub_free (direl); - grub_free (origpath); - grub_free (path_alloc); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_btrfs_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_btrfs_data *data = grub_btrfs_mount (device); - struct grub_btrfs_key key_in, key_out; - grub_err_t err; - grub_disk_addr_t elemaddr; - grub_size_t elemsize; - grub_size_t allocated = 0; - struct grub_btrfs_dir_item *direl = NULL; - struct grub_btrfs_leaf_descriptor desc; - int r = 0; - grub_uint64_t tree; - grub_uint8_t type; - grub_size_t est_size = 0; - grub_size_t sz; - - if (!data) - return grub_errno; - - err = find_path (data, path, &key_in, &tree, &type); - if (err) - { - grub_btrfs_unmount (data); - return err; - } - if (type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) - { - grub_btrfs_unmount (data); - return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); - } - - err = lower_bound (data, &key_in, &key_out, tree, - &elemaddr, &elemsize, &desc, 0); - if (err) - { - grub_btrfs_unmount (data); - grub_free (desc.data); - return err; - } - if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM - || key_out.object_id != key_in.object_id) - { - r = next (data, &desc, &elemaddr, &elemsize, &key_out); - if (r <= 0) - goto out; - } - do - { - struct grub_btrfs_dir_item *cdirel; - if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM - || key_out.object_id != key_in.object_id) - { - r = 0; - break; - } - if (elemsize > allocated) - { - if (grub_mul (2, elemsize, &allocated) || - grub_add (allocated, 1, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory element size overflow")); - r = -grub_errno; - break; - } - grub_free (direl); - direl = grub_malloc (sz); - if (!direl) - { - r = -grub_errno; - break; - } - } - - err = grub_btrfs_read_logical (data, elemaddr, direl, elemsize, 0); - if (err) - { - r = -err; - break; - } - - if (direl == NULL || - grub_add (grub_le_to_cpu16 (direl->n), - grub_le_to_cpu16 (direl->m), &est_size) || - grub_add (est_size, sizeof (*direl), &est_size) || - grub_sub (est_size, sizeof (direl->name), &est_size) || - est_size > allocated) - { - grub_errno = GRUB_ERR_OUT_OF_RANGE; - r = -grub_errno; - goto out; - } - - for (cdirel = direl; - (grub_uint8_t *) cdirel - (grub_uint8_t *) direl - < (grub_ssize_t) elemsize; - cdirel = (void *) ((grub_uint8_t *) (direl + 1) - + grub_le_to_cpu16 (cdirel->n) - + grub_le_to_cpu16 (cdirel->m))) - { - char c; - struct grub_btrfs_inode inode; - struct grub_dirhook_info info; - - if (cdirel == NULL || - grub_add (grub_le_to_cpu16 (cdirel->n), - grub_le_to_cpu16 (cdirel->m), &est_size) || - grub_add (est_size, sizeof (*cdirel), &est_size) || - grub_sub (est_size, sizeof (cdirel->name), &est_size) || - est_size > allocated) - { - grub_errno = GRUB_ERR_OUT_OF_RANGE; - r = -grub_errno; - goto out; - } - - err = grub_btrfs_read_inode (data, &inode, cdirel->key.object_id, - tree); - grub_memset (&info, 0, sizeof (info)); - if (err) - grub_errno = GRUB_ERR_NONE; - else - { - info.mtime = grub_le_to_cpu64 (inode.mtime.sec); - info.mtimeset = 1; - } - c = cdirel->name[grub_le_to_cpu16 (cdirel->n)]; - cdirel->name[grub_le_to_cpu16 (cdirel->n)] = 0; - info.dir = (cdirel->type == GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY); - if (hook (cdirel->name, &info, hook_data)) - goto out; - cdirel->name[grub_le_to_cpu16 (cdirel->n)] = c; - } - r = next (data, &desc, &elemaddr, &elemsize, &key_out); - } - while (r > 0); - -out: - grub_free (direl); - - free_iterator (&desc); - grub_btrfs_unmount (data); - - return -r; -} - -static grub_err_t -grub_btrfs_open (struct grub_file *file, const char *name) -{ - struct grub_btrfs_data *data = grub_btrfs_mount (file->device); - grub_err_t err; - struct grub_btrfs_inode inode; - grub_uint8_t type; - struct grub_btrfs_key key_in; - - if (!data) - return grub_errno; - - err = find_path (data, name, &key_in, &data->tree, &type); - if (err) - { - grub_btrfs_unmount (data); - return err; - } - if (type != GRUB_BTRFS_DIR_ITEM_TYPE_REGULAR) - { - grub_btrfs_unmount (data); - return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file")); - } - - data->inode = key_in.object_id; - err = grub_btrfs_read_inode (data, &inode, data->inode, data->tree); - if (err) - { - grub_btrfs_unmount (data); - return err; - } - - file->data = data; - file->size = grub_le_to_cpu64 (inode.size); - - return err; -} - -static grub_err_t -grub_btrfs_close (grub_file_t file) -{ - grub_btrfs_unmount (file->data); - - return GRUB_ERR_NONE; -} - -static grub_ssize_t -grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) -{ - struct grub_btrfs_data *data = file->data; - - return grub_btrfs_extent_read (data, data->inode, - data->tree, file->offset, buf, len); -} - -static grub_err_t -grub_btrfs_uuid (grub_device_t device, char **uuid) -{ - struct grub_btrfs_data *data; - - *uuid = NULL; - - data = grub_btrfs_mount (device); - if (!data) - return grub_errno; - - *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])); - - grub_btrfs_unmount (data); - - return grub_errno; -} - -static grub_err_t -grub_btrfs_label (grub_device_t device, char **label) -{ - struct grub_btrfs_data *data; - - *label = NULL; - - data = grub_btrfs_mount (device); - if (!data) - return grub_errno; - - *label = grub_strndup (data->sblock.label, sizeof (data->sblock.label)); - - grub_btrfs_unmount (data); - - return grub_errno; -} - -#ifdef GRUB_UTIL - -struct embed_region { - unsigned int start; - unsigned int secs; -}; - -/* - * https://btrfs.wiki.kernel.org/index.php/Manpage/btrfs(5)#BOOTLOADER_SUPPORT - * The first 1 MiB on each device is unused with the exception of primary - * superblock that is on the offset 64 KiB and spans 4 KiB. - */ - -static const struct { - struct embed_region available; - struct embed_region used[6]; -} btrfs_head = { - .available = {0, GRUB_DISK_KiB_TO_SECTORS (1024)}, /* The first 1 MiB. */ - .used = { - {0, 1}, /* boot.S. */ - {GRUB_DISK_KiB_TO_SECTORS (64) - 1, 1}, /* Overflow guard. */ - {GRUB_DISK_KiB_TO_SECTORS (64), GRUB_DISK_KiB_TO_SECTORS (4)}, /* 4 KiB superblock. */ - {GRUB_DISK_KiB_TO_SECTORS (68), 1}, /* Overflow guard. */ - {GRUB_DISK_KiB_TO_SECTORS (1024) - 1, 1}, /* Overflow guard. */ - {0, 0} /* Array terminator. */ - } -}; - -static grub_err_t -grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), - unsigned int *nsectors, - unsigned int max_nsectors, - grub_embed_type_t embed_type, - grub_disk_addr_t **sectors) -{ - unsigned int i, j, n = 0; - const struct embed_region *u; - grub_disk_addr_t *map; - - if (embed_type != GRUB_EMBED_PCBIOS) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "BtrFS currently supports only PC-BIOS embedding"); - - map = grub_calloc (btrfs_head.available.secs, sizeof (*map)); - if (map == NULL) - return grub_errno; - - /* - * Populating the map array so that it can be used to index if a disk - * address is available to embed: - * - 0: available, - * - 1: unavailable. - */ - for (u = btrfs_head.used; u->secs; ++u) - { - unsigned int end = u->start + u->secs; - - if (end > btrfs_head.available.secs) - end = btrfs_head.available.secs; - for (i = u->start; i < end; ++i) - map[i] = 1; - } - - /* Adding up n until it matches total size of available embedding area. */ - for (i = 0; i < btrfs_head.available.secs; ++i) - if (map[i] == 0) - n++; - - if (n < *nsectors) - { - grub_free (map); - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("your core.img is unusually large. " - "It won't fit in the embedding area")); - } - - if (n > max_nsectors) - n = max_nsectors; - - /* - * Populating the array so that it can used to index disk block address for - * an image file's offset to be embedded on disk (the unit is in sectors): - * - i: The disk block address relative to btrfs_head.available.start, - * - j: The offset in image file. - */ - for (i = 0, j = 0; i < btrfs_head.available.secs && j < n; ++i) - if (map[i] == 0) - map[j++] = btrfs_head.available.start + i; - - *nsectors = n; - *sectors = map; - - return GRUB_ERR_NONE; -} -#endif - -static struct grub_fs grub_btrfs_fs = { - .name = "btrfs", - .fs_dir = grub_btrfs_dir, - .fs_open = grub_btrfs_open, - .fs_read = grub_btrfs_read, - .fs_close = grub_btrfs_close, - .fs_uuid = grub_btrfs_uuid, - .fs_label = grub_btrfs_label, -#ifdef GRUB_UTIL - .fs_embed = grub_btrfs_embed, - .reserved_first_sector = 1, - .blocklist_install = 0, -#endif -}; - -GRUB_MOD_INIT (btrfs) -{ - grub_btrfs_fs.mod = mod; - grub_fs_register (&grub_btrfs_fs); -} - -GRUB_MOD_FINI (btrfs) -{ - grub_fs_unregister (&grub_btrfs_fs); -} diff --git a/grub-core/fs/cbfs.c b/grub-core/fs/cbfs.c deleted file mode 100644 index b62c8777c..000000000 --- a/grub-core/fs/cbfs.c +++ /dev/null @@ -1,408 +0,0 @@ -/* cbfs.c - cbfs and tar filesystem. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007,2008,2009,2013 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 . - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - - -struct grub_archelp_data -{ - grub_disk_t disk; - grub_off_t hofs, next_hofs; - grub_off_t dofs; - grub_off_t size; - grub_off_t cbfs_start; - grub_off_t cbfs_end; - grub_off_t cbfs_align; -}; - -static grub_err_t -grub_cbfs_find_file (struct grub_archelp_data *data, char **name, - grub_int32_t *mtime, - grub_uint32_t *mode) -{ - grub_size_t offset; - for (;; - data->dofs = data->hofs + offset, - data->next_hofs = ALIGN_UP (data->dofs + data->size, data->cbfs_align)) - { - struct cbfs_file hd; - grub_size_t namesize; - - data->hofs = data->next_hofs; - - if (data->hofs >= data->cbfs_end) - { - *mode = GRUB_ARCHELP_ATTR_END; - return GRUB_ERR_NONE; - } - - if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd)) - return grub_errno; - - if (grub_memcmp (hd.magic, CBFS_FILE_MAGIC, sizeof (hd.magic)) != 0) - { - *mode = GRUB_ARCHELP_ATTR_END; - return GRUB_ERR_NONE; - } - data->size = grub_be_to_cpu32 (hd.len); - (void) mtime; - offset = grub_be_to_cpu32 (hd.offset); - - *mode = GRUB_ARCHELP_ATTR_FILE | GRUB_ARCHELP_ATTR_NOTIME; - - namesize = offset; - if (namesize >= sizeof (hd)) - namesize -= sizeof (hd); - if (namesize == 0) - continue; - *name = grub_malloc (namesize + 1); - if (*name == NULL) - return grub_errno; - - if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd), - namesize, *name)) - { - grub_free (*name); - return grub_errno; - } - - if ((*name)[0] == '\0') - { - grub_free (*name); - *name = NULL; - continue; - } - - (*name)[namesize] = 0; - - data->dofs = data->hofs + offset; - data->next_hofs = ALIGN_UP (data->dofs + data->size, data->cbfs_align); - return GRUB_ERR_NONE; - } -} - -static void -grub_cbfs_rewind (struct grub_archelp_data *data) -{ - data->next_hofs = data->cbfs_start; -} - -static struct grub_archelp_ops arcops = - { - .find_file = grub_cbfs_find_file, - .rewind = grub_cbfs_rewind - }; - -static int -validate_head (struct cbfs_header *head) -{ - return (head->magic == grub_cpu_to_be32_compile_time (CBFS_HEADER_MAGIC) - && (head->version - == grub_cpu_to_be32_compile_time (CBFS_HEADER_VERSION1) - || head->version - == grub_cpu_to_be32_compile_time (CBFS_HEADER_VERSION2)) - && (grub_be_to_cpu32 (head->bootblocksize) - < grub_be_to_cpu32 (head->romsize)) - && (grub_be_to_cpu32 (head->offset) - < grub_be_to_cpu32 (head->romsize)) - && (grub_be_to_cpu32 (head->offset) - + grub_be_to_cpu32 (head->bootblocksize) - < grub_be_to_cpu32 (head->romsize)) - && head->align != 0 - && (head->align & (head->align - 1)) == 0 - && head->romsize != 0); -} - -static struct grub_archelp_data * -grub_cbfs_mount (grub_disk_t disk) -{ - struct cbfs_file hd; - struct grub_archelp_data *data = NULL; - grub_uint32_t ptr; - grub_off_t header_off; - struct cbfs_header head; - - if (grub_disk_native_sectors (disk) == GRUB_DISK_SIZE_UNKNOWN) - goto fail; - - if (grub_disk_read (disk, grub_disk_native_sectors (disk) - 1, - GRUB_DISK_SECTOR_SIZE - sizeof (ptr), - sizeof (ptr), &ptr)) - goto fail; - - ptr = grub_cpu_to_le32 (ptr); - header_off = (grub_disk_native_sectors (disk) << GRUB_DISK_SECTOR_BITS) - + (grub_int32_t) ptr; - - if (grub_disk_read (disk, 0, header_off, - sizeof (head), &head)) - goto fail; - - if (!validate_head (&head)) - goto fail; - - data = (struct grub_archelp_data *) grub_zalloc (sizeof (*data)); - if (!data) - goto fail; - - data->cbfs_start = (grub_disk_native_sectors (disk) << GRUB_DISK_SECTOR_BITS) - - (grub_be_to_cpu32 (head.romsize) - grub_be_to_cpu32 (head.offset)); - data->cbfs_end = (grub_disk_native_sectors (disk) << GRUB_DISK_SECTOR_BITS) - - grub_be_to_cpu32 (head.bootblocksize); - data->cbfs_align = grub_be_to_cpu32 (head.align); - - if (data->cbfs_start >= (grub_disk_native_sectors (disk) << GRUB_DISK_SECTOR_BITS)) - goto fail; - if (data->cbfs_end > (grub_disk_native_sectors (disk) << GRUB_DISK_SECTOR_BITS)) - data->cbfs_end = (grub_disk_native_sectors (disk) << GRUB_DISK_SECTOR_BITS); - - data->next_hofs = data->cbfs_start; - - if (grub_disk_read (disk, 0, data->cbfs_start, sizeof (hd), &hd)) - goto fail; - - if (grub_memcmp (hd.magic, CBFS_FILE_MAGIC, sizeof (CBFS_FILE_MAGIC) - 1)) - goto fail; - - data->disk = disk; - - return data; - -fail: - grub_free (data); - grub_error (GRUB_ERR_BAD_FS, "not a cbfs filesystem"); - return 0; -} - -static grub_err_t -grub_cbfs_dir (grub_device_t device, const char *path_in, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_archelp_data *data; - grub_err_t err; - - data = grub_cbfs_mount (device->disk); - if (!data) - return grub_errno; - - err = grub_archelp_dir (data, &arcops, - path_in, hook, hook_data); - - grub_free (data); - - return err; -} - -static grub_err_t -grub_cbfs_open (grub_file_t file, const char *name_in) -{ - struct grub_archelp_data *data; - grub_err_t err; - - data = grub_cbfs_mount (file->device->disk); - if (!data) - return grub_errno; - - err = grub_archelp_open (data, &arcops, name_in); - if (err) - { - grub_free (data); - } - else - { - file->data = data; - file->size = data->size; - } - return err; -} - -static grub_ssize_t -grub_cbfs_read (grub_file_t file, char *buf, grub_size_t len) -{ - struct grub_archelp_data *data; - grub_ssize_t ret; - - data = file->data; - data->disk->read_hook = file->read_hook; - data->disk->read_hook_data = file->read_hook_data; - - ret = (grub_disk_read (data->disk, 0, data->dofs + file->offset, - len, buf)) ? -1 : (grub_ssize_t) len; - data->disk->read_hook = 0; - - return ret; -} - -static grub_err_t -grub_cbfs_close (grub_file_t file) -{ - struct grub_archelp_data *data; - - data = file->data; - grub_free (data); - - return grub_errno; -} - -#if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) \ - && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN) - -static char *cbfsdisk_addr; -static grub_off_t cbfsdisk_size = 0; - -static int -grub_cbfsdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - if (pull != GRUB_DISK_PULL_NONE) - return 0; - - return hook ("cbfsdisk", hook_data); -} - -static grub_err_t -grub_cbfsdisk_open (const char *name, grub_disk_t disk) -{ - if (grub_strcmp (name, "cbfsdisk")) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a cbfsdisk"); - - disk->total_sectors = cbfsdisk_size / GRUB_DISK_SECTOR_SIZE; - disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE; - disk->id = 0; - - return GRUB_ERR_NONE; -} - -static void -grub_cbfsdisk_close (grub_disk_t disk __attribute((unused))) -{ -} - -static grub_err_t -grub_cbfsdisk_read (grub_disk_t disk __attribute((unused)), - grub_disk_addr_t sector, - grub_size_t size, char *buf) -{ - grub_memcpy (buf, cbfsdisk_addr + (sector << GRUB_DISK_SECTOR_BITS), - size << GRUB_DISK_SECTOR_BITS); - return 0; -} - -static grub_err_t -grub_cbfsdisk_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_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "rom flashing isn't implemented yet"); -} - -static struct grub_disk_dev grub_cbfsdisk_dev = - { - .name = "cbfsdisk", - .id = GRUB_DISK_DEVICE_CBFSDISK_ID, - .disk_iterate = grub_cbfsdisk_iterate, - .disk_open = grub_cbfsdisk_open, - .disk_close = grub_cbfsdisk_close, - .disk_read = grub_cbfsdisk_read, - .disk_write = grub_cbfsdisk_write, - .next = 0 - }; - -static void -init_cbfsdisk (void) -{ - grub_uint32_t ptr; - struct cbfs_header *head; - - ptr = *((grub_uint32_t *) grub_absolute_pointer (0xfffffffc)); - head = (struct cbfs_header *) (grub_addr_t) ptr; - grub_dprintf ("cbfs", "head=%p\n", head); - - /* coreboot current supports only ROMs <= 16 MiB. Bigger ROMs will - have problems as RCBA is 18 MiB below end of 32-bit typically, - so either memory map would have to be rearranged or we'd need to support - reading ROMs through controller directly. - */ - if (ptr < 0xff000000 - || 0xffffffff - ptr < (grub_uint32_t) sizeof (*head) + 0xf - || !validate_head (head)) - return; - - cbfsdisk_size = ALIGN_UP (grub_be_to_cpu32 (head->romsize), - GRUB_DISK_SECTOR_SIZE); - cbfsdisk_addr = (void *) (grub_addr_t) (0x100000000ULL - cbfsdisk_size); - - grub_disk_dev_register (&grub_cbfsdisk_dev); -} - -static void -fini_cbfsdisk (void) -{ - if (! cbfsdisk_size) - return; - grub_disk_dev_unregister (&grub_cbfsdisk_dev); -} - -#endif - -static struct grub_fs grub_cbfs_fs = { - .name = "cbfs", - .fs_dir = grub_cbfs_dir, - .fs_open = grub_cbfs_open, - .fs_read = grub_cbfs_read, - .fs_close = grub_cbfs_close, -#ifdef GRUB_UTIL - .reserved_first_sector = 0, - .blocklist_install = 0, -#endif -}; - -GRUB_MOD_INIT (cbfs) -{ -#if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN) - init_cbfsdisk (); -#endif - if (!grub_is_lockdown ()) - { - grub_cbfs_fs.mod = mod; - grub_fs_register (&grub_cbfs_fs); - } -} - -GRUB_MOD_FINI (cbfs) -{ - if (!grub_is_lockdown ()) - grub_fs_unregister (&grub_cbfs_fs); -#if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN) - fini_cbfsdisk (); -#endif -} diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c deleted file mode 100644 index 1799f7ff5..000000000 --- a/grub-core/fs/cpio.c +++ /dev/null @@ -1,62 +0,0 @@ -/* cpio.c - cpio and tar filesystem. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007,2008,2009,2013 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 . - */ - -#include - -/* cpio support */ -#define ALIGN_CPIO(x) (ALIGN_UP ((x), 2)) -#define MAGIC "\xc7\x71" -struct head -{ - grub_uint16_t magic[1]; - grub_uint16_t dev; - grub_uint16_t ino; - grub_uint16_t mode[1]; - grub_uint16_t uid; - grub_uint16_t gid; - grub_uint16_t nlink; - grub_uint16_t rdev; - grub_uint16_t mtime[2]; - grub_uint16_t namesize[1]; - grub_uint16_t filesize[2]; -} GRUB_PACKED; - -static inline unsigned long long -read_number (const grub_uint16_t *arr, grub_size_t size) -{ - long long ret = 0; - while (size--) - ret = (ret << 16) | grub_le_to_cpu16 (*arr++); - return ret; -} - -#define FSNAME "cpiofs" - -#include "cpio_common.c" - -GRUB_MOD_INIT (cpio) -{ - grub_cpio_fs.mod = mod; - grub_fs_register (&grub_cpio_fs); -} - -GRUB_MOD_FINI (cpio) -{ - grub_fs_unregister (&grub_cpio_fs); -} diff --git a/grub-core/fs/cpio_be.c b/grub-core/fs/cpio_be.c deleted file mode 100644 index 7bed1b848..000000000 --- a/grub-core/fs/cpio_be.c +++ /dev/null @@ -1,62 +0,0 @@ -/* cpio.c - cpio and tar filesystem. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007,2008,2009,2013 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 . - */ - -#include - -#define ALIGN_CPIO(x) (ALIGN_UP ((x), 2)) -#define MAGIC "\x71\xc7" - -struct head -{ - grub_uint16_t magic[1]; - grub_uint16_t dev; - grub_uint16_t ino; - grub_uint16_t mode[1]; - grub_uint16_t uid; - grub_uint16_t gid; - grub_uint16_t nlink; - grub_uint16_t rdev; - grub_uint16_t mtime[2]; - grub_uint16_t namesize[1]; - grub_uint16_t filesize[2]; -} GRUB_PACKED; - -static inline unsigned long long -read_number (const grub_uint16_t *arr, grub_size_t size) -{ - long long ret = 0; - while (size--) - ret = (ret << 16) | grub_be_to_cpu16 (*arr++); - return ret; -} - -#define FSNAME "cpiofs_be" - -#include "cpio_common.c" - -GRUB_MOD_INIT (cpio_be) -{ - grub_cpio_fs.mod = mod; - grub_fs_register (&grub_cpio_fs); -} - -GRUB_MOD_FINI (cpio_be) -{ - grub_fs_unregister (&grub_cpio_fs); -} diff --git a/grub-core/fs/cpio_common.c b/grub-core/fs/cpio_common.c deleted file mode 100644 index 45ac119a8..000000000 --- a/grub-core/fs/cpio_common.c +++ /dev/null @@ -1,275 +0,0 @@ -/* cpio.c - cpio and tar filesystem. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007,2008,2009,2013 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct grub_archelp_data -{ - grub_disk_t disk; - grub_off_t hofs; - grub_off_t next_hofs; - grub_off_t dofs; - grub_off_t size; -}; - -#if __GNUC__ >= 9 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Waddress-of-packed-member" -#endif - -static grub_err_t -grub_cpio_find_file (struct grub_archelp_data *data, char **name, - grub_int32_t *mtime, grub_uint32_t *mode) -{ - struct head hd; - grub_size_t namesize; - grub_uint32_t modeval; - grub_size_t sz; - - data->hofs = data->next_hofs; - - if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd)) - return grub_errno; - - if (grub_memcmp (hd.magic, MAGIC, sizeof (hd.magic)) != 0 -#ifdef MAGIC2 - && grub_memcmp (hd.magic, MAGIC2, sizeof (hd.magic)) != 0 -#endif - ) - return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive"); - - if (grub_cast (read_number (hd.filesize, ARRAY_SIZE (hd.filesize)), &data->size)) - return grub_error (GRUB_ERR_BAD_FS, N_("data size overflow")); - - if (mtime) - { - if (grub_cast (read_number (hd.mtime, ARRAY_SIZE (hd.mtime)), mtime)) - return grub_error (GRUB_ERR_BAD_FS, N_("mtime overflow")); - } - - if (grub_cast (read_number (hd.mode, ARRAY_SIZE (hd.mode)), &modeval)) - return grub_error (GRUB_ERR_BAD_FS, N_("mode overflow")); - - if (grub_cast (read_number (hd.namesize, ARRAY_SIZE (hd.namesize)), &namesize)) - return grub_error (GRUB_ERR_BAD_FS, N_("namesize overflow")); - - /* Don't allow negative numbers. */ - if (namesize >= 0x80000000) - { - /* Probably a corruption, don't attempt to recover. */ - *mode = GRUB_ARCHELP_ATTR_END; - return GRUB_ERR_NONE; - } - - *mode = modeval; - - if (grub_add (namesize, 1, &sz)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("file name size overflow")); - - *name = grub_malloc (sz); - if (*name == NULL) - return grub_errno; - - if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd), - namesize, *name)) - { - grub_free (*name); - return grub_errno; - } - (*name)[namesize] = 0; - - if (data->size == 0 && modeval == 0 && namesize == 11 - && grub_memcmp(*name, "TRAILER!!!", 11) == 0) - { - *mode = GRUB_ARCHELP_ATTR_END; - grub_free (*name); - return GRUB_ERR_NONE; - } - - data->dofs = data->hofs + ALIGN_CPIO (sizeof (hd) + namesize); - data->next_hofs = data->dofs + ALIGN_CPIO (data->size); - return GRUB_ERR_NONE; -} - -#if __GNUC__ >= 9 -#pragma GCC diagnostic pop -#endif - -static char * -grub_cpio_get_link_target (struct grub_archelp_data *data) -{ - char *ret; - grub_err_t err; - grub_size_t sz; - - if (data->size == 0) - return grub_strdup (""); - - if (grub_add (data->size, 1, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("target data size overflow")); - return NULL; - } - ret = grub_malloc (sz); - if (!ret) - return NULL; - - err = grub_disk_read (data->disk, 0, data->dofs, data->size, - ret); - if (err) - { - grub_free (ret); - return NULL; - } - ret[data->size] = '\0'; - return ret; -} - -static void -grub_cpio_rewind (struct grub_archelp_data *data) -{ - data->next_hofs = 0; -} - -static struct grub_archelp_ops arcops = - { - .find_file = grub_cpio_find_file, - .get_link_target = grub_cpio_get_link_target, - .rewind = grub_cpio_rewind - }; - -static struct grub_archelp_data * -grub_cpio_mount (grub_disk_t disk) -{ - struct head hd; - struct grub_archelp_data *data; - - if (grub_disk_read (disk, 0, 0, sizeof (hd), &hd)) - goto fail; - - if (grub_memcmp (hd.magic, MAGIC, sizeof (MAGIC) - 1) -#ifdef MAGIC2 - && grub_memcmp (hd.magic, MAGIC2, sizeof (MAGIC2) - 1) -#endif - ) - goto fail; - - data = (struct grub_archelp_data *) grub_zalloc (sizeof (*data)); - if (!data) - goto fail; - - data->disk = disk; - - return data; - -fail: - grub_error (GRUB_ERR_BAD_FS, "not a " FSNAME " filesystem"); - return 0; -} - -static grub_err_t -grub_cpio_dir (grub_device_t device, const char *path_in, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_archelp_data *data; - grub_err_t err; - - data = grub_cpio_mount (device->disk); - if (!data) - return grub_errno; - - err = grub_archelp_dir (data, &arcops, - path_in, hook, hook_data); - - grub_free (data); - - return err; -} - -static grub_err_t -grub_cpio_open (grub_file_t file, const char *name_in) -{ - struct grub_archelp_data *data; - grub_err_t err; - - data = grub_cpio_mount (file->device->disk); - if (!data) - return grub_errno; - - err = grub_archelp_open (data, &arcops, name_in); - if (err) - { - grub_free (data); - } - else - { - file->data = data; - file->size = data->size; - } - return err; -} - -static grub_ssize_t -grub_cpio_read (grub_file_t file, char *buf, grub_size_t len) -{ - struct grub_archelp_data *data; - grub_ssize_t ret; - - data = file->data; - data->disk->read_hook = file->read_hook; - data->disk->read_hook_data = file->read_hook_data; - - ret = (grub_disk_read (data->disk, 0, data->dofs + file->offset, - len, buf)) ? -1 : (grub_ssize_t) len; - data->disk->read_hook = 0; - - return ret; -} - -static grub_err_t -grub_cpio_close (grub_file_t file) -{ - struct grub_archelp_data *data; - - data = file->data; - grub_free (data); - - return grub_errno; -} - -static struct grub_fs grub_cpio_fs = { - .name = FSNAME, - .fs_dir = grub_cpio_dir, - .fs_open = grub_cpio_open, - .fs_read = grub_cpio_read, - .fs_close = grub_cpio_close, -#ifdef GRUB_UTIL - .reserved_first_sector = 0, - .blocklist_install = 0, -#endif -}; diff --git a/grub-core/fs/erofs.c b/grub-core/fs/erofs.c deleted file mode 100644 index 82a05051d..000000000 --- a/grub-core/fs/erofs.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* erofs.c - Enhanced Read-Only File System */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define EROFS_SUPER_OFFSET 1024 -#define EROFS_MAGIC 0xE0F5E1E2 -#define EROFS_ISLOTBITS 5 - -#define EROFS_FEATURE_INCOMPAT_CHUNKED_FILE 0x00000004 -#define EROFS_ALL_FEATURE_INCOMPAT EROFS_FEATURE_INCOMPAT_CHUNKED_FILE - -struct grub_erofs_super -{ - grub_uint32_t magic; - grub_uint32_t checksum; - grub_uint32_t feature_compat; - grub_uint8_t log2_blksz; - grub_uint8_t sb_extslots; - - grub_uint16_t root_nid; - grub_uint64_t inos; - - grub_uint64_t build_time; - grub_uint32_t build_time_nsec; - grub_uint32_t blocks; - grub_uint32_t meta_blkaddr; - grub_uint32_t xattr_blkaddr; - grub_packed_guid_t uuid; - grub_uint8_t volume_name[16]; - grub_uint32_t feature_incompat; - - union - { - grub_uint16_t available_compr_algs; - grub_uint16_t lz4_max_distance; - } GRUB_PACKED u1; - - grub_uint16_t extra_devices; - grub_uint16_t devt_slotoff; - grub_uint8_t log2_dirblksz; - grub_uint8_t xattr_prefix_count; - grub_uint32_t xattr_prefix_start; - grub_uint64_t packed_nid; - grub_uint8_t reserved2[24]; -} GRUB_PACKED; - -#define EROFS_INODE_LAYOUT_COMPACT 0 -#define EROFS_INODE_LAYOUT_EXTENDED 1 - -#define EROFS_INODE_FLAT_PLAIN 0 -#define EROFS_INODE_COMPRESSED_FULL 1 -#define EROFS_INODE_FLAT_INLINE 2 -#define EROFS_INODE_COMPRESSED_COMPACT 3 -#define EROFS_INODE_CHUNK_BASED 4 - -#define EROFS_I_VERSION_MASKS 0x01 -#define EROFS_I_DATALAYOUT_MASKS 0x07 - -#define EROFS_I_VERSION_BIT 0 -#define EROFS_I_DATALAYOUT_BIT 1 - -struct grub_erofs_inode_chunk_info -{ - grub_uint16_t format; - grub_uint16_t reserved; -} GRUB_PACKED; - -#define EROFS_CHUNK_FORMAT_BLKBITS_MASK 0x001F -#define EROFS_CHUNK_FORMAT_INDEXES 0x0020 - -#define EROFS_BLOCK_MAP_ENTRY_SIZE 4 -#define EROFS_MAP_MAPPED 0x02 - -#define EROFS_NULL_ADDR 1 -#define EROFS_NAME_LEN 255 -#define EROFS_PATH_LEN 4096 -#define EROFS_MIN_LOG2_BLOCK_SIZE 9 -#define EROFS_MAX_LOG2_BLOCK_SIZE 16 - -struct grub_erofs_inode_chunk_index -{ - grub_uint16_t advise; - grub_uint16_t device_id; - grub_uint32_t blkaddr; -}; - -union grub_erofs_inode_i_u -{ - grub_uint32_t compressed_blocks; - grub_uint32_t raw_blkaddr; - - grub_uint32_t rdev; - - struct grub_erofs_inode_chunk_info c; -}; - -struct grub_erofs_inode_compact -{ - grub_uint16_t i_format; - - grub_uint16_t i_xattr_icount; - grub_uint16_t i_mode; - grub_uint16_t i_nlink; - grub_uint32_t i_size; - grub_uint32_t i_reserved; - - union grub_erofs_inode_i_u i_u; - - grub_uint32_t i_ino; - grub_uint16_t i_uid; - grub_uint16_t i_gid; - grub_uint32_t i_reserved2; -} GRUB_PACKED; - -struct grub_erofs_inode_extended -{ - grub_uint16_t i_format; - - grub_uint16_t i_xattr_icount; - grub_uint16_t i_mode; - grub_uint16_t i_reserved; - grub_uint64_t i_size; - - union grub_erofs_inode_i_u i_u; - - grub_uint32_t i_ino; - - grub_uint32_t i_uid; - grub_uint32_t i_gid; - grub_uint64_t i_mtime; - grub_uint32_t i_mtime_nsec; - grub_uint32_t i_nlink; - grub_uint8_t i_reserved2[16]; -} GRUB_PACKED; - -union grub_erofs_inode -{ - struct grub_erofs_inode_compact c; - struct grub_erofs_inode_extended e; -} GRUB_PACKED; - -#define EROFS_FT_UNKNOWN 0 -#define EROFS_FT_REG_FILE 1 -#define EROFS_FT_DIR 2 -#define EROFS_FT_CHRDEV 3 -#define EROFS_FT_BLKDEV 4 -#define EROFS_FT_FIFO 5 -#define EROFS_FT_SOCK 6 -#define EROFS_FT_SYMLINK 7 - -struct grub_erofs_dirent -{ - grub_uint64_t nid; - grub_uint16_t nameoff; - grub_uint8_t file_type; - grub_uint8_t reserved; -} GRUB_PACKED; - -struct grub_erofs_map_blocks -{ - grub_uint64_t m_pa; /* physical address */ - grub_uint64_t m_la; /* logical address */ - grub_uint64_t m_plen; /* physical length */ - grub_uint64_t m_llen; /* logical length */ - grub_uint32_t m_flags; -}; - -struct grub_erofs_xattr_ibody_header -{ - grub_uint32_t h_reserved; - grub_uint8_t h_shared_count; - grub_uint8_t h_reserved2[7]; - grub_uint32_t h_shared_xattrs[0]; -}; - -struct grub_fshelp_node -{ - struct grub_erofs_data *data; - union grub_erofs_inode inode; - - grub_uint64_t ino; - grub_uint8_t inode_type; - grub_uint8_t inode_datalayout; - - /* If the inode has been read into memory? */ - bool inode_loaded; -}; - -struct grub_erofs_data -{ - grub_disk_t disk; - struct grub_erofs_super sb; - - struct grub_fshelp_node inode; -}; - -#define erofs_blocksz(data) (((grub_uint32_t) 1) << data->sb.log2_blksz) - -static grub_size_t -grub_erofs_strnlen (const char *s, grub_size_t n) -{ - const char *p = s; - - if (n == 0) - return 0; - - while (n-- && *p) - p++; - - return p - s; -} - -static grub_uint64_t -erofs_iloc (grub_fshelp_node_t node) -{ - struct grub_erofs_super *sb = &node->data->sb; - - return ((grub_uint64_t) grub_le_to_cpu32 (sb->meta_blkaddr) << sb->log2_blksz) + - (node->ino << EROFS_ISLOTBITS); -} - -static grub_err_t -erofs_read_inode (struct grub_erofs_data *data, grub_fshelp_node_t node) -{ - union grub_erofs_inode *di; - grub_err_t err; - grub_uint16_t i_format; - grub_uint64_t addr = erofs_iloc (node); - - di = (union grub_erofs_inode *) &node->inode; - - err = grub_disk_read (data->disk, addr >> GRUB_DISK_SECTOR_BITS, - addr & (GRUB_DISK_SECTOR_SIZE - 1), - sizeof (struct grub_erofs_inode_compact), &di->c); - if (err != GRUB_ERR_NONE) - return err; - - i_format = grub_le_to_cpu16 (di->c.i_format); - node->inode_type = (i_format >> EROFS_I_VERSION_BIT) & EROFS_I_VERSION_MASKS; - node->inode_datalayout = (i_format >> EROFS_I_DATALAYOUT_BIT) & EROFS_I_DATALAYOUT_MASKS; - - switch (node->inode_type) - { - case EROFS_INODE_LAYOUT_EXTENDED: - addr += sizeof (struct grub_erofs_inode_compact); - err = grub_disk_read (data->disk, addr >> GRUB_DISK_SECTOR_BITS, - addr & (GRUB_DISK_SECTOR_SIZE - 1), - sizeof (struct grub_erofs_inode_extended) - sizeof (struct grub_erofs_inode_compact), - (grub_uint8_t *) di + sizeof (struct grub_erofs_inode_compact)); - if (err != GRUB_ERR_NONE) - return err; - break; - case EROFS_INODE_LAYOUT_COMPACT: - break; - default: - return grub_error (GRUB_ERR_BAD_FS, "invalid type %u @ inode %" PRIuGRUB_UINT64_T, - node->inode_type, node->ino); - } - - node->inode_loaded = true; - - return 0; -} - -static grub_uint64_t -erofs_inode_size (grub_fshelp_node_t node) -{ - return node->inode_type == EROFS_INODE_LAYOUT_COMPACT - ? sizeof (struct grub_erofs_inode_compact) - : sizeof (struct grub_erofs_inode_extended); -} - -static grub_uint64_t -erofs_inode_file_size (grub_fshelp_node_t node) -{ - union grub_erofs_inode *di = (union grub_erofs_inode *) &node->inode; - - return node->inode_type == EROFS_INODE_LAYOUT_COMPACT - ? grub_le_to_cpu32 (di->c.i_size) - : grub_le_to_cpu64 (di->e.i_size); -} - -static grub_uint32_t -erofs_inode_xattr_ibody_size (grub_fshelp_node_t node) -{ - grub_uint16_t cnt = grub_le_to_cpu16 (node->inode.e.i_xattr_icount); - - if (cnt == 0) - return 0; - - return sizeof (struct grub_erofs_xattr_ibody_header) + ((cnt - 1) * sizeof (grub_uint32_t)); -} - -static grub_uint64_t -erofs_inode_mtime (grub_fshelp_node_t node) -{ - return node->inode_type == EROFS_INODE_LAYOUT_COMPACT - ? grub_le_to_cpu64 (node->data->sb.build_time) - : grub_le_to_cpu64 (node->inode.e.i_mtime); -} - -static grub_err_t -erofs_map_blocks_flatmode (grub_fshelp_node_t node, - struct grub_erofs_map_blocks *map) -{ - grub_uint64_t nblocks, lastblk, file_size; - bool tailendpacking = (node->inode_datalayout == EROFS_INODE_FLAT_INLINE); - grub_uint64_t blocksz = erofs_blocksz (node->data); - - /* `file_size` is checked by caller and cannot be zero, hence nblocks > 0. */ - file_size = erofs_inode_file_size (node); - if (grub_add (file_size, blocksz - 1, &nblocks)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "nblocks overflow"); - nblocks >>= node->data->sb.log2_blksz; - lastblk = nblocks - tailendpacking; - - map->m_flags = EROFS_MAP_MAPPED; - - /* No overflow as (lastblk <= nblocks) && (nblocks * blocksz <= UINT64_MAX - blocksz + 1). */ - if (map->m_la < (lastblk * blocksz)) - { - if (grub_mul ((grub_uint64_t) grub_le_to_cpu32 (node->inode.e.i_u.raw_blkaddr), blocksz, &map->m_pa) || - grub_add (map->m_pa, map->m_la, &map->m_pa)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "m_pa overflow"); - if (grub_sub (lastblk * blocksz, map->m_la, &map->m_plen)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "m_plen underflow"); - } - else if (tailendpacking) - { - if (grub_add (erofs_iloc (node), erofs_inode_size (node), &map->m_pa) || - grub_add (map->m_pa, erofs_inode_xattr_ibody_size (node), &map->m_pa) || - grub_add (map->m_pa, map->m_la & (blocksz - 1), &map->m_pa)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "m_pa overflow when handling tailpacking"); - if (grub_sub (file_size, map->m_la, &map->m_plen)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "m_plen overflow when handling tailpacking"); - - /* No overflow as map->m_plen <= UINT64_MAX - blocksz + 1. */ - if (((map->m_pa & (blocksz - 1)) + map->m_plen) > blocksz) - return grub_error (GRUB_ERR_BAD_FS, - "inline data cross block boundary @ inode %" PRIuGRUB_UINT64_T, - node->ino); - } - else - return grub_error (GRUB_ERR_BAD_FS, - "invalid map->m_la=%" PRIuGRUB_UINT64_T - " @ inode %" PRIuGRUB_UINT64_T, - map->m_la, node->ino); - - map->m_llen = map->m_plen; - return GRUB_ERR_NONE; -} - -static grub_err_t -erofs_map_blocks_chunkmode (grub_fshelp_node_t node, - struct grub_erofs_map_blocks *map) -{ - grub_uint16_t chunk_format = grub_le_to_cpu16 (node->inode.e.i_u.c.format); - grub_uint64_t unit, pos, chunknr, blkaddr; - grub_uint8_t chunkbits; - grub_err_t err; - - if (chunk_format & EROFS_CHUNK_FORMAT_INDEXES) - unit = sizeof (struct grub_erofs_inode_chunk_index); - else - unit = EROFS_BLOCK_MAP_ENTRY_SIZE; - - chunkbits = node->data->sb.log2_blksz + (chunk_format & EROFS_CHUNK_FORMAT_BLKBITS_MASK); - if (chunkbits > 63) - return grub_error (GRUB_ERR_BAD_FS, "invalid chunkbits %u @ inode %" PRIuGRUB_UINT64_T, - chunkbits, node->ino); - - chunknr = map->m_la >> chunkbits; - - if (grub_add (erofs_iloc (node), erofs_inode_size (node), &pos)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "chunkmap position overflow when adding inode size"); - - if (grub_add (pos, erofs_inode_xattr_ibody_size (node), &pos)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "chunkmap position overflow when adding xattr size"); - - if (ALIGN_UP_OVF (pos, unit, &pos)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "position overflow when seeking at the start of chunkmap"); - - /* No overflow for multiplication as chunkbits >= 9 and sizeof(unit) <= 8. */ - if (grub_add (pos, chunknr * unit, &pos)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "chunkmap position overflow when finding the specific chunk"); - - map->m_la = chunknr << chunkbits; - - if (grub_sub (erofs_inode_file_size (node), map->m_la, &map->m_plen)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "m_plen underflow"); - map->m_plen = grub_min (((grub_uint64_t) 1) << chunkbits, - ALIGN_UP (map->m_plen, erofs_blocksz (node->data))); - - if (chunk_format & EROFS_CHUNK_FORMAT_INDEXES) - { - struct grub_erofs_inode_chunk_index idx; - - err = grub_disk_read (node->data->disk, pos >> GRUB_DISK_SECTOR_BITS, - pos & (GRUB_DISK_SECTOR_SIZE - 1), unit, &idx); - if (err != GRUB_ERR_NONE) - return err; - - blkaddr = grub_le_to_cpu32 (idx.blkaddr); - } - else - { - grub_uint32_t blkaddr_le; - - err = grub_disk_read (node->data->disk, pos >> GRUB_DISK_SECTOR_BITS, - pos & (GRUB_DISK_SECTOR_SIZE - 1), unit, &blkaddr_le); - if (err != GRUB_ERR_NONE) - return err; - - blkaddr = grub_le_to_cpu32 (blkaddr_le); - } - - if (blkaddr == EROFS_NULL_ADDR) - { - map->m_pa = 0; - map->m_flags = 0; - } - else - { - map->m_pa = blkaddr << node->data->sb.log2_blksz; - map->m_flags = EROFS_MAP_MAPPED; - } - - map->m_llen = map->m_plen; - return GRUB_ERR_NONE; -} - -static grub_err_t -erofs_map_blocks (grub_fshelp_node_t node, struct grub_erofs_map_blocks *map) -{ - if (map->m_la >= erofs_inode_file_size (node)) - { - map->m_llen = map->m_plen = 0; - map->m_pa = 0; - map->m_flags = 0; - return GRUB_ERR_NONE; - } - - if (node->inode_datalayout != EROFS_INODE_CHUNK_BASED) - return erofs_map_blocks_flatmode (node, map); - else - return erofs_map_blocks_chunkmode (node, map); -} - -static grub_err_t -erofs_read_raw_data (grub_fshelp_node_t node, grub_uint8_t *buf, grub_uint64_t size, - grub_uint64_t offset, grub_uint64_t *bytes) -{ - struct grub_erofs_map_blocks map = {0}; - grub_uint64_t cur; - grub_err_t err; - - if (bytes) - *bytes = 0; - - if (node->inode_loaded == false) - { - err = erofs_read_inode (node->data, node); - if (err != GRUB_ERR_NONE) - return err; - } - - cur = offset; - while (cur < offset + size) - { - grub_uint8_t *const estart = buf + cur - offset; - grub_uint64_t eend, moff = 0; - - map.m_la = cur; - err = erofs_map_blocks (node, &map); - if (err != GRUB_ERR_NONE) - return err; - - if (grub_add(map.m_la, map.m_llen, &eend)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "eend overflow"); - - eend = grub_min (eend, offset + size); - if (!(map.m_flags & EROFS_MAP_MAPPED)) - { - if (!map.m_llen) - { - /* Reached EOF. */ - grub_memset (estart, 0, offset + size - cur); - cur = offset + size; - continue; - } - - /* It's a hole. */ - grub_memset (estart, 0, eend - cur); - if (bytes) - *bytes += eend - cur; - cur = eend; - continue; - } - - if (cur > map.m_la) - { - moff = cur - map.m_la; - map.m_la = cur; - } - - err = grub_disk_read (node->data->disk, - (map.m_pa + moff) >> GRUB_DISK_SECTOR_BITS, - (map.m_pa + moff) & (GRUB_DISK_SECTOR_SIZE - 1), - eend - map.m_la, estart); - if (err != GRUB_ERR_NONE) - return err; - - if (bytes) - *bytes += eend - map.m_la; - - cur = eend; - } - - return GRUB_ERR_NONE; -} - -static int -erofs_iterate_dir (grub_fshelp_node_t dir, grub_fshelp_iterate_dir_hook_t hook, - void *hook_data) -{ - grub_uint64_t offset = 0, file_size; - grub_uint32_t blocksz = erofs_blocksz (dir->data); - grub_uint8_t *buf; - grub_err_t err; - - if (dir->inode_loaded == false) - { - err = erofs_read_inode (dir->data, dir); - if (err != GRUB_ERR_NONE) - return 0; - } - - file_size = erofs_inode_file_size (dir); - buf = grub_malloc (blocksz); - if (buf == NULL) - return 0; - - while (offset < file_size) - { - grub_uint64_t maxsize = grub_min (blocksz, file_size - offset); - struct grub_erofs_dirent *de = (void *) buf, *end; - grub_uint16_t nameoff; - - err = erofs_read_raw_data (dir, buf, maxsize, offset, NULL); - if (err != GRUB_ERR_NONE) - goto not_found; - - nameoff = grub_le_to_cpu16 (de->nameoff); - if (nameoff < sizeof (struct grub_erofs_dirent) || nameoff >= maxsize) - { - grub_error (GRUB_ERR_BAD_FS, - "invalid nameoff %u @ inode %" PRIuGRUB_UINT64_T, - nameoff, dir->ino); - goto not_found; - } - - end = (struct grub_erofs_dirent *) ((grub_uint8_t *) de + nameoff); - while (de < end) - { - struct grub_fshelp_node *fdiro; - enum grub_fshelp_filetype type; - char filename[EROFS_NAME_LEN + 1]; - grub_size_t de_namelen; - const char *de_name; - - fdiro = grub_malloc (sizeof (struct grub_fshelp_node)); - if (fdiro == NULL) - goto not_found; - - fdiro->data = dir->data; - fdiro->ino = grub_le_to_cpu64 (de->nid); - fdiro->inode_loaded = false; - - nameoff = grub_le_to_cpu16 (de->nameoff); - if (nameoff < sizeof (struct grub_erofs_dirent) || nameoff >= maxsize) - { - grub_error (GRUB_ERR_BAD_FS, - "invalid nameoff %u @ inode %" PRIuGRUB_UINT64_T, - nameoff, dir->ino); - grub_free (fdiro); - goto not_found; - } - - de_name = (char *) buf + nameoff; - if (de + 1 >= end) - de_namelen = grub_erofs_strnlen (de_name, maxsize - nameoff); - else - { - if (grub_sub (grub_le_to_cpu16 (de[1].nameoff), nameoff, &de_namelen)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "de_namelen underflow"); - grub_free (fdiro); - goto not_found; - } - } - - if (nameoff + de_namelen > maxsize || de_namelen > EROFS_NAME_LEN) - { - grub_error (GRUB_ERR_BAD_FS, - "invalid de_namelen %" PRIuGRUB_SIZE - " @ inode %" PRIuGRUB_UINT64_T, - de_namelen, dir->ino); - grub_free (fdiro); - goto not_found; - } - - grub_memcpy (filename, de_name, de_namelen); - filename[de_namelen] = '\0'; - - switch (grub_le_to_cpu16 (de->file_type)) - { - case EROFS_FT_REG_FILE: - case EROFS_FT_BLKDEV: - case EROFS_FT_CHRDEV: - case EROFS_FT_FIFO: - case EROFS_FT_SOCK: - type = GRUB_FSHELP_REG; - break; - case EROFS_FT_DIR: - type = GRUB_FSHELP_DIR; - break; - case EROFS_FT_SYMLINK: - type = GRUB_FSHELP_SYMLINK; - break; - case EROFS_FT_UNKNOWN: - default: - type = GRUB_FSHELP_UNKNOWN; - } - - if (hook (filename, type, fdiro, hook_data)) - { - grub_free (buf); - return 1; - } - - ++de; - } - - offset += maxsize; - } - - not_found: - grub_free (buf); - return 0; -} - -static char * -erofs_read_symlink (grub_fshelp_node_t node) -{ - char *symlink; - grub_size_t sz, lsz; - grub_err_t err; - - if (node->inode_loaded == false) - { - err = erofs_read_inode (node->data, node); - if (err != GRUB_ERR_NONE) - return NULL; - } - - sz = erofs_inode_file_size (node); - if (sz >= EROFS_PATH_LEN) - { - grub_error (GRUB_ERR_BAD_FS, - "symlink too long @ inode %" PRIuGRUB_UINT64_T, node->ino); - return NULL; - } - - if (grub_add (sz, 1, &lsz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink size overflow")); - return NULL; - } - symlink = grub_malloc (lsz); - if (symlink == NULL) - return NULL; - - err = erofs_read_raw_data (node, (grub_uint8_t *) symlink, sz, 0, NULL); - if (err != GRUB_ERR_NONE) - { - grub_free (symlink); - return NULL; - } - - symlink[sz] = '\0'; - return symlink; -} - -static struct grub_erofs_data * -erofs_mount (grub_disk_t disk, bool read_root) -{ - struct grub_erofs_super sb; - grub_err_t err; - struct grub_erofs_data *data; - grub_uint32_t feature; - - err = grub_disk_read (disk, EROFS_SUPER_OFFSET >> GRUB_DISK_SECTOR_BITS, 0, - sizeof (sb), &sb); - if (err != GRUB_ERR_NONE) - return NULL; - if (sb.magic != grub_cpu_to_le32_compile_time (EROFS_MAGIC) || - grub_le_to_cpu32 (sb.log2_blksz) < EROFS_MIN_LOG2_BLOCK_SIZE || - grub_le_to_cpu32 (sb.log2_blksz) > EROFS_MAX_LOG2_BLOCK_SIZE) - { - grub_error (GRUB_ERR_BAD_FS, "not a valid erofs filesystem"); - return NULL; - } - - feature = grub_le_to_cpu32 (sb.feature_incompat); - if (feature & ~EROFS_ALL_FEATURE_INCOMPAT) - { - grub_error (GRUB_ERR_BAD_FS, "unsupported features: 0x%x", - feature & ~EROFS_ALL_FEATURE_INCOMPAT); - return NULL; - } - - data = grub_malloc (sizeof (*data)); - if (data == NULL) - return NULL; - - data->disk = disk; - data->sb = sb; - - if (read_root) - { - data->inode.data = data; - data->inode.ino = grub_le_to_cpu16 (sb.root_nid); - err = erofs_read_inode (data, &data->inode); - if (err != GRUB_ERR_NONE) - { - grub_free (data); - return NULL; - } - } - - return data; -} - -/* Context for grub_erofs_dir. */ -struct grub_erofs_dir_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; - struct grub_erofs_data *data; -}; - -/* Helper for grub_erofs_dir. */ -static int -erofs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, void *data) -{ - struct grub_erofs_dir_ctx *ctx = data; - struct grub_dirhook_info info = {0}; - grub_err_t err; - - if (node->inode_loaded == false) - { - err = erofs_read_inode (ctx->data, node); - if (err != GRUB_ERR_NONE) - return 0; - } - - if (node->inode_loaded == true) - { - info.mtimeset = 1; - info.mtime = erofs_inode_mtime (node); - } - - info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); - grub_free (node); - return ctx->hook (filename, &info, ctx->hook_data); -} - -static grub_err_t -grub_erofs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, - void *hook_data) -{ - grub_fshelp_node_t fdiro = NULL; - grub_err_t err; - struct grub_erofs_dir_ctx ctx = { - .hook = hook, - .hook_data = hook_data - }; - - ctx.data = erofs_mount (device->disk, true); - if (ctx.data == NULL) - goto fail; - - err = grub_fshelp_find_file (path, &ctx.data->inode, &fdiro, erofs_iterate_dir, - erofs_read_symlink, GRUB_FSHELP_DIR); - if (err != GRUB_ERR_NONE) - goto fail; - - erofs_iterate_dir (fdiro, erofs_dir_iter, &ctx); - - fail: - if (fdiro != &ctx.data->inode) - grub_free (fdiro); - grub_free (ctx.data); - - return grub_errno; -} - -static grub_err_t -grub_erofs_open (grub_file_t file, const char *name) -{ - struct grub_erofs_data *data; - struct grub_fshelp_node *fdiro = NULL; - grub_err_t err; - - data = erofs_mount (file->device->disk, true); - if (data == NULL) - { - err = grub_errno; - goto fail; - } - - err = grub_fshelp_find_file (name, &data->inode, &fdiro, erofs_iterate_dir, - erofs_read_symlink, GRUB_FSHELP_REG); - if (err != GRUB_ERR_NONE) - goto fail; - - if (fdiro->inode_loaded == false) - { - err = erofs_read_inode (data, fdiro); - if (err != GRUB_ERR_NONE) - goto fail; - } - - grub_memcpy (&data->inode, fdiro, sizeof (*fdiro)); - grub_free (fdiro); - - file->data = data; - file->size = erofs_inode_file_size (&data->inode); - - return GRUB_ERR_NONE; - - fail: - if (fdiro != &data->inode) - grub_free (fdiro); - grub_free (data); - - return err; -} - -static grub_ssize_t -grub_erofs_read (grub_file_t file, char *buf, grub_size_t len) -{ - struct grub_erofs_data *data = file->data; - struct grub_fshelp_node *inode = &data->inode; - grub_off_t off = file->offset; - grub_uint64_t ret = 0, file_size; - grub_err_t err; - - if (inode->inode_loaded == false) - { - err = erofs_read_inode (data, inode); - if (err != GRUB_ERR_NONE) - return -1; - } - - file_size = erofs_inode_file_size (inode); - - if (off > file_size) - { - grub_error (GRUB_ERR_IO, "read past EOF @ inode %" PRIuGRUB_UINT64_T, inode->ino); - return -1; - } - if (off == file_size) - return 0; - - if (off + len > file_size) - len = file_size - off; - - err = erofs_read_raw_data (inode, (grub_uint8_t *) buf, len, off, &ret); - if (err != GRUB_ERR_NONE) - return -1; - - return ret; -} - -static grub_err_t -grub_erofs_close (grub_file_t file) -{ - grub_free (file->data); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_erofs_uuid (grub_device_t device, char **uuid) -{ - struct grub_erofs_data *data; - - data = erofs_mount (device->disk, false); - if (data == NULL) - { - *uuid = NULL; - return grub_errno; - } - - *uuid = grub_xasprintf ("%pG", &data->sb.uuid); - - grub_free (data); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_erofs_label (grub_device_t device, char **label) -{ - struct grub_erofs_data *data; - - data = erofs_mount (device->disk, false); - if (data == NULL) - { - *label = NULL; - return grub_errno; - } - - *label = grub_strndup ((char *) data->sb.volume_name, sizeof (data->sb.volume_name)); - grub_free (data); - - if (*label == NULL) - return grub_errno; - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_erofs_mtime (grub_device_t device, grub_int64_t *tm) -{ - struct grub_erofs_data *data; - - data = erofs_mount (device->disk, false); - if (data == NULL) - { - *tm = 0; - return grub_errno; - } - - *tm = grub_le_to_cpu64 (data->sb.build_time); - - grub_free (data); - - return GRUB_ERR_NONE; -} - -static struct grub_fs grub_erofs_fs = { - .name = "erofs", - .fs_dir = grub_erofs_dir, - .fs_open = grub_erofs_open, - .fs_read = grub_erofs_read, - .fs_close = grub_erofs_close, - .fs_uuid = grub_erofs_uuid, - .fs_label = grub_erofs_label, - .fs_mtime = grub_erofs_mtime, -#ifdef GRUB_UTIL - .reserved_first_sector = 1, - .blocklist_install = 0, -#endif - .next = 0, -}; - -GRUB_MOD_INIT (erofs) -{ - grub_erofs_fs.mod = mod; - grub_fs_register (&grub_erofs_fs); -} - -GRUB_MOD_FINI (erofs) -{ - grub_fs_unregister (&grub_erofs_fs); -} diff --git a/grub-core/fs/exfat.c b/grub-core/fs/exfat.c deleted file mode 100644 index fe149ddd3..000000000 --- a/grub-core/fs/exfat.c +++ /dev/null @@ -1,2 +0,0 @@ -#define MODE_EXFAT 1 -#include "fat.c" diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c deleted file mode 100644 index 72b4aa1e6..000000000 --- a/grub-core/fs/f2fs.c +++ /dev/null @@ -1,1377 +0,0 @@ -/* - * f2fs.c - Flash-Friendly File System - * - * Written by Jaegeuk Kim - * - * Copyright (C) 2015 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* F2FS Magic Number. */ -#define F2FS_SUPER_MAGIC 0xf2f52010 - -#define CHECKSUM_OFFSET 4092 /* Must be aligned 4 bytes. */ -#define U32_CHECKSUM_OFFSET (CHECKSUM_OFFSET >> 2) -#define CRCPOLY_LE 0xedb88320 - -/* Byte-size offset. */ -#define F2FS_SUPER_OFFSET ((grub_disk_addr_t)1024) -#define F2FS_SUPER_OFFSET0 (F2FS_SUPER_OFFSET >> GRUB_DISK_SECTOR_BITS) -#define F2FS_SUPER_OFFSET1 ((F2FS_SUPER_OFFSET + F2FS_BLKSIZE) >> \ - GRUB_DISK_SECTOR_BITS) - -/* 9 bits for 512 bytes. */ -#define F2FS_MIN_LOG_SECTOR_SIZE 9 - -/* Support only 4KB block. */ -#define F2FS_BLK_BITS 12 -#define F2FS_BLKSIZE (1 << F2FS_BLK_BITS) -#define F2FS_BLK_SEC_BITS (F2FS_BLK_BITS - GRUB_DISK_SECTOR_BITS) - -#define VERSION_LEN 256 -#define F2FS_MAX_EXTENSION 64 - -#define CP_COMPACT_SUM_FLAG 0x00000004 -#define CP_UMOUNT_FLAG 0x00000001 - -#define MAX_ACTIVE_LOGS 16 -#define MAX_ACTIVE_NODE_LOGS 8 -#define MAX_ACTIVE_DATA_LOGS 8 -#define NR_CURSEG_DATA_TYPE 3 -#define NR_CURSEG_NODE_TYPE 3 -#define NR_CURSEG_TYPE (NR_CURSEG_DATA_TYPE + NR_CURSEG_NODE_TYPE) - -#define ENTRIES_IN_SUM 512 -#define SUMMARY_SIZE 7 -#define SUM_FOOTER_SIZE 5 -#define JENTRY_SIZE (sizeof(struct grub_f2fs_nat_jent)) -#define SUM_ENTRIES_SIZE (SUMMARY_SIZE * ENTRIES_IN_SUM) -#define SUM_JOURNAL_SIZE (F2FS_BLKSIZE - SUM_FOOTER_SIZE - SUM_ENTRIES_SIZE) -#define NAT_JOURNAL_ENTRIES ((SUM_JOURNAL_SIZE - 2) / JENTRY_SIZE) -#define NAT_JOURNAL_RESERVED ((SUM_JOURNAL_SIZE - 2) % JENTRY_SIZE) - -#define NAT_ENTRY_SIZE (sizeof(struct grub_f2fs_nat_entry)) -#define NAT_ENTRY_PER_BLOCK (F2FS_BLKSIZE / NAT_ENTRY_SIZE) - -#define F2FS_NAME_LEN 255 -#define F2FS_SLOT_LEN 8 -#define NR_DENTRY_IN_BLOCK 214 -#define SIZE_OF_DIR_ENTRY 11 /* By byte. */ -#define BITS_PER_BYTE 8 -#define SIZE_OF_DENTRY_BITMAP ((NR_DENTRY_IN_BLOCK + BITS_PER_BYTE - 1) / \ - BITS_PER_BYTE) -#define SIZE_OF_RESERVED (F2FS_BLKSIZE - \ - ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ - NR_DENTRY_IN_BLOCK + SIZE_OF_DENTRY_BITMAP)) - -#define F2FS_INLINE_XATTR_ADDRS 50 /* 200 bytes for inline xattrs. */ -#define DEF_ADDRS_PER_INODE 923 /* Address Pointers in an Inode. */ - -#define ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block. */ -#define NIDS_PER_BLOCK 1018 /* Node IDs in an Indirect Block. */ -#define NODE_DIR1_BLOCK (DEF_ADDRS_PER_INODE + 1) -#define NODE_DIR2_BLOCK (DEF_ADDRS_PER_INODE + 2) -#define NODE_IND1_BLOCK (DEF_ADDRS_PER_INODE + 3) -#define NODE_IND2_BLOCK (DEF_ADDRS_PER_INODE + 4) -#define NODE_DIND_BLOCK (DEF_ADDRS_PER_INODE + 5) - -#define MAX_INLINE_DATA (4 * (DEF_ADDRS_PER_INODE - \ - F2FS_INLINE_XATTR_ADDRS - 1)) -#define NR_INLINE_DENTRY (MAX_INLINE_DATA * BITS_PER_BYTE / \ - ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ - BITS_PER_BYTE + 1)) -#define INLINE_DENTRY_BITMAP_SIZE ((NR_INLINE_DENTRY + BITS_PER_BYTE - 1) / \ - BITS_PER_BYTE) -#define INLINE_RESERVED_SIZE (MAX_INLINE_DATA - \ - ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ - NR_INLINE_DENTRY + \ - INLINE_DENTRY_BITMAP_SIZE)) -#define CURSEG_HOT_DATA 0 - -#define CKPT_FLAG_SET(ckpt, f) (ckpt)->ckpt_flags & \ - grub_cpu_to_le32_compile_time (f) - -#define F2FS_INLINE_XATTR 0x01 /* File inline xattr flag. */ -#define F2FS_INLINE_DATA 0x02 /* File inline data flag. */ -#define F2FS_INLINE_DENTRY 0x04 /* File inline dentry flag. */ -#define F2FS_DATA_EXIST 0x08 /* File inline data exist flag. */ -#define F2FS_INLINE_DOTS 0x10 /* File having implicit dot dentries. */ - -#define MAX_VOLUME_NAME 512 -#define MAX_NAT_BITMAP_SIZE 3900 - -enum FILE_TYPE -{ - F2FS_FT_UNKNOWN, - F2FS_FT_REG_FILE = 1, - F2FS_FT_DIR = 2, - F2FS_FT_SYMLINK = 7 -}; - -struct grub_f2fs_superblock -{ - grub_uint32_t magic; - grub_uint16_t dummy1[2]; - grub_uint32_t log_sectorsize; - grub_uint32_t log_sectors_per_block; - grub_uint32_t log_blocksize; - grub_uint32_t log_blocks_per_seg; - grub_uint32_t segs_per_sec; - grub_uint32_t secs_per_zone; - grub_uint32_t checksum_offset; - grub_uint8_t dummy2[40]; - grub_uint32_t cp_blkaddr; - grub_uint32_t sit_blkaddr; - grub_uint32_t nat_blkaddr; - grub_uint32_t ssa_blkaddr; - grub_uint32_t main_blkaddr; - grub_uint32_t root_ino; - grub_uint32_t node_ino; - grub_uint32_t meta_ino; - grub_uint8_t uuid[16]; - grub_uint16_t volume_name[MAX_VOLUME_NAME]; - grub_uint32_t extension_count; - grub_uint8_t extension_list[F2FS_MAX_EXTENSION][8]; - grub_uint32_t cp_payload; - grub_uint8_t version[VERSION_LEN]; - grub_uint8_t init_version[VERSION_LEN]; -} GRUB_PACKED; - -struct grub_f2fs_checkpoint -{ - grub_uint64_t checkpoint_ver; - grub_uint64_t user_block_count; - grub_uint64_t valid_block_count; - grub_uint32_t rsvd_segment_count; - grub_uint32_t overprov_segment_count; - grub_uint32_t free_segment_count; - grub_uint32_t cur_node_segno[MAX_ACTIVE_NODE_LOGS]; - grub_uint16_t cur_node_blkoff[MAX_ACTIVE_NODE_LOGS]; - grub_uint32_t cur_data_segno[MAX_ACTIVE_DATA_LOGS]; - grub_uint16_t cur_data_blkoff[MAX_ACTIVE_DATA_LOGS]; - grub_uint32_t ckpt_flags; - grub_uint32_t cp_pack_total_block_count; - grub_uint32_t cp_pack_start_sum; - grub_uint32_t valid_node_count; - grub_uint32_t valid_inode_count; - grub_uint32_t next_free_nid; - grub_uint32_t sit_ver_bitmap_bytesize; - grub_uint32_t nat_ver_bitmap_bytesize; - grub_uint32_t checksum_offset; - grub_uint64_t elapsed_time; - grub_uint8_t alloc_type[MAX_ACTIVE_LOGS]; - grub_uint8_t sit_nat_version_bitmap[MAX_NAT_BITMAP_SIZE]; - grub_uint32_t checksum; -} GRUB_PACKED; - -struct grub_f2fs_nat_entry { - grub_uint8_t version; - grub_uint32_t ino; - grub_uint32_t block_addr; -} GRUB_PACKED; - -struct grub_f2fs_nat_jent -{ - grub_uint32_t nid; - struct grub_f2fs_nat_entry ne; -} GRUB_PACKED; - -struct grub_f2fs_nat_journal { - grub_uint16_t n_nats; - struct grub_f2fs_nat_jent entries[NAT_JOURNAL_ENTRIES]; - grub_uint8_t reserved[NAT_JOURNAL_RESERVED]; -} GRUB_PACKED; - -struct grub_f2fs_nat_block { - struct grub_f2fs_nat_entry ne[NAT_ENTRY_PER_BLOCK]; -} GRUB_PACKED; - -struct grub_f2fs_dir_entry -{ - grub_uint32_t hash_code; - grub_uint32_t ino; - grub_uint16_t name_len; - grub_uint8_t file_type; -} GRUB_PACKED; - -struct grub_f2fs_inline_dentry -{ - grub_uint8_t dentry_bitmap[INLINE_DENTRY_BITMAP_SIZE]; - grub_uint8_t reserved[INLINE_RESERVED_SIZE]; - struct grub_f2fs_dir_entry dentry[NR_INLINE_DENTRY]; - grub_uint8_t filename[NR_INLINE_DENTRY][F2FS_SLOT_LEN]; -} GRUB_PACKED; - -struct grub_f2fs_dentry_block { - grub_uint8_t dentry_bitmap[SIZE_OF_DENTRY_BITMAP]; - grub_uint8_t reserved[SIZE_OF_RESERVED]; - struct grub_f2fs_dir_entry dentry[NR_DENTRY_IN_BLOCK]; - grub_uint8_t filename[NR_DENTRY_IN_BLOCK][F2FS_SLOT_LEN]; -} GRUB_PACKED; - -struct grub_f2fs_inode -{ - grub_uint16_t i_mode; - grub_uint8_t i_advise; - grub_uint8_t i_inline; - grub_uint32_t i_uid; - grub_uint32_t i_gid; - grub_uint32_t i_links; - grub_uint64_t i_size; - grub_uint64_t i_blocks; - grub_uint64_t i_atime; - grub_uint64_t i_ctime; - grub_uint64_t i_mtime; - grub_uint32_t i_atime_nsec; - grub_uint32_t i_ctime_nsec; - grub_uint32_t i_mtime_nsec; - grub_uint32_t i_generation; - grub_uint32_t i_current_depth; - grub_uint32_t i_xattr_nid; - grub_uint32_t i_flags; - grub_uint32_t i_pino; - grub_uint32_t i_namelen; - grub_uint8_t i_name[F2FS_NAME_LEN]; - grub_uint8_t i_dir_level; - grub_uint8_t i_ext[12]; - grub_uint32_t i_addr[DEF_ADDRS_PER_INODE]; - grub_uint32_t i_nid[5]; -} GRUB_PACKED; - -struct grub_direct_node { - grub_uint32_t addr[ADDRS_PER_BLOCK]; -} GRUB_PACKED; - -struct grub_indirect_node { - grub_uint32_t nid[NIDS_PER_BLOCK]; -} GRUB_PACKED; - -struct grub_f2fs_node -{ - union - { - struct grub_f2fs_inode i; - struct grub_direct_node dn; - struct grub_indirect_node in; - /* Should occupy F2FS_BLKSIZE totally. */ - char buf[F2FS_BLKSIZE - 40]; - }; - grub_uint8_t dummy[40]; -} GRUB_PACKED; - -struct grub_fshelp_node -{ - struct grub_f2fs_data *data; - struct grub_f2fs_node inode; - grub_uint32_t ino; - int inode_read; -}; - -struct grub_f2fs_data -{ - struct grub_f2fs_superblock sblock; - struct grub_f2fs_checkpoint ckpt; - - grub_uint32_t root_ino; - grub_uint32_t blocks_per_seg; - grub_uint32_t cp_blkaddr; - grub_uint32_t nat_blkaddr; - - struct grub_f2fs_nat_journal nat_j; - char *nat_bitmap; - grub_uint32_t nat_bitmap_size; - - grub_disk_t disk; - struct grub_f2fs_node *inode; - struct grub_fshelp_node diropen; -}; - -struct grub_f2fs_dir_iter_ctx -{ - struct grub_f2fs_data *data; - grub_fshelp_iterate_dir_hook_t hook; - void *hook_data; - grub_uint8_t *bitmap; - grub_uint8_t (*filename)[F2FS_SLOT_LEN]; - struct grub_f2fs_dir_entry *dentry; - int max; -}; - -struct grub_f2fs_dir_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; - struct grub_f2fs_data *data; -}; - -static grub_dl_t my_mod; - -static int -grub_f2fs_test_bit_le (int nr, const grub_uint8_t *addr) -{ - return addr[nr >> 3] & (1 << (nr & 7)); -} - -static char * -get_inline_addr (struct grub_f2fs_inode *inode) -{ - return (char *) &inode->i_addr[1]; -} - -static grub_uint64_t -grub_f2fs_file_size (struct grub_f2fs_inode *inode) -{ - return grub_le_to_cpu64 (inode->i_size); -} - -static grub_uint32_t -start_cp_addr (struct grub_f2fs_data *data) -{ - struct grub_f2fs_checkpoint *ckpt = &data->ckpt; - grub_uint32_t start_addr = data->cp_blkaddr; - - if (!(ckpt->checkpoint_ver & grub_cpu_to_le64_compile_time(1))) - return start_addr + data->blocks_per_seg; - - return start_addr; -} - -static grub_uint32_t -start_sum_block (struct grub_f2fs_data *data) -{ - struct grub_f2fs_checkpoint *ckpt = &data->ckpt; - - return start_cp_addr (data) + grub_le_to_cpu32 (ckpt->cp_pack_start_sum); -} - -static grub_uint32_t -sum_blk_addr (struct grub_f2fs_data *data, int base, int type) -{ - struct grub_f2fs_checkpoint *ckpt = &data->ckpt; - - return start_cp_addr (data) + - grub_le_to_cpu32 (ckpt->cp_pack_total_block_count) - - (base + 1) + type; -} - -static void * -nat_bitmap_ptr (struct grub_f2fs_data *data, grub_uint32_t *nat_bitmap_size) -{ - struct grub_f2fs_checkpoint *ckpt = &data->ckpt; - grub_uint32_t offset; - *nat_bitmap_size = MAX_NAT_BITMAP_SIZE; - - if (grub_le_to_cpu32 (data->sblock.cp_payload) > 0) - return ckpt->sit_nat_version_bitmap; - - offset = grub_le_to_cpu32 (ckpt->sit_ver_bitmap_bytesize); - if (offset >= MAX_NAT_BITMAP_SIZE) - return NULL; - - *nat_bitmap_size = *nat_bitmap_size - offset; - - return ckpt->sit_nat_version_bitmap + offset; -} - -static grub_uint32_t -get_node_id (struct grub_f2fs_node *rn, int off, int inode_block) -{ - if (inode_block) - return grub_le_to_cpu32 (rn->i.i_nid[off - NODE_DIR1_BLOCK]); - - return grub_le_to_cpu32 (rn->in.nid[off]); -} - -static grub_err_t -grub_f2fs_block_read (struct grub_f2fs_data *data, grub_uint32_t blkaddr, - void *buf) -{ - return grub_disk_read (data->disk, - ((grub_disk_addr_t)blkaddr) << F2FS_BLK_SEC_BITS, - 0, F2FS_BLKSIZE, buf); -} - -/* CRC32 */ -static grub_uint32_t -grub_f2fs_cal_crc32 (const void *buf, const grub_uint32_t len) -{ - grub_uint32_t crc = F2FS_SUPER_MAGIC; - unsigned char *p = (unsigned char *)buf; - grub_uint32_t tmp = len; - int i; - - while (tmp--) - { - crc ^= *p++; - for (i = 0; i < 8; i++) - crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0); - } - - return crc; -} - -static int -grub_f2fs_crc_valid (grub_uint32_t blk_crc, void *buf, const grub_uint32_t len) -{ - grub_uint32_t cal_crc = 0; - - cal_crc = grub_f2fs_cal_crc32 (buf, len); - - return (cal_crc == blk_crc) ? 1 : 0; -} - -static int -grub_f2fs_test_bit (grub_uint32_t nr, const char *p, grub_uint32_t len) -{ - int mask; - grub_uint32_t shifted_nr = (nr >> 3); - - if (shifted_nr >= len) - return -1; - - p += shifted_nr; - mask = 1 << (7 - (nr & 0x07)); - - return mask & *p; -} - -static int -grub_f2fs_sanity_check_sb (struct grub_f2fs_superblock *sb) -{ - grub_uint32_t log_sectorsize, log_sectors_per_block; - - if (sb->magic != grub_cpu_to_le32_compile_time (F2FS_SUPER_MAGIC)) - return -1; - - if (sb->log_blocksize != grub_cpu_to_le32_compile_time (F2FS_BLK_BITS)) - return -1; - - log_sectorsize = grub_le_to_cpu32 (sb->log_sectorsize); - log_sectors_per_block = grub_le_to_cpu32 (sb->log_sectors_per_block); - - if (log_sectorsize > F2FS_BLK_BITS) - return -1; - - if (log_sectorsize < F2FS_MIN_LOG_SECTOR_SIZE) - return -1; - - if (log_sectors_per_block + log_sectorsize != F2FS_BLK_BITS) - return -1; - - return 0; -} - -static int -grub_f2fs_read_sb (struct grub_f2fs_data *data, grub_disk_addr_t offset) -{ - grub_disk_t disk = data->disk; - grub_err_t err; - - /* Read first super block. */ - err = grub_disk_read (disk, offset, 0, sizeof (data->sblock), &data->sblock); - if (err) - return -1; - - return grub_f2fs_sanity_check_sb (&data->sblock); -} - -static void * -validate_checkpoint (struct grub_f2fs_data *data, grub_uint32_t cp_addr, - grub_uint64_t *version) -{ - grub_uint32_t *cp_page_1, *cp_page_2; - struct grub_f2fs_checkpoint *cp_block; - grub_uint64_t cur_version = 0, pre_version = 0; - grub_uint32_t crc = 0; - grub_uint32_t crc_offset; - grub_err_t err; - - /* Read the 1st cp block in this CP pack. */ - cp_page_1 = grub_malloc (F2FS_BLKSIZE); - if (!cp_page_1) - return NULL; - - err = grub_f2fs_block_read (data, cp_addr, cp_page_1); - if (err) - goto invalid_cp1; - - cp_block = (struct grub_f2fs_checkpoint *)cp_page_1; - crc_offset = grub_le_to_cpu32 (cp_block->checksum_offset); - if (crc_offset != CHECKSUM_OFFSET) - goto invalid_cp1; - - crc = grub_le_to_cpu32 (*(cp_page_1 + U32_CHECKSUM_OFFSET)); - if (!grub_f2fs_crc_valid (crc, cp_block, crc_offset)) - goto invalid_cp1; - - pre_version = grub_le_to_cpu64 (cp_block->checkpoint_ver); - - /* Read the 2nd cp block in this CP pack. */ - cp_page_2 = grub_malloc (F2FS_BLKSIZE); - if (!cp_page_2) - goto invalid_cp1; - - cp_addr += grub_le_to_cpu32 (cp_block->cp_pack_total_block_count) - 1; - - err = grub_f2fs_block_read (data, cp_addr, cp_page_2); - if (err) - goto invalid_cp2; - - cp_block = (struct grub_f2fs_checkpoint *)cp_page_2; - crc_offset = grub_le_to_cpu32 (cp_block->checksum_offset); - if (crc_offset != CHECKSUM_OFFSET) - goto invalid_cp2; - - crc = grub_le_to_cpu32 (*(cp_page_2 + U32_CHECKSUM_OFFSET)); - if (!grub_f2fs_crc_valid (crc, cp_block, crc_offset)) - goto invalid_cp2; - - cur_version = grub_le_to_cpu64 (cp_block->checkpoint_ver); - if (cur_version == pre_version) - { - *version = cur_version; - grub_free (cp_page_2); - - return cp_page_1; - } - - invalid_cp2: - grub_free (cp_page_2); - - invalid_cp1: - grub_free (cp_page_1); - - return NULL; -} - -static grub_err_t -grub_f2fs_read_cp (struct grub_f2fs_data *data) -{ - void *cp1, *cp2, *cur_page; - grub_uint64_t cp1_version = 0, cp2_version = 0; - grub_uint64_t cp_start_blk_no; - - /* - * Finding out valid cp block involves read both - * sets (cp pack1 and cp pack 2). - */ - cp_start_blk_no = data->cp_blkaddr; - cp1 = validate_checkpoint (data, cp_start_blk_no, &cp1_version); - if (!cp1 && grub_errno) - return grub_errno; - - /* The second checkpoint pack should start at the next segment. */ - cp_start_blk_no += data->blocks_per_seg; - cp2 = validate_checkpoint (data, cp_start_blk_no, &cp2_version); - if (!cp2 && grub_errno) - { - grub_free (cp1); - return grub_errno; - } - - if (cp1 && cp2) - cur_page = (cp2_version > cp1_version) ? cp2 : cp1; - else if (cp1) - cur_page = cp1; - else if (cp2) - cur_page = cp2; - else - return grub_error (GRUB_ERR_BAD_FS, "no checkpoints"); - - grub_memcpy (&data->ckpt, cur_page, F2FS_BLKSIZE); - - grub_free (cp1); - grub_free (cp2); - - return 0; -} - -static grub_err_t -get_nat_journal (struct grub_f2fs_data *data) -{ - grub_uint32_t block; - char *buf; - grub_err_t err; - - buf = grub_malloc (F2FS_BLKSIZE); - if (!buf) - return grub_errno; - - if (CKPT_FLAG_SET(&data->ckpt, CP_COMPACT_SUM_FLAG)) - block = start_sum_block (data); - else if (CKPT_FLAG_SET (&data->ckpt, CP_UMOUNT_FLAG)) - block = sum_blk_addr (data, NR_CURSEG_TYPE, CURSEG_HOT_DATA); - else - block = sum_blk_addr (data, NR_CURSEG_DATA_TYPE, CURSEG_HOT_DATA); - - err = grub_f2fs_block_read (data, block, buf); - if (err) - goto fail; - - if (CKPT_FLAG_SET (&data->ckpt, CP_COMPACT_SUM_FLAG)) - grub_memcpy (&data->nat_j, buf, SUM_JOURNAL_SIZE); - else - grub_memcpy (&data->nat_j, buf + SUM_ENTRIES_SIZE, SUM_JOURNAL_SIZE); - - fail: - grub_free (buf); - - return err; -} - -static grub_err_t -get_blkaddr_from_nat_journal (struct grub_f2fs_data *data, grub_uint32_t nid, - grub_uint32_t *blkaddr) -{ - grub_uint16_t n = grub_le_to_cpu16 (data->nat_j.n_nats); - grub_uint16_t i; - - if (n > NAT_JOURNAL_ENTRIES) - return grub_error (GRUB_ERR_BAD_FS, - "invalid number of nat journal entries"); - - for (i = 0; i < n; i++) - { - if (grub_le_to_cpu32 (data->nat_j.entries[i].nid) == nid) - { - *blkaddr = grub_le_to_cpu32 (data->nat_j.entries[i].ne.block_addr); - break; - } - } - - return GRUB_ERR_NONE; -} - -static grub_uint32_t -get_node_blkaddr (struct grub_f2fs_data *data, grub_uint32_t nid) -{ - struct grub_f2fs_nat_block *nat_block; - grub_uint32_t seg_off, block_off, entry_off, block_addr; - grub_uint32_t blkaddr = 0; - grub_err_t err; - int result_bit; - - err = get_blkaddr_from_nat_journal (data, nid, &blkaddr); - if (err != GRUB_ERR_NONE) - return 0; - - if (blkaddr) - return blkaddr; - - nat_block = grub_malloc (F2FS_BLKSIZE); - if (!nat_block) - return 0; - - block_off = nid / NAT_ENTRY_PER_BLOCK; - entry_off = nid % NAT_ENTRY_PER_BLOCK; - - seg_off = block_off / data->blocks_per_seg; - block_addr = data->nat_blkaddr + - ((seg_off * data->blocks_per_seg) << 1) + - (block_off & (data->blocks_per_seg - 1)); - - result_bit = grub_f2fs_test_bit (block_off, data->nat_bitmap, - data->nat_bitmap_size); - if (result_bit > 0) - block_addr += data->blocks_per_seg; - else if (result_bit == -1) - { - grub_free (nat_block); - return 0; - } - - err = grub_f2fs_block_read (data, block_addr, nat_block); - if (err) - { - grub_free (nat_block); - return 0; - } - - blkaddr = grub_le_to_cpu32 (nat_block->ne[entry_off].block_addr); - - grub_free (nat_block); - - return blkaddr; -} - -static int -grub_get_node_path (struct grub_f2fs_inode *inode, grub_uint32_t block, - grub_uint32_t offset[4], grub_uint32_t noffset[4]) -{ - grub_uint32_t direct_blks = ADDRS_PER_BLOCK; - grub_uint32_t dptrs_per_blk = NIDS_PER_BLOCK; - grub_uint32_t indirect_blks = ADDRS_PER_BLOCK * NIDS_PER_BLOCK; - grub_uint32_t dindirect_blks = indirect_blks * NIDS_PER_BLOCK; - grub_uint32_t direct_index = DEF_ADDRS_PER_INODE; - int n = 0; - int level = -1; - - if (inode->i_inline & F2FS_INLINE_XATTR) - direct_index -= F2FS_INLINE_XATTR_ADDRS; - - noffset[0] = 0; - - if (block < direct_index) - { - offset[n] = block; - level = 0; - goto got; - } - - block -= direct_index; - if (block < direct_blks) - { - offset[n++] = NODE_DIR1_BLOCK; - noffset[n] = 1; - offset[n] = block; - level = 1; - goto got; - } - - block -= direct_blks; - if (block < direct_blks) - { - offset[n++] = NODE_DIR2_BLOCK; - noffset[n] = 2; - offset[n] = block; - level = 1; - goto got; - } - - block -= direct_blks; - if (block < indirect_blks) - { - offset[n++] = NODE_IND1_BLOCK; - noffset[n] = 3; - offset[n++] = block / direct_blks; - noffset[n] = 4 + offset[n - 1]; - offset[n] = block % direct_blks; - level = 2; - goto got; - } - - block -= indirect_blks; - if (block < indirect_blks) - { - offset[n++] = NODE_IND2_BLOCK; - noffset[n] = 4 + dptrs_per_blk; - offset[n++] = block / direct_blks; - noffset[n] = 5 + dptrs_per_blk + offset[n - 1]; - offset[n] = block % direct_blks; - level = 2; - goto got; - } - - block -= indirect_blks; - if (block < dindirect_blks) - { - offset[n++] = NODE_DIND_BLOCK; - noffset[n] = 5 + (dptrs_per_blk * 2); - offset[n++] = block / indirect_blks; - noffset[n] = 6 + (dptrs_per_blk * 2) + - offset[n - 1] * (dptrs_per_blk + 1); - offset[n++] = (block / direct_blks) % dptrs_per_blk; - noffset[n] = 7 + (dptrs_per_blk * 2) + - offset[n - 2] * (dptrs_per_blk + 1) + offset[n - 1]; - offset[n] = block % direct_blks; - level = 3; - goto got; - } - - got: - return level; -} - -static grub_err_t -grub_f2fs_read_node (struct grub_f2fs_data *data, - grub_uint32_t nid, struct grub_f2fs_node *np) -{ - grub_uint32_t blkaddr; - - blkaddr = get_node_blkaddr (data, nid); - if (!blkaddr) - return grub_errno; - - return grub_f2fs_block_read (data, blkaddr, np); -} - -static struct grub_f2fs_data * -grub_f2fs_mount (grub_disk_t disk) -{ - struct grub_f2fs_data *data; - grub_err_t err; - - data = grub_malloc (sizeof (*data)); - if (!data) - return NULL; - - data->disk = disk; - - if (grub_f2fs_read_sb (data, F2FS_SUPER_OFFSET0)) - { - if (grub_f2fs_read_sb (data, F2FS_SUPER_OFFSET1)) - { - if (grub_errno == GRUB_ERR_NONE) - grub_error (GRUB_ERR_BAD_FS, - "not a F2FS filesystem (no superblock)"); - goto fail; - } - } - - data->root_ino = grub_le_to_cpu32 (data->sblock.root_ino); - data->cp_blkaddr = grub_le_to_cpu32 (data->sblock.cp_blkaddr); - data->nat_blkaddr = grub_le_to_cpu32 (data->sblock.nat_blkaddr); - data->blocks_per_seg = 1 << - grub_le_to_cpu32 (data->sblock.log_blocks_per_seg); - - err = grub_f2fs_read_cp (data); - if (err) - goto fail; - - data->nat_bitmap = nat_bitmap_ptr (data, &data->nat_bitmap_size); - if (data->nat_bitmap == NULL) - goto fail; - - err = get_nat_journal (data); - if (err) - goto fail; - - data->diropen.data = data; - data->diropen.ino = data->root_ino; - data->diropen.inode_read = 1; - data->inode = &data->diropen.inode; - - err = grub_f2fs_read_node (data, data->root_ino, data->inode); - if (err) - goto fail; - - return data; - - fail: - if (grub_errno == GRUB_ERR_NONE) - grub_error (GRUB_ERR_BAD_FS, "not a F2FS filesystem"); - - grub_free (data); - - return NULL; -} - -/* Guarantee inline_data was handled by caller. */ -static grub_disk_addr_t -grub_f2fs_get_block (grub_fshelp_node_t node, grub_disk_addr_t block_ofs) -{ - struct grub_f2fs_data *data = node->data; - struct grub_f2fs_inode *inode = &node->inode.i; - grub_uint32_t offset[4], noffset[4], nids[4]; - struct grub_f2fs_node *node_block; - grub_uint32_t block_addr = -1; - int level, i; - - level = grub_get_node_path (inode, block_ofs, offset, noffset); - - if (level < 0) - return -1; - - if (level == 0) - return grub_le_to_cpu32 (inode->i_addr[offset[0]]); - - node_block = grub_malloc (F2FS_BLKSIZE); - if (!node_block) - return -1; - - nids[1] = get_node_id (&node->inode, offset[0], 1); - - /* Get indirect or direct nodes. */ - for (i = 1; i <= level; i++) - { - grub_f2fs_read_node (data, nids[i], node_block); - if (grub_errno) - goto fail; - - if (i < level) - nids[i + 1] = get_node_id (node_block, offset[i], 0); - } - - block_addr = grub_le_to_cpu32 (node_block->dn.addr[offset[level]]); - - fail: - grub_free (node_block); - - return block_addr; -} - -static grub_ssize_t -grub_f2fs_read_file (grub_fshelp_node_t node, - grub_disk_read_hook_t read_hook, void *read_hook_data, - grub_off_t pos, grub_size_t len, char *buf) -{ - struct grub_f2fs_inode *inode = &node->inode.i; - grub_off_t filesize = grub_f2fs_file_size (inode); - char *inline_addr = get_inline_addr (inode); - - if (inode->i_inline & F2FS_INLINE_DATA) - { - if (filesize > MAX_INLINE_DATA) - return -1; - - if (len > filesize - pos) - len = filesize - pos; - - grub_memcpy (buf, inline_addr + pos, len); - return len; - } - - return grub_fshelp_read_file (node->data->disk, node, - read_hook, read_hook_data, - pos, len, buf, grub_f2fs_get_block, - filesize, - F2FS_BLK_SEC_BITS, 0); -} - -static char * -grub_f2fs_read_symlink (grub_fshelp_node_t node) -{ - char *symlink; - struct grub_fshelp_node *diro = node; - grub_uint64_t filesize; - grub_size_t sz; - - if (!diro->inode_read) - { - grub_f2fs_read_node (diro->data, diro->ino, &diro->inode); - if (grub_errno) - return 0; - } - - filesize = grub_f2fs_file_size(&diro->inode.i); - - if (grub_add (filesize, 1, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink size overflow")); - return 0; - } - symlink = grub_malloc (sz); - if (!symlink) - return 0; - - grub_f2fs_read_file (diro, 0, 0, 0, filesize, symlink); - if (grub_errno) - { - grub_free (symlink); - return 0; - } - - symlink[filesize] = '\0'; - - return symlink; -} - -static int -grub_f2fs_check_dentries (struct grub_f2fs_dir_iter_ctx *ctx) -{ - struct grub_fshelp_node *fdiro; - int i; - - for (i = 0; i < ctx->max;) - { - char *filename; - enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; - enum FILE_TYPE ftype; - int name_len; - int ret; - int sz; - - if (grub_f2fs_test_bit_le (i, ctx->bitmap) == 0) - { - i++; - continue; - } - - ftype = ctx->dentry[i].file_type; - name_len = grub_le_to_cpu16 (ctx->dentry[i].name_len); - - if (name_len >= F2FS_NAME_LEN) - return 0; - - if (grub_add (name_len, 1, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory entry name length overflow")); - return 0; - } - filename = grub_malloc (sz); - if (!filename) - return 0; - - grub_memcpy (filename, ctx->filename[i], name_len); - filename[name_len] = 0; - - fdiro = grub_malloc (sizeof (struct grub_fshelp_node)); - if (!fdiro) - { - grub_free(filename); - return 0; - } - - if (ftype == F2FS_FT_DIR) - type = GRUB_FSHELP_DIR; - else if (ftype == F2FS_FT_SYMLINK) - type = GRUB_FSHELP_SYMLINK; - else if (ftype == F2FS_FT_REG_FILE) - type = GRUB_FSHELP_REG; - - fdiro->data = ctx->data; - fdiro->ino = grub_le_to_cpu32 (ctx->dentry[i].ino); - fdiro->inode_read = 0; - - ret = ctx->hook (filename, type, fdiro, ctx->hook_data); - grub_free(filename); - if (ret) - return 1; - - i += (name_len + F2FS_SLOT_LEN - 1) / F2FS_SLOT_LEN; - } - - return 0; -} - -static int -grub_f2fs_iterate_inline_dir (struct grub_f2fs_inode *dir, - struct grub_f2fs_dir_iter_ctx *ctx) -{ - struct grub_f2fs_inline_dentry *de_blk; - - de_blk = (struct grub_f2fs_inline_dentry *) get_inline_addr (dir); - - ctx->bitmap = de_blk->dentry_bitmap; - ctx->dentry = de_blk->dentry; - ctx->filename = de_blk->filename; - ctx->max = NR_INLINE_DENTRY; - - return grub_f2fs_check_dentries (ctx); -} - -static int -grub_f2fs_iterate_dir (grub_fshelp_node_t dir, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data) -{ - struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; - struct grub_f2fs_inode *inode; - struct grub_f2fs_dir_iter_ctx ctx = { - .data = diro->data, - .hook = hook, - .hook_data = hook_data - }; - grub_off_t fpos = 0; - - if (!diro->inode_read) - { - grub_f2fs_read_node (diro->data, diro->ino, &diro->inode); - if (grub_errno) - return 0; - } - - inode = &diro->inode.i; - - if (inode->i_inline & F2FS_INLINE_DENTRY) - return grub_f2fs_iterate_inline_dir (inode, &ctx); - - while (fpos < grub_f2fs_file_size (inode)) - { - struct grub_f2fs_dentry_block *de_blk; - char *buf; - int ret; - - buf = grub_zalloc (F2FS_BLKSIZE); - if (!buf) - return 0; - - grub_f2fs_read_file (diro, 0, 0, fpos, F2FS_BLKSIZE, buf); - if (grub_errno) - { - grub_free (buf); - return 0; - } - - de_blk = (struct grub_f2fs_dentry_block *) buf; - - ctx.bitmap = de_blk->dentry_bitmap; - ctx.dentry = de_blk->dentry; - ctx.filename = de_blk->filename; - ctx.max = NR_DENTRY_IN_BLOCK; - - ret = grub_f2fs_check_dentries (&ctx); - grub_free (buf); - if (ret) - return 1; - - fpos += F2FS_BLKSIZE; - } - - return 0; -} - -static int -grub_f2fs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, void *data) -{ - struct grub_f2fs_dir_ctx *ctx = data; - struct grub_dirhook_info info; - - grub_memset (&info, 0, sizeof (info)); - if (!node->inode_read) - { - grub_f2fs_read_node (ctx->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.i_mtime); - } - - info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); - grub_free (node); - - return ctx->hook (filename, &info, ctx->hook_data); -} - -static grub_err_t -grub_f2fs_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_f2fs_dir_ctx ctx = { - .hook = hook, - .hook_data = hook_data - }; - struct grub_fshelp_node *fdiro = 0; - - grub_dl_ref (my_mod); - - ctx.data = grub_f2fs_mount (device->disk); - if (!ctx.data) - goto fail; - - grub_fshelp_find_file (path, &ctx.data->diropen, &fdiro, - grub_f2fs_iterate_dir, grub_f2fs_read_symlink, - GRUB_FSHELP_DIR); - if (grub_errno) - goto fail; - - grub_f2fs_iterate_dir (fdiro, grub_f2fs_dir_iter, &ctx); - - fail: - if (fdiro != &ctx.data->diropen) - grub_free (fdiro); - grub_free (ctx.data); - grub_dl_unref (my_mod); - - return grub_errno; -} - -/* Open a file named NAME and initialize FILE. */ -static grub_err_t -grub_f2fs_open (struct grub_file *file, const char *name) -{ - struct grub_f2fs_data *data = NULL; - struct grub_fshelp_node *fdiro = 0; - struct grub_f2fs_inode *inode; - - grub_dl_ref (my_mod); - - data = grub_f2fs_mount (file->device->disk); - if (!data) - goto fail; - - grub_fshelp_find_file (name, &data->diropen, &fdiro, - grub_f2fs_iterate_dir, grub_f2fs_read_symlink, - GRUB_FSHELP_REG); - if (grub_errno) - goto fail; - - if (!fdiro->inode_read) - { - grub_f2fs_read_node (data, fdiro->ino, &fdiro->inode); - if (grub_errno) - goto fail; - } - - grub_memcpy (data->inode, &fdiro->inode, sizeof (*data->inode)); - grub_free (fdiro); - - inode = &(data->inode->i); - file->size = grub_f2fs_file_size (inode); - file->data = data; - file->offset = 0; - - if (inode->i_inline & F2FS_INLINE_DATA && file->size > MAX_INLINE_DATA) - grub_error (GRUB_ERR_BAD_FS, "corrupted inline_data: need fsck"); - - return 0; - - fail: - if (fdiro != &data->diropen) - grub_free (fdiro); - grub_free (data); - - grub_dl_unref (my_mod); - - return grub_errno; -} - -static grub_ssize_t -grub_f2fs_read (grub_file_t file, char *buf, grub_size_t len) -{ - struct grub_f2fs_data *data = (struct grub_f2fs_data *) file->data; - - return grub_f2fs_read_file (&data->diropen, - file->read_hook, file->read_hook_data, - file->offset, len, buf); -} - -static grub_err_t -grub_f2fs_close (grub_file_t file) -{ - struct grub_f2fs_data *data = (struct grub_f2fs_data *) file->data; - - grub_free (data); - - grub_dl_unref (my_mod); - - return GRUB_ERR_NONE; -} - -static grub_uint8_t * -grub_f2fs_utf16_to_utf8 (grub_uint16_t *in_buf_le) -{ - grub_uint16_t in_buf[MAX_VOLUME_NAME]; - grub_uint8_t *out_buf; - int len = 0; - - out_buf = grub_malloc (MAX_VOLUME_NAME * GRUB_MAX_UTF8_PER_UTF16 + 1); - if (!out_buf) - return NULL; - - while (*in_buf_le != 0 && len < MAX_VOLUME_NAME) { - in_buf[len] = grub_le_to_cpu16 (in_buf_le[len]); - len++; - } - - *grub_utf16_to_utf8 (out_buf, in_buf, len) = '\0'; - - return out_buf; -} - -#if __GNUC__ >= 9 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Waddress-of-packed-member" -#endif - -static grub_err_t -grub_f2fs_label (grub_device_t device, char **label) -{ - struct grub_f2fs_data *data; - grub_disk_t disk = device->disk; - - grub_dl_ref (my_mod); - - data = grub_f2fs_mount (disk); - if (data) - *label = (char *) grub_f2fs_utf16_to_utf8 (data->sblock.volume_name); - else - *label = NULL; - - grub_free (data); - grub_dl_unref (my_mod); - - return grub_errno; -} - -#if __GNUC__ >= 9 -#pragma GCC diagnostic pop -#endif - -static grub_err_t -grub_f2fs_uuid (grub_device_t device, char **uuid) -{ - struct grub_f2fs_data *data; - grub_disk_t disk = device->disk; - - grub_dl_ref (my_mod); - - data = grub_f2fs_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_free (data); - grub_dl_unref (my_mod); - - return grub_errno; -} - -static struct grub_fs grub_f2fs_fs = { - .name = "f2fs", - .fs_dir = grub_f2fs_dir, - .fs_open = grub_f2fs_open, - .fs_read = grub_f2fs_read, - .fs_close = grub_f2fs_close, - .fs_label = grub_f2fs_label, - .fs_uuid = grub_f2fs_uuid, -#ifdef GRUB_UTIL - .reserved_first_sector = 1, - .blocklist_install = 0, -#endif - .next = 0 -}; - -GRUB_MOD_INIT (f2fs) -{ - grub_f2fs_fs.mod = mod; - grub_fs_register (&grub_f2fs_fs); - my_mod = mod; -} - -GRUB_MOD_FINI (f2fs) -{ - grub_fs_unregister (&grub_f2fs_fs); -} diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c deleted file mode 100644 index 6e62b915d..000000000 --- a/grub-core/fs/fat.c +++ /dev/null @@ -1,1327 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef MODE_EXFAT -#include -#else -#include -#endif -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -enum - { - GRUB_FAT_ATTR_READ_ONLY = 0x01, - GRUB_FAT_ATTR_HIDDEN = 0x02, - GRUB_FAT_ATTR_SYSTEM = 0x04, -#ifndef MODE_EXFAT - GRUB_FAT_ATTR_VOLUME_ID = 0x08, -#endif - GRUB_FAT_ATTR_DIRECTORY = 0x10, - GRUB_FAT_ATTR_ARCHIVE = 0x20, - -#ifndef MODE_EXFAT - GRUB_FAT_ATTR_LONG_NAME = (GRUB_FAT_ATTR_READ_ONLY - | GRUB_FAT_ATTR_HIDDEN - | GRUB_FAT_ATTR_SYSTEM - | GRUB_FAT_ATTR_VOLUME_ID), -#endif - 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 -#ifndef MODE_EXFAT - | GRUB_FAT_ATTR_VOLUME_ID -#endif - ) - }; - -#ifdef MODE_EXFAT -typedef struct grub_exfat_bpb grub_current_fat_bpb_t; -#else -typedef struct grub_fat_bpb grub_current_fat_bpb_t; -#endif - -#ifdef MODE_EXFAT -enum - { - FLAG_CONTIGUOUS = 2 - }; -struct grub_fat_dir_entry -{ - grub_uint8_t entry_type; - union - { - grub_uint8_t placeholder[31]; - struct { - grub_uint8_t secondary_count; - grub_uint16_t checksum; - grub_uint16_t attr; - grub_uint16_t reserved1; - grub_uint32_t c_time; - grub_uint32_t m_time; - grub_uint32_t a_time; - grub_uint8_t c_time_tenth; - grub_uint8_t m_time_tenth; - grub_uint8_t a_time_tenth; - grub_uint8_t reserved2[9]; - } GRUB_PACKED file; - struct { - grub_uint8_t flags; - grub_uint8_t reserved1; - grub_uint8_t name_length; - grub_uint16_t name_hash; - grub_uint16_t reserved2; - grub_uint64_t valid_size; - grub_uint32_t reserved3; - grub_uint32_t first_cluster; - grub_uint64_t file_size; - } GRUB_PACKED stream_extension; - struct { - grub_uint8_t flags; - grub_uint16_t str[15]; - } GRUB_PACKED file_name; - struct { - grub_uint8_t character_count; - grub_uint16_t str[15]; - } GRUB_PACKED volume_label; - } GRUB_PACKED type_specific; -} GRUB_PACKED; - -struct grub_fat_dir_node -{ - grub_uint32_t attr; - grub_uint32_t first_cluster; - grub_uint64_t file_size; - grub_uint64_t valid_size; - int have_stream; - int is_contiguous; -}; - -typedef struct grub_fat_dir_node grub_fat_dir_node_t; - -#else -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; -} GRUB_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]; -} GRUB_PACKED; - -typedef struct grub_fat_dir_entry grub_fat_dir_node_t; - -#endif - -struct grub_fat_data -{ - int logical_sector_bits; - grub_uint32_t num_sectors; - - grub_uint32_t fat_sector; - grub_uint32_t sectors_per_fat; - int fat_size; - - grub_uint32_t root_cluster; -#ifndef MODE_EXFAT - grub_uint32_t root_sector; - grub_uint32_t num_root_sectors; -#endif - - int cluster_bits; - grub_uint32_t cluster_eof_mark; - grub_uint32_t cluster_sector; - grub_uint32_t num_clusters; - - grub_uint32_t uuid; -}; - -struct grub_fshelp_node { - grub_disk_t disk; - struct grub_fat_data *data; - - grub_uint8_t attr; -#ifndef MODE_EXFAT - grub_uint32_t file_size; -#else - grub_uint64_t file_size; -#endif - grub_uint32_t file_cluster; - grub_uint32_t cur_cluster_num; - grub_uint32_t cur_cluster; - -#ifdef MODE_EXFAT - int is_contiguous; -#endif -}; - -static grub_dl_t my_mod; - -#ifndef MODE_EXFAT -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; -} -#endif - -static struct grub_fat_data * -grub_fat_mount (grub_disk_t disk) -{ - grub_current_fat_bpb_t 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; - -#ifdef MODE_EXFAT - if (grub_memcmp ((const char *) bpb.oem_name, "EXFAT ", - sizeof (bpb.oem_name)) != 0) - goto fail; -#endif - - /* Get the sizes of logical sectors and clusters. */ -#ifdef MODE_EXFAT - data->logical_sector_bits = bpb.bytes_per_sector_shift; -#else - data->logical_sector_bits = - fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector)); -#endif - if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS - || data->logical_sector_bits >= 16) - goto fail; - data->logical_sector_bits -= GRUB_DISK_SECTOR_BITS; - -#ifdef MODE_EXFAT - data->cluster_bits = bpb.sectors_per_cluster_shift; -#else - data->cluster_bits = fat_log2 (bpb.sectors_per_cluster); -#endif - if (data->cluster_bits < 0 || data->cluster_bits > 25) - goto fail; - data->cluster_bits += data->logical_sector_bits; - - /* Get information about FATs. */ -#ifdef MODE_EXFAT - data->fat_sector = (grub_le_to_cpu32 (bpb.num_reserved_sectors) - << data->logical_sector_bits); -#else - data->fat_sector = (grub_le_to_cpu16 (bpb.num_reserved_sectors) - << data->logical_sector_bits); -#endif - if (data->fat_sector == 0) - goto fail; - -#ifdef MODE_EXFAT - data->sectors_per_fat = (grub_le_to_cpu32 (bpb.sectors_per_fat) - << data->logical_sector_bits); -#else - 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); -#endif - if (data->sectors_per_fat == 0) - goto fail; - - /* Get the number of sectors in this volume. */ -#ifdef MODE_EXFAT - data->num_sectors = ((grub_le_to_cpu64 (bpb.num_total_sectors)) - << data->logical_sector_bits); -#else - 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); -#endif - if (data->num_sectors == 0) - goto fail; - - /* Get information about the root directory. */ - if (bpb.num_fats == 0) - goto fail; - -#ifndef MODE_EXFAT - 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) - * sizeof (struct grub_fat_dir_entry) - + grub_le_to_cpu16 (bpb.bytes_per_sector) - 1) - >> (data->logical_sector_bits + GRUB_DISK_SECTOR_BITS)) - << (data->logical_sector_bits)); -#endif - -#ifdef MODE_EXFAT - data->cluster_sector = (grub_le_to_cpu32 (bpb.cluster_offset) - << data->logical_sector_bits); - data->num_clusters = (grub_le_to_cpu32 (bpb.cluster_count) - << data->logical_sector_bits); -#else - data->cluster_sector = data->root_sector + data->num_root_sectors; - data->num_clusters = (((data->num_sectors - data->cluster_sector) - >> data->cluster_bits) - + 2); -#endif - - if (data->num_clusters <= 2) - goto fail; - -#ifdef MODE_EXFAT - { - /* exFAT. */ - data->root_cluster = grub_le_to_cpu32 (bpb.root_cluster); - data->fat_size = 32; - data->cluster_eof_mark = 0xffffffff; - - if ((bpb.volume_flags & grub_cpu_to_le16_compile_time (0x1)) - && bpb.num_fats > 1) - data->fat_sector += data->sectors_per_fat; - } -#else - 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; - } - } -#endif - - /* 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. */ -#ifdef MODE_EXFAT - data->uuid = grub_le_to_cpu32 (bpb.num_serial); -#else - 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); -#endif - -#ifndef MODE_EXFAT - /* 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; -#else - (void) magic; -#endif - - 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, grub_fshelp_node_t node, - grub_disk_read_hook_t read_hook, void *read_hook_data, - 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; - -#ifndef MODE_EXFAT - /* This is a special case. FAT12 and FAT16 doesn't have the root directory - in clusters. */ - if (node->file_cluster == ~0U) - { - size = (node->data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset; - if (size > len) - size = len; - - if (grub_disk_read (disk, node->data->root_sector, offset, size, buf)) - return -1; - - return size; - } -#endif - -#ifdef MODE_EXFAT - if (node->is_contiguous) - { - /* Read the data here. */ - sector = (node->data->cluster_sector - + ((node->file_cluster - 2) - << node->data->cluster_bits)); - - disk->read_hook = read_hook; - disk->read_hook_data = read_hook_data; - grub_disk_read (disk, sector + (offset >> GRUB_DISK_SECTOR_BITS), - offset & (GRUB_DISK_SECTOR_SIZE - 1), len, buf); - disk->read_hook = 0; - if (grub_errno) - return -1; - - return len; - } -#endif - - /* Calculate the logical cluster number and offset. */ - logical_cluster_bits = (node->data->cluster_bits - + GRUB_DISK_SECTOR_BITS); - logical_cluster = offset >> logical_cluster_bits; - offset &= (1ULL << logical_cluster_bits) - 1; - - if (logical_cluster < node->cur_cluster_num) - { - node->cur_cluster_num = 0; - node->cur_cluster = node->file_cluster; - } - - while (len) - { - while (logical_cluster > node->cur_cluster_num) - { - /* Find next cluster. */ - grub_uint32_t next_cluster; - grub_uint32_t fat_offset; - - switch (node->data->fat_size) - { - case 32: - fat_offset = node->cur_cluster << 2; - break; - case 16: - fat_offset = node->cur_cluster << 1; - break; - default: - /* case 12: */ - fat_offset = node->cur_cluster + (node->cur_cluster >> 1); - break; - } - - /* Read the FAT. */ - if (grub_disk_read (disk, node->data->fat_sector, fat_offset, - (node->data->fat_size + 7) >> 3, - (char *) &next_cluster)) - return -1; - - next_cluster = grub_le_to_cpu32 (next_cluster); - switch (node->data->fat_size) - { - case 16: - next_cluster &= 0xFFFF; - break; - case 12: - if (node->cur_cluster & 1) - next_cluster >>= 4; - - next_cluster &= 0x0FFF; - break; - } - - grub_dprintf ("fat", "fat_size=%d, next_cluster=%u\n", - node->data->fat_size, next_cluster); - - /* Check the end. */ - if (next_cluster >= node->data->cluster_eof_mark) - return ret; - - if (next_cluster < 2 || next_cluster >= node->data->num_clusters) - { - grub_error (GRUB_ERR_BAD_FS, "invalid cluster %u", - next_cluster); - return -1; - } - - node->cur_cluster = next_cluster; - node->cur_cluster_num++; - } - - /* Read the data here. */ - sector = (node->data->cluster_sector - + ((node->cur_cluster - 2) - << node->data->cluster_bits)); - size = (1 << logical_cluster_bits) - offset; - if (size > len) - size = len; - - disk->read_hook = read_hook; - disk->read_hook_data = read_hook_data; - 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; -} - -struct grub_fat_iterate_context -{ -#ifdef MODE_EXFAT - struct grub_fat_dir_node dir; - struct grub_fat_dir_entry entry; -#else - struct grub_fat_dir_entry dir; -#endif - char *filename; - grub_uint16_t *unibuf; - grub_ssize_t offset; -}; - -static grub_err_t -grub_fat_iterate_init (struct grub_fat_iterate_context *ctxt) -{ - ctxt->offset = -sizeof (struct grub_fat_dir_entry); - -#ifndef MODE_EXFAT - /* Allocate space enough to hold a long name. */ - ctxt->filename = grub_malloc (0x40 * 13 * GRUB_MAX_UTF8_PER_UTF16 + 1); - ctxt->unibuf = (grub_uint16_t *) grub_malloc (0x40 * 13 * 2); -#else - ctxt->unibuf = grub_malloc (15 * 256 * 2); - ctxt->filename = grub_malloc (15 * 256 * GRUB_MAX_UTF8_PER_UTF16 + 1); -#endif - - if (! ctxt->filename || ! ctxt->unibuf) - { - grub_free (ctxt->filename); - grub_free (ctxt->unibuf); - return grub_errno; - } - return GRUB_ERR_NONE; -} - -static void -grub_fat_iterate_fini (struct grub_fat_iterate_context *ctxt) -{ - grub_free (ctxt->filename); - grub_free (ctxt->unibuf); -} - -#ifdef MODE_EXFAT -static grub_err_t -grub_fat_iterate_dir_next (grub_fshelp_node_t node, - struct grub_fat_iterate_context *ctxt) -{ - grub_memset (&ctxt->dir, 0, sizeof (ctxt->dir)); - while (1) - { - struct grub_fat_dir_entry *dir = &ctxt->entry; - - ctxt->offset += sizeof (*dir); - - if (grub_fat_read_data (node->disk, node, 0, 0, ctxt->offset, sizeof (*dir), - (char *) dir) - != sizeof (*dir)) - break; - - if (dir->entry_type == 0) - break; - if (!(dir->entry_type & 0x80)) - continue; - - if (dir->entry_type == 0x85) - { - unsigned i, nsec, slots = 0; - - nsec = dir->type_specific.file.secondary_count; - - ctxt->dir.attr = grub_cpu_to_le16 (dir->type_specific.file.attr); - ctxt->dir.have_stream = 0; - for (i = 0; i < nsec; i++) - { - struct grub_fat_dir_entry sec; - ctxt->offset += sizeof (sec); - if (grub_fat_read_data (node->disk, node, 0, 0, - ctxt->offset, sizeof (sec), (char *) &sec) - != sizeof (sec)) - break; - if (!(sec.entry_type & 0x80)) - continue; - if (!(sec.entry_type & 0x40)) - break; - switch (sec.entry_type) - { - case 0xc0: - ctxt->dir.first_cluster = grub_cpu_to_le32 (sec.type_specific.stream_extension.first_cluster); - ctxt->dir.valid_size - = grub_cpu_to_le64 (sec.type_specific.stream_extension.valid_size); - ctxt->dir.file_size - = grub_cpu_to_le64 (sec.type_specific.stream_extension.file_size); - ctxt->dir.have_stream = 1; - ctxt->dir.is_contiguous = !!(sec.type_specific.stream_extension.flags - & grub_cpu_to_le16_compile_time (FLAG_CONTIGUOUS)); - break; - case 0xc1: - { - int j; - for (j = 0; j < 15; j++) - ctxt->unibuf[slots * 15 + j] - = grub_le_to_cpu16 (sec.type_specific.file_name.str[j]); - slots++; - } - break; - default: - grub_dprintf ("exfat", "unknown secondary type 0x%02x\n", - sec.entry_type); - } - } - - if (i != nsec) - { - ctxt->offset -= sizeof (*dir); - continue; - } - - *grub_utf16_to_utf8 ((grub_uint8_t *) ctxt->filename, ctxt->unibuf, - slots * 15) = '\0'; - - return 0; - } - /* Allocation bitmap. */ - if (dir->entry_type == 0x81) - continue; - /* Upcase table. */ - if (dir->entry_type == 0x82) - continue; - /* Volume label. */ - if (dir->entry_type == 0x83) - continue; - grub_dprintf ("exfat", "unknown primary type 0x%02x\n", - dir->entry_type); - } - return grub_errno ? : GRUB_ERR_EOF; -} - -/* - * Convert a timestamp in exFAT format to seconds since the UNIX epoch - * according to sections 7.4.8 and 7.4.9 in the exFAT specification. - * https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification - */ -static int -grub_exfat_timestamp (grub_uint32_t field, grub_uint8_t msec, grub_int64_t *nix) { - struct grub_datetime datetime = { - .year = (field >> 25) + 1980, - .month = (field & 0x01E00000) >> 21, - .day = (field & 0x001F0000) >> 16, - .hour = (field & 0x0000F800) >> 11, - .minute = (field & 0x000007E0) >> 5, - .second = (field & 0x0000001F) * 2 + (msec >= 100 ? 1 : 0), - }; - - /* The conversion below allows seconds=60, so don't trust its validation. */ - if ((field & 0x1F) > 29) - return 0; - - /* Validate the 10-msec field even though it is rounded down to seconds. */ - if (msec > 199) - return 0; - - return grub_datetime2unixtime (&datetime, nix); -} - -#else - -static grub_err_t -grub_fat_iterate_dir_next (grub_fshelp_node_t node, - struct grub_fat_iterate_context *ctxt) -{ - char *filep = 0; - int checksum = -1; - int slot = -1, slots = -1; - - while (1) - { - unsigned i; - - /* Adjust the offset. */ - ctxt->offset += sizeof (ctxt->dir); - - /* Read a directory entry. */ - if (grub_fat_read_data (node->disk, node, 0, 0, - ctxt->offset, sizeof (ctxt->dir), - (char *) &ctxt->dir) - != sizeof (ctxt->dir) || ctxt->dir.name[0] == 0) - break; - - /* Handle long name entries. */ - if (ctxt->dir.attr == GRUB_FAT_ATTR_LONG_NAME) - { - struct grub_fat_long_name_entry *long_name - = (struct grub_fat_long_name_entry *) &ctxt->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 (ctxt->unibuf + slot * 13, long_name->name1, 5 * 2); - grub_memcpy (ctxt->unibuf + slot * 13 + 5, long_name->name2, 6 * 2); - grub_memcpy (ctxt->unibuf + slot * 13 + 11, long_name->name3, 2 * 2); - continue; - } - - /* Check if this entry is valid. */ - if (ctxt->dir.name[0] == 0xe5 || (ctxt->dir.attr & ~GRUB_FAT_ATTR_VALID)) - continue; - - /* This is a workaround for Japanese. */ - if (ctxt->dir.name[0] == 0x05) - ctxt->dir.name[0] = 0xe5; - - if (checksum != -1 && slot == 0) - { - grub_uint8_t sum; - - for (sum = 0, i = 0; i < sizeof (ctxt->dir.name); i++) - sum = ((sum >> 1) | (sum << 7)) + ctxt->dir.name[i]; - - if (sum == checksum) - { - int u; - - for (u = 0; u < slots * 13; u++) - ctxt->unibuf[u] = grub_le_to_cpu16 (ctxt->unibuf[u]); - - *grub_utf16_to_utf8 ((grub_uint8_t *) ctxt->filename, - ctxt->unibuf, - slots * 13) = '\0'; - - return GRUB_ERR_NONE; - } - - checksum = -1; - } - - /* Convert the 8.3 file name. */ - filep = ctxt->filename; - if (ctxt->dir.attr & GRUB_FAT_ATTR_VOLUME_ID) - { - for (i = 0; i < sizeof (ctxt->dir.name) && ctxt->dir.name[i]; i++) - *filep++ = ctxt->dir.name[i]; - while (i > 0 && ctxt->dir.name[i - 1] == ' ') - { - filep--; - i--; - } - } - else - { - for (i = 0; i < 8 && ctxt->dir.name[i]; i++) - *filep++ = grub_tolower (ctxt->dir.name[i]); - while (i > 0 && ctxt->dir.name[i - 1] == ' ') - { - filep--; - i--; - } - - /* XXX should we check that dir position is 0 or 1? */ - if (i > 2 || filep[0] != '.' || (i == 2 && filep[1] != '.')) - *filep++ = '.'; - - for (i = 8; i < 11 && ctxt->dir.name[i]; i++) - *filep++ = grub_tolower (ctxt->dir.name[i]); - while (i > 8 && ctxt->dir.name[i - 1] == ' ') - { - filep--; - i--; - } - - if (i == 8) - filep--; - } - *filep = '\0'; - return GRUB_ERR_NONE; - } - - return grub_errno ? : GRUB_ERR_EOF; -} - -/* - * Convert a date and time in FAT format to seconds since the UNIX epoch - * according to sections 11.3.5 and 11.3.6 in ECMA-107. - * https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-107.pdf - */ -static int -grub_fat_timestamp (grub_uint16_t time, grub_uint16_t date, grub_int64_t *nix) { - struct grub_datetime datetime = { - .year = (date >> 9) + 1980, - .month = (date & 0x01E0) >> 5, - .day = (date & 0x001F), - .hour = (time >> 11), - .minute = (time & 0x07E0) >> 5, - .second = (time & 0x001F) * 2, - }; - - /* The conversion below allows seconds=60, so don't trust its validation. */ - if ((time & 0x1F) > 29) - return 0; - - return grub_datetime2unixtime (&datetime, nix); -} - -#endif - -static grub_err_t lookup_file (grub_fshelp_node_t node, - const char *name, - grub_fshelp_node_t *foundnode, - enum grub_fshelp_filetype *foundtype) -{ - grub_err_t err; - struct grub_fat_iterate_context ctxt; - - err = grub_fat_iterate_init (&ctxt); - if (err) - return err; - - while (!(err = grub_fat_iterate_dir_next (node, &ctxt))) - { - -#ifdef MODE_EXFAT - if (!ctxt.dir.have_stream) - continue; -#else - if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID) - continue; -#endif - - if (grub_strcasecmp (name, ctxt.filename) == 0) - { - *foundnode = grub_malloc (sizeof (struct grub_fshelp_node)); - if (!*foundnode) - return grub_errno; - (*foundnode)->attr = ctxt.dir.attr; -#ifdef MODE_EXFAT - (*foundnode)->file_size = ctxt.dir.file_size; - (*foundnode)->file_cluster = ctxt.dir.first_cluster; - (*foundnode)->is_contiguous = ctxt.dir.is_contiguous; -#else - (*foundnode)->file_size = grub_le_to_cpu32 (ctxt.dir.file_size); - (*foundnode)->file_cluster = ((grub_le_to_cpu16 (ctxt.dir.first_cluster_high) << 16) - | grub_le_to_cpu16 (ctxt.dir.first_cluster_low)); - /* If directory points to root, starting cluster is 0 */ - if (!(*foundnode)->file_cluster) - (*foundnode)->file_cluster = node->data->root_cluster; -#endif - (*foundnode)->cur_cluster_num = ~0U; - (*foundnode)->data = node->data; - (*foundnode)->disk = node->disk; - - *foundtype = ((*foundnode)->attr & GRUB_FAT_ATTR_DIRECTORY) ? GRUB_FSHELP_DIR : GRUB_FSHELP_REG; - - grub_fat_iterate_fini (&ctxt); - return GRUB_ERR_NONE; - } - } - - grub_fat_iterate_fini (&ctxt); - if (err == GRUB_ERR_EOF) - err = 0; - - return err; - -} - -static grub_err_t -grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, - void *hook_data) -{ - struct grub_fat_data *data = 0; - grub_disk_t disk = device->disk; - grub_fshelp_node_t found = NULL; - grub_err_t err; - struct grub_fat_iterate_context ctxt; - - grub_dl_ref (my_mod); - - data = grub_fat_mount (disk); - if (! data) - goto fail; - - struct grub_fshelp_node root = { - .data = data, - .disk = disk, - .attr = GRUB_FAT_ATTR_DIRECTORY, - .file_size = 0, - .file_cluster = data->root_cluster, - .cur_cluster_num = ~0U, - .cur_cluster = 0, -#ifdef MODE_EXFAT - .is_contiguous = 0, -#endif - }; - - err = grub_fshelp_find_file_lookup (path, &root, &found, lookup_file, NULL, GRUB_FSHELP_DIR); - if (err) - goto fail; - - err = grub_fat_iterate_init (&ctxt); - if (err) - goto fail; - - while (!(err = grub_fat_iterate_dir_next (found, &ctxt))) - { - struct grub_dirhook_info info; - grub_memset (&info, 0, sizeof (info)); - - info.dir = !! (ctxt.dir.attr & GRUB_FAT_ATTR_DIRECTORY); - info.case_insensitive = 1; -#ifdef MODE_EXFAT - if (!ctxt.dir.have_stream) - continue; - info.mtimeset = grub_exfat_timestamp (grub_le_to_cpu32 (ctxt.entry.type_specific.file.m_time), - ctxt.entry.type_specific.file.m_time_tenth, - &info.mtime); -#else - if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID) - continue; - info.mtimeset = grub_fat_timestamp (grub_le_to_cpu16 (ctxt.dir.w_time), - grub_le_to_cpu16 (ctxt.dir.w_date), - &info.mtime); -#endif - - if (hook (ctxt.filename, &info, hook_data)) - break; - } - grub_fat_iterate_fini (&ctxt); - if (err == GRUB_ERR_EOF) - err = 0; - - fail: - if (found != &root) - grub_free (found); - - 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; - grub_fshelp_node_t found = NULL; - grub_err_t err; - grub_disk_t disk = file->device->disk; - - grub_dl_ref (my_mod); - - data = grub_fat_mount (disk); - if (! data) - goto fail; - - struct grub_fshelp_node root = { - .data = data, - .disk = disk, - .attr = GRUB_FAT_ATTR_DIRECTORY, - .file_size = 0, - .file_cluster = data->root_cluster, - .cur_cluster_num = ~0U, - .cur_cluster = 0, -#ifdef MODE_EXFAT - .is_contiguous = 0, -#endif - }; - - err = grub_fshelp_find_file_lookup (name, &root, &found, lookup_file, NULL, GRUB_FSHELP_REG); - if (err) - goto fail; - - file->data = found; - file->size = found->file_size; - - return GRUB_ERR_NONE; - - fail: - - if (found != &root) - grub_free (found); - - 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->read_hook_data, - file->offset, len, buf); -} - -static grub_err_t -grub_fat_close (grub_file_t file) -{ - grub_fshelp_node_t node = file->data; - - grub_free (node->data); - grub_free (node); - - grub_dl_unref (my_mod); - - return grub_errno; -} - -#ifdef MODE_EXFAT -static grub_err_t -grub_fat_label (grub_device_t device, char **label) -{ - struct grub_fat_dir_entry dir; - grub_ssize_t offset = -sizeof(dir); - grub_disk_t disk = device->disk; - struct grub_fshelp_node root = { - .disk = disk, - .attr = GRUB_FAT_ATTR_DIRECTORY, - .file_size = 0, - .cur_cluster_num = ~0U, - .cur_cluster = 0, - .is_contiguous = 0, - }; - - root.data = grub_fat_mount (disk); - if (! root.data) - return grub_errno; - - root.file_cluster = root.data->root_cluster; - - *label = NULL; - - while (1) - { - offset += sizeof (dir); - - if (grub_fat_read_data (disk, &root, 0, 0, - offset, sizeof (dir), (char *) &dir) - != sizeof (dir)) - break; - - if (dir.entry_type == 0) - break; - if (!(dir.entry_type & 0x80)) - continue; - - /* Volume label. */ - if (dir.entry_type == 0x83) - { - grub_size_t chc; - grub_uint16_t t[ARRAY_SIZE (dir.type_specific.volume_label.str)]; - grub_size_t i; - *label = grub_malloc (ARRAY_SIZE (dir.type_specific.volume_label.str) - * GRUB_MAX_UTF8_PER_UTF16 + 1); - if (!*label) - { - grub_free (root.data); - return grub_errno; - } - chc = dir.type_specific.volume_label.character_count; - if (chc > ARRAY_SIZE (dir.type_specific.volume_label.str)) - chc = ARRAY_SIZE (dir.type_specific.volume_label.str); - for (i = 0; i < chc; i++) - t[i] = grub_le_to_cpu16 (dir.type_specific.volume_label.str[i]); - *grub_utf16_to_utf8 ((grub_uint8_t *) *label, t, chc) = '\0'; - } - } - - grub_free (root.data); - return grub_errno; -} - -#else - -static grub_err_t -grub_fat_label (grub_device_t device, char **label) -{ - grub_disk_t disk = device->disk; - grub_err_t err; - struct grub_fat_iterate_context ctxt; - struct grub_fshelp_node root = { - .disk = disk, - .attr = GRUB_FAT_ATTR_DIRECTORY, - .file_size = 0, - .cur_cluster_num = ~0U, - .cur_cluster = 0, - }; - - *label = 0; - - grub_dl_ref (my_mod); - - root.data = grub_fat_mount (disk); - if (! root.data) - goto fail; - - root.file_cluster = root.data->root_cluster; - - err = grub_fat_iterate_init (&ctxt); - if (err) - goto fail; - - while (!(err = grub_fat_iterate_dir_next (&root, &ctxt))) - if ((ctxt.dir.attr & ~GRUB_FAT_ATTR_ARCHIVE) == GRUB_FAT_ATTR_VOLUME_ID) - { - *label = grub_strdup (ctxt.filename); - break; - } - - grub_fat_iterate_fini (&ctxt); - - fail: - - grub_dl_unref (my_mod); - - grub_free (root.data); - - return grub_errno; -} - -#endif - -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) - { - char *ptr; - *uuid = grub_xasprintf ("%04x-%04x", - (grub_uint16_t) (data->uuid >> 16), - (grub_uint16_t) data->uuid); - for (ptr = *uuid; ptr && *ptr; ptr++) - *ptr = grub_toupper (*ptr); - } - else - *uuid = NULL; - - grub_dl_unref (my_mod); - - grub_free (data); - - return grub_errno; -} - -#ifdef GRUB_UTIL -#ifndef MODE_EXFAT -grub_disk_addr_t -grub_fat_get_cluster_sector (grub_disk_t disk, grub_uint64_t *sec_per_lcn) -#else -grub_disk_addr_t - grub_exfat_get_cluster_sector (grub_disk_t disk, grub_uint64_t *sec_per_lcn) -#endif -{ - grub_disk_addr_t ret; - struct grub_fat_data *data; - data = grub_fat_mount (disk); - if (!data) - return 0; - ret = data->cluster_sector; - - *sec_per_lcn = 1ULL << data->cluster_bits; - - grub_free (data); - return ret; -} -#endif - -static struct grub_fs grub_fat_fs = - { -#ifdef MODE_EXFAT - .name = "exfat", -#else - .name = "fat", -#endif - .fs_dir = grub_fat_dir, - .fs_open = grub_fat_open, - .fs_read = grub_fat_read, - .fs_close = grub_fat_close, - .fs_label = grub_fat_label, - .fs_uuid = grub_fat_uuid, -#ifdef GRUB_UTIL -#ifdef MODE_EXFAT - /* ExFAT BPB is 30 larger than FAT32 one. */ - .reserved_first_sector = 0, -#else - .reserved_first_sector = 1, -#endif - .blocklist_install = 1, -#endif - .next = 0 - }; - -#ifdef MODE_EXFAT -GRUB_MOD_INIT(exfat) -#else -GRUB_MOD_INIT(fat) -#endif -{ - COMPILE_TIME_ASSERT (sizeof (struct grub_fat_dir_entry) == 32); - grub_fat_fs.mod = mod; - grub_fs_register (&grub_fat_fs); - my_mod = mod; -} -#ifdef MODE_EXFAT -GRUB_MOD_FINI(exfat) -#else -GRUB_MOD_FINI(fat) -#endif -{ - grub_fs_unregister (&grub_fat_fs); -} - diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c deleted file mode 100644 index 15278fb80..000000000 --- a/grub-core/fs/fshelp.c +++ /dev/null @@ -1,444 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -typedef int (*iterate_dir_func) (grub_fshelp_node_t dir, - grub_fshelp_iterate_dir_hook_t hook, - void *data); -typedef grub_err_t (*lookup_file_func) (grub_fshelp_node_t dir, - const char *name, - grub_fshelp_node_t *foundnode, - enum grub_fshelp_filetype *foundtype); -typedef char *(*read_symlink_func) (grub_fshelp_node_t node); - -struct stack_element { - struct stack_element *parent; - grub_fshelp_node_t node; - enum grub_fshelp_filetype type; -}; - -/* Context for grub_fshelp_find_file. */ -struct grub_fshelp_find_file_ctx -{ - /* Inputs. */ - const char *path; - grub_fshelp_node_t rootnode; - - /* Global options. */ - int symlinknest; - - /* Current file being traversed and its parents. */ - struct stack_element *currnode; -}; - -/* Helper for find_file_iter. */ -static void -free_node (grub_fshelp_node_t node, struct grub_fshelp_find_file_ctx *ctx) -{ - if (node != ctx->rootnode) - grub_free (node); -} - -static void -pop_element (struct grub_fshelp_find_file_ctx *ctx) -{ - struct stack_element *el; - el = ctx->currnode; - ctx->currnode = el->parent; - free_node (el->node, ctx); - grub_free (el); -} - -static void -free_stack (struct grub_fshelp_find_file_ctx *ctx) -{ - while (ctx->currnode) - pop_element (ctx); -} - -static void -go_up_a_level (struct grub_fshelp_find_file_ctx *ctx) -{ - if (!ctx->currnode->parent) - return; - pop_element (ctx); -} - -static grub_err_t -push_node (struct grub_fshelp_find_file_ctx *ctx, grub_fshelp_node_t node, enum grub_fshelp_filetype filetype) -{ - struct stack_element *nst; - nst = grub_malloc (sizeof (*nst)); - if (!nst) - return grub_errno; - nst->node = node; - nst->type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE; - nst->parent = ctx->currnode; - ctx->currnode = nst; - return GRUB_ERR_NONE; -} - -static grub_err_t -go_to_root (struct grub_fshelp_find_file_ctx *ctx) -{ - free_stack (ctx); - return push_node (ctx, ctx->rootnode, GRUB_FSHELP_DIR); -} - -struct grub_fshelp_find_file_iter_ctx -{ - const char *name; - grub_fshelp_node_t *foundnode; - enum grub_fshelp_filetype *foundtype; -}; - -/* Helper for grub_fshelp_find_file. */ -static int -find_file_iter (const char *filename, enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, void *data) -{ - struct grub_fshelp_find_file_iter_ctx *ctx = data; - - if (filetype == GRUB_FSHELP_UNKNOWN || - ((filetype & GRUB_FSHELP_CASE_INSENSITIVE) - ? grub_strcasecmp (ctx->name, filename) - : grub_strcmp (ctx->name, filename))) - { - grub_free (node); - return 0; - } - - /* The node is found, stop iterating over the nodes. */ - *ctx->foundnode = node; - *ctx->foundtype = filetype; - return 1; -} - -static grub_err_t -directory_find_file (grub_fshelp_node_t node, const char *name, grub_fshelp_node_t *foundnode, - enum grub_fshelp_filetype *foundtype, iterate_dir_func iterate_dir) -{ - int found; - struct grub_fshelp_find_file_iter_ctx ctx = { - .foundnode = foundnode, - .foundtype = foundtype, - .name = name - }; - found = iterate_dir (node, find_file_iter, &ctx); - if (! found) - { - if (grub_errno) - return grub_errno; - } - return GRUB_ERR_NONE; -} - -static grub_err_t -find_file (char *currpath, - iterate_dir_func iterate_dir, lookup_file_func lookup_file, - read_symlink_func read_symlink, - struct grub_fshelp_find_file_ctx *ctx) -{ - char *name, *next; - grub_err_t err; - for (name = currpath; ; name = next) - { - char c; - grub_fshelp_node_t foundnode = NULL; - enum grub_fshelp_filetype foundtype = 0; - - /* Remove all leading slashes. */ - while (*name == '/') - name++; - - /* Found the node! */ - if (! *name) - return 0; - - /* Extract the actual part from the pathname. */ - for (next = name; *next && *next != '/'; next++); - - /* At this point it is expected that the current node is a - directory, check if this is true. */ - if (ctx->currnode->type != GRUB_FSHELP_DIR) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); - - /* Don't rely on fs providing actual . in the listing. */ - if (next - name == 1 && name[0] == '.') - continue; - - /* Don't rely on fs providing actual .. in the listing. */ - if (next - name == 2 && name[0] == '.' && name[1] == '.') - { - go_up_a_level (ctx); - continue; - } - - /* Iterate over the directory. */ - c = *next; - *next = '\0'; - if (lookup_file) - err = lookup_file (ctx->currnode->node, name, &foundnode, &foundtype); - else - err = directory_find_file (ctx->currnode->node, name, &foundnode, &foundtype, iterate_dir); - *next = c; - - if (err) - return err; - - if (!foundnode) - break; - - push_node (ctx, foundnode, foundtype); - - /* Read in the symlink and follow it. */ - if (ctx->currnode->type == GRUB_FSHELP_SYMLINK) - { - char *symlink; - - /* Test if the symlink does not loop. */ - if (++ctx->symlinknest == 8) - return grub_error (GRUB_ERR_SYMLINK_LOOP, - N_("too deep nesting of symlinks")); - - if (read_symlink != NULL) - symlink = read_symlink (ctx->currnode->node); - else - return grub_error (GRUB_ERR_BAD_FS, "read_symlink is NULL"); - - if (!symlink) - return grub_errno; - - /* The symlink is an absolute path, go back to the root inode. */ - if (symlink[0] == '/') - { - err = go_to_root (ctx); - if (err) - return err; - } - else - { - /* Get from symlink to containing directory. */ - go_up_a_level (ctx); - } - - - /* Lookup the node the symlink points to. */ - find_file (symlink, iterate_dir, lookup_file, read_symlink, ctx); - grub_free (symlink); - - if (grub_errno) - return grub_errno; - } - } - - return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), - ctx->path); -} - -static grub_err_t -grub_fshelp_find_file_real (const char *path, grub_fshelp_node_t rootnode, - grub_fshelp_node_t *foundnode, - iterate_dir_func iterate_dir, - lookup_file_func lookup_file, - read_symlink_func read_symlink, - enum grub_fshelp_filetype expecttype) -{ - struct grub_fshelp_find_file_ctx ctx = { - .path = path, - .rootnode = rootnode, - .symlinknest = 0, - .currnode = 0 - }; - grub_err_t err; - enum grub_fshelp_filetype foundtype; - char *duppath; - - if (!path || path[0] != '/') - { - return grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid file name `%s'"), path); - } - - err = go_to_root (&ctx); - if (err) - return err; - - duppath = grub_strdup (path); - if (!duppath) - return grub_errno; - err = find_file (duppath, iterate_dir, lookup_file, read_symlink, &ctx); - grub_free (duppath); - if (err) - { - free_stack (&ctx); - return err; - } - - *foundnode = ctx.currnode->node; - foundtype = ctx.currnode->type; - /* Avoid the node being freed. */ - ctx.currnode->node = 0; - free_stack (&ctx); - - /* 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, N_("not a regular file")); - else if (expecttype == GRUB_FSHELP_DIR && foundtype != expecttype) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); - - return 0; -} - -/* 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. */ -grub_err_t -grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, - grub_fshelp_node_t *foundnode, - iterate_dir_func iterate_dir, - read_symlink_func read_symlink, - enum grub_fshelp_filetype expecttype) -{ - return grub_fshelp_find_file_real (path, rootnode, foundnode, - iterate_dir, NULL, - read_symlink, expecttype); - -} - -grub_err_t -grub_fshelp_find_file_lookup (const char *path, grub_fshelp_node_t rootnode, - grub_fshelp_node_t *foundnode, - lookup_file_func lookup_file, - read_symlink_func read_symlink, - enum grub_fshelp_filetype expecttype) -{ - return grub_fshelp_find_file_real (path, rootnode, foundnode, - NULL, lookup_file, - read_symlink, expecttype); - -} - -/* 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. READ_HOOK_DATA is passed through as - the DATA argument to READ_HOOK. 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, - grub_disk_read_hook_t read_hook, void *read_hook_data, - 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 blocks_start) -{ - grub_disk_addr_t i, blockcnt; - int blocksize = 1 << (log2blocksize + GRUB_DISK_SECTOR_BITS); - - /* - * Catch blatantly invalid log2blocksize. We could be a lot stricter, but - * this is the most permissive we can be before we start to see integer - * overflow/underflow issues. - */ - if (log2blocksize + GRUB_DISK_SECTOR_BITS >= 31) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("blocksize too large")); - return -1; - } - - if (pos > filesize) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("attempt to read past the end of file")); - return -1; - } - - /* 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; - disk->read_hook_data = read_hook_data; - - grub_disk_read (disk, blknr + blocks_start, skipfirst, - blockend, buf); - disk->read_hook = 0; - if (grub_errno) - return -1; - } - else - grub_memset (buf, 0, blockend); - - buf += blocksize - skipfirst; - } - - return len; -} diff --git a/grub-core/fs/hfspluscomp.c b/grub-core/fs/hfspluscomp.c deleted file mode 100644 index a80954ee6..000000000 --- a/grub-core/fs/hfspluscomp.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2012 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -/* HFS+ is documented at http://developer.apple.com/technotes/tn/tn1150.html */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* big-endian. */ -struct grub_hfsplus_compress_header1 -{ - grub_uint32_t header_size; - grub_uint32_t end_descriptor_offset; - grub_uint32_t total_compressed_size_including_seek_blocks_and_header2; - grub_uint32_t value_0x32; - grub_uint8_t unused[0xf0]; -} GRUB_PACKED; - -/* big-endian. */ -struct grub_hfsplus_compress_header2 -{ - grub_uint32_t total_compressed_size_including_seek_blocks; -} GRUB_PACKED; - -/* little-endian. */ -struct grub_hfsplus_compress_header3 -{ - grub_uint32_t num_chunks; -} GRUB_PACKED; - -/* little-endian. */ -struct grub_hfsplus_compress_block_descriptor -{ - grub_uint32_t offset; - grub_uint32_t size; -}; - -struct grub_hfsplus_compress_end_descriptor -{ - grub_uint8_t always_the_same[50]; -} GRUB_PACKED; - -struct grub_hfsplus_attr_header -{ - grub_uint8_t unused[3]; - grub_uint8_t type; - grub_uint32_t unknown[1]; - grub_uint64_t size; -} GRUB_PACKED; - -struct grub_hfsplus_compress_attr -{ - grub_uint32_t magic; - grub_uint32_t type; - grub_uint32_t uncompressed_inline_size; - grub_uint32_t always_0; -} GRUB_PACKED; - -enum - { - HFSPLUS_COMPRESSION_INLINE = 3, - HFSPLUS_COMPRESSION_RESOURCE = 4 - }; - -static int -grub_hfsplus_cmp_attrkey (struct grub_hfsplus_key *keya, - struct grub_hfsplus_key_internal *keyb) -{ - struct grub_hfsplus_attrkey *attrkey_a = &keya->attrkey; - struct grub_hfsplus_attrkey_internal *attrkey_b = &keyb->attrkey; - grub_uint32_t aparent = grub_be_to_cpu32 (attrkey_a->cnid); - grub_size_t len; - int diff; - - if (aparent > attrkey_b->cnid) - return 1; - if (aparent < attrkey_b->cnid) - return -1; - - len = grub_be_to_cpu16 (attrkey_a->namelen); - if (len > attrkey_b->namelen) - len = attrkey_b->namelen; - /* Since it's big-endian memcmp gives the same result as manually comparing - uint16_t but may be faster. */ - diff = grub_memcmp (attrkey_a->name, attrkey_b->name, - len * sizeof (attrkey_a->name[0])); - if (diff == 0) - diff = grub_be_to_cpu16 (attrkey_a->namelen) - attrkey_b->namelen; - return diff; -} - -#define HFSPLUS_COMPRESS_BLOCK_SIZE 65536 - -static grub_ssize_t -hfsplus_read_compressed_real (struct grub_hfsplus_file *node, - grub_off_t pos, grub_size_t len, char *buf) -{ - char *tmp_buf = 0; - grub_size_t len0 = len; - - if (node->compressed == 1) - { - grub_memcpy (buf, node->cbuf + pos, len); - if (grub_file_progress_hook && node->file) - grub_file_progress_hook (0, 0, len, NULL, node->file); - return len; - } - - while (len) - { - grub_uint32_t block = pos / HFSPLUS_COMPRESS_BLOCK_SIZE; - grub_size_t curlen = HFSPLUS_COMPRESS_BLOCK_SIZE - - (pos % HFSPLUS_COMPRESS_BLOCK_SIZE); - - if (curlen > len) - curlen = len; - - if (node->cbuf_block != block) - { - grub_uint32_t sz = grub_le_to_cpu32 (node->compress_index[block].size); - grub_size_t ts; - if (!tmp_buf) - tmp_buf = grub_malloc (HFSPLUS_COMPRESS_BLOCK_SIZE); - if (!tmp_buf) - return -1; - if (grub_hfsplus_read_file (node, 0, 0, - grub_le_to_cpu32 (node->compress_index[block].start) + 0x104, - sz, tmp_buf) - != (grub_ssize_t) sz) - { - grub_free (tmp_buf); - return -1; - } - ts = HFSPLUS_COMPRESS_BLOCK_SIZE; - if (ts > node->size - (pos & ~(HFSPLUS_COMPRESS_BLOCK_SIZE))) - ts = node->size - (pos & ~(HFSPLUS_COMPRESS_BLOCK_SIZE)); - if (grub_zlib_decompress (tmp_buf, sz, 0, - node->cbuf, ts) != (grub_ssize_t) ts) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, - "premature end of compressed"); - - grub_free (tmp_buf); - return -1; - } - node->cbuf_block = block; - } - grub_memcpy (buf, node->cbuf + (pos % HFSPLUS_COMPRESS_BLOCK_SIZE), - curlen); - if (grub_file_progress_hook && node->file) - grub_file_progress_hook (0, 0, curlen, NULL, node->file); - buf += curlen; - pos += curlen; - len -= curlen; - } - grub_free (tmp_buf); - return len0; -} - -static grub_err_t -hfsplus_open_compressed_real (struct grub_hfsplus_file *node) -{ - grub_err_t err; - struct grub_hfsplus_btnode *attr_node; - grub_off_t attr_off; - struct grub_hfsplus_key_internal key; - struct grub_hfsplus_attr_header *attr_head; - struct grub_hfsplus_compress_attr *cmp_head; -#define c grub_cpu_to_be16_compile_time - const grub_uint16_t compress_attr_name[] = - { - c('c'), c('o'), c('m'), c('.'), c('a'), c('p'), c('p'), c('l'), c('e'), - c('.'), c('d'), c('e'), c('c'), c('m'), c('p'), c('f'), c('s') }; -#undef c - if (node->size) - return 0; - - key.attrkey.cnid = node->fileid; - key.attrkey.namelen = sizeof (compress_attr_name) / sizeof (compress_attr_name[0]); - key.attrkey.name = compress_attr_name; - - err = grub_hfsplus_btree_search (&node->data->attr_tree, &key, - grub_hfsplus_cmp_attrkey, - &attr_node, &attr_off); - if (err || !attr_node) - { - grub_errno = 0; - return 0; - } - - attr_head = (struct grub_hfsplus_attr_header *) - ((char *) grub_hfsplus_btree_recptr (&node->data->attr_tree, - attr_node, attr_off) - + sizeof (struct grub_hfsplus_attrkey) + sizeof (compress_attr_name)); - if (attr_head->type != 0x10 - || !(attr_head->size & grub_cpu_to_be64_compile_time(~0xfULL))) - { - grub_free (attr_node); - return 0; - } - cmp_head = (struct grub_hfsplus_compress_attr *) (attr_head + 1); - if (cmp_head->magic != grub_cpu_to_be32_compile_time (0x66706d63)) - { - grub_free (attr_node); - return 0; - } - node->size = grub_le_to_cpu32 (cmp_head->uncompressed_inline_size); - - if (cmp_head->type == grub_cpu_to_le32_compile_time (HFSPLUS_COMPRESSION_RESOURCE)) - { - grub_uint32_t index_size; - node->compressed = 2; - - if (grub_hfsplus_read_file (node, 0, 0, - 0x104, sizeof (index_size), - (char *) &index_size) - != 4) - { - node->compressed = 0; - grub_free (attr_node); - grub_errno = 0; - return 0; - } - node->compress_index_size = grub_le_to_cpu32 (index_size); - node->compress_index = grub_calloc (node->compress_index_size, - sizeof (node->compress_index[0])); - if (!node->compress_index) - { - node->compressed = 0; - grub_free (attr_node); - return grub_errno; - } - - /* - * The node->compress_index_size * sizeof (node->compress_index[0]) is safe here - * due to relevant checks done in grub_calloc() above. - */ - if (grub_hfsplus_read_file (node, 0, 0, - 0x104 + sizeof (index_size), - node->compress_index_size - * sizeof (node->compress_index[0]), - (char *) node->compress_index) - != (grub_ssize_t) (node->compress_index_size - * sizeof (node->compress_index[0]))) - { - node->compressed = 0; - grub_free (attr_node); - grub_free (node->compress_index); - grub_errno = 0; - return 0; - } - - node->cbuf_block = -1; - - node->cbuf = grub_malloc (HFSPLUS_COMPRESS_BLOCK_SIZE); - grub_free (attr_node); - if (!node->cbuf) - { - node->compressed = 0; - grub_free (node->compress_index); - return grub_errno; - } - return 0; - } - if (cmp_head->type != HFSPLUS_COMPRESSION_INLINE) - { - grub_free (attr_node); - return 0; - } - - node->cbuf = grub_malloc (node->size); - if (!node->cbuf) - return grub_errno; - - if (grub_zlib_decompress ((char *) (cmp_head + 1), - grub_cpu_to_be64 (attr_head->size) - - sizeof (*cmp_head), 0, - node->cbuf, node->size) - != (grub_ssize_t) node->size) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, - "premature end of compressed"); - return grub_errno; - } - node->compressed = 1; - return 0; -} - -GRUB_MOD_INIT(hfspluscomp) -{ - grub_hfsplus_open_compressed = hfsplus_open_compressed_real; - grub_hfsplus_read_compressed = hfsplus_read_compressed_real; -} - -GRUB_MOD_FINI(hfspluscomp) -{ - grub_hfsplus_open_compressed = 0; - grub_hfsplus_read_compressed = 0; -} diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c deleted file mode 100644 index c73cb9ce0..000000000 --- a/grub-core/fs/iso9660.c +++ /dev/null @@ -1,1271 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#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 - -#define GRUB_ISO9660_SUSP_HEADER_SZ 4 -#define GRUB_ISO9660_MAX_CE_HOPS 100000 - -/* The head of a volume descriptor. */ -struct grub_iso9660_voldesc -{ - grub_uint8_t type; - grub_uint8_t magic[5]; - grub_uint8_t version; -} GRUB_PACKED; - -struct grub_iso9660_date2 -{ - grub_uint8_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 offset; -} GRUB_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; - struct grub_iso9660_date2 mtime; - grub_uint8_t flags; - grub_uint8_t unused2[6]; -#define MAX_NAMELEN 255 - grub_uint8_t namelen; -} GRUB_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; -} GRUB_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; -} GRUB_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]; -} GRUB_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]; -} GRUB_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; -} GRUB_PACKED; - -struct grub_iso9660_data -{ - struct grub_iso9660_primary_voldesc voldesc; - grub_disk_t disk; - int rockridge; - int susp_skip; - int joliet; - struct grub_fshelp_node *node; -}; - -struct grub_fshelp_node -{ - struct grub_iso9660_data *data; - grub_size_t have_dirents, alloc_dirents; - int have_symlink; - struct grub_iso9660_dir dirents[8]; - char symlink[0]; -}; - -enum - { - FLAG_TYPE_PLAIN = 0, - FLAG_TYPE_DIR = 2, - FLAG_TYPE = 3, - FLAG_MORE_EXTENTS = 0x80 - }; - -static grub_dl_t my_mod; - - -static grub_err_t -iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int64_t *nix) -{ - struct grub_datetime datetime; - - if (! i->year[0] && ! i->year[1] - && ! i->year[2] && ! i->year[3] - && ! i->month[0] && ! i->month[1] - && ! i->day[0] && ! i->day[1] - && ! i->hour[0] && ! i->hour[1] - && ! i->minute[0] && ! i->minute[1] - && ! i->second[0] && ! i->second[1] - && ! i->hundredth[0] && ! i->hundredth[1]) - return grub_error (GRUB_ERR_BAD_NUMBER, "empty date"); - datetime.year = (i->year[0] - '0') * 1000 + (i->year[1] - '0') * 100 - + (i->year[2] - '0') * 10 + (i->year[3] - '0'); - datetime.month = (i->month[0] - '0') * 10 + (i->month[1] - '0'); - datetime.day = (i->day[0] - '0') * 10 + (i->day[1] - '0'); - datetime.hour = (i->hour[0] - '0') * 10 + (i->hour[1] - '0'); - datetime.minute = (i->minute[0] - '0') * 10 + (i->minute[1] - '0'); - datetime.second = (i->second[0] - '0') * 10 + (i->second[1] - '0'); - - if (!grub_datetime2unixtime (&datetime, nix)) - return grub_error (GRUB_ERR_BAD_NUMBER, "incorrect date"); - *nix -= i->offset * 60 * 15; - return GRUB_ERR_NONE; -} - -static int -iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int64_t *nix) -{ - struct grub_datetime datetime; - - datetime.year = i->year + 1900; - datetime.month = i->month; - datetime.day = i->day; - datetime.hour = i->hour; - datetime.minute = i->minute; - datetime.second = i->second; - - if (!grub_datetime2unixtime (&datetime, nix)) - return 0; - *nix -= i->offset * 60 * 15; - return 1; -} - -static grub_err_t -read_node (grub_fshelp_node_t node, grub_off_t off, grub_size_t len, char *buf) -{ - grub_size_t i = 0; - - while (len > 0) - { - grub_size_t toread; - grub_err_t err; - while (i < node->have_dirents - && off >= grub_le_to_cpu32 (node->dirents[i].size)) - { - off -= grub_le_to_cpu32 (node->dirents[i].size); - i++; - } - if (i == node->have_dirents) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "read out of range"); - toread = grub_le_to_cpu32 (node->dirents[i].size); - if (toread > len) - toread = len; - err = grub_disk_read (node->data->disk, - ((grub_disk_addr_t) grub_le_to_cpu32 (node->dirents[i].first_sector)) << GRUB_ISO9660_LOG2_BLKSZ, - off, toread, buf); - if (err) - return err; - len -= toread; - off += toread; - buf += toread; - } - return GRUB_ERR_NONE; -} - -/* 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 (grub_fshelp_node_t node, grub_off_t off, - grub_ssize_t sua_size, - grub_err_t (*hook) - (struct grub_iso9660_susp_entry *entry, void *hook_arg), - void *hook_arg) -{ - char *sua; - struct grub_iso9660_susp_entry *entry; - grub_err_t err; - int ce_counter = 0; - grub_ssize_t ce_sua_size = 0; - grub_off_t ce_off; - grub_disk_addr_t ce_block; - - if (sua_size <= 0) - return GRUB_ERR_NONE; - - if (sua_size < GRUB_ISO9660_SUSP_HEADER_SZ) - return grub_error (GRUB_ERR_BAD_FS, "invalid susp entry size"); - - sua = grub_malloc (sua_size); - if (!sua) - return grub_errno; - - /* Load a part of the System Usage Area. */ - err = read_node (node, off, sua_size, sua); - if (err) - { - grub_free (sua); - return err; - } - - entry = (struct grub_iso9660_susp_entry *) sua; - - next_susp_area: - while (entry->len > 0) - { - /* Ensure the entry is within System Use Area. */ - if ((char *) entry + entry->len > (sua + sua_size)) - break; - - /* 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; - - if (ce_sua_size > 0) - { - grub_free (sua); - return grub_error (GRUB_ERR_BAD_FS, - "more than one CE entry in SUSP area"); - } - - /* Buffer CE parameters for use after the end of this loop. */ - ce = (struct grub_iso9660_susp_ce *) entry; - ce_sua_size = grub_le_to_cpu32 (ce->len); - ce_off = grub_le_to_cpu32 (ce->off); - ce_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ; - } - else if (hook (entry, hook_arg)) - { - grub_free (sua); - return 0; - } - - entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len); - - if (((sua + sua_size) - (char *) entry) < GRUB_ISO9660_SUSP_HEADER_SZ) - break; - } - - if (ce_sua_size > 0) - { - /* Load the next System Use Area by buffered CE entry parameters. */ - if (++ce_counter > GRUB_ISO9660_MAX_CE_HOPS) - { - grub_free (sua); - return grub_error (GRUB_ERR_BAD_FS, "suspecting endless CE loop"); - } - if (ce_sua_size < GRUB_ISO9660_SUSP_HEADER_SZ) - { - grub_free (sua); - return grub_error (GRUB_ERR_BAD_FS, "invalid continuation area in CE entry"); - } - - grub_free (sua); - sua = grub_malloc (ce_sua_size); - if (!sua) - return grub_errno; - - err = grub_disk_read (node->data->disk, ce_block, ce_off, ce_sua_size, sua); - if (err) - { - grub_free (sua); - return err; - } - entry = (struct grub_iso9660_susp_entry *) sua; - sua_size = ce_sua_size; - ce_sua_size = 0; - - goto next_susp_area; - } - - grub_free (sua); - return 0; -} - -static char * -grub_iso9660_convert_string (grub_uint8_t *us, int len) -{ - char *p; - int i; - grub_uint16_t t[MAX_NAMELEN / 2 + 1]; - - p = grub_calloc (len, GRUB_MAX_UTF8_PER_UTF16 + 1); - if (! p) - return NULL; - - for (i=0; isig, "ER", 2) == 0) - { - data->rockridge = 1; - return 1; - } - return 0; -} - -static grub_err_t -set_rockridge (struct grub_iso9660_data *data) -{ - int sua_pos; - int sua_size; - char *sua; - struct grub_iso9660_dir rootdir; - struct grub_iso9660_susp_entry *entry; - - data->rockridge = 0; - - /* Read the system use area and test it to see if SUSP is - supported. */ - if (grub_disk_read (data->disk, - (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) - << GRUB_ISO9660_LOG2_BLKSZ), 0, - sizeof (rootdir), (char *) &rootdir)) - return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); - - sua_pos = (sizeof (rootdir) + rootdir.namelen - + (rootdir.namelen % 2) - 1); - sua_size = rootdir.len - sua_pos; - - if (!sua_size) - return GRUB_ERR_NONE; - - if (sua_size < GRUB_ISO9660_SUSP_HEADER_SZ) - return grub_error (GRUB_ERR_BAD_FS, "invalid rock ridge entry size"); - - sua = grub_malloc (sua_size); - if (! sua) - return grub_errno; - - if (grub_disk_read (data->disk, - (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) - << GRUB_ISO9660_LOG2_BLKSZ), sua_pos, - sua_size, sua)) - { - grub_free (sua); - return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); - } - - 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) - { - struct grub_fshelp_node rootnode; - - rootnode.data = data; - rootnode.alloc_dirents = ARRAY_SIZE (rootnode.dirents); - rootnode.have_dirents = 1; - rootnode.have_symlink = 0; - rootnode.dirents[0] = data->voldesc.rootdir; - - /* The size of SP (version 1) is fixed to 7. */ - if (sua_size < 7 || entry->len < 7) - { - grub_free (sua); - return grub_error (GRUB_ERR_BAD_FS, "corrupted rock ridge entry"); - } - - /* - * 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 (&rootnode, - sua_pos, sua_size, susp_iterate_set_rockridge, - data)) - { - grub_free (sua); - return grub_errno; - } - } - grub_free (sua); - return GRUB_ERR_NONE; -} - -static struct grub_iso9660_data * -grub_iso9660_mount (grub_disk_t disk) -{ - struct grub_iso9660_data *data = 0; - struct grub_iso9660_primary_voldesc voldesc; - int block; - - 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 (!data->rockridge - && (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)); - if (set_rockridge (data)) - goto fail; - } - - block++; - } while (voldesc.voldesc.type != GRUB_ISO9660_VOLDESC_END); - - return data; - - fail: - if (grub_errno == GRUB_ERR_NONE) - grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); - - grub_free (data); - return 0; -} - - -static char * -grub_iso9660_read_symlink (grub_fshelp_node_t node) -{ - return node->have_symlink - ? grub_strdup (node->symlink - + (node->have_dirents) * sizeof (node->dirents[0]) - - sizeof (node->dirents)) : grub_strdup (""); -} - -static grub_off_t -get_node_size (grub_fshelp_node_t node) -{ - grub_off_t ret = 0; - grub_size_t i; - - for (i = 0; i < node->have_dirents; i++) - ret += grub_le_to_cpu32 (node->dirents[i].size); - return ret; -} - -struct iterate_dir_ctx -{ - char *filename; - int filename_alloc; - enum grub_fshelp_filetype type; - char *symlink; - int was_continue; -}; - - /* Extend the symlink. */ -static void -add_part (struct iterate_dir_ctx *ctx, - const char *part, - int len2) -{ - int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0; - grub_size_t sz; - char *new; - - if (grub_add (size, len2, &sz) || - grub_add (sz, 1, &sz)) - return; - - new = grub_realloc (ctx->symlink, sz); - if (!new) - { - grub_free (ctx->symlink); - ctx->symlink = NULL; - return; - } - ctx->symlink = new; - - grub_memcpy (ctx->symlink + size, part, len2); - ctx->symlink[size + len2] = 0; -} - -static grub_err_t -susp_iterate_dir (struct grub_iso9660_susp_entry *entry, - void *_ctx) -{ - struct iterate_dir_ctx *ctx = _ctx; - - /* 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. */ - /* FIXME: Fix this slightly improper cast. */ - if (entry->data[0] & GRUB_ISO9660_RR_DOT) - { - if (ctx->filename_alloc) - grub_free (ctx->filename); - ctx->filename_alloc = 0; - ctx->filename = (char *) "."; - } - else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT) - { - if (ctx->filename_alloc) - grub_free (ctx->filename); - ctx->filename_alloc = 0; - ctx->filename = (char *) ".."; - } - else if (entry->len >= 5) - { - grub_size_t off = 0, csize = 1; - char *old; - grub_size_t sz; - - csize = entry->len - 5; - old = ctx->filename; - if (ctx->filename_alloc) - { - off = grub_strlen (ctx->filename); - if (grub_add (csize, off, &sz) || - grub_add (sz, 1, &sz)) - return GRUB_ERR_OUT_OF_RANGE; - ctx->filename = grub_realloc (ctx->filename, sz); - } - else - { - off = 0; - if (grub_add (csize, 1, &sz)) - return GRUB_ERR_OUT_OF_RANGE; - ctx->filename = grub_zalloc (sz); - } - if (!ctx->filename) - { - ctx->filename = old; - return grub_errno; - } - ctx->filename_alloc = 1; - grub_memcpy (ctx->filename + off, (char *) &entry->data[1], csize); - ctx->filename[off + csize] = '\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: - ctx->type = GRUB_FSHELP_DIR; - break; - case GRUB_ISO9660_FSTYPE_REG: - ctx->type = GRUB_FSHELP_REG; - break; - case GRUB_ISO9660_FSTYPE_SYMLINK: - ctx->type = GRUB_FSHELP_SYMLINK; - break; - default: - ctx->type = GRUB_FSHELP_UNKNOWN; - } - } - else if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0) - { - unsigned int pos = 1; - unsigned int csize; - - /* The symlink is not stored as a POSIX symlink, translate it. */ - while ((pos + GRUB_ISO9660_SUSP_HEADER_SZ + 1) < entry->len) - { - /* - * entry->len is GRUB_ISO9660_SUSP_HEADER_SZ + 1 (the FLAGS) + - * length of the "Component Area". The length of a component - * record is 2 (pos and pos + 1) plus the "Component Content", - * of which starts at pos + 2. entry->data[pos] is the - * "Component Flags"; entry->data[pos + 1] is the length - * of the component. - */ - csize = entry->data[pos + 1] + 2; - if (GRUB_ISO9660_SUSP_HEADER_SZ + 1 + csize > entry->len) - break; - - /* 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'. */ - if (ctx->symlink && !ctx->was_continue) - { - add_part (ctx, "/", 1); - if (grub_errno) - return grub_errno; - } - - add_part (ctx, (char *) &entry->data[pos + 2], - entry->data[pos + 1]); - ctx->was_continue = (entry->data[pos] & 1); - break; - } - - case 2: - add_part (ctx, "./", 2); - break; - - case 4: - add_part (ctx, "../", 3); - break; - - case 8: - add_part (ctx, "/", 1); - break; - } - - /* Check if grub_realloc() failed in add_part(). */ - if (grub_errno) - return grub_errno; - - /* 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; -} - -static int -grub_iso9660_iterate_dir (grub_fshelp_node_t dir, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data) -{ - struct grub_iso9660_dir dirent; - grub_off_t offset = 0; - grub_off_t len; - struct iterate_dir_ctx ctx; - - len = get_node_size (dir); - - for (; offset < len; offset += dirent.len) - { - ctx.symlink = 0; - ctx.was_continue = 0; - - if (read_node (dir, offset, 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[MAX_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; - - ctx.filename = 0; - ctx.filename_alloc = 0; - ctx.type = GRUB_FSHELP_UNKNOWN; - - if (dir->data->rockridge - && grub_iso9660_susp_iterate (dir, sua_off, sua_size, - susp_iterate_dir, &ctx)) - return 0; - - /* Read the name. */ - if (read_node (dir, nameoffset, dirent.namelen, (char *) name)) - return 0; - - node = grub_malloc (sizeof (struct grub_fshelp_node)); - if (!node) - return 0; - - node->alloc_dirents = ARRAY_SIZE (node->dirents); - node->have_dirents = 1; - - /* Setup a new node. */ - node->data = dir->data; - node->have_symlink = 0; - - /* If the filetype was not stored using rockridge, use - whatever is stored in the iso9660 filesystem. */ - if (ctx.type == GRUB_FSHELP_UNKNOWN) - { - if ((dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR) - ctx.type = GRUB_FSHELP_DIR; - else - ctx.type = GRUB_FSHELP_REG; - } - - /* . and .. */ - if (!ctx.filename && dirent.namelen == 1 && name[0] == 0) - ctx.filename = (char *) "."; - - if (!ctx.filename && dirent.namelen == 1 && name[0] == 1) - ctx.filename = (char *) ".."; - - /* The filename was not stored in a rock ridge entry. Read it - from the iso9660 filesystem. */ - if (!dir->data->joliet && !ctx.filename) - { - char *ptr; - name[dirent.namelen] = '\0'; - ctx.filename = grub_strrchr (name, ';'); - if (ctx.filename) - *ctx.filename = '\0'; - /* ISO9660 names are not case-preserving. */ - ctx.type |= GRUB_FSHELP_CASE_INSENSITIVE; - for (ptr = name; *ptr; ptr++) - *ptr = grub_tolower (*ptr); - if (ptr != name && *(ptr - 1) == '.') - *(ptr - 1) = 0; - ctx.filename = name; - } - - if (dir->data->joliet && !ctx.filename) - { - char *semicolon; - - ctx.filename = grub_iso9660_convert_string - ((grub_uint8_t *) name, dirent.namelen >> 1); - - semicolon = grub_strrchr (ctx.filename, ';'); - if (semicolon) - *semicolon = '\0'; - - ctx.filename_alloc = 1; - } - - node->dirents[0] = dirent; - while (dirent.flags & FLAG_MORE_EXTENTS) - { - offset += dirent.len; - - /* offset should within the dir's len. */ - if (offset > len) - { - if (ctx.filename_alloc) - grub_free (ctx.filename); - grub_free (node); - return 0; - } - - if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) - { - if (ctx.filename_alloc) - grub_free (ctx.filename); - grub_free (node); - return 0; - } - - /* - * It is either the end of block or zero-padded sector, - * skip to the next block. - */ - if (!dirent.len) - { - offset = (offset / GRUB_ISO9660_BLKSZ + 1) * GRUB_ISO9660_BLKSZ; - dirent.flags |= FLAG_MORE_EXTENTS; - continue; - } - - if (node->have_dirents >= node->alloc_dirents) - { - struct grub_fshelp_node *new_node; - grub_size_t sz; - - if (grub_mul (node->alloc_dirents, 2, &node->alloc_dirents) || - grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) || - grub_mul (sz, sizeof (node->dirents[0]), &sz) || - grub_add (sz, sizeof (struct grub_fshelp_node), &sz)) - goto fail_0; - - new_node = grub_realloc (node, sz); - if (!new_node) - { - fail_0: - if (ctx.filename_alloc) - grub_free (ctx.filename); - grub_free (node); - return 0; - } - node = new_node; - } - node->dirents[node->have_dirents++] = dirent; - } - if (ctx.symlink) - { - if ((node->alloc_dirents - node->have_dirents) - * sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1) - { - struct grub_fshelp_node *new_node; - grub_size_t sz; - - if (grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) || - grub_mul (sz, sizeof (node->dirents[0]), &sz) || - grub_add (sz, sizeof (struct grub_fshelp_node) + 1, &sz) || - grub_add (sz, grub_strlen (ctx.symlink), &sz)) - goto fail_1; - - new_node = grub_realloc (node, sz); - if (!new_node) - { - fail_1: - if (ctx.filename_alloc) - grub_free (ctx.filename); - grub_free (node); - return 0; - } - node = new_node; - } - node->have_symlink = 1; - grub_strcpy (node->symlink - + node->have_dirents * sizeof (node->dirents[0]) - - sizeof (node->dirents), ctx.symlink); - grub_free (ctx.symlink); - ctx.symlink = 0; - ctx.was_continue = 0; - } - if (hook (ctx.filename, ctx.type, node, hook_data)) - { - if (ctx.filename_alloc) - grub_free (ctx.filename); - return 1; - } - if (ctx.filename_alloc) - grub_free (ctx.filename); - } - } - - return 0; -} - - - -/* Context for grub_iso9660_dir. */ -struct grub_iso9660_dir_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; -}; - -/* Helper for grub_iso9660_dir. */ -static int -grub_iso9660_dir_iter (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, void *data) -{ - struct grub_iso9660_dir_ctx *ctx = data; - struct grub_dirhook_info info; - - grub_memset (&info, 0, sizeof (info)); - info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); - info.mtimeset = !!iso9660_to_unixtime2 (&node->dirents[0].mtime, &info.mtime); - - grub_free (node); - return ctx->hook (filename, &info, ctx->hook_data); -} - -static grub_err_t -grub_iso9660_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_iso9660_dir_ctx ctx = { hook, hook_data }; - struct grub_iso9660_data *data = 0; - struct grub_fshelp_node rootnode; - struct grub_fshelp_node *foundnode; - - grub_dl_ref (my_mod); - - data = grub_iso9660_mount (device->disk); - if (! data) - goto fail; - - rootnode.data = data; - rootnode.alloc_dirents = 0; - rootnode.have_dirents = 1; - rootnode.have_symlink = 0; - rootnode.dirents[0] = data->voldesc.rootdir; - - /* 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, grub_iso9660_dir_iter, &ctx); - - 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.alloc_dirents = 0; - rootnode.have_dirents = 1; - rootnode.have_symlink = 0; - rootnode.dirents[0] = data->voldesc.rootdir; - - /* 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->node = foundnode; - file->data = data; - file->size = get_node_size (foundnode); - 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; - grub_err_t err; - - /* XXX: The file is stored in as a single extent. */ - data->disk->read_hook = file->read_hook; - data->disk->read_hook_data = file->read_hook_data; - err = read_node (data->node, file->offset, len, buf); - data->disk->read_hook = NULL; - - if (err || grub_errno) - return -1; - - return len; -} - - -static grub_err_t -grub_iso9660_close (grub_file_t file) -{ - struct grub_iso9660_data *data = - (struct grub_iso9660_data *) file->data; - grub_free (data->node); - grub_free (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 (data->voldesc.volname, 16); - else - *label = grub_strndup ((char *) data->voldesc.volname, 32); - if (*label) - { - char *ptr; - for (ptr = *label; *ptr;ptr++); - ptr--; - while (ptr >= *label && *ptr == ' ') - *ptr-- = 0; - } - - 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; -} - -/* Get writing time of filesystem. */ -static grub_err_t -grub_iso9660_mtime (grub_device_t device, grub_int64_t *timebuf) -{ - struct grub_iso9660_data *data; - grub_disk_t disk = device->disk; - grub_err_t err; - - grub_dl_ref (my_mod); - - data = grub_iso9660_mount (disk); - if (!data) - { - grub_dl_unref (my_mod); - return grub_errno; - } - err = iso9660_to_unixtime (&data->voldesc.modified, timebuf); - - grub_dl_unref (my_mod); - - grub_free (data); - - return err; -} - - - - -static struct grub_fs grub_iso9660_fs = - { - .name = "iso9660", - .fs_dir = grub_iso9660_dir, - .fs_open = grub_iso9660_open, - .fs_read = grub_iso9660_read, - .fs_close = grub_iso9660_close, - .fs_label = grub_iso9660_label, - .fs_uuid = grub_iso9660_uuid, - .fs_mtime = grub_iso9660_mtime, -#ifdef GRUB_UTIL - .reserved_first_sector = 1, - .blocklist_install = 1, -#endif - .next = 0 - }; - -GRUB_MOD_INIT(iso9660) -{ - grub_iso9660_fs.mod = mod; - 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/minix.c b/grub-core/fs/minix.c deleted file mode 100644 index 4440fcca8..000000000 --- a/grub-core/fs/minix.c +++ /dev/null @@ -1,766 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#ifdef MODE_MINIX3 -#define GRUB_MINIX_MAGIC 0x4D5A -#elif defined(MODE_MINIX2) -#define GRUB_MINIX_MAGIC 0x2468 -#define GRUB_MINIX_MAGIC_30 0x2478 -#else -#define GRUB_MINIX_MAGIC 0x137F -#define GRUB_MINIX_MAGIC_30 0x138F -#endif - -#define EXT2_MAGIC 0xEF53 - -#define GRUB_MINIX_INODE_DIR_BLOCKS 7 -#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 - -#ifdef MODE_BIGENDIAN -#define grub_cpu_to_minix16_compile_time grub_cpu_to_be16_compile_time -#define grub_minix_to_cpu16 grub_be_to_cpu16 -#define grub_minix_to_cpu32 grub_be_to_cpu32 -#else -#define grub_cpu_to_minix16_compile_time grub_cpu_to_le16_compile_time -#define grub_minix_to_cpu16 grub_le_to_cpu16 -#define grub_minix_to_cpu32 grub_le_to_cpu32 -#endif - -#if defined(MODE_MINIX2) || defined(MODE_MINIX3) -typedef grub_uint32_t grub_minix_uintn_t; -#define grub_minix_to_cpu_n grub_minix_to_cpu32 -#else -typedef grub_uint16_t grub_minix_uintn_t; -#define grub_minix_to_cpu_n grub_minix_to_cpu16 -#endif - -#ifdef MODE_MINIX3 -typedef grub_uint32_t grub_minix_ino_t; -#define grub_minix_to_cpu_ino grub_minix_to_cpu32 -#else -typedef grub_uint16_t grub_minix_ino_t; -#define grub_minix_to_cpu_ino grub_minix_to_cpu16 -#endif - -#define GRUB_MINIX_INODE_SIZE(data) (grub_minix_to_cpu32 (data->inode.size)) -#define GRUB_MINIX_INODE_MODE(data) (grub_minix_to_cpu16 (data->inode.mode)) -#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) (grub_minix_to_cpu_n \ - (data->inode.dir_zones[blk])) -#define GRUB_MINIX_INODE_INDIR_ZONE(data) (grub_minix_to_cpu_n \ - (data->inode.indir_zone)) -#define GRUB_MINIX_INODE_DINDIR_ZONE(data) (grub_minix_to_cpu_n \ - (data->inode.double_indir_zone)) - - -#ifdef MODE_MINIX3 -struct grub_minix_sblock -{ - grub_uint32_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_uint16_t pad; - grub_uint32_t max_file_size; - grub_uint32_t zones; - grub_uint16_t magic; - - grub_uint16_t pad2; - grub_uint16_t block_size; - grub_uint8_t disk_version; -}; -#else -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; -}; -#endif - -#if defined(MODE_MINIX3) || defined(MODE_MINIX2) -struct grub_minix_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 triple_indir_zone; -}; -#else -struct grub_minix_inode -{ - grub_uint16_t mode; - grub_uint16_t uid; - grub_uint32_t size; - grub_uint32_t mtime; - 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; -}; - -#endif - -#if defined(MODE_MINIX3) -#define MAX_MINIX_FILENAME_SIZE 60 -#else -#define MAX_MINIX_FILENAME_SIZE 30 -#endif - -/* Information about a "mounted" minix filesystem. */ -struct grub_minix_data -{ - struct grub_minix_sblock sblock; - struct grub_minix_inode inode; - grub_uint32_t block_per_zone; - grub_minix_ino_t ino; - int linknest; - grub_disk_t disk; - int filename_size; - grub_size_t block_size; -}; - -static grub_dl_t my_mod; - -static grub_err_t grub_minix_find_file (struct grub_minix_data *data, - const char *path); - -#ifdef MODE_MINIX3 -static inline grub_disk_addr_t -grub_minix_zone2sect (struct grub_minix_data *data, grub_minix_uintn_t zone) -{ - return ((grub_disk_addr_t) zone) * data->block_size; -} -#else -static inline grub_disk_addr_t -grub_minix_zone2sect (struct grub_minix_data *data, grub_minix_uintn_t zone) -{ - int log2_zonesz = (GRUB_MINIX_LOG2_BSIZE - + grub_minix_to_cpu16 (data->sblock.log2_zone_size)); - return (((grub_disk_addr_t) zone) << log2_zonesz); -} -#endif - - - /* Read the block pointer in ZONE, on the offset NUM. */ -static grub_minix_uintn_t -grub_get_indir (struct grub_minix_data *data, - grub_minix_uintn_t zone, - grub_minix_uintn_t num) -{ - grub_minix_uintn_t indirn; - grub_disk_read (data->disk, - grub_minix_zone2sect(data, zone), - sizeof (grub_minix_uintn_t) * num, - sizeof (grub_minix_uintn_t), (char *) &indirn); - return grub_minix_to_cpu_n (indirn); -} - -static grub_minix_uintn_t -grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) -{ - grub_minix_uintn_t indir; - - /* Direct block. */ - if (blk < GRUB_MINIX_INODE_DIR_BLOCKS) - return GRUB_MINIX_INODE_DIR_ZONES (data, blk); - - /* Indirect block. */ - blk -= GRUB_MINIX_INODE_DIR_BLOCKS; - if (blk < data->block_per_zone) - { - indir = grub_get_indir (data, GRUB_MINIX_INODE_INDIR_ZONE (data), blk); - return indir; - } - - /* Double indirect block. */ - blk -= data->block_per_zone; - if (blk < (grub_uint64_t) data->block_per_zone * (grub_uint64_t) data->block_per_zone) - { - indir = grub_get_indir (data, GRUB_MINIX_INODE_DINDIR_ZONE (data), - blk / data->block_per_zone); - - indir = grub_get_indir (data, indir, blk % data->block_per_zone); - - return indir; - } - -#if defined (MODE_MINIX3) || defined (MODE_MINIX2) - blk -= data->block_per_zone * data->block_per_zone; - if (blk < ((grub_uint64_t) data->block_per_zone * (grub_uint64_t) data->block_per_zone - * (grub_uint64_t) data->block_per_zone)) - { - indir = grub_get_indir (data, grub_minix_to_cpu_n (data->inode.triple_indir_zone), - (blk / data->block_per_zone) / data->block_per_zone); - indir = grub_get_indir (data, indir, (blk / data->block_per_zone) % data->block_per_zone); - indir = grub_get_indir (data, indir, blk % data->block_per_zone); - - return indir; - } -#endif - - /* 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, - grub_disk_read_hook_t read_hook, void *read_hook_data, - grub_off_t pos, grub_size_t len, char *buf) -{ - grub_uint32_t i; - grub_uint32_t blockcnt; - grub_uint32_t posblock; - grub_uint32_t blockoff; - - if (pos > GRUB_MINIX_INODE_SIZE (data)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("attempt to read past the end of file")); - return -1; - } - - /* 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; - if (len == 0) - return 0; - - /* Files are at most 2G/4G - 1 bytes on minixfs. Avoid 64-bit division. */ - blockcnt = ((grub_uint32_t) ((len + pos - 1) - >> GRUB_DISK_SECTOR_BITS)) / data->block_size + 1; - posblock = (((grub_uint32_t) pos) - / (data->block_size << GRUB_DISK_SECTOR_BITS)); - blockoff = (((grub_uint32_t) pos) - % (data->block_size << GRUB_DISK_SECTOR_BITS)); - - for (i = posblock; i < blockcnt; i++) - { - grub_minix_uintn_t blknr; - grub_uint64_t blockend = data->block_size << GRUB_DISK_SECTOR_BITS; - grub_off_t skipfirst = 0; - - blknr = grub_minix_get_file_block (data, i); - if (grub_errno) - return -1; - - /* Last block. */ - if (i == blockcnt - 1) - { - /* len + pos < 4G (checked above), so it doesn't overflow. */ - blockend = (((grub_uint32_t) (len + pos)) - % (data->block_size << GRUB_DISK_SECTOR_BITS)); - - if (!blockend) - blockend = data->block_size << GRUB_DISK_SECTOR_BITS; - } - - /* First block. */ - if (i == posblock) - { - skipfirst = blockoff; - blockend -= skipfirst; - } - - data->disk->read_hook = read_hook; - data->disk->read_hook_data = read_hook_data; - grub_disk_read (data->disk, - grub_minix_zone2sect(data, blknr), - skipfirst, blockend, buf); - data->disk->read_hook = 0; - if (grub_errno) - return -1; - - buf += (data->block_size << GRUB_DISK_SECTOR_BITS) - 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, grub_minix_ino_t ino) -{ - struct grub_minix_sblock *sblock = &data->sblock; - - /* Block in which the inode is stored. */ - grub_disk_addr_t block; - data->ino = ino; - - /* The first inode in minix is inode 1. */ - ino--; - block = grub_minix_zone2sect (data, - 2 + grub_minix_to_cpu16 (sblock->inode_bmap_size) - + grub_minix_to_cpu16 (sblock->zone_bmap_size)); - 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); - - 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, grub_minix_ino_t ino) -{ - char *symlink; - grub_size_t sz = GRUB_MINIX_INODE_SIZE (data); - - if (++data->linknest > GRUB_MINIX_MAX_SYMLNK_CNT) - return grub_error (GRUB_ERR_SYMLINK_LOOP, N_("too deep nesting of symlinks")); - - symlink = grub_malloc (sz + 1); - if (!symlink) - return grub_errno; - if (grub_minix_read_file (data, 0, 0, 0, sz, symlink) < 0) - goto fail; - - symlink[sz] = '\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)) - goto fail; - - grub_minix_find_file (data, symlink); - - fail: - grub_free(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) -{ - const char *name; - const char *next = path; - unsigned int pos = 0; - grub_minix_ino_t dirino; - - while (1) - { - name = next; - /* Skip the first slash. */ - while (*name == '/') - name++; - if (!*name) - return GRUB_ERR_NONE; - - if ((GRUB_MINIX_INODE_MODE (data) - & GRUB_MINIX_IFDIR) != GRUB_MINIX_IFDIR) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); - - /* Extract the actual part from the pathname. */ - for (next = name; *next && *next != '/'; next++); - - for (pos = 0; ; ) - { - grub_minix_ino_t ino; - char filename[MAX_MINIX_FILENAME_SIZE + 1]; - - if (pos >= GRUB_MINIX_INODE_SIZE (data)) - { - grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path); - return grub_errno; - } - - if (grub_minix_read_file (data, 0, 0, pos, sizeof (ino), - (char *) &ino) < 0) - return grub_errno; - if (grub_minix_read_file (data, 0, 0, pos + sizeof (ino), - data->filename_size, (char *) filename)< 0) - return grub_errno; - - pos += sizeof (ino) + data->filename_size; - - filename[data->filename_size] = '\0'; - - /* Check if the current direntry matches the current part of the - pathname. */ - if (grub_strncmp (name, filename, next - name) == 0 - && filename[next - name] == '\0') - { - dirino = data->ino; - grub_minix_read_inode (data, grub_minix_to_cpu_ino (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; - } - - break; - } - } - } -} - - -/* Mount the filesystem on the disk DISK. */ -static struct grub_minix_data * -grub_minix_mount (grub_disk_t disk) -{ - struct grub_minix_data *data = NULL; - grub_uint16_t ext2_marker; - - grub_disk_read (disk, 2, 56, sizeof (ext2_marker), &ext2_marker); - if (grub_errno != GRUB_ERR_NONE) - goto fail; - - /* - * The ext2 filesystems can sometimes be mistakenly identified as MINIX, e.g. - * due to the number of free ext2 inodes being written to the same location - * where the MINIX superblock magic is found. Avoid such situations by - * skipping any filesystems that have the ext2 superblock magic. - */ - if (ext2_marker == grub_cpu_to_le16_compile_time (EXT2_MAGIC)) - goto fail; - - 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 (data->sblock.magic == grub_cpu_to_minix16_compile_time (GRUB_MINIX_MAGIC)) - { -#if !defined(MODE_MINIX3) - data->filename_size = 14; -#else - data->filename_size = 60; -#endif - } -#if !defined(MODE_MINIX3) - else if (data->sblock.magic - == grub_cpu_to_minix16_compile_time (GRUB_MINIX_MAGIC_30)) - data->filename_size = 30; -#endif - else - goto fail; - - /* 20 means 1G zones. We could support up to 31 but already 1G isn't - supported by anything else. */ - if (grub_minix_to_cpu16 (data->sblock.log2_zone_size) >= 20) - goto fail; - - data->disk = disk; - data->linknest = 0; -#ifdef MODE_MINIX3 - /* These tests are endian-independent. No need to byteswap. */ - if (data->sblock.block_size == 0xffff) - data->block_size = 2; - else - { - if ((data->sblock.block_size == grub_cpu_to_minix16_compile_time (0x200)) - || (data->sblock.block_size == 0) - || (data->sblock.block_size & grub_cpu_to_minix16_compile_time (0x1ff))) - goto fail; - data->block_size = grub_minix_to_cpu16 (data->sblock.block_size) - >> GRUB_DISK_SECTOR_BITS; - } -#else - data->block_size = 2; -#endif - - data->block_per_zone = (((grub_uint64_t) data->block_size << \ - (GRUB_DISK_SECTOR_BITS + grub_minix_to_cpu16 (data->sblock.log2_zone_size))) - / sizeof (grub_minix_uintn_t)); - if (!data->block_per_zone) - goto fail; - - return data; - - fail: - grub_free (data); -#if defined(MODE_MINIX3) - grub_error (GRUB_ERR_BAD_FS, "not a minix3 filesystem"); -#elif defined(MODE_MINIX2) - grub_error (GRUB_ERR_BAD_FS, "not a minix2 filesystem"); -#else - grub_error (GRUB_ERR_BAD_FS, "not a minix filesystem"); -#endif - return 0; -} - -static grub_err_t -grub_minix_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_minix_data *data = 0; - 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; - - 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, N_("not a directory")); - goto fail; - } - - while (pos < GRUB_MINIX_INODE_SIZE (data)) - { - grub_minix_ino_t ino; - char filename[MAX_MINIX_FILENAME_SIZE + 1]; - grub_minix_ino_t dirino = data->ino; - struct grub_dirhook_info info; - grub_memset (&info, 0, sizeof (info)); - - - if (grub_minix_read_file (data, 0, 0, pos, sizeof (ino), - (char *) &ino) < 0) - return grub_errno; - - if (grub_minix_read_file (data, 0, 0, pos + sizeof (ino), - data->filename_size, - (char *) filename) < 0) - return grub_errno; - filename[data->filename_size] = '\0'; - if (!ino) - { - pos += sizeof (ino) + data->filename_size; - continue; - } - - grub_minix_read_inode (data, grub_minix_to_cpu_ino (ino)); - info.dir = ((GRUB_MINIX_INODE_MODE (data) - & GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR); - info.mtimeset = 1; - info.mtime = grub_minix_to_cpu32 (data->inode.mtime); - - if (hook (filename, &info, hook_data) ? 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, N_("invalid file name `%s'"), name); - 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->read_hook_data, - file->offset, len, buf); -} - - -static grub_err_t -grub_minix_close (grub_file_t file) -{ - grub_free (file->data); - - return GRUB_ERR_NONE; -} - - - -static struct grub_fs grub_minix_fs = - { -#ifdef MODE_BIGENDIAN -#if defined(MODE_MINIX3) - .name = "minix3_be", -#elif defined(MODE_MINIX2) - .name = "minix2_be", -#else - .name = "minix_be", -#endif -#else -#if defined(MODE_MINIX3) - .name = "minix3", -#elif defined(MODE_MINIX2) - .name = "minix2", -#else - .name = "minix", -#endif -#endif - .fs_dir = grub_minix_dir, - .fs_open = grub_minix_open, - .fs_read = grub_minix_read, - .fs_close = grub_minix_close, -#ifdef GRUB_UTIL - .reserved_first_sector = 1, - .blocklist_install = 1, -#endif - .next = 0 - }; - -#ifdef MODE_BIGENDIAN -#if defined(MODE_MINIX3) -GRUB_MOD_INIT(minix3_be) -#elif defined(MODE_MINIX2) -GRUB_MOD_INIT(minix2_be) -#else -GRUB_MOD_INIT(minix_be) -#endif -#else -#if defined(MODE_MINIX3) -GRUB_MOD_INIT(minix3) -#elif defined(MODE_MINIX2) -GRUB_MOD_INIT(minix2) -#else -GRUB_MOD_INIT(minix) -#endif -#endif -{ - if (!grub_is_lockdown ()) - { - grub_minix_fs.mod = mod; - grub_fs_register (&grub_minix_fs); - } - my_mod = mod; -} - -#ifdef MODE_BIGENDIAN -#if defined(MODE_MINIX3) -GRUB_MOD_FINI(minix3_be) -#elif defined(MODE_MINIX2) -GRUB_MOD_FINI(minix2_be) -#else -GRUB_MOD_FINI(minix_be) -#endif -#else -#if defined(MODE_MINIX3) -GRUB_MOD_FINI(minix3) -#elif defined(MODE_MINIX2) -GRUB_MOD_FINI(minix2) -#else -GRUB_MOD_FINI(minix) -#endif -#endif -{ - if (!grub_is_lockdown ()) - grub_fs_unregister (&grub_minix_fs); -} diff --git a/grub-core/fs/minix2.c b/grub-core/fs/minix2.c deleted file mode 100644 index 0fcd4b139..000000000 --- a/grub-core/fs/minix2.c +++ /dev/null @@ -1,2 +0,0 @@ -#define MODE_MINIX2 1 -#include "minix.c" diff --git a/grub-core/fs/minix2_be.c b/grub-core/fs/minix2_be.c deleted file mode 100644 index cb786df1c..000000000 --- a/grub-core/fs/minix2_be.c +++ /dev/null @@ -1,3 +0,0 @@ -#define MODE_MINIX2 1 -#define MODE_BIGENDIAN 1 -#include "minix.c" diff --git a/grub-core/fs/minix3.c b/grub-core/fs/minix3.c deleted file mode 100644 index 58a21d2b5..000000000 --- a/grub-core/fs/minix3.c +++ /dev/null @@ -1,2 +0,0 @@ -#define MODE_MINIX3 1 -#include "minix.c" diff --git a/grub-core/fs/minix3_be.c b/grub-core/fs/minix3_be.c deleted file mode 100644 index d0305e4ff..000000000 --- a/grub-core/fs/minix3_be.c +++ /dev/null @@ -1,3 +0,0 @@ -#define MODE_MINIX3 1 -#define MODE_BIGENDIAN 1 -#include "minix.c" diff --git a/grub-core/fs/minix_be.c b/grub-core/fs/minix_be.c deleted file mode 100644 index fade347d6..000000000 --- a/grub-core/fs/minix_be.c +++ /dev/null @@ -1,2 +0,0 @@ -#define MODE_BIGENDIAN 1 -#include "minix.c" diff --git a/grub-core/fs/newc.c b/grub-core/fs/newc.c deleted file mode 100644 index 43b7f8b64..000000000 --- a/grub-core/fs/newc.c +++ /dev/null @@ -1,74 +0,0 @@ -/* cpio.c - cpio and tar filesystem. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007,2008,2009,2013 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 . - */ - -#include - -#define ALIGN_CPIO(x) (ALIGN_UP ((x), 4)) -#define MAGIC "070701" -#define MAGIC2 "070702" -struct head -{ - char magic[6]; - char ino[8]; - char mode[8]; - char uid[8]; - char gid[8]; - char nlink[8]; - char mtime[8]; - char filesize[8]; - char devmajor[8]; - char devminor[8]; - char rdevmajor[8]; - char rdevminor[8]; - char namesize[8]; - char check[8]; -} GRUB_PACKED; - -static inline unsigned long long -read_number (const char *str, grub_size_t size) -{ - unsigned long long ret = 0; - while (size-- && grub_isxdigit (*str)) - { - char dig = *str++; - if (dig >= '0' && dig <= '9') - dig &= 0xf; - else if (dig >= 'a' && dig <= 'f') - dig -= 'a' - 10; - else - dig -= 'A' - 10; - ret = (ret << 4) | (dig); - } - return ret; -} - -#define FSNAME "newc" - -#include "cpio_common.c" - -GRUB_MOD_INIT (newc) -{ - grub_cpio_fs.mod = mod; - grub_fs_register (&grub_cpio_fs); -} - -GRUB_MOD_FINI (newc) -{ - grub_fs_unregister (&grub_cpio_fs); -} diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c deleted file mode 100644 index 26e6077ff..000000000 --- a/grub-core/fs/nilfs2.c +++ /dev/null @@ -1,1247 +0,0 @@ -/* - * nilfs2.c - New Implementation of Log filesystem - * - * Written by Jiro SEKIBA - * - * 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 . - */ - - -/* 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 -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#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) - -/* nilfs 1st super block posission from beginning of the partition - in 512 block size */ -#define NILFS_1ST_SUPER_BLOCK 2 -/* nilfs 2nd super block posission from beginning of the partition - in 512 block size */ -#define NILFS_2ND_SUPER_BLOCK(devsize) (((devsize >> 3) - 1) << 3) - -#define LOG_INODE_SIZE 7 -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[80]; - 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; -#define MAX_NAMELEN 255 - grub_uint8_t name_len; - grub_uint8_t file_type; -#if 0 /* followed by file name. */ - char name[NILFS_NAME_LEN]; - char pad; -#endif -} GRUB_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; - grub_uint64_t keys[0]; -}; - -struct grub_nilfs2_palloc_group_desc -{ - grub_uint32_t pg_nfrees; -}; - -#define LOG_SIZE_GROUP_DESC 2 - -#define LOG_NILFS_DAT_ENTRY_SIZE 5 -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; - - - -static inline unsigned long -grub_nilfs2_log_palloc_entries_per_group (struct grub_nilfs2_data *data) -{ - return LOG2_BLOCK_SIZE (data) + 3; -} - -static inline grub_uint64_t -grub_nilfs2_palloc_group (struct grub_nilfs2_data *data, - grub_uint64_t nr, grub_uint64_t * offset) -{ - *offset = nr & ((1 << grub_nilfs2_log_palloc_entries_per_group (data)) - 1); - return nr >> grub_nilfs2_log_palloc_entries_per_group (data); -} - -static inline grub_uint32_t -grub_nilfs2_palloc_log_groups_per_desc_block (struct grub_nilfs2_data *data) -{ - return LOG2_BLOCK_SIZE (data) - LOG_SIZE_GROUP_DESC; - - COMPILE_TIME_ASSERT (sizeof (struct grub_nilfs2_palloc_group_desc) - == (1 << LOG_SIZE_GROUP_DESC)); -} - -static inline grub_uint32_t -grub_nilfs2_log_entries_per_block_log (struct grub_nilfs2_data *data, - unsigned long log_entry_size) -{ - return LOG2_BLOCK_SIZE (data) - log_entry_size; -} - - -static inline grub_uint32_t -grub_nilfs2_blocks_per_group_log (struct grub_nilfs2_data *data, - unsigned long log_entry_size) -{ - return (1 << (grub_nilfs2_log_palloc_entries_per_group (data) - - grub_nilfs2_log_entries_per_block_log (data, - log_entry_size))) + 1; -} - -static inline grub_uint32_t -grub_nilfs2_blocks_per_desc_block_log (struct grub_nilfs2_data *data, - unsigned long log_entry_size) -{ - return(grub_nilfs2_blocks_per_group_log (data, log_entry_size) - << grub_nilfs2_palloc_log_groups_per_desc_block (data)) + 1; -} - -static inline grub_uint32_t -grub_nilfs2_palloc_desc_block_offset_log (struct grub_nilfs2_data *data, - unsigned long group, - unsigned long log_entry_size) -{ - grub_uint32_t desc_block = - group >> grub_nilfs2_palloc_log_groups_per_desc_block (data); - return desc_block * grub_nilfs2_blocks_per_desc_block_log (data, - log_entry_size); -} - -static inline grub_uint32_t -grub_nilfs2_palloc_bitmap_block_offset (struct grub_nilfs2_data *data, - unsigned long group, - unsigned long log_entry_size) -{ - unsigned long desc_offset = group - & ((1 << grub_nilfs2_palloc_log_groups_per_desc_block (data)) - 1); - - return grub_nilfs2_palloc_desc_block_offset_log (data, group, log_entry_size) - + 1 - + desc_offset * grub_nilfs2_blocks_per_group_log (data, log_entry_size); -} - -static inline grub_uint32_t -grub_nilfs2_palloc_entry_offset_log (struct grub_nilfs2_data *data, - grub_uint64_t nr, - unsigned long log_entry_size) -{ - unsigned long group; - grub_uint64_t group_offset; - - group = grub_nilfs2_palloc_group (data, nr, &group_offset); - - return grub_nilfs2_palloc_bitmap_block_offset (data, group, - log_entry_size) + 1 + - (group_offset >> grub_nilfs2_log_entries_per_block_log (data, - log_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 (node->keys + - ((node->bn_flags & NILFS_BTREE_NODE_ROOT) ? - 0 : (NILFS_BTREE_NODE_EXTRA_PAD_SIZE / sizeof (grub_uint64_t)))); -} - -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_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 int -grub_nilfs2_btree_node_lookup (struct grub_nilfs2_data *data, - struct grub_nilfs2_btree_node *node, - grub_uint64_t key, int *indexp) -{ - grub_uint64_t nkey; - int index = 0, low, high, s; - - low = 0; - - high = grub_le_to_cpu16 (node->bn_nchildren) - 1; - if (high >= grub_nilfs2_btree_node_nchildren_max (data, node)) - { - grub_error (GRUB_ERR_BAD_FS, "too many children"); - *indexp = index; - return 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 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; - void *block; - grub_uint64_t ptr; - int level, found = 0, index; - - block = grub_malloc (NILFS2_BLOCK_SIZE (data)); - if (!block) - return -1; - - node = grub_nilfs2_btree_get_root (inode); - level = grub_nilfs2_btree_get_level (node); - - found = grub_nilfs2_btree_node_lookup (data, node, key, &index); - - if (grub_errno != GRUB_ERR_NONE) - goto fail; - - 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) - { - goto fail; - } - node = (struct grub_nilfs2_btree_node *) block; - - if (node->bn_level != level) - { - grub_error (GRUB_ERR_BAD_FS, "btree level mismatch\n"); - goto fail; - } - - if (!found) - found = grub_nilfs2_btree_node_lookup (data, node, key, &index); - else - index = 0; - - if (index < grub_nilfs2_btree_node_nchildren_max (data, node) && - grub_errno == GRUB_ERR_NONE) - { - 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"); - goto fail; - } - } - - grub_free (block); - - if (!found) - return -1; - - return ptr; - fail: - grub_free (block); - return -1; -} - -static inline grub_uint64_t -grub_nilfs2_direct_lookup (struct grub_nilfs2_inode *inode, grub_uint64_t key) -{ - if (1 + key > 6) - { - grub_error (GRUB_ERR_BAD_FS, "key is too large"); - return 0xffffffffffffffff; - } - 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 (ptr != ((grub_uint64_t) 0xffffffffffffffff) && 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_uint64_t blockno, offset; - unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); - - blockno = grub_nilfs2_palloc_entry_offset_log (data, key, - LOG_NILFS_DAT_ENTRY_SIZE); - - offset = ((key * sizeof (struct grub_nilfs2_dat_entry)) - & ((1 << LOG2_BLOCK_SIZE (data)) - 1)); - - 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, - grub_disk_read_hook_t read_hook, void *read_hook_data, - grub_off_t pos, grub_size_t len, char *buf) -{ - return grub_fshelp_read_file (node->data->disk, node, - read_hook, read_hook_data, - pos, len, buf, grub_nilfs2_read_block, - grub_le_to_cpu64 (node->inode.i_size), - LOG2_NILFS2_BLOCK_SIZE (node->data), 0); - -} - -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_uint64_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; - grub_uint64_t 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_log (data, ino, - LOG_INODE_SIZE); - - offset = ((sizeof (struct grub_nilfs2_inode) * ino) - & ((1 << LOG2_BLOCK_SIZE (data)) - 1)); - 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; - - /* 20 already means 1GiB blocks. We don't want to deal with blocks overflowing int32. */ - if (grub_le_to_cpu32 (sbp->s_log_block_size) > 20) - return 0; - - return 1; -} - -static grub_err_t -grub_nilfs2_load_sb (struct grub_nilfs2_data *data) -{ - grub_disk_t disk = data->disk; - struct grub_nilfs2_super_block sb2; - grub_uint64_t partition_size; - int valid[2]; - int swp = 0; - grub_err_t err; - - /* Read first super block. */ - err = grub_disk_read (disk, NILFS_1ST_SUPER_BLOCK, 0, - sizeof (struct grub_nilfs2_super_block), &data->sblock); - if (err) - return err; - /* Make sure if 1st super block is valid. */ - valid[0] = grub_nilfs2_valid_sb (&data->sblock); - - if (valid[0]) - partition_size = (grub_le_to_cpu64 (data->sblock.s_dev_size) - >> GRUB_DISK_SECTOR_BITS); - else - partition_size = grub_disk_native_sectors (disk); - if (partition_size != GRUB_DISK_SIZE_UNKNOWN) - { - /* Read second super block. */ - err = grub_disk_read (disk, NILFS_2ND_SUPER_BLOCK (partition_size), 0, - sizeof (struct grub_nilfs2_super_block), &sb2); - if (err) - { - valid[1] = 0; - grub_errno = GRUB_ERR_NONE; - } - else - /* Make sure if 2nd super block is valid. */ - valid[1] = grub_nilfs2_valid_sb (&sb2); - } - else - /* 2nd super block may not exist, so it's invalid. */ - valid[1] = 0; - - if (!valid[0] && !valid[1]) - return grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); - - swp = valid[1] && (!valid[0] || - grub_le_to_cpu64 (data->sblock.s_last_cno) < - grub_le_to_cpu64 (sb2.s_last_cno)); - - /* swap if first super block is invalid or older than second one. */ - if (swp) - grub_memcpy (&data->sblock, &sb2, - sizeof (struct grub_nilfs2_super_block)); - - return GRUB_ERR_NONE; -} - -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; - - data->disk = disk; - - /* Read the superblock. */ - grub_nilfs2_load_sb (data); - if (grub_errno) - 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; - - 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, 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, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data) -{ - grub_off_t 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, 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[MAX_NAMELEN + 1]; - struct grub_fshelp_node *fdiro; - enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; - - grub_nilfs2_read_file (diro, 0, 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, hook_data)) - 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->read_hook_data, - file->offset, len, buf); -} - -/* Context for grub_nilfs2_dir. */ -struct grub_nilfs2_dir_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; - struct grub_nilfs2_data *data; -}; - -/* Helper for grub_nilfs2_dir. */ -static int -grub_nilfs2_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, void *data) -{ - struct grub_nilfs2_dir_ctx *ctx = data; - struct grub_dirhook_info info; - - grub_memset (&info, 0, sizeof (info)); - if (!node->inode_read) - { - grub_nilfs2_read_inode (ctx->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 ctx->hook (filename, &info, ctx->hook_data); -} - -static grub_err_t -grub_nilfs2_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_nilfs2_dir_ctx ctx = { - .hook = hook, - .hook_data = hook_data - }; - struct grub_fshelp_node *fdiro = 0; - - grub_dl_ref (my_mod); - - ctx.data = grub_nilfs2_mount (device->disk); - if (!ctx.data) - goto fail; - - grub_fshelp_find_file (path, &ctx.data->diropen, &fdiro, - grub_nilfs2_iterate_dir, grub_nilfs2_read_symlink, - GRUB_FSHELP_DIR); - if (grub_errno) - goto fail; - - grub_nilfs2_iterate_dir (fdiro, grub_nilfs2_dir_iter, &ctx); - -fail: - if (fdiro != &ctx.data->diropen) - grub_free (fdiro); - grub_free (ctx.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, - sizeof (data->sblock.s_volume_name)); - 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%02x-%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_int64_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_wtime); - - grub_dl_unref (my_mod); - - grub_free (data); - - return grub_errno; -} - - - -static struct grub_fs grub_nilfs2_fs = { - .name = "nilfs2", - .fs_dir = grub_nilfs2_dir, - .fs_open = grub_nilfs2_open, - .fs_read = grub_nilfs2_read, - .fs_close = grub_nilfs2_close, - .fs_label = grub_nilfs2_label, - .fs_uuid = grub_nilfs2_uuid, - .fs_mtime = grub_nilfs2_mtime, -#ifdef GRUB_UTIL - .reserved_first_sector = 1, - .blocklist_install = 0, -#endif - .next = 0 -}; - -GRUB_MOD_INIT (nilfs2) -{ - COMPILE_TIME_ASSERT ((1 << LOG_NILFS_DAT_ENTRY_SIZE) - == sizeof (struct - grub_nilfs2_dat_entry)); - COMPILE_TIME_ASSERT (1 << LOG_INODE_SIZE - == sizeof (struct grub_nilfs2_inode)); - if (!grub_is_lockdown ()) - { - grub_nilfs2_fs.mod = mod; - grub_fs_register (&grub_nilfs2_fs); - } - my_mod = mod; -} - -GRUB_MOD_FINI (nilfs2) -{ - if (!grub_is_lockdown ()) - grub_fs_unregister (&grub_nilfs2_fs); -} diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c deleted file mode 100644 index 5b0a18f3d..000000000 --- a/grub-core/fs/ntfs.c +++ /dev/null @@ -1,1666 +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 . - */ - -#define grub_fshelp_node grub_ntfs_file - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_dl_t my_mod; - -#define grub_fshelp_node grub_ntfs_file - -static inline grub_uint16_t -u16at (void *ptr, grub_size_t ofs) -{ - return grub_le_to_cpu16 (grub_get_unaligned16 ((char *) ptr + ofs)); -} - -static inline grub_uint32_t -u32at (void *ptr, grub_size_t ofs) -{ - return grub_le_to_cpu32 (grub_get_unaligned32 ((char *) ptr + ofs)); -} - -static inline grub_uint64_t -u64at (void *ptr, grub_size_t ofs) -{ - return grub_le_to_cpu64 (grub_get_unaligned64 ((char *) ptr + ofs)); -} - -static grub_uint16_t -first_attr_off (void *mft_buf_ptr) -{ - return u16at (mft_buf_ptr, 0x14); -} - -static grub_uint16_t -res_attr_data_off (void *res_attr_ptr) -{ - return u16at (res_attr_ptr, 0x14); -} - -static grub_uint32_t -res_attr_data_len (void *res_attr_ptr) -{ - return u32at (res_attr_ptr, 0x10); -} - -/* - * Check if the attribute is valid and doesn't exceed the allocated region. - * This accounts for resident and non-resident data. - * - * This is based off the documentation from the linux-ntfs project: - * https://flatcap.github.io/linux-ntfs/ntfs/concepts/attribute_header.html - */ -static bool -validate_attribute (grub_uint8_t *attr, void *end) -{ - grub_size_t attr_size = 0; - grub_size_t min_size = 0; - grub_size_t run_size = 0; - grub_size_t spare = (grub_uint8_t *) end - attr; - /* - * Just used as a temporary variable to try and deal with cases where someone - * tries to overlap fields. - */ - grub_size_t curr = 0; - - /* Need verify we can entirely read the attributes header. */ - if (attr + GRUB_NTFS_ATTRIBUTE_HEADER_SIZE >= (grub_uint8_t *) end) - goto fail; - - /* - * So, the rest of this code uses a 16bit int for the attribute length but - * from reading the all the documentation I could find it says this field is - * actually 32bit. But let's be consistent with the rest of the code. - * - * https://elixir.bootlin.com/linux/v6.10.7/source/fs/ntfs3/ntfs.h#L370 - */ - attr_size = u16at (attr, GRUB_NTFS_ATTRIBUTE_LENGTH); - - if (attr_size > spare) - goto fail; - - /* Not an error case, just reached the end of the attributes. */ - if (attr_size == 0) - return false; - - /* - * Extra validation by trying to calculate a minimum possible size for this - * attribute. +8 from the size of the resident data struct which is the - * minimum that can be added. - */ - min_size = GRUB_NTFS_ATTRIBUTE_HEADER_SIZE + 8; - - if (min_size > attr_size) - goto fail; - - /* Is the data is resident (0) or not (1). */ - if (attr[GRUB_NTFS_ATTRIBUTE_RESIDENT] == 0) - { - /* Read the offset and size of the attribute. */ - curr = u16at (attr, GRUB_NTFS_ATTRIBUTE_RES_OFFSET); - curr += u32at (attr, GRUB_NTFS_ATTRIBUTE_RES_LENGTH); - if (curr > min_size) - min_size = curr; - } - else - { - /* - * If the data is non-resident, the minimum size is 64 which is where - * the data runs start. We already have a minimum size of 24. So, just - * adding 40 to get to the real value. - */ - min_size += 40; - if (min_size > attr_size) - goto fail; - /* If the compression unit size is > 0, +8 bytes*/ - if (u16at (attr, GRUB_NTFS_ATTRIBUTE_COMPRESSION_UNIT_SIZE) > 0) - min_size += 8; - - /* - * Need to consider the data runs now. Each member of the run has byte - * that describes the size of the data length and offset. Each being - * 4 bits in the byte. - */ - curr = u16at (attr, GRUB_NTFS_ATTRIBUTE_DATA_RUNS); - - if (curr + 1 > min_size) - min_size = curr + 1; - - if (min_size > attr_size) - goto fail; - - /* - * Each attribute can store multiple data runs which are stored - * continuously in the attribute. They exist as one header byte - * with up to 14 bytes following it depending on the lengths. - * We stop when we hit a header that is just a NUL byte. - * - * https://flatcap.github.io/linux-ntfs/ntfs/concepts/data_runs.html - */ - while (attr[curr] != 0) - { - /* - * We stop when we hit a header that is just a NUL byte. The data - * run header is stored as a single byte where the top 4 bits refer - * to the number of bytes used to store the total length of the - * data run, and the number of bytes used to store the offset. - * These directly follow the header byte, so we use them to update - * the minimum size. Increment by one more than run size to move on - * to the next run size header byte. An example is a run size field - * value of 0x32, 3 + 2 = 5 bytes follow the run size. Increment - * by 5 to get to the end of this data run then one more to get to - * the start of the next run size byte. - */ - run_size = (attr[curr] & 0x7) + ((attr[curr] >> 4) & 0x7); - curr += (run_size + 1); - min_size += (run_size + 1); - if (min_size > attr_size) - goto fail; - } - } - - /* Name offset, doing this after data residence checks. */ - if (u16at (attr, GRUB_NTFS_ATTRIBUTE_NAME_OFFSET) != 0) - { - curr = u16at (attr, GRUB_NTFS_ATTRIBUTE_NAME_OFFSET); - /* - * Multiple the name length by 2 as its UTF-16. Can be zero if this in an - * unamed attribute. - */ - curr += attr[GRUB_NTFS_ATTRIBUTE_NAME_LENGTH] * 2; - if (curr > min_size) - min_size = curr; - } - - /* Padded to 8 bytes. */ - if (min_size % 8 != 0) - min_size += 8 - (min_size % 8); - - /* - * At this point min_size should be exactly attr_size but being flexible - * here to avoid any issues. - */ - if (min_size > attr_size) - goto fail; - - return true; - - fail: - grub_dprintf ("ntfs", "spare=%" PRIuGRUB_SIZE " min_size=%" PRIuGRUB_SIZE " attr_size=%" PRIuGRUB_SIZE "\n", - spare, min_size, attr_size); - return false; -} - -/* Return the next attribute if it exists, otherwise return NULL. */ -static grub_uint8_t * -next_attribute (grub_uint8_t *curr_attribute, void *end, bool validate) -{ - grub_uint8_t *next = curr_attribute; - - /* - * Need to verify we aren't exceeding the end of the buffer by reading the - * header for the current attribute - */ - if (curr_attribute + GRUB_NTFS_ATTRIBUTE_HEADER_SIZE >= (grub_uint8_t *) end) - return NULL; - - next += u16at (curr_attribute, 4); - if (validate && validate_attribute (next, end) == false) - return NULL; - - return next; -} - - -grub_ntfscomp_func_t grub_ntfscomp_func; - -static grub_err_t -fixup (grub_uint8_t *buf, grub_size_t len, const grub_uint8_t *magic) -{ - grub_uint16_t ss; - grub_uint8_t *pu; - grub_uint16_t us; - grub_uint16_t pu_offset; - - COMPILE_TIME_ASSERT ((1 << GRUB_NTFS_BLK_SHR) == GRUB_DISK_SECTOR_SIZE); - - 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 != len) - return grub_error (GRUB_ERR_BAD_FS, "size not match"); - pu_offset = u16at (buf, 4); - if (pu_offset >= (len * GRUB_DISK_SECTOR_SIZE - (2 * ss))) - return grub_error (GRUB_ERR_BAD_FS, "pu offset size incorrect"); - pu = buf + pu_offset; - us = u16at (pu, 0); - buf -= 2; - while (ss > 0) - { - buf += GRUB_DISK_SECTOR_SIZE; - pu += 2; - if (u16at (buf, 0) != us) - return grub_error (GRUB_ERR_BAD_FS, "fixup signature not match"); - buf[0] = pu[0]; - buf[1] = pu[1]; - ss--; - } - - return 0; -} - -static grub_err_t read_mft (struct grub_ntfs_data *data, grub_uint8_t *buf, - grub_uint64_t mftno); -static grub_err_t read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, - grub_disk_addr_t ofs, grub_size_t len, - int cached, - grub_disk_read_hook_t read_hook, - void *read_hook_data); - -static grub_err_t read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, - grub_uint8_t *dest, - grub_disk_addr_t ofs, grub_size_t len, - int cached, - grub_disk_read_hook_t read_hook, - void *read_hook_data); - -static grub_err_t -init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft) -{ - at->mft = mft; - at->flags = (mft == &mft->data->mmft) ? GRUB_NTFS_AF_MMFT : 0; - at->attr_nxt = mft->buf + first_attr_off (mft->buf); - at->end = mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR); - - if (at->attr_nxt > at->end) - return grub_error (GRUB_ERR_BAD_FS, "attributes start outside the MFT"); - - at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL; - - return GRUB_ERR_NONE; -} - -static void -free_attr (struct grub_ntfs_attr *at) -{ - grub_free (at->emft_buf); - grub_free (at->edat_buf); - grub_free (at->sbuf); -} - -static grub_uint8_t * -find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) -{ - grub_uint8_t *mft_end; - grub_uint16_t nsize; - grub_uint16_t nxt_offset; - grub_uint32_t edat_offset; - - /* GRUB_NTFS_AF_ALST indicates the attribute list type */ - if (at->flags & GRUB_NTFS_AF_ALST) - { - retry: - while (at->attr_nxt) - { - at->attr_cur = at->attr_nxt; - /* - * Go to the next attribute in the list but do not validate - * because this is the attribute list type. - */ - at->attr_nxt = next_attribute (at->attr_cur, at->attr_end, false); - if ((*at->attr_cur == attr) || (attr == 0)) - { - grub_uint8_t *new_pos, *end; - - if (at->flags & GRUB_NTFS_AF_MMFT) - { - if ((grub_disk_read - (at->mft->data->disk, u32at (at->attr_cur, 0x10), 0, - 512, at->emft_buf)) - || - (grub_disk_read - (at->mft->data->disk, u32at (at->attr_cur, 0x14), 0, - 512, at->emft_buf + 512))) - return NULL; - - if (fixup (at->emft_buf, at->mft->data->mft_size, - (const grub_uint8_t *) "FILE")) - return NULL; - } - else - { - if (read_mft (at->mft->data, at->emft_buf, - u32at (at->attr_cur, 0x10))) - return NULL; - } - - /* - * Only time emft_bufs is defined is in this function, with this - * size. - */ - grub_size_t emft_buf_size = - at->mft->data->mft_size << GRUB_NTFS_BLK_SHR; - - /* - * Needs to be enough space for the successful case to even - * bother. - */ - if (first_attr_off (at->emft_buf) >= (emft_buf_size - 0x18 - 2)) - { - grub_error (GRUB_ERR_BAD_FS, - "can\'t find 0x%X in attribute list", - (unsigned char) *at->attr_cur); - return NULL; - } - - new_pos = &at->emft_buf[first_attr_off (at->emft_buf)]; - end = &at->emft_buf[emft_buf_size]; - at->end = end; - - while (new_pos && *new_pos != 0xFF) - { - if ((*new_pos == *at->attr_cur) - && (u16at (new_pos, 0xE) == u16at (at->attr_cur, 0x18))) - { - return new_pos; - } - /* - * Go to the next attribute in the list but do not validate - * because this is the attribute list type. - */ - new_pos = next_attribute (new_pos, end, false); - } - 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; - mft_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR); - while (at->attr_cur >= at->mft->buf && at->attr_cur < (mft_end - 4) - && *at->attr_cur != 0xFF) - { - /* - * We can't use validate_attribute here because this logic - * seems to be used for both parsing through attributes - * and attribute lists. - */ - nsize = u16at (at->attr_cur, 4); - if (at->attr_cur + grub_max (GRUB_NTFS_ATTRIBUTE_HEADER_SIZE, nsize) >= at->end) - { - at->attr_nxt = at->attr_cur; - break; - } - else - at->attr_nxt = at->attr_cur + nsize; - - if (*at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST) - at->attr_end = at->attr_cur; - if ((*at->attr_cur == attr) || (attr == 0) || (nsize == 0)) - return at->attr_cur; - at->attr_cur = at->attr_nxt; - } - if (at->attr_end) - { - grub_uint8_t *pa, *pa_end; - - at->emft_buf = grub_malloc (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR); - if (at->emft_buf == NULL) - return NULL; - - pa = at->attr_end; - if (pa[8]) - { - grub_uint32_t 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, 0)) - { - grub_error (GRUB_ERR_BAD_FS, - "fail to read non-resident attribute list"); - return NULL; - } - at->attr_nxt = at->edat_buf; - edat_offset = u32at (pa, 0x30); - if (edat_offset >= n) - { - grub_error (GRUB_ERR_BAD_FS, "edat offset is out of bounds"); - return NULL; - } - at->attr_end = at->edat_buf + edat_offset; - pa_end = at->edat_buf + n; - } - else - { - at->attr_nxt = at->attr_end + res_attr_data_off (pa); - edat_offset = u32at (pa, 4); - if ((at->attr_end + edat_offset) >= (at->end)) - { - grub_error (GRUB_ERR_BAD_FS, "edat offset is out of bounds"); - return NULL; - } - at->attr_end = at->attr_end + edat_offset; - pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR); - } - at->flags |= GRUB_NTFS_AF_ALST; - - /* From this point on pa_end is the end of the buffer */ - at->end = pa_end; - - if (at->attr_end >= pa_end || at->attr_nxt >= pa_end) - return NULL; - - while (at->attr_nxt) - { - if ((*at->attr_nxt == attr) || (attr == 0)) - break; - - nxt_offset = u16at (at->attr_nxt, 4); - at->attr_nxt += nxt_offset; - - /* - * Stop and set attr_nxt to NULL when either the next offset is zero, - * or when the pointer is within four bytes of the end of the buffer - * since we could attempt to access attr_nxt + 4 bytes offset above to - * get the next 16-bit 'nxt_offset' value. - */ - if (nxt_offset == 0 || at->attr_nxt >= (pa_end - 4)) - at->attr_nxt = NULL; - } - - if ((at->attr_nxt + GRUB_NTFS_ATTRIBUTE_HEADER_SIZE) >= at->attr_end || at->attr_nxt == NULL) - return NULL; - - if ((at->flags & GRUB_NTFS_AF_MMFT) && (attr == GRUB_NTFS_AT_DATA)) - { - at->flags |= GRUB_NTFS_AF_GPOS; - at->attr_cur = at->attr_nxt; - pa = at->attr_cur; - - if ((pa >= pa_end) || (pa_end - pa < 0x18)) - { - grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list"); - return NULL; - } - - grub_set_unaligned32 ((char *) pa + 0x10, - grub_cpu_to_le32 (at->mft->data->mft_start)); - grub_set_unaligned32 ((char *) pa + 0x14, - grub_cpu_to_le32 (at->mft->data->mft_start - + 1)); - pa = at->attr_nxt + u16at (pa, 4); - - if (pa >= pa_end) - pa = NULL; - - while (pa) - { - if (*pa != attr) - break; - - if ((pa >= pa_end) || (pa_end - pa < 0x18)) - { - grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list"); - return NULL; - } - - if (read_attr - (at, pa + 0x10, - u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR), - at->mft->data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0, 0)) - return NULL; - pa += u16at (pa, 4); - if (pa >= pa_end) - pa = NULL; - } - at->attr_nxt = at->attr_cur; - at->flags &= ~GRUB_NTFS_AF_GPOS; - } - goto retry; - } - return NULL; -} - -static grub_uint8_t * -locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft, - grub_uint8_t attr) -{ - grub_uint8_t *pa; - grub_uint8_t *last_pa; - - if (init_attr (at, mft) != GRUB_ERR_NONE) - return NULL; - - pa = find_attr (at, attr); - if (pa == NULL) - return NULL; - if ((at->flags & GRUB_NTFS_AF_ALST) == 0) - { - /* Used to make sure we're not stuck in a loop. */ - last_pa = NULL; - while (1) - { - pa = find_attr (at, attr); - if (pa == NULL || pa == last_pa) - break; - if (at->flags & GRUB_NTFS_AF_ALST) - return pa; - last_pa = pa; - } - grub_errno = GRUB_ERR_NONE; - free_attr (at); - if (init_attr (at, mft) != GRUB_ERR_NONE) - return NULL; - pa = find_attr (at, attr); - } - return pa; -} - -static grub_disk_addr_t -read_run_data (const grub_uint8_t *run, int nn, int sig) -{ - grub_uint64_t r = 0; - - if (sig && nn && (run[nn - 1] & 0x80)) - r = -1; - - grub_memcpy (&r, run, nn); - - return grub_le_to_cpu64 (r); -} - -grub_err_t -grub_ntfs_read_run_list (struct grub_ntfs_rlst * ctx) -{ - grub_uint8_t c1, c2; - grub_disk_addr_t val; - grub_uint8_t *run; - - run = ctx->cur_run; -retry: - c1 = ((*run) & 0x7); - c2 = ((*run) >> 4) & 0x7; - run++; - if (!c1) - { - if ((ctx->attr) && (ctx->attr->flags & GRUB_NTFS_AF_ALST)) - { - grub_disk_read_hook_t save_hook; - - save_hook = ctx->comp.disk->read_hook; - ctx->comp.disk->read_hook = 0; - run = find_attr (ctx->attr, *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 overflow"); - } - ctx->curr_vcn = ctx->next_vcn; - ctx->next_vcn += read_run_data (run, c1, 0); /* length of current VCN */ - run += c1; - val = read_run_data (run, c2, 1); /* offset to previous LCN */ - run += c2; - ctx->curr_lcn += val; - if (val == 0) - ctx->flags |= GRUB_NTFS_RF_BLNK; - else - ctx->flags &= ~GRUB_NTFS_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 & GRUB_NTFS_RF_BLNK) ? 0 : (block - - ctx->curr_vcn + ctx->curr_lcn); -} - -static grub_err_t -read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest, - grub_disk_addr_t ofs, grub_size_t len, int cached, - grub_disk_read_hook_t read_hook, void *read_hook_data) -{ - struct grub_ntfs_rlst cc, *ctx; - grub_uint8_t *end_ptr = (pa + len); - grub_uint16_t run_offset; - - if (len == 0) - return 0; - - grub_memset (&cc, 0, sizeof (cc)); - ctx = &cc; - ctx->attr = at; - ctx->comp.log_spc = at->mft->data->log_spc; - ctx->comp.disk = at->mft->data->disk; - - if (read_hook == grub_file_progress_hook) - ctx->file = read_hook_data; - - if (pa[8] == 0) - { - if (ofs + len > res_attr_data_len (pa)) - return grub_error (GRUB_ERR_BAD_FS, "read out of range"); - - if (res_attr_data_len (pa) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR)) - return grub_error (GRUB_ERR_BAD_FS, "resident attribute too large"); - - if (pa >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR)) - return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range"); - - if (res_attr_data_off (pa) + res_attr_data_len (pa) > - (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) pa) - return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range"); - - grub_memcpy (dest, pa + res_attr_data_off (pa) + ofs, len); - return 0; - } - - run_offset = u16at (pa, 0x20); - if ((run_offset + pa) >= end_ptr || ((run_offset + pa) >= (at->end))) - return grub_error (GRUB_ERR_BAD_FS, "run offset out of range"); - - ctx->cur_run = pa + run_offset; - - ctx->next_vcn = u32at (pa, 0x10); - ctx->curr_lcn = 0; - - if ((pa[0xC] & GRUB_NTFS_FLAG_COMPRESSED) - && !(at->flags & GRUB_NTFS_AF_GPOS)) - { - if (!cached) - return grub_error (GRUB_ERR_BAD_FS, "attribute can\'t be compressed"); - - return (grub_ntfscomp_func) ? grub_ntfscomp_func (dest, ofs, len, ctx) - : grub_error (GRUB_ERR_BAD_FS, N_("module `%s' isn't loaded"), - "ntfscomp"); - } - - ctx->target_vcn = ofs >> (GRUB_NTFS_BLK_SHR + ctx->comp.log_spc); - while (ctx->next_vcn <= ctx->target_vcn) - { - if (grub_ntfs_read_run_list (ctx)) - return grub_errno; - } - - if (at->flags & GRUB_NTFS_AF_GPOS) - { - grub_disk_addr_t st0, st1; - grub_uint64_t m; - - m = (ofs >> GRUB_NTFS_BLK_SHR) & ((1 << ctx->comp.log_spc) - 1); - - st0 = - ((ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) << ctx->comp.log_spc) + m; - st1 = st0 + 1; - if (st1 == - (ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) << ctx->comp.log_spc) - { - if (grub_ntfs_read_run_list (ctx)) - return grub_errno; - st1 = ctx->curr_lcn << ctx->comp.log_spc; - } - grub_set_unaligned32 (dest, grub_cpu_to_le32 (st0)); - grub_set_unaligned32 (dest + 4, grub_cpu_to_le32 (st1)); - return 0; - } - - grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx, - read_hook, read_hook_data, ofs, len, - (char *) dest, - grub_ntfs_read_block, ofs + len, - ctx->comp.log_spc, 0); - return grub_errno; -} - -static grub_err_t -read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs, - grub_size_t len, int cached, - grub_disk_read_hook_t read_hook, void *read_hook_data) -{ - grub_uint8_t *save_cur; - grub_uint8_t attr; - grub_uint8_t *pp; - grub_err_t ret; - - if (at == NULL || at->attr_cur == NULL) - return grub_error (GRUB_ERR_BAD_FS, "attribute not found"); - save_cur = at->attr_cur; - at->attr_nxt = at->attr_cur; - attr = *at->attr_nxt; - if (at->flags & GRUB_NTFS_AF_ALST) - { - grub_uint8_t *pa; - grub_disk_addr_t vcn; - - /* If compression is possible make sure that we include possible - compressed block size. */ - if (GRUB_NTFS_LOG_COM_SEC >= at->mft->data->log_spc) - vcn = ((ofs >> GRUB_NTFS_COM_LOG_LEN) - << (GRUB_NTFS_LOG_COM_SEC - at->mft->data->log_spc)) & ~0xFULL; - else - vcn = ofs >> (at->mft->data->log_spc + GRUB_NTFS_BLK_SHR); - pa = at->attr_nxt + u16at (at->attr_nxt, 4); - if (validate_attribute (pa, at->attr_end) == false) - pa = NULL; - - while (pa) - { - if (*pa != attr) - break; - if (u32at (pa, 8) > vcn) - break; - at->attr_nxt = pa; - pa = next_attribute (pa, at->attr_end, true); - } - } - pp = find_attr (at, attr); - if (pp) - ret = read_data (at, pp, dest, ofs, len, cached, - read_hook, read_hook_data); - 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, grub_uint8_t *buf, grub_uint64_t mftno) -{ - if (read_attr - (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << GRUB_NTFS_BLK_SHR), - data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0, 0)) - return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%llx fails", (unsigned long long) mftno); - return fixup (buf, data->mft_size, (const grub_uint8_t *) "FILE"); -} - -static grub_err_t -init_file (struct grub_ntfs_file *mft, grub_uint64_t mftno) -{ - unsigned short flag; - - mft->inode_read = 1; - - mft->buf = grub_malloc (mft->data->mft_size << GRUB_NTFS_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%llx is not in use", - (unsigned long long) mftno); - - if ((flag & 2) == 0) - { - grub_uint8_t *pa; - - pa = locate_attr (&mft->attr, mft, GRUB_NTFS_AT_DATA); - if (pa == NULL) - return grub_error (GRUB_ERR_BAD_FS, "no $DATA in MFT 0x%llx", - (unsigned long long) mftno); - - if (!pa[8]) - mft->size = res_attr_data_len (pa); - else - mft->size = u64at (pa, 0x30); - - if ((mft->attr.flags & GRUB_NTFS_AF_ALST) == 0) - mft->attr.attr_end = 0; /* Don't jump to attribute list */ - } - else - return init_attr (&mft->attr, mft); - - return 0; -} - -static void -free_file (struct grub_ntfs_file *mft) -{ - if (mft) - { - free_attr (&mft->attr); - grub_free (mft->buf); - } -} - -static char * -get_utf8 (grub_uint8_t *in, grub_size_t len) -{ - grub_uint8_t *buf; - grub_uint16_t *tmp; - grub_size_t i; - - buf = grub_calloc (len, GRUB_MAX_UTF8_PER_UTF16 + 1); - tmp = grub_calloc (len, sizeof (tmp[0])); - if (!buf || !tmp) - { - grub_free (buf); - grub_free (tmp); - return NULL; - } - for (i = 0; i < len; i++) - tmp[i] = grub_le_to_cpu16 (grub_get_unaligned16 (in + 2 * i)); - *grub_utf16_to_utf8 (buf, tmp, len) = '\0'; - grub_free (tmp); - return (char *) buf; -} - -static int -list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, grub_uint8_t *end_pos, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data) -{ - grub_uint8_t *np; - int ns; - grub_uint16_t pos_incr; - - while (1) - { - grub_uint8_t namespace; - char *ustr; - - if ((pos >= end_pos) || (end_pos - pos < 0x52)) - break; - - if (pos[0xC] & 2) /* end signature */ - break; - - np = pos + 0x50; - ns = *(np++); - namespace = *(np++); - - if (2 * ns > end_pos - pos - 0x52) - break; - - /* - * 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; - grub_uint32_t attr; - - attr = u32at (pos, 0x48); - if (attr & GRUB_NTFS_ATTR_REPARSE) - type = GRUB_FSHELP_SYMLINK; - else if (attr & GRUB_NTFS_ATTR_DIRECTORY) - type = GRUB_FSHELP_DIR; - else - type = GRUB_FSHELP_REG; - - fdiro = grub_zalloc (sizeof (struct grub_ntfs_file)); - if (!fdiro) - return 0; - - fdiro->data = diro->data; - fdiro->ino = u64at (pos, 0) & 0xffffffffffffULL; - fdiro->mtime = u64at (pos, 0x20); - - ustr = get_utf8 (np, ns); - if (ustr == NULL) - { - grub_free (fdiro); - return 0; - } - if (namespace) - type |= GRUB_FSHELP_CASE_INSENSITIVE; - - if (hook (ustr, type, fdiro, hook_data)) - { - grub_free (ustr); - return 1; - } - - grub_free (ustr); - } - pos_incr = u16at (pos, 8); - if (pos_incr > 0) - pos += pos_incr; - else - return 0; - - } - return 0; -} - -struct symlink_descriptor -{ - grub_uint32_t type; - grub_uint32_t total_len; - grub_uint16_t off1; - grub_uint16_t len1; - grub_uint16_t off2; - grub_uint16_t len2; -} GRUB_PACKED; - -static char * -grub_ntfs_read_symlink (grub_fshelp_node_t node) -{ - struct grub_ntfs_file *mft; - struct symlink_descriptor symdesc; - grub_err_t err; - grub_uint8_t *buf16 = NULL; - char *buf, *end; - grub_size_t len; - grub_uint8_t *pa; - grub_size_t off; - - mft = (struct grub_ntfs_file *) node; - - mft->buf = grub_malloc (mft->data->mft_size << GRUB_NTFS_BLK_SHR); - if (mft->buf == NULL) - return NULL; - - if (read_mft (mft->data, mft->buf, mft->ino)) - goto fail; - - pa = locate_attr (&mft->attr, mft, GRUB_NTFS_AT_SYMLINK); - if (pa == NULL) - { - grub_error (GRUB_ERR_BAD_FS, "no $SYMLINK in MFT 0x%llx", - (unsigned long long) mft->ino); - goto fail; - } - - err = read_attr (&mft->attr, (grub_uint8_t *) &symdesc, 0, - sizeof (struct symlink_descriptor), 1, 0, 0); - if (err) - goto fail; - - switch (grub_cpu_to_le32 (symdesc.type)) - { - case 0xa000000c: - off = (sizeof (struct symlink_descriptor) + 4 - + grub_cpu_to_le32 (symdesc.off1)); - len = grub_cpu_to_le32 (symdesc.len1); - break; - case 0xa0000003: - off = (sizeof (struct symlink_descriptor) - + grub_cpu_to_le32 (symdesc.off1)); - len = grub_cpu_to_le32 (symdesc.len1); - break; - default: - grub_error (GRUB_ERR_BAD_FS, "symlink type invalid (%x)", - grub_cpu_to_le32 (symdesc.type)); - goto fail; - } - - buf16 = grub_malloc (len); - if (!buf16) - goto fail; - - err = read_attr (&mft->attr, buf16, off, len, 1, 0, 0); - if (err) - goto fail; - - buf = get_utf8 (buf16, len / 2); - if (!buf) - goto fail; - - grub_free (mft->buf); - grub_free (buf16); - - for (end = buf; *end; end++) - if (*end == '\\') - *end = '/'; - - /* Split the sequence to avoid GCC thinking that this is a trigraph. */ - if (grub_memcmp (buf, "/?" "?/", 4) == 0 && buf[5] == ':' && buf[6] == '/' - && grub_isalpha (buf[4])) - { - grub_memmove (buf, buf + 6, end - buf + 1 - 6); - end -= 6; - } - return buf; - - fail: - grub_free (mft->buf); - grub_free (buf16); - return NULL; -} - -static int -grub_ntfs_iterate_dir (grub_fshelp_node_t dir, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data) -{ - grub_uint8_t *bitmap; - struct grub_ntfs_attr attr, *at; - grub_uint8_t *cur_pos, *indx, *bmp; - int ret = 0; - grub_size_t bitmap_len; - struct grub_ntfs_file *mft; - /* Used to make sure we're not stuck in a loop. */ - grub_uint8_t *last_pos = NULL; - grub_uint32_t tmp_len; - - mft = (struct grub_ntfs_file *) dir; - - if (!mft->inode_read) - { - if (init_file (mft, mft->ino)) - return 0; - } - - indx = NULL; - bmp = NULL; - - at = &attr; - if (init_attr (at, mft) != GRUB_ERR_NONE) - return 0; - - while (1) - { - cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ROOT); - if (cur_pos == NULL || cur_pos == last_pos) - { - grub_error (GRUB_ERR_BAD_FS, "no $INDEX_ROOT"); - goto done; - } - last_pos = cur_pos; - - /* 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 += res_attr_data_off (cur_pos); - if(cur_pos >= at->end) - continue; - 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), - at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR), - hook, hook_data); - if (ret) - goto done; - - bitmap = NULL; - bitmap_len = 0; - free_attr (at); - /* No need to check errors here, as it will already be fine */ - init_attr (at, mft); - - last_pos = NULL; - while ((cur_pos = find_attr (at, GRUB_NTFS_AT_BITMAP)) != NULL) - { - int ofs; - - if (cur_pos == last_pos) - { - grub_error (GRUB_ERR_BAD_FS, "bitmap attribute loop"); - goto done; - } - last_pos = cur_pos; - - ofs = 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) ? res_attr_data_len (cur_pos) : - u32at (cur_pos, 0x28)); - - bmp = grub_malloc (bitmap_len); - if (bmp == NULL) - goto done; - - if (is_resident) - { - if (bitmap_len > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR)) - { - grub_error (GRUB_ERR_BAD_FS, "resident bitmap too large"); - goto done; - } - - if (cur_pos >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR)) - { - grub_error (GRUB_ERR_BAD_FS, "resident bitmap out of range"); - goto done; - } - - if (res_attr_data_off (cur_pos) + res_attr_data_len (cur_pos) > - (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) cur_pos) - { - grub_error (GRUB_ERR_BAD_FS, "resident bitmap out of range"); - goto done; - } - - grub_memcpy (bmp, cur_pos + res_attr_data_off (cur_pos), - bitmap_len); - } - else - { - if (read_data (at, cur_pos, bmp, 0, bitmap_len, 0, 0, 0)) - { - grub_error (GRUB_ERR_BAD_FS, - "fails to read non-resident $BITMAP"); - goto done; - } - tmp_len = u32at (cur_pos, 0x30); - if (tmp_len <= bitmap_len) - bitmap_len = tmp_len; - else - { - grub_error (GRUB_ERR_BAD_FS, - "bitmap len too large for non-resident $BITMAP"); - goto done; - } - } - - bitmap = bmp; - break; - } - } - - free_attr (at); - last_pos = NULL; - cur_pos = locate_attr (at, mft, GRUB_NTFS_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, GRUB_NTFS_AT_INDEX_ALLOCATION); - if (cur_pos == last_pos) - break; - last_pos = cur_pos; - } - - if ((!cur_pos) && (bitmap)) - { - grub_error (GRUB_ERR_BAD_FS, "$BITMAP without $INDEX_ALLOCATION"); - goto done; - } - - if (bitmap) - { - grub_disk_addr_t i; - grub_uint8_t v; - - indx = grub_malloc (mft->data->idx_size << GRUB_NTFS_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 << GRUB_NTFS_BLK_SHR), - (mft->data->idx_size << GRUB_NTFS_BLK_SHR), 0, 0, 0)) - || (fixup (indx, mft->data->idx_size, - (const grub_uint8_t *) "INDX"))) - goto done; - ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], - indx + (mft->data->idx_size << GRUB_NTFS_BLK_SHR), - hook, hook_data); - if (ret) - goto done; - } - v <<= 1; - if (!v) - { - 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; - grub_uint32_t spc; - - 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) != 0 - || bpb.sectors_per_cluster == 0 - || (bpb.sectors_per_cluster & (bpb.sectors_per_cluster - 1)) != 0 - || bpb.bytes_per_sector == 0 - || (bpb.bytes_per_sector & (bpb.bytes_per_sector - 1)) != 0) - goto fail; - - spc = (((grub_uint32_t) bpb.sectors_per_cluster - * (grub_uint32_t) grub_le_to_cpu16 (bpb.bytes_per_sector)) - >> GRUB_NTFS_BLK_SHR); - if (spc == 0) - goto fail; - - for (data->log_spc = 0; (1U << data->log_spc) < spc; data->log_spc++); - - if (bpb.clusters_per_mft > 0) - data->mft_size = ((grub_disk_addr_t) bpb.clusters_per_mft) << data->log_spc; - else if (-bpb.clusters_per_mft < GRUB_NTFS_BLK_SHR || -bpb.clusters_per_mft >= 31) - goto fail; - else - data->mft_size = 1ULL << (-bpb.clusters_per_mft - GRUB_NTFS_BLK_SHR); - - if (bpb.clusters_per_index > 0) - data->idx_size = (((grub_disk_addr_t) bpb.clusters_per_index) - << data->log_spc); - else if (-bpb.clusters_per_index < GRUB_NTFS_BLK_SHR || -bpb.clusters_per_index >= 31) - goto fail; - else - data->idx_size = 1ULL << (-bpb.clusters_per_index - GRUB_NTFS_BLK_SHR); - - data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) << data->log_spc; - - if ((data->mft_size > GRUB_NTFS_MAX_MFT) || (data->idx_size > GRUB_NTFS_MAX_IDX)) - goto fail; - - data->mmft.data = data; - data->cmft.data = data; - - data->mmft.buf = grub_malloc (data->mft_size << GRUB_NTFS_BLK_SHR); - if (!data->mmft.buf) - goto fail; - - if (grub_disk_read - (disk, data->mft_start, 0, data->mft_size << GRUB_NTFS_BLK_SHR, data->mmft.buf)) - goto fail; - - data->uuid = grub_le_to_cpu64 (bpb.num_serial); - - if (fixup (data->mmft.buf, data->mft_size, (const grub_uint8_t *) "FILE")) - goto fail; - - if (!locate_attr (&data->mmft.attr, &data->mmft, GRUB_NTFS_AT_DATA)) - goto fail; - - if (init_file (&data->cmft, GRUB_NTFS_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; -} - -/* Context for grub_ntfs_dir. */ -struct grub_ntfs_dir_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; -}; - -/* Helper for grub_ntfs_dir. */ -static int -grub_ntfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, void *data) -{ - struct grub_ntfs_dir_ctx *ctx = data; - 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 = grub_divmod64 (node->mtime, 10000000, 0) - - 86400ULL * 365 * (1970 - 1601) - - 86400ULL * ((1970 - 1601) / 4) + 86400ULL * ((1970 - 1601) / 100); - grub_free (node); - return ctx->hook (filename, &info, ctx->hook_data); -} - -static grub_err_t -grub_ntfs_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_ntfs_dir_ctx ctx = { hook, hook_data }; - struct grub_ntfs_data *data = 0; - struct grub_fshelp_node *fdiro = 0; - - 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, - grub_ntfs_read_symlink, GRUB_FSHELP_DIR); - - if (grub_errno) - goto fail; - - grub_ntfs_iterate_dir (fdiro, grub_ntfs_dir_iter, &ctx); - -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, - grub_ntfs_read_symlink, 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, (grub_uint8_t *) buf, file->offset, len, 1, - file->read_hook, file->read_hook_data); - return (grub_errno) ? -1 : (grub_ssize_t) 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; - grub_uint8_t *pa; - grub_err_t err; - - 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 << GRUB_NTFS_BLK_SHR); - if (mft->buf == NULL) - goto fail; - - if (read_mft (mft->data, mft->buf, mft->ino)) - goto fail; - } - - err = init_attr (&mft->attr, mft); - if (err != GRUB_ERR_NONE) - return err; - - pa = find_attr (&mft->attr, GRUB_NTFS_AT_VOLUME_NAME); - - if (pa == NULL || pa >= mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR)) - { - grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label"); - goto fail; - } - - if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa < 0x16) - { - grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label"); - goto fail; - } - - if ((pa) && (pa[8] == 0) && (res_attr_data_len (pa))) - { - int len; - - len = res_attr_data_len (pa) / 2; - pa += res_attr_data_off (pa); - if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa >= 2 * len && - pa >= mft->buf && (pa + len < (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR)))) - *label = get_utf8 (pa, len); - else - grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label"); - } - -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) - { - char *ptr; - *uuid = grub_xasprintf ("%016llx", (unsigned long long) data->uuid); - if (*uuid) - for (ptr = *uuid; *ptr; ptr++) - *ptr = grub_toupper (*ptr); - free_file (&data->mmft); - free_file (&data->cmft); - grub_free (data); - } - else - *uuid = NULL; - - grub_dl_unref (my_mod); - - return grub_errno; -} - -static struct grub_fs grub_ntfs_fs = - { - .name = "ntfs", - .fs_dir = grub_ntfs_dir, - .fs_open = grub_ntfs_open, - .fs_read = grub_ntfs_read, - .fs_close = grub_ntfs_close, - .fs_label = grub_ntfs_label, - .fs_uuid = grub_ntfs_uuid, -#ifdef GRUB_UTIL - .reserved_first_sector = 1, - .blocklist_install = 1, -#endif - .next = 0 -}; - -GRUB_MOD_INIT (ntfs) -{ - if (!grub_is_lockdown ()) - { - grub_ntfs_fs.mod = mod; - grub_fs_register (&grub_ntfs_fs); - } - my_mod = mod; -} - -GRUB_MOD_FINI (ntfs) -{ - if (!grub_is_lockdown ()) - grub_fs_unregister (&grub_ntfs_fs); -} diff --git a/grub-core/fs/odc.c b/grub-core/fs/odc.c deleted file mode 100644 index 8e4e8aeac..000000000 --- a/grub-core/fs/odc.c +++ /dev/null @@ -1,62 +0,0 @@ -/* cpio.c - cpio and tar filesystem. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007,2008,2009,2013 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 . - */ - -#include - -#define ALIGN_CPIO(x) x - -#define MAGIC "070707" -struct head -{ - char magic[6]; - char dev[6]; - char ino[6]; - char mode[6]; - char uid[6]; - char gid[6]; - char nlink[6]; - char rdev[6]; - char mtime[11]; - char namesize[6]; - char filesize[11]; -} GRUB_PACKED; - -static inline unsigned long long -read_number (const char *str, grub_size_t size) -{ - unsigned long long ret = 0; - while (size-- && *str >= '0' && *str <= '7') - ret = (ret << 3) | (*str++ & 0xf); - return ret; -} - -#define FSNAME "odc" - -#include "cpio_common.c" - -GRUB_MOD_INIT (odc) -{ - grub_cpio_fs.mod = mod; - grub_fs_register (&grub_cpio_fs); -} - -GRUB_MOD_FINI (odc) -{ - grub_fs_unregister (&grub_cpio_fs); -} diff --git a/grub-core/fs/proc.c b/grub-core/fs/proc.c deleted file mode 100644 index bcde43349..000000000 --- a/grub-core/fs/proc.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct grub_procfs_entry *grub_procfs_entries; - -static int -grub_procdev_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - if (pull != GRUB_DISK_PULL_NONE) - return 0; - - return hook ("proc", hook_data); -} - -static grub_err_t -grub_procdev_open (const char *name, grub_disk_t disk) -{ - if (grub_strcmp (name, "proc")) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a procfs disk"); - - disk->total_sectors = 0; - disk->id = 0; - - disk->data = 0; - - return GRUB_ERR_NONE; -} - -static void -grub_procdev_close (grub_disk_t disk __attribute((unused))) -{ -} - -static grub_err_t -grub_procdev_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_procdev_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; -} - -struct grub_archelp_data -{ - struct grub_procfs_entry *entry, *next_entry; -}; - -static void -grub_procfs_rewind (struct grub_archelp_data *data) -{ - data->entry = NULL; - data->next_entry = grub_procfs_entries; -} - -static grub_err_t -grub_procfs_find_file (struct grub_archelp_data *data, char **name, - grub_int32_t *mtime, - grub_uint32_t *mode) -{ - data->entry = data->next_entry; - if (!data->entry) - { - *mode = GRUB_ARCHELP_ATTR_END; - return GRUB_ERR_NONE; - } - data->next_entry = data->entry->next; - *mode = GRUB_ARCHELP_ATTR_FILE | GRUB_ARCHELP_ATTR_NOTIME; - *name = grub_strdup (data->entry->name); - *mtime = 0; - if (!*name) - return grub_errno; - return GRUB_ERR_NONE; -} - -static struct grub_archelp_ops arcops = - { - .find_file = grub_procfs_find_file, - .rewind = grub_procfs_rewind - }; - -static grub_ssize_t -grub_procfs_read (grub_file_t file, char *buf, grub_size_t len) -{ - char *data = file->data; - - grub_memcpy (buf, data + file->offset, len); - - return len; -} - -static grub_err_t -grub_procfs_close (grub_file_t file) -{ - char *data; - - data = file->data; - grub_free (data); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_procfs_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_archelp_data data; - - /* Check if the disk is our dummy disk. */ - if (grub_strcmp (device->disk->name, "proc")) - return grub_error (GRUB_ERR_BAD_FS, "not a procfs"); - - grub_procfs_rewind (&data); - - return grub_archelp_dir (&data, &arcops, - path, hook, hook_data); -} - -static grub_err_t -grub_procfs_open (struct grub_file *file, const char *path) -{ - grub_err_t err; - struct grub_archelp_data data; - grub_size_t sz; - - grub_procfs_rewind (&data); - - err = grub_archelp_open (&data, &arcops, path); - if (err) - return err; - file->data = data.entry->get_contents (&sz); - if (!file->data) - return grub_errno; - file->size = sz; - return GRUB_ERR_NONE; -} - -static struct grub_disk_dev grub_procfs_dev = { - .name = "proc", - .id = GRUB_DISK_DEVICE_PROCFS_ID, - .disk_iterate = grub_procdev_iterate, - .disk_open = grub_procdev_open, - .disk_close = grub_procdev_close, - .disk_read = grub_procdev_read, - .disk_write = grub_procdev_write, - .next = 0 -}; - -static struct grub_fs grub_procfs_fs = - { - .name = "procfs", - .fs_dir = grub_procfs_dir, - .fs_open = grub_procfs_open, - .fs_read = grub_procfs_read, - .fs_close = grub_procfs_close, - .next = 0 - }; - -GRUB_MOD_INIT (procfs) -{ - grub_procfs_fs.mod = mod; - grub_disk_dev_register (&grub_procfs_dev); - grub_fs_register (&grub_procfs_fs); -} - -GRUB_MOD_FINI (procfs) -{ - grub_disk_dev_unregister (&grub_procfs_dev); - grub_fs_unregister (&grub_procfs_fs); -} diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c deleted file mode 100644 index eafab03b2..000000000 --- a/grub-core/fs/romfs.c +++ /dev/null @@ -1,490 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct grub_romfs_superblock -{ - char magic[8]; -#define GRUB_ROMFS_MAGIC "-rom1fs-" - grub_uint32_t total_size; - grub_uint32_t chksum; - char label[0]; -}; - -struct grub_romfs_file_header -{ - grub_uint32_t next_file; - grub_uint32_t spec; - grub_uint32_t size; - grub_uint32_t chksum; - char name[0]; -}; - -struct grub_romfs_data -{ - grub_disk_addr_t first_file; - grub_disk_t disk; -}; - -struct grub_fshelp_node -{ - grub_disk_addr_t addr; - struct grub_romfs_data *data; - grub_disk_addr_t data_addr; - /* Not filled for root. */ - struct grub_romfs_file_header file; -}; - -#define GRUB_ROMFS_ALIGN 16 -#define GRUB_ROMFS_TYPE_MASK 7 -#define GRUB_ROMFS_TYPE_HARDLINK 0 -#define GRUB_ROMFS_TYPE_DIRECTORY 1 -#define GRUB_ROMFS_TYPE_REGULAR 2 -#define GRUB_ROMFS_TYPE_SYMLINK 3 - -static grub_err_t -do_checksum (void *in, grub_size_t insize) -{ - grub_uint32_t *a = in; - grub_size_t sz = insize / 4; - grub_uint32_t *b = a + sz; - grub_uint32_t csum = 0; - - while (a < b) - csum += grub_be_to_cpu32 (*a++); - if (csum) - return grub_error (GRUB_ERR_BAD_FS, "invalid checksum"); - return GRUB_ERR_NONE; -} - -static struct grub_romfs_data * -grub_romfs_mount (grub_device_t dev) -{ - union { - struct grub_romfs_superblock sb; - char d[512]; - } sb; - grub_err_t err; - char *ptr; - grub_disk_addr_t sec = 0; - struct grub_romfs_data *data; - if (!dev->disk) - { - grub_error (GRUB_ERR_BAD_FS, "not a disk"); - return NULL; - } - err = grub_disk_read (dev->disk, 0, 0, sizeof (sb), &sb); - if (err == GRUB_ERR_OUT_OF_RANGE) - err = grub_errno = GRUB_ERR_BAD_FS; - if (err) - return NULL; - if (grub_be_to_cpu32 (sb.sb.total_size) < sizeof (sb)) - { - grub_error (GRUB_ERR_BAD_FS, "too short filesystem"); - return NULL; - } - if (grub_memcmp (sb.sb.magic, GRUB_ROMFS_MAGIC, - sizeof (sb.sb.magic)) != 0) - { - grub_error (GRUB_ERR_BAD_FS, "not romfs"); - return NULL; - } - err = do_checksum (&sb, sizeof (sb) < grub_be_to_cpu32 (sb.sb.total_size) ? - sizeof (sb) : grub_be_to_cpu32 (sb.sb.total_size)); - if (err) - { - grub_error (GRUB_ERR_BAD_FS, "checksum incorrect"); - return NULL; - } - for (ptr = sb.sb.label; (void *) ptr < (void *) (&sb + 1) - && ptr - sb.d < (grub_ssize_t) grub_be_to_cpu32 (sb.sb.total_size); ptr++) - if (!*ptr) - break; - while ((void *) ptr == &sb + 1) - { - sec++; - err = grub_disk_read (dev->disk, sec, 0, sizeof (sb), &sb); - if (err == GRUB_ERR_OUT_OF_RANGE) - err = grub_errno = GRUB_ERR_BAD_FS; - if (err) - return NULL; - for (ptr = sb.d; (void *) ptr < (void *) (&sb + 1) - && (ptr - sb.d + (sec << GRUB_DISK_SECTOR_BITS) - < grub_be_to_cpu32 (sb.sb.total_size)); - ptr++) - if (!*ptr) - break; - } - data = grub_malloc (sizeof (*data)); - if (!data) - return NULL; - data->first_file = ALIGN_UP (ptr + 1 - sb.d, GRUB_ROMFS_ALIGN) - + (sec << GRUB_DISK_SECTOR_BITS); - data->disk = dev->disk; - return data; -} - -static char * -grub_romfs_read_symlink (grub_fshelp_node_t node) -{ - char *ret; - grub_err_t err; - ret = grub_malloc (grub_be_to_cpu32 (node->file.size) + 1); - if (!ret) - return NULL; - err = grub_disk_read (node->data->disk, - (node->data_addr) >> GRUB_DISK_SECTOR_BITS, - (node->data_addr) & (GRUB_DISK_SECTOR_SIZE - 1), - grub_be_to_cpu32 (node->file.size), ret); - if (err) - { - grub_free (ret); - return NULL; - } - ret[grub_be_to_cpu32 (node->file.size)] = 0; - return ret; -} - -static int -grub_romfs_iterate_dir (grub_fshelp_node_t dir, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data) -{ - grub_disk_addr_t caddr; - struct grub_romfs_file_header hdr; - unsigned nptr; - unsigned i, j; - grub_size_t a = 0; - grub_properly_aligned_t *name = NULL; - - for (caddr = dir->data_addr; caddr; - caddr = grub_be_to_cpu32 (hdr.next_file) & ~(GRUB_ROMFS_ALIGN - 1)) - { - grub_disk_addr_t naddr = caddr + sizeof (hdr); - grub_uint32_t csum = 0; - enum grub_fshelp_filetype filetype = GRUB_FSHELP_UNKNOWN; - struct grub_fshelp_node *node = NULL; - grub_err_t err; - - err = grub_disk_read (dir->data->disk, caddr >> GRUB_DISK_SECTOR_BITS, - caddr & (GRUB_DISK_SECTOR_SIZE - 1), - sizeof (hdr), &hdr); - if (err) - { - grub_free (name); - return 1; - } - for (nptr = 0; ; nptr++, naddr += 16) - { - if (a <= nptr) - { - grub_properly_aligned_t *on; - a = 2 * (nptr + 1); - on = name; - name = grub_realloc (name, a * 16); - if (!name) - { - grub_free (on); - return 1; - } - } - COMPILE_TIME_ASSERT (16 % sizeof (name[0]) == 0); - err = grub_disk_read (dir->data->disk, naddr >> GRUB_DISK_SECTOR_BITS, - naddr & (GRUB_DISK_SECTOR_SIZE - 1), - 16, name + (16 / sizeof (name[0])) * nptr); - if (err) - return 1; - for (j = 0; j < 16; j++) - if (!((char *) name)[16 * nptr + j]) - break; - if (j != 16) - break; - } - for (i = 0; i < sizeof (hdr) / sizeof (grub_uint32_t); i++) - csum += grub_be_to_cpu32 (((grub_uint32_t *) &hdr)[i]); - for (i = 0; i < (nptr + 1) * 4; i++) - csum += grub_be_to_cpu32 (((grub_uint32_t *) name)[i]); - if (csum != 0) - { - grub_error (GRUB_ERR_BAD_FS, "invalid checksum"); - grub_free (name); - return 1; - } - node = grub_malloc (sizeof (*node)); - if (!node) - return 1; - node->addr = caddr; - node->data_addr = caddr + (nptr + 1) * 16 + sizeof (hdr); - node->data = dir->data; - node->file = hdr; - switch (grub_be_to_cpu32 (hdr.next_file) & GRUB_ROMFS_TYPE_MASK) - { - case GRUB_ROMFS_TYPE_REGULAR: - filetype = GRUB_FSHELP_REG; - break; - case GRUB_ROMFS_TYPE_SYMLINK: - filetype = GRUB_FSHELP_SYMLINK; - break; - case GRUB_ROMFS_TYPE_DIRECTORY: - node->data_addr = grub_be_to_cpu32 (hdr.spec); - filetype = GRUB_FSHELP_DIR; - break; - case GRUB_ROMFS_TYPE_HARDLINK: - { - grub_disk_addr_t laddr; - node->addr = laddr = grub_be_to_cpu32 (hdr.spec); - err = grub_disk_read (dir->data->disk, - laddr >> GRUB_DISK_SECTOR_BITS, - laddr & (GRUB_DISK_SECTOR_SIZE - 1), - sizeof (node->file), &node->file); - if (err) - return 1; - if ((grub_be_to_cpu32 (node->file.next_file) & GRUB_ROMFS_TYPE_MASK) - == GRUB_ROMFS_TYPE_REGULAR - || (grub_be_to_cpu32 (node->file.next_file) - & GRUB_ROMFS_TYPE_MASK) == GRUB_ROMFS_TYPE_SYMLINK) - { - laddr += sizeof (hdr); - while (1) - { - char buf[16]; - err = grub_disk_read (dir->data->disk, - laddr >> GRUB_DISK_SECTOR_BITS, - laddr & (GRUB_DISK_SECTOR_SIZE - 1), - 16, buf); - if (err) - return 1; - for (i = 0; i < 16; i++) - if (!buf[i]) - break; - if (i != 16) - break; - laddr += 16; - } - node->data_addr = laddr + 16; - } - if ((grub_be_to_cpu32 (node->file.next_file) - & GRUB_ROMFS_TYPE_MASK) == GRUB_ROMFS_TYPE_REGULAR) - filetype = GRUB_FSHELP_REG; - if ((grub_be_to_cpu32 (node->file.next_file) - & GRUB_ROMFS_TYPE_MASK) == GRUB_ROMFS_TYPE_SYMLINK) - filetype = GRUB_FSHELP_SYMLINK; - if ((grub_be_to_cpu32 (node->file.next_file) & GRUB_ROMFS_TYPE_MASK) - == GRUB_ROMFS_TYPE_DIRECTORY) - { - node->data_addr = grub_be_to_cpu32 (node->file.spec); - filetype = GRUB_FSHELP_DIR; - } - - break; - } - } - - if (hook ((char *) name, filetype, node, hook_data)) - { - grub_free (name); - return 1; - } - } - grub_free (name); - return 0; -} - -/* Context for grub_romfs_dir. */ -struct grub_romfs_dir_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; -}; - -/* Helper for grub_romfs_dir. */ -static int -grub_romfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, void *data) -{ - struct grub_romfs_dir_ctx *ctx = data; - 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 ctx->hook (filename, &info, ctx->hook_data); -} - -static grub_err_t -grub_romfs_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_romfs_dir_ctx ctx = { hook, hook_data }; - struct grub_romfs_data *data = 0; - struct grub_fshelp_node *fdiro = 0, start; - - data = grub_romfs_mount (device); - if (! data) - goto fail; - - start.addr = data->first_file; - start.data_addr = data->first_file; - start.data = data; - grub_fshelp_find_file (path, &start, &fdiro, grub_romfs_iterate_dir, - grub_romfs_read_symlink, GRUB_FSHELP_DIR); - if (grub_errno) - goto fail; - - grub_romfs_iterate_dir (fdiro, grub_romfs_dir_iter, &ctx); - - fail: - grub_free (data); - - return grub_errno; -} - -static grub_err_t -grub_romfs_open (struct grub_file *file, const char *name) -{ - struct grub_romfs_data *data = 0; - struct grub_fshelp_node *fdiro = 0, start; - - data = grub_romfs_mount (file->device); - if (! data) - goto fail; - - start.addr = data->first_file; - start.data_addr = data->first_file; - start.data = data; - - grub_fshelp_find_file (name, &start, &fdiro, grub_romfs_iterate_dir, - grub_romfs_read_symlink, GRUB_FSHELP_REG); - if (grub_errno) - goto fail; - - file->size = grub_be_to_cpu32 (fdiro->file.size); - file->data = fdiro; - return GRUB_ERR_NONE; - - fail: - grub_free (data); - - return grub_errno; -} - -static grub_ssize_t -grub_romfs_read (grub_file_t file, char *buf, grub_size_t len) -{ - struct grub_fshelp_node *data = file->data; - - /* XXX: The file is stored in as a single extent. */ - data->data->disk->read_hook = file->read_hook; - data->data->disk->read_hook_data = file->read_hook_data; - grub_disk_read (data->data->disk, - (data->data_addr + file->offset) >> GRUB_DISK_SECTOR_BITS, - (data->data_addr + file->offset) & (GRUB_DISK_SECTOR_SIZE - 1), - len, buf); - data->data->disk->read_hook = NULL; - - if (grub_errno) - return -1; - - return len; -} - -static grub_err_t -grub_romfs_close (grub_file_t file) -{ - struct grub_fshelp_node *data = file->data; - - grub_free (data->data); - grub_free (data); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_romfs_label (grub_device_t device, char **label) -{ - struct grub_romfs_data *data; - grub_err_t err; - - *label = NULL; - - data = grub_romfs_mount (device); - if (!data) - return grub_errno; - *label = grub_malloc (data->first_file + 1 - - sizeof (struct grub_romfs_superblock)); - if (!*label) - { - grub_free (data); - return grub_errno; - } - err = grub_disk_read (device->disk, 0, sizeof (struct grub_romfs_superblock), - data->first_file - - sizeof (struct grub_romfs_superblock), - *label); - if (err) - { - grub_free (data); - grub_free (*label); - *label = NULL; - return err; - } - (*label)[data->first_file - sizeof (struct grub_romfs_superblock)] = 0; - grub_free (data); - return GRUB_ERR_NONE; -} - - -static struct grub_fs grub_romfs_fs = - { - .name = "romfs", - .fs_dir = grub_romfs_dir, - .fs_open = grub_romfs_open, - .fs_read = grub_romfs_read, - .fs_close = grub_romfs_close, - .fs_label = grub_romfs_label, -#ifdef GRUB_UTIL - .reserved_first_sector = 0, - .blocklist_install = 0, -#endif - .next = 0 - }; - -GRUB_MOD_INIT(romfs) -{ - if (!grub_is_lockdown ()) - { - grub_romfs_fs.mod = mod; - grub_fs_register (&grub_romfs_fs); - } -} - -GRUB_MOD_FINI(romfs) -{ - if (!grub_is_lockdown ()) - grub_fs_unregister (&grub_romfs_fs); -} diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c deleted file mode 100644 index cf2bca822..000000000 --- a/grub-core/fs/squash4.c +++ /dev/null @@ -1,1061 +0,0 @@ -/* squash4.c - SquashFS */ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "xz.h" -#include "xz_stream.h" - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* - object format Pointed by - superblock RAW Fixed offset (0) - data RAW ? Fixed offset (60) - inode table Chunk superblock - dir table Chunk superblock - fragment table Chunk unk1 - unk1 RAW, Chunk superblock - unk2 RAW superblock - UID/GID Chunk exttblptr - exttblptr RAW superblock - - UID/GID table is the array ot uint32_t - unk1 contains pointer to fragment table followed by some chunk. - unk2 containts one uint64_t -*/ - -struct grub_squash_super -{ - grub_uint32_t magic; -#define SQUASH_MAGIC 0x73717368 - grub_uint32_t dummy1; - grub_uint32_t creation_time; - grub_uint32_t block_size; - grub_uint32_t dummy2; - grub_uint16_t compression; - grub_uint16_t dummy3; - grub_uint64_t dummy4; - grub_uint16_t root_ino_offset; - grub_uint32_t root_ino_chunk; - grub_uint16_t dummy5; - grub_uint64_t total_size; - grub_uint64_t exttbloffset; - grub_uint64_t dummy6; - grub_uint64_t inodeoffset; - grub_uint64_t diroffset; - grub_uint64_t unk1offset; - grub_uint64_t unk2offset; -} GRUB_PACKED; - -/* Chunk-based */ -struct grub_squash_inode -{ - /* Same values as direlem types. */ - grub_uint16_t type; - grub_uint16_t dummy[3]; - grub_uint32_t mtime; - grub_uint32_t dummy2; - union - { - struct { - grub_uint32_t chunk; - grub_uint32_t fragment; - grub_uint32_t offset; - grub_uint32_t size; - grub_uint32_t block_size[0]; - } GRUB_PACKED file; - struct { - grub_uint64_t chunk; - grub_uint64_t size; - grub_uint32_t dummy1[3]; - grub_uint32_t fragment; - grub_uint32_t offset; - grub_uint32_t dummy3; - grub_uint32_t block_size[0]; - } GRUB_PACKED long_file; - struct { - grub_uint32_t chunk; - grub_uint32_t dummy; - grub_uint16_t size; - grub_uint16_t offset; - } GRUB_PACKED dir; - struct { - grub_uint32_t dummy1; - grub_uint32_t size; - grub_uint32_t chunk; - grub_uint32_t dummy2; - grub_uint16_t dummy3; - grub_uint16_t offset; - } GRUB_PACKED long_dir; - struct { - grub_uint32_t dummy; - grub_uint32_t namelen; - char name[0]; - } GRUB_PACKED symlink; - } GRUB_PACKED; -} GRUB_PACKED; - -struct grub_squash_cache_inode -{ - struct grub_squash_inode ino; - grub_disk_addr_t ino_chunk; - grub_uint16_t ino_offset; - grub_uint32_t *block_sizes; - grub_disk_addr_t *cumulated_block_sizes; -}; - -/* Chunk-based. */ -struct grub_squash_dirent_header -{ - /* Actually the value is the number of elements - 1. */ - grub_uint32_t nelems; - grub_uint32_t ino_chunk; - grub_uint32_t dummy; -} GRUB_PACKED; - -struct grub_squash_dirent -{ - grub_uint16_t ino_offset; - grub_uint16_t dummy; - grub_uint16_t type; - /* Actually the value is the length of name - 1. */ - grub_uint16_t namelen; - char name[0]; -} GRUB_PACKED; - -enum - { - SQUASH_TYPE_DIR = 1, - SQUASH_TYPE_REGULAR = 2, - SQUASH_TYPE_SYMLINK = 3, - SQUASH_TYPE_LONG_DIR = 8, - SQUASH_TYPE_LONG_REGULAR = 9, - }; - - -struct grub_squash_frag_desc -{ - grub_uint64_t offset; - grub_uint32_t size; - grub_uint32_t dummy; -} GRUB_PACKED; - -enum - { - SQUASH_CHUNK_FLAGS = 0x8000, - SQUASH_CHUNK_UNCOMPRESSED = 0x8000 - }; - -enum - { - SQUASH_BLOCK_FLAGS = 0x1000000, - SQUASH_BLOCK_UNCOMPRESSED = 0x1000000 - }; - -enum - { - COMPRESSION_ZLIB = 1, - COMPRESSION_LZO = 3, - COMPRESSION_XZ = 4, - }; - - -#define SQUASH_CHUNK_SIZE 0x2000 -#define XZBUFSIZ 0x2000 - -struct grub_squash_data -{ - grub_disk_t disk; - struct grub_squash_super sb; - struct grub_squash_cache_inode ino; - grub_uint64_t fragments; - int log2_blksz; - grub_size_t blksz; - grub_ssize_t (*decompress) (char *inbuf, grub_size_t insize, grub_off_t off, - char *outbuf, grub_size_t outsize, - struct grub_squash_data *data); - struct xz_dec *xzdec; - char *xzbuf; -}; - -struct grub_fshelp_node -{ - struct grub_squash_data *data; - struct grub_squash_inode ino; - grub_size_t stsize; - struct - { - grub_disk_addr_t ino_chunk; - grub_uint16_t ino_offset; - } stack[1]; -}; - -static grub_err_t -read_chunk (struct grub_squash_data *data, void *buf, grub_size_t len, - grub_uint64_t chunk_start, grub_off_t offset) -{ - while (len > 0) - { - grub_uint64_t csize; - grub_uint16_t d; - grub_err_t err; - while (1) - { - err = grub_disk_read (data->disk, - chunk_start >> GRUB_DISK_SECTOR_BITS, - chunk_start & (GRUB_DISK_SECTOR_SIZE - 1), - sizeof (d), &d); - if (err) - return err; - if (offset < SQUASH_CHUNK_SIZE) - break; - offset -= SQUASH_CHUNK_SIZE; - chunk_start += 2 + (grub_le_to_cpu16 (d) & ~SQUASH_CHUNK_FLAGS); - } - - csize = SQUASH_CHUNK_SIZE - offset; - if (csize > len) - csize = len; - - if (grub_le_to_cpu16 (d) & SQUASH_CHUNK_UNCOMPRESSED) - { - grub_disk_addr_t a = chunk_start + 2 + offset; - err = grub_disk_read (data->disk, (a >> GRUB_DISK_SECTOR_BITS), - a & (GRUB_DISK_SECTOR_SIZE - 1), - csize, buf); - if (err) - return err; - } - else - { - char *tmp; - grub_size_t bsize = grub_le_to_cpu16 (d) & ~SQUASH_CHUNK_FLAGS; - grub_disk_addr_t a = chunk_start + 2; - tmp = grub_malloc (bsize); - if (!tmp) - return grub_errno; - /* FIXME: buffer uncompressed data. */ - err = grub_disk_read (data->disk, (a >> GRUB_DISK_SECTOR_BITS), - a & (GRUB_DISK_SECTOR_SIZE - 1), - bsize, tmp); - if (err) - { - grub_free (tmp); - return err; - } - - if (data->decompress (tmp, bsize, offset, - buf, csize, data) < 0) - { - grub_free (tmp); - return grub_errno; - } - grub_free (tmp); - } - len -= csize; - offset += csize; - buf = (char *) buf + csize; - } - return GRUB_ERR_NONE; -} - -static grub_ssize_t -zlib_decompress (char *inbuf, grub_size_t insize, grub_off_t off, - char *outbuf, grub_size_t outsize, - struct grub_squash_data *data __attribute__ ((unused))) -{ - return grub_zlib_decompress (inbuf, insize, off, outbuf, outsize); -} - -static grub_ssize_t -lzo_decompress (char *inbuf, grub_size_t insize, grub_off_t off, - char *outbuf, grub_size_t len, struct grub_squash_data *data) -{ - lzo_uint usize = data->blksz; - grub_uint8_t *udata; - - if (usize < 8192) - usize = 8192; - - udata = grub_malloc (usize); - if (!udata) - return -1; - - if (lzo1x_decompress_safe ((grub_uint8_t *) inbuf, - insize, udata, &usize, NULL) != LZO_E_OK) - { - grub_error (GRUB_ERR_BAD_FS, "incorrect compressed chunk"); - grub_free (udata); - return -1; - } - grub_memcpy (outbuf, udata + off, len); - grub_free (udata); - return len; -} - -static grub_ssize_t -xz_decompress (char *inbuf, grub_size_t insize, grub_off_t off, - char *outbuf, grub_size_t len, struct grub_squash_data *data) -{ - grub_size_t ret = 0; - grub_off_t pos = 0; - struct xz_buf buf; - - xz_dec_reset (data->xzdec); - buf.in = (grub_uint8_t *) inbuf; - buf.in_pos = 0; - buf.in_size = insize; - buf.out = (grub_uint8_t *) data->xzbuf; - buf.out_pos = 0; - buf.out_size = XZBUFSIZ; - - while (len) - { - enum xz_ret xzret; - - buf.out_pos = 0; - - xzret = xz_dec_run (data->xzdec, &buf); - - if (xzret != XZ_OK && xzret != XZ_STREAM_END) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "invalid xz chunk"); - return -1; - } - if (pos + buf.out_pos >= off) - { - grub_ssize_t outoff = pos - off; - grub_size_t l; - if (outoff >= 0) - { - l = buf.out_pos; - if (l > len) - l = len; - grub_memcpy (outbuf + outoff, buf.out, l); - } - else - { - outoff = -outoff; - l = buf.out_pos - outoff; - if (l > len) - l = len; - grub_memcpy (outbuf, buf.out + outoff, l); - } - ret += l; - len -= l; - } - pos += buf.out_pos; - if (xzret == XZ_STREAM_END) - break; - } - return ret; -} - -static struct grub_squash_data * -squash_mount (grub_disk_t disk) -{ - struct grub_squash_super sb; - grub_err_t err; - struct grub_squash_data *data; - grub_uint64_t frag; - - err = grub_disk_read (disk, 0, 0, sizeof (sb), &sb); - if (grub_errno == GRUB_ERR_OUT_OF_RANGE) - grub_error (GRUB_ERR_BAD_FS, "not a squash4"); - if (err) - return NULL; - if (sb.magic != grub_cpu_to_le32_compile_time (SQUASH_MAGIC) - || sb.block_size == 0 - || ((sb.block_size - 1) & sb.block_size)) - { - grub_error (GRUB_ERR_BAD_FS, "not squash4"); - return NULL; - } - - err = grub_disk_read (disk, - grub_le_to_cpu64 (sb.unk1offset) - >> GRUB_DISK_SECTOR_BITS, - grub_le_to_cpu64 (sb.unk1offset) - & (GRUB_DISK_SECTOR_SIZE - 1), sizeof (frag), &frag); - if (grub_errno == GRUB_ERR_OUT_OF_RANGE) - grub_error (GRUB_ERR_BAD_FS, "not a squash4"); - if (err) - return NULL; - - data = grub_zalloc (sizeof (*data)); - if (!data) - return NULL; - data->sb = sb; - data->disk = disk; - data->fragments = grub_le_to_cpu64 (frag); - - switch (sb.compression) - { - case grub_cpu_to_le16_compile_time (COMPRESSION_ZLIB): - data->decompress = zlib_decompress; - break; - case grub_cpu_to_le16_compile_time (COMPRESSION_LZO): - data->decompress = lzo_decompress; - break; - case grub_cpu_to_le16_compile_time (COMPRESSION_XZ): - data->decompress = xz_decompress; - data->xzbuf = grub_malloc (XZBUFSIZ); - if (!data->xzbuf) - { - grub_free (data); - return NULL; - } - data->xzdec = xz_dec_init (1 << 16); - if (!data->xzdec) - { - grub_free (data->xzbuf); - grub_free (data); - return NULL; - } - break; - default: - grub_free (data); - grub_error (GRUB_ERR_BAD_FS, "unsupported compression %d", - grub_le_to_cpu16 (sb.compression)); - return NULL; - } - - data->blksz = grub_le_to_cpu32 (data->sb.block_size); - for (data->log2_blksz = 0; - (1U << data->log2_blksz) < data->blksz; - data->log2_blksz++); - - return data; -} - -static char * -grub_squash_read_symlink (grub_fshelp_node_t node) -{ - char *ret; - grub_err_t err; - grub_uint32_t sz; - - if (grub_add (grub_le_to_cpu32 (node->ino.symlink.namelen), 1, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink name length overflow")); - return NULL; - } - - ret = grub_malloc (sz); - if (!ret) - return NULL; - - err = read_chunk (node->data, ret, - grub_le_to_cpu32 (node->ino.symlink.namelen), - grub_le_to_cpu64 (node->data->sb.inodeoffset) - + node->stack[node->stsize - 1].ino_chunk, - node->stack[node->stsize - 1].ino_offset - + (node->ino.symlink.name - (char *) &node->ino)); - if (err) - { - grub_free (ret); - return NULL; - } - ret[grub_le_to_cpu32 (node->ino.symlink.namelen)] = 0; - return ret; -} - -static int -grub_squash_iterate_dir (grub_fshelp_node_t dir, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data) -{ - grub_uint32_t off; - grub_uint32_t endoff; - grub_uint64_t chunk; - unsigned i; - - /* FIXME: why - 3 ? */ - switch (dir->ino.type) - { - case grub_cpu_to_le16_compile_time (SQUASH_TYPE_DIR): - off = grub_le_to_cpu16 (dir->ino.dir.offset); - endoff = grub_le_to_cpu16 (dir->ino.dir.size) + off - 3; - chunk = grub_le_to_cpu32 (dir->ino.dir.chunk); - break; - case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_DIR): - off = grub_le_to_cpu16 (dir->ino.long_dir.offset); - endoff = grub_le_to_cpu16 (dir->ino.long_dir.size) + off - 3; - chunk = grub_le_to_cpu32 (dir->ino.long_dir.chunk); - break; - default: - grub_error (GRUB_ERR_BAD_FS, "unexpected ino type 0x%x", - grub_le_to_cpu16 (dir->ino.type)); - return 0; - } - - { - grub_fshelp_node_t node; - grub_size_t sz; - - if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) || - grub_add (sz, sizeof (*node), &sz)) - return 0; - - node = grub_malloc (sz); - if (!node) - return 0; - grub_memcpy (node, dir, sz); - if (hook (".", GRUB_FSHELP_DIR, node, hook_data)) - return 1; - - if (dir->stsize != 1) - { - grub_err_t err; - - if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) || - grub_add (sz, sizeof (*node), &sz)) - return 0; - - node = grub_malloc (sz); - if (!node) - return 0; - - grub_memcpy (node, dir, sz); - - node->stsize--; - err = read_chunk (dir->data, &node->ino, sizeof (node->ino), - grub_le_to_cpu64 (dir->data->sb.inodeoffset) - + node->stack[node->stsize - 1].ino_chunk, - node->stack[node->stsize - 1].ino_offset); - if (err) - { - grub_free (node); - return 0; - } - - if (hook ("..", GRUB_FSHELP_DIR, node, hook_data)) - return 1; - } - } - - while (off < endoff) - { - struct grub_squash_dirent_header dh; - grub_err_t err; - - err = read_chunk (dir->data, &dh, sizeof (dh), - grub_le_to_cpu64 (dir->data->sb.diroffset) - + chunk, off); - if (err) - return 0; - off += sizeof (dh); - for (i = 0; i < (unsigned) grub_le_to_cpu32 (dh.nelems) + 1; i++) - { - char *buf; - int r; - struct grub_fshelp_node *node; - enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG; - struct grub_squash_dirent di; - struct grub_squash_inode ino; - grub_size_t sz; - grub_uint16_t nlen; - - err = read_chunk (dir->data, &di, sizeof (di), - grub_le_to_cpu64 (dir->data->sb.diroffset) - + chunk, off); - if (err) - return 0; - off += sizeof (di); - - err = read_chunk (dir->data, &ino, sizeof (ino), - grub_le_to_cpu64 (dir->data->sb.inodeoffset) - + grub_le_to_cpu32 (dh.ino_chunk), - grub_cpu_to_le16 (di.ino_offset)); - if (err) - return 0; - - if (grub_add (grub_le_to_cpu16 (di.namelen), 2, &nlen)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("name length overflow")); - return 0; - } - buf = grub_malloc (nlen); - if (!buf) - return 0; - err = read_chunk (dir->data, buf, - grub_le_to_cpu16 (di.namelen) + 1, - grub_le_to_cpu64 (dir->data->sb.diroffset) - + chunk, off); - if (err) - { - grub_free (buf); - return 0; - } - - off += grub_le_to_cpu16 (di.namelen) + 1; - buf[grub_le_to_cpu16 (di.namelen) + 1] = 0; - if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_DIR) - filetype = GRUB_FSHELP_DIR; - if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK) - filetype = GRUB_FSHELP_SYMLINK; - - if (grub_add (dir->stsize, 1, &sz) || - grub_mul (sz, sizeof (dir->stack[0]), &sz) || - grub_add (sz, sizeof (*node), &sz)) - { - grub_free (buf); - return 0; - } - - node = grub_malloc (sz); - if (! node) - { - grub_free (buf); - return 0; - } - - grub_memcpy (node, dir, sz - sizeof(dir->stack[0])); - - node->ino = ino; - node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk); - node->stack[node->stsize].ino_offset = grub_le_to_cpu16 (di.ino_offset); - node->stsize++; - r = hook (buf, filetype, node, hook_data); - - grub_free (buf); - if (r) - return r; - } - } - return 0; -} - -static grub_err_t -make_root_node (struct grub_squash_data *data, struct grub_fshelp_node *root) -{ - grub_memset (root, 0, sizeof (*root)); - root->data = data; - root->stsize = 1; - root->stack[0].ino_chunk = grub_le_to_cpu32 (data->sb.root_ino_chunk); - root->stack[0].ino_offset = grub_cpu_to_le16 (data->sb.root_ino_offset); - return read_chunk (data, &root->ino, sizeof (root->ino), - grub_le_to_cpu64 (data->sb.inodeoffset) - + root->stack[0].ino_chunk, - root->stack[0].ino_offset); -} - -static void -squash_unmount (struct grub_squash_data *data) -{ - if (data->xzdec) - xz_dec_end (data->xzdec); - grub_free (data->xzbuf); - grub_free (data->ino.cumulated_block_sizes); - grub_free (data->ino.block_sizes); - grub_free (data); -} - - -/* Context for grub_squash_dir. */ -struct grub_squash_dir_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; -}; - -/* Helper for grub_squash_dir. */ -static int -grub_squash_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, void *data) -{ - struct grub_squash_dir_ctx *ctx = data; - 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 = grub_le_to_cpu32 (node->ino.mtime); - grub_free (node); - return ctx->hook (filename, &info, ctx->hook_data); -} - -static grub_err_t -grub_squash_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_squash_dir_ctx ctx = { hook, hook_data }; - struct grub_squash_data *data = 0; - struct grub_fshelp_node *fdiro = 0; - struct grub_fshelp_node root; - grub_err_t err; - - data = squash_mount (device->disk); - if (! data) - return grub_errno; - - err = make_root_node (data, &root); - if (err) - return err; - - grub_fshelp_find_file (path, &root, &fdiro, grub_squash_iterate_dir, - grub_squash_read_symlink, GRUB_FSHELP_DIR); - if (!grub_errno) - grub_squash_iterate_dir (fdiro, grub_squash_dir_iter, &ctx); - - squash_unmount (data); - - return grub_errno; -} - -static grub_err_t -grub_squash_open (struct grub_file *file, const char *name) -{ - struct grub_squash_data *data = 0; - struct grub_fshelp_node *fdiro = 0; - struct grub_fshelp_node root; - grub_err_t err; - - data = squash_mount (file->device->disk); - if (! data) - return grub_errno; - - err = make_root_node (data, &root); - if (err) - return err; - - grub_fshelp_find_file (name, &root, &fdiro, grub_squash_iterate_dir, - grub_squash_read_symlink, GRUB_FSHELP_REG); - if (grub_errno) - { - squash_unmount (data); - return grub_errno; - } - - file->data = data; - data->ino.ino = fdiro->ino; - data->ino.block_sizes = NULL; - data->ino.cumulated_block_sizes = NULL; - data->ino.ino_chunk = fdiro->stack[fdiro->stsize - 1].ino_chunk; - data->ino.ino_offset = fdiro->stack[fdiro->stsize - 1].ino_offset; - - switch (fdiro->ino.type) - { - case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR): - file->size = grub_le_to_cpu64 (fdiro->ino.long_file.size); - break; - case grub_cpu_to_le16_compile_time (SQUASH_TYPE_REGULAR): - file->size = grub_le_to_cpu32 (fdiro->ino.file.size); - break; - default: - { - grub_uint16_t type = grub_le_to_cpu16 (fdiro->ino.type); - grub_free (fdiro); - squash_unmount (data); - return grub_error (GRUB_ERR_BAD_FS, "unexpected ino type 0x%x", type); - } - } - - grub_free (fdiro); - - return GRUB_ERR_NONE; -} - -static grub_ssize_t -direct_read (struct grub_squash_data *data, - struct grub_squash_cache_inode *ino, - grub_off_t off, char *buf, grub_size_t len) -{ - grub_err_t err = GRUB_ERR_NONE; - grub_off_t cumulated_uncompressed_size = 0; - grub_uint64_t a = 0; - grub_size_t i; - grub_size_t origlen = len; - - switch (ino->ino.type) - { - case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR): - a = grub_le_to_cpu64 (ino->ino.long_file.chunk); - break; - case grub_cpu_to_le16_compile_time (SQUASH_TYPE_REGULAR): - a = grub_le_to_cpu32 (ino->ino.file.chunk); - break; - } - - if (!ino->block_sizes) - { - grub_off_t total_size = 0; - grub_size_t total_blocks; - grub_size_t block_offset = 0; - switch (ino->ino.type) - { - case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR): - total_size = grub_le_to_cpu64 (ino->ino.long_file.size); - block_offset = ((char *) &ino->ino.long_file.block_size - - (char *) &ino->ino); - break; - case grub_cpu_to_le16_compile_time (SQUASH_TYPE_REGULAR): - total_size = grub_le_to_cpu32 (ino->ino.file.size); - block_offset = ((char *) &ino->ino.file.block_size - - (char *) &ino->ino); - break; - } - total_blocks = ((total_size + data->blksz - 1) >> data->log2_blksz); - ino->block_sizes = grub_calloc (total_blocks, - sizeof (ino->block_sizes[0])); - ino->cumulated_block_sizes = grub_calloc (total_blocks, - sizeof (ino->cumulated_block_sizes[0])); - if (!ino->block_sizes || !ino->cumulated_block_sizes) - { - grub_free (ino->block_sizes); - grub_free (ino->cumulated_block_sizes); - ino->block_sizes = 0; - ino->cumulated_block_sizes = 0; - return -1; - } - err = read_chunk (data, ino->block_sizes, - total_blocks * sizeof (ino->block_sizes[0]), - grub_le_to_cpu64 (data->sb.inodeoffset) - + ino->ino_chunk, - ino->ino_offset + block_offset); - if (err) - { - grub_free (ino->block_sizes); - grub_free (ino->cumulated_block_sizes); - ino->block_sizes = 0; - ino->cumulated_block_sizes = 0; - return -1; - } - ino->cumulated_block_sizes[0] = 0; - for (i = 1; i < total_blocks; i++) - ino->cumulated_block_sizes[i] = ino->cumulated_block_sizes[i - 1] - + (grub_le_to_cpu32 (ino->block_sizes[i - 1]) & ~SQUASH_BLOCK_FLAGS); - } - - if (a == 0) - a = sizeof (struct grub_squash_super); - i = off >> data->log2_blksz; - cumulated_uncompressed_size = data->blksz * (grub_disk_addr_t) i; - while (cumulated_uncompressed_size < off + len) - { - grub_size_t boff, curread; - boff = off - cumulated_uncompressed_size; - curread = data->blksz - boff; - if (curread > len) - curread = len; - if (!ino->block_sizes[i]) - { - /* Sparse block */ - grub_memset (buf, '\0', curread); - } - else if (!(ino->block_sizes[i] - & grub_cpu_to_le32_compile_time (SQUASH_BLOCK_UNCOMPRESSED))) - { - char *block; - grub_size_t csize; - csize = grub_le_to_cpu32 (ino->block_sizes[i]) & ~SQUASH_BLOCK_FLAGS; - block = grub_malloc (csize); - if (!block) - return -1; - err = grub_disk_read (data->disk, - (ino->cumulated_block_sizes[i] + a) - >> GRUB_DISK_SECTOR_BITS, - (ino->cumulated_block_sizes[i] + a) - & (GRUB_DISK_SECTOR_SIZE - 1), - csize, block); - if (err) - { - grub_free (block); - return -1; - } - if (data->decompress (block, csize, boff, buf, curread, data) - != (grub_ssize_t) curread) - { - grub_free (block); - if (!grub_errno) - grub_error (GRUB_ERR_BAD_FS, "incorrect compressed chunk"); - return -1; - } - grub_free (block); - } - else - err = grub_disk_read (data->disk, - (ino->cumulated_block_sizes[i] + a + boff) - >> GRUB_DISK_SECTOR_BITS, - (ino->cumulated_block_sizes[i] + a + boff) - & (GRUB_DISK_SECTOR_SIZE - 1), - curread, buf); - if (err) - return -1; - off += curread; - len -= curread; - buf += curread; - cumulated_uncompressed_size += grub_le_to_cpu32 (data->sb.block_size); - i++; - } - return origlen; -} - - -static grub_ssize_t -grub_squash_read (grub_file_t file, char *buf, grub_size_t len) -{ - struct grub_squash_data *data = file->data; - struct grub_squash_cache_inode *ino = &data->ino; - grub_off_t off = file->offset; - grub_err_t err; - grub_uint64_t a, b; - grub_uint32_t fragment = 0; - int compressed = 0; - struct grub_squash_frag_desc frag; - grub_off_t direct_len; - grub_uint64_t mask = grub_le_to_cpu32 (data->sb.block_size) - 1; - grub_size_t orig_len = len; - - switch (ino->ino.type) - { - case grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR): - fragment = grub_le_to_cpu32 (ino->ino.long_file.fragment); - break; - case grub_cpu_to_le16_compile_time (SQUASH_TYPE_REGULAR): - fragment = grub_le_to_cpu32 (ino->ino.file.fragment); - break; - } - - /* Squash may pack file tail as fragment. So read initial part directly and - get tail from fragments */ - direct_len = fragment == 0xffffffff ? file->size : file->size & ~mask; - if (off < direct_len) - { - grub_size_t read_len = direct_len - off; - grub_ssize_t res; - - if (read_len > len) - read_len = len; - res = direct_read (data, ino, off, buf, read_len); - if ((grub_size_t) res != read_len) - return -1; /* FIXME: is short read possible here? */ - len -= read_len; - if (!len) - return read_len; - buf += read_len; - off = 0; - } - else - off -= direct_len; - - err = read_chunk (data, &frag, sizeof (frag), - data->fragments, sizeof (frag) * fragment); - if (err) - return -1; - a = grub_le_to_cpu64 (frag.offset); - compressed = !(frag.size & grub_cpu_to_le32_compile_time (SQUASH_BLOCK_UNCOMPRESSED)); - if (ino->ino.type == grub_cpu_to_le16_compile_time (SQUASH_TYPE_LONG_REGULAR)) - b = grub_le_to_cpu32 (ino->ino.long_file.offset) + off; - else - b = grub_le_to_cpu32 (ino->ino.file.offset) + off; - - /* FIXME: cache uncompressed chunks. */ - if (compressed) - { - char *block; - block = grub_malloc (grub_le_to_cpu32 (frag.size)); - if (!block) - return -1; - err = grub_disk_read (data->disk, - a >> GRUB_DISK_SECTOR_BITS, - a & (GRUB_DISK_SECTOR_SIZE - 1), - grub_le_to_cpu32 (frag.size), block); - if (err) - { - grub_free (block); - return -1; - } - if (data->decompress (block, grub_le_to_cpu32 (frag.size), - b, buf, len, data) - != (grub_ssize_t) len) - { - grub_free (block); - if (!grub_errno) - grub_error (GRUB_ERR_BAD_FS, "incorrect compressed chunk"); - return -1; - } - grub_free (block); - } - else - { - err = grub_disk_read (data->disk, (a + b) >> GRUB_DISK_SECTOR_BITS, - (a + b) & (GRUB_DISK_SECTOR_SIZE - 1), len, buf); - if (err) - return -1; - } - return orig_len; -} - -static grub_err_t -grub_squash_close (grub_file_t file) -{ - squash_unmount (file->data); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_squash_mtime (grub_device_t dev, grub_int64_t *tm) -{ - struct grub_squash_data *data = 0; - - data = squash_mount (dev->disk); - if (! data) - return grub_errno; - *tm = grub_le_to_cpu32 (data->sb.creation_time); - squash_unmount (data); - return GRUB_ERR_NONE; -} - -static struct grub_fs grub_squash_fs = - { - .name = "squash4", - .fs_dir = grub_squash_dir, - .fs_open = grub_squash_open, - .fs_read = grub_squash_read, - .fs_close = grub_squash_close, - .fs_mtime = grub_squash_mtime, -#ifdef GRUB_UTIL - .reserved_first_sector = 0, - .blocklist_install = 0, -#endif - .next = 0 - }; - -GRUB_MOD_INIT(squash4) -{ - grub_squash_fs.mod = mod; - grub_fs_register (&grub_squash_fs); -} - -GRUB_MOD_FINI(squash4) -{ - grub_fs_unregister (&grub_squash_fs); -} - diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c deleted file mode 100644 index 1eaa5349f..000000000 --- a/grub-core/fs/tar.c +++ /dev/null @@ -1,373 +0,0 @@ -/* cpio.c - cpio and tar filesystem. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007,2008,2009,2013 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 . - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* tar support */ -#define MAGIC "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]; -} GRUB_PACKED; - -static inline unsigned long long -read_number (const char *str, grub_size_t size) -{ - unsigned long long ret = 0; - while (size-- && *str >= '0' && *str <= '7') - ret = (ret << 3) | (*str++ & 0xf); - return ret; -} - -struct grub_archelp_data -{ - grub_disk_t disk; - grub_off_t hofs, next_hofs; - grub_off_t dofs; - grub_off_t size; - char *linkname; - grub_size_t linkname_alloc; -}; - -static grub_err_t -grub_cpio_find_file (struct grub_archelp_data *data, char **name, - grub_int32_t *mtime, - grub_uint32_t *mode) -{ - struct head hd; - int reread = 0, have_longname = 0, have_longlink = 0; - grub_size_t sz; - - data->hofs = data->next_hofs; - *name = NULL; - - for (reread = 0; reread < 3; reread++) - { - if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd)) - return grub_errno; - - if (!hd.name[0] && !hd.prefix[0]) - { - *mode = GRUB_ARCHELP_ATTR_END; - return GRUB_ERR_NONE; - } - - if (grub_memcmp (hd.magic, MAGIC, sizeof (MAGIC) - 1)) - return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive"); - - if (hd.typeflag == 'L') - { - grub_err_t err; - grub_size_t namesize; - - if (grub_cast (read_number (hd.size, sizeof (hd.size)), &namesize) || - grub_add (namesize, 1, &sz)) - return grub_error (GRUB_ERR_BAD_FS, N_("name size overflow")); - - *name = grub_malloc (sz); - if (*name == NULL) - return grub_errno; - err = grub_disk_read (data->disk, 0, - data->hofs + GRUB_DISK_SECTOR_SIZE, namesize, - *name); - (*name)[namesize] = 0; - if (err) - return err; - data->hofs += GRUB_DISK_SECTOR_SIZE - + ((namesize + GRUB_DISK_SECTOR_SIZE - 1) & - ~(GRUB_DISK_SECTOR_SIZE - 1)); - have_longname = 1; - continue; - } - - if (hd.typeflag == 'K') - { - grub_err_t err; - grub_size_t linksize; - - if (grub_cast (read_number (hd.size, sizeof (hd.size)), &linksize) || - grub_add (linksize, 1, &sz)) - return grub_error (GRUB_ERR_BAD_FS, N_("link size overflow")); - - if (data->linkname_alloc < sz) - { - char *n; - n = grub_calloc (2, sz); - if (!n) - return grub_errno; - grub_free (data->linkname); - data->linkname = n; - data->linkname_alloc = 2 * (sz); - } - - err = grub_disk_read (data->disk, 0, - data->hofs + GRUB_DISK_SECTOR_SIZE, linksize, - data->linkname); - if (err) - return err; - data->linkname[linksize] = 0; - data->hofs += GRUB_DISK_SECTOR_SIZE - + ((linksize + GRUB_DISK_SECTOR_SIZE - 1) & - ~(GRUB_DISK_SECTOR_SIZE - 1)); - have_longlink = 1; - continue; - } - - if (!have_longname) - { - grub_size_t extra_size = 0; - - while (extra_size < sizeof (hd.prefix) - && hd.prefix[extra_size]) - extra_size++; - - if (grub_add (sizeof (hd.name) + 2, extra_size, &sz)) - return grub_error (GRUB_ERR_BAD_FS, N_("long name size overflow")); - *name = grub_malloc (sz); - if (*name == NULL) - return grub_errno; - if (hd.prefix[0]) - { - grub_memcpy (*name, hd.prefix, extra_size); - (*name)[extra_size++] = '/'; - } - grub_memcpy (*name + extra_size, hd.name, sizeof (hd.name)); - (*name)[extra_size + sizeof (hd.name)] = 0; - } - - if (grub_cast (read_number (hd.size, sizeof (hd.size)), &data->size)) - return grub_error (GRUB_ERR_BAD_FS, N_("data size overflow")); - - data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE; - data->next_hofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) & - ~(GRUB_DISK_SECTOR_SIZE - 1)); - if (mtime) - { - if (grub_cast (read_number (hd.mtime, sizeof (hd.mtime)), mtime)) - return grub_error (GRUB_ERR_BAD_FS, N_("mtime overflow")); - } - if (mode) - { - if (grub_cast (read_number (hd.mode, sizeof (hd.mode)), mode)) - return grub_error (GRUB_ERR_BAD_FS, N_("mode overflow")); - - switch (hd.typeflag) - { - /* Hardlink. */ - case '1': - /* Symlink. */ - case '2': - *mode |= GRUB_ARCHELP_ATTR_LNK; - break; - case '0': - *mode |= GRUB_ARCHELP_ATTR_FILE; - break; - case '5': - *mode |= GRUB_ARCHELP_ATTR_DIR; - break; - } - } - if (!have_longlink) - { - if (data->linkname_alloc < 101) - { - char *n; - n = grub_malloc (101); - if (!n) - return grub_errno; - grub_free (data->linkname); - data->linkname = n; - data->linkname_alloc = 101; - } - grub_memcpy (data->linkname, hd.linkname, sizeof (hd.linkname)); - data->linkname[100] = 0; - } - return GRUB_ERR_NONE; - } - - if (*name == NULL) - return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive"); - - return GRUB_ERR_NONE; -} - -static char * -grub_cpio_get_link_target (struct grub_archelp_data *data) -{ - return grub_strdup (data->linkname); -} - -static void -grub_cpio_rewind (struct grub_archelp_data *data) -{ - data->next_hofs = 0; -} - -static struct grub_archelp_ops arcops = - { - .find_file = grub_cpio_find_file, - .get_link_target = grub_cpio_get_link_target, - .rewind = grub_cpio_rewind - }; - -static struct grub_archelp_data * -grub_cpio_mount (grub_disk_t disk) -{ - struct head hd; - struct grub_archelp_data *data; - - if (grub_disk_read (disk, 0, 0, sizeof (hd), &hd)) - goto fail; - - if (grub_memcmp (hd.magic, MAGIC, sizeof (MAGIC) - 1)) - goto fail; - - data = (struct grub_archelp_data *) grub_zalloc (sizeof (*data)); - if (!data) - goto fail; - - data->disk = disk; - - return data; - -fail: - grub_error (GRUB_ERR_BAD_FS, "not a tarfs filesystem"); - return 0; -} - -static grub_err_t -grub_cpio_dir (grub_device_t device, const char *path_in, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_archelp_data *data; - grub_err_t err; - - data = grub_cpio_mount (device->disk); - if (!data) - return grub_errno; - - err = grub_archelp_dir (data, &arcops, - path_in, hook, hook_data); - - grub_free (data->linkname); - grub_free (data); - - return err; -} - -static grub_err_t -grub_cpio_open (grub_file_t file, const char *name_in) -{ - struct grub_archelp_data *data; - grub_err_t err; - - data = grub_cpio_mount (file->device->disk); - if (!data) - return grub_errno; - - err = grub_archelp_open (data, &arcops, name_in); - if (err) - { - grub_free (data->linkname); - grub_free (data); - } - else - { - file->data = data; - file->size = data->size; - } - return err; -} - -static grub_ssize_t -grub_cpio_read (grub_file_t file, char *buf, grub_size_t len) -{ - struct grub_archelp_data *data; - grub_ssize_t ret; - - data = file->data; - - data->disk->read_hook = file->read_hook; - data->disk->read_hook_data = file->read_hook_data; - ret = (grub_disk_read (data->disk, 0, data->dofs + file->offset, - len, buf)) ? -1 : (grub_ssize_t) len; - data->disk->read_hook = 0; - - return ret; -} - -static grub_err_t -grub_cpio_close (grub_file_t file) -{ - struct grub_archelp_data *data; - - data = file->data; - grub_free (data->linkname); - grub_free (data); - - return grub_errno; -} - -static struct grub_fs grub_cpio_fs = { - .name = "tarfs", - .fs_dir = grub_cpio_dir, - .fs_open = grub_cpio_open, - .fs_read = grub_cpio_read, - .fs_close = grub_cpio_close, -#ifdef GRUB_UTIL - .reserved_first_sector = 0, - .blocklist_install = 0, -#endif -}; - -GRUB_MOD_INIT (tar) -{ - grub_cpio_fs.mod = mod; - grub_fs_register (&grub_cpio_fs); -} - -GRUB_MOD_FINI (tar) -{ - grub_fs_unregister (&grub_cpio_fs); -} diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c deleted file mode 100644 index 3d5ee5af5..000000000 --- a/grub-core/fs/udf.c +++ /dev/null @@ -1,1471 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#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_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 - -#define GRUB_UDF_INVALID_STRUCT_PTR(_ptr, _struct) \ - ((char *) (_ptr) >= end_ptr || \ - ((grub_ssize_t) (end_ptr - (char *) (_ptr)) < (grub_ssize_t) sizeof (_struct))) - -struct grub_udf_lb_addr -{ - grub_uint32_t block_num; - grub_uint16_t part_ref; -} GRUB_PACKED; - -struct grub_udf_short_ad -{ - grub_uint32_t length; - grub_uint32_t position; -} GRUB_PACKED; - -struct grub_udf_long_ad -{ - grub_uint32_t length; - struct grub_udf_lb_addr block; - grub_uint8_t imp_use[6]; -} GRUB_PACKED; - -struct grub_udf_extent_ad -{ - grub_uint32_t length; - grub_uint32_t start; -} GRUB_PACKED; - -struct grub_udf_charspec -{ - grub_uint8_t charset_type; - grub_uint8_t charset_info[63]; -} GRUB_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; -} GRUB_PACKED; - -struct grub_udf_regid -{ - grub_uint8_t flags; - grub_uint8_t ident[23]; - grub_uint8_t ident_suffix[8]; -} GRUB_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; -} GRUB_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; -} GRUB_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; -} GRUB_PACKED; - -struct grub_udf_file_ident -{ - struct grub_udf_tag tag; - grub_uint16_t version_num; - grub_uint8_t characteristics; -#define MAX_FILE_IDENT_LENGTH 256 - grub_uint8_t file_ident_length; - struct grub_udf_long_ad icb; - grub_uint16_t imp_use_length; -} GRUB_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[0]; -} GRUB_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[0]; -} GRUB_PACKED; - -struct grub_udf_vrs -{ - grub_uint8_t type; - grub_uint8_t magic[5]; - grub_uint8_t version; -} GRUB_PACKED; - -struct grub_udf_avdp -{ - struct grub_udf_tag tag; - struct grub_udf_extent_ad vds; -} GRUB_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; -} GRUB_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; - }; -} GRUB_PACKED; - -struct grub_udf_pvd -{ - struct grub_udf_tag tag; - grub_uint32_t seq_num; - grub_uint32_t pvd_num; - grub_uint8_t ident[32]; - grub_uint16_t vol_seq_num; - grub_uint16_t max_vol_seq_num; - grub_uint16_t interchange_level; - grub_uint16_t max_interchange_level; - grub_uint32_t charset_list; - grub_uint32_t max_charset_list; - grub_uint8_t volset_ident[128]; - struct grub_udf_charspec desc_charset; - struct grub_udf_charspec expl_charset; - struct grub_udf_extent_ad vol_abstract; - struct grub_udf_extent_ad vol_copyright; - struct grub_udf_regid app_ident; - struct grub_udf_timestamp recording_time; - struct grub_udf_regid imp_ident; - grub_uint8_t imp_use[64]; - grub_uint32_t pred_vds_loc; - grub_uint16_t flags; - grub_uint8_t reserved[22]; -} GRUB_PACKED; - -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]; -} GRUB_PACKED; - -struct grub_udf_aed -{ - struct grub_udf_tag tag; - grub_uint32_t prev_ae; - grub_uint32_t ae_len; -} GRUB_PACKED; - -struct grub_udf_data -{ - grub_disk_t disk; - struct grub_udf_pvd pvd; - 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, lbshift; -}; - -struct grub_fshelp_node -{ - struct grub_udf_data *data; - int part_ref; - union - { - struct grub_udf_file_entry fe; - struct grub_udf_extended_file_entry efe; - char raw[0]; - } block; -}; - -static inline grub_size_t -get_fshelp_size (struct grub_udf_data *data) -{ - struct grub_fshelp_node *x = NULL; - return sizeof (*x) - + (1 << (GRUB_DISK_SECTOR_BITS - + data->lbshift)) - sizeof (x->block); -} - -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 << data->lbshift, 0, - 1 << (GRUB_DISK_SECTOR_BITS - + data->lbshift), - &node->block)) - return grub_errno; - - if ((U16 (node->block.fe.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FE) && - (U16 (node->block.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 *buf = NULL; - char *ptr; - grub_ssize_t len; - grub_disk_addr_t filebytes; - char *end_ptr; - - switch (U16 (node->block.fe.tag.tag_ident)) - { - case GRUB_UDF_TAG_IDENT_FE: - ptr = (char *) &node->block.fe.ext_attr[0] + U32 (node->block.fe.ext_attr_length); - len = U32 (node->block.fe.alloc_descs_length); - break; - - case GRUB_UDF_TAG_IDENT_EFE: - ptr = (char *) &node->block.efe.ext_attr[0] + U32 (node->block.efe.ext_attr_length); - len = U32 (node->block.efe.alloc_descs_length); - break; - - default: - grub_error (GRUB_ERR_BAD_FS, "invalid file entry"); - return 0; - } - - end_ptr = (char *) node + get_fshelp_size (node->data); - - if ((U16 (node->block.fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK) - == GRUB_UDF_ICBTAG_FLAG_AD_SHORT) - { - if (GRUB_UDF_INVALID_STRUCT_PTR (ptr, struct grub_udf_short_ad)) - { - grub_error (GRUB_ERR_BAD_FS, "corrupted UDF file system"); - return 0; - } - - struct grub_udf_short_ad *ad = (struct grub_udf_short_ad *) ptr; - - filebytes = fileblock * U32 (node->data->lvd.bsize); - while (len >= (grub_ssize_t) sizeof (struct grub_udf_short_ad)) - { - grub_uint32_t adlen = U32 (ad->length) & 0x3fffffff; - grub_uint32_t adtype = U32 (ad->length) >> 30; - if (adtype == 3) - { - struct grub_udf_aed *extension; - grub_disk_addr_t sec = grub_udf_get_block(node->data, - node->part_ref, - ad->position); - if (!buf) - { - buf = grub_malloc (U32 (node->data->lvd.bsize)); - if (!buf) - return 0; - } - if (grub_disk_read (node->data->disk, sec << node->data->lbshift, - 0, adlen, buf)) - goto fail; - - extension = (struct grub_udf_aed *) buf; - if (U16 (extension->tag.tag_ident) != GRUB_UDF_TAG_IDENT_AED) - { - grub_error (GRUB_ERR_BAD_FS, "invalid aed tag"); - goto fail; - } - - len = U32 (extension->ae_len); - /* - * Ensure AE length is less than block size - * per UDF spec v2.01 section 2.3.11. - * - * node->data->lbshift is initialized by - * grub_udf_mount(). lbshift has a maximum value - * of 3 and it does not cause an overflow here. - */ - if (len < 0 || len > ((grub_ssize_t) 1 << node->data->lbshift)) - { - grub_error (GRUB_ERR_BAD_FS, "invalid ae length"); - goto fail; - } - - ad = (struct grub_udf_short_ad *) - (buf + sizeof (struct grub_udf_aed)); - continue; - } - - if (filebytes < adlen) - { - grub_uint32_t ad_pos = ad->position; - grub_free (buf); - return ((U32 (ad_pos) & GRUB_UDF_EXT_MASK) ? 0 : - (grub_udf_get_block (node->data, node->part_ref, ad_pos) - + (filebytes >> (GRUB_DISK_SECTOR_BITS - + node->data->lbshift)))); - } - - filebytes -= adlen; - ad++; - len -= sizeof (struct grub_udf_short_ad); - - if (GRUB_UDF_INVALID_STRUCT_PTR (ad, struct grub_udf_short_ad)) - { - grub_error (GRUB_ERR_BAD_FS, "corrupted UDF file system"); - return 0; - } - } - } - else - { - if (GRUB_UDF_INVALID_STRUCT_PTR (ptr, struct grub_udf_long_ad)) - { - grub_error (GRUB_ERR_BAD_FS, "corrupted UDF file system"); - return 0; - } - - struct grub_udf_long_ad *ad = (struct grub_udf_long_ad *) ptr; - - filebytes = fileblock * U32 (node->data->lvd.bsize); - while (len >= (grub_ssize_t) sizeof (struct grub_udf_long_ad)) - { - grub_uint32_t adlen = U32 (ad->length) & 0x3fffffff; - grub_uint32_t adtype = U32 (ad->length) >> 30; - if (adtype == 3) - { - struct grub_udf_aed *extension; - grub_disk_addr_t sec = grub_udf_get_block(node->data, - ad->block.part_ref, - ad->block.block_num); - if (!buf) - { - buf = grub_malloc (U32 (node->data->lvd.bsize)); - if (!buf) - return 0; - } - if (grub_disk_read (node->data->disk, sec << node->data->lbshift, - 0, adlen, buf)) - goto fail; - - extension = (struct grub_udf_aed *) buf; - if (U16 (extension->tag.tag_ident) != GRUB_UDF_TAG_IDENT_AED) - { - grub_error (GRUB_ERR_BAD_FS, "invalid aed tag"); - goto fail; - } - - len = U32 (extension->ae_len); - /* - * Ensure AE length is less than block size - * per UDF spec v2.01 section 2.3.11. - * - * node->data->lbshift is initialized by - * grub_udf_mount(). lbshift has a maximum value - * of 3 and it does not cause an overflow here. - */ - if (len < 0 || len > ((grub_ssize_t) 1 << node->data->lbshift)) - { - grub_error (GRUB_ERR_BAD_FS, "invalid ae length"); - goto fail; - } - - ad = (struct grub_udf_long_ad *) - (buf + sizeof (struct grub_udf_aed)); - continue; - } - - if (filebytes < adlen) - { - grub_uint32_t ad_block_num = ad->block.block_num; - grub_uint32_t ad_part_ref = ad->block.part_ref; - grub_free (buf); - return ((U32 (ad_block_num) & GRUB_UDF_EXT_MASK) ? 0 : - (grub_udf_get_block (node->data, ad_part_ref, - ad_block_num) - + (filebytes >> (GRUB_DISK_SECTOR_BITS - + node->data->lbshift)))); - } - - filebytes -= adlen; - ad++; - len -= sizeof (struct grub_udf_long_ad); - - if (GRUB_UDF_INVALID_STRUCT_PTR (ad, struct grub_udf_long_ad)) - { - grub_error (GRUB_ERR_BAD_FS, "corrupted UDF file system"); - return 0; - } - } - } - -fail: - grub_free (buf); - - return 0; -} - -static grub_ssize_t -grub_udf_read_file (grub_fshelp_node_t node, - grub_disk_read_hook_t read_hook, void *read_hook_data, - grub_off_t pos, grub_size_t len, char *buf) -{ - switch (U16 (node->block.fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK) - { - case GRUB_UDF_ICBTAG_FLAG_AD_IN_ICB: - { - char *ptr; - char *end_ptr = (char *) node + get_fshelp_size (node->data); - - ptr = ((U16 (node->block.fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE) ? - ((char *) &node->block.fe.ext_attr[0] - + U32 (node->block.fe.ext_attr_length)) : - ((char *) &node->block.efe.ext_attr[0] - + U32 (node->block.efe.ext_attr_length))); - - if ((ptr + pos + len) > end_ptr) - { - grub_error (GRUB_ERR_BAD_FS, "corrupted UDF file system"); - return 0; - } - - 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, read_hook_data, - pos, len, buf, grub_udf_read_block, - U64 (node->block.fe.file_size), - node->data->lbshift, 0); -} - -static unsigned 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; - unsigned *sblklist; - grub_uint32_t block, vblock; - int i, lbshift; - - data = grub_malloc (sizeof (struct grub_udf_data)); - if (!data) - return 0; - - data->disk = disk; - - /* Search for Anchor Volume Descriptor Pointer (AVDP) - * and determine logical block size. */ - block = 0; - for (lbshift = 0; lbshift < 4; lbshift++) - { - for (sblklist = sblocklist; *sblklist; sblklist++) - { - struct grub_udf_avdp avdp; - - if (grub_disk_read (disk, *sblklist << lbshift, 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 && - U32 (avdp.tag.tag_location) == *sblklist) - { - block = U32 (avdp.vds.start); - break; - } - } - - if (block) - break; - } - - if (!block) - { - grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); - goto fail; - } - data->lbshift = lbshift; - - /* Search for Volume Recognition Sequence (VRS). */ - for (vblock = (32767 >> (lbshift + GRUB_DISK_SECTOR_BITS)) + 1;; - vblock += (2047 >> (lbshift + GRUB_DISK_SECTOR_BITS)) + 1) - { - struct grub_udf_vrs vrs; - - if (grub_disk_read (disk, vblock << lbshift, 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; - } - } - - 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 << lbshift, 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_PVD) - { - if (grub_disk_read (disk, block << lbshift, 0, - sizeof (struct grub_udf_pvd), - &data->pvd)) - { - grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); - goto fail; - } - } - else 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 << lbshift, 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 << lbshift, 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 << lbshift, 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; -} - -#ifdef GRUB_UTIL -grub_disk_addr_t -grub_udf_get_cluster_sector (grub_disk_t disk, grub_uint64_t *sec_per_lcn) -{ - grub_disk_addr_t ret; - static struct grub_udf_data *data; - - data = grub_udf_mount (disk); - if (!data) - return 0; - - ret = U32 (data->pds[data->pms[0]->type1.part_num].start); - *sec_per_lcn = 1ULL << data->lbshift; - grub_free (data); - return ret; -} -#endif - -static char * -read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf) -{ - grub_uint16_t *utf16 = NULL; - grub_size_t utf16len = 0; - - if (sz == 0) - return NULL; - - if (raw[0] != 8 && raw[0] != 16) - return NULL; - - if (raw[0] == 8) - { - unsigned i; - utf16len = sz - 1; - utf16 = grub_calloc (utf16len, sizeof (utf16[0])); - if (!utf16) - return NULL; - for (i = 0; i < utf16len; i++) - utf16[i] = raw[i + 1]; - } - if (raw[0] == 16) - { - unsigned i; - utf16len = (sz - 1) / 2; - utf16 = grub_calloc (utf16len, sizeof (utf16[0])); - if (!utf16) - return NULL; - for (i = 0; i < utf16len; i++) - utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2]; - } - if (!outbuf) - { - grub_size_t size; - - if (grub_mul (utf16len, GRUB_MAX_UTF8_PER_UTF16, &size) || - grub_add (size, 1, &size)) - goto fail; - - outbuf = grub_malloc (size); - } - if (outbuf) - *grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0'; - - fail: - grub_free (utf16); - return outbuf; -} - -static char * -read_dstring (const grub_uint8_t *raw, grub_size_t sz) -{ - grub_size_t len; - - if (raw[0] == 0) { - char *outbuf = grub_malloc (1); - if (!outbuf) - return NULL; - outbuf[0] = 0; - return outbuf; - } - - len = raw[sz - 1]; - if (len > sz - 1) - len = sz - 1; - return read_string (raw, len, NULL); -} - -static int -grub_udf_iterate_dir (grub_fshelp_node_t dir, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data) -{ - grub_fshelp_node_t child; - struct grub_udf_file_ident dirent; - grub_off_t offset = 0; - - child = grub_malloc (get_fshelp_size (dir->data)); - if (!child) - return 0; - - /* The current directory is not stored. */ - grub_memcpy (child, dir, get_fshelp_size (dir->data)); - - if (hook (".", GRUB_FSHELP_DIR, child, hook_data)) - return 1; - - while (offset < U64 (dir->block.fe.file_size)) - { - if (grub_udf_read_file (dir, 0, 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; - } - - offset += sizeof (dirent) + U16 (dirent.imp_use_length); - if (!(dirent.characteristics & GRUB_UDF_FID_CHAR_DELETED)) - { - child = grub_malloc (get_fshelp_size (dir->data)); - if (!child) - return 0; - - if (grub_udf_read_icb (dir->data, &dirent.icb, child)) - { - grub_free (child); - return 0; - } - if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT) - { - /* This is the parent directory. */ - if (hook ("..", GRUB_FSHELP_DIR, child, hook_data)) - return 1; - } - else - { - enum grub_fshelp_filetype type; - char *filename; - grub_uint8_t raw[MAX_FILE_IDENT_LENGTH]; - - type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ? - (GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG)); - if (child->block.fe.icbtag.file_type == GRUB_UDF_ICBTAG_TYPE_SYMLINK) - type = GRUB_FSHELP_SYMLINK; - - if ((grub_udf_read_file (dir, 0, 0, offset, - dirent.file_ident_length, - (char *) raw)) - != dirent.file_ident_length) - { - grub_free (child); - return 0; - } - - filename = read_string (raw, dirent.file_ident_length, 0); - if (!filename) - { - /* As the hook won't get called. */ - grub_free (child); - grub_print_error (); - } - - if (filename && hook (filename, type, child, hook_data)) - { - grub_free (filename); - return 1; - } - grub_free (filename); - } - } - - /* Align to dword boundary. */ - offset = (offset + dirent.file_ident_length + 3) & (~3); - } - - return 0; -} - -static char * -grub_udf_read_symlink (grub_fshelp_node_t node) -{ - grub_size_t s, sz = U64 (node->block.fe.file_size); - grub_uint8_t *raw; - const grub_uint8_t *ptr; - char *out = NULL, *optr; - - if (sz < 4) - return NULL; - raw = grub_malloc (sz); - if (!raw) - return NULL; - if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0) - goto fail_1; - - /* - * Local sz is the size of the symlink file data, which contains a sequence - * of path components (ECMA-167 14.16.1) representing the link destination. - * This size is an upper-bound on the number of bytes of a contained and - * potentially compressed UTF-16 character string. Allocate 2*sz for the - * output buffer containing the string converted to UTF-8 because the - * resulting string can not be more than double the size (2-byte unicode - * code points will be converted to a maximum of 3 bytes in UTF-8). - */ - if (grub_mul (sz, 2, &s)) - goto fail_0; - - out = grub_malloc (s); - if (!out) - { - fail_0: - grub_free (raw); - return NULL; - } - - optr = out; - - for (ptr = raw; ptr < raw + sz; ) - { - if ((grub_size_t) (ptr - raw + 4) > sz) - goto fail_1; - if (!(ptr[2] == 0 && ptr[3] == 0)) - goto fail_1; - s = 4 + ptr[1]; - if ((grub_size_t) (ptr - raw + s) > sz) - goto fail_1; - switch (*ptr) - { - case 1: - if (ptr[1]) - goto fail_1; - /* Fallthrough. */ - case 2: - /* in 4 bytes. out: 1 byte. */ - optr = out; - *optr++ = '/'; - break; - case 3: - /* in 4 bytes. out: 3 bytes. */ - if (optr != out) - *optr++ = '/'; - *optr++ = '.'; - *optr++ = '.'; - break; - case 4: - /* in 4 bytes. out: 2 bytes. */ - if (optr != out) - *optr++ = '/'; - *optr++ = '.'; - break; - case 5: - /* in 4 + n bytes. out, at most: 1 + 2 * n bytes. */ - if (optr != out) - *optr++ = '/'; - if (!read_string (ptr + 4, s - 4, optr)) - goto fail_1; - optr += grub_strlen (optr); - break; - default: - goto fail_1; - } - ptr += s; - } - *optr = 0; - grub_free (raw); - return out; - - fail_1: - grub_free (raw); - grub_free (out); - grub_error (GRUB_ERR_BAD_FS, "invalid symlink"); - return NULL; -} - -/* Context for grub_udf_dir. */ -struct grub_udf_dir_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; -}; - -/* Helper for grub_udf_dir. */ -static int -grub_udf_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, void *data) -{ - struct grub_udf_dir_ctx *ctx = data; - struct grub_dirhook_info info; - const struct grub_udf_timestamp *tstamp = NULL; - - grub_memset (&info, 0, sizeof (info)); - info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); - if (U16 (node->block.fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE) - tstamp = &node->block.fe.modification_time; - else if (U16 (node->block.fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_EFE) - tstamp = &node->block.efe.modification_time; - - if (tstamp && (U16 (tstamp->type_and_timezone) & 0xf000) == 0x1000) - { - grub_int16_t tz; - struct grub_datetime datetime; - - datetime.year = U16 (tstamp->year); - datetime.month = tstamp->month; - datetime.day = tstamp->day; - datetime.hour = tstamp->hour; - datetime.minute = tstamp->minute; - datetime.second = tstamp->second; - - tz = U16 (tstamp->type_and_timezone) & 0xfff; - if (tz & 0x800) - tz |= 0xf000; - if (tz == -2047) - tz = 0; - - info.mtimeset = !!grub_datetime2unixtime (&datetime, &info.mtime); - - info.mtime -= 60 * tz; - } - grub_free (node); - return ctx->hook (filename, &info, ctx->hook_data); -} - -static grub_err_t -grub_udf_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_udf_dir_ctx ctx = { hook, hook_data }; - struct grub_udf_data *data = 0; - struct grub_fshelp_node *rootnode = 0; - struct grub_fshelp_node *foundnode = 0; - - grub_dl_ref (my_mod); - - data = grub_udf_mount (device->disk); - if (!data) - goto fail; - - rootnode = grub_malloc (get_fshelp_size (data)); - if (!rootnode) - 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, grub_udf_read_symlink, - GRUB_FSHELP_DIR)) - goto fail; - - grub_udf_iterate_dir (foundnode, grub_udf_dir_iter, &ctx); - - if (foundnode != rootnode) - grub_free (foundnode); - -fail: - grub_free (rootnode); - - 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 = 0; - struct grub_fshelp_node *foundnode; - - grub_dl_ref (my_mod); - - data = grub_udf_mount (file->device->disk); - if (!data) - goto fail; - - rootnode = grub_malloc (get_fshelp_size (data)); - if (!rootnode) - 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, grub_udf_read_symlink, - GRUB_FSHELP_REG)) - goto fail; - - file->data = foundnode; - file->offset = 0; - file->size = U64 (foundnode->block.fe.file_size); - - grub_free (rootnode); - - return 0; - -fail: - grub_dl_unref (my_mod); - - grub_free (data); - grub_free (rootnode); - - 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->read_hook_data, - 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 = read_dstring (data->lvd.ident, sizeof (data->lvd.ident)); - grub_free (data); - } - else - *label = 0; - - return grub_errno; -} - -static char * -gen_uuid_from_volset (char *volset_ident) -{ - grub_size_t i; - grub_size_t len; - grub_size_t nonhexpos; - grub_uint8_t buf[17]; - char *uuid; - - len = grub_strlen (volset_ident); - if (len < 8) - return NULL; - - uuid = grub_malloc (17); - if (!uuid) - return NULL; - - if (len > 16) - len = 16; - - grub_memset (buf, 0, sizeof (buf)); - grub_memcpy (buf, volset_ident, len); - - nonhexpos = 16; - for (i = 0; i < 16; ++i) - { - if (!grub_isxdigit (buf[i])) - { - nonhexpos = i; - break; - } - } - - if (nonhexpos < 8) - { - grub_snprintf (uuid, 17, "%02x%02x%02x%02x%02x%02x%02x%02x", - buf[0], buf[1], buf[2], buf[3], - buf[4], buf[5], buf[6], buf[7]); - } - else if (nonhexpos < 16) - { - for (i = 0; i < 8; ++i) - uuid[i] = grub_tolower (buf[i]); - grub_snprintf (uuid+8, 9, "%02x%02x%02x%02x", - buf[8], buf[9], buf[10], buf[11]); - } - else - { - for (i = 0; i < 16; ++i) - uuid[i] = grub_tolower (buf[i]); - uuid[16] = 0; - } - - return uuid; -} - -static grub_err_t -grub_udf_uuid (grub_device_t device, char **uuid) -{ - char *volset_ident; - struct grub_udf_data *data; - data = grub_udf_mount (device->disk); - - if (data) - { - volset_ident = read_dstring (data->pvd.volset_ident, sizeof (data->pvd.volset_ident)); - if (volset_ident) - { - *uuid = gen_uuid_from_volset (volset_ident); - grub_free (volset_ident); - } - else - *uuid = 0; - grub_free (data); - } - else - *uuid = 0; - - return grub_errno; -} - -static struct grub_fs grub_udf_fs = { - .name = "udf", - .fs_dir = grub_udf_dir, - .fs_open = grub_udf_open, - .fs_read = grub_udf_read, - .fs_close = grub_udf_close, - .fs_label = grub_udf_label, - .fs_uuid = grub_udf_uuid, -#ifdef GRUB_UTIL - .reserved_first_sector = 1, - .blocklist_install = 1, -#endif - .next = 0 -}; - -GRUB_MOD_INIT (udf) -{ - if (!grub_is_lockdown ()) - { - grub_udf_fs.mod = mod; - grub_fs_register (&grub_udf_fs); - } - my_mod = mod; -} - -GRUB_MOD_FINI (udf) -{ - if (!grub_is_lockdown ()) - grub_fs_unregister (&grub_udf_fs); -} diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c deleted file mode 100644 index 1bc4017ca..000000000 --- a/grub-core/fs/xfs.c +++ /dev/null @@ -1,1350 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define XFS_INODE_EXTENTS 9 - -#define XFS_INODE_FORMAT_INO 1 -#define XFS_INODE_FORMAT_EXT 2 -#define XFS_INODE_FORMAT_BTREE 3 - -/* Superblock version field flags */ -#define XFS_SB_VERSION_NUMBITS 0x000f -#define XFS_SB_VERSION_ATTRBIT 0x0010 -#define XFS_SB_VERSION_NLINKBIT 0x0020 -#define XFS_SB_VERSION_QUOTABIT 0x0040 -#define XFS_SB_VERSION_ALIGNBIT 0x0080 -#define XFS_SB_VERSION_DALIGNBIT 0x0100 -#define XFS_SB_VERSION_LOGV2BIT 0x0400 -#define XFS_SB_VERSION_SECTORBIT 0x0800 -#define XFS_SB_VERSION_EXTFLGBIT 0x1000 -#define XFS_SB_VERSION_DIRV2BIT 0x2000 -#define XFS_SB_VERSION_MOREBITSBIT 0x8000 -#define XFS_SB_VERSION_BITS_SUPPORTED \ - (XFS_SB_VERSION_NUMBITS | \ - XFS_SB_VERSION_ATTRBIT | \ - XFS_SB_VERSION_NLINKBIT | \ - XFS_SB_VERSION_QUOTABIT | \ - XFS_SB_VERSION_ALIGNBIT | \ - XFS_SB_VERSION_DALIGNBIT | \ - XFS_SB_VERSION_LOGV2BIT | \ - XFS_SB_VERSION_SECTORBIT | \ - XFS_SB_VERSION_EXTFLGBIT | \ - XFS_SB_VERSION_DIRV2BIT | \ - XFS_SB_VERSION_MOREBITSBIT) - -/* Recognized xfs format versions */ -#define XFS_SB_VERSION_4 4 /* Good old XFS filesystem */ -#define XFS_SB_VERSION_5 5 /* CRC enabled filesystem */ - -/* features2 field flags */ -#define XFS_SB_VERSION2_LAZYSBCOUNTBIT 0x00000002 /* Superblk counters */ -#define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ -#define XFS_SB_VERSION2_PROJID32BIT 0x00000080 /* 32-bit project ids */ -#define XFS_SB_VERSION2_FTYPE 0x00000200 /* inode type in dir */ -#define XFS_SB_VERSION2_BITS_SUPPORTED \ - (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \ - XFS_SB_VERSION2_ATTR2BIT | \ - XFS_SB_VERSION2_PROJID32BIT | \ - XFS_SB_VERSION2_FTYPE) - -/* Inode flags2 flags */ -#define XFS_DIFLAG2_BIGTIME_BIT 3 -#define XFS_DIFLAG2_BIGTIME (1 << XFS_DIFLAG2_BIGTIME_BIT) -#define XFS_DIFLAG2_NREXT64_BIT 4 -#define XFS_DIFLAG2_NREXT64 (1 << XFS_DIFLAG2_NREXT64_BIT) - -/* incompat feature flags */ -#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ -#define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */ -#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */ -#define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */ -#define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4) /* needs xfs_repair */ -#define XFS_SB_FEAT_INCOMPAT_NREXT64 (1 << 5) /* large extent counters */ -#define XFS_SB_FEAT_INCOMPAT_EXCHRANGE (1 << 6) /* exchangerange supported */ -#define XFS_SB_FEAT_INCOMPAT_PARENT (1 << 7) /* parent pointers */ -#define XFS_SB_FEAT_INCOMPAT_METADIR (1 << 8) /* metadata dir tree */ - -/* - * Directory entries with ftype are explicitly handled by GRUB code. - * - * We do not currently read the inode btrees, so it is safe to read filesystems - * with the XFS_SB_FEAT_INCOMPAT_SPINODES feature. - * - * We do not currently verify metadata UUID, so it is safe to read filesystems - * with the XFS_SB_FEAT_INCOMPAT_META_UUID feature. - * - * We do not currently replay the log, so it is safe to read filesystems - * with the XFS_SB_FEAT_INCOMPAT_EXCHRANGE feature. - * - * We do not currently read directory parent pointers, so it is safe to read - * filesystems with the XFS_SB_FEAT_INCOMPAT_PARENT feature. - * - * We do not currently look at realtime or quota metadata, so it is safe to - * read filesystems with the XFS_SB_FEAT_INCOMPAT_METADIR feature. - */ -#define XFS_SB_FEAT_INCOMPAT_SUPPORTED \ - (XFS_SB_FEAT_INCOMPAT_FTYPE | \ - XFS_SB_FEAT_INCOMPAT_SPINODES | \ - XFS_SB_FEAT_INCOMPAT_META_UUID | \ - XFS_SB_FEAT_INCOMPAT_BIGTIME | \ - XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR | \ - XFS_SB_FEAT_INCOMPAT_NREXT64 | \ - XFS_SB_FEAT_INCOMPAT_EXCHRANGE | \ - XFS_SB_FEAT_INCOMPAT_PARENT | \ - XFS_SB_FEAT_INCOMPAT_METADIR) - -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[12]; - grub_uint16_t version; - grub_uint8_t unused5[6]; - 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; - grub_uint8_t unused7[7]; - grub_uint32_t features2; - grub_uint8_t unused8[4]; - grub_uint32_t sb_features_compat; - grub_uint32_t sb_features_ro_compat; - grub_uint32_t sb_features_incompat; - grub_uint32_t sb_features_log_incompat; -} GRUB_PACKED; - -struct grub_xfs_dir_header -{ - grub_uint8_t count; - grub_uint8_t largeino; - union - { - grub_uint32_t i4; - grub_uint64_t i8; - } GRUB_PACKED parent; -} GRUB_PACKED; - -/* Structure for directory entry inlined in the inode */ -struct grub_xfs_dir_entry -{ - grub_uint8_t len; - grub_uint16_t offset; - char name[1]; - /* Inode number follows, 32 / 64 bits. */ -} GRUB_PACKED; - -/* Structure for directory entry in a block */ -struct grub_xfs_dir2_entry -{ - grub_uint64_t inode; - grub_uint8_t len; -} GRUB_PACKED; - -struct grub_xfs_extent -{ - /* This should be a bitfield but bietfields are unportable, so just have - a raw array and functions extracting useful info from it. - */ - grub_uint32_t raw[4]; -} GRUB_PACKED; - -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; - /* In V5 here follow crc, uuid, etc. */ - /* Then follow keys and block pointers */ -} GRUB_PACKED; - -struct grub_xfs_btree_root -{ - grub_uint16_t level; - grub_uint16_t numrecs; - grub_uint64_t keys[1]; -} GRUB_PACKED; - -struct grub_xfs_time_legacy -{ - grub_uint32_t sec; - grub_uint32_t nanosec; -} GRUB_PACKED; - -/* - * The struct grub_xfs_inode layout was taken from the - * struct xfs_dinode_core which is described here: - * https://mirrors.edge.kernel.org/pub/linux/utils/fs/xfs/docs/xfs_filesystem_structure.pdf - */ -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[18]; - grub_uint64_t nextents_big; - grub_uint64_t atime; - grub_uint64_t mtime; - grub_uint64_t ctime; - grub_uint64_t size; - grub_uint64_t nblocks; - grub_uint32_t extsize; - grub_uint32_t nextents; - grub_uint16_t unused3; - grub_uint8_t fork_offset; - grub_uint8_t unused4[17]; /* Last member of inode v2. */ - grub_uint8_t unused5[20]; /* First member of inode v3. */ - grub_uint64_t flags2; - grub_uint8_t unused6[48]; /* Last member of inode v3. */ -} GRUB_PACKED; - -#define XFS_V3_INODE_SIZE sizeof(struct grub_xfs_inode) -/* Size of struct grub_xfs_inode v2, up to unused4 member included. */ -#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 76) - -struct grub_xfs_dir_leaf_entry -{ - grub_uint32_t hashval; - grub_uint32_t address; -} GRUB_PACKED; - -struct grub_xfs_dirblock_tail -{ - grub_uint32_t leaf_count; - grub_uint32_t leaf_stale; -} GRUB_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 -{ - grub_size_t data_size; - struct grub_xfs_sblock sblock; - grub_disk_t disk; - int pos; - int bsize; - grub_uint32_t agsize; - unsigned int hasftype:1; - unsigned int hascrc:1; - struct grub_fshelp_node diropen; -}; - -static grub_dl_t my_mod; - - - -static int grub_xfs_sb_hascrc(struct grub_xfs_data *data) -{ - return (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) == - grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5); -} - -static int grub_xfs_sb_hasftype(struct grub_xfs_data *data) -{ - if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) == - grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5) && - data->sblock.sb_features_incompat & grub_cpu_to_be32_compile_time(XFS_SB_FEAT_INCOMPAT_FTYPE)) - return 1; - if (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_MOREBITSBIT) && - data->sblock.features2 & grub_cpu_to_be32_compile_time(XFS_SB_VERSION2_FTYPE)) - return 1; - return 0; -} - -static int grub_xfs_sb_valid(struct grub_xfs_data *data) -{ - grub_dprintf("xfs", "Validating superblock\n"); - if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4) - || data->sblock.log2_bsize < GRUB_DISK_SECTOR_BITS - || ((int) data->sblock.log2_bsize - + (int) data->sblock.log2_dirblk) >= 27) - { - grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem"); - return 0; - } - if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) == - grub_cpu_to_be16_compile_time(XFS_SB_VERSION_5)) - { - grub_dprintf("xfs", "XFS v5 superblock detected\n"); - if (data->sblock.sb_features_incompat & - grub_cpu_to_be32_compile_time(~XFS_SB_FEAT_INCOMPAT_SUPPORTED)) - { - grub_error (GRUB_ERR_BAD_FS, "XFS filesystem has unsupported " - "incompatible features"); - return 0; - } - return 1; - } - else if ((data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_NUMBITS)) == - grub_cpu_to_be16_compile_time(XFS_SB_VERSION_4)) - { - grub_dprintf("xfs", "XFS v4 superblock detected\n"); - if (!(data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_DIRV2BIT))) - { - grub_error (GRUB_ERR_BAD_FS, "XFS filesystem without V2 directories " - "is unsupported"); - return 0; - } - if (data->sblock.version & grub_cpu_to_be16_compile_time(~XFS_SB_VERSION_BITS_SUPPORTED) || - (data->sblock.version & grub_cpu_to_be16_compile_time(XFS_SB_VERSION_MOREBITSBIT) && - data->sblock.features2 & grub_cpu_to_be16_compile_time(~XFS_SB_VERSION2_BITS_SUPPORTED))) - { - grub_error (GRUB_ERR_BAD_FS, "XFS filesystem has unsupported version " - "bits"); - return 0; - } - return 1; - } - - grub_error (GRUB_ERR_BAD_FS, "unsupported XFS filesystem version"); - return 0; -} - -static int -grub_xfs_sb_needs_repair (struct grub_xfs_data *data) -{ - return ((data->sblock.version & - grub_cpu_to_be16_compile_time (XFS_SB_VERSION_NUMBITS)) == - grub_cpu_to_be16_compile_time (XFS_SB_VERSION_5) && - (data->sblock.sb_features_incompat & - grub_cpu_to_be32_compile_time (XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR))); -} - -/* 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 - -static inline int -GRUB_XFS_INO_AGBITS(struct grub_xfs_data *data) -{ - return ((data)->sblock.log2_agblk + (data)->sblock.log2_inop); -} - -static inline grub_uint64_t -GRUB_XFS_INO_INOINAG (struct grub_xfs_data *data, - grub_uint64_t ino) -{ - return (ino & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1)); -} - -static inline grub_uint64_t -GRUB_XFS_INO_AG (struct grub_xfs_data *data, - grub_uint64_t ino) -{ - return (ino >> GRUB_XFS_INO_AGBITS (data)); -} - -static inline grub_disk_addr_t -GRUB_XFS_FSB_TO_BLOCK (struct grub_xfs_data *data, grub_disk_addr_t fsb) -{ - return ((fsb >> data->sblock.log2_agblk) * data->agsize - + (fsb & ((1LL << data->sblock.log2_agblk) - 1))); -} - -static inline grub_uint64_t -GRUB_XFS_EXTENT_OFFSET (struct grub_xfs_extent *exts, int ex) -{ - return ((grub_be_to_cpu32 (exts[ex].raw[0]) & ~(1 << 31)) << 23 - | grub_be_to_cpu32 (exts[ex].raw[1]) >> 9); -} - -static inline grub_uint64_t -GRUB_XFS_EXTENT_BLOCK (struct grub_xfs_extent *exts, int ex) -{ - return ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex].raw[1]) - & (0x1ff)) << 43 - | (grub_uint64_t) grub_be_to_cpu32 (exts[ex].raw[2]) << 11 - | grub_be_to_cpu32 (exts[ex].raw[3]) >> 21); -} - -static inline grub_uint64_t -GRUB_XFS_EXTENT_SIZE (struct grub_xfs_extent *exts, int ex) -{ - return (grub_be_to_cpu32 (exts[ex].raw[3]) & ((1 << 21) - 1)); -} - - -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 inline grub_size_t -grub_xfs_inode_size(struct grub_xfs_data *data) -{ - return (grub_size_t)1 << data->sblock.log2_inode; -} - -/* - * Returns size occupied by XFS inode stored in memory - we store struct - * grub_fshelp_node there but on disk inode size may be actually larger than - * struct grub_xfs_inode so we need to account for that so that we can read - * from disk directly into in-memory structure. - */ -static inline grub_size_t -grub_xfs_fshelp_size(struct grub_xfs_data *data) -{ - return sizeof (struct grub_fshelp_node) - sizeof (struct grub_xfs_inode) - + grub_xfs_inode_size(data); -} - -/* This should return void * but XFS code is error-prone with alignment, so - return char to retain cast-align. - */ -static char * -grub_xfs_inode_data(struct grub_xfs_inode *inode) -{ - if (inode->version <= 2) - return ((char *)inode) + XFS_V2_INODE_SIZE; - return ((char *)inode) + XFS_V3_INODE_SIZE; -} - -static struct grub_xfs_dir_entry * -grub_xfs_inline_de(struct grub_xfs_dir_header *head) -{ - /* - With small inode numbers the header is 4 bytes smaller because of - smaller parent pointer - */ - return (struct grub_xfs_dir_entry *) - (((char *) head) + sizeof(struct grub_xfs_dir_header) - - (head->largeino ? 0 : sizeof(grub_uint32_t))); -} - -static grub_uint8_t * -grub_xfs_inline_de_inopos(struct grub_xfs_data *data, - struct grub_xfs_dir_entry *de) -{ - return ((grub_uint8_t *)(de + 1)) + de->len - 1 + (data->hasftype ? 1 : 0); -} - -static struct grub_xfs_dir_entry * -grub_xfs_inline_next_de(struct grub_xfs_data *data, - struct grub_xfs_dir_header *head, - struct grub_xfs_dir_entry *de) -{ - char *p = (char *)de + sizeof(struct grub_xfs_dir_entry) - 1 + de->len; - - p += head->largeino ? sizeof(grub_uint64_t) : sizeof(grub_uint32_t); - if (data->hasftype) - p++; - - return (struct grub_xfs_dir_entry *)p; -} - -static struct grub_xfs_dirblock_tail * -grub_xfs_dir_tail(struct grub_xfs_data *data, void *dirblock) -{ - int dirblksize = 1 << (data->sblock.log2_bsize + data->sblock.log2_dirblk); - - return (struct grub_xfs_dirblock_tail *) - ((char *)dirblock + dirblksize - sizeof (struct grub_xfs_dirblock_tail)); -} - -static struct grub_xfs_dir2_entry * -grub_xfs_first_de(struct grub_xfs_data *data, void *dirblock) -{ - if (data->hascrc) - return (struct grub_xfs_dir2_entry *)((char *)dirblock + 64); - return (struct grub_xfs_dir2_entry *)((char *)dirblock + 16); -} - -static struct grub_xfs_dir2_entry * -grub_xfs_next_de(struct grub_xfs_data *data, struct grub_xfs_dir2_entry *de) -{ - int size = sizeof (struct grub_xfs_dir2_entry) + de->len + 2 /* Tag */; - - if (data->hasftype) - size++; /* File type */ - return (struct grub_xfs_dir2_entry *)(((char *)de) + ALIGN_UP(size, 8)); -} - -/* This should return void * but XFS code is error-prone with alignment, so - return char to retain cast-align. - */ -static char * -grub_xfs_btree_keys(struct grub_xfs_data *data, - struct grub_xfs_btree_node *leaf) -{ - char *keys = (char *)(leaf + 1); - - if (data->hascrc) - keys += 48; /* skip crc, uuid, ... */ - return keys; -} - -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); - - grub_dprintf("xfs", "Reading inode (%" PRIuGRUB_UINT64_T ") - %" PRIuGRUB_UINT64_T ", %d\n", - ino, block, offset); - /* Read the inode. */ - if (grub_disk_read (data->disk, block, offset, grub_xfs_inode_size(data), - 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_uint64_t -get_fsb (const void *keys, int idx) -{ - const char *p = (const char *) keys + sizeof(grub_uint64_t) * idx; - return grub_be_to_cpu64 (grub_get_unaligned64 (p)); -} - -static int -grub_xfs_inode_has_large_extent_counts (const struct grub_xfs_inode *inode) -{ - return inode->version >= 3 && - (inode->flags2 & grub_cpu_to_be64_compile_time (XFS_DIFLAG2_NREXT64)); -} - -static grub_uint64_t -grub_xfs_get_inode_nextents (struct grub_xfs_inode *inode) -{ - return (grub_xfs_inode_has_large_extent_counts (inode)) ? - grub_be_to_cpu64 (inode->nextents_big) : - grub_be_to_cpu32 (inode->nextents); -} - -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; - grub_uint64_t ex, nrec; - struct grub_xfs_extent *exts; - grub_uint64_t ret = 0; - - if (node->inode.format == XFS_INODE_FORMAT_BTREE) - { - struct grub_xfs_btree_root *root; - const char *keys; - int recoffset; - - leaf = grub_malloc (node->data->bsize); - if (leaf == 0) - return 0; - - root = (struct grub_xfs_btree_root *) grub_xfs_inode_data(&node->inode); - nrec = grub_be_to_cpu16 (root->numrecs); - keys = (char *) &root->keys[0]; - if (node->inode.fork_offset) - recoffset = (node->inode.fork_offset - 1) / 2; - else - recoffset = (grub_xfs_inode_size(node->data) - - ((char *) keys - (char *) &node->inode)) - / (2 * sizeof (grub_uint64_t)); - do - { - grub_uint64_t i; - grub_addr_t keys_end, data_end; - - if (grub_mul (sizeof (grub_uint64_t), nrec, &keys_end) || - grub_add ((grub_addr_t) keys, keys_end, &keys_end) || - grub_add ((grub_addr_t) node->data, node->data->data_size, &data_end) || - keys_end > data_end) - { - grub_error (GRUB_ERR_BAD_FS, "invalid number of XFS root keys"); - grub_free (leaf); - return 0; - } - - for (i = 0; i < nrec; i++) - { - if (fileblock < get_fsb(keys, i)) - break; - } - - /* Sparse block. */ - if (i == 0) - { - grub_free (leaf); - return 0; - } - - if (grub_disk_read (node->data->disk, - GRUB_XFS_FSB_TO_BLOCK (node->data, get_fsb (keys, i - 1 + recoffset)) << (node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS), - 0, node->data->bsize, leaf)) - { - grub_free (leaf); - return 0; - } - - if ((!node->data->hascrc && - grub_strncmp ((char *) leaf->magic, "BMAP", 4)) || - (node->data->hascrc && - grub_strncmp ((char *) leaf->magic, "BMA3", 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 = grub_xfs_btree_keys(node->data, leaf); - recoffset = ((node->data->bsize - ((char *) keys - - (char *) leaf)) - / (2 * sizeof (grub_uint64_t))); - } - while (leaf->level); - exts = (struct grub_xfs_extent *) keys; - } - else if (node->inode.format == XFS_INODE_FORMAT_EXT) - { - grub_addr_t exts_end = 0; - grub_addr_t data_end = 0; - - nrec = grub_xfs_get_inode_nextents (&node->inode); - exts = (struct grub_xfs_extent *) grub_xfs_inode_data(&node->inode); - - if (grub_mul (sizeof (struct grub_xfs_extent), nrec, &exts_end) || - grub_add ((grub_addr_t) node->data, exts_end, &exts_end) || - grub_add ((grub_addr_t) node->data, node->data->data_size, &data_end) || - exts_end > data_end) - { - grub_error (GRUB_ERR_BAD_FS, "invalid number of XFS extents"); - return 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; - } - } - - 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, - grub_disk_read_hook_t read_hook, void *read_hook_data, - grub_off_t pos, grub_size_t len, char *buf, grub_uint32_t header_size) -{ - return grub_fshelp_read_file (node->data->disk, node, - read_hook, read_hook_data, - pos, len, buf, grub_xfs_read_block, - grub_be_to_cpu64 (node->inode.size) + header_size, - node->data->sblock.log2_bsize - - GRUB_DISK_SECTOR_BITS, 0); -} - - -static char * -grub_xfs_read_symlink (grub_fshelp_node_t node) -{ - grub_ssize_t size = grub_be_to_cpu64 (node->inode.size); - grub_size_t sz; - - if (size < 0) - { - grub_error (GRUB_ERR_BAD_FS, "invalid symlink"); - return 0; - } - - switch (node->inode.format) - { - case XFS_INODE_FORMAT_INO: - return grub_strndup (grub_xfs_inode_data(&node->inode), size); - - case XFS_INODE_FORMAT_EXT: - { - char *symlink; - grub_ssize_t numread; - int off = 0; - - if (node->data->hascrc) - off = 56; - - if (grub_add (size, 1, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink size overflow")); - return 0; - } - symlink = grub_malloc (sz); - if (!symlink) - return 0; - - node->inode.size = grub_be_to_cpu64 (size + off); - numread = grub_xfs_read_file (node, 0, 0, off, size, symlink, off); - 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; -} - - -/* Context for grub_xfs_iterate_dir. */ -struct grub_xfs_iterate_dir_ctx -{ - grub_fshelp_iterate_dir_hook_t hook; - void *hook_data; - struct grub_fshelp_node *diro; -}; - -/* Helper for grub_xfs_iterate_dir. */ -static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename, - struct grub_xfs_iterate_dir_ctx *ctx) -{ - struct grub_fshelp_node *fdiro; - grub_err_t err; - grub_size_t sz; - - if (grub_add (grub_xfs_fshelp_size(ctx->diro->data), 1, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory data size overflow")); - grub_print_error (); - return 0; - } - fdiro = grub_malloc (sz); - if (!fdiro) - { - grub_print_error (); - return 0; - } - - /* The inode should be read, otherwise the filetype can - not be determined. */ - fdiro->ino = ino; - fdiro->inode_read = 1; - fdiro->data = ctx->diro->data; - err = grub_xfs_read_inode (ctx->diro->data, ino, &fdiro->inode); - if (err) - { - grub_print_error (); - grub_free (fdiro); - return 0; - } - - return ctx->hook (filename, grub_xfs_mode_to_filetype (fdiro->inode.mode), - fdiro, ctx->hook_data); -} - -static int -grub_xfs_iterate_dir (grub_fshelp_node_t dir, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data) -{ - struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; - struct grub_xfs_iterate_dir_ctx ctx = { - .hook = hook, - .hook_data = hook_data, - .diro = diro - }; - - switch (diro->inode.format) - { - case XFS_INODE_FORMAT_INO: - { - struct grub_xfs_dir_header *head = (struct grub_xfs_dir_header *) grub_xfs_inode_data(&diro->inode); - struct grub_xfs_dir_entry *de = grub_xfs_inline_de(head); - int smallino = !head->largeino; - 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 (head->parent.i4); - else - parent = grub_be_to_cpu64 (head->parent.i8); - - /* Synthesize the direntries for `.' and `..'. */ - if (iterate_dir_call_hook (diro->ino, ".", &ctx)) - return 1; - - if (iterate_dir_call_hook (parent, "..", &ctx)) - return 1; - - for (i = 0; i < head->count && - (grub_uint8_t *) de < ((grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data)); i++) - { - grub_uint64_t ino; - grub_uint8_t *inopos = grub_xfs_inline_de_inopos(dir->data, de); - grub_uint8_t c; - - if ((inopos + (smallino ? 4 : 8)) > (grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data)) - { - grub_error (GRUB_ERR_BAD_FS, "invalid XFS inode"); - return 0; - } - - - /* inopos might be unaligned. */ - if (smallino) - ino = (((grub_uint32_t) inopos[0]) << 24) - | (((grub_uint32_t) inopos[1]) << 16) - | (((grub_uint32_t) inopos[2]) << 8) - | (((grub_uint32_t) inopos[3]) << 0); - else - ino = (((grub_uint64_t) inopos[0]) << 56) - | (((grub_uint64_t) inopos[1]) << 48) - | (((grub_uint64_t) inopos[2]) << 40) - | (((grub_uint64_t) inopos[3]) << 32) - | (((grub_uint64_t) inopos[4]) << 24) - | (((grub_uint64_t) inopos[5]) << 16) - | (((grub_uint64_t) inopos[6]) << 8) - | (((grub_uint64_t) inopos[7]) << 0); - - c = de->name[de->len]; - de->name[de->len] = '\0'; - if (iterate_dir_call_hook (ino, de->name, &ctx)) - { - de->name[de->len] = c; - return 1; - } - de->name[de->len] = c; - - de = grub_xfs_inline_next_de(dir->data, head, de); - } - 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++) - { - struct grub_xfs_dir2_entry *direntry = - grub_xfs_first_de(dir->data, dirblock); - int entries = -1; - char *end = dirblock + dirblk_size; - grub_uint32_t magic; - - numread = grub_xfs_read_file (dir, 0, 0, - blk << dirblk_log2, - dirblk_size, dirblock, 0); - if (numread != dirblk_size) - { - grub_free (dirblock); - return 0; - } - - /* - * If this data block isn't actually part of the extent list then - * grub_xfs_read_file() returns a block of zeros. So, if the magic - * number field is all zeros then this block should be skipped. - */ - magic = *(grub_uint32_t *)(void *) dirblock; - if (!magic) - continue; - - /* - * Leaf and tail information are only in the data block if the number - * of extents is 1. - */ - if (grub_xfs_get_inode_nextents (&dir->inode) == 1) - { - struct grub_xfs_dirblock_tail *tail = grub_xfs_dir_tail (dir->data, dirblock); - - end = (char *) tail; - - /* Subtract the space used by leaf nodes. */ - end -= grub_be_to_cpu32 (tail->leaf_count) * sizeof (struct grub_xfs_dir_leaf_entry); - - entries = grub_be_to_cpu32 (tail->leaf_count) - grub_be_to_cpu32 (tail->leaf_stale); - - if (!entries) - continue; - } - - /* Iterate over all entries within this block. */ - while ((char *) direntry < (char *) end) - { - grub_uint8_t *freetag; - char *filename; - - freetag = (grub_uint8_t *) direntry; - - if (grub_get_unaligned16 (freetag) == 0XFFFF) - { - grub_uint8_t *skip = (freetag + sizeof (grub_uint16_t)); - - /* This entry is not used, go to the next one. */ - direntry = (struct grub_xfs_dir2_entry *) - (((char *)direntry) + - grub_be_to_cpu16 (grub_get_unaligned16 (skip))); - - continue; - } - - filename = (char *)(direntry + 1); - if (filename + direntry->len + 1 > (char *) end) - { - grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry"); - return 0; - } - - /* The byte after the filename is for the filetype, padding, or - tag, which is not used by GRUB. So it can be overwritten. */ - filename[direntry->len] = '\0'; - - if (iterate_dir_call_hook (grub_be_to_cpu64(direntry->inode), - filename, &ctx)) - { - grub_free (dirblock); - return 1; - } - - /* - * The expected number of directory entries is only tracked for the - * single extent case. - */ - if (grub_xfs_get_inode_nextents (&dir->inode) == 1) - { - /* Check if last direntry in this block is reached. */ - entries--; - if (!entries) - break; - } - - /* Select the next directory entry. */ - direntry = grub_xfs_next_de(dir->data, direntry); - } - } - 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; - grub_size_t sz; - - data = grub_zalloc (sizeof (struct grub_xfs_data)); - if (!data) - return 0; - - data->data_size = sizeof (struct grub_xfs_data); - - grub_dprintf("xfs", "Reading sb\n"); - /* Read the superblock. */ - if (grub_disk_read (disk, 0, 0, - sizeof (struct grub_xfs_sblock), &data->sblock)) - goto fail; - - if (!grub_xfs_sb_valid(data)) - goto fail; - - if (grub_xfs_sb_needs_repair (data)) - grub_dprintf ("xfs", "XFS filesystem needs repair, boot may fail\n"); - - if (grub_add (grub_xfs_inode_size (data), - sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz)) - goto fail; - - data = grub_realloc (data, sz); - - if (! data) - goto fail; - - data->data_size = sz; - data->diropen.data = data; - data->diropen.ino = grub_be_to_cpu64(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->hasftype = grub_xfs_sb_hasftype(data); - data->hascrc = grub_xfs_sb_hascrc(data); - - data->disk = disk; - data->pos = 0; - grub_dprintf("xfs", "Reading root ino %" PRIuGRUB_UINT64_T "\n", - grub_cpu_to_be64(data->sblock.rootino)); - - grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode); - - return data; - fail: - - if (grub_errno == GRUB_ERR_OUT_OF_RANGE || grub_errno == GRUB_ERR_NONE) - grub_error (GRUB_ERR_BAD_FS, "not an XFS filesystem"); - - grub_free (data); - - return 0; -} - - -/* Context for grub_xfs_dir. */ -struct grub_xfs_dir_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; -}; - -/* Bigtime inodes helpers. */ -#define XFS_BIGTIME_EPOCH_OFFSET (-(grub_int64_t) GRUB_INT32_MIN) - -static int grub_xfs_inode_has_bigtime (const struct grub_xfs_inode *inode) -{ - return inode->version >= 3 && - (inode->flags2 & grub_cpu_to_be64_compile_time (XFS_DIFLAG2_BIGTIME)); -} - -static grub_int64_t -grub_xfs_get_inode_time (struct grub_xfs_inode *inode) -{ - struct grub_xfs_time_legacy *lts; - - if (grub_xfs_inode_has_bigtime (inode)) - return grub_divmod64 (grub_be_to_cpu64 (inode->mtime), NSEC_PER_SEC, NULL) - XFS_BIGTIME_EPOCH_OFFSET; - - lts = (struct grub_xfs_time_legacy *) &inode->mtime; - return grub_be_to_cpu32 (lts->sec); -} - -/* Helper for grub_xfs_dir. */ -static int -grub_xfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, void *data) -{ - struct grub_xfs_dir_ctx *ctx = data; - struct grub_dirhook_info info; - - grub_memset (&info, 0, sizeof (info)); - if (node->inode_read) - { - info.mtimeset = 1; - info.mtime = grub_xfs_get_inode_time (&node->inode); - } - info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); - grub_free (node); - return ctx->hook (filename, &info, ctx->hook_data); -} - -static grub_err_t -grub_xfs_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_xfs_dir_ctx ctx = { hook, hook_data }; - struct grub_xfs_data *data = 0; - struct grub_fshelp_node *fdiro = 0; - - 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, grub_xfs_dir_iter, &ctx); - - 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, grub_xfs_fshelp_size(data)); - grub_free (fdiro); - } - - 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->read_hook_data, - file->offset, len, buf, 0); -} - - -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; -} - - - -static struct grub_fs grub_xfs_fs = - { - .name = "xfs", - .fs_dir = grub_xfs_dir, - .fs_open = grub_xfs_open, - .fs_read = grub_xfs_read, - .fs_close = grub_xfs_close, - .fs_label = grub_xfs_label, - .fs_uuid = grub_xfs_uuid, -#ifdef GRUB_UTIL - .reserved_first_sector = 0, - .blocklist_install = 1, -#endif - .next = 0 - }; - -GRUB_MOD_INIT(xfs) -{ - grub_xfs_fs.mod = mod; - grub_fs_register (&grub_xfs_fs); - my_mod = mod; -} - -GRUB_MOD_FINI(xfs) -{ - grub_fs_unregister (&grub_xfs_fs); -} diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c deleted file mode 100644 index afe821f9b..000000000 --- a/grub-core/fs/zfs/zfs.c +++ /dev/null @@ -1,4581 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2009,2010,2011 Free Software Foundation, Inc. - * Copyright 2010 Sun Microsystems, Inc. - * Copyright (c) 2012 by Delphix. All rights reserved. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - * The zfs plug-in routines for GRUB are: - * - * zfs_mount() - locates a valid uberblock of the root pool and reads - * in its MOS at the memory address MOS. - * - * zfs_open() - locates a plain file object by following the MOS - * and places its dnode at the memory address DNODE. - * - * zfs_read() - read in the data blocks pointed by the DNODE. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define ZPOOL_PROP_BOOTFS "bootfs" - -/* - * For nvlist manipulation. (from nvpair.h) - */ -#define NV_ENCODE_NATIVE 0 -#define NV_ENCODE_XDR 1 -#define NV_BIG_ENDIAN 0 -#define NV_LITTLE_ENDIAN 1 -#define DATA_TYPE_UINT64 8 -#define DATA_TYPE_STRING 9 -#define DATA_TYPE_NVLIST 19 -#define DATA_TYPE_NVLIST_ARRAY 20 - -#define DNODE_NUM_MASK 0xffffffffffffULL - -#ifndef GRUB_UTIL -static grub_dl_t my_mod; -#endif - -#define P2PHASE(x, align) ((x) & ((align) - 1)) - -static inline grub_disk_addr_t -DVA_OFFSET_TO_PHYS_SECTOR (grub_disk_addr_t offset) -{ - return ((offset + VDEV_LABEL_START_SIZE) >> SPA_MINBLOCKSHIFT); -} - -/* - * FAT ZAP data structures - */ -#define ZFS_CRC64_POLY 0xC96C5795D7870F42ULL /* ECMA-182, reflected form */ -static inline grub_uint64_t -ZAP_HASH_IDX (grub_uint64_t hash, grub_uint64_t n) -{ - return (((n) == 0) ? 0 : ((hash) >> (64 - (n)))); -} - -#define CHAIN_END 0xffff /* end of the chunk chain */ - -/* - * The amount of space within the chunk available for the array is: - * chunk size - space for type (1) - space for next pointer (2) - */ -#define ZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3) - -static inline int -ZAP_LEAF_HASH_SHIFT (int bs) -{ - return bs - 5; -} - -static inline int -ZAP_LEAF_HASH_NUMENTRIES (int bs) -{ - return 1 << ZAP_LEAF_HASH_SHIFT(bs); -} - -static inline grub_size_t -LEAF_HASH (int bs, grub_uint64_t h, zap_leaf_phys_t *l) -{ - return ((ZAP_LEAF_HASH_NUMENTRIES (bs)-1) - & ((h) >> (64 - ZAP_LEAF_HASH_SHIFT (bs) - l->l_hdr.lh_prefix_len))); -} - -/* - * The amount of space available for chunks is: - * block size shift - hash entry size (2) * number of hash - * entries - header space (2*chunksize) - */ -static inline int -ZAP_LEAF_NUMCHUNKS (int bs) -{ - return (((1U << bs) - 2 * ZAP_LEAF_HASH_NUMENTRIES (bs)) / - ZAP_LEAF_CHUNKSIZE - 2); -} - -/* - * The chunks start immediately after the hash table. The end of the - * hash table is at l_hash + HASH_NUMENTRIES, which we simply cast to a - * chunk_t. - */ -static inline zap_leaf_chunk_t * -ZAP_LEAF_CHUNK (zap_leaf_phys_t *l, int bs, int idx) -{ - grub_properly_aligned_t *l_entries; - - l_entries = (grub_properly_aligned_t *) ALIGN_UP((grub_addr_t)l->l_hash, sizeof (grub_properly_aligned_t)); - return &((zap_leaf_chunk_t *) (l_entries - + (ZAP_LEAF_HASH_NUMENTRIES(bs) * 2) - / sizeof (grub_properly_aligned_t)))[idx]; -} - -static inline struct zap_leaf_entry * -ZAP_LEAF_ENTRY(zap_leaf_phys_t *l, int bs, int idx) -{ - return &ZAP_LEAF_CHUNK(l, bs, idx)->l_entry; -} - - -/* - * Decompression Entry - lzjb & lz4 - */ - -extern grub_err_t lzjb_decompress (void *, void *, grub_size_t, grub_size_t); - -extern grub_err_t lz4_decompress (void *, void *, grub_size_t, grub_size_t); - -typedef grub_err_t zfs_decomp_func_t (void *s_start, void *d_start, - grub_size_t s_len, grub_size_t d_len); -typedef struct decomp_entry -{ - const char *name; - zfs_decomp_func_t *decomp_func; -} decomp_entry_t; - -/* - * Signature for checksum functions. - */ -typedef void zio_checksum_t(const void *data, grub_uint64_t size, - grub_zfs_endian_t endian, zio_cksum_t *zcp); - -/* - * Information about each checksum function. - */ -typedef struct zio_checksum_info { - zio_checksum_t *ci_func; /* checksum function for each byteorder */ - int ci_correctable; /* number of correctable bits */ - int ci_eck; /* uses zio embedded checksum? */ - const char *ci_name; /* descriptive name */ -} zio_checksum_info_t; - -typedef struct dnode_end -{ - dnode_phys_t dn; - grub_zfs_endian_t endian; -} dnode_end_t; - -struct grub_zfs_device_desc -{ - enum { DEVICE_LEAF, DEVICE_MIRROR, DEVICE_RAIDZ } type; - grub_uint64_t id; - grub_uint64_t guid; - unsigned ashift; - unsigned max_children_ashift; - - /* Valid only for non-leafs. */ - unsigned n_children; - struct grub_zfs_device_desc *children; - - /* Valid only for RAIDZ. */ - unsigned nparity; - - /* Valid only for leaf devices. */ - grub_device_t dev; - grub_disk_addr_t vdev_phys_sector; - uberblock_t current_uberblock; - int original; -}; - -struct subvolume -{ - dnode_end_t mdn; - grub_uint64_t obj; - grub_uint64_t case_insensitive; - grub_size_t nkeys; - struct - { - grub_crypto_cipher_handle_t cipher; - grub_uint64_t txg; - grub_uint64_t algo; - } *keyring; -}; - -struct grub_zfs_data -{ - /* cache for a file block of the currently zfs_open()-ed file */ - char *file_buf; - grub_uint64_t file_start; - grub_uint64_t file_end; - - /* cache for a dnode block */ - dnode_phys_t *dnode_buf; - dnode_phys_t *dnode_mdn; - grub_uint64_t dnode_start; - grub_uint64_t dnode_end; - grub_zfs_endian_t dnode_endian; - - dnode_end_t mos; - dnode_end_t dnode; - struct subvolume subvol; - - struct grub_zfs_device_desc *devices_attached; - unsigned n_devices_attached; - unsigned n_devices_allocated; - struct grub_zfs_device_desc *device_original; - - uberblock_t current_uberblock; - - grub_uint64_t guid; -}; - -/* Context for grub_zfs_dir. */ -struct grub_zfs_dir_ctx -{ - grub_fs_dir_hook_t hook; - void *hook_data; - struct grub_zfs_data *data; -}; - -grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, - grub_uint64_t algo, - void *nonce, - char *buf, grub_size_t size, - const grub_uint32_t *expected_mac, - grub_zfs_endian_t endian) = NULL; -grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key, - grub_size_t keysize, - grub_uint64_t salt, - grub_uint64_t algo) = NULL; -/* - * List of pool features that the grub implementation of ZFS supports for - * read. Note that features that are only required for write do not need - * to be listed here since grub opens pools in read-only mode. - */ -#define MAX_SUPPORTED_FEATURE_STRLEN 50 -static const char *spa_feature_names[] = { - "org.illumos:lz4_compress", - "com.delphix:hole_birth", - "com.delphix:embedded_data", - "com.delphix:extensible_dataset", - "org.open-zfs:large_blocks", - "com.klarasystems:vdev_zaps_v2", - "com.delphix:head_errlog", - "org.freebsd:zstd_compress", - NULL -}; - -static int -check_feature(const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx); -static grub_err_t -check_mos_features(dnode_phys_t *mosmdn_phys,grub_zfs_endian_t endian,struct grub_zfs_data* data ); - -static grub_err_t -zlib_decompress (void *s, void *d, - grub_size_t slen, grub_size_t dlen) -{ - if (grub_zlib_decompress (s, slen, 0, d, dlen) == (grub_ssize_t) dlen) - return GRUB_ERR_NONE; - - if (!grub_errno) - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, - "premature end of compressed"); - return grub_errno; -} - -static grub_err_t -zstd_decompress (void *ibuf, void *obuf, grub_size_t isize, - grub_size_t osize) -{ - grub_size_t zstd_ret; - grub_uint32_t c_len; - grub_uint8_t *byte_buf = (grub_uint8_t *) ibuf; - - if (isize < 8) - return grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "zstd data too short"); - - c_len = grub_be_to_cpu32 (grub_get_unaligned32 (byte_buf)); - - if (c_len > isize - 8) - return grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, - "zstd data announced size overflow"); - - /* - * ZFS uses non-stadard magic for zstd streams. Rather than adjusting - * library functions, replace non-standard magic with standard one. - */ - byte_buf[4] = 0x28; - byte_buf[5] = 0xb5; - byte_buf[6] = 0x2f; - byte_buf[7] = 0xfd; - zstd_ret = ZSTD_decompress (obuf, osize, byte_buf + 4, c_len + 4); - - if (ZSTD_isError (zstd_ret)) - return grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, - "zstd data corrupted (error %d)", (int) zstd_ret); - - return GRUB_ERR_NONE; -} - -static grub_err_t -zle_decompress (void *s, void *d, - grub_size_t slen, grub_size_t dlen) -{ - grub_uint8_t *iptr, *optr; - grub_size_t clen; - for (iptr = s, optr = d; iptr < (grub_uint8_t *) s + slen - && optr < (grub_uint8_t *) d + dlen;) - { - if (*iptr & 0x80) - clen = ((*iptr) & 0x7f) + 0x41; - else - clen = ((*iptr) & 0x3f) + 1; - if ((grub_ssize_t) clen > (grub_uint8_t *) d + dlen - optr) - clen = (grub_uint8_t *) d + dlen - optr; - if (*iptr & 0x40 || *iptr & 0x80) - { - grub_memset (optr, 0, clen); - iptr++; - optr += clen; - continue; - } - if ((grub_ssize_t) clen > (grub_uint8_t *) s + slen - iptr - 1) - clen = (grub_uint8_t *) s + slen - iptr - 1; - grub_memcpy (optr, iptr + 1, clen); - optr += clen; - iptr += clen + 1; - } - if (optr < (grub_uint8_t *) d + dlen) - grub_memset (optr, 0, (grub_uint8_t *) d + dlen - optr); - return GRUB_ERR_NONE; -} - -static decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = { - {"inherit", NULL}, /* ZIO_COMPRESS_INHERIT */ - {"on", lzjb_decompress}, /* ZIO_COMPRESS_ON */ - {"off", NULL}, /* ZIO_COMPRESS_OFF */ - {"lzjb", lzjb_decompress}, /* ZIO_COMPRESS_LZJB */ - {"empty", NULL}, /* ZIO_COMPRESS_EMPTY */ - {"gzip-1", zlib_decompress}, /* ZIO_COMPRESS_GZIP1 */ - {"gzip-2", zlib_decompress}, /* ZIO_COMPRESS_GZIP2 */ - {"gzip-3", zlib_decompress}, /* ZIO_COMPRESS_GZIP3 */ - {"gzip-4", zlib_decompress}, /* ZIO_COMPRESS_GZIP4 */ - {"gzip-5", zlib_decompress}, /* ZIO_COMPRESS_GZIP5 */ - {"gzip-6", zlib_decompress}, /* ZIO_COMPRESS_GZIP6 */ - {"gzip-7", zlib_decompress}, /* ZIO_COMPRESS_GZIP7 */ - {"gzip-8", zlib_decompress}, /* ZIO_COMPRESS_GZIP8 */ - {"gzip-9", zlib_decompress}, /* ZIO_COMPRESS_GZIP9 */ - {"zle", zle_decompress}, /* ZIO_COMPRESS_ZLE */ - {"lz4", lz4_decompress}, /* ZIO_COMPRESS_LZ4 */ - {"zstd", zstd_decompress}, /* ZIO_COMPRESS_ZSTD */ -}; - -static grub_err_t zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, - void *buf, struct grub_zfs_data *data); - -/* - * Our own version of log2(). Same thing as highbit()-1. - */ -static int -zfs_log2 (grub_uint64_t num) -{ - int i = 0; - - while (num > 1) - { - i++; - num = num >> 1; - } - - return i; -} - -/* Checksum Functions */ -static void -zio_checksum_off (const void *buf __attribute__ ((unused)), - grub_uint64_t size __attribute__ ((unused)), - grub_zfs_endian_t endian __attribute__ ((unused)), - zio_cksum_t * zcp) -{ - ZIO_SET_CHECKSUM (zcp, 0, 0, 0, 0); -} - -/* Checksum Table and Values */ -static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { - {NULL, 0, 0, "inherit"}, - {NULL, 0, 0, "on"}, - {zio_checksum_off, 0, 0, "off"}, - {zio_checksum_SHA256, 1, 1, "label"}, - {zio_checksum_SHA256, 1, 1, "gang_header"}, - {NULL, 0, 0, "zilog"}, - {fletcher_2, 0, 0, "fletcher2"}, - {fletcher_4, 1, 0, "fletcher4"}, - {zio_checksum_SHA256, 1, 0, "SHA256"}, - {NULL, 0, 0, "zilog2"}, - {zio_checksum_SHA256, 1, 0, "SHA256+MAC"}, -}; - -/* - * zio_checksum_verify: Provides support for checksum verification. - * - * Fletcher2, Fletcher4, and SHA256 are supported. - * - */ -static grub_err_t -zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, - grub_zfs_endian_t endian, - char *buf, grub_size_t size) -{ - zio_eck_t *zec = (zio_eck_t *) (buf + size) - 1; - zio_checksum_info_t *ci = &zio_checksum_table[checksum]; - zio_cksum_t actual_cksum, expected_cksum; - - if (checksum >= ZIO_CHECKSUM_FUNCTIONS || ci->ci_func == NULL) - { - grub_dprintf ("zfs", "unknown checksum function %d\n", checksum); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unknown checksum function %d", checksum); - } - - if (ci->ci_eck) - { - expected_cksum = zec->zec_cksum; - zec->zec_cksum = zc; - ci->ci_func (buf, size, endian, &actual_cksum); - zec->zec_cksum = expected_cksum; - zc = expected_cksum; - } - else - ci->ci_func (buf, size, endian, &actual_cksum); - - if (grub_memcmp (&actual_cksum, &zc, - checksum != ZIO_CHECKSUM_SHA256_MAC ? 32 : 20) != 0) - { - grub_dprintf ("zfs", "checksum %s verification failed\n", ci->ci_name); - grub_dprintf ("zfs", "actual checksum %016llx %016llx %016llx %016llx\n", - (unsigned long long) actual_cksum.zc_word[0], - (unsigned long long) actual_cksum.zc_word[1], - (unsigned long long) actual_cksum.zc_word[2], - (unsigned long long) actual_cksum.zc_word[3]); - grub_dprintf ("zfs", "expected checksum %016llx %016llx %016llx %016llx\n", - (unsigned long long) zc.zc_word[0], - (unsigned long long) zc.zc_word[1], - (unsigned long long) zc.zc_word[2], - (unsigned long long) zc.zc_word[3]); - return grub_error (GRUB_ERR_BAD_FS, N_("checksum verification failed")); - } - - return GRUB_ERR_NONE; -} - -/* - * vdev_uberblock_compare takes two uberblock structures and returns an integer - * indicating the more recent of the two. - * Return Value = 1 if ub2 is more recent - * Return Value = -1 if ub1 is more recent - * The most recent uberblock is determined using its transaction number and - * timestamp. The uberblock with the highest transaction number is - * considered "newer". If the transaction numbers of the two blocks match, the - * timestamps are compared to determine the "newer" of the two. - */ -static int -vdev_uberblock_compare (uberblock_t * ub1, uberblock_t * ub2) -{ - grub_zfs_endian_t ub1_endian, ub2_endian; - if (grub_zfs_to_cpu64 (ub1->ub_magic, GRUB_ZFS_LITTLE_ENDIAN) - == UBERBLOCK_MAGIC) - ub1_endian = GRUB_ZFS_LITTLE_ENDIAN; - else - ub1_endian = GRUB_ZFS_BIG_ENDIAN; - if (grub_zfs_to_cpu64 (ub2->ub_magic, GRUB_ZFS_LITTLE_ENDIAN) - == UBERBLOCK_MAGIC) - ub2_endian = GRUB_ZFS_LITTLE_ENDIAN; - else - ub2_endian = GRUB_ZFS_BIG_ENDIAN; - - if (grub_zfs_to_cpu64 (ub1->ub_txg, ub1_endian) - < grub_zfs_to_cpu64 (ub2->ub_txg, ub2_endian)) - return -1; - if (grub_zfs_to_cpu64 (ub1->ub_txg, ub1_endian) - > grub_zfs_to_cpu64 (ub2->ub_txg, ub2_endian)) - return 1; - - if (grub_zfs_to_cpu64 (ub1->ub_timestamp, ub1_endian) - < grub_zfs_to_cpu64 (ub2->ub_timestamp, ub2_endian)) - return -1; - if (grub_zfs_to_cpu64 (ub1->ub_timestamp, ub1_endian) - > grub_zfs_to_cpu64 (ub2->ub_timestamp, ub2_endian)) - return 1; - - return 0; -} - -/* - * Three pieces of information are needed to verify an uberblock: the magic - * number, the version number, and the checksum. - * - * Currently Implemented: version number, magic number, checksum - * - */ -static grub_err_t -uberblock_verify (uberblock_phys_t * ub, grub_uint64_t offset, - grub_size_t s) -{ - uberblock_t *uber = &ub->ubp_uberblock; - grub_err_t err; - grub_zfs_endian_t endian = GRUB_ZFS_UNKNOWN_ENDIAN; - zio_cksum_t zc; - - if (grub_zfs_to_cpu64 (uber->ub_magic, GRUB_ZFS_LITTLE_ENDIAN) - == UBERBLOCK_MAGIC - && SPA_VERSION_IS_SUPPORTED(grub_zfs_to_cpu64 (uber->ub_version, GRUB_ZFS_LITTLE_ENDIAN))) - endian = GRUB_ZFS_LITTLE_ENDIAN; - - if (grub_zfs_to_cpu64 (uber->ub_magic, GRUB_ZFS_BIG_ENDIAN) == UBERBLOCK_MAGIC - && SPA_VERSION_IS_SUPPORTED(grub_zfs_to_cpu64 (uber->ub_version, GRUB_ZFS_BIG_ENDIAN))) - endian = GRUB_ZFS_BIG_ENDIAN; - - if (endian == GRUB_ZFS_UNKNOWN_ENDIAN) - return grub_error (GRUB_ERR_BAD_FS, "invalid uberblock magic"); - - grub_memset (&zc, 0, sizeof (zc)); - - zc.zc_word[0] = grub_cpu_to_zfs64 (offset, endian); - err = zio_checksum_verify (zc, ZIO_CHECKSUM_LABEL, endian, - (char *) ub, s); - - return err; -} - -/* - * Find the best uberblock. - * Return: - * Success - Pointer to the best uberblock. - * Failure - NULL - */ -static uberblock_phys_t * -find_bestub (uberblock_phys_t * ub_array, - const struct grub_zfs_device_desc *desc) -{ - uberblock_phys_t *ubbest = NULL, *ubptr; - int i; - grub_disk_addr_t offset; - grub_err_t err = GRUB_ERR_NONE; - int ub_shift; - - ub_shift = desc->ashift; - if (ub_shift < VDEV_UBERBLOCK_SHIFT) - ub_shift = VDEV_UBERBLOCK_SHIFT; - - for (i = 0; i < (VDEV_UBERBLOCK_RING >> ub_shift); i++) - { - offset = (desc->vdev_phys_sector << SPA_MINBLOCKSHIFT) + VDEV_PHYS_SIZE - + (i << ub_shift); - - ubptr = (uberblock_phys_t *) ((grub_properly_aligned_t *) ub_array - + ((i << ub_shift) - / sizeof (grub_properly_aligned_t))); - err = uberblock_verify (ubptr, offset, (grub_size_t) 1 << ub_shift); - if (err) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - if (ubbest == NULL - || vdev_uberblock_compare (&(ubptr->ubp_uberblock), - &(ubbest->ubp_uberblock)) > 0) - ubbest = ubptr; - } - if (!ubbest) - grub_errno = err; - - return ubbest; -} - -static inline grub_size_t -get_psize (blkptr_t * bp, grub_zfs_endian_t endian) -{ - return ((((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) >> 16) & 0xffff) + 1) - << SPA_MINBLOCKSHIFT); -} - -static grub_uint64_t -dva_get_offset (const dva_t *dva, grub_zfs_endian_t endian) -{ - grub_dprintf ("zfs", "dva=%llx, %llx\n", - (unsigned long long) dva->dva_word[0], - (unsigned long long) dva->dva_word[1]); - return grub_zfs_to_cpu64 ((dva)->dva_word[1], - endian) << SPA_MINBLOCKSHIFT; -} - -static grub_err_t -zfs_fetch_nvlist (struct grub_zfs_device_desc *diskdesc, char **nvlist) -{ - grub_err_t err; - - *nvlist = 0; - - if (!diskdesc->dev) - return grub_error (GRUB_ERR_BUG, "member drive unknown"); - - *nvlist = grub_malloc (VDEV_PHYS_SIZE); - if (!*nvlist) - return grub_errno; - - /* Read in the vdev name-value pair list (112K). */ - err = grub_disk_read (diskdesc->dev->disk, diskdesc->vdev_phys_sector, 0, - VDEV_PHYS_SIZE, *nvlist); - if (err) - { - grub_free (*nvlist); - *nvlist = 0; - return err; - } - return GRUB_ERR_NONE; -} - -static grub_err_t -fill_vdev_info_real (struct grub_zfs_data *data, - const char *nvlist, - struct grub_zfs_device_desc *fill, - struct grub_zfs_device_desc *insert, - int *inserted, - unsigned ashift) -{ - char *type; - - type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE); - - if (!type) - return grub_errno; - - if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &(fill->id))) - { - grub_free (type); - return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); - } - - if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "guid", &(fill->guid))) - { - grub_free (type); - return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); - } - - { - grub_uint64_t par; - if (grub_zfs_nvlist_lookup_uint64 (nvlist, "ashift", &par)) - fill->ashift = par; - else if (ashift != 0xffffffff) - fill->ashift = ashift; - else - { - grub_free (type); - return grub_error (GRUB_ERR_BAD_FS, "couldn't find ashift"); - } - } - - fill->max_children_ashift = 0; - - if (grub_strcmp (type, VDEV_TYPE_DISK) == 0 - || grub_strcmp (type, VDEV_TYPE_FILE) == 0) - { - fill->type = DEVICE_LEAF; - - if (!fill->dev && fill->guid == insert->guid) - { - fill->dev = insert->dev; - fill->vdev_phys_sector = insert->vdev_phys_sector; - fill->current_uberblock = insert->current_uberblock; - fill->original = insert->original; - if (!data->device_original) - data->device_original = fill; - insert->ashift = fill->ashift; - *inserted = 1; - } - - grub_free (type); - - return GRUB_ERR_NONE; - } - - if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0 - || grub_strcmp (type, VDEV_TYPE_RAIDZ) == 0) - { - int nelm, i; - - if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0) - fill->type = DEVICE_MIRROR; - else - { - grub_uint64_t par; - fill->type = DEVICE_RAIDZ; - if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "nparity", &par)) - { - grub_free (type); - return grub_error (GRUB_ERR_BAD_FS, "couldn't find raidz parity"); - } - fill->nparity = par; - } - - nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm (nvlist, - ZPOOL_CONFIG_CHILDREN); - - if (nelm <= 0) - { - grub_free (type); - return grub_error (GRUB_ERR_BAD_FS, "incorrect mirror VDEV"); - } - - if (!fill->children) - { - fill->n_children = nelm; - - fill->children = grub_calloc (fill->n_children, - sizeof (fill->children[0])); - if (!fill->children) - { - grub_free (type); - return grub_errno; - } - } - - for (i = 0; i < nelm; i++) - { - char *child; - grub_err_t err; - - child = grub_zfs_nvlist_lookup_nvlist_array - (nvlist, ZPOOL_CONFIG_CHILDREN, i); - - err = fill_vdev_info_real (data, child, &fill->children[i], insert, - inserted, fill->ashift); - - grub_free (child); - - if (err) - { - grub_free (type); - return err; - } - if (fill->children[i].ashift > fill->max_children_ashift) - fill->max_children_ashift = fill->children[i].ashift; - } - grub_free (type); - return GRUB_ERR_NONE; - } - - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "vdev %s isn't supported", type); - grub_free (type); - return grub_errno; -} - -static grub_err_t -fill_vdev_info (struct grub_zfs_data *data, - char *nvlist, struct grub_zfs_device_desc *diskdesc, - int *inserted) -{ - grub_uint64_t id; - unsigned i; - - *inserted = 0; - - if (!grub_zfs_nvlist_lookup_uint64 (nvlist, "id", &id)) - return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev id"); - - for (i = 0; i < data->n_devices_attached; i++) - if (data->devices_attached[i].id == id) - return fill_vdev_info_real (data, nvlist, &data->devices_attached[i], - diskdesc, inserted, 0xffffffff); - - data->n_devices_attached++; - if (data->n_devices_attached > data->n_devices_allocated) - { - void *tmp; - grub_size_t sz; - - if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) || - grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) || - grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz)) - return GRUB_ERR_OUT_OF_RANGE; - - data->devices_attached = grub_realloc (tmp = data->devices_attached, sz); - if (!data->devices_attached) - { - data->devices_attached = tmp; - return grub_errno; - } - } - - grub_memset (&data->devices_attached[data->n_devices_attached - 1], - 0, sizeof (data->devices_attached[data->n_devices_attached - 1])); - - return fill_vdev_info_real (data, nvlist, - &data->devices_attached[data->n_devices_attached - 1], - diskdesc, inserted, 0xffffffff); -} - -/* - * For a given XDR packed nvlist, verify the first 4 bytes and move on. - * - * An XDR packed nvlist is encoded as (comments from nvs_xdr_create) : - * - * encoding method/host endian (4 bytes) - * nvl_version (4 bytes) - * nvl_nvflag (4 bytes) - * encoded nvpairs: - * encoded size of the nvpair (4 bytes) - * decoded size of the nvpair (4 bytes) - * name string size (4 bytes) - * name string data (sizeof(NV_ALIGN4(string)) - * data type (4 bytes) - * # of elements in the nvpair (4 bytes) - * data - * 2 zero's for the last nvpair - * (end of the entire list) (8 bytes) - * - */ - -/* - * The nvlist_next_nvpair() function returns a handle to the next nvpair in the - * list following nvpair. If nvpair is NULL, the first pair is returned. If - * nvpair is the last pair in the nvlist, NULL is returned. - */ -static const char * -nvlist_next_nvpair (const char *nvl, const char *nvpair) -{ - const char *nvp; - int encode_size; - int name_len; - if (nvl == NULL) - return NULL; - - if (nvpair == NULL) - { - /* skip over header, nvl_version and nvl_nvflag */ - nvpair = nvl + 4 * 3; - } - else - { - /* skip to the next nvpair */ - encode_size = grub_be_to_cpu32 (grub_get_unaligned32(nvpair)); - nvpair += encode_size; - /*If encode_size equals 0 nvlist_next_nvpair would return - * the same pair received in input, leading to an infinite loop. - * If encode_size is less than 0, this will move the pointer - * backwards, *possibly* examinining two times the same nvpair - * and potentially getting into an infinite loop. */ - if(encode_size <= 0) - { - grub_dprintf ("zfs", "nvpair with size <= 0\n"); - grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist"); - return NULL; - } - } - /* 8 bytes of 0 marks the end of the list */ - if (grub_get_unaligned64 (nvpair) == 0) - return NULL; - /*consistency checks*/ - if (nvpair + 4 * 3 >= nvl + VDEV_PHYS_SIZE) - { - grub_dprintf ("zfs", "nvlist overflow\n"); - grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist"); - return NULL; - } - encode_size = grub_be_to_cpu32 (grub_get_unaligned32(nvpair)); - - nvp = nvpair + 4*2; - name_len = grub_be_to_cpu32 (grub_get_unaligned32 (nvp)); - nvp += 4; - - nvp = nvp + ((name_len + 3) & ~3); // align - if (nvp + 4 >= nvl + VDEV_PHYS_SIZE - || encode_size < 0 - || nvp + 4 + encode_size > nvl + VDEV_PHYS_SIZE) - { - grub_dprintf ("zfs", "nvlist overflow\n"); - grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist"); - return NULL; - } - /* end consistency checks */ - - return nvpair; -} - -/* - * This function returns 0 on success and 1 on failure. On success, a string - * containing the name of nvpair is saved in buf. - */ -static int -nvpair_name (const char *nvp, char **buf, grub_size_t *buflen) -{ - /* skip over encode/decode size */ - nvp += 4 * 2; - - *buf = (char *) (nvp + 4); - *buflen = grub_be_to_cpu32 (grub_get_unaligned32 (nvp)); - - return 0; -} - -/* - * This function retrieves the value of the nvpair in the form of enumerated - * type data_type_t. - */ -static int -nvpair_type (const char *nvp) -{ - int name_len, type; - - /* skip over encode/decode size */ - nvp += 4 * 2; - - /* skip over name_len */ - name_len = grub_be_to_cpu32 (grub_get_unaligned32 (nvp)); - nvp += 4; - - /* skip over name */ - nvp = nvp + ((name_len + 3) & ~3); /* align */ - - type = grub_be_to_cpu32 (grub_get_unaligned32 (nvp)); - - return type; -} - -static int -nvpair_value (const char *nvp,char **val, - grub_size_t *size_out, grub_size_t *nelm_out) -{ - int name_len,nelm,encode_size; - - /* skip over encode/decode size */ - encode_size = grub_be_to_cpu32 (grub_get_unaligned32(nvp)); - nvp += 8; - - /* skip over name_len */ - name_len = grub_be_to_cpu32 (grub_get_unaligned32 (nvp)); - nvp += 4; - - /* skip over name */ - nvp = nvp + ((name_len + 3) & ~3); /* align */ - - /* skip over type */ - nvp += 4; - nelm = grub_be_to_cpu32 (grub_get_unaligned32 (nvp)); - nvp +=4; - if (nelm < 1) - { - grub_error (GRUB_ERR_BAD_FS, "empty nvpair"); - return 0; - } - *val = (char *) nvp; - *size_out = encode_size; - if (nelm_out) - *nelm_out = nelm; - - return 1; -} - -/* - * Check the disk label information and retrieve needed vdev name-value pairs. - * - */ -static grub_err_t -check_pool_label (struct grub_zfs_data *data, - struct grub_zfs_device_desc *diskdesc, - int *inserted, int original) -{ - grub_uint64_t pool_state, txg = 0; - char *nvlist,*features; -#if 0 - char *nv; -#endif - grub_uint64_t poolguid; - grub_uint64_t version; - int found; - grub_err_t err; - grub_zfs_endian_t endian; - vdev_phys_t *phys; - zio_cksum_t emptycksum; - - *inserted = 0; - - err = zfs_fetch_nvlist (diskdesc, &nvlist); - if (err) - return err; - - phys = (vdev_phys_t*) nvlist; - if (grub_zfs_to_cpu64 (phys->vp_zbt.zec_magic, - GRUB_ZFS_LITTLE_ENDIAN) - == ZEC_MAGIC) - endian = GRUB_ZFS_LITTLE_ENDIAN; - else if (grub_zfs_to_cpu64 (phys->vp_zbt.zec_magic, - GRUB_ZFS_BIG_ENDIAN) - == ZEC_MAGIC) - endian = GRUB_ZFS_BIG_ENDIAN; - else - { - grub_free (nvlist); - return grub_error (GRUB_ERR_BAD_FS, - "bad vdev_phys_t.vp_zbt.zec_magic number"); - } - /* Now check the integrity of the vdev_phys_t structure though checksum. */ - ZIO_SET_CHECKSUM(&emptycksum, diskdesc->vdev_phys_sector << 9, 0, 0, 0); - err = zio_checksum_verify (emptycksum, ZIO_CHECKSUM_LABEL, endian, - nvlist, VDEV_PHYS_SIZE); - if (err) { - grub_free (nvlist); - return err; - } - - grub_dprintf ("zfs", "check 2 passed\n"); - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_STATE, - &pool_state); - if (! found) - { - grub_free (nvlist); - if (! grub_errno) - grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_STATE " not found"); - return grub_errno; - } - grub_dprintf ("zfs", "check 3 passed\n"); - - if (pool_state == POOL_STATE_DESTROYED) - { - grub_free (nvlist); - return grub_error (GRUB_ERR_BAD_FS, "zpool is marked as destroyed"); - } - grub_dprintf ("zfs", "check 4 passed\n"); - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_TXG, &txg); - if (!found) - { - grub_free (nvlist); - if (! grub_errno) - grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_TXG " not found"); - return grub_errno; - } - grub_dprintf ("zfs", "check 6 passed\n"); - - /* not an active device */ - if (txg == 0) - { - grub_free (nvlist); - return grub_error (GRUB_ERR_BAD_FS, "zpool isn't active"); - } - grub_dprintf ("zfs", "check 7 passed\n"); - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_VERSION, - &version); - if (! found) - { - grub_free (nvlist); - if (! grub_errno) - grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_VERSION " not found"); - return grub_errno; - } - grub_dprintf ("zfs", "check 8 passed\n"); - - if (!SPA_VERSION_IS_SUPPORTED(version)) - { - grub_free (nvlist); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "too new version %llu > %llu", - (unsigned long long) version, - (unsigned long long) SPA_VERSION_BEFORE_FEATURES); - } - grub_dprintf ("zfs", "check 9 passed\n"); - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_GUID, - &(diskdesc->guid)); - if (! found) - { - grub_free (nvlist); - if (! grub_errno) - grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_GUID " not found"); - return grub_errno; - } - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_GUID, - &poolguid); - if (! found) - { - grub_free (nvlist); - if (! grub_errno) - grub_error (GRUB_ERR_BAD_FS, ZPOOL_CONFIG_POOL_GUID " not found"); - return grub_errno; - } - - grub_dprintf ("zfs", "check 11 passed\n"); - - if (original) - data->guid = poolguid; - - if (data->guid != poolguid) { - grub_free (nvlist); - return grub_error (GRUB_ERR_BAD_FS, "another zpool"); - } - - { - char *nv; - nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE); - - if (!nv) - { - grub_free (nvlist); - return grub_error (GRUB_ERR_BAD_FS, "couldn't find vdev tree"); - } - err = fill_vdev_info (data, nv, diskdesc, inserted); - if (err) - { - grub_free (nv); - grub_free (nvlist); - return err; - } - grub_free (nv); - } - grub_dprintf ("zfs", "check 10 passed\n"); - features = grub_zfs_nvlist_lookup_nvlist(nvlist, - ZPOOL_CONFIG_FEATURES_FOR_READ); - if (features) - { - const char *nvp=NULL; - char name[MAX_SUPPORTED_FEATURE_STRLEN + 1]; - char *nameptr; - grub_size_t namelen; - while ((nvp = nvlist_next_nvpair(features, nvp)) != NULL) - { - nvpair_name (nvp, &nameptr, &namelen); - if(namelen > MAX_SUPPORTED_FEATURE_STRLEN) - namelen = MAX_SUPPORTED_FEATURE_STRLEN; - grub_memcpy (name, nameptr, namelen); - name[namelen] = '\0'; - grub_dprintf("zfs","str=%s\n",name); - if (check_feature(name,1, NULL) != 0) - { - grub_dprintf("zfs","feature missing in check_pool_label:%s\n",name); - err= grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET," check_pool_label missing feature '%s' for read",name); - grub_free(features); - grub_free(nvlist); - return err; - } - } - grub_free(features); - } - grub_dprintf ("zfs", "check 12 passed (feature flags)\n"); - grub_free (nvlist); - - return GRUB_ERR_NONE; -} - -static grub_err_t -scan_disk (grub_device_t dev, struct grub_zfs_data *data, - int original, int *inserted) -{ - int label = 0; - uberblock_phys_t *ub_array, *ubbest = NULL; - vdev_boot_header_t *bh; - grub_err_t err; - int vdevnum; - struct grub_zfs_device_desc desc; - - ub_array = grub_malloc (VDEV_UBERBLOCK_RING); - if (!ub_array) - return grub_errno; - - bh = grub_malloc (VDEV_BOOT_HEADER_SIZE); - if (!bh) - { - grub_free (ub_array); - return grub_errno; - } - - vdevnum = VDEV_LABELS; - - desc.dev = dev; - desc.original = original; - - /* Don't check back labels on CDROM. */ - if (grub_disk_native_sectors (dev->disk) == GRUB_DISK_SIZE_UNKNOWN) - vdevnum = VDEV_LABELS / 2; - - for (label = 0; ubbest == NULL && label < vdevnum; label++) - { - desc.vdev_phys_sector - = label * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT) - + ((VDEV_SKIP_SIZE + VDEV_BOOT_HEADER_SIZE) >> SPA_MINBLOCKSHIFT) - + (label < VDEV_LABELS / 2 ? 0 : - ALIGN_DOWN (grub_disk_native_sectors (dev->disk), sizeof (vdev_label_t)) - - VDEV_LABELS * (sizeof (vdev_label_t) >> SPA_MINBLOCKSHIFT)); - - /* Read in the uberblock ring (128K). */ - err = grub_disk_read (dev->disk, desc.vdev_phys_sector - + (VDEV_PHYS_SIZE >> SPA_MINBLOCKSHIFT), - 0, VDEV_UBERBLOCK_RING, (char *) ub_array); - if (err) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - grub_dprintf ("zfs", "label ok %d\n", label); - - err = check_pool_label (data, &desc, inserted, original); - if (err || !*inserted) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - - ubbest = find_bestub (ub_array, &desc); - if (!ubbest) - { - grub_dprintf ("zfs", "No uberblock found\n"); - grub_errno = GRUB_ERR_NONE; - continue; - } - - grub_memmove (&(desc.current_uberblock), - &ubbest->ubp_uberblock, sizeof (uberblock_t)); - if (original) - grub_memmove (&(data->current_uberblock), - &ubbest->ubp_uberblock, sizeof (uberblock_t)); - -#if 0 - if (find_best_root && - vdev_uberblock_compare (&ubbest->ubp_uberblock, - &(current_uberblock)) <= 0) - continue; -#endif - grub_free (ub_array); - grub_free (bh); - return GRUB_ERR_NONE; - } - - grub_free (ub_array); - grub_free (bh); - - return grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid label"); -} - -/* Helper for scan_devices. */ -static int -scan_devices_iter (const char *name, void *hook_data) -{ - struct grub_zfs_data *data = hook_data; - grub_device_t dev; - grub_err_t err; - int inserted; - - dev = grub_device_open (name); - if (!dev) - return 0; - if (!dev->disk) - { - grub_device_close (dev); - return 0; - } - err = scan_disk (dev, data, 0, &inserted); - if (err == GRUB_ERR_BAD_FS) - { - grub_device_close (dev); - grub_errno = GRUB_ERR_NONE; - return 0; - } - if (err) - { - grub_device_close (dev); - grub_print_error (); - return 0; - } - - if (!inserted) - grub_device_close (dev); - - return 0; -} - -static grub_err_t -scan_devices (struct grub_zfs_data *data) -{ - grub_device_iterate (scan_devices_iter, data); - return GRUB_ERR_NONE; -} - -/* x**y. */ -static grub_uint8_t powx[255 * 2]; -/* Such an s that x**s = y */ -static int powx_inv[256]; -static const grub_uint8_t poly = 0x1d; - -/* perform the operation a ^= b * (x ** (known_idx * recovery_pow) ) */ -static inline void -xor_out (grub_uint8_t *a, const grub_uint8_t *b, grub_size_t s, - unsigned known_idx, unsigned recovery_pow) -{ - unsigned add; - - /* Simple xor. */ - if (known_idx == 0 || recovery_pow == 0) - { - grub_crypto_xor (a, a, b, s); - return; - } - add = (known_idx * recovery_pow) % 255; - for (;s--; b++, a++) - if (*b) - *a ^= powx[powx_inv[*b] + add]; -} - -static inline grub_uint8_t -gf_mul (grub_uint8_t a, grub_uint8_t b) -{ - if (a == 0 || b == 0) - return 0; - return powx[powx_inv[a] + powx_inv[b]]; -} - -#define MAX_NBUFS 4 - -static grub_err_t -recovery (grub_uint8_t *bufs[4], grub_size_t s, const int nbufs, - const unsigned *powers, - const unsigned *idx) -{ - grub_dprintf ("zfs", "recovering %u buffers\n", nbufs); - /* Now we have */ - /* b_i = sum (r_j* (x ** (powers[i] * idx[j])))*/ - /* Let's invert the matrix in question. */ - switch (nbufs) - { - /* Easy: r_0 = bufs[0] / (x << (powers[i] * idx[j])). */ - case 1: - { - int add; - grub_uint8_t *a; - if (powers[0] == 0 || idx[0] == 0) - return GRUB_ERR_NONE; - add = 255 - ((powers[0] * idx[0]) % 255); - for (a = bufs[0]; s--; a++) - if (*a) - *a = powx[powx_inv[*a] + add]; - return GRUB_ERR_NONE; - } - /* Case 2x2: Let's use the determinant formula. */ - case 2: - { - grub_uint8_t det, det_inv; - grub_uint8_t matrixinv[2][2]; - unsigned i; - /* The determinant is: */ - det = (powx[(powers[0] * idx[0] + powers[1] * idx[1]) % 255] - ^ powx[(powers[0] * idx[1] + powers[1] * idx[0]) % 255]); - if (det == 0) - return grub_error (GRUB_ERR_BAD_FS, "singular recovery matrix"); - det_inv = powx[255 - powx_inv[det]]; - matrixinv[0][0] = gf_mul (powx[(powers[1] * idx[1]) % 255], det_inv); - matrixinv[1][1] = gf_mul (powx[(powers[0] * idx[0]) % 255], det_inv); - matrixinv[0][1] = gf_mul (powx[(powers[0] * idx[1]) % 255], det_inv); - matrixinv[1][0] = gf_mul (powx[(powers[1] * idx[0]) % 255], det_inv); - for (i = 0; i < s; i++) - { - grub_uint8_t b0, b1; - b0 = bufs[0][i]; - b1 = bufs[1][i]; - - bufs[0][i] = (gf_mul (b0, matrixinv[0][0]) - ^ gf_mul (b1, matrixinv[0][1])); - bufs[1][i] = (gf_mul (b0, matrixinv[1][0]) - ^ gf_mul (b1, matrixinv[1][1])); - } - return GRUB_ERR_NONE; - } - /* Otherwise use Gauss. */ - case 3: - { - grub_uint8_t matrix1[MAX_NBUFS][MAX_NBUFS], matrix2[MAX_NBUFS][MAX_NBUFS]; - int i, j, k; - - for (i = 0; i < nbufs; i++) - for (j = 0; j < nbufs; j++) - matrix1[i][j] = powx[(powers[i] * idx[j]) % 255]; - for (i = 0; i < nbufs; i++) - for (j = 0; j < nbufs; j++) - matrix2[i][j] = 0; - for (i = 0; i < nbufs; i++) - matrix2[i][i] = 1; - - for (i = 0; i < nbufs; i++) - { - grub_uint8_t mul; - for (j = i; j < nbufs; j++) - if (matrix1[i][j]) - break; - if (j == nbufs) - return grub_error (GRUB_ERR_BAD_FS, "singular recovery matrix"); - if (j != i) - { - int xchng; - xchng = j; - for (j = 0; j < nbufs; j++) - { - grub_uint8_t t; - t = matrix1[xchng][j]; - matrix1[xchng][j] = matrix1[i][j]; - matrix1[i][j] = t; - } - for (j = 0; j < nbufs; j++) - { - grub_uint8_t t; - t = matrix2[xchng][j]; - matrix2[xchng][j] = matrix2[i][j]; - matrix2[i][j] = t; - } - } - mul = powx[255 - powx_inv[matrix1[i][i]]]; - for (j = 0; j < nbufs; j++) - matrix1[i][j] = gf_mul (matrix1[i][j], mul); - for (j = 0; j < nbufs; j++) - matrix2[i][j] = gf_mul (matrix2[i][j], mul); - for (j = i + 1; j < nbufs; j++) - { - mul = matrix1[j][i]; - for (k = 0; k < nbufs; k++) - matrix1[j][k] ^= gf_mul (matrix1[i][k], mul); - for (k = 0; k < nbufs; k++) - matrix2[j][k] ^= gf_mul (matrix2[i][k], mul); - } - } - for (i = nbufs - 1; i >= 0; i--) - { - for (j = 0; j < i; j++) - { - grub_uint8_t mul; - mul = matrix1[j][i]; - for (k = 0; k < nbufs; k++) - matrix1[j][k] ^= gf_mul (matrix1[i][k], mul); - for (k = 0; k < nbufs; k++) - matrix2[j][k] ^= gf_mul (matrix2[i][k], mul); - } - } - - for (i = 0; i < (int) s; i++) - { - grub_uint8_t b[MAX_NBUFS]; - for (j = 0; j < nbufs; j++) - b[j] = bufs[j][i]; - for (j = 0; j < nbufs; j++) - { - bufs[j][i] = 0; - for (k = 0; k < nbufs; k++) - bufs[j][i] ^= gf_mul (matrix2[j][k], b[k]); - } - } - return GRUB_ERR_NONE; - } - default: - return grub_error (GRUB_ERR_BUG, "too big matrix"); - } -} - -static grub_err_t -read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, - grub_size_t len, void *buf) -{ - switch (desc->type) - { - case DEVICE_LEAF: - { - grub_uint64_t sector; - sector = DVA_OFFSET_TO_PHYS_SECTOR (offset); - if (!desc->dev) - { - return grub_error (GRUB_ERR_BAD_FS, - N_("couldn't find a necessary member device " - "of multi-device filesystem")); - } - /* read in a data block */ - return grub_disk_read (desc->dev->disk, sector, 0, len, buf); - } - case DEVICE_MIRROR: - { - grub_err_t err = GRUB_ERR_NONE; - unsigned i; - if (desc->n_children <= 0) - return grub_error (GRUB_ERR_BAD_FS, - "non-positive number of mirror children"); - for (i = 0; i < desc->n_children; i++) - { - err = read_device (offset, &desc->children[i], - len, buf); - if (!err) - break; - grub_errno = GRUB_ERR_NONE; - } - grub_errno = err; - - return err; - } - case DEVICE_RAIDZ: - { - unsigned c = 0; - grub_uint64_t high; - grub_uint64_t devn; - grub_uint64_t m; - grub_uint32_t s, orig_s; - void *orig_buf = buf; - grub_size_t orig_len = len; - grub_uint8_t *recovery_buf[4]; - grub_size_t recovery_len[4]; - unsigned recovery_idx[4]; - unsigned failed_devices = 0; - int idx, orig_idx; - - if (desc->nparity < 1 || desc->nparity > 3) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "raidz%d is not supported", desc->nparity); - - if (desc->n_children <= desc->nparity || desc->n_children < 1) - return grub_error(GRUB_ERR_BAD_FS, "too little devices for given parity"); - - orig_s = (((len + (1 << desc->ashift) - 1) >> desc->ashift) - + (desc->n_children - desc->nparity) - 1); - s = orig_s; - - high = grub_divmod64 ((offset >> desc->ashift), - desc->n_children, &m); - if (desc->nparity == 2) - c = 2; - if (desc->nparity == 3) - c = 3; - if (((len + (1 << desc->ashift) - 1) >> desc->ashift) - >= (desc->n_children - desc->nparity)) - idx = (desc->n_children - desc->nparity - 1); - else - idx = ((len + (1 << desc->ashift) - 1) >> desc->ashift) - 1; - orig_idx = idx; - while (len > 0) - { - grub_size_t csize; - grub_uint32_t bsize; - grub_err_t err; - bsize = s / (desc->n_children - desc->nparity); - - if (desc->nparity == 1 - && ((offset >> (desc->ashift + 20 - desc->max_children_ashift)) - & 1) == c) - c++; - - high = grub_divmod64 ((offset >> desc->ashift) + c, - desc->n_children, &devn); - csize = (grub_size_t) bsize << desc->ashift; - if (csize > len) - csize = len; - - grub_dprintf ("zfs", "RAIDZ mapping 0x%" PRIxGRUB_UINT64_T - "+%u (%" PRIxGRUB_SIZE ", %" PRIxGRUB_UINT32_T - ") -> (0x%" PRIxGRUB_UINT64_T ", 0x%" - PRIxGRUB_UINT64_T ")\n", - offset >> desc->ashift, c, len, bsize, high, - devn); - err = read_device ((high << desc->ashift) - | (offset & ((1 << desc->ashift) - 1)), - &desc->children[devn], - csize, buf); - if (err && failed_devices < desc->nparity) - { - recovery_buf[failed_devices] = buf; - recovery_len[failed_devices] = csize; - recovery_idx[failed_devices] = idx; - failed_devices++; - grub_errno = err = 0; - } - if (err) - return err; - - c++; - idx--; - s--; - buf = (char *) buf + csize; - len -= csize; - } - if (failed_devices) - { - unsigned redundancy_pow[4]; - unsigned cur_redundancy_pow = 0; - unsigned n_redundancy = 0; - unsigned i, j; - grub_err_t err; - - /* Compute mul. x**s has a period of 255. */ - if (powx[0] == 0) - { - grub_uint8_t cur = 1; - for (i = 0; i < 255; i++) - { - powx[i] = cur; - powx[i + 255] = cur; - powx_inv[cur] = i; - if (cur & 0x80) - cur = (cur << 1) ^ poly; - else - cur <<= 1; - } - } - - /* Read redundancy data. */ - for (n_redundancy = 0, cur_redundancy_pow = 0; - n_redundancy < failed_devices; - cur_redundancy_pow++) - { - high = grub_divmod64 ((offset >> desc->ashift) - + cur_redundancy_pow - + ((desc->nparity == 1) - && ((offset >> (desc->ashift + 20 - - desc->max_children_ashift)) - & 1)), - desc->n_children, &devn); - err = read_device ((high << desc->ashift) - | (offset & ((1 << desc->ashift) - 1)), - &desc->children[devn], - recovery_len[n_redundancy], - recovery_buf[n_redundancy]); - /* Ignore error if we may still have enough devices. */ - if (err && n_redundancy + desc->nparity - cur_redundancy_pow - 1 - >= failed_devices) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - if (err) - return err; - redundancy_pow[n_redundancy] = cur_redundancy_pow; - n_redundancy++; - } - /* Now xor-our the parts we already know. */ - buf = orig_buf; - len = orig_len; - s = orig_s; - idx = orig_idx; - - while (len > 0) - { - grub_size_t csize = s; - csize = ((csize / (desc->n_children - desc->nparity)) - << desc->ashift); - if (csize > len) - csize = len; - - for (j = 0; j < failed_devices; j++) - if (buf == recovery_buf[j]) - break; - - if (j == failed_devices) - for (j = 0; j < failed_devices; j++) - xor_out (recovery_buf[j], buf, - csize < recovery_len[j] ? csize : recovery_len[j], - idx, redundancy_pow[j]); - - s--; - buf = (char *) buf + csize; - len -= csize; - idx--; - } - for (i = 0; i < failed_devices - && recovery_len[i] == recovery_len[0]; - i++); - /* Since the chunks have variable length handle the last block - separately. */ - if (i != failed_devices) - { - grub_uint8_t *tmp_recovery_buf[4]; - for (j = 0; j < i; j++) - tmp_recovery_buf[j] = recovery_buf[j] + recovery_len[failed_devices - 1]; - err = recovery (tmp_recovery_buf, recovery_len[0] - recovery_len[failed_devices - 1], i, redundancy_pow, - recovery_idx); - if (err) - return err; - } - err = recovery (recovery_buf, recovery_len[failed_devices - 1], - failed_devices, redundancy_pow, recovery_idx); - if (err) - return err; - } - return GRUB_ERR_NONE; - } - } - return grub_error (GRUB_ERR_BAD_FS, "unsupported device type"); -} - -static grub_err_t -read_dva (const dva_t *dva, - grub_zfs_endian_t endian, struct grub_zfs_data *data, - void *buf, grub_size_t len) -{ - grub_uint64_t offset; - unsigned i; - grub_err_t err = 0; - int try = 0; - offset = dva_get_offset (dva, endian); - - for (try = 0; try < 2; try++) - { - for (i = 0; i < data->n_devices_attached; i++) - if (data->devices_attached[i].id == DVA_GET_VDEV (dva)) - { - err = read_device (offset, &data->devices_attached[i], len, buf); - if (!err) - return GRUB_ERR_NONE; - break; - } - if (try == 1) - break; - err = scan_devices (data); - if (err) - return err; - } - if (!err) - return grub_error (GRUB_ERR_BAD_FS, "unknown device %d", - (int) DVA_GET_VDEV (dva)); - return err; -} - -/* - * Read a block of data based on the gang block address dva, - * and put its data in buf. - * - */ -static grub_err_t -zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian, dva_t * dva, void *buf, - struct grub_zfs_data *data) -{ - zio_gbh_phys_t *zio_gb; - unsigned i; - grub_err_t err; - zio_cksum_t zc; - - grub_memset (&zc, 0, sizeof (zc)); - - zio_gb = grub_malloc (SPA_GANGBLOCKSIZE); - if (!zio_gb) - return grub_errno; - grub_dprintf ("zfs", endian == GRUB_ZFS_LITTLE_ENDIAN ? "little-endian gang\n" - :"big-endian gang\n"); - - err = read_dva (dva, endian, data, zio_gb, SPA_GANGBLOCKSIZE); - if (err) - { - grub_free (zio_gb); - return err; - } - - /* XXX */ - /* self checksuming the gang block header */ - ZIO_SET_CHECKSUM (&zc, DVA_GET_VDEV (dva), - dva_get_offset (dva, endian), bp->blk_birth, 0); - err = zio_checksum_verify (zc, ZIO_CHECKSUM_GANG_HEADER, endian, - (char *) zio_gb, SPA_GANGBLOCKSIZE); - if (err) - { - grub_free (zio_gb); - return err; - } - - endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1; - - for (i = 0; i < SPA_GBH_NBLKPTRS; i++) - { - if (BP_IS_HOLE(&zio_gb->zg_blkptr[i])) - continue; - - err = zio_read_data (&zio_gb->zg_blkptr[i], endian, buf, data); - if (err) - { - grub_free (zio_gb); - return err; - } - buf = (char *) buf + get_psize (&zio_gb->zg_blkptr[i], endian); - } - grub_free (zio_gb); - return GRUB_ERR_NONE; -} - -/* - * Read in a block of raw data to buf. - */ -static grub_err_t -zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf, - struct grub_zfs_data *data) -{ - int i, psize; - grub_err_t err = GRUB_ERR_NONE; - - psize = get_psize (bp, endian); - - /* pick a good dva from the block pointer */ - for (i = 0; i < SPA_DVAS_PER_BP; i++) - { - if (bp->blk_dva[i].dva_word[0] == 0 && bp->blk_dva[i].dva_word[1] == 0) - continue; - - if ((grub_zfs_to_cpu64 (bp->blk_dva[i].dva_word[1], endian)>>63) & 1) - err = zio_read_gang (bp, endian, &bp->blk_dva[i], buf, data); - else - err = read_dva (&bp->blk_dva[i], endian, data, buf, psize); - if (!err) - return GRUB_ERR_NONE; - grub_errno = GRUB_ERR_NONE; - } - - if (!err) - err = grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid DVA"); - grub_errno = err; - - return err; -} - -/* - * buf must be at least BPE_GET_PSIZE(bp) bytes long (which will never be - * more than BPE_PAYLOAD_SIZE bytes). - */ -static grub_err_t -decode_embedded_bp_compressed(const blkptr_t *bp, void *buf) -{ - grub_size_t psize, i; - grub_uint8_t *buf8 = buf; - grub_uint64_t w = 0; - const grub_uint64_t *bp64 = (const grub_uint64_t *)bp; - - psize = BPE_GET_PSIZE(bp); - - /* - * Decode the words of the block pointer into the byte array. - * Low bits of first word are the first byte (little endian). - */ - for (i = 0; i < psize; i++) - { - if (i % sizeof (w) == 0) - { - /* beginning of a word */ - w = *bp64; - bp64++; - if (!BPE_IS_PAYLOADWORD(bp, bp64)) - bp64++; - } - buf8[i] = BF64_GET(w, (i % sizeof (w)) * 8, 8); - } - return GRUB_ERR_NONE; -} - -/* - * Read in a block of data, verify its checksum, decompress if needed, - * and put the uncompressed data in buf. - */ -static grub_err_t -zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, - grub_size_t *size, struct grub_zfs_data *data) -{ - grub_size_t lsize, psize; - unsigned int comp, encrypted; - char *compbuf = NULL; - grub_err_t err; - zio_cksum_t zc = bp->blk_cksum; - grub_uint32_t checksum; - - *buf = NULL; - - checksum = (grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 40) & 0xff; - comp = (grub_zfs_to_cpu64((bp)->blk_prop, endian)>>32) & 0x7f; - encrypted = ((grub_zfs_to_cpu64((bp)->blk_prop, endian) >> 60) & 3); - if (BP_IS_EMBEDDED(bp)) - { - if (BPE_GET_ETYPE(bp) != BP_EMBEDDED_TYPE_DATA) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported embedded BP (type=%" - PRIuGRUB_UINT64_T ")\n", - BPE_GET_ETYPE (bp)); - lsize = BPE_GET_LSIZE(bp); - psize = BF64_GET_SB(grub_zfs_to_cpu64 ((bp)->blk_prop, endian), 25, 7, 0, 1); - } - else - { - lsize = (BP_IS_HOLE(bp) ? 0 : - (((grub_zfs_to_cpu64 ((bp)->blk_prop, endian) & 0xffff) + 1) - << SPA_MINBLOCKSHIFT)); - psize = get_psize (bp, endian); - } - grub_dprintf("zfs", "zio_read: E %d: size %" PRIdGRUB_SSIZE "/%" - PRIdGRUB_SSIZE "\n", (int)BP_IS_EMBEDDED(bp), lsize, psize); - - if (size) - *size = lsize; - - if (comp >= ZIO_COMPRESS_FUNCTIONS) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "compression algorithm %u not supported\n", (unsigned int) comp); - - if (comp != ZIO_COMPRESS_OFF && decomp_table[comp].decomp_func == NULL) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "compression algorithm %s not supported\n", decomp_table[comp].name); - - if (comp != ZIO_COMPRESS_OFF) - /* It's not really necessary to align to 16, just for safety. */ - compbuf = grub_malloc (ALIGN_UP (psize, 16)); - else - compbuf = *buf = grub_malloc (lsize); - if (! compbuf) - return grub_errno; - - grub_dprintf ("zfs", "endian = %d\n", endian); - if (BP_IS_EMBEDDED(bp)) - err = decode_embedded_bp_compressed(bp, compbuf); - else - { - err = zio_read_data (bp, endian, compbuf, data); - /* FIXME is it really necessary? */ - if (comp != ZIO_COMPRESS_OFF) - grub_memset (compbuf + psize, 0, ALIGN_UP (psize, 16) - psize); - } - if (err) - { - grub_free (compbuf); - *buf = NULL; - return err; - } - - if (!BP_IS_EMBEDDED(bp)) - { - err = zio_checksum_verify (zc, checksum, endian, - compbuf, psize); - if (err) - { - grub_dprintf ("zfs", "incorrect checksum\n"); - grub_free (compbuf); - *buf = NULL; - return err; - } - } - - if (encrypted) - { - if (!grub_zfs_decrypt) - err = grub_error (GRUB_ERR_BAD_FS, - N_("module `%s' isn't loaded"), - "zfscrypt"); - else - { - unsigned i, besti = 0; - grub_uint64_t bestval = 0; - for (i = 0; i < data->subvol.nkeys; i++) - if (data->subvol.keyring[i].txg <= grub_zfs_to_cpu64 (bp->blk_birth, - endian) - && data->subvol.keyring[i].txg > bestval) - { - besti = i; - bestval = data->subvol.keyring[i].txg; - } - if (bestval == 0) - { - grub_free (compbuf); - *buf = NULL; - grub_dprintf ("zfs", "no key for txg %" PRIxGRUB_UINT64_T "\n", - grub_zfs_to_cpu64 (bp->blk_birth, - endian)); - return grub_error (GRUB_ERR_BAD_FS, "no key found in keychain"); - } - grub_dprintf ("zfs", "using key %u (%" PRIxGRUB_UINT64_T - ", %p) for txg %" PRIxGRUB_UINT64_T "\n", - besti, data->subvol.keyring[besti].txg, - data->subvol.keyring[besti].cipher, - grub_zfs_to_cpu64 (bp->blk_birth, - endian)); - err = grub_zfs_decrypt (data->subvol.keyring[besti].cipher, - data->subvol.keyring[besti].algo, - &(bp)->blk_dva[encrypted], - compbuf, psize, zc.zc_mac, - endian); - } - if (err) - { - grub_free (compbuf); - *buf = NULL; - return err; - } - } - - if (comp != ZIO_COMPRESS_OFF) - { - *buf = grub_malloc (lsize); - if (!*buf) - { - grub_free (compbuf); - return grub_errno; - } - - err = decomp_table[comp].decomp_func (compbuf, *buf, psize, lsize); - grub_free (compbuf); - if (err) - { - grub_free (*buf); - *buf = NULL; - return err; - } - } - - return GRUB_ERR_NONE; -} - -/* - * Get the block from a block id. - * push the block onto the stack. - * - */ -static grub_err_t -dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf, - grub_zfs_endian_t *endian_out, struct grub_zfs_data *data) -{ - int level; - grub_off_t idx; - blkptr_t *bp_array = dn->dn.dn_blkptr; - int epbs = dn->dn.dn_indblkshift - SPA_BLKPTRSHIFT; - blkptr_t *bp; - void *tmpbuf = 0; - grub_zfs_endian_t endian; - grub_err_t err = GRUB_ERR_NONE; - - bp = grub_malloc (sizeof (blkptr_t)); - if (!bp) - return grub_errno; - - endian = dn->endian; - for (level = dn->dn.dn_nlevels - 1; level >= 0; level--) - { - grub_dprintf ("zfs", "endian = %d\n", endian); - idx = (blkid >> (epbs * level)) & ((1 << epbs) - 1); - *bp = bp_array[idx]; - if (bp_array != dn->dn.dn_blkptr) - { - grub_free (bp_array); - bp_array = 0; - } - - if (BP_IS_HOLE (bp)) - { - grub_size_t size = grub_zfs_to_cpu16 (dn->dn.dn_datablkszsec, - dn->endian) - << SPA_MINBLOCKSHIFT; - *buf = grub_malloc (size); - if (!*buf) - { - err = grub_errno; - break; - } - grub_memset (*buf, 0, size); - endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1; - break; - } - if (level == 0) - { - grub_dprintf ("zfs", "endian = %d\n", endian); - err = zio_read (bp, endian, buf, 0, data); - endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1; - break; - } - grub_dprintf ("zfs", "endian = %d\n", endian); - err = zio_read (bp, endian, &tmpbuf, 0, data); - endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1; - if (err) - break; - bp_array = tmpbuf; - } - if (bp_array != dn->dn.dn_blkptr) - grub_free (bp_array); - if (endian_out) - *endian_out = endian; - - grub_free (bp); - return err; -} - -/* - * mzap_lookup: Looks up property described by "name" and returns the value - * in "value". - */ -static grub_err_t -mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian, - grub_uint32_t objsize, const char *name, grub_uint64_t * value, - int case_insensitive) -{ - grub_uint32_t i, chunks; - mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk; - - if (objsize < MZAP_ENT_LEN) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), name); - chunks = objsize / MZAP_ENT_LEN - 1; - for (i = 0; i < chunks; i++) - { - if (case_insensitive ? (grub_strcasecmp (mzap_ent[i].mze_name, name) == 0) - : (grub_strcmp (mzap_ent[i].mze_name, name) == 0)) - { - *value = grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian); - return GRUB_ERR_NONE; - } - } - - return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), name); -} - -static int -mzap_iterate (mzap_phys_t * zapobj, grub_zfs_endian_t endian, int objsize, - int (*hook) (const char *name, grub_uint64_t val, - struct grub_zfs_dir_ctx *ctx), - struct grub_zfs_dir_ctx *ctx) -{ - int i, chunks; - mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk; - - chunks = objsize / MZAP_ENT_LEN - 1; - for (i = 0; i < chunks; i++) - { - grub_dprintf ("zfs", "zap: name = %s, value = %llx, cd = %x\n", - mzap_ent[i].mze_name, (long long)mzap_ent[i].mze_value, - (int)mzap_ent[i].mze_cd); - if (hook (mzap_ent[i].mze_name, - grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian), ctx)) - return 1; - } - - return 0; -} - -static grub_uint64_t -zap_hash (grub_uint64_t salt, const char *name, - int case_insensitive) -{ - static grub_uint64_t table[256]; - const grub_uint8_t *cp; - grub_uint8_t c; - grub_uint64_t crc = salt; - - if (table[128] == 0) - { - grub_uint64_t *ct; - int i, j; - for (i = 0; i < 256; i++) - { - for (ct = table + i, *ct = i, j = 8; j > 0; j--) - *ct = (*ct >> 1) ^ (-(*ct & 1) & ZFS_CRC64_POLY); - } - } - - if (case_insensitive) - for (cp = (const grub_uint8_t *) name; (c = *cp) != '\0'; cp++) - crc = (crc >> 8) ^ table[(crc ^ grub_toupper (c)) & 0xFF]; - else - for (cp = (const grub_uint8_t *) name; (c = *cp) != '\0'; cp++) - crc = (crc >> 8) ^ table[(crc ^ c) & 0xFF]; - - /* - * Only use 28 bits, since we need 4 bits in the cookie for the - * collision differentiator. We MUST use the high bits, since - * those are the onces that we first pay attention to when - * chosing the bucket. - */ - crc &= ~((1ULL << (64 - ZAP_HASHBITS)) - 1); - - return crc; -} - -/* - * Only to be used on 8-bit arrays. - * array_len is actual len in bytes (not encoded le_value_length). - * buf is null-terminated. - */ - -static inline int -name_cmp (const char *s1, const char *s2, grub_size_t n, - int case_insensitive) -{ - const char *t1 = (const char *) s1; - const char *t2 = (const char *) s2; - - if (!case_insensitive) - return grub_memcmp (t1, t2, n); - - while (n--) - { - if (grub_toupper (*t1) != grub_toupper (*t2)) - return (int) grub_toupper (*t1) - (int) grub_toupper (*t2); - - t1++; - t2++; - } - - return 0; -} - -/* XXX */ -static int -zap_leaf_array_equal (zap_leaf_phys_t * l, grub_zfs_endian_t endian, - int blksft, int chunk, grub_size_t array_len, - const char *buf, int case_insensitive) -{ - grub_size_t bseen = 0; - - while (bseen < array_len) - { - struct zap_leaf_array *la = &ZAP_LEAF_CHUNK (l, blksft, chunk)->l_array; - grub_size_t toread = array_len - bseen; - - if (toread > ZAP_LEAF_ARRAY_BYTES) - toread = ZAP_LEAF_ARRAY_BYTES; - - if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft)) - return 0; - - if (name_cmp ((char *) la->la_array, buf + bseen, toread, - case_insensitive) != 0) - break; - chunk = grub_zfs_to_cpu16 (la->la_next, endian); - bseen += toread; - } - return (bseen == array_len); -} - -/* XXX */ -static grub_err_t -zap_leaf_array_get (zap_leaf_phys_t * l, grub_zfs_endian_t endian, int blksft, - int chunk, grub_size_t array_len, char *buf) -{ - grub_size_t bseen = 0; - - while (bseen < array_len) - { - struct zap_leaf_array *la; - grub_size_t toread = array_len - bseen; - - if (toread > ZAP_LEAF_ARRAY_BYTES) - toread = ZAP_LEAF_ARRAY_BYTES; - - if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft)) - /* Don't use grub_error because this error is to be ignored. */ - return GRUB_ERR_BAD_FS; - - la = &ZAP_LEAF_CHUNK (l, blksft, chunk)->l_array; - grub_memcpy (buf + bseen,la->la_array, toread); - chunk = grub_zfs_to_cpu16 (la->la_next, endian); - bseen += toread; - } - return GRUB_ERR_NONE; -} - - -/* - * Given a zap_leaf_phys_t, walk thru the zap leaf chunks to get the - * value for the property "name". - * - */ -/* XXX */ -static grub_err_t -zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, - int blksft, grub_uint64_t h, - const char *name, grub_uint64_t * value, - int case_insensitive) -{ - grub_uint16_t chunk; - struct zap_leaf_entry *le; - - /* Verify if this is a valid leaf block */ - if (grub_zfs_to_cpu64 (l->l_hdr.lh_block_type, endian) != ZBT_LEAF) - return grub_error (GRUB_ERR_BAD_FS, "invalid leaf type"); - if (grub_zfs_to_cpu32 (l->l_hdr.lh_magic, endian) != ZAP_LEAF_MAGIC) - return grub_error (GRUB_ERR_BAD_FS, "invalid leaf magic"); - - for (chunk = grub_zfs_to_cpu16 (l->l_hash[LEAF_HASH (blksft, h, l)], endian); - chunk != CHAIN_END; chunk = grub_zfs_to_cpu16 (le->le_next, endian)) - { - - if (chunk >= ZAP_LEAF_NUMCHUNKS (blksft)) - return grub_error (GRUB_ERR_BAD_FS, "invalid chunk number"); - - le = ZAP_LEAF_ENTRY (l, blksft, chunk); - - /* Verify the chunk entry */ - if (le->le_type != ZAP_CHUNK_ENTRY) - return grub_error (GRUB_ERR_BAD_FS, "invalid chunk entry"); - - if (grub_zfs_to_cpu64 (le->le_hash,endian) != h) - continue; - - grub_dprintf ("zfs", "fzap: length %d\n", (int) le->le_name_length); - - if (zap_leaf_array_equal (l, endian, blksft, - grub_zfs_to_cpu16 (le->le_name_chunk,endian), - grub_zfs_to_cpu16 (le->le_name_length, endian), - name, case_insensitive)) - { - struct zap_leaf_array *la; - - if (le->le_int_size != 8 || grub_zfs_to_cpu16 (le->le_value_length, - endian) != 1) - return grub_error (GRUB_ERR_BAD_FS, "invalid leaf chunk entry"); - - /* get the uint64_t property value */ - la = &ZAP_LEAF_CHUNK (l, blksft, le->le_value_chunk)->l_array; - - *value = grub_be_to_cpu64 (la->la_array64); - - return GRUB_ERR_NONE; - } - } - - return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), name); -} - - -/* Verify if this is a fat zap header block */ -static grub_err_t -zap_verify (zap_phys_t *zap, grub_zfs_endian_t endian) -{ - if (grub_zfs_to_cpu64 (zap->zap_magic, endian) != (grub_uint64_t) ZAP_MAGIC) - return grub_error (GRUB_ERR_BAD_FS, "bad ZAP magic"); - - if (zap->zap_salt == 0) - return grub_error (GRUB_ERR_BAD_FS, "bad ZAP salt"); - - return GRUB_ERR_NONE; -} - -/* - * Fat ZAP lookup - * - */ -/* XXX */ -static grub_err_t -fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, - const char *name, grub_uint64_t * value, - struct grub_zfs_data *data, int case_insensitive) -{ - void *l; - grub_uint64_t hash, idx, blkid; - int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, - zap_dnode->endian) << DNODE_SHIFT); - grub_err_t err; - grub_zfs_endian_t leafendian; - - err = zap_verify (zap, zap_dnode->endian); - if (err) - return err; - - hash = zap_hash (zap->zap_salt, name, case_insensitive); - - /* get block id from index */ - if (zap->zap_ptrtbl.zt_numblks != 0) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "external pointer tables not supported"); - idx = ZAP_HASH_IDX (hash, zap->zap_ptrtbl.zt_shift); - blkid = grub_zfs_to_cpu64 (((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))], zap_dnode->endian); - - /* Get the leaf block */ - if ((1U << blksft) < sizeof (zap_leaf_phys_t)) - return grub_error (GRUB_ERR_BAD_FS, "ZAP leaf is too small"); - err = dmu_read (zap_dnode, blkid, &l, &leafendian, data); - if (err) - return err; - - err = zap_leaf_lookup (l, leafendian, blksft, hash, name, value, - case_insensitive); - grub_free (l); - return err; -} - -/* XXX */ -static int -fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, - grub_size_t name_elem_length, - int (*hook) (const void *name, grub_size_t name_length, - const void *val_in, - grub_size_t nelem, grub_size_t elemsize, - void *data), - void *hook_data, struct grub_zfs_data *data) -{ - zap_leaf_phys_t *l; - void *l_in; - grub_uint64_t idx, idx2, blkid; - grub_uint16_t chunk; - int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, - zap_dnode->endian) << DNODE_SHIFT); - grub_err_t err; - grub_zfs_endian_t endian; - grub_size_t sz; - - if (zap_verify (zap, zap_dnode->endian)) - return 0; - - /* get block id from index */ - if (zap->zap_ptrtbl.zt_numblks != 0) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "external pointer tables not supported"); - return 0; - } - /* Get the leaf block */ - if ((1U << blksft) < sizeof (zap_leaf_phys_t)) - { - grub_error (GRUB_ERR_BAD_FS, "ZAP leaf is too small"); - return 0; - } - for (idx = 0; idx < (1ULL << zap->zap_ptrtbl.zt_shift); idx++) - { - blkid = grub_zfs_to_cpu64 (((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))], - zap_dnode->endian); - - for (idx2 = 0; idx2 < idx; idx2++) - if (blkid == grub_zfs_to_cpu64 (((grub_uint64_t *) zap)[idx2 + (1 << (blksft - 3 - 1))], - zap_dnode->endian)) - break; - if (idx2 != idx) - continue; - - err = dmu_read (zap_dnode, blkid, &l_in, &endian, data); - l = l_in; - if (err) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - - /* Verify if this is a valid leaf block */ - if (grub_zfs_to_cpu64 (l->l_hdr.lh_block_type, endian) != ZBT_LEAF) - { - grub_free (l); - continue; - } - if (grub_zfs_to_cpu32 (l->l_hdr.lh_magic, endian) != ZAP_LEAF_MAGIC) - { - grub_free (l); - continue; - } - - for (chunk = 0; chunk < ZAP_LEAF_NUMCHUNKS (blksft); chunk++) - { - char *buf; - struct zap_leaf_entry *le; - char *val; - grub_size_t val_length; - le = ZAP_LEAF_ENTRY (l, blksft, chunk); - - /* Verify the chunk entry */ - if (le->le_type != ZAP_CHUNK_ENTRY) - continue; - - if (grub_mul (grub_zfs_to_cpu16 (le->le_name_length, endian), name_elem_length, &sz) || - grub_add (sz, 1, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("buffer size overflow")); - grub_free (l); - return grub_errno; - } - buf = grub_malloc (sz); - if (!buf) - { - grub_free (l); - return grub_errno; - } - if (zap_leaf_array_get (l, endian, blksft, - grub_zfs_to_cpu16 (le->le_name_chunk, - endian), - grub_zfs_to_cpu16 (le->le_name_length, - endian) - * name_elem_length, buf)) - { - grub_free (buf); - continue; - } - buf[le->le_name_length * name_elem_length] = 0; - - val_length = ((int) le->le_value_length - * (int) le->le_int_size); - val = grub_malloc (grub_zfs_to_cpu16 (val_length, endian)); - if (!val) - { - grub_free (l); - grub_free (buf); - return grub_errno; - } - if (zap_leaf_array_get (l, endian, blksft, - grub_zfs_to_cpu16 (le->le_value_chunk, - endian), - val_length, val)) - { - grub_free (buf); - grub_free (val); - continue; - } - - if (hook (buf, le->le_name_length, - val, le->le_value_length, le->le_int_size, hook_data)) - { - grub_free (l); - return 1; - } - grub_free (buf); - grub_free (val); - } - grub_free (l); - } - return 0; -} - -/* - * Read in the data of a zap object and find the value for a matching - * property name. - * - */ -static grub_err_t -zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val, - struct grub_zfs_data *data, int case_insensitive) -{ - grub_uint64_t block_type; - grub_uint32_t size; - void *zapbuf; - grub_err_t err; - grub_zfs_endian_t endian; - - grub_dprintf ("zfs", "looking for '%s'\n", name); - - /* Read in the first block of the zap object data. */ - size = (grub_uint32_t) grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, - zap_dnode->endian) << SPA_MINBLOCKSHIFT; - err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data); - if (err) - return err; - block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian); - - grub_dprintf ("zfs", "zap read\n"); - - if (block_type == ZBT_MICRO) - { - grub_dprintf ("zfs", "micro zap\n"); - err = mzap_lookup (zapbuf, endian, size, name, val, - case_insensitive); - grub_dprintf ("zfs", "returned %d\n", err); - grub_free (zapbuf); - return err; - } - else if (block_type == ZBT_HEADER) - { - grub_dprintf ("zfs", "fat zap\n"); - /* this is a fat zap */ - err = fzap_lookup (zap_dnode, zapbuf, name, val, data, - case_insensitive); - grub_dprintf ("zfs", "returned %d\n", err); - grub_free (zapbuf); - return err; - } - - grub_free (zapbuf); - return grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); -} - -/* Context for zap_iterate_u64. */ -struct zap_iterate_u64_ctx -{ - int (*hook) (const char *, grub_uint64_t, struct grub_zfs_dir_ctx *); - struct grub_zfs_dir_ctx *dir_ctx; -}; - -/* Helper for zap_iterate_u64. */ -static int -zap_iterate_u64_transform (const void *name, - grub_size_t namelen __attribute__ ((unused)), - const void *val_in, - grub_size_t nelem, - grub_size_t elemsize, - void *data) -{ - struct zap_iterate_u64_ctx *ctx = data; - - if (elemsize != sizeof (grub_uint64_t) || nelem != 1) - return 0; - return ctx->hook (name, grub_be_to_cpu64 (*(const grub_uint64_t *) val_in), - ctx->dir_ctx); -} - -static int -zap_iterate_u64 (dnode_end_t * zap_dnode, - int (*hook) (const char *name, grub_uint64_t val, - struct grub_zfs_dir_ctx *ctx), - struct grub_zfs_data *data, struct grub_zfs_dir_ctx *ctx) -{ - grub_uint64_t block_type; - int size; - void *zapbuf; - grub_err_t err; - int ret; - grub_zfs_endian_t endian; - - /* Read in the first block of the zap object data. */ - size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << SPA_MINBLOCKSHIFT; - err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data); - if (err) - return 0; - block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian); - - grub_dprintf ("zfs", "zap iterate\n"); - - if (block_type == ZBT_MICRO) - { - grub_dprintf ("zfs", "micro zap\n"); - ret = mzap_iterate (zapbuf, endian, size, hook, ctx); - grub_free (zapbuf); - return ret; - } - else if (block_type == ZBT_HEADER) - { - struct zap_iterate_u64_ctx transform_ctx = { - .hook = hook, - .dir_ctx = ctx - }; - - grub_dprintf ("zfs", "fat zap\n"); - /* this is a fat zap */ - ret = fzap_iterate (zap_dnode, zapbuf, 1, - zap_iterate_u64_transform, &transform_ctx, data); - grub_free (zapbuf); - return ret; - } - grub_free (zapbuf); - grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); - return 0; -} - -static int -zap_iterate (dnode_end_t * zap_dnode, - grub_size_t nameelemlen, - int (*hook) (const void *name, grub_size_t namelen, - const void *val_in, - grub_size_t nelem, grub_size_t elemsize, - void *data), - void *hook_data, struct grub_zfs_data *data) -{ - grub_uint64_t block_type; - void *zapbuf; - grub_err_t err; - int ret; - grub_zfs_endian_t endian; - - /* Read in the first block of the zap object data. */ - err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data); - if (err) - return 0; - block_type = grub_zfs_to_cpu64 (*((grub_uint64_t *) zapbuf), endian); - - grub_dprintf ("zfs", "zap iterate\n"); - - if (block_type == ZBT_MICRO) - { - grub_error (GRUB_ERR_BAD_FS, "micro ZAP where FAT ZAP expected"); - grub_free (zapbuf); - return 0; - } - if (block_type == ZBT_HEADER) - { - grub_dprintf ("zfs", "fat zap\n"); - /* this is a fat zap */ - ret = fzap_iterate (zap_dnode, zapbuf, nameelemlen, hook, hook_data, - data); - grub_free (zapbuf); - return ret; - } - grub_free (zapbuf); - grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); - return 0; -} - - -/* - * Get the dnode of an object number from the metadnode of an object set. - * - * Input - * mdn - metadnode to get the object dnode - * objnum - object number for the object dnode - * buf - data buffer that holds the returning dnode - */ -static grub_err_t -dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type, - dnode_end_t * buf, struct grub_zfs_data *data) -{ - grub_uint64_t blkid, blksz; /* the block id this object dnode is in */ - int epbs; /* shift of number of dnodes in a block */ - int idx; /* index within a block */ - void *dnbuf; - grub_err_t err; - grub_zfs_endian_t endian; - - objnum &= DNODE_NUM_MASK; - - blksz = grub_zfs_to_cpu16 (mdn->dn.dn_datablkszsec, - mdn->endian) << SPA_MINBLOCKSHIFT; - epbs = zfs_log2 (blksz) - DNODE_SHIFT; - - /* While this should never happen, we should check that epbs is not negative. */ - if (epbs < 0) - epbs = 0; - - blkid = objnum >> epbs; - idx = objnum & ((1 << epbs) - 1); - - if (data->dnode_buf != NULL && grub_memcmp (data->dnode_mdn, &mdn->dn, - sizeof (mdn->dn)) == 0 - && objnum >= data->dnode_start && objnum < data->dnode_end) - { - grub_memmove (&(buf->dn), &(data->dnode_buf)[idx], DNODE_SIZE); - buf->endian = data->dnode_endian; - if (type && buf->dn.dn_type != type) - return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type"); - return GRUB_ERR_NONE; - } - - grub_dprintf ("zfs", "endian = %d, blkid=%llx\n", mdn->endian, - (unsigned long long) blkid); - err = dmu_read (mdn, blkid, &dnbuf, &endian, data); - if (err) - return err; - grub_dprintf ("zfs", "alive\n"); - - grub_free (data->dnode_buf); - grub_free (data->dnode_mdn); - data->dnode_mdn = grub_malloc (sizeof (*mdn)); - if (! data->dnode_mdn) - { - grub_errno = GRUB_ERR_NONE; - data->dnode_buf = 0; - } - else - { - grub_memcpy (data->dnode_mdn, mdn, sizeof (*mdn)); - data->dnode_buf = dnbuf; - data->dnode_start = blkid << epbs; - data->dnode_end = (blkid + 1) << epbs; - data->dnode_endian = endian; - } - - grub_memmove (&(buf->dn), (dnode_phys_t *) dnbuf + idx, DNODE_SIZE); - if (data->dnode_buf == 0) - /* dnbuf not used anymore if data->dnode_mdn malloc failed */ - grub_free (dnbuf); - buf->endian = endian; - if (type && buf->dn.dn_type != type) - return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type"); - - return GRUB_ERR_NONE; -} - -#pragma GCC diagnostic ignored "-Wstrict-aliasing" - -/* - * Get the file dnode for a given file name where mdn is the meta dnode - * for this ZFS object set. When found, place the file dnode in dn. - * The 'path' argument will be mangled. - * - */ -static grub_err_t -dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, - struct grub_zfs_data *data) -{ - grub_uint64_t objnum, version; - char *cname, ch; - grub_err_t err = GRUB_ERR_NONE; - char *path, *path_buf; - struct dnode_chain - { - struct dnode_chain *next; - dnode_end_t dn; - }; - struct dnode_chain *dnode_path = 0, *dn_new, *root; - - dn_new = grub_malloc (sizeof (*dn_new)); - if (! dn_new) - return grub_errno; - dn_new->next = 0; - dnode_path = root = dn_new; - - err = dnode_get (&subvol->mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, - &(dnode_path->dn), data); - if (err) - { - grub_free (dn_new); - return err; - } - - err = zap_lookup (&(dnode_path->dn), ZPL_VERSION_STR, &version, - data, 0); - if (err) - { - grub_free (dn_new); - return err; - } - - if (version > ZPL_VERSION) - { - grub_free (dn_new); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "too new ZPL version"); - } - - err = zap_lookup (&(dnode_path->dn), "casesensitivity", - &subvol->case_insensitive, - data, 0); - if (err == GRUB_ERR_FILE_NOT_FOUND) - { - grub_errno = GRUB_ERR_NONE; - subvol->case_insensitive = 0; - } - - err = zap_lookup (&(dnode_path->dn), ZFS_ROOT_OBJ, &objnum, data, 0); - if (err) - { - grub_free (dn_new); - return err; - } - - err = dnode_get (&subvol->mdn, objnum, 0, &(dnode_path->dn), data); - if (err) - { - grub_free (dn_new); - return err; - } - - path = path_buf = grub_strdup (path_in); - if (!path_buf) - { - grub_free (dn_new); - return grub_errno; - } - - while (1) - { - /* skip leading slashes */ - while (*path == '/') - path++; - if (!*path) - break; - /* get the next component name */ - cname = path; - while (*path && *path != '/') - path++; - /* Skip dot. */ - if (cname + 1 == path && cname[0] == '.') - continue; - /* Handle double dot. */ - if (cname + 2 == path && cname[0] == '.' && cname[1] == '.') - { - if (dn_new->next) - { - dn_new = dnode_path; - dnode_path = dn_new->next; - grub_free (dn_new); - } - else - { - err = grub_error (GRUB_ERR_FILE_NOT_FOUND, - "can't resolve .."); - break; - } - continue; - } - - ch = *path; - *path = 0; /* ensure null termination */ - - if (dnode_path->dn.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS) - { - err = grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); - break; - } - err = zap_lookup (&(dnode_path->dn), cname, &objnum, - data, subvol->case_insensitive); - if (err) - break; - - dn_new = grub_malloc (sizeof (*dn_new)); - if (! dn_new) - { - err = grub_errno; - break; - } - dn_new->next = dnode_path; - dnode_path = dn_new; - - objnum = ZFS_DIRENT_OBJ (objnum); - err = dnode_get (&subvol->mdn, objnum, 0, &(dnode_path->dn), data); - if (err) - break; - - *path = ch; - if (dnode_path->dn.dn.dn_bonustype == DMU_OT_ZNODE - && ((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa) - { - char *sym_value; - grub_size_t sz; - grub_size_t sym_sz; - int free_symval = 0; - char *oldpath = path, *oldpathbuf = path_buf; - sym_value = ((char *) DN_BONUS (&dnode_path->dn.dn) + sizeof (struct znode_phys)); - - sym_sz = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_size, dnode_path->dn.endian); - - if (dnode_path->dn.dn.dn_flags & 1) - { - grub_size_t block; - grub_size_t blksz; - blksz = (grub_zfs_to_cpu16 (dnode_path->dn.dn.dn_datablkszsec, - dnode_path->dn.endian) - << SPA_MINBLOCKSHIFT); - - if (blksz == 0) - { - err = grub_error (GRUB_ERR_BAD_FS, "0-sized block"); - break; - } - - sym_value = grub_malloc (sym_sz); - if (!sym_value) - { - err = grub_errno; - break; - } - - for (block = 0; block < (sym_sz + blksz - 1) / blksz; block++) - { - void *t; - grub_size_t movesize; - - err = dmu_read (&(dnode_path->dn), block, &t, 0, data); - if (err) - { - grub_free (sym_value); - break; - } - - movesize = sym_sz - block * blksz; - if (movesize > blksz) - movesize = blksz; - - grub_memcpy (sym_value + block * blksz, t, movesize); - grub_free (t); - } - if (err) - break; - free_symval = 1; - } - - if (grub_add (sym_sz, grub_strlen (oldpath), &sz) || - grub_add (sz, 1, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("path buffer size overflow")); - grub_free (oldpathbuf); - if (free_symval) - grub_free (sym_value); - err = grub_errno; - break; - } - path = path_buf = grub_malloc (sz); - if (!path_buf) - { - grub_free (oldpathbuf); - if (free_symval) - grub_free (sym_value); - err = grub_errno; - break; - } - grub_memcpy (path, sym_value, sym_sz); - if (free_symval) - grub_free (sym_value); - path [sym_sz] = 0; - grub_memcpy (path + grub_strlen (path), oldpath, - grub_strlen (oldpath) + 1); - - grub_free (oldpathbuf); - - /* Restart dnode walk using path of symlink. */ - if (path[0] != '/') - { - dn_new = dnode_path; - dnode_path = dn_new->next; - grub_free (dn_new); - } - else while (dnode_path != root) - { - dn_new = dnode_path; - dnode_path = dn_new->next; - grub_free (dn_new); - } - dn_new = dnode_path; - } - if (dnode_path->dn.dn.dn_bonustype == DMU_OT_SA) - { - void *sahdrp; - int hdrsize; - grub_size_t sz; - bool free_sahdrp = false; - - if (dnode_path->dn.dn.dn_bonuslen != 0) - { - sahdrp = DN_BONUS (&dnode_path->dn.dn); - } - else if (dnode_path->dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR) - { - blkptr_t *bp = &dnode_path->dn.dn.dn_spill; - - err = zio_read (bp, dnode_path->dn.endian, &sahdrp, NULL, data); - if (err) - break; - free_sahdrp = true; - } - else - { - err = grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); - break; - } - - hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); - - if (((grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp - + hdrsize - + SA_TYPE_OFFSET), - dnode_path->dn.endian) >> 12) & 0xf) == 0xa) - { - char *sym_value = (char *) sahdrp + hdrsize + SA_SYMLINK_OFFSET; - grub_size_t sym_sz = - grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp - + hdrsize - + SA_SIZE_OFFSET), - dnode_path->dn.endian); - char *oldpath = path, *oldpathbuf = path_buf; - if (grub_add (sym_sz, grub_strlen (oldpath), &sz) || - grub_add (sz, 1, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("path buffer size overflow")); - grub_free (oldpathbuf); - err = grub_errno; - break; - } - path = path_buf = grub_malloc (sz); - if (!path_buf) - { - grub_free (oldpathbuf); - err = grub_errno; - break; - } - grub_memcpy (path, sym_value, sym_sz); - path [sym_sz] = 0; - grub_memcpy (path + grub_strlen (path), oldpath, - grub_strlen (oldpath) + 1); - - grub_free (oldpathbuf); - - /* Restart dnode walk using path of symlink. */ - if (path[0] != '/') - { - dn_new = dnode_path; - dnode_path = dn_new->next; - grub_free (dn_new); - } - else while (dnode_path != root) - { - dn_new = dnode_path; - dnode_path = dn_new->next; - grub_free (dn_new); - } - dn_new = dnode_path; - } - if (free_sahdrp == true) - grub_free (sahdrp); - - } - } - - if (!err) - grub_memcpy (dn, &(dnode_path->dn), sizeof (*dn)); - - while (dnode_path) - { - dn_new = dnode_path->next; - grub_free (dnode_path); - dnode_path = dn_new; - } - grub_free (path_buf); - return err; -} - -#if 0 -/* - * Get the default 'bootfs' property value from the rootpool. - * - */ -static grub_err_t -get_default_bootfsobj (dnode_phys_t * mosmdn, grub_uint64_t * obj, - struct grub_zfs_data *data) -{ - grub_uint64_t objnum = 0; - dnode_phys_t *dn; - if (!dn) - return grub_errno; - - if ((grub_errno = dnode_get (mosmdn, DMU_POOL_DIRECTORY_OBJECT, - DMU_OT_OBJECT_DIRECTORY, dn, data))) - { - grub_free (dn); - return (grub_errno); - } - - /* - * find the object number for 'pool_props', and get the dnode - * of the 'pool_props'. - */ - if (zap_lookup (dn, DMU_POOL_PROPS, &objnum, data)) - { - grub_free (dn); - return (GRUB_ERR_BAD_FS); - } - if ((grub_errno = dnode_get (mosmdn, objnum, DMU_OT_POOL_PROPS, dn, data))) - { - grub_free (dn); - return (grub_errno); - } - if (zap_lookup (dn, ZPOOL_PROP_BOOTFS, &objnum, data)) - { - grub_free (dn); - return (GRUB_ERR_BAD_FS); - } - - if (!objnum) - { - grub_free (dn); - return (GRUB_ERR_BAD_FS); - } - - *obj = objnum; - return (0); -} -#endif -/* - * Given a MOS metadnode, get the metadnode of a given filesystem name (fsname), - * e.g. pool/rootfs, or a given object number (obj), e.g. the object number - * of pool/rootfs. - * - * If no fsname and no obj are given, return the DSL_DIR metadnode. - * If fsname is given, return its metadnode and its matching object number. - * If only obj is given, return the metadnode for this object number. - * - */ -static grub_err_t -get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname, - dnode_end_t * mdn, struct grub_zfs_data *data) -{ - grub_uint64_t objnum; - grub_err_t err; - - grub_dprintf ("zfs", "endian = %d\n", mosmdn->endian); - - err = dnode_get (mosmdn, DMU_POOL_DIRECTORY_OBJECT, - DMU_OT_OBJECT_DIRECTORY, mdn, data); - if (err) - return err; - - grub_dprintf ("zfs", "alive\n"); - - err = zap_lookup (mdn, DMU_POOL_ROOT_DATASET, &objnum, data, 0); - if (err) - return err; - - grub_dprintf ("zfs", "alive\n"); - - err = dnode_get (mosmdn, objnum, 0, mdn, data); - if (err) - return err; - - grub_dprintf ("zfs", "alive\n"); - - while (*fsname) - { - grub_uint64_t childobj; - char *cname, ch; - - while (*fsname == '/') - fsname++; - - if (! *fsname || *fsname == '@') - break; - - cname = fsname; - while (*fsname && *fsname != '/') - fsname++; - ch = *fsname; - *fsname = 0; - - childobj = grub_zfs_to_cpu64 ((((dsl_dir_phys_t *) DN_BONUS (&mdn->dn)))->dd_child_dir_zapobj, mdn->endian); - err = dnode_get (mosmdn, childobj, - DMU_OT_DSL_DIR_CHILD_MAP, mdn, data); - if (err) - return err; - - err = zap_lookup (mdn, cname, &objnum, data, 0); - if (err) - return err; - - err = dnode_get (mosmdn, objnum, 0, mdn, data); - if (err) - return err; - - *fsname = ch; - } - return GRUB_ERR_NONE; -} - -static grub_err_t -make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data) -{ - objset_phys_t *osp; - blkptr_t *bp; - grub_size_t ospsize = 0; - grub_err_t err; - - grub_dprintf ("zfs", "endian = %d\n", mdn->endian); - - bp = &(((dsl_dataset_phys_t *) DN_BONUS (&mdn->dn))->ds_bp); - err = zio_read (bp, mdn->endian, (void **) &osp, &ospsize, data); - if (err) - return err; - if (ospsize < OBJSET_PHYS_SIZE_V14) - { - grub_free (osp); - return grub_error (GRUB_ERR_BAD_FS, "too small osp"); - } - - mdn->endian = (grub_zfs_to_cpu64 (bp->blk_prop, mdn->endian)>>63) & 1; - grub_memmove ((char *) &(mdn->dn), - (char *) &(osp)->os_meta_dnode, DNODE_SIZE); - grub_free (osp); - return GRUB_ERR_NONE; -} - -/* Context for dnode_get_fullpath. */ -struct dnode_get_fullpath_ctx -{ - struct subvolume *subvol; - grub_uint64_t salt; - int keyn; -}; - -/* Helper for dnode_get_fullpath. */ -static int -count_zap_keys (const void *name __attribute__ ((unused)), - grub_size_t namelen __attribute__ ((unused)), - const void *val_in __attribute__ ((unused)), - grub_size_t nelem __attribute__ ((unused)), - grub_size_t elemsize __attribute__ ((unused)), - void *data) -{ - struct dnode_get_fullpath_ctx *ctx = data; - - ctx->subvol->nkeys++; - return 0; -} - -/* Helper for dnode_get_fullpath. */ -static int -load_zap_key (const void *name, grub_size_t namelen, const void *val_in, - grub_size_t nelem, grub_size_t elemsize, void *data) -{ - struct dnode_get_fullpath_ctx *ctx = data; - - if (namelen != 1) - { - grub_dprintf ("zfs", "Unexpected key index size %" PRIuGRUB_SIZE "\n", - namelen); - return 0; - } - - if (elemsize != 1) - { - grub_dprintf ("zfs", "Unexpected key element size %" PRIuGRUB_SIZE "\n", - elemsize); - return 0; - } - - ctx->subvol->keyring[ctx->keyn].txg = - grub_be_to_cpu64 (*(grub_uint64_t *) name); - ctx->subvol->keyring[ctx->keyn].algo = - grub_le_to_cpu64 (*(grub_uint64_t *) val_in); - ctx->subvol->keyring[ctx->keyn].cipher = - grub_zfs_load_key (val_in, nelem, ctx->salt, - ctx->subvol->keyring[ctx->keyn].algo); - ctx->keyn++; - return 0; -} - -static grub_err_t -dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, - dnode_end_t * dn, int *isfs, - struct grub_zfs_data *data) -{ - char *fsname, *snapname; - const char *ptr_at, *filename; - grub_uint64_t headobj; - grub_uint64_t keychainobj; - grub_err_t err; - - ptr_at = grub_strchr (fullpath, '@'); - if (! ptr_at) - { - *isfs = 1; - filename = 0; - snapname = 0; - fsname = grub_strdup (fullpath); - if (!fsname) - return grub_errno; - } - else - { - const char *ptr_slash = grub_strchr (ptr_at, '/'); - - *isfs = 0; - fsname = grub_malloc (ptr_at - fullpath + 1); - if (!fsname) - return grub_errno; - grub_memcpy (fsname, fullpath, ptr_at - fullpath); - fsname[ptr_at - fullpath] = 0; - if (ptr_at[1] && ptr_at[1] != '/') - { - snapname = grub_malloc (ptr_slash - ptr_at); - if (!snapname) - { - grub_free (fsname); - return grub_errno; - } - grub_memcpy (snapname, ptr_at + 1, ptr_slash - ptr_at - 1); - snapname[ptr_slash - ptr_at - 1] = 0; - } - else - snapname = 0; - if (ptr_slash) - filename = ptr_slash; - else - filename = "/"; - grub_dprintf ("zfs", "fsname = '%s' snapname='%s' filename = '%s'\n", - fsname, snapname, filename); - } - grub_dprintf ("zfs", "alive\n"); - err = get_filesystem_dnode (&(data->mos), fsname, dn, data); - if (err) - { - grub_free (fsname); - grub_free (snapname); - return err; - } - - grub_dprintf ("zfs", "alive\n"); - - headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->dd_head_dataset_obj, dn->endian); - - grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian); - - err = dnode_get (&(data->mos), headobj, 0, &subvol->mdn, data); - if (err) - { - grub_free (fsname); - grub_free (snapname); - return err; - } - grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian); - - keychainobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->keychain, dn->endian); - if (grub_zfs_load_key && keychainobj) - { - struct dnode_get_fullpath_ctx ctx = { - .subvol = subvol, - .keyn = 0 - }; - dnode_end_t keychain_dn, props_dn; - grub_uint64_t propsobj; - propsobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->dd_props_zapobj, dn->endian); - - err = dnode_get (&(data->mos), propsobj, DMU_OT_DSL_PROPS, - &props_dn, data); - if (err) - { - grub_free (fsname); - grub_free (snapname); - return err; - } - - err = zap_lookup (&props_dn, "salt", &ctx.salt, data, 0); - if (err == GRUB_ERR_FILE_NOT_FOUND) - { - err = 0; - grub_errno = 0; - ctx.salt = 0; - } - if (err) - { - grub_dprintf ("zfs", "failed here\n"); - grub_free (fsname); - grub_free (snapname); - return err; - } - - err = dnode_get (&(data->mos), keychainobj, DMU_OT_DSL_KEYCHAIN, - &keychain_dn, data); - if (err) - { - grub_free (fsname); - grub_free (snapname); - return err; - } - subvol->nkeys = 0; - zap_iterate (&keychain_dn, 8, count_zap_keys, &ctx, data); - subvol->keyring = grub_calloc (subvol->nkeys, sizeof (subvol->keyring[0])); - if (!subvol->keyring) - { - grub_free (fsname); - grub_free (snapname); - return err; - } - zap_iterate (&keychain_dn, 8, load_zap_key, &ctx, data); - } - - if (snapname) - { - grub_uint64_t snapobj; - - snapobj = grub_zfs_to_cpu64 (((dsl_dataset_phys_t *) DN_BONUS (&subvol->mdn.dn))->ds_snapnames_zapobj, subvol->mdn.endian); - - err = dnode_get (&(data->mos), snapobj, - DMU_OT_DSL_DS_SNAP_MAP, &subvol->mdn, data); - if (!err) - err = zap_lookup (&subvol->mdn, snapname, &headobj, data, 0); - if (!err) - err = dnode_get (&(data->mos), headobj, 0, - &subvol->mdn, data); - if (!err && subvol->mdn.dn.dn_type != DMU_OT_DSL_DATASET && subvol->mdn.dn.dn_bonustype != DMU_OT_DSL_DATASET) { - grub_free (fsname); - grub_free (snapname); - return grub_error(GRUB_ERR_BAD_FS, "incorrect dataset dnode type"); - } - - if (err) - { - grub_free (fsname); - grub_free (snapname); - return err; - } - } - - subvol->obj = headobj; - - make_mdn (&subvol->mdn, data); - - grub_dprintf ("zfs", "endian = %d\n", subvol->mdn.endian); - - if (*isfs) - { - grub_free (fsname); - grub_free (snapname); - return GRUB_ERR_NONE; - } - err = dnode_get_path (subvol, filename, dn, data); - grub_free (fsname); - grub_free (snapname); - return err; -} - -static int -nvlist_find_value (const char *nvlist_in, const char *name, - int valtype, char **val, - grub_size_t *size_out, grub_size_t *nelm_out) -{ - grub_size_t nvp_name_len, name_len = grub_strlen(name); - int type; - const char *nvpair=NULL,*nvlist=nvlist_in; - char *nvp_name; - - /* Verify if the 1st and 2nd byte in the nvlist are valid. */ - /* NOTE: independently of what endianness header announces all - subsequent values are big-endian. */ - if (nvlist[0] != NV_ENCODE_XDR || (nvlist[1] != NV_LITTLE_ENDIAN - && nvlist[1] != NV_BIG_ENDIAN)) - { - grub_dprintf ("zfs", "incorrect nvlist header\n"); - grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist"); - return 0; - } - - /* - * Loop thru the nvpair list - * The XDR representation of an integer is in big-endian byte order. - */ - while ((nvpair=nvlist_next_nvpair(nvlist,nvpair))) - { - nvpair_name(nvpair,&nvp_name, &nvp_name_len); - type = nvpair_type(nvpair); - if (type == valtype - && (nvp_name_len == name_len - || (nvp_name_len > name_len && nvp_name[name_len] == '\0')) - && grub_memcmp (nvp_name, name, name_len) == 0) - { - return nvpair_value(nvpair,val,size_out,nelm_out); - } - } - return 0; -} - -int -grub_zfs_nvlist_lookup_uint64 (const char *nvlist, const char *name, - grub_uint64_t * out) -{ - char *nvpair; - grub_size_t size; - int found; - - found = nvlist_find_value (nvlist, name, DATA_TYPE_UINT64, &nvpair, &size, 0); - if (!found) - return 0; - if (size < sizeof (grub_uint64_t)) - { - grub_error (GRUB_ERR_BAD_FS, "invalid uint64"); - return 0; - } - - *out = grub_be_to_cpu64 (grub_get_unaligned64 (nvpair)); - return 1; -} - -char * -grub_zfs_nvlist_lookup_string (const char *nvlist, const char *name) -{ - char *nvpair; - char *ret; - grub_size_t slen; - grub_size_t size; - int found; - - found = nvlist_find_value (nvlist, name, DATA_TYPE_STRING, &nvpair, &size, 0); - if (!found) - return 0; - if (size < 4) - { - grub_error (GRUB_ERR_BAD_FS, "invalid string"); - return 0; - } - slen = grub_be_to_cpu32 (grub_get_unaligned32 (nvpair)); - if (slen > size - 4) - slen = size - 4; - ret = grub_malloc (slen + 1); - if (!ret) - return 0; - grub_memcpy (ret, nvpair + 4, slen); - ret[slen] = 0; - return ret; -} - -char * -grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name) -{ - char *nvpair; - char *ret; - grub_size_t size, sz; - int found; - - found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair, - &size, 0); - if (!found) - return 0; - - if (grub_add (size, 3 * sizeof (grub_uint32_t), &sz)) - return 0; - - ret = grub_zalloc (sz); - if (!ret) - return 0; - grub_memcpy (ret, nvlist, sizeof (grub_uint32_t)); - - grub_memcpy (ret + sizeof (grub_uint32_t), nvpair, size); - return ret; -} - -int -grub_zfs_nvlist_lookup_nvlist_array_get_nelm (const char *nvlist, - const char *name) -{ - char *nvpair; - grub_size_t nelm, size; - int found; - - found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST_ARRAY, &nvpair, - &size, &nelm); - if (! found) - return -1; - return nelm; -} - -static int -get_nvlist_size (const char *beg, const char *limit) -{ - const char *ptr; - grub_uint32_t encode_size; - - ptr = beg + 8; - - while (ptr < limit - && (encode_size = grub_be_to_cpu32 (grub_get_unaligned32 (ptr)))) - ptr += encode_size; /* goto the next nvpair */ - ptr += 8; - return (ptr > limit) ? -1 : (ptr - beg); -} - -char * -grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, const char *name, - grub_size_t index) -{ - char *nvpair, *nvpairptr; - int found; - char *ret; - grub_size_t size; - unsigned i; - grub_size_t nelm; - int elemsize = 0; - int sz; - - found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST_ARRAY, &nvpair, - &size, &nelm); - if (!found) - return 0; - if (index >= nelm) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "trying to lookup past nvlist array"); - return 0; - } - - nvpairptr = nvpair; - - for (i = 0; i < index; i++) - { - int r; - r = get_nvlist_size (nvpairptr, nvpair + size); - - if (r < 0) - { - grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist array"); - return NULL; - } - nvpairptr += r; - } - - elemsize = get_nvlist_size (nvpairptr, nvpair + size); - - if (elemsize < 0) - { - grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist array"); - return 0; - } - - if (grub_add (elemsize, sizeof (grub_uint32_t), &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("elemsize overflow")); - return 0; - } - ret = grub_zalloc (sz); - if (!ret) - return 0; - grub_memcpy (ret, nvlist, sizeof (grub_uint32_t)); - - grub_memcpy (ret + sizeof (grub_uint32_t), nvpairptr, elemsize); - return ret; -} - -static void -unmount_device (struct grub_zfs_device_desc *desc) -{ - unsigned i; - switch (desc->type) - { - case DEVICE_LEAF: - if (!desc->original && desc->dev) - grub_device_close (desc->dev); - return; - case DEVICE_RAIDZ: - case DEVICE_MIRROR: - for (i = 0; i < desc->n_children; i++) - unmount_device (&desc->children[i]); - grub_free (desc->children); - return; - } -} - -static void -zfs_unmount (struct grub_zfs_data *data) -{ - unsigned i; - for (i = 0; i < data->n_devices_attached; i++) - unmount_device (&data->devices_attached[i]); - grub_free (data->devices_attached); - grub_free (data->dnode_buf); - grub_free (data->dnode_mdn); - grub_free (data->file_buf); - for (i = 0; i < data->subvol.nkeys; i++) - grub_crypto_cipher_close (data->subvol.keyring[i].cipher); - grub_free (data->subvol.keyring); - grub_free (data); -} - -/* - * zfs_mount() locates a valid uberblock of the root pool and read in its MOS - * to the memory address MOS. - * - */ -static struct grub_zfs_data * -zfs_mount (grub_device_t dev) -{ - struct grub_zfs_data *data = 0; - grub_err_t err; - objset_phys_t *osp = 0; - grub_size_t ospsize; - grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN; - uberblock_t *ub; - int inserted; - - if (! dev->disk) - { - grub_error (GRUB_ERR_BAD_DEVICE, "not a disk"); - return 0; - } - - data = grub_zalloc (sizeof (*data)); - if (!data) - return 0; -#if 0 - /* if it's our first time here, zero the best uberblock out */ - if (data->best_drive == 0 && data->best_part == 0 && find_best_root) - grub_memset (¤t_uberblock, 0, sizeof (uberblock_t)); -#endif - - data->n_devices_allocated = 16; - data->devices_attached = grub_calloc (data->n_devices_allocated, - sizeof (data->devices_attached[0])); - if (!data->devices_attached) - { - grub_free (data); - return NULL; - } - data->n_devices_attached = 0; - err = scan_disk (dev, data, 1, &inserted); - if (err) - { - zfs_unmount (data); - return NULL; - } - - ub = &(data->current_uberblock); - ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, - GRUB_ZFS_LITTLE_ENDIAN) == UBERBLOCK_MAGIC - ? GRUB_ZFS_LITTLE_ENDIAN : GRUB_ZFS_BIG_ENDIAN); - - err = zio_read (&ub->ub_rootbp, ub_endian, - (void **) &osp, &ospsize, data); - if (err) - { - zfs_unmount (data); - return NULL; - } - - if (ospsize < OBJSET_PHYS_SIZE_V14) - { - grub_error (GRUB_ERR_BAD_FS, "OSP too small"); - grub_free (osp); - zfs_unmount (data); - return NULL; - } - - if (ub->ub_version >= SPA_VERSION_FEATURES && - check_mos_features(&osp->os_meta_dnode, ub_endian, data) != 0) - { - grub_error (GRUB_ERR_BAD_FS, "Unsupported features in pool"); - grub_free (osp); - zfs_unmount (data); - return NULL; - } - - /* Got the MOS. Save it at the memory addr MOS. */ - grub_memmove (&(data->mos.dn), &osp->os_meta_dnode, DNODE_SIZE); - data->mos.endian = (grub_zfs_to_cpu64 (ub->ub_rootbp.blk_prop, - ub_endian) >> 63) & 1; - grub_free (osp); - - return data; -} - -grub_err_t -grub_zfs_fetch_nvlist (grub_device_t dev, char **nvlist) -{ - struct grub_zfs_data *zfs; - grub_err_t err; - - zfs = zfs_mount (dev); - if (!zfs) - return grub_errno; - err = zfs_fetch_nvlist (zfs->device_original, nvlist); - zfs_unmount (zfs); - return err; -} - -static grub_err_t -zfs_label (grub_device_t device, char **label) -{ - char *nvlist; - grub_err_t err; - struct grub_zfs_data *data; - - data = zfs_mount (device); - if (! data) - return grub_errno; - - err = zfs_fetch_nvlist (data->device_original, &nvlist); - if (err) - { - zfs_unmount (data); - return err; - } - - *label = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME); - grub_free (nvlist); - zfs_unmount (data); - return grub_errno; -} - -static grub_err_t -zfs_uuid (grub_device_t device, char **uuid) -{ - struct grub_zfs_data *data; - - *uuid = 0; - - data = zfs_mount (device); - if (! data) - return grub_errno; - - *uuid = grub_xasprintf ("%016llx", (long long unsigned) data->guid); - zfs_unmount (data); - if (! *uuid) - return grub_errno; - return GRUB_ERR_NONE; -} - -static grub_err_t -zfs_mtime (grub_device_t device, grub_int64_t *mt) -{ - struct grub_zfs_data *data; - grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN; - uberblock_t *ub; - - *mt = 0; - - data = zfs_mount (device); - if (! data) - return grub_errno; - - ub = &(data->current_uberblock); - ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, - GRUB_ZFS_LITTLE_ENDIAN) == UBERBLOCK_MAGIC - ? GRUB_ZFS_LITTLE_ENDIAN : GRUB_ZFS_BIG_ENDIAN); - - *mt = grub_zfs_to_cpu64 (ub->ub_timestamp, ub_endian); - zfs_unmount (data); - return GRUB_ERR_NONE; -} - -/* - * zfs_open() locates a file in the rootpool by following the - * MOS and places the dnode of the file in the memory address DNODE. - */ -static grub_err_t -grub_zfs_open (struct grub_file *file, const char *fsfilename) -{ - struct grub_zfs_data *data; - grub_err_t err; - int isfs; - - data = zfs_mount (file->device); - if (! data) - return grub_errno; - - err = dnode_get_fullpath (fsfilename, &(data->subvol), - &(data->dnode), &isfs, data); - if (err) - { - zfs_unmount (data); - return err; - } - - if (isfs) - { - zfs_unmount (data); - return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("missing `%c' symbol"), '@'); - } - - /* We found the dnode for this file. Verify if it is a plain file. */ - if (data->dnode.dn.dn_type != DMU_OT_PLAIN_FILE_CONTENTS) - { - zfs_unmount (data); - return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file")); - } - - /* get the file size and set the file position to 0 */ - - /* - * For DMU_OT_SA we will need to locate the SIZE attribute - * attribute, which could be either in the bonus buffer - * or the "spill" block. - */ - if (data->dnode.dn.dn_bonustype == DMU_OT_SA) - { - void *sahdrp; - int hdrsize; - bool free_sahdrp = false; - - if (data->dnode.dn.dn_bonuslen != 0) - { - sahdrp = (sa_hdr_phys_t *) DN_BONUS (&data->dnode.dn); - } - else if (data->dnode.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR) - { - blkptr_t *bp = &data->dnode.dn.dn_spill; - - err = zio_read (bp, data->dnode.endian, &sahdrp, NULL, data); - if (err) - return err; - free_sahdrp = true; - } - else - { - return grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); - } - - hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); - file->size = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), data->dnode.endian); - if (free_sahdrp) - grub_free(sahdrp); - } - else if (data->dnode.dn.dn_bonustype == DMU_OT_ZNODE) - { - file->size = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&data->dnode.dn))->zp_size, data->dnode.endian); - } - else - return grub_error (GRUB_ERR_BAD_FS, "bad bonus type"); - - file->data = data; - file->offset = 0; - -#ifndef GRUB_UTIL - grub_dl_ref (my_mod); -#endif - - return GRUB_ERR_NONE; -} - -static grub_ssize_t -grub_zfs_read (grub_file_t file, char *buf, grub_size_t len) -{ - struct grub_zfs_data *data = (struct grub_zfs_data *) file->data; - grub_size_t blksz, movesize; - grub_size_t length; - grub_size_t read; - grub_err_t err; - - /* - * If offset is in memory, move it into the buffer provided and return. - */ - if (file->offset >= data->file_start - && file->offset + len <= data->file_end) - { - grub_memmove (buf, data->file_buf + file->offset - data->file_start, - len); - return len; - } - - blksz = grub_zfs_to_cpu16 (data->dnode.dn.dn_datablkszsec, - data->dnode.endian) << SPA_MINBLOCKSHIFT; - - if (blksz == 0) - { - grub_error (GRUB_ERR_BAD_FS, "0-sized block"); - return -1; - } - - /* - * Entire Dnode is too big to fit into the space available. We - * will need to read it in chunks. This could be optimized to - * read in as large a chunk as there is space available, but for - * now, this only reads in one data block at a time. - */ - length = len; - read = 0; - while (length) - { - void *t; - /* - * Find requested blkid and the offset within that block. - */ - grub_uint64_t blkid = grub_divmod64 (file->offset + read, blksz, 0); - grub_free (data->file_buf); - data->file_buf = 0; - - err = dmu_read (&(data->dnode), blkid, &t, - 0, data); - data->file_buf = t; - if (err) - { - data->file_buf = NULL; - data->file_start = data->file_end = 0; - return -1; - } - - data->file_start = blkid * blksz; - data->file_end = data->file_start + blksz; - - movesize = data->file_end - file->offset - read; - if (movesize > length) - movesize = length; - - grub_memmove (buf, data->file_buf + file->offset + read - - data->file_start, movesize); - buf += movesize; - length -= movesize; - read += movesize; - } - - return len; -} - -static grub_err_t -grub_zfs_close (grub_file_t file) -{ - zfs_unmount ((struct grub_zfs_data *) file->data); - -#ifndef GRUB_UTIL - grub_dl_unref (my_mod); -#endif - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_zfs_getmdnobj (grub_device_t dev, const char *fsfilename, - grub_uint64_t *mdnobj) -{ - struct grub_zfs_data *data; - grub_err_t err; - int isfs; - - data = zfs_mount (dev); - if (! data) - return grub_errno; - - err = dnode_get_fullpath (fsfilename, &(data->subvol), - &(data->dnode), &isfs, data); - *mdnobj = data->subvol.obj; - zfs_unmount (data); - return err; -} - -/* - * Note: fill_fs_info() uses functions such as make_mdn() that modify - * the input dnode_end_t parameter. However, we should not allow it. - * Therefore, we are making mdn_in constant - fill_fs_info() makes - * a local copy of it. - */ -static grub_err_t -fill_fs_info (struct grub_dirhook_info *info, - const dnode_end_t *mdn_in, struct grub_zfs_data *data) -{ - grub_err_t err; - dnode_end_t dn; - grub_uint64_t objnum; - grub_uint64_t headobj; - dnode_end_t mdn; - - grub_memcpy (&mdn, mdn_in, sizeof (*mdn_in)); - - grub_memset (info, 0, sizeof (*info)); - - info->dir = 1; - - if (mdn.dn.dn_type == DMU_OT_DSL_DIR || mdn.dn.dn_bonustype == DMU_OT_DSL_DIR) - { - headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&mdn.dn))->dd_head_dataset_obj, mdn.endian); - - err = dnode_get (&(data->mos), headobj, 0, &mdn, data); - if (err) - { - grub_dprintf ("zfs", "failed here\n"); - return err; - } - } - err = make_mdn (&mdn, data); - if (err) - return err; - err = dnode_get (&mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, - &dn, data); - if (err) - { - grub_dprintf ("zfs", "failed here\n"); - return err; - } - - err = zap_lookup (&dn, ZFS_ROOT_OBJ, &objnum, data, 0); - if (err) - { - grub_dprintf ("zfs", "failed here\n"); - return err; - } - - err = dnode_get (&mdn, objnum, 0, &dn, data); - if (err) - { - grub_dprintf ("zfs", "failed here\n"); - return err; - } - - if (dn.dn.dn_bonustype == DMU_OT_SA) - { - void *sahdrp; - int hdrsize; - bool free_sahdrp = false; - - if (dn.dn.dn_bonuslen != 0) - { - sahdrp = (sa_hdr_phys_t *) DN_BONUS (&dn.dn); - } - else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR) - { - blkptr_t *bp = &dn.dn.dn_spill; - - err = zio_read (bp, dn.endian, &sahdrp, NULL, data); - if (err) - return err; - free_sahdrp = true; - } - else - { - grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); - return grub_errno; - } - - hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); - info->mtimeset = 1; - info->mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); - if (free_sahdrp) - grub_free (sahdrp); - } - - if (dn.dn.dn_bonustype == DMU_OT_ZNODE) - { - info->mtimeset = 1; - info->mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian); - } - return 0; -} - -/* Helper for grub_zfs_dir. */ -static int -iterate_zap (const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx) -{ - grub_err_t err; - struct grub_dirhook_info info; - - dnode_end_t dn; - grub_memset (&info, 0, sizeof (info)); - - err = dnode_get (&(ctx->data->subvol.mdn), val, 0, &dn, ctx->data); - if (err) - { - grub_print_error (); - return 0; - } - - if (dn.dn.dn_bonustype == DMU_OT_SA) - { - void *sahdrp; - int hdrsize; - bool free_sahdrp = false; - - if (dn.dn.dn_bonuslen != 0) - { - sahdrp = (sa_hdr_phys_t *) DN_BONUS (&ctx->data->dnode.dn); - } - else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR) - { - blkptr_t *bp = &dn.dn.dn_spill; - - err = zio_read (bp, dn.endian, &sahdrp, NULL, ctx->data); - if (err) - { - grub_print_error (); - return 0; - } - free_sahdrp = true; - } - else - { - grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); - grub_print_error (); - return 0; - } - - hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); - info.mtimeset = 1; - info.mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); - info.case_insensitive = ctx->data->subvol.case_insensitive; - if (free_sahdrp) - grub_free (sahdrp); - } - - if (dn.dn.dn_bonustype == DMU_OT_ZNODE) - { - info.mtimeset = 1; - info.mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], - dn.endian); - } - info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS); - grub_dprintf ("zfs", "type=%d, name=%s\n", - (int)dn.dn.dn_type, (char *)name); - return ctx->hook (name, &info, ctx->hook_data); -} - -/* Helper for grub_zfs_dir. */ -static int -iterate_zap_fs (const char *name, grub_uint64_t val, - struct grub_zfs_dir_ctx *ctx) -{ - grub_err_t err; - struct grub_dirhook_info info; - - if (name[0] == 0 && val == 0) - return 0; - - dnode_end_t mdn; - err = dnode_get (&(ctx->data->mos), val, 0, &mdn, ctx->data); - if (err) - { - grub_errno = 0; - return 0; - } - if (mdn.dn.dn_type != DMU_OT_DSL_DIR && mdn.dn.dn_bonustype != DMU_OT_DSL_DIR) { - grub_dprintf ("zfs", "type = 0x%x, val = 0x%llx\n", mdn.dn.dn_type, (long long)val); - return 0; - } - - err = fill_fs_info (&info, &mdn, ctx->data); - if (err) - { - grub_errno = 0; - return 0; - } - return ctx->hook (name, &info, ctx->hook_data); -} - -/* Helper for grub_zfs_dir. */ -static int -iterate_zap_snap (const char *name, grub_uint64_t val, - struct grub_zfs_dir_ctx *ctx) -{ - grub_err_t err; - struct grub_dirhook_info info; - char *name2; - int ret; - grub_size_t sz; - - dnode_end_t mdn; - - err = dnode_get (&(ctx->data->mos), val, 0, &mdn, ctx->data); - if (err) - { - grub_errno = 0; - return 0; - } - - if (mdn.dn.dn_type != DMU_OT_DSL_DATASET && mdn.dn.dn_bonustype != DMU_OT_DSL_DATASET) - return 0; - - err = fill_fs_info (&info, &mdn, ctx->data); - if (err) - { - grub_errno = 0; - return 0; - } - - if (grub_add (grub_strlen (name), 2, &sz)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("name length overflow")); - - name2 = grub_malloc (sz); - if (!name2) - return grub_errno; - - name2[0] = '@'; - grub_memcpy (name2 + 1, name, grub_strlen (name) + 1); - ret = ctx->hook (name2, &info, ctx->hook_data); - grub_free (name2); - return ret; -} - -static grub_err_t -grub_zfs_dir (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data) -{ - struct grub_zfs_dir_ctx ctx = { - .hook = hook, - .hook_data = hook_data - }; - struct grub_zfs_data *data; - grub_err_t err; - int isfs; - - data = zfs_mount (device); - if (! data) - return grub_errno; - err = dnode_get_fullpath (path, &(data->subvol), &(data->dnode), &isfs, data); - if (err) - { - zfs_unmount (data); - return err; - } - ctx.data = data; - - if (isfs) - { - grub_uint64_t childobj, headobj; - grub_uint64_t snapobj; - dnode_end_t dn; - struct grub_dirhook_info info; - - err = fill_fs_info (&info, &data->dnode, data); - if (err) - { - zfs_unmount (data); - return err; - } - if (hook ("@", &info, hook_data)) - { - zfs_unmount (data); - return GRUB_ERR_NONE; - } - - childobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&data->dnode.dn))->dd_child_dir_zapobj, data->dnode.endian); - headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&data->dnode.dn))->dd_head_dataset_obj, data->dnode.endian); - err = dnode_get (&(data->mos), childobj, - DMU_OT_DSL_DIR_CHILD_MAP, &dn, data); - if (err) - { - zfs_unmount (data); - return err; - } - - zap_iterate_u64 (&dn, iterate_zap_fs, data, &ctx); - - err = dnode_get (&(data->mos), headobj, 0, &dn, data); - if (!err && dn.dn.dn_type != DMU_OT_DSL_DATASET && dn.dn.dn_bonustype != DMU_OT_DSL_DATASET) - return grub_error(GRUB_ERR_BAD_FS, "incorrect dataset dnode type"); - - if (err) - { - zfs_unmount (data); - return err; - } - - snapobj = grub_zfs_to_cpu64 (((dsl_dataset_phys_t *) DN_BONUS (&dn.dn))->ds_snapnames_zapobj, dn.endian); - - err = dnode_get (&(data->mos), snapobj, - DMU_OT_DSL_DS_SNAP_MAP, &dn, data); - if (err) - { - zfs_unmount (data); - return err; - } - - zap_iterate_u64 (&dn, iterate_zap_snap, data, &ctx); - } - else - { - if (data->dnode.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS) - { - zfs_unmount (data); - return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); - } - zap_iterate_u64 (&(data->dnode), iterate_zap, data, &ctx); - } - zfs_unmount (data); - return grub_errno; -} - -static int -check_feature (const char *name, grub_uint64_t val, - struct grub_zfs_dir_ctx *ctx __attribute__((unused))) -{ - int i; - if (val == 0) - return 0; - if (name[0] == 0) - return 0; - for (i = 0; spa_feature_names[i] != NULL; i++) - if (grub_strcmp (name, spa_feature_names[i]) == 0) - return 0; - return 1; -} - -/* - * Checks whether the MOS features that are active are supported by this - * (GRUB's) implementation of ZFS. - * - * Return: - * 0: Success. - * errnum: Failure. - */ - -static grub_err_t -check_mos_features(dnode_phys_t *mosmdn_phys,grub_zfs_endian_t endian,struct grub_zfs_data* data ) -{ - grub_uint64_t objnum; - grub_err_t errnum = 0; - dnode_end_t dn,mosmdn; - mzap_phys_t* mzp; - grub_zfs_endian_t endianzap; - int size, ret; - grub_memmove(&(mosmdn.dn),mosmdn_phys,sizeof(dnode_phys_t)); - mosmdn.endian=endian; - errnum = dnode_get(&mosmdn, DMU_POOL_DIRECTORY_OBJECT, - DMU_OT_OBJECT_DIRECTORY, &dn,data); - if (errnum != 0) - return errnum; - - /* - * Find the object number for 'features_for_read' and retrieve its - * corresponding dnode. Note that we don't check features_for_write - * because GRUB is not opening the pool for write. - */ - errnum = zap_lookup(&dn, DMU_POOL_FEATURES_FOR_READ, &objnum, data,0); - if (errnum != 0) - return errnum; - - errnum = dnode_get(&mosmdn, objnum, DMU_OTN_ZAP_METADATA, &dn, data); - if (errnum != 0) - return errnum; - - errnum = dmu_read(&dn, 0, (void**)&mzp, &endianzap,data); - if (errnum != 0) - return errnum; - - size = grub_zfs_to_cpu16 (dn.dn.dn_datablkszsec, dn.endian) << SPA_MINBLOCKSHIFT; - ret = mzap_iterate (mzp,endianzap, size, check_feature,NULL); - grub_free(mzp); - return ret; -} - - -#ifdef GRUB_UTIL -static grub_err_t -grub_zfs_embed (grub_device_t device __attribute__ ((unused)), - unsigned int *nsectors, - unsigned int max_nsectors, - grub_embed_type_t embed_type, - grub_disk_addr_t **sectors) -{ - unsigned i; - - if (embed_type != GRUB_EMBED_PCBIOS) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "ZFS currently supports only PC-BIOS embedding"); - - if ((VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS) < *nsectors) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("your core.img is unusually large. " - "It won't fit in the embedding area")); - - *nsectors = (VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS); - if (*nsectors > max_nsectors) - *nsectors = max_nsectors; - *sectors = grub_calloc (*nsectors, sizeof (**sectors)); - if (!*sectors) - return grub_errno; - for (i = 0; i < *nsectors; i++) - (*sectors)[i] = i + (VDEV_BOOT_OFFSET >> GRUB_DISK_SECTOR_BITS); - - return GRUB_ERR_NONE; -} -#endif - -static struct grub_fs grub_zfs_fs = { - .name = "zfs", - .fs_dir = grub_zfs_dir, - .fs_open = grub_zfs_open, - .fs_read = grub_zfs_read, - .fs_close = grub_zfs_close, - .fs_label = zfs_label, - .fs_uuid = zfs_uuid, - .fs_mtime = zfs_mtime, -#ifdef GRUB_UTIL - .fs_embed = grub_zfs_embed, - .reserved_first_sector = 1, - .blocklist_install = 0, -#endif - .next = 0 -}; - -GRUB_MOD_INIT (zfs) -{ - COMPILE_TIME_ASSERT (sizeof (zap_leaf_chunk_t) == ZAP_LEAF_CHUNKSIZE); - grub_zfs_fs.mod = mod; - grub_fs_register (&grub_zfs_fs); -#ifndef GRUB_UTIL - my_mod = mod; -#endif -} - -GRUB_MOD_FINI (zfs) -{ - grub_fs_unregister (&grub_zfs_fs); -} diff --git a/grub-core/fs/zfs/zfs_fletcher.c b/grub-core/fs/zfs/zfs_fletcher.c deleted file mode 100644 index ad3be6705..000000000 --- a/grub-core/fs/zfs/zfs_fletcher.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc. - * Copyright 2007 Sun Microsystems, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void -fletcher_2(const void *buf, grub_uint64_t size, grub_zfs_endian_t endian, - zio_cksum_t *zcp) -{ - const grub_uint64_t *ip = buf; - const grub_uint64_t *ipend = ip + (size / sizeof (grub_uint64_t)); - grub_uint64_t a0, b0, a1, b1; - - for (a0 = b0 = a1 = b1 = 0; ip < ipend; ip += 2) - { - a0 += grub_zfs_to_cpu64 (ip[0], endian); - a1 += grub_zfs_to_cpu64 (ip[1], endian); - b0 += a0; - b1 += a1; - } - - zcp->zc_word[0] = grub_cpu_to_zfs64 (a0, endian); - zcp->zc_word[1] = grub_cpu_to_zfs64 (a1, endian); - zcp->zc_word[2] = grub_cpu_to_zfs64 (b0, endian); - zcp->zc_word[3] = grub_cpu_to_zfs64 (b1, endian); -} - -void -fletcher_4 (const void *buf, grub_uint64_t size, grub_zfs_endian_t endian, - zio_cksum_t *zcp) -{ - const grub_uint32_t *ip = buf; - const grub_uint32_t *ipend = ip + (size / sizeof (grub_uint32_t)); - grub_uint64_t a, b, c, d; - - for (a = b = c = d = 0; ip < ipend; ip++) - { - a += grub_zfs_to_cpu32 (ip[0], endian);; - b += a; - c += b; - d += c; - } - - zcp->zc_word[0] = grub_cpu_to_zfs64 (a, endian); - zcp->zc_word[1] = grub_cpu_to_zfs64 (b, endian); - zcp->zc_word[2] = grub_cpu_to_zfs64 (c, endian); - zcp->zc_word[3] = grub_cpu_to_zfs64 (d, endian); -} - diff --git a/grub-core/fs/zfs/zfs_lz4.c b/grub-core/fs/zfs/zfs_lz4.c deleted file mode 100644 index 5453822d0..000000000 --- a/grub-core/fs/zfs/zfs_lz4.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * LZ4 - Fast LZ compression algorithm - * Header File - * Copyright (C) 2011-2013, Yann Collet. - * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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 COPYRIGHT HOLDERS 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 COPYRIGHT - * OWNER 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. - * - * You can contact the author at : - * - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html - * - LZ4 source repository : http://code.google.com/p/lz4/ - */ - -#include -#include -#include -#include - -static int LZ4_uncompress_unknownOutputSize(const char *source, char *dest, - int isize, int maxOutputSize); - -/* - * CPU Feature Detection - */ - -/* 32 or 64 bits ? */ -#if (GRUB_CPU_SIZEOF_VOID_P == 8) -#define LZ4_ARCH64 1 -#else -#define LZ4_ARCH64 0 -#endif - -/* - * Compiler Options - */ - - -#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) - -#if (GCC_VERSION >= 302) || (defined (__INTEL_COMPILER) && __INTEL_COMPILER >= 800) || defined(__clang__) -#define expect(expr, value) (__builtin_expect((expr), (value))) -#else -#define expect(expr, value) (expr) -#endif - -#define likely(expr) expect((expr) != 0, 1) -#define unlikely(expr) expect((expr) != 0, 0) - -/* Basic types */ -#define BYTE grub_uint8_t -#define U16 grub_uint16_t -#define U32 grub_uint32_t -#define S32 grub_int32_t -#define U64 grub_uint64_t - -typedef struct _U16_S { - U16 v; -} GRUB_PACKED U16_S; -typedef struct _U32_S { - U32 v; -} GRUB_PACKED U32_S; -typedef struct _U64_S { - U64 v; -} GRUB_PACKED U64_S; - -#define A64(x) (((U64_S *)(x))->v) -#define A32(x) (((U32_S *)(x))->v) -#define A16(x) (((U16_S *)(x))->v) - -/* - * Constants - */ -#define MINMATCH 4 - -#define COPYLENGTH 8 -#define LASTLITERALS 5 - -#define ML_BITS 4 -#define ML_MASK ((1U< s_len) - return grub_error(GRUB_ERR_BAD_FS,"lz4 decompression failed."); - - /* - * Returns 0 on success (decompression function returned non-negative) - * and appropriate error on failure (decompression function returned negative). - */ - return (LZ4_uncompress_unknownOutputSize((char*)s_start + 4, d_start, bufsiz, - d_len) < 0)?grub_error(GRUB_ERR_BAD_FS,"lz4 decompression failed."):0; -} - -static int -LZ4_uncompress_unknownOutputSize(const char *source, - char *dest, int isize, int maxOutputSize) -{ - /* Local Variables */ - const BYTE * ip = (const BYTE *) source; - const BYTE *const iend = ip + isize; - const BYTE * ref; - - BYTE * op = (BYTE *) dest; - BYTE *const oend = op + maxOutputSize; - BYTE *cpy; - - grub_size_t dec[] = { 0, 3, 2, 3, 0, 0, 0, 0 }; - - /* Main Loop */ - while (ip < iend) { - BYTE token; - int length; - - /* get runlength */ - token = *ip++; - if ((length = (token >> ML_BITS)) == RUN_MASK) { - int s = 255; - while ((ip < iend) && (s == 255)) { - s = *ip++; - length += s; - } - } - /* copy literals */ - if ((grub_addr_t) length > ~(grub_addr_t)op) - goto _output_error; - cpy = op + length; - if ((cpy > oend - COPYLENGTH) || - (ip + length > iend - COPYLENGTH)) { - if (cpy > oend) - /* - * Error: request to write beyond destination - * buffer. - */ - goto _output_error; - if (ip + length > iend) - /* - * Error : request to read beyond source - * buffer. - */ - goto _output_error; - grub_memcpy(op, ip, length); - op += length; - ip += length; - if (ip < iend) - /* Error : LZ4 format violation */ - goto _output_error; - /* Necessarily EOF, due to parsing restrictions. */ - break; - } - LZ4_WILDCOPY(ip, op, cpy); - ip -= (op - cpy); - op = cpy; - - /* get offset */ - LZ4_READ_LITTLEENDIAN_16(ref, cpy, ip); - ip += 2; - if (ref < (BYTE * const) dest) - /* - * Error: offset creates reference outside of - * destination buffer. - */ - goto _output_error; - - /* get matchlength */ - if ((length = (token & ML_MASK)) == ML_MASK) { - while (ip < iend) { - int s = *ip++; - length += s; - if (s == 255) - continue; - break; - } - } - /* copy repeated sequence */ - if unlikely(op - ref < STEPSIZE) { -#if LZ4_ARCH64 - grub_size_t dec2table[] = { 0, 0, 0, -1, 0, 1, 2, 3 }; - grub_size_t dec2 = dec2table[op - ref]; -#else - const int dec2 = 0; -#endif - *op++ = *ref++; - *op++ = *ref++; - *op++ = *ref++; - *op++ = *ref++; - ref -= dec[op - ref]; - A32(op) = A32(ref); - op += STEPSIZE - 4; - ref -= dec2; - } else { - LZ4_COPYSTEP(ref, op); - } - cpy = op + length - (STEPSIZE - 4); - if (cpy > oend - COPYLENGTH) { - if (cpy > oend) - /* - * Error: request to write outside of - * destination buffer. - */ - goto _output_error; - LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH)); - while (op < cpy) - *op++ = *ref++; - op = cpy; - if (op == oend) - /* - * Check EOF (should never happen, since last - * 5 bytes are supposed to be literals). - */ - break; - continue; - } - LZ4_SECURECOPY(ref, op, cpy); - op = cpy; /* correction */ - } - - /* end of decoding */ - return (int)(((char *)op) - dest); - - /* write overflow error detected */ - _output_error: - return (int)(-(((char *)ip) - source)); -} diff --git a/grub-core/fs/zfs/zfs_lzjb.c b/grub-core/fs/zfs/zfs_lzjb.c deleted file mode 100644 index 62b5ea6a0..000000000 --- a/grub-core/fs/zfs/zfs_lzjb.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc. - * Copyright 2007 Sun Microsystems, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MATCH_BITS 6 -#define MATCH_MIN 3 -#define OFFSET_MASK ((1 << (16 - MATCH_BITS)) - 1) - -/* - * Decompression Entry - lzjb - */ -#ifndef NBBY -#define NBBY 8 -#endif - -grub_err_t -lzjb_decompress (void *s_start, void *d_start, grub_size_t s_len, - grub_size_t d_len); - -grub_err_t -lzjb_decompress (void *s_start, void *d_start, grub_size_t s_len, - grub_size_t d_len) -{ - grub_uint8_t *src = s_start; - grub_uint8_t *dst = d_start; - grub_uint8_t *d_end = (grub_uint8_t *) d_start + d_len; - grub_uint8_t *s_end = (grub_uint8_t *) s_start + s_len; - grub_uint8_t *cpy, copymap = 0; - int copymask = 1 << (NBBY - 1); - - while (dst < d_end && src < s_end) - { - if ((copymask <<= 1) == (1 << NBBY)) - { - copymask = 1; - copymap = *src++; - } - if (src >= s_end) - return grub_error (GRUB_ERR_BAD_FS, "lzjb decompression failed"); - if (copymap & copymask) - { - int mlen = (src[0] >> (NBBY - MATCH_BITS)) + MATCH_MIN; - int offset = ((src[0] << NBBY) | src[1]) & OFFSET_MASK; - src += 2; - cpy = dst - offset; - if (src > s_end || cpy < (grub_uint8_t *) d_start) - return grub_error (GRUB_ERR_BAD_FS, "lzjb decompression failed"); - while (--mlen >= 0 && dst < d_end) - *dst++ = *cpy++; - } - else - *dst++ = *src++; - } - if (dst < d_end) - return grub_error (GRUB_ERR_BAD_FS, "lzjb decompression failed"); - return GRUB_ERR_NONE; -} diff --git a/grub-core/fs/zfs/zfs_sha256.c b/grub-core/fs/zfs/zfs_sha256.c deleted file mode 100644 index f042fa61a..000000000 --- a/grub-core/fs/zfs/zfs_sha256.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc. - * Copyright 2007 Sun Microsystems, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * SHA-256 checksum, as specified in FIPS 180-2, available at: - * http://csrc.nist.gov/cryptval - * - * This is a very compact implementation of SHA-256. - * It is designed to be simple and portable, not to be fast. - */ - -/* - * The literal definitions according to FIPS180-2 would be: - * - * Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) - * Maj(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) - * - * We use logical equivalents which require one less op. - */ -#define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -#define Maj(x, y, z) (((x) & (y)) ^ ((z) & ((x) ^ (y)))) -#define Rot32(x, s) (((x) >> s) | ((x) << (32 - s))) -#define SIGMA0(x) (Rot32(x, 2) ^ Rot32(x, 13) ^ Rot32(x, 22)) -#define SIGMA1(x) (Rot32(x, 6) ^ Rot32(x, 11) ^ Rot32(x, 25)) -#define sigma0(x) (Rot32(x, 7) ^ Rot32(x, 18) ^ ((x) >> 3)) -#define sigma1(x) (Rot32(x, 17) ^ Rot32(x, 19) ^ ((x) >> 10)) - -static const grub_uint32_t SHA256_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 -}; - -static void -SHA256Transform(grub_uint32_t *H, const grub_uint8_t *cp) -{ - grub_uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64]; - - for (t = 0; t < 16; t++, cp += 4) - W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3]; - - for (t = 16; t < 64; t++) - W[t] = sigma1(W[t - 2]) + W[t - 7] + - sigma0(W[t - 15]) + W[t - 16]; - - a = H[0]; b = H[1]; c = H[2]; d = H[3]; - e = H[4]; f = H[5]; g = H[6]; h = H[7]; - - for (t = 0; t < 64; t++) { - T1 = h + SIGMA1(e) + Ch(e, f, g) + SHA256_K[t] + W[t]; - T2 = SIGMA0(a) + Maj(a, b, c); - h = g; g = f; f = e; e = d + T1; - d = c; c = b; b = a; a = T1 + T2; - } - - H[0] += a; H[1] += b; H[2] += c; H[3] += d; - H[4] += e; H[5] += f; H[6] += g; H[7] += h; -} - -void -zio_checksum_SHA256(const void *buf, grub_uint64_t size, - grub_zfs_endian_t endian, zio_cksum_t *zcp) -{ - grub_uint32_t H[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; - grub_uint8_t pad[128]; - unsigned padsize = size & 63; - unsigned i; - - for (i = 0; i < size - padsize; i += 64) - SHA256Transform(H, (grub_uint8_t *)buf + i); - - for (i = 0; i < padsize; i++) - pad[i] = ((grub_uint8_t *)buf)[i]; - - for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++) - pad[padsize] = 0; - - for (i = 0; i < 8; i++) - pad[padsize++] = (size << 3) >> (56 - 8 * i); - - for (i = 0; i < padsize && i <= 64; i += 64) - SHA256Transform(H, pad + i); - - zcp->zc_word[0] = grub_cpu_to_zfs64 ((grub_uint64_t)H[0] << 32 | H[1], - endian); - zcp->zc_word[1] = grub_cpu_to_zfs64 ((grub_uint64_t)H[2] << 32 | H[3], - endian); - zcp->zc_word[2] = grub_cpu_to_zfs64 ((grub_uint64_t)H[4] << 32 | H[5], - endian); - zcp->zc_word[3] = grub_cpu_to_zfs64 ((grub_uint64_t)H[6] << 32 | H[7], - endian); -} diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c deleted file mode 100644 index da30e9ab3..000000000 --- a/grub-core/fs/zfs/zfscrypt.c +++ /dev/null @@ -1,491 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* - Mostly based on following article: - https://blogs.oracle.com/darren/entry/zfs_encryption_what_is_on - */ - -enum grub_zfs_algo - { - GRUB_ZFS_ALGO_CCM, - GRUB_ZFS_ALGO_GCM, - }; - -struct grub_zfs_key -{ - grub_uint64_t algo; - grub_uint8_t enc_nonce[13]; - grub_uint8_t unused[3]; - grub_uint8_t enc_key[48]; - grub_uint8_t unknown_purpose_nonce[13]; - grub_uint8_t unused2[3]; - grub_uint8_t unknown_purpose_key[48]; -}; - -struct grub_zfs_wrap_key -{ - struct grub_zfs_wrap_key *next; - grub_size_t keylen; - int is_passphrase; - grub_uint64_t key[0]; -}; - -static struct grub_zfs_wrap_key *zfs_wrap_keys; - -grub_err_t -grub_zfs_add_key (grub_uint8_t *key_in, - grub_size_t keylen, - int passphrase) -{ - struct grub_zfs_wrap_key *key; - grub_size_t sz; - - if (!passphrase && keylen > 32) - keylen = 32; - if (grub_add (sizeof (*key), keylen, &sz)) - return GRUB_ERR_OUT_OF_RANGE; - key = grub_malloc (sz); - if (!key) - return grub_errno; - key->is_passphrase = passphrase; - key->keylen = keylen; - grub_memcpy (key->key, key_in, keylen); - key->next = zfs_wrap_keys; - zfs_wrap_keys = key; - return GRUB_ERR_NONE; -} - -static gcry_err_code_t -grub_ccm_decrypt (grub_crypto_cipher_handle_t cipher, - grub_uint8_t *out, const grub_uint8_t *in, - grub_size_t psize, - void *mac_out, const void *nonce, - unsigned l, unsigned m) -{ - grub_uint8_t iv[16]; - grub_uint8_t mul[16]; - grub_uint32_t mac[4]; - unsigned i, j; - gcry_err_code_t err; - - grub_memcpy (iv + 1, nonce, 15 - l); - - iv[0] = (l - 1) | (((m-2) / 2) << 3); - for (j = 0; j < l; j++) - iv[15 - j] = psize >> (8 * j); - err = grub_crypto_ecb_encrypt (cipher, mac, iv, 16); - if (err) - return err; - - iv[0] = l - 1; - - for (i = 0; i < (psize + 15) / 16; i++) - { - grub_size_t csize; - csize = 16; - if (csize > psize - 16 * i) - csize = psize - 16 * i; - for (j = 0; j < l; j++) - iv[15 - j] = (i + 1) >> (8 * j); - err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); - if (err) - return err; - grub_crypto_xor (out + 16 * i, in + 16 * i, mul, csize); - grub_crypto_xor (mac, mac, out + 16 * i, csize); - err = grub_crypto_ecb_encrypt (cipher, mac, mac, 16); - if (err) - return err; - } - for (j = 0; j < l; j++) - iv[15 - j] = 0; - err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); - if (err) - return err; - if (mac_out) - grub_crypto_xor (mac_out, mac, mul, m); - return GPG_ERR_NO_ERROR; -} - -static void -grub_gcm_mul_x (grub_uint8_t *a) -{ - int i; - int c = 0, d = 0; - for (i = 0; i < 16; i++) - { - c = a[i] & 0x1; - a[i] = (a[i] >> 1) | (d << 7); - d = c; - } - if (d) - a[0] ^= 0xe1; -} - -static void -grub_gcm_mul (grub_uint8_t *a, const grub_uint8_t *b) -{ - grub_uint8_t res[16], bs[16]; - int i; - grub_memcpy (bs, b, 16); - grub_memset (res, 0, 16); - for (i = 0; i < 128; i++) - { - if ((a[i / 8] << (i % 8)) & 0x80) - grub_crypto_xor (res, res, bs, 16); - grub_gcm_mul_x (bs); - } - - grub_memcpy (a, res, 16); -} - -static gcry_err_code_t -grub_gcm_decrypt (grub_crypto_cipher_handle_t cipher, - grub_uint8_t *out, const grub_uint8_t *in, - grub_size_t psize, - void *mac_out, const void *nonce, - unsigned nonce_len, unsigned m) -{ - grub_uint8_t iv[16]; - grub_uint8_t mul[16]; - grub_uint8_t mac[16], h[16], mac_xor[16]; - unsigned i, j; - gcry_err_code_t err; - - grub_memset (mac, 0, sizeof (mac)); - - err = grub_crypto_ecb_encrypt (cipher, h, mac, 16); - if (err) - return err; - - if (nonce_len == 12) - { - grub_memcpy (iv, nonce, 12); - iv[12] = 0; - iv[13] = 0; - iv[14] = 0; - iv[15] = 1; - } - else - { - grub_memset (iv, 0, sizeof (iv)); - grub_memcpy (iv, nonce, nonce_len); - grub_gcm_mul (iv, h); - iv[15] ^= nonce_len * 8; - grub_gcm_mul (iv, h); - } - - err = grub_crypto_ecb_encrypt (cipher, mac_xor, iv, 16); - if (err) - return err; - - for (i = 0; i < (psize + 15) / 16; i++) - { - grub_size_t csize; - csize = 16; - if (csize > psize - 16 * i) - csize = psize - 16 * i; - for (j = 0; j < 4; j++) - { - iv[15 - j]++; - if (iv[15 - j] != 0) - break; - } - grub_crypto_xor (mac, mac, in + 16 * i, csize); - grub_gcm_mul (mac, h); - err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16); - if (err) - return err; - grub_crypto_xor (out + 16 * i, in + 16 * i, mul, csize); - } - for (j = 0; j < 8; j++) - mac[15 - j] ^= ((((grub_uint64_t) psize) * 8) >> (8 * j)); - grub_gcm_mul (mac, h); - - if (mac_out) - grub_crypto_xor (mac_out, mac, mac_xor, m); - - return GPG_ERR_NO_ERROR; -} - - -static gcry_err_code_t -algo_decrypt (grub_crypto_cipher_handle_t cipher, grub_uint64_t algo, - grub_uint8_t *out, const grub_uint8_t *in, - grub_size_t psize, - void *mac_out, const void *nonce, - unsigned l, unsigned m) -{ - switch (algo) - { - case 0: - return grub_ccm_decrypt (cipher, out, in, psize, - mac_out, nonce, l, m); - case 1: - return grub_gcm_decrypt (cipher, out, in, psize, - mac_out, nonce, - 15 - l, m); - default: - return GPG_ERR_CIPHER_ALGO; - } -} - -static grub_err_t -grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, - grub_uint64_t algo, - void *nonce, - char *buf, grub_size_t size, - const grub_uint32_t *expected_mac, - grub_zfs_endian_t endian) -{ - grub_uint32_t mac[4]; - unsigned i; - grub_uint32_t sw[4]; - gcry_err_code_t err; - - grub_memcpy (sw, nonce, 16); - if (endian != GRUB_ZFS_BIG_ENDIAN) - for (i = 0; i < 4; i++) - sw[i] = grub_swap_bytes32 (sw[i]); - - if (!cipher) - return grub_error (GRUB_ERR_ACCESS_DENIED, - N_("no decryption key available")); - err = algo_decrypt (cipher, algo, - (grub_uint8_t *) buf, - (grub_uint8_t *) buf, - size, mac, - sw + 1, 3, 12); - if (err) - return grub_crypto_gcry_error (err); - - for (i = 0; i < 3; i++) - if (grub_zfs_to_cpu32 (expected_mac[i], endian) - != grub_be_to_cpu32 (mac[i])) - return grub_error (GRUB_ERR_BAD_FS, N_("MAC verification failed")); - return GRUB_ERR_NONE; -} - -static grub_crypto_cipher_handle_t -grub_zfs_load_key_real (const struct grub_zfs_key *key, - grub_size_t keysize, - grub_uint64_t salt, - grub_uint64_t algo) -{ - unsigned keylen; - struct grub_zfs_wrap_key *wrap_key; - grub_crypto_cipher_handle_t ret = NULL; - - if (keysize != sizeof (*key)) - { - grub_dprintf ("zfs", "Unexpected key size %" PRIuGRUB_SIZE "\n", keysize); - return 0; - } - - if (grub_memcmp (key->enc_key + 32, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) - == 0) - keylen = 16; - else if (grub_memcmp (key->enc_key + 40, "\0\0\0\0\0\0\0\0", 8) == 0) - keylen = 24; - else - keylen = 32; - - for (wrap_key = zfs_wrap_keys; wrap_key; wrap_key = wrap_key->next) - { - grub_crypto_cipher_handle_t cipher; - grub_uint8_t decrypted[32], mac[32], wrap_key_real[32]; - gcry_err_code_t err; - cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES); - if (!cipher) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - grub_memset (wrap_key_real, 0, sizeof (wrap_key_real)); - err = 0; - if (!wrap_key->is_passphrase) - grub_memcpy(wrap_key_real, wrap_key->key, - wrap_key->keylen < keylen ? wrap_key->keylen : keylen); - else - err = grub_crypto_pbkdf2 (GRUB_MD_SHA1, - (const grub_uint8_t *) wrap_key->key, - wrap_key->keylen, - (const grub_uint8_t *) &salt, sizeof (salt), - 1000, wrap_key_real, keylen); - if (err) - { - grub_errno = GRUB_ERR_NONE; - grub_crypto_cipher_close (cipher); - continue; - } - - err = grub_crypto_cipher_set_key (cipher, wrap_key_real, - keylen); - if (err) - { - grub_errno = GRUB_ERR_NONE; - grub_crypto_cipher_close (cipher); - continue; - } - - err = algo_decrypt (cipher, algo, decrypted, key->unknown_purpose_key, 32, - mac, key->unknown_purpose_nonce, 2, 16); - if (err || (grub_crypto_memcmp (mac, key->unknown_purpose_key + 32, 16) - != 0)) - { - grub_dprintf ("zfs", "key loading failed\n"); - grub_errno = GRUB_ERR_NONE; - grub_crypto_cipher_close (cipher); - continue; - } - - err = algo_decrypt (cipher, algo, decrypted, key->enc_key, keylen, mac, - key->enc_nonce, 2, 16); - if (err || grub_crypto_memcmp (mac, key->enc_key + keylen, 16) != 0) - { - grub_dprintf ("zfs", "key loading failed\n"); - grub_errno = GRUB_ERR_NONE; - grub_crypto_cipher_close (cipher); - continue; - } - ret = grub_crypto_cipher_open (GRUB_CIPHER_AES); - if (!ret) - { - grub_errno = GRUB_ERR_NONE; - grub_crypto_cipher_close (cipher); - continue; - } - err = grub_crypto_cipher_set_key (ret, decrypted, keylen); - if (err) - { - grub_errno = GRUB_ERR_NONE; - grub_crypto_cipher_close (ret); - grub_crypto_cipher_close (cipher); - continue; - } - grub_crypto_cipher_close (cipher); - return ret; - } - return NULL; -} - -static const struct grub_arg_option options[] = - { - {"raw", 'r', 0, N_("Assume input is raw."), 0, 0}, - {"hex", 'h', 0, N_("Assume input is hex."), 0, 0}, - {"passphrase", 'p', 0, N_("Assume input is passphrase."), 0, 0}, - {0, 0, 0, 0, 0, 0} - }; - -static grub_err_t -grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) -{ - grub_uint8_t buf[1024]; - grub_ssize_t real_size; - - if (argc > 0) - { - grub_file_t file; - file = grub_file_open (args[0], GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY); - if (!file) - return grub_errno; - real_size = grub_file_read (file, buf, 1024); - if (real_size < 0) - return grub_errno; - } - else - { - grub_xputs (_("Enter ZFS password: ")); - if (!grub_password_get ((char *) buf, 1023)) - return grub_errno; - real_size = grub_strlen ((char *) buf); - } - - if (ctxt->state[1].set) - { - int i; - grub_err_t err; - for (i = 0; i < real_size / 2; i++) - { - char c1 = grub_tolower (buf[2 * i]) - '0'; - char c2 = grub_tolower (buf[2 * i + 1]) - '0'; - if (c1 > 9) - c1 += '0' - 'a' + 10; - if (c2 > 9) - c2 += '0' - 'a' + 10; - buf[i] = (c1 << 4) | c2; - } - err = grub_zfs_add_key (buf, real_size / 2, 0); - if (err) - return err; - return GRUB_ERR_NONE; - } - - return grub_zfs_add_key (buf, real_size, - ctxt->state[2].set - || (argc == 0 && !ctxt->state[0].set - && !ctxt->state[1].set)); -} - -static grub_extcmd_t cmd_key; - -GRUB_MOD_INIT(zfscrypt) -{ - grub_zfs_decrypt = grub_zfs_decrypt_real; - grub_zfs_load_key = grub_zfs_load_key_real; - cmd_key = grub_register_extcmd ("zfskey", grub_cmd_zfs_key, 0, - N_("[-h|-p|-r] [FILE]"), - N_("Import ZFS wrapping key stored in FILE."), - options); -} - -GRUB_MOD_FINI(zfscrypt) -{ - grub_zfs_decrypt = 0; - grub_zfs_load_key = 0; - grub_unregister_extcmd (cmd_key); -} diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c deleted file mode 100644 index 31d767bbd..000000000 --- a/grub-core/fs/zfs/zfsinfo.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc. - * Copyright 2008 Sun Microsystems, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static inline void -print_tabs (int n) -{ - int i; - - for (i = 0; i < n; i++) - grub_printf (" "); -} - -static grub_err_t -print_state (char *nvlist, int tab) -{ - grub_uint64_t ival; - int isok = 1; - - print_tabs (tab); - - if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_REMOVED, &ival)) - { - grub_puts_ (N_("Virtual device is removed")); - isok = 0; - } - - if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_FAULTED, &ival)) - { - grub_puts_ (N_("Virtual device is faulted")); - isok = 0; - } - - if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_OFFLINE, &ival)) - { - grub_puts_ (N_("Virtual device is offline")); - isok = 0; - } - - if (grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_FAULTED, &ival)) - /* TRANSLATORS: degraded doesn't mean broken but that some of - component are missing but virtual device as whole is still usable. */ - grub_puts_ (N_("Virtual device is degraded")); - - if (isok) - grub_puts_ (N_("Virtual device is online")); - grub_xputs ("\n"); - - return GRUB_ERR_NONE; -} - -static grub_err_t -print_vdev_info (char *nvlist, int tab) -{ - char *type = 0; - - type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE); - - if (!type) - { - print_tabs (tab); - grub_puts_ (N_("Incorrect virtual device: no type available")); - return grub_errno; - } - - if (grub_strcmp (type, VDEV_TYPE_DISK) == 0) - { - char *bootpath = 0; - char *path = 0; - char *devid = 0; - - print_tabs (tab); - /* TRANSLATORS: The virtual devices form a tree (in graph-theoretical - sense). The nodes like mirror or raidz have children: member devices. - The "real" devices which actually store data are called "leafs" - (again borrowed from graph theory) and can be either disks - (or partitions) or files. */ - grub_puts_ (N_("Leaf virtual device (file or disk)")); - - print_state (nvlist, tab); - - bootpath = - grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_PHYS_PATH); - print_tabs (tab); - if (!bootpath) - grub_puts_ (N_("Bootpath: unavailable\n")); - else - grub_printf_ (N_("Bootpath: %s\n"), bootpath); - - path = grub_zfs_nvlist_lookup_string (nvlist, "path"); - print_tabs (tab); - if (!path) - grub_puts_ (N_("Path: unavailable")); - else - grub_printf_ (N_("Path: %s\n"), path); - - devid = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_DEVID); - print_tabs (tab); - if (!devid) - grub_puts_ (N_("Devid: unavailable")); - else - grub_printf_ (N_("Devid: %s\n"), devid); - grub_free (bootpath); - grub_free (devid); - grub_free (path); - grub_free (type); - return GRUB_ERR_NONE; - } - char is_mirror=(grub_strcmp(type,VDEV_TYPE_MIRROR) == 0); - char is_raidz=(grub_strcmp(type,VDEV_TYPE_RAIDZ) == 0); - grub_free (type); - - if (is_mirror || is_raidz) - { - int nelm, i; - - nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm - (nvlist, ZPOOL_CONFIG_CHILDREN); - - if(is_mirror){ - grub_puts_ (N_("This VDEV is a mirror")); - } - else if(is_raidz){ - grub_uint64_t parity; - grub_zfs_nvlist_lookup_uint64(nvlist,"nparity",&parity); - grub_printf_ (N_("This VDEV is a RAIDZ%llu\n"),(unsigned long long)parity); - } - print_tabs (tab); - if (nelm <= 0) - { - grub_puts_ (N_("Incorrect VDEV")); - return GRUB_ERR_NONE; - } - grub_printf_ (N_("VDEV with %d children\n"), nelm); - print_state (nvlist, tab); - for (i = 0; i < nelm; i++) - { - char *child; - - child = grub_zfs_nvlist_lookup_nvlist_array - (nvlist, ZPOOL_CONFIG_CHILDREN, i); - - print_tabs (tab); - if (!child) - { - /* TRANSLATORS: it's the element carying the number %d, not - total element number. And the number itself is fine, - only the element isn't. - */ - grub_printf_ (N_("VDEV element number %d isn't correct\n"), i); - continue; - } - - /* TRANSLATORS: it's the element carying the number %d, not - total element number. This is used in enumeration - "Element number 1", "Element number 2", ... */ - grub_printf_ (N_("VDEV element number %d:\n"), i); - print_vdev_info (child, tab + 1); - - grub_free (child); - } - return GRUB_ERR_NONE; - } - - print_tabs (tab); - grub_printf_ (N_("Unknown virtual device type: %s\n"), type); - - return GRUB_ERR_NONE; -} - -static grub_err_t -get_bootpath (char *nvlist, char **bootpath, char **devid) -{ - char *type = 0; - - type = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_TYPE); - - if (!type) - return grub_errno; - - if (grub_strcmp (type, VDEV_TYPE_DISK) == 0) - { - *bootpath = grub_zfs_nvlist_lookup_string (nvlist, - ZPOOL_CONFIG_PHYS_PATH); - *devid = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_DEVID); - if (!*bootpath || !*devid) - { - grub_free (*bootpath); - grub_free (*devid); - *bootpath = 0; - *devid = 0; - } - return GRUB_ERR_NONE; - } - - if (grub_strcmp (type, VDEV_TYPE_MIRROR) == 0) - { - int nelm, i; - - nelm = grub_zfs_nvlist_lookup_nvlist_array_get_nelm - (nvlist, ZPOOL_CONFIG_CHILDREN); - - for (i = 0; i < nelm; i++) - { - char *child; - - child = grub_zfs_nvlist_lookup_nvlist_array (nvlist, - ZPOOL_CONFIG_CHILDREN, - i); - - get_bootpath (child, bootpath, devid); - - grub_free (child); - - if (*bootpath && *devid) - return GRUB_ERR_NONE; - } - } - - return GRUB_ERR_NONE; -} - -static const char *poolstates[] = { - /* TRANSLATORS: Here we speak about ZFS pools it's semi-marketing, - semi-technical term by Sun/Oracle and should be translated in sync with - other ZFS-related software and documentation. */ - [POOL_STATE_ACTIVE] = N_("Pool state: active"), - [POOL_STATE_EXPORTED] = N_("Pool state: exported"), - [POOL_STATE_DESTROYED] = N_("Pool state: destroyed"), - [POOL_STATE_SPARE] = N_("Pool state: reserved for hot spare"), - [POOL_STATE_L2CACHE] = N_("Pool state: level 2 ARC device"), - [POOL_STATE_UNINITIALIZED] = N_("Pool state: uninitialized"), - [POOL_STATE_UNAVAIL] = N_("Pool state: unavailable"), - [POOL_STATE_POTENTIALLY_ACTIVE] = N_("Pool state: potentially active") -}; - -static grub_err_t -grub_cmd_zfsinfo (grub_command_t cmd __attribute__ ((unused)), int argc, - char **args) -{ - grub_device_t dev; - char *devname; - grub_err_t err; - char *nvlist = 0; - char *nv = 0; - char *poolname; - grub_uint64_t guid; - grub_uint64_t pool_state; - int found; - - if (argc < 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - - if (args[0][0] == '(' && args[0][grub_strlen (args[0]) - 1] == ')') - { - devname = grub_strdup (args[0] + 1); - if (devname) - devname[grub_strlen (devname) - 1] = 0; - } - else - devname = grub_strdup (args[0]); - if (!devname) - return grub_errno; - - dev = grub_device_open (devname); - grub_free (devname); - if (!dev) - return grub_errno; - - err = grub_zfs_fetch_nvlist (dev, &nvlist); - - grub_device_close (dev); - - if (err) - return err; - - poolname = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME); - if (!poolname) - grub_puts_ (N_("Pool name: unavailable")); - else - grub_printf_ (N_("Pool name: %s\n"), poolname); - - found = - grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_GUID, &guid); - if (!found) - grub_puts_ (N_("Pool GUID: unavailable")); - else - grub_printf_ (N_("Pool GUID: %016llx\n"), (long long unsigned) guid); - - found = grub_zfs_nvlist_lookup_uint64 (nvlist, ZPOOL_CONFIG_POOL_STATE, - &pool_state); - if (!found) - grub_puts_ (N_("Unable to retrieve pool state")); - else if (pool_state >= ARRAY_SIZE (poolstates)) - grub_puts_ (N_("Unrecognized pool state")); - else - grub_puts_ (poolstates[pool_state]); - - nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE); - - if (!nv) - /* TRANSLATORS: There are undetermined number of virtual devices - in a device tree, not just one. - */ - grub_puts_ (N_("No virtual device tree available")); - else - print_vdev_info (nv, 1); - - grub_free (nv); - grub_free (nvlist); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc, - char **args) -{ - grub_device_t dev; - char *devname; - grub_err_t err; - char *nvlist = 0; - char *nv = 0; - char *bootpath = 0, *devid = 0; - char *fsname; - char *bootfs; - char *poolname; - grub_uint64_t mdnobj; - - if (argc < 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - - devname = grub_file_get_device_name (args[0]); - if (grub_errno) - return grub_errno; - - dev = grub_device_open (devname); - grub_free (devname); - if (!dev) - return grub_errno; - - err = grub_zfs_fetch_nvlist (dev, &nvlist); - - fsname = grub_strchr (args[0], ')'); - if (fsname) - fsname++; - else - fsname = args[0]; - - if (!err) - err = grub_zfs_getmdnobj (dev, fsname, &mdnobj); - - grub_device_close (dev); - - if (err) { - grub_free (nvlist); - return err; - } - - poolname = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME); - if (!poolname) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_FS, "No poolname found"); - grub_free (nvlist); - return grub_errno; - } - - nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE); - - if (nv) - get_bootpath (nv, &bootpath, &devid); - - grub_free (nv); - grub_free (nvlist); - - bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu%s%s%s%s%s%s", - poolname, (unsigned long long) mdnobj, - bootpath ? ",bootpath=\"" : "", - bootpath ? : "", - bootpath ? "\"" : "", - devid ? ",diskdevid=\"" : "", - devid ? : "", - devid ? "\"" : ""); - if (!bootfs) - return grub_errno; - if (argc >= 2) - grub_env_set (args[1], bootfs); - else - grub_printf ("%s\n", bootfs); - - grub_free (bootfs); - grub_free (poolname); - grub_free (bootpath); - grub_free (devid); - - return GRUB_ERR_NONE; -} - - -static grub_command_t cmd_info, cmd_bootfs; - -GRUB_MOD_INIT (zfsinfo) -{ - cmd_info = grub_register_command ("zfsinfo", grub_cmd_zfsinfo, - N_("DEVICE"), - N_("Print ZFS info about DEVICE.")); - cmd_bootfs = grub_register_command ("zfs-bootfs", grub_cmd_zfs_bootfs, - N_("FILESYSTEM [VARIABLE]"), - N_("Print ZFS-BOOTFSOBJ or store it into VARIABLE")); -} - -GRUB_MOD_FINI (zfsinfo) -{ - grub_unregister_command (cmd_info); - grub_unregister_command (cmd_bootfs); -} diff --git a/grub-core/gdb/cstub.c b/grub-core/gdb/cstub.c deleted file mode 100644 index b64acd70f..000000000 --- a/grub-core/gdb/cstub.c +++ /dev/null @@ -1,366 +0,0 @@ -/* cstub.c - machine independent portion of remote GDB stub */ -/* - * Copyright (C) 2006 Lubomir Kundrak - * - * 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 -#include -#include -#include -#include - -static const char hexchars[] = "0123456789abcdef"; -int grub_gdb_regs[GRUB_MACHINE_NR_REGS]; - -#define GRUB_GDB_COMBUF_SIZE 400 /* At least sizeof(grub_gdb_regs)*2 are needed for - register packets. */ -static char grub_gdb_inbuf[GRUB_GDB_COMBUF_SIZE + 1]; -static char grub_gdb_outbuf[GRUB_GDB_COMBUF_SIZE + 1]; - -struct grub_serial_port *grub_gdb_port; - -static int -hex (char ch) -{ - if ((ch >= 'a') && (ch <= 'f')) - return (ch - 'a' + 10); - if ((ch >= '0') && (ch <= '9')) - return (ch - '0'); - if ((ch >= 'A') && (ch <= 'F')) - return (ch - 'A' + 10); - return (-1); -} - -/* Scan for the sequence $#. */ -static char * -grub_gdb_getpacket (void) -{ - char *buffer = &grub_gdb_inbuf[0]; - unsigned char checksum; - unsigned char xmitcsum; - int count; - int ch; - - while (1) - { - /* Wait around for the start character, ignore all other - characters. */ - while ((ch = grub_serial_port_fetch (grub_gdb_port)) != '$'); - - retry: - checksum = 0; - xmitcsum = -1; - count = 0; - - /* Now read until a # or end of buffer is found. */ - while (count < GRUB_GDB_COMBUF_SIZE) - { - do - ch = grub_serial_port_fetch (grub_gdb_port); - while (ch < 0); - if (ch == '$') - goto retry; - if (ch == '#') - break; - checksum += ch; - buffer[count] = ch; - count = count + 1; - } - buffer[count] = 0; - if (ch == '#') - { - do - ch = grub_serial_port_fetch (grub_gdb_port); - while (ch < 0); - xmitcsum = hex (ch) << 4; - do - ch = grub_serial_port_fetch (grub_gdb_port); - while (ch < 0); - xmitcsum += hex (ch); - - if (checksum != xmitcsum) - grub_serial_port_put (grub_gdb_port, '-'); /* Failed checksum. */ - else - { - grub_serial_port_put (grub_gdb_port, '+'); /* Successful transfer. */ - - /* If a sequence char is present, reply the sequence ID. */ - if (buffer[2] == ':') - { - grub_serial_port_put (grub_gdb_port, buffer[0]); - grub_serial_port_put (grub_gdb_port, buffer[1]); - - return &buffer[3]; - } - return &buffer[0]; - } - } - } -} - -/* Send the packet in buffer. */ -static void -grub_gdb_putpacket (char *buffer) -{ - grub_uint8_t checksum; - - /* $#. */ - do - { - char *ptr; - grub_serial_port_put (grub_gdb_port, '$'); - checksum = 0; - - for (ptr = buffer; *ptr; ptr++) - { - grub_serial_port_put (grub_gdb_port, *ptr); - checksum += *ptr; - } - - grub_serial_port_put (grub_gdb_port, '#'); - grub_serial_port_put (grub_gdb_port, hexchars[checksum >> 4]); - grub_serial_port_put (grub_gdb_port, hexchars[checksum & 0xf]); - } - while (grub_serial_port_fetch (grub_gdb_port) != '+'); -} - -/* Convert the memory pointed to by mem into hex, placing result in buf. - Return a pointer to the last char put in buf (NULL). */ -static char * -grub_gdb_mem2hex (char *mem, char *buf, grub_size_t count) -{ - grub_size_t i; - unsigned char ch; - - for (i = 0; i < count; i++) - { - ch = *mem++; - *buf++ = hexchars[ch >> 4]; - *buf++ = hexchars[ch % 16]; - } - *buf = 0; - return (buf); -} - -/* Convert the hex array pointed to by buf into binary to be placed in mem. - Return a pointer to the character after the last byte written. */ -static char * -grub_gdb_hex2mem (char *buf, char *mem, int count) -{ - int i; - unsigned char ch; - - for (i = 0; i < count; i++) - { - ch = hex (*buf++) << 4; - ch = ch + hex (*buf++); - *mem++ = ch; - } - return (mem); -} - -/* Convert hex characters to int and return the number of characters - processed. */ -static int -grub_gdb_hex2int (char **ptr, grub_uint64_t *int_value) -{ - int num_chars = 0; - int hex_value; - - *int_value = 0; - - while (**ptr) - { - hex_value = hex (**ptr); - if (hex_value >= 0) - { - *int_value = (*int_value << 4) | hex_value; - num_chars++; - } - else - break; - - (*ptr)++; - } - - return (num_chars); -} - -/* This function does all command procesing for interfacing to gdb. */ -void __attribute__ ((regparm(3))) -grub_gdb_trap (int trap_no) -{ - unsigned int sig_no; - int stepping; - grub_uint64_t addr; - grub_uint64_t length; - char *ptr; - - if (!grub_gdb_port) - { - grub_printf ("Unhandled exception 0x%x at ", trap_no); - grub_backtrace_print_address ((void *) grub_gdb_regs[PC]); - grub_printf ("\n"); - grub_backtrace_pointer ((void *) grub_gdb_regs[EBP]); - grub_fatal ("Unhandled exception"); - } - - sig_no = grub_gdb_trap2sig (trap_no); - - ptr = grub_gdb_outbuf; - - /* Reply to host that an exception has occurred. */ - - *ptr++ = 'T'; /* Notify gdb with signo, PC, FP and SP. */ - - *ptr++ = hexchars[sig_no >> 4]; - *ptr++ = hexchars[sig_no & 0xf]; - - /* Stack pointer. */ - *ptr++ = hexchars[SP]; - *ptr++ = ':'; - ptr = grub_gdb_mem2hex ((char *) &grub_gdb_regs[ESP], ptr, 4); - *ptr++ = ';'; - - /* Frame pointer. */ - *ptr++ = hexchars[FP]; - *ptr++ = ':'; - ptr = grub_gdb_mem2hex ((char *) &grub_gdb_regs[EBP], ptr, 4); - *ptr++ = ';'; - - /* Program counter. */ - *ptr++ = hexchars[PC]; - *ptr++ = ':'; - ptr = grub_gdb_mem2hex ((char *) &grub_gdb_regs[PC], ptr, 4); - *ptr++ = ';'; - - *ptr = '\0'; - - grub_gdb_putpacket (grub_gdb_outbuf); - - stepping = 0; - - while (1) - { - grub_gdb_outbuf[0] = 0; - ptr = grub_gdb_getpacket (); - - switch (*ptr++) - { - case '?': - grub_gdb_outbuf[0] = 'S'; - grub_gdb_outbuf[1] = hexchars[sig_no >> 4]; - grub_gdb_outbuf[2] = hexchars[sig_no & 0xf]; - grub_gdb_outbuf[3] = 0; - break; - - /* Return values of the CPU registers. */ - case 'g': - grub_gdb_mem2hex ((char *) grub_gdb_regs, grub_gdb_outbuf, - sizeof (grub_gdb_regs)); - break; - - /* Set values of the CPU registers -- return OK. */ - case 'G': - grub_gdb_hex2mem (ptr, (char *) grub_gdb_regs, - sizeof (grub_gdb_regs)); - grub_strcpy (grub_gdb_outbuf, "OK"); - break; - - /* Set the value of a single CPU register -- return OK. */ - case 'P': - { - grub_uint64_t regno; - - if (grub_gdb_hex2int (&ptr, ®no) && *ptr++ == '=') - if (regno < GRUB_MACHINE_NR_REGS) - { - grub_gdb_hex2mem (ptr, (char *) &grub_gdb_regs[regno], 4); - grub_strcpy (grub_gdb_outbuf, "OK"); - break; - } - /* FIXME: GDB requires setting orig_eax. I don't know what's - this register is about. For now just simulate setting any - registers. */ - grub_strcpy (grub_gdb_outbuf, /*"E01"*/ "OK"); - break; - } - - /* mAA..AA,LLLL: Read LLLL bytes at address AA..AA. */ - case 'm': - /* Try to read %x,%x. Set ptr = 0 if successful. */ - if (grub_gdb_hex2int (&ptr, &addr)) - if (*(ptr++) == ',') - if (grub_gdb_hex2int (&ptr, &length)) - { - ptr = 0; - grub_gdb_mem2hex ((char *) (grub_addr_t) addr, - grub_gdb_outbuf, length); - } - if (ptr) - grub_strcpy (grub_gdb_outbuf, "E01"); - break; - - /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA -- return OK. */ - case 'M': - /* Try to read %x,%x. Set ptr = 0 if successful. */ - if (grub_gdb_hex2int (&ptr, &addr)) - if (*(ptr++) == ',') - if (grub_gdb_hex2int (&ptr, &length)) - if (*(ptr++) == ':') - { - grub_gdb_hex2mem (ptr, (char *) (grub_addr_t) addr, length); - grub_strcpy (grub_gdb_outbuf, "OK"); - ptr = 0; - } - if (ptr) - { - grub_strcpy (grub_gdb_outbuf, "E02"); - } - break; - - /* sAA..AA: Step one instruction from AA..AA(optional). */ - case 's': - stepping = 1; - /* FALLTHROUGH */ - - /* cAA..AA: Continue at address AA..AA(optional). */ - case 'c': - /* try to read optional parameter, pc unchanged if no parm */ - if (grub_gdb_hex2int (&ptr, &addr)) - grub_gdb_regs[PC] = addr; - - /* Clear the trace bit. */ - grub_gdb_regs[PS] &= 0xfffffeff; - - /* Set the trace bit if we're stepping. */ - if (stepping) - grub_gdb_regs[PS] |= 0x100; - - return; - - /* Kill the program. */ - case 'k': - /* Do nothing. */ - return; - } - - /* Reply to the request. */ - grub_gdb_putpacket (grub_gdb_outbuf); - } -} - diff --git a/grub-core/gdb/gdb.c b/grub-core/gdb/gdb.c deleted file mode 100644 index 9e091ee1b..000000000 --- a/grub-core/gdb/gdb.c +++ /dev/null @@ -1,105 +0,0 @@ -/* gdb.c - gdb remote stub module */ -/* - * Copyright (C) 2003 Free Software Foundation, Inc. - * Copyright (C) 2006 Lubomir Kundrak - * - * 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, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -grub_cmd_gdbstub (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - struct grub_serial_port *port; - if (argc < 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "port required"); - port = grub_serial_find (args[0]); - if (!port) - return grub_errno; - grub_gdb_port = port; - /* TRANSLATORS: at this position GRUB waits for the user to do an action - in remote debugger, namely to tell it to establish connection. */ - grub_puts_ (N_("Now connect the remote debugger, please.")); - grub_gdb_breakpoint (); - return 0; -} - -static grub_err_t -grub_cmd_gdbstop (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - grub_gdb_port = NULL; - return 0; -} - -static grub_err_t -grub_cmd_gdb_break (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - if (!grub_gdb_port) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "No GDB stub is running"); - grub_gdb_breakpoint (); - return 0; -} - -static grub_command_t cmd, cmd_stop, cmd_break; - -GRUB_MOD_INIT (gdb) -{ - grub_gdb_idtinit (); - cmd = grub_register_command_lockdown ("gdbstub", grub_cmd_gdbstub, - N_("PORT"), - /* - * TRANSLATORS: GDB stub is a small part of - * GDB functionality running on local host - * which allows remote debugger to - * connect to it. - */ - N_("Start GDB stub on given port")); - cmd_break = grub_register_command_lockdown ("gdbstub_break", grub_cmd_gdb_break, - /* - * TRANSLATORS: this refers to triggering - * a breakpoint so that the user will land - * into GDB. - */ - 0, N_("Break into GDB")); - cmd_stop = grub_register_command_lockdown ("gdbstub_stop", grub_cmd_gdbstop, - 0, N_("Stop GDB stub")); -} - -GRUB_MOD_FINI (gdb) -{ - grub_unregister_command (cmd); - grub_unregister_command (cmd_break); - grub_unregister_command (cmd_stop); - grub_gdb_idtrestore (); -} - diff --git a/grub-core/gdb/i386/idt.c b/grub-core/gdb/i386/idt.c deleted file mode 100644 index 43bde51a0..000000000 --- a/grub-core/gdb/i386/idt.c +++ /dev/null @@ -1,78 +0,0 @@ -/* idt.c - routines for constructing IDT for the GDB stub */ -/* - * Copyright (C) 2006 Lubomir Kundrak - * - * 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 -#include -#include -#include - -static struct grub_cpu_interrupt_gate grub_gdb_idt[GRUB_GDB_LAST_TRAP + 1] - __attribute__ ((aligned(16))); - -/* Sets up a gate descriptor in the IDT table. */ -static void -grub_idt_gate (struct grub_cpu_interrupt_gate *gate, void (*offset) (void), - grub_uint16_t selector, grub_uint8_t type, grub_uint8_t dpl) -{ - gate->offset_lo = (int) offset & 0xffff; - gate->selector = selector & 0xffff; - gate->unused = 0; - gate->gate = (type & 0x1f) | ((dpl & 0x3) << 5) | 0x80; - gate->offset_hi = ((int) offset >> 16) & 0xffff; -} - -static struct grub_cpu_idt_descriptor grub_gdb_orig_idt_desc - __attribute__ ((aligned(16))); -static struct grub_cpu_idt_descriptor grub_gdb_idt_desc - __attribute__ ((aligned(16))); - -/* Set up interrupt and trap handler descriptors in IDT. */ -void -grub_gdb_idtinit (void) -{ - int i; - grub_uint16_t seg; - - asm volatile ("xorl %%eax, %%eax\n" - "mov %%cs, %%ax\n" :"=a" (seg)); - - for (i = 0; i <= GRUB_GDB_LAST_TRAP; i++) - { - grub_idt_gate (&grub_gdb_idt[i], - grub_gdb_trapvec[i], seg, - GRUB_CPU_TRAP_GATE, 0); - } - - grub_gdb_idt_desc.base = (grub_addr_t) grub_gdb_idt; - grub_gdb_idt_desc.limit = sizeof (grub_gdb_idt) - 1; - asm volatile ("sidt %0" : : "m" (grub_gdb_orig_idt_desc)); - asm volatile ("lidt %0" : : "m" (grub_gdb_idt_desc)); -} - -void -grub_gdb_idtrestore (void) -{ - asm volatile ("lidt %0" : : "m" (grub_gdb_orig_idt_desc)); -} - -void -grub_gdb_breakpoint (void) -{ - asm volatile ("int $3"); -} diff --git a/grub-core/gdb/i386/machdep.S b/grub-core/gdb/i386/machdep.S deleted file mode 100644 index f96d2b9c4..000000000 --- a/grub-core/gdb/i386/machdep.S +++ /dev/null @@ -1,245 +0,0 @@ -/* machdep.S - machine dependent assembly routines for the GDB stub */ -/* - * Copyright (C) 2006 Lubomir Kundrak - * - * 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 -#include - -#define EC_PRESENT 1 -#define EC_ABSENT 0 - -#define GRUB_GDB_STACKSIZE 40000 - -#define SEP , - -#ifdef __APPLE__ - .zerofill __DATA, __bss, LOCAL(grub_gdb_stack_end), GRUB_GDB_STACKSIZE, 4 - LOCAL(grub_gdb_stack) = LOCAL(grub_gdb_stack_end) -#else -/* - * The .data index for the address vector. - */ - -#define VECTOR 1 - - .bss - .space GRUB_GDB_STACKSIZE -VARIABLE(grub_gdb_stack) -#endif - -/* - * Supplemental macros for register saving/restoration - * on exception handler entry/leave. - */ - -#ifdef __APPLE__ -.macro save32 -#define REG $0 -#define NDX $1 -#else -.macro save32 reg ndx -#define REG \reg -#define NDX \ndx -#endif - movl REG, EXT_C(grub_gdb_regs)+(NDX * 4) -.endm - -#undef REG -#undef NDX - -#ifdef __APPLE__ -.macro save16 -#define REG $0 -#define NDX $1 -#else -.macro save16 reg ndx -#define REG \reg -#define NDX \ndx -#endif - xorl %eax, %eax - movw REG, EXT_C(grub_gdb_regs)+(NDX * 4) - movw %ax, EXT_C(grub_gdb_regs)+(NDX * 4 + 2) - movl EXT_C(grub_gdb_regs)+(EAX * 4), %eax -.endm - -#undef REG -#undef NDX - -#ifdef __APPLE__ -.macro load32 -#define NDX $0 -#define REG $1 -#else -.macro load32 ndx reg -#define REG \reg -#define NDX \ndx -#endif - movl EXT_C(grub_gdb_regs)+(NDX * 4), REG -.endm - -#undef REG -#undef NDX - -#ifdef __APPLE__ -.macro load16 -#define NDX $0 -#define REG $1 -#else -.macro load16 ndx reg -#define NDX \ndx -#define REG \reg -#endif - movw EXT_C(grub_gdb_regs)+(NDX * 4), REG -.endm - -#undef REG -#undef NDX - -.macro save_context - save32 %eax, EAX - - save32 %ecx, ECX - save32 %edx, EDX - save32 %ebx, EBX - save32 %ebp, EBP - save32 %esi, ESI - save32 %edi, EDI - - popl %ebx - save32 %ebx, EIP - popl %ebx - save32 %ebx, CS - popl %ebx - save32 %ebx, EFLAGS - - save32 %esp, ESP - - save16 %ds, DS - save16 %es, ES - save16 %fs, FS - save16 %gs, GS - save16 %ss, SS -.endm - -.macro load_context - load16 SS, %ss - load32 ESP, %esp - - load32 EBP, %ebp - load32 ESI, %esi - load32 EDI, %edi - - load16 DS, %ds - load16 ES, %es - load16 FS, %fs - load16 GS, %gs - - load32 EFLAGS, %eax - pushl %eax - load32 CS, %eax - pushl %eax - load32 EIP, %eax - pushl %eax - - load32 EBX, %ebx - load32 EDX, %edx - load32 ECX, %ecx - load32 EAX, %eax -.endm - -/* - * This macro creates handlers for a given range of exception numbers - * and adds their addresses to the grub_gdb_trapvec array. - */ - -#ifdef __APPLE__ -.macro ent -#define EC $0 -#define BEG $1 -#define END $2 -#else -.macro ent ec beg end=0 -#define EC \ec -#define BEG \beg -#define END \end -#endif - - /* - * Wrapper body itself. - */ - - .text -1: - .if EC - add MACRO_DOLLAR(4), %esp - .endif - - save_context -#ifdef __APPLE__ - mov $LOCAL(grub_gdb_stack), %esp -#else - mov $EXT_C(grub_gdb_stack), %esp -#endif - mov $(BEG), %eax /* trap number */ - call EXT_C(grub_gdb_trap) - load_context - iret - - /* - * Address entry in trapvec array. - */ - -#ifdef __APPLE__ - .section __DATA, VECTOR -#else - .data VECTOR -#endif - .long 1b - - /* - * Next... (recursion). - */ - - .if END-BEG > 0 -#ifdef __APPLE__ - ent EC, (BEG+1), END -#else - ent \ec "(\beg+1)" \end -#endif - .endif -.endm - -/* - * Here does the actual construction of the address array and handlers - * take place. - */ -#ifdef __APPLE__ - .section __DATA, VECTOR -#else - .data VECTOR -#endif -VARIABLE(grub_gdb_trapvec) - ent EC_ABSENT, 0, 7 - ent EC_PRESENT, 8 - ent EC_ABSENT, 9 - ent EC_PRESENT, 10, 14 - /* - * You may have to split this further or as(1) - * will complain about nesting being too deep. - */ - ent EC_ABSENT, 15, GRUB_GDB_LAST_TRAP diff --git a/grub-core/gdb/i386/signal.c b/grub-core/gdb/i386/signal.c deleted file mode 100644 index b169c6b23..000000000 --- a/grub-core/gdb/i386/signal.c +++ /dev/null @@ -1,53 +0,0 @@ -/* idt.c - routines for constructing IDT for the GDB stub */ -/* - * Copyright (C) 2006 Lubomir Kundrak - * - * 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 -#include -#include -#include - -/* Converting CPU trap number to UNIX signal number as - described in System V ABI i386 Processor Supplement, 3-25. */ -unsigned int -grub_gdb_trap2sig (int trap_no) -{ - const int signals[] = { - SIGFPE, /* 0: Divide error fault */ - SIGTRAP, /* 1: Single step trap fault */ - SIGABRT, /* 2: # Nonmaskable interrupt */ - SIGTRAP, /* 3: Breakpoint trap */ - SIGSEGV, /* 4: Overflow trap */ - SIGSEGV, /* 5: Bounds check fault */ - SIGILL, /* 6: Invalid opcode fault */ - SIGFPE, /* 7: No coprocessor fault */ - SIGABRT, /* 8: # Double fault abort */ - SIGSEGV, /* 9: Coprocessor overrun abort */ - SIGSEGV, /* 10: Invalid TSS fault */ - SIGSEGV, /* 11: Segment not present fault */ - SIGSEGV, /* 12: Stack exception fault */ - SIGSEGV, /* 13: General protection fault abort */ - SIGSEGV, /* 14: Page fault */ - SIGABRT, /* 15: (reserved) */ - SIGFPE, /* 16: Coprocessor error fault */ - SIGUSR1 /* other */ - }; - - return signals[trap_no < 17 ? trap_no : 17]; -} - diff --git a/grub-core/gdb_grub.in b/grub-core/gdb_grub.in deleted file mode 100644 index f188a842a..000000000 --- a/grub-core/gdb_grub.in +++ /dev/null @@ -1,136 +0,0 @@ -### -### Load debuging information about GNU GRUB 2 modules into GDB -### automatically. Needs readelf, objdump, Python and gdb_helper.py script -### -### Has to be launched from the writable and trusted -### directory containing *.image and *.module -### -### $Id: .gdbinit,v 1.1 2006/05/14 11:38:08 lkundrak Exp $ -### Lubomir Kundrak -### - -source gdb_helper.py - - -define dynamic_load_symbols - dynamic_load_kernel_exec_symbols $arg0 - - run_on_start - - # We may have been very late to loading the kernel.exec symbols and - # and modules may already be loaded. So load symbols for any already - # loaded. - load_all_modules - - if $is_grub_loaded() - runtime_load_module - end -end -document dynamic_load_symbols - Load debugging symbols from kernel.exec and any loaded modules given - the address of the .text segment of the UEFI binary in memory. Also - setup session to automatically load module symbols for modules loaded - in the future. -end - -define load_all_modules - set $this = grub_dl_head - while ($this != 0) - load_module $this - set $this = $this->next - end -end -document load_all_modules - Load debugging information for all loaded modules. -end - -define runtime_load_module - break grub_dl_add - commands - silent - load_module mod - cont - end -end -document runtime_load_module - Load module symbols at runtime as they are loaded. -end - -define run_on_start - # TODO: Add check to see if _start symbol is defined, if not, then - # the symbols have not yet been loaded and this command will not work. - watch *_start - set $break_efi_start_bpnum = $bpnum - commands - silent - delete $break_efi_start_bpnum - - # Save the breakpoints here before the GRUB image is loaded - # into memory, then delete them. Later they will be reloaded - # once the GRUB image has been loaded. This avoids the issue - # where the loading of the GRUB image overwrites the software - # breakpoints, thus confusing GDB and effectively clearing - # those breakpoints. - save breakpoints .early-breakpoints.gdb - delete breakpoints - - tbreak _start - commands - silent - - # Reload the breakpoints now that the GRUB image has - # finished being loaded into memory. - source .early-breakpoints.gdb - - runtime_load_module - - if $is_user_command("onstart") - onstart - end - continue - end - continue - end -end -document run_on_start - On some targets, such as x86_64-efi, even if you know where the - firmware will load the GRUB image, you can not simply set a break - point before the image is loaded because loading the image - overwrites the break point in memory. So setup a hardware watch - point, which does not have that problem, and if that gets triggered, - then reset the break point. If a user-defined command named - "onstart" exists it will be run after the start is hit. - NOTE: This assumes symbols have already been correctly loaded for - the EFI application. -end - -### - -set confirm off - -# Note: On EFI and other platforms that load GRUB to an address that is -# determined at runtime, the symbols in kernel.exec will be wrong. -# However, we must start by loading some executable file or GDB will -# fail. - -set $platform_efi = $_streq("@platform@", "efi") -set $target = "@target_cpu@-@platform@" - -if ! $runonce - if $platform_efi - # Only load the executable file, not the symbols - exec-file kernel.exec - else - if $_streq($target, "i386-pc") - add-symbol-file boot.image - add-symbol-file diskboot.image - add-symbol-file lzma_decompress.image - end - file kernel.exec - run_on_start - runtime_load_module - end - - target remote :1234 - set $runonce = 1 -end diff --git a/grub-core/gdb_helper.py.in b/grub-core/gdb_helper.py.in deleted file mode 100644 index a2cab416a..000000000 --- a/grub-core/gdb_helper.py.in +++ /dev/null @@ -1,173 +0,0 @@ -import os -import re -import subprocess - -def prompt_hook (current_prompt): - return "(grub gdb) " -gdb.prompt_hook = prompt_hook - -##### Convenience functions ##### - -class IsGrubLoaded (gdb.Function): - """Return 1 if GRUB has been loaded in memory, otherwise 0. -The heuristic used is checking if the first 4 bytes of the memory pointed -to by the _start symbol are not 0. This is true for QEMU on the first run -of GRUB. This may not be true on physical hardware, where memory is not -necessarily cleared on soft reset. This may not also be true in QEMU on -soft resets. Also this many not be true when chainloading GRUB. -""" - - def __init__ (self): - super (IsGrubLoaded, self).__init__ ("is_grub_loaded") - - def invoke (self): - return int (gdb.parse_and_eval ("*(int *) _start")) != 0 - -is_grub_loaded = IsGrubLoaded () - -class IsUserCommand (gdb.Function): - """Set the second argument to true value if first argument is the name -of a user-defined command. -""" - - def __init__ (self): - super (IsUserCommand, self).__init__ ("is_user_command") - - def invoke (self, fmt, *args): - name = fmt.string () % tuple(a.string () for a in args) - for line in gdb.execute ("help user-defined", to_string=True).splitlines (): - line_parts = line.split(' -- ', 1) - if len (line_parts) > 1 and line_parts[0] == name: - return True - return False - -is_user_command = IsUserCommand () - -##### Commands ##### - -# Loading symbols is complicated by the fact that kernel.exec is an ELF -# ELF binary, but the UEFI runtime is PE32+. All the data sections of -# the ELF binary are concatenated (accounting for ELF section alignment) -# and put into one .data section of the PE32+ runtime image. So given -# the load address of the .data PE32+ section we can determine the -# addresses each ELF data section maps to. The UEFI application is -# loaded into memory just as it is laid out in the file. It is not -# assumed that the binary is available, but it is known that the .text -# section directly precedes the .data section and that .data is EFI -# page aligned. Using this, the .data offset can be found from the .text -# address. -class GrubLoadKernelExecSymbols (gdb.Command): - """Load debugging symbols from kernel.exec given the address of the -.text segment of the UEFI binary in memory.""" - - PE_SECTION_ALIGN = 12 - - def __init__ (self): - super (GrubLoadKernelExecSymbols, self).__init__ ("dynamic_load_kernel_exec_symbols", - gdb.COMMAND_USER, - gdb.COMPLETE_EXPRESSION) - - def invoke (self, arg, from_tty): - self.dont_repeat () - args = gdb.string_to_argv (arg) - - if len (args) != 1: - raise RuntimeError ("dynamic_load_kernel_exec_symbols expects exactly one argument") - - sections = self.parse_objdump_sections ("kernel.exec") - pe_text = args[0] - text_size = [s['size'] for s in sections if s['name'] == '.text'][0] - pe_data_offset = self.alignup (text_size, self.PE_SECTION_ALIGN) - - sym_load_cmd_parts = ["add-symbol-file", "kernel.exec", pe_text] - offset = 0 - for section in sections: - if 'DATA' in section["flags"] or section["name"] == ".bss": - offset = self.alignup (offset, section["align"]) - sym_load_cmd_parts.extend (["-s", section["name"], "(%s+0x%x+0x%x)" % (pe_text, pe_data_offset, offset)]) - offset += section["size"] - gdb.execute (' '.join (sym_load_cmd_parts)) - - @staticmethod - def parse_objdump_sections (filename): - fields = ("idx", "name", "size", "vma", "lma", "fileoff", "align") - re_section = re.compile ("^\s*" + "\s+".join(["(?P<%s>\S+)" % f for f in fields])) - c = subprocess.run (["objdump", "-h", filename], text=True, capture_output=True) - section_lines = c.stdout.splitlines ()[5:] - sections = [] - - for i in range (len (section_lines) >> 1): - m = re_section.match (section_lines[i * 2]) - s = dict (m.groupdict ()) - for f in ("size", "vma", "lma", "fileoff"): - s[f] = int (s[f], 16) - s["idx"] = int (s["idx"]) - s["align"] = int (s["align"].split ("**", 1)[1]) - s["flags"] = section_lines[(i * 2) + 1].strip ().split (", ") - sections.append (s) - return sections - - @staticmethod - def alignup (addr, align): - pad = (addr % (1 << align)) and 1 or 0 - return ((addr >> align) + pad) << align - -dynamic_load_kernel_exec_symbols = GrubLoadKernelExecSymbols () - - -class GrubLoadModuleSymbols (gdb.Command): - """Load module symbols at correct locations. -Takes one argument which is a pointer to a grub_dl_t struct.""" - - def __init__ (self): - super (GrubLoadModuleSymbols, self).__init__ ("load_module", - gdb.COMMAND_USER, - gdb.COMPLETE_EXPRESSION) - - def invoke (self, arg, from_tty): - self.dont_repeat () - args = gdb.string_to_argv (arg) - self.mod = gdb.parse_and_eval (args[0]) - sections = self.get_section_offsets () - section_names = self.get_section_names () - - sym_load_cmd_parts = ["add-symbol-file", - "%s.module" % (self.mod['name'].string (),)] - for idx, addr in sections: - section_name = section_names[idx] - if section_name == ".text": - sym_load_cmd_parts.append (addr) - else: - sym_load_cmd_parts.extend (["-s", section_name, addr]) - gdb.execute (' '.join (sym_load_cmd_parts)) - - if is_user_command.invoke (gdb.Value ("onload_%s"), self.mod['name']): - gdb.execute ("onload_%s (grub_dl_t)%s" % (self.mod['name'].string (), - self.mod.format_string (format='x'))) - - def get_section_offsets (self): - sections = [] - segment = self.mod['segment'] - while segment: - sections.append ((int (segment['section']), segment['addr'].format_string (format='x'))) - segment = segment['next'] - return sections - - def get_section_names (self): - re_index = re.compile ("^\s+\[\s*(\d+)\] (\S*)") - names = {} - modfilename = "%s.mod" % (self.mod['name'].string (),) - - if not os.path.exists (modfilename): - raise RuntimeError ("%s not found in current directory" % (modfilename,)) - - c = subprocess.run (["readelf", "-SW", modfilename], text=True, capture_output=True) - for line in c.stdout.splitlines ()[4:]: - m = re_index.match (line) - if not m: - continue - idx, name = m.groups () - names[int (idx)] = name - return names - -grub_load_module = GrubLoadModuleSymbols () diff --git a/grub-core/genmod.sh.in b/grub-core/genmod.sh.in deleted file mode 100644 index 337753c57..000000000 --- a/grub-core/genmod.sh.in +++ /dev/null @@ -1,106 +0,0 @@ -#! @BUILD_SHEBANG@ -set -e - -# Copyright (C) 2010 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. - -# -# Example: -# -# genmod.sh moddep.lst normal.module build-grub-module-verifier normal.mod -# - -moddep=$1 -infile=$2 -outfile=$4 - -tmpfile=${outfile}.tmp -modname=`echo $infile | sed -e 's@\.module.*$@@'` - -if ! grep ^$modname: $moddep >/dev/null; then - echo "warning: moddep.lst has no dependencies for $modname" >&2 - exit 0 -fi - -deps=`grep ^$modname: $moddep | sed s@^.*:@@` - -# remove old files if any -rm -f $tmpfile $outfile - -if test x@TARGET_APPLE_LINKER@ != x1; then - # stripout .modname and .moddeps sections from input module - @TARGET_OBJCOPY@ -R .modname -R .moddeps $infile $tmpfile - - # Attach .modname and .moddeps sections - t1=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 - printf "$modname\0" >$t1 - - t2=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 - for dep in $deps; do printf "$dep\0" >> $t2; done - - if test -n "$deps"; then - @TARGET_OBJCOPY@ --add-section .modname=$t1 --add-section .moddeps=$t2 $tmpfile - else - @TARGET_OBJCOPY@ --add-section .modname=$t1 $tmpfile - fi - rm -f $t1 $t2 - - if test x@platform@ != xemu; then - @TARGET_STRIP@ --strip-unneeded \ - -K grub_mod_init -K grub_mod_fini \ - -K _grub_mod_init -K _grub_mod_fini \ - -R .note.GNU-stack \ - -R .note.gnu.gold-version \ - -R .note.gnu.property \ - -R .gnu.build.attributes \ - -R '.llvm*' \ - -R .rel.gnu.build.attributes \ - -R .rela.gnu.build.attributes \ - -R .eh_frame -R .rela.eh_frame -R .rel.eh_frame \ - -R .note -R .comment -R .ARM.exidx $tmpfile || exit 1 - fi - if ! test -z "${TARGET_OBJ2ELF}"; then - "${TARGET_OBJ2ELF}" $tmpfile || exit 1 - fi -else - tmpfile2=${outfile}.tmp2 - t1=${outfile}.t1.c - t2=${outfile}.t2.c - - # remove old files if any - rm -f $t1 $t2 - - cp $infile $tmpfile - - # Attach .modname and .moddeps sections - echo "char modname[] __attribute__ ((section(\"_modname, _modname\"))) = \"$modname\";" >$t1 - - for dep in $deps; do echo "char moddep_$dep[] __attribute__ ((section(\"_moddeps, _moddeps\"))) = \"$dep\";" >>$t2; done - - if test -n "$deps"; then - @TARGET_CC@ @TARGET_LDFLAGS@ -ffreestanding -nostdlib -o $tmpfile2 $t1 $t2 $tmpfile -Wl,-r - else - @TARGET_CC@ @TARGET_LDFLAGS@ -ffreestanding -nostdlib -o $tmpfile2 $t1 $tmpfile -Wl,-r - fi - rm -f $t1 $t2 $tmpfile - mv $tmpfile2 $tmpfile - - cp $tmpfile $tmpfile.bin - @TARGET_OBJCONV@ -f@TARGET_MODULE_FORMAT@ \ - -nr:_grub_mod_init:grub_mod_init \ - -nr:_grub_mod_fini:grub_mod_fini \ - -wd1106 -nu -nd $tmpfile.bin $tmpfile || exit 1 - rm -f $tmpfile.bin -fi -if test x@platform@ != xemu; then - ./build-grub-module-verifier@BUILD_EXEEXT@ $tmpfile @target_cpu@ @platform@ -fi -mv $tmpfile $outfile diff --git a/grub-core/genmoddep.awk b/grub-core/genmoddep.awk deleted file mode 100644 index ab457cb2b..000000000 --- a/grub-core/genmoddep.awk +++ /dev/null @@ -1,108 +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 symbols' info from stdin. -BEGIN { - error = 0 -} - -{ - if ($1 == "defined") { - if ($3 !~ /^\.refptr\./ && $3 in symtab) { - printf "%s in %s is duplicated in %s\n", $3, $2, symtab[$3] >"/dev/stderr"; - error++; - } - symtab[$3] = $2; - modtab[$2] = "" modtab[$2] - } else if ($1 == "undefined") { - if ($3 in symtab) - modtab[$2] = modtab[$2] " " symtab[$3]; - else if ($3 != "__gnu_local_gp" && $3 != "_gp_disp") { - printf "%s in %s is not defined\n", $3, $2 >"/dev/stderr"; - error++; - } - } else if ($1 == "depends") { - for (i = 3; i <= NF; i++) { - modtab[$2] = modtab[$2] " " $i; - } - } else if ($1 == "") {} #Skip empty lines - else { - printf "error: %u: unrecognized input format\n", NR >"/dev/stderr"; - error++; - } -} - -# Output the result. -END { - if (error >= 1) - exit 1; - - total_depcount = 0 - - 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 = "" - depcount[mod] = 0 - n = asorti(uniqmods, w) - for (i = 1; i <= n; i++) { - depmod = w[i] - modlist = modlist " " depmod; - inverse_dependencies[depmod] = inverse_dependencies[depmod] " " mod - depcount[mod]++ - total_depcount++ - } - if (mod == "all_video") { - continue; - } - printf "%s:%s\n", mod, modlist; - } - - # Check that we have no dependency circles - while (total_depcount != 0) { - something_done = 0 - for (mod in depcount) { - if (depcount[mod] == 0) { - delete depcount[mod] - split(inverse_dependencies[mod], inv_depmods, " "); - for (ctr in inv_depmods) { - depcount[inv_depmods[ctr]]-- - total_depcount-- - } - delete inverse_dependencies[mod] - something_done = 1 - } - } - if (something_done == 0) { - for (mod in depcount) { - circle = circle " " mod - } - printf "error: modules %s form a dependency circle\n", circle >"/dev/stderr"; - exit 1 - } - } - modlist = "" - while (getline <"video.lst") { - modlist = modlist " " $1; - } - printf "all_video:%s\n", modlist; -} diff --git a/grub-core/gensyminfo.sh.in b/grub-core/gensyminfo.sh.in deleted file mode 100644 index 9bc767532..000000000 --- a/grub-core/gensyminfo.sh.in +++ /dev/null @@ -1,37 +0,0 @@ -#! @BUILD_SHEBANG@ -set -e - -# Copyright (C) 2010 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. - -# -# Example: -# -# gensyms.sh normal.module -# - -module=$1 -modname=`echo $module | sed -e 's@\.module.*$@@'` - -# Print all symbols defined by module -if test x"@TARGET_NMFLAGS_DEFINED_ONLY@" = x && test x"@TARGET_NMFLAGS_MINUS_P@" = x; then - @TARGET_NM@ -g -p $module | \ - sed -n "s@^\([0-9a-fA-F]*\) *[TBRDS] *\([^ ]*\).*@defined $modname \2@p" -elif test x"@TARGET_NMFLAGS_DEFINED_ONLY@" = x; then - @TARGET_NM@ -g @TARGET_NMFLAGS_MINUS_P@ -p $module | \ - sed -n "s@^\([^ ]*\) *[TBRDS] *\([0-9a-fA-F]*\).*@defined $modname \1@p" -else - @TARGET_NM@ -g --defined-only @TARGET_NMFLAGS_MINUS_P@ -p $module | \ - sed "s@^\([^ ]*\).*@defined $modname \1@g" -fi - -# Print all undefined symbols used by module -@TARGET_NM@ -u @TARGET_NMFLAGS_MINUS_P@ -p $module | sed "s@^\([^ ]*\).*@undefined $modname \1@g" diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c deleted file mode 100644 index 9ffc73428..000000000 --- a/grub-core/gettext/gettext.c +++ /dev/null @@ -1,551 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* - .mo file information from: - http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html . -*/ - -static const char *(*grub_gettext_original) (const char *s); - -struct grub_gettext_msg -{ - char *name; - char *translated; -}; - -struct header -{ - grub_uint32_t magic; - grub_uint32_t version; - grub_uint32_t number_of_strings; - grub_uint32_t offset_original; - grub_uint32_t offset_translation; -}; - -struct string_descriptor -{ - grub_uint32_t length; - grub_uint32_t offset; -}; - -struct grub_gettext_context -{ - grub_file_t fd_mo; - grub_off_t grub_gettext_offset_original; - grub_off_t grub_gettext_offset_translation; - grub_size_t grub_gettext_max; - int grub_gettext_max_log; - struct grub_gettext_msg *grub_gettext_msg_list; -}; - -static struct grub_gettext_context main_context, secondary_context; - -#define MO_MAGIC_NUMBER 0x950412de - -static grub_err_t -grub_gettext_pread (grub_file_t file, void *buf, grub_size_t len, - grub_off_t offset) -{ - if (len == 0) - return GRUB_ERR_NONE; - if (grub_file_seek (file, offset) == (grub_off_t) - 1) - return grub_errno; - if (grub_file_read (file, buf, len) != (grub_ssize_t) len) - { - if (!grub_errno) - grub_error (GRUB_ERR_READ_ERROR, N_("premature end of file")); - return grub_errno; - } - return GRUB_ERR_NONE; -} - -static char * -grub_gettext_getstr_from_position (struct grub_gettext_context *ctx, - grub_off_t off, - grub_size_t position) -{ - grub_off_t internal_position; - grub_size_t length; - grub_off_t offset; - char *translation; - struct string_descriptor desc; - grub_err_t err; - grub_size_t alloc_sz; - - internal_position = (off + position * sizeof (desc)); - - err = grub_gettext_pread (ctx->fd_mo, (char *) &desc, - sizeof (desc), internal_position); - if (err) - return NULL; - length = grub_cpu_to_le32 (desc.length); - offset = grub_cpu_to_le32 (desc.offset); - - if (grub_add (length, 1, &alloc_sz)) - return NULL; - - translation = grub_malloc (alloc_sz); - if (!translation) - return NULL; - - err = grub_gettext_pread (ctx->fd_mo, translation, length, offset); - if (err) - { - grub_free (translation); - return NULL; - } - translation[length] = '\0'; - - return translation; -} - -static const char * -grub_gettext_gettranslation_from_position (struct grub_gettext_context *ctx, - grub_size_t position) -{ - if (!ctx->grub_gettext_msg_list[position].translated) - ctx->grub_gettext_msg_list[position].translated - = grub_gettext_getstr_from_position (ctx, - ctx->grub_gettext_offset_translation, - position); - return ctx->grub_gettext_msg_list[position].translated; -} - -static const char * -grub_gettext_getstring_from_position (struct grub_gettext_context *ctx, - grub_size_t position) -{ - if (!ctx->grub_gettext_msg_list[position].name) - ctx->grub_gettext_msg_list[position].name - = grub_gettext_getstr_from_position (ctx, - ctx->grub_gettext_offset_original, - position); - return ctx->grub_gettext_msg_list[position].name; -} - -static const char * -grub_gettext_translate_real (struct grub_gettext_context *ctx, - const char *orig) -{ - grub_size_t current = 0; - int i; - const char *current_string; - static int depth = 0; - - if (!ctx->grub_gettext_msg_list || !ctx->fd_mo) - return NULL; - - /* Shouldn't happen. Just a precaution if our own code - calls gettext somehow. */ - if (depth > 2) - return NULL; - depth++; - - /* 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 (); - - for (i = ctx->grub_gettext_max_log; i >= 0; i--) - { - grub_size_t test; - int cmp; - - test = current | (1 << i); - if (test >= ctx->grub_gettext_max) - continue; - - current_string = grub_gettext_getstring_from_position (ctx, test); - - if (!current_string) - { - grub_errno = GRUB_ERR_NONE; - grub_error_pop (); - depth--; - return NULL; - } - - /* Search by bisection. */ - cmp = grub_strcmp (current_string, orig); - if (cmp <= 0) - current = test; - if (cmp == 0) - { - const char *ret = 0; - ret = grub_gettext_gettranslation_from_position (ctx, current); - if (!ret) - { - grub_errno = GRUB_ERR_NONE; - grub_error_pop (); - depth--; - return NULL; - } - grub_error_pop (); - depth--; - return ret; - } - } - - if (current == 0 && ctx->grub_gettext_max != 0) - { - current_string = grub_gettext_getstring_from_position (ctx, 0); - - if (!current_string) - { - grub_errno = GRUB_ERR_NONE; - grub_error_pop (); - depth--; - return NULL; - } - - if (grub_strcmp (current_string, orig) == 0) - { - const char *ret = 0; - ret = grub_gettext_gettranslation_from_position (ctx, current); - if (!ret) - { - grub_errno = GRUB_ERR_NONE; - grub_error_pop (); - depth--; - return NULL; - } - grub_error_pop (); - depth--; - return ret; - } - } - - grub_error_pop (); - depth--; - return NULL; -} - -static const char * -grub_gettext_translate (const char *orig) -{ - const char *ret; - if (orig[0] == 0) - return orig; - - ret = grub_gettext_translate_real (&main_context, orig); - if (ret) - return ret; - ret = grub_gettext_translate_real (&secondary_context, orig); - if (ret) - return ret; - return orig; -} - -static void -grub_gettext_delete_list (struct grub_gettext_context *ctx) -{ - struct grub_gettext_msg *l = ctx->grub_gettext_msg_list; - grub_size_t i; - - if (!l) - return; - ctx->grub_gettext_msg_list = 0; - for (i = 0; i < ctx->grub_gettext_max; i++) - grub_free (l[i].name); - /* Don't delete the translated message because could be in use. */ - grub_free (l); - if (ctx->fd_mo) - grub_file_close (ctx->fd_mo); - ctx->fd_mo = 0; - grub_memset (ctx, 0, sizeof (*ctx)); -} - -/* This is similar to grub_file_open. */ -static grub_err_t -grub_mofile_open (struct grub_gettext_context *ctx, - const char *filename) -{ - struct header head; - grub_err_t err; - grub_file_t fd; - - /* Using fd_mo and not another variable because - it's needed for grub_gettext_get_info. */ - - fd = grub_file_open (filename, GRUB_FILE_TYPE_GETTEXT_CATALOG); - - if (!fd) - return grub_errno; - - err = grub_gettext_pread (fd, &head, sizeof (head), 0); - if (err) - { - grub_file_close (fd); - return err; - } - - if (head.magic != grub_cpu_to_le32_compile_time (MO_MAGIC_NUMBER)) - { - grub_file_close (fd); - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "mo: invalid mo magic in file: %s", filename); - } - - if (head.version != 0) - { - grub_file_close (fd); - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "mo: invalid mo version in file: %s", filename); - } - - ctx->grub_gettext_offset_original = grub_le_to_cpu32 (head.offset_original); - ctx->grub_gettext_offset_translation = grub_le_to_cpu32 (head.offset_translation); - ctx->grub_gettext_max = grub_le_to_cpu32 (head.number_of_strings); - for (ctx->grub_gettext_max_log = 0; ctx->grub_gettext_max >> ctx->grub_gettext_max_log; - ctx->grub_gettext_max_log++); - - ctx->grub_gettext_msg_list = grub_calloc (ctx->grub_gettext_max, - sizeof (ctx->grub_gettext_msg_list[0])); - if (!ctx->grub_gettext_msg_list) - { - grub_file_close (fd); - return grub_errno; - } - ctx->fd_mo = fd; - if (grub_gettext != grub_gettext_translate) - { - grub_gettext_original = grub_gettext; - grub_gettext = grub_gettext_translate; - } - return 0; -} - -/* Returning grub_file_t would be more natural, but grub_mofile_open assigns - to fd_mo anyway ... */ -static grub_err_t -grub_mofile_open_lang (struct grub_gettext_context *ctx, - const char *part1, const char *part2, const char *locale) -{ - char *mo_file; - grub_err_t err; - - /* mo_file e.g.: /boot/grub/locale/ca.mo */ - - mo_file = grub_xasprintf ("%s%s/%s.mo", part1, part2, locale); - if (!mo_file) - return grub_errno; - - err = grub_mofile_open (ctx, mo_file); - grub_free (mo_file); - - /* Will try adding .gz as well. */ - if (err) - { - grub_errno = GRUB_ERR_NONE; - mo_file = grub_xasprintf ("%s%s/%s.mo.gz", part1, part2, locale); - if (!mo_file) - return grub_errno; - err = grub_mofile_open (ctx, mo_file); - grub_free (mo_file); - } - - /* Will try adding .gmo as well. */ - if (err) - { - grub_errno = GRUB_ERR_NONE; - mo_file = grub_xasprintf ("%s%s/%s.gmo", part1, part2, locale); - if (!mo_file) - return grub_errno; - err = grub_mofile_open (ctx, mo_file); - grub_free (mo_file); - } - - return err; -} - -static grub_err_t -grub_gettext_init_ext (struct grub_gettext_context *ctx, - const char *locale, - const char *locale_dir, const char *prefix) -{ - const char *part1, *part2; - grub_err_t err; - - grub_gettext_delete_list (ctx); - - if (!locale || locale[0] == 0) - return 0; - - part1 = locale_dir; - part2 = ""; - if (!part1 || part1[0] == 0) - { - part1 = prefix; - part2 = "/locale"; - } - - if (!part1 || part1[0] == 0) - return 0; - - err = grub_mofile_open_lang (ctx, part1, part2, locale); - - /* ll_CC didn't work, so try ll. */ - if (err) - { - char *lang = grub_strdup (locale); - char *underscore = lang ? grub_strchr (lang, '_') : 0; - - if (underscore) - { - *underscore = '\0'; - grub_errno = GRUB_ERR_NONE; - err = grub_mofile_open_lang (ctx, part1, part2, lang); - } - - grub_free (lang); - } - - if (locale[0] == 'e' && locale[1] == 'n' - && (locale[2] == '\0' || locale[2] == '_')) - grub_errno = err = GRUB_ERR_NONE; - return err; -} - -static char * -grub_gettext_env_write_lang (struct grub_env_var *var - __attribute__ ((unused)), const char *val) -{ - grub_err_t err; - err = grub_gettext_init_ext (&main_context, val, grub_env_get ("locale_dir"), - grub_env_get ("prefix")); - if (err) - grub_print_error (); - - err = grub_gettext_init_ext (&secondary_context, val, - grub_env_get ("secondary_locale_dir"), 0); - if (err) - grub_print_error (); - - return grub_strdup (val); -} - -void -grub_gettext_reread_prefix (const char *val) -{ - grub_err_t err; - err = grub_gettext_init_ext (&main_context, grub_env_get ("lang"), - grub_env_get ("locale_dir"), - val); - if (err) - grub_print_error (); -} - -static char * -read_main (struct grub_env_var *var - __attribute__ ((unused)), const char *val) -{ - grub_err_t err; - err = grub_gettext_init_ext (&main_context, grub_env_get ("lang"), val, - grub_env_get ("prefix")); - if (err) - grub_print_error (); - return grub_strdup (val); -} - -static char * -read_secondary (struct grub_env_var *var - __attribute__ ((unused)), const char *val) -{ - grub_err_t err; - err = grub_gettext_init_ext (&secondary_context, grub_env_get ("lang"), val, - 0); - if (err) - grub_print_error (); - - 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, N_("one argument expected")); - - const char *translation; - translation = grub_gettext_translate (args[0]); - grub_printf ("%s\n", translation); - return 0; -} - -GRUB_MOD_INIT (gettext) -{ - const char *lang; - grub_err_t err; - - lang = grub_env_get ("lang"); - - err = grub_gettext_init_ext (&main_context, lang, grub_env_get ("locale_dir"), - grub_env_get ("prefix")); - if (err) - grub_print_error (); - err = grub_gettext_init_ext (&secondary_context, lang, - grub_env_get ("secondary_locale_dir"), 0); - if (err) - grub_print_error (); - - grub_register_variable_hook ("locale_dir", NULL, read_main); - grub_register_variable_hook ("secondary_locale_dir", NULL, read_secondary); - - grub_register_command_p1 ("gettext", grub_cmd_translate, - N_("STRING"), - /* TRANSLATORS: It refers to passing the string through gettext. - So it's "translate" in the same meaning as in what you're - doing now. - */ - 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_env_export ("locale_dir"); - grub_env_export ("secondary_locale_dir"); -} - -GRUB_MOD_FINI (gettext) -{ - grub_register_variable_hook ("locale_dir", NULL, NULL); - grub_register_variable_hook ("secondary_locale_dir", NULL, NULL); - grub_register_variable_hook ("lang", NULL, NULL); - - grub_gettext_delete_list (&main_context); - grub_gettext_delete_list (&secondary_context); - - grub_gettext = grub_gettext_original; -} diff --git a/grub-core/gfxmenu/font.c b/grub-core/gfxmenu/font.c deleted file mode 100644 index 756c24f20..000000000 --- a/grub-core/gfxmenu/font.c +++ /dev/null @@ -1,116 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* 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; - grub_uint32_t *logical; - grub_ssize_t logical_len, visual_len; - struct grub_unicode_glyph *visual, *ptr; - grub_err_t err; - - logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0); - if (logical_len < 0) - return grub_errno; - - visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual, - 0, 0, 0, 0, 0, 0, 0); - grub_free (logical); - if (visual_len < 0) - return grub_errno; - - err = GRUB_ERR_NONE; - for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++) - { - struct grub_font_glyph *glyph; - glyph = grub_font_construct_glyph (font, ptr); - if (!glyph) - { - err = grub_errno; - goto out; - } - err = grub_font_draw_glyph (glyph, color, x, baseline_y); - if (err) - goto out; - x += glyph->device_width; - } - -out: - for (ptr = visual; ptr < visual + visual_len; ptr++) - grub_unicode_destroy_glyph (ptr); - grub_free (visual); - - return err; -} - -/* 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 = 0; - grub_uint32_t *ptr; - grub_ssize_t logical_len; - grub_uint32_t *logical; - - logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0); - if (logical_len < 0) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - - for (ptr = logical; ptr < logical + logical_len;) - { - struct grub_unicode_glyph glyph; - - ptr += grub_unicode_aglomerate_comb (ptr, - logical_len - (ptr - logical), - &glyph); - width += grub_font_get_constructed_device_width (font, &glyph); - - grub_unicode_destroy_glyph (&glyph); - } - grub_free (logical); - - return width; -} diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c deleted file mode 100644 index 2ccd4345f..000000000 --- a/grub-core/gfxmenu/gui_list.c +++ /dev/null @@ -1,953 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -enum scrollbar_slice_mode { - SCROLLBAR_SLICE_WEST, - SCROLLBAR_SLICE_CENTER, - SCROLLBAR_SLICE_EAST -}; - -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; - int selected_item_font_inherit; - grub_font_t selected_item_font; - grub_video_rgba_color_t item_color; - int selected_item_color_inherit; - grub_video_rgba_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_thumb_overlay; - int scrollbar_width; - enum scrollbar_slice_mode scrollbar_slice; - int scrollbar_left_pad; - int scrollbar_right_pad; - int scrollbar_top_pad; - int scrollbar_bottom_pad; - - int first_shown_index; - - int need_to_recreate_boxes; - char *theme_dir; - char *menu_box_pattern; - char *item_box_pattern; - int selected_item_box_pattern_inherit; - char *selected_item_box_pattern; - grub_gfxmenu_box_t menu_box; - grub_gfxmenu_box_t selected_item_box; - grub_gfxmenu_box_t 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->item_box_pattern); - grub_free (self->selected_item_box_pattern); - if (self->menu_box) - self->menu_box->destroy (self->menu_box); - if (self->item_box) - self->item_box->destroy (self->item_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); - if (self->scrollbar_thumb) - self->scrollbar_thumb->destroy (self->scrollbar_thumb); - if (self->scrollbar_frame) - self->scrollbar_frame->destroy (self->scrollbar_frame); - grub_free (self->scrollbar_thumb_pattern); - grub_free (self->scrollbar_frame_pattern); - 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); - grub_gfxmenu_box_t itembox = self->item_box; - grub_gfxmenu_box_t selbox = self->selected_item_box; - int item_top_pad = itembox->get_top_pad (itembox); - int item_bottom_pad = itembox->get_bottom_pad (itembox); - int sel_top_pad = selbox->get_top_pad (selbox); - int sel_bottom_pad = selbox->get_bottom_pad (selbox); - int max_top_pad = grub_max (item_top_pad, sel_top_pad); - int max_bottom_pad = grub_max (item_bottom_pad, sel_bottom_pad); - - if (item_height + item_vspace <= 0) - return 1; - - return (self->bounds.height + item_vspace - 2 * boxpad - - max_top_pad - max_bottom_pad - - 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->item_box, - self->item_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 - && self->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; - } - - if (self->scrollbar_frame == 0 || self->scrollbar_thumb == 0) - return 0; - - /* Sanity checks. */ - grub_gfxmenu_box_t frame = self->scrollbar_frame; - grub_gfxmenu_box_t thumb = self->scrollbar_thumb; - grub_gfxmenu_box_t menu = self->menu_box; - int min_width = frame->get_left_pad (frame) - + frame->get_right_pad (frame); - int min_height = frame->get_top_pad (frame) - + frame->get_bottom_pad (frame) - + self->scrollbar_top_pad + self->scrollbar_bottom_pad - + menu->get_top_pad (menu) - + menu->get_bottom_pad (menu); - if (!self->scrollbar_thumb_overlay) - { - min_width += thumb->get_left_pad (thumb) - + thumb->get_right_pad (thumb); - min_height += thumb->get_top_pad (thumb) - + thumb->get_bottom_pad (thumb); - } - if (min_width <= self->scrollbar_width - && min_height <= (int) self->bounds.height) - return 1; - - /* Unprintable dimenstions. */ - self->draw_scrollbar = 0; - return 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 scrollbar_width, int scrollbar_height) -{ - unsigned thumby, thumbheight; - - 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)); - unsigned thumb_vertical_pad = (thumb->get_top_pad (thumb) - + thumb->get_bottom_pad (thumb)); - int thumb_horizontal_pad = (thumb->get_left_pad (thumb) - + thumb->get_right_pad (thumb)); - int tracktop = frame->get_top_pad (frame); - unsigned tracklen; - if (scrollbar_height <= frame_vertical_pad) - tracklen = 0; - else - tracklen = scrollbar_height - frame_vertical_pad; - frame->set_content_size (frame, - scrollbar_width - frame_horizontal_pad, - tracklen); - if (self->scrollbar_thumb_overlay) - { - tracklen += thumb_vertical_pad; - tracktop -= thumb->get_top_pad (thumb); - } - if (value <= min || max <= min) - thumby = 0; - else - thumby = ((unsigned) tracklen * (value - min)) - / ((unsigned) (max - min)); - if (max <= min) - thumbheight = 1; - else - thumbheight = ((unsigned) (tracklen * extent) - / ((unsigned) (max - min))) + 1; - /* Rare occasion: too many entries or too low height. */ - if (thumbheight < thumb_vertical_pad) - { - thumbheight = thumb_vertical_pad; - if (value <= min || max <= extent - || tracklen <= thumb_vertical_pad) - thumby = 0; - else - thumby = ((unsigned) ((tracklen - thumb_vertical_pad) * (value - min)) - / ((unsigned)(max - extent))); - } - thumby += tracktop; - int thumbx = frame->get_left_pad (frame); - int thumbwidth = scrollbar_width - frame_horizontal_pad; - if (!self->scrollbar_thumb_overlay) - thumbwidth -= thumb_horizontal_pad; - else - thumbx -= thumb->get_left_pad (thumb); - thumb->set_content_size (thumb, thumbwidth, - thumbheight - thumb_vertical_pad); - frame->draw (frame, 0, 0); - thumb->draw (thumb, thumbx, thumby); -} - -/* Draw the list of items. */ -static void -draw_menu (list_impl_t self, int num_shown_items) -{ - if (! self->menu_box || ! self->selected_item_box || ! self->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 selected_ascent = grub_font_get_ascent (self->selected_item_font); - int selected_descent = grub_font_get_descent (self->selected_item_font); - int text_box_height = self->item_height; - - make_selected_item_visible (self); - - grub_gfxmenu_box_t itembox = self->item_box; - grub_gfxmenu_box_t selbox = self->selected_item_box; - int item_leftpad = itembox->get_left_pad (itembox); - int item_rightpad = itembox->get_right_pad (itembox); - int item_border_width = item_leftpad + item_rightpad; - int item_toppad = itembox->get_top_pad (itembox); - int sel_leftpad = selbox->get_left_pad (selbox); - int sel_rightpad = selbox->get_right_pad (selbox); - int sel_border_width = sel_leftpad + sel_rightpad; - int sel_toppad = selbox->get_top_pad (selbox); - - int max_leftpad = grub_max (item_leftpad, sel_leftpad); - int max_toppad = grub_max (item_toppad, sel_toppad); - int item_top = 0; - int menu_index; - int visible_index; - struct grub_video_rect oviewport; - - grub_video_get_viewport (&oviewport.x, &oviewport.y, - &oviewport.width, &oviewport.height); - grub_video_set_viewport (oviewport.x + boxpad, - oviewport.y + boxpad, - oviewport.width - 2 * boxpad, - oviewport.height - 2 * boxpad); - - int cwidth = oviewport.width - 2 * boxpad; - - itembox->set_content_size (itembox, cwidth - item_border_width, - text_box_height); - selbox->set_content_size (selbox, cwidth - sel_border_width, - text_box_height); - - int text_left_offset = self->icon_width + icon_text_space; - int item_text_top_offset = (text_box_height - (ascent + descent)) / 2 + ascent; - int sel_text_top_offset = (text_box_height - (selected_ascent - + selected_descent)) / 2 - + selected_ascent; - - grub_video_rect_t svpsave, sviewport; - sviewport.x = max_leftpad + text_left_offset; - int text_viewport_width = cwidth - sviewport.x; - sviewport.height = text_box_height; - - grub_video_color_t item_color; - grub_video_color_t sel_color; - item_color = grub_video_map_rgba_color (self->item_color); - sel_color = grub_video_map_rgba_color (self->selected_item_color); - - int item_box_top_offset = max_toppad - item_toppad; - int sel_box_top_offset = max_toppad - sel_toppad; - int item_viewport_width = text_viewport_width - item_rightpad; - int sel_viewport_width = text_viewport_width - sel_rightpad; - int tmp_icon_top_offset = (text_box_height - self->icon_height) / 2; - int item_icon_top_offset = item_toppad + tmp_icon_top_offset; - int sel_icon_top_offset = sel_toppad + tmp_icon_top_offset; - - 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); - struct grub_video_bitmap *icon; - grub_font_t font; - grub_video_color_t color; - int text_top_offset; - int top_pad; - int icon_top_offset; - int viewport_width; - - if (is_selected) - { - selbox->draw (selbox, 0, item_top + sel_box_top_offset); - font = self->selected_item_font; - color = sel_color; - text_top_offset = sel_text_top_offset; - top_pad = sel_toppad; - icon_top_offset = sel_icon_top_offset; - viewport_width = sel_viewport_width; - } - else - { - itembox->draw (itembox, 0, item_top + item_box_top_offset); - font = self->item_font; - color = item_color; - text_top_offset = item_text_top_offset; - top_pad = item_toppad; - icon_top_offset = item_icon_top_offset; - viewport_width = item_viewport_width; - } - - icon = get_item_icon (self, menu_index); - if (icon != 0) - grub_video_blit_bitmap (icon, GRUB_VIDEO_BLIT_BLEND, - max_leftpad, - item_top + icon_top_offset, - 0, 0, self->icon_width, self->icon_height); - - const char *item_title = - grub_menu_get_entry (self->view->menu, menu_index)->title; - - sviewport.y = item_top + top_pad; - sviewport.width = viewport_width; - grub_gui_set_viewport (&sviewport, &svpsave); - grub_font_draw_string (item_title, - font, - color, - 0, - text_top_offset); - grub_gui_restore_viewport (&svpsave); - - item_top += text_box_height + item_vspace; - } - grub_video_set_viewport (oviewport.x, - oviewport.y, - oviewport.width, - oviewport.height); -} - -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 || ! self->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)); - int scrollbar_width = self->scrollbar_width; - - 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); - - switch (self->scrollbar_slice) - { - case SCROLLBAR_SLICE_WEST: - content_rect.x += self->scrollbar_right_pad; - content_rect.width -= self->scrollbar_right_pad; - break; - case SCROLLBAR_SLICE_CENTER: - if (drawing_scrollbar) - content_rect.width -= scrollbar_width + self->scrollbar_left_pad - + self->scrollbar_right_pad; - break; - case SCROLLBAR_SLICE_EAST: - content_rect.width -= self->scrollbar_left_pad; - break; - } - - grub_gui_set_viewport (&content_rect, &vpsave2); - draw_menu (self, num_shown_items); - grub_gui_restore_viewport (&vpsave2); - - if (drawing_scrollbar) - { - content_rect.y += self->scrollbar_top_pad; - content_rect.height -= self->scrollbar_top_pad - + self->scrollbar_bottom_pad; - content_rect.width = scrollbar_width; - switch (self->scrollbar_slice) - { - case SCROLLBAR_SLICE_WEST: - if (box_left_pad > scrollbar_width) - { - content_rect.x = box_left_pad - scrollbar_width; - content_rect.width = scrollbar_width; - } - else - { - content_rect.x = 0; - content_rect.width = box_left_pad; - } - break; - case SCROLLBAR_SLICE_CENTER: - content_rect.x = self->bounds.width - box_right_pad - - scrollbar_width - self->scrollbar_right_pad; - content_rect.width = scrollbar_width; - break; - case SCROLLBAR_SLICE_EAST: - content_rect.x = self->bounds.width - box_right_pad; - content_rect.width = box_right_pad; - break; - } - - grub_gui_set_viewport (&content_rect, &vpsave2); - draw_scrollbar (self, - self->first_shown_index, num_shown_items, - 0, self->view->menu->size, - scrollbar_width, - content_rect.height); - grub_gui_restore_viewport (&vpsave2); - } - } - - 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; - - grub_gfxmenu_box_t selbox = self->selected_item_box; - int sel_top_pad = selbox->get_top_pad (selbox); - int sel_bottom_pad = selbox->get_bottom_pad (selbox); - int sel_left_pad = selbox->get_left_pad (selbox); - int sel_right_pad = selbox->get_right_pad (selbox); - - grub_gfxmenu_box_t itembox = self->item_box; - int item_top_pad = itembox->get_top_pad (itembox); - int item_bottom_pad = itembox->get_bottom_pad (itembox); - int item_left_pad = itembox->get_left_pad (itembox); - int item_right_pad = itembox->get_right_pad (itembox); - - int max_left_pad = grub_max (item_left_pad, sel_left_pad); - int max_right_pad = grub_max (item_right_pad, sel_right_pad); - int max_top_pad = grub_max (item_top_pad, sel_top_pad); - int max_bottom_pad = grub_max (item_bottom_pad, sel_bottom_pad); - - *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 - + max_left_pad + max_right_pad - + self->item_icon_space + self->icon_width; - - switch (self->scrollbar_slice) - { - case SCROLLBAR_SLICE_WEST: - *width += self->scrollbar_right_pad; - break; - case SCROLLBAR_SLICE_CENTER: - *width += self->scrollbar_width + self->scrollbar_left_pad - + self->scrollbar_right_pad; - break; - case SCROLLBAR_SLICE_EAST: - *width += self->scrollbar_left_pad; - break; - } - - /* 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 - + max_top_pad + max_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); - if (self->selected_item_font_inherit) - self->selected_item_font = self->item_font; - } - else if (grub_strcmp (name, "selected_item_font") == 0) - { - if (! value || grub_strcmp (value, "inherit") == 0) - { - self->selected_item_font = self->item_font; - self->selected_item_font_inherit = 1; - } - else - { - self->selected_item_font = grub_font_get (value); - self->selected_item_font_inherit = 0; - } - } - else if (grub_strcmp (name, "item_color") == 0) - { - grub_video_rgba_color_t color; - if (grub_video_parse_color (value, &color) == GRUB_ERR_NONE) - { - self->item_color = color; - if (self->selected_item_color_inherit) - self->selected_item_color = self->item_color; - } - } - else if (grub_strcmp (name, "selected_item_color") == 0) - { - if (! value || grub_strcmp (value, "inherit") == 0) - { - self->selected_item_color = self->item_color; - self->selected_item_color_inherit = 1; - } - else - { - grub_video_rgba_color_t color; - if (grub_video_parse_color (value, &color) - == GRUB_ERR_NONE) - { - self->selected_item_color = color; - self->selected_item_color_inherit = 0; - } - } - } - 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, "item_pixmap_style") == 0) - { - self->need_to_recreate_boxes = 1; - grub_free (self->item_box_pattern); - self->item_box_pattern = value ? grub_strdup (value) : 0; - if (self->selected_item_box_pattern_inherit) - { - grub_free (self->selected_item_box_pattern); - self->selected_item_box_pattern = value ? grub_strdup (value) : 0; - } - } - else if (grub_strcmp (name, "selected_item_pixmap_style") == 0) - { - if (!value || grub_strcmp (value, "inherit") == 0) - { - grub_free (self->selected_item_box_pattern); - char *tmp = self->item_box_pattern; - self->selected_item_box_pattern = tmp ? grub_strdup (tmp) : 0; - self->selected_item_box_pattern_inherit = 1; - } - else - { - self->need_to_recreate_boxes = 1; - grub_free (self->selected_item_box_pattern); - self->selected_item_box_pattern = grub_strdup (value); - self->selected_item_box_pattern_inherit = 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_thumb_overlay") == 0) - { - self->scrollbar_thumb_overlay = grub_strcmp (value, "true") == 0; - } - else if (grub_strcmp (name, "scrollbar_width") == 0) - { - self->scrollbar_width = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "scrollbar_slice") == 0) - { - if (grub_strcmp (value, "west") == 0) - self->scrollbar_slice = SCROLLBAR_SLICE_WEST; - else if (grub_strcmp (value, "center") == 0) - self->scrollbar_slice = SCROLLBAR_SLICE_CENTER; - else if (grub_strcmp (value, "east") == 0) - self->scrollbar_slice = SCROLLBAR_SLICE_EAST; - } - else if (grub_strcmp (name, "scrollbar_left_pad") == 0) - { - self->scrollbar_left_pad = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "scrollbar_right_pad") == 0) - { - self->scrollbar_right_pad = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "scrollbar_top_pad") == 0) - { - self->scrollbar_top_pad = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "scrollbar_bottom_pad") == 0) - { - self->scrollbar_bottom_pad = 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; -} - -/* Refresh list variables */ -static void -list_refresh_info (void *vself, - grub_gfxmenu_view_t view) -{ - list_impl_t self = vself; - if (view->nested) - self->first_shown_index = 0; -} - -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, - .refresh_list = list_refresh_info -}; - -grub_gui_component_t -grub_gui_list_new (void) -{ - list_impl_t self; - grub_font_t default_font; - grub_video_rgba_color_t default_fg_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_video_rgba_color_rgb (0, 0, 0); - - 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_inherit = 1; /* Default to using the item_font. */ - self->selected_item_font = default_font; - self->item_color = default_fg_color; - self->selected_item_color_inherit = 1; /* 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_thumb_overlay = 0; - self->scrollbar_width = 16; - self->scrollbar_slice = SCROLLBAR_SLICE_EAST; - self->scrollbar_left_pad = 2; - self->scrollbar_right_pad = 0; - self->scrollbar_top_pad = 0; - self->scrollbar_bottom_pad = 0; - - self->first_shown_index = 0; - - self->need_to_recreate_boxes = 0; - self->theme_dir = 0; - self->menu_box_pattern = 0; - self->item_box_pattern = 0; - self->selected_item_box_pattern_inherit = 1;/*Default to using the item_box.*/ - self->selected_item_box_pattern = 0; - self->menu_box = grub_gfxmenu_create_box (0, 0); - self->item_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/io/bufio.c b/grub-core/io/bufio.c deleted file mode 100644 index a458c3aca..000000000 --- a/grub-core/io/bufio.c +++ /dev/null @@ -1,214 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#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; - grub_off_t buffer_at; - 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, grub_size_t size) -{ - grub_file_t file; - grub_bufio_t bufio = 0; - - file = (grub_file_t) grub_zalloc (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 > io->size) - size = ((io->size > GRUB_BUFIO_MAX_SIZE) ? GRUB_BUFIO_MAX_SIZE : - io->size); - - /* - * Round up size to power of 2 which the binary math to - * calculate next_buf in grub_bufio_read() requires. - */ - while (size & (size - 1)) - size = (size | (size - 1)) + 1; - - bufio = grub_zalloc (sizeof (struct grub_bufio) + size); - if (! bufio) - { - grub_free (file); - return 0; - } - - bufio->file = io; - bufio->block_size = size; - - file->device = io->device; - file->size = io->size; - file->data = bufio; - file->fs = &grub_bufio_fs; - file->not_easily_seekable = io->not_easily_seekable; - - return file; -} - -grub_file_t -grub_buffile_open (const char *name, enum grub_file_type type, grub_size_t size) -{ - grub_file_t io, file; - - io = grub_file_open (name, type); - 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 = 0; - grub_off_t next_buf; - grub_bufio_t bufio = file->data; - grub_ssize_t really_read; - - if (file->size == GRUB_FILE_SIZE_UNKNOWN) - file->size = bufio->file->size; - - /* First part: use whatever we already have in the buffer. */ - if ((file->offset >= bufio->buffer_at) && - (file->offset < bufio->buffer_at + bufio->buffer_len)) - { - grub_size_t n; - grub_uint64_t pos; - - pos = file->offset - bufio->buffer_at; - n = bufio->buffer_len - pos; - if (n > len) - n = len; - - grub_memcpy (buf, &bufio->buffer[pos], n); - len -= n; - res += n; - - buf += n; - } - if (len == 0) - return res; - - /* Need to read some more. */ - next_buf = (file->offset + res + len - 1) & ~((grub_off_t) bufio->block_size - 1); - /* Now read between file->offset + res and bufio->buffer_at. */ - if (file->offset + res < next_buf) - { - grub_size_t read_now; - read_now = next_buf - (file->offset + res); - grub_file_seek (bufio->file, file->offset + res); - really_read = grub_file_read (bufio->file, buf, read_now); - if (really_read < 0) - return -1; - if (file->size == GRUB_FILE_SIZE_UNKNOWN) - file->size = bufio->file->size; - len -= really_read; - buf += really_read; - res += really_read; - - /* Partial read. File ended unexpectedly. Save the last chunk in buffer. - */ - if (really_read != (grub_ssize_t) read_now) - { - bufio->buffer_len = really_read; - if (bufio->buffer_len > bufio->block_size) - bufio->buffer_len = bufio->block_size; - bufio->buffer_at = file->offset + res - bufio->buffer_len; - grub_memcpy (&bufio->buffer[0], buf - bufio->buffer_len, - bufio->buffer_len); - return res; - } - } - - /* Read into buffer. */ - grub_file_seek (bufio->file, next_buf); - really_read = grub_file_read (bufio->file, bufio->buffer, - bufio->block_size); - if (really_read < 0) - return -1; - bufio->buffer_at = next_buf; - bufio->buffer_len = really_read; - - if (file->size == GRUB_FILE_SIZE_UNKNOWN) - file->size = bufio->file->size; - - if (len > bufio->buffer_len) - len = bufio->buffer_len; - grub_memcpy (buf, &bufio->buffer[file->offset + res - next_buf], len); - res += 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", - .fs_dir = 0, - .fs_open = 0, - .fs_read = grub_bufio_read, - .fs_close = grub_bufio_close, - .fs_label = 0, - .next = 0 - }; diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c deleted file mode 100644 index a7d442543..000000000 --- a/grub-core/io/lzopio.c +++ /dev/null @@ -1,546 +0,0 @@ -/* lzopio.c - decompression support for lzop */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define LZOP_MAGIC "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a" -#define LZOP_MAGIC_SIZE 9 -#define LZOP_CHECK_SIZE 4 -#define LZOP_NEW_LIB 0x0940 - -/* Header flags - copied from conf.h of LZOP source code. */ -#define F_ADLER32_D 0x00000001L -#define F_ADLER32_C 0x00000002L -#define F_STDIN 0x00000004L -#define F_STDOUT 0x00000008L -#define F_NAME_DEFAULT 0x00000010L -#define F_DOSISH 0x00000020L -#define F_H_EXTRA_FIELD 0x00000040L -#define F_H_GMTDIFF 0x00000080L -#define F_CRC32_D 0x00000100L -#define F_CRC32_C 0x00000200L -#define F_MULTIPART 0x00000400L -#define F_H_FILTER 0x00000800L -#define F_H_CRC32 0x00001000L -#define F_H_PATH 0x00002000L -#define F_MASK 0x00003FFFL - -struct block_header -{ - grub_uint32_t usize; - grub_uint32_t csize; - grub_uint32_t ucheck; - grub_uint32_t ccheck; - unsigned char *cdata; - unsigned char *udata; -}; - -struct grub_lzopio -{ - grub_file_t file; - int has_ccheck; - int has_ucheck; - const gcry_md_spec_t *ucheck_fun; - const gcry_md_spec_t *ccheck_fun; - grub_off_t saved_off; /* Rounded down to block boundary. */ - grub_off_t start_block_off; - struct block_header block; -}; - -typedef struct grub_lzopio *grub_lzopio_t; -static struct grub_fs grub_lzopio_fs; - -/* Some helper functions. On errors memory allocated by those function is free - * either on close() so no risk of leaks. This makes functions simpler. */ - -/* Read block header from file, after successful exit file points to - * beginning of block data. */ -static int -read_block_header (struct grub_lzopio *lzopio) -{ - lzopio->saved_off += lzopio->block.usize; - - /* Free cached block data if any. */ - grub_free (lzopio->block.udata); - grub_free (lzopio->block.cdata); - lzopio->block.udata = NULL; - lzopio->block.cdata = NULL; - - if (grub_file_read (lzopio->file, &lzopio->block.usize, - sizeof (lzopio->block.usize)) != - sizeof (lzopio->block.usize)) - return -1; - - lzopio->block.usize = grub_be_to_cpu32 (lzopio->block.usize); - - /* Last block has uncompressed data size == 0 and no other fields. */ - if (lzopio->block.usize == 0) - { - if (grub_file_tell (lzopio->file) == grub_file_size (lzopio->file)) - return 0; - else - return -1; - } - - /* Read compressed data block size. */ - if (grub_file_read (lzopio->file, &lzopio->block.csize, - sizeof (lzopio->block.csize)) != - sizeof (lzopio->block.csize)) - return -1; - - lzopio->block.csize = grub_be_to_cpu32 (lzopio->block.csize); - - /* Corrupted. */ - if (lzopio->block.csize > lzopio->block.usize) - return -1; - - /* Read checksum of uncompressed data. */ - if (lzopio->has_ucheck) - { - if (grub_file_read (lzopio->file, &lzopio->block.ucheck, - sizeof (lzopio->block.ucheck)) != - sizeof (lzopio->block.ucheck)) - return -1; - } - - /* Read checksum of compressed data. */ - if (lzopio->has_ccheck) - { - /* Incompressible data block. */ - if (lzopio->block.csize == lzopio->block.usize) - { - lzopio->block.ccheck = lzopio->block.ucheck; - } - else - { - if (grub_file_read (lzopio->file, &lzopio->block.ccheck, - sizeof (lzopio->block.ccheck)) != - sizeof (lzopio->block.ccheck)) - return -1; - } - } - - return 0; -} - -/* Read block data into memory. File must be set to beginning of block data. - * Can't be called on last block. */ -static int -read_block_data (struct grub_lzopio *lzopio) -{ - lzopio->block.cdata = grub_malloc (lzopio->block.csize); - if (!lzopio->block.cdata) - return -1; - - if (grub_file_read (lzopio->file, lzopio->block.cdata, lzopio->block.csize) - != (grub_ssize_t) lzopio->block.csize) - return -1; - - if (lzopio->ccheck_fun) - { - grub_uint8_t computed_hash[GRUB_CRYPTO_MAX_MDLEN]; - - if (lzopio->ccheck_fun->mdlen > GRUB_CRYPTO_MAX_MDLEN) - return -1; - - grub_crypto_hash (lzopio->ccheck_fun, computed_hash, - lzopio->block.cdata, - lzopio->block.csize); - - if (grub_memcmp - (computed_hash, &lzopio->block.ccheck, - sizeof (lzopio->block.ccheck)) != 0) - return -1; - } - - return 0; -} - -/* Read block data, uncompressed and also store it in memory. */ -/* XXX Investigate possibility of in-place decompression to reduce memory - * footprint. Or try to uncompress directly to buf if possible. */ -static int -uncompress_block (struct grub_lzopio *lzopio) -{ - lzo_uint usize = lzopio->block.usize; - - if (read_block_data (lzopio) < 0) - return -1; - - /* Incompressible data. */ - if (lzopio->block.csize == lzopio->block.usize) - { - lzopio->block.udata = lzopio->block.cdata; - lzopio->block.cdata = NULL; - } - else - { - lzopio->block.udata = grub_malloc (lzopio->block.usize); - if (!lzopio->block.udata) - return -1; - - if (lzo1x_decompress_safe (lzopio->block.cdata, lzopio->block.csize, - lzopio->block.udata, &usize, NULL) - != LZO_E_OK) - return -1; - - if (lzopio->ucheck_fun) - { - grub_uint8_t computed_hash[GRUB_CRYPTO_MAX_MDLEN]; - - if (lzopio->ucheck_fun->mdlen > GRUB_CRYPTO_MAX_MDLEN) - return -1; - - grub_crypto_hash (lzopio->ucheck_fun, computed_hash, - lzopio->block.udata, - lzopio->block.usize); - - if (grub_memcmp - (computed_hash, &lzopio->block.ucheck, - sizeof (lzopio->block.ucheck)) != 0) - return -1; - } - - /* Compressed data can be free now. */ - grub_free (lzopio->block.cdata); - lzopio->block.cdata = NULL; - } - - return 0; -} - -/* Jump to next block and read its header. */ -static int -jump_block (struct grub_lzopio *lzopio) -{ - /* only jump if block was not decompressed (and read from disk) */ - if (!lzopio->block.udata) - { - grub_off_t off = grub_file_tell (lzopio->file) + lzopio->block.csize; - - if (grub_file_seek (lzopio->file, off) == ((grub_off_t) - 1)) - return -1; - } - - return read_block_header (lzopio); -} - -static int -calculate_uncompressed_size (grub_file_t file) -{ - grub_lzopio_t lzopio = file->data; - grub_off_t usize_total = 0; - - if (read_block_header (lzopio) < 0) - return -1; - - /* FIXME: Don't do this for not easily seekable files. */ - while (lzopio->block.usize != 0) - { - usize_total += lzopio->block.usize; - - if (jump_block (lzopio) < 0) - return -1; - } - - file->size = usize_total; - - return 0; -} - -struct lzop_header -{ - grub_uint8_t magic[LZOP_MAGIC_SIZE]; - grub_uint16_t lzop_version; - grub_uint16_t lib_version; - grub_uint16_t lib_version_ext; - grub_uint8_t method; - grub_uint8_t level; - grub_uint32_t flags; - /* grub_uint32_t filter; */ /* No filters support. Rarely used anyway. */ - grub_uint32_t mode; - grub_uint32_t mtime_lo; - grub_uint32_t mtime_hi; - grub_uint8_t name_len; -} GRUB_PACKED; - -static int -test_header (grub_file_t file) -{ - grub_lzopio_t lzopio = file->data; - struct lzop_header header; - grub_uint32_t flags, checksum; - const gcry_md_spec_t *hcheck; - grub_uint8_t *context = NULL; - grub_uint8_t *name = NULL; - - if (grub_file_read (lzopio->file, &header, sizeof (header)) != sizeof (header)) - return 0; - - if (grub_memcmp (header.magic, LZOP_MAGIC, LZOP_MAGIC_SIZE) != 0) - return 0; - - if (grub_be_to_cpu16(header.lib_version) < LZOP_NEW_LIB) - return 0; - - /* Too new version, should upgrade minilzo? */ - if (grub_be_to_cpu16 (header.lib_version_ext) > MINILZO_VERSION) - return 0; - - flags = grub_be_to_cpu32 (header.flags); - - if (flags & F_CRC32_D) - { - lzopio->has_ucheck = 1; - lzopio->ucheck_fun = grub_crypto_lookup_md_by_name ("crc32"); - } - else if (flags & F_ADLER32_D) - { - lzopio->has_ucheck = 1; - lzopio->ucheck_fun = grub_crypto_lookup_md_by_name ("adler32"); - } - - if (flags & F_CRC32_C) - { - lzopio->has_ccheck = 1; - lzopio->ccheck_fun = grub_crypto_lookup_md_by_name ("crc32"); - } - else if (flags & F_ADLER32_C) - { - lzopio->has_ccheck = 1; - lzopio->ccheck_fun = grub_crypto_lookup_md_by_name ("adler32"); - } - - if (flags & F_H_CRC32) - hcheck = grub_crypto_lookup_md_by_name ("crc32"); - else - hcheck = grub_crypto_lookup_md_by_name ("adler32"); - - if (hcheck) { - context = grub_malloc(hcheck->contextsize); - if (! context) - return 0; - - hcheck->init(context); - - /* MAGIC is not included in check calculation. */ - hcheck->write(context, &header.lzop_version, sizeof(header)- LZOP_MAGIC_SIZE); - } - - if (header.name_len != 0) - { - name = grub_malloc (header.name_len); - if (! name) - { - grub_free (context); - return 0; - } - - if (grub_file_read (lzopio->file, name, header.name_len) != - header.name_len) - { - grub_free(name); - goto CORRUPTED; - } - - if (hcheck) - hcheck->write(context, name, header.name_len); - - grub_free(name); - } - - if (hcheck) - hcheck->final(context); - - if (grub_file_read (lzopio->file, &checksum, sizeof (checksum)) != - sizeof (checksum)) - goto CORRUPTED; - - if (hcheck && grub_memcmp (&checksum, hcheck->read(context), sizeof(checksum)) != 0) - goto CORRUPTED; - - lzopio->start_block_off = grub_file_tell (lzopio->file); - - if (calculate_uncompressed_size (file) < 0) - goto CORRUPTED; - - /* Get back to start block. */ - grub_file_seek (lzopio->file, lzopio->start_block_off); - - /* Read first block - grub_lzopio_read() expects valid block. */ - if (read_block_header (lzopio) < 0) - goto CORRUPTED; - - lzopio->saved_off = 0; - return 1; - -CORRUPTED: - return 0; -} - -static grub_file_t -grub_lzopio_open (grub_file_t io, enum grub_file_type type) -{ - grub_file_t file; - grub_lzopio_t lzopio; - - if (type & GRUB_FILE_TYPE_NO_DECOMPRESS) - return io; - - file = (grub_file_t) grub_zalloc (sizeof (*file)); - if (!file) - return 0; - - lzopio = grub_zalloc (sizeof (*lzopio)); - if (!lzopio) - { - grub_free (file); - return 0; - } - - lzopio->file = io; - - file->device = io->device; - file->data = lzopio; - file->fs = &grub_lzopio_fs; - file->size = GRUB_FILE_SIZE_UNKNOWN; - file->not_easily_seekable = 1; - - if (grub_file_tell (lzopio->file) != 0) - grub_file_seek (lzopio->file, 0); - - if (!test_header (file)) - { - grub_errno = GRUB_ERR_NONE; - grub_file_seek (io, 0); - grub_free (lzopio); - grub_free (file); - - return io; - } - - return file; -} - -static grub_ssize_t -grub_lzopio_read (grub_file_t file, char *buf, grub_size_t len) -{ - grub_lzopio_t lzopio = file->data; - grub_ssize_t ret = 0; - grub_off_t off; - - /* Backward seek before last read block. */ - if (lzopio->saved_off > grub_file_tell (file)) - { - grub_file_seek (lzopio->file, lzopio->start_block_off); - - if (read_block_header (lzopio) < 0) - goto CORRUPTED; - - lzopio->saved_off = 0; - } - - /* Forward to first block with requested data. */ - while (lzopio->saved_off + lzopio->block.usize <= grub_file_tell (file)) - { - /* EOF, could be possible files with unknown size. */ - if (lzopio->block.usize == 0) - return 0; - - if (jump_block (lzopio) < 0) - goto CORRUPTED; - } - - off = grub_file_tell (file) - lzopio->saved_off; - - while (len != 0 && lzopio->block.usize != 0) - { - grub_size_t to_copy; - - /* Block not decompressed yet. */ - if (!lzopio->block.udata && uncompress_block (lzopio) < 0) - goto CORRUPTED; - - /* Copy requested data into buffer. */ - to_copy = lzopio->block.usize - off; - if (to_copy > len) - to_copy = len; - grub_memcpy (buf, lzopio->block.udata + off, to_copy); - - len -= to_copy; - buf += to_copy; - ret += to_copy; - off = 0; - - /* Read next block if needed. */ - if (len > 0 && read_block_header (lzopio) < 0) - goto CORRUPTED; - } - - return ret; - -CORRUPTED: - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, N_("lzop file corrupted")); - return -1; -} - -/* Release everything, including the underlying file object. */ -static grub_err_t -grub_lzopio_close (grub_file_t file) -{ - grub_lzopio_t lzopio = file->data; - - grub_file_close (lzopio->file); - grub_free (lzopio->block.cdata); - grub_free (lzopio->block.udata); - grub_free (lzopio); - - /* Device must not be closed twice. */ - file->device = 0; - file->name = 0; - return grub_errno; -} - -static struct grub_fs grub_lzopio_fs = { - .name = "lzopio", - .fs_dir = 0, - .fs_open = 0, - .fs_read = grub_lzopio_read, - .fs_close = grub_lzopio_close, - .fs_label = 0, - .next = 0 -}; - -GRUB_MOD_INIT (lzopio) -{ - grub_file_filter_register (GRUB_FILE_FILTER_LZOPIO, grub_lzopio_open); -} - -GRUB_MOD_FINI (lzopio) -{ - grub_file_filter_unregister (GRUB_FILE_FILTER_LZOPIO); -} diff --git a/grub-core/io/offset.c b/grub-core/io/offset.c deleted file mode 100644 index 7e2db4a3a..000000000 --- a/grub-core/io/offset.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct grub_offset_file -{ - grub_file_t parent; - grub_off_t off; -}; - -static grub_ssize_t -grub_offset_read (grub_file_t file, char *buf, grub_size_t len) -{ - struct grub_offset_file *data = file->data; - if (grub_file_seek (data->parent, data->off + file->offset) == (grub_off_t) -1) - return -1; - return grub_file_read (data->parent, buf, len); -} - -static grub_err_t -grub_offset_close (grub_file_t file) -{ - struct grub_offset_file *data = file->data; - - if (data->parent) - grub_file_close (data->parent); - - /* No need to close the same device twice. */ - file->device = 0; - - return 0; -} - -static struct grub_fs grub_offset_fs = { - .name = "offset", - .fs_dir = 0, - .fs_open = 0, - .fs_read = grub_offset_read, - .fs_close = grub_offset_close, - .fs_label = 0, - .next = 0 -}; - -void -grub_file_offset_close (grub_file_t file) -{ - struct grub_offset_file *off_data = file->data; - off_data->parent = NULL; - grub_file_close (file); -} - -grub_file_t -grub_file_offset_open (grub_file_t parent, enum grub_file_type type, - grub_off_t start, grub_off_t size) -{ - struct grub_offset_file *off_data; - grub_file_t off_file, last_off_file; - grub_file_filter_id_t filter; - - off_file = grub_zalloc (sizeof (*off_file)); - off_data = grub_zalloc (sizeof (*off_data)); - if (!off_file || !off_data) - { - grub_free (off_file); - grub_free (off_data); - return 0; - } - - off_data->off = start; - off_data->parent = parent; - - off_file->device = parent->device; - off_file->data = off_data; - off_file->fs = &grub_offset_fs; - off_file->size = size; - - last_off_file = NULL; - for (filter = GRUB_FILE_FILTER_COMPRESSION_FIRST; - off_file && filter <= GRUB_FILE_FILTER_COMPRESSION_LAST; filter++) - if (grub_file_filters[filter]) - { - last_off_file = off_file; - off_file = grub_file_filters[filter] (off_file, type); - } - - if (!off_file) - { - off_data->parent = NULL; - grub_file_close (last_off_file); - return 0; - } - return off_file; -} diff --git a/grub-core/io/xzio.c b/grub-core/io/xzio.c deleted file mode 100644 index 63d8cda6a..000000000 --- a/grub-core/io/xzio.c +++ /dev/null @@ -1,346 +0,0 @@ -/* xzio.c - decompression support for xz */ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#include "xz.h" -#include "xz_stream.h" - -#define XZBUFSIZ 0x2000 -#define VLI_MAX_DIGITS 9 -#define XZ_STREAM_FOOTER_SIZE 12 - -struct grub_xzio -{ - grub_file_t file; - struct xz_buf buf; - struct xz_dec *dec; - grub_uint8_t inbuf[XZBUFSIZ]; - grub_uint8_t outbuf[XZBUFSIZ]; - grub_off_t saved_offset; -}; - -typedef struct grub_xzio *grub_xzio_t; -static struct grub_fs grub_xzio_fs; - -static grub_size_t -decode_vli (const grub_uint8_t buf[], grub_size_t size_max, - grub_uint64_t *num) -{ - if (size_max == 0) - return 0; - - if (size_max > VLI_MAX_DIGITS) - size_max = VLI_MAX_DIGITS; - - *num = buf[0] & 0x7F; - grub_size_t i = 0; - - while (buf[i++] & 0x80) - { - if (i >= size_max || buf[i] == 0x00) - return 0; - - *num |= (uint64_t) (buf[i] & 0x7F) << (i * 7); - } - - return i; -} - -static grub_ssize_t -read_vli (grub_file_t file, grub_uint64_t *num) -{ - grub_uint8_t buf[VLI_MAX_DIGITS]; - grub_ssize_t read_bytes; - grub_size_t dec; - - read_bytes = grub_file_read (file, buf, VLI_MAX_DIGITS); - if (read_bytes < 0) - return -1; - - dec = decode_vli (buf, read_bytes, num); - grub_file_seek (file, file->offset - (read_bytes - dec)); - return dec; -} - -/* Function xz_dec_run() should consume header and ask for more (XZ_OK) - * else file is corrupted (or options not supported) or not xz. */ -static int -test_header (grub_file_t file) -{ - grub_xzio_t xzio = file->data; - enum xz_ret ret; - - xzio->buf.in_size = grub_file_read (xzio->file, xzio->inbuf, - STREAM_HEADER_SIZE); - - if (xzio->buf.in_size != STREAM_HEADER_SIZE) - return 0; - - ret = xz_dec_run (xzio->dec, &xzio->buf); - - if (ret == XZ_FORMAT_ERROR) - return 0; - - if (ret != XZ_OK) - return 0; - - return 1; -} - -/* Try to find out size of uncompressed data, - * also do some footer sanity checks. */ -static int -test_footer (grub_file_t file) -{ - grub_xzio_t xzio = file->data; - grub_uint8_t footer[FOOTER_MAGIC_SIZE]; - grub_uint32_t backsize; - grub_uint8_t imarker; - grub_uint64_t uncompressed_size_total = 0; - grub_uint64_t uncompressed_size; - grub_uint64_t records; - - grub_file_seek (xzio->file, xzio->file->size - FOOTER_MAGIC_SIZE); - if (grub_file_read (xzio->file, footer, FOOTER_MAGIC_SIZE) - != FOOTER_MAGIC_SIZE - || grub_memcmp (footer, FOOTER_MAGIC, FOOTER_MAGIC_SIZE) != 0) - goto ERROR; - - grub_file_seek (xzio->file, xzio->file->size - 8); - if (grub_file_read (xzio->file, &backsize, sizeof (backsize)) - != sizeof (backsize)) - goto ERROR; - - /* Calculate real backward size. */ - backsize = (grub_le_to_cpu32 (backsize) + 1) * 4; - - /* Set file to the beginning of stream index. */ - grub_file_seek (xzio->file, - xzio->file->size - XZ_STREAM_FOOTER_SIZE - backsize); - - /* Test index marker. */ - if (grub_file_read (xzio->file, &imarker, sizeof (imarker)) - != sizeof (imarker) && imarker != 0x00) - goto ERROR; - - if (read_vli (xzio->file, &records) <= 0) - goto ERROR; - - for (; records != 0; records--) - { - if (read_vli (xzio->file, &uncompressed_size) <= 0) /* Ignore unpadded. */ - goto ERROR; - if (read_vli (xzio->file, &uncompressed_size) <= 0) /* Uncompressed. */ - goto ERROR; - - uncompressed_size_total += uncompressed_size; - } - - file->size = uncompressed_size_total; - grub_file_seek (xzio->file, STREAM_HEADER_SIZE); - return 1; - -ERROR: - return 0; -} - -static grub_file_t -grub_xzio_open (grub_file_t io, enum grub_file_type type) -{ - grub_file_t file; - grub_xzio_t xzio; - - if (type & GRUB_FILE_TYPE_NO_DECOMPRESS) - return io; - - file = (grub_file_t) grub_zalloc (sizeof (*file)); - if (!file) - return 0; - - xzio = grub_zalloc (sizeof (*xzio)); - if (!xzio) - { - grub_free (file); - return 0; - } - - xzio->file = io; - - file->device = io->device; - file->data = xzio; - file->fs = &grub_xzio_fs; - file->size = GRUB_FILE_SIZE_UNKNOWN; - file->not_easily_seekable = 1; - - if (grub_file_tell (xzio->file) != 0) - grub_file_seek (xzio->file, 0); - - /* Allocated 64KiB for dictionary. - * Decoder will relocate if bigger is needed. */ - xzio->dec = xz_dec_init (1 << 16); - if (!xzio->dec) - { - grub_free (file); - grub_free (xzio); - return 0; - } - - xzio->buf.in = xzio->inbuf; - xzio->buf.out = xzio->outbuf; - xzio->buf.out_size = XZBUFSIZ; - - /* FIXME: don't test footer on not easily seekable files. */ - if (!test_header (file) || !test_footer (file)) - { - grub_errno = GRUB_ERR_NONE; - grub_file_seek (io, 0); - xz_dec_end (xzio->dec); - grub_free (xzio); - grub_free (file); - - return io; - } - - return file; -} - -static grub_ssize_t -grub_xzio_read (grub_file_t file, char *buf, grub_size_t len) -{ - grub_ssize_t ret = 0; - grub_ssize_t readret; - enum xz_ret xzret; - grub_xzio_t xzio = file->data; - grub_off_t current_offset; - - /* If seek backward need to reset decoder and start from beginning of file. - TODO Possible improvement by jumping blocks. */ - if (file->offset < xzio->saved_offset) - { - xz_dec_reset (xzio->dec); - xzio->saved_offset = 0; - xzio->buf.out_pos = 0; - xzio->buf.in_pos = 0; - xzio->buf.in_size = 0; - grub_file_seek (xzio->file, 0); - } - - current_offset = xzio->saved_offset; - - while (len > 0) - { - xzio->buf.out_size = file->offset + ret + len - current_offset; - if (xzio->buf.out_size > XZBUFSIZ) - xzio->buf.out_size = XZBUFSIZ; - /* Feed input. */ - if (xzio->buf.in_pos == xzio->buf.in_size) - { - readret = grub_file_read (xzio->file, xzio->inbuf, XZBUFSIZ); - if (readret < 0) - return -1; - xzio->buf.in_size = readret; - xzio->buf.in_pos = 0; - } - - xzret = xz_dec_run (xzio->dec, &xzio->buf); - switch (xzret) - { - case XZ_MEMLIMIT_ERROR: - case XZ_FORMAT_ERROR: - case XZ_OPTIONS_ERROR: - case XZ_DATA_ERROR: - case XZ_BUF_ERROR: - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, - N_("xz file corrupted or unsupported block options")); - return -1; - default: - break; - } - - { - grub_off_t new_offset = current_offset + xzio->buf.out_pos; - - if (file->offset <= new_offset) - /* Store first chunk of data in buffer. */ - { - grub_size_t delta = new_offset - (file->offset + ret); - grub_memmove (buf, xzio->buf.out + (xzio->buf.out_pos - delta), - delta); - len -= delta; - buf += delta; - ret += delta; - } - current_offset = new_offset; - } - xzio->buf.out_pos = 0; - - if (xzret == XZ_STREAM_END) /* Stream end, EOF. */ - break; - } - - if (ret >= 0) - xzio->saved_offset = file->offset + ret; - - return ret; -} - -/* Release everything, including the underlying file object. */ -static grub_err_t -grub_xzio_close (grub_file_t file) -{ - grub_xzio_t xzio = file->data; - - xz_dec_end (xzio->dec); - - grub_file_close (xzio->file); - grub_free (xzio); - - /* Device must not be closed twice. */ - file->device = 0; - file->name = 0; - return grub_errno; -} - -static struct grub_fs grub_xzio_fs = { - .name = "xzio", - .fs_dir = 0, - .fs_open = 0, - .fs_read = grub_xzio_read, - .fs_close = grub_xzio_close, - .fs_label = 0, - .next = 0 -}; - -GRUB_MOD_INIT (xzio) -{ - grub_file_filter_register (GRUB_FILE_FILTER_XZIO, grub_xzio_open); -} - -GRUB_MOD_FINI (xzio) -{ - grub_file_filter_unregister (GRUB_FILE_FILTER_XZIO); -} diff --git a/grub-core/kern/acpi.c b/grub-core/kern/acpi.c deleted file mode 100644 index 8ff0835d5..000000000 --- a/grub-core/kern/acpi.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2012 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include - -/* 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; -} - -static void * -grub_acpi_rsdt_find_table (struct grub_acpi_table_header *rsdt, const char *sig) -{ - grub_size_t s; - grub_unaligned_uint32_t *ptr; - - if (!rsdt) - return 0; - - if (grub_memcmp (rsdt->signature, "RSDT", 4) != 0) - return 0; - - ptr = (grub_unaligned_uint32_t *) (rsdt + 1); - s = (rsdt->length - sizeof (*rsdt)) / sizeof (grub_uint32_t); - for (; s; s--, ptr++) - { - struct grub_acpi_table_header *tbl; - - /* Skip NULL entries in RSDT/XSDT. */ - if (!ptr->val) - continue; - tbl = (struct grub_acpi_table_header *) (grub_addr_t) ptr->val; - if (grub_memcmp (tbl->signature, sig, 4) == 0) - return tbl; - } - return 0; -} - -static void * -grub_acpi_xsdt_find_table (struct grub_acpi_table_header *xsdt, const char *sig) -{ - grub_size_t s; - grub_unaligned_uint64_t *ptr; - - if (!xsdt) - return 0; - - if (grub_memcmp (xsdt->signature, "XSDT", 4) != 0) - return 0; - - ptr = (grub_unaligned_uint64_t *) (xsdt + 1); - s = (xsdt->length - sizeof (*xsdt)) / sizeof (grub_uint64_t); - for (; s; s--, ptr++) - { - struct grub_acpi_table_header *tbl; - - /* Skip NULL entries in RSDT/XSDT. */ - if (!ptr->val) - continue; -#if GRUB_CPU_SIZEOF_VOID_P != 8 - if (ptr->val >> 32) - continue; -#endif - tbl = (struct grub_acpi_table_header *) (grub_addr_t) ptr->val; - if (grub_memcmp (tbl->signature, sig, 4) == 0) - return tbl; - } - return 0; -} - -void * -grub_acpi_find_table (const char *sig) -{ - struct grub_acpi_fadt *r = NULL; - struct grub_acpi_rsdp_v10 *rsdpv1; - struct grub_acpi_rsdp_v20 *rsdpv2; - - rsdpv1 = grub_machine_acpi_get_rsdpv1 (); - if (rsdpv1) - r = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *) - (grub_addr_t) rsdpv1->rsdt_addr, - sig); - if (r) - return r; - rsdpv2 = grub_machine_acpi_get_rsdpv2 (); - if (rsdpv2 -#if GRUB_CPU_SIZEOF_VOID_P != 8 - && !(rsdpv2->xsdt_addr >> 32) -#endif - ) - r = grub_acpi_xsdt_find_table ((struct grub_acpi_table_header *) - (grub_addr_t) rsdpv2->xsdt_addr, - sig); - if (r) - return r; - if (rsdpv2) - r = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *) - (grub_addr_t) rsdpv2->rsdpv1.rsdt_addr, - sig); - if (r) - return r; - return 0; -} - -struct grub_acpi_fadt * -grub_acpi_find_fadt (void) -{ - return grub_acpi_find_table (GRUB_ACPI_FADT_SIGNATURE); -} diff --git a/grub-core/kern/arm/cache.S b/grub-core/kern/arm/cache.S deleted file mode 100644 index 354a069fe..000000000 --- a/grub-core/kern/arm/cache.S +++ /dev/null @@ -1,123 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - - .file "cache.S" - .text - .syntax unified -#if !defined (__thumb2__) || !defined (ARMV7) - .arm -#else - .thumb -#endif - -#if !defined (ARMV6) && !defined (ARMV7) -# error Unsupported architecture version! -#endif - - .align 2 - -/* - * Simple cache maintenance functions - */ - -@ r0 - *beg (inclusive) -@ r1 - *end (exclusive) -@void grub_arm_clean_dcache_range (grub_addr_t start, grub_addr_t end, grub_addr_t dlinesz) -#ifdef ARMV6 -FUNCTION(grub_arm_clean_dcache_range_armv6) -#else -FUNCTION(grub_arm_clean_dcache_range_armv7) -#endif - DSB - @ Clean data cache for range to point-of-unification -1: cmp r0, r1 - bge 2f -#ifdef ARMV6 - mcr p15, 0, r0, c7, c10, 1 @ Clean data cache line by MVA -#else - mcr p15, 0, r0, c7, c11, 1 @ DCCMVAU -#endif - add r0, r0, r2 @ Next line - b 1b -2: DSB - bx lr - -@ r0 - *beg (inclusive) -@ r1 - *end (exclusive) -#ifdef ARMV6 -FUNCTION(grub_arm_invalidate_icache_range_armv6) -#else -FUNCTION(grub_arm_invalidate_icache_range_armv7) -#endif - @ Invalidate instruction cache for range to point-of-unification -1: cmp r0, r1 - bge 2f - mcr p15, 0, r0, c7, c5, 1 @ ICIMVAU - add r0, r0, r2 @ Next line - b 1b - @ Branch predictor invalidate all -2: mcr p15, 0, r0, c7, c5, 6 @ BPIALL - DSB - ISB - bx lr - -#ifdef ARMV6 -FUNCTION(grub_arm_disable_caches_mmu_armv6) -#else -FUNCTION(grub_arm_disable_caches_mmu_armv7) -#endif - - push {r4, lr} - - @ disable D-cache - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #(1 << 2) - mcr p15, 0, r0, c1, c0, 0 - DSB - ISB - - @ clean/invalidate D-cache - bl clean_invalidate_dcache - - @ disable I-cache - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #(1 << 12) - mcr p15, 0, r0, c1, c0, 0 - DSB - ISB - - @ invalidate I-cache (also invalidates branch predictors) - mcr p15, 0, r0, c7, c5, 0 - DSB - ISB - - @ clear SCTLR M bit - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #(1 << 0) - mcr p15, 0, r0, c1, c0, 0 - - mcr p15, 0, r0, c8, c7, 0 @ invalidate TLB - mcr p15, 0, r0, c7, c5, 6 @ invalidate branch predictor - DSB - ISB - - pop {r4, lr} - bx lr - diff --git a/grub-core/kern/arm/cache.c b/grub-core/kern/arm/cache.c deleted file mode 100644 index 6c75193e4..000000000 --- a/grub-core/kern/arm/cache.c +++ /dev/null @@ -1,311 +0,0 @@ -#include -#include -#include -#ifdef GRUB_MACHINE_UBOOT -#include -#include -#include -#endif - -/* This is only about cache architecture. It doesn't imply - the CPU architecture. */ -static enum - { - ARCH_UNKNOWN, - ARCH_ARMV5_WRITE_THROUGH, - ARCH_ARMV6, - ARCH_ARMV6_UNIFIED, - ARCH_ARMV7 - } type = ARCH_UNKNOWN; - -static int is_v6_mmu; - -static grub_uint32_t grub_arch_cache_dlinesz; -static grub_uint32_t grub_arch_cache_ilinesz; -static grub_uint32_t grub_arch_cache_max_linesz; - -/* Prototypes for asm functions. */ -void grub_arm_clean_dcache_range_armv6 (grub_addr_t start, grub_addr_t end, - grub_addr_t dlinesz); -void grub_arm_clean_dcache_range_armv7 (grub_addr_t start, grub_addr_t end, - grub_addr_t dlinesz); -void grub_arm_clean_dcache_range_poc_armv7 (grub_addr_t start, grub_addr_t end, - grub_addr_t dlinesz); -void grub_arm_invalidate_icache_range_armv6 (grub_addr_t start, grub_addr_t end, - grub_addr_t dlinesz); -void grub_arm_invalidate_icache_range_armv7 (grub_addr_t start, grub_addr_t end, - grub_addr_t dlinesz); -void grub_arm_disable_caches_mmu_armv6 (void); -void grub_arm_disable_caches_mmu_armv7 (void); -grub_uint32_t grub_arm_main_id (void); -grub_uint32_t grub_arm_cache_type (void); - -static void -probe_caches (void) -{ - grub_uint32_t main_id, cache_type; - - /* Read main ID Register */ - main_id = grub_arm_main_id (); - - switch ((main_id >> 16) & 0xf) - { - case 0x3: - case 0x4: - case 0x5: - case 0x6: - is_v6_mmu = 0; - break; - case 0x7: - case 0xf: - is_v6_mmu = 1; - break; - default: - grub_fatal ("Unsupported ARM ID 0x%x", main_id); - } - - /* Read Cache Type Register */ - cache_type = grub_arm_cache_type (); - - switch (cache_type >> 24) - { - case 0x00: - case 0x01: - grub_arch_cache_dlinesz = 8 << ((cache_type >> 12) & 3); - grub_arch_cache_ilinesz = 8 << (cache_type & 3); - type = ARCH_ARMV5_WRITE_THROUGH; - break; - case 0x04: - case 0x0a: - case 0x0c: - case 0x0e: - case 0x1c: - grub_arch_cache_dlinesz = 8 << ((cache_type >> 12) & 3); - grub_arch_cache_ilinesz = 8 << (cache_type & 3); - type = ARCH_ARMV6_UNIFIED; - break; - case 0x05: - case 0x0b: - case 0x0d: - case 0x0f: - case 0x1d: - grub_arch_cache_dlinesz = 8 << ((cache_type >> 12) & 3); - grub_arch_cache_ilinesz = 8 << (cache_type & 3); - type = ARCH_ARMV6; - break; - default: - /* - * The CTR register is pretty much unchanged from v7 onwards, - * and is guaranteed to be backward compatible (the IDC/DIC bits - * allow certain CMOs to be elided, but performing them is never - * wrong), hence handling it like its AArch64 equivalent. - */ - grub_arch_cache_dlinesz = 4 << ((cache_type >> 16) & 0xf); - grub_arch_cache_ilinesz = 4 << (cache_type & 0xf); - type = ARCH_ARMV7; - } - if (grub_arch_cache_dlinesz > grub_arch_cache_ilinesz) - grub_arch_cache_max_linesz = grub_arch_cache_dlinesz; - else - grub_arch_cache_max_linesz = grub_arch_cache_ilinesz; -} - -#ifdef GRUB_MACHINE_UBOOT - -static void subdivide (grub_uint32_t *table, grub_uint32_t *subtable, - grub_uint32_t addr) -{ - grub_uint32_t j; - addr = addr >> 20 << 20; - table[addr >> 20] = (grub_addr_t) subtable | 1; - for (j = 0; j < 256; j++) - subtable[j] = addr | (j << 12) - | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 10) - | (0 << 3) | (1 << 2) | 2; -} - -void -grub_arm_enable_caches_mmu (void) -{ - grub_uint32_t *table; - grub_uint32_t i; - grub_uint32_t border_crossing = 0; - grub_uint32_t *subtable; - struct sys_info *si = grub_uboot_get_sys_info (); - - if (!si || (si->mr_no == 0)) - { - grub_printf ("couldn't get memory map, not enabling caches"); - grub_errno = GRUB_ERR_NONE; - return; - } - - if (type == ARCH_UNKNOWN) - probe_caches (); - - for (i = 0; (signed) i < si->mr_no; i++) - { - if (si->mr[i].start & ((1 << 20) - 1)) - border_crossing++; - if ((si->mr[i].start + si->mr[i].size) & ((1 << 20) - 1)) - border_crossing++; - } - - grub_printf ("%d crossers\n", border_crossing); - - table = grub_memalign (1 << 14, (1 << 14) + (border_crossing << 10)); - if (!table) - { - grub_printf ("couldn't allocate place for MMU table, not enabling caches"); - grub_errno = GRUB_ERR_NONE; - return; - } - - subtable = table + (1 << 12); - /* Map all unknown as device. */ - for (i = 0; i < (1 << 12); i++) - table[i] = (i << 20) | (3 << 10) | (0 << 3) | (1 << 2) | 2; - /* - Device: TEX= 0, C=0, B=1 - normal: TEX= 0, C=1, B=1 - AP = 3 - IMP = 0 - Domain = 0 -*/ - - for (i = 0; (signed) i < si->mr_no; i++) - { - if (si->mr[i].start & ((1 << 20) - 1)) - { - subdivide (table, subtable, si->mr[i].start); - subtable += (1 << 8); - } - if ((si->mr[i].start + si->mr[i].size) & ((1 << 20) - 1)) - { - subdivide (table, subtable, si->mr[i].start + si->mr[i].size); - subtable += (1 << 8); - } - } - - for (i = 0; (signed) i < si->mr_no; i++) - if ((si->mr[i].flags & MR_ATTR_MASK) == MR_ATTR_DRAM - || (si->mr[i].flags & MR_ATTR_MASK) == MR_ATTR_SRAM - || (si->mr[i].flags & MR_ATTR_MASK) == MR_ATTR_FLASH) - { - grub_uint32_t cur, end; - cur = si->mr[i].start; - end = si->mr[i].start + si->mr[i].size; - while (cur < end) - { - grub_uint32_t *st; - if ((table[cur >> 20] & 3) == 2) - { - cur = cur >> 20 << 20; - table[cur >> 20] = cur | (3 << 10) | (1 << 3) | (1 << 2) | 2; - cur += (1 << 20); - continue; - } - cur = cur >> 12 << 12; - st = (grub_uint32_t *) (table[cur >> 20] & ~0x3ff); - st[(cur >> 12) & 0xff] = cur | (3 << 4) | (3 << 6) - | (3 << 8) | (3 << 10) - | (1 << 3) | (1 << 2) | 2; - cur += (1 << 12); - } - } - - grub_printf ("MMU tables generated\n"); - if (is_v6_mmu) - grub_arm_clear_mmu_v6 (); - - grub_printf ("enabling MMU\n"); - grub_arm_enable_mmu (table); - grub_printf ("MMU enabled\n"); -} - -#endif - -void -grub_arch_sync_caches (void *address, grub_size_t len) -{ - grub_addr_t start = (grub_addr_t) address; - grub_addr_t end = start + len; - - if (type == ARCH_UNKNOWN) - probe_caches (); - start = ALIGN_DOWN (start, grub_arch_cache_max_linesz); - end = ALIGN_UP (end, grub_arch_cache_max_linesz); - switch (type) - { - case ARCH_ARMV6: - grub_arm_clean_dcache_range_armv6 (start, end, grub_arch_cache_dlinesz); - grub_arm_invalidate_icache_range_armv6 (start, end, - grub_arch_cache_ilinesz); - break; - case ARCH_ARMV7: - grub_arm_clean_dcache_range_armv7 (start, end, grub_arch_cache_dlinesz); - grub_arm_invalidate_icache_range_armv7 (start, end, - grub_arch_cache_ilinesz); - break; - /* Nothing to do. */ - case ARCH_ARMV5_WRITE_THROUGH: - case ARCH_ARMV6_UNIFIED: - break; - /* Pacify GCC. */ - case ARCH_UNKNOWN: - break; - } -} - -void -grub_arch_sync_dma_caches (volatile void *address, grub_size_t len) -{ - grub_addr_t start = (grub_addr_t) address; - grub_addr_t end = start + len; - - if (type == ARCH_UNKNOWN) - probe_caches (); - start = ALIGN_DOWN (start, grub_arch_cache_max_linesz); - end = ALIGN_UP (end, grub_arch_cache_max_linesz); - switch (type) - { - case ARCH_ARMV6: - grub_arm_clean_dcache_range_armv6 (start, end, grub_arch_cache_dlinesz); - grub_arm_invalidate_icache_range_armv6 (start, end, - grub_arch_cache_ilinesz); - break; - case ARCH_ARMV5_WRITE_THROUGH: - case ARCH_ARMV6_UNIFIED: - grub_arm_clean_dcache_range_armv6 (start, end, grub_arch_cache_dlinesz); - break; - case ARCH_ARMV7: - grub_arm_clean_dcache_range_poc_armv7 (start, end, grub_arch_cache_dlinesz); - grub_arm_invalidate_icache_range_armv7 (start, end, - grub_arch_cache_ilinesz); - break; - /* Pacify GCC. */ - case ARCH_UNKNOWN: - break; - } -} - -void -grub_arm_disable_caches_mmu (void) -{ - if (type == ARCH_UNKNOWN) - probe_caches (); - switch (type) - { - case ARCH_ARMV5_WRITE_THROUGH: - case ARCH_ARMV6_UNIFIED: - case ARCH_ARMV6: - grub_arm_disable_caches_mmu_armv6 (); - break; - case ARCH_ARMV7: - grub_arm_disable_caches_mmu_armv7 (); - break; - /* Pacify GCC. */ - case ARCH_UNKNOWN: - break; - } -} diff --git a/grub-core/kern/arm/cache_armv6.S b/grub-core/kern/arm/cache_armv6.S deleted file mode 100644 index dfaded0eb..000000000 --- a/grub-core/kern/arm/cache_armv6.S +++ /dev/null @@ -1,72 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - - .file "cache_armv6.S" - .text - .syntax unified - .arm - -# define DMB mcr p15, 0, r0, c7, c10, 5 -# define DSB mcr p15, 0, r0, c7, c10, 4 -# define ISB mcr p15, 0, r0, c7, c5, 4 -#define ARMV6 1 - -clean_invalidate_dcache: - mcr p15, 0, r0, c7, c14, 0 @ Clean/Invalidate D-cache - bx lr - -#include "cache.S" - -FUNCTION(grub_arm_main_id) - mrc p15, 0, r0, c0, c0, 0 - bx lr - -FUNCTION(grub_arm_cache_type) - mrc p15, 0, r0, c0, c0, 1 - bx lr - -FUNCTION(grub_arm_clear_mmu_v6) - mov r0, #0 - mcr p15, 0, r0, c2, c0, 2 - bx lr - -FUNCTION(grub_arm_enable_mmu) - mcr p15, 0, r0, c2, c0, 0 - - mvn r0, #0 - mcr p15, 0, r0, c3, c0, 0 - - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #(1 << 23) - mcr p15, 0, r0, c1, c0, 0 - - mrc p15, 0, r0, c1, c0, 0 - orr r0, r0, #(1 << 0) - mcr p15, 0, r0, c1, c0, 0 - - mrc p15, 0, r0, c1, c0, 0 - orr r0, r0, #(1 << 2) - mcr p15, 0, r0, c1, c0, 0 - - mrc p15, 0, r0, c1, c0, 0 - orr r0, r0, #(1 << 12) - mcr p15, 0, r0, c1, c0, 0 - - bx lr diff --git a/grub-core/kern/arm/cache_armv7.S b/grub-core/kern/arm/cache_armv7.S deleted file mode 100644 index 5ae76a3d8..000000000 --- a/grub-core/kern/arm/cache_armv7.S +++ /dev/null @@ -1,138 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - - .file "cache_armv7.S" - .text - .syntax unified -#if !defined (__thumb2__) - .arch armv7a - .arm -#else - .arch armv7 - .thumb -#endif -# define DMB dmb -# define DSB dsb -# define ISB isb -#define ARMV7 1 - -FUNCTION(grub_arm_clean_dcache_range_poc_armv7) - DSB - @ Clean data cache for range to point-of-coherence -1: cmp r0, r1 - bge 2f - mcr p15, 0, r0, c7, c14, 1 @ DCCMVAC - add r0, r0, r2 @ Next line - b 1b -2: DSB - bx lr - - - @ r0 - CLIDR - @ r1 - LoC - @ r2 - current level - @ r3 - num sets - @ r4 - num ways - @ r5 - current set - @ r6 - current way - @ r7 - line size - @ r8 - scratch - @ r9 - scratch - @ r10 - scratch - @ r11 - scratch -clean_invalidate_dcache: - push {r4-r12, lr} - mrc p15, 1, r0, c0, c0, 1 @ Read CLIDR - lsr r1, r0, #24 @ Extract LoC - and r1, r1, #0x7 - - mov r2, #0 @ First level, L1 -2: and r8, r0, #7 @ cache type at current level - cmp r8, #2 - blt 5f @ instruction only, or none, skip level - - @ set current cache level/type (for CCSIDR read) - lsl r8, r2, #1 - mcr p15, 2, r8, c0, c0, 0 @ Write CSSELR (level, type: data/uni) - - @ read current cache information - mrc p15, 1, r8, c0, c0, 0 @ Read CCSIDR - lsr r3, r8, #13 @ Number of sets -1 - - @ Keep only 14 bits of r3 - lsl r3, r3, #18 - lsr r3, r3, #18 - - lsr r4, r8, #3 @ Number of ways -1 - - @ Keep only 9 bits of r4 - lsl r4, r4, #23 - lsr r4, r4, #23 - - and r7, r8, #7 @ log2(line size in words) - 2 - add r7, r7, #2 @ adjust - mov r8, #1 - lsl r7, r8, r7 @ -> line size in words - lsl r7, r7, #2 @ -> bytes - - @ set loop - mov r5, #0 @ current set = 0 -3: lsl r8, r2, #1 @ insert level - clz r9, r7 @ calculate set field offset - mov r10, #31 - sub r9, r10, r9 - lsl r10, r5, r9 - orr r8, r8, r10 @ insert set field - - @ way loop - @ calculate way field offset - mov r6, #0 @ current way = 0 - add r10, r4, #1 - clz r9, r10 @ r9 = way field offset - add r9, r9, #1 -4: lsl r10, r6, r9 - orr r11, r8, r10 @ insert way field - - @ clean and invalidate line by set/way - mcr p15, 0, r11, c7, c14, 2 @ DCCISW - - @ next way - add r6, r6, #1 - cmp r6, r4 - ble 4b - - @ next set - add r5, r5, #1 - cmp r5, r3 - ble 3b - - @ next level -5: lsr r0, r0, #3 @ align next level CLIDR 'type' field - add r2, r2, #1 @ increment cache level counter - cmp r2, r1 - blt 2b @ outer loop - - @ return -6: DSB - ISB - pop {r4-r12, lr} - bx lr - -#include "cache.S" \ No newline at end of file diff --git a/grub-core/kern/arm/compiler-rt.S b/grub-core/kern/arm/compiler-rt.S deleted file mode 100644 index 645b42f50..000000000 --- a/grub-core/kern/arm/compiler-rt.S +++ /dev/null @@ -1,86 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - - .file "misc.S" - .text - .syntax unified -#if !defined (__thumb2__) - .arm -#else - .thumb -#endif - - .align 2 - -FUNCTION(__muldi3) -FUNCTION(__aeabi_lmul) - stmfd sp!, {r4, fp} - add fp, sp, #4 - sub sp, sp, #16 - str r0, [fp, #-12] - str r1, [fp, #-8] - str r2, [fp, #-20] - str r3, [fp, #-16] - ldr r3, [fp, #-8] - ldr r2, [fp, #-20] - mul r2, r3, r2 - ldr r3, [fp, #-16] - ldr r1, [fp, #-12] - mul r3, r1, r3 - add r2, r2, r3 - ldr r0, [fp, #-12] - ldr r1, [fp, #-20] - umull r3, r4, r0, r1 - add r2, r2, r4 - mov r4, r2 - mov r0, r3 - mov r1, r4 - mov sp, fp - sub sp, sp, #4 - ldmfd sp!, {r4, fp} - bx lr - - .macro division32 parent - - sub sp, sp, #8 @ Allocate naturally aligned 64-bit space - stmfd sp!, {r3,lr} @ Dummy r3 to maintain stack alignment - add r2, sp, #8 @ Set r2 to address of 64-bit space - bl \parent - ldr r1, [sp, #8] @ Extract remainder - ldmfd sp!, {r3,lr} @ Pop into an unused arg/scratch register - add sp, sp, #8 - bx lr - .endm - -FUNCTION(__aeabi_uidivmod) - division32 grub_divmod32 -FUNCTION(__aeabi_idivmod) - division32 grub_divmod32s - -/* - * Null divide-by-zero handler - */ -FUNCTION(__aeabi_unwind_cpp_pr0) -FUNCTION(raise) - mov r0, #0 - bx lr - - END diff --git a/grub-core/kern/arm/coreboot/cbtable.c b/grub-core/kern/arm/coreboot/cbtable.c deleted file mode 100644 index 8a655bb5c..000000000 --- a/grub-core/kern/arm/coreboot/cbtable.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007,2008,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#pragma GCC diagnostic ignored "-Wcast-align" - -grub_linuxbios_table_header_t -grub_linuxbios_get_tables (void) -{ - grub_linuxbios_table_header_t table_header - = (grub_linuxbios_table_header_t) grub_arm_saved_registers.r[0]; - - if (!grub_linuxbios_check_signature (table_header)) - return 0; - - return table_header; -} diff --git a/grub-core/kern/arm/coreboot/dma.c b/grub-core/kern/arm/coreboot/dma.c deleted file mode 100644 index 2c2a62789..000000000 --- a/grub-core/kern/arm/coreboot/dma.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include - -struct grub_pci_dma_chunk * -grub_memalign_dma32 (grub_size_t align, grub_size_t size) -{ - void *ret; - if (align < 64) - align = 64; - size = ALIGN_UP (size, align); - ret = grub_memalign (align, size); - if (!ret) - return 0; - grub_arch_sync_dma_caches (ret, size); - return ret; -} - -void -grub_dma_free (struct grub_pci_dma_chunk *ch) -{ - grub_size_t size = (((struct grub_mm_header *) ch) - 1)->size * GRUB_MM_ALIGN; - grub_arch_sync_dma_caches (ch, size); - grub_free (ch); -} - -volatile void * -grub_dma_get_virt (struct grub_pci_dma_chunk *ch) -{ - return (void *) ch; -} - -grub_uint32_t -grub_dma_get_phys (struct grub_pci_dma_chunk *ch) -{ - return (grub_uint32_t) (grub_addr_t) ch; -} - diff --git a/grub-core/kern/arm/coreboot/init.c b/grub-core/kern/arm/coreboot/init.c deleted file mode 100644 index 8d8c5b829..000000000 --- a/grub-core/kern/arm/coreboot/init.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern grub_uint8_t _start[]; -extern grub_uint8_t _end[]; -extern grub_uint8_t _edata[]; -grub_addr_t start_of_ram = ~(grub_addr_t)0; - -void __attribute__ ((noreturn)) -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 (); -} - -static grub_uint64_t modend; -static int have_memory = 0; - -/* Helper for grub_machine_init. */ -static int -heap_init (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, - void *data __attribute__ ((unused))) -{ - grub_uint64_t begin = addr, end = addr + size; - -#if GRUB_CPU_SIZEOF_VOID_P == 4 - /* Restrict ourselves to 32-bit memory space. */ - if (begin > GRUB_ULONG_MAX) - return 0; - if (end > GRUB_ULONG_MAX) - end = GRUB_ULONG_MAX; -#endif - - if (start_of_ram > begin) - start_of_ram = begin; - - if (type != GRUB_MEMORY_AVAILABLE) - return 0; - - if (modend && begin < modend) - { - if (begin < (grub_addr_t)_start) - { - grub_mm_init_region ((void *) (grub_addr_t) begin, (grub_size_t) ((grub_addr_t)_start - begin)); - have_memory = 1; - } - begin = modend; - } - - /* Avoid DMA problems. */ - if (end >= 0xfe000000) - end = 0xfe000000; - - if (end <= begin) - return 0; - - grub_mm_init_region ((void *) (grub_addr_t) begin, (grub_size_t) (end - begin)); - - have_memory = 1; - - return 0; -} - -void -grub_machine_init (void) -{ - struct grub_module_header *header; - void *dtb = 0; - grub_size_t dtb_size = 0; - - modend = grub_modules_get_end (); - - grub_video_coreboot_fb_early_init (); - - grub_machine_mmap_iterate (heap_init, NULL); - if (!have_memory) - grub_fatal ("No memory found"); - - grub_video_coreboot_fb_late_init (); - - grub_font_init (); - grub_gfxterm_init (); - - FOR_MODULES (header) - if (header->type == OBJ_TYPE_DTB) - { - char *dtb_orig_addr, *dtb_copy; - dtb_orig_addr = (char *) header + sizeof (struct grub_module_header); - - dtb_size = header->size - sizeof (struct grub_module_header); - dtb = dtb_copy = grub_malloc (dtb_size); - grub_memmove (dtb_copy, dtb_orig_addr, dtb_size); - break; - } - if (!dtb) - grub_fatal ("No DTB found"); - grub_fdtbus_init (dtb, dtb_size); - - grub_rk3288_spi_init (); - - grub_machine_timer_init (); - grub_cros_init (); - grub_pl050_init (); -} - -void -grub_machine_get_bootlocation (char **device __attribute__ ((unused)), - char **path __attribute__ ((unused))) -{ -} - -void -grub_machine_fini (int flags __attribute__ ((unused))) -{ -} diff --git a/grub-core/kern/arm/coreboot/timer.c b/grub-core/kern/arm/coreboot/timer.c deleted file mode 100644 index d97b844f8..000000000 --- a/grub-core/kern/arm/coreboot/timer.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2016 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -grub_uint64_t -grub_armv7_get_timer_value(void); - -grub_uint32_t -grub_armv7_get_timer_frequency(void); - -grub_uint32_t -grub_arm_pfr1(void); - -static int have_timer = 0; -static volatile grub_uint32_t *sp804_regs; - -static grub_uint64_t -sp804_get_time_ms (void) -{ - static grub_uint32_t high, last_low; - grub_uint32_t low = ~sp804_regs[1]; - if (last_low > low) - high++; - last_low = low; - return grub_divmod64 ((((grub_uint64_t) high) << 32) | low, - 1000, 0); -} - -static grub_err_t -sp804_attach(const struct grub_fdtbus_dev *dev) -{ - if (have_timer) - return GRUB_ERR_NONE; - sp804_regs = grub_fdtbus_map_reg (dev, 0, 0); - if (!grub_fdtbus_is_mapping_valid (sp804_regs)) - return grub_error (GRUB_ERR_IO, "could not map sp804: %p", sp804_regs); - grub_install_get_time_ms (sp804_get_time_ms); - have_timer = 1; - return GRUB_ERR_NONE; -} - -struct grub_fdtbus_driver sp804 = -{ - .compatible = "arm,sp804", - .attach = sp804_attach -}; - -static grub_uint32_t timer_frequency_in_khz; - -static grub_uint64_t -generic_get_time_ms (void) -{ - return grub_divmod64 (grub_armv7_get_timer_value(), timer_frequency_in_khz, 0); -} - -static int -try_generic_timer (void) -{ - if (((grub_arm_pfr1 () >> 16) & 0xf) != 1) - return 0; - grub_printf ("freq = %x\n", grub_armv7_get_timer_frequency()); - timer_frequency_in_khz = 0x016e3600 / 1000; //grub_armv7_get_timer_frequency() / 1000; - if (timer_frequency_in_khz == 0) - return 0; - grub_install_get_time_ms (generic_get_time_ms); - have_timer = 1; - return 1; -} - -void -grub_machine_timer_init (void) -{ - grub_fdtbus_register (&sp804); - - if (!have_timer) - try_generic_timer (); - if (!have_timer) - grub_fatal ("No timer found"); -} diff --git a/grub-core/kern/arm/dl.c b/grub-core/kern/arm/dl.c deleted file mode 100644 index eab9d17ff..000000000 --- a/grub-core/kern/arm/dl.c +++ /dev/null @@ -1,280 +0,0 @@ -/* dl.c - arch-dependent part of loadable module support */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -struct trampoline_arm -{ -#define ARM_LOAD_IP 0xe59fc000 -#define ARM_BX 0xe12fff1c -#define ARM_MOV_PC 0xe1a0f00c - grub_uint32_t load_ip; /* ldr ip, [pc] */ - grub_uint32_t bx; /* bx ip or mov pc, ip*/ - grub_uint32_t addr; -}; - -static grub_uint16_t thumb_template[8] = - { - 0x468c, /* mov ip, r1 */ - 0x4903, /* ldr r1, [pc, #12] ; (10 <.text+0x10>) */ - /* Exchange R1 and IP in limited Thumb instruction set. - IP gets negated but we compensate it by C code. */ - /* R1 IP */ - /* -A R1 */ - 0x4461, /* add r1, ip */ /* R1-A R1 */ - 0x4249, /* negs r1, r1 */ /* A-R1 R1 */ - 0x448c, /* add ip, r1 */ /* A-R1 A */ - 0x4249, /* negs r1, r1 */ /* R1-A A */ - 0x4461, /* add r1, ip */ /* R1 A */ - 0x4760 /* bx ip */ - }; - -struct trampoline_thumb -{ - grub_uint16_t template[8]; - grub_uint32_t neg_addr; -}; - -#pragma GCC diagnostic ignored "-Wcast-align" - -grub_err_t -grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, - grub_size_t *got) -{ - const Elf_Ehdr *e = ehdr; - const Elf_Shdr *s; - unsigned i; - - *tramp = 0; - *got = 0; - - for (i = 0, s = (const Elf_Shdr *) ((grub_addr_t) e + e->e_shoff); - i < e->e_shnum; - i++, s = (const Elf_Shdr *) ((grub_addr_t) s + e->e_shentsize)) - if (s->sh_type == SHT_REL) - { - const Elf_Rel *rel, *max; - - for (rel = (const Elf_Rel *) ((grub_addr_t) e + s->sh_offset), - max = (const Elf_Rel *) ((grub_addr_t) rel + s->sh_size); - rel + 1 <= max; - rel = (const Elf_Rel *) ((grub_addr_t) rel + s->sh_entsize)) - switch (ELF_R_TYPE (rel->r_info)) - { - case R_ARM_CALL: - case R_ARM_JUMP24: - { - *tramp += sizeof (struct trampoline_arm); - break; - } - case R_ARM_THM_CALL: - case R_ARM_THM_JUMP24: - case R_ARM_THM_JUMP19: - { - *tramp += sizeof (struct trampoline_thumb); - break; - } - } - } - - grub_dprintf ("dl", "trampoline size %x\n", *tramp); - - return GRUB_ERR_NONE; -} - -/************************************************* - * Runtime dynamic linker with helper functions. * - *************************************************/ -grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - Elf_Shdr *s, grub_dl_segment_t seg) -{ - Elf_Rel *rel, *max; - - for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset), - max = (Elf_Rel *) ((char *) rel + s->sh_size); - rel < max; - rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) - { - Elf_Addr *target, sym_addr; - grub_err_t retval; - Elf_Sym *sym; - - if (seg->size < rel->r_offset) - return grub_error (GRUB_ERR_BAD_MODULE, - "reloc offset is out of the segment"); - target = (void *) ((char *) seg->addr + rel->r_offset); - sym = (Elf_Sym *) ((char *) mod->symtab - + mod->symsize * ELF_R_SYM (rel->r_info)); - - sym_addr = sym->st_value; - - switch (ELF_R_TYPE (rel->r_info)) - { - case R_ARM_ABS32: - { - /* Data will be naturally aligned */ - retval = grub_arm_reloc_abs32 (target, sym_addr); - if (retval != GRUB_ERR_NONE) - return retval; - } - break; - case R_ARM_CALL: - case R_ARM_JUMP24: - { - grub_int32_t offset; - - sym_addr += grub_arm_jump24_get_offset (target); - offset = sym_addr - (grub_uint32_t) target; - - if ((sym_addr & 1) || !grub_arm_jump24_check_offset (offset)) - { - struct trampoline_arm *tp = mod->trampptr; - mod->trampptr = tp + 1; - tp->load_ip = ARM_LOAD_IP; - tp->bx = (sym_addr & 1) ? ARM_BX : ARM_MOV_PC; - tp->addr = sym_addr + 8; - offset = (grub_uint8_t *) tp - (grub_uint8_t *) target - 8; - } - if (!grub_arm_jump24_check_offset (offset)) - return grub_error (GRUB_ERR_BAD_MODULE, - "trampoline out of range"); - grub_arm_jump24_set_offset (target, offset); - } - break; - case R_ARM_THM_CALL: - case R_ARM_THM_JUMP24: - { - /* Thumb instructions can be 16-bit aligned */ - grub_int32_t offset; - - sym_addr += grub_arm_thm_call_get_offset ((grub_uint16_t *) target); - - grub_dprintf ("dl", " sym_addr = 0x%08x\n", sym_addr); - if (ELF_ST_TYPE (sym->st_info) != STT_FUNC) - sym_addr |= 1; - - offset = sym_addr - (grub_uint32_t) target; - - grub_dprintf("dl", " BL*: target=%p, sym_addr=0x%08x, offset=%d\n", - target, sym_addr, offset); - - if (!(sym_addr & 1) || (offset < -0x200000 || offset >= 0x200000)) - { - struct trampoline_thumb *tp = mod->trampptr; - mod->trampptr = tp + 1; - grub_memcpy (tp->template, thumb_template, sizeof (tp->template)); - tp->neg_addr = -sym_addr - 4; - offset = ((grub_uint8_t *) tp - (grub_uint8_t *) target - 4) | 1; - } - - if (offset < -0x200000 || offset >= 0x200000) - return grub_error (GRUB_ERR_BAD_MODULE, - "trampoline out of range"); - - grub_dprintf ("dl", " relative destination = %p\n", - (char *) target + offset); - - retval = grub_arm_thm_call_set_offset ((grub_uint16_t *) target, offset); - if (retval != GRUB_ERR_NONE) - return retval; - } - break; - /* Happens when compiled with -march=armv4. Since currently we need - at least armv5, keep bx as-is. - */ - case R_ARM_V4BX: - break; - case R_ARM_THM_MOVW_ABS_NC: - case R_ARM_THM_MOVT_ABS: - { - grub_uint32_t offset; - offset = grub_arm_thm_movw_movt_get_value((grub_uint16_t *) target); - offset += sym_addr; - - if (ELF_R_TYPE (rel->r_info) == R_ARM_THM_MOVT_ABS) - offset >>= 16; - else - offset &= 0xffff; - - grub_arm_thm_movw_movt_set_value((grub_uint16_t *) target, offset); - } - break; - case R_ARM_THM_JUMP19: - { - /* Thumb instructions can be 16-bit aligned */ - grub_int32_t offset; - - sym_addr += grub_arm_thm_jump19_get_offset ((grub_uint16_t *) target); - - if (ELF_ST_TYPE (sym->st_info) != STT_FUNC) - sym_addr |= 1; - - offset = sym_addr - (grub_uint32_t) target; - - if (!grub_arm_thm_jump19_check_offset (offset) - || !(sym_addr & 1)) - { - struct trampoline_thumb *tp = mod->trampptr; - mod->trampptr = tp + 1; - grub_memcpy (tp->template, thumb_template, sizeof (tp->template)); - tp->neg_addr = -sym_addr - 4; - offset = ((grub_uint8_t *) tp - (grub_uint8_t *) target - 4) | 1; - } - - if (!grub_arm_thm_jump19_check_offset (offset)) - return grub_error (GRUB_ERR_BAD_MODULE, - "trampoline out of range"); - - grub_arm_thm_jump19_set_offset ((grub_uint16_t *) target, offset); - } - break; - default: - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - ELF_R_TYPE (rel->r_info)); - } - } - - return GRUB_ERR_NONE; -} - - -/* - * 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_ARM) - return grub_error (GRUB_ERR_BAD_OS, - N_("invalid arch-dependent ELF magic")); - - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/arm/dl_helper.c b/grub-core/kern/arm/dl_helper.c deleted file mode 100644 index 21d77f763..000000000 --- a/grub-core/kern/arm/dl_helper.c +++ /dev/null @@ -1,245 +0,0 @@ -/* dl.c - arch-dependent part of loadable module support */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -static inline grub_uint32_t -thumb_get_instruction_word (grub_uint16_t *target) -{ - /* Extract instruction word in alignment-safe manner */ - return grub_le_to_cpu16 ((*target)) << 16 | grub_le_to_cpu16 (*(target + 1)); -} - -static inline void -thumb_set_instruction_word (grub_uint16_t *target, grub_uint32_t insword) -{ - *target = grub_cpu_to_le16 (insword >> 16); - *(target + 1) = grub_cpu_to_le16 (insword & 0xffff); -} - -/* - * R_ARM_ABS32 - * - * Simple relocation of 32-bit value (in literal pool) - */ -grub_err_t -grub_arm_reloc_abs32 (Elf32_Word *target, Elf32_Addr sym_addr) -{ - Elf32_Addr tmp; - - tmp = grub_le_to_cpu32 (*target); - tmp += sym_addr; - *target = grub_cpu_to_le32 (tmp); - - return GRUB_ERR_NONE; -} - -/******************************************************************** - * Thumb (T32) relocations: * - * * - * 32-bit Thumb instructions can be 16-bit aligned, and are fetched * - * little-endian, requiring some additional fiddling. * - ********************************************************************/ - -grub_int32_t -grub_arm_thm_call_get_offset (grub_uint16_t *target) -{ - grub_uint32_t sign, j1, j2; - grub_uint32_t insword; - grub_int32_t offset; - - insword = thumb_get_instruction_word (target); - - /* Extract bitfields from instruction words */ - sign = (insword >> 26) & 1; - j1 = (insword >> 13) & 1; - j2 = (insword >> 11) & 1; - offset = (sign << 24) | ((~(j1 ^ sign) & 1) << 23) | - ((~(j2 ^ sign) & 1) << 22) | - ((insword & 0x03ff0000) >> 4) | ((insword & 0x000007ff) << 1); - - /* Sign adjust and calculate offset */ - if (offset & (1 << 24)) - offset -= (1 << 25); - - return offset; -} - -grub_err_t -grub_arm_thm_call_set_offset (grub_uint16_t *target, grub_int32_t offset) -{ - grub_uint32_t sign, j1, j2; - const grub_uint32_t insmask = 0xf800d000; - grub_uint32_t insword; - int is_blx; - - insword = thumb_get_instruction_word (target); - - if (((insword >> 12) & 0xd) == 0xc) - is_blx = 1; - else - is_blx = 0; - - if (!is_blx && !(offset & 1)) - return grub_error (GRUB_ERR_BAD_MODULE, "bl/b.w targettting ARM"); - - /* Transform blx into bl if necessarry. */ - if (is_blx && (offset & 1)) - insword |= (1 << 12); - - /* Reassemble instruction word */ - sign = (offset >> 24) & 1; - j1 = sign ^ (~(offset >> 23) & 1); - j2 = sign ^ (~(offset >> 22) & 1); - insword = (insword & insmask) | - (sign << 26) | - (((offset >> 12) & 0x03ff) << 16) | - (j1 << 13) | (j2 << 11) | ((offset >> 1) & 0x07ff); - - thumb_set_instruction_word (target, insword); - - grub_dprintf ("dl", " *insword = 0x%08x", insword); - - return GRUB_ERR_NONE; -} - -grub_int32_t -grub_arm_thm_jump19_get_offset (grub_uint16_t *target) -{ - grub_int32_t offset; - grub_uint32_t insword; - - insword = thumb_get_instruction_word (target); - - /* Extract and sign extend offset */ - offset = ((insword >> 26) & 1) << 19 - | ((insword >> 11) & 1) << 18 - | ((insword >> 13) & 1) << 17 - | ((insword >> 16) & 0x3f) << 11 - | (insword & 0x7ff); - offset <<= 1; - if (offset & (1 << 20)) - offset -= (1 << 21); - - return offset; -} - -void -grub_arm_thm_jump19_set_offset (grub_uint16_t *target, grub_int32_t offset) -{ - grub_uint32_t insword; - const grub_uint32_t insmask = 0xfbc0d000; - - offset >>= 1; - offset &= 0xfffff; - - insword = thumb_get_instruction_word (target); - - /* Reassemble instruction word and write back */ - insword &= insmask; - insword |= ((offset >> 19) & 1) << 26 - | ((offset >> 18) & 1) << 11 - | ((offset >> 17) & 1) << 13 - | ((offset >> 11) & 0x3f) << 16 - | (offset & 0x7ff); - thumb_set_instruction_word (target, insword); -} - -int -grub_arm_thm_jump19_check_offset (grub_int32_t offset) -{ - if ((offset > 1048574) || (offset < -1048576)) - return 0; - return 1; -} - -grub_uint16_t -grub_arm_thm_movw_movt_get_value (grub_uint16_t *target) -{ - grub_uint32_t insword; - - insword = thumb_get_instruction_word (target); - - return ((insword & 0xf0000) >> 4) | ((insword & 0x04000000) >> 15) | \ - ((insword & 0x7000) >> 4) | (insword & 0xff); -} - -void -grub_arm_thm_movw_movt_set_value (grub_uint16_t *target, grub_uint16_t value) -{ - grub_uint32_t insword; - const grub_uint32_t insmask = 0xfbf08f00; - - insword = thumb_get_instruction_word (target); - insword &= insmask; - - insword |= ((value & 0xf000) << 4) | ((value & 0x0800) << 15) | \ - ((value & 0x0700) << 4) | (value & 0xff); - - thumb_set_instruction_word (target, insword); -} - - -/*********************************************************** - * ARM (A32) relocations: * - * * - * ARM instructions are 32-bit in size and 32-bit aligned. * - ***********************************************************/ - -grub_int32_t -grub_arm_jump24_get_offset (grub_uint32_t *target) -{ - grub_int32_t offset; - grub_uint32_t insword; - - insword = grub_le_to_cpu32 (*target); - - offset = (insword & 0x00ffffff) << 2; - if (offset & 0x02000000) - offset -= 0x04000000; - return offset; -} - -int -grub_arm_jump24_check_offset (grub_int32_t offset) -{ - if (offset >= 0x02000000 || offset < -0x02000000) - return 0; - return 1; -} - -void -grub_arm_jump24_set_offset (grub_uint32_t *target, - grub_int32_t offset) -{ - grub_uint32_t insword; - - insword = grub_le_to_cpu32 (*target); - - insword &= 0xff000000; - insword |= (offset >> 2) & 0x00ffffff; - - *target = grub_cpu_to_le32 (insword); -} diff --git a/grub-core/kern/arm/efi/init.c b/grub-core/kern/arm/efi/init.c deleted file mode 100644 index 809f69c8c..000000000 --- a/grub-core/kern/arm/efi/init.c +++ /dev/null @@ -1,77 +0,0 @@ -/* init.c - initialize an arm-based EFI system */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -static grub_uint64_t tmr; -static grub_efi_event_t tmr_evt; - -static grub_uint64_t -grub_efi_get_time_ms (void) -{ - return tmr; -} - -static void __grub_efi_api -increment_timer (grub_efi_event_t event __attribute__ ((unused)), - void *context __attribute__ ((unused))) -{ - tmr += 10; -} - -void -grub_machine_init (void) -{ - grub_efi_boot_services_t *b; - - grub_efi_init (); - - b = grub_efi_system_table->boot_services; - - b->create_event (GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL, - GRUB_EFI_TPL_CALLBACK, increment_timer, NULL, &tmr_evt); - b->set_timer (tmr_evt, GRUB_EFI_TIMER_PERIODIC, 100000); - - grub_install_get_time_ms (grub_efi_get_time_ms); -} - -void -grub_machine_fini (int flags) -{ - grub_efi_boot_services_t *b; - - if (!(flags & GRUB_LOADER_FLAG_NORETURN)) - return; - - b = grub_efi_system_table->boot_services; - - b->set_timer (tmr_evt, GRUB_EFI_TIMER_CANCEL, 0); - b->close_event (tmr_evt); - - grub_efi_fini (); - - if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) - grub_efi_memory_fini (); -} diff --git a/grub-core/kern/arm/efi/startup.S b/grub-core/kern/arm/efi/startup.S deleted file mode 100644 index 9f8265315..000000000 --- a/grub-core/kern/arm/efi/startup.S +++ /dev/null @@ -1,36 +0,0 @@ -/* - * (C) Copyright 2013 Free Software Foundation - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - */ - -#include - - .file "startup.S" - .text - .arm -FUNCTION(_start) - /* - * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in r1/r0. - */ - ldr ip, =EXT_C(grub_efi_image_handle) - str r0, [ip] - ldr ip, =EXT_C(grub_efi_system_table) - str r1, [ip] - ldr ip, =EXT_C(grub_main) - bx ip - END diff --git a/grub-core/kern/arm/startup.S b/grub-core/kern/arm/startup.S deleted file mode 100644 index 3946fe8e1..000000000 --- a/grub-core/kern/arm/startup.S +++ /dev/null @@ -1,177 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -/* - * GRUB is called from U-Boot as a Linux Kernel type image, which - * means among other things that it always enters in ARM state. - * - * coreboot starts in ARM mode as well. - * - * Overview of GRUB image layout: - * - * _start: - * Entry point (1 ARM branch instruction, to "codestart") - * grub_total_module_size: - * Data field: Size of included module blob - * (when generated by grub-mkimage) - * codestart: - * Remainder of statically-linked executable code and data. - * __bss_start: - * Start of included module blob. - * Also where global/static variables are located. - * _end: - * End of bss region (but not necessarily module blob). - * : - * : - * Loadable modules, post relocation. - * : - */ - - .text - .arm -FUNCTION(_start) - b codestart - - @ Size of final image integrated module blob - set by grub-mkimage - .org _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE -VARIABLE(grub_total_module_size) - .long 0 - -VARIABLE(grub_modbase) - .long 0 -bss_start_ptr: - .long EXT_C(__bss_start) -end_ptr: - .long EXT_C(_end) - - @ Memory map at start: - @ * text+data - @ * list relocations - @ * modules - @ Before we enter C, we need to apply the relocations - @ and get following map: - @ * text+data - @ * BSS (cleared) - @ * stack - @ * modules - @ - @ To make things easier we ensure - @ that BSS+stack is larger than list of relocations - @ by increasing stack if necessarry. - @ This allows us to always unconditionally copy backwards - @ Currently list of relocations is ~5K and stack is set - @ to be at least 256K - -FUNCTION(codestart) - @ Store context: Machine ID, atags/dtb, ... - @ U-Boot API signature is stored on the U-Boot heap - @ Stack pointer used as start address for signature probing - mov r12, sp - adr sp, entry_state - push {r0-r12,lr} @ store U-Boot context (sp in r12) - - adr r1, _start - ldr r0, bss_start_ptr @ src - add r0, r0, r1 - - add r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1) - mvn r2, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1) - and r0, r0, r2 -1: - ldr r3, [r0], #4 @load next offset - @ both -2 and -1 are treated the same as we have only one type of relocs - @ -2 means "end of this type of relocs" and -1 means "end of all relocs" - add r2, r3, #2 - cmp r2, #1 - bls reloc_done - @ Adjust next offset - ldr r2, [r3, r1] - add r2, r2, r1 - str r2, [r3, r1] - b 1b - -reloc_done: - - @ Modules have been stored as a blob - @ they need to be manually relocated to _end - add r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1) - mvn r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1) - and r0, r0, r1 @ src = aligned end of relocations - - ldr r1, end_ptr @ dst = End of BSS - ldr r2, grub_total_module_size @ blob size - - add r1, r1, #GRUB_KERNEL_MACHINE_STACK_SIZE - and r1, r1, #~0x7 @ Ensure 8-byte alignment - - sub sp, r1, #8 - add r1, r1, #1024 - - str r1, EXT_C(grub_modbase) - - /* Coreboot already places modules at right place. */ -#ifndef GRUB_MACHINE_COREBOOT - add r1, r1, r2 - add r0, r0, r2 - sub r1, r1, #4 - sub r0, r0, #4 - -1: ldr r3, [r0], #-4 @ r3 = *src-- - str r3, [r1], #-4 @ *dst-- = r3 - subs r2, #4 @ remaining -= 4 - bne 1b @ while remaining != 0 -#endif - - @ Since we _are_ the C run-time, we need to manually zero the BSS - @ region before continuing - ldr r0, bss_start_ptr @ zero from here - @ If unaligned, bytewise zero until base address aligned. - mov r2, #0 -1: tst r0, #3 - beq 2f - strb r2, [r0], #1 - b 1b -2: ldr r1, end_ptr @ to here -1: str r2, [r0], #4 - cmp r0, r1 - bne 1b - - b EXT_C(grub_main) - - .align 3 -@ U-boot/coreboot context stack space -VARIABLE(grub_arm_saved_registers) - .long 0 @ r0 - .long 0 @ r1 - .long 0 @ r2 - .long 0 @ r3 - .long 0 @ r4 - .long 0 @ r5 - .long 0 @ r6 - .long 0 @ r7 - .long 0 @ r8 - .long 0 @ r9 - .long 0 @ r10 - .long 0 @ r11 - .long 0 @ sp - .long 0 @ lr -entry_state: diff --git a/grub-core/kern/arm/uboot/init.c b/grub-core/kern/arm/uboot/init.c deleted file mode 100644 index 2a6aa3fdd..000000000 --- a/grub-core/kern/arm/uboot/init.c +++ /dev/null @@ -1,70 +0,0 @@ -/* init.c - generic U-Boot initialization and finalization */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2016 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -extern int (*grub_uboot_syscall_ptr) (int, int *, ...); - -grub_uint32_t -grub_uboot_get_machine_type (void) -{ - return grub_arm_saved_registers.r[1]; -} - -grub_addr_t -grub_uboot_get_boot_data (void) -{ - return grub_arm_saved_registers.r[2]; -} - -int -grub_uboot_api_init (void) -{ - struct api_signature *start, *end; - struct api_signature *p; - grub_addr_t grub_uboot_search_hint = grub_arm_saved_registers.sp; - if (grub_uboot_search_hint) - { - /* Extended search range to work around Trim Slice U-Boot issue */ - start = (struct api_signature *) ((grub_uboot_search_hint & ~0x000fffff) - - 0x00500000); - end = - (struct api_signature *) ((grub_addr_t) start + UBOOT_API_SEARCH_LEN - - API_SIG_MAGLEN + 0x00500000); - } - else - { - start = 0; - end = (struct api_signature *) (256 * 1024 * 1024); - } - - /* Structure alignment is (at least) 8 bytes */ - for (p = start; p < end; p = (void *) ((grub_addr_t) p + 8)) - { - if (grub_memcmp (&(p->magic), API_SIG_MAGIC, API_SIG_MAGLEN) == 0) - { - grub_uboot_syscall_ptr = p->syscall; - return p->version; - } - } - - return 0; -} diff --git a/grub-core/kern/arm/uboot/uboot.S b/grub-core/kern/arm/uboot/uboot.S deleted file mode 100644 index d128775f1..000000000 --- a/grub-core/kern/arm/uboot/uboot.S +++ /dev/null @@ -1,73 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - - /* - * uboot_syscall(): - * This function is effectively a veneer, so it cannot - * modify the stack or corrupt any registers other than - * r12 (ip). Furthermore it needs to restore r8 for - * U-Boot (Global Data Pointer) and preserve it for Grub. - */ -FUNCTION(grub_uboot_syscall) - str r8, transition_space - str lr, transition_space + 4 - str r9, transition_space + 8 - - ldr ip, saved_registers_ptr - ldr r8, [ip, #4 * 8] - ldr r9, [ip, #4 * 9] - - bl do_syscall - - ldr r8, transition_space - ldr lr, transition_space + 4 - ldr r9, transition_space + 8 - - bx lr -do_syscall: - - ldr ip, grub_uboot_syscall_ptr - bx ip - -FUNCTION(grub_uboot_return) - ldr ip, saved_registers_ptr - ldr sp, [ip, #4 * 4] - pop {r4-r12, lr} - mov sp, r12 - bx lr - - - .align 3 - -@ GRUB context stack space -transition_space: - .long 0 @ r8 - .long 0 @ lr - .long 0 @ r9 - -saved_registers_ptr: - .long EXT_C(grub_arm_saved_registers) - -VARIABLE(grub_uboot_syscall_ptr) - .long 0 @ - - END diff --git a/grub-core/kern/arm64/cache.c b/grub-core/kern/arm64/cache.c deleted file mode 100644 index b84383da1..000000000 --- a/grub-core/kern/arm64/cache.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -static grub_int64_t dlinesz; -static grub_int64_t ilinesz; - -/* Prototypes for asm functions. */ -void grub_arch_clean_dcache_range (grub_addr_t beg, grub_addr_t end, - grub_uint64_t line_size); -void grub_arch_invalidate_icache_range (grub_addr_t beg, grub_addr_t end, - grub_uint64_t line_size); - -static void -probe_caches (void) -{ - grub_uint64_t cache_type; - - /* Read Cache Type Register */ - asm volatile ("mrs %0, ctr_el0": "=r"(cache_type)); - - dlinesz = 4 << ((cache_type >> 16) & 0xf); - ilinesz = 4 << (cache_type & 0xf); - - grub_dprintf("cache", "D$ line size: %lld\n", (long long) dlinesz); - grub_dprintf("cache", "I$ line size: %lld\n", (long long) ilinesz); -} - -void -grub_arch_sync_caches (void *address, grub_size_t len) -{ - grub_uint64_t start, end, max_align; - - if (dlinesz == 0) - probe_caches(); - if (dlinesz == 0) - grub_fatal ("Unknown cache line size!"); - - max_align = dlinesz > ilinesz ? dlinesz : ilinesz; - - start = ALIGN_DOWN ((grub_uint64_t) address, max_align); - end = ALIGN_UP ((grub_uint64_t) address + len, max_align); - - grub_arch_clean_dcache_range (start, end, dlinesz); - grub_arch_invalidate_icache_range (start, end, ilinesz); -} diff --git a/grub-core/kern/arm64/cache_flush.S b/grub-core/kern/arm64/cache_flush.S deleted file mode 100644 index e064f7ece..000000000 --- a/grub-core/kern/arm64/cache_flush.S +++ /dev/null @@ -1,55 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - - .file "cache_flush.S" - .text - -/* - * Simple cache maintenance functions - */ - -// x0 - *beg (inclusive) -// x1 - *end (exclusive) -// x2 - line size -FUNCTION(grub_arch_clean_dcache_range) - // Clean data cache for range to point-of-unification -1: cmp x0, x1 - b.ge 2f - dc cvau, x0 // Clean Virtual Address to PoU - add x0, x0, x2 // Next line - b 1b -2: dsb ish - isb - ret - -// x0 - *beg (inclusive) -// x1 - *end (exclusive) -// x2 - line size -FUNCTION(grub_arch_invalidate_icache_range) - // Invalidate instruction cache for range to point-of-unification -1: cmp x0, x1 - b.ge 2f - ic ivau, x0 // Invalidate Virtual Address to PoU - add x0, x0, x2 // Next line - b 1b - // Branch predictor invalidation not needed on AArch64 -2: dsb ish - isb - ret diff --git a/grub-core/kern/arm64/dl.c b/grub-core/kern/arm64/dl.c deleted file mode 100644 index a2b5789a9..000000000 --- a/grub-core/kern/arm64/dl.c +++ /dev/null @@ -1,198 +0,0 @@ -/* dl.c - arch-dependent part of loadable module support */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -#define LDR 0x58000050 -#define BR 0xd61f0200 - - -/* - * 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] != ELFDATA2LSB || e->e_machine != EM_AARCH64) - return grub_error (GRUB_ERR_BAD_OS, - N_("invalid arch-dependent ELF magic")); - - return GRUB_ERR_NONE; -} - -#pragma GCC diagnostic ignored "-Wcast-align" - -/* - * Unified function for both REL and RELA - */ -grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - Elf_Shdr *s, grub_dl_segment_t seg) -{ - Elf_Rel *rel, *max; - unsigned unmatched_adr_got_page = 0; - - for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset), - max = (Elf_Rel *) ((char *) rel + s->sh_size); - rel < max; - rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) - { - Elf_Sym *sym; - void *place; - grub_uint64_t sym_addr; - - if (rel->r_offset >= seg->size) - return grub_error (GRUB_ERR_BAD_MODULE, - "reloc offset is out of the segment"); - - sym = (Elf_Sym *) ((char *) mod->symtab - + mod->symsize * ELF_R_SYM (rel->r_info)); - - sym_addr = sym->st_value; - if (s->sh_type == SHT_RELA) - sym_addr += ((Elf_Rela *) rel)->r_addend; - - place = (void *) ((grub_addr_t) seg->addr + rel->r_offset); - - switch (ELF_R_TYPE (rel->r_info)) - { - case R_AARCH64_ABS64: - { - grub_uint64_t *abs_place = place; - - grub_dprintf ("dl", " reloc_abs64 %p => 0x%016llx\n", - place, (unsigned long long) sym_addr); - - *abs_place = (grub_uint64_t) sym_addr; - } - break; - case R_AARCH64_ADD_ABS_LO12_NC: - grub_arm64_set_abs_lo12 (place, sym_addr); - break; - case R_AARCH64_LDST64_ABS_LO12_NC: - grub_arm64_set_abs_lo12_ldst64 (place, sym_addr); - break; - case R_AARCH64_CALL26: - case R_AARCH64_JUMP26: - { - grub_int64_t offset = sym_addr - (grub_uint64_t) place; - - if (!grub_arm_64_check_xxxx26_offset (offset)) - { - struct grub_arm64_trampoline *tp = mod->trampptr; - mod->trampptr = tp + 1; - tp->ldr = LDR; - tp->br = BR; - tp->addr = sym_addr; - offset = (grub_uint8_t *) tp - (grub_uint8_t *) place; - } - - if (!grub_arm_64_check_xxxx26_offset (offset)) - return grub_error (GRUB_ERR_BAD_MODULE, - "trampoline out of range"); - - grub_arm64_set_xxxx26_offset (place, offset); - } - break; - case R_AARCH64_PREL32: - { - grub_int64_t value; - Elf64_Word *addr32 = place; - value = ((grub_int32_t) *addr32) + sym_addr - - (Elf64_Xword) (grub_addr_t) seg->addr - rel->r_offset; - if (value != (grub_int32_t) value) - return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range"); - grub_dprintf("dl", " reloc_prel32 %p => 0x%016llx\n", - place, (unsigned long long) sym_addr); - *addr32 = value; - } - break; - case R_AARCH64_ADR_GOT_PAGE: - { - grub_uint64_t *gp = mod->gotptr; - Elf_Rela *rel2; - grub_int64_t gpoffset = ((grub_uint64_t) gp & ~0xfffULL) - (((grub_uint64_t) place) & ~0xfffULL); - *gp = (grub_uint64_t) sym_addr; - mod->gotptr = gp + 1; - unmatched_adr_got_page++; - grub_dprintf("dl", " reloc_got %p => 0x%016llx (0x%016llx)\n", - place, (unsigned long long) sym_addr, (unsigned long long) gp); - if (!grub_arm64_check_hi21_signed (gpoffset)) - return grub_error (GRUB_ERR_BAD_MODULE, - "HI21 out of range"); - grub_arm64_set_hi21(place, gpoffset); - for (rel2 = (Elf_Rela *) ((char *) rel + s->sh_entsize); - rel2 < (Elf_Rela *) max; - rel2 = (Elf_Rela *) ((char *) rel2 + s->sh_entsize)) - if (ELF_R_SYM (rel2->r_info) - == ELF_R_SYM (rel->r_info) - && ((Elf_Rela *) rel)->r_addend == rel2->r_addend - && ELF_R_TYPE (rel2->r_info) == R_AARCH64_LD64_GOT_LO12_NC) - { - grub_arm64_set_abs_lo12_ldst64 ((void *) ((grub_addr_t) seg->addr + rel2->r_offset), - (grub_uint64_t)gp); - break; - } - if (rel2 >= (Elf_Rela *) max) - return grub_error (GRUB_ERR_BAD_MODULE, - "ADR_GOT_PAGE without matching LD64_GOT_LO12_NC"); - } - break; - case R_AARCH64_LD64_GOT_LO12_NC: - if (unmatched_adr_got_page == 0) - return grub_error (GRUB_ERR_BAD_MODULE, - "LD64_GOT_LO12_NC without matching ADR_GOT_PAGE"); - unmatched_adr_got_page--; - break; - case R_AARCH64_ADR_PREL_PG_HI21: - { - grub_int64_t offset = (sym_addr & ~0xfffULL) - (((grub_uint64_t) place) & ~0xfffULL); - - if (!grub_arm64_check_hi21_signed (offset)) - return grub_error (GRUB_ERR_BAD_MODULE, - "HI21 out of range"); - - grub_arm64_set_hi21 (place, offset); - } - break; - - default: - { - char rel_info[17]; /* log16(2^64) = 16, plus NUL. */ - - grub_snprintf (rel_info, sizeof (rel_info) - 1, "%" PRIxGRUB_UINT64_T, - ELF_R_TYPE (rel->r_info)); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%s is not implemented yet"), rel_info); - } - } - } - - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/arm64/dl_helper.c b/grub-core/kern/arm64/dl_helper.c deleted file mode 100644 index 10e3d1ec2..000000000 --- a/grub-core/kern/arm64/dl_helper.c +++ /dev/null @@ -1,134 +0,0 @@ -/* dl_helper.c - relocation helper functions for modules and grub-mkimage */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -/* - * grub_arm64_reloc_xxxx26(): - * - * JUMP26/CALL26 relocations for B and BL instructions. - */ - -int -grub_arm_64_check_xxxx26_offset (grub_int64_t offset) -{ - const grub_ssize_t offset_low = -(1 << 27), offset_high = (1 << 27) - 1; - - if ((offset < offset_low) || (offset > offset_high)) - return 0; - return 1; -} - -void -grub_arm64_set_xxxx26_offset (grub_uint32_t *place, grub_int64_t offset) -{ - const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfc000000); - - grub_dprintf ("dl", " reloc_xxxx64 %p %c= 0x%" PRIxGRUB_INT64_T "\n", - place, offset > 0 ? '+' : '-', - offset < 0 ? -offset : offset); - - *place &= insmask; - *place |= grub_cpu_to_le32 (offset >> 2) & ~insmask; -} - -int -grub_arm64_check_hi21_signed (grub_int64_t offset) -{ - if (offset != (grub_int64_t)(grub_int32_t)offset) - return 0; - return 1; -} - -void -grub_arm64_set_hi21 (grub_uint32_t *place, grub_int64_t offset) -{ - const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0x9f00001f); - grub_uint32_t val; - - offset >>= 12; - - val = ((offset & 3) << 29) | (((offset >> 2) & 0x7ffff) << 5); - - *place &= insmask; - *place |= grub_cpu_to_le32 (val) & ~insmask; -} - -void -grub_arm64_set_abs_lo12 (grub_uint32_t *place, grub_int64_t target) -{ - const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xffc003ff); - - *place &= insmask; - *place |= grub_cpu_to_le32 (target << 10) & ~insmask; -} - -void -grub_arm64_set_abs_lo12_ldst64 (grub_uint32_t *place, grub_int64_t target) -{ - const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfff803ff); - - *place &= insmask; - *place |= grub_cpu_to_le32 (target << 7) & ~insmask; -} - -#pragma GCC diagnostic ignored "-Wcast-align" - -grub_err_t -grub_arm64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, - grub_size_t *got) -{ - const Elf64_Ehdr *e = ehdr; - const Elf64_Shdr *s; - unsigned i; - - *tramp = 0; - *got = 0; - - for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu64 (e->e_shoff)); - i < grub_le_to_cpu16 (e->e_shnum); - i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize))) - if (s->sh_type == grub_cpu_to_le32_compile_time (SHT_REL) - || s->sh_type == grub_cpu_to_le32_compile_time (SHT_RELA)) - { - const Elf64_Rela *rel, *max; - - for (rel = (Elf64_Rela *) ((char *) e + grub_le_to_cpu64 (s->sh_offset)), - max = (const Elf64_Rela *) ((char *) rel + grub_le_to_cpu64 (s->sh_size)); - rel < max; rel = (const Elf64_Rela *) ((char *) rel + grub_le_to_cpu64 (s->sh_entsize))) - switch (ELF64_R_TYPE (rel->r_info)) - { - case R_AARCH64_CALL26: - case R_AARCH64_JUMP26: - *tramp += sizeof (struct grub_arm64_trampoline); - break; - case R_AARCH64_ADR_GOT_PAGE: - *got += 8; - break; - } - } - - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/arm64/efi/init.c b/grub-core/kern/arm64/efi/init.c deleted file mode 100644 index 5010caefd..000000000 --- a/grub-core/kern/arm64/efi/init.c +++ /dev/null @@ -1,63 +0,0 @@ -/* init.c - initialize an arm-based EFI system */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -static grub_uint64_t timer_frequency_in_khz; - -static grub_uint64_t -grub_efi_get_time_ms (void) -{ - grub_uint64_t tmr; - asm volatile("mrs %0, cntvct_el0" : "=r" (tmr)); - - return tmr / timer_frequency_in_khz; -} - - -void -grub_machine_init (void) -{ - grub_uint64_t timer_frequency; - - grub_efi_init (); - - asm volatile("mrs %0, cntfrq_el0" : "=r" (timer_frequency)); - timer_frequency_in_khz = timer_frequency / 1000; - - grub_install_get_time_ms (grub_efi_get_time_ms); -} - -void -grub_machine_fini (int flags) -{ - if (!(flags & GRUB_LOADER_FLAG_NORETURN)) - return; - - grub_efi_fini (); - - if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) - grub_efi_memory_fini (); -} diff --git a/grub-core/kern/arm64/efi/startup.S b/grub-core/kern/arm64/efi/startup.S deleted file mode 100644 index 666a7ee3c..000000000 --- a/grub-core/kern/arm64/efi/startup.S +++ /dev/null @@ -1,39 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - - .file "startup.S" - .text -FUNCTION(_start) - /* - * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in x1/x0. - */ - ldr x2, efi_image_handle_val - str x0, [x2] - ldr x2, efi_system_table_val - str x1, [x2] - ldr x2, grub_main_val - br x2 -grub_main_val: - .quad EXT_C(grub_main) -efi_system_table_val: - .quad EXT_C(grub_efi_system_table) -efi_image_handle_val: - .quad EXT_C(grub_efi_image_handle) - diff --git a/grub-core/kern/buffer.c b/grub-core/kern/buffer.c deleted file mode 100644 index a2587729c..000000000 --- a/grub-core/kern/buffer.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2021 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -grub_buffer_t -grub_buffer_new (grub_size_t sz) -{ - struct grub_buffer *ret; - - ret = (struct grub_buffer *) grub_malloc (sizeof (*ret)); - if (ret == NULL) - return NULL; - - ret->data = (grub_uint8_t *) grub_malloc (sz); - if (ret->data == NULL) - { - grub_free (ret); - return NULL; - } - - ret->sz = sz; - ret->pos = 0; - ret->used = 0; - - return ret; -} - -void -grub_buffer_free (grub_buffer_t buf) -{ - if (buf != NULL) - { - grub_free (buf->data); - grub_free (buf); - } -} - -grub_err_t -grub_buffer_ensure_space (grub_buffer_t buf, grub_size_t req) -{ - grub_uint8_t *d; - grub_size_t newsz = 1; - - /* Is the current buffer size adequate? */ - if (buf->sz >= req) - return GRUB_ERR_NONE; - - /* Find the smallest power-of-2 size that satisfies the request. */ - while (newsz < req) - { - if (newsz == 0) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("requested buffer size is too large")); - newsz <<= 1; - } - - d = (grub_uint8_t *) grub_realloc (buf->data, newsz); - if (d == NULL) - return grub_errno; - - buf->data = d; - buf->sz = newsz; - - return GRUB_ERR_NONE; -} - -void * -grub_buffer_take_data (grub_buffer_t buf) -{ - void *data = buf->data; - - buf->data = NULL; - buf->sz = buf->pos = buf->used = 0; - - return data; -} - -void -grub_buffer_reset (grub_buffer_t buf) -{ - buf->pos = buf->used = 0; -} - -grub_err_t -grub_buffer_advance_read_pos (grub_buffer_t buf, grub_size_t n) -{ - grub_size_t newpos; - - if (grub_add (buf->pos, n, &newpos)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); - - if (newpos > buf->used) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("new read is position beyond the end of the written data")); - - buf->pos = newpos; - - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/command.c b/grub-core/kern/command.c deleted file mode 100644 index 5812e131c..000000000 --- a/grub-core/kern/command.c +++ /dev/null @@ -1,111 +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 . - */ - -#include -#include -#include - -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; - int inactive = 0; - - grub_command_t *p, q; - - 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 = 0; - cmd->prio = prio; - - for (p = &grub_command_list, q = *p; q; p = &(q->next), q = q->next) - { - int r; - - r = grub_strcmp (cmd->name, q->name); - if (r < 0) - break; - if (r > 0) - continue; - - if (cmd->prio >= (q->prio & GRUB_COMMAND_PRIO_MASK)) - { - q->prio &= ~GRUB_COMMAND_FLAG_ACTIVE; - break; - } - - inactive = 1; - } - - *p = cmd; - cmd->next = q; - if (q) - q->prev = &cmd->next; - cmd->prev = p; - - if (! inactive) - cmd->prio |= GRUB_COMMAND_FLAG_ACTIVE; - - return cmd; -} - -static grub_err_t -grub_cmd_lockdown (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **argv __attribute__ ((unused))) - -{ - return grub_error (GRUB_ERR_ACCESS_DENIED, - N_("%s: the command is not allowed when lockdown is enforced"), - cmd->name); -} - -grub_command_t -grub_register_command_lockdown (const char *name, - grub_command_func_t func, - const char *summary, - const char *description) -{ - if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED) - func = grub_cmd_lockdown; - - return grub_register_command_prio (name, func, summary, description, 0); -} - -void -grub_unregister_command (grub_command_t cmd) -{ - if ((cmd->prio & GRUB_COMMAND_FLAG_ACTIVE) && (cmd->next)) - cmd->next->prio |= GRUB_COMMAND_FLAG_ACTIVE; - grub_list_remove (GRUB_AS_LIST (cmd)); - grub_free (cmd); -} diff --git a/grub-core/kern/compiler-rt.c b/grub-core/kern/compiler-rt.c deleted file mode 100644 index eda689a0c..000000000 --- a/grub-core/kern/compiler-rt.c +++ /dev/null @@ -1,454 +0,0 @@ -/* compiler-rt.c - compiler helpers. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010-2014 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#ifndef GRUB_EMBED_DECOMPRESSOR -void * GRUB_BUILTIN_ATTR -memcpy (void *dest, const void *src, grub_size_t n) -{ - return grub_memmove (dest, src, n); -} -void * GRUB_BUILTIN_ATTR -memmove (void *dest, const void *src, grub_size_t n) -{ - return grub_memmove (dest, src, n); -} -int GRUB_BUILTIN_ATTR -memcmp (const void *s1, const void *s2, grub_size_t n) -{ - return grub_memcmp (s1, s2, n); -} -void * GRUB_BUILTIN_ATTR -memset (void *s, int c, grub_size_t n) -{ - return grub_memset (s, c, n); -} - -#ifdef __APPLE__ - -void GRUB_BUILTIN_ATTR -__bzero (void *s, grub_size_t n) -{ - grub_memset (s, 0, n); -} - -#endif - -#if GRUB_DIVISION_IN_SOFTWARE - -grub_uint32_t -__udivsi3 (grub_uint32_t a, grub_uint32_t b) -{ - return grub_divmod64 (a, b, 0); -} - -grub_int32_t -__divsi3 (grub_int32_t a, grub_int32_t b) -{ - return grub_divmod64s (a, b, 0); -} - -grub_uint32_t -__umodsi3 (grub_uint32_t a, grub_uint32_t b) -{ - grub_uint64_t ret; - grub_divmod64 (a, b, &ret); - return ret; -} - -grub_int32_t -__modsi3 (grub_int32_t a, grub_int32_t b) -{ - grub_int64_t ret; - grub_divmod64s (a, b, &ret); - return ret; -} - -grub_uint64_t -__udivdi3 (grub_uint64_t a, grub_uint64_t b) -{ - return grub_divmod64 (a, b, 0); -} - -grub_uint64_t -__umoddi3 (grub_uint64_t a, grub_uint64_t b) -{ - grub_uint64_t ret; - grub_divmod64 (a, b, &ret); - return ret; -} - -grub_int64_t -__divdi3 (grub_int64_t a, grub_int64_t b) -{ - return grub_divmod64s (a, b, 0); -} - -grub_int64_t -__moddi3 (grub_int64_t a, grub_int64_t b) -{ - grub_int64_t ret; - grub_divmod64s (a, b, &ret); - return ret; -} - -#endif - -#endif - -#ifdef NEED_CTZDI2 - -unsigned -__ctzdi2 (grub_uint64_t x) -{ - unsigned ret = 0; - if (!x) - return 64; - if (!(x & 0xffffffff)) - { - x >>= 32; - ret |= 32; - } - if (!(x & 0xffff)) - { - x >>= 16; - ret |= 16; - } - if (!(x & 0xff)) - { - x >>= 8; - ret |= 8; - } - if (!(x & 0xf)) - { - x >>= 4; - ret |= 4; - } - if (!(x & 0x3)) - { - x >>= 2; - ret |= 2; - } - if (!(x & 0x1)) - { - x >>= 1; - ret |= 1; - } - return ret; -} -#endif - -#ifdef NEED_CTZSI2 -unsigned -__ctzsi2 (grub_uint32_t x) -{ - unsigned ret = 0; - if (!x) - return 32; - - if (!(x & 0xffff)) - { - x >>= 16; - ret |= 16; - } - if (!(x & 0xff)) - { - x >>= 8; - ret |= 8; - } - if (!(x & 0xf)) - { - x >>= 4; - ret |= 4; - } - if (!(x & 0x3)) - { - x >>= 2; - ret |= 2; - } - if (!(x & 0x1)) - { - x >>= 1; - ret |= 1; - } - return ret; -} - -#endif - -#if (defined (__MINGW32__) || defined (__CYGWIN__)) -void __register_frame_info (void) -{ -} - -void __deregister_frame_info (void) -{ -} - -void ___chkstk_ms (void) -{ -} - -void __chkstk_ms (void) -{ -} -#endif - -union component64 -{ - grub_uint64_t full; - struct - { -#ifdef GRUB_CPU_WORDS_BIGENDIAN - grub_uint32_t high; - grub_uint32_t low; -#else - grub_uint32_t low; - grub_uint32_t high; -#endif - }; -}; - -#if defined (__powerpc__) || defined (__arm__) || defined(__mips__) || \ - (defined(__riscv) && (__riscv_xlen == 32)) - -/* Based on libgcc2.c from gcc suite. */ -grub_uint64_t -__lshrdi3 (grub_uint64_t u, int b) -{ - if (b == 0) - return u; - - const union component64 uu = {.full = u}; - const int bm = 32 - b; - union component64 w; - - if (bm <= 0) - { - w.high = 0; - w.low = (grub_uint32_t) uu.high >> -bm; - } - else - { - const grub_uint32_t carries = (grub_uint32_t) uu.high << bm; - - w.high = (grub_uint32_t) uu.high >> b; - w.low = ((grub_uint32_t) uu.low >> b) | carries; - } - - return w.full; -} - -/* Based on libgcc2.c from gcc suite. */ -grub_uint64_t -__ashrdi3 (grub_uint64_t u, int b) -{ - if (b == 0) - return u; - - const union component64 uu = {.full = u}; - const int bm = 32 - b; - union component64 w; - - if (bm <= 0) - { - /* w.high = 1..1 or 0..0 */ - w.high = ((grub_int32_t) uu.high) >> (32 - 1); - w.low = ((grub_int32_t) uu.high) >> -bm; - } - else - { - const grub_uint32_t carries = ((grub_uint32_t) uu.high) << bm; - - w.high = ((grub_int32_t) uu.high) >> b; - w.low = ((grub_uint32_t) uu.low >> b) | carries; - } - - return w.full; -} - -/* Based on libgcc2.c from gcc suite. */ -grub_uint64_t -__ashldi3 (grub_uint64_t u, int b) -{ - if (b == 0) - return u; - - const union component64 uu = {.full = u}; - const int bm = 32 - b; - union component64 w; - - if (bm <= 0) - { - w.low = 0; - w.high = (grub_uint32_t) uu.low << -bm; - } - else - { - const grub_uint32_t carries = (grub_uint32_t) uu.low >> bm; - - w.low = (grub_uint32_t) uu.low << b; - w.high = ((grub_uint32_t) uu.high << b) | carries; - } - - return w.full; -} - -/* Based on libgcc2.c from gcc suite. */ -int -__ucmpdi2 (grub_uint64_t a, grub_uint64_t b) -{ - union component64 ac, bc; - ac.full = a; - bc.full = b; - - if (ac.high < bc.high) - return 0; - else if (ac.high > bc.high) - return 2; - - if (ac.low < bc.low) - return 0; - else if (ac.low > bc.low) - return 2; - return 1; -} - -#endif - -#if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || \ - defined(__arm__) || defined(__riscv) - -/* Based on libgcc2.c from gcc suite. */ -grub_uint32_t -__bswapsi2 (grub_uint32_t u) -{ - return ((((u) & 0xff000000) >> 24) - | (((u) & 0x00ff0000) >> 8) - | (((u) & 0x0000ff00) << 8) - | (((u) & 0x000000ff) << 24)); -} - -/* Based on libgcc2.c from gcc suite. */ -grub_uint64_t -__bswapdi2 (grub_uint64_t u) -{ - return ((((u) & 0xff00000000000000ull) >> 56) - | (((u) & 0x00ff000000000000ull) >> 40) - | (((u) & 0x0000ff0000000000ull) >> 24) - | (((u) & 0x000000ff00000000ull) >> 8) - | (((u) & 0x00000000ff000000ull) << 8) - | (((u) & 0x0000000000ff0000ull) << 24) - | (((u) & 0x000000000000ff00ull) << 40) - | (((u) & 0x00000000000000ffull) << 56)); -} - - -#endif - -#ifdef __arm__ -grub_uint32_t -__aeabi_uidiv (grub_uint32_t a, grub_uint32_t b) - __attribute__ ((alias ("__udivsi3"))); -grub_int32_t -__aeabi_idiv (grub_int32_t a, grub_int32_t b) - __attribute__ ((alias ("__divsi3"))); -void *__aeabi_memcpy (void *dest, const void *src, grub_size_t n) - __attribute__ ((alias ("grub_memcpy"))); -void *__aeabi_memcpy4 (void *dest, const void *src, grub_size_t n) - __attribute__ ((alias ("grub_memcpy"))); -void *__aeabi_memcpy8 (void *dest, const void *src, grub_size_t n) - __attribute__ ((alias ("grub_memcpy"))); -void *__aeabi_memset (void *s, int c, grub_size_t n) - __attribute__ ((alias ("memset"))); - -void -__aeabi_memclr (void *s, grub_size_t n) -{ - grub_memset (s, 0, n); -} - -void __aeabi_memclr4 (void *s, grub_size_t n) - __attribute__ ((alias ("__aeabi_memclr"))); -void __aeabi_memclr8 (void *s, grub_size_t n) - __attribute__ ((alias ("__aeabi_memclr"))); - -int -__aeabi_ulcmp (grub_uint64_t a, grub_uint64_t b) -{ - return __ucmpdi2 (a, b) - 1; -} - -grub_uint64_t -__aeabi_lasr (grub_uint64_t u, int b) - __attribute__ ((alias ("__ashrdi3"))); -grub_uint64_t -__aeabi_llsr (grub_uint64_t u, int b) - __attribute__ ((alias ("__lshrdi3"))); - -grub_uint64_t -__aeabi_llsl (grub_uint64_t u, int b) - __attribute__ ((alias ("__ashldi3"))); - -#endif - -#if defined(__mips__) || defined(__riscv) || defined(__sparc__) -/* Based on libgcc from gcc suite. */ -int -__clzsi2 (grub_uint32_t val) -{ - int i = 32; - int j = 16; - int temp; - - for (; j; j >>= 1) - { - if ((temp = val >> j)) - { - if (j == 1) - { - return (i - 2); - } - else - { - i -= j; - val = temp; - } - } - } - return (i - val); -} -#endif - -#if defined(__mips__) || defined(__riscv) || defined(__sparc__) -int -__clzdi2 (grub_uint64_t val) -{ - if (val >> 32) - { - return __clzsi2 (val >> 32); - } - else - { - return __clzsi2 (val) + 32; - } -} -#endif diff --git a/grub-core/kern/coreboot/cbtable.c b/grub-core/kern/coreboot/cbtable.c deleted file mode 100644 index b6d0801c1..000000000 --- a/grub-core/kern/coreboot/cbtable.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007,2008,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#pragma GCC diagnostic ignored "-Wcast-align" - -/* Helper for grub_linuxbios_table_iterate. */ -int -grub_linuxbios_check_signature (grub_linuxbios_table_header_t tbl_header) -{ - if (! grub_memcmp (tbl_header->signature, "LBIO", 4)) - return 1; - - return 0; -} - -grub_err_t -grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t, - void *), - void *hook_data) -{ - grub_linuxbios_table_header_t table_header = grub_linuxbios_get_tables (); - grub_linuxbios_table_item_t table_item; - - if (!table_header) - return 0; - -signature_found: - - table_item = - (grub_linuxbios_table_item_t) ((char *) table_header + - table_header->header_size); - for (; table_item < (grub_linuxbios_table_item_t) ((char *) table_header - + table_header->header_size - + table_header->table_size); - table_item = (grub_linuxbios_table_item_t) ((char *) table_item + table_item->size)) - { - if (table_item->tag == GRUB_LINUXBIOS_MEMBER_LINK - && grub_linuxbios_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, hook_data)) - return 1; - } - - return 0; -} diff --git a/grub-core/kern/coreboot/mmap.c b/grub-core/kern/coreboot/mmap.c deleted file mode 100644 index caf8f7cef..000000000 --- a/grub-core/kern/coreboot/mmap.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007,2008,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include - -/* Context for grub_machine_mmap_iterate. */ -struct grub_machine_mmap_iterate_ctx -{ - grub_memory_hook_t hook; - void *hook_data; -}; - -#define GRUB_MACHINE_MEMORY_BADRAM 5 - -/* Helper for grub_machine_mmap_iterate. */ -static int -iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data) -{ - struct grub_machine_mmap_iterate_ctx *ctx = data; - mem_region_t mem_region; - - if (table_item->tag != GRUB_LINUXBIOS_MEMBER_MEMORY) - return 0; - - mem_region = - (mem_region_t) ((long) table_item + - sizeof (struct grub_linuxbios_table_item)); - for (; (long) mem_region < (long) table_item + (long) table_item->size; - mem_region++) - { - grub_uint64_t start = mem_region->addr; - grub_uint64_t end = mem_region->addr + mem_region->size; -#ifdef __i386__ - /* Mark region 0xa0000 - 0x100000 as reserved. */ - if (start < 0x100000 && end >= 0xa0000 - && mem_region->type == GRUB_MACHINE_MEMORY_AVAILABLE) - { - if (start < 0xa0000 - && ctx->hook (start, 0xa0000 - start, - /* Multiboot mmaps match with the coreboot mmap - definition. Therefore, we can just pass type - through. */ - mem_region->type, - ctx->hook_data)) - return 1; - if (start < 0xa0000) - start = 0xa0000; - if (start >= end) - continue; - - if (ctx->hook (start, (end > 0x100000 ? 0x100000 : end) - start, - GRUB_MEMORY_RESERVED, - ctx->hook_data)) - return 1; - start = 0x100000; - - if (end <= start) - continue; - } -#endif - if (ctx->hook (start, end - start, - /* Multiboot mmaps match with the coreboot mmap - definition. Therefore, we can just pass type - through. */ - mem_region->type, - ctx->hook_data)) - return 1; - } - - return 0; -} - -grub_err_t -grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) -{ - struct grub_machine_mmap_iterate_ctx ctx = { hook, hook_data }; - - grub_linuxbios_table_iterate (iterate_linuxbios_table, &ctx); - - return 0; -} diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c deleted file mode 100644 index 670e213cf..000000000 --- a/grub-core/kern/device.c +++ /dev/null @@ -1,194 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -grub_net_t (*grub_net_open) (const char *name) = NULL; - -grub_device_t -grub_device_open (const char *name) -{ - grub_device_t dev = 0; - - if (! name) - { - name = grub_env_get ("root"); - if (name == NULL || *name == '\0') - { - grub_error (GRUB_ERR_BAD_DEVICE, N_("variable `%s' isn't set"), "root"); - goto fail; - } - } - - dev = grub_malloc (sizeof (*dev)); - if (! dev) - goto fail; - - dev->net = NULL; - /* Try to open a disk. */ - dev->disk = grub_disk_open (name); - if (dev->disk) - return dev; - if (grub_net_open && grub_errno == GRUB_ERR_UNKNOWN_DEVICE) - { - grub_errno = GRUB_ERR_NONE; - dev->net = grub_net_open (name); - } - - if (dev->net) - return dev; - - fail: - grub_free (dev); - - return 0; -} - -grub_err_t -grub_device_close (grub_device_t device) -{ - if (device == NULL) - return GRUB_ERR_NONE; - - if (device->disk) - grub_disk_close (device->disk); - - if (device->net) - { - grub_free (device->net->server); - grub_free (device->net); - } - - grub_free (device); - - return grub_errno; -} - -struct part_ent -{ - struct part_ent *next; - char *name; -}; - -/* Context for grub_device_iterate. */ -struct grub_device_iterate_ctx -{ - grub_device_iterate_hook_t hook; - void *hook_data; - struct part_ent *ents; -}; - -/* Helper for grub_device_iterate. */ -static int -iterate_partition (grub_disk_t disk, const grub_partition_t partition, - void *data) -{ - struct grub_device_iterate_ctx *ctx = data; - struct part_ent *p; - char *part_name; - - p = grub_malloc (sizeof (*p)); - if (!p) - { - return 1; - } - - part_name = grub_partition_get_name (partition); - if (!part_name) - { - grub_free (p); - return 1; - } - p->name = grub_xasprintf ("%s,%s", disk->name, part_name); - grub_free (part_name); - if (!p->name) - { - grub_free (p); - return 1; - } - - p->next = ctx->ents; - ctx->ents = p; - - return 0; -} - -/* Helper for grub_device_iterate. */ -static int -iterate_disk (const char *disk_name, void *data) -{ - struct grub_device_iterate_ctx *ctx = data; - grub_device_t dev; - - if (ctx->hook (disk_name, ctx->hook_data)) - return 1; - - dev = grub_device_open (disk_name); - if (! dev) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - - if (dev->disk) - { - struct part_ent *p; - int ret = 0; - - ctx->ents = NULL; - (void) grub_partition_iterate (dev->disk, iterate_partition, ctx); - grub_device_close (dev); - - grub_errno = GRUB_ERR_NONE; - - p = ctx->ents; - while (p != NULL) - { - struct part_ent *next = p->next; - - if (!ret) - ret = ctx->hook (p->name, ctx->hook_data); - grub_free (p->name); - grub_free (p); - p = next; - } - - return ret; - } - - grub_device_close (dev); - return 0; -} - -int -grub_device_iterate (grub_device_iterate_hook_t hook, void *hook_data) -{ - struct grub_device_iterate_ctx ctx = { hook, hook_data, NULL }; - - /* Only disk devices are supported at the moment. */ - return grub_disk_dev_iterate (iterate_disk, &ctx); -} diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c deleted file mode 100644 index 82e04fd00..000000000 --- a/grub-core/kern/disk.c +++ /dev/null @@ -1,561 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define GRUB_CACHE_TIMEOUT 2 - -/* Disk reads may trigger other disk reads. So, limit recursion depth. */ -#define MAX_READ_RECURSION_DEPTH 16 -static unsigned int read_recursion_depth = 0; - -/* The last time the disk was used. */ -static grub_uint64_t grub_last_time = 0; - -struct grub_disk_cache grub_disk_cache_table[GRUB_DISK_CACHE_NUM]; - -void (*grub_disk_firmware_fini) (void); -int grub_disk_firmware_is_tainted; - -#if DISK_CACHE_STATS -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 - -grub_err_t (*grub_disk_write_weak) (grub_disk_t disk, - grub_disk_addr_t sector, - grub_off_t offset, - grub_size_t size, - const void *buf); -#include "disk_common.c" - -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 cache_index; - - cache_index = grub_disk_cache_get_index (dev_id, disk_id, sector); - cache = grub_disk_cache_table + cache_index; - - if (cache->dev_id == dev_id && cache->disk_id == disk_id - && cache->sector == sector) - { - cache->lock = 1; -#if DISK_CACHE_STATS - grub_disk_cache_hits++; -#endif - return cache->data; - } - -#if DISK_CACHE_STATS - 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 cache_index; - - cache_index = grub_disk_cache_get_index (dev_id, disk_id, sector); - cache = grub_disk_cache_table + cache_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 cache_index; - struct grub_disk_cache *cache; - - cache_index = grub_disk_cache_get_index (dev_id, disk_id, sector); - cache = grub_disk_cache_table + cache_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; -} - - - -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; - } -} - -/* 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->log_sector_size = GRUB_DISK_SECTOR_BITS; - /* Default 1MiB of maximum agglomerate. */ - disk->max_agglomerate = 1048576 >> (GRUB_DISK_SECTOR_BITS - + GRUB_DISK_CACHE_BITS); - - 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'; - disk->name = grub_strdup (raw); - } - else - disk->name = grub_strdup (name); - if (! disk->name) - goto fail; - - for (dev = grub_disk_dev_list; dev; dev = dev->next) - { - if ((dev->disk_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, N_("disk `%s' not found"), - name); - goto fail; - } - if (disk->log_sector_size > GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS - || disk->log_sector_size < GRUB_DISK_SECTOR_BITS) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "sector sizes of %d bytes aren't supported yet", - (1 << disk->log_sector_size)); - goto fail; - } - - disk->dev = dev; - - if (p) - { - disk->partition = grub_partition_probe (disk, p + 1); - if (! disk->partition) - { - /* TRANSLATORS: It means that the specified partition e.g. - hd0,msdos1=/dev/sda1 doesn't exist. */ - grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("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; - - if (disk == NULL) - return; - - grub_dprintf ("disk", "Closing `%s'.\n", disk->name); - - if (disk->dev && disk->dev->disk_close) - (disk->dev->disk_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); -} - -/* Small read (less than cache size and not pass across cache unit boundaries). - sector is already adjusted and is divisible by cache unit size. - */ -static grub_err_t -grub_disk_read_small_real (grub_disk_t disk, grub_disk_addr_t sector, - grub_off_t offset, grub_size_t size, void *buf) -{ - char *data; - char *tmp_buf; - - /* Fetch the cache. */ - data = grub_disk_cache_fetch (disk->dev->id, disk->id, sector); - if (data) - { - /* Just copy it! */ - grub_memcpy (buf, data + offset, size); - grub_disk_cache_unlock (disk->dev->id, disk->id, sector); - return GRUB_ERR_NONE; - } - - /* Allocate a temporary buffer. */ - tmp_buf = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS); - if (! tmp_buf) - return grub_errno; - - /* Otherwise read data from the disk actually. */ - if (disk->total_sectors == GRUB_DISK_SIZE_UNKNOWN - || sector + GRUB_DISK_CACHE_SIZE - < (disk->total_sectors << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS))) - { - grub_err_t err; - err = (disk->dev->disk_read) (disk, grub_disk_to_native_sector (disk, sector), - 1U << (GRUB_DISK_CACHE_BITS - + GRUB_DISK_SECTOR_BITS - - disk->log_sector_size), tmp_buf); - if (!err) - { - /* Copy it and store it in the disk cache. */ - grub_memcpy (buf, tmp_buf + offset, size); - grub_disk_cache_store (disk->dev->id, disk->id, - sector, tmp_buf); - grub_free (tmp_buf); - return GRUB_ERR_NONE; - } - } - - grub_free (tmp_buf); - grub_errno = GRUB_ERR_NONE; - - { - /* Uggh... Failed. Instead, just read necessary data. */ - unsigned num; - grub_disk_addr_t aligned_sector; - - sector += (offset >> GRUB_DISK_SECTOR_BITS); - offset &= ((1 << GRUB_DISK_SECTOR_BITS) - 1); - aligned_sector = (sector & ~((1ULL << (disk->log_sector_size - - GRUB_DISK_SECTOR_BITS)) - - 1)); - offset += ((sector - aligned_sector) << GRUB_DISK_SECTOR_BITS); - num = ((size + offset + (1ULL << (disk->log_sector_size)) - - 1) >> (disk->log_sector_size)); - - tmp_buf = grub_malloc (num << disk->log_sector_size); - if (!tmp_buf) - return grub_errno; - - if ((disk->dev->disk_read) (disk, grub_disk_to_native_sector (disk, aligned_sector), - num, tmp_buf)) - { - grub_error_push (); - grub_dprintf ("disk", "%s read failed\n", disk->name); - grub_error_pop (); - grub_free (tmp_buf); - return grub_errno; - } - grub_memcpy (buf, tmp_buf + offset, size); - grub_free (tmp_buf); - return GRUB_ERR_NONE; - } -} - -static grub_err_t -grub_disk_read_small (grub_disk_t disk, grub_disk_addr_t sector, - grub_off_t offset, grub_size_t size, void *buf) -{ - grub_err_t err; - - err = grub_disk_read_small_real (disk, sector, offset, size, buf); - if (err) - return err; - if (disk->read_hook) - err = (disk->read_hook) (sector + (offset >> GRUB_DISK_SECTOR_BITS), - offset & (GRUB_DISK_SECTOR_SIZE - 1), - size, buf, disk->read_hook_data); - return err; -} - -/* 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) -{ - grub_err_t err = GRUB_ERR_NONE; - - /* First of all, check if the region is within the disk. */ - if (grub_disk_adjust_range (disk, §or, &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; - } - - if (++read_recursion_depth >= MAX_READ_RECURSION_DEPTH) - { - grub_error (GRUB_ERR_RECURSION_DEPTH, "grub_disk_read(): Maximum recursion depth exceeded"); - goto error; - } - - /* First read until first cache boundary. */ - if (offset || (sector & (GRUB_DISK_CACHE_SIZE - 1))) - { - grub_disk_addr_t start_sector; - grub_size_t pos; - grub_size_t len; - - start_sector = sector & ~((grub_disk_addr_t) GRUB_DISK_CACHE_SIZE - 1); - pos = (sector - start_sector) << GRUB_DISK_SECTOR_BITS; - len = ((GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS) - - pos - offset); - if (len > size) - len = size; - err = grub_disk_read_small (disk, start_sector, - offset + pos, len, buf); - if (err) - goto error; - buf = (char *) buf + len; - size -= len; - offset += len; - sector += (offset >> GRUB_DISK_SECTOR_BITS); - offset &= ((1 << GRUB_DISK_SECTOR_BITS) - 1); - } - - /* Until SIZE is zero... */ - while (size >= (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS)) - { - char *data = NULL; - grub_disk_addr_t agglomerate; - - /* agglomerate read until we find a first cached entry. */ - for (agglomerate = 0; agglomerate - < (size >> (GRUB_DISK_SECTOR_BITS + GRUB_DISK_CACHE_BITS)) - && agglomerate < disk->max_agglomerate; - agglomerate++) - { - data = grub_disk_cache_fetch (disk->dev->id, disk->id, - sector + (agglomerate - << GRUB_DISK_CACHE_BITS)); - if (data) - break; - } - - if (data) - { - grub_memcpy ((char *) buf - + (agglomerate << (GRUB_DISK_CACHE_BITS - + GRUB_DISK_SECTOR_BITS)), - data, GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); - grub_disk_cache_unlock (disk->dev->id, disk->id, - sector + (agglomerate - << GRUB_DISK_CACHE_BITS)); - } - - if (agglomerate) - { - grub_disk_addr_t i; - - err = (disk->dev->disk_read) (disk, grub_disk_to_native_sector (disk, sector), - agglomerate << (GRUB_DISK_CACHE_BITS - + GRUB_DISK_SECTOR_BITS - - disk->log_sector_size), - buf); - if (err) - goto error; - - for (i = 0; i < agglomerate; i ++) - grub_disk_cache_store (disk->dev->id, disk->id, - sector + (i << GRUB_DISK_CACHE_BITS), - (char *) buf - + (i << (GRUB_DISK_CACHE_BITS - + GRUB_DISK_SECTOR_BITS))); - - - if (disk->read_hook) - (disk->read_hook) (sector, 0, agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS), - buf, disk->read_hook_data); - - sector += agglomerate << GRUB_DISK_CACHE_BITS; - size -= agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS); - buf = (char *) buf - + (agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS)); - } - - if (data) - { - if (disk->read_hook) - (disk->read_hook) (sector, 0, (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS), - buf, disk->read_hook_data); - sector += GRUB_DISK_CACHE_SIZE; - buf = (char *) buf + (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); - size -= (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS); - } - } - - /* And now read the last part. */ - if (size) - { - err = grub_disk_read_small (disk, sector, 0, size, buf); - if (err) - goto error; - } - - err = grub_errno; - - error: - read_recursion_depth--; - return err; -} - -grub_uint64_t -grub_disk_native_sectors (grub_disk_t disk) -{ - if (disk->partition) - return grub_partition_get_len (disk->partition); - else if (disk->total_sectors != GRUB_DISK_SIZE_UNKNOWN) - return disk->total_sectors << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); - else - return GRUB_DISK_SIZE_UNKNOWN; -} diff --git a/grub-core/kern/disk_common.c b/grub-core/kern/disk_common.c deleted file mode 100644 index ab6cd0c2b..000000000 --- a/grub-core/kern/disk_common.c +++ /dev/null @@ -1,60 +0,0 @@ -/* 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; - grub_disk_addr_t total_sectors; - - *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, - N_("attempt to read or write outside of partition")); - - *sector += start; - } - - /* Transform total_sectors to number of 512B blocks. */ - total_sectors = disk->total_sectors << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); - - /* - * Some drivers have problems with disks above reasonable sizes. - * Clamp the size to GRUB_DISK_MAX_SECTORS. Just one condition is enough - * since GRUB_DISK_SIZE_UNKNOWN is always above GRUB_DISK_MAX_SECTORS, - * assuming a maximum 4 KiB sector size. - */ - if (total_sectors > GRUB_DISK_MAX_SECTORS) - total_sectors = GRUB_DISK_MAX_SECTORS; - - if ((total_sectors <= *sector - || ((*offset + size + GRUB_DISK_SECTOR_SIZE - 1) - >> GRUB_DISK_SECTOR_BITS) > total_sectors - *sector)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("attempt to read or write outside of disk `%s'"), disk->name); - - return GRUB_ERR_NONE; -} - -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); -} diff --git a/grub-core/kern/efi/debug.c b/grub-core/kern/efi/debug.c deleted file mode 100644 index 5d2ab1a36..000000000 --- a/grub-core/kern/efi/debug.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* debug.c - aides for debugging the EFI application */ - -#include -#include -#include - -static grub_err_t -grub_cmd_gdbinfo (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - grub_efi_print_gdb_info (); - return 0; -} - -void -grub_efi_register_debug_commands (void) -{ - grub_register_command ("gdbinfo", grub_cmd_gdbinfo, 0, - N_("Print infomation useful for GDB debugging")); -} diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c deleted file mode 100644 index b93ae3aba..000000000 --- a/grub-core/kern/efi/efi.c +++ /dev/null @@ -1,1051 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* 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_guid_t console_control_guid = GRUB_EFI_CONSOLE_CONTROL_GUID; -static grub_guid_t loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID; -static grub_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID; - -void * -grub_efi_locate_protocol (grub_guid_t *protocol, void *registration) -{ - void *interface; - grub_efi_status_t status; - - status = 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_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 = 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 = 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_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 = b->open_protocol (handle, - protocol, - &interface, - grub_efi_image_handle, - 0, - attributes); - if (status != GRUB_EFI_SUCCESS) - return 0; - - return interface; -} - -grub_efi_status_t -grub_efi_close_protocol (grub_efi_handle_t handle, grub_guid_t *protocol) -{ - grub_efi_boot_services_t *b = grub_efi_system_table->boot_services; - - return b->close_protocol (handle, protocol, grub_efi_image_handle, NULL); -} - -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 (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 (c->set_mode (c, new_mode) != GRUB_EFI_SUCCESS) - return 0; - - return 1; -} - -void -grub_efi_stall (grub_efi_uintn_t microseconds) -{ - 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_reboot (void) -{ - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN | - GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY); - grub_efi_system_table->runtime_services->reset_system (GRUB_EFI_RESET_COLD, - GRUB_EFI_SUCCESS, 0, - NULL); - for (;;) ; -} - -void -grub_exit (void) -{ - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); - grub_efi_system_table->boot_services->exit (grub_efi_image_handle, - GRUB_EFI_SUCCESS, 0, 0); - for (;;) ; -} - -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 = 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_err_t -grub_efi_set_variable_with_attributes (const char *var, const grub_guid_t *guid, - void *data, grub_size_t datasize, grub_efi_uint32_t attributes) -{ - grub_efi_status_t status; - grub_efi_runtime_services_t *r; - grub_efi_char16_t *var16; - - grub_utf8_to_utf16_alloc (var, &var16, NULL); - - if (var16 == NULL) - return grub_errno; - - r = grub_efi_system_table->runtime_services; - - status = r->set_variable (var16, guid, attributes, datasize, data); - grub_free (var16); - if (status == GRUB_EFI_SUCCESS) - return GRUB_ERR_NONE; - - return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var); -} - -grub_err_t -grub_efi_set_variable (const char *var, const grub_guid_t *guid, - void *data, grub_size_t datasize) -{ - return grub_efi_set_variable_with_attributes (var, guid, data, datasize, - GRUB_EFI_VARIABLE_NON_VOLATILE - | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS - | GRUB_EFI_VARIABLE_RUNTIME_ACCESS); -} - -grub_efi_status_t -grub_efi_get_variable_with_attributes (const char *var, - const grub_guid_t *guid, - grub_size_t *datasize_out, - void **data_out, - grub_efi_uint32_t *attributes) -{ - grub_efi_status_t status; - grub_efi_uintn_t datasize = 0; - grub_efi_runtime_services_t *r; - grub_efi_char16_t *var16; - void *data; - - *data_out = NULL; - *datasize_out = 0; - - grub_utf8_to_utf16_alloc (var, &var16, NULL); - if (var16 == NULL) - return grub_errno; - - r = grub_efi_system_table->runtime_services; - - status = r->get_variable (var16, guid, NULL, &datasize, NULL); - - if (status != GRUB_EFI_BUFFER_TOO_SMALL || !datasize) - { - grub_free (var16); - return status; - } - - data = grub_malloc (datasize); - if (!data) - { - grub_free (var16); - return GRUB_EFI_OUT_OF_RESOURCES; - } - - status = r->get_variable (var16, guid, attributes, &datasize, data); - grub_free (var16); - - if (status == GRUB_EFI_SUCCESS) - { - *data_out = data; - *datasize_out = datasize; - return status; - } - - grub_free (data); - return status; -} - -grub_err_t -grub_efi_set_variable_to_string (const char *name, const grub_guid_t *guid, - const char *value, grub_efi_uint32_t attributes) -{ - grub_efi_char16_t *value_16; - grub_ssize_t len16; - grub_err_t status; - - len16 = grub_utf8_to_utf16_alloc (value, &value_16, NULL); - - if (len16 < 0) - return grub_errno; - - status = grub_efi_set_variable_with_attributes (name, guid, - (void *) value_16, (len16 + 1) * sizeof (value_16[0]), - attributes); - - grub_free (value_16); - - return status; -} - -grub_efi_status_t -grub_efi_get_variable (const char *var, const grub_guid_t *guid, - grub_size_t *datasize_out, void **data_out) -{ - return grub_efi_get_variable_with_attributes (var, guid, datasize_out, data_out, NULL); -} - -#pragma GCC diagnostic ignored "-Wcast-align" - -/* 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_efi_section_addr (const char *section_name) -{ - grub_efi_loaded_image_t *image; - struct grub_msdos_image_header *header; - struct grub_pe_image_header *pe_image_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; - pe_image_header - = (struct grub_pe_image_header *) ((char *) header - + header->pe_image_header_offset); - coff_header = &(pe_image_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, section_name) == 0) - break; - } - - if (i == coff_header->num_sections) - { - grub_dprintf("sections", "section %d is last section; invalid.\n", i); - return 0; - } - - info = (struct grub_module_info *) ((char *) image->image_base - + section->virtual_address); - if (section->name[0] != '.' && info->magic != GRUB_MODULE_MAGIC) - { - grub_dprintf("sections", - "section %d has bad magic %08x, should be %08x\n", - i, info->magic, GRUB_MODULE_MAGIC); - return 0; - } - - grub_dprintf("sections", "returning section info for section %d: \"%s\"\n", - i, section->name); - return (grub_addr_t) info; -} - -#pragma GCC diagnostic error "-Wcast-align" - -char * -grub_efi_get_filename (grub_efi_device_path_t *dp0) -{ - char *name = 0, *p, *pi; - grub_size_t filesize = 0; - grub_efi_device_path_t *dp; - - if (!dp0) - return NULL; - - dp = dp0; - - while (dp) - { - 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; - if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE - && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE) - { - grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); - - if (len < 4) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, - "malformed EFI Device Path node has length=%d", len); - return NULL; - } - len = (len - 4) / sizeof (grub_efi_char16_t); - filesize += GRUB_MAX_UTF8_PER_UTF16 * len + 2; - } - - dp = GRUB_EFI_NEXT_DEVICE_PATH (dp); - } - - if (!filesize) - return NULL; - - dp = dp0; - - p = name = grub_malloc (filesize); - if (!name) - return NULL; - - while (dp) - { - 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; - grub_efi_char16_t *dup_name; - - *p++ = '/'; - - len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); - if (len < 4) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, - "malformed EFI Device Path node has length=%d", len); - grub_free (name); - return NULL; - } - - len = (len - 4) / sizeof (grub_efi_char16_t); - fp = (grub_efi_file_path_device_path_t *) dp; - /* According to EFI spec Path Name is NULL terminated */ - while (len > 0 && fp->path_name[len - 1] == 0) - len--; - - dup_name = grub_calloc (len, sizeof (*dup_name)); - if (!dup_name) - { - grub_free (name); - return NULL; - } - p = (char *) grub_utf16_to_utf8 ((unsigned char *) p, - grub_memcpy (dup_name, fp->path_name, len * sizeof (*dup_name)), - len); - grub_free (dup_name); - } - - dp = GRUB_EFI_NEXT_DEVICE_PATH (dp); - } - - *p = '\0'; - - for (pi = name, p = name; *pi;) - { - /* EFI breaks paths with backslashes. */ - if (*pi == '\\' || *pi == '/') - { - *p++ = '/'; - while (*pi == '\\' || *pi == '/') - pi++; - continue; - } - *p++ = *pi++; - } - *p = '\0'; - - 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); -} - -/* Return the device path node right before the end node. */ -grub_efi_device_path_t * -grub_efi_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; -} - -/* Duplicate a device path. */ -grub_efi_device_path_t * -grub_efi_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)) - { - grub_size_t len = GRUB_EFI_DEVICE_PATH_LENGTH (p); - - /* - * In the event that we find a node that's completely garbage, for - * example if we get to 0x7f 0x01 0x02 0x00 ... (EndInstance with a size - * of 2), GRUB_EFI_END_ENTIRE_DEVICE_PATH() will be true and - * GRUB_EFI_NEXT_DEVICE_PATH() will return NULL, so we won't continue, - * and neither should our consumers, but there won't be any error raised - * even though the device path is junk. - * - * This keeps us from passing junk down back to our caller. - */ - if (len < 4) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, - "malformed EFI Device Path node has length=%" PRIuGRUB_SIZE, len); - return NULL; - } - - total_size += len; - 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; -} - -static void -dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor) -{ - grub_uint32_t vendor_data_len = vendor->header.length - sizeof (*vendor); - grub_printf ("/%sVendor(%pG)[%x: ", type, &vendor->vendor_guid, vendor_data_len); - if (vendor->header.length > sizeof (*vendor)) - { - grub_uint32_t i; - for (i = 0; i < vendor_data_len; i++) - grub_printf ("%02x ", vendor->vendor_defined_data[i]); - } - grub_printf ("]"); -} - - -/* 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 (GRUB_EFI_DEVICE_PATH_VALID (dp)) - { - 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_efi_pci_device_path_t *) dp; - 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_efi_pccard_device_path_t *) dp; - 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_efi_memory_mapped_device_path_t *) dp; - 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: - dump_vendor_path ("Hardware", - (grub_efi_vendor_device_path_t *) dp); - break; - case GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE: - { - grub_efi_controller_device_path_t *controller - = (grub_efi_controller_device_path_t *) dp; - 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_efi_acpi_device_path_t *) dp; - 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_efi_expanded_acpi_device_path_t *) dp; - 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_efi_atapi_device_path_t *) dp; - 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_efi_scsi_device_path_t *) dp; - 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_efi_fibre_channel_device_path_t *) dp; - 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_efi_1394_device_path_t *) dp; - 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_efi_usb_device_path_t *) dp; - grub_printf ("/USB(%x,%x)", - (unsigned) usb->parent_port_number, - (unsigned) usb->usb_interface); - } - break; - case GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE: - { - grub_efi_usb_class_device_path_t *usb_class - = (grub_efi_usb_class_device_path_t *) dp; - 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_efi_i2o_device_path_t *) dp; - 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_efi_mac_address_device_path_t *) dp; - 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_efi_ipv4_device_path_t *) dp; - 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_efi_ipv6_device_path_t *) dp; - 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_efi_infiniband_device_path_t *) dp; - 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_efi_uart_device_path_t *) dp; - 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_SATA_DEVICE_PATH_SUBTYPE: - { - grub_efi_sata_device_path_t *sata; - sata = (grub_efi_sata_device_path_t *) dp; - grub_printf ("/Sata(%x,%x,%x)", - sata->hba_port, - sata->multiplier_port, - sata->lun); - } - break; - case GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE: - { - grub_efi_vlan_device_path_t *vlan; - vlan = (grub_efi_vlan_device_path_t *) dp; - grub_printf ("/Vlan(%u)", vlan->vlan_id); - } - break; - - case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE: - dump_vendor_path ("Messaging", - (grub_efi_vendor_device_path_t *) dp); - 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_efi_hard_drive_device_path_t *) dp; - 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->partmap_type, - (unsigned) hd->signature_type); - } - break; - case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE: - { - grub_efi_cdrom_device_path_t *cd - = (grub_efi_cdrom_device_path_t *) dp; - 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: - dump_vendor_path ("Media", - (grub_efi_vendor_device_path_t *) dp); - break; - case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE: - { - grub_efi_file_path_device_path_t *fp; - grub_uint8_t *buf; - fp = (grub_efi_file_path_device_path_t *) dp; - buf = grub_malloc ((len - 4) * 2 + 1); - if (buf) - { - grub_efi_char16_t *dup_name = grub_malloc (len - 4); - if (!dup_name) - { - grub_errno = GRUB_ERR_NONE; - grub_printf ("/File((null))"); - grub_free (buf); - break; - } - *grub_utf16_to_utf8 (buf, grub_memcpy (dup_name, fp->path_name, len - 4), - (len - 4) / sizeof (grub_efi_char16_t)) - = '\0'; - grub_free (dup_name); - } - else - grub_errno = GRUB_ERR_NONE; - grub_printf ("/File(%s)", buf); - grub_free (buf); - } - break; - case GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE: - { - grub_efi_protocol_device_path_t *proto - = (grub_efi_protocol_device_path_t *) dp; - grub_printf ("/Protocol(%pG)",&proto->guid); - } - 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_efi_bios_device_path_t *) dp; - 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); - } -} - -/* Compare device paths. */ -int -grub_efi_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; - - if (dp1 == dp2) - return 0; - - while (GRUB_EFI_DEVICE_PATH_VALID (dp1) && GRUB_EFI_DEVICE_PATH_VALID (dp2)) - { - 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); - } - - /* - * There's no "right" answer here, but we probably don't want to call a valid - * dp and an invalid dp equal, so pick one way or the other. - */ - if (GRUB_EFI_DEVICE_PATH_VALID (dp1) && !GRUB_EFI_DEVICE_PATH_VALID (dp2)) - return 1; - else if (!GRUB_EFI_DEVICE_PATH_VALID (dp1) && GRUB_EFI_DEVICE_PATH_VALID (dp2)) - return -1; - - return 0; -} - -void * -grub_efi_find_configuration_table (const grub_guid_t *target_guid) -{ - unsigned i; - - for (i = 0; i < grub_efi_system_table->num_table_entries; i++) - { - grub_packed_guid_t *guid = - &grub_efi_system_table->configuration_table[i].vendor_guid; - - if (! grub_memcmp (guid, target_guid, sizeof (grub_guid_t))) - return (void *) - grub_efi_system_table->configuration_table[i].vendor_table; - } - - return 0; -} diff --git a/grub-core/kern/efi/fdt.c b/grub-core/kern/efi/fdt.c deleted file mode 100644 index 15a495a34..000000000 --- a/grub-core/kern/efi/fdt.c +++ /dev/null @@ -1,35 +0,0 @@ -/* fdt.c - EFI Flattened Device Tree interaction */ -/* - * 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 . - */ - -#include -#include - -void * -grub_efi_get_firmware_fdt (void) -{ - static grub_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID; - void *firmware_fdt = grub_efi_find_configuration_table (&fdt_guid); - - if (firmware_fdt) { - grub_dprintf ("linux", "found registered FDT @ %p\n", firmware_fdt); - } else { - grub_dprintf ("linux", "not found registered FDT\n"); - } - return firmware_fdt; -} diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c deleted file mode 100644 index 1637077e1..000000000 --- a/grub-core/kern/efi/init.c +++ /dev/null @@ -1,160 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef GRUB_STACK_PROTECTOR - -static grub_efi_char16_t stack_chk_fail_msg[] = - L"* GRUB: STACK SMASHING DETECTED!!! *\r\n" - L"* GRUB: ABORTED!!! *\r\n" - L"* GRUB: REBOOTING IN 5 SECONDS... *\r\n"; - -static grub_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID; - -/* Initialize canary in case there is no RNG protocol. */ -grub_addr_t __stack_chk_guard = (grub_addr_t) GRUB_STACK_PROTECTOR_INIT; - -void __attribute__ ((noreturn)) -__stack_chk_fail (void) -{ - grub_efi_simple_text_output_interface_t *o; - - /* - * Use ConOut here rather than StdErr. StdErr only goes to - * the serial console, at least on EDK2. - */ - o = grub_efi_system_table->con_out; - o->output_string (o, stack_chk_fail_msg); - - grub_efi_system_table->boot_services->stall (5000000); - grub_efi_system_table->runtime_services->reset_system (GRUB_EFI_RESET_SHUTDOWN, - GRUB_EFI_ABORTED, 0, NULL); - - /* - * We shouldn't get here. It's unsafe to return because the stack - * is compromised and this function is noreturn, so just busy - * loop forever. - */ - do - { - /* Do not optimize out the loop. */ - asm volatile (""); - } - while (1); -} - -grub_addr_t -grub_stack_protector_init (void) -{ - grub_efi_rng_protocol_t *rng; - - /* Set up the stack canary. Make errors here non-fatal for now. */ - rng = grub_efi_locate_protocol (&rng_protocol_guid, NULL); - if (rng != NULL) - { - grub_efi_status_t status; - grub_addr_t guard = 0; - - status = rng->get_rng (rng, NULL, sizeof (guard) - 1, - (grub_efi_uint8_t *) &guard); - if (status == GRUB_EFI_SUCCESS) - return guard; - } - return 0; -} -#endif - -grub_addr_t grub_modbase; - -void -grub_efi_init (void) -{ - grub_modbase = grub_efi_section_addr ("mods"); - /* First of all, initialize the console so that GRUB can display - messages. */ - grub_console_init (); - - /* Initialize the memory management system. */ - grub_efi_mm_init (); - - /* - * Lockdown the GRUB and register the shim_lock verifier - * if the UEFI Secure Boot is enabled. - */ - if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) - { - grub_lockdown (); - grub_shim_lock_verifier_setup (); - } - - grub_efi_system_table->boot_services->set_watchdog_timer (0, 0, 0, NULL); - - grub_efidisk_init (); - - grub_efi_register_debug_commands (); -} - -void (*grub_efi_net_config) (grub_efi_handle_t hnd, - char **device, - char **path); - -void -grub_machine_get_bootlocation (char **device, char **path) -{ - grub_efi_loaded_image_t *image = NULL; - char *p; - - image = grub_efi_get_loaded_image (grub_efi_image_handle); - if (!image) - return; - *device = grub_efidisk_get_device_name (image->device_handle); - if (!*device && grub_efi_net_config) - { - grub_efi_net_config (image->device_handle, device, path); - return; - } - - *path = grub_efi_get_filename (image->file_path); - if (*path) - { - /* Get the directory. */ - p = grub_strrchr (*path, '/'); - if (p) - *p = '\0'; - } -} - -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 deleted file mode 100644 index df238b165..000000000 --- a/grub-core/kern/efi/mm.c +++ /dev/null @@ -1,806 +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 . - */ - -#include -#include -#include -#include -#include - -#if defined (__i386__) || defined (__x86_64__) -#include -#endif - -#define NEXT_MEMORY_DESCRIPTOR(desc, size) \ - ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) - -#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) -#define BYTES_TO_PAGES_DOWN(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 - -/* The default heap size for GRUB itself in bytes. */ -#define DEFAULT_HEAP_SIZE 0x2000000 - -static void *finish_mmap_buf = 0; -static grub_efi_uintn_t finish_mmap_size = 0; -static grub_efi_uintn_t finish_key = 0; -static grub_efi_uintn_t finish_desc_size; -static grub_efi_uint32_t finish_desc_version; -int grub_efi_is_finished = 0; - -/* - * We need to roll back EFI allocations on exit. Remember allocations that - * we'll free on exit. - */ -struct efi_allocation; -struct efi_allocation { - grub_efi_physical_address_t address; - grub_efi_uint64_t pages; - struct efi_allocation *next; -}; -static struct efi_allocation *efi_allocated_memory; - -static void -grub_efi_store_alloc (grub_efi_physical_address_t address, - grub_efi_uintn_t pages) -{ - grub_efi_boot_services_t *b; - struct efi_allocation *alloc; - grub_efi_status_t status; - - b = grub_efi_system_table->boot_services; - status = b->allocate_pool (GRUB_EFI_LOADER_DATA, - sizeof(*alloc), (void**)&alloc); - - if (status == GRUB_EFI_SUCCESS) - { - alloc->next = efi_allocated_memory; - alloc->address = address; - alloc->pages = pages; - efi_allocated_memory = alloc; - } - else - grub_printf ("Could not malloc memory to remember EFI allocation. " - "Exiting GRUB won't free all memory.\n"); -} - -static void -grub_efi_drop_alloc (grub_efi_physical_address_t address, - grub_efi_uintn_t pages) -{ - struct efi_allocation *ea, *eap; - grub_efi_boot_services_t *b; - - b = grub_efi_system_table->boot_services; - - for (eap = NULL, ea = efi_allocated_memory; ea; eap = ea, ea = ea->next) - { - if (ea->address != address) - continue; - if (ea->pages != pages) - grub_fatal ("grub_efi_drop_alloc() called with wrong page count"); - - /* Remove the current entry from the list. */ - if (eap) - eap->next = ea->next; - else - efi_allocated_memory = ea->next; - - /* Then free the memory backing it. */ - b->free_pool (ea); - - /* And leave, we're done. */ - break; - } -} - -/* Allocate pages. Return the pointer to the first of allocated pages. */ -void * -grub_efi_allocate_pages_real (grub_efi_physical_address_t address, - grub_efi_uintn_t pages, - grub_efi_allocate_type_t alloctype, - grub_efi_memory_type_t memtype) -{ - grub_efi_status_t status; - grub_efi_boot_services_t *b; - - /* Limit the memory access to less than 4GB for 32-bit platforms. */ - if (address > GRUB_EFI_MAX_USABLE_ADDRESS) - { - char inv_addr[17], max_addr[17]; /* log16(2^64) = 16, plus NUL. */ - - grub_snprintf (inv_addr, sizeof (inv_addr) - 1, "%" PRIxGRUB_UINT64_T, - address); - grub_snprintf (max_addr, sizeof (max_addr) - 1, "%" PRIxGRUB_UINT64_T, - (grub_efi_uint64_t) GRUB_EFI_MAX_USABLE_ADDRESS); - grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("invalid memory address (0x%s > 0x%s)"), inv_addr, max_addr); - return NULL; - } - - b = grub_efi_system_table->boot_services; - status = b->allocate_pages (alloctype, memtype, pages, &address); - if (status != GRUB_EFI_SUCCESS) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - return NULL; - } - - if (address == 0) - { - /* Uggh, the address 0 was allocated... This is too annoying, - so reallocate another one. */ - address = GRUB_EFI_MAX_USABLE_ADDRESS; - status = b->allocate_pages (alloctype, memtype, pages, &address); - b->free_pages (0, pages); - if (status != GRUB_EFI_SUCCESS) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - return NULL; - } - } - - grub_efi_store_alloc (address, pages); - - return (void *) ((grub_addr_t) address); -} - -void * -grub_efi_allocate_any_pages (grub_efi_uintn_t pages) -{ - return grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, - pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, - GRUB_EFI_LOADER_DATA); -} - -void * -grub_efi_allocate_fixed (grub_efi_physical_address_t address, - grub_efi_uintn_t pages) -{ - return grub_efi_allocate_pages_real (address, pages, - GRUB_EFI_ALLOCATE_ADDRESS, - GRUB_EFI_LOADER_DATA); -} - -/* 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; - - b = grub_efi_system_table->boot_services; - b->free_pages (address, pages); - - grub_efi_drop_alloc (address, pages); -} - -#if defined (__i386__) || defined (__x86_64__) - -/* Helper for stop_broadcom. */ -static int -find_card (grub_pci_device_t dev, grub_pci_id_t pciid, - void *data __attribute__ ((unused))) -{ - grub_pci_address_t addr; - grub_uint8_t cap; - grub_uint16_t pm_state; - - if ((pciid & 0xffff) != GRUB_PCI_VENDOR_BROADCOM) - return 0; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - if (grub_pci_read (addr) >> 24 != GRUB_PCI_CLASS_NETWORK) - return 0; - cap = grub_pci_find_capability (dev, GRUB_PCI_CAP_POWER_MANAGEMENT); - if (!cap) - return 0; - addr = grub_pci_make_address (dev, cap + 4); - pm_state = grub_pci_read_word (addr); - pm_state = pm_state | 0x03; - grub_pci_write_word (addr, pm_state); - grub_pci_read_word (addr); - return 0; -} - -static void -stop_broadcom (void) -{ - grub_pci_iterate (find_card, NULL); -} - -#endif - -grub_err_t -grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf, - grub_efi_uintn_t *map_key, - grub_efi_uintn_t *efi_desc_size, - grub_efi_uint32_t *efi_desc_version) -{ - grub_efi_boot_services_t *b; - grub_efi_status_t status; - -#if defined (__i386__) || defined (__x86_64__) - const grub_uint16_t apple[] = { 'A', 'p', 'p', 'l', 'e' }; - int is_apple; - - is_apple = (grub_memcmp (grub_efi_system_table->firmware_vendor, - apple, sizeof (apple)) == 0); -#endif - - while (1) - { - if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key, - &finish_desc_size, &finish_desc_version) < 0) - return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map"); - - if (outbuf && *outbuf_size < finish_mmap_size) - return grub_error (GRUB_ERR_IO, "memory map buffer is too small"); - - finish_mmap_buf = grub_malloc (finish_mmap_size); - if (!finish_mmap_buf) - return grub_errno; - - if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key, - &finish_desc_size, &finish_desc_version) <= 0) - { - grub_free (finish_mmap_buf); - finish_mmap_buf = NULL; - return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map"); - } - - b = grub_efi_system_table->boot_services; - status = b->exit_boot_services (grub_efi_image_handle, finish_key); - if (status == GRUB_EFI_SUCCESS) - break; - - if (status != GRUB_EFI_INVALID_PARAMETER) - { - grub_free (finish_mmap_buf); - finish_mmap_buf = NULL; - return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services"); - } - - grub_free (finish_mmap_buf); - finish_mmap_buf = NULL; - grub_printf ("Trying to terminate EFI services again\n"); - } - grub_efi_is_finished = 1; - if (outbuf_size) - *outbuf_size = finish_mmap_size; - if (outbuf) - grub_memcpy (outbuf, finish_mmap_buf, finish_mmap_size); - if (map_key) - *map_key = finish_key; - if (efi_desc_size) - *efi_desc_size = finish_desc_size; - if (efi_desc_version) - *efi_desc_version = finish_desc_version; - - /* - * We cannot request new memory regions from the EFI Boot Services anymore. - * FIXME: Can we completely avoid memory allocations after this? - */ - grub_mm_add_region_fn = NULL; - -#if defined (__i386__) || defined (__x86_64__) - if (is_apple) - stop_broadcom (); -#endif - - return GRUB_ERR_NONE; -} - -/* - * To obtain the UEFI memory map, we must pass a buffer of sufficient size - * to hold the entire map. This function returns a sane start value for - * buffer size. - */ -grub_efi_uintn_t -grub_efi_find_mmap_size (void) -{ - grub_efi_uintn_t mmap_size = 0; - grub_efi_uintn_t desc_size; - - if (grub_efi_get_memory_map (&mmap_size, NULL, NULL, &desc_size, 0) < 0) - { - grub_error (GRUB_ERR_IO, "cannot get EFI memory map size"); - return 0; - } - - /* - * Add an extra page, since UEFI can alter the memory map itself on - * callbacks or explicit calls, including console output. - */ - return ALIGN_UP (mmap_size + GRUB_EFI_PAGE_SIZE, GRUB_EFI_PAGE_SIZE); -} - -/* 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; - grub_efi_uintn_t size; - - if (grub_efi_is_finished) - { - int ret = 1; - - if (memory_map != NULL) - { - if (*memory_map_size < finish_mmap_size) - { - grub_memcpy (memory_map, finish_mmap_buf, *memory_map_size); - ret = 0; - } - else - grub_memcpy (memory_map, finish_mmap_buf, finish_mmap_size); - } - else - { - /* - * Incomplete, no buffer to copy into, same as - * GRUB_EFI_BUFFER_TOO_SMALL below. - */ - ret = 0; - } - *memory_map_size = finish_mmap_size; - if (map_key) - *map_key = finish_key; - if (descriptor_size) - *descriptor_size = finish_desc_size; - if (descriptor_version) - *descriptor_version = finish_desc_version; - return ret; - } - - /* Allow some parameters to be missing. */ - if (! map_key) - map_key = &key; - if (! descriptor_version) - descriptor_version = &version; - if (! descriptor_size) - descriptor_size = &size; - - b = grub_efi_system_table->boot_services; - status = b->get_memory_map (memory_map_size, memory_map, map_key, - descriptor_size, descriptor_version); - if (*descriptor_size == 0) - *descriptor_size = sizeof (grub_efi_memory_descriptor_t); - 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 1 - && desc->physical_start <= GRUB_EFI_MAX_USABLE_ADDRESS -#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 1 - if (BYTES_TO_PAGES (filtered_desc->physical_start) - + filtered_desc->num_pages - > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS)) - filtered_desc->num_pages - = (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS) - - 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; -} - -/* Add memory regions. */ -static grub_err_t -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, - unsigned int flags) -{ - 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 && (flags & GRUB_MM_ADD_REGION_CONSECUTIVE)) - continue; - - if (pages > required_pages) - { - start += PAGES_TO_BYTES (pages - required_pages); - pages = required_pages; - } - - addr = grub_efi_allocate_pages_real (start, pages, - GRUB_EFI_ALLOCATE_ADDRESS, - GRUB_EFI_LOADER_CODE); - if (! addr) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Memory starting at %p (%u pages) marked as free, but EFI would not allocate", - (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) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "could not allocate all requested memory: %" PRIuGRUB_UINT64_T " pages still required after iterating EFI memory map", - required_pages); - - return GRUB_ERR_NONE; -} - -void -grub_efi_memory_fini (void) -{ - /* - * Free all stale allocations. grub_efi_free_pages() will remove - * the found entry from the list and it will always find the first - * list entry (efi_allocated_memory is the list start). Hence we - * remove all entries from the list until none is left altogether. - */ - while (efi_allocated_memory) - grub_efi_free_pages (efi_allocated_memory->address, - efi_allocated_memory->pages); -} - -#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 - -static grub_err_t -grub_efi_mm_add_regions (grub_size_t required_bytes, unsigned int flags) -{ - 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 alloc_size; - grub_efi_uintn_t map_size; - grub_efi_uintn_t desc_size; - grub_err_t err; - int mm_status; - - /* Prepare a memory region to store two memory maps. */ - alloc_size = 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE); - memory_map = grub_efi_allocate_any_pages (alloc_size); - if (! memory_map) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory for memory map"); - - /* Obtain descriptors for available memory. */ - map_size = MEMORY_MAP_SIZE; - - mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0); - - if (mm_status == 0) - { - grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) memory_map, alloc_size); - - /* Freeing/allocating operations may increase memory map size. */ - map_size += desc_size * 32; - - alloc_size = 2 * BYTES_TO_PAGES (map_size); - memory_map = grub_efi_allocate_any_pages (alloc_size); - if (! memory_map) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory for new memory map"); - - mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0, - &desc_size, 0); - } - - if (mm_status < 0) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "error fetching memory map from EFI"); - - memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size); - - filtered_memory_map = memory_map_end; - - filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map, - desc_size, memory_map_end); - - /* 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. */ - err = add_memory_regions (filtered_memory_map, desc_size, - filtered_memory_map_end, - BYTES_TO_PAGES (required_bytes), - flags); - if (err != GRUB_ERR_NONE) - return err; - -#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_fatal ("Debug. "); -#endif - - /* Release the memory maps. */ - grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) memory_map, alloc_size); - - return GRUB_ERR_NONE; -} - -void -grub_efi_mm_init (void) -{ - if (grub_efi_mm_add_regions (DEFAULT_HEAP_SIZE, GRUB_MM_ADD_REGION_NONE) != GRUB_ERR_NONE) - grub_fatal ("%s", grub_errmsg); - grub_mm_add_region_fn = grub_efi_mm_add_regions; -} - -#if defined (__aarch64__) || defined (__arm__) || defined (__riscv) || \ - defined (__loongarch__) -grub_err_t -grub_efi_get_ram_base(grub_addr_t *base_addr) -{ - grub_efi_memory_descriptor_t *memory_map, *desc; - grub_efi_uintn_t memory_map_size, desc_size; - int ret; - - memory_map_size = grub_efi_find_mmap_size(); - - memory_map = grub_malloc (memory_map_size); - if (! memory_map) - return GRUB_ERR_OUT_OF_MEMORY; - ret = grub_efi_get_memory_map (&memory_map_size, memory_map, NULL, - &desc_size, NULL); - - if (ret < 1) - return GRUB_ERR_BUG; - - for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS; - (grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size); - desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) - if (desc->attribute & GRUB_EFI_MEMORY_WB) - *base_addr = grub_min (*base_addr, desc->physical_start); - - grub_free(memory_map); - - return GRUB_ERR_NONE; -} -#endif - -static grub_uint64_t -grub_mem_attrs_to_uefi_mem_attrs (grub_mem_attr_t attrs) -{ - grub_efi_uint64_t ret = GRUB_EFI_MEMORY_RP | GRUB_EFI_MEMORY_RO | GRUB_EFI_MEMORY_XP; - - if (attrs & GRUB_MEM_ATTR_R) - ret &= ~GRUB_EFI_MEMORY_RP; - - if (attrs & GRUB_MEM_ATTR_W) - ret &= ~GRUB_EFI_MEMORY_RO; - - if (attrs & GRUB_MEM_ATTR_X) - ret &= ~GRUB_EFI_MEMORY_XP; - - return ret; -} - -static grub_mem_attr_t -uefi_mem_attrs_to_grub_mem_attrs (grub_efi_uint64_t attrs) -{ - grub_mem_attr_t ret = GRUB_MEM_ATTR_R | GRUB_MEM_ATTR_W | GRUB_MEM_ATTR_X; - - if (attrs & GRUB_EFI_MEMORY_RP) - ret &= ~GRUB_MEM_ATTR_R; - - if (attrs & GRUB_EFI_MEMORY_RO) - ret &= ~GRUB_MEM_ATTR_W; - - if (attrs & GRUB_EFI_MEMORY_XP) - ret &= ~GRUB_MEM_ATTR_X; - - return ret; -} - -grub_err_t -grub_get_mem_attrs (grub_addr_t addr, grub_size_t size, grub_mem_attr_t *attrs) -{ - grub_efi_memory_attribute_protocol_t *proto; - grub_efi_physical_address_t physaddr = addr; - static grub_guid_t protocol_guid = GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID; - grub_efi_status_t efi_status; - grub_efi_uint64_t efi_attrs; - - if (physaddr & (GRUB_EFI_PAGE_SIZE - 1) || size & (GRUB_EFI_PAGE_SIZE - 1) || size == 0 || attrs == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "%s() called with invalid arguments", __FUNCTION__); - - proto = grub_efi_locate_protocol (&protocol_guid, 0); - if (proto == NULL) - { - /* No protocol -> do nothing, all memory is RWX in boot services */ - *attrs = GRUB_MEM_ATTR_R | GRUB_MEM_ATTR_W | GRUB_MEM_ATTR_X; - return GRUB_ERR_NONE; - } - - efi_status = proto->get_memory_attributes (proto, physaddr, size, &efi_attrs); - if (efi_status != GRUB_EFI_SUCCESS) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "%s() called with invalid arguments", __FUNCTION__); - - *attrs = uefi_mem_attrs_to_grub_mem_attrs (efi_attrs); - - grub_dprintf ("nx", "get 0x%" PRIxGRUB_ADDR "-0x%" PRIxGRUB_ADDR ":%c%c%c\n", - addr, addr + size - 1, - (*attrs & GRUB_MEM_ATTR_R) ? 'r' : '-', - (*attrs & GRUB_MEM_ATTR_W) ? 'w' : '-', - (*attrs & GRUB_MEM_ATTR_X) ? 'x' : '-'); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_update_mem_attrs (grub_addr_t addr, grub_size_t size, - grub_mem_attr_t set_attrs, grub_mem_attr_t clear_attrs) -{ - grub_efi_memory_attribute_protocol_t *proto; - grub_efi_physical_address_t physaddr = addr; - static grub_guid_t protocol_guid = GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID; - grub_efi_status_t efi_status = GRUB_EFI_SUCCESS; - grub_efi_uint64_t uefi_set_attrs, uefi_clear_attrs; - - if (physaddr & (GRUB_EFI_PAGE_SIZE - 1) || size & (GRUB_EFI_PAGE_SIZE - 1) || size == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "%s() called with invalid arguments", __FUNCTION__); - - proto = grub_efi_locate_protocol (&protocol_guid, 0); - if (proto == NULL) - /* No protocol -> do nothing, all memory is RWX in boot services */ - return GRUB_ERR_NONE; - - uefi_set_attrs = grub_mem_attrs_to_uefi_mem_attrs (set_attrs); - uefi_clear_attrs = grub_mem_attrs_to_uefi_mem_attrs (clear_attrs); - if (uefi_set_attrs) - efi_status = proto->set_memory_attributes (proto, physaddr, size, uefi_set_attrs); - if (efi_status == GRUB_EFI_SUCCESS && uefi_clear_attrs) - efi_status = proto->clear_memory_attributes (proto, physaddr, size, uefi_clear_attrs); - - if (efi_status != GRUB_EFI_SUCCESS) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "%s() called with invalid arguments", __FUNCTION__); - - grub_dprintf ("nx", "set +%s%s%s -%s%s%s on 0x%" PRIxGRUB_ADDR "-0x%" PRIxGRUB_ADDR "\n", - (set_attrs & GRUB_MEM_ATTR_R) ? "r" : "", - (set_attrs & GRUB_MEM_ATTR_W) ? "w" : "", - (set_attrs & GRUB_MEM_ATTR_X) ? "x" : "", - (clear_attrs & GRUB_MEM_ATTR_R) ? "r" : "", - (clear_attrs & GRUB_MEM_ATTR_W) ? "w" : "", - (clear_attrs & GRUB_MEM_ATTR_X) ? "x" : "", - addr, addr + size - 1); - - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c deleted file mode 100644 index 8d3e41360..000000000 --- a/grub-core/kern/efi/sb.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2020 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - * - * UEFI Secure Boot related checkings. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static grub_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID; - -static bool shim_lock_enabled = false; - -/* - * Determine whether we're in secure boot mode. - * - * Please keep the logic in sync with the Linux kernel, - * drivers/firmware/efi/libstub/secureboot.c:efi_get_secureboot(). - */ -grub_uint8_t -grub_efi_get_secureboot (void) -{ - static grub_guid_t efi_variable_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; - grub_efi_status_t status; - grub_efi_uint32_t attr = 0; - grub_size_t size = 0; - grub_uint8_t *secboot = NULL; - grub_uint8_t *setupmode = NULL; - grub_uint8_t *moksbstate = NULL; - grub_uint8_t secureboot = GRUB_EFI_SECUREBOOT_MODE_UNKNOWN; - const char *secureboot_str = "UNKNOWN"; - - status = grub_efi_get_variable ("SecureBoot", &efi_variable_guid, - &size, (void **) &secboot); - - if (status == GRUB_EFI_NOT_FOUND) - { - secureboot = GRUB_EFI_SECUREBOOT_MODE_DISABLED; - goto out; - } - - if (status != GRUB_EFI_SUCCESS) - goto out; - - status = grub_efi_get_variable ("SetupMode", &efi_variable_guid, - &size, (void **) &setupmode); - - if (status != GRUB_EFI_SUCCESS) - goto out; - - if ((*secboot == 0) || (*setupmode == 1)) - { - secureboot = GRUB_EFI_SECUREBOOT_MODE_DISABLED; - goto out; - } - - /* - * See if a user has put the shim into insecure mode. If so, and if the - * variable doesn't have the runtime attribute set, we might as well - * honor that. - */ - status = grub_efi_get_variable_with_attributes ("MokSBState", &shim_lock_guid, - &size, (void **) &moksbstate, &attr); - - /* If it fails, we don't care why. Default to secure. */ - if (status != GRUB_EFI_SUCCESS) - { - secureboot = GRUB_EFI_SECUREBOOT_MODE_ENABLED; - goto out; - } - - if (!(attr & GRUB_EFI_VARIABLE_RUNTIME_ACCESS) && *moksbstate == 1) - { - secureboot = GRUB_EFI_SECUREBOOT_MODE_DISABLED; - /* - * TODO: Replace this all with shim's LoadImage protocol, delegating policy to it. - * - * We need to set shim_lock_enabled here because we disabled secure boot - * validation *inside* shim but not in the firmware, so we set this variable - * here to trigger that code path, whereas the actual verifier is not enabled. - */ - shim_lock_enabled = true; - goto out; - } - - secureboot = GRUB_EFI_SECUREBOOT_MODE_ENABLED; - - out: - grub_free (moksbstate); - grub_free (setupmode); - grub_free (secboot); - - if (secureboot == GRUB_EFI_SECUREBOOT_MODE_DISABLED) - secureboot_str = "Disabled"; - else if (secureboot == GRUB_EFI_SECUREBOOT_MODE_ENABLED) - secureboot_str = "Enabled"; - - grub_dprintf ("efi", "UEFI Secure Boot state: %s\n", secureboot_str); - - return secureboot; -} - -static grub_err_t -shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)), - enum grub_file_type type, - void **context __attribute__ ((unused)), - enum grub_verify_flags *flags) -{ - *flags = GRUB_VERIFY_FLAGS_NONE; - - switch (type & GRUB_FILE_TYPE_MASK) - { - /* Files we check. */ - case GRUB_FILE_TYPE_LINUX_KERNEL: - case GRUB_FILE_TYPE_MULTIBOOT_KERNEL: - case GRUB_FILE_TYPE_BSD_KERNEL: - case GRUB_FILE_TYPE_XNU_KERNEL: - case GRUB_FILE_TYPE_PLAN9_KERNEL: - case GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE: - *flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK; - return GRUB_ERR_NONE; - - /* Files that do not affect secureboot state. */ - case GRUB_FILE_TYPE_NONE: - case GRUB_FILE_TYPE_LOOPBACK: - case GRUB_FILE_TYPE_LINUX_INITRD: - case GRUB_FILE_TYPE_OPENBSD_RAMDISK: - case GRUB_FILE_TYPE_XNU_RAMDISK: - case GRUB_FILE_TYPE_SIGNATURE: - case GRUB_FILE_TYPE_PUBLIC_KEY: - case GRUB_FILE_TYPE_PUBLIC_KEY_TRUST: - case GRUB_FILE_TYPE_PRINT_BLOCKLIST: - case GRUB_FILE_TYPE_TESTLOAD: - case GRUB_FILE_TYPE_GET_SIZE: - case GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY: - case GRUB_FILE_TYPE_CAT: - case GRUB_FILE_TYPE_HEXCAT: - case GRUB_FILE_TYPE_CMP: - case GRUB_FILE_TYPE_HASHLIST: - case GRUB_FILE_TYPE_TO_HASH: - case GRUB_FILE_TYPE_KEYBOARD_LAYOUT: - case GRUB_FILE_TYPE_PIXMAP: - case GRUB_FILE_TYPE_GRUB_MODULE_LIST: - case GRUB_FILE_TYPE_CONFIG: - case GRUB_FILE_TYPE_THEME: - case GRUB_FILE_TYPE_GETTEXT_CATALOG: - case GRUB_FILE_TYPE_FS_SEARCH: - case GRUB_FILE_TYPE_LOADENV: - case GRUB_FILE_TYPE_SAVEENV: - case GRUB_FILE_TYPE_VERIFY_SIGNATURE: - *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; - return GRUB_ERR_NONE; - - /* Other files. */ - default: - return grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited by secure boot policy")); - } -} - -static grub_err_t -shim_lock_verifier_write (void *context __attribute__ ((unused)), void *buf, grub_size_t size) -{ - grub_efi_shim_lock_protocol_t *sl = grub_efi_locate_protocol (&shim_lock_guid, 0); - - if (!sl) - return grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim_lock protocol not found")); - - if (sl->verify (buf, size) != GRUB_EFI_SUCCESS) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim signature")); - - return GRUB_ERR_NONE; -} - -struct grub_file_verifier shim_lock_verifier = - { - .name = "shim_lock_verifier", - .init = shim_lock_verifier_init, - .write = shim_lock_verifier_write - }; - -void -grub_shim_lock_verifier_setup (void) -{ - struct grub_module_header *header; - grub_efi_shim_lock_protocol_t *sl = - grub_efi_locate_protocol (&shim_lock_guid, 0); - - /* shim_lock is missing, check if GRUB image is built with --disable-shim-lock. */ - if (!sl) - { - FOR_MODULES (header) - { - if (header->type == OBJ_TYPE_DISABLE_SHIM_LOCK) - return; - } - } - - /* Secure Boot is off. Do not load shim_lock. */ - if (grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED) - return; - - /* Enforce shim_lock_verifier. */ - grub_verifier_register (&shim_lock_verifier); - - shim_lock_enabled = true; - - grub_env_set ("shim_lock", "y"); - grub_env_export ("shim_lock"); -} - -bool -grub_is_shim_lock_enabled (void) -{ - return shim_lock_enabled; -} diff --git a/grub-core/kern/elf.c b/grub-core/kern/elf.c deleted file mode 100644 index 077a8500c..000000000 --- a/grub-core/kern/elf.c +++ /dev/null @@ -1,230 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#pragma GCC diagnostic ignored "-Wcast-align" - -#if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275) -#define GRUB_ELF_ENABLE_BI_ENDIAN 1 -#else -#define GRUB_ELF_ENABLE_BI_ENDIAN 0 -#endif - -#if defined(GRUB_CPU_WORDS_BIGENDIAN) -#define GRUB_ELF_NATIVE_ENDIANNESS ELFDATA2MSB -#define GRUB_ELF_OPPOSITE_ENDIANNESS ELFDATA2LSB -#else -#define GRUB_ELF_NATIVE_ENDIANNESS ELFDATA2LSB -#define GRUB_ELF_OPPOSITE_ENDIANNESS ELFDATA2MSB -#endif - -static int grub_elf32_check_endianess_and_bswap_ehdr (grub_elf_t elf); -static int grub_elf64_check_endianess_and_bswap_ehdr (grub_elf_t elf); - -/* 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) - return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-independent ELF magic")); - - if (grub_elf_is_elf32 (elf)) - { - if (!grub_elf32_check_endianess_and_bswap_ehdr (elf)) { - return grub_error (GRUB_ERR_BAD_OS, "invalid ELF endianness magic"); - } - } - else if (grub_elf_is_elf64 (elf)) - { - if (!grub_elf64_check_endianess_and_bswap_ehdr (elf)) { - return grub_error (GRUB_ERR_BAD_OS, "invalid ELF endianness magic"); - } - } - else - return grub_error (GRUB_ERR_BAD_OS, "unknown ELF class"); - - if (e->e_version != EV_CURRENT) - return grub_error (GRUB_ERR_BAD_OS, N_("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->filename); - grub_free (elf); - - if (file) - grub_file_close (file); - - return grub_errno; -} - -grub_elf_t -grub_elf_file (grub_file_t file, const char *filename) -{ - 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)) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - filename); - goto fail; - } - - if (grub_elf_check_header (elf)) - goto fail; - - elf->filename = grub_strdup (filename); - if (!elf->filename) - goto fail; - - return elf; - -fail: - grub_free (elf->filename); - grub_free (elf->phdrs); - grub_free (elf); - return 0; -} - -grub_elf_t -grub_elf_open (const char *name, enum grub_file_type type) -{ - grub_file_t file; - grub_elf_t elf; - - file = grub_file_open (name, type); - if (! file) - return 0; - - elf = grub_elf_file (file, name); - if (! elf) - grub_file_close (file); - - return elf; -} - - -#define grub_swap_bytes_halfXX grub_swap_bytes16 -#define grub_swap_bytes_wordXX grub_swap_bytes32 - -/* 32-bit */ -#define ehdrXX ehdr32 -#define ELFCLASSXX ELFCLASS32 -#define ElfXX_Addr Elf32_Addr -#define grub_elfXX_size grub_elf32_size -#define grub_elfXX_load grub_elf32_load -#define FOR_ELFXX_PHDRS FOR_ELF32_PHDRS -#define grub_elf_is_elfXX grub_elf_is_elf32 -#define grub_elfXX_load_phdrs grub_elf32_load_phdrs -#define ElfXX_Phdr Elf32_Phdr -#define ElfXX_Ehdr Elf32_Ehdr -#define ElfXX_Shdr Elf32_Shdr -#define ElfXX_Word Elf32_Word -#define ElfXX_Shnum Elf32_Shnum -#define grub_uintXX_t grub_uint32_t -#define grub_swap_bytes_addrXX grub_swap_bytes32 -#define grub_swap_bytes_offXX grub_swap_bytes32 -#define grub_swap_bytes_XwordXX grub_swap_bytes32 -#define grub_elfXX_check_endianess_and_bswap_ehdr grub_elf32_check_endianess_and_bswap_ehdr -#define grub_elfXX_get_shnum grub_elf32_get_shnum -#define grub_elfXX_get_shstrndx grub_elf32_get_shstrndx -#define grub_elfXX_get_phnum grub_elf32_get_phnum - -#include "elfXX.c" - -#undef ehdrXX -#undef ELFCLASSXX -#undef ElfXX_Addr -#undef grub_elfXX_size -#undef grub_elfXX_load -#undef FOR_ELFXX_PHDRS -#undef grub_elf_is_elfXX -#undef grub_elfXX_load_phdrs -#undef ElfXX_Phdr -#undef ElfXX_Ehdr -#undef ElfXX_Shdr -#undef ElfXX_Word -#undef ElfXX_Shnum -#undef grub_uintXX_t -#undef grub_swap_bytes_addrXX -#undef grub_swap_bytes_offXX -#undef grub_swap_bytes_XwordXX -#undef grub_elfXX_check_endianess_and_bswap_ehdr -#undef grub_elfXX_get_shnum -#undef grub_elfXX_get_shstrndx -#undef grub_elfXX_get_phnum - - -/* 64-bit */ -#define ehdrXX ehdr64 -#define ELFCLASSXX ELFCLASS64 -#define ElfXX_Addr Elf64_Addr -#define grub_elfXX_size grub_elf64_size -#define grub_elfXX_load grub_elf64_load -#define FOR_ELFXX_PHDRS FOR_ELF64_PHDRS -#define grub_elf_is_elfXX grub_elf_is_elf64 -#define grub_elfXX_load_phdrs grub_elf64_load_phdrs -#define ElfXX_Phdr Elf64_Phdr -#define ElfXX_Ehdr Elf64_Ehdr -#define ElfXX_Shdr Elf64_Shdr -#define ElfXX_Word Elf64_Word -#define ElfXX_Shnum Elf64_Shnum -#define grub_uintXX_t grub_uint64_t -#define grub_swap_bytes_addrXX grub_swap_bytes64 -#define grub_swap_bytes_offXX grub_swap_bytes64 -#define grub_swap_bytes_XwordXX grub_swap_bytes64 -#define grub_elfXX_check_endianess_and_bswap_ehdr grub_elf64_check_endianess_and_bswap_ehdr -#define grub_elfXX_get_shnum grub_elf64_get_shnum -#define grub_elfXX_get_shstrndx grub_elf64_get_shstrndx -#define grub_elfXX_get_phnum grub_elf64_get_phnum - -#include "elfXX.c" diff --git a/grub-core/kern/elfXX.c b/grub-core/kern/elfXX.c deleted file mode 100644 index aabf4b9d7..000000000 --- a/grub-core/kern/elfXX.c +++ /dev/null @@ -1,308 +0,0 @@ -int -grub_elf_is_elfXX (grub_elf_t elf) -{ - return elf->ehdr.ehdrXX.e_ident[EI_CLASS] == ELFCLASSXX; -} - -grub_err_t -grub_elfXX_load_phdrs (grub_elf_t elf) -{ - grub_ssize_t phdrs_size; - - if (elf->phdrs) - return GRUB_ERR_NONE; - - phdrs_size = (grub_uint32_t) elf->ehdr.ehdrXX.e_phnum * elf->ehdr.ehdrXX.e_phentsize; - - grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%lx.\n", - (unsigned long long) elf->ehdr.ehdrXX.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.ehdrXX.e_phoff) == (grub_off_t) -1) - || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size)) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - elf->filename); - return grub_errno; - } - -#if GRUB_ELF_ENABLE_BI_ENDIAN - if (elf->ehdr.ehdrXX.e_ident[EI_DATA] == GRUB_ELF_OPPOSITE_ENDIANNESS) - { - ElfXX_Phdr *phdr; - for (phdr = elf->phdrs; (char *) phdr < (char *) elf->phdrs + phdrs_size; - phdr = (ElfXX_Phdr *) ((char *) phdr + elf->ehdr.ehdrXX.e_phentsize)) - { - phdr->p_type = grub_swap_bytes_wordXX (phdr->p_type); - phdr->p_flags = grub_swap_bytes_wordXX (phdr->p_flags); - phdr->p_offset = grub_swap_bytes_offXX (phdr->p_offset); - phdr->p_vaddr = grub_swap_bytes_addrXX (phdr->p_vaddr); - phdr->p_paddr = grub_swap_bytes_addrXX (phdr->p_paddr); - phdr->p_filesz = grub_swap_bytes_XwordXX (phdr->p_filesz); - phdr->p_memsz = grub_swap_bytes_XwordXX (phdr->p_memsz); - phdr->p_align = grub_swap_bytes_XwordXX (phdr->p_align); - } - } -#endif /* GRUB_ELF_ENABLE_BI_ENDIAN */ - - return GRUB_ERR_NONE; -} - -/* Calculate the amount of memory spanned by the segments. */ -grub_size_t -grub_elfXX_size (grub_elf_t elf, - ElfXX_Addr *base, grub_uintXX_t *max_align) -{ - ElfXX_Addr segments_start = (ElfXX_Addr) -1; - ElfXX_Addr segments_end = 0; - int nr_phdrs = 0; - grub_uint32_t curr_align = 1; - ElfXX_Phdr *phdr; - - /* Run through the program headers to calculate the total memory size we - * should claim. */ - FOR_ELFXX_PHDRS (elf, phdr) - { - /* Only consider loadable segments. */ - if (phdr->p_type != PT_LOAD) - continue; - 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; - if (curr_align < phdr->p_align) - curr_align = phdr->p_align; - } - - 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; - if (max_align) - *max_align = curr_align; - return segments_end - segments_start; -} - -grub_err_t -grub_elfXX_load (grub_elf_t elf, const char *filename, - void *load_offset, enum grub_elf_load_flags load_flags, - grub_addr_t *base, grub_size_t *size) -{ - grub_addr_t load_base = (grub_addr_t) -1ULL; - grub_size_t load_size = 0; - ElfXX_Phdr *phdr; - - FOR_ELFXX_PHDRS(elf, phdr) - { - grub_addr_t load_addr; - - if (phdr->p_type != PT_LOAD && !((load_flags & GRUB_ELF_LOAD_FLAGS_LOAD_PT_DYNAMIC) && phdr->p_type == PT_DYNAMIC)) - continue; - - load_addr = (grub_addr_t) phdr->p_paddr; - switch (load_flags & GRUB_ELF_LOAD_FLAGS_BITS) - { - case GRUB_ELF_LOAD_FLAGS_ALL_BITS: - break; - case GRUB_ELF_LOAD_FLAGS_28BITS: - load_addr &= 0xFFFFFFF; - break; - case GRUB_ELF_LOAD_FLAGS_30BITS: - load_addr &= 0x3FFFFFFF; - break; - case GRUB_ELF_LOAD_FLAGS_62BITS: - load_addr &= 0x3FFFFFFFFFFFFFFFULL; - break; - } - load_addr += (grub_addr_t) load_offset; - - 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) - return grub_errno; - - 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) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - filename); - return grub_errno; - } - } - - if (phdr->p_filesz < phdr->p_memsz) - grub_memset ((void *) (grub_addr_t) (load_addr + phdr->p_filesz), - 0, phdr->p_memsz - phdr->p_filesz); - - load_size += phdr->p_memsz; - } - - if (base) - *base = load_base; - if (size) - *size = load_size; - - return grub_errno; -} - -static int -grub_elfXX_check_endianess_and_bswap_ehdr (grub_elf_t elf) -{ - ElfXX_Ehdr *e = &(elf->ehdr.ehdrXX); - if (e->e_ident[EI_DATA] == GRUB_ELF_NATIVE_ENDIANNESS) - { - return 1; - } - -#if GRUB_ELF_ENABLE_BI_ENDIAN - if (e->e_ident[EI_DATA] == GRUB_ELF_OPPOSITE_ENDIANNESS) - { - e->e_type = grub_swap_bytes_halfXX (e->e_type); - e->e_machine = grub_swap_bytes_halfXX (e->e_machine); - e->e_version = grub_swap_bytes_wordXX (e->e_version); - e->e_entry = grub_swap_bytes_addrXX (e->e_entry); - e->e_phoff = grub_swap_bytes_offXX (e->e_phoff); - e->e_shoff = grub_swap_bytes_offXX (e->e_shoff); - e->e_flags = grub_swap_bytes_wordXX (e->e_flags); - e->e_ehsize = grub_swap_bytes_halfXX (e->e_ehsize); - e->e_phentsize = grub_swap_bytes_halfXX (e->e_phentsize); - e->e_phnum = grub_swap_bytes_halfXX (e->e_phnum); - e->e_shentsize = grub_swap_bytes_halfXX (e->e_shentsize); - e->e_shnum = grub_swap_bytes_halfXX (e->e_shnum); - e->e_shstrndx = grub_swap_bytes_halfXX (e->e_shstrndx); - return 1; - } -#endif /* GRUB_ELF_ENABLE_BI_ENDIAN */ - - return 0; -} - -grub_err_t -grub_elfXX_get_shnum (ElfXX_Ehdr *e, ElfXX_Shnum *shnum) -{ - ElfXX_Shdr *s; - - if (shnum == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("NULL pointer passed for shnum")); - - /* Set *shnum to 0 so that shnum doesn't return junk on error */ - *shnum = 0; - - if (e == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("NULL pointer passed for elf header")); - - *shnum = e->e_shnum; - if (*shnum == SHN_UNDEF) - { - if (e->e_shoff == 0) - return grub_error (GRUB_ERR_BAD_NUMBER, N_("invalid section header table offset in e_shoff")); - - s = (ElfXX_Shdr *) ((grub_uint8_t *) e + e->e_shoff); - *shnum = s->sh_size; - if (*shnum < SHN_LORESERVE) - return grub_error (GRUB_ERR_BAD_NUMBER, N_("invalid number of section header table entries in sh_size: %" PRIuGRUB_UINT64_T), (grub_uint64_t) *shnum); - } - else - { - if (*shnum >= SHN_LORESERVE) - return grub_error (GRUB_ERR_BAD_NUMBER, N_("invalid number of section header table entries in e_shnum: %" PRIuGRUB_UINT64_T), (grub_uint64_t) *shnum); - } - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_elfXX_get_shstrndx (ElfXX_Ehdr *e, ElfXX_Word *shstrndx) -{ - ElfXX_Shdr *s; - - if (shstrndx == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("NULL pointer passed for shstrndx")); - - /* Set *shstrndx to 0 so that shstrndx doesn't return junk on error */ - *shstrndx = 0; - - if (e == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("NULL pointer passed for elf header")); - - *shstrndx = e->e_shstrndx; - if (*shstrndx == SHN_XINDEX) - { - if (e->e_shoff == 0) - return grub_error (GRUB_ERR_BAD_NUMBER, N_("invalid section header table offset in e_shoff")); - - s = (ElfXX_Shdr *) ((grub_uint8_t *) e + e->e_shoff); - *shstrndx = s->sh_link; - if (*shstrndx < SHN_LORESERVE) - return grub_error (GRUB_ERR_BAD_NUMBER, N_("invalid section header table index in sh_link: %d"), *shstrndx); - } - else - { - if (*shstrndx >= SHN_LORESERVE) - return grub_error (GRUB_ERR_BAD_NUMBER, N_("invalid section header table index in e_shstrndx: %d"), *shstrndx); - } - return GRUB_ERR_NONE; -} - -grub_err_t -grub_elfXX_get_phnum (ElfXX_Ehdr *e, ElfXX_Word *phnum) -{ - ElfXX_Shdr *s; - - if (phnum == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("NULL pointer passed for phnum")); - - /* Set *phnum to 0 so that phnum doesn't return junk on error */ - *phnum = 0; - - if (e == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("NULL pointer passed for elf header")); - - *phnum = e->e_phnum; - if (*phnum == PN_XNUM) - { - if (e->e_shoff == 0) - return grub_error (GRUB_ERR_BAD_NUMBER, N_("invalid section header table offset in e_shoff")); - - s = (ElfXX_Shdr *) ((grub_uint8_t *) e + e->e_shoff); - *phnum = s->sh_info; - if (*phnum < PN_XNUM) - return grub_error (GRUB_ERR_BAD_NUMBER, N_("invalid number of program header table entries in sh_info: %d"), *phnum); - } - else - { - if (*phnum >= PN_XNUM) - return grub_error (GRUB_ERR_BAD_NUMBER, N_("invalid number of program header table entries in e_phnum: %d"), *phnum); - } - - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/emu/argp_common.c b/grub-core/kern/emu/argp_common.c deleted file mode 100644 index 8cb4608c3..000000000 --- a/grub-core/kern/emu/argp_common.c +++ /dev/null @@ -1,41 +0,0 @@ -/* grub-setup.c - make GRUB usable */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#pragma GCC diagnostic ignored "-Wmissing-prototypes" -#pragma GCC diagnostic ignored "-Wmissing-declarations" - -#define _GNU_SOURCE 1 -#include -#include -#include -#include - -/* Print the version information. */ -static void -print_version (FILE *stream, struct argp_state *state) -{ - fprintf (stream, "%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); -} -void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; - -/* Set the bug report address */ -const char *argp_program_bug_address = "<"PACKAGE_BUGREPORT">"; diff --git a/grub-core/kern/emu/cache.c b/grub-core/kern/emu/cache.c deleted file mode 100644 index 113682cc4..000000000 --- a/grub-core/kern/emu/cache.c +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef GRUB_MACHINE_EMU -#error "This source is only meant for grub-emu platform" -#endif - -#include - -#if defined(__ia64__) -#include "../ia64/cache.c" -#elif defined (__arm__) || defined (__aarch64__) - -void __clear_cache (void *beg, void *end); - -void -grub_arch_sync_caches (void *address, grub_size_t len) -{ - __clear_cache (address, (char *) address + len); -} - -#elif defined (__mips__) -void _flush_cache (void *address, grub_size_t len, int type); - -void -grub_arch_sync_caches (void *address, grub_size_t len) -{ - return _flush_cache (address, len, 0); -} - -#elif defined(__riscv) -void -grub_arch_sync_caches (void *address, grub_size_t len) -{ -} - -#endif - diff --git a/grub-core/kern/emu/cache_s.S b/grub-core/kern/emu/cache_s.S deleted file mode 100644 index 6885ffd69..000000000 --- a/grub-core/kern/emu/cache_s.S +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef GRUB_MACHINE_EMU -#error "This source is only meant for grub-emu platform" -#endif - -/* An executable stack is not required for these functions. */ -#if defined (__linux__) && defined (__ELF__) -.section .note.GNU-stack,"",%progbits -#endif - -#if defined(__i386__) || defined(__x86_64__) -/* Nothing is necessary. */ -#elif defined(__sparc__) -#include "../sparc64/cache.S" -#elif defined(__powerpc__) -#include "../powerpc/cache.S" -#elif defined(__ia64__) || defined(__arm__) || defined(__aarch64__) || \ - defined(__mips__) || defined(__riscv) -#else -#error "No target cpu type is defined" -#endif diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c deleted file mode 100644 index e8d63b1f5..000000000 --- a/grub-core/kern/emu/full.c +++ /dev/null @@ -1,69 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -const int grub_no_modules = 1; - -void -grub_register_exported_symbols (void) -{ -} - -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, - Elf_Shdr *s, grub_dl_segment_t seg) -{ - (void) mod; - (void) ehdr; - (void) s; - (void) seg; - return GRUB_ERR_BAD_MODULE; -} - -#if !defined (__i386__) && !defined (__x86_64__) -grub_err_t -grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)), - grub_size_t *tramp, grub_size_t *got) -{ - *tramp = 0; - *got = 0; - return GRUB_ERR_BAD_MODULE; -} -#endif - -#ifdef GRUB_LINKER_HAVE_INIT -void -grub_arch_dl_init_linker (void) -{ -} -#endif - diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c deleted file mode 100644 index 0e6eebdc8..000000000 --- a/grub-core/kern/emu/hostdisk.c +++ /dev/null @@ -1,686 +0,0 @@ -/* hostdisk.c - emulate biosdisk */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,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 . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __linux__ -# include /* ioctl */ -# include -# ifndef BLKFLSBUF -# define BLKFLSBUF _IO (0x12,97) /* flush buffer cache */ -# endif /* ! BLKFLSBUF */ -#endif /* __linux__ */ - -static struct -{ - char *drive; - char *device; - int device_map; -} map[256]; - -static int -unescape_cmp (const char *a, const char *b_escaped) -{ - while (*a || *b_escaped) - { - if (*b_escaped == '\\' && b_escaped[1] != 0) - b_escaped++; - if (*a < *b_escaped) - return -1; - if (*a > *b_escaped) - return +1; - a++; - b_escaped++; - } - if (*a) - return +1; - if (*b_escaped) - return -1; - return 0; -} - -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 && unescape_cmp (map[i].drive, name) == 0) - return i; - } - - return -1; -} - -static int -find_free_slot (void) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE (map); i++) - if (! map[i].drive) - return i; - - return -1; -} - -static int -grub_util_biosdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -{ - unsigned i; - - if (pull != GRUB_DISK_PULL_NONE) - return 0; - - for (i = 0; i < ARRAY_SIZE (map); i++) - if (map[i].drive && hook (map[i].drive, hook_data)) - return 1; - - return 0; -} - -static grub_err_t -grub_util_biosdisk_open (const char *name, grub_disk_t disk) -{ - int drive; - struct grub_util_hostdisk_data *data; - - drive = find_grub_drive (name); - grub_util_info ("drive = %d", drive); - if (drive < 0) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "no mapping exists for `%s'", name); - - disk->id = drive; - disk->data = data = xmalloc (sizeof (struct grub_util_hostdisk_data)); - data->dev = NULL; - data->access_mode = 0; - data->fd = GRUB_UTIL_FD_INVALID; - data->is_disk = 0; - data->device_map = map[drive].device_map; - - /* Get the size. */ - { - grub_util_fd_t fd; - - fd = grub_util_fd_open (map[drive].device, GRUB_UTIL_FD_O_RDONLY); - - if (!GRUB_UTIL_FD_IS_VALID(fd)) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("cannot open `%s': %s"), - map[drive].device, grub_util_fd_strerror ()); - - disk->total_sectors = grub_util_get_fd_size (fd, map[drive].device, - &disk->log_sector_size); - disk->total_sectors >>= disk->log_sector_size; - disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE; - -#if GRUB_UTIL_FD_STAT_IS_FUNCTIONAL - { - struct stat st; -# if GRUB_DISK_DEVS_ARE_CHAR - if (fstat (fd, &st) >= 0 && S_ISCHR (st.st_mode)) -# else - if (fstat (fd, &st) >= 0 && S_ISBLK (st.st_mode)) -# endif - data->is_disk = 1; - } -#endif - - grub_util_fd_close (fd); - - grub_util_info ("the size of %s is %" GRUB_HOST_PRIuLONG_LONG, - name, (unsigned long long) disk->total_sectors); - - return GRUB_ERR_NONE; - } -} - -const char * -grub_hostdisk_os_dev_to_grub_drive (const char *os_disk, int add) -{ - unsigned int i; - char *canon; - - canon = grub_canonicalize_file_name (os_disk); - if (!canon) - canon = xstrdup (os_disk); - - for (i = 0; i < ARRAY_SIZE (map); i++) - if (! map[i].device) - break; - else if (strcmp (map[i].device, canon) == 0) - { - free (canon); - return map[i].drive; - } - - if (!add) - { - free (canon); - return NULL; - } - - if (i == ARRAY_SIZE (map)) - /* TRANSLATORS: it refers to the lack of free slots. */ - grub_util_error ("%s", _("device count exceeds limit")); - - map[i].device = canon; - map[i].drive = xmalloc (sizeof ("hostdisk/") + strlen (os_disk)); - strcpy (map[i].drive, "hostdisk/"); - strcpy (map[i].drive + sizeof ("hostdisk/") - 1, os_disk); - map[i].device_map = 0; - - grub_hostdisk_flush_initial_buffer (os_disk); - - return map[i].drive; -} - -#ifndef __linux__ -grub_util_fd_t -grub_util_fd_open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags, - grub_disk_addr_t *max) -{ - grub_util_fd_t fd; - struct grub_util_hostdisk_data *data = disk->data; - - *max = ~0ULL; - - flags |= GRUB_UTIL_FD_O_SYNC; - - 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); - data->dev = 0; - if (GRUB_UTIL_FD_IS_VALID(data->fd)) - { - if (data->access_mode == O_RDWR || data->access_mode == O_WRONLY) - grub_util_fd_sync (data->fd); - grub_util_fd_close (data->fd); - data->fd = GRUB_UTIL_FD_INVALID; - } - - fd = grub_util_fd_open (map[disk->id].device, flags); - if (GRUB_UTIL_FD_IS_VALID(fd)) - { - data->dev = xstrdup (map[disk->id].device); - data->access_mode = (flags & O_ACCMODE); - data->fd = fd; - } - } - - if (!GRUB_UTIL_FD_IS_VALID(data->fd)) - { - grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot open `%s': %s"), - map[disk->id].device, grub_util_fd_strerror ()); - return GRUB_UTIL_FD_INVALID; - } - - if (grub_util_fd_seek (fd, sector << disk->log_sector_size)) - { - grub_util_fd_close (fd); - grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"), - map[disk->id].device, grub_util_fd_strerror ()); - - return GRUB_UTIL_FD_INVALID; - } - - return fd; -} -#endif - - -static grub_err_t -grub_util_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, char *buf) -{ - while (size) - { - grub_util_fd_t fd; - grub_disk_addr_t max = ~0ULL; - fd = grub_util_fd_open_device (disk, sector, GRUB_UTIL_FD_O_RDONLY, &max); - if (!GRUB_UTIL_FD_IS_VALID (fd)) - return grub_errno; - -#ifdef __linux__ - if (sector == 0) - /* 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 */ - max = 1; -#endif /* __linux__ */ - - if (max > size) - max = size; - - if (grub_util_fd_read (fd, buf, max << disk->log_sector_size) - != (ssize_t) (max << disk->log_sector_size)) - return grub_error (GRUB_ERR_READ_ERROR, N_("cannot read `%s': %s"), - map[disk->id].device, grub_util_fd_strerror ()); - size -= max; - buf += (max << disk->log_sector_size); - sector += max; - } - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_util_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector, - grub_size_t size, const char *buf) -{ - while (size) - { - grub_util_fd_t fd; - grub_disk_addr_t max = ~0ULL; - fd = grub_util_fd_open_device (disk, sector, GRUB_UTIL_FD_O_WRONLY, &max); - if (!GRUB_UTIL_FD_IS_VALID (fd)) - return grub_errno; - -#ifdef __linux__ - if (sector == 0) - /* Work around a bug in Linux ez remapping. Linux remaps all - sectors that are write together with the MBR in one write. It - should only remap the MBR, so we split the write in two - parts. -jochen */ - max = 1; -#endif /* __linux__ */ - - if (max > size) - max = size; - - if (grub_util_fd_write (fd, buf, max << disk->log_sector_size) - != (ssize_t) (max << disk->log_sector_size)) - return grub_error (GRUB_ERR_WRITE_ERROR, N_("cannot write to `%s': %s"), - map[disk->id].device, grub_util_fd_strerror ()); - size -= max; - buf += (max << disk->log_sector_size); - } - return GRUB_ERR_NONE; -} - -grub_err_t -grub_util_biosdisk_flush (struct grub_disk *disk) -{ - struct grub_util_hostdisk_data *data = disk->data; - - if (disk->dev->id != GRUB_DISK_DEVICE_BIOSDISK_ID) - return GRUB_ERR_NONE; - if (!GRUB_UTIL_FD_IS_VALID (data->fd)) - { - grub_disk_addr_t max; - data->fd = grub_util_fd_open_device (disk, 0, GRUB_UTIL_FD_O_RDONLY, &max); - if (!GRUB_UTIL_FD_IS_VALID (data->fd)) - return grub_errno; - } - grub_util_fd_sync (data->fd); -#ifdef __linux__ - if (data->is_disk) - ioctl (data->fd, BLKFLSBUF, 0); -#endif - return GRUB_ERR_NONE; -} - -static void -grub_util_biosdisk_close (struct grub_disk *disk) -{ - struct grub_util_hostdisk_data *data = disk->data; - - free (data->dev); - if (GRUB_UTIL_FD_IS_VALID (data->fd)) - { - if (data->access_mode == O_RDWR || data->access_mode == O_WRONLY) - grub_util_biosdisk_flush (disk); - grub_util_fd_close (data->fd); - } - free (data); -} - -static struct grub_disk_dev grub_util_biosdisk_dev = - { - .name = "hostdisk", - .id = GRUB_DISK_DEVICE_HOSTDISK_ID, - .disk_iterate = grub_util_biosdisk_iterate, - .disk_open = grub_util_biosdisk_open, - .disk_close = grub_util_biosdisk_close, - .disk_read = grub_util_biosdisk_read, - .disk_write = grub_util_biosdisk_write, - .next = 0 - }; - -static int -grub_util_check_file_presence (const char *p) -{ -#if !GRUB_UTIL_FD_STAT_IS_FUNCTIONAL - grub_util_fd_t h; - h = grub_util_fd_open (p, GRUB_UTIL_FD_O_RDONLY); - if (!GRUB_UTIL_FD_IS_VALID(h)) - return 0; - grub_util_fd_close (h); - return 1; -#else - struct stat st; - - if (stat (p, &st) == -1) - return 0; - return 1; -#endif -} - -static void -read_device_map (const char *dev_map) -{ - FILE *fp; - char buf[1024]; /* XXX */ - int lineno = 0; - - if (!dev_map || dev_map[0] == '\0') - { - grub_util_info ("no device.map"); - return; - } - - fp = grub_util_fopen (dev_map, "r"); - if (! fp) - { - grub_util_info (_("cannot open `%s': %s"), dev_map, strerror (errno)); - return; - } - - while (fgets (buf, sizeof (buf), fp)) - { - char *p = buf; - char *e; - char *drive_e, *drive_p; - int drive; - - lineno++; - - /* Skip leading spaces. */ - while (*p && grub_isspace (*p)) - p++; - - /* If the first character is `#' or NUL, skip this line. */ - if (*p == '\0' || *p == '#') - continue; - - if (*p != '(') - { - char *tmp; - tmp = xasprintf (_("missing `%c' symbol"), '('); - grub_util_error ("%s:%d: %s", dev_map, lineno, tmp); - } - - p++; - /* Find a free slot. */ - drive = find_free_slot (); - if (drive < 0) - grub_util_error ("%s:%d: %s", dev_map, lineno, _("device count exceeds limit")); - - e = p; - p = strchr (p, ')'); - if (! p) - { - char *tmp; - tmp = xasprintf (_("missing `%c' symbol"), ')'); - grub_util_error ("%s:%d: %s", dev_map, lineno, tmp); - } - - map[drive].drive = 0; - if ((e[0] == 'f' || e[0] == 'h' || e[0] == 'c') && e[1] == 'd') - { - char *ptr; - for (ptr = e + 2; ptr < p; ptr++) - if (!grub_isdigit (*ptr)) - break; - if (ptr == p) - { - map[drive].drive = xmalloc (p - e + sizeof ('\0')); - strncpy (map[drive].drive, e, p - e + sizeof ('\0')); - map[drive].drive[p - e] = '\0'; - } - if (*ptr == ',') - { - *p = 0; - - /* TRANSLATORS: Only one entry is ignored. However the suggestion - is to correct/delete the whole file. - device.map is a file indicating which - devices are available at boot time. Fedora populated it with - entries like (hd0,1) /dev/sda1 which would mean that every - partition is a separate disk for BIOS. Such entries were - inactive in GRUB due to its bug which is now gone. Without - this additional check these entries would be harmful now. - */ - grub_util_warn (_("the device.map entry `%s' is invalid. " - "Ignoring it. Please correct or " - "delete your device.map"), e); - continue; - } - } - drive_e = e; - drive_p = p; - map[drive].device_map = 1; - - p++; - /* Skip leading spaces. */ - while (*p && grub_isspace (*p)) - p++; - - if (*p == '\0') - grub_util_error ("%s:%d: %s", dev_map, lineno, _("filename expected")); - - /* NUL-terminate the filename. */ - e = p; - while (*e && ! grub_isspace (*e)) - e++; - *e = '\0'; - - if (!grub_util_check_file_presence (p)) - { - free (map[drive].drive); - map[drive].drive = NULL; - grub_util_info ("Cannot stat `%s', skipping", p); - continue; - } - - /* 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 = grub_canonicalize_file_name (p); - if (! map[drive].device) - map[drive].device = xstrdup (p); - - if (!map[drive].drive) - { - char c; - map[drive].drive = xmalloc (sizeof ("hostdisk/") + strlen (p)); - memcpy (map[drive].drive, "hostdisk/", sizeof ("hostdisk/") - 1); - strcpy (map[drive].drive + sizeof ("hostdisk/") - 1, p); - c = *drive_p; - *drive_p = 0; - /* TRANSLATORS: device.map is a filename. Not to be translated. - device.map specifies disk correspondance overrides. Previously - one could create any kind of device name with this. Due to - some problems we decided to limit it to just a handful - possibilities. */ - grub_util_warn (_("the drive name `%s' in device.map is incorrect. " - "Using %s instead. " - "Please use the form [hfc]d[0-9]* " - "(E.g. `hd0' or `cd')"), - drive_e, map[drive].drive); - *drive_p = c; - } - - grub_util_info ("adding `%s' -> `%s' from device.map", map[drive].drive, - map[drive].device); - - grub_hostdisk_flush_initial_buffer (map[drive].device); - } - - 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 < ARRAY_SIZE(map); 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); -} - -const char * -grub_util_biosdisk_get_compatibility_hint (grub_disk_t disk) -{ - if (disk->dev != &grub_util_biosdisk_dev || map[disk->id].device_map) - return disk->name; - return 0; -} - -const char * -grub_util_biosdisk_get_osdev (grub_disk_t disk) -{ - if (disk->dev != &grub_util_biosdisk_dev) - return 0; - - return map[disk->id].device; -} - - -static char * -grub_util_path_concat_real (size_t n, int ext, va_list ap) -{ - size_t totlen = 0; - char **l = xcalloc (n + ext, sizeof (l[0])); - char *r, *p, *pi; - size_t i; - int first = 1; - - for (i = 0; i < n + ext; i++) - { - l[i] = va_arg (ap, char *); - if (l[i]) - totlen += strlen (l[i]) + 1; - } - - r = xmalloc (totlen + 10); - - p = r; - for (i = 0; i < n; i++) - { - pi = l[i]; - if (!pi) - continue; - while (*pi == '/') - pi++; - if ((p != r || (pi != l[i] && first)) && (p == r || *(p - 1) != '/')) - *p++ = '/'; - first = 0; - p = grub_stpcpy (p, pi); - while (p != r && p != r + 1 && *(p - 1) == '/') - p--; - } - - if (ext && l[i]) - p = grub_stpcpy (p, l[i]); - - *p = '\0'; - - free (l); - - return r; -} - -char * -grub_util_path_concat (size_t n, ...) -{ - va_list ap; - char *r; - - va_start (ap, n); - - r = grub_util_path_concat_real (n, 0, ap); - - va_end (ap); - - return r; -} - -char * -grub_util_path_concat_ext (size_t n, ...) -{ - va_list ap; - char *r; - - va_start (ap, n); - - r = grub_util_path_concat_real (n, 1, ap); - - va_end (ap); - - return r; -} diff --git a/grub-core/kern/emu/lite.c b/grub-core/kern/emu/lite.c deleted file mode 100644 index b327d4e41..000000000 --- a/grub-core/kern/emu/lite.c +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include - -#ifndef GRUB_MACHINE_EMU -#error "This source is only meant for grub-emu platform" -#endif - -#if defined(__i386__) -#include "../i386/dl.c" -#elif defined(__x86_64__) -#include "../x86_64/dl.c" -#elif defined(__sparc__) -#include "../sparc64/dl.c" -#elif defined(__mips__) -#include "../mips/dl.c" -#elif defined(__powerpc__) -#include "../powerpc/dl.c" -#elif defined(__ia64__) -#include "../ia64/dl_helper.c" -#include "../ia64/dl.c" -#elif defined(__arm__) -#include "../arm/dl_helper.c" -#include "../arm/dl.c" -#elif defined(__aarch64__) -#include "../arm64/dl_helper.c" -#include "../arm64/dl.c" -#elif defined(__riscv) -#include "../riscv/dl.c" -#else -#error "No target cpu type is defined" -#endif - -const int grub_no_modules = 0; - -/* 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 deleted file mode 100644 index 8a70bd7d6..000000000 --- a/grub-core/kern/emu/main.c +++ /dev/null @@ -1,299 +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 . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#pragma GCC diagnostic ignored "-Wmissing-prototypes" - -#include "progname.h" -#include - -#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 *root_dev = NULL, *dir = NULL, *tpm_dev = NULL; - -grub_addr_t grub_modbase = 0; - -void -grub_reboot (void) -{ - longjmp (main_env, 1); - grub_fatal ("longjmp failed"); -} - -void -grub_exit (void) -{ - grub_reboot (); -} - -void -grub_machine_init (void) -{ -} - -void -grub_machine_get_bootlocation (char **device, char **path) -{ - *device = root_dev; - *path = dir; -} - -void -grub_machine_fini (int flags) -{ - if (flags & GRUB_LOADER_FLAG_NORETURN) - grub_console_fini (); -} - - - -#define OPT_MEMDISK 257 - -static struct argp_option options[] = { - {"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2}, - {"device-map", 'm', N_("FILE"), 0, - /* TRANSLATORS: There are many devices in device map. */ - N_("use FILE as the device map [default=%s]"), 0}, - {"memdisk", OPT_MEMDISK, N_("FILE"), 0, - /* TRANSLATORS: There are many devices in device map. */ - N_("use FILE as memdisk"), 0}, - {"directory", 'd', N_("DIR"), 0, - N_("use GRUB files in the directory DIR [default=%s]"), 0}, - {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, - {"hold", 'H', N_("SECS"), OPTION_ARG_OPTIONAL, N_("wait until a debugger will attach"), 0}, - {"kexec", 'X', 0, 0, N_("use kexec to boot Linux kernels via systemctl (pass twice to enable dangerous fallback to non-systemctl)."), 0}, - {"tpm-device", 't', N_("DEV"), 0, N_("set TPM device."), 0}, - { 0, 0, 0, 0, 0, 0 } -}; - -#pragma GCC diagnostic ignored "-Wformat-nonliteral" - -static char * -help_filter (int key, const char *text, void *input __attribute__ ((unused))) -{ - switch (key) - { - case 'd': - return xasprintf (text, DEFAULT_DIRECTORY); - case 'm': - return xasprintf (text, DEFAULT_DEVICE_MAP); - default: - return (char *) text; - } -} - -#pragma GCC diagnostic error "-Wformat-nonliteral" - -struct arguments -{ - const char *dev_map; - const char *mem_disk; - int hold; -}; - -static error_t -argp_parser (int key, char *arg, struct argp_state *state) -{ - /* Get the input argument from argp_parse, which we - know is a pointer to our arguments structure. */ - struct arguments *arguments = state->input; - - switch (key) - { - case OPT_MEMDISK: - arguments->mem_disk = arg; - break; - case 'r': - free (root_dev); - root_dev = xstrdup (arg); - break; - case 'd': - free (dir); - dir = xstrdup (arg); - break; - case 'm': - arguments->dev_map = arg; - break; - case 'H': - arguments->hold = (arg ? atoi (arg) : -1); - break; - case 'v': - verbosity++; - break; - case 'X': - grub_util_set_kexecute (); - break; - case 't': - free (tpm_dev); - tpm_dev = xstrdup (arg); - break; - - case ARGP_KEY_ARG: - { - /* Too many arguments. */ - fprintf (stderr, _("Unknown extra argument `%s'."), arg); - fprintf (stderr, "\n"); - argp_usage (state); - } - break; - - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -static struct argp argp = { - options, argp_parser, NULL, - N_("GRUB emulator."), - NULL, help_filter, NULL -}; - - - -#pragma GCC diagnostic ignored "-Wmissing-prototypes" - -int -main (int argc, char *argv[]) -{ - struct arguments arguments = - { - .dev_map = DEFAULT_DEVICE_MAP, - .hold = 0, - .mem_disk = 0, - }; - volatile int hold = 0; - size_t total_module_size = sizeof (struct grub_module_info), memdisk_size = 0; - struct grub_module_info *modinfo; - void *mods; - - grub_util_host_init (&argc, &argv); - - dir = xstrdup (DEFAULT_DIRECTORY); - - if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0) - { - fprintf (stderr, "%s", _("Error in parsing command line arguments\n")); - exit(1); - } - - if (arguments.mem_disk) - { - memdisk_size = ALIGN_UP(grub_util_get_image_size (arguments.mem_disk), 512); - total_module_size += memdisk_size + sizeof (struct grub_module_header); - } - - mods = xmalloc (total_module_size); - modinfo = grub_memset (mods, 0, total_module_size); - mods = (char *) (modinfo + 1); - - modinfo->magic = GRUB_MODULE_MAGIC; - modinfo->offset = sizeof (struct grub_module_info); - modinfo->size = total_module_size; - - if (arguments.mem_disk) - { - struct grub_module_header *header = (struct grub_module_header *) mods; - header->type = OBJ_TYPE_MEMDISK; - header->size = memdisk_size + sizeof (*header); - mods = header + 1; - - grub_util_load_image (arguments.mem_disk, mods); - mods = (char *) mods + memdisk_size; - } - - grub_modbase = (grub_addr_t) modinfo; - - hold = arguments.hold; - /* Wait until the ARGS.HOLD variable is cleared by an attached debugger. */ - if (hold && verbosity > 0) - /* TRANSLATORS: In this case GRUB tells user what he has to do. */ - 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 (); - - /* XXX: This is a bit unportable. */ - grub_util_biosdisk_init (arguments.dev_map); - - grub_init_all (); - - grub_hostfs_init (); - - /* Make sure that there is a root device. */ - if (! root_dev) - root_dev = grub_strdup ("host"); - - dir = xstrdup (dir); - - if (tpm_dev) - grub_util_tpm_open (tpm_dev); - - /* Start GRUB! */ - if (setjmp (main_env) == 0) - grub_main (); - - grub_fini_all (); - grub_hostfs_fini (); - grub_host_fini (); - grub_util_tpm_close (); - - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); - - return 0; -} diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c deleted file mode 100644 index 1db24fde7..000000000 --- a/grub-core/kern/emu/misc.c +++ /dev/null @@ -1,283 +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 . - */ - -#ifndef GRUB_BUILD -#include -#endif -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -int verbosity; -int kexecute; - -static int grub_util_tpm_fd = -1; - -void -grub_util_warn (const char *fmt, ...) -{ - va_list ap; - - fprintf (stderr, _("%s: warning:"), 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"); - grub_exit (); -} - -void * -xcalloc (grub_size_t nmemb, grub_size_t size) -{ - void *p; - - p = calloc (nmemb, size); - if (!p) - grub_util_error ("%s", _("out of memory")); - - return p; -} - -void * -xmalloc (grub_size_t size) -{ - void *p; - - p = malloc (size); - if (! p) - grub_util_error ("%s", _("out of memory")); - - return p; -} - -void * -xrealloc (void *ptr, grub_size_t size) -{ - ptr = realloc (ptr, size); - if (! ptr) - grub_util_error ("%s", _("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; -} - -#if !defined (GRUB_MKFONT) && !defined (GRUB_BUILD) -char * -xasprintf (const char *fmt, ...) -{ - va_list ap; - char *result; - - va_start (ap, fmt); - result = grub_xvasprintf (fmt, ap); - va_end (ap); - if (!result) - grub_util_error ("%s", _("out of memory")); - - return result; -} -#endif - -#if !defined (GRUB_MACHINE_EMU) || defined (GRUB_UTIL) -void -grub_exit (void) -{ -#if defined (GRUB_KERNEL) - grub_reboot (); -#endif - exit (1); -} -#endif - -grub_uint64_t -grub_get_time_ms (void) -{ - struct timeval tv; - - gettimeofday (&tv, 0); - - return (tv.tv_sec * 1000 + tv.tv_usec / 1000); -} - -size_t -grub_util_get_image_size (const char *path) -{ - FILE *f; - size_t ret; - off_t sz; - - f = grub_util_fopen (path, "rb"); - - if (!f) - grub_util_error (_("cannot open `%s': %s"), path, strerror (errno)); - - fseeko (f, 0, SEEK_END); - - sz = ftello (f); - if (sz < 0) - grub_util_error (_("cannot open `%s': %s"), path, strerror (errno)); - if (sz != (size_t) sz) - grub_util_error (_("file `%s' is too big"), path); - ret = (size_t) sz; - - fclose (f); - - return ret; -} - -void -grub_util_load_image (const char *path, char *buf) -{ - FILE *fp; - size_t size; - - grub_util_info ("reading %s", path); - - size = grub_util_get_image_size (path); - - fp = grub_util_fopen (path, "rb"); - if (! fp) - grub_util_error (_("cannot open `%s': %s"), path, - strerror (errno)); - - if (fread (buf, 1, size, fp) != size) - grub_util_error (_("cannot read `%s': %s"), path, - strerror (errno)); - - fclose (fp); -} - -void -grub_util_set_kexecute (void) -{ - kexecute++; -} - -int -grub_util_get_kexecute (void) -{ - return kexecute; -} - -grub_err_t -grub_util_tpm_open (const char *tpm_dev) -{ - if (grub_util_tpm_fd != -1) - return GRUB_ERR_NONE; - - grub_util_tpm_fd = open (tpm_dev, O_RDWR); - if (grub_util_tpm_fd == -1) - grub_util_error (_("cannot open TPM device '%s': %s"), tpm_dev, strerror (errno)); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_util_tpm_close (void) -{ - int err; - - if (grub_util_tpm_fd == -1) - return GRUB_ERR_NONE; - - err = close (grub_util_tpm_fd); - if (err != GRUB_ERR_NONE) - grub_util_error (_("cannot close TPM device: %s"), strerror (errno)); - - grub_util_tpm_fd = -1; - return GRUB_ERR_NONE; -} - -grub_size_t -grub_util_tpm_read (void *output, grub_size_t size) -{ - if (grub_util_tpm_fd == -1) - return -1; - - return read (grub_util_tpm_fd, output, size); -} - -grub_size_t -grub_util_tpm_write (const void *input, grub_size_t size) -{ - if (grub_util_tpm_fd == -1) - return -1; - - return write (grub_util_tpm_fd, input, size); -} diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c deleted file mode 100644 index 4d1046a21..000000000 --- a/grub-core/kern/emu/mm.c +++ /dev/null @@ -1,75 +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 . - */ - -#include - -#include -#include -#include -#include -#include -#include - -void * -grub_calloc (grub_size_t nmemb, grub_size_t size) -{ - void *ret; - ret = calloc (nmemb, size); - if (!ret) - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - return ret; -} - -void * -grub_malloc (grub_size_t size) -{ - void *ret; - ret = malloc (size); - if (!ret) - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - return ret; -} - -void * -grub_zalloc (grub_size_t size) -{ - void *ret; - - ret = grub_malloc (size); - if (!ret) - return NULL; - memset (ret, 0, size); - return ret; -} - -void -grub_free (void *ptr) -{ - if (ptr) - free (ptr); -} - -void * -grub_realloc (void *ptr, grub_size_t size) -{ - void *ret; - ret = realloc (ptr, size); - if (!ret) - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - return ret; -} diff --git a/grub-core/kern/emu/time.c b/grub-core/kern/emu/time.c deleted file mode 100644 index 5da8092a9..000000000 --- a/grub-core/kern/emu/time.c +++ /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 . - */ - -#include -#include - -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/i386/coreboot/cbtable.c b/grub-core/kern/i386/coreboot/cbtable.c deleted file mode 100644 index 34a2b59be..000000000 --- a/grub-core/kern/i386/coreboot/cbtable.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007,2008,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -grub_linuxbios_table_header_t -grub_linuxbios_get_tables (void) -{ - grub_linuxbios_table_header_t table_header; - /* 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 (grub_linuxbios_check_signature (table_header)) - return table_header; - - for (table_header = (grub_linuxbios_table_header_t) 0xf0000; - table_header < (grub_linuxbios_table_header_t) 0x100000; table_header++) - if (grub_linuxbios_check_signature (table_header)) - return table_header; - - return 0; -} diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c deleted file mode 100644 index 4fae8b571..000000000 --- a/grub-core/kern/i386/coreboot/init.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern grub_uint8_t _start[]; -extern grub_uint8_t _end[]; -extern grub_uint8_t _edata[]; - -void __attribute__ ((noreturn)) -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 (); -} - -grub_addr_t grub_modbase = GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR; -static grub_uint64_t modend; -static int have_memory = 0; - -/* Helper for grub_machine_init. */ -static int -heap_init (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, - void *data __attribute__ ((unused))) -{ - grub_uint64_t begin = addr, end = addr + size; - -#if GRUB_CPU_SIZEOF_VOID_P == 4 - /* Restrict ourselves to 32-bit memory space. */ - if (begin > GRUB_ULONG_MAX) - return 0; - if (end > GRUB_ULONG_MAX) - end = GRUB_ULONG_MAX; -#endif - - if (type != GRUB_MEMORY_AVAILABLE) - return 0; - - /* Avoid the lower memory. */ - if (begin < GRUB_MEMORY_MACHINE_LOWER_SIZE) - begin = GRUB_MEMORY_MACHINE_LOWER_SIZE; - - if (modend && begin < modend) - begin = modend; - - if (end <= begin) - return 0; - - grub_mm_init_region ((void *) (grub_addr_t) begin, (grub_size_t) (end - begin)); - - have_memory = 1; - - return 0; -} - -#ifndef GRUB_MACHINE_MULTIBOOT - -void -grub_machine_init (void) -{ - modend = grub_modules_get_end (); - - grub_video_coreboot_fb_early_init (); - - grub_vga_text_init (); - - grub_machine_mmap_iterate (heap_init, NULL); - if (!have_memory) - grub_fatal ("No memory found"); - - grub_video_coreboot_fb_late_init (); - - grub_font_init (); - grub_gfxterm_init (); - - grub_tsc_init (); -} - -#else - -void -grub_machine_init (void) -{ - modend = grub_modules_get_end (); - - grub_vga_text_init (); - - grub_machine_mmap_init (); - grub_machine_mmap_iterate (heap_init, NULL); - - grub_tsc_init (); -} - -#endif - -void -grub_machine_get_bootlocation (char **device __attribute__ ((unused)), - char **path __attribute__ ((unused))) -{ -} - -void -grub_machine_fini (int flags) -{ - if (flags & GRUB_LOADER_FLAG_NORETURN) - grub_vga_text_fini (); - grub_stop_floppy (); -} diff --git a/grub-core/kern/i386/dl.c b/grub-core/kern/i386/dl.c deleted file mode 100644 index 1346da5cc..000000000 --- a/grub-core/kern/i386/dl.c +++ /dev/null @@ -1,81 +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 . - */ - -#include -#include -#include -#include -#include - -/* 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, N_("invalid arch-dependent ELF magic")); - - return GRUB_ERR_NONE; -} - -/* Relocate symbols. */ -grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - Elf_Shdr *s, grub_dl_segment_t seg) -{ - Elf_Rel *rel, *max; - - for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset), - max = (Elf_Rel *) ((char *) rel + s->sh_size); - rel < max; - rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) - { - 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 - + mod->symsize * 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 - (grub_addr_t) addr); - break; - default: - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - ELF_R_TYPE (rel->r_info)); - } - } - - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/i386/efi/tsc.c b/grub-core/kern/i386/efi/tsc.c deleted file mode 100644 index e41dc6526..000000000 --- a/grub-core/kern/i386/efi/tsc.c +++ /dev/null @@ -1,40 +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 PIT 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 . - */ - -#include -#include -#include -#include -#include -#include - -int -grub_tsc_calibrate_from_efi (void) -{ - grub_uint64_t start_tsc, end_tsc; - /* Use EFI Time Service to calibrate TSC */ - start_tsc = grub_get_tsc (); - grub_efi_system_table->boot_services->stall (1000); - end_tsc = grub_get_tsc (); - grub_tsc_rate = grub_divmod64 ((1ULL << 32), end_tsc - start_tsc, 0); - return 1; -} diff --git a/grub-core/kern/i386/int.S b/grub-core/kern/i386/int.S deleted file mode 100644 index 862a54202..000000000 --- a/grub-core/kern/i386/int.S +++ /dev/null @@ -1,134 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -FUNCTION(grub_bios_interrupt) - pushf - cli - popf - pushl %ebp - pushl %ecx - pushl %eax - pushl %ebx - pushl %esi - pushl %edi - pushl %edx - - movb %al, intno - movl (%edx), %eax - movl %eax, LOCAL(bios_register_eax) - movw 4(%edx), %ax - movw %ax, LOCAL(bios_register_es) - movw 6(%edx), %ax - movw %ax, LOCAL(bios_register_ds) - movw 8(%edx), %ax - movw %ax, LOCAL(bios_register_flags) - - movl 12(%edx), %ebx - movl 16(%edx), %ecx - movl 20(%edx), %edi - movl 24(%edx), %esi - movl 28(%edx), %edx - - /* - Via C3 CPUs have cache coherence problems, so we need to call - wbinvd at these 2 points. As wbinvd slows down boot, don't do - it on non-VIA. 9090 is nop nop. */ -VARIABLE(grub_bios_via_workaround1) - .byte 0x90, 0x90 - - PROT_TO_REAL - .code16 - pushf - cli - - mov %ds, %ax - push %ax - - /* movw imm16, %ax*/ - .byte 0xb8 -LOCAL(bios_register_es): - .short 0 - movw %ax, %es - /* movw imm16, %ax*/ - .byte 0xb8 -LOCAL(bios_register_ds): - .short 0 - movw %ax, %ds - - /* movw imm16, %ax*/ - .byte 0xb8 -LOCAL(bios_register_flags): - .short 0 - push %ax - popf - - /* movl imm32, %eax*/ - .byte 0x66, 0xb8 -LOCAL(bios_register_eax): - .long 0 - - /* int imm8. */ - .byte 0xcd -intno: - .byte 0 - - movl %eax, %cs:LOCAL(bios_register_eax) - movw %ds, %ax - movw %ax, %cs:LOCAL(bios_register_ds) - pop %ax - mov %ax, %ds - pushf - pop %ax - movw %ax, LOCAL(bios_register_flags) - mov %es, %ax - movw %ax, LOCAL(bios_register_es) - - popf - -VARIABLE(grub_bios_via_workaround2) - .byte 0x90, 0x90 - - REAL_TO_PROT - .code32 - - popl %eax - - movl %ebx, 12(%eax) - movl %ecx, 16(%eax) - movl %edi, 20(%eax) - movl %esi, 24(%eax) - movl %edx, 28(%eax) - - movl %eax, %edx - - movl LOCAL(bios_register_eax), %eax - movl %eax, (%edx) - movw LOCAL(bios_register_es), %ax - movw %ax, 4(%edx) - movw LOCAL(bios_register_ds), %ax - movw %ax, 6(%edx) - movw LOCAL(bios_register_flags), %ax - movw %ax, 8(%edx) - - popl %edi - popl %esi - popl %ebx - popl %eax - popl %ecx - popl %ebp - ret diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c deleted file mode 100644 index 326d491c5..000000000 --- a/grub-core/kern/i386/pc/init.c +++ /dev/null @@ -1,280 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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; - -void (*grub_pc_net_config) (char **device, char **path); - -/* - * return the real time in ticks, of which there are about - * 18-20 per second - */ -grub_uint64_t -grub_rtc_get_time_ms (void) -{ - struct grub_bios_int_registers regs; - - regs.eax = 0; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x1a, ®s); - - return ((regs.ecx << 16) | (regs.edx & 0xffff)) * 55ULL; -} - -void -grub_machine_get_bootlocation (char **device, char **path) -{ - char *ptr; - grub_uint8_t boot_drive, dos_part, bsd_part; - - boot_drive = (grub_boot_device >> 24); - dos_part = (grub_boot_device >> 16); - bsd_part = (grub_boot_device >> 8); - - /* No hardcoded root partition - make it from the boot drive and the - partition number encoded at the install time. */ - if (boot_drive == GRUB_BOOT_MACHINE_PXE_DL) - { - if (grub_pc_net_config) - grub_pc_net_config (device, path); - return; - } - - /* XXX: This should be enough. */ -#define DEV_SIZE 100 - *device = grub_malloc (DEV_SIZE); - ptr = *device; - grub_snprintf (*device, DEV_SIZE, - "%cd%u", (boot_drive & 0x80) ? 'h' : 'f', - boot_drive & 0x7f); - ptr += grub_strlen (ptr); - - if (dos_part != 0xff) - grub_snprintf (ptr, DEV_SIZE - (ptr - *device), - ",%u", dos_part + 1); - ptr += grub_strlen (ptr); - - if (bsd_part != 0xff) - grub_snprintf (ptr, DEV_SIZE - (ptr - *device), ",%u", - bsd_part + 1); - ptr += grub_strlen (ptr); - *ptr = 0; -} - -/* 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--; - } -} - -grub_addr_t grub_modbase; -extern grub_uint8_t _start[], _edata[]; - -/* Helper for grub_machine_init. */ -static int -mmap_iterate_hook (grub_uint64_t addr, grub_uint64_t size, - grub_memory_type_t type, - void *data __attribute__ ((unused))) -{ - /* Avoid the lower memory. */ - if (addr < GRUB_MEMORY_MACHINE_UPPER_START) - { - if (size <= GRUB_MEMORY_MACHINE_UPPER_START - addr) - return 0; - - size -= GRUB_MEMORY_MACHINE_UPPER_START - addr; - addr = GRUB_MEMORY_MACHINE_UPPER_START; - } - - /* Ignore >4GB. */ - if (addr <= 0xFFFFFFFF && type == GRUB_MEMORY_AVAILABLE) - { - grub_size_t len; - - len = (grub_size_t) ((addr + size > 0xFFFFFFFF) - ? 0xFFFFFFFF - addr - : size); - add_mem_region (addr, len); - } - - return 0; -} - -extern grub_uint16_t grub_bios_via_workaround1, grub_bios_via_workaround2; - -/* Via needs additional wbinvd. */ -static void -grub_via_workaround_init (void) -{ - grub_uint32_t manufacturer[3], max_cpuid, proc_info; - if (! grub_cpu_is_cpuid_supported ()) - return; - - grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]); - - if (grub_memcmp (manufacturer, "CentaurHauls", 12) != 0) - return; - - if (max_cpuid > 0) - { - grub_cpuid (1, proc_info, /* Don't care. */ manufacturer[0], - manufacturer[2], manufacturer[1]); - /* Check model, apply only to VIA C3 and lower. */ - if (((proc_info & 0xf0) >> 4 | (proc_info & 0xf0000) >> 12) > 10) - return; - } - - grub_bios_via_workaround1 = 0x090f; - grub_bios_via_workaround2 = 0x090f; - asm volatile ("wbinvd"); -} - -void -grub_machine_init (void) -{ - int i; -#if 0 - int grub_lower_mem; -#endif - grub_addr_t modend; - - /* This has to happen before any BIOS calls. */ - grub_via_workaround_init (); - - grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - _start); - - /* Initialize the console as early as possible. */ - grub_console_init (); - - /* This sanity check is useless since top of GRUB_MEMORY_MACHINE_RESERVED_END - is used for stack and if it's unavailable we wouldn't have gotten so far. - */ -#if 0 - grub_lower_mem = grub_get_conv_memsize () << 10; - - /* Sanity check. */ - if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END) - grub_fatal ("too small memory"); -#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 - - grub_machine_mmap_iterate (mmap_iterate_hook, NULL); - - compact_mem_regions (); - - modend = grub_modules_get_end (); - for (i = 0; i < num_regions; i++) - { - grub_addr_t beg = mem_regions[i].addr; - grub_addr_t fin = mem_regions[i].addr + mem_regions[i].size; - if (modend && beg < modend) - beg = modend; - if (beg >= fin) - continue; - grub_mm_init_region ((void *) beg, fin - beg); - } - - grub_tsc_init (); -} - -void -grub_machine_fini (int flags) -{ - if (flags & GRUB_LOADER_FLAG_NORETURN) - grub_console_fini (); - grub_stop_floppy (); -} diff --git a/grub-core/kern/i386/pc/mmap.c b/grub-core/kern/i386/pc/mmap.c deleted file mode 100644 index 53fcf45af..000000000 --- a/grub-core/kern/i386/pc/mmap.c +++ /dev/null @@ -1,193 +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 . - */ - -#include -#include -#include -#include -#include - -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_BADRAM 5 - grub_uint32_t type; -} GRUB_PACKED; - - -/* - * - * grub_get_conv_memsize(i) : return the conventional memory size in KB. - * BIOS call "INT 12H" to get conventional memory size - * The return value in AX. - */ -static inline grub_uint16_t -grub_get_conv_memsize (void) -{ - struct grub_bios_int_registers regs; - - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x12, ®s); - return regs.eax & 0xffff; -} - -/* - * grub_get_ext_memsize() : return the extended memory size in KB. - * BIOS call "INT 15H, AH=88H" to get extended memory size - * The return value in AX. - * - */ -static inline grub_uint16_t -grub_get_ext_memsize (void) -{ - struct grub_bios_int_registers regs; - - regs.eax = 0x8800; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x15, ®s); - return regs.eax & 0xffff; -} - -/* 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. 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. -*/ - -static inline grub_uint32_t -grub_get_eisa_mmap (void) -{ - struct grub_bios_int_registers regs; - - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - regs.eax = 0xe801; - grub_bios_interrupt (0x15, ®s); - - if ((regs.eax & 0xff00) == 0x8600) - return 0; - - return (regs.eax & 0xffff) | (regs.ebx << 16); -} - -/* - * - * 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. - */ -/* Get a memory map entry. Return next continuation value. Zero means - the end. */ -static grub_uint32_t -grub_get_mmap_entry (struct grub_machine_mmap_entry *entry, - grub_uint32_t cont) -{ - struct grub_bios_int_registers regs; - - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - - /* place address (+4) in ES:DI */ - regs.es = ((grub_addr_t) &entry->addr) >> 4; - regs.edi = ((grub_addr_t) &entry->addr) & 0xf; - - /* set continuation value */ - regs.ebx = cont; - - /* set default maximum buffer size */ - regs.ecx = sizeof (*entry) - sizeof (entry->size); - - /* set EDX to 'SMAP' */ - regs.edx = 0x534d4150; - - regs.eax = 0xe820; - grub_bios_interrupt (0x15, ®s); - - /* write length of buffer (zero if error) into ADDR */ - if ((regs.flags & GRUB_CPU_INT_FLAGS_CARRY) || regs.eax != 0x534d4150 - || regs.ecx < 0x14 || regs.ecx > 0x400) - entry->size = 0; - else - entry->size = regs.ecx; - - /* return the continuation value */ - return regs.ebx; -} - -grub_err_t -grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) -{ - grub_uint32_t cont = 0; - struct grub_machine_mmap_entry *entry - = (struct grub_machine_mmap_entry *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); - int e820_works = 0; - - while (1) - { - grub_memset (entry, 0, sizeof (*entry)); - - cont = grub_get_mmap_entry (entry, cont); - - if (!entry->size) - break; - - if (entry->len) - e820_works = 1; - if (entry->len - && hook (entry->addr, entry->len, - /* GRUB mmaps have been defined to match with - the E820 definition. - Therefore, we can just pass type through. */ - entry->type, hook_data)) - break; - - if (! cont) - break; - } - - if (!e820_works) - { - grub_uint32_t eisa_mmap = grub_get_eisa_mmap (); - - if (hook (0x0, ((grub_uint32_t) grub_get_conv_memsize ()) << 10, - GRUB_MEMORY_AVAILABLE, hook_data)) - return 0; - - if (eisa_mmap) - { - if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10, - GRUB_MEMORY_AVAILABLE, hook_data) == 0) - hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MEMORY_AVAILABLE, - hook_data); - } - else - hook (0x100000, ((grub_uint32_t) grub_get_ext_memsize ()) << 10, - GRUB_MEMORY_AVAILABLE, hook_data); - } - - return 0; -} diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S deleted file mode 100644 index b8a9b33b4..000000000 --- a/grub-core/kern/i386/pc/startup.S +++ /dev/null @@ -1,217 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - - -/* - * 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 -#include -#include -#ifdef __APPLE__ -#include -#endif - - .file "startup.S" - - .text - - .globl start, _start, __start -start: -_start: -__start: -#ifdef __APPLE__ -LOCAL(start): -#endif - .code32 - - movl %ecx, (LOCAL(real_to_prot_addr) - _start) (%esi) - movl %edi, (LOCAL(prot_to_real_addr) - _start) (%esi) - movl %eax, (EXT_C(grub_realidt) - _start) (%esi) - - /* copy back the decompressed part (except the modules) */ -#ifdef __APPLE__ - movl $EXT_C(_edata), %ecx - subl $LOCAL(start), %ecx -#else - movl $(_edata - _start), %ecx -#endif - movl $(_start), %edi - rep - movsb - - movl $LOCAL (cont), %esi - jmp *%esi -LOCAL(cont): - -#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__ - /* clean out the bss */ - movl $EXT_C(_edata), %edi - - /* compute the bss length */ - movl $GRUB_MEMORY_MACHINE_SCRATCH_ADDR, %ecx -#else - /* clean out the bss */ - movl $BSS_START_SYMBOL, %edi - - /* compute the bss length */ - movl $END_SYMBOL, %ecx -#endif - subl %edi, %ecx - - /* clean out */ - xorl %eax, %eax - cld - rep - stosb - - movl %edx, EXT_C(grub_boot_device) - - /* - * Call the start of main body of C code. - */ - call EXT_C(grub_main) - -LOCAL(real_to_prot_addr): - .long 0 -LOCAL(prot_to_real_addr): - .long 0 - - .macro PROT_TO_REAL - movl LOCAL(prot_to_real_addr), %eax - call *%eax - .endm - - .macro REAL_TO_PROT - movl LOCAL(real_to_prot_addr), %eax - calll *%eax - .endm - -/* - * grub_exit() - * - * Exit the system. - */ -FUNCTION(grub_exit) - PROT_TO_REAL - .code16 - /* Tell the BIOS a boot failure. If this does not work, reboot. */ - int $0x18 - /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */ - xorw %ax, %ax - movw $0x0472, %di - movw %ax, (%di) - ljmp $0xf000, $0xfff0 - .code32 - -/* - * int grub_pxe_call (int func, void* data, grub_uint32_t pxe_rm_entry); - */ -FUNCTION(grub_pxe_call) - pushl %ebp - movl %esp, %ebp - pushl %esi - pushl %edi - pushl %ebx - - movl %ecx, %ebx - movl %eax, %ecx - movl %edx, %eax - andl $0xF, %eax - shrl $4, %edx - shll $16, %edx - addl %eax, %edx - - PROT_TO_REAL - .code16 - - pushl %ebx - pushl %edx - pushw %cx - movw %sp, %bx - lcall *%ss:6(%bx) - cld - addw $10, %sp - movw %ax, %cx - - REAL_TO_PROT - .code32 - - movzwl %cx, %eax - - popl %ebx - popl %edi - popl %esi - popl %ebp - ret - -#include "../int.S" - -VARIABLE(grub_realidt) - .long 0 - -#ifdef __APPLE__ - /* Older versions of objconv assume that there is the same number - of text and data sections. Hence this dummy. */ - .section __TEXT, __zz_dummy - .byte 0 - .globl EXT_C(_edata) - .globl EXT_C(grub_boot_device) - .zerofill __DATA, __aa_before_bss, EXT_C(_edata), 1, 0 - .zerofill __DATA, __bss, EXT_C(grub_boot_device), 4, 2 -#else - .bss -VARIABLE(grub_boot_device) - .long 0 -#endif diff --git a/grub-core/kern/i386/qemu/init.c b/grub-core/kern/i386/qemu/init.c deleted file mode 100644 index 08f81d25e..000000000 --- a/grub-core/kern/i386/qemu/init.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern grub_uint8_t _start[]; -extern grub_uint8_t _end[]; -extern grub_uint8_t _edata[]; - -void __attribute__ ((noreturn)) -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 (); -} - -grub_addr_t grub_modbase; - -/* Helper for grub_machine_init. */ -static int -heap_init (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, - void *data __attribute__ ((unused))) -{ - grub_uint64_t begin = addr, end = addr + size; - -#if GRUB_CPU_SIZEOF_VOID_P == 4 - /* Restrict ourselves to 32-bit memory space. */ - if (begin > GRUB_ULONG_MAX) - return 0; - if (end > GRUB_ULONG_MAX) - end = GRUB_ULONG_MAX; -#endif - - if (type != GRUB_MEMORY_AVAILABLE) - return 0; - - /* Avoid the lower memory. */ - if (begin < GRUB_MEMORY_MACHINE_LOWER_SIZE) - begin = GRUB_MEMORY_MACHINE_LOWER_SIZE; - - if (end <= begin) - return 0; - - grub_mm_init_region ((void *) (grub_addr_t) begin, (grub_size_t) (end - begin)); - - return 0; -} - -struct resource -{ - grub_pci_device_t dev; - grub_size_t size; - unsigned type:4; - unsigned bar:3; -}; - -struct iterator_ctx -{ - struct resource *resources; - grub_size_t nresources; -}; - -/* We don't support bridges, so can't have more than 32 devices. */ -#define MAX_DEVICES 32 - -static int -find_resources (grub_pci_device_t dev, - grub_pci_id_t pciid __attribute__ ((unused)), - void *data) -{ - struct iterator_ctx *ctx = data; - int bar; - - if (ctx->nresources >= MAX_DEVICES * 6) - return 1; - - for (bar = 0; bar < 6; bar++) - { - grub_pci_address_t addr; - grub_uint32_t ones, zeros, mask; - struct resource *res; - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0 - + 4 * bar); - grub_pci_write (addr, 0xffffffff); - grub_pci_read (addr); - ones = grub_pci_read (addr); - grub_pci_write (addr, 0); - grub_pci_read (addr); - zeros = grub_pci_read (addr); - if (ones == zeros) - continue; - res = &ctx->resources[ctx->nresources++]; - if ((zeros & GRUB_PCI_ADDR_SPACE_MASK) == GRUB_PCI_ADDR_SPACE_IO) - mask = GRUB_PCI_ADDR_SPACE_MASK; - else - mask = (GRUB_PCI_ADDR_MEM_TYPE_MASK | GRUB_PCI_ADDR_SPACE_MASK | GRUB_PCI_ADDR_MEM_PREFETCH); - - res->type = ones & mask; - res->dev = dev; - res->bar = bar; - res->size = (~((zeros ^ ones)) | mask) + 1; - if ((zeros & (GRUB_PCI_ADDR_MEM_TYPE_MASK | GRUB_PCI_ADDR_SPACE_MASK)) - == (GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_64)) - bar++; - } - return 0; -} - -static int -enable_cards (grub_pci_device_t dev, - grub_pci_id_t pciid __attribute__ ((unused)), - void *data __attribute__ ((unused))) -{ - grub_uint16_t cmd = 0; - grub_pci_address_t addr; - grub_uint32_t class; - int bar; - - for (bar = 0; bar < 6; bar++) - { - grub_uint32_t val; - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0 - + 4 * bar); - val = grub_pci_read (addr); - if (!val) - continue; - if ((val & GRUB_PCI_ADDR_SPACE_MASK) == GRUB_PCI_ADDR_SPACE_IO) - cmd |= GRUB_PCI_COMMAND_IO_ENABLED; - else - cmd |= GRUB_PCI_COMMAND_MEM_ENABLED; - } - - class = (grub_pci_read (addr) >> 16) & 0xffff; - - if (class == GRUB_PCI_CLASS_DISPLAY_VGA) - cmd |= GRUB_PCI_COMMAND_IO_ENABLED - | GRUB_PCI_COMMAND_MEM_ENABLED; - - if (class == GRUB_PCI_CLASS_SERIAL_USB) - return 0; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write (addr, cmd); - - return 0; -} - -static void -grub_pci_assign_addresses (void) -{ - struct iterator_ctx ctx; - - { - struct resource resources[MAX_DEVICES * 6]; - int done; - unsigned i; - ctx.nresources = 0; - ctx.resources = resources; - grub_uint32_t memptr = 0xf0000000; - grub_uint16_t ioptr = 0x1000; - - grub_pci_iterate (find_resources, &ctx); - /* FIXME: do we need a better sort here? */ - do - { - done = 0; - for (i = 0; i + 1 < ctx.nresources; i++) - if (resources[i].size < resources[i+1].size) - { - struct resource t; - t = resources[i]; - resources[i] = resources[i+1]; - resources[i+1] = t; - done = 1; - } - } - while (done); - - for (i = 0; i < ctx.nresources; i++) - { - grub_pci_address_t addr; - addr = grub_pci_make_address (resources[i].dev, - GRUB_PCI_REG_ADDRESS_REG0 - + 4 * resources[i].bar); - if ((resources[i].type & GRUB_PCI_ADDR_SPACE_MASK) - == GRUB_PCI_ADDR_SPACE_IO) - { - grub_pci_write (addr, ioptr | resources[i].type); - ioptr += resources[i].size; - } - else - { - grub_pci_write (addr, memptr | resources[i].type); - memptr += resources[i].size; - if ((resources[i].type & (GRUB_PCI_ADDR_MEM_TYPE_MASK - | GRUB_PCI_ADDR_SPACE_MASK)) - == (GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_64)) - { - addr = grub_pci_make_address (resources[i].dev, - GRUB_PCI_REG_ADDRESS_REG0 - + 4 * resources[i].bar + 4); - grub_pci_write (addr, 0); - } - } - } - grub_pci_iterate (enable_cards, NULL); - } -} - -void -grub_machine_init (void) -{ - grub_modbase = grub_core_entry_addr + (_edata - _start); - - grub_pci_assign_addresses (); - - grub_qemu_init_cirrus (); - - grub_vga_text_init (); - - grub_machine_mmap_init (); - grub_machine_mmap_iterate (heap_init, NULL); - - - grub_tsc_init (); -} - -void -grub_machine_get_bootlocation (char **device __attribute__ ((unused)), - char **path __attribute__ ((unused))) -{ -} - -void -grub_machine_fini (int flags) -{ - if (flags & GRUB_LOADER_FLAG_NORETURN) - grub_vga_text_fini (); - grub_stop_floppy (); -} diff --git a/grub-core/kern/i386/tsc.c b/grub-core/kern/i386/tsc.c deleted file mode 100644 index 9293b161d..000000000 --- a/grub-core/kern/i386/tsc.c +++ /dev/null @@ -1,78 +0,0 @@ -/* kern/i386/tsc.c - x86 TSC time source implementation - * Requires Pentium or better x86 CPU that supports the RDTSC instruction. - * This module calibrates 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 . - */ - -#include -#include -#include -#include -#include - -/* 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 ms per 2^32 ticks) */ -/* We assume that the tick is less than 1 ms and hence this value fits - in 32-bit. */ -grub_uint32_t grub_tsc_rate; - -static grub_uint64_t -grub_tsc_get_time_ms (void) -{ - grub_uint64_t a = grub_get_tsc () - tsc_boot_time; - grub_uint64_t ah = a >> 32; - grub_uint64_t al = a & 0xffffffff; - - return ((al * grub_tsc_rate) >> 32) + ah * grub_tsc_rate; -} - -static int -calibrate_tsc_hardcode (void) -{ - grub_tsc_rate = 5368;/* 800 MHz */ - return 1; -} - -void -grub_tsc_init (void) -{ - if (!grub_cpu_is_tsc_supported ()) - { -#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_IEEE1275) - grub_install_get_time_ms (grub_rtc_get_time_ms); -#else - grub_fatal ("no TSC found"); -#endif - return; - } - - tsc_boot_time = grub_get_tsc (); - -#if defined (GRUB_MACHINE_XEN) || defined (GRUB_MACHINE_XEN_PVH) - (void) (grub_tsc_calibrate_from_xen () || calibrate_tsc_hardcode()); -#elif defined (GRUB_MACHINE_EFI) - (void) (grub_tsc_calibrate_from_pmtimer () || grub_tsc_calibrate_from_pit () || grub_tsc_calibrate_from_efi() || calibrate_tsc_hardcode()); -#elif defined (GRUB_MACHINE_COREBOOT) - (void) (grub_tsc_calibrate_from_pmtimer () || grub_tsc_calibrate_from_pit () || calibrate_tsc_hardcode()); -#else - (void) (grub_tsc_calibrate_from_pit () || calibrate_tsc_hardcode()); -#endif - grub_install_get_time_ms (grub_tsc_get_time_ms); -} diff --git a/grub-core/kern/i386/tsc_pit.c b/grub-core/kern/i386/tsc_pit.c deleted file mode 100644 index 67990bfa6..000000000 --- a/grub-core/kern/i386/tsc_pit.c +++ /dev/null @@ -1,84 +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 PIT 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 . - */ - -#include -#include -#include -#include -#include -#include - -static int -grub_pit_wait (void) -{ - int ret = 0; - - /* Disable timer2 gate and speaker. */ - grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT) - & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2), - GRUB_PIT_SPEAKER_PORT); - - /* Set tics. */ - grub_outb (GRUB_PIT_CTRL_SELECT_2 | GRUB_PIT_CTRL_READLOAD_WORD, - GRUB_PIT_CTRL); - /* 0xffff ticks: 55ms. */ - grub_outb (0xff, GRUB_PIT_COUNTER_2); - grub_outb (0xff, GRUB_PIT_COUNTER_2); - - /* Enable timer2 gate, keep speaker disabled. */ - grub_outb ((grub_inb (GRUB_PIT_SPEAKER_PORT) & ~ GRUB_PIT_SPK_DATA) - | GRUB_PIT_SPK_TMR2, - GRUB_PIT_SPEAKER_PORT); - - if ((grub_inb (GRUB_PIT_SPEAKER_PORT) & GRUB_PIT_SPK_TMR2_LATCH) == 0x00) { - ret = 1; - /* Wait. */ - while ((grub_inb (GRUB_PIT_SPEAKER_PORT) & GRUB_PIT_SPK_TMR2_LATCH) == 0x00); - } - - /* Disable timer2 gate and speaker. */ - grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT) - & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2), - GRUB_PIT_SPEAKER_PORT); - - return ret; -} - -/* Calibrate the TSC based on the RTC. */ -int -grub_tsc_calibrate_from_pit (void) -{ - /* First calibrate the TSC rate (relative, not absolute time). */ - grub_uint64_t start_tsc, end_tsc; - - start_tsc = grub_get_tsc (); - if (!grub_pit_wait ()) - return 0; - end_tsc = grub_get_tsc (); - - grub_tsc_rate = 0; - if (end_tsc > start_tsc) - grub_tsc_rate = grub_divmod64 ((55ULL << 32), end_tsc - start_tsc, 0); - if (grub_tsc_rate == 0) - return 0; - return 1; -} diff --git a/grub-core/kern/i386/tsc_pmtimer.c b/grub-core/kern/i386/tsc_pmtimer.c deleted file mode 100644 index dd044590d..000000000 --- a/grub-core/kern/i386/tsc_pmtimer.c +++ /dev/null @@ -1,157 +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 PIT 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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -grub_uint64_t -grub_pmtimer_wait_count_tsc (grub_port_t pmtimer, - grub_uint16_t num_pm_ticks) -{ - grub_uint32_t start; - grub_uint64_t cur, end; - grub_uint64_t start_tsc; - grub_uint64_t end_tsc; - grub_uint32_t num_iter = 0; - int bad_reads = 0; - - /* - * Some timers are 24-bit and some are 32-bit, but it doesn't make much - * difference to us. Caring which one we have isn't really worth it since - * the low-order digits will give us enough data to calibrate TSC. So just - * mask the top-order byte off. - */ - cur = start = grub_inl (pmtimer) & 0x00ffffffUL; - end = start + num_pm_ticks; - start_tsc = grub_get_tsc (); - while (1) - { - cur &= 0xffffffffff000000ULL; - - /* Only take the low-order 24-bit for the reason explained above. */ - cur |= grub_inl (pmtimer) & 0x00ffffffUL; - - end_tsc = grub_get_tsc(); - - /* - * If we get 10 reads in a row that are obviously dead pins, there's no - * reason to do this thousands of times. - */ - if (cur == 0xffffffUL || cur == 0) - { - bad_reads++; - grub_dprintf ("pmtimer", - "pmtimer: 0x%"PRIxGRUB_UINT64_T" bad_reads: %d\n", - cur, bad_reads); - - if (bad_reads == 10) - { - grub_dprintf ("pmtimer", "timer is broken; giving up.\n"); - return 0; - } - } - - if (cur < start) - cur += 0x1000000; - - if (cur >= end) - { - grub_dprintf ("pmtimer", "pmtimer delta is 0x%"PRIxGRUB_UINT64_T"\n", - cur - start); - grub_dprintf ("pmtimer", "tsc delta is 0x%"PRIxGRUB_UINT64_T"\n", - end_tsc - start_tsc); - return end_tsc - start_tsc; - } - - /* - * Check for broken PM timer. 1ms at 10GHz should be 1E+7 TSCs; at - * 250MHz it should be 2.5E5. So if after 4E+7 TSCs on a 10GHz machine, - * we should have seen pmtimer show 4ms of change (i.e. cur =~ start + 14320); - * on a 250MHz machine that should be 160ms (start + 572800). If after - * this a time we still don't have 1ms on pmtimer, then pmtimer is broken. - * - * Likewise, if our code is perfectly efficient and introduces no delays - * whatsoever, on a 10GHz system we should see a TSC delta of 3580 in - * ~3580 iterations. On a 250MHz machine that should be ~900 iterations. - * - * With those factors in mind, there are two limits here. There's a hard - * limit here at 8x our desired pm timer delta. This limit was picked as - * an arbitrarily large value that's still not a lot of time to humans, - * because if we get that far this is either an implausibly fast machine - * or the pmtimer is not running. And there is another limit on a 4 ms TSC - * delta on a 10 GHz clock, without seeing cur converge on our target value. - */ - if ((++num_iter > (grub_uint32_t) num_pm_ticks << 3UL) || end_tsc - start_tsc > 40000000) - { - grub_dprintf ("pmtimer", - "pmtimer delta is 0x%"PRIxGRUB_UINT64_T" (%"PRIxGRUB_UINT32_T" iterations)\n", - cur - start, num_iter); - grub_dprintf ("pmtimer", - "tsc delta is implausible: 0x%"PRIxGRUB_UINT64_T"\n", - end_tsc - start_tsc); - return 0; - } - } -} - -int -grub_tsc_calibrate_from_pmtimer (void) -{ - struct grub_acpi_fadt *fadt; - grub_port_t pmtimer; - grub_uint64_t tsc_diff; - - fadt = grub_acpi_find_fadt (); - if (!fadt) - { - grub_dprintf ("pmtimer", "No FADT found; not using pmtimer.\n"); - return 0; - } - pmtimer = fadt->pmtimer; - if (!pmtimer) - { - grub_dprintf ("pmtimer", "FADT does not specify pmtimer; skipping.\n"); - return 0; - } - - /* It's 3.579545 MHz clock. Wait 1 ms. */ - tsc_diff = grub_pmtimer_wait_count_tsc (pmtimer, 3580); - if (tsc_diff == 0) - return 0; - grub_tsc_rate = grub_divmod64 ((1ULL << 32), tsc_diff, 0); - /* - * Specifically, when the tsc_diff (end_tsc - start_tsc) is greater than (1ULL << 32), - * the result of grub_divmod64() becomes zero, causing grub_tsc_rate to always be zero. - * As a result, grub_tsc_get_time_ms() consistently returns zero, and the GRUB menu - * countdown gets stuck. To resolve this, we return 0 to proceed to the next calibration - * function when grub_tsc_rate is zero. - */ - if (grub_tsc_rate == 0) - return 0; - - return 1; -} diff --git a/grub-core/kern/i386/xen/hypercall.S b/grub-core/kern/i386/xen/hypercall.S deleted file mode 100644 index 09d75c3a5..000000000 --- a/grub-core/kern/i386/xen/hypercall.S +++ /dev/null @@ -1,43 +0,0 @@ -/* hypercall.S - wrappers for Xen hypercalls */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -FUNCTION(grub_xen_hypercall) - pushl %ebp - movl %esp, %ebp - pushl %esi - pushl %edi - pushl %ebx - - /* call number already in %eax. */ - /* %edx -> %ebx*/ - /* %ecx -> %ecx*/ - movl %edx, %ebx - movl 8(%ebp), %edx - movl 12(%ebp), %esi - movl 16(%ebp), %edi - movl 20(%ebp), %ebp - int $0x82 - popl %ebx - popl %edi - popl %esi - popl %ebp - ret diff --git a/grub-core/kern/i386/xen/pvh.c b/grub-core/kern/i386/xen/pvh.c deleted file mode 100644 index 91fbca859..000000000 --- a/grub-core/kern/i386/xen/pvh.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define XEN_MEMORY_MAP_SIZE 128 - -grub_uint64_t grub_rsdp_addr; - -static char hypercall_page[GRUB_XEN_PAGE_SIZE] - __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE))); - -static grub_uint32_t xen_cpuid_base; -static struct start_info grub_xen_start_page; -static struct grub_e820_mmap_entry map[XEN_MEMORY_MAP_SIZE]; -static unsigned int nr_map_entries; - -static void -grub_xen_cons_msg (const char *msg) -{ - const char *c; - - for (c = msg; *c; c++) - grub_outb (*c, XEN_HVM_DEBUGCONS_IOPORT); -} - -static void -grub_xen_panic (const char *msg) -{ - grub_xen_cons_msg (msg); - grub_xen_cons_msg ("System halted!\n"); - - asm volatile ("cli"); - - while (1) - { - asm volatile ("hlt"); - } -} - -static void -grub_xen_cpuid_base (void) -{ - grub_uint32_t base, eax, signature[3]; - - for (base = 0x40000000; base < 0x40010000; base += 0x100) - { - grub_cpuid (base, eax, signature[0], signature[1], signature[2]); - if (!grub_memcmp ("XenVMMXenVMM", signature, 12) && (eax - base) >= 2) - { - xen_cpuid_base = base; - return; - } - } - - grub_xen_panic ("Found no Xen signature!\n"); -} - -static void -grub_xen_setup_hypercall_page (void) -{ - grub_uint32_t msr, addr, eax, ebx, ecx, edx; - - /* Get base address of Xen-specific MSRs. */ - grub_cpuid (xen_cpuid_base + 2, eax, ebx, ecx, edx); - msr = ebx; - addr = (grub_uint32_t) (&hypercall_page); - - /* Specify hypercall page address for Xen. */ - asm volatile ("wrmsr" : : "c" (msr), "a" (addr), "d" (0) : "memory"); -} - -int -grub_xen_hypercall (grub_uint32_t callno, grub_uint32_t a0, - grub_uint32_t a1, grub_uint32_t a2, - grub_uint32_t a3, grub_uint32_t a4, - grub_uint32_t a5 __attribute__ ((unused))) -{ - grub_uint32_t res; - - asm volatile ("call *%[callno]" - : "=a" (res), "+b" (a0), "+c" (a1), "+d" (a2), - "+S" (a3), "+D" (a4) - : [callno] "a" (&hypercall_page[callno * 32]) - : "memory"); - return res; -} - -static grub_uint32_t -grub_xen_get_param (int idx) -{ - struct xen_hvm_param xhv; - int r; - - xhv.domid = DOMID_SELF; - xhv.index = idx; - r = grub_xen_hypercall (__HYPERVISOR_hvm_op, HVMOP_get_param, - (grub_uint32_t) (&xhv), 0, 0, 0, 0); - if (r < 0) - grub_xen_panic ("Could not get parameter from Xen!\n"); - return xhv.value; -} - -static void * -grub_xen_add_physmap (unsigned int space, void *addr) -{ - struct xen_add_to_physmap xatp; - - xatp.domid = DOMID_SELF; - xatp.idx = 0; - xatp.space = space; - xatp.gpfn = (grub_addr_t) addr >> GRUB_XEN_LOG_PAGE_SIZE; - if (grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_add_to_physmap, - (grub_uint32_t) (&xatp), 0, 0, 0, 0)) - grub_xen_panic ("Memory_op hypercall failed!\n"); - return addr; -} - -static void -grub_xen_sort_mmap (void) -{ - grub_uint64_t from, to; - unsigned int i; - struct grub_e820_mmap_entry tmp; - - /* Align map entries to page boundaries. */ - for (i = 0; i < nr_map_entries; i++) - { - from = map[i].addr; - to = from + map[i].len; - if (map[i].type == GRUB_MEMORY_AVAILABLE) - { - from = ALIGN_UP (from, GRUB_XEN_PAGE_SIZE); - to = ALIGN_DOWN (to, GRUB_XEN_PAGE_SIZE); - } - else - { - from = ALIGN_DOWN (from, GRUB_XEN_PAGE_SIZE); - to = ALIGN_UP (to, GRUB_XEN_PAGE_SIZE); - } - map[i].addr = from; - map[i].len = to - from; - } - - again: - /* Sort entries by start address. */ - for (i = 1; i < nr_map_entries; i++) - { - if (map[i].addr >= map[i - 1].addr) - continue; - tmp = map[i]; - map[i] = map[i - 1]; - map[i - 1] = tmp; - i = 0; - } - - /* Detect overlapping areas. */ - for (i = 1; i < nr_map_entries; i++) - { - if (map[i].addr >= map[i - 1].addr + map[i - 1].len) - continue; - tmp = map[i - 1]; - map[i - 1].len = map[i].addr - map[i - 1].addr; - if (map[i].addr + map[i].len >= tmp.addr + tmp.len) - continue; - if (nr_map_entries < ARRAY_SIZE (map)) - { - map[nr_map_entries].addr = map[i].addr + map[i].len; - map[nr_map_entries].len = tmp.addr + tmp.len - map[nr_map_entries].addr; - map[nr_map_entries].type = tmp.type; - nr_map_entries++; - goto again; - } - } - - /* Merge adjacent entries. */ - for (i = 1; i < nr_map_entries; i++) - { - if (map[i].type == map[i - 1].type && - map[i].addr == map[i - 1].addr + map[i - 1].len) - { - map[i - 1].len += map[i].len; - map[i] = map[nr_map_entries - 1]; - nr_map_entries--; - goto again; - } - } -} - -static void -grub_xen_get_mmap (void) -{ - struct xen_memory_map memmap; - - memmap.nr_entries = ARRAY_SIZE (map); - set_xen_guest_handle (memmap.buffer, map); - if (grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_memory_map, - (grub_uint32_t) (&memmap), 0, 0, 0, 0)) - grub_xen_panic ("Could not get memory map from Xen!\n"); - nr_map_entries = memmap.nr_entries; - - grub_xen_sort_mmap (); -} - -static void -grub_xen_set_mmap (void) -{ - struct xen_foreign_memory_map memmap; - - memmap.domid = DOMID_SELF; - memmap.map.nr_entries = nr_map_entries; - set_xen_guest_handle (memmap.map.buffer, map); - grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_set_memory_map, - (grub_uint32_t) (&memmap), 0, 0, 0, 0); -} - -static void -grub_xen_mm_init_regions (void) -{ - grub_uint64_t modend, from, to; - unsigned int i; - - modend = grub_modules_get_end (); - - for (i = 0; i < nr_map_entries; i++) - { - if (map[i].type != GRUB_MEMORY_AVAILABLE) - continue; - from = map[i].addr; - to = from + map[i].len; - if (from < modend) - from = modend; - if (from >= to || from >= (1ULL << 32)) - continue; - if (to > (1ULL << 32)) - to = 1ULL << 32; - grub_mm_init_region ((void *) (grub_addr_t) from, to - from); - } -} - -static grub_uint64_t -grub_xen_find_page (grub_uint64_t start) -{ - unsigned int i, j; - grub_uint64_t last = start; - - /* - * Try to find a e820 map hole below 4G. - * Relies on page-aligned entries (addr and len) and input (start). - */ - - for (i = 0; i < nr_map_entries; i++) - { - if (last > map[i].addr + map[i].len) - continue; - if (last < map[i].addr) - return last; - if ((map[i].addr >> 32) || ((map[i].addr + map[i].len) >> 32)) - break; - last = map[i].addr + map[i].len; - } - if (i == nr_map_entries) - return last; - - /* No hole found, use the highest RAM page below 4G and reserve it. */ - if (nr_map_entries == ARRAY_SIZE (map)) - grub_xen_panic ("Memory map size limit reached!\n"); - for (i = 0, j = 0; i < nr_map_entries; i++) - { - if (map[i].type != GRUB_MEMORY_AVAILABLE) - continue; - if (map[i].addr >> 32) - break; - j = i; - if ((map[i].addr + map[i].len) >> 32) - break; - } - if (map[j].type != GRUB_MEMORY_AVAILABLE) - grub_xen_panic ("No free memory page found!\n"); - if ((map[j].addr + map[j].len) >> 32) - last = (1ULL << 32) - GRUB_XEN_PAGE_SIZE; - else - last = map[j].addr + map[j].len - GRUB_XEN_PAGE_SIZE; - map[nr_map_entries].addr = last; - map[nr_map_entries].len = GRUB_XEN_PAGE_SIZE; - map[nr_map_entries].type = GRUB_MEMORY_RESERVED; - nr_map_entries++; - grub_xen_sort_mmap (); - - return last; -} - -void -grub_xen_setup_pvh (void) -{ - grub_addr_t par; - - grub_xen_cpuid_base (); - grub_xen_setup_hypercall_page (); - grub_xen_get_mmap (); - - /* Setup Xen data. */ - grub_xen_start_page_addr = &grub_xen_start_page; - - par = grub_xen_get_param (HVM_PARAM_CONSOLE_PFN); - grub_xen_start_page_addr->console.domU.mfn = par; - grub_xen_xcons = (void *) (grub_addr_t) (par << GRUB_XEN_LOG_PAGE_SIZE); - par = grub_xen_get_param (HVM_PARAM_CONSOLE_EVTCHN); - grub_xen_start_page_addr->console.domU.evtchn = par; - - par = grub_xen_get_param (HVM_PARAM_STORE_PFN); - grub_xen_start_page_addr->store_mfn = par; - grub_xen_xenstore = (void *) (grub_addr_t) (par << GRUB_XEN_LOG_PAGE_SIZE); - par = grub_xen_get_param (HVM_PARAM_STORE_EVTCHN); - grub_xen_start_page_addr->store_evtchn = par; - - par = grub_xen_find_page (0); - grub_xen_grant_table = grub_xen_add_physmap (XENMAPSPACE_grant_table, - (void *) par); - par = grub_xen_find_page (par + GRUB_XEN_PAGE_SIZE); - grub_xen_shared_info = grub_xen_add_physmap (XENMAPSPACE_shared_info, - (void *) par); - grub_xen_set_mmap (); - - grub_xen_mm_init_regions (); - - grub_rsdp_addr = pvh_start_info->rsdp_paddr; -} - -grub_err_t -grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) -{ - unsigned int i; - - for (i = 0; i < nr_map_entries; i++) - { - if (map[i].len && hook (map[i].addr, map[i].len, map[i].type, hook_data)) - break; - } - - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/i386/xen/startup_pvh.S b/grub-core/kern/i386/xen/startup_pvh.S deleted file mode 100644 index 363c31858..000000000 --- a/grub-core/kern/i386/xen/startup_pvh.S +++ /dev/null @@ -1,81 +0,0 @@ -/* startup.S - bootstrap GRUB itself */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - - .file "startup_pvh.S" - .text - .globl start, _start - .code32 - -start: -_start: - cld - lgdt gdtdesc - ljmp $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $1f -1: - movl $GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %eax - mov %eax, %ds - mov %eax, %es - mov %eax, %fs - mov %eax, %gs - mov %eax, %ss - leal LOCAL(stack_end), %esp - - /* Save address of start info structure. */ - mov %ebx, pvh_start_info - call EXT_C(grub_main) - /* Doesn't return. */ - - .p2align 3 -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 - - .p2align 3 -/* this is the GDT descriptor */ -gdtdesc: - .word 0x17 /* limit */ - .long gdt /* addr */ - - .p2align 2 -/* Saved pointer to start info structure. */ - .globl pvh_start_info -pvh_start_info: - .long 0 - - .bss - .space GRUB_MEMORY_MACHINE_PROT_STACK_SIZE -LOCAL(stack_end): diff --git a/grub-core/kern/i386/xen/tsc.c b/grub-core/kern/i386/xen/tsc.c deleted file mode 100644 index 8792b308d..000000000 --- a/grub-core/kern/i386/xen/tsc.c +++ /dev/null @@ -1,40 +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 PIT 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 . - */ - -#include -#include -#include -#include -#include - -int -grub_tsc_calibrate_from_xen (void) -{ - grub_uint64_t t; - t = grub_xen_shared_info->vcpu_info[0].time.tsc_to_system_mul; - if (grub_xen_shared_info->vcpu_info[0].time.tsc_shift > 0) - t <<= grub_xen_shared_info->vcpu_info[0].time.tsc_shift; - else - t >>= -grub_xen_shared_info->vcpu_info[0].time.tsc_shift; - grub_tsc_rate = grub_divmod64 (t, 1000000, 0); - return 1; -} diff --git a/grub-core/kern/ia64/cache.c b/grub-core/kern/ia64/cache.c deleted file mode 100644 index 13efd308f..000000000 --- a/grub-core/kern/ia64/cache.c +++ /dev/null @@ -1,35 +0,0 @@ -/* init.c - initialize an ia64-based EFI system */ -/* - * 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 . - */ - -#include -#include - -void -grub_arch_sync_caches (void *address, grub_size_t len) -{ - /* Cache line length is at least 32. */ - len += (grub_uint64_t)address & 0x1f; - grub_uint64_t a = (grub_uint64_t)address & ~0x1f; - - /* Flush data. */ - for (len = (len + 31) & ~0x1f; len > 0; len -= 0x20, a += 0x20) - asm volatile ("fc.i %0" : : "r" (a)); - /* Sync and serialize. Maybe extra. */ - asm volatile (";; sync.i;; srlz.i;;"); -} diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c deleted file mode 100644 index db59300fe..000000000 --- a/grub-core/kern/ia64/dl.c +++ /dev/null @@ -1,150 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -#define MASK19 ((1 << 19) - 1) -#define MASK20 ((1 << 20) - 1) - -/* 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] != ELFDATA2LSB - || e->e_machine != EM_IA_64) - return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); - - return GRUB_ERR_NONE; -} - -#pragma GCC diagnostic ignored "-Wcast-align" - -/* Relocate symbols. */ -grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - Elf_Shdr *s, grub_dl_segment_t seg) -{ - Elf_Rela *rel, *max; - - for (rel = (Elf_Rela *) ((char *) ehdr + s->sh_offset), - max = (Elf_Rela *) ((char *) rel + s->sh_size); - rel < max; - rel = (Elf_Rela *) ((char *) rel + s->sh_entsize)) - { - grub_addr_t addr; - Elf_Sym *sym; - grub_uint64_t value; - - if (seg->size < (rel->r_offset & ~3)) - return grub_error (GRUB_ERR_BAD_MODULE, - "reloc offset is out of the segment"); - - addr = (grub_addr_t) seg->addr + rel->r_offset; - sym = (Elf_Sym *) ((char *) mod->symtab - + mod->symsize * 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_IA64_PCREL21B: - { - grub_int64_t noff; - if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) - { - struct grub_ia64_trampoline *tr = mod->trampptr; - grub_ia64_make_trampoline (tr, value); - noff = ((char *) tr - (char *) (addr & ~3)) >> 4; - mod->trampptr = tr + 1; - } - else - noff = ((char *) value - (char *) (addr & ~3)) >> 4; - - if ((noff & ~MASK19) && ((-noff) & ~MASK19)) - return grub_error (GRUB_ERR_BAD_MODULE, - "jump offset too big (%lx)", noff); - grub_ia64_add_value_to_slot_20b (addr, noff); - } - break; - case R_IA64_SEGREL64LSB: - *(grub_uint64_t *) addr += value - (grub_addr_t) seg->addr; - break; - case R_IA64_FPTR64LSB: - case R_IA64_DIR64LSB: - *(grub_uint64_t *) addr += value; - break; - case R_IA64_PCREL64LSB: - *(grub_uint64_t *) addr += value - addr; - break; - case R_IA64_GPREL64I: - grub_ia64_set_immu64 (addr, value - (grub_addr_t) mod->base); - break; - case R_IA64_GPREL22: - if ((value - (grub_addr_t) mod->base) & ~MASK20) - return grub_error (GRUB_ERR_BAD_MODULE, - "gprel offset too big (%lx)", - value - (grub_addr_t) mod->base); - grub_ia64_add_value_to_slot_21 (addr, value - (grub_addr_t) mod->base); - break; - - case R_IA64_LTOFF22X: - case R_IA64_LTOFF22: - if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) - value = *(grub_uint64_t *) sym->st_value + rel->r_addend; - /* Fallthrough. */ - case R_IA64_LTOFF_FPTR22: - { - grub_uint64_t *gpptr = mod->gotptr; - *gpptr = value; - if (((grub_addr_t) gpptr - (grub_addr_t) mod->base) & ~MASK20) - return grub_error (GRUB_ERR_BAD_MODULE, - "gprel offset too big (%lx)", - (grub_addr_t) gpptr - (grub_addr_t) mod->base); - grub_ia64_add_value_to_slot_21 (addr, (grub_addr_t) gpptr - (grub_addr_t) mod->base); - mod->gotptr = gpptr + 1; - break; - } - /* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */ - case R_IA64_LDXMOV: - break; - default: - { - char rel_info[17]; /* log16(2^64) = 16, plus NUL. */ - - grub_snprintf (rel_info, sizeof (rel_info) - 1, "%" PRIxGRUB_UINT64_T, - ELF_R_TYPE (rel->r_info)); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%s is not implemented yet"), rel_info); - } - } - } - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/ia64/dl_helper.c b/grub-core/kern/ia64/dl_helper.c deleted file mode 100644 index 05a0a68db..000000000 --- a/grub-core/kern/ia64/dl_helper.c +++ /dev/null @@ -1,241 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -#pragma GCC diagnostic ignored "-Wcast-align" - -#define MASK20 ((1 << 20) - 1) -#define MASK3 (~(grub_addr_t) 3) - -void -grub_ia64_set_immu64 (grub_addr_t addr, grub_uint64_t val) -{ - /* Copied from binutils. */ - grub_uint64_t *ptr = ((grub_uint64_t *) (addr & MASK3)); - grub_uint64_t t0, t1; - - t0 = grub_le_to_cpu64 (ptr[0]); - t1 = grub_le_to_cpu64 (ptr[1]); - - /* tmpl/s: bits 0.. 5 in t0 - slot 0: bits 5..45 in t0 - slot 1: bits 46..63 in t0, bits 0..22 in t1 - slot 2: bits 23..63 in t1 */ - - /* First, clear the bits that form the 64 bit constant. */ - t0 &= ~(0x3ffffLL << 46); - t1 &= ~(0x7fffffLL - | (( (0x07fLL << 13) | (0x1ffLL << 27) - | (0x01fLL << 22) | (0x001LL << 21) - | (0x001LL << 36)) << 23)); - - t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */ - t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */ - t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */ - | (((val >> 7) & 0x1ff) << 27) /* imm9d */ - | (((val >> 16) & 0x01f) << 22) /* imm5c */ - | (((val >> 21) & 0x001) << 21) /* ic */ - | (((val >> 63) & 0x001) << 36)) << 23; /* i */ - - ptr[0] = t0; - ptr[1] = t1; -} - -void -grub_ia64_add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value) -{ - grub_uint32_t val; - switch (addr & 3) - { - case 0: - val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *) - (addr & MASK3) + 2))); - val = (((((val & MASK20) + value) & MASK20) << 2) - | (val & ~(MASK20 << 2))); - grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 2), - grub_cpu_to_le32 (val)); - break; - case 1: - val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *) - (addr & MASK3) + 7))); - val = ((((((val >> 3) & MASK20) + value) & MASK20) << 3) - | (val & ~(MASK20 << 3))); - grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 7), - grub_cpu_to_le32 (val)); - break; - case 2: - val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *) - (addr & MASK3) + 12))); - val = ((((((val >> 4) & MASK20) + value) & MASK20) << 4) - | (val & ~(MASK20 << 4))); - grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 12), - grub_cpu_to_le32 (val)); - break; - } -} - -#define MASKF21 ( ((1 << 23) - 1) & ~((1 << 7) | (1 << 8)) ) - -static grub_uint32_t -add_value_to_slot_21_real (grub_uint32_t a, grub_uint32_t value) -{ - grub_uint32_t high, mid, low, c; - low = (a & 0x00007f); - mid = (a & 0x7fc000) >> 7; - high = (a & 0x003e00) << 7; - c = (low | mid | high) + value; - return (c & 0x7f) | ((c << 7) & 0x7fc000) | ((c >> 7) & 0x0003e00); //0x003e00 -} - -void -grub_ia64_add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value) -{ - grub_uint32_t val; - switch (addr & 3) - { - case 0: - val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *) - (addr & MASK3) + 2))); - val = ((add_value_to_slot_21_real (((val >> 2) & MASKF21), value) - & MASKF21) << 2) | (val & ~(MASKF21 << 2)); - grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 2), - grub_cpu_to_le32 (val)); - break; - case 1: - val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *) - (addr & MASK3) + 7))); - val = ((add_value_to_slot_21_real (((val >> 3) & MASKF21), value) - & MASKF21) << 3) | (val & ~(MASKF21 << 3)); - grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 7), - grub_cpu_to_le32 (val)); - break; - case 2: - val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *) - (addr & MASK3) + 12))); - val = ((add_value_to_slot_21_real (((val >> 4) & MASKF21), value) - & MASKF21) << 4) | (val & ~(MASKF21 << 4)); - grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 12), - grub_cpu_to_le32 (val)); - break; - } -} - -static const grub_uint8_t nopm[5] = - { - /* [MLX] nop.m 0x0 */ - 0x05, 0x00, 0x00, 0x00, 0x01 - }; - -#ifdef GRUB_UTIL -static grub_uint8_t jump[0x20] = - { - /* [MMI] add r15=r15,r1;; */ - 0x0b, 0x78, 0x3c, 0x02, 0x00, 0x20, - /* ld8 r16=[r15],8 */ - 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, - /* mov r14=r1;; */ - 0x01, 0x08, 0x00, 0x84, - /* [MIB] ld8 r1=[r15] */ - 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, - /* mov b6=r16 */ - 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, - /* br.few b6;; */ - 0x60, 0x00, 0x80, 0x00 - }; -#else -static const grub_uint8_t jump[0x20] = - { - /* ld8 r16=[r15],8 */ - 0x02, 0x80, 0x20, 0x1e, 0x18, 0x14, - /* mov r14=r1;; */ - 0xe0, 0x00, 0x04, 0x00, 0x42, 0x00, - /* nop.i 0x0 */ - 0x00, 0x00, 0x04, 0x00, - /* ld8 r1=[r15] */ - 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, - /* mov b6=r16 */ - 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, - /* br.few b6;; */ - 0x60, 0x00, 0x80, 0x00 - }; -#endif - -void -grub_ia64_make_trampoline (struct grub_ia64_trampoline *tr, grub_uint64_t addr) -{ - grub_memcpy (tr->nop, nopm, sizeof (tr->nop)); - tr->addr_hi[0] = ((addr & 0xc00000) >> 16); - tr->addr_hi[1] = (addr >> 24) & 0xff; - tr->addr_hi[2] = (addr >> 32) & 0xff; - tr->addr_hi[3] = (addr >> 40) & 0xff; - tr->addr_hi[4] = (addr >> 48) & 0xff; - tr->addr_hi[5] = (addr >> 56) & 0xff; - tr->e0 = 0xe0; - tr->addr_lo[0] = ((addr & 0x000f) << 4) | 0x01; - tr->addr_lo[1] = (((addr & 0x0070) >> 4) | ((addr & 0x070000) >> 11) - | ((addr & 0x200000) >> 17)); - tr->addr_lo[2] = ((addr & 0x1f80) >> 5) | ((addr & 0x180000) >> 19); - tr->addr_lo[3] = ((addr & 0xe000) >> 13) | 0x60; - grub_memcpy (tr->jump, jump, sizeof (tr->jump)); -} - -grub_err_t -grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, - grub_size_t *got) -{ - const Elf64_Ehdr *e = ehdr; - grub_size_t cntt = 0, cntg = 0; - const Elf64_Shdr *s; - unsigned i; - - for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu64 (e->e_shoff)); - i < grub_le_to_cpu16 (e->e_shnum); - i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize))) - if (s->sh_type == grub_cpu_to_le32_compile_time (SHT_RELA)) - { - const Elf64_Rela *rel, *max; - - for (rel = (Elf64_Rela *) ((char *) e + grub_le_to_cpu64 (s->sh_offset)), - max = (const Elf64_Rela *) ((char *) rel + grub_le_to_cpu64 (s->sh_size)); - rel < max; rel = (const Elf64_Rela *) ((char *) rel + grub_le_to_cpu64 (s->sh_entsize))) - switch (ELF64_R_TYPE (grub_le_to_cpu64 (rel->r_info))) - { - case R_IA64_PCREL21B: - cntt++; - break; - case R_IA64_LTOFF_FPTR22: - case R_IA64_LTOFF22X: - case R_IA64_LTOFF22: - cntg++; - break; - } - } - *tramp = cntt * sizeof (struct grub_ia64_trampoline); - *got = cntg * sizeof (grub_uint64_t); - - return GRUB_ERR_NONE; -} - diff --git a/grub-core/kern/ia64/efi/init.c b/grub-core/kern/ia64/efi/init.c deleted file mode 100644 index f8de85398..000000000 --- a/grub-core/kern/ia64/efi/init.c +++ /dev/null @@ -1,80 +0,0 @@ -/* init.c - initialize an ia64-based EFI system */ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static grub_uint64_t divisor = 1; - -static grub_uint64_t -get_itc (void) -{ - grub_uint64_t ret; - asm volatile ("mov %0=ar.itc" : "=r" (ret)); - return ret; -} - -grub_uint64_t -grub_rtc_get_time_ms (void) -{ - return get_itc () / divisor; -} - -void -grub_machine_init (void) -{ - grub_efi_event_t event; - grub_uint64_t before, after; - grub_efi_uintn_t idx; - grub_efi_init (); - - grub_efi_system_table->boot_services->create_event (GRUB_EFI_EVT_TIMER, - GRUB_EFI_TPL_CALLBACK, - 0, 0, &event); - - before = get_itc (); - grub_efi_system_table->boot_services->set_timer (event, GRUB_EFI_TIMER_RELATIVE, - 200000); - grub_efi_system_table->boot_services->wait_for_event (1, &event, &idx); - after = get_itc (); - grub_efi_system_table->boot_services->close_event (event); - divisor = (after - before + 5) / 20; - if (divisor == 0) - divisor = 800000; - grub_install_get_time_ms (grub_rtc_get_time_ms); -} - -void -grub_machine_fini (int flags) -{ - if (!(flags & GRUB_LOADER_FLAG_NORETURN)) - return; - - grub_efi_fini (); - - if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) - grub_efi_memory_fini (); -} diff --git a/grub-core/kern/ia64/efi/startup.S b/grub-core/kern/ia64/efi/startup.S deleted file mode 100644 index d75c6d7cc..000000000 --- a/grub-core/kern/ia64/efi/startup.S +++ /dev/null @@ -1,44 +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 . - */ -#include -#include -#include - - .text - .psr abi64 - .psr lsb - .lsb - - .global _start - .proc _start -_start: - alloc loc0=ar.pfs,2,4,0,0 - mov loc1=rp - addl loc2=@gprel(grub_efi_image_handle),gp - addl loc3=@gprel(grub_efi_system_table),gp - ;; - st8 [loc2]=in0 - st8 [loc3]=in1 - br.call.sptk.few rp=grub_main - ;; - mov ar.pfs=loc0 - mov rp=loc1 - ;; - br.ret.sptk.few rp - - .endp _start diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c deleted file mode 100644 index a5586f85b..000000000 --- a/grub-core/kern/ieee1275/init.c +++ /dev/null @@ -1,1047 +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 . - */ - -#include /* offsetof() */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef __sparc__ -#include -#endif -#include -#include -#include -#include -#include -#ifdef __i386__ -#include -#endif -#ifdef __sparc__ -#include -#endif -#if defined(__powerpc__) || defined(__i386__) -#include -#endif - -/* The maximum heap size we're going to claim at boot. Not used by sparc. */ -#ifdef __i386__ -#define HEAP_MAX_SIZE (unsigned long) (64 * 1024 * 1024) -#else /* __powerpc__ */ -#define HEAP_MAX_SIZE (unsigned long) (32 * 1024 * 1024) -#endif - -/* RMO max. address at 768 MB */ -#define RMO_ADDR_MAX (grub_uint64_t) (768 * 1024 * 1024) - -/* - * The amount of OF space we will not claim here so as to leave space for - * the loader and linux to service early allocations. - * - * In 2021, Daniel Axtens claims that we should leave at least 128MB to - * ensure we can load a stock kernel and initrd on a pseries guest with - * a 512MB real memory area under PowerVM. - */ -#define RUNTIME_MIN_SPACE (128UL * 1024 * 1024) - -extern char _start[]; -extern char _end[]; - -#ifdef __sparc__ -grub_addr_t grub_ieee1275_original_stack; -#endif - -/* Options vector5 properties. */ - -#define LPAR 0x80 -#define SPLPAR 0x40 -#define DYN_RCON_MEM 0x20 -#define LARGE_PAGES 0x10 -#define DONATE_DCPU_CLS 0x02 -#define PCI_EXP 0x01 -#define BYTE2 (LPAR | SPLPAR | DYN_RCON_MEM | LARGE_PAGES | DONATE_DCPU_CLS | PCI_EXP) - -#define CMOC 0x80 -#define EXT_CMO 0x40 -#define CMO (CMOC | EXT_CMO) - -#define ASSOC_REF 0x80 -#define AFFINITY 0x40 -#define NUMA 0x20 -#define ASSOCIATIVITY (ASSOC_REF | AFFINITY | NUMA) - -#define HOTPLUG_INTRPT 0x04 -#define HPT_RESIZE 0x01 -#define BIN_OPTS (HOTPLUG_INTRPT | HPT_RESIZE) - -#define MAX_CPU 256 - -#define PFO_HWRNG 0x80000000 -#define PFO_HW_COMP 0x40000000 -#define PFO_ENCRYPT 0x20000000 -#define PLATFORM_FACILITIES (PFO_HWRNG | PFO_HW_COMP | PFO_ENCRYPT) - -#define SUB_PROCESSORS 1 - -#define DY_MEM_V2 0x80 -#define DRC_INFO 0x40 -#define BYTE22 (DY_MEM_V2 | DRC_INFO) - -/* For ibm,arch-vec-5-platform-support. */ -#define XIVE_INDEX 0x17 -#define MMU_INDEX 0x18 -#define RADIX_GTSE_INDEX 0x1a -#define RADIX_ENABLED 0x40 -#define XIVE_ENABLED 0x40 -#define HASH_ENABLED 0x00 -#define MAX_SUPPORTED 0xC0 -#define RADIX_GTSE_ENABLED 0x40 - -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_ieee1275_net_config) (const char *dev, char **device, char **path, - char *bootpath); -void -grub_machine_get_bootlocation (char **device, char **path) -{ - char *bootpath; - char *filename; - char *type; - - bootpath = grub_ieee1275_get_boot_dev (); - if (! bootpath) - return; - - /* Transform an OF device path to a GRUB path. */ - - type = grub_ieee1275_get_device_type (bootpath); - if (type && grub_strcmp (type, "network") == 0) - { - char *dev, *canon; - char *ptr; - dev = grub_ieee1275_get_aliasdevname (bootpath); - canon = grub_ieee1275_canonicalise_devname (dev); - if (! canon) - return; - ptr = canon + grub_strlen (canon) - 1; - while (ptr > canon && (*ptr == ',' || *ptr == ':')) - ptr--; - ptr++; - *ptr = 0; - - if (grub_ieee1275_net_config) - grub_ieee1275_net_config (canon, device, path, bootpath); - grub_free (dev); - grub_free (canon); - } - else - *device = grub_ieee1275_encode_devname (bootpath); - grub_free (type); - - filename = grub_ieee1275_get_filename (bootpath); - if (filename) - { - char *lastslash = grub_strrchr (filename, '\\'); - - /* Truncate at last directory. */ - if (lastslash) - { - *lastslash = '\0'; - grub_translate_ieee1275_path (filename); - - *path = filename; - } - } - grub_free (bootpath); -} - -/* Claim some available memory in the first /memory node. */ -#ifdef __sparc__ -static void -grub_claim_heap (void) -{ - grub_mm_init_region ((void *) (grub_modules_get_end () - + GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000); -} -#else -/* Helpers for mm on powerpc. */ - -/* ibm,kernel-dump data structures */ -struct kd_section -{ - grub_uint32_t flags; - grub_uint16_t src_datatype; -#define KD_SRC_DATATYPE_REAL_MODE_REGION 0x0011 - grub_uint16_t error_flags; - grub_uint64_t src_address; - grub_uint64_t num_bytes; - grub_uint64_t act_bytes; - grub_uint64_t dst_address; -} GRUB_PACKED; - -#define MAX_KD_SECTIONS 10 - -struct kernel_dump -{ - grub_uint32_t format; - grub_uint16_t num_sections; - grub_uint16_t status_flags; - grub_uint32_t offset_1st_section; - grub_uint32_t num_blocks; - grub_uint64_t start_block; - grub_uint64_t num_blocks_avail; - grub_uint32_t offet_path_string; - grub_uint32_t max_time_allowed; - struct kd_section kds[MAX_KD_SECTIONS]; /* offset_1st_section should point to kds[0] */ -} GRUB_PACKED; - -/* - * Determine if a kernel dump exists and if it does, then determine the highest - * address that grub can use for memory allocations. - * The caller must have initialized *highest to rmo_top. *highest will not - * be modified if no kernel dump is found. - */ -static void -check_kernel_dump (grub_uint64_t *highest) -{ - struct kernel_dump kernel_dump; - grub_ssize_t kernel_dump_size; - grub_ieee1275_phandle_t rtas; - struct kd_section *kds; - grub_size_t i; - - /* If there's a kernel-dump it must have at least one section */ - if (grub_ieee1275_finddevice ("/rtas", &rtas) || - grub_ieee1275_get_property (rtas, "ibm,kernel-dump", &kernel_dump, - sizeof (kernel_dump), &kernel_dump_size) || - kernel_dump_size <= (grub_ssize_t) offsetof (struct kernel_dump, kds[1])) - return; - - kernel_dump_size = grub_min (kernel_dump_size, (grub_ssize_t) sizeof (kernel_dump)); - - if (grub_be_to_cpu32 (kernel_dump.format) != 1) - { - grub_printf (_("Error: ibm,kernel-dump has an unexpected format version '%u'\n"), - grub_be_to_cpu32 (kernel_dump.format)); - return; - } - - if (grub_be_to_cpu16 (kernel_dump.num_sections) > MAX_KD_SECTIONS) - { - grub_printf (_("Error: Too many kernel dump sections: %d\n"), - grub_be_to_cpu32 (kernel_dump.num_sections)); - return; - } - - for (i = 0; i < grub_be_to_cpu16 (kernel_dump.num_sections); i++) - { - kds = (struct kd_section *) ((grub_addr_t) &kernel_dump + - grub_be_to_cpu32 (kernel_dump.offset_1st_section) + - i * sizeof (struct kd_section)); - /* sanity check the address is within the 'kernel_dump' struct */ - if ((grub_addr_t) kds > (grub_addr_t) &kernel_dump + kernel_dump_size + sizeof (*kds)) - { - grub_printf (_("Error: 'kds' address beyond last available section\n")); - return; - } - - if ((grub_be_to_cpu16 (kds->src_datatype) == KD_SRC_DATATYPE_REAL_MODE_REGION) && - (grub_be_to_cpu64 (kds->src_address) == 0)) - { - *highest = grub_min (*highest, grub_be_to_cpu64 (kds->num_bytes)); - break; - } - } - - return; -} - -/* - * How much memory does OF believe exists in total? - * - * This isn't necessarily the true total. It can be the total memory - * accessible in real mode for a pseries guest, for example. - */ -static grub_uint64_t rmo_top; - -static int -count_free (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - void *data) -{ - if (type != GRUB_MEMORY_AVAILABLE) - return 0; - - /* Do not consider memory beyond 4GB */ - if (addr > 0xffffffffULL) - return 0; - - if (addr + len > 0xffffffffULL) - len = 0xffffffffULL - addr; - - *(grub_uint32_t *) data += len; - - return 0; -} - -int -grub_regions_claim (grub_uint64_t addr, grub_uint64_t len, - grub_memory_type_t type, void *data) -{ - struct regions_claim_request *rcr = data; - grub_uint64_t linux_rmo_save; - - if (type != GRUB_MEMORY_AVAILABLE) - return 0; - - /* Do not consider memory beyond 4GB */ - if (addr > 0xffffffffULL) - return 0; - - if (addr + len > 0xffffffffULL) - len = 0xffffffffULL - addr; - - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM)) - { - if (addr + len <= 0x180000) - return 0; - - if (addr < 0x180000) - { - len = addr + len - 0x180000; - addr = 0x180000; - } - } - - /* 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; - } - - /* - * Linux likes to claim memory at min(RMO top, 768MB) and works down - * without reference to /memory/available. (See prom_init.c::alloc_down) - * - * If this block contains min(RMO top, 768MB), do not claim below that for - * at least a few MB (this is where RTAS, SML and potentially TCEs live). - * - * We also need to leave enough space for the DT in the RMA. (See - * prom_init.c::alloc_up) - * - * Finally, we also want to make sure that when grub loads the kernel, - * it isn't going to use up all the memory we're trying to reserve! So - * enforce our entire RUNTIME_MIN_SPACE here (no fadump): - * - * | Top of memory == upper_mem_limit -| - * | | - * | available | - * | | - * |---------- 768 MB ----------| - * | | - * | reserved | - * | | - * |--- 768 MB - runtime min space ---| - * | | - * | available | - * | | - * |---------- 0 MB ----------| - * - * In case fadump is used, we allow the following: - * - * |---------- Top of memory ----------| - * | | - * | unavailable | - * | (kernel dump area) | - * | | - * |--------- upper_mem_limit ---------| - * | | - * | available | - * | | - * |---------- 768 MB ----------| - * | | - * | reserved | - * | | - * |--- 768 MB - runtime min space ---| - * | | - * | available | - * | | - * |---------- 0 MB ----------| - * - * Edge cases: - * - * - Total memory less than RUNTIME_MIN_SPACE: only claim up to HEAP_MAX_SIZE. - * (enforced elsewhere) - * - * - Total memory between RUNTIME_MIN_SPACE and 768MB: - * - * |---------- Top of memory ----------| - * | | - * | reserved | - * | | - * |---- top - runtime min space ----| - * | | - * | available | - * | | - * |---------- 0 MB ----------| - * - * This by itself would not leave us with RUNTIME_MIN_SPACE of free bytes: if - * rmo_top < 768MB, we will almost certainly have FW claims in the reserved - * region. We try to address that elsewhere: grub_ieee1275_mm_add_region will - * not call us if the resulting free space would be less than RUNTIME_MIN_SPACE. - */ - linux_rmo_save = grub_min (RMO_ADDR_MAX, rmo_top) - RUNTIME_MIN_SPACE; - if (rmo_top > RUNTIME_MIN_SPACE) - { - if (rmo_top <= RMO_ADDR_MAX) - { - if (addr > linux_rmo_save) - { - grub_dprintf ("ieee1275", "rejecting region in RUNTIME_MIN_SPACE reservation (%llx)\n", - addr); - return 0; - } - else if (addr + len > linux_rmo_save) - { - grub_dprintf ("ieee1275", "capping region: (%llx -> %llx) -> (%llx -> %llx)\n", - addr, addr + len, addr, rmo_top - RUNTIME_MIN_SPACE); - len = linux_rmo_save - addr; - } - } - else - { - grub_uint64_t upper_mem_limit = rmo_top; - grub_uint64_t orig_addr = addr; - - check_kernel_dump (&upper_mem_limit); - - grub_dprintf ("ieee1275", "upper_mem_limit is at %llx (%lld MiB)\n", - upper_mem_limit, upper_mem_limit >> 20); - - /* - * we order these cases to prefer higher addresses and avoid some - * splitting issues - * The following shows the order of variables: - * no kernel dump: linux_rmo_save < RMO_ADDR_MAX <= upper_mem_limit == rmo_top - * with kernel dump: liuxx_rmo_save < RMO_ADDR_MAX <= upper_mem_limit <= rmo_top - */ - if (addr < RMO_ADDR_MAX && (addr + len) > RMO_ADDR_MAX && upper_mem_limit >= RMO_ADDR_MAX) - { - grub_dprintf ("ieee1275", - "adjusting region for RUNTIME_MIN_SPACE: (%llx -> %llx) -> (%llx -> %llx)\n", - addr, addr + len, RMO_ADDR_MAX, addr + len); - len = (addr + len) - RMO_ADDR_MAX; - addr = RMO_ADDR_MAX; - - /* We must not exceed the upper_mem_limit (assuming it's >= RMO_ADDR_MAX) */ - if (addr + len > upper_mem_limit) - { - /* Take the bigger chunk from either below linux_rmo_save or above RMO_ADDR_MAX. */ - len = upper_mem_limit - addr; - if (orig_addr < linux_rmo_save && linux_rmo_save - orig_addr > len) - { - /* lower part is bigger */ - addr = orig_addr; - len = linux_rmo_save - addr; - } - - grub_dprintf ("ieee1275", "re-adjusted region to: (%llx -> %llx)\n", - addr, addr + len); - - if (len == 0) - return 0; - } - } - else if ((addr < linux_rmo_save) && ((addr + len) > linux_rmo_save)) - { - grub_dprintf ("ieee1275", "capping region: (%llx -> %llx) -> (%llx -> %llx)\n", - addr, addr + len, addr, linux_rmo_save); - len = linux_rmo_save - addr; - } - else if (addr >= linux_rmo_save && (addr + len) <= RMO_ADDR_MAX) - { - grub_dprintf ("ieee1275", "rejecting region in RUNTIME_MIN_SPACE reservation (%llx)\n", - addr); - return 0; - } - } - } - - /* Honor alignment restrictions on candidate addr */ - if (rcr->align) - { - grub_uint64_t align_addr = ALIGN_UP (addr, rcr->align); - grub_uint64_t d = align_addr - addr; - - if (d > len) - return 0; - - len -= d; - addr = align_addr; - } - - if (rcr->flags & GRUB_MM_ADD_REGION_CONSECUTIVE && len < rcr->total) - return 0; - - if (len > rcr->total) - len = rcr->total; - - if (len) - { - grub_err_t err; - /* Claim and use it. */ - err = grub_claimmap (addr, len); - if (err) - return err; - if (rcr->init_region) - grub_mm_init_region ((void *) (grub_addr_t) addr, len); - rcr->total -= len; - - rcr->addr = addr; - } - - *(grub_uint32_t *) data = rcr->total; - - if (rcr->total == 0) - return 1; - - return 0; -} - -static int -heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - void *data) -{ - struct regions_claim_request rcr = { - .flags = GRUB_MM_ADD_REGION_NONE, - .total = *(grub_uint32_t *) data, - .init_region = true, - }; - int ret; - - ret = grub_regions_claim (addr, len, type, &rcr); - - *(grub_uint32_t *) data = rcr.total; - - return ret; -} - -static int -region_claim (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - void *data) -{ - struct regions_claim_request rcr = { - .flags = GRUB_MM_ADD_REGION_CONSECUTIVE, - .total = *(grub_uint32_t *) data, - .init_region = true, - }; - int ret; - - ret = grub_regions_claim (addr, len, type, &rcr); - - *(grub_uint32_t *) data = rcr.total; - - return ret; -} - -static grub_err_t -grub_ieee1275_mm_add_region (grub_size_t size, unsigned int flags) -{ - grub_uint32_t free_memory = 0; - grub_uint32_t avail = 0; - grub_uint32_t total; - - grub_dprintf ("ieee1275", "mm requested region of size %x, flags %x\n", - size, flags); - - /* - * Update free memory each time, which is a bit inefficient but guards us - * against a situation where some OF driver goes out to firmware for - * memory and we don't realise. - */ - grub_machine_mmap_iterate (count_free, &free_memory); - - /* Ensure we leave enough space to boot. */ - if (free_memory <= RUNTIME_MIN_SPACE + size) - { - grub_dprintf ("ieee1275", "Cannot satisfy allocation and retain minimum runtime space\n"); - return GRUB_ERR_OUT_OF_MEMORY; - } - - if (free_memory > RUNTIME_MIN_SPACE) - avail = free_memory - RUNTIME_MIN_SPACE; - - grub_dprintf ("ieee1275", "free = 0x%x available = 0x%x\n", free_memory, avail); - - if (flags & GRUB_MM_ADD_REGION_CONSECUTIVE) - { - /* first try rounding up hard for the sake of speed */ - total = grub_max (ALIGN_UP (size, 1024 * 1024) + 1024 * 1024, 32 * 1024 * 1024); - total = grub_min (avail, total); - - grub_dprintf ("ieee1275", "looking for %x bytes of memory (%x requested)\n", total, size); - - grub_machine_mmap_iterate (region_claim, &total); - grub_dprintf ("ieee1275", "get memory from fw %s\n", total == 0 ? "succeeded" : "failed"); - - if (total != 0) - { - total = grub_min (avail, size); - - grub_dprintf ("ieee1275", "fallback for %x bytes of memory (%x requested)\n", total, size); - - grub_machine_mmap_iterate (region_claim, &total); - grub_dprintf ("ieee1275", "fallback from fw %s\n", total == 0 ? "succeeded" : "failed"); - } - } - else - { - /* provide padding for a grub_mm_header_t and region */ - total = grub_min (avail, size); - grub_machine_mmap_iterate (heap_init, &total); - grub_dprintf ("ieee1275", "get noncontig memory from fw %s\n", total == 0 ? "succeeded" : "failed"); - } - - if (total == 0) - return GRUB_ERR_NONE; - else - return GRUB_ERR_OUT_OF_MEMORY; -} - -/* - * How much memory does OF believe it has? (regardless of whether - * it's accessible or not) - */ -static grub_err_t -grub_ieee1275_total_mem (grub_uint64_t *total) -{ - grub_ieee1275_phandle_t root; - grub_ieee1275_phandle_t memory; - grub_uint32_t reg[4]; - grub_ssize_t reg_size; - grub_uint32_t address_cells = 1; - grub_uint32_t size_cells = 1; - grub_uint64_t size; - - /* If we fail to get to the end, report 0. */ - *total = 0; - - /* Determine the format of each entry in `reg'. */ - if (grub_ieee1275_finddevice ("/", &root)) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "couldn't find / node"); - if (grub_ieee1275_get_integer_property (root, "#address-cells", &address_cells, - sizeof (address_cells), 0)) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "couldn't examine #address-cells"); - if (grub_ieee1275_get_integer_property (root, "#size-cells", &size_cells, - sizeof (size_cells), 0)) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "couldn't examine #size-cells"); - - if (size_cells > address_cells) - address_cells = size_cells; - - /* Load `/memory/reg'. */ - 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, "reg", reg, - sizeof (reg), ®_size)) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "couldn't examine /memory/reg property"); - if (reg_size < 0 || (grub_size_t) reg_size > sizeof (reg)) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "/memory response buffer exceeded"); - - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS)) - { - address_cells = 1; - size_cells = 1; - } - - /* Decode only the size */ - size = reg[address_cells]; - if (size_cells == 2) - size = (size << 32) | reg[address_cells + 1]; - - *total = size; - - return grub_errno; -} - -#if defined(__powerpc__) - -/* See PAPR or arch/powerpc/kernel/prom_init.c */ -struct option_vector2 -{ - grub_uint8_t byte1; - grub_uint16_t reserved; - grub_uint32_t real_base; - grub_uint32_t real_size; - grub_uint32_t virt_base; - grub_uint32_t virt_size; - grub_uint32_t load_base; - grub_uint32_t min_rma; - grub_uint32_t min_load; - grub_uint8_t min_rma_percent; - grub_uint8_t max_pft_size; -} GRUB_PACKED; - -struct option_vector5 -{ - grub_uint8_t byte1; - grub_uint8_t byte2; - grub_uint8_t byte3; - grub_uint8_t cmo; - grub_uint8_t associativity; - grub_uint8_t bin_opts; - grub_uint8_t micro_checkpoint; - grub_uint8_t reserved0; - grub_uint32_t max_cpus; - grub_uint16_t base_papr; - grub_uint16_t mem_reference; - grub_uint32_t platform_facilities; - grub_uint8_t sub_processors; - grub_uint8_t byte22; - grub_uint8_t xive; - grub_uint8_t mmu; - grub_uint8_t hpt_ext; - grub_uint8_t radix_gtse; -} GRUB_PACKED; - -struct pvr_entry -{ - grub_uint32_t mask; - grub_uint32_t entry; -}; - -struct cas_vector -{ - struct - { - struct pvr_entry terminal; - } pvr_list; - grub_uint8_t num_vecs; - grub_uint8_t vec1_size; - grub_uint8_t vec1; - grub_uint8_t vec2_size; - struct option_vector2 vec2; - grub_uint8_t vec3_size; - grub_uint16_t vec3; - grub_uint8_t vec4_size; - grub_uint16_t vec4; - grub_uint8_t vec5_size; - struct option_vector5 vec5; -} GRUB_PACKED; - -/* - * Call ibm,client-architecture-support to try to get more RMA. - * We ask for 768MB which should be enough to verify a distro kernel. - * We ignore most errors: if we don't succeed we'll proceed with whatever - * memory we have. - */ -static void -grub_ieee1275_ibm_cas (void) -{ - int rc; - grub_ieee1275_ihandle_t root; - grub_uint8_t ibm_arch_platform_support[8]; - grub_ssize_t actual; - grub_uint8_t xive_support = 0; - grub_uint8_t mmu_support = 0; - grub_uint8_t radix_gtse_support = 0; - int i = 0; - int prop_len = 8; - struct cas_args - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t method; - grub_ieee1275_ihandle_t ihandle; - grub_ieee1275_cell_t cas_addr; - grub_ieee1275_cell_t result; - } args; - - grub_ieee1275_get_integer_property (grub_ieee1275_chosen, - "ibm,arch-vec-5-platform-support", - (grub_uint32_t *) ibm_arch_platform_support, - sizeof (ibm_arch_platform_support), - &actual); - - for (i = 0; i < prop_len; i++) - { - switch (ibm_arch_platform_support[i]) - { - case XIVE_INDEX: - if (ibm_arch_platform_support[i + 1] & MAX_SUPPORTED) - xive_support = XIVE_ENABLED; - else - xive_support = 0; - break; - - case MMU_INDEX: - if (ibm_arch_platform_support[i + 1] & MAX_SUPPORTED) - mmu_support = RADIX_ENABLED; - else - mmu_support = HASH_ENABLED; - break; - - case RADIX_GTSE_INDEX: - if (mmu_support == RADIX_ENABLED) - radix_gtse_support = ibm_arch_platform_support[i + 1] & RADIX_GTSE_ENABLED; - else - radix_gtse_support = 0; - break; - - default: - /* Ignoring the other indexes of ibm,arch-vec-5-platform-support. */ - break; - } - /* Skipping the property value. */ - i++; - } - - struct cas_vector vector = - { - .pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */ - .num_vecs = 5 - 1, - .vec1_size = 0, - .vec1 = 0x80, /* ignore */ - .vec2_size = 1 + sizeof (struct option_vector2) - 2, - .vec2 = { - 0, 0, -1, -1, -1, -1, -1, 768, -1, 0, 48 - }, - .vec3_size = 2 - 1, - .vec3 = 0x00e0, /* ask for FP + VMX + DFP but don't halt if unsatisfied */ - .vec4_size = 2 - 1, - .vec4 = 0x0001, /* set required minimum capacity % to the lowest value */ - .vec5_size = 1 + sizeof (struct option_vector5) - 2, - .vec5 = { - 0, BYTE2, 0, CMO, ASSOCIATIVITY, BIN_OPTS, 0, 0, MAX_CPU, 0, 0, PLATFORM_FACILITIES, SUB_PROCESSORS, BYTE22, xive_support, mmu_support, 0, radix_gtse_support - } - }; - - INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2); - args.method = (grub_ieee1275_cell_t) "ibm,client-architecture-support"; - rc = grub_ieee1275_open ("/", &root); - if (rc) - { - grub_error (GRUB_ERR_IO, "could not open root when trying to call CAS"); - return; - } - args.ihandle = root; - args.cas_addr = (grub_ieee1275_cell_t) &vector; - - grub_printf ("Calling ibm,client-architecture-support from grub..."); - IEEE1275_CALL_ENTRY_FN (&args); - grub_printf ("done\n"); - - grub_ieee1275_close (root); -} - -#endif /* __powerpc__ */ - -static void -grub_claim_heap (void) -{ - grub_err_t err; - grub_uint32_t total = HEAP_MAX_SIZE; -#if defined(__powerpc__) - grub_uint32_t ibm_ca_support_reboot = 0; - grub_ssize_t actual; -#endif - - err = grub_ieee1275_total_mem (&rmo_top); - - /* - * If we cannot size the available memory, we can't be sure we're leaving - * space for the kernel, initrd and things Linux loads early in boot. So only - * allow further allocations from firmware on success - */ - if (err == GRUB_ERR_NONE) - grub_mm_add_region_fn = grub_ieee1275_mm_add_region; - -#if defined(__powerpc__) - /* Check if it's a CAS reboot with below property. If so, we will skip CAS call. */ - if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, - "ibm,client-architecture-support-reboot", - &ibm_ca_support_reboot, - sizeof (ibm_ca_support_reboot), - &actual) >= 0) - grub_dprintf ("ieee1275", "ibm,client-architecture-support-reboot: %" PRIuGRUB_UINT32_T "\n", - ibm_ca_support_reboot); - - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY)) - { - /* - * If we have an error don't call CAS. Just hope for the best. - * Along with the above, if the rmo_top is 512 MB or above. We - * will skip the CAS call. However, if we call CAS, the rmo_top - * will be set to 768 MB via CAS Vector2. But we need to call - * CAS with rmo_top < 512 MB to avoid the issue on the older - * Linux kernel, which still uses rmo_top as 512 MB. If we call - * CAS with a condition rmo_top < 768 MB, it will result in an - * issue due to the IBM CAS reboot feature and we won't be able - * to boot the newer kernel. Whenever a reboot is detected as - * the CAS reboot by GRUB it will boot the machine with the - * last booted kernel by reading the variable boot-last-label - * which has the info related to the last boot and it's specific - * to IBM PowerPC. Due to this, the machine will boot with the - * last booted kernel which has rmo_top as 512 MB. Also, if the - * reboot is detected as a CAS reboot, the GRUB will skip the CAS - * call. As the CAS has already been called earlier, so it is - * not required to call CAS even if the other conditions are met. - * This condition will also prevent a scenario where the machine - * get stuck in the CAS reboot loop while booting a machine with - * an older kernel, having option_vector2 MIN_RMA as 512 MB in - * Linux prom_init.c and GRUB uses rmo_top < 768 MB condition - * for calling CAS. Due to their respective conditions, Linux - * CAS and GRUB CAS will keep doing the CAS calls and change - * the MIN_RMA from 768, changed by GRUB, to 512, changed by Linux, - * to 768, changed by GRUB, to 512, changed by Linux, and so on. - * The machine will stuck in this CAS reboot loop forever. - * - * IBM PAPR: https://openpower.foundation/specifications/linuxonpower/ - */ - if (!ibm_ca_support_reboot && err == GRUB_ERR_NONE && rmo_top < (512 * 1024 * 1024)) - grub_ieee1275_ibm_cas (); - } -#endif - - grub_machine_mmap_iterate (heap_init, &total); -} -#endif - -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); - } - } - } -} - -grub_addr_t grub_modbase; - -void -grub_machine_init (void) -{ - grub_modbase = ALIGN_UP((grub_addr_t) _end - + GRUB_KERNEL_MACHINE_MOD_GAP, - GRUB_KERNEL_MACHINE_MOD_ALIGN); - grub_ieee1275_init (); - - grub_console_init_early (); - grub_claim_heap (); - grub_console_init_lately (); -#ifdef __sparc__ - grub_obdisk_init (); -#else - grub_ofdisk_init (); -#endif - grub_parse_cmdline (); - -#ifdef __i386__ - grub_tsc_init (); -#else - grub_install_get_time_ms (grub_rtc_get_time_ms); -#endif -} - -void -grub_machine_fini (int flags) -{ - if (flags & GRUB_LOADER_FLAG_NORETURN) - { -#ifdef __sparc__ - grub_obdisk_fini (); -#else - grub_ofdisk_fini (); -#endif - grub_console_fini (); - } -} - -grub_uint64_t -grub_rtc_get_time_ms (void) -{ - grub_uint32_t msecs = 0; - - grub_ieee1275_milliseconds (&msecs); - - return msecs; -} diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c deleted file mode 100644 index 11b2beb2f..000000000 --- a/grub-core/kern/ieee1275/openfw.c +++ /dev/null @@ -1,593 +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 . - */ - -#include -#include -#include -#include -#include -#include - -enum grub_ieee1275_parse_type -{ - GRUB_PARSE_FILENAME, - GRUB_PARSE_PARTITION, - GRUB_PARSE_DEVICE, - GRUB_PARSE_DEVICE_TYPE -}; - -static int -fill_alias (struct grub_ieee1275_devalias *alias) -{ - grub_ssize_t actual; - - if (grub_ieee1275_get_property (alias->phandle, "device_type", alias->type, - IEEE1275_MAX_PROP_LEN, &actual)) - alias->type[0] = 0; - - if (alias->parent_dev == alias->phandle) - return 0; - - if (grub_ieee1275_package_to_path (alias->phandle, alias->path, - IEEE1275_MAX_PATH_LEN, &actual)) - return 0; - - if (grub_strcmp (alias->parent_path, alias->path) == 0) - return 0; - - if (grub_ieee1275_get_property (alias->phandle, "name", alias->name, - IEEE1275_MAX_PROP_LEN, &actual)) - return 0; - grub_dprintf ("devalias", "device path=%s\n", alias->path); - return 1; -} - -void -grub_ieee1275_devalias_free (struct grub_ieee1275_devalias *alias) -{ - grub_free (alias->name); - grub_free (alias->type); - grub_free (alias->path); - grub_free (alias->parent_path); - alias->name = 0; - alias->type = 0; - alias->path = 0; - alias->parent_path = 0; - alias->phandle = GRUB_IEEE1275_PHANDLE_INVALID; -} - -void -grub_ieee1275_children_peer (struct grub_ieee1275_devalias *alias) -{ - while (grub_ieee1275_peer (alias->phandle, &alias->phandle) != -1) - if (fill_alias (alias)) - return; - grub_ieee1275_devalias_free (alias); -} - -void -grub_ieee1275_children_first (const char *devpath, - struct grub_ieee1275_devalias *alias) -{ - grub_ieee1275_phandle_t dev; - - grub_dprintf ("devalias", "iterating children of %s\n", - devpath); - - alias->name = 0; - alias->path = 0; - alias->parent_path = 0; - alias->type = 0; - - if (grub_ieee1275_finddevice (devpath, &dev)) - return; - - if (grub_ieee1275_child (dev, &alias->phandle)) - return; - - alias->type = grub_malloc (IEEE1275_MAX_PROP_LEN); - if (!alias->type) - return; - alias->path = grub_malloc (IEEE1275_MAX_PATH_LEN); - if (!alias->path) - { - grub_free (alias->type); - return; - } - alias->parent_path = grub_strdup (devpath); - if (!alias->parent_path) - { - grub_free (alias->path); - grub_free (alias->type); - return; - } - - alias->name = grub_malloc (IEEE1275_MAX_PROP_LEN); - if (!alias->name) - { - grub_free (alias->path); - grub_free (alias->type); - grub_free (alias->parent_path); - return; - } - if (!fill_alias (alias)) - grub_ieee1275_children_peer (alias); -} - -static int -iterate_recursively (const char *path, - int (*hook) (struct grub_ieee1275_devalias *alias)) -{ - struct grub_ieee1275_devalias alias; - int ret = 0; - - FOR_IEEE1275_DEVCHILDREN(path, alias) - { - ret = hook (&alias); - if (ret) - break; - ret = iterate_recursively (alias.path, hook); - if (ret) - break; - } - grub_ieee1275_devalias_free (&alias); - return ret; -} - -int -grub_ieee1275_devices_iterate (int (*hook) (struct grub_ieee1275_devalias *alias)) -{ - return iterate_recursively ("/", hook); -} - -void -grub_ieee1275_devalias_init_iterator (struct grub_ieee1275_devalias *alias) -{ - alias->name = 0; - alias->path = 0; - alias->parent_path = 0; - alias->type = 0; - - grub_dprintf ("devalias", "iterating aliases\n"); - - if (grub_ieee1275_finddevice ("/aliases", &alias->parent_dev)) - return; - - alias->name = grub_malloc (IEEE1275_MAX_PROP_LEN); - if (!alias->name) - return; - - alias->type = grub_malloc (IEEE1275_MAX_PROP_LEN); - if (!alias->type) - { - grub_free (alias->name); - alias->name = 0; - return; - } - - alias->name[0] = '\0'; -} - -int -grub_ieee1275_devalias_next (struct grub_ieee1275_devalias *alias) -{ - if (!alias->name) - return 0; - while (1) - { - grub_ssize_t pathlen; - grub_ssize_t actual; - char *tmp; - - if (alias->path) - { - grub_free (alias->path); - alias->path = 0; - } - tmp = grub_strdup (alias->name); - if (grub_ieee1275_next_property (alias->parent_dev, tmp, - alias->name) <= 0) - { - grub_free (tmp); - grub_ieee1275_devalias_free (alias); - return 0; - } - grub_free (tmp); - - grub_dprintf ("devalias", "devalias name = %s\n", alias->name); - - grub_ieee1275_get_property_length (alias->parent_dev, alias->name, &pathlen); - - /* The property `name' is a special case we should skip. */ - if (grub_strcmp (alias->name, "name") == 0) - 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; - - alias->path = grub_malloc (pathlen + 1); - if (! alias->path) - { - grub_ieee1275_devalias_free (alias); - return 0; - } - - if (grub_ieee1275_get_property (alias->parent_dev, alias->name, alias->path, - pathlen, &actual) || actual < 0) - { - grub_dprintf ("devalias", "get_property (%s) failed\n", alias->name); - grub_free (alias->path); - continue; - } - if (actual > pathlen) - actual = pathlen; - alias->path[actual] = '\0'; - alias->path[pathlen] = '\0'; - - if (grub_ieee1275_finddevice (alias->path, &alias->phandle)) - { - grub_dprintf ("devalias", "finddevice (%s) failed\n", alias->path); - grub_free (alias->path); - alias->path = 0; - continue; - } - - if (grub_ieee1275_get_property (alias->phandle, "device_type", alias->type, - IEEE1275_MAX_PROP_LEN, &actual)) - { - /* NAND device don't have device_type property. */ - alias->type[0] = 0; - } - return 1; - } -} - -/* 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 __sparc__ - 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 __sparc__ - 7, -#else - 6, -#endif - 1); - args.method = (grub_ieee1275_cell_t) "map"; - args.ihandle = grub_ieee1275_mmu; -#ifdef __sparc__ - 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; -} - -grub_err_t -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_error (GRUB_ERR_OUT_OF_MEMORY, "map failed: address 0x%llx, size 0x%llx\n", - (long long) addr, (long long) size); - grub_ieee1275_release (addr, size); - return grub_errno; - } - - return GRUB_ERR_NONE; -} - -/* 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'. */ -char * -grub_ieee1275_get_devname (const char *path) -{ - char *colon = grub_strchr (path, ':'); - int pathlen = grub_strlen (path); - struct grub_ieee1275_devalias curalias; - if (colon) - pathlen = (int)(colon - path); - - /* Try to find an alias for this device. */ - FOR_IEEE1275_DEVALIASES (curalias) - /* briQ firmware can change capitalization in /chosen/bootpath. */ - if (grub_strncasecmp (curalias.path, path, pathlen) == 0 - && curalias.path[pathlen] == 0) - { - char *newpath; - newpath = grub_strdup (curalias.name); - grub_ieee1275_devalias_free (&curalias); - return newpath; - } - - return grub_strndup (path, pathlen); -} - -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 *ret = 0; - grub_ieee1275_phandle_t dev; - - /* 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; - } - - switch (ptype) - { - case GRUB_PARSE_DEVICE: - ret = grub_strdup (device); - break; - case GRUB_PARSE_DEVICE_TYPE: - ret = grub_strdup (type); - break; - case GRUB_PARSE_FILENAME: - { - char *comma; - char *args; - - args = grub_ieee1275_get_devargs (path); - if (!args) - /* Shouldn't happen. */ - return 0; - - /* The syntax of the device arguments is defined in the CHRP and PReP - IEEE1275 bindings: "[partition][,[filename]]". */ - comma = grub_strchr (args, ','); - - 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); - } - grub_free (args); - } - break; - case GRUB_PARSE_PARTITION: - { - char *comma; - char *args; - - if (grub_strcmp ("block", type) != 0) - goto unknown; - - args = grub_ieee1275_get_devargs (path); - if (!args) - /* Shouldn't happen. */ - return 0; - - comma = grub_strchr (args, ','); - if (!comma) - ret = grub_strdup (args); - else - ret = grub_strndup (args, (grub_size_t)(comma - args)); - /* Consistently provide numbered partitions to GRUB. - OpenBOOT traditionally uses alphabetical partition - specifiers. */ - if (ret[0] >= 'a' && ret[0] <= 'z') - ret[0] = '1' + (ret[0] - 'a'); - grub_free (args); - } - break; - default: - unknown: - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported type %s for device %s", type, device); - } - -fail: - grub_free (device); - return ret; -} - -char * -grub_ieee1275_get_device_type (const char *path) -{ - return grub_ieee1275_parse_args (path, GRUB_PARSE_DEVICE_TYPE); -} - -char * -grub_ieee1275_get_aliasdevname (const char *path) -{ - return grub_ieee1275_parse_args (path, GRUB_PARSE_DEVICE); -} - -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; - char *encoding; - char *optr; - const char *iptr; - - if (! device) - return 0; - - encoding = grub_malloc (sizeof ("ieee1275/") + 2 * grub_strlen (device) - + sizeof (",XXXXXXXXXXXX")); - if (!encoding) - { - grub_free (device); - return 0; - } - - partition = grub_ieee1275_parse_args (path, GRUB_PARSE_PARTITION); - - optr = grub_stpcpy (encoding, "ieee1275/"); - for (iptr = device; *iptr; ) - { - if (*iptr == ',') - *optr++ ='\\'; - *optr++ = *iptr++; - } - if (partition && partition[0]) - { - unsigned int partno = grub_strtoul (partition, 0, 0); - - *optr++ = ','; - - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS)) - /* GRUB partition 1 is OF partition 0. */ - partno++; - - grub_snprintf (optr, sizeof ("XXXXXXXXXXXX"), "%d", partno); - } - else - *optr = '\0'; - - grub_free (partition); - grub_free (device); - - return encoding; -} - -/* Resolve aliases. */ -char * -grub_ieee1275_canonicalise_devname (const char *path) -{ - struct canon_args - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t path; - grub_ieee1275_cell_t buf; - grub_ieee1275_cell_t inlen; - grub_ieee1275_cell_t outlen; - } - args; - char *buf = NULL; - grub_size_t bufsize = 64; - int i; - - for (i = 0; i < 2; i++) - { - grub_free (buf); - - buf = grub_malloc (bufsize); - if (!buf) - return NULL; - - INIT_IEEE1275_COMMON (&args.common, "canon", 3, 1); - args.path = (grub_ieee1275_cell_t) path; - args.buf = (grub_ieee1275_cell_t) buf; - args.inlen = (grub_ieee1275_cell_t) (bufsize - 1); - - if (IEEE1275_CALL_ENTRY_FN (&args) == -1) - return 0; - if (args.outlen > bufsize - 1) - { - bufsize = args.outlen + 2; - continue; - } - return buf; - } - /* Shouldn't reach here. */ - grub_free (buf); - return NULL; -} - -char * -grub_ieee1275_get_boot_dev (void) -{ - char *bootpath; - grub_ssize_t bootpath_size; - - if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath", - &bootpath_size) - || bootpath_size <= 0) - { - /* Should never happen. */ - grub_printf ("/chosen/bootpath property missing!\n"); - return NULL; - } - - bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64); - if (! bootpath) - { - grub_print_error (); - return NULL; - } - grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath, - (grub_size_t) bootpath_size + 1, 0); - bootpath[bootpath_size] = '\0'; - - return bootpath; -} diff --git a/grub-core/kern/list.c b/grub-core/kern/list.c deleted file mode 100644 index a256bb3f8..000000000 --- a/grub-core/kern/list.c +++ /dev/null @@ -1,55 +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 . - */ - -#include -#include -#include - -void * -grub_named_list_find (grub_named_list_t head, const char *name) -{ - grub_named_list_t item; - - FOR_LIST_ELEMENTS (item, head) - if (grub_strcmp (item->name, name) == 0) - return item; - - return NULL; -} - -void -grub_list_push (grub_list_t *head, grub_list_t item) -{ - item->prev = head; - if (*head) - (*head)->prev = &item->next; - item->next = *head; - *head = item; -} - -void -grub_list_remove (grub_list_t item) -{ - if (item->prev) - *item->prev = item->next; - if (item->next) - item->next->prev = item->prev; - item->next = 0; - item->prev = 0; -} diff --git a/grub-core/kern/lockdown.c b/grub-core/kern/lockdown.c deleted file mode 100644 index af6d493cd..000000000 --- a/grub-core/kern/lockdown.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2020 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - * - */ - -#include -#include -#include -#include -#include - -static int lockdown = GRUB_LOCKDOWN_DISABLED; - -static grub_err_t -lockdown_verifier_init (grub_file_t io __attribute__ ((unused)), - enum grub_file_type type, - void **context __attribute__ ((unused)), - enum grub_verify_flags *flags) -{ - *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; - - switch (type & GRUB_FILE_TYPE_MASK) - { - case GRUB_FILE_TYPE_GRUB_MODULE: - case GRUB_FILE_TYPE_LINUX_KERNEL: - case GRUB_FILE_TYPE_MULTIBOOT_KERNEL: - case GRUB_FILE_TYPE_XEN_HYPERVISOR: - case GRUB_FILE_TYPE_BSD_KERNEL: - case GRUB_FILE_TYPE_XNU_KERNEL: - case GRUB_FILE_TYPE_PLAN9_KERNEL: - case GRUB_FILE_TYPE_NTLDR: - case GRUB_FILE_TYPE_TRUECRYPT: - case GRUB_FILE_TYPE_FREEDOS: - case GRUB_FILE_TYPE_PXECHAINLOADER: - case GRUB_FILE_TYPE_PCCHAINLOADER: - case GRUB_FILE_TYPE_COREBOOT_CHAINLOADER: - case GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE: - case GRUB_FILE_TYPE_ACPI_TABLE: - case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE: - case GRUB_FILE_TYPE_FONT: - *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH; - - /* Fall through. */ - - default: - return GRUB_ERR_NONE; - } -} - -struct grub_file_verifier lockdown_verifier = - { - .name = "lockdown_verifier", - .init = lockdown_verifier_init, - }; - -void -grub_lockdown (void) -{ - lockdown = GRUB_LOCKDOWN_ENABLED; - - grub_verifier_register (&lockdown_verifier); - - grub_env_set ("lockdown", "y"); - grub_env_export ("lockdown"); -} - -int -grub_is_lockdown (void) -{ - return lockdown; -} diff --git a/grub-core/kern/loongarch64/cache.c b/grub-core/kern/loongarch64/cache.c deleted file mode 100644 index ff834dca4..000000000 --- a/grub-core/kern/loongarch64/cache.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -/* Prototypes for asm functions. */ -void grub_arch_clean_dcache_range (void); -void grub_arch_invalidate_icache_range (void); - -void -grub_arch_sync_caches (void *address __attribute__((unused)), - grub_size_t len __attribute__((unused))) -{ - grub_arch_clean_dcache_range (); - grub_arch_invalidate_icache_range (); -} - -void -grub_arch_sync_dma_caches (volatile void *address __attribute__((unused)), - grub_size_t len __attribute__((unused))) -{ - /* DMA non-coherent devices not supported yet */ -} diff --git a/grub-core/kern/loongarch64/dl.c b/grub-core/kern/loongarch64/dl.c deleted file mode 100644 index 7f923b415..000000000 --- a/grub-core/kern/loongarch64/dl.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* 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] != ELFDATA2LSB || e->e_machine != EM_LOONGARCH) - return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); - - return GRUB_ERR_NONE; -} - -#pragma GCC diagnostic ignored "-Wcast-align" - -/* - * Unified function for both REL and RELA. - */ -grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - Elf_Shdr *s, grub_dl_segment_t seg) -{ - Elf_Rel *rel, *max; - struct grub_loongarch64_stack stack; - grub_loongarch64_stack_init (&stack); - - for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset), - max = (Elf_Rel *) ((char *) rel + s->sh_size); - rel < max; - rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) - { - Elf_Sym *sym; - void *place; - grub_uint64_t sym_addr; - - if (rel->r_offset >= seg->size) - return grub_error (GRUB_ERR_BAD_MODULE, - "reloc offset is outside the segment"); - - sym = (Elf_Sym *) ((char*) mod->symtab - + mod->symsize * ELF_R_SYM (rel->r_info)); - - sym_addr = sym->st_value; - if (s->sh_type == SHT_RELA) - sym_addr += ((Elf_Rela *) rel)->r_addend; - - place = (void *) ((grub_addr_t) seg->addr + rel->r_offset); - - switch (ELF_R_TYPE (rel->r_info)) - { - case R_LARCH_64: - { - grub_uint64_t *abs_place = place; - - grub_dprintf ("dl", "reloc_abs64 %p => 0x%016llx, %p\n", - place, (unsigned long long) sym_addr, abs_place); - - *abs_place += (grub_uint64_t) sym_addr; - } - break; - case R_LARCH_MARK_LA: - break; - case R_LARCH_SOP_PUSH_PCREL: - case R_LARCH_SOP_PUSH_PLT_PCREL: - grub_loongarch64_sop_push (&stack, sym_addr - (grub_uint64_t)place); - break; - case R_LARCH_B26: - { - grub_uint32_t *abs_place = place; - grub_ssize_t off = sym_addr - (grub_addr_t) place; - - grub_loongarch64_b26 (abs_place, off); - } - break; - case R_LARCH_ABS_HI20: - { - grub_uint32_t *abs_place = place; - grub_loongarch64_xxx_hi20 (abs_place, sym_addr); - } - break; - case R_LARCH_ABS64_LO20: - { - grub_uint32_t *abs_place = place; - grub_loongarch64_abs64_lo20 (abs_place, sym_addr); - } - break; - case R_LARCH_ABS64_HI12: - { - grub_uint32_t *abs_place = place; - grub_loongarch64_abs64_hi12 (abs_place, sym_addr); - } - break; - case R_LARCH_PCALA_HI20: - { - grub_uint32_t *abs_place = place; - grub_int32_t off = (((sym_addr + 0x800) & ~0xfffULL) - ((grub_addr_t)place & ~0xfffULL)); - - grub_loongarch64_xxx_hi20 (abs_place, off); - } - break; - case R_LARCH_ABS_LO12: - case R_LARCH_PCALA_LO12: - { - grub_uint32_t *abs_place = place; - grub_loongarch64_xxx_lo12 (abs_place, sym_addr); - } - break; - GRUB_LOONGARCH64_RELOCATION (&stack, place, sym_addr) - default: - { - char rel_info[17]; /* log16(2^64) = 16, plus NUL. */ - - grub_snprintf (rel_info, sizeof (rel_info) - 1, "%" PRIxGRUB_UINT64_T, - (grub_uint64_t) ELF_R_TYPE (rel->r_info)); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%s is not implemented yet"), rel_info); - } - break; - } - } - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/loongarch64/dl_helper.c b/grub-core/kern/loongarch64/dl_helper.c deleted file mode 100644 index 006e8500e..000000000 --- a/grub-core/kern/loongarch64/dl_helper.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -/* - * LoongArch relocations documentation: - * https://github.com/loongson/la-abi-specs/blob/release/laelf.adoc#relocations - */ -static void grub_loongarch64_stack_push (grub_loongarch64_stack_t stack, grub_uint64_t x); -static grub_uint64_t grub_loongarch64_stack_pop (grub_loongarch64_stack_t stack); - -void -grub_loongarch64_stack_init (grub_loongarch64_stack_t stack) -{ - stack->top = -1; - stack->count = LOONGARCH64_STACK_MAX; -} - -static void -grub_loongarch64_stack_push (grub_loongarch64_stack_t stack, grub_uint64_t x) -{ - if (stack->top == stack->count) - return; - stack->data[++stack->top] = x; -} - -static grub_uint64_t -grub_loongarch64_stack_pop (grub_loongarch64_stack_t stack) -{ - if (stack->top == -1) - return 0; - return stack->data[stack->top--]; -} - -void -grub_loongarch64_sop_push (grub_loongarch64_stack_t stack, grub_int64_t offset) -{ - grub_loongarch64_stack_push (stack, offset); -} - -/* opr2 = pop (), opr1 = pop (), push (opr1 - opr2) */ -void -grub_loongarch64_sop_sub (grub_loongarch64_stack_t stack) -{ - grub_uint64_t a, b; - b = grub_loongarch64_stack_pop (stack); - a = grub_loongarch64_stack_pop (stack); - grub_loongarch64_stack_push (stack, a - b); -} - -/* opr2 = pop (), opr1 = pop (), push (opr1 << opr2) */ -void -grub_loongarch64_sop_sl (grub_loongarch64_stack_t stack) -{ - grub_uint64_t a, b; - b = grub_loongarch64_stack_pop (stack); - a = grub_loongarch64_stack_pop (stack); - grub_loongarch64_stack_push (stack, a << b); -} - -/* opr2 = pop (), opr1 = pop (), push (opr1 >> opr2) */ -void -grub_loongarch64_sop_sr (grub_loongarch64_stack_t stack) -{ - grub_uint64_t a, b; - b = grub_loongarch64_stack_pop (stack); - a = grub_loongarch64_stack_pop (stack); - grub_loongarch64_stack_push (stack, a >> b); -} - -/* opr2 = pop (), opr1 = pop (), push (opr1 + opr2) */ -void -grub_loongarch64_sop_add (grub_loongarch64_stack_t stack) -{ - grub_uint64_t a, b; - b = grub_loongarch64_stack_pop (stack); - a = grub_loongarch64_stack_pop (stack); - grub_loongarch64_stack_push (stack, a + b); -} - -/* opr2 = pop (), opr1 = pop (), push (opr1 & opr2) */ -void -grub_loongarch64_sop_and (grub_loongarch64_stack_t stack) -{ - grub_uint64_t a, b; - b = grub_loongarch64_stack_pop (stack); - a = grub_loongarch64_stack_pop (stack); - grub_loongarch64_stack_push (stack, a & b); -} - -/* opr3 = pop (), opr2 = pop (), opr1 = pop (), push (opr1 ? opr2 : opr3) */ -void -grub_loongarch64_sop_if_else (grub_loongarch64_stack_t stack) -{ - grub_uint64_t a, b, c; - c = grub_loongarch64_stack_pop (stack); - b = grub_loongarch64_stack_pop (stack); - a = grub_loongarch64_stack_pop (stack); - - if (a) { - grub_loongarch64_stack_push (stack, b); - } else { - grub_loongarch64_stack_push (stack, c); - } -} - -/* opr1 = pop (), (*(uint32_t *) PC) [14 ... 10] = opr1 [4 ... 0] */ -void -grub_loongarch64_sop_32_s_10_5 (grub_loongarch64_stack_t stack, - grub_uint64_t *place) -{ - grub_uint64_t a = grub_loongarch64_stack_pop (stack); - *place |= ((a & 0x1f) << 10); -} - -/* opr1 = pop (), (*(uint32_t *) PC) [21 ... 10] = opr1 [11 ... 0] */ -void -grub_loongarch64_sop_32_u_10_12 (grub_loongarch64_stack_t stack, - grub_uint64_t *place) -{ - grub_uint64_t a = grub_loongarch64_stack_pop (stack); - *place = *place | ((a & 0xfff) << 10); -} - -/* opr1 = pop (), (*(uint32_t *) PC) [21 ... 10] = opr1 [11 ... 0] */ -void -grub_loongarch64_sop_32_s_10_12 (grub_loongarch64_stack_t stack, - grub_uint64_t *place) -{ - grub_uint64_t a = grub_loongarch64_stack_pop (stack); - *place = (*place) | ((a & 0xfff) << 10); -} - -/* opr1 = pop (), (*(uint32_t *) PC) [25 ... 10] = opr1 [15 ... 0] */ -void -grub_loongarch64_sop_32_s_10_16 (grub_loongarch64_stack_t stack, - grub_uint64_t *place) -{ - grub_uint64_t a = grub_loongarch64_stack_pop (stack); - *place = (*place) | ((a & 0xffff) << 10); -} - -/* opr1 = pop (), (*(uint32_t *) PC) [25 ... 10] = opr1 [17 ... 2] */ -void -grub_loongarch64_sop_32_s_10_16_s2 (grub_loongarch64_stack_t stack, - grub_uint64_t *place) -{ - grub_uint64_t a = grub_loongarch64_stack_pop (stack); - *place = (*place) | (((a >> 2) & 0xffff) << 10); -} - -/* opr1 = pop (), (*(uint32_t *) PC) [24 ... 5] = opr1 [19 ... 0] */ -void -grub_loongarch64_sop_32_s_5_20 (grub_loongarch64_stack_t stack, grub_uint64_t *place) -{ - grub_uint64_t a = grub_loongarch64_stack_pop (stack); - *place = (*place) | ((a & 0xfffff)<<5); -} - -/* opr1 = pop (), (*(uint32_t *) PC) [4 ... 0] = opr1 [22 ... 18] */ -void -grub_loongarch64_sop_32_s_0_5_10_16_s2 (grub_loongarch64_stack_t stack, - grub_uint64_t *place) -{ - grub_uint64_t a = grub_loongarch64_stack_pop (stack); - - *place =(*place) | (((a >> 2) & 0xffff) << 10); - *place =(*place) | ((a >> 18) & 0x1f); -} - -/* - * opr1 = pop () - * (*(uint32_t *) PC) [9 ... 0] = opr1 [27 ... 18], - * (*(uint32_t *) PC) [25 ... 10] = opr1 [17 ... 2] - */ -void -grub_loongarch64_sop_32_s_0_10_10_16_s2 (grub_loongarch64_stack_t stack, - grub_uint64_t *place) -{ - grub_uint64_t a = grub_loongarch64_stack_pop (stack); - *place =(*place) | (((a >> 2) & 0xffff) << 10); - *place =(*place) | ((a >> 18) & 0x3ff); -} - -/* - * B26 relocation for the 28-bit PC-relative jump - * (*(uint32_t *) PC) [9 ... 0] = (S + A - PC) [27 ... 18] - * (*(uint32_t *) PC) [25 ... 10] = (S + A - PC) [17 ... 2] - */ -void grub_loongarch64_b26 (grub_uint32_t *place, grub_int64_t offset) -{ - grub_uint32_t val; - const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfc000000); - - grub_dprintf ("dl", " reloc_b26 %p %c= 0x%" PRIxGRUB_INT64_T "\n", - place, offset > 0 ? '+' : '-', - offset < 0 ? -offset : offset); - - val = ((offset >> 18) & 0x3ff) | (((offset >> 2) & 0xffff) << 10); - - *place &= insmask; - *place |= grub_cpu_to_le32 (val) & ~insmask; -} - -/* - * ABS_HI20/PCALA_HI20 relocations for 32/64-bit absolute address/PC-relative offset - * (*(uint32_t *) PC) [24 ... 5] = (S + A) [31 ... 12] - */ -void grub_loongarch64_xxx_hi20 (grub_uint32_t *place, grub_int64_t offset) -{ - const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfe00001f); - grub_uint32_t val; - - offset >>= 12; - val = ((offset & 0xfffff) << 5); - - *place &= insmask; - *place |= grub_cpu_to_le32 (val) & ~insmask; -} - -/* - * ABS_LO12/PCALA_LO12 relocations for 32/64-bit absolute address - * (*(uint32_t *) PC) [21 ... 10] = (S + A) [11 ... 0] - */ -void grub_loongarch64_xxx_lo12 (grub_uint32_t *place, grub_int64_t offset) -{ - const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xffc003ff); - - *place &= insmask; - *place |= grub_cpu_to_le32 (offset << 10) & ~insmask; -} - -/* - * ABS64_HI12 relocation for the 64-bit absolute address - * (*(uint32_t *) PC) [21 ... 10] = (S + A) [63 ... 52] - */ -void grub_loongarch64_abs64_hi12 (grub_uint32_t *place, grub_int64_t offset) -{ - const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xffc003ff); - grub_uint32_t val; - - offset >>= 52; - val = ((offset & 0xfff) << 10); - - *place &= insmask; - *place |= grub_cpu_to_le32 (val) & ~insmask; -} - -/* - * ABS64_LO20 relocation for the 64-bit absolute address - * (*(uint32_t *) PC) [24 ... 5] = (S + A) [51 ... 32] - */ -void grub_loongarch64_abs64_lo20 (grub_uint32_t *place, grub_int64_t offset) -{ - const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfe00001f); - grub_uint32_t val; - - offset >>= 32; - val = ((offset & 0xfffff) << 5); - - *place &= insmask; - *place |= grub_cpu_to_le32 (val) & ~insmask; -} diff --git a/grub-core/kern/loongarch64/efi/init.c b/grub-core/kern/loongarch64/efi/init.c deleted file mode 100644 index 924b0e87d..000000000 --- a/grub-core/kern/loongarch64/efi/init.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -#define EFI_TIMER_PERIOD_MILLISECONDS(ms) ((grub_uint64_t)(ms * 10000)) - -static grub_uint64_t tmr; -static grub_efi_event_t tmr_evt; - -static grub_uint64_t -grub_efi_get_time_ms (void) -{ - return tmr; -} - -static void -grub_loongson_increment_timer (grub_efi_event_t event __attribute__ ((unused)), - void *context __attribute__ ((unused))) -{ - tmr += 10; -} - -void -grub_machine_init (void) -{ - grub_efi_boot_services_t *b; - - grub_efi_init (); - - b = grub_efi_system_table->boot_services; - b->create_event (GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL, - GRUB_EFI_TPL_CALLBACK, grub_loongson_increment_timer, NULL, &tmr_evt); - b->set_timer (tmr_evt, GRUB_EFI_TIMER_PERIODIC, EFI_TIMER_PERIOD_MILLISECONDS(10)); - - grub_install_get_time_ms (grub_efi_get_time_ms); -} - -void -grub_machine_fini (int flags) -{ - grub_efi_boot_services_t *b; - - if (!(flags & GRUB_LOADER_FLAG_NORETURN)) - return; - - b = grub_efi_system_table->boot_services; - - b->set_timer (tmr_evt, GRUB_EFI_TIMER_CANCEL, 0); - b->close_event (tmr_evt); - - grub_efi_fini (); - - if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) - grub_efi_memory_fini (); -} diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c deleted file mode 100644 index 143a232b8..000000000 --- a/grub-core/kern/main.c +++ /dev/null @@ -1,370 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef GRUB_MACHINE_PCBIOS -#include -#endif - -static bool cli_disabled = false; -static bool cli_need_auth = false; - -grub_addr_t -grub_modules_get_end (void) -{ - struct grub_module_info *modinfo; - - modinfo = (struct grub_module_info *) grub_modbase; - - /* Check if there are any modules. */ - if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC) - return grub_modbase; - - return grub_modbase + modinfo->size; -} - -/* Load all modules in core. */ -static void -grub_load_modules (void) -{ - struct grub_module_header *header; - FOR_MODULES (header) - { - /* Not an ELF module, skip. */ - if (header->type != OBJ_TYPE_ELF) - continue; - - 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 (); - } -} - -static char *load_config; - -static void -grub_load_config (void) -{ - struct grub_module_header *header; - FOR_MODULES (header) - { - /* Not an embedded config, skip. */ - if (header->type != OBJ_TYPE_CONFIG) - continue; - - load_config = grub_malloc (header->size - sizeof (struct grub_module_header) + 1); - if (!load_config) - { - grub_print_error (); - break; - } - grub_memcpy (load_config, (char *) header + - sizeof (struct grub_module_header), - header->size - sizeof (struct grub_module_header)); - load_config[header->size - sizeof (struct grub_module_header)] = 0; - break; - } -} - -/* 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); -} - -static void -grub_set_prefix_and_root (void) -{ - char *device = NULL; - char *path = NULL; - char *fwdevice = NULL; - char *fwpath = NULL; - char *prefix = NULL; - struct grub_module_header *header; - - FOR_MODULES (header) - if (header->type == OBJ_TYPE_PREFIX) - prefix = (char *) header + sizeof (struct grub_module_header); - - grub_register_variable_hook ("root", 0, grub_env_write_root); - - grub_machine_get_bootlocation (&fwdevice, &fwpath); - - if (fwdevice) - { - char *cmdpath; - - cmdpath = grub_xasprintf ("(%s)%s", fwdevice, fwpath ? : ""); - if (cmdpath) - { - grub_env_set ("cmdpath", cmdpath); - grub_env_export ("cmdpath"); - grub_free (cmdpath); - } - } - - if (prefix) - { - char *pptr = NULL; - if (prefix[0] == '(') - { - pptr = grub_strrchr (prefix, ')'); - if (pptr) - { - device = grub_strndup (prefix + 1, pptr - prefix - 1); - pptr++; - } - } - if (!pptr) - pptr = prefix; - if (pptr[0]) - path = grub_strdup (pptr); - } - - if (!device && fwdevice) - device = fwdevice; - else if (fwdevice && (device[0] == ',' || !device[0])) - { - /* We have a partition, but still need to fill in the drive. */ - char *comma, *new_device; - - for (comma = fwdevice; *comma; ) - { - if (comma[0] == '\\' && comma[1] == ',') - { - comma += 2; - continue; - } - if (*comma == ',') - break; - comma++; - } - if (*comma) - { - char *drive = grub_strndup (fwdevice, comma - fwdevice); - new_device = grub_xasprintf ("%s%s", drive, device); - grub_free (drive); - } - else - new_device = grub_xasprintf ("%s%s", fwdevice, device); - - grub_free (fwdevice); - grub_free (device); - device = new_device; - } - else - grub_free (fwdevice); - if (fwpath && !path) - { - grub_size_t len = grub_strlen (fwpath); - while (len > 1 && fwpath[len - 1] == '/') - fwpath[--len] = 0; - if (len >= sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1 - && grub_memcmp (fwpath + len - (sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1), GRUB_TARGET_CPU "-" GRUB_PLATFORM, - sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1) == 0) - fwpath[len - (sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1)] = 0; - path = fwpath; - } - else - grub_free (fwpath); - if (device) - { - char *prefix_set; - - prefix_set = grub_xasprintf ("(%s)%s", device, path ? : ""); - if (prefix_set) - { - grub_env_set ("prefix", prefix_set); - grub_free (prefix_set); - } - grub_env_set ("root", device); - } - - grub_free (device); - grub_free (path); - grub_print_error (); -} - -/* 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"); - - /* Print errors if any. */ - grub_print_error (); - grub_errno = 0; - - grub_command_execute ("normal", 0, 0); -} - -bool -grub_is_cli_disabled (void) -{ - return cli_disabled; -} - -bool -grub_is_cli_need_auth (void) -{ - return cli_need_auth; -} - -void grub_cli_set_auth_needed (void) -{ - cli_need_auth = true; -} - -static void -check_is_cli_disabled (void) -{ - struct grub_module_header *header; - header = 0; - - FOR_MODULES (header) - { - if (header->type == OBJ_TYPE_DISABLE_CLI) - { - cli_disabled = true; - return; - } - } -} - -static void -reclaim_module_space (void) -{ - grub_addr_t modstart, modend; - - if (!grub_modbase) - return; - -#ifdef GRUB_MACHINE_PCBIOS - modstart = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR; -#else - modstart = grub_modbase; -#endif - modend = grub_modules_get_end (); - grub_modbase = 0; - -#if GRUB_KERNEL_PRELOAD_SPACE_REUSABLE - grub_mm_init_region ((void *) modstart, modend - modstart); -#else - (void) modstart; - (void) modend; -#endif -} - -/* The main routine. */ -void __attribute__ ((noreturn)) -grub_main (void) -{ -#ifdef GRUB_STACK_PROTECTOR - /* - * This call should only be made from a function that does not return because - * functions that return will get instrumented to check that the stack cookie - * does not change and this call will change the stack cookie. Thus a stack - * guard failure will be triggered. - */ - grub_update_stack_guard (); -#endif - - /* First of all, initialize the machine. */ - grub_machine_init (); - - grub_boot_time ("After machine init."); - - /* This breaks flicker-free boot on EFI systems, so disable it there. */ -#ifndef GRUB_MACHINE_EFI - /* Hello. */ - grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); - grub_printf ("Welcome to GRUB!\n\n"); - grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); -#endif - - /* Init verifiers API. */ - grub_verifiers_init (); - - grub_load_config (); - - grub_boot_time ("Before loading embedded modules."); - - /* 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 (); - - grub_boot_time ("After loading embedded modules."); - - /* Check if the CLI should be disabled */ - check_is_cli_disabled (); - - /* It is better to set the root device as soon as possible, - for convenience. */ - grub_set_prefix_and_root (); - grub_env_export ("root"); - grub_env_export ("prefix"); - - /* Reclaim space used for modules. */ - reclaim_module_space (); - - grub_boot_time ("After reclaiming module space."); - - grub_register_core_commands (); - - grub_boot_time ("Before execution of embedded config."); - - if (load_config) - grub_parser_execute (load_config); - - grub_boot_time ("After execution of embedded config. Attempt to go to normal mode"); - - grub_load_normal_mode (); - grub_rescue_run (); -} diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c deleted file mode 100644 index 2ed3ff319..000000000 --- a/grub-core/kern/mips/arc/init.c +++ /dev/null @@ -1,463 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const char *type_names[] = { -#ifdef GRUB_CPU_WORDS_BIGENDIAN - NULL, -#endif - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - "eisa", "tc", "scsi", "dti", "multi", "disk", "tape", "cdrom", "worm", - "serial", "net", "video", "par", "point", "key", "audio", "other", - "rdisk", "fdisk", "tape", "modem", "monitor", "print", "pointer", - "keyboard", "term", -#ifndef GRUB_CPU_WORDS_BIGENDIAN - "other", -#endif - "line", "network", NULL -}; - -static int -iterate_rec (const char *prefix, const struct grub_arc_component *parent, - grub_arc_iterate_devs_hook_t hook, void *hook_data, - int alt_names) -{ - const struct grub_arc_component *comp; - FOR_ARC_CHILDREN(comp, parent) - { - char *name; - const char *cname = NULL; - if (comp->type < ARRAY_SIZE (type_names)) - cname = type_names[comp->type]; - if (!cname) - cname = "unknown"; - if (alt_names) - name = grub_xasprintf ("%s/%s%lu", prefix, cname, comp->key); - else - name = grub_xasprintf ("%s%s(%lu)", prefix, cname, comp->key); - if (!name) - return 1; - if (hook (name, comp, hook_data)) - { - grub_free (name); - return 1; - } - if (iterate_rec ((parent ? name : prefix), comp, hook, hook_data, - alt_names)) - { - grub_free (name); - return 1; - } - grub_free (name); - } - return 0; -} - -int -grub_arc_iterate_devs (grub_arc_iterate_devs_hook_t hook, void *hook_data, - int alt_names) -{ - return iterate_rec ((alt_names ? "arc" : ""), NULL, hook, hook_data, - alt_names); -} - -grub_err_t -grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) -{ - struct grub_arc_memory_descriptor *cur = NULL; - while (1) - { - grub_memory_type_t type; - cur = GRUB_ARC_FIRMWARE_VECTOR->getmemorydescriptor (cur); - if (!cur) - return GRUB_ERR_NONE; - switch (cur->type) - { - case GRUB_ARC_MEMORY_EXCEPTION_BLOCK: - case GRUB_ARC_MEMORY_SYSTEM_PARAMETER_BLOCK: - case GRUB_ARC_MEMORY_FW_PERMANENT: - default: - type = GRUB_MEMORY_RESERVED; - break; - - case GRUB_ARC_MEMORY_FW_TEMPORARY: - case GRUB_ARC_MEMORY_FREE: - case GRUB_ARC_MEMORY_LOADED: - case GRUB_ARC_MEMORY_FREE_CONTIGUOUS: - type = GRUB_MEMORY_AVAILABLE; - break; - case GRUB_ARC_MEMORY_BADRAM: - type = GRUB_MEMORY_BADRAM; - break; - } - if (hook (((grub_uint64_t) cur->start_page) << 12, - ((grub_uint64_t) cur->num_pages) << 12, type, hook_data)) - return GRUB_ERR_NONE; - } -} - -char * -grub_arc_alt_name_to_norm (const char *name, const char *suffix) -{ - char *optr; - const char *iptr; - char * ret = grub_malloc (2 * grub_strlen (name) + grub_strlen (suffix)); - int state = 0; - - if (!ret) - return NULL; - optr = ret; - for (iptr = name + 4; *iptr; iptr++) - if (state == 0) - { - if (!grub_isdigit (*iptr)) - *optr++ = *iptr; - else - { - *optr++ = '('; - *optr++ = *iptr; - state = 1; - } - } - else - { - if (grub_isdigit (*iptr)) - *optr++ = *iptr; - else - { - *optr++ = ')'; - state = 0; - } - } - if (state) - *optr++ = ')'; - grub_strcpy (optr, suffix); - return ret; -} - -static char * -norm_name_to_alt (const char *name) -{ - char *optr; - const char *iptr; - int state = 0; - char * ret = grub_malloc (grub_strlen (name) + sizeof ("arc/")); - - if (!ret) - return NULL; - optr = grub_stpcpy (ret, "arc/"); - for (iptr = name; *iptr; iptr++) - { - if (state == 3) - { - *optr++ = '/'; - state = 0; - } - if (*iptr == '(') - { - state = 1; - continue; - } - if (*iptr == ')') - { - if (state == 1) - *optr++ = '0'; - state = 3; - continue; - } - *optr++ = *iptr; - if (state == 1) - state = 2; - } - *optr = '\0'; - return ret; -} - -extern grub_uint32_t grub_total_modules_size __attribute__ ((section(".text"))); -grub_addr_t grub_modbase; - -extern char _end[]; -static char boot_location[256]; - -void -grub_machine_init (void) -{ - struct grub_arc_memory_descriptor *cur = NULL; - grub_addr_t modend; - - grub_memcpy (boot_location, - (char *) (GRUB_DECOMPRESSOR_LINK_ADDR - 256), 256); - - grub_modbase = ALIGN_UP ((grub_addr_t) _end, GRUB_KERNEL_MACHINE_MOD_ALIGN); - modend = grub_modbase + grub_total_modules_size; - grub_console_init_early (); - - /* FIXME: measure this. */ - grub_arch_cpuclock = 150000000; - grub_install_get_time_ms (grub_rtc_get_time_ms); - - while (1) - { - grub_uint64_t start, end; - cur = GRUB_ARC_FIRMWARE_VECTOR->getmemorydescriptor (cur); - if (!cur) - break; - if (cur->type != GRUB_ARC_MEMORY_FREE - && cur->type != GRUB_ARC_MEMORY_LOADED - && cur->type != GRUB_ARC_MEMORY_FREE_CONTIGUOUS) - continue; - start = ((grub_uint64_t) cur->start_page) << 12; - end = ((grub_uint64_t) cur->num_pages) << 12; - end += start; - if ((grub_uint64_t) start < (modend & 0x1fffffff)) - start = (modend & 0x1fffffff); - if ((grub_uint64_t) end > 0x20000000) - end = 0x20000000; - if (end > start) - grub_mm_init_region ((void *) (grub_addr_t) (start | 0x80000000), - end - start); - } - - grub_console_init_lately (); - - grub_arcdisk_init (); -} - -void -grub_machine_fini (int flags __attribute__ ((unused))) -{ -} - -void -grub_halt (void) -{ - GRUB_ARC_FIRMWARE_VECTOR->powerdown (); - - grub_millisleep (1500); - - grub_puts_ (N_("Shutdown failed")); - grub_refresh (); - while (1); -} - -void -grub_exit (void) -{ - GRUB_ARC_FIRMWARE_VECTOR->exit (); - - grub_millisleep (1500); - - grub_puts_ (N_("Exit failed")); - grub_refresh (); - while (1); -} - -static char * -get_part (char *dev) -{ - char *ptr; - if (!*dev) - return 0; - ptr = dev + grub_strlen (dev) - 1; - if (ptr == dev || *ptr != ')') - return 0; - ptr--; - while (grub_isdigit (*ptr) && ptr > dev) - ptr--; - if (*ptr != '(' || ptr == dev) - return 0; - ptr--; - if (ptr - dev < (int) sizeof ("partition") - 2) - return 0; - ptr -= sizeof ("partition") - 2; - if (grub_memcmp (ptr, "partition", sizeof ("partition") - 1) != 0) - return 0; - return ptr; -} - -static grub_disk_addr_t -get_partition_offset (char *part, grub_disk_addr_t *en) -{ - grub_arc_fileno_t handle; - grub_disk_addr_t ret = -1; - struct grub_arc_fileinfo info; - grub_arc_err_t r; - - if (GRUB_ARC_FIRMWARE_VECTOR->open (part, GRUB_ARC_FILE_ACCESS_OPEN_RO, - &handle)) - return -1; - - r = GRUB_ARC_FIRMWARE_VECTOR->getfileinformation (handle, &info); - if (!r) - { - ret = (info.start >> 9); - *en = (info.end >> 9); - } - GRUB_ARC_FIRMWARE_VECTOR->close (handle); - return ret; -} - -struct get_device_name_ctx -{ - char *partition_name; - grub_disk_addr_t poff, pend; -}; - -static int -get_device_name_iter (grub_disk_t disk __attribute__ ((unused)), - const grub_partition_t part, void *data) -{ - struct get_device_name_ctx *ctx = data; - - if (grub_partition_get_start (part) == ctx->poff - && grub_partition_get_len (part) == ctx->pend) - { - ctx->partition_name = grub_partition_get_name (part); - return 1; - } - - return 0; -} - -void -grub_machine_get_bootlocation (char **device, char **path) -{ - char *loaddev = boot_location; - char *pptr, *partptr; - char *dname; - grub_disk_addr_t poff = -1, pend = -1; - struct get_device_name_ctx ctx; - grub_disk_t parent = 0; - unsigned i; - - for (i = 0; i < ARRAY_SIZE (type_names); i++) - if (type_names[i] - && grub_memcmp (loaddev, type_names[i], grub_strlen (type_names[i])) == 0 - && loaddev[grub_strlen (type_names[i])] == '(') - break; - if (i == ARRAY_SIZE (type_names)) - pptr = loaddev; - else - for (pptr = loaddev; *pptr && *pptr != '/' && *pptr != '\\'; pptr++); - if (*pptr) - { - char *iptr, *optr; - char sep = *pptr; - *path = grub_malloc (grub_strlen (pptr) + 1); - if (!*path) - return; - for (iptr = pptr, optr = *path; *iptr; iptr++, optr++) - if (*iptr == sep) - *optr = '/'; - else - *optr = *iptr; - *optr = '\0'; - *path = grub_strdup (pptr); - *pptr = '\0'; - } - - if (*loaddev == '\0') - { - const char *syspart = 0; - - if (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmware_vector_length - >= (unsigned) ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable + 1) - - (char *) GRUB_ARC_FIRMWARE_VECTOR) - && GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable) - syspart = GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable ("SystemPartition"); - if (!syspart) - return; - loaddev = grub_strdup (syspart); - } - - partptr = get_part (loaddev); - if (partptr) - { - poff = get_partition_offset (loaddev, &pend); - *partptr = '\0'; - } - dname = norm_name_to_alt (loaddev); - if (poff == (grub_addr_t) -1) - { - *device = dname; - if (loaddev != boot_location) - grub_free (loaddev); - return; - } - - parent = grub_disk_open (dname); - if (!parent) - { - *device = dname; - if (loaddev != boot_location) - grub_free (loaddev); - return; - } - - if (poff == 0 - && pend == grub_disk_native_sectors (parent)) - { - grub_disk_close (parent); - *device = dname; - if (loaddev != boot_location) - grub_free (loaddev); - return; - } - - ctx.partition_name = NULL; - ctx.poff = poff; - ctx.pend = pend; - - grub_partition_iterate (parent, get_device_name_iter, &ctx); - grub_disk_close (parent); - - if (! ctx.partition_name) - { - *device = dname; - if (loaddev != boot_location) - grub_free (loaddev); - return; - } - - *device = grub_xasprintf ("%s,%s", dname, - ctx.partition_name); - grub_free (ctx.partition_name); - grub_free (dname); - if (loaddev != boot_location) - grub_free (loaddev); -} diff --git a/grub-core/kern/mips/cache.S b/grub-core/kern/mips/cache.S deleted file mode 100644 index fa331eca1..000000000 --- a/grub-core/kern/mips/cache.S +++ /dev/null @@ -1,70 +0,0 @@ - -#include - - .set noreorder - .set nomacro - -FUNCTION (grub_arch_sync_caches) -#include "cache_flush.S" - j $ra - nop - -FUNCTION (grub_arch_sync_dma_caches) - 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_op 1, 0($t0) -#ifdef GRUB_MACHINE_MIPS_LOONGSON - cache_op 1, 1($t0) - cache_op 1, 2($t0) - cache_op 1, 3($t0) - - addiu $t1, $t1, -0x20 - bne $t1, $zero, 1b - addiu $t0, $t0, 0x20 -#else - addiu $t1, $t1, -4 - bne $t1, $zero, 1b - addiu $t0, $t0, 0x4 -#endif - sync_op - move $t0, $t2 - subu $t1, $t3, $t2 -2: -#ifdef GRUB_MACHINE_MIPS_LOONGSON - cache_op 0, 0($t0) - addiu $t1, $t1, -0x20 - bne $t1, $zero, 2b - addiu $t0, $t0, 0x20 -#else - cache_op 0, 0($t0) - addiu $t1, $t1, -4 - bne $t1, $zero, 2b - addiu $t0, $t0, 0x4 -#endif - sync_op - move $t0, $t2 - subu $t1, $t3, $t2 -2: -#ifdef GRUB_MACHINE_MIPS_LOONGSON - cache_op 23, 0($t0) - addiu $t1, $t1, -0x20 - bne $t1, $zero, 2b - addiu $t0, $t0, 0x20 -#else - cache_op 23, 0($t0) - addiu $t1, $t1, -0x4 - bne $t1, $zero, 2b - addiu $t0, $t0, 0x4 -#endif - sync_op - - jr $ra - nop diff --git a/grub-core/kern/mips/cache_flush.S b/grub-core/kern/mips/cache_flush.S deleted file mode 100644 index 89961a0f7..000000000 --- a/grub-core/kern/mips/cache_flush.S +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef CACHE_OP_DEFINED -#define CACHE_OP_DEFINED 1 - .macro cache_op op addr - .set mips3 - cache \op, \addr - .set mips1 - .endm - .macro sync_op - .set mips3 - sync - .set mips1 - .endm -#endif - - 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_op 1, 0($t0) - /* All four ways. */ -#ifdef GRUB_MACHINE_MIPS_LOONGSON - cache_op 1, 1($t0) - cache_op 1, 2($t0) - cache_op 1, 3($t0) - addiu $t1, $t1, -0x20 - bne $t1, $zero, 1b - addiu $t0, $t0, 0x20 - -#else - addiu $t1, $t1, -0x4 - bne $t1, $zero, 1b - addiu $t0, $t0, 0x4 -#endif - sync_op - move $t0, $t2 - subu $t1, $t3, $t2 -2: - cache_op 0, 0($t0) -#ifdef GRUB_MACHINE_MIPS_LOONGSON - addiu $t1, $t1, -0x20 - bne $t1, $zero, 2b - addiu $t0, $t0, 0x20 -#else - addiu $t1, $t1, -0x4 - bne $t1, $zero, 2b - addiu $t0, $t0, 0x4 -#endif - sync_op diff --git a/grub-core/kern/mips/dl.c b/grub-core/kern/mips/dl.c deleted file mode 100644 index 5b02f97fc..000000000 --- a/grub-core/kern/mips/dl.c +++ /dev/null @@ -1,274 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -/* Dummy __gnu_local_gp. Resolved by linker. */ -static char __gnu_local_gp_dummy; -static char _gp_disp_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 GRUB_CPU_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, N_("invalid arch-dependent ELF magic")); - - return GRUB_ERR_NONE; -} - -#pragma GCC diagnostic ignored "-Wcast-align" - -grub_err_t -grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, - grub_size_t *got) -{ - const Elf_Ehdr *e = ehdr; - const Elf_Shdr *s; - /* FIXME: suboptimal. */ - grub_size_t gp_size = 0; - unsigned i; - - *tramp = 0; - *got = 0; - - for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize)) - if (s->sh_type == SHT_REL) - { - const Elf_Rel *rel, *max; - - for (rel = (const Elf_Rel *) ((const 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"); - - *got = gp_size; - - return GRUB_ERR_NONE; -} - -/* Relocate symbols. */ -grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - Elf_Shdr *s, grub_dl_segment_t seg) -{ - grub_uint32_t gp0; - Elf_Ehdr *e = ehdr; - - if (!mod->reginfo) - { - unsigned i; - Elf_Shdr *ri; - - /* Find reginfo. */ - for (i = 0, ri = (Elf_Shdr *) ((char *) ehdr + e->e_shoff); - i < e->e_shnum; - i++, ri = (Elf_Shdr *) ((char *) ri + e->e_shentsize)) - if (ri->sh_type == SHT_MIPS_REGINFO) - break; - if (i == e->e_shnum) - return grub_error (GRUB_ERR_BAD_MODULE, "no reginfo found"); - mod->reginfo = (grub_uint32_t *)((char *) ehdr + ri->sh_offset); - } - - gp0 = mod->reginfo[5]; - Elf_Rel *rel, *max; - - for (rel = (Elf_Rel *) ((char *) e + s->sh_offset), - max = (Elf_Rel *) ((char *) rel + s->sh_size); - rel < max; - rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) - { - grub_uint8_t *addr; - Elf_Sym *sym; - grub_uint32_t sym_value; - - if (seg->size < rel->r_offset) - return grub_error (GRUB_ERR_BAD_MODULE, - "reloc offset is out of the segment"); - - addr = (grub_uint8_t *) ((char *) seg->addr + rel->r_offset); - sym = (Elf_Sym *) ((char *) mod->symtab - + mod->symsize * ELF_R_SYM (rel->r_info)); - sym_value = sym->st_value; - if (s->sh_type == SHT_RELA) - { - sym_value += ((Elf_Rela *) rel)->r_addend; - } - if (sym_value == (grub_addr_t) &__gnu_local_gp_dummy) - sym_value = (grub_addr_t) mod->got; - else if (sym_value == (grub_addr_t) &_gp_disp_dummy) - { - sym_value = (grub_addr_t) mod->got - (grub_addr_t) addr; - if (ELF_R_TYPE (rel->r_info) == R_MIPS_LO16) - /* ABI mandates +4 even if partner lui doesn't - immediately precede addiu. */ - sym_value += 4; - } - switch (ELF_R_TYPE (rel->r_info)) - { - case R_MIPS_HI16: - { - grub_uint32_t value; - Elf_Rel *rel2; - -#ifdef GRUB_CPU_WORDS_BIGENDIAN - addr += 2; -#endif - - /* Handle partner lo16 relocation. Lower part is - treated as signed. Hence add 0x8000 to compensate. - */ - value = (*(grub_uint16_t *) addr << 16) - + sym_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 -#ifdef GRUB_CPU_WORDS_BIGENDIAN - + 2 -#endif - ); - break; - } - *(grub_uint16_t *) addr = (value >> 16) & 0xffff; - } - break; - case R_MIPS_LO16: -#ifdef GRUB_CPU_WORDS_BIGENDIAN - addr += 2; -#endif - *(grub_uint16_t *) addr += sym_value & 0xffff; - break; - case R_MIPS_32: - *(grub_uint32_t *) addr += sym_value; - break; - case R_MIPS_GPREL32: - *(grub_uint32_t *) addr = sym_value - + *(grub_uint32_t *) addr + gp0 - (grub_uint32_t)mod->got; - break; - - case R_MIPS_26: - { - grub_uint32_t value; - grub_uint32_t raw; - raw = (*(grub_uint32_t *) addr) & 0x3ffffff; - value = raw << 2; - value += sym_value; - raw = (value >> 2) & 0x3ffffff; - - *(grub_uint32_t *) addr = - raw | ((*(grub_uint32_t *) addr) & 0xfc000000); - } - break; - case R_MIPS_GOT16: - if (ELF_ST_BIND (sym->st_info) == STB_LOCAL) - { - Elf_Rel *rel2; - /* Handle partner lo16 relocation. Lower part is - treated as signed. Hence add 0x8000 to compensate. - */ - sym_value += (*(grub_uint16_t *) addr << 16) - + 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) - { - sym_value += *(grub_int16_t *) - ((char *) seg->addr + rel2->r_offset -#ifdef GRUB_CPU_WORDS_BIGENDIAN - + 2 -#endif - ); - break; - } - sym_value &= 0xffff0000; - *(grub_uint16_t *) addr = 0; - } - /* Fallthrough. */ - case R_MIPS_CALL16: - { - grub_uint32_t *gpptr = mod->gotptr; - /* FIXME: reuse*/ -#ifdef GRUB_CPU_WORDS_BIGENDIAN - addr += 2; -#endif - *gpptr = sym_value + *(grub_uint16_t *) addr; - *(grub_uint16_t *) addr - = sizeof (grub_uint32_t) * (gpptr - (grub_uint32_t *) mod->got); - mod->gotptr = gpptr + 1; - break; - } - case R_MIPS_JALR: - break; - default: - { - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - 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, 0); - grub_dl_register_symbol ("_gp_disp", &_gp_disp_dummy, 0, 0); -} - diff --git a/grub-core/kern/mips/init.c b/grub-core/kern/mips/init.c deleted file mode 100644 index 14b8752ec..000000000 --- a/grub-core/kern/mips/init.c +++ /dev/null @@ -1,38 +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 . - */ - -#include -#include -#include -#include - -/* 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, " GRUB_CPU_MIPS_COP0_TIMER_COUNT : "=r" (low)); - if (low < last) - high++; - last = low; - - return (((grub_uint64_t) high) << 32) | low; -} diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c deleted file mode 100644 index 5bd721260..000000000 --- a/grub-core/kern/mips/loongson/init.c +++ /dev/null @@ -1,320 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -grub_err_t -grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) -{ - hook (GRUB_ARCH_LOWMEMPSTART, grub_arch_memsize << 20, - GRUB_MEMORY_AVAILABLE, hook_data); - hook (GRUB_ARCH_HIGHMEMPSTART, grub_arch_highmemsize << 20, - GRUB_MEMORY_AVAILABLE, hook_data); - return GRUB_ERR_NONE; -} - -/* Helper for init_pci. */ -static int -set_card (grub_pci_device_t dev, grub_pci_id_t pciid, - void *data __attribute__ ((unused))) -{ - grub_pci_address_t addr; - /* We could use grub_pci_assign_addresses for this but we prefer to - have exactly same memory map as on pmon. */ - switch (pciid) - { - case GRUB_LOONGSON_OHCI_PCIID: - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - grub_pci_write (addr, 0x5025000); - addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE - | GRUB_PCI_COMMAND_PARITY_ERROR - | GRUB_PCI_COMMAND_BUS_MASTER - | GRUB_PCI_COMMAND_MEM_ENABLED); - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); - grub_pci_write_word (addr, 0x0200 | GRUB_PCI_STATUS_CAPABILITIES); - break; - case GRUB_LOONGSON_EHCI_PCIID: - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - grub_pci_write (addr, 0x5026000); - addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE - | GRUB_PCI_COMMAND_PARITY_ERROR - | GRUB_PCI_COMMAND_BUS_MASTER - | GRUB_PCI_COMMAND_MEM_ENABLED); - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); - grub_pci_write_word (addr, (1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT) - | GRUB_PCI_STATUS_CAPABILITIES); - break; - } - return 0; -} - -static void -init_pci (void) -{ - *((volatile grub_uint32_t *) GRUB_CPU_LOONGSON_PCI_HIT1_SEL_LO) = 0x8000000c; - *((volatile grub_uint32_t *) GRUB_CPU_LOONGSON_PCI_HIT1_SEL_HI) = 0xffffffff; - - /* Setup PCI controller. */ - *((volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER - + GRUB_PCI_REG_COMMAND)) - = GRUB_PCI_COMMAND_PARITY_ERROR | GRUB_PCI_COMMAND_BUS_MASTER - | GRUB_PCI_COMMAND_MEM_ENABLED; - *((volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER - + GRUB_PCI_REG_STATUS)) - = (1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT) - | GRUB_PCI_STATUS_FAST_B2B_CAPABLE | GRUB_PCI_STATUS_66MHZ_CAPABLE - | GRUB_PCI_STATUS_CAPABILITIES; - - *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER - + GRUB_PCI_REG_CACHELINE)) = 0xff; - *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER - + GRUB_PCI_REG_ADDRESS_REG0)) - = 0x80000000 | GRUB_PCI_ADDR_MEM_TYPE_64 | GRUB_PCI_ADDR_MEM_PREFETCH; - *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER - + GRUB_PCI_REG_ADDRESS_REG1)) = 0; - - grub_pci_iterate (set_card, NULL); -} - -void -grub_machine_init (void) -{ - grub_addr_t modend; - grub_uint32_t prid; - - asm volatile ("mfc0 %0, " GRUB_CPU_LOONGSON_COP0_PRID : "=r" (prid)); - - switch (prid) - { - /* Loongson 2E. */ - case 0x6302: - grub_arch_machine = GRUB_ARCH_MACHINE_FULOONG2E; - grub_bonito_type = GRUB_BONITO_2F; - break; - /* Loongson 2F. */ - case 0x6303: - if (grub_arch_machine != GRUB_ARCH_MACHINE_FULOONG2F - && grub_arch_machine != GRUB_ARCH_MACHINE_YEELOONG) - grub_arch_machine = GRUB_ARCH_MACHINE_YEELOONG; - grub_bonito_type = GRUB_BONITO_2F; - break; - /* Loongson 3A. */ - case 0x6305: - grub_arch_machine = GRUB_ARCH_MACHINE_YEELOONG_3A; - grub_bonito_type = GRUB_BONITO_3A; - break; - } - - /* FIXME: measure this. */ - if (grub_arch_busclock == 0) - { - grub_arch_busclock = 66000000; - grub_arch_cpuclock = 797000000; - } - - grub_install_get_time_ms (grub_rtc_get_time_ms); - - if (grub_arch_memsize == 0) - { - grub_port_t smbbase; - grub_err_t err; - grub_pci_device_t dev; - struct grub_smbus_spd spd; - unsigned totalmem; - int i; - - if (!grub_cs5536_find (&dev)) - grub_fatal ("No CS5536 found\n"); - - err = grub_cs5536_init_smbus (dev, 0x7ff, &smbbase); - if (err) - grub_fatal ("Couldn't init SMBus: %s\n", grub_errmsg); - - /* Yeeloong and Fuloong have only one memory slot. */ - err = grub_cs5536_read_spd (smbbase, GRUB_SMB_RAM_START_ADDR, &spd); - if (err) - grub_fatal ("Couldn't read SPD: %s\n", grub_errmsg); - for (i = 5; i < 13; i++) - if (spd.ddr2.rank_capacity & (1 << (i & 7))) - break; - /* Something is wrong. */ - if (i == 13) - totalmem = 256; - else - totalmem = ((spd.ddr2.num_of_ranks - & GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_MASK) + 1) << (i + 2); - - if (totalmem >= 256) - { - grub_arch_memsize = 256; - grub_arch_highmemsize = totalmem - 256; - } - else - { - grub_arch_memsize = totalmem; - grub_arch_highmemsize = 0; - } - - grub_cs5536_init_geode (dev); - - init_pci (); - } - - 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. */ - - /* Initialize output terminal (can't be done earlier, as gfxterm - relies on a working heap. */ - grub_video_sm712_init (); - grub_video_sis315pro_init (); - grub_video_radeon_fuloong2e_init (); - grub_video_radeon_yeeloong3a_init (); - grub_font_init (); - grub_gfxterm_init (); - - grub_keylayouts_init (); - if (grub_arch_machine == GRUB_ARCH_MACHINE_YEELOONG - || grub_arch_machine == GRUB_ARCH_MACHINE_YEELOONG_3A) - grub_at_keyboard_init (); - - grub_terminfo_init (); - grub_serial_init (); - - grub_boot_init (); -} - -void -grub_machine_fini (int flags __attribute__ ((unused))) -{ -} - -static int -halt_via (grub_pci_device_t dev, grub_pci_id_t pciid, - void *data __attribute__ ((unused))) -{ - grub_uint16_t pm; - grub_pci_address_t addr; - - if (pciid != 0x30571106) - return 0; - - addr = grub_pci_make_address (dev, 0x40); - pm = grub_pci_read (addr) & ~1; - - if (pm == 0) - { - grub_pci_write (addr, 0x1801); - pm = 0x1800; - } - - addr = grub_pci_make_address (dev, 0x80); - grub_pci_write_byte (addr, 0xff); - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write_word (addr, grub_pci_read_word (addr) | GRUB_PCI_COMMAND_IO_ENABLED); - - /* FIXME: This one is derived from qemu. Check on real hardware. */ - grub_outw (0x2000, pm + 4 + GRUB_MACHINE_PCI_IO_BASE); - grub_millisleep (5000); - - return 0; -} - -void -grub_halt (void) -{ - switch (grub_arch_machine) - { - case GRUB_ARCH_MACHINE_FULOONG2E: - grub_pci_iterate (halt_via, NULL); - break; - case GRUB_ARCH_MACHINE_FULOONG2F: - { - grub_pci_device_t dev; - grub_port_t p; - if (grub_cs5536_find (&dev)) - { - p = (grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_GPIO_BAR) - & GRUB_CS5536_LBAR_ADDR_MASK) + GRUB_MACHINE_PCI_IO_BASE; - grub_outl ((1 << 13), p + 4); - grub_outl ((1 << 29), p); - grub_millisleep (5000); - } - } - break; - case GRUB_ARCH_MACHINE_YEELOONG: - grub_outb (grub_inb (GRUB_CPU_LOONGSON_GPIOCFG) - & ~GRUB_CPU_YEELOONG_SHUTDOWN_GPIO, GRUB_CPU_LOONGSON_GPIOCFG); - grub_millisleep (1500); - break; - case GRUB_ARCH_MACHINE_YEELOONG_3A: - grub_millisleep (1); - grub_outb (0x4e, GRUB_MACHINE_PCI_IO_BASE_3A | 0x66); - grub_millisleep (1); - grub_outb (2, GRUB_MACHINE_PCI_IO_BASE_3A | 0x62); - grub_millisleep (5000); - break; - } - - grub_puts_ (N_("Shutdown failed")); - grub_refresh (); - while (1); -} - -void -grub_exit (void) -{ - grub_halt (); -} - -void -grub_machine_get_bootlocation (char **device __attribute__ ((unused)), - char **path __attribute__ ((unused))) -{ -} - -extern char _end[]; -grub_addr_t grub_modbase = (grub_addr_t) _end; - diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c deleted file mode 100644 index b5477b87f..000000000 --- a/grub-core/kern/mips/qemu_mips/init.c +++ /dev/null @@ -1,105 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static inline int -probe_mem (grub_addr_t addr) -{ - volatile grub_uint8_t *ptr = (grub_uint8_t *) (0xa0000000 | addr); - grub_uint8_t c = *ptr; - *ptr = 0xAA; - if (*ptr != 0xAA) - return 0; - *ptr = 0x55; - if (*ptr != 0x55) - return 0; - *ptr = c; - return 1; -} - -void -grub_machine_init (void) -{ - grub_addr_t modend; - - if (grub_arch_memsize == 0) - { - int i; - - for (i = 27; i >= 0; i--) - if (probe_mem (grub_arch_memsize | (1 << i))) - grub_arch_memsize |= (1 << i); - grub_arch_memsize++; - } - - /* FIXME: measure this. */ - grub_arch_cpuclock = 200000000; - - modend = grub_modules_get_end (); - grub_mm_init_region ((void *) modend, grub_arch_memsize - - (modend - GRUB_ARCH_LOWMEMVSTART)); - - grub_install_get_time_ms (grub_rtc_get_time_ms); - - grub_keylayouts_init (); - grub_at_keyboard_init (); - - grub_qemu_init_cirrus (); - grub_vga_text_init (); - - grub_terminfo_init (); - grub_serial_init (); - - grub_boot_init (); -} - -void -grub_machine_fini (int flags __attribute__ ((unused))) -{ -} - -void -grub_exit (void) -{ - grub_halt (); -} - -void -grub_halt (void) -{ - grub_outl (42, 0xbfbf0004); - while (1); -} - -grub_err_t -grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) -{ - hook (0, grub_arch_memsize, GRUB_MEMORY_AVAILABLE, hook_data); - return GRUB_ERR_NONE; -} - -void -grub_machine_get_bootlocation (char **device __attribute__ ((unused)), - char **path __attribute__ ((unused))) -{ -} - -extern char _end[]; -grub_addr_t grub_modbase = (grub_addr_t) _end; - diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S deleted file mode 100644 index 1fdb58aca..000000000 --- a/grub-core/kern/mips/startup.S +++ /dev/null @@ -1,126 +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 . - */ - -#include -#include -#include -#include -#include -#include - -#define BASE_ADDR 8 - - .globl __start, _start, start - .set noreorder - .set nomacro -__start: -_start: -start: -.extern __bss_start -.extern _end - bal cont - nop - - .org GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE -VARIABLE(grub_total_modules_size) - .long 0 - -VARIABLE (grub_arch_busclock) - .long 0 -VARIABLE (grub_arch_cpuclock) - .long 0 -VARIABLE (grub_arch_memsize) - .long 0 -VARIABLE (grub_arch_highmemsize) - .long 0 -#ifdef GRUB_MACHINE_MIPS_LOONGSON -VARIABLE (grub_arch_machine) - .long GRUB_ARCH_MACHINE_FULOONG2F -#endif -cont: - /* Save our base. */ - move $s0, $ra - -#ifdef GRUB_MACHINE_MIPS_QEMU_MIPS - lui $t1, %hi(grub_arch_busclock) - addiu $t1, %lo(grub_arch_busclock) - sw $s4, 8($t1) -#endif - -#ifdef GRUB_MACHINE_MIPS_LOONGSON - 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) - sw $s7, 16($t1) -#endif - - /* Move the modules out of BSS. */ - lui $t2, %hi(__bss_start) - addiu $t2, %lo(__bss_start) - - lui $t1, %hi(_end) - addiu $t1, %lo(_end) - addiu $t1, (GRUB_KERNEL_MACHINE_MOD_ALIGN - 1) - li $t3, (GRUB_KERNEL_MACHINE_MOD_ALIGN - 1) - nor $t3, $t3, $0 - and $t1, $t1, $t3 - - lw $t3, (GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE - BASE_ADDR)($s0) - - /* Backward copy. */ - add $t1, $t1, $t3 - add $t2, $t2, $t3 - addiu $t1, $t1, -1 - addiu $t2, $t2, -1 - - /* $t2 is source. $t1 is destination. $t3 is size. */ -modulesmovcont: - beq $t3, $0, modulesmovdone - nop - lb GRUB_ASM_T4, 0($t2) - sb GRUB_ASM_T4, 0($t1) - addiu $t2, $t2, -1 - addiu $t1, $t1, -1 - b modulesmovcont - addiu $t3, $t3, -1 -modulesmovdone: - - /* Clean BSS. */ - - lui $t1, %hi(__bss_start) - addiu $t1, $t1, %lo(__bss_start) - lui $t2, %hi(_end) - addiu $t2, $t2, %lo(_end) -bsscont: - sb $0,0($t1) - addiu $t1, $t1, 1 - sltu $t3, $t1, $t2 - bne $t3, $0, bsscont - nop - - lui $t9, %hi(grub_main) - addiu $t9, %lo(grub_main) - - lui $sp, %hi(GRUB_MACHINE_MEMORY_STACK_HIGH) - jr $t9 - addiu $sp, $sp, %lo(GRUB_MACHINE_MEMORY_STACK_HIGH) - diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c deleted file mode 100644 index 2b7922393..000000000 --- a/grub-core/kern/misc.c +++ /dev/null @@ -1,1405 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -union printf_arg -{ - /* Yes, type is also part of union as the moment we fill the value - we don't need to store its type anymore (when we'll need it, we'll - have format spec again. So save some space. */ - enum - { - INT, LONG, LONGLONG, - UNSIGNED_INT = 3, UNSIGNED_LONG, UNSIGNED_LONGLONG, - STRING, - GUID - } type; - long long ll; -}; - -struct printf_args -{ - union printf_arg prealloc[32]; - union printf_arg *ptr; - grub_size_t count; -}; - -static void -parse_printf_args (const char *fmt0, struct printf_args *args, - va_list args_in); -static int -grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, - struct printf_args *args); - -static void -free_printf_args (struct printf_args *args) -{ - if (args->ptr != args->prealloc) - grub_free (args->ptr); -} - -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; -} - -char * -grub_strcpy (char *dest, const char *src) -{ - char *p = dest; - - while ((*p++ = *src++) != '\0') - ; - - return dest; -} - -int -grub_printf (const char *fmt, ...) -{ - va_list ap; - int ret; - -#if defined(MM_DEBUG) && !defined(GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) - /* - * To prevent infinite recursion when grub_mm_debug is on, disable it - * when calling grub_vprintf(). One such call loop is: - * grub_vprintf() -> parse_printf_args() -> parse_printf_arg_fmt() -> - * grub_debug_calloc() -> grub_printf() -> grub_vprintf(). - */ - int grub_mm_debug_save = 0; - - if (grub_mm_debug) - { - grub_mm_debug_save = grub_mm_debug; - grub_mm_debug = 0; - } -#endif - - va_start (ap, fmt); - ret = grub_vprintf (fmt, ap); - va_end (ap); - -#if defined(MM_DEBUG) && !defined(GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) - grub_mm_debug = grub_mm_debug_save; -#endif - - 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) -{ - return grub_puts (_(s)); -} - -#if defined (__APPLE__) && ! 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__) && ! defined (GRUB_UTIL) -int grub_err_printf (const char *fmt, ...) -__attribute__ ((alias("grub_printf"))); -#endif - -int -grub_debug_enabled (const char * condition) -{ - const char *debug, *found; - grub_size_t clen; - int ret = 0; - - debug = grub_env_get ("debug"); - if (!debug) - return 0; - - if (grub_strword (debug, "all")) - { - if (debug[3] == '\0') - return 1; - ret = 1; - } - - clen = grub_strlen (condition); - found = debug-1; - while(1) - { - found = grub_strstr (found+1, condition); - - if (found == NULL) - break; - - /* Found condition is not a whole word, so ignore it. */ - if (*(found + clen) != '\0' && *(found + clen) != ',' - && !grub_isspace (*(found + clen))) - continue; - - /* - * If found condition is at the start of debug or the start is on a word - * boundary, then enable debug. Else if found condition is prefixed with - * '-' and the start is on a word boundary, then disable debug. If none - * of these cases, ignore. - */ - if (found == debug || *(found - 1) == ',' || grub_isspace (*(found - 1))) - ret = 1; - else if (*(found - 1) == '-' && ((found == debug + 1) || (*(found - 2) == ',' - || grub_isspace (*(found - 2))))) - ret = 0; - } - - return ret; -} - -void -grub_real_dprintf (const char *file, const int line, const char *condition, - const char *fmt, ...) -{ - va_list args; - - if (grub_debug_enabled (condition)) - { - grub_printf ("%s:%d:%s: ", file, line, condition); - va_start (args, fmt); - grub_vprintf (fmt, args); - va_end (args); - grub_refresh (); - } -} - -#define PREALLOC_SIZE 255 - -int -grub_vprintf (const char *fmt, va_list ap) -{ - grub_size_t s; - static char buf[PREALLOC_SIZE + 1]; - char *curbuf = buf; - struct printf_args args; - - parse_printf_args (fmt, &args, ap); - - s = grub_vsnprintf_real (buf, PREALLOC_SIZE, fmt, &args); - if (s > PREALLOC_SIZE) - { - curbuf = grub_malloc (s + 1); - if (!curbuf) - { - grub_errno = GRUB_ERR_NONE; - buf[PREALLOC_SIZE - 3] = '.'; - buf[PREALLOC_SIZE - 2] = '.'; - buf[PREALLOC_SIZE - 1] = '.'; - buf[PREALLOC_SIZE] = 0; - curbuf = buf; - } - else - s = grub_vsnprintf_real (curbuf, s, fmt, &args); - } - - free_printf_args (&args); - - grub_xputs (curbuf); - - if (curbuf != buf) - grub_free (curbuf); - - return s; -} - -int -grub_memcmp (const void *s1, const void *s2, grub_size_t n) -{ - const grub_uint8_t *t1 = s1; - const grub_uint8_t *t2 = s2; - - while (n--) - { - if (*t1 != *t2) - return (int) *t1 - (int) *t2; - - t1++; - t2++; - } - - return 0; -} - -int -grub_strcmp (const char *s1, const char *s2) -{ - while (*s1 && *s2) - { - if (*s1 != *s2) - break; - - s1++; - s2++; - } - - return (int) (grub_uint8_t) *s1 - (int) (grub_uint8_t) *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) (grub_uint8_t) *s1 - (int) (grub_uint8_t) *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; -} - -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'); -} - -unsigned long -grub_strtoul (const char * restrict str, const char ** const restrict end, - int base) -{ - unsigned long long num; - - num = grub_strtoull (str, end, base); -#if GRUB_CPU_SIZEOF_LONG != 8 - if (num > ~0UL) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); - return ~0UL; - } -#endif - - return (unsigned long) num; -} - -unsigned long long -grub_strtoull (const char * restrict str, const char ** const restrict end, - int base) -{ - unsigned long long num = 0; - int found = 0; - - /* Skip white spaces. */ - /* grub_isspace checks that *str != '\0'. */ - while (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 >= 'a' - '0') - digit += '0' - 'a' + 10; - else if (digit > 9) - break; - - 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, - N_("overflow is detected")); - - if (end) - *end = (char *) str; - - return ~0ULL; - } - - num = num * base + digit; - str++; - } - - if (! found) - { - grub_error (GRUB_ERR_BAD_NUMBER, - N_("unrecognized number")); - - if (end) - *end = (char *) str; - - 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; -} - -/* clang detects that we're implementing here a memset so it decides to - optimise and calls memset resulting in infinite recursion. With volatile - we make it not optimise in this way. */ -#ifdef __clang__ -#define VOLATILE_CLANG volatile -#else -#define VOLATILE_CLANG -#endif - -void * -grub_memset (void *s, int c, grub_size_t len) -{ - void *p = s; - grub_uint8_t pattern8 = c; - - if (len >= 3 * sizeof (unsigned long)) - { - unsigned long patternl = 0; - grub_size_t i; - - for (i = 0; i < sizeof (unsigned long); i++) - patternl |= ((unsigned long) pattern8) << (8 * i); - - while (len > 0 && (((grub_addr_t) p) & (sizeof (unsigned long) - 1))) - { - *(VOLATILE_CLANG grub_uint8_t *) p = pattern8; - p = (grub_uint8_t *) p + 1; - len--; - } - while (len >= sizeof (unsigned long)) - { - *(VOLATILE_CLANG unsigned long *) p = patternl; - p = (unsigned long *) p + 1; - len -= sizeof (unsigned long); - } - } - - while (len > 0) - { - *(VOLATILE_CLANG grub_uint8_t *) p = pattern8; - p = (grub_uint8_t *) p + 1; - len--; - } - - return s; -} - -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_uint64_t d, grub_uint64_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) = (Q * D + M), where upper - represents the high 64 bits in 128-bits space. */ - unsigned bits = 64; - grub_uint64_t q = 0; - grub_uint64_t m = 0; - - /* ARM and IA64 don't have a fast 32-bit division. - Using that code would just make us use software division routines, calling - ourselves indirectly and hence getting infinite recursion. - */ -#if !GRUB_DIVISION_IN_SOFTWARE - /* Skip the slow computation if 32-bit arithmetic is possible. */ - if (n < 0xffffffff && d < 0xffffffff) - { - if (r) - *r = ((grub_uint32_t) n) % (grub_uint32_t) d; - - return ((grub_uint32_t) n) / (grub_uint32_t) d; - } -#endif - - 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 inline char * -grub_lltoa (char *str, int c, unsigned long long n) -{ - unsigned base = ((c == 'x') || (c == 'X')) ? 16 : ((c == 'o') ? 8 : 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 + ((c == 'x') ? 'a' : 'A') - 10) : d + '0'; - } - while (n >>= 4); - else if (base == 8) - do - { - *p++ = ((unsigned) (n & 0x7)) + '0'; - } - while (n >>= 3); - else - /* BASE == 10 */ - do - { - grub_uint64_t m; - - n = grub_divmod64 (n, 10, &m); - *p++ = m + '0'; - } - while (n); - - *p = 0; - - grub_reverse (str); - return p; -} - -/* - * Parse printf() fmt0 string into args arguments. - * - * The parsed arguments are either used by a printf() function to format the fmt0 - * string or they are used to compare a format string from an untrusted source - * against a format string with expected arguments. - * - * When the fmt_check is set to !0, e.g. 1, then this function is executed in - * printf() format check mode. This enforces stricter rules for parsing the - * fmt0 to limit exposure to possible errors in printf() handling. It also - * disables positional parameters, "$", because some formats, e.g "%s%1$d", - * cannot be validated with the current implementation. - * - * The max_args allows to set a maximum number of accepted arguments. If the fmt0 - * string defines more arguments than the max_args then the parse_printf_arg_fmt() - * function returns an error. This is currently used for format check only. - */ -static grub_err_t -parse_printf_arg_fmt (const char *fmt0, struct printf_args *args, - int fmt_check, grub_size_t max_args) -{ - const char *fmt; - char c; - grub_size_t n = 0; - - args->count = 0; - - COMPILE_TIME_ASSERT (sizeof (int) == sizeof (grub_uint32_t)); - COMPILE_TIME_ASSERT (sizeof (int) <= sizeof (long long)); - COMPILE_TIME_ASSERT (sizeof (long) <= sizeof (long long)); - COMPILE_TIME_ASSERT (sizeof (long long) == sizeof (void *) - || sizeof (int) == sizeof (void *)); - - fmt = fmt0; - while ((c = *fmt++) != 0) - { - if (c != '%') - continue; - - if (*fmt =='-') - fmt++; - - while (grub_isdigit (*fmt)) - fmt++; - - if (*fmt == '$') - { - if (fmt_check) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "positional arguments are not supported"); - fmt++; - } - - if (*fmt =='-') - fmt++; - - while (grub_isdigit (*fmt)) - fmt++; - - if (*fmt =='.') - fmt++; - - while (grub_isdigit (*fmt)) - fmt++; - - c = *fmt++; - if (c == 'l') - c = *fmt++; - if (c == 'l') - c = *fmt++; - - switch (c) - { - case 'p': - if (*(fmt) == 'G') - ++fmt; - /* Fall through. */ - case 'x': - case 'X': - case 'u': - case 'd': - case 'o': - case 'c': - case 'C': - case 's': - args->count++; - break; - case '%': - /* "%%" is the escape sequence to output "%". */ - break; - default: - if (fmt_check) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unexpected format"); - break; - } - } - - if (fmt_check && args->count > max_args) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many arguments"); - - if (args->count <= ARRAY_SIZE (args->prealloc)) - args->ptr = args->prealloc; - else - { - args->ptr = grub_calloc (args->count, sizeof (args->ptr[0])); - if (!args->ptr) - { - if (fmt_check) - return grub_errno; - - grub_errno = GRUB_ERR_NONE; - args->ptr = args->prealloc; - args->count = ARRAY_SIZE (args->prealloc); - } - } - - grub_memset (args->ptr, 0, args->count * sizeof (args->ptr[0])); - - fmt = fmt0; - n = 0; - while ((c = *fmt++) != 0) - { - int longfmt = 0; - unsigned long curn; - const char *p; - - if (c != '%') - continue; - - curn = n++; - - if (*fmt =='-') - fmt++; - - p = fmt; - - while (grub_isdigit (*fmt)) - fmt++; - - if (*fmt == '$') - { - curn = grub_strtoul (p, 0, 10); - if (curn == 0) - continue; - curn--; - fmt++; - } - - if (*fmt =='-') - fmt++; - - while (grub_isdigit (*fmt)) - fmt++; - - if (*fmt =='.') - fmt++; - - while (grub_isdigit (*fmt)) - fmt++; - - c = *fmt++; - if (c == '%') - { - n--; - continue; - } - - if (c == 'l') - { - c = *fmt++; - longfmt = 1; - } - if (c == 'l') - { - c = *fmt++; - longfmt = 2; - } - if (curn >= args->count) - continue; - switch (c) - { - case 'x': - case 'X': - case 'o': - case 'u': - args->ptr[curn].type = UNSIGNED_INT + longfmt; - break; - case 'd': - args->ptr[curn].type = INT + longfmt; - break; - case 'p': - if (sizeof (void *) == sizeof (long long)) - args->ptr[curn].type = UNSIGNED_LONGLONG; - else - args->ptr[curn].type = UNSIGNED_INT; - if (*(fmt) == 'G') { - args->ptr[curn].type = GUID; - ++fmt; - } - break; - case 's': - args->ptr[curn].type = STRING; - break; - case 'C': - case 'c': - args->ptr[curn].type = INT; - break; - } - } - - return GRUB_ERR_NONE; -} - -static void -parse_printf_args (const char *fmt0, struct printf_args *args, va_list args_in) -{ - grub_size_t n; - - parse_printf_arg_fmt (fmt0, args, 0, 0); - - for (n = 0; n < args->count; n++) - switch (args->ptr[n].type) - { - case INT: - args->ptr[n].ll = va_arg (args_in, int); - break; - case LONG: - args->ptr[n].ll = va_arg (args_in, long); - break; - case UNSIGNED_INT: - args->ptr[n].ll = va_arg (args_in, unsigned int); - break; - case UNSIGNED_LONG: - args->ptr[n].ll = va_arg (args_in, unsigned long); - break; - case LONGLONG: - case UNSIGNED_LONGLONG: - args->ptr[n].ll = va_arg (args_in, long long); - break; - case STRING: - case GUID: - if (sizeof (void *) == sizeof (long long)) - args->ptr[n].ll = va_arg (args_in, long long); - else - args->ptr[n].ll = va_arg (args_in, unsigned int); - break; - } -} - -static inline void __attribute__ ((always_inline)) -write_char (char *str, grub_size_t *count, grub_size_t max_len, unsigned char ch) -{ - if (*count < max_len) - str[*count] = ch; - - (*count)++; -} - -static void -write_number (char *str, grub_size_t *count, grub_size_t max_len, grub_size_t format1, - char rightfill, char zerofill, char c, long long value) -{ - char tmp[32]; - const char *p = tmp; - grub_size_t len; - grub_size_t fill; - - len = grub_lltoa (tmp, c, value) - tmp; - fill = len < format1 ? format1 - len : 0; - if (! rightfill) - while (fill--) - write_char (str, count, max_len, zerofill); - while (*p) - write_char (str, count, max_len, *p++); - if (rightfill) - while (fill--) - write_char (str, count, max_len, zerofill); -} - -static int -grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, - struct printf_args *args) -{ - char c; - grub_size_t n = 0; - grub_size_t count = 0; - const char *fmt; - - fmt = fmt0; - - while ((c = *fmt++) != 0) - { - unsigned int format1 = 0; - unsigned int format2 = ~ 0U; - char zerofill = ' '; - char rightfill = 0; - grub_size_t curn; - - if (c != '%') - { - write_char (str, &count, max_len, c); - continue; - } - - curn = n++; - - rescan:; - - if (*fmt =='-') - { - rightfill = 1; - fmt++; - } - - /* Read formatting parameters. */ - if (grub_isdigit (*fmt)) - { - if (fmt[0] == '0') - zerofill = '0'; - format1 = grub_strtoul (fmt, &fmt, 10); - } - - if (*fmt == '.') - fmt++; - - if (grub_isdigit (*fmt)) - format2 = grub_strtoul (fmt, &fmt, 10); - - if (*fmt == '$') - { - if (format1 == 0) - continue; - curn = format1 - 1; - fmt++; - format1 = 0; - format2 = ~ 0U; - zerofill = ' '; - rightfill = 0; - - goto rescan; - } - - c = *fmt++; - if (c == 'l') - c = *fmt++; - if (c == 'l') - c = *fmt++; - - if (c == '%') - { - write_char (str, &count, max_len, c); - n--; - continue; - } - - if (curn >= args->count) - continue; - - long long curarg = args->ptr[curn].ll; - - switch (c) - { - case 'p': - if (*(fmt) == 'G') - { - ++fmt; - grub_packed_guid_t *guid = (grub_packed_guid_t *)(grub_addr_t) curarg; - write_number (str, &count, max_len, 8, 0, '0', 'x', guid->data1); - write_char (str, &count, max_len, '-'); - write_number (str, &count, max_len, 4, 0, '0', 'x', guid->data2); - write_char (str, &count, max_len, '-'); - write_number (str, &count, max_len, 4, 0, '0', 'x', guid->data3); - write_char (str, &count, max_len, '-'); - write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[0]); - write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[1]); - write_char (str, &count, max_len, '-'); - write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[2]); - write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[3]); - write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[4]); - write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[5]); - write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[6]); - write_number (str, &count, max_len, 2, 0, '0', 'x', guid->data4[7]); - break; - } - else - { - write_char (str, &count, max_len, '0'); - write_char (str, &count, max_len, 'x'); - c = 'x'; - } - /* Fall through. */ - case 'x': - case 'X': - case 'u': - case 'd': - case 'o': - write_number (str, &count, max_len, format1, rightfill, zerofill, c, curarg); - break; - - case 'c': - write_char (str, &count, max_len, curarg & 0xff); - break; - - case 'C': - { - grub_uint32_t code = curarg; - 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 <= 0x10ffff) - { - shift = 18; - mask = 0xf0; - } - else - { - code = '?'; - shift = 0; - mask = 0; - } - - write_char (str, &count, max_len, mask | (code >> shift)); - - for (shift -= 6; shift >= 0; shift -= 6) - write_char (str, &count, max_len, 0x80 | (0x3f & (code >> shift))); - } - break; - - case 's': - { - grub_size_t len = 0; - grub_size_t fill; - const char *p = ((char *) (grub_addr_t) curarg) ? : "(null)"; - grub_size_t i; - - while (len < format2 && p[len]) - len++; - - fill = len < format1 ? format1 - len : 0; - - if (!rightfill) - while (fill--) - write_char (str, &count, max_len, zerofill); - - for (i = 0; i < len; i++) - write_char (str, &count, max_len, *p++); - - if (rightfill) - while (fill--) - write_char (str, &count, max_len, zerofill); - } - - break; - - default: - write_char (str, &count, max_len, c); - break; - } - } - - if (count < max_len) - str[count] = '\0'; - else - str[max_len] = '\0'; - return count; -} - -int -grub_vsnprintf (char *str, grub_size_t n, const char *fmt, va_list ap) -{ - grub_size_t ret; - struct printf_args args; - - if (!n) - return 0; - - n--; - - parse_printf_args (fmt, &args, ap); - - ret = grub_vsnprintf_real (str, n, fmt, &args); - - free_printf_args (&args); - - return ret; -} - -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; -} - -char * -grub_xvasprintf (const char *fmt, va_list ap) -{ - grub_size_t s, as = PREALLOC_SIZE; - char *ret; - struct printf_args args; - - parse_printf_args (fmt, &args, ap); - - while (1) - { - ret = grub_malloc (as + 1); - if (!ret) - { - free_printf_args (&args); - return NULL; - } - - s = grub_vsnprintf_real (ret, as, fmt, &args); - - if (s <= as) - { - free_printf_args (&args); - 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; -} - -grub_err_t -grub_printf_fmt_check (const char *fmt, const char *fmt_expected) -{ - struct printf_args args_expected, args_fmt; - grub_err_t ret; - grub_size_t n; - - if (fmt == NULL || fmt_expected == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid format"); - - ret = parse_printf_arg_fmt (fmt_expected, &args_expected, 1, GRUB_SIZE_MAX); - if (ret != GRUB_ERR_NONE) - return ret; - - /* Limit parsing to the number of expected arguments. */ - ret = parse_printf_arg_fmt (fmt, &args_fmt, 1, args_expected.count); - if (ret != GRUB_ERR_NONE) - { - free_printf_args (&args_expected); - return ret; - } - - for (n = 0; n < args_fmt.count; n++) - if (args_fmt.ptr[n].type != args_expected.ptr[n].type) - { - ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments types do not match"); - break; - } - - free_printf_args (&args_expected); - free_printf_args (&args_fmt); - - return ret; -} - - -/* Abort GRUB. This function does not return. */ -void __attribute__ ((noreturn)) -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 (); -} - -void -grub_fatal (const char *fmt, ...) -{ - va_list ap; - - va_start (ap, fmt); - grub_vprintf (_(fmt), ap); - va_end (ap); - - grub_refresh (); - - grub_abort (); -} - -grub_ssize_t -grub_utf8_to_utf16_alloc (const char *str8, grub_uint16_t **utf16_msg, grub_uint16_t **last_position) -{ - grub_size_t len; - grub_size_t len16; - - len = grub_strlen (str8); - - /* Check for integer overflow */ - if (len > GRUB_SSIZE_MAX / GRUB_MAX_UTF16_PER_UTF8 - 1) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("string too long")); - *utf16_msg = NULL; - return -1; - } - - len16 = len * GRUB_MAX_UTF16_PER_UTF8; - - *utf16_msg = grub_calloc (len16 + 1, sizeof (*utf16_msg[0])); - if (*utf16_msg == NULL) - return -1; - - len16 = grub_utf8_to_utf16 (*utf16_msg, len16, (grub_uint8_t *) str8, len, NULL); - - if (last_position != NULL) - *last_position = *utf16_msg + len16; - - return len16; -} - - -#if BOOT_TIME_STATS - -#include - -struct grub_boot_time *grub_boot_time_head; -static struct grub_boot_time **boot_time_last = &grub_boot_time_head; - -void -grub_real_boot_time (const char *file, - const int line, - const char *fmt, ...) -{ - struct grub_boot_time *n; - va_list args; - - grub_error_push (); - n = grub_malloc (sizeof (*n)); - if (!n) - { - grub_errno = 0; - grub_error_pop (); - return; - } - n->file = file; - n->line = line; - n->tp = grub_get_time_ms (); - n->next = 0; - - va_start (args, fmt); - n->msg = grub_xvasprintf (fmt, args); - va_end (args); - - *boot_time_last = n; - boot_time_last = &n->next; - - grub_errno = 0; - grub_error_pop (); -} -#endif diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c deleted file mode 100644 index 027a25cd1..000000000 --- a/grub-core/kern/mm.c +++ /dev/null @@ -1,863 +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 . - */ - -/* - 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. - - - if existing regions are insufficient to satisfy an allocation, a new - region can be requested from firmware. - - 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef MM_DEBUG -# undef grub_calloc -# undef grub_malloc -# undef grub_zalloc -# undef grub_realloc -# undef grub_free -# undef grub_memalign -#endif - - - -/* - * GRUB_MM_MGMT_OVERHEAD is an upper bound of management overhead of - * each region, with any possible padding taken into account. - * - * The value must be large enough to make sure grub_memalign(align, size) - * always succeeds after a successful call to - * grub_mm_init_region(addr, size + align + GRUB_MM_MGMT_OVERHEAD), - * for any given addr, align and size (assuming no interger overflow). - * - * The worst case which has maximum overhead is shown in the figure below: - * - * +-- addr - * v |<- size + align ->| - * +---------+----------------+----------------+------------------+---------+ - * | padding | grub_mm_region | grub_mm_header | usable bytes | padding | - * +---------+----------------+----------------+------------------+---------+ - * |<- a ->|<- b ->|<- c ->|<- d ->|<- e ->| - * ^ - * b == sizeof (struct grub_mm_region) | / Assuming no other suitable - * c == sizeof (struct grub_mm_header) | | block is available, then: - * d == size + align +-| If align == 0, this will be - * | the pointer returned by next - * Assuming addr % GRUB_MM_ALIGN == 1, then: | grub_memalign(align, size). - * a == GRUB_MM_ALIGN - 1 | If align > 0, this chunk may - * | need to be split to fulfill - * Assuming d % GRUB_MM_ALIGN == 1, then: | alignment requirements, and - * e == GRUB_MM_ALIGN - 1 | the returned pointer may be - * \ inside these usable bytes. - * Therefore, the maximum overhead is: - * a + b + c + e == (GRUB_MM_ALIGN - 1) + sizeof (struct grub_mm_region) - * + sizeof (struct grub_mm_header) + (GRUB_MM_ALIGN - 1) - */ -#define GRUB_MM_MGMT_OVERHEAD ((GRUB_MM_ALIGN - 1) \ - + sizeof (struct grub_mm_region) \ - + sizeof (struct grub_mm_header) \ - + (GRUB_MM_ALIGN - 1)) - -/* The size passed to grub_mm_add_region_fn() is aligned up by this value. */ -#define GRUB_MM_HEAP_GROW_ALIGN 4096 - -/* Minimal heap growth granularity when existing heap space is exhausted. */ -#define GRUB_MM_HEAP_GROW_EXTRA 0x100000 - -grub_mm_region_t grub_mm_base; -grub_mm_add_region_func_t grub_mm_add_region_fn; - -/* 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 = grub_mm_base; *r; *r = (*r)->next) - if ((grub_addr_t) ptr > (grub_addr_t) ((*r) + 1) - && (grub_addr_t) ptr <= (grub_addr_t) ((*r) + 1) + (*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_FREE_MAGIC) - grub_fatal ("double free at %p", *p); - if ((*p)->magic != GRUB_MM_ALLOC_MAGIC) - grub_fatal ("alloc magic is broken at %p: %lx", *p, - (unsigned long) (*p)->magic); -} - -/* 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; - - grub_dprintf ("regions", "Using memory for heap: start=%p, end=%p\n", - addr, (char *) addr + (unsigned int) size); - - /* Exclude last 4K to avoid overflows. */ - /* If addr + 0x1000 overflows then whole region is in excluded zone. */ - if ((grub_addr_t) addr > ~((grub_addr_t) 0x1000)) - return; - - /* If addr + 0x1000 + size overflows then decrease size. */ - if (((grub_addr_t) addr + 0x1000) > ~(grub_addr_t) size) - size = ((grub_addr_t) -0x1000) - (grub_addr_t) addr; - - /* Attempt to merge this region with every existing region */ - for (p = &grub_mm_base, q = *p; q; p = &(q->next), q = *p) - { - /* - * Is the new region immediately below an existing region? That - * is, is the address of the memory we're adding now (addr) + size - * of the memory we're adding (size) + the bytes we couldn't use - * at the start of the region we're considering (q->pre_size) - * equal to the address of q? In other words, does the memory - * looks like this? - * - * addr q - * |----size-----|-q->pre_size-|| - */ - grub_dprintf ("regions", "Can we extend into region above?" - " %p + %" PRIxGRUB_SIZE " + %" PRIxGRUB_SIZE " ?=? %p\n", - (grub_uint8_t *) addr, size, q->pre_size, (grub_uint8_t *) q); - if ((grub_uint8_t *) addr + size + q->pre_size == (grub_uint8_t *) q) - { - grub_dprintf ("regions", "Yes: extending a region: (%p -> %p) -> (%p -> %p)\n", - q, (grub_uint8_t *) q + sizeof (*q) + q->size, - addr, (grub_uint8_t *) q + sizeof (*q) + q->size); - /* - * Yes, we can merge the memory starting at addr into the - * existing region from below. Align up addr to GRUB_MM_ALIGN - * so that our new region has proper alignment. - */ - r = (grub_mm_region_t) ALIGN_UP ((grub_addr_t) addr, GRUB_MM_ALIGN); - /* Copy the region data across */ - *r = *q; - /* Consider all the new size as pre-size */ - r->pre_size += size; - - /* - * If we have enough pre-size to create a block, create a - * block with it. Mark it as allocated and pass it to - * grub_free (), which will sort out getting it into the free - * list. - */ - if (r->pre_size >> GRUB_MM_ALIGN_LOG2) - { - h = (grub_mm_header_t) (r + 1); - /* block size is pre-size converted to cells */ - h->size = (r->pre_size >> GRUB_MM_ALIGN_LOG2); - h->magic = GRUB_MM_ALLOC_MAGIC; - /* region size grows by block size converted back to bytes */ - r->size += h->size << GRUB_MM_ALIGN_LOG2; - /* adjust pre_size to be accurate */ - r->pre_size &= (GRUB_MM_ALIGN - 1); - *p = r; - grub_free (h + 1); - } - /* Replace the old region with the new region */ - *p = r; - return; - } - - /* - * Is the new region immediately above an existing region? That - * is: - * q addr - * ||-q->post_size-|----size-----| - */ - grub_dprintf ("regions", "Can we extend into region below?" - " %p + %x + %" PRIxGRUB_SIZE " + %" PRIxGRUB_SIZE " ?=? %p\n", - (grub_uint8_t *) q, (int) sizeof (*q), q->size, q->post_size, (grub_uint8_t *) addr); - if ((grub_uint8_t *) q + sizeof (*q) + q->size + q->post_size == - (grub_uint8_t *) addr) - { - grub_dprintf ("regions", "Yes: extending a region: (%p -> %p) -> (%p -> %p)\n", - q, (grub_uint8_t *) q + sizeof (*q) + q->size, - q, (grub_uint8_t *) addr + size); - /* - * Yes! Follow a similar pattern to above, but simpler. - * Our header starts at address - post_size, which should align us - * to a cell boundary. - * - * Cast to (void *) first to avoid the following build error: - * kern/mm.c: In function ‘grub_mm_init_region’: - * kern/mm.c:211:15: error: cast increases required alignment of target type [-Werror=cast-align] - * 211 | h = (grub_mm_header_t) ((grub_uint8_t *) addr - q->post_size); - * | ^ - * It is safe to do that because proper alignment is enforced in grub_mm_size_sanity_check(). - */ - h = (grub_mm_header_t)(void *) ((grub_uint8_t *) addr - q->post_size); - /* our size is the allocated size plus post_size, in cells */ - h->size = (size + q->post_size) >> GRUB_MM_ALIGN_LOG2; - h->magic = GRUB_MM_ALLOC_MAGIC; - /* region size grows by block size converted back to bytes */ - q->size += h->size << GRUB_MM_ALIGN_LOG2; - /* adjust new post_size to be accurate */ - q->post_size = (q->post_size + size) & (GRUB_MM_ALIGN - 1); - grub_free (h + 1); - return; - } - } - - grub_dprintf ("regions", "No: considering a new region at %p of size %" PRIxGRUB_SIZE "\n", - addr, size); - /* - * If you want to modify the code below, please also take a look at - * GRUB_MM_MGMT_OVERHEAD and make sure it is synchronized with the code. - */ - - /* Allocate a region from the head. */ - r = (grub_mm_region_t) ALIGN_UP ((grub_addr_t) addr, GRUB_MM_ALIGN); - - /* If this region is too small, ignore it. */ - if (size < GRUB_MM_ALIGN + (char *) r - (char *) addr + sizeof (*r)) - return; - - size -= (char *) r - (char *) addr + sizeof (*r); - - h = (grub_mm_header_t) (r + 1); - h->next = h; - h->magic = GRUB_MM_FREE_MAGIC; - h->size = (size >> GRUB_MM_ALIGN_LOG2); - - r->first = h; - r->pre_size = (grub_addr_t) r - (grub_addr_t) addr; - r->size = (h->size << GRUB_MM_ALIGN_LOG2); - r->post_size = size - r->size; - - /* Find where to insert this region. Put a smaller one before bigger ones, - to prevent fragmentation. */ - for (p = &grub_mm_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 given in *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. - * - * Note: because in certain circumstances we need to adjust the ->next - * pointer of the previous block, we iterate over the singly linked - * list with the pair (prev, cur). *FIRST is our initial previous, and - * *FIRST->next is our initial current pointer. So we will actually - * allocate from *FIRST->next first and *FIRST itself last. - */ -static void * -grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) -{ - grub_mm_header_t cur, prev; - - /* 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 (prev = *first, cur = prev->next; ; prev = cur, cur = cur->next) - { - grub_off_t extra; - - extra = ((grub_addr_t) (cur + 1) >> GRUB_MM_ALIGN_LOG2) & (align - 1); - if (extra) - extra = align - extra; - - if (! cur) - grub_fatal ("null in the ring"); - - if (cur->magic != GRUB_MM_FREE_MAGIC) - grub_fatal ("free magic is broken at %p: 0x%x", cur, cur->magic); - - if (cur->size >= n + extra) - { - extra += (cur->size - extra - n) & (~(align - 1)); - if (extra == 0 && cur->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 - */ - prev->next = cur->next; - } - else if (align == 1 || cur->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 - */ - cur->size -= n; - cur += cur->size; - } - else if (extra == 0) - { - grub_mm_header_t r; - - r = cur + extra + n; - r->magic = GRUB_MM_FREE_MAGIC; - r->size = cur->size - extra - n; - r->next = cur->next; - prev->next = r; - - if (prev == cur) - { - prev = 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 = cur + extra + n; - r->magic = GRUB_MM_FREE_MAGIC; - r->size = cur->size - extra - n; - r->next = cur; - - cur->size = extra; - prev->next = r; - cur += extra; - } - - cur->magic = GRUB_MM_ALLOC_MAGIC; - cur->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. */ - /* So do it only for chunks under 32K. */ - if (n < (0x8000 >> GRUB_MM_ALIGN_LOG2) - || *first == cur) - *first = prev; - - return cur + 1; - } - - /* Search was completed without result. */ - if (cur == *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; - grub_size_t grow; - int count = 0; - - if (!grub_mm_base) - goto fail; - - if (size > ~(grub_size_t) align) - goto fail; - - grow = size + align; - - /* We currently assume at least a 32-bit grub_size_t, - so limiting allocations to - 1MiB - in name of sanity is beneficial. */ - if (grow > ~(grub_size_t) 0x100000) - goto fail; - - align = (align >> GRUB_MM_ALIGN_LOG2); - if (align == 0) - align = 1; - - again: - - for (r = grub_mm_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: - /* Request additional pages, contiguous */ - count++; - - /* - * Calculate the necessary size of heap growth (if applicable), - * with region management overhead taken into account. - */ - if (grub_add (grow, GRUB_MM_MGMT_OVERHEAD, &grow)) - goto fail; - - /* Preallocate some extra space if heap growth is small. */ - grow = grub_max (grow, GRUB_MM_HEAP_GROW_EXTRA); - - /* Align up heap growth to make it friendly to CPU/MMU. */ - if (grow > ~(grub_size_t) (GRUB_MM_HEAP_GROW_ALIGN - 1)) - goto fail; - grow = ALIGN_UP (grow, GRUB_MM_HEAP_GROW_ALIGN); - - /* Do the same sanity check again. */ - if (grow > ~(grub_size_t) 0x100000) - goto fail; - - if (grub_mm_add_region_fn != NULL && - grub_mm_add_region_fn (grow, GRUB_MM_ADD_REGION_CONSECUTIVE) == GRUB_ERR_NONE) - goto again; - - /* fallthrough */ - - case 1: - /* Request additional pages, anything at all */ - count++; - - if (grub_mm_add_region_fn != NULL) - { - /* - * Try again even if this fails, in case it was able to partially - * satisfy the request - */ - grub_mm_add_region_fn (grow, GRUB_MM_ADD_REGION_NONE); - goto again; - } - - /* fallthrough */ - - case 2: - /* Invalidate disk caches. */ - grub_disk_cache_invalidate_all (); - count++; - goto again; - - default: - break; - } - - fail: - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - return 0; -} - -/* - * Allocate NMEMB instances of SIZE bytes and return the pointer, or error on - * integer overflow. - */ -void * -grub_calloc (grub_size_t nmemb, grub_size_t size) -{ - void *ret; - grub_size_t sz = 0; - - if (grub_mul (nmemb, size, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); - return NULL; - } - - ret = grub_memalign (0, sz); - if (!ret) - return NULL; - - grub_memset (ret, 0, sz); - return ret; -} - -/* 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 cur, prev; - -#if 0 - cur = r->first; - do - { - grub_printf ("%s:%d: q=%p, q->size=0x%x, q->magic=0x%x\n", - GRUB_FILE, __LINE__, cur, cur->size, cur->magic); - cur = cur->next; - } - while (cur != r->first); -#endif - /* Iterate over all blocks in the free ring. - * - * The free ring is arranged from high addresses to low - * addresses, modulo wraparound. - * - * We are looking for a block with a higher address than p or - * whose next address is lower than p. - */ - for (prev = r->first, cur = prev->next; cur <= p || cur->next >= p; - prev = cur, cur = prev->next) - { - if (cur->magic != GRUB_MM_FREE_MAGIC) - grub_fatal ("free magic is broken at %p: 0x%x", cur, cur->magic); - - /* Deal with wrap-around */ - if (cur <= cur->next && (cur > p || cur->next < p)) - break; - } - - /* mark p as free and insert it between cur and cur->next */ - p->magic = GRUB_MM_FREE_MAGIC; - p->next = cur->next; - cur->next = p; - - /* - * If the block we are freeing can be merged with the next - * free block, do that. - */ - if (p->next + p->next->size == p) - { - p->magic = 0; - - p->next->size += p->size; - cur->next = p->next; - p = p->next; - } - - r->first = cur; - - /* Likewise if can be merged with the preceeding free block */ - if (cur == p + p->size) - { - cur->magic = 0; - p->size += cur->size; - if (cur == prev) - prev = p; - prev->next = p; - cur = prev; - } - - /* - * Set r->first such that the just free()d block is tried first. - * (An allocation is tried from *first->next, and cur->next == p.) - */ - r->first = cur; - } -} - -/* 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; - - /* We've already checked that p->size < n. */ - grub_memcpy (q, ptr, p->size << GRUB_MM_ALIGN_LOG2); - 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 = grub_mm_base; r; r = r->next) - { - grub_mm_header_t p; - - grub_printf ("Region %p (size %" PRIuGRUB_SIZE ")\n\n", r, r->size); - - /* 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 = grub_mm_base; r; r = r->next) - { - grub_mm_header_t p; - - grub_printf ("Region %p (size %" PRIuGRUB_SIZE ")\n\n", r, r->size); - - for (p = (grub_mm_header_t) ALIGN_UP ((grub_addr_t) (r + 1), - GRUB_MM_ALIGN); - (grub_addr_t) p < (grub_addr_t) (r+1) + 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_calloc (const char *file, int line, grub_size_t nmemb, grub_size_t size) -{ - void *ptr; - - if (grub_mm_debug) - grub_printf ("%s:%d: calloc (0x%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE ") = ", - file, line, nmemb, size); - ptr = grub_calloc (nmemb, size); - if (grub_mm_debug) - grub_printf ("%p\n", ptr); - return ptr; -} - -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%" PRIxGRUB_SIZE ") = ", 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%" PRIxGRUB_SIZE ") = ", 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%" PRIxGRUB_SIZE ") = ", 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%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE - ") = ", 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 deleted file mode 100644 index 9b7b31a51..000000000 --- a/grub-core/kern/parser.c +++ /dev/null @@ -1,344 +0,0 @@ -/* parser.c - the part of the parser that can return partial tokens */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2007,2009,2021 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include - - -/* 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_VARNAME, GRUB_PARSER_STATE_TEXT, '\t', 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_QVARNAME, GRUB_PARSER_STATE_DQUOTE, '\t', 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 (grub_isspace (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; -} - - -/* Helper for grub_parser_split_cmdline. */ -static inline 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); -} - - -static grub_err_t -add_var (grub_buffer_t varname, grub_buffer_t buf, - grub_parser_state_t state, grub_parser_state_t newstate) -{ - const 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 GRUB_ERR_NONE; - - if (grub_buffer_append_char (varname, '\0') != GRUB_ERR_NONE) - return grub_errno; - - val = grub_env_get ((const char *) grub_buffer_peek_data (varname)); - grub_buffer_reset (varname); - if (!val) - return GRUB_ERR_NONE; - - /* Insert the contents of the variable in the buffer. */ - return grub_buffer_append_data (buf, val, grub_strlen (val)); -} - -static grub_err_t -terminate_arg (grub_buffer_t buffer, int *argc) -{ - grub_size_t unread = grub_buffer_get_unread_bytes (buffer); - - if (unread == 0) - return GRUB_ERR_NONE; - - if (*(const char *) grub_buffer_peek_data_at (buffer, unread - 1) == '\0') - return GRUB_ERR_NONE; - - if (grub_buffer_append_char (buffer, '\0') != GRUB_ERR_NONE) - return grub_errno; - - (*argc)++; - - return GRUB_ERR_NONE; -} - -static grub_err_t -process_char (char c, grub_buffer_t buffer, grub_buffer_t varname, - grub_parser_state_t state, int *argc, - grub_parser_state_t *newstate) -{ - char use; - - *newstate = grub_parser_cmdline_state (state, c, &use); - - /* - * If a variable was being processed and this character does - * not describe the variable anymore, write the variable to - * the buffer. - */ - if (add_var (varname, buffer, state, *newstate) != GRUB_ERR_NONE) - return grub_errno; - - if (check_varstate (*newstate)) - { - if (use) - return grub_buffer_append_char (varname, use); - } - else if (*newstate == GRUB_PARSER_STATE_TEXT && - state != GRUB_PARSER_STATE_ESC && grub_isspace (use)) - { - /* - * Don't add more than one argument if multiple - * spaces are used. - */ - return terminate_arg (buffer, argc); - } - else if (use) - return grub_buffer_append_char (buffer, use); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_parser_split_cmdline (const char *cmdline, - grub_reader_getline_t getline, void *getline_data, - int *argc, char ***argv) -{ - grub_parser_state_t state = GRUB_PARSER_STATE_TEXT; - grub_buffer_t buffer, varname; - char *rd = (char *) cmdline; - char *rp = rd; - int i; - - *argc = 0; - *argv = NULL; - - buffer = grub_buffer_new (1024); - if (buffer == NULL) - return grub_errno; - - varname = grub_buffer_new (200); - if (varname == NULL) - goto fail; - - do - { - if (rp == NULL || *rp == '\0') - { - if (rd != cmdline) - { - grub_free (rd); - rd = rp = NULL; - } - if (getline) - { - getline (&rd, 1, getline_data); - rp = rd; - } - else - break; - } - - if (!rd) - break; - - for (; *rp != '\0'; rp++) - { - grub_parser_state_t newstate; - - if (process_char (*rp, buffer, varname, state, argc, - &newstate) != GRUB_ERR_NONE) - goto fail; - - state = newstate; - } - } - while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state)); - - /* A special case for when the last character was part of a - variable. */ - if (add_var (varname, buffer, state, GRUB_PARSER_STATE_TEXT) != GRUB_ERR_NONE) - goto fail; - - /* Ensure that the last argument is terminated. */ - if (terminate_arg (buffer, argc) != GRUB_ERR_NONE) - goto fail; - - /* If there are no args, then we're done. */ - if (!*argc) - { - grub_errno = GRUB_ERR_NONE; - goto out; - } - - *argv = grub_calloc (*argc + 1, sizeof (char *)); - if (!*argv) - goto fail; - - /* The arguments are separated with 0's, setup argv so it points to - the right values. */ - for (i = 0; i < *argc; i++) - { - char *arg; - - if (i > 0) - { - if (grub_buffer_advance_read_pos (buffer, 1) != GRUB_ERR_NONE) - goto fail; - } - - arg = (char *) grub_buffer_peek_data (buffer); - if (arg == NULL || - grub_buffer_advance_read_pos (buffer, grub_strlen (arg)) != GRUB_ERR_NONE) - goto fail; - - (*argv)[i] = arg; - } - - /* Keep memory for the return values. */ - grub_buffer_take_data (buffer); - - grub_errno = GRUB_ERR_NONE; - - out: - if (rd != cmdline) - grub_free (rd); - grub_buffer_free (buffer); - grub_buffer_free (varname); - - return grub_errno; - - fail: - grub_free (*argv); - *argv = NULL; - *argc = 0; - goto out; -} - -/* Helper for grub_parser_execute. */ -static grub_err_t -grub_parser_execute_getline (char **line, int cont __attribute__ ((unused)), - void *data) -{ - char **source = data; - 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; -} - -grub_err_t -grub_parser_execute (char *source) -{ - while (source) - { - char *line; - - grub_parser_execute_getline (&line, 0, &source); - grub_rescue_parse_line (line, grub_parser_execute_getline, &source); - grub_free (line); - grub_print_error (); - } - - return grub_errno; -} diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c deleted file mode 100644 index 3b128e6d2..000000000 --- a/grub-core/kern/partition.c +++ /dev/null @@ -1,295 +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 . - */ - -#include -#include -#include -#include -#include - -#ifdef GRUB_UTIL -#include -#endif - -grub_partition_map_t grub_partition_map_list; - -#define MAX_RECURSION_DEPTH 32 -static unsigned int recursion_depth = 0; - -/* - * Checks that disk->partition contains part. This function assumes that the - * start of part is relative to the start of disk->partition. Returns 1 if - * disk->partition is null. - */ -static int -grub_partition_check_containment (const grub_disk_t disk, - const grub_partition_t part) -{ - if (disk->partition == NULL) - return 1; - - if (part->start + part->len > disk->partition->len) - { - char *partname; - - partname = grub_partition_get_name (disk->partition); - grub_dprintf ("partition", "sub-partition %s%d of (%s,%s) ends after parent.\n", - part->partmap->name, part->number + 1, disk->name, partname); -#ifdef GRUB_UTIL - grub_util_warn (_("Discarding improperly nested partition (%s,%s,%s%d)"), - disk->name, partname, part->partmap->name, part->number + 1); -#endif - grub_free (partname); - - return 0; - } - - return 1; -} - -/* Context for grub_partition_map_probe. */ -struct grub_partition_map_probe_ctx -{ - int partnum; - grub_partition_t p; -}; - -/* Helper for grub_partition_map_probe. */ -static int -probe_iter (grub_disk_t dsk, const grub_partition_t partition, void *data) -{ - struct grub_partition_map_probe_ctx *ctx = data; - - if (ctx->partnum != partition->number) - return 0; - - if (!(grub_partition_check_containment (dsk, partition))) - return 0; - - ctx->p = (grub_partition_t) grub_malloc (sizeof (*ctx->p)); - if (! ctx->p) - return 1; - - grub_memcpy (ctx->p, partition, sizeof (*ctx->p)); - return 1; -} - -static grub_partition_t -grub_partition_map_probe (const grub_partition_map_t partmap, - grub_disk_t disk, int partnum) -{ - struct grub_partition_map_probe_ctx ctx = { - .partnum = partnum, - .p = 0 - }; - - partmap->iterate (disk, probe_iter, &ctx); - if (grub_errno) - goto fail; - - return ctx.p; - - fail: - grub_free (ctx.p); - return 0; -} - -grub_partition_t -grub_partition_probe (struct grub_disk *disk, const char *str) -{ - grub_partition_t part; - grub_partition_t curpart = 0; - grub_partition_t tail; - const char *ptr; - - if (str == NULL) - return 0; - - part = tail = disk->partition; - - for (ptr = str; *ptr;) - { - grub_partition_map_t partmap; - unsigned long num; - const char *partname, *partname_end; - - partname = ptr; - while (*ptr && grub_isalpha (*ptr)) - ptr++; - partname_end = ptr; - - num = grub_strtoul (ptr, &ptr, 0); - if (num == 0 || num > GRUB_INT_MAX) - { - grub_error (GRUB_ERR_BAD_NUMBER, N_("invalid partition number")); - return 0; - } - - num -= 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; -} - -/* Context for grub_partition_iterate. */ -struct grub_partition_iterate_ctx -{ - int ret; - grub_partition_iterate_hook_t hook; - void *hook_data; -}; - -/* Helper for grub_partition_iterate. */ -static int -part_iterate (grub_disk_t dsk, const grub_partition_t partition, void *data) -{ - struct grub_partition_iterate_ctx *ctx = data; - struct grub_partition p = *partition; - - if (!(grub_partition_check_containment (dsk, partition))) - return 0; - - p.parent = dsk->partition; - dsk->partition = 0; - if (ctx->hook (dsk, &p, ctx->hook_data)) - { - ctx->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; - recursion_depth++; - if (recursion_depth <= MAX_RECURSION_DEPTH) - err = partmap->iterate (dsk, part_iterate, ctx); - else - err = grub_error (GRUB_ERR_RECURSION_DEPTH, "maximum recursion depth exceeded"); - recursion_depth--; - if (err) - grub_errno = GRUB_ERR_NONE; - if (ctx->ret) - break; - } - } - dsk->partition = p.parent; - return ctx->ret; -} - -int -grub_partition_iterate (struct grub_disk *disk, - grub_partition_iterate_hook_t hook, void *hook_data) -{ - struct grub_partition_iterate_ctx ctx = { - .ret = 0, - .hook = hook, - .hook_data = hook_data - }; - const struct grub_partition_map *partmap; - - FOR_PARTITION_MAPS(partmap) - { - grub_err_t err; - err = partmap->iterate (disk, part_iterate, &ctx); - if (err) - grub_errno = GRUB_ERR_NONE; - if (ctx.ret) - break; - } - - return ctx.ret; -} - -char * -grub_partition_get_name (const grub_partition_t partition) -{ - char *out = 0, *ptr; - grub_size_t needlen = 0; - grub_partition_t part; - if (!partition) - return grub_strdup (""); - for (part = partition; part; part = part->parent) - /* Even on 64-bit machines this buffer is enough to hold - longest number. */ - needlen += grub_strlen (part->partmap->name) + 1 + 27; - out = grub_malloc (needlen + 1); - if (!out) - return NULL; - - ptr = out + needlen; - *ptr = 0; - for (part = partition; part; part = part->parent) - { - char buf[27]; - grub_size_t len; - grub_snprintf (buf, sizeof (buf), "%d", part->number + 1); - len = grub_strlen (buf); - ptr -= len; - grub_memcpy (ptr, buf, len); - len = grub_strlen (part->partmap->name); - ptr -= len; - grub_memcpy (ptr, part->partmap->name, len); - *--ptr = ','; - } - grub_memmove (out, ptr + 1, out + needlen - ptr); - return out; -} diff --git a/grub-core/kern/powerpc/compiler-rt.S b/grub-core/kern/powerpc/compiler-rt.S deleted file mode 100644 index b3b912db6..000000000 --- a/grub-core/kern/powerpc/compiler-rt.S +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Special support for eabi and SVR4 - * - * Copyright (C) 1995-2014 Free Software Foundation, Inc. - * Written By Michael Meissner - * 64-bit support written by David Edelsohn - * - * This file is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 3, or (at your option) any - * later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * Under Section 7 of GPL version 3, you are granted additional - * permissions described in the GCC Runtime Library Exception, version - * 3.1, as published by the Free Software Foundation. - * - * You should have received a copy of the GNU General Public License and - * a copy of the GCC Runtime Library Exception along with this program; - * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - * . - */ - -/* Do any initializations needed for the eabi environment */ - -#include -#include - - .section ".text" - -#define CFI_RESTORE(reg) .cfi_restore reg -#define CFI_OFFSET(reg, off) .cfi_offset reg, off -#define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg -#define CFI_STARTPROC .cfi_startproc -#define CFI_ENDPROC .cfi_endproc - -/* Routines for restoring integer registers, called by the compiler. */ -/* Called with r11 pointing to the stack header word of the caller of the */ -/* function, just beyond the end of the integer restore area. */ - -CFI_STARTPROC -CFI_DEF_CFA_REGISTER (11) -CFI_OFFSET (65, 4) -CFI_OFFSET (14, -72) -CFI_OFFSET (15, -68) -CFI_OFFSET (16, -64) -CFI_OFFSET (17, -60) -CFI_OFFSET (18, -56) -CFI_OFFSET (19, -52) -CFI_OFFSET (20, -48) -CFI_OFFSET (21, -44) -CFI_OFFSET (22, -40) -CFI_OFFSET (23, -36) -CFI_OFFSET (24, -32) -CFI_OFFSET (25, -28) -CFI_OFFSET (26, -24) -CFI_OFFSET (27, -20) -CFI_OFFSET (28, -16) -CFI_OFFSET (29, -12) -CFI_OFFSET (30, -8) -CFI_OFFSET (31, -4) -FUNCTION(_restgpr_14_x) lwz 14,-72(11) /* restore gp registers */ -CFI_RESTORE (14) -FUNCTION(_restgpr_15_x) lwz 15,-68(11) -CFI_RESTORE (15) -FUNCTION(_restgpr_16_x) lwz 16,-64(11) -CFI_RESTORE (16) -FUNCTION(_restgpr_17_x) lwz 17,-60(11) -CFI_RESTORE (17) -FUNCTION(_restgpr_18_x) lwz 18,-56(11) -CFI_RESTORE (18) -FUNCTION(_restgpr_19_x) lwz 19,-52(11) -CFI_RESTORE (19) -FUNCTION(_restgpr_20_x) lwz 20,-48(11) -CFI_RESTORE (20) -FUNCTION(_restgpr_21_x) lwz 21,-44(11) -CFI_RESTORE (21) -FUNCTION(_restgpr_22_x) lwz 22,-40(11) -CFI_RESTORE (22) -FUNCTION(_restgpr_23_x) lwz 23,-36(11) -CFI_RESTORE (23) -FUNCTION(_restgpr_24_x) lwz 24,-32(11) -CFI_RESTORE (24) -FUNCTION(_restgpr_25_x) lwz 25,-28(11) -CFI_RESTORE (25) -FUNCTION(_restgpr_26_x) lwz 26,-24(11) -CFI_RESTORE (26) -FUNCTION(_restgpr_27_x) lwz 27,-20(11) -CFI_RESTORE (27) -FUNCTION(_restgpr_28_x) lwz 28,-16(11) -CFI_RESTORE (28) -FUNCTION(_restgpr_29_x) lwz 29,-12(11) -CFI_RESTORE (29) -FUNCTION(_restgpr_30_x) lwz 30,-8(11) -CFI_RESTORE (30) -FUNCTION(_restgpr_31_x) lwz 0,4(11) - lwz 31,-4(11) -CFI_RESTORE (31) - mtlr 0 -CFI_RESTORE (65) - mr 1,11 -CFI_DEF_CFA_REGISTER (1) - blr -CFI_ENDPROC - -CFI_STARTPROC -FUNCTION(_savegpr_14) stw 14,-72(11) /* save gp registers */ -FUNCTION(_savegpr_15) stw 15,-68(11) -FUNCTION(_savegpr_16) stw 16,-64(11) -FUNCTION(_savegpr_17) stw 17,-60(11) -FUNCTION(_savegpr_18) stw 18,-56(11) -FUNCTION(_savegpr_19) stw 19,-52(11) -FUNCTION(_savegpr_20) stw 20,-48(11) -FUNCTION(_savegpr_21) stw 21,-44(11) -FUNCTION(_savegpr_22) stw 22,-40(11) -FUNCTION(_savegpr_23) stw 23,-36(11) -FUNCTION(_savegpr_24) stw 24,-32(11) -FUNCTION(_savegpr_25) stw 25,-28(11) -FUNCTION(_savegpr_26) stw 26,-24(11) -FUNCTION(_savegpr_27) stw 27,-20(11) -FUNCTION(_savegpr_28) stw 28,-16(11) -FUNCTION(_savegpr_29) stw 29,-12(11) -FUNCTION(_savegpr_30) stw 30,-8(11) -FUNCTION(_savegpr_31) stw 31,-4(11) - blr -CFI_ENDPROC diff --git a/grub-core/kern/powerpc/dl.c b/grub-core/kern/powerpc/dl.c deleted file mode 100644 index 7b6418eab..000000000 --- a/grub-core/kern/powerpc/dl.c +++ /dev/null @@ -1,169 +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 . - */ - -#include -#include -#include -#include -#include - -/* 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, N_("invalid arch-dependent ELF magic")); - - return GRUB_ERR_NONE; -} - -/* For low-endian reverse lis and addr_high as well as ori and addr_low. */ -struct trampoline -{ - grub_uint32_t lis; - grub_uint32_t ori; - grub_uint32_t mtctr; - grub_uint32_t bctr; -}; - -static const struct trampoline trampoline_template = - { - 0x3d800000, - 0x618c0000, - 0x7d8903a6, - 0x4e800420, - }; - -#pragma GCC diagnostic ignored "-Wcast-align" - -grub_err_t -grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, - grub_size_t *got) -{ - const Elf_Ehdr *e = ehdr; - const Elf_Shdr *s; - unsigned i; - - *tramp = 0; - *got = 0; - - for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize)) - if (s->sh_type == SHT_RELA) - { - const Elf_Rela *rel, *max; - - for (rel = (const Elf_Rela *) ((const char *) e + s->sh_offset), - max = rel + s->sh_size / s->sh_entsize; - rel < max; - rel++) - if (ELF_R_TYPE (rel->r_info) == GRUB_ELF_R_PPC_REL24 - || ELF_R_TYPE (rel->r_info) == GRUB_ELF_R_PPC_PLTREL24) - (*tramp)++; - - } - - *tramp *= sizeof (struct trampoline); - - return GRUB_ERR_NONE; -} - -/* Relocate symbols. */ -grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - Elf_Shdr *s, grub_dl_segment_t seg) -{ - Elf_Rela *rel, *max; - - for (rel = (Elf_Rela *) ((char *) ehdr + s->sh_offset), - max = (Elf_Rela *) ((char *) rel + s->sh_size); - rel < max; - rel = (Elf_Rela *) ((char *) rel + s->sh_entsize)) - { - 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 - + mod->symsize * 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 GRUB_ELF_R_PPC_ADDR16_LO: - *(Elf_Half *) addr = value; - break; - - case GRUB_ELF_R_PPC_PLTREL24: - case GRUB_ELF_R_PPC_REL24: - { - Elf_Sword delta = value - (Elf_Word) addr; - - if (delta << 6 >> 6 != delta) - { - struct trampoline *tptr = mod->trampptr; - grub_memcpy (tptr, &trampoline_template, - sizeof (*tptr)); - delta = (grub_uint8_t *) tptr - (grub_uint8_t *) addr; - tptr->lis |= (((value) >> 16) & 0xffff); - tptr->ori |= ((value) & 0xffff); - mod->trampptr = tptr + 1; - } - - if (delta << 6 >> 6 != delta) - return grub_error (GRUB_ERR_BAD_MODULE, - "relocation overflow"); - *addr = (*addr & 0xfc000003) | (delta & 0x3fffffc); - break; - } - - case GRUB_ELF_R_PPC_ADDR16_HA: - *(Elf_Half *) addr = (value + 0x8000) >> 16; - break; - - case GRUB_ELF_R_PPC_ADDR32: - *addr = value; - break; - - case GRUB_ELF_R_PPC_REL32: - *addr = value - (Elf_Word) addr; - break; - - default: - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - ELF_R_TYPE (rel->r_info)); - } - } - - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/riscv/cache.c b/grub-core/kern/riscv/cache.c deleted file mode 100644 index 47777a033..000000000 --- a/grub-core/kern/riscv/cache.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -static grub_int64_t dlinesz; -static grub_int64_t ilinesz; - -/* Prototypes for asm functions. */ -void grub_arch_clean_dcache_range (grub_addr_t beg, grub_addr_t end, - grub_size_t line_size); -void grub_arch_invalidate_icache_range (grub_addr_t beg, grub_addr_t end, - grub_size_t line_size); - -static void -probe_caches (void) -{ - /* TODO */ - dlinesz = 32; - ilinesz = 32; -} - -void -grub_arch_sync_caches (void *address, grub_size_t len) -{ - grub_size_t start, end, max_align; - - if (dlinesz == 0) - probe_caches(); - if (dlinesz == 0) - grub_fatal ("Unknown cache line size!"); - - max_align = dlinesz > ilinesz ? dlinesz : ilinesz; - - start = ALIGN_DOWN ((grub_size_t) address, max_align); - end = ALIGN_UP ((grub_size_t) address + len, max_align); - - grub_arch_clean_dcache_range (start, end, dlinesz); - grub_arch_invalidate_icache_range (start, end, ilinesz); -} - -void -grub_arch_sync_dma_caches (volatile void *address __attribute__((unused)), - grub_size_t len __attribute__((unused))) -{ - /* DMA incoherent devices not supported yet */ -} diff --git a/grub-core/kern/riscv/dl.c b/grub-core/kern/riscv/dl.c deleted file mode 100644 index 896653bb4..000000000 --- a/grub-core/kern/riscv/dl.c +++ /dev/null @@ -1,346 +0,0 @@ -/* dl.c - arch-dependent part of loadable module support */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -/* - * Instructions and instruction encoding are documented in the RISC-V - * specification. This file is based on version 2.2: - * - * https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-spec-v2.2.pdf - */ -#define LDR 0x58000050 -#define BR 0xd61f0200 - -/* - * 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_DATA] != ELFDATA2LSB || e->e_machine != EM_RISCV) - return grub_error (GRUB_ERR_BAD_OS, - N_("invalid arch-dependent ELF magic")); - - return GRUB_ERR_NONE; -} - -#pragma GCC diagnostic ignored "-Wcast-align" - -/* Relocate symbols. */ -grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - Elf_Shdr *s, grub_dl_segment_t seg) -{ - Elf_Rel *rel, *max; - - for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset), - max = (Elf_Rel *) ((char *) rel + s->sh_size); - rel < max; - rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) - { - Elf_Sym *sym; - void *place; - grub_size_t sym_addr; - - if (rel->r_offset >= seg->size) - return grub_error (GRUB_ERR_BAD_MODULE, - "reloc offset is out of the segment"); - - sym = (Elf_Sym *) ((char *) mod->symtab - + mod->symsize * ELF_R_SYM (rel->r_info)); - - sym_addr = sym->st_value; - if (s->sh_type == SHT_RELA) - sym_addr += ((Elf_Rela *) rel)->r_addend; - - place = (void *) ((grub_addr_t) seg->addr + rel->r_offset); - - switch (ELF_R_TYPE (rel->r_info)) - { - case R_RISCV_32: - { - grub_uint32_t *abs_place = place; - - grub_dprintf ("dl", " reloc_abs32 %p => 0x%016llx\n", - place, (unsigned long long) sym_addr); - - *abs_place = (grub_uint32_t) sym_addr; - } - break; - case R_RISCV_64: - { - grub_size_t *abs_place = place; - - grub_dprintf ("dl", " reloc_abs64 %p => 0x%016llx\n", - place, (unsigned long long) sym_addr); - - *abs_place = (grub_size_t) sym_addr; - } - break; - - case R_RISCV_ADD8: - { - grub_uint8_t *abs_place = place; - - *abs_place += (grub_uint8_t) sym_addr; - } - break; - case R_RISCV_ADD16: - { - grub_uint16_t *abs_place = place; - - *abs_place += (grub_uint16_t) sym_addr; - } - break; - case R_RISCV_ADD32: - { - grub_uint32_t *abs_place = place; - - *abs_place += (grub_uint32_t) sym_addr; - } - break; - case R_RISCV_ADD64: - { - grub_size_t *abs_place = place; - - *abs_place += (grub_size_t) sym_addr; - } - break; - - case R_RISCV_SUB8: - { - grub_uint8_t *abs_place = place; - - *abs_place -= (grub_uint8_t) sym_addr; - } - break; - case R_RISCV_SUB16: - { - grub_uint16_t *abs_place = place; - - *abs_place -= (grub_uint16_t) sym_addr; - } - break; - case R_RISCV_SUB32: - { - grub_uint32_t *abs_place = place; - - *abs_place -= (grub_uint32_t) sym_addr; - } - break; - case R_RISCV_SUB64: - { - grub_size_t *abs_place = place; - - *abs_place -= (grub_size_t) sym_addr; - } - break; - - case R_RISCV_BRANCH: - { - grub_uint32_t *abs_place = place; - grub_ssize_t off = sym_addr - (grub_addr_t) place; - grub_uint32_t imm12 = (off & 0x1000) << (31 - 12); - grub_uint32_t imm11 = (off & 0x800) >> (11 - 7); - grub_uint32_t imm10_5 = (off & 0x7e0) << (30 - 10); - grub_uint32_t imm4_1 = (off & 0x1e) << (11 - 4); - *abs_place = (*abs_place & 0x1fff07f) - | imm12 | imm11 | imm10_5 | imm4_1; - } - break; - - case R_RISCV_JAL: - { - grub_uint32_t *abs_place = place; - grub_ssize_t off = sym_addr - (grub_addr_t) place; - grub_uint32_t imm20 = (off & 0x100000) << (31 - 20); - grub_uint32_t imm19_12 = (off & 0xff000); - grub_uint32_t imm11 = (off & 0x800) << (20 - 11); - grub_uint32_t imm10_1 = (off & 0x7fe) << (30 - 10); - *abs_place = (*abs_place & 0xfff) - | imm20 | imm19_12 | imm11 | imm10_1; - } - break; - - case R_RISCV_CALL: - case R_RISCV_CALL_PLT: - { - grub_uint32_t *abs_place = place; - grub_ssize_t off = sym_addr - (grub_addr_t) place; - grub_uint32_t hi20, lo12; - - if (off != (grub_int32_t) off) - return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow"); - - hi20 = (off + 0x800) & 0xfffff000; - lo12 = (off - hi20) & 0xfff; - abs_place[0] = (abs_place[0] & 0xfff) | hi20; - abs_place[1] = (abs_place[1] & 0xfffff) | (lo12 << 20); - } - break; - - case R_RISCV_RVC_BRANCH: - { - grub_uint16_t *abs_place = place; - grub_ssize_t off = sym_addr - (grub_addr_t) place; - grub_uint16_t imm8 = (off & 0x100) << (12 - 8); - grub_uint16_t imm7_6 = (off & 0xc0) >> (6 - 5); - grub_uint16_t imm5 = (off & 0x20) >> (5 - 2); - grub_uint16_t imm4_3 = (off & 0x18) << (12 - 5); - grub_uint16_t imm2_1 = (off & 0x6) << (12 - 10); - *abs_place = (*abs_place & 0xe383) - | imm8 | imm7_6 | imm5 | imm4_3 | imm2_1; - } - break; - - case R_RISCV_RVC_JUMP: - { - grub_uint16_t *abs_place = place; - grub_ssize_t off = sym_addr - (grub_addr_t) place; - grub_uint16_t imm11 = (off & 0x800) << (12 - 11); - grub_uint16_t imm10 = (off & 0x400) >> (10 - 8); - grub_uint16_t imm9_8 = (off & 0x300) << (12 - 11); - grub_uint16_t imm7 = (off & 0x80) >> (7 - 6); - grub_uint16_t imm6 = (off & 0x40) << (12 - 11); - grub_uint16_t imm5 = (off & 0x20) >> (5 - 2); - grub_uint16_t imm4 = (off & 0x10) << (12 - 5); - grub_uint16_t imm3_1 = (off & 0xe) << (12 - 10); - *abs_place = ((*abs_place & 0xe003) - | imm11 | imm10 | imm9_8 | imm7 | imm6 - | imm5 | imm4 | imm3_1); - } - break; - - case R_RISCV_PCREL_HI20: - { - grub_uint32_t *abs_place = place; - grub_ssize_t off = sym_addr - (grub_addr_t) place; - grub_int32_t hi20; - - if (off != (grub_int32_t)off) - return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow"); - - hi20 = (off + 0x800) & 0xfffff000; - *abs_place = (*abs_place & 0xfff) | hi20; - } - break; - - case R_RISCV_PCREL_LO12_I: - case R_RISCV_PCREL_LO12_S: - { - grub_uint32_t *t32 = place; - Elf_Rela *rel2; - /* Search backwards for matching HI20 reloc. */ - for (rel2 = (Elf_Rela *) ((char *) rel - s->sh_entsize); - (unsigned long)rel2 >= ((unsigned long)ehdr + s->sh_offset); - rel2 = (Elf_Rela *) ((char *) rel2 - s->sh_entsize)) - { - Elf_Addr rel2_info; - Elf_Addr rel2_offset; - Elf_Addr rel2_sym_addr; - Elf_Addr rel2_loc; - grub_ssize_t rel2_off; - grub_ssize_t off; - Elf_Sym *sym2; - - rel2_offset = rel2->r_offset; - rel2_info = rel2->r_info; - rel2_loc = (grub_addr_t) seg->addr + rel2_offset; - - if (ELF_R_TYPE (rel2_info) == R_RISCV_PCREL_HI20 - && rel2_loc == sym_addr) - { - sym2 = (Elf_Sym *) ((char *) mod->symtab - + mod->symsize * ELF_R_SYM (rel2->r_info)); - rel2_sym_addr = sym2->st_value; - if (s->sh_type == SHT_RELA) - rel2_sym_addr += ((Elf_Rela *) rel2)->r_addend; - - rel2_off = rel2_sym_addr - rel2_loc; - off = rel2_off - ((rel2_off + 0x800) & 0xfffff000); - - if (ELF_R_TYPE (rel->r_info) == R_RISCV_PCREL_LO12_I) - *t32 = (*t32 & 0xfffff) | (off & 0xfff) << 20; - else - { - grub_uint32_t imm11_5 = (off & 0xfe0) << (31 - 11); - grub_uint32_t imm4_0 = (off & 0x1f) << (11 - 4); - *t32 = (*t32 & 0x1fff07f) | imm11_5 | imm4_0; - } - break; - } - } - if ((unsigned long)rel2 < ((unsigned long)ehdr + s->sh_offset)) - return grub_error (GRUB_ERR_BAD_MODULE, "cannot find matching HI20 relocation"); - } - break; - - case R_RISCV_HI20: - { - grub_uint32_t *abs_place = place; - *abs_place = (*abs_place & 0xfff) | - (((grub_int32_t) sym_addr + 0x800) & 0xfffff000); - } - break; - - case R_RISCV_LO12_I: - { - grub_uint32_t *abs_place = place; - grub_int32_t lo12 = (grub_int32_t) sym_addr - - (((grub_int32_t) sym_addr + 0x800) & 0xfffff000); - *abs_place = (*abs_place & 0xfffff) | ((lo12 & 0xfff) << 20); - } - break; - - case R_RISCV_LO12_S: - { - grub_uint32_t *abs_place = place; - grub_int32_t lo12 = (grub_int32_t) sym_addr - - (((grub_int32_t) sym_addr + 0x800) & 0xfffff000); - grub_uint32_t imm11_5 = (lo12 & 0xfe0) << (31 - 11); - grub_uint32_t imm4_0 = (lo12 & 0x1f) << (11 - 4); - *abs_place = (*abs_place & 0x1fff07f) | imm11_5 | imm4_0; - } - break; - - case R_RISCV_RELAX: - break; - default: - { - char rel_info[17]; /* log16(2^64) = 16, plus NUL. */ - - grub_snprintf (rel_info, sizeof (rel_info) - 1, "%" PRIxGRUB_UINT64_T, - (grub_uint64_t) ELF_R_TYPE (rel->r_info)); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%s is not implemented yet"), rel_info); - } - } - } - - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/riscv/efi/init.c b/grub-core/kern/riscv/efi/init.c deleted file mode 100644 index 0d7de4f54..000000000 --- a/grub-core/kern/riscv/efi/init.c +++ /dev/null @@ -1,78 +0,0 @@ -/* init.c - initialize a riscv-based EFI system */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -static grub_uint64_t timer_frequency_in_khz; - -static grub_uint64_t -grub_efi_get_time_ms (void) -{ - grub_uint64_t tmr; - -#if __riscv_xlen == 64 - asm volatile ("rdtime %0" : "=r"(tmr)); -#else - grub_uint32_t lo, hi, tmp; - asm volatile ("1:\n" - "rdtimeh %0\n" - "rdtime %1\n" - "rdtimeh %2\n" - "bne %0, %2, 1b" - : "=&r" (hi), "=&r" (lo), "=&r" (tmp)); - tmr = ((grub_uint64_t)hi << 32) | lo; -#endif - - return tmr / timer_frequency_in_khz; -} - -void -grub_machine_init (void) -{ - grub_uint64_t time_before, time_after; - - grub_efi_init (); - - /* Calculate timer frequency */ - timer_frequency_in_khz = 1; - time_before = grub_efi_get_time_ms(); - grub_efi_stall(1000); - time_after = grub_efi_get_time_ms(); - timer_frequency_in_khz = time_after - time_before; - - grub_install_get_time_ms (grub_efi_get_time_ms); -} - -void -grub_machine_fini (int flags) -{ - if (!(flags & GRUB_LOADER_FLAG_NORETURN)) - return; - - grub_efi_fini (); - - if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) - grub_efi_memory_fini (); -} diff --git a/grub-core/kern/riscv/efi/startup.S b/grub-core/kern/riscv/efi/startup.S deleted file mode 100644 index f2a7b2b1e..000000000 --- a/grub-core/kern/riscv/efi/startup.S +++ /dev/null @@ -1,48 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#if __riscv_xlen == 64 -#define sl sd -#define ll ld -#else -#define sl sw -#define ll lw -#endif - - - .file "startup.S" - .text -FUNCTION(_start) - /* - * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in a1/a0. - */ - - ll a2, efi_image_handle_val - sl a0, 0(a2) - ll a2, efi_system_table_val - sl a1, 0(a2) - ll a2, grub_main_val - jr a2 -grub_main_val: - .quad EXT_C(grub_main) -efi_system_table_val: - .quad EXT_C(grub_efi_system_table) -efi_image_handle_val: - .quad EXT_C(grub_efi_image_handle) diff --git a/grub-core/kern/sparc64/dl.c b/grub-core/kern/sparc64/dl.c deleted file mode 100644 index f3d960186..000000000 --- a/grub-core/kern/sparc64/dl.c +++ /dev/null @@ -1,191 +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 . - */ - -#include -#include -#include -#include -#include - -/* 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, N_("invalid arch-dependent ELF magic")); - - return GRUB_ERR_NONE; -} - -#pragma GCC diagnostic ignored "-Wcast-align" - -struct trampoline -{ - grub_uint8_t code[0x28]; - grub_uint64_t addr; -}; - -static const grub_uint8_t trampoline_code[0x28] = -{ - /* 0: */ 0x82, 0x10, 0x00, 0x0f, /* mov %o7, %g1 */ - /* 4: */ 0x40, 0x00, 0x00, 0x02, /* call 0xc */ - /* 8: */ 0x01, 0x00, 0x00, 0x00, /* nop */ - /* c: */ 0x9e, 0x1b, 0xc0, 0x01, /* xor %o7, %g1, %o7 */ - /* 10: */ 0x82, 0x18, 0x40, 0x0f, /* xor %g1, %o7, %g1 */ - /* 14: */ 0x9e, 0x1b, 0xc0, 0x01, /* xor %o7, %g1, %o7 */ - /* 18: */ 0xc2, 0x58, 0x60, 0x24, /* ldx [ %g1 + 0x24 ], %g1 */ - /* 1c: */ 0x81, 0xc0, 0x40, 0x00, /* jmp %g1 */ - /* 20: */ 0x01, 0x00, 0x00, 0x00, /* nop */ - /* 24: */ 0x01, 0x00, 0x00, 0x00, /* nop */ -}; - -grub_err_t -grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, - grub_size_t *got) -{ - const Elf_Ehdr *e = ehdr; - const Elf_Shdr *s; - unsigned i; - - *tramp = 0; - *got = 0; - - for (i = 0, s = (const Elf_Shdr *) ((grub_addr_t) e + e->e_shoff); - i < e->e_shnum; - i++, s = (const Elf_Shdr *) ((grub_addr_t) s + e->e_shentsize)) - if (s->sh_type == SHT_REL || s->sh_type == SHT_RELA) - { - const Elf_Rel *rel, *max; - - for (rel = (const Elf_Rel *) ((grub_addr_t) e + s->sh_offset), - max = rel + s->sh_size / s->sh_entsize; - rel < max; - rel = (const Elf_Rel *) ((grub_addr_t) rel + s->sh_entsize)) - switch (ELF_R_TYPE (rel->r_info)) - { - case R_SPARC_WDISP30: - { - *tramp += sizeof (struct trampoline); - break; - } - } - } - - return GRUB_ERR_NONE; -} - -/* Relocate symbols. */ -grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - Elf_Shdr *s, grub_dl_segment_t seg) -{ - Elf_Rela *rel, *max; - - for (rel = (Elf_Rela *) ((char *) ehdr + s->sh_offset), - max = (Elf_Rela *) ((char *) rel + s->sh_size); - rel < max; - rel = (Elf_Rela *) ((char *) rel + s->sh_entsize)) - { - 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 - + mod->symsize * 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)) - { - struct trampoline *tp = mod->trampptr; - mod->trampptr = tp + 1; - grub_memcpy (tp->code, trampoline_code, sizeof (tp->code)); - tp->addr = value; - value = (Elf_Addr) tp; - } - - 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_HH22: /* 9 V-imm22 */ - *addr = (*addr & 0xFFC00000) | ((value >> 42) & 0x3FFFFF); - break; - case R_SPARC_HM10: /* 12 T-simm13 */ - *addr = (*addr & 0xFFFFFC00) | ((value >> 32) & 0x3FF); - break; - case R_SPARC_HI22: /* 9 V-imm22 */ - if (value >> 32) - return grub_error (GRUB_ERR_BAD_MODULE, - "address out of 32 bits range"); - /* Fallthrough. */ - case R_SPARC_LM22: - *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: - { - char rel_info[17]; /* log16(2^64) = 16, plus NUL. */ - - grub_snprintf (rel_info, sizeof (rel_info) - 1, "%" PRIxGRUB_UINT64_T, - ELF_R_TYPE (rel->r_info)); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%s is not implemented yet"), rel_info); - } - } - } - - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/term.c b/grub-core/kern/term.c deleted file mode 100644 index 14d596498..000000000 --- a/grub-core/kern/term.c +++ /dev/null @@ -1,169 +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 . - */ - -#include -#include -#include -#include -#include -#include - -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; - -/* Current color state. */ -grub_uint8_t grub_term_normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR; -grub_uint8_t grub_term_highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR; - -void (*grub_term_poll_usb) (int wait_for_completion) = NULL; -void (*grub_net_poll_cards_idle) (void) = NULL; - -/* Put a Unicode character. */ -static void -grub_putcode_dumb (grub_uint32_t code, - struct grub_term_output *term) -{ - struct grub_unicode_glyph c = - { - .base = code, - .variant = 0, - .attributes = 0, - .ncomb = 0, - .estimated_width = 1 - }; - - if (code == '\t' && term->getxy) - { - int n; - - n = GRUB_TERM_TAB_WIDTH - ((term->getxy (term).x) - % GRUB_TERM_TAB_WIDTH); - while (n--) - grub_putcode_dumb (' ', term); - - return; - } - - (term->putchar) (term, &c); - if (code == '\n') - grub_putcode_dumb ('\r', term); -} - -static void -grub_xputs_dumb (const char *str) -{ - for (; *str; str++) - { - grub_term_output_t term; - grub_uint32_t code = *str; - if (code > 0x7f) - code = '?'; - - FOR_ACTIVE_TERM_OUTPUTS(term) - grub_putcode_dumb (code, term); - } -} - -void (*grub_xputs) (const char *str) = grub_xputs_dumb; - -int -grub_getkey_noblock (void) -{ - grub_term_input_t term; - - if (grub_term_poll_usb) - grub_term_poll_usb (0); - - if (grub_net_poll_cards_idle) - grub_net_poll_cards_idle (); - - FOR_ACTIVE_TERM_INPUTS(term) - { - int key = term->getkey (term); - if (key != GRUB_TERM_NO_KEY) - return key; - } - - return GRUB_TERM_NO_KEY; -} - -int -grub_getkey (void) -{ - int ret; - - grub_refresh (); - - while (1) - { - ret = grub_getkey_noblock (); - if (ret != GRUB_TERM_NO_KEY) - return ret; - grub_cpu_idle (); - } -} - -int -grub_getkeystatus (void) -{ - int status = 0; - grub_term_input_t term; - - if (grub_term_poll_usb) - grub_term_poll_usb (0); - - FOR_ACTIVE_TERM_INPUTS(term) - { - if (term->getkeystatus) - status |= term->getkeystatus (term); - } - - return status; -} - -int -grub_key_is_interrupt (int key) -{ - /* - * ESC sometimes is the BIOS setup hotkey and may be hard to discover, also - * check F4, which was chosen because is not used as a hotkey to enter the - * BIOS setup by any vendor. - */ - if (key == GRUB_TERM_ESC || key == GRUB_TERM_KEY_F4) - return 1; - - /* - * Pressing keys at the right time during boot is hard to time, also allow - * interrupting sleeps / the menu countdown by keeping shift pressed. - */ - if (grub_getkeystatus() & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT)) - return 1; - - return 0; -} - -void -grub_refresh (void) -{ - struct grub_term_output *term; - - FOR_ACTIVE_TERM_OUTPUTS(term) - grub_term_refresh (term); -} diff --git a/grub-core/kern/uboot/hw.c b/grub-core/kern/uboot/hw.c deleted file mode 100644 index 272b83bd7..000000000 --- a/grub-core/kern/uboot/hw.c +++ /dev/null @@ -1,112 +0,0 @@ -/* hw.c - U-Boot hardware discovery */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -grub_addr_t start_of_ram; - -/* - * grub_uboot_probe_memory(): - * Queries U-Boot for available memory regions. - * - * Sets up heap near the image in memory and sets up "start_of_ram". - */ -void -grub_uboot_mm_init (void) -{ - struct sys_info *si = grub_uboot_get_sys_info (); - - grub_mm_init_region ((void *) grub_modules_get_end (), - GRUB_KERNEL_MACHINE_HEAP_SIZE); - - if (si && (si->mr_no != 0)) - { - int i; - start_of_ram = GRUB_UINT_MAX; - - for (i = 0; i < si->mr_no; i++) - if ((si->mr[i].flags & MR_ATTR_MASK) == MR_ATTR_DRAM) - if (si->mr[i].start < start_of_ram) - start_of_ram = si->mr[i].start; - } -} - -/* - * grub_uboot_probe_hardware(): - */ -grub_err_t -grub_uboot_probe_hardware (void) -{ - int devcount, i; - - devcount = grub_uboot_dev_enum (); - grub_dprintf ("init", "%d devices found\n", devcount); - - for (i = 0; i < devcount; i++) - { - struct device_info *devinfo = grub_uboot_dev_get (i); - - grub_dprintf ("init", "device handle: %d\n", i); - grub_dprintf ("init", " cookie\t= 0x%08x\n", - (grub_uint32_t) devinfo->cookie); - - if (devinfo->type & DEV_TYP_STOR) - { - grub_dprintf ("init", " type\t\t= DISK\n"); - grub_ubootdisk_register (devinfo); - } - else if (devinfo->type & DEV_TYP_NET) - { - /* Dealt with in ubootnet module. */ - grub_dprintf ("init", " type\t\t= NET (not supported yet)\n"); - } - else - { - grub_dprintf ("init", "%s: unknown device type", __FUNCTION__); - } - } - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) -{ - int i; - struct sys_info *si = grub_uboot_get_sys_info (); - - if (!si || (si->mr_no < 1)) - return GRUB_ERR_BUG; - - /* Iterate and call `hook'. */ - for (i = 0; i < si->mr_no; i++) - if ((si->mr[i].flags & MR_ATTR_MASK) == MR_ATTR_DRAM) - hook (si->mr[i].start, si->mr[i].size, GRUB_MEMORY_AVAILABLE, - hook_data); - - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/uboot/init.c b/grub-core/kern/uboot/init.c deleted file mode 100644 index 3e338645c..000000000 --- a/grub-core/kern/uboot/init.c +++ /dev/null @@ -1,172 +0,0 @@ -/* init.c - generic U-Boot initialization and finalization */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern char __bss_start[]; -extern char _end[]; -extern grub_size_t grub_total_module_size; -static unsigned long timer_start; - -void -grub_exit (void) -{ - grub_uboot_return (0); -} - -static grub_uint64_t -uboot_timer_ms (void) -{ - static grub_uint32_t last = 0, high = 0; - grub_uint32_t cur = grub_uboot_get_timer (timer_start); - if (cur < last) - high++; - last = cur; - return (((grub_uint64_t) high) << 32) | cur; -} - -#ifdef __arm__ -static grub_uint64_t -rpi_timer_ms (void) -{ - static grub_uint32_t last = 0, high = 0; - grub_uint32_t cur = *(volatile grub_uint32_t *) 0x20003004; - if (cur < last) - high++; - last = cur; - return grub_divmod64 ((((grub_uint64_t) high) << 32) | cur, 1000, 0); -} -#endif - -void -grub_machine_init (void) -{ - int ver; - - /* First of all - establish connection with U-Boot */ - ver = grub_uboot_api_init (); - if (!ver) - { - /* Don't even have a console to log errors to... */ - grub_exit (); - } - else if (ver > API_SIG_VERSION) - { - /* Try to print an error message */ - grub_uboot_puts ("invalid U-Boot API version\n"); - } - - /* Initialize the console so that GRUB can display messages. */ - grub_console_init_early (); - - /* Enumerate memory and initialize the memory management system. */ - grub_uboot_mm_init (); - - /* Should be earlier but it needs memalign. */ -#ifdef __arm__ - grub_arm_enable_caches_mmu (); -#endif - - grub_dprintf ("init", "__bss_start: %p\n", __bss_start); - grub_dprintf ("init", "_end: %p\n", _end); - grub_dprintf ("init", "grub_modbase: %p\n", (void *) grub_modbase); - grub_dprintf ("init", "grub_modules_get_end(): %p\n", - (void *) grub_modules_get_end ()); - - /* Initialise full terminfo support */ - grub_console_init_lately (); - - /* Enumerate uboot devices */ - grub_uboot_probe_hardware (); - - /* Initialise timer */ -#ifdef __arm__ - if (grub_uboot_get_machine_type () == GRUB_ARM_MACHINE_TYPE_RASPBERRY_PI) - { - grub_install_get_time_ms (rpi_timer_ms); - } - else -#endif - { - timer_start = grub_uboot_get_timer (0); - grub_install_get_time_ms (uboot_timer_ms); - } - - /* Initialize */ - grub_ubootdisk_init (); -} - - -void -grub_machine_fini (int flags __attribute__ ((unused))) -{ -} - -/* - * grub_machine_get_bootlocation(): - * Called from kern/main.c, which expects a device name (minus parentheses) - * and a filesystem path back, if any are known. - * Any returned values must be pointers to dynamically allocated strings. - */ -void -grub_machine_get_bootlocation (char **device, char **path) -{ - char *tmp; - - tmp = grub_uboot_env_get ("grub_bootdev"); - if (tmp) - { - *device = grub_strdup (tmp); - if (*device == NULL) - return; - } - else - *device = NULL; - - tmp = grub_uboot_env_get ("grub_bootpath"); - if (tmp) - { - *path = grub_strdup (tmp); - if (*path == NULL) - return; - } - else - *path = NULL; -} - -void -grub_uboot_fini (void) -{ - grub_ubootdisk_fini (); - grub_console_fini (); -} diff --git a/grub-core/kern/uboot/uboot.c b/grub-core/kern/uboot/uboot.c deleted file mode 100644 index aac8f9ae1..000000000 --- a/grub-core/kern/uboot/uboot.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -/* - * The main syscall entry point is not reentrant, only one call is - * serviced until finished. - * - * int syscall(int call, int *retval, ...) - * e.g. syscall(1, int *, u_int32_t, u_int32_t, u_int32_t, u_int32_t); - * - * call: syscall number - * - * retval: points to the return value placeholder, this is the place the - * syscall puts its return value, if NULL the caller does not - * expect a return value - * - * ... syscall arguments (variable number) - * - * returns: 0 if the call not found, 1 if serviced - */ - -extern int grub_uboot_syscall (int, int *, ...); - -static struct sys_info uboot_sys_info; -static struct mem_region uboot_mem_info[5]; -static struct device_info * devices; -static int num_devices; - - -/* - * All functions below are wrappers around the grub_uboot_syscall() function - */ - -int -grub_uboot_getc (void) -{ - int c; - if (!grub_uboot_syscall (API_GETC, NULL, &c)) - return -1; - - return c; -} - -int -grub_uboot_tstc (void) -{ - int c; - if (!grub_uboot_syscall (API_TSTC, NULL, &c)) - return -1; - - return c; -} - -void -grub_uboot_putc (int c) -{ - grub_uboot_syscall (API_PUTC, NULL, &c); -} - -void -grub_uboot_puts (const char *s) -{ - grub_uboot_syscall (API_PUTS, NULL, s); -} - -void -grub_uboot_reset (void) -{ - grub_uboot_syscall (API_RESET, NULL, 0); -} - -struct sys_info * -grub_uboot_get_sys_info (void) -{ - int retval; - - grub_memset (&uboot_sys_info, 0, sizeof (uboot_sys_info)); - grub_memset (&uboot_mem_info, 0, sizeof (uboot_mem_info)); - uboot_sys_info.mr = uboot_mem_info; - uboot_sys_info.mr_no = sizeof (uboot_mem_info) / sizeof (struct mem_region); - - if (grub_uboot_syscall (API_GET_SYS_INFO, &retval, &uboot_sys_info)) - if (retval == 0) - return &uboot_sys_info; - - return NULL; -} - -void -grub_uboot_udelay (grub_uint32_t usec) -{ - grub_uboot_syscall (API_UDELAY, NULL, &usec); -} - -grub_uint32_t -grub_uboot_get_timer (grub_uint32_t base) -{ - grub_uint32_t current; - - if (!grub_uboot_syscall (API_GET_TIMER, NULL, ¤t, &base)) - return 0; - - return current; -} - -int -grub_uboot_dev_enum (void) -{ - struct device_info * enum_devices; - int num_enum_devices, max_devices; - - if (num_devices) - return num_devices; - - max_devices = 2; - enum_devices = grub_calloc (max_devices, sizeof(struct device_info)); - if (!enum_devices) - return 0; - - /* - * The API_DEV_ENUM call starts a fresh enumeration when passed a - * struct device_info with a NULL cookie, and then depends on having - * the previously enumerated device cookie "seeded" into the target - * structure. - */ - - enum_devices[0].cookie = NULL; - num_enum_devices = 0; - - if (grub_uboot_syscall (API_DEV_ENUM, NULL, - &enum_devices[num_enum_devices]) == 0) - goto error; - - num_enum_devices++; - - while (enum_devices[num_enum_devices - 1].cookie != NULL) - { - if (num_enum_devices == max_devices) - { - struct device_info *tmp; - int new_max; - new_max = max_devices * 2; - tmp = grub_realloc (enum_devices, - sizeof (struct device_info) * new_max); - if (!tmp) - { - /* Failed to realloc, so return what we have */ - break; - } - enum_devices = tmp; - max_devices = new_max; - } - - enum_devices[num_enum_devices].cookie = - enum_devices[num_enum_devices - 1].cookie; - if (grub_uboot_syscall (API_DEV_ENUM, NULL, - &enum_devices[num_enum_devices]) == 0) - goto error; - - if (enum_devices[num_enum_devices].cookie == NULL) - break; - - num_enum_devices++; - } - - devices = enum_devices; - return num_devices = num_enum_devices; - - error: - grub_free (enum_devices); - return 0; -} - -#define VALID_DEV(x) (((x) < num_devices) && ((x) >= 0)) -#define OPEN_DEV(x) ((x->state == DEV_STA_OPEN)) - -struct device_info * -grub_uboot_dev_get (int index) -{ - if (VALID_DEV (index)) - return &devices[index]; - - return NULL; -} - - -int -grub_uboot_dev_open (struct device_info *dev) -{ - int retval; - - if (!grub_uboot_syscall (API_DEV_OPEN, &retval, dev)) - return -1; - - return retval; -} - -int -grub_uboot_dev_close (struct device_info *dev) -{ - int retval; - - if (!grub_uboot_syscall (API_DEV_CLOSE, &retval, dev)) - return -1; - - return retval; -} - - -int -grub_uboot_dev_read (struct device_info *dev, void *buf, grub_size_t blocks, - grub_uint32_t start, grub_size_t * real_blocks) -{ - int retval; - - if (!OPEN_DEV (dev)) - return -1; - - if (!grub_uboot_syscall (API_DEV_READ, &retval, dev, buf, - &blocks, &start, real_blocks)) - return -1; - - return retval; -} - -int -grub_uboot_dev_write (struct device_info *dev, const void *buf, - grub_size_t blocks, grub_uint32_t start) -{ - int retval; - - if (!OPEN_DEV (dev)) - return -1; - - if (!grub_uboot_syscall (API_DEV_WRITE, &retval, dev, buf, - &blocks, &start)) - return -1; - - return retval; -} - -int -grub_uboot_dev_recv (struct device_info *dev, void *buf, - int size, int *real_size) -{ - int retval; - - if (!OPEN_DEV (dev)) - return -1; - - if (!grub_uboot_syscall (API_DEV_READ, &retval, dev, buf, &size, real_size)) - return -1; - - return retval; - -} - -int -grub_uboot_dev_send (struct device_info *dev, void *buf, int size) -{ - int retval; - - if (!OPEN_DEV (dev)) - return -1; - - if (!grub_uboot_syscall (API_DEV_WRITE, &retval, dev, buf, &size)) - return -1; - - return retval; -} - -char * -grub_uboot_env_get (const char *name) -{ - char *value; - - if (!grub_uboot_syscall (API_ENV_GET, NULL, name, &value)) - return NULL; - - return value; -} - -void -grub_uboot_env_set (const char *name, const char *value) -{ - grub_uboot_syscall (API_ENV_SET, NULL, name, value); -} diff --git a/grub-core/kern/verifiers.c b/grub-core/kern/verifiers.c deleted file mode 100644 index 75d7994cf..000000000 --- a/grub-core/kern/verifiers.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2017 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - * - * Verifiers helper. - */ - -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct grub_file_verifier *grub_file_verifiers; - -struct grub_verified -{ - grub_file_t file; - void *buf; -}; -typedef struct grub_verified *grub_verified_t; - -static void -verified_free (grub_verified_t verified) -{ - if (verified) - { - grub_free (verified->buf); - grub_free (verified); - } -} - -static grub_ssize_t -verified_read (struct grub_file *file, char *buf, grub_size_t len) -{ - grub_verified_t verified = file->data; - - grub_memcpy (buf, (char *) verified->buf + file->offset, len); - return len; -} - -static grub_err_t -verified_close (struct grub_file *file) -{ - grub_verified_t verified = file->data; - - grub_file_close (verified->file); - verified_free (verified); - file->data = 0; - - /* Device and name are freed by parent. */ - file->device = 0; - file->name = 0; - - return grub_errno; -} - -struct grub_fs verified_fs = -{ - .name = "verified_read", - .fs_read = verified_read, - .fs_close = verified_close -}; - -static grub_file_t -grub_verifiers_open (grub_file_t io, enum grub_file_type type) -{ - grub_verified_t verified = NULL; - struct grub_file_verifier *ver; - void *context; - grub_file_t ret = 0; - grub_err_t err; - int defer = 0; - - grub_dprintf ("verify", "file: %s type: %d\n", io->name, type); - - if ((type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_SIGNATURE - || (type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_VERIFY_SIGNATURE - || (type & GRUB_FILE_TYPE_SKIP_SIGNATURE)) - return io; - - if (io->device->disk && - (io->device->disk->dev->id == GRUB_DISK_DEVICE_MEMDISK_ID - || io->device->disk->dev->id == GRUB_DISK_DEVICE_PROCFS_ID)) - return io; - - FOR_LIST_ELEMENTS(ver, grub_file_verifiers) - { - enum grub_verify_flags flags = 0; - err = ver->init (io, type, &context, &flags); - if (err) - goto fail_noclose; - if (flags & GRUB_VERIFY_FLAGS_DEFER_AUTH) - { - defer = 1; - continue; - } - if (!(flags & GRUB_VERIFY_FLAGS_SKIP_VERIFICATION)) - break; - } - - if (!ver) - { - if (defer) - { - grub_error (GRUB_ERR_ACCESS_DENIED, - N_("verification requested but nobody cares: %s"), io->name); - goto fail_noclose; - } - - /* No verifiers wanted to verify. Just return underlying file. */ - return io; - } - - ret = grub_malloc (sizeof (*ret)); - if (!ret) - { - goto fail; - } - *ret = *io; - - ret->fs = &verified_fs; - ret->not_easily_seekable = 0; - if (ret->size >> (sizeof (grub_size_t) * GRUB_CHAR_BIT - 1)) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("big file signature isn't implemented yet")); - goto fail; - } - verified = grub_malloc (sizeof (*verified)); - if (!verified) - { - goto fail; - } - verified->buf = grub_malloc (ret->size); - if (!verified->buf) - { - goto fail; - } - if (grub_file_read (io, verified->buf, ret->size) != (grub_ssize_t) ret->size) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - io->name); - goto fail; - } - - err = ver->write (context, verified->buf, ret->size); - if (err) - goto fail; - - err = ver->fini ? ver->fini (context) : GRUB_ERR_NONE; - if (err) - goto fail; - - if (ver->close) - ver->close (context); - - FOR_LIST_ELEMENTS_NEXT(ver, grub_file_verifiers) - { - enum grub_verify_flags flags = 0; - err = ver->init (io, type, &context, &flags); - if (err) - goto fail_noclose; - if (flags & GRUB_VERIFY_FLAGS_SKIP_VERIFICATION || - /* Verification done earlier. So, we are happy here. */ - flags & GRUB_VERIFY_FLAGS_DEFER_AUTH) - continue; - err = ver->write (context, verified->buf, ret->size); - if (err) - goto fail; - - err = ver->fini ? ver->fini (context) : GRUB_ERR_NONE; - if (err) - goto fail; - - if (ver->close) - ver->close (context); - } - - verified->file = io; - ret->data = verified; - return ret; - - fail: - if (ver->close) - ver->close (context); - fail_noclose: - verified_free (verified); - grub_free (ret); - return NULL; -} - -grub_err_t -grub_verify_string (char *str, enum grub_verify_string_type type) -{ - struct grub_file_verifier *ver; - - grub_dprintf ("verify", "string: %s, type: %d\n", str, type); - - FOR_LIST_ELEMENTS(ver, grub_file_verifiers) - { - grub_err_t err; - err = ver->verify_string ? ver->verify_string (str, type) : GRUB_ERR_NONE; - if (err) - return err; - } - return GRUB_ERR_NONE; -} - -void -grub_verifiers_init (void) -{ - grub_file_filter_register (GRUB_FILE_FILTER_VERIFY, grub_verifiers_open); -} diff --git a/grub-core/kern/vga_init.c b/grub-core/kern/vga_init.c deleted file mode 100644 index 3fe2f16de..000000000 --- a/grub-core/kern/vga_init.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef __mips__ -#include -#include -#endif -#include -#include -#include - -static struct {grub_uint8_t r, g, b, a; } colors[] = - { - // {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 - }; - -#include - -#ifdef __mips__ -#define VGA_ADDR 0xb00a0000 -#else -#define VGA_ADDR 0xa0000 -#endif - -static void -load_font (void) -{ - unsigned i; - - grub_vga_gr_write (0 << 2, GRUB_VGA_GR_GR6); - - grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_NORMAL, GRUB_VGA_SR_MEMORY_MODE); - grub_vga_sr_write (1 << GRUB_VGA_TEXT_FONT_PLANE, - GRUB_VGA_SR_MAP_MASK_REGISTER); - - grub_vga_gr_write (0, GRUB_VGA_GR_DATA_ROTATE); - grub_vga_gr_write (0, GRUB_VGA_GR_MODE); - grub_vga_gr_write (0xff, GRUB_VGA_GR_BITMASK); - - for (i = 0; i < 128; i++) - grub_memcpy ((void *) (VGA_ADDR + 32 * i), ascii_bitmaps + 16 * i, 16); -} - -static void -load_palette (void) -{ - unsigned i; - for (i = 0; i < 16; i++) - grub_vga_write_arx (i, i); - - for (i = 0; i < ARRAY_SIZE (colors); i++) - grub_vga_palette_write (i, colors[i].r, colors[i].g, colors[i].b); -} - -void -grub_qemu_init_cirrus (void) -{ - grub_outb (GRUB_VGA_IO_MISC_COLOR, - GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_MISC_WRITE); - - load_font (); - - grub_vga_gr_write (GRUB_VGA_GR_GR6_MMAP_CGA, GRUB_VGA_GR_GR6); - grub_vga_gr_write (GRUB_VGA_GR_MODE_ODD_EVEN, GRUB_VGA_GR_MODE); - - grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_NORMAL, GRUB_VGA_SR_MEMORY_MODE); - - grub_vga_sr_write ((1 << GRUB_VGA_TEXT_TEXT_PLANE) - | (1 << GRUB_VGA_TEXT_ATTR_PLANE), - GRUB_VGA_SR_MAP_MASK_REGISTER); - - grub_vga_cr_write (15, GRUB_VGA_CR_CELL_HEIGHT); - grub_vga_cr_write (79, GRUB_VGA_CR_HORIZ_END); - grub_vga_cr_write (40, GRUB_VGA_CR_PITCH); - - int vert = 25 * 16; - grub_vga_cr_write (vert & 0xff, GRUB_VGA_CR_VDISPLAY_END); - grub_vga_cr_write (((vert >> GRUB_VGA_CR_OVERFLOW_HEIGHT1_SHIFT) - & GRUB_VGA_CR_OVERFLOW_HEIGHT1_MASK) - | ((vert >> GRUB_VGA_CR_OVERFLOW_HEIGHT2_SHIFT) - & GRUB_VGA_CR_OVERFLOW_HEIGHT2_MASK), - GRUB_VGA_CR_OVERFLOW); - - load_palette (); - - grub_vga_write_arx (GRUB_VGA_ARX_MODE_TEXT, GRUB_VGA_ARX_MODE); - grub_vga_write_arx (0, GRUB_VGA_ARX_COLOR_SELECT); - - grub_vga_sr_write (GRUB_VGA_SR_CLOCKING_MODE_8_DOT_CLOCK, - GRUB_VGA_SR_CLOCKING_MODE); - - grub_vga_cr_write (14, GRUB_VGA_CR_CURSOR_START); - grub_vga_cr_write (15, GRUB_VGA_CR_CURSOR_END); - - grub_outb (0x20, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX); -} diff --git a/grub-core/kern/x86_64/dl.c b/grub-core/kern/x86_64/dl.c deleted file mode 100644 index e5a8bdcf4..000000000 --- a/grub-core/kern/x86_64/dl.c +++ /dev/null @@ -1,121 +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 . - */ - -#include -#include -#include -#include -#include - -/* 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, N_("invalid arch-dependent ELF magic")); - - return GRUB_ERR_NONE; -} - -/* Relocate symbols. */ -grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - Elf_Shdr *s, grub_dl_segment_t seg) -{ - Elf64_Rela *rel, *max; - - for (rel = (Elf64_Rela *) ((char *) ehdr + s->sh_offset), - max = (Elf64_Rela *) ((char *) rel + s->sh_size); - rel < max; - rel = (Elf64_Rela *) ((char *) rel + s->sh_entsize)) - { - 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 - + mod->symsize * 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: - case R_X86_64_PLT32: - { - grub_int64_t value; - value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value - - (Elf64_Xword) (grub_addr_t) seg->addr - rel->r_offset; - if (value != (grub_int32_t) value) - return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range"); - *addr32 = value; - } - break; - - case R_X86_64_PC64: - { - *addr64 += rel->r_addend + sym->st_value - - (Elf64_Xword) (grub_addr_t) seg->addr - rel->r_offset; - } - break; - - case R_X86_64_32: - { - grub_uint64_t value = *addr32 + rel->r_addend + sym->st_value; - if (value != (grub_uint32_t) value) - return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range"); - *addr32 = value; - } - break; - case R_X86_64_32S: - { - grub_int64_t value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value; - if (value != (grub_int32_t) value) - return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range"); - *addr32 = value; - } - break; - - default: - { - char rel_info[17]; /* log16(2^64) = 16, plus NUL. */ - - grub_snprintf (rel_info, sizeof (rel_info) - 1, "%" PRIxGRUB_UINT64_T, - ELF_R_TYPE (rel->r_info)); - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%s is not implemented yet"), rel_info); - } - } - } - - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/x86_64/xen/hypercall.S b/grub-core/kern/x86_64/xen/hypercall.S deleted file mode 100644 index 9b04db6a0..000000000 --- a/grub-core/kern/x86_64/xen/hypercall.S +++ /dev/null @@ -1,53 +0,0 @@ -/* hypercall.S - wrappers for Xen hypercalls */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -FUNCTION(grub_xen_sched_op) - movq $__HYPERVISOR_sched_op, %rax - syscall - ret - -FUNCTION(grub_xen_event_channel_op) - movq $__HYPERVISOR_event_channel_op, %rax - syscall - ret - -FUNCTION(grub_xen_update_va_mapping) - movq $__HYPERVISOR_update_va_mapping, %rax - syscall - ret - -FUNCTION(grub_xen_mmuext_op) - movq %rcx, %r10 - movq $__HYPERVISOR_mmuext_op, %rax - syscall - ret - -FUNCTION(grub_xen_grant_table_op) - movq $__HYPERVISOR_grant_table_op, %rax - syscall - ret - -FUNCTION(grub_xen_mmu_update) - movq %rcx, %r10 - movq $__HYPERVISOR_mmu_update, %rax - syscall - ret diff --git a/grub-core/kern/x86_64/xen/startup.S b/grub-core/kern/x86_64/xen/startup.S deleted file mode 100644 index 21a139f40..000000000 --- a/grub-core/kern/x86_64/xen/startup.S +++ /dev/null @@ -1,39 +0,0 @@ -/* startup.S - bootstrap GRUB itself */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - - .file "startup.S" - .text - .globl start, _start - .code64 - -start: -_start: - leaq LOCAL(stack_end), %rsp - movq %rsi, EXT_C(grub_xen_start_page_addr)(%rip) - - andq $~0xf, %rsp - call EXT_C(grub_main) - /* Doesn't return. */ - - .bss - .space (1 << 22) -LOCAL(stack_end): diff --git a/grub-core/kern/xen/init.c b/grub-core/kern/xen/init.c deleted file mode 100644 index 782ca7295..000000000 --- a/grub-core/kern/xen/init.c +++ /dev/null @@ -1,601 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -grub_addr_t grub_modbase; -struct start_info *grub_xen_start_page_addr; -volatile struct xencons_interface *grub_xen_xcons; -volatile struct shared_info *grub_xen_shared_info; -volatile struct xenstore_domain_interface *grub_xen_xenstore; -volatile grant_entry_v1_t *grub_xen_grant_table; -static const grub_size_t total_grants = - GRUB_XEN_PAGE_SIZE / sizeof (grub_xen_grant_table[0]); -grub_size_t grub_xen_n_allocated_shared_pages; - -static grub_xen_mfn_t -grub_xen_ptr2mfn (void *ptr) -{ -#ifdef GRUB_MACHINE_XEN - grub_xen_mfn_t *mfn_list = - (grub_xen_mfn_t *) grub_xen_start_page_addr->mfn_list; - return mfn_list[(grub_addr_t) ptr >> GRUB_XEN_LOG_PAGE_SIZE]; -#else - return (grub_addr_t) ptr >> GRUB_XEN_LOG_PAGE_SIZE; -#endif -} - -void * -grub_xen_alloc_shared_page (domid_t dom, grub_xen_grant_t * grnum) -{ - void *ret; - grub_xen_mfn_t mfn; - volatile grant_entry_v1_t *entry; - - /* Avoid 0. */ - for (entry = grub_xen_grant_table; - entry < grub_xen_grant_table + total_grants; entry++) - if (!entry->flags) - break; - - if (entry == grub_xen_grant_table + total_grants) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of grant entries"); - return NULL; - } - ret = grub_memalign (GRUB_XEN_PAGE_SIZE, GRUB_XEN_PAGE_SIZE); - if (!ret) - return NULL; - mfn = grub_xen_ptr2mfn (ret); - entry->frame = mfn; - entry->domid = dom; - mb (); - entry->flags = GTF_permit_access; - mb (); - *grnum = entry - grub_xen_grant_table; - grub_xen_n_allocated_shared_pages++; - return ret; -} - -void -grub_xen_free_shared_page (void *ptr) -{ - grub_xen_mfn_t mfn; - volatile grant_entry_v1_t *entry; - - mfn = grub_xen_ptr2mfn (ptr); - for (entry = grub_xen_grant_table + 1; - entry < grub_xen_grant_table + total_grants; entry++) - if (entry->flags && entry->frame == mfn) - { - mb (); - entry->flags = 0; - mb (); - entry->frame = 0; - mb (); - } - grub_xen_n_allocated_shared_pages--; -} - -void -grub_machine_get_bootlocation (char **device __attribute__ ((unused)), - char **path __attribute__ ((unused))) -{ -} - -void -grub_xen_store_send (const void *buf_, grub_size_t len) -{ - const grub_uint8_t *buf = buf_; - struct evtchn_send send; - int event_sent = 0; - while (len) - { - grub_size_t avail, inbuf; - grub_size_t prod, cons; - mb (); - prod = grub_xen_xenstore->req_prod; - cons = grub_xen_xenstore->req_cons; - if (prod >= cons + sizeof (grub_xen_xenstore->req)) - { - if (!event_sent) - { - send.port = grub_xen_start_page_addr->store_evtchn; - grub_xen_event_channel_op (EVTCHNOP_send, &send); - event_sent = 1; - } - grub_xen_sched_op (SCHEDOP_yield, 0); - continue; - } - event_sent = 0; - avail = cons + sizeof (grub_xen_xenstore->req) - prod; - inbuf = (~prod & (sizeof (grub_xen_xenstore->req) - 1)) + 1; - if (avail > inbuf) - avail = inbuf; - if (avail > len) - avail = len; - grub_memcpy ((void *) &grub_xen_xenstore->req[prod & (sizeof (grub_xen_xenstore->req) - 1)], - buf, avail); - buf += avail; - len -= avail; - mb (); - grub_xen_xenstore->req_prod += avail; - mb (); - if (!event_sent) - { - send.port = grub_xen_start_page_addr->store_evtchn; - grub_xen_event_channel_op (EVTCHNOP_send, &send); - event_sent = 1; - } - grub_xen_sched_op (SCHEDOP_yield, 0); - } -} - -void -grub_xen_store_recv (void *buf_, grub_size_t len) -{ - grub_uint8_t *buf = buf_; - struct evtchn_send send; - int event_sent = 0; - while (len) - { - grub_size_t avail, inbuf; - grub_size_t prod, cons; - mb (); - prod = grub_xen_xenstore->rsp_prod; - cons = grub_xen_xenstore->rsp_cons; - if (prod <= cons) - { - if (!event_sent) - { - send.port = grub_xen_start_page_addr->store_evtchn; - grub_xen_event_channel_op (EVTCHNOP_send, &send); - event_sent = 1; - } - grub_xen_sched_op (SCHEDOP_yield, 0); - continue; - } - event_sent = 0; - avail = prod - cons; - inbuf = (~cons & (sizeof (grub_xen_xenstore->req) - 1)) + 1; - if (avail > inbuf) - avail = inbuf; - if (avail > len) - avail = len; - grub_memcpy (buf, - (void *) &grub_xen_xenstore->rsp[cons & (sizeof (grub_xen_xenstore->rsp) - 1)], - avail); - buf += avail; - len -= avail; - mb (); - grub_xen_xenstore->rsp_cons += avail; - mb (); - if (!event_sent) - { - send.port = grub_xen_start_page_addr->store_evtchn; - grub_xen_event_channel_op(EVTCHNOP_send, &send); - event_sent = 1; - } - grub_xen_sched_op(SCHEDOP_yield, 0); - } -} - -void * -grub_xenstore_get_file (const char *dir, grub_size_t *len) -{ - struct xsd_sockmsg msg; - char *buf; - grub_size_t dirlen = grub_strlen (dir) + 1; - - if (len) - *len = 0; - - grub_memset (&msg, 0, sizeof (msg)); - msg.type = XS_READ; - msg.len = dirlen; - grub_xen_store_send (&msg, sizeof (msg)); - grub_xen_store_send (dir, dirlen); - grub_xen_store_recv (&msg, sizeof (msg)); - buf = grub_malloc (msg.len + 1); - if (!buf) - return NULL; - grub_dprintf ("xen", "msg type = %d, len = %d\n", msg.type, msg.len); - grub_xen_store_recv (buf, msg.len); - buf[msg.len] = '\0'; - if (msg.type == XS_ERROR) - { - grub_error (GRUB_ERR_IO, "couldn't read xenstorage `%s': %s", dir, buf); - grub_free (buf); - return NULL; - } - if (len) - *len = msg.len; - return buf; -} - -grub_err_t -grub_xenstore_write_file (const char *dir, const void *buf, grub_size_t len) -{ - struct xsd_sockmsg msg; - grub_size_t dirlen = grub_strlen (dir) + 1; - char *resp; - - grub_memset (&msg, 0, sizeof (msg)); - msg.type = XS_WRITE; - msg.len = dirlen + len; - grub_xen_store_send (&msg, sizeof (msg)); - grub_xen_store_send (dir, dirlen); - grub_xen_store_send (buf, len); - grub_xen_store_recv (&msg, sizeof (msg)); - resp = grub_malloc (msg.len + 1); - if (!resp) - return grub_errno; - grub_dprintf ("xen", "msg type = %d, len = %d\n", msg.type, msg.len); - grub_xen_store_recv (resp, msg.len); - resp[msg.len] = '\0'; - if (msg.type == XS_ERROR) - { - grub_dprintf ("xen", "error = %s\n", resp); - grub_error (GRUB_ERR_IO, "couldn't read xenstorage `%s': %s", - dir, resp); - grub_free (resp); - return grub_errno; - } - grub_free (resp); - return GRUB_ERR_NONE; -} - -/* FIXME: error handling. */ -grub_err_t -grub_xenstore_dir (const char *dir, - int (*hook) (const char *dir, void *hook_data), - void *hook_data) -{ - struct xsd_sockmsg msg; - char *buf; - char *ptr; - grub_size_t dirlen = grub_strlen (dir) + 1; - - grub_memset (&msg, 0, sizeof (msg)); - msg.type = XS_DIRECTORY; - msg.len = dirlen; - grub_xen_store_send (&msg, sizeof (msg)); - grub_xen_store_send (dir, dirlen); - grub_xen_store_recv (&msg, sizeof (msg)); - buf = grub_malloc (msg.len + 1); - if (!buf) - return grub_errno; - grub_dprintf ("xen", "msg type = %d, len = %d\n", msg.type, msg.len); - grub_xen_store_recv (buf, msg.len); - buf[msg.len] = '\0'; - if (msg.type == XS_ERROR) - { - grub_err_t err; - err = grub_error (GRUB_ERR_IO, "couldn't read xenstorage `%s': %s", - dir, buf); - grub_free (buf); - return err; - } - for (ptr = buf; ptr < buf + msg.len; ptr += grub_strlen (ptr) + 1) - if (hook (ptr, hook_data)) - break; - grub_free (buf); - return grub_errno; -} - -unsigned long gntframe = 0; - -static void -grub_xen_setup_gnttab (void) -{ - struct gnttab_set_version gnttab_setver; - struct gnttab_setup_table gnttab_setup; - - grub_memset (&gnttab_setver, 0, sizeof (gnttab_setver)); - - gnttab_setver.version = 1; - grub_xen_grant_table_op (GNTTABOP_set_version, &gnttab_setver, 1); - - grub_memset (&gnttab_setup, 0, sizeof (gnttab_setup)); - gnttab_setup.dom = DOMID_SELF; - gnttab_setup.nr_frames = 1; - gnttab_setup.frame_list.p = &gntframe; - - grub_xen_grant_table_op (GNTTABOP_setup_table, &gnttab_setup, 1); -} - -#ifdef GRUB_MACHINE_XEN -static grub_uint8_t window[GRUB_XEN_PAGE_SIZE] - __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE))); - -#ifdef __x86_64__ -#define NUMBER_OF_LEVELS 4 -#else -#define NUMBER_OF_LEVELS 3 -#endif - -#define LOG_POINTERS_PER_PAGE 9 -#define POINTERS_PER_PAGE (1 << LOG_POINTERS_PER_PAGE) - -#define MAX_N_UNUSABLE_PAGES 4 - -static int -grub_xen_is_page_usable (grub_xen_mfn_t mfn) -{ - if (mfn == grub_xen_start_page_addr->console.domU.mfn) - return 0; - if (mfn == grub_xen_start_page_addr->shared_info) - return 0; - if (mfn == grub_xen_start_page_addr->store_mfn) - return 0; - if (mfn == gntframe) - return 0; - return 1; -} - -static grub_uint64_t -page2offset (grub_uint64_t page) -{ - return page << 12; -} - -#if defined (__x86_64__) && defined (__code_model_large__) -#define MAX_TOTAL_PAGES (1LL << (64 - 12)) -#elif defined (__x86_64__) -#define MAX_TOTAL_PAGES (1LL << (31 - 12)) -#else -#define MAX_TOTAL_PAGES (1LL << (32 - 12)) -#endif - -static void -map_all_pages (void) -{ - grub_uint64_t total_pages = grub_xen_start_page_addr->nr_pages; - grub_uint64_t i, j; - grub_xen_mfn_t *mfn_list = - (grub_xen_mfn_t *) grub_xen_start_page_addr->mfn_list; - grub_uint64_t *pg = (grub_uint64_t *) window; - grub_uint64_t oldpgstart, oldpgend; - grub_size_t n_unusable_pages = 0; - struct mmu_update m2p_updates[2 * MAX_N_UNUSABLE_PAGES]; - - if (total_pages > MAX_TOTAL_PAGES - 4) - total_pages = MAX_TOTAL_PAGES - 4; - - for (j = 0; j < total_pages - n_unusable_pages; j++) - while (!grub_xen_is_page_usable (mfn_list[j])) - { - grub_xen_mfn_t t; - if (n_unusable_pages >= MAX_N_UNUSABLE_PAGES) - { - struct sched_shutdown arg; - arg.reason = SHUTDOWN_crash; - grub_xen_sched_op (SCHEDOP_shutdown, &arg); - while (1); - } - t = mfn_list[j]; - mfn_list[j] = mfn_list[total_pages - n_unusable_pages - 1]; - mfn_list[total_pages - n_unusable_pages - 1] = t; - - m2p_updates[2 * n_unusable_pages].ptr - = page2offset (mfn_list[j]) | MMU_MACHPHYS_UPDATE; - m2p_updates[2 * n_unusable_pages].val = j; - m2p_updates[2 * n_unusable_pages + 1].ptr - = page2offset (mfn_list[total_pages - n_unusable_pages - 1]) - | MMU_MACHPHYS_UPDATE; - m2p_updates[2 * n_unusable_pages + 1].val = total_pages - - n_unusable_pages - 1; - - n_unusable_pages++; - } - - grub_xen_mmu_update (m2p_updates, 2 * n_unusable_pages, NULL, DOMID_SELF); - - total_pages += 4; - - grub_uint64_t lx[NUMBER_OF_LEVELS], nlx; - grub_uint64_t paging_start = total_pages - 4 - n_unusable_pages, curpage; - - for (nlx = total_pages, i = 0; i < (unsigned) NUMBER_OF_LEVELS; i++) - { - nlx = (nlx + POINTERS_PER_PAGE - 1) >> LOG_POINTERS_PER_PAGE; - /* PAE wants all 4 root directories present. */ -#ifdef __i386__ - if (i == 1) - nlx = 4; -#endif - lx[i] = nlx; - paging_start -= nlx; - } - - oldpgstart = grub_xen_start_page_addr->pt_base >> 12; - oldpgend = oldpgstart + grub_xen_start_page_addr->nr_pt_frames; - - curpage = paging_start; - - int l; - - for (l = NUMBER_OF_LEVELS - 1; l >= 1; l--) - { - for (i = 0; i < lx[l]; i++) - { - grub_xen_update_va_mapping (&window, - page2offset (mfn_list[curpage + i]) | 7, - UVMF_INVLPG); - grub_memset (&window, 0, sizeof (window)); - - for (j = i * POINTERS_PER_PAGE; - j < (i + 1) * POINTERS_PER_PAGE && j < lx[l - 1]; j++) - pg[j - i * POINTERS_PER_PAGE] = - page2offset (mfn_list[curpage + lx[l] + j]) -#ifdef __x86_64__ - | 4 -#endif - | 3; - } - curpage += lx[l]; - } - - for (i = 0; i < lx[0]; i++) - { - grub_xen_update_va_mapping (&window, - page2offset (mfn_list[curpage + i]) | 7, - UVMF_INVLPG); - grub_memset (&window, 0, sizeof (window)); - - for (j = i * POINTERS_PER_PAGE; - j < (i + 1) * POINTERS_PER_PAGE && j < total_pages; j++) - if (j < paging_start && !(j >= oldpgstart && j < oldpgend)) - pg[j - i * POINTERS_PER_PAGE] = page2offset (mfn_list[j]) | 0x7; - else if (j < grub_xen_start_page_addr->nr_pages) - pg[j - i * POINTERS_PER_PAGE] = page2offset (mfn_list[j]) | 5; - else if (j == grub_xen_start_page_addr->nr_pages) - { - pg[j - i * POINTERS_PER_PAGE] = - page2offset (grub_xen_start_page_addr->console.domU.mfn) | 7; - grub_xen_xcons = (void *) (grub_addr_t) page2offset (j); - } - else if (j == grub_xen_start_page_addr->nr_pages + 1) - { - pg[j - i * POINTERS_PER_PAGE] = - grub_xen_start_page_addr->shared_info | 7; - grub_xen_shared_info = (void *) (grub_addr_t) page2offset (j); - } - else if (j == grub_xen_start_page_addr->nr_pages + 2) - { - pg[j - i * POINTERS_PER_PAGE] = - page2offset (grub_xen_start_page_addr->store_mfn) | 7; - grub_xen_xenstore = (void *) (grub_addr_t) page2offset (j); - } - else if (j == grub_xen_start_page_addr->nr_pages + 3) - { - pg[j - i * POINTERS_PER_PAGE] = page2offset (gntframe) | 7; - grub_xen_grant_table = (void *) (grub_addr_t) page2offset (j); - } - } - - grub_xen_update_va_mapping (&window, 0, UVMF_INVLPG); - - mmuext_op_t op[3]; - - op[0].cmd = MMUEXT_PIN_L1_TABLE + (NUMBER_OF_LEVELS - 1); - op[0].arg1.mfn = mfn_list[paging_start]; - op[1].cmd = MMUEXT_NEW_BASEPTR; - op[1].arg1.mfn = mfn_list[paging_start]; - op[2].cmd = MMUEXT_UNPIN_TABLE; - op[2].arg1.mfn = mfn_list[oldpgstart]; - - grub_xen_mmuext_op (op, 3, NULL, DOMID_SELF); - - for (i = oldpgstart; i < oldpgend; i++) - grub_xen_update_va_mapping ((void *) (grub_addr_t) page2offset (i), - page2offset (mfn_list[i]) | 7, UVMF_INVLPG); - void *new_start_page, *new_mfn_list; - new_start_page = (void *) (grub_addr_t) page2offset (paging_start - 1); - grub_memcpy (new_start_page, grub_xen_start_page_addr, 4096); - grub_xen_start_page_addr = new_start_page; - new_mfn_list = (void *) (grub_addr_t) - page2offset (paging_start - 1 - - ((grub_xen_start_page_addr->nr_pages - * sizeof (grub_uint64_t) + 4095) / 4096)); - grub_memcpy (new_mfn_list, mfn_list, grub_xen_start_page_addr->nr_pages - * sizeof (grub_uint64_t)); - grub_xen_start_page_addr->pt_base = page2offset (paging_start); - grub_xen_start_page_addr->mfn_list = (grub_addr_t) new_mfn_list; - - grub_addr_t heap_start = grub_modules_get_end (); - grub_addr_t heap_end = (grub_addr_t) new_mfn_list; - - grub_mm_init_region ((void *) heap_start, heap_end - heap_start); -} - -grub_err_t -grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) -{ - grub_uint64_t total_pages = grub_xen_start_page_addr->nr_pages; - grub_uint64_t usable_pages = grub_xen_start_page_addr->pt_base >> 12; - if (hook (0, page2offset (usable_pages), GRUB_MEMORY_AVAILABLE, hook_data)) - return GRUB_ERR_NONE; - - hook (page2offset (usable_pages), page2offset (total_pages - usable_pages), - GRUB_MEMORY_RESERVED, hook_data); - - return GRUB_ERR_NONE; -} -#endif - -extern char _end[]; - -void -grub_machine_init (void) -{ -#ifdef GRUB_MACHINE_XEN -#ifdef __i386__ - grub_xen_vm_assist (VMASST_CMD_enable, VMASST_TYPE_pae_extended_cr3); -#endif -#endif - - grub_modbase = ALIGN_UP ((grub_addr_t) _end - + GRUB_KERNEL_MACHINE_MOD_GAP, - GRUB_KERNEL_MACHINE_MOD_ALIGN); - -#ifdef GRUB_MACHINE_XEN_PVH - grub_xen_setup_pvh (); -#endif - - grub_xen_setup_gnttab (); - -#ifdef GRUB_MACHINE_XEN - map_all_pages (); -#endif - - grub_console_init (); - - grub_tsc_init (); - - grub_xendisk_init (); - - grub_boot_init (); -} - -void -grub_exit (void) -{ - struct sched_shutdown arg; - - arg.reason = SHUTDOWN_poweroff; - grub_xen_sched_op (SCHEDOP_shutdown, &arg); - while (1); -} - -void -grub_machine_fini (int flags __attribute__ ((unused))) -{ - grub_xendisk_fini (); - grub_boot_fini (); -} diff --git a/grub-core/lib/adler32.c b/grub-core/lib/adler32.c deleted file mode 100644 index 43b68af62..000000000 --- a/grub-core/lib/adler32.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2012 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - - -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct adler32_context -{ - grub_uint16_t a, b; - grub_uint32_t c; -}; - -static void -adler32_init (void *context) -{ - struct adler32_context *ctx = context; - - ctx->a = 1; - ctx->b = 0; -} - -#define MOD 65521 - -static grub_uint16_t -mod_add (grub_uint16_t a, grub_uint16_t b) -{ - if ((grub_uint32_t) a + (grub_uint32_t) b >= MOD) - return a + b - MOD; - return a + b; -} - -static void -adler32_write (void *context, const void *inbuf, grub_size_t inlen) -{ - struct adler32_context *ctx = context; - const grub_uint8_t *ptr = inbuf; - - while (inlen) - { - ctx->a = mod_add (ctx->a, *ptr); - ctx->b = mod_add (ctx->a, ctx->b); - inlen--; - ptr++; - } -} - -static void -adler32_final (void *context __attribute__ ((unused))) -{ -} - -static grub_uint8_t * -adler32_read (void *context) -{ - struct adler32_context *ctx = context; - if (ctx->a > MOD) - ctx->a -= MOD; - if (ctx->b > MOD) - ctx->b -= MOD; - ctx->c = grub_cpu_to_be32 (ctx->a | (ctx->b << 16)); - return (grub_uint8_t *) &ctx->c; -} - -static gcry_md_spec_t spec_adler32 = - { - "ADLER32", 0, 0, 0, 4, - adler32_init, adler32_write, adler32_final, adler32_read, - sizeof (struct adler32_context), -#ifdef GRUB_UTIL - .modname = "adler32", -#endif - .blocksize = 64 - }; - - -GRUB_MOD_INIT(adler32) -{ - grub_md_register (&spec_adler32); -} - -GRUB_MOD_FINI(adler32) -{ - grub_md_unregister (&spec_adler32); -} diff --git a/grub-core/lib/arc/datetime.c b/grub-core/lib/arc/datetime.c deleted file mode 100644 index b8d910e5f..000000000 --- a/grub-core/lib/arc/datetime.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -grub_err_t -grub_get_datetime (struct grub_datetime *datetime) -{ - struct grub_arc_timeinfo *dt; - grub_memset (datetime, 0, sizeof (*datetime)); - - dt = GRUB_ARC_FIRMWARE_VECTOR->gettime (); - - datetime->year = dt->y; - datetime->month = dt->m; - datetime->day = dt->d; - datetime->hour = dt->h; - datetime->minute = dt->min; - datetime->second = dt->s; - - return 0; -} - -grub_err_t -grub_set_datetime (struct grub_datetime *datetime __attribute__ ((unused))) -{ - return grub_error (GRUB_ERR_IO, "setting time isn't supported"); -} diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c deleted file mode 100644 index c2bd6a452..000000000 --- a/grub-core/lib/arg.c +++ /dev/null @@ -1,492 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -/* Built-in parser for default options. */ -static const struct grub_arg_option help_options[] = - { - {"help", 0, 0, - N_("Display this help and exit."), 0, ARG_TYPE_NONE}, - {"usage", 0, 0, - N_("Display the usage of this command and exit."), 0, ARG_TYPE_NONE}, - {0, 0, 0, 0, 0, 0} - }; - -/* Helper for find_short. */ -static const struct grub_arg_option * -fnd_short (const struct grub_arg_option *opt, char c) -{ - while (opt->doc) - { - if (opt->shortarg == c) - return opt; - opt++; - } - return 0; -} - -static const struct grub_arg_option * -find_short (const struct grub_arg_option *options, char c) -{ - const struct grub_arg_option *found = 0; - - if (options) - found = fnd_short (options, c); - - if (! found) - { - switch (c) - { - case 'h': - found = help_options; - break; - - case 'u': - found = (help_options + 1); - break; - - default: - break; - } - } - - return found; -} - -/* Helper for find_long. */ -static const struct grub_arg_option * -fnd_long (const struct grub_arg_option *opt, const char *s, int len) -{ - while (opt->doc) - { - if (opt->longarg && ! grub_strncmp (opt->longarg, s, len) && - opt->longarg[len] == '\0') - return opt; - opt++; - } - return 0; -} - -static const struct grub_arg_option * -find_long (const struct grub_arg_option *options, const char *s, int len) -{ - const struct grub_arg_option *found = 0; - - if (options) - found = fnd_long (options, s, len); - - if (! found) - found = fnd_long (help_options, s, len); - - return found; -} - -static void -show_usage (grub_extcmd_t cmd) -{ - grub_printf ("%s %s %s\n", _("Usage:"), cmd->cmd->name, _(cmd->cmd->summary)); -} - -static void -showargs (const struct grub_arg_option *opt, - int h_is_used, int u_is_used) -{ - 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 == help_options && ! h_is_used) - grub_printf ("-h, "); - else if (opt == help_options + 1 && ! 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; - } - } - - if (spacing <= 0) - spacing = 3; - - while (spacing--) - grub_xputs (" "); - - grub_printf ("%s\n", _(opt->doc)); - } -} - -void -grub_arg_show_help (grub_extcmd_t cmd) -{ - int h_is_used = 0; - int u_is_used = 0; - const struct grub_arg_option *opt; - - show_usage (cmd); - grub_printf ("%s\n\n", _(cmd->cmd->description)); - - for (opt = cmd->options; opt && opt->doc; opt++) - switch (opt->shortarg) - { - case 'h': - h_is_used = 1; - break; - - case 'u': - u_is_used = 1; - break; - } - - if (cmd->options) - showargs (cmd->options, h_is_used, u_is_used); - showargs (help_options, h_is_used, u_is_used); -#if 0 - grub_printf ("\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT); -#endif -} - - -static int -parse_option (grub_extcmd_t cmd, const struct grub_arg_option *opt, - char *arg, struct grub_arg_list *usr) -{ - if (opt == help_options) - { - grub_arg_show_help (cmd); - return -1; - } - - if (opt == help_options + 1) - { - show_usage (cmd); - return -1; - } - { - int found = opt - cmd->options; - - if (opt->flags & GRUB_ARG_OPTION_REPEATABLE) - { - usr[found].args[usr[found].set++] = arg; - usr[found].args[usr[found].set] = NULL; - } - else - { - usr[found].set = 1; - usr[found].arg = arg; - } - } - - return 0; -} - -static inline grub_err_t -add_arg (char ***argl, int *num, char *s) -{ - char **p = *argl; - grub_size_t sz; - - if (grub_add (++(*num), 1, &sz) || - grub_mul (sz, sizeof (char *), &sz)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); - - *argl = grub_realloc (*argl, sz); - if (! *argl) - { - grub_free (p); - return grub_errno; - } - (*argl)[(*num) - 1] = s; - (*argl)[(*num)] = NULL; - 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; - char **argl = 0; - int num = 0; - - for (curarg = 0; curarg < argc; curarg++) - { - char *arg = argv[curarg]; - const struct grub_arg_option *opt; - char *option = 0; - - /* No option is used. */ - if ((num && (cmd->cmd->flags & GRUB_COMMAND_OPTIONS_AT_START)) - || arg[0] != '-' || grub_strlen (arg) == 1) - { - if (add_arg (&argl, &num, arg) != 0) - goto fail; - - continue; - } - - /* One or more short options. */ - if (arg[1] != '-') - { - char *curshort; - - if (cmd->cmd->flags & GRUB_COMMAND_ACCEPT_DASH) - { - for (curshort = arg + 1; *curshort; curshort++) - if (!find_short (cmd->options, *curshort)) - break; - - if (*curshort) - { - if (add_arg (&argl, &num, arg) != 0) - goto fail; - continue; - } - } - - curshort = arg + 1; - - while (1) - { - opt = find_short (cmd->options, *curshort); - - if (! opt) - { - char tmp[3] = { '-', *curshort, 0 }; - grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unknown argument `%s'"), tmp); - goto fail; - } - - curshort++; - - /* Parse all arguments here except the last one because - it can have an argument value. */ - if (*curshort) - { - /* - * Only permit further short opts if this one doesn't - * require a value. - */ - if (opt->type != ARG_TYPE_NONE && - !(opt->flags & GRUB_ARG_OPTION_OPTIONAL)) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("missing mandatory option for `%s'"), - opt->longarg); - goto fail; - } - - if (parse_option (cmd, opt, 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 (&argl, &num, 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 (!option && argv[curarg + 1] && argv[curarg + 1][0] != '-' - && opt && opt->type != ARG_TYPE_NONE) - option = argv[++curarg]; - - if (!opt && (cmd->cmd->flags & GRUB_COMMAND_ACCEPT_DASH)) - { - if (add_arg (&argl, &num, arg) != 0) - goto fail; - continue; - } - - if (! opt) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("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, - N_("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: - { - const char * tail; - - grub_strtoull (option, &tail, 0); - if (tail == 0 || tail == option || *tail != '\0' || grub_errno) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("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, option, usr) || grub_errno) - goto fail; - } - else - { - if (option) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("a value was assigned to the argument `%s' while it " - "doesn't require an argument"), arg); - goto fail; - } - - if (parse_option (cmd, opt, 0, usr) || grub_errno) - goto fail; - } - } - - *args = argl; - *argnum = num; - return 1; - - fail: - return 0; -} - -struct grub_arg_list* -grub_arg_list_alloc(grub_extcmd_t extcmd, int argc, - char **argv __attribute__((unused))) -{ - int i; - char **args; - grub_size_t argcnt; - struct grub_arg_list *list; - const struct grub_arg_option *options; - grub_size_t sz0, sz1; - - options = extcmd->options; - if (! options) - return 0; - - argcnt = 0; - for (i = 0; options[i].doc; i++) - { - if (options[i].flags & GRUB_ARG_OPTION_REPEATABLE) - argcnt += ((grub_size_t) argc + 1) / 2 + 1; /* max possible for any option */ - } - - if (grub_mul (sizeof (*list), i, &sz0) || - grub_mul (sizeof (char *), argcnt, &sz1) || - grub_add (sz0, sz1, &sz0)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); - return 0; - } - - list = grub_zalloc (sz0); - if (! list) - return 0; - - args = (char**) (list + i); - for (i = 0; options[i].doc; i++) - { - list[i].set = 0; - list[i].arg = 0; - - if (options[i].flags & GRUB_ARG_OPTION_REPEATABLE) - { - list[i].args = args; - args += (grub_size_t) argc / 2 + 1; - } - } - return list; -} diff --git a/grub-core/lib/arm64/setjmp.S b/grub-core/lib/arm64/setjmp.S deleted file mode 100644 index ffcabf6e4..000000000 --- a/grub-core/lib/arm64/setjmp.S +++ /dev/null @@ -1,56 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - - .file "setjmp.S" -GRUB_MOD_LICENSE "GPLv3+" - .text - -/* - * int grub_setjmp (grub_jmp_buf env) - */ -FUNCTION(grub_setjmp) - stp x19, x20, [x0], #16 - stp x21, x22, [x0], #16 - stp x23, x24, [x0], #16 - stp x25, x26, [x0], #16 - stp x27, x28, [x0], #16 - stp x29, x30, [x0], #16 - mov x1, sp - str x1, [x0] - mov x0, #0 - ret - -/* - * int grub_longjmp (grub_jmp_buf env, int val) - */ -FUNCTION(grub_longjmp) - ldp x19, x20, [x0], #16 - ldp x21, x22, [x0], #16 - ldp x23, x24, [x0], #16 - ldp x25, x26, [x0], #16 - ldp x27, x28, [x0], #16 - ldp x29, x30, [x0], #16 - ldr x2, [x0] - mov sp, x2 - mov x0, #1 - cmp x1, #0 - csel x0, x1, x0, ne - ret diff --git a/grub-core/lib/backtrace.c b/grub-core/lib/backtrace.c deleted file mode 100644 index 825a8800e..000000000 --- a/grub-core/lib/backtrace.c +++ /dev/null @@ -1,70 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -void -grub_backtrace_print_address (void *addr) -{ - grub_dl_t mod; - - FOR_DL_MODULES (mod) - { - grub_dl_segment_t segment; - for (segment = mod->segment; segment; segment = segment->next) - if (segment->addr <= addr && (grub_uint8_t *) segment->addr - + segment->size > (grub_uint8_t *) addr) - { - grub_printf ("%s.%x+%" PRIxGRUB_SIZE, mod->name, segment->section, - (grub_size_t) ((grub_uint8_t *) addr - (grub_uint8_t *) segment->addr)); - return; - } - } - - grub_printf ("%p", addr); -} - -static grub_err_t -grub_cmd_backtrace (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - grub_backtrace (); - return 0; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(backtrace) -{ - cmd = grub_register_command ("backtrace", grub_cmd_backtrace, - 0, N_("Print backtrace.")); -} - -GRUB_MOD_FINI(backtrace) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/lib/cmdline.c b/grub-core/lib/cmdline.c deleted file mode 100644 index ed0b149dc..000000000 --- a/grub-core/lib/cmdline.c +++ /dev/null @@ -1,109 +0,0 @@ -/* cmdline.c - linux command line handling */ -/* - * 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 . - */ - -#include -#include - -static unsigned int check_arg (char *c, int *has_space) -{ - int space = 0; - unsigned int size = 0; - - while (*c) - { - if (*c == '\\' || *c == '\'' || *c == '"') - size++; - else if (*c == ' ') - space = 1; - - size++; - c++; - } - - if (space) - size += 2; - - if (has_space) - *has_space = space; - - return size; -} - -unsigned int grub_loader_cmdline_size (int argc, char *argv[]) -{ - int i; - unsigned int size = 0; - - for (i = 0; i < argc; i++) - { - size += check_arg (argv[i], 0); - size++; /* Separator space or NULL. */ - } - - if (size == 0) - size = 1; - - return size; -} - -grub_err_t -grub_create_loader_cmdline (int argc, char *argv[], char *buf, - grub_size_t size, enum grub_verify_string_type type) -{ - int i, space; - unsigned int arg_size; - char *c, *orig_buf = buf; - - for (i = 0; i < argc; i++) - { - c = argv[i]; - arg_size = check_arg(argv[i], &space); - arg_size++; /* Separator space or NULL. */ - - if (size < arg_size) - break; - - size -= arg_size; - - if (space) - *buf++ = '"'; - - while (*c) - { - if (*c == '\\' || *c == '\'' || *c == '"') - *buf++ = '\\'; - - *buf++ = *c; - c++; - } - - if (space) - *buf++ = '"'; - - *buf++ = ' '; - } - - /* Replace last space with null. */ - if (i) - buf--; - - *buf = 0; - - return grub_verify_string (orig_buf, type); -} diff --git a/grub-core/lib/crc64.c b/grub-core/lib/crc64.c deleted file mode 100644 index 4960f3f89..000000000 --- a/grub-core/lib/crc64.c +++ /dev/null @@ -1,114 +0,0 @@ -/* crc64.c - crc64 function */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_uint64_t crc64_table [256]; - -/* Helper for init_crc64_table. */ -static grub_uint64_t -reflect (grub_uint64_t ref, int len) -{ - grub_uint64_t result = 0; - int i; - - for (i = 1; i <= len; i++) - { - if (ref & 1) - result |= 1ULL << (len - i); - ref >>= 1; - } - - return result; -} - -static void -init_crc64_table (void) -{ - grub_uint64_t polynomial = 0x42f0e1eba9ea3693ULL; - int i, j; - - for(i = 0; i < 256; i++) - { - crc64_table[i] = reflect(i, 8) << 56; - for (j = 0; j < 8; j++) - { - crc64_table[i] = (crc64_table[i] << 1) ^ - (crc64_table[i] & (1ULL << 63) ? polynomial : 0); - } - crc64_table[i] = reflect(crc64_table[i], 64); - } -} - -static void -crc64_init (void *context) -{ - if (! crc64_table[1]) - init_crc64_table (); - *(grub_uint64_t *) context = 0; -} - -static void -crc64_write (void *context, const void *buf, grub_size_t size) -{ - unsigned i; - const grub_uint8_t *data = buf; - grub_uint64_t crc = ~grub_le_to_cpu64 (*(grub_uint64_t *) context); - - for (i = 0; i < size; i++) - { - crc = (crc >> 8) ^ crc64_table[(crc & 0xFF) ^ *data]; - data++; - } - - *(grub_uint64_t *) context = grub_cpu_to_le64 (~crc); -} - -static grub_uint8_t * -crc64_read (void *context) -{ - return context; -} - -static void -crc64_final (void *context __attribute__ ((unused))) -{ -} - -gcry_md_spec_t _gcry_digest_spec_crc64 = - { - "CRC64", 0, 0, 0, 8, - crc64_init, crc64_write, crc64_final, crc64_read, - sizeof (grub_uint64_t), - .blocksize = 64 - }; - -GRUB_MOD_INIT(crc64) -{ - grub_md_register (&_gcry_digest_spec_crc64); -} - -GRUB_MOD_FINI(crc64) -{ - grub_md_unregister (&_gcry_digest_spec_crc64); -} diff --git a/grub-core/lib/datetime.c b/grub-core/lib/datetime.c deleted file mode 100644 index 8f0922fb0..000000000 --- a/grub-core/lib/datetime.c +++ /dev/null @@ -1,122 +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 . - */ - -#include -#include -#include -#include -#ifdef GRUB_MACHINE_EMU -#include - -GRUB_MOD_LICENSE ("GPLv3+"); -#endif - -static const char *const grub_weekday_names[] = -{ - N_("Sunday"), - N_("Monday"), - N_("Tuesday"), - N_("Wednesday"), - N_("Thursday"), - N_("Friday"), - N_("Saturday"), -}; - -int -grub_get_weekday (struct grub_datetime *datetime) -{ - unsigned a, y, m; - - if (datetime->month <= 2) - a = 1; - else - a = 0; - y = datetime->year - a; - m = datetime->month + 12 * a - 2; - - return (datetime->day + y + y / 4 - y / 100 + y / 400 + (31 * m / 12)) % 7; -} - -const 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 DAYSPERYEAR 365 -#define DAYSPER4YEARS (4*DAYSPERYEAR+1) - - -void -grub_unixtime2datetime (grub_int64_t nix, struct grub_datetime *datetime) -{ - int i; - 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 counting date. So count from 1901. */ - int days_epoch; - /* Number of days since 1st Januar, 1901. */ - unsigned days; - /* Seconds into current day. */ - unsigned secs_in_day; - - /* Transform C divisions and modulos to mathematical ones */ - if (nix < 0) - /* - * The result of division here shouldn't be larger than GRUB_INT_MAX. - * So, it's safe to store the result back in an int. - */ - days_epoch = -(grub_divmod64 (((grub_int64_t) (SECPERDAY) - nix - 1), SECPERDAY, NULL)); - else - days_epoch = grub_divmod64 (nix, SECPERDAY, NULL); - - secs_in_day = nix - days_epoch * SECPERDAY; - days = days_epoch + 69 * DAYSPERYEAR + 17; - - datetime->year = 1901 + 4 * (days / DAYSPER4YEARS); - days %= DAYSPER4YEARS; - /* On 31st December of bissextile years 365 days from the beginning - of the year elapsed but year isn't finished yet */ - if (days / DAYSPERYEAR == 4) - { - datetime->year += 3; - days -= 3*DAYSPERYEAR; - } - else - { - datetime->year += days / DAYSPERYEAR; - days %= DAYSPERYEAR; - } - for (i = 0; i < 12 - && days >= (i==1 && datetime->year % 4 == 0 - ? 29 : months[i]); i++) - days -= (i==1 && datetime->year % 4 == 0 - ? 29 : months[i]); - datetime->month = i + 1; - datetime->day = 1 + days; - datetime->hour = (secs_in_day / SECPERHOUR); - secs_in_day %= SECPERHOUR; - datetime->minute = secs_in_day / SECPERMIN; - datetime->second = secs_in_day % SECPERMIN; -} diff --git a/grub-core/lib/disk.c b/grub-core/lib/disk.c deleted file mode 100644 index 123993dd4..000000000 --- a/grub-core/lib/disk.c +++ /dev/null @@ -1,161 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#include "../kern/disk_common.c" - -static void -grub_disk_cache_invalidate (unsigned long dev_id, unsigned long disk_id, - grub_disk_addr_t sector) -{ - unsigned cache_index; - struct grub_disk_cache *cache; - - sector &= ~((grub_disk_addr_t) GRUB_DISK_CACHE_SIZE - 1); - cache_index = grub_disk_cache_get_index (dev_id, disk_id, sector); - cache = grub_disk_cache_table + cache_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; - } -} - -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_disk_addr_t aligned_sector; - - grub_dprintf ("disk", "Writing `%s'...\n", disk->name); - - if (grub_disk_adjust_range (disk, §or, &offset, size) != GRUB_ERR_NONE) - return -1; - - aligned_sector = (sector & ~((1ULL << (disk->log_sector_size - - GRUB_DISK_SECTOR_BITS)) - 1)); - real_offset = offset + ((sector - aligned_sector) << GRUB_DISK_SECTOR_BITS); - sector = aligned_sector; - - while (size) - { - if (real_offset != 0 || (size < (1U << disk->log_sector_size) - && size != 0)) - { - char *tmp_buf; - grub_size_t len; - grub_partition_t part; - - tmp_buf = grub_malloc (1U << disk->log_sector_size); - if (!tmp_buf) - return grub_errno; - - part = disk->partition; - disk->partition = 0; - if (grub_disk_read (disk, sector, - 0, (1U << disk->log_sector_size), tmp_buf) - != GRUB_ERR_NONE) - { - disk->partition = part; - grub_free (tmp_buf); - goto finish; - } - disk->partition = part; - - len = (1U << disk->log_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->disk_write) (disk, grub_disk_to_native_sector (disk, sector), - 1, tmp_buf) != GRUB_ERR_NONE) - { - grub_free (tmp_buf); - goto finish; - } - - grub_free (tmp_buf); - - sector += (1U << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); - buf = (const char *) buf + len; - size -= len; - real_offset = 0; - } - else - { - grub_size_t len; - grub_size_t n; - - len = size & ~((1ULL << disk->log_sector_size) - 1); - n = size >> disk->log_sector_size; - - if (n > (disk->max_agglomerate - << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS - - disk->log_sector_size))) - n = (disk->max_agglomerate - << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS - - disk->log_sector_size)); - - if ((disk->dev->disk_write) (disk, grub_disk_to_native_sector (disk, sector), - n, buf) != GRUB_ERR_NONE) - goto finish; - - while (n--) - { - grub_disk_cache_invalidate (disk->dev->id, disk->id, sector); - sector += (1U << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); - } - - buf = (const char *) buf + len; - size -= len; - } - } - - finish: - - return grub_errno; -} - -GRUB_MOD_INIT(disk) -{ - grub_disk_write_weak = grub_disk_write; -} - -GRUB_MOD_FINI(disk) -{ - grub_disk_write_weak = NULL; -} diff --git a/grub-core/lib/division.c b/grub-core/lib/division.c deleted file mode 100644 index 35606fea7..000000000 --- a/grub-core/lib/division.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2015 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_uint64_t -abs64(grub_int64_t a) -{ - return a > 0 ? a : -a; -} - -grub_int64_t -grub_divmod64s (grub_int64_t n, - grub_int64_t d, - grub_int64_t *ro) -{ - grub_uint64_t ru; - grub_int64_t q, r; - q = grub_divmod64 (abs64(n), abs64(d), &ru); - r = ru; - /* Now: |n| = |d| * q + r */ - if (n < 0) - { - /* -|n| = |d| * (-q) + (-r) */ - q = -q; - r = -r; - } - /* Now: n = |d| * q + r */ - if (d < 0) - { - /* n = (-|d|) * (-q) + r */ - q = -q; - } - /* Now: n = d * q + r */ - if (ro) - *ro = r; - return q; -} - -grub_uint32_t -grub_divmod32 (grub_uint32_t n, grub_uint32_t d, grub_uint32_t *ro) -{ - grub_uint64_t q, r; - q = grub_divmod64 (n, d, &r); - *ro = r; - return q; -} - -grub_int32_t -grub_divmod32s (grub_int32_t n, grub_int32_t d, grub_int32_t *ro) -{ - grub_int64_t q, r; - q = grub_divmod64s (n, d, &r); - *ro = r; - return q; -} diff --git a/grub-core/lib/dummy/datetime.c b/grub-core/lib/dummy/datetime.c deleted file mode 100644 index cf693fc6b..000000000 --- a/grub-core/lib/dummy/datetime.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* No simple platform-independent RTC access exists in U-Boot. */ - -grub_err_t -grub_get_datetime (struct grub_datetime *datetime __attribute__ ((unused))) -{ - return grub_error (GRUB_ERR_INVALID_COMMAND, - "can\'t get datetime on this machine"); -} - -grub_err_t -grub_set_datetime (struct grub_datetime * datetime __attribute__ ((unused))) -{ - return grub_error (GRUB_ERR_INVALID_COMMAND, - "can\'t set datetime on this machine"); -} diff --git a/grub-core/lib/efi/halt.c b/grub-core/lib/efi/halt.c deleted file mode 100644 index a58a747e5..000000000 --- a/grub-core/lib/efi/halt.c +++ /dev/null @@ -1,41 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -void -grub_halt (void) -{ - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN | - GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY); -#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && \ - !defined(__loongarch__) && !defined(__riscv) - grub_acpi_halt (); -#endif - grub_efi_system_table->runtime_services->reset_system (GRUB_EFI_RESET_SHUTDOWN, - GRUB_EFI_SUCCESS, 0, NULL); - - while (1); -} diff --git a/grub-core/lib/efi/relocator.c b/grub-core/lib/efi/relocator.c deleted file mode 100644 index b4518d000..000000000 --- a/grub-core/lib/efi/relocator.c +++ /dev/null @@ -1,119 +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 . - */ - -#include -#include -#include -#include -#include -#include - -#define NEXT_MEMORY_DESCRIPTOR(desc, size) \ - ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) - -unsigned -grub_relocator_firmware_get_max_events (void) -{ - grub_efi_uintn_t mmapsize = 0, descriptor_size = 0; - grub_efi_uint32_t descriptor_version = 0; - grub_efi_uintn_t key; - grub_efi_get_memory_map (&mmapsize, NULL, &key, &descriptor_size, - &descriptor_version); - /* Since grub_relocator_firmware_fill_events uses malloc - we need some reserve. Hence +10. */ - return 2 * (mmapsize / descriptor_size + 10); -} - -unsigned -grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events) -{ - grub_efi_uintn_t mmapsize = 0, desc_size = 0; - grub_efi_uint32_t descriptor_version = 0; - grub_efi_memory_descriptor_t *descs = NULL; - grub_efi_uintn_t key; - int counter = 0; - grub_efi_memory_descriptor_t *desc; - - grub_efi_get_memory_map (&mmapsize, NULL, &key, &desc_size, - &descriptor_version); - descs = grub_malloc (mmapsize); - if (!descs) - return 0; - - grub_efi_get_memory_map (&mmapsize, descs, &key, &desc_size, - &descriptor_version); - - for (desc = descs; - (char *) desc < ((char *) descs + mmapsize); - desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) - { - grub_uint64_t start = desc->physical_start; - grub_uint64_t end = desc->physical_start + (desc->num_pages << 12); - - /* post-4G addresses are never supported on 32-bit EFI. - Moreover it has been reported that some 64-bit EFI contrary to the - spec don't map post-4G pages. So if you enable post-4G allocations, - map pages manually or check that they are mapped. - */ - if (end >= 0x100000000ULL) - end = 0x100000000ULL; - if (end <= start) - continue; - if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY) - continue; - events[counter].type = REG_FIRMWARE_START; - events[counter].pos = start; - counter++; - events[counter].type = REG_FIRMWARE_END; - events[counter].pos = end; - counter++; - } - - return counter; -} - -int -grub_relocator_firmware_alloc_region (grub_addr_t start, grub_size_t size) -{ - grub_efi_boot_services_t *b; - grub_efi_physical_address_t address = start; - grub_efi_status_t status; - - if (grub_efi_is_finished) - return 1; -#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF - grub_dprintf ("relocator", "EFI alloc: %llx, %llx\n", - (unsigned long long) start, (unsigned long long) size); -#endif - b = grub_efi_system_table->boot_services; - status = b->allocate_pages (GRUB_EFI_ALLOCATE_ADDRESS, - GRUB_EFI_LOADER_DATA, size >> 12, &address); - return (status == GRUB_EFI_SUCCESS); -} - -void -grub_relocator_firmware_free_region (grub_addr_t start, grub_size_t size) -{ - grub_efi_boot_services_t *b; - - if (grub_efi_is_finished) - return; - - b = grub_efi_system_table->boot_services; - b->free_pages (start, size >> 12); -} diff --git a/grub-core/lib/efi/tcg2.c b/grub-core/lib/efi/tcg2.c deleted file mode 100644 index 841bf50bb..000000000 --- a/grub-core/lib/efi/tcg2.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -#include - -static grub_err_t -tcg2_get_caps (grub_efi_tpm2_protocol_t *protocol, int *tpm2, grub_size_t *max_output_size) -{ - grub_efi_status_t status; - static bool has_caps = 0; - static EFI_TCG2_BOOT_SERVICE_CAPABILITY caps = - { - .Size = (grub_uint8_t) sizeof (caps) - }; - - if (has_caps) - goto exit; - - status = protocol->get_capability (protocol, &caps); - if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag) - return GRUB_ERR_FILE_NOT_FOUND; - - has_caps = 1; - - exit: - if (tpm2 != NULL) - *tpm2 = caps.TPMPresentFlag; - if (max_output_size != NULL) - *max_output_size = caps.MaxResponseSize; - - return GRUB_ERR_NONE; -} - -static grub_err_t -tcg2_get_protocol (grub_efi_tpm2_protocol_t **protocol) -{ - static grub_guid_t tpm2_guid = EFI_TPM2_GUID; - static grub_efi_tpm2_protocol_t *tpm2_protocol = NULL; - int tpm2; - grub_efi_handle_t *handles; - grub_efi_uintn_t num_handles; - grub_efi_handle_t tpm2_handle; - grub_err_t err = GRUB_ERR_FILE_NOT_FOUND; - - if (tpm2_protocol != NULL) - { - *protocol = tpm2_protocol; - return GRUB_ERR_NONE; - } - - handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL, - &num_handles); - if (handles == NULL || num_handles == 0) - return err; - - tpm2_handle = handles[0]; - - tpm2_protocol = grub_efi_open_protocol (tpm2_handle, &tpm2_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (tpm2_protocol == NULL) - goto exit; - - err = tcg2_get_caps (tpm2_protocol, &tpm2, NULL); - if (err != GRUB_ERR_NONE || tpm2 == 0) - goto exit; - - *protocol = tpm2_protocol; - err = GRUB_ERR_NONE; - - exit: - grub_free (handles); - return err; -} - -grub_err_t -grub_tcg2_get_max_output_size (grub_size_t *size) -{ - grub_err_t err; - grub_size_t max; - grub_efi_tpm2_protocol_t *protocol; - - if (size == NULL) - return GRUB_ERR_BAD_ARGUMENT; - - err = tcg2_get_protocol (&protocol); - if (err != GRUB_ERR_NONE) - return err; - - err = tcg2_get_caps (protocol, NULL, &max); - if (err != GRUB_ERR_NONE) - return err; - - *size = max; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_tcg2_submit_command (grub_size_t input_size, - grub_uint8_t *input, - grub_size_t output_size, - grub_uint8_t *output) -{ - grub_err_t err; - grub_efi_status_t status; - grub_efi_tpm2_protocol_t *protocol; - - if (input_size == 0 || input == NULL || - output_size == 0 || output == NULL) - return GRUB_ERR_BAD_ARGUMENT; - - err = tcg2_get_protocol (&protocol); - if (err != GRUB_ERR_NONE) - return err; - - status = protocol->submit_command (protocol, input_size, input, - output_size, output); - if (status != GRUB_EFI_SUCCESS) - return GRUB_ERR_INVALID_COMMAND; - - return GRUB_ERR_NONE; -} diff --git a/grub-core/lib/fake_module.c b/grub-core/lib/fake_module.c deleted file mode 100644 index 3646cedbc..000000000 --- a/grub-core/lib/fake_module.c +++ /dev/null @@ -1,4 +0,0 @@ -/* This file is intentionally empty: it's used to generate modules with no code or data. (purely dependency modules) */ -#include - -GRUB_MOD_LICENSE ("GPLv3+"); diff --git a/grub-core/lib/fdt.c b/grub-core/lib/fdt.c deleted file mode 100644 index 73cfa94a2..000000000 --- a/grub-core/lib/fdt.c +++ /dev/null @@ -1,531 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define FDT_SUPPORTED_VERSION 17 - -#define FDT_BEGIN_NODE 0x00000001 -#define FDT_END_NODE 0x00000002 -#define FDT_PROP 0x00000003 -#define FDT_NOP 0x00000004 -#define FDT_END 0x00000009 - -#define struct_end(fdt) \ - ((grub_addr_t) fdt + grub_fdt_get_off_dt_struct(fdt) \ - + grub_fdt_get_size_dt_struct(fdt)) - -/* Size needed by a node entry: 2 tokens (FDT_BEGIN_NODE and FDT_END_NODE), plus - the NULL-terminated string containing the name, plus padding if needed. */ -#define node_entry_size(node_name) \ - (2 * sizeof(grub_uint32_t) \ - + ALIGN_UP (grub_strlen (name) + 1, sizeof(grub_uint32_t))) - -#define SKIP_NODE_NAME(name, token, end) \ - name = (char *) ((token) + 1); \ - while (name < (char *) end) \ - { \ - if (!*name++) \ - break; \ - } \ - token = (grub_uint32_t *) ALIGN_UP((grub_addr_t) (name), sizeof(*token)) - - -static grub_uint32_t *get_next_node (const void *fdt, char *node_name) -{ - grub_uint32_t *end = (void *) struct_end (fdt); - grub_uint32_t *token; - - if (node_name >= (char *) end) - return NULL; - while (*node_name++) - { - if (node_name >= (char *) end) - return NULL; - } - token = (grub_uint32_t *) ALIGN_UP ((grub_addr_t) node_name, 4); - while (token < end) - { - switch (grub_be_to_cpu32(*token)) - { - case FDT_BEGIN_NODE: - token = get_next_node (fdt, (char *) (token + 1)); - if (!token) - return NULL; - break; - case FDT_END_NODE: - token++; - if (token >= end) - return NULL; - return token; - case FDT_PROP: - /* Skip property token and following data (len, nameoff and property - value). */ - token += grub_fdt_prop_entry_size(grub_be_to_cpu32(*(token + 1))) - / sizeof(*token); - break; - case FDT_NOP: - token++; - break; - default: - return NULL; - } - } - return NULL; -} - -static int get_mem_rsvmap_size (const void *fdt) -{ - int size = 0; - grub_unaligned_uint64_t *ptr = (void *) ((grub_addr_t) fdt - + grub_fdt_get_off_mem_rsvmap (fdt)); - - do - { - size += 2 * sizeof(*ptr); - if (!ptr[0].val && !ptr[1].val) - return size; - ptr += 2; - } while ((grub_addr_t) ptr <= (grub_addr_t) fdt + grub_fdt_get_totalsize (fdt) - - 2 * sizeof(grub_uint64_t)); - return -1; -} - -static grub_uint32_t get_free_space (void *fdt) -{ - int mem_rsvmap_size = get_mem_rsvmap_size (fdt); - - if (mem_rsvmap_size < 0) - /* invalid memory reservation block */ - return 0; - return (grub_fdt_get_totalsize (fdt) - sizeof(grub_fdt_header_t) - - mem_rsvmap_size - grub_fdt_get_size_dt_strings (fdt) - - grub_fdt_get_size_dt_struct (fdt)); -} - -static int add_subnode (void *fdt, int parentoffset, const char *name) -{ - grub_uint32_t *token = (void *) ((grub_addr_t) fdt - + grub_fdt_get_off_dt_struct(fdt) - + parentoffset); - grub_uint32_t *end = (void *) struct_end (fdt); - unsigned int entry_size = node_entry_size (name); - unsigned int struct_size = grub_fdt_get_size_dt_struct(fdt); - char *node_name; - - SKIP_NODE_NAME(node_name, token, end); - - /* Insert the new subnode just after the properties of the parent node (if - any).*/ - while (1) - { - if (token >= end) - return -1; - switch (grub_be_to_cpu32(*token)) - { - case FDT_PROP: - /* Skip len, nameoff and property value. */ - token += grub_fdt_prop_entry_size(grub_be_to_cpu32(*(token + 1))) - / sizeof(*token); - break; - case FDT_BEGIN_NODE: - case FDT_END_NODE: - goto insert; - case FDT_NOP: - token++; - break; - default: - /* invalid token */ - return -1; - } - } -insert: - grub_memmove (token + entry_size / sizeof(*token), token, - (grub_addr_t) end - (grub_addr_t) token); - *token = grub_cpu_to_be32_compile_time(FDT_BEGIN_NODE); - token[entry_size / sizeof(*token) - 2] = 0; /* padding bytes */ - grub_strcpy((char *) (token + 1), name); - token[entry_size / sizeof(*token) - 1] = grub_cpu_to_be32_compile_time(FDT_END_NODE); - grub_fdt_set_size_dt_struct (fdt, struct_size + entry_size); - return ((grub_addr_t) token - (grub_addr_t) fdt - - grub_fdt_get_off_dt_struct(fdt)); -} - -/* Rearrange FDT blocks in the canonical order: first the memory reservation - block (just after the FDT header), then the structure block and finally the - strings block. No free space is left between the first and the second block, - while the space between the second and the third block is given by the - clearance argument. */ -static int rearrange_blocks (void *fdt, unsigned int clearance) -{ - grub_uint32_t off_mem_rsvmap = ALIGN_UP(sizeof(grub_fdt_header_t), 8); - grub_uint32_t off_dt_struct = off_mem_rsvmap + get_mem_rsvmap_size (fdt); - grub_uint32_t off_dt_strings = off_dt_struct - + grub_fdt_get_size_dt_struct (fdt) - + clearance; - grub_uint8_t *fdt_ptr = fdt; - grub_uint8_t *tmp_fdt; - - if ((grub_fdt_get_off_mem_rsvmap (fdt) == off_mem_rsvmap) - && (grub_fdt_get_off_dt_struct (fdt) == off_dt_struct)) - { - /* No need to allocate memory for a temporary FDT, just move the strings - block if needed. */ - if (grub_fdt_get_off_dt_strings (fdt) != off_dt_strings) - { - grub_memmove(fdt_ptr + off_dt_strings, - fdt_ptr + grub_fdt_get_off_dt_strings (fdt), - grub_fdt_get_size_dt_strings (fdt)); - grub_fdt_set_off_dt_strings (fdt, off_dt_strings); - } - return 0; - } - tmp_fdt = grub_malloc (grub_fdt_get_totalsize (fdt)); - if (!tmp_fdt) - return -1; - grub_memcpy (tmp_fdt + off_mem_rsvmap, - fdt_ptr + grub_fdt_get_off_mem_rsvmap (fdt), - get_mem_rsvmap_size (fdt)); - grub_fdt_set_off_mem_rsvmap (fdt, off_mem_rsvmap); - grub_memcpy (tmp_fdt + off_dt_struct, - fdt_ptr + grub_fdt_get_off_dt_struct (fdt), - grub_fdt_get_size_dt_struct (fdt)); - grub_fdt_set_off_dt_struct (fdt, off_dt_struct); - grub_memcpy (tmp_fdt + off_dt_strings, - fdt_ptr + grub_fdt_get_off_dt_strings (fdt), - grub_fdt_get_size_dt_strings (fdt)); - grub_fdt_set_off_dt_strings (fdt, off_dt_strings); - - /* Copy reordered blocks back to fdt. */ - grub_memcpy (fdt_ptr + off_mem_rsvmap, tmp_fdt + off_mem_rsvmap, - grub_fdt_get_totalsize (fdt) - off_mem_rsvmap); - - grub_free(tmp_fdt); - return 0; -} - -static grub_uint32_t *find_prop (const void *fdt, unsigned int nodeoffset, - const char *name) -{ - grub_uint32_t *prop = (void *) ((grub_addr_t) fdt - + grub_fdt_get_off_dt_struct (fdt) - + nodeoffset); - grub_uint32_t *end = (void *) struct_end(fdt); - grub_uint32_t nameoff; - char *node_name; - - SKIP_NODE_NAME(node_name, prop, end); - while (prop < end - 2) - { - if (grub_be_to_cpu32(*prop) == FDT_PROP) - { - nameoff = grub_be_to_cpu32(*(prop + 2)); - if ((nameoff + grub_strlen (name) < grub_fdt_get_size_dt_strings (fdt)) - && !grub_strcmp (name, (char *) fdt + - grub_fdt_get_off_dt_strings (fdt) + nameoff)) - { - if (prop + grub_fdt_prop_entry_size(grub_be_to_cpu32(*(prop + 1))) - / sizeof (*prop) >= end) - return NULL; - return prop; - } - prop += grub_fdt_prop_entry_size(grub_be_to_cpu32(*(prop + 1))) / sizeof (*prop); - } - else if (grub_be_to_cpu32(*prop) == FDT_NOP) - prop++; - else - return NULL; - } - return NULL; -} - -/* Check the FDT header for consistency and adjust the totalsize field to match - the size allocated for the FDT; if this function is called before the other - functions in this file and returns success, the other functions are - guaranteed not to access memory locations outside the allocated memory. */ -int grub_fdt_check_header_nosize (const void *fdt) -{ - if (((grub_addr_t) fdt & 0x3) || (grub_fdt_get_magic (fdt) != FDT_MAGIC) - || (grub_fdt_get_version (fdt) < FDT_SUPPORTED_VERSION) - || (grub_fdt_get_last_comp_version (fdt) > FDT_SUPPORTED_VERSION) - || (grub_fdt_get_off_dt_struct (fdt) & 0x00000003) - || (grub_fdt_get_size_dt_struct (fdt) & 0x00000003) - || (grub_fdt_get_off_dt_struct (fdt) + grub_fdt_get_size_dt_struct (fdt) - > grub_fdt_get_totalsize (fdt)) - || (grub_fdt_get_off_dt_strings (fdt) + grub_fdt_get_size_dt_strings (fdt) - > grub_fdt_get_totalsize (fdt)) - || (grub_fdt_get_off_mem_rsvmap (fdt) & 0x00000007) - || (grub_fdt_get_off_mem_rsvmap (fdt) - > grub_fdt_get_totalsize (fdt) - 2 * sizeof(grub_uint64_t))) - return -1; - return 0; -} - -int grub_fdt_check_header (const void *fdt, unsigned int size) -{ - if (size < sizeof (grub_fdt_header_t) - || (grub_fdt_get_totalsize (fdt) > size) - || grub_fdt_check_header_nosize (fdt) == -1) - return -1; - return 0; -} - -static const grub_uint32_t * -advance_token (const void *fdt, const grub_uint32_t *token, const grub_uint32_t *end, int skip_current) -{ - for (; token < end; skip_current = 0) - { - switch (grub_be_to_cpu32 (*token)) - { - case FDT_BEGIN_NODE: - if (skip_current) - { - token = get_next_node (fdt, (char *) (token + 1)); - continue; - } - char *ptr; - for (ptr = (char *) (token + 1); *ptr && ptr < (char *) end; ptr++) - ; - if (ptr >= (char *) end) - return 0; - return token; - case FDT_PROP: - /* Skip property token and following data (len, nameoff and property - value). */ - if (token >= end - 1) - return 0; - token += grub_fdt_prop_entry_size(grub_be_to_cpu32(*(token + 1))) - / sizeof(*token); - break; - case FDT_NOP: - token++; - break; - default: - return 0; - } - } - return 0; -} - -int grub_fdt_next_node (const void *fdt, unsigned int currentoffset) -{ - const grub_uint32_t *token = (const grub_uint32_t *) fdt + (currentoffset + grub_fdt_get_off_dt_struct (fdt)) / 4; - token = advance_token (fdt, token, (const void *) struct_end (fdt), 1); - if (!token) - return -1; - return (int) ((grub_addr_t) token - (grub_addr_t) fdt - - grub_fdt_get_off_dt_struct (fdt)); -} - -int grub_fdt_first_node (const void *fdt, unsigned int parentoffset) -{ - const grub_uint32_t *token, *end; - char *node_name; - - if (parentoffset & 0x3) - return -1; - token = (const void *) ((grub_addr_t) fdt + grub_fdt_get_off_dt_struct(fdt) - + parentoffset); - end = (const void *) struct_end (fdt); - if ((token >= end) || (grub_be_to_cpu32(*token) != FDT_BEGIN_NODE)) - return -1; - SKIP_NODE_NAME(node_name, token, end); - token = advance_token (fdt, token, end, 0); - if (!token) - return -1; - return (int) ((grub_addr_t) token - (grub_addr_t) fdt - - grub_fdt_get_off_dt_struct (fdt)); -} - -/* Find a direct sub-node of a given parent node. */ -int grub_fdt_find_subnode (const void *fdt, unsigned int parentoffset, - const char *name) -{ - const grub_uint32_t *token, *end; - const char *node_name; - int skip_current = 0; - - if (parentoffset & 0x3) - return -1; - token = (const void *) ((grub_addr_t) fdt + grub_fdt_get_off_dt_struct(fdt) - + parentoffset); - end = (const void *) struct_end (fdt); - if ((token >= end) || (grub_be_to_cpu32(*token) != FDT_BEGIN_NODE)) - return -1; - SKIP_NODE_NAME(node_name, token, end); - while (1) { - token = advance_token (fdt, token, end, skip_current); - if (!token) - return -1; - skip_current = 1; - node_name = (const char *) token + 4; - if (grub_strcmp (node_name, name) == 0) - return (int) ((grub_addr_t) token - (grub_addr_t) fdt - - grub_fdt_get_off_dt_struct (fdt)); - } -} - -const char * -grub_fdt_get_nodename (const void *fdt, unsigned int nodeoffset) -{ - return (const char *) fdt + grub_fdt_get_off_dt_struct(fdt) + nodeoffset + 4; -} - -int grub_fdt_add_subnode (void *fdt, unsigned int parentoffset, - const char *name) -{ - unsigned int entry_size = node_entry_size(name); - - if ((parentoffset & 0x3) || (get_free_space (fdt) < entry_size)) - return -1; - - /* The new node entry will increase the size of the structure block: rearrange - blocks such that there is sufficient free space between the structure and - the strings block, then add the new node entry. */ - if (rearrange_blocks (fdt, entry_size) < 0) - return -1; - return add_subnode (fdt, parentoffset, name); -} - -const void * -grub_fdt_get_prop (const void *fdt, unsigned int nodeoffset, const char *name, - grub_uint32_t *len) -{ - grub_uint32_t *prop; - if ((nodeoffset >= grub_fdt_get_size_dt_struct (fdt)) || (nodeoffset & 0x3) - || (grub_be_to_cpu32(*(grub_uint32_t *) ((grub_addr_t) fdt - + grub_fdt_get_off_dt_struct (fdt) + nodeoffset)) - != FDT_BEGIN_NODE)) - return 0; - prop = find_prop (fdt, nodeoffset, name); - if (!prop) - return 0; - if (len) - *len = grub_be_to_cpu32 (*(prop + 1)); - return prop + 3; -} - -int grub_fdt_set_prop (void *fdt, unsigned int nodeoffset, const char *name, - const void *val, grub_uint32_t len) -{ - grub_uint32_t *prop; - int prop_name_present = 0; - grub_uint32_t nameoff = 0; - - if ((nodeoffset >= grub_fdt_get_size_dt_struct (fdt)) || (nodeoffset & 0x3) - || (grub_be_to_cpu32(*(grub_uint32_t *) ((grub_addr_t) fdt - + grub_fdt_get_off_dt_struct (fdt) + nodeoffset)) - != FDT_BEGIN_NODE)) - return -1; - prop = find_prop (fdt, nodeoffset, name); - if (prop) - { - grub_uint32_t prop_len = ALIGN_UP(grub_be_to_cpu32 (*(prop + 1)), - sizeof(grub_uint32_t)); - grub_uint32_t i; - - prop_name_present = 1; - for (i = 0; i < prop_len / sizeof(grub_uint32_t); i++) - *(prop + 3 + i) = grub_cpu_to_be32_compile_time (FDT_NOP); - if (len > ALIGN_UP(prop_len, sizeof(grub_uint32_t))) - { - /* Length of new property value is greater than the space allocated - for the current value: a new entry needs to be created, so save the - nameoff field of the current entry and replace the current entry - with NOP tokens. */ - nameoff = grub_be_to_cpu32 (*(prop + 2)); - *prop = *(prop + 1) = *(prop + 2) = grub_cpu_to_be32_compile_time (FDT_NOP); - prop = NULL; - } - } - if (!prop || !prop_name_present) { - unsigned int needed_space = 0; - - if (!prop) - needed_space = grub_fdt_prop_entry_size(len); - if (!prop_name_present) - needed_space += grub_strlen (name) + 1; - if (needed_space > get_free_space (fdt)) - return -1; - if (rearrange_blocks (fdt, !prop ? grub_fdt_prop_entry_size(len) : 0) < 0) - return -1; - } - if (!prop_name_present) { - /* Append the property name at the end of the strings block. */ - nameoff = grub_fdt_get_size_dt_strings (fdt); - grub_strcpy ((char *) fdt + grub_fdt_get_off_dt_strings (fdt) + nameoff, - name); - grub_fdt_set_size_dt_strings (fdt, grub_fdt_get_size_dt_strings (fdt) - + grub_strlen (name) + 1); - } - if (!prop) { - char *node_name = (char *) ((grub_addr_t) fdt - + grub_fdt_get_off_dt_struct (fdt) + nodeoffset - + sizeof(grub_uint32_t)); - - prop = (void *) (node_name + ALIGN_UP(grub_strlen(node_name) + 1, 4)); - grub_memmove (prop + grub_fdt_prop_entry_size(len) / sizeof(*prop), prop, - struct_end(fdt) - (grub_addr_t) prop); - grub_fdt_set_size_dt_struct (fdt, grub_fdt_get_size_dt_struct (fdt) - + grub_fdt_prop_entry_size(len)); - *prop = grub_cpu_to_be32_compile_time (FDT_PROP); - *(prop + 2) = grub_cpu_to_be32 (nameoff); - } - *(prop + 1) = grub_cpu_to_be32 (len); - - /* Insert padding bytes at the end of the value; if they are not needed, they - will be overwritten by the following memcpy. */ - *(prop + grub_fdt_prop_entry_size(len) / sizeof(grub_uint32_t) - 1) = 0; - - grub_memcpy (prop + 3, val, len); - return 0; -} - -int -grub_fdt_create_empty_tree (void *fdt, unsigned int size) -{ - struct grub_fdt_empty_tree *et; - - if (size < GRUB_FDT_EMPTY_TREE_SZ) - return -1; - - grub_memset (fdt, 0, size); - et = fdt; - - et->empty_node.tree_end = grub_cpu_to_be32_compile_time (FDT_END); - et->empty_node.node_end = grub_cpu_to_be32_compile_time (FDT_END_NODE); - et->empty_node.node_start = grub_cpu_to_be32_compile_time (FDT_BEGIN_NODE); - ((struct grub_fdt_empty_tree *) fdt)->header.off_mem_rsvmap = - grub_cpu_to_be32_compile_time (ALIGN_UP (sizeof (grub_fdt_header_t), 8)); - - grub_fdt_set_off_dt_strings (fdt, sizeof (*et)); - grub_fdt_set_off_dt_struct (fdt, - sizeof (et->header) + sizeof (et->empty_rsvmap)); - grub_fdt_set_version (fdt, FDT_SUPPORTED_VERSION); - grub_fdt_set_last_comp_version (fdt, FDT_SUPPORTED_VERSION); - grub_fdt_set_size_dt_struct (fdt, sizeof (et->empty_node)); - grub_fdt_set_totalsize (fdt, size); - grub_fdt_set_magic (fdt, FDT_MAGIC); - - return 0; -} diff --git a/grub-core/lib/getline.c b/grub-core/lib/getline.c deleted file mode 100644 index edb8e9ffe..000000000 --- a/grub-core/lib/getline.c +++ /dev/null @@ -1,92 +0,0 @@ -/* main.c - the normal mode main routine */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000,2001,2002,2003,2005,2006,2007,2008,2009,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Read a line from the file FILE. */ -char * -grub_file_getline (grub_file_t file) -{ - char c; - grub_size_t pos = 0; - char *cmdline; - int have_newline = 0; - grub_size_t 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; - - - if (pos + 1 >= 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') - { - have_newline = 1; - break; - } - - cmdline[pos++] = c; - } - - cmdline[pos] = '\0'; - - /* If the buffer is empty, don't return anything at all. */ - if (pos == 0 && !have_newline) - { - grub_free (cmdline); - cmdline = 0; - } - - return cmdline; -} diff --git a/grub-core/lib/gnulib-patches/fix-gcc-15-compile.patch b/grub-core/lib/gnulib-patches/fix-gcc-15-compile.patch deleted file mode 100644 index 287332ea0..000000000 --- a/grub-core/lib/gnulib-patches/fix-gcc-15-compile.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/lib/base64.c -+++ b/lib/base64.c -@@ -61,7 +61,7 @@ - return ch; - } - --static const char b64c[64] = -+static const char b64c[64] _GL_ATTRIBUTE_NONSTRING = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - /* Base64 encode IN array of size INLEN into OUT array. OUT needs diff --git a/grub-core/lib/gnulib-patches/fix-regcomp-resource-leak.patch b/grub-core/lib/gnulib-patches/fix-regcomp-resource-leak.patch deleted file mode 100644 index b2e900023..000000000 --- a/grub-core/lib/gnulib-patches/fix-regcomp-resource-leak.patch +++ /dev/null @@ -1,110 +0,0 @@ ---- a/lib/regcomp.c -+++ b/lib/regcomp.c -@@ -1001,21 +1001,25 @@ create_initial_state (re_dfa_t *dfa) - Idx dest_idx = dfa->edests[node_idx].elems[0]; - if (!re_node_set_contains (&init_nodes, dest_idx)) - { -- reg_errcode_t merge_err -+ err - = re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx); -- if (merge_err != REG_NOERROR) -- return merge_err; -+ if (err != REG_NOERROR) -+ break; - 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. */ -+ dfa->init_state -+ = (err == REG_NOERROR -+ ? re_acquire_state_context (&err, dfa, &init_nodes, 0) -+ : NULL); - if (__glibc_unlikely (dfa->init_state == NULL)) -- return err; -- if (dfa->init_state->has_constraint) -+ { -+ /* Don't check ERR here, as the initial state must not be null. */ -+ } -+ else if (dfa->init_state->has_constraint) - { - dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes, - CONTEXT_WORD); -@@ -1025,17 +1029,13 @@ create_initial_state (re_dfa_t *dfa) - &init_nodes, - CONTEXT_NEWLINE - | CONTEXT_BEGBUF); -- if (__glibc_unlikely (dfa->init_state_word == NULL -- || dfa->init_state_nl == NULL -- || dfa->init_state_begbuf == NULL)) -- 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; -+ return err; - } - - /* If it is possible to do searching in single byte encoding instead of UTF-8 -@@ -1677,12 +1677,11 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) - { - err = duplicate_node_closure (dfa, node, node, node, - dfa->nodes[node].constraint); -- if (__glibc_unlikely (err != REG_NOERROR)) -- return err; - } - - /* Expand each epsilon destination nodes. */ -- if (IS_EPSILON_NODE(dfa->nodes[node].type)) -+ if (__glibc_likely (err == REG_NOERROR) -+ && IS_EPSILON_NODE (dfa->nodes[node].type)) - for (i = 0; i < dfa->edests[node].nelem; ++i) - { - re_node_set eclosure_elem; -@@ -1700,14 +1699,14 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) - { - err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false); - if (__glibc_unlikely (err != REG_NOERROR)) -- return err; -+ break; - } - else - eclosure_elem = dfa->eclosures[edest]; - /* Merge the epsilon closure of 'edest'. */ - err = re_node_set_merge (&eclosure, &eclosure_elem); - if (__glibc_unlikely (err != REG_NOERROR)) -- return err; -+ break; - /* If the epsilon closure of 'edest' is incomplete, - the epsilon closure of this node is also incomplete. */ - if (dfa->eclosures[edest].nelem == 0) -@@ -1717,12 +1716,18 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) - } - } - -- if (incomplete && !root) -- dfa->eclosures[node].nelem = 0; -+ if (err != REG_NOERROR) -+ re_node_set_free (&eclosure); - else -- dfa->eclosures[node] = eclosure; -- *new_set = eclosure; -- return REG_NOERROR; -+ { -+ if (incomplete && !root) -+ dfa->eclosures[node].nelem = 0; -+ else -+ dfa->eclosures[node] = eclosure; -+ *new_set = eclosure; -+ } -+ -+ return err; - } - - /* Functions for token which are used in the parser. */ diff --git a/grub-core/lib/gnulib-patches/fix-regexec-resource-leak.patch b/grub-core/lib/gnulib-patches/fix-regexec-resource-leak.patch deleted file mode 100644 index f490e05fb..000000000 --- a/grub-core/lib/gnulib-patches/fix-regexec-resource-leak.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/lib/regexec.c -+++ b/lib/regexec.c -@@ -2270,7 +2270,7 @@ merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, - these destinations and the results of the transition table. */ - pstate = mctx->state_log[cur_idx]; - log_nodes = pstate->entrance_nodes; -- if (next_state != NULL) -+ if (next_state != NULL && next_state->entrance_nodes != NULL) - { - table_nodes = next_state->entrance_nodes; - *err = re_node_set_init_union (&next_nodes, table_nodes, diff --git a/grub-core/lib/gnulib-patches/fix-unused-value.patch b/grub-core/lib/gnulib-patches/fix-unused-value.patch deleted file mode 100644 index ba51f1bf2..000000000 --- a/grub-core/lib/gnulib-patches/fix-unused-value.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/lib/regexec.c 2020-10-21 14:25:35.310195912 +0000 -+++ b/lib/regexec.c 2020-10-21 14:32:07.961765604 +0000 -@@ -828,7 +828,11 @@ - break; - if (__glibc_unlikely (err != REG_NOMATCH)) - goto free_return; -+#ifdef DEBUG -+ /* Only used for assertion below when DEBUG is set, otherwise -+ it will be over-written when we loop around. */ - match_last = -1; -+#endif - } - else - break; /* We found a match. */ diff --git a/grub-core/lib/gnulib-patches/fix-width.patch b/grub-core/lib/gnulib-patches/fix-width.patch deleted file mode 100644 index 15f091c0d..000000000 --- a/grub-core/lib/gnulib-patches/fix-width.patch +++ /dev/null @@ -1,217 +0,0 @@ -diff --git a/lib/argp-fmtstream.c b/lib/argp-fmtstream.c -index ba6a407f7..d0685b3d4 100644 ---- a/lib/argp-fmtstream.c -+++ b/lib/argp-fmtstream.c -@@ -28,9 +28,11 @@ - #include - #include - #include -+#include - - #include "argp-fmtstream.h" - #include "argp-namefrob.h" -+#include "mbswidth.h" - - #ifndef ARGP_FMTSTREAM_USE_LINEWRAP - -@@ -115,6 +117,51 @@ weak_alias (__argp_fmtstream_free, argp_fmtstream_free) - #endif - #endif - -+ -+/* Return the pointer to the first character that doesn't fit in l columns. */ -+static inline const ptrdiff_t -+add_width (const char *ptr, const char *end, size_t l) -+{ -+ mbstate_t ps; -+ const char *ptr0 = ptr; -+ -+ memset (&ps, 0, sizeof (ps)); -+ -+ while (ptr < end) -+ { -+ wchar_t wc; -+ size_t s, k; -+ -+ s = mbrtowc (&wc, ptr, end - ptr, &ps); -+ if (s == (size_t) -1) -+ break; -+ if (s == (size_t) -2) -+ { -+ if (1 >= l) -+ break; -+ l--; -+ ptr++; -+ continue; -+ } -+ -+ if (wc == '\e' && ptr + 3 < end -+ && ptr[1] == '[' && (ptr[2] == '0' || ptr[2] == '1') -+ && ptr[3] == 'm') -+ { -+ ptr += 4; -+ continue; -+ } -+ -+ k = wcwidth (wc); -+ -+ if (k >= l) -+ break; -+ l -= k; -+ ptr += s; -+ } -+ return ptr - ptr0; -+} -+ - /* 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 -@@ -168,13 +215,15 @@ __argp_fmtstream_update (argp_fmtstream_t fs) - if (!nl) - { - /* The buffer ends in a partial line. */ -+ size_t display_width = mbsnwidth (buf, fs->p - buf, -+ MBSW_STOP_AT_NUL); - -- if (fs->point_col + len < fs->rmargin) -+ if (fs->point_col + display_width < 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; -+ fs->point_col += display_width; - break; - } - else -@@ -182,14 +231,18 @@ __argp_fmtstream_update (argp_fmtstream_t fs) - 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; -- } -+ else -+ { -+ size_t display_width = mbsnwidth (buf, nl - buf, MBSW_STOP_AT_NUL); -+ if (display_width < (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; -@@ -225,7 +278,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs) - char *p, *nextline; - int i; - -- p = buf + (r + 1 - fs->point_col); -+ p = buf + add_width (buf, fs->p, (r + 1 - fs->point_col)); - while (p >= buf && !isblank ((unsigned char) *p)) - --p; - nextline = p + 1; /* This will begin the next line. */ -@@ -243,7 +296,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs) - { - /* 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); -+ p = buf + add_width (buf, fs->p, (r + 1 - fs->point_col)); - /* Find the end of the long word. */ - if (p < nl) - do -@@ -277,7 +330,8 @@ __argp_fmtstream_update (argp_fmtstream_t fs) - && fs->p > nextline) - { - /* The margin needs more blanks than we removed. */ -- if (fs->end - fs->p > fs->wmargin + 1) -+ if (mbsnwidth (fs->p, fs->end - fs->p, MBSW_STOP_AT_NUL) -+ > fs->wmargin + 1) - /* Make some space for them. */ - { - size_t mv = fs->p - nextline; -diff --git a/lib/argp-help.c b/lib/argp-help.c -index e5375a0f0..5d8f451ec 100644 ---- a/lib/argp-help.c -+++ b/lib/argp-help.c -@@ -52,6 +52,7 @@ - #include "argp.h" - #include "argp-fmtstream.h" - #include "argp-namefrob.h" -+#include "mbswidth.h" - - #ifndef SIZE_MAX - # define SIZE_MAX ((size_t) -1) -@@ -1547,7 +1548,7 @@ argp_args_usage (const struct argp *argp, const struct argp_state *state, - - /* Manually do line wrapping so that it (probably) won't get wrapped at - any embedded spaces. */ -- space (stream, 1 + nl - cp); -+ space (stream, 1 + mbsnwidth (cp, nl - cp, MBSW_STOP_AT_NUL)); - - __argp_fmtstream_write (stream, cp, nl - cp); - } -diff --git a/lib/mbswidth.c b/lib/mbswidth.c -index 408a15e34..b3fb7f83a 100644 ---- a/lib/mbswidth.c -+++ b/lib/mbswidth.c -@@ -38,6 +38,14 @@ - /* Get INT_MAX. */ - #include - -+#ifndef FALLTHROUGH -+# if __GNUC__ < 7 -+# define FALLTHROUGH ((void) 0) -+# else -+# define FALLTHROUGH __attribute__ ((__fallthrough__)) -+# endif -+#endif -+ - /* Returns the number of columns needed to represent the multibyte - character string pointed to by STRING. If a non-printable character - occurs, and MBSW_REJECT_UNPRINTABLE is specified, -1 is returned. -@@ -90,6 +98,10 @@ mbsnwidth (const char *string, size_t nbytes, int flags) - p++; - width++; - break; -+ case '\0': -+ if (flags & MBSW_STOP_AT_NUL) -+ return width; -+ FALLTHROUGH; - default: - /* If we have a multibyte sequence, scan it up to its end. */ - { -@@ -168,6 +180,9 @@ mbsnwidth (const char *string, size_t nbytes, int flags) - { - unsigned char c = (unsigned char) *p++; - -+ if (c == 0 && (flags & MBSW_STOP_AT_NUL)) -+ return width; -+ - if (isprint (c)) - { - if (width == INT_MAX) -diff --git a/lib/mbswidth.h b/lib/mbswidth.h -index 2b5c53c37..45a123e63 100644 ---- a/lib/mbswidth.h -+++ b/lib/mbswidth.h -@@ -40,6 +40,10 @@ extern "C" { - control characters and 1 otherwise. */ - #define MBSW_REJECT_UNPRINTABLE 2 - -+/* If this bit is set \0 is treated as the end of string. -+ Otherwise it's treated as a normal one column width character. */ -+#define MBSW_STOP_AT_NUL 4 -+ - - /* Returns the number of screen columns needed for STRING. */ - #define mbswidth gnu_mbswidth /* avoid clash with UnixWare 7.1.1 function */ diff --git a/grub-core/lib/i386/backtrace.c b/grub-core/lib/i386/backtrace.c deleted file mode 100644 index c3e03c727..000000000 --- a/grub-core/lib/i386/backtrace.c +++ /dev/null @@ -1,66 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -#define MAX_STACK_FRAME 102400 - -void -grub_backtrace_pointer (void *ebp) -{ - void *ptr, *nptr; - unsigned i; - - ptr = ebp; - while (1) - { - grub_printf ("%p: ", ptr); - grub_backtrace_print_address (((void **) ptr)[1]); - grub_printf (" ("); - for (i = 0; i < 2; i++) - grub_printf ("%p,", ((void **)ptr) [i + 2]); - grub_printf ("%p)\n", ((void **)ptr) [i + 2]); - nptr = *(void **)ptr; - if (nptr < ptr || (void **) nptr - (void **) ptr > MAX_STACK_FRAME - || nptr == ptr) - { - grub_printf ("Invalid stack frame at %p (%p)\n", ptr, nptr); - break; - } - ptr = nptr; - } -} - -void -grub_backtrace (void) -{ -#ifdef __x86_64__ - asm volatile ("movq %%rbp, %%rdi\n" - "callq *%%rax": :"a"(grub_backtrace_pointer)); -#else - asm volatile ("movl %%ebp, %%eax\n" - "calll *%%ecx": :"c"(grub_backtrace_pointer)); -#endif -} - diff --git a/grub-core/lib/i386/halt.c b/grub-core/lib/i386/halt.c deleted file mode 100644 index 2364fe4d7..000000000 --- a/grub-core/lib/i386/halt.c +++ /dev/null @@ -1,82 +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 . - */ - -#include -#include -#include -#include -#include -#include - -const char bochs_shutdown[] = "Shutdown"; - -/* - * This call is special... it never returns... in fact it should simply - * hang at this point! - */ -static inline void __attribute__ ((noreturn)) -stop (void) -{ - asm volatile ("cli"); - while (1) - { - asm volatile ("hlt"); - } -} - -static int -grub_shutdown_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, - void *data __attribute__ ((unused))) -{ - /* QEMU. */ - if (pciid == 0x71138086) - { - grub_pci_address_t addr; - addr = grub_pci_make_address (dev, 0x40); - grub_pci_write (addr, 0x7001); - addr = grub_pci_make_address (dev, 0x80); - grub_pci_write (addr, grub_pci_read (addr) | 1); - grub_outw (0x2000, 0x7004); - } - return 0; -} - -void -grub_halt (void) -{ - unsigned int i; - -#if defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) - grub_acpi_halt (); -#endif - - /* Disable interrupts. */ - asm volatile ("cli"); - - /* Bochs, QEMU, etc. Removed in newer QEMU releases. */ - for (i = 0; i < sizeof (bochs_shutdown) - 1; i++) - grub_outb (bochs_shutdown[i], 0x8900); - - grub_pci_iterate (grub_shutdown_pci_iter, NULL); - - grub_puts_ (N_("GRUB doesn't know how to halt this machine yet!")); - - /* 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 ... */ - stop (); -} diff --git a/grub-core/lib/i386/pc/vesa_modes_table.c b/grub-core/lib/i386/pc/vesa_modes_table.c deleted file mode 100644 index 6dc4b7d8d..000000000 --- a/grub-core/lib/i386/pc/vesa_modes_table.c +++ /dev/null @@ -1,127 +0,0 @@ - -#include - -/* 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 grub_vesa_mode_table_entry -grub_vesa_mode_table[GRUB_VESA_MODE_TABLE_END - - GRUB_VESA_MODE_TABLE_START + 1] = - { - { 640, 400, 8 }, /* 0x300 */ - { 640, 480, 8 }, /* 0x301 */ - { 800, 600, 4 }, /* 0x302 */ - { 800, 600, 8 }, /* 0x303 */ - { 1024, 768, 4 }, /* 0x304 */ - { 1024, 768, 8 }, /* 0x305 */ - { 1280, 1024, 4 }, /* 0x306 */ - { 1280, 1024, 8 }, /* 0x307 */ - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 320, 200, 15 }, /* 0x30d */ - { 320, 200, 16 }, /* 0x30e */ - { 320, 200, 24 }, /* 0x30f */ - { 640, 480, 15 }, /* 0x310 */ - { 640, 480, 16 }, /* 0x311 */ - { 640, 480, 24 }, /* 0x312 */ - { 800, 600, 15 }, /* 0x313 */ - { 800, 600, 16 }, /* 0x314 */ - { 800, 600, 24 }, /* 0x315 */ - { 1024, 768, 15 }, /* 0x316 */ - { 1024, 768, 16 }, /* 0x317 */ - { 1024, 768, 24 }, /* 0x318 */ - { 1280, 1024, 15 }, /* 0x319 */ - { 1280, 1024, 16 }, /* 0x31a */ - { 1280, 1024, 24 }, /* 0x31b */ - { 1600, 1200, 8 }, /* 0x31c */ - { 1600, 1200, 15 }, /* 0x31d */ - { 1600, 1200, 16 }, /* 0x31e */ - { 1600, 1200, 24 }, /* 0x31f */ - { 0, 0, 0 }, - { 640, 400, 15 }, /* 0x321 */ - { 640, 400, 16 }, /* 0x322 */ - { 640, 400, 24 }, /* 0x323 */ - { 640, 400, 32 }, /* 0x324 */ - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 640, 480, 32 }, /* 0x329 */ - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 896, 672, 8 }, /* 0x32f */ - { 896, 672, 15 }, /* 0x330 */ - { 896, 672, 16 }, /* 0x331 */ - { 896, 672, 24 }, /* 0x332 */ - { 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, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 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, 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 }, - { 1440, 900, 8 }, /* 0x360 */ - { 1440, 900, 15 }, /* 0x361 */ - { 1440, 900, 16 }, /* 0x362 */ - { 1440, 900, 24 }, /* 0x363 */ - { 1440, 900, 32 }, /* 0x364 */ - { 1152, 720, 8 }, /* 0x365 */ - { 1152, 720, 15 }, /* 0x366 */ - { 1152, 720, 16 }, /* 0x367 */ - { 1152, 720, 24 }, /* 0x368 */ - { 1152, 720, 32 }, /* 0x369 */ - { 1024, 640, 8 }, /* 0x36a */ - { 1024, 640, 15 }, /* 0x36b */ - { 1024, 640, 16 }, /* 0x36c */ - { 1024, 640, 24 }, /* 0x36d */ - { 1024, 640, 32 }, /* 0x36e */ - { 800, 500, 8 }, /* 0x36f */ - { 800, 500, 15 }, /* 0x370 */ - { 800, 500, 16 }, /* 0x371 */ - { 800, 500, 24 }, /* 0x372 */ - { 800, 500, 32 }, /* 0x373 */ - }; diff --git a/grub-core/lib/i386/random.c b/grub-core/lib/i386/random.c deleted file mode 100644 index cd83d2f8f..000000000 --- a/grub-core/lib/i386/random.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2016 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include - -static int have_tsc = -1, have_pmtimer = -1; -static grub_port_t pmtimer_port; - -static int -detect_pmtimer (void) -{ - struct grub_acpi_fadt *fadt; - fadt = grub_acpi_find_fadt (); - if (!fadt) - return 0; - pmtimer_port = fadt->pmtimer; - if (!pmtimer_port) - return 0; - return 1; -} - -static int -pmtimer_tsc_get_random_bit (void) -{ - /* It's hard to come up with figures about pmtimer and tsc jitter but - 50 ppm seems to be typical. So we need 10^6/50 tsc cycles to get drift - of one tsc cycle. With TSC at least of 800 MHz it means 1/(50*800) - = 1/40000 s or about 3579545 / 40000 = 90 pmtimer ticks. - This gives us rate of 40000 bit/s or 5 kB/s. - */ - grub_uint64_t tsc_diff; - tsc_diff = grub_pmtimer_wait_count_tsc (pmtimer_port, 90); - if (tsc_diff == 0) - { - have_pmtimer = 0; - return -1; - } - return tsc_diff & 1; -} - -static int -pmtimer_tsc_get_random_byte (void) -{ - grub_uint8_t ret = 0; - int i, c; - for (i = 0; i < 8; i++) - { - c = pmtimer_tsc_get_random_bit (); - if (c < 0) - return -1; - ret |= c << i; - } - return ret; -} - -static int -pmtimer_fill_buffer (void *buffer, grub_size_t sz) -{ - grub_uint8_t *p = buffer; - int c; - while (sz) - { - c = pmtimer_tsc_get_random_byte (); - if (c < 0) - return 0; - *p++ = c; - sz--; - } - return 1; -} - -int -grub_crypto_arch_get_random (void *buffer, grub_size_t sz) -{ - if (have_tsc == -1) - have_tsc = grub_cpu_is_tsc_supported (); - if (!have_tsc) - return 0; - if (have_pmtimer == -1) - have_pmtimer = detect_pmtimer (); - if (!have_pmtimer) - return 0; - return pmtimer_fill_buffer (buffer, sz); -} diff --git a/grub-core/lib/i386/reboot.c b/grub-core/lib/i386/reboot.c deleted file mode 100644 index d0fd6a50e..000000000 --- a/grub-core/lib/i386/reboot.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_MACHINE_EFI - -#include -#include -#include -#include -#include -#include - -void -grub_reboot (void) -{ - struct grub_relocator *relocator = NULL; - grub_relocator_chunk_t ch; - grub_err_t err; - void *buf; - struct grub_relocator16_state state; - grub_uint16_t segment; - - relocator = grub_relocator_new (); - if (!relocator) - while (1); - err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000, 0x1000, - grub_reboot_end - grub_reboot_start, - 16, GRUB_RELOCATOR_PREFERENCE_NONE, - 0); - if (err) - while (1); - buf = get_virtual_current_address (ch); - grub_memcpy (buf, grub_reboot_start, grub_reboot_end - grub_reboot_start); - - segment = ((grub_addr_t) get_physical_target_address (ch)) >> 4; - state.gs = state.fs = state.es = state.ds = state.ss = segment; - state.sp = 0; - state.cs = segment; - state.ip = 0; - state.a20 = 0; - - grub_stop_floppy (); - - err = grub_relocator16_boot (relocator, state); - - while (1); -} - -#endif /* GRUB_MACHINE_EFI */ diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c deleted file mode 100644 index 54a1dcd8b..000000000 --- a/grub-core/lib/i386/relocator.c +++ /dev/null @@ -1,210 +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 . - */ - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -extern grub_uint8_t grub_relocator16_start; -extern grub_uint8_t grub_relocator16_end; -extern grub_uint16_t grub_relocator16_cs; -extern grub_uint16_t grub_relocator16_ip; -extern grub_uint16_t grub_relocator16_ds; -extern grub_uint16_t grub_relocator16_es; -extern grub_uint16_t grub_relocator16_fs; -extern grub_uint16_t grub_relocator16_gs; -extern grub_uint16_t grub_relocator16_ss; -extern grub_uint16_t grub_relocator16_sp; -extern grub_uint32_t grub_relocator16_edx; -extern grub_uint32_t grub_relocator16_ebx; -extern grub_uint32_t grub_relocator16_esi; -extern grub_uint32_t grub_relocator16_ebp; - -extern grub_uint16_t grub_relocator16_keep_a20_enabled; - -extern grub_uint8_t grub_relocator32_start; -extern grub_uint8_t grub_relocator32_end; -extern grub_uint32_t grub_relocator32_eax; -extern grub_uint32_t grub_relocator32_ebx; -extern grub_uint32_t grub_relocator32_ecx; -extern grub_uint32_t grub_relocator32_edx; -extern grub_uint32_t grub_relocator32_eip; -extern grub_uint32_t grub_relocator32_esp; -extern grub_uint32_t grub_relocator32_ebp; -extern grub_uint32_t grub_relocator32_esi; -extern grub_uint32_t grub_relocator32_edi; - -extern grub_uint8_t grub_relocator64_start; -extern grub_uint8_t grub_relocator64_end; -extern grub_uint64_t grub_relocator64_rax; -extern grub_uint64_t grub_relocator64_rbx; -extern grub_uint64_t grub_relocator64_rcx; -extern grub_uint64_t grub_relocator64_rdx; -extern grub_uint64_t grub_relocator64_rip; -extern grub_uint64_t grub_relocator64_rsp; -extern grub_uint64_t grub_relocator64_rsi; -extern grub_addr_t grub_relocator64_cr3; -extern struct grub_i386_idt grub_relocator16_idt; - -#define RELOCATOR_SIZEOF(x) (&grub_relocator##x##_end - &grub_relocator##x##_start) - -grub_err_t -grub_relocator32_boot (struct grub_relocator *rel, - struct grub_relocator32_state state, - int avoid_efi_bootservices) -{ - grub_err_t err; - void *relst; - grub_relocator_chunk_t ch; - - /* Specific memory range due to Global Descriptor Table for use by payload - that we will store in returned chunk. The address range and preference - are based on "THE LINUX/x86 BOOT PROTOCOL" specification. */ - err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0x1000, 0x9a000, - RELOCATOR_SIZEOF (32), 16, - GRUB_RELOCATOR_PREFERENCE_LOW, - avoid_efi_bootservices); - if (err) - return err; - - grub_relocator32_eax = state.eax; - grub_relocator32_ebx = state.ebx; - grub_relocator32_ecx = state.ecx; - grub_relocator32_edx = state.edx; - grub_relocator32_eip = state.eip; - grub_relocator32_esp = state.esp; - grub_relocator32_ebp = state.ebp; - grub_relocator32_esi = state.esi; - grub_relocator32_edi = state.edi; - - grub_memmove (get_virtual_current_address (ch), &grub_relocator32_start, - RELOCATOR_SIZEOF (32)); - - err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch), - &relst, NULL); - if (err) - return err; - - asm volatile ("cli"); - ((void (*) (void)) relst) (); - - /* Not reached. */ - return GRUB_ERR_NONE; -} - -grub_err_t -grub_relocator16_boot (struct grub_relocator *rel, - struct grub_relocator16_state state) -{ - grub_err_t err; - void *relst; - grub_relocator_chunk_t ch; - - /* Put it higher than the byte it checks for A20 check. */ - err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0x8010, 0xa0000, - RELOCATOR_SIZEOF (16) + - GRUB_RELOCATOR16_STACK_SIZE, 16, - GRUB_RELOCATOR_PREFERENCE_NONE, 0); - if (err) - return err; - - grub_relocator16_cs = state.cs; - grub_relocator16_ip = state.ip; - - grub_relocator16_ds = state.ds; - grub_relocator16_es = state.es; - grub_relocator16_fs = state.fs; - grub_relocator16_gs = state.gs; - - grub_relocator16_ss = state.ss; - grub_relocator16_sp = state.sp; - - grub_relocator16_ebp = state.ebp; - grub_relocator16_ebx = state.ebx; - grub_relocator16_edx = state.edx; - grub_relocator16_esi = state.esi; -#ifdef GRUB_MACHINE_PCBIOS - grub_relocator16_idt = *grub_realidt; -#else - grub_relocator16_idt.base = 0; - grub_relocator16_idt.limit = 0; -#endif - - grub_relocator16_keep_a20_enabled = state.a20; - - grub_memmove (get_virtual_current_address (ch), &grub_relocator16_start, - RELOCATOR_SIZEOF (16)); - - err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch), - &relst, NULL); - if (err) - return err; - - asm volatile ("cli"); - ((void (*) (void)) relst) (); - - /* Not reached. */ - return GRUB_ERR_NONE; -} - -grub_err_t -grub_relocator64_boot (struct grub_relocator *rel, - struct grub_relocator64_state state, - grub_addr_t min_addr, grub_addr_t max_addr) -{ - grub_err_t err; - void *relst; - grub_relocator_chunk_t ch; - - err = grub_relocator_alloc_chunk_align_safe (rel, &ch, min_addr, max_addr, - RELOCATOR_SIZEOF (64), 16, - GRUB_RELOCATOR_PREFERENCE_NONE, 0); - if (err) - return err; - - grub_relocator64_rax = state.rax; - grub_relocator64_rbx = state.rbx; - grub_relocator64_rcx = state.rcx; - grub_relocator64_rdx = state.rdx; - grub_relocator64_rip = state.rip; - grub_relocator64_rsp = state.rsp; - grub_relocator64_rsi = state.rsi; - grub_relocator64_cr3 = state.cr3; - - grub_memmove (get_virtual_current_address (ch), &grub_relocator64_start, - RELOCATOR_SIZEOF (64)); - - err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch), - &relst, NULL); - if (err) - return err; - - asm volatile ("cli"); - ((void (*) (void)) relst) (); - - /* Not reached. */ - return GRUB_ERR_NONE; -} diff --git a/grub-core/lib/i386/relocator16.S b/grub-core/lib/i386/relocator16.S deleted file mode 100644 index e9238119b..000000000 --- a/grub-core/lib/i386/relocator16.S +++ /dev/null @@ -1,341 +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 . - */ - -/* The code segment of the protected mode. */ -#define CODE_SEGMENT 0x08 - -/* The data segment of the protected mode. */ -#define DATA_SEGMENT 0x10 - -#define PSEUDO_REAL_CSEG 0x18 - -#define PSEUDO_REAL_DSEG 0x20 - -#include - -#include "relocator_common.S" - - .p2align 4 /* force 16-byte alignment */ - -VARIABLE(grub_relocator16_start) - PREAMBLE - -#ifdef __APPLE__ - LOCAL(cs_base_bytes12_offset) = LOCAL (cs_base_bytes12) - LOCAL (base) - LOCAL(cs_base_byte3_offset) = LOCAL (cs_base_byte3) - LOCAL (base) - LOCAL(ds_base_bytes12_offset) = LOCAL (ds_base_bytes12) - LOCAL (base) - LOCAL(ds_base_byte3_offset) = LOCAL (ds_base_byte3) - LOCAL (base) - movl %esi, %eax - movw %ax, (LOCAL(cs_base_bytes12_offset)) (RSI, 1) - movw %ax, (LOCAL(ds_base_bytes12_offset)) (RSI, 1) - shrl $16, %eax - movb %al, (LOCAL (cs_base_byte3_offset)) (RSI, 1) - movb %al, (LOCAL (ds_base_byte3_offset)) (RSI, 1) -#else - movl %esi, %eax - movw %ax, (LOCAL (cs_base_bytes12) - LOCAL (base)) (RSI, 1) - movw %ax, (LOCAL (ds_base_bytes12) - LOCAL (base)) (RSI, 1) - shrl $16, %eax - movb %al, (LOCAL (cs_base_byte3) - LOCAL (base)) (RSI, 1) - movb %al, (LOCAL (ds_base_byte3) - LOCAL (base)) (RSI, 1) -#endif - - RELOAD_GDT - .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 - -#ifdef __x86_64__ - /* Disable amd64. */ - movl $GRUB_MEMORY_CPU_AMD64_MSR, %ecx - rdmsr - andl $(~GRUB_MEMORY_CPU_AMD64_MSR_ON), %eax - wrmsr -#endif - - /* Turn off PAE. */ - movl %cr4, %eax - andl $(~GRUB_MEMORY_CPU_CR4_PAE_ON), %eax - movl %eax, %cr4 - - /* Update other registers. */ - movl $PSEUDO_REAL_DSEG, %eax - movl %eax, %ds - movl %eax, %es - movl %eax, %fs - movl %eax, %gs - movl %eax, %ss - - movl %esi, %eax - shrl $4, %eax -#ifdef __APPLE__ - LOCAL(segment_offset) = LOCAL (segment) - LOCAL (base) - LOCAL(idt_offset) = LOCAL(relocator16_idt) - LOCAL (base) - LOCAL(cont2_offset) = LOCAL (cont2) - LOCAL(base) - movw %ax, (LOCAL(segment_offset)) - lidt (LOCAL(idt_offset)) - - /* jump to a 16 bit segment */ - ljmp $PSEUDO_REAL_CSEG, $(LOCAL(cont2_offset)) -#else - movw %ax, (LOCAL (segment) - LOCAL (base)) - - lidt (EXT_C(grub_relocator16_idt) - LOCAL (base)) - - /* jump to a 16 bit segment */ - ljmp $PSEUDO_REAL_CSEG, $(LOCAL (cont2) - LOCAL(base)) -#endif -LOCAL(cont2): - .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 */ - /* ljmp */ - .byte 0xea -#ifdef __APPLE__ - LOCAL(cont3_offset) = LOCAL(cont3) - LOCAL(base) - .word LOCAL(cont3_offset) -#else - .word LOCAL(cont3)-LOCAL(base) -#endif -LOCAL(segment): - .word 0 - -LOCAL(cont3): - - /* movw imm16, %ax. */ - .byte 0xb8 -VARIABLE(grub_relocator16_keep_a20_enabled) - .word 0 - - test %ax, %ax - jnz LOCAL(gate_a20_done) - - movw %cs, %ax - movw %ax, %ss -#ifdef __APPLE__ - LOCAL(relocator16_end_offset) = LOCAL(relocator16_end) - LOCAL(base) - leaw LOCAL(relocator16_end_offset), %sp -#else - leaw LOCAL(relocator16_end) - LOCAL(base), %sp -#endif - addw $GRUB_RELOCATOR16_STACK_SIZE, %sp - - /* second, try a BIOS call */ - movw $0x2400, %ax - int $0x15 - - call LOCAL(gate_a20_check_state) - testb %al, %al - jz LOCAL(gate_a20_done) - - /* - * 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 - 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. */ - jmp LOCAL(gate_a20_done) - -LOCAL(gate_a20_check_state): - /* iterate the checking for a while */ - movw $100, %cx -1: - xorw %ax, %ax - movw %ax, %ds - decw %ax - movw %ax, %es - xorw %ax, %ax - - movw $0x8000, %ax - /* compare the byte at ADDR with that at 0x100000 + ADDR */ - movw %ax, %si - addw $0x10, %ax - movw %ax, %di - - /* save the original byte in DL */ - movb %ds:(%si), %dl - movb %es:(%di), %al - /* try to set one less value at ADDR */ - movb %al, %dh - decb %dh - movb %dh, %ds:(%si) - /* serialize */ - outb %al, $0x80 - outb %al, $0x80 - /* obtain the value at 0x100000 + ADDR in CH */ - movb %es:(%di), %dh - /* this result is 1 if A20 is on or 0 if it is off */ - subb %dh, %al - xorb $1, %al - /* restore the original */ - movb %dl, %ds:(%si) - - testb %al, %al - jz LOCAL(gate_a20_done) - loop 1b -2: - ret - -LOCAL(gate_a20_done): - /* - * We are in real mode now. Set up the real mode segment registers and - * all the other general purpose registers. cs is updated with ljmp. - */ - /* movw imm16, %ax. */ - .byte 0xb8 -VARIABLE(grub_relocator16_ds) - .word 0 - movw %ax, %ds - - /* movw imm16, %ax. */ - .byte 0xb8 -VARIABLE(grub_relocator16_es) - .word 0 - movw %ax, %es - - /* movw imm16, %ax. */ - .byte 0xb8 -VARIABLE(grub_relocator16_fs) - .word 0 - movw %ax, %fs - - /* movw imm16, %ax. */ - .byte 0xb8 -VARIABLE(grub_relocator16_gs) - .word 0 - movw %ax, %gs - - /* movw imm16, %ax. */ - .byte 0xb8 -VARIABLE(grub_relocator16_ss) - .word 0 - movw %ax, %ss - - /* movw imm16, %ax. */ - .byte 0xb8 -VARIABLE(grub_relocator16_sp) - .word 0 - movzwl %ax, %esp - - /* movw imm32, %eax. */ - .byte 0x66, 0xb8 -VARIABLE(grub_relocator16_esi) - .long 0 - movl %eax, %esi - - /* movw imm32, %edx. */ - .byte 0x66, 0xba -VARIABLE(grub_relocator16_edx) - .long 0 - - /* movw imm32, %ebx. */ - .byte 0x66, 0xbb -VARIABLE(grub_relocator16_ebx) - .long 0 - - /* movl imm32, %ebp. */ - .byte 0x66, 0xbd -VARIABLE(grub_relocator16_ebp) - .long 0 - - /* Cleared direction flag is of no problem with any current - payload and makes this implementation easier. */ - cld - - /* ljmp */ - .byte 0xea -VARIABLE(grub_relocator16_ip) - .word 0 -VARIABLE(grub_relocator16_cs) - .word 0 - - .code32 - - /* GDT. Copied from loader/i386/linux.c. */ - .p2align 4 -LOCAL(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 = filled by code, limit 0x0FFFF (1 B Granularity), present - * type = 16 bit code execute/read only/conforming, DPL = 0 - */ - .word 0xFFFF -LOCAL(cs_base_bytes12): - .word 0 -LOCAL(cs_base_byte3): - .byte 0 - - .byte 0x9E, 0, 0 - - /* -- 16 bit real mode DS -- - * base = filled by code, limit 0x0FFFF (1 B Granularity), present - * type = 16 bit data read/write, DPL = 0 - */ - .word 0xFFFF -LOCAL(ds_base_bytes12): - .word 0 -LOCAL(ds_base_byte3): - .byte 0 - - .byte 0x92, 0, 0 - -LOCAL(gdt_end): - -#ifdef __APPLE__ -LOCAL(relocator16_idt): -#endif -VARIABLE(grub_relocator16_idt) - .word 0 - .long 0 -LOCAL(relocator16_end): -VARIABLE(grub_relocator16_end) - .byte 0 diff --git a/grub-core/lib/i386/relocator32.S b/grub-core/lib/i386/relocator32.S deleted file mode 100644 index 09ce56ad0..000000000 --- a/grub-core/lib/i386/relocator32.S +++ /dev/null @@ -1,134 +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 . - */ - -/* The code segment of the protected mode. */ -#define CODE_SEGMENT 0x10 - -/* The data segment of the protected mode. */ -#define DATA_SEGMENT 0x18 - -#include "relocator_common.S" - - .p2align 4 /* force 16-byte alignment */ - -VARIABLE(grub_relocator32_start) - PREAMBLE - - RELOAD_GDT - .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 - -#ifdef __x86_64__ - /* Disable amd64. */ - movl $GRUB_MEMORY_CPU_AMD64_MSR, %ecx - rdmsr - andl $(~GRUB_MEMORY_CPU_AMD64_MSR_ON), %eax - wrmsr -#endif - - /* 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 -VARIABLE(grub_relocator32_esp) - .long 0 - - movl %eax, %esp - - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_relocator32_ebp) - .long 0 - - movl %eax, %ebp - - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_relocator32_esi) - .long 0 - - movl %eax, %esi - - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_relocator32_edi) - .long 0 - - movl %eax, %edi - - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_relocator32_eax) - .long 0 - - /* mov imm32, %ebx */ - .byte 0xbb -VARIABLE(grub_relocator32_ebx) - .long 0 - - /* mov imm32, %ecx */ - .byte 0xb9 -VARIABLE(grub_relocator32_ecx) - .long 0 - - /* mov imm32, %edx */ - .byte 0xba -VARIABLE(grub_relocator32_edx) - .long 0 - - /* Cleared direction flag is of no problem with any current - payload and makes this implementation easier. */ - cld - - .byte 0xea -VARIABLE(grub_relocator32_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 -LOCAL(gdt_end): - -VARIABLE(grub_relocator32_end) diff --git a/grub-core/lib/i386/relocator64.S b/grub-core/lib/i386/relocator64.S deleted file mode 100644 index c80538e7e..000000000 --- a/grub-core/lib/i386/relocator64.S +++ /dev/null @@ -1,210 +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 . - */ - -#define CODE32_SEGMENT 0x18 -#define CODE_SEGMENT 0x08 - -/* The data segment of the protected mode. */ -#define DATA_SEGMENT 0x10 - -#include "relocator_common.S" - - .p2align 4 /* force 16-byte alignment */ - -VARIABLE(grub_relocator64_start) - PREAMBLE -#ifndef __x86_64__ - DISABLE_PAGING - - /* Turn on PAE. */ - movl %cr4, %eax - orl $(GRUB_MEMORY_CPU_CR4_PAE_ON | GRUB_MEMORY_CPU_CR4_PSE_ON), %eax - movl %eax, %cr4 - - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_relocator64_cr3) - .long 0 - movl %eax, %cr3 - - /* Turn on amd64. */ - movl $GRUB_MEMORY_CPU_AMD64_MSR, %ecx - rdmsr - orl $GRUB_MEMORY_CPU_AMD64_MSR_ON, %eax - wrmsr - - /* Enable paging. */ - movl %cr0, %eax - orl $GRUB_MEMORY_CPU_CR0_PAGING_ON, %eax - movl %eax, %cr0 - - RELOAD_GDT -#else - /* mov imm64, %rax */ - .byte 0x48 - .byte 0xb8 -VARIABLE(grub_relocator64_cr3) - .quad 0 - movq %rax, %cr3 -#endif - -#ifdef __x86_64__ - .code64 -#endif - - /* mov imm64, %rax */ - .byte 0x48 - .byte 0xb8 -VARIABLE(grub_relocator64_rsp) - .quad 0 - -#ifdef __x86_64__ - movq %rax, %rsp -#else - /* movq %rax, %rsp */ - .byte 0x48 - .byte 0x89 - .byte 0xc4 -#endif - -#ifdef GRUB_MACHINE_EFI - jmp LOCAL(skip_efi_stack_align) - - /* - * Here is grub_relocator64_efi_start() entry point. Most of the - * code below is shared between grub_relocator64_efi_start() - * and grub_relocator64_start(). - * - * Think twice before changing anything there!!! - */ -VARIABLE(grub_relocator64_efi_start) - /* Align the stack as UEFI spec requires. */ -#ifdef __x86_64__ - andq $~15, %rsp -#else - /* andq $~15, %rsp */ - .byte 0x48 - .byte 0x83 - .byte 0xe4 - .byte 0xf0 -#endif - -LOCAL(skip_efi_stack_align): -#endif - /* mov imm64, %rax */ - .byte 0x48 - .byte 0xb8 -VARIABLE(grub_relocator64_rsi) - .quad 0 - -#ifdef __x86_64__ - movq %rax, %rsi -#else - /* movq %rax, %rsi */ - .byte 0x48 - .byte 0x89 - .byte 0xc6 -#endif - - /* mov imm64, %rax */ - .byte 0x48 - .byte 0xb8 -VARIABLE(grub_relocator64_rax) - .quad 0 - - /* mov imm64, %rbx */ - .byte 0x48 - .byte 0xbb -VARIABLE(grub_relocator64_rbx) - .quad 0 - - /* mov imm64, %rcx */ - .byte 0x48 - .byte 0xb9 -VARIABLE(grub_relocator64_rcx) - .quad 0 - - /* mov imm64, %rdx */ - .byte 0x48 - .byte 0xba -VARIABLE(grub_relocator64_rdx) - .quad 0 - - /* Cleared direction flag is of no problem with any current - payload and makes this implementation easier. */ - cld - -#if defined (__APPLE__) || !defined (__x86_64__) - .byte 0xff, 0x25 - .long 0 -#else - jmp *LOCAL(jump_addr) (%rip) -#endif - -LOCAL(jump_addr): -VARIABLE(grub_relocator64_rip) - .quad 0 - -#ifdef GRUB_MACHINE_EFI - /* Here grub_relocator64_efi_start() ends. Ufff... */ -VARIABLE(grub_relocator64_efi_end) -#endif - -#ifndef __x86_64__ - .p2align 4 -LOCAL(gdt): - /* NULL. */ - .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - - /* 64-bit segment. */ - .word 0xffff /* Limit xffff. */ - .word 0x0000 /* Base xxxx0000. */ - .byte 0x00 /* Base xx00xxxx. */ - .byte (0x8 /* Type 8. */ | (1 << 4) /* Code. */ \ - | (0 << 5) /* Ring 0. */ | (1 << 7) /* Present. */) - .byte (0xf /* Limit fxxxx. */ | (0 << 4) /* AVL flag. */ \ - | (1 << 5) /* 64-bit. */ | (0 << 6) \ - | (1 << 7) /* 4K granular. */) - .byte 0x00 /* Base 00xxxxxx. */ - - /* Data segment*/ - .word 0xffff /* Limit xffff. */ - .word 0x0000 /* Base xxxx0000. */ - .byte 0x00 /* Base xx00xxxx. */ - .byte (0x0 /* Type 0. */ | (0 << 4) /* Data. */ \ - | (0 << 5) /* Ring 0. */ | (1 << 7) /* Present. */) - .byte (0xf /* Limit fxxxx. */ | (0 << 4) /* AVL flag. */ \ - | (0 << 5) /* Data. */ | (0 << 6) \ - | (1 << 7) /* 4K granular. */) - .byte 0x00 /* Base 00xxxxxx. */ - - /* Compatibility segment. */ - .word 0xffff /* Limit xffff. */ - .word 0x0000 /* Base xxxx0000. */ - .byte 0x00 /* Base xx00xxxx. */ - .byte (0x8 /* Type 8. */ | (1 << 4) /* Code. */ \ - | (0 << 5) /* Ring 0. */ | (1 << 7) /* Present. */) - .byte (0xf /* Limit fxxxx. */ | (0 << 4) /* AVL flag. */ \ - | (0 << 5) /* 32-bit. */ | (1 << 6) /* 32-bit. */ \ - | (1 << 7) /* 4K granular. */) - .byte 0x00 /* Base 00xxxxxx. */ - -LOCAL(gdt_end): -#endif - -VARIABLE(grub_relocator64_end) diff --git a/grub-core/lib/i386/relocator_asm.S b/grub-core/lib/i386/relocator_asm.S deleted file mode 100644 index f273586fe..000000000 --- a/grub-core/lib/i386/relocator_asm.S +++ /dev/null @@ -1,80 +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 . - */ - -#include -#include - - .p2align 2 - -VARIABLE(grub_relocator_backward_start) - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_relocator_backward_dest) - .long 0 - movl %eax, %edi - - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_relocator_backward_src) - .long 0 - movl %eax, %esi - - /* mov imm32, %ecx */ - .byte 0xb9 -VARIABLE(grub_relocator_backward_chunk_size) - .long 0 - - add %ecx, %esi - add %ecx, %edi - - - /* Backward movsb is implicitly off-by-one. compensate that. */ - sub $1, %esi - sub $1, %edi - - /* Backward copy. */ - std - - rep - movsb -VARIABLE(grub_relocator_backward_end) - - -VARIABLE(grub_relocator_forward_start) - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_relocator_forward_dest) - .long 0 - movl %eax, %edi - - /* mov imm32, %rax */ - .byte 0xb8 -VARIABLE(grub_relocator_forward_src) - .long 0 - movl %eax, %esi - - /* mov imm32, %ecx */ - .byte 0xb9 -VARIABLE(grub_relocator_forward_chunk_size) - .long 0 - - /* Forward copy. */ - cld - rep - movsb -VARIABLE(grub_relocator_forward_end) diff --git a/grub-core/lib/i386/relocator_common.S b/grub-core/lib/i386/relocator_common.S deleted file mode 100644 index 1b5210dd3..000000000 --- a/grub-core/lib/i386/relocator_common.S +++ /dev/null @@ -1,111 +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 . - */ - - -#include -#include - -#ifdef __x86_64__ -#define RAX %rax -#define RSI %rsi -#else -#define RAX %eax -#define RSI %esi -#endif - - .macro DISABLE_PAGING - - movl %cr0, %eax - andl $(~GRUB_MEMORY_CPU_CR0_PAGING_ON), %eax - movl %eax, %cr0 - .endm - - .macro PREAMBLE -LOCAL(base): - /* %rax contains now our new 'base'. */ - mov RAX, RSI - -#if defined (__APPLE__) && defined (__x86_64__) - leaq LOCAL(cont0) (%rip), RAX -#elif defined (__APPLE__) - LOCAL(cont0_offset) = LOCAL(cont0) - LOCAL(base) - add $LOCAL(cont0_offset), RAX -#else - add $(LOCAL(cont0) - LOCAL(base)), RAX -#endif - jmp *RAX -LOCAL(cont0): - .endm - - .macro RELOAD_GDT -#ifdef __APPLE__ - LOCAL(cont1_offset) = LOCAL(cont1) - LOCAL(base) - LOCAL(jump_vector_offset) = LOCAL(jump_vector) - LOCAL(base) - LOCAL(gdt_offset) = LOCAL(gdt) - LOCAL(base) - LOCAL(gdt_addr_offset) = LOCAL(gdt_addr) - LOCAL(base) - LOCAL(gdtdesc_offset) = LOCAL(gdtdesc) - LOCAL(base) - - lea LOCAL(cont1_offset) (RSI, 1), RAX - movl %eax, LOCAL(jump_vector_offset) (RSI, 1) - - lea LOCAL(gdt_offset) (RSI, 1), RAX - mov RAX, (LOCAL(gdt_addr_offset)) (RSI, 1) - - /* Switch to compatibility mode. */ - lgdt (LOCAL(gdtdesc_offset)) (RSI, 1) - - /* Update %cs. */ - ljmp *(LOCAL(jump_vector_offset)) (RSI, 1) - .p2align 4 -LOCAL(gdtdesc): - LOCAL(gdtsize) = LOCAL(gdt_end) - LOCAL(gdt) - .word LOCAL(gdtsize) -#else - 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) - - .p2align 4 -LOCAL(gdtdesc): - .word LOCAL(gdt_end) - LOCAL(gdt) -#endif -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 - -LOCAL(cont1): - .endm diff --git a/grub-core/lib/i386/relocator_common_c.c b/grub-core/lib/i386/relocator_common_c.c deleted file mode 100644 index 7be609b73..000000000 --- a/grub-core/lib/i386/relocator_common_c.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009-2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include - -#include -#include - -extern grub_uint8_t grub_relocator_forward_start; -extern grub_uint8_t grub_relocator_forward_end; -extern grub_uint8_t grub_relocator_backward_start; -extern grub_uint8_t grub_relocator_backward_end; - -extern void *grub_relocator_backward_dest; -extern void *grub_relocator_backward_src; -extern grub_size_t grub_relocator_backward_chunk_size; - -extern void *grub_relocator_forward_dest; -extern void *grub_relocator_forward_src; -extern grub_size_t grub_relocator_forward_chunk_size; - -#define RELOCATOR_SIZEOF(x) (&grub_relocator##x##_end - &grub_relocator##x##_start) - -grub_size_t grub_relocator_align = 1; -grub_size_t grub_relocator_forward_size; -grub_size_t grub_relocator_backward_size; -#ifdef __x86_64__ -grub_size_t grub_relocator_jumper_size = 12; -#else -grub_size_t grub_relocator_jumper_size = 7; -#endif - -void -grub_cpu_relocator_init (void) -{ - grub_relocator_forward_size = RELOCATOR_SIZEOF (_forward); - grub_relocator_backward_size = RELOCATOR_SIZEOF (_backward); -} - -void -grub_cpu_relocator_jumper (void *rels, grub_addr_t addr) -{ - grub_uint8_t *ptr; - ptr = rels; -#ifdef __x86_64__ - /* movq imm64, %rax (for relocator) */ - *(grub_uint8_t *) ptr = 0x48; - ptr++; - *(grub_uint8_t *) ptr = 0xb8; - ptr++; - *(grub_uint64_t *) ptr = addr; - ptr += sizeof (grub_uint64_t); -#else - /* movl imm32, %eax (for relocator) */ - *(grub_uint8_t *) ptr = 0xb8; - ptr++; - *(grub_uint32_t *) ptr = addr; - ptr += sizeof (grub_uint32_t); -#endif - /* jmp $eax/$rax */ - *(grub_uint8_t *) ptr = 0xff; - ptr++; - *(grub_uint8_t *) ptr = 0xe0; - ptr++; -} - -void -grub_cpu_relocator_backward (void *ptr, void *src, void *dest, - grub_size_t size) -{ - grub_relocator_backward_dest = dest; - grub_relocator_backward_src = src; - grub_relocator_backward_chunk_size = size; - - grub_memmove (ptr, - &grub_relocator_backward_start, RELOCATOR_SIZEOF (_backward)); -} - -void -grub_cpu_relocator_forward (void *ptr, void *src, void *dest, - grub_size_t size) -{ - grub_relocator_forward_dest = dest; - grub_relocator_forward_src = src; - grub_relocator_forward_chunk_size = size; - - grub_memmove (ptr, - &grub_relocator_forward_start, RELOCATOR_SIZEOF (_forward)); -} diff --git a/grub-core/lib/i386/xen/relocator.S b/grub-core/lib/i386/xen/relocator.S deleted file mode 100644 index dab4d8ace..000000000 --- a/grub-core/lib/i386/xen/relocator.S +++ /dev/null @@ -1,165 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - - .p2align 4 /* force 16-byte alignment */ - -VARIABLE(grub_relocator_xen_remap_start) -LOCAL(base): - /* Remap the remapper to it's new address. */ - /* mov imm32, %ebx - %ebx: new virtual address of remapper */ - .byte 0xbb -VARIABLE(grub_relocator_xen_remapper_virt) - .long 0 - - /* mov imm32, %ecx - %ecx: low part of page table entry */ - .byte 0xb9 -VARIABLE(grub_relocator_xen_remapper_map) - .long 0 - - /* mov imm32, %edx - %edx: high part of page table entry */ - .byte 0xba -VARIABLE(grub_relocator_xen_remapper_map_high) - .long 0 - - movl %ebx, %ebp /* %ebx is clobbered by hypercall */ - - movl $UVMF_INVLPG, %esi /* esi: flags (inv. single entry) */ - movl $__HYPERVISOR_update_va_mapping, %eax - int $0x82 - - movl %ebp, %ebx - addl $(LOCAL(cont) - LOCAL(base)), %ebx - - jmp *%ebx /* Continue with new virtual address */ - -LOCAL(cont): - /* Modify mappings of new page tables to be read-only. */ - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_relocator_xen_paging_areas_addr) - .long 0 - movl %eax, %ebx -1: - movl 0(%ebx), %ebp /* Get start pfn of the current area */ - movl GRUB_TARGET_SIZEOF_LONG(%ebx), %ecx /* Get # of pg tables */ - testl %ecx, %ecx /* 0 -> last area reached */ - jz 3f - addl $(2 * GRUB_TARGET_SIZEOF_LONG), %ebx - movl %ebx, %esp /* Save current area pointer */ - -2: - movl %ecx, %edi - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_relocator_xen_mfn_list) - .long 0 - movl 0(%eax, %ebp, 4), %ecx /* mfn */ - movl %ebp, %ebx - shll $GRUB_PAGE_SHIFT, %ebx /* virtual address (1:1 mapping) */ - movl %ecx, %edx - shll $GRUB_PAGE_SHIFT, %ecx /* prepare pte low part */ - shrl $(32 - GRUB_PAGE_SHIFT), %edx /* pte high part */ - orl $(GRUB_PAGE_PRESENT | GRUB_PAGE_USER), %ecx /* pte low */ - movl $UVMF_INVLPG, %esi - movl $__HYPERVISOR_update_va_mapping, %eax - int $0x82 /* parameters: eax, ebx, ecx, edx, esi */ - - incl %ebp /* next pfn */ - movl %edi, %ecx - - loop 2b - - mov %esp, %ebx /* restore area poniter */ - jmp 1b - -3: - /* Switch page tables: pin new L3 pt, load cr3, unpin old L3. */ - /* mov imm32, %ebx */ - .byte 0xbb -VARIABLE(grub_relocator_xen_mmu_op_addr) - .long 0 - movl $3, %ecx /* 3 mmu ops */ - movl $0, %edx /* pdone (not used) */ - movl $DOMID_SELF, %esi - movl $__HYPERVISOR_mmuext_op, %eax - int $0x82 - - /* Continue in virtual kernel mapping. */ - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_relocator_xen_remap_continue) - .long 0 - - jmp *%eax - -VARIABLE(grub_relocator_xen_paging_areas) - .long 0, 0, 0, 0, 0, 0, 0, 0 - -VARIABLE(grub_relocator_xen_mmu_op) - .space 256 - -VARIABLE(grub_relocator_xen_remap_end) - - -VARIABLE(grub_relocator_xen_start) - /* Unmap old remapper area. */ - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_relocator_xen_remapper_virt2) - .long 0 - - movl %eax, %ebx - - xorl %ecx, %ecx /* Invalid pte */ - xorl %edx, %edx - - movl $UVMF_INVLPG, %esi - movl $__HYPERVISOR_update_va_mapping, %eax - int $0x82 - - /* Prepare registers for starting kernel. */ - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_relocator_xen_stack) - .long 0 - - movl %eax, %esp - - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_relocator_xen_start_info) - .long 0 - - movl %eax, %esi - - cld - - /* mov imm32, %eax */ - .byte 0xb8 -VARIABLE(grub_relocator_xen_entry_point) - .long 0 - - /* Now start the new kernel. */ - jmp *%eax - -VARIABLE(grub_relocator_xen_end) diff --git a/grub-core/lib/ia64/longjmp.S b/grub-core/lib/ia64/longjmp.S deleted file mode 100644 index 38afb2243..000000000 --- a/grub-core/lib/ia64/longjmp.S +++ /dev/null @@ -1,162 +0,0 @@ -/* Copyright (C) 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc. - Contributed by David Mosberger-Tang . - - 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. - - Note that __sigsetjmp() did NOT flush the register stack. Instead, - we do it here since __longjmp() is usually much less frequently - invoked than __sigsetjmp(). The only difficulty is that __sigsetjmp() - didn't (and wouldn't be able to) save ar.rnat either. This is a problem - because if we're not careful, we could end up loading random NaT bits. - There are two cases: - - (i) ar.bsp < ia64_rse_rnat_addr(jmpbuf.ar_bsp) - ar.rnat contains the desired bits---preserve ar.rnat - across loadrs and write to ar.bspstore - - (ii) ar.bsp >= ia64_rse_rnat_addr(jmpbuf.ar_bsp) - The desired ar.rnat is stored in - ia64_rse_rnat_addr(jmpbuf.ar_bsp). Load those - bits into ar.rnat after setting ar.bspstore. */ - - - -# define pPos p6 /* is rotate count positive? */ -# define pNeg p7 /* is rotate count negative? */ - - - /* __longjmp(__jmp_buf buf, int val) */ - - .text - - .proc EXT_C(grub_longjmp) -FUNCTION(grub_longjmp) - alloc r8=ar.pfs,2,1,0,0 - mov r27=ar.rsc - add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr - ;; - ld8 r8=[r2],-16 // r8 <- orig_jmp_buf_addr - mov r10=ar.bsp - and r11=~0x3,r27 // clear ar.rsc.mode - ;; - flushrs // flush dirty regs to backing store (must be first in insn grp) - ld8 r23=[r2],8 // r23 <- jmpbuf.ar_bsp - sub r8=r8,in0 // r8 <- &orig_jmpbuf - &jmpbuf - ;; - ld8 r25=[r2] // r25 <- jmpbuf.ar_unat - extr.u r8=r8,3,6 // r8 <- (&orig_jmpbuf - &jmpbuf)/8 & 0x3f - ;; - cmp.lt pNeg,pPos=r8,r0 - mov r2=in0 - ;; -(pPos) mov r16=r8 -(pNeg) add r16=64,r8 -(pPos) sub r17=64,r8 -(pNeg) sub r17=r0,r8 - ;; - mov ar.rsc=r11 // put RSE in enforced lazy mode - shr.u r8=r25,r16 - add r3=8,in0 // r3 <- &jmpbuf.r1 - shl r9=r25,r17 - ;; - or r25=r8,r9 - ;; - mov r26=ar.rnat - mov ar.unat=r25 // setup ar.unat (NaT bits for r1, r4-r7, and r12) - ;; - ld8.fill.nta sp=[r2],16 // r12 (sp) - ld8.fill.nta gp=[r3],16 // r1 (gp) - dep r11=-1,r23,3,6 // r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp) - ;; - ld8.nta r16=[r2],16 // caller's unat - ld8.nta r17=[r3],16 // fpsr - ;; - ld8.fill.nta r4=[r2],16 // r4 - ld8.fill.nta r5=[r3],16 // r5 (gp) - cmp.geu p8,p0=r10,r11 // p8 <- (ar.bsp >= jmpbuf.ar_bsp) - ;; - ld8.fill.nta r6=[r2],16 // r6 - ld8.fill.nta r7=[r3],16 // r7 - ;; - mov ar.unat=r16 // restore caller's unat - mov ar.fpsr=r17 // restore fpsr - ;; - ld8.nta r16=[r2],16 // b0 - ld8.nta r17=[r3],16 // b1 - ;; -(p8) ld8 r26=[r11] // r26 <- *ia64_rse_rnat_addr(jmpbuf.ar_bsp) - mov ar.bspstore=r23 // restore ar.bspstore - ;; - ld8.nta r18=[r2],16 // b2 - ld8.nta r19=[r3],16 // b3 - ;; - ld8.nta r20=[r2],16 // b4 - ld8.nta r21=[r3],16 // b5 - ;; - ld8.nta r11=[r2],16 // ar.pfs - ld8.nta r22=[r3],56 // ar.lc - ;; - ld8.nta r24=[r2],32 // pr - mov b0=r16 - ;; - ldf.fill.nta f2=[r2],32 - ldf.fill.nta f3=[r3],32 - mov b1=r17 - ;; - ldf.fill.nta f4=[r2],32 - ldf.fill.nta f5=[r3],32 - mov b2=r18 - ;; - ldf.fill.nta f16=[r2],32 - ldf.fill.nta f17=[r3],32 - mov b3=r19 - ;; - ldf.fill.nta f18=[r2],32 - ldf.fill.nta f19=[r3],32 - mov b4=r20 - ;; - ldf.fill.nta f20=[r2],32 - ldf.fill.nta f21=[r3],32 - mov b5=r21 - ;; - ldf.fill.nta f22=[r2],32 - ldf.fill.nta f23=[r3],32 - mov ar.lc=r22 - ;; - ldf.fill.nta f24=[r2],32 - ldf.fill.nta f25=[r3],32 - cmp.eq p8,p9=0,in1 - ;; - ldf.fill.nta f26=[r2],32 - ldf.fill.nta f27=[r3],32 - mov ar.pfs=r11 - ;; - ldf.fill.nta f28=[r2],32 - ldf.fill.nta f29=[r3],32 - ;; - ldf.fill.nta f30=[r2] - ldf.fill.nta f31=[r3] -(p8) mov r8=1 - - mov ar.rnat=r26 // restore ar.rnat - ;; - mov ar.rsc=r27 // restore ar.rsc -(p9) mov r8=in1 - - invala // virt. -> phys. regnum mapping may change - mov pr=r24,-1 - br.ret.dptk.few rp - .endp EXT_C(grub_longjmp) diff --git a/grub-core/lib/ia64/setjmp.S b/grub-core/lib/ia64/setjmp.S deleted file mode 100644 index a0382d83d..000000000 --- a/grub-core/lib/ia64/setjmp.S +++ /dev/null @@ -1,177 +0,0 @@ -/* Copyright (C) 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc. - Contributed by David Mosberger-Tang . - - 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. - - The layout of the jmp_buf is as follows. This is subject to change - and user-code should never depend on the particular layout of - jmp_buf! - - - offset: description: - ------- ------------ - 0x000 stack pointer (r12) ; unchangeable (see _JMPBUF_UNWINDS) - 0x008 r1 (gp) - 0x010 caller's unat - 0x018 fpsr - 0x020 r4 - 0x028 r5 - 0x030 r6 - 0x038 r7 - 0x040 rp (b0) - 0x048 b1 - 0x050 b2 - 0x058 b3 - 0x060 b4 - 0x068 b5 - 0x070 ar.pfs - 0x078 ar.lc - 0x080 pr - 0x088 ar.bsp ; unchangeable (see __longjmp.S) - 0x090 ar.unat - 0x098 &__jmp_buf ; address of the jmpbuf (needed to locate NaT bits in unat) - 0x0a0 f2 - 0x0b0 f3 - 0x0c0 f4 - 0x0d0 f5 - 0x0e0 f16 - 0x0f0 f17 - 0x100 f18 - 0x110 f19 - 0x120 f20 - 0x130 f21 - 0x130 f22 - 0x140 f23 - 0x150 f24 - 0x160 f25 - 0x170 f26 - 0x180 f27 - 0x190 f28 - 0x1a0 f29 - 0x1b0 f30 - 0x1c0 f31 */ - -#include -#include - - .file "setjmp.S" - -GRUB_MOD_LICENSE "GPLv2+" - - /* The following two entry points are the traditional entry points: */ - - .text - - .proc EXT_C(grub_setjmp) -FUNCTION(grub_setjmp) - alloc r8=ar.pfs,2,0,0,0 - mov in1=1 - br.cond.sptk.many __sigsetjmp - .endp EXT_C(grub_setjmp) - - /* __sigsetjmp(__jmp_buf buf, int savemask) */ - - .proc __sigsetjmp -__sigsetjmp: - //.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2) - alloc loc1=ar.pfs,2,2,2,0 - mov r16=ar.unat - ;; - mov r17=ar.fpsr - mov r2=in0 - add r3=8,in0 - ;; - st8.spill.nta [r2]=sp,16 // r12 (sp) - st8.spill.nta [r3]=gp,16 // r1 (gp) - ;; - st8.nta [r2]=r16,16 // save caller's unat - st8.nta [r3]=r17,16 // save fpsr - add r8=0xa0,in0 - ;; - st8.spill.nta [r2]=r4,16 // r4 - st8.spill.nta [r3]=r5,16 // r5 - add r9=0xb0,in0 - ;; - stf.spill.nta [r8]=f2,32 - stf.spill.nta [r9]=f3,32 - mov loc0=rp - .body - ;; - stf.spill.nta [r8]=f4,32 - stf.spill.nta [r9]=f5,32 - mov r17=b1 - ;; - stf.spill.nta [r8]=f16,32 - stf.spill.nta [r9]=f17,32 - mov r18=b2 - ;; - stf.spill.nta [r8]=f18,32 - stf.spill.nta [r9]=f19,32 - mov r19=b3 - ;; - stf.spill.nta [r8]=f20,32 - stf.spill.nta [r9]=f21,32 - mov r20=b4 - ;; - stf.spill.nta [r8]=f22,32 - stf.spill.nta [r9]=f23,32 - mov r21=b5 - ;; - stf.spill.nta [r8]=f24,32 - stf.spill.nta [r9]=f25,32 - mov r22=ar.lc - ;; - stf.spill.nta [r8]=f26,32 - stf.spill.nta [r9]=f27,32 - mov r24=pr - ;; - stf.spill.nta [r8]=f28,32 - stf.spill.nta [r9]=f29,32 - ;; - stf.spill.nta [r8]=f30 - stf.spill.nta [r9]=f31 - - st8.spill.nta [r2]=r6,16 // r6 - st8.spill.nta [r3]=r7,16 // r7 - ;; - mov r23=ar.bsp - mov r25=ar.unat - mov out0=in0 - - st8.nta [r2]=loc0,16 // b0 - st8.nta [r3]=r17,16 // b1 - mov out1=in1 - ;; - st8.nta [r2]=r18,16 // b2 - st8.nta [r3]=r19,16 // b3 - ;; - st8.nta [r2]=r20,16 // b4 - st8.nta [r3]=r21,16 // b5 - ;; - st8.nta [r2]=loc1,16 // ar.pfs - st8.nta [r3]=r22,16 // ar.lc - ;; - st8.nta [r2]=r24,16 // pr - st8.nta [r3]=r23,16 // ar.bsp - ;; - st8.nta [r2]=r25 // ar.unat - st8.nta [r3]=in0 // &__jmp_buf - mov r8=0 - mov rp=loc0 - mov ar.pfs=loc1 - br.ret.sptk.many rp - - .endp __sigsetjmp diff --git a/grub-core/lib/ieee1275/cmos.c b/grub-core/lib/ieee1275/cmos.c deleted file mode 100644 index 1400cfb67..000000000 --- a/grub-core/lib/ieee1275/cmos.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include - -volatile grub_uint8_t *grub_cmos_port = 0; - -/* Helper for grub_cmos_find_port. */ -static int -grub_cmos_find_port_iter (struct grub_ieee1275_devalias *alias) -{ - grub_ieee1275_phandle_t dev; - grub_uint32_t addr[2]; - grub_ssize_t actual; - /* Enough to check if it's "m5819" */ - char compat[100]; - if (grub_ieee1275_finddevice (alias->path, &dev)) - return 0; - if (grub_ieee1275_get_property (dev, "compatible", compat, sizeof (compat), - 0)) - return 0; - if (grub_strcmp (compat, "m5819") != 0) - return 0; - if (grub_ieee1275_get_integer_property (dev, "address", - addr, sizeof (addr), &actual)) - return 0; - if (actual == 4) - { - grub_cmos_port = (volatile grub_uint8_t *) (grub_addr_t) addr[0]; - return 1; - } - -#if GRUB_CPU_SIZEOF_VOID_P == 8 - if (actual == 8) - { - grub_cmos_port = (volatile grub_uint8_t *) - ((((grub_addr_t) addr[0]) << 32) | addr[1]); - return 1; - } -#else - if (actual == 8 && addr[0] == 0) - { - grub_cmos_port = (volatile grub_uint8_t *) addr[1]; - return 1; - } -#endif - return 0; -} - -grub_err_t -grub_cmos_find_port (void) -{ - grub_ieee1275_devices_iterate (grub_cmos_find_port_iter); - if (!grub_cmos_port) - return grub_error (GRUB_ERR_IO, "no cmos found"); - - return GRUB_ERR_NONE; -} diff --git a/grub-core/lib/ieee1275/datetime.c b/grub-core/lib/ieee1275/datetime.c deleted file mode 100644 index 74578f15a..000000000 --- a/grub-core/lib/ieee1275/datetime.c +++ /dev/null @@ -1,156 +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 . - */ - -#include -#include -#include -#include -#if defined (__powerpc__) || defined (__sparc__) -#include -#endif - -GRUB_MOD_LICENSE ("GPLv3+"); - -static char *rtc = 0; -static int no_ieee1275_rtc = 0; - -/* Helper for find_rtc. */ -static int -find_rtc_iter (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; -} - -static void -find_rtc (void) -{ - grub_ieee1275_devices_iterate (find_rtc_iter); - if (!rtc) - no_ieee1275_rtc = 1; -} - -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 (no_ieee1275_rtc) - return grub_get_datetime_cmos (datetime); - if (!rtc) - find_rtc (); - if (!rtc) - return grub_get_datetime_cmos (datetime); - - 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 || args.catch_result) - 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 (no_ieee1275_rtc) - return grub_set_datetime_cmos (datetime); - if (!rtc) - find_rtc (); - if (!rtc) - return grub_set_datetime_cmos (datetime); - - 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 || args.catch_result) - return grub_error (GRUB_ERR_IO, "set-time failed"); - - return GRUB_ERR_NONE; -} diff --git a/grub-core/lib/ieee1275/halt.c b/grub-core/lib/ieee1275/halt.c deleted file mode 100644 index 8fc16d243..000000000 --- a/grub-core/lib/ieee1275/halt.c +++ /dev/null @@ -1,33 +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 . - */ - -#include -#include - -void -grub_halt (void) -{ - /* Not standardized. We try three known commands. */ - - grub_ieee1275_interpret ("power-off", 0); - grub_ieee1275_interpret ("shut-down", 0); - grub_ieee1275_interpret ("poweroff", 0); - - while (1); -} diff --git a/grub-core/lib/ieee1275/relocator.c b/grub-core/lib/ieee1275/relocator.c deleted file mode 100644 index 918392f1e..000000000 --- a/grub-core/lib/ieee1275/relocator.c +++ /dev/null @@ -1,110 +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 . - */ - -#include -#include -#include -#include - -/* Helper for grub_relocator_firmware_get_max_events. */ -static int -count (grub_uint64_t addr __attribute__ ((unused)), - grub_uint64_t len __attribute__ ((unused)), - grub_memory_type_t type __attribute__ ((unused)), void *data) -{ - int *counter = data; - - (*counter)++; - return 0; -} - -unsigned -grub_relocator_firmware_get_max_events (void) -{ - int counter = 0; - - grub_machine_mmap_iterate (count, &counter); - return 2 * counter; -} - -/* Context for grub_relocator_firmware_fill_events. */ -struct grub_relocator_firmware_fill_events_ctx -{ - struct grub_relocator_mmap_event *events; - int counter; -}; - -/* Helper for grub_relocator_firmware_fill_events. */ -static int -grub_relocator_firmware_fill_events_iter (grub_uint64_t addr, - grub_uint64_t len, - grub_memory_type_t type, void *data) -{ - struct grub_relocator_firmware_fill_events_ctx *ctx = data; - - if (type != GRUB_MEMORY_AVAILABLE) - return 0; - - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM)) - { - if (addr + len <= 0x180000) - return 0; - - if (addr < 0x180000) - { - len = addr + len - 0x180000; - addr = 0x180000; - } - } - - ctx->events[ctx->counter].type = REG_FIRMWARE_START; - ctx->events[ctx->counter].pos = addr; - ctx->counter++; - ctx->events[ctx->counter].type = REG_FIRMWARE_END; - ctx->events[ctx->counter].pos = addr + len; - ctx->counter++; - - return 0; -} - -unsigned -grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events) -{ - struct grub_relocator_firmware_fill_events_ctx ctx = { - .events = events, - .counter = 0 - }; - - grub_machine_mmap_iterate (grub_relocator_firmware_fill_events_iter, &ctx); - return ctx.counter; -} - -int -grub_relocator_firmware_alloc_region (grub_addr_t start, grub_size_t size) -{ - grub_err_t err; - err = grub_claimmap (start, size); - grub_errno = 0; - return (err == 0); -} - -void -grub_relocator_firmware_free_region (grub_addr_t start, grub_size_t size) -{ - grub_ieee1275_release (start, size); -} diff --git a/grub-core/lib/ieee1275/tcg2.c b/grub-core/lib/ieee1275/tcg2.c deleted file mode 100644 index 40161c2f9..000000000 --- a/grub-core/lib/ieee1275/tcg2.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2024 IBM Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include - -#include - -grub_ieee1275_ihandle_t grub_ieee1275_tpm_ihandle = GRUB_IEEE1275_IHANDLE_INVALID; - -grub_err_t -grub_ieee1275_tpm_init (void) -{ - static bool init_tried = false; - grub_ieee1275_phandle_t vtpm; - char buffer[20]; - - if (init_tried == false) - { - init_tried = true; - - if (grub_ieee1275_open ("/vdevice/vtpm", &grub_ieee1275_tpm_ihandle) < 0 || - grub_ieee1275_finddevice ("/vdevice/vtpm", &vtpm) || - grub_ieee1275_get_property (vtpm, "compatible", buffer, sizeof (buffer), NULL) || - grub_strcmp (buffer, "IBM,vtpm20")) - { - if (grub_ieee1275_tpm_ihandle != GRUB_IEEE1275_IHANDLE_INVALID) - grub_ieee1275_close (grub_ieee1275_tpm_ihandle); - - grub_ieee1275_tpm_ihandle = GRUB_IEEE1275_IHANDLE_INVALID; - } - } - - if (grub_ieee1275_tpm_ihandle == GRUB_IEEE1275_IHANDLE_INVALID) - return GRUB_ERR_UNKNOWN_DEVICE; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_tcg2_get_max_output_size (grub_size_t *size) -{ - struct tpm_get_maximum_cmd_size - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t method; - grub_ieee1275_cell_t ihandle; - grub_ieee1275_cell_t catch_result; - grub_ieee1275_cell_t size; - }; - struct tpm_get_maximum_cmd_size args; - static bool error_displayed = false; - grub_err_t err; - - err = grub_ieee1275_tpm_init (); - if (err != GRUB_ERR_NONE) - return err; - - INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 2); - args.method = (grub_ieee1275_cell_t) "get-maximum-cmd-size"; - args.ihandle = grub_ieee1275_tpm_ihandle; - - if (IEEE1275_CALL_ENTRY_FN (&args) == -1) - return GRUB_ERR_INVALID_COMMAND; - - /* - * args.catch_result is set if firmware does not support get-maximum-cmd-size. - * rc is GRUB_IEEE1275_CELL_FALSE (0) on failure. - */ - if (args.catch_result) - { - if (error_displayed == false) - { - error_displayed = true; - return grub_error (GRUB_ERR_BAD_DEVICE, - "get-maximum-cmd-size failed: Firmware is likely too old"); - } - return GRUB_ERR_INVALID_COMMAND; - } - - *size = args.size; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_tcg2_submit_command (grub_size_t input_size, - grub_uint8_t *input, - grub_size_t output_size, - grub_uint8_t *output) -{ - struct tpm_pass_through_to_tpm - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t method; - grub_ieee1275_cell_t ihandle; - grub_ieee1275_cell_t buf_size; - grub_ieee1275_cell_t buf_addr; - grub_ieee1275_cell_t catch_result; - grub_ieee1275_cell_t resp_size; - }; - struct tpm_pass_through_to_tpm args; - static bool error_displayed = false; - grub_err_t err; - - if (input_size == 0 || input == NULL || - output_size == 0 || output == NULL) - return GRUB_ERR_BAD_ARGUMENT; - - err = grub_ieee1275_tpm_init (); - if (err != GRUB_ERR_NONE) - return err; - - INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 2); - args.method = (grub_ieee1275_cell_t) "pass-through-to-tpm"; - args.ihandle = grub_ieee1275_tpm_ihandle; - args.buf_size = (grub_ieee1275_cell_t) input_size; - args.buf_addr = (grub_ieee1275_cell_t) input; - - if (IEEE1275_CALL_ENTRY_FN (&args) == -1) - return GRUB_ERR_INVALID_COMMAND; - - /* args.catch_result is set if firmware does not support pass-through-to-tpm. */ - if (args.catch_result) - { - if (error_displayed == false) - { - error_displayed = true; - return grub_error (GRUB_ERR_BAD_DEVICE, - "pass-through-to-tpm failed: Firmware is likely too old"); - } - return GRUB_ERR_INVALID_COMMAND; - } - - grub_memcpy (output, input, args.resp_size); - - return GRUB_ERR_NONE; -} diff --git a/grub-core/lib/json/jsmn.h b/grub-core/lib/json/jsmn.h deleted file mode 100644 index 3178dcc97..000000000 --- a/grub-core/lib/json/jsmn.h +++ /dev/null @@ -1,471 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2010 Serge Zaitsev - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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 JSMN_H -#define JSMN_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef JSMN_STATIC -#define JSMN_API static -#else -#define JSMN_API extern -#endif - -/** - * JSON type identifier. Basic types are: - * o Object - * o Array - * o String - * o Other primitive: number, boolean (true/false) or null - */ -typedef enum { - JSMN_UNDEFINED = 0, - JSMN_OBJECT = 1, - JSMN_ARRAY = 2, - JSMN_STRING = 3, - JSMN_PRIMITIVE = 4 -} jsmntype_t; - -enum jsmnerr { - /* Not enough tokens were provided */ - JSMN_ERROR_NOMEM = -1, - /* Invalid character inside JSON string */ - JSMN_ERROR_INVAL = -2, - /* The string is not a full JSON packet, more bytes expected */ - JSMN_ERROR_PART = -3 -}; - -/** - * JSON token description. - * type type (object, array, string etc.) - * start start position in JSON data string - * end end position in JSON data string - */ -typedef struct jsmntok { - jsmntype_t type; - int start; - int end; - int size; -#ifdef JSMN_PARENT_LINKS - int parent; -#endif -} jsmntok_t; - -/** - * JSON parser. Contains an array of token blocks available. Also stores - * the string being parsed now and current position in that string. - */ -typedef struct jsmn_parser { - unsigned int pos; /* offset in the JSON string */ - unsigned int toknext; /* next token to allocate */ - int toksuper; /* superior token node, e.g. parent object or array */ -} jsmn_parser; - -/** - * Create JSON parser over an array of tokens - */ -JSMN_API void jsmn_init(jsmn_parser *parser); - -/** - * Run JSON parser. It parses a JSON data string into and array of tokens, each - * describing - * a single JSON object. - */ -JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len, - jsmntok_t *tokens, const unsigned int num_tokens); - -#ifndef JSMN_HEADER -/** - * Allocates a fresh unused token from the token pool. - */ -static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, jsmntok_t *tokens, - const size_t num_tokens) { - jsmntok_t *tok; - if (parser->toknext >= num_tokens) { - return NULL; - } - tok = &tokens[parser->toknext++]; - tok->start = tok->end = -1; - tok->size = 0; -#ifdef JSMN_PARENT_LINKS - tok->parent = -1; -#endif - return tok; -} - -/** - * Fills token type and boundaries. - */ -static void jsmn_fill_token(jsmntok_t *token, const jsmntype_t type, - const int start, const int end) { - token->type = type; - token->start = start; - token->end = end; - token->size = 0; -} - -/** - * Fills next available token with JSON primitive. - */ -static int jsmn_parse_primitive(jsmn_parser *parser, const char *js, - const size_t len, jsmntok_t *tokens, - const size_t num_tokens) { - jsmntok_t *token; - int start; - - start = parser->pos; - - for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { - switch (js[parser->pos]) { -#ifndef JSMN_STRICT - /* In strict mode primitive must be followed by "," or "}" or "]" */ - case ':': -#endif - case '\t': - case '\r': - case '\n': - case ' ': - case ',': - case ']': - case '}': - goto found; - default: - /* to quiet a warning from gcc*/ - break; - } - if (js[parser->pos] < 32 || js[parser->pos] >= 127) { - parser->pos = start; - return JSMN_ERROR_INVAL; - } - } -#ifdef JSMN_STRICT - /* In strict mode primitive must be followed by a comma/object/array */ - parser->pos = start; - return JSMN_ERROR_PART; -#endif - -found: - if (tokens == NULL) { - parser->pos--; - return 0; - } - token = jsmn_alloc_token(parser, tokens, num_tokens); - if (token == NULL) { - parser->pos = start; - return JSMN_ERROR_NOMEM; - } - jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos); -#ifdef JSMN_PARENT_LINKS - token->parent = parser->toksuper; -#endif - parser->pos--; - return 0; -} - -/** - * Fills next token with JSON string. - */ -static int jsmn_parse_string(jsmn_parser *parser, const char *js, - const size_t len, jsmntok_t *tokens, - const size_t num_tokens) { - jsmntok_t *token; - - int start = parser->pos; - - parser->pos++; - - /* Skip starting quote */ - for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { - char c = js[parser->pos]; - - /* Quote: end of string */ - if (c == '\"') { - if (tokens == NULL) { - return 0; - } - token = jsmn_alloc_token(parser, tokens, num_tokens); - if (token == NULL) { - parser->pos = start; - return JSMN_ERROR_NOMEM; - } - jsmn_fill_token(token, JSMN_STRING, start + 1, parser->pos); -#ifdef JSMN_PARENT_LINKS - token->parent = parser->toksuper; -#endif - return 0; - } - - /* Backslash: Quoted symbol expected */ - if (c == '\\' && parser->pos + 1 < len) { - int i; - parser->pos++; - switch (js[parser->pos]) { - /* Allowed escaped symbols */ - case '\"': - case '/': - case '\\': - case 'b': - case 'f': - case 'r': - case 'n': - case 't': - break; - /* Allows escaped symbol \uXXXX */ - case 'u': - parser->pos++; - for (i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; - i++) { - /* If it isn't a hex character we have an error */ - if (!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */ - (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */ - (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */ - parser->pos = start; - return JSMN_ERROR_INVAL; - } - parser->pos++; - } - parser->pos--; - break; - /* Unexpected symbol */ - default: - parser->pos = start; - return JSMN_ERROR_INVAL; - } - } - } - parser->pos = start; - return JSMN_ERROR_PART; -} - -/** - * Parse JSON string and fill tokens. - */ -JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len, - jsmntok_t *tokens, const unsigned int num_tokens) { - int r; - int i; - jsmntok_t *token; - int count = parser->toknext; - - for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { - char c; - jsmntype_t type; - - c = js[parser->pos]; - switch (c) { - case '{': - case '[': - count++; - if (tokens == NULL) { - break; - } - token = jsmn_alloc_token(parser, tokens, num_tokens); - if (token == NULL) { - return JSMN_ERROR_NOMEM; - } - if (parser->toksuper != -1) { - jsmntok_t *t = &tokens[parser->toksuper]; -#ifdef JSMN_STRICT - /* In strict mode an object or array can't become a key */ - if (t->type == JSMN_OBJECT) { - return JSMN_ERROR_INVAL; - } -#endif - t->size++; -#ifdef JSMN_PARENT_LINKS - token->parent = parser->toksuper; -#endif - } - token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); - token->start = parser->pos; - parser->toksuper = parser->toknext - 1; - break; - case '}': - case ']': - if (tokens == NULL) { - break; - } - type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); -#ifdef JSMN_PARENT_LINKS - if (parser->toknext < 1) { - return JSMN_ERROR_INVAL; - } - token = &tokens[parser->toknext - 1]; - for (;;) { - if (token->start != -1 && token->end == -1) { - if (token->type != type) { - return JSMN_ERROR_INVAL; - } - token->end = parser->pos + 1; - parser->toksuper = token->parent; - break; - } - if (token->parent == -1) { - if (token->type != type || parser->toksuper == -1) { - return JSMN_ERROR_INVAL; - } - break; - } - token = &tokens[token->parent]; - } -#else - for (i = parser->toknext - 1; i >= 0; i--) { - token = &tokens[i]; - if (token->start != -1 && token->end == -1) { - if (token->type != type) { - return JSMN_ERROR_INVAL; - } - parser->toksuper = -1; - token->end = parser->pos + 1; - break; - } - } - /* Error if unmatched closing bracket */ - if (i == -1) { - return JSMN_ERROR_INVAL; - } - for (; i >= 0; i--) { - token = &tokens[i]; - if (token->start != -1 && token->end == -1) { - parser->toksuper = i; - break; - } - } -#endif - break; - case '\"': - r = jsmn_parse_string(parser, js, len, tokens, num_tokens); - if (r < 0) { - return r; - } - count++; - if (parser->toksuper != -1 && tokens != NULL) { - tokens[parser->toksuper].size++; - } - break; - case '\t': - case '\r': - case '\n': - case ' ': - break; - case ':': - parser->toksuper = parser->toknext - 1; - break; - case ',': - if (tokens != NULL && parser->toksuper != -1 && - tokens[parser->toksuper].type != JSMN_ARRAY && - tokens[parser->toksuper].type != JSMN_OBJECT) { -#ifdef JSMN_PARENT_LINKS - parser->toksuper = tokens[parser->toksuper].parent; -#else - for (i = parser->toknext - 1; i >= 0; i--) { - if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) { - if (tokens[i].start != -1 && tokens[i].end == -1) { - parser->toksuper = i; - break; - } - } - } -#endif - } - break; -#ifdef JSMN_STRICT - /* In strict mode primitives are: numbers and booleans */ - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case 't': - case 'f': - case 'n': - /* And they must not be keys of the object */ - if (tokens != NULL && parser->toksuper != -1) { - const jsmntok_t *t = &tokens[parser->toksuper]; - if (t->type == JSMN_OBJECT || - (t->type == JSMN_STRING && t->size != 0)) { - return JSMN_ERROR_INVAL; - } - } -#else - /* In non-strict mode every unquoted value is a primitive */ - default: -#endif - r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens); - if (r < 0) { - return r; - } - count++; - if (parser->toksuper != -1 && tokens != NULL) { - tokens[parser->toksuper].size++; - } - break; - -#ifdef JSMN_STRICT - /* Unexpected char in strict mode */ - default: - return JSMN_ERROR_INVAL; -#endif - } - } - - if (tokens != NULL) { - for (i = parser->toknext - 1; i >= 0; i--) { - /* Unmatched opened object or array */ - if (tokens[i].start != -1 && tokens[i].end == -1) { - return JSMN_ERROR_PART; - } - } - } - - return count; -} - -/** - * Creates a new parser based over a given buffer with an array of tokens - * available. - */ -JSMN_API void jsmn_init(jsmn_parser *parser) { - parser->pos = 0; - parser->toknext = 0; - parser->toksuper = -1; -} - -#endif /* JSMN_HEADER */ - -#ifdef __cplusplus -} -#endif - -#endif /* JSMN_H */ diff --git a/grub-core/lib/json/json.c b/grub-core/lib/json/json.c deleted file mode 100644 index 1eadd1ce9..000000000 --- a/grub-core/lib/json/json.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2019 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#define JSMN_STATIC -#include "jsmn.h" -#include "json.h" - -GRUB_MOD_LICENSE ("GPLv3"); - -grub_err_t -grub_json_parse (grub_json_t **out, char *string, grub_size_t string_len) -{ - grub_json_t *json = NULL; - jsmn_parser parser; - grub_err_t ret = GRUB_ERR_NONE; - int jsmn_ret; - - if (!string) - return GRUB_ERR_BAD_ARGUMENT; - - json = grub_zalloc (sizeof (*json)); - if (!json) - return GRUB_ERR_OUT_OF_MEMORY; - json->string = string; - - /* - * Parse the string twice: first to determine how many tokens - * we need to allocate, second to fill allocated tokens. - */ - jsmn_init (&parser); - jsmn_ret = jsmn_parse (&parser, string, string_len, NULL, 0); - if (jsmn_ret <= 0) - { - ret = GRUB_ERR_BAD_ARGUMENT; - goto err; - } - - json->tokens = grub_calloc (jsmn_ret, sizeof (jsmntok_t)); - if (!json->tokens) - { - ret = GRUB_ERR_OUT_OF_MEMORY; - goto err; - } - - jsmn_init (&parser); - jsmn_ret = jsmn_parse (&parser, string, string_len, json->tokens, jsmn_ret); - if (jsmn_ret <= 0) - { - ret = GRUB_ERR_BAD_ARGUMENT; - goto err; - } - - *out = json; - - err: - if (ret) - grub_json_free (json); - - return ret; -} - -void -grub_json_free (grub_json_t *json) -{ - if (json) - { - grub_free (json->tokens); - grub_free (json); - } -} - -grub_err_t -grub_json_getsize (grub_size_t *out, const grub_json_t *json) -{ - int size; - - size = json->tokens[json->idx].size; - if (size < 0) - return GRUB_ERR_OUT_OF_RANGE; - - *out = (grub_size_t) size; - return GRUB_ERR_NONE; -} - -grub_err_t -grub_json_gettype (grub_json_type_t *out, const grub_json_t *json) -{ - switch (json->tokens[json->idx].type) - { - case JSMN_OBJECT: - *out = GRUB_JSON_OBJECT; - break; - case JSMN_ARRAY: - *out = GRUB_JSON_ARRAY; - break; - case JSMN_STRING: - *out = GRUB_JSON_STRING; - break; - case JSMN_PRIMITIVE: - *out = GRUB_JSON_PRIMITIVE; - break; - default: - return GRUB_ERR_BAD_ARGUMENT; - } - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_json_getchild (grub_json_t *out, const grub_json_t *parent, grub_size_t n) -{ - grub_size_t offset = 1, size; - jsmntok_t *p; - - if (grub_json_getsize (&size, parent) || n >= size) - return GRUB_ERR_OUT_OF_RANGE; - - /* - * Skip the first n children. For each of the children, we need - * to skip their own potential children (e.g. if it's an - * array), as well. We thus add the children's size to n on - * each iteration. - */ - p = &parent->tokens[parent->idx]; - while (n--) - n += p[offset++].size; - - out->string = parent->string; - out->tokens = parent->tokens; - out->idx = parent->idx + offset; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_json_getvalue (grub_json_t *out, const grub_json_t *parent, const char *key) -{ - grub_json_type_t type; - grub_size_t i, size; - - if (grub_json_gettype (&type, parent) || type != GRUB_JSON_OBJECT) - return GRUB_ERR_BAD_ARGUMENT; - - if (grub_json_getsize (&size, parent)) - return GRUB_ERR_BAD_ARGUMENT; - - for (i = 0; i < size; i++) - { - grub_json_t child; - const char *s; - - if (grub_json_getchild (&child, parent, i) || - grub_json_getstring (&s, &child, NULL) || - grub_strcmp (s, key) != 0) - continue; - - return grub_json_getchild (out, &child, 0); - } - - return GRUB_ERR_FILE_NOT_FOUND; -} - -static grub_err_t -get_value (grub_json_type_t *out_type, const char **out_string, const grub_json_t *parent, const char *key) -{ - const grub_json_t *p = parent; - grub_json_t child; - grub_err_t ret; - jsmntok_t *tok; - - if (key) - { - ret = grub_json_getvalue (&child, parent, key); - if (ret) - return ret; - p = &child; - } - - tok = &p->tokens[p->idx]; - p->string[tok->end] = '\0'; - - *out_string = p->string + tok->start; - - return grub_json_gettype (out_type, p); -} - -grub_err_t -grub_json_getstring (const char **out, const grub_json_t *parent, const char *key) -{ - grub_json_type_t type; - const char *value; - grub_err_t ret; - - ret = get_value (&type, &value, parent, key); - if (ret) - return ret; - if (type != GRUB_JSON_STRING) - return GRUB_ERR_BAD_ARGUMENT; - - *out = value; - return GRUB_ERR_NONE; -} - -grub_err_t -grub_json_getuint64 (grub_uint64_t *out, const grub_json_t *parent, const char *key) -{ - grub_json_type_t type; - const char *value; - const char *end; - grub_err_t ret; - - ret = get_value (&type, &value, parent, key); - if (ret) - return ret; - if (type != GRUB_JSON_STRING && type != GRUB_JSON_PRIMITIVE) - return GRUB_ERR_BAD_ARGUMENT; - - grub_errno = GRUB_ERR_NONE; - *out = grub_strtoul (value, &end, 10); - if (grub_errno != GRUB_ERR_NONE || *end) - return GRUB_ERR_BAD_NUMBER; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_json_getint64 (grub_int64_t *out, const grub_json_t *parent, const char *key) -{ - grub_json_type_t type; - const char *value; - const char *end; - grub_err_t ret; - - ret = get_value (&type, &value, parent, key); - if (ret) - return ret; - if (type != GRUB_JSON_STRING && type != GRUB_JSON_PRIMITIVE) - return GRUB_ERR_BAD_ARGUMENT; - - grub_errno = GRUB_ERR_NONE; - *out = grub_strtol (value, &end, 10); - if (grub_errno != GRUB_ERR_NONE || *end) - return GRUB_ERR_BAD_NUMBER; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_json_unescape (char **out, grub_size_t *outlen, const char *in, grub_size_t inlen) -{ - grub_err_t ret = GRUB_ERR_NONE; - grub_size_t inpos, resultpos; - char *result; - - if (out == NULL || outlen == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("output parameters are not set")); - - result = grub_calloc (1, inlen + 1); - if (result == NULL) - return GRUB_ERR_OUT_OF_MEMORY; - - for (inpos = resultpos = 0; inpos < inlen; inpos++) - { - if (in[inpos] == '\\') - { - inpos++; - if (inpos >= inlen) - { - ret = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("expected escaped character")); - goto err; - } - - switch (in[inpos]) - { - case '"': - result[resultpos++] = '"'; - break; - - case '/': - result[resultpos++] = '/'; - break; - - case '\\': - result[resultpos++] = '\\'; - break; - - case 'b': - result[resultpos++] = '\b'; - break; - - case 'f': - result[resultpos++] = '\f'; - break; - - case 'r': - result[resultpos++] = '\r'; - break; - - case 'n': - result[resultpos++] = '\n'; - break; - - case 't': - result[resultpos++] = '\t'; - break; - - case 'u': - { - char values[4] = {0}; - unsigned i; - - inpos++; - if (inpos + ARRAY_SIZE(values) > inlen) - { - ret = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unicode sequence too short")); - goto err; - } - - for (i = 0; i < ARRAY_SIZE(values); i++) - { - char c = in[inpos++]; - - if (c >= '0' && c <= '9') - values[i] = c - '0'; - else if (c >= 'A' && c <= 'F') - values[i] = c - 'A' + 10; - else if (c >= 'a' && c <= 'f') - values[i] = c - 'a' + 10; - else - { - ret = grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unicode sequence with invalid character '%c'"), c); - goto err; - } - } - - if (values[0] != 0 || values[1] != 0) - result[resultpos++] = values[0] << 4 | values[1]; - result[resultpos++] = values[2] << 4 | values[3]; - - /* Offset the increment that's coming in via the loop increment. */ - inpos--; - - break; - } - - default: - ret = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unrecognized escaped character '%c'"), in[inpos]); - goto err; - } - } - else - result[resultpos++] = in[inpos]; - } - - *out = result; - *outlen = resultpos; - - err: - if (ret != GRUB_ERR_NONE) - grub_free (result); - - return ret; -} diff --git a/grub-core/lib/json/json.h b/grub-core/lib/json/json.h deleted file mode 100644 index 626074c35..000000000 --- a/grub-core/lib/json/json.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2019 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_JSON_JSON_H -#define GRUB_JSON_JSON_H 1 - -#include - -enum grub_json_type -{ - /* Unordered collection of key-value pairs. */ - GRUB_JSON_OBJECT, - /* Ordered list of zero or more values. */ - GRUB_JSON_ARRAY, - /* Zero or more Unicode characters. */ - GRUB_JSON_STRING, - /* Number, boolean or empty value. */ - GRUB_JSON_PRIMITIVE, - /* Invalid token. */ - GRUB_JSON_UNDEFINED, -}; -typedef enum grub_json_type grub_json_type_t; - -/* Forward-declaration to avoid including jsmn.h. */ -struct jsmntok; - -struct grub_json -{ - struct jsmntok *tokens; - char *string; - grub_size_t idx; -}; -typedef struct grub_json grub_json_t; - -/* - * Parse a JSON-encoded string. Note that the string passed to - * this function will get modified on subsequent calls to - * grub_json_get*(). Returns the root object of the parsed JSON - * object, which needs to be free'd via grub_json_free(). Callers - * must ensure that the string outlives the returned root object, - * and that child objects must not be used after the root object - * has been free'd. - */ -extern grub_err_t EXPORT_FUNC(grub_json_parse) (grub_json_t **out, - char *string, - grub_size_t string_len); - -/* - * Free the structure and its contents. The string passed to - * grub_json_parse() will not be free'd. - */ -extern void EXPORT_FUNC(grub_json_free) (grub_json_t *json); - -/* - * Get the child count of a valid grub_json_t instance. Children - * are present for arrays, objects (dicts) and keys of a dict. - */ -extern grub_err_t EXPORT_FUNC(grub_json_getsize) (grub_size_t *out, - const grub_json_t *json); - -/* Get the type of a valid grub_json_t instance. */ -extern grub_err_t EXPORT_FUNC(grub_json_gettype) (grub_json_type_t *out, - const grub_json_t *json); - -/* - * Get n'th child of a valid object, array or key. Will return an - * error if no such child exists. The result does not need to be - * free'd. - */ -extern grub_err_t EXPORT_FUNC(grub_json_getchild) (grub_json_t *out, - const grub_json_t *parent, - grub_size_t n); - -/* - * Get value of key from a valid grub_json_t instance. The result - * does not need to be free'd. - */ -extern grub_err_t EXPORT_FUNC(grub_json_getvalue) (grub_json_t *out, - const grub_json_t *parent, - const char *key); - -/* - * Get the string representation of a valid grub_json_t instance. - * If a key is given and parent is a JSON object, this function - * will return the string value of a child mapping to the key. - * If no key is given, it will return the string value of the - * parent itself. - */ -extern grub_err_t EXPORT_FUNC(grub_json_getstring) (const char **out, - const grub_json_t *parent, - const char *key); - -/* - * Get the uint64 representation of a valid grub_json_t instance. - * Returns an error if the value pointed to by `parent` cannot be - * converted to an uint64. See grub_json_getstring() for details - * on the key parameter. - */ -extern grub_err_t EXPORT_FUNC(grub_json_getuint64) (grub_uint64_t *out, - const grub_json_t *parent, - const char *key); - -/* - * Get the int64 representation of a valid grub_json_t instance. - * Returns an error if the value pointed to by `parent` cannot be - * converted to an int64. See grub_json_getstring() for - * details on the key parameter. - */ -extern grub_err_t EXPORT_FUNC(grub_json_getint64) (grub_int64_t *out, - const grub_json_t *parent, - const char *key); - -/* - * Unescape escaped characters and Unicode sequences in the - * given JSON-encoded string. Returns a newly allocated string - * passed back via the `out` parameter that has a length of - * `*outlen`. - * - * See https://datatracker.ietf.org/doc/html/rfc8259#section-7 for more - * information on escaping in JSON. - */ -extern grub_err_t EXPORT_FUNC(grub_json_unescape) (char **out, grub_size_t *outlen, - const char *in, grub_size_t inlen); - -#endif diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c deleted file mode 100644 index fa0131a1e..000000000 --- a/grub-core/lib/legacy_parse.c +++ /dev/null @@ -1,875 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2010,2012 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -#pragma GCC diagnostic ignored "-Wformat-nonliteral" - -struct legacy_command -{ - const char *name; - const char *map; - const char *suffix; - unsigned suffixarg; - unsigned argc; - enum arg_type { - TYPE_VERBATIM, - TYPE_FORCE_OPTION, - TYPE_NOAPM_OPTION, - TYPE_TYPE_OR_NOMEM_OPTION, - TYPE_OPTION, - TYPE_FILE, - TYPE_FILE_NO_CONSUME, - TYPE_PARTITION, - TYPE_BOOL, - TYPE_INT, - TYPE_REST_VERBATIM, - TYPE_VBE_MODE, - TYPE_WITH_CONFIGFILE_OPTION - } argt[4]; - enum { - FLAG_IGNORE_REST = 0x001, - FLAG_FALLBACK_AVAILABLE = 0x004, - FLAG_FALLBACK = 0x008, - FLAG_COLOR_INVERT = 0x010, - FLAG_NO_MENUENTRY = 0x020, - FLAG_MENUENTRY_ONLY = 0x040, - FLAG_TERMINAL = 0x080, - FLAG_TITLE = 0x100, - } flags; - const char *shortdesc; - const char *longdesc; -}; - -/* Help texts are kept here mostly for reference. They are never shown. So - no need to gettextize. - */ -static struct legacy_command legacy_commands[] = - { - /* FIXME: background unsupported. */ - {"blocklist", "blocklist '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE", - "Print the blocklist notation of the file FILE."}, - {"boot", "boot\n", NULL, 0, 0, {}, 0, 0, - "Boot the OS/chain-loader which has been loaded."}, - {"bootp", "net_bootp; net_ls_addr; echo $\"" N_("Default server is ${net_default_server}") "\"; if [ x%s = x--with-configfile ]; then " - "if net_get_dhcp_option configfile_name pxe 150 string; then " - "configfile $configfile_name; fi; fi\n", NULL, 0, 1, - {TYPE_WITH_CONFIGFILE_OPTION}, FLAG_IGNORE_REST, "[--with-configfile]", - "Initialize a network device via BOOTP. If the option `--with-configfile'" - " is given, try to load a configuration file specified by the 150 vendor" - " tag."}, - /* FIXME: border unsupported. */ - {"cat", "cat '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE", - "Print the contents of the file FILE."}, - {"chainloader", "chainloader %s '%s'\n", NULL, 0, - 2, {TYPE_FORCE_OPTION, TYPE_FILE}, 0, "[--force] FILE", - "Load the chain-loader FILE. If --force is specified, then load it" - " forcibly, whether the boot loader signature is present or not."}, - {"clear", "clear\n", NULL, 0, 0, {}, 0, 0, - "Clear the screen."}, - {"cmp", "cmp '%s' '%s'\n", NULL, 0, - 2, {TYPE_FILE, TYPE_FILE}, FLAG_IGNORE_REST, "FILE1 FILE2", - "Compare the file FILE1 with the FILE2 and inform the different values" - " if any."}, - {"color", "set color_normal='%s'; set color_highlight='%s'\n", NULL, 0, - 2, {TYPE_VERBATIM, TYPE_VERBATIM}, - FLAG_IGNORE_REST | FLAG_FALLBACK_AVAILABLE, "NORMAL [HIGHLIGHT]", - "Change the menu colors. The color NORMAL is used for most" - " lines in the menu, and the color HIGHLIGHT is used to highlight the" - " line where the cursor points. If you omit HIGHLIGHT, then the" - " inverted color of NORMAL is used for the highlighted line." - " The format of a color is \"FG/BG\". FG and BG are symbolic color names." - " A symbolic color name must be one of these: black, blue, green," - " cyan, red, magenta, brown, light-gray, dark-gray, light-blue," - " light-green, light-cyan, light-red, light-magenta, yellow and white." - " But only the first eight names can be used for BG. You can prefix" - " \"blink-\" to FG if you want a blinking foreground color."}, - {"color", "set color_normal='%s'; set color_highlight='%s'\n", NULL, 0, - 1, {TYPE_VERBATIM}, - FLAG_IGNORE_REST | FLAG_FALLBACK | FLAG_COLOR_INVERT, NULL, NULL}, - {"configfile", "legacy_configfile '%s'\n", NULL, 0, 1, {TYPE_FILE}, - 0, "FILE", "Load FILE as the configuration file."}, - {"debug", - "if [ -z \"$debug\" ]; then set debug=all; else set debug=; fi\n", NULL, 0, - 0, {}, 0, 0, "Turn on/off the debug mode."}, - {"default", - "set default='%s'; if [ x\"$default\" = xsaved ]; then load_env; " - "set default=\"$saved_entry\"; fi\n", NULL, 0, 1, {TYPE_VERBATIM}, 0, - "[NUM | `saved']", - "Set the default entry to entry number NUM (if not specified, it is" - " 0, the first entry) or the entry number saved by savedefault."}, - {"dhcp", "net_bootp; net_ls_addr; if [ x%s = x--with-configfile ]; then " - "if net_get_dhcp_option configfile_name pxe 150 string; then " - "configfile $configfile_name; fi; fi\n", NULL, 0, 1, - {TYPE_WITH_CONFIGFILE_OPTION}, FLAG_IGNORE_REST, "[--with-configfile]", - "Initialize a network device via BOOTP. If the option `--with-configfile'" - " is given, try to load a configuration file specified by the 150 vendor" - " tag."}, - {"displayapm", "lsapm\n", NULL, 0, 0, {}, 0, 0, - "Display APM BIOS information."}, - {"displaymem", "lsmmap\n", NULL, 0, 0, {}, 0, 0, - "Display what GRUB thinks the system address space map of the" - " machine is, including all regions of physical RAM installed."}, - /* FIXME: device and efimap unsupported. */ - /* NOTE: embed unsupported. */ - {"fallback", "set fallback='%s'\n", NULL, 0, - 1, {TYPE_VERBATIM}, 0, "NUM...", - "Go into unattended boot mode: if the default boot entry has any" - " errors, instead of waiting for the user to do anything, it" - " immediately starts over using the NUM entry (same numbering as the" - " `default' command). This obviously won't help if the machine" - " was rebooted by a kernel that GRUB loaded."}, - {"find", "search -f '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILENAME", - "Search for the filename FILENAME in all of partitions and print the list of" - " the devices which contain the file."}, - /* FIXME: findiso unsupported. */ - /* FIXME: foreground unsupported. */ - /* FIXME: fstest unsupported. */ - /* NOTE: The obsolete C/H/S geometry isn't shown anymore. */ - {"geometry", "insmod regexp; ls -l (%s*)\n", NULL, 0, 1, {TYPE_VERBATIM}, 0, "DRIVE", - "Print the information for a drive DRIVE. "}, - {"halt", "halt %s\n", NULL, 0, 1, {TYPE_NOAPM_OPTION}, 0, "[--no-apm]", - "Halt your system. If APM is available on it, turn off the power using" - " the APM BIOS, unless you specify the option `--no-apm'."}, - /* FIXME: help unsupported. */ /* NUL_TERMINATE */ - {"hiddenmenu", NULL, - "if sleep -i $timeout; then timeout=0; else timeout=-1; fi\n", 0, - 0, {}, 0, "", "Hide the menu."}, - {"hide", "parttool '%s' hidden+\n", NULL, 0, 1, {TYPE_PARTITION}, - 0, "PARTITION", - "Hide PARTITION by setting the \"hidden\" bit in" - " its partition type code."}, - /* FIXME: ifconfig unsupported. */ - /* FIXME: impsprobe unsupported. */ - {"initrd", "legacy_initrd '%s' %s\n", NULL, 0, 2, {TYPE_FILE_NO_CONSUME, - TYPE_REST_VERBATIM}, 0, - "FILE [ARG ...]", - "Load an initial ramdisk FILE for a Linux format boot image and set the" - " appropriate parameters in the Linux setup area in memory."}, - /* NOTE: install unsupported. */ - /* FIXME: ioprobe unsupported. */ - /* FIXME: really support --no-mem-option. */ - {"kernel", "legacy_kernel %s %s '%s' %s\n", NULL, 0, - 4, {TYPE_TYPE_OR_NOMEM_OPTION, TYPE_TYPE_OR_NOMEM_OPTION, - TYPE_FILE_NO_CONSUME, TYPE_REST_VERBATIM}, 0, - "[--no-mem-option] [--type=TYPE] FILE [ARG ...]", - "Attempt to load the primary boot image from FILE. The rest of the" - " line is passed verbatim as the \"kernel command line\". Any modules" - " must be reloaded after using this command. The option --type is used" - " to suggest what type of kernel to be loaded. TYPE must be either of" - " \"netbsd\", \"freebsd\", \"openbsd\", \"linux\", \"biglinux\" and" - " \"multiboot\". The option --no-mem-option tells GRUB not to pass a" - " Linux's mem option automatically."}, - {"lock", "if ! authenticate legacy; then return; fi", NULL, 0, 0, {}, 0, - 0, "Break a command execution unless the user is authenticated."}, - {"makeactive", "parttool \"$root\" boot+\n", NULL, 0, 0, {}, 0, 0, - "Set the active partition on the root disk to GRUB's root device." - " This command is limited to _primary_ PC partitions on a hard disk."}, - {"map", "drivemap '%s' '%s'\n", NULL, 0, - 2, {TYPE_PARTITION, TYPE_PARTITION}, - FLAG_IGNORE_REST, "TO_DRIVE FROM_DRIVE", - "Map the drive FROM_DRIVE to the drive TO_DRIVE. This is necessary" - " when you chain-load some operating systems, such as DOS, if such an" - " OS resides at a non-first drive."}, - /* NOTE: md5crypt unsupported since GRUB has not enough entropy and this - hash shouldn't be used anymore. */ - {"module", "legacy_initrd '%s' %s\n", NULL, 0, 2, {TYPE_FILE_NO_CONSUME, - TYPE_REST_VERBATIM}, 0, - "FILE [ARG ...]", - "Load a boot module FILE for a Multiboot format boot image (no" - " interpretation of the file contents is made, so users of this" - " command must know what the kernel in question expects). The" - " rest of the line is passed as the \"module command line\", like" - " the `kernel' command."}, - {"modulenounzip", "legacy_initrd_nounzip '%s' %s\n", NULL, 0, 2, - {TYPE_FILE_NO_CONSUME, TYPE_REST_VERBATIM}, 0, - "FILE [ARG ...]", - "The same as `module', except that automatic decompression is" - " disabled."}, - {"pager", "set pager=%s; if [ \"$pager\" = 0 ]; then " - " echo Internal pager is now off; else " - "echo Internal pager is now on; fi\n", NULL, 0, - 1, {TYPE_BOOL}, FLAG_FALLBACK_AVAILABLE, "[FLAG]", - "Toggle pager mode with no argument. If FLAG is given and its value" - " is `on', turn on the mode. If FLAG is `off', turn off the mode."}, - {"pager", - "if [ \"$pager\" = 1 ]; then pager=0; echo Internal pager is now off;" - "else pager=1; echo Internal pager is now on; fi\n", NULL, 0, 0, {}, - FLAG_FALLBACK, NULL, NULL}, - /* FIXME: partnew unsupported. */ - {"parttype", "parttool '%s' type=%s\n", NULL, 0, - 2, {TYPE_PARTITION, TYPE_INT}, 0, - "PART TYPE", "Change the type of the partition PART to TYPE."}, - {"password", "if [ \"$superusers\" = "" ]; then superusers=legacy; fi;\n" - "legacy_password %s '%s'\n", - "menuentry \"Superuser menu\" --users \"legacy\" { configfile '%s'; }\n", - 2, 3, {TYPE_OPTION, TYPE_VERBATIM, TYPE_FILE}, - FLAG_IGNORE_REST | FLAG_FALLBACK_AVAILABLE | FLAG_NO_MENUENTRY, - "[--md5] PASSWD [FILE]", - "If used in the first section of a menu file, disable all" - " interactive editing control (menu entry editor and" - " command line). If the password PASSWD is entered, it loads the" - " FILE as a new config file and restarts the GRUB Stage 2. If you" - " omit the argument FILE, then GRUB just unlocks privileged" - " instructions. You can also use it in the script section, in" - " which case it will ask for the password, before continuing." - " The option --md5 tells GRUB that PASSWD is encrypted with" - " md5crypt."}, - {"password", "if [ \"$superusers\" = "" ]; then superusers=legacy; fi;\n" - "legacy_password %s '%s'\n", NULL, 0, 2, {TYPE_OPTION, TYPE_VERBATIM}, - FLAG_IGNORE_REST | FLAG_FALLBACK | FLAG_NO_MENUENTRY, NULL, NULL}, - {"password", "if legacy_check_password %s '%s'; then configfile '%s'; " - "else return; fi\n", NULL, 2, 3, {TYPE_OPTION, TYPE_VERBATIM, TYPE_FILE}, - FLAG_IGNORE_REST | FLAG_FALLBACK_AVAILABLE | FLAG_MENUENTRY_ONLY, - NULL, NULL}, - {"password", "if ! legacy_check_password %s '%s'; then return fi;\n", - NULL, 0, 2, {TYPE_OPTION, TYPE_VERBATIM}, - FLAG_IGNORE_REST | FLAG_FALLBACK | FLAG_MENUENTRY_ONLY, NULL, NULL}, - /* NOTE: GRUB2 has a design principle of not eternally waiting for user - input. 60 seconds should be enough. - */ - {"pause", "echo %s; if ! sleep -i 60; then return; fi\n", NULL, 0, 1, - {TYPE_REST_VERBATIM}, 0, - "[MESSAGE ...]", "Print MESSAGE, then wait until a key is pressed."}, - {"print", "echo %s\n", NULL, 0, 1, - {TYPE_REST_VERBATIM}, 0, - "[MESSAGE ...]", "Print MESSAGE."}, - /* FIXME: quit unsupported. */ - /* FIXME: rarp unsupported. */ - {"read", "read_dword %s\n", NULL, 0, 1, {TYPE_INT}, 0, "ADDR", - "Read a 32-bit value from memory at address ADDR and" - " display it in hex format."}, - {"reboot", "reboot\n", NULL, 0, 0, {}, 0, 0, "Reboot your system."}, - {"root", "set root='%s'; set legacy_hdbias='%s'\n", NULL, 0, - 2, {TYPE_PARTITION, TYPE_INT}, FLAG_FALLBACK_AVAILABLE, - "[DEVICE [HDBIAS]]", - "Set the current \"root device\" to the device DEVICE, then" - " attempt to mount it to get the partition size (for passing the" - " partition descriptor in `ES:ESI', used by some chain-loaded" - " bootloaders), the BSD drive-type (for booting BSD kernels using" - " their native boot format), and correctly determine " - " the PC partition where a BSD sub-partition is located. The" - " optional HDBIAS parameter is a number to tell a BSD kernel" - " how many BIOS drive numbers are on controllers before the current" - " one. For example, if there is an IDE disk and a SCSI disk, and your" - " FreeBSD root partition is on the SCSI disk, then use a `1' for HDBIAS."}, - {"root", "echo \"$root\"\n", NULL, 0, 0, {}, FLAG_FALLBACK, NULL, NULL}, - {"rootnoverify", "set root='%s'; set legacy_hdbias='%s'\n", NULL, 0, - 2, {TYPE_PARTITION, TYPE_INT}, 0, - "[DEVICE [HDBIAS]]", - "Similar to `root', but don't attempt to mount the partition. This" - " is useful for when an OS is outside of the area of the disk that" - " GRUB can read, but setting the correct root device is still" - " desired. Note that the items mentioned in `root' which" - " derived from attempting the mount will NOT work correctly."}, - {"rootnoverify", "echo \"$root\"\n", NULL, 0, - 0, {}, FLAG_FALLBACK, NULL, NULL}, - /* FIXME: support saving NUM and fallback. */ - {"savedefault", "saved_entry=${chosen}; save_env saved_entry\n", NULL, 0, - 0, {}, 0, "[NUM | `fallback']", - "Save the current entry as the default boot entry if no argument is" - " specified. If a number is specified, this number is saved. If" - " `fallback' is used, next fallback entry is saved."}, - {"serial", "serial %s\n", NULL, 0, 1, {TYPE_REST_VERBATIM}, 0, - "[--unit=UNIT] [--port=PORT] [--speed=SPEED] [--word=WORD] " - "[--parity=PARITY] [--stop=STOP] [--device=DEV]", - "Initialize a serial device. UNIT is a digit that specifies which serial" - " device is used (e.g. 0 == COM1). If you need to specify the port number," - " set it by --port. SPEED is the DTE-DTE speed. WORD is the word length," - " PARITY is the type of parity, which is one of `no', `odd' and `even'." - " STOP is the length of stop bit(s). The option --device can be used only" - " in the grub shell, which specifies the file name of a tty device. The" - " default values are COM1, 9600, 8N1."}, - /* FIXME: shade unsupported. */ - /* FIXME: silent unsupported. */ - /* FIXME: splashimage unsupported. */ - /* FIXME: setkey unsupported. */ /* NUL_TERMINATE */ - /* NOTE: setup unsupported. */ - /* FIXME: --no-echo, --no-edit unsupported. */ - /* NOTE: both terminals are activated so --silent and --timeout - are useless. */ - /* FIXME: graphics unsupported. */ - {"terminal", NULL, NULL, 0, 0, {}, FLAG_TERMINAL | FLAG_IGNORE_REST, - "[--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] " - "[--silent] [console] [serial] [hercules] [graphics]", - "Select a terminal. When multiple terminals are specified, wait until" - " you push any key to continue. If both console and serial are specified," - " the terminal to which you input a key first will be selected. If no" - " argument is specified, print current setting. The option --dumb" - " specifies that your terminal is dumb, otherwise, vt100-compatibility" - " is assumed. If you specify --no-echo, input characters won't be echoed." - " If you specify --no-edit, the BASH-like editing feature will be disabled." - " If --timeout is present, this command will wait at most for SECS" - " seconds. The option --lines specifies the maximum number of lines." - " The option --silent is used to suppress messages."}, - /* FIXME: terminfo unsupported. */ /* NUL_TERMINATE */ - {"testload", "testload '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE", - "Read the entire contents of FILE in several different ways and" - " compares them, to test the filesystem code. " - " If this test succeeds, then a good next" - " step is to try loading a kernel."}, - {"testvbe", "insmod vbe; videotest '%s'\n", NULL, 0, 1, {TYPE_VBE_MODE}, 0, - "MODE", "Test the VBE mode MODE. Hit any key to return."}, - /* FIXME: tftpserver unsupported. */ - {"timeout", "set timeout=%s\n", NULL, 0, 1, {TYPE_INT}, 0, "SEC", - "Set a timeout, in SEC seconds, before automatically booting the" - " default entry (normally the first entry defined)."}, - {"title", NULL, NULL, 0, 0, {}, FLAG_TITLE, "NAME ...", - "Start a new boot entry, and set its name to the contents of the" - " rest of the line, starting with the first non-space character."}, - {"unhide", "parttool '%s' hidden-\n", NULL, 0, - 1, {TYPE_PARTITION}, 0, "PARTITION", - "Unhide PARTITION by clearing the \"hidden\" bit in its" - " partition type code."}, - /* FIXME: uppermem unsupported. */ - {"uuid", "search --set=root --fs-uuid '%s'\n", NULL, 0, 1, {TYPE_VERBATIM}, - 0, "UUID", "Find root by UUID"}, - {"vbeprobe", "insmod vbe; videoinfo '%s'\n", NULL, 0, 1, {TYPE_VBE_MODE}, - FLAG_FALLBACK_AVAILABLE, "[MODE]", - "Probe VBE information. If the mode number MODE is specified, show only" - " the information about only the mode."}, - {"vbeprobe", "insmod vbe; videoinfo\n", NULL, 0, 0, {}, - FLAG_FALLBACK, NULL, NULL} - /* FIXME: verbose unsupported. */ - /* FIXME: version unsupported. */ - /* FIXME: viewport unsupported. */ - }; - -char * -grub_legacy_escape (const char *in, grub_size_t len) -{ - char *ptr; - char *ret; - char saved; - int overhead = 0; - - for (ptr = (char*)in; ptr < in + len && *ptr; ptr++) - if (*ptr == '\'') - overhead += 3; - ret = grub_malloc (ptr - in + overhead + 1); - if (!ret) - return NULL; - - ptr = (char*)in; - saved = ptr[len]; - ptr[len] = '\0'; - grub_strchrsub (ret, ptr, '\'', "'\\''"); - ptr[len] = saved; - return ret; -} - -static char * -adjust_file (const char *in, grub_size_t len) -{ - const char *comma, *ptr, *rest; - char *ret, *outptr; - int overhead = 0; - int part = -1, subpart = -1; - if (in[0] != '(') - return grub_legacy_escape (in, len); - for (ptr = in + 1; ptr < in + len && *ptr && *ptr != ')' - && *ptr != ','; ptr++) - if (*ptr == '\'' || *ptr == '\\') - overhead++; - comma = ptr; - if (*comma == ')' && comma - in == 3 - && in[1] == 'n' && in[2] == 'd') - { - rest = comma + 1; - for (ptr = rest; ptr < in + len && *ptr; ptr++) - if (*ptr == '\'' || *ptr == '\\') - overhead++; - - ret = grub_malloc (ptr - in + overhead + 15); - if (!ret) - return NULL; - - outptr = grub_stpcpy (ret, "(tftp)");; - for (ptr = rest; ptr < in + len; ptr++) - { - if (*ptr == '\'' || *ptr == '\\') - *outptr++ = '\\'; - - *outptr++ = *ptr; - } - *outptr = 0; - return ret; - } - if (*comma != ',') - return grub_legacy_escape (in, len); - part = grub_strtoull (comma + 1, &rest, 0); - if (rest[0] == ',' && rest[1] >= 'a' && rest[1] <= 'z') - { - subpart = rest[1] - 'a'; - rest += 2; - } - for (ptr = rest; ptr < in + len && *ptr; ptr++) - if (*ptr == '\'' || *ptr == '\\') - overhead++; - - /* 35 is enough for any 2 numbers. */ - ret = grub_malloc (ptr - in + overhead + 35 + 5); - if (!ret) - return NULL; - - outptr = ret; - for (ptr = in; ptr < in + len && ptr <= comma; ptr++) - { - if (*ptr == '\'' || *ptr == '\\') - *outptr++ = '\\'; - - *outptr++ = *ptr; - } - if (subpart != -1) - grub_snprintf (outptr, 35, "%d,%d", part + 1, subpart + 1); - else - grub_snprintf (outptr, 35, "%d", part + 1); - while (*outptr) - outptr++; - for (ptr = rest; ptr < in + len; ptr++) - { - if (*ptr == '\'' || *ptr == '\\') - *outptr++ = '\\'; - - *outptr++ = *ptr; - } - *outptr = 0; - return ret; -} - -static int -check_option (const char *a, const char *b, grub_size_t len) -{ - if (grub_strlen (b) != len) - return 0; - return grub_strncmp (a, b, len) == 0; -} - -static int -is_option (enum arg_type opt, const char *curarg, grub_size_t len) -{ - switch (opt) - { - case TYPE_WITH_CONFIGFILE_OPTION: - return check_option (curarg, "--with-configfile", len); - case TYPE_NOAPM_OPTION: - return check_option (curarg, "--no-apm", len); - case TYPE_FORCE_OPTION: - return check_option (curarg, "--force", len); - case TYPE_TYPE_OR_NOMEM_OPTION: - return check_option (curarg, "--type=netbsd", len) - || check_option (curarg, "--type=freebsd", len) - || check_option (curarg, "--type=openbsd", len) - || check_option (curarg, "--type=linux", len) - || check_option (curarg, "--type=biglinux", len) - || check_option (curarg, "--type=multiboot", len) - || check_option (curarg, "--no-mem-option", len); - case TYPE_OPTION: - return (len >= 2 && curarg[0] == '-' && curarg[1] == '-'); - default: - return 0; - } -} - -char * -grub_legacy_parse (const char *buf, char **entryname, char **suffix) -{ - const char *ptr; - const char *cmdname; - unsigned i, cmdnum; - char *args[ARRAY_SIZE (legacy_commands[0].argt)]; - - *suffix = NULL; - - for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); - if (!*ptr || *ptr == '#') - { - char *ret; - int len = grub_strlen (buf); - ret = grub_malloc (len + 2); - grub_memcpy (ret, buf, len); - if (len && ret[len - 1] == '\n') - ret[len] = 0; - else - { - ret[len] = '\n'; - ret[len + 1] = 0; - } - return ret; - } - - cmdname = ptr; - for (ptr = buf; *ptr && !grub_isspace (*ptr) && *ptr != '='; ptr++); - - for (cmdnum = 0; cmdnum < ARRAY_SIZE (legacy_commands); cmdnum++) - if (grub_strncmp (legacy_commands[cmdnum].name, cmdname, ptr - cmdname) == 0 - && legacy_commands[cmdnum].name[ptr - cmdname] == 0 - && (!(*entryname != NULL && (legacy_commands[cmdnum].flags - & FLAG_NO_MENUENTRY))) - && (!(*entryname == NULL && (legacy_commands[cmdnum].flags - & FLAG_MENUENTRY_ONLY)))) - break; - if (cmdnum == ARRAY_SIZE (legacy_commands)) - return grub_xasprintf ("# Unsupported legacy command: %s\n", buf); - - for (; grub_isspace (*ptr) || *ptr == '='; ptr++); - - if (legacy_commands[cmdnum].flags & FLAG_TITLE) - { - const char *ptr2; - ptr2 = ptr + grub_strlen (ptr); - while (ptr2 > ptr && grub_isspace (*(ptr2 - 1))) - ptr2--; - *entryname = grub_strndup (ptr, ptr2 - ptr); - return NULL; - } - - if (legacy_commands[cmdnum].flags & FLAG_TERMINAL) - { - int dumb = 0, lines = 24; -#ifdef TODO - int no_echo = 0, no_edit = 0; -#endif - int hercules = 0; - int console = 0, serial = 0, graphics = 0; - /* Big enough for any possible resulting command. */ - char outbuf[512] = ""; - char *outptr; - while (*ptr) - { - /* "[--timeout=SECS] [--silent]" - " [console] [serial] [hercules]"*/ - if (grub_memcmp (ptr, "--dumb", sizeof ("--dumb") - 1) == 0) - dumb = 1; -#ifdef TODO - if (grub_memcmp (ptr, "--no-echo", sizeof ("--no-echo") - 1) == 0) - no_echo = 1; - - if (grub_memcmp (ptr, "--no-edit", sizeof ("--no-edit") - 1) == 0) - no_edit = 1; -#endif - if (grub_memcmp (ptr, "--lines=", sizeof ("--lines=") - 1) == 0) - { - lines = grub_strtoul (ptr + sizeof ("--lines=") - 1, 0, 0); - if (grub_errno) - { - lines = 24; - grub_errno = GRUB_ERR_NONE; - } - } - - if (grub_memcmp (ptr, "console", sizeof ("console") - 1) == 0) - console = 1; - - if (grub_memcmp (ptr, "serial", sizeof ("serial") - 1) == 0) - serial = 1; - if (grub_memcmp (ptr, "hercules", sizeof ("hercules") - 1) == 0) - hercules = 1; - if (grub_memcmp (ptr, "graphics", sizeof ("graphics") - 1) == 0) - graphics = 1; - while (*ptr && !grub_isspace (*ptr)) - ptr++; - while (*ptr && grub_isspace (*ptr)) - ptr++; - } - - if (!console && !serial && !hercules && !graphics) - return grub_strdup ("terminal_input; terminal_output; terminfo\n"); - - outptr = outbuf; - - if (graphics) - outptr = grub_stpcpy (outptr, "insmod all_video; "); - - outptr = grub_stpcpy (outptr, "terminal_input "); - if (serial) - outptr = grub_stpcpy (outptr, "serial "); - if (console || hercules || graphics) - outptr = grub_stpcpy (outptr, "console "); - outptr = grub_stpcpy (outptr, "; terminal_output "); - if (serial) - outptr = grub_stpcpy (outptr, "serial "); - if (console) - outptr = grub_stpcpy (outptr, "console "); - if (hercules) - outptr = grub_stpcpy (outptr, "mda_text "); - if (graphics) - outptr = grub_stpcpy (outptr, "gfxterm "); - outptr = grub_stpcpy (outptr, "; "); - *outptr = '\0'; - if (serial) - { - grub_snprintf (outptr, outbuf + sizeof (outbuf) - outptr, - "terminfo serial -g 80x%d %s; ", - lines, dumb ? "dumb" : "vt100"); - outptr += grub_strlen (outptr); - } - - grub_strcpy (outptr, "\n"); - - return grub_strdup (outbuf); - } - - grub_memset (args, 0, sizeof (args)); - - { - int hold_arg = 0; - const char *curarg = NULL; - for (i = 0; i < legacy_commands[cmdnum].argc; i++) - { - grub_size_t curarglen; - if (hold_arg) - { - ptr = curarg; - hold_arg = 0; - } - for (; grub_isspace (*ptr); ptr++); - curarg = ptr; - if (!*curarg) - break; - for (; *ptr && !grub_isspace (*ptr); ptr++); - if (i != legacy_commands[cmdnum].argc - 1 - || (legacy_commands[cmdnum].flags & FLAG_IGNORE_REST)) - curarglen = ptr - curarg; - else - { - curarglen = grub_strlen (curarg); - while (curarglen > 0 && grub_isspace (curarg[curarglen - 1])) - curarglen--; - } - if (*ptr) - ptr++; - switch (legacy_commands[cmdnum].argt[i]) - { - case TYPE_FILE_NO_CONSUME: - hold_arg = 1; - /* Fallthrough. */ - case TYPE_PARTITION: - case TYPE_FILE: - args[i] = adjust_file (curarg, curarglen); - break; - - case TYPE_REST_VERBATIM: - { - char *outptr, *outptr0; - int overhead = 3; - ptr = curarg; - while (*ptr) - { - for (; *ptr && grub_isspace (*ptr); ptr++); - for (; *ptr && !grub_isspace (*ptr); ptr++) - if (*ptr == '\'') - overhead += 3; - if (*ptr) - ptr++; - overhead += 3; - } - - outptr0 = args[i] = grub_malloc (overhead + (ptr - curarg)); - if (!outptr0) - return NULL; - ptr = curarg; - outptr = outptr0; - while (*ptr) - { - for (; *ptr && grub_isspace (*ptr); ptr++); - if (outptr != outptr0) - *outptr++ = ' '; - *outptr++ = '\''; - for (; *ptr && !grub_isspace (*ptr); ptr++) - { - if (*ptr == '\'') - { - *outptr++ = '\''; - *outptr++ = '\\'; - *outptr++ = '\''; - *outptr++ = '\''; - } - else - *outptr++ = *ptr; - } - *outptr++ = '\''; - if (*ptr) - ptr++; - } - *outptr++ = 0; - } - break; - - case TYPE_VERBATIM: - args[i] = grub_legacy_escape (curarg, curarglen); - break; - case TYPE_WITH_CONFIGFILE_OPTION: - case TYPE_FORCE_OPTION: - case TYPE_NOAPM_OPTION: - case TYPE_TYPE_OR_NOMEM_OPTION: - case TYPE_OPTION: - if (is_option (legacy_commands[cmdnum].argt[i], curarg, curarglen)) - { - args[i] = grub_strndup (curarg, curarglen); - break; - } - args[i] = grub_strdup (""); - hold_arg = 1; - break; - case TYPE_INT: - { - const char *brk; - int base = 10; - brk = curarg; - if (brk[0] == '0' && brk[1] == 'x') - { - base = 16; - brk += 2; - } - else if (brk[0] == '0') - base = 8; - for (; *brk && brk < curarg + curarglen; brk++) - { - if (base == 8 && (*brk == '8' || *brk == '9')) - break; - if (grub_isdigit (*brk)) - continue; - if (base != 16) - break; - if (!(*brk >= 'a' && *brk <= 'f') - && !(*brk >= 'A' && *brk <= 'F')) - break; - } - if (brk == curarg) - args[i] = grub_strdup ("0"); - else - args[i] = grub_strndup (curarg, brk - curarg); - } - break; - case TYPE_VBE_MODE: - { - unsigned mod; - struct grub_vesa_mode_table_entry *modedesc; - - mod = grub_strtoul (curarg, 0, 0); - if (grub_errno) - { - mod = 0; - grub_errno = GRUB_ERR_NONE; - } - if (mod < GRUB_VESA_MODE_TABLE_START - || mod > GRUB_VESA_MODE_TABLE_END) - { - args[i] = grub_strdup ("auto"); - break; - } - modedesc = &grub_vesa_mode_table[mod - GRUB_VESA_MODE_TABLE_START]; - if (!modedesc->width) - { - args[i] = grub_strdup ("auto"); - break; - } - args[i] = grub_xasprintf ("%ux%ux%u", - modedesc->width, modedesc->height, - modedesc->depth); - break; - } - case TYPE_BOOL: - if (curarglen == 2 && curarg[0] == 'o' && curarg[1] == 'n') - args[i] = grub_strdup ("1"); - else - args[i] = grub_strdup ("0"); - break; - } - } - } - - while (legacy_commands[cmdnum].argc > 0 - && args[legacy_commands[cmdnum].argc - 1] == NULL - && (legacy_commands[cmdnum].flags & FLAG_FALLBACK_AVAILABLE) - && args[legacy_commands[cmdnum + 1].argc] == NULL) - cmdnum++; - - for (; i < legacy_commands[cmdnum].argc; i++) - switch (legacy_commands[cmdnum].argt[i]) - { - case TYPE_FILE_NO_CONSUME: - case TYPE_PARTITION: - case TYPE_FILE: - case TYPE_REST_VERBATIM: - case TYPE_VERBATIM: - case TYPE_WITH_CONFIGFILE_OPTION: - case TYPE_FORCE_OPTION: - case TYPE_NOAPM_OPTION: - case TYPE_TYPE_OR_NOMEM_OPTION: - case TYPE_OPTION: - args[i] = grub_strdup (""); - break; - case TYPE_BOOL: - case TYPE_INT: - args[i] = grub_strdup ("0"); - break; - case TYPE_VBE_MODE: - args[i] = grub_strdup ("auto"); - break; - } - - if (legacy_commands[cmdnum].flags & FLAG_COLOR_INVERT) - { - char *corig = args[legacy_commands[cmdnum].argc - 1]; - char *slash = grub_strchr (corig, '/'); - char *invert; - grub_size_t len; - - len = grub_strlen (corig); - if (!slash) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid color specification `%s'"), - args[0]); - return NULL; - } - invert = grub_malloc (len + 1); - if (!invert) - return NULL; - grub_memcpy (invert, slash + 1, len - (slash - corig) - 1); - invert[len - (slash - args[0]) - 1] = '/'; - grub_memcpy (invert + len - (slash - corig), corig, slash - corig); - invert[len] = 0; - args[legacy_commands[cmdnum].argc] = invert; - } - - if (legacy_commands[cmdnum].suffix) - { - *suffix = grub_xasprintf (legacy_commands[cmdnum].suffix, - args[legacy_commands[cmdnum].suffixarg]); - if (*suffix) - return NULL; - } - - { - char *ret = grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1], - args[2], args[3]); - grub_free (args[0]); - grub_free (args[1]); - grub_free (args[2]); - grub_free (args[3]); - return ret; - } -} diff --git a/grub-core/lib/libgcrypt/cipher/ChangeLog-2011 b/grub-core/lib/libgcrypt/cipher/ChangeLog-2011 deleted file mode 100644 index 05516c99e..000000000 --- a/grub-core/lib/libgcrypt/cipher/ChangeLog-2011 +++ /dev/null @@ -1,4247 +0,0 @@ -2011-12-01 Werner Koch - - NB: ChangeLog files are no longer manually maintained. Starting - on December 1st, 2011 we put change information only in the GIT - commit log, and generate a top-level ChangeLog file from logs at - "make dist". See doc/HACKING for details. - -2011-06-29 Werner Koch - - * cipher.c (cipher_get_keylen): Return zero for an invalid algorithm. - (cipher_get_blocksize): Ditto. - -2011-06-13 Werner Koch - - * dsa.c (selftest_sign_1024): Use the raw and not the pkcs1 flag. - - * pubkey.c (gcry_pk_sign): Special case output generation for PKCS1. - (sexp_data_to_mpi): Parse "random-override" for pkcs1 encryption. - (pkcs1_encode_for_encryption): Add args RANDOM_OVERRIDE and - RANDOM_OVERRIDE_LEN. - (gcry_pk_encrypt): Special case output generation for PKCS1. - (sexp_data_to_mpi): Use GCRYMPI_FMT_USG for raw encoding. - -2011-06-10 Werner Koch - - * pubkey.c (gcry_pk_sign): Use format specifier '%M' to avoid - leading zeroes. Special case output generation for PSS. - (gcry_pk_encrypt): Special case output generation for OAEP. - (sexp_data_to_mpi): Use GCRYMPI_FMT_USG for PSS verify. - -2011-06-09 Werner Koch - - * pubkey.c (oaep_decode): Make use of octet_string_from_mpi. - (sexp_to_enc): Skip "random-override". - - * pubkey.c (oaep_encode, pss_encode): Add args RANDOM_OVERRIDE and - RANDOM_OVERRIDE_LEN. - (sexp_data_to_mpi): Extract new random-override parameter. - - * pubkey.c (pss_encode, pss_verify): Use VALUE verbatim for MHASH. - (octet_string_from_mpi): Add arg SPACE. - -2011-06-08 Werner Koch - - * pubkey.c (pss_encode, pss_verify): Restructure and comment code - to match rfc-3447. Replace secure allocs by plain allocs and - wipememory. Use gcry_md_hash_buffer. - (octet_string_from_mpi): New. - -2011-06-03 Werner Koch - - * pubkey.c (oaep_decode): Add more comments and restructure to - match the description in RFC-3447. - (oaep_encode): Check for mgf1 error. s/dlen/hlen/. - -2011-05-31 Werner Koch - - * pubkey.c (mgf1): Optimize by using gcry_md_reset. Re-implement - for easier readability. - (oaep_encode): Add more comments and restructure to match the - description in RFC-3447. - - * pubkey.c (pkcs1_encode_for_signature, oaep_decode): Change - return value from one MPI to a buffer. - (gcry_pk_decrypt): Adjust for this change. - -2011-05-30 Werner Koch - - * pubkey.c (pkcs1_decode_for_encryption): Change handling of - leading zero byte. - -2011-05-27 Daiki Ueno - - * pubkey.c (gcry_pk_decrypt): Fix double-free when un-padding - invalid data. Thanks to Tom Ritter. - -2011-05-24 Daiki Ueno - - * rsa.c (rsa_verify): Use CMP if given, to check the decrypted - sig. - - * pubkey.c (sexp_to_enc, sexp_data_to_mpi): Factor out - CTX initialization to ... - (init_encoding_ctx): .. new. - (gcry_pk_verify): Pass verify func and the arg to pubkey_verify. - (pss_encode, pss_verify, pss_verify_cmp): New. - -2011-05-23 Daiki Ueno - - * pubkey.c (pkcs1_decode_for_encryption, oaep_decode): Fix memleak - when gcry_mpi_print fails. - -2011-05-18 Daiki Ueno - - * pubkey.c (sexp_data_to_mpi): Factor some code out to ... - (pkcs1_encode_for_encryption): .. new, - (pkcs1_encode_for_signature): .. new. - (pkcs1_decode_for_encryption): New. - (gcry_pk_decrypt): Do un-padding for PKCS#1 as well as OAEP. - (sexp_to_enc): Abolish "unpad" flag, which is not necessary since - we can do un-padding implicitly when "pkcs1" or "oaep" is given. - -2011-05-11 Werner Koch - - * pubkey.c (sexp_to_enc, sexp_data_to_mpi): Set LABEL to NULL - after free. - (sexp_to_enc, sexp_data_to_mpi): Do not allow multiple encoding - flags. - (oaep_encode, oaep_decode, sexp_to_key, sexp_to_sig) - (sexp_to_enc, sexp_data_to_mpi, gcry_pk_encrypt, gcry_pk_sign) - (gcry_pk_genkey, _gcry_pk_get_elements): Replace access to ERRNO - by gpg_err_code_from_syserror. - -2011-05-11 Daiki Ueno - - * pubkey.c (sexp_data_to_mpi): Factor some code out to ... - (get_hash_algo): .. new. - (mgf1, oaep_encode, oaep_decode): New. - (sexp_to_enc): Add arg CTX. Remove arg RET_WANT_PKCS1. Support - OAEP. - (sexp_data_to_mpi): Add arg CTX. Support OAEP. - (gcry_pk_encrypt): Pass a CTX to sexp_data_to_mpi. - (gcry_pk_decrypt): Pass a CTX tp sexp_to_enc and replace - WANT_PKCS1. Implement unpadding for OAEP. - (gcry_pk_sign): Pass NULL for CTX arg of sexp_data_to_mpi. - (gcry_pk_verify): Ditto. - -2011-04-19 Werner Koch - - * cipher.c (gcry_cipher_open): Replace gpg_err_code_from_errno by - gpg_err_code_from_syserror. - -2011-04-11 Werner Koch - - * pubkey.c (gcry_pk_get_keygrip): Avoid double free of L2. - - * cipher.c (_gcry_cipher_setctr): Clear unused lastiv info. - (gcry_cipher_ctl) : Implement by calling - _gcry_cipher_setctr. - (do_ctr_encrypt): Save last counter and reuse it. - - * cipher.c (do_ctr_encrypt): Allow arbitrary length inputs to - match the 1.4 behaviour. - -2011-04-04 Werner Koch - - * ecc.c (compute_keygrip): Release L1 while parsing "curve". - - * pubkey.c (gcry_pk_get_keygrip): Always release NAME and L2. - Reported by Ben Kibbey. - -2011-03-28 Werner Koch - - * primegen.c (_gcry_generate_elg_prime): Make sure that PRIME is - NULL if the called func ever returns an error. - - * pubkey.c (gcry_pk_decrypt): Remove unused var PUBKEY. - -2011-03-09 Werner Koch - - * kdf.c: New. - -2011-02-22 Werner Koch - - * rijndael.c (aesni_cleanup_2_4): New. - (aesenc_xmm1_xmm0, do_aesni_ctr_4): New. - (_gcry_aes_ctr_enc): New. - * cipher.c (struct gcry_cipher_handle): Add CTR_ENC. Move field - CTR into an u_ctr union and adjust all users. - (gcry_cipher_open): Use _gcry_aes_ctr_enc. - (do_ctr_encrypt): Use bulk mode. - -2011-02-18 Werner Koch - - * rijndael.c (u32_a_t): New. - (do_encrypt_aligned, do_encrypt_aligned): Use the new type to - avoid problems with strict aliasing rules. - -2011-02-16 Werner Koch - - * rijndael.c (do_aesni_cfb) [USE_AESNI]: New. - (_gcry_aes_cfb_enc, _gcry_aes_cfb_dec) [USE_AESNI]: Use new fucntion. - -2011-02-15 Werner Koch - - * rijndael.c (do_aesni_enc_aligned, do_aesni_dec_aligned): Use - movdqa for the key but keep using movdqu for the data. - (do_aesni): Remove alignment detection. Don't burn the stack. - (aesni_prepare, aesni_cleanup): New macros. - (rijndael_encrypt, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc) - (rijndael_decrypt, _gcry_aes_cfb_dec, _gcry_aes_cbc_dec): Use - these macros. Don't burn the stack in the USE_AESNI case. - (do_setkey): Add disabled code to use aeskeygenassist. - -2011-02-14 Werner Koch - - * rijndael.c (ATTR_ALIGNED_16): New - (do_aesni): Do not copy if already aligned. - (do_encrypt, do_decrypt): Ditto. - (rijndael_decrypt, rijndael_encrypt): Increase stack burning amount. - - * rijndael.c (RIJNDAEL_context): Reorder fields. Change fieldname - ROUNDS to rounds. Move padlock_key into u1. - (keySched, keySched2): Rename macros to keyscherr and keyschdec - and change all users. - (padlockkey): New macro. Change all users of padlock_key. - * cipher.c (NEED_16BYTE_ALIGNED_CONTEXT): Always define if using gcc. - (struct gcry_cipher_handle): Align U_IV to at least 16 byte. - -2011-02-13 Werner Koch - - * rijndael.c (USE_AESNI): New. Define for ia32 and gcc >= 4. - (m128i_t) [USE_AESNI]: New. - (RIJNDAEL_context) [USE_AESNI]: Add field use_aesni. - (do_setkey): Set USE_AESNI for all key lengths. - (prepare_decryption) [USE_AESNI]: Use aesimc instn if requested. - (do_aesni_enc_aligned, do_aesni_dec_aligned) - (do_aesni) [USE_AESNI]: New. - (rijndael_encrypt, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc) - (rijndael_decrypt, _gcry_aes_cfb_dec) - (_gcry_aes_cbc_dec) [USE_AESNI]: Use do_aesni. - -2011-02-01 Werner Koch - - * pubkey.c (gcry_pk_get_curve): New. - (sexp_to_key): Add arg OVERRIDE_ELEMS. - (sexp_elements_extract_ecc): Allow for params only. - (gcry_pk_get_param): New. - * ecc.c (ecc_get_curve): New. - (ecc_get_param_sexp): New. - -2011-01-28 Werner Koch - - * pubkey.c (gcry_pk_genkey): Hack to insert the used curve name. - -2011-01-27 Werner Koch - - * ecc.c (fill_in_curve): Remove. - (generate_curve): Rename to .. - (fill_in_curve): this. Remove setting of NAME_OID. - (ecc_encrypt_raw): Change name of arg DATA to K for better - readability. Use ECC_public_key instead of ECC_secret_key. - Require a caller to pass a complete pkey array. - (ecc_decrypt_raw): Require a caller to pass a complete skey array. - (elliptic_curve_t): Add field NAME. - (fill_in_curve): Set field. - (generate_key): Add arg R_USED_CURVE. - (ecc_generate_ext): Return used curve name. - -2011-01-13 Andrey Jivsov (wk) - - * ecc.c (ec2os): Do not free passed parameters X and Y. Adjust - callers. - (ecc_encrypt_raw, ecc_decrypt_raw): New. - (ecdh_names, _gcry_pubkey_spec_ecdh): New. - * pubkey.c (pubkey_table): Support ECDH. - -2010-08-19 Werner Koch - - * cipher.c (gcry_cipher_open): Remove double release of the module. - Fixes bug#1263. - -2010-06-10 Jeff Johnson (wk) - - * ecc.c (ecc_generate_ext): Parse transient-key flag. - (generate_key): Add arg TRANSIENT_KEY and use it to set the random - level. - -2010-04-12 Brad Hards (wk) - - Spelling fixes. - -2010-03-26 Werner Koch - - * tiger.c (asn): Unfetter the old TIGER from an OID. - (TIGER_CONTEXT): Add field VARIANT. - (tiger_init): Factor code out to ... - (do_init): New. - (tiger1_init, tiger2_init): New. - (_gcry_digest_spec_tiger1, _gcry_digest_spec_tiger2): New. - * md.c (digest_table): Add TIGER1 and TIGER2 variants. - -2009-12-11 Werner Koch - - * sha256.c (Cho, Maj, Sum0, Sum1): Turn macros into inline - functions. - (transform): Partly unroll to interweave the chain variables - - * sha512.c (ROTR, Ch, Maj, Sum0, Sum1): Turn macros into inline - functions. - (transform): Partly unroll to interweave the chain variables. - Suggested by Christian Grothoff. - -2009-12-10 Werner Koch - - * Makefile.am (o_flag_munging): New. - (tiger.o, tiger.lo): Use it. - - * cipher.c (do_ctr_encrypt): Add arg OUTBUFLEN. Check for - suitable value. Add check for valid inputlen. Wipe temporary - memory. - (do_ctr_decrypt): Likewise. - (do_cbc_encrypt, do_cbc_decrypt): Add arg OUTBUFLEN. Check for - suitable value. Move check for valid inputlen to here; change - returned error from INV_ARG to INV_LENGTH. - (do_ecb_encrypt, do_ecb_decrypt): Ditto. - (do_cfb_encrypt, do_cfb_decrypt): Ditto. - (do_ofb_encrypt, do_ofb_decrypt): Ditto. - (cipher_encrypt, cipher_encrypt): Adjust for above changes. - (gcry_cipher_encrypt, gcry_cipher_decrypt): Simplify. - -2009-12-09 Werner Koch - - * cipher.c (gcry_cipher_open): Allow for GCRY_CIPHER_MODE_AESWRAP. - (cipher_encrypt, cipher_decrypt): Ditto. - (do_aeswrap_encrypt, do_aeswrap_decrypt): New. - (struct gcry_cipher_handle): Add field marks. - (cipher_setkey, cipher_setiv): Update marks flags. - (cipher_reset): Reset marks. - (cipher_encrypt, cipher_decrypt): Add new arg OUTBUFLEN. - (gcry_cipher_encrypt, gcry_cipher_decrypt): Pass outbuflen to - cipher_encrypt. Replace GPG_ERR_TOO_SHORT by - GPG_ERR_BUFFER_TOO_SHORT. - -2009-08-21 Werner Koch - - * dsa.c (dsa_generate_ext): Release retfactors array before - setting it to NULL. Reported by Daiko Ueno. - -2009-07-02 Werner Koch - - * md.c (md_read): Fix incomplete check for NULL. - Reported by Fabian Kail. - -2009-03-31 Werner Koch - - * rsa.c (rsa_check_secret_key): Return GPG_ERR_BAD_SECKEY and not - GPG_ERR_PUBKEY_ALGO. - -2009-02-16 Werner Koch - - * rsa.c (generate_x931): Do not initialize TBL with automatic - variables. - * whirlpool.c, tiger.c, sha256.c, sha1.c, rmd160.c, md5.c - * md4.c, crc.c: Remove memory.h. This is garbage from gnupg. - Reported by Dan Fandrich. - -2009-01-22 Werner Koch - - * ecc.c (compute_keygrip): Remove superfluous const. - -2009-01-06 Werner Koch - - * rmd160.c (oid_spec_rmd160): Add TeleTrust identifier. - -2008-12-10 Werner Koch - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * rsa.c (rsa_decrypt): Use gcry_create_nonce for blinding. - (generate): Rename to generate_std. - -2008-11-05 Werner Koch - - * 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 - - * 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 - - * rijndael.c (do_setkey): Properly align "t" and "tk". - (prepare_decryption): Properly align "w". Fixes bug #936. - -2008-09-18 Werner Koch - - * 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 - - * ecc.c (run_selftests): Add arg EXTENDED. - -2008-09-12 Werner Koch - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * primegen.c (_gcry_generate_secret_prime) - (_gcry_generate_public_prime): Use a constant macro for the random - level. - -2008-08-19 Werner Koch - - * pubkey.c (sexp_elements_extract_ecc) [!USE_ECC]: Do not allow - allow "curve" parameter. - -2008-08-15 Werner Koch - - * 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 - - * 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 (wk) - - * ac.c (_gcry_ac_key_destroy, _gcry_ac_key_pair_generate): Relase - some more memory. - -2008-04-22 Werner Koch - - * 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 - - * 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 - - * cipher.c (gcry_cipher_open) [USE_AES]: Init bulk encryption only - if requested. Suggested by Dirk Stoecker. - -2008-03-18 Werner Koch - - * 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 - - * 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 - - * 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 - - * rsa.c (_gcry_rsa_verify) [IS_DEVELOPMENT_VERSION]: Print - intermediate results. - -2008-01-08 Werner Koch - - * 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 - - * pubkey.c (sexp_data_to_mpi): Support SHA-224. - -2007-12-05 Werner Koch - - * 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 - - * random.c (gcry_random_add_bytes): Implement it. - * rand-internal.h (RANDOM_ORIGIN_EXTERNAL): New. - -2007-11-30 Werner Koch - - * 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 - - * 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 - - * 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 - - * 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 - - * rndw32.c: Disable debug flag. - -2007-10-25 Werner Koch - - * 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 - - * random.c (pool_filled_counter): New. - (add_randomness): Use it. - -2007-08-22 Werner Koch - - * rndw32.c, rndunix.c: Switched to LGPL. - -2007-05-30 Werner Koch - - * camellia.h, camellia.c: Replace by new LGPL version and adjusted - camellia.h. - -2007-05-09 Marcus Brinkmann - - * 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 - - * 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 - - * 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 - - * cipher.c: Use #if instead of #ifdef as configure defines the - USE_cipher defines as 0 for disabled. - -2007-04-30 Werner Koch - - * rndegd.c (_gcry_rndegd_set_socket_name): New. - -2007-04-30 Marcus Brinkmann - - * 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 - - * 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 - - * ecc.c (domain_parms): Add standard brainpool curves. - -2007-04-18 Werner Koch - - * 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 - - * ecc.c (_gcry_ecc_generate): Renamed DUMMY to CURVE and use it. - -2007-04-13 Marcus Brinkmann - - * 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 - - * sha1.c (oid_spec_sha1): Add another oid from X9.62. - -2007-03-28 Werner Koch - - * 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 - - * pubkey.c (gcry_pk_genkey): Increase size of SKEY array and add a - runtime bounds check. - -2007-03-23 Werner Koch - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * rndlinux.c (open_device): Remove unsused arg MINOR. - -2007-01-30 Werner Koch - - * 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 - - * 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 - - * serpent.c (byte_swap_32): Remove trailing semicolon. - -2006-11-15 Werner Koch - - * Makefile.am (INCLUDES): Include ../src/ - -2006-11-03 Werner Koch - - * random.c [HAVE_GETTIMEOFDAY]: Included sys/time.h and not - sys/times.h. Reported by RafaĂ«l CarrĂ©. - -2006-11-05 Moritz Schulte - - * 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 - - * 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 - - * 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 - - * 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 - - * md.c (gcry_md_algo_info) : Check that the algo is - available. - -2006-10-04 David Shaw (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 - - * 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 - - * pubkey.c (sexp_data_to_mpi): Need to allow "ripemd160" here as - this is the canonical name. - -2006-08-29 Hye-Shik Chang (wk) - - * seed.c: New. - -2006-08-03 Werner Koch - - * 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 - - * 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 - - * sha512.c: Fix typo in copyright notice. - -2006-06-21 Werner Koch - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 (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 (wk, patch 2005-04-22) - - * md.c, sha256.c: Add support for SHA-224. - (sha224_init): New. - -2006-01-18 Brad Hards (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 - - * 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 - - * pubkey.c (gcry_pk_algo_info): Don't forget to break after switch - case. - -2005-09-19 Werner Koch - - * 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 - - * 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 - - * ac.c (_gcry_ac_init): New function. - -2005-04-12 Moritz Schulte - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * pubkey.c (gcry_pk_get_keygrip): Allow for shadowed-private-key. - -2005-02-13 Moritz Schulte - - * 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 - - * ac.c: Major parts rewritten. - * pubkey.c (_gcry_pk_get_elements): New function. - -2004-12-09 Werner Koch - - * serpent.c (serpent_setkey): Moved prototype of serpent_test to - outer scope. - -2004-09-11 Moritz Schulte - - * pubkey.c (pubkey_table): Added an alias entry for GCRY_PK_ELG_E. - -2004-08-23 Moritz Schulte - - * ac.c: Do not include . - * 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 - - * 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 - - * pubkey.c (gcry_pk_sign): Fixed memory leak; fix provided by - Modestas Vainius. - -2004-07-16 Werner Koch - - * 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 - - * rsa.c (_gcry_rsa_decrypt): Don't forget to free "a". Thanks to - Nikos Mavroyanopoulos. - -2004-05-09 Werner Koch - - * random.c (read_pool): Mix the PID in to better protect after a - fork. - -2004-07-04 Moritz Schulte - - * 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 - - * 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 - - * ac.c (gcry_ac_open): Do not dereference NULL pointer. Reported - by Umberto Salsi. - -2004-02-20 Werner Koch - - * 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 - - * 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 - - * 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 - - * 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 - - * primegen.c (is_prime): Release A2. - -2003-12-19 Werner Koch - - * 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 - - * primegen.c (gen_prime): Doc fix. Thanks to Newton Hammet. - -2003-12-11 Werner Koch - - * 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 - - * 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 - - * 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 - - * cipher.c: Documentation cleanups. - (gcry_cipher_mode_from_oid): Allow NULL for STRING. - -2003-12-03 Werner Koch - - * elgamal.c (sign, do_encrypt, gen_k): Make sure that a small K is - only used for encryption. - -2003-11-18 Werner Koch - - * random.h (rndw32_set_dll_name): Removed unused prototype. - - * Makefile.am (EXTRA_DIST): Added Manifest. - -2003-11-11 Werner Koch - - * Manifest: New. - -2003-11-04 Werner Koch - - * 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 - - * 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 - - * pubkey.c (gcry_pk_encrypt): Don't forget to deallocate pkey. - -2003-10-27 Werner Koch - - * 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 - - * 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 - - * 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 - - * primegen.c (gen_prime): Assert that NBITS is never zero, it - would cause a segv. - -2003-09-28 Moritz Schulte - - * ac.c: Include "cipher.h". - -2003-09-27 Moritz Schulte - - * rndegd.c (do_read): Return nread instead of nbytes; thanks to - Michael Caerwyn. - -2003-09-04 Werner Koch - - * 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 - - * 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 - - * 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 - - * cipher.c: Add support for Serpent - * serpent.c: New file. - -2003-08-10 Moritz Schulte - - * rsa.c (_gcry_rsa_blind, _gcry_rsa_unblind): Declare static. - -2003-08-09 Timo Schulz - - * 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 - - * 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 - - * md.c (gcry_md_lookup_func_oid): Allow for empty OID lists. - -2003-07-23 Moritz Schulte - - * 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 - - * 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 - - * 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 - - * 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 - - * md.c (gcry_md_hash_buffer): Convert ERR to gpg_error_t in - gpg_strerror. - -2003-07-14 Moritz Schulte - - * 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 - - * 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 - - * 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 - - * ac.c (gcry_ac_data_set): Only release old MPI value if it is - different from the new value. Bug reported by Simon Josefsson - . - - * 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 - - * 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 . - - * 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 . - -2003-07-04 Moritz Schulte - - * cipher.c (gcry_cipher_list): New function. - -2003-07-01 Moritz Schulte - - * pubkey.c (sexp_to_sig): Accept a `flags' S-expression to be more - consistent with sexp_to_enc. - -2003-06-30 Moritz Schulte - - * 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 - - * ac.c: New file. - -2003-06-26 Werner Koch - - * md.c (gcry_md_hash_buffer): Trigger BUG correcly with new API. - -2003-06-19 Werner Koch - - * md.c (gcry_md_is_enabled): Fixed. - -2003-06-18 Werner Koch - - * cipher.c (gcry_cipher_get_algo_keylen): New. - (gcry_cipher_get_algo_blklen): New. - -2003-06-18 Moritz Schulte - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * cipher.c (gcry_cipher_open): Make sure HANDLE is set to NULL on - error. - -2003-06-11 Werner Koch - - * 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 - - * Makefile.am: Removed rules serpent, since that is not commited - yet. - -2003-06-08 Moritz Schulte - - * pubkey.c (gcry_pk_encrypt): Improve calculation for size of the - format string. - -2003-06-07 Moritz Schulte - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * tiger.c: Merged code ussing the U64_C macro from GnuPG. - - * sha512.c: Likewise. - -2003-05-17 Moritz Schulte - - * pubkey.c (gcry_pk_genkey): Fix type: acquire a lock, instead of - releasing it. - -2003-05-11 Moritz Schulte - - * pubkey.c (gcry_pk_testkey): Call REGISTER_DEFAULT_CIPHERS. - (gcry_pk_ctl): Likewise. - -2003-04-27 Moritz Schulte - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * des.c: Removed checks for GCRY_CIPHER_3DES and GCRY_CIPHER_DES. - -2003-03-31 Moritz Schulte - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * primegen.c: Initialize `no_of_small_prime_numbers' statically. - (gen_prime): Remove calculation of `no_of_small_prime_numbers'. - -2003-03-03 Moritz Schulte - - * md.c (gcry_md_ctl): Rewritten to use same style like the other - functions dispatchers. - -2003-03-02 Moritz Schulte - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * random.c (gcry_random_add_bytes): New. Function to add external - random to the pool. - -2003-01-20 Simon Josefsson - - * 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 - - * 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 - - * pubkey.c (gcry_pk_get_keygrip): Implemented keygrips for DSA - and ElGamal. - -2003-01-17 Werner Koch - - * 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 - - * 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 - - * 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 - - * random.c (_gcry_random_initialize): New. - -2002-12-16 Werner Koch - - * cipher.c: Added a Teletrust specific OID for 3DES. - -2002-12-12 Werner Koch - - * md.c: Added another oddball OIW OID (sha-1WithRSAEncryption). - -2002-11-23 Werner Koch - - * 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 - - * 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 - - * 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 - - * arcfour.c (do_encrypt_stream): Don't use increment op when - assigning to the same variable. - -2002-10-10 Timo Schulz - - * 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 - - * md.c: Include an OID for TIGER. - * tiger.c (tiger_get_info): Use a regular OID. - -2002-09-17 Werner Koch - - * random.c: Replaced mutex.h by the new ath.h. Changed all calls. - -2002-09-16 Werner Koch - - * 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 - - * 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 - - * pubkey.c: Enable keygrip calculation for "openpgp-rsa". - -2002-08-17 Werner Koch - - * cipher.c (setup_cipher_table): Don't overwrite the DES entry - with the entry for DUMMY. - -2002-08-14 Werner Koch - - * 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 - - * rndunix.c (_gcry_rndunix_constructor): Prefixed with _gcry_. - Noted by Stephan Austermuehle. - -2002-07-08 Timo Schulz - - * rndw32.c: Replaced the m_ memory functions with the real - gcry_ functions. Renamed all g10_ prefixed functions to log_. - -2002-06-12 Werner Koch - - * rsa.c (generate): Use e = 65537 for now. - -2002-06-11 Werner Koch - - * pubkey.c (gcry_pk_get_keygrip): Allow a "protected-private-key". - -2002-06-05 Timo Schulz - - * cipher.c (gcry_cipher_encrypt, gcry_cipher_decrypt): - Check that the input size is a multiple of the blocksize. - -2002-05-23 Werner Koch - - * md.c (oid_table): Add an rsadsi OID for MD5. - -2002-05-21 Werner Koch - - * 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 - - * 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 - - * random.c (gcry_random_bytes,gcry_random_bytes_secure) - (gcry_randomize): Make sure we are initialized. - -2002-05-14 Werner Koch - - Changed license of most files to the LGPL. - -2002-05-02 Werner Koch - - * 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 - - * cipher.c: Fixed list of copyright years. - -2002-03-18 Werner Koch - - * 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 - - * md.c: Add rsaSignatureWithripemd160 to OID table. - -2002-02-20 Werner Koch - - * 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 - - * rndunix.c (rndunix_constructor): Use the the new prefixed - function name. Reported by Jordi Mallach. - -2002-02-10 Werner Koch - - * random.c (mix_pool): Carry an extra failsafe_digest buffer - around to make the function more robust. - -2002-02-08 Werner Koch - - * 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 - - * 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 - - * 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 - - * pubkey.c (gcry_pk_get_keygrip): New - experimental. - -2001-12-11 Werner Koch - - * 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 - - * 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 - - * cipher.c (gcry_cipher_map_name): Look also for OIDs prefixed - with "oid." or "OID.". - -2001-12-05 Werner Koch - - * pubkey.c (algo_info_table): Fixed entry for openpgp-rsa. - -2001-11-24 Werner Koch - - * 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 - - * 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 - - * md.c (gcry_md_info): New operator GCRYCTL_IS_ALGO_ENABLED. - -2001-11-07 Werner Koch - - * md.c (gcry_md_hash_buffer): Close the handle which was left open - for algorithms other than rmd160. - -2001-08-08 Werner Koch - - * 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 - - * 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 - - * 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 - - * 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 - - * rndegd.c (gather_random): Removed the use of tty_printf. - -2001-03-29 Werner Koch - - * 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 - - * cipher.c (cipher_encrypt,gcry_cipher_encrypt): Use blocksize and - not 8. - -2000-12-19 Werner Koch - - Major change: - Removed all GnuPG stuff and renamed this piece of software - to gcrypt. - -2000-11-14 Werner Koch - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * random.c (gather_faked): Replaced make_timestamp by time(2) again. - -Fri Jul 14 19:38:23 CEST 2000 Werner Koch - - * 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 - - * 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 - - * md.c (gcry_md_hash_buffer): Add support for the other algorithms. - -Mon Jan 31 16:37:34 CET 2000 Werner Koch - - * 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 - - * pubkey.c (sexp_to_key): Fixed mem leaks in case of errors. - -Mon Jan 24 22:24:38 CET 2000 Werner Koch - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * rndw32.c: New. - -Mon Sep 13 10:51:29 CEST 1999 Werner Koch - - * 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 - - * Makefile.am: Fixed seds for latest egcc. By Ollivier Robert. - -Mon Sep 6 19:59:08 CEST 1999 Werner Koch - - * des.c (selftest): Add some testpattern - -Mon Aug 30 20:38:33 CEST 1999 Werner Koch - - * 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 - - * md5.c (md5_final): Fix for a SCO cpp bug. - -Thu Jul 15 10:15:35 CEST 1999 Werner Koch - - * 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 - - * Makefile.am: Support for libtool. - -Fri Jul 2 11:45:54 CEST 1999 Werner Koch - - * 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 - - * 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 - - * 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 - - * 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 - - * dynload.c (register_internal_cipher_extension): Minor init fix. - -Tue May 4 15:47:53 CEST 1999 Werner Koch - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * rndlinux.c (tty_printf) [IS_MODULE]: Removed. - - * rndegd.c (gather_random): Some fixes. - -Wed Mar 17 13:09:03 CET 1999 Werner Koch - - * rndegd.c (do_read): New. - (gather_random): Changed the implementation. - -Mon Mar 8 20:47:17 CET 1999 Werner Koch - - * dynload.c (DLSYM_NEEDS_UNDERSCORE): Renamed. - -Fri Feb 26 17:55:41 CET 1999 Werner Koch - - * md.c: Nearly a total rewrote. - -Wed Feb 24 11:07:27 CET 1999 Werner Koch - - * cipher.c (context): Fixed alignment - * md.c: Ditto. - - * rndegd.c: New - -Mon Feb 22 20:04:00 CET 1999 Werner Koch - - * rndegd.c: New. - -Wed Feb 10 17:15:39 CET 1999 Werner Koch - - * 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 - - * rndunix.c (gather_random): Fix to avoid infinite loop. - -Sun Jan 17 11:04:33 CET 1999 Werner Koch - - * 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 - - * 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 - - * 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 - - * 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 - - * rndunix.c (start_gatherer): Fixed stupid ==/= bug - -1998-12-31 Geoff Keating - - * des.c (is_weak_key): Rewrite loop end condition. - -Tue Dec 29 14:41:47 CET 1998 Werner Koch - - * random.c: add unistd.h for getpid(). - (RAND_MAX): Fallback value for Sun. - -Wed Dec 23 17:12:24 CET 1998 Werner Koch - - * md.c (md_copy): Reset debug. - -Mon Dec 14 21:18:49 CET 1998 Werner Koch - - * 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 - - * 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 - - * 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 - - * 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 - -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, 2010, 2011 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/Makefile.am b/grub-core/lib/libgcrypt/cipher/Makefile.am deleted file mode 100644 index 76cdc96ad..000000000 --- a/grub-core/lib/libgcrypt/cipher/Makefile.am +++ /dev/null @@ -1,83 +0,0 @@ -# Makefile for cipher modules -# Copyright (C) 1998, 1999, 2000, 2001, 2002, -# 2003, 2009 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 . - -# Process this file with automake to produce Makefile.in - -EXTRA_DIST = Manifest - -# Need to include ../src in addition to top_srcdir because gcrypt.h is -# a built header. -AM_CPPFLAGS = -I../src -I$(top_srcdir)/src -AM_CFLAGS = $(GPG_ERROR_CFLAGS) - - -noinst_LTLIBRARIES = libcipher.la - -GCRYPT_MODULES = @GCRYPT_CIPHERS@ @GCRYPT_PUBKEY_CIPHERS@ @GCRYPT_DIGESTS@ - -libcipher_la_DEPENDENCIES = $(GCRYPT_MODULES) -libcipher_la_LIBADD = $(GCRYPT_MODULES) - -libcipher_la_SOURCES = \ -cipher.c pubkey.c ac.c md.c kdf.c \ -hmac-tests.c \ -bithelp.h \ -primegen.c \ -hash-common.c hash-common.h \ -rmd.h - -EXTRA_libcipher_la_SOURCES = \ -arcfour.c \ -blowfish.c \ -cast5.c \ -crc.c \ -des.c \ -dsa.c \ -elgamal.c \ -ecc.c \ -idea.c \ -md4.c \ -md5.c \ -rijndael.c rijndael-tables.h \ -rmd160.c \ -rsa.c \ -seed.c \ -serpent.c \ -sha1.c \ -sha256.c \ -sha512.c \ -tiger.c \ -whirlpool.c \ -twofish.c \ -rfc2268.c \ -camellia.c camellia.h camellia-glue.c - -if ENABLE_O_FLAG_MUNGING -o_flag_munging = sed -e 's/-O\([2-9s][2-9s]*\)/-O1/' -e 's/-Ofast/-O1/g' -else -o_flag_munging = cat -endif - - -# We need to lower the optimization for this module. -tiger.o: $(srcdir)/tiger.c - `echo $(COMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) ` - -tiger.lo: $(srcdir)/tiger.c - `echo $(LTCOMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) ` diff --git a/grub-core/lib/libgcrypt/cipher/Manifest b/grub-core/lib/libgcrypt/cipher/Manifest deleted file mode 100644 index 0cd64f71f..000000000 --- a/grub-core/lib/libgcrypt/cipher/Manifest +++ /dev/null @@ -1,73 +0,0 @@ -# Manifest - checksums of the cipher directory -# Copyright 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 - -# Checksums for all source files in this directory. Format is -# filename, blanks, base-64 part of an OpenPGP detached signature -# without the header lines. Blank lines and lines beginning with a -# hash mark are ignored. A tool to process this file is available by -# cvs -d :pserver:anoncvs@cvs.gnupg.org:/cvs/wk co misc-scripts/manifest-tool -# -# The special entry "$names$" holds a signature over all sorted -# filenames excluding itself. - - -# Algorithm API -cipher.c iQCVAwUAQDzrVjEAnp832S/7AQIPDgP+OVJ/YNWY5m7c09EBbPAzL/WsGoj6wrBNMmkRlMOqTHeh+OOtjuFHt1f9uhfM2Nzl7sJ5+h4ryZKLEZmQPRMTZTnAqkvGdsrJWJnigUA9QwYdV0ONqC9C63gpuG465gO9TZVOqlQu/FTxSRuTQYUulkaBNG71n8nZEOusBVwV2YA==58xH -pubkey.c iQCVAwUAP9XQ3jEAnp832S/7AQJ5UgQAyHfEBvPVJ8wTRg8c7ixS2GiVmIgwIo5tvQaiQJTPWASevvYrB+2Z2qa9cATyu50ACjLzbaquGBgPzjJV3dU/qttT1gCqRuN/LCNvXFe5qnIZezejc3RAadFNTw/pOTHq0wxD1Keg66ruei9R36Nba59pEQIWIBXTfubRft2hMYk==E09t -ac.c iQCVAwUAQDzsOzEAnp832S/7AQJCBQP/WI6EV/dsR4rmha6RVhvkjZo17kQ8z6pIl5J3cXOvqEkIFeD2HYu3HHrWST5l7yXlffhpDkVHkfMih4ruK76q6Fm0dxZ98pO4C/dVtgimlvvcy/wOQjpzsE0fYAe1BYdg81LJ09X33vW5x6C29lunfKROO2tPlV5i8ffeoFvmMF8==j26g -md.c iQCVAwUAP+NFGjEAnp832S/7AQJs8wP/Qdk0EAKsyr3O1/pmOSN8AG4rPKbd6KDTzvoBPAN4upFwKYY4hWwvy12Q3YU9DmECrzZkRCXHR7mljVQKs6B7CRZJKjFKmOELpcJDtKvu40vTs1bOH4k9iJYZpGgRA83nkQ+ELAcphAbCA+KIpVr2K4mCJAB0FhpC2uOQ50JHAko==BeF6 -primegen.c iQCVAwUAQDzsoDEAnp832S/7AQKYRwP/TqAQBm1rHTnF0HYE05PqXfWlOqa6EosqVpaOcs/OIW6PaqX0xH1UlrukK7jNOjK3xC4o1qNQ1UKzz2dvQaq1bMvNNizeavxAh10SJZc0hIc/ofc83IbjLh8SZVWQ67JxjsUd3DOXmSmhPZ+Pqd7cUIiw8fDoF+I9EZqy3COu1wY==1ebT - -# Algorithm implementations -arcfour.c iQCVAwUAP9XR/TEAnp832S/7AQJcRwP6AlvYEx++fpT4mIYo0xRDqKEQeqMQvbaRhIg2eV74JxItpHa3q5YsYIl+n1yUz5g35JRWWXSWmAZBwO5wLKsHii4kRUhgrKWnSoQZoPpl49L5+N3R58ON3S0ru5lsBiEJEze3xplf2vqwrH9v1QHVD+gU7UTlfNqrIJoOUXN+1O4==Tq+x -blowfish.c iQCVAwUAP9XTETEAnp832S/7AQJaEgQAgiqqfuO+zQtscgTB0rvOzVymIKjRKjYhFuLjVuc79G4z1RCAffvIn/YM2d7kt+Z/QF7zjcTAOgETCQL1XokpX2zz9HPAMi2tlDY5zsDufTNqj0n4WBL9nM7w6XAvsiwP1B3bqCTv9SjJV4KbxJ58vw1yQE+sqW74R/QIHFvC7mU==wZnX -cast5.c iQCVAwUAP9XT6DEAnp832S/7AQJ3xgP/ehLjEN3GELGudbqeo91Xd+PqitHrkuBbtRIYX7Udd/fyXLN+h8rMJVyIQX2m+mpxbBxudVU3x8/DNT8B0ZHAwK6qqJmEBLLhEYPgIuF76i9LMrP1KqUPhAwRZ2OppjIIugBQ+rP74aD4eLyd/aKQHNuXML8QGWR6KwQShohXM5I==/BRh -crc.c iQCVAwUAP7ouejEAnp832S/7AQIgwQQApg5Nm63tH5DQkbN+zPzMO9Ygoj3ukxfFTyTBPYSXYKMiTjEbESegaU40uN8jnz2vprcIQWcgZfzO4+opEJMcI35aPwzEk0vKOp0S/PrBLUY2rJfnDVkX5XgJFZa2Q7LLe826UEBzTVYW924utiCCe8oOaOEWVNpg1mqdknu3M9o==kz5D -des.c iQCVAwUAQCN2oDEAnp832S/7AQL/jwP6Auoq6nZCDBjpgc9tDzuIRwa9DqyuM3gX94uvgEpUwdHszb2bG43dz03kVmcYxtj1MzXbyCeCZOwox0b2SKmLgxIbrNP6yGbzVdTj6592gDYuf/ZXmc1ZNJ1DDldcPQ0n9fXUipUPwyPaNWo3mSZaNcMKSWWzdK0J6ciG6nk7SWI==9k/t -dsa.c iQCVAwUAP9XZHDEAnp832S/7AQLBRgP/XrBzTEYx5ccMj1MMb6sg37liEHdIyyy49zjvt6jUqxj4RuwVEN8S6v3u4q/QyJkHAi1E0EkREgENlyHW6PKWhYbcrd0vPIAN15yjnl2yqtrCrJImexUCoqJJewK0E4JOicGbabTil8MZjk+mbhEPnjJBqOkyP1w0i31pEDgE/8M==pC8s -elgamal.c iQCVAwUAP9XbYzEAnp832S/7AQLXagQA3HrvspZfbTGgmUH0IqLQTJ0exUPxJv5DET2TvoIy62trDmMN6lTAj5P+a7jQ8udcu0w+mR2vXUHcxUpNA2PxLaMwGzNSY4zRDNe9r3SFTDrFm6m4y9Ko2e8XtEA+WF6P/XLpck4Jn7vMEDmVGPwkNd22kXFFE8dBGwG6i5Hk1Mk==oBUs -md4.c iQCVAwUAP9h50DEAnp832S/7AQJhHgQAzNA/B6MWFDlCtPkIVaW8RpP1Eg0ZNMsy0s7SJkopOCBlu6CwXUOKe+8ppcSxhjYKh4i4uQr/QtfipYlBjzKJGnrafoF/NugXNCOHSTGT11TvK7mCiBuUMVgvZGAlOJImk6eTTfUjRrMfaXM/SWl8bdJ4ZpzdjEyVh89r7I5JrGk==x2UD -md5.c iQCVAwUAP9h7LzEAnp832S/7AQJUGQP/c0cbf6WZXCzmjufHxiE9FAQBzTsA0WtaNqdFcHl7fhmikGtknlaED8n5a7eYd/C481UQW6Wgq/oZdsvgoPWPhG3fOCy2CFP9cZVXITuMSf0ucyZTFUJNO15fnZ+nDfsUv+JPdv1aSeRinAUtfAcSKfkSyR9BCPZvkx+tgU6cphU==Zv+h -rijndael.c iQCVAwUAP9h9cTEAnp832S/7AQKF1AP+P2L/tPqDJRDg+/fwbOk8Ts0MNxnvvYEm3gE73TKuLt1S+B2+jkrZcKNvM5VGPnVMJbnS0lmIK04nmedHCOftGTOwhGulZAHHIaKGystT3Jql4iPws/JMgAjE7Fyxh5WZMtB9yEljKBpJ5XNqhrMvvxcHpnyP3+YzIXNwzk34V+c==dJ5k -rmd160.c iQCVAwUAP9h+bTEAnp832S/7AQK1OgP+PNKF6Nzi6X93easVlksdLqKEsArCAw2QjGWDGyxTnbiJM55qAl9JxR1mn3V+oOL7izLLwTt6EYK9evhzfcxY5N5Mni85RAcsLPsuAfQDEzjI6GUWHtQUKPbM+BaorzfhQjYFSZyvum/dZYJ/WfiwwwhqqIKyVU2ZFSqA38YGC/c==9jdA -rsa.c iQCVAwUAP9iHIzEAnp832S/7AQKAYwQAuWtnMte54QHN+Hij9t4sGuypXogajOb1vQQwGgS0fKsaBZsuSP2amze4o5diIvsQTsFQ4CzjvqoCVuBDoHM3xkSD8wGDizgvtCamAxkdbF7wmzldKFn8SpJqlVwWQMP6kk1IjXHEuYb4IDWGTbVMhfEu+eOlU8+PSK4IhZqNvt4==/3hp -serpent.c iQCVAwUAP9h/VzEAnp832S/7AQLyCwP/d1zbmb7l/PriZNa9/Z7mo01XFe5MnAqCfIwhl9GjeaMszcoS37jECNq5nLvrTTFIIJpm3rvBePwiCG4Wwx1I18HCxaP198pcSaR+BLOJ3Aj52EZPrxtqlDKuFr38ZOP5giyUqUYVYGVdrz4kRMNWAZQK53GeJnGhXCnhxojLEgA==ck46 -sha1.c iQCVAwUAP9iATTEAnp832S/7AQKcSwQAwAs/HnNqho3lU1ZUgCPNt5P2/Brm6W21+wWWGKJkSrra/c4NYVKJGDDwlsFE0b9ln1uZt7bHReFkKXK3JnrKTmNVcx/Cy64iCMRNMhaM72Mqy7wWx5yHBAmMBxzFGnNQKbmeY52zeGih5HsNLSibc2pPuOViWo2JPJ5Ci/wIwl8==/wtO -sha256.c iQCVAwUAP9iAtzEAnp832S/7AQJD2QP/UqvL0hhjG1wEFbGrdkV9tba1sMDXdnnK6X7HdLuRpVAgNiQiFf8JDmntd/dZ2Q71p4Uae2ctqve4WoEijPUZPjACnpuZfx0SEQL0lQBkwxzJp7lz9ujVtwQ2cM/aYexJkXcWgGcloJNLM3JbWPGIJnuYbr/IwJ6RQF9vgj0357o==UWO1 -sha512.c iQCVAwUAP9iBTDEAnp832S/7AQIPBAQA28CJSUQLiW0s2x9u8/OH2eKnxPjA4sZmb50WP7920Lem66P31C3BrOqwfBot4RLhjL+zh/+Uc4s3HPwApZuj9E4BxNMlqLv+Tqk++DAbdaOeYT4jeUt+mlhQQ6mH/RDsy32rZsNsGQ2bUGxazZmfG++PL3JyhawqCy00SUDr/o0==H+0X -tiger.c iQCVAwUAP9iCfjEAnp832S/7AQKufwP/fryv3MqSOYY+90325DH7X3/CtekxeooN0scGsHX0fxBakWSMecTNrj33KPddLS46gU/S89zIc2N/Bw/7EVIAXVFA3/3Ip+OrFOuIMO4Py1sCdB8o2Y+5ygv8iXLcsXIq1O0av79i9g774V3uaXa2qN9ZnXe0AEhcy8FHJ2i/wro==5XVB -twofish.c iQCVAwUAP9iD6TEAnp832S/7AQKUnQP/Rq8FaYeHTG7HbZuqAs9pbPitzjDbkdZddmInWR7NmevBkKvhsJALjVooc0KGQfo2lAAmy3Xi/4QQN8VPn51DVjDIgf7x+DQh/9TFJHMccxI9asUgi4+TNnmMqLU1k3N8S2PjyZ1sjeC8B79fKPpwCzj72WkqPkzZw3l2jArr+dU==NdJT -rfc2268.c iQCVAwUAQCN+3jEAnp832S/7AQLv1gQA1hJh29hAjKi4uLSGxXvJ6cyYmPdmevdKrbLnuHZWtHe4xvCgy/nTdEojEpxgLp/hL/ogasuWRC1W16Wiz9ryxf7YR0uhZWayO/bQNagpfU5MIkJTLuKqqgpwYumCSQfOugXVAqcgEzj+13eeyJaFVrzwrNa67sh84nmbjOjNjvE==0zBq - -# Random number related -random.c iQCVAwUAP7nsITEAnp832S/7AQK4SAQAtvfUgrtGOQ2PlxGMla0qJLPHjJacMwgq0ecusiI79elPdDsFfCCk6dK1Ug2kFbNm22nCGHNcUquqbX7noi7ZVQnmPBQXzyLNZd7GmrawRZfdlRerTUDBpSnR8V8ui/5+YYp627E7kKGC0hPSgqXFql6oBMIfno0LZwFJTjIevRY==L419 -random.h iQCVAwUAP7ovKDEAnp832S/7AQJ3bQQAjnPebnyTC7sphAv2I7uIz+yPgw1ZfbVhLv+OiWDlO9ish+fRyyMpy+HELBOgZjJdgRegqhlZC6qyns5arM/VglYi+PzvdLO3hIqHE/YFfpIFPz8wBrcmlqrYyd3CsGqcYsfjocXNttCBLeSWmoJ09ltKQH8yzJf3oAgN6X1yuc4==eNoU -rand-internal.h iQCVAwUAP7ouvDEAnp832S/7AQLYnAQAhdI7ERoJVCkV8GiV7MjaUxv1WIL7iZ+jIOvVhv4fNyhCGCGoEtTjkyput/lj7Nsh3FXEqRhypGGrCLf47x/gua5n+BwffogxVyUDqiOyyGhNTPpe3fQcNBvbPCtco8yMK4GJO5G3BqzlPyN+BMeogLymyV6Sm1mvh5LZDyAFbfQ==tZSE -rndlinux.c iQCVAwUAP9iPYTEAnp832S/7AQL6/AP/ZDrbOkVuB9qJ7sKeX1MImZEsz3mi0xPovJzaBtBU7a0idcUKrWYOvQFWRlLUeq0iCT6+h2l5bniP7q7hepzlKa+VPY9VWaQthqeJm2l5LN6QQ5PyMfBq04QuBncw9BJnCGmEyTLt3RxIXBAPdxmiVxtcRIFUqCBtQvoUXGLvemw==t37k -rndegd.c iQCVAwUAP9iPRDEAnp832S/7AQImBQP/WHKg+hKXcm1pQvilzML0jZpwK5PAMM4uBnnPJNIXWOYBO6I/Xg9d/tPLg8NlmmtyQCo2Eu0ybDSt+8mu+dWveAys+0LTi0MIqeP9BMzCKz8dnWH6+S8huLXwTF3m0IrqM0JLb6b71GK9SOq6sWQ22yW5vf61hXP8kH9dhIaoMZs==FaHV -rndunix.c iQCVAwUAP9iQlzEAnp832S/7AQL/KgQA29GnvcD4Xb5qjDMBgW9THEE4+4lfex/6k+Fh0IT61OLJsWVLJ7bJpRntburw4uQm4Tf7CO8vaiDFDYhKKrzXeOF1fmdpcL8hA+fNp9I/MUOc4e9kN9+YJ9wikVa0SZj1OBfhzgcFLd1xOtulkr3ii52HLF9vhrxzkgVwvD10Bi8==2cML -rndw32.c iQCVAwUAP9iRKDEAnp832S/7AQIuaAQA3AJr3WqnxNDsWCIdvehf8Suotthj+laX8nJsvDfFhXPKcXDpsg0wTTXSnnKgyED53+uYiMDnVRsxeWAyhKwvx1MjjlaSMMjzbH6isWTH8FaWpLgrxEkXoPeNqYf5FXpdUkcUxGX2RkQeuX/cIfiHLNE9CV0usaF2jysjBX2iERY==EEnO - -# Helper -bithelp.h iQCVAwUAP7ouPTEAnp832S/7AQKXggQAqjcgvihIF3WclOgw1JV2rbARw4ISIDRMFqdaNCqBRx6BwEz3UGsEIlz6+iR1sS/reqN61WvtjLb+D0+tujAkGrgQJhFLG85WtG2tB5UVoI3am1fpkwiRm+bR4rv0rGk0BYk81bC7+l4KrK9o5lVp4lCsrorlUKsd48lNmBHyAXM==mDDN -rmd.h iQCVAwUAP7oumjEAnp832S/7AQJiJQP/V4bJwjZaYndJzV+KRnIDbl1koHuw+ZK5heMYVu8Qk4ylqv//BGyeRa3jZCcfPHI35q6HilCs2VBm8hiBMjHSqY/VPn2ZQ0yg/lt6qEvl7YjsLmyMICvjG+ncszHoq9pRvnF3vTnM18sPIioXLk8fskuM0XOCNBs0ARBAQjY9UGI==olUN - -# Configuration -Makefile.am iQCVAwUAQCN33TEAnp832S/7AQKFJAQAz7BDkC814q+QiuE/jnutJHR5qlgbrm3ikGbQwdRzYUscst4bCCWy3uKL/sIPGLg+JQXtF5FnsQy3s4D9BOYhp72cA9ktYK65hhi4pNm/JQ0lXkZMNfk8Go5lNzKezlWwHvkMwRXR0Fep0wPdyeaKW5BfaW2ABvgep6Bp+hHEbyg==zSyi -$names$ iQCVAwUAQCN3EDEAnp832S/7AQJXLAP8DvHTpm5DkTF35EmzeKpi9ie59AZcZanD19ir/e/7+PaQxr2riuLHDGwFKTju+dcvvBsqrygXOC378GXVWzIF2OZwS4EdDcJ+pgojo9UpsqpKsJHouY4Ugx5cQialxba462kUn8hcihSBnMyc4LzbJ5WQ4puQuqy544d2x94+2ms==G4Ls diff --git a/grub-core/lib/libgcrypt/cipher/bufhelp.h b/grub-core/lib/libgcrypt/cipher/bufhelp.h deleted file mode 100644 index df3559472..000000000 --- a/grub-core/lib/libgcrypt/cipher/bufhelp.h +++ /dev/null @@ -1,432 +0,0 @@ -/* bufhelp.h - Some buffer manipulation helpers - * Copyright (C) 2012 Jussi Kivilinna - * - * 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 . - */ -#ifndef GCRYPT_BUFHELP_H -#define GCRYPT_BUFHELP_H - - -#include "bithelp.h" - - -#undef BUFHELP_FAST_UNALIGNED_ACCESS -#if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \ - defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \ - (defined(__i386__) || defined(__x86_64__) || \ - (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \ - defined(__aarch64__)) -/* These architectures are able of unaligned memory accesses and can - handle those fast. - */ -# define BUFHELP_FAST_UNALIGNED_ACCESS 1 -#endif - - -#ifdef BUFHELP_FAST_UNALIGNED_ACCESS -/* Define type with one-byte alignment on architectures with fast unaligned - memory accesses. - */ -typedef struct bufhelp_int_s -{ - uintptr_t a; -} __attribute__((packed, aligned(1))) bufhelp_int_t; -#else -/* Define type with default alignment for other architectures (unaligned - accessed handled in per byte loops). - */ -typedef struct bufhelp_int_s -{ - uintptr_t a; -} bufhelp_int_t; -#endif - - -/* Optimized function for small buffer copying */ -static inline void -buf_cpy(void *_dst, const void *_src, size_t len) -{ -#if __GNUC__ >= 4 && (defined(__x86_64__) || defined(__i386__)) - /* For AMD64 and i386, memcpy is faster. */ - memcpy(_dst, _src, len); -#else - byte *dst = _dst; - const byte *src = _src; - bufhelp_int_t *ldst; - const bufhelp_int_t *lsrc; -#ifndef BUFHELP_FAST_UNALIGNED_ACCESS - const unsigned int longmask = sizeof(bufhelp_int_t) - 1; - - /* Skip fast processing if buffers are unaligned. */ - if (((uintptr_t)dst | (uintptr_t)src) & longmask) - goto do_bytes; -#endif - - ldst = (bufhelp_int_t *)(void *)dst; - lsrc = (const bufhelp_int_t *)(const void *)src; - - for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t)) - (ldst++)->a = (lsrc++)->a; - - dst = (byte *)ldst; - src = (const byte *)lsrc; - -#ifndef BUFHELP_FAST_UNALIGNED_ACCESS -do_bytes: -#endif - /* Handle tail. */ - for (; len; len--) - *dst++ = *src++; -#endif /*__GNUC__ >= 4 && (__x86_64__ || __i386__)*/ -} - - -/* Optimized function for buffer xoring */ -static inline void -buf_xor(void *_dst, const void *_src1, const void *_src2, size_t len) -{ - byte *dst = _dst; - const byte *src1 = _src1; - const byte *src2 = _src2; - bufhelp_int_t *ldst; - const bufhelp_int_t *lsrc1, *lsrc2; -#ifndef BUFHELP_FAST_UNALIGNED_ACCESS - const unsigned int longmask = sizeof(bufhelp_int_t) - 1; - - /* Skip fast processing if buffers are unaligned. */ - if (((uintptr_t)dst | (uintptr_t)src1 | (uintptr_t)src2) & longmask) - goto do_bytes; -#endif - - ldst = (bufhelp_int_t *)(void *)dst; - lsrc1 = (const bufhelp_int_t *)(const void *)src1; - lsrc2 = (const bufhelp_int_t *)(const void *)src2; - - for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t)) - (ldst++)->a = (lsrc1++)->a ^ (lsrc2++)->a; - - dst = (byte *)ldst; - src1 = (const byte *)lsrc1; - src2 = (const byte *)lsrc2; - -#ifndef BUFHELP_FAST_UNALIGNED_ACCESS -do_bytes: -#endif - /* Handle tail. */ - for (; len; len--) - *dst++ = *src1++ ^ *src2++; -} - - -/* Optimized function for in-place buffer xoring. */ -static inline void -buf_xor_1(void *_dst, const void *_src, size_t len) -{ - byte *dst = _dst; - const byte *src = _src; - bufhelp_int_t *ldst; - const bufhelp_int_t *lsrc; -#ifndef BUFHELP_FAST_UNALIGNED_ACCESS - const unsigned int longmask = sizeof(bufhelp_int_t) - 1; - - /* Skip fast processing if buffers are unaligned. */ - if (((uintptr_t)dst | (uintptr_t)src) & longmask) - goto do_bytes; -#endif - - ldst = (bufhelp_int_t *)(void *)dst; - lsrc = (const bufhelp_int_t *)(const void *)src; - - for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t)) - (ldst++)->a ^= (lsrc++)->a; - - dst = (byte *)ldst; - src = (const byte *)lsrc; - -#ifndef BUFHELP_FAST_UNALIGNED_ACCESS -do_bytes: -#endif - /* Handle tail. */ - for (; len; len--) - *dst++ ^= *src++; -} - - -/* Optimized function for buffer xoring with two destination buffers. Used - mainly by CFB mode encryption. */ -static inline void -buf_xor_2dst(void *_dst1, void *_dst2, const void *_src, size_t len) -{ - byte *dst1 = _dst1; - byte *dst2 = _dst2; - const byte *src = _src; - bufhelp_int_t *ldst1, *ldst2; - const bufhelp_int_t *lsrc; -#ifndef BUFHELP_FAST_UNALIGNED_ACCESS - const unsigned int longmask = sizeof(bufhelp_int_t) - 1; - - /* Skip fast processing if buffers are unaligned. */ - if (((uintptr_t)src | (uintptr_t)dst1 | (uintptr_t)dst2) & longmask) - goto do_bytes; -#endif - - ldst1 = (bufhelp_int_t *)(void *)dst1; - ldst2 = (bufhelp_int_t *)(void *)dst2; - lsrc = (const bufhelp_int_t *)(const void *)src; - - for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t)) - (ldst1++)->a = ((ldst2++)->a ^= (lsrc++)->a); - - dst1 = (byte *)ldst1; - dst2 = (byte *)ldst2; - src = (const byte *)lsrc; - -#ifndef BUFHELP_FAST_UNALIGNED_ACCESS -do_bytes: -#endif - /* Handle tail. */ - for (; len; len--) - *dst1++ = (*dst2++ ^= *src++); -} - - -/* Optimized function for combined buffer xoring and copying. Used by mainly - CBC mode decryption. */ -static inline void -buf_xor_n_copy_2(void *_dst_xor, const void *_src_xor, void *_srcdst_cpy, - const void *_src_cpy, size_t len) -{ - byte *dst_xor = _dst_xor; - byte *srcdst_cpy = _srcdst_cpy; - const byte *src_xor = _src_xor; - const byte *src_cpy = _src_cpy; - byte temp; - bufhelp_int_t *ldst_xor, *lsrcdst_cpy; - const bufhelp_int_t *lsrc_cpy, *lsrc_xor; - uintptr_t ltemp; -#ifndef BUFHELP_FAST_UNALIGNED_ACCESS - const unsigned int longmask = sizeof(bufhelp_int_t) - 1; - - /* Skip fast processing if buffers are unaligned. */ - if (((uintptr_t)src_cpy | (uintptr_t)src_xor | (uintptr_t)dst_xor | - (uintptr_t)srcdst_cpy) & longmask) - goto do_bytes; -#endif - - ldst_xor = (bufhelp_int_t *)(void *)dst_xor; - lsrc_xor = (const bufhelp_int_t *)(void *)src_xor; - lsrcdst_cpy = (bufhelp_int_t *)(void *)srcdst_cpy; - lsrc_cpy = (const bufhelp_int_t *)(const void *)src_cpy; - - for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t)) - { - ltemp = (lsrc_cpy++)->a; - (ldst_xor++)->a = (lsrcdst_cpy)->a ^ (lsrc_xor++)->a; - (lsrcdst_cpy++)->a = ltemp; - } - - dst_xor = (byte *)ldst_xor; - src_xor = (const byte *)lsrc_xor; - srcdst_cpy = (byte *)lsrcdst_cpy; - src_cpy = (const byte *)lsrc_cpy; - -#ifndef BUFHELP_FAST_UNALIGNED_ACCESS -do_bytes: -#endif - /* Handle tail. */ - for (; len; len--) - { - temp = *src_cpy++; - *dst_xor++ = *srcdst_cpy ^ *src_xor++; - *srcdst_cpy++ = temp; - } -} - - -/* Optimized function for combined buffer xoring and copying. Used by mainly - CFB mode decryption. */ -static inline void -buf_xor_n_copy(void *_dst_xor, void *_srcdst_cpy, const void *_src, size_t len) -{ - buf_xor_n_copy_2(_dst_xor, _src, _srcdst_cpy, _src, len); -} - - -/* Constant-time compare of two buffers. Returns 1 if buffers are equal, - and 0 if buffers differ. */ -static inline int -buf_eq_const(const void *_a, const void *_b, size_t len) -{ - const byte *a = _a; - const byte *b = _b; - size_t diff, i; - - /* Constant-time compare. */ - for (i = 0, diff = 0; i < len; i++) - diff -= !!(a[i] - b[i]); - - return !diff; -} - - -#ifndef BUFHELP_FAST_UNALIGNED_ACCESS - -/* Functions for loading and storing unaligned u32 values of different - endianness. */ -static inline u32 buf_get_be32(const void *_buf) -{ - const byte *in = _buf; - return ((u32)in[0] << 24) | ((u32)in[1] << 16) | \ - ((u32)in[2] << 8) | (u32)in[3]; -} - -static inline u32 buf_get_le32(const void *_buf) -{ - const byte *in = _buf; - return ((u32)in[3] << 24) | ((u32)in[2] << 16) | \ - ((u32)in[1] << 8) | (u32)in[0]; -} - -static inline void buf_put_be32(void *_buf, u32 val) -{ - byte *out = _buf; - out[0] = val >> 24; - out[1] = val >> 16; - out[2] = val >> 8; - out[3] = val; -} - -static inline void buf_put_le32(void *_buf, u32 val) -{ - byte *out = _buf; - out[3] = val >> 24; - out[2] = val >> 16; - out[1] = val >> 8; - out[0] = val; -} - - -/* Functions for loading and storing unaligned u64 values of different - endianness. */ -static inline u64 buf_get_be64(const void *_buf) -{ - const byte *in = _buf; - return ((u64)in[0] << 56) | ((u64)in[1] << 48) | \ - ((u64)in[2] << 40) | ((u64)in[3] << 32) | \ - ((u64)in[4] << 24) | ((u64)in[5] << 16) | \ - ((u64)in[6] << 8) | (u64)in[7]; -} - -static inline u64 buf_get_le64(const void *_buf) -{ - const byte *in = _buf; - return ((u64)in[7] << 56) | ((u64)in[6] << 48) | \ - ((u64)in[5] << 40) | ((u64)in[4] << 32) | \ - ((u64)in[3] << 24) | ((u64)in[2] << 16) | \ - ((u64)in[1] << 8) | (u64)in[0]; -} - -static inline void buf_put_be64(void *_buf, u64 val) -{ - byte *out = _buf; - out[0] = val >> 56; - out[1] = val >> 48; - out[2] = val >> 40; - out[3] = val >> 32; - out[4] = val >> 24; - out[5] = val >> 16; - out[6] = val >> 8; - out[7] = val; -} - -static inline void buf_put_le64(void *_buf, u64 val) -{ - byte *out = _buf; - out[7] = val >> 56; - out[6] = val >> 48; - out[5] = val >> 40; - out[4] = val >> 32; - out[3] = val >> 24; - out[2] = val >> 16; - out[1] = val >> 8; - out[0] = val; -} - -#else /*BUFHELP_FAST_UNALIGNED_ACCESS*/ - -typedef struct bufhelp_u32_s -{ - u32 a; -} __attribute__((packed, aligned(1))) bufhelp_u32_t; - -/* Functions for loading and storing unaligned u32 values of different - endianness. */ -static inline u32 buf_get_be32(const void *_buf) -{ - return be_bswap32(((const bufhelp_u32_t *)_buf)->a); -} - -static inline u32 buf_get_le32(const void *_buf) -{ - return le_bswap32(((const bufhelp_u32_t *)_buf)->a); -} - -static inline void buf_put_be32(void *_buf, u32 val) -{ - bufhelp_u32_t *out = _buf; - out->a = be_bswap32(val); -} - -static inline void buf_put_le32(void *_buf, u32 val) -{ - bufhelp_u32_t *out = _buf; - out->a = le_bswap32(val); -} - - -typedef struct bufhelp_u64_s -{ - u64 a; -} __attribute__((packed, aligned(1))) bufhelp_u64_t; - -/* Functions for loading and storing unaligned u64 values of different - endianness. */ -static inline u64 buf_get_be64(const void *_buf) -{ - return be_bswap64(((const bufhelp_u64_t *)_buf)->a); -} - -static inline u64 buf_get_le64(const void *_buf) -{ - return le_bswap64(((const bufhelp_u64_t *)_buf)->a); -} - -static inline void buf_put_be64(void *_buf, u64 val) -{ - bufhelp_u64_t *out = _buf; - out->a = be_bswap64(val); -} - -static inline void buf_put_le64(void *_buf, u64 val) -{ - bufhelp_u64_t *out = _buf; - out->a = le_bswap64(val); -} - - -#endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/ - -#endif /*GCRYPT_BUFHELP_H*/ diff --git a/grub-core/lib/libgcrypt/cipher/crc.c b/grub-core/lib/libgcrypt/cipher/crc.c deleted file mode 100644 index 28454f8ab..000000000 --- a/grub-core/lib/libgcrypt/cipher/crc.c +++ /dev/null @@ -1,793 +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 -#include -#include -#include - -#include "g10lib.h" -#include "cipher.h" - -#include "bithelp.h" -#include "bufhelp.h" - - -typedef struct -{ - u32 CRC; - byte buf[4]; -} -CRC_CONTEXT; - - -/* - * Code generated by universal_crc by Danjel McGougan - * - * CRC parameters used: - * bits: 32 - * poly: 0x04c11db7 - * init: 0xffffffff - * xor: 0xffffffff - * reverse: true - * non-direct: false - * - * CRC of the string "123456789" is 0xcbf43926 - */ - -static const u32 crc32_table[1024] = { - 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, - 0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, - 0x646cc504, 0x7d77f445, 0x565aa786, 0x4f4196c7, - 0xc8d98a08, 0xd1c2bb49, 0xfaefe88a, 0xe3f4d9cb, - 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, 0x87981ccf, - 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, - 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, - 0x821b9859, 0x9b00a918, 0xb02dfadb, 0xa936cb9a, - 0xe6775d5d, 0xff6c6c1c, 0xd4413fdf, 0xcd5a0e9e, - 0x958424a2, 0x8c9f15e3, 0xa7b24620, 0xbea97761, - 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, - 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, - 0x39316bae, 0x202a5aef, 0x0b07092c, 0x121c386d, - 0xdf4636f3, 0xc65d07b2, 0xed705471, 0xf46b6530, - 0xbb2af3f7, 0xa231c2b6, 0x891c9175, 0x9007a034, - 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, - 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, - 0xf0794f05, 0xe9627e44, 0xc24f2d87, 0xdb541cc6, - 0x94158a01, 0x8d0ebb40, 0xa623e883, 0xbf38d9c2, - 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, 0x138d96ce, - 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, - 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, - 0xded79850, 0xc7cca911, 0xece1fad2, 0xf5facb93, - 0x7262d75c, 0x6b79e61d, 0x4054b5de, 0x594f849f, - 0x160e1258, 0x0f152319, 0x243870da, 0x3d23419b, - 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, - 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, - 0xad24e1af, 0xb43fd0ee, 0x9f12832d, 0x8609b26c, - 0xc94824ab, 0xd05315ea, 0xfb7e4629, 0xe2657768, - 0x2f3f79f6, 0x362448b7, 0x1d091b74, 0x04122a35, - 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, - 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, - 0x838a36fa, 0x9a9107bb, 0xb1bc5478, 0xa8a76539, - 0x3b83984b, 0x2298a90a, 0x09b5fac9, 0x10aecb88, - 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, 0x74c20e8c, - 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, - 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, - 0x71418a1a, 0x685abb5b, 0x4377e898, 0x5a6cd9d9, - 0x152d4f1e, 0x0c367e5f, 0x271b2d9c, 0x3e001cdd, - 0xb9980012, 0xa0833153, 0x8bae6290, 0x92b553d1, - 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, - 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, - 0xca6b79ed, 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, - 0x66de36e1, 0x7fc507a0, 0x54e85463, 0x4df36522, - 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, 0x299fa026, - 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, - 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, - 0x2c1c24b0, 0x350715f1, 0x1e2a4632, 0x07317773, - 0x4870e1b4, 0x516bd0f5, 0x7a468336, 0x635db277, - 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, 0xe0d7848d, - 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, - 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, - 0x674f9842, 0x7e54a903, 0x5579fac0, 0x4c62cb81, - 0x8138c51f, 0x9823f45e, 0xb30ea79d, 0xaa1596dc, - 0xe554001b, 0xfc4f315a, 0xd7626299, 0xce7953d8, - 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, - 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, - 0x5e7ef3ec, 0x4765c2ad, 0x6c48916e, 0x7553a02f, - 0x3a1236e8, 0x230907a9, 0x0824546a, 0x113f652b, - 0x96a779e4, 0x8fbc48a5, 0xa4911b66, 0xbd8a2a27, - 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, - 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, - 0x70d024b9, 0x69cb15f8, 0x42e6463b, 0x5bfd777a, - 0xdc656bb5, 0xc57e5af4, 0xee530937, 0xf7483876, - 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, 0x9324fd72, - 0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, - 0x0709a8dc, 0x06cbc2eb, 0x048d7cb2, 0x054f1685, - 0x0e1351b8, 0x0fd13b8f, 0x0d9785d6, 0x0c55efe1, - 0x091af964, 0x08d89353, 0x0a9e2d0a, 0x0b5c473d, - 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, - 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, - 0x1235f2c8, 0x13f798ff, 0x11b126a6, 0x10734c91, - 0x153c5a14, 0x14fe3023, 0x16b88e7a, 0x177ae44d, - 0x384d46e0, 0x398f2cd7, 0x3bc9928e, 0x3a0bf8b9, - 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, - 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, - 0x3157bf84, 0x3095d5b3, 0x32d36bea, 0x331101dd, - 0x246be590, 0x25a98fa7, 0x27ef31fe, 0x262d5bc9, - 0x23624d4c, 0x22a0277b, 0x20e69922, 0x2124f315, - 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, - 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, - 0x709a8dc0, 0x7158e7f7, 0x731e59ae, 0x72dc3399, - 0x7793251c, 0x76514f2b, 0x7417f172, 0x75d59b45, - 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, 0x7ccf6221, - 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, - 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, - 0x6bb5866c, 0x6a77ec5b, 0x68315202, 0x69f33835, - 0x62af7f08, 0x636d153f, 0x612bab66, 0x60e9c151, - 0x65a6d7d4, 0x6464bde3, 0x662203ba, 0x67e0698d, - 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, - 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, - 0x46c49a98, 0x4706f0af, 0x45404ef6, 0x448224c1, - 0x41cd3244, 0x400f5873, 0x4249e62a, 0x438b8c1d, - 0x54f16850, 0x55330267, 0x5775bc3e, 0x56b7d609, - 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, - 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, - 0x5deb9134, 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, - 0xe1351b80, 0xe0f771b7, 0xe2b1cfee, 0xe373a5d9, - 0xe63cb35c, 0xe7fed96b, 0xe5b86732, 0xe47a0d05, - 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, - 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, - 0xfd13b8f0, 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, - 0xfa1a102c, 0xfbd87a1b, 0xf99ec442, 0xf85cae75, - 0xf300e948, 0xf2c2837f, 0xf0843d26, 0xf1465711, - 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, - 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, - 0xde71f5bc, 0xdfb39f8b, 0xddf521d2, 0xdc374be5, - 0xd76b0cd8, 0xd6a966ef, 0xd4efd8b6, 0xd52db281, - 0xd062a404, 0xd1a0ce33, 0xd3e6706a, 0xd2241a5d, - 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, - 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, - 0xcb4dafa8, 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, - 0xcc440774, 0xcd866d43, 0xcfc0d31a, 0xce02b92d, - 0x91af9640, 0x906dfc77, 0x922b422e, 0x93e92819, - 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, - 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, - 0x98b56f24, 0x99770513, 0x9b31bb4a, 0x9af3d17d, - 0x8d893530, 0x8c4b5f07, 0x8e0de15e, 0x8fcf8b69, - 0x8a809dec, 0x8b42f7db, 0x89044982, 0x88c623b5, - 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, - 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, - 0xa9e2d0a0, 0xa820ba97, 0xaa6604ce, 0xaba46ef9, - 0xaeeb787c, 0xaf29124b, 0xad6fac12, 0xacadc625, - 0xa7f18118, 0xa633eb2f, 0xa4755576, 0xa5b73f41, - 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, - 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, - 0xb2cddb0c, 0xb30fb13b, 0xb1490f62, 0xb08b6555, - 0xbbd72268, 0xba15485f, 0xb853f606, 0xb9919c31, - 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, 0xbe9834ed, - 0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, - 0x8f629757, 0x37def032, 0x256b5fdc, 0x9dd738b9, - 0xc5b428ef, 0x7d084f8a, 0x6fbde064, 0xd7018701, - 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, 0x58631056, - 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, - 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, - 0x95ad7f70, 0x2d111815, 0x3fa4b7fb, 0x8718d09e, - 0x1acfe827, 0xa2738f42, 0xb0c620ac, 0x087a47c9, - 0xa032af3e, 0x188ec85b, 0x0a3b67b5, 0xb28700d0, - 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, - 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, - 0xeae41086, 0x525877e3, 0x40edd80d, 0xf851bf68, - 0xf02bf8a1, 0x48979fc4, 0x5a22302a, 0xe29e574f, - 0x7f496ff6, 0xc7f50893, 0xd540a77d, 0x6dfcc018, - 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, - 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, - 0x9b14583d, 0x23a83f58, 0x311d90b6, 0x89a1f7d3, - 0x1476cf6a, 0xaccaa80f, 0xbe7f07e1, 0x06c36084, - 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, 0x4c15df3c, - 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, - 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, - 0x446f98f5, 0xfcd3ff90, 0xee66507e, 0x56da371b, - 0x0eb9274d, 0xb6054028, 0xa4b0efc6, 0x1c0c88a3, - 0x81dbb01a, 0x3967d77f, 0x2bd27891, 0x936e1ff4, - 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, - 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, - 0xfe92dfec, 0x462eb889, 0x549b1767, 0xec277002, - 0x71f048bb, 0xc94c2fde, 0xdbf98030, 0x6345e755, - 0x6b3fa09c, 0xd383c7f9, 0xc1366817, 0x798a0f72, - 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, - 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, - 0x21e91f24, 0x99557841, 0x8be0d7af, 0x335cb0ca, - 0xed59b63b, 0x55e5d15e, 0x47507eb0, 0xffec19d5, - 0x623b216c, 0xda874609, 0xc832e9e7, 0x708e8e82, - 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, - 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, - 0xbd40e1a4, 0x05fc86c1, 0x1749292f, 0xaff54e4a, - 0x322276f3, 0x8a9e1196, 0x982bbe78, 0x2097d91d, - 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, 0x6a4166a5, - 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, - 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, - 0xc2098e52, 0x7ab5e937, 0x680046d9, 0xd0bc21bc, - 0x88df31ea, 0x3063568f, 0x22d6f961, 0x9a6a9e04, - 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, 0x15080953, - 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, - 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, - 0xd8c66675, 0x607a0110, 0x72cfaefe, 0xca73c99b, - 0x57a4f122, 0xef189647, 0xfdad39a9, 0x45115ecc, - 0x764dee06, 0xcef18963, 0xdc44268d, 0x64f841e8, - 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, - 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, - 0x3c9b51be, 0x842736db, 0x96929935, 0x2e2efe50, - 0x2654b999, 0x9ee8defc, 0x8c5d7112, 0x34e11677, - 0xa9362ece, 0x118a49ab, 0x033fe645, 0xbb838120, - 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, - 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, - 0xd67f4138, 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, - 0x591dd66f, 0xe1a1b10a, 0xf3141ee4, 0x4ba87981, - 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, 0x017ec639, - 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, - 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, - 0x090481f0, 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, - 0x43d23e48, 0xfb6e592d, 0xe9dbf6c3, 0x516791a6, - 0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1 -}; - -/* CRC32 */ - -static inline u32 -crc32_next (u32 crc, byte data) -{ - return (crc >> 8) ^ crc32_table[(crc & 0xff) ^ data]; -} - -/* - * Process 4 bytes in one go - */ -static inline u32 -crc32_next4 (u32 crc, u32 data) -{ - crc ^= data; - crc = crc32_table[(crc & 0xff) + 0x300] ^ - crc32_table[((crc >> 8) & 0xff) + 0x200] ^ - crc32_table[((crc >> 16) & 0xff) + 0x100] ^ - crc32_table[(crc >> 24) & 0xff]; - return crc; -} - -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_arg, size_t inlen) -{ - CRC_CONTEXT *ctx = (CRC_CONTEXT *) context; - const byte *inbuf = inbuf_arg; - u32 crc; - - if (!inbuf || !inlen) - return; - - crc = ctx->CRC; - - while (inlen >= 16) - { - inlen -= 16; - crc = crc32_next4(crc, buf_get_le32(&inbuf[0])); - crc = crc32_next4(crc, buf_get_le32(&inbuf[4])); - crc = crc32_next4(crc, buf_get_le32(&inbuf[8])); - crc = crc32_next4(crc, buf_get_le32(&inbuf[12])); - inbuf += 16; - } - - while (inlen >= 4) - { - inlen -= 4; - crc = crc32_next4(crc, buf_get_le32(inbuf)); - inbuf += 4; - } - - while (inlen--) - { - crc = crc32_next(crc, *inbuf++); - } - - ctx->CRC = crc; -} - -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; - buf_put_be32 (ctx->buf, ctx->CRC); -} - -/* CRC32 a'la RFC 1510 */ -/* CRC of the string "123456789" is 0x2dfd2d88 */ - -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; - buf_put_be32(ctx->buf, ctx->CRC); -} - -/* CRC24 a'la RFC 2440 */ -/* - * Code generated by universal_crc by Danjel McGougan - * - * CRC parameters used: - * bits: 24 - * poly: 0x864cfb - * init: 0xb704ce - * xor: 0x000000 - * reverse: false - * non-direct: false - * - * CRC of the string "123456789" is 0x21cf02 - */ - -static const u32 crc24_table[1024] = -{ - 0x00000000, 0x00fb4c86, 0x000dd58a, 0x00f6990c, - 0x00e1e693, 0x001aaa15, 0x00ec3319, 0x00177f9f, - 0x003981a1, 0x00c2cd27, 0x0034542b, 0x00cf18ad, - 0x00d86732, 0x00232bb4, 0x00d5b2b8, 0x002efe3e, - 0x00894ec5, 0x00720243, 0x00849b4f, 0x007fd7c9, - 0x0068a856, 0x0093e4d0, 0x00657ddc, 0x009e315a, - 0x00b0cf64, 0x004b83e2, 0x00bd1aee, 0x00465668, - 0x005129f7, 0x00aa6571, 0x005cfc7d, 0x00a7b0fb, - 0x00e9d10c, 0x00129d8a, 0x00e40486, 0x001f4800, - 0x0008379f, 0x00f37b19, 0x0005e215, 0x00feae93, - 0x00d050ad, 0x002b1c2b, 0x00dd8527, 0x0026c9a1, - 0x0031b63e, 0x00cafab8, 0x003c63b4, 0x00c72f32, - 0x00609fc9, 0x009bd34f, 0x006d4a43, 0x009606c5, - 0x0081795a, 0x007a35dc, 0x008cacd0, 0x0077e056, - 0x00591e68, 0x00a252ee, 0x0054cbe2, 0x00af8764, - 0x00b8f8fb, 0x0043b47d, 0x00b52d71, 0x004e61f7, - 0x00d2a319, 0x0029ef9f, 0x00df7693, 0x00243a15, - 0x0033458a, 0x00c8090c, 0x003e9000, 0x00c5dc86, - 0x00eb22b8, 0x00106e3e, 0x00e6f732, 0x001dbbb4, - 0x000ac42b, 0x00f188ad, 0x000711a1, 0x00fc5d27, - 0x005beddc, 0x00a0a15a, 0x00563856, 0x00ad74d0, - 0x00ba0b4f, 0x004147c9, 0x00b7dec5, 0x004c9243, - 0x00626c7d, 0x009920fb, 0x006fb9f7, 0x0094f571, - 0x00838aee, 0x0078c668, 0x008e5f64, 0x007513e2, - 0x003b7215, 0x00c03e93, 0x0036a79f, 0x00cdeb19, - 0x00da9486, 0x0021d800, 0x00d7410c, 0x002c0d8a, - 0x0002f3b4, 0x00f9bf32, 0x000f263e, 0x00f46ab8, - 0x00e31527, 0x001859a1, 0x00eec0ad, 0x00158c2b, - 0x00b23cd0, 0x00497056, 0x00bfe95a, 0x0044a5dc, - 0x0053da43, 0x00a896c5, 0x005e0fc9, 0x00a5434f, - 0x008bbd71, 0x0070f1f7, 0x008668fb, 0x007d247d, - 0x006a5be2, 0x00911764, 0x00678e68, 0x009cc2ee, - 0x00a44733, 0x005f0bb5, 0x00a992b9, 0x0052de3f, - 0x0045a1a0, 0x00beed26, 0x0048742a, 0x00b338ac, - 0x009dc692, 0x00668a14, 0x00901318, 0x006b5f9e, - 0x007c2001, 0x00876c87, 0x0071f58b, 0x008ab90d, - 0x002d09f6, 0x00d64570, 0x0020dc7c, 0x00db90fa, - 0x00ccef65, 0x0037a3e3, 0x00c13aef, 0x003a7669, - 0x00148857, 0x00efc4d1, 0x00195ddd, 0x00e2115b, - 0x00f56ec4, 0x000e2242, 0x00f8bb4e, 0x0003f7c8, - 0x004d963f, 0x00b6dab9, 0x004043b5, 0x00bb0f33, - 0x00ac70ac, 0x00573c2a, 0x00a1a526, 0x005ae9a0, - 0x0074179e, 0x008f5b18, 0x0079c214, 0x00828e92, - 0x0095f10d, 0x006ebd8b, 0x00982487, 0x00636801, - 0x00c4d8fa, 0x003f947c, 0x00c90d70, 0x003241f6, - 0x00253e69, 0x00de72ef, 0x0028ebe3, 0x00d3a765, - 0x00fd595b, 0x000615dd, 0x00f08cd1, 0x000bc057, - 0x001cbfc8, 0x00e7f34e, 0x00116a42, 0x00ea26c4, - 0x0076e42a, 0x008da8ac, 0x007b31a0, 0x00807d26, - 0x009702b9, 0x006c4e3f, 0x009ad733, 0x00619bb5, - 0x004f658b, 0x00b4290d, 0x0042b001, 0x00b9fc87, - 0x00ae8318, 0x0055cf9e, 0x00a35692, 0x00581a14, - 0x00ffaaef, 0x0004e669, 0x00f27f65, 0x000933e3, - 0x001e4c7c, 0x00e500fa, 0x001399f6, 0x00e8d570, - 0x00c62b4e, 0x003d67c8, 0x00cbfec4, 0x0030b242, - 0x0027cddd, 0x00dc815b, 0x002a1857, 0x00d154d1, - 0x009f3526, 0x006479a0, 0x0092e0ac, 0x0069ac2a, - 0x007ed3b5, 0x00859f33, 0x0073063f, 0x00884ab9, - 0x00a6b487, 0x005df801, 0x00ab610d, 0x00502d8b, - 0x00475214, 0x00bc1e92, 0x004a879e, 0x00b1cb18, - 0x00167be3, 0x00ed3765, 0x001bae69, 0x00e0e2ef, - 0x00f79d70, 0x000cd1f6, 0x00fa48fa, 0x0001047c, - 0x002ffa42, 0x00d4b6c4, 0x00222fc8, 0x00d9634e, - 0x00ce1cd1, 0x00355057, 0x00c3c95b, 0x003885dd, - 0x00000000, 0x00488f66, 0x00901ecd, 0x00d891ab, - 0x00db711c, 0x0093fe7a, 0x004b6fd1, 0x0003e0b7, - 0x00b6e338, 0x00fe6c5e, 0x0026fdf5, 0x006e7293, - 0x006d9224, 0x00251d42, 0x00fd8ce9, 0x00b5038f, - 0x006cc771, 0x00244817, 0x00fcd9bc, 0x00b456da, - 0x00b7b66d, 0x00ff390b, 0x0027a8a0, 0x006f27c6, - 0x00da2449, 0x0092ab2f, 0x004a3a84, 0x0002b5e2, - 0x00015555, 0x0049da33, 0x00914b98, 0x00d9c4fe, - 0x00d88ee3, 0x00900185, 0x0048902e, 0x00001f48, - 0x0003ffff, 0x004b7099, 0x0093e132, 0x00db6e54, - 0x006e6ddb, 0x0026e2bd, 0x00fe7316, 0x00b6fc70, - 0x00b51cc7, 0x00fd93a1, 0x0025020a, 0x006d8d6c, - 0x00b44992, 0x00fcc6f4, 0x0024575f, 0x006cd839, - 0x006f388e, 0x0027b7e8, 0x00ff2643, 0x00b7a925, - 0x0002aaaa, 0x004a25cc, 0x0092b467, 0x00da3b01, - 0x00d9dbb6, 0x009154d0, 0x0049c57b, 0x00014a1d, - 0x004b5141, 0x0003de27, 0x00db4f8c, 0x0093c0ea, - 0x0090205d, 0x00d8af3b, 0x00003e90, 0x0048b1f6, - 0x00fdb279, 0x00b53d1f, 0x006dacb4, 0x002523d2, - 0x0026c365, 0x006e4c03, 0x00b6dda8, 0x00fe52ce, - 0x00279630, 0x006f1956, 0x00b788fd, 0x00ff079b, - 0x00fce72c, 0x00b4684a, 0x006cf9e1, 0x00247687, - 0x00917508, 0x00d9fa6e, 0x00016bc5, 0x0049e4a3, - 0x004a0414, 0x00028b72, 0x00da1ad9, 0x009295bf, - 0x0093dfa2, 0x00db50c4, 0x0003c16f, 0x004b4e09, - 0x0048aebe, 0x000021d8, 0x00d8b073, 0x00903f15, - 0x00253c9a, 0x006db3fc, 0x00b52257, 0x00fdad31, - 0x00fe4d86, 0x00b6c2e0, 0x006e534b, 0x0026dc2d, - 0x00ff18d3, 0x00b797b5, 0x006f061e, 0x00278978, - 0x002469cf, 0x006ce6a9, 0x00b47702, 0x00fcf864, - 0x0049fbeb, 0x0001748d, 0x00d9e526, 0x00916a40, - 0x00928af7, 0x00da0591, 0x0002943a, 0x004a1b5c, - 0x0096a282, 0x00de2de4, 0x0006bc4f, 0x004e3329, - 0x004dd39e, 0x00055cf8, 0x00ddcd53, 0x00954235, - 0x002041ba, 0x0068cedc, 0x00b05f77, 0x00f8d011, - 0x00fb30a6, 0x00b3bfc0, 0x006b2e6b, 0x0023a10d, - 0x00fa65f3, 0x00b2ea95, 0x006a7b3e, 0x0022f458, - 0x002114ef, 0x00699b89, 0x00b10a22, 0x00f98544, - 0x004c86cb, 0x000409ad, 0x00dc9806, 0x00941760, - 0x0097f7d7, 0x00df78b1, 0x0007e91a, 0x004f667c, - 0x004e2c61, 0x0006a307, 0x00de32ac, 0x0096bdca, - 0x00955d7d, 0x00ddd21b, 0x000543b0, 0x004dccd6, - 0x00f8cf59, 0x00b0403f, 0x0068d194, 0x00205ef2, - 0x0023be45, 0x006b3123, 0x00b3a088, 0x00fb2fee, - 0x0022eb10, 0x006a6476, 0x00b2f5dd, 0x00fa7abb, - 0x00f99a0c, 0x00b1156a, 0x006984c1, 0x00210ba7, - 0x00940828, 0x00dc874e, 0x000416e5, 0x004c9983, - 0x004f7934, 0x0007f652, 0x00df67f9, 0x0097e89f, - 0x00ddf3c3, 0x00957ca5, 0x004ded0e, 0x00056268, - 0x000682df, 0x004e0db9, 0x00969c12, 0x00de1374, - 0x006b10fb, 0x00239f9d, 0x00fb0e36, 0x00b38150, - 0x00b061e7, 0x00f8ee81, 0x00207f2a, 0x0068f04c, - 0x00b134b2, 0x00f9bbd4, 0x00212a7f, 0x0069a519, - 0x006a45ae, 0x0022cac8, 0x00fa5b63, 0x00b2d405, - 0x0007d78a, 0x004f58ec, 0x0097c947, 0x00df4621, - 0x00dca696, 0x009429f0, 0x004cb85b, 0x0004373d, - 0x00057d20, 0x004df246, 0x009563ed, 0x00ddec8b, - 0x00de0c3c, 0x0096835a, 0x004e12f1, 0x00069d97, - 0x00b39e18, 0x00fb117e, 0x002380d5, 0x006b0fb3, - 0x0068ef04, 0x00206062, 0x00f8f1c9, 0x00b07eaf, - 0x0069ba51, 0x00213537, 0x00f9a49c, 0x00b12bfa, - 0x00b2cb4d, 0x00fa442b, 0x0022d580, 0x006a5ae6, - 0x00df5969, 0x0097d60f, 0x004f47a4, 0x0007c8c2, - 0x00042875, 0x004ca713, 0x009436b8, 0x00dcb9de, - 0x00000000, 0x00d70983, 0x00555f80, 0x00825603, - 0x0051f286, 0x0086fb05, 0x0004ad06, 0x00d3a485, - 0x0059a88b, 0x008ea108, 0x000cf70b, 0x00dbfe88, - 0x00085a0d, 0x00df538e, 0x005d058d, 0x008a0c0e, - 0x00491c91, 0x009e1512, 0x001c4311, 0x00cb4a92, - 0x0018ee17, 0x00cfe794, 0x004db197, 0x009ab814, - 0x0010b41a, 0x00c7bd99, 0x0045eb9a, 0x0092e219, - 0x0041469c, 0x00964f1f, 0x0014191c, 0x00c3109f, - 0x006974a4, 0x00be7d27, 0x003c2b24, 0x00eb22a7, - 0x00388622, 0x00ef8fa1, 0x006dd9a2, 0x00bad021, - 0x0030dc2f, 0x00e7d5ac, 0x006583af, 0x00b28a2c, - 0x00612ea9, 0x00b6272a, 0x00347129, 0x00e378aa, - 0x00206835, 0x00f761b6, 0x007537b5, 0x00a23e36, - 0x00719ab3, 0x00a69330, 0x0024c533, 0x00f3ccb0, - 0x0079c0be, 0x00aec93d, 0x002c9f3e, 0x00fb96bd, - 0x00283238, 0x00ff3bbb, 0x007d6db8, 0x00aa643b, - 0x0029a4ce, 0x00fead4d, 0x007cfb4e, 0x00abf2cd, - 0x00785648, 0x00af5fcb, 0x002d09c8, 0x00fa004b, - 0x00700c45, 0x00a705c6, 0x002553c5, 0x00f25a46, - 0x0021fec3, 0x00f6f740, 0x0074a143, 0x00a3a8c0, - 0x0060b85f, 0x00b7b1dc, 0x0035e7df, 0x00e2ee5c, - 0x00314ad9, 0x00e6435a, 0x00641559, 0x00b31cda, - 0x003910d4, 0x00ee1957, 0x006c4f54, 0x00bb46d7, - 0x0068e252, 0x00bfebd1, 0x003dbdd2, 0x00eab451, - 0x0040d06a, 0x0097d9e9, 0x00158fea, 0x00c28669, - 0x001122ec, 0x00c62b6f, 0x00447d6c, 0x009374ef, - 0x001978e1, 0x00ce7162, 0x004c2761, 0x009b2ee2, - 0x00488a67, 0x009f83e4, 0x001dd5e7, 0x00cadc64, - 0x0009ccfb, 0x00dec578, 0x005c937b, 0x008b9af8, - 0x00583e7d, 0x008f37fe, 0x000d61fd, 0x00da687e, - 0x00506470, 0x00876df3, 0x00053bf0, 0x00d23273, - 0x000196f6, 0x00d69f75, 0x0054c976, 0x0083c0f5, - 0x00a9041b, 0x007e0d98, 0x00fc5b9b, 0x002b5218, - 0x00f8f69d, 0x002fff1e, 0x00ada91d, 0x007aa09e, - 0x00f0ac90, 0x0027a513, 0x00a5f310, 0x0072fa93, - 0x00a15e16, 0x00765795, 0x00f40196, 0x00230815, - 0x00e0188a, 0x00371109, 0x00b5470a, 0x00624e89, - 0x00b1ea0c, 0x0066e38f, 0x00e4b58c, 0x0033bc0f, - 0x00b9b001, 0x006eb982, 0x00ecef81, 0x003be602, - 0x00e84287, 0x003f4b04, 0x00bd1d07, 0x006a1484, - 0x00c070bf, 0x0017793c, 0x00952f3f, 0x004226bc, - 0x00918239, 0x00468bba, 0x00c4ddb9, 0x0013d43a, - 0x0099d834, 0x004ed1b7, 0x00cc87b4, 0x001b8e37, - 0x00c82ab2, 0x001f2331, 0x009d7532, 0x004a7cb1, - 0x00896c2e, 0x005e65ad, 0x00dc33ae, 0x000b3a2d, - 0x00d89ea8, 0x000f972b, 0x008dc128, 0x005ac8ab, - 0x00d0c4a5, 0x0007cd26, 0x00859b25, 0x005292a6, - 0x00813623, 0x00563fa0, 0x00d469a3, 0x00036020, - 0x0080a0d5, 0x0057a956, 0x00d5ff55, 0x0002f6d6, - 0x00d15253, 0x00065bd0, 0x00840dd3, 0x00530450, - 0x00d9085e, 0x000e01dd, 0x008c57de, 0x005b5e5d, - 0x0088fad8, 0x005ff35b, 0x00dda558, 0x000aacdb, - 0x00c9bc44, 0x001eb5c7, 0x009ce3c4, 0x004bea47, - 0x00984ec2, 0x004f4741, 0x00cd1142, 0x001a18c1, - 0x009014cf, 0x00471d4c, 0x00c54b4f, 0x001242cc, - 0x00c1e649, 0x0016efca, 0x0094b9c9, 0x0043b04a, - 0x00e9d471, 0x003eddf2, 0x00bc8bf1, 0x006b8272, - 0x00b826f7, 0x006f2f74, 0x00ed7977, 0x003a70f4, - 0x00b07cfa, 0x00677579, 0x00e5237a, 0x00322af9, - 0x00e18e7c, 0x003687ff, 0x00b4d1fc, 0x0063d87f, - 0x00a0c8e0, 0x0077c163, 0x00f59760, 0x00229ee3, - 0x00f13a66, 0x002633e5, 0x00a465e6, 0x00736c65, - 0x00f9606b, 0x002e69e8, 0x00ac3feb, 0x007b3668, - 0x00a892ed, 0x007f9b6e, 0x00fdcd6d, 0x002ac4ee, - 0x00000000, 0x00520936, 0x00a4126c, 0x00f61b5a, - 0x004825d8, 0x001a2cee, 0x00ec37b4, 0x00be3e82, - 0x006b0636, 0x00390f00, 0x00cf145a, 0x009d1d6c, - 0x002323ee, 0x00712ad8, 0x00873182, 0x00d538b4, - 0x00d60c6c, 0x0084055a, 0x00721e00, 0x00201736, - 0x009e29b4, 0x00cc2082, 0x003a3bd8, 0x006832ee, - 0x00bd0a5a, 0x00ef036c, 0x00191836, 0x004b1100, - 0x00f52f82, 0x00a726b4, 0x00513dee, 0x000334d8, - 0x00ac19d8, 0x00fe10ee, 0x00080bb4, 0x005a0282, - 0x00e43c00, 0x00b63536, 0x00402e6c, 0x0012275a, - 0x00c71fee, 0x009516d8, 0x00630d82, 0x003104b4, - 0x008f3a36, 0x00dd3300, 0x002b285a, 0x0079216c, - 0x007a15b4, 0x00281c82, 0x00de07d8, 0x008c0eee, - 0x0032306c, 0x0060395a, 0x00962200, 0x00c42b36, - 0x00111382, 0x00431ab4, 0x00b501ee, 0x00e708d8, - 0x0059365a, 0x000b3f6c, 0x00fd2436, 0x00af2d00, - 0x00a37f36, 0x00f17600, 0x00076d5a, 0x0055646c, - 0x00eb5aee, 0x00b953d8, 0x004f4882, 0x001d41b4, - 0x00c87900, 0x009a7036, 0x006c6b6c, 0x003e625a, - 0x00805cd8, 0x00d255ee, 0x00244eb4, 0x00764782, - 0x0075735a, 0x00277a6c, 0x00d16136, 0x00836800, - 0x003d5682, 0x006f5fb4, 0x009944ee, 0x00cb4dd8, - 0x001e756c, 0x004c7c5a, 0x00ba6700, 0x00e86e36, - 0x005650b4, 0x00045982, 0x00f242d8, 0x00a04bee, - 0x000f66ee, 0x005d6fd8, 0x00ab7482, 0x00f97db4, - 0x00474336, 0x00154a00, 0x00e3515a, 0x00b1586c, - 0x006460d8, 0x003669ee, 0x00c072b4, 0x00927b82, - 0x002c4500, 0x007e4c36, 0x0088576c, 0x00da5e5a, - 0x00d96a82, 0x008b63b4, 0x007d78ee, 0x002f71d8, - 0x00914f5a, 0x00c3466c, 0x00355d36, 0x00675400, - 0x00b26cb4, 0x00e06582, 0x00167ed8, 0x004477ee, - 0x00fa496c, 0x00a8405a, 0x005e5b00, 0x000c5236, - 0x0046ff6c, 0x0014f65a, 0x00e2ed00, 0x00b0e436, - 0x000edab4, 0x005cd382, 0x00aac8d8, 0x00f8c1ee, - 0x002df95a, 0x007ff06c, 0x0089eb36, 0x00dbe200, - 0x0065dc82, 0x0037d5b4, 0x00c1ceee, 0x0093c7d8, - 0x0090f300, 0x00c2fa36, 0x0034e16c, 0x0066e85a, - 0x00d8d6d8, 0x008adfee, 0x007cc4b4, 0x002ecd82, - 0x00fbf536, 0x00a9fc00, 0x005fe75a, 0x000dee6c, - 0x00b3d0ee, 0x00e1d9d8, 0x0017c282, 0x0045cbb4, - 0x00eae6b4, 0x00b8ef82, 0x004ef4d8, 0x001cfdee, - 0x00a2c36c, 0x00f0ca5a, 0x0006d100, 0x0054d836, - 0x0081e082, 0x00d3e9b4, 0x0025f2ee, 0x0077fbd8, - 0x00c9c55a, 0x009bcc6c, 0x006dd736, 0x003fde00, - 0x003cead8, 0x006ee3ee, 0x0098f8b4, 0x00caf182, - 0x0074cf00, 0x0026c636, 0x00d0dd6c, 0x0082d45a, - 0x0057ecee, 0x0005e5d8, 0x00f3fe82, 0x00a1f7b4, - 0x001fc936, 0x004dc000, 0x00bbdb5a, 0x00e9d26c, - 0x00e5805a, 0x00b7896c, 0x00419236, 0x00139b00, - 0x00ada582, 0x00ffacb4, 0x0009b7ee, 0x005bbed8, - 0x008e866c, 0x00dc8f5a, 0x002a9400, 0x00789d36, - 0x00c6a3b4, 0x0094aa82, 0x0062b1d8, 0x0030b8ee, - 0x00338c36, 0x00618500, 0x00979e5a, 0x00c5976c, - 0x007ba9ee, 0x0029a0d8, 0x00dfbb82, 0x008db2b4, - 0x00588a00, 0x000a8336, 0x00fc986c, 0x00ae915a, - 0x0010afd8, 0x0042a6ee, 0x00b4bdb4, 0x00e6b482, - 0x00499982, 0x001b90b4, 0x00ed8bee, 0x00bf82d8, - 0x0001bc5a, 0x0053b56c, 0x00a5ae36, 0x00f7a700, - 0x00229fb4, 0x00709682, 0x00868dd8, 0x00d484ee, - 0x006aba6c, 0x0038b35a, 0x00cea800, 0x009ca136, - 0x009f95ee, 0x00cd9cd8, 0x003b8782, 0x00698eb4, - 0x00d7b036, 0x0085b900, 0x0073a25a, 0x0021ab6c, - 0x00f493d8, 0x00a69aee, 0x005081b4, 0x00028882, - 0x00bcb600, 0x00eebf36, 0x0018a46c, 0x004aad5a -}; - -static inline -u32 crc24_init (void) -{ - return 0xce04b7; -} - -static inline -u32 crc24_next (u32 crc, byte data) -{ - return (crc >> 8) ^ crc24_table[(crc & 0xff) ^ data]; -} - -/* - * Process 4 bytes in one go - */ -static inline -u32 crc24_next4 (u32 crc, u32 data) -{ - crc ^= data; - crc = crc24_table[(crc & 0xff) + 0x300] ^ - crc24_table[((crc >> 8) & 0xff) + 0x200] ^ - crc24_table[((crc >> 16) & 0xff) + 0x100] ^ - crc24_table[(crc >> 24) & 0xff]; - return crc; -} - -static inline -u32 crc24_final (u32 crc) -{ - return crc & 0xffffff; -} - -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; - CRC_CONTEXT *ctx = (CRC_CONTEXT *) context; - u32 crc; - - if (!inbuf || !inlen) - return; - - crc = ctx->CRC; - - while (inlen >= 16) - { - inlen -= 16; - crc = crc24_next4(crc, buf_get_le32(&inbuf[0])); - crc = crc24_next4(crc, buf_get_le32(&inbuf[4])); - crc = crc24_next4(crc, buf_get_le32(&inbuf[8])); - crc = crc24_next4(crc, buf_get_le32(&inbuf[12])); - inbuf += 16; - } - - while (inlen >= 4) - { - inlen -= 4; - crc = crc24_next4(crc, buf_get_le32(inbuf)); - inbuf += 4; - } - - while (inlen--) - { - crc = crc24_next(crc, *inbuf++); - } - - ctx->CRC = crc; -} - -static void -crc24rfc2440_final (void *context) -{ - CRC_CONTEXT *ctx = (CRC_CONTEXT *) context; - ctx->CRC = crc24_final(ctx->CRC); - buf_put_le32 (ctx->buf, ctx->CRC); -} - -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/idea.c b/grub-core/lib/libgcrypt/cipher/idea.c deleted file mode 100644 index 3c5578f95..000000000 --- a/grub-core/lib/libgcrypt/cipher/idea.c +++ /dev/null @@ -1,378 +0,0 @@ -/* idea.c - IDEA function - * Copyright 1997, 1998, 1999, 2001 Werner Koch (dd9jn) - * Copyright 2013 g10 Code GmbH - * - * 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 - * WERNER KOCH 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. - * - * Except as contained in this notice, the name of Werner Koch shall not be - * used in advertising or otherwise to promote the sale, use or other dealings - * in this Software without prior written authorization from Werner Koch. - * - * Patents on IDEA have expired: - * Europe: EP0482154 on 2011-05-16, - * Japan: JP3225440 on 2011-05-16, - * U.S.: 5,214,703 on 2012-01-07. - */ - -/* - * Please see http://www.noepatents.org/ to learn why software patents - * are bad for society and what you can do to fight them. - * - * The code herein is based on the one from: - * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996. - * ISBN 0-471-11709-9. - */ - - -#include -#include -#include -#include -#include - -#include "types.h" /* for byte and u32 typedefs */ -#include "g10lib.h" -#include "cipher.h" - - -#define IDEA_KEYSIZE 16 -#define IDEA_BLOCKSIZE 8 -#define IDEA_ROUNDS 8 -#define IDEA_KEYLEN (6*IDEA_ROUNDS+4) - -typedef struct { - u16 ek[IDEA_KEYLEN]; - u16 dk[IDEA_KEYLEN]; - int have_dk; -} IDEA_context; - -static const char *selftest(void); - - -static u16 -mul_inv( u16 x ) -{ - u16 t0, t1; - u16 q, y; - - if( x < 2 ) - return x; - t1 = 0x10001UL / x; - y = 0x10001UL % x; - if( y == 1 ) - return (1-t1) & 0xffff; - - t0 = 1; - do { - q = x / y; - x = x % y; - t0 += q * t1; - if( x == 1 ) - return t0; - q = y / x; - y = y % x; - t1 += q * t0; - } while( y != 1 ); - return (1-t1) & 0xffff; -} - - - -static void -expand_key( const byte *userkey, u16 *ek ) -{ - int i,j; - - for(j=0; j < 8; j++ ) { - ek[j] = (*userkey << 8) + userkey[1]; - userkey += 2; - } - for(i=0; j < IDEA_KEYLEN; j++ ) { - i++; - ek[i+7] = ek[i&7] << 9 | ek[(i+1)&7] >> 7; - ek += i & 8; - i &= 7; - } -} - - -static void -invert_key( u16 *ek, u16 dk[IDEA_KEYLEN] ) -{ - int i; - u16 t1, t2, t3; - u16 temp[IDEA_KEYLEN]; - u16 *p = temp + IDEA_KEYLEN; - - t1 = mul_inv( *ek++ ); - t2 = -*ek++; - t3 = -*ek++; - *--p = mul_inv( *ek++ ); - *--p = t3; - *--p = t2; - *--p = t1; - - for(i=0; i < IDEA_ROUNDS-1; i++ ) { - t1 = *ek++; - *--p = *ek++; - *--p = t1; - - t1 = mul_inv( *ek++ ); - t2 = -*ek++; - t3 = -*ek++; - *--p = mul_inv( *ek++ ); - *--p = t2; - *--p = t3; - *--p = t1; - } - t1 = *ek++; - *--p = *ek++; - *--p = t1; - - t1 = mul_inv( *ek++ ); - t2 = -*ek++; - t3 = -*ek++; - *--p = mul_inv( *ek++ ); - *--p = t3; - *--p = t2; - *--p = t1; - memcpy(dk, temp, sizeof(temp) ); - memset(temp, 0, sizeof(temp) ); /* burn temp */ -} - - -static void -cipher( byte *outbuf, const byte *inbuf, u16 *key ) -{ - u16 s2, s3; - u16 in[4]; - int r = IDEA_ROUNDS; -#define x1 (in[0]) -#define x2 (in[1]) -#define x3 (in[2]) -#define x4 (in[3]) -#define MUL(x,y) \ - do {u16 _t16; u32 _t32; \ - if( (_t16 = (y)) ) { \ - if( (x = (x)&0xffff) ) { \ - _t32 = (u32)x * _t16; \ - x = _t32 & 0xffff; \ - _t16 = _t32 >> 16; \ - x = ((x)-_t16) + (x<_t16?1:0); \ - } \ - else { \ - x = 1 - _t16; \ - } \ - } \ - else { \ - x = 1 - x; \ - } \ - } while(0) - - memcpy (in, inbuf, sizeof in); -#ifndef WORDS_BIGENDIAN - x1 = (x1>>8) | (x1<<8); - x2 = (x2>>8) | (x2<<8); - x3 = (x3>>8) | (x3<<8); - x4 = (x4>>8) | (x4<<8); -#endif - do { - MUL(x1, *key++); - x2 += *key++; - x3 += *key++; - MUL(x4, *key++ ); - - s3 = x3; - x3 ^= x1; - MUL(x3, *key++); - s2 = x2; - x2 ^=x4; - x2 += x3; - MUL(x2, *key++); - x3 += x2; - - x1 ^= x2; - x4 ^= x3; - - x2 ^= s3; - x3 ^= s2; - } while( --r ); - MUL(x1, *key++); - x3 += *key++; - x2 += *key++; - MUL(x4, *key); - -#ifndef WORDS_BIGENDIAN - x1 = (x1>>8) | (x1<<8); - x2 = (x2>>8) | (x2<<8); - x3 = (x3>>8) | (x3<<8); - x4 = (x4>>8) | (x4<<8); -#endif - memcpy (outbuf+0, &x1, 2); - memcpy (outbuf+2, &x3, 2); - memcpy (outbuf+4, &x2, 2); - memcpy (outbuf+6, &x4, 2); -#undef MUL -#undef x1 -#undef x2 -#undef x3 -#undef x4 -} - - -static int -do_setkey( IDEA_context *c, const byte *key, unsigned int keylen ) -{ - static int initialized = 0; - static const char *selftest_failed = 0; - - if( !initialized ) { - initialized = 1; - selftest_failed = selftest(); - if( selftest_failed ) - log_error( "%s\n", selftest_failed ); - } - if( selftest_failed ) - return GPG_ERR_SELFTEST_FAILED; - - assert(keylen == 16); - c->have_dk = 0; - expand_key( key, c->ek ); - invert_key( c->ek, c->dk ); - return 0; -} - -static gcry_err_code_t -idea_setkey (void *context, const byte *key, unsigned int keylen) -{ - IDEA_context *ctx = context; - int rc = do_setkey (ctx, key, keylen); - _gcry_burn_stack (23+6*sizeof(void*)); - return rc; -} - -static void -encrypt_block( IDEA_context *c, byte *outbuf, const byte *inbuf ) -{ - cipher( outbuf, inbuf, c->ek ); -} - -static void -idea_encrypt (void *context, byte *out, const byte *in) -{ - IDEA_context *ctx = context; - encrypt_block (ctx, out, in); - _gcry_burn_stack (24+3*sizeof (void*)); -} - -static void -decrypt_block( IDEA_context *c, byte *outbuf, const byte *inbuf ) -{ - if( !c->have_dk ) { - c->have_dk = 1; - invert_key( c->ek, c->dk ); - } - cipher( outbuf, inbuf, c->dk ); -} - -static void -idea_decrypt (void *context, byte *out, const byte *in) -{ - IDEA_context *ctx = context; - decrypt_block (ctx, out, in); - _gcry_burn_stack (24+3*sizeof (void*)); -} - - -static const char * -selftest( void ) -{ -static struct { - byte key[16]; - byte plain[8]; - byte cipher[8]; -} test_vectors[] = { - { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, - 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }, - { 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03 }, - { 0x11, 0xFB, 0xED, 0x2B, 0x01, 0x98, 0x6D, 0xE5 } }, - { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, - 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }, - { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }, - { 0x54, 0x0E, 0x5F, 0xEA, 0x18, 0xC2, 0xF8, 0xB1 } }, - { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, - 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }, - { 0x00, 0x19, 0x32, 0x4B, 0x64, 0x7D, 0x96, 0xAF }, - { 0x9F, 0x0A, 0x0A, 0xB6, 0xE1, 0x0C, 0xED, 0x78 } }, - { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, - 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }, - { 0xF5, 0x20, 0x2D, 0x5B, 0x9C, 0x67, 0x1B, 0x08 }, - { 0xCF, 0x18, 0xFD, 0x73, 0x55, 0xE2, 0xC5, 0xC5 } }, - { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, - 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }, - { 0xFA, 0xE6, 0xD2, 0xBE, 0xAA, 0x96, 0x82, 0x6E }, - { 0x85, 0xDF, 0x52, 0x00, 0x56, 0x08, 0x19, 0x3D } }, - { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, - 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }, - { 0x0A, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x46, 0x50 }, - { 0x2F, 0x7D, 0xE7, 0x50, 0x21, 0x2F, 0xB7, 0x34 } }, - { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, - 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }, - { 0x05, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x23, 0x28 }, - { 0x7B, 0x73, 0x14, 0x92, 0x5D, 0xE5, 0x9C, 0x09 } }, - { { 0x00, 0x05, 0x00, 0x0A, 0x00, 0x0F, 0x00, 0x14, - 0x00, 0x19, 0x00, 0x1E, 0x00, 0x23, 0x00, 0x28 }, - { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }, - { 0x3E, 0xC0, 0x47, 0x80, 0xBE, 0xFF, 0x6E, 0x20 } }, - { { 0x3A, 0x98, 0x4E, 0x20, 0x00, 0x19, 0x5D, 0xB3, - 0x2E, 0xE5, 0x01, 0xC8, 0xC4, 0x7C, 0xEA, 0x60 }, - { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }, - { 0x97, 0xBC, 0xD8, 0x20, 0x07, 0x80, 0xDA, 0x86 } }, - { { 0x00, 0x64, 0x00, 0xC8, 0x01, 0x2C, 0x01, 0x90, - 0x01, 0xF4, 0x02, 0x58, 0x02, 0xBC, 0x03, 0x20 }, - { 0x05, 0x32, 0x0A, 0x64, 0x14, 0xC8, 0x19, 0xFA }, - { 0x65, 0xBE, 0x87, 0xE7, 0xA2, 0x53, 0x8A, 0xED } }, - { { 0x9D, 0x40, 0x75, 0xC1, 0x03, 0xBC, 0x32, 0x2A, - 0xFB, 0x03, 0xE7, 0xBE, 0x6A, 0xB3, 0x00, 0x06 }, - { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, - { 0xF5, 0xDB, 0x1A, 0xC4, 0x5E, 0x5E, 0xF9, 0xF9 } } -}; - IDEA_context c; - byte buffer[8]; - int i; - - for(i=0; i < DIM(test_vectors); i++ ) { - do_setkey( &c, test_vectors[i].key, 16 ); - encrypt_block( &c, buffer, test_vectors[i].plain ); - if( memcmp( buffer, test_vectors[i].cipher, 8 ) ) - return "IDEA test encryption failed."; - decrypt_block( &c, buffer, test_vectors[i].cipher ); - if( memcmp( buffer, test_vectors[i].plain, 8 ) ) - return "IDEA test decryption failed."; - } - - return NULL; -} - - -gcry_cipher_spec_t _gcry_cipher_spec_idea = -{ - "IDEA", NULL, NULL, IDEA_BLOCKSIZE, 128, - sizeof (IDEA_context), - idea_setkey, idea_encrypt, idea_decrypt -}; diff --git a/grub-core/lib/libgcrypt/cipher/kdf.c b/grub-core/lib/libgcrypt/cipher/kdf.c deleted file mode 100644 index 46e8550df..000000000 --- a/grub-core/lib/libgcrypt/cipher/kdf.c +++ /dev/null @@ -1,278 +0,0 @@ -/* kdf.c - Key Derivation Functions - * Copyright (C) 1998, 2011 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 . - */ - -#include -#include -#include -#include -#include - -#include "g10lib.h" -#include "cipher.h" -#include "ath.h" - - -/* Transform a passphrase into a suitable key of length KEYSIZE and - store this key in the caller provided buffer KEYBUFFER. The caller - must provide an HASHALGO, a valid ALGO and depending on that algo a - SALT of 8 bytes and the number of ITERATIONS. Code taken from - gnupg/agent/protect.c:hash_passphrase. */ -gpg_err_code_t -openpgp_s2k (const void *passphrase, size_t passphraselen, - int algo, int hashalgo, - const void *salt, size_t saltlen, - unsigned long iterations, - size_t keysize, void *keybuffer) -{ - gpg_err_code_t ec; - gcry_md_hd_t md; - char *key = keybuffer; - int pass, i; - int used = 0; - int secmode; - - if ((algo == GCRY_KDF_SALTED_S2K || algo == GCRY_KDF_ITERSALTED_S2K) - && (!salt || saltlen != 8)) - return GPG_ERR_INV_VALUE; - - secmode = gcry_is_secure (passphrase) || gcry_is_secure (keybuffer); - - ec = gpg_err_code (gcry_md_open (&md, hashalgo, - secmode? GCRY_MD_FLAG_SECURE : 0)); - if (ec) - return ec; - - for (pass=0; used < keysize; pass++) - { - if (pass) - { - gcry_md_reset (md); - for (i=0; i < pass; i++) /* Preset the hash context. */ - gcry_md_putc (md, 0); - } - - if (algo == GCRY_KDF_SALTED_S2K || algo == GCRY_KDF_ITERSALTED_S2K) - { - int len2 = passphraselen + 8; - unsigned long count = len2; - - if (algo == GCRY_KDF_ITERSALTED_S2K) - { - count = iterations; - if (count < len2) - count = len2; - } - - while (count > len2) - { - gcry_md_write (md, salt, saltlen); - gcry_md_write (md, passphrase, passphraselen); - count -= len2; - } - if (count < saltlen) - gcry_md_write (md, salt, count); - else - { - gcry_md_write (md, salt, saltlen); - count -= saltlen; - gcry_md_write (md, passphrase, count); - } - } - else - gcry_md_write (md, passphrase, passphraselen); - - gcry_md_final (md); - i = gcry_md_get_algo_dlen (hashalgo); - if (i > keysize - used) - i = keysize - used; - memcpy (key+used, gcry_md_read (md, hashalgo), i); - used += i; - } - gcry_md_close (md); - return 0; -} - - -/* Transform a passphrase into a suitable key of length KEYSIZE and - store this key in the caller provided buffer KEYBUFFER. The caller - must provide PRFALGO which indicates the pseudorandom function to - use: This shall be the algorithms id of a hash algorithm; it is - used in HMAC mode. SALT is a salt of length SALTLEN and ITERATIONS - gives the number of iterations. */ -gpg_err_code_t -pkdf2 (const void *passphrase, size_t passphraselen, - int hashalgo, - const void *salt, size_t saltlen, - unsigned long iterations, - size_t keysize, void *keybuffer) -{ - gpg_err_code_t ec; - gcry_md_hd_t md; - int secmode; - unsigned int dklen = keysize; - char *dk = keybuffer; - unsigned int hlen; /* Output length of the digest function. */ - unsigned int l; /* Rounded up number of blocks. */ - unsigned int r; /* Number of octets in the last block. */ - char *sbuf; /* Malloced buffer to concatenate salt and iter - as well as space to hold TBUF and UBUF. */ - char *tbuf; /* Buffer for T; ptr into SBUF, size is HLEN. */ - char *ubuf; /* Buffer for U; ptr into SBUF, size is HLEN. */ - unsigned int lidx; /* Current block number. */ - unsigned long iter; /* Current iteration number. */ - unsigned int i; - - if (!salt || !saltlen || !iterations || !dklen) - return GPG_ERR_INV_VALUE; - - hlen = gcry_md_get_algo_dlen (hashalgo); - if (!hlen) - return GPG_ERR_DIGEST_ALGO; - - secmode = gcry_is_secure (passphrase) || gcry_is_secure (keybuffer); - - /* We ignore step 1 from pksc5v2.1 which demands a check that dklen - is not larger that 0xffffffff * hlen. */ - - /* Step 2 */ - l = ((dklen - 1)/ hlen) + 1; - r = dklen - (l - 1) * hlen; - - /* Setup buffers and prepare a hash context. */ - sbuf = (secmode - ? gcry_malloc_secure (saltlen + 4 + hlen + hlen) - : gcry_malloc (saltlen + 4 + hlen + hlen)); - if (!sbuf) - return gpg_err_code_from_syserror (); - tbuf = sbuf + saltlen + 4; - ubuf = tbuf + hlen; - - ec = gpg_err_code (gcry_md_open (&md, hashalgo, - (GCRY_MD_FLAG_HMAC - | (secmode?GCRY_MD_FLAG_SECURE:0)))); - if (ec) - { - gcry_free (sbuf); - return ec; - } - - /* Step 3 and 4. */ - memcpy (sbuf, salt, saltlen); - for (lidx = 1; lidx <= l; lidx++) - { - for (iter = 0; iter < iterations; iter++) - { - ec = gpg_err_code (gcry_md_setkey (md, passphrase, passphraselen)); - if (ec) - { - gcry_md_close (md); - gcry_free (sbuf); - return ec; - } - if (!iter) /* Compute U_1: */ - { - sbuf[saltlen] = (lidx >> 24); - sbuf[saltlen + 1] = (lidx >> 16); - sbuf[saltlen + 2] = (lidx >> 8); - sbuf[saltlen + 3] = lidx; - gcry_md_write (md, sbuf, saltlen + 4); - memcpy (ubuf, gcry_md_read (md, 0), hlen); - memcpy (tbuf, ubuf, hlen); - } - else /* Compute U_(2..c): */ - { - gcry_md_write (md, ubuf, hlen); - memcpy (ubuf, gcry_md_read (md, 0), hlen); - for (i=0; i < hlen; i++) - tbuf[i] ^= ubuf[i]; - } - } - if (lidx == l) /* Last block. */ - memcpy (dk, tbuf, r); - else - { - memcpy (dk, tbuf, hlen); - dk += hlen; - } - } - - gcry_md_close (md); - gcry_free (sbuf); - return 0; -} - - -/* Derive a key from a passphrase. KEYSIZE gives the requested size - of the keys in octets. KEYBUFFER is a caller provided buffer - filled on success with the derived key. The input passphrase is - taken from (PASSPHRASE,PASSPHRASELEN) which is an arbitrary memory - buffer. ALGO specifies the KDF algorithm to use; these are the - constants GCRY_KDF_*. SUBALGO specifies an algorithm used - internally by the KDF algorithms; this is usually a hash algorithm - but certain KDF algorithm may use it differently. {SALT,SALTLEN} - is a salt as needed by most KDF algorithms. ITERATIONS is a - positive integer parameter to most KDFs. 0 is returned on success, - or an error code on failure. */ -gpg_error_t -gcry_kdf_derive (const void *passphrase, size_t passphraselen, - int algo, int subalgo, - const void *salt, size_t saltlen, - unsigned long iterations, - size_t keysize, void *keybuffer) -{ - gpg_err_code_t ec; - - if (!passphrase || (!passphraselen && algo != GCRY_KDF_PBKDF2)) - { - ec = GPG_ERR_INV_DATA; - goto leave; - } - if (!keybuffer || !keysize) - { - ec = GPG_ERR_INV_VALUE; - goto leave; - } - - - switch (algo) - { - case GCRY_KDF_SIMPLE_S2K: - case GCRY_KDF_SALTED_S2K: - case GCRY_KDF_ITERSALTED_S2K: - ec = openpgp_s2k (passphrase, passphraselen, algo, subalgo, - salt, saltlen, iterations, keysize, keybuffer); - break; - - case GCRY_KDF_PBKDF1: - ec = GPG_ERR_UNSUPPORTED_ALGORITHM; - break; - - case GCRY_KDF_PBKDF2: - ec = pkdf2 (passphrase, passphraselen, subalgo, - salt, saltlen, iterations, keysize, keybuffer); - break; - - default: - ec = GPG_ERR_UNKNOWN_ALGORITHM; - break; - } - - leave: - return gpg_error (ec); -} diff --git a/grub-core/lib/libgcrypt/cipher/rijndael-tables.h b/grub-core/lib/libgcrypt/cipher/rijndael-tables.h deleted file mode 100644 index b6a5b158c..000000000 --- a/grub-core/lib/libgcrypt/cipher/rijndael-tables.h +++ /dev/null @@ -1,1686 +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 . - */ - -/* 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 deleted file mode 100644 index b3effa2db..000000000 --- a/grub-core/lib/libgcrypt/cipher/rijndael.c +++ /dev/null @@ -1,2095 +0,0 @@ -/* Rijndael (AES) for GnuPG - * Copyright (C) 2000, 2001, 2002, 2003, 2007, - * 2008, 2011 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 . - ******************************************************************* - * 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 -#include -#include -#include /* 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) - - -/* Helper macro to force alignment to 16 bytes. */ -#ifdef __GNUC__ -# define ATTR_ALIGNED_16 __attribute__ ((aligned (16))) -#else -# define ATTR_ALIGNED_16 -#endif - - -/* 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 1 -# endif -#endif /*ENABLE_PADLOCK_SUPPORT*/ - -/* USE_AESNI inidicates whether to compile with Intel AES-NI code. We - need the vector-size attribute which seems to be available since - gcc 3. However, to be on the safe side we require at least gcc 4. */ -#undef USE_AESNI -#ifdef ENABLE_AESNI_SUPPORT -# if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ >= 4 -# define USE_AESNI 1 -# endif -#endif /* ENABLE_AESNI_SUPPORT */ - -#ifdef USE_AESNI - typedef int m128i_t __attribute__ ((__vector_size__ (16))); -#endif /*USE_AESNI*/ - -/* Define an u32 variant for the sake of gcc 4.4's strict aliasing. */ -#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 4 ) -typedef u32 __attribute__ ((__may_alias__)) u32_a_t; -#else -typedef u32 u32_a_t; -#endif - - - -/* Our context object. */ -typedef struct -{ - /* The first fields are the keyschedule arrays. This is so that - they are aligned on a 16 byte boundary if using gcc. This - alignment is required for the AES-NI code and a good idea in any - case. The alignment is guaranteed due to the way cipher.c - allocates the space for the context. The PROPERLY_ALIGNED_TYPE - hack is used to force a minimal alignment if not using gcc of if - the alignment requirement is higher that 16 bytes. */ - union - { - PROPERLY_ALIGNED_TYPE dummy; - byte keyschedule[MAXROUNDS+1][4][4]; -#ifdef USE_PADLOCK - /* The key as passed to the padlock engine. It is only used if - the padlock engine is used (USE_PADLOCK, below). */ - unsigned char padlock_key[16] __attribute__ ((aligned (16))); -#endif /*USE_PADLOCK*/ - } u1; - union - { - PROPERLY_ALIGNED_TYPE dummy; - byte keyschedule[MAXROUNDS+1][4][4]; - } u2; - 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. */ -#endif /*USE_PADLOCK*/ -#ifdef USE_AESNI - int use_aesni; /* AES-NI shall be used. */ -#endif /*USE_AESNI*/ -} RIJNDAEL_context ATTR_ALIGNED_16; - -/* Macros defining alias for the keyschedules. */ -#define keyschenc u1.keyschedule -#define keyschdec u2.keyschedule -#define padlockkey u1.padlock_key - -/* Two macros to be called prior and after the use of AESNI - instructions. There should be no external function calls between - the use of these macros. There purpose is to make sure that the - SSE regsiters are cleared and won't reveal any information about - the key or the data. */ -#ifdef USE_AESNI -# define aesni_prepare() do { } while (0) -# define aesni_cleanup() \ - do { asm volatile ("pxor %%xmm0, %%xmm0\n\t" \ - "pxor %%xmm1, %%xmm1\n" :: ); \ - } while (0) -# define aesni_cleanup_2_4() \ - do { asm volatile ("pxor %%xmm2, %%xmm2\n\t" \ - "pxor %%xmm3, %%xmm3\n" \ - "pxor %%xmm4, %%xmm4\n":: ); \ - } while (0) -#else -# define aesni_prepare() do { } while (0) -# define aesni_cleanup() do { } while (0) -#endif - - -/* All the numbers. */ -#include "rijndael-tables.h" - - - -/* Function prototypes. */ -#ifdef USE_AESNI -/* We don't want to inline these functions to help gcc allocate enough - registers. */ -static void do_aesni_ctr (const RIJNDAEL_context *ctx, unsigned char *ctr, - unsigned char *b, const unsigned char *a) - __attribute__ ((__noinline__)); -static void do_aesni_ctr_4 (const RIJNDAEL_context *ctx, unsigned char *ctr, - unsigned char *b, const unsigned char *a) - __attribute__ ((__noinline__)); -#endif /*USE_AESNI*/ - -static const char *selftest(void); - - - -/* 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; - unsigned int i; - int 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 -#ifdef USE_AESNI - ctx->use_aesni = 0; -#endif - - if( keylen == 128/8 ) - { - rounds = 10; - KC = 4; - - if (0) - { - ; - } -#ifdef USE_PADLOCK - else if ((_gcry_get_hw_features () & HWF_PADLOCK_AES)) - { - ctx->use_padlock = 1; - memcpy (ctx->padlockkey, key, keylen); - } -#endif -#ifdef USE_AESNI - else if ((_gcry_get_hw_features () & HWF_INTEL_AESNI)) - { - ctx->use_aesni = 1; - } -#endif - } - else if ( keylen == 192/8 ) - { - rounds = 12; - KC = 6; - - if (0) - { - ; - } -#ifdef USE_AESNI - else if ((_gcry_get_hw_features () & HWF_INTEL_AESNI)) - { - ctx->use_aesni = 1; - } -#endif - } - else if ( keylen == 256/8 ) - { - rounds = 14; - KC = 8; - - if (0) - { - ; - } -#ifdef USE_AESNI - else if ((_gcry_get_hw_features () & HWF_INTEL_AESNI)) - { - ctx->use_aesni = 1; - } -#endif - } - else - return GPG_ERR_INV_KEYLEN; - - ctx->rounds = rounds; - - /* NB: We don't yet support Padlock hardware key generation. */ - - if (0) - ; -#ifdef USE_AESNI_is_disabled_here - else if (ctx->use_aesni && ctx->rounds == 10) - { - /* Note: This code works for AES-128 but it is not much better - than using the standard key schedule. We disable it for - now and don't put any effort into implementing this for - AES-192 and AES-256. */ - asm volatile ("movl %[key], %%esi\n\t" - "movdqu (%%esi), %%xmm1\n\t" /* xmm1 := key */ - "movl %[ksch], %%esi\n\t" - "movdqa %%xmm1, (%%esi)\n\t" /* ksch[0] := xmm1 */ - "aeskeygenassist $0x01, %%xmm1, %%xmm2\n\t" - "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x10(%%esi)\n\t" /* ksch[1] := xmm1 */ - "aeskeygenassist $0x02, %%xmm1, %%xmm2\n\t" - "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x20(%%esi)\n\t" /* ksch[2] := xmm1 */ - "aeskeygenassist $0x04, %%xmm1, %%xmm2\n\t" - "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x30(%%esi)\n\t" /* ksch[3] := xmm1 */ - "aeskeygenassist $0x08, %%xmm1, %%xmm2\n\t" - "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x40(%%esi)\n\t" /* ksch[4] := xmm1 */ - "aeskeygenassist $0x10, %%xmm1, %%xmm2\n\t" - "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x50(%%esi)\n\t" /* ksch[5] := xmm1 */ - "aeskeygenassist $0x20, %%xmm1, %%xmm2\n\t" - "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x60(%%esi)\n\t" /* ksch[6] := xmm1 */ - "aeskeygenassist $0x40, %%xmm1, %%xmm2\n\t" - "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x70(%%esi)\n\t" /* ksch[7] := xmm1 */ - "aeskeygenassist $0x80, %%xmm1, %%xmm2\n\t" - "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x80(%%esi)\n\t" /* ksch[8] := xmm1 */ - "aeskeygenassist $0x1b, %%xmm1, %%xmm2\n\t" - "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0x90(%%esi)\n\t" /* ksch[9] := xmm1 */ - "aeskeygenassist $0x36, %%xmm1, %%xmm2\n\t" - "call .Lexpand128_%=\n\t" - "movdqa %%xmm1, 0xa0(%%esi)\n\t" /* ksch[10] := xmm1 */ - "jmp .Lleave%=\n" - - ".Lexpand128_%=:\n\t" - "pshufd $0xff, %%xmm2, %%xmm2\n\t" - "movdqa %%xmm1, %%xmm3\n\t" - "pslldq $4, %%xmm3\n\t" - "pxor %%xmm3, %%xmm1\n\t" - "pslldq $4, %%xmm3\n\t" - "pxor %%xmm3, %%xmm1\n\t" - "pslldq $4, %%xmm3\n\t" - "pxor %%xmm3, %%xmm2\n\t" - "pxor %%xmm2, %%xmm1\n\t" - "ret\n" - - ".Lleave%=:\n\t" - "pxor %%xmm1, %%xmm1\n\t" - "pxor %%xmm2, %%xmm2\n\t" - "pxor %%xmm3, %%xmm3\n" - : - : [key] "g" (key), [ksch] "g" (ctx->keyschenc) - : "%esi", "cc", "memory" ); - } -#endif /*USE_AESNI*/ - else - { -#define W (ctx->keyschenc) - for (i = 0; i < keylen; i++) - { - k[i >> 2][i & 3] = key[i]; - } - - for (j = KC-1; j >= 0; j--) - { - *((u32_a_t*)tk[j]) = *((u32_a_t*)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_a_t*)W[r][t]) = *((u32_a_t*)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_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]); - } - } - else - { - for (j = 1; j < KC/2; j++) - { - *((u32_a_t*)tk[j]) ^= *((u32_a_t*)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_a_t*)tk[j]) ^= *((u32_a_t*)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_a_t*)W[r][t]) = *((u32_a_t*)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; - -#ifdef USE_AESNI - if (ctx->use_aesni) - { - /* The AES-NI decrypt instructions use the Equivalent Inverse - Cipher, thus we can't use the the standard decrypt key - preparation. */ - m128i_t *ekey = (m128i_t*)ctx->keyschenc; - m128i_t *dkey = (m128i_t*)ctx->keyschdec; - int rr; - - dkey[0] = ekey[ctx->rounds]; - for (r=1, rr=ctx->rounds-1; r < ctx->rounds; r++, rr--) - { - asm volatile - ("movdqu %[ekey], %%xmm1\n\t" - /*"aesimc %%xmm1, %%xmm1\n\t"*/ - ".byte 0x66, 0x0f, 0x38, 0xdb, 0xc9\n\t" - "movdqu %%xmm1, %[dkey]" - : [dkey] "=m" (dkey[r]) - : [ekey] "m" (ekey[rr]) ); - } - dkey[r] = ekey[0]; - } - else -#endif /*USE_AESNI*/ - { - union - { - PROPERLY_ALIGNED_TYPE dummy; - byte *w; - } w; -#define w w.w - - for (r=0; r < MAXROUNDS+1; r++ ) - { - *((u32_a_t*)ctx->keyschdec[r][0]) = *((u32_a_t*)ctx->keyschenc[r][0]); - *((u32_a_t*)ctx->keyschdec[r][1]) = *((u32_a_t*)ctx->keyschenc[r][1]); - *((u32_a_t*)ctx->keyschdec[r][2]) = *((u32_a_t*)ctx->keyschenc[r][2]); - *((u32_a_t*)ctx->keyschdec[r][3]) = *((u32_a_t*)ctx->keyschenc[r][3]); - } -#define W (ctx->keyschdec) - for (r = 1; r < ctx->rounds; r++) - { - w = W[r][0]; - *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) - ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); - - w = W[r][1]; - *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) - ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); - - w = W[r][2]; - *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) - ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); - - w = W[r][3]; - *((u32_a_t*)w) = *((u32_a_t*)U1[w[0]]) ^ *((u32_a_t*)U2[w[1]]) - ^ *((u32_a_t*)U3[w[2]]) ^ *((u32_a_t*)U4[w[3]]); - } -#undef W -#undef w - } -} - - -/* 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->keyschenc) - int rounds = ctx->rounds; - int r; - union - { - u32 tempu32[4]; /* Force correct alignment. */ - byte temp[4][4]; - } u; - - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(a )) ^ *((u32_a_t*)rk[0][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(a+ 4)) ^ *((u32_a_t*)rk[0][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(a+ 8)) ^ *((u32_a_t*)rk[0][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(a+12)) ^ *((u32_a_t*)rk[0][3]); - *((u32_a_t*)(b )) = (*((u32_a_t*)T1[u.temp[0][0]]) - ^ *((u32_a_t*)T2[u.temp[1][1]]) - ^ *((u32_a_t*)T3[u.temp[2][2]]) - ^ *((u32_a_t*)T4[u.temp[3][3]])); - *((u32_a_t*)(b + 4)) = (*((u32_a_t*)T1[u.temp[1][0]]) - ^ *((u32_a_t*)T2[u.temp[2][1]]) - ^ *((u32_a_t*)T3[u.temp[3][2]]) - ^ *((u32_a_t*)T4[u.temp[0][3]])); - *((u32_a_t*)(b + 8)) = (*((u32_a_t*)T1[u.temp[2][0]]) - ^ *((u32_a_t*)T2[u.temp[3][1]]) - ^ *((u32_a_t*)T3[u.temp[0][2]]) - ^ *((u32_a_t*)T4[u.temp[1][3]])); - *((u32_a_t*)(b +12)) = (*((u32_a_t*)T1[u.temp[3][0]]) - ^ *((u32_a_t*)T2[u.temp[0][1]]) - ^ *((u32_a_t*)T3[u.temp[1][2]]) - ^ *((u32_a_t*)T4[u.temp[2][3]])); - - for (r = 1; r < rounds-1; r++) - { - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[r][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[r][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[r][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[r][3]); - - *((u32_a_t*)(b )) = (*((u32_a_t*)T1[u.temp[0][0]]) - ^ *((u32_a_t*)T2[u.temp[1][1]]) - ^ *((u32_a_t*)T3[u.temp[2][2]]) - ^ *((u32_a_t*)T4[u.temp[3][3]])); - *((u32_a_t*)(b + 4)) = (*((u32_a_t*)T1[u.temp[1][0]]) - ^ *((u32_a_t*)T2[u.temp[2][1]]) - ^ *((u32_a_t*)T3[u.temp[3][2]]) - ^ *((u32_a_t*)T4[u.temp[0][3]])); - *((u32_a_t*)(b + 8)) = (*((u32_a_t*)T1[u.temp[2][0]]) - ^ *((u32_a_t*)T2[u.temp[3][1]]) - ^ *((u32_a_t*)T3[u.temp[0][2]]) - ^ *((u32_a_t*)T4[u.temp[1][3]])); - *((u32_a_t*)(b +12)) = (*((u32_a_t*)T1[u.temp[3][0]]) - ^ *((u32_a_t*)T2[u.temp[0][1]]) - ^ *((u32_a_t*)T3[u.temp[1][2]]) - ^ *((u32_a_t*)T4[u.temp[2][3]])); - } - - /* Last round is special. */ - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[rounds-1][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[rounds-1][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[rounds-1][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)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_a_t*)(b )) ^= *((u32_a_t*)rk[rounds][0]); - *((u32_a_t*)(b+ 4)) ^= *((u32_a_t*)rk[rounds][1]); - *((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[rounds][2]); - *((u32_a_t*)(b+12)) ^= *((u32_a_t*)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 might - need to copy them here. We try to align to a 16 bytes. */ - if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f)) - { - union - { - u32 dummy[4]; - byte a[16] ATTR_ALIGNED_16; - } a; - union - { - u32 dummy[4]; - byte b[16] ATTR_ALIGNED_16; - } b; - - memcpy (a.a, ax, 16); - do_encrypt_aligned (ctx, b.b, a.a); - memcpy (bx, b.b, 16); - } - else - { - do_encrypt_aligned (ctx, bx, ax); - } -} - - -/* 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->padlockkey) - : "%ecx", "cc", "memory" - ); - - memcpy (bx, b, 16); - -} -#endif /*USE_PADLOCK*/ - - -#ifdef USE_AESNI -/* Encrypt one block using the Intel AES-NI instructions. A and B may - be the same; they need to be properly aligned to 16 bytes. - - Our problem here is that gcc does not allow the "x" constraint for - SSE registers in asm unless you compile with -msse. The common - wisdom is to use a separate file for SSE instructions and build it - separately. This would require a lot of extra build system stuff, - similar to what we do in mpi/ for the asm stuff. What we do - instead is to use standard registers and a bit more of plain asm - which copies the data and key stuff to the SSE registers and later - back. If we decide to implement some block modes with parallelized - AES instructions, it might indeed be better to use plain asm ala - mpi/. */ -static void -do_aesni_enc_aligned (const RIJNDAEL_context *ctx, - unsigned char *b, const unsigned char *a) -{ -#define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t" -#define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t" - /* Note: For now we relax the alignment requirement for A and B: It - does not make much difference because in many case we would need - to memcpy them to an extra buffer; using the movdqu is much faster - that memcpy and movdqa. For CFB we know that the IV is properly - aligned but that is a special case. We should better implement - CFB direct in asm. */ - asm volatile ("movdqu %[src], %%xmm0\n\t" /* xmm0 := *a */ - "movl %[key], %%esi\n\t" /* esi := keyschenc */ - "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */ - "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ - "movdqa 0x10(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x20(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x30(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x40(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x50(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x60(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x70(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x80(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x90(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xa0(%%esi), %%xmm1\n\t" - "cmp $10, %[rounds]\n\t" - "jz .Lenclast%=\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xb0(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xc0(%%esi), %%xmm1\n\t" - "cmp $12, %[rounds]\n\t" - "jz .Lenclast%=\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xd0(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xe0(%%esi), %%xmm1\n" - - ".Lenclast%=:\n\t" - aesenclast_xmm1_xmm0 - "movdqu %%xmm0, %[dst]\n" - : [dst] "=m" (*b) - : [src] "m" (*a), - [key] "r" (ctx->keyschenc), - [rounds] "r" (ctx->rounds) - : "%esi", "cc", "memory"); -#undef aesenc_xmm1_xmm0 -#undef aesenclast_xmm1_xmm0 -} - - -static void -do_aesni_dec_aligned (const RIJNDAEL_context *ctx, - unsigned char *b, const unsigned char *a) -{ -#define aesdec_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xde, 0xc1\n\t" -#define aesdeclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xc1\n\t" - asm volatile ("movdqu %[src], %%xmm0\n\t" /* xmm0 := *a */ - "movl %[key], %%esi\n\t" - "movdqa (%%esi), %%xmm1\n\t" - "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ - "movdqa 0x10(%%esi), %%xmm1\n\t" - aesdec_xmm1_xmm0 - "movdqa 0x20(%%esi), %%xmm1\n\t" - aesdec_xmm1_xmm0 - "movdqa 0x30(%%esi), %%xmm1\n\t" - aesdec_xmm1_xmm0 - "movdqa 0x40(%%esi), %%xmm1\n\t" - aesdec_xmm1_xmm0 - "movdqa 0x50(%%esi), %%xmm1\n\t" - aesdec_xmm1_xmm0 - "movdqa 0x60(%%esi), %%xmm1\n\t" - aesdec_xmm1_xmm0 - "movdqa 0x70(%%esi), %%xmm1\n\t" - aesdec_xmm1_xmm0 - "movdqa 0x80(%%esi), %%xmm1\n\t" - aesdec_xmm1_xmm0 - "movdqa 0x90(%%esi), %%xmm1\n\t" - aesdec_xmm1_xmm0 - "movdqa 0xa0(%%esi), %%xmm1\n\t" - "cmp $10, %[rounds]\n\t" - "jz .Ldeclast%=\n\t" - aesdec_xmm1_xmm0 - "movdqa 0xb0(%%esi), %%xmm1\n\t" - aesdec_xmm1_xmm0 - "movdqa 0xc0(%%esi), %%xmm1\n\t" - "cmp $12, %[rounds]\n\t" - "jz .Ldeclast%=\n\t" - aesdec_xmm1_xmm0 - "movdqa 0xd0(%%esi), %%xmm1\n\t" - aesdec_xmm1_xmm0 - "movdqa 0xe0(%%esi), %%xmm1\n" - - ".Ldeclast%=:\n\t" - aesdeclast_xmm1_xmm0 - "movdqu %%xmm0, %[dst]\n" - : [dst] "=m" (*b) - : [src] "m" (*a), - [key] "r" (ctx->keyschdec), - [rounds] "r" (ctx->rounds) - : "%esi", "cc", "memory"); -#undef aesdec_xmm1_xmm0 -#undef aesdeclast_xmm1_xmm0 -} - - -/* Perform a CFB encryption or decryption round using the - initialization vector IV and the input block A. Write the result - to the output block B and update IV. IV needs to be 16 byte - aligned. */ -static void -do_aesni_cfb (const RIJNDAEL_context *ctx, int decrypt_flag, - unsigned char *iv, unsigned char *b, const unsigned char *a) -{ -#define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t" -#define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t" - asm volatile ("movdqa %[iv], %%xmm0\n\t" /* xmm0 := IV */ - "movl %[key], %%esi\n\t" /* esi := keyschenc */ - "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */ - "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ - "movdqa 0x10(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x20(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x30(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x40(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x50(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x60(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x70(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x80(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x90(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xa0(%%esi), %%xmm1\n\t" - "cmp $10, %[rounds]\n\t" - "jz .Lenclast%=\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xb0(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xc0(%%esi), %%xmm1\n\t" - "cmp $12, %[rounds]\n\t" - "jz .Lenclast%=\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xd0(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xe0(%%esi), %%xmm1\n" - - ".Lenclast%=:\n\t" - aesenclast_xmm1_xmm0 - "movdqu %[src], %%xmm1\n\t" /* Save input. */ - "pxor %%xmm1, %%xmm0\n\t" /* xmm0 = input ^ IV */ - - "cmp $1, %[decrypt]\n\t" - "jz .Ldecrypt_%=\n\t" - "movdqa %%xmm0, %[iv]\n\t" /* [encrypt] Store IV. */ - "jmp .Lleave_%=\n" - ".Ldecrypt_%=:\n\t" - "movdqa %%xmm1, %[iv]\n" /* [decrypt] Store IV. */ - ".Lleave_%=:\n\t" - "movdqu %%xmm0, %[dst]\n" /* Store output. */ - : [iv] "+m" (*iv), [dst] "=m" (*b) - : [src] "m" (*a), - [key] "g" (ctx->keyschenc), - [rounds] "g" (ctx->rounds), - [decrypt] "m" (decrypt_flag) - : "%esi", "cc", "memory"); -#undef aesenc_xmm1_xmm0 -#undef aesenclast_xmm1_xmm0 -} - -/* Perform a CTR encryption round using the counter CTR and the input - block A. Write the result to the output block B and update CTR. - CTR needs to be a 16 byte aligned little-endian value. */ -static void -do_aesni_ctr (const RIJNDAEL_context *ctx, - unsigned char *ctr, unsigned char *b, const unsigned char *a) -{ -#define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t" -#define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t" - static unsigned char be_mask[16] __attribute__ ((aligned (16))) = - { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; - - asm volatile ("movdqa %[ctr], %%xmm0\n\t" /* xmm0, xmm2 := CTR */ - "movaps %%xmm0, %%xmm2\n\t" - "mov $1, %%esi\n\t" /* xmm2++ (big-endian) */ - "movd %%esi, %%xmm1\n\t" - "pshufb %[mask], %%xmm2\n\t" - "paddq %%xmm1, %%xmm2\n\t" - "pshufb %[mask], %%xmm2\n\t" - "movdqa %%xmm2, %[ctr]\n" /* Update CTR. */ - - "movl %[key], %%esi\n\t" /* esi := keyschenc */ - "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */ - "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ - "movdqa 0x10(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x20(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x30(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x40(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x50(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x60(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x70(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x80(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0x90(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xa0(%%esi), %%xmm1\n\t" - "cmp $10, %[rounds]\n\t" - "jz .Lenclast%=\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xb0(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xc0(%%esi), %%xmm1\n\t" - "cmp $12, %[rounds]\n\t" - "jz .Lenclast%=\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xd0(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - "movdqa 0xe0(%%esi), %%xmm1\n" - - ".Lenclast%=:\n\t" - aesenclast_xmm1_xmm0 - "movdqu %[src], %%xmm1\n\t" /* xmm1 := input */ - "pxor %%xmm1, %%xmm0\n\t" /* EncCTR ^= input */ - "movdqu %%xmm0, %[dst]" /* Store EncCTR. */ - - : [ctr] "+m" (*ctr), [dst] "=m" (*b) - : [src] "m" (*a), - [key] "g" (ctx->keyschenc), - [rounds] "g" (ctx->rounds), - [mask] "m" (*be_mask) - : "%esi", "cc", "memory"); -#undef aesenc_xmm1_xmm0 -#undef aesenclast_xmm1_xmm0 -} - - -/* Four blocks at a time variant of do_aesni_ctr. */ -static void -do_aesni_ctr_4 (const RIJNDAEL_context *ctx, - unsigned char *ctr, unsigned char *b, const unsigned char *a) -{ -#define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t" -#define aesenc_xmm1_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd1\n\t" -#define aesenc_xmm1_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd9\n\t" -#define aesenc_xmm1_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xe1\n\t" -#define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t" -#define aesenclast_xmm1_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd1\n\t" -#define aesenclast_xmm1_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd9\n\t" -#define aesenclast_xmm1_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe1\n\t" - - static unsigned char be_mask[16] __attribute__ ((aligned (16))) = - { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; - - /* Register usage: - esi keyschedule - xmm0 CTR-0 - xmm1 temp / round key - xmm2 CTR-1 - xmm3 CTR-2 - xmm4 CTR-3 - xmm5 temp - */ - - asm volatile ("movdqa %[ctr], %%xmm0\n\t" /* xmm0, xmm2 := CTR */ - "movaps %%xmm0, %%xmm2\n\t" - "mov $1, %%esi\n\t" /* xmm1 := 1 */ - "movd %%esi, %%xmm1\n\t" - "pshufb %[mask], %%xmm2\n\t" /* xmm2 := le(xmm2) */ - "paddq %%xmm1, %%xmm2\n\t" /* xmm2++ */ - "movaps %%xmm2, %%xmm3\n\t" /* xmm3 := xmm2 */ - "paddq %%xmm1, %%xmm3\n\t" /* xmm3++ */ - "movaps %%xmm3, %%xmm4\n\t" /* xmm4 := xmm3 */ - "paddq %%xmm1, %%xmm4\n\t" /* xmm4++ */ - "movaps %%xmm4, %%xmm5\n\t" /* xmm5 := xmm4 */ - "paddq %%xmm1, %%xmm5\n\t" /* xmm5++ */ - "pshufb %[mask], %%xmm2\n\t" /* xmm2 := be(xmm2) */ - "pshufb %[mask], %%xmm3\n\t" /* xmm3 := be(xmm3) */ - "pshufb %[mask], %%xmm4\n\t" /* xmm4 := be(xmm4) */ - "pshufb %[mask], %%xmm5\n\t" /* xmm5 := be(xmm5) */ - "movdqa %%xmm5, %[ctr]\n" /* Update CTR. */ - - "movl %[key], %%esi\n\t" /* esi := keyschenc */ - "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */ - "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */ - "pxor %%xmm1, %%xmm2\n\t" /* xmm2 ^= key[0] */ - "pxor %%xmm1, %%xmm3\n\t" /* xmm3 ^= key[0] */ - "pxor %%xmm1, %%xmm4\n\t" /* xmm4 ^= key[0] */ - "movdqa 0x10(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - aesenc_xmm1_xmm2 - aesenc_xmm1_xmm3 - aesenc_xmm1_xmm4 - "movdqa 0x20(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - aesenc_xmm1_xmm2 - aesenc_xmm1_xmm3 - aesenc_xmm1_xmm4 - "movdqa 0x30(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - aesenc_xmm1_xmm2 - aesenc_xmm1_xmm3 - aesenc_xmm1_xmm4 - "movdqa 0x40(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - aesenc_xmm1_xmm2 - aesenc_xmm1_xmm3 - aesenc_xmm1_xmm4 - "movdqa 0x50(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - aesenc_xmm1_xmm2 - aesenc_xmm1_xmm3 - aesenc_xmm1_xmm4 - "movdqa 0x60(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - aesenc_xmm1_xmm2 - aesenc_xmm1_xmm3 - aesenc_xmm1_xmm4 - "movdqa 0x70(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - aesenc_xmm1_xmm2 - aesenc_xmm1_xmm3 - aesenc_xmm1_xmm4 - "movdqa 0x80(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - aesenc_xmm1_xmm2 - aesenc_xmm1_xmm3 - aesenc_xmm1_xmm4 - "movdqa 0x90(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - aesenc_xmm1_xmm2 - aesenc_xmm1_xmm3 - aesenc_xmm1_xmm4 - "movdqa 0xa0(%%esi), %%xmm1\n\t" - "cmp $10, %[rounds]\n\t" - "jz .Lenclast%=\n\t" - aesenc_xmm1_xmm0 - aesenc_xmm1_xmm2 - aesenc_xmm1_xmm3 - aesenc_xmm1_xmm4 - "movdqa 0xb0(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - aesenc_xmm1_xmm2 - aesenc_xmm1_xmm3 - aesenc_xmm1_xmm4 - "movdqa 0xc0(%%esi), %%xmm1\n\t" - "cmp $12, %[rounds]\n\t" - "jz .Lenclast%=\n\t" - aesenc_xmm1_xmm0 - aesenc_xmm1_xmm2 - aesenc_xmm1_xmm3 - aesenc_xmm1_xmm4 - "movdqa 0xd0(%%esi), %%xmm1\n\t" - aesenc_xmm1_xmm0 - aesenc_xmm1_xmm2 - aesenc_xmm1_xmm3 - aesenc_xmm1_xmm4 - "movdqa 0xe0(%%esi), %%xmm1\n" - - ".Lenclast%=:\n\t" - aesenclast_xmm1_xmm0 - aesenclast_xmm1_xmm2 - aesenclast_xmm1_xmm3 - aesenclast_xmm1_xmm4 - - "movdqu %[src], %%xmm1\n\t" /* Get block 1. */ - "pxor %%xmm1, %%xmm0\n\t" /* EncCTR-1 ^= input */ - "movdqu %%xmm0, %[dst]\n\t" /* Store block 1 */ - - "movdqu (16)%[src], %%xmm1\n\t" /* Get block 2. */ - "pxor %%xmm1, %%xmm2\n\t" /* EncCTR-2 ^= input */ - "movdqu %%xmm2, (16)%[dst]\n\t" /* Store block 2. */ - - "movdqu (32)%[src], %%xmm1\n\t" /* Get block 3. */ - "pxor %%xmm1, %%xmm3\n\t" /* EncCTR-3 ^= input */ - "movdqu %%xmm3, (32)%[dst]\n\t" /* Store block 3. */ - - "movdqu (48)%[src], %%xmm1\n\t" /* Get block 4. */ - "pxor %%xmm1, %%xmm4\n\t" /* EncCTR-4 ^= input */ - "movdqu %%xmm4, (48)%[dst]" /* Store block 4. */ - - : [ctr] "+m" (*ctr), [dst] "=m" (*b) - : [src] "m" (*a), - [key] "g" (ctx->keyschenc), - [rounds] "g" (ctx->rounds), - [mask] "m" (*be_mask) - : "%esi", "cc", "memory"); -#undef aesenc_xmm1_xmm0 -#undef aesenc_xmm1_xmm2 -#undef aesenc_xmm1_xmm3 -#undef aesenc_xmm1_xmm4 -#undef aesenclast_xmm1_xmm0 -#undef aesenclast_xmm1_xmm2 -#undef aesenclast_xmm1_xmm3 -#undef aesenclast_xmm1_xmm4 -} - - -static void -do_aesni (RIJNDAEL_context *ctx, int decrypt_flag, - unsigned char *bx, const unsigned char *ax) -{ - - if (decrypt_flag) - { - if (!ctx->decryption_prepared ) - { - prepare_decryption ( ctx ); - ctx->decryption_prepared = 1; - } - do_aesni_dec_aligned (ctx, bx, ax); - } - else - do_aesni_enc_aligned (ctx, bx, ax); -} -#endif /*USE_AESNI*/ - - -static void -rijndael_encrypt (void *context, byte *b, const byte *a) -{ - RIJNDAEL_context *ctx = context; - - if (0) - ; -#ifdef USE_PADLOCK - else if (ctx->use_padlock) - { - do_padlock (ctx, 0, b, a); - _gcry_burn_stack (48 + 15 /* possible padding for alignment */); - } -#endif /*USE_PADLOCK*/ -#ifdef USE_AESNI - else if (ctx->use_aesni) - { - aesni_prepare (); - do_aesni (ctx, 0, b, a); - aesni_cleanup (); - } -#endif /*USE_AESNI*/ - else - { - do_encrypt (ctx, b, a); - _gcry_burn_stack (56 + 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; - - if (0) - ; -#ifdef USE_PADLOCK - else 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++); - } - } -#endif /*USE_PADLOCK*/ -#ifdef USE_AESNI - else if (ctx->use_aesni) - { - aesni_prepare (); - for ( ;nblocks; nblocks-- ) - { - do_aesni_cfb (ctx, 0, iv, outbuf, inbuf); - outbuf += BLOCKSIZE; - inbuf += BLOCKSIZE; - } - aesni_cleanup (); - } -#endif /*USE_AESNI*/ - else - { - 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; - -#ifdef USE_AESNI - if (ctx->use_aesni) - aesni_prepare (); -#endif /*USE_AESNI*/ - - for ( ;nblocks; nblocks-- ) - { - for (ivp=iv, i=0; i < BLOCKSIZE; i++ ) - outbuf[i] = inbuf[i] ^ *ivp++; - - if (0) - ; -#ifdef USE_PADLOCK - else if (ctx->use_padlock) - do_padlock (ctx, 0, outbuf, outbuf); -#endif /*USE_PADLOCK*/ -#ifdef USE_AESNI - else if (ctx->use_aesni) - do_aesni (ctx, 0, outbuf, outbuf); -#endif /*USE_AESNI*/ - else - do_encrypt (ctx, outbuf, outbuf ); - - memcpy (iv, outbuf, BLOCKSIZE); - inbuf += BLOCKSIZE; - if (!cbc_mac) - outbuf += BLOCKSIZE; - } - -#ifdef USE_AESNI - if (ctx->use_aesni) - aesni_cleanup (); -#endif /*USE_AESNI*/ - - _gcry_burn_stack (48 + 2*sizeof(int)); -} - - -/* Bulk encryption of complete blocks in CTR mode. Caller needs to - make sure that CTR is aligned on a 16 byte boundary if AESNI; the - minimum alignment is for an u32. This function is only intended - for the bulk encryption feature of cipher.c. CTR is expected to be - of size BLOCKSIZE. */ -void -_gcry_aes_ctr_enc (void *context, unsigned char *ctr, - 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 *p; - int i; - - if (0) - ; -#ifdef USE_AESNI - else if (ctx->use_aesni) - { - aesni_prepare (); - for ( ;nblocks > 3 ; nblocks -= 4 ) - { - do_aesni_ctr_4 (ctx, ctr, outbuf, inbuf); - outbuf += 4*BLOCKSIZE; - inbuf += 4*BLOCKSIZE; - } - for ( ;nblocks; nblocks-- ) - { - do_aesni_ctr (ctx, ctr, outbuf, inbuf); - outbuf += BLOCKSIZE; - inbuf += BLOCKSIZE; - } - aesni_cleanup (); - aesni_cleanup_2_4 (); - } -#endif /*USE_AESNI*/ - else - { - union { unsigned char x1[16]; u32 x32[4]; } tmp; - - for ( ;nblocks; nblocks-- ) - { - /* Encrypt the counter. */ - do_encrypt_aligned (ctx, tmp.x1, ctr); - /* XOR the input with the encrypted counter and store in output. */ - for (p=tmp.x1, i=0; i < BLOCKSIZE; i++) - *outbuf++ = (*p++ ^= *inbuf++); - /* Increment the counter. */ - for (i = BLOCKSIZE; i > 0; i--) - { - ctr[i-1]++; - if (ctr[i-1]) - break; - } - } - } - - _gcry_burn_stack (48 + 2*sizeof(int)); -} - - - -/* 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->keyschdec) - int rounds = ctx->rounds; - int r; - union - { - u32 tempu32[4]; /* Force correct alignment. */ - byte temp[4][4]; - } u; - - - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(a )) ^ *((u32_a_t*)rk[rounds][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(a+ 4)) ^ *((u32_a_t*)rk[rounds][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(a+ 8)) ^ *((u32_a_t*)rk[rounds][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(a+12)) ^ *((u32_a_t*)rk[rounds][3]); - - *((u32_a_t*)(b )) = (*((u32_a_t*)T5[u.temp[0][0]]) - ^ *((u32_a_t*)T6[u.temp[3][1]]) - ^ *((u32_a_t*)T7[u.temp[2][2]]) - ^ *((u32_a_t*)T8[u.temp[1][3]])); - *((u32_a_t*)(b+ 4)) = (*((u32_a_t*)T5[u.temp[1][0]]) - ^ *((u32_a_t*)T6[u.temp[0][1]]) - ^ *((u32_a_t*)T7[u.temp[3][2]]) - ^ *((u32_a_t*)T8[u.temp[2][3]])); - *((u32_a_t*)(b+ 8)) = (*((u32_a_t*)T5[u.temp[2][0]]) - ^ *((u32_a_t*)T6[u.temp[1][1]]) - ^ *((u32_a_t*)T7[u.temp[0][2]]) - ^ *((u32_a_t*)T8[u.temp[3][3]])); - *((u32_a_t*)(b+12)) = (*((u32_a_t*)T5[u.temp[3][0]]) - ^ *((u32_a_t*)T6[u.temp[2][1]]) - ^ *((u32_a_t*)T7[u.temp[1][2]]) - ^ *((u32_a_t*)T8[u.temp[0][3]])); - - for (r = rounds-1; r > 1; r--) - { - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[r][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[r][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[r][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[r][3]); - *((u32_a_t*)(b )) = (*((u32_a_t*)T5[u.temp[0][0]]) - ^ *((u32_a_t*)T6[u.temp[3][1]]) - ^ *((u32_a_t*)T7[u.temp[2][2]]) - ^ *((u32_a_t*)T8[u.temp[1][3]])); - *((u32_a_t*)(b+ 4)) = (*((u32_a_t*)T5[u.temp[1][0]]) - ^ *((u32_a_t*)T6[u.temp[0][1]]) - ^ *((u32_a_t*)T7[u.temp[3][2]]) - ^ *((u32_a_t*)T8[u.temp[2][3]])); - *((u32_a_t*)(b+ 8)) = (*((u32_a_t*)T5[u.temp[2][0]]) - ^ *((u32_a_t*)T6[u.temp[1][1]]) - ^ *((u32_a_t*)T7[u.temp[0][2]]) - ^ *((u32_a_t*)T8[u.temp[3][3]])); - *((u32_a_t*)(b+12)) = (*((u32_a_t*)T5[u.temp[3][0]]) - ^ *((u32_a_t*)T6[u.temp[2][1]]) - ^ *((u32_a_t*)T7[u.temp[1][2]]) - ^ *((u32_a_t*)T8[u.temp[0][3]])); - } - - /* Last round is special. */ - *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[1][0]); - *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[1][1]); - *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[1][2]); - *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)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_a_t*)(b )) ^= *((u32_a_t*)rk[0][0]); - *((u32_a_t*)(b+ 4)) ^= *((u32_a_t*)rk[0][1]); - *((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[0][2]); - *((u32_a_t*)(b+12)) ^= *((u32_a_t*)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) -{ - if ( !ctx->decryption_prepared ) - { - prepare_decryption ( ctx ); - _gcry_burn_stack (64); - ctx->decryption_prepared = 1; - } - - /* BX and AX are not necessary correctly aligned. Thus we might - need to copy them here. We try to align to a 16 bytes. */ - if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f)) - { - union - { - u32 dummy[4]; - byte a[16] ATTR_ALIGNED_16; - } a; - union - { - u32 dummy[4]; - byte b[16] ATTR_ALIGNED_16; - } b; - - memcpy (a.a, ax, 16); - do_decrypt_aligned (ctx, b.b, a.a); - memcpy (bx, b.b, 16); - } - else - { - do_decrypt_aligned (ctx, bx, ax); - } -} - - - - -static void -rijndael_decrypt (void *context, byte *b, const byte *a) -{ - RIJNDAEL_context *ctx = context; - - if (0) - ; -#ifdef USE_PADLOCK - else if (ctx->use_padlock) - { - do_padlock (ctx, 1, b, a); - _gcry_burn_stack (48 + 2*sizeof(int) /* FIXME */); - } -#endif /*USE_PADLOCK*/ -#ifdef USE_AESNI - else if (ctx->use_aesni) - { - aesni_prepare (); - do_aesni (ctx, 1, b, a); - aesni_cleanup (); - } -#endif /*USE_AESNI*/ - else - { - do_decrypt (ctx, b, a); - _gcry_burn_stack (56+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; - - if (0) - ; -#ifdef USE_PADLOCK - else 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; - } - } - } -#endif /*USE_PADLOCK*/ -#ifdef USE_AESNI - else if (ctx->use_aesni) - { - aesni_prepare (); - for ( ;nblocks; nblocks-- ) - { - do_aesni_cfb (ctx, 1, iv, outbuf, inbuf); - outbuf += BLOCKSIZE; - inbuf += BLOCKSIZE; - } - aesni_cleanup (); - } -#endif /*USE_AESNI*/ - else - { - 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]; - -#ifdef USE_AESNI - if (ctx->use_aesni) - aesni_prepare (); -#endif /*USE_AESNI*/ - - for ( ;nblocks; nblocks-- ) - { - /* We need to save INBUF away because it may be identical to - OUTBUF. */ - memcpy (savebuf, inbuf, BLOCKSIZE); - - if (0) - ; -#ifdef USE_PADLOCK - else if (ctx->use_padlock) - do_padlock (ctx, 1, outbuf, inbuf); -#endif /*USE_PADLOCK*/ -#ifdef USE_AESNI - else if (ctx->use_aesni) - do_aesni (ctx, 1, outbuf, inbuf); -#endif /*USE_AESNI*/ - else - do_decrypt (ctx, outbuf, inbuf); - - for (ivp=iv, i=0; i < BLOCKSIZE; i++ ) - outbuf[i] ^= *ivp++; - memcpy (iv, savebuf, BLOCKSIZE); - inbuf += BLOCKSIZE; - outbuf += BLOCKSIZE; - } - -#ifdef USE_AESNI - if (ctx->use_aesni) - aesni_cleanup (); -#endif /*USE_AESNI*/ - - _gcry_burn_stack (48 + 2*sizeof(int) + BLOCKSIZE + 4*sizeof (char*)); -} - - - - -/* 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) */ -#if 1 - 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 - }; -#else - /* Test vectors from fips-197, appendix C. */ -# warning debug test vectors in use - static const unsigned char plaintext_128[16] = - { - 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77, - 0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff - }; - static const unsigned char key_128[16] = - { - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f - /* 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, */ - /* 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c */ - }; - static const unsigned char ciphertext_128[16] = - { - 0x69,0xc4,0xe0,0xd8,0x6a,0x7b,0x04,0x30, - 0xd8,0xcd,0xb7,0x80,0x70,0xb4,0xc5,0x5a - }; -#endif - - 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; -} - - - - -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/test-getrusage.c b/grub-core/lib/libgcrypt/cipher/test-getrusage.c deleted file mode 100644 index 978cf2de9..000000000 --- a/grub-core/lib/libgcrypt/cipher/test-getrusage.c +++ /dev/null @@ -1,105 +0,0 @@ -#include -#include -#include - -int -main (int argc, char **argv) -{ - struct rusage buf; - - if (argc > 1) - { - system (argv[1]); - - if (getrusage (RUSAGE_CHILDREN, &buf )) - { - perror ("getrusage"); - return 1; - } - } - else - { - if (getrusage (RUSAGE_SELF, &buf )) - { - perror ("getrusage"); - return 1; - } - } - - printf ("ru_utime = %ld.%06ld\n", - buf.ru_utime.tv_sec, buf.ru_utime.tv_usec); - printf ("ru_stime = %ld.%06ld\n", - buf.ru_stime.tv_sec, buf.ru_stime.tv_usec); - printf ("ru_maxrss = %ld\n", buf.ru_maxrss ); - printf ("ru_ixrss = %ld\n", buf.ru_ixrss ); - printf ("ru_idrss = %ld\n", buf.ru_idrss ); - printf ("ru_isrss = %ld\n", buf.ru_isrss ); - printf ("ru_minflt = %ld\n", buf.ru_minflt ); - printf ("ru_majflt = %ld\n", buf.ru_majflt ); - printf ("ru_nswap = %ld\n", buf.ru_nswap ); - printf ("ru_inblock = %ld\n", buf.ru_inblock ); - printf ("ru_oublock = %ld\n", buf.ru_oublock ); - printf ("ru_msgsnd = %ld\n", buf.ru_msgsnd ); - printf ("ru_msgrcv = %ld\n", buf.ru_msgrcv ); - printf ("ru_nsignals= %ld\n", buf.ru_nsignals ); - printf ("ru_nvcsw = %ld\n", buf.ru_nvcsw ); - printf ("ru_nivcsw = %ld\n", buf.ru_nivcsw ); - - fprintf (stderr, "ru_utime ru_stime ru_minflt ru_nccsw ru_nivcsw\n"); - fprintf (stderr, "%ld.%06ld %ld.%06ld %5ld %5ld %5ld\n"); - - - return 0; -} - - -/* Codesnippet for debugging in random.c. */ -#if 0 -static void -collect_rusage_stats (struct rusage *rb) -{ - static int idx; - static struct rusage buf[100]; - - if (!rb) - { - int i; - - fprintf (stderr, "ru_utime ru_stime ru_minflt ru_nvcsw ru_nivcsw\n"); - for (i=0; i < idx; i++) - fprintf (stderr, "%ld.%06ld %ld.%06ld %5ld %5ld %5ld\n", - buf[i].ru_utime.tv_sec, buf[i].ru_utime.tv_usec, - buf[i].ru_stime.tv_sec, buf[i].ru_stime.tv_usec, - buf[i].ru_minflt, - buf[i].ru_nvcsw, - buf[i].ru_nivcsw); - } - else if (idx < DIM(buf)) - { - buf[idx++] = *rb; - } -} -#endif -/* - void - _gcry_random_dump_stats() - { -@@ -233,8 +261,11 @@ - rndstats.naddbytes, rndstats.addbytes, - rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1, - rndstats.ngetbytes2, rndstats.getbytes2 ); -+ -+ collect_rusage_stats (NULL); - } - -======== - - getrusage (RUSAGE_SELF, &buf ); -+ collect_rusage_stats (&buf); - add_randomness( &buf, sizeof buf, 1 ); - memset( &buf, 0, sizeof buf ); - } - -*/ - - diff --git a/grub-core/lib/libgcrypt/mpi/ChangeLog-2011 b/grub-core/lib/libgcrypt/mpi/ChangeLog-2011 deleted file mode 100644 index 930717141..000000000 --- a/grub-core/lib/libgcrypt/mpi/ChangeLog-2011 +++ /dev/null @@ -1,822 +0,0 @@ -2011-12-01 Werner Koch - - NB: ChangeLog files are no longer manually maintained. Starting - on December 1st, 2011 we put change information only in the GIT - commit log, and generate a top-level ChangeLog file from logs at - "make dist". See doc/HACKING for details. - -2011-03-28 Werner Koch - - * mpi-pow.c (gcry_mpi_powm): Remove unused var RSEC. - -2011-02-01 Werner Koch - - * mpi-cmp.c (gcry_mpi_cmp): Allow comparing of opaque MPIs. - -2010-04-12 Brad Hards (wk) - - Spelling fixes. - -2010-02-22 Aurelien Jarno (wk) - - * longlong.h (umul_ppmm) [__GNUC__ >= 4.4]: Patch according - to recommended gcc 4.4 changes. - -2009-12-09 Werner Koch - - * config.links: Remove asm modules for all sparc64. This is - debian#560028. - -2009-05-26 Werner Koch - - * mpicoder.c (mpi_read_from_buffer): Allow zero-sized MPIs (i.e a - zero). - -2009-02-16 Werner Koch - - * mpiutil.c: Remove memory.h. - -2008-12-05 Werner Koch - - * mpicoder.c (mpi_read_from_buffer): Do not bail out if the mpi is - larger than the buffer (potential problem). Do not print error - messages. - (mpi_fromstr): Return an error instead of hitting an assert. - (gcry_mpi_scan) : Fix potential double free problem. - (gcry_mpi_scan) : Fix potential memory leak. - (do_get_buffer): Return NULL on memory allocation failure. - (gcry_mpi_print): Check result of do_get_buffer. - (gcry_mpi_aprint): Return error on a memory allocation failure. - - * mpicoder.c: Re-indent. - -2008-12-03 Werner Koch - - * mpi-pow.c (gcry_mpi_powm): Fix last change. Asserts are really - useful! - -2008-12-02 Werner Koch - - * mpi-pow.c (gcry_mpi_powm): Re-indent. - (gcry_mpi_powm): Simplified allocation of the result to fix a - double free bug. This is bug#977. Reported by Haakon Ringberg. - -2008-08-20 Werner Koch - - * mpi-bit.c (gcry_mpi_lshift): Actually implement. - -2008-08-19 Werner Koch - - * mpi-bit.c (gcry_mpi_lshift): New. - -2007-10-31 Werner Koch - - * mpi-mod.c (gcry_mpi_mod): Remove - * mpi-inv.c (_gcry_mpi_invm): Remove _ prefix. - * mpiutil.c (_gcry_mpi_swap): Remove. - (_gcry_mpi_new): Remove. - (_gcry_mpi_snew): Remove. - (gcry_mpi_invm): Remove. - (gcry_mpi_copy): Remove and rename _version to this. - (gcry_mpi_set, gcry_mpi_set_ui): Merge with _ version. - * mpi-inv.c (gcry_mpi_invm): Remove _ prefix and return 1. - * mpi-mul.c (gcry_mpi_mul_2exp): Remove and rename _ version to this. - -2007-10-29 Werner Koch - - * config.links: No Candadian Cross here, thus use $host instead of - $target. - -2007-10-26 Werner Koch - - * config.links (mpi_optional_modules): Special rules for Apple - Darwin on ia32 from Gregor Riepl. - -2007-05-09 Marcus Brinkmann - - * config.links: Rename assembler file links by suffixing "-asm". - * Makefile.am (CCASCOMPILE, LTCCASCOMPILE, CLEANFILES, - libmpi_la_LIBADD, libmpi_la_DEPENDENCIES, SUFFIXES, .S.o, .S.obj, - .S.lo): Removed variables and targets. - (mpih_add1, mpih_sub1, mpih_mul1, mpih_mul2, mpih_mul3, - mpih_lshift, mpih_rshift, mpih_udiv, mpih_udiv_qrnnd, - nodist_libmpi_la_SOURCES): New variables. - (DISTCLEANFILES): Rename assembler file links by suffixing "-asm". - Add variants for C file links. - -2007-05-04 Werner Koch - - * config.links (path): Allowthe sue of colons as delimiters. - -2007-05-03 Werner Koch - - * pentium4/distfiles: Fixed. - -2007-04-30 Werner Koch - - * config.links: Create a file mod-source-info.h. - * Makefile.am (DISTCLEANFILES): Add that file. - * mpiutil.c (_gcry_mpi_get_hw_config): New. - -2007-04-28 Marcus Brinkmann - - * config.links: Add additional assembler search directories. - -2007-03-28 Werner Koch - - * ec.c: New. - -2007-03-23 Werner Koch - - * mpi-bit.c (_gcry_mpi_lshift_limbs): Assign AP after the resize. - - * mpi-div.c (gcry_mpi_mod, _gcry_mpi_mod): Moved to .. - * mpi-mod.c: .. new file. - (_gcry_mpi_barrett_init, _gcry_mpi_barrett_free): New. - (_gcry_mpi_mod_barrett): New. - (_gcry_mpi_mul_barrett): New. - -2007-03-22 Werner Koch - - * mpi-div.c (_gcry_mpi_mod): New. - * mpiutil.c (_gcry_mpi_new, _gcry_mpi_snew): New. - -2007-03-13 Werner Dittmann (wk) - - * amd64/mpih-add1.S, amd64/mpih-add1.S, amd64/mpih-lshift.S - * amd64/mpih-mul1.S, amd64/mpih-mul2.S, amd64/mpih-mul3.S - * amd64/mpih-rshift.S, amd64/mpih-sub1.S: New. - * config.links: Add case for x86_64. - -2007-02-23 Werner Koch - - * mpi-pow.c (gcry_mpi_powm): Remove unused var ESIGN. - - * mpiutil.c (gcry_mpi_get_flag): Let it return a value to silent - MIPSpro cc warning. - -2007-02-21 Werner Koch - - * mpicoder.c (_gcry_mpi_set_buffer): Made BUFFER a void*. - -2006-11-15 Werner Koch - - * Makefile.am (.S.o): Check for srcdir also in in CPP pass. - (INCLUDES): Removed. - (AM_CPPFLAGS, AM_CFLAGS): New, modified. Merged with Moritz' - changes. - -2006-11-05 Moritz Schulte - - * 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-23 Werner Koch - - * config.links (mpi_optional_modules): Make sure that powerpc64 is - matched before a generic powerpc. Reported by Andreas Metzler. - Should fix Debian bug 284609. - -2006-08-25 Werner Koch - - * mpi-bit.c (gcry_mpi_rshift): Don't shift if N == 0 but do a - plain copy. - -2006-08-04 Werner Koch - - * mpi-bit.c (gcry_mpi_rshift): Rewritten to remove the limitation - on N (which used to be less than BITS_PER_MPI_LIMB). - -2006-08-03 Werner Koch - - * mpi-bit.c (gcry_mpi_set_bit, gcry_mpi_set_highbit): Fixed - allocation. Reported by bpgcrypt at itaparica.org. - * mpiutil.c (_gcry_mpi_resize): Clear the new part of the resized - limb space. - -2006-07-26 Werner Koch - - * mpiutil.c (gcry_mpi_randomize): Changed P to unsigned char*. - - * mpicoder.c (gcry_mpi_scan): Changed arg BUFFER to void*. - (mpi_read_from_buffer): Made BUFFER arg const. - (gcry_mpi_scan): Removed now needless cast. Add cast for arg to - mpi_fromstr. - (gcry_mpi_print): Made TMP unsigned. - - * Makefile.am (AM_CCASFLAGS): New. - -2005-10-09 Moritz Schulte - - * mpi-cmp.c (gcry_mpi_cmp_ui): Rewritten; correctly handle case of - zero limbs in U. - -2005-04-27 Moritz Schulte - - * mpiutil.c (gcry_mpi_randomize): Store random data in secure - memory if the given MPI is secure - not the other way around (argl). - -2005-04-23 Moritz Schulte - - * Makefile.am: Don't assume the compiler will pre-process the .S - files. Some compilers, like those from HP and IBM, don't do - this. So, we use the same solution gnupg-1.4.0 does. Preprocess - first and then compile. - - * hppa1.1/mpih-mul3.S: Add "level 1.1" directive to disable - warning about using PA-RISC1.1 opcodes. - * hppa1.1/mpih-mul2.S: Likewise. - * hppa1.1/mpih-mul1.S: Likewise. - * hppa1.1/udiv-qrnnd.S: Likewise. - -2005-02-16 Moritz Schulte - - * mpiutil.c (_gcry_mpi_alloc_limb_space): Rewritten, fixed memory - corruption. - -2005-02-06 Moritz Schulte - - * mpiutil.c (_gcry_mpi_get_ui, gcry_mpi_get_ui): New functions. - -2005-01-05 Werner Koch - - * hppa1.1/udiv-qrnnd.S: Reverted change of 2004-03-02 but kept the - .align directive. - -2004-12-16 Werner Koch - - * config.links (mpi_optional_modules): Move entry for powerpc64 - before generic powerpc. Suggested by Rafael Ăvila de EspĂ­ndola. - -2004-03-02 Werner Koch - - * hppa1.1/udiv-qrnnd.S: Alignment fix from Lamont Jones for - Debian. Taken from gnupg-1.3. - - * longlong.h: Added PowerPC 64 bit code from GPM-4.1.2 but didn't - enable it yet. Some whitespace changes in HPPA to fix assembler - problems on HP-UX. From gnupg 1.3 - - * mpiutil.c (_gcry_mpi_alloc_limb_space): Better allocate - something even if NLIMBS is passed as 0. - - * config.links: Updated system list to match gnupg 1.3. - -2003-12-19 Werner Koch - - * mpi-internal.h [M_DEBUG]: Removed this unused code. - (struct karatsuba_ctx): Added TSPACE_NLIMBS and TP_NLIMBS. - * mpiutil.c (_gcry_mpi_free_limb_space): Add arg NLIMBS and wipe - out the memory. Changed all callers. - * mpih-mul.c (_gcry_mpih_mul_karatsuba_case): Keep track of - allocated limbs. - * mpi-div.c (_gcry_mpi_tdiv_qr): Keep track of allocated limbs. - * mpi-mul.c (gcry_mpi_mul): Ditto. - * mpi-pow.c (gcry_mpi_powm): Ditto. - - * Manifest: Empty new file. Also add Manifest files to all CPU - specific directories. - * Makefile.am: Added. - - * mpiutil.c (gcry_mpi_randomize): Use gcry_create_nonce if WEAK - random has been requested. - -2003-10-31 Werner Koch - - * i386/mpih-rshift.S, i386/mpih-lshift.S: Use %dl and not %edx for - testb; this avoids an assembler warning. - - * mpi-pow.c (gcry_mpi_powm): s/exp/expo/ to avoid shadowing warning. - -2003-08-19 Marcus Brinkmann - - * Makefile.am (SUFFIXES): New variable. - (.S.o, .S.lo, .S.obj): Rewritten. - -2003-07-30 Moritz Schulte - - * longlong.h (__clz_tab): Renamed to _gcry_clz_tab. - * mpi-bit.c (__clz_tab): Likewise. - -2003-07-27 Werner Koch - - * mpicoder.c (gcry_mpi_scan): New argument BUFLEN to replace the - use of the intial value of NBYTES. Changed BUFFER to unsigned. - (gcry_mpi_print): Likewise. - (gcry_mpi_dump): New. - (_gcry_log_mpidump): Make use of gcry_mpi_dump. - (mpi_print): Removed. - (gcry_mpi_scan): Allocated mpi in secure memory when required. - (gcry_mpi_aprint): Changed BUFFER to unsigned char*. - -2003-07-14 Moritz Schulte - - * mpicoder.c: Used gcry_err* wrappers for libgpg-error symbols. - -2003-06-16 Moritz Schulte - - * mpi-add.c: Replace last occurences of old type names with newer - names (i.e. replace MPI with gcry_mpi_t). - * mpi-bit.c: Likewise. - * mpi-cmp.c: Likewise. - * mpi-div.c: Likewise. - * mpi-gcd.c: Likewise. - * mpi-internal.h: Likewise. - * mpi-inv.c: Likewise. - * mpi-mpow.c: Likewise. - * mpi-mul.c: Likewise. - * mpi-pow.c: Likewise. - * mpi-scan.c: Likewise. - * mpicoder.c: Likewise. - * mpiutil.c: Likewise. - -2003-06-09 Moritz Schulte - - * mpicoder.c (gcry_mpi_scan): Adjust for libgpg-error. - (gcry_mpi_print): Likewise. - (gcry_mpi_aprint): Likewise. - -2003-06-07 Moritz Schulte - - * longlong.h, mpi-add.c, mpi-bit.c, mpi-cmp.c, mpi-div.c, - mpi-gcd.c, mpi-inline.c, mpi-inline.h, mpi-internal.h, mpi-inv.c, - mpi-mpow.c, mpi-mul.c, mpi-pow.c, mpi-scan.c, mpicoder.c, - mpih-div.c, mpih-mul.c, mpiutil.c, generic/mpi-asm-defs.h, - generic/mpih-add1.c, generic/mpih-lshift.c, generic/mpih-mul1.c, - generic/mpih-mul2.c, generic/mpih-mul3.c, generic/mpih-rshift.c, - generic/mpih-sub1.c, generic/udiv-w-sdiv.c, i386/syntax.h, - m68k/syntax.h, mips3/mpi-asm-defs.h, powerpc32/syntax.h: 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-05-21 Moritz Schulte - - * mpiutil.c (_gcry_mpi_alloc_limb_space): Only try to allocate - memory in case the amount of bytes to allocate is non-zero. - -2003-04-27 Moritz Schulte - - * mpiutil.c (_gcry_mpi_resize): Allocate secure memory, in case - bit zero of `flags' is set. - - * mpi-add.c (gcry_mpi_sub): Simplify function; always use a - temporary variable now. - -2003-04-15 Werner Koch - - * longlong.h (umul_ppmm): Support SH3 and SH4. Thanks to - kazuya.s@jp.yokogawa.com. - -2003-04-02 Werner Koch - - * mpicoder.c (gcry_mpi_print): Fixed testing against possible - uninitialized LEN. Valgrinded by Nikos Mavroyanopoulos. - -2003-01-15 Werner Koch - - * longlong.h: Removed some spaces between backslashes and newlines. - -2002-09-20 Werner Koch - - * mpi-mul.c (gcry_mpi_mul_2exp): New. This was declared in - gcrypt.h but only implemented as internal function. Noted by Timo - but a few minutes to late for today's release. - - * Makefile.am (DISTCLEANFILES): Include mpi-asm-defs.h - -2002-09-18 Werner Koch - - * Makefile.am (.S.lo): Pass -DPIC. i386, PPC and Sparc code - require it. It worked for me because I am using the i586 code. - -2002-08-23 Werner Koch - - * Makefile.am (.S.lo): Fixed for libtool build with --disable-shared. - -2002-07-24 Werner Koch - - * longlong.h: Replaced all K&R multiline strings by ISO ones for - the sake of modern compilers. Suggested by Marco Parrone. - -2002-06-24 Werner Koch - - * mpiutil.c (gcry_mpi_swap): New. - - * mpi-div.c (gcry_mpi_div): New. - (gcry_mpi_mod): New. - * mpi-inv.c (gcry_mpi_invm): New. - - * mpicoder.c (do_get_buffer): Make sure that we allocate at least - one byte. - -2002-06-12 Werner Koch - - * hppa1.1/udiv-qrnnd.S: Changes for PIC by Randolph Chung. - -2002-05-15 Werner Koch - - * config.links: Chnage the way the mpi modules are determined. - * Makefile.am: Revamped to better handle modules - -2002-05-14 Werner Koch - - Changed license of all files to the LGPL. - -2002-04-18 Werner Koch - - * mpicoder.c (gcry_mpi_scan): Don't use normalize on a NULL MPI. - -2002-03-20 Werner Koch - - * mpicoder.c (mpi_read_from_buffer): Bail out on a zero length - buffer because we can't eventually do an malloc of this size. - Reported by Timo. - -2002-01-14 Werner Koch - - * mpi-inv.c (_gcry_mpi_invm): Typo fixes, noted by Carlo Perassi. - -2001-11-01 Werner Koch - - * mpicoder.c (gcry_mpi_scan): Allow to pass a nbytes as NULL or - with value 0 for format GCRY_FMT_SSH, so that the length is not - used for any checks, only the length stored in the bufer is used. - This is a nice format becuase we can just pass a buffer around and - don't need to care about its length. - -2001-08-03 Werner Koch - - * config.links: Changed the way the list of files to be - symlinked is returned. - -2001-05-31 Werner Koch - - * mpih-cmp.c: Removed and moved mpihelp_cmp to .. - * mpi-inline.h: .. here. - - Major function renaming. All global functions are now prefixed - with _gcry_ or gcry_. Renamed also all mpihelp_ to just mpih_ so - that functions names are not getting to long an unreadable and for - better matching with the filenames. - -2001-05-28 Werner Koch - - * mpicoder.c (mpi_fromstr): Made static and assume that all input - is in hexformat. - - Updated all CPU specific code with the one from GnuPG-1.0.5. This - is just a change of text formatting and the use of .label - instead of labels for hppa and pa7100. - - * longlong.h: Fixes for ARM by Phil Blundell. - -2001-03-29 Werner Koch - - * mpi-mul.c (mpi_mul): Make sure that secret temporary results are - not stored in w. Suggested by Florian Weimer. - - * config.links: Use i386 code for i386. According to tests by - Kevin Ryde the i586 code runs slow on i386 CPUs. Ditto for i786. - -2001-01-11 Werner Koch - - * Makefile.am: Removed mpi.h. - -2000-12-19 Werner Koch - - * mpi-internal.h: Put limb_t definition in an ifdef. - - Major change: - Removed all GnuPG stuff and renamed this piece of software - to gcrypt. - -2000-11-14 Werner Koch - - * mpi-internal.h, mpi.h: Changed the way they are called and - introduced DID_MPI_LIMP_TYPEDEF hack. Very ugly, should all be - revamped. - - * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency - problems. - -2000-10-11 Werner Koch - - * generic/mpi-asm-defs.h: New. - * mips3/mpi-asm-defs.h: New. - * config.links: Create a link to one of the above files. - -Fri Jul 28 18:19:11 CEST 2000 Werner Koch - - * mpicoder.c (gcry_mpi_scan): Normalize the returned MPI. - -Tue Jul 25 17:44:15 CEST 2000 Werner Koch - - * config.links: Support for powerpc--netbsd by Gabriel Rosenkoetter. - -Mon Jul 17 16:35:47 CEST 2000 Werner Koch - - * power/: Add all files from GMP for this CPU. Converted comments to - CPP comments because some ASes complain about ' in comments. - - * config.links: Support for BSDI 4.x; by Wayne Chapeskie. Add support - for FreeBSD 5 and made the case stmt looking nicer; by Jun Kuriyama. - Add support for NetBSD. - (sparc8): Made the search path the same as sparc9 - (sparc64-unknown-linux-gnu): use udiv module; by Adam Mitchell. - - * Makefile.am: c/SFLAGS/ASFLAGS/. This has only been used by the - powerpc and actually never passed the -Wa,foo to the cc. - - * mpih-div.c (mpihelp_divrem): The MPN_COPY_DECR copied one element - too many. This is a gmp2.0.2p9.txt patch. - - * longlong.h (umul_ppmm): Fixes for ARM-4. By Sean MacLennan. - - * mpi-internal.h (karatsuba_ctx): New. - * mpih-mul.c (mpihelp_release_karatsuba_ctx): New. - (mpihelp_mul_karatsuba_case): New. - (mpihelp_mul): Splitted to make use of the new functions. - * mpi-pow.c (mpi_powm): Make use of the new splitted function to avoid - multiple allocation of temporary memory during the karatsuba operations. - * mpi_mpow.c: Removed the unused Barrett code. - -2000-03-21 16:17:30 Werner Koch (wk@habibti.openit.de) - - * config.links: Add support for FreeBSD 5. - -Mon Jan 24 22:24:38 CET 2000 Werner Koch - - * mpicoder.c (gcry_mpi_aprint): Now really returns the length. - -Mon Jan 24 13:04:28 CET 2000 Werner Koch - - * mpiutil.c: Removed all memory debugging code. - - * mpicoder.c (gcry_mpi_aprint): New. - - * Replaced all m_ memory functions by g10_ ones. - -Fri Dec 31 14:06:56 CET 1999 Werner Koch - - * mpi-bit.c (gcry_mpi_get_nbits): New. - - * mpiutil.c (mpi_set_secure): made static. - (gcry_mpi_get_flag): New. - (gcry_mpi_set_flag): New. - (gcry_mpi_clear_flag): New. - (mpi_set_opaque): renamed to gcry_mpi_set_opaque. - (mpi_get_opaque): renamed to gcry_mpi_get_opaque. - -Fri Dec 31 12:48:31 CET 1999 Werner Koch - - * mpicoder.c (mpi_read_from_buffer): Made static. - (gcry_mpi_print): A buffer of NULL is now allowed to get the required - length back. - (mpi_get_keyid): Removed. - (mpi_print): Made static - should be removed. - -Wed Dec 8 21:58:32 CET 1999 Werner Koch - - * Makefile.am (INCLUDES): Add ../gcrypt. - - * g10m.c : Removed. - - * mpicoder.c (mpi_write): Removed. - (mpi_read): Removed. - (gcry_mpi_scan): New. Taken from ../gcrypt/mpiapi.c. - (gcry_mpi_print): Ditto. - - * mpi-pow.c (mpi_powm): Renamed to ... - (gcry_mpi_powm): ... this. - - * mpiutil.c (gcry_mpi_new): New as a wrapper around the old function. - Taken from ../gcrypt/mpiapi.c. - (gcry_mpi_snew): Ditto. - (gcry_mpi_release): Ditto. - (gcry_mpi_copy): Ditto. - (gcry_mpi_set): Ditto. - (gcry_mpi_set_ui): Ditto. - (gcry_mpi_cmp): Ditto. - (gcry_mpi_cmp_ui): Ditto. - (gcry_mpi_randomize): Ditto. - - * mpicoder.c (mpi_print): Removed the nbit_info kludge. - * mpi-bits.c (mpi_get_nbits): Replaced the is_protected stuff by - checking whether it is an opaque mpi and then returns it's length - in bits. - * mpiutil.c (mpi_set_opaque): Changed the interface to take a number - of bits for the length. Adjusted all users. - (mpi_get_opaque): Ditto. - -Fri Nov 19 17:15:20 CET 1999 Werner Koch - - * mpicoder.c (g10_log_mpidump): Add a temporary workaround - - * mpih-mul.c (mpihelp_mul_n): s/m_is_ecure/g10_is_secure/ - - * mpiutil.c (mpi_alloc): Remved the debug mode because it has turned - out, that this feature was not very useful in the past. Use the - new alloc functions. - (mpi_alloc_secure): Ditto. - (mpi_alloc_limb_space): Ditto. - (mpi_free_limb_space): Ditto. - (mpi_resize): Ditto. - (mpi_free): Ditto. - (mpi_set_secure): Removed the debug stuff. - (mpi_set_opaque): Ditto. - (mpi_copy): Ditto. - (mpi_alloc_set_ui): Ditto. - (mpi_m_check): Use g10_ wrapper. - -Mon Aug 30 20:38:33 CEST 1999 Werner Koch - - - * config.links: Add case label for DJGPP - -Wed Jul 14 19:42:08 CEST 1999 Werner Koch - - - * Makefile.am: Use .s files as temporaries, disabled other .S rules. - -Wed Jul 7 13:08:40 CEST 1999 Werner Koch - - - * mpicoder.c (g10_log_mpidump): New. - - * Makefile.am: Support for libtool. - -Fri Jul 2 11:45:54 CEST 1999 Werner Koch - - - * mpi-bit.c (mpi_lshift_limbs,mpi_rshift_limbs): New. - * mpi-mpow.c (barrett_mulm): New but diabled. - -Tue Jun 1 16:01:46 CEST 1999 Werner Koch - - * config.links (i[56]86*-*-freebsdelf*): New. - -Sun May 23 14:20:22 CEST 1999 Werner Koch - - * config.links (sysdep.h): Not any more conditionally created. - -Tue May 4 15:47:53 CEST 1999 Werner Koch - - * mpiutil.c (mpi_alloc_like): New. - -Mon Apr 26 17:48:15 CEST 1999 Werner Koch - - * mpih-add.c, mpih-sub.c: Removed - * mpi-inline.c: New. - * mpi-inline.h: Make it usable by mpi-inline.c. - -Sun Apr 18 10:11:28 CEST 1999 Werner Koch - - * mpih-mul.c (mpihelp_mul_n): Fixed use of memory region. - (mpihelp_mul): Ditto. - -Wed Apr 7 20:51:39 CEST 1999 Werner Koch - - * Makefile.am: Explicit rules to invoke cpp on *.S - -Mon Mar 8 20:47:17 CET 1999 Werner Koch - - * config.links: Take advantage of the with_symbol_underscore macro. - Add support for freebsd 4. - -Wed Feb 24 11:07:27 CET 1999 Werner Koch - - * mips3/mpih-sub1.S: Removed left over junk in last line. (Should I - blame me or my editor?). - -Sat Feb 13 12:04:43 CET 1999 Werner Koch - - * Makefile.am: Removed the +=. Add MPI_OPT_FLAGS. - -Sat Jan 9 16:02:23 CET 1999 Werner Koch - - * mpi-cmp.c (mpi_cmp_ui): Normalized the arg. - -Thu Jan 7 18:00:58 CET 1999 Werner Koch - - * mpi-bit.c (mpi_normalize): New. - (mpi_get_nbits): Normalize the MPI. - * mpi-bit.c (mpi_cmp): Normalize the MPI before the compare. - - -Tue Dec 8 13:15:16 CET 1998 Werner Koch - - * config.links: Moved the case for powerpc*linux - * powerpcp32/*.S: Removed some underscores. - -Thu Nov 26 07:27:52 1998 Werner Koch - - * config.links: Support for ppc with ELF - * powerpc32/syntax.h: New. - * powerpc32/*.S: Applied ELF patches (glibc patches) - -Tue Nov 10 19:31:37 1998 Werner Koch (wk@isil.d.shuttle.de) - - * power*/ : Started with stuff for PPC - * config.links: Some stuff for PPC. - * generic/udiv-w-sdiv.c: New but disabled. - -Tue Oct 27 12:37:46 1998 Werner Koch (wk@isil.d.shuttle.de) - - * config.links (freebsd): Fixes for FreeBSD 3.0 - -Wed Oct 14 09:59:30 1998 Werner Koch (wk@isil.d.shuttle.de) - - * config.links (freebsd): ELF patches from Jun Kuriyama. - -Thu Oct 8 13:28:17 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mpi-mpow.c (mpi_mulpowm): Fixed mem leak (m_free/mpi_free). - -Thu Sep 17 18:08:50 1998 Werner Koch (wk@(none)) - - * hppa1.1/udiv-qrnnd.S: Fix from Steffen Zahn for HPUX 10.20 - -Thu Aug 6 16:39:28 1998 Werner Koch,mobil,,, (wk@tobold) - - * mpi-bit.c (mpi_set_bytes): Removed. - -Wed Aug 5 15:11:12 1998 Werner Koch (wk@(none)) - - * mpicoder.c (mpi_read_from_buffer): New. - - * mpiutil.c (mpi_set_opaque): New. - (mpi_get_opaque): New. - (mpi_copy): Changed to support opauqe flag - (mpi_free): Ditto. - -Sat Jul 4 10:11:11 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mpiutil.c (mpi_clear): Reset flags. - (mpi_set): Ditto. - (mpi_alloc_secure): Set flag to 1 and not ored the 1 in, tsss.. - -Fri Jun 26 11:19:06 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mpiutil.c (mpi_alloc): set nbits to 0. - (mpi_alloc_secure): Ditto. - (mpi_clear): Ditto. - -Thu Jun 25 11:50:01 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mips3/*.S: New - -Mon May 18 13:47:06 1998 Werner Koch (wk@isil.d.shuttle.de) - - * config.links: split mpih-shift into mpih-[lr]shift and - changed all implementations. - * mpi/alpha: add some new assembler stuff. - -Wed May 13 11:04:29 1998 Werner Koch (wk@isil.d.shuttle.de) - - * config.links: Add support for MIPS - -Thu Apr 9 11:31:36 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mpicoder.c (mpi_get_secure_buffer): New. - -Wed Apr 8 09:44:33 1998 Werner Koch (wk@isil.d.shuttle.de) - - * config.links: Applied small fix from Ulf Möller. - -Mon Apr 6 12:38:52 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mpicoder.c (mpi_get_buffer): Removed returned leading zeroes - and changed all callers. - -Tue Mar 10 13:40:34 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mpi-bit.c (mpi_clear_highbit): New. - -Mon Mar 2 19:29:00 1998 Werner Koch (wk@isil.d.shuttle.de) - - * Makefile.am (DISTCLEANFILES): New - -Thu Feb 26 06:48:54 1998 Werner Koch (wk@isil.d.shuttle.de) - - * config.links (X86_BROKEN_ALIGN): Added for some systems. - -Mon Feb 23 12:21:40 1998 Werner Koch (wk@isil.d.shuttle.de) - - * mpi/m68k/mpih-shift.S (Lspecial): Changed duplicate symbol. - -Mon Feb 16 13:00:27 1998 Werner Koch (wk@isil.d.shuttle.de) - - * config.links : Add detection of m68k cpus - - - Copyright 1998,1999,2000,2001,2002,2003 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/mpi/Makefile.am b/grub-core/lib/libgcrypt/mpi/Makefile.am deleted file mode 100644 index e900539a2..000000000 --- a/grub-core/lib/libgcrypt/mpi/Makefile.am +++ /dev/null @@ -1,177 +0,0 @@ -## Process this file with automake to produce Makefile.in -# Copyright (C) 1992, 1999, 2000, 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 - -# 1.5 leads to a combinatorial explosion due to all the conditionals -# I was not able to build it with 64Megs - 1.6 fixes this. -# not anymore required: AUTOMAKE_OPTIONS = 1.6 - -# Need to include ../src in addition to top_srcdir because gcrypt.h is -# a built header. -AM_CPPFLAGS = -I../src -I$(top_srcdir)/src -AM_CFLAGS = $(GPG_ERROR_CFLAGS) - -AM_ASFLAGS = $(MPI_SFLAGS) -AM_CCASFLAGS = $(NOEXECSTACK_FLAGS) - -EXTRA_DIST = Manifest config.links -DISTCLEANFILES = mpi-asm-defs.h \ - mpih-add1-asm.S mpih-mul1-asm.S mpih-mul2-asm.S mpih-mul3-asm.S \ - mpih-lshift-asm.S mpih-rshift-asm.S mpih-sub1-asm.S asm-syntax.h \ - mpih-add1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c \ - mpih-lshift.c mpih-rshift.c mpih-sub1.c \ - sysdep.h mod-source-info.h - -# Beware: The following list is not a comment but grepped by -# config.links to get the list of symlinked modules -# Optional modules are marked with an O in the second column. -#BEGIN_ASM_LIST -# mpih-add1 C -# mpih-sub1 C -# mpih-mul1 C -# mpih-mul2 C -# mpih-mul3 C -# mpih-lshift C -# mpih-rshift C -# udiv O -# udiv-qrnnd O -#END_ASM_LIST - -# Note: This function has not yet been implemented. There is only a dummy in -# generic/ -# udiv-w-sdiv O - -# And we need to have conditionals for all modules because -# we don't know whether they are .c or .S. Very ugly; I know. -# Remember to define them all in configure.ac -if MPI_MOD_ASM_MPIH_ADD1 -mpih_add1 = mpih-add1-asm.S -else -if MPI_MOD_C_MPIH_ADD1 -mpih_add1 = mpih-add1.c -else -mpih_add1 = -endif -endif - -if MPI_MOD_ASM_MPIH_SUB1 -mpih_sub1 = mpih-sub1-asm.S -else -if MPI_MOD_C_MPIH_SUB1 -mpih_sub1 = mpih-sub1.c -else -mpih_sub1 = -endif -endif - -if MPI_MOD_ASM_MPIH_MUL1 -mpih_mul1 = mpih-mul1-asm.S -else -if MPI_MOD_C_MPIH_MUL1 -mpih_mul1 = mpih-mul1.c -else -mpih_mul1 = -endif -endif - -if MPI_MOD_ASM_MPIH_MUL2 -mpih_mul2 = mpih-mul2-asm.S -else -if MPI_MOD_C_MPIH_MUL2 -mpih_mul2 = mpih-mul2.c -else -mpih_mul2 = -endif -endif - -if MPI_MOD_ASM_MPIH_MUL3 -mpih_mul3 = mpih-mul3-asm.S -else -if MPI_MOD_C_MPIH_MUL3 -mpih_mul3 = mpih-mul3.c -else -mpih_mul3 = -endif -endif - -if MPI_MOD_ASM_MPIH_LSHIFT -mpih_lshift = mpih-lshift-asm.S -else -if MPI_MOD_C_MPIH_LSHIFT -mpih_lshift = mpih-lshift.c -else -mpih_lshift = -endif -endif - -if MPI_MOD_ASM_MPIH_RSHIFT -mpih_rshift = mpih-rshift-asm.S -else -if MPI_MOD_C_MPIH_RSHIFT -mpih_rshift = mpih-rshift.c -else -mpih_rshift = -endif -endif - -if MPI_MOD_ASM_UDIV -udiv = udiv-asm.S -else -if MPI_MOD_C_UDIV -udiv = udiv.c -else -udiv = -endif -endif - -if MPI_MOD_ASM_UDIV_QRNND -udiv_qrnnd = udiv-qrnnd-asm.S -else -if MPI_MOD_C_UDIV_QRNND -udiv_qrnnd = udiv-qrnnd.c -else -udiv_qrnnd = -endif -endif - -noinst_LTLIBRARIES = libmpi.la - -libmpi_la_LDFLAGS = -nodist_libmpi_la_SOURCES = $(mpih_add1) $(mpih_sub1) $(mpih_mul1) \ - $(mpih_mul2) $(mpih_mul3) $(mpih_lshift) $(mpih_rshift) \ - $(udiv) $(udiv_qrnnd) -libmpi_la_SOURCES = longlong.h \ - mpi-add.c \ - mpi-bit.c \ - mpi-cmp.c \ - mpi-div.c \ - mpi-gcd.c \ - mpi-internal.h \ - mpi-inline.h \ - mpi-inline.c \ - mpi-inv.c \ - mpi-mul.c \ - mpi-mod.c \ - mpi-pow.c \ - mpi-mpow.c \ - mpi-scan.c \ - mpicoder.c \ - mpih-div.c \ - mpih-mul.c \ - mpiutil.c \ - ec.c diff --git a/grub-core/lib/libgcrypt/mpi/Manifest b/grub-core/lib/libgcrypt/mpi/Manifest deleted file mode 100644 index 3b0d6733d..000000000 --- a/grub-core/lib/libgcrypt/mpi/Manifest +++ /dev/null @@ -1,41 +0,0 @@ -# Manifest - checksums of the mpi directory -# Copyright 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 - -Makefile.am -config.links -longlong.h -mpi-add.c -mpi-bit.c -mpi-cmp.c -mpi-div.c -mpi-gcd.c -mpi-inline.c -mpi-inline.h -mpi-internal.h -mpi-inv.c -mpi-mpow.c -mpi-mul.c -mpi-pow.c -mpi-scan.c -mpicoder.c -mpih-div.c -mpih-mul.c -mpiutil.c -$names$ iQCVAwUAP+LmfDEAnp832S/7AQKZJQQAkR/gQITUM+6Ygy9WAOAO17btyKAlCtGTXp5XSZ+J3X0o/rYneRdSCW89IJvwFRJjAOcFJd52MXs6ZVFF/RQBC8MvJzuQChbEzvihK8o2VgK34YWjU+6XH9sFgRMIgzkHs/51ZZxeQUOPy1XF7TyKB0WE7YBUVisFiRaqB1qGIOs==Z3qB - diff --git a/grub-core/lib/libgcrypt/mpi/alpha/README b/grub-core/lib/libgcrypt/mpi/alpha/README deleted file mode 100644 index 55c0a2917..000000000 --- a/grub-core/lib/libgcrypt/mpi/alpha/README +++ /dev/null @@ -1,53 +0,0 @@ -This directory contains mpn functions optimized for DEC Alpha processors. - -RELEVANT OPTIMIZATION ISSUES - -EV4 - -1. This chip has very limited store bandwidth. The on-chip L1 cache is -write-through, and a cache line is transfered from the store buffer to the -off-chip L2 in as much 15 cycles on most systems. This delay hurts -mpn_add_n, mpn_sub_n, mpn_lshift, and mpn_rshift. - -2. Pairing is possible between memory instructions and integer arithmetic -instructions. - -3. mulq and umulh is documented to have a latency of 23 cycles, but 2 of -these cycles are pipelined. Thus, multiply instructions can be issued at a -rate of one each 21nd cycle. - -EV5 - -1. The memory bandwidth of this chip seems excellent, both for loads and -stores. Even when the working set is larger than the on-chip L1 and L2 -caches, the perfromance remain almost unaffected. - -2. mulq has a measured latency of 13 cycles and an issue rate of 1 each 8th -cycle. umulh has a measured latency of 15 cycles and an issue rate of 1 -each 10th cycle. But the exact timing is somewhat confusing. - -3. mpn_add_n. With 4-fold unrolling, we need 37 instructions, whereof 12 - are memory operations. This will take at least - ceil(37/2) [dual issue] + 1 [taken branch] = 20 cycles - We have 12 memory cycles, plus 4 after-store conflict cycles, or 16 data - cache cycles, which should be completely hidden in the 20 issue cycles. - The computation is inherently serial, with these dependencies: - addq - / \ - addq cmpult - | | - cmpult | - \ / - or - I.e., there is a 4 cycle path for each limb, making 16 cycles the absolute - minimum. We could replace the `or' with a cmoveq/cmovne, which would save - a cycle on EV5, but that might waste a cycle on EV4. Also, cmov takes 2 - cycles. - addq - / \ - addq cmpult - | \ - cmpult -> cmovne - -STATUS - diff --git a/grub-core/lib/libgcrypt/mpi/alpha/distfiles b/grub-core/lib/libgcrypt/mpi/alpha/distfiles deleted file mode 100644 index f2ab9fc3c..000000000 --- a/grub-core/lib/libgcrypt/mpi/alpha/distfiles +++ /dev/null @@ -1,11 +0,0 @@ -README -mpih-add1.S -mpih-sub1.S -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S -mpih-lshift.S -mpih-rshift.S - -udiv-qrnnd.S - diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-add1.S deleted file mode 100644 index 50dbb2b9d..000000000 --- a/grub-core/lib/libgcrypt/mpi/alpha/mpih-add1.S +++ /dev/null @@ -1,124 +0,0 @@ -/* alpha add_n -- Add two limb vectors of the same length > 0 and store - * sum in a third limb vector. - * Copyright (C) 1995, 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 - */ - - - -/******************* - * mpi_limb_t - * _gcry_mpih_add_n( mpi_ptr_t res_ptr, ($16) - * mpi_ptr_t s1_ptr, ($17) - * mpi_ptr_t s2_ptr, ($18) - * mpi_size_t size) ($19) - */ - - - .set noreorder - .set noat -.text - .align 3 - .globl _gcry_mpih_add_n - .ent _gcry_mpih_add_n -_gcry_mpih_add_n: - .frame $30,0,$26,0 - - ldq $3,0($17) - ldq $4,0($18) - - subq $19,1,$19 - and $19,4-1,$2 # number of limbs in first loop - bis $31,$31,$0 - beq $2,.L0 # if multiple of 4 limbs, skip first loop - - subq $19,$2,$19 - -.Loop0: subq $2,1,$2 - ldq $5,8($17) - addq $4,$0,$4 - ldq $6,8($18) - cmpult $4,$0,$1 - addq $3,$4,$4 - cmpult $4,$3,$0 - stq $4,0($16) - or $0,$1,$0 - - addq $17,8,$17 - addq $18,8,$18 - bis $5,$5,$3 - bis $6,$6,$4 - addq $16,8,$16 - bne $2,.Loop0 - -.L0: beq $19,.Lend - - .align 3 -.Loop: subq $19,4,$19 - - ldq $5,8($17) - addq $4,$0,$4 - ldq $6,8($18) - cmpult $4,$0,$1 - addq $3,$4,$4 - cmpult $4,$3,$0 - stq $4,0($16) - or $0,$1,$0 - - ldq $3,16($17) - addq $6,$0,$6 - ldq $4,16($18) - cmpult $6,$0,$1 - addq $5,$6,$6 - cmpult $6,$5,$0 - stq $6,8($16) - or $0,$1,$0 - - ldq $5,24($17) - addq $4,$0,$4 - ldq $6,24($18) - cmpult $4,$0,$1 - addq $3,$4,$4 - cmpult $4,$3,$0 - stq $4,16($16) - or $0,$1,$0 - - ldq $3,32($17) - addq $6,$0,$6 - ldq $4,32($18) - cmpult $6,$0,$1 - addq $5,$6,$6 - cmpult $6,$5,$0 - stq $6,24($16) - or $0,$1,$0 - - addq $17,32,$17 - addq $18,32,$18 - addq $16,32,$16 - bne $19,.Loop - -.Lend: addq $4,$0,$4 - cmpult $4,$0,$1 - addq $3,$4,$4 - cmpult $4,$3,$0 - stq $4,0($16) - or $0,$1,$0 - ret $31,($26),1 - - .end _gcry_mpih_add_n - diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-lshift.S deleted file mode 100644 index ded4b15c0..000000000 --- a/grub-core/lib/libgcrypt/mpi/alpha/mpih-lshift.S +++ /dev/null @@ -1,122 +0,0 @@ -/* alpha - left shift - * - * Copyright (C) 1994, 1995, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - - -/******************* - * mpi_limb_t - * _gcry_mpih_lshift( mpi_ptr_t wp, (r16) - * mpi_ptr_t up, (r17) - * mpi_size_t usize, (r18) - * unsigned cnt) (r19) - * - * This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling, - * it would take 4 cycles/limb. It should be possible to get down to 3 - * cycles/limb since both ldq and stq can be paired with the other used - * instructions. But there are many restrictions in the 21064 pipeline that - * makes it hard, if not impossible, to get down to 3 cycles/limb: - * - * 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay. - * 2. Only aligned instruction pairs can be paired. - * 3. The store buffer or silo might not be able to deal with the bandwidth. - */ - - .set noreorder - .set noat -.text - .align 3 - .globl _gcry_mpih_lshift - .ent _gcry_mpih_lshift -_gcry_mpih_lshift: - .frame $30,0,$26,0 - - s8addq $18,$17,$17 # make r17 point at end of s1 - ldq $4,-8($17) # load first limb - subq $17,8,$17 - subq $31,$19,$7 - s8addq $18,$16,$16 # make r16 point at end of RES - subq $18,1,$18 - and $18,4-1,$20 # number of limbs in first loop - srl $4,$7,$0 # compute function result - - beq $20,.L0 - subq $18,$20,$18 - - .align 3 -.Loop0: - ldq $3,-8($17) - subq $16,8,$16 - subq $17,8,$17 - subq $20,1,$20 - sll $4,$19,$5 - srl $3,$7,$6 - bis $3,$3,$4 - bis $5,$6,$8 - stq $8,0($16) - bne $20,.Loop0 - -.L0: beq $18,.Lend - - .align 3 -.Loop: ldq $3,-8($17) - subq $16,32,$16 - subq $18,4,$18 - sll $4,$19,$5 - srl $3,$7,$6 - - ldq $4,-16($17) - sll $3,$19,$1 - bis $5,$6,$8 - stq $8,24($16) - srl $4,$7,$2 - - ldq $3,-24($17) - sll $4,$19,$5 - bis $1,$2,$8 - stq $8,16($16) - srl $3,$7,$6 - - ldq $4,-32($17) - sll $3,$19,$1 - bis $5,$6,$8 - stq $8,8($16) - srl $4,$7,$2 - - subq $17,32,$17 - bis $1,$2,$8 - stq $8,0($16) - - bgt $18,.Loop - -.Lend: sll $4,$19,$8 - stq $8,-8($16) - ret $31,($26),1 - .end _gcry_mpih_lshift - - diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul1.S deleted file mode 100644 index cd91b1049..000000000 --- a/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul1.S +++ /dev/null @@ -1,90 +0,0 @@ -/* Alpha 21064 mpih-mul1.S -- Multiply a limb vector with a limb and store - * the result in a second limb vector. - * - * Copyright (C) 1992, 1994, 1995, 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 - */ - - -/******************* - * mpi_limb_t - * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r16) - * mpi_ptr_t s1_ptr, (r17) - * mpi_size_t s1_size, (r18) - * mpi_limb_t s2_limb) (r19) - * - * This code runs at 42 cycles/limb on the EV4 and 18 cycles/limb on the EV5. - * - * To improve performance for long multiplications, we would use - * 'fetch' for S1 and 'fetch_m' for RES. It's not obvious how to use - * these instructions without slowing down the general code: 1. We can - * only have two prefetches in operation at any time in the Alpha - * architecture. 2. There will seldom be any special alignment - * between RES_PTR and S1_PTR. Maybe we can simply divide the current - * loop into an inner and outer loop, having the inner loop handle - * exactly one prefetch block? - */ - - .set noreorder - .set noat -.text - .align 3 - .globl _gcry_mpih_mul_1 - .ent _gcry_mpih_mul_1 2 -_gcry_mpih_mul_1: - .frame $30,0,$26 - - ldq $2,0($17) # $2 = s1_limb - subq $18,1,$18 # size-- - mulq $2,$19,$3 # $3 = prod_low - bic $31,$31,$4 # clear cy_limb - umulh $2,$19,$0 # $0 = prod_high - beq $18,Lend1 # jump if size was == 1 - ldq $2,8($17) # $2 = s1_limb - subq $18,1,$18 # size-- - stq $3,0($16) - beq $18,Lend2 # jump if size was == 2 - - .align 3 -Loop: mulq $2,$19,$3 # $3 = prod_low - addq $4,$0,$0 # cy_limb = cy_limb + 'cy' - subq $18,1,$18 # size-- - umulh $2,$19,$4 # $4 = cy_limb - ldq $2,16($17) # $2 = s1_limb - addq $17,8,$17 # s1_ptr++ - addq $3,$0,$3 # $3 = cy_limb + prod_low - stq $3,8($16) - cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low) - addq $16,8,$16 # res_ptr++ - bne $18,Loop - -Lend2: mulq $2,$19,$3 # $3 = prod_low - addq $4,$0,$0 # cy_limb = cy_limb + 'cy' - umulh $2,$19,$4 # $4 = cy_limb - addq $3,$0,$3 # $3 = cy_limb + prod_low - cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low) - stq $3,8($16) - addq $4,$0,$0 # cy_limb = prod_high + cy - ret $31,($26),1 -Lend1: stq $3,0($16) - ret $31,($26),1 - - .end _gcry_mpih_mul_1 - - diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul2.S deleted file mode 100644 index 5eb6b98be..000000000 --- a/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul2.S +++ /dev/null @@ -1,97 +0,0 @@ -/* Alpha 21064 addmul_1 -- Multiply a limb vector with a limb and add - * the result to a second limb vector. - * - * Copyright (C) 1992, 1994, 1995, 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 - */ - - -/******************* - * mpi_limb_t - * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r16) - * mpi_ptr_t s1_ptr, (r17) - * mpi_size_t s1_size, (r18) - * mpi_limb_t s2_limb) (r19) - * - * This code runs at 42 cycles/limb on EV4 and 18 cycles/limb on EV5. - */ - - - .set noreorder - .set noat -.text - .align 3 - .globl _gcry_mpih_addmul_1 - .ent _gcry_mpih_addmul_1 2 -_gcry_mpih_addmul_1: - .frame $30,0,$26 - - ldq $2,0($17) # $2 = s1_limb - addq $17,8,$17 # s1_ptr++ - subq $18,1,$18 # size-- - mulq $2,$19,$3 # $3 = prod_low - ldq $5,0($16) # $5 = *res_ptr - umulh $2,$19,$0 # $0 = prod_high - beq $18,.Lend1 # jump if size was == 1 - ldq $2,0($17) # $2 = s1_limb - addq $17,8,$17 # s1_ptr++ - subq $18,1,$18 # size-- - addq $5,$3,$3 - cmpult $3,$5,$4 - stq $3,0($16) - addq $16,8,$16 # res_ptr++ - beq $18,.Lend2 # jump if size was == 2 - - .align 3 -.Loop: mulq $2,$19,$3 # $3 = prod_low - ldq $5,0($16) # $5 = *res_ptr - addq $4,$0,$0 # cy_limb = cy_limb + 'cy' - subq $18,1,$18 # size-- - umulh $2,$19,$4 # $4 = cy_limb - ldq $2,0($17) # $2 = s1_limb - addq $17,8,$17 # s1_ptr++ - addq $3,$0,$3 # $3 = cy_limb + prod_low - cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low) - addq $5,$3,$3 - cmpult $3,$5,$5 - stq $3,0($16) - addq $16,8,$16 # res_ptr++ - addq $5,$0,$0 # combine carries - bne $18,.Loop - -.Lend2: mulq $2,$19,$3 # $3 = prod_low - ldq $5,0($16) # $5 = *res_ptr - addq $4,$0,$0 # cy_limb = cy_limb + 'cy' - umulh $2,$19,$4 # $4 = cy_limb - addq $3,$0,$3 # $3 = cy_limb + prod_low - cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low) - addq $5,$3,$3 - cmpult $3,$5,$5 - stq $3,0($16) - addq $5,$0,$0 # combine carries - addq $4,$0,$0 # cy_limb = prod_high + cy - ret $31,($26),1 -.Lend1: addq $5,$3,$3 - cmpult $3,$5,$5 - stq $3,0($16) - addq $0,$5,$0 - ret $31,($26),1 - - .end _gcry_mpih_addmul_1 - diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul3.S deleted file mode 100644 index 7d5d2afe4..000000000 --- a/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul3.S +++ /dev/null @@ -1,95 +0,0 @@ -/* Alpha 21064 submul_1 -- Multiply a limb vector with a limb and - * subtract the result from a second limb vector. - * Copyright (C) 1992, 1994, 1995, 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 - */ - - -/******************* - * mpi_limb_t - * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r16 ) - * mpi_ptr_t s1_ptr, (r17 ) - * mpi_size_t s1_size, (r18 ) - * mpi_limb_t s2_limb) (r19 ) - * - * This code runs at 42 cycles/limb on EV4 and 18 cycles/limb on EV5. - */ - - .set noreorder - .set noat -.text - .align 3 - .globl _gcry_mpih_submul_1 - .ent _gcry_mpih_submul_1 2 -_gcry_mpih_submul_1: - .frame $30,0,$26 - - ldq $2,0($17) # $2 = s1_limb - addq $17,8,$17 # s1_ptr++ - subq $18,1,$18 # size-- - mulq $2,$19,$3 # $3 = prod_low - ldq $5,0($16) # $5 = *res_ptr - umulh $2,$19,$0 # $0 = prod_high - beq $18,.Lend1 # jump if size was == 1 - ldq $2,0($17) # $2 = s1_limb - addq $17,8,$17 # s1_ptr++ - subq $18,1,$18 # size-- - subq $5,$3,$3 - cmpult $5,$3,$4 - stq $3,0($16) - addq $16,8,$16 # res_ptr++ - beq $18,.Lend2 # jump if size was == 2 - - .align 3 -.Loop: mulq $2,$19,$3 # $3 = prod_low - ldq $5,0($16) # $5 = *res_ptr - addq $4,$0,$0 # cy_limb = cy_limb + 'cy' - subq $18,1,$18 # size-- - umulh $2,$19,$4 # $4 = cy_limb - ldq $2,0($17) # $2 = s1_limb - addq $17,8,$17 # s1_ptr++ - addq $3,$0,$3 # $3 = cy_limb + prod_low - cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low) - subq $5,$3,$3 - cmpult $5,$3,$5 - stq $3,0($16) - addq $16,8,$16 # res_ptr++ - addq $5,$0,$0 # combine carries - bne $18,.Loop - -.Lend2: mulq $2,$19,$3 # $3 = prod_low - ldq $5,0($16) # $5 = *res_ptr - addq $4,$0,$0 # cy_limb = cy_limb + 'cy' - umulh $2,$19,$4 # $4 = cy_limb - addq $3,$0,$3 # $3 = cy_limb + prod_low - cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low) - subq $5,$3,$3 - cmpult $5,$3,$5 - stq $3,0($16) - addq $5,$0,$0 # combine carries - addq $4,$0,$0 # cy_limb = prod_high + cy - ret $31,($26),1 -.Lend1: subq $5,$3,$3 - cmpult $5,$3,$5 - stq $3,0($16) - addq $0,$5,$0 - ret $31,($26),1 - - .end _gcry_mpih_submul_1 - diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-rshift.S deleted file mode 100644 index f0c981438..000000000 --- a/grub-core/lib/libgcrypt/mpi/alpha/mpih-rshift.S +++ /dev/null @@ -1,118 +0,0 @@ -/* alpha rshift - * Copyright (C) 1994, 1995, 1998, 1999, - * 2000, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - - - -/******************* - * mpi_limb_t - * _gcry_mpih_rshift( mpi_ptr_t wp, (r16) - * mpi_ptr_t up, (r17) - * mpi_size_t usize, (r18) - * unsigned cnt) (r19) - * - * This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling, - * it would take 4 cycles/limb. It should be possible to get down to 3 - * cycles/limb since both ldq and stq can be paired with the other used - * instructions. But there are many restrictions in the 21064 pipeline that - * makes it hard, if not impossible, to get down to 3 cycles/limb: - * - * 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay. - * 2. Only aligned instruction pairs can be paired. - * 3. The store buffer or silo might not be able to deal with the bandwidth. - */ - - .set noreorder - .set noat -.text - .align 3 - .globl _gcry_mpih_rshift - .ent _gcry_mpih_rshift -_gcry_mpih_rshift: - .frame $30,0,$26,0 - - ldq $4,0($17) # load first limb - addq $17,8,$17 - subq $31,$19,$7 - subq $18,1,$18 - and $18,4-1,$20 # number of limbs in first loop - sll $4,$7,$0 # compute function result - - beq $20,.R0 - subq $18,$20,$18 - - .align 3 -.Roop0: - ldq $3,0($17) - addq $16,8,$16 - addq $17,8,$17 - subq $20,1,$20 - srl $4,$19,$5 - sll $3,$7,$6 - bis $3,$3,$4 - bis $5,$6,$8 - stq $8,-8($16) - bne $20,.Roop0 - -.R0: beq $18,.Rend - - .align 3 -.Roop: ldq $3,0($17) - addq $16,32,$16 - subq $18,4,$18 - srl $4,$19,$5 - sll $3,$7,$6 - - ldq $4,8($17) - srl $3,$19,$1 - bis $5,$6,$8 - stq $8,-32($16) - sll $4,$7,$2 - - ldq $3,16($17) - srl $4,$19,$5 - bis $1,$2,$8 - stq $8,-24($16) - sll $3,$7,$6 - - ldq $4,24($17) - srl $3,$19,$1 - bis $5,$6,$8 - stq $8,-16($16) - sll $4,$7,$2 - - addq $17,32,$17 - bis $1,$2,$8 - stq $8,-8($16) - - bgt $18,.Roop - -.Rend: srl $4,$19,$8 - stq $8,0($16) - ret $31,($26),1 - .end _gcry_mpih_rshift - diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-sub1.S deleted file mode 100644 index 9a644468c..000000000 --- a/grub-core/lib/libgcrypt/mpi/alpha/mpih-sub1.S +++ /dev/null @@ -1,124 +0,0 @@ -/* Alpha sub_n -- Subtract two limb vectors of the same length > 0 and - * store difference in a third limb vector. - * Copyright (C) 1995, 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 - */ - - -/******************* - * mpi_limb_t - * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r16) - * mpi_ptr_t s1_ptr, (r17) - * mpi_ptr_t s2_ptr, (r18) - * mpi_size_t size) (r19) - */ - - .set noreorder - .set noat -.text - .align 3 - .globl _gcry_mpih_sub_n - .ent _gcry_mpih_sub_n -_gcry_mpih_sub_n: - .frame $30,0,$26,0 - - ldq $3,0($17) - ldq $4,0($18) - - subq $19,1,$19 - and $19,4-1,$2 # number of limbs in first loop - bis $31,$31,$0 - beq $2,.L0 # if multiple of 4 limbs, skip first loop - - subq $19,$2,$19 - -.Loop0: subq $2,1,$2 - ldq $5,8($17) - addq $4,$0,$4 - ldq $6,8($18) - cmpult $4,$0,$1 - subq $3,$4,$4 - cmpult $3,$4,$0 - stq $4,0($16) - or $0,$1,$0 - - addq $17,8,$17 - addq $18,8,$18 - bis $5,$5,$3 - bis $6,$6,$4 - addq $16,8,$16 - bne $2,.Loop0 - -.L0: beq $19,.Lend - - .align 3 -.Loop: subq $19,4,$19 - - ldq $5,8($17) - addq $4,$0,$4 - ldq $6,8($18) - cmpult $4,$0,$1 - subq $3,$4,$4 - cmpult $3,$4,$0 - stq $4,0($16) - or $0,$1,$0 - - ldq $3,16($17) - addq $6,$0,$6 - ldq $4,16($18) - cmpult $6,$0,$1 - subq $5,$6,$6 - cmpult $5,$6,$0 - stq $6,8($16) - or $0,$1,$0 - - ldq $5,24($17) - addq $4,$0,$4 - ldq $6,24($18) - cmpult $4,$0,$1 - subq $3,$4,$4 - cmpult $3,$4,$0 - stq $4,16($16) - or $0,$1,$0 - - ldq $3,32($17) - addq $6,$0,$6 - ldq $4,32($18) - cmpult $6,$0,$1 - subq $5,$6,$6 - cmpult $5,$6,$0 - stq $6,24($16) - or $0,$1,$0 - - addq $17,32,$17 - addq $18,32,$18 - addq $16,32,$16 - bne $19,.Loop - -.Lend: addq $4,$0,$4 - cmpult $4,$0,$1 - subq $3,$4,$4 - cmpult $3,$4,$0 - stq $4,0($16) - or $0,$1,$0 - ret $31,($26),1 - - .end _gcry_mpih_sub_n - - diff --git a/grub-core/lib/libgcrypt/mpi/alpha/udiv-qrnnd.S b/grub-core/lib/libgcrypt/mpi/alpha/udiv-qrnnd.S deleted file mode 100644 index dd0c52d7d..000000000 --- a/grub-core/lib/libgcrypt/mpi/alpha/udiv-qrnnd.S +++ /dev/null @@ -1,159 +0,0 @@ -/* Alpha 21064 __udiv_qrnnd - * - * Copyright (C) 1992, 1994, 1995, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - - - .set noreorder - .set noat -.text - .align 3 - .globl __udiv_qrnnd - .ent __udiv_qrnnd -__udiv_qrnnd: - .frame $30,0,$26,0 - .prologue 0 -#define cnt $2 -#define tmp $3 -#define rem_ptr $16 -#define n1 $17 -#define n0 $18 -#define d $19 -#define qb $20 - - ldiq cnt,16 - blt d,.Largedivisor - -.Loop1: cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule d,n1,qb - subq n1,d,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule d,n1,qb - subq n1,d,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule d,n1,qb - subq n1,d,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule d,n1,qb - subq n1,d,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - subq cnt,1,cnt - bgt cnt,.Loop1 - stq n1,0(rem_ptr) - bis $31,n0,$0 - ret $31,($26),1 - -.Largedivisor: - and n0,1,$4 - - srl n0,1,n0 - sll n1,63,tmp - or tmp,n0,n0 - srl n1,1,n1 - - and d,1,$6 - srl d,1,$5 - addq $5,$6,$5 - -.Loop2: cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule $5,n1,qb - subq n1,$5,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule $5,n1,qb - subq n1,$5,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule $5,n1,qb - subq n1,$5,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule $5,n1,qb - subq n1,$5,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - subq cnt,1,cnt - bgt cnt,.Loop2 - - addq n1,n1,n1 - addq $4,n1,n1 - bne $6,.LOdd - stq n1,0(rem_ptr) - bis $31,n0,$0 - ret $31,($26),1 - -.LOdd: - /* q' in n0. r' in n1 */ - addq n1,n0,n1 - cmpult n1,n0,tmp # tmp := carry from addq - beq tmp,.LLp6 - addq n0,1,n0 - subq n1,d,n1 -.LLp6: cmpult n1,d,tmp - bne tmp,.LLp7 - addq n0,1,n0 - subq n1,d,n1 -.LLp7: - stq n1,0(rem_ptr) - bis $31,n0,$0 - ret $31,($26),1 - - .end __udiv_qrnnd diff --git a/grub-core/lib/libgcrypt/mpi/amd64/distfiles b/grub-core/lib/libgcrypt/mpi/amd64/distfiles deleted file mode 100644 index 634e36fb0..000000000 --- a/grub-core/lib/libgcrypt/mpi/amd64/distfiles +++ /dev/null @@ -1,8 +0,0 @@ -mpih-add1.S -mpih-lshift.S -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S -mpih-rshift.S -mpih-sub1.S -mpi-asm-defs.h diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpi-asm-defs.h b/grub-core/lib/libgcrypt/mpi/amd64/mpi-asm-defs.h deleted file mode 100644 index 17de1c190..000000000 --- a/grub-core/lib/libgcrypt/mpi/amd64/mpi-asm-defs.h +++ /dev/null @@ -1,4 +0,0 @@ -/* This file defines some basic constants for the MPI machinery. We - * need to define the types on a per-CPU basis, so it is done with - * this file here. */ -#define BYTES_PER_MPI_LIMB 8 diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-add1.S deleted file mode 100644 index f0ec89cc6..000000000 --- a/grub-core/lib/libgcrypt/mpi/amd64/mpih-add1.S +++ /dev/null @@ -1,63 +0,0 @@ -/* AMD64 (x86_64) add_n -- Add two limb vectors of the same length > 0 and store - * sum in a third limb vector. - * - * Copyright (C) 1992, 1994, 1995, 1998, - * 2001, 2002, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_add_n( mpi_ptr_t res_ptr, rdi - * mpi_ptr_t s1_ptr, rsi - * mpi_ptr_t s2_ptr, rdx - * mpi_size_t size) rcx - */ - -.text - .globl C_SYMBOL_NAME(_gcry_mpih_add_n) -C_SYMBOL_NAME(_gcry_mpih_add_n:) - leaq (%rsi,%rcx,8), %rsi - leaq (%rdi,%rcx,8), %rdi - leaq (%rdx,%rcx,8), %rdx - negq %rcx - xorl %eax, %eax /* clear cy */ - - ALIGN(4) /* minimal alignment for claimed speed */ -.Loop: movq (%rsi,%rcx,8), %rax - movq (%rdx,%rcx,8), %r10 - adcq %r10, %rax - movq %rax, (%rdi,%rcx,8) - incq %rcx - jne .Loop - - movq %rcx, %rax /* zero %rax */ - adcq %rax, %rax - ret - \ No newline at end of file diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-lshift.S deleted file mode 100644 index e87dd1a99..000000000 --- a/grub-core/lib/libgcrypt/mpi/amd64/mpih-lshift.S +++ /dev/null @@ -1,77 +0,0 @@ -/* AMD64 (x86_64) lshift -- Left shift a limb vector and store - * result in a second limb vector. - * - * Copyright (C) 1992, 1994, 1995, 1998, - * 2001, 2002, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - -/******************* - * mpi_limb_t - * _gcry_mpih_lshift( mpi_ptr_t wp, rdi - * mpi_ptr_t up, rsi - * mpi_size_t usize, rdx - * unsigned cnt) rcx - */ - -.text - .globl C_SYMBOL_NAME(_gcry_mpih_lshift) -C_SYMBOL_NAME(_gcry_mpih_lshift:) - movq -8(%rsi,%rdx,8), %mm7 - movd %ecx, %mm1 - movl $64, %eax - subl %ecx, %eax - movd %eax, %mm0 - movq %mm7, %mm3 - psrlq %mm0, %mm7 - movd %mm7, %rax - subq $2, %rdx - jl .Lendo - - ALIGN(4) /* minimal alignment for claimed speed */ -.Loop: movq (%rsi,%rdx,8), %mm6 - movq %mm6, %mm2 - psrlq %mm0, %mm6 - psllq %mm1, %mm3 - por %mm6, %mm3 - movq %mm3, 8(%rdi,%rdx,8) - je .Lende - movq -8(%rsi,%rdx,8), %mm7 - movq %mm7, %mm3 - psrlq %mm0, %mm7 - psllq %mm1, %mm2 - por %mm7, %mm2 - movq %mm2, (%rdi,%rdx,8) - subq $2, %rdx - jge .Loop - -.Lendo: movq %mm3, %mm2 -.Lende: psllq %mm1, %mm2 - movq %mm2, (%rdi) - emms - ret diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul1.S deleted file mode 100644 index 54b0ab489..000000000 --- a/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul1.S +++ /dev/null @@ -1,65 +0,0 @@ -/* AMD64 mul_1 -- Multiply a limb vector with a limb and store - * the result in a second limb vector. - * Copyright (C) 1992, 1994, 1998, - * 2001, 2002, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - -/******************* - * mpi_limb_t - * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (rdi) - * mpi_ptr_t s1_ptr, (rsi) - * mpi_size_t s1_size, (rdx) - * mpi_limb_t s2_limb) (rcx) - */ - - - TEXT - ALIGN(5) - .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - - GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1) -C_SYMBOL_NAME(_gcry_mpih_mul_1:) - - movq %rdx, %r11 - leaq (%rsi,%rdx,8), %rsi - leaq (%rdi,%rdx,8), %rdi - negq %r11 - xorl %r8d, %r8d - -.Loop: movq (%rsi,%r11,8), %rax - mulq %rcx - addq %r8, %rax - movl $0, %r8d - adcq %rdx, %r8 - movq %rax, (%rdi,%r11,8) - incq %r11 - jne .Loop - - movq %r8, %rax - ret diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul2.S deleted file mode 100644 index 1180f7602..000000000 --- a/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul2.S +++ /dev/null @@ -1,107 +0,0 @@ -/* AMD64 addmul2 -- Multiply a limb vector with a limb and add - * the result to a second limb vector. - * - * Copyright (C) 1992, 1994, 1998, - * 2001, 2002, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_addmul_2( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_size_t s1_size, (sp + 12) - * mpi_limb_t s2_limb) (sp + 16) - */ - - /* i80386 addmul_1 -- Multiply a limb vector with a limb and add - * the result to a second limb vector. - * - * Copyright (C) 1992, 1994, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (rdi) - * mpi_ptr_t s1_ptr, (rsi) - * mpi_size_t s1_size, (rdx) - * mpi_limb_t s2_limb) (rcx) - */ - TEXT - GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1) -C_SYMBOL_NAME(_gcry_mpih_addmul_1:) - movq %rdx, %r11 - leaq (%rsi,%rdx,8), %rsi - leaq (%rdi,%rdx,8), %rdi - negq %r11 - xorl %r8d, %r8d - xorl %r10d, %r10d - - ALIGN(3) /* minimal alignment for claimed speed */ -.Loop: movq (%rsi,%r11,8), %rax - mulq %rcx - addq (%rdi,%r11,8), %rax - adcq %r10, %rdx - addq %r8, %rax - movq %r10, %r8 - movq %rax, (%rdi,%r11,8) - adcq %rdx, %r8 - incq %r11 - jne .Loop - - movq %r8, %rax - ret diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul3.S deleted file mode 100644 index 4d458a794..000000000 --- a/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul3.S +++ /dev/null @@ -1,66 +0,0 @@ -/* AMD64 submul_1 -- Multiply a limb vector with a limb and add - * the result to a second limb vector. - * - * Copyright (C) 1992, 1994, 1998, - * 2001, 2002, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (rdi) - * mpi_ptr_t s1_ptr, (rsi) - * mpi_size_t s1_size, (rdx) - * mpi_limb_t s2_limb) (rcx) - */ - TEXT - GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1) -C_SYMBOL_NAME(_gcry_mpih_submul_1:) - - movq %rdx, %r11 - leaq (%rsi,%r11,8), %rsi - leaq (%rdi,%r11,8), %rdi - negq %r11 - xorl %r8d, %r8d - - ALIGN(3) /* minimal alignment for claimed speed */ -.Loop: movq (%rsi,%r11,8), %rax - movq (%rdi,%r11,8), %r10 - mulq %rcx - subq %r8, %r10 - movl $0, %r8d - adcl %r8d, %r8d - subq %rax, %r10 - adcq %rdx, %r8 - movq %r10, (%rdi,%r11,8) - incq %r11 - jne .Loop - - movq %r8, %rax - ret diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-rshift.S deleted file mode 100644 index 4cfc8f602..000000000 --- a/grub-core/lib/libgcrypt/mpi/amd64/mpih-rshift.S +++ /dev/null @@ -1,80 +0,0 @@ -/* AMD64 (x86_64) rshift -- Right shift a limb vector and store - * result in a second limb vector. - * - * Copyright (C) 1992, 1994, 1995, 1998, - * 2001, 2002, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - -/******************* - * mpi_limb_t - * _gcry_mpih_rshift( mpi_ptr_t wp, rdi - * mpi_ptr_t up, rsi - * mpi_size_t usize, rdx - * unsigned cnt) rcx - */ - -.text - .globl C_SYMBOL_NAME(_gcry_mpih_rshift) -C_SYMBOL_NAME(_gcry_mpih_rshift:) - movq (%rsi), %mm7 - movd %ecx, %mm1 - movl $64, %eax - subl %ecx, %eax - movd %eax, %mm0 - movq %mm7, %mm3 - psllq %mm0, %mm7 - movd %mm7, %rax - leaq (%rsi,%rdx,8), %rsi - leaq (%rdi,%rdx,8), %rdi - negq %rdx - addq $2, %rdx - jg .Lendo - - ALIGN(8) /* minimal alignment for claimed speed */ -.Loop: movq -8(%rsi,%rdx,8), %mm6 - movq %mm6, %mm2 - psllq %mm0, %mm6 - psrlq %mm1, %mm3 - por %mm6, %mm3 - movq %mm3, -16(%rdi,%rdx,8) - je .Lende - movq (%rsi,%rdx,8), %mm7 - movq %mm7, %mm3 - psllq %mm0, %mm7 - psrlq %mm1, %mm2 - por %mm7, %mm2 - movq %mm2, -8(%rdi,%rdx,8) - addq $2, %rdx - jle .Loop - -.Lendo: movq %mm3, %mm2 -.Lende: psrlq %mm1, %mm2 - movq %mm2, -8(%rdi) - emms - ret diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-sub1.S deleted file mode 100644 index b3609b024..000000000 --- a/grub-core/lib/libgcrypt/mpi/amd64/mpih-sub1.S +++ /dev/null @@ -1,61 +0,0 @@ -/* AMD64 (x86_64) sub_n -- Subtract two limb vectors of the same length > 0 and store - * sum in a third limb vector. - * - * Copyright (C) 1992, 1994, 1995, 1998, - * 2001, 2002, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, rdi - * mpi_ptr_t s1_ptr, rsi - * mpi_ptr_t s2_ptr, rdx - * mpi_size_t size) rcx - */ -.text - .globl C_SYMBOL_NAME(_gcry_mpih_sub_n) -C_SYMBOL_NAME(_gcry_mpih_sub_n:) - leaq (%rsi,%rcx,8), %rsi - leaq (%rdi,%rcx,8), %rdi - leaq (%rdx,%rcx,8), %rdx - negq %rcx - xorl %eax, %eax /* clear cy */ - - ALIGN(4) /* minimal alignment for claimed speed */ -.Loop: movq (%rsi,%rcx,8), %rax - movq (%rdx,%rcx,8), %r10 - sbbq %r10, %rax - movq %rax, (%rdi,%rcx,8) - incq %rcx - jne .Loop - - movq %rcx, %rax /* zero %rax */ - adcq %rax, %rax - ret diff --git a/grub-core/lib/libgcrypt/mpi/config.links b/grub-core/lib/libgcrypt/mpi/config.links deleted file mode 100644 index 7e910ee37..000000000 --- a/grub-core/lib/libgcrypt/mpi/config.links +++ /dev/null @@ -1,360 +0,0 @@ -# config.links - helper for ../configure -*- mode: sh -*- -# Copyright (C) 1998, 1999, 2000, 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 -# -# sourced by ../configure to get the list of files to link -# this should set $mpi_ln_list. -# Note: this is called from the above directory. - -mpi_sflags= -mpi_extra_modules= - -test -d ./mpi || mkdir ./mpi - -# We grep the list of modules from the Makefile so that -# we don't need to maintain them here. -mpi_standard_modules=`$AWK '/^#BEGIN_ASM_LIST/,/^#END_ASM_LIST/ { - if( $3 != "O" ) print $2 }' $srcdir/mpi/Makefile.am` -mpi_optional_modules=`$AWK '/^#BEGIN_ASM_LIST/,/^#END_ASM_LIST/ { - if( $3 == "O" ) print $2 }' $srcdir/mpi/Makefile.am` - - -echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h -echo "/* Host: ${host} */" >>./mpi/asm-syntax.h - -if test "$try_asm_modules" = "yes" ; then -case "${host}" in - powerpc-apple-darwin* | \ - i[34567]86*-*-openbsd[12]* | \ - i[34567]86*-*-openbsd3.[0123]*) - echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h - path="" - ;; - i[3467]86*-*-openbsd* | \ - i[3467]86*-*-freebsd*-elf | \ - i[3467]86*-*-freebsd[3-9]* | \ - i[3467]86*-*-freebsdelf* | \ - i[3467]86*-*-netbsd* | \ - i[3467]86*-*-k*bsd*) - echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h - path="i386" - ;; - i586*-*-openbsd* | \ - i586*-*-freebsd*-elf | \ - i586*-*-freebsd[3-9]* | \ - i586*-*-freebsdelf* | \ - i586*-*-netbsd* | \ - i586*-*-k*bsd* | \ - pentium-*-netbsd* | \ - pentiumpro-*-netbsd*) - echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h - path="i586 i386" - ;; - i[34]86*-*-bsdi4*) - echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h - path="i386" - ;; - i[3467]86*-*-linuxaout* | \ - i[3467]86*-*-linuxoldld* | \ - i[3467]86*-*-*bsd*) - echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h - echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h - cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h - path="i386" - ;; - i586*-*-linuxaout* | \ - i586*-*-linuxoldld* | \ - i586*-*-*bsd*) - echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h - echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h - cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h - path="i586 i386" - ;; - i[3467]86*-msdosdjgpp* | \ - i[34]86*-apple-darwin*) - echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h - path="i386" - ;; - i586*-msdosdjgpp* | \ - i[567]86*-apple-darwin*) - echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h - path="i586 i386" - ;; - i[3467]86*-*-*) - echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h - path="i386" - ;; - i586*-*-* | \ - pentium-*-* | \ - pentiumpro-*-*) - echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h - path="i586 i386" - ;; - x86_64-*-*) - echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h - path="amd64" - ;; - alpha*-*-*) - echo '/* configured for alpha */' >>./mpi/asm-syntax.h - path="alpha" - mpi_extra_modules="udiv-qrnnd" - ;; - hppa7000*-*-*) - echo '/* configured for HPPA (pa7000) */' >>./mpi/asm-syntax.h - path="hppa1.1 hppa" - mpi_extra_modules="udiv-qrnnd" - ;; - hppa1.0*-*-*) - echo '/* configured for HPPA 1.0 */' >>./mpi/asm-syntax.h - path="hppa" - mpi_extra_modules="udiv-qrnnd" - ;; - hppa*-*-*) # assume pa7100 - echo '/* configured for HPPA (pa7100) */' >>./mpi/asm-syntax.h - path="pa7100 hppa1.1 hppa" - mpi_extra_modules="udiv-qrnnd" - ;; - sparc64-*-linux-gnu) - echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h - path="" - ;; - sparc64-sun-solaris2*) - echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h - path="" - ;; - sparc64-*-netbsd* | sparc64-*-freebsd* | sparc64-*-openbsd*) - # There are no sparc64 assembler modules that work on the - # *BSDs, so use the generic C functions. - echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h - path="" - ;; - sparc64*-*-*) - echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h - path="" - ;; - sparc9*-*-* | \ - ultrasparc*-*-* ) - echo '/* configured for sparc9 or higher */' >>./mpi/asm-syntax.h - path="sparc32v8 sparc32" - ;; - sparc8*-*-* | \ - microsparc*-*-*) - echo '/* configured for sparc8 */' >>./mpi/asm-syntax.h - path="sparc32v8 sparc32" - ;; - supersparc*-*-*) - echo '/* configured for supersparc */' >>./mpi/asm-syntax.h - path="supersparc sparc32v8 sparc32" - mpi_extra_modules="udiv" - ;; - sparc*-*-*) - echo '/* configured for sparc */' >>./mpi/asm-syntax.h - path="sparc32" - mpi_extra_modules="udiv" - ;; - mips[34]*-*-* | \ - mips*-*-irix6*) - echo '/* configured for MIPS3 */' >>./mpi/asm-syntax.h - path="mips3" - ;; - mips*-*-*) - echo '/* configured for MIPS2 */' >>./mpi/asm-syntax.h - path="mips2" - ;; - - # Motorola 68k configurations. Let m68k mean 68020-68040. - # mc68000 or mc68060 configurations need to be specified explicitly - m680[234]0*-*-linuxaout* | \ - m68k*-*-linuxaout*) - echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h - path="m68k/mc68020 m68k" - ;; - m68060*-*-linuxaout*) - echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h - path="m68k" - ;; - m680[234]0*-*-linux* | \ - m68k*-*-linux*) - echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h - ;; - m68060*-*-linux*) - echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h - path="m68k" - ;; - m68k-atari-mint) - echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h - path="m68k/mc68020 m68k" - ;; - m68000*-*-* | \ - m68060*-*-*) - echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h - path="m68k/mc68000" - ;; - m680[234]0*-*-* | \ - m68k*-*-*) - echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h - path="m68k/mc68020 m68k" - ;; - - powerpc*-*-netbsd* | powerpc*-*-openbsd*) - echo '/* configured {Open,Net}BSD on powerpc */' >>./mpi/asm-syntax.h - echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h - mpi_sflags="-Wa,-mppc" - path="powerpc32" - ;; - - ppc620-*-* | \ - powerpc64*-*-*) - mpi_sflags="-Wa,-mppc" - path="powerpc64" - ;; - powerpc*-*-linux*) - echo '/* configured for powerpc/ELF */' >>./mpi/asm-syntax.h - echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h - cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h - path="powerpc32" - ;; - - rs6000-*-aix[456789]* | \ - rs6000-*-aix3.2.[456789]) - mpi_sflags="-Wa,-mpwr" - path="power" - mpi_extra_modules="udiv-w-sdiv" - ;; - rs6000-*-* | \ - power-*-* | \ - power2-*-*) - mpi_sflags="-Wa,-mppc" - path="power" - mpi_extra_modules="udiv-w-sdiv" - ;; - powerpc-ibm-aix4.2.* ) - # I am not sure about this one but a machine identified by - # powerpc-ibm-aix4.2.1.0 cannot use the powerpc32 code. - mpi_sflags="-Wa,-mpwr" - path="power" - mpi_extra_modules="udiv-w-sdiv" - ;; - ppc601-*-*) - mpi_sflags="-Wa,-mppc" - path="power powerpc32" - ;; - ppc60[234]*-*-*) - mpi_sflags="-Wa,-mppc" - path="powerpc32" - ;; - powerpc*-*-*) - mpi_sflags="-Wa,-mppc" - path="powerpc32" - ;; - *) - echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h - path="" - ;; -esac -else - echo '/* Assembler modules disabled on request */' >>./mpi/asm-syntax.h - path="" -fi - - -# Make sysdep.h -echo '/* created by config.links - do not edit */' >./mpi/sysdep.h -if test x$ac_cv_sys_symbol_underscore = xyes; then - cat <>./mpi/sysdep.h -#if __STDC__ -#define C_SYMBOL_NAME(name) _##name -#else -#define C_SYMBOL_NAME(name) _/**/name -#endif -EOF -else - cat <>./mpi/sysdep.h -#define C_SYMBOL_NAME(name) name -EOF -fi - - -# Figure the required modules out -mpi_required_modules=$mpi_standard_modules -if test "$mpi_extra_modules" != ""; then - for fn in $mpi_extra_modules; do - for i in $mpi_optional_modules; do - if test "$fn" = "$i" ; then - mpi_required_modules="$mpi_required_modules $fn" - fi - done - done -fi - -# Try to get file to link from the assembler subdirectory and -# if this fails get it from the generic subdirectory. -mpi_ln_list= -mpi_mod_list= -path=`echo "$mpi_extra_path $path generic" | tr ':' ' '` -echo '/* Created by config.links - do not edit */' >./mpi/mod-source-info.h -echo "/* Host: ${host} */" >>./mpi/mod-source-info.h -echo "static char mod_source_info[] =" >>./mpi/mod-source-info.h -for fn in $mpi_required_modules ; do - fnu=`echo $fn | sed 's/-/_/g'` - eval mpi_mod_c_${fnu}=no - eval mpi_mod_asm_${fnu}=no - for dir in $path ; do - rm -f $srcdir/mpi/$fn.[Sc] - if test -f $srcdir/mpi/$dir/$fn.S ; then - echo " \":$dir/$fn.S\"" >>./mpi/mod-source-info.h - mpi_ln_list="$mpi_ln_list mpi/$fn-asm.S:mpi/$dir/$fn.S" - eval mpi_mod_asm_${fnu}=yes - mpi_mod_list="$mpi_mod_list $fn" - break; - elif test -f $srcdir/mpi/$dir/$fn.c ; then - echo " \":$dir/$fn.c\"" >>./mpi/mod-source-info.h - mpi_ln_list="$mpi_ln_list mpi/$fn.c:mpi/$dir/$fn.c" - eval mpi_mod_c_${fnu}=yes - mpi_mod_list="$mpi_mod_list $fn" - break; - fi - done -done -echo " ;" >>./mpi/mod-source-info.h - -# Same thing for the file which defines the limb size -path=`echo "$path generic" | tr ':' ' '` -for dir in $path ; do - rm -f $srcdir/mpi/mpi-asm-defs.h - if test -f $srcdir/mpi/$dir/mpi-asm-defs.h ; then - mpi_ln_list="$mpi_ln_list mpi/mpi-asm-defs.h:mpi/$dir/mpi-asm-defs.h" - break; - fi -done diff --git a/grub-core/lib/libgcrypt/mpi/ec.c b/grub-core/lib/libgcrypt/mpi/ec.c deleted file mode 100644 index fa00818fe..000000000 --- a/grub-core/lib/libgcrypt/mpi/ec.c +++ /dev/null @@ -1,721 +0,0 @@ -/* ec.c - Elliptic Curve functions - 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 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. */ - - -#include -#include -#include - -#include "mpi-internal.h" -#include "longlong.h" -#include "g10lib.h" - - -#define point_init(a) _gcry_mpi_ec_point_init ((a)) -#define point_free(a) _gcry_mpi_ec_point_free ((a)) - - -/* Object to represent a point in projective coordinates. */ -/* Currently defined in mpi.h */ - -/* This context is used with all our EC functions. */ -struct mpi_ec_ctx_s -{ - /* Domain parameters. */ - gcry_mpi_t p; /* Prime specifying the field GF(p). */ - gcry_mpi_t a; /* First coefficient of the Weierstrass equation. */ - - int a_is_pminus3; /* True if A = P - 3. */ - - /* Some often used constants. */ - gcry_mpi_t one; - gcry_mpi_t two; - gcry_mpi_t three; - gcry_mpi_t four; - gcry_mpi_t eight; - gcry_mpi_t two_inv_p; - - /* Scratch variables. */ - gcry_mpi_t scratch[11]; - - /* Helper for fast reduction. */ -/* int nist_nbits; /\* If this is a NIST curve, the number of bits. *\/ */ -/* gcry_mpi_t s[10]; */ -/* gcry_mpi_t c; */ - -}; - - - -/* Initialized a point object. gcry_mpi_ec_point_free shall be used - to release this object. */ -void -_gcry_mpi_ec_point_init (mpi_point_t *p) -{ - p->x = mpi_new (0); - p->y = mpi_new (0); - p->z = mpi_new (0); -} - - -/* Release a point object. */ -void -_gcry_mpi_ec_point_free (mpi_point_t *p) -{ - mpi_free (p->x); p->x = NULL; - mpi_free (p->y); p->y = NULL; - mpi_free (p->z); p->z = NULL; -} - -/* 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); -} - - - -static void -ec_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx) -{ - mpi_addm (w, u, v, ctx->p); -} - -static void -ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx) -{ - mpi_subm (w, u, v, ctx->p); -} - -static void -ec_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx) -{ -#if 0 - /* NOTE: This code works only for limb sizes of 32 bit. */ - mpi_limb_t *wp, *sp; - - if (ctx->nist_nbits == 192) - { - mpi_mul (w, u, v); - mpi_resize (w, 12); - wp = w->d; - - sp = ctx->s[0]->d; - sp[0*2+0] = wp[0*2+0]; - sp[0*2+1] = wp[0*2+1]; - sp[1*2+0] = wp[1*2+0]; - sp[1*2+1] = wp[1*2+1]; - sp[2*2+0] = wp[2*2+0]; - sp[2*2+1] = wp[2*2+1]; - - sp = ctx->s[1]->d; - sp[0*2+0] = wp[3*2+0]; - sp[0*2+1] = wp[3*2+1]; - sp[1*2+0] = wp[3*2+0]; - sp[1*2+1] = wp[3*2+1]; - sp[2*2+0] = 0; - sp[2*2+1] = 0; - - sp = ctx->s[2]->d; - sp[0*2+0] = 0; - sp[0*2+1] = 0; - sp[1*2+0] = wp[4*2+0]; - sp[1*2+1] = wp[4*2+1]; - sp[2*2+0] = wp[4*2+0]; - sp[2*2+1] = wp[4*2+1]; - - sp = ctx->s[3]->d; - sp[0*2+0] = wp[5*2+0]; - sp[0*2+1] = wp[5*2+1]; - sp[1*2+0] = wp[5*2+0]; - sp[1*2+1] = wp[5*2+1]; - sp[2*2+0] = wp[5*2+0]; - sp[2*2+1] = wp[5*2+1]; - - ctx->s[0]->nlimbs = 6; - ctx->s[1]->nlimbs = 6; - ctx->s[2]->nlimbs = 6; - ctx->s[3]->nlimbs = 6; - - mpi_add (ctx->c, ctx->s[0], ctx->s[1]); - mpi_add (ctx->c, ctx->c, ctx->s[2]); - mpi_add (ctx->c, ctx->c, ctx->s[3]); - - while ( mpi_cmp (ctx->c, ctx->p ) >= 0 ) - mpi_sub ( ctx->c, ctx->c, ctx->p ); - mpi_set (w, ctx->c); - } - else if (ctx->nist_nbits == 384) - { - int i; - mpi_mul (w, u, v); - mpi_resize (w, 24); - wp = w->d; - -#define NEXT(a) do { ctx->s[(a)]->nlimbs = 12; \ - sp = ctx->s[(a)]->d; \ - i = 0; } while (0) -#define X(a) do { sp[i++] = wp[(a)];} while (0) -#define X0(a) do { sp[i++] = 0; } while (0) - NEXT(0); - X(0);X(1);X(2);X(3);X(4);X(5);X(6);X(7);X(8);X(9);X(10);X(11); - NEXT(1); - X0();X0();X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0(); - NEXT(2); - X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22);X(23); - NEXT(3); - X(21);X(22);X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20); - NEXT(4); - X0();X(23);X0();X(20);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19); - NEXT(5); - X0();X0();X0();X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0(); - NEXT(6); - X(20);X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0();X0(); - NEXT(7); - X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22); - NEXT(8); - X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0();X0();X0();X0(); - NEXT(9); - X0();X0();X0();X(23);X(23);X0();X0();X0();X0();X0();X0();X0(); -#undef X0 -#undef X -#undef NEXT - mpi_add (ctx->c, ctx->s[0], ctx->s[1]); - mpi_add (ctx->c, ctx->c, ctx->s[1]); - mpi_add (ctx->c, ctx->c, ctx->s[2]); - mpi_add (ctx->c, ctx->c, ctx->s[3]); - mpi_add (ctx->c, ctx->c, ctx->s[4]); - mpi_add (ctx->c, ctx->c, ctx->s[5]); - mpi_add (ctx->c, ctx->c, ctx->s[6]); - mpi_sub (ctx->c, ctx->c, ctx->s[7]); - mpi_sub (ctx->c, ctx->c, ctx->s[8]); - mpi_sub (ctx->c, ctx->c, ctx->s[9]); - - while ( mpi_cmp (ctx->c, ctx->p ) >= 0 ) - mpi_sub ( ctx->c, ctx->c, ctx->p ); - while ( ctx->c->sign ) - mpi_add ( ctx->c, ctx->c, ctx->p ); - mpi_set (w, ctx->c); - } - else -#endif /*0*/ - mpi_mulm (w, u, v, ctx->p); -} - -static void -ec_powm (gcry_mpi_t w, const gcry_mpi_t b, const gcry_mpi_t e, - mpi_ec_t ctx) -{ - mpi_powm (w, b, e, ctx->p); -} - -static void -ec_invm (gcry_mpi_t x, gcry_mpi_t a, mpi_ec_t ctx) -{ - mpi_invm (x, a, ctx->p); -} - - - -/* This function returns a new context for elliptic curve based on the - field GF(p). P is the prime specifying thuis field, A is the first - coefficient. - - This context needs to be released using _gcry_mpi_ec_free. */ -mpi_ec_t -_gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a) -{ - int i; - mpi_ec_t ctx; - gcry_mpi_t tmp; - - mpi_normalize (p); - mpi_normalize (a); - - /* Fixme: Do we want to check some constraints? e.g. - a < p - */ - - ctx = gcry_xcalloc (1, sizeof *ctx); - - ctx->p = mpi_copy (p); - ctx->a = mpi_copy (a); - - tmp = mpi_alloc_like (ctx->p); - mpi_sub_ui (tmp, ctx->p, 3); - ctx->a_is_pminus3 = !mpi_cmp (ctx->a, tmp); - mpi_free (tmp); - - - /* Allocate constants. */ - ctx->one = mpi_alloc_set_ui (1); - ctx->two = mpi_alloc_set_ui (2); - ctx->three = mpi_alloc_set_ui (3); - ctx->four = mpi_alloc_set_ui (4); - ctx->eight = mpi_alloc_set_ui (8); - ctx->two_inv_p = mpi_alloc (0); - ec_invm (ctx->two_inv_p, ctx->two, ctx); - - /* Allocate scratch variables. */ - for (i=0; i< DIM(ctx->scratch); i++) - ctx->scratch[i] = mpi_alloc_like (ctx->p); - - /* Prepare for fast reduction. */ - /* FIXME: need a test for NIST values. However it does not gain us - any real advantage, for 384 bits it is actually slower than using - mpi_mulm. */ -/* ctx->nist_nbits = mpi_get_nbits (ctx->p); */ -/* if (ctx->nist_nbits == 192) */ -/* { */ -/* for (i=0; i < 4; i++) */ -/* ctx->s[i] = mpi_new (192); */ -/* ctx->c = mpi_new (192*2); */ -/* } */ -/* else if (ctx->nist_nbits == 384) */ -/* { */ -/* for (i=0; i < 10; i++) */ -/* ctx->s[i] = mpi_new (384); */ -/* ctx->c = mpi_new (384*2); */ -/* } */ - - return ctx; -} - -void -_gcry_mpi_ec_free (mpi_ec_t ctx) -{ - int i; - - if (!ctx) - return; - - mpi_free (ctx->p); - mpi_free (ctx->a); - - mpi_free (ctx->one); - mpi_free (ctx->two); - mpi_free (ctx->three); - mpi_free (ctx->four); - mpi_free (ctx->eight); - - mpi_free (ctx->two_inv_p); - - for (i=0; i< DIM(ctx->scratch); i++) - mpi_free (ctx->scratch[i]); - -/* if (ctx->nist_nbits == 192) */ -/* { */ -/* for (i=0; i < 4; i++) */ -/* mpi_free (ctx->s[i]); */ -/* mpi_free (ctx->c); */ -/* } */ -/* else if (ctx->nist_nbits == 384) */ -/* { */ -/* for (i=0; i < 10; i++) */ -/* mpi_free (ctx->s[i]); */ -/* mpi_free (ctx->c); */ -/* } */ - - gcry_free (ctx); -} - -/* Compute the affine coordinates from the projective coordinates in - POINT. Set them into X and Y. If one coordinate is not required, - X or Y may be passed as NULL. CTX is the usual context. Returns: 0 - on success or !0 if POINT is at infinity. */ -int -_gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point, - mpi_ec_t ctx) -{ - gcry_mpi_t z1, z2, z3; - - if (!mpi_cmp_ui (point->z, 0)) - return -1; - - z1 = mpi_new (0); - z2 = mpi_new (0); - ec_invm (z1, point->z, ctx); /* z1 = z^(-1) mod p */ - ec_mulm (z2, z1, z1, ctx); /* z2 = z^(-2) mod p */ - - if (x) - ec_mulm (x, point->x, z2, ctx); - - if (y) - { - z3 = mpi_new (0); - ec_mulm (z3, z2, z1, ctx); /* z3 = z^(-3) mod p */ - ec_mulm (y, point->y, z3, ctx); - mpi_free (z3); - } - - mpi_free (z2); - mpi_free (z1); - return 0; -} - - - - - -/* RESULT = 2 * POINT */ -void -_gcry_mpi_ec_dup_point (mpi_point_t *result, mpi_point_t *point, mpi_ec_t ctx) -{ -#define x3 (result->x) -#define y3 (result->y) -#define z3 (result->z) -#define t1 (ctx->scratch[0]) -#define t2 (ctx->scratch[1]) -#define t3 (ctx->scratch[2]) -#define l1 (ctx->scratch[3]) -#define l2 (ctx->scratch[4]) -#define l3 (ctx->scratch[5]) - - if (!mpi_cmp_ui (point->y, 0) || !mpi_cmp_ui (point->z, 0)) - { - /* P_y == 0 || P_z == 0 => [1:1:0] */ - mpi_set_ui (x3, 1); - mpi_set_ui (y3, 1); - mpi_set_ui (z3, 0); - } - else - { - if (ctx->a_is_pminus3) /* Use the faster case. */ - { - /* L1 = 3(X - Z^2)(X + Z^2) */ - /* T1: used for Z^2. */ - /* T2: used for the right term. */ - ec_powm (t1, point->z, ctx->two, ctx); - ec_subm (l1, point->x, t1, ctx); - ec_mulm (l1, l1, ctx->three, ctx); - ec_addm (t2, point->x, t1, ctx); - ec_mulm (l1, l1, t2, ctx); - } - else /* Standard case. */ - { - /* L1 = 3X^2 + aZ^4 */ - /* T1: used for aZ^4. */ - ec_powm (l1, point->x, ctx->two, ctx); - ec_mulm (l1, l1, ctx->three, ctx); - ec_powm (t1, point->z, ctx->four, ctx); - ec_mulm (t1, t1, ctx->a, ctx); - ec_addm (l1, l1, t1, ctx); - } - /* Z3 = 2YZ */ - ec_mulm (z3, point->y, point->z, ctx); - ec_mulm (z3, z3, ctx->two, ctx); - - /* L2 = 4XY^2 */ - /* T2: used for Y2; required later. */ - ec_powm (t2, point->y, ctx->two, ctx); - ec_mulm (l2, t2, point->x, ctx); - ec_mulm (l2, l2, ctx->four, ctx); - - /* X3 = L1^2 - 2L2 */ - /* T1: used for L2^2. */ - ec_powm (x3, l1, ctx->two, ctx); - ec_mulm (t1, l2, ctx->two, ctx); - ec_subm (x3, x3, t1, ctx); - - /* L3 = 8Y^4 */ - /* T2: taken from above. */ - ec_powm (t2, t2, ctx->two, ctx); - ec_mulm (l3, t2, ctx->eight, ctx); - - /* Y3 = L1(L2 - X3) - L3 */ - ec_subm (y3, l2, x3, ctx); - ec_mulm (y3, y3, l1, ctx); - ec_subm (y3, y3, l3, ctx); - } - -#undef x3 -#undef y3 -#undef z3 -#undef t1 -#undef t2 -#undef t3 -#undef l1 -#undef l2 -#undef l3 -} - - - -/* RESULT = P1 + P2 */ -void -_gcry_mpi_ec_add_points (mpi_point_t *result, - mpi_point_t *p1, mpi_point_t *p2, - mpi_ec_t ctx) -{ -#define x1 (p1->x ) -#define y1 (p1->y ) -#define z1 (p1->z ) -#define x2 (p2->x ) -#define y2 (p2->y ) -#define z2 (p2->z ) -#define x3 (result->x) -#define y3 (result->y) -#define z3 (result->z) -#define l1 (ctx->scratch[0]) -#define l2 (ctx->scratch[1]) -#define l3 (ctx->scratch[2]) -#define l4 (ctx->scratch[3]) -#define l5 (ctx->scratch[4]) -#define l6 (ctx->scratch[5]) -#define l7 (ctx->scratch[6]) -#define l8 (ctx->scratch[7]) -#define l9 (ctx->scratch[8]) -#define t1 (ctx->scratch[9]) -#define t2 (ctx->scratch[10]) - - if ( (!mpi_cmp (x1, x2)) && (!mpi_cmp (y1, y2)) && (!mpi_cmp (z1, z2)) ) - { - /* Same point; need to call the duplicate function. */ - _gcry_mpi_ec_dup_point (result, p1, ctx); - } - else if (!mpi_cmp_ui (z1, 0)) - { - /* P1 is at infinity. */ - mpi_set (x3, p2->x); - mpi_set (y3, p2->y); - mpi_set (z3, p2->z); - } - else if (!mpi_cmp_ui (z2, 0)) - { - /* P2 is at infinity. */ - mpi_set (x3, p1->x); - mpi_set (y3, p1->y); - mpi_set (z3, p1->z); - } - else - { - int z1_is_one = !mpi_cmp_ui (z1, 1); - int z2_is_one = !mpi_cmp_ui (z2, 1); - - /* l1 = x1 z2^2 */ - /* l2 = x2 z1^2 */ - if (z2_is_one) - mpi_set (l1, x1); - else - { - ec_powm (l1, z2, ctx->two, ctx); - ec_mulm (l1, l1, x1, ctx); - } - if (z1_is_one) - mpi_set (l2, x2); - else - { - ec_powm (l2, z1, ctx->two, ctx); - ec_mulm (l2, l2, x2, ctx); - } - /* l3 = l1 - l2 */ - ec_subm (l3, l1, l2, ctx); - /* l4 = y1 z2^3 */ - ec_powm (l4, z2, ctx->three, ctx); - ec_mulm (l4, l4, y1, ctx); - /* l5 = y2 z1^3 */ - ec_powm (l5, z1, ctx->three, ctx); - ec_mulm (l5, l5, y2, ctx); - /* l6 = l4 - l5 */ - ec_subm (l6, l4, l5, ctx); - - if (!mpi_cmp_ui (l3, 0)) - { - if (!mpi_cmp_ui (l6, 0)) - { - /* P1 and P2 are the same - use duplicate function. */ - _gcry_mpi_ec_dup_point (result, p1, ctx); - } - else - { - /* P1 is the inverse of P2. */ - mpi_set_ui (x3, 1); - mpi_set_ui (y3, 1); - mpi_set_ui (z3, 0); - } - } - else - { - /* l7 = l1 + l2 */ - ec_addm (l7, l1, l2, ctx); - /* l8 = l4 + l5 */ - ec_addm (l8, l4, l5, ctx); - /* z3 = z1 z2 l3 */ - ec_mulm (z3, z1, z2, ctx); - ec_mulm (z3, z3, l3, ctx); - /* x3 = l6^2 - l7 l3^2 */ - ec_powm (t1, l6, ctx->two, ctx); - ec_powm (t2, l3, ctx->two, ctx); - ec_mulm (t2, t2, l7, ctx); - ec_subm (x3, t1, t2, ctx); - /* l9 = l7 l3^2 - 2 x3 */ - ec_mulm (t1, x3, ctx->two, ctx); - ec_subm (l9, t2, t1, ctx); - /* y3 = (l9 l6 - l8 l3^3)/2 */ - ec_mulm (l9, l9, l6, ctx); - ec_powm (t1, l3, ctx->three, ctx); /* fixme: Use saved value*/ - ec_mulm (t1, t1, l8, ctx); - ec_subm (y3, l9, t1, ctx); - ec_mulm (y3, y3, ctx->two_inv_p, ctx); - } - } - -#undef x1 -#undef y1 -#undef z1 -#undef x2 -#undef y2 -#undef z2 -#undef x3 -#undef y3 -#undef z3 -#undef l1 -#undef l2 -#undef l3 -#undef l4 -#undef l5 -#undef l6 -#undef l7 -#undef l8 -#undef l9 -#undef t1 -#undef t2 -} - - - -/* Scalar point multiplication - the main function for ECC. If takes - an integer SCALAR and a POINT as well as the usual context CTX. - RESULT will be set to the resulting point. */ -void -_gcry_mpi_ec_mul_point (mpi_point_t *result, - gcry_mpi_t scalar, mpi_point_t *point, - mpi_ec_t ctx) -{ -#if 0 - /* Simple left to right binary method. GECC Algorithm 3.27 */ - unsigned int nbits; - int i; - - nbits = mpi_get_nbits (scalar); - mpi_set_ui (result->x, 1); - mpi_set_ui (result->y, 1); - mpi_set_ui (result->z, 0); - - for (i=nbits-1; i >= 0; i--) - { - _gcry_mpi_ec_dup_point (result, result, ctx); - if (mpi_test_bit (scalar, i) == 1) - _gcry_mpi_ec_add_points (result, result, point, ctx); - } - -#else - gcry_mpi_t x1, y1, z1, k, h, yy; - unsigned int i, loops; - mpi_point_t p1, p2, p1inv; - - x1 = mpi_alloc_like (ctx->p); - y1 = mpi_alloc_like (ctx->p); - h = mpi_alloc_like (ctx->p); - k = mpi_copy (scalar); - yy = mpi_copy (point->y); - - if ( mpi_is_neg (k) ) - { - k->sign = 0; - ec_invm (yy, yy, ctx); - } - - if (!mpi_cmp_ui (point->z, 1)) - { - mpi_set (x1, point->x); - mpi_set (y1, yy); - } - else - { - gcry_mpi_t z2, z3; - - z2 = mpi_alloc_like (ctx->p); - z3 = mpi_alloc_like (ctx->p); - ec_mulm (z2, point->z, point->z, ctx); - ec_mulm (z3, point->z, z2, ctx); - ec_invm (z2, z2, ctx); - ec_mulm (x1, point->x, z2, ctx); - ec_invm (z3, z3, ctx); - ec_mulm (y1, yy, z3, ctx); - mpi_free (z2); - mpi_free (z3); - } - z1 = mpi_copy (ctx->one); - - mpi_mul (h, k, ctx->three); /* h = 3k */ - loops = mpi_get_nbits (h); - if (loops < 2) - { - /* If SCALAR is zero, the above mpi_mul sets H to zero and thus - LOOPs will be zero. To avoid an underflow of I in the main - loop we set LOOP to 2 and the result to (0,0,0). */ - loops = 2; - mpi_clear (result->x); - mpi_clear (result->y); - mpi_clear (result->z); - } - else - { - mpi_set (result->x, point->x); - mpi_set (result->y, yy); - mpi_set (result->z, point->z); - } - mpi_free (yy); yy = NULL; - - p1.x = x1; x1 = NULL; - p1.y = y1; y1 = NULL; - p1.z = z1; z1 = NULL; - point_init (&p2); - point_init (&p1inv); - - for (i=loops-2; i > 0; i--) - { - _gcry_mpi_ec_dup_point (result, result, ctx); - if (mpi_test_bit (h, i) == 1 && mpi_test_bit (k, i) == 0) - { - point_set (&p2, result); - _gcry_mpi_ec_add_points (result, &p2, &p1, ctx); - } - if (mpi_test_bit (h, i) == 0 && mpi_test_bit (k, i) == 1) - { - point_set (&p2, result); - /* Invert point: y = p - y mod p */ - point_set (&p1inv, &p1); - ec_subm (p1inv.y, ctx->p, p1inv.y, ctx); - _gcry_mpi_ec_add_points (result, &p2, &p1inv, ctx); - } - } - - point_free (&p1); - point_free (&p2); - point_free (&p1inv); - mpi_free (h); - mpi_free (k); -#endif -} diff --git a/grub-core/lib/libgcrypt/mpi/generic/Manifest b/grub-core/lib/libgcrypt/mpi/generic/Manifest deleted file mode 100644 index c429fde72..000000000 --- a/grub-core/lib/libgcrypt/mpi/generic/Manifest +++ /dev/null @@ -1,29 +0,0 @@ -# Manifest - checksums -# Copyright 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 - -mpih-add1.c iQCVAwUAP+Lj2DEAnp832S/7AQKn/AQAwQLWggl6zNQ5EZ+lE+jKV8W3FsogW3/6tp9T5rrSR5JnlWyoHQ9/Pu4knOcLjS6nIfVOiAEifu3nuIysQr9jDSSSJA2LylSUBSXKLKDamPsOCwXOLxiZODslJT3CCGAUtLvXJrWDbTZQrkEuwnLnjQFDzuA7iY9JLrG9kAoXD6Q==WoWm -mpih-mul1.c iQCVAwUAP+LkCTEAnp832S/7AQKFVQP+MhBNjcY73JtnsHZfnaVZq3TiKwN151cWV51nDc1RnTaMhSIFeuNlj3vNML2W0Gn8n+GnyiWE2XXdQEaik6BL02eekUn9aq7I/rdpnTHuOjQPK1uwjuNl8RuJ9YrERBAxq4oB71f+iwMab8dsMSUlVC+NdeAocRqLLgnR/efkdLc==2Tkb -mpih-mul2.c iQCVAwUAP+LkMjEAnp832S/7AQLPeAQAqmRzxFe/mDqTdZr/pTXT8RVyB1vKB0Ei2THV05BxmI4OPv39uysfFpLMt/INsX7AGqdOlj4jOZ/qNaFXR1ceMrlSXvo8u/epk6rCXFp82kM7Qs983LjoP//PrMCkYkXwblaVrgUGiBUCbuPMliWTK6qKkxxXtEfqZ7nVbEWdBx8==Kwhl -mpih-mul3.c iQCVAwUAP+LkVDEAnp832S/7AQL91gP/Qd5iZWxRiN5DdEIVHAedoNvl23NPrT2UUdXvnSK49DpplTxkLiMBj0WqCayG/YIET2NpMRCeLvAZNcSt6lOm0bSZDYo1Hv/N+UoqD3V1McjY16REBv/nnPaMWMZcx7rl5yKTVZiX2PgV6oQOL7Yfrt5ZIOlrHBRs9S2/zcCaVz0==9BQe -mpih-lshift.c iQCVAwUAP+LlATEAnp832S/7AQIACAQAhMrpx0SRXE/LN1NkjMO9n74nMrvmzYJyru0gw2O4BYrUPvD/LWGju2FZaggKV0IBjmi0cDoCrNeK9EGjKOO1lfgODbX2IZ1LUhr9jDuMj0QRqj6T9YkAFYTNUk4GfpwIf7T6Ybo7c78Jx93PidCJt7d39eMMEalooC7LZ4IU3NM==nZ4k -mpih-rshift.c iQCVAwUAP+LlIjEAnp832S/7AQKiuAP/eYC2ZScd+taBx/kNzRvGjA0eAXvORMkMLV6Ot+OXVzVUi04eoP2yXdxSNFKwUj12p8GWXkdoMG3aOGBKg2a7bY5Q5RUho3hUWb9UsVYVUfXLf7IOTt/3a6MLh2CmV5dFPWJmSlbCyQRcn6n/fLDeJ3A2bWTS/BhqGfpOXUIU1ws==jCf8 -mpih-sub1.c iQCVAwUAP+LlZzEAnp832S/7AQIEPgP/dLHTDRbPrYJhsLp9SjGstU1M8/IC5XytcDtO3NQeu4mx6vaXjpujtsTvKIbX4QL5IahNntVVKv1xFLEm2yFg7L2ns0uD/mfwGgOhCG1j2o/SaTAWP5KxP7ae5UDcZl2w6NWvEuMj9t32zmziAZjP8W73A37FUspeRDYiL9sQzkI==QQzk -udiv-w-sdiv.c iQCVAwUAP+Lk0TEAnp832S/7AQICXAQAsxe1SQD4+xZaZTqBC0V9Cyuo0mrdccnRFzthOtm0ARwKFXU2cuLW/ZBOkmeWOVmOFhBp22/I8dEGYnMA3gcfmOMCpNu9i9zk/XHfptdunA1MnOe3GsoWgfHL0rhpAyPhp/X043ICB41NElnnuxADuQQlD4Z1fca5ygYxMr2crJg==EI/6 -mpi-asm-defs.h iQCVAwUAP+LkgDEAnp832S/7AQK0FgQAxJZ7xvXhoZa33GWe23LRb3asrno/loZSyAIXrntqtVH8M3pEsCY0OyW4ry4hX2RnxpuhRCM/PdRNLG3xXyMSVIhkHU8WVRLqzF2LLjEkyU3cAmHnnTQ9aO/XpUWtJGTZ8q2bv7ZsAEi4aPl0p6KhPXcPgM9vQ2XcyOPn3Dl0d6Q==xpjI -$names$ iQCVAwUAP+LmNDEAnp832S/7AQJa+gP+KQNJpbNOgc+s2UX+Ya2gDaOFcAROImIllhg3ej8EaBF8xxdHmWT1zaKwTwi3moEEleykMR104YAGWyQeMbFYiuPPBW+ohrT6KxRBVJpIA9auOOqqJMyglZyoR3Hv7gduVYUW1h/DebnqiKXKEfzQDFqYuT0ayuteoOR4B5NICbE==nLSh diff --git a/grub-core/lib/libgcrypt/mpi/generic/distfiles b/grub-core/lib/libgcrypt/mpi/generic/distfiles deleted file mode 100644 index 9810eef4d..000000000 --- a/grub-core/lib/libgcrypt/mpi/generic/distfiles +++ /dev/null @@ -1,11 +0,0 @@ -Manifest -mpih-add1.c -mpih-mul1.c -mpih-mul2.c -mpih-mul3.c -mpih-lshift.c -mpih-rshift.c -mpih-sub1.c -udiv-w-sdiv.c -mpi-asm-defs.h - diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpi-asm-defs.h b/grub-core/lib/libgcrypt/mpi/generic/mpi-asm-defs.h deleted file mode 100644 index 13424e280..000000000 --- a/grub-core/lib/libgcrypt/mpi/generic/mpi-asm-defs.h +++ /dev/null @@ -1,10 +0,0 @@ -/* This file defines some basic constants for the MPI machinery. We - * need to define the types on a per-CPU basis, so it is done with - * this file here. */ -#define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG) - - - - - - diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c deleted file mode 100644 index 4ffe0eb23..000000000 --- a/grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c +++ /dev/null @@ -1,65 +0,0 @@ -/* mpihelp-add_1.c - MPI helper functions - * Copyright (C) 1994, 1996, 1997, 1998, - * 2000, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#include -#include -#include -#include "mpi-internal.h" -#include "longlong.h" - -mpi_limb_t -_gcry_mpih_add_n (mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_ptr_t s2_ptr, mpi_size_t size) -{ - mpi_limb_t x, y, cy; - mpi_size_t j; - - /* The loop counter and index J goes from -SIZE to -1. This way - the loop becomes faster. */ - j = -size; - - /* Offset the base pointers to compensate for the negative indices. */ - s1_ptr -= j; - s2_ptr -= j; - res_ptr -= j; - - cy = 0; - do - { - y = s2_ptr[j]; - x = s1_ptr[j]; - y += cy; /* add previous carry to one addend */ - cy = y < cy; /* get out carry from that addition */ - y += x; /* add other addend */ - cy += y < x; /* get out carry from that add, combine */ - res_ptr[j] = y; - } - while ( ++j ); - - return cy; -} - diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-lshift.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-lshift.c deleted file mode 100644 index 8c1d943b0..000000000 --- a/grub-core/lib/libgcrypt/mpi/generic/mpih-lshift.c +++ /dev/null @@ -1,68 +0,0 @@ -/* mpi-lshift.c - MPI helper functions - * Copyright (C) 1994, 1996, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#include -#include -#include -#include "mpi-internal.h" - -/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left - * and store the USIZE least significant digits of the result at WP. - * Return the bits shifted out from the most significant digit. - * - * Argument constraints: - * 1. 0 < CNT < BITS_PER_MP_LIMB - * 2. If the result is to be written over the input, WP must be >= UP. - */ - -mpi_limb_t -_gcry_mpih_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, - unsigned int cnt) -{ - mpi_limb_t high_limb, low_limb; - unsigned sh_1, sh_2; - mpi_size_t i; - mpi_limb_t retval; - - sh_1 = cnt; - wp += 1; - sh_2 = BITS_PER_MPI_LIMB - sh_1; - i = usize - 1; - low_limb = up[i]; - retval = low_limb >> sh_2; - high_limb = low_limb; - while ( --i >= 0 ) - { - low_limb = up[i]; - wp[i] = (high_limb << sh_1) | (low_limb >> sh_2); - high_limb = low_limb; - } - wp[i] = high_limb << sh_1; - - return retval; -} - - diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c deleted file mode 100644 index 614646c43..000000000 --- a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c +++ /dev/null @@ -1,62 +0,0 @@ -/* mpihelp-mul_1.c - MPI helper functions - * Copyright (C) 1994, 1996, 1997, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#include -#include -#include -#include "mpi-internal.h" -#include "longlong.h" - -mpi_limb_t -_gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, - mpi_limb_t s2_limb) -{ - mpi_limb_t cy_limb; - mpi_size_t j; - mpi_limb_t prod_high, prod_low; - - /* The loop counter and index J goes from -S1_SIZE to -1. This way - * the loop becomes faster. */ - j = -s1_size; - - /* Offset the base pointers to compensate for the negative indices. */ - s1_ptr -= j; - res_ptr -= j; - - cy_limb = 0; - do - { - umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb ); - prod_low += cy_limb; - cy_limb = (prod_low < cy_limb?1:0) + prod_high; - res_ptr[j] = prod_low; - } - while( ++j ); - - return cy_limb; -} - diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul2.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul2.c deleted file mode 100644 index 56979dfdb..000000000 --- a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul2.c +++ /dev/null @@ -1,68 +0,0 @@ -/* mpih-mul2.c - MPI helper functions - * Copyright (C) 1994, 1996, 1997, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#include -#include -#include -#include "mpi-internal.h" -#include "longlong.h" - - -mpi_limb_t -_gcry_mpih_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_size_t s1_size, mpi_limb_t s2_limb) -{ - mpi_limb_t cy_limb; - mpi_size_t j; - mpi_limb_t prod_high, prod_low; - mpi_limb_t x; - - /* The loop counter and index J goes from -SIZE to -1. This way - * the loop becomes faster. */ - j = -s1_size; - res_ptr -= j; - s1_ptr -= j; - - cy_limb = 0; - do - { - umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb ); - - prod_low += cy_limb; - cy_limb = (prod_low < cy_limb?1:0) + prod_high; - - x = res_ptr[j]; - prod_low = x + prod_low; - cy_limb += prod_low < x?1:0; - res_ptr[j] = prod_low; - } - while ( ++j ); - - return cy_limb; -} - - diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul3.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul3.c deleted file mode 100644 index 9b8df1a69..000000000 --- a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul3.c +++ /dev/null @@ -1,68 +0,0 @@ -/* mpih-mul3.c - MPI helper functions - * Copyright (C) 1994, 1996, 1997, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#include -#include -#include -#include "mpi-internal.h" -#include "longlong.h" - - -mpi_limb_t -_gcry_mpih_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_size_t s1_size, mpi_limb_t s2_limb) -{ - mpi_limb_t cy_limb; - mpi_size_t j; - mpi_limb_t prod_high, prod_low; - mpi_limb_t x; - - /* The loop counter and index J goes from -SIZE to -1. This way - * the loop becomes faster. */ - j = -s1_size; - res_ptr -= j; - s1_ptr -= j; - - cy_limb = 0; - do - { - umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb); - - prod_low += cy_limb; - cy_limb = (prod_low < cy_limb?1:0) + prod_high; - - x = res_ptr[j]; - prod_low = x - prod_low; - cy_limb += prod_low > x?1:0; - res_ptr[j] = prod_low; - } - while( ++j ); - - return cy_limb; -} - - diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-rshift.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-rshift.c deleted file mode 100644 index e40794fcf..000000000 --- a/grub-core/lib/libgcrypt/mpi/generic/mpih-rshift.c +++ /dev/null @@ -1,67 +0,0 @@ -/* mpih-rshift.c - MPI helper functions - * Copyright (C) 1994, 1996, 1998, 1999, - * 2000, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#include -#include -#include -#include "mpi-internal.h" - - -/* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right - * and store the USIZE least significant limbs of the result at WP. - * The bits shifted out to the right are returned. - * - * Argument constraints: - * 1. 0 < CNT < BITS_PER_MP_LIMB - * 2. If the result is to be written over the input, WP must be <= UP. - */ - -mpi_limb_t -_gcry_mpih_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, unsigned cnt) -{ - mpi_limb_t high_limb, low_limb; - unsigned sh_1, sh_2; - mpi_size_t i; - mpi_limb_t retval; - - sh_1 = cnt; - wp -= 1; - sh_2 = BITS_PER_MPI_LIMB - sh_1; - high_limb = up[0]; - retval = high_limb << sh_2; - low_limb = high_limb; - for (i=1; i < usize; i++) - { - high_limb = up[i]; - wp[i] = (low_limb >> sh_1) | (high_limb << sh_2); - low_limb = high_limb; - } - wp[i] = low_limb >> sh_1; - - return retval; -} - diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c deleted file mode 100644 index 25b08af1c..000000000 --- a/grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c +++ /dev/null @@ -1,66 +0,0 @@ -/* mpihelp-add_2.c - MPI helper functions - * Copyright (C) 1994, 1996, 1997, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#include -#include -#include -#include "mpi-internal.h" -#include "longlong.h" - -mpi_limb_t -_gcry_mpih_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_ptr_t s2_ptr, mpi_size_t size) -{ - mpi_limb_t x, y, cy; - mpi_size_t j; - - /* The loop counter and index J goes from -SIZE to -1. This way - the loop becomes faster. */ - j = -size; - - /* Offset the base pointers to compensate for the negative indices. */ - s1_ptr -= j; - s2_ptr -= j; - res_ptr -= j; - - cy = 0; - do - { - y = s2_ptr[j]; - x = s1_ptr[j]; - y += cy; /* add previous carry to subtrahend */ - cy = y < cy; /* get out carry from that addition */ - y = x - y; /* main subtract */ - cy += y > x; /* get out carry from the subtract, combine */ - res_ptr[j] = y; - } - while( ++j ); - - return cy; -} - - diff --git a/grub-core/lib/libgcrypt/mpi/generic/udiv-w-sdiv.c b/grub-core/lib/libgcrypt/mpi/generic/udiv-w-sdiv.c deleted file mode 100644 index e80d98bc5..000000000 --- a/grub-core/lib/libgcrypt/mpi/generic/udiv-w-sdiv.c +++ /dev/null @@ -1,133 +0,0 @@ -/* mpih-w-sdiv -- implement udiv_qrnnd on machines with only signed - * division. - * Copyright (C) 1992, 1994, 1996, 1998, 2002 Free Software Foundation, Inc. - * Contributed by Peter L. Montgomery. - * - * 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 -#include -#include -#include "mpi-internal.h" -#include "longlong.h" - - -#if 0 /* not yet ported to MPI */ - -mpi_limb_t -mpihelp_udiv_w_sdiv( mpi_limp_t *rp, - mpi_limp_t *a1, - mpi_limp_t *a0, - mpi_limp_t *d ) -{ - mp_limb_t q, r; - mp_limb_t c0, c1, b1; - - if ((mpi_limb_signed_t) d >= 0) - { - if (a1 < d - a1 - (a0 >> (BITS_PER_MP_LIMB - 1))) - { - /* dividend, divisor, and quotient are nonnegative */ - sdiv_qrnnd (q, r, a1, a0, d); - } - else - { - /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */ - sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (BITS_PER_MP_LIMB - 1)); - /* Divide (c1*2^32 + c0) by d */ - sdiv_qrnnd (q, r, c1, c0, d); - /* Add 2^31 to quotient */ - q += (mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1); - } - } - else - { - b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */ - c1 = a1 >> 1; /* A/2 */ - c0 = (a1 << (BITS_PER_MP_LIMB - 1)) + (a0 >> 1); - - if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */ - { - sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ - - r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */ - if ((d & 1) != 0) - { - if (r >= q) - r = r - q; - else if (q - r <= d) - { - r = r - q + d; - q--; - } - else - { - r = r - q + 2*d; - q -= 2; - } - } - } - else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */ - { - c1 = (b1 - 1) - c1; - c0 = ~c0; /* logical NOT */ - - sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ - - q = ~q; /* (A/2)/b1 */ - r = (b1 - 1) - r; - - r = 2*r + (a0 & 1); /* A/(2*b1) */ - - if ((d & 1) != 0) - { - if (r >= q) - r = r - q; - else if (q - r <= d) - { - r = r - q + d; - q--; - } - else - { - r = r - q + 2*d; - q -= 2; - } - } - } - else /* Implies c1 = b1 */ - { /* Hence a1 = d - 1 = 2*b1 - 1 */ - if (a0 >= -d) - { - q = -1; - r = a0 + d; - } - else - { - q = -2; - r = a0 + 2*d; - } - } - } - - *rp = r; - return q; -} - -#endif - diff --git a/grub-core/lib/libgcrypt/mpi/hppa/README b/grub-core/lib/libgcrypt/mpi/hppa/README deleted file mode 100644 index 5a2d5fd97..000000000 --- a/grub-core/lib/libgcrypt/mpi/hppa/README +++ /dev/null @@ -1,84 +0,0 @@ -This directory contains mpn functions for various HP PA-RISC chips. Code -that runs faster on the PA7100 and later implementations, is in the pa7100 -directory. - -RELEVANT OPTIMIZATION ISSUES - - Load and Store timing - -On the PA7000 no memory instructions can issue the two cycles after a store. -For the PA7100, this is reduced to one cycle. - -The PA7100 has a lookup-free cache, so it helps to schedule loads and the -dependent instruction really far from each other. - -STATUS - -1. mpn_mul_1 could be improved to 6.5 cycles/limb on the PA7100, using the - instructions bwlow (but some sw pipelining is needed to avoid the - xmpyu-fstds delay): - - fldds s1_ptr - - xmpyu - fstds N(%r30) - xmpyu - fstds N(%r30) - - ldws N(%r30) - ldws N(%r30) - ldws N(%r30) - ldws N(%r30) - - addc - stws res_ptr - addc - stws res_ptr - - addib Loop - -2. mpn_addmul_1 could be improved from the current 10 to 7.5 cycles/limb - (asymptotically) on the PA7100, using the instructions below. With proper - sw pipelining and the unrolling level below, the speed becomes 8 - cycles/limb. - - fldds s1_ptr - fldds s1_ptr - - xmpyu - fstds N(%r30) - xmpyu - fstds N(%r30) - xmpyu - fstds N(%r30) - xmpyu - fstds N(%r30) - - ldws N(%r30) - ldws N(%r30) - ldws N(%r30) - ldws N(%r30) - ldws N(%r30) - ldws N(%r30) - ldws N(%r30) - ldws N(%r30) - addc - addc - addc - addc - addc %r0,%r0,cy-limb - - ldws res_ptr - ldws res_ptr - ldws res_ptr - ldws res_ptr - add - stws res_ptr - addc - stws res_ptr - addc - stws res_ptr - addc - stws res_ptr - - addib diff --git a/grub-core/lib/libgcrypt/mpi/hppa/distfiles b/grub-core/lib/libgcrypt/mpi/hppa/distfiles deleted file mode 100644 index 7f24205d3..000000000 --- a/grub-core/lib/libgcrypt/mpi/hppa/distfiles +++ /dev/null @@ -1,7 +0,0 @@ -README -udiv-qrnnd.S -mpih-add1.S -mpih-sub1.S -mpih-lshift.S -mpih-rshift.S - diff --git a/grub-core/lib/libgcrypt/mpi/hppa/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/hppa/mpih-add1.S deleted file mode 100644 index 3bc0e5e19..000000000 --- a/grub-core/lib/libgcrypt/mpi/hppa/mpih-add1.S +++ /dev/null @@ -1,70 +0,0 @@ -/* hppa add_n -- Add two limb vectors of the same length > 0 and store - * sum in a third limb vector. - * - * Copyright (C) 1992, 1994, 1998, - * 2001, 2002 Fee 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - - -/******************* - * mpi_limb_t - * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (gr26) - * mpi_ptr_t s1_ptr, (gr25) - * mpi_ptr_t s2_ptr, (gr24) - * mpi_size_t size) (gr23) - * - * One might want to unroll this as for other processors, but it turns - * out that the data cache contention after a store makes such - * unrolling useless. We can't come under 5 cycles/limb anyway. - */ - - .code - .export _gcry_mpih_add_n - .label _gcry_mpih_add_n - .proc - .callinfo frame=0,no_calls - .entry - - ldws,ma 4(0,%r25),%r20 - ldws,ma 4(0,%r24),%r19 - - addib,= -1,%r23,L$end ; check for (SIZE == 1) - add %r20,%r19,%r28 ; add first limbs ignoring cy - - .label L$loop - ldws,ma 4(0,%r25),%r20 - ldws,ma 4(0,%r24),%r19 - stws,ma %r28,4(0,%r26) - addib,<> -1,%r23,L$loop - addc %r20,%r19,%r28 - - .label L$end - stws %r28,0(0,%r26) - bv 0(%r2) - addc %r0,%r0,%r28 - - .exit - .procend diff --git a/grub-core/lib/libgcrypt/mpi/hppa/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/hppa/mpih-lshift.S deleted file mode 100644 index 91b29bb6e..000000000 --- a/grub-core/lib/libgcrypt/mpi/hppa/mpih-lshift.S +++ /dev/null @@ -1,77 +0,0 @@ -/* hppa lshift - * - * Copyright (C) 1992, 1994, 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 - */ - - - -/******************* - * mpi_limb_t - * _gcry_mpih_lshift( mpi_ptr_t wp, (gr26) - * mpi_ptr_t up, (gr25) - * mpi_size_t usize, (gr24) - * unsigned cnt) (gr23) - */ - - .code - .export _gcry_mpih_lshift - .label _gcry_mpih_lshift - .proc - .callinfo frame=64,no_calls - .entry - - sh2add %r24,%r25,%r25 - sh2add %r24,%r26,%r26 - ldws,mb -4(0,%r25),%r22 - subi 32,%r23,%r1 - mtsar %r1 - addib,= -1,%r24,L$0004 - vshd %r0,%r22,%r28 ; compute carry out limb - ldws,mb -4(0,%r25),%r29 - addib,= -1,%r24,L$0002 - vshd %r22,%r29,%r20 - - .label L$loop - ldws,mb -4(0,%r25),%r22 - stws,mb %r20,-4(0,%r26) - addib,= -1,%r24,L$0003 - vshd %r29,%r22,%r20 - ldws,mb -4(0,%r25),%r29 - stws,mb %r20,-4(0,%r26) - addib,<> -1,%r24,L$loop - vshd %r22,%r29,%r20 - - .label L$0002 - stws,mb %r20,-4(0,%r26) - vshd %r29,%r0,%r20 - bv 0(%r2) - stw %r20,-4(0,%r26) - .label L$0003 - stws,mb %r20,-4(0,%r26) - .label L$0004 - vshd %r22,%r0,%r20 - bv 0(%r2) - stw %r20,-4(0,%r26) - - .exit - .procend - - - diff --git a/grub-core/lib/libgcrypt/mpi/hppa/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/hppa/mpih-rshift.S deleted file mode 100644 index 37a9d4ef9..000000000 --- a/grub-core/lib/libgcrypt/mpi/hppa/mpih-rshift.S +++ /dev/null @@ -1,73 +0,0 @@ -/* hppa rshift - * - * Copyright (C) 1992, 1994, 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 - */ - - - - -/******************* - * mpi_limb_t - * _gcry_mpih_rshift( mpi_ptr_t wp, (gr26) - * mpi_ptr_t up, (gr25) - * mpi_size_t usize, (gr24) - * unsigned cnt) (gr23) - */ - - .code - .export _gcry_mpih_rshift - .label _gcry_mpih_rshift - .proc - .callinfo frame=64,no_calls - .entry - - ldws,ma 4(0,%r25),%r22 - mtsar %r23 - addib,= -1,%r24,L$r004 - vshd %r22,%r0,%r28 ; compute carry out limb - ldws,ma 4(0,%r25),%r29 - addib,= -1,%r24,L$r002 - vshd %r29,%r22,%r20 - - .label L$roop - ldws,ma 4(0,%r25),%r22 - stws,ma %r20,4(0,%r26) - addib,= -1,%r24,L$r003 - vshd %r22,%r29,%r20 - ldws,ma 4(0,%r25),%r29 - stws,ma %r20,4(0,%r26) - addib,<> -1,%r24,L$roop - vshd %r29,%r22,%r20 - - .label L$r002 - stws,ma %r20,4(0,%r26) - vshd %r0,%r29,%r20 - bv 0(%r2) - stw %r20,0(0,%r26) - .label L$r003 - stws,ma %r20,4(0,%r26) - .label L$r004 - vshd %r0,%r22,%r20 - bv 0(%r2) - stw %r20,0(0,%r26) - - .exit - .procend - diff --git a/grub-core/lib/libgcrypt/mpi/hppa/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/hppa/mpih-sub1.S deleted file mode 100644 index 8d197e412..000000000 --- a/grub-core/lib/libgcrypt/mpi/hppa/mpih-sub1.S +++ /dev/null @@ -1,78 +0,0 @@ -/* hppa sub_n -- Sub two limb vectors of the same length > 0 and store - * sum in a third limb vector. - * - * Copyright (C) 1992, 1994, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (gr26) - * mpi_ptr_t s1_ptr, (gr25) - * mpi_ptr_t s2_ptr, (gr24) - * mpi_size_t size) (gr23) - * - * One might want to unroll this as for other processors, but it turns - * out that the data cache contention after a store makes such - * unrolling useless. We can't come under 5 cycles/limb anyway. - */ - - - .code - .export _gcry_mpih_sub_n - .label _gcry_mpih_sub_n - .proc - .callinfo frame=0,no_calls - .entry - - ldws,ma 4(0,%r25),%r20 - ldws,ma 4(0,%r24),%r19 - - addib,= -1,%r23,L$end ; check for (SIZE == 1) - sub %r20,%r19,%r28 ; subtract first limbs ignoring cy - - .label L$loop - ldws,ma 4(0,%r25),%r20 - ldws,ma 4(0,%r24),%r19 - stws,ma %r28,4(0,%r26) - addib,<> -1,%r23,L$loop - subb %r20,%r19,%r28 - - .label L$end - stws %r28,0(0,%r26) - addc %r0,%r0,%r28 - bv 0(%r2) - subi 1,%r28,%r28 - - .exit - .procend - - - diff --git a/grub-core/lib/libgcrypt/mpi/hppa/udiv-qrnnd.S b/grub-core/lib/libgcrypt/mpi/hppa/udiv-qrnnd.S deleted file mode 100644 index 59ebf7a00..000000000 --- a/grub-core/lib/libgcrypt/mpi/hppa/udiv-qrnnd.S +++ /dev/null @@ -1,297 +0,0 @@ -/* HP-PA __udiv_qrnnd division support, used from longlong.h. - * This version runs fast on pre-PA7000 CPUs. - * - * Copyright (C) 1993, 1994, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - - -/* INPUT PARAMETERS - * rem_ptr gr26 - * n1 gr25 - * n0 gr24 - * d gr23 - * - * The code size is a bit excessive. We could merge the last two ds;addc - * sequences by simply moving the "bb,< Odd" instruction down. The only - * trouble is the FFFFFFFF code that would need some hacking. - */ - - .code - .export __udiv_qrnnd - .label __udiv_qrnnd - .proc - .callinfo frame=0,no_calls - .entry - - comb,< %r23,0,L$largedivisor - sub %r0,%r23,%r1 ; clear cy as side-effect - ds %r0,%r1,%r0 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r24 - ds %r25,%r23,%r25 - addc %r24,%r24,%r28 - ds %r25,%r23,%r25 - comclr,>= %r25,%r0,%r0 - addl %r25,%r23,%r25 - stws %r25,0(0,%r26) - bv 0(%r2) - addc %r28,%r28,%r28 - - .label L$largedivisor - extru %r24,31,1,%r19 ; r19 = n0 & 1 - bb,< %r23,31,L$odd - extru %r23,30,31,%r22 ; r22 = d >> 1 - shd %r25,%r24,1,%r24 ; r24 = new n0 - extru %r25,30,31,%r25 ; r25 = new n1 - sub %r0,%r22,%r21 - ds %r0,%r21,%r0 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - comclr,>= %r25,%r0,%r0 - addl %r25,%r22,%r25 - sh1addl %r25,%r19,%r25 - stws %r25,0(0,%r26) - bv 0(%r2) - addc %r24,%r24,%r28 - - .label L$odd - addib,sv,n 1,%r22,L$FF.. ; r22 = (d / 2 + 1) - shd %r25,%r24,1,%r24 ; r24 = new n0 - extru %r25,30,31,%r25 ; r25 = new n1 - sub %r0,%r22,%r21 - ds %r0,%r21,%r0 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r24 - ds %r25,%r22,%r25 - addc %r24,%r24,%r28 - comclr,>= %r25,%r0,%r0 - addl %r25,%r22,%r25 - sh1addl %r25,%r19,%r25 -; We have computed (n1,,n0) / (d + 1), q' = r28, r' = r25 - add,nuv %r28,%r25,%r25 - addl %r25,%r1,%r25 - addc %r0,%r28,%r28 - sub,<< %r25,%r23,%r0 - addl %r25,%r1,%r25 - stws %r25,0(0,%r26) - bv 0(%r2) - addc %r0,%r28,%r28 - -; This is just a special case of the code above. -; We come here when d == 0xFFFFFFFF - .label L$FF.. - add,uv %r25,%r24,%r24 - sub,<< %r24,%r23,%r0 - ldo 1(%r24),%r24 - stws %r24,0(0,%r26) - bv 0(%r2) - addc %r0,%r25,%r28 - - .exit - .procend diff --git a/grub-core/lib/libgcrypt/mpi/i386/Manifest b/grub-core/lib/libgcrypt/mpi/i386/Manifest deleted file mode 100644 index 812bc8a5c..000000000 --- a/grub-core/lib/libgcrypt/mpi/i386/Manifest +++ /dev/null @@ -1,28 +0,0 @@ -# Manifest - checksums -# Copyright 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 - -mpih-add1.S -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S -mpih-lshift.S -mpih-rshift.S -mpih-sub1.S -syntax.h -$names$ iQCVAwUAP+LmOTEAnp832S/7AQJZmgQA1+GIl7rXiEY00y5xD2kG5Lm2QD6c9aBME8hTl812OEcj0ul/QSpdv8E2NEKooifr4SiLVhEVfLNaLqAgN3cIsttn3rRX3/pMC5JwSKHDJPsUbpN9tzb5dr2YC9GG9m8xngAQrN11IQPnGfvFLJK+oDnEMIAeHDpOnX9NeQPDAQA==bnOy diff --git a/grub-core/lib/libgcrypt/mpi/i386/distfiles b/grub-core/lib/libgcrypt/mpi/i386/distfiles deleted file mode 100644 index 22b9979bd..000000000 --- a/grub-core/lib/libgcrypt/mpi/i386/distfiles +++ /dev/null @@ -1,10 +0,0 @@ -Manifest -mpih-add1.S -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S -mpih-lshift.S -mpih-rshift.S -mpih-sub1.S -syntax.h - diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-add1.S deleted file mode 100644 index 652b23218..000000000 --- a/grub-core/lib/libgcrypt/mpi/i386/mpih-add1.S +++ /dev/null @@ -1,116 +0,0 @@ -/* i80386 add_n -- Add two limb vectors of the same length > 0 and store - * sum in a third limb vector. - * - * Copyright (C) 1992, 1994, 1995, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_ptr_t s2_ptr, (sp + 12) - * mpi_size_t size) (sp + 16) - */ - -.text - ALIGN (3) - .globl C_SYMBOL_NAME(_gcry_mpih_add_n) -C_SYMBOL_NAME(_gcry_mpih_add_n:) - pushl %edi - pushl %esi - - movl 12(%esp),%edi /* res_ptr */ - movl 16(%esp),%esi /* s1_ptr */ - movl 20(%esp),%edx /* s2_ptr */ - movl 24(%esp),%ecx /* size */ - - movl %ecx,%eax - shrl $3,%ecx /* compute count for unrolled loop */ - negl %eax - andl $7,%eax /* get index where to start loop */ - jz Loop /* necessary special case for 0 */ - incl %ecx /* adjust loop count */ - shll $2,%eax /* adjustment for pointers... */ - subl %eax,%edi /* ... since they are offset ... */ - subl %eax,%esi /* ... by a constant when we ... */ - subl %eax,%edx /* ... enter the loop */ - shrl $2,%eax /* restore previous value */ -#ifdef PIC -/* Calculate start address in loop for PIC. Due to limitations in some - assemblers, Loop-L0-3 cannot be put into the leal */ - call L0 -L0: leal (%eax,%eax,8),%eax - addl (%esp),%eax - addl $(Loop-L0-3),%eax - addl $4,%esp -#else -/* Calculate start address in loop for non-PIC. */ - leal (Loop - 3)(%eax,%eax,8),%eax -#endif - jmp *%eax /* jump into loop */ - ALIGN (3) -Loop: movl (%esi),%eax - adcl (%edx),%eax - movl %eax,(%edi) - movl 4(%esi),%eax - adcl 4(%edx),%eax - movl %eax,4(%edi) - movl 8(%esi),%eax - adcl 8(%edx),%eax - movl %eax,8(%edi) - movl 12(%esi),%eax - adcl 12(%edx),%eax - movl %eax,12(%edi) - movl 16(%esi),%eax - adcl 16(%edx),%eax - movl %eax,16(%edi) - movl 20(%esi),%eax - adcl 20(%edx),%eax - movl %eax,20(%edi) - movl 24(%esi),%eax - adcl 24(%edx),%eax - movl %eax,24(%edi) - movl 28(%esi),%eax - adcl 28(%edx),%eax - movl %eax,28(%edi) - leal 32(%edi),%edi - leal 32(%esi),%esi - leal 32(%edx),%edx - decl %ecx - jnz Loop - - sbbl %eax,%eax - negl %eax - - popl %esi - popl %edi - ret - diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-lshift.S deleted file mode 100644 index bf8ed9d4c..000000000 --- a/grub-core/lib/libgcrypt/mpi/i386/mpih-lshift.S +++ /dev/null @@ -1,94 +0,0 @@ -/* i80386 lshift - * Copyright (C) 1992, 1994, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4) - * mpi_ptr_t up, (sp + 8) - * mpi_size_t usize, (sp + 12) - * unsigned cnt) (sp + 16) - */ - -.text - ALIGN (3) - .globl C_SYMBOL_NAME(_gcry_mpih_lshift) -C_SYMBOL_NAME(_gcry_mpih_lshift:) - pushl %edi - pushl %esi - pushl %ebx - - movl 16(%esp),%edi /* res_ptr */ - movl 20(%esp),%esi /* s_ptr */ - movl 24(%esp),%edx /* size */ - movl 28(%esp),%ecx /* cnt */ - - subl $4,%esi /* adjust s_ptr */ - - movl (%esi,%edx,4),%ebx /* read most significant limb */ - xorl %eax,%eax - shldl %cl,%ebx,%eax /* compute carry limb */ - decl %edx - jz Lend - pushl %eax /* push carry limb onto stack */ - testb $1,%dl - jnz L1 /* enter loop in the middle */ - movl %ebx,%eax - - ALIGN (3) -Loop: movl (%esi,%edx,4),%ebx /* load next lower limb */ - shldl %cl,%ebx,%eax /* compute result limb */ - movl %eax,(%edi,%edx,4) /* store it */ - decl %edx -L1: movl (%esi,%edx,4),%eax - shldl %cl,%eax,%ebx - movl %ebx,(%edi,%edx,4) - decl %edx - jnz Loop - - shll %cl,%eax /* compute least significant limb */ - movl %eax,(%edi) /* store it */ - - popl %eax /* pop carry limb */ - - popl %ebx - popl %esi - popl %edi - ret - -Lend: shll %cl,%ebx /* compute least significant limb */ - movl %ebx,(%edi) /* store it */ - - popl %ebx - popl %esi - popl %edi - ret - diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-mul1.S deleted file mode 100644 index c9760ef92..000000000 --- a/grub-core/lib/libgcrypt/mpi/i386/mpih-mul1.S +++ /dev/null @@ -1,84 +0,0 @@ -/* i80386 mul_1 -- Multiply a limb vector with a limb and store - * the result in a second limb vector. - * Copyright (C) 1992, 1994, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_size_t s1_size, (sp + 12) - * mpi_limb_t s2_limb) (sp + 16) - */ - -#define res_ptr edi -#define s1_ptr esi -#define size ecx -#define s2_limb ebp - - TEXT - ALIGN (3) - GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1) -C_SYMBOL_NAME(_gcry_mpih_mul_1:) - - INSN1(push,l ,R(edi)) - INSN1(push,l ,R(esi)) - INSN1(push,l ,R(ebx)) - INSN1(push,l ,R(ebp)) - - INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20)) - INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24)) - INSN2(mov,l ,R(size),MEM_DISP(esp,28)) - INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32)) - - INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4)) - INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4)) - INSN1(neg,l ,R(size)) - INSN2(xor,l ,R(ebx),R(ebx)) - ALIGN (3) -Loop: - INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4)) - INSN1(mul,l ,R(s2_limb)) - INSN2(add,l ,R(eax),R(ebx)) - INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(eax)) - INSN2(adc,l ,R(edx),$0) - INSN2(mov,l ,R(ebx),R(edx)) - - INSN1(inc,l ,R(size)) - INSN1(jnz, ,Loop) - INSN2(mov,l ,R(eax),R(ebx)) - - INSN1(pop,l ,R(ebp)) - INSN1(pop,l ,R(ebx)) - INSN1(pop,l ,R(esi)) - INSN1(pop,l ,R(edi)) - ret - diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-mul2.S deleted file mode 100644 index 9794e1108..000000000 --- a/grub-core/lib/libgcrypt/mpi/i386/mpih-mul2.S +++ /dev/null @@ -1,86 +0,0 @@ -/* i80386 addmul_1 -- Multiply a limb vector with a limb and add - * the result to a second limb vector. - * - * Copyright (C) 1992, 1994, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_size_t s1_size, (sp + 12) - * mpi_limb_t s2_limb) (sp + 16) - */ - -#define res_ptr edi -#define s1_ptr esi -#define size ecx -#define s2_limb ebp - - TEXT - ALIGN (3) - GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1) -C_SYMBOL_NAME(_gcry_mpih_addmul_1:) - - INSN1(push,l ,R(edi)) - INSN1(push,l ,R(esi)) - INSN1(push,l ,R(ebx)) - INSN1(push,l ,R(ebp)) - - INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20)) - INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24)) - INSN2(mov,l ,R(size),MEM_DISP(esp,28)) - INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32)) - - INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4)) - INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4)) - INSN1(neg,l ,R(size)) - INSN2(xor,l ,R(ebx),R(ebx)) - ALIGN (3) -Loop: - INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4)) - INSN1(mul,l ,R(s2_limb)) - INSN2(add,l ,R(eax),R(ebx)) - INSN2(adc,l ,R(edx),$0) - INSN2(add,l ,MEM_INDEX(res_ptr,size,4),R(eax)) - INSN2(adc,l ,R(edx),$0) - INSN2(mov,l ,R(ebx),R(edx)) - - INSN1(inc,l ,R(size)) - INSN1(jnz, ,Loop) - INSN2(mov,l ,R(eax),R(ebx)) - - INSN1(pop,l ,R(ebp)) - INSN1(pop,l ,R(ebx)) - INSN1(pop,l ,R(esi)) - INSN1(pop,l ,R(edi)) - ret - diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-mul3.S deleted file mode 100644 index 6df201763..000000000 --- a/grub-core/lib/libgcrypt/mpi/i386/mpih-mul3.S +++ /dev/null @@ -1,86 +0,0 @@ -/* i80386 submul_1 -- Multiply a limb vector with a limb and add - * the result to a second limb vector. - * - * Copyright (C) 1992, 1994, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_size_t s1_size, (sp + 12) - * mpi_limb_t s2_limb) (sp + 16) - */ - -#define res_ptr edi -#define s1_ptr esi -#define size ecx -#define s2_limb ebp - - TEXT - ALIGN (3) - GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1) -C_SYMBOL_NAME(_gcry_mpih_submul_1:) - - INSN1(push,l ,R(edi)) - INSN1(push,l ,R(esi)) - INSN1(push,l ,R(ebx)) - INSN1(push,l ,R(ebp)) - - INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20)) - INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24)) - INSN2(mov,l ,R(size),MEM_DISP(esp,28)) - INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32)) - - INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4)) - INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4)) - INSN1(neg,l ,R(size)) - INSN2(xor,l ,R(ebx),R(ebx)) - ALIGN (3) -Loop: - INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4)) - INSN1(mul,l ,R(s2_limb)) - INSN2(add,l ,R(eax),R(ebx)) - INSN2(adc,l ,R(edx),$0) - INSN2(sub,l ,MEM_INDEX(res_ptr,size,4),R(eax)) - INSN2(adc,l ,R(edx),$0) - INSN2(mov,l ,R(ebx),R(edx)) - - INSN1(inc,l ,R(size)) - INSN1(jnz, ,Loop) - INSN2(mov,l ,R(eax),R(ebx)) - - INSN1(pop,l ,R(ebp)) - INSN1(pop,l ,R(ebx)) - INSN1(pop,l ,R(esi)) - INSN1(pop,l ,R(edi)) - ret - diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-rshift.S deleted file mode 100644 index 2920e55d8..000000000 --- a/grub-core/lib/libgcrypt/mpi/i386/mpih-rshift.S +++ /dev/null @@ -1,97 +0,0 @@ -/* i80386 rshift - * - * Copyright (C) 1992, 1994, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4) - * mpi_ptr_t up, (sp + 8) - * mpi_size_t usize, (sp + 12) - * unsigned cnt) (sp + 16) - */ - -.text - ALIGN (3) - .globl C_SYMBOL_NAME(_gcry_mpih_rshift) -C_SYMBOL_NAME(_gcry_mpih_rshift:) - pushl %edi - pushl %esi - pushl %ebx - - movl 16(%esp),%edi /* wp */ - movl 20(%esp),%esi /* up */ - movl 24(%esp),%edx /* usize */ - movl 28(%esp),%ecx /* cnt */ - - leal -4(%edi,%edx,4),%edi - leal (%esi,%edx,4),%esi - negl %edx - - movl (%esi,%edx,4),%ebx /* read least significant limb */ - xorl %eax,%eax - shrdl %cl,%ebx,%eax /* compute carry limb */ - incl %edx - jz Lend2 - pushl %eax /* push carry limb onto stack */ - testb $1,%dl - jnz L2 /* enter loop in the middle */ - movl %ebx,%eax - - ALIGN (3) -Loop2: movl (%esi,%edx,4),%ebx /* load next higher limb */ - shrdl %cl,%ebx,%eax /* compute result limb */ - movl %eax,(%edi,%edx,4) /* store it */ - incl %edx -L2: movl (%esi,%edx,4),%eax - shrdl %cl,%eax,%ebx - movl %ebx,(%edi,%edx,4) - incl %edx - jnz Loop2 - - shrl %cl,%eax /* compute most significant limb */ - movl %eax,(%edi) /* store it */ - - popl %eax /* pop carry limb */ - - popl %ebx - popl %esi - popl %edi - ret - -Lend2: shrl %cl,%ebx /* compute most significant limb */ - movl %ebx,(%edi) /* store it */ - - popl %ebx - popl %esi - popl %edi - ret - diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-sub1.S deleted file mode 100644 index f447f7a66..000000000 --- a/grub-core/lib/libgcrypt/mpi/i386/mpih-sub1.S +++ /dev/null @@ -1,117 +0,0 @@ -/* i80386 sub_n -- Sub two limb vectors of the same length > 0 and store - * sum in a third limb vector. - * - * Copyright (C) 1992, 1994, 1995, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_ptr_t s2_ptr, (sp + 12) - * mpi_size_t size) (sp + 16) - */ - - -.text - ALIGN (3) - .globl C_SYMBOL_NAME(_gcry_mpih_sub_n) -C_SYMBOL_NAME(_gcry_mpih_sub_n:) - pushl %edi - pushl %esi - - movl 12(%esp),%edi /* res_ptr */ - movl 16(%esp),%esi /* s1_ptr */ - movl 20(%esp),%edx /* s2_ptr */ - movl 24(%esp),%ecx /* size */ - - movl %ecx,%eax - shrl $3,%ecx /* compute count for unrolled loop */ - negl %eax - andl $7,%eax /* get index where to start loop */ - jz Loop /* necessary special case for 0 */ - incl %ecx /* adjust loop count */ - shll $2,%eax /* adjustment for pointers... */ - subl %eax,%edi /* ... since they are offset ... */ - subl %eax,%esi /* ... by a constant when we ... */ - subl %eax,%edx /* ... enter the loop */ - shrl $2,%eax /* restore previous value */ -#ifdef PIC -/* Calculate start address in loop for PIC. Due to limitations in some - assemblers, Loop-L0-3 cannot be put into the leal */ - call L0 -L0: leal (%eax,%eax,8),%eax - addl (%esp),%eax - addl $(Loop-L0-3),%eax - addl $4,%esp -#else -/* Calculate start address in loop for non-PIC. */ - leal (Loop - 3)(%eax,%eax,8),%eax -#endif - jmp *%eax /* jump into loop */ - ALIGN (3) -Loop: movl (%esi),%eax - sbbl (%edx),%eax - movl %eax,(%edi) - movl 4(%esi),%eax - sbbl 4(%edx),%eax - movl %eax,4(%edi) - movl 8(%esi),%eax - sbbl 8(%edx),%eax - movl %eax,8(%edi) - movl 12(%esi),%eax - sbbl 12(%edx),%eax - movl %eax,12(%edi) - movl 16(%esi),%eax - sbbl 16(%edx),%eax - movl %eax,16(%edi) - movl 20(%esi),%eax - sbbl 20(%edx),%eax - movl %eax,20(%edi) - movl 24(%esi),%eax - sbbl 24(%edx),%eax - movl %eax,24(%edi) - movl 28(%esi),%eax - sbbl 28(%edx),%eax - movl %eax,28(%edi) - leal 32(%edi),%edi - leal 32(%esi),%esi - leal 32(%edx),%edx - decl %ecx - jnz Loop - - sbbl %eax,%eax - negl %eax - - popl %esi - popl %edi - ret - diff --git a/grub-core/lib/libgcrypt/mpi/i386/syntax.h b/grub-core/lib/libgcrypt/mpi/i386/syntax.h deleted file mode 100644 index 88845f28d..000000000 --- a/grub-core/lib/libgcrypt/mpi/i386/syntax.h +++ /dev/null @@ -1,68 +0,0 @@ -/* syntax.h -- Definitions for x86 syntax variations. - * - * Copyright (C) 1992, 1994, 1995, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#undef ALIGN - -#if defined (BSD_SYNTAX) || defined (ELF_SYNTAX) -#define R(r) %r -#define MEM(base)(base) -#define MEM_DISP(base,displacement)displacement(R(base)) -#define MEM_INDEX(base,index,size)(R(base),R(index),size) -#ifdef __STDC__ -#define INSN1(mnemonic,size_suffix,dst)mnemonic##size_suffix dst -#define INSN2(mnemonic,size_suffix,dst,src)mnemonic##size_suffix src,dst -#else -#define INSN1(mnemonic,size_suffix,dst)mnemonic/**/size_suffix dst -#define INSN2(mnemonic,size_suffix,dst,src)mnemonic/**/size_suffix src,dst -#endif -#define TEXT .text -#if defined (BSD_SYNTAX) -#define ALIGN(log) .align log -#endif -#if defined (ELF_SYNTAX) -#define ALIGN(log) .align 1<<(log) -#endif -#define GLOBL .globl -#endif - -#ifdef INTEL_SYNTAX -#define R(r) r -#define MEM(base)[base] -#define MEM_DISP(base,displacement)[base+(displacement)] -#define MEM_INDEX(base,index,size)[base+index*size] -#define INSN1(mnemonic,size_suffix,dst)mnemonic dst -#define INSN2(mnemonic,size_suffix,dst,src)mnemonic dst,src -#define TEXT .text -#define ALIGN(log) .align log -#define GLOBL .globl -#endif - -#ifdef X86_BROKEN_ALIGN -#undef ALIGN -#define ALIGN(log) .align log,0x90 -#endif diff --git a/grub-core/lib/libgcrypt/mpi/i586/Manifest b/grub-core/lib/libgcrypt/mpi/i586/Manifest deleted file mode 100644 index 6d1d7f824..000000000 --- a/grub-core/lib/libgcrypt/mpi/i586/Manifest +++ /dev/null @@ -1,27 +0,0 @@ -# Manifest - checksums -# Copyright 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 - -mpih-add1.S -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S -mpih-lshift.S -mpih-rshift.S -mpih-sub1.S -$names$ iQCVAwUAP+LmQDEAnp832S/7AQKCmgQAhG+E7X0KB4qdVf3sMb6Qr+Iv5Jlehzoub/5vxTRgePKzRuOHidCnTzSSoyzA++UcHrOjHQQDMsXnO6PqpS1d/TKkxjnGN7rE8mvMYlFAT8RsawTozSfh14mCzI0HTDbaKL9Z8pcMJtadB3XqAuqWJNO8kyECJFwurt3DRWXSWS8==Rug5 diff --git a/grub-core/lib/libgcrypt/mpi/i586/README b/grub-core/lib/libgcrypt/mpi/i586/README deleted file mode 100644 index d73b08268..000000000 --- a/grub-core/lib/libgcrypt/mpi/i586/README +++ /dev/null @@ -1,26 +0,0 @@ -This directory contains mpn functions optimized for Intel Pentium -processors. - -RELEVANT OPTIMIZATION ISSUES - -1. Pentium doesn't allocate cache lines on writes, unlike most other modern -processors. Since the functions in the mpn class do array writes, we have to -handle allocating the destination cache lines by reading a word from it in the -loops, to achieve the best performance. - -2. Pairing of memory operations requires that the two issued operations refer -to different cache banks. The simplest way to insure this is to read/write -two words from the same object. If we make operations on different objects, -they might or might not be to the same cache bank. - -STATUS - -1. mpn_lshift and mpn_rshift run at about 6 cycles/limb, but the Pentium -documentation indicates that they should take only 43/8 = 5.375 cycles/limb, -or 5 cycles/limb asymptotically. - -2. mpn_add_n and mpn_sub_n run at asymptotically 2 cycles/limb. Due to loop -overhead and other delays (cache refill?), they run at or near 2.5 cycles/limb. - -3. mpn_mul_1, mpn_addmul_1, mpn_submul_1 all run 1 cycle faster than they -should... diff --git a/grub-core/lib/libgcrypt/mpi/i586/distfiles b/grub-core/lib/libgcrypt/mpi/i586/distfiles deleted file mode 100644 index 546f77768..000000000 --- a/grub-core/lib/libgcrypt/mpi/i586/distfiles +++ /dev/null @@ -1,10 +0,0 @@ -Manifest -mpih-add1.S -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S -mpih-lshift.S -mpih-rshift.S -mpih-sub1.S -README - diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-add1.S deleted file mode 100644 index 7436d5926..000000000 --- a/grub-core/lib/libgcrypt/mpi/i586/mpih-add1.S +++ /dev/null @@ -1,135 +0,0 @@ -/* i80586 add_n -- Add two limb vectors of the same length > 0 and store - * sum in a third limb vector. - * - * Copyright (C) 1992, 1994, 1995, 1996, 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 - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_ptr_t s2_ptr, (sp + 12) - * mpi_size_t size) (sp + 16) - */ - -.text - ALIGN (3) - .globl C_SYMBOL_NAME(_gcry_mpih_add_n) -C_SYMBOL_NAME(_gcry_mpih_add_n:) - pushl %edi - pushl %esi - pushl %ebx - pushl %ebp - - movl 20(%esp),%edi /* res_ptr */ - movl 24(%esp),%esi /* s1_ptr */ - movl 28(%esp),%ebp /* s2_ptr */ - movl 32(%esp),%ecx /* size */ - - movl (%ebp),%ebx - - decl %ecx - movl %ecx,%edx - shrl $3,%ecx - andl $7,%edx - testl %ecx,%ecx /* zero carry flag */ - jz Lend - pushl %edx - - ALIGN (3) -Loop: movl 28(%edi),%eax /* fetch destination cache line */ - leal 32(%edi),%edi - -L1: movl (%esi),%eax - movl 4(%esi),%edx - adcl %ebx,%eax - movl 4(%ebp),%ebx - adcl %ebx,%edx - movl 8(%ebp),%ebx - movl %eax,-32(%edi) - movl %edx,-28(%edi) - -L2: movl 8(%esi),%eax - movl 12(%esi),%edx - adcl %ebx,%eax - movl 12(%ebp),%ebx - adcl %ebx,%edx - movl 16(%ebp),%ebx - movl %eax,-24(%edi) - movl %edx,-20(%edi) - -L3: movl 16(%esi),%eax - movl 20(%esi),%edx - adcl %ebx,%eax - movl 20(%ebp),%ebx - adcl %ebx,%edx - movl 24(%ebp),%ebx - movl %eax,-16(%edi) - movl %edx,-12(%edi) - -L4: movl 24(%esi),%eax - movl 28(%esi),%edx - adcl %ebx,%eax - movl 28(%ebp),%ebx - adcl %ebx,%edx - movl 32(%ebp),%ebx - movl %eax,-8(%edi) - movl %edx,-4(%edi) - - leal 32(%esi),%esi - leal 32(%ebp),%ebp - decl %ecx - jnz Loop - - popl %edx -Lend: - decl %edx /* test %edx w/o clobbering carry */ - js Lend2 - incl %edx -Loop2: - leal 4(%edi),%edi - movl (%esi),%eax - adcl %ebx,%eax - movl 4(%ebp),%ebx - movl %eax,-4(%edi) - leal 4(%esi),%esi - leal 4(%ebp),%ebp - decl %edx - jnz Loop2 -Lend2: - movl (%esi),%eax - adcl %ebx,%eax - movl %eax,(%edi) - - sbbl %eax,%eax - negl %eax - - popl %ebp - popl %ebx - popl %esi - popl %edi - ret - - diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-lshift.S deleted file mode 100644 index 9d25fe9d7..000000000 --- a/grub-core/lib/libgcrypt/mpi/i586/mpih-lshift.S +++ /dev/null @@ -1,229 +0,0 @@ -/* i80586 lshift - * - * Copyright (C) 1992, 1994, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4) - * mpi_ptr_t up, (sp + 8) - * mpi_size_t usize, (sp + 12) - * unsigned cnt) (sp + 16) - */ - -.text - ALIGN (3) - .globl C_SYMBOL_NAME(_gcry_mpih_lshift) -C_SYMBOL_NAME(_gcry_mpih_lshift:) - - pushl %edi - pushl %esi - pushl %ebx - pushl %ebp - - movl 20(%esp),%edi /* res_ptr */ - movl 24(%esp),%esi /* s_ptr */ - movl 28(%esp),%ebp /* size */ - movl 32(%esp),%ecx /* cnt */ - -/* We can use faster code for shift-by-1 under certain conditions. */ - cmp $1,%ecx - jne Lnormal - leal 4(%esi),%eax - cmpl %edi,%eax - jnc Lspecial /* jump if s_ptr + 1 >= res_ptr */ - leal (%esi,%ebp,4),%eax - cmpl %eax,%edi - jnc Lspecial /* jump if res_ptr >= s_ptr + size */ - -Lnormal: - leal -4(%edi,%ebp,4),%edi - leal -4(%esi,%ebp,4),%esi - - movl (%esi),%edx - subl $4,%esi - xorl %eax,%eax - shldl %cl,%edx,%eax /* compute carry limb */ - pushl %eax /* push carry limb onto stack */ - - decl %ebp - pushl %ebp - shrl $3,%ebp - jz Lend - - movl (%edi),%eax /* fetch destination cache line */ - - ALIGN (2) -Loop: movl -28(%edi),%eax /* fetch destination cache line */ - movl %edx,%ebx - - movl (%esi),%eax - movl -4(%esi),%edx - shldl %cl,%eax,%ebx - shldl %cl,%edx,%eax - movl %ebx,(%edi) - movl %eax,-4(%edi) - - movl -8(%esi),%ebx - movl -12(%esi),%eax - shldl %cl,%ebx,%edx - shldl %cl,%eax,%ebx - movl %edx,-8(%edi) - movl %ebx,-12(%edi) - - movl -16(%esi),%edx - movl -20(%esi),%ebx - shldl %cl,%edx,%eax - shldl %cl,%ebx,%edx - movl %eax,-16(%edi) - movl %edx,-20(%edi) - - movl -24(%esi),%eax - movl -28(%esi),%edx - shldl %cl,%eax,%ebx - shldl %cl,%edx,%eax - movl %ebx,-24(%edi) - movl %eax,-28(%edi) - - subl $32,%esi - subl $32,%edi - decl %ebp - jnz Loop - -Lend: popl %ebp - andl $7,%ebp - jz Lend2 -Loop2: movl (%esi),%eax - shldl %cl,%eax,%edx - movl %edx,(%edi) - movl %eax,%edx - subl $4,%esi - subl $4,%edi - decl %ebp - jnz Loop2 - -Lend2: shll %cl,%edx /* compute least significant limb */ - movl %edx,(%edi) /* store it */ - - popl %eax /* pop carry limb */ - - popl %ebp - popl %ebx - popl %esi - popl %edi - ret - -/* We loop from least significant end of the arrays, which is only - permissable if the source and destination don't overlap, since the - function is documented to work for overlapping source and destination. -*/ - -Lspecial: - movl (%esi),%edx - addl $4,%esi - - decl %ebp - pushl %ebp - shrl $3,%ebp - - addl %edx,%edx - incl %ebp - decl %ebp - jz LLend - - movl (%edi),%eax /* fetch destination cache line */ - - ALIGN (2) -LLoop: movl 28(%edi),%eax /* fetch destination cache line */ - movl %edx,%ebx - - movl (%esi),%eax - movl 4(%esi),%edx - adcl %eax,%eax - movl %ebx,(%edi) - adcl %edx,%edx - movl %eax,4(%edi) - - movl 8(%esi),%ebx - movl 12(%esi),%eax - adcl %ebx,%ebx - movl %edx,8(%edi) - adcl %eax,%eax - movl %ebx,12(%edi) - - movl 16(%esi),%edx - movl 20(%esi),%ebx - adcl %edx,%edx - movl %eax,16(%edi) - adcl %ebx,%ebx - movl %edx,20(%edi) - - movl 24(%esi),%eax - movl 28(%esi),%edx - adcl %eax,%eax - movl %ebx,24(%edi) - adcl %edx,%edx - movl %eax,28(%edi) - - leal 32(%esi),%esi /* use leal not to clobber carry */ - leal 32(%edi),%edi - decl %ebp - jnz LLoop - -LLend: popl %ebp - sbbl %eax,%eax /* save carry in %eax */ - andl $7,%ebp - jz LLend2 - addl %eax,%eax /* restore carry from eax */ -LLoop2: movl %edx,%ebx - movl (%esi),%edx - adcl %edx,%edx - movl %ebx,(%edi) - - leal 4(%esi),%esi /* use leal not to clobber carry */ - leal 4(%edi),%edi - decl %ebp - jnz LLoop2 - - jmp LL1 -LLend2: addl %eax,%eax /* restore carry from eax */ -LL1: movl %edx,(%edi) /* store last limb */ - - sbbl %eax,%eax - negl %eax - - popl %ebp - popl %ebx - popl %esi - popl %edi - ret - - diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-mul1.S deleted file mode 100644 index 3601d968b..000000000 --- a/grub-core/lib/libgcrypt/mpi/i586/mpih-mul1.S +++ /dev/null @@ -1,89 +0,0 @@ -/* i80586 mul_1 -- Multiply a limb vector with a limb and store - * the result in a second limb vector. - * - * Copyright (C) 1992, 1994, 1996, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_size_t s1_size, (sp + 12) - * mpi_limb_t s2_limb) (sp + 16) - */ - -#define res_ptr edi -#define s1_ptr esi -#define size ecx -#define s2_limb ebp - - TEXT - ALIGN (3) - GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1) -C_SYMBOL_NAME(_gcry_mpih_mul_1:) - - INSN1(push,l ,R(edi)) - INSN1(push,l ,R(esi)) - INSN1(push,l ,R(ebx)) - INSN1(push,l ,R(ebp)) - - INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20)) - INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24)) - INSN2(mov,l ,R(size),MEM_DISP(esp,28)) - INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32)) - - INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4)) - INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4)) - INSN1(neg,l ,R(size)) - INSN2(xor,l ,R(ebx),R(ebx)) - ALIGN (3) - -Loop: INSN2(adc,l ,R(ebx),$0) - INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4)) - - INSN1(mul,l ,R(s2_limb)) - - INSN2(add,l ,R(ebx),R(eax)) - - INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx)) - INSN1(inc,l ,R(size)) - - INSN2(mov,l ,R(ebx),R(edx)) - INSN1(jnz, ,Loop) - - INSN2(adc,l ,R(ebx),$0) - INSN2(mov,l ,R(eax),R(ebx)) - INSN1(pop,l ,R(ebp)) - INSN1(pop,l ,R(ebx)) - INSN1(pop,l ,R(esi)) - INSN1(pop,l ,R(edi)) - ret - diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-mul2.S deleted file mode 100644 index f32d363a7..000000000 --- a/grub-core/lib/libgcrypt/mpi/i586/mpih-mul2.S +++ /dev/null @@ -1,93 +0,0 @@ -/* i80586 addmul_1 -- Multiply a limb vector with a limb and add - * the result to a second limb vector. - * - * Copyright (C) 1992, 1994, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_size_t s1_size, (sp + 12) - * mpi_limb_t s2_limb) (sp + 16) - */ - -#define res_ptr edi -#define s1_ptr esi -#define size ecx -#define s2_limb ebp - - TEXT - ALIGN (3) - GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1) -C_SYMBOL_NAME(_gcry_mpih_addmul_1:) - - INSN1(push,l ,R(edi)) - INSN1(push,l ,R(esi)) - INSN1(push,l ,R(ebx)) - INSN1(push,l ,R(ebp)) - - INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20)) - INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24)) - INSN2(mov,l ,R(size),MEM_DISP(esp,28)) - INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32)) - - INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4)) - INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4)) - INSN1(neg,l ,R(size)) - INSN2(xor,l ,R(ebx),R(ebx)) - ALIGN (3) - -Loop: INSN2(adc,l ,R(ebx),$0) - INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4)) - - INSN1(mul,l ,R(s2_limb)) - - INSN2(add,l ,R(eax),R(ebx)) - INSN2(mov,l ,R(ebx),MEM_INDEX(res_ptr,size,4)) - - INSN2(adc,l ,R(edx),$0) - INSN2(add,l ,R(ebx),R(eax)) - - INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx)) - INSN1(inc,l ,R(size)) - - INSN2(mov,l ,R(ebx),R(edx)) - INSN1(jnz, ,Loop) - - INSN2(adc,l ,R(ebx),$0) - INSN2(mov,l ,R(eax),R(ebx)) - INSN1(pop,l ,R(ebp)) - INSN1(pop,l ,R(ebx)) - INSN1(pop,l ,R(esi)) - INSN1(pop,l ,R(edi)) - ret - diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-mul3.S deleted file mode 100644 index fa27d4e1a..000000000 --- a/grub-core/lib/libgcrypt/mpi/i586/mpih-mul3.S +++ /dev/null @@ -1,93 +0,0 @@ -/* i80586 submul_1 -- Multiply a limb vector with a limb and add - * the result to a second limb vector. - * - * Copyright (C) 1992, 1994, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_size_t s1_size, (sp + 12) - * mpi_limb_t s2_limb) (sp + 16) - */ - -#define res_ptr edi -#define s1_ptr esi -#define size ecx -#define s2_limb ebp - - TEXT - ALIGN (3) - GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1) -C_SYMBOL_NAME(_gcry_mpih_submul_1:) - - INSN1(push,l ,R(edi)) - INSN1(push,l ,R(esi)) - INSN1(push,l ,R(ebx)) - INSN1(push,l ,R(ebp)) - - INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20)) - INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24)) - INSN2(mov,l ,R(size),MEM_DISP(esp,28)) - INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32)) - - INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4)) - INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4)) - INSN1(neg,l ,R(size)) - INSN2(xor,l ,R(ebx),R(ebx)) - ALIGN (3) - -Loop: INSN2(adc,l ,R(ebx),$0) - INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4)) - - INSN1(mul,l ,R(s2_limb)) - - INSN2(add,l ,R(eax),R(ebx)) - INSN2(mov,l ,R(ebx),MEM_INDEX(res_ptr,size,4)) - - INSN2(adc,l ,R(edx),$0) - INSN2(sub,l ,R(ebx),R(eax)) - - INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx)) - INSN1(inc,l ,R(size)) - - INSN2(mov,l ,R(ebx),R(edx)) - INSN1(jnz, ,Loop) - - INSN2(adc,l ,R(ebx),$0) - INSN2(mov,l ,R(eax),R(ebx)) - INSN1(pop,l ,R(ebp)) - INSN1(pop,l ,R(ebx)) - INSN1(pop,l ,R(esi)) - INSN1(pop,l ,R(edi)) - ret - diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-rshift.S deleted file mode 100644 index c661e3d3b..000000000 --- a/grub-core/lib/libgcrypt/mpi/i586/mpih-rshift.S +++ /dev/null @@ -1,228 +0,0 @@ -/* i80586 rshift - * - * Copyright (C) 1992, 1994, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - - -/******************* - * mpi_limb_t - * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4) - * mpi_ptr_t up, (sp + 8) - * mpi_size_t usize, (sp + 12) - * unsigned cnt) (sp + 16) - */ - -.text - ALIGN (3) - .globl C_SYMBOL_NAME(_gcry_mpih_rshift) -C_SYMBOL_NAME(_gcry_mpih_rshift:) - pushl %edi - pushl %esi - pushl %ebx - pushl %ebp - - movl 20(%esp),%edi /* res_ptr */ - movl 24(%esp),%esi /* s_ptr */ - movl 28(%esp),%ebp /* size */ - movl 32(%esp),%ecx /* cnt */ - -/* We can use faster code for shift-by-1 under certain conditions. */ - cmp $1,%ecx - jne Rnormal - leal 4(%edi),%eax - cmpl %esi,%eax - jnc Rspecial /* jump if res_ptr + 1 >= s_ptr */ - leal (%edi,%ebp,4),%eax - cmpl %eax,%esi - jnc Rspecial /* jump if s_ptr >= res_ptr + size */ - -Rnormal: - movl (%esi),%edx - addl $4,%esi - xorl %eax,%eax - shrdl %cl,%edx,%eax /* compute carry limb */ - pushl %eax /* push carry limb onto stack */ - - decl %ebp - pushl %ebp - shrl $3,%ebp - jz Rend - - movl (%edi),%eax /* fetch destination cache line */ - - ALIGN (2) -Roop: movl 28(%edi),%eax /* fetch destination cache line */ - movl %edx,%ebx - - movl (%esi),%eax - movl 4(%esi),%edx - shrdl %cl,%eax,%ebx - shrdl %cl,%edx,%eax - movl %ebx,(%edi) - movl %eax,4(%edi) - - movl 8(%esi),%ebx - movl 12(%esi),%eax - shrdl %cl,%ebx,%edx - shrdl %cl,%eax,%ebx - movl %edx,8(%edi) - movl %ebx,12(%edi) - - movl 16(%esi),%edx - movl 20(%esi),%ebx - shrdl %cl,%edx,%eax - shrdl %cl,%ebx,%edx - movl %eax,16(%edi) - movl %edx,20(%edi) - - movl 24(%esi),%eax - movl 28(%esi),%edx - shrdl %cl,%eax,%ebx - shrdl %cl,%edx,%eax - movl %ebx,24(%edi) - movl %eax,28(%edi) - - addl $32,%esi - addl $32,%edi - decl %ebp - jnz Roop - -Rend: popl %ebp - andl $7,%ebp - jz Rend2 -Roop2: movl (%esi),%eax - shrdl %cl,%eax,%edx /* compute result limb */ - movl %edx,(%edi) - movl %eax,%edx - addl $4,%esi - addl $4,%edi - decl %ebp - jnz Roop2 - -Rend2: shrl %cl,%edx /* compute most significant limb */ - movl %edx,(%edi) /* store it */ - - popl %eax /* pop carry limb */ - - popl %ebp - popl %ebx - popl %esi - popl %edi - ret - -/* We loop from least significant end of the arrays, which is only - permissable if the source and destination don't overlap, since the - function is documented to work for overlapping source and destination. -*/ - -Rspecial: - leal -4(%edi,%ebp,4),%edi - leal -4(%esi,%ebp,4),%esi - - movl (%esi),%edx - subl $4,%esi - - decl %ebp - pushl %ebp - shrl $3,%ebp - - shrl $1,%edx - incl %ebp - decl %ebp - jz RLend - - movl (%edi),%eax /* fetch destination cache line */ - - ALIGN (2) -RLoop: movl -28(%edi),%eax /* fetch destination cache line */ - movl %edx,%ebx - - movl (%esi),%eax - movl -4(%esi),%edx - rcrl $1,%eax - movl %ebx,(%edi) - rcrl $1,%edx - movl %eax,-4(%edi) - - movl -8(%esi),%ebx - movl -12(%esi),%eax - rcrl $1,%ebx - movl %edx,-8(%edi) - rcrl $1,%eax - movl %ebx,-12(%edi) - - movl -16(%esi),%edx - movl -20(%esi),%ebx - rcrl $1,%edx - movl %eax,-16(%edi) - rcrl $1,%ebx - movl %edx,-20(%edi) - - movl -24(%esi),%eax - movl -28(%esi),%edx - rcrl $1,%eax - movl %ebx,-24(%edi) - rcrl $1,%edx - movl %eax,-28(%edi) - - leal -32(%esi),%esi /* use leal not to clobber carry */ - leal -32(%edi),%edi - decl %ebp - jnz RLoop - -RLend: popl %ebp - sbbl %eax,%eax /* save carry in %eax */ - andl $7,%ebp - jz RLend2 - addl %eax,%eax /* restore carry from eax */ -RLoop2: movl %edx,%ebx - movl (%esi),%edx - rcrl $1,%edx - movl %ebx,(%edi) - - leal -4(%esi),%esi /* use leal not to clobber carry */ - leal -4(%edi),%edi - decl %ebp - jnz RLoop2 - - jmp RL1 -RLend2: addl %eax,%eax /* restore carry from eax */ -RL1: movl %edx,(%edi) /* store last limb */ - - movl $0,%eax - rcrl $1,%eax - - popl %ebp - popl %ebx - popl %esi - popl %edi - ret - diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-sub1.S deleted file mode 100644 index ef2d58074..000000000 --- a/grub-core/lib/libgcrypt/mpi/i586/mpih-sub1.S +++ /dev/null @@ -1,142 +0,0 @@ -/* i80586 sub_n -- Sub two limb vectors of the same length > 0 and store - * sum in a third limb vector. - * - * Copyright (C) 1992, 1994, 1995, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_ptr_t s2_ptr, (sp + 12) - * mpi_size_t size) (sp + 16) - */ - - -.text - ALIGN (3) - .globl C_SYMBOL_NAME(_gcry_mpih_sub_n) -C_SYMBOL_NAME(_gcry_mpih_sub_n:) - - pushl %edi - pushl %esi - pushl %ebx - pushl %ebp - - movl 20(%esp),%edi /* res_ptr */ - movl 24(%esp),%esi /* s1_ptr */ - movl 28(%esp),%ebp /* s2_ptr */ - movl 32(%esp),%ecx /* size */ - - movl (%ebp),%ebx - - decl %ecx - movl %ecx,%edx - shrl $3,%ecx - andl $7,%edx - testl %ecx,%ecx /* zero carry flag */ - jz Lend - pushl %edx - - ALIGN (3) -Loop: movl 28(%edi),%eax /* fetch destination cache line */ - leal 32(%edi),%edi - -L1: movl (%esi),%eax - movl 4(%esi),%edx - sbbl %ebx,%eax - movl 4(%ebp),%ebx - sbbl %ebx,%edx - movl 8(%ebp),%ebx - movl %eax,-32(%edi) - movl %edx,-28(%edi) - -L2: movl 8(%esi),%eax - movl 12(%esi),%edx - sbbl %ebx,%eax - movl 12(%ebp),%ebx - sbbl %ebx,%edx - movl 16(%ebp),%ebx - movl %eax,-24(%edi) - movl %edx,-20(%edi) - -L3: movl 16(%esi),%eax - movl 20(%esi),%edx - sbbl %ebx,%eax - movl 20(%ebp),%ebx - sbbl %ebx,%edx - movl 24(%ebp),%ebx - movl %eax,-16(%edi) - movl %edx,-12(%edi) - -L4: movl 24(%esi),%eax - movl 28(%esi),%edx - sbbl %ebx,%eax - movl 28(%ebp),%ebx - sbbl %ebx,%edx - movl 32(%ebp),%ebx - movl %eax,-8(%edi) - movl %edx,-4(%edi) - - leal 32(%esi),%esi - leal 32(%ebp),%ebp - decl %ecx - jnz Loop - - popl %edx -Lend: - decl %edx /* test %edx w/o clobbering carry */ - js Lend2 - incl %edx -Loop2: - leal 4(%edi),%edi - movl (%esi),%eax - sbbl %ebx,%eax - movl 4(%ebp),%ebx - movl %eax,-4(%edi) - leal 4(%esi),%esi - leal 4(%ebp),%ebp - decl %edx - jnz Loop2 -Lend2: - movl (%esi),%eax - sbbl %ebx,%eax - movl %eax,(%edi) - - sbbl %eax,%eax - negl %eax - - popl %ebp - popl %ebx - popl %esi - popl %edi - ret - diff --git a/grub-core/lib/libgcrypt/mpi/longlong.h b/grub-core/lib/libgcrypt/mpi/longlong.h deleted file mode 100644 index b3fce0958..000000000 --- a/grub-core/lib/libgcrypt/mpi/longlong.h +++ /dev/null @@ -1,1613 +0,0 @@ -/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. - Note: I added some stuff for use with gnupg - -Copyright (C) 1991, 1992, 1993, 1994, 1996, 1998, - 2000, 2001, 2002, 2003, 2004, 2011 Free Software Foundation, Inc. - -This file 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 file is distributed in the hope that 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 Library General Public License -along with this file; see the file COPYING.LIB. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, -MA 02111-1307, USA. */ - -/* You have to define the following before including this file: - - UWtype -- An unsigned type, default type for operations (typically a "word") - UHWtype -- An unsigned type, at least half the size of UWtype. - UDWtype -- An unsigned type, at least twice as large a UWtype - W_TYPE_SIZE -- size in bits of UWtype - - SItype, USItype -- Signed and unsigned 32 bit types. - DItype, UDItype -- Signed and unsigned 64 bit types. - - On a 32 bit machine UWtype should typically be USItype; - on a 64 bit machine, UWtype should typically be UDItype. -*/ - -#define __BITS4 (W_TYPE_SIZE / 4) -#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) -#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) -#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) - -/* This is used to make sure no undesirable sharing between different libraries - that use this file takes place. */ -#ifndef __MPN -#define __MPN(x) __##x -#endif - -/* Define auxiliary asm macros. - - 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two - UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype - word product in HIGH_PROD and LOW_PROD. - - 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a - UDWtype product. This is just a variant of umul_ppmm. - - 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, - denominator) divides a UDWtype, composed by the UWtype integers - HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient - in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less - than DENOMINATOR for correct operation. If, in addition, the most - significant bit of DENOMINATOR must be 1, then the pre-processor symbol - UDIV_NEEDS_NORMALIZATION is defined to 1. - - 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, - denominator). Like udiv_qrnnd but the numbers are signed. The quotient - is rounded towards 0. - - 5) count_leading_zeros(count, x) counts the number of zero-bits from the - msb to the first non-zero bit in the UWtype X. This is the number of - steps X needs to be shifted left to set the msb. Undefined for X == 0, - unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. - - 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts - from the least significant end. - - 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, - high_addend_2, low_addend_2) adds two UWtype integers, composed by - HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 - respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow - (i.e. carry out) is not stored anywhere, and is lost. - - 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, - high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, - composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and - LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE - and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, - and is lost. - - If any of these macros are left undefined for a particular CPU, - C macros are used. */ - -/* The CPUs come in alphabetical order below. - - Please add support for more CPUs here, or improve the current support - for the CPUs below! */ - -#ifdef __riscos__ -#pragma continue_after_hash_error -#else /* !__riscos__ */ -#if defined (__GNUC__) && !defined (NO_ASM) - -/* We sometimes need to clobber "cc" with gcc2, but that would not be - understood by gcc1. Use cpp to avoid major code duplication. */ -#if __GNUC__ < 2 -#define __CLOBBER_CC -#define __AND_CLOBBER_CC -#else /* __GNUC__ >= 2 */ -#define __CLOBBER_CC : "cc" -#define __AND_CLOBBER_CC , "cc" -#endif /* __GNUC__ < 2 */ - - -/*************************************** - ************** A29K ***************** - ***************************************/ -#if (defined (__a29k__) || defined (_AM29K)) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("add %1,%4,%5\n" \ - "addc %0,%2,%3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ - : "%r" ((USItype)(ah)), \ - "rI" ((USItype)(bh)), \ - "%r" ((USItype)(al)), \ - "rI" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("sub %1,%4,%5\n" \ - "subc %0,%2,%3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ - : "r" ((USItype)(ah)), \ - "rI" ((USItype)(bh)), \ - "r" ((USItype)(al)), \ - "rI" ((USItype)(bl))) -#define umul_ppmm(xh, xl, m0, m1) \ - do { \ - USItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("multiplu %0,%1,%2" \ - : "=r" ((USItype)(xl)) \ - : "r" (__m0), \ - "r" (__m1)); \ - __asm__ ("multmu %0,%1,%2" \ - : "=r" ((USItype)(xh)) \ - : "r" (__m0), \ - "r" (__m1)); \ - } while (0) -#define udiv_qrnnd(q, r, n1, n0, d) \ - __asm__ ("dividu %0,%3,%4" \ - : "=r" ((USItype)(q)), \ - "=q" ((USItype)(r)) \ - : "1" ((USItype)(n1)), \ - "r" ((USItype)(n0)), \ - "r" ((USItype)(d))) -#define count_leading_zeros(count, x) \ - __asm__ ("clz %0,%1" \ - : "=r" ((USItype)(count)) \ - : "r" ((USItype)(x))) -#define COUNT_LEADING_ZEROS_0 32 -#endif /* __a29k__ */ - - -#if defined (__alpha) && W_TYPE_SIZE == 64 -#define umul_ppmm(ph, pl, m0, m1) \ - do { \ - UDItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("umulh %r1,%2,%0" \ - : "=r" ((UDItype) ph) \ - : "%rJ" (__m0), \ - "rI" (__m1)); \ - (pl) = __m0 * __m1; \ - } while (0) -#define UMUL_TIME 46 -#ifndef LONGLONG_STANDALONE -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { UDItype __r; \ - (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ - (r) = __r; \ - } while (0) -extern UDItype __udiv_qrnnd (); -#define UDIV_TIME 220 -#endif /* LONGLONG_STANDALONE */ -#endif /* __alpha */ - -/*************************************** - ************** ARM ****************** - ***************************************/ -#if defined (__arm__) && W_TYPE_SIZE == 32 && \ - (!defined (__thumb__) || defined (__thumb2__)) -/* The __ARM_ARCH define is provided by gcc 4.8. Construct it otherwise. */ -#ifndef __ARM_ARCH -# ifdef __ARM_ARCH_2__ -# define __ARM_ARCH 2 -# elif defined (__ARM_ARCH_3__) || defined (__ARM_ARCH_3M__) -# define __ARM_ARCH 3 -# elif defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__) -# define __ARM_ARCH 4 -# elif defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5E__) \ - || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \ - || defined(__ARM_ARCH_5TEJ__) -# define __ARM_ARCH 5 -# elif defined (__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ - || defined (__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \ - || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) -# define __ARM_ARCH 6 -# elif defined (__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ - || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \ - || defined(__ARM_ARCH_7EM__) -# define __ARM_ARCH 7 -# else - /* could not detect? */ -# endif -#endif -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("adds %1, %4, %5\n" \ - "adc %0, %2, %3" \ - : "=r" ((sh)), \ - "=&r" ((sl)) \ - : "%r" ((USItype)(ah)), \ - "rI" ((USItype)(bh)), \ - "%r" ((USItype)(al)), \ - "rI" ((USItype)(bl)) __CLOBBER_CC) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subs %1, %4, %5\n" \ - "sbc %0, %2, %3" \ - : "=r" ((sh)), \ - "=&r" ((sl)) \ - : "r" ((USItype)(ah)), \ - "rI" ((USItype)(bh)), \ - "r" ((USItype)(al)), \ - "rI" ((USItype)(bl)) __CLOBBER_CC) -#if (defined __ARM_ARCH && __ARM_ARCH <= 3) -#define umul_ppmm(xh, xl, a, b) \ - __asm__ ("@ Inlined umul_ppmm\n" \ - "mov %|r0, %2, lsr #16 @ AAAA\n" \ - "mov %|r2, %3, lsr #16 @ BBBB\n" \ - "bic %|r1, %2, %|r0, lsl #16 @ aaaa\n" \ - "bic %0, %3, %|r2, lsl #16 @ bbbb\n" \ - "mul %1, %|r1, %|r2 @ aaaa * BBBB\n" \ - "mul %|r2, %|r0, %|r2 @ AAAA * BBBB\n" \ - "mul %|r1, %0, %|r1 @ aaaa * bbbb\n" \ - "mul %0, %|r0, %0 @ AAAA * bbbb\n" \ - "adds %|r0, %1, %0 @ central sum\n" \ - "addcs %|r2, %|r2, #65536\n" \ - "adds %1, %|r1, %|r0, lsl #16\n" \ - "adc %0, %|r2, %|r0, lsr #16" \ - : "=&r" ((xh)), \ - "=r" ((xl)) \ - : "r" ((USItype)(a)), \ - "r" ((USItype)(b)) \ - : "r0", "r1", "r2" __AND_CLOBBER_CC) -#else /* __ARM_ARCH >= 4 */ -#define umul_ppmm(xh, xl, a, b) \ - __asm__ ("@ Inlined umul_ppmm\n" \ - "umull %1, %0, %2, %3" \ - : "=&r" ((xh)), \ - "=r" ((xl)) \ - : "r" ((USItype)(a)), \ - "r" ((USItype)(b))) -#endif /* __ARM_ARCH >= 4 */ -#define UMUL_TIME 20 -#define UDIV_TIME 100 -#if (defined __ARM_ARCH && __ARM_ARCH >= 5) -#define count_leading_zeros(count, x) \ - __asm__ ("clz %0, %1" \ - : "=r" ((count)) \ - : "r" ((USItype)(x))) -#endif /* __ARM_ARCH >= 5 */ -#endif /* __arm__ */ - -/*************************************** - ************** CLIPPER ************** - ***************************************/ -#if defined (__clipper__) && W_TYPE_SIZE == 32 -#define umul_ppmm(w1, w0, u, v) \ - ({union {UDItype __ll; \ - struct {USItype __l, __h;} __i; \ - } __xx; \ - __asm__ ("mulwux %2,%0" \ - : "=r" (__xx.__ll) \ - : "%0" ((USItype)(u)), \ - "r" ((USItype)(v))); \ - (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) -#define smul_ppmm(w1, w0, u, v) \ - ({union {DItype __ll; \ - struct {SItype __l, __h;} __i; \ - } __xx; \ - __asm__ ("mulwx %2,%0" \ - : "=r" (__xx.__ll) \ - : "%0" ((SItype)(u)), \ - "r" ((SItype)(v))); \ - (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) -#define __umulsidi3(u, v) \ - ({UDItype __w; \ - __asm__ ("mulwux %2,%0" \ - : "=r" (__w) \ - : "%0" ((USItype)(u)), \ - "r" ((USItype)(v))); \ - __w; }) -#endif /* __clipper__ */ - - -/*************************************** - ************** GMICRO *************** - ***************************************/ -#if defined (__gmicro__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("add.w %5,%1\n" \ - "addx %3,%0" \ - : "=g" ((USItype)(sh)), \ - "=&g" ((USItype)(sl)) \ - : "%0" ((USItype)(ah)), \ - "g" ((USItype)(bh)), \ - "%1" ((USItype)(al)), \ - "g" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("sub.w %5,%1\n" \ - "subx %3,%0" \ - : "=g" ((USItype)(sh)), \ - "=&g" ((USItype)(sl)) \ - : "0" ((USItype)(ah)), \ - "g" ((USItype)(bh)), \ - "1" ((USItype)(al)), \ - "g" ((USItype)(bl))) -#define umul_ppmm(ph, pl, m0, m1) \ - __asm__ ("mulx %3,%0,%1" \ - : "=g" ((USItype)(ph)), \ - "=r" ((USItype)(pl)) \ - : "%0" ((USItype)(m0)), \ - "g" ((USItype)(m1))) -#define udiv_qrnnd(q, r, nh, nl, d) \ - __asm__ ("divx %4,%0,%1" \ - : "=g" ((USItype)(q)), \ - "=r" ((USItype)(r)) \ - : "1" ((USItype)(nh)), \ - "0" ((USItype)(nl)), \ - "g" ((USItype)(d))) -#define count_leading_zeros(count, x) \ - __asm__ ("bsch/1 %1,%0" \ - : "=g" (count) \ - : "g" ((USItype)(x)), \ - "0" ((USItype)0)) -#endif - - -/*************************************** - ************** HPPA ***************** - ***************************************/ -#if defined (__hppa) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ (" add %4,%5,%1\n" \ - " addc %2,%3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ - : "%rM" ((USItype)(ah)), \ - "rM" ((USItype)(bh)), \ - "%rM" ((USItype)(al)), \ - "rM" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ (" sub %4,%5,%1\n" \ - " subb %2,%3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ - : "rM" ((USItype)(ah)), \ - "rM" ((USItype)(bh)), \ - "rM" ((USItype)(al)), \ - "rM" ((USItype)(bl))) -#if defined (_PA_RISC1_1) -#define umul_ppmm(wh, wl, u, v) \ - do { \ - union {UDItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __xx; \ - __asm__ (" xmpyu %1,%2,%0" \ - : "=*f" (__xx.__ll) \ - : "*f" ((USItype)(u)), \ - "*f" ((USItype)(v))); \ - (wh) = __xx.__i.__h; \ - (wl) = __xx.__i.__l; \ - } while (0) -#define UMUL_TIME 8 -#define UDIV_TIME 60 -#else -#define UMUL_TIME 40 -#define UDIV_TIME 80 -#endif -#ifndef LONGLONG_STANDALONE -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { USItype __r; \ - (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ - (r) = __r; \ - } while (0) -extern USItype __udiv_qrnnd (); -#endif /* LONGLONG_STANDALONE */ -#define count_leading_zeros(count, x) \ - do { \ - USItype __tmp; \ - __asm__ ( \ - " ldi 1,%0 \n" \ - " extru,= %1,15,16,%%r0 ; Bits 31..16 zero? \n" \ - " extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n" \ - " ldo 16(%0),%0 ; Yes. Perform add. \n" \ - " extru,= %1,23,8,%%r0 ; Bits 15..8 zero? \n" \ - " extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n" \ - " ldo 8(%0),%0 ; Yes. Perform add. \n" \ - " extru,= %1,27,4,%%r0 ; Bits 7..4 zero? \n" \ - " extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n" \ - " ldo 4(%0),%0 ; Yes. Perform add. \n" \ - " extru,= %1,29,2,%%r0 ; Bits 3..2 zero? \n" \ - " extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n" \ - " ldo 2(%0),%0 ; Yes. Perform add. \n" \ - " extru %1,30,1,%1 ; Extract bit 1. \n" \ - " sub %0,%1,%0 ; Subtract it. " \ - : "=r" (count), "=r" (__tmp) : "1" (x)); \ - } while (0) -#endif /* hppa */ - - -/*************************************** - ************** I370 ***************** - ***************************************/ -#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32 -#define umul_ppmm(xh, xl, m0, m1) \ - do { \ - union {UDItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __xx; \ - USItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("mr %0,%3" \ - : "=r" (__xx.__i.__h), \ - "=r" (__xx.__i.__l) \ - : "%1" (__m0), \ - "r" (__m1)); \ - (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ - (xh) += ((((SItype) __m0 >> 31) & __m1) \ - + (((SItype) __m1 >> 31) & __m0)); \ - } while (0) -#define smul_ppmm(xh, xl, m0, m1) \ - do { \ - union {DItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __xx; \ - __asm__ ("mr %0,%3" \ - : "=r" (__xx.__i.__h), \ - "=r" (__xx.__i.__l) \ - : "%1" (m0), \ - "r" (m1)); \ - (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ - } while (0) -#define sdiv_qrnnd(q, r, n1, n0, d) \ - do { \ - union {DItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __xx; \ - __xx.__i.__h = n1; __xx.__i.__l = n0; \ - __asm__ ("dr %0,%2" \ - : "=r" (__xx.__ll) \ - : "0" (__xx.__ll), "r" (d)); \ - (q) = __xx.__i.__l; (r) = __xx.__i.__h; \ - } while (0) -#endif - - -/*************************************** - ************** I386 ***************** - ***************************************/ -#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("addl %5,%1\n" \ - "adcl %3,%0" \ - : "=r" ((sh)), \ - "=&r" ((sl)) \ - : "%0" ((USItype)(ah)), \ - "g" ((USItype)(bh)), \ - "%1" ((USItype)(al)), \ - "g" ((USItype)(bl)) \ - __CLOBBER_CC) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subl %5,%1\n" \ - "sbbl %3,%0" \ - : "=r" ((sh)), \ - "=&r" ((sl)) \ - : "0" ((USItype)(ah)), \ - "g" ((USItype)(bh)), \ - "1" ((USItype)(al)), \ - "g" ((USItype)(bl)) \ - __CLOBBER_CC) -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("mull %3" \ - : "=a" ((w0)), \ - "=d" ((w1)) \ - : "%0" ((USItype)(u)), \ - "rm" ((USItype)(v)) \ - __CLOBBER_CC) -#define udiv_qrnnd(q, r, n1, n0, d) \ - __asm__ ("divl %4" \ - : "=a" ((q)), \ - "=d" ((r)) \ - : "0" ((USItype)(n0)), \ - "1" ((USItype)(n1)), \ - "rm" ((USItype)(d)) \ - __CLOBBER_CC) -#define count_leading_zeros(count, x) \ - do { \ - USItype __cbtmp; \ - __asm__ ("bsrl %1,%0" \ - : "=r" (__cbtmp) : "rm" ((USItype)(x)) \ - __CLOBBER_CC); \ - (count) = __cbtmp ^ 31; \ - } while (0) -#define count_trailing_zeros(count, x) \ - __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)) __CLOBBER_CC) -#ifndef UMUL_TIME -#define UMUL_TIME 40 -#endif -#ifndef UDIV_TIME -#define UDIV_TIME 40 -#endif -#endif /* 80x86 */ - - -/*************************************** - ************** I860 ***************** - ***************************************/ -#if defined (__i860__) && W_TYPE_SIZE == 32 -#define rshift_rhlc(r,h,l,c) \ - __asm__ ("shr %3,r0,r0\n" \ - "shrd %1,%2,%0" \ - "=r" (r) : "r" (h), "r" (l), "rn" (c)) -#endif /* i860 */ - -/*************************************** - ************** I960 ***************** - ***************************************/ -#if defined (__i960__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("cmpo 1,0\n" \ - "addc %5,%4,%1\n" \ - "addc %3,%2,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ - : "%dI" ((USItype)(ah)), \ - "dI" ((USItype)(bh)), \ - "%dI" ((USItype)(al)), \ - "dI" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("cmpo 0,0\n" \ - "subc %5,%4,%1\n" \ - "subc %3,%2,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ - : "dI" ((USItype)(ah)), \ - "dI" ((USItype)(bh)), \ - "dI" ((USItype)(al)), \ - "dI" ((USItype)(bl))) -#define umul_ppmm(w1, w0, u, v) \ - ({union {UDItype __ll; \ - struct {USItype __l, __h;} __i; \ - } __xx; \ - __asm__ ("emul %2,%1,%0" \ - : "=d" (__xx.__ll) \ - : "%dI" ((USItype)(u)), \ - "dI" ((USItype)(v))); \ - (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) -#define __umulsidi3(u, v) \ - ({UDItype __w; \ - __asm__ ("emul %2,%1,%0" \ - : "=d" (__w) \ - : "%dI" ((USItype)(u)), \ - "dI" ((USItype)(v))); \ - __w; }) -#define udiv_qrnnd(q, r, nh, nl, d) \ - do { \ - union {UDItype __ll; \ - struct {USItype __l, __h;} __i; \ - } __nn; \ - __nn.__i.__h = (nh); __nn.__i.__l = (nl); \ - __asm__ ("ediv %d,%n,%0" \ - : "=d" (__rq.__ll) \ - : "dI" (__nn.__ll), \ - "dI" ((USItype)(d))); \ - (r) = __rq.__i.__l; (q) = __rq.__i.__h; \ - } while (0) -#define count_leading_zeros(count, x) \ - do { \ - USItype __cbtmp; \ - __asm__ ("scanbit %1,%0" \ - : "=r" (__cbtmp) \ - : "r" ((USItype)(x))); \ - (count) = __cbtmp ^ 31; \ - } while (0) -#define COUNT_LEADING_ZEROS_0 (-32) /* sic */ -#if defined (__i960mx) /* what is the proper symbol to test??? */ -#define rshift_rhlc(r,h,l,c) \ - do { \ - union {UDItype __ll; \ - struct {USItype __l, __h;} __i; \ - } __nn; \ - __nn.__i.__h = (h); __nn.__i.__l = (l); \ - __asm__ ("shre %2,%1,%0" \ - : "=d" (r) : "dI" (__nn.__ll), "dI" (c)); \ - } -#endif /* i960mx */ -#endif /* i960 */ - - -/*************************************** - ************** 68000 **************** - ***************************************/ -#if (defined (__mc68000__) || defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("add%.l %5,%1\n" \ - "addx%.l %3,%0" \ - : "=d" ((USItype)(sh)), \ - "=&d" ((USItype)(sl)) \ - : "%0" ((USItype)(ah)), \ - "d" ((USItype)(bh)), \ - "%1" ((USItype)(al)), \ - "g" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("sub%.l %5,%1\n" \ - "subx%.l %3,%0" \ - : "=d" ((USItype)(sh)), \ - "=&d" ((USItype)(sl)) \ - : "0" ((USItype)(ah)), \ - "d" ((USItype)(bh)), \ - "1" ((USItype)(al)), \ - "g" ((USItype)(bl))) -#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("mulu%.l %3,%1:%0" \ - : "=d" ((USItype)(w0)), \ - "=d" ((USItype)(w1)) \ - : "%0" ((USItype)(u)), \ - "dmi" ((USItype)(v))) -#define UMUL_TIME 45 -#define udiv_qrnnd(q, r, n1, n0, d) \ - __asm__ ("divu%.l %4,%1:%0" \ - : "=d" ((USItype)(q)), \ - "=d" ((USItype)(r)) \ - : "0" ((USItype)(n0)), \ - "1" ((USItype)(n1)), \ - "dmi" ((USItype)(d))) -#define UDIV_TIME 90 -#define sdiv_qrnnd(q, r, n1, n0, d) \ - __asm__ ("divs%.l %4,%1:%0" \ - : "=d" ((USItype)(q)), \ - "=d" ((USItype)(r)) \ - : "0" ((USItype)(n0)), \ - "1" ((USItype)(n1)), \ - "dmi" ((USItype)(d))) -#define count_leading_zeros(count, x) \ - __asm__ ("bfffo %1{%b2:%b2},%0" \ - : "=d" ((USItype)(count)) \ - : "od" ((USItype)(x)), "n" (0)) -#define COUNT_LEADING_ZEROS_0 32 -#else /* not mc68020 */ -#define umul_ppmm(xh, xl, a, b) \ - do { USItype __umul_tmp1, __umul_tmp2; \ - __asm__ ("| Inlined umul_ppmm \n" \ - " move%.l %5,%3 \n" \ - " move%.l %2,%0 \n" \ - " move%.w %3,%1 \n" \ - " swap %3 \n" \ - " swap %0 \n" \ - " mulu %2,%1 \n" \ - " mulu %3,%0 \n" \ - " mulu %2,%3 \n" \ - " swap %2 \n" \ - " mulu %5,%2 \n" \ - " add%.l %3,%2 \n" \ - " jcc 1f \n" \ - " add%.l %#0x10000,%0 \n" \ - "1: move%.l %2,%3 \n" \ - " clr%.w %2 \n" \ - " swap %2 \n" \ - " swap %3 \n" \ - " clr%.w %3 \n" \ - " add%.l %3,%1 \n" \ - " addx%.l %2,%0 \n" \ - " | End inlined umul_ppmm" \ - : "=&d" ((USItype)(xh)), "=&d" ((USItype)(xl)), \ - "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \ - : "%2" ((USItype)(a)), "d" ((USItype)(b))); \ - } while (0) -#define UMUL_TIME 100 -#define UDIV_TIME 400 -#endif /* not mc68020 */ -#endif /* mc68000 */ - - -/*************************************** - ************** 88000 **************** - ***************************************/ -#if defined (__m88000__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("addu.co %1,%r4,%r5\n" \ - "addu.ci %0,%r2,%r3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ - : "%rJ" ((USItype)(ah)), \ - "rJ" ((USItype)(bh)), \ - "%rJ" ((USItype)(al)), \ - "rJ" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subu.co %1,%r4,%r5\n" \ - "subu.ci %0,%r2,%r3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ - : "rJ" ((USItype)(ah)), \ - "rJ" ((USItype)(bh)), \ - "rJ" ((USItype)(al)), \ - "rJ" ((USItype)(bl))) -#define count_leading_zeros(count, x) \ - do { \ - USItype __cbtmp; \ - __asm__ ("ff1 %0,%1" \ - : "=r" (__cbtmp) \ - : "r" ((USItype)(x))); \ - (count) = __cbtmp ^ 31; \ - } while (0) -#define COUNT_LEADING_ZEROS_0 63 /* sic */ -#if defined (__m88110__) -#define umul_ppmm(wh, wl, u, v) \ - do { \ - union {UDItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __x; \ - __asm__ ("mulu.d %0,%1,%2" : "=r" (__x.__ll) : "r" (u), "r" (v)); \ - (wh) = __x.__i.__h; \ - (wl) = __x.__i.__l; \ - } while (0) -#define udiv_qrnnd(q, r, n1, n0, d) \ - ({union {UDItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __x, __q; \ - __x.__i.__h = (n1); __x.__i.__l = (n0); \ - __asm__ ("divu.d %0,%1,%2" \ - : "=r" (__q.__ll) : "r" (__x.__ll), "r" (d)); \ - (r) = (n0) - __q.__l * (d); (q) = __q.__l; }) -#define UMUL_TIME 5 -#define UDIV_TIME 25 -#else -#define UMUL_TIME 17 -#define UDIV_TIME 150 -#endif /* __m88110__ */ -#endif /* __m88000__ */ - -/*************************************** - ************** MIPS ***************** - ***************************************/ -#if defined (__mips__) && W_TYPE_SIZE == 32 -#if defined (__clang__) || (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) -#define umul_ppmm(w1, w0, u, v) \ - do { \ - UDItype _r; \ - _r = (UDItype) u * v; \ - (w1) = _r >> 32; \ - (w0) = (USItype) _r; \ - } while (0) -#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("multu %2,%3" \ - : "=l" ((USItype)(w0)), \ - "=h" ((USItype)(w1)) \ - : "d" ((USItype)(u)), \ - "d" ((USItype)(v))) -#else -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("multu %2,%3 \n" \ - "mflo %0 \n" \ - "mfhi %1" \ - : "=d" ((USItype)(w0)), \ - "=d" ((USItype)(w1)) \ - : "d" ((USItype)(u)), \ - "d" ((USItype)(v))) -#endif -#define UMUL_TIME 10 -#define UDIV_TIME 100 -#endif /* __mips__ */ - -/*************************************** - ************** MIPS/64 ************** - ***************************************/ -#if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64 -#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) -typedef unsigned int UTItype __attribute__ ((mode (TI))); -#define umul_ppmm(w1, w0, u, v) \ - do { \ - UTItype _r; \ - _r = (UTItype) u * v; \ - (w1) = _r >> 64; \ - (w0) = (UDItype) _r; \ - } while (0) -#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("dmultu %2,%3" \ - : "=l" ((UDItype)(w0)), \ - "=h" ((UDItype)(w1)) \ - : "d" ((UDItype)(u)), \ - "d" ((UDItype)(v))) -#else -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("dmultu %2,%3 \n" \ - "mflo %0 \n" \ - "mfhi %1" \ - : "=d" ((UDItype)(w0)), \ - "=d" ((UDItype)(w1)) \ - : "d" ((UDItype)(u)), \ - "d" ((UDItype)(v))) -#endif -#define UMUL_TIME 20 -#define UDIV_TIME 140 -#endif /* __mips__ */ - - -/*************************************** - ************** 32000 **************** - ***************************************/ -#if defined (__ns32000__) && W_TYPE_SIZE == 32 -#define umul_ppmm(w1, w0, u, v) \ - ({union {UDItype __ll; \ - struct {USItype __l, __h;} __i; \ - } __xx; \ - __asm__ ("meid %2,%0" \ - : "=g" (__xx.__ll) \ - : "%0" ((USItype)(u)), \ - "g" ((USItype)(v))); \ - (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) -#define __umulsidi3(u, v) \ - ({UDItype __w; \ - __asm__ ("meid %2,%0" \ - : "=g" (__w) \ - : "%0" ((USItype)(u)), \ - "g" ((USItype)(v))); \ - __w; }) -#define udiv_qrnnd(q, r, n1, n0, d) \ - ({union {UDItype __ll; \ - struct {USItype __l, __h;} __i; \ - } __xx; \ - __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ - __asm__ ("deid %2,%0" \ - : "=g" (__xx.__ll) \ - : "0" (__xx.__ll), \ - "g" ((USItype)(d))); \ - (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) -#define count_trailing_zeros(count,x) \ - do { - __asm__ ("ffsd %2,%0" \ - : "=r" ((USItype) (count)) \ - : "0" ((USItype) 0), \ - "r" ((USItype) (x))); \ - } while (0) -#endif /* __ns32000__ */ - - -/*************************************** - ************** PPC ****************** - ***************************************/ -#if (defined (_ARCH_PPC) || defined (_IBMR2)) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - do { \ - if (__builtin_constant_p (bh) && (bh) == 0) \ - __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ - : "=r" ((sh)), \ - "=&r" ((sl)) \ - : "%r" ((USItype)(ah)), \ - "%r" ((USItype)(al)), \ - "rI" ((USItype)(bl))); \ - else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \ - __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ - : "=r" ((sh)), \ - "=&r" ((sl)) \ - : "%r" ((USItype)(ah)), \ - "%r" ((USItype)(al)), \ - "rI" ((USItype)(bl))); \ - else \ - __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ - : "=r" ((sh)), \ - "=&r" ((sl)) \ - : "%r" ((USItype)(ah)), \ - "r" ((USItype)(bh)), \ - "%r" ((USItype)(al)), \ - "rI" ((USItype)(bl))); \ - } while (0) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - do { \ - if (__builtin_constant_p (ah) && (ah) == 0) \ - __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ - : "=r" ((sh)), \ - "=&r" ((sl)) \ - : "r" ((USItype)(bh)), \ - "rI" ((USItype)(al)), \ - "r" ((USItype)(bl))); \ - else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \ - __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ - : "=r" ((sh)), \ - "=&r" ((sl)) \ - : "r" ((USItype)(bh)), \ - "rI" ((USItype)(al)), \ - "r" ((USItype)(bl))); \ - else if (__builtin_constant_p (bh) && (bh) == 0) \ - __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ - : "=r" ((sh)), \ - "=&r" ((sl)) \ - : "r" ((USItype)(ah)), \ - "rI" ((USItype)(al)), \ - "r" ((USItype)(bl))); \ - else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \ - __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ - : "=r" ((sh)), \ - "=&r" ((sl)) \ - : "r" ((USItype)(ah)), \ - "rI" ((USItype)(al)), \ - "r" ((USItype)(bl))); \ - else \ - __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ - : "=r" ((sh)), \ - "=&r" ((sl)) \ - : "r" ((USItype)(ah)), \ - "r" ((USItype)(bh)), \ - "rI" ((USItype)(al)), \ - "r" ((USItype)(bl))); \ - } while (0) -#define count_leading_zeros(count, x) \ - __asm__ ("{cntlz|cntlzw} %0,%1" \ - : "=r" ((count)) \ - : "r" ((USItype)(x))) -#define COUNT_LEADING_ZEROS_0 32 -#if defined (_ARCH_PPC) -#define umul_ppmm(ph, pl, m0, m1) \ - do { \ - USItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("mulhwu %0,%1,%2" \ - : "=r" (ph) \ - : "%r" (__m0), \ - "r" (__m1)); \ - (pl) = __m0 * __m1; \ - } while (0) -#define UMUL_TIME 15 -#define smul_ppmm(ph, pl, m0, m1) \ - do { \ - SItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("mulhw %0,%1,%2" \ - : "=r" ((SItype) ph) \ - : "%r" (__m0), \ - "r" (__m1)); \ - (pl) = __m0 * __m1; \ - } while (0) -#define SMUL_TIME 14 -#define UDIV_TIME 120 -#else -#define umul_ppmm(xh, xl, m0, m1) \ - do { \ - USItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("mul %0,%2,%3" \ - : "=r" ((xh)), \ - "=q" ((xl)) \ - : "r" (__m0), \ - "r" (__m1)); \ - (xh) += ((((SItype) __m0 >> 31) & __m1) \ - + (((SItype) __m1 >> 31) & __m0)); \ - } while (0) -#define UMUL_TIME 8 -#define smul_ppmm(xh, xl, m0, m1) \ - __asm__ ("mul %0,%2,%3" \ - : "=r" ((SItype)(xh)), \ - "=q" ((SItype)(xl)) \ - : "r" (m0), \ - "r" (m1)) -#define SMUL_TIME 4 -#define sdiv_qrnnd(q, r, nh, nl, d) \ - __asm__ ("div %0,%2,%4" \ - : "=r" ((SItype)(q)), "=q" ((SItype)(r)) \ - : "r" ((SItype)(nh)), "1" ((SItype)(nl)), "r" ((SItype)(d))) -#define UDIV_TIME 100 -#endif -#endif /* Power architecture variants. */ - -/* Powerpc 64 bit support taken from gmp-4.1.2. */ -/* We should test _IBMR2 here when we add assembly support for the system - vendor compilers. */ -#if 0 /* Not yet enabled because we don't have hardware for a test. */ -#if (defined (_ARCH_PPC) || defined (__powerpc__)) && W_TYPE_SIZE == 64 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - do { \ - if (__builtin_constant_p (bh) && (bh) == 0) \ - __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ - : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ - else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ - __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ - : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ - else \ - __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ - : "=r" (sh), "=&r" (sl) \ - : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ - } while (0) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - do { \ - if (__builtin_constant_p (ah) && (ah) == 0) \ - __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ - : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ - else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \ - __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ - : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ - else if (__builtin_constant_p (bh) && (bh) == 0) \ - __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ - : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ - else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ - __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ - : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ - else \ - __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ - : "=r" (sh), "=&r" (sl) \ - : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ - } while (0) -#define count_leading_zeros(count, x) \ - __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x)) -#define COUNT_LEADING_ZEROS_0 64 -#define umul_ppmm(ph, pl, m0, m1) \ - do { \ - UDItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ - (pl) = __m0 * __m1; \ - } while (0) -#define UMUL_TIME 15 -#define smul_ppmm(ph, pl, m0, m1) \ - do { \ - DItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ - (pl) = __m0 * __m1; \ - } while (0) -#define SMUL_TIME 14 /* ??? */ -#define UDIV_TIME 120 /* ??? */ -#endif /* 64-bit PowerPC. */ -#endif /* if 0 */ - -/*************************************** - ************** PYR ****************** - ***************************************/ -#if defined (__pyr__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("addw %5,%1 \n" \ - "addwc %3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ - : "%0" ((USItype)(ah)), \ - "g" ((USItype)(bh)), \ - "%1" ((USItype)(al)), \ - "g" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subw %5,%1 \n" \ - "subwb %3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ - : "0" ((USItype)(ah)), \ - "g" ((USItype)(bh)), \ - "1" ((USItype)(al)), \ - "g" ((USItype)(bl))) -/* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */ -#define umul_ppmm(w1, w0, u, v) \ - ({union {UDItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __xx; \ - __asm__ ("movw %1,%R0 \n" \ - "uemul %2,%0" \ - : "=&r" (__xx.__ll) \ - : "g" ((USItype) (u)), \ - "g" ((USItype)(v))); \ - (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) -#endif /* __pyr__ */ - - -/*************************************** - ************** RT/ROMP ************** - ***************************************/ -#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("a %1,%5 \n" \ - "ae %0,%3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ - : "%0" ((USItype)(ah)), \ - "r" ((USItype)(bh)), \ - "%1" ((USItype)(al)), \ - "r" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("s %1,%5\n" \ - "se %0,%3" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ - : "0" ((USItype)(ah)), \ - "r" ((USItype)(bh)), \ - "1" ((USItype)(al)), \ - "r" ((USItype)(bl))) -#define umul_ppmm(ph, pl, m0, m1) \ - do { \ - USItype __m0 = (m0), __m1 = (m1); \ - __asm__ ( \ - "s r2,r2 \n" \ - "mts r10,%2 \n" \ - "m r2,%3 \n" \ - "m r2,%3 \n" \ - "m r2,%3 \n" \ - "m r2,%3 \n" \ - "m r2,%3 \n" \ - "m r2,%3 \n" \ - "m r2,%3 \n" \ - "m r2,%3 \n" \ - "m r2,%3 \n" \ - "m r2,%3 \n" \ - "m r2,%3 \n" \ - "m r2,%3 \n" \ - "m r2,%3 \n" \ - "m r2,%3 \n" \ - "m r2,%3 \n" \ - "m r2,%3 \n" \ - "cas %0,r2,r0 \n" \ - "mfs r10,%1" \ - : "=r" ((USItype)(ph)), \ - "=r" ((USItype)(pl)) \ - : "%r" (__m0), \ - "r" (__m1) \ - : "r2"); \ - (ph) += ((((SItype) __m0 >> 31) & __m1) \ - + (((SItype) __m1 >> 31) & __m0)); \ - } while (0) -#define UMUL_TIME 20 -#define UDIV_TIME 200 -#define count_leading_zeros(count, x) \ - do { \ - if ((x) >= 0x10000) \ - __asm__ ("clz %0,%1" \ - : "=r" ((USItype)(count)) \ - : "r" ((USItype)(x) >> 16)); \ - else \ - { \ - __asm__ ("clz %0,%1" \ - : "=r" ((USItype)(count)) \ - : "r" ((USItype)(x))); \ - (count) += 16; \ - } \ - } while (0) -#endif /* RT/ROMP */ - - -/*************************************** - ************** SH2 ****************** - ***************************************/ -#if (defined (__sh2__) || defined(__sh3__) || defined(__SH4__) ) \ - && W_TYPE_SIZE == 32 -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ( \ - "dmulu.l %2,%3\n" \ - "sts macl,%1\n" \ - "sts mach,%0" \ - : "=r" ((USItype)(w1)), \ - "=r" ((USItype)(w0)) \ - : "r" ((USItype)(u)), \ - "r" ((USItype)(v)) \ - : "macl", "mach") -#define UMUL_TIME 5 -#endif - -/*************************************** - ************** SPARC **************** - ***************************************/ -#if defined (__sparc__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("addcc %r4,%5,%1\n" \ - "addx %r2,%3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ - : "%rJ" ((USItype)(ah)), \ - "rI" ((USItype)(bh)), \ - "%rJ" ((USItype)(al)), \ - "rI" ((USItype)(bl)) \ - __CLOBBER_CC) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subcc %r4,%5,%1\n" \ - "subx %r2,%3,%0" \ - : "=r" ((USItype)(sh)), \ - "=&r" ((USItype)(sl)) \ - : "rJ" ((USItype)(ah)), \ - "rI" ((USItype)(bh)), \ - "rJ" ((USItype)(al)), \ - "rI" ((USItype)(bl)) \ - __CLOBBER_CC) -#if defined (__sparc_v8__) -/* Don't match immediate range because, 1) it is not often useful, - 2) the 'I' flag thinks of the range as a 13 bit signed interval, - while we want to match a 13 bit interval, sign extended to 32 bits, - but INTERPRETED AS UNSIGNED. */ -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("umul %2,%3,%1;rd %%y,%0" \ - : "=r" ((USItype)(w1)), \ - "=r" ((USItype)(w0)) \ - : "r" ((USItype)(u)), \ - "r" ((USItype)(v))) -#define UMUL_TIME 5 -#ifndef SUPERSPARC /* SuperSPARC's udiv only handles 53 bit dividends */ -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { \ - USItype __q; \ - __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \ - : "=r" ((USItype)(__q)) \ - : "r" ((USItype)(n1)), \ - "r" ((USItype)(n0)), \ - "r" ((USItype)(d))); \ - (r) = (n0) - __q * (d); \ - (q) = __q; \ - } while (0) -#define UDIV_TIME 25 -#endif /* SUPERSPARC */ -#else /* ! __sparc_v8__ */ -#if defined (__sparclite__) -/* This has hardware multiply but not divide. It also has two additional - instructions scan (ffs from high bit) and divscc. */ -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("umul %2,%3,%1;rd %%y,%0" \ - : "=r" ((USItype)(w1)), \ - "=r" ((USItype)(w0)) \ - : "r" ((USItype)(u)), \ - "r" ((USItype)(v))) -#define UMUL_TIME 5 -#define udiv_qrnnd(q, r, n1, n0, d) \ - __asm__ ("! Inlined udiv_qrnnd \n" \ - " wr %%g0,%2,%%y ! Not a delayed write for sparclite \n" \ - " tst %%g0 \n" \ - " divscc %3,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%%g1 \n" \ - " divscc %%g1,%4,%0 \n" \ - " rd %%y,%1 \n" \ - " bl,a 1f \n" \ - " add %1,%4,%1 \n" \ - "1: ! End of inline udiv_qrnnd" \ - : "=r" ((USItype)(q)), \ - "=r" ((USItype)(r)) \ - : "r" ((USItype)(n1)), \ - "r" ((USItype)(n0)), \ - "rI" ((USItype)(d)) \ - : "%g1" __AND_CLOBBER_CC) -#define UDIV_TIME 37 -#define count_leading_zeros(count, x) \ - __asm__ ("scan %1,0,%0" \ - : "=r" ((USItype)(x)) \ - : "r" ((USItype)(count))) -/* Early sparclites return 63 for an argument of 0, but they warn that future - implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 - undefined. */ -#endif /* __sparclite__ */ -#endif /* __sparc_v8__ */ -/* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */ -#ifndef umul_ppmm -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("! Inlined umul_ppmm \n" \ - " wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr \n" \ - " sra %3,31,%%g2 ! Don't move this insn \n" \ - " and %2,%%g2,%%g2 ! Don't move this insn \n" \ - " andcc %%g0,0,%%g1 ! Don't move this insn \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,%3,%%g1 \n" \ - " mulscc %%g1,0,%%g1 \n" \ - " add %%g1,%%g2,%0 \n" \ - " rd %%y,%1" \ - : "=r" ((USItype)(w1)), \ - "=r" ((USItype)(w0)) \ - : "%rI" ((USItype)(u)), \ - "r" ((USItype)(v)) \ - : "%g1", "%g2" __AND_CLOBBER_CC) -#define UMUL_TIME 39 /* 39 instructions */ -#endif -#ifndef udiv_qrnnd -#ifndef LONGLONG_STANDALONE -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { USItype __r; \ - (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ - (r) = __r; \ - } while (0) -extern USItype __udiv_qrnnd (); -#define UDIV_TIME 140 -#endif /* LONGLONG_STANDALONE */ -#endif /* udiv_qrnnd */ -#endif /* __sparc__ */ - - -/*************************************** - ************** VAX ****************** - ***************************************/ -#if defined (__vax__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("addl2 %5,%1\n" \ - "adwc %3,%0" \ - : "=g" ((USItype)(sh)), \ - "=&g" ((USItype)(sl)) \ - : "%0" ((USItype)(ah)), \ - "g" ((USItype)(bh)), \ - "%1" ((USItype)(al)), \ - "g" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subl2 %5,%1\n" \ - "sbwc %3,%0" \ - : "=g" ((USItype)(sh)), \ - "=&g" ((USItype)(sl)) \ - : "0" ((USItype)(ah)), \ - "g" ((USItype)(bh)), \ - "1" ((USItype)(al)), \ - "g" ((USItype)(bl))) -#define umul_ppmm(xh, xl, m0, m1) \ - do { \ - union {UDItype __ll; \ - struct {USItype __l, __h;} __i; \ - } __xx; \ - USItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("emul %1,%2,$0,%0" \ - : "=g" (__xx.__ll) \ - : "g" (__m0), \ - "g" (__m1)); \ - (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ - (xh) += ((((SItype) __m0 >> 31) & __m1) \ - + (((SItype) __m1 >> 31) & __m0)); \ - } while (0) -#define sdiv_qrnnd(q, r, n1, n0, d) \ - do { \ - union {DItype __ll; \ - struct {SItype __l, __h;} __i; \ - } __xx; \ - __xx.__i.__h = n1; __xx.__i.__l = n0; \ - __asm__ ("ediv %3,%2,%0,%1" \ - : "=g" (q), "=g" (r) \ - : "g" (__xx.__ll), "g" (d)); \ - } while (0) -#endif /* __vax__ */ - - -/*************************************** - ************** Z8000 **************** - ***************************************/ -#if defined (__z8000__) && W_TYPE_SIZE == 16 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ - : "=r" ((unsigned int)(sh)), \ - "=&r" ((unsigned int)(sl)) \ - : "%0" ((unsigned int)(ah)), \ - "r" ((unsigned int)(bh)), \ - "%1" ((unsigned int)(al)), \ - "rQR" ((unsigned int)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ - : "=r" ((unsigned int)(sh)), \ - "=&r" ((unsigned int)(sl)) \ - : "0" ((unsigned int)(ah)), \ - "r" ((unsigned int)(bh)), \ - "1" ((unsigned int)(al)), \ - "rQR" ((unsigned int)(bl))) -#define umul_ppmm(xh, xl, m0, m1) \ - do { \ - union {long int __ll; \ - struct {unsigned int __h, __l;} __i; \ - } __xx; \ - unsigned int __m0 = (m0), __m1 = (m1); \ - __asm__ ("mult %S0,%H3" \ - : "=r" (__xx.__i.__h), \ - "=r" (__xx.__i.__l) \ - : "%1" (__m0), \ - "rQR" (__m1)); \ - (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ - (xh) += ((((signed int) __m0 >> 15) & __m1) \ - + (((signed int) __m1 >> 15) & __m0)); \ - } while (0) -#endif /* __z8000__ */ - -#endif /* __GNUC__ */ -#endif /* !__riscos__ */ - - -/*************************************** - *********** Generic Versions ******** - ***************************************/ -#if !defined (umul_ppmm) && defined (__umulsidi3) -#define umul_ppmm(ph, pl, m0, m1) \ - { \ - UDWtype __ll = __umulsidi3 (m0, m1); \ - ph = (UWtype) (__ll >> W_TYPE_SIZE); \ - pl = (UWtype) __ll; \ - } -#endif - -#if !defined (__umulsidi3) -#define __umulsidi3(u, v) \ - ({UWtype __hi, __lo; \ - umul_ppmm (__hi, __lo, u, v); \ - ((UDWtype) __hi << W_TYPE_SIZE) | __lo; }) -#endif - -/* If this machine has no inline assembler, use C macros. */ - -#if !defined (add_ssaaaa) -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - do { \ - UWtype __x; \ - __x = (al) + (bl); \ - (sh) = (ah) + (bh) + (__x < (al)); \ - (sl) = __x; \ - } while (0) -#endif - -#if !defined (sub_ddmmss) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - do { \ - UWtype __x; \ - __x = (al) - (bl); \ - (sh) = (ah) - (bh) - (__x > (al)); \ - (sl) = __x; \ - } while (0) -#endif - -#if !defined (umul_ppmm) -#define umul_ppmm(w1, w0, u, v) \ - do { \ - UWtype __x0, __x1, __x2, __x3; \ - UHWtype __ul, __vl, __uh, __vh; \ - UWtype __u = (u), __v = (v); \ - \ - __ul = __ll_lowpart (__u); \ - __uh = __ll_highpart (__u); \ - __vl = __ll_lowpart (__v); \ - __vh = __ll_highpart (__v); \ - \ - __x0 = (UWtype) __ul * __vl; \ - __x1 = (UWtype) __ul * __vh; \ - __x2 = (UWtype) __uh * __vl; \ - __x3 = (UWtype) __uh * __vh; \ - \ - __x1 += __ll_highpart (__x0);/* this can't give carry */ \ - __x1 += __x2; /* but this indeed can */ \ - if (__x1 < __x2) /* did we get it? */ \ - __x3 += __ll_B; /* yes, add it in the proper pos. */ \ - \ - (w1) = __x3 + __ll_highpart (__x1); \ - (w0) = (__ll_lowpart (__x1) << W_TYPE_SIZE/2) + __ll_lowpart (__x0);\ - } while (0) -#endif - -#if !defined (umul_ppmm) -#define smul_ppmm(w1, w0, u, v) \ - do { \ - UWtype __w1; \ - UWtype __m0 = (u), __m1 = (v); \ - umul_ppmm (__w1, w0, __m0, __m1); \ - (w1) = __w1 - (-(__m0 >> (W_TYPE_SIZE - 1)) & __m1) \ - - (-(__m1 >> (W_TYPE_SIZE - 1)) & __m0); \ - } while (0) -#endif - -/* Define this unconditionally, so it can be used for debugging. */ -#define __udiv_qrnnd_c(q, r, n1, n0, d) \ - do { \ - UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \ - __d1 = __ll_highpart (d); \ - __d0 = __ll_lowpart (d); \ - \ - __r1 = (n1) % __d1; \ - __q1 = (n1) / __d1; \ - __m = (UWtype) __q1 * __d0; \ - __r1 = __r1 * __ll_B | __ll_highpart (n0); \ - if (__r1 < __m) \ - { \ - __q1--, __r1 += (d); \ - if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ - if (__r1 < __m) \ - __q1--, __r1 += (d); \ - } \ - __r1 -= __m; \ - \ - __r0 = __r1 % __d1; \ - __q0 = __r1 / __d1; \ - __m = (UWtype) __q0 * __d0; \ - __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ - if (__r0 < __m) \ - { \ - __q0--, __r0 += (d); \ - if (__r0 >= (d)) \ - if (__r0 < __m) \ - __q0--, __r0 += (d); \ - } \ - __r0 -= __m; \ - \ - (q) = (UWtype) __q1 * __ll_B | __q0; \ - (r) = __r0; \ - } while (0) - -/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through - __udiv_w_sdiv (defined in libgcc or elsewhere). */ -#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) -#define udiv_qrnnd(q, r, nh, nl, d) \ - do { \ - UWtype __r; \ - (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \ - (r) = __r; \ - } while (0) -#endif - -/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ -#if !defined (udiv_qrnnd) -#define UDIV_NEEDS_NORMALIZATION 1 -#define udiv_qrnnd __udiv_qrnnd_c -#endif - -#if !defined (count_leading_zeros) -extern -#ifdef __STDC__ -const -#endif -unsigned char _gcry_clz_tab[]; -#define MPI_INTERNAL_NEED_CLZ_TAB 1 -#define count_leading_zeros(count, x) \ - do { \ - UWtype __xr = (x); \ - UWtype __a; \ - \ - if (W_TYPE_SIZE <= 32) \ - { \ - __a = __xr < ((UWtype) 1 << 2*__BITS4) \ - ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \ - : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4);\ - } \ - else \ - { \ - for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ - if (((__xr >> __a) & 0xff) != 0) \ - break; \ - } \ - \ - (count) = W_TYPE_SIZE - (_gcry_clz_tab[__xr >> __a] + __a); \ - } while (0) -/* This version gives a well-defined value for zero. */ -#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE -#endif - -#if !defined (count_trailing_zeros) -/* Define count_trailing_zeros using count_leading_zeros. The latter might be - defined in asm, but if it is not, the C version above is good enough. */ -#define count_trailing_zeros(count, x) \ - do { \ - UWtype __ctz_x = (x); \ - UWtype __ctz_c; \ - count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ - (count) = W_TYPE_SIZE - 1 - __ctz_c; \ - } while (0) -#endif - -#ifndef UDIV_NEEDS_NORMALIZATION -#define UDIV_NEEDS_NORMALIZATION 0 -#endif diff --git a/grub-core/lib/libgcrypt/mpi/m68k/Manifest b/grub-core/lib/libgcrypt/mpi/m68k/Manifest deleted file mode 100644 index 8e0538adf..000000000 --- a/grub-core/lib/libgcrypt/mpi/m68k/Manifest +++ /dev/null @@ -1,25 +0,0 @@ -# Manifest - checksums -# Copyright 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 - -syntax.h -mpih-lshift.S -mpih-rshift.S -mpih-add1.S -mpih-sub1.S -$names$ iQCVAwUAP+LmTDEAnp832S/7AQJHUAP/dxfq2U0pDc5ZLoEizoqgjjcnHIyb9EjMG3YjvgK6jQ62yoAOCuo/jFYlJS+Mdve6bgfdTzYMrnKV7BG2SEcwb263pVnIntS7ZhKQPiMCbFgXWR2VjN3+a1v8yjQDZtgqEgm8OlQ+u7jKBY13Oryiuq5nPNxsXZqJpelG6Zkdg9M==PIee diff --git a/grub-core/lib/libgcrypt/mpi/m68k/distfiles b/grub-core/lib/libgcrypt/mpi/m68k/distfiles deleted file mode 100644 index 1e2e36f05..000000000 --- a/grub-core/lib/libgcrypt/mpi/m68k/distfiles +++ /dev/null @@ -1,9 +0,0 @@ -Manifest -syntax.h -mpih-lshift.S -mpih-rshift.S -mpih-add1.S -mpih-sub1.S - - - diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/Manifest b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/Manifest deleted file mode 100644 index bcb27681e..000000000 --- a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/Manifest +++ /dev/null @@ -1,23 +0,0 @@ -# Manifest - checksums -# Copyright 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 - -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S -$names$ iQCVAwUAP+LmRTEAnp832S/7AQK3rwP/TyGBbii5HCrjDiLCVJHiDNeOdENx6AicRXnu4vuJmMmPZ0y+i7MPusDaeTbIUA0w6RaJx+Ep41nIvthmNDnFePY5Mw0pIUJcpI7AJR4vYqpwNQA6nlEdn/m1jg6sPLKZXUXNUkhroEzcHzoU+12BPS+nvSXlwSksg6rXEGOJ+Ms==XCXP diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/distfiles b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/distfiles deleted file mode 100644 index 6b96433af..000000000 --- a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/distfiles +++ /dev/null @@ -1,4 +0,0 @@ -Manifest -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S deleted file mode 100644 index 007c94c6d..000000000 --- a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S +++ /dev/null @@ -1,104 +0,0 @@ -/* mc68020 __mpn_mul_1 -- Multiply a limb vector with a limb and store - * the result in a second limb vector. - * - * Copyright (C) 1992, 1994, 1996, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_size_t s1_size, (sp + 12) - * mpi_limb_t s2_limb) (sp + 16) - */ - - - TEXT - ALIGN - GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1) - -C_SYMBOL_NAME(_gcry_mpih_mul_1:) -PROLOG(_gcry_mpih_mul_1) - -#define res_ptr a0 -#define s1_ptr a1 -#define s1_size d2 -#define s2_limb d4 - -/* Save used registers on the stack. */ - moveml R(d2)-R(d4),MEM_PREDEC(sp) -#if 0 - movel R(d2),MEM_PREDEC(sp) - movel R(d3),MEM_PREDEC(sp) - movel R(d4),MEM_PREDEC(sp) -#endif - -/* Copy the arguments to registers. Better use movem? */ - movel MEM_DISP(sp,16),R(res_ptr) - movel MEM_DISP(sp,20),R(s1_ptr) - movel MEM_DISP(sp,24),R(s1_size) - movel MEM_DISP(sp,28),R(s2_limb) - - eorw #1,R(s1_size) - clrl R(d1) - lsrl #1,R(s1_size) - bcc L(L1) - subql #1,R(s1_size) - subl R(d0),R(d0) /* (d0,cy) <= (0,0) */ - -L(Loop:) - movel MEM_POSTINC(s1_ptr),R(d3) - mulul R(s2_limb),R(d1):R(d3) - addxl R(d0),R(d3) - movel R(d3),MEM_POSTINC(res_ptr) -L(L1:) movel MEM_POSTINC(s1_ptr),R(d3) - mulul R(s2_limb),R(d0):R(d3) - addxl R(d1),R(d3) - movel R(d3),MEM_POSTINC(res_ptr) - - dbf R(s1_size),L(Loop) - clrl R(d3) - addxl R(d3),R(d0) - subl #0x10000,R(s1_size) - bcc L(Loop) - -/* Restore used registers from stack frame. */ - moveml MEM_POSTINC(sp),R(d2)-R(d4) -#if 0 - movel MEM_POSTINC(sp),R(d4) - movel MEM_POSTINC(sp),R(d3) - movel MEM_POSTINC(sp),R(d2) -#endif - rts -EPILOG(_gcry_mpih_mul_1) - - diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S deleted file mode 100644 index 44baa8d88..000000000 --- a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S +++ /dev/null @@ -1,94 +0,0 @@ -/* mc68020 __mpn_addmul_1 -- Multiply a limb vector with a limb and add - * the result to a second limb vector. - * - * Copyright (C) 1992, 1994, 1996, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - -/******************* - * mpi_limb_t - * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_size_t s1_size, (sp + 12) - * mpi_limb_t s2_limb) (sp + 16) - */ - - - TEXT - ALIGN - GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1) - -C_SYMBOL_NAME(_gcry_mpih_addmul_1:) -PROLOG(_gcry_mpih_addmul_1) - -#define res_ptr a0 -#define s1_ptr a1 -#define s1_size d2 -#define s2_limb d4 - -/* Save used registers on the stack. */ - moveml R(d2)-R(d5),MEM_PREDEC(sp) - -/* Copy the arguments to registers. Better use movem? */ - movel MEM_DISP(sp,20),R(res_ptr) - movel MEM_DISP(sp,24),R(s1_ptr) - movel MEM_DISP(sp,28),R(s1_size) - movel MEM_DISP(sp,32),R(s2_limb) - - eorw #1,R(s1_size) - clrl R(d1) - clrl R(d5) - lsrl #1,R(s1_size) - bcc L(L1) - subql #1,R(s1_size) - subl R(d0),R(d0) /* (d0,cy) <= (0,0) */ - -L(Loop:) - movel MEM_POSTINC(s1_ptr),R(d3) - mulul R(s2_limb),R(d1):R(d3) - addxl R(d0),R(d3) - addxl R(d5),R(d1) - addl R(d3),MEM_POSTINC(res_ptr) -L(L1:) movel MEM_POSTINC(s1_ptr),R(d3) - mulul R(s2_limb),R(d0):R(d3) - addxl R(d1),R(d3) - addxl R(d5),R(d0) - addl R(d3),MEM_POSTINC(res_ptr) - - dbf R(s1_size),L(Loop) - addxl R(d5),R(d0) - subl #0x10000,R(s1_size) - bcc L(Loop) - -/* Restore used registers from stack frame. */ - moveml MEM_POSTINC(sp),R(d2)-R(d5) - - rts -EPILOG(_gcry_mpih_addmul_1) - diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S deleted file mode 100644 index e958ef611..000000000 --- a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S +++ /dev/null @@ -1,97 +0,0 @@ -/* mc68020 __mpn_submul_1 -- Multiply a limb vector with a limb and subtract - * the result from a second limb vector. - * - * Copyright (C) 1992, 1994, 1996, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - - - -#include "sysdep.h" -#include "asm-syntax.h" - -/******************* - * mpi_limb_t - * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_size_t s1_size, (sp + 12) - * mpi_limb_t s2_limb) (sp + 16) - */ - - - TEXT - ALIGN - GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1) - -C_SYMBOL_NAME(_gcry_mpih_submul_1:) -PROLOG(_gcry_mpih_submul_1) - -#define res_ptr a0 -#define s1_ptr a1 -#define s1_size d2 -#define s2_limb d4 - -/* Save used registers on the stack. */ - moveml R(d2)-R(d5),MEM_PREDEC(sp) - -/* Copy the arguments to registers. Better use movem? */ - movel MEM_DISP(sp,20),R(res_ptr) - movel MEM_DISP(sp,24),R(s1_ptr) - movel MEM_DISP(sp,28),R(s1_size) - movel MEM_DISP(sp,32),R(s2_limb) - - eorw #1,R(s1_size) - clrl R(d1) - clrl R(d5) - lsrl #1,R(s1_size) - bcc L(L1) - subql #1,R(s1_size) - subl R(d0),R(d0) /* (d0,cy) <= (0,0) */ - -L(Loop:) - movel MEM_POSTINC(s1_ptr),R(d3) - mulul R(s2_limb),R(d1):R(d3) - addxl R(d0),R(d3) - addxl R(d5),R(d1) - subl R(d3),MEM_POSTINC(res_ptr) -L(L1:) movel MEM_POSTINC(s1_ptr),R(d3) - mulul R(s2_limb),R(d0):R(d3) - addxl R(d1),R(d3) - addxl R(d5),R(d0) - subl R(d3),MEM_POSTINC(res_ptr) - - dbf R(s1_size),L(Loop) - addxl R(d5),R(d0) - subl #0x10000,R(s1_size) - bcc L(Loop) - -/* Restore used registers from stack frame. */ - moveml MEM_POSTINC(sp),R(d2)-R(d5) - - rts -EPILOG(_gcry_mpih_submul_1) - - diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/m68k/mpih-add1.S deleted file mode 100644 index 8182d21a3..000000000 --- a/grub-core/lib/libgcrypt/mpi/m68k/mpih-add1.S +++ /dev/null @@ -1,92 +0,0 @@ -/* mc68020 __mpn_add_n -- Add two limb vectors of the same length > 0 and store - * sum in a third limb vector. - * - * Copyright (C) 1992, 1994,1996, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_ptr_t s2_ptr, (sp + 16) - * mpi_size_t size) (sp + 12) - */ - - - TEXT - ALIGN - GLOBL C_SYMBOL_NAME(_gcry_mpih_add_n) - -C_SYMBOL_NAME(_gcry_mpih_add_n:) -PROLOG(_gcry_mpih_add_n) - /* Save used registers on the stack. */ - movel R(d2),MEM_PREDEC(sp) - movel R(a2),MEM_PREDEC(sp) - - /* Copy the arguments to registers. Better use movem? */ - movel MEM_DISP(sp,12),R(a2) - movel MEM_DISP(sp,16),R(a0) - movel MEM_DISP(sp,20),R(a1) - movel MEM_DISP(sp,24),R(d2) - - eorw #1,R(d2) - lsrl #1,R(d2) - bcc L(L1) - subql #1,R(d2) /* clears cy as side effect */ - -L(Loop:) - movel MEM_POSTINC(a0),R(d0) - movel MEM_POSTINC(a1),R(d1) - addxl R(d1),R(d0) - movel R(d0),MEM_POSTINC(a2) -L(L1:) movel MEM_POSTINC(a0),R(d0) - movel MEM_POSTINC(a1),R(d1) - addxl R(d1),R(d0) - movel R(d0),MEM_POSTINC(a2) - - dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */ - subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */ - subl #0x10000,R(d2) - bcs L(L2) - addl R(d0),R(d0) /* restore cy */ - bra L(Loop) - -L(L2:) - negl R(d0) - - /* Restore used registers from stack frame. */ - movel MEM_POSTINC(sp),R(a2) - movel MEM_POSTINC(sp),R(d2) - - rts -EPILOG(_gcry_mpih_add_n) - - diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/m68k/mpih-lshift.S deleted file mode 100644 index 133d1aae3..000000000 --- a/grub-core/lib/libgcrypt/mpi/m68k/mpih-lshift.S +++ /dev/null @@ -1,164 +0,0 @@ -/* mc68020 lshift -- Shift left a low-level natural-number integer. - * - * Copyright (C) 1996, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4) - * mpi_ptr_t up, (sp + 8) - * mpi_size_t usize, (sp + 12) - * unsigned cnt) (sp + 16) - */ - -#define res_ptr a1 -#define s_ptr a0 -#define s_size d6 -#define cnt d4 - - TEXT - ALIGN - GLOBL C_SYMBOL_NAME(_gcry_mpih_lshift) - -C_SYMBOL_NAME(_gcry_mpih_lshift:) -PROLOG(_gcry_mpih_lshift) - - /* Save used registers on the stack. */ - moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp) - - /* Copy the arguments to registers. */ - movel MEM_DISP(sp,28),R(res_ptr) - movel MEM_DISP(sp,32),R(s_ptr) - movel MEM_DISP(sp,36),R(s_size) - movel MEM_DISP(sp,40),R(cnt) - - moveql #1,R(d5) - cmpl R(d5),R(cnt) - bne L(Lnormal) - cmpl R(s_ptr),R(res_ptr) - bls L(Lspecial) /* jump if s_ptr >= res_ptr */ -#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) - lea MEM_INDX1(s_ptr,s_size,l,4),R(a2) -#else /* not mc68020 */ - movel R(s_size),R(d0) - asll #2,R(d0) - lea MEM_INDX(s_ptr,d0,l),R(a2) -#endif - cmpl R(res_ptr),R(a2) - bls L(Lspecial) /* jump if res_ptr >= s_ptr + s_size */ - -L(Lnormal:) - moveql #32,R(d5) - subl R(cnt),R(d5) - -#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) - lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr) - lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr) -#else /* not mc68000 */ - movel R(s_size),R(d0) - asll #2,R(d0) - addl R(s_size),R(s_ptr) - addl R(s_size),R(res_ptr) -#endif - movel MEM_PREDEC(s_ptr),R(d2) - movel R(d2),R(d0) - lsrl R(d5),R(d0) /* compute carry limb */ - - lsll R(cnt),R(d2) - movel R(d2),R(d1) - subql #1,R(s_size) - beq L(Lend) - lsrl #1,R(s_size) - bcs L(L1) - subql #1,R(s_size) - -L(Loop:) - movel MEM_PREDEC(s_ptr),R(d2) - movel R(d2),R(d3) - lsrl R(d5),R(d3) - orl R(d3),R(d1) - movel R(d1),MEM_PREDEC(res_ptr) - lsll R(cnt),R(d2) -L(L1:) - movel MEM_PREDEC(s_ptr),R(d1) - movel R(d1),R(d3) - lsrl R(d5),R(d3) - orl R(d3),R(d2) - movel R(d2),MEM_PREDEC(res_ptr) - lsll R(cnt),R(d1) - - dbf R(s_size),L(Loop) - subl #0x10000,R(s_size) - bcc L(Loop) - -L(Lend:) - movel R(d1),MEM_PREDEC(res_ptr) /* store least significant limb */ - -/* Restore used registers from stack frame. */ - moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) - rts - -/* We loop from least significant end of the arrays, which is only - permissable if the source and destination don't overlap, since the - function is documented to work for overlapping source and destination. */ - -L(Lspecial:) - clrl R(d0) /* initialize carry */ - eorw #1,R(s_size) - lsrl #1,R(s_size) - bcc L(LL1) - subql #1,R(s_size) - -L(LLoop:) - movel MEM_POSTINC(s_ptr),R(d2) - addxl R(d2),R(d2) - movel R(d2),MEM_POSTINC(res_ptr) -L(LL1:) - movel MEM_POSTINC(s_ptr),R(d2) - addxl R(d2),R(d2) - movel R(d2),MEM_POSTINC(res_ptr) - - dbf R(s_size),L(LLoop) - addxl R(d0),R(d0) /* save cy in lsb */ - subl #0x10000,R(s_size) - bcs L(LLend) - lsrl #1,R(d0) /* restore cy */ - bra L(LLoop) - -L(LLend:) -/* Restore used registers from stack frame. */ - moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) - rts -EPILOG(_gcry_mpih_lshift) - - - - - diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/m68k/mpih-rshift.S deleted file mode 100644 index be9f43502..000000000 --- a/grub-core/lib/libgcrypt/mpi/m68k/mpih-rshift.S +++ /dev/null @@ -1,162 +0,0 @@ -/* mc68020 rshift -- Shift right a low-level natural-number integer. - * - * Copyright (C) 1996, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4) - * mpi_ptr_t up, (sp + 8) - * mpi_size_t usize, (sp + 12) - * unsigned cnt) (sp + 16) - */ - -#define res_ptr a1 -#define s_ptr a0 -#define s_size d6 -#define cnt d4 - - TEXT - ALIGN - GLOBL C_SYMBOL_NAME(_gcry_mpih_rshift) - -C_SYMBOL_NAME(_gcry_mpih_rshift:) -PROLOG(_gcry_mpih_rshift) - /* Save used registers on the stack. */ - moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp) - - /* Copy the arguments to registers. */ - movel MEM_DISP(sp,28),R(res_ptr) - movel MEM_DISP(sp,32),R(s_ptr) - movel MEM_DISP(sp,36),R(s_size) - movel MEM_DISP(sp,40),R(cnt) - - moveql #1,R(d5) - cmpl R(d5),R(cnt) - bne L(Rnormal) - cmpl R(res_ptr),R(s_ptr) - bls L(Rspecial) /* jump if res_ptr >= s_ptr */ -#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) - lea MEM_INDX1(res_ptr,s_size,l,4),R(a2) -#else /* not mc68020 */ - movel R(s_size),R(d0) - asll #2,R(d0) - lea MEM_INDX(res_ptr,d0,l),R(a2) -#endif - cmpl R(s_ptr),R(a2) - bls L(Rspecial) /* jump if s_ptr >= res_ptr + s_size */ - -L(Rnormal:) - moveql #32,R(d5) - subl R(cnt),R(d5) - movel MEM_POSTINC(s_ptr),R(d2) - movel R(d2),R(d0) - lsll R(d5),R(d0) /* compute carry limb */ - - lsrl R(cnt),R(d2) - movel R(d2),R(d1) - subql #1,R(s_size) - beq L(Rend) - lsrl #1,R(s_size) - bcs L(R1) - subql #1,R(s_size) - -L(Roop:) - movel MEM_POSTINC(s_ptr),R(d2) - movel R(d2),R(d3) - lsll R(d5),R(d3) - orl R(d3),R(d1) - movel R(d1),MEM_POSTINC(res_ptr) - lsrl R(cnt),R(d2) -L(R1:) - movel MEM_POSTINC(s_ptr),R(d1) - movel R(d1),R(d3) - lsll R(d5),R(d3) - orl R(d3),R(d2) - movel R(d2),MEM_POSTINC(res_ptr) - lsrl R(cnt),R(d1) - - dbf R(s_size),L(Roop) - subl #0x10000,R(s_size) - bcc L(Roop) - -L(Rend:) - movel R(d1),MEM(res_ptr) /* store most significant limb */ - -/* Restore used registers from stack frame. */ - moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) - rts - -/* We loop from most significant end of the arrays, which is only - permissable if the source and destination don't overlap, since the - function is documented to work for overlapping source and destination. */ - -L(Rspecial:) -#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) - lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr) - lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr) -#else /* not mc68000 */ - movel R(s_size),R(d0) - asll #2,R(d0) - addl R(s_size),R(s_ptr) - addl R(s_size),R(res_ptr) -#endif - - clrl R(d0) /* initialize carry */ - eorw #1,R(s_size) - lsrl #1,R(s_size) - bcc L(LR1) - subql #1,R(s_size) - -L(LRoop:) - movel MEM_PREDEC(s_ptr),R(d2) - roxrl #1,R(d2) - movel R(d2),MEM_PREDEC(res_ptr) -L(LR1:) - movel MEM_PREDEC(s_ptr),R(d2) - roxrl #1,R(d2) - movel R(d2),MEM_PREDEC(res_ptr) - - dbf R(s_size),L(LRoop) - roxrl #1,R(d0) /* save cy in msb */ - subl #0x10000,R(s_size) - bcs L(LRend) - addl R(d0),R(d0) /* restore cy */ - bra L(LRoop) - -L(LRend:) -/* Restore used registers from stack frame. */ - moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) - rts -EPILOG(_gcry_mpih_rshift) - - - - diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/m68k/mpih-sub1.S deleted file mode 100644 index ee7555f89..000000000 --- a/grub-core/lib/libgcrypt/mpi/m68k/mpih-sub1.S +++ /dev/null @@ -1,91 +0,0 @@ -/* mc68020 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and - * store difference in a third limb vector. - * - * Copyright (C) 1992, 1994, 1996, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_ptr_t s2_ptr, (sp + 16) - * mpi_size_t size) (sp + 12) - */ - - - TEXT - ALIGN - GLOBL C_SYMBOL_NAME(_gcry_mpih_sub_n) - -C_SYMBOL_NAME(_gcry_mpih_sub_n:) -PROLOG(_gcry_mpih_sub_n) -/* Save used registers on the stack. */ - movel R(d2),MEM_PREDEC(sp) - movel R(a2),MEM_PREDEC(sp) - -/* Copy the arguments to registers. Better use movem? */ - movel MEM_DISP(sp,12),R(a2) - movel MEM_DISP(sp,16),R(a0) - movel MEM_DISP(sp,20),R(a1) - movel MEM_DISP(sp,24),R(d2) - - eorw #1,R(d2) - lsrl #1,R(d2) - bcc L(L1) - subql #1,R(d2) /* clears cy as side effect */ - -L(Loop:) - movel MEM_POSTINC(a0),R(d0) - movel MEM_POSTINC(a1),R(d1) - subxl R(d1),R(d0) - movel R(d0),MEM_POSTINC(a2) -L(L1:) movel MEM_POSTINC(a0),R(d0) - movel MEM_POSTINC(a1),R(d1) - subxl R(d1),R(d0) - movel R(d0),MEM_POSTINC(a2) - - dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */ - subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */ - subl #0x10000,R(d2) - bcs L(L2) - addl R(d0),R(d0) /* restore cy */ - bra L(Loop) - -L(L2:) - negl R(d0) - -/* Restore used registers from stack frame. */ - movel MEM_POSTINC(sp),R(a2) - movel MEM_POSTINC(sp),R(d2) - - rts -EPILOG(_gcry_mpih_sub_n) - - diff --git a/grub-core/lib/libgcrypt/mpi/m68k/syntax.h b/grub-core/lib/libgcrypt/mpi/m68k/syntax.h deleted file mode 100644 index 6a3fea130..000000000 --- a/grub-core/lib/libgcrypt/mpi/m68k/syntax.h +++ /dev/null @@ -1,185 +0,0 @@ -/* asm.h -- Definitions for 68k syntax variations. - * - * Copyright (C) 1992, 1994, 1996, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#undef ALIGN - -#ifdef MIT_SYNTAX -#define PROLOG(name) -#define EPILOG(name) -#define R(r)r -#define MEM(base)base@ -#define MEM_DISP(base,displacement)base@(displacement) -#define MEM_INDX(base,idx,size_suffix)base@(idx:size_suffix) -#define MEM_INDX1(base,idx,size_suffix,scale)base@(idx:size_suffix:scale) -#define MEM_PREDEC(memory_base)memory_base@- -#define MEM_POSTINC(memory_base)memory_base@+ -#define L(label) label -#define TEXT .text -#define ALIGN .even -#define GLOBL .globl -#define moveql moveq -/* Use variable sized opcodes. */ -#define bcc jcc -#define bcs jcs -#define bls jls -#define beq jeq -#define bne jne -#define bra jra -#endif - -#ifdef SONY_SYNTAX -#define PROLOG(name) -#define EPILOG(name) -#define R(r)r -#define MEM(base)(base) -#define MEM_DISP(base,displacement)(displacement,base) -#define MEM_INDX(base,idx,size_suffix)(base,idx.size_suffix) -#define MEM_INDX1(base,idx,size_suffix,scale)(base,idx.size_suffix*scale) -#define MEM_PREDEC(memory_base)-(memory_base) -#define MEM_POSTINC(memory_base)(memory_base)+ -#define L(label) label -#define TEXT .text -#define ALIGN .even -#define GLOBL .globl -#endif - -#ifdef MOTOROLA_SYNTAX -#define PROLOG(name) -#define EPILOG(name) -#define R(r)r -#define MEM(base)(base) -#define MEM_DISP(base,displacement)(displacement,base) -#define MEM_INDX(base,idx,size_suffix)(base,idx.size_suffix) -#define MEM_INDX1(base,idx,size_suffix,scale)(base,idx.size_suffix*scale) -#define MEM_PREDEC(memory_base)-(memory_base) -#define MEM_POSTINC(memory_base)(memory_base)+ -#define L(label) label -#define TEXT -#define ALIGN -#define GLOBL XDEF -#define lea LEA -#define movel MOVE.L -#define moveml MOVEM.L -#define moveql MOVEQ.L -#define cmpl CMP.L -#define orl OR.L -#define clrl CLR.L -#define eorw EOR.W -#define lsrl LSR.L -#define lsll LSL.L -#define roxrl ROXR.L -#define roxll ROXL.L -#define addl ADD.L -#define addxl ADDX.L -#define addql ADDQ.L -#define subl SUB.L -#define subxl SUBX.L -#define subql SUBQ.L -#define negl NEG.L -#define mulul MULU.L -#define bcc BCC -#define bcs BCS -#define bls BLS -#define beq BEQ -#define bne BNE -#define bra BRA -#define dbf DBF -#define rts RTS -#define d0 D0 -#define d1 D1 -#define d2 D2 -#define d3 D3 -#define d4 D4 -#define d5 D5 -#define d6 D6 -#define d7 D7 -#define a0 A0 -#define a1 A1 -#define a2 A2 -#define a3 A3 -#define a4 A4 -#define a5 A5 -#define a6 A6 -#define a7 A7 -#define sp SP -#endif - -#ifdef ELF_SYNTAX -#define PROLOG(name) .type name,@function -#define EPILOG(name) .size name,.-name -#define MEM(base)(R(base)) -#define MEM_DISP(base,displacement)(displacement,R(base)) -#define MEM_PREDEC(memory_base)-(R(memory_base)) -#define MEM_POSTINC(memory_base)(R(memory_base))+ -#ifdef __STDC__ -#define R_(r)%##r -#define R(r)R_(r) -#define MEM_INDX_(base,idx,size_suffix)(R(base),R(idx##.##size_suffix)) -#define MEM_INDX(base,idx,size_suffix)MEM_INDX_(base,idx,size_suffix) -#define MEM_INDX1_(base,idx,size_suffix,scale)(R(base),R(idx##.##size_suffix*scale)) -#define MEM_INDX1(base,idx,size_suffix,scale)MEM_INDX1_(base,idx,size_suffix,scale) -#define L(label) .##label -#else -#define R(r)%/**/r -#define MEM_INDX(base,idx,size_suffix)(R(base),R(idx).size_suffix) -#define MEM_INDX1(base,idx,size_suffix,scale)(R(base),R(idx).size_suffix*scale) -#define L(label) ./**/label -#endif -#define TEXT .text -#define ALIGN .align 2 -#define GLOBL .globl -#define bcc jbcc -#define bcs jbcs -#define bls jbls -#define beq jbeq -#define bne jbne -#define bra jbra -#endif - -#if defined (SONY_SYNTAX) || defined (ELF_SYNTAX) -#define movel move.l -#define moveml movem.l -#define moveql moveq.l -#define cmpl cmp.l -#define orl or.l -#define clrl clr.l -#define eorw eor.w -#define lsrl lsr.l -#define lsll lsl.l -#define roxrl roxr.l -#define roxll roxl.l -#define addl add.l -#define addxl addx.l -#define addql addq.l -#define subl sub.l -#define subxl subx.l -#define subql subq.l -#define negl neg.l -#define mulul mulu.l -#endif diff --git a/grub-core/lib/libgcrypt/mpi/mips3/Manifest b/grub-core/lib/libgcrypt/mpi/mips3/Manifest deleted file mode 100644 index e191184f3..000000000 --- a/grub-core/lib/libgcrypt/mpi/mips3/Manifest +++ /dev/null @@ -1,28 +0,0 @@ -# Manifest - checksums -# Copyright 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 - -mpih-add1.S -mpih-sub1.S -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S -mpih-lshift.S -mpih-rshift.S -mpi-asm-defs.h -$names$ iQCVAwUAP+LmUTEAnp832S/7AQLm/gP/RHR2aLMwHPxsq0mGO5H0kneVn8a9l9yDNEZBefkYcOJMb7MZGKxbGspyENiU04Mc2TFnA1wS9gjNHlRWtUYxxn/wyuV6BIRgfstXt2nXGgEQrK07GIz8ETFcYqcxu7JKiICIuXZgnIgdwBJswbBV1zaMUDXeg5B8vkkEeRWj8hQ==IQVO diff --git a/grub-core/lib/libgcrypt/mpi/mips3/README b/grub-core/lib/libgcrypt/mpi/mips3/README deleted file mode 100644 index e94b2c746..000000000 --- a/grub-core/lib/libgcrypt/mpi/mips3/README +++ /dev/null @@ -1,23 +0,0 @@ -This directory contains mpn functions optimized for MIPS3. Example of -processors that implement MIPS3 are R4000, R4400, R4600, R4700, and R8000. - -RELEVANT OPTIMIZATION ISSUES - -1. On the R4000 and R4400, branches, both the plain and the "likely" ones, - take 3 cycles to execute. (The fastest possible loop will take 4 cycles, - because of the delay insn.) - - On the R4600, branches takes a single cycle - - On the R8000, branches often take no noticable cycles, as they are - executed in a separate function unit.. - -2. The R4000 and R4400 have a load latency of 4 cycles. - -3. On the R4000 and R4400, multiplies take a data-dependent number of - cycles, contrary to the SGI documentation. There seem to be 3 or 4 - possible latencies. - -STATUS - -Good... diff --git a/grub-core/lib/libgcrypt/mpi/mips3/distfiles b/grub-core/lib/libgcrypt/mpi/mips3/distfiles deleted file mode 100644 index ef9b6fef3..000000000 --- a/grub-core/lib/libgcrypt/mpi/mips3/distfiles +++ /dev/null @@ -1,11 +0,0 @@ -Manifest -README -mpih-add1.S -mpih-sub1.S -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S -mpih-lshift.S -mpih-rshift.S -mpi-asm-defs.h - diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpi-asm-defs.h b/grub-core/lib/libgcrypt/mpi/mips3/mpi-asm-defs.h deleted file mode 100644 index 2d9a9c1f2..000000000 --- a/grub-core/lib/libgcrypt/mpi/mips3/mpi-asm-defs.h +++ /dev/null @@ -1,10 +0,0 @@ -/* This file defines some basic constants for the MPI machinery. We - * need to define the types on a per-CPU basis, so it is done with - * this file here. */ -#define BYTES_PER_MPI_LIMB 8 - - - - - - diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-add1.S deleted file mode 100644 index f3db029de..000000000 --- a/grub-core/lib/libgcrypt/mpi/mips3/mpih-add1.S +++ /dev/null @@ -1,124 +0,0 @@ -/* mips3 add_n -- Add two limb vectors of the same length > 0 and store - * sum in a third limb vector. - * - * Copyright (C) 1995, 1998, 2000 - * 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 - */ - - -/******************* - * mpi_limb_t - * _gcry_mpih_add_n( mpi_ptr_t res_ptr, ($4) - * mpi_ptr_t s1_ptr, ($5) - * mpi_ptr_t s2_ptr, ($6) - * mpi_size_t size) ($7) - */ - - .text - .align 2 - .globl _gcry_mpih_add_n - .ent _gcry_mpih_add_n -_gcry_mpih_add_n: - .set noreorder - .set nomacro - - ld $10,0($5) - ld $11,0($6) - - daddiu $7,$7,-1 - and $9,$7,4-1 # number of limbs in first loop - beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop - move $2,$0 - - dsubu $7,$7,$9 - -.Loop0: daddiu $9,$9,-1 - ld $12,8($5) - daddu $11,$11,$2 - ld $13,8($6) - sltu $8,$11,$2 - daddu $11,$10,$11 - sltu $2,$11,$10 - sd $11,0($4) - or $2,$2,$8 - - daddiu $5,$5,8 - daddiu $6,$6,8 - move $10,$12 - move $11,$13 - bne $9,$0,.Loop0 - daddiu $4,$4,8 - -.L0: beq $7,$0,.Lend - nop - -.Loop: daddiu $7,$7,-4 - - ld $12,8($5) - daddu $11,$11,$2 - ld $13,8($6) - sltu $8,$11,$2 - daddu $11,$10,$11 - sltu $2,$11,$10 - sd $11,0($4) - or $2,$2,$8 - - ld $10,16($5) - daddu $13,$13,$2 - ld $11,16($6) - sltu $8,$13,$2 - daddu $13,$12,$13 - sltu $2,$13,$12 - sd $13,8($4) - or $2,$2,$8 - - ld $12,24($5) - daddu $11,$11,$2 - ld $13,24($6) - sltu $8,$11,$2 - daddu $11,$10,$11 - sltu $2,$11,$10 - sd $11,16($4) - or $2,$2,$8 - - ld $10,32($5) - daddu $13,$13,$2 - ld $11,32($6) - sltu $8,$13,$2 - daddu $13,$12,$13 - sltu $2,$13,$12 - sd $13,24($4) - or $2,$2,$8 - - daddiu $5,$5,32 - daddiu $6,$6,32 - - bne $7,$0,.Loop - daddiu $4,$4,32 - -.Lend: daddu $11,$11,$2 - sltu $8,$11,$2 - daddu $11,$10,$11 - sltu $2,$11,$10 - sd $11,0($4) - j $31 - or $2,$2,$8 - - .end _gcry_mpih_add_n - diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-lshift.S deleted file mode 100644 index 084c109b2..000000000 --- a/grub-core/lib/libgcrypt/mpi/mips3/mpih-lshift.S +++ /dev/null @@ -1,97 +0,0 @@ -/* mips3 lshift - * - * Copyright (C) 1995, 1998, 2000, - * 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 - */ - -/******************* - * mpi_limb_t - * _gcry_mpih_lshift( mpi_ptr_t wp, ($4) - * mpi_ptr_t up, ($5) - * mpi_size_t usize, ($6) - * unsigned cnt) ($7) - */ - - .text - .align 2 - .globl _gcry_mpih_lshift - .ent _gcry_mpih_lshift -_gcry_mpih_lshift: - .set noreorder - .set nomacro - - dsll $2,$6,3 - daddu $5,$5,$2 # make r5 point at end of src - ld $10,-8($5) # load first limb - dsubu $13,$0,$7 - daddu $4,$4,$2 # make r4 point at end of res - daddiu $6,$6,-1 - and $9,$6,4-1 # number of limbs in first loop - beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop - dsrl $2,$10,$13 # compute function result - - dsubu $6,$6,$9 - -.Loop0: ld $3,-16($5) - daddiu $4,$4,-8 - daddiu $5,$5,-8 - daddiu $9,$9,-1 - dsll $11,$10,$7 - dsrl $12,$3,$13 - move $10,$3 - or $8,$11,$12 - bne $9,$0,.Loop0 - sd $8,0($4) - -.L0: beq $6,$0,.Lend - nop - -.Loop: ld $3,-16($5) - daddiu $4,$4,-32 - daddiu $6,$6,-4 - dsll $11,$10,$7 - dsrl $12,$3,$13 - - ld $10,-24($5) - dsll $14,$3,$7 - or $8,$11,$12 - sd $8,24($4) - dsrl $9,$10,$13 - - ld $3,-32($5) - dsll $11,$10,$7 - or $8,$14,$9 - sd $8,16($4) - dsrl $12,$3,$13 - - ld $10,-40($5) - dsll $14,$3,$7 - or $8,$11,$12 - sd $8,8($4) - dsrl $9,$10,$13 - - daddiu $5,$5,-32 - or $8,$14,$9 - bgtz $6,.Loop - sd $8,0($4) - -.Lend: dsll $8,$10,$7 - j $31 - sd $8,-8($4) - .end _gcry_mpih_lshift diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul1.S deleted file mode 100644 index 6c0099de3..000000000 --- a/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul1.S +++ /dev/null @@ -1,89 +0,0 @@ -/* mips3 mpih-mul1.S -- Multiply a limb vector with a limb and store - * the result in a second limb vector. - * - * Copyright (C) 1992, 1994, 1995, 1998, 2000 - * 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 - */ - - -/******************* - * mpi_limb_t - * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r4) - * mpi_ptr_t s1_ptr, (r5) - * mpi_size_t s1_size, (r6) - * mpi_limb_t s2_limb) (r7) - */ - - .text - .align 4 - .globl _gcry_mpih_mul_1 - .ent _gcry_mpih_mul_1 -_gcry_mpih_mul_1: - .set noreorder - .set nomacro - -/* # warm up phase 0 */ - ld $8,0($5) - -/* # warm up phase 1 */ - daddiu $5,$5,8 - dmultu $8,$7 - - daddiu $6,$6,-1 - beq $6,$0,$LC0 - move $2,$0 # zero cy2 - - daddiu $6,$6,-1 - beq $6,$0,$LC1 - ld $8,0($5) # load new s1 limb as early as possible - -Loop: mflo $10 - mfhi $9 - daddiu $5,$5,8 - daddu $10,$10,$2 # add old carry limb to low product limb - dmultu $8,$7 - ld $8,0($5) # load new s1 limb as early as possible - daddiu $6,$6,-1 # decrement loop counter - sltu $2,$10,$2 # carry from previous addition -> $2 - sd $10,0($4) - daddiu $4,$4,8 - bne $6,$0,Loop - daddu $2,$9,$2 # add high product limb and carry from addition - -/* # cool down phase 1 */ -$LC1: mflo $10 - mfhi $9 - daddu $10,$10,$2 - sltu $2,$10,$2 - dmultu $8,$7 - sd $10,0($4) - daddiu $4,$4,8 - daddu $2,$9,$2 # add high product limb and carry from addition - -/* # cool down phase 0 */ -$LC0: mflo $10 - mfhi $9 - daddu $10,$10,$2 - sltu $2,$10,$2 - sd $10,0($4) - j $31 - daddu $2,$9,$2 # add high product limb and carry from addition - - .end _gcry_mpih_mul_1 - diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul2.S deleted file mode 100644 index ca8276388..000000000 --- a/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul2.S +++ /dev/null @@ -1,101 +0,0 @@ -/* MIPS3 addmul_1 -- Multiply a limb vector with a single limb and - * add the product to a second limb vector. - * - * Copyright (C) 1992, 1994, 1995, 1998, 2000 - * 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 - */ - - -/******************* - * mpi_limb_t - * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r4) - * mpi_ptr_t s1_ptr, (r5) - * mpi_size_t s1_size, (r6) - * mpi_limb_t s2_limb) (r7) - */ - - .text - .align 4 - .globl _gcry_mpih_addmul_1 - .ent _gcry_mpih_addmul_1 -_gcry_mpih_addmul_1: - .set noreorder - .set nomacro - -/* # warm up phase 0 */ - ld $8,0($5) - -/* # warm up phase 1 */ - daddiu $5,$5,8 - dmultu $8,$7 - - daddiu $6,$6,-1 - beq $6,$0,$LC0 - move $2,$0 # zero cy2 - - daddiu $6,$6,-1 - beq $6,$0,$LC1 - ld $8,0($5) # load new s1 limb as early as possible - -Loop: ld $10,0($4) - mflo $3 - mfhi $9 - daddiu $5,$5,8 - daddu $3,$3,$2 # add old carry limb to low product limb - dmultu $8,$7 - ld $8,0($5) # load new s1 limb as early as possible - daddiu $6,$6,-1 # decrement loop counter - sltu $2,$3,$2 # carry from previous addition -> $2 - daddu $3,$10,$3 - sltu $10,$3,$10 - daddu $2,$2,$10 - sd $3,0($4) - daddiu $4,$4,8 - bne $6,$0,Loop - daddu $2,$9,$2 # add high product limb and carry from addition - -/* # cool down phase 1 */ -$LC1: ld $10,0($4) - mflo $3 - mfhi $9 - daddu $3,$3,$2 - sltu $2,$3,$2 - dmultu $8,$7 - daddu $3,$10,$3 - sltu $10,$3,$10 - daddu $2,$2,$10 - sd $3,0($4) - daddiu $4,$4,8 - daddu $2,$9,$2 # add high product limb and carry from addition - -/* # cool down phase 0 */ -$LC0: ld $10,0($4) - mflo $3 - mfhi $9 - daddu $3,$3,$2 - sltu $2,$3,$2 - daddu $3,$10,$3 - sltu $10,$3,$10 - daddu $2,$2,$10 - sd $3,0($4) - j $31 - daddu $2,$9,$2 # add high product limb and carry from addition - - .end _gcry_mpih_addmul_1 - diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul3.S deleted file mode 100644 index be421a68e..000000000 --- a/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul3.S +++ /dev/null @@ -1,101 +0,0 @@ -/* MIPS3 submul_1 -- Multiply a limb vector with a single limb and - * subtract the product from a second limb vector. - * - * Copyright (C) 1992, 1994, 1995, 1998, 2000 - * 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 - */ - - -/******************* - * mpi_limb_t - * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r4) - * mpi_ptr_t s1_ptr, (r5) - * mpi_size_t s1_size, (r6) - * mpi_limb_t s2_limb) (r7) - */ - - .text - .align 4 - .globl _gcry_mpih_submul_1 - .ent _gcry_mpih_submul_1 -_gcry_mpih_submul_1: - .set noreorder - .set nomacro - -/* # warm up phase 0 */ - ld $8,0($5) - -/* # warm up phase 1 */ - daddiu $5,$5,8 - dmultu $8,$7 - - daddiu $6,$6,-1 - beq $6,$0,$LC0 - move $2,$0 # zero cy2 - - daddiu $6,$6,-1 - beq $6,$0,$LC1 - ld $8,0($5) # load new s1 limb as early as possible - -Loop: ld $10,0($4) - mflo $3 - mfhi $9 - daddiu $5,$5,8 - daddu $3,$3,$2 # add old carry limb to low product limb - dmultu $8,$7 - ld $8,0($5) # load new s1 limb as early as possible - daddiu $6,$6,-1 # decrement loop counter - sltu $2,$3,$2 # carry from previous addition -> $2 - dsubu $3,$10,$3 - sgtu $10,$3,$10 - daddu $2,$2,$10 - sd $3,0($4) - daddiu $4,$4,8 - bne $6,$0,Loop - daddu $2,$9,$2 # add high product limb and carry from addition - -/* # cool down phase 1 */ -$LC1: ld $10,0($4) - mflo $3 - mfhi $9 - daddu $3,$3,$2 - sltu $2,$3,$2 - dmultu $8,$7 - dsubu $3,$10,$3 - sgtu $10,$3,$10 - daddu $2,$2,$10 - sd $3,0($4) - daddiu $4,$4,8 - daddu $2,$9,$2 # add high product limb and carry from addition - -/* # cool down phase 0 */ -$LC0: ld $10,0($4) - mflo $3 - mfhi $9 - daddu $3,$3,$2 - sltu $2,$3,$2 - dsubu $3,$10,$3 - sgtu $10,$3,$10 - daddu $2,$2,$10 - sd $3,0($4) - j $31 - daddu $2,$9,$2 # add high product limb and carry from addition - - .end _gcry_mpih_submul_1 - diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-rshift.S deleted file mode 100644 index e7e035a03..000000000 --- a/grub-core/lib/libgcrypt/mpi/mips3/mpih-rshift.S +++ /dev/null @@ -1,95 +0,0 @@ -/* mips3 rshift - * - * Copyright (C) 1995, 1998, 2000 - * 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 - */ - -/******************* - * mpi_limb_t - * _gcry_mpih_rshift( mpi_ptr_t wp, ($4) - * mpi_ptr_t up, ($5) - * mpi_size_t usize, ($6) - * unsigned cnt) ($7) - */ - - .text - .align 2 - .globl _gcry_mpih_rshift - .ent _gcry_mpih_rshift -_gcry_mpih_rshift: - .set noreorder - .set nomacro - - ld $10,0($5) # load first limb - dsubu $13,$0,$7 - daddiu $6,$6,-1 - and $9,$6,4-1 # number of limbs in first loop - beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop - dsll $2,$10,$13 # compute function result - - dsubu $6,$6,$9 - -.Loop0: ld $3,8($5) - daddiu $4,$4,8 - daddiu $5,$5,8 - daddiu $9,$9,-1 - dsrl $11,$10,$7 - dsll $12,$3,$13 - move $10,$3 - or $8,$11,$12 - bne $9,$0,.Loop0 - sd $8,-8($4) - -.L0: beq $6,$0,.Lend - nop - -.Loop: ld $3,8($5) - daddiu $4,$4,32 - daddiu $6,$6,-4 - dsrl $11,$10,$7 - dsll $12,$3,$13 - - ld $10,16($5) - dsrl $14,$3,$7 - or $8,$11,$12 - sd $8,-32($4) - dsll $9,$10,$13 - - ld $3,24($5) - dsrl $11,$10,$7 - or $8,$14,$9 - sd $8,-24($4) - dsll $12,$3,$13 - - ld $10,32($5) - dsrl $14,$3,$7 - or $8,$11,$12 - sd $8,-16($4) - dsll $9,$10,$13 - - daddiu $5,$5,32 - or $8,$14,$9 - bgtz $6,.Loop - sd $8,-8($4) - -.Lend: dsrl $8,$10,$7 - j $31 - sd $8,0($4) - .end _gcry_mpih_rshift - diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-sub1.S deleted file mode 100644 index 9fac67439..000000000 --- a/grub-core/lib/libgcrypt/mpi/mips3/mpih-sub1.S +++ /dev/null @@ -1,125 +0,0 @@ -/* mips3 sub_n -- Subtract two limb vectors of the same length > 0 and - * store difference in a third limb vector. - * - * Copyright (C) 1995, 1998, 1999, 2000, - * 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 - */ - - -/******************* - * mpi_limb_t - * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r4) - * mpi_ptr_t s1_ptr, (r5) - * mpi_ptr_t s2_ptr, (r6) - * mpi_size_t size) (r7) - */ - - - .text - .align 2 - .globl _gcry_mpih_sub_n - .ent _gcry_mpih_sub_n -_gcry_mpih_sub_n: - .set noreorder - .set nomacro - - ld $10,0($5) - ld $11,0($6) - - daddiu $7,$7,-1 - and $9,$7,4-1 # number of limbs in first loop - beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop - move $2,$0 - - dsubu $7,$7,$9 - -.Loop0: daddiu $9,$9,-1 - ld $12,8($5) - daddu $11,$11,$2 - ld $13,8($6) - sltu $8,$11,$2 - dsubu $11,$10,$11 - sltu $2,$10,$11 - sd $11,0($4) - or $2,$2,$8 - - daddiu $5,$5,8 - daddiu $6,$6,8 - move $10,$12 - move $11,$13 - bne $9,$0,.Loop0 - daddiu $4,$4,8 - -.L0: beq $7,$0,.Lend - nop - -.Loop: daddiu $7,$7,-4 - - ld $12,8($5) - daddu $11,$11,$2 - ld $13,8($6) - sltu $8,$11,$2 - dsubu $11,$10,$11 - sltu $2,$10,$11 - sd $11,0($4) - or $2,$2,$8 - - ld $10,16($5) - daddu $13,$13,$2 - ld $11,16($6) - sltu $8,$13,$2 - dsubu $13,$12,$13 - sltu $2,$12,$13 - sd $13,8($4) - or $2,$2,$8 - - ld $12,24($5) - daddu $11,$11,$2 - ld $13,24($6) - sltu $8,$11,$2 - dsubu $11,$10,$11 - sltu $2,$10,$11 - sd $11,16($4) - or $2,$2,$8 - - ld $10,32($5) - daddu $13,$13,$2 - ld $11,32($6) - sltu $8,$13,$2 - dsubu $13,$12,$13 - sltu $2,$12,$13 - sd $13,24($4) - or $2,$2,$8 - - daddiu $5,$5,32 - daddiu $6,$6,32 - - bne $7,$0,.Loop - daddiu $4,$4,32 - -.Lend: daddu $11,$11,$2 - sltu $8,$11,$2 - dsubu $11,$10,$11 - sltu $2,$10,$11 - sd $11,0($4) - j $31 - or $2,$2,$8 - - .end _gcry_mpih_sub_n - diff --git a/grub-core/lib/libgcrypt/mpi/mpi-add.c b/grub-core/lib/libgcrypt/mpi/mpi-add.c deleted file mode 100644 index 98abc5650..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpi-add.c +++ /dev/null @@ -1,235 +0,0 @@ -/* mpi-add.c - MPI functions - * Copyright (C) 1994, 1996, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#include -#include -#include - -#include "mpi-internal.h" - - -/**************** - * Add the unsigned integer V to the mpi-integer U and store the - * result in W. U and V may be the same. - */ -void -gcry_mpi_add_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v ) -{ - mpi_ptr_t wp, up; - mpi_size_t usize, wsize; - int usign, wsign; - - usize = u->nlimbs; - usign = u->sign; - wsign = 0; - - /* If not space for W (and possible carry), increase space. */ - wsize = usize + 1; - if( w->alloced < wsize ) - mpi_resize(w, wsize); - - /* These must be after realloc (U may be the same as W). */ - up = u->d; - wp = w->d; - - if( !usize ) { /* simple */ - wp[0] = v; - wsize = v? 1:0; - } - else if( !usign ) { /* mpi is not negative */ - mpi_limb_t cy; - cy = _gcry_mpih_add_1(wp, up, usize, v); - wp[usize] = cy; - wsize = usize + cy; - } - else { /* The signs are different. Need exact comparison to determine - * which operand to subtract from which. */ - if( usize == 1 && up[0] < v ) { - wp[0] = v - up[0]; - wsize = 1; - } - else { - _gcry_mpih_sub_1(wp, up, usize, v); - /* Size can decrease with at most one limb. */ - wsize = usize - (wp[usize-1]==0); - wsign = 1; - } - } - - w->nlimbs = wsize; - w->sign = wsign; -} - - -void -gcry_mpi_add(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) -{ - mpi_ptr_t wp, up, vp; - mpi_size_t usize, vsize, wsize; - int usign, vsign, wsign; - - if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */ - usize = v->nlimbs; - usign = v->sign; - vsize = u->nlimbs; - vsign = u->sign; - wsize = usize + 1; - RESIZE_IF_NEEDED(w, wsize); - /* These must be after realloc (u or v may be the same as w). */ - up = v->d; - vp = u->d; - } - else { - usize = u->nlimbs; - usign = u->sign; - vsize = v->nlimbs; - vsign = v->sign; - wsize = usize + 1; - RESIZE_IF_NEEDED(w, wsize); - /* These must be after realloc (u or v may be the same as w). */ - up = u->d; - vp = v->d; - } - wp = w->d; - wsign = 0; - - if( !vsize ) { /* simple */ - MPN_COPY(wp, up, usize ); - wsize = usize; - wsign = usign; - } - else if( usign != vsign ) { /* different sign */ - /* This test is right since USIZE >= VSIZE */ - if( usize != vsize ) { - _gcry_mpih_sub(wp, up, usize, vp, vsize); - wsize = usize; - MPN_NORMALIZE(wp, wsize); - wsign = usign; - } - else if( _gcry_mpih_cmp(up, vp, usize) < 0 ) { - _gcry_mpih_sub_n(wp, vp, up, usize); - wsize = usize; - MPN_NORMALIZE(wp, wsize); - if( !usign ) - wsign = 1; - } - else { - _gcry_mpih_sub_n(wp, up, vp, usize); - wsize = usize; - MPN_NORMALIZE(wp, wsize); - if( usign ) - wsign = 1; - } - } - else { /* U and V have same sign. Add them. */ - mpi_limb_t cy = _gcry_mpih_add(wp, up, usize, vp, vsize); - wp[usize] = cy; - wsize = usize + cy; - if( usign ) - wsign = 1; - } - - w->nlimbs = wsize; - w->sign = wsign; -} - - -/**************** - * Subtract the unsigned integer V from the mpi-integer U and store the - * result in W. - */ -void -gcry_mpi_sub_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v ) -{ - mpi_ptr_t wp, up; - mpi_size_t usize, wsize; - int usign, wsign; - - usize = u->nlimbs; - usign = u->sign; - wsign = 0; - - /* If not space for W (and possible carry), increase space. */ - wsize = usize + 1; - if( w->alloced < wsize ) - mpi_resize(w, wsize); - - /* These must be after realloc (U may be the same as W). */ - up = u->d; - wp = w->d; - - if( !usize ) { /* simple */ - wp[0] = v; - wsize = v? 1:0; - wsign = 1; - } - else if( usign ) { /* mpi and v are negative */ - mpi_limb_t cy; - cy = _gcry_mpih_add_1(wp, up, usize, v); - wp[usize] = cy; - wsize = usize + cy; - } - else { /* The signs are different. Need exact comparison to determine - * which operand to subtract from which. */ - if( usize == 1 && up[0] < v ) { - wp[0] = v - up[0]; - wsize = 1; - wsign = 1; - } - else { - _gcry_mpih_sub_1(wp, up, usize, v); - /* Size can decrease with at most one limb. */ - wsize = usize - (wp[usize-1]==0); - } - } - - w->nlimbs = wsize; - w->sign = wsign; -} - -void -gcry_mpi_sub(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) -{ - gcry_mpi_t vv = mpi_copy (v); - vv->sign = ! vv->sign; - gcry_mpi_add (w, u, vv); - mpi_free (vv); -} - - -void -gcry_mpi_addm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) -{ - gcry_mpi_add(w, u, v); - _gcry_mpi_fdiv_r( w, w, m ); -} - -void -gcry_mpi_subm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) -{ - gcry_mpi_sub(w, u, v); - _gcry_mpi_fdiv_r( w, w, m ); -} diff --git a/grub-core/lib/libgcrypt/mpi/mpi-bit.c b/grub-core/lib/libgcrypt/mpi/mpi-bit.c deleted file mode 100644 index cdc6b0b33..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpi-bit.c +++ /dev/null @@ -1,364 +0,0 @@ -/* mpi-bit.c - MPI bit level functions - * Copyright (C) 1998, 1999, 2001, 2002, 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 - */ - -#include -#include -#include -#include "mpi-internal.h" -#include "longlong.h" - - -#ifdef MPI_INTERNAL_NEED_CLZ_TAB -#ifdef __STDC__ -const -#endif -unsigned char -_gcry_clz_tab[] = -{ - 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, -}; -#endif - - -#define A_LIMB_1 ((mpi_limb_t)1) - - -/**************** - * Sometimes we have MSL (most significant limbs) which are 0; - * this is for some reasons not good, so this function removes them. - */ -void -_gcry_mpi_normalize( gcry_mpi_t a ) -{ - if( mpi_is_opaque(a) ) - return; - - for( ; a->nlimbs && !a->d[a->nlimbs-1]; a->nlimbs-- ) - ; -} - - - -/**************** - * Return the number of bits in A. - */ -unsigned int -gcry_mpi_get_nbits( gcry_mpi_t a ) -{ - unsigned n; - - if( mpi_is_opaque(a) ) { - return a->sign; /* which holds the number of bits */ - } - - _gcry_mpi_normalize( a ); - if( a->nlimbs ) { - mpi_limb_t alimb = a->d[a->nlimbs-1]; - if( alimb ) - count_leading_zeros( n, alimb ); - else - n = BITS_PER_MPI_LIMB; - n = BITS_PER_MPI_LIMB - n + (a->nlimbs-1) * BITS_PER_MPI_LIMB; - } - else - n = 0; - return n; -} - - -/**************** - * Test whether bit N is set. - */ -int -gcry_mpi_test_bit( gcry_mpi_t a, unsigned int n ) -{ - unsigned int limbno, bitno; - mpi_limb_t limb; - - limbno = n / BITS_PER_MPI_LIMB; - bitno = n % BITS_PER_MPI_LIMB; - - if( limbno >= a->nlimbs ) - return 0; /* too far left: this is a 0 */ - limb = a->d[limbno]; - return (limb & (A_LIMB_1 << bitno))? 1: 0; -} - - -/**************** - * Set bit N of A. - */ -void -gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n ) -{ - unsigned int limbno, bitno; - - limbno = n / BITS_PER_MPI_LIMB; - bitno = n % BITS_PER_MPI_LIMB; - - if ( limbno >= a->nlimbs ) - { - mpi_resize (a, limbno+1 ); - a->nlimbs = limbno+1; - } - a->d[limbno] |= (A_LIMB_1<= a->nlimbs ) - { - mpi_resize (a, limbno+1 ); - a->nlimbs = limbno+1; - } - a->d[limbno] |= (A_LIMB_1<d[limbno] &= ~(A_LIMB_1 << bitno); - a->nlimbs = limbno+1; -} - -/**************** - * clear bit N of A and all bits above - */ -void -gcry_mpi_clear_highbit( gcry_mpi_t a, unsigned int n ) -{ - unsigned int limbno, bitno; - - limbno = n / BITS_PER_MPI_LIMB; - bitno = n % BITS_PER_MPI_LIMB; - - if( limbno >= a->nlimbs ) - return; /* not allocated, therefore no need to clear bits - :-) */ - - for( ; bitno < BITS_PER_MPI_LIMB; bitno++ ) - a->d[limbno] &= ~(A_LIMB_1 << bitno); - a->nlimbs = limbno+1; -} - -/**************** - * Clear bit N of A. - */ -void -gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n ) -{ - unsigned int limbno, bitno; - - limbno = n / BITS_PER_MPI_LIMB; - bitno = n % BITS_PER_MPI_LIMB; - - if( limbno >= a->nlimbs ) - return; /* don't need to clear this bit, it's to far to left */ - a->d[limbno] &= ~(A_LIMB_1 << bitno); -} - - -/**************** - * Shift A by COUNT limbs to the right - * This is used only within the MPI library - */ -void -_gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count ) -{ - mpi_ptr_t ap = a->d; - mpi_size_t n = a->nlimbs; - unsigned int i; - - if( count >= n ) { - a->nlimbs = 0; - return; - } - - for( i = 0; i < n - count; i++ ) - ap[i] = ap[i+count]; - ap[i] = 0; - a->nlimbs -= count; -} - - -/* - * Shift A by N bits to the right. - */ -void -gcry_mpi_rshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n ) -{ - mpi_size_t xsize; - unsigned int i; - unsigned int nlimbs = (n/BITS_PER_MPI_LIMB); - unsigned int nbits = (n%BITS_PER_MPI_LIMB); - - if ( x == a ) - { - /* In-place operation. */ - if ( nlimbs >= x->nlimbs ) - { - x->nlimbs = 0; - return; - } - - if (nlimbs) - { - for (i=0; i < x->nlimbs - nlimbs; i++ ) - x->d[i] = x->d[i+nlimbs]; - x->d[i] = 0; - x->nlimbs -= nlimbs; - - } - if ( x->nlimbs && nbits ) - _gcry_mpih_rshift ( x->d, x->d, x->nlimbs, nbits ); - } - else if ( nlimbs ) - { - /* Copy and shift by more or equal bits than in a limb. */ - xsize = a->nlimbs; - x->sign = a->sign; - RESIZE_IF_NEEDED (x, xsize); - x->nlimbs = xsize; - for (i=0; i < a->nlimbs; i++ ) - x->d[i] = a->d[i]; - x->nlimbs = i; - - if ( nlimbs >= x->nlimbs ) - { - x->nlimbs = 0; - return; - } - - if (nlimbs) - { - for (i=0; i < x->nlimbs - nlimbs; i++ ) - x->d[i] = x->d[i+nlimbs]; - x->d[i] = 0; - x->nlimbs -= nlimbs; - } - - if ( x->nlimbs && nbits ) - _gcry_mpih_rshift ( x->d, x->d, x->nlimbs, nbits ); - } - else - { - /* Copy and shift by less than bits in a limb. */ - xsize = a->nlimbs; - x->sign = a->sign; - RESIZE_IF_NEEDED (x, xsize); - x->nlimbs = xsize; - - if ( xsize ) - { - if (nbits ) - _gcry_mpih_rshift (x->d, a->d, x->nlimbs, nbits ); - else - { - /* The rshift helper function is not specified for - NBITS==0, thus we do a plain copy here. */ - for (i=0; i < x->nlimbs; i++ ) - x->d[i] = a->d[i]; - } - } - } - MPN_NORMALIZE (x->d, x->nlimbs); -} - - -/**************** - * Shift A by COUNT limbs to the left - * This is used only within the MPI library - */ -void -_gcry_mpi_lshift_limbs (gcry_mpi_t a, unsigned int count) -{ - mpi_ptr_t ap; - int n = a->nlimbs; - int i; - - if (!count || !n) - return; - - RESIZE_IF_NEEDED (a, n+count); - - ap = a->d; - for (i = n-1; i >= 0; i--) - ap[i+count] = ap[i]; - for (i=0; i < count; i++ ) - ap[i] = 0; - a->nlimbs += count; -} - - -/* - * Shift A by N bits to the left. - */ -void -gcry_mpi_lshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n ) -{ - unsigned int nlimbs = (n/BITS_PER_MPI_LIMB); - unsigned int nbits = (n%BITS_PER_MPI_LIMB); - - if (x == a && !n) - return; /* In-place shift with an amount of zero. */ - - if ( x != a ) - { - /* Copy A to X. */ - unsigned int alimbs = a->nlimbs; - int asign = a->sign; - mpi_ptr_t xp, ap; - - RESIZE_IF_NEEDED (x, alimbs+nlimbs+1); - xp = x->d; - ap = a->d; - MPN_COPY (xp, ap, alimbs); - x->nlimbs = alimbs; - x->flags = a->flags; - x->sign = asign; - } - - if (nlimbs && !nbits) - { - /* Shift a full number of limbs. */ - _gcry_mpi_lshift_limbs (x, nlimbs); - } - else if (n) - { - /* We use a very dump approach: Shift left by the number of - limbs plus one and than fix it up by an rshift. */ - _gcry_mpi_lshift_limbs (x, nlimbs+1); - gcry_mpi_rshift (x, x, BITS_PER_MPI_LIMB - nbits); - } - - MPN_NORMALIZE (x->d, x->nlimbs); -} diff --git a/grub-core/lib/libgcrypt/mpi/mpi-cmp.c b/grub-core/lib/libgcrypt/mpi/mpi-cmp.c deleted file mode 100644 index 30e1fce93..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpi-cmp.c +++ /dev/null @@ -1,107 +0,0 @@ -/* mpi-cmp.c - MPI functions - * Copyright (C) 1998, 1999, 2001, 2002, 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 -#include -#include -#include "mpi-internal.h" - -int -gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v) -{ - mpi_limb_t limb = v; - - _gcry_mpi_normalize (u); - - /* Handle the case that U contains no limb. */ - if (u->nlimbs == 0) - return -(limb != 0); - - /* Handle the case that U is negative. */ - if (u->sign) - return -1; - - if (u->nlimbs == 1) - { - /* Handle the case that U contains exactly one limb. */ - - if (u->d[0] > limb) - return 1; - if (u->d[0] < limb) - return -1; - return 0; - } - else - /* Handle the case that U contains more than one limb. */ - return 1; -} - - -int -gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v) -{ - mpi_size_t usize; - mpi_size_t vsize; - int cmp; - - if (mpi_is_opaque (u) || mpi_is_opaque (v)) - { - if (mpi_is_opaque (u) && !mpi_is_opaque (v)) - return -1; - if (!mpi_is_opaque (u) && mpi_is_opaque (v)) - return 1; - if (!u->sign && !v->sign) - return 0; /* Empty buffers are identical. */ - if (u->sign < v->sign) - return -1; - if (u->sign > v->sign) - return 1; - return memcmp (u->d, v->d, (u->sign+7)/8); - } - else - { - _gcry_mpi_normalize (u); - _gcry_mpi_normalize (v); - - usize = u->nlimbs; - vsize = v->nlimbs; - - /* Compare sign bits. */ - - if (!u->sign && v->sign) - return 1; - if (u->sign && !v->sign) - return -1; - - /* U and V are either both positive or both negative. */ - - if (usize != vsize && !u->sign && !v->sign) - return usize - vsize; - if (usize != vsize && u->sign && v->sign) - return vsize + usize; - if (!usize ) - return 0; - if (!(cmp = _gcry_mpih_cmp (u->d, v->d, usize))) - return 0; - if ((cmp < 0?1:0) == (u->sign?1:0)) - return 1; - } - return -1; -} diff --git a/grub-core/lib/libgcrypt/mpi/mpi-div.c b/grub-core/lib/libgcrypt/mpi/mpi-div.c deleted file mode 100644 index a6ee3006e..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpi-div.c +++ /dev/null @@ -1,355 +0,0 @@ -/* mpi-div.c - MPI functions - * Copyright (C) 1994, 1996, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#include -#include -#include -#include "mpi-internal.h" -#include "longlong.h" -#include "g10lib.h" - - -void -_gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor ) -{ - int divisor_sign = divisor->sign; - gcry_mpi_t temp_divisor = NULL; - - /* We need the original value of the divisor after the remainder has been - * preliminary calculated. We have to copy it to temporary space if it's - * the same variable as REM. */ - if( rem == divisor ) { - temp_divisor = mpi_copy( divisor ); - divisor = temp_divisor; - } - - _gcry_mpi_tdiv_r( rem, dividend, divisor ); - - if( ((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs ) - gcry_mpi_add( rem, rem, divisor); - - if( temp_divisor ) - mpi_free(temp_divisor); -} - - - -/**************** - * Division rounding the quotient towards -infinity. - * The remainder gets the same sign as the denominator. - * rem is optional - */ - -ulong -_gcry_mpi_fdiv_r_ui( gcry_mpi_t rem, gcry_mpi_t dividend, ulong divisor ) -{ - mpi_limb_t rlimb; - - rlimb = _gcry_mpih_mod_1( dividend->d, dividend->nlimbs, divisor ); - if( rlimb && dividend->sign ) - rlimb = divisor - rlimb; - - if( rem ) { - rem->d[0] = rlimb; - rem->nlimbs = rlimb? 1:0; - } - return rlimb; -} - - -void -_gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor ) -{ - gcry_mpi_t tmp = mpi_alloc( mpi_get_nlimbs(quot) ); - _gcry_mpi_fdiv_qr( quot, tmp, dividend, divisor); - mpi_free(tmp); -} - -void -_gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor ) -{ - int divisor_sign = divisor->sign; - gcry_mpi_t temp_divisor = NULL; - - if( quot == divisor || rem == divisor ) { - temp_divisor = mpi_copy( divisor ); - divisor = temp_divisor; - } - - _gcry_mpi_tdiv_qr( quot, rem, dividend, divisor ); - - if( (divisor_sign ^ dividend->sign) && rem->nlimbs ) { - gcry_mpi_sub_ui( quot, quot, 1 ); - gcry_mpi_add( rem, rem, divisor); - } - - if( temp_divisor ) - mpi_free(temp_divisor); -} - - -/* If den == quot, den needs temporary storage. - * If den == rem, den needs temporary storage. - * If num == quot, num needs temporary storage. - * If den has temporary storage, it can be normalized while being copied, - * i.e no extra storage should be allocated. - */ - -void -_gcry_mpi_tdiv_r( gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den) -{ - _gcry_mpi_tdiv_qr(NULL, rem, num, den ); -} - -void -_gcry_mpi_tdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den) -{ - mpi_ptr_t np, dp; - mpi_ptr_t qp, rp; - mpi_size_t nsize = num->nlimbs; - mpi_size_t dsize = den->nlimbs; - mpi_size_t qsize, rsize; - mpi_size_t sign_remainder = num->sign; - mpi_size_t sign_quotient = num->sign ^ den->sign; - unsigned normalization_steps; - mpi_limb_t q_limb; - mpi_ptr_t marker[5]; - unsigned int marker_nlimbs[5]; - int markidx=0; - - /* Ensure space is enough for quotient and remainder. - * We need space for an extra limb in the remainder, because it's - * up-shifted (normalized) below. */ - rsize = nsize + 1; - mpi_resize( rem, rsize); - - qsize = rsize - dsize; /* qsize cannot be bigger than this. */ - if( qsize <= 0 ) { - if( num != rem ) { - rem->nlimbs = num->nlimbs; - rem->sign = num->sign; - MPN_COPY(rem->d, num->d, nsize); - } - if( quot ) { - /* This needs to follow the assignment to rem, in case the - * numerator and quotient are the same. */ - quot->nlimbs = 0; - quot->sign = 0; - } - return; - } - - if( quot ) - mpi_resize( quot, qsize); - - /* Read pointers here, when reallocation is finished. */ - np = num->d; - dp = den->d; - rp = rem->d; - - /* Optimize division by a single-limb divisor. */ - if( dsize == 1 ) { - mpi_limb_t rlimb; - if( quot ) { - qp = quot->d; - rlimb = _gcry_mpih_divmod_1( qp, np, nsize, dp[0] ); - qsize -= qp[qsize - 1] == 0; - quot->nlimbs = qsize; - quot->sign = sign_quotient; - } - else - rlimb = _gcry_mpih_mod_1( np, nsize, dp[0] ); - rp[0] = rlimb; - rsize = rlimb != 0?1:0; - rem->nlimbs = rsize; - rem->sign = sign_remainder; - return; - } - - - if( quot ) { - qp = quot->d; - /* Make sure QP and NP point to different objects. Otherwise the - * numerator would be gradually overwritten by the quotient limbs. */ - if(qp == np) { /* Copy NP object to temporary space. */ - marker_nlimbs[markidx] = nsize; - np = marker[markidx++] = mpi_alloc_limb_space(nsize, - mpi_is_secure(quot)); - MPN_COPY(np, qp, nsize); - } - } - else /* Put quotient at top of remainder. */ - qp = rp + dsize; - - count_leading_zeros( normalization_steps, dp[dsize - 1] ); - - /* Normalize the denominator, i.e. make its most significant bit set by - * shifting it NORMALIZATION_STEPS bits to the left. Also shift the - * numerator the same number of steps (to keep the quotient the same!). - */ - if( normalization_steps ) { - mpi_ptr_t tp; - mpi_limb_t nlimb; - - /* Shift up the denominator setting the most significant bit of - * the most significant word. Use temporary storage not to clobber - * the original contents of the denominator. */ - marker_nlimbs[markidx] = dsize; - tp = marker[markidx++] = mpi_alloc_limb_space(dsize,mpi_is_secure(den)); - _gcry_mpih_lshift( tp, dp, dsize, normalization_steps ); - dp = tp; - - /* Shift up the numerator, possibly introducing a new most - * significant word. Move the shifted numerator in the remainder - * meanwhile. */ - nlimb = _gcry_mpih_lshift(rp, np, nsize, normalization_steps); - if( nlimb ) { - rp[nsize] = nlimb; - rsize = nsize + 1; - } - else - rsize = nsize; - } - else { - /* The denominator is already normalized, as required. Copy it to - * temporary space if it overlaps with the quotient or remainder. */ - if( dp == rp || (quot && (dp == qp))) { - mpi_ptr_t tp; - - marker_nlimbs[markidx] = dsize; - tp = marker[markidx++] = mpi_alloc_limb_space(dsize, - mpi_is_secure(den)); - MPN_COPY( tp, dp, dsize ); - dp = tp; - } - - /* Move the numerator to the remainder. */ - if( rp != np ) - MPN_COPY(rp, np, nsize); - - rsize = nsize; - } - - q_limb = _gcry_mpih_divrem( qp, 0, rp, rsize, dp, dsize ); - - if( quot ) { - qsize = rsize - dsize; - if(q_limb) { - qp[qsize] = q_limb; - qsize += 1; - } - - quot->nlimbs = qsize; - quot->sign = sign_quotient; - } - - rsize = dsize; - MPN_NORMALIZE (rp, rsize); - - if( normalization_steps && rsize ) { - _gcry_mpih_rshift(rp, rp, rsize, normalization_steps); - rsize -= rp[rsize - 1] == 0?1:0; - } - - rem->nlimbs = rsize; - rem->sign = sign_remainder; - while( markidx ) - { - markidx--; - _gcry_mpi_free_limb_space (marker[markidx], marker_nlimbs[markidx]); - } -} - -void -_gcry_mpi_tdiv_q_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned int count ) -{ - mpi_size_t usize, wsize; - mpi_size_t limb_cnt; - - usize = u->nlimbs; - limb_cnt = count / BITS_PER_MPI_LIMB; - wsize = usize - limb_cnt; - if( limb_cnt >= usize ) - w->nlimbs = 0; - else { - mpi_ptr_t wp; - mpi_ptr_t up; - - RESIZE_IF_NEEDED( w, wsize ); - wp = w->d; - up = u->d; - - count %= BITS_PER_MPI_LIMB; - if( count ) { - _gcry_mpih_rshift( wp, up + limb_cnt, wsize, count ); - wsize -= !wp[wsize - 1]; - } - else { - MPN_COPY_INCR( wp, up + limb_cnt, wsize); - } - - w->nlimbs = wsize; - } -} - -/**************** - * Check whether dividend is divisible by divisor - * (note: divisor must fit into a limb) - */ -int -_gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor ) -{ - return !_gcry_mpih_mod_1( dividend->d, dividend->nlimbs, divisor ); -} - - -void -gcry_mpi_div (gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor, int round) -{ - if (!round) - { - if (!rem) - { - gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs(quot)); - _gcry_mpi_tdiv_qr (quot, tmp, dividend, divisor); - mpi_free (tmp); - } - else - _gcry_mpi_tdiv_qr (quot, rem, dividend, divisor); - } - else if (round < 0) - { - if (!rem) - _gcry_mpi_fdiv_q (quot, dividend, divisor); - else if (!quot) - _gcry_mpi_fdiv_r (rem, dividend, divisor); - else - _gcry_mpi_fdiv_qr (quot, rem, dividend, divisor); - } - else - log_bug ("mpi rounding to ceiling not yet implemented\n"); -} diff --git a/grub-core/lib/libgcrypt/mpi/mpi-gcd.c b/grub-core/lib/libgcrypt/mpi/mpi-gcd.c deleted file mode 100644 index 5cbefa121..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpi-gcd.c +++ /dev/null @@ -1,51 +0,0 @@ -/* mpi-gcd.c - MPI functions - * 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 -#include -#include -#include "mpi-internal.h" - -/**************** - * Find the greatest common divisor G of A and B. - * Return: true if this 1, false in all other cases - */ -int -gcry_mpi_gcd( gcry_mpi_t g, gcry_mpi_t xa, gcry_mpi_t xb ) -{ - gcry_mpi_t a, b; - - a = mpi_copy(xa); - b = mpi_copy(xb); - - /* TAOCP Vol II, 4.5.2, Algorithm A */ - a->sign = 0; - b->sign = 0; - while( gcry_mpi_cmp_ui( b, 0 ) ) { - _gcry_mpi_fdiv_r( g, a, b ); /* g used as temorary variable */ - mpi_set(a,b); - mpi_set(b,g); - } - mpi_set(g, a); - - mpi_free(a); - mpi_free(b); - return !gcry_mpi_cmp_ui( g, 1); -} diff --git a/grub-core/lib/libgcrypt/mpi/mpi-inline.c b/grub-core/lib/libgcrypt/mpi/mpi-inline.c deleted file mode 100644 index 39e222247..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpi-inline.c +++ /dev/null @@ -1,35 +0,0 @@ -/* mpi-inline.c - * 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 - */ - -#include -#include -#include - -/* put the inline functions as real functions into the lib */ -#define G10_MPI_INLINE_DECL - -#include "mpi-internal.h" - -/* always include the header because it is only - * included by mpi-internal if __GCC__ is defined but we - * need it here in all cases and the above definition of - * of the macro allows us to do so - */ -#include "mpi-inline.h" diff --git a/grub-core/lib/libgcrypt/mpi/mpi-inline.h b/grub-core/lib/libgcrypt/mpi/mpi-inline.h deleted file mode 100644 index 94e2aec8a..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpi-inline.h +++ /dev/null @@ -1,161 +0,0 @@ -/* mpi-inline.h - Internal to the Multi Precision Integers - * Copyright (C) 1994, 1996, 1998, 1999, - * 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#ifndef G10_MPI_INLINE_H -#define G10_MPI_INLINE_H - -/* Starting with gcc 4.3 "extern inline" conforms in c99 mode to the - c99 semantics. To keep the useful old semantics we use an - attribute. */ -#ifndef G10_MPI_INLINE_DECL -# ifdef __GNUC_STDC_INLINE__ -# define G10_MPI_INLINE_DECL extern inline __attribute__ ((__gnu_inline__)) -# else -# define G10_MPI_INLINE_DECL extern __inline__ -# endif -#endif - -G10_MPI_INLINE_DECL mpi_limb_t -_gcry_mpih_add_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_size_t s1_size, mpi_limb_t s2_limb) -{ - mpi_limb_t x; - - x = *s1_ptr++; - s2_limb += x; - *res_ptr++ = s2_limb; - if( s2_limb < x ) { /* sum is less than the left operand: handle carry */ - while( --s1_size ) { - x = *s1_ptr++ + 1; /* add carry */ - *res_ptr++ = x; /* and store */ - if( x ) /* not 0 (no overflow): we can stop */ - goto leave; - } - return 1; /* return carry (size of s1 to small) */ - } - - leave: - if( res_ptr != s1_ptr ) { /* not the same variable */ - mpi_size_t i; /* copy the rest */ - for( i=0; i < s1_size-1; i++ ) - res_ptr[i] = s1_ptr[i]; - } - return 0; /* no carry */ -} - - - -G10_MPI_INLINE_DECL mpi_limb_t -_gcry_mpih_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, - mpi_ptr_t s2_ptr, mpi_size_t s2_size) -{ - mpi_limb_t cy = 0; - - if( s2_size ) - cy = _gcry_mpih_add_n( res_ptr, s1_ptr, s2_ptr, s2_size ); - - if( s1_size - s2_size ) - cy = _gcry_mpih_add_1( res_ptr + s2_size, s1_ptr + s2_size, - s1_size - s2_size, cy); - return cy; -} - - -G10_MPI_INLINE_DECL mpi_limb_t -_gcry_mpih_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_size_t s1_size, mpi_limb_t s2_limb ) -{ - mpi_limb_t x; - - x = *s1_ptr++; - s2_limb = x - s2_limb; - *res_ptr++ = s2_limb; - if( s2_limb > x ) { - while( --s1_size ) { - x = *s1_ptr++; - *res_ptr++ = x - 1; - if( x ) - goto leave; - } - return 1; - } - - leave: - if( res_ptr != s1_ptr ) { - mpi_size_t i; - for( i=0; i < s1_size-1; i++ ) - res_ptr[i] = s1_ptr[i]; - } - return 0; -} - - - -G10_MPI_INLINE_DECL mpi_limb_t -_gcry_mpih_sub( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, - mpi_ptr_t s2_ptr, mpi_size_t s2_size) -{ - mpi_limb_t cy = 0; - - if( s2_size ) - cy = _gcry_mpih_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size); - - if( s1_size - s2_size ) - cy = _gcry_mpih_sub_1(res_ptr + s2_size, s1_ptr + s2_size, - s1_size - s2_size, cy); - return cy; -} - -/**************** - * Compare OP1_PTR/OP1_SIZE with OP2_PTR/OP2_SIZE. - * There are no restrictions on the relative sizes of - * the two arguments. - * Return 1 if OP1 > OP2, 0 if they are equal, and -1 if OP1 < OP2. - */ -G10_MPI_INLINE_DECL int -_gcry_mpih_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size ) -{ - mpi_size_t i; - mpi_limb_t op1_word, op2_word; - - for( i = size - 1; i >= 0 ; i--) { - op1_word = op1_ptr[i]; - op2_word = op2_ptr[i]; - if( op1_word != op2_word ) - goto diff; - } - return 0; - - diff: - /* This can *not* be simplified to - * op2_word - op2_word - * since that expression might give signed overflow. */ - return (op1_word > op2_word) ? 1 : -1; -} - - -#endif /*G10_MPI_INLINE_H*/ diff --git a/grub-core/lib/libgcrypt/mpi/mpi-internal.h b/grub-core/lib/libgcrypt/mpi/mpi-internal.h deleted file mode 100644 index e75b7c6d7..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpi-internal.h +++ /dev/null @@ -1,277 +0,0 @@ -/* mpi-internal.h - Internal to the Multi Precision Integers - * Copyright (C) 1994, 1996, 1998, 2000, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#ifndef G10_MPI_INTERNAL_H -#define G10_MPI_INTERNAL_H - -#include "mpi-asm-defs.h" - -#ifndef BITS_PER_MPI_LIMB -#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT - typedef unsigned int mpi_limb_t; - typedef signed int mpi_limb_signed_t; -#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG - typedef unsigned long int mpi_limb_t; - typedef signed long int mpi_limb_signed_t; -#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG - typedef unsigned long long int mpi_limb_t; - typedef signed long long int mpi_limb_signed_t; -#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT - typedef unsigned short int mpi_limb_t; - typedef signed short int mpi_limb_signed_t; -#else -#error BYTES_PER_MPI_LIMB does not match any C type -#endif -#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB) -#endif /*BITS_PER_MPI_LIMB*/ - -#include "mpi.h" - -/* If KARATSUBA_THRESHOLD is not already defined, define it to a - * value which is good on most machines. */ - -/* tested 4, 16, 32 and 64, where 16 gave the best performance when - * checking a 768 and a 1024 bit ElGamal signature. - * (wk 22.12.97) */ -#ifndef KARATSUBA_THRESHOLD -#define KARATSUBA_THRESHOLD 16 -#endif - -/* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */ -#if KARATSUBA_THRESHOLD < 2 -#undef KARATSUBA_THRESHOLD -#define KARATSUBA_THRESHOLD 2 -#endif - - -typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */ -typedef int mpi_size_t; /* (must be a signed type) */ - -#define ABS(x) (x >= 0 ? x : -x) -#define MIN(l,o) ((l) < (o) ? (l) : (o)) -#define MAX(h,i) ((h) > (i) ? (h) : (i)) -#define RESIZE_IF_NEEDED(a,b) \ - do { \ - if( (a)->alloced < (b) ) \ - mpi_resize((a), (b)); \ - } while(0) - -/* Copy N limbs from S to D. */ -#define MPN_COPY( d, s, n) \ - do { \ - mpi_size_t _i; \ - for( _i = 0; _i < (n); _i++ ) \ - (d)[_i] = (s)[_i]; \ - } while(0) - -#define MPN_COPY_INCR( d, s, n) \ - do { \ - mpi_size_t _i; \ - for( _i = 0; _i < (n); _i++ ) \ - (d)[_i] = (d)[_i]; \ - } while (0) - -#define MPN_COPY_DECR( d, s, n ) \ - do { \ - mpi_size_t _i; \ - for( _i = (n)-1; _i >= 0; _i--) \ - (d)[_i] = (s)[_i]; \ - } while(0) - -/* Zero N limbs at D */ -#define MPN_ZERO(d, n) \ - do { \ - int _i; \ - for( _i = 0; _i < (n); _i++ ) \ - (d)[_i] = 0; \ - } while (0) - -#define MPN_NORMALIZE(d, n) \ - do { \ - while( (n) > 0 ) { \ - if( (d)[(n)-1] ) \ - break; \ - (n)--; \ - } \ - } while(0) - -#define MPN_NORMALIZE_NOT_ZERO(d, n) \ - do { \ - for(;;) { \ - if( (d)[(n)-1] ) \ - break; \ - (n)--; \ - } \ - } while(0) - -#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \ - do { \ - if( (size) < KARATSUBA_THRESHOLD ) \ - mul_n_basecase (prodp, up, vp, size); \ - else \ - mul_n (prodp, up, vp, size, tspace); \ - } while (0); - - -/* Divide the two-limb number in (NH,,NL) by D, with DI being the largest - * limb not larger than (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB). - * If this would yield overflow, DI should be the largest possible number - * (i.e., only ones). For correct operation, the most significant bit of D - * has to be set. Put the quotient in Q and the remainder in R. - */ -#define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) \ - do { \ - mpi_limb_t _q, _ql, _r; \ - mpi_limb_t _xh, _xl; \ - umul_ppmm (_q, _ql, (nh), (di)); \ - _q += (nh); /* DI is 2**BITS_PER_MPI_LIMB too small */ \ - umul_ppmm (_xh, _xl, _q, (d)); \ - sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl); \ - if( _xh ) { \ - sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \ - _q++; \ - if( _xh) { \ - sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \ - _q++; \ - } \ - } \ - if( _r >= (d) ) { \ - _r -= (d); \ - _q++; \ - } \ - (r) = _r; \ - (q) = _q; \ - } while (0) - - -/*-- mpiutil.c --*/ -#define mpi_alloc_limb_space(n,f) _gcry_mpi_alloc_limb_space((n),(f)) -mpi_ptr_t _gcry_mpi_alloc_limb_space( unsigned nlimbs, int sec ); -void _gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs ); -void _gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned nlimbs ); - -/*-- mpi-bit.c --*/ -#define mpi_rshift_limbs(a,n) _gcry_mpi_rshift_limbs ((a), (n)) -#define mpi_lshift_limbs(a,n) _gcry_mpi_lshift_limbs ((a), (n)) - -void _gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count ); -void _gcry_mpi_lshift_limbs( gcry_mpi_t a, unsigned int count ); - - -/*-- mpih-add.c --*/ -mpi_limb_t _gcry_mpih_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_size_t s1_size, mpi_limb_t s2_limb ); -mpi_limb_t _gcry_mpih_add_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_ptr_t s2_ptr, mpi_size_t size); -mpi_limb_t _gcry_mpih_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, - mpi_ptr_t s2_ptr, mpi_size_t s2_size); - -/*-- mpih-sub.c --*/ -mpi_limb_t _gcry_mpih_sub_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_size_t s1_size, mpi_limb_t s2_limb ); -mpi_limb_t _gcry_mpih_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_ptr_t s2_ptr, mpi_size_t size); -mpi_limb_t _gcry_mpih_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, - mpi_ptr_t s2_ptr, mpi_size_t s2_size); - -/*-- mpih-cmp.c --*/ -int _gcry_mpih_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size ); - -/*-- mpih-mul.c --*/ - -struct karatsuba_ctx { - struct karatsuba_ctx *next; - mpi_ptr_t tspace; - unsigned int tspace_nlimbs; - mpi_size_t tspace_size; - mpi_ptr_t tp; - unsigned int tp_nlimbs; - mpi_size_t tp_size; -}; - -void _gcry_mpih_release_karatsuba_ctx( struct karatsuba_ctx *ctx ); - -mpi_limb_t _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_size_t s1_size, mpi_limb_t s2_limb); -mpi_limb_t _gcry_mpih_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_size_t s1_size, mpi_limb_t s2_limb); -void _gcry_mpih_mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp, - mpi_size_t size); -mpi_limb_t _gcry_mpih_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize, - mpi_ptr_t vp, mpi_size_t vsize); -void _gcry_mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size ); -void _gcry_mpih_sqr_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size, - mpi_ptr_t tspace); - -void _gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp, - mpi_ptr_t up, mpi_size_t usize, - mpi_ptr_t vp, mpi_size_t vsize, - struct karatsuba_ctx *ctx ); - - -/*-- mpih-mul_1.c (or xxx/cpu/ *.S) --*/ -mpi_limb_t _gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, - mpi_size_t s1_size, mpi_limb_t s2_limb); - -/*-- mpih-div.c --*/ -mpi_limb_t _gcry_mpih_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size, - mpi_limb_t divisor_limb); -mpi_limb_t _gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs, - mpi_ptr_t np, mpi_size_t nsize, - mpi_ptr_t dp, mpi_size_t dsize); -mpi_limb_t _gcry_mpih_divmod_1( mpi_ptr_t quot_ptr, - mpi_ptr_t dividend_ptr, mpi_size_t dividend_size, - mpi_limb_t divisor_limb); - -/*-- mpih-shift.c --*/ -mpi_limb_t _gcry_mpih_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, - unsigned cnt); -mpi_limb_t _gcry_mpih_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, - unsigned cnt); - - -/* Define stuff for longlong.h. */ -#define W_TYPE_SIZE BITS_PER_MPI_LIMB - typedef mpi_limb_t UWtype; - typedef unsigned int UHWtype; -#if defined (__GNUC__) - typedef unsigned int UQItype __attribute__ ((mode (QI))); - typedef int SItype __attribute__ ((mode (SI))); - typedef unsigned int USItype __attribute__ ((mode (SI))); - typedef int DItype __attribute__ ((mode (DI))); - typedef unsigned int UDItype __attribute__ ((mode (DI))); -#else - typedef unsigned char UQItype; - typedef long SItype; - typedef unsigned long USItype; -#endif - -#ifdef __GNUC__ -#include "mpi-inline.h" -#endif - -#endif /*G10_MPI_INTERNAL_H*/ diff --git a/grub-core/lib/libgcrypt/mpi/mpi-inv.c b/grub-core/lib/libgcrypt/mpi/mpi-inv.c deleted file mode 100644 index 5d269466e..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpi-inv.c +++ /dev/null @@ -1,267 +0,0 @@ -/* mpi-inv.c - MPI functions - * 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, see . - */ - -#include -#include -#include -#include "mpi-internal.h" -#include "g10lib.h" - -/**************** - * Calculate the multiplicative inverse X of A mod N - * That is: Find the solution x for - * 1 = (a*x) mod n - */ -int -gcry_mpi_invm( gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t n ) -{ -#if 0 - gcry_mpi_t u, v, u1, u2, u3, v1, v2, v3, q, t1, t2, t3; - gcry_mpi_t ta, tb, tc; - - u = mpi_copy(a); - v = mpi_copy(n); - u1 = mpi_alloc_set_ui(1); - u2 = mpi_alloc_set_ui(0); - u3 = mpi_copy(u); - v1 = mpi_alloc_set_ui(0); - v2 = mpi_alloc_set_ui(1); - v3 = mpi_copy(v); - q = mpi_alloc( mpi_get_nlimbs(u)+1 ); - t1 = mpi_alloc( mpi_get_nlimbs(u)+1 ); - t2 = mpi_alloc( mpi_get_nlimbs(u)+1 ); - t3 = mpi_alloc( mpi_get_nlimbs(u)+1 ); - while( mpi_cmp_ui( v3, 0 ) ) { - mpi_fdiv_q( q, u3, v3 ); - mpi_mul(t1, v1, q); mpi_mul(t2, v2, q); mpi_mul(t3, v3, q); - mpi_sub(t1, u1, t1); mpi_sub(t2, u2, t2); mpi_sub(t3, u3, t3); - mpi_set(u1, v1); mpi_set(u2, v2); mpi_set(u3, v3); - mpi_set(v1, t1); mpi_set(v2, t2); mpi_set(v3, t3); - } - /* log_debug("result:\n"); - log_mpidump("q =", q ); - log_mpidump("u1=", u1); - log_mpidump("u2=", u2); - log_mpidump("u3=", u3); - log_mpidump("v1=", v1); - log_mpidump("v2=", v2); */ - mpi_set(x, u1); - - mpi_free(u1); - mpi_free(u2); - mpi_free(u3); - mpi_free(v1); - mpi_free(v2); - mpi_free(v3); - mpi_free(q); - mpi_free(t1); - mpi_free(t2); - mpi_free(t3); - mpi_free(u); - mpi_free(v); -#elif 0 - /* Extended Euclid's algorithm (See TAOCP Vol II, 4.5.2, Alg X) - * modified according to Michael Penk's solution for Exercise 35 */ - - /* FIXME: we can simplify this in most cases (see Knuth) */ - gcry_mpi_t u, v, u1, u2, u3, v1, v2, v3, t1, t2, t3; - unsigned k; - int sign; - - u = mpi_copy(a); - v = mpi_copy(n); - for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) { - mpi_rshift(u, u, 1); - mpi_rshift(v, v, 1); - } - - - u1 = mpi_alloc_set_ui(1); - u2 = mpi_alloc_set_ui(0); - u3 = mpi_copy(u); - v1 = mpi_copy(v); /* !-- used as const 1 */ - v2 = mpi_alloc( mpi_get_nlimbs(u) ); mpi_sub( v2, u1, u ); - v3 = mpi_copy(v); - if( mpi_test_bit(u, 0) ) { /* u is odd */ - t1 = mpi_alloc_set_ui(0); - t2 = mpi_alloc_set_ui(1); t2->sign = 1; - t3 = mpi_copy(v); t3->sign = !t3->sign; - goto Y4; - } - else { - t1 = mpi_alloc_set_ui(1); - t2 = mpi_alloc_set_ui(0); - t3 = mpi_copy(u); - } - do { - do { - if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */ - mpi_add(t1, t1, v); - mpi_sub(t2, t2, u); - } - mpi_rshift(t1, t1, 1); - mpi_rshift(t2, t2, 1); - mpi_rshift(t3, t3, 1); - Y4: - ; - } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */ - - if( !t3->sign ) { - mpi_set(u1, t1); - mpi_set(u2, t2); - mpi_set(u3, t3); - } - else { - mpi_sub(v1, v, t1); - sign = u->sign; u->sign = !u->sign; - mpi_sub(v2, u, t2); - u->sign = sign; - sign = t3->sign; t3->sign = !t3->sign; - mpi_set(v3, t3); - t3->sign = sign; - } - mpi_sub(t1, u1, v1); - mpi_sub(t2, u2, v2); - mpi_sub(t3, u3, v3); - if( t1->sign ) { - mpi_add(t1, t1, v); - mpi_sub(t2, t2, u); - } - } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */ - /* mpi_lshift( u3, k ); */ - mpi_set(x, u1); - - mpi_free(u1); - mpi_free(u2); - mpi_free(u3); - mpi_free(v1); - mpi_free(v2); - mpi_free(v3); - mpi_free(t1); - mpi_free(t2); - mpi_free(t3); -#else - /* Extended Euclid's algorithm (See TAOCP Vol II, 4.5.2, Alg X) - * modified according to Michael Penk's solution for Exercise 35 - * with further enhancement */ - gcry_mpi_t u, v, u1, u2=NULL, u3, v1, v2=NULL, v3, t1, t2=NULL, t3; - unsigned k; - int sign; - int odd ; - - u = mpi_copy(a); - v = mpi_copy(n); - - for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) { - mpi_rshift(u, u, 1); - mpi_rshift(v, v, 1); - } - odd = mpi_test_bit(v,0); - - u1 = mpi_alloc_set_ui(1); - if( !odd ) - u2 = mpi_alloc_set_ui(0); - u3 = mpi_copy(u); - v1 = mpi_copy(v); - if( !odd ) { - v2 = mpi_alloc( mpi_get_nlimbs(u) ); - mpi_sub( v2, u1, u ); /* U is used as const 1 */ - } - v3 = mpi_copy(v); - if( mpi_test_bit(u, 0) ) { /* u is odd */ - t1 = mpi_alloc_set_ui(0); - if( !odd ) { - t2 = mpi_alloc_set_ui(1); t2->sign = 1; - } - t3 = mpi_copy(v); t3->sign = !t3->sign; - goto Y4; - } - else { - t1 = mpi_alloc_set_ui(1); - if( !odd ) - t2 = mpi_alloc_set_ui(0); - t3 = mpi_copy(u); - } - do { - do { - if( !odd ) { - if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */ - mpi_add(t1, t1, v); - mpi_sub(t2, t2, u); - } - mpi_rshift(t1, t1, 1); - mpi_rshift(t2, t2, 1); - mpi_rshift(t3, t3, 1); - } - else { - if( mpi_test_bit(t1, 0) ) - mpi_add(t1, t1, v); - mpi_rshift(t1, t1, 1); - mpi_rshift(t3, t3, 1); - } - Y4: - ; - } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */ - - if( !t3->sign ) { - mpi_set(u1, t1); - if( !odd ) - mpi_set(u2, t2); - mpi_set(u3, t3); - } - else { - mpi_sub(v1, v, t1); - sign = u->sign; u->sign = !u->sign; - if( !odd ) - mpi_sub(v2, u, t2); - u->sign = sign; - sign = t3->sign; t3->sign = !t3->sign; - mpi_set(v3, t3); - t3->sign = sign; - } - mpi_sub(t1, u1, v1); - if( !odd ) - mpi_sub(t2, u2, v2); - mpi_sub(t3, u3, v3); - if( t1->sign ) { - mpi_add(t1, t1, v); - if( !odd ) - mpi_sub(t2, t2, u); - } - } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */ - /* mpi_lshift( u3, k ); */ - mpi_set(x, u1); - - mpi_free(u1); - mpi_free(v1); - mpi_free(t1); - if( !odd ) { - mpi_free(u2); - mpi_free(v2); - mpi_free(t2); - } - mpi_free(u3); - mpi_free(v3); - mpi_free(t3); - - mpi_free(u); - mpi_free(v); -#endif - return 1; -} diff --git a/grub-core/lib/libgcrypt/mpi/mpi-mod.c b/grub-core/lib/libgcrypt/mpi/mpi-mod.c deleted file mode 100644 index 7ebfe6dca..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpi-mod.c +++ /dev/null @@ -1,184 +0,0 @@ -/* mpi-mod.c - Modular reduction - Copyright (C) 1998, 1999, 2001, 2002, 2003, - 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 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. */ - - -#include -#include -#include - -#include "mpi-internal.h" -#include "longlong.h" -#include "g10lib.h" - - -/* Context used with Barrett reduction. */ -struct barrett_ctx_s -{ - gcry_mpi_t m; /* The modulus - may not be modified. */ - int m_copied; /* If true, M needs to be released. */ - int k; - gcry_mpi_t y; - gcry_mpi_t r1; /* Helper MPI. */ - gcry_mpi_t r2; /* Helper MPI. */ - gcry_mpi_t r3; /* Helper MPI allocated on demand. */ -}; - - - -void -_gcry_mpi_mod (gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor) -{ - _gcry_mpi_fdiv_r (rem, dividend, divisor); - rem->sign = 0; -} - - -/* This function returns a new context for Barrett based operations on - the modulus M. This context needs to be released using - _gcry_mpi_barrett_free. If COPY is true M will be transferred to - the context and the user may change M. If COPY is false, M may not - be changed until gcry_mpi_barrett_free has been called. */ -mpi_barrett_t -_gcry_mpi_barrett_init (gcry_mpi_t m, int copy) -{ - mpi_barrett_t ctx; - gcry_mpi_t tmp; - - mpi_normalize (m); - ctx = gcry_xcalloc (1, sizeof *ctx); - - if (copy) - { - ctx->m = mpi_copy (m); - ctx->m_copied = 1; - } - else - ctx->m = m; - - ctx->k = mpi_get_nlimbs (m); - tmp = mpi_alloc (ctx->k + 1); - - /* Barrett precalculation: y = floor(b^(2k) / m). */ - mpi_set_ui (tmp, 1); - mpi_lshift_limbs (tmp, 2 * ctx->k); - mpi_fdiv_q (tmp, tmp, m); - - ctx->y = tmp; - ctx->r1 = mpi_alloc ( 2 * ctx->k + 1 ); - ctx->r2 = mpi_alloc ( 2 * ctx->k + 1 ); - - return ctx; -} - -void -_gcry_mpi_barrett_free (mpi_barrett_t ctx) -{ - if (ctx) - { - mpi_free (ctx->y); - mpi_free (ctx->r1); - mpi_free (ctx->r2); - if (ctx->r3) - mpi_free (ctx->r3); - if (ctx->m_copied) - mpi_free (ctx->m); - gcry_free (ctx); - } -} - - -/* R = X mod M - - Using Barrett reduction. Before using this function - _gcry_mpi_barrett_init must have been called to do the - precalculations. CTX is the context created by this precalculation - and also conveys M. If the Barret reduction could no be done a - starightforward reduction method is used. - - We assume that these conditions are met: - Input: x =(x_2k-1 ...x_0)_b - m =(m_k-1 ....m_0)_b with m_k-1 != 0 - Output: r = x mod m - */ -void -_gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx) -{ - gcry_mpi_t m = ctx->m; - int k = ctx->k; - gcry_mpi_t y = ctx->y; - gcry_mpi_t r1 = ctx->r1; - gcry_mpi_t r2 = ctx->r2; - - mpi_normalize (x); - if (mpi_get_nlimbs (x) > 2*k ) - { - mpi_mod (r, x, m); - return; - } - - /* 1. q1 = floor( x / b^k-1) - * q2 = q1 * y - * q3 = floor( q2 / b^k+1 ) - * Actually, we don't need qx, we can work direct on r2 - */ - mpi_set ( r2, x ); - mpi_rshift_limbs ( r2, k-1 ); - mpi_mul ( r2, r2, y ); - mpi_rshift_limbs ( r2, k+1 ); - - /* 2. r1 = x mod b^k+1 - * r2 = q3 * m mod b^k+1 - * r = r1 - r2 - * 3. if r < 0 then r = r + b^k+1 - */ - mpi_set ( r1, x ); - if ( r1->nlimbs > k+1 ) /* Quick modulo operation. */ - r1->nlimbs = k+1; - mpi_mul ( r2, r2, m ); - if ( r2->nlimbs > k+1 ) /* Quick modulo operation. */ - r2->nlimbs = k+1; - mpi_sub ( r, r1, r2 ); - - if ( mpi_is_neg( r ) ) - { - if (!ctx->r3) - { - ctx->r3 = mpi_alloc ( k + 2 ); - mpi_set_ui (ctx->r3, 1); - mpi_lshift_limbs (ctx->r3, k + 1 ); - } - mpi_add ( r, r, ctx->r3 ); - } - - /* 4. while r >= m do r = r - m */ - while ( mpi_cmp( r, m ) >= 0 ) - mpi_sub ( r, r, m ); - -} - - -void -_gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, - mpi_barrett_t ctx) -{ - gcry_mpi_mul (w, u, v); - mpi_mod_barrett (w, w, ctx); -} diff --git a/grub-core/lib/libgcrypt/mpi/mpi-mpow.c b/grub-core/lib/libgcrypt/mpi/mpi-mpow.c deleted file mode 100644 index ca5b3f184..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpi-mpow.c +++ /dev/null @@ -1,223 +0,0 @@ -/* mpi-mpow.c - MPI functions - * Copyright (C) 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 - */ - -#include -#include -#include - -#include "mpi-internal.h" -#include "longlong.h" -#include "g10lib.h" - - -/* Barrett is slower than the classical way. It can be tweaked by - * using partial multiplications - */ -/*#define USE_BARRETT*/ - - - -#ifdef USE_BARRETT -static void barrett_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 ); -static gcry_mpi_t init_barrett( gcry_mpi_t m, int *k, gcry_mpi_t *r1, gcry_mpi_t *r2 ); -static int calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 ); -#else -#define barrett_mulm( w, u, v, m, y, k, r1, r2 ) gcry_mpi_mulm( (w), (u), (v), (m) ) -#endif - - -static int -build_index( gcry_mpi_t *exparray, int k, int i, int t ) -{ - int j, bitno; - int idx = 0; - - bitno = t-i; - for(j=k-1; j >= 0; j-- ) { - idx <<= 1; - if( mpi_test_bit( exparray[j], bitno ) ) - idx |= 1; - } - /*log_debug("t=%d i=%d idx=%d\n", t, i, idx );*/ - return idx; -} - -/**************** - * RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M - */ -void -_gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t m) -{ - int k; /* number of elements */ - int t; /* bit size of largest exponent */ - int i, j, idx; - gcry_mpi_t *G; /* table with precomputed values of size 2^k */ - gcry_mpi_t tmp; -#ifdef USE_BARRETT - gcry_mpi_t barrett_y, barrett_r1, barrett_r2; - int barrett_k; -#endif - - for(k=0; basearray[k]; k++ ) - ; - gcry_assert(k); - for(t=0, i=0; (tmp=exparray[i]); i++ ) { - /*log_mpidump("exp: ", tmp );*/ - j = mpi_get_nbits(tmp); - if( j > t ) - t = j; - } - /*log_mpidump("mod: ", m );*/ - gcry_assert (i==k); - gcry_assert (t); - gcry_assert (k < 10); - - G = gcry_xcalloc( (1<= 0 && idx < (1< 3 ? k-3:0; - - mpi_normalize( x ); - if( mpi_get_nlimbs(x) > 2*k ) - return 1; /* can't do it */ - - /* 1. q1 = floor( x / b^k-1) - * q2 = q1 * y - * q3 = floor( q2 / b^k+1 ) - * Actually, we don't need qx, we can work direct on r2 - */ - mpi_set( r2, x ); - mpi_rshift_limbs( r2, k-1 ); - mpi_mul( r2, r2, y ); - mpi_rshift_limbs( r2, k+1 ); - - /* 2. r1 = x mod b^k+1 - * r2 = q3 * m mod b^k+1 - * r = r1 - r2 - * 3. if r < 0 then r = r + b^k+1 - */ - mpi_set( r1, x ); - if( r1->nlimbs > k+1 ) /* quick modulo operation */ - r1->nlimbs = k+1; - mpi_mul( r2, r2, m ); - if( r2->nlimbs > k+1 ) /* quick modulo operation */ - r2->nlimbs = k+1; - mpi_sub( r, r1, r2 ); - - if( mpi_is_neg( r ) ) { - gcry_mpi_t tmp; - - tmp = mpi_alloc( k + 2 ); - mpi_set_ui( tmp, 1 ); - mpi_lshift_limbs( tmp, k+1 ); - mpi_add( r, r, tmp ); - mpi_free(tmp); - } - - /* 4. while r >= m do r = r - m */ - while( mpi_cmp( r, m ) >= 0 ) - mpi_sub( r, r, m ); - - return 0; -} -#endif /* USE_BARRETT */ diff --git a/grub-core/lib/libgcrypt/mpi/mpi-mul.c b/grub-core/lib/libgcrypt/mpi/mpi-mul.c deleted file mode 100644 index 9aefd217a..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpi-mul.c +++ /dev/null @@ -1,212 +0,0 @@ -/* mpi-mul.c - MPI functions - * Copyright (C) 1994, 1996, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#include -#include -#include -#include "mpi-internal.h" - - -void -gcry_mpi_mul_ui( gcry_mpi_t prod, gcry_mpi_t mult, unsigned long small_mult ) -{ - mpi_size_t size, prod_size; - mpi_ptr_t prod_ptr; - mpi_limb_t cy; - int sign; - - size = mult->nlimbs; - sign = mult->sign; - - if( !size || !small_mult ) { - prod->nlimbs = 0; - prod->sign = 0; - return; - } - - prod_size = size + 1; - if( prod->alloced < prod_size ) - mpi_resize( prod, prod_size ); - prod_ptr = prod->d; - - cy = _gcry_mpih_mul_1( prod_ptr, mult->d, size, (mpi_limb_t)small_mult ); - if( cy ) - prod_ptr[size++] = cy; - prod->nlimbs = size; - prod->sign = sign; -} - - -void -gcry_mpi_mul_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt) -{ - mpi_size_t usize, wsize, limb_cnt; - mpi_ptr_t wp; - mpi_limb_t wlimb; - int usign, wsign; - - usize = u->nlimbs; - usign = u->sign; - - if( !usize ) { - w->nlimbs = 0; - w->sign = 0; - return; - } - - limb_cnt = cnt / BITS_PER_MPI_LIMB; - wsize = usize + limb_cnt + 1; - if( w->alloced < wsize ) - mpi_resize(w, wsize ); - wp = w->d; - wsize = usize + limb_cnt; - wsign = usign; - - cnt %= BITS_PER_MPI_LIMB; - if( cnt ) { - wlimb = _gcry_mpih_lshift( wp + limb_cnt, u->d, usize, cnt ); - if( wlimb ) { - wp[wsize] = wlimb; - wsize++; - } - } - else { - MPN_COPY_DECR( wp + limb_cnt, u->d, usize ); - } - - /* Zero all whole limbs at low end. Do it here and not before calling - * mpn_lshift, not to lose for U == W. */ - MPN_ZERO( wp, limb_cnt ); - - w->nlimbs = wsize; - w->sign = wsign; -} - - -void -gcry_mpi_mul( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) -{ - mpi_size_t usize, vsize, wsize; - mpi_ptr_t up, vp, wp; - mpi_limb_t cy; - int usign, vsign, usecure, vsecure, sign_product; - int assign_wp=0; - mpi_ptr_t tmp_limb=NULL; - unsigned int tmp_limb_nlimbs = 0; - - if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */ - usize = v->nlimbs; - usign = v->sign; - usecure = mpi_is_secure(v); - up = v->d; - vsize = u->nlimbs; - vsign = u->sign; - vsecure = mpi_is_secure(u); - vp = u->d; - } - else { - usize = u->nlimbs; - usign = u->sign; - usecure = mpi_is_secure(u); - up = u->d; - vsize = v->nlimbs; - vsign = v->sign; - vsecure = mpi_is_secure(v); - vp = v->d; - } - sign_product = usign ^ vsign; - wp = w->d; - - /* Ensure W has space enough to store the result. */ - wsize = usize + vsize; - if ( !mpi_is_secure (w) && (mpi_is_secure (u) || mpi_is_secure (v)) ) { - /* w is not allocated in secure space but u or v is. To make sure - * that no temporray results are stored in w, we temporary use - * a newly allocated limb space for w */ - wp = mpi_alloc_limb_space( wsize, 1 ); - assign_wp = 2; /* mark it as 2 so that we can later copy it back to - * mormal memory */ - } - else if( w->alloced < wsize ) { - if( wp == up || wp == vp ) { - wp = mpi_alloc_limb_space( wsize, mpi_is_secure(w) ); - assign_wp = 1; - } - else { - mpi_resize(w, wsize ); - wp = w->d; - } - } - else { /* Make U and V not overlap with W. */ - if( wp == up ) { - /* W and U are identical. Allocate temporary space for U. */ - tmp_limb_nlimbs = usize; - up = tmp_limb = mpi_alloc_limb_space( usize, usecure ); - /* Is V identical too? Keep it identical with U. */ - if( wp == vp ) - vp = up; - /* Copy to the temporary space. */ - MPN_COPY( up, wp, usize ); - } - else if( wp == vp ) { - /* W and V are identical. Allocate temporary space for V. */ - tmp_limb_nlimbs = vsize; - vp = tmp_limb = mpi_alloc_limb_space( vsize, vsecure ); - /* Copy to the temporary space. */ - MPN_COPY( vp, wp, vsize ); - } - } - - if( !vsize ) - wsize = 0; - else { - cy = _gcry_mpih_mul( wp, up, usize, vp, vsize ); - wsize -= cy? 0:1; - } - - if( assign_wp ) { - if (assign_wp == 2) { - /* copy the temp wp from secure memory back to normal memory */ - mpi_ptr_t tmp_wp = mpi_alloc_limb_space (wsize, 0); - MPN_COPY (tmp_wp, wp, wsize); - _gcry_mpi_free_limb_space (wp, 0); - wp = tmp_wp; - } - _gcry_mpi_assign_limb_space( w, wp, wsize ); - } - w->nlimbs = wsize; - w->sign = sign_product; - if( tmp_limb ) - _gcry_mpi_free_limb_space (tmp_limb, tmp_limb_nlimbs); -} - - -void -gcry_mpi_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) -{ - gcry_mpi_mul(w, u, v); - _gcry_mpi_fdiv_r( w, w, m ); -} diff --git a/grub-core/lib/libgcrypt/mpi/mpi-pow.c b/grub-core/lib/libgcrypt/mpi/mpi-pow.c deleted file mode 100644 index 58643fed2..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpi-pow.c +++ /dev/null @@ -1,338 +0,0 @@ -/* mpi-pow.c - MPI functions for exponentiation - * Copyright (C) 1994, 1996, 1998, 2000, 2002 - * 2003 Free Software Foundation, Inc. - * 2013 g10 Code GmbH - * - * 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 . - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#include -#include -#include -#include - -#include "mpi-internal.h" -#include "longlong.h" - - -/**************** - * RES = BASE ^ EXPO mod MOD - */ -void -gcry_mpi_powm (gcry_mpi_t res, - gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod) -{ - /* Pointer to the limbs of the arguments, their size and signs. */ - mpi_ptr_t rp, ep, mp, bp; - mpi_size_t esize, msize, bsize, rsize; - int msign, bsign, rsign; - /* Flags telling the secure allocation status of the arguments. */ - int esec, msec, bsec; - /* Size of the result including space for temporary values. */ - mpi_size_t size; - /* Helper. */ - int mod_shift_cnt; - int negative_result; - mpi_ptr_t mp_marker = NULL; - mpi_ptr_t bp_marker = NULL; - mpi_ptr_t ep_marker = NULL; - mpi_ptr_t xp_marker = NULL; - unsigned int mp_nlimbs = 0; - unsigned int bp_nlimbs = 0; - unsigned int ep_nlimbs = 0; - unsigned int xp_nlimbs = 0; - mpi_ptr_t tspace = NULL; - mpi_size_t tsize = 0; - - - esize = expo->nlimbs; - msize = mod->nlimbs; - size = 2 * msize; - msign = mod->sign; - - esec = mpi_is_secure(expo); - msec = mpi_is_secure(mod); - bsec = mpi_is_secure(base); - - rp = res->d; - ep = expo->d; - - if (!msize) - grub_fatal ("mpi division by zero"); - - if (!esize) - { - /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 depending - on if MOD equals 1. */ - res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1; - if (res->nlimbs) - { - RESIZE_IF_NEEDED (res, 1); - rp = res->d; - rp[0] = 1; - } - res->sign = 0; - goto leave; - } - - /* Normalize MOD (i.e. make its most significant bit set) as - required by mpn_divrem. This will make the intermediate values - in the calculation slightly larger, but the correct result is - obtained after a final reduction using the original MOD value. */ - mp_nlimbs = msec? msize:0; - mp = mp_marker = mpi_alloc_limb_space(msize, msec); - count_leading_zeros (mod_shift_cnt, mod->d[msize-1]); - if (mod_shift_cnt) - _gcry_mpih_lshift (mp, mod->d, msize, mod_shift_cnt); - else - MPN_COPY( mp, mod->d, msize ); - - bsize = base->nlimbs; - bsign = base->sign; - if (bsize > msize) - { - /* The base is larger than the module. Reduce it. - - Allocate (BSIZE + 1) with space for remainder and quotient. - (The quotient is (bsize - msize + 1) limbs.) */ - bp_nlimbs = bsec ? (bsize + 1):0; - bp = bp_marker = mpi_alloc_limb_space( bsize + 1, bsec ); - MPN_COPY ( bp, base->d, bsize ); - /* We don't care about the quotient, store it above the - * remainder, at BP + MSIZE. */ - _gcry_mpih_divrem( bp + msize, 0, bp, bsize, mp, msize ); - bsize = msize; - /* Canonicalize the base, since we are going to multiply with it - quite a few times. */ - MPN_NORMALIZE( bp, bsize ); - } - else - bp = base->d; - - if (!bsize) - { - res->nlimbs = 0; - res->sign = 0; - goto leave; - } - - - /* Make BASE, EXPO and MOD not overlap with RES. */ - if ( rp == bp ) - { - /* RES and BASE are identical. Allocate temp. space for BASE. */ - gcry_assert (!bp_marker); - bp_nlimbs = bsec? bsize:0; - bp = bp_marker = mpi_alloc_limb_space( bsize, bsec ); - MPN_COPY(bp, rp, bsize); - } - if ( rp == ep ) - { - /* RES and EXPO are identical. Allocate temp. space for EXPO. */ - ep_nlimbs = esec? esize:0; - ep = ep_marker = mpi_alloc_limb_space( esize, esec ); - MPN_COPY(ep, rp, esize); - } - if ( rp == mp ) - { - /* RES and MOD are identical. Allocate temporary space for MOD.*/ - gcry_assert (!mp_marker); - mp_nlimbs = msec?msize:0; - mp = mp_marker = mpi_alloc_limb_space( msize, msec ); - MPN_COPY(mp, rp, msize); - } - - /* Copy base to the result. */ - if (res->alloced < size) - { - mpi_resize (res, size); - rp = res->d; - } - MPN_COPY ( rp, bp, bsize ); - rsize = bsize; - rsign = bsign; - - /* Main processing. */ - { - mpi_size_t i; - mpi_ptr_t xp; - int c; - mpi_limb_t e; - mpi_limb_t carry_limb; - struct karatsuba_ctx karactx; - - xp_nlimbs = msec? (2 * (msize + 1)):0; - xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec ); - - memset( &karactx, 0, sizeof karactx ); - negative_result = (ep[0] & 1) && base->sign; - - i = esize - 1; - e = ep[i]; - count_leading_zeros (c, e); - e = (e << c) << 1; /* Shift the expo bits to the left, lose msb. */ - c = BITS_PER_MPI_LIMB - 1 - c; - - /* Main loop. - - Make the result be pointed to alternately by XP and RP. This - helps us avoid block copying, which would otherwise be - necessary with the overlap restrictions of - _gcry_mpih_divmod. With 50% probability the result after this - loop will be in the area originally pointed by RP (==RES->d), - and with 50% probability in the area originally pointed to by XP. */ - for (;;) - { - while (c) - { - mpi_ptr_t tp; - mpi_size_t xsize; - - /*mpih_mul_n(xp, rp, rp, rsize);*/ - if ( rsize < KARATSUBA_THRESHOLD ) - _gcry_mpih_sqr_n_basecase( xp, rp, rsize ); - else - { - if ( !tspace ) - { - tsize = 2 * rsize; - tspace = mpi_alloc_limb_space( tsize, 0 ); - } - else if ( tsize < (2*rsize) ) - { - _gcry_mpi_free_limb_space (tspace, 0); - tsize = 2 * rsize; - tspace = mpi_alloc_limb_space (tsize, 0 ); - } - _gcry_mpih_sqr_n (xp, rp, rsize, tspace); - } - - xsize = 2 * rsize; - if ( xsize > msize ) - { - _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize); - xsize = msize; - } - - tp = rp; rp = xp; xp = tp; - rsize = xsize; - - /* To mitigate the Yarom/Falkner flush+reload cache - * side-channel attack on the RSA secret exponent, we do - * the multiplication regardless of the value of the - * high-bit of E. But to avoid this performance penalty - * we do it only if the exponent has been stored in secure - * memory and we can thus assume it is a secret exponent. */ - if (esec || (mpi_limb_signed_t)e < 0) - { - /*mpih_mul( xp, rp, rsize, bp, bsize );*/ - if( bsize < KARATSUBA_THRESHOLD ) - _gcry_mpih_mul ( xp, rp, rsize, bp, bsize ); - else - _gcry_mpih_mul_karatsuba_case (xp, rp, rsize, bp, bsize, - &karactx); - - xsize = rsize + bsize; - if ( xsize > msize ) - { - _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize); - xsize = msize; - } - } - if ( (mpi_limb_signed_t)e < 0 ) - { - tp = rp; rp = xp; xp = tp; - rsize = xsize; - } - e <<= 1; - c--; - } - - i--; - if ( i < 0 ) - break; - e = ep[i]; - c = BITS_PER_MPI_LIMB; - } - - /* We shifted MOD, the modulo reduction argument, left - MOD_SHIFT_CNT steps. Adjust the result by reducing it with the - original MOD. - - Also make sure the result is put in RES->d (where it already - might be, see above). */ - if ( mod_shift_cnt ) - { - carry_limb = _gcry_mpih_lshift( res->d, rp, rsize, mod_shift_cnt); - rp = res->d; - if ( carry_limb ) - { - rp[rsize] = carry_limb; - rsize++; - } - } - else if (res->d != rp) - { - MPN_COPY (res->d, rp, rsize); - rp = res->d; - } - - if ( rsize >= msize ) - { - _gcry_mpih_divrem(rp + msize, 0, rp, rsize, mp, msize); - rsize = msize; - } - - /* Remove any leading zero words from the result. */ - if ( mod_shift_cnt ) - _gcry_mpih_rshift( rp, rp, rsize, mod_shift_cnt); - MPN_NORMALIZE (rp, rsize); - - _gcry_mpih_release_karatsuba_ctx (&karactx ); - } - - /* Fixup for negative results. */ - if ( negative_result && rsize ) - { - if ( mod_shift_cnt ) - _gcry_mpih_rshift( mp, mp, msize, mod_shift_cnt); - _gcry_mpih_sub( rp, mp, msize, rp, rsize); - rsize = msize; - rsign = msign; - MPN_NORMALIZE(rp, rsize); - } - gcry_assert (res->d == rp); - res->nlimbs = rsize; - res->sign = rsign; - - leave: - if (mp_marker) - _gcry_mpi_free_limb_space( mp_marker, mp_nlimbs ); - if (bp_marker) - _gcry_mpi_free_limb_space( bp_marker, bp_nlimbs ); - if (ep_marker) - _gcry_mpi_free_limb_space( ep_marker, ep_nlimbs ); - if (xp_marker) - _gcry_mpi_free_limb_space( xp_marker, xp_nlimbs ); - if (tspace) - _gcry_mpi_free_limb_space( tspace, 0 ); -} diff --git a/grub-core/lib/libgcrypt/mpi/mpi-scan.c b/grub-core/lib/libgcrypt/mpi/mpi-scan.c deleted file mode 100644 index 2473cd9b7..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpi-scan.c +++ /dev/null @@ -1,130 +0,0 @@ -/* mpi-scan.c - MPI functions - * 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 -#include -#include -#include "mpi-internal.h" -#include "longlong.h" - -/**************** - * Scan through an mpi and return byte for byte. a -1 is returned to indicate - * the end of the mpi. Scanning is done from the lsb to the msb, returned - * values are in the range of 0 .. 255. - * - * FIXME: This code is VERY ugly! - */ -int -_gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx ) -{ - int i, j; - unsigned n; - mpi_ptr_t ap; - mpi_limb_t limb; - - ap = a->d; - for(n=0,i=0; i < a->nlimbs; i++ ) { - limb = ap[i]; - for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ ) - if( n == idx ) - return (limb >> j*8) & 0xff; - } - return -1; -} - - -/**************** - * Put a value at position IDX into A. idx counts from lsb to msb - */ -void -_gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int xc ) -{ - int i, j; - unsigned n; - mpi_ptr_t ap; - mpi_limb_t limb, c; - - c = xc & 0xff; - ap = a->d; - for(n=0,i=0; i < a->alloced; i++ ) { - limb = ap[i]; - for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ ) - if( n == idx ) { - #if BYTES_PER_MPI_LIMB == 4 - if( j == 0 ) - limb = (limb & 0xffffff00) | c; - else if( j == 1 ) - limb = (limb & 0xffff00ff) | (c<<8); - else if( j == 2 ) - limb = (limb & 0xff00ffff) | (c<<16); - else - limb = (limb & 0x00ffffff) | (c<<24); - #elif BYTES_PER_MPI_LIMB == 8 - if( j == 0 ) - limb = (limb & 0xffffffffffffff00) | c; - else if( j == 1 ) - limb = (limb & 0xffffffffffff00ff) | (c<<8); - else if( j == 2 ) - limb = (limb & 0xffffffffff00ffff) | (c<<16); - else if( j == 3 ) - limb = (limb & 0xffffffff00ffffff) | (c<<24); - else if( j == 4 ) - limb = (limb & 0xffffff00ffffffff) | (c<<32); - else if( j == 5 ) - limb = (limb & 0xffff00ffffffffff) | (c<<40); - else if( j == 6 ) - limb = (limb & 0xff00ffffffffffff) | (c<<48); - else - limb = (limb & 0x00ffffffffffffff) | (c<<56); - #else - #error please enhance this function, its ugly - i know. - #endif - if( a->nlimbs <= i ) - a->nlimbs = i+1; - ap[i] = limb; - return; - } - } - abort(); /* index out of range */ -} - - -/**************** - * Count the number of zerobits at the low end of A - */ -unsigned -_gcry_mpi_trailing_zeros( gcry_mpi_t a ) -{ - unsigned n, count = 0; - - for(n=0; n < a->nlimbs; n++ ) { - if( a->d[n] ) { - unsigned nn; - mpi_limb_t alimb = a->d[n]; - - count_trailing_zeros( nn, alimb ); - count += nn; - break; - } - count += BITS_PER_MPI_LIMB; - } - return count; - -} diff --git a/grub-core/lib/libgcrypt/mpi/mpicoder.c b/grub-core/lib/libgcrypt/mpi/mpicoder.c deleted file mode 100644 index 6fe389165..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpicoder.c +++ /dev/null @@ -1,753 +0,0 @@ -/* mpicoder.c - Coder for the external representation of MPIs - * Copyright (C) 1998, 1999, 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 . - */ - -#include -#include -#include -#include - -#include "mpi-internal.h" -#include "g10lib.h" - -#define MAX_EXTERN_MPI_BITS 16384 - -/* Helper used to scan PGP style MPIs. Returns NULL on failure. */ -static gcry_mpi_t -mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread, - int secure) -{ - int i, j; - unsigned int nbits, nbytes, nlimbs, nread=0; - mpi_limb_t a; - gcry_mpi_t val = MPI_NULL; - - if ( *ret_nread < 2 ) - goto leave; - nbits = buffer[0] << 8 | buffer[1]; - if ( nbits > MAX_EXTERN_MPI_BITS ) - { -/* log_debug ("mpi too large (%u bits)\n", nbits); */ - goto leave; - } - buffer += 2; - nread = 2; - - nbytes = (nbits+7) / 8; - nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB; - val = secure? mpi_alloc_secure (nlimbs) : mpi_alloc (nlimbs); - i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; - i %= BYTES_PER_MPI_LIMB; - j= val->nlimbs = nlimbs; - val->sign = 0; - for ( ; j > 0; j-- ) - { - a = 0; - for (; i < BYTES_PER_MPI_LIMB; i++ ) - { - if ( ++nread > *ret_nread ) - { -/* log_debug ("mpi larger than buffer"); */ - mpi_free (val); - val = NULL; - goto leave; - } - a <<= 8; - a |= *buffer++; - } - i = 0; - val->d[j-1] = a; - } - - leave: - *ret_nread = nread; - return val; -} - - -/**************** - * Fill the mpi VAL from the hex string in STR. - */ -static int -mpi_fromstr (gcry_mpi_t val, const char *str) -{ - int sign = 0; - int prepend_zero = 0; - int i, j, c, c1, c2; - unsigned int nbits, nbytes, nlimbs; - mpi_limb_t a; - - if ( *str == '-' ) - { - sign = 1; - str++; - } - - /* Skip optional hex prefix. */ - if ( *str == '0' && str[1] == 'x' ) - str += 2; - - nbits = 4 * strlen (str); - if ((nbits % 8)) - prepend_zero = 1; - - nbytes = (nbits+7) / 8; - nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB; - - if ( val->alloced < nlimbs ) - mpi_resize (val, nlimbs); - - i = BYTES_PER_MPI_LIMB - (nbytes % BYTES_PER_MPI_LIMB); - i %= BYTES_PER_MPI_LIMB; - j = val->nlimbs = nlimbs; - val->sign = sign; - for (; j > 0; j--) - { - a = 0; - for (; i < BYTES_PER_MPI_LIMB; i++) - { - if (prepend_zero) - { - c1 = '0'; - prepend_zero = 0; - } - else - c1 = *str++; - - if (!c1) - { - mpi_clear (val); - return 1; /* Error. */ - } - c2 = *str++; - if (!c2) - { - mpi_clear (val); - return 1; /* Error. */ - } - if ( c1 >= '0' && c1 <= '9' ) - c = c1 - '0'; - else if ( c1 >= 'a' && c1 <= 'f' ) - c = c1 - 'a' + 10; - else if ( c1 >= 'A' && c1 <= 'F' ) - c = c1 - 'A' + 10; - else - { - mpi_clear (val); - return 1; /* Error. */ - } - c <<= 4; - if ( c2 >= '0' && c2 <= '9' ) - c |= c2 - '0'; - else if( c2 >= 'a' && c2 <= 'f' ) - c |= c2 - 'a' + 10; - else if( c2 >= 'A' && c2 <= 'F' ) - c |= c2 - 'A' + 10; - else - { - mpi_clear(val); - return 1; /* Error. */ - } - a <<= 8; - a |= c; - } - i = 0; - val->d[j-1] = a; - } - - return 0; /* Okay. */ -} - - -/* Dump the value of A in a format suitable for debugging to - Libgcrypt's logging stream. Note that one leading space but no - trailing space or linefeed will be printed. It is okay to pass - NULL for A. */ -void -gcry_mpi_dump (const gcry_mpi_t a) -{ - int i; - - log_printf (" "); - if (!a) - log_printf ("[MPI_NULL]"); - else - { - if (a->sign) - log_printf ( "-"); -#if BYTES_PER_MPI_LIMB == 2 -# define X "4" -#elif BYTES_PER_MPI_LIMB == 4 -# define X "8" -#elif BYTES_PER_MPI_LIMB == 8 -# define X "16" -#elif BYTES_PER_MPI_LIMB == 16 -# define X "32" -#else -# error please define the format here -#endif - for (i=a->nlimbs; i > 0 ; i-- ) - { - log_printf (i != a->nlimbs? "%0" X "lX":"%lX", (ulong)a->d[i-1]); - } -#undef X - if (!a->nlimbs) - log_printf ("0"); - } -} - -/* Convience function used internally. */ -void -_gcry_log_mpidump (const char *text, gcry_mpi_t a) -{ - log_printf ("%s:", text); - gcry_mpi_dump (a); - log_printf ("\n"); -} - - -/* Return an allocated buffer with the MPI (msb first). NBYTES - receives the length of this buffer. Caller must free the return - string. This function returns an allocated buffer with NBYTES set - to zero if the value of A is zero. If sign is not NULL, it will be - set to the sign of the A. On error NULL is returned and ERRNO set - appropriately. */ -static unsigned char * -do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure) -{ - unsigned char *p, *buffer; - mpi_limb_t alimb; - int i; - size_t n; - - if (sign) - *sign = a->sign; - - *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB; - n = *nbytes? *nbytes:1; /* Allocate at least one byte. */ - p = buffer = (force_secure || mpi_is_secure(a))? gcry_malloc_secure (n) - : gcry_malloc (n); - if (!buffer) - return NULL; - - for (i=a->nlimbs-1; i >= 0; i--) - { - alimb = a->d[i]; -#if BYTES_PER_MPI_LIMB == 4 - *p++ = alimb >> 24; - *p++ = alimb >> 16; - *p++ = alimb >> 8; - *p++ = alimb ; -#elif BYTES_PER_MPI_LIMB == 8 - *p++ = alimb >> 56; - *p++ = alimb >> 48; - *p++ = alimb >> 40; - *p++ = alimb >> 32; - *p++ = alimb >> 24; - *p++ = alimb >> 16; - *p++ = alimb >> 8; - *p++ = alimb ; -#else -# error please implement for this limb size. -#endif - } - - /* This is sub-optimal but we need to do the shift operation because - the caller has to free the returned buffer. */ - for (p=buffer; *nbytes && !*p; p++, --*nbytes) - ; - if (p != buffer) - memmove (buffer,p, *nbytes); - return buffer; -} - - -byte * -_gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign) -{ - return do_get_buffer (a, nbytes, sign, 0); -} - -byte * -_gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned *nbytes, int *sign) -{ - return do_get_buffer (a, nbytes, sign, 1); -} - - -/* - * Use the NBYTES at BUFFER_ARG to update A. Set the sign of a to - * SIGN. - */ -void -_gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg, - unsigned int nbytes, int sign) -{ - const unsigned char *buffer = (const unsigned char*)buffer_arg; - const unsigned char *p; - mpi_limb_t alimb; - int nlimbs; - int i; - - nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB; - RESIZE_IF_NEEDED(a, nlimbs); - a->sign = sign; - - for (i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; ) - { -#if BYTES_PER_MPI_LIMB == 4 - alimb = *p-- ; - alimb |= *p-- << 8 ; - alimb |= *p-- << 16 ; - alimb |= *p-- << 24 ; -#elif BYTES_PER_MPI_LIMB == 8 - alimb = (mpi_limb_t)*p-- ; - alimb |= (mpi_limb_t)*p-- << 8 ; - alimb |= (mpi_limb_t)*p-- << 16 ; - alimb |= (mpi_limb_t)*p-- << 24 ; - alimb |= (mpi_limb_t)*p-- << 32 ; - alimb |= (mpi_limb_t)*p-- << 40 ; - alimb |= (mpi_limb_t)*p-- << 48 ; - alimb |= (mpi_limb_t)*p-- << 56 ; -#else -# error please implement for this limb size. -#endif - a->d[i++] = alimb; - } - if ( p >= buffer ) - { -#if BYTES_PER_MPI_LIMB == 4 - alimb = *p--; - if (p >= buffer) - alimb |= *p-- << 8; - if (p >= buffer) - alimb |= *p-- << 16; - if (p >= buffer) - alimb |= *p-- << 24; -#elif BYTES_PER_MPI_LIMB == 8 - alimb = (mpi_limb_t)*p--; - if (p >= buffer) - alimb |= (mpi_limb_t)*p-- << 8; - if (p >= buffer) - alimb |= (mpi_limb_t)*p-- << 16; - if (p >= buffer) - alimb |= (mpi_limb_t)*p-- << 24; - if (p >= buffer) - alimb |= (mpi_limb_t)*p-- << 32; - if (p >= buffer) - alimb |= (mpi_limb_t)*p-- << 40; - if (p >= buffer) - alimb |= (mpi_limb_t)*p-- << 48; - if (p >= buffer) - alimb |= (mpi_limb_t)*p-- << 56; -#else -# error please implement for this limb size. -#endif - a->d[i++] = alimb; - } - a->nlimbs = i; - gcry_assert (i == nlimbs); -} - - -/* Convert the external representation of an integer stored in BUFFER - with a length of BUFLEN into a newly create MPI returned in - RET_MPI. If NBYTES is not NULL, it will receive the number of - bytes actually scanned after a successful operation. */ -gcry_error_t -gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format, - const void *buffer_arg, size_t buflen, size_t *nscanned) -{ - const unsigned char *buffer = (const unsigned char*)buffer_arg; - struct gcry_mpi *a = NULL; - unsigned int len; - int secure = (buffer && gcry_is_secure (buffer)); - - if (!buffer) - return gcry_error (GPG_ERR_INV_ARG); - - if (format == GCRYMPI_FMT_SSH) - len = 0; - else - len = buflen; - - if (format == GCRYMPI_FMT_STD) - { - const unsigned char *s = buffer; - - a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1) - /BYTES_PER_MPI_LIMB) - : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB); - if (len) - { - a->sign = !!(*s & 0x80); - if (a->sign) - { - /* FIXME: we have to convert from 2compl to magnitude format */ - mpi_free (a); - return gcry_error (GPG_ERR_INTERNAL); - } - else - _gcry_mpi_set_buffer (a, s, len, 0); - } - if (ret_mpi) - { - mpi_normalize ( a ); - *ret_mpi = a; - } - else - mpi_free(a); - return 0; - } - else if (format == GCRYMPI_FMT_USG) - { - a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1) - /BYTES_PER_MPI_LIMB) - : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB); - - if (len) - _gcry_mpi_set_buffer (a, buffer, len, 0); - if (ret_mpi) - { - mpi_normalize ( a ); - *ret_mpi = a; - } - else - mpi_free(a); - return 0; - } - else if (format == GCRYMPI_FMT_PGP) - { - a = mpi_read_from_buffer (buffer, &len, secure); - if (nscanned) - *nscanned = len; - if (ret_mpi && a) - { - mpi_normalize (a); - *ret_mpi = a; - } - else if (a) - { - mpi_free(a); - a = NULL; - } - return a? 0 : gcry_error (GPG_ERR_INV_OBJ); - } - else if (format == GCRYMPI_FMT_SSH) - { - const unsigned char *s = buffer; - size_t n; - - /* This test is not strictly necessary and an assert (!len) - would be sufficient. We keep this test in case we later - allow the BUFLEN argument to act as a sanitiy check. Same - below. */ - if (len && len < 4) - return gcry_error (GPG_ERR_TOO_SHORT); - - n = ((size_t)s[0] << 24 | (size_t)s[1] << 16 | (size_t)s[2] << 8 | (size_t)s[3]); - s += 4; - if (len) - len -= 4; - if (len && n > len) - return gcry_error (GPG_ERR_TOO_LARGE); - - a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1) - /BYTES_PER_MPI_LIMB) - : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB); - if (n) - { - a->sign = !!(*s & 0x80); - if (a->sign) - { - /* FIXME: we have to convert from 2compl to magnitude format */ - mpi_free(a); - return gcry_error (GPG_ERR_INTERNAL); - } - else - _gcry_mpi_set_buffer( a, s, n, 0 ); - } - if (nscanned) - *nscanned = n+4; - if (ret_mpi) - { - mpi_normalize ( a ); - *ret_mpi = a; - } - else - mpi_free(a); - return 0; - } - else if (format == GCRYMPI_FMT_HEX) - { - /* We can only handle C strings for now. */ - if (buflen) - return gcry_error (GPG_ERR_INV_ARG); - - a = secure? mpi_alloc_secure (0) : mpi_alloc(0); - if (mpi_fromstr (a, (const char *)buffer)) - { - mpi_free (a); - return gcry_error (GPG_ERR_INV_OBJ); - } - if (ret_mpi) - { - mpi_normalize ( a ); - *ret_mpi = a; - } - else - mpi_free(a); - return 0; - } - else - return gcry_error (GPG_ERR_INV_ARG); -} - - -/* Convert the big integer A into the external representation - described by FORMAT and store it in the provided BUFFER which has - been allocated by the user with a size of BUFLEN bytes. NWRITTEN - receives the actual length of the external representation unless it - has been passed as NULL. BUFFER may be NULL to query the required - length. */ -gcry_error_t -gcry_mpi_print (enum gcry_mpi_format format, - unsigned char *buffer, size_t buflen, - size_t *nwritten, struct gcry_mpi *a) -{ - unsigned int nbits = mpi_get_nbits (a); - size_t len; - size_t dummy_nwritten; - - if (!nwritten) - nwritten = &dummy_nwritten; - - len = buflen; - *nwritten = 0; - if (format == GCRYMPI_FMT_STD) - { - unsigned char *tmp; - int extra = 0; - unsigned int n; - - if (a->sign) - return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */ - - tmp = _gcry_mpi_get_buffer (a, &n, NULL); - if (!tmp) - return gpg_error_from_syserror (); - if (n && (*tmp & 0x80)) - { - n++; - extra=1; - } - - if (buffer && n > len) - { - /* The provided buffer is too short. */ - gcry_free (tmp); - return gcry_error (GPG_ERR_TOO_SHORT); - } - if (buffer) - { - unsigned char *s = buffer; - - if (extra) - *s++ = 0; - memcpy (s, tmp, n-extra); - } - gcry_free(tmp); - *nwritten = n; - return 0; - } - else if (format == GCRYMPI_FMT_USG) - { - unsigned int n = (nbits + 7)/8; - - /* Note: We ignore the sign for this format. */ - /* FIXME: for performance reasons we should put this into - mpi_aprint because we can then use the buffer directly. */ - if (buffer && n > len) - return gcry_error (GPG_ERR_TOO_SHORT); - if (buffer) - { - unsigned char *tmp; - - tmp = _gcry_mpi_get_buffer (a, &n, NULL); - if (!tmp) - return gpg_error_from_syserror (); - memcpy (buffer, tmp, n); - gcry_free (tmp); - } - *nwritten = n; - return 0; - } - else if (format == GCRYMPI_FMT_PGP) - { - unsigned int n = (nbits + 7)/8; - - /* The PGP format can only handle unsigned integers. */ - if( a->sign ) - return gcry_error (GPG_ERR_INV_ARG); - - if (buffer && n+2 > len) - return gcry_error (GPG_ERR_TOO_SHORT); - - if (buffer) - { - unsigned char *tmp; - unsigned char *s = buffer; - - s[0] = nbits >> 8; - s[1] = nbits; - - tmp = _gcry_mpi_get_buffer (a, &n, NULL); - if (!tmp) - return gpg_error_from_syserror (); - memcpy (s+2, tmp, n); - gcry_free (tmp); - } - *nwritten = n+2; - return 0; - } - else if (format == GCRYMPI_FMT_SSH) - { - unsigned char *tmp; - int extra = 0; - unsigned int n; - - if (a->sign) - return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */ - - tmp = _gcry_mpi_get_buffer (a, &n, NULL); - if (!tmp) - return gpg_error_from_syserror (); - if (n && (*tmp & 0x80)) - { - n++; - extra=1; - } - - if (buffer && n+4 > len) - { - gcry_free(tmp); - return gcry_error (GPG_ERR_TOO_SHORT); - } - - if (buffer) - { - unsigned char *s = buffer; - - *s++ = n >> 24; - *s++ = n >> 16; - *s++ = n >> 8; - *s++ = n; - if (extra) - *s++ = 0; - - memcpy (s, tmp, n-extra); - } - gcry_free (tmp); - *nwritten = 4+n; - return 0; - } - else if (format == GCRYMPI_FMT_HEX) - { - unsigned char *tmp; - int i; - int extra = 0; - unsigned int n = 0; - - tmp = _gcry_mpi_get_buffer (a, &n, NULL); - if (!tmp) - return gpg_error_from_syserror (); - if (!n || (*tmp & 0x80)) - extra = 2; - - if (buffer && 2*n + extra + !!a->sign + 1 > len) - { - gcry_free(tmp); - return gcry_error (GPG_ERR_TOO_SHORT); - } - if (buffer) - { - unsigned char *s = buffer; - - if (a->sign) - *s++ = '-'; - if (extra) - { - *s++ = '0'; - *s++ = '0'; - } - - for (i=0; i < n; i++) - { - unsigned int c = tmp[i]; - - *s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ; - c &= 15; - *s++ = c < 10? '0'+c : 'A'+c-10 ; - } - *s++ = 0; - *nwritten = s - buffer; - } - else - { - *nwritten = 2*n + extra + !!a->sign + 1; - } - gcry_free (tmp); - return 0; - } - else - return gcry_error (GPG_ERR_INV_ARG); -} - - -/* - * Like gcry_mpi_print but this function allocates the buffer itself. - * The caller has to supply the address of a pointer. NWRITTEN may be - * NULL. - */ -gcry_error_t -gcry_mpi_aprint (enum gcry_mpi_format format, - unsigned char **buffer, size_t *nwritten, - struct gcry_mpi *a) -{ - size_t n; - gcry_error_t rc; - - *buffer = NULL; - rc = gcry_mpi_print (format, NULL, 0, &n, a); - if (rc) - return rc; - - *buffer = mpi_is_secure(a) ? gcry_malloc_secure (n) : gcry_malloc (n); - if (!*buffer) - return gpg_error_from_syserror (); - rc = gcry_mpi_print( format, *buffer, n, &n, a ); - if (rc) - { - gcry_free(*buffer); - *buffer = NULL; - } - else if (nwritten) - *nwritten = n; - return rc; -} diff --git a/grub-core/lib/libgcrypt/mpi/mpih-div.c b/grub-core/lib/libgcrypt/mpi/mpih-div.c deleted file mode 100644 index 0b458fffd..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpih-div.c +++ /dev/null @@ -1,534 +0,0 @@ -/* mpih-div.c - MPI helper functions - * Copyright (C) 1994, 1996, 1998, 2000, - * 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#include -#include -#include -#include "mpi-internal.h" -#include "longlong.h" - -#ifndef UMUL_TIME -#define UMUL_TIME 1 -#endif -#ifndef UDIV_TIME -#define UDIV_TIME UMUL_TIME -#endif - -/* FIXME: We should be using invert_limb (or invert_normalized_limb) - * here (not udiv_qrnnd). - */ - -mpi_limb_t -_gcry_mpih_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size, - mpi_limb_t divisor_limb) -{ - mpi_size_t i; - mpi_limb_t n1, n0, r; - int dummy; - - /* Botch: Should this be handled at all? Rely on callers? */ - if( !dividend_size ) - return 0; - - /* If multiplication is much faster than division, and the - * dividend is large, pre-invert the divisor, and use - * only multiplications in the inner loop. - * - * This test should be read: - * Does it ever help to use udiv_qrnnd_preinv? - * && Does what we save compensate for the inversion overhead? - */ - if( UDIV_TIME > (2 * UMUL_TIME + 6) - && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) { - int normalization_steps; - - count_leading_zeros( normalization_steps, divisor_limb ); - if( normalization_steps ) { - mpi_limb_t divisor_limb_inverted; - - divisor_limb <<= normalization_steps; - - /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The - * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the - * most significant bit (with weight 2**N) implicit. - * - * Special case for DIVISOR_LIMB == 100...000. - */ - if( !(divisor_limb << 1) ) - divisor_limb_inverted = ~(mpi_limb_t)0; - else - udiv_qrnnd(divisor_limb_inverted, dummy, - -divisor_limb, 0, divisor_limb); - - n1 = dividend_ptr[dividend_size - 1]; - r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps); - - /* Possible optimization: - * if (r == 0 - * && divisor_limb > ((n1 << normalization_steps) - * | (dividend_ptr[dividend_size - 2] >> ...))) - * ...one division less... - */ - for( i = dividend_size - 2; i >= 0; i--) { - n0 = dividend_ptr[i]; - UDIV_QRNND_PREINV(dummy, r, r, - ((n1 << normalization_steps) - | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))), - divisor_limb, divisor_limb_inverted); - n1 = n0; - } - UDIV_QRNND_PREINV(dummy, r, r, - n1 << normalization_steps, - divisor_limb, divisor_limb_inverted); - return r >> normalization_steps; - } - else { - mpi_limb_t divisor_limb_inverted; - - /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The - * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the - * most significant bit (with weight 2**N) implicit. - * - * Special case for DIVISOR_LIMB == 100...000. - */ - if( !(divisor_limb << 1) ) - divisor_limb_inverted = ~(mpi_limb_t)0; - else - udiv_qrnnd(divisor_limb_inverted, dummy, - -divisor_limb, 0, divisor_limb); - - i = dividend_size - 1; - r = dividend_ptr[i]; - - if( r >= divisor_limb ) - r = 0; - else - i--; - - for( ; i >= 0; i--) { - n0 = dividend_ptr[i]; - UDIV_QRNND_PREINV(dummy, r, r, - n0, divisor_limb, divisor_limb_inverted); - } - return r; - } - } - else { - if( UDIV_NEEDS_NORMALIZATION ) { - int normalization_steps; - - count_leading_zeros(normalization_steps, divisor_limb); - if( normalization_steps ) { - divisor_limb <<= normalization_steps; - - n1 = dividend_ptr[dividend_size - 1]; - r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps); - - /* Possible optimization: - * if (r == 0 - * && divisor_limb > ((n1 << normalization_steps) - * | (dividend_ptr[dividend_size - 2] >> ...))) - * ...one division less... - */ - for(i = dividend_size - 2; i >= 0; i--) { - n0 = dividend_ptr[i]; - udiv_qrnnd (dummy, r, r, - ((n1 << normalization_steps) - | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))), - divisor_limb); - n1 = n0; - } - udiv_qrnnd (dummy, r, r, - n1 << normalization_steps, - divisor_limb); - return r >> normalization_steps; - } - } - /* No normalization needed, either because udiv_qrnnd doesn't require - * it, or because DIVISOR_LIMB is already normalized. */ - i = dividend_size - 1; - r = dividend_ptr[i]; - - if(r >= divisor_limb) - r = 0; - else - i--; - - for(; i >= 0; i--) { - n0 = dividend_ptr[i]; - udiv_qrnnd (dummy, r, r, n0, divisor_limb); - } - return r; - } -} - -/* Divide num (NP/NSIZE) by den (DP/DSIZE) and write - * the NSIZE-DSIZE least significant quotient limbs at QP - * and the DSIZE long remainder at NP. If QEXTRA_LIMBS is - * non-zero, generate that many fraction bits and append them after the - * other quotient limbs. - * Return the most significant limb of the quotient, this is always 0 or 1. - * - * Preconditions: - * 0. NSIZE >= DSIZE. - * 1. The most significant bit of the divisor must be set. - * 2. QP must either not overlap with the input operands at all, or - * QP + DSIZE >= NP must hold true. (This means that it's - * possible to put the quotient in the high part of NUM, right after the - * remainder in NUM. - * 3. NSIZE >= DSIZE, even if QEXTRA_LIMBS is non-zero. - */ - -mpi_limb_t -_gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs, - mpi_ptr_t np, mpi_size_t nsize, - mpi_ptr_t dp, mpi_size_t dsize) -{ - mpi_limb_t most_significant_q_limb = 0; - - switch(dsize) { - case 0: - /* We are asked to divide by zero, so go ahead and do it! (To make - the compiler not remove this statement, return the value.) */ - grub_fatal ("mpi division by zero"); - return 0; - - case 1: - { - mpi_size_t i; - mpi_limb_t n1; - mpi_limb_t d; - - d = dp[0]; - n1 = np[nsize - 1]; - - if( n1 >= d ) { - n1 -= d; - most_significant_q_limb = 1; - } - - qp += qextra_limbs; - for( i = nsize - 2; i >= 0; i--) - udiv_qrnnd( qp[i], n1, n1, np[i], d ); - qp -= qextra_limbs; - - for( i = qextra_limbs - 1; i >= 0; i-- ) - udiv_qrnnd (qp[i], n1, n1, 0, d); - - np[0] = n1; - } - break; - - case 2: - { - mpi_size_t i; - mpi_limb_t n1, n0, n2; - mpi_limb_t d1, d0; - - np += nsize - 2; - d1 = dp[1]; - d0 = dp[0]; - n1 = np[1]; - n0 = np[0]; - - if( n1 >= d1 && (n1 > d1 || n0 >= d0) ) { - sub_ddmmss (n1, n0, n1, n0, d1, d0); - most_significant_q_limb = 1; - } - - for( i = qextra_limbs + nsize - 2 - 1; i >= 0; i-- ) { - mpi_limb_t q; - mpi_limb_t r; - - if( i >= qextra_limbs ) - np--; - else - np[0] = 0; - - if( n1 == d1 ) { - /* Q should be either 111..111 or 111..110. Need special - * treatment of this rare case as normal division would - * give overflow. */ - q = ~(mpi_limb_t)0; - - r = n0 + d1; - if( r < d1 ) { /* Carry in the addition? */ - add_ssaaaa( n1, n0, r - d0, np[0], 0, d0 ); - qp[i] = q; - continue; - } - n1 = d0 - (d0 != 0?1:0); - n0 = -d0; - } - else { - udiv_qrnnd (q, r, n1, n0, d1); - umul_ppmm (n1, n0, d0, q); - } - - n2 = np[0]; - q_test: - if( n1 > r || (n1 == r && n0 > n2) ) { - /* The estimated Q was too large. */ - q--; - sub_ddmmss (n1, n0, n1, n0, 0, d0); - r += d1; - if( r >= d1 ) /* If not carry, test Q again. */ - goto q_test; - } - - qp[i] = q; - sub_ddmmss (n1, n0, r, n2, n1, n0); - } - np[1] = n1; - np[0] = n0; - } - break; - - default: - { - mpi_size_t i; - mpi_limb_t dX, d1, n0; - - np += nsize - dsize; - dX = dp[dsize - 1]; - d1 = dp[dsize - 2]; - n0 = np[dsize - 1]; - - if( n0 >= dX ) { - if(n0 > dX || _gcry_mpih_cmp(np, dp, dsize - 1) >= 0 ) { - _gcry_mpih_sub_n(np, np, dp, dsize); - n0 = np[dsize - 1]; - most_significant_q_limb = 1; - } - } - - for( i = qextra_limbs + nsize - dsize - 1; i >= 0; i--) { - mpi_limb_t q; - mpi_limb_t n1, n2; - mpi_limb_t cy_limb; - - if( i >= qextra_limbs ) { - np--; - n2 = np[dsize]; - } - else { - n2 = np[dsize - 1]; - MPN_COPY_DECR (np + 1, np, dsize - 1); - np[0] = 0; - } - - if( n0 == dX ) { - /* This might over-estimate q, but it's probably not worth - * the extra code here to find out. */ - q = ~(mpi_limb_t)0; - } - else { - mpi_limb_t r; - - udiv_qrnnd(q, r, n0, np[dsize - 1], dX); - umul_ppmm(n1, n0, d1, q); - - while( n1 > r || (n1 == r && n0 > np[dsize - 2])) { - q--; - r += dX; - if( r < dX ) /* I.e. "carry in previous addition?" */ - break; - n1 -= n0 < d1; - n0 -= d1; - } - } - - /* Possible optimization: We already have (q * n0) and (1 * n1) - * after the calculation of q. Taking advantage of that, we - * could make this loop make two iterations less. */ - cy_limb = _gcry_mpih_submul_1(np, dp, dsize, q); - - if( n2 != cy_limb ) { - _gcry_mpih_add_n(np, np, dp, dsize); - q--; - } - - qp[i] = q; - n0 = np[dsize - 1]; - } - } - } - - return most_significant_q_limb; -} - - -/**************** - * Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB. - * Write DIVIDEND_SIZE limbs of quotient at QUOT_PTR. - * Return the single-limb remainder. - * There are no constraints on the value of the divisor. - * - * QUOT_PTR and DIVIDEND_PTR might point to the same limb. - */ - -mpi_limb_t -_gcry_mpih_divmod_1( mpi_ptr_t quot_ptr, - mpi_ptr_t dividend_ptr, mpi_size_t dividend_size, - mpi_limb_t divisor_limb) -{ - mpi_size_t i; - mpi_limb_t n1, n0, r; - int dummy; - - if( !dividend_size ) - return 0; - - /* If multiplication is much faster than division, and the - * dividend is large, pre-invert the divisor, and use - * only multiplications in the inner loop. - * - * This test should be read: - * Does it ever help to use udiv_qrnnd_preinv? - * && Does what we save compensate for the inversion overhead? - */ - if( UDIV_TIME > (2 * UMUL_TIME + 6) - && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) { - int normalization_steps; - - count_leading_zeros( normalization_steps, divisor_limb ); - if( normalization_steps ) { - mpi_limb_t divisor_limb_inverted; - - divisor_limb <<= normalization_steps; - - /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The - * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the - * most significant bit (with weight 2**N) implicit. - */ - /* Special case for DIVISOR_LIMB == 100...000. */ - if( !(divisor_limb << 1) ) - divisor_limb_inverted = ~(mpi_limb_t)0; - else - udiv_qrnnd(divisor_limb_inverted, dummy, - -divisor_limb, 0, divisor_limb); - - n1 = dividend_ptr[dividend_size - 1]; - r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps); - - /* Possible optimization: - * if (r == 0 - * && divisor_limb > ((n1 << normalization_steps) - * | (dividend_ptr[dividend_size - 2] >> ...))) - * ...one division less... - */ - for( i = dividend_size - 2; i >= 0; i--) { - n0 = dividend_ptr[i]; - UDIV_QRNND_PREINV( quot_ptr[i + 1], r, r, - ((n1 << normalization_steps) - | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))), - divisor_limb, divisor_limb_inverted); - n1 = n0; - } - UDIV_QRNND_PREINV( quot_ptr[0], r, r, - n1 << normalization_steps, - divisor_limb, divisor_limb_inverted); - return r >> normalization_steps; - } - else { - mpi_limb_t divisor_limb_inverted; - - /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The - * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the - * most significant bit (with weight 2**N) implicit. - */ - /* Special case for DIVISOR_LIMB == 100...000. */ - if( !(divisor_limb << 1) ) - divisor_limb_inverted = ~(mpi_limb_t) 0; - else - udiv_qrnnd(divisor_limb_inverted, dummy, - -divisor_limb, 0, divisor_limb); - - i = dividend_size - 1; - r = dividend_ptr[i]; - - if( r >= divisor_limb ) - r = 0; - else - quot_ptr[i--] = 0; - - for( ; i >= 0; i-- ) { - n0 = dividend_ptr[i]; - UDIV_QRNND_PREINV( quot_ptr[i], r, r, - n0, divisor_limb, divisor_limb_inverted); - } - return r; - } - } - else { - if(UDIV_NEEDS_NORMALIZATION) { - int normalization_steps; - - count_leading_zeros (normalization_steps, divisor_limb); - if( normalization_steps ) { - divisor_limb <<= normalization_steps; - - n1 = dividend_ptr[dividend_size - 1]; - r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps); - - /* Possible optimization: - * if (r == 0 - * && divisor_limb > ((n1 << normalization_steps) - * | (dividend_ptr[dividend_size - 2] >> ...))) - * ...one division less... - */ - for( i = dividend_size - 2; i >= 0; i--) { - n0 = dividend_ptr[i]; - udiv_qrnnd (quot_ptr[i + 1], r, r, - ((n1 << normalization_steps) - | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))), - divisor_limb); - n1 = n0; - } - udiv_qrnnd (quot_ptr[0], r, r, - n1 << normalization_steps, - divisor_limb); - return r >> normalization_steps; - } - } - /* No normalization needed, either because udiv_qrnnd doesn't require - * it, or because DIVISOR_LIMB is already normalized. */ - i = dividend_size - 1; - r = dividend_ptr[i]; - - if(r >= divisor_limb) - r = 0; - else - quot_ptr[i--] = 0; - - for(; i >= 0; i--) { - n0 = dividend_ptr[i]; - udiv_qrnnd( quot_ptr[i], r, r, n0, divisor_limb ); - } - return r; - } -} diff --git a/grub-core/lib/libgcrypt/mpi/mpih-mul.c b/grub-core/lib/libgcrypt/mpi/mpih-mul.c deleted file mode 100644 index b8e056173..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpih-mul.c +++ /dev/null @@ -1,528 +0,0 @@ -/* mpih-mul.c - MPI helper functions - * Copyright (C) 1994, 1996, 1998, 1999, 2000, - * 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#include -#include -#include -#include -#include "mpi-internal.h" -#include "longlong.h" -#include "g10lib.h" - -#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \ - do { \ - if( (size) < KARATSUBA_THRESHOLD ) \ - mul_n_basecase (prodp, up, vp, size); \ - else \ - mul_n (prodp, up, vp, size, tspace); \ - } while (0); - -#define MPN_SQR_N_RECURSE(prodp, up, size, tspace) \ - do { \ - if ((size) < KARATSUBA_THRESHOLD) \ - _gcry_mpih_sqr_n_basecase (prodp, up, size); \ - else \ - _gcry_mpih_sqr_n (prodp, up, size, tspace); \ - } while (0); - - - - -/* Multiply the natural numbers u (pointed to by UP) and v (pointed to by VP), - * both with SIZE limbs, and store the result at PRODP. 2 * SIZE limbs are - * always stored. Return the most significant limb. - * - * Argument constraints: - * 1. PRODP != UP and PRODP != VP, i.e. the destination - * must be distinct from the multiplier and the multiplicand. - * - * - * Handle simple cases with traditional multiplication. - * - * This is the most critical code of multiplication. All multiplies rely - * on this, both small and huge. Small ones arrive here immediately. Huge - * ones arrive here as this is the base case for Karatsuba's recursive - * algorithm below. - */ - -static mpi_limb_t -mul_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, - mpi_ptr_t vp, mpi_size_t size) -{ - mpi_size_t i; - mpi_limb_t cy; - mpi_limb_t v_limb; - - /* Multiply by the first limb in V separately, as the result can be - * stored (not added) to PROD. We also avoid a loop for zeroing. */ - v_limb = vp[0]; - if( v_limb <= 1 ) { - if( v_limb == 1 ) - MPN_COPY( prodp, up, size ); - else - MPN_ZERO( prodp, size ); - cy = 0; - } - else - cy = _gcry_mpih_mul_1( prodp, up, size, v_limb ); - - prodp[size] = cy; - prodp++; - - /* For each iteration in the outer loop, multiply one limb from - * U with one limb from V, and add it to PROD. */ - for( i = 1; i < size; i++ ) { - v_limb = vp[i]; - if( v_limb <= 1 ) { - cy = 0; - if( v_limb == 1 ) - cy = _gcry_mpih_add_n(prodp, prodp, up, size); - } - else - cy = _gcry_mpih_addmul_1(prodp, up, size, v_limb); - - prodp[size] = cy; - prodp++; - } - - return cy; -} - - -static void -mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp, - mpi_size_t size, mpi_ptr_t tspace ) -{ - if( size & 1 ) { - /* The size is odd, and the code below doesn't handle that. - * Multiply the least significant (size - 1) limbs with a recursive - * call, and handle the most significant limb of S1 and S2 - * separately. - * A slightly faster way to do this would be to make the Karatsuba - * code below behave as if the size were even, and let it check for - * odd size in the end. I.e., in essence move this code to the end. - * Doing so would save us a recursive call, and potentially make the - * stack grow a lot less. - */ - mpi_size_t esize = size - 1; /* even size */ - mpi_limb_t cy_limb; - - MPN_MUL_N_RECURSE( prodp, up, vp, esize, tspace ); - cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, esize, vp[esize] ); - prodp[esize + esize] = cy_limb; - cy_limb = _gcry_mpih_addmul_1( prodp + esize, vp, size, up[esize] ); - prodp[esize + size] = cy_limb; - } - else { - /* Anatolij Alekseevich Karatsuba's divide-and-conquer algorithm. - * - * Split U in two pieces, U1 and U0, such that - * U = U0 + U1*(B**n), - * and V in V1 and V0, such that - * V = V0 + V1*(B**n). - * - * UV is then computed recursively using the identity - * - * 2n n n n - * UV = (B + B )U V + B (U -U )(V -V ) + (B + 1)U V - * 1 1 1 0 0 1 0 0 - * - * Where B = 2**BITS_PER_MP_LIMB. - */ - mpi_size_t hsize = size >> 1; - mpi_limb_t cy; - int negflg; - - /* Product H. ________________ ________________ - * |_____U1 x V1____||____U0 x V0_____| - * Put result in upper part of PROD and pass low part of TSPACE - * as new TSPACE. - */ - MPN_MUL_N_RECURSE(prodp + size, up + hsize, vp + hsize, hsize, tspace); - - /* Product M. ________________ - * |_(U1-U0)(V0-V1)_| - */ - if( _gcry_mpih_cmp(up + hsize, up, hsize) >= 0 ) { - _gcry_mpih_sub_n(prodp, up + hsize, up, hsize); - negflg = 0; - } - else { - _gcry_mpih_sub_n(prodp, up, up + hsize, hsize); - negflg = 1; - } - if( _gcry_mpih_cmp(vp + hsize, vp, hsize) >= 0 ) { - _gcry_mpih_sub_n(prodp + hsize, vp + hsize, vp, hsize); - negflg ^= 1; - } - else { - _gcry_mpih_sub_n(prodp + hsize, vp, vp + hsize, hsize); - /* No change of NEGFLG. */ - } - /* Read temporary operands from low part of PROD. - * Put result in low part of TSPACE using upper part of TSPACE - * as new TSPACE. - */ - MPN_MUL_N_RECURSE(tspace, prodp, prodp + hsize, hsize, tspace + size); - - /* Add/copy product H. */ - MPN_COPY (prodp + hsize, prodp + size, hsize); - cy = _gcry_mpih_add_n( prodp + size, prodp + size, - prodp + size + hsize, hsize); - - /* Add product M (if NEGFLG M is a negative number) */ - if(negflg) - cy -= _gcry_mpih_sub_n(prodp + hsize, prodp + hsize, tspace, size); - else - cy += _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace, size); - - /* Product L. ________________ ________________ - * |________________||____U0 x V0_____| - * Read temporary operands from low part of PROD. - * Put result in low part of TSPACE using upper part of TSPACE - * as new TSPACE. - */ - MPN_MUL_N_RECURSE(tspace, up, vp, hsize, tspace + size); - - /* Add/copy Product L (twice) */ - - cy += _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace, size); - if( cy ) - _gcry_mpih_add_1(prodp + hsize + size, prodp + hsize + size, hsize, cy); - - MPN_COPY(prodp, tspace, hsize); - cy = _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace + hsize, hsize); - if( cy ) - _gcry_mpih_add_1(prodp + size, prodp + size, size, 1); - } -} - - -void -_gcry_mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size ) -{ - mpi_size_t i; - mpi_limb_t cy_limb; - mpi_limb_t v_limb; - - /* Multiply by the first limb in V separately, as the result can be - * stored (not added) to PROD. We also avoid a loop for zeroing. */ - v_limb = up[0]; - if( v_limb <= 1 ) { - if( v_limb == 1 ) - MPN_COPY( prodp, up, size ); - else - MPN_ZERO(prodp, size); - cy_limb = 0; - } - else - cy_limb = _gcry_mpih_mul_1( prodp, up, size, v_limb ); - - prodp[size] = cy_limb; - prodp++; - - /* For each iteration in the outer loop, multiply one limb from - * U with one limb from V, and add it to PROD. */ - for( i=1; i < size; i++) { - v_limb = up[i]; - if( v_limb <= 1 ) { - cy_limb = 0; - if( v_limb == 1 ) - cy_limb = _gcry_mpih_add_n(prodp, prodp, up, size); - } - else - cy_limb = _gcry_mpih_addmul_1(prodp, up, size, v_limb); - - prodp[size] = cy_limb; - prodp++; - } -} - - -void -_gcry_mpih_sqr_n( mpi_ptr_t prodp, - mpi_ptr_t up, mpi_size_t size, mpi_ptr_t tspace) -{ - if( size & 1 ) { - /* The size is odd, and the code below doesn't handle that. - * Multiply the least significant (size - 1) limbs with a recursive - * call, and handle the most significant limb of S1 and S2 - * separately. - * A slightly faster way to do this would be to make the Karatsuba - * code below behave as if the size were even, and let it check for - * odd size in the end. I.e., in essence move this code to the end. - * Doing so would save us a recursive call, and potentially make the - * stack grow a lot less. - */ - mpi_size_t esize = size - 1; /* even size */ - mpi_limb_t cy_limb; - - MPN_SQR_N_RECURSE( prodp, up, esize, tspace ); - cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, esize, up[esize] ); - prodp[esize + esize] = cy_limb; - cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, size, up[esize] ); - - prodp[esize + size] = cy_limb; - } - else { - mpi_size_t hsize = size >> 1; - mpi_limb_t cy; - - /* Product H. ________________ ________________ - * |_____U1 x U1____||____U0 x U0_____| - * Put result in upper part of PROD and pass low part of TSPACE - * as new TSPACE. - */ - MPN_SQR_N_RECURSE(prodp + size, up + hsize, hsize, tspace); - - /* Product M. ________________ - * |_(U1-U0)(U0-U1)_| - */ - if( _gcry_mpih_cmp( up + hsize, up, hsize) >= 0 ) - _gcry_mpih_sub_n( prodp, up + hsize, up, hsize); - else - _gcry_mpih_sub_n (prodp, up, up + hsize, hsize); - - /* Read temporary operands from low part of PROD. - * Put result in low part of TSPACE using upper part of TSPACE - * as new TSPACE. */ - MPN_SQR_N_RECURSE(tspace, prodp, hsize, tspace + size); - - /* Add/copy product H */ - MPN_COPY(prodp + hsize, prodp + size, hsize); - cy = _gcry_mpih_add_n(prodp + size, prodp + size, - prodp + size + hsize, hsize); - - /* Add product M (if NEGFLG M is a negative number). */ - cy -= _gcry_mpih_sub_n (prodp + hsize, prodp + hsize, tspace, size); - - /* Product L. ________________ ________________ - * |________________||____U0 x U0_____| - * Read temporary operands from low part of PROD. - * Put result in low part of TSPACE using upper part of TSPACE - * as new TSPACE. */ - MPN_SQR_N_RECURSE (tspace, up, hsize, tspace + size); - - /* Add/copy Product L (twice). */ - cy += _gcry_mpih_add_n (prodp + hsize, prodp + hsize, tspace, size); - if( cy ) - _gcry_mpih_add_1(prodp + hsize + size, prodp + hsize + size, - hsize, cy); - - MPN_COPY(prodp, tspace, hsize); - cy = _gcry_mpih_add_n (prodp + hsize, prodp + hsize, tspace + hsize, hsize); - if( cy ) - _gcry_mpih_add_1 (prodp + size, prodp + size, size, 1); - } -} - - -/* This should be made into an inline function in gmp.h. */ -void -_gcry_mpih_mul_n( mpi_ptr_t prodp, - mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size) -{ - int secure; - - if( up == vp ) { - if( size < KARATSUBA_THRESHOLD ) - _gcry_mpih_sqr_n_basecase( prodp, up, size ); - else { - mpi_ptr_t tspace; - secure = gcry_is_secure( up ); - tspace = mpi_alloc_limb_space( 2 * size, secure ); - _gcry_mpih_sqr_n( prodp, up, size, tspace ); - _gcry_mpi_free_limb_space (tspace, 2 * size ); - } - } - else { - if( size < KARATSUBA_THRESHOLD ) - mul_n_basecase( prodp, up, vp, size ); - else { - mpi_ptr_t tspace; - secure = gcry_is_secure( up ) || gcry_is_secure( vp ); - tspace = mpi_alloc_limb_space( 2 * size, secure ); - mul_n (prodp, up, vp, size, tspace); - _gcry_mpi_free_limb_space (tspace, 2 * size ); - } - } -} - - - -void -_gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp, - mpi_ptr_t up, mpi_size_t usize, - mpi_ptr_t vp, mpi_size_t vsize, - struct karatsuba_ctx *ctx ) -{ - mpi_limb_t cy; - - if( !ctx->tspace || ctx->tspace_size < vsize ) { - if( ctx->tspace ) - _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs ); - ctx->tspace_nlimbs = 2 * vsize; - ctx->tspace = mpi_alloc_limb_space( 2 * vsize, - (gcry_is_secure( up ) - || gcry_is_secure( vp )) ); - ctx->tspace_size = vsize; - } - - MPN_MUL_N_RECURSE( prodp, up, vp, vsize, ctx->tspace ); - - prodp += vsize; - up += vsize; - usize -= vsize; - if( usize >= vsize ) { - if( !ctx->tp || ctx->tp_size < vsize ) { - if( ctx->tp ) - _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs ); - ctx->tp_nlimbs = 2 * vsize; - ctx->tp = mpi_alloc_limb_space( 2 * vsize, gcry_is_secure( up ) - || gcry_is_secure( vp ) ); - ctx->tp_size = vsize; - } - - do { - MPN_MUL_N_RECURSE( ctx->tp, up, vp, vsize, ctx->tspace ); - cy = _gcry_mpih_add_n( prodp, prodp, ctx->tp, vsize ); - _gcry_mpih_add_1( prodp + vsize, ctx->tp + vsize, vsize, cy ); - prodp += vsize; - up += vsize; - usize -= vsize; - } while( usize >= vsize ); - } - - if( usize ) { - if( usize < KARATSUBA_THRESHOLD ) { - _gcry_mpih_mul( ctx->tspace, vp, vsize, up, usize ); - } - else { - if( !ctx->next ) { - ctx->next = gcry_xcalloc( 1, sizeof *ctx ); - } - _gcry_mpih_mul_karatsuba_case( ctx->tspace, - vp, vsize, - up, usize, - ctx->next ); - } - - cy = _gcry_mpih_add_n( prodp, prodp, ctx->tspace, vsize); - _gcry_mpih_add_1( prodp + vsize, ctx->tspace + vsize, usize, cy ); - } -} - - -void -_gcry_mpih_release_karatsuba_ctx( struct karatsuba_ctx *ctx ) -{ - struct karatsuba_ctx *ctx2; - - if( ctx->tp ) - _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs ); - if( ctx->tspace ) - _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs ); - for( ctx=ctx->next; ctx; ctx = ctx2 ) { - ctx2 = ctx->next; - if( ctx->tp ) - _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs ); - if( ctx->tspace ) - _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs ); - gcry_free( ctx ); - } -} - -/* Multiply the natural numbers u (pointed to by UP, with USIZE limbs) - * and v (pointed to by VP, with VSIZE limbs), and store the result at - * PRODP. USIZE + VSIZE limbs are always stored, but if the input - * operands are normalized. Return the most significant limb of the - * result. - * - * NOTE: The space pointed to by PRODP is overwritten before finished - * with U and V, so overlap is an error. - * - * Argument constraints: - * 1. USIZE >= VSIZE. - * 2. PRODP != UP and PRODP != VP, i.e. the destination - * must be distinct from the multiplier and the multiplicand. - */ - -mpi_limb_t -_gcry_mpih_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize, - mpi_ptr_t vp, mpi_size_t vsize) -{ - mpi_ptr_t prod_endp = prodp + usize + vsize - 1; - mpi_limb_t cy; - struct karatsuba_ctx ctx; - - if( vsize < KARATSUBA_THRESHOLD ) { - mpi_size_t i; - mpi_limb_t v_limb; - - if( !vsize ) - return 0; - - /* Multiply by the first limb in V separately, as the result can be - * stored (not added) to PROD. We also avoid a loop for zeroing. */ - v_limb = vp[0]; - if( v_limb <= 1 ) { - if( v_limb == 1 ) - MPN_COPY( prodp, up, usize ); - else - MPN_ZERO( prodp, usize ); - cy = 0; - } - else - cy = _gcry_mpih_mul_1( prodp, up, usize, v_limb ); - - prodp[usize] = cy; - prodp++; - - /* For each iteration in the outer loop, multiply one limb from - * U with one limb from V, and add it to PROD. */ - for( i = 1; i < vsize; i++ ) { - v_limb = vp[i]; - if( v_limb <= 1 ) { - cy = 0; - if( v_limb == 1 ) - cy = _gcry_mpih_add_n(prodp, prodp, up, usize); - } - else - cy = _gcry_mpih_addmul_1(prodp, up, usize, v_limb); - - prodp[usize] = cy; - prodp++; - } - - return cy; - } - - memset( &ctx, 0, sizeof ctx ); - _gcry_mpih_mul_karatsuba_case( prodp, up, usize, vp, vsize, &ctx ); - _gcry_mpih_release_karatsuba_ctx( &ctx ); - return *prod_endp; -} diff --git a/grub-core/lib/libgcrypt/mpi/mpiutil.c b/grub-core/lib/libgcrypt/mpi/mpiutil.c deleted file mode 100644 index 76630a629..000000000 --- a/grub-core/lib/libgcrypt/mpi/mpiutil.c +++ /dev/null @@ -1,460 +0,0 @@ -/* mpiutil.ac - Utility functions for MPI - * Copyright (C) 1998, 2000, 2001, 2002, 2003, - * 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 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 . - */ - -#include -#include -#include -#include - -#include "g10lib.h" -#include "mpi-internal.h" -#include "mod-source-info.h" - - -const char * -_gcry_mpi_get_hw_config (void) -{ - return mod_source_info + 1; -} - - -/**************** - * Note: It was a bad idea to use the number of limbs to allocate - * because on a alpha the limbs are large but we normally need - * integers of n bits - So we should change this to bits (or bytes). - * - * But mpi_alloc is used in a lot of places :-(. New code - * should use mpi_new. - */ -gcry_mpi_t -_gcry_mpi_alloc( unsigned nlimbs ) -{ - gcry_mpi_t a; - - a = gcry_xmalloc( sizeof *a ); - a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL; - a->alloced = nlimbs; - a->nlimbs = 0; - a->sign = 0; - a->flags = 0; - return a; -} - -void -_gcry_mpi_m_check( gcry_mpi_t a ) -{ - _gcry_check_heap(a); - _gcry_check_heap(a->d); -} - -gcry_mpi_t -_gcry_mpi_alloc_secure( unsigned nlimbs ) -{ - gcry_mpi_t a; - - a = gcry_xmalloc( sizeof *a ); - a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL; - a->alloced = nlimbs; - a->flags = 1; - a->nlimbs = 0; - a->sign = 0; - return a; -} - - - -mpi_ptr_t -_gcry_mpi_alloc_limb_space( unsigned int nlimbs, int secure ) -{ - mpi_ptr_t p; - size_t len; - - len = (nlimbs ? nlimbs : 1) * sizeof (mpi_limb_t); - p = secure ? gcry_xmalloc_secure (len) : gcry_xmalloc (len); - if (! nlimbs) - *p = 0; - - return p; -} - -void -_gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs) -{ - if (a) - { - size_t len = nlimbs * sizeof(mpi_limb_t); - - /* If we have information on the number of allocated limbs, we - better wipe that space out. This is a failsafe feature if - secure memory has been disabled or was not properly - implemented in user provided allocation functions. */ - if (len) - wipememory (a, len); - gcry_free(a); - } -} - - -void -_gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned int nlimbs ) -{ - _gcry_mpi_free_limb_space (a->d, a->alloced); - a->d = ap; - a->alloced = nlimbs; -} - - - -/**************** - * Resize the array of A to NLIMBS. The additional space is cleared - * (set to 0). - */ -void -_gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs) -{ - size_t i; - - if (nlimbs <= a->alloced) - { - /* We only need to clear the new space (this is a nop if the - limb space is already of the correct size. */ - for (i=a->nlimbs; i < a->alloced; i++) - a->d[i] = 0; - return; - } - - /* Actually resize the limb space. */ - if (a->d) - { - a->d = gcry_xrealloc (a->d, nlimbs * sizeof (mpi_limb_t)); - for (i=a->alloced; i < nlimbs; i++) - a->d[i] = 0; - } - else - { - if (a->flags & 1) - /* Secure memory is wanted. */ - a->d = gcry_xcalloc_secure (nlimbs , sizeof (mpi_limb_t)); - else - /* Standard memory. */ - a->d = gcry_xcalloc (nlimbs , sizeof (mpi_limb_t)); - } - a->alloced = nlimbs; -} - -void -_gcry_mpi_clear( gcry_mpi_t a ) -{ - a->nlimbs = 0; - a->flags = 0; -} - - -void -_gcry_mpi_free( gcry_mpi_t a ) -{ - if (!a ) - return; - if ((a->flags & 4)) - gcry_free( a->d ); - else - { - _gcry_mpi_free_limb_space(a->d, a->alloced); - } - if ((a->flags & ~7)) - log_bug("invalid flag value in mpi\n"); - gcry_free(a); -} - -static void -mpi_set_secure( gcry_mpi_t a ) -{ - mpi_ptr_t ap, bp; - - if ( (a->flags & 1) ) - return; - a->flags |= 1; - ap = a->d; - if (!a->nlimbs) - { - gcry_assert (!ap); - return; - } - bp = mpi_alloc_limb_space (a->nlimbs, 1); - MPN_COPY( bp, ap, a->nlimbs ); - a->d = bp; - _gcry_mpi_free_limb_space (ap, a->alloced); -} - - -gcry_mpi_t -gcry_mpi_set_opaque( gcry_mpi_t a, void *p, unsigned int nbits ) -{ - if (!a) - a = mpi_alloc(0); - - if( a->flags & 4 ) - gcry_free( a->d ); - else - _gcry_mpi_free_limb_space (a->d, a->alloced); - - a->d = p; - a->alloced = 0; - a->nlimbs = 0; - a->sign = nbits; - a->flags = 4; - return a; -} - - -void * -gcry_mpi_get_opaque( gcry_mpi_t a, unsigned int *nbits ) -{ - if( !(a->flags & 4) ) - log_bug("mpi_get_opaque on normal mpi\n"); - if( nbits ) - *nbits = a->sign; - return a->d; -} - - -/**************** - * Note: This copy function should not interpret the MPI - * but copy it transparently. - */ -gcry_mpi_t -gcry_mpi_copy( gcry_mpi_t a ) -{ - int i; - gcry_mpi_t b; - - if( a && (a->flags & 4) ) { - void *p = gcry_is_secure(a->d)? gcry_xmalloc_secure( (a->sign+7)/8 ) - : gcry_xmalloc( (a->sign+7)/8 ); - memcpy( p, a->d, (a->sign+7)/8 ); - b = gcry_mpi_set_opaque( NULL, p, a->sign ); - } - else if( a ) { - b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs ) - : mpi_alloc( a->nlimbs ); - b->nlimbs = a->nlimbs; - b->sign = a->sign; - b->flags = a->flags; - for(i=0; i < b->nlimbs; i++ ) - b->d[i] = a->d[i]; - } - else - b = NULL; - return b; -} - - -/**************** - * This function allocates an MPI which is optimized to hold - * a value as large as the one given in the argument and allocates it - * with the same flags as A. - */ -gcry_mpi_t -_gcry_mpi_alloc_like( gcry_mpi_t a ) -{ - gcry_mpi_t b; - - if( a && (a->flags & 4) ) { - int n = (a->sign+7)/8; - void *p = gcry_is_secure(a->d)? gcry_malloc_secure( n ) - : gcry_malloc( n ); - memcpy( p, a->d, n ); - b = gcry_mpi_set_opaque( NULL, p, a->sign ); - } - else if( a ) { - b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs ) - : mpi_alloc( a->nlimbs ); - b->nlimbs = 0; - b->sign = 0; - b->flags = a->flags; - } - else - b = NULL; - return b; -} - - -gcry_mpi_t -gcry_mpi_set( gcry_mpi_t w, gcry_mpi_t u) -{ - mpi_ptr_t wp, up; - mpi_size_t usize = u->nlimbs; - int usign = u->sign; - - if (!w) - w = _gcry_mpi_alloc( mpi_get_nlimbs(u) ); - RESIZE_IF_NEEDED(w, usize); - wp = w->d; - up = u->d; - MPN_COPY( wp, up, usize ); - w->nlimbs = usize; - w->flags = u->flags; - w->sign = usign; - return w; -} - - -gcry_mpi_t -gcry_mpi_set_ui( gcry_mpi_t w, unsigned long u) -{ - if (!w) - w = _gcry_mpi_alloc (1); - /* FIXME: If U is 0 we have no need to resize and thus possible - allocating the the limbs. */ - RESIZE_IF_NEEDED(w, 1); - w->d[0] = u; - w->nlimbs = u? 1:0; - w->sign = 0; - w->flags = 0; - return w; -} - -gcry_err_code_t -_gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u) -{ - gcry_err_code_t err = GPG_ERR_NO_ERROR; - unsigned long x = 0; - - if (w->nlimbs > 1) - err = GPG_ERR_TOO_LARGE; - else if (w->nlimbs == 1) - x = w->d[0]; - else - x = 0; - - if (! err) - *u = x; - - return err; -} - -gcry_error_t -gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u) -{ - gcry_err_code_t err = GPG_ERR_NO_ERROR; - - err = _gcry_mpi_get_ui (w, u); - - return gcry_error (err); -} - -gcry_mpi_t -_gcry_mpi_alloc_set_ui( unsigned long u) -{ - gcry_mpi_t w = mpi_alloc(1); - w->d[0] = u; - w->nlimbs = u? 1:0; - w->sign = 0; - return w; -} - -void -gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b) -{ - struct gcry_mpi tmp; - - tmp = *a; *a = *b; *b = tmp; -} - - -gcry_mpi_t -gcry_mpi_new( unsigned int nbits ) -{ - return _gcry_mpi_alloc ( (nbits+BITS_PER_MPI_LIMB-1) - / BITS_PER_MPI_LIMB ); -} - - -gcry_mpi_t -gcry_mpi_snew( unsigned int nbits ) -{ - return _gcry_mpi_alloc_secure ( (nbits+BITS_PER_MPI_LIMB-1) - / BITS_PER_MPI_LIMB ); -} - -void -gcry_mpi_release( gcry_mpi_t a ) -{ - _gcry_mpi_free( a ); -} - -void -gcry_mpi_randomize( gcry_mpi_t w, - unsigned int nbits, enum gcry_random_level level ) -{ - unsigned char *p; - size_t nbytes = (nbits+7)/8; - - if (level == GCRY_WEAK_RANDOM) - { - p = mpi_is_secure(w) ? gcry_xmalloc_secure (nbytes) - : gcry_xmalloc (nbytes); - gcry_create_nonce (p, nbytes); - } - else - { - p = mpi_is_secure(w) ? gcry_random_bytes_secure (nbytes, level) - : gcry_random_bytes (nbytes, level); - } - _gcry_mpi_set_buffer( w, p, nbytes, 0 ); - gcry_free (p); -} - - -void -gcry_mpi_set_flag( gcry_mpi_t a, enum gcry_mpi_flag flag ) -{ - switch( flag ) { - case GCRYMPI_FLAG_SECURE: mpi_set_secure(a); break; - case GCRYMPI_FLAG_OPAQUE: - default: log_bug("invalid flag value\n"); - } -} - -void -gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag ) -{ - (void)a; /* Not yet used. */ - - switch (flag) - { - case GCRYMPI_FLAG_SECURE: - case GCRYMPI_FLAG_OPAQUE: - default: log_bug("invalid flag value\n"); - } -} - -int -gcry_mpi_get_flag( gcry_mpi_t a, enum gcry_mpi_flag flag ) -{ - switch (flag) - { - case GCRYMPI_FLAG_SECURE: return (a->flags & 1); - case GCRYMPI_FLAG_OPAQUE: return (a->flags & 4); - default: log_bug("invalid flag value\n"); - } - /*NOTREACHED*/ - return 0; -} diff --git a/grub-core/lib/libgcrypt/mpi/pa7100/Manifest b/grub-core/lib/libgcrypt/mpi/pa7100/Manifest deleted file mode 100644 index f075ab056..000000000 --- a/grub-core/lib/libgcrypt/mpi/pa7100/Manifest +++ /dev/null @@ -1,22 +0,0 @@ -# Manifest - checksums -# Copyright 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 - -mpih-lshift.S -mpih-rshift.S -$names$ iQCVAwUAP+LmVjEAnp832S/7AQKlEQQAv2+x/d+Z0t8FwwHlxKpIKOJDr9e+Y2i8y8orcIEa3dnwU5LMOH3EzFoNSD9crc31FMokgm/X5xeLjqRTdcmGHyJJQJDPJVJyuaOm6qHJaFzzfJjrfMW66nJxfNSXIiIm4DgpP20NmumaorLCkiIZ5Z81KGAc8FiRggbRVYx+wxo==Vjh9 diff --git a/grub-core/lib/libgcrypt/mpi/pa7100/distfiles b/grub-core/lib/libgcrypt/mpi/pa7100/distfiles deleted file mode 100644 index e1cde4d57..000000000 --- a/grub-core/lib/libgcrypt/mpi/pa7100/distfiles +++ /dev/null @@ -1,4 +0,0 @@ -Manifest -mpih-lshift.S -mpih-rshift.S - diff --git a/grub-core/lib/libgcrypt/mpi/pa7100/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/pa7100/mpih-lshift.S deleted file mode 100644 index 8ade19643..000000000 --- a/grub-core/lib/libgcrypt/mpi/pa7100/mpih-lshift.S +++ /dev/null @@ -1,96 +0,0 @@ -/* hppa lshift - * optimized for the PA7100, where it runs at 3.25 cycles/limb - * - * Copyright (C) 1992, 1994, 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 - */ - - - -/******************* - * mpi_limb_t - * _gcry_mpih_lshift( mpi_ptr_t wp, (gr26) - * mpi_ptr_t up, (gr25) - * mpi_size_t usize, (gr24) - * unsigned cnt) (gr23) - */ - - .code - .export _gcry_mpih_lshift - .label _gcry_mpih_lshift - .proc - .callinfo frame=64,no_calls - .entry - - sh2add %r24,%r25,%r25 - sh2add %r24,%r26,%r26 - ldws,mb -4(0,%r25),%r22 - subi 32,%r23,%r1 - mtsar %r1 - addib,= -1,%r24,L$0004 - vshd %r0,%r22,%r28 ; compute carry out limb - ldws,mb -4(0,%r25),%r29 - addib,<= -5,%r24,L$rest - vshd %r22,%r29,%r20 - - .label L$loop - ldws,mb -4(0,%r25),%r22 - stws,mb %r20,-4(0,%r26) - vshd %r29,%r22,%r20 - ldws,mb -4(0,%r25),%r29 - stws,mb %r20,-4(0,%r26) - vshd %r22,%r29,%r20 - ldws,mb -4(0,%r25),%r22 - stws,mb %r20,-4(0,%r26) - vshd %r29,%r22,%r20 - ldws,mb -4(0,%r25),%r29 - stws,mb %r20,-4(0,%r26) - addib,> -4,%r24,L$loop - vshd %r22,%r29,%r20 - - .label L$rest - addib,= 4,%r24,L$end1 - nop - .label L$eloop - ldws,mb -4(0,%r25),%r22 - stws,mb %r20,-4(0,%r26) - addib,<= -1,%r24,L$end2 - vshd %r29,%r22,%r20 - ldws,mb -4(0,%r25),%r29 - stws,mb %r20,-4(0,%r26) - addib,> -1,%r24,L$eloop - vshd %r22,%r29,%r20 - - .label L$end1 - stws,mb %r20,-4(0,%r26) - vshd %r29,%r0,%r20 - bv 0(%r2) - stw %r20,-4(0,%r26) - .label L$end2 - stws,mb %r20,-4(0,%r26) - .label L$0004 - vshd %r22,%r0,%r20 - bv 0(%r2) - stw %r20,-4(0,%r26) - - .exit - .procend - - - diff --git a/grub-core/lib/libgcrypt/mpi/pa7100/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/pa7100/mpih-rshift.S deleted file mode 100644 index 062420272..000000000 --- a/grub-core/lib/libgcrypt/mpi/pa7100/mpih-rshift.S +++ /dev/null @@ -1,92 +0,0 @@ -/* hppa rshift - * optimized for the PA7100, where it runs at 3.25 cycles/limb - * - * Copyright (C) 1992, 1994, 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 - */ - - - -/******************* - * mpi_limb_t - * _gcry_mpih_rshift( mpi_ptr_t wp, (gr26) - * mpi_ptr_t up, (gr25) - * mpi_size_t usize, (gr24) - * unsigned cnt) (gr23) - */ - - .code - .export _gcry_mpih_rshift - .label _gcry_mpih_rshift - .proc - .callinfo frame=64,no_calls - .entry - - ldws,ma 4(0,%r25),%r22 - mtsar %r23 - addib,= -1,%r24,L$r004 - vshd %r22,%r0,%r28 ; compute carry out limb - ldws,ma 4(0,%r25),%r29 - addib,<= -5,%r24,L$rrest - vshd %r29,%r22,%r20 - - .label L$roop - ldws,ma 4(0,%r25),%r22 - stws,ma %r20,4(0,%r26) - vshd %r22,%r29,%r20 - ldws,ma 4(0,%r25),%r29 - stws,ma %r20,4(0,%r26) - vshd %r29,%r22,%r20 - ldws,ma 4(0,%r25),%r22 - stws,ma %r20,4(0,%r26) - vshd %r22,%r29,%r20 - ldws,ma 4(0,%r25),%r29 - stws,ma %r20,4(0,%r26) - addib,> -4,%r24,L$roop - vshd %r29,%r22,%r20 - - .label L$rrest - addib,= 4,%r24,L$rend1 - nop - .label L$eroop - ldws,ma 4(0,%r25),%r22 - stws,ma %r20,4(0,%r26) - addib,<= -1,%r24,L$rend2 - vshd %r22,%r29,%r20 - ldws,ma 4(0,%r25),%r29 - stws,ma %r20,4(0,%r26) - addib,> -1,%r24,L$eroop - vshd %r29,%r22,%r20 - - .label L$rend1 - stws,ma %r20,4(0,%r26) - vshd %r0,%r29,%r20 - bv 0(%r2) - stw %r20,0(0,%r26) - .label L$rend2 - stws,ma %r20,4(0,%r26) - .label L$r004 - vshd %r0,%r22,%r20 - bv 0(%r2) - stw %r20,0(0,%r26) - - .exit - .procend - - diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/README b/grub-core/lib/libgcrypt/mpi/pentium4/README deleted file mode 100644 index 215fc7f8b..000000000 --- a/grub-core/lib/libgcrypt/mpi/pentium4/README +++ /dev/null @@ -1,115 +0,0 @@ -Copyright 2001 Free Software Foundation, Inc. - -This file is part of the GNU MP Library. - -The GNU MP 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 MP 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 MP Library; see the file COPYING.LIB. If not, write to -the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. - - - - - INTEL PENTIUM-4 MPN SUBROUTINES - - -This directory contains mpn functions optimized for Intel Pentium-4. - -The mmx subdirectory has routines using MMX instructions, the sse2 -subdirectory has routines using SSE2 instructions. All P4s have these, the -separate directories are just so configure can omit that code if the -assembler doesn't support it. - - -STATUS - - cycles/limb - - mpn_add_n/sub_n 4 normal, 6 in-place - - mpn_mul_1 4 normal, 6 in-place - mpn_addmul_1 6 - mpn_submul_1 7 - - mpn_mul_basecase 6 cycles/crossproduct (approx) - - mpn_sqr_basecase 3.5 cycles/crossproduct (approx) - or 7.0 cycles/triangleproduct (approx) - - mpn_l/rshift 1.75 - - - -The shifts ought to be able to go at 1.5 c/l, but not much effort has been -applied to them yet. - -In-place operations, and all addmul, submul, mul_basecase and sqr_basecase -calls, suffer from pipeline anomalies associated with write combining and -movd reads and writes to the same or nearby locations. The movq -instructions do not trigger the same hardware problems. Unfortunately, -using movq and splitting/combining seems to require too many extra -instructions to help. Perhaps future chip steppings will be better. - - - -NOTES - -The Pentium-4 pipeline "Netburst", provides for quite a number of surprises. -Many traditional x86 instructions run very slowly, requiring use of -alterative instructions for acceptable performance. - -adcl and sbbl are quite slow at 8 cycles for reg->reg. paddq of 32-bits -within a 64-bit mmx register seems better, though the combination -paddq/psrlq when propagating a carry is still a 4 cycle latency. - -incl and decl should be avoided, instead use add $1 and sub $1. Apparently -the carry flag is not separately renamed, so incl and decl depend on all -previous flags-setting instructions. - -shll and shrl have a 4 cycle latency, or 8 times the latency of the fastest -integer instructions (addl, subl, orl, andl, and some more). shldl and -shrdl seem to have 13 and 15 cycles latency, respectively. Bizarre. - -movq mmx -> mmx does have 6 cycle latency, as noted in the documentation. -pxor/por or similar combination at 2 cycles latency can be used instead. -The movq however executes in the float unit, thereby saving MMX execution -resources. With the right juggling, data moves shouldn't be on a dependent -chain. - -L1 is write-through, but the write-combining sounds like it does enough to -not require explicit destination prefetching. - -xmm registers so far haven't found a use, but not much effort has been -expended. A configure test for whether the operating system knows -fxsave/fxrestor will be needed if they're used. - - - -REFERENCES - -Intel Pentium-4 processor manuals, - - http://developer.intel.com/design/pentium4/manuals - -"Intel Pentium 4 Processor Optimization Reference Manual", Intel, 2001, -order number 248966. Available on-line: - - http://developer.intel.com/design/pentium4/manuals/248966.htm - - - ----------------- -Local variables: -mode: text -fill-column: 76 -End: diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/distfiles b/grub-core/lib/libgcrypt/mpi/pentium4/distfiles deleted file mode 100644 index b419f85a9..000000000 --- a/grub-core/lib/libgcrypt/mpi/pentium4/distfiles +++ /dev/null @@ -1,3 +0,0 @@ -README - - diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/mmx/distfiles b/grub-core/lib/libgcrypt/mpi/pentium4/mmx/distfiles deleted file mode 100644 index 8f0ea426d..000000000 --- a/grub-core/lib/libgcrypt/mpi/pentium4/mmx/distfiles +++ /dev/null @@ -1,2 +0,0 @@ -mpih-lshift.S -mpih-rshift.S diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S deleted file mode 100644 index e2dd184ba..000000000 --- a/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S +++ /dev/null @@ -1,457 +0,0 @@ -/* Intel Pentium-4 mpn_lshift -- left shift. - * - * Copyright 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4) - * mpi_ptr_t up, (sp + 8) - * mpi_size_t usize, (sp + 12) - * unsigned cnt) (sp + 16) - * - * P4 Willamette, Northwood: 1.75 cycles/limb - * P4 Prescott: 2.0 cycles/limb - */ - -.text - ALIGN (3) - .globl C_SYMBOL_NAME(_gcry_mpih_lshift) -C_SYMBOL_NAME(_gcry_mpih_lshift:) - - - pushl %ebx - pushl %edi - - - movl 20(%esp), %eax - movl 12(%esp), %edx - - movl 16(%esp), %ebx - movl 24(%esp), %ecx - - cmp $5, %eax - jae .Lunroll - - movl -4(%ebx,%eax,4), %edi - decl %eax - - jnz .Lsimple - - shldl %cl, %edi, %eax - - shll %cl, %edi - - movl %edi, (%edx) - popl %edi - - popl %ebx - - ret - - - - - -.Lsimple: - - - - - - - - - - movd (%ebx,%eax,4), %mm5 - - movd %ecx, %mm6 - negl %ecx - - psllq %mm6, %mm5 - addl $32, %ecx - - movd %ecx, %mm7 - psrlq $32, %mm5 - - -.Lsimple_top: - - - - - - - - - - - - - movq -4(%ebx,%eax,4), %mm0 - decl %eax - - psrlq %mm7, %mm0 - - - - movd %mm0, 4(%edx,%eax,4) - jnz .Lsimple_top - - - movd (%ebx), %mm0 - - movd %mm5, %eax - psllq %mm6, %mm0 - - popl %edi - popl %ebx - - movd %mm0, (%edx) - - emms - - ret - - - - - - .align 8, 0x90 -.Lunroll: - - - - - - - - - - movd -4(%ebx,%eax,4), %mm5 - leal (%ebx,%eax,4), %edi - - movd %ecx, %mm6 - andl $4, %edi - - psllq %mm6, %mm5 - jz .Lstart_src_aligned - - - - - - - - - - - - - - - - - - - - movq -8(%ebx,%eax,4), %mm0 - - psllq %mm6, %mm0 - decl %eax - - psrlq $32, %mm0 - - - - movd %mm0, (%edx,%eax,4) -.Lstart_src_aligned: - - movq -8(%ebx,%eax,4), %mm1 - leal (%edx,%eax,4), %edi - - andl $4, %edi - psrlq $32, %mm5 - - movq -16(%ebx,%eax,4), %mm3 - jz .Lstart_dst_aligned - - - - - - - - - - - - - - - - - - - - - movq %mm1, %mm0 - addl $32, %ecx - - psllq %mm6, %mm0 - - movd %ecx, %mm6 - psrlq $32, %mm0 - - - - movd %mm0, -4(%edx,%eax,4) - subl $4, %edx -.Lstart_dst_aligned: - - - psllq %mm6, %mm1 - negl %ecx - - addl $64, %ecx - movq %mm3, %mm2 - - movd %ecx, %mm7 - subl $8, %eax - - psrlq %mm7, %mm3 - - por %mm1, %mm3 - jc .Lfinish - - - - - .align 8, 0x90 -.Lunroll_loop: - - - - - - - - - - - - - - - - - movq 8(%ebx,%eax,4), %mm0 - psllq %mm6, %mm2 - - movq %mm0, %mm1 - psrlq %mm7, %mm0 - - movq %mm3, 24(%edx,%eax,4) - por %mm2, %mm0 - - movq (%ebx,%eax,4), %mm3 - psllq %mm6, %mm1 - - movq %mm0, 16(%edx,%eax,4) - movq %mm3, %mm2 - - psrlq %mm7, %mm3 - subl $4, %eax - - por %mm1, %mm3 - jnc .Lunroll_loop - - - -.Lfinish: - - - testb $2, %al - - jz .Lfinish_no_two - - movq 8(%ebx,%eax,4), %mm0 - psllq %mm6, %mm2 - - movq %mm0, %mm1 - psrlq %mm7, %mm0 - - movq %mm3, 24(%edx,%eax,4) - por %mm2, %mm0 - - movq %mm1, %mm2 - movq %mm0, %mm3 - - subl $2, %eax -.Lfinish_no_two: - - - - - - - - testb $1, %al - movd %mm5, %eax - - popl %edi - jz .Lfinish_zero - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - movd (%ebx), %mm0 - psllq %mm6, %mm2 - - movq %mm3, 12(%edx) - psllq $32, %mm0 - - movq %mm0, %mm1 - psrlq %mm7, %mm0 - - por %mm2, %mm0 - psllq %mm6, %mm1 - - movq %mm0, 4(%edx) - psrlq $32, %mm1 - - andl $32, %ecx - popl %ebx - - jz .Lfinish_one_unaligned - - movd %mm1, (%edx) -.Lfinish_one_unaligned: - - emms - - ret - - - - -.Lfinish_zero: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - movq %mm3, 8(%edx) - andl $32, %ecx - - psllq %mm6, %mm2 - jz .Lfinish_zero_unaligned - - movq %mm2, (%edx) -.Lfinish_zero_unaligned: - - psrlq $32, %mm2 - popl %ebx - - movd %mm5, %eax - - movd %mm2, 4(%edx) - - emms - - ret diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S deleted file mode 100644 index e3374e3ba..000000000 --- a/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S +++ /dev/null @@ -1,453 +0,0 @@ -/* Intel Pentium-4 mpn_rshift -- right shift. - * - * Copyright 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4) - * mpi_ptr_t up, (sp + 8) - * mpi_size_t usize, (sp + 12) - * unsigned cnt) (sp + 16) - * - * P4 Willamette, Northwood: 1.75 cycles/limb - * P4 Prescott: 2.0 cycles/limb - */ - -.text - ALIGN (3) - .globl C_SYMBOL_NAME(_gcry_mpih_rshift) -C_SYMBOL_NAME(_gcry_mpih_rshift:) - pushl %ebx - pushl %edi - - - movl 20(%esp), %eax - movl 12(%esp), %edx - - movl 16(%esp), %ebx - movl 24(%esp), %ecx - - cmp $5, %eax - jae .Lunroll - - decl %eax - movl (%ebx), %edi - - jnz .Lsimple - - shrdl %cl, %edi, %eax - - shrl %cl, %edi - - movl %edi, (%edx) - popl %edi - - popl %ebx - - ret - - - - - - .align 8, 0x90 -.Lsimple: - - - - - - - - - - movd (%ebx), %mm5 - leal (%ebx,%eax,4), %ebx - - movd %ecx, %mm6 - leal -4(%edx,%eax,4), %edx - - psllq $32, %mm5 - negl %eax - - - - - - - -.Lsimple_top: - - - - - - - - - - movq (%ebx,%eax,4), %mm0 - incl %eax - - psrlq %mm6, %mm0 - - movd %mm0, (%edx,%eax,4) - jnz .Lsimple_top - - - movd (%ebx), %mm0 - psrlq %mm6, %mm5 - - psrlq %mm6, %mm0 - popl %edi - - movd %mm5, %eax - popl %ebx - - movd %mm0, 4(%edx) - - emms - - ret - - - - - - .align 8, 0x90 -.Lunroll: - - - - - - - - - - movd (%ebx), %mm5 - movl $4, %edi - - movd %ecx, %mm6 - testl %edi, %ebx - - psllq $32, %mm5 - jz .Lstart_src_aligned - - - - - - - - - - - - - - - - - movq (%ebx), %mm0 - - psrlq %mm6, %mm0 - addl $4, %ebx - - decl %eax - - movd %mm0, (%edx) - addl $4, %edx -.Lstart_src_aligned: - - - movq (%ebx), %mm1 - testl %edi, %edx - - psrlq %mm6, %mm5 - jz .Lstart_dst_aligned - - - - - - - - - - - - - - - - - - movq %mm1, %mm0 - addl $32, %ecx - - psrlq %mm6, %mm0 - - movd %ecx, %mm6 - - movd %mm0, (%edx) - addl $4, %edx -.Lstart_dst_aligned: - - - movq 8(%ebx), %mm3 - negl %ecx - - movq %mm3, %mm2 - addl $64, %ecx - - movd %ecx, %mm7 - psrlq %mm6, %mm1 - - leal -12(%ebx,%eax,4), %ebx - leal -20(%edx,%eax,4), %edx - - psllq %mm7, %mm3 - subl $7, %eax - - por %mm1, %mm3 - negl %eax - - jns .Lfinish - - - - - - - - - - - - - - - - .align 8, 0x90 -.Lunroll_loop: - - - - - - - - - - - - - - - - - movq (%ebx,%eax,4), %mm0 - psrlq %mm6, %mm2 - - movq %mm0, %mm1 - psllq %mm7, %mm0 - - movq %mm3, -8(%edx,%eax,4) - por %mm2, %mm0 - - movq 8(%ebx,%eax,4), %mm3 - psrlq %mm6, %mm1 - - movq %mm0, (%edx,%eax,4) - movq %mm3, %mm2 - - psllq %mm7, %mm3 - addl $4, %eax - - por %mm1, %mm3 - js .Lunroll_loop - - -.Lfinish: - - - testb $2, %al - - jnz .Lfinish_no_two - - movq (%ebx,%eax,4), %mm0 - psrlq %mm6, %mm2 - - movq %mm0, %mm1 - psllq %mm7, %mm0 - - movq %mm3, -8(%edx,%eax,4) - por %mm2, %mm0 - - movq %mm1, %mm2 - movq %mm0, %mm3 - - addl $2, %eax -.Lfinish_no_two: - - - - - - - - testb $1, %al - popl %edi - - movd %mm5, %eax - jnz .Lfinish_zero - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - movd 8(%ebx), %mm0 - psrlq %mm6, %mm2 - - movq %mm0, %mm1 - psllq %mm7, %mm0 - - movq %mm3, (%edx) - por %mm2, %mm0 - - psrlq %mm6, %mm1 - andl $32, %ecx - - popl %ebx - jz .Lfinish_one_unaligned - - - movd %mm1, 16(%edx) -.Lfinish_one_unaligned: - - movq %mm0, 8(%edx) - - emms - - ret - - - - -.Lfinish_zero: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - movq %mm3, 4(%edx) - psrlq %mm6, %mm2 - - movd %mm2, 12(%edx) - andl $32, %ecx - - popl %ebx - jz .Lfinish_zero_unaligned - - movq %mm2, 12(%edx) -.Lfinish_zero_unaligned: - - emms - - ret diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/distfiles b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/distfiles deleted file mode 100644 index 7252cd7e3..000000000 --- a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/distfiles +++ /dev/null @@ -1,5 +0,0 @@ -mpih-add1.S -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S -mpih-sub1.S diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-add1.S deleted file mode 100644 index 55ed66303..000000000 --- a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-add1.S +++ /dev/null @@ -1,91 +0,0 @@ -/* Intel Pentium-4 mpn_add_n -- mpn addition. - * - * Copyright 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - - /******************* - * mpi_limb_t - * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_ptr_t s2_ptr, (sp + 12) - * mpi_size_t size) (sp + 16) - * - * P4 Willamette, Northwood: 4.0 cycles/limb if dst!=src1 and dst!=src2 - * 6.0 cycles/limb if dst==src1 or dst==src2 - * P4 Prescott: >= 5 cycles/limb - * - * The 4 c/l achieved here isn't particularly good, but is better than 9 c/l - * for a basic adc loop. - */ - - TEXT - ALIGN (3) - GLOBL C_SYMBOL_NAME(_gcry_mpih_add_n) -C_SYMBOL_NAME(_gcry_mpih_add_n:) - - pxor %mm0, %mm0 - - movl 8(%esp), %eax /* s1_ptr */ - movl %ebx, 8(%esp) /* re-use parameter space */ - movl 12(%esp), %ebx /* res_ptr */ - movl 4(%esp), %edx /* s2_ptr */ - movl 16(%esp), %ecx /* size */ - - leal (%eax,%ecx,4), %eax /* src1 end */ - leal (%ebx,%ecx,4), %ebx /* src2 end */ - leal (%edx,%ecx,4), %edx /* dst end */ - negl %ecx /* -size */ - -Ltop: -/* - C eax src1 end - C ebx src2 end - C ecx counter, limbs, negative - C edx dst end - C mm0 carry bit -*/ - - movd (%eax,%ecx,4), %mm1 - movd (%ebx,%ecx,4), %mm2 - paddq %mm2, %mm1 - - paddq %mm1, %mm0 - movd %mm0, (%edx,%ecx,4) - - psrlq $32, %mm0 - - addl $1, %ecx - jnz Ltop - - - movd %mm0, %eax - movl 8(%esp), %ebx /* restore saved EBX */ - emms - ret diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S deleted file mode 100644 index a0c98fb4d..000000000 --- a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S +++ /dev/null @@ -1,96 +0,0 @@ -/* Intel Pentium-4 mpn_mul_1 -- Multiply a limb vector with a limb and store - * the result in a second limb vector. - * - * Copyright 2001, 2002, 2003, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_size_t s1_size, (sp + 12) - * mpi_limb_t s2_limb) (sp + 16) - * - * src != dst src == dst - * P6 model 9 (Banias) ?.? - * P6 model 13 (Dothan) 4.75 4.75 - * P4 model 0 (Willamette) 4.0 6.0 - * P4 model 1 (?) 4.0 6.0 - * P4 model 2 (Northwood) 4.0 6.0 - * P4 model 3 (Prescott) ?.? ?.? - * P4 model 4 (Nocona) ?.? ?.? - * Unfortunately when src==dst the write-combining described in - * pentium4/README takes us up to 6 c/l. - * - */ - - TEXT - ALIGN (3) - GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1) -C_SYMBOL_NAME(_gcry_mpih_mul_1:); - - pxor %mm0, %mm0 - -.Lstart_1c: - movl 8(%esp), %eax - movd 16(%esp), %mm7 - movl 4(%esp), %edx - movl 12(%esp), %ecx - -.Ltop: - -/* - C eax src, incrementing - C ebx - C ecx counter, size iterations - C edx dst, incrementing - C - C mm0 carry limb - C mm7 multiplier -*/ - - movd (%eax), %mm1 - addl $4, %eax - pmuludq %mm7, %mm1 - - paddq %mm1, %mm0 - movd %mm0, (%edx) - addl $4, %edx - - psrlq $32, %mm0 - - subl $1, %ecx - jnz .Ltop - - - movd %mm0, %eax - emms - ret - diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S deleted file mode 100644 index f975adfca..000000000 --- a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S +++ /dev/null @@ -1,136 +0,0 @@ -/* Intel Pentium-4 mpn_addmul_1 -- Multiply a limb vector with a limb and add - * the result to a second limb vector. - * - * Copyright 2001, 2002, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_size_t s1_size, (sp + 12) - * mpi_limb_t s2_limb) (sp + 16) - * - * P3 model 9 (Banias) ?.? - * P3 model 13 (Dothan) 5.8 - * P4 model 0 (Willamette) 5.5 - * P4 model 1 (?) 5.5 - * P4 model 2 (Northwood) 5.5 - * P4 model 3 (Prescott) 6.0 - * P4 model 4 (Nocona) - * - * Only the carry limb propagation is on the dependent chain, but some other - * Pentium4 pipeline magic brings down performance to 6 cycles/l from the - * ideal 4 cycles/l. - */ - - - TEXT - ALIGN (4) - GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1) -C_SYMBOL_NAME(_gcry_mpih_addmul_1:) - - pxor %mm4, %mm4 -.Lstart_1c: - movl 8(%esp), %eax - movl 12(%esp), %ecx - movl 4(%esp), %edx - movd 16(%esp), %mm7 - -/* - C eax src, incrementing ; 5B - C ecx loop counter, decrementing - C edx dst, incrementing - C - C mm4 carry, low 32-bits - C mm7 multiplier -*/ - - movd (%eax), %mm2 - pmuludq %mm7, %mm2 - - shrl $1, %ecx - jnc .Leven - - leal 4(%eax), %eax - movd (%edx), %mm1 - paddq %mm2, %mm1 - paddq %mm1, %mm4 - movd %mm4, (%edx) - psrlq $32, %mm4 - - testl %ecx, %ecx - jz .Lrtn - leal 4(%edx), %edx - - movd (%eax), %mm2 - pmuludq %mm7, %mm2 -.Leven: - movd 4(%eax), %mm0 - movd (%edx), %mm1 - pmuludq %mm7, %mm0 - - subl $1, %ecx - jz .Lend -.Lloop: - paddq %mm2, %mm1 - movd 8(%eax), %mm2 - paddq %mm1, %mm4 - movd 4(%edx), %mm3 - pmuludq %mm7, %mm2 - movd %mm4, (%edx) - psrlq $32, %mm4 - - paddq %mm0, %mm3 - movd 12(%eax), %mm0 - paddq %mm3, %mm4 - movd 8(%edx), %mm1 - pmuludq %mm7, %mm0 - movd %mm4, 4(%edx) - psrlq $32, %mm4 - - leal 8(%eax), %eax - leal 8(%edx), %edx - subl $1, %ecx - jnz .Lloop -.Lend: - paddq %mm2, %mm1 - paddq %mm1, %mm4 - movd 4(%edx), %mm3 - movd %mm4, (%edx) - psrlq $32, %mm4 - paddq %mm0, %mm3 - paddq %mm3, %mm4 - movd %mm4, 4(%edx) - psrlq $32, %mm4 -.Lrtn: - movd %mm4, %eax - emms - ret diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S deleted file mode 100644 index ebcd2a68e..000000000 --- a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S +++ /dev/null @@ -1,127 +0,0 @@ -/* Intel Pentium-4 mpn_submul_1 -- Multiply a limb vector with a limb and - * subtract the result from a second limb vector. - * - * Copyright 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_size_t s1_size, (sp + 12) - * mpi_limb_t s2_limb) (sp + 16) - * - * P4: 7 cycles/limb, unstable timing, at least on early Pentium4 silicon - * (stepping 10). - * - * This code is not particularly good at 7 c/l. The dependent chain is only - * 4 c/l and there's only 4 MMX unit instructions, so it's not clear why that - * speed isn't achieved. - * - * The arrangements made here to get a two instruction dependent chain are - * slightly subtle. In the loop the carry (or borrow rather) is a negative - * so that a paddq can be used to give a low limb ready to store, and a high - * limb ready to become the new carry after a psrlq. - * - * If the carry was a simple twos complement negative then the psrlq shift - * would need to bring in 0 bits or 1 bits according to whether the high was - * zero or non-zero, since a non-zero value would represent a negative - * needing sign extension. That wouldn't be particularly easy to arrange and - * certainly would add an instruction to the dependent chain, so instead an - * offset is applied so that the high limb will be 0xFFFFFFFF+c. With c in - * the range -0xFFFFFFFF to 0, the value 0xFFFFFFFF+c is in the range 0 to - * 0xFFFFFFFF and is therefore always positive and can always have 0 bits - * shifted in, which is what psrlq does. - * - * The extra 0xFFFFFFFF must be subtracted before c is used, but that can be - * done off the dependent chain. The total adjustment then is to add - * 0xFFFFFFFF00000000 to offset the new carry, and subtract - * 0x00000000FFFFFFFF to remove the offset from the current carry, for a net - * add of 0xFFFFFFFE00000001. In the code this is applied to the destination - * limb when fetched. - * - * It's also possible to view the 0xFFFFFFFF adjustment as a ones-complement - * negative, which is how it's undone for the return value, but that doesn't - * seem as clear. -*/ - - TEXT - ALIGN (4) - GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1) -C_SYMBOL_NAME(_gcry_mpih_submul_1:) - - pxor %mm1, %mm1 - -.Lstart_1c: - movl 8(%esp), %eax - pcmpeqd %mm0, %mm0 - - movd 16(%esp), %mm7 - pcmpeqd %mm6, %mm6 - - movl 4(%esp), %edx - psrlq $32, %mm0 - - movl 12(%esp), %ecx - psllq $32, %mm6 - - psubq %mm0, %mm6 - - psubq %mm1, %mm0 - -/* - C eax src, incrementing - C ebx - C ecx loop counter, decrementing - C edx dst, incrementing - C - C mm0 0xFFFFFFFF - borrow - C mm6 0xFFFFFFFE00000001 - C mm7 multiplier -*/ - -.Lloop: - movd (%eax), %mm1 - leal 4(%eax), %eax - movd (%edx), %mm2 - paddq %mm6, %mm2 - pmuludq %mm7, %mm1 - psubq %mm1, %mm2 - paddq %mm2, %mm0 - subl $1, %ecx - movd %mm0, (%edx) - psrlq $32, %mm0 - leal 4(%edx), %edx - jnz .Lloop - - movd %mm0, %eax - notl %eax - emms - ret diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S deleted file mode 100644 index 33900c742..000000000 --- a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S +++ /dev/null @@ -1,112 +0,0 @@ -/* Intel Pentium-4 mpn_sub_n -- mpn subtraction. - * - * Copyright 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -/******************* - * mpi_limb_t - * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4) - * mpi_ptr_t s1_ptr, (sp + 8) - * mpi_ptr_t s2_ptr, (sp + 12) - * mpi_size_t size) (sp + 16) - * - * P4 Willamette, Northwood: 4.0 cycles/limb if dst!=src1 and dst!=src2 - * 6.0 cycles/limb if dst==src1 or dst==src2 - * P4 Prescott: >= 5 cycles/limb - * - * The main loop code is 2x unrolled so that the carry bit can alternate - * between mm0 and mm1. - */ - - -.text - ALIGN (3) - .globl C_SYMBOL_NAME(_gcry_mpih_sub_n) -C_SYMBOL_NAME(_gcry_mpih_sub_n:) - - pxor %mm0, %mm0 -.Lstart_nc: - movl 8(%esp), %eax - movl %ebx, 8(%esp) - movl 12(%esp), %ebx - movl 4(%esp), %edx - movl 16(%esp), %ecx - - leal (%eax,%ecx,4), %eax - leal (%ebx,%ecx,4), %ebx - leal (%edx,%ecx,4), %edx - negl %ecx - -.Ltop: -/* - C eax src1 end - C ebx src2 end - C ecx counter, limbs, negative - C edx dst end - C mm0 carry bit -*/ - - movd (%eax,%ecx,4), %mm1 - movd (%ebx,%ecx,4), %mm2 - psubq %mm2, %mm1 - - psubq %mm0, %mm1 - movd %mm1, (%edx,%ecx,4) - - psrlq $63, %mm1 - - addl $1, %ecx - jz .Ldone_mm1 - - movd (%eax,%ecx,4), %mm0 - movd (%ebx,%ecx,4), %mm2 - psubq %mm2, %mm0 - - psubq %mm1, %mm0 - movd %mm0, (%edx,%ecx,4) - - psrlq $63, %mm0 - - addl $1, %ecx - jnz .Ltop - - - movd %mm0, %eax - movl 8(%esp), %ebx - emms - ret - - - -.Ldone_mm1: - movd %mm1, %eax - movl 8(%esp), %ebx - emms - ret diff --git a/grub-core/lib/libgcrypt/mpi/power/Manifest b/grub-core/lib/libgcrypt/mpi/power/Manifest deleted file mode 100644 index c60fc23c2..000000000 --- a/grub-core/lib/libgcrypt/mpi/power/Manifest +++ /dev/null @@ -1,27 +0,0 @@ -# Manifest - checksums -# Copyright 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 - -mpih-add1.S -mpih-lshift.S -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S -mpih-rshift.S -mpih-sub1.S -$names$ iQCVAwUAP+LmXTEAnp832S/7AQJ+ngP/XYr5Fvl/8WGVHcIKaehxvnKcSD2ILTWZNGubgnWp8ebIxVijjQCxYneTTy+zO0sNaB002neyscyiwaJj/JQIwZXfr06uGweIqlSpwpj9ndkoJc8E4/FZu+5NTO+E3RaBDAD+Tpo+MTfbC1s18p5i+an93VrSTgNck5PPYQrUcPA==sl3t diff --git a/grub-core/lib/libgcrypt/mpi/power/distfiles b/grub-core/lib/libgcrypt/mpi/power/distfiles deleted file mode 100644 index e1bc008bc..000000000 --- a/grub-core/lib/libgcrypt/mpi/power/distfiles +++ /dev/null @@ -1,8 +0,0 @@ -Manifest -mpih-add1.S -mpih-lshift.S -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S -mpih-rshift.S -mpih-sub1.S diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/power/mpih-add1.S deleted file mode 100644 index 876b56c66..000000000 --- a/grub-core/lib/libgcrypt/mpi/power/mpih-add1.S +++ /dev/null @@ -1,87 +0,0 @@ -/* IBM POWER add_n -- Add two limb vectors of equal, non-zero length. - * - * Copyright (C) 1992, 1994, 1996, 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 - */ - -#include "sysdep.h" -#include "asm-syntax.h" - -/* -# INPUT PARAMETERS -# res_ptr r3 -# s1_ptr r4 -# s2_ptr r5 -# size r6 - */ - - .toc - .extern _gcry_mpih_add_n[DS] - .extern ._gcry_mpih_add_n -.csect [PR] - .align 2 - .globl _gcry_mpih_add_n - .globl ._gcry_mpih_add_n - .csect _gcry_mpih_add_n[DS] -_gcry_mpih_add_n: - .long ._gcry_mpih_add_n, TOC[tc0], 0 - .csect [PR] -._gcry_mpih_add_n: - andil. 10,6,1 # odd or even number of limbs? - l 8,0(4) # load least significant s1 limb - l 0,0(5) # load least significant s2 limb - cal 3,-4(3) # offset res_ptr, it's updated before it's used - sri 10,6,1 # count for unrolled loop - a 7,0,8 # add least significant limbs, set cy - mtctr 10 # copy count into CTR - beq 0,Leven # branch if even # of limbs (# of limbs >= 2) - -# We have an odd # of limbs. Add the first limbs separately. - cmpi 1,10,0 # is count for unrolled loop zero? - bne 1,L1 # branch if not - st 7,4(3) - aze 3,10 # use the fact that r10 is zero... - br # return - -# We added least significant limbs. Now reload the next limbs to enter loop. -L1: lu 8,4(4) # load s1 limb and update s1_ptr - lu 0,4(5) # load s2 limb and update s2_ptr - stu 7,4(3) - ae 7,0,8 # add limbs, set cy -Leven: lu 9,4(4) # load s1 limb and update s1_ptr - lu 10,4(5) # load s2 limb and update s2_ptr - bdz Lend # If done, skip loop - -Loop: lu 8,4(4) # load s1 limb and update s1_ptr - lu 0,4(5) # load s2 limb and update s2_ptr - ae 11,9,10 # add previous limbs with cy, set cy - stu 7,4(3) # - lu 9,4(4) # load s1 limb and update s1_ptr - lu 10,4(5) # load s2 limb and update s2_ptr - ae 7,0,8 # add previous limbs with cy, set cy - stu 11,4(3) # - bdn Loop # decrement CTR and loop back - -Lend: ae 11,9,10 # add limbs with cy, set cy - st 7,4(3) # - st 11,8(3) # - lil 3,0 # load cy into ... - aze 3,3 # ... return value register - br - diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/power/mpih-lshift.S deleted file mode 100644 index d9e42daf8..000000000 --- a/grub-core/lib/libgcrypt/mpi/power/mpih-lshift.S +++ /dev/null @@ -1,64 +0,0 @@ -/* IBM POWER lshift - * - * Copyright (C) 1992, 1994, 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 - */ - -#include "sysdep.h" -#include "asm-syntax.h" - -/* -# INPUT PARAMETERS -# res_ptr r3 -# s_ptr r4 -# size r5 -# cnt r6 - */ - - .toc - .extern _gcry_mpih_lshift[DS] - .extern ._gcry_mpih_lshift -.csect [PR] - .align 2 - .globl _gcry_mpih_lshift - .globl ._gcry_mpih_lshift - .csect _gcry_mpih_lshift[DS] -_gcry_mpih_lshift: - .long ._gcry_mpih_lshift, TOC[tc0], 0 - .csect [PR] -._gcry_mpih_lshift: - sli 0,5,2 - cax 9,3,0 - cax 4,4,0 - sfi 8,6,32 - mtctr 5 # put limb count in CTR loop register - lu 0,-4(4) # read most significant limb - sre 3,0,8 # compute carry out limb, and init MQ register - bdz Lend2 # if just one limb, skip loop - lu 0,-4(4) # read 2:nd most significant limb - sreq 7,0,8 # compute most significant limb of result - bdz Lend # if just two limb, skip loop -Loop: lu 0,-4(4) # load next lower limb - stu 7,-4(9) # store previous result during read latency - sreq 7,0,8 # compute result limb - bdn Loop # loop back until CTR is zero -Lend: stu 7,-4(9) # store 2:nd least significant limb -Lend2: sle 7,0,6 # compute least significant limb - st 7,-4(9) # store it - br - diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/power/mpih-mul1.S deleted file mode 100644 index 35034fa40..000000000 --- a/grub-core/lib/libgcrypt/mpi/power/mpih-mul1.S +++ /dev/null @@ -1,115 +0,0 @@ -/* IBM POWER mul_1 -- Multiply a limb vector with a limb and store - * the result in a second limb vector. - * - * Copyright (C) 1992, 1994, 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 - */ - -#include "sysdep.h" -#include "asm-syntax.h" - -/* -# INPUT PARAMETERS -# res_ptr r3 -# s1_ptr r4 -# size r5 -# s2_limb r6 - -# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To -# obtain that operation, we have to use the 32x32->64 signed multiplication -# instruction, and add the appropriate compensation to the high limb of the -# result. We add the multiplicand if the multiplier has its most significant -# bit set, and we add the multiplier if the multiplicand has its most -# significant bit set. We need to preserve the carry flag between each -# iteration, so we have to compute the compensation carefully (the natural, -# srai+and doesn't work). Since the POWER architecture has a branch unit -# we can branch in zero cycles, so that's how we perform the additions. - */ - - .toc - .csect ._gcry_mpih_mul_1[PR] - .align 2 - .globl _gcry_mpih_mul_1 - .globl ._gcry_mpih_mul_1 - .csect _gcry_mpih_mul_1[DS] -_gcry_mpih_mul_1: - .long ._gcry_mpih_mul_1[PR], TOC[tc0], 0 - .csect ._gcry_mpih_mul_1[PR] -._gcry_mpih_mul_1: - - cal 3,-4(3) - l 0,0(4) - cmpi 0,6,0 - mtctr 5 - mul 9,0,6 - srai 7,0,31 - and 7,7,6 - mfmq 8 - ai 0,0,0 # reset carry - cax 9,9,7 - blt Lneg -Lpos: bdz Lend -Lploop: lu 0,4(4) - stu 8,4(3) - cmpi 0,0,0 - mul 10,0,6 - mfmq 0 - ae 8,0,9 - bge Lp0 - cax 10,10,6 # adjust high limb for negative limb from s1 -Lp0: bdz Lend0 - lu 0,4(4) - stu 8,4(3) - cmpi 0,0,0 - mul 9,0,6 - mfmq 0 - ae 8,0,10 - bge Lp1 - cax 9,9,6 # adjust high limb for negative limb from s1 -Lp1: bdn Lploop - b Lend - -Lneg: cax 9,9,0 - bdz Lend -Lnloop: lu 0,4(4) - stu 8,4(3) - cmpi 0,0,0 - mul 10,0,6 - cax 10,10,0 # adjust high limb for negative s2_limb - mfmq 0 - ae 8,0,9 - bge Ln0 - cax 10,10,6 # adjust high limb for negative limb from s1 -Ln0: bdz Lend0 - lu 0,4(4) - stu 8,4(3) - cmpi 0,0,0 - mul 9,0,6 - cax 9,9,0 # adjust high limb for negative s2_limb - mfmq 0 - ae 8,0,10 - bge Ln1 - cax 9,9,6 # adjust high limb for negative limb from s1 -Ln1: bdn Lnloop - b Lend - -Lend0: cal 9,0(10) -Lend: st 8,4(3) - aze 3,9 - br - diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/power/mpih-mul2.S deleted file mode 100644 index d056e8f3c..000000000 --- a/grub-core/lib/libgcrypt/mpi/power/mpih-mul2.S +++ /dev/null @@ -1,130 +0,0 @@ -/* IBM POWER addmul_1 -- Multiply a limb vector with a limb and add - * the result to a second limb vector. - * - * Copyright (C) 1992, 1994, 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 - */ - -#include "sysdep.h" -#include "asm-syntax.h" - - - -/* -# INPUT PARAMETERS -# res_ptr r3 -# s1_ptr r4 -# size r5 -# s2_limb r6 - -# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To -# obtain that operation, we have to use the 32x32->64 signed multiplication -# instruction, and add the appropriate compensation to the high limb of the -# result. We add the multiplicand if the multiplier has its most significant -# bit set, and we add the multiplier if the multiplicand has its most -# significant bit set. We need to preserve the carry flag between each -# iteration, so we have to compute the compensation carefully (the natural, -# srai+and doesn't work). Since the POWER architecture has a branch unit -# we can branch in zero cycles, so that's how we perform the additions. - */ - - .toc - .csect ._gcry_mpih_addmul_1[PR] - .align 2 - .globl _gcry_mpih_addmul_1 - .globl ._gcry_mpih_addmul_1 - .csect _gcry_mpih_addmul_1[DS] -_gcry_mpih_addmul_1: - .long ._gcry_mpih_addmul_1[PR], TOC[tc0], 0 - .csect ._gcry_mpih_addmul_1[PR] -._gcry_mpih_addmul_1: - - cal 3,-4(3) - l 0,0(4) - cmpi 0,6,0 - mtctr 5 - mul 9,0,6 - srai 7,0,31 - and 7,7,6 - mfmq 8 - cax 9,9,7 - l 7,4(3) - a 8,8,7 # add res_limb - blt Lneg -Lpos: bdz Lend - -Lploop: lu 0,4(4) - stu 8,4(3) - cmpi 0,0,0 - mul 10,0,6 - mfmq 0 - ae 8,0,9 # low limb + old_cy_limb + old cy - l 7,4(3) - aze 10,10 # propagate cy to new cy_limb - a 8,8,7 # add res_limb - bge Lp0 - cax 10,10,6 # adjust high limb for negative limb from s1 -Lp0: bdz Lend0 - lu 0,4(4) - stu 8,4(3) - cmpi 0,0,0 - mul 9,0,6 - mfmq 0 - ae 8,0,10 - l 7,4(3) - aze 9,9 - a 8,8,7 - bge Lp1 - cax 9,9,6 # adjust high limb for negative limb from s1 -Lp1: bdn Lploop - - b Lend - -Lneg: cax 9,9,0 - bdz Lend -Lnloop: lu 0,4(4) - stu 8,4(3) - cmpi 0,0,0 - mul 10,0,6 - mfmq 7 - ae 8,7,9 - l 7,4(3) - ae 10,10,0 # propagate cy to new cy_limb - a 8,8,7 # add res_limb - bge Ln0 - cax 10,10,6 # adjust high limb for negative limb from s1 -Ln0: bdz Lend0 - lu 0,4(4) - stu 8,4(3) - cmpi 0,0,0 - mul 9,0,6 - mfmq 7 - ae 8,7,10 - l 7,4(3) - ae 9,9,0 # propagate cy to new cy_limb - a 8,8,7 # add res_limb - bge Ln1 - cax 9,9,6 # adjust high limb for negative limb from s1 -Ln1: bdn Lnloop - b Lend - -Lend0: cal 9,0(10) -Lend: st 8,4(3) - aze 3,9 - br - diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/power/mpih-mul3.S deleted file mode 100644 index 8bc317b76..000000000 --- a/grub-core/lib/libgcrypt/mpi/power/mpih-mul3.S +++ /dev/null @@ -1,135 +0,0 @@ -/* IBM POWER submul_1 -- Multiply a limb vector with a limb and subtract - * the result from a second limb vector. - * - * Copyright (C) 1992, 1994, 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 - */ - -#include "sysdep.h" -#include "asm-syntax.h" - - -/* - -# INPUT PARAMETERS -# res_ptr r3 -# s1_ptr r4 -# size r5 -# s2_limb r6 - -# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To -# obtain that operation, we have to use the 32x32->64 signed multiplication -# instruction, and add the appropriate compensation to the high limb of the -# result. We add the multiplicand if the multiplier has its most significant -# bit set, and we add the multiplier if the multiplicand has its most -# significant bit set. We need to preserve the carry flag between each -# iteration, so we have to compute the compensation carefully (the natural, -# srai+and doesn't work). Since the POWER architecture has a branch unit -# we can branch in zero cycles, so that's how we perform the additions. - */ - - .toc - .csect ._gcry_mpih_submul_1[PR] - .align 2 - .globl _gcry_mpih_submul_1 - .globl ._gcry_mpih_submul_1 - .csect _gcry_mpih_submul_1[DS] -_gcry_mpih_submul_1: - .long ._gcry_mpih_submul_1[PR], TOC[tc0], 0 - .csect ._gcry_mpih_submul_1[PR] -._gcry_mpih_submul_1: - - cal 3,-4(3) - l 0,0(4) - cmpi 0,6,0 - mtctr 5 - mul 9,0,6 - srai 7,0,31 - and 7,7,6 - mfmq 11 - cax 9,9,7 - l 7,4(3) - sf 8,11,7 # add res_limb - a 11,8,11 # invert cy (r11 is junk) - blt Lneg -Lpos: bdz Lend - -Lploop: lu 0,4(4) - stu 8,4(3) - cmpi 0,0,0 - mul 10,0,6 - mfmq 0 - ae 11,0,9 # low limb + old_cy_limb + old cy - l 7,4(3) - aze 10,10 # propagate cy to new cy_limb - sf 8,11,7 # add res_limb - a 11,8,11 # invert cy (r11 is junk) - bge Lp0 - cax 10,10,6 # adjust high limb for negative limb from s1 -Lp0: bdz Lend0 - lu 0,4(4) - stu 8,4(3) - cmpi 0,0,0 - mul 9,0,6 - mfmq 0 - ae 11,0,10 - l 7,4(3) - aze 9,9 - sf 8,11,7 - a 11,8,11 # invert cy (r11 is junk) - bge Lp1 - cax 9,9,6 # adjust high limb for negative limb from s1 -Lp1: bdn Lploop - - b Lend - -Lneg: cax 9,9,0 - bdz Lend -Lnloop: lu 0,4(4) - stu 8,4(3) - cmpi 0,0,0 - mul 10,0,6 - mfmq 7 - ae 11,7,9 - l 7,4(3) - ae 10,10,0 # propagate cy to new cy_limb - sf 8,11,7 # add res_limb - a 11,8,11 # invert cy (r11 is junk) - bge Ln0 - cax 10,10,6 # adjust high limb for negative limb from s1 -Ln0: bdz Lend0 - lu 0,4(4) - stu 8,4(3) - cmpi 0,0,0 - mul 9,0,6 - mfmq 7 - ae 11,7,10 - l 7,4(3) - ae 9,9,0 # propagate cy to new cy_limb - sf 8,11,7 # add res_limb - a 11,8,11 # invert cy (r11 is junk) - bge Ln1 - cax 9,9,6 # adjust high limb for negative limb from s1 -Ln1: bdn Lnloop - b Lend - -Lend0: cal 9,0(10) -Lend: st 8,4(3) - aze 3,9 - br - diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/power/mpih-rshift.S deleted file mode 100644 index f131a86d7..000000000 --- a/grub-core/lib/libgcrypt/mpi/power/mpih-rshift.S +++ /dev/null @@ -1,64 +0,0 @@ -/* IBM POWER rshift - * - * Copyright (C) 1992, 1994, 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 - */ - -#include "sysdep.h" -#include "asm-syntax.h" - - -/* -# INPUT PARAMETERS -# res_ptr r3 -# s_ptr r4 -# size r5 -# cnt r6 -*/ - - .toc - .extern _gcry_mpih_rshift[DS] - .extern ._gcry_mpih_rshift -.csect [PR] - .align 2 - .globl _gcry_mpih_rshift - .globl ._gcry_mpih_rshift - .csect _gcry_mpih_rshift[DS] -_gcry_mpih_rshift: - .long ._gcry_mpih_rshift, TOC[tc0], 0 - .csect [PR] -._gcry_mpih_rshift: - sfi 8,6,32 - mtctr 5 # put limb count in CTR loop register - l 0,0(4) # read least significant limb - ai 9,3,-4 # adjust res_ptr since it's offset in the stu:s - sle 3,0,8 # compute carry limb, and init MQ register - bdz Lend2 # if just one limb, skip loop - lu 0,4(4) # read 2:nd least significant limb - sleq 7,0,8 # compute least significant limb of result - bdz Lend # if just two limb, skip loop -Loop: lu 0,4(4) # load next higher limb - stu 7,4(9) # store previous result during read latency - sleq 7,0,8 # compute result limb - bdn Loop # loop back until CTR is zero -Lend: stu 7,4(9) # store 2:nd most significant limb -Lend2: sre 7,0,6 # compute most significant limb - st 7,4(9) # store it - br - - diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/power/mpih-sub1.S deleted file mode 100644 index 02748fc55..000000000 --- a/grub-core/lib/libgcrypt/mpi/power/mpih-sub1.S +++ /dev/null @@ -1,88 +0,0 @@ -/* IBM POWER sub_n -- Subtract two limb vectors of equal, non-zero length. - * - * Copyright (C) 1992, 1994, 1995, 1996, 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 - */ - -#include "sysdep.h" -#include "asm-syntax.h" - -/* -# INPUT PARAMETERS -# res_ptr r3 -# s1_ptr r4 -# s2_ptr r5 -# size r6 - */ - - .toc - .extern _gcry_mpih_sub_n[DS] - .extern ._gcry_mpih_sub_n -.csect [PR] - .align 2 - .globl _gcry_mpih_sub_n - .globl ._gcry_mpih_sub_n - .csect _gcry_mpih_sub_n[DS] -_gcry_mpih_sub_n: - .long ._gcry_mpih_sub_n, TOC[tc0], 0 - .csect [PR] -._gcry_mpih_sub_n: - andil. 10,6,1 # odd or even number of limbs? - l 8,0(4) # load least significant s1 limb - l 0,0(5) # load least significant s2 limb - cal 3,-4(3) # offset res_ptr, it's updated before it's used - sri 10,6,1 # count for unrolled loop - sf 7,0,8 # subtract least significant limbs, set cy - mtctr 10 # copy count into CTR - beq 0,Leven # branch if even # of limbs (# of limbs >= 2) - -# We have an odd # of limbs. Add the first limbs separately. - cmpi 1,10,0 # is count for unrolled loop zero? - bne 1,L1 # branch if not - st 7,4(3) - sfe 3,0,0 # load !cy into ... - sfi 3,3,0 # ... return value register - br # return - -# We added least significant limbs. Now reload the next limbs to enter loop. -L1: lu 8,4(4) # load s1 limb and update s1_ptr - lu 0,4(5) # load s2 limb and update s2_ptr - stu 7,4(3) - sfe 7,0,8 # subtract limbs, set cy -Leven: lu 9,4(4) # load s1 limb and update s1_ptr - lu 10,4(5) # load s2 limb and update s2_ptr - bdz Lend # If done, skip loop - -Loop: lu 8,4(4) # load s1 limb and update s1_ptr - lu 0,4(5) # load s2 limb and update s2_ptr - sfe 11,10,9 # subtract previous limbs with cy, set cy - stu 7,4(3) # - lu 9,4(4) # load s1 limb and update s1_ptr - lu 10,4(5) # load s2 limb and update s2_ptr - sfe 7,0,8 # subtract previous limbs with cy, set cy - stu 11,4(3) # - bdn Loop # decrement CTR and loop back - -Lend: sfe 11,10,9 # subtract limbs with cy, set cy - st 7,4(3) # - st 11,8(3) # - sfe 3,0,0 # load !cy into ... - sfi 3,3,0 # ... return value register - br - diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/Manifest b/grub-core/lib/libgcrypt/mpi/powerpc32/Manifest deleted file mode 100644 index 26ab6ea3e..000000000 --- a/grub-core/lib/libgcrypt/mpi/powerpc32/Manifest +++ /dev/null @@ -1,28 +0,0 @@ -# Manifest - checksums -# Copyright 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 - -mpih-add1.S -mpih-sub1.S -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S -mpih-lshift.S -mpih-rshift.S -syntax.h -$names$ iQCVAwUAP+LmYzEAnp832S/7AQI/cQP+Mcg9rF/c/bJTY48PE1/ARt7vCMtpIlv9alZSSSrU3WHzCtv9nVczFmwHU3DdKFawigY2DljQcK92dZ5ZlOfpFNMz4PKlVMWaKDk+jKlqm2dxvlHuqEvXPpjFAE2gHrhq5qLXS5ZHeMLJIEK84GYC6fjfLUMdZU3altXTUBvoXhA==Yax+ diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/distfiles b/grub-core/lib/libgcrypt/mpi/powerpc32/distfiles deleted file mode 100644 index a08661489..000000000 --- a/grub-core/lib/libgcrypt/mpi/powerpc32/distfiles +++ /dev/null @@ -1,10 +0,0 @@ -Manifest -mpih-add1.S -mpih-sub1.S -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S -mpih-lshift.S -mpih-rshift.S -syntax.h - diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-add1.S deleted file mode 100644 index 1661f5e67..000000000 --- a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-add1.S +++ /dev/null @@ -1,136 +0,0 @@ -/* PowerPC-32 add_n -- Add two limb vectors of equal, non-zero length. - * - * Copyright (C) 1992, 1994, 1995, 1998, 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 - */ - -#include "sysdep.h" -#include "asm-syntax.h" - - -#ifndef USE_PPC_PATCHES - -/******************* - * mpi_limb_t - * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (r3) - * mpi_ptr_t s1_ptr, (r4) - * mpi_ptr_t s2_ptr, (r5) - * mpi_size_t size) (r6) - */ - - .toc - .extern _gcry_mpih_add_n[DS] - .extern ._gcry_mpih_add_n -.csect [PR] - .align 2 - .globl _gcry_mpih_add_n - .globl ._gcry_mpih_add_n - .csect _gcry_mpih_add_n[DS] -_gcry_mpih_add_n: - .long ._gcry_mpih_add_n, TOC[tc0], 0 - .csect [PR] -._gcry_mpih_add_n: - mtctr 6 # copy size into CTR - lwz 8,0(4) # load least significant s1 limb - lwz 0,0(5) # load least significant s2 limb - addi 3,3,-4 # offset res_ptr, it is updated before used - addc 7,0,8 # add least significant limbs, set cy - bdz Lend # If done, skip loop -Loop: lwzu 8,4(4) # load s1 limb and update s1_ptr - lwzu 0,4(5) # load s2 limb and update s2_ptr - stwu 7,4(3) # store previous limb in load latency slot - adde 7,0,8 # add new limbs with cy, set cy - bdnz Loop # decrement CTR and loop back -Lend: stw 7,4(3) # store ultimate result limb - li 3,0 # load cy into ... - addze 3,3 # ... return value register - blr - -#else -/* Add two limb vectors of equal, non-zero length for PowerPC. - Copyright (C) 1997 Free Software Foundation, Inc. - This file is 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 Library General Public License as - published by the Free Software Foundation; either version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "sysdep.h" -#include "asm-syntax.h" - - -/* mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr, - mp_size_t size) - Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1. */ - -/* Note on optimisation: This code is optimal for the 601. Almost every other - possible 2-unrolled inner loop will not be. Also, watch out for the - alignment... */ - -EALIGN(_gcry_mpih_add_n,3,0) -/* Set up for loop below. */ - mtcrf 0x01,%r6 - srwi. %r7,%r6,1 - li %r10,0 - mtctr %r7 - bt 31,2f - -/* Clear the carry. */ - addic %r0,%r0,0 -/* Adjust pointers for loop. */ - addi %r3,%r3,-4 - addi %r4,%r4,-4 - addi %r5,%r5,-4 - b 0f - -2: lwz %r7,0(%r5) - lwz %r6,0(%r4) - addc %r6,%r6,%r7 - stw %r6,0(%r3) - beq 1f - -/* The loop. */ - -/* Align start of loop to an odd word boundary to guarantee that the - last two words can be fetched in one access (for 601). */ -0: lwz %r9,4(%r4) - lwz %r8,4(%r5) - lwzu %r6,8(%r4) - lwzu %r7,8(%r5) - adde %r8,%r9,%r8 - stw %r8,4(%r3) - adde %r6,%r6,%r7 - stwu %r6,8(%r3) - bdnz 0b -/* Return the carry. */ -1: addze %r3,%r10 - blr -END(_gcry_mpih_add_n) -#endif - diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-lshift.S deleted file mode 100644 index 6231095dc..000000000 --- a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-lshift.S +++ /dev/null @@ -1,198 +0,0 @@ -/* PowerPC-32 lshift - * - * Copyright (C) 1995, 1998, 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 - */ - -#include "sysdep.h" -#include "asm-syntax.h" - - -#ifndef USE_PPC_PATCHES - -/******************* - * mpi_limb_t - * _gcry_mpih_lshift( mpi_ptr_t wp, (r3) - * mpi_ptr_t up, (r4) - * mpi_size_t usize, (r5) - * unsigned cnt) (r6) - */ - - .toc -.csect .text[PR] - .align 2 - .globl _gcry_mpih_lshift - .globl ._gcry_mpih_lshift - .csect _gcry_mpih_lshift[DS] -_gcry_mpih_lshift: - .long ._gcry_mpih_lshift, TOC[tc0], 0 - .csect .text[PR] -._gcry_mpih_lshift: - mtctr 5 # copy size into CTR - slwi 0,5,2 - add 7,3,0 # make r7 point at end of res - add 4,4,0 # make r4 point at end of s1 - subfic 8,6,32 - lwzu 11,-4(4) # load first s1 limb - srw 3,11,8 # compute function return value - bdz Lend1 - -Loop: lwzu 10,-4(4) - slw 9,11,6 - srw 12,10,8 - or 9,9,12 - stwu 9,-4(7) - bdz Lend2 - lwzu 11,-4(4) - slw 9,10,6 - srw 12,11,8 - or 9,9,12 - stwu 9,-4(7) - bdnz Loop - -Lend1: slw 0,11,6 - stw 0,-4(7) - blr - -Lend2: slw 0,10,6 - stw 0,-4(7) - blr - -#else -/* Shift a limb left, low level routine. - Copyright (C) 1996, 1997 Free Software Foundation, Inc. - This file is 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 Library General Public License as - published by the Free Software Foundation; either version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize, - unsigned int cnt) */ - -EALIGN(_gcry_mpih_lshift,3,0) - mtctr %r5 # copy size into CTR - cmplwi %cr0,%r5,16 # is size < 16 - slwi %r0,%r5,2 - add %r7,%r3,%r0 # make r7 point at end of res - add %r4,%r4,%r0 # make r4 point at end of s1 - lwzu %r11,-4(%r4) # load first s1 limb - subfic %r8,%r6,32 - srw %r3,%r11,%r8 # compute function return value - bge %cr0,L(big) # branch if size >= 16 - - bdz L(end1) - -0: lwzu %r10,-4(%r4) - slw %r9,%r11,%r6 - srw %r12,%r10,%r8 - or %r9,%r9,%r12 - stwu %r9,-4(%r7) - bdz L(end2) - lwzu %r11,-4(%r4) - slw %r9,%r10,%r6 - srw %r12,%r11,%r8 - or %r9,%r9,%r12 - stwu %r9,-4(%r7) - bdnz 0b - -L(end1):slw %r0,%r11,%r6 - stw %r0,-4(%r7) - blr - - -/* Guaranteed not to succeed. */ -L(boom): tweq %r0,%r0 - -/* We imitate a case statement, by using (yuk!) fixed-length code chunks, - of size 4*12 bytes. We have to do this (or something) to make this PIC. */ -L(big): mflr %r9 - bltl- %cr0,L(boom) # Never taken, only used to set LR. - slwi %r10,%r6,4 - mflr %r12 - add %r10,%r12,%r10 - slwi %r8,%r6,5 - add %r10,%r8,%r10 - mtctr %r10 - addi %r5,%r5,-1 - mtlr %r9 - bctr - -L(end2):slw %r0,%r10,%r6 - stw %r0,-4(%r7) - blr - -#define DO_LSHIFT(n) \ - mtctr %r5; \ -0: lwzu %r10,-4(%r4); \ - slwi %r9,%r11,n; \ - inslwi %r9,%r10,n,32-n; \ - stwu %r9,-4(%r7); \ - bdz- L(end2); \ - lwzu %r11,-4(%r4); \ - slwi %r9,%r10,n; \ - inslwi %r9,%r11,n,32-n; \ - stwu %r9,-4(%r7); \ - bdnz 0b; \ - b L(end1) - - DO_LSHIFT(1) - DO_LSHIFT(2) - DO_LSHIFT(3) - DO_LSHIFT(4) - DO_LSHIFT(5) - DO_LSHIFT(6) - DO_LSHIFT(7) - DO_LSHIFT(8) - DO_LSHIFT(9) - DO_LSHIFT(10) - DO_LSHIFT(11) - DO_LSHIFT(12) - DO_LSHIFT(13) - DO_LSHIFT(14) - DO_LSHIFT(15) - DO_LSHIFT(16) - DO_LSHIFT(17) - DO_LSHIFT(18) - DO_LSHIFT(19) - DO_LSHIFT(20) - DO_LSHIFT(21) - DO_LSHIFT(22) - DO_LSHIFT(23) - DO_LSHIFT(24) - DO_LSHIFT(25) - DO_LSHIFT(26) - DO_LSHIFT(27) - DO_LSHIFT(28) - DO_LSHIFT(29) - DO_LSHIFT(30) - DO_LSHIFT(31) - -END(_gcry_mpih_lshift) -#endif diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul1.S deleted file mode 100644 index bd418f7e3..000000000 --- a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul1.S +++ /dev/null @@ -1,120 +0,0 @@ -/* PowerPC-32 mul_1 -- Multiply a limb vector with a limb and store - * the result in a second limb vector. - * - * Copyright (C) 1992, 1993, 1994, 1995, - * 1998, 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 - */ - -#include "sysdep.h" -#include "asm-syntax.h" - - -#ifndef USE_PPC_PATCHES - -/******************* - * mpi_limb_t - * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r3) - * mpi_ptr_t s1_ptr, (r4) - * mpi_size_t s1_size, (r5) - * mpi_limb_t s2_limb) (r6) - * - * This is a fairly straightforward implementation. The timing of the PC601 - * is hard to understand, so I will wait to optimize this until I have some - * hardware to play with. - * - * The code trivially generalizes to 64 bit limbs for the PC620. - */ - - .toc - .csect ._gcry_mpih_mul_1[PR] - .align 2 - .globl _gcry_mpih_mul_1 - .globl ._gcry_mpih_mul_1 - .csect _gcry_mpih_mul_1[DS] -_gcry_mpih_mul_1: - .long ._gcry_mpih_mul_1[PR], TOC[tc0], 0 - .csect ._gcry_mpih_mul_1[PR] -._gcry_mpih_mul_1: - mtctr 5 - - lwz 0,0(4) - mullw 7,0,6 - mulhwu 10,0,6 - addi 3,3,-4 # adjust res_ptr - addic 5,5,0 # clear cy with dummy insn - bdz Lend - -Loop: lwzu 0,4(4) - stwu 7,4(3) - mullw 8,0,6 - adde 7,8,10 - mulhwu 10,0,6 - bdnz Loop - -Lend: stw 7,4(3) - addze 3,10 - blr - -#else -/* Multiply a limb vector by a limb, for PowerPC. - Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc. - This file is 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 Library General Public License as - published by the Free Software Foundation; either version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - - -/* mp_limb_t mpn_mul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr, - mp_size_t s1_size, mp_limb_t s2_limb) - Calculate s1*s2 and put result in res_ptr; return carry. */ - -ENTRY(_gcry_mpih_mul_1) - mtctr %r5 - - lwz %r0,0(%r4) - mullw %r7,%r0,%r6 - mulhwu %r10,%r0,%r6 - addi %r3,%r3,-4 # adjust res_ptr - addic %r5,%r5,0 # clear cy with dummy insn - bdz 1f - -0: lwzu %r0,4(%r4) - stwu %r7,4(%r3) - mullw %r8,%r0,%r6 - adde %r7,%r8,%r10 - mulhwu %r10,%r0,%r6 - bdnz 0b - -1: stw %r7,4(%r3) - addze %r3,%r10 - blr -END(_gcry_mpih_mul_1) -#endif diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul2.S deleted file mode 100644 index 1d97b81a4..000000000 --- a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul2.S +++ /dev/null @@ -1,127 +0,0 @@ -/* PowerPC-32 addmul_1 -- Multiply a limb vector with a limb and add - * the result to a second limb vector. - * - * Copyright (C) 1995, 1998, 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 - */ - -#include "sysdep.h" -#include "asm-syntax.h" - - -#ifndef USE_PPC_PATCHES - -/******************* - * mpi_limb_t - * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r3) - * mpi_ptr_t s1_ptr, (r4) - * mpi_size_t s1_size, (r5) - * mpi_limb_t s2_limb) (r6) - * - * This is a fairly straightforward implementation. The timing of the PC601 - * is hard to understand, so I will wait to optimize this until I have some - * hardware to play with. - * - * The code trivially generalizes to 64 bit limbs for the PC620. - */ - - - .toc - .csect ._gcry_mpih_addmul_1[PR] - .align 2 - .globl _gcry_mpih_addmul_1 - .globl ._gcry_mpih_addmul_1 - .csect _gcry_mpih_addmul_1[DS] -_gcry_mpih_addmul_1: - .long ._gcry_mpih_addmul_1[PR], TOC[tc0], 0 - .csect ._gcry_mpih_addmul_1[PR] -._gcry_mpih_addmul_1: - mtctr 5 - - lwz 0,0(4) - mullw 7,0,6 - mulhwu 10,0,6 - lwz 9,0(3) - addc 8,7,9 - addi 3,3,-4 - bdz Lend - -Loop: lwzu 0,4(4) - stwu 8,4(3) - mullw 8,0,6 - adde 7,8,10 - mulhwu 10,0,6 - lwz 9,4(3) - addze 10,10 - addc 8,7,9 - bdnz Loop - -Lend: stw 8,4(3) - addze 3,10 - blr - -#else -/* Multiply a limb vector by a single limb, for PowerPC. - Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc. - This file is 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 Library General Public License as - published by the Free Software Foundation; either version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - - -/* mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr, - mp_size_t s1_size, mp_limb_t s2_limb) - Calculate res+s1*s2 and put result back in res; return carry. */ -ENTRY(_gcry_mpih_addmul_1) - mtctr %r5 - - lwz %r0,0(%r4) - mullw %r7,%r0,%r6 - mulhwu %r10,%r0,%r6 - lwz %r9,0(%r3) - addc %r8,%r7,%r9 - addi %r3,%r3,-4 /* adjust res_ptr */ - bdz 1f - -0: lwzu %r0,4(%r4) - stwu %r8,4(%r3) - mullw %r8,%r0,%r6 - adde %r7,%r8,%r10 - mulhwu %r10,%r0,%r6 - lwz %r9,4(%r3) - addze %r10,%r10 - addc %r8,%r7,%r9 - bdnz 0b - -1: stw %r8,4(%r3) - addze %r3,%r10 - blr -END(_gcry_mpih_addmul_1) -#endif diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul3.S deleted file mode 100644 index c410dbb02..000000000 --- a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul3.S +++ /dev/null @@ -1,130 +0,0 @@ -/* PowerPC-32 submul_1 -- Multiply a limb vector with a limb and subtract - * the result from a second limb vector. - * - * Copyright (C) 1995, 1998, 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 - */ - -#include "sysdep.h" -#include "asm-syntax.h" - - -#ifndef USE_PPC_PATCHES - -/******************* - * mpi_limb_t - * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r3) - * mpi_ptr_t s1_ptr, (r4) - * mpi_size_t s1_size, (r5) - * mpi_limb_t s2_limb) (r6) - * - * This is a fairly straightforward implementation. The timing of the PC601 - * is hard to understand, so I will wait to optimize this until I have some - * hardware to play with. - * - * The code trivially generalizes to 64 bit limbs for the PC620. - */ - - .toc - .csect ._gcry_mpih_submul_1[PR] - .align 2 - .globl _gcry_mpih_submul_1 - .globl ._gcry_mpih_submul_1 - .csect _gcry_mpih_submul_1[DS] -_gcry_mpih_submul_1: - .long ._gcry_mpih_submul_1[PR], TOC[tc0], 0 - .csect ._gcry_mpih_submul_1[PR] -._gcry_mpih_submul_1: - mtctr 5 - - lwz 0,0(4) - mullw 7,0,6 - mulhwu 10,0,6 - lwz 9,0(3) - subfc 8,7,9 - addc 7,7,8 # invert cy (r7 is junk) - addi 3,3,-4 - bdz Lend - -Loop: lwzu 0,4(4) - stwu 8,4(3) - mullw 8,0,6 - adde 7,8,10 - mulhwu 10,0,6 - lwz 9,4(3) - addze 10,10 - subfc 8,7,9 - addc 7,7,8 # invert cy (r7 is junk) - bdnz Loop - -Lend: stw 8,4(3) - addze 3,10 - blr - -#else -/* Multiply a limb vector by a single limb, for PowerPC. - Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc. - This file is 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 Library General Public License as - published by the Free Software Foundation; either version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr, - mp_size_t s1_size, mp_limb_t s2_limb) - Calculate res-s1*s2 and put result back in res; return carry. */ - -ENTRY(_gcry_mpih_submul_1) - mtctr %r5 - - lwz %r0,0(%r4) - mullw %r7,%r0,%r6 - mulhwu %r10,%r0,%r6 - lwz %r9,0(%r3) - subf %r8,%r7,%r9 - addc %r7,%r7,%r8 # invert cy (r7 is junk) - addi %r3,%r3,-4 # adjust res_ptr - bdz 1f - -0: lwzu %r0,4(%r4) - stwu %r8,4(%r3) - mullw %r8,%r0,%r6 - adde %r7,%r8,%r10 - mulhwu %r10,%r0,%r6 - lwz %r9,4(%r3) - addze %r10,%r10 - subf %r8,%r7,%r9 - addc %r7,%r7,%r8 # invert cy (r7 is junk) - bdnz 0b - -1: stw %r8,4(%r3) - addze %r3,%r10 - blr -END(_gcry_mpih_submul_1) -#endif diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-rshift.S deleted file mode 100644 index 98349edb5..000000000 --- a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-rshift.S +++ /dev/null @@ -1,131 +0,0 @@ -/* PowerPC-32 rshift - * - * Copyright (C) 1995, 1998, 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 - */ - - -#include "sysdep.h" -#include "asm-syntax.h" - - -#ifndef USE_PPC_PATCHES - -/******************* - * mpi_limb_t - * _gcry_mpih_rshift( mpi_ptr_t wp, (r3) - * mpi_ptr_t up, (r4) - * mpi_size_t usize, (r5) - * unsigned cnt) (r6) - */ - - .toc -.csect .text[PR] - .align 2 - .globl _gcry_mpih_rshift - .globl ._gcry_mpih_rshift - .csect _gcry_mpih_rshift[DS] -_gcry_mpih_rshift: - .long ._gcry_mpih_rshift, TOC[tc0], 0 - .csect .text[PR] -._gcry_mpih_rshift: - mtctr 5 # copy size into CTR - addi 7,3,-4 # move adjusted res_ptr to free return reg - subfic 8,6,32 - lwz 11,0(4) # load first s1 limb - slw 3,11,8 # compute function return value - bdz Lend1 - -Loop: lwzu 10,4(4) - srw 9,11,6 - slw 12,10,8 - or 9,9,12 - stwu 9,4(7) - bdz Lend2 - lwzu 11,4(4) - srw 9,10,6 - slw 12,11,8 - or 9,9,12 - stwu 9,4(7) - bdnz Loop - -Lend1: srw 0,11,6 - stw 0,4(7) - blr - -Lend2: srw 0,10,6 - stw 0,4(7) - blr - -#else -/* Shift a limb right, low level routine. - Copyright (C) 1995, 1997 Free Software Foundation, Inc. - This file is 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 Library General Public License as - published by the Free Software Foundation; either version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - - -/* INPUT PARAMETERS - res_ptr r3 - s1_ptr r4 - size r5 - cnt r6 */ - -ENTRY(_gcry_mpih_rshift) - mtctr 5 # copy size into CTR - addi 7,3,-4 # move adjusted res_ptr to free return reg - subfic 8,6,32 - lwz 11,0(4) # load first s1 limb - slw 3,11,8 # compute function return value - bdz 1f - -0: lwzu 10,4(4) - srw 9,11,6 - slw 12,10,8 - or 9,9,12 - stwu 9,4(7) - bdz 2f - lwzu 11,4(4) - srw 9,10,6 - slw 12,11,8 - or 9,9,12 - stwu 9,4(7) - bdnz 0b - -1: srw 0,11,6 - stw 0,4(7) - blr - -2: srw 0,10,6 - stw 0,4(7) - blr -END(_gcry_mpih_rshift) -#endif diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-sub1.S deleted file mode 100644 index d612ea890..000000000 --- a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-sub1.S +++ /dev/null @@ -1,133 +0,0 @@ -/* PowerPC-32 sub_n -- Subtract two limb vectors of the same length > 0 - * and store difference in a third limb vector. - * - * Copyright (C) 1992, 1994, 1995, 1998, - * 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 - */ - -#include "sysdep.h" -#include "asm-syntax.h" - - -#ifndef USE_PPC_PATCHES - -/******************* - * mpi_limb_t - * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r3) - * mpi_ptr_t s1_ptr, (r4) - * mpi_ptr_t s2_ptr, (r5) - * mpi_size_t size) (r6) - */ - - .toc - .extern _gcry_mpih_sub_n[DS] - .extern ._gcry_mpih_sub_n -.csect [PR] - .align 2 - .globl _gcry_mpih_sub_n - .globl ._gcry_mpih_sub_n - .csect _gcry_mpih_sub_n[DS] -_gcry_mpih_sub_n: - .long ._gcry_mpih_sub_n, TOC[tc0], 0 - .csect [PR] -._gcry_mpih_sub_n: - mtctr 6 # copy size into CTR - lwz 8,0(4) # load least significant s1 limb - lwz 0,0(5) # load least significant s2 limb - addi 3,3,-4 # offset res_ptr, it is updated before used - subfc 7,0,8 # add least significant limbs, set cy - bdz Lend # If done, skip loop -Loop: lwzu 8,4(4) # load s1 limb and update s1_ptr - lwzu 0,4(5) # load s2 limb and update s2_ptr - stwu 7,4(3) # store previous limb in load latency slot - subfe 7,0,8 # add new limbs with cy, set cy - bdnz Loop # decrement CTR and loop back -Lend: stw 7,4(3) # store ultimate result limb - subfe 3,0,0 # load !cy into ... - subfic 3,3,0 # ... return value register - blr - -#else -/* Subtract two limb vectors of equal, non-zero length for PowerPC. - Copyright (C) 1997 Free Software Foundation, Inc. - This file is 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 Library General Public License as - published by the Free Software Foundation; either version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr, - mp_size_t size) - Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1. */ - -/* Note on optimisation: This code is optimal for the 601. Almost every other - possible 2-unrolled inner loop will not be. Also, watch out for the - alignment... */ - -EALIGN(_gcry_mpih_sub_n,3,1) -/* Set up for loop below. */ - mtcrf 0x01,%r6 - srwi. %r7,%r6,1 - mtctr %r7 - bt 31,2f - -/* Set the carry (clear the borrow). */ - subfc %r0,%r0,%r0 -/* Adjust pointers for loop. */ - addi %r3,%r3,-4 - addi %r4,%r4,-4 - addi %r5,%r5,-4 - b 0f - -2: lwz %r7,0(%r5) - lwz %r6,0(%r4) - subfc %r6,%r7,%r6 - stw %r6,0(%r3) - beq 1f - -/* Align start of loop to an odd word boundary to guarantee that the - last two words can be fetched in one access (for 601). This turns - out to be important. */ -0: - lwz %r9,4(%r4) - lwz %r8,4(%r5) - lwzu %r6,8(%r4) - lwzu %r7,8(%r5) - subfe %r8,%r8,%r9 - stw %r8,4(%r3) - subfe %r6,%r7,%r6 - stwu %r6,8(%r3) - bdnz 0b -/* Return the borrow. */ -1: subfe %r3,%r3,%r3 - neg %r3,%r3 - blr -END(_gcry_mpih_sub_n) -#endif diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/syntax.h b/grub-core/lib/libgcrypt/mpi/powerpc32/syntax.h deleted file mode 100644 index 5d4af9f0a..000000000 --- a/grub-core/lib/libgcrypt/mpi/powerpc32/syntax.h +++ /dev/null @@ -1,75 +0,0 @@ -/* gmp2-2.0.2-ppc/mpn/powerpc-linux/syntax.h Tue Oct 6 19:27:01 1998 */ -/* From glibc's sysdeps/unix/sysv/linux/powerpc/sysdep.h */ - -/* Copyright (C) 1992, 1997, 1998 Free Software Foundation, Inc. - This file is 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 Library General Public License as - published by the Free Software Foundation; either version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - - -#define USE_PPC_PATCHES 1 - -/* This seems to always be the case on PPC. */ -#define ALIGNARG(log2) log2 -/* For ELF we need the `.type' directive to make shared libs work right. */ -#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg; -#define ASM_SIZE_DIRECTIVE(name) .size name,.-name -#define ASM_GLOBAL_DIRECTIVE .globl - -#ifdef __STDC__ -#define C_LABEL(name) C_SYMBOL_NAME(name)##: -#else -#define C_LABEL(name) C_SYMBOL_NAME(name)/**/: -#endif - -#ifdef __STDC__ -#define L(body) .L##body -#else -#define L(body) .L/**/body -#endif - -/* No profiling of gmp's assembly for now... */ -#define CALL_MCOUNT /* no profiling */ - -#define ENTRY(name) \ - ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ - ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ - .align ALIGNARG(2); \ - C_LABEL(name) \ - CALL_MCOUNT - -#define EALIGN_W_0 /* No words to insert. */ -#define EALIGN_W_1 nop -#define EALIGN_W_2 nop;nop -#define EALIGN_W_3 nop;nop;nop -#define EALIGN_W_4 EALIGN_W_3;nop -#define EALIGN_W_5 EALIGN_W_4;nop -#define EALIGN_W_6 EALIGN_W_5;nop -#define EALIGN_W_7 EALIGN_W_6;nop - -/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes - past a 2^align boundary. */ -#define EALIGN(name, alignt, words) \ - ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ - ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ - .align ALIGNARG(alignt); \ - EALIGN_W_##words; \ - C_LABEL(name) - -#undef END -#define END(name) \ - ASM_SIZE_DIRECTIVE(name) - diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/Manifest b/grub-core/lib/libgcrypt/mpi/sparc32/Manifest deleted file mode 100644 index d279229b0..000000000 --- a/grub-core/lib/libgcrypt/mpi/sparc32/Manifest +++ /dev/null @@ -1,24 +0,0 @@ -# Manifest - checksums -# Copyright 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 - -mpih-lshift.S -mpih-rshift.S -mpih-add1.S -udiv.S -$names$ iQCVAwUAP+LmaDEAnp832S/7AQISHgP/Z5orU+CPKBeRFCogSQDm4p7J2VpDovU6mtfMTdjhqWuZG0U6y8WqH0aj3USfziOhtc8YjQHQ+97g3+EnIWZgLjKacWC6pScY/QbATEpF1D0Wrcea5rk3qR1t7isdBVVOrxedZ5vuj5Op2zx/0OlPI+wt6fTtW88BdG/a6w/ZU/8==Py6h diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/distfiles b/grub-core/lib/libgcrypt/mpi/sparc32/distfiles deleted file mode 100644 index a20f18ead..000000000 --- a/grub-core/lib/libgcrypt/mpi/sparc32/distfiles +++ /dev/null @@ -1,6 +0,0 @@ -Manifest -mpih-lshift.S -mpih-rshift.S -mpih-add1.S -udiv.S - diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/sparc32/mpih-add1.S deleted file mode 100644 index 61a80ca32..000000000 --- a/grub-core/lib/libgcrypt/mpi/sparc32/mpih-add1.S +++ /dev/null @@ -1,239 +0,0 @@ -/* SPARC _add_n -- Add two limb vectors of the same length > 0 and store - * sum in a third limb vector. - * - * Copyright (C) 1995, 1996, 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 - */ - - - -/******************* - * mpi_limb_t - * _gcry_mpih_add_n( mpi_ptr_t res_ptr, - * mpi_ptr_t s1_ptr, - * mpi_ptr_t s2_ptr, - * mpi_size_t size) - */ - -! INPUT PARAMETERS -#define res_ptr %o0 -#define s1_ptr %o1 -#define s2_ptr %o2 -#define size %o3 - -#include "sysdep.h" - - .text - .align 4 - .global C_SYMBOL_NAME(_gcry_mpih_add_n) -C_SYMBOL_NAME(_gcry_mpih_add_n): - xor s2_ptr,res_ptr,%g1 - andcc %g1,4,%g0 - bne L1 ! branch if alignment differs - nop -! ** V1a ** -L0: andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0 - be L_v1 ! if no, branch - nop -/* Add least significant limb separately to align res_ptr and s2_ptr */ - ld [s1_ptr],%g4 - add s1_ptr,4,s1_ptr - ld [s2_ptr],%g2 - add s2_ptr,4,s2_ptr - add size,-1,size - addcc %g4,%g2,%o4 - st %o4,[res_ptr] - add res_ptr,4,res_ptr -L_v1: addx %g0,%g0,%o4 ! save cy in register - cmp size,2 ! if size < 2 ... - bl Lend2 ! ... branch to tail code - subcc %g0,%o4,%g0 ! restore cy - - ld [s1_ptr+0],%g4 - addcc size,-10,size - ld [s1_ptr+4],%g1 - ldd [s2_ptr+0],%g2 - blt Lfin1 - subcc %g0,%o4,%g0 ! restore cy -/* Add blocks of 8 limbs until less than 8 limbs remain */ -Loop1: addxcc %g4,%g2,%o4 - ld [s1_ptr+8],%g4 - addxcc %g1,%g3,%o5 - ld [s1_ptr+12],%g1 - ldd [s2_ptr+8],%g2 - std %o4,[res_ptr+0] - addxcc %g4,%g2,%o4 - ld [s1_ptr+16],%g4 - addxcc %g1,%g3,%o5 - ld [s1_ptr+20],%g1 - ldd [s2_ptr+16],%g2 - std %o4,[res_ptr+8] - addxcc %g4,%g2,%o4 - ld [s1_ptr+24],%g4 - addxcc %g1,%g3,%o5 - ld [s1_ptr+28],%g1 - ldd [s2_ptr+24],%g2 - std %o4,[res_ptr+16] - addxcc %g4,%g2,%o4 - ld [s1_ptr+32],%g4 - addxcc %g1,%g3,%o5 - ld [s1_ptr+36],%g1 - ldd [s2_ptr+32],%g2 - std %o4,[res_ptr+24] - addx %g0,%g0,%o4 ! save cy in register - addcc size,-8,size - add s1_ptr,32,s1_ptr - add s2_ptr,32,s2_ptr - add res_ptr,32,res_ptr - bge Loop1 - subcc %g0,%o4,%g0 ! restore cy - -Lfin1: addcc size,8-2,size - blt Lend1 - subcc %g0,%o4,%g0 ! restore cy -/* Add blocks of 2 limbs until less than 2 limbs remain */ -Loope1: addxcc %g4,%g2,%o4 - ld [s1_ptr+8],%g4 - addxcc %g1,%g3,%o5 - ld [s1_ptr+12],%g1 - ldd [s2_ptr+8],%g2 - std %o4,[res_ptr+0] - addx %g0,%g0,%o4 ! save cy in register - addcc size,-2,size - add s1_ptr,8,s1_ptr - add s2_ptr,8,s2_ptr - add res_ptr,8,res_ptr - bge Loope1 - subcc %g0,%o4,%g0 ! restore cy -Lend1: addxcc %g4,%g2,%o4 - addxcc %g1,%g3,%o5 - std %o4,[res_ptr+0] - addx %g0,%g0,%o4 ! save cy in register - - andcc size,1,%g0 - be Lret1 - subcc %g0,%o4,%g0 ! restore cy -/* Add last limb */ - ld [s1_ptr+8],%g4 - ld [s2_ptr+8],%g2 - addxcc %g4,%g2,%o4 - st %o4,[res_ptr+8] - -Lret1: retl - addx %g0,%g0,%o0 ! return carry-out from most sign. limb - -L1: xor s1_ptr,res_ptr,%g1 - andcc %g1,4,%g0 - bne L2 - nop -! ** V1b ** - mov s2_ptr,%g1 - mov s1_ptr,s2_ptr - b L0 - mov %g1,s1_ptr - -! ** V2 ** -/* If we come here, the alignment of s1_ptr and res_ptr as well as the - alignment of s2_ptr and res_ptr differ. Since there are only two ways - things can be aligned (that we care about) we now know that the alignment - of s1_ptr and s2_ptr are the same. */ - -L2: cmp size,1 - be Ljone - nop - andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0 - be L_v2 ! if no, branch - nop -/* Add least significant limb separately to align s1_ptr and s2_ptr */ - ld [s1_ptr],%g4 - add s1_ptr,4,s1_ptr - ld [s2_ptr],%g2 - add s2_ptr,4,s2_ptr - add size,-1,size - addcc %g4,%g2,%o4 - st %o4,[res_ptr] - add res_ptr,4,res_ptr - -L_v2: addx %g0,%g0,%o4 ! save cy in register - addcc size,-8,size - blt Lfin2 - subcc %g0,%o4,%g0 ! restore cy -/* Add blocks of 8 limbs until less than 8 limbs remain */ -Loop2: ldd [s1_ptr+0],%g2 - ldd [s2_ptr+0],%o4 - addxcc %g2,%o4,%g2 - st %g2,[res_ptr+0] - addxcc %g3,%o5,%g3 - st %g3,[res_ptr+4] - ldd [s1_ptr+8],%g2 - ldd [s2_ptr+8],%o4 - addxcc %g2,%o4,%g2 - st %g2,[res_ptr+8] - addxcc %g3,%o5,%g3 - st %g3,[res_ptr+12] - ldd [s1_ptr+16],%g2 - ldd [s2_ptr+16],%o4 - addxcc %g2,%o4,%g2 - st %g2,[res_ptr+16] - addxcc %g3,%o5,%g3 - st %g3,[res_ptr+20] - ldd [s1_ptr+24],%g2 - ldd [s2_ptr+24],%o4 - addxcc %g2,%o4,%g2 - st %g2,[res_ptr+24] - addxcc %g3,%o5,%g3 - st %g3,[res_ptr+28] - addx %g0,%g0,%o4 ! save cy in register - addcc size,-8,size - add s1_ptr,32,s1_ptr - add s2_ptr,32,s2_ptr - add res_ptr,32,res_ptr - bge Loop2 - subcc %g0,%o4,%g0 ! restore cy - -Lfin2: addcc size,8-2,size - blt Lend2 - subcc %g0,%o4,%g0 ! restore cy -Loope2: ldd [s1_ptr+0],%g2 - ldd [s2_ptr+0],%o4 - addxcc %g2,%o4,%g2 - st %g2,[res_ptr+0] - addxcc %g3,%o5,%g3 - st %g3,[res_ptr+4] - addx %g0,%g0,%o4 ! save cy in register - addcc size,-2,size - add s1_ptr,8,s1_ptr - add s2_ptr,8,s2_ptr - add res_ptr,8,res_ptr - bge Loope2 - subcc %g0,%o4,%g0 ! restore cy -Lend2: andcc size,1,%g0 - be Lret2 - subcc %g0,%o4,%g0 ! restore cy -/* Add last limb */ -Ljone: ld [s1_ptr],%g4 - ld [s2_ptr],%g2 - addxcc %g4,%g2,%o4 - st %o4,[res_ptr] - -Lret2: retl - addx %g0,%g0,%o0 ! return carry-out from most sign. limb - - - diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/sparc32/mpih-lshift.S deleted file mode 100644 index 3422ab04e..000000000 --- a/grub-core/lib/libgcrypt/mpi/sparc32/mpih-lshift.S +++ /dev/null @@ -1,97 +0,0 @@ -/* sparc lshift - * - * Copyright (C) 1995, 1996, 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 - */ - - -! INPUT PARAMETERS -! res_ptr %o0 -! src_ptr %o1 -! size %o2 -! cnt %o3 - -#include "sysdep.h" - - .text - .align 4 - .global C_SYMBOL_NAME(_gcry_mpih_lshift) -C_SYMBOL_NAME(_gcry_mpih_lshift): - sll %o2,2,%g1 - add %o1,%g1,%o1 ! make %o1 point at end of src - ld [%o1-4],%g2 ! load first limb - sub %g0,%o3,%o5 ! negate shift count - add %o0,%g1,%o0 ! make %o0 point at end of res - add %o2,-1,%o2 - andcc %o2,4-1,%g4 ! number of limbs in first loop - srl %g2,%o5,%g1 ! compute function result - be L0 ! if multiple of 4 limbs, skip first loop - st %g1,[%sp+80] - - sub %o2,%g4,%o2 ! adjust count for main loop - -Loop0: ld [%o1-8],%g3 - add %o0,-4,%o0 - add %o1,-4,%o1 - addcc %g4,-1,%g4 - sll %g2,%o3,%o4 - srl %g3,%o5,%g1 - mov %g3,%g2 - or %o4,%g1,%o4 - bne Loop0 - st %o4,[%o0+0] - -L0: tst %o2 - be Lend - nop - -Loop: ld [%o1-8],%g3 - add %o0,-16,%o0 - addcc %o2,-4,%o2 - sll %g2,%o3,%o4 - srl %g3,%o5,%g1 - - ld [%o1-12],%g2 - sll %g3,%o3,%g4 - or %o4,%g1,%o4 - st %o4,[%o0+12] - srl %g2,%o5,%g1 - - ld [%o1-16],%g3 - sll %g2,%o3,%o4 - or %g4,%g1,%g4 - st %g4,[%o0+8] - srl %g3,%o5,%g1 - - ld [%o1-20],%g2 - sll %g3,%o3,%g4 - or %o4,%g1,%o4 - st %o4,[%o0+4] - srl %g2,%o5,%g1 - - add %o1,-16,%o1 - or %g4,%g1,%g4 - bne Loop - st %g4,[%o0+0] - -Lend: sll %g2,%o3,%g2 - st %g2,[%o0-4] - retl - ld [%sp+80],%o0 - diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/sparc32/mpih-rshift.S deleted file mode 100644 index cd3db41df..000000000 --- a/grub-core/lib/libgcrypt/mpi/sparc32/mpih-rshift.S +++ /dev/null @@ -1,93 +0,0 @@ -/* sparc rshift - * - * Copyright (C) 1995, 1996, 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 - */ - -! INPUT PARAMETERS -! res_ptr %o0 -! src_ptr %o1 -! size %o2 -! cnt %o3 - -#include "sysdep.h" - - .text - .align 4 - .global C_SYMBOL_NAME(_gcry_mpih_rshift) -C_SYMBOL_NAME(_gcry_mpih_rshift): - ld [%o1],%g2 ! load first limb - sub %g0,%o3,%o5 ! negate shift count - add %o2,-1,%o2 - andcc %o2,4-1,%g4 ! number of limbs in first loop - sll %g2,%o5,%g1 ! compute function result - be L0 ! if multiple of 4 limbs, skip first loop - st %g1,[%sp+80] - - sub %o2,%g4,%o2 ! adjust count for main loop - -Loop0: ld [%o1+4],%g3 - add %o0,4,%o0 - add %o1,4,%o1 - addcc %g4,-1,%g4 - srl %g2,%o3,%o4 - sll %g3,%o5,%g1 - mov %g3,%g2 - or %o4,%g1,%o4 - bne Loop0 - st %o4,[%o0-4] - -L0: tst %o2 - be Lend - nop - -Loop: ld [%o1+4],%g3 - add %o0,16,%o0 - addcc %o2,-4,%o2 - srl %g2,%o3,%o4 - sll %g3,%o5,%g1 - - ld [%o1+8],%g2 - srl %g3,%o3,%g4 - or %o4,%g1,%o4 - st %o4,[%o0-16] - sll %g2,%o5,%g1 - - ld [%o1+12],%g3 - srl %g2,%o3,%o4 - or %g4,%g1,%g4 - st %g4,[%o0-12] - sll %g3,%o5,%g1 - - ld [%o1+16],%g2 - srl %g3,%o3,%g4 - or %o4,%g1,%o4 - st %o4,[%o0-8] - sll %g2,%o5,%g1 - - add %o1,16,%o1 - or %g4,%g1,%g4 - bne Loop - st %g4,[%o0-4] - -Lend: srl %g2,%o3,%g2 - st %g2,[%o0-0] - retl - ld [%sp+80],%o0 - diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/udiv.S b/grub-core/lib/libgcrypt/mpi/sparc32/udiv.S deleted file mode 100644 index 006b5c125..000000000 --- a/grub-core/lib/libgcrypt/mpi/sparc32/udiv.S +++ /dev/null @@ -1,195 +0,0 @@ -/* SPARC v7 __udiv_qrnnd division support, used from longlong.h. - * This is for v7 CPUs without a floating-point unit. - * - * Copyright (C) 1993, 1994, 1996, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -! INPUT PARAMETERS -! rem_ptr o0 -! n1 o1 -! n0 o2 -! d o3 - -#include "sysdep.h" - - .text - .align 4 - .global C_SYMBOL_NAME(__udiv_qrnnd) -C_SYMBOL_NAME(__udiv_qrnnd): - tst %o3 - bneg Largedivisor - mov 8,%g1 - - b Lp1 - addxcc %o2,%o2,%o2 - -Lplop: bcc Ln1 - addxcc %o2,%o2,%o2 -Lp1: addx %o1,%o1,%o1 - subcc %o1,%o3,%o4 - bcc Ln2 - addxcc %o2,%o2,%o2 -Lp2: addx %o1,%o1,%o1 - subcc %o1,%o3,%o4 - bcc Ln3 - addxcc %o2,%o2,%o2 -Lp3: addx %o1,%o1,%o1 - subcc %o1,%o3,%o4 - bcc Ln4 - addxcc %o2,%o2,%o2 -Lp4: addx %o1,%o1,%o1 - addcc %g1,-1,%g1 - bne Lplop - subcc %o1,%o3,%o4 - bcc Ln5 - addxcc %o2,%o2,%o2 -Lp5: st %o1,[%o0] - retl - xnor %g0,%o2,%o0 - -Lnlop: bcc Lp1 - addxcc %o2,%o2,%o2 -Ln1: addx %o4,%o4,%o4 - subcc %o4,%o3,%o1 - bcc Lp2 - addxcc %o2,%o2,%o2 -Ln2: addx %o4,%o4,%o4 - subcc %o4,%o3,%o1 - bcc Lp3 - addxcc %o2,%o2,%o2 -Ln3: addx %o4,%o4,%o4 - subcc %o4,%o3,%o1 - bcc Lp4 - addxcc %o2,%o2,%o2 -Ln4: addx %o4,%o4,%o4 - addcc %g1,-1,%g1 - bne Lnlop - subcc %o4,%o3,%o1 - bcc Lp5 - addxcc %o2,%o2,%o2 -Ln5: st %o4,[%o0] - retl - xnor %g0,%o2,%o0 - -Largedivisor: - and %o2,1,%o5 ! %o5 = n0 & 1 - - srl %o2,1,%o2 - sll %o1,31,%g2 - or %g2,%o2,%o2 ! %o2 = lo(n1n0 >> 1) - srl %o1,1,%o1 ! %o1 = hi(n1n0 >> 1) - - and %o3,1,%g2 - srl %o3,1,%g3 ! %g3 = floor(d / 2) - add %g3,%g2,%g3 ! %g3 = ceil(d / 2) - - b LLp1 - addxcc %o2,%o2,%o2 - -LLplop: bcc LLn1 - addxcc %o2,%o2,%o2 -LLp1: addx %o1,%o1,%o1 - subcc %o1,%g3,%o4 - bcc LLn2 - addxcc %o2,%o2,%o2 -LLp2: addx %o1,%o1,%o1 - subcc %o1,%g3,%o4 - bcc LLn3 - addxcc %o2,%o2,%o2 -LLp3: addx %o1,%o1,%o1 - subcc %o1,%g3,%o4 - bcc LLn4 - addxcc %o2,%o2,%o2 -LLp4: addx %o1,%o1,%o1 - addcc %g1,-1,%g1 - bne LLplop - subcc %o1,%g3,%o4 - bcc LLn5 - addxcc %o2,%o2,%o2 -LLp5: add %o1,%o1,%o1 ! << 1 - tst %g2 - bne Oddp - add %o5,%o1,%o1 - st %o1,[%o0] - retl - xnor %g0,%o2,%o0 - -LLnlop: bcc LLp1 - addxcc %o2,%o2,%o2 -LLn1: addx %o4,%o4,%o4 - subcc %o4,%g3,%o1 - bcc LLp2 - addxcc %o2,%o2,%o2 -LLn2: addx %o4,%o4,%o4 - subcc %o4,%g3,%o1 - bcc LLp3 - addxcc %o2,%o2,%o2 -LLn3: addx %o4,%o4,%o4 - subcc %o4,%g3,%o1 - bcc LLp4 - addxcc %o2,%o2,%o2 -LLn4: addx %o4,%o4,%o4 - addcc %g1,-1,%g1 - bne LLnlop - subcc %o4,%g3,%o1 - bcc LLp5 - addxcc %o2,%o2,%o2 -LLn5: add %o4,%o4,%o4 ! << 1 - tst %g2 - bne Oddn - add %o5,%o4,%o4 - st %o4,[%o0] - retl - xnor %g0,%o2,%o0 - -Oddp: xnor %g0,%o2,%o2 - ! q' in %o2. r' in %o1 - addcc %o1,%o2,%o1 - bcc LLp6 - addx %o2,0,%o2 - sub %o1,%o3,%o1 -LLp6: subcc %o1,%o3,%g0 - bcs LLp7 - subx %o2,-1,%o2 - sub %o1,%o3,%o1 -LLp7: st %o1,[%o0] - retl - mov %o2,%o0 - -Oddn: xnor %g0,%o2,%o2 - ! q' in %o2. r' in %o4 - addcc %o4,%o2,%o4 - bcc LLn6 - addx %o2,0,%o2 - sub %o4,%o3,%o4 -LLn6: subcc %o4,%o3,%g0 - bcs LLn7 - subx %o2,-1,%o2 - sub %o4,%o3,%o4 -LLn7: st %o4,[%o0] - retl - mov %o2,%o0 diff --git a/grub-core/lib/libgcrypt/mpi/sparc32v8/Manifest b/grub-core/lib/libgcrypt/mpi/sparc32v8/Manifest deleted file mode 100644 index dc1ce6a8e..000000000 --- a/grub-core/lib/libgcrypt/mpi/sparc32v8/Manifest +++ /dev/null @@ -1,23 +0,0 @@ -# Manifest - checksums -# Copyright 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 - -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S -$names$ iQCVAwUAP+LmbjEAnp832S/7AQKQ2gQAotpCpY9rOJUCdZHbDLXXB9i1UUMraRKbVWimtKq493Y2d2wcqXCK2WaGs1AePK3K6Qk6msxZ0PL5Ho7KgHMkzsZ+wG0EUziiuX0yZRTWNm0r3TYerP6SdWH5GOVdSXn7ckkppk2sVOokfQTy+Tmrnah3+dlYJoujan+fmXWN6Us==DolM diff --git a/grub-core/lib/libgcrypt/mpi/sparc32v8/distfiles b/grub-core/lib/libgcrypt/mpi/sparc32v8/distfiles deleted file mode 100644 index 6e9a53091..000000000 --- a/grub-core/lib/libgcrypt/mpi/sparc32v8/distfiles +++ /dev/null @@ -1,5 +0,0 @@ -Manifest -mpih-mul1.S -mpih-mul2.S -mpih-mul3.S - diff --git a/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul1.S deleted file mode 100644 index 03fcddab0..000000000 --- a/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul1.S +++ /dev/null @@ -1,109 +0,0 @@ -/* SPARC v8 __mpn_mul_1 -- Multiply a limb vector with a single limb and - * store the product in a second limb vector. - * - * Copyright (C) 1992, 1994, 1995, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - - -! INPUT PARAMETERS -! res_ptr o0 -! s1_ptr o1 -! size o2 -! s2_limb o3 - -#include "sysdep.h" - -.text - .align 8 - .global C_SYMBOL_NAME(_gcry_mpih_mul_1) -C_SYMBOL_NAME(_gcry_mpih_mul_1): - sll %o2,4,%g1 - and %g1,(4-1)<<4,%g1 -#if PIC - mov %o7,%g4 ! Save return address register - call 1f - add %o7,LL-1f,%g3 -1: mov %g4,%o7 ! Restore return address register -#else - sethi %hi(LL),%g3 - or %g3,%lo(LL),%g3 -#endif - jmp %g3+%g1 - ld [%o1+0],%o4 ! 1 -LL: -LL00: add %o0,-4,%o0 - add %o1,-4,%o1 - b Loop00 /* 4, 8, 12, ... */ - orcc %g0,%g0,%g2 -LL01: b Loop01 /* 1, 5, 9, ... */ - orcc %g0,%g0,%g2 - nop - nop -LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */ - add %o1,4,%o1 - b Loop10 - orcc %g0,%g0,%g2 - nop -LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */ - add %o1,-8,%o1 - b Loop11 - orcc %g0,%g0,%g2 - -Loop: addcc %g3,%g2,%g3 ! 1 - ld [%o1+4],%o4 ! 2 - st %g3,[%o0+0] ! 1 - rd %y,%g2 ! 1 -Loop00: umul %o4,%o3,%g3 ! 2 - addxcc %g3,%g2,%g3 ! 2 - ld [%o1+8],%o4 ! 3 - st %g3,[%o0+4] ! 2 - rd %y,%g2 ! 2 -Loop11: umul %o4,%o3,%g3 ! 3 - addxcc %g3,%g2,%g3 ! 3 - ld [%o1+12],%o4 ! 4 - add %o1,16,%o1 - st %g3,[%o0+8] ! 3 - rd %y,%g2 ! 3 -Loop10: umul %o4,%o3,%g3 ! 4 - addxcc %g3,%g2,%g3 ! 4 - ld [%o1+0],%o4 ! 1 - st %g3,[%o0+12] ! 4 - add %o0,16,%o0 - rd %y,%g2 ! 4 - addx %g0,%g2,%g2 -Loop01: addcc %o2,-4,%o2 - bg Loop - umul %o4,%o3,%g3 ! 1 - - addcc %g3,%g2,%g3 ! 4 - st %g3,[%o0+0] ! 4 - rd %y,%g2 ! 4 - - retl - addx %g0,%g2,%o0 - - diff --git a/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul2.S deleted file mode 100644 index 6f5cc436a..000000000 --- a/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul2.S +++ /dev/null @@ -1,132 +0,0 @@ -/* SPARC v8 __mpn_addmul_1 -- Multiply a limb vector with a limb and - * add the result to a second limb vector. - * - * Copyright (C) 1992, 1993, 1994, 1995, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - - -! INPUT PARAMETERS -! res_ptr o0 -! s1_ptr o1 -! size o2 -! s2_limb o3 - -#include "sysdep.h" - -.text - .align 4 - .global C_SYMBOL_NAME(_gcry_mpih_addmul_1) -C_SYMBOL_NAME(_gcry_mpih_addmul_1): - orcc %g0,%g0,%g2 - ld [%o1+0],%o4 ! 1 - - sll %o2,4,%g1 - and %g1,(4-1)<<4,%g1 -#if PIC - mov %o7,%g4 ! Save return address register - call 1f - add %o7,LL-1f,%g3 -1: mov %g4,%o7 ! Restore return address register -#else - sethi %hi(LL),%g3 - or %g3,%lo(LL),%g3 -#endif - jmp %g3+%g1 - nop -LL: -LL00: add %o0,-4,%o0 - b Loop00 /* 4, 8, 12, ... */ - add %o1,-4,%o1 - nop -LL01: b Loop01 /* 1, 5, 9, ... */ - nop - nop - nop -LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */ - b Loop10 - add %o1,4,%o1 - nop -LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */ - b Loop11 - add %o1,-8,%o1 - nop - -1: addcc %g3,%g2,%g3 ! 1 - ld [%o1+4],%o4 ! 2 - rd %y,%g2 ! 1 - addx %g0,%g2,%g2 - ld [%o0+0],%g1 ! 2 - addcc %g1,%g3,%g3 - st %g3,[%o0+0] ! 1 -Loop00: umul %o4,%o3,%g3 ! 2 - ld [%o0+4],%g1 ! 2 - addxcc %g3,%g2,%g3 ! 2 - ld [%o1+8],%o4 ! 3 - rd %y,%g2 ! 2 - addx %g0,%g2,%g2 - nop - addcc %g1,%g3,%g3 - st %g3,[%o0+4] ! 2 -Loop11: umul %o4,%o3,%g3 ! 3 - addxcc %g3,%g2,%g3 ! 3 - ld [%o1+12],%o4 ! 4 - rd %y,%g2 ! 3 - add %o1,16,%o1 - addx %g0,%g2,%g2 - ld [%o0+8],%g1 ! 2 - addcc %g1,%g3,%g3 - st %g3,[%o0+8] ! 3 -Loop10: umul %o4,%o3,%g3 ! 4 - addxcc %g3,%g2,%g3 ! 4 - ld [%o1+0],%o4 ! 1 - rd %y,%g2 ! 4 - addx %g0,%g2,%g2 - ld [%o0+12],%g1 ! 2 - addcc %g1,%g3,%g3 - st %g3,[%o0+12] ! 4 - add %o0,16,%o0 - addx %g0,%g2,%g2 -Loop01: addcc %o2,-4,%o2 - bg 1b - umul %o4,%o3,%g3 ! 1 - - addcc %g3,%g2,%g3 ! 4 - rd %y,%g2 ! 4 - addx %g0,%g2,%g2 - ld [%o0+0],%g1 ! 2 - addcc %g1,%g3,%g3 - st %g3,[%o0+0] ! 4 - addx %g0,%g2,%o0 - - retl - nop - - -! umul, ld, addxcc, rd, st - -! umul, ld, addxcc, rd, ld, addcc, st, addx - diff --git a/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul3.S deleted file mode 100644 index 93bb19433..000000000 --- a/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul3.S +++ /dev/null @@ -1,67 +0,0 @@ -/* SPARC v8 __mpn_submul_1 -- Multiply a limb vector with a limb and - * subtract the result from a second limb vector. - * - * Copyright (C) 1992, 1993, 1994, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - -! INPUT PARAMETERS -! res_ptr o0 -! s1_ptr o1 -! size o2 -! s2_limb o3 - -#include "sysdep.h" - -.text - .align 4 - .global C_SYMBOL_NAME(_gcry_mpih_submul_1) -C_SYMBOL_NAME(_gcry_mpih_submul_1): - sub %g0,%o2,%o2 ! negate ... - sll %o2,2,%o2 ! ... and scale size - sub %o1,%o2,%o1 ! o1 is offset s1_ptr - sub %o0,%o2,%g1 ! g1 is offset res_ptr - - mov 0,%o0 ! clear cy_limb - -Loop: ld [%o1+%o2],%o4 - ld [%g1+%o2],%g2 - umul %o4,%o3,%o5 - rd %y,%g3 - addcc %o5,%o0,%o5 - addx %g3,0,%o0 - subcc %g2,%o5,%g2 - addx %o0,0,%o0 - st %g2,[%g1+%o2] - - addcc %o2,4,%o2 - bne Loop - nop - - retl - nop - - diff --git a/grub-core/lib/libgcrypt/mpi/supersparc/Manifest b/grub-core/lib/libgcrypt/mpi/supersparc/Manifest deleted file mode 100644 index 869b97bdb..000000000 --- a/grub-core/lib/libgcrypt/mpi/supersparc/Manifest +++ /dev/null @@ -1,21 +0,0 @@ -# Manifest - checksums -# Copyright 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 - -udiv.S -$names$ iQCVAwUAP+LmdjEAnp832S/7AQIrUgQA3YmurZhK7r20DqRvg0gwNe9jMDcFfUY4ZPhW5HkGzMbmrxXtj5Dx50RIPteum72bXE+IhcngljQb/cskiN5Hi9oc2a2CPhyTqVFEeGyF+kJ170GI1pVfFOfzbVG0F4nEwm5lGHgv/nvFsvrjmmAXVW1v/yk5N35wbiLviOFrLOQ==byFc diff --git a/grub-core/lib/libgcrypt/mpi/supersparc/distfiles b/grub-core/lib/libgcrypt/mpi/supersparc/distfiles deleted file mode 100644 index ef7c0a538..000000000 --- a/grub-core/lib/libgcrypt/mpi/supersparc/distfiles +++ /dev/null @@ -1,3 +0,0 @@ -Manifest -udiv.S - diff --git a/grub-core/lib/libgcrypt/mpi/supersparc/udiv.S b/grub-core/lib/libgcrypt/mpi/supersparc/udiv.S deleted file mode 100644 index 79e506a11..000000000 --- a/grub-core/lib/libgcrypt/mpi/supersparc/udiv.S +++ /dev/null @@ -1,118 +0,0 @@ -/* SuperSPARC __udiv_qrnnd division support, used from longlong.h. - * This is for SuperSPARC only, to compensate for its - * semi-functional udiv instruction. - * - * Copyright (C) 1993, 1994, 1996, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - - - -! INPUT PARAMETERS -! rem_ptr i0 -! n1 i1 -! n0 i2 -! d i3 - -#include "sysdep.h" -#undef ret /* Kludge for glibc */ - - .text - .align 8 -LC0: .double 0r4294967296 -LC1: .double 0r2147483648 - - .align 4 - .global C_SYMBOL_NAME(__udiv_qrnnd) -C_SYMBOL_NAME(__udiv_qrnnd): - !#PROLOGUE# 0 - save %sp,-104,%sp - !#PROLOGUE# 1 - st %i1,[%fp-8] - ld [%fp-8],%f10 - sethi %hi(LC0),%o7 - fitod %f10,%f4 - ldd [%o7+%lo(LC0)],%f8 - cmp %i1,0 - bge L248 - mov %i0,%i5 - faddd %f4,%f8,%f4 -L248: - st %i2,[%fp-8] - ld [%fp-8],%f10 - fmuld %f4,%f8,%f6 - cmp %i2,0 - bge L249 - fitod %f10,%f2 - faddd %f2,%f8,%f2 -L249: - st %i3,[%fp-8] - faddd %f6,%f2,%f2 - ld [%fp-8],%f10 - cmp %i3,0 - bge L250 - fitod %f10,%f4 - faddd %f4,%f8,%f4 -L250: - fdivd %f2,%f4,%f2 - sethi %hi(LC1),%o7 - ldd [%o7+%lo(LC1)],%f4 - fcmped %f2,%f4 - nop - fbge,a L251 - fsubd %f2,%f4,%f2 - fdtoi %f2,%f2 - st %f2,[%fp-8] - b L252 - ld [%fp-8],%i4 -L251: - fdtoi %f2,%f2 - st %f2,[%fp-8] - ld [%fp-8],%i4 - sethi %hi(-2147483648),%g2 - xor %i4,%g2,%i4 -L252: - umul %i3,%i4,%g3 - rd %y,%i0 - subcc %i2,%g3,%o7 - subxcc %i1,%i0,%g0 - be L253 - cmp %o7,%i3 - - add %i4,-1,%i0 - add %o7,%i3,%o7 - st %o7,[%i5] - ret - restore -L253: - blu L246 - mov %i4,%i0 - add %i4,1,%i0 - sub %o7,%i3,%o7 -L246: - st %o7,[%i5] - ret - restore - diff --git a/grub-core/lib/libgcrypt/src/ChangeLog-2011 b/grub-core/lib/libgcrypt/src/ChangeLog-2011 deleted file mode 100644 index 796fea403..000000000 --- a/grub-core/lib/libgcrypt/src/ChangeLog-2011 +++ /dev/null @@ -1,2335 +0,0 @@ -2011-12-01 Werner Koch - - NB: ChangeLog files are no longer manually maintained. Starting - on December 1st, 2011 we put change information only in the GIT - commit log, and generate a top-level ChangeLog file from logs at - "make dist". See doc/HACKING for details. - -2011-09-08 Werner Koch - - * gcrypt.h.in [GCRYPT_NO_DEPRECATED]: Exclude gcry_ac structures. - -2011-06-10 Werner Koch - - * sexp.c (vsexp_sscan): Add new format specifiers 'M' and 'u'. - -2011-05-24 Daiki Ueno - - * cipher.h (pk_operation): New. - (pk_encoding_ctx): Add new fields: op, nbits, flags, verify_cmp, - and verify_arg. - -2011-05-19 Daiki Ueno - - * Makefile.am (gcryptrnd_LDADD): Supply $(GPG_ERROR_LIBS) for - gpg_strerror. - -2011-05-18 Daiki Ueno - - * cipher.h: Remove PUBKEY_FLAG_UNPAD. - -2011-05-11 Daiki Ueno - - * cipher.h (PUBKEY_FLAG_UNPAD): New. - (enum pk_encoding): New. - (struct pk_encoding_ctx): New. - -2011-04-19 Werner Koch - - * stdmem.c (_gcry_private_malloc_secure, _gcry_private_malloc): - Set ERRNO on failure. - * secmem.c (mb_get_new): Set ERRNO on failure. - (_gcry_secmem_malloc_internal): Ditto. - -2011-04-01 Werner Koch - - * global.c (gcry_realloc): Divert to gcry_malloc or gcry_free. - -2011-03-09 Werner Koch - - * gcrypt.h.in (gcry_kdf_algos): New. - (gcry_kdf_derive): New. - * visibility.c (gcry_kdf_derive): New. - * visibility.h, libgcrypt.vers, libgcrypt.def: Add gcry_kdf_derive. - -2011-02-23 Werner Koch - - * libgcrypt-config.in: Add option --host. - * libgcrypt.m4: Use AC_PROG_TOOL to find the config script. Print - a warning is the config scripts does not match the configure host. - -2011-02-21 Werner Koch - - * global.c (gcry_check_version): Do not take the patchlevel in - account; it is not well defined. - -2011-02-17 Werner Koch - - * gcrypt-module.h (gcry_cipher_register, gcry_cipher_unregister) - (gcry_pk_register, gcry_pk_unregister, gcry_md_register) - (gcry_md_unregister): Mark as deprecated by the API; in a future - version the module register feature will be removed. - - * gcrypt.h.in: Attribute all _ac_ functions and types as - deprecated by the API. - - * hwfeatures.c (detect_ia32_gnuc): Fix AES-NI detection. Use AND - instead of SUB for bit testing. - -2011-02-16 Werner Koch - - * gcrypt.h.in (GCRYCTL_DISABLE_HWF): New. - * global.c (_gcry_vcontrol): Support new control code. - (print_config): Factor list of hwfeatures out to ... - (hwflist): new. - (disabled_hw_features): New. - (global_init): Pass new variable to _gcry_detect_hw_features. - * hwfeatures.c (_gcry_detect_hw_features): Add arg - DISABLED_FEATURES and disable detected features. - -2011-02-11 Werner Koch - - * g10lib.h (HWF_INTEL_AES): Rename to HWF_INTEL_AESNI. - * hwfeatures.c (detect_ia32_gnuc): Fix setting of this flag. - -2011-02-01 Werner Koch - - * gcrypt.h.in (gcry_pk_get_curve, gcry_pk_get_param): New. - * libgcrypt.vers (gcry_pk_get_curve, gcry_pk_get_param): Add. - * libgcrypt.def (gcry_pk_get_curve, gcry_pk_get_param): Add. - * visibility.c (gcry_pk_get_curve, gcry_pk_get_param): New. - * cipher-proto.h (pk_extra_spec): Add fields GET_CURVE and - GET_CURVE_PARM. - -2011-01-31 Werner Koch - - * sexp.c (vsexp_sscan): Allow opaque MPIs in "%m". - -2010-08-27 Werner Koch - - * g10lib.h (HWF_INTEL_AES): New. - * global.c (print_config): Print new flag. - * hwfeatures.c (detect_ia32_gnuc): Detect this flag. - -2010-08-16 Werner Koch - - * gcrypt.h.in [!WIN32]: Add INSERT_SYS_SELECT_H autoconf substitute. - -2010-07-09 Werner Koch - - * gcrypt.h.in [!__GNUC__ && W32]: Typedef ssize_t and pid_t to - help building with MSVC. - -2010-06-24 Werner Koch - - * gcrypt.h.in [W32]: Include time.h and not sys/time.h. - -2010-04-19 Marcus Brinkmann - - * misc.c (write2stderr): Dummy variable to silence gcc warning. - -2010-04-16 Marcus Brinkmann - - * sexp.c: (sexp_sscan): Make it variable length, and rename the - old version to ... - (vsexp_sscan): ... this new function. Also swap last two arguments. - (gcry_sexp_create): Remove dummy va_list. - (gcry_sexp_build): Use vsexp_sscan instead of sexp_sscan. - (_gcry_sexp_vbuild): Likewise. - (gcry_sexp_build_array): Remove dummy va_list. - (gcry_sexp_sscan): Likewise. - -2010-04-12 Brad Hards (wk) - - Spelling fixes. - -2010-03-15 Werner Koch - - * gcrypt.h.in: Add autoconf template to set generated file to - read-only in an Emacs buffer. - -2010-01-21 Werner Koch - - * Makefile.am (arch_gpg_error_cflags, arch_gpg_error_libs): New. - (dumpsexp_CFLAGS): New. - (dumpsexp_LDADD): Add arch_gpg_error_libs. - (hmac256_CFLAGS, hmac256_LDADD): Add the arch variables. - (libgcrypt_la_DEPENDENCIES): Add libcompat. - * secmem.c (lock_pool): Mark unused args. - * global.c (do_malloc, gcry_realloc, gcry_free, gcry_calloc) - (gcry_calloc_secure, gcry_xcalloc, gcry_xcalloc_secure): Use - gpg_err_set_errno. - (_gcry_vcontrol): Call _gcry_compat_identification. - * hmac256.c [__MINGW32CE__]: Include gpg-error.h. - (_gcry_hmac256_file): Use gpg_err_set_errno. - (gpg_err_set_errno) [!GPG_ERR_INLINE]: Add macro. - * g10lib.h: Include libcompat.h. - -2010-01-05 Werner Koch - - * gcrypt.h.in (GCRY_PK_ECDH): New. - -2009-12-08 Werner Koch - - * gcrypt.h.in (GCRY_CIPHER_MODE_AESWRAP): New. - -2009-12-08 Marcus Brinkmann - - * Makefile.am (LTRCCOMPILE): Refactor with ... - (RCCOMPILE): ... this new macro. Add $(libgcrypt_la_CPPFLAGS). - (SUFFIXES): Add .lo. - (.rc.o): Change to ... - (.rc.lo): ... this implicit rule. - (gcrypt_res_ldflag): Removed. - (gcrypt_res): Use libtool object file name here. - (libgcrypt_la_LDFLAGS): Remove gcrypt_res_ldflag usage. - (libgcrypt_la_LIBADD): Add gcrypt_res. - -2009-11-29 Werner Koch - - * hwfeatures.c (detect_ia32_gnuc): Repalce "=r" by "+r" so that - HAS-CPUDID is always initialized. Thanks to Ben Hutchings for - pointing out this problem. - -2009-08-05 Werner Koch - - * ath.h: Include sys/msg.h. - -2009-07-02 Werner Koch - - * fips.c (_gcry_initialize_fips_mode): Do not use FIPS mode if - /proc/.../fips_enabled has insufficient permissions. - - * dumpsexp.c (main): Fix handling multiple files. - (parse_and_print): Implement hex and octal escaping. - - * sexp.c (unquote_string): Remove superfluous clearing of ESC. - * dumpsexp.c (parse_and_print): Add missing break. - (main): Fix return value. - Reported by Fabian Keil. - -2009-02-16 Werner Koch - - * ath.h [HAVE_SYS_SELECT_H]: Include for fd_set. - [!HAVE_SYS_SELECT_H]: Include . Move inclusion of - config.h to the top. The actual configure check was already - there. - - * sexp.c: Remove memory.h. - * mpi.h: Remove memory.h. Add string.h. - -2009-02-02 Werner Koch - - * ath.h: Include sys/time.h. Fixes bug#993. - -2009-01-22 Werner Koch - - * fips.c (_gcry_initialize_fips_mode): Remove superfluous const - from static string. Reported by Albert Chin. - * hmac256.c (selftest): Ditto and change to unsigned char. - -2008-12-10 Werner Koch - - * hmac256.c (finalize): Fix for big endian hosts. - -2008-12-05 Werner Koch - - * global.c (gcry_free): Save and restore ERRNO if set. - -2008-11-24 Werner Koch - - * sexp.c (get_internal_buffer): New. - (sexp_sscan): Add format character S. - * cipher-proto.h (pk_ext_generate_t): Add field EXTRAINFO changed - all implementors. - - * cipher-proto.h (pk_ext_generate_t): Simplify. - (pk_get_param): New. - (pk_extra_spec_t): Add field GET_PARAM. - * cipher.h (PUBKEY_FLAG_TRANSIENT_KEY): Remove. - (_gcry_pubkey_extraspec_elg): New. - -2008-11-05 Werner Koch - - * cipher.h (CIPHER_INFO_NO_WEAK_KEY): New. - - * cipher-proto.h (cipher_set_extra_info_t): New. - (cipher_extra_spec): Add field SET_EXTRA_INFO. - -2008-10-30 Werner Koch - - * g10lib.h (GCC_ATTR_FORMAT_ARG): New. - (_gcry_gettext): Use it. - -2008-10-24 Werner Koch - - * global.c (inactive_fips_mode): Move to fips.c. - (gcry_set_allocation_handler): Factor code out to ... - * fips.c (_gcry_inactivate_fips_mode): New. - (_gcry_is_fips_mode_inactive): New. - -2008-09-29 Werner Koch - - * gcrypt-module.h (GCRY_MODULE_ID_USER, GCRY_MODULE_ID_USER_LAST): - New. - * module.c (MODULE_ID_USER, MODULE_ID_USER_LAST): Define using new - macros. - -2008-09-20 Werner Koch - - * hmac256.c (finalize) [WORDS_BIGENDIAN]: Fix sigbus problem. - -2008-09-18 Werner Koch - - * cipher-proto.h (pk_ext_generate_t): Add args QBITS, NAME, DOMAIN. - - * fips.c (fips_new_state): Allow Error => Error transition. - -2008-09-18 Werner Koch - - * gcrypt.h.in (gcry_fips_mode_active): New. - - * secmem.c (_gcry_secmem_init): Factor most code out to .. - (secmem_init): .. new. - (DEFAULT_POOL_SIZE): Rename to MINIMUM_POOL_SIZE. - (STANDARD_POOL_SIZE): New. - (_gcry_secmem_malloc_internal): Don't abort if the pool is not - initialized but try to out intialize it first and only then print - an error message and return NULL. If the pool is not locked while - in FIPS mode, return NULL. - - * fips.c (FIPS_FORCE_FILE): New constant. Change the file name to - "/etc/gcrypt/fips_enabled". - (enforced_fips_mode): New. - (_gcry_initialize_fips_mode): Set that flag. - (_gcry_enforced_fips_mode): New. - * global.c (inactive_fips_mode): New. - (_gcry_vcontrol): Take that flag in account for GCRYCTL_FIPS_MODE_P. - (gcry_set_allocation_handler): Take care of the enforced fips mdoe - flag. - (get_no_secure_memory): New. - (do_malloc, gcry_is_secure): Use it. - -2008-09-16 Werner Koch - - * global.c (print_config): Use y/n for fips mode. - - * fips.c (fips_new_state): Allow transition to Error and - Fatal-error from Init. - -2008-09-15 Werner Koch - - * fips.c [HAVE_SYSLOG]: Include syslog.h. - (_gcry_initialize_fips_mode, lock_fsm, unlock_fsm) - (_gcry_fips_signal_error, fips_new_state) - (_gcry_fips_noreturn) [HAVE_SYSLOG]: Also log via syslog. - (check_binary_integrity) [HAVE_SYSLOG]: Log failure. - * global.h [HAVE_SYSLOG]: Include syslog.h. - (_gcry_global_is_operational) [HAVE_SYSLOG]: Print warning. - - * global.c (_gcry_vcontrol): Use GCRYCTL_INITIALIZATION_FINISHED - to run power-up tests. Add unpublished control commands 58-60. - - * global.c (_gcry_global_is_operational): New. - * g10lib.h (fips_is_operational): Change to call this function. - -2008-09-12 Werner Koch - - * fips.c (_gcry_fips_run_selftests): Add arg EXTENDED. - (run_cipher_selftests, run_digest_selftests, run_hmac_selftests) - (run_pubkey_selftests): Ditto. - * cipher-proto.h (selftest_func_t): Add arg EXTENDED - -2008-09-11 Werner Koch - - * fips.c: Include string.h. - (loxtoi_1, loxtoi_2, loxdigit_p): New. - (check_binary_integrity): Change the format of the expected file. - - * fips.c (_gcry_fips_run_selftests): Run random tests before the - pubkey tests. - -2008-09-05 Werner Koch - - * gcrypt.h.in (GCYRCTL_SELFTEST): New. - * global.c (_gcry_vcontrol): Implement. - * fips.c (_gcry_fips_run_selftests): Do state transitions only if - in fips mode. Return an error code. - -2008-09-01 Werner Koch - - * stdmem.c: Re-indented. - -2008-08-29 Werner Koch - - * fips.c (_gcry_initialize_fips_mode): Changed /proc file to test - for FIPS mode. - - * cipher-proto.h (pk_compute_keygrip_t): New. - (pk_extra_spec): Add field comp_keygrip. - -2008-08-28 Werner Koch - - * hwfeatures.c (_gcry_detect_hw_features): Disable hardware - detection in FIPS mode. - -2008-08-27 Werner Koch - - * global.c (_gcry_vcontrol): Allow running selftests from error - state. - (gcry_set_outofcore_handler): Only print a warning if used in FIPS - mode. - (gcry_xmalloc, gcry_xrealloc, gcry_xmalloc_secure, gcry_xstrdup): - Ignore an outofcore handler in FIPS mode. - - * fips.c (_gcry_fips_test_error_or_operational): New. - (fips_new_state): Allow transition from error into selftest. - Disallow error to init. - -2008-08-26 Werner Koch - - * fips.c (fips_new_state): Print state transitions only at - verbosity level of 2. - (reporter): Likewise. - - * cipher-proto.h (pk_ext_generate_t): New. - (pk_extra_spec): Add member ext_generate. - * cipher.h (PUBKEY_FLAG_TRANSIENT_KEY): New. - -2008-08-22 Werner Koch - - * hmac256.c (_gcry_hmac256_file): New. - (main): New option --binary. - * fips.c (check_binary_integrity): New. - (_gcry_fips_run_selftests): Run it. - - * global.c (_gcry_vcontrol) : - Check for fips operational state. - (_gcry_vcontrol) : Ditt. - -2008-08-21 Werner Koch - - * misc.c (_gcry_log_printhex): New. - -2008-08-20 Werner Koch - - * g10lib.h (gcry_assert): New. use this at almost all places - where we used a plain assert. - * misc.c (_gcry_assert_failed): New. - (_gcry_bug): Also use func variant for ISO-C99. - -2008-08-19 Werner Koch - - * visibility.c, visibility.h (gcry_mpi_lshift): New. - * libgcrypt.vers, libgcrypt.def, gcrypt.h.in: Ditto. - -2008-08-15 Werner Koch - - * gcrypt.h.in (gcry_cipher_setkey): Replace macro by function. - (gcry_cipher_setiv): Ditto. - (gcry_cipher_setctr): Ditto. - * visibility.c (gcry_cipher_setkey, gcry_cipher_setiv) - (gcry_cipher_setctr): New. - * visibility.h (gcry_cipher_setkey, gcry_cipher_setiv) - (gcry_cipher_setctr): New. - * libgcrypt.vers (gcry_cipher_setkey, gcry_cipher_setiv) - (gcry_cipher_setctr): New. - * libgcrypt.def (gcry_cipher_setkey, gcry_cipher_setiv) - (gcry_cipher_setctr): New. - - * hmac256.h, hmac256.c: New. - * Makefile.am (hmac256_SOURCES): New. - * Makefile.am (bin_PROGRAMS): Add hmac256. - - * gcrypt.h.in (struct gcry_thread_cbs): Change type of OPTION to - unsigned int. Although this is a type change it does not make a - difference. - * ath.c (ath_install): Take the version of the option field in - account. - - * visibility.c (gcry_pk_encrypt, gcry_pk_decrypt, gcry_pk_sign) - (gcry_pk_verify, gcry_pk_testkey, gcry_pk_genkey) - (gcry_pk_get_nbits, gcry_pk_get_keygrip) - (gcry_md_open, gcry_md_copy, gcry_md_enable) - (gcry_md_write, md_final, gcry_md_ctl, gcry_md_setkey) - (gcry_md_hash_buffer, gcry_md_get_algo, gcry_md_info) - (gcry_md_is_enabled) - (gcry_cipher_open, gcry_cipher_encrypt) - (gcry_cipher_decrypt, gcry_cipher_ctl) - (gcry_cipher_algo_info): Check whether the library is operational. - - * cipher-proto.h: New. - * cipher.h: Include cipher-proto.h. - * visibility.h: Remove duplicate macro definitions. Remove - gcry_cipher_register, gcry_md_register, gcry_pk_register macros. - * visibility.c: Include cipher-proto.h. - (gcry_cipher_register): Pass dummy extra args to the internal - register function. - (gcry_md_register, gcry_pk_register): Ditto. - * g10lib.h (struct gcry_module): Add field EXTRASPEC. - * module.c (_gcry_module_add): Add arg EXTRASPEC. Changed all - callers to pass NULL. - - * fips.c: New. - * gcrypt.h.in (GCRYCTL_FIPS_MODE_P): New. - * global.c (global_init): Call fips initialization. - (_gcry_vcontrol): Add GCRYCTL_FIPS_MODE_P code. - (print_config): Add config item fips-mode. - (gcry_set_allocation_handler): Do not allow the use of custom - allocation handlers. - (gcry_set_outofcore_handler): Ditto. - (_gcry_get_debug_flag): Do not return any debug flags in fips mode. - * misc.c (_gcry_logv): Signal fips error on BUG or FATAL. - (_gcry_fatal_error): Ditto. - -2008-07-05 Werner Koch - - * Makefile.am: Include librandom.la. - -2008-04-18 Werner Koch - - * missing-string.c (vasprintf): Remove. It is not used. Reported - by Simon Josefsson. - -2008-03-11 Werner Koch - - * gcrypt.h.in (gcry_ac_em_t, gcry_ac_scheme_t): Remove trailing - comma for full C-89 compatibility. - -2008-01-21 Marcus Brinkmann - - * hwfeatures.c (detect_ia32_gnuc): Fix inline asm. - -2007-12-11 Werner Koch - - * visibility.c (gcry_md_hash_buffer): Don't use return vor a void - function. Hey, why does gcc not complain about this? - (gcry_ac_io_init_va): Ditto. - -2007-12-05 Werner Koch - - * hwfeatures.c (detect_ia32_gnuc): Depend on ENABLE_PADLOCK_SUPPORT. - -2007-12-03 Werner Koch - - * misc.c (_gcry_logv): Use abort for error levels fatal and bug as - this is more approriate for a library. Terminate the secmem - before doing so. - (_gcry_fatal_error): Terminate secmem before abort. - * secmem.c (_gcry_secmem_malloc_internal): Use log_bug instead of - exit. - -2007-11-29 Werner Koch - - * hwfeatures.c (detect_ia32_gnuc): Detect Padlock engine. - -2007-11-13 Werner Koch - - * gcrypt.h.in (_GCRY_GCC_ATTR_MALLOC): Fixed gcc version check. - Reported by Gabriele Monti. - -2007-10-31 Werner Koch - - * global.c (gcry_control): Factor most code out to .. - (_gcry_vcontrol): .. new. - * sexp.c (_gcry_sexp_vbuild): New. - * mpi.h (_gcry_mpi_set, _gcry_mpi_set_ui, _gcry_mpi_invm): Remove - prototypes as they are already in gcrypt.h. - -2007-10-30 Werner Koch - - * sexp.c (gcry_sexp_nth_string): Replace by _gcry_sexp_nth_string. - - * visibility.h, visibility.c: New. - * g10lib.h: Include visibility.h instead of gcrypt.h. - * globals.c (_gcry_malloc): Rename to .. - (do_malloc): .. this. - - * hwfeatures.c: New. - * global.c (global_init): Detect features. - (print_config): Print them. - -2007-08-22 Werner Koch - - * dumpsexp.c: New. - * Makefile.am (bin_PROGRAMS): Install it. - - * getrandom.c (print_version): Use new standard license line. - * gcryptrnd.c (print_version): Ditto. - -2007-06-06 Werner Koch - - * gcrypt.h.in (GCRY_THREAD_OPTION_PTH_IMPL): Factror network - related code out so that the prototypes can be adjusted for W32. - (_GCRY_THREAD_OPTION_PTH_IMPL_NET): New. - -2007-05-09 Werner Koch - - * libgcrypt.m4: Print found version on success. - -2007-05-09 Marcus Brinkmann - - * gcrypt.h.in (gcry_ac_io_t): Add name for anonymous union, and mark - all members as internal (actually: deprecated). - -2007-05-04 Werner Koch - - * Makefile.am (.rc.lo): New to replace gmake specific suffix rule. - -2007-05-03 Werner Koch - - * libgcrypt.def (gcry_sexp_nth_string): New. - * Makefile.am (EXTRA_DIST): Add libgcrypt.def. - -2007-05-02 Werner Koch - - * global.c (print_config): Print ciphers, digests and pubkeys. - -2007-05-02 David Shaw - - * cipher.h, gcrypt.h.in: Add Camellia. - -2007-04-30 Werner Koch - - * gcrypt.h.in (GCRYCTL_PRINT_CONFIG): New. - (GCRYCTL_SET_RNDEGD_SOCKET): New. - * global.c (gcry_control): Add GCRYCTL_PRINT_CONFIG and - GCRYCTL_SET_RNDEGD_SOCKET. - (print_config): New. - * misc.c (_gcry_log_info_with_dummy_fp): New. - -2007-04-18 Werner Koch - - * gcrypt.h.in (gcry_sexp_nth_string): New. - - * sexp.c (gcry_sexp_nth_data): Factored code out to ... - (sexp_nth_data): ... new. - (gcry_sexp_nth_string): New. - (gcry_sexp_nth_mpi): Reimplemented in terms of sexp_ntd_data. - -2007-04-16 Werner Koch - - * secmem.c (init_pool): Use sysconf() if available to determine - page size. - -2007-03-22 Werner Koch - - * mpi.h (mpi_mod): New. - (mpi_new, mpi_snew): New. - - * gcrypt.h.in: Add GCRY_PK_ECDSA. - -2007-03-16 Werner Koch - - * gcrypt.h.in (GCRY_THREAD_OPTION_PTHREAD_IMPL): Fixed typo - introduced by me on 2006-10-23. - -2007-02-22 Werner Koch - - * gcrypt.h.in (gcry_ac_id_to_name, gcry_ac_name_to_id): Mark as - deprecated. - - * libgcrypt.def (gcry_fast_random_poll): Removed - it is a macro. - (gcry_cipher_register, gcry_cipher_unregister): New. - (gcry_md_register, gcry_md_unregister): New. - (gcry_pk_register, gcry_pk_unregister): New. - (gcry_ac_data_from_sexp, gcry_ac_data_to_sexp): New. - (gcry_ac_io_init, gcry_ac_io_init_va): New. - (gcry_ac_data_encrypt_scheme, gcry_ac_data_decrypt_scheme): New. - (gcry_ac_data_sign_scheme, gcry_ac_data_verify_scheme): New. - - * missing-string.c: Include stdio.h for the vsprintf prototype. - - * ath.h (struct ath_ops) [_WIN32]: Use int instead of socklen_t. - -2007-02-21 Werner Koch - - * libgcrypt.def (gcry_create_nonce, gcry_fast_random_poll) - (gcry_md_debug): New. - - * libgcrypt-config.in: Remove duplicates from --cflags and --libs. - Print a error for option --thread. - - * gcrypt.h.in (gcry_sexp_sprint): Change BUFFER from char* to void*. - (gcry_md_ctl): Change BUFFER from unsigned char* to void*. - (gcry_md_debug): New. - (gcry_cipher_encrypt, gcry_cipher_decrypt): Change buffer args to - void*. - (gcry_randomize): Change BUFFER to void. - (gcry_create_nonce): Ditto. - - * libgcrypt.vers (gcry_md_debug): New. - - * sexp.c (gcry_sexp_sprint): Ditto. - (normalize): Make P unsigned. - (gcry_sexp_nth_data): Cast return value to char*. - (sexp_sscan): Fix sign/unsigned conflicts. - (whitespacep): Change P to char*. - (unquote_string): Change STRING to char*. - (convert_to_hex): Change DEST to char*. - (convert_to_string): Change DEST and P to char*. - (convert_to_token): Chnage DEST to char*. - (gcry_sexp_canon_len): Change DISPHINT to unsigned char*. - - * gcrypt-module.h (gcry_pk_spec): Made ALIASES a const. - (gcry_md_write_t): Changed BUF to a const void*. - -2007-02-12 Werner Koch - - * gcrypt.h.in: Include stdlib.h for the sake fo the trheading - macros. Suggested by Andreas Metzler. - - * secmem.c (ptr_into_pool_p): New. - (_gcry_private_is_secure): Implement in terms of new function. - (BLOCK_VALID): Removed. Replaced all users by new function. - -2007-01-31 Werner Koch - - * secmem.c (_gcry_private_is_secure): Fixed severe implementation - flaw. Might be the reason for some of the more obscure bugs. - (MB_WIPE_OUT): Use wipememory2. - -2006-10-23 Werner Koch - - * gcrypt.h.in (GCRY_THREAD_OPTION_PTHREAD_IMPL): Add some cast for - use by C-doubleplus. In general I don't like this but due to - public demand I give up ;-) - -2006-10-19 Werner Koch - - * global.c (gcry_control) : Return an error - if the memory could not be locked. - * secmem.c (not_locked): New. - (_gcry_secmem_get_flags): Return that flag. - * secmem.h (GCRY_SECMEM_FLAG_NOT_LOCKED): New. - -2006-10-05 Werner Koch - - * module.c (_gcry_module_id_new): Don't assign modules in the range - the range of 1024..4096. - * gcrypt.h (GCRY_MD_USER, GCRY_MD_USER_LAST): New - (GCRY_PK_USER, GCRY_PK_USER_LAST): New. - (GCRY_CIPHER_USER, GCRY_CIPHER_USER_LAST): New. - -2006-10-12 Marcus Brinkmann - - * gcrypt.h.in: Replace socklen_t with gcry_socklen_t. - -2006-10-11 Marcus Brinkmann - - * gcrypt.h.in: Replace version by @VERSION@. - -2006-10-10 Marcus Brinkmann - - * gcrypt.h: Add fallback type for socklen_t. Move to ... - * gcrypt.h.in: ... this file. - * Makefile.am (EXTRA_DIST): Add gcrypt.h.in. - -2006-09-04 Werner Koch - - * gcrypt.h: Removed some trailing comma in enums. - -2006-08-29 Werner Koch - - * global.c (gcry_xrealloc): Pass secure flag to outofcore handler. - - * gcrypt.h (GCRY_CIPHER_SEED): New. - -2006-08-21 Werner Koch - - * gcrypt.h (GCRYCTL_FAKED_RANDOM_P): New. - -2006-07-29 Marcus Brinkmann - - * secmem.c (init_pool): Close FD after establishing the mapping. - -2006-07-12 Marcus Brinkmann - - * ath.c (ath_mutex_destroy): Microoptimize destruction of unused - statitically initialized mutexes. Suggested by Victor Stinner - . - - * gcrypt.h (GCRY_THREAD_OPTION_PTHREAD_IMPL, - (GCRY_THREAD_OPTION_PTH_IMPL): Add missing initializers to - suppress gcc warning. - Submitted by Victor Stinner . - -2006-07-04 Marcus Brinkmann - - * ath.c: Avoid warning about double defined type byte and other - hacks to let it build for W32 (backported from LIBGCRYPT-1-2-BRANCH). - * ath.h, gcrypt.h, tests/benchmark.c, src/types.h: Likewise. - - * gcrypt.h: Revert last change, and instead: - [_WIN32 || __WIN32__]: Do not include , but - and . - Suggested by Simon Josefsson . - - * Makefile.am (install-data-local, uninstall-local, %.lo, - (install-def-file, uninstall-def-file): New targets. - (LTRCCOMPILE, gcrypt_res, gcrypt_res_ldflag, no_undefined, - (export_symbols, gcrypt_deps): New variables. - * versioninfo.rc.in: New file. - * libgcrypt.def: New file from ../w32-dll/libgcrypt.def. - - * gcrypt.h [!HAVE_SYS_SOCKET_H]: Do not include sys/socket.h, but - the appropriate windows socket header. - -2006-06-21 Werner Koch - - * global.c (gcry_xcalloc, gcry_xcalloc_secure): Made safe against - integer overflow. - - * sexp.c (make_space): Return an error on out of core. - (sexp_sscan): Remove all xmalloc style calls and return proper - error codes on allocation failures. - (gcry_sexp_find_token): Ditto. - (gcry_sexp_nth): - - * sexp.c (gcry_sexp_find_token): Re-indented and removed a cruft - "while(level);" which fortunately had no effect. - -2006-04-28 Werner Koch - - * gcrypt.h (GCRY_MD_SHA224): Change value from 306 to 11 to match - the use in OpenPGP. There has been no release yet, so we can - safely do it. - -2006-04-22 Moritz Schulte - - * gcrypt.h (gcry_ctl_cmds): New commands: - GCRYCTL_SET_RANDOM_DAEMON_SOCKET, GCRYCTL_USE_RANDOM_DAEMON. - * global.c (gcry_control): Handle new commands, calling - _gcry_set_random_daemon_socket() and _gcry_use_random_daemon(). - -2006-04-18 Werner Koch - - * gcrypt.h (GCRY_PK_USAGE_CERT, GCRY_PK_USAGE_AUTH) - (GCRY_PK_USAGE_UNKN): New. - -2006-04-01 Moritz Schulte - - * gcrypt.h (gcry_ac_eme_pkcs_v1_5): Removed members: key, handle; - added member: key_size. - - * secmem.c (MB_FLAG_ACTIVE): Write braces around MB_FLAG_ACTIVE - definition. - -2006-03-15 Werner Koch - - * getrandom.c: New. - -2006-03-14 Werner Koch - - * gcryptrnd.c: New. - -2006-03-10 Werner Koch - - * gcrypt.h: Add GCRY_MD_SHA224. - -2005-11-02 Moritz Schulte - - * gcrypt.h: Update comments for functions: gcry_cipher_algo_name, - gcry_pk_algo_name. - -2005-10-31 Moritz Schulte - - * global.c: Added documentation. - -2005-10-16 Moritz Schulte - - * global.c (global_init): Use gcry_error_t instead of - gcry_err_code_t; use goto instead of if constructs. - - * stdmem.c: Inserted description of the layered memory management - in Libgcrypt. - - * g10lib.h: Removed G10_I18N_H related check; it seems to be a - GnuPG relict (Libgcrypt does not define this symbol anywhere). - (FLAG_MODULE_DISABLED): Don't forget parantheses around shifted - value. - - Removed GCC_ATTR_PURE macro definitions, since gcrypt.h does - already contain such a macro named _GCRY_GCC_ATTR_PURE, which we - can use here as well. - - Likewise for GCC_ATTR_MALLOC and _GCRY_GCC_ATTR_MALLOC. - - * stdmem.h: Use _GCRY_GCC_ATTR_MALLOC instead of GCC_ATTR_MALLOC. - * secmem.h: Likewise. - -2005-10-09 Moritz Schulte - - * global.c (gcry_control): Call global_init() after passing thread - cbs to ath. global_init() MUST to be called AFTER passing the cbs - to ath and BEFORE calling library functions, which make use of - ath. This change combines cbs installing with ath initialization - and thus removes the need to call other library initialization - functions inbetween like e.g. gcry_check_version(). - -2005-10-01 Moritz Schulte - - * ath.c: Assign copyright to FSF. - * ath.h: Likewise. - -2005-06-25 Moritz Schulte - - * Makefile.am (pkgconfigdir, pkgconfig_DATA): Removed variables. - * libgcrypt.pc.in: Removed file - we do not want to support a - second, foreign configuration system. - -2005-06-17 Moritz Schulte - - * global.c (gcry_xstrdup): Removed superfluous strcpy call. - -2005-04-22 Moritz Schulte - - * Makefile.am (pkgconfigdir, pkgconfig_DATA): New; support for - pkgconfig provided by Albert Chin. - * libgcrypt.pc.in (Cflags): New file. - -2005-04-16 Moritz Schulte - - * g10lib.h (_gcry_ac_init): Declare. - * global.c (global_init): Call _gcry_ac_init; don't forget to set - err. - -2005-04-14 Werner Koch - - * sexp.c (whitespacep): New. - (sexp_sscan): Replaced isdigit and isspace by whitespacep and - digitp. - -2005-04-11 Moritz Schulte - - * gcrypt.h (gcry_md_algos): Added: GCRY_MD_WHIRLPOOL. - * cipher.h (_gcry_digest_spec_whirlpool): Declare. - -2005-03-30 Moritz Schulte - - * libgcrypt.vers: Added: gcry_ac_io_init, gry_ac_io_init_va. - - * gcrypt.h (gcry_ac_data_read_cb_t, gcry_ac_data_write_cb_t, - gcry_ac_io_mode_t, gcry_ac_io_type_t, gcry_ac_io_t): New types. - (gcry_ac_io_init_va): Declare function. - (gcry_ac_data_encode, gcry_ac_data_decode, - gcry_ac_data_encrypt_scheme, gcry_ac_data_decrypt_scheme, - gcry_ac_data_sign_scheme, gcry_ac_data_verify_scheme): Use - gcry_ac_io_type_t objects instead of memory strings directly. - -2005-03-03 Moritz Schulte - - * libgcrypt.vers: Added: gcry_ac_data_to_sexp() and - gcry_ac_data_from_sexp(). - -2005-02-22 Werner Koch - - * global.c (_gcry_malloc): Make sure ERRNO is set if we return - NULL. Remove unneeded initialization of M to allow the compiler - to catch errors. - (gcry_realloc): Make sure ERRNO is set if we return NULL> - -2005-02-13 Moritz Schulte - - * gcrypt.h: Declare new functions: gcry_ac_data_encrypt_scheme, - gcry_ac_data_decrypt_scheme, gcry_ac_data_sign_scheme, - gcry_ac_data_verify_scheme, gcry_ac_data_encode, - gcry_ac_data_decode, gcry_ac_data_to_sexp, gcry_ac_data_from_sexp. - New types: gcry_ac_emsa_pkcs_v1_5_t, gcry_ac_ssa_pkcs_v1_5_t, - gcry_md_algo_t. - New enumeration lists: gcry_ac_scheme_t, gcry_ac_em_t. - * libgcrypt.vers: Added new ac functions. - * g10lib.h: Declare function: _gcry_pk_get_elements. - * mpi.h (mpi_get_ui): New macro. - Declare function: _gcry_mpi_get_ui. - -2004-11-09 Werner Koch - - * gcrypt.h: Removed 3 trailing commas from enums. Noted by Heiko - Stamer. - -2004-09-21 Werner Koch - - * sexp.c (sexp_sscan): Removed C++ style comments. Noted by Yoann - Vandoorselaere. - -2004-08-23 Moritz Schulte - - * global.c: Do not include . - * sexp.c: Likewise. - * module.c: Likewise. - * misc.c: Likewise. - -2004-08-18 Moritz Schulte - - * secmem.c (_gcry_secmem_init): Try to lock pool into core not - only when running with root privileges. - -2004-08-16 Werner Koch - - * secmem.h (_gcry_secmem_set_flags,_gcry_secmem_get_flags): - Removed __pure__. - (GCRY_SECMEM_FLAG_NO_WARNING): Put macro value into parens. - - * secmem.c (_gcry_secmem_init): Defer printing of the warning. - -2004-08-10 Moritz Schulte - - * gcrypt.h: Include , thanks to Simon Josefsson. - -2004-05-07 Werner Koch - - * gcrypt.h: Added GCRYCTL_FAST_POLL. - (gcry_fast_random_poll): New. - * global.c (gcry_control) : Do only basic - random subsystem init. - (gcry_control) : New. - -2004-04-22 Marcus Brinkmann - - * libgcrypt.m4: Quote first argument to AC_DEFUN. - -2004-04-15 Werner Koch - - * secmem.c (_gcry_secmem_malloc_internal): Removed old extra info - error output. - (_gcry_secmem_term): Use wipememory2 here. - - * misc.c (_gcry_burn_stack): Use wipememory to avoid optimizations. - - * string.c: Removed. Was never used. - * global.c (gcry_strdup): Replaced by the version from string.c - (gcry_xstrdup): Rewritten. - * gcrypt.h: Removed duplicate prototype for gcry_strdup. - -2004-03-29 Werner Koch - - * secmem.c (_gcry_secmem_realloc): Fixed double unlock; bug - manifested itself due to the more rigorous checking in the changed - ath.h - - * libgcrypt-config.in (Options): Ignore the obsolete --threads - option for now. - -2004-03-17 Marcus Brinkmann - - * libgcrypt-config.in (includedir, libdir): Quote'em. Use - $gpg_error_cflags and $gpg_error_libs. Fix construction of - $includes. - -2004-03-14 Marcus Brinkmann - - * libgcrypt-config.in (includedir, libdir): New variables. For - --cflags, don't test $cflags. Also check against /include for the - GNU/Hurd. Don't overwrite but extend $cflags_final. Likewise for - --libs. - -2004-03-10 Marcus Brinkmann - - * Makefile.am (ltlib_libgcrypt_pthread, ltlib_libgcrypt_pth): Removed. - (lib_LTLIBRARIES): Remove those variables from here. - (libgcrypt_pthread_la_SOURCES, libgcrypt_pthread_la_LDFLAGS, - (libgcrypt_pthread_la_DEPENDENCIES, libgcrypt_pthread_la_LIBADD, - (libgcrypt_pth_la_SOURCES, libgcrypt_pth_la_LDFLAGS, - (libgcrypt_pth_la_DEPENDENCIES, libgcrypt_pth_la_LIBADD, - (noinst_LTLIBRARIES): Removed. - (libgcrypt_real_la_SOURCES): Merge with ... - (libgcrypt_la_SOURCES): ... likewise. - (libgcrypt_real_la_DEPENDENCIES): Merge with ... - (libgcrypt_la_DEPENDENCIES): ... this. - (libgcrypt_real_la_LIBADD): Merge with ... - (libgcrypt_la_LIBADD): ... this. - * libgcrypt-config.in (libs_pthread, libs_pth, cflags_pth) - (cflags_pthread, thread_module, thread_modules): Removed. - (Options): Remove --thread option from help output. If the option - is specified, output an error and exit. - For --cflags and --libs option, remove pth and pthread from output. - * gcrypt.h: Include and . - (enum gcry_ctl_cmds): Add GCRYCTL_SET_THREAD_CBS. - (gcry_thread_cbs): New struct. - * global.c (gcry_control): Implement GCRYCTL_SET_THREAD_CBS. - (global_init): Don't call ath_init here. - * ath.h: Rewritten. - * ath.c: Rewritten. - -2004-03-06 Werner Koch - - * libgcrypt-config.in: s/--soname-number/--api-version/ - * libgcrypt.m4: Changed test for API version. - -2004-03-05 Werner Koch - - * libgcrypt.m4: Optionally check the SONAME number. - - * libgcrypt-config.in: Add option --soname-number - -2004-03-01 Marcus Brinkmann - - * Makefile.am (libgcrypt_la_SOURCES): Add ath.c. - * ath.c (ath_init): Add missing function. - - * Makefile.am (ath_pth_src): Removed. - (ath_pthread_src): Removed. - (libgcrypt_la_SOURCES): Remove ath-compat, $(ath_pth_src) and - $(ath_pthread_src). - * ath-compat.c, ath-pth-compat.c, ath-pthread-compat.c: Files - removed. - -2004-02-20 Werner Koch - - * gcrypt.h (GCRY_PRIME_CHECK_AT_GOT_PRIME) - (GCRY_PRIME_CHECK_AT_FINISH), - (GCRY_PRIME_CHECK_AT_MAYBE_PRIME): New. - -2004-02-18 Werner Koch - - * libgcrypt-config.in: Ignore setting of --prefix. - -2004-02-13 Werner Koch - - * gcrypt.h: Added GCRY_CIPHER_RFC2268_128, alsthough not yet - supported. - -2004-02-06 Werner Koch - - * gcrypt.h: Added GCRY_CIPHER_RFC2268_40. - -2004-02-03 Werner Koch - - * secmem.c (_gcry_secmem_init): Do not print the "not locked into - core warning" if the NO_WARNING flag has been set. - - * sexp.c (sexp_sscan): Allocate result in secure memory if BUFFER - is in secure memory. Switch to secure memory for the a secure %b - format item. Extra paranoid wipe on error. - (gcry_sexp_release): Added paranoid wiping for securely allocated - S-expressions. - -2004-01-25 Moritz Schulte - - * ath.h: Include . - -2004-01-12 Moritz Schulte - - * gcrypt.h: Adjusted declarations of: gcry_ac_data_set, - gcry_ac_data_get_name, gcry_ac_data_get_index, - gcry_ac_key_pair_generate, gcry_ac_key_test, - gcry_ac_key_get_nbits, gcry_ac_key_get_grip. - - * gcrypt.h (GCRY_AC_FLAG_DATA_NO_BLINDING): Removed symbol. - (GCRY_AC_FLAG_DEALLOC, GCRY_AC_FLAG_COPY) - (GCRY_AC_FLAG_NO_BLINDING): New symbols. - - * global.c (gcry_strdup): Removed function. - * string.c: New file. - * Makefile.am (libgcrypt_real_la_SOURCES): Added: string.c. - * string.c (gcry_strdup): New function. - * gcrypt.h (gcry_strdup): Declare. - -2003-12-19 Werner Koch - - * g10lib.h (wipememory, wipememory2): New; taken from gnupg. - -2003-11-14 Werner Koch - - * global.c (gcry_strdup): Don't copy the string after a malloc - error. - -2003-11-11 Werner Koch - - * sexp.c (sexp_sscan): Implemented "%b" format specifier. - -2003-11-11 Moritz Schulte - - * libgcrypt.m4: Do not set prefix when calling libgcrypt-config. - Thanks to Nikos Mavroyanopoulos. - -2003-11-08 Moritz Schulte - - * cipher.h (small_prime_numbers): Removed declaration. - (PUBKEY_FLAG_NO_BLINDING): Put braces around shift. - -2003-11-04 Werner Koch - - * cipher.h (_gcry_sha1_has_buffer): New. - - * gcrypt.h (gcry_create_nonce): New. - -2003-10-31 Werner Koch - - * libgcrypt.vers (_gcry_generate_elg_prime): Removed this symbol; - gnutls does not need it anymore. - - * secmem.c (mb_get_new): s/pool/block/ due to global pool. - - * misc.c (gcry_set_log_handler): s/logf/f/ to avoid shadowing - warning against a builtin. - - * ath-pth-compat.c: cast pth_connect to get rid of the const - prototype. - -2003-10-27 Werner Koch - - * ath.h (ATH_MUTEX_INITIALIZER): Removed spurious semicolon. - -2003-10-27 Moritz Schulte - - * libgcrypt-config.in: Include libs/cflags of libgpg-error. - - * sexp.c (sexp_sscan): Cleaned up, deallocate scanned sexp on - error. - - * module.c (MODULE_ID_MIN): New symbol, use it. - -2003-10-27 Werner Koch - - * gcrypt.h (gcry_pk_testkey): Doc fix. - -2003-09-29 Moritz Schulte - - * libgcrypt-config.in: Fix --algorithms option. - -2003-10-23 Werner Koch - - * gcrypt.h (gcry_err_code): Use GPG_ERR_INLINE instead of - __inline__. - - * secmem.c (lock_pool): Don't print the warning for certain - systems, handle ENOMEM. - -2003-10-21 Werner Koch - - * secmem.c (_gcry_secmem_dump_stats): Fixed format sepcifier for a - size_t. Reported by Stephane Corthesy. - -2003-10-10 Werner Koch - - * global.c (_gcry_malloc): Handle the no_secure_memory option. - - * gcrypt.h (gcry_prime_group_generator): New. - (gcry_prime_release_factors): New. - -2003-10-07 Werner Koch - - * sexp.c (sexp_sscan): Check that parenthesis are matching. - -2003-09-28 Moritz Schulte - - * g10lib.h: Declare: _gcry_malloc. - (GCRY_ALLOC_FLAG_SECURE): New symbol. - - * global.c (_gcry_malloc): New function... - (gcry_malloc): ... use it. - (gcry_malloc_secure): Likewise. - - * ath.c: Change License to LGPL. - * ath-pthread-compat.c: Likewise. - * ath-pthread.c: Likewise. - * ath-pth-compat.c: Likewise. - * ath-pth.c: Likewise. - * ath.h: Likewise. - * ath-compat.c: Likewise. - - * secmem.c (_gcry_secmem_realloc): Do not forget to release secmem - lock. Thanks to low halo for triggering this bug. - -2003-09-04 Werner Koch - - * gcrypt.h (_GCRY_ERR_SOURCE_DEFAULT): Removed cruft. - (gcry_prime_check_func_t): Renamed arg for clarity. - -2003-09-02 Moritz Schulte - - * gcrypt.h (GCRY_PRIME_FLAG_SPECIAL_FACTOR): New symbol. - -2003-09-01 Moritz Schulte - - * gcrypt.h (gcry_random_level_t): New type. - (gcry_prime_check_func_t): Likewise. - (GCRY_PRIME_FLAG_SECRET): New symbol. - (gcry_prime_generate, gcry_prime_check): Declare functions. - -2003-08-28 Werner Koch - - * Makefile.am (libgcrypt_pth_la_LDFLAGS): Removed PTH_CFLAGS cruft. - -2003-08-27 Moritz Schulte - - * global.c (gcry_control): Remove call to ath_deinit. - - * Makefile.am (libgcrypt_real_la_DEPENDENCIES): Fixed. - (libgcrypt_real_la_LIBADD): Fixed. - Removed unecessary variables. - - * libgcrypt-config.in: Adjusted script for new thread handling. - - * Makefile.am: New version, based on GPGMEs Makefile.am. - - * ath.c, ath-compat.c, ath.h, ath-pth.c, ath-pth-compat.c, - ath-pthread.c, ath-pthread-compat.c: New files, merged from GPGME. - * ath.c, ath.h, ath-pthread.c, ath-pth.c: Removed files. - -2003-08-08 Moritz Schulte - - * global.c (gcry_realloc): Remove FIXME about `clearing out - realloced memory', since _gcry_secmem_realloc takes care of - overwriting old memory. - -2003-08-07 Werner Koch - - * module.c (_gcry_module_release): Don't act if module is NULL. - -2003-07-30 Moritz Schulte - - * gcrypt.h (enum gcry_ac_id): Added: GCRY_AC_ELG_E. - Reverted change: use gcry_md_flags enumeration list instead of - defines. - -2003-07-29 Werner Koch - - * global.c (gcry_control): Add GCRYCTL_SET_RANDOM_SEED_FILE and - GCRYCTL_UPDATE_RANDOM_SEED_FILE. - * gcrypt.h: Ditto. Renamed index to idx, so avoid warning - related to the old index function. - -2003-07-28 Moritz Schulte - - * global.c (gcry_err_code_from_errno, gcry_err_code_to_errno) - (gcry_err_make_from_errno, gcry_error_from_errno): New functions. - - * gcrypt.h: Declared: gcry_err_code_from_errno, - gcry_err_code_to_errno, gcry_err_make_from_errno, - gcry_error_from_errno. - - * Makefile.am (include_HEADERS): Added: gcrypt-module.h. - - * gcrypt.h: Include . - - * gcrypt-module.h: New file. - -2003-07-27 Werner Koch - - * gcrypt.h (gcry_mpi_scan, gcry_mpi_print): API change. - (gcry_mpi_dump): New. - -2003-07-21 Moritz Schulte - - * gcrypt.h: Declared: gcry_ac_key_data_get. - (gcry_pk_spec): Renamed member `sexp_names' into `aliases'. - -2003-07-20 Moritz Schulte - - * gcrypt.h (gcry_md_oid_spec_t): New type. - (gcry_md_spec): New member: oids. - -2003-07-19 Moritz Schulte - - * gcrypt.h (gcry_cipher_oid_spec_t): New type. - (gcry_cipher_spec): New member: oids; - -2003-07-18 Werner Koch - - * gcrypt.h (gcry_mpi_set_opaque): Add a warning comment. - -2003-07-15 Moritz Schulte - - * secmem.c (compress_pool): Remove function, since unused blocks - are automatically concatenad. - - * gcrypt.h: Bumped version number up to 1.1.42-cvs. - -2003-07-14 Moritz Schulte - - * gcrypt.h (gcry_cipher_spec): New member: aliases. - - * Makefile.am (noinst_PROGRAMS, testapi_SOURCES, testapai_LDADD, - benchmark_SOURCES, benchmark_LDADD): Removed. - - * benchmark.c, testapi.c: Removed files. - - * mpi.h: Removed disabled typedef. - * g10lib.h: Likewise. - - * benchmark.c, g10lib.h, gcrypt.h, global.c, module.c, sexp.c: - Used gcry_err* wrappers for libgpg-error symbols. - -2003-07-12 Moritz Schulte - - * global.c: Likewise. - - * gcrypt.h: New type: gcry_error_t, gcry_err_code_t and - gcry_err_source_t. - (gcry_err_make, gcry_error, gcry_err_code, gcry_err_source): New - functions. - - * global.c (gcry_strerror): New function. - (gcry_strsource): New function. - - * gcrypt.h: New symbol: GCRY_CIPHER_TWOFISH128. - -2003-07-09 Moritz Schulte - - * gcrypt.h (enum gcry_md_flags): Removed, used define instead, - since that is more common than an enumeration list when it comes - to flags that can be bitwise ORed. - -2003-07-08 Moritz Schulte - - * global.c: Use new types for handlers. - - * gcrypt.h: Declare: gcry_ac_data_copy. - -2003-07-07 Moritz Schulte - - * sexp.c (gcry_sexp_build_array): Use dummy argument pointer. - Thanks to Simon Josefsson . - - * gcrypt.h: Declare: gcry_cipher_list, gcry_pk_list, gcry_md_list. - -2003-07-05 Moritz Schulte - - * gcrypt.h: Declare: gcry_cipher_register, gcry_cipher_unregister, - gcry_md_register, gcry_md_unregister, gcry_pk_register, - gcry_pk_unregister. - (gcry_cipher_spec): Removed member: algorithm. - (gcry_pk_spec): Likewise. - (gcry_md_spec): Likewise. - Adjusted declarations: gcry_cipher_register, gcry_pk_register, - gcry_md_register. - - * module.c: Replaced all occurences of `id' with `mod_id', since - `id' is a keyword in obj-c. - - * gcrypt.h (gcry_cipher_spec): Renamed member `id' to `algorithm'. - (gcry_pk_spec): Likewise. - (gcry_md_spec): Likewise. - - * cipher.h: Removed types: gcry_pubkey_generate_t, - gcry_pubkey_check_secret_key_t, gcry_pubkey_encrypt_t, - gcry_pubkey_decrypt_t, gcry_pubkey_sign_t, gcry_pubkey_verify_t, - gcry_pubkey_get_nbits_t, gcry_pk_spec_t, gcry_digest_init_t, - gcry_digest_write_t, gcry_digest_final_t, gcry_digest_read_t, - gcry_digest_spec_t, gcry_cipher_setkey_t, gcry_cipher_encrypt_t, - gcry_cipher_decrypt_t, gcry_cipher_stencrypt_t, - gcry_cipher_stdecrypt_t, gcry_cipher_spec_t. - - * gcrypt.h: New types: gcry_pk_generate_t, - gcry_pk_check_secret_key_t, gcry_pk_encrypt_t, gcry_pk_decrypt_t, - gcry_pk_sign_t, gcry_pk_verify_t, gcry_pk_get_nbits_t, - gcry_pk_spec_t, gcry_md_init_t, gcry_md_write_t, gcry_md_final_t, - gcry_md_read_t, gcry_md_spec_t, gcry_cipher_setkey_t, - gcry_cipher_encrypt_t, gcry_cipher_decrypt_t, - gcry_cipher_stencrypt_t, gcry_cipher_stdecrypt_t, - gcry_cipher_spec_t, gcry_module_t. - -2003-07-04 Moritz Schulte - - * module.c (_gcry_module_list): New function. - -2003-07-02 Moritz Schulte - - * module.c (_gcry_module_lookup): Fixed typo. - - * gcrypt.h: Added all definitions and declarations necessary for - the new ac interface. - -2003-06-30 Moritz Schulte - - * g10lib.h: Added declarations: _gcry_pk_module_lookup, - _gcry_pk_module_release. - -2003-06-18 Werner Koch - - * benchmark.c (cipher_bench): Adjusted for new API of get_blklen - and get_keylen. - - * gcrypt.h (gcry_cipher_get_algo_blklen) - (gcry_cipher_get_algo_keylen): Replaced macro by funcion. - -2003-06-18 Moritz Schulte - - * cipher.h: Renamed types GcryDigestSpec, GcryCipherSpec and - GcryPubkeySpec into: gcry_digest_spec_t, gcry_cipher_spec_t and - gcry_pubkey_spec_t. - (gcry_pubkey_spec): Defined member `id' as unsigned. - (gcry_digest_spec): Likewise. - (gcry_cipher_spec): Likewise. - - * module.c (_gcry_module_id_new): New function. - (_gcry_module_add): Generate a new ID via _gcry_module_id_new in - case `id' is zero. - - * g10lib.h, module.c: Replace old type GcryModule with newer one: - gcry_module_t. - - * module.c (_gcry_module_add): Added argument `id', use it. - - * g10lib.h: Added declaration: _gcry_module_lookup_id. - (_gcry_module_add): Added argument `id'. - - * module.c (_gcry_module_lookup_id): New function. - - * g10lib.h (struct gcry_module): New member: id. - - * gcrypt.h: New type: gcry_handler_progress_t, - gcry_handler_alloc_t, gcry_haandler_secure_check_t, - gcry_handler_realloc_t, gcry_handler_free_t, - gcry_handler_no_mem_t, gcry_handler_error_t, gcry_handler_log_t. - Use new types. - - * cipher.h: Include . - New types: gcry_pk_generate_t, gcry_pk_check_secret_key_t, - gcry_pk_encrypt_t, gcry_pk_decrypt_t, gcry_pk_sign_t, - gcry_pk_verify_t, gcry_pk_get_nbits_t, gcry_md_init_t, - gcry_md_write_t, gcry_md_final_t, gcry_md_read_t, - gcry_cipher_setkey_t, gcry_cipher_encrypt_t, - gcry_cipher_decrypt_t, gcry_cipher_stencrypt_t, - gcry_cipher_stdecrypt_t. - Use new types. - -2003-06-17 Moritz Schulte - - * Makefile.am (AM_CFLAGS): Added: @GPG_ERROR_CFLAGS@. - -2003-06-16 Moritz Schulte - - * g10lib.h: Replace last occurences of old type names with newer - names (i.e. replace MPI with gcry_mpi_t). - * mpi.h: Likewise. - * sexp.c: Likewise. - -2003-06-15 Moritz Schulte - - * testapi.c (test_genkey): Use gpg_strerror instead of - gcry_strerror. - - * global.c (gcry_control): Fixed typo. - - * misc.c (_gcry_fatal_error): Use gpg_strerror instead of - gcry_strerror. - - * types.h (STRLIST): Removed type since it is not used. - -2003-06-11 Moritz Schulte - - * global.c (global_init): Call: _gcry_cipher_init, _gcry_md_init, - _gcry_pk_init. - - * g10lib.h: Declare: _gcry_cipher_init, _gcry_md_init, - _gcry_pk_init. - - * global.c (gcry_strerror): Remove compatibility code. - - * Makefile.am: Remove support libgpg-error special handling. - (AM_CPPFLAGS): Add @GPG_ERROR_CFLAGS@ - - * gcrypt.h: Likewise. - -2003-06-13 Werner Koch - - * gcrypt.h (gcry_md_get_algo): Reverted to old API. This is a - convenience function anyway and error checking is not approriate. - (gcry_md_is_enabled): New. - (gcry_md_is_secure): Replaced macro by function and reverted to old - API. - -2003-06-11 Werner Koch - - * gcrypt.h (GCRYERR): Define _GCRY_ERR_SOURCE_DEFAULT instead of - GPG_ERR_SOURCE_DEFAULT, so that libgpg-error still works despite - the use of the old gcrypt error codes. - (gcry_md_copy): Swapped arguments. - -2003-06-09 Moritz Schulte - - * Makefile.am: Support for libgpg-error. - -2003-06-08 Moritz Schulte - - * sexp.c (gcry_sexp_create): Expect sane error values from - gcry_sexp_canon_len instead of the `historical' values. - -2003-06-07 Moritz Schulte - - * ath.c, ath.c, ath-pth.c, ath-pthread.c, benchmark.c, cipher.h, - g10lib.h, gcrypt.h, global.c, misc.c, missing-string.c, module.c, - mpi.h, secmem.c, secmem.h, sexp.c, stdmem.c, stdmem.h, testapi.c, - types.h: 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. - - * gcrypt.h: Re-organized checking for gcc features; New macro: - _GCRY_GCC_ATTR_DEPRECATED. - Include copy of libgpg-error's gpg-error.h in order to make it - easy to build libgcrypt without needing libgpg-error.h. - - (GCRY_MPI, GcryMPI, GCRY_SEXP, GcrySexp, GCRY_CIPHER_HD, - GcryCipherHd, GCRY_MD_HD, GcryMDHd): Declared deprecated. - (gcry_mpi_t, gcry_sexp_t, gcry_cipher_hd_t, gcry_md_hd_t): New - types. - -2003-06-04 Moritz Schulte - - * sexp.c (sexp_sscan): New argument: arg_list, adjusted all - callers. - (ARG_NEXT): New macro. - (sexp_sscan): Use ARG_NEXT for receiving format string arguments. - (gcry_sexp_build_array): New function. - -2003-06-02 Moritz Schulte - - * gcrypt.h: Added some comments describing the gcry_sexp_* - functions. - Include instead of . - -2003-06-01 Moritz Schulte - - * sexp.c (OLDPARSECODE): Removed macro... - (gcry_sexp_canon_len): ... and do not use it. - - * gcrypt.h (gcry_errno): Removed declaration. - - * g10lib.h (string_to_pubkey_algo, pubkey_algo_to_string, - pubkey_nbits): Removed declarations for non-existing functions. - -2003-05-31 Moritz Schulte - - * cipher.h (is_RSA, is_ELGAMAL): Removed macros. - - * g10lib.h (set_lasterr): Removed macro. - (_gcry_set_lasterr): Removed declaration. - - * gcrypt.h: Changed declarations for: gcry_pk_algo_info, - gcry_md_open, gcry_md_copy, gcry_md_algo_info, gcry_md_info, - gcry_md_get_algo, gcry_random_add_bytes. - - (gcry_md_is_secure): Adjust macro for new API. - -2003-05-29 Moritz Schulte - - * gcrypt.h: Changed declarations for: gcry_cipher_open, - gcry_cipher_info, gcry_cipher_algo_info. - (gcry_cipher_get_algo_keylen): Adjuster for new - gcry_cipher_algo_info interface. - (gcry_cipher_get_algo_blklen): Likewise. - - * global.c (gcry_errno): Removed function. - (gcry_strerror): Do not use gcry_errno. - (_gcry_set_lasterr): Removed function. - (last_ec): Removed variable. - -2003-05-27 Moritz Schulte - - * gcrypt.h (enum gcry_cipher_algos): Make Serpent IDs do not - conflict with OpenPGP. Reported by Timo Schulz. - - * global.c (gcry_control): Fixed name of enum list. - -2003-05-25 Moritz Schulte - - * cipher.h (gcry_cipher_spec): Adjust return type of `setkey' for - libgpg-error. - (gcry_pubkey_spec): Adjust return type of `generate', - `check_secret_key', `encrypt', `decrypt', `sign' and `verify' for - libgpg-error. - - * sexp.c (gcry_sexp_canon_len): Adjusted for libgpg-error. - (gcry_sexp_create): Likewise. - (gcry_sexp_new): Likewise. - (sexp_sscan): Likewise. - (gcry_sexp_build): Likewise. - (gcry_sexp_sscan): Likewise. - - * module.c (_gcry_module_add): Likewise. - - * global.c (last_ec): Change type to gpg_error_t. - (gcry_control): Adjust for libgpg-error. - (gcry_errno): Likewise. - (gcry_strerror): Likewise. - (_gcry_set_lasterr): Likewise. - (gcry_xmalloc): Likewise. - (gcry_xrealloc): Likewise. - -2003-05-22 Moritz Schulte - - * types.h: Merged code from GnuPG regarding U64_C. - - * missing-string.c (strsep): Removed function. - - * g10lib.h: Removed declarations: strsep, strlwr. - - * secmem.c (secmem_lock): New variable. - (SECMEM_LOCK, SECMEM_UNLOCK): New macros. - (_gcry_secmem_set_flags): Use SECMEM_LOCK and SECMEM_UNLOCK. - (_gcry_secmem_get_flags): Likewise. - (_gcry_secmem_init): Likewie. - (_gcry_secmem_malloc): Likewise. - (_gcry_secmem_free): Likewise. - (_gcry_secmem_malloc): Renamed to ... - (_gcry_secmem_malloc_internal): ... this. - (_gcry_secmem_malloc): New function, use SECMEM_LOCK, - SECMEM_UNLOCK, call _gcry_secmem_malloc_internal. - (_gcry_secmem_free): Renamed to ... - (_gcry_secmem_free_internal): ... this. - (_gcry_secmem_free): New function, use SECMEM_LOCK, SECMEM_UNLOCK, - call _gcry_secmem_free_internal. - (_gcry_secmem_realloc): Use SECMEM_LOCK, SECMEM_UNLOCK, call - _gcry_secmem_malloc_internal and _gcry_secmem_free_internal. - (_gcry_private_is_secure): Use SECMEM_LOCK, SECMEM_UNLOCK. - (_gcry_secmem_dump_stats): Likewise. - (_gcry_secmem_malloc_internal): Removed unused variable: - compressed. - Include "ath.h". - -2003-05-21 Moritz Schulte - - * gcrypt.h (GCRY_CIPHER_SERPENT128, GCRY_CIPHER_SERPENT192, - GCRY_CIPHER_SERPENT256): New symbols. - -2003-05-19 Moritz Schulte - - * gcrypt.h: Reversed changes from 2003-03-03 since they would have - been an unnecessary ABI break. - -2003-05-13 Moritz Schulte - - * secmem.c (stats_update): New function. - (BLOCK_HEAD_SIZE): New symbol. - (MB_FLAG_ACTIVE): New symbol. - (ADDR_TO_BLOCK, BLOCK_VALID): New macros. - (mb_get_next): New function. - (mb_get_prev): New function. - (mb_merge): New function. - (mb_get_new): New function. - (unused_blocks): Removed variable. - (init_pool): Initialize new memory pool. - (_gcry_secmem_malloc): Use new heap management code. - (_gcry_secmem_free): Likewise. - (_gcry_secmem_realloc): Likewise. - Renamed type MEMBLOCK to memblock_t. - -2003-04-27 Moritz Schulte - - * cipher.h (gcry_pubkey_spec): New member: sexp_names. - -2003-04-23 Moritz Schulte - - * cipher.h (gcry_pubkey_spec): Removed members: npkey, nskey, - nenc, nsig. - (gcry_pubkey_spec): Added members: elements_pkey, elements_skey, - elements_enc, elements_sig, elements_grip. - -2003-04-17 Moritz Schulte - - * g10lib.h (GcryModule): New typedef. - - * gcrypt.h (gcry_cipher_register, gcry_cipher_unregister, - gcry_digest_register, gcry_digest_unregister, - gcry_pubkey_register, gcry_pubkey_unregister): Function - declarations removed - for now. - - * gcrypt.h (GcryModule): Declaration removed. - * gcrypt.h (GcryPubkeySpec, GcryDigestSpec, GcryCipherSpec): - Types Moved... - * cipher.h: ... here. - -2003-04-17 Moritz Schulte - - * cipher.h: Declare digest_spec_sha512 and digest_spec_384. - -2003-04-16 Moritz Schulte - - * module.c (_gcry_module_use): New function. - * g10lib.h (_gcry_module_use): Declare function. - - * libgcrypt-config.in: Support for --algorithms switch, which - prints the algorithms included in the built libgcrypt. - - * global.c (gcry_set_progress_handler): Register progress - functions depending on the enabled algorithms. - -2003-04-07 Moritz Schulte - - * Makefile.am (libgcrypt_la_SOURCES): Added module.c - - * module.c: New file. - (_gcry_module_add): New function. - (_gcry_module_drop): New function. - (_gcry_module_lookup): New function. - (_gcry_module_release): New function. - - * g10lib.h (GcryModule): New types. - (FLAG_MODULE_DISABLED): New symbol. - Added declarations for _gcry_module_add, _gcry_module_release and - _gcry_module_lookup. - - * gcrypt.h: New types: GcryPubkeySpec, GcryDigestSpec, - GcryCipherSpec. - Added declarations for: gcry_cipher_register, - gcry_cipher_unregister, gcry_digest_register, - gcry_digest_unregister, gcry_pubkey_register and - gcry_pubkey_unregister. - - * cipher.h: Removed symbols: CIPHER_ALGO_NONE, CIPHER_ALGO_IDEA, - CIPHER_ALGO_3DES, CIPHER_ALGO_CAST5, CIPHER_ALGO_BLOWFISH, - CIPHER_ALGO_SAFER_SK128, CIPHER_ALGO_DES_SK, CIPHER_ALGO_TWOFISH, - CIPHER_ALGO_TWOFISH_OLD, CIPHER_ALGO_DUMMY, PUBKEY_USAGE_SIG, - PUBKEY_USAGE_ENC, DIGEST_ALGO_MD5, DIGEST_ALGO_SHA1, - DIGEST_ALGO_RMD160, DIGEST_ALGO_TIGER, PUBKEY_ALGO_RSA, - PUBKEY_ALGO_RSA_E, PUBKEY_ALGO_RSA_S, PUBKEY_ALGO_DSA, - PUBKEY_ALGO_ELGAMAL, PUBKEY_ALGO_ELGAMAL_E. - -2003-04-02 Moritz Schulte - - * benchmark.c (md_bench): Fix error message. - -2003-03-31 Moritz Schulte - - * benchmark.c (cipher_bench): Added CTR mode. - -2003-03-30 Simon Josefsson - - * gcrypt.h (enum gcry_control_cmds): Add GCRY_SET_CTR. - (enum gcry_cipher_modes): Add GCRY_CIPHER_MODE_CTR. - (gcry_cipher_setctr): New macro to set counter. - -2003-03-19 Moritz Schulte - - * cipher.h (PUBKEY_FLAG_NO_BLINDING): New symbol. - -2003-03-22 Simon Josefsson - - * gcrypt.h: Add GCRYCTL_SET_CBC_MAC and GCRY_CIPHER_CBC_MAC. - -2003-03-19 Werner Koch - - * g10lib.h: Adjusted primegen.c prototypes. - -2003-03-12 Werner Koch - - * sexp.c (sexp_sscan): Initialize NM. Thanks to Ian Peters for - valgrinding this. - -2003-03-06 Moritz Schulte - - * secmem.h (GCRY_SECMEM_FLAG_NO_WARNING, - GCRY_SECMEM_FLAG_SUSPEND_WARNING): New symbols. - - * global.c (gcry_control): Use - GCRY_SECMEM_FLAG_{NO,SUSPEND}_WARNING, instead of hard-coded - values. - * secmem.c (_gcry_secmem_set_flags): Likewise. - * secmem.c (_gcry_secmem_get_flags): Likewise. - -2003-03-03 Moritz Schulte - - * misc.c: Removed old FIXME, since there is already a function to - set the value of `verbosity_level'. - - * gcrypt.h: Removed enumeration list: gcry_ctl_cmds. - New enumeration lists: gcry_global_control_cmds, - gcry_control_cmds, gcry_info_cmds, gcry_algo_info_cmds. - -2003-03-02 Moritz Schulte - - * gcrypt.h (gcry_cipher_reset): New macro for resetting a handle. - -2003-02-28 Moritz Schulte - - * secmem.c (DEFAULT_PAGESIZE): New symbol. - (init_pool): Use DEFAULT_PAGESIZE. - -2003-02-23 Moritz Schulte - - * secmem.h: Fix typo in declaration of _gcry_secmem_term. - - * sexp.c: Move macro definitions of `digitp', `octdigit', `alphap' - and `hexdigit' ... - * g10lib.h: ... here. - - * misc.c (_gcry_burn_stack): New function (former name: - burn_stack). - - * g10lib.h (burn_stack): Declare _gcry_burn_stack(). - -2003-01-24 Werner Koch - - * global.c (gcry_set_progress_handler): Register a random progress - handler. - -2003-01-23 Werner Koch - - * gcrypt.h (GCRY_ENABLE_QUICK_RANDOM): New. - * global.c (gcry_control): Make use of it. - -2003-01-21 Werner Koch - - * gcrypt.h (gcry_random_add_bytes): Add QUALITY argument. - -2003-01-21 Timo Schulz - - * gcrypt.h (gcry_random_add_bytes): New. - -2003-01-20 Simon Josefsson - - * gcrypt.h (gcry_md_algos): Add GCRY_MD_CRC32, - GCRY_MD_CRC32_RFC1510, GCRY_MD_CRC24_RFC2440. - -2003-01-16 Werner Koch - - * gcrypt.h (gcry_md_write): Changed type of 2nd argument to void*. - (gcry_md_hash_buffer): Changed type of both buffers to void*. - (gcry_md_setkey): Changed type of 2nd argument to void*. - (gcry_md_get_asnoid): New. - -2003-01-15 Werner Koch - - * sexp.c (gcry_sexp_length): Fixed. This was seriously broken. - -2003-01-14 Werner Koch - - * gcrypt.h (GCRYERR_INV_FLAG), global.c (gcry_strerror): New. - -2003-01-02 Werner Koch - - * libgcrypt.vers: Temporary export _gcry_generate_elg_prime for - use by GNUTLS. - -2002-12-21 Werner Koch - - * gcrypt.h: Make use of gcc's pure and malloc attributes - (gcry_md_putc): Use a helper variable to avoid multiple - evaluation of H. - * g10lib.h, stdmem.h, secmem.h: Use gcc attributes pure and malloc. - - * stdmem.c (use_m_guard): Don't default to yes. - -2002-12-19 Werner Koch - - * global.c (global_init): The meat was never run due to a faulty - check. Thanks to Nikos for pointing this out. - - * global.c (gcry_control): Return 1 and not -1 for the - initialization tests. - - * libgcrypt.vers: New. - * Makefile.am: Use this instead of the build symbol file. - - * global.c (gcry_control) : Call the random module - initializer to make sure that the pool lock flag has been - initialized. - -2002-12-09 Werner Koch - - * global.c (gcry_calloc,gcry_calloc_secure): Check for overflow. - Noted by Florian Weimer. - -2002-11-10 Simon Josefsson - - * gcrypt.h (gcry_ctl_cmds): New GCRYCTL_SET_CBC_CTS control flag. - (gcry_cipher_flags): New GCRY_CIPHER_CBC_CTS gcry_cipher_open() flag. - (gcry_cipher_cts): New macro for toggling CTS. - -2002-11-10 Werner Koch - - * gcrypt.h (GCRY_MD_MD4): New. We use a non OpenPGP value here. - -2002-09-20 Werner Koch - - * ath.c: Include sys.time.h if sys/select.h does not exist. - (ath_select, ath_waitpid): Shortcut for Windows. - * ath.h: Include some Windows headers. By Timo. - -2002-09-18 Werner Koch - - * ath.h: Prefix ath_deinit. - -2002-09-17 Werner Koch - - * benchmark.c: New. - (mpi_bench, do_powm): Add a a simple test for RSA. - - * global.c (global_init): New. Use it instead of the setting - any_init_done. Initialize the ATH system. - (gcry_check_version): Hook global_init in. This is the suggested - way to initialize the library. - (_gcry_no_internal_locking): Removed. We simply call a ath_deinit - and leave it to ATH to disbale the locking. - - * ath.c, ath.h, ath-pth.c, ath-pthread.c: New. Taken from GPGME. - * mutex.h: Removed. - * Makefile.am (ath_components): New. - -2002-09-16 Werner Koch - - * secmem.c (_gcry_secmem_dump_stats): Replaced fprintf by log_*. - -2002-08-23 Werner Koch - - * missing-string.c: Removed unneeded strlwr. - - * libgcrypt.m4: Made much more simple. - * libgcrypt-config.in: Made --prefix work for --libs. - -2002-08-14 Werner Koch - - * gcrypt.h: Add GCRY_CIPGER_DES. Included string.h for size_t. - Suggested by Simon Josefsson. - -2002-07-25 Werner Koch - - * cipher.h: Added prototypes for progress functions. - * global.c: Include cipher.h for those prototypes. - - * stdmem.c (_gcry_private_realloc): Replaced void* by char * for - pointer arithmetic reasons. Noted by Stephan Austermuehle. - -2002-06-24 Werner Koch - - * missing-string.c: Include ctype.h. - - * gcrypt.h (gcry_mpi_invm, gcry_mpi_div, gcry_mpi_mod) - (gcry_mpi_swap): New. - -2002-06-18 Werner Koch - - * gcrypt.h: Added a bunch of brief function descriptions. - -2002-05-21 Werner Koch - - * misc.c (_gcry_log_printf): Don't initialize a va_list. Noted by - Jeff Johnson. - - * global.c (gcry_set_progress_handler): New. - - * gcrypt.h: Replaced the typedef for byte. - -2002-05-16 Werner Koch - - * missing-string.c: New. - - * gcrypt.h: Add new error codes GCRYERR_SEXP_ and typedefs - GcryMPI, GcrySexp, GcryCipherHd, GcryMDHd as aliases for the old - ones using an underscore. - - * global.c (gcry_strerror): Add strings fro the new error codes. - * sexp.c (gcry_sexp_canon_len): Use a macro to convert from new to - old error codes. - (gcry_sexp_create,gcry_sexp_new): New. - -2002-05-15 Werner Koch - - * mutex.h (DEFINE_LOCAL_MUTEX): Macro to define a mutex and - initialize it so that we can detect an unitialized mutex and don't - read from stdin. - -2002-05-14 Werner Koch - - Changed license of all files to the LGPL. - -2002-05-07 Werner Koch - - * global.c (gcry_control): Add commands - GCRYCTL_ANY_INITIALIZATION_P and GCRYCTL_INITIALIZATION_FINISHED_P - so that other libraries are able to check for required - initializations. - -2002-05-02 Werner Koch - - * gcrypt.h (GCRYCTL_DISABLE_INTERNAL_LOCKING): New. - * global.c (gcry_control): Implement it. - (_gcry_no_internal_locking): New. - * mutex.h: Prefixed all fucntions with _gcry_. Bypass all - functions when desired. - - * gcrypt.h (GCRYCTL_DISABLE_SECMEM): New. - * global.c (gcry_control,gcry_malloc_secure,gcry_is_secure): - Implement it here. - * secmem.c (_gcry_private_is_secure): Return false if the pool is - not initialized. - - * gcrypt.h (GCRYCTL_INITIALIZATION_FINISHED): New. - - * gcrypt.h (gcry_cipher_algos): Replaced RINDAEL by AES and change - the macros to expand from rijdael to aes. - - * stdmem.c (_gcry_private_malloc): Return NULL for 0 byte allocation. - (_gcry_private_malloc_secure): Ditto. - - * g10lib.h: Copied the JNLIB_GCC macros from ../jnlib/mischelp.h - and removed the inclusion of that file. - -2002-04-15 Werner Koch - - * global.c (gcry_strdup): New. - -2002-03-18 Werner Koch - - * mutex.h: New file with a portable thread mutex implementation - written by Marcus Brinkmann. Taken from GPGME. - -2002-02-18 Werner Koch - - * sexp.c (gcry_sexp_sscan): Don't initialize the dummy - variable. Suggested by Jordi Mallach. - -2002-01-31 Werner Koch - - * sexp.c (suitable_encoding,convert_to_hex,convert_to_string) - (convert_to_token): New. - (gcry_sexp_sprint): Better formatting of advanced encoding, does - now insert LFs and escapes all unprintable characters. - (unquote_string): New. - (sexp_sscan): Implemented the missing conversion of quoted strings. - -2002-01-26 Werner Koch - - * libgcrypt-config.in: Add copyright notice. - -2002-01-11 Werner Koch - - * sexp.c (gcry_sexp_canon_len): Fixed last change. - -2002-01-01 Timo Schulz - - * stdmem.c (_gcry_private_realloc): If pointer is NULL now realloc - behaves like malloc. - -2001-12-20 Werner Koch - - * sexp.c (gcry_sexp_canon_len): Describe the error codes and - return an error if this is not a S-Exp; i.e. it does not start - with an open parenthesis. - -2001-12-18 Werner Koch - - * sexp.c (gcry_sexp_canon_len): Fixed the test on NULL buffer. - - * Makefile.am (DISTCLEANFILES): Include libgcrypt.sym - - * sexp.c: Removed the commented test code because we now have a - test in ../tests/ - -2001-12-17 Werner Koch - - * sexp.c (gcry_sexp_canon_len): New. - -2001-12-11 Werner Koch - - * gcrypt.h: Fixed AES128 macro, add enum for OFB mode. - -2001-12-05 Werner Koch - - * misc.c (_gcry_log_printf): New. - * sexp.c (dump_string,gcry_sexp_dump): Use logging functions - instead of stderr. - -2001-11-16 Werner Koch - - * gcrypt.h: New constant GCRYCTL_IS_ALGO_ENABLED. - -2001-10-02 Werner Koch - - * gcrypt.h: Removed a couple of trailing commas. - -2001-08-28 Werner Koch - - * sexp.c (sexp_sscan): Add an argument to enable the - arg_ptr. Changed all callers. Suggested by Tom Holroyd. - -2001-08-03 Werner Koch - - * global.c (gcry_strerror): Updated list of error codes. - -2001-07-23 Werner Koch - - * gcrypt.h: Replaced the last ulong. Noted by Rami Lehti. - -2001-05-31 Werner Koch - - * gcrypt.h, mpi.h: Made some mpi functions public. - - * wrapper.c: Removed. - * global.c: Renamed all g10_ prefixed functions which had wrappers - to gcry_xxx. So we now use the exported memory functions inernally. - - Renamed all g10_ prefixed functions to _gcry_ prefixed ones. - - * g10lib.h (_GCRYPT_IN_LIBGCRYPT): Replace defintion by a test on it. - -2001-05-28 Werner Koch - - * libgcrypt.m4: Check GCRYPT_VERSION macro and not LIBGCRYPT_VERSION. - - * mpi.h: Removed mpi_fromstr prototype. - -2001-01-11 Werner Koch - - * Makefile.am (libgcrypt_la_SOURCES): Add mpi.h - -2000-12-19 Werner Koch - - * types.h: Moved from ../include to here. - - Major change: - Removed all GnuPG stuff and renamed this piece of software - to gcrypt. - -2000-11-14 Werner Koch - - * mpi.h: Moved to ../mpi. - - * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency - problems. - -2000-10-11 Werner Koch - - * mpi.h: Changed the way mpi_limb_t is defined. - -2000-10-10 Werner Koch - - * Makefile.am: Take version-info from configure. - -2000-10-09 Werner Koch - - * gcrypt.h: New cipher mode, new algo Arcfour and new error code - GCRYERR_INV_CIPHER_MODE. - * global.c (gcry_strerror): New errorcode. - -Wed Oct 4 13:16:18 CEST 2000 Werner Koch - - * gcrypt.h (gcry_md_setkey): Replaced macro by function prototype. - -Mon Sep 18 16:35:45 CEST 2000 Werner Koch - - * gcrypt.h (GCRYCTL_GET_ALGO_USAGE): New. - - * secmem.c (secmem_realloc): check for failed secmem_malloc. By - Matt Kraai. - -Mon Jul 31 10:04:47 CEST 2000 Werner Koch - - * sexp.c: Removed the datalen fields from list tags. - (gcry_sexp_car_data,gcry_sexp_cdr_data,gcry_sexp_car_mpi, - gcry_sexp_cdr_mpi): Removed. - (gcry_sexp_nth,gcry_sexp_nth_data,gcry_sexp_nth_mpi): New. - -Fri Jul 28 18:19:11 CEST 2000 Werner Koch - - * sexp.c (sexp_sscan): Fixed reallocation to secure memory. - (new_empty_list): Removed - (gcry_sexp_length): New. - (gcry_sexp_enum): Removed. - (normalize): New. Reworked the whole thing to use NULL for an empty list. - (make_space): New instead of the macro. - -Tue Jul 25 17:44:15 CEST 2000 Werner Koch - - * sexp.c: Major rewrite. - (gcry_sexp_sscan): Reordered arguments. Moved functionality to .. - (sexp_sscan): .. this. - (gcry_sexp_build): New. - (gcry_sexp_new_name_mpi, gcry_sexp_new_name_data, gcry_sexp_new_data, - gcry_sexp_new_mpi): Removed. - -Fri Jul 14 19:38:23 CEST 2000 Werner Koch - - * gcrypt.h (gcry_md_start_debug, gcry_md_stop_debug): New. - (gcry_ctl_cmds): New control values - - * sexp.c (gcry_sexp_sscan): Add hex format parsing. - - * secmem.c (lock_pool): Check for ENOSYS return my mlock() on old SCOs. - (pool_is_mmapped): Made volatile. - (lock_pool): No more warning for QNX. By Sam Roberts. - (lock_pool,secmem_init): Additional check for dropped privs. - -2000-03-21 09:18:48 Werner Koch (wk@habibti.gnupg.de) - - * gcrypt.h (gcry_md_setkey): New. - (GCRY_MD_FLAG_HMAC): New. - -Mon Jan 31 16:37:34 CET 2000 Werner Koch - - * Makefile.am: Add g10lib.h - -Thu Jan 27 18:00:44 CET 2000 Werner Koch - - * sexp.c (gcry_sexp_sscan): Allow NULL for erroff. - -Mon Jan 24 22:24:38 CET 2000 Werner Koch - - * sexp.c (gcry_sexp_alist): New. - -Mon Jan 24 13:04:28 CET 2000 Werner Koch - - * secmem.c: Moved from ../util to here. - * secmem.h: New. - * stdmem.c: New. Based on the old ../util/memory.c. - * stdmem.h: New. - -Wed Dec 8 21:58:32 CET 1999 Werner Koch - - * gcrypt.m4: New. - * gcrypt-config: New. - - * mpi.h (mpi_get_nbit_info): Removed - (mpi_set_nbit_info): Removed. - (struct gcry_mpi): Removed the nbits field. - - * misc.c (g10_log_verbosity): New. - - * global.c (g10_xstrdup): New. - - * mpiapi.c: Removed. - - * mpi.h: Moved from ../include to here. Removed some obsolete - prototypes and the iobuf.h header. - * cipher.h: Moved from ../include to here. Removed the mpi.h header. - * g10lib.h: Moved from ../include to here. - -Fri Nov 19 17:15:20 CET 1999 Werner Koch - - * sexp.c (dump_string): New. Taken from gnupg/util/miscutil.c. - (do_dump_list): s/print_string/dump_string/. - - * testapi.c: New. - - * mpiapi.c (gcry_mpi_randomize): Use new random API. - -Sat Nov 13 17:44:23 CET 1999 Werner Koch - - * gloabl.c (gcry_control): Add cases for dumping random - and secmem stats. - -Tue Oct 26 14:10:21 CEST 1999 Werner Koch - - * pkapi.c: Removed. - - * symapi.c: Removed. - - * g10lib.h: Moved to ../include. - - * mdapi.c: Removed. - -Wed Jul 7 13:08:40 CEST 1999 Werner Koch - - * sexp.c: New. - -Tue Dec 8 13:15:16 CET 1998 Werner Koch - - * gcrypt.h: New - * mpiapi.c: New - - - Copyright (C) 1998,1999,2000,2001,2002,2003 - 2004,2005,2008,2009,2011 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/src/Makefile.am b/grub-core/lib/libgcrypt/src/Makefile.am deleted file mode 100644 index 91680220e..000000000 --- a/grub-core/lib/libgcrypt/src/Makefile.am +++ /dev/null @@ -1,143 +0,0 @@ -# Makefile.am - for gcrypt/src -# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, -# 2006, 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 Lesser 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 . - - -## Process this file with automake to produce Makefile.in - -EXTRA_DIST = Manifest libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \ - gcrypt.h.in libgcrypt.def - -bin_SCRIPTS = libgcrypt-config -m4datadir = $(datadir)/aclocal -m4data_DATA = libgcrypt.m4 -include_HEADERS = gcrypt.h gcrypt-module.h - -lib_LTLIBRARIES = libgcrypt.la -bin_PROGRAMS = dumpsexp hmac256 -if USE_RANDOM_DAEMON -sbin_PROGRAMS = gcryptrnd -bin_PROGRAMS += getrandom -endif USE_RANDOM_DAEMON - -# Depending on the architecture some targets require libgpg-error. -if HAVE_W32CE_SYSTEM -arch_gpg_error_cflags = $(GPG_ERROR_CFLAGS) -arch_gpg_error_libs = $(GPG_ERROR_LIBS) -else -arch_gpg_error_cflags = -arch_gpg_error_libs = -endif - - -if HAVE_LD_VERSION_SCRIPT - libgcrypt_version_script_cmd = -Wl,--version-script=$(srcdir)/libgcrypt.vers -else - libgcrypt_version_script_cmd = -endif - -libgcrypt_la_CFLAGS = $(GPG_ERROR_CFLAGS) -libgcrypt_la_SOURCES = g10lib.h visibility.c visibility.h types.h \ - cipher.h cipher-proto.h \ - misc.c global.c sexp.c hwfeatures.c \ - stdmem.c stdmem.h secmem.c secmem.h \ - mpi.h missing-string.c module.c fips.c \ - hmac256.c hmac256.h \ - ath.h ath.c - -if HAVE_W32_SYSTEM - -RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(libgcrypt_la_CPPFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) - -SUFFIXES = .rc .lo - -.rc.lo: - $(LTRCCOMPILE) -i "$<" -o "$@" - -gcrypt_res = versioninfo.lo -no_undefined = -no-undefined -export_symbols = -export-symbols $(srcdir)/libgcrypt.def - -install-def-file: - $(INSTALL) $(srcdir)/libgcrypt.def $(DESTDIR)$(libdir)/libgcrypt.def - -uninstall-def-file: - -rm $(DESTDIR)$(libdir)/libgcrypt.def - -gcrypt_deps = $(gcrypt_res) libgcrypt.def - -else !HAVE_W32_SYSTEM - -gcrypt_res = -gcrypt_res_ldflag = -no_undefined = -export_symbols = -install-def-file: -uninstall-def-file: - -gcrypt_deps = - -endif !HAVE_W32_SYSTEM - - -libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) \ - $(libgcrypt_version_script_cmd) -version-info \ - @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@ -libgcrypt_la_DEPENDENCIES = \ - ../cipher/libcipher.la \ - ../random/librandom.la \ - ../mpi/libmpi.la \ - ../compat/libcompat.la \ - $(srcdir)/libgcrypt.vers $(gcrypt_deps) -libgcrypt_la_LIBADD = $(gcrypt_res) \ - ../cipher/libcipher.la \ - ../random/librandom.la \ - ../mpi/libmpi.la \ - ../compat/libcompat.la $(GPG_ERROR_LIBS) - - -dumpsexp_SOURCES = dumpsexp.c -dumpsexp_CFLAGS = $(arch_gpg_error_cflags) -dumpsexp_LDADD = $(arch_gpg_error_libs) - -hmac256_SOURCES = hmac256.c -hmac256_CFLAGS = -DSTANDALONE $(arch_gpg_error_cflags) -hmac256_LDADD = $(arch_gpg_error_libs) - -if USE_RANDOM_DAEMON -gcryptrnd_SOURCES = gcryptrnd.c -gcryptrnd_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS) -gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS) - -getrandom_SOURCES = getrandom.c -endif USE_RANDOM_DAEMON - - -install-data-local: install-def-file - -uninstall-local: uninstall-def-file - -# FIXME: We need to figure out how to get the actual name (parsing -# libgcrypt.la?) and how to create the hmac file already at link time -# so that it can be used without installing libgcrypt first. -#install-exec-hook: -# ./hmac256 "What am I, a doctor or a moonshuttle conductor?" \ -# < $(DESTDIR)$(libdir)/libgcrypt.so.11.5.0 \ -# > $(DESTDIR)$(libdir)/.libgcrypt.so.11.5.0.hmac diff --git a/grub-core/lib/libgcrypt/src/Manifest b/grub-core/lib/libgcrypt/src/Manifest deleted file mode 100644 index 2d003d83e..000000000 --- a/grub-core/lib/libgcrypt/src/Manifest +++ /dev/null @@ -1,58 +0,0 @@ -# Manifest - checksums of the src directory -# Copyright 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 - -# Checksums for all source files in this directory. Format is -# filename, blanks, base-64 part of an OpenPGP detached signature -# without the header lines. Blank lines and lines beginning with a -# hash mark are ignored. A tool to process this file is available by -# cvs -d :pserver:anoncvs@cvs.gnupg.org:/cvs/wk co misc-scripts/manifest-tool -# -# The special entry "$names$" holds a signature over all sorted -# filenames excluding itself. - -gcrypt.h iQCVAwUAQH5RsTEAnp832S/7AQK7xgP+Kc3NY9lipZkaAMrnHDkQVLdHYwTbZWuGOYdTLp8Xy7Auh9wtWV9hrWVUqs+kxDzT/2iF6XkO3WT3rf/PmQ/Q0TIGfOyjE3c/qvB/jVippaxoGda3tnGpODytdI3XPhfPS0Ss8nDzfCStPBGAEq0OVU7imnExrFzhRXt+Gljr0o0==Yagz -gcrypt-module.h iQCVAwUAQH5UXzEAnp832S/7AQJMQgQAzumz9aaZelhw+FxTCeVadphBxt1bbNQvMrnddYYblyJv+AcxZ9ZxGz2oPeusN58Qg54DQcaW3lYhTgnWfXultsi+Ruxlz7400OUrzSXOl3At7KssdODAoscFzZIgh94G9lzQxEBr9lTXI9R3LsPFJP6muNG4frcNBAA42yckK7w==BBp5 - -ath.c iQCVAwUAQH5E+DEAnp832S/7AQKFpgP+KSZHtVcnh9FFggIyHKbALUljW2FXauasZvFyN8Sk/mIMgKxyXFOG1THBAUzWLaKWIEWU+WkYU7uThqBtpnEImM5AenWzbQuJjftPC3gVHO8yjjmBWD4zmJj28htoKDoa/xDsoqumrHxae3FYcaCWtYGVjM/Pbl+OMRMOFAhp0ho==lQZ3 -ath.h iQCVAwUAQH5FODEAnp832S/7AQKiuQQAg4K+KOAn1LWBZN32MAhms4FeZKoce0fAuZW7BpyY4cCxIVgxqrtUC90CDykw8XegFfOyyYrgd0NmaMVdY7HZDncNOvIPxpgFQPCZrycsMOoAtoVwjK704RDeNo3zmeyxTKeDH+3M1J7JmLiafaEdSbOC8flX/W0icaV0Ol4dmBc==Ll6w - -cipher.h iQCVAwUAQH5FUzEAnp832S/7AQJKLgP9GSSk9f7EINIRqSQH1XKX+dYzt3phDHdqFTUGIfYNh7YzGdy0drvgFhG4k15nqDouKRuFVM/hKY3ZVY7JccmKXKGAH6+ZYShoG6LMFfIGgDX8zne0dNxc72PLfns3fVxNn/RlHmHBkrQ+ppjR9HnSthFmOqzbQaW1BKmc3Z2x5GU==lIeW -g10lib.h iQCVAwUAQH5FejEAnp832S/7AQJ75wP/ZjOybwRix5eoXdfVeXPjoPygejzpYJJdMUGN3Y5UtkfBu9mPREsKfvZ6tH+Evjx+3xfeAb4bU/k2mRMp0tiWnk2koToS08vI9uxnioKQr9oulZH6r28S+NLSgMQuEGN1JNUky6RQ9TTNRndeTjKKSrEjZ7V6bv+rb8A1bYCKChs==P5mk -mpi.h iQCVAwUAQH5FwzEAnp832S/7AQJJ4wP9E3jVkcO9M0YtSBHIbjG3hDWKWXzi86AlUh51qiE8/2XP0FfjA4TosyvmicZs7j48HitAByr9tHOSxnbeo7NBf17ICwAo6Eqty+wKDg+eyLeEGUy7VpVK3RJRQAA4H+kl3S2l3YMTKf3WJlbc7qkWSXZspdy5c9sAxeodCKrAubU==oALf - -global.c iQCVAwUAQH5HFzEAnp832S/7AQJc+QQAvi53ZkMCzLnVULHvhI6W+EX537zi9n8cplYguvIJqUhAZrP68yGAIyqyCONbZVDyB7wqeXdUMLzMk7W8fg+xuk5JSDpppAQf2m/bdQyze6XVqJso682eYBM8+b9z/IVEvLaFwhZcOKO1bcXudBlBCcJgVDpupfTtAWgPnewil9Q==Xwy1 -misc.c iQCVAwUAQH5IIjEAnp832S/7AQKNJAQAkEpyY3fCG7tvADJFAW9xA7DEQwLCa8YmiUhHvrEsWOI4YgvS7LUbWWc7VqK+ryORvXLKRAVieznbnHAuy0TKtqdnmA/kUmiurS0ah5SWqR/iuAeJtt0RGsmZaZ6oa2m4PZ2Y2GCHSTZqcclvwsetS9eq5AipxHxYFUltu5wGZNI==twM2 -missing-string.c iQCVAwUAQH5JfjEAnp832S/7AQI3ZQQAg55eEJbGQQHyBEJGxvt/FXpQiXcoDit3ZHzvdaQn/NUgdLjCHiWVzhyCXACGivLWMNModDaSaZk073NXxVkWfPcX9vkF//Wugwzidd5P3Bfu5k35o+Xxz82fsk5KuFGGq1mBUZ07xUYQ8KkKkhADUkr0QiQAuypp079Yq0uUC7Q==zvKn -module.c iQCVAwUAQH5JvjEAnp832S/7AQKlMgQAjZYTXMpWb5kHxCMXzRi069Ku/4/xnWsD+S0dje1LiKzCnRpwTTxARzc/y10Y8OcygkMuR4unEaWedO+9syjjty3fBCcue/j7YlLitq5EC9UE4o23poWvWCuX9Tadm2DK5qf4p7smMJ22O22cLTYTVCyAoYTQ2xC8ajzBsBRkX80==yRRD -secmem.c iQCVAwUAQH5LLDEAnp832S/7AQKtFwQAwY2wBr6WJC1cwqp/1DQoKzHx9C3plONxbZMazwR7VMI83NUbBAbv1mcxpeZWXmb2dRrnsR1VBbNPDSbJLN5T6czLQ2nIb6mnq9u8Ip4SAa+GCWfDV4AUtAJ4hN/yvWo8iEKu+KD5iJ6xJh31NdXjt5yk6vnk46SA6R4FkHdIEXc==UKVr -secmem.h iQCVAwUAQH5LTDEAnp832S/7AQIsJwQAkZUu4hvmh9NXCLNm98+tGZFzWYvZO/NffC2wdPE8Q/OTa/m3g+oBbEhaV1ze3oY4t1F/p7ZHFx5CsIp4zVjyPkxlni8AAVMUOQr/LopyxouHn2OjKO+dVqecWQf01+nPWjklbL2FZ3mQ99k2qeWZlVSkz0nm8u39F3v7z3OTCss==AJqE -sexp.c iQCVAwUAQH5LojEAnp832S/7AQKCTQQArlrj1KGwR2x93fcyN3M0iXuGkBq5R9KNu+1Bq04G4SLlpZ1RRY0OjV3L9To1BHTd01lXlO8MNz7NpRxWlG1Sw5FohbBlhWZQRcW8GdAawJPcfIY2Y8Ek6Yx8quZKbk9uD3bcBmStmg0P+TIA0nr20bmtfB3uX2KQVHQqWZQT5qU==P8FE -stdmem.c iQCVAwUAQH5LzjEAnp832S/7AQLOUAP9FU16itXBBrkfRDGmhUjAOeEEKdd+brQ3XdT8xoLvP/IH/6U1Kq3ampP2/xcL4kwVdz2rw6NRzP7jlL/yM3tW722lSS/JPJkH+2+qUkcb0fYNoql/WYPMYp1/Mzu6ttXnjag1cQGlKIyYAD+G6h3FtpLwQy0hEJopnF9+Ovd8U7A==CkiZ -stdmem.h iQCVAwUAQH5L8jEAnp832S/7AQIH0wP+Lyqh0tj++s2L79Tmf/gqgCK+HLMxTddcewF3XbsYf9T5FmLez1gz6Ggti4Ss9VjozOA3ti3trCiA/YNRmV9AYw4zLUPm+MsjJuveL/AgB9HdoD2v+RfJm0WwgSKiysp+8iyjg3Plopmhba4cGuOP5MJ3CWTqYwPmJVscUKC6g38==02MN - -types.h iQCVAwUAQH5MKTEAnp832S/7AQLqTAP6A3mUMD5MMkBkebq4bRY6Bq0KsgdKfZ8TLhc2o87gFay8YD0Uom3YJNG2LF/rAIct2ih4jYJaIb5dRfJ0KJoPi2ETd462J8OFCL4fjq9TaSjB2pXcB+kWoxzPasGNg2Ukk0dQ6lvF1tSYrtt32PVI7q/UaPsjTylgRmzLfX/VxrU==OMu3 - - -# Configuration -Makefile.am iQCVAwUAQH5WVjEAnp832S/7AQLmsQP/bbI8/UWAC5yITVhGcCOCbN/FaMqXVKjxESzo6GTs02jxK1y3RuuaoNU1ssQZGAxpFiMJW8u933V3yTHFMxWpwHemDnEyv/a8YACxJBQ0tQgpgHS716BjMbHOfcuOis2WlCOOm0ErjhAYNa4NQ1q3jwkOvTDLFpdnqaWI2wWn08U==Yjun -libgcrypt.m4 iQCVAwUAQH5MbTEAnp832S/7AQJ1uAQA1C6xI7qXiKVtUeXawhPytAldosrzcXmqz34xi7JklQqw83d68WtWHFMBEUa7MKfi4WCbuQb7FjGUvMRw5z/T9ez7CoDekHc63+cIIZLQ23weUK8GaA1uQLoD0scmT41J5RkBlJbH7ck1zRd3d04o75rWNEUNit6KBvrQ4Pd8oQ8==uMgB -libgcrypt-config.in iQCVAwUAQH5UbzEAnp832S/7AQJISgP+Nbd2AQnDM/k8sQLbvz8YZjwX3LigZM+AkF1VAwyAm6YOU3nrXnz5t+cXkQD2dkz4L2F0AAsIkFiJsrgmZgCp2h1L6LeFnH+hoId9RhbYw4NkDaHb+MC9JcalpcfFvvxq6vM/W37bSFimM78P+5RLKypXCytVQNAAaIRgZjVfXY8==IGDS -libgcrypt.vers iQCVAwUAQH5MjTEAnp832S/7AQKCdQQAotG6Z3zdcePI0V33YY2sh91uYkLBNhQw+PzyE3BRRAVhMGLOBD1nSWJHJvE3eyCVOqFY0ZmvpVex51Fa0D/TwsJOO4RVxf1L9bbAncu9OuEXaGXKytLZp54TliDTAWGDq0lvtx1TvDDgtM8TbbaXvMbjfQ4wXBxdLvaenFCTlR4==kgHq - -$names$ iQCVAwUAQH5UhDEAnp832S/7AQK/jwP9H7A3mI99M1NGuhD+16C+2gJIITB8GJeYeUd3vm8kWQ5n76WyMCdeA62qn0JUddIBjAbagtfvTL5aesnD9MlhEGaNlHauU7SINTIJ8njKf87EAAfDZrhS/tGDziC2nakMPweRxXQCLDWHkBPjYfrspSLLohjdegqBvTNyVM76+KE==3p9Z diff --git a/grub-core/lib/libgcrypt/src/ath.c b/grub-core/lib/libgcrypt/src/ath.c deleted file mode 100644 index 656ed896f..000000000 --- a/grub-core/lib/libgcrypt/src/ath.c +++ /dev/null @@ -1,344 +0,0 @@ -/* ath.c - Thread-safeness library. - Copyright (C) 2002, 2003, 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 - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with Libgcrypt; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include /* Right: We need to use assert and not gcry_assert. */ -#include -#ifdef HAVE_SYS_SELECT_H -# include -#else -# include -#endif -#include -#ifndef _WIN32 -#include -#endif -#include - -#include "ath.h" - - - -/* The interface table. */ -static struct ath_ops ops; - -/* True if we should use the external callbacks. */ -static int ops_set; - - -/* For the dummy interface. */ -#define MUTEX_UNLOCKED ((ath_mutex_t) 0) -#define MUTEX_LOCKED ((ath_mutex_t) 1) -#define MUTEX_DESTROYED ((ath_mutex_t) 2) - - -/* Return the thread type from the option field. */ -#define GET_OPTION(a) ((a) & 0xff) -/* Return the version number from the option field. */ -#define GET_VERSION(a) (((a) >> 8)& 0xff) - - - -/* The lock we take while checking for lazy lock initialization. */ -static ath_mutex_t check_init_lock = ATH_MUTEX_INITIALIZER; - -int -ath_init (void) -{ - int err = 0; - - if (ops_set) - { - if (ops.init) - err = (*ops.init) (); - if (err) - return err; - err = (*ops.mutex_init) (&check_init_lock); - } - return err; -} - - -/* Initialize the locking library. Returns 0 if the operation was - successful, EINVAL if the operation table was invalid and EBUSY if - we already were initialized. */ -gpg_err_code_t -ath_install (struct ath_ops *ath_ops, int check_only) -{ - if (check_only) - { - unsigned int option = 0; - - /* Check if the requested thread option is compatible to the - thread option we are already committed to. */ - if (ath_ops) - option = ath_ops->option; - - if (!ops_set && GET_OPTION (option)) - return GPG_ERR_NOT_SUPPORTED; - - if (GET_OPTION (ops.option) == ATH_THREAD_OPTION_USER - || GET_OPTION (option) == ATH_THREAD_OPTION_USER - || GET_OPTION (ops.option) != GET_OPTION (option) - || GET_VERSION (ops.option) != GET_VERSION (option)) - return GPG_ERR_NOT_SUPPORTED; - - return 0; - } - - if (ath_ops) - { - /* It is convenient to not require DESTROY. */ - if (!ath_ops->mutex_init || !ath_ops->mutex_lock - || !ath_ops->mutex_unlock) - return GPG_ERR_INV_ARG; - - ops = *ath_ops; - ops_set = 1; - } - else - ops_set = 0; - - return 0; -} - - -static int -mutex_init (ath_mutex_t *lock, int just_check) -{ - int err = 0; - - if (just_check) - (*ops.mutex_lock) (&check_init_lock); - if (*lock == ATH_MUTEX_INITIALIZER || !just_check) - err = (*ops.mutex_init) (lock); - if (just_check) - (*ops.mutex_unlock) (&check_init_lock); - return err; -} - - -int -ath_mutex_init (ath_mutex_t *lock) -{ - if (ops_set) - return mutex_init (lock, 0); - -#ifndef NDEBUG - *lock = MUTEX_UNLOCKED; -#endif - return 0; -} - - -int -ath_mutex_destroy (ath_mutex_t *lock) -{ - if (ops_set) - { - if (!ops.mutex_destroy) - return 0; - - (*ops.mutex_lock) (&check_init_lock); - if (*lock == ATH_MUTEX_INITIALIZER) - { - (*ops.mutex_unlock) (&check_init_lock); - return 0; - } - (*ops.mutex_unlock) (&check_init_lock); - return (*ops.mutex_destroy) (lock); - } - -#ifndef NDEBUG - assert (*lock == MUTEX_UNLOCKED); - - *lock = MUTEX_DESTROYED; -#endif - return 0; -} - - -int -ath_mutex_lock (ath_mutex_t *lock) -{ - if (ops_set) - { - int ret = mutex_init (lock, 1); - if (ret) - return ret; - return (*ops.mutex_lock) (lock); - } - -#ifndef NDEBUG - assert (*lock == MUTEX_UNLOCKED); - - *lock = MUTEX_LOCKED; -#endif - return 0; -} - - -int -ath_mutex_unlock (ath_mutex_t *lock) -{ - if (ops_set) - { - int ret = mutex_init (lock, 1); - if (ret) - return ret; - return (*ops.mutex_unlock) (lock); - } - -#ifndef NDEBUG - assert (*lock == MUTEX_LOCKED); - - *lock = MUTEX_UNLOCKED; -#endif - return 0; -} - - -ssize_t -ath_read (int fd, void *buf, size_t nbytes) -{ - if (ops_set && ops.read) - return (*ops.read) (fd, buf, nbytes); - else - return read (fd, buf, nbytes); -} - - -ssize_t -ath_write (int fd, const void *buf, size_t nbytes) -{ - if (ops_set && ops.write) - return (*ops.write) (fd, buf, nbytes); - else - return write (fd, buf, nbytes); -} - - -ssize_t -#ifdef _WIN32 -ath_select (int nfd, void *rset, void *wset, void *eset, - struct timeval *timeout) -#else -ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, - struct timeval *timeout) -#endif -{ - if (ops_set && ops.select) - return (*ops.select) (nfd, rset, wset, eset, timeout); - else -#ifdef _WIN32 - return -1; -#else - return select (nfd, rset, wset, eset, timeout); -#endif -} - - -ssize_t -ath_waitpid (pid_t pid, int *status, int options) -{ - if (ops_set && ops.waitpid) - return (*ops.waitpid) (pid, status, options); - else -#ifdef _WIN32 - return -1; -#else - return waitpid (pid, status, options); -#endif -} - - -int -#ifdef _WIN32 -ath_accept (int s, void *addr, int *length_ptr) -#else -ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr) -#endif -{ - if (ops_set && ops.accept) - return (*ops.accept) (s, addr, length_ptr); - else -#ifdef _WIN32 - return -1; -#else - return accept (s, addr, length_ptr); -#endif -} - - -int -#ifdef _WIN32 -ath_connect (int s, void *addr, int length) -#else -ath_connect (int s, struct sockaddr *addr, socklen_t length) -#endif -{ - if (ops_set && ops.connect) - return (*ops.connect) (s, addr, length); - else -#ifdef _WIN32 - return -1; -#else - return connect (s, addr, length); -#endif -} - - -int -#ifdef _WIN32 -ath_sendmsg (int s, const void *msg, int flags) -#else -ath_sendmsg (int s, const struct msghdr *msg, int flags) -#endif -{ - if (ops_set && ops.sendmsg) - return (*ops.sendmsg) (s, msg, flags); - else -#ifdef _WIN32 - return -1; -#else - return sendmsg (s, msg, flags); -#endif -} - - -int -#ifdef _WIN32 -ath_recvmsg (int s, void *msg, int flags) -#else -ath_recvmsg (int s, struct msghdr *msg, int flags) -#endif -{ - if (ops_set && ops.recvmsg) - return (*ops.recvmsg) (s, msg, flags); - else -#ifdef _WIN32 - return -1; -#else - return recvmsg (s, msg, flags); -#endif -} diff --git a/grub-core/lib/libgcrypt/src/ath.h b/grub-core/lib/libgcrypt/src/ath.h deleted file mode 100644 index 8769551be..000000000 --- a/grub-core/lib/libgcrypt/src/ath.h +++ /dev/null @@ -1,147 +0,0 @@ -/* ath.h - Thread-safeness library. - Copyright (C) 2002, 2003, 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 - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with Libgcrypt; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef ATH_H -#define ATH_H - -#include - -#ifdef _WIN32 -# include -#else /* !_WIN32 */ -# ifdef HAVE_SYS_SELECT_H -# include -# else -# include -# endif -# include -# ifdef HAVE_SYS_MSG_H -# include /* (e.g. for zOS) */ -# endif -# include -#endif /* !_WIN32 */ -#include - - - -/* Define _ATH_EXT_SYM_PREFIX if you want to give all external symbols - a prefix. */ -#define _ATH_EXT_SYM_PREFIX _gcry_ - -#ifdef _ATH_EXT_SYM_PREFIX -#define _ATH_PREFIX1(x,y) x ## y -#define _ATH_PREFIX2(x,y) _ATH_PREFIX1(x,y) -#define _ATH_PREFIX(x) _ATH_PREFIX2(_ATH_EXT_SYM_PREFIX,x) -#define ath_install _ATH_PREFIX(ath_install) -#define ath_init _ATH_PREFIX(ath_init) -#define ath_mutex_init _ATH_PREFIX(ath_mutex_init) -#define ath_mutex_destroy _ATH_PREFIX(ath_mutex_destroy) -#define ath_mutex_lock _ATH_PREFIX(ath_mutex_lock) -#define ath_mutex_unlock _ATH_PREFIX(ath_mutex_unlock) -#define ath_read _ATH_PREFIX(ath_read) -#define ath_write _ATH_PREFIX(ath_write) -#define ath_select _ATH_PREFIX(ath_select) -#define ath_waitpid _ATH_PREFIX(ath_waitpid) -#define ath_connect _ATH_PREFIX(ath_connect) -#define ath_accept _ATH_PREFIX(ath_accept) -#define ath_sendmsg _ATH_PREFIX(ath_sendmsg) -#define ath_recvmsg _ATH_PREFIX(ath_recvmsg) -#endif - - -enum ath_thread_option - { - ATH_THREAD_OPTION_DEFAULT = 0, - ATH_THREAD_OPTION_USER = 1, - ATH_THREAD_OPTION_PTH = 2, - ATH_THREAD_OPTION_PTHREAD = 3 - }; - -struct ath_ops -{ - /* The OPTION field encodes the thread model and the version number - of this structure. - Bits 7 - 0 are used for the thread model - Bits 15 - 8 are used for the version number. - */ - unsigned int option; - - int (*init) (void); - int (*mutex_init) (void **priv); - int (*mutex_destroy) (void *priv); - int (*mutex_lock) (void *priv); - int (*mutex_unlock) (void *priv); - ssize_t (*read) (int fd, void *buf, size_t nbytes); - ssize_t (*write) (int fd, const void *buf, size_t nbytes); -#ifdef _WIN32 - ssize_t (*select) (int nfd, void *rset, void *wset, void *eset, - struct timeval *timeout); - ssize_t (*waitpid) (pid_t pid, int *status, int options); - int (*accept) (int s, void *addr, int *length_ptr); - int (*connect) (int s, void *addr, int length); - int (*sendmsg) (int s, const void *msg, int flags); - int (*recvmsg) (int s, void *msg, int flags); -#else - ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, - struct timeval *timeout); - ssize_t (*waitpid) (pid_t pid, int *status, int options); - int (*accept) (int s, struct sockaddr *addr, socklen_t *length_ptr); - int (*connect) (int s, struct sockaddr *addr, socklen_t length); - int (*sendmsg) (int s, const struct msghdr *msg, int flags); - int (*recvmsg) (int s, struct msghdr *msg, int flags); -#endif -}; - -gpg_err_code_t ath_install (struct ath_ops *ath_ops, int check_only); -int ath_init (void); - - -/* Functions for mutual exclusion. */ -typedef void *ath_mutex_t; -#define ATH_MUTEX_INITIALIZER 0 - -int ath_mutex_init (ath_mutex_t *mutex); -int ath_mutex_destroy (ath_mutex_t *mutex); -int ath_mutex_lock (ath_mutex_t *mutex); -int ath_mutex_unlock (ath_mutex_t *mutex); - -/* Replacement for the POSIX functions, which can be used to allow - other (user-level) threads to run. */ -ssize_t ath_read (int fd, void *buf, size_t nbytes); -ssize_t ath_write (int fd, const void *buf, size_t nbytes); -#ifdef _WIN32 -ssize_t ath_select (int nfd, void *rset, void *wset, void *eset, - struct timeval *timeout); -ssize_t ath_waitpid (pid_t pid, int *status, int options); -int ath_accept (int s, void *addr, int *length_ptr); -int ath_connect (int s, void *addr, int length); -int ath_sendmsg (int s, const void *msg, int flags); -int ath_recvmsg (int s, void *msg, int flags); -#else -ssize_t ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, - struct timeval *timeout); -ssize_t ath_waitpid (pid_t pid, int *status, int options); -int ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr); -int ath_connect (int s, struct sockaddr *addr, socklen_t length); -int ath_sendmsg (int s, const struct msghdr *msg, int flags); -int ath_recvmsg (int s, struct msghdr *msg, int flags); -#endif - -#endif /* ATH_H */ diff --git a/grub-core/lib/libgcrypt/src/cipher-proto.h b/grub-core/lib/libgcrypt/src/cipher-proto.h deleted file mode 100644 index 347681ffe..000000000 --- a/grub-core/lib/libgcrypt/src/cipher-proto.h +++ /dev/null @@ -1,124 +0,0 @@ -/* cipher-proto.h - Internal declarations - * Copyright (C) 2008, 2011 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 . - */ - -/* This file has been factored out from cipher.h so that it can be - used standalone in visibility.c . */ - -#ifndef G10_CIPHER_PROTO_H -#define G10_CIPHER_PROTO_H - -/* Definition of a function used to report selftest failures. - DOMAIN is a string describing the function block: - "cipher", "digest", "pubkey or "random", - ALGO is the algorithm under test, - WHAT is a string describing what has been tested, - DESC is a string describing the error. */ -typedef void (*selftest_report_func_t)(const char *domain, - int algo, - const char *what, - const char *errdesc); - -/* Definition of the selftest functions. */ -typedef gpg_err_code_t (*selftest_func_t) - (int algo, int extended, selftest_report_func_t report); - - -/* An extended type of the generate function. */ -typedef gcry_err_code_t (*pk_ext_generate_t) - (int algo, - unsigned int nbits, - unsigned long evalue, - gcry_sexp_t genparms, - gcry_mpi_t *skey, - gcry_mpi_t **retfactors, - gcry_sexp_t *extrainfo); - -/* The type used to compute the keygrip. */ -typedef gpg_err_code_t (*pk_comp_keygrip_t) - (gcry_md_hd_t md, gcry_sexp_t keyparm); - -/* The type used to query ECC curve parameters. */ -typedef gcry_err_code_t (*pk_get_param_t) - (const char *name, gcry_mpi_t *pkey); - -/* The type used to query an ECC curve name. */ -typedef const char *(*pk_get_curve_t)(gcry_mpi_t *pkey, int iterator, - unsigned int *r_nbits); - -/* The type used to query ECC curve parameters by name. */ -typedef gcry_sexp_t (*pk_get_curve_param_t)(const char *name); - -/* The type used to convey additional information to a cipher. */ -typedef gpg_err_code_t (*cipher_set_extra_info_t) - (void *c, int what, const void *buffer, size_t buflen); - - -/* Extra module specification structures. These are used for internal - modules which provide more functions than available through the - public algorithm register APIs. */ -typedef struct cipher_extra_spec -{ - selftest_func_t selftest; - cipher_set_extra_info_t set_extra_info; -} cipher_extra_spec_t; - -typedef struct md_extra_spec -{ - selftest_func_t selftest; -} md_extra_spec_t; - -typedef struct pk_extra_spec -{ - selftest_func_t selftest; - pk_ext_generate_t ext_generate; - pk_comp_keygrip_t comp_keygrip; - pk_get_param_t get_param; - pk_get_curve_t get_curve; - pk_get_curve_param_t get_curve_param; -} pk_extra_spec_t; - - - -/* The private register functions. */ -gcry_error_t _gcry_cipher_register (gcry_cipher_spec_t *cipher, - cipher_extra_spec_t *extraspec, - int *algorithm_id, - gcry_module_t *module); -gcry_error_t _gcry_md_register (gcry_md_spec_t *cipher, - md_extra_spec_t *extraspec, - unsigned int *algorithm_id, - gcry_module_t *module); -gcry_error_t _gcry_pk_register (gcry_pk_spec_t *cipher, - pk_extra_spec_t *extraspec, - unsigned int *algorithm_id, - gcry_module_t *module); - -/* The selftest functions. */ -gcry_error_t _gcry_cipher_selftest (int algo, int extended, - selftest_report_func_t report); -gcry_error_t _gcry_md_selftest (int algo, int extended, - selftest_report_func_t report); -gcry_error_t _gcry_pk_selftest (int algo, int extended, - selftest_report_func_t report); -gcry_error_t _gcry_hmac_selftest (int algo, int extended, - selftest_report_func_t report); - -gcry_error_t _gcry_random_selftest (selftest_report_func_t report); - -#endif /*G10_CIPHER_PROTO_H*/ diff --git a/grub-core/lib/libgcrypt/src/cipher.h b/grub-core/lib/libgcrypt/src/cipher.h deleted file mode 100644 index 48eeeda5e..000000000 --- a/grub-core/lib/libgcrypt/src/cipher.h +++ /dev/null @@ -1,182 +0,0 @@ -/* cipher.h - * Copyright (C) 1998, 2002, 2003, 2009 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_CIPHER_H -#define G10_CIPHER_H - -#include - -#define DBG_CIPHER _gcry_get_debug_flag( 1 ) - -#include "../random/random.h" - -#define PUBKEY_FLAG_NO_BLINDING (1 << 0) - -enum pk_operation - { - PUBKEY_OP_ENCRYPT, - PUBKEY_OP_DECRYPT, - PUBKEY_OP_SIGN, - PUBKEY_OP_VERIFY - }; - -enum pk_encoding - { - PUBKEY_ENC_RAW, - PUBKEY_ENC_PKCS1, - PUBKEY_ENC_OAEP, - PUBKEY_ENC_PSS, - PUBKEY_ENC_UNKNOWN - }; - -struct pk_encoding_ctx -{ - enum pk_operation op; - unsigned int nbits; - - enum pk_encoding encoding; - int flags; - - int hash_algo; - - /* for OAEP */ - unsigned char *label; - size_t labellen; - - /* for PSS */ - size_t saltlen; - - int (* verify_cmp) (void *opaque, gcry_mpi_t tmp); - void *verify_arg; -}; - -#define CIPHER_INFO_NO_WEAK_KEY 1 - -#include "cipher-proto.h" - - -/*-- rmd160.c --*/ -void _gcry_rmd160_hash_buffer (void *outbuf, - const void *buffer, size_t length); -/*-- sha1.c --*/ -void _gcry_sha1_hash_buffer (void *outbuf, - const void *buffer, size_t length); - -/*-- rijndael.c --*/ -void _gcry_aes_cfb_enc (void *context, unsigned char *iv, - void *outbuf, const void *inbuf, - unsigned int nblocks); -void _gcry_aes_cfb_dec (void *context, unsigned char *iv, - void *outbuf_arg, const void *inbuf_arg, - unsigned int nblocks); -void _gcry_aes_cbc_enc (void *context, unsigned char *iv, - void *outbuf_arg, const void *inbuf_arg, - unsigned int nblocks, int cbc_mac); -void _gcry_aes_cbc_dec (void *context, unsigned char *iv, - void *outbuf_arg, const void *inbuf_arg, - unsigned int nblocks); -void _gcry_aes_ctr_enc (void *context, unsigned char *ctr, - void *outbuf_arg, const void *inbuf_arg, - unsigned int nblocks); - - -/*-- dsa.c --*/ -void _gcry_register_pk_dsa_progress (gcry_handler_progress_t cbc, void *cb_data); - -/*-- elgamal.c --*/ -void _gcry_register_pk_elg_progress (gcry_handler_progress_t cb, - void *cb_data); - - -/*-- ecc.c --*/ -void _gcry_register_pk_ecc_progress (gcry_handler_progress_t cbc, - void *cb_data); - - -/*-- primegen.c --*/ -void _gcry_register_primegen_progress (gcry_handler_progress_t cb, - void *cb_data); - -/*-- pubkey.c --*/ -const char * _gcry_pk_aliased_algo_name (int algorithm); - -/* Declarations for the cipher specifications. */ -extern gcry_cipher_spec_t _gcry_cipher_spec_blowfish; -extern gcry_cipher_spec_t _gcry_cipher_spec_des; -extern gcry_cipher_spec_t _gcry_cipher_spec_tripledes; -extern gcry_cipher_spec_t _gcry_cipher_spec_arcfour; -extern gcry_cipher_spec_t _gcry_cipher_spec_cast5; -extern gcry_cipher_spec_t _gcry_cipher_spec_aes; -extern gcry_cipher_spec_t _gcry_cipher_spec_aes192; -extern gcry_cipher_spec_t _gcry_cipher_spec_aes256; -extern gcry_cipher_spec_t _gcry_cipher_spec_twofish; -extern gcry_cipher_spec_t _gcry_cipher_spec_twofish128; -extern gcry_cipher_spec_t _gcry_cipher_spec_serpent128; -extern gcry_cipher_spec_t _gcry_cipher_spec_serpent192; -extern gcry_cipher_spec_t _gcry_cipher_spec_serpent256; -extern gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40; -extern gcry_cipher_spec_t _gcry_cipher_spec_seed; -extern gcry_cipher_spec_t _gcry_cipher_spec_camellia128; -extern gcry_cipher_spec_t _gcry_cipher_spec_camellia192; -extern gcry_cipher_spec_t _gcry_cipher_spec_camellia256; -extern gcry_cipher_spec_t _gcry_cipher_spec_idea; - -extern cipher_extra_spec_t _gcry_cipher_extraspec_tripledes; -extern cipher_extra_spec_t _gcry_cipher_extraspec_aes; -extern cipher_extra_spec_t _gcry_cipher_extraspec_aes192; -extern cipher_extra_spec_t _gcry_cipher_extraspec_aes256; - - -/* Declarations for the digest specifications. */ -extern gcry_md_spec_t _gcry_digest_spec_crc32; -extern gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510; -extern gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440; -extern gcry_md_spec_t _gcry_digest_spec_md4; -extern gcry_md_spec_t _gcry_digest_spec_md5; -extern gcry_md_spec_t _gcry_digest_spec_rmd160; -extern gcry_md_spec_t _gcry_digest_spec_sha1; -extern gcry_md_spec_t _gcry_digest_spec_sha224; -extern gcry_md_spec_t _gcry_digest_spec_sha256; -extern gcry_md_spec_t _gcry_digest_spec_sha512; -extern gcry_md_spec_t _gcry_digest_spec_sha384; -extern gcry_md_spec_t _gcry_digest_spec_tiger; -extern gcry_md_spec_t _gcry_digest_spec_tiger1; -extern gcry_md_spec_t _gcry_digest_spec_tiger2; -extern gcry_md_spec_t _gcry_digest_spec_whirlpool; - -extern md_extra_spec_t _gcry_digest_extraspec_sha1; -extern md_extra_spec_t _gcry_digest_extraspec_sha224; -extern md_extra_spec_t _gcry_digest_extraspec_sha256; -extern md_extra_spec_t _gcry_digest_extraspec_sha384; -extern md_extra_spec_t _gcry_digest_extraspec_sha512; - -/* Declarations for the pubkey cipher specifications. */ -extern gcry_pk_spec_t _gcry_pubkey_spec_rsa; -extern gcry_pk_spec_t _gcry_pubkey_spec_elg; -extern gcry_pk_spec_t _gcry_pubkey_spec_dsa; -extern gcry_pk_spec_t _gcry_pubkey_spec_ecdsa; -extern gcry_pk_spec_t _gcry_pubkey_spec_ecdh; - -extern pk_extra_spec_t _gcry_pubkey_extraspec_rsa; -extern pk_extra_spec_t _gcry_pubkey_extraspec_dsa; -extern pk_extra_spec_t _gcry_pubkey_extraspec_elg; -extern pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa; - - -#endif /*G10_CIPHER_H*/ diff --git a/grub-core/lib/libgcrypt/src/dumpsexp.c b/grub-core/lib/libgcrypt/src/dumpsexp.c deleted file mode 100644 index f6384d7d5..000000000 --- a/grub-core/lib/libgcrypt/src/dumpsexp.c +++ /dev/null @@ -1,766 +0,0 @@ -/* dumpsexp.c - Dump S-expressions. - * Copyright (C) 2007, 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -/* For a native WindowsCE binary we need to include gpg-error.h to - provide a replacement for strerror. */ -#ifdef __MINGW32CE__ -# include -#endif - -#define PGM "dumpsexp" -#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION -#define BUGREPORT_LINE "\nReport bugs to .\n" - - -static int verbose; /* Verbose mode. */ -static int decimal; /* Print addresses in decimal. */ -static int assume_hex; /* Assume input is hexencoded. */ -static int advanced; /* Advanced format output. */ - -static void -print_version (int with_help) -{ - fputs (MYVERSION_LINE "\n" - "Copyright (C) 2010 Free Software Foundation, Inc.\n" - "License GPLv3+: GNU GPL version 3 or later " - "\n" - "This is free software: you are free to change and redistribute it.\n" - "There is NO WARRANTY, to the extent permitted by law.\n", - stdout); - - if (with_help) - fputs ("\n" - "Usage: " PGM " [OPTIONS] [file]\n" - "Debug tool for S-expressions\n" - "\n" - " --decimal Print offsets using decimal notation\n" - " --assume-hex Assume input is a hex dump\n" - " --advanced Print file in advanced format\n" - " --verbose Show what we are doing\n" - " --version Print version of the program and exit\n" - " --help Display this help and exit\n" - BUGREPORT_LINE, stdout ); - - exit (0); -} - -static int -print_usage (void) -{ - fputs ("usage: " PGM " [OPTIONS] NBYTES\n", stderr); - fputs (" (use --help to display options)\n", stderr); - exit (1); -} - - -#define space_p(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t') -#define digit_p(a) ((a) >= '0' && (a) <= '9') -#define octdigit_p(a) ((a) >= '0' && (a) <= '7') -#define alpha_p(a) ( ((a) >= 'A' && (a) <= 'Z') \ - || ((a) >= 'a' && (a) <= 'z')) -#define hexdigit_p(a) (digit_p (a) \ - || ((a) >= 'A' && (a) <= 'F') \ - || ((a) >= 'a' && (a) <= 'f')) -#define xtoi_1(a) ((a) <= '9'? ((a)- '0'): \ - (a) <= 'F'? ((a)-'A'+10):((a)-'a'+10)) - - -/* Return true if P points to a byte containing a whitespace according - to the S-expressions definition. */ -static inline int -whitespace_p (int c) -{ - switch (c) - { - case ' ': case '\t': case '\v': case '\f': case '\r': case '\n': return 1; - default: return 0; - } -} - -static void -logit (const char *format, ...) -{ - va_list arg_ptr; - - va_start (arg_ptr, format) ; - fputs (PGM ": ", stderr); - vfprintf (stderr, format, arg_ptr); - putc ('\n', stderr); - va_end (arg_ptr); -} - -/* The raw data buffer and its current length */ -static unsigned char databuffer[16]; -static int databufferlen; -/* The number of bytes in databuffer which should be skipped at a flush. */ -static int skipdatabufferlen; -/* The number of raw bytes printed on the last line. */ -static int nbytesprinted; -/* The file offset of the current data buffer . */ -static unsigned long databufferoffset; - - - -static int -my_getc (FILE *fp) -{ - int c1, c2; - - if (!assume_hex) - return getc (fp); - - while ( (c1=getc (fp)) != EOF && space_p (c1) ) - ; - if (c1 == EOF) - return EOF; - - if (!hexdigit_p (c1)) - { - logit ("non hex-digit encountered\n"); - return EOF; - } - - while ( (c2=getc (fp)) != EOF && space_p (c2) ) - ; - if (c2 == EOF) - { - logit ("error reading second hex nibble\n"); - return EOF; - } - if (!hexdigit_p (c2)) - { - logit ("second hex nibble is not a hex-digit\n"); - return EOF; - } - return xtoi_1 (c1) * 16 + xtoi_1 (c2); -} - - - - - -/* Flush the raw data buffer. */ -static void -flushdatabuffer (void) -{ - int i; - - if (!databufferlen) - return; - nbytesprinted = 0; - if (decimal) - printf ("%08lu ", databufferoffset); - else - printf ("%08lx ", databufferoffset); - for (i=0; i < databufferlen; i++) - { - if (i == 8) - putchar (' '); - if (i < skipdatabufferlen) - fputs (" ", stdout); - else - { - printf (" %02x", databuffer[i]); - databufferoffset++; - } - nbytesprinted++; - } - for (; i < sizeof (databuffer); i++) - { - if (i == 8) - putchar (' '); - fputs (" ", stdout); - } - fputs (" |", stdout); - for (i=0; i < databufferlen; i++) - { - if (i < skipdatabufferlen) - putchar (' '); - else if (databuffer[i] >= ' ' && databuffer[i] <= '~' - && databuffer[i] != '|') - putchar (databuffer[i]); - else - putchar ('.'); - } - putchar ('|'); - putchar ('\n'); - databufferlen = 0; - skipdatabufferlen = 0; -} - - -/* Add C to the raw data buffer and flush as needed. */ -static void -addrawdata (int c) -{ - if ( databufferlen >= sizeof databuffer ) - flushdatabuffer (); - databuffer[databufferlen++] = c; -} - - -static void -printcursor (int both) -{ - int i; - - flushdatabuffer (); - printf ("%8s ", ""); - for (i=0; i < sizeof (databuffer); i++) - { - if (i == 8) - putchar (' '); - if (i+1 == nbytesprinted) - { - fputs (" ^ ", stdout); - if (!both) - break; - } - else - fputs (" ", stdout); - } - if (both) - { - fputs (" ", stdout); - for (i=0; i < nbytesprinted-1; i++) - putchar (' '); - putchar ('^'); - } - databufferlen = skipdatabufferlen = nbytesprinted; -} - -static void -printerr (const char *text) -{ - printcursor (1); - printf ("\n Error: %s\n", text); -} - -static void -printctl (const char *text) -{ - if (verbose && !advanced) - { - printcursor (0); - printf ("%s\n", text); - } -} - -static void -printchr (int c) -{ - putchar (c); -} - -/* static void */ -/* printhex (int c) */ -/* { */ -/* printf ("\\x%02x", c); */ -/* } */ - - -#if 0 -/**************** - * Print SEXP to buffer using the MODE. Returns the length of the - * SEXP in buffer or 0 if the buffer is too short (We have at least an - * empty list consisting of 2 bytes). If a buffer of NULL is provided, - * the required length is returned. - */ -size_t -gcry_sexp_sprint (const gcry_sexp_t list, - void *buffer, size_t maxlength ) -{ - static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP }; - const unsigned char *s; - char *d; - DATALEN n; - char numbuf[20]; - int i, indent = 0; - - s = list? list->d : empty; - d = buffer; - while ( *s != ST_STOP ) - { - switch ( *s ) - { - case ST_OPEN: - s++; - if (indent) - putchar ('\n'); - for (i=0; i < indent; i++) - putchar (' '); - putchar ('('); - indent++; - break; - case ST_CLOSE: - s++; - putchar (')'); - indent--; - if (*s != ST_OPEN && *s != ST_STOP) - { - putchar ('\n'); - for (i=0; i < indent; i++) - putchar (' '); - } - break; - case ST_DATA: - s++; - memcpy (&n, s, sizeof n); - s += sizeof n; - { - int type; - size_t nn; - - switch ( (type=suitable_encoding (s, n))) - { - case 1: nn = convert_to_string (s, n, NULL); break; - case 2: nn = convert_to_token (s, n, NULL); break; - default: nn = convert_to_hex (s, n, NULL); break; - } - switch (type) - { - case 1: convert_to_string (s, n, d); break; - case 2: convert_to_token (s, n, d); break; - default: convert_to_hex (s, n, d); break; - } - d += nn; - if (s[n] != ST_CLOSE) - putchar (' '); - } - else - { - snprintf (numbuf, sizeof numbuf, "%u:", (unsigned int)n ); - d = stpcpy (d, numbuf); - memcpy (d, s, n); - d += n; - } - s += n; - break; - default: - BUG (); - } - } - putchar ('\n'); - return len; -} -#endif - - -/* Prepare for saving a chunk of data. */ -static void -init_data (void) -{ - -} - -/* Push C on the current data chunk. */ -static void -push_data (int c) -{ - (void)c; -} - -/* Flush and thus print the current data chunk. */ -static void -flush_data (void) -{ - -} - - -/* Returns 0 on success. */ -static int -parse_and_print (FILE *fp) -{ - static const char tokenchars[] = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789-./_:*+="; - int c; - int level = 0; - int tokenc = 0; - int hexcount = 0; - int disphint = 0; - unsigned long datalen = 0; - char quote_buf[10]; - int quote_idx = 0; - enum - { - INIT_STATE = 0, IN_NUMBER, PRE_DATA, IN_DATA, IN_STRING, - IN_ESCAPE, IN_OCT_ESC, IN_HEX_ESC, - CR_ESC, LF_ESC, IN_HEXFMT, IN_BASE64 - } - state = INIT_STATE; - - - while ((c = my_getc (fp)) != EOF ) - { - addrawdata (c); - switch (state) - { - case INIT_STATE: - if (tokenc) - { - if (strchr (tokenchars, c)) - { - printchr (c); - continue; - } - tokenc = 0; - } - parse_init_state: - if (c == '(') - { - if (disphint) - { - printerr ("unmatched display hint"); - disphint = 0; - } - printctl ("open"); - level++; - } - else if (c == ')') - { - if (disphint) - { - printerr ("unmatched display hint"); - disphint = 0; - } - printctl ("close"); - level--; - } - else if (c == '\"') - { - state = IN_STRING; - printctl ("beginstring"); - init_data (); - } - else if (c == '#') - { - state = IN_HEXFMT; - hexcount = 0; - printctl ("beginhex"); - init_data (); - } - else if (c == '|') - { - state = IN_BASE64; - printctl ("beginbase64"); - init_data (); - } - else if (c == '[') - { - if (disphint) - printerr ("nested display hint"); - disphint = c; - } - else if (c == ']') - { - if (!disphint) - printerr ("no open display hint"); - disphint = 0; - } - else if (c >= '0' && c <= '9') - { - if (c == '0') - printerr ("zero prefixed length"); - state = IN_NUMBER; - datalen = (c - '0'); - } - else if (strchr (tokenchars, c)) - { - printchr (c); - tokenc = c; - } - else if (whitespace_p (c)) - ; - else if (c == '{') - { - printerr ("rescanning is not supported"); - } - else if (c == '&' || c == '\\') - { - printerr ("reserved punctuation detected"); - } - else - { - printerr ("bad character detected"); - } - break; - - case IN_NUMBER: - if (digit_p (c)) - { - unsigned long tmp = datalen * 10 + (c - '0'); - if (tmp < datalen) - { - printerr ("overflow in data length"); - state = INIT_STATE; - datalen = 0; - } - else - datalen = tmp; - } - else if (c == ':') - { - if (!datalen) - { - printerr ("no data length"); - state = INIT_STATE; - } - else - state = PRE_DATA; - } - else if (c == '\"' || c == '#' || c == '|' ) - { - /* We ignore the optional length and divert to the init - state parser code. */ - goto parse_init_state; - } - else - printerr ("invalid length specification"); - break; - - case PRE_DATA: - state = IN_DATA; - printctl ("begindata"); - init_data (); - case IN_DATA: - if (datalen) - { - push_data (c); - datalen--; - } - if (!datalen) - { - state = INIT_STATE; - printctl ("enddata"); - flush_data (); - } - break; - - case IN_STRING: - if (c == '\"') - { - printctl ("endstring"); - flush_data (); - state = INIT_STATE; - } - else if (c == '\\') - state = IN_ESCAPE; - else - push_data (c); - break; - - case IN_ESCAPE: - switch (c) - { - case 'b': push_data ('\b'); state = IN_STRING; break; - case 't': push_data ('\t'); state = IN_STRING; break; - case 'v': push_data ('\v'); state = IN_STRING; break; - case 'n': push_data ('\n'); state = IN_STRING; break; - case 'f': push_data ('\f'); state = IN_STRING; break; - case 'r': push_data ('\r'); state = IN_STRING; break; - case '"': push_data ('"'); state = IN_STRING; break; - case '\'': push_data ('\''); state = IN_STRING; break; - case '\\': push_data ('\\'); state = IN_STRING; break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - state = IN_OCT_ESC; - quote_idx = 0; - quote_buf[quote_idx++] = c; - break; - - case 'x': - state = IN_HEX_ESC; - quote_idx = 0; - break; - - case '\r': - state = CR_ESC; - break; - - case '\n': - state = LF_ESC; - break; - - default: - printerr ("invalid escape sequence"); - state = IN_STRING; - break; - } - break; - - case IN_OCT_ESC: - if (quote_idx < 3 && strchr ("01234567", c)) - { - quote_buf[quote_idx++] = c; - if (quote_idx == 3) - { - push_data ((unsigned int)quote_buf[0] * 8 * 8 - + (unsigned int)quote_buf[1] * 8 - + (unsigned int)quote_buf[2]); - state = IN_STRING; - } - } - else - state = IN_STRING; - break; - case IN_HEX_ESC: - if (quote_idx < 2 && strchr ("0123456789abcdefABCDEF", c)) - { - quote_buf[quote_idx++] = c; - if (quote_idx == 2) - { - push_data (xtoi_1 (quote_buf[0]) * 16 - + xtoi_1 (quote_buf[1])); - state = IN_STRING; - } - } - else - state = IN_STRING; - break; - case CR_ESC: - state = IN_STRING; - break; - case LF_ESC: - state = IN_STRING; - break; - - case IN_HEXFMT: - if (hexdigit_p (c)) - { - push_data (c); - hexcount++; - } - else if (c == '#') - { - if ((hexcount & 1)) - printerr ("odd number of hex digits"); - printctl ("endhex"); - flush_data (); - state = INIT_STATE; - } - else if (!whitespace_p (c)) - printerr ("bad hex character"); - break; - - case IN_BASE64: - if (c == '|') - { - printctl ("endbase64"); - flush_data (); - state = INIT_STATE; - } - else - push_data (c); - break; - - default: - logit ("invalid state %d detected", state); - exit (1); - } - } - flushdatabuffer (); - if (ferror (fp)) - { - logit ("error reading input: %s\n", strerror (errno)); - return -1; - } - return 0; -} - - - -int -main (int argc, char **argv) -{ - int rc; - - if (argc) - { - argc--; argv++; - } - while (argc && **argv == '-' && (*argv)[1] == '-') - { - if (!(*argv)[2]) - { - argc--; argv++; - break; - } - else if (!strcmp (*argv, "--version")) - print_version (0); - else if (!strcmp (*argv, "--help")) - print_version (1); - else if (!strcmp (*argv, "--verbose")) - { - argc--; argv++; - verbose = 1; - } - else if (!strcmp (*argv, "--decimal")) - { - argc--; argv++; - decimal = 1; - } - else if (!strcmp (*argv, "--assume-hex")) - { - argc--; argv++; - assume_hex = 1; - } - else if (!strcmp (*argv, "--advanced")) - { - argc--; argv++; - advanced = 1; - } - else - print_usage (); - } - - if (!argc) - { - rc = parse_and_print (stdin); - } - else - { - rc = 0; - for (; argc; argv++, argc--) - { - FILE *fp = fopen (*argv, "rb"); - if (!fp) - { - logit ("can't open `%s': %s\n", *argv, strerror (errno)); - rc = 1; - } - else - { - if (parse_and_print (fp)) - rc = 1; - fclose (fp); - } - } - } - - return !!rc; -} diff --git a/grub-core/lib/libgcrypt/src/fips.c b/grub-core/lib/libgcrypt/src/fips.c deleted file mode 100644 index c5737a78d..000000000 --- a/grub-core/lib/libgcrypt/src/fips.c +++ /dev/null @@ -1,860 +0,0 @@ -/* fips.c - FIPS mode management - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#ifdef ENABLE_HMAC_BINARY_CHECK -# include -#endif -#ifdef HAVE_SYSLOG -# include -#endif /*HAVE_SYSLOG*/ - -#include "g10lib.h" -#include "ath.h" -#include "cipher-proto.h" -#include "hmac256.h" - - -/* The name of the file used to foce libgcrypt into fips mode. */ -#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled" - - -/* The states of the finite state machine used in fips mode. */ -enum module_states - { - /* POWEROFF cannot be represented. */ - STATE_POWERON = 0, - STATE_INIT, - STATE_SELFTEST, - STATE_OPERATIONAL, - STATE_ERROR, - STATE_FATALERROR, - STATE_SHUTDOWN - }; - - -/* Flag telling whether we are in fips mode. It uses inverse logic so - that fips mode is the default unless changed by the initialization - code. To check whether fips mode is enabled, use the function - fips_mode()! */ -static int no_fips_mode_required; - -/* Flag to indicate that we are in the enforced FIPS mode. */ -static int enforced_fips_mode; - -/* If this flag is set, the application may no longer assume that the - process is running in FIPS mode. This flag is protected by the - FSM_LOCK. */ -static int inactive_fips_mode; - -/* This is the lock we use to protect the FSM. */ -static ath_mutex_t fsm_lock = ATH_MUTEX_INITIALIZER; - -/* The current state of the FSM. The whole state machinery is only - used while in fips mode. Change this only while holding fsm_lock. */ -static enum module_states current_state; - - - - - -static void fips_new_state (enum module_states new_state); - - - -/* Convert lowercase hex digits; assumes valid hex digits. */ -#define loxtoi_1(p) (*(p) <= '9'? (*(p)- '0'): (*(p)-'a'+10)) -#define loxtoi_2(p) ((loxtoi_1(p) * 16) + loxtoi_1((p)+1)) - -/* Returns true if P points to a lowercase hex digit. */ -#define loxdigit_p(p) !!strchr ("01234567890abcdef", *(p)) - - - -/* Check whether the OS is in FIPS mode and record that in a module - local variable. If FORCE is passed as true, fips mode will be - enabled anyway. Note: This function is not thread-safe and should - be called before any threads are created. This function may only - be called once. */ -void -_gcry_initialize_fips_mode (int force) -{ - static int done; - gpg_error_t err; - - /* Make sure we are not accidently called twice. */ - if (done) - { - if ( fips_mode () ) - { - fips_new_state (STATE_FATALERROR); - fips_noreturn (); - } - /* If not in fips mode an assert is sufficient. */ - gcry_assert (!done); - } - done = 1; - - /* If the calling application explicitly requested fipsmode, do so. */ - if (force) - { - gcry_assert (!no_fips_mode_required); - goto leave; - } - - /* For testing the system it is useful to override the system - provided detection of the FIPS mode and force FIPS mode using a - file. The filename is hardwired so that there won't be any - confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is - actually used. The file itself may be empty. */ - if ( !access (FIPS_FORCE_FILE, F_OK) ) - { - gcry_assert (!no_fips_mode_required); - goto leave; - } - - /* Checking based on /proc file properties. */ - { - static const char procfname[] = "/proc/sys/crypto/fips_enabled"; - FILE *fp; - int saved_errno; - - fp = fopen (procfname, "r"); - if (fp) - { - char line[256]; - - if (fgets (line, sizeof line, fp) && atoi (line)) - { - /* System is in fips mode. */ - fclose (fp); - gcry_assert (!no_fips_mode_required); - goto leave; - } - fclose (fp); - } - else if ((saved_errno = errno) != ENOENT - && saved_errno != EACCES - && !access ("/proc/version", F_OK) ) - { - /* Problem reading the fips file despite that we have the proc - file system. We better stop right away. */ - log_info ("FATAL: error reading `%s' in libgcrypt: %s\n", - procfname, strerror (saved_errno)); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " - "reading `%s' failed: %s - abort", - procfname, strerror (saved_errno)); -#endif /*HAVE_SYSLOG*/ - abort (); - } - } - - /* Fips not not requested, set flag. */ - no_fips_mode_required = 1; - - leave: - if (!no_fips_mode_required) - { - /* Yes, we are in FIPS mode. */ - FILE *fp; - - /* Intitialize the lock to protect the FSM. */ - err = ath_mutex_init (&fsm_lock); - if (err) - { - /* If that fails we can't do anything but abort the - process. We need to use log_info so that the FSM won't - get involved. */ - log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n", - strerror (err)); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " - "creating FSM lock failed: %s - abort", - strerror (err)); -#endif /*HAVE_SYSLOG*/ - abort (); - } - - - /* If the FIPS force files exists, is readable and has a number - != 0 on its first line, we enable the enforced fips mode. */ - fp = fopen (FIPS_FORCE_FILE, "r"); - if (fp) - { - char line[256]; - - if (fgets (line, sizeof line, fp) && atoi (line)) - enforced_fips_mode = 1; - fclose (fp); - } - - /* Now get us into the INIT state. */ - fips_new_state (STATE_INIT); - - } - return; -} - -static void -lock_fsm (void) -{ - gpg_error_t err; - - err = ath_mutex_lock (&fsm_lock); - if (err) - { - log_info ("FATAL: failed to acquire the FSM lock in libgrypt: %s\n", - strerror (err)); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " - "acquiring FSM lock failed: %s - abort", - strerror (err)); -#endif /*HAVE_SYSLOG*/ - abort (); - } -} - -static void -unlock_fsm (void) -{ - gpg_error_t err; - - err = ath_mutex_unlock (&fsm_lock); - if (err) - { - log_info ("FATAL: failed to release the FSM lock in libgrypt: %s\n", - strerror (err)); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " - "releasing FSM lock failed: %s - abort", - strerror (err)); -#endif /*HAVE_SYSLOG*/ - abort (); - } -} - - -/* This function returns true if fips mode is enabled. This is - independent of the fips required finite state machine and only used - to enable fips specific code. Please use the fips_mode macro - instead of calling this function directly. */ -int -_gcry_fips_mode (void) -{ - /* No locking is required because we have the requirement that this - variable is only initialized once with no other threads - existing. */ - return !no_fips_mode_required; -} - - -/* Return a flag telling whether we are in the enforced fips mode. */ -int -_gcry_enforced_fips_mode (void) -{ - if (!_gcry_fips_mode ()) - return 0; - return enforced_fips_mode; -} - -/* Set a flag telling whether we are in the enforced fips mode. */ -void -_gcry_set_enforced_fips_mode (void) -{ - enforced_fips_mode = 1; -} - -/* If we do not want to enforce the fips mode, we can set a flag so - that the application may check whether it is still in fips mode. - TEXT will be printed as part of a syslog message. This function - may only be be called if in fips mode. */ -void -_gcry_inactivate_fips_mode (const char *text) -{ - gcry_assert (_gcry_fips_mode ()); - - if (_gcry_enforced_fips_mode () ) - { - /* Get us into the error state. */ - fips_signal_error (text); - return; - } - - lock_fsm (); - if (!inactive_fips_mode) - { - inactive_fips_mode = 1; - unlock_fsm (); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s - FIPS mode inactivated", text); -#endif /*HAVE_SYSLOG*/ - } - else - unlock_fsm (); -} - - -/* Return the FIPS mode inactive flag. If it is true the FIPS mode is - not anymore active. */ -int -_gcry_is_fips_mode_inactive (void) -{ - int flag; - - if (!_gcry_fips_mode ()) - return 0; - lock_fsm (); - flag = inactive_fips_mode; - unlock_fsm (); - return flag; -} - - - -static const char * -state2str (enum module_states state) -{ - const char *s; - - switch (state) - { - case STATE_POWERON: s = "Power-On"; break; - case STATE_INIT: s = "Init"; break; - case STATE_SELFTEST: s = "Self-Test"; break; - case STATE_OPERATIONAL: s = "Operational"; break; - case STATE_ERROR: s = "Error"; break; - case STATE_FATALERROR: s = "Fatal-Error"; break; - case STATE_SHUTDOWN: s = "Shutdown"; break; - default: s = "?"; break; - } - return s; -} - - -/* Return true if the library is in the operational state. */ -int -_gcry_fips_is_operational (void) -{ - int result; - - if (!fips_mode ()) - result = 1; - else - { - lock_fsm (); - if (current_state == STATE_INIT) - { - /* If we are still in the INIT state, we need to run the - selftests so that the FSM can eventually get into - operational state. Given that we would need a 2-phase - initialization of libgcrypt, but that has traditionally - not been enforced, we use this on demand self-test - checking. Note that Proper applications would do the - application specific libgcrypt initialization between a - gcry_check_version() and gcry_control - (GCRYCTL_INITIALIZATION_FINISHED) where the latter will - run the selftests. The drawback of these on-demand - self-tests are a small chance that self-tests are - performed by severeal threads; that is no problem because - our FSM make sure that we won't oversee any error. */ - unlock_fsm (); - _gcry_fips_run_selftests (0); - lock_fsm (); - } - - result = (current_state == STATE_OPERATIONAL); - unlock_fsm (); - } - return result; -} - - -/* This is test on whether the library is in the operational state. In - contrast to _gcry_fips_is_operational this function won't do a - state transition on the fly. */ -int -_gcry_fips_test_operational (void) -{ - int result; - - if (!fips_mode ()) - result = 1; - else - { - lock_fsm (); - result = (current_state == STATE_OPERATIONAL); - unlock_fsm (); - } - return result; -} - - -/* This is a test on whether the library is in the error or - operational state. */ -int -_gcry_fips_test_error_or_operational (void) -{ - int result; - - if (!fips_mode ()) - result = 1; - else - { - lock_fsm (); - result = (current_state == STATE_OPERATIONAL - || current_state == STATE_ERROR); - unlock_fsm (); - } - return result; -} - - -static void -reporter (const char *domain, int algo, const char *what, const char *errtxt) -{ - if (!errtxt && !_gcry_log_verbosity (2)) - return; - - log_info ("libgcrypt selftest: %s %s%s (%d): %s%s%s%s\n", - !strcmp (domain, "hmac")? "digest":domain, - !strcmp (domain, "hmac")? "HMAC-":"", - !strcmp (domain, "cipher")? _gcry_cipher_algo_name (algo) : - !strcmp (domain, "digest")? _gcry_md_algo_name (algo) : - !strcmp (domain, "hmac")? _gcry_md_algo_name (algo) : - !strcmp (domain, "pubkey")? _gcry_pk_algo_name (algo) : "", - algo, errtxt? errtxt:"Okay", - what?" (":"", what? what:"", what?")":""); -} - -/* Run self-tests for all required cipher algorithms. Return 0 on - success. */ -static int -run_cipher_selftests (int extended) -{ - static int algos[] = - { - GCRY_CIPHER_3DES, - GCRY_CIPHER_AES128, - GCRY_CIPHER_AES192, - GCRY_CIPHER_AES256, - 0 - }; - int idx; - gpg_error_t err; - int anyerr = 0; - - for (idx=0; algos[idx]; idx++) - { - err = _gcry_cipher_selftest (algos[idx], extended, reporter); - reporter ("cipher", algos[idx], NULL, - err? gpg_strerror (err):NULL); - if (err) - anyerr = 1; - } - return anyerr; -} - - -/* Run self-tests for all required hash algorithms. Return 0 on - success. */ -static int -run_digest_selftests (int extended) -{ - static int algos[] = - { - GCRY_MD_SHA1, - GCRY_MD_SHA224, - GCRY_MD_SHA256, - GCRY_MD_SHA384, - GCRY_MD_SHA512, - 0 - }; - int idx; - gpg_error_t err; - int anyerr = 0; - - for (idx=0; algos[idx]; idx++) - { - err = _gcry_md_selftest (algos[idx], extended, reporter); - reporter ("digest", algos[idx], NULL, - err? gpg_strerror (err):NULL); - if (err) - anyerr = 1; - } - return anyerr; -} - - -/* Run self-tests for all HMAC algorithms. Return 0 on success. */ -static int -run_hmac_selftests (int extended) -{ - static int algos[] = - { - GCRY_MD_SHA1, - GCRY_MD_SHA224, - GCRY_MD_SHA256, - GCRY_MD_SHA384, - GCRY_MD_SHA512, - 0 - }; - int idx; - gpg_error_t err; - int anyerr = 0; - - for (idx=0; algos[idx]; idx++) - { - err = _gcry_hmac_selftest (algos[idx], extended, reporter); - reporter ("hmac", algos[idx], NULL, - err? gpg_strerror (err):NULL); - if (err) - anyerr = 1; - } - return anyerr; -} - - -/* Run self-tests for all required public key algorithms. Return 0 on - success. */ -static int -run_pubkey_selftests (int extended) -{ - static int algos[] = - { - GCRY_PK_RSA, - GCRY_PK_DSA, - /* GCRY_PK_ECDSA is not enabled in fips mode. */ - 0 - }; - int idx; - gpg_error_t err; - int anyerr = 0; - - for (idx=0; algos[idx]; idx++) - { - err = _gcry_pk_selftest (algos[idx], extended, reporter); - reporter ("pubkey", algos[idx], NULL, - err? gpg_strerror (err):NULL); - if (err) - anyerr = 1; - } - return anyerr; -} - - -/* Run self-tests for the random number generator. Returns 0 on - success. */ -static int -run_random_selftests (void) -{ - gpg_error_t err; - - err = _gcry_random_selftest (reporter); - reporter ("random", 0, NULL, err? gpg_strerror (err):NULL); - - return !!err; -} - -/* Run an integrity check on the binary. Returns 0 on success. */ -static int -check_binary_integrity (void) -{ -#ifdef ENABLE_HMAC_BINARY_CHECK - gpg_error_t err; - Dl_info info; - unsigned char digest[32]; - int dlen; - char *fname = NULL; - const char key[] = "What am I, a doctor or a moonshuttle conductor?"; - - if (!dladdr ("gcry_check_version", &info)) - err = gpg_error_from_syserror (); - else - { - dlen = _gcry_hmac256_file (digest, sizeof digest, info.dli_fname, - key, strlen (key)); - if (dlen < 0) - err = gpg_error_from_syserror (); - else if (dlen != 32) - err = gpg_error (GPG_ERR_INTERNAL); - else - { - fname = gcry_malloc (strlen (info.dli_fname) + 1 + 5 + 1 ); - if (!fname) - err = gpg_error_from_syserror (); - else - { - FILE *fp; - char *p; - - /* Prefix the basename with a dot. */ - strcpy (fname, info.dli_fname); - p = strrchr (fname, '/'); - if (p) - p++; - else - p = fname; - memmove (p+1, p, strlen (p)+1); - *p = '.'; - strcat (fname, ".hmac"); - - /* Open the file. */ - fp = fopen (fname, "r"); - if (!fp) - err = gpg_error_from_syserror (); - else - { - /* A buffer of 64 bytes plus one for a LF and one to - detect garbage. */ - unsigned char buffer[64+1+1]; - const unsigned char *s; - int n; - - /* The HMAC files consists of lowercase hex digits - only with an optional trailing linefeed. Fail if - there is any garbage. */ - err = gpg_error (GPG_ERR_SELFTEST_FAILED); - n = fread (buffer, 1, sizeof buffer, fp); - if (n == 64 || (n == 65 && buffer[64] == '\n')) - { - buffer[64] = 0; - for (n=0, s= buffer; - n < 32 && loxdigit_p (s) && loxdigit_p (s+1); - n++, s += 2) - buffer[n] = loxtoi_2 (s); - if ( n == 32 && !memcmp (digest, buffer, 32) ) - err = 0; - } - fclose (fp); - } - } - } - } - reporter ("binary", 0, fname, err? gpg_strerror (err):NULL); -#ifdef HAVE_SYSLOG - if (err) - syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " - "integrity check using `%s' failed: %s", - fname? fname:"[?]", gpg_strerror (err)); -#endif /*HAVE_SYSLOG*/ - gcry_free (fname); - return !!err; -#else - return 0; -#endif -} - - -/* Run the self-tests. If EXTENDED is true, extended versions of the - selftest are run, that is more tests than required by FIPS. */ -gpg_err_code_t -_gcry_fips_run_selftests (int extended) -{ - enum module_states result = STATE_ERROR; - gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED; - - if (fips_mode ()) - fips_new_state (STATE_SELFTEST); - - if (run_cipher_selftests (extended)) - goto leave; - - if (run_digest_selftests (extended)) - goto leave; - - if (run_hmac_selftests (extended)) - goto leave; - - /* Run random tests before the pubkey tests because the latter - require random. */ - if (run_random_selftests ()) - goto leave; - - if (run_pubkey_selftests (extended)) - goto leave; - - /* Now check the integrity of the binary. We do this this after - having checked the HMAC code. */ - if (check_binary_integrity ()) - goto leave; - - /* All selftests passed. */ - result = STATE_OPERATIONAL; - ec = 0; - - leave: - if (fips_mode ()) - fips_new_state (result); - - return ec; -} - - -/* This function is used to tell the FSM about errors in the library. - The FSM will be put into an error state. This function should not - be called directly but by one of the macros - - fips_signal_error (description) - fips_signal_fatal_error (description) - - where DESCRIPTION is a string describing the error. */ -void -_gcry_fips_signal_error (const char *srcfile, int srcline, const char *srcfunc, - int is_fatal, const char *description) -{ - if (!fips_mode ()) - return; /* Not required. */ - - /* Set new state before printing an error. */ - fips_new_state (is_fatal? STATE_FATALERROR : STATE_ERROR); - - /* Print error. */ - log_info ("%serror in libgcrypt, file %s, line %d%s%s: %s\n", - is_fatal? "fatal ":"", - srcfile, srcline, - srcfunc? ", function ":"", srcfunc? srcfunc:"", - description? description : "no description available"); -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " - "%serror in file %s, line %d%s%s: %s", - is_fatal? "fatal ":"", - srcfile, srcline, - srcfunc? ", function ":"", srcfunc? srcfunc:"", - description? description : "no description available"); -#endif /*HAVE_SYSLOG*/ -} - - -/* Perform a state transition to NEW_STATE. If this is an invalid - transition, the module will go into a fatal error state. */ -static void -fips_new_state (enum module_states new_state) -{ - int ok = 0; - enum module_states last_state; - - lock_fsm (); - - last_state = current_state; - switch (current_state) - { - case STATE_POWERON: - if (new_state == STATE_INIT - || new_state == STATE_ERROR - || new_state == STATE_FATALERROR) - ok = 1; - break; - - case STATE_INIT: - if (new_state == STATE_SELFTEST - || new_state == STATE_ERROR - || new_state == STATE_FATALERROR) - ok = 1; - break; - - case STATE_SELFTEST: - if (new_state == STATE_OPERATIONAL - || new_state == STATE_ERROR - || new_state == STATE_FATALERROR) - ok = 1; - break; - - case STATE_OPERATIONAL: - if (new_state == STATE_SHUTDOWN - || new_state == STATE_SELFTEST - || new_state == STATE_ERROR - || new_state == STATE_FATALERROR) - ok = 1; - break; - - case STATE_ERROR: - if (new_state == STATE_SHUTDOWN - || new_state == STATE_ERROR - || new_state == STATE_FATALERROR - || new_state == STATE_SELFTEST) - ok = 1; - break; - - case STATE_FATALERROR: - if (new_state == STATE_SHUTDOWN ) - ok = 1; - break; - - case STATE_SHUTDOWN: - /* We won't see any transition *from* Shutdown because the only - allowed new state is Power-Off and that one can't be - represented. */ - break; - - } - - if (ok) - { - current_state = new_state; - } - - unlock_fsm (); - - if (!ok || _gcry_log_verbosity (2)) - log_info ("libgcrypt state transition %s => %s %s\n", - state2str (last_state), state2str (new_state), - ok? "granted":"denied"); - - if (!ok) - { - /* Invalid state transition. Halting library. */ -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_ERR, - "Libgcrypt error: invalid state transition %s => %s", - state2str (last_state), state2str (new_state)); -#endif /*HAVE_SYSLOG*/ - fips_noreturn (); - } - else if (new_state == STATE_ERROR || new_state == STATE_FATALERROR) - { -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, - "Libgcrypt notice: state transition %s => %s", - state2str (last_state), state2str (new_state)); -#endif /*HAVE_SYSLOG*/ - } -} - - - - -/* This function should be called to ensure that the execution shall - not continue. */ -void -_gcry_fips_noreturn (void) -{ -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_ERR, "Libgcrypt terminated the application"); -#endif /*HAVE_SYSLOG*/ - fflush (NULL); - abort (); - /*NOTREACHED*/ -} diff --git a/grub-core/lib/libgcrypt/src/g10lib.h b/grub-core/lib/libgcrypt/src/g10lib.h deleted file mode 100644 index 6bde20f1e..000000000 --- a/grub-core/lib/libgcrypt/src/g10lib.h +++ /dev/null @@ -1,302 +0,0 @@ -/* g10lib.h - Internal definitions for libgcrypt - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 - * 2007, 2011 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 . - */ - -/* This header is to be used inside of libgcrypt in place of gcrypt.h. - This way we can better distinguish between internal and external - usage of gcrypt.h. */ - -#ifndef G10LIB_H -#define G10LIB_H 1 - -#ifdef _GCRYPT_H -#error gcrypt.h already included -#endif - -#ifndef _GCRYPT_IN_LIBGCRYPT -#error something is wrong with config.h -#endif - -#include -#include - -#include "visibility.h" -#include "types.h" - - - - -/* Attribute handling macros. */ - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) -#define JNLIB_GCC_M_FUNCTION 1 -#define JNLIB_GCC_A_NR __attribute__ ((noreturn)) -#define JNLIB_GCC_A_PRINTF( f, a ) __attribute__ ((format (printf,f,a))) -#define JNLIB_GCC_A_NR_PRINTF( f, a ) \ - __attribute__ ((noreturn, format (printf,f,a))) -#define GCC_ATTR_NORETURN __attribute__ ((__noreturn__)) -#else -#define JNLIB_GCC_A_NR -#define JNLIB_GCC_A_PRINTF( f, a ) -#define JNLIB_GCC_A_NR_PRINTF( f, a ) -#define GCC_ATTR_NORETURN -#endif - -#if __GNUC__ >= 3 -/* According to glibc this attribute is available since 2.8 however we - better play safe and use it only with gcc 3 or newer. */ -#define GCC_ATTR_FORMAT_ARG(a) __attribute__ ((format_arg (a))) -#else -#define GCC_ATTR_FORMAT_ARG(a) -#endif - - -/* Gettext macros. */ - -/* Some handy macros */ -#ifndef STR -#define STR(v) #v -#endif -#define STR2(v) STR(v) -#define DIM(v) (sizeof(v)/sizeof((v)[0])) -#define DIMof(type,member) DIM(((type *)0)->member) - - - -/*-- src/global.c -*/ -int _gcry_global_is_operational (void); -gcry_error_t _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr); -void _gcry_check_heap (const void *a); -int _gcry_get_debug_flag (unsigned int mask); - - -/*-- src/misc.c --*/ - -#if defined(JNLIB_GCC_M_FUNCTION) || __STDC_VERSION__ >= 199901L -void _gcry_bug (const char *file, int line, - const char *func) GCC_ATTR_NORETURN; -void _gcry_assert_failed (const char *expr, const char *file, int line, - const char *func) GCC_ATTR_NORETURN; -#else -void _gcry_bug (const char *file, int line); -void _gcry_assert_failed (const char *expr, const char *file, int line); -#endif - -const char *_gcry_gettext (const char *key) GCC_ATTR_FORMAT_ARG(1); -void _gcry_fatal_error(int rc, const char *text ) JNLIB_GCC_A_NR; -void _gcry_log( int level, const char *fmt, ... ) JNLIB_GCC_A_PRINTF(2,3); -void _gcry_log_bug( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2); -void _gcry_log_fatal( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2); -void _gcry_log_error( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); -void _gcry_log_info( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); -int _gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... ) - JNLIB_GCC_A_PRINTF(2,3); -void _gcry_log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); -void _gcry_log_printf ( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); -void _gcry_log_printhex (const char *text, const void *buffer, size_t length); - -void _gcry_set_log_verbosity( int level ); -int _gcry_log_verbosity( int level ); - -#ifdef JNLIB_GCC_M_FUNCTION -#define BUG() _gcry_bug( __FILE__ , __LINE__, __FUNCTION__ ) -#define gcry_assert(expr) ((expr)? (void)0 \ - : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __FUNCTION__)) -#elif __STDC_VERSION__ >= 199901L -#define BUG() _gcry_bug( __FILE__ , __LINE__, __func__ ) -#define gcry_assert(expr) ((expr)? (void)0 \ - : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __func__)) -#else -#define BUG() _gcry_bug( __FILE__ , __LINE__ ) -#define gcry_assert(expr) ((expr)? (void)0 \ - : _gcry_assert_failed (STR(expr), __FILE__, __LINE__)) -#endif - - -#define log_bug _gcry_log_bug -#define log_fatal _gcry_log_fatal -#define log_error _gcry_log_error -#define log_info _gcry_log_info -#define log_debug _gcry_log_debug -#define log_printf _gcry_log_printf -#define log_printhex _gcry_log_printhex - - -/*-- src/hwfeatures.c --*/ -/* (Do not change these values unless synced with the asm code.) */ -#define HWF_PADLOCK_RNG 1 -#define HWF_PADLOCK_AES 2 -#define HWF_PADLOCK_SHA 4 -#define HWF_PADLOCK_MMUL 8 - -#define HWF_INTEL_AESNI 256 - - -unsigned int _gcry_get_hw_features (void); -void _gcry_detect_hw_features (unsigned int); - - -/*-- mpi/mpiutil.c --*/ -const char *_gcry_mpi_get_hw_config (void); - - -/*-- cipher/pubkey.c --*/ - -/* FIXME: shouldn't this go into mpi.h? */ -#ifndef mpi_powm -#define mpi_powm(w,b,e,m) gcry_mpi_powm( (w), (b), (e), (m) ) -#endif - -/*-- primegen.c --*/ -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 _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 _gcry_generate_elg_prime (int mode, - unsigned int pbits, unsigned int qbits, - gcry_mpi_t g, gcry_mpi_t **factors); -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); -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 _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); - - -/* Replacements of missing functions (missing-string.c). */ -#ifndef HAVE_STPCPY -char *stpcpy (char *a, const char *b); -#endif -#ifndef HAVE_STRCASECMP -int strcasecmp (const char *a, const char *b) _GCRY_GCC_ATTR_PURE; -#endif - - -/* Macros used to rename missing functions. */ -#ifndef HAVE_STRTOUL -#define strtoul(a,b,c) ((unsigned long)strtol((a),(b),(c))) -#endif -#ifndef HAVE_MEMMOVE -#define memmove(d, s, n) bcopy((s), (d), (n)) -#endif -#ifndef HAVE_STRICMP -#define stricmp(a,b) strcasecmp( (a), (b) ) -#endif -#ifndef HAVE_ATEXIT -#define atexit(a) (on_exit((a),0)) -#endif -#ifndef HAVE_RAISE -#define raise(a) kill(getpid(), (a)) -#endif - - -/* Stack burning. */ - -void _gcry_burn_stack (int bytes); - - -/* To avoid that a compiler optimizes certain memset calls away, these - macros may be used instead. */ -#define wipememory2(_ptr,_set,_len) do { \ - volatile char *_vptr=(volatile char *)(_ptr); \ - size_t _vlen=(_len); \ - while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \ - } while(0) -#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) - - - -/* Digit predicates. */ - -#define digitp(p) (*(p) >= '0' && *(p) <= '9') -#define octdigitp(p) (*(p) >= '0' && *(p) <= '7') -#define alphap(a) ( (*(a) >= 'A' && *(a) <= 'Z') \ - || (*(a) >= 'a' && *(a) <= 'z')) -#define hexdigitp(a) (digitp (a) \ - || (*(a) >= 'A' && *(a) <= 'F') \ - || (*(a) >= 'a' && *(a) <= 'f')) - - -/*-- sexp.c --*/ -gcry_error_t _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff, - const char *format, va_list arg_ptr); -char *_gcry_sexp_nth_string (const gcry_sexp_t list, int number); - - -/*-- fips.c --*/ - -void _gcry_initialize_fips_mode (int force); - -int _gcry_fips_mode (void); -#define fips_mode() _gcry_fips_mode () - -int _gcry_enforced_fips_mode (void); - -void _gcry_set_enforced_fips_mode (void); - -void _gcry_inactivate_fips_mode (const char *text); -int _gcry_is_fips_mode_inactive (void); - - -void _gcry_fips_signal_error (const char *srcfile, - int srcline, - const char *srcfunc, - int is_fatal, - const char *description); -#ifdef JNLIB_GCC_M_FUNCTION -# define fips_signal_error(a) \ - _gcry_fips_signal_error (__FILE__, __LINE__, __FUNCTION__, 0, (a)) -# define fips_signal_fatal_error(a) \ - _gcry_fips_signal_error (__FILE__, __LINE__, __FUNCTION__, 1, (a)) -#else -# define fips_signal_error(a) \ - _gcry_fips_signal_error (__FILE__, __LINE__, NULL, 0, (a)) -# define fips_signal_fatal_error(a) \ - _gcry_fips_signal_error (__FILE__, __LINE__, NULL, 1, (a)) -#endif - -int _gcry_fips_is_operational (void); -#define fips_is_operational() (_gcry_global_is_operational ()) -#define fips_not_operational() (GCRY_GPG_ERR_NOT_OPERATIONAL) - -int _gcry_fips_test_operational (void); -int _gcry_fips_test_error_or_operational (void); - -gpg_err_code_t _gcry_fips_run_selftests (int extended); - -void _gcry_fips_noreturn (void); -#define fips_noreturn() (_gcry_fips_noreturn ()) - - - -#endif /* G10LIB_H */ diff --git a/grub-core/lib/libgcrypt/src/gcrypt-module.h b/grub-core/lib/libgcrypt/src/gcrypt-module.h deleted file mode 100644 index f39e2b5c7..000000000 --- a/grub-core/lib/libgcrypt/src/gcrypt-module.h +++ /dev/null @@ -1,240 +0,0 @@ -/* gcrypt-module.h - GNU Cryptographic Library Interface - Copyright (C) 2003, 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 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 . - */ - -/* - This file contains the necessary declarations/definitions for - working with Libgcrypt modules. - */ - -#ifndef _GCRYPT_MODULE_H -#define _GCRYPT_MODULE_H - -#ifdef __cplusplus -extern "C" { -#if 0 /* keep Emacsens's auto-indent happy */ -} -#endif -#endif - -/* The interfaces using the module system reserve a certain range of - IDs for application use. These IDs are not valid within Libgcrypt - but Libgcrypt makes sure never to allocate such a module ID. */ -#define GCRY_MODULE_ID_USER 1024 -#define GCRY_MODULE_ID_USER_LAST 4095 - - -/* This type represents a `module'. */ -typedef struct gcry_module *gcry_module_t; - -/* Check that the library fulfills the version requirement. */ - -/* 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; - size_t blocksize; - size_t keylen; - 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; -} gcry_cipher_spec_t; - -/* 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 representing this module is stored in MODULE. */ -gcry_error_t gcry_cipher_register (gcry_cipher_spec_t *cipher, - int *algorithm_id, - gcry_module_t *module) - /* */ _GCRY_ATTR_INTERNAL; - - -/* Unregister the cipher identified by MODULE, which must have been - registered with gcry_cipher_register. */ -void gcry_cipher_unregister (gcry_module_t module) - /* */ _GCRY_ATTR_INTERNAL; - -/* ********************** */ - -/* Type for the pk_generate function. */ -typedef gcry_err_code_t (*gcry_pk_generate_t) (int algo, - unsigned int nbits, - unsigned long use_e, - gcry_mpi_t *skey, - gcry_mpi_t **retfactors); - -/* Type for the pk_check_secret_key function. */ -typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo, - gcry_mpi_t *skey); - -/* Type for the pk_encrypt function. */ -typedef gcry_err_code_t (*gcry_pk_encrypt_t) (int algo, - gcry_mpi_t *resarr, - gcry_mpi_t data, - gcry_mpi_t *pkey, - int flags); - -/* Type for the pk_decrypt function. */ -typedef gcry_err_code_t (*gcry_pk_decrypt_t) (int algo, - gcry_mpi_t *result, - gcry_mpi_t *data, - gcry_mpi_t *skey, - int flags); - -/* Type for the pk_sign function. */ -typedef gcry_err_code_t (*gcry_pk_sign_t) (int algo, - gcry_mpi_t *resarr, - gcry_mpi_t data, - gcry_mpi_t *skey); - -/* Type for the pk_verify function. */ -typedef gcry_err_code_t (*gcry_pk_verify_t) (int algo, - gcry_mpi_t hash, - gcry_mpi_t *data, - gcry_mpi_t *pkey, - int (*cmp) (void *, gcry_mpi_t), - void *opaquev); - -/* Type for the pk_get_nbits function. */ -typedef unsigned (*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey); - -/* Module specification structure for message digests. */ -typedef struct gcry_pk_spec -{ - const char *name; - const char **aliases; - const char *elements_pkey; - const char *elements_skey; - const char *elements_enc; - const char *elements_sig; - const char *elements_grip; - int use; - gcry_pk_generate_t generate; - gcry_pk_check_secret_key_t check_secret_key; - gcry_pk_encrypt_t encrypt; - gcry_pk_decrypt_t decrypt; - gcry_pk_sign_t sign; - gcry_pk_verify_t verify; - gcry_pk_get_nbits_t get_nbits; -} gcry_pk_spec_t; - -/* 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, - unsigned int *algorithm_id, - gcry_module_t *module) - /* */ _GCRY_ATTR_INTERNAL; - -/* Unregister the pubkey identified by ID, which must have been - registered with gcry_pk_register. */ -void gcry_pk_unregister (gcry_module_t module) - /* */ _GCRY_ATTR_INTERNAL; - -/* ********************** */ - -/* 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, 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; - int mdlen; - gcry_md_init_t init; - gcry_md_write_t write; - gcry_md_final_t final; - gcry_md_read_t read; - size_t contextsize; /* allocate this amount of context */ -} gcry_md_spec_t; - -/* 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, - unsigned int *algorithm_id, - gcry_module_t *module) - /* */ _GCRY_ATTR_INTERNAL; - -/* Unregister the digest identified by ID, which must have been - registered with gcry_digest_register. */ -void gcry_md_unregister (gcry_module_t module) - /* */ _GCRY_ATTR_INTERNAL; - -#if 0 /* keep Emacsens's auto-indent happy */ -{ -#endif -#ifdef __cplusplus -} -#endif -#endif diff --git a/grub-core/lib/libgcrypt/src/gcrypt.h.in b/grub-core/lib/libgcrypt/src/gcrypt.h.in deleted file mode 100644 index b65184e6b..000000000 --- a/grub-core/lib/libgcrypt/src/gcrypt.h.in +++ /dev/null @@ -1,1760 +0,0 @@ -/* gcrypt.h - GNU Cryptographic Library Interface -*- c -*- - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 - 2007, 2008, 2009, 2010, 2011, - 2012 Free Software Foundation, Inc. - Copyright (C) 2012, 2013 g10 Code GmbH - - 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 . - - File: @configure_input@ */ - -#ifndef _GCRYPT_H -#define _GCRYPT_H - -#include -#include -#include - -#include - -#include - -#if defined _WIN32 || defined __WIN32__ -# include -# include -# include -# ifndef __GNUC__ - typedef long ssize_t; - typedef int pid_t; -# endif /*!__GNUC__*/ -#else -# include -# include -#@INSERT_SYS_SELECT_H@ -#endif /*!_WIN32*/ - -@FALLBACK_SOCKLEN_T@ - -/* This is required for error code compatibility. */ -#define _GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GCRYPT - -#ifdef __cplusplus -extern "C" { -#if 0 /* (Keep Emacsens' auto-indent happy.) */ -} -#endif -#endif - -/* The version of this header should match the one of the library. It - should not be used by a program because gcry_check_version() should - return the same version. The purpose of this macro is to let - autoconf (using the AM_PATH_GCRYPT macro) check that this header - matches the installed library. */ -#define GCRYPT_VERSION "@VERSION@" - -/* The version number of this header. It may be used to handle minor - API incompatibilities. */ -#define GCRYPT_VERSION_NUMBER @VERSION_NUMBER@ - - -/* Internal: We can't use the convenience macros for the multi - precision integer functions when building this library. */ -#ifdef _GCRYPT_IN_LIBGCRYPT -#ifndef GCRYPT_NO_MPI_MACROS -#define GCRYPT_NO_MPI_MACROS 1 -#endif -#endif - -/* We want to use gcc attributes when possible. Warning: Don't use - these macros in your programs: As indicated by the leading - underscore they are subject to change without notice. */ -#ifdef __GNUC__ - -#define _GCRY_GCC_VERSION (__GNUC__ * 10000 \ - + __GNUC_MINOR__ * 100 \ - + __GNUC_PATCHLEVEL__) - -#if _GCRY_GCC_VERSION >= 30100 -#define _GCRY_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__)) -#endif - -#if _GCRY_GCC_VERSION >= 29600 -#define _GCRY_GCC_ATTR_PURE __attribute__ ((__pure__)) -#endif - -#if _GCRY_GCC_VERSION >= 30200 -#define _GCRY_GCC_ATTR_MALLOC __attribute__ ((__malloc__)) -#endif - -#endif /*__GNUC__*/ - -#ifndef _GCRY_GCC_ATTR_DEPRECATED -#define _GCRY_GCC_ATTR_DEPRECATED -#endif -#ifndef _GCRY_GCC_ATTR_PURE -#define _GCRY_GCC_ATTR_PURE -#endif -#ifndef _GCRY_GCC_ATTR_MALLOC -#define _GCRY_GCC_ATTR_MALLOC -#endif - -/* Make up an attribute to mark functions and types as deprecated but - allow internal use by Libgcrypt. */ -#ifdef _GCRYPT_IN_LIBGCRYPT -#define _GCRY_ATTR_INTERNAL -#else -#define _GCRY_ATTR_INTERNAL _GCRY_GCC_ATTR_DEPRECATED -#endif - -/* Wrappers for the libgpg-error library. */ - -typedef gpg_error_t gcry_error_t; -typedef gpg_err_code_t gcry_err_code_t; -typedef gpg_err_source_t gcry_err_source_t; - -static GPG_ERR_INLINE gcry_error_t -gcry_err_make (gcry_err_source_t source, gcry_err_code_t code) -{ - return gpg_err_make (source, code); -} - -/* The user can define GPG_ERR_SOURCE_DEFAULT before including this - file to specify a default source for gpg_error. */ -#ifndef GCRY_ERR_SOURCE_DEFAULT -#define GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_USER_1 -#endif - -static GPG_ERR_INLINE gcry_error_t -gcry_error (gcry_err_code_t code) -{ - return gcry_err_make (GCRY_ERR_SOURCE_DEFAULT, code); -} - -static GPG_ERR_INLINE gcry_err_code_t -gcry_err_code (gcry_error_t err) -{ - return gpg_err_code (err); -} - - -static GPG_ERR_INLINE gcry_err_source_t -gcry_err_source (gcry_error_t err) -{ - return gpg_err_source (err); -} - -/* Return a pointer to a string containing a description of the error - code in the error value ERR. */ -const char *gcry_strerror (gcry_error_t err); - -/* Return a pointer to a string containing a description of the error - source in the error value ERR. */ -const char *gcry_strsource (gcry_error_t err); - -/* Retrieve the error code for the system error ERR. This returns - GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report - this). */ -gcry_err_code_t gcry_err_code_from_errno (int err); - -/* Retrieve the system error for the error code CODE. This returns 0 - if CODE is not a system error code. */ -int gcry_err_code_to_errno (gcry_err_code_t code); - -/* Return an error value with the error source SOURCE and the system - error ERR. */ -gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err); - -/* Return an error value with the system error ERR. */ -gcry_err_code_t gcry_error_from_errno (int err); - - -/* The data object used to hold a multi precision integer. */ -struct gcry_mpi; -typedef struct gcry_mpi *gcry_mpi_t; - -#ifndef GCRYPT_NO_DEPRECATED -typedef struct gcry_mpi *GCRY_MPI _GCRY_GCC_ATTR_DEPRECATED; -typedef struct gcry_mpi *GcryMPI _GCRY_GCC_ATTR_DEPRECATED; -#endif - - - -/* Check that the library fulfills the version requirement. */ -const char *gcry_check_version (const char *req_version); - -/* Codes for function dispatchers. */ - -/* Codes used with the gcry_control function. */ -enum gcry_ctl_cmds - { - GCRYCTL_SET_KEY = 1, - GCRYCTL_SET_IV = 2, - GCRYCTL_CFB_SYNC = 3, - GCRYCTL_RESET = 4, /* e.g. for MDs */ - GCRYCTL_FINALIZE = 5, - GCRYCTL_GET_KEYLEN = 6, - GCRYCTL_GET_BLKLEN = 7, - GCRYCTL_TEST_ALGO = 8, - GCRYCTL_IS_SECURE = 9, - GCRYCTL_GET_ASNOID = 10, - GCRYCTL_ENABLE_ALGO = 11, - GCRYCTL_DISABLE_ALGO = 12, - GCRYCTL_DUMP_RANDOM_STATS = 13, - GCRYCTL_DUMP_SECMEM_STATS = 14, - GCRYCTL_GET_ALGO_NPKEY = 15, - GCRYCTL_GET_ALGO_NSKEY = 16, - GCRYCTL_GET_ALGO_NSIGN = 17, - GCRYCTL_GET_ALGO_NENCR = 18, - GCRYCTL_SET_VERBOSITY = 19, - GCRYCTL_SET_DEBUG_FLAGS = 20, - GCRYCTL_CLEAR_DEBUG_FLAGS = 21, - GCRYCTL_USE_SECURE_RNDPOOL= 22, - GCRYCTL_DUMP_MEMORY_STATS = 23, - GCRYCTL_INIT_SECMEM = 24, - GCRYCTL_TERM_SECMEM = 25, - GCRYCTL_DISABLE_SECMEM_WARN = 27, - GCRYCTL_SUSPEND_SECMEM_WARN = 28, - GCRYCTL_RESUME_SECMEM_WARN = 29, - GCRYCTL_DROP_PRIVS = 30, - GCRYCTL_ENABLE_M_GUARD = 31, - GCRYCTL_START_DUMP = 32, - GCRYCTL_STOP_DUMP = 33, - GCRYCTL_GET_ALGO_USAGE = 34, - GCRYCTL_IS_ALGO_ENABLED = 35, - GCRYCTL_DISABLE_INTERNAL_LOCKING = 36, - GCRYCTL_DISABLE_SECMEM = 37, - GCRYCTL_INITIALIZATION_FINISHED = 38, - GCRYCTL_INITIALIZATION_FINISHED_P = 39, - GCRYCTL_ANY_INITIALIZATION_P = 40, - GCRYCTL_SET_CBC_CTS = 41, - GCRYCTL_SET_CBC_MAC = 42, - GCRYCTL_SET_CTR = 43, - GCRYCTL_ENABLE_QUICK_RANDOM = 44, - GCRYCTL_SET_RANDOM_SEED_FILE = 45, - GCRYCTL_UPDATE_RANDOM_SEED_FILE = 46, - GCRYCTL_SET_THREAD_CBS = 47, - GCRYCTL_FAST_POLL = 48, - GCRYCTL_SET_RANDOM_DAEMON_SOCKET = 49, - GCRYCTL_USE_RANDOM_DAEMON = 50, - GCRYCTL_FAKED_RANDOM_P = 51, - GCRYCTL_SET_RNDEGD_SOCKET = 52, - GCRYCTL_PRINT_CONFIG = 53, - GCRYCTL_OPERATIONAL_P = 54, - GCRYCTL_FIPS_MODE_P = 55, - GCRYCTL_FORCE_FIPS_MODE = 56, - GCRYCTL_SELFTEST = 57, - /* Note: 58 .. 62 are used internally. */ - GCRYCTL_DISABLE_HWF = 63, - GCRYCTL_SET_ENFORCED_FIPS_FLAG = 64 - }; - -/* Perform various operations defined by CMD. */ -gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...); - - -/* S-expression management. */ - -/* The object to represent an S-expression as used with the public key - functions. */ -struct gcry_sexp; -typedef struct gcry_sexp *gcry_sexp_t; - -#ifndef GCRYPT_NO_DEPRECATED -typedef struct gcry_sexp *GCRY_SEXP _GCRY_GCC_ATTR_DEPRECATED; -typedef struct gcry_sexp *GcrySexp _GCRY_GCC_ATTR_DEPRECATED; -#endif - -/* The possible values for the S-expression format. */ -enum gcry_sexp_format - { - GCRYSEXP_FMT_DEFAULT = 0, - GCRYSEXP_FMT_CANON = 1, - GCRYSEXP_FMT_BASE64 = 2, - GCRYSEXP_FMT_ADVANCED = 3 - }; - -/* Create an new S-expression object from BUFFER of size LENGTH and - return it in RETSEXP. With AUTODETECT set to 0 the data in BUFFER - is expected to be in canonized format. */ -gcry_error_t gcry_sexp_new (gcry_sexp_t *retsexp, - const void *buffer, size_t length, - int autodetect); - - /* Same as gcry_sexp_new but allows to pass a FREEFNC which has the - effect to transfer ownership of BUFFER to the created object. */ -gcry_error_t gcry_sexp_create (gcry_sexp_t *retsexp, - void *buffer, size_t length, - int autodetect, void (*freefnc) (void *)); - -/* Scan BUFFER and return a new S-expression object in RETSEXP. This - function expects a printf like string in BUFFER. */ -gcry_error_t gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, - const char *buffer, size_t length); - -/* Same as gcry_sexp_sscan but expects a string in FORMAT and can thus - only be used for certain encodings. */ -gcry_error_t gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, - const char *format, ...); - -/* Like gcry_sexp_build, but uses an array instead of variable - function arguments. */ -gcry_error_t gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff, - const char *format, void **arg_list); - -/* Release the S-expression object SEXP */ -void gcry_sexp_release (gcry_sexp_t sexp); - -/* Calculate the length of an canonized S-expresion in BUFFER and - check for a valid encoding. */ -size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length, - size_t *erroff, gcry_error_t *errcode); - -/* Copies the S-expression object SEXP into BUFFER using the format - specified in MODE. */ -size_t gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer, - size_t maxlength); - -/* Dumps the S-expression object A in a format suitable for debugging - to Libgcrypt's logging stream. */ -void gcry_sexp_dump (const gcry_sexp_t a); - -gcry_sexp_t gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b); -gcry_sexp_t gcry_sexp_alist (const gcry_sexp_t *array); -gcry_sexp_t gcry_sexp_vlist (const gcry_sexp_t a, ...); -gcry_sexp_t gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n); -gcry_sexp_t gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n); - -/* Scan the S-expression for a sublist with a type (the car of the - list) matching the string TOKEN. If TOKLEN is not 0, the token is - assumed to be raw memory of this length. The function returns a - newly allocated S-expression consisting of the found sublist or - `NULL' when not found. */ -gcry_sexp_t gcry_sexp_find_token (gcry_sexp_t list, - const char *tok, size_t toklen); -/* Return the length of the LIST. For a valid S-expression this - should be at least 1. */ -int gcry_sexp_length (const gcry_sexp_t list); - -/* Create and return a new S-expression from the element with index - NUMBER in LIST. Note that the first element has the index 0. If - there is no such element, `NULL' is returned. */ -gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t list, int number); - -/* Create and return a new S-expression from the first element in - LIST; this called the "type" and should always exist and be a - string. `NULL' is returned in case of a problem. */ -gcry_sexp_t gcry_sexp_car (const gcry_sexp_t list); - -/* Create and return a new list form all elements except for the first - one. Note, that this function may return an invalid S-expression - because it is not guaranteed, that the type exists and is a string. - However, for parsing a complex S-expression it might be useful for - intermediate lists. Returns `NULL' on error. */ -gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t list); - -gcry_sexp_t gcry_sexp_cadr (const gcry_sexp_t list); - - -/* This function is used to get data from a LIST. A pointer to the - actual data with index NUMBER is returned and the length of this - data will be stored to DATALEN. If there is no data at the given - index or the index represents another list, `NULL' is returned. - *Note:* The returned pointer is valid as long as LIST is not - modified or released. */ -const char *gcry_sexp_nth_data (const gcry_sexp_t list, int number, - size_t *datalen); - -/* This function is used to get and convert data from a LIST. The - data is assumed to be a Nul terminated string. The caller must - release the returned value using `gcry_free'. If there is no data - at the given index, the index represents a list or the value can't - be converted to a string, `NULL' is returned. */ -char *gcry_sexp_nth_string (gcry_sexp_t list, int number); - -/* This function is used to get and convert data from a LIST. This - data is assumed to be an MPI stored in the format described by - MPIFMT and returned as a standard Libgcrypt MPI. The caller must - release this returned value using `gcry_mpi_release'. If there is - no data at the given index, the index represents a list or the - value can't be converted to an MPI, `NULL' is returned. */ -gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt); - - - -/******************************************* - * * - * Multi Precision Integer Functions * - * * - *******************************************/ - -/* Different formats of external big integer representation. */ -enum gcry_mpi_format - { - GCRYMPI_FMT_NONE= 0, - GCRYMPI_FMT_STD = 1, /* Twos complement stored without length. */ - GCRYMPI_FMT_PGP = 2, /* As used by OpenPGP (unsigned only). */ - GCRYMPI_FMT_SSH = 3, /* As used by SSH (like STD but with length). */ - GCRYMPI_FMT_HEX = 4, /* Hex format. */ - GCRYMPI_FMT_USG = 5 /* Like STD but unsigned. */ - }; - -/* Flags used for creating big integers. */ -enum gcry_mpi_flag - { - GCRYMPI_FLAG_SECURE = 1, /* Allocate the number in "secure" memory. */ - GCRYMPI_FLAG_OPAQUE = 2 /* The number is not a real one but just - a way to store some bytes. This is - useful for encrypted big integers. */ - }; - - -/* Allocate a new big integer object, initialize it with 0 and - initially allocate memory for a number of at least NBITS. */ -gcry_mpi_t gcry_mpi_new (unsigned int nbits); - -/* Same as gcry_mpi_new() but allocate in "secure" memory. */ -gcry_mpi_t gcry_mpi_snew (unsigned int nbits); - -/* Release the number A and free all associated resources. */ -void gcry_mpi_release (gcry_mpi_t a); - -/* Create a new number with the same value as A. */ -gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t a); - -/* Store the big integer value U in W. */ -gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u); - -/* Store the unsigned integer value U in W. */ -gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u); - -/* Swap the values of A and B. */ -void gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b); - -/* Compare the big integer number U and V returning 0 for equality, a - positive value for U > V and a negative for U < V. */ -int gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v); - -/* Compare the big integer number U with the unsigned integer V - returning 0 for equality, a positive value for U > V and a negative - for U < V. */ -int gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v); - -/* Convert the external representation of an integer stored in BUFFER - with a length of BUFLEN into a newly create MPI returned in - RET_MPI. If NSCANNED is not NULL, it will receive the number of - bytes actually scanned after a successful operation. */ -gcry_error_t gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format, - const void *buffer, size_t buflen, - size_t *nscanned); - -/* Convert the big integer A into the external representation - described by FORMAT and store it in the provided BUFFER which has - been allocated by the user with a size of BUFLEN bytes. NWRITTEN - receives the actual length of the external representation unless it - has been passed as NULL. */ -gcry_error_t gcry_mpi_print (enum gcry_mpi_format format, - unsigned char *buffer, size_t buflen, - size_t *nwritten, - const gcry_mpi_t a); - -/* Convert the big integer A int the external representation described - by FORMAT and store it in a newly allocated buffer which address - will be put into BUFFER. NWRITTEN receives the actual lengths of the - external representation. */ -gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format format, - unsigned char **buffer, size_t *nwritten, - const gcry_mpi_t a); - -/* Dump the value of A in a format suitable for debugging to - Libgcrypt's logging stream. Note that one leading space but no - trailing space or linefeed will be printed. It is okay to pass - NULL for A. */ -void gcry_mpi_dump (const gcry_mpi_t a); - - -/* W = U + V. */ -void gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); - -/* W = U + V. V is an unsigned integer. */ -void gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v); - -/* W = U + V mod M. */ -void gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); - -/* W = U - V. */ -void gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); - -/* W = U - V. V is an unsigned integer. */ -void gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ); - -/* W = U - V mod M */ -void gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); - -/* W = U * V. */ -void gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); - -/* W = U * V. V is an unsigned integer. */ -void gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ); - -/* W = U * V mod M. */ -void gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); - -/* W = U * (2 ^ CNT). */ -void gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt); - -/* Q = DIVIDEND / DIVISOR, R = DIVIDEND % DIVISOR, - Q or R may be passed as NULL. ROUND should be negative or 0. */ -void gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r, - gcry_mpi_t dividend, gcry_mpi_t divisor, int round); - -/* R = DIVIDEND % DIVISOR */ -void gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor); - -/* W = B ^ E mod M. */ -void gcry_mpi_powm (gcry_mpi_t w, - const gcry_mpi_t b, const gcry_mpi_t e, - const gcry_mpi_t m); - -/* Set G to the greatest common divisor of A and B. - Return true if the G is 1. */ -int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b); - -/* Set X to the multiplicative inverse of A mod M. - Return true if the value exists. */ -int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m); - - -/* Return the number of bits required to represent A. */ -unsigned int gcry_mpi_get_nbits (gcry_mpi_t a); - -/* Return true when bit number N (counting from 0) is set in A. */ -int gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n); - -/* Set bit number N in A. */ -void gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n); - -/* Clear bit number N in A. */ -void gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n); - -/* Set bit number N in A and clear all bits greater than N. */ -void gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n); - -/* Clear bit number N in A and all bits greater than N. */ -void gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n); - -/* Shift the value of A by N bits to the right and store the result in X. */ -void gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n); - -/* Shift the value of A by N bits to the left and store the result in X. */ -void gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n); - -/* Store NBITS of the value P points to in A and mark A as an opaque - value. WARNING: Never use an opaque MPI for anything thing else then - gcry_mpi_release, gcry_mpi_get_opaque. */ -gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits); - -/* Return a pointer to an opaque value stored in A and return its size - in NBITS. Note that the returned pointer is still owned by A and - that the function should never be used for an non-opaque MPI. */ -void *gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits); - -/* Set the FLAG for the big integer A. Currently only the flag - GCRYMPI_FLAG_SECURE is allowed to convert A into an big intger - stored in "secure" memory. */ -void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); - -/* Clear FLAG for the big integer A. Note that this function is - currently useless as no flags are allowed. */ -void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); - -/* Return true when the FLAG is set for A. */ -int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); - -/* Unless the GCRYPT_NO_MPI_MACROS is used, provide a couple of - convenience macros for the big integer functions. */ -#ifndef GCRYPT_NO_MPI_MACROS -#define mpi_new(n) gcry_mpi_new( (n) ) -#define mpi_secure_new( n ) gcry_mpi_snew( (n) ) -#define mpi_release(a) \ - do \ - { \ - gcry_mpi_release ((a)); \ - (a) = NULL; \ - } \ - while (0) - -#define mpi_copy( a ) gcry_mpi_copy( (a) ) -#define mpi_set( w, u) gcry_mpi_set( (w), (u) ) -#define mpi_set_ui( w, u) gcry_mpi_set_ui( (w), (u) ) -#define mpi_cmp( u, v ) gcry_mpi_cmp( (u), (v) ) -#define mpi_cmp_ui( u, v ) gcry_mpi_cmp_ui( (u), (v) ) - -#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v)) -#define mpi_add(w,u,v) gcry_mpi_add ((w),(u),(v)) -#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m)) -#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v)) -#define mpi_sub(w,u,v) gcry_mpi_sub ((w),(u),(v)) -#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m)) -#define mpi_mul_ui(w,u,v) gcry_mpi_mul_ui ((w),(u),(v)) -#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v)) -#define mpi_mul(w,u,v) gcry_mpi_mul ((w),(u),(v)) -#define mpi_mulm(w,u,v,m) gcry_mpi_mulm ((w),(u),(v),(m)) -#define mpi_powm(w,b,e,m) gcry_mpi_powm ( (w), (b), (e), (m) ) -#define mpi_tdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), 0) -#define mpi_fdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), -1) -#define mpi_mod(r,a,m) gcry_mpi_mod ((r), (a), (m)) -#define mpi_gcd(g,a,b) gcry_mpi_gcd ( (g), (a), (b) ) -#define mpi_invm(g,a,b) gcry_mpi_invm ( (g), (a), (b) ) - -#define mpi_get_nbits(a) gcry_mpi_get_nbits ((a)) -#define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b)) -#define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b)) -#define mpi_set_highbit(a,b) gcry_mpi_set_highbit ((a),(b)) -#define mpi_clear_bit(a,b) gcry_mpi_clear_bit ((a),(b)) -#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b)) -#define mpi_rshift(a,b,c) gcry_mpi_rshift ((a),(b),(c)) -#define mpi_lshift(a,b,c) gcry_mpi_lshift ((a),(b),(c)) - -#define mpi_set_opaque(a,b,c) gcry_mpi_set_opaque( (a), (b), (c) ) -#define mpi_get_opaque(a,b) gcry_mpi_get_opaque( (a), (b) ) -#endif /* GCRYPT_NO_MPI_MACROS */ - - - -/************************************ - * * - * Symmetric Cipher Functions * - * * - ************************************/ - -/* The data object used to hold a handle to an encryption object. */ -struct gcry_cipher_handle; -typedef struct gcry_cipher_handle *gcry_cipher_hd_t; - -#ifndef GCRYPT_NO_DEPRECATED -typedef struct gcry_cipher_handle *GCRY_CIPHER_HD _GCRY_GCC_ATTR_DEPRECATED; -typedef struct gcry_cipher_handle *GcryCipherHd _GCRY_GCC_ATTR_DEPRECATED; -#endif - -/* All symmetric encryption algorithms are identified by their IDs. - More IDs may be registered at runtime. */ -enum gcry_cipher_algos - { - GCRY_CIPHER_NONE = 0, - GCRY_CIPHER_IDEA = 1, - GCRY_CIPHER_3DES = 2, - GCRY_CIPHER_CAST5 = 3, - GCRY_CIPHER_BLOWFISH = 4, - GCRY_CIPHER_SAFER_SK128 = 5, - GCRY_CIPHER_DES_SK = 6, - GCRY_CIPHER_AES = 7, - GCRY_CIPHER_AES192 = 8, - GCRY_CIPHER_AES256 = 9, - GCRY_CIPHER_TWOFISH = 10, - - /* Other cipher numbers are above 300 for OpenPGP reasons. */ - GCRY_CIPHER_ARCFOUR = 301, /* Fully compatible with RSA's RC4 (tm). */ - GCRY_CIPHER_DES = 302, /* Yes, this is single key 56 bit DES. */ - GCRY_CIPHER_TWOFISH128 = 303, - GCRY_CIPHER_SERPENT128 = 304, - GCRY_CIPHER_SERPENT192 = 305, - GCRY_CIPHER_SERPENT256 = 306, - GCRY_CIPHER_RFC2268_40 = 307, /* Ron's Cipher 2 (40 bit). */ - GCRY_CIPHER_RFC2268_128 = 308, /* Ron's Cipher 2 (128 bit). */ - GCRY_CIPHER_SEED = 309, /* 128 bit cipher described in RFC4269. */ - GCRY_CIPHER_CAMELLIA128 = 310, - GCRY_CIPHER_CAMELLIA192 = 311, - GCRY_CIPHER_CAMELLIA256 = 312 - }; - -/* The Rijndael algorithm is basically AES, so provide some macros. */ -#define GCRY_CIPHER_AES128 GCRY_CIPHER_AES -#define GCRY_CIPHER_RIJNDAEL GCRY_CIPHER_AES -#define GCRY_CIPHER_RIJNDAEL128 GCRY_CIPHER_AES128 -#define GCRY_CIPHER_RIJNDAEL192 GCRY_CIPHER_AES192 -#define GCRY_CIPHER_RIJNDAEL256 GCRY_CIPHER_AES256 - -/* The supported encryption modes. Note that not all of them are - supported for each algorithm. */ -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. */ - GCRY_CIPHER_MODE_AESWRAP= 7 /* AES-WRAP algorithm. */ - }; - -/* Flags used with the open function. */ -enum gcry_cipher_flags - { - GCRY_CIPHER_SECURE = 1, /* Allocate in secure memory. */ - GCRY_CIPHER_ENABLE_SYNC = 2, /* Enable CFB sync mode. */ - GCRY_CIPHER_CBC_CTS = 4, /* Enable CBC cipher text stealing (CTS). */ - GCRY_CIPHER_CBC_MAC = 8 /* Enable CBC message auth. code (MAC). */ - }; - - -/* Create a handle for algorithm ALGO to be used in MODE. FLAGS may - be given as an bitwise OR of the gcry_cipher_flags values. */ -gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *handle, - int algo, int mode, unsigned int flags); - -/* Close the cioher handle H and release all resource. */ -void gcry_cipher_close (gcry_cipher_hd_t h); - -/* Perform various operations on the cipher object H. */ -gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, - size_t buflen); - -/* Retrieve various information about the cipher object H. */ -gcry_error_t gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer, - size_t *nbytes); - -/* Retrieve various information about the cipher algorithm ALGO. */ -gcry_error_t gcry_cipher_algo_info (int algo, int what, void *buffer, - size_t *nbytes); - -/* 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 "?". */ -const char *gcry_cipher_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE; - -/* Map the algorithm name NAME to an cipher algorithm ID. Return 0 if - the algorithm name is not known. */ -int gcry_cipher_map_name (const char *name) _GCRY_GCC_ATTR_PURE; - -/* Given an ASN.1 object identifier in standard IETF dotted decimal - format in STRING, return the encryption mode associated with that - OID or 0 if not known or applicable. */ -int gcry_cipher_mode_from_oid (const char *string) _GCRY_GCC_ATTR_PURE; - -/* Encrypt the plaintext of size INLEN in IN using the cipher handle H - into the buffer OUT which has an allocated length of OUTSIZE. For - most algorithms it is possible to pass NULL for in and 0 for INLEN - and do a in-place decryption of the data provided in OUT. */ -gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t h, - void *out, size_t outsize, - const void *in, size_t inlen); - -/* The counterpart to gcry_cipher_encrypt. */ -gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t h, - void *out, size_t outsize, - const void *in, size_t inlen); - -/* Set KEY of length KEYLEN bytes for the cipher handle HD. */ -gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t hd, - const void *key, size_t keylen); - - -/* Set initialization vector IV of length IVLEN for the cipher handle HD. */ -gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd, - const void *iv, size_t ivlen); - - -/* Reset the handle to the state after open. */ -#define gcry_cipher_reset(h) gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0) - -/* Perform the OpenPGP sync operation if this is enabled for the - cipher handle H. */ -#define gcry_cipher_sync(h) gcry_cipher_ctl( (h), GCRYCTL_CFB_SYNC, NULL, 0) - -/* Enable or disable CTS in future calls to gcry_encrypt(). CBC mode only. */ -#define gcry_cipher_cts(h,on) gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \ - NULL, on ) - -/* 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); - -/* Retrieve the key length in bytes used with algorithm A. */ -size_t gcry_cipher_get_algo_keylen (int algo); - -/* Retrieve the block length in bytes used with algorithm A. */ -size_t gcry_cipher_get_algo_blklen (int algo); - -/* Return 0 if the algorithm A is available for use. */ -#define gcry_cipher_test_algo(a) \ - gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) - -/* 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); - - -/************************************ - * * - * Asymmetric Cipher Functions * - * * - ************************************/ - -/* The algorithms and their IDs we support. */ -enum gcry_pk_algos - { - GCRY_PK_RSA = 1, - GCRY_PK_RSA_E = 2, /* (deprecated) */ - GCRY_PK_RSA_S = 3, /* (deprecated) */ - GCRY_PK_ELG_E = 16, - GCRY_PK_DSA = 17, - GCRY_PK_ELG = 20, - GCRY_PK_ECDSA = 301, - GCRY_PK_ECDH = 302 - }; - -/* Flags describing usage capabilities of a PK algorithm. */ -#define GCRY_PK_USAGE_SIGN 1 /* Good for signatures. */ -#define GCRY_PK_USAGE_ENCR 2 /* Good for encryption. */ -#define GCRY_PK_USAGE_CERT 4 /* Good to certify other keys. */ -#define GCRY_PK_USAGE_AUTH 8 /* Good for authentication. */ -#define GCRY_PK_USAGE_UNKN 128 /* Unknown usage flag. */ - -/* Encrypt the DATA using the public key PKEY and store the result as - a newly created S-expression at RESULT. */ -gcry_error_t gcry_pk_encrypt (gcry_sexp_t *result, - gcry_sexp_t data, gcry_sexp_t pkey); - -/* Decrypt the DATA using the private key SKEY and store the result as - a newly created S-expression at RESULT. */ -gcry_error_t gcry_pk_decrypt (gcry_sexp_t *result, - gcry_sexp_t data, gcry_sexp_t skey); - -/* Sign the DATA using the private key SKEY and store the result as - a newly created S-expression at RESULT. */ -gcry_error_t gcry_pk_sign (gcry_sexp_t *result, - gcry_sexp_t data, gcry_sexp_t skey); - -/* Check the signature SIGVAL on DATA using the public key PKEY. */ -gcry_error_t gcry_pk_verify (gcry_sexp_t sigval, - gcry_sexp_t data, gcry_sexp_t pkey); - -/* Check that private KEY is sane. */ -gcry_error_t gcry_pk_testkey (gcry_sexp_t key); - -/* Generate a new key pair according to the parameters given in - S_PARMS. The new key pair is returned in as an S-expression in - R_KEY. */ -gcry_error_t gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms); - -/* Catch all function for miscellaneous operations. */ -gcry_error_t gcry_pk_ctl (int cmd, void *buffer, size_t buflen); - -/* Retrieve information about the public key algorithm ALGO. */ -gcry_error_t gcry_pk_algo_info (int algo, int what, - void *buffer, size_t *nbytes); - -/* 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_GCC_ATTR_PURE; - -/* Map the algorithm NAME to a public key algorithm Id. Return 0 if - the algorithm name is not known. */ -int gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE; - -/* Return what is commonly referred as the key length for the given - public or private KEY. */ -unsigned int gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE; - -/* Please note that keygrip is still experimental and should not be - used without contacting the author. */ -unsigned char *gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array); - -/* Return the name of the curve matching KEY. */ -const char *gcry_pk_get_curve (gcry_sexp_t key, int iterator, - unsigned int *r_nbits); - -/* Return an S-expression with the parameters of the named ECC curve - NAME. ALGO must be set to an ECC algorithm. */ -gcry_sexp_t gcry_pk_get_param (int algo, const char *name); - -/* Return 0 if the public key algorithm A is available for use. */ -#define gcry_pk_test_algo(a) \ - gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) - -/* 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); - - - -/************************************ - * * - * Cryptograhic Hash Functions * - * * - ************************************/ - -/* Algorithm IDs for the hash functions we know about. Not all of them - are implemnted. */ -enum gcry_md_algos - { - GCRY_MD_NONE = 0, - GCRY_MD_MD5 = 1, - GCRY_MD_SHA1 = 2, - GCRY_MD_RMD160 = 3, - GCRY_MD_MD2 = 5, - GCRY_MD_TIGER = 6, /* TIGER/192 as used by gpg <= 1.3.2. */ - GCRY_MD_HAVAL = 7, /* HAVAL, 5 pass, 160 bit. */ - GCRY_MD_SHA256 = 8, - GCRY_MD_SHA384 = 9, - GCRY_MD_SHA512 = 10, - GCRY_MD_SHA224 = 11, - GCRY_MD_MD4 = 301, - GCRY_MD_CRC32 = 302, - GCRY_MD_CRC32_RFC1510 = 303, - GCRY_MD_CRC24_RFC2440 = 304, - GCRY_MD_WHIRLPOOL = 305, - GCRY_MD_TIGER1 = 306, /* TIGER fixed. */ - GCRY_MD_TIGER2 = 307 /* TIGER2 variant. */ - }; - -/* Flags used with the open function. */ -enum gcry_md_flags - { - GCRY_MD_FLAG_SECURE = 1, /* Allocate all buffers in "secure" memory. */ - GCRY_MD_FLAG_HMAC = 2 /* Make an HMAC out of this algorithm. */ - }; - -/* (Forward declaration.) */ -struct gcry_md_context; - -/* This object is used to hold a handle to a message digest object. - This structure is private - only to be used by the public gcry_md_* - macros. */ -typedef struct gcry_md_handle -{ - /* Actual context. */ - struct gcry_md_context *ctx; - - /* Buffer management. */ - int bufpos; - int bufsize; - unsigned char buf[1]; -} *gcry_md_hd_t; - -/* Compatibility types, do not use them. */ -#ifndef GCRYPT_NO_DEPRECATED -typedef struct gcry_md_handle *GCRY_MD_HD _GCRY_GCC_ATTR_DEPRECATED; -typedef struct gcry_md_handle *GcryMDHd _GCRY_GCC_ATTR_DEPRECATED; -#endif - -/* 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. */ -gcry_error_t gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags); - -/* Release the message digest object HD. */ -void gcry_md_close (gcry_md_hd_t hd); - -/* Add the message digest algorithm ALGO to the digest object HD. */ -gcry_error_t gcry_md_enable (gcry_md_hd_t hd, int algo); - -/* Create a new digest object as an exact copy of the object HD. */ -gcry_error_t gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd); - -/* Reset the digest object HD to its initial state. */ -void gcry_md_reset (gcry_md_hd_t hd); - -/* Perform various operations on the digest object HD. */ -gcry_error_t gcry_md_ctl (gcry_md_hd_t hd, int cmd, - void *buffer, size_t buflen); - -/* Pass LENGTH bytes of data in BUFFER to the digest object HD so that - it can update the digest values. This is the actual hash - function. */ -void gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length); - -/* Read out the final digest from HD return the digest value for - algorithm ALGO. */ -unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo); - -/* Convenience function to calculate the hash from the data in BUFFER - of size LENGTH using the algorithm ALGO avoiding the creating of a - hash object. The hash is returned in the caller provided buffer - DIGEST which must be large enough to hold the digest of the given - algorithm. */ -void gcry_md_hash_buffer (int algo, void *digest, - const void *buffer, size_t length); - -/* Retrieve the algorithm used with HD. This does not work reliable - if more than one algorithm is enabled in HD. */ -int gcry_md_get_algo (gcry_md_hd_t hd); - -/* Retrieve the length in bytes of the digest yielded by algorithm - ALGO. */ -unsigned int gcry_md_get_algo_dlen (int algo); - -/* Return true if the the algorithm ALGO is enabled in the digest - object A. */ -int gcry_md_is_enabled (gcry_md_hd_t a, int algo); - -/* Return true if the digest object A is allocated in "secure" memory. */ -int gcry_md_is_secure (gcry_md_hd_t a); - -/* Retrieve various information about the object H. */ -gcry_error_t gcry_md_info (gcry_md_hd_t h, int what, void *buffer, - size_t *nbytes); - -/* Retrieve various information about the algorithm ALGO. */ -gcry_error_t gcry_md_algo_info (int algo, int what, void *buffer, - size_t *nbytes); - -/* Map the digest algorithm id ALGO to a string representation of the - algorithm name. For unknown algorithms this function returns - "?". */ -const char *gcry_md_algo_name (int algo) _GCRY_GCC_ATTR_PURE; - -/* Map the algorithm NAME to a digest algorithm Id. Return 0 if - the algorithm name is not known. */ -int gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE; - -/* For use with the HMAC feature, the set MAC key to the KEY of - KEYLEN bytes. */ -gcry_error_t gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen); - -/* Start or stop debugging for digest handle HD; i.e. create a file - named dbgmd-. while hashing. If SUFFIX is NULL, - debugging stops and the file will be closed. */ -void gcry_md_debug (gcry_md_hd_t hd, const char *suffix); - - -/* Update the hash(s) of H with the character C. This is a buffered - version of the gcry_md_write function. */ -#define gcry_md_putc(h,c) \ - do { \ - gcry_md_hd_t h__ = (h); \ - if( (h__)->bufpos == (h__)->bufsize ) \ - gcry_md_write( (h__), NULL, 0 ); \ - (h__)->buf[(h__)->bufpos++] = (c) & 0xff; \ - } while(0) - -/* Finalize the digest calculation. This is not really needed because - gcry_md_read() does this implicitly. */ -#define gcry_md_final(a) \ - gcry_md_ctl ((a), GCRYCTL_FINALIZE, NULL, 0) - -/* Return 0 if the algorithm A is available for use. */ -#define gcry_md_test_algo(a) \ - gcry_md_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) - -/* Return an DER encoded ASN.1 OID for the algorithm A in buffer B. N - must point to size_t variable with the available size of buffer B. - After return it will receive the actual size of the returned - OID. */ -#define gcry_md_get_asnoid(a,b,n) \ - gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n)) - -/* Enable debugging for digest object A; i.e. create files named - dbgmd-. while hashing. B is a string used as the suffix - for the filename. This macro is deprecated, use gcry_md_debug. */ -#ifndef GCRYPT_NO_DEPRECATED -#define gcry_md_start_debug(a,b) \ - gcry_md_ctl( (a), GCRYCTL_START_DUMP, (b), 0 ) - -/* Disable the debugging of A. This macro is deprecated, use - gcry_md_debug. */ -#define gcry_md_stop_debug(a,b) \ - gcry_md_ctl( (a), GCRYCTL_STOP_DUMP, (b), 0 ) -#endif - -/* 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); - - -#if !defined(GCRYPT_NO_DEPRECATED) || defined(_GCRYPT_IN_LIBGCRYPT) -/* Alternative interface for asymmetric cryptography. This interface - is deprecated. */ - -/* The algorithm IDs. */ -typedef enum gcry_ac_id - { - GCRY_AC_RSA = 1, - GCRY_AC_DSA = 17, - GCRY_AC_ELG = 20, - GCRY_AC_ELG_E = 16 - } -gcry_ac_id_t _GCRY_ATTR_INTERNAL; - -/* Key types. */ -typedef enum gcry_ac_key_type - { - GCRY_AC_KEY_SECRET, - GCRY_AC_KEY_PUBLIC - } -gcry_ac_key_type_t _GCRY_ATTR_INTERNAL; - -/* Encoding methods. */ -typedef enum gcry_ac_em - { - GCRY_AC_EME_PKCS_V1_5, - GCRY_AC_EMSA_PKCS_V1_5 - } -gcry_ac_em_t _GCRY_ATTR_INTERNAL; - -/* Encryption and Signature schemes. */ -typedef enum gcry_ac_scheme - { - GCRY_AC_ES_PKCS_V1_5, - GCRY_AC_SSA_PKCS_V1_5 - } -gcry_ac_scheme_t _GCRY_ATTR_INTERNAL; - -/* AC data. */ -#define GCRY_AC_FLAG_DEALLOC (1 << 0) -#define GCRY_AC_FLAG_COPY (1 << 1) -#define GCRY_AC_FLAG_NO_BLINDING (1 << 2) - -/* This type represents a `data set'. */ -typedef struct gcry_ac_data *gcry_ac_data_t _GCRY_ATTR_INTERNAL; - -/* This type represents a single `key', either a secret one or a - public one. */ -typedef struct gcry_ac_key *gcry_ac_key_t _GCRY_ATTR_INTERNAL; - -/* This type represents a `key pair' containing a secret and a public - key. */ -typedef struct gcry_ac_key_pair *gcry_ac_key_pair_t _GCRY_ATTR_INTERNAL; - -/* This type represents a `handle' that is needed by functions - performing cryptographic operations. */ -typedef struct gcry_ac_handle *gcry_ac_handle_t _GCRY_ATTR_INTERNAL; - -typedef gpg_error_t (*gcry_ac_data_read_cb_t) (void *opaque, - unsigned char *buffer, - size_t *buffer_n) - /* */ _GCRY_ATTR_INTERNAL; - -typedef gpg_error_t (*gcry_ac_data_write_cb_t) (void *opaque, - unsigned char *buffer, - size_t buffer_n) - /* */ _GCRY_ATTR_INTERNAL; - -typedef enum - { - GCRY_AC_IO_READABLE, - GCRY_AC_IO_WRITABLE - } -gcry_ac_io_mode_t _GCRY_ATTR_INTERNAL; - -typedef enum - { - GCRY_AC_IO_STRING, - GCRY_AC_IO_CALLBACK - } -gcry_ac_io_type_t _GCRY_ATTR_INTERNAL; - -typedef struct gcry_ac_io -{ - /* This is an INTERNAL structure, do NOT use manually. */ - gcry_ac_io_mode_t mode _GCRY_ATTR_INTERNAL; - gcry_ac_io_type_t type _GCRY_ATTR_INTERNAL; - union - { - union - { - struct - { - gcry_ac_data_read_cb_t cb; - void *opaque; - } callback; - struct - { - unsigned char *data; - size_t data_n; - } string; - void *opaque; - } readable; - union - { - struct - { - gcry_ac_data_write_cb_t cb; - void *opaque; - } callback; - struct - { - unsigned char **data; - size_t *data_n; - } string; - void *opaque; - } writable; - } io _GCRY_ATTR_INTERNAL; -} -gcry_ac_io_t _GCRY_ATTR_INTERNAL; - -/* The caller of gcry_ac_key_pair_generate can provide one of these - structures in order to influence the key generation process in an - algorithm-specific way. */ -typedef struct gcry_ac_key_spec_rsa -{ - gcry_mpi_t e; /* E to use. */ -} gcry_ac_key_spec_rsa_t _GCRY_ATTR_INTERNAL; - -/* Structure used for passing data to the implementation of the - `EME-PKCS-V1_5' encoding method. */ -typedef struct gcry_ac_eme_pkcs_v1_5 -{ - size_t key_size; -} gcry_ac_eme_pkcs_v1_5_t _GCRY_ATTR_INTERNAL; - -typedef enum gcry_md_algos gcry_md_algo_t _GCRY_ATTR_INTERNAL; - -/* Structure used for passing data to the implementation of the - `EMSA-PKCS-V1_5' encoding method. */ -typedef struct gcry_ac_emsa_pkcs_v1_5 -{ - gcry_md_algo_t md; - size_t em_n; -} gcry_ac_emsa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL; - -/* Structure used for passing data to the implementation of the - `SSA-PKCS-V1_5' signature scheme. */ -typedef struct gcry_ac_ssa_pkcs_v1_5 -{ - gcry_md_algo_t md; -} gcry_ac_ssa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL; -#endif /* !GCRYPT_NO_DEPRECATED || !_GCRYPT_IN_LIBGCRYPT */ - - -#ifndef GCRYPT_NO_DEPRECATED -/* Returns a new, empty data set in DATA. */ -gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data) - /* */ _GCRY_ATTR_INTERNAL; - -/* Destroy the data set DATA. */ -void gcry_ac_data_destroy (gcry_ac_data_t data) - /* */ _GCRY_ATTR_INTERNAL; - -/* 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_ATTR_INTERNAL; - -/* Return the number of named MPI values inside of the data set - DATA. */ -unsigned int gcry_ac_data_length (gcry_ac_data_t data) - /* */ _GCRY_ATTR_INTERNAL; - -/* Destroy any values contained in the data set DATA. */ -void gcry_ac_data_clear (gcry_ac_data_t data) - /* */ _GCRY_ATTR_INTERNAL; - -/* Add the value MPI to DATA with the label NAME. If FLAGS contains - GCRY_AC_FLAG_DATA_COPY, the data set will contain copies of NAME - and MPI. If FLAGS contains GCRY_AC_FLAG_DATA_DEALLOC or - GCRY_AC_FLAG_DATA_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_ATTR_INTERNAL; - -/* Store the value labelled with NAME found in DATA in MPI. If FLAGS - contains GCRY_AC_FLAG_COPY, store a copy of the MPI value contained - in the data set. MPI may be NULL. */ -gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags, - const char *name, gcry_mpi_t *mpi) - /* */ _GCRY_ATTR_INTERNAL; - -/* Stores in NAME and MPI the named MPI value contained in the data - set DATA with the index IDX. If FLAGS contains GCRY_AC_FLAG_COPY, - store copies of the values contained in the data set. NAME or MPI - may be NULL. */ -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_ATTR_INTERNAL; - -/* 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_ATTR_INTERNAL; - -/* 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, gcry_sexp_t sexp, - const char **identifiers) - /* */ _GCRY_ATTR_INTERNAL; - -/* 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, ...) - /* */ _GCRY_ATTR_INTERNAL; - -/* 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) - /* */ _GCRY_ATTR_INTERNAL; - -/* Create a new ac handle. */ -gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle, - gcry_ac_id_t algorithm, unsigned int flags) - /* */ _GCRY_ATTR_INTERNAL; - -/* Destroy an ac handle. */ -void gcry_ac_close (gcry_ac_handle_t handle) - /* */ _GCRY_ATTR_INTERNAL; - -/* Initialize a key from a given data set. */ -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_ATTR_INTERNAL; - -/* 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__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 *spec, - gcry_ac_key_pair_t *key_pair, - gcry_mpi_t **misc_data) - /* */ _GCRY_ATTR_INTERNAL; - -/* 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_ATTR_INTERNAL; - -/* Returns the data set contained in the key KEY. */ -gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key) - /* */ _GCRY_ATTR_INTERNAL; - -/* 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_ATTR_INTERNAL; - -/* 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_ATTR_INTERNAL; - -/* 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_ATTR_INTERNAL; - -/* Destroy a key. */ -void gcry_ac_key_destroy (gcry_ac_key_t key) - /* */ _GCRY_ATTR_INTERNAL; - -/* Destroy a key pair. */ -void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair) - /* */ _GCRY_ATTR_INTERNAL; - -/* Encodes 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 *io_read, - gcry_ac_io_t *io_write) - /* */ _GCRY_ATTR_INTERNAL; - -/* Decodes 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 *io_read, - gcry_ac_io_t *io_write) - /* */ _GCRY_ATTR_INTERNAL; - -/* Encrypt the plain text MPI value DATA_PLAIN with the key KEY under - the control of the flags FLAGS and store 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_ATTR_INTERNAL; - -/* Decrypt the decrypted data contained in the data set DATA_ENCRYPTED - with the key KEY under the control of the flags FLAGS and store 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_ATTR_INTERNAL; - -/* Sign the data contained in DATA with the key KEY and store the - resulting signature in the data set 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_ATTR_INTERNAL; - -/* Verify 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_ATTR_INTERNAL; - -/* Encrypts the plain text readable from IO_MESSAGE through HANDLE - with the public key KEY according to SCHEME, FLAGS and OPTS. If - OPTS is not NULL, it has to be a pointer to a structure specific to - the chosen scheme (gcry_ac_es_*_t). The encrypted message is - written to IO_CIPHER. */ -gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle, - gcry_ac_scheme_t scheme, - unsigned int flags, void *opts, - gcry_ac_key_t key, - gcry_ac_io_t *io_message, - gcry_ac_io_t *io_cipher) - /* */ _GCRY_ATTR_INTERNAL; - -/* Decrypts the cipher text readable from IO_CIPHER through HANDLE - with the secret key KEY according to SCHEME, @var{flags} and OPTS. - If OPTS is not NULL, it has to be a pointer to a structure specific - to the chosen scheme (gcry_ac_es_*_t). The decrypted message is - written to IO_MESSAGE. */ -gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle, - gcry_ac_scheme_t scheme, - unsigned int flags, void *opts, - gcry_ac_key_t key, - gcry_ac_io_t *io_cipher, - gcry_ac_io_t *io_message) - /* */ _GCRY_ATTR_INTERNAL; - -/* Signs the message readable from IO_MESSAGE through HANDLE with the - secret key KEY according to SCHEME, FLAGS and OPTS. If OPTS is not - NULL, it has to be a pointer to a structure specific to the chosen - scheme (gcry_ac_ssa_*_t). The signature is written to - IO_SIGNATURE. */ -gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle, - gcry_ac_scheme_t scheme, - unsigned int flags, void *opts, - gcry_ac_key_t key, - gcry_ac_io_t *io_message, - gcry_ac_io_t *io_signature) - /* */ _GCRY_ATTR_INTERNAL; - -/* Verifies through HANDLE that the signature readable from - IO_SIGNATURE is indeed the result of signing the message readable - from IO_MESSAGE with the secret key belonging to the public key KEY - according to SCHEME and OPTS. If OPTS is not NULL, it has to be an - anonymous structure (gcry_ac_ssa_*_t) specific to the chosen - scheme. */ -gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle, - gcry_ac_scheme_t scheme, - unsigned int flags, void *opts, - gcry_ac_key_t key, - gcry_ac_io_t *io_message, - gcry_ac_io_t *io_signature) - /* */ _GCRY_ATTR_INTERNAL; - -/* Store the textual representation of the algorithm whose id is given - in ALGORITHM in NAME. This function is deprecated; use - gcry_pk_algo_name. */ -gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm, - const char **name) - /* */ _GCRY_GCC_ATTR_DEPRECATED; -/* Store the numeric ID of the algorithm whose textual representation - is contained in NAME in ALGORITHM. This function is deprecated; - use gcry_pk_map_name. */ -gcry_error_t gcry_ac_name_to_id (const char *name, - gcry_ac_id_t *algorithm) - /* */ _GCRY_GCC_ATTR_DEPRECATED; -#endif /*GCRYPT_NO_DEPRECATED*/ - - -/****************************** - * * - * Key Derivation Functions * - * * - ******************************/ - -/* Algorithm IDs for the KDFs. */ -enum gcry_kdf_algos - { - GCRY_KDF_NONE = 0, - GCRY_KDF_SIMPLE_S2K = 16, - GCRY_KDF_SALTED_S2K = 17, - GCRY_KDF_ITERSALTED_S2K = 19, - GCRY_KDF_PBKDF1 = 33, - GCRY_KDF_PBKDF2 = 34 - }; - -/* Derive a key from a passphrase. */ -gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen, - int algo, int subalgo, - const void *salt, size_t saltlen, - unsigned long iterations, - size_t keysize, void *keybuffer); - - - - -/************************************ - * * - * Random Generating Functions * - * * - ************************************/ - -/* The possible values for the random quality. The rule of thumb is - to use STRONG for session keys and VERY_STRONG for key material. - WEAK is usually an alias for STRONG and should not be used anymore - (except with gcry_mpi_randomize); use gcry_create_nonce instead. */ -typedef enum gcry_random_level - { - GCRY_WEAK_RANDOM = 0, - GCRY_STRONG_RANDOM = 1, - GCRY_VERY_STRONG_RANDOM = 2 - } -gcry_random_level_t; - -/* Fill BUFFER with LENGTH bytes of random, using random numbers of - quality LEVEL. */ -void gcry_randomize (void *buffer, size_t length, - enum gcry_random_level level); - -/* Add the external random from BUFFER with LENGTH bytes into the - pool. QUALITY should either be -1 for unknown or in the range of 0 - to 100 */ -gcry_error_t gcry_random_add_bytes (const void *buffer, size_t length, - int quality); - -/* If random numbers are used in an application, this macro should be - called from time to time so that new stuff gets added to the - internal pool of the RNG. */ -#define gcry_fast_random_poll() gcry_control (GCRYCTL_FAST_POLL, NULL) - - -/* Return NBYTES of allocated random using a random numbers of quality - LEVEL. */ -void *gcry_random_bytes (size_t nbytes, enum gcry_random_level level) - _GCRY_GCC_ATTR_MALLOC; - -/* Return NBYTES of allocated random using a random numbers of quality - LEVEL. The random numbers are created returned in "secure" - memory. */ -void *gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level) - _GCRY_GCC_ATTR_MALLOC; - - -/* Set the big integer W to a random value of NBITS using a random - generator with quality LEVEL. Note that by using a level of - GCRY_WEAK_RANDOM gcry_create_nonce is used internally. */ -void gcry_mpi_randomize (gcry_mpi_t w, - unsigned int nbits, enum gcry_random_level level); - - -/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */ -void gcry_create_nonce (void *buffer, size_t length); - - - - - -/*******************************/ -/* */ -/* Prime Number Functions */ -/* */ -/*******************************/ - -/* Mode values passed to a gcry_prime_check_func_t. */ -#define GCRY_PRIME_CHECK_AT_FINISH 0 -#define GCRY_PRIME_CHECK_AT_GOT_PRIME 1 -#define GCRY_PRIME_CHECK_AT_MAYBE_PRIME 2 - -/* The function should return 1 if the operation shall continue, 0 to - reject the prime candidate. */ -typedef int (*gcry_prime_check_func_t) (void *arg, int mode, - gcry_mpi_t candidate); - -/* Flags for gcry_prime_generate(): */ - -/* Allocate prime numbers and factors in secure memory. */ -#define GCRY_PRIME_FLAG_SECRET (1 << 0) - -/* Make sure that at least one prime factor is of size - `FACTOR_BITS'. */ -#define GCRY_PRIME_FLAG_SPECIAL_FACTOR (1 << 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); - -/* 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 - teh start for the search. */ -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); - - -/* Convenience function to release the FACTORS array. */ -void gcry_prime_release_factors (gcry_mpi_t *factors); - - -/* Check wether the number X is prime. */ -gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags); - - - -/************************************ - * * - * Miscellaneous Stuff * - * * - ************************************/ - -/* Log levels used by the internal logging facility. */ -enum gcry_log_levels - { - GCRY_LOG_CONT = 0, /* (Continue the last log line.) */ - GCRY_LOG_INFO = 10, - GCRY_LOG_WARN = 20, - GCRY_LOG_ERROR = 30, - GCRY_LOG_FATAL = 40, - GCRY_LOG_BUG = 50, - GCRY_LOG_DEBUG = 100 - }; - -/* Type for progress handlers. */ -typedef void (*gcry_handler_progress_t) (void *, const char *, int, int, int); - -/* Type for memory allocation handlers. */ -typedef void *(*gcry_handler_alloc_t) (size_t n); - -/* Type for secure memory check handlers. */ -typedef int (*gcry_handler_secure_check_t) (const void *); - -/* Type for memory reallocation handlers. */ -typedef void *(*gcry_handler_realloc_t) (void *p, size_t n); - -/* Type for memory free handlers. */ -typedef void (*gcry_handler_free_t) (void *); - -/* Type for out-of-memory handlers. */ -typedef int (*gcry_handler_no_mem_t) (void *, size_t, unsigned int); - -/* Type for fatal error handlers. */ -typedef void (*gcry_handler_error_t) (void *, int, const char *); - -/* Type for logging handlers. */ -typedef void (*gcry_handler_log_t) (void *, int, const char *, va_list); - -/* Certain operations can provide progress information. This function - is used to register a handler for retrieving these information. */ -void gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data); - - -/* Register a custom memory allocation functions. */ -void gcry_set_allocation_handler ( - gcry_handler_alloc_t func_alloc, - gcry_handler_alloc_t func_alloc_secure, - gcry_handler_secure_check_t func_secure_check, - gcry_handler_realloc_t func_realloc, - gcry_handler_free_t func_free); - -/* Register a function used instead of the internal out of memory - handler. */ -void gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque); - -/* Register a function used instead of the internal fatal error - handler. */ -void gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque); - -/* Register a function used instead of the internal logging - facility. */ -void gcry_set_log_handler (gcry_handler_log_t f, void *opaque); - -/* Reserved for future use. */ -void gcry_set_gettext_handler (const char *(*f)(const char*)); - -/* Libgcrypt uses its own memory allocation. It is important to use - gcry_free () to release memory allocated by libgcrypt. */ -void *gcry_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC; -void *gcry_calloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; -void *gcry_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC; -void *gcry_calloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; -void *gcry_realloc (void *a, size_t n); -char *gcry_strdup (const char *string) _GCRY_GCC_ATTR_MALLOC; -void *gcry_xmalloc (size_t n) _GCRY_GCC_ATTR_MALLOC; -void *gcry_xcalloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; -void *gcry_xmalloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC; -void *gcry_xcalloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; -void *gcry_xrealloc (void *a, size_t n); -char *gcry_xstrdup (const char * a) _GCRY_GCC_ATTR_MALLOC; -void gcry_free (void *a); - -/* Return true if A is allocated in "secure" memory. */ -int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE; - -/* Return true if Libgcrypt is in FIPS mode. */ -#define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) - - -/* Include support for Libgcrypt modules. */ -#include - -#if 0 /* (Keep Emacsens' auto-indent happy.) */ -{ -#endif -#ifdef __cplusplus -} -#endif -#endif /* _GCRYPT_H */ -/* -@emacs_local_vars_begin@ -@emacs_local_vars_read_only@ -@emacs_local_vars_end@ -*/ diff --git a/grub-core/lib/libgcrypt/src/gcryptrnd.c b/grub-core/lib/libgcrypt/src/gcryptrnd.c deleted file mode 100644 index b13931b6e..000000000 --- a/grub-core/lib/libgcrypt/src/gcryptrnd.c +++ /dev/null @@ -1,680 +0,0 @@ -/* gcryptrnd.c - Libgcrypt Random Number Daemon - * Copyright (C) 2006 Free Software Foundation, Inc. - * - * Gcryptend is free software; you can 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. - * - * Gcryptrnd is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR 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. - */ - -/* We require vsyslog pth - We need to test for: setrlimit - - We should also prioritize requests. This is best done by putting - the requests into queues and have a main thread processing these - queues. - - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PGM "gcryptrnd" -#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION -#define BUGREPORT_LINE "\nReport bugs to .\n" - -/* Pth wrapper function definitions. */ -GCRY_THREAD_OPTION_PTH_IMPL; - - -/* Flag set to true if we have been daemonized. */ -static int running_detached; -/* Flag indicating that a shutdown has been requested. */ -static int shutdown_pending; -/* Counter for active connections. */ -static int active_connections; - - - -/* Local prototypes. */ -static void serve (int listen_fd); - - - - - -/* To avoid that a compiler optimizes certain memset calls away, these - macros may be used instead. */ -#define wipememory2(_ptr,_set,_len) do { \ - volatile char *_vptr=(volatile char *)(_ptr); \ - size_t _vlen=(_len); \ - while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \ - } while(0) -#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) - - - - -/* Error printing utility. PRIORITY should be one of syslog's - priority levels. This functions prints to the stderr or syslog - depending on whether we are already daemonized. */ -static void -logit (int priority, const char *format, ...) -{ - va_list arg_ptr; - - va_start (arg_ptr, format) ; - if (running_detached) - { - vsyslog (priority, format, arg_ptr); - } - else - { - fputs (PGM ": ", stderr); - vfprintf (stderr, format, arg_ptr); - putc ('\n', stderr); - } - va_end (arg_ptr); -} - -/* Callback used by libgcrypt for logging. */ -static void -my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr) -{ - (void)dummy; - - /* Map the log levels. */ - switch (level) - { - case GCRY_LOG_CONT: level = LOG_INFO /* FIXME */; break; - case GCRY_LOG_INFO: level = LOG_INFO; break; - case GCRY_LOG_WARN: level = LOG_WARNING; break; - case GCRY_LOG_ERROR:level = LOG_ERR; break; - case GCRY_LOG_FATAL:level = LOG_CRIT; break; - case GCRY_LOG_BUG: level = LOG_CRIT; break; - case GCRY_LOG_DEBUG:level = LOG_DEBUG; break; - default: level = LOG_ERR; break; - } - if (running_detached) - { - vsyslog (level, format, arg_ptr); - } - else - { - fputs (PGM ": ", stderr); - vfprintf (stderr, format, arg_ptr); - if (!*format || format[strlen (format)-1] != '\n') - putc ('\n', stderr); - } -} - - -/* The cleanup handler - used to wipe out the secure memory. */ -static void -cleanup (void) -{ - gcry_control (GCRYCTL_TERM_SECMEM ); -} - - -/* Make us a daemon and open the syslog. */ -static void -daemonize (void) -{ - int i; - pid_t pid; - - fflush (NULL); - - pid = fork (); - if (pid == (pid_t)-1) - { - logit (LOG_CRIT, "fork failed: %s", strerror (errno)); - exit (1); - } - if (pid) - exit (0); - - if (setsid() == -1) - { - logit (LOG_CRIT, "setsid() failed: %s", strerror(errno)); - exit (1); - } - - signal (SIGHUP, SIG_IGN); - - pid = fork (); - if (pid == (pid_t)-1) - { - logit (LOG_CRIT, PGM ": second fork failed: %s", strerror (errno)); - exit (1); - } - if (pid) - exit (0); /* First child exits. */ - - running_detached = 1; - - if (chdir("/")) - { - logit (LOG_CRIT, "chdir(\"/\") failed: %s", strerror (errno)); - exit (1); - } - umask (0); - - for (i=0; i <= 2; i++) - close (i); - - openlog (PGM, LOG_PID, LOG_DAEMON); -} - - -static void -disable_core_dumps (void) -{ -#ifdef HAVE_SETRLIMIT - struct rlimit limit; - - if (getrlimit (RLIMIT_CORE, &limit)) - limit.rlim_max = 0; - limit.rlim_cur = 0; - if( !setrlimit (RLIMIT_CORE, &limit) ) - return 0; - if (errno != EINVAL && errno != ENOSYS) - logit (LOG_ERR, "can't disable core dumps: %s\n", strerror (errno)); -#endif /* HAVE_SETRLIMIT */ -} - - - -static void -print_version (int with_help) -{ - fputs (MYVERSION_LINE "\n" - "Copyright (C) 2006 Free Software Foundation, Inc.\n" - "License GPLv2+: GNU GPL version 2 or later " - "\n" - "This is free software: you are free to change and redistribute it.\n" - "There is NO WARRANTY, to the extent permitted by law.\n", - stdout); - - if (with_help) - fputs ("\n" - "Usage: " PGM " [OPTIONS] [SOCKETNAME]\n" - "Start Libgcrypt's random number daemon listening" - " on socket SOCKETNAME\n" - "SOCKETNAME defaults to XXX\n" - "\n" - " --no-detach do not deatach from the console\n" - " --version print version of the program and exit\n" - " --help display this help and exit\n" - BUGREPORT_LINE, stdout ); - - exit (0); -} - -static int -print_usage (void) -{ - fputs ("usage: " PGM " [OPTIONS] [SOCKETNAME]\n", stderr); - fputs (" (use --help to display options)\n", stderr); - exit (1); -} - - -int -main (int argc, char **argv) -{ - int no_detach = 0; - gpg_error_t err; - struct sockaddr_un *srvr_addr; - socklen_t addrlen; - int fd; - int rc; - const char *socketname = "/var/run/libgcrypt/S.gcryptrnd"; - - - if (argc) - { - argc--; argv++; - } - while (argc && **argv == '-' && (*argv)[1] == '-') - { - if (!(*argv)[2]) - { - argc--; argv++; - break; - } - else if (!strcmp (*argv, "--version")) - print_version (0); - else if (!strcmp (*argv, "--help")) - print_version (1); - else if (!strcmp (*argv, "--no-detach")) - { - no_detach = 1; - argc--; argv++; - } - else - print_usage (); - } - - if (argc == 1) - socketname = argv[0]; - else if (argc > 1) - print_usage (); - - if (!no_detach) - daemonize (); - - signal (SIGPIPE, SIG_IGN); - - logit (LOG_NOTICE, "started version " VERSION ); - - /* Libgcrypt requires us to register the threading model before we - do anything else with it. Note that this also calls pth_init. We - do the initialization while already running as a daemon to avoid - overhead with double initialization of Libgcrypt. */ - err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth); - if (err) - { - logit (LOG_CRIT, "can't register GNU Pth with Libgcrypt: %s", - gpg_strerror (err)); - exit (1); - } - - /* Check that the libgcrypt version is sufficient. */ - if (!gcry_check_version (VERSION) ) - { - logit (LOG_CRIT, "libgcrypt is too old (need %s, have %s)", - VERSION, gcry_check_version (NULL) ); - exit (1); - } - - /* Register the logging callback and tell Libcgrypt to put the - random pool into secure memory. */ - gcry_set_log_handler (my_gcry_logger, NULL); - gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); - - /* Obviously we don't want to allow any core dumps. */ - disable_core_dumps (); - - /* Initialize the secure memory stuff which will also drop any extra - privileges we have. */ - gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); - - /* Register a cleanup handler. */ - atexit (cleanup); - - /* Create and listen on the socket. */ - fd = socket (AF_UNIX, SOCK_STREAM, 0); - if (fd == -1) - { - logit (LOG_CRIT, "can't create socket: %s", strerror (errno)); - exit (1); - } - srvr_addr = gcry_xmalloc (sizeof *srvr_addr); - memset (srvr_addr, 0, sizeof *srvr_addr); - srvr_addr->sun_family = AF_UNIX; - if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path)) - { - logit (LOG_CRIT, "socket name `%s' too long", socketname); - exit (1); - } - strcpy (srvr_addr->sun_path, socketname); - addrlen = (offsetof (struct sockaddr_un, sun_path) - + strlen (srvr_addr->sun_path) + 1); - rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen); - if (rc == -1 && errno == EADDRINUSE) - { - remove (socketname); - rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen); - } - if (rc == -1) - { - logit (LOG_CRIT, "error binding socket to `%s': %s", - srvr_addr->sun_path, strerror (errno)); - close (fd); - exit (1); - } - - if (listen (fd, 5 ) == -1) - { - logit (LOG_CRIT, "listen() failed: %s", strerror (errno)); - close (fd); - exit (1); - } - - logit (LOG_INFO, "listening on socket `%s', fd=%d", - srvr_addr->sun_path, fd); - - serve (fd); - close (fd); - - logit (LOG_NOTICE, "stopped version " VERSION ); - return 0; -} - - -/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on - success or another value on write error. */ -static int -writen (int fd, const void *buffer, size_t length) -{ - while (length) - { - ssize_t n = pth_write (fd, buffer, length); - if (n < 0) - { - logit (LOG_ERR, "connection %d: write error: %s", - fd, strerror (errno)); - return -1; /* write error */ - } - length -= n; - buffer = (const char*)buffer + n; - } - return 0; /* Okay */ -} - - -/* Send an error response back. Returns 0 on success. */ -static int -send_error (int fd, int errcode) -{ - unsigned char buf[2]; - - buf[0] = errcode; - buf[1] = 0; - return writen (fd, buf, 2 ); -} - -/* Send a pong response back. Returns 0 on success or another value - on write error. */ -static int -send_pong (int fd) -{ - return writen (fd, "\x00\x04pong", 6); -} - -/* Send a nonce of size LENGTH back. Return 0 on success. */ -static int -send_nonce (int fd, int length) -{ - unsigned char buf[2+255]; - int rc; - - assert (length >= 0 && length <= 255); - buf[0] = 0; - buf[1] = length; - gcry_create_nonce (buf+2, length); - rc = writen (fd, buf, 2+length ); - wipememory (buf+2, length); - return rc; -} - -/* Send a random of size LENGTH with quality LEVEL back. Return 0 on - success. */ -static int -send_random (int fd, int length, int level) -{ - unsigned char buf[2+255]; - int rc; - - assert (length >= 0 && length <= 255); - assert (level == GCRY_STRONG_RANDOM || level == GCRY_VERY_STRONG_RANDOM); - buf[0] = 0; - buf[1] = length; - /* Note that we don't bother putting the random stuff into secure - memory because this daemon is anyway intended to be run under - root and it is questionable whether the kernel buffers etc. are - equally well protected. */ - gcry_randomize (buf+2, length, level); - rc = writen (fd, buf, 2+length ); - wipememory (buf+2, length); - return rc; -} - -/* Main processing loop for a connection. - - A request is made up of: - - 1 byte Total length of request; must be 3 - 1 byte Command - 0 = Ping - 10 = GetNonce - 11 = GetStrongRandom - 12 = GetVeryStrongRandom - (all other values are reserved) - 1 byte Number of requested bytes. - This is ignored for command Ping. - - A response is made up of: - - 1 byte Error Code - 0 = Everything is fine - 1 = Bad Command - 0xff = Other error. - (For a bad request the connection will simply be closed) - 1 byte Length of data - n byte data - - The requests are read as long as the connection is open. - - - */ -static void -connection_loop (int fd) -{ - unsigned char request[3]; - unsigned char *p; - int nleft, n; - int rc; - - for (;;) - { - for (nleft=3, p=request; nleft > 0; ) - { - n = pth_read (fd, p, nleft); - if (!n && p == request) - return; /* Client terminated connection. */ - if (n <= 0) - { - logit (LOG_ERR, "connection %d: read error: %s", - fd, n? strerror (errno) : "Unexpected EOF"); - return; - } - p += n; - nleft -= n; - } - if (request[0] != 3) - { - logit (LOG_ERR, "connection %d: invalid length (%d) of request", - fd, request[0]); - return; - } - - switch (request[1]) - { - case 0: /* Ping */ - rc = send_pong (fd); - break; - case 10: /* GetNonce */ - rc = send_nonce (fd, request[2]); - break; - case 11: /* GetStrongRandom */ - rc = send_random (fd, request[2], GCRY_STRONG_RANDOM); - break; - case 12: /* GetVeryStrongRandom */ - rc = send_random (fd, request[2], GCRY_VERY_STRONG_RANDOM); - break; - - default: /* Invalid command */ - rc = send_error (fd, 1); - break; - } - if (rc) - break; /* A write error occurred while sending the response. */ - } -} - - - -/* Entry point for a connection's thread. */ -static void * -connection_thread (void *arg) -{ - int fd = (int)arg; - - active_connections++; - logit (LOG_INFO, "connection handler for fd %d started", fd); - - connection_loop (fd); - - close (fd); - logit (LOG_INFO, "connection handler for fd %d terminated", fd); - active_connections--; - - return NULL; -} - - -/* This signal handler is called from the main loop between acepting - connections. It is called on the regular stack, thus no special - caution needs to be taken. It returns true to indicate that the - process should terminate. */ -static int -handle_signal (int signo) -{ - switch (signo) - { - case SIGHUP: - logit (LOG_NOTICE, "SIGHUP received - re-reading configuration"); - break; - - case SIGUSR1: - logit (LOG_NOTICE, "SIGUSR1 received - no action defined"); - break; - - case SIGUSR2: - logit (LOG_NOTICE, "SIGUSR2 received - no action defined"); - break; - - case SIGTERM: - if (!shutdown_pending) - logit (LOG_NOTICE, "SIGTERM received - shutting down ..."); - else - logit (LOG_NOTICE, "SIGTERM received - still %d active connections", - active_connections); - shutdown_pending++; - if (shutdown_pending > 2) - { - logit (LOG_NOTICE, "shutdown forced"); - return 1; - } - break; - - case SIGINT: - logit (LOG_NOTICE, "SIGINT received - immediate shutdown"); - return 1; - - default: - logit (LOG_NOTICE, "signal %d received - no action defined\n", signo); - } - return 0; -} - - - -/* Main server loop. This is called with the FD of the listening - socket. */ -static void -serve (int listen_fd) -{ - pth_attr_t tattr; - pth_event_t ev; - sigset_t sigs; - int signo; - struct sockaddr_un paddr; - socklen_t plen = sizeof (paddr); - int fd; - - tattr = pth_attr_new(); - pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); - pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024); - pth_attr_set (tattr, PTH_ATTR_NAME, "connection"); - - sigemptyset (&sigs); - sigaddset (&sigs, SIGHUP); - sigaddset (&sigs, SIGUSR1); - sigaddset (&sigs, SIGUSR2); - sigaddset (&sigs, SIGINT); - sigaddset (&sigs, SIGTERM); - ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); - - for (;;) - { - if (shutdown_pending) - { - if (!active_connections) - break; /* Ready. */ - - /* Do not accept anymore connections but wait for existing - connections to terminate. */ - signo = 0; - pth_wait (ev); - if (pth_event_occurred (ev) && signo) - if (handle_signal (signo)) - break; /* Stop the loop. */ - continue; - } - - gcry_fast_random_poll (); - fd = pth_accept_ev (listen_fd, (struct sockaddr *)&paddr, &plen, ev); - if (fd == -1) - { - if (pth_event_occurred (ev)) - { - if (handle_signal (signo)) - break; /* Stop the loop. */ - continue; - } - logit (LOG_WARNING, "accept failed: %s - waiting 1s\n", - strerror (errno)); - gcry_fast_random_poll (); - pth_sleep (1); - continue; - } - - if (!pth_spawn (tattr, connection_thread, (void*)fd)) - { - logit (LOG_ERR, "error spawning connection handler: %s\n", - strerror (errno) ); - close (fd); - } - } - - pth_event_free (ev, PTH_FREE_ALL); -} diff --git a/grub-core/lib/libgcrypt/src/getrandom.c b/grub-core/lib/libgcrypt/src/getrandom.c deleted file mode 100644 index f9bb5c0c5..000000000 --- a/grub-core/lib/libgcrypt/src/getrandom.c +++ /dev/null @@ -1,326 +0,0 @@ -/* getrandom.c - Libgcrypt Random Number client - * Copyright (C) 2006 Free Software Foundation, Inc. - * - * Getrandom is free software; you can 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. - * - * Getrandom is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PGM "getrandom" -#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION -#define BUGREPORT_LINE "\nReport bugs to .\n" - - -static void -logit (const char *format, ...) -{ - va_list arg_ptr; - - va_start (arg_ptr, format) ; - fputs (PGM ": ", stderr); - vfprintf (stderr, format, arg_ptr); - putc ('\n', stderr); - va_end (arg_ptr); -} - - -/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on - success or another value on write error. */ -static int -writen (int fd, const void *buffer, size_t length) -{ - while (length) - { - ssize_t n; - - do - n = write (fd, buffer, length); - while (n < 0 && errno == EINTR); - if (n < 0) - { - logit ("write error: %s", strerror (errno)); - return -1; /* write error */ - } - length -= n; - buffer = (const char *)buffer + n; - } - return 0; /* Okay */ -} - - - - -static void -print_version (int with_help) -{ - fputs (MYVERSION_LINE "\n" - "Copyright (C) 2006 Free Software Foundation, Inc.\n" - "License GPLv2+: GNU GPL version 2 or later " - "\n" - "This is free software: you are free to change and redistribute it.\n" - "There is NO WARRANTY, to the extent permitted by law.\n", - stdout); - - if (with_help) - fputs ("\n" - "Usage: " PGM " [OPTIONS] NBYTES\n" - "Connect to libgcrypt's random number daemon and " - "return random numbers" - "\n" - " --nonce Return weak random suitable for a nonce\n" - " --very-strong Return very strong random\n" - " --ping Send a ping\n" - " --socket NAME Name of sockket to connect to\n" - " --hex Return result as a hex dump\n" - " --verbose Show what we are doing\n" - " --version Print version of the program and exit\n" - " --help Display this help and exit\n" - BUGREPORT_LINE, stdout ); - - exit (0); -} - -static int -print_usage (void) -{ - fputs ("usage: " PGM " [OPTIONS] NBYTES\n", stderr); - fputs (" (use --help to display options)\n", stderr); - exit (1); -} - - -int -main (int argc, char **argv) -{ - struct sockaddr_un *srvr_addr; - socklen_t addrlen; - int fd; - int rc; - unsigned char buffer[300]; - int nleft, nread; - const char *socketname = "/var/run/libgcrypt/S.gcryptrnd"; - int do_ping = 0; - int get_nonce = 0; - int get_very_strong = 0; - int req_nbytes, nbytes, n; - int verbose = 0; - int fail = 0; - int do_hex = 0; - - if (argc) - { - argc--; argv++; - } - while (argc && **argv == '-' && (*argv)[1] == '-') - { - if (!(*argv)[2]) - { - argc--; argv++; - break; - } - else if (!strcmp (*argv, "--version")) - print_version (0); - else if (!strcmp (*argv, "--help")) - print_version (1); - else if (!strcmp (*argv, "--socket") && argc > 1 ) - { - argc--; argv++; - socketname = *argv; - argc--; argv++; - } - else if (!strcmp (*argv, "--nonce")) - { - argc--; argv++; - get_nonce = 1; - } - else if (!strcmp (*argv, "--very-strong")) - { - argc--; argv++; - get_very_strong = 1; - } - else if (!strcmp (*argv, "--ping")) - { - argc--; argv++; - do_ping = 1; - } - else if (!strcmp (*argv, "--hex")) - { - argc--; argv++; - do_hex = 1; - } - else if (!strcmp (*argv, "--verbose")) - { - argc--; argv++; - verbose = 1; - } - else - print_usage (); - } - - - if (!argc && do_ping) - ; /* This is allowed. */ - else if (argc != 1) - print_usage (); - req_nbytes = argc? atoi (*argv) : 0; - - if (req_nbytes < 0) - print_usage (); - - /* Create a socket. */ - fd = socket (AF_UNIX, SOCK_STREAM, 0); - if (fd == -1) - { - logit ("can't create socket: %s", strerror (errno)); - exit (1); - } - srvr_addr = malloc (sizeof *srvr_addr); - if (!srvr_addr) - { - logit ("malloc failed: %s", strerror (errno)); - exit (1); - } - memset (srvr_addr, 0, sizeof *srvr_addr); - srvr_addr->sun_family = AF_UNIX; - if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path)) - { - logit ("socket name `%s' too long", socketname); - exit (1); - } - strcpy (srvr_addr->sun_path, socketname); - addrlen = (offsetof (struct sockaddr_un, sun_path) - + strlen (srvr_addr->sun_path) + 1); - rc = connect (fd, (struct sockaddr*) srvr_addr, addrlen); - if (rc == -1) - { - logit ("error connecting socket `%s': %s", - srvr_addr->sun_path, strerror (errno)); - close (fd); - exit (1); - } - - do - { - nbytes = req_nbytes > 255? 255 : req_nbytes; - req_nbytes -= nbytes; - - buffer[0] = 3; - if (do_ping) - buffer[1] = 0; - else if (get_nonce) - buffer[1] = 10; - else if (get_very_strong) - buffer[1] = 12; - else - buffer[1] = 11; - buffer[2] = nbytes; - if (writen (fd, buffer, 3)) - fail = 1; - else - { - for (nleft=2, nread=0; nleft > 0; ) - { - do - n = read (fd, buffer+nread, nleft); - while (n < 0 && errno == EINTR); - if (n < 0) - { - logit ("read error: %s", strerror (errno)); - exit (1); - } - nleft -= n; - nread += n; - if (nread && buffer[0]) - { - logit ("server returned error code %d", buffer[0]); - exit (1); - } - } - if (verbose) - logit ("received response with %d bytes of data", buffer[1]); - if (buffer[1] < nbytes) - { - logit ("warning: server returned less bytes than requested"); - fail = 1; - } - else if (buffer[1] > nbytes && !do_ping) - { - logit ("warning: server returned more bytes than requested"); - fail = 1; - } - nbytes = buffer[1]; - if (nbytes > sizeof buffer) - { - logit ("buffer too short to receive data"); - exit (1); - } - - for (nleft=nbytes, nread=0; nleft > 0; ) - { - do - n = read (fd, buffer+nread, nleft); - while (n < 0 && errno == EINTR); - if (n < 0) - { - logit ("read error: %s", strerror (errno)); - exit (1); - } - nleft -= n; - nread += n; - } - - if (do_hex) - { - for (n=0; n < nbytes; n++) - { - if (!n) - ; - else if (!(n % 16)) - putchar ('\n'); - else - putchar (' '); - printf ("%02X", buffer[n]); - } - if (nbytes) - putchar ('\n'); - } - else - { - if (fwrite (buffer, nbytes, 1, stdout) != 1) - { - logit ("error writing to stdout: %s", strerror (errno)); - fail = 1; - } - } - } - } - while (!fail && req_nbytes); - - close (fd); - free (srvr_addr); - return fail? 1 : 0; -} diff --git a/grub-core/lib/libgcrypt/src/global.c b/grub-core/lib/libgcrypt/src/global.c deleted file mode 100644 index 9b9d531ad..000000000 --- a/grub-core/lib/libgcrypt/src/global.c +++ /dev/null @@ -1,1123 +0,0 @@ -/* global.c - global control functions - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 - * 2004, 2005, 2006, 2008, 2011 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 . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_SYSLOG -# include -#endif /*HAVE_SYSLOG*/ - -#include "g10lib.h" -#include "cipher.h" -#include "stdmem.h" /* our own memory allocator */ -#include "secmem.h" /* our own secmem allocator */ -#include "ath.h" - - - -/**************** - * flag bits: 0 : general cipher debug - * 1 : general MPI debug - */ -static unsigned int debug_flags; - -/* gcry_control (GCRYCTL_SET_FIPS_MODE), sets this flag so that the - initialization code switched fips mode on. */ -static int force_fips_mode; - -/* Controlled by global_init(). */ -static int any_init_done; - -/* A table to map hardware features to a string. */ -static struct -{ - unsigned int flag; - const char *desc; -} hwflist[] = - { - { HWF_PADLOCK_RNG, "padlock-rng" }, - { HWF_PADLOCK_AES, "padlock-aes" }, - { HWF_PADLOCK_SHA, "padlock-sha" }, - { HWF_PADLOCK_MMUL,"padlock-mmul"}, - { HWF_INTEL_AESNI, "intel-aesni" }, - { 0, NULL} - }; - -/* A bit vector with the hardware features which shall not be used. - This variable must be set prior to any initialization. */ -static unsigned int disabled_hw_features; - - -/* Memory management. */ - -static gcry_handler_alloc_t alloc_func; -static gcry_handler_alloc_t alloc_secure_func; -static gcry_handler_secure_check_t is_secure_func; -static gcry_handler_realloc_t realloc_func; -static gcry_handler_free_t free_func; -static gcry_handler_no_mem_t outofcore_handler; -static void *outofcore_handler_value; -static int no_secure_memory; - - - - - -/* This is our handmade constructor. It gets called by any function - likely to be called at startup. The suggested way for an - application to make sure that this has been called is by using - gcry_check_version. */ -static void -global_init (void) -{ - gcry_error_t err = 0; - - if (any_init_done) - return; - any_init_done = 1; - - /* Initialize our portable thread/mutex wrapper. */ - err = ath_init (); - if (err) - goto fail; - - /* See whether the system is in FIPS mode. This needs to come as - early as possible put after the ATH has been initialized. */ - _gcry_initialize_fips_mode (force_fips_mode); - - /* Before we do any other initialization we need to test available - hardware features. */ - _gcry_detect_hw_features (disabled_hw_features); - - err = _gcry_cipher_init (); - if (err) - goto fail; - err = _gcry_md_init (); - if (err) - goto fail; - err = _gcry_pk_init (); - if (err) - goto fail; -#if 0 - /* Hmmm, as of now ac_init does nothing. */ - if ( !fips_mode () ) - { - err = _gcry_ac_init (); - if (err) - goto fail; - } -#endif - - return; - - fail: - BUG (); -} - - -/* This function is called by the macro fips_is_operational and makes - sure that the minimal initialization has been done. This is far - from a perfect solution and hides problems with an improper - initialization but at least in single-threaded mode it should work - reliable. - - The reason we need this is that a lot of applications don't use - Libgcrypt properly by not running any initialization code at all. - They just call a Libgcrypt function and that is all what they want. - Now with the FIPS mode, that has the side effect of entering FIPS - mode (for security reasons, FIPS mode is the default if no - initialization has been done) and bailing out immediately because - the FSM is in the wrong state. If we always run the init code, - Libgcrypt can test for FIPS mode and at least if not in FIPS mode, - it will behave as before. Note that this on-the-fly initialization - is only done for the cryptographic functions subject to FIPS mode - and thus not all API calls will do such an initialization. */ -int -_gcry_global_is_operational (void) -{ - if (!any_init_done) - { -#ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "missing initialization - please fix the application"); -#endif /*HAVE_SYSLOG*/ - global_init (); - } - return _gcry_fips_is_operational (); -} - - - - -/* Version number parsing. */ - -/* This function parses the first portion of the version number S and - stores it in *NUMBER. On success, this function returns a pointer - into S starting with the first character, which is not part of the - initial number portion; on failure, NULL is returned. */ -static const char* -parse_version_number( const char *s, int *number ) -{ - int val = 0; - - if( *s == '0' && isdigit(s[1]) ) - return NULL; /* leading zeros are not allowed */ - for ( ; isdigit(*s); s++ ) { - val *= 10; - val += *s - '0'; - } - *number = val; - return val < 0? NULL : s; -} - -/* This function breaks up the complete string-representation of the - version number S, which is of the following struture: ... The major, - minor and micro number components will be stored in *MAJOR, *MINOR - and *MICRO. - - On success, the last component, the patch level, will be returned; - in failure, NULL will be returned. */ - -static const char * -parse_version_string( const char *s, int *major, int *minor, int *micro ) -{ - s = parse_version_number( s, major ); - if( !s || *s != '.' ) - return NULL; - s++; - s = parse_version_number( s, minor ); - if( !s || *s != '.' ) - return NULL; - s++; - s = parse_version_number( s, micro ); - if( !s ) - return NULL; - return s; /* patchlevel */ -} - -/* If REQ_VERSION is non-NULL, check that the version of the library - is at minimum the requested one. Returns the string representation - of the library version if the condition is satisfied; return NULL - if the requested version is newer than that of the library. - - If a NULL is passed to this function, no check is done, but the - string representation of the library is simply returned. */ -const char * -gcry_check_version( const char *req_version ) -{ - const char *ver = VERSION; - int my_major, my_minor, my_micro; - int rq_major, rq_minor, rq_micro; - const char *my_plvl; - - if (req_version && req_version[0] == 1 && req_version[1] == 1) - return _gcry_compat_identification (); - - /* Initialize library. */ - global_init (); - - if ( !req_version ) - /* Caller wants our version number. */ - return ver; - - /* Parse own version number. */ - my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro ); - if ( !my_plvl ) - /* very strange our own version is bogus. Shouldn't we use - assert() here and bail out in case this happens? -mo. */ - return NULL; - - /* Parse requested version number. */ - if (!parse_version_string (req_version, &rq_major, &rq_minor, &rq_micro)) - return NULL; /* req version string is invalid, this can happen. */ - - /* Compare version numbers. */ - if ( my_major > rq_major - || (my_major == rq_major && my_minor > rq_minor) - || (my_major == rq_major && my_minor == rq_minor && my_micro > rq_micro) - || (my_major == rq_major && my_minor == rq_minor - && my_micro == rq_micro)) - { - return ver; - } - - return NULL; -} - - -static void -print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp) -{ - unsigned int hwf; - int i; - - fnc (fp, "version:%s:\n", VERSION); - fnc (fp, "ciphers:%s:\n", LIBGCRYPT_CIPHERS); - fnc (fp, "pubkeys:%s:\n", LIBGCRYPT_PUBKEY_CIPHERS); - fnc (fp, "digests:%s:\n", LIBGCRYPT_DIGESTS); - fnc (fp, "rnd-mod:" -#if USE_RNDEGD - "egd:" -#endif -#if USE_RNDLINUX - "linux:" -#endif -#if USE_RNDUNIX - "unix:" -#endif -#if USE_RNDW32 - "w32:" -#endif - "\n"); - fnc (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ()); - hwf = _gcry_get_hw_features (); - fnc (fp, "hwflist:"); - for (i=0; hwflist[i].desc; i++) - if ( (hwf & hwflist[i].flag) ) - fnc (fp, "%s:", hwflist[i].desc); - fnc (fp, "\n"); - /* We use y/n instead of 1/0 for the simple reason that Emacsen's - compile error parser would accidently flag that line when printed - during "make check" as an error. */ - fnc (fp, "fips-mode:%c:%c:\n", - fips_mode ()? 'y':'n', - _gcry_enforced_fips_mode ()? 'y':'n' ); -} - - - - -/* Command dispatcher function, acting as general control - function. */ -gcry_error_t -_gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) -{ - static int init_finished = 0; - gcry_err_code_t err = 0; - - switch (cmd) - { - case GCRYCTL_ENABLE_M_GUARD: - _gcry_private_enable_m_guard (); - break; - - case GCRYCTL_ENABLE_QUICK_RANDOM: - _gcry_enable_quick_random_gen (); - break; - - case GCRYCTL_FAKED_RANDOM_P: - /* Return an error if the RNG is faked one (e.g. enabled by - ENABLE_QUICK_RANDOM. */ - if (_gcry_random_is_faked ()) - err = GPG_ERR_GENERAL; /* Use as TRUE value. */ - break; - - case GCRYCTL_DUMP_RANDOM_STATS: - _gcry_random_dump_stats (); - break; - - case GCRYCTL_DUMP_MEMORY_STATS: - /*m_print_stats("[fixme: prefix]");*/ - break; - - case GCRYCTL_DUMP_SECMEM_STATS: - _gcry_secmem_dump_stats (); - break; - - case GCRYCTL_DROP_PRIVS: - global_init (); - _gcry_secmem_init (0); - break; - - case GCRYCTL_DISABLE_SECMEM: - global_init (); - no_secure_memory = 1; - break; - - case GCRYCTL_INIT_SECMEM: - global_init (); - _gcry_secmem_init (va_arg (arg_ptr, unsigned int)); - if ((_gcry_secmem_get_flags () & GCRY_SECMEM_FLAG_NOT_LOCKED)) - err = GPG_ERR_GENERAL; - break; - - case GCRYCTL_TERM_SECMEM: - global_init (); - _gcry_secmem_term (); - break; - - case GCRYCTL_DISABLE_SECMEM_WARN: - _gcry_secmem_set_flags ((_gcry_secmem_get_flags () - | GCRY_SECMEM_FLAG_NO_WARNING)); - break; - - case GCRYCTL_SUSPEND_SECMEM_WARN: - _gcry_secmem_set_flags ((_gcry_secmem_get_flags () - | GCRY_SECMEM_FLAG_SUSPEND_WARNING)); - break; - - case GCRYCTL_RESUME_SECMEM_WARN: - _gcry_secmem_set_flags ((_gcry_secmem_get_flags () - & ~GCRY_SECMEM_FLAG_SUSPEND_WARNING)); - break; - - case GCRYCTL_USE_SECURE_RNDPOOL: - global_init (); - _gcry_secure_random_alloc (); /* Put random number into secure memory. */ - break; - - case GCRYCTL_SET_RANDOM_SEED_FILE: - _gcry_set_random_seed_file (va_arg (arg_ptr, const char *)); - break; - - case GCRYCTL_UPDATE_RANDOM_SEED_FILE: - if ( fips_is_operational () ) - _gcry_update_random_seed_file (); - break; - - case GCRYCTL_SET_VERBOSITY: - _gcry_set_log_verbosity (va_arg (arg_ptr, int)); - break; - - case GCRYCTL_SET_DEBUG_FLAGS: - debug_flags |= va_arg (arg_ptr, unsigned int); - break; - - case GCRYCTL_CLEAR_DEBUG_FLAGS: - debug_flags &= ~va_arg (arg_ptr, unsigned int); - break; - - case GCRYCTL_DISABLE_INTERNAL_LOCKING: - /* Not used anymore. */ - global_init (); - break; - - case GCRYCTL_ANY_INITIALIZATION_P: - if (any_init_done) - err = GPG_ERR_GENERAL; - break; - - case GCRYCTL_INITIALIZATION_FINISHED_P: - if (init_finished) - err = GPG_ERR_GENERAL; /* Yes. */ - break; - - case GCRYCTL_INITIALIZATION_FINISHED: - /* This is a hook which should be used by an application after - all initialization has been done and right before any threads - are started. It is not really needed but the only way to be - really sure that all initialization for thread-safety has - been done. */ - if (! init_finished) - { - global_init (); - /* Do only a basic random initialization, i.e. init the - mutexes. */ - _gcry_random_initialize (0); - init_finished = 1; - /* Force us into operational state if in FIPS mode. */ - (void)fips_is_operational (); - } - break; - - case GCRYCTL_SET_THREAD_CBS: - err = ath_install (va_arg (arg_ptr, void *), any_init_done); - if (! err) - global_init (); - break; - - case GCRYCTL_FAST_POLL: - /* We need to do make sure that the random pool is really - initialized so that the poll function is not a NOP. */ - _gcry_random_initialize (1); - - if ( fips_is_operational () ) - _gcry_fast_random_poll (); - break; - - case GCRYCTL_SET_RNDEGD_SOCKET: -#if USE_RNDEGD - err = _gcry_rndegd_set_socket_name (va_arg (arg_ptr, const char *)); -#else - err = gpg_error (GPG_ERR_NOT_SUPPORTED); -#endif - break; - - case GCRYCTL_SET_RANDOM_DAEMON_SOCKET: - _gcry_set_random_daemon_socket (va_arg (arg_ptr, const char *)); - break; - - case GCRYCTL_USE_RANDOM_DAEMON: - /* We need to do make sure that the random pool is really - initialized so that the poll function is not a NOP. */ - _gcry_random_initialize (1); - _gcry_use_random_daemon (!! va_arg (arg_ptr, int)); - break; - - /* This command dumps information pertaining to the - configuration of libgcrypt to the given stream. It may be - used before the initialization has been finished but not - before a gcry_version_check. */ - case GCRYCTL_PRINT_CONFIG: - { - FILE *fp = va_arg (arg_ptr, FILE *); - print_config (fp?fprintf:_gcry_log_info_with_dummy_fp, fp); - } - break; - - case GCRYCTL_OPERATIONAL_P: - /* Returns true if the library is in an operational state. This - is always true for non-fips mode. */ - if (_gcry_fips_test_operational ()) - err = GPG_ERR_GENERAL; /* Used as TRUE value */ - break; - - case GCRYCTL_FIPS_MODE_P: - if (fips_mode () - && !_gcry_is_fips_mode_inactive () - && !no_secure_memory) - err = GPG_ERR_GENERAL; /* Used as TRUE value */ - break; - - case GCRYCTL_FORCE_FIPS_MODE: - /* Performing this command puts the library into fips mode. If - the library has already been initialized into fips mode, a - selftest is triggered. It is not possible to put the libraty - into fips mode after having passed the initialization. */ - if (!any_init_done) - { - /* Not yet intialized at all. Set a flag so that we are put - into fips mode during initialization. */ - force_fips_mode = 1; - } - else - { - /* Already initialized. If we are already operational we - run a selftest. If not we use the is_operational call to - force us into operational state if possible. */ - if (_gcry_fips_test_error_or_operational ()) - _gcry_fips_run_selftests (1); - if (_gcry_fips_is_operational ()) - err = GPG_ERR_GENERAL; /* Used as TRUE value */ - } - break; - - case GCRYCTL_SELFTEST: - /* Run a selftest. This works in fips mode as well as in - standard mode. In contrast to the power-up tests, we use an - extended version of the selftests. Returns 0 on success or an - error code. */ - global_init (); - err = _gcry_fips_run_selftests (1); - break; - -#if _GCRY_GCC_VERSION >= 40600 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wswitch" -#endif - case 58: /* Init external random test. */ - { - void **rctx = va_arg (arg_ptr, void **); - unsigned int flags = va_arg (arg_ptr, unsigned int); - const void *key = va_arg (arg_ptr, const void *); - size_t keylen = va_arg (arg_ptr, size_t); - const void *seed = va_arg (arg_ptr, const void *); - size_t seedlen = va_arg (arg_ptr, size_t); - const void *dt = va_arg (arg_ptr, const void *); - size_t dtlen = va_arg (arg_ptr, size_t); - if (!fips_is_operational ()) - err = fips_not_operational (); - else - err = _gcry_random_init_external_test (rctx, flags, key, keylen, - seed, seedlen, dt, dtlen); - } - break; - case 59: /* Run external random test. */ - { - void *ctx = va_arg (arg_ptr, void *); - void *buffer = va_arg (arg_ptr, void *); - size_t buflen = va_arg (arg_ptr, size_t); - if (!fips_is_operational ()) - err = fips_not_operational (); - else - err = _gcry_random_run_external_test (ctx, buffer, buflen); - } - break; - case 60: /* Deinit external random test. */ - { - void *ctx = va_arg (arg_ptr, void *); - _gcry_random_deinit_external_test (ctx); - } - break; - case 61: /* RFU */ - break; - case 62: /* RFU */ - break; -#if _GCRY_GCC_VERSION >= 40600 -# pragma GCC diagnostic pop -#endif - - case GCRYCTL_DISABLE_HWF: - { - const char *name = va_arg (arg_ptr, const char *); - int i; - - for (i=0; hwflist[i].desc; i++) - if (!strcmp (hwflist[i].desc, name)) - { - disabled_hw_features |= hwflist[i].flag; - break; - } - if (!hwflist[i].desc) - err = GPG_ERR_INV_NAME; - } - break; - - case GCRYCTL_SET_ENFORCED_FIPS_FLAG: - if (!any_init_done) - { - /* Not yet intialized at all. Set the enforced fips mode flag */ - _gcry_set_enforced_fips_mode (); - } - else - err = GPG_ERR_GENERAL; - break; - - default: - err = GPG_ERR_INV_OP; - } - - return gcry_error (err); -} - - -/* Command dispatcher function, acting as general control - function. */ -gcry_error_t -gcry_control (enum gcry_ctl_cmds cmd, ...) -{ - gcry_error_t err; - va_list arg_ptr; - - va_start (arg_ptr, cmd); - err = _gcry_vcontrol (cmd, arg_ptr); - va_end(arg_ptr); - return err; -} - - - -/* Return a pointer to a string containing a description of the error - code in the error value ERR. */ -const char * -gcry_strerror (gcry_error_t err) -{ - return gpg_strerror (err); -} - -/* Return a pointer to a string containing a description of the error - source in the error value ERR. */ -const char * -gcry_strsource (gcry_error_t err) -{ - return gpg_strsource (err); -} - -/* Retrieve the error code for the system error ERR. This returns - GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report - this). */ -gcry_err_code_t -gcry_err_code_from_errno (int err) -{ - return gpg_err_code_from_errno (err); -} - - -/* Retrieve the system error for the error code CODE. This returns 0 - if CODE is not a system error code. */ -int -gcry_err_code_to_errno (gcry_err_code_t code) -{ - return gpg_err_code_from_errno (code); -} - - -/* Return an error value with the error source SOURCE and the system - error ERR. */ -gcry_error_t -gcry_err_make_from_errno (gpg_err_source_t source, int err) -{ - return gpg_err_make_from_errno (source, err); -} - - -/* Return an error value with the system error ERR. */ -gcry_err_code_t -gcry_error_from_errno (int err) -{ - return gcry_error (gpg_err_code_from_errno (err)); -} - - -/* Set custom allocation handlers. This is in general not useful - * because the libgcrypt allocation functions are guaranteed to - * provide proper allocation handlers which zeroize memory if needed. - * NOTE: All 5 functions should be set. */ -void -gcry_set_allocation_handler (gcry_handler_alloc_t new_alloc_func, - gcry_handler_alloc_t new_alloc_secure_func, - gcry_handler_secure_check_t new_is_secure_func, - gcry_handler_realloc_t new_realloc_func, - gcry_handler_free_t new_free_func) -{ - global_init (); - - if (fips_mode ()) - { - /* We do not want to enforce the fips mode, but merely set a - flag so that the application may check whether it is still in - fips mode. */ - _gcry_inactivate_fips_mode ("custom allocation handler"); - } - - alloc_func = new_alloc_func; - alloc_secure_func = new_alloc_secure_func; - is_secure_func = new_is_secure_func; - realloc_func = new_realloc_func; - free_func = new_free_func; -} - - - -/**************** - * Set an optional handler which is called in case the xmalloc functions - * ran out of memory. This handler may do one of these things: - * o free some memory and return true, so that the xmalloc function - * tries again. - * o Do whatever it like and return false, so that the xmalloc functions - * use the default fatal error handler. - * o Terminate the program and don't return. - * - * The handler function is called with 3 arguments: The opaque value set with - * this function, the requested memory size, and a flag with these bits - * currently defined: - * bit 0 set = secure memory has been requested. - */ -void -gcry_set_outofcore_handler( int (*f)( void*, size_t, unsigned int ), - void *value ) -{ - global_init (); - - if (fips_mode () ) - { - log_info ("out of core handler ignored in FIPS mode\n"); - return; - } - - outofcore_handler = f; - outofcore_handler_value = value; -} - -/* Return the no_secure_memory flag. */ -static int -get_no_secure_memory (void) -{ - if (!no_secure_memory) - return 0; - if (_gcry_enforced_fips_mode ()) - { - no_secure_memory = 0; - return 0; - } - return no_secure_memory; -} - - -static gcry_err_code_t -do_malloc (size_t n, unsigned int flags, void **mem) -{ - gcry_err_code_t err = 0; - void *m; - - if ((flags & GCRY_ALLOC_FLAG_SECURE) && !get_no_secure_memory ()) - { - if (alloc_secure_func) - m = (*alloc_secure_func) (n); - else - m = _gcry_private_malloc_secure (n); - } - else - { - if (alloc_func) - m = (*alloc_func) (n); - else - m = _gcry_private_malloc (n); - } - - if (!m) - { - /* Make sure that ERRNO has been set in case a user supplied - memory handler didn't it correctly. */ - if (!errno) - gpg_err_set_errno (ENOMEM); - err = gpg_err_code_from_errno (errno); - } - else - *mem = m; - - return err; -} - -void * -gcry_malloc (size_t n) -{ - void *mem = NULL; - - do_malloc (n, 0, &mem); - - return mem; -} - -void * -gcry_malloc_secure (size_t n) -{ - void *mem = NULL; - - do_malloc (n, GCRY_ALLOC_FLAG_SECURE, &mem); - - return mem; -} - -int -gcry_is_secure (const void *a) -{ - if (get_no_secure_memory ()) - return 0; - if (is_secure_func) - return is_secure_func (a) ; - return _gcry_private_is_secure (a); -} - -void -_gcry_check_heap( const void *a ) -{ - (void)a; - - /* FIXME: implement this*/ -#if 0 - if( some_handler ) - some_handler(a) - else - _gcry_private_check_heap(a) -#endif -} - -void * -gcry_realloc (void *a, size_t n) -{ - void *p; - - /* To avoid problems with non-standard realloc implementations and - our own secmem_realloc, we divert to malloc and free here. */ - if (!a) - return gcry_malloc (n); - if (!n) - { - gcry_free (a); - return NULL; - } - - if (realloc_func) - p = realloc_func (a, n); - else - p = _gcry_private_realloc (a, n); - if (!p && !errno) - gpg_err_set_errno (ENOMEM); - return p; -} - -void -gcry_free (void *p) -{ - int save_errno; - - if (!p) - return; - - /* In case ERRNO is set we better save it so that the free machinery - may not accidently change ERRNO. We restore it only if it was - already set to comply with the usual C semantic for ERRNO. */ - save_errno = errno; - if (free_func) - free_func (p); - else - _gcry_private_free (p); - - if (save_errno) - gpg_err_set_errno (save_errno); -} - -void * -gcry_calloc (size_t n, size_t m) -{ - size_t bytes; - void *p; - - bytes = n * m; /* size_t is unsigned so the behavior on overflow is - defined. */ - if (m && bytes / m != n) - { - gpg_err_set_errno (ENOMEM); - return NULL; - } - - p = gcry_malloc (bytes); - if (p) - memset (p, 0, bytes); - return p; -} - -void * -gcry_calloc_secure (size_t n, size_t m) -{ - size_t bytes; - void *p; - - bytes = n * m; /* size_t is unsigned so the behavior on overflow is - defined. */ - if (m && bytes / m != n) - { - gpg_err_set_errno (ENOMEM); - return NULL; - } - - p = gcry_malloc_secure (bytes); - if (p) - memset (p, 0, bytes); - return p; -} - - -/* Create and return a copy of the null-terminated string STRING. If - it is contained in secure memory, the copy will be contained in - secure memory as well. In an out-of-memory condition, NULL is - returned. */ -char * -gcry_strdup (const char *string) -{ - char *string_cp = NULL; - size_t string_n = 0; - - string_n = strlen (string); - - if (gcry_is_secure (string)) - string_cp = gcry_malloc_secure (string_n + 1); - else - string_cp = gcry_malloc (string_n + 1); - - if (string_cp) - strcpy (string_cp, string); - - return string_cp; -} - - -void * -gcry_xmalloc( size_t n ) -{ - void *p; - - while ( !(p = gcry_malloc( n )) ) - { - if ( fips_mode () - || !outofcore_handler - || !outofcore_handler (outofcore_handler_value, n, 0) ) - { - _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL); - } - } - return p; -} - -void * -gcry_xrealloc( void *a, size_t n ) -{ - void *p; - - while ( !(p = gcry_realloc( a, n )) ) - { - if ( fips_mode () - || !outofcore_handler - || !outofcore_handler (outofcore_handler_value, n, - gcry_is_secure(a)? 3:2 ) ) - { - _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL ); - } - } - return p; -} - -void * -gcry_xmalloc_secure( size_t n ) -{ - void *p; - - while ( !(p = gcry_malloc_secure( n )) ) - { - if ( fips_mode () - || !outofcore_handler - || !outofcore_handler (outofcore_handler_value, n, 1) ) - { - _gcry_fatal_error (gpg_err_code_from_errno (errno), - _("out of core in secure memory")); - } - } - return p; -} - - -void * -gcry_xcalloc( size_t n, size_t m ) -{ - size_t nbytes; - void *p; - - nbytes = n * m; - if (m && nbytes / m != n) - { - gpg_err_set_errno (ENOMEM); - _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL ); - } - - p = gcry_xmalloc ( nbytes ); - memset ( p, 0, nbytes ); - return p; -} - -void * -gcry_xcalloc_secure( size_t n, size_t m ) -{ - size_t nbytes; - void *p; - - nbytes = n * m; - if (m && nbytes / m != n) - { - gpg_err_set_errno (ENOMEM); - _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL ); - } - - p = gcry_xmalloc_secure ( nbytes ); - memset ( p, 0, nbytes ); - return p; -} - -char * -gcry_xstrdup (const char *string) -{ - char *p; - - while ( !(p = gcry_strdup (string)) ) - { - size_t n = strlen (string); - int is_sec = !!gcry_is_secure (string); - - if (fips_mode () - || !outofcore_handler - || !outofcore_handler (outofcore_handler_value, n, is_sec) ) - { - _gcry_fatal_error (gpg_err_code_from_errno (errno), - is_sec? _("out of core in secure memory"):NULL); - } - } - - return p; -} - - -int -_gcry_get_debug_flag (unsigned int mask) -{ - if ( fips_mode () ) - return 0; - return (debug_flags & mask); -} - - - -/* It is often useful to get some feedback of long running operations. - This function may be used to register a handler for this. - The callback function CB is used as: - - void cb (void *opaque, const char *what, int printchar, - int current, int total); - - Where WHAT is a string identifying the the type of the progress - output, PRINTCHAR the character usually printed, CURRENT the amount - of progress currently done and TOTAL the expected amount of - progress. A value of 0 for TOTAL indicates that there is no - estimation available. - - Defined values for WHAT: - - "need_entropy" X 0 number-of-bytes-required - When running low on entropy - "primegen" '\n' 0 0 - Prime generated - '!' - Need to refresh the prime pool - '<','>' - Number of bits adjusted - '^' - Looking for a generator - '.' - Fermat tests on 10 candidates failed - ':' - Restart with a new random value - '+' - Rabin Miller test passed - "pk_elg" '+','-','.','\n' 0 0 - Only used in debugging mode. - "pk_dsa" - Only used in debugging mode. -*/ -void -gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int), - void *cb_data) -{ -#if USE_DSA - _gcry_register_pk_dsa_progress (cb, cb_data); -#endif -#if USE_ELGAMAL - _gcry_register_pk_elg_progress (cb, cb_data); -#endif - _gcry_register_primegen_progress (cb, cb_data); - _gcry_register_random_progress (cb, cb_data); -} diff --git a/grub-core/lib/libgcrypt/src/hmac256.c b/grub-core/lib/libgcrypt/src/hmac256.c deleted file mode 100644 index f3bc09244..000000000 --- a/grub-core/lib/libgcrypt/src/hmac256.c +++ /dev/null @@ -1,793 +0,0 @@ -/* hmac256.c - Standalone HMAC implementation - * 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 . - */ - -/* - This is a standalone HMAC-SHA-256 implementation based on the code - from ../cipher/sha256.c. It is a second implementation to allow - comparing against the standard implementations and to be used for - internal consistency checks. It should not be used for sensitive - data because no mechanisms to clear the stack etc are used. - - This module may be used standalone and requires only a few - standard definitions to be provided in a config.h file. - - Types: - - u32 - unsigned 32 bit type. - - Constants: - - WORDS_BIGENDIAN Defined to 1 on big endian systems. - inline If defined, it should yield the keyword used - to inline a function. - HAVE_U32_TYPEDEF Defined if the u32 type is available. - SIZEOF_UNSIGNED_INT Defined to the size in bytes of an unsigned int. - SIZEOF_UNSIGNED_LONG Defined to the size in bytes of an unsigned long. - - STANDALONE Compile a test driver similar to the - sha1sum tool. This driver uses a self-test - identically to the one used by Libcgrypt - for testing this included module. - */ - -#include -#include -#include -#include -#include -#include -#if defined(__WIN32) && defined(STANDALONE) -# include /* We need setmode(). */ -#endif - -/* For a native WindowsCE binary we need to include gpg-error.h to - provide a replacement for strerror. In other cases we need a - replacement macro for gpg_err_set_errno. */ -#ifdef __MINGW32CE__ -# include -#else -# define gpg_err_set_errno(a) (errno = (a)) -#endif - -#include "hmac256.h" - - - -#ifndef HAVE_U32_TYPEDEF -# undef u32 /* Undef a possible macro with that name. */ -# if SIZEOF_UNSIGNED_INT == 4 - typedef unsigned int u32; -# elif SIZEOF_UNSIGNED_LONG == 4 - typedef unsigned long u32; -# else -# error no typedef for u32 -# endif -# define HAVE_U32_TYPEDEF -#endif - - - - -/* The context used by this module. */ -struct hmac256_context -{ - u32 h0, h1, h2, h3, h4, h5, h6, h7; - u32 nblocks; - int count; - int finalized:1; - int use_hmac:1; - unsigned char buf[64]; - unsigned char opad[64]; -}; - - -/* Rotate a 32 bit word. */ -#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 - -#define my_wipememory2(_ptr,_set,_len) do { \ - volatile char *_vptr=(volatile char *)(_ptr); \ - size_t _vlen=(_len); \ - while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \ - } while(0) -#define my_wipememory(_ptr,_len) my_wipememory2(_ptr,0,_len) - - - - -/* - The SHA-256 core: Transform the message X which consists of 16 - 32-bit-words. See FIPS 180-2 for details. - */ -static void -transform (hmac256_context_t hd, const void *data_arg) -{ - const unsigned char *data = data_arg; - -#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 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 /*!WORDS_BIGENDIAN*/ - { - unsigned char *p2; - - for (i=0, p2=(unsigned char*)x; i < 16; i++, p2 += 4 ) - { - p2[3] = *data++; - p2[2] = *data++; - p2[1] = *data++; - p2[0] = *data++; - } - } -#endif /*!WORDS_BIGENDIAN*/ - - 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 - - -/* Finalize the current SHA256 calculation. */ -static void -finalize (hmac256_context_t hd) -{ - u32 t, msb, lsb; - unsigned char *p; - - if (hd->finalized) - return; /* Silently ignore a finalized context. */ - - _gcry_hmac256_update (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; - _gcry_hmac256_update (hd, NULL, 0); /* Flush. */; - memset (hd->buf, 0, 56 ); /* Zero out next next block. */ - } - /* 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); - - /* Store the digest into hd->buf. */ - p = hd->buf; -#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) - X(0); - X(1); - X(2); - X(3); - X(4); - X(5); - X(6); - X(7); -#undef X - hd->finalized = 1; -} - - - -/* Create a new context. On error NULL is returned and errno is set - appropriately. If KEY is given the function computes HMAC using - this key; with KEY given as NULL, a plain SHA-256 digest is - computed. */ -hmac256_context_t -_gcry_hmac256_new (const void *key, size_t keylen) -{ - hmac256_context_t hd; - - hd = malloc (sizeof *hd); - if (!hd) - return NULL; - - 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; - hd->finalized = 0; - hd->use_hmac = 0; - - if (key) - { - int i; - unsigned char ipad[64]; - - memset (ipad, 0, 64); - memset (hd->opad, 0, 64); - if (keylen <= 64) - { - memcpy (ipad, key, keylen); - memcpy (hd->opad, key, keylen); - } - else - { - hmac256_context_t tmphd; - - tmphd = _gcry_hmac256_new (NULL, 0); - if (!tmphd) - { - free (hd); - return NULL; - } - _gcry_hmac256_update (tmphd, key, keylen); - finalize (tmphd); - memcpy (ipad, tmphd->buf, 32); - memcpy (hd->opad, tmphd->buf, 32); - _gcry_hmac256_release (tmphd); - } - for (i=0; i < 64; i++) - { - ipad[i] ^= 0x36; - hd->opad[i] ^= 0x5c; - } - hd->use_hmac = 1; - _gcry_hmac256_update (hd, ipad, 64); - my_wipememory (ipad, 64); - } - - return hd; -} - -/* Release a context created by _gcry_hmac256_new. CTX may be NULL - in which case the function does nothing. */ -void -_gcry_hmac256_release (hmac256_context_t ctx) -{ - if (ctx) - { - /* Note: We need to take care not to modify errno. */ - if (ctx->use_hmac) - my_wipememory (ctx->opad, 64); - free (ctx); - } -} - - -/* Update the message digest with the contents of BUFFER containing - LENGTH bytes. */ -void -_gcry_hmac256_update (hmac256_context_t hd, - const void *buffer, size_t length) -{ - const unsigned char *inbuf = buffer; - - if (hd->finalized) - return; /* Silently ignore a finalized context. */ - - if (hd->count == 64) - { - /* Flush the buffer. */ - transform (hd, hd->buf); - hd->count = 0; - hd->nblocks++; - } - if (!inbuf) - return; /* Only flushing was requested. */ - if (hd->count) - { - for (; length && hd->count < 64; length--) - hd->buf[hd->count++] = *inbuf++; - _gcry_hmac256_update (hd, NULL, 0); /* Flush. */ - if (!length) - return; - } - - - while (length >= 64) - { - transform (hd, inbuf); - hd->count = 0; - hd->nblocks++; - length -= 64; - inbuf += 64; - } - for (; length && hd->count < 64; length--) - hd->buf[hd->count++] = *inbuf++; -} - - -/* Finalize an operation and return the digest. If R_DLEN is not NULL - the length of the digest will be stored at that address. The - returned value is valid as long as the context exists. On error - NULL is returned. */ -const void * -_gcry_hmac256_finalize (hmac256_context_t hd, size_t *r_dlen) -{ - finalize (hd); - if (hd->use_hmac) - { - hmac256_context_t tmphd; - - tmphd = _gcry_hmac256_new (NULL, 0); - if (!tmphd) - { - free (hd); - return NULL; - } - _gcry_hmac256_update (tmphd, hd->opad, 64); - _gcry_hmac256_update (tmphd, hd->buf, 32); - finalize (tmphd); - memcpy (hd->buf, tmphd->buf, 32); - _gcry_hmac256_release (tmphd); - } - if (r_dlen) - *r_dlen = 32; - return (void*)hd->buf; -} - - -/* Convenience function to compute the HMAC-SHA256 of one file. The - user needs to provide a buffer RESULT of at least 32 bytes, he - needs to put the size of the buffer into RESULTSIZE and the - FILENAME. KEY and KEYLEN are as described for _gcry_hmac256_new. - On success the function returns the valid length of the result - buffer (which will be 32) or -1 on error. On error ERRNO is set - appropriate. */ -int -_gcry_hmac256_file (void *result, size_t resultsize, const char *filename, - const void *key, size_t keylen) -{ - FILE *fp; - hmac256_context_t hd; - size_t buffer_size, nread, digestlen; - char *buffer; - const unsigned char *digest; - - fp = fopen (filename, "rb"); - if (!fp) - return -1; - - hd = _gcry_hmac256_new (key, keylen); - if (!hd) - { - fclose (fp); - return -1; - } - - buffer_size = 32768; - buffer = malloc (buffer_size); - if (!buffer) - { - fclose (fp); - _gcry_hmac256_release (hd); - return -1; - } - - while ( (nread = fread (buffer, 1, buffer_size, fp))) - _gcry_hmac256_update (hd, buffer, nread); - - free (buffer); - - if (ferror (fp)) - { - fclose (fp); - _gcry_hmac256_release (hd); - return -1; - } - - fclose (fp); - - digest = _gcry_hmac256_finalize (hd, &digestlen); - if (!digest) - { - _gcry_hmac256_release (hd); - return -1; - } - - if (digestlen > resultsize) - { - _gcry_hmac256_release (hd); - gpg_err_set_errno (EINVAL); - return -1; - } - memcpy (result, digest, digestlen); - _gcry_hmac256_release (hd); - - return digestlen; -} - - - -#ifdef STANDALONE -static int -selftest (void) -{ - static struct - { - const char * const desc; - const char * const data; - const char * const key; - const unsigned 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 } - }; - int tvidx; - - for (tvidx=0; tv[tvidx].desc; tvidx++) - { - hmac256_context_t hmachd; - const unsigned char *digest; - size_t dlen; - - hmachd = _gcry_hmac256_new (tv[tvidx].key, strlen (tv[tvidx].key)); - if (!hmachd) - return -1; - _gcry_hmac256_update (hmachd, tv[tvidx].data, strlen (tv[tvidx].data)); - digest = _gcry_hmac256_finalize (hmachd, &dlen); - if (!digest) - { - _gcry_hmac256_release (hmachd); - return -1; - } - if (dlen != sizeof (tv[tvidx].expect) - || memcmp (digest, tv[tvidx].expect, sizeof (tv[tvidx].expect))) - { - _gcry_hmac256_release (hmachd); - return -1; - } - _gcry_hmac256_release (hmachd); - } - - return 0; /* Succeeded. */ -} - - -int -main (int argc, char **argv) -{ - const char *pgm; - int last_argc = -1; - const char *key; - size_t keylen; - FILE *fp; - hmac256_context_t hd; - const unsigned char *digest; - char buffer[4096]; - size_t n, dlen, idx; - int use_stdin = 0; - int use_binary = 0; - - assert (sizeof (u32) == 4); -#ifdef __WIN32 - setmode (fileno (stdin), O_BINARY); -#endif - - if (argc) - { - pgm = strrchr (*argv, '/'); - if (pgm) - pgm++; - else - pgm = *argv; - argc--; argv++; - } - else - pgm = "?"; - - while (argc && last_argc != argc ) - { - last_argc = argc; - if (!strcmp (*argv, "--")) - { - argc--; argv++; - break; - } - else if (!strcmp (*argv, "--version")) - { - fputs ("hmac256 (Libgcrypt) " VERSION "\n" - "Copyright (C) 2008 Free Software Foundation, Inc.\n" - "License LGPLv2.1+: GNU LGPL version 2.1 or later " - "\n" - "This is free software: you are free to change and " - "redistribute it.\n" - "There is NO WARRANTY, to the extent permitted by law.\n", - stdout); - exit (0); - } - else if (!strcmp (*argv, "--binary")) - { - argc--; argv++; - use_binary = 1; - } - } - - if (argc < 1) - { - fprintf (stderr, "usage: %s [--binary] key [filename]\n", pgm); - exit (1); - } - -#ifdef __WIN32 - if (use_binary) - setmode (fileno (stdout), O_BINARY); -#endif - - key = *argv; - argc--, argv++; - keylen = strlen (key); - use_stdin = !argc; - - if (selftest ()) - { - fprintf (stderr, "%s: fatal error: self-test failed\n", pgm); - exit (2); - } - - for (; argc || use_stdin; argv++, argc--) - { - const char *fname = use_stdin? "-" : *argv; - fp = use_stdin? stdin : fopen (fname, "rb"); - if (!fp) - { - fprintf (stderr, "%s: can't open `%s': %s\n", - pgm, fname, strerror (errno)); - exit (1); - } - hd = _gcry_hmac256_new (key, keylen); - if (!hd) - { - fprintf (stderr, "%s: can't allocate context: %s\n", - pgm, strerror (errno)); - exit (1); - } - while ( (n = fread (buffer, 1, sizeof buffer, fp))) - _gcry_hmac256_update (hd, buffer, n); - if (ferror (fp)) - { - fprintf (stderr, "%s: error reading `%s': %s\n", - pgm, fname, strerror (errno)); - exit (1); - } - if (!use_stdin) - fclose (fp); - - digest = _gcry_hmac256_finalize (hd, &dlen); - if (!digest) - { - fprintf (stderr, "%s: error computing HMAC: %s\n", - pgm, strerror (errno)); - exit (1); - } - if (use_binary) - { - if (fwrite (digest, dlen, 1, stdout) != 1) - { - fprintf (stderr, "%s: error writing output: %s\n", - pgm, strerror (errno)); - exit (1); - } - } - else - { - for (idx=0; idx < dlen; idx++) - printf ("%02x", digest[idx]); - _gcry_hmac256_release (hd); - if (use_stdin) - { - putchar ('\n'); - break; - } - printf (" %s\n", fname); - } - } - - return 0; -} -#endif /*STANDALONE*/ - - -/* -Local Variables: -compile-command: "cc -Wall -g -I.. -DSTANDALONE -o hmac256 hmac256.c" -End: -*/ diff --git a/grub-core/lib/libgcrypt/src/hmac256.h b/grub-core/lib/libgcrypt/src/hmac256.h deleted file mode 100644 index df28e7272..000000000 --- a/grub-core/lib/libgcrypt/src/hmac256.h +++ /dev/null @@ -1,36 +0,0 @@ -/* hmac256.h - Declarations for _gcry_hmac256 - * 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 . - */ - -#ifndef HMAC256_H -#define HMAC256_H - - -struct hmac256_context; -typedef struct hmac256_context *hmac256_context_t; - -hmac256_context_t _gcry_hmac256_new (const void *key, size_t keylen); -void _gcry_hmac256_update (hmac256_context_t hd, const void *buf, size_t len); -const void *_gcry_hmac256_finalize (hmac256_context_t hd, size_t *r_dlen); -void _gcry_hmac256_release (hmac256_context_t hd); - -int _gcry_hmac256_file (void *result, size_t resultsize, const char *filename, - const void *key, size_t keylen); - - -#endif /*HMAC256_H*/ diff --git a/grub-core/lib/libgcrypt/src/hwfeatures.c b/grub-core/lib/libgcrypt/src/hwfeatures.c deleted file mode 100644 index c3567989d..000000000 --- a/grub-core/lib/libgcrypt/src/hwfeatures.c +++ /dev/null @@ -1,192 +0,0 @@ -/* hwfeatures.c - Detect hardware features. - * Copyright (C) 2007, 2011 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 . - */ - -#include -#include -#include -#include -#include -#include - -#include "g10lib.h" - -/* A bit vector describing the hardware features currently - available. */ -static unsigned int hw_features; - - -/* Return a bit vector describing the available hardware features. - The HWF_ constants are used to test for them. */ -unsigned int -_gcry_get_hw_features (void) -{ - return hw_features; -} - - -#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__) -static void -detect_ia32_gnuc (void) -{ - /* The code here is only useful for the PadLock engine thus we don't - build it if that support has been disabled. */ - int has_cpuid = 0; - char vendor_id[12+1]; - - /* Detect the CPUID feature by testing some undefined behaviour (16 - vs 32 bit pushf/popf). */ - asm volatile - ("pushf\n\t" /* Copy flags to EAX. */ - "popl %%eax\n\t" - "movl %%eax, %%ecx\n\t" /* Save flags into ECX. */ - "xorl $0x200000, %%eax\n\t" /* Toggle ID bit and copy it to the flags. */ - "pushl %%eax\n\t" - "popf\n\t" - "pushf\n\t" /* Copy changed flags again to EAX. */ - "popl %%eax\n\t" - "pushl %%ecx\n\t" /* Restore flags from ECX. */ - "popf\n\t" - "xorl %%eax, %%ecx\n\t" /* Compare flags against saved flags. */ - "jz .Lno_cpuid%=\n\t" /* Toggling did not work, thus no CPUID. */ - "movl $1, %0\n" /* Worked. true -> HAS_CPUID. */ - ".Lno_cpuid%=:\n\t" - : "+r" (has_cpuid) - : - : "%eax", "%ecx", "cc" - ); - - if (!has_cpuid) - return; /* No way. */ - - asm volatile - ("pushl %%ebx\n\t" /* Save GOT register. */ - "xorl %%eax, %%eax\n\t" /* 0 -> EAX. */ - "cpuid\n\t" /* Get vendor ID. */ - "movl %%ebx, (%0)\n\t" /* EBX,EDX,ECX -> VENDOR_ID. */ - "movl %%edx, 4(%0)\n\t" - "movl %%ecx, 8(%0)\n\t" - "popl %%ebx\n" - : - : "S" (&vendor_id[0]) - : "%eax", "%ecx", "%edx", "cc" - ); - vendor_id[12] = 0; - - if (0) - ; /* Just to make "else if" and ifdef macros look pretty. */ -#ifdef ENABLE_PADLOCK_SUPPORT - else if (!strcmp (vendor_id, "CentaurHauls")) - { - /* This is a VIA CPU. Check what PadLock features we have. */ - asm volatile - ("pushl %%ebx\n\t" /* Save GOT register. */ - "movl $0xC0000000, %%eax\n\t" /* Check for extended centaur */ - "cpuid\n\t" /* feature flags. */ - "popl %%ebx\n\t" /* Restore GOT register. */ - "cmpl $0xC0000001, %%eax\n\t" - "jb .Lready%=\n\t" /* EAX < 0xC0000000 => no padlock. */ - - "pushl %%ebx\n\t" /* Save GOT register. */ - "movl $0xC0000001, %%eax\n\t" /* Ask for the extended */ - "cpuid\n\t" /* feature flags. */ - "popl %%ebx\n\t" /* Restore GOT register. */ - - "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ - "andl $0x0C, %%eax\n\t" /* Test bits 2 and 3 to see whether */ - "cmpl $0x0C, %%eax\n\t" /* the RNG exists and is enabled. */ - "jnz .Lno_rng%=\n\t" - "orl $1, %0\n" /* Set our HWF_PADLOCK_RNG bit. */ - - ".Lno_rng%=:\n\t" - "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ - "andl $0xC0, %%eax\n\t" /* Test bits 6 and 7 to see whether */ - "cmpl $0xC0, %%eax\n\t" /* the ACE exists and is enabled. */ - "jnz .Lno_ace%=\n\t" - "orl $2, %0\n" /* Set our HWF_PADLOCK_AES bit. */ - - ".Lno_ace%=:\n\t" - "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ - "andl $0xC00, %%eax\n\t" /* Test bits 10, 11 to see whether */ - "cmpl $0xC00, %%eax\n\t" /* the PHE exists and is enabled. */ - "jnz .Lno_phe%=\n\t" - "orl $4, %0\n" /* Set our HWF_PADLOCK_SHA bit. */ - - ".Lno_phe%=:\n\t" - "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ - "andl $0x3000, %%eax\n\t" /* Test bits 12, 13 to see whether */ - "cmpl $0x3000, %%eax\n\t" /* MONTMUL exists and is enabled. */ - "jnz .Lready%=\n\t" - "orl $8, %0\n" /* Set our HWF_PADLOCK_MMUL bit. */ - - ".Lready%=:\n" - : "+r" (hw_features) - : - : "%eax", "%edx", "cc" - ); - } -#endif /*ENABLE_PADLOCK_SUPPORT*/ - else if (!strcmp (vendor_id, "GenuineIntel")) - { - /* This is an Intel CPU. */ - asm volatile - ("pushl %%ebx\n\t" /* Save GOT register. */ - "movl $1, %%eax\n\t" /* Get CPU info and feature flags. */ - "cpuid\n" - "popl %%ebx\n\t" /* Restore GOT register. */ - "testl $0x02000000, %%ecx\n\t" /* Test bit 25. */ - "jz .Lno_aes%=\n\t" /* No AES support. */ - "orl $256, %0\n" /* Set our HWF_INTEL_AES bit. */ - - ".Lno_aes%=:\n" - : "+r" (hw_features) - : - : "%eax", "%ecx", "%edx", "cc" - ); - } - else if (!strcmp (vendor_id, "AuthenticAMD")) - { - /* This is an AMD CPU. */ - - } -} -#endif /* __i386__ && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ */ - - -/* Detect the available hardware features. This function is called - once right at startup and we assume that no other threads are - running. */ -void -_gcry_detect_hw_features (unsigned int disabled_features) -{ - hw_features = 0; - - if (fips_mode ()) - return; /* Hardware support is not to be evaluated. */ - -#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 -#ifdef __GNUC__ - detect_ia32_gnuc (); -#endif -#elif defined (__i386__) && SIZEOF_UNSIGNED_LONG == 8 -#ifdef __GNUC__ -#endif -#endif - - hw_features &= ~disabled_features; -} diff --git a/grub-core/lib/libgcrypt/src/libgcrypt-config.in b/grub-core/lib/libgcrypt/src/libgcrypt-config.in deleted file mode 100644 index c052638cd..000000000 --- a/grub-core/lib/libgcrypt/src/libgcrypt-config.in +++ /dev/null @@ -1,189 +0,0 @@ -#!/bin/sh -# Copyright (C) 1999, 2002, 2003, 2004, 2011 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. -# -# File: @configure_input@ - -# General. -prefix="@prefix@" -exec_prefix="@exec_prefix@" -version="@VERSION@" -includedir="@includedir@" -libdir="@libdir@" -gpg_error_libs="@GPG_ERROR_LIBS@" -gpg_error_cflags="@GPG_ERROR_CFLAGS@" - -# libgcrypt values. -libs="@LIBGCRYPT_CONFIG_LIBS@" -cflags="@LIBGCRYPT_CONFIG_CFLAGS@" - -# API info -api_version="@LIBGCRYPT_CONFIG_API_VERSION@" - -# Configured for host -my_host="@LIBGCRYPT_CONFIG_HOST@" - -# Misc information. -symmetric_ciphers="@LIBGCRYPT_CIPHERS@" -asymmetric_ciphers="@LIBGCRYPT_PUBKEY_CIPHERS@" -digests="@LIBGCRYPT_DIGESTS@" - -# State variables. -echo_libs=no -echo_cflags=no -echo_prefix=no -echo_algorithms=no -echo_exec_prefix=no -echo_version=no -echo_api_version=no -echo_host=no - -# Prints usage information. -usage() -{ - cat <&2 -fi - -while test $# -gt 0; do - case "$1" in - # Set up `optarg'. - --*=*) - optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` - ;; - *) - optarg="" - ;; - esac - - case $1 in - --thread=*) - echo "$0: --thread option obsolete: use the thread callback interface" 1>&2 - exit 1 - ;; - --prefix=*) - # For compatibility reasons with old M4 macros, we ignore - # setting of prefix. - ;; - --prefix) - echo_prefix=yes - ;; - --exec-prefix=*) - ;; - --exec-prefix) - echo_exec_prefix=yes - ;; - --version) - echo_version=yes - ;; - --api-version) - echo_api_version=yes - ;; - --cflags) - echo_cflags=yes - ;; - --libs) - echo_libs=yes - ;; - --algorithms) - echo_algorithms=yes - ;; - --host) - echo_host=yes - ;; - *) - usage 1 1>&2 - ;; - esac - shift -done - -if test "$echo_prefix" = "yes"; then - echo "$prefix" -fi - -if test "$echo_exec_prefix" = "yes"; then - echo "$exec_prefix" -fi - -if test "$echo_cflags" = "yes"; then - includes="" - cflags_final="$cflags" - - # Set up `includes'. - if test "x$includedir" != "x/usr/include" -a "x$includedir" != "x/include"; then - includes="-I$includedir" - fi - # Set up `cflags_final'. - cflags_final="$cflags_final $gpg_error_cflags" - - tmp="" - for i in $includes $cflags_final; do - if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then - tmp="$tmp $i" - fi - done - echo $tmp -fi - -if test "$echo_libs" = "yes"; then - libdirs="" - libs_final="$libs" - - # Set up `libdirs'. - if test "x$libdir" != "x/usr/lib" -a "x$libdir" != "x/lib"; then - libdirs="-L$libdir" - fi - - # Set up `libs_final'. - libs_final="$libs_final $gpg_error_libs" - - tmp="" - for i in $libdirs $libs_final; do - if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then - tmp="$tmp $i" - fi - done - echo $tmp -fi - -if test "$echo_version" = "yes"; then - echo "$version" -fi - -if test "$echo_api_version" = "yes"; then - echo "$api_version" -fi - -if test "$echo_host" = "yes"; then - echo "$my_host" -fi - -if test "$echo_algorithms" = "yes"; then - echo "Symmetric cipher algorithms: $symmetric_ciphers" - echo "Public-key cipher algorithms: $asymmetric_ciphers" - echo "Message digest algorithms: $digests" -fi diff --git a/grub-core/lib/libgcrypt/src/libgcrypt.def b/grub-core/lib/libgcrypt/src/libgcrypt.def deleted file mode 100644 index 031b9410b..000000000 --- a/grub-core/lib/libgcrypt/src/libgcrypt.def +++ /dev/null @@ -1,239 +0,0 @@ -;; libgcrypt.defs - Exported symbols for W32 -;; Copyright (C) 2003, 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 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 -;; - -;; Note: This file should be updated manually and the ordinals shall -;; never be changed. Also check libgcrypt.vers and visibility.h. - - -EXPORTS - gcry_check_version @1 - gcry_control @2 - - gcry_malloc @3 - gcry_calloc @4 - gcry_malloc_secure @5 - gcry_calloc_secure @6 - gcry_realloc @7 - gcry_strdup @8 - gcry_xmalloc @9 - gcry_xcalloc @10 - gcry_xmalloc_secure @11 - gcry_xcalloc_secure @12 - gcry_xrealloc @13 - gcry_xstrdup @14 - gcry_is_secure @15 - gcry_free @16 - - gcry_set_progress_handler @17 - gcry_set_allocation_handler @18 - gcry_set_outofcore_handler @19 - gcry_set_fatalerror_handler @20 - gcry_set_log_handler @21 - gcry_set_gettext_handler @22 - - gcry_strerror @23 - gcry_strsource @24 - gcry_err_code_from_errno @25 - gcry_err_code_to_errno @26 - gcry_err_make_from_errno @27 - gcry_error_from_errno @28 - - gcry_sexp_new @29 - gcry_sexp_create @30 - gcry_sexp_sscan @31 - gcry_sexp_build @32 - gcry_sexp_build_array @33 - gcry_sexp_release @34 - gcry_sexp_canon_len @35 - gcry_sexp_sprint @36 - gcry_sexp_dump @37 - gcry_sexp_cons @38 - gcry_sexp_alist @39 - gcry_sexp_vlist @40 - gcry_sexp_append @41 - gcry_sexp_prepend @42 - gcry_sexp_find_token @43 - gcry_sexp_length @44 - gcry_sexp_nth @45 - gcry_sexp_car @46 - gcry_sexp_cdr @47 - gcry_sexp_cadr @48 - gcry_sexp_nth_data @49 - gcry_sexp_nth_mpi @50 - - gcry_mpi_new @51 - gcry_mpi_snew @52 - gcry_mpi_release @53 - gcry_mpi_copy @54 - gcry_mpi_set @55 - gcry_mpi_set_ui @56 - gcry_mpi_swap @57 - gcry_mpi_cmp @58 - gcry_mpi_cmp_ui @59 - gcry_mpi_scan @60 - gcry_mpi_print @61 - gcry_mpi_aprint @62 - gcry_mpi_dump @63 - gcry_mpi_add @64 - gcry_mpi_add_ui @65 - gcry_mpi_addm @66 - gcry_mpi_sub @67 - gcry_mpi_sub_ui @68 - gcry_mpi_subm @69 - gcry_mpi_mul @70 - gcry_mpi_mul_ui @71 - gcry_mpi_mulm @72 - gcry_mpi_mul_2exp @73 - gcry_mpi_div @74 - gcry_mpi_mod @75 - gcry_mpi_powm @76 - gcry_mpi_gcd @77 - gcry_mpi_invm @78 - gcry_mpi_get_nbits @79 - gcry_mpi_test_bit @80 - gcry_mpi_set_bit @81 - gcry_mpi_clear_bit @82 - gcry_mpi_set_highbit @83 - gcry_mpi_clear_highbit @84 - gcry_mpi_rshift @85 - gcry_mpi_set_opaque @86 - gcry_mpi_get_opaque @87 - gcry_mpi_set_flag @88 - gcry_mpi_clear_flag @89 - gcry_mpi_get_flag @90 - - - gcry_cipher_open @92 - gcry_cipher_close @93 - gcry_cipher_ctl @94 - gcry_cipher_info @95 - gcry_cipher_algo_info @96 - gcry_cipher_algo_name @97 - gcry_cipher_map_name @98 - gcry_cipher_mode_from_oid @99 - gcry_cipher_encrypt @100 - gcry_cipher_decrypt @101 - gcry_cipher_get_algo_keylen @102 - gcry_cipher_get_algo_blklen @103 - gcry_cipher_list @104 - - gcry_pk_encrypt @105 - gcry_pk_decrypt @106 - gcry_pk_sign @107 - gcry_pk_verify @108 - gcry_pk_testkey @109 - gcry_pk_genkey @110 - gcry_pk_ctl @111 - gcry_pk_algo_info @112 - gcry_pk_algo_name @113 - gcry_pk_map_name @114 - gcry_pk_get_nbits @115 - gcry_pk_get_keygrip @116 - gcry_pk_list @117 - - gcry_ac_data_new @118 - gcry_ac_data_destroy @119 - gcry_ac_data_set @120 - gcry_ac_data_copy @121 - gcry_ac_data_length @122 - gcry_ac_data_get_name @123 - gcry_ac_data_get_index @124 - gcry_ac_data_clear @125 - gcry_ac_open @126 - gcry_ac_close @127 - gcry_ac_key_init @128 - gcry_ac_key_pair_generate @129 - gcry_ac_key_pair_extract @130 - gcry_ac_key_data_get @131 - gcry_ac_key_test @132 - gcry_ac_key_get_nbits @133 - gcry_ac_key_get_grip @134 - gcry_ac_key_destroy @135 - gcry_ac_key_pair_destroy @136 - gcry_ac_data_encrypt @137 - gcry_ac_data_decrypt @138 - gcry_ac_data_sign @139 - gcry_ac_data_verify @140 - gcry_ac_id_to_name @141 - gcry_ac_name_to_id @142 - - gcry_md_open @143 - gcry_md_close @144 - gcry_md_enable @145 - gcry_md_copy @146 - gcry_md_reset @147 - gcry_md_ctl @148 - gcry_md_write @149 - gcry_md_read @150 - gcry_md_hash_buffer @151 - gcry_md_get_algo @152 - gcry_md_get_algo_dlen @153 - gcry_md_is_enabled @154 - gcry_md_is_secure @155 - gcry_md_info @156 - gcry_md_algo_info @157 - gcry_md_algo_name @158 - gcry_md_map_name @159 - gcry_md_setkey @160 - gcry_md_list @161 - - gcry_randomize @162 - gcry_random_add_bytes @163 - gcry_random_bytes @164 - gcry_random_bytes_secure @165 - gcry_mpi_randomize @166 - - gcry_prime_generate @167 - gcry_prime_group_generator @168 - gcry_prime_release_factors @169 - gcry_prime_check @170 - - gcry_create_nonce @171 - - gcry_md_debug @172 - - gcry_cipher_register @173 - gcry_cipher_unregister @174 - gcry_md_register @175 - gcry_md_unregister @176 - gcry_pk_register @177 - gcry_pk_unregister @178 - - gcry_ac_data_from_sexp @179 - gcry_ac_data_to_sexp @180 - gcry_ac_io_init @181 - gcry_ac_io_init_va @182 - gcry_ac_data_encrypt_scheme @183 - gcry_ac_data_decrypt_scheme @184 - gcry_ac_data_sign_scheme @185 - gcry_ac_data_verify_scheme @186 - - gcry_sexp_nth_string @187 - - gcry_cipher_setkey @188 - gcry_cipher_setiv @189 - gcry_cipher_setctr @190 - - gcry_mpi_lshift @191 - - gcry_pk_get_curve @192 - gcry_pk_get_param @193 - - gcry_kdf_derive @194 diff --git a/grub-core/lib/libgcrypt/src/libgcrypt.m4 b/grub-core/lib/libgcrypt/src/libgcrypt.m4 deleted file mode 100644 index 831dc0c6f..000000000 --- a/grub-core/lib/libgcrypt/src/libgcrypt.m4 +++ /dev/null @@ -1,123 +0,0 @@ -dnl Autoconf macros for libgcrypt -dnl Copyright (C) 2002, 2004 Free Software Foundation, Inc. -dnl -dnl This file is free software; as a special exception the author gives -dnl unlimited permission to copy and/or distribute it, with or without -dnl modifications, as long as this notice is preserved. -dnl -dnl This file is distributed in the hope that it will be useful, but -dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - -dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION, -dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS. -dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed -dnl with the API version to also check the API compatibility. Example: -dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed -dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using -dnl this features allows to prevent build against newer versions of libgcrypt -dnl with a changed API. -dnl -AC_DEFUN([AM_PATH_LIBGCRYPT], -[ AC_ARG_WITH(libgcrypt-prefix, - AC_HELP_STRING([--with-libgcrypt-prefix=PFX], - [prefix where LIBGCRYPT is installed (optional)]), - libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="") - if test x$libgcrypt_config_prefix != x ; then - if test x${LIBGCRYPT_CONFIG+set} != xset ; then - LIBGCRYPT_CONFIG=$libgcrypt_config_prefix/bin/libgcrypt-config - fi - fi - - AC_PATH_TOOL(LIBGCRYPT_CONFIG, libgcrypt-config, no) - tmp=ifelse([$1], ,1:1.2.0,$1) - if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then - req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` - min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` - else - req_libgcrypt_api=0 - min_libgcrypt_version="$tmp" - fi - - AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version) - ok=no - if test "$LIBGCRYPT_CONFIG" != "no" ; then - req_major=`echo $min_libgcrypt_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` - req_minor=`echo $min_libgcrypt_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` - req_micro=`echo $min_libgcrypt_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` - libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version` - major=`echo $libgcrypt_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` - minor=`echo $libgcrypt_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` - micro=`echo $libgcrypt_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` - if test "$major" -gt "$req_major"; then - ok=yes - else - if test "$major" -eq "$req_major"; then - if test "$minor" -gt "$req_minor"; then - ok=yes - else - if test "$minor" -eq "$req_minor"; then - if test "$micro" -ge "$req_micro"; then - ok=yes - fi - fi - fi - fi - fi - fi - if test $ok = yes; then - AC_MSG_RESULT([yes ($libgcrypt_config_version)]) - else - AC_MSG_RESULT(no) - fi - if test $ok = yes; then - # If we have a recent libgcrypt, we should also check that the - # API is compatible - if test "$req_libgcrypt_api" -gt 0 ; then - tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0` - if test "$tmp" -gt 0 ; then - AC_MSG_CHECKING([LIBGCRYPT API version]) - if test "$req_libgcrypt_api" -eq "$tmp" ; then - AC_MSG_RESULT([okay]) - else - ok=no - AC_MSG_RESULT([does not match. want=$req_libgcrypt_api got=$tmp]) - fi - fi - fi - fi - if test $ok = yes; then - LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags` - LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs` - ifelse([$2], , :, [$2]) - if test x"$host" != x ; then - libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none` - if test x"$libgcrypt_config_host" != xnone ; then - if test x"$libgcrypt_config_host" != x"$host" ; then - AC_MSG_WARN([[ -*** -*** The config script $LIBGCRYPT_CONFIG was -*** built for $libgcrypt_config_host and thus may not match the -*** used host $host. -*** You may want to use the configure option --with-libgcrypt-prefix -*** to specify a matching config script. -***]]) - fi - fi - fi - else - LIBGCRYPT_CFLAGS="" - LIBGCRYPT_LIBS="" - ifelse([$3], , :, [$3]) - fi - AC_SUBST(LIBGCRYPT_CFLAGS) - AC_SUBST(LIBGCRYPT_LIBS) -]) diff --git a/grub-core/lib/libgcrypt/src/libgcrypt.vers b/grub-core/lib/libgcrypt/src/libgcrypt.vers deleted file mode 100644 index 5a617ccbe..000000000 --- a/grub-core/lib/libgcrypt/src/libgcrypt.vers +++ /dev/null @@ -1,111 +0,0 @@ -# libgcrypt.vers - What symbols to export -*- std -*- -# Copyright (C) 2002, 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 - -# NOTE: When adding new functions, please make sure to add them to -# visibility.h and libgcrypt.def as well. - -GCRYPT_1.2 { - global: - gcry_check_version; gcry_control; - gcry_set_allocation_handler; gcry_set_fatalerror_handler; - gcry_set_gettext_handler; gcry_set_log_handler; - gcry_set_outofcore_handler; gcry_set_progress_handler; - - gcry_err_code_from_errno; gcry_err_code_to_errno; - gcry_err_make_from_errno; gcry_error_from_errno; - gcry_strerror; gcry_strsource; - - gcry_free; gcry_malloc; gcry_malloc_secure; gcry_calloc; - gcry_calloc_secure; gcry_realloc; gcry_strdup; gcry_is_secure; - gcry_xcalloc; gcry_xcalloc_secure; gcry_xmalloc; - gcry_xmalloc_secure; gcry_xrealloc; gcry_xstrdup; - - gcry_md_algo_info; gcry_md_algo_name; gcry_md_close; - gcry_md_copy; gcry_md_ctl; gcry_md_enable; gcry_md_get; - gcry_md_get_algo; gcry_md_get_algo_dlen; gcry_md_hash_buffer; - gcry_md_info; gcry_md_is_enabled; gcry_md_is_secure; - gcry_md_list; gcry_md_map_name; gcry_md_open; gcry_md_read; - gcry_md_register; gcry_md_reset; gcry_md_setkey; - gcry_md_unregister; gcry_md_write; gcry_md_debug; - - gcry_cipher_algo_info; gcry_cipher_algo_name; gcry_cipher_close; - gcry_cipher_ctl; gcry_cipher_decrypt; gcry_cipher_encrypt; - gcry_cipher_get_algo_blklen; gcry_cipher_get_algo_keylen; - gcry_cipher_info; gcry_cipher_list; gcry_cipher_map_name; - gcry_cipher_mode_from_oid; gcry_cipher_open; - gcry_cipher_register; gcry_cipher_unregister; - gcry_cipher_setkey; gcry_cipher_setiv; gcry_cipher_setctr; - - gcry_pk_algo_info; gcry_pk_algo_name; gcry_pk_ctl; - gcry_pk_decrypt; gcry_pk_encrypt; gcry_pk_genkey; - gcry_pk_get_keygrip; gcry_pk_get_nbits; gcry_pk_list; - gcry_pk_map_name; gcry_pk_register; gcry_pk_sign; - gcry_pk_testkey; gcry_pk_unregister; gcry_pk_verify; - gcry_pk_get_curve; gcry_pk_get_param; - - gcry_ac_data_new; gcry_ac_data_destroy; gcry_ac_data_copy; - gcry_ac_data_length; gcry_ac_data_clear; gcry_ac_data_set; - gcry_ac_data_get_name; gcry_ac_data_get_index; gcry_ac_open; - gcry_ac_close; gcry_ac_key_init; gcry_ac_key_pair_generate; - gcry_ac_key_pair_extract; gcry_ac_key_data_get; gcry_ac_key_test; - gcry_ac_key_get_nbits; gcry_ac_key_get_grip; gcry_ac_key_destroy; - gcry_ac_key_pair_destroy; gcry_ac_data_encrypt; gcry_ac_data_decrypt; - gcry_ac_data_sign; gcry_ac_data_verify; gcry_ac_id_to_name; - gcry_ac_name_to_id; gcry_ac_list; 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_data_to_sexp; gcry_ac_data_from_sexp; - gcry_ac_io_init; gcry_ac_io_init_va; - - gcry_kdf_derive; - - gcry_prime_check; gcry_prime_generate; - gcry_prime_group_generator; gcry_prime_release_factors; - - gcry_random_add_bytes; gcry_random_bytes; gcry_random_bytes_secure; - gcry_randomize; gcry_create_nonce; - - gcry_sexp_alist; gcry_sexp_append; gcry_sexp_build; - gcry_sexp_build_array; gcry_sexp_cadr; gcry_sexp_canon_len; - gcry_sexp_car; gcry_sexp_cdr; gcry_sexp_cons; gcry_sexp_create; - gcry_sexp_dump; gcry_sexp_find_token; gcry_sexp_length; - gcry_sexp_new; gcry_sexp_nth; gcry_sexp_nth_data; - gcry_sexp_nth_mpi; gcry_sexp_prepend; gcry_sexp_release; - gcry_sexp_sprint; gcry_sexp_sscan; gcry_sexp_vlist; - gcry_sexp_nth_string; - - gcry_mpi_add; gcry_mpi_add_ui; gcry_mpi_addm; gcry_mpi_aprint; - gcry_mpi_clear_bit; gcry_mpi_clear_flag; gcry_mpi_clear_highbit; - gcry_mpi_cmp; gcry_mpi_cmp_ui; gcry_mpi_copy; gcry_mpi_div; - gcry_mpi_dump; gcry_mpi_gcd; gcry_mpi_get_flag; gcry_mpi_get_nbits; - gcry_mpi_get_opaque; gcry_mpi_invm; gcry_mpi_mod; gcry_mpi_mul; - gcry_mpi_mul_2exp; gcry_mpi_mul_ui; gcry_mpi_mulm; gcry_mpi_new; - gcry_mpi_powm; gcry_mpi_print; gcry_mpi_randomize; gcry_mpi_release; - gcry_mpi_rshift; gcry_mpi_scan; gcry_mpi_set; gcry_mpi_set_bit; - gcry_mpi_set_flag; gcry_mpi_set_highbit; gcry_mpi_set_opaque; - gcry_mpi_set_ui; gcry_mpi_snew; gcry_mpi_sub; gcry_mpi_sub_ui; - gcry_mpi_subm; gcry_mpi_swap; gcry_mpi_test_bit; - gcry_mpi_lshift; - - local: - *; - -}; diff --git a/grub-core/lib/libgcrypt/src/misc.c b/grub-core/lib/libgcrypt/src/misc.c deleted file mode 100644 index 17bd54671..000000000 --- a/grub-core/lib/libgcrypt/src/misc.c +++ /dev/null @@ -1,298 +0,0 @@ -/* misc.c - * Copyright (C) 1999, 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 . - */ - -#include -#include -#include -#include -#include -#include - -#include "g10lib.h" -#include "secmem.h" - -static int verbosity_level = 0; - -static void (*fatal_error_handler)(void*,int, const char*) = NULL; -static void *fatal_error_handler_value = 0; -static void (*log_handler)(void*,int, const char*, va_list) = NULL; -static void *log_handler_value = 0; - -static const char *(*user_gettext_handler)( const char * ) = NULL; - -void -gcry_set_gettext_handler( const char *(*f)(const char*) ) -{ - user_gettext_handler = f; -} - - -const char * -_gcry_gettext( const char *key ) -{ - if( user_gettext_handler ) - return user_gettext_handler( key ); - /* FIXME: switch the domain to gnupg and restore later */ - return key; -} - -void -gcry_set_fatalerror_handler( void (*fnc)(void*,int, const char*), void *value) -{ - fatal_error_handler_value = value; - fatal_error_handler = fnc; -} - -static void -write2stderr( const char *s ) -{ - /* Dummy variable to silence gcc warning. */ - int res = write( 2, s, strlen(s) ); - (void) res; -} - -/* - * This function is called for fatal errors. A caller might want to - * set his own handler because this function simply calls abort(). - */ -void -_gcry_fatal_error (int rc, const char *text) -{ - if ( !text ) /* get a default text */ - text = gpg_strerror (rc); - - if (fatal_error_handler && !fips_mode () ) - fatal_error_handler (fatal_error_handler_value, rc, text); - - fips_signal_fatal_error (text); - write2stderr("\nFatal error: "); - write2stderr(text); - write2stderr("\n"); - _gcry_secmem_term (); - abort (); -} - -void -gcry_set_log_handler( void (*f)(void*,int, const char*, va_list ), - void *opaque ) -{ - log_handler = f; - log_handler_value = opaque; -} - -void -_gcry_set_log_verbosity( int level ) -{ - verbosity_level = level; -} - -int -_gcry_log_verbosity( int level ) -{ - return verbosity_level >= level; -} - -/**************** - * This is our log function which prints all log messages to stderr or - * using the function defined with gcry_set_log_handler(). - */ -static void -_gcry_logv( int level, const char *fmt, va_list arg_ptr ) -{ - if (log_handler) - log_handler (log_handler_value, level, fmt, arg_ptr); - else - { - switch (level) - { - case GCRY_LOG_CONT: break; - case GCRY_LOG_INFO: break; - case GCRY_LOG_WARN: break; - case GCRY_LOG_ERROR: break; - case GCRY_LOG_FATAL: fputs("Fatal: ",stderr ); break; - case GCRY_LOG_BUG: fputs("Ohhhh jeeee: ", stderr); break; - case GCRY_LOG_DEBUG: fputs("DBG: ", stderr ); break; - default: fprintf(stderr,"[Unknown log level %d]: ", level ); break; - } - vfprintf(stderr,fmt,arg_ptr) ; - } - - if ( level == GCRY_LOG_FATAL || level == GCRY_LOG_BUG ) - { - fips_signal_fatal_error ("internal error (fatal or bug)"); - _gcry_secmem_term (); - abort (); - } -} - - -void -_gcry_log( int level, const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - _gcry_logv( level, fmt, arg_ptr ); - va_end(arg_ptr); -} - - -#if defined(JNLIB_GCC_M_FUNCTION) || __STDC_VERSION__ >= 199901L -void -_gcry_bug( const char *file, int line, const char *func ) -{ - _gcry_log( GCRY_LOG_BUG, - ("... this is a bug (%s:%d:%s)\n"), file, line, func ); - abort(); /* never called, but it makes the compiler happy */ -} -void -_gcry_assert_failed (const char *expr, const char *file, int line, - const char *func) -{ - _gcry_log (GCRY_LOG_BUG, - ("Assertion `%s' failed (%s:%d:%s)\n"), expr, file, line, func ); - abort(); /* Never called, but it makes the compiler happy. */ -} -#else -void -_gcry_bug( const char *file, int line ) -{ - _gcry_log( GCRY_LOG_BUG, - _("you found a bug ... (%s:%d)\n"), file, line); - abort(); /* never called, but it makes the compiler happy */ -} -void -_gcry_assert_failed (const char *expr, const char *file, int line) -{ - _gcry_log (GCRY_LOG_BUG, - ("Assertion `%s' failed (%s:%d)\n"), expr, file, line); - abort(); /* Never called, but it makes the compiler happy. */ -} -#endif - -void -_gcry_log_info( const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - _gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr ); - va_end(arg_ptr); -} - -int -_gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... ) -{ - va_list arg_ptr; - - (void)fp; - va_start( arg_ptr, fmt ) ; - _gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr ); - va_end(arg_ptr); - return 0; -} - -void -_gcry_log_error( const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - _gcry_logv( GCRY_LOG_ERROR, fmt, arg_ptr ); - va_end(arg_ptr); -} - - -void -_gcry_log_fatal( const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - _gcry_logv( GCRY_LOG_FATAL, fmt, arg_ptr ); - va_end(arg_ptr); - abort(); /* never called, but it makes the compiler happy */ -} - -void -_gcry_log_bug( const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - _gcry_logv( GCRY_LOG_BUG, fmt, arg_ptr ); - va_end(arg_ptr); - abort(); /* never called, but it makes the compiler happy */ -} - -void -_gcry_log_debug( const char *fmt, ... ) -{ - va_list arg_ptr ; - - va_start( arg_ptr, fmt ) ; - _gcry_logv( GCRY_LOG_DEBUG, fmt, arg_ptr ); - va_end(arg_ptr); -} - - -void -_gcry_log_printf (const char *fmt, ...) -{ - va_list arg_ptr; - - if (fmt) - { - va_start( arg_ptr, fmt ) ; - _gcry_logv (GCRY_LOG_CONT, fmt, arg_ptr); - va_end(arg_ptr); - } -} - -/* Print a hexdump of BUFFER. With TEXT of NULL print just the raw - dump, with TEXT an empty string, print a trailing linefeed, - otherwise print an entire debug line. */ -void -_gcry_log_printhex (const char *text, const void *buffer, size_t length) -{ - if (text && *text) - log_debug ("%s ", text); - if (length) - { - const unsigned char *p = buffer; - log_printf ("%02X", *p); - for (length--, p++; length--; p++) - log_printf (" %02X", *p); - } - if (text) - log_printf ("\n"); -} - - -void -_gcry_burn_stack (int bytes) -{ - char buf[64]; - - wipememory (buf, sizeof buf); - bytes -= sizeof buf; - if (bytes > 0) - _gcry_burn_stack (bytes); -} diff --git a/grub-core/lib/libgcrypt/src/missing-string.c b/grub-core/lib/libgcrypt/src/missing-string.c deleted file mode 100644 index 4756c00ea..000000000 --- a/grub-core/lib/libgcrypt/src/missing-string.c +++ /dev/null @@ -1,54 +0,0 @@ -/* missing-string.c - missing string utilities - * Copyright (C) 1994, 1998, 1999, 2000, 2001, - * 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 -#include -#include -#include -#include - -#include "g10lib.h" - - -#ifndef HAVE_STPCPY -char * -stpcpy(char *a,const char *b) -{ - while( *b ) - *a++ = *b++; - *a = 0; - - return (char*)a; -} -#endif - - -#ifndef HAVE_STRCASECMP -int -strcasecmp( const char *a, const char *b ) -{ - for( ; *a && *b; a++, b++ ) { - if( *a != *b && toupper(*a) != toupper(*b) ) - break; - } - return *(const byte*)a - *(const byte*)b; -} -#endif diff --git a/grub-core/lib/libgcrypt/src/module.c b/grub-core/lib/libgcrypt/src/module.c deleted file mode 100644 index 32f668de4..000000000 --- a/grub-core/lib/libgcrypt/src/module.c +++ /dev/null @@ -1,212 +0,0 @@ -/* module.c - Module management for libgcrypt. - * 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 . - */ - -#include -#include -#include "g10lib.h" - -/* Please match these numbers with the allocated algorithm - numbers. */ -#define MODULE_ID_MIN 600 -#define MODULE_ID_LAST 65500 -#define MODULE_ID_USER GCRY_MODULE_ID_USER -#define MODULE_ID_USER_LAST GCRY_MODULE_ID_USER_LAST - -#if MODULE_ID_MIN >= MODULE_ID_USER -#error Need to implement a different search strategy -#endif - -/* Internal function. Generate a new, unique module ID for a module - that should be inserted into the module chain starting at - MODULES. */ -static gcry_err_code_t -_gcry_module_id_new (gcry_module_t modules, unsigned int *id_new) -{ - unsigned int mod_id; - gcry_err_code_t err = GPG_ERR_NO_ERROR; - gcry_module_t module; - - /* Search for unused ID. */ - for (mod_id = MODULE_ID_MIN; mod_id < MODULE_ID_LAST; mod_id++) - { - if (mod_id == MODULE_ID_USER) - { - mod_id = MODULE_ID_USER_LAST; - continue; - } - - /* Search for a module with the current ID. */ - for (module = modules; module; module = module->next) - if (mod_id == module->mod_id) - break; - - if (! module) - /* None found -> the ID is available for use. */ - break; - } - - if (mod_id < MODULE_ID_LAST) - /* Done. */ - *id_new = mod_id; - else - /* No free ID found. */ - err = GPG_ERR_INTERNAL; - - return err; -} - -/* Add a module specification to the list ENTRIES. The new module has - it's use-counter set to one. */ -gcry_err_code_t -_gcry_module_add (gcry_module_t *entries, unsigned int mod_id, - void *spec, void *extraspec, gcry_module_t *module) -{ - gcry_err_code_t err = 0; - gcry_module_t entry; - - if (! mod_id) - err = _gcry_module_id_new (*entries, &mod_id); - - if (! err) - { - entry = gcry_malloc (sizeof (struct gcry_module)); - if (! entry) - err = gpg_err_code_from_errno (errno); - } - - if (! err) - { - /* Fill new module entry. */ - entry->flags = 0; - entry->counter = 1; - entry->spec = spec; - entry->extraspec = extraspec; - entry->mod_id = mod_id; - - /* Link it into the list. */ - entry->next = *entries; - entry->prevp = entries; - if (*entries) - (*entries)->prevp = &entry->next; - *entries = entry; - - /* And give it to the caller. */ - if (module) - *module = entry; - } - return err; -} - -/* Internal function. Unlink CIPHER_ENTRY from the list of registered - ciphers and destroy it. */ -static void -_gcry_module_drop (gcry_module_t entry) -{ - *entry->prevp = entry->next; - if (entry->next) - entry->next->prevp = entry->prevp; - - gcry_free (entry); -} - -/* Lookup a module specification by it's ID. After a successful - lookup, the module has it's resource counter incremented. */ -gcry_module_t -_gcry_module_lookup_id (gcry_module_t entries, unsigned int mod_id) -{ - gcry_module_t entry; - - for (entry = entries; entry; entry = entry->next) - if (entry->mod_id == mod_id) - { - entry->counter++; - break; - } - - return entry; -} - -/* Lookup a module specification. After a successful lookup, the - module has it's resource counter incremented. FUNC is a function - provided by the caller, which is responsible for identifying the - wanted module. */ -gcry_module_t -_gcry_module_lookup (gcry_module_t entries, void *data, - gcry_module_lookup_t func) -{ - gcry_module_t entry; - - for (entry = entries; entry; entry = entry->next) - if ((*func) (entry->spec, data)) - { - entry->counter++; - break; - } - - return entry; -} - -/* Release a module. In case the use-counter reaches zero, destroy - the module. Passing MODULE as NULL is a dummy operation (similar - to free()). */ -void -_gcry_module_release (gcry_module_t module) -{ - if (module && ! --module->counter) - _gcry_module_drop (module); -} - -/* Add a reference to a module. */ -void -_gcry_module_use (gcry_module_t module) -{ - ++module->counter; -} - -/* If LIST is zero, write the number of modules identified by 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_err_code_t -_gcry_module_list (gcry_module_t modules, - int *list, int *list_length) -{ - gcry_err_code_t err = GPG_ERR_NO_ERROR; - gcry_module_t module; - int length, i; - - for (module = modules, length = 0; module; module = module->next, length++); - - if (list) - { - if (length > *list_length) - length = *list_length; - - for (module = modules, i = 0; i < length; module = module->next, i++) - list[i] = module->mod_id; - - if (length < *list_length) - *list_length = length; - } - else - *list_length = length; - - return err; -} diff --git a/grub-core/lib/libgcrypt/src/mpi.h b/grub-core/lib/libgcrypt/src/mpi.h deleted file mode 100644 index 5883196b1..000000000 --- a/grub-core/lib/libgcrypt/src/mpi.h +++ /dev/null @@ -1,266 +0,0 @@ -/* mpi.h - Multi Precision Integers - * Copyright (C) 1994, 1996, 1998, - * 2001, 2002, 2003, 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 - * - * Note: This code is heavily based on the GNU MP Library. - * Actually it's the same code with only minor changes in the - * way the data is stored; this is to support the abstraction - * of an optional secure memory allocation which may be used - * to avoid revealing of sensitive data due to paging etc. - */ - -#ifndef G10_MPI_H -#define G10_MPI_H - -#include -#include -#include - -#include "types.h" -#include "../mpi/mpi-asm-defs.h" - -#include "g10lib.h" - -#ifndef _GCRYPT_IN_LIBGCRYPT -#error this file should only be used inside libgcrypt -#endif - -#ifndef BITS_PER_MPI_LIMB -#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT - typedef unsigned int mpi_limb_t; - typedef signed int mpi_limb_signed_t; -#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG - typedef unsigned long int mpi_limb_t; - typedef signed long int mpi_limb_signed_t; -#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG - typedef unsigned long long int mpi_limb_t; - typedef signed long long int mpi_limb_signed_t; -#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT - typedef unsigned short int mpi_limb_t; - typedef signed short int mpi_limb_signed_t; -#else -#error BYTES_PER_MPI_LIMB does not match any C type -#endif -#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB) -#endif /*BITS_PER_MPI_LIMB*/ - -#define DBG_MPI _gcry_get_debug_flag( 2 ); - -struct gcry_mpi -{ - int alloced; /* Array size (# of allocated limbs). */ - int nlimbs; /* Number of valid limbs. */ - int sign; /* Indicates a negative number and is also used - for opaque MPIs to store the length. */ - unsigned int flags; /* Bit 0: Array to be allocated in secure memory space.*/ - /* Bit 2: the limb is a pointer to some m_alloced data.*/ - mpi_limb_t *d; /* Array with the limbs */ -}; - -#define MPI_NULL NULL - -#define mpi_get_nlimbs(a) ((a)->nlimbs) -#define mpi_is_neg(a) ((a)->sign) - -/*-- mpiutil.c --*/ - -#ifdef M_DEBUG -# define mpi_alloc(n) _gcry_mpi_debug_alloc((n), M_DBGINFO( __LINE__ ) ) -# define mpi_alloc_secure(n) _gcry_mpi_debug_alloc_secure((n), M_DBGINFO( __LINE__ ) ) -# define mpi_free(a) _gcry_mpi_debug_free((a), M_DBGINFO(__LINE__) ) -# define mpi_resize(a,b) _gcry_mpi_debug_resize((a),(b), M_DBGINFO(__LINE__) ) -# define mpi_copy(a) _gcry_mpi_debug_copy((a), M_DBGINFO(__LINE__) ) - gcry_mpi_t _gcry_mpi_debug_alloc( unsigned nlimbs, const char *info ); - gcry_mpi_t _gcry_mpi_debug_alloc_secure( unsigned nlimbs, const char *info ); - void _gcry_mpi_debug_free( gcry_mpi_t a, const char *info ); - void _gcry_mpi_debug_resize( gcry_mpi_t a, unsigned nlimbs, const char *info ); - gcry_mpi_t _gcry_mpi_debug_copy( gcry_mpi_t a, const char *info ); -#else -# define mpi_alloc(n) _gcry_mpi_alloc((n) ) -# define mpi_alloc_secure(n) _gcry_mpi_alloc_secure((n) ) -# define mpi_free(a) _gcry_mpi_free((a) ) -# define mpi_resize(a,b) _gcry_mpi_resize((a),(b)) -# define mpi_copy(a) _gcry_mpi_copy((a)) - gcry_mpi_t _gcry_mpi_alloc( unsigned nlimbs ); - gcry_mpi_t _gcry_mpi_alloc_secure( unsigned nlimbs ); - void _gcry_mpi_free( gcry_mpi_t a ); - void _gcry_mpi_resize( gcry_mpi_t a, unsigned nlimbs ); - gcry_mpi_t _gcry_mpi_copy( gcry_mpi_t a ); -#endif - -#define gcry_mpi_copy _gcry_mpi_copy - -#define mpi_is_opaque(a) ((a) && ((a)->flags&4)) -#define mpi_is_secure(a) ((a) && ((a)->flags&1)) -#define mpi_clear(a) _gcry_mpi_clear ((a)) -#define mpi_alloc_like(a) _gcry_mpi_alloc_like((a)) -#define mpi_set(a,b) gcry_mpi_set ((a),(b)) -#define mpi_set_ui(a,b) gcry_mpi_set_ui ((a),(b)) -#define mpi_get_ui(a,b) _gcry_mpi_get_ui ((a),(b)) -#define mpi_alloc_set_ui(a) _gcry_mpi_alloc_set_ui ((a)) -#define mpi_m_check(a) _gcry_mpi_m_check ((a)) -#define mpi_swap(a,b) _gcry_mpi_swap ((a),(b)) -#define mpi_new(n) _gcry_mpi_new ((n)) -#define mpi_snew(n) _gcry_mpi_snew ((n)) - -void _gcry_mpi_clear( gcry_mpi_t a ); -gcry_mpi_t _gcry_mpi_alloc_like( gcry_mpi_t a ); -gcry_mpi_t _gcry_mpi_alloc_set_ui( unsigned long u); -gcry_err_code_t _gcry_mpi_get_ui (gcry_mpi_t w, ulong *u); -gcry_err_code_t gcry_mpi_get_ui (gcry_mpi_t w, ulong *u); -void _gcry_mpi_m_check( gcry_mpi_t a ); -void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b); -gcry_mpi_t _gcry_mpi_new (unsigned int nbits); -gcry_mpi_t _gcry_mpi_snew (unsigned int nbits); - -/*-- mpicoder.c --*/ -void _gcry_log_mpidump( const char *text, gcry_mpi_t a ); -u32 _gcry_mpi_get_keyid( gcry_mpi_t a, u32 *keyid ); -byte *_gcry_mpi_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign ); -byte *_gcry_mpi_get_secure_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign ); -void _gcry_mpi_set_buffer ( gcry_mpi_t a, const void *buffer, - unsigned int nbytes, int sign ); - -#define log_mpidump _gcry_log_mpidump - -/*-- mpi-add.c --*/ -#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v)) -#define mpi_add(w,u,v) gcry_mpi_add ((w),(u),(v)) -#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m)) -#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v)) -#define mpi_sub(w,u,v) gcry_mpi_sub ((w),(u),(v)) -#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m)) - - -/*-- mpi-mul.c --*/ -#define mpi_mul_ui(w,u,v) gcry_mpi_mul_ui ((w),(u),(v)) -#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v)) -#define mpi_mul(w,u,v) gcry_mpi_mul ((w),(u),(v)) -#define mpi_mulm(w,u,v,m) gcry_mpi_mulm ((w),(u),(v),(m)) - - -/*-- mpi-div.c --*/ -#define mpi_fdiv_r_ui(a,b,c) _gcry_mpi_fdiv_r_ui((a),(b),(c)) -#define mpi_fdiv_r(a,b,c) _gcry_mpi_fdiv_r((a),(b),(c)) -#define mpi_fdiv_q(a,b,c) _gcry_mpi_fdiv_q((a),(b),(c)) -#define mpi_fdiv_qr(a,b,c,d) _gcry_mpi_fdiv_qr((a),(b),(c),(d)) -#define mpi_tdiv_r(a,b,c) _gcry_mpi_tdiv_r((a),(b),(c)) -#define mpi_tdiv_qr(a,b,c,d) _gcry_mpi_tdiv_qr((a),(b),(c),(d)) -#define mpi_tdiv_q_2exp(a,b,c) _gcry_mpi_tdiv_q_2exp((a),(b),(c)) -#define mpi_divisible_ui(a,b) _gcry_mpi_divisible_ui((a),(b)) - -ulong _gcry_mpi_fdiv_r_ui( gcry_mpi_t rem, gcry_mpi_t dividend, ulong divisor ); -void _gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor ); -void _gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor ); -void _gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor ); -void _gcry_mpi_tdiv_r( gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den); -void _gcry_mpi_tdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den); -void _gcry_mpi_tdiv_q_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned count ); -int _gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor ); - - -/*-- mpi-mod.c --*/ -#define mpi_mod(r,a,m) _gcry_mpi_mod ((r), (a), (m)) -#define mpi_barrett_init(m,f) _gcry_mpi_barrett_init ((m),(f)) -#define mpi_barrett_free(c) _gcry_mpi_barrett_free ((c)) -#define mpi_mod_barrett(r,a,c) _gcry_mpi_mod_barrett ((r), (a), (c)) -#define mpi_mul_barrett(r,u,v,c) _gcry_mpi_mul_barrett ((r), (u), (v), (c)) - -void _gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor); - -/* Context used with Barrett reduction. */ -struct barrett_ctx_s; -typedef struct barrett_ctx_s *mpi_barrett_t; - -mpi_barrett_t _gcry_mpi_barrett_init (gcry_mpi_t m, int copy); -void _gcry_mpi_barrett_free (mpi_barrett_t ctx); -void _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx); -void _gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, - mpi_barrett_t ctx); - - - -/*-- mpi-gcd.c --*/ - -/*-- mpi-mpow.c --*/ -#define mpi_mulpowm(a,b,c,d) _gcry_mpi_mulpowm ((a),(b),(c),(d)) -void _gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t mod); - -/*-- mpi-cmp.c --*/ -#define mpi_cmp_ui(a,b) gcry_mpi_cmp_ui ((a),(b)) -#define mpi_cmp(a,b) gcry_mpi_cmp ((a),(b)) -int gcry_mpi_cmp_ui( gcry_mpi_t u, ulong v ); -int gcry_mpi_cmp( gcry_mpi_t u, gcry_mpi_t v ); - -/*-- mpi-scan.c --*/ -#define mpi_trailing_zeros(a) _gcry_mpi_trailing_zeros ((a)) -int _gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx ); -void _gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int value ); -unsigned _gcry_mpi_trailing_zeros( gcry_mpi_t a ); - -/*-- mpi-bit.c --*/ -#define mpi_normalize(a) _gcry_mpi_normalize ((a)) -#define mpi_get_nbits(a) gcry_mpi_get_nbits ((a)) -#define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b)) -#define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b)) -#define mpi_set_highbit(a,b) gcry_mpi_set_highbit ((a),(b)) -#define mpi_clear_bit(a,b) gcry_mpi_clear_bit ((a),(b)) -#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b)) -#define mpi_rshift(a,b,c) gcry_mpi_rshift ((a),(b),(c)) -#define mpi_lshift(a,b,c) gcry_mpi_lshift ((a),(b),(c)) - -void _gcry_mpi_normalize( gcry_mpi_t a ); - -/*-- mpi-inv.c --*/ -#define mpi_invm(a,b,c) gcry_mpi_invm ((a),(b),(c)) - -/*-- ec.c --*/ - -/* Object to represent a point in projective coordinates. */ -struct mpi_point_s; -typedef struct mpi_point_s mpi_point_t; -struct mpi_point_s -{ - gcry_mpi_t x; - gcry_mpi_t y; - gcry_mpi_t z; -}; - -/* Context used with elliptic curve functions. */ -struct mpi_ec_ctx_s; -typedef struct mpi_ec_ctx_s *mpi_ec_t; - -void _gcry_mpi_ec_point_init (mpi_point_t *p); -void _gcry_mpi_ec_point_free (mpi_point_t *p); -mpi_ec_t _gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a); -void _gcry_mpi_ec_free (mpi_ec_t ctx); -int _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point, - mpi_ec_t ctx); -void _gcry_mpi_ec_dup_point (mpi_point_t *result, - mpi_point_t *point, mpi_ec_t ctx); -void _gcry_mpi_ec_add_points (mpi_point_t *result, - mpi_point_t *p1, mpi_point_t *p2, - mpi_ec_t ctx); -void _gcry_mpi_ec_mul_point (mpi_point_t *result, - gcry_mpi_t scalar, mpi_point_t *point, - mpi_ec_t ctx); - - - -#endif /*G10_MPI_H*/ diff --git a/grub-core/lib/libgcrypt/src/secmem.c b/grub-core/lib/libgcrypt/src/secmem.c deleted file mode 100644 index 2beb234ac..000000000 --- a/grub-core/lib/libgcrypt/src/secmem.c +++ /dev/null @@ -1,696 +0,0 @@ -/* secmem.c - memory allocation from a secure heap - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003, 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 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(HAVE_MLOCK) || defined(HAVE_MMAP) -#include -#include -#include -#ifdef USE_CAPABILITIES -#include -#endif -#endif - -#include "ath.h" -#include "g10lib.h" -#include "secmem.h" - -#if defined (MAP_ANON) && ! defined (MAP_ANONYMOUS) -#define MAP_ANONYMOUS MAP_ANON -#endif - -#define MINIMUM_POOL_SIZE 16384 -#define STANDARD_POOL_SIZE 32768 -#define DEFAULT_PAGE_SIZE 4096 - -typedef struct memblock -{ - unsigned size; /* Size of the memory available to the - user. */ - int flags; /* See below. */ - PROPERLY_ALIGNED_TYPE aligned; -} memblock_t; - -/* This flag specifies that the memory block is in use. */ -#define MB_FLAG_ACTIVE (1 << 0) - -/* The pool of secure memory. */ -static void *pool; - -/* Size of POOL in bytes. */ -static size_t pool_size; - -/* True, if the memory pool is ready for use. May be checked in an - atexit function. */ -static volatile int pool_okay; - -/* True, if the memory pool is mmapped. */ -static volatile int pool_is_mmapped; - -/* FIXME? */ -static int disable_secmem; -static int show_warning; -static int not_locked; -static int no_warning; -static int suspend_warning; - -/* Stats. */ -static unsigned int cur_alloced, cur_blocks; - -/* Lock protecting accesses to the memory pool. */ -static ath_mutex_t secmem_lock; - -/* Convenient macros. */ -#define SECMEM_LOCK ath_mutex_lock (&secmem_lock) -#define SECMEM_UNLOCK ath_mutex_unlock (&secmem_lock) - -/* The size of the memblock structure; this does not include the - memory that is available to the user. */ -#define BLOCK_HEAD_SIZE \ - offsetof (memblock_t, aligned) - -/* Convert an address into the according memory block structure. */ -#define ADDR_TO_BLOCK(addr) \ - (memblock_t *) ((char *) addr - BLOCK_HEAD_SIZE) - -/* Check whether P points into the pool. */ -static int -ptr_into_pool_p (const void *p) -{ - /* We need to convert pointers to addresses. This is required by - C-99 6.5.8 to avoid undefined behaviour. Using size_t is at - least only implementation defined. See also - http://lists.gnupg.org/pipermail/gcrypt-devel/2007-February/001102.html - */ - size_t p_addr = (size_t)p; - size_t pool_addr = (size_t)pool; - - return p_addr >= pool_addr && p_addr < pool_addr+pool_size; -} - -/* Update the stats. */ -static void -stats_update (size_t add, size_t sub) -{ - if (add) - { - cur_alloced += add; - cur_blocks++; - } - if (sub) - { - cur_alloced -= sub; - cur_blocks--; - } -} - -/* Return the block following MB or NULL, if MB is the last block. */ -static memblock_t * -mb_get_next (memblock_t *mb) -{ - memblock_t *mb_next; - - mb_next = (memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE + mb->size); - - if (! ptr_into_pool_p (mb_next)) - mb_next = NULL; - - return mb_next; -} - -/* Return the block preceding MB or NULL, if MB is the first - block. */ -static memblock_t * -mb_get_prev (memblock_t *mb) -{ - memblock_t *mb_prev, *mb_next; - - if (mb == pool) - mb_prev = NULL; - else - { - mb_prev = (memblock_t *) pool; - while (1) - { - mb_next = mb_get_next (mb_prev); - if (mb_next == mb) - break; - else - mb_prev = mb_next; - } - } - - return mb_prev; -} - -/* If the preceding block of MB and/or the following block of MB - exist and are not active, merge them to form a bigger block. */ -static void -mb_merge (memblock_t *mb) -{ - memblock_t *mb_prev, *mb_next; - - mb_prev = mb_get_prev (mb); - mb_next = mb_get_next (mb); - - if (mb_prev && (! (mb_prev->flags & MB_FLAG_ACTIVE))) - { - mb_prev->size += BLOCK_HEAD_SIZE + mb->size; - mb = mb_prev; - } - if (mb_next && (! (mb_next->flags & MB_FLAG_ACTIVE))) - mb->size += BLOCK_HEAD_SIZE + mb_next->size; -} - -/* Return a new block, which can hold SIZE bytes. */ -static memblock_t * -mb_get_new (memblock_t *block, size_t size) -{ - memblock_t *mb, *mb_split; - - for (mb = block; ptr_into_pool_p (mb); mb = mb_get_next (mb)) - if (! (mb->flags & MB_FLAG_ACTIVE) && mb->size >= size) - { - /* Found a free block. */ - mb->flags |= MB_FLAG_ACTIVE; - - if (mb->size - size > BLOCK_HEAD_SIZE) - { - /* Split block. */ - - mb_split = (memblock_t *) (((char *) mb) + BLOCK_HEAD_SIZE + size); - mb_split->size = mb->size - size - BLOCK_HEAD_SIZE; - mb_split->flags = 0; - - mb->size = size; - - mb_merge (mb_split); - - } - - break; - } - - if (! ptr_into_pool_p (mb)) - { - gpg_err_set_errno (ENOMEM); - mb = NULL; - } - - return mb; -} - -/* Print a warning message. */ -static void -print_warn (void) -{ - if (!no_warning) - log_info (_("Warning: using insecure memory!\n")); -} - -/* Lock the memory pages into core and drop privileges. */ -static void -lock_pool (void *p, size_t n) -{ -#if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK) - int err; - - cap_set_proc (cap_from_text ("cap_ipc_lock+ep")); - err = mlock (p, n); - if (err && errno) - err = errno; - cap_set_proc (cap_from_text ("cap_ipc_lock+p")); - - if (err) - { - if (errno != EPERM -#ifdef EAGAIN /* OpenBSD returns this */ - && errno != EAGAIN -#endif -#ifdef ENOSYS /* Some SCOs return this (function not implemented) */ - && errno != ENOSYS -#endif -#ifdef ENOMEM /* Linux might return this. */ - && errno != ENOMEM -#endif - ) - log_error ("can't lock memory: %s\n", strerror (err)); - show_warning = 1; - not_locked = 1; - } - -#elif defined(HAVE_MLOCK) - uid_t uid; - int err; - - uid = getuid (); - -#ifdef HAVE_BROKEN_MLOCK - /* Under HP/UX mlock segfaults if called by non-root. Note, we have - noch checked whether mlock does really work under AIX where we - also detected a broken nlock. Note further, that using plock () - is not a good idea under AIX. */ - if (uid) - { - errno = EPERM; - err = errno; - } - else - { - err = mlock (p, n); - if (err && errno) - err = errno; - } -#else /* !HAVE_BROKEN_MLOCK */ - err = mlock (p, n); - if (err && errno) - err = errno; -#endif /* !HAVE_BROKEN_MLOCK */ - - if (uid && ! geteuid ()) - { - /* check that we really dropped the privs. - * Note: setuid(0) should always fail */ - if (setuid (uid) || getuid () != geteuid () || !setuid (0)) - log_fatal ("failed to reset uid: %s\n", strerror (errno)); - } - - if (err) - { - if (errno != EPERM -#ifdef EAGAIN /* OpenBSD returns this. */ - && errno != EAGAIN -#endif -#ifdef ENOSYS /* Some SCOs return this (function not implemented). */ - && errno != ENOSYS -#endif -#ifdef ENOMEM /* Linux might return this. */ - && errno != ENOMEM -#endif - ) - log_error ("can't lock memory: %s\n", strerror (err)); - show_warning = 1; - not_locked = 1; - } - -#elif defined ( __QNX__ ) - /* QNX does not page at all, so the whole secure memory stuff does - * not make much sense. However it is still of use because it - * wipes out the memory on a free(). - * Therefore it is sufficient to suppress the warning. */ - (void)p; - (void)n; -#elif defined (HAVE_DOSISH_SYSTEM) || defined (__CYGWIN__) - /* It does not make sense to print such a warning, given the fact that - * this whole Windows !@#$% and their user base are inherently insecure. */ - (void)p; - (void)n; -#elif defined (__riscos__) - /* No virtual memory on RISC OS, so no pages are swapped to disc, - * besides we don't have mmap, so we don't use it! ;-) - * But don't complain, as explained above. */ - (void)p; - (void)n; -#else - (void)p; - (void)n; - log_info ("Please note that you don't have secure memory on this system\n"); -#endif -} - -/* Initialize POOL. */ -static void -init_pool (size_t n) -{ - size_t pgsize; - long int pgsize_val; - memblock_t *mb; - - pool_size = n; - - if (disable_secmem) - log_bug ("secure memory is disabled"); - -#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) - pgsize_val = sysconf (_SC_PAGESIZE); -#elif defined(HAVE_GETPAGESIZE) - pgsize_val = getpagesize (); -#else - pgsize_val = -1; -#endif - pgsize = (pgsize_val != -1 && pgsize_val > 0)? pgsize_val:DEFAULT_PAGE_SIZE; - - -#if HAVE_MMAP - pool_size = (pool_size + pgsize - 1) & ~(pgsize - 1); -#ifdef MAP_ANONYMOUS - pool = mmap (0, pool_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -#else /* map /dev/zero instead */ - { - int fd; - - fd = open ("/dev/zero", O_RDWR); - if (fd == -1) - { - log_error ("can't open /dev/zero: %s\n", strerror (errno)); - pool = (void *) -1; - } - else - { - pool = mmap (0, pool_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - close (fd); - } - } -#endif - if (pool == (void *) -1) - log_info ("can't mmap pool of %u bytes: %s - using malloc\n", - (unsigned) pool_size, strerror (errno)); - else - { - pool_is_mmapped = 1; - pool_okay = 1; - } - -#endif - if (!pool_okay) - { - pool = malloc (pool_size); - if (!pool) - log_fatal ("can't allocate memory pool of %u bytes\n", - (unsigned) pool_size); - else - pool_okay = 1; - } - - /* Initialize first memory block. */ - mb = (memblock_t *) pool; - mb->size = pool_size; - mb->flags = 0; -} - -void -_gcry_secmem_set_flags (unsigned flags) -{ - int was_susp; - - SECMEM_LOCK; - - was_susp = suspend_warning; - no_warning = flags & GCRY_SECMEM_FLAG_NO_WARNING; - suspend_warning = flags & GCRY_SECMEM_FLAG_SUSPEND_WARNING; - - /* and now issue the warning if it is not longer suspended */ - if (was_susp && !suspend_warning && show_warning) - { - show_warning = 0; - print_warn (); - } - - SECMEM_UNLOCK; -} - -unsigned int -_gcry_secmem_get_flags (void) -{ - unsigned flags; - - SECMEM_LOCK; - - flags = no_warning ? GCRY_SECMEM_FLAG_NO_WARNING : 0; - flags |= suspend_warning ? GCRY_SECMEM_FLAG_SUSPEND_WARNING : 0; - flags |= not_locked ? GCRY_SECMEM_FLAG_NOT_LOCKED : 0; - - SECMEM_UNLOCK; - - return flags; -} - - -/* See _gcry_secmem_init. This function is expected to be called with - the secmem lock held. */ -static void -secmem_init (size_t n) -{ - if (!n) - { -#ifdef USE_CAPABILITIES - /* drop all capabilities */ - cap_set_proc (cap_from_text ("all-eip")); - -#elif !defined(HAVE_DOSISH_SYSTEM) - uid_t uid; - - disable_secmem = 1; - uid = getuid (); - if (uid != geteuid ()) - { - if (setuid (uid) || getuid () != geteuid () || !setuid (0)) - log_fatal ("failed to drop setuid\n"); - } -#endif - } - else - { - if (n < MINIMUM_POOL_SIZE) - n = MINIMUM_POOL_SIZE; - if (! pool_okay) - { - init_pool (n); - lock_pool (pool, n); - } - else - log_error ("Oops, secure memory pool already initialized\n"); - } -} - - - -/* Initialize the secure memory system. If running with the necessary - privileges, the secure memory pool will be locked into the core in - order to prevent page-outs of the data. Furthermore allocated - secure memory will be wiped out when released. */ -void -_gcry_secmem_init (size_t n) -{ - SECMEM_LOCK; - - secmem_init (n); - - SECMEM_UNLOCK; -} - - -static void * -_gcry_secmem_malloc_internal (size_t size) -{ - memblock_t *mb; - - if (!pool_okay) - { - /* Try to initialize the pool if the user forgot about it. */ - secmem_init (STANDARD_POOL_SIZE); - if (!pool_okay) - { - log_info (_("operation is not possible without " - "initialized secure memory\n")); - gpg_err_set_errno (ENOMEM); - return NULL; - } - } - if (not_locked && fips_mode ()) - { - log_info (_("secure memory pool is not locked while in FIPS mode\n")); - gpg_err_set_errno (ENOMEM); - return NULL; - } - if (show_warning && !suspend_warning) - { - show_warning = 0; - print_warn (); - } - - /* Blocks are always a multiple of 32. */ - size = ((size + 31) / 32) * 32; - - mb = mb_get_new ((memblock_t *) pool, size); - if (mb) - stats_update (size, 0); - - return mb ? &mb->aligned.c : NULL; -} - -void * -_gcry_secmem_malloc (size_t size) -{ - void *p; - - SECMEM_LOCK; - p = _gcry_secmem_malloc_internal (size); - SECMEM_UNLOCK; - - return p; -} - -static void -_gcry_secmem_free_internal (void *a) -{ - memblock_t *mb; - int size; - - if (!a) - return; - - mb = ADDR_TO_BLOCK (a); - size = mb->size; - - /* This does not make much sense: probably this memory is held in the - * cache. We do it anyway: */ -#define MB_WIPE_OUT(byte) \ - wipememory2 ((memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE), (byte), size); - - MB_WIPE_OUT (0xff); - MB_WIPE_OUT (0xaa); - MB_WIPE_OUT (0x55); - MB_WIPE_OUT (0x00); - - stats_update (0, size); - - mb->flags &= ~MB_FLAG_ACTIVE; - - /* Update stats. */ - - mb_merge (mb); -} - -/* Wipe out and release memory. */ -void -_gcry_secmem_free (void *a) -{ - SECMEM_LOCK; - _gcry_secmem_free_internal (a); - SECMEM_UNLOCK; -} - -/* Realloc memory. */ -void * -_gcry_secmem_realloc (void *p, size_t newsize) -{ - memblock_t *mb; - size_t size; - void *a; - - SECMEM_LOCK; - - mb = (memblock_t *) ((char *) p - ((size_t) &((memblock_t *) 0)->aligned.c)); - size = mb->size; - if (newsize < size) - { - /* It is easier to not shrink the memory. */ - a = p; - } - else - { - a = _gcry_secmem_malloc_internal (newsize); - if (a) - { - memcpy (a, p, size); - memset ((char *) a + size, 0, newsize - size); - _gcry_secmem_free_internal (p); - } - } - - SECMEM_UNLOCK; - - return a; -} - - -/* Return true if P points into the secure memory area. */ -int -_gcry_private_is_secure (const void *p) -{ - return pool_okay && ptr_into_pool_p (p); -} - - -/**************** - * Warning: This code might be called by an interrupt handler - * and frankly, there should really be such a handler, - * to make sure that the memory is wiped out. - * We hope that the OS wipes out mlocked memory after - * receiving a SIGKILL - it really should do so, otherwise - * there is no chance to get the secure memory cleaned. - */ -void -_gcry_secmem_term () -{ - if (!pool_okay) - return; - - wipememory2 (pool, 0xff, pool_size); - wipememory2 (pool, 0xaa, pool_size); - wipememory2 (pool, 0x55, pool_size); - wipememory2 (pool, 0x00, pool_size); -#if HAVE_MMAP - if (pool_is_mmapped) - munmap (pool, pool_size); -#endif - pool = NULL; - pool_okay = 0; - pool_size = 0; - not_locked = 0; -} - - -void -_gcry_secmem_dump_stats () -{ -#if 1 - SECMEM_LOCK; - - if (pool_okay) - log_info ("secmem usage: %u/%lu bytes in %u blocks\n", - cur_alloced, (unsigned long)pool_size, cur_blocks); - SECMEM_UNLOCK; -#else - memblock_t *mb; - int i; - - SECMEM_LOCK; - - for (i = 0, mb = (memblock_t *) pool; - ptr_into_pool_p (mb); - mb = mb_get_next (mb), i++) - log_info ("SECMEM: [%s] block: %i; size: %i\n", - (mb->flags & MB_FLAG_ACTIVE) ? "used" : "free", - i, - mb->size); - SECMEM_UNLOCK; -#endif -} diff --git a/grub-core/lib/libgcrypt/src/secmem.h b/grub-core/lib/libgcrypt/src/secmem.h deleted file mode 100644 index 29e151af4..000000000 --- a/grub-core/lib/libgcrypt/src/secmem.h +++ /dev/null @@ -1,39 +0,0 @@ -/* secmem.h - internal definitions for secmem - * 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 - */ - -#ifndef G10_SECMEM_H -#define G10_SECMEM_H 1 - -void _gcry_secmem_init (size_t npool); -void _gcry_secmem_term (void); -void *_gcry_secmem_malloc (size_t size) _GCRY_GCC_ATTR_MALLOC; -void *_gcry_secmem_realloc (void *a, size_t newsize); -void _gcry_secmem_free (void *a); -void _gcry_secmem_dump_stats (void); -void _gcry_secmem_set_flags (unsigned flags); -unsigned _gcry_secmem_get_flags(void); -int _gcry_private_is_secure (const void *p); - -/* Flags for _gcry_secmem_{set,get}_flags. */ -#define GCRY_SECMEM_FLAG_NO_WARNING (1 << 0) -#define GCRY_SECMEM_FLAG_SUSPEND_WARNING (1 << 1) -#define GCRY_SECMEM_FLAG_NOT_LOCKED (1 << 2) - -#endif /* G10_SECMEM_H */ diff --git a/grub-core/lib/libgcrypt/src/sexp.c b/grub-core/lib/libgcrypt/src/sexp.c deleted file mode 100644 index 78013fdf3..000000000 --- a/grub-core/lib/libgcrypt/src/sexp.c +++ /dev/null @@ -1,2045 +0,0 @@ -/* sexp.c - S-Expression handling - * Copyright (C) 1999, 2000, 2001, 2002, 2003, - * 2004, 2006, 2007, 2008, 2011 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 -#include -#include -#include -#include -#include -#include - -#define GCRYPT_NO_MPI_MACROS 1 -#include "g10lib.h" - -typedef struct gcry_sexp *NODE; -typedef unsigned short DATALEN; - -struct gcry_sexp -{ - byte d[1]; -}; - -#define ST_STOP 0 -#define ST_DATA 1 /* datalen follows */ -#define ST_HINT 2 /* datalen follows */ -#define ST_OPEN 3 -#define ST_CLOSE 4 - -/* the atoi macros assume that the buffer has only valid digits */ -#define atoi_1(p) (*(p) - '0' ) -#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ - *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) - -#define TOKEN_SPECIALS "-./_:*+=" - -static gcry_error_t -vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, - const char *buffer, size_t length, int argflag, - void **arg_list, va_list arg_ptr); - -static gcry_error_t -sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, - const char *buffer, size_t length, int argflag, - void **arg_list, ...); - -/* Return true if P points to a byte containing a whitespace according - to the S-expressions definition. */ -#undef whitespacep -static GPG_ERR_INLINE int -whitespacep (const char *p) -{ - switch (*p) - { - case ' ': case '\t': case '\v': case '\f': case '\r': case '\n': return 1; - default: return 0; - } -} - - -#if 0 -static void -dump_mpi( gcry_mpi_t a ) -{ - char buffer[1000]; - size_t n = 1000; - - if( !a ) - fputs("[no MPI]", stderr ); - else if( gcry_mpi_print( GCRYMPI_FMT_HEX, buffer, &n, a ) ) - fputs("[MPI too large to print]", stderr ); - else - fputs( buffer, stderr ); -} -#endif - -static void -dump_string (const byte *p, size_t n, int delim ) -{ - for (; n; n--, p++ ) - { - if ((*p & 0x80) || iscntrl( *p ) || *p == delim ) - { - if( *p == '\n' ) - log_printf ("\\n"); - else if( *p == '\r' ) - log_printf ("\\r"); - else if( *p == '\f' ) - log_printf ("\\f"); - else if( *p == '\v' ) - log_printf ("\\v"); - else if( *p == '\b' ) - log_printf ("\\b"); - else if( !*p ) - log_printf ("\\0"); - else - log_printf ("\\x%02x", *p ); - } - else - log_printf ("%c", *p); - } -} - - -void -gcry_sexp_dump (const gcry_sexp_t a) -{ - const byte *p; - int indent = 0; - int type; - - if (!a) - { - log_printf ( "[nil]\n"); - return; - } - - p = a->d; - while ( (type = *p) != ST_STOP ) - { - p++; - switch ( type ) - { - case ST_OPEN: - log_printf ("%*s[open]\n", 2*indent, ""); - indent++; - break; - case ST_CLOSE: - if( indent ) - indent--; - log_printf ("%*s[close]\n", 2*indent, ""); - break; - case ST_DATA: { - DATALEN n; - memcpy ( &n, p, sizeof n ); - p += sizeof n; - log_printf ("%*s[data=\"", 2*indent, "" ); - dump_string (p, n, '\"' ); - log_printf ("\"]\n"); - p += n; - } - break; - default: - log_printf ("%*s[unknown tag %d]\n", 2*indent, "", type); - break; - } - } -} - -/**************** - * Pass list through except when it is an empty list - in that case - * return NULL and release the passed list. - */ -static gcry_sexp_t -normalize ( gcry_sexp_t list ) -{ - unsigned char *p; - - if ( !list ) - return NULL; - p = list->d; - if ( *p == ST_STOP ) - { - /* this is "" */ - gcry_sexp_release ( list ); - return NULL; - } - if ( *p == ST_OPEN && p[1] == ST_CLOSE ) - { - /* this is "()" */ - gcry_sexp_release ( list ); - return NULL; - } - - return list; -} - -/* Create a new S-expression object by reading LENGTH bytes from - BUFFER, assuming it is canonical encoded or autodetected encoding - when AUTODETECT is set to 1. With FREEFNC not NULL, ownership of - the buffer is transferred to the newly created object. FREEFNC - should be the freefnc used to release BUFFER; there is no guarantee - at which point this function is called; most likey you want to use - free() or gcry_free(). - - Passing LENGTH and AUTODETECT as 0 is allowed to indicate that - BUFFER points to a valid canonical encoded S-expression. A LENGTH - of 0 and AUTODETECT 1 indicates that buffer points to a - null-terminated string. - - This function returns 0 and and the pointer to the new object in - RETSEXP or an error code in which case RETSEXP is set to NULL. */ -gcry_error_t -gcry_sexp_create (gcry_sexp_t *retsexp, void *buffer, size_t length, - int autodetect, void (*freefnc)(void*) ) -{ - gcry_error_t errcode; - gcry_sexp_t se; - - if (!retsexp) - return gcry_error (GPG_ERR_INV_ARG); - *retsexp = NULL; - if (autodetect < 0 || autodetect > 1 || !buffer) - return gcry_error (GPG_ERR_INV_ARG); - - if (!length && !autodetect) - { /* What a brave caller to assume that there is really a canonical - encoded S-expression in buffer */ - length = gcry_sexp_canon_len (buffer, 0, NULL, &errcode); - if (!length) - return errcode; - } - else if (!length && autodetect) - { /* buffer is a string */ - length = strlen ((char *)buffer); - } - - errcode = sexp_sscan (&se, NULL, buffer, length, 0, NULL); - if (errcode) - return errcode; - - *retsexp = se; - if (freefnc) - { - /* For now we release the buffer immediately. As soon as we - have changed the internal represenation of S-expression to - the canoncial format - which has the advantage of faster - parsing - we will use this function as a closure in our - GCRYSEXP object and use the BUFFER directly. */ - freefnc (buffer); - } - return gcry_error (GPG_ERR_NO_ERROR); -} - -/* Same as gcry_sexp_create but don't transfer ownership */ -gcry_error_t -gcry_sexp_new (gcry_sexp_t *retsexp, const void *buffer, size_t length, - int autodetect) -{ - return gcry_sexp_create (retsexp, (void *)buffer, length, autodetect, NULL); -} - - -/**************** - * Release resource of the given SEXP object. - */ -void -gcry_sexp_release( gcry_sexp_t sexp ) -{ - if (sexp) - { - if (gcry_is_secure (sexp)) - { - /* Extra paranoid wiping. */ - const byte *p = sexp->d; - int type; - - while ( (type = *p) != ST_STOP ) - { - p++; - switch ( type ) - { - case ST_OPEN: - break; - case ST_CLOSE: - break; - case ST_DATA: - { - DATALEN n; - memcpy ( &n, p, sizeof n ); - p += sizeof n; - p += n; - } - break; - default: - break; - } - } - wipememory (sexp->d, p - sexp->d); - } - gcry_free ( sexp ); - } -} - - -/**************** - * Make a pair from lists a and b, don't use a or b later on. - * Special behaviour: If one is a single element list we put the - * element straight into the new pair. - */ -gcry_sexp_t -gcry_sexp_cons( const gcry_sexp_t a, const gcry_sexp_t b ) -{ - (void)a; - (void)b; - - /* NYI: Implementation should be quite easy with our new data - representation */ - BUG (); - return NULL; -} - - -/**************** - * Make a list from all items in the array the end of the array is marked - * with a NULL. - */ -gcry_sexp_t -gcry_sexp_alist( const gcry_sexp_t *array ) -{ - (void)array; - - /* NYI: Implementation should be quite easy with our new data - representation. */ - BUG (); - return NULL; -} - -/**************** - * Make a list from all items, the end of list is indicated by a NULL - */ -gcry_sexp_t -gcry_sexp_vlist( const gcry_sexp_t a, ... ) -{ - (void)a; - /* NYI: Implementation should be quite easy with our new data - representation. */ - BUG (); - return NULL; -} - - -/**************** - * Append n to the list a - * Returns: a new ist (which maybe a) - */ -gcry_sexp_t -gcry_sexp_append( const gcry_sexp_t a, const gcry_sexp_t n ) -{ - (void)a; - (void)n; - /* NYI: Implementation should be quite easy with our new data - representation. */ - BUG (); - return NULL; -} - -gcry_sexp_t -gcry_sexp_prepend( const gcry_sexp_t a, const gcry_sexp_t n ) -{ - (void)a; - (void)n; - /* NYI: Implementation should be quite easy with our new data - representation. */ - BUG (); - return NULL; -} - - - -/**************** - * Locate token in a list. The token must be the car of a sublist. - * Returns: A new list with this sublist or NULL if not found. - */ -gcry_sexp_t -gcry_sexp_find_token( const gcry_sexp_t list, const char *tok, size_t toklen ) -{ - const byte *p; - DATALEN n; - - if ( !list ) - return NULL; - - if ( !toklen ) - toklen = strlen(tok); - - p = list->d; - while ( *p != ST_STOP ) - { - if ( *p == ST_OPEN && p[1] == ST_DATA ) - { - const byte *head = p; - - p += 2; - memcpy ( &n, p, sizeof n ); - p += sizeof n; - if ( n == toklen && !memcmp( p, tok, toklen ) ) - { /* found it */ - gcry_sexp_t newlist; - byte *d; - int level = 1; - - /* Look for the end of the list. */ - for ( p += n; level; p++ ) - { - if ( *p == ST_DATA ) - { - memcpy ( &n, ++p, sizeof n ); - p += sizeof n + n; - p--; /* Compensate for later increment. */ - } - else if ( *p == ST_OPEN ) - { - level++; - } - else if ( *p == ST_CLOSE ) - { - level--; - } - else if ( *p == ST_STOP ) - { - BUG (); - } - } - n = p - head; - - newlist = gcry_malloc ( sizeof *newlist + n ); - if (!newlist) - { - /* No way to return an error code, so we can only - return Not Found. */ - return NULL; - } - d = newlist->d; - memcpy ( d, head, n ); d += n; - *d++ = ST_STOP; - return normalize ( newlist ); - } - p += n; - } - else if ( *p == ST_DATA ) - { - memcpy ( &n, ++p, sizeof n ); p += sizeof n; - p += n; - } - else - p++; - } - return NULL; -} - -/**************** - * Return the length of the given list - */ -int -gcry_sexp_length( const gcry_sexp_t list ) -{ - const byte *p; - DATALEN n; - int type; - int length = 0; - int level = 0; - - if ( !list ) - return 0; - - p = list->d; - while ( (type=*p) != ST_STOP ) { - p++; - if ( type == ST_DATA ) { - memcpy ( &n, p, sizeof n ); - p += sizeof n + n; - if ( level == 1 ) - length++; - } - else if ( type == ST_OPEN ) { - if ( level == 1 ) - length++; - level++; - } - else if ( type == ST_CLOSE ) { - level--; - } - } - return length; -} - - -/* Return the internal lengths offset of LIST. That is the size of - the buffer from the first ST_OPEN, which is retruned at R_OFF, to - the corresponding ST_CLOSE inclusive. */ -static size_t -get_internal_buffer (const gcry_sexp_t list, size_t *r_off) -{ - const unsigned char *p; - DATALEN n; - int type; - int level = 0; - - *r_off = 0; - if (list) - { - p = list->d; - while ( (type=*p) != ST_STOP ) - { - p++; - if (type == ST_DATA) - { - memcpy (&n, p, sizeof n); - p += sizeof n + n; - } - else if (type == ST_OPEN) - { - if (!level) - *r_off = (p-1) - list->d; - level++; - } - else if ( type == ST_CLOSE ) - { - level--; - if (!level) - return p - list->d; - } - } - } - return 0; /* Not a proper list. */ -} - - - -/* Extract the CAR of the given list. May return NULL for bad lists - or memory failure. */ -gcry_sexp_t -gcry_sexp_nth( const gcry_sexp_t list, int number ) -{ - const byte *p; - DATALEN n; - gcry_sexp_t newlist; - byte *d; - int level = 0; - - if ( !list || list->d[0] != ST_OPEN ) - return NULL; - p = list->d; - - while ( number > 0 ) { - p++; - if ( *p == ST_DATA ) { - memcpy ( &n, ++p, sizeof n ); - p += sizeof n + n; - p--; - if ( !level ) - number--; - } - else if ( *p == ST_OPEN ) { - level++; - } - else if ( *p == ST_CLOSE ) { - level--; - if ( !level ) - number--; - } - else if ( *p == ST_STOP ) { - return NULL; - } - } - p++; - - if ( *p == ST_DATA ) { - memcpy ( &n, p, sizeof n ); - /* Allocate 1 (=sizeof *newlist) byte for ST_OPEN - 1 byte for ST_DATA - sizeof n byte for n - n byte for the data - 1 byte for ST_CLOSE - 1 byte for ST_STOP */ - newlist = gcry_malloc ( sizeof *newlist + 1 + sizeof n + n + 2 ); - if (!newlist) - return NULL; - d = newlist->d; - *d = ST_OPEN; /* Put the ST_OPEN flag */ - d++; /* Move forward */ - /* Copy ST_DATA, n and the data from p to d */ - memcpy ( d, p, 1 + sizeof n + n ); - d += 1 + sizeof n + n; /* Move after the data copied */ - *d = ST_CLOSE; /* Put the ST_CLOSE flag */ - d++; /* Move forward */ - *d = ST_STOP; /* Put the ST_STOP flag */ - } - else if ( *p == ST_OPEN ) { - const byte *head = p; - - level = 1; - do { - p++; - if ( *p == ST_DATA ) { - memcpy ( &n, ++p, sizeof n ); - p += sizeof n + n; - p--; - } - else if ( *p == ST_OPEN ) { - level++; - } - else if ( *p == ST_CLOSE ) { - level--; - } - else if ( *p == ST_STOP ) { - BUG (); - } - } while ( level ); - n = p + 1 - head; - - newlist = gcry_malloc ( sizeof *newlist + n ); - if (!newlist) - return NULL; - d = newlist->d; - memcpy ( d, head, n ); d += n; - *d++ = ST_STOP; - } - else - newlist = NULL; - - return normalize (newlist); -} - -gcry_sexp_t -gcry_sexp_car( const gcry_sexp_t list ) -{ - return gcry_sexp_nth ( list, 0 ); -} - - -/* Helper to get data from the car. The returned value is valid as - long as the list is not modified. */ -static const char * -sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen) -{ - const byte *p; - DATALEN n; - int level = 0; - - *datalen = 0; - if ( !list ) - return NULL; - - p = list->d; - if ( *p == ST_OPEN ) - p++; /* Yep, a list. */ - else if (number) - return NULL; /* Not a list but N > 0 requested. */ - - /* Skip over N elements. */ - while ( number > 0 ) - { - if ( *p == ST_DATA ) - { - memcpy ( &n, ++p, sizeof n ); - p += sizeof n + n; - p--; - if ( !level ) - number--; - } - else if ( *p == ST_OPEN ) - { - level++; - } - else if ( *p == ST_CLOSE ) - { - level--; - if ( !level ) - number--; - } - else if ( *p == ST_STOP ) - { - return NULL; - } - p++; - } - - /* If this is data, return it. */ - if ( *p == ST_DATA ) - { - memcpy ( &n, ++p, sizeof n ); - *datalen = n; - return (const char*)p + sizeof n; - } - - return NULL; -} - - -/* Get data from the car. The returned value is valid as long as the - list is not modified. */ -const char * -gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen ) -{ - return sexp_nth_data (list, number, datalen); -} - - -/* Get a string from the car. The returned value is a malloced string - and needs to be freed by the caller. */ -char * -gcry_sexp_nth_string (const gcry_sexp_t list, int number) -{ - const char *s; - size_t n; - char *buf; - - s = sexp_nth_data (list, number, &n); - if (!s || n < 1 || (n+1) < 1) - return NULL; - buf = gcry_malloc (n+1); - if (!buf) - return NULL; - memcpy (buf, s, n); - buf[n] = 0; - return buf; -} - -/* - * Get a MPI from the car - */ -gcry_mpi_t -gcry_sexp_nth_mpi( gcry_sexp_t list, int number, int mpifmt ) -{ - const char *s; - size_t n; - gcry_mpi_t a; - - if ( !mpifmt ) - mpifmt = GCRYMPI_FMT_STD; - - s = sexp_nth_data (list, number, &n); - if (!s) - return NULL; - - if ( gcry_mpi_scan ( &a, mpifmt, s, n, NULL ) ) - return NULL; - - return a; -} - - -/**************** - * Get the CDR - */ -gcry_sexp_t -gcry_sexp_cdr( const gcry_sexp_t list ) -{ - const byte *p; - const byte *head; - DATALEN n; - gcry_sexp_t newlist; - byte *d; - int level = 0; - int skip = 1; - - if ( !list || list->d[0] != ST_OPEN ) - return NULL; - p = list->d; - - while ( skip > 0 ) { - p++; - if ( *p == ST_DATA ) { - memcpy ( &n, ++p, sizeof n ); - p += sizeof n + n; - p--; - if ( !level ) - skip--; - } - else if ( *p == ST_OPEN ) { - level++; - } - else if ( *p == ST_CLOSE ) { - level--; - if ( !level ) - skip--; - } - else if ( *p == ST_STOP ) { - return NULL; - } - } - p++; - - head = p; - level = 0; - do { - if ( *p == ST_DATA ) { - memcpy ( &n, ++p, sizeof n ); - p += sizeof n + n; - p--; - } - else if ( *p == ST_OPEN ) { - level++; - } - else if ( *p == ST_CLOSE ) { - level--; - } - else if ( *p == ST_STOP ) { - return NULL; - } - p++; - } while ( level ); - n = p - head; - - newlist = gcry_malloc ( sizeof *newlist + n + 2 ); - if (!newlist) - return NULL; - d = newlist->d; - *d++ = ST_OPEN; - memcpy ( d, head, n ); d += n; - *d++ = ST_CLOSE; - *d++ = ST_STOP; - - return normalize (newlist); -} - -gcry_sexp_t -gcry_sexp_cadr ( const gcry_sexp_t list ) -{ - gcry_sexp_t a, b; - - a = gcry_sexp_cdr ( list ); - b = gcry_sexp_car ( a ); - gcry_sexp_release ( a ); - return b; -} - - - -static int -hextobyte( const byte *s ) -{ - int c=0; - - if( *s >= '0' && *s <= '9' ) - c = 16 * (*s - '0'); - else if( *s >= 'A' && *s <= 'F' ) - c = 16 * (10 + *s - 'A'); - else if( *s >= 'a' && *s <= 'f' ) { - c = 16 * (10 + *s - 'a'); - } - s++; - if( *s >= '0' && *s <= '9' ) - c += *s - '0'; - else if( *s >= 'A' && *s <= 'F' ) - c += 10 + *s - 'A'; - else if( *s >= 'a' && *s <= 'f' ) { - c += 10 + *s - 'a'; - } - return c; -} - -struct make_space_ctx { - gcry_sexp_t sexp; - size_t allocated; - byte *pos; -}; - -static gpg_err_code_t -make_space ( struct make_space_ctx *c, size_t n ) -{ - size_t used = c->pos - c->sexp->d; - - if ( used + n + sizeof(DATALEN) + 1 >= c->allocated ) - { - gcry_sexp_t newsexp; - byte *newhead; - size_t newsize; - - newsize = c->allocated + 2*(n+sizeof(DATALEN)+1); - if (newsize <= c->allocated) - return GPG_ERR_TOO_LARGE; - newsexp = gcry_realloc ( c->sexp, sizeof *newsexp + newsize - 1); - if (!newsexp) - return gpg_err_code_from_errno (errno); - c->allocated = newsize; - newhead = newsexp->d; - c->pos = newhead + used; - c->sexp = newsexp; - } - return 0; -} - - -/* Unquote STRING of LENGTH and store it into BUF. The surrounding - quotes are must already be removed from STRING. We assume that the - quoted string is syntacillay correct. */ -static size_t -unquote_string (const char *string, size_t length, unsigned char *buf) -{ - int esc = 0; - const unsigned char *s = (const unsigned char*)string; - unsigned char *d = buf; - size_t n = length; - - for (; n; n--, s++) - { - if (esc) - { - switch (*s) - { - case 'b': *d++ = '\b'; break; - case 't': *d++ = '\t'; break; - case 'v': *d++ = '\v'; break; - case 'n': *d++ = '\n'; break; - case 'f': *d++ = '\f'; break; - case 'r': *d++ = '\r'; break; - case '"': *d++ = '\"'; break; - case '\'': *d++ = '\''; break; - case '\\': *d++ = '\\'; break; - - case '\r': /* ignore CR[,LF] */ - if (n>1 && s[1] == '\n') - { - s++; n--; - } - break; - - case '\n': /* ignore LF[,CR] */ - if (n>1 && s[1] == '\r') - { - s++; n--; - } - break; - - case 'x': /* hex value */ - if (n>2 && hexdigitp (s+1) && hexdigitp (s+2)) - { - s++; n--; - *d++ = xtoi_2 (s); - s++; n--; - } - break; - - default: - if (n>2 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2)) - { - *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2); - s += 2; - n -= 2; - } - break; - } - esc = 0; - } - else if( *s == '\\' ) - esc = 1; - else - *d++ = *s; - } - - return d - buf; -} - -/**************** - * Scan the provided buffer and return the S expression in our internal - * format. Returns a newly allocated expression. If erroff is not NULL and - * a parsing error has occurred, the offset into buffer will be returned. - * If ARGFLAG is true, the function supports some printf like - * expressions. - * These are: - * %m - MPI - * %s - string (no autoswitch to secure allocation) - * %d - integer stored as string (no autoswitch to secure allocation) - * %b - memory buffer; this takes _two_ arguments: an integer with the - * length of the buffer and a pointer to the buffer. - * %S - Copy an gcry_sexp_t here. The S-expression needs to be a - * regular one, starting with a parenthesis. - * (no autoswitch to secure allocation) - * all other format elements are currently not defined and return an error. - * this includes the "%%" sequence becauce the percent sign is not an - * allowed character. - * FIXME: We should find a way to store the secure-MPIs not in the string - * but as reference to somewhere - this can help us to save huge amounts - * of secure memory. The problem is, that if only one element is secure, all - * other elements are automagicaly copied to secure memory too, so the most - * common operation gcry_sexp_cdr_mpi() will always return a secure MPI - * regardless whether it is needed or not. - */ -static gcry_error_t -vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, - const char *buffer, size_t length, int argflag, - void **arg_list, va_list arg_ptr) -{ - gcry_err_code_t err = 0; - static const char tokenchars[] = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789-./_:*+="; - const char *p; - size_t n; - const char *digptr = NULL; - const char *quoted = NULL; - const char *tokenp = NULL; - const char *hexfmt = NULL; - const char *base64 = NULL; - const char *disphint = NULL; - const char *percent = NULL; - int hexcount = 0; - int quoted_esc = 0; - int datalen = 0; - size_t dummy_erroff; - struct make_space_ctx c; - int arg_counter = 0; - int level = 0; - - if (!erroff) - erroff = &dummy_erroff; - - /* Depending on whether ARG_LIST is non-zero or not, this macro gives - us the next argument, either from the variable argument list as - specified by ARG_PTR or from the argument array ARG_LIST. */ -#define ARG_NEXT(storage, type) \ - do \ - { \ - if (!arg_list) \ - storage = va_arg (arg_ptr, type); \ - else \ - storage = *((type *) (arg_list[arg_counter++])); \ - } \ - while (0) - - /* The MAKE_SPACE macro is used before each store operation to - ensure that the buffer is large enough. It requires a global - context named C and jumps out to the label LEAVE on error! It - also sets ERROFF using the variables BUFFER and P. */ -#define MAKE_SPACE(n) do { \ - gpg_err_code_t _ms_err = make_space (&c, (n)); \ - if (_ms_err) \ - { \ - err = _ms_err; \ - *erroff = p - buffer; \ - goto leave; \ - } \ - } while (0) - - /* The STORE_LEN macro is used to store the length N at buffer P. */ -#define STORE_LEN(p,n) do { \ - DATALEN ashort = (n); \ - memcpy ( (p), &ashort, sizeof(ashort) ); \ - (p) += sizeof (ashort); \ - } while (0) - - /* We assume that the internal representation takes less memory than - the provided one. However, we add space for one extra datalen so - that the code which does the ST_CLOSE can use MAKE_SPACE */ - c.allocated = length + sizeof(DATALEN); - if (buffer && length && gcry_is_secure (buffer)) - c.sexp = gcry_malloc_secure (sizeof *c.sexp + c.allocated - 1); - else - c.sexp = gcry_malloc (sizeof *c.sexp + c.allocated - 1); - if (!c.sexp) - { - err = gpg_err_code_from_errno (errno); - *erroff = 0; - goto leave; - } - c.pos = c.sexp->d; - - for (p = buffer, n = length; n; p++, n--) - { - if (tokenp && !hexfmt) - { - if (strchr (tokenchars, *p)) - continue; - else - { - datalen = p - tokenp; - MAKE_SPACE (datalen); - *c.pos++ = ST_DATA; - STORE_LEN (c.pos, datalen); - memcpy (c.pos, tokenp, datalen); - c.pos += datalen; - tokenp = NULL; - } - } - - if (quoted) - { - if (quoted_esc) - { - switch (*p) - { - case 'b': case 't': case 'v': case 'n': case 'f': - case 'r': case '"': case '\'': case '\\': - quoted_esc = 0; - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - if (!((n > 2) - && (p[1] >= '0') && (p[1] <= '7') - && (p[2] >= '0') && (p[2] <= '7'))) - { - *erroff = p - buffer; - /* Invalid octal value. */ - err = GPG_ERR_SEXP_BAD_QUOTATION; - goto leave; - } - p += 2; - n -= 2; - quoted_esc = 0; - break; - - case 'x': - if (!((n > 2) && hexdigitp (p+1) && hexdigitp (p+2))) - { - *erroff = p - buffer; - /* Invalid hex value. */ - err = GPG_ERR_SEXP_BAD_QUOTATION; - goto leave; - } - p += 2; - n -= 2; - quoted_esc = 0; - break; - - case '\r': - /* ignore CR[,LF] */ - if (n && (p[1] == '\n')) - { - p++; - n--; - } - quoted_esc = 0; - break; - - case '\n': - /* ignore LF[,CR] */ - if (n && (p[1] == '\r')) - { - p++; - n--; - } - quoted_esc = 0; - break; - - default: - *erroff = p - buffer; - /* Invalid quoted string escape. */ - err = GPG_ERR_SEXP_BAD_QUOTATION; - goto leave; - } - } - else if (*p == '\\') - quoted_esc = 1; - else if (*p == '\"') - { - /* Keep it easy - we know that the unquoted string will - never be larger. */ - unsigned char *save; - size_t len; - - quoted++; /* Skip leading quote. */ - MAKE_SPACE (p - quoted); - *c.pos++ = ST_DATA; - save = c.pos; - STORE_LEN (c.pos, 0); /* Will be fixed up later. */ - len = unquote_string (quoted, p - quoted, c.pos); - c.pos += len; - STORE_LEN (save, len); - quoted = NULL; - } - } - else if (hexfmt) - { - if (isxdigit (*p)) - hexcount++; - else if (*p == '#') - { - if ((hexcount & 1)) - { - *erroff = p - buffer; - err = GPG_ERR_SEXP_ODD_HEX_NUMBERS; - goto leave; - } - - datalen = hexcount / 2; - MAKE_SPACE (datalen); - *c.pos++ = ST_DATA; - STORE_LEN (c.pos, datalen); - for (hexfmt++; hexfmt < p; hexfmt++) - { - if (whitespacep (hexfmt)) - continue; - *c.pos++ = hextobyte ((const unsigned char*)hexfmt); - hexfmt++; - } - hexfmt = NULL; - } - else if (!whitespacep (p)) - { - *erroff = p - buffer; - err = GPG_ERR_SEXP_BAD_HEX_CHAR; - goto leave; - } - } - else if (base64) - { - if (*p == '|') - base64 = NULL; - } - else if (digptr) - { - if (digitp (p)) - ; - else if (*p == ':') - { - datalen = atoi (digptr); /* FIXME: check for overflow. */ - digptr = NULL; - if (datalen > n - 1) - { - *erroff = p - buffer; - /* Buffer too short. */ - err = GPG_ERR_SEXP_STRING_TOO_LONG; - goto leave; - } - /* Make a new list entry. */ - MAKE_SPACE (datalen); - *c.pos++ = ST_DATA; - STORE_LEN (c.pos, datalen); - memcpy (c.pos, p + 1, datalen); - c.pos += datalen; - n -= datalen; - p += datalen; - } - else if (*p == '\"') - { - digptr = NULL; /* We ignore the optional length. */ - quoted = p; - quoted_esc = 0; - } - else if (*p == '#') - { - digptr = NULL; /* We ignore the optional length. */ - hexfmt = p; - hexcount = 0; - } - else if (*p == '|') - { - digptr = NULL; /* We ignore the optional length. */ - base64 = p; - } - else - { - *erroff = p - buffer; - err = GPG_ERR_SEXP_INV_LEN_SPEC; - goto leave; - } - } - else if (percent) - { - if (*p == 'm' || *p == 'M') - { - /* Insert an MPI. */ - gcry_mpi_t m; - size_t nm = 0; - int mpifmt = *p == 'm'? GCRYMPI_FMT_STD: GCRYMPI_FMT_USG; - - ARG_NEXT (m, gcry_mpi_t); - - if (gcry_mpi_get_flag (m, GCRYMPI_FLAG_OPAQUE)) - { - void *mp; - unsigned int nbits; - - mp = gcry_mpi_get_opaque (m, &nbits); - nm = (nbits+7)/8; - if (mp && nm) - { - MAKE_SPACE (nm); - if (!gcry_is_secure (c.sexp->d) - && gcry_mpi_get_flag (m, GCRYMPI_FLAG_SECURE)) - { - /* We have to switch to secure allocation. */ - gcry_sexp_t newsexp; - byte *newhead; - - newsexp = gcry_malloc_secure (sizeof *newsexp - + c.allocated - 1); - if (!newsexp) - { - err = gpg_err_code_from_errno (errno); - goto leave; - } - newhead = newsexp->d; - memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d)); - c.pos = newhead + (c.pos - c.sexp->d); - gcry_free (c.sexp); - c.sexp = newsexp; - } - - *c.pos++ = ST_DATA; - STORE_LEN (c.pos, nm); - memcpy (c.pos, mp, nm); - c.pos += nm; - } - } - else - { - if (gcry_mpi_print (mpifmt, NULL, 0, &nm, m)) - BUG (); - - MAKE_SPACE (nm); - if (!gcry_is_secure (c.sexp->d) - && gcry_mpi_get_flag ( m, GCRYMPI_FLAG_SECURE)) - { - /* We have to switch to secure allocation. */ - gcry_sexp_t newsexp; - byte *newhead; - - newsexp = gcry_malloc_secure (sizeof *newsexp - + c.allocated - 1); - if (!newsexp) - { - err = gpg_err_code_from_errno (errno); - goto leave; - } - newhead = newsexp->d; - memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d)); - c.pos = newhead + (c.pos - c.sexp->d); - gcry_free (c.sexp); - c.sexp = newsexp; - } - - *c.pos++ = ST_DATA; - STORE_LEN (c.pos, nm); - if (gcry_mpi_print (mpifmt, c.pos, nm, &nm, m)) - BUG (); - c.pos += nm; - } - } - else if (*p == 's') - { - /* Insert an string. */ - const char *astr; - size_t alen; - - ARG_NEXT (astr, const char *); - alen = strlen (astr); - - MAKE_SPACE (alen); - *c.pos++ = ST_DATA; - STORE_LEN (c.pos, alen); - memcpy (c.pos, astr, alen); - c.pos += alen; - } - else if (*p == 'b') - { - /* Insert a memory buffer. */ - const char *astr; - int alen; - - ARG_NEXT (alen, int); - ARG_NEXT (astr, const char *); - - MAKE_SPACE (alen); - if (alen - && !gcry_is_secure (c.sexp->d) - && gcry_is_secure (astr)) - { - /* We have to switch to secure allocation. */ - gcry_sexp_t newsexp; - byte *newhead; - - newsexp = gcry_malloc_secure (sizeof *newsexp - + c.allocated - 1); - if (!newsexp) - { - err = gpg_err_code_from_errno (errno); - goto leave; - } - newhead = newsexp->d; - memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d)); - c.pos = newhead + (c.pos - c.sexp->d); - gcry_free (c.sexp); - c.sexp = newsexp; - } - - *c.pos++ = ST_DATA; - STORE_LEN (c.pos, alen); - memcpy (c.pos, astr, alen); - c.pos += alen; - } - else if (*p == 'd') - { - /* Insert an integer as string. */ - int aint; - size_t alen; - char buf[35]; - - ARG_NEXT (aint, int); - sprintf (buf, "%d", aint); - alen = strlen (buf); - MAKE_SPACE (alen); - *c.pos++ = ST_DATA; - STORE_LEN (c.pos, alen); - memcpy (c.pos, buf, alen); - c.pos += alen; - } - else if (*p == 'u') - { - /* Insert an unsigned integer as string. */ - unsigned int aint; - size_t alen; - char buf[35]; - - ARG_NEXT (aint, unsigned int); - sprintf (buf, "%u", aint); - alen = strlen (buf); - MAKE_SPACE (alen); - *c.pos++ = ST_DATA; - STORE_LEN (c.pos, alen); - memcpy (c.pos, buf, alen); - c.pos += alen; - } - else if (*p == 'S') - { - /* Insert a gcry_sexp_t. */ - gcry_sexp_t asexp; - size_t alen, aoff; - - ARG_NEXT (asexp, gcry_sexp_t); - alen = get_internal_buffer (asexp, &aoff); - if (alen) - { - MAKE_SPACE (alen); - memcpy (c.pos, asexp->d + aoff, alen); - c.pos += alen; - } - } - else - { - *erroff = p - buffer; - /* Invalid format specifier. */ - err = GPG_ERR_SEXP_INV_LEN_SPEC; - goto leave; - } - percent = NULL; - } - else if (*p == '(') - { - if (disphint) - { - *erroff = p - buffer; - /* Open display hint. */ - err = GPG_ERR_SEXP_UNMATCHED_DH; - goto leave; - } - MAKE_SPACE (0); - *c.pos++ = ST_OPEN; - level++; - } - else if (*p == ')') - { - /* Walk up. */ - if (disphint) - { - *erroff = p - buffer; - /* Open display hint. */ - err = GPG_ERR_SEXP_UNMATCHED_DH; - goto leave; - } - MAKE_SPACE (0); - *c.pos++ = ST_CLOSE; - level--; - } - else if (*p == '\"') - { - quoted = p; - quoted_esc = 0; - } - else if (*p == '#') - { - hexfmt = p; - hexcount = 0; - } - else if (*p == '|') - base64 = p; - else if (*p == '[') - { - if (disphint) - { - *erroff = p - buffer; - /* Open display hint. */ - err = GPG_ERR_SEXP_NESTED_DH; - goto leave; - } - disphint = p; - } - else if (*p == ']') - { - if (!disphint) - { - *erroff = p - buffer; - /* Open display hint. */ - err = GPG_ERR_SEXP_UNMATCHED_DH; - goto leave; - } - disphint = NULL; - } - else if (digitp (p)) - { - if (*p == '0') - { - /* A length may not begin with zero. */ - *erroff = p - buffer; - err = GPG_ERR_SEXP_ZERO_PREFIX; - goto leave; - } - digptr = p; - } - else if (strchr (tokenchars, *p)) - tokenp = p; - else if (whitespacep (p)) - ; - else if (*p == '{') - { - /* fixme: handle rescanning: we can do this by saving our - current state and start over at p+1 -- Hmmm. At this - point here we are in a well defined state, so we don't - need to save it. Great. */ - *erroff = p - buffer; - err = GPG_ERR_SEXP_UNEXPECTED_PUNC; - goto leave; - } - else if (strchr ("&\\", *p)) - { - /* Reserved punctuation. */ - *erroff = p - buffer; - err = GPG_ERR_SEXP_UNEXPECTED_PUNC; - goto leave; - } - else if (argflag && (*p == '%')) - percent = p; - else - { - /* Bad or unavailable. */ - *erroff = p - buffer; - err = GPG_ERR_SEXP_BAD_CHARACTER; - goto leave; - } - } - MAKE_SPACE (0); - *c.pos++ = ST_STOP; - - if (level && !err) - err = GPG_ERR_SEXP_UNMATCHED_PAREN; - - leave: - if (err) - { - /* Error -> deallocate. */ - if (c.sexp) - { - /* Extra paranoid wipe on error. */ - if (gcry_is_secure (c.sexp)) - wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1); - gcry_free (c.sexp); - } - /* This might be expected by existing code... */ - *retsexp = NULL; - } - else - *retsexp = normalize (c.sexp); - - return gcry_error (err); -#undef MAKE_SPACE -#undef STORE_LEN -} - - -static gcry_error_t -sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, - const char *buffer, size_t length, int argflag, - void **arg_list, ...) -{ - gcry_error_t rc; - va_list arg_ptr; - - va_start (arg_ptr, arg_list); - rc = vsexp_sscan (retsexp, erroff, buffer, length, argflag, - arg_list, arg_ptr); - va_end (arg_ptr); - - return rc; -} - - -gcry_error_t -gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, const char *format, ...) -{ - gcry_error_t rc; - va_list arg_ptr; - - va_start (arg_ptr, format); - rc = vsexp_sscan (retsexp, erroff, format, strlen(format), 1, - NULL, arg_ptr); - va_end (arg_ptr); - - return rc; -} - - -gcry_error_t -_gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff, - const char *format, va_list arg_ptr) -{ - return vsexp_sscan (retsexp, erroff, format, strlen(format), 1, - NULL, arg_ptr); -} - - -/* Like gcry_sexp_build, but uses an array instead of variable - function arguments. */ -gcry_error_t -gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff, - const char *format, void **arg_list) -{ - return sexp_sscan (retsexp, erroff, format, strlen(format), 1, arg_list); -} - - -gcry_error_t -gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, - const char *buffer, size_t length) -{ - return sexp_sscan (retsexp, erroff, buffer, length, 0, NULL); -} - - -/* Figure out a suitable encoding for BUFFER of LENGTH. - Returns: 0 = Binary - 1 = String possible - 2 = Token possible -*/ -static int -suitable_encoding (const unsigned char *buffer, size_t length) -{ - const unsigned char *s; - int maybe_token = 1; - - if (!length) - return 1; - - for (s=buffer; length; s++, length--) - { - if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)) - && !strchr ("\b\t\v\n\f\r\"\'\\", *s)) - return 0; /*binary*/ - if ( maybe_token - && !alphap (s) && !digitp (s) && !strchr (TOKEN_SPECIALS, *s)) - maybe_token = 0; - } - s = buffer; - if ( maybe_token && !digitp (s) ) - return 2; - return 1; -} - - -static int -convert_to_hex (const unsigned char *src, size_t len, char *dest) -{ - int i; - - if (dest) - { - *dest++ = '#'; - for (i=0; i < len; i++, dest += 2 ) - sprintf (dest, "%02X", src[i]); - *dest++ = '#'; - } - return len*2+2; -} - -static int -convert_to_string (const unsigned char *s, size_t len, char *dest) -{ - if (dest) - { - char *p = dest; - *p++ = '\"'; - for (; len; len--, s++ ) - { - switch (*s) - { - case '\b': *p++ = '\\'; *p++ = 'b'; break; - case '\t': *p++ = '\\'; *p++ = 't'; break; - case '\v': *p++ = '\\'; *p++ = 'v'; break; - case '\n': *p++ = '\\'; *p++ = 'n'; break; - case '\f': *p++ = '\\'; *p++ = 'f'; break; - case '\r': *p++ = '\\'; *p++ = 'r'; break; - case '\"': *p++ = '\\'; *p++ = '\"'; break; - case '\'': *p++ = '\\'; *p++ = '\''; break; - case '\\': *p++ = '\\'; *p++ = '\\'; break; - default: - if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))) - { - sprintf (p, "\\x%02x", *s); - p += 4; - } - else - *p++ = *s; - } - } - *p++ = '\"'; - return p - dest; - } - else - { - int count = 2; - for (; len; len--, s++ ) - { - switch (*s) - { - case '\b': - case '\t': - case '\v': - case '\n': - case '\f': - case '\r': - case '\"': - case '\'': - case '\\': count += 2; break; - default: - if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))) - count += 4; - else - count++; - } - } - return count; - } -} - - - -static int -convert_to_token (const unsigned char *src, size_t len, char *dest) -{ - if (dest) - memcpy (dest, src, len); - return len; -} - - -/**************** - * Print SEXP to buffer using the MODE. Returns the length of the - * SEXP in buffer or 0 if the buffer is too short (We have at least an - * empty list consisting of 2 bytes). If a buffer of NULL is provided, - * the required length is returned. - */ -size_t -gcry_sexp_sprint (const gcry_sexp_t list, int mode, - void *buffer, size_t maxlength ) -{ - static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP }; - const unsigned char *s; - char *d; - DATALEN n; - char numbuf[20]; - size_t len = 0; - int i, indent = 0; - - s = list? list->d : empty; - d = buffer; - while ( *s != ST_STOP ) - { - switch ( *s ) - { - case ST_OPEN: - s++; - if ( mode != GCRYSEXP_FMT_CANON ) - { - if (indent) - len++; - len += indent; - } - len++; - if ( buffer ) - { - if ( len >= maxlength ) - return 0; - if ( mode != GCRYSEXP_FMT_CANON ) - { - if (indent) - *d++ = '\n'; - for (i=0; i < indent; i++) - *d++ = ' '; - } - *d++ = '('; - } - indent++; - break; - case ST_CLOSE: - s++; - len++; - if ( buffer ) - { - if ( len >= maxlength ) - return 0; - *d++ = ')'; - } - indent--; - if (*s != ST_OPEN && *s != ST_STOP && mode != GCRYSEXP_FMT_CANON) - { - len++; - len += indent; - if (buffer) - { - if (len >= maxlength) - return 0; - *d++ = '\n'; - for (i=0; i < indent; i++) - *d++ = ' '; - } - } - break; - case ST_DATA: - s++; - memcpy ( &n, s, sizeof n ); s += sizeof n; - if (mode == GCRYSEXP_FMT_ADVANCED) - { - int type; - size_t nn; - - switch ( (type=suitable_encoding (s, n))) - { - case 1: nn = convert_to_string (s, n, NULL); break; - case 2: nn = convert_to_token (s, n, NULL); break; - default: nn = convert_to_hex (s, n, NULL); break; - } - len += nn; - if (buffer) - { - if (len >= maxlength) - return 0; - switch (type) - { - case 1: convert_to_string (s, n, d); break; - case 2: convert_to_token (s, n, d); break; - default: convert_to_hex (s, n, d); break; - } - d += nn; - } - if (s[n] != ST_CLOSE) - { - len++; - if (buffer) - { - if (len >= maxlength) - return 0; - *d++ = ' '; - } - } - } - else - { - sprintf (numbuf, "%u:", (unsigned int)n ); - len += strlen (numbuf) + n; - if ( buffer ) - { - if ( len >= maxlength ) - return 0; - d = stpcpy ( d, numbuf ); - memcpy ( d, s, n ); d += n; - } - } - s += n; - break; - default: - BUG (); - } - } - if ( mode != GCRYSEXP_FMT_CANON ) - { - len++; - if (buffer) - { - if ( len >= maxlength ) - return 0; - *d++ = '\n'; - } - } - if (buffer) - { - if ( len >= maxlength ) - return 0; - *d++ = 0; /* for convenience we make a C string */ - } - else - len++; /* we need one byte more for this */ - - return len; -} - - -/* Scan a canonical encoded buffer with implicit length values and - return the actual length this S-expression uses. For a valid S-Exp - it should never return 0. If LENGTH is not zero, the maximum - length to scan is given - this can be used for syntax checks of - data passed from outside. errorcode and erroff may both be passed as - NULL. */ -size_t -gcry_sexp_canon_len (const unsigned char *buffer, size_t length, - size_t *erroff, gcry_error_t *errcode) -{ - const unsigned char *p; - const unsigned char *disphint = NULL; - unsigned int datalen = 0; - size_t dummy_erroff; - gcry_error_t dummy_errcode; - size_t count = 0; - int level = 0; - - if (!erroff) - erroff = &dummy_erroff; - if (!errcode) - errcode = &dummy_errcode; - - *errcode = gcry_error (GPG_ERR_NO_ERROR); - *erroff = 0; - if (!buffer) - return 0; - if (*buffer != '(') - { - *errcode = gcry_error (GPG_ERR_SEXP_NOT_CANONICAL); - return 0; - } - - for (p=buffer; ; p++, count++ ) - { - if (length && count >= length) - { - *erroff = count; - *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG); - return 0; - } - - if (datalen) - { - if (*p == ':') - { - if (length && (count+datalen) >= length) - { - *erroff = count; - *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG); - return 0; - } - count += datalen; - p += datalen; - datalen = 0; - } - else if (digitp(p)) - datalen = datalen*10 + atoi_1(p); - else - { - *erroff = count; - *errcode = gcry_error (GPG_ERR_SEXP_INV_LEN_SPEC); - return 0; - } - } - else if (*p == '(') - { - if (disphint) - { - *erroff = count; - *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH); - return 0; - } - level++; - } - else if (*p == ')') - { /* walk up */ - if (!level) - { - *erroff = count; - *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_PAREN); - return 0; - } - if (disphint) - { - *erroff = count; - *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH); - return 0; - } - if (!--level) - return ++count; /* ready */ - } - else if (*p == '[') - { - if (disphint) - { - *erroff = count; - *errcode = gcry_error (GPG_ERR_SEXP_NESTED_DH); - return 0; - } - disphint = p; - } - else if (*p == ']') - { - if ( !disphint ) - { - *erroff = count; - *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH); - return 0; - } - disphint = NULL; - } - else if (digitp (p) ) - { - if (*p == '0') - { - *erroff = count; - *errcode = gcry_error (GPG_ERR_SEXP_ZERO_PREFIX); - return 0; - } - datalen = atoi_1 (p); - } - else if (*p == '&' || *p == '\\') - { - *erroff = count; - *errcode = gcry_error (GPG_ERR_SEXP_UNEXPECTED_PUNC); - return 0; - } - else - { - *erroff = count; - *errcode = gcry_error (GPG_ERR_SEXP_BAD_CHARACTER); - return 0; - } - } -} diff --git a/grub-core/lib/libgcrypt/src/stdmem.c b/grub-core/lib/libgcrypt/src/stdmem.c deleted file mode 100644 index 189da3720..000000000 --- a/grub-core/lib/libgcrypt/src/stdmem.c +++ /dev/null @@ -1,242 +0,0 @@ -/* stdmem.c - private memory allocator - * Copyright (C) 1998, 2000, 2002, 2005, 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 . - */ - -/* - * Description of the layered memory management in Libgcrypt: - * - * [User] - * | - * | - * \ / - * global.c: [MM entrance points] -----> [user callbacks] - * | | - * | | - * \ / \ / - * - * stdmem.c: [non-secure handlers] [secure handlers] - * - * | | - * | | - * \ / \ / - * - * stdmem.c: [ memory guard ] - * - * | | - * | | - * \ / \ / - * - * libc: [ MM functions ] secmem.c: [ secure MM functions] - */ - -#include -#include -#include -#include -#include -#include - -#include "g10lib.h" -#include "stdmem.h" -#include "secmem.h" - - - -#define MAGIC_NOR_BYTE 0x55 -#define MAGIC_SEC_BYTE 0xcc -#define MAGIC_END_BYTE 0xaa - -#if SIZEOF_UNSIGNED_LONG == 8 -#define EXTRA_ALIGN 4 -#else -#define EXTRA_ALIGN 0 -#endif - - -static int use_m_guard = 0; - -/**************** - * Warning: Never use this function after any of the functions - * here have been used. - */ -void -_gcry_private_enable_m_guard (void) -{ - use_m_guard = 1; -} - - -/* - * Allocate memory of size n. - * Return NULL if we are out of memory. - */ -void * -_gcry_private_malloc (size_t n) -{ - if (!n) - { - gpg_err_set_errno (EINVAL); - return NULL; /* Allocating 0 bytes is undefined - we better return - an error to detect such coding errors. */ - } - - if (use_m_guard) - { - char *p; - - if ( !(p = malloc (n + EXTRA_ALIGN+5)) ) - return NULL; - ((byte*)p)[EXTRA_ALIGN+0] = n; - ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ; - ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ; - ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_NOR_BYTE; - p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE; - return p+EXTRA_ALIGN+4; - } - else - { - return malloc( n ); - } -} - - -/* - * Allocate memory of size N from the secure memory pool. Return NULL - * if we are out of memory. - */ -void * -_gcry_private_malloc_secure (size_t n) -{ - if (!n) - { - gpg_err_set_errno (EINVAL); - return NULL; /* Allocating 0 bytes is undefined - better return an - error to detect such coding errors. */ - } - - if (use_m_guard) - { - char *p; - - if ( !(p = _gcry_secmem_malloc (n +EXTRA_ALIGN+ 5)) ) - return NULL; - ((byte*)p)[EXTRA_ALIGN+0] = n; - ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ; - ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ; - ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_SEC_BYTE; - p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE; - return p+EXTRA_ALIGN+4; - } - else - { - return _gcry_secmem_malloc( n ); - } -} - - -/* - * Realloc and clear the old space - * Return NULL if there is not enough memory. - */ -void * -_gcry_private_realloc ( void *a, size_t n ) -{ - if (use_m_guard) - { - unsigned char *p = a; - char *b; - size_t len; - - if (!a) - return _gcry_private_malloc(n); - - _gcry_private_check_heap(p); - len = p[-4]; - len |= p[-3] << 8; - len |= p[-2] << 16; - if( len >= n ) /* We don't shrink for now. */ - return a; - if (p[-1] == MAGIC_SEC_BYTE) - b = _gcry_private_malloc_secure(n); - else - b = _gcry_private_malloc(n); - if (!b) - return NULL; - memcpy (b, a, len); - memset (b+len, 0, n-len); - _gcry_private_free (p); - return b; - } - else if ( _gcry_private_is_secure(a) ) - { - return _gcry_secmem_realloc( a, n ); - } - else - { - return realloc( a, n ); - } -} - - -void -_gcry_private_check_heap (const void *a) -{ - if (use_m_guard) - { - const byte *p = a; - size_t len; - - if (!p) - return; - - if ( !(p[-1] == MAGIC_NOR_BYTE || p[-1] == MAGIC_SEC_BYTE) ) - _gcry_log_fatal ("memory at %p corrupted (underflow=%02x)\n", p, p[-1]); - len = p[-4]; - len |= p[-3] << 8; - len |= p[-2] << 16; - if ( p[len] != MAGIC_END_BYTE ) - _gcry_log_fatal ("memory at %p corrupted (overflow=%02x)\n", p, p[-1]); - } -} - - -/* - * Free a memory block allocated by this or the secmem module - */ -void -_gcry_private_free (void *a) -{ - unsigned char *p = a; - - if (!p) - return; - if (use_m_guard ) - { - _gcry_private_check_heap(p); - if ( _gcry_private_is_secure(a) ) - _gcry_secmem_free(p-EXTRA_ALIGN-4); - else - { - free(p-EXTRA_ALIGN-4); - } - } - else if ( _gcry_private_is_secure(a) ) - _gcry_secmem_free(p); - else - free(p); -} diff --git a/grub-core/lib/libgcrypt/src/stdmem.h b/grub-core/lib/libgcrypt/src/stdmem.h deleted file mode 100644 index b476e7e50..000000000 --- a/grub-core/lib/libgcrypt/src/stdmem.h +++ /dev/null @@ -1,32 +0,0 @@ -/* stdmem.h - internal definitions for stdmem - * Copyright (C) 2000, 2002, 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 - */ - -#ifndef G10_STDMEM_H -#define G10_STDMEM_H 1 - -void _gcry_private_enable_m_guard(void); - -void *_gcry_private_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC; -void *_gcry_private_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC; -void *_gcry_private_realloc (void *a, size_t n); -void _gcry_private_check_heap (const void *a); -void _gcry_private_free (void *a); - -#endif /* G10_STDMEM_H */ diff --git a/grub-core/lib/libgcrypt/src/types.h b/grub-core/lib/libgcrypt/src/types.h deleted file mode 100644 index ee0a62bb9..000000000 --- a/grub-core/lib/libgcrypt/src/types.h +++ /dev/null @@ -1,128 +0,0 @@ -/* types.h - some common typedefs - * Copyright (C) 1998, 2000, 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 - */ - -#ifndef GCRYPT_TYPES_H -#define GCRYPT_TYPES_H - - -/* The AC_CHECK_SIZEOF() in configure fails for some machines. - * we provide some fallback values here */ -#if !SIZEOF_UNSIGNED_SHORT -#undef SIZEOF_UNSIGNED_SHORT -#define SIZEOF_UNSIGNED_SHORT 2 -#endif -#if !SIZEOF_UNSIGNED_INT -#undef SIZEOF_UNSIGNED_INT -#define SIZEOF_UNSIGNED_INT 4 -#endif -#if !SIZEOF_UNSIGNED_LONG -#undef SIZEOF_UNSIGNED_LONG -#define SIZEOF_UNSIGNED_LONG 4 -#endif - - -#include - - -#ifndef HAVE_BYTE_TYPEDEF -#undef byte /* maybe there is a macro with this name */ -/* Windows typedefs byte in the rpc headers. Avoid warning about - double definition. */ -#if !(defined(_WIN32) && defined(cbNDRContext)) - typedef unsigned char byte; -#endif -#define HAVE_BYTE_TYPEDEF -#endif - -#ifndef HAVE_USHORT_TYPEDEF -#undef ushort /* maybe there is a macro with this name */ - typedef unsigned short ushort; -#define HAVE_USHORT_TYPEDEF -#endif - -#ifndef HAVE_ULONG_TYPEDEF -#undef ulong /* maybe there is a macro with this name */ - typedef unsigned long ulong; -#define HAVE_ULONG_TYPEDEF -#endif - -#ifndef HAVE_U16_TYPEDEF -#undef u16 /* maybe there is a macro with this name */ -#if SIZEOF_UNSIGNED_INT == 2 - typedef unsigned int u16; -#elif SIZEOF_UNSIGNED_SHORT == 2 - typedef unsigned short u16; -#else -#error no typedef for u16 -#endif -#define HAVE_U16_TYPEDEF -#endif - -#ifndef HAVE_U32_TYPEDEF -#undef u32 /* maybe there is a macro with this name */ -#if SIZEOF_UNSIGNED_INT == 4 - typedef unsigned int u32; -#elif SIZEOF_UNSIGNED_LONG == 4 - typedef unsigned long u32; -#else -#error no typedef for u32 -#endif -#define HAVE_U32_TYPEDEF -#endif - -/**************** - * Warning: Some systems segfault when this u64 typedef and - * the dummy code in cipher/md.c is not available. Examples are - * Solaris and IRIX. - */ -#ifndef HAVE_U64_TYPEDEF -#undef u64 /* maybe there is a macro with this name */ -#if SIZEOF_UNSIGNED_INT == 8 - typedef unsigned int u64; -#define U64_C(c) (c ## U) -#define HAVE_U64_TYPEDEF -#elif SIZEOF_UNSIGNED_LONG == 8 - typedef unsigned long u64; -#define U64_C(c) (c ## UL) -#define HAVE_U64_TYPEDEF -#elif SIZEOF_UNSIGNED_LONG_LONG == 8 - typedef unsigned long long u64; -#define U64_C(c) (c ## ULL) -#define HAVE_U64_TYPEDEF -#elif SIZEOF_UINT64_T == 8 - typedef uint64_t u64; -#define U64_C(c) (UINT64_C(c)) -#define HAVE_U64_TYPEDEF -#endif -#endif - -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; - -#endif /*GCRYPT_TYPES_H*/ diff --git a/grub-core/lib/libgcrypt/src/versioninfo.rc.in b/grub-core/lib/libgcrypt/src/versioninfo.rc.in deleted file mode 100644 index 3199521c9..000000000 --- a/grub-core/lib/libgcrypt/src/versioninfo.rc.in +++ /dev/null @@ -1,51 +0,0 @@ -/* versioninfo.rc.in - for libgcrypt - * Copyright (C) 2005, 2006 g10 Code GmbH - * - * 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 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 processed by configure to create versioninfo.rc */ - -#line __LINE__ "versioninfo.rc.in" - -#include - - -VS_VERSION_INFO VERSIONINFO - FILEVERSION @BUILD_FILEVERSION@ - PRODUCTVERSION @BUILD_FILEVERSION@ - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x21L -#else - FILEFLAGS 0x20L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "Provided under the terms of the GNU Lesser General Public License (LGPLv2.1+).\0" - VALUE "CompanyName", "g10 Code GmbH\0" - VALUE "FileDescription", "Libgcrypt - The GNU Crypto Library\0" - VALUE "FileVersion", "@LIBGCRYPT_LT_CURRENT@.@LIBGCRYPT_LT_AGE@.@LIBGCRYPT_LT_REVISION@.@BUILD_REVISION@\0" - VALUE "InternalName", "libgcrypt\0" - VALUE "LegalCopyright", "Copyright © 2012 Free Software Foundation, Inc.\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "libgcrypt.dll\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "libgcrypt\0" - VALUE "ProductVersion", "@VERSION@\0" - VALUE "SpecialBuild", "@BUILD_TIMESTAMP@\0" - END - END -END diff --git a/grub-core/lib/libgcrypt/src/visibility.c b/grub-core/lib/libgcrypt/src/visibility.c deleted file mode 100644 index 2fccb017b..000000000 --- a/grub-core/lib/libgcrypt/src/visibility.c +++ /dev/null @@ -1,1486 +0,0 @@ -/* visibility.c - Wrapper for all public functions. - * Copyright (C) 2007, 2008, 2011 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 . - */ - -#include -#include - -#define _GCRY_INCLUDED_BY_VISIBILITY_C -#include "g10lib.h" -#include "cipher-proto.h" - - - -const char * -gcry_strerror (gcry_error_t err) -{ - return _gcry_strerror (err); -} - -const char * -gcry_strsource (gcry_error_t err) -{ - return _gcry_strsource (err); -} - -gcry_err_code_t -gcry_err_code_from_errno (int err) -{ - return _gcry_err_code_from_errno (err); -} - -int -gcry_err_code_to_errno (gcry_err_code_t code) -{ - return _gcry_err_code_to_errno (code); -} - -gcry_error_t -gcry_err_make_from_errno (gcry_err_source_t source, int err) -{ - return _gcry_err_make_from_errno (source, err); -} - -gcry_err_code_t -gcry_error_from_errno (int err) -{ - return _gcry_error_from_errno (err); -} - -const char * -gcry_check_version (const char *req_version) -{ - return _gcry_check_version (req_version); -} - -gcry_error_t -gcry_control (enum gcry_ctl_cmds cmd, ...) -{ - gcry_error_t err; - va_list arg_ptr; - - va_start (arg_ptr, cmd); - err = _gcry_vcontrol (cmd, arg_ptr); - va_end(arg_ptr); - return err; -} - -gcry_error_t -gcry_sexp_new (gcry_sexp_t *retsexp, - const void *buffer, size_t length, - int autodetect) -{ - return _gcry_sexp_new (retsexp, buffer, length, autodetect); -} - -gcry_error_t -gcry_sexp_create (gcry_sexp_t *retsexp, - void *buffer, size_t length, - int autodetect, void (*freefnc) (void *)) -{ - return _gcry_sexp_create (retsexp, buffer, length, - autodetect, freefnc); -} - -gcry_error_t -gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, - const char *buffer, size_t length) -{ - return _gcry_sexp_sscan (retsexp, erroff, buffer, length); -} - -gcry_error_t -gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, - const char *format, ...) -{ - gcry_error_t err; - va_list arg_ptr; - - va_start (arg_ptr, format); - err = _gcry_sexp_vbuild (retsexp, erroff, format, arg_ptr); - va_end (arg_ptr); - return err; -} - -gcry_error_t -gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff, - const char *format, void **arg_list) -{ - return _gcry_sexp_build_array (retsexp, erroff, format, arg_list); -} - -void -gcry_sexp_release (gcry_sexp_t sexp) -{ - _gcry_sexp_release (sexp); -} - -size_t -gcry_sexp_canon_len (const unsigned char *buffer, size_t length, - size_t *erroff, gcry_error_t *errcode) -{ - return _gcry_sexp_canon_len (buffer, length, erroff, errcode); -} - -size_t -gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer, size_t maxlength) -{ - return _gcry_sexp_sprint (sexp, mode, buffer, maxlength); -} - -void -gcry_sexp_dump (const gcry_sexp_t a) -{ - _gcry_sexp_dump (a); -} - -gcry_sexp_t -gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b) -{ - return _gcry_sexp_cons (a, b); -} - -gcry_sexp_t -gcry_sexp_alist (const gcry_sexp_t *array) -{ - return _gcry_sexp_alist (array); -} - -gcry_sexp_t -gcry_sexp_vlist (const gcry_sexp_t a, ...) -{ - /* This is not yet implemented in sexp.c. */ - (void)a; - BUG (); - return NULL; -} - -gcry_sexp_t -gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n) -{ - return _gcry_sexp_append (a, n); -} - -gcry_sexp_t -gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n) -{ - return _gcry_sexp_prepend (a, n); -} - - -gcry_sexp_t -gcry_sexp_find_token (gcry_sexp_t list, const char *tok, size_t toklen) -{ - return _gcry_sexp_find_token (list, tok, toklen); -} - -int -gcry_sexp_length (const gcry_sexp_t list) -{ - return _gcry_sexp_length (list); -} - -gcry_sexp_t -gcry_sexp_nth (const gcry_sexp_t list, int number) -{ - return _gcry_sexp_nth (list, number); -} - -gcry_sexp_t -gcry_sexp_car (const gcry_sexp_t list) -{ - return _gcry_sexp_car (list); -} - -gcry_sexp_t -gcry_sexp_cdr (const gcry_sexp_t list) -{ - return _gcry_sexp_cdr (list); -} - -gcry_sexp_t -gcry_sexp_cadr (const gcry_sexp_t list) -{ - return _gcry_sexp_cadr (list); -} - -const char * -gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen) -{ - return _gcry_sexp_nth_data (list, number, datalen); -} - -char * -gcry_sexp_nth_string (gcry_sexp_t list, int number) -{ - return _gcry_sexp_nth_string (list, number); -} - -gcry_mpi_t -gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt) -{ - return _gcry_sexp_nth_mpi (list, number, mpifmt); -} - -gcry_mpi_t -gcry_mpi_new (unsigned int nbits) -{ - return _gcry_mpi_new (nbits); -} - -gcry_mpi_t -gcry_mpi_snew (unsigned int nbits) -{ - return _gcry_mpi_snew (nbits); -} - -void -gcry_mpi_release (gcry_mpi_t a) -{ - _gcry_mpi_release (a); -} - -gcry_mpi_t -gcry_mpi_copy (const gcry_mpi_t a) -{ - return _gcry_mpi_copy (a); -} - -gcry_mpi_t -gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u) -{ - return _gcry_mpi_set (w, u); -} - -gcry_mpi_t -gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u) -{ - return _gcry_mpi_set_ui (w, u); -} - -void -gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b) -{ - _gcry_mpi_swap (a, b); -} - -int -gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v) -{ - return _gcry_mpi_cmp (u, v); -} - -int -gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v) -{ - return _gcry_mpi_cmp_ui (u, v); -} - -gcry_error_t -gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format, - const void *buffer, size_t buflen, - size_t *nscanned) -{ - return _gcry_mpi_scan (ret_mpi, format, buffer, buflen, nscanned); -} - -gcry_error_t -gcry_mpi_print (enum gcry_mpi_format format, - unsigned char *buffer, size_t buflen, - size_t *nwritten, - const gcry_mpi_t a) -{ - return _gcry_mpi_print (format, buffer, buflen, nwritten, a); -} - -gcry_error_t -gcry_mpi_aprint (enum gcry_mpi_format format, - unsigned char **buffer, size_t *nwritten, - const gcry_mpi_t a) -{ - return _gcry_mpi_aprint (format, buffer, nwritten, a); -} - -void -gcry_mpi_dump (const gcry_mpi_t a) -{ - _gcry_mpi_dump (a); -} - -void -gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) -{ - _gcry_mpi_add (w, u, v); -} - -void -gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v) -{ - _gcry_mpi_add_ui (w, u, v); -} - -void -gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) -{ - _gcry_mpi_addm (w, u, v, m); -} - -void -gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) -{ - _gcry_mpi_sub (w, u, v); -} - -void -gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ) -{ - _gcry_mpi_sub_ui (w, u, v); -} - -void -gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) -{ - _gcry_mpi_subm (w, u, v, m); -} - -void -gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) -{ - _gcry_mpi_mul (w, u, v); -} - -void -gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ) -{ - _gcry_mpi_mul_ui (w, u, v); -} - -void -gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) -{ - _gcry_mpi_mulm (w, u, v, m); -} - -void -gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt) -{ - _gcry_mpi_mul_2exp (w, u, cnt); -} - -void -gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r, - gcry_mpi_t dividend, gcry_mpi_t divisor, int round) -{ - _gcry_mpi_div (q, r, dividend, divisor, round); -} - -void -gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor) -{ - _gcry_mpi_mod (r, dividend, divisor); -} - -void -gcry_mpi_powm (gcry_mpi_t w, const gcry_mpi_t b, const gcry_mpi_t e, - const gcry_mpi_t m) -{ - _gcry_mpi_powm (w, b, e, m); -} - -int -gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b) -{ - return _gcry_mpi_gcd (g, a, b); -} - -int -gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m) -{ - return _gcry_mpi_invm (x, a, m); -} - - -unsigned int -gcry_mpi_get_nbits (gcry_mpi_t a) -{ - return _gcry_mpi_get_nbits (a); -} - -int -gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n) -{ - return _gcry_mpi_test_bit (a, n); -} - -void -gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n) -{ - _gcry_mpi_set_bit (a, n); -} - -void -gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n) -{ - _gcry_mpi_clear_bit (a, n); -} - -void -gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n) -{ - _gcry_mpi_set_highbit (a, n); -} - -void -gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n) -{ - _gcry_mpi_clear_highbit (a, n); -} - -void -gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n) -{ - _gcry_mpi_rshift (x, a, n); -} - -void -gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n) -{ - _gcry_mpi_lshift (x, a, n); -} - -gcry_mpi_t -gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits) -{ - return _gcry_mpi_set_opaque (a, p, nbits); -} - -void * -gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits) -{ - return _gcry_mpi_get_opaque (a, nbits); -} - -void -gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag) -{ - _gcry_mpi_set_flag (a, flag); -} - -void -gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag) -{ - _gcry_mpi_clear_flag (a, flag); -} - -int -gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag) -{ - return _gcry_mpi_get_flag (a, flag); -} - -gcry_error_t -gcry_cipher_open (gcry_cipher_hd_t *handle, - int algo, int mode, unsigned int flags) -{ - if (!fips_is_operational ()) - { - *handle = NULL; - return gpg_error (fips_not_operational ()); - } - - return _gcry_cipher_open (handle, algo, mode, flags); -} - -void -gcry_cipher_close (gcry_cipher_hd_t h) -{ - _gcry_cipher_close (h); -} - -gcry_error_t -gcry_cipher_setkey (gcry_cipher_hd_t hd, const void *key, size_t keylen) -{ - if (!fips_is_operational ()) - return gpg_error (fips_not_operational ()); - - return _gcry_cipher_setkey (hd, key, keylen); -} - -gcry_error_t -gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen) -{ - if (!fips_is_operational ()) - return gpg_error (fips_not_operational ()); - - return _gcry_cipher_setiv (hd, iv, ivlen); -} - -gpg_error_t -gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen) -{ - if (!fips_is_operational ()) - return gpg_error (fips_not_operational ()); - - return _gcry_cipher_setctr (hd, ctr, ctrlen); -} - - -gcry_error_t -gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen) -{ - if (!fips_is_operational ()) - return gpg_error (fips_not_operational ()); - - return _gcry_cipher_ctl (h, cmd, buffer, buflen); -} - -gcry_error_t -gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer, size_t *nbytes) -{ - return _gcry_cipher_info (h, what, buffer, nbytes); -} - -gcry_error_t -gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes) -{ - if (!fips_is_operational ()) - return gpg_error (fips_not_operational ()); - - return _gcry_cipher_algo_info (algo, what, buffer, nbytes); -} - -const char * -gcry_cipher_algo_name (int algorithm) -{ - return _gcry_cipher_algo_name (algorithm); -} - -int -gcry_cipher_map_name (const char *name) -{ - return _gcry_cipher_map_name (name); -} - -int -gcry_cipher_mode_from_oid (const char *string) -{ - return _gcry_cipher_mode_from_oid (string); -} - -gcry_error_t -gcry_cipher_encrypt (gcry_cipher_hd_t h, - void *out, size_t outsize, - const void *in, size_t inlen) -{ - if (!fips_is_operational ()) - { - /* Make sure that the plaintext will never make it to OUT. */ - if (out) - memset (out, 0x42, outsize); - return gpg_error (fips_not_operational ()); - } - - return _gcry_cipher_encrypt (h, out, outsize, in, inlen); -} - -gcry_error_t -gcry_cipher_decrypt (gcry_cipher_hd_t h, - void *out, size_t outsize, - const void *in, size_t inlen) -{ - if (!fips_is_operational ()) - return gpg_error (fips_not_operational ()); - - return _gcry_cipher_decrypt (h, out, outsize, in, inlen); -} - -size_t -gcry_cipher_get_algo_keylen (int algo) -{ - return _gcry_cipher_get_algo_keylen (algo); -} - -size_t -gcry_cipher_get_algo_blklen (int algo) -{ - return _gcry_cipher_get_algo_blklen (algo); -} - -gcry_error_t -gcry_cipher_list (int *list, int *list_length) -{ - return _gcry_cipher_list (list, list_length); -} - -gcry_error_t -gcry_pk_encrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t pkey) -{ - if (!fips_is_operational ()) - { - *result = NULL; - return gpg_error (fips_not_operational ()); - } - return _gcry_pk_encrypt (result, data, pkey); -} - -gcry_error_t -gcry_pk_decrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey) -{ - if (!fips_is_operational ()) - { - *result = NULL; - return gpg_error (fips_not_operational ()); - } - return _gcry_pk_decrypt (result, data, skey); -} - -gcry_error_t -gcry_pk_sign (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey) -{ - if (!fips_is_operational ()) - { - *result = NULL; - return gpg_error (fips_not_operational ()); - } - return _gcry_pk_sign (result, data, skey); -} - -gcry_error_t -gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey) -{ - if (!fips_is_operational ()) - return gpg_error (fips_not_operational ()); - return _gcry_pk_verify (sigval, data, pkey); -} - -gcry_error_t -gcry_pk_testkey (gcry_sexp_t key) -{ - if (!fips_is_operational ()) - return gpg_error (fips_not_operational ()); - return _gcry_pk_testkey (key); -} - -gcry_error_t -gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms) -{ - if (!fips_is_operational ()) - { - *r_key = NULL; - return gpg_error (fips_not_operational ()); - } - return _gcry_pk_genkey (r_key, s_parms); -} - -gcry_error_t -gcry_pk_ctl (int cmd, void *buffer, size_t buflen) -{ - return _gcry_pk_ctl (cmd, buffer, buflen); -} - -gcry_error_t -gcry_pk_algo_info (int algo, int what, void *buffer, size_t *nbytes) -{ - if (!fips_is_operational ()) - return gpg_error (fips_not_operational ()); - - return _gcry_pk_algo_info (algo, what, buffer, nbytes); -} - -const char * -gcry_pk_algo_name (int algorithm) -{ - return _gcry_pk_algo_name (algorithm); -} - -int -gcry_pk_map_name (const char *name) -{ - return _gcry_pk_map_name (name); -} - -unsigned int -gcry_pk_get_nbits (gcry_sexp_t key) -{ - if (!fips_is_operational ()) - { - (void)fips_not_operational (); - return 0; - } - - return _gcry_pk_get_nbits (key); -} - -unsigned char * -gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array) -{ - if (!fips_is_operational ()) - { - (void)fips_not_operational (); - return NULL; - } - return _gcry_pk_get_keygrip (key, array); -} - -const char * -gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits) -{ - if (!fips_is_operational ()) - { - (void)fips_not_operational (); - return NULL; - } - return _gcry_pk_get_curve (key, iterator, r_nbits); -} - -gcry_sexp_t -gcry_pk_get_param (int algo, const char *name) -{ - if (!fips_is_operational ()) - { - (void)fips_not_operational (); - return NULL; - } - return _gcry_pk_get_param (algo, name); -} - -gcry_error_t -gcry_pk_list (int *list, int *list_length) -{ - return _gcry_pk_list (list, list_length); -} - -gcry_error_t -gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags) -{ - if (!fips_is_operational ()) - { - *h = NULL; - return gpg_error (fips_not_operational ()); - } - - return _gcry_md_open (h, algo, flags); -} - -void -gcry_md_close (gcry_md_hd_t hd) -{ - _gcry_md_close (hd); -} - -gcry_error_t -gcry_md_enable (gcry_md_hd_t hd, int algo) -{ - if (!fips_is_operational ()) - return gpg_error (fips_not_operational ()); - return _gcry_md_enable (hd, algo); -} - -gcry_error_t -gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd) -{ - if (!fips_is_operational ()) - { - *bhd = NULL; - return gpg_error (fips_not_operational ()); - } - return _gcry_md_copy (bhd, ahd); -} - -void -gcry_md_reset (gcry_md_hd_t hd) -{ - _gcry_md_reset (hd); -} - -gcry_error_t -gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen) -{ - if (!fips_is_operational ()) - return gpg_error (fips_not_operational ()); - return _gcry_md_ctl (hd, cmd, buffer, buflen); -} - -void -gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length) -{ - if (!fips_is_operational ()) - { - (void)fips_not_operational (); - return; - } - _gcry_md_write (hd, buffer, length); -} - -unsigned char * -gcry_md_read (gcry_md_hd_t hd, int algo) -{ - return _gcry_md_read (hd, algo); -} - -void -gcry_md_hash_buffer (int algo, void *digest, - const void *buffer, size_t length) -{ - if (!fips_is_operational ()) - { - (void)fips_not_operational (); - fips_signal_error ("called in non-operational state"); - } - _gcry_md_hash_buffer (algo, digest, buffer, length); -} - -int -gcry_md_get_algo (gcry_md_hd_t hd) -{ - if (!fips_is_operational ()) - { - (void)fips_not_operational (); - fips_signal_error ("used in non-operational state"); - return 0; - } - return _gcry_md_get_algo (hd); -} - -unsigned int -gcry_md_get_algo_dlen (int algo) -{ - return _gcry_md_get_algo_dlen (algo); -} - -int -gcry_md_is_enabled (gcry_md_hd_t a, int algo) -{ - if (!fips_is_operational ()) - { - (void)fips_not_operational (); - return 0; - } - - return _gcry_md_is_enabled (a, algo); -} - -int -gcry_md_is_secure (gcry_md_hd_t a) -{ - return _gcry_md_is_secure (a); -} - -gcry_error_t -gcry_md_info (gcry_md_hd_t h, int what, void *buffer, size_t *nbytes) -{ - if (!fips_is_operational ()) - return gpg_error (fips_not_operational ()); - - return _gcry_md_info (h, what, buffer, nbytes); -} - -gcry_error_t -gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes) -{ - return _gcry_md_algo_info (algo, what, buffer, nbytes); -} - -const char * -gcry_md_algo_name (int algo) -{ - return _gcry_md_algo_name (algo); -} - -int -gcry_md_map_name (const char* name) -{ - return _gcry_md_map_name (name); -} - -gcry_error_t -gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen) -{ - if (!fips_is_operational ()) - return gpg_error (fips_not_operational ()); - return _gcry_md_setkey (hd, key, keylen); -} - -void -gcry_md_debug (gcry_md_hd_t hd, const char *suffix) -{ - _gcry_md_debug (hd, suffix); -} - -gcry_error_t -gcry_md_list (int *list, int *list_length) -{ - return _gcry_md_list (list, list_length); -} - -gcry_error_t -gcry_ac_data_new (gcry_ac_data_t *data) -{ - return _gcry_ac_data_new (data); -} - -void -gcry_ac_data_destroy (gcry_ac_data_t data) -{ - _gcry_ac_data_destroy (data); -} - -gcry_error_t -gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data) -{ - return _gcry_ac_data_copy (data_cp, data); -} - -unsigned int -gcry_ac_data_length (gcry_ac_data_t data) -{ - return _gcry_ac_data_length (data); -} - -void -gcry_ac_data_clear (gcry_ac_data_t data) -{ - _gcry_ac_data_clear (data); -} - -gcry_error_t -gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags, - const char *name, gcry_mpi_t mpi) -{ - return _gcry_ac_data_set (data, flags, name, mpi); -} - -gcry_error_t -gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags, - const char *name, gcry_mpi_t *mpi) -{ - return _gcry_ac_data_get_name (data, flags, name, mpi); -} - -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) -{ - return _gcry_ac_data_get_index (data, flags, idx, name, mpi); -} - -gcry_error_t -gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp, - const char **identifiers) -{ - return _gcry_ac_data_to_sexp (data, sexp, identifiers); -} - -gcry_error_t -gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp, - const char **identifiers) -{ - return _gcry_ac_data_from_sexp (data, sexp, identifiers); -} - -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 arg_ptr; - - va_start (arg_ptr, type); - _gcry_ac_io_init_va (ac_io, mode, type, arg_ptr); - va_end (arg_ptr); -} - -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) -{ - _gcry_ac_io_init_va (ac_io, mode, type, ap); -} - -gcry_error_t -gcry_ac_open (gcry_ac_handle_t *handle, - gcry_ac_id_t algorithm, unsigned int flags) -{ - return _gcry_ac_open (handle, algorithm, flags); -} - -void -gcry_ac_close (gcry_ac_handle_t handle) -{ - _gcry_ac_close (handle); -} - -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) -{ - return _gcry_ac_key_init (key, handle, type, data); -} - -gcry_error_t -gcry_ac_key_pair_generate (gcry_ac_handle_t handle, - unsigned int nbits, void *spec, - gcry_ac_key_pair_t *key_pair, - gcry_mpi_t **miscdata) -{ - return _gcry_ac_key_pair_generate ( handle, nbits, spec, key_pair, miscdata); -} - -gcry_ac_key_t -gcry_ac_key_pair_extract (gcry_ac_key_pair_t keypair, gcry_ac_key_type_t which) -{ - return _gcry_ac_key_pair_extract (keypair, which); -} - -gcry_ac_data_t -gcry_ac_key_data_get (gcry_ac_key_t key) -{ - return _gcry_ac_key_data_get (key); -} - -gcry_error_t -gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key) -{ - return _gcry_ac_key_test (handle, key); -} - -gcry_error_t -gcry_ac_key_get_nbits (gcry_ac_handle_t handle, - gcry_ac_key_t key, unsigned int *nbits) -{ - return _gcry_ac_key_get_nbits (handle, key, nbits); -} - -gcry_error_t -gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key, - unsigned char *key_grip) -{ - return _gcry_ac_key_get_grip (handle, key, key_grip); -} - -void -gcry_ac_key_destroy (gcry_ac_key_t key) -{ - _gcry_ac_key_destroy (key); -} - -void -gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair) -{ - _gcry_ac_key_pair_destroy (key_pair); -} - -gcry_error_t -gcry_ac_data_encode (gcry_ac_em_t method, unsigned int flags, void *options, - gcry_ac_io_t *io_read, gcry_ac_io_t *io_write) -{ - return _gcry_ac_data_encode (method, flags, options, io_read, io_write); -} - -gcry_error_t -gcry_ac_data_decode (gcry_ac_em_t method, unsigned int flags, void *options, - gcry_ac_io_t *io_read, gcry_ac_io_t *io_write) -{ - return _gcry_ac_data_decode (method, flags, options, io_read, io_write); -} - -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) -{ - return _gcry_ac_data_encrypt (handle, flags, key, - data_plain, data_encrypted); -} - -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) -{ - return _gcry_ac_data_decrypt (handle, flags, key, - data_plain, data_encrypted); -} - -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) -{ - return _gcry_ac_data_sign (handle, key, data, data_signature); -} - -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) -{ - return _gcry_ac_data_verify (handle, key, data, data_signature); -} - -gcry_error_t -gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle, - gcry_ac_scheme_t scheme, - unsigned int flags, void *opts, - gcry_ac_key_t key, - gcry_ac_io_t *io_message, - gcry_ac_io_t *io_cipher) -{ - return _gcry_ac_data_encrypt_scheme (handle, scheme, flags, opts, key, - io_message, io_cipher); -} - -gcry_error_t -gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle, - gcry_ac_scheme_t scheme, - unsigned int flags, void *opts, - gcry_ac_key_t key, - gcry_ac_io_t *io_cipher, - gcry_ac_io_t *io_message) -{ - return _gcry_ac_data_decrypt_scheme (handle, scheme, flags, opts, key, - io_cipher, io_message); -} - -gcry_error_t -gcry_ac_data_sign_scheme (gcry_ac_handle_t handle, - gcry_ac_scheme_t scheme, - unsigned int flags, void *opts, - gcry_ac_key_t key, - gcry_ac_io_t *io_message, - gcry_ac_io_t *io_signature) -{ - return _gcry_ac_data_sign_scheme (handle, scheme, flags, opts, key, - io_message, io_signature); -} - -gcry_error_t -gcry_ac_data_verify_scheme (gcry_ac_handle_t handle, - gcry_ac_scheme_t scheme, - unsigned int flags, void *opts, - gcry_ac_key_t key, - gcry_ac_io_t *io_message, - gcry_ac_io_t *io_signature) -{ - return _gcry_ac_data_verify_scheme (handle, scheme, flags, opts, key, - io_message, io_signature); -} - -gcry_error_t -gcry_ac_id_to_name (gcry_ac_id_t algorithm, const char **name) -{ - /* This function is deprecated. We implement it in terms of the - suggested replacement. */ - const char *tmp = _gcry_pk_algo_name (algorithm); - if (!*tmp) - return gcry_error (GPG_ERR_PUBKEY_ALGO); - *name = tmp; - return 0; -} - -gcry_error_t -gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm) -{ - /* This function is deprecated. We implement it in terms of the - suggested replacement. */ - int algo = _gcry_pk_map_name (name); - if (!algo) - return gcry_error (GPG_ERR_PUBKEY_ALGO); - *algorithm = algo; - return 0; -} - -gpg_error_t -gcry_kdf_derive (const void *passphrase, size_t passphraselen, - int algo, int hashalgo, - const void *salt, size_t saltlen, - unsigned long iterations, - size_t keysize, void *keybuffer) -{ - return _gcry_kdf_derive (passphrase, passphraselen, algo, hashalgo, - salt, saltlen, iterations, keysize, keybuffer); -} - -void -gcry_randomize (void *buffer, size_t length, enum gcry_random_level level) -{ - if (!fips_is_operational ()) - { - (void)fips_not_operational (); - fips_signal_fatal_error ("called in non-operational state"); - fips_noreturn (); - } - _gcry_randomize (buffer, length, level); -} - -gcry_error_t -gcry_random_add_bytes (const void *buffer, size_t length, int quality) -{ - if (!fips_is_operational ()) - return gpg_error (fips_not_operational ()); - return _gcry_random_add_bytes (buffer, length, quality); -} - -void * -gcry_random_bytes (size_t nbytes, enum gcry_random_level level) -{ - if (!fips_is_operational ()) - { - (void)fips_not_operational (); - fips_signal_fatal_error ("called in non-operational state"); - fips_noreturn (); - } - - return _gcry_random_bytes (nbytes,level); -} - -void * -gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level) -{ - if (!fips_is_operational ()) - { - (void)fips_not_operational (); - fips_signal_fatal_error ("called in non-operational state"); - fips_noreturn (); - } - - return _gcry_random_bytes_secure (nbytes, level); -} - -void -gcry_mpi_randomize (gcry_mpi_t w, - unsigned int nbits, enum gcry_random_level level) -{ - _gcry_mpi_randomize (w, nbits, level); -} - -void -gcry_create_nonce (void *buffer, size_t length) -{ - if (!fips_is_operational ()) - { - (void)fips_not_operational (); - fips_signal_fatal_error ("called in non-operational state"); - fips_noreturn (); - } - _gcry_create_nonce (buffer, length); -} - -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) -{ - return _gcry_prime_generate (prime, prime_bits, factor_bits, factors, - cb_func, cb_arg, random_level, flags); -} - -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) -{ - return _gcry_prime_group_generator (r_g, prime, factors, start_g); -} - -void -gcry_prime_release_factors (gcry_mpi_t *factors) -{ - _gcry_prime_release_factors (factors); -} - -gcry_error_t -gcry_prime_check (gcry_mpi_t x, unsigned int flags) -{ - return _gcry_prime_check (x, flags); -} - -void -gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data) -{ - _gcry_set_progress_handler (cb, cb_data); -} - -void -gcry_set_allocation_handler (gcry_handler_alloc_t func_alloc, - gcry_handler_alloc_t func_alloc_secure, - gcry_handler_secure_check_t func_secure_check, - gcry_handler_realloc_t func_realloc, - gcry_handler_free_t func_free) -{ - _gcry_set_allocation_handler (func_alloc, func_alloc_secure, - func_secure_check, func_realloc, func_free); -} - -void -gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque) -{ - _gcry_set_outofcore_handler (h, opaque); -} - -void -gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque) -{ - _gcry_set_fatalerror_handler (fnc, opaque); -} - -void -gcry_set_log_handler (gcry_handler_log_t f, void *opaque) -{ - _gcry_set_log_handler (f, opaque); -} - -void -gcry_set_gettext_handler (const char *(*f)(const char*)) -{ - _gcry_set_gettext_handler (f); -} - -void * -gcry_malloc (size_t n) -{ - return _gcry_malloc (n); -} - -void * -gcry_calloc (size_t n, size_t m) -{ - return _gcry_calloc (n, m); -} - -void * -gcry_malloc_secure (size_t n) -{ - return _gcry_malloc_secure (n); -} - -void * -gcry_calloc_secure (size_t n, size_t m) -{ - return _gcry_calloc_secure (n,m); -} - -void * -gcry_realloc (void *a, size_t n) -{ - return _gcry_realloc (a, n); -} - -char * -gcry_strdup (const char *string) -{ - return _gcry_strdup (string); -} - -void * -gcry_xmalloc (size_t n) -{ - return _gcry_xmalloc (n); -} - -void * -gcry_xcalloc (size_t n, size_t m) -{ - return _gcry_xcalloc (n, m); -} - -void * -gcry_xmalloc_secure (size_t n) -{ - return _gcry_xmalloc_secure (n); -} - -void * -gcry_xcalloc_secure (size_t n, size_t m) -{ - return _gcry_xcalloc_secure (n, m); -} - -void * -gcry_xrealloc (void *a, size_t n) -{ - return _gcry_xrealloc (a, n); -} - -char * -gcry_xstrdup (const char *a) -{ - return _gcry_xstrdup (a); -} - -void -gcry_free (void *a) -{ - _gcry_free (a); -} - -int -gcry_is_secure (const void *a) -{ - return _gcry_is_secure (a); -} - - -gcry_error_t -gcry_cipher_register (gcry_cipher_spec_t *cipher, int *algorithm_id, - gcry_module_t *module) -{ - return _gcry_cipher_register (cipher, NULL, algorithm_id, module); -} - -void -gcry_cipher_unregister (gcry_module_t module) -{ - _gcry_cipher_unregister (module); -} - -gcry_error_t -gcry_pk_register (gcry_pk_spec_t *pubkey, unsigned int *algorithm_id, - gcry_module_t *module) -{ - return _gcry_pk_register (pubkey, NULL, algorithm_id, module); -} - -void -gcry_pk_unregister (gcry_module_t module) -{ - _gcry_pk_unregister (module); -} - -gcry_error_t -gcry_md_register (gcry_md_spec_t *digest, unsigned int *algorithm_id, - gcry_module_t *module) -{ - return _gcry_md_register (digest, NULL, algorithm_id, module); -} - -void -gcry_md_unregister (gcry_module_t module) -{ - _gcry_md_unregister (module); -} diff --git a/grub-core/lib/libgcrypt/src/visibility.h b/grub-core/lib/libgcrypt/src/visibility.h deleted file mode 100644 index 3c1e8aa89..000000000 --- a/grub-core/lib/libgcrypt/src/visibility.h +++ /dev/null @@ -1,807 +0,0 @@ -/* visibility.h - Set visibility attribute - * 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 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 . - */ - -#ifndef GCRY_VISIBILITY_H -#define GCRY_VISIBILITY_H - -/* Redefine all public symbols with an underscore unless we already - use the underscore prefixed version internally. */ -#define gcry_check_version _gcry_check_version -#define gcry_control _gcry_control - -#define gcry_set_allocation_handler _gcry_set_allocation_handler -#define gcry_set_fatalerror_handler _gcry_set_fatalerror_handler -#define gcry_set_gettext_handler _gcry_set_gettext_handler -#define gcry_set_log_handler _gcry_set_log_handler -#define gcry_set_outofcore_handler _gcry_set_outofcore_handler -#define gcry_set_progress_handler _gcry_set_progress_handler -#define gcry_err_code_from_errno _gcry_err_code_from_errno -#define gcry_err_code_to_errno _gcry_err_code_to_errno -#define gcry_err_make_from_errno _gcry_err_make_from_errno -#define gcry_error_from_errno _gcry_error_from_errno -#define gcry_strerror _gcry_strerror -#define gcry_strsource _gcry_strsource - -#define gcry_free _gcry_free -#define gcry_malloc _gcry_malloc -#define gcry_malloc_secure _gcry_malloc_secure -#define gcry_calloc _gcry_calloc -#define gcry_calloc_secure _gcry_calloc_secure -#define gcry_realloc _gcry_realloc -#define gcry_strdup _gcry_strdup -#define gcry_is_secure _gcry_is_secure -#define gcry_xcalloc _gcry_xcalloc -#define gcry_xcalloc_secure _gcry_xcalloc_secure -#define gcry_xmalloc _gcry_xmalloc -#define gcry_xmalloc_secure _gcry_xmalloc_secure -#define gcry_xrealloc _gcry_xrealloc -#define gcry_xstrdup _gcry_xstrdup - -#define gcry_md_algo_info _gcry_md_algo_info -#define gcry_md_algo_name _gcry_md_algo_name -#define gcry_md_close _gcry_md_close -#define gcry_md_copy _gcry_md_copy -#define gcry_md_ctl _gcry_md_ctl -#define gcry_md_enable _gcry_md_enable -#define gcry_md_get _gcry_md_get -#define gcry_md_get_algo _gcry_md_get_algo -#define gcry_md_get_algo_dlen _gcry_md_get_algo_dlen -#define gcry_md_hash_buffer _gcry_md_hash_buffer -#define gcry_md_info _gcry_md_info -#define gcry_md_is_enabled _gcry_md_is_enabled -#define gcry_md_is_secure _gcry_md_is_secure -#define gcry_md_list _gcry_md_list -#define gcry_md_map_name _gcry_md_map_name -#define gcry_md_open _gcry_md_open -#define gcry_md_read _gcry_md_read -/* gcry_md_register and _gcry_md_register differ. */ -#define gcry_md_unregister _gcry_md_unregister -#define gcry_md_reset _gcry_md_reset -#define gcry_md_setkey _gcry_md_setkey -#define gcry_md_write _gcry_md_write -#define gcry_md_debug _gcry_md_debug - -#define gcry_cipher_algo_info _gcry_cipher_algo_info -#define gcry_cipher_algo_name _gcry_cipher_algo_name -#define gcry_cipher_close _gcry_cipher_close -#define gcry_cipher_setkey _gcry_cipher_setkey -#define gcry_cipher_setiv _gcry_cipher_setiv -#define gcry_cipher_setctr _gcry_cipher_setctr -#define gcry_cipher_ctl _gcry_cipher_ctl -#define gcry_cipher_decrypt _gcry_cipher_decrypt -#define gcry_cipher_encrypt _gcry_cipher_encrypt -#define gcry_cipher_get_algo_blklen _gcry_cipher_get_algo_blklen -#define gcry_cipher_get_algo_keylen _gcry_cipher_get_algo_keylen -#define gcry_cipher_info _gcry_cipher_info -#define gcry_cipher_list _gcry_cipher_list -#define gcry_cipher_map_name _gcry_cipher_map_name -#define gcry_cipher_mode_from_oid _gcry_cipher_mode_from_oid -#define gcry_cipher_open _gcry_cipher_open -/* gcry_cipher_register and _gcry_cipher_register differ. */ -#define gcry_cipher_unregister _gcry_cipher_unregister - -#define gcry_pk_algo_info _gcry_pk_algo_info -#define gcry_pk_algo_name _gcry_pk_algo_name -#define gcry_pk_ctl _gcry_pk_ctl -#define gcry_pk_decrypt _gcry_pk_decrypt -#define gcry_pk_encrypt _gcry_pk_encrypt -#define gcry_pk_genkey _gcry_pk_genkey -#define gcry_pk_get_keygrip _gcry_pk_get_keygrip -#define gcry_pk_get_curve _gcry_pk_get_curve -#define gcry_pk_get_param _gcry_pk_get_param -#define gcry_pk_get_nbits _gcry_pk_get_nbits -#define gcry_pk_list _gcry_pk_list -#define gcry_pk_map_name _gcry_pk_map_name -/* gcry_pk_register and _gcry_pk_register differ. */ -#define gcry_pk_unregister _gcry_pk_unregister -#define gcry_pk_sign _gcry_pk_sign -#define gcry_pk_testkey _gcry_pk_testkey -#define gcry_pk_verify _gcry_pk_verify - -#define gcry_ac_data_new _gcry_ac_data_new -#define gcry_ac_data_destroy _gcry_ac_data_destroy -#define gcry_ac_data_copy _gcry_ac_data_copy -#define gcry_ac_data_length _gcry_ac_data_length -#define gcry_ac_data_clear _gcry_ac_data_clear -#define gcry_ac_data_set _gcry_ac_data_set -#define gcry_ac_data_get_name _gcry_ac_data_get_name -#define gcry_ac_data_get_index _gcry_ac_data_get_index -#define gcry_ac_open _gcry_ac_open -#define gcry_ac_close _gcry_ac_close -#define gcry_ac_key_init _gcry_ac_key_init -#define gcry_ac_key_pair_generate _gcry_ac_key_pair_generate -#define gcry_ac_key_pair_extract _gcry_ac_key_pair_extract -#define gcry_ac_key_data_get _gcry_ac_key_data_get -#define gcry_ac_key_test _gcry_ac_key_test -#define gcry_ac_key_get_nbits _gcry_ac_key_get_nbits -#define gcry_ac_key_get_grip _gcry_ac_key_get_grip -#define gcry_ac_key_destroy _gcry_ac_key_destroy -#define gcry_ac_key_pair_destroy _gcry_ac_key_pair_destroy -#define gcry_ac_data_encrypt _gcry_ac_data_encrypt -#define gcry_ac_data_decrypt _gcry_ac_data_decrypt -#define gcry_ac_data_sign _gcry_ac_data_sign -#define gcry_ac_data_verify _gcry_ac_data_verify -#define gcry_ac_id_to_name _gcry_ac_id_to_name -#define gcry_ac_name_to_id _gcry_ac_name_to_id -#define gcry_ac_data_encode _gcry_ac_data_encode -#define gcry_ac_data_decode _gcry_ac_data_decode -#define gcry_ac_mpi_to_os _gcry_ac_mpi_to_os -#define gcry_ac_mpi_to_os_alloc _gcry_ac_mpi_to_os_alloc -#define gcry_ac_os_to_mpi _gcry_ac_os_to_mpi -#define gcry_ac_data_encrypt_scheme _gcry_ac_data_encrypt_scheme -#define gcry_ac_data_decrypt_scheme _gcry_ac_data_decrypt_scheme -#define gcry_ac_data_sign_scheme _gcry_ac_data_sign_scheme -#define gcry_ac_data_verify_scheme _gcry_ac_data_verify_scheme -#define gcry_ac_data_to_sexp _gcry_ac_data_to_sexp -#define gcry_ac_data_from_sexp _gcry_ac_data_from_sexp -#define gcry_ac_io_init _gcry_ac_io_init -#define gcry_ac_io_init_va _gcry_ac_io_init_va - -#define gcry_kdf_derive _gcry_kdf_derive - -#define gcry_prime_check _gcry_prime_check -#define gcry_prime_generate _gcry_prime_generate -#define gcry_prime_group_generator _gcry_prime_group_generator -#define gcry_prime_release_factors _gcry_prime_release_factors - -#define gcry_random_add_bytes _gcry_random_add_bytes -#define gcry_random_bytes _gcry_random_bytes -#define gcry_random_bytes_secure _gcry_random_bytes_secure -#define gcry_randomize _gcry_randomize -#define gcry_create_nonce _gcry_create_nonce - -#define gcry_sexp_alist _gcry_sexp_alist -#define gcry_sexp_append _gcry_sexp_append -#define gcry_sexp_build _gcry_sexp_build -#define gcry_sexp_build_array _gcry_sexp_build_array -#define gcry_sexp_cadr _gcry_sexp_cadr -#define gcry_sexp_canon_len _gcry_sexp_canon_len -#define gcry_sexp_car _gcry_sexp_car -#define gcry_sexp_cdr _gcry_sexp_cdr -#define gcry_sexp_cons _gcry_sexp_cons -#define gcry_sexp_create _gcry_sexp_create -#define gcry_sexp_dump _gcry_sexp_dump -#define gcry_sexp_find_token _gcry_sexp_find_token -#define gcry_sexp_length _gcry_sexp_length -#define gcry_sexp_new _gcry_sexp_new -#define gcry_sexp_nth _gcry_sexp_nth -#define gcry_sexp_nth_data _gcry_sexp_nth_data -#define gcry_sexp_nth_mpi _gcry_sexp_nth_mpi -#define gcry_sexp_prepend _gcry_sexp_prepend -#define gcry_sexp_release _gcry_sexp_release -#define gcry_sexp_sprint _gcry_sexp_sprint -#define gcry_sexp_sscan _gcry_sexp_sscan -#define gcry_sexp_vlist _gcry_sexp_vlist -#define gcry_sexp_nth_string _gcry_sexp_nth_string - -#define gcry_mpi_add _gcry_mpi_add -#define gcry_mpi_add_ui _gcry_mpi_add_ui -#define gcry_mpi_addm _gcry_mpi_addm -#define gcry_mpi_aprint _gcry_mpi_aprint -#define gcry_mpi_clear_bit _gcry_mpi_clear_bit -#define gcry_mpi_clear_flag _gcry_mpi_clear_flag -#define gcry_mpi_clear_highbit _gcry_mpi_clear_highbit -#define gcry_mpi_cmp _gcry_mpi_cmp -#define gcry_mpi_cmp_ui _gcry_mpi_cmp_ui -#define gcry_mpi_copy _gcry_mpi_copy -#define gcry_mpi_div _gcry_mpi_div -#define gcry_mpi_dump _gcry_mpi_dump -#define gcry_mpi_gcd _gcry_mpi_gcd -#define gcry_mpi_get_flag _gcry_mpi_get_flag -#define gcry_mpi_get_nbits _gcry_mpi_get_nbits -#define gcry_mpi_get_opaque _gcry_mpi_get_opaque -#define gcry_mpi_invm _gcry_mpi_invm -#define gcry_mpi_mod _gcry_mpi_mod -#define gcry_mpi_mul _gcry_mpi_mul -#define gcry_mpi_mul_2exp _gcry_mpi_mul_2exp -#define gcry_mpi_mul_ui _gcry_mpi_mul_ui -#define gcry_mpi_mulm _gcry_mpi_mulm -#define gcry_mpi_new _gcry_mpi_new -#define gcry_mpi_powm _gcry_mpi_powm -#define gcry_mpi_print _gcry_mpi_print -#define gcry_mpi_randomize _gcry_mpi_randomize -#define gcry_mpi_release _gcry_mpi_release -#define gcry_mpi_rshift _gcry_mpi_rshift -#define gcry_mpi_lshift _gcry_mpi_lshift -#define gcry_mpi_scan _gcry_mpi_scan -#define gcry_mpi_set _gcry_mpi_set -#define gcry_mpi_set_bit _gcry_mpi_set_bit -#define gcry_mpi_set_flag _gcry_mpi_set_flag -#define gcry_mpi_set_highbit _gcry_mpi_set_highbit -#define gcry_mpi_set_opaque _gcry_mpi_set_opaque -#define gcry_mpi_set_ui _gcry_mpi_set_ui -#define gcry_mpi_snew _gcry_mpi_snew -#define gcry_mpi_sub _gcry_mpi_sub -#define gcry_mpi_sub_ui _gcry_mpi_sub_ui -#define gcry_mpi_subm _gcry_mpi_subm -#define gcry_mpi_swap _gcry_mpi_swap -#define gcry_mpi_test_bit _gcry_mpi_test_bit - - -/* Include the main header here so that public symbols are mapped to - the internal underscored ones. */ -#ifdef _GCRY_INCLUDED_BY_VISIBILITY_C - /* We need to redeclare the deprecated functions without the - deprecated attribute. */ -# define GCRYPT_NO_DEPRECATED -# include "gcrypt.h" -/* The algorithm IDs. */ - gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data); - void gcry_ac_data_destroy (gcry_ac_data_t data); - gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *data_cp, - gcry_ac_data_t data); - unsigned int gcry_ac_data_length (gcry_ac_data_t data); - void gcry_ac_data_clear (gcry_ac_data_t data); - 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 gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags, - const char *name, gcry_mpi_t *mpi); - 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 gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp, - const char **identifiers); - gcry_error_t gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp, - const char **identifiers); - void gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode, - gcry_ac_io_type_t 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); - gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle, - gcry_ac_id_t algorithm, unsigned int flags); - void gcry_ac_close (gcry_ac_handle_t handle); - 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_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t handle, - unsigned int nbits, void *spec, - gcry_ac_key_pair_t *key_pair, - gcry_mpi_t **misc_data); - gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair, - gcry_ac_key_type_t which); - gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key); - gcry_error_t gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key); - gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t handle, - gcry_ac_key_t key, unsigned int *nbits); - gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key, - unsigned char *key_grip); - void gcry_ac_key_destroy (gcry_ac_key_t key); - void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair); - gcry_error_t gcry_ac_data_encode (gcry_ac_em_t method, - unsigned int flags, void *options, - gcry_ac_io_t *io_read, - gcry_ac_io_t *io_write); - gcry_error_t gcry_ac_data_decode (gcry_ac_em_t method, - unsigned int flags, void *options, - gcry_ac_io_t *io_read, - gcry_ac_io_t *io_write); - 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_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_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_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_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle, - gcry_ac_scheme_t scheme, - 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 gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle, - gcry_ac_scheme_t scheme, - unsigned int flags, void *opts, - gcry_ac_key_t key, - gcry_ac_io_t *io_cipher, - gcry_ac_io_t *io_message); - gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle, - gcry_ac_scheme_t scheme, - unsigned int flags, void *opts, - gcry_ac_key_t key, - gcry_ac_io_t *io_message, - gcry_ac_io_t *io_signature); - gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle, - gcry_ac_scheme_t scheme, - unsigned int flags, void *opts, - gcry_ac_key_t key, - gcry_ac_io_t *io_message, - gcry_ac_io_t *io_signature); - gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm, const char **name); - gcry_error_t gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm); -#else -# include "gcrypt.h" -#endif - -/* Prototypes of functions exported but not ready for use. */ -gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo, - unsigned char *buffer, int buflen); -void gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n); -gcry_error_t gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os, - size_t *os_n); -void gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n); - - - -/* Our use of the ELF visibility feature works by passing - -fvisibiliy=hidden on the command line and by explicitly marking - all exported functions as visible. - - NOTE: When adding new functions, please make sure to add them to - libgcrypt.vers and libgcrypt.def as well. */ - -#ifdef _GCRY_INCLUDED_BY_VISIBILITY_C - -/* A macro to flag a function as visible. Note that we take the - definition from the mapped name. */ -#ifdef GCRY_USE_VISIBILITY -# define MARK_VISIBLE(name) \ - extern __typeof__ (_##name) name __attribute__ ((visibility("default"))); -# define MARK_VISIBLEX(name) \ - extern __typeof__ (name) name __attribute__ ((visibility("default"))); -#else -# define MARK_VISIBLE(name) /* */ -# define MARK_VISIBLEX(name) /* */ -#endif - - -/* First undef all redefined symbols so that we set the attribute on - the correct version name. */ -#undef gcry_check_version -#undef gcry_control - -#undef gcry_set_allocation_handler -#undef gcry_set_fatalerror_handler -#undef gcry_set_gettext_handler -#undef gcry_set_log_handler -#undef gcry_set_outofcore_handler -#undef gcry_set_progress_handler -#undef gcry_err_code_from_errno -#undef gcry_err_code_to_errno -#undef gcry_err_make_from_errno -#undef gcry_error_from_errno -#undef gcry_strerror -#undef gcry_strsource - -#undef gcry_free -#undef gcry_malloc -#undef gcry_malloc_secure -#undef gcry_calloc -#undef gcry_calloc_secure -#undef gcry_realloc -#undef gcry_strdup -#undef gcry_is_secure -#undef gcry_xcalloc -#undef gcry_xcalloc_secure -#undef gcry_xmalloc -#undef gcry_xmalloc_secure -#undef gcry_xrealloc -#undef gcry_xstrdup - -#undef gcry_md_algo_info -#undef gcry_md_algo_name -#undef gcry_md_close -#undef gcry_md_copy -#undef gcry_md_ctl -#undef gcry_md_enable -#undef gcry_md_get -#undef gcry_md_get_algo -#undef gcry_md_get_algo_dlen -#undef gcry_md_hash_buffer -#undef gcry_md_info -#undef gcry_md_is_enabled -#undef gcry_md_is_secure -#undef gcry_md_list -#undef gcry_md_map_name -#undef gcry_md_open -#undef gcry_md_read -/* gcry_md_register is not anymore a macro. */ -#undef gcry_md_unregister -#undef gcry_md_reset -#undef gcry_md_setkey -#undef gcry_md_write -#undef gcry_md_debug - -#undef gcry_cipher_algo_info -#undef gcry_cipher_algo_name -#undef gcry_cipher_close -#undef gcry_cipher_setkey -#undef gcry_cipher_setiv -#undef gcry_cipher_setctr -#undef gcry_cipher_ctl -#undef gcry_cipher_decrypt -#undef gcry_cipher_encrypt -#undef gcry_cipher_get_algo_blklen -#undef gcry_cipher_get_algo_keylen -#undef gcry_cipher_info -#undef gcry_cipher_list -#undef gcry_cipher_map_name -#undef gcry_cipher_mode_from_oid -#undef gcry_cipher_open -/* gcry_cipher_register is not anymore a macro. */ -#undef gcry_cipher_unregister - -#undef gcry_pk_algo_info -#undef gcry_pk_algo_name -#undef gcry_pk_ctl -#undef gcry_pk_decrypt -#undef gcry_pk_encrypt -#undef gcry_pk_genkey -#undef gcry_pk_get_keygrip -#undef gcry_pk_get_curve -#undef gcry_pk_get_param -#undef gcry_pk_get_nbits -#undef gcry_pk_list -#undef gcry_pk_map_name -/* gcry_pk_register is not anymore a macro. */ -#undef gcry_pk_unregister -#undef gcry_pk_sign -#undef gcry_pk_testkey -#undef gcry_pk_verify - -#undef gcry_ac_data_new -#undef gcry_ac_data_destroy -#undef gcry_ac_data_copy -#undef gcry_ac_data_length -#undef gcry_ac_data_clear -#undef gcry_ac_data_set -#undef gcry_ac_data_get_name -#undef gcry_ac_data_get_index -#undef gcry_ac_open -#undef gcry_ac_close -#undef gcry_ac_key_init -#undef gcry_ac_key_pair_generate -#undef gcry_ac_key_pair_extract -#undef gcry_ac_key_data_get -#undef gcry_ac_key_test -#undef gcry_ac_key_get_nbits -#undef gcry_ac_key_get_grip -#undef gcry_ac_key_destroy -#undef gcry_ac_key_pair_destroy -#undef gcry_ac_data_encrypt -#undef gcry_ac_data_decrypt -#undef gcry_ac_data_sign -#undef gcry_ac_data_verify -#undef gcry_ac_id_to_name -#undef gcry_ac_name_to_id -#undef gcry_ac_data_encode -#undef gcry_ac_data_decode -#undef gcry_ac_mpi_to_os -#undef gcry_ac_mpi_to_os_alloc -#undef gcry_ac_os_to_mpi -#undef gcry_ac_data_encrypt_scheme -#undef gcry_ac_data_decrypt_scheme -#undef gcry_ac_data_sign_scheme -#undef gcry_ac_data_verify_scheme -#undef gcry_ac_data_to_sexp -#undef gcry_ac_data_from_sexp -#undef gcry_ac_io_init -#undef gcry_ac_io_init_va - -#undef gcry_kdf_derive - -#undef gcry_prime_check -#undef gcry_prime_generate -#undef gcry_prime_group_generator -#undef gcry_prime_release_factors - -#undef gcry_random_add_bytes -#undef gcry_random_bytes -#undef gcry_random_bytes_secure -#undef gcry_randomize -#undef gcry_create_nonce - -#undef gcry_sexp_alist -#undef gcry_sexp_append -#undef gcry_sexp_build -#undef gcry_sexp_build_array -#undef gcry_sexp_cadr -#undef gcry_sexp_canon_len -#undef gcry_sexp_car -#undef gcry_sexp_cdr -#undef gcry_sexp_cons -#undef gcry_sexp_create -#undef gcry_sexp_dump -#undef gcry_sexp_find_token -#undef gcry_sexp_length -#undef gcry_sexp_new -#undef gcry_sexp_nth -#undef gcry_sexp_nth_data -#undef gcry_sexp_nth_mpi -#undef gcry_sexp_prepend -#undef gcry_sexp_release -#undef gcry_sexp_sprint -#undef gcry_sexp_sscan -#undef gcry_sexp_vlist -#undef gcry_sexp_nth_string - -#undef gcry_mpi_add -#undef gcry_mpi_add_ui -#undef gcry_mpi_addm -#undef gcry_mpi_aprint -#undef gcry_mpi_clear_bit -#undef gcry_mpi_clear_flag -#undef gcry_mpi_clear_highbit -#undef gcry_mpi_cmp -#undef gcry_mpi_cmp_ui -#undef gcry_mpi_copy -#undef gcry_mpi_div -#undef gcry_mpi_dump -#undef gcry_mpi_gcd -#undef gcry_mpi_get_flag -#undef gcry_mpi_get_nbits -#undef gcry_mpi_get_opaque -#undef gcry_mpi_invm -#undef gcry_mpi_mod -#undef gcry_mpi_mul -#undef gcry_mpi_mul_2exp -#undef gcry_mpi_mul_ui -#undef gcry_mpi_mulm -#undef gcry_mpi_new -#undef gcry_mpi_powm -#undef gcry_mpi_print -#undef gcry_mpi_randomize -#undef gcry_mpi_release -#undef gcry_mpi_rshift -#undef gcry_mpi_lshift -#undef gcry_mpi_scan -#undef gcry_mpi_set -#undef gcry_mpi_set_bit -#undef gcry_mpi_set_flag -#undef gcry_mpi_set_highbit -#undef gcry_mpi_set_opaque -#undef gcry_mpi_set_ui -#undef gcry_mpi_snew -#undef gcry_mpi_sub -#undef gcry_mpi_sub_ui -#undef gcry_mpi_subm -#undef gcry_mpi_swap -#undef gcry_mpi_test_bit - - -/* Now mark all symbols. */ - -MARK_VISIBLE (gcry_check_version) -MARK_VISIBLE (gcry_control) - -MARK_VISIBLE (gcry_set_allocation_handler) -MARK_VISIBLE (gcry_set_fatalerror_handler) -MARK_VISIBLE (gcry_set_gettext_handler) -MARK_VISIBLE (gcry_set_log_handler) -MARK_VISIBLE (gcry_set_outofcore_handler) -MARK_VISIBLE (gcry_set_progress_handler) -MARK_VISIBLE (gcry_err_code_from_errno) -MARK_VISIBLE (gcry_err_code_to_errno) -MARK_VISIBLE (gcry_err_make_from_errno) -MARK_VISIBLE (gcry_error_from_errno) -MARK_VISIBLE (gcry_strerror) -MARK_VISIBLE (gcry_strsource) - -MARK_VISIBLE (gcry_free) -MARK_VISIBLE (gcry_malloc) -MARK_VISIBLE (gcry_malloc_secure) -MARK_VISIBLE (gcry_calloc) -MARK_VISIBLE (gcry_calloc_secure) -MARK_VISIBLE (gcry_realloc) -MARK_VISIBLE (gcry_strdup) -MARK_VISIBLE (gcry_is_secure) -MARK_VISIBLE (gcry_xcalloc) -MARK_VISIBLE (gcry_xcalloc_secure) -MARK_VISIBLE (gcry_xmalloc) -MARK_VISIBLE (gcry_xmalloc_secure) -MARK_VISIBLE (gcry_xrealloc) -MARK_VISIBLE (gcry_xstrdup) - -MARK_VISIBLE (gcry_md_algo_info) -MARK_VISIBLE (gcry_md_algo_name) -MARK_VISIBLE (gcry_md_close) -MARK_VISIBLE (gcry_md_copy) -MARK_VISIBLE (gcry_md_ctl) -MARK_VISIBLE (gcry_md_enable) -MARK_VISIBLE (gcry_md_get) -MARK_VISIBLE (gcry_md_get_algo) -MARK_VISIBLE (gcry_md_get_algo_dlen) -MARK_VISIBLE (gcry_md_hash_buffer) -MARK_VISIBLE (gcry_md_info) -MARK_VISIBLE (gcry_md_is_enabled) -MARK_VISIBLE (gcry_md_is_secure) -MARK_VISIBLE (gcry_md_list) -MARK_VISIBLE (gcry_md_map_name) -MARK_VISIBLE (gcry_md_open) -MARK_VISIBLE (gcry_md_read) -MARK_VISIBLEX(gcry_md_register) -MARK_VISIBLE (gcry_md_reset) -MARK_VISIBLE (gcry_md_setkey) -MARK_VISIBLE (gcry_md_unregister) -MARK_VISIBLE (gcry_md_write) -MARK_VISIBLE (gcry_md_debug) - -MARK_VISIBLE (gcry_cipher_algo_info) -MARK_VISIBLE (gcry_cipher_algo_name) -MARK_VISIBLE (gcry_cipher_close) -MARK_VISIBLE (gcry_cipher_setkey) -MARK_VISIBLE (gcry_cipher_setiv) -MARK_VISIBLE (gcry_cipher_setctr) -MARK_VISIBLE (gcry_cipher_ctl) -MARK_VISIBLE (gcry_cipher_decrypt) -MARK_VISIBLE (gcry_cipher_encrypt) -MARK_VISIBLE (gcry_cipher_get_algo_blklen) -MARK_VISIBLE (gcry_cipher_get_algo_keylen) -MARK_VISIBLE (gcry_cipher_info) -MARK_VISIBLE (gcry_cipher_list) -MARK_VISIBLE (gcry_cipher_map_name) -MARK_VISIBLE (gcry_cipher_mode_from_oid) -MARK_VISIBLE (gcry_cipher_open) -MARK_VISIBLEX(gcry_cipher_register) -MARK_VISIBLE (gcry_cipher_unregister) - -MARK_VISIBLE (gcry_pk_algo_info) -MARK_VISIBLE (gcry_pk_algo_name) -MARK_VISIBLE (gcry_pk_ctl) -MARK_VISIBLE (gcry_pk_decrypt) -MARK_VISIBLE (gcry_pk_encrypt) -MARK_VISIBLE (gcry_pk_genkey) -MARK_VISIBLE (gcry_pk_get_keygrip) -MARK_VISIBLE (gcry_pk_get_curve) -MARK_VISIBLE (gcry_pk_get_param) -MARK_VISIBLE (gcry_pk_get_nbits) -MARK_VISIBLE (gcry_pk_list) -MARK_VISIBLE (gcry_pk_map_name) -MARK_VISIBLEX(gcry_pk_register) -MARK_VISIBLE (gcry_pk_sign) -MARK_VISIBLE (gcry_pk_testkey) -MARK_VISIBLE (gcry_pk_unregister) -MARK_VISIBLE (gcry_pk_verify) - -MARK_VISIBLE (gcry_ac_data_new) -MARK_VISIBLE (gcry_ac_data_destroy) -MARK_VISIBLE (gcry_ac_data_copy) -MARK_VISIBLE (gcry_ac_data_length) -MARK_VISIBLE (gcry_ac_data_clear) -MARK_VISIBLE (gcry_ac_data_set) -MARK_VISIBLE (gcry_ac_data_get_name) -MARK_VISIBLE (gcry_ac_data_get_index) -MARK_VISIBLE (gcry_ac_open) -MARK_VISIBLE (gcry_ac_close) -MARK_VISIBLE (gcry_ac_key_init) -MARK_VISIBLE (gcry_ac_key_pair_generate) -MARK_VISIBLE (gcry_ac_key_pair_extract) -MARK_VISIBLE (gcry_ac_key_data_get) -MARK_VISIBLE (gcry_ac_key_test) -MARK_VISIBLE (gcry_ac_key_get_nbits) -MARK_VISIBLE (gcry_ac_key_get_grip) -MARK_VISIBLE (gcry_ac_key_destroy) -MARK_VISIBLE (gcry_ac_key_pair_destroy) -MARK_VISIBLE (gcry_ac_data_encrypt) -MARK_VISIBLE (gcry_ac_data_decrypt) -MARK_VISIBLE (gcry_ac_data_sign) -MARK_VISIBLE (gcry_ac_data_verify) -MARK_VISIBLE (gcry_ac_id_to_name) -MARK_VISIBLE (gcry_ac_name_to_id) -/* MARK_VISIBLE (gcry_ac_list) Not defined although it is in - libgcrypt.vers. */ -MARK_VISIBLE (gcry_ac_data_encode) -MARK_VISIBLE (gcry_ac_data_decode) -MARK_VISIBLE (gcry_ac_mpi_to_os) -MARK_VISIBLE (gcry_ac_mpi_to_os_alloc) -MARK_VISIBLE (gcry_ac_os_to_mpi) -MARK_VISIBLE (gcry_ac_data_encrypt_scheme) -MARK_VISIBLE (gcry_ac_data_decrypt_scheme) -MARK_VISIBLE (gcry_ac_data_sign_scheme) -MARK_VISIBLE (gcry_ac_data_verify_scheme) -MARK_VISIBLE (gcry_ac_data_to_sexp) -MARK_VISIBLE (gcry_ac_data_from_sexp) -MARK_VISIBLE (gcry_ac_io_init) -MARK_VISIBLE (gcry_ac_io_init_va) - -MARK_VISIBLE (gcry_kdf_derive) - -MARK_VISIBLE (gcry_prime_check) -MARK_VISIBLE (gcry_prime_generate) -MARK_VISIBLE (gcry_prime_group_generator) -MARK_VISIBLE (gcry_prime_release_factors) - -MARK_VISIBLE (gcry_random_add_bytes) -MARK_VISIBLE (gcry_random_bytes) -MARK_VISIBLE (gcry_random_bytes_secure) -MARK_VISIBLE (gcry_randomize) -MARK_VISIBLE (gcry_create_nonce) - -MARK_VISIBLE (gcry_sexp_alist) -MARK_VISIBLE (gcry_sexp_append) -MARK_VISIBLE (gcry_sexp_build) -MARK_VISIBLE (gcry_sexp_build_array) -MARK_VISIBLE (gcry_sexp_cadr) -MARK_VISIBLE (gcry_sexp_canon_len) -MARK_VISIBLE (gcry_sexp_car) -MARK_VISIBLE (gcry_sexp_cdr) -MARK_VISIBLE (gcry_sexp_cons) -MARK_VISIBLE (gcry_sexp_create) -MARK_VISIBLE (gcry_sexp_dump) -MARK_VISIBLE (gcry_sexp_find_token) -MARK_VISIBLE (gcry_sexp_length) -MARK_VISIBLE (gcry_sexp_new) -MARK_VISIBLE (gcry_sexp_nth) -MARK_VISIBLE (gcry_sexp_nth_data) -MARK_VISIBLE (gcry_sexp_nth_mpi) -MARK_VISIBLE (gcry_sexp_prepend) -MARK_VISIBLE (gcry_sexp_release) -MARK_VISIBLE (gcry_sexp_sprint) -MARK_VISIBLE (gcry_sexp_sscan) -MARK_VISIBLE (gcry_sexp_vlist) -MARK_VISIBLE (gcry_sexp_nth_string) - -MARK_VISIBLE (gcry_mpi_add) -MARK_VISIBLE (gcry_mpi_add_ui) -MARK_VISIBLE (gcry_mpi_addm) -MARK_VISIBLE (gcry_mpi_aprint) -MARK_VISIBLE (gcry_mpi_clear_bit) -MARK_VISIBLE (gcry_mpi_clear_flag) -MARK_VISIBLE (gcry_mpi_clear_highbit) -MARK_VISIBLE (gcry_mpi_cmp) -MARK_VISIBLE (gcry_mpi_cmp_ui) -MARK_VISIBLE (gcry_mpi_copy) -MARK_VISIBLE (gcry_mpi_div) -MARK_VISIBLE (gcry_mpi_dump) -MARK_VISIBLE (gcry_mpi_gcd) -MARK_VISIBLE (gcry_mpi_get_flag) -MARK_VISIBLE (gcry_mpi_get_nbits) -MARK_VISIBLE (gcry_mpi_get_opaque) -MARK_VISIBLE (gcry_mpi_invm) -MARK_VISIBLE (gcry_mpi_mod) -MARK_VISIBLE (gcry_mpi_mul) -MARK_VISIBLE (gcry_mpi_mul_2exp) -MARK_VISIBLE (gcry_mpi_mul_ui) -MARK_VISIBLE (gcry_mpi_mulm) -MARK_VISIBLE (gcry_mpi_new) -MARK_VISIBLE (gcry_mpi_powm) -MARK_VISIBLE (gcry_mpi_print) -MARK_VISIBLE (gcry_mpi_randomize) -MARK_VISIBLE (gcry_mpi_release) -MARK_VISIBLE (gcry_mpi_rshift) -MARK_VISIBLE (gcry_mpi_lshift) -MARK_VISIBLE (gcry_mpi_scan) -MARK_VISIBLE (gcry_mpi_set) -MARK_VISIBLE (gcry_mpi_set_bit) -MARK_VISIBLE (gcry_mpi_set_flag) -MARK_VISIBLE (gcry_mpi_set_highbit) -MARK_VISIBLE (gcry_mpi_set_opaque) -MARK_VISIBLE (gcry_mpi_set_ui) -MARK_VISIBLE (gcry_mpi_snew) -MARK_VISIBLE (gcry_mpi_sub) -MARK_VISIBLE (gcry_mpi_sub_ui) -MARK_VISIBLE (gcry_mpi_subm) -MARK_VISIBLE (gcry_mpi_swap) -MARK_VISIBLE (gcry_mpi_test_bit) - - - -#undef MARK_VISIBLE -#endif /*_GCRY_INCLUDED_BY_VISIBILITY_C*/ - -#endif /*GCRY_VISIBILITY_H*/ diff --git a/grub-core/lib/libgcrypt_wrap/mem.c b/grub-core/lib/libgcrypt_wrap/mem.c deleted file mode 100644 index 74c6eafe5..000000000 --- a/grub-core/lib/libgcrypt_wrap/mem.c +++ /dev/null @@ -1,140 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -void * -gcry_malloc (size_t n) -{ - return grub_malloc (n); -} - -void * -gcry_malloc_secure (size_t n) -{ - return grub_malloc (n); -} - -void -gcry_free (void *a) -{ - grub_free (a); -} - -int -gcry_is_secure (const void *a __attribute__ ((unused))) -{ - return 0; -} - -/* FIXME: implement "exit". */ -void * -gcry_xcalloc (size_t n, size_t m) -{ - void *ret; - size_t sz; - if (grub_mul (n, m, &sz)) - grub_fatal ("gcry_xcalloc would overflow"); - ret = grub_zalloc (sz); - if (!ret) - grub_fatal ("gcry_xcalloc failed"); - return ret; -} - -void * -gcry_xmalloc_secure (size_t n) -{ - void *ret; - ret = grub_malloc (n); - if (!ret) - grub_fatal ("gcry_xmalloc failed"); - return ret; -} - -void * -gcry_xcalloc_secure (size_t n, size_t m) -{ - void *ret; - size_t sz; - if (grub_mul (n, m, &sz)) - grub_fatal ("gcry_xcalloc would overflow"); - ret = grub_zalloc (sz); - if (!ret) - grub_fatal ("gcry_xcalloc failed"); - return ret; -} - -void * -gcry_xmalloc (size_t n) -{ - void *ret; - ret = grub_malloc (n); - if (!ret) - grub_fatal ("gcry_xmalloc failed"); - return ret; -} - -void * -gcry_xrealloc (void *a, size_t n) -{ - void *ret; - ret = grub_realloc (a, n); - if (!ret) - grub_fatal ("gcry_xrealloc failed"); - return ret; -} - -void -_gcry_check_heap (const void *a __attribute__ ((unused))) -{ - -} - -void _gcry_log_printf (const char *fmt, ...) -{ - va_list args; - const char *debug = grub_env_get ("debug"); - - if (! debug) - return; - - if (grub_strword (debug, "all") || grub_strword (debug, "gcrypt")) - { - grub_printf ("gcrypt: "); - va_start (args, fmt); - grub_vprintf (fmt, args); - va_end (args); - grub_refresh (); - } -} - -void _gcry_log_bug (const char *fmt, ...) -{ - va_list args; - - grub_printf ("gcrypt bug: "); - va_start (args, fmt); - grub_vprintf (fmt, args); - va_end (args); - grub_refresh (); - grub_fatal ("gcrypt bug"); -} - -gcry_err_code_t -gpg_error_from_syserror (void) -{ - switch (grub_errno) - { - case GRUB_ERR_NONE: - return GPG_ERR_NO_ERROR; - case GRUB_ERR_OUT_OF_MEMORY: - return GPG_ERR_OUT_OF_MEMORY; - default: - return GPG_ERR_GENERAL; - } -} diff --git a/grub-core/lib/libtasn1-patches/0001-libtasn1-disable-code-not-needed-in-grub.patch b/grub-core/lib/libtasn1-patches/0001-libtasn1-disable-code-not-needed-in-grub.patch deleted file mode 100644 index 85bfa0732..000000000 --- a/grub-core/lib/libtasn1-patches/0001-libtasn1-disable-code-not-needed-in-grub.patch +++ /dev/null @@ -1,320 +0,0 @@ -From f534b3c0902adf207b7e51b8364284fe6a06731b Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 1 May 2020 17:12:23 +1000 -Subject: [PATCH 01/13] libtasn1: disable code not needed in grub - -We don't expect to be able to write ASN.1, only read it, -so we can disable some code. - -Do that with #if 0/#endif, rather than deletion. This means -that the difference between upstream and grub is smaller, -which should make updating libtasn1 easier in the future. - -With these exclusions we also avoid the need for minmax.h, -which is convenient because it means we don't have to -import it from gnulib. - -Signed-off-by: Daniel Axtens -Signed-off-by: Gary Lin -Reviewed-by: Daniel Kiper ---- - grub-core/lib/libtasn1-grub/lib/coding.c | 12 ++++++++++-- - grub-core/lib/libtasn1-grub/lib/decoding.c | 2 ++ - grub-core/lib/libtasn1-grub/lib/element.c | 6 +++--- - grub-core/lib/libtasn1-grub/lib/errors.c | 3 +++ - grub-core/lib/libtasn1-grub/lib/structure.c | 10 ++++++---- - grub-core/lib/libtasn1-grub/libtasn1.h | 15 +++++++++++++++ - 6 files changed, 39 insertions(+), 9 deletions(-) - -diff --git a/grub-core/lib/libtasn1-grub/lib/coding.c b/grub-core/lib/libtasn1-grub/lib/coding.c -index ea5bc370e..5d03bca9d 100644 ---- a/grub-core/lib/libtasn1-grub/lib/coding.c -+++ b/grub-core/lib/libtasn1-grub/lib/coding.c -@@ -30,11 +30,11 @@ - #include "parser_aux.h" - #include - #include "element.h" --#include "minmax.h" - #include - - #define MAX_TAG_LEN 16 - -+#if 0 /* GRUB SKIPPED IMPORTING */ - /******************************************************/ - /* Function : _asn1_error_description_value_not_found */ - /* Description: creates the ErrorDescription string */ -@@ -58,6 +58,7 @@ _asn1_error_description_value_not_found (asn1_node node, - Estrcat (ErrorDescription, "' not found"); - - } -+#endif - - /** - * asn1_length_der: -@@ -244,6 +245,7 @@ asn1_encode_simple_der (unsigned int etype, const unsigned char *str, - return ASN1_SUCCESS; - } - -+#if 0 /* GRUB SKIPPED IMPORTING */ - /******************************************************/ - /* Function : _asn1_time_der */ - /* Description: creates the DER coding for a TIME */ -@@ -278,7 +280,7 @@ _asn1_time_der (unsigned char *str, int str_len, unsigned char *der, - - return ASN1_SUCCESS; - } -- -+#endif - - /* - void -@@ -519,6 +521,7 @@ asn1_bit_der (const unsigned char *str, int bit_len, - } - - -+#if 0 /* GRUB SKIPPED IMPORTING */ - /******************************************************/ - /* Function : _asn1_complete_explicit_tag */ - /* Description: add the length coding to the EXPLICIT */ -@@ -595,6 +598,7 @@ _asn1_complete_explicit_tag (asn1_node node, unsigned char *der, - - return ASN1_SUCCESS; - } -+#endif - - const tag_and_class_st _asn1_tags[] = { - [ASN1_ETYPE_GENERALSTRING] = -@@ -647,6 +651,8 @@ const tag_and_class_st _asn1_tags[] = { - - unsigned int _asn1_tags_size = sizeof (_asn1_tags) / sizeof (_asn1_tags[0]); - -+ -+#if 0 /* GRUB SKIPPED IMPORTING */ - /******************************************************/ - /* Function : _asn1_insert_tag_der */ - /* Description: creates the DER coding of tags of one */ -@@ -1423,3 +1429,5 @@ error: - asn1_delete_structure (&node); - return err; - } -+ -+#endif -diff --git a/grub-core/lib/libtasn1-grub/lib/decoding.c b/grub-core/lib/libtasn1-grub/lib/decoding.c -index b9245c486..bf9cb13ac 100644 ---- a/grub-core/lib/libtasn1-grub/lib/decoding.c -+++ b/grub-core/lib/libtasn1-grub/lib/decoding.c -@@ -1620,6 +1620,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len, - return asn1_der_decoding2 (element, ider, &ider_len, 0, errorDescription); - } - -+#if 0 /* GRUB SKIPPED IMPORTING */ - /** - * asn1_der_decoding_element: - * @structure: pointer to an ASN1 structure -@@ -1650,6 +1651,7 @@ asn1_der_decoding_element (asn1_node * structure, const char *elementName, - { - return asn1_der_decoding (structure, ider, len, errorDescription); - } -+#endif - - /** - * asn1_der_decoding_startEnd: -diff --git a/grub-core/lib/libtasn1-grub/lib/element.c b/grub-core/lib/libtasn1-grub/lib/element.c -index d4c558e10..bc4c3c8d7 100644 ---- a/grub-core/lib/libtasn1-grub/lib/element.c -+++ b/grub-core/lib/libtasn1-grub/lib/element.c -@@ -118,7 +118,7 @@ _asn1_convert_integer (const unsigned char *value, unsigned char *value_out, - value_out[k2 - k] = val[k2]; - } - --#if 0 -+#if 0 /* GRUB SKIPPED IMPORTING */ - printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len); - for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) - printf (", vOut[%d]=%d", k, value_out[k]); -@@ -191,7 +191,7 @@ _asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcache) - return ASN1_SUCCESS; - } - -- -+#if 0 - /** - * asn1_write_value: - * @node_root: pointer to a structure -@@ -646,7 +646,7 @@ asn1_write_value (asn1_node node_root, const char *name, - - return ASN1_SUCCESS; - } -- -+#endif - - #define PUT_VALUE( ptr, ptr_size, data, data_size) \ - *len = data_size; \ -diff --git a/grub-core/lib/libtasn1-grub/lib/errors.c b/grub-core/lib/libtasn1-grub/lib/errors.c -index aef5dfe6f..2b2322152 100644 ---- a/grub-core/lib/libtasn1-grub/lib/errors.c -+++ b/grub-core/lib/libtasn1-grub/lib/errors.c -@@ -57,6 +57,8 @@ static const libtasn1_error_entry error_algorithms[] = { - {0, 0} - }; - -+ -+#if 0 /* GRUB SKIPPED IMPORTING */ - /** - * asn1_perror: - * @error: is an error returned by a libtasn1 function. -@@ -73,6 +75,7 @@ asn1_perror (int error) - const char *str = asn1_strerror (error); - fprintf (stderr, "LIBTASN1 ERROR: %s\n", str ? str : "(null)"); - } -+#endif - - /** - * asn1_strerror: -diff --git a/grub-core/lib/libtasn1-grub/lib/structure.c b/grub-core/lib/libtasn1-grub/lib/structure.c -index 512dd601f..f5a947d57 100644 ---- a/grub-core/lib/libtasn1-grub/lib/structure.c -+++ b/grub-core/lib/libtasn1-grub/lib/structure.c -@@ -76,7 +76,7 @@ _asn1_find_left (asn1_node_const node) - return node->left; - } - -- -+#if 0 /* GRUB SKIPPED IMPORTING */ - int - _asn1_create_static_structure (asn1_node_const pointer, - char *output_file_name, char *vector_name) -@@ -155,7 +155,7 @@ _asn1_create_static_structure (asn1_node_const pointer, - - return ASN1_SUCCESS; - } -- -+#endif - - /** - * asn1_array2tree: -@@ -721,7 +721,7 @@ asn1_create_element (asn1_node_const definitions, const char *source_name, - return res; - } - -- -+#if 0 /* GRUB SKIPPED IMPORTING */ - /** - * asn1_print_structure: - * @out: pointer to the output file (e.g. stdout). -@@ -1062,7 +1062,7 @@ asn1_print_structure (FILE * out, asn1_node_const structure, const char *name, - } - } - } -- -+#endif - - - /** -@@ -1158,6 +1158,7 @@ asn1_find_structure_from_oid (asn1_node_const definitions, - return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ - } - -+#if 0 /* GRUB SKIPPED IMPORTING */ - /** - * asn1_copy_node: - * @dst: Destination asn1 node. -@@ -1207,6 +1208,7 @@ asn1_copy_node (asn1_node dst, const char *dst_name, - - return result; - } -+#endif - - /** - * asn1_dup_node: -diff --git a/grub-core/lib/libtasn1-grub/libtasn1.h b/grub-core/lib/libtasn1-grub/libtasn1.h -index 51cc7879f..058ab27b0 100644 ---- a/grub-core/lib/libtasn1-grub/libtasn1.h -+++ b/grub-core/lib/libtasn1-grub/libtasn1.h -@@ -318,6 +318,8 @@ extern "C" - /* Functions definitions */ - /***********************************/ - -+/* These functions are not used in grub and should not be referenced. */ -+# if 0 /* GRUB SKIPPED IMPORTING */ - extern ASN1_API int - asn1_parser2tree (const char *file, - asn1_node * definitions, char *error_desc); -@@ -326,14 +328,17 @@ extern "C" - asn1_parser2array (const char *inputFileName, - const char *outputFileName, - const char *vectorName, char *error_desc); -+# endif - - extern ASN1_API int - asn1_array2tree (const asn1_static_node * array, - asn1_node * definitions, char *errorDescription); - -+# if 0 /* GRUB SKIPPED IMPORTING */ - extern ASN1_API void - asn1_print_structure (FILE * out, asn1_node_const structure, - const char *name, int mode); -+# endif - - extern ASN1_API int - asn1_create_element (asn1_node_const definitions, -@@ -347,9 +352,11 @@ extern "C" - extern ASN1_API int - asn1_delete_element (asn1_node structure, const char *element_name); - -+# if 0 /* GRUB SKIPPED IMPORTING */ - extern ASN1_API int - asn1_write_value (asn1_node node_root, const char *name, - const void *ivalue, int len); -+# endif - - extern ASN1_API int - asn1_read_value (asn1_node_const root, const char *name, -@@ -366,9 +373,11 @@ extern "C" - asn1_number_of_elements (asn1_node_const element, const char *name, - int *num); - -+# if 0 /* GRUB SKIPPED IMPORTING */ - extern ASN1_API int - asn1_der_coding (asn1_node_const element, const char *name, - void *ider, int *len, char *ErrorDescription); -+# endif - - extern ASN1_API int - asn1_der_decoding2 (asn1_node * element, const void *ider, -@@ -379,6 +388,7 @@ extern "C" - asn1_der_decoding (asn1_node * element, const void *ider, - int ider_len, char *errorDescription); - -+# if 0 /* GRUB SKIPPED IMPORTING */ - /* Do not use. Use asn1_der_decoding() instead. */ - extern ASN1_API int - asn1_der_decoding_element (asn1_node * structure, -@@ -386,6 +396,7 @@ extern "C" - const void *ider, int len, - char *errorDescription) - _ASN1_GCC_ATTR_DEPRECATED; -+# endif - - extern ASN1_API int - asn1_der_decoding_startEnd (asn1_node element, -@@ -411,12 +422,16 @@ extern "C" - const char - *oidValue); - -+# if 0 /* GRUB SKIPPED IMPORTING */ - __LIBTASN1_PURE__ - extern ASN1_API const char *asn1_check_version (const char *req_version); -+# endif - - __LIBTASN1_PURE__ extern ASN1_API const char *asn1_strerror (int error); - -+# if 0 /* GRUB SKIPPED IMPORTING */ - extern ASN1_API void asn1_perror (int error); -+# endif - - # define ASN1_MAX_TAG_SIZE 4 - # define ASN1_MAX_LENGTH_SIZE 9 --- -2.43.0 - diff --git a/grub-core/lib/libtasn1-patches/0002-libtasn1-replace-strcat-with-strcpy-in-_asn1_str_cat.patch b/grub-core/lib/libtasn1-patches/0002-libtasn1-replace-strcat-with-strcpy-in-_asn1_str_cat.patch deleted file mode 100644 index 908016df7..000000000 --- a/grub-core/lib/libtasn1-patches/0002-libtasn1-replace-strcat-with-strcpy-in-_asn1_str_cat.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 93453558fbe34634096770933b3dc40c9199dfb4 Mon Sep 17 00:00:00 2001 -From: Gary Lin -Date: Tue, 20 Aug 2024 16:14:51 +0800 -Subject: [PATCH 02/13] libtasn1: replace strcat() with strcpy() in - _asn1_str_cat() - -strcat() is not available in GRUB. This commit replaces strcat() with -strcpy() in _asn1_str_cat() as the preparation to replace other strcat() -with the bounds-checking _asn1_str_cat(). - -Signed-off-by: Daniel Axtens -Signed-off-by: Gary Lin -Reviewed-by: Daniel Kiper ---- - grub-core/lib/libtasn1-grub/lib/gstr.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/lib/libtasn1-grub/lib/gstr.c b/grub-core/lib/libtasn1-grub/lib/gstr.c -index eef419554..a9c16f5d3 100644 ---- a/grub-core/lib/libtasn1-grub/lib/gstr.c -+++ b/grub-core/lib/libtasn1-grub/lib/gstr.c -@@ -36,7 +36,7 @@ _asn1_str_cat (char *dest, size_t dest_tot_size, const char *src) - - if (dest_tot_size - dest_size > str_size) - { -- strcat (dest, src); -+ strcpy (dest + dest_size, src); - } - else - { --- -2.43.0 - diff --git a/grub-core/lib/libtasn1-patches/0003-libtasn1-replace-strcat-with-_asn1_str_cat.patch b/grub-core/lib/libtasn1-patches/0003-libtasn1-replace-strcat-with-_asn1_str_cat.patch deleted file mode 100644 index d92ae1586..000000000 --- a/grub-core/lib/libtasn1-patches/0003-libtasn1-replace-strcat-with-_asn1_str_cat.patch +++ /dev/null @@ -1,71 +0,0 @@ -From b5efa707619fde1921a3cbd83f4ee95a7d995fa0 Mon Sep 17 00:00:00 2001 -From: Gary Lin -Date: Tue, 20 Aug 2024 16:26:45 +0800 -Subject: [PATCH 03/13] libtasn1: replace strcat() with _asn1_str_cat() - -strcat() is not available in GRUB. This commit replaces strcat() and -_asn1_strcat() with the bounds-checking _asn1_str_cat(). - -Signed-off-by: Daniel Axtens -Signed-off-by: Gary Lin -Reviewed-by: Daniel Kiper ---- - grub-core/lib/libtasn1-grub/lib/decoding.c | 8 ++++---- - grub-core/lib/libtasn1-grub/lib/element.c | 2 +- - grub-core/lib/libtasn1-grub/lib/int.h | 1 - - 3 files changed, 5 insertions(+), 6 deletions(-) - -diff --git a/grub-core/lib/libtasn1-grub/lib/decoding.c b/grub-core/lib/libtasn1-grub/lib/decoding.c -index bf9cb13ac..51859fe36 100644 ---- a/grub-core/lib/libtasn1-grub/lib/decoding.c -+++ b/grub-core/lib/libtasn1-grub/lib/decoding.c -@@ -2016,8 +2016,8 @@ asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element, - (p2->type & CONST_ASSIGN)) - { - strcpy (name, definitions->name); -- strcat (name, "."); -- strcat (name, p2->name); -+ _asn1_str_cat (name, sizeof (name), "."); -+ _asn1_str_cat (name, sizeof (name), p2->name); - - len = sizeof (value); - result = asn1_read_value (definitions, name, value, &len); -@@ -2034,8 +2034,8 @@ asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element, - if (p2) - { - strcpy (name, definitions->name); -- strcat (name, "."); -- strcat (name, p2->name); -+ _asn1_str_cat (name, sizeof (name), "."); -+ _asn1_str_cat (name, sizeof (name), p2->name); - - result = asn1_create_element (definitions, name, &aux); - if (result == ASN1_SUCCESS) -diff --git a/grub-core/lib/libtasn1-grub/lib/element.c b/grub-core/lib/libtasn1-grub/lib/element.c -index bc4c3c8d7..8694fecb9 100644 ---- a/grub-core/lib/libtasn1-grub/lib/element.c -+++ b/grub-core/lib/libtasn1-grub/lib/element.c -@@ -688,7 +688,7 @@ asn1_write_value (asn1_node node_root, const char *name, - return ASN1_MEM_ERROR; \ - } else { \ - /* this strcat is checked */ \ -- if (ptr) _asn1_strcat (ptr, data); \ -+ if (ptr) _asn1_str_cat ((char *)ptr, ptr_size, (const char *)data); \ - } - - /** -diff --git a/grub-core/lib/libtasn1-grub/lib/int.h b/grub-core/lib/libtasn1-grub/lib/int.h -index d94d51c8c..cadd80df6 100644 ---- a/grub-core/lib/libtasn1-grub/lib/int.h -+++ b/grub-core/lib/libtasn1-grub/lib/int.h -@@ -115,7 +115,6 @@ extern const tag_and_class_st _asn1_tags[]; - # define _asn1_strtoul(n,e,b) strtoul((const char *) n, e, b) - # define _asn1_strcmp(a,b) strcmp((const char *)a, (const char *)b) - # define _asn1_strcpy(a,b) strcpy((char *)a, (const char *)b) --# define _asn1_strcat(a,b) strcat((char *)a, (const char *)b) - - # if SIZEOF_UNSIGNED_LONG_INT == 8 - # define _asn1_strtou64(n,e,b) strtoul((const char *) n, e, b) --- -2.43.0 - diff --git a/grub-core/lib/libtasn1-patches/0004-libtasn1-adjust-the-header-paths-in-libtasn1.h.patch b/grub-core/lib/libtasn1-patches/0004-libtasn1-adjust-the-header-paths-in-libtasn1.h.patch deleted file mode 100644 index a5d5be417..000000000 --- a/grub-core/lib/libtasn1-patches/0004-libtasn1-adjust-the-header-paths-in-libtasn1.h.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 24036474fab426917507fcadc85a83fa0b1cef3b Mon Sep 17 00:00:00 2001 -From: Gary Lin -Date: Tue, 25 Jun 2024 16:30:40 +0800 -Subject: [PATCH 04/13] libtasn1: adjust the header paths in libtasn1.h - -Since libtasn1.h is the header to be included by users, including the -standard POSIX headers in libtasn1.h would force the user to add the -CFLAGS/CPPFLAGS for the POSIX headers. - -This commit adjusts the header paths to use the grub headers instead of -the standard POSIX headers, so that users only need to include -libtasn1.h to use libtasn1 functions. - -Signed-off-by: Daniel Axtens -Signed-off-by: Gary Lin -Reviewed-by: Daniel Kiper ---- - grub-core/lib/libtasn1-grub/libtasn1.h | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/grub-core/lib/libtasn1-grub/libtasn1.h b/grub-core/lib/libtasn1-grub/libtasn1.h -index 058ab27b0..7d64b6ab7 100644 ---- a/grub-core/lib/libtasn1-grub/libtasn1.h -+++ b/grub-core/lib/libtasn1-grub/libtasn1.h -@@ -54,9 +54,8 @@ - # define __LIBTASN1_PURE__ - # endif - --# include --# include --# include /* for FILE* */ -+# include -+# include - - # ifdef __cplusplus - extern "C" --- -2.43.0 - diff --git a/grub-core/lib/libtasn1-patches/0005-libtasn1-Use-grub_divmod64-for-division.patch b/grub-core/lib/libtasn1-patches/0005-libtasn1-Use-grub_divmod64-for-division.patch deleted file mode 100644 index 201df10f7..000000000 --- a/grub-core/lib/libtasn1-patches/0005-libtasn1-Use-grub_divmod64-for-division.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 5ee39f0bb8b0b713f766c0fc83439d83ac2c0bf2 Mon Sep 17 00:00:00 2001 -From: Gary Lin -Date: Tue, 25 Jun 2024 16:32:50 +0800 -Subject: [PATCH 05/13] libtasn1: Use grub_divmod64() for division - -Replace a 64-bit division with a call to grub_divmod64(), preventing -creation of __udivdi3() calls on 32-bit platforms. - -Signed-off-by: Daniel Axtens -Signed-off-by: Gary Lin -Reviewed-by: Daniel Kiper ---- - grub-core/lib/libtasn1-grub/lib/parser_aux.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/lib/libtasn1-grub/lib/parser_aux.c b/grub-core/lib/libtasn1-grub/lib/parser_aux.c -index c05bd2339..e4e4c0556 100644 ---- a/grub-core/lib/libtasn1-grub/lib/parser_aux.c -+++ b/grub-core/lib/libtasn1-grub/lib/parser_aux.c -@@ -632,7 +632,7 @@ _asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE]) - count = 0; - do - { -- d = val / 10; -+ d = grub_divmod64(val, 10, NULL); - r = val - d * 10; - temp[start + count] = '0' + (char) r; - count++; --- -2.43.0 - diff --git a/grub-core/lib/libtasn1-patches/0006-libtasn1-fix-the-potential-buffer-overrun.patch b/grub-core/lib/libtasn1-patches/0006-libtasn1-fix-the-potential-buffer-overrun.patch deleted file mode 100644 index f9f45ae72..000000000 --- a/grub-core/lib/libtasn1-patches/0006-libtasn1-fix-the-potential-buffer-overrun.patch +++ /dev/null @@ -1,36 +0,0 @@ -From f629f58b01b3e88052be5e50f51a667181203e05 Mon Sep 17 00:00:00 2001 -From: Gary Lin -Date: Mon, 8 Apr 2024 14:57:21 +0800 -Subject: [PATCH 06/13] libtasn1: fix the potential buffer overrun - -In _asn1_tag_der(), the first while loop for the long form may end up -with a 'k' value with 'ASN1_MAX_TAG_SIZE' and cause the buffer overrun -in the second while loop. This commit tweaks the conditional check to -avoid producing a too large 'k'. - -This is a quick fix and may differ from the official upstream fix. - -libtasn1 issue: https://gitlab.com/gnutls/libtasn1/-/issues/49 - -Signed-off-by: Gary Lin -Reviewed-by: Daniel Kiper ---- - grub-core/lib/libtasn1-grub/lib/coding.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/lib/libtasn1-grub/lib/coding.c b/grub-core/lib/libtasn1-grub/lib/coding.c -index 5d03bca9d..0458829a5 100644 ---- a/grub-core/lib/libtasn1-grub/lib/coding.c -+++ b/grub-core/lib/libtasn1-grub/lib/coding.c -@@ -143,7 +143,7 @@ _asn1_tag_der (unsigned char class, unsigned int tag_value, - temp[k++] = tag_value & 0x7F; - tag_value >>= 7; - -- if (k > ASN1_MAX_TAG_SIZE - 1) -+ if (k >= ASN1_MAX_TAG_SIZE - 1) - break; /* will not encode larger tags */ - } - *ans_len = k + 1; --- -2.43.0 - diff --git a/grub-core/lib/libtasn1-patches/0007-asn1_test-include-asn1_test.h-only.patch b/grub-core/lib/libtasn1-patches/0007-asn1_test-include-asn1_test.h-only.patch deleted file mode 100644 index 29b931368..000000000 --- a/grub-core/lib/libtasn1-patches/0007-asn1_test-include-asn1_test.h-only.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 9cc63a71d6772947127d4d77e135d5fda68ccb8d Mon Sep 17 00:00:00 2001 -From: Gary Lin -Date: Fri, 16 Aug 2024 14:10:21 +0800 -Subject: [PATCH 07/13] asn1_test: include asn1_test.h only - -This commit removes all the headers and only uses asn1_test.h. -To avoid including int.h from grub-core/lib/libtasn1-grub/lib/, -CONST_DOWN is defined in reproducers.c. - -Signed-off-by: Daniel Axtens -Signed-off-by: Gary Lin -Reviewed-by: Daniel Kiper ---- - grub-core/tests/asn1/tests/CVE-2018-1000654.c | 4 +--- - grub-core/tests/asn1/tests/Test_overflow.c | 7 +------ - grub-core/tests/asn1/tests/Test_simple.c | 6 +----- - grub-core/tests/asn1/tests/Test_strings.c | 6 +----- - grub-core/tests/asn1/tests/object-id-decoding.c | 6 +----- - grub-core/tests/asn1/tests/object-id-encoding.c | 6 +----- - grub-core/tests/asn1/tests/octet-string.c | 6 +----- - grub-core/tests/asn1/tests/reproducers.c | 8 ++------ - 8 files changed, 9 insertions(+), 40 deletions(-) - -diff --git a/grub-core/tests/asn1/tests/CVE-2018-1000654.c b/grub-core/tests/asn1/tests/CVE-2018-1000654.c -index 0c22b7012..98c2a8b8c 100644 ---- a/grub-core/tests/asn1/tests/CVE-2018-1000654.c -+++ b/grub-core/tests/asn1/tests/CVE-2018-1000654.c -@@ -22,9 +22,7 @@ - /* Description: reproducer for CVE-2018-1000654 */ - /****************************************************************/ - --#include --#include --#include -+#include "asn1_test.h" - #include "CVE-2018-1000654-1_asn1_tab.h" - #include "CVE-2018-1000654-2_asn1_tab.h" - -diff --git a/grub-core/tests/asn1/tests/Test_overflow.c b/grub-core/tests/asn1/tests/Test_overflow.c -index c61dea4bb..73e9d8c68 100644 ---- a/grub-core/tests/asn1/tests/Test_overflow.c -+++ b/grub-core/tests/asn1/tests/Test_overflow.c -@@ -20,12 +20,7 @@ - - /* Written by Simon Josefsson */ - --#include --#include --#include --#include -- --#include "libtasn1.h" -+#include "asn1_test.h" - - int - main (int argc, char **argv) -diff --git a/grub-core/tests/asn1/tests/Test_simple.c b/grub-core/tests/asn1/tests/Test_simple.c -index 6cd07e069..3aa8ce21b 100644 ---- a/grub-core/tests/asn1/tests/Test_simple.c -+++ b/grub-core/tests/asn1/tests/Test_simple.c -@@ -20,11 +20,7 @@ - * - */ - --#include --#include --#include -- --#include "libtasn1.h" -+#include "asn1_test.h" - - struct tv - { -diff --git a/grub-core/tests/asn1/tests/Test_strings.c b/grub-core/tests/asn1/tests/Test_strings.c -index 27f7215e1..c49229af9 100644 ---- a/grub-core/tests/asn1/tests/Test_strings.c -+++ b/grub-core/tests/asn1/tests/Test_strings.c -@@ -20,11 +20,7 @@ - * - */ - --#include --#include --#include -- --#include "libtasn1.h" -+#include "asn1_test.h" - - struct tv - { -diff --git a/grub-core/tests/asn1/tests/object-id-decoding.c b/grub-core/tests/asn1/tests/object-id-decoding.c -index 06a6c52a2..0a77db752 100644 ---- a/grub-core/tests/asn1/tests/object-id-decoding.c -+++ b/grub-core/tests/asn1/tests/object-id-decoding.c -@@ -18,11 +18,7 @@ - * - */ - --#include --#include --#include -- --#include "libtasn1.h" -+#include "asn1_test.h" - - struct tv - { -diff --git a/grub-core/tests/asn1/tests/object-id-encoding.c b/grub-core/tests/asn1/tests/object-id-encoding.c -index 1a3396986..e32835830 100644 ---- a/grub-core/tests/asn1/tests/object-id-encoding.c -+++ b/grub-core/tests/asn1/tests/object-id-encoding.c -@@ -18,11 +18,7 @@ - * - */ - --#include --#include --#include -- --#include "libtasn1.h" -+#include "asn1_test.h" - - struct tv - { -diff --git a/grub-core/tests/asn1/tests/octet-string.c b/grub-core/tests/asn1/tests/octet-string.c -index 69eb18a62..8e803af41 100644 ---- a/grub-core/tests/asn1/tests/octet-string.c -+++ b/grub-core/tests/asn1/tests/octet-string.c -@@ -20,11 +20,7 @@ - * - */ - --#include --#include --#include -- --#include "libtasn1.h" -+#include "asn1_test.h" - - struct tv - { -diff --git a/grub-core/tests/asn1/tests/reproducers.c b/grub-core/tests/asn1/tests/reproducers.c -index a09d8b021..ce24e0991 100644 ---- a/grub-core/tests/asn1/tests/reproducers.c -+++ b/grub-core/tests/asn1/tests/reproducers.c -@@ -22,13 +22,9 @@ - /* Description: run reproducers for several fixed issues */ - /****************************************************************/ - --#include --#include --#include -+#include "asn1_test.h" - --#include -- --#include -+#define CONST_DOWN (1U<<29) - - /* produces endless loop (fixed by d4b624b2): - * The following translates into a single node with all pointers --- -2.43.0 - diff --git a/grub-core/lib/libtasn1-patches/0008-asn1_test-rename-the-main-functions-to-the-test-name.patch b/grub-core/lib/libtasn1-patches/0008-asn1_test-rename-the-main-functions-to-the-test-name.patch deleted file mode 100644 index bd34b47f8..000000000 --- a/grub-core/lib/libtasn1-patches/0008-asn1_test-rename-the-main-functions-to-the-test-name.patch +++ /dev/null @@ -1,129 +0,0 @@ -From c0f39b9eae745a36c44fc0dfa106675405ea154f Mon Sep 17 00:00:00 2001 -From: Gary Lin -Date: Fri, 16 Aug 2024 14:18:44 +0800 -Subject: [PATCH 08/13] asn1_test: rename the main functions to the test names - -This commit changes the main functions in the testcases to the test -names so that the real 'main' test function can invokes them. - -Signed-off-by: Daniel Axtens -Signed-off-by: Gary Lin -Reviewed-by: Daniel Kiper ---- - grub-core/tests/asn1/tests/CVE-2018-1000654.c | 2 +- - grub-core/tests/asn1/tests/Test_overflow.c | 2 +- - grub-core/tests/asn1/tests/Test_simple.c | 2 +- - grub-core/tests/asn1/tests/Test_strings.c | 2 +- - grub-core/tests/asn1/tests/object-id-decoding.c | 2 +- - grub-core/tests/asn1/tests/object-id-encoding.c | 2 +- - grub-core/tests/asn1/tests/octet-string.c | 2 +- - grub-core/tests/asn1/tests/reproducers.c | 2 +- - 8 files changed, 8 insertions(+), 8 deletions(-) - -diff --git a/grub-core/tests/asn1/tests/CVE-2018-1000654.c b/grub-core/tests/asn1/tests/CVE-2018-1000654.c -index 98c2a8b8c..a935ab541 100644 ---- a/grub-core/tests/asn1/tests/CVE-2018-1000654.c -+++ b/grub-core/tests/asn1/tests/CVE-2018-1000654.c -@@ -27,7 +27,7 @@ - #include "CVE-2018-1000654-2_asn1_tab.h" - - int --main (int argc, char *argv[]) -+test_CVE_2018_1000654 (void) - { - int result, verbose = 0; - asn1_node definitions = NULL; -diff --git a/grub-core/tests/asn1/tests/Test_overflow.c b/grub-core/tests/asn1/tests/Test_overflow.c -index 73e9d8c68..bc28d0826 100644 ---- a/grub-core/tests/asn1/tests/Test_overflow.c -+++ b/grub-core/tests/asn1/tests/Test_overflow.c -@@ -23,7 +23,7 @@ - #include "asn1_test.h" - - int --main (int argc, char **argv) -+test_overflow (void) - { - /* Test that values larger than long are rejected. This has worked - fine with all versions of libtasn1. */ -diff --git a/grub-core/tests/asn1/tests/Test_simple.c b/grub-core/tests/asn1/tests/Test_simple.c -index 3aa8ce21b..12993bfba 100644 ---- a/grub-core/tests/asn1/tests/Test_simple.c -+++ b/grub-core/tests/asn1/tests/Test_simple.c -@@ -73,7 +73,7 @@ static const struct tv tv[] = { - }; - - int --main (int argc, char *argv[]) -+test_simple (void) - { - int result; - unsigned char der[100]; -diff --git a/grub-core/tests/asn1/tests/Test_strings.c b/grub-core/tests/asn1/tests/Test_strings.c -index c49229af9..2538f2558 100644 ---- a/grub-core/tests/asn1/tests/Test_strings.c -+++ b/grub-core/tests/asn1/tests/Test_strings.c -@@ -70,7 +70,7 @@ static const struct tv ber[] = { - }; - - int --main (int argc, char *argv[]) -+test_strings (void) - { - int ret; - unsigned char tl[ASN1_MAX_TL_SIZE]; -diff --git a/grub-core/tests/asn1/tests/object-id-decoding.c b/grub-core/tests/asn1/tests/object-id-decoding.c -index 0a77db752..fdbb8ea21 100644 ---- a/grub-core/tests/asn1/tests/object-id-decoding.c -+++ b/grub-core/tests/asn1/tests/object-id-decoding.c -@@ -70,7 +70,7 @@ static const struct tv tv[] = { - }; - - int --main (int argc, char *argv[]) -+test_object_id_decoding (void) - { - char str[128]; - int ret, ret_len; -diff --git a/grub-core/tests/asn1/tests/object-id-encoding.c b/grub-core/tests/asn1/tests/object-id-encoding.c -index e32835830..a497015e3 100644 ---- a/grub-core/tests/asn1/tests/object-id-encoding.c -+++ b/grub-core/tests/asn1/tests/object-id-encoding.c -@@ -80,7 +80,7 @@ static const struct tv tv[] = { - }; - - int --main (int argc, char *argv[]) -+test_object_id_encoding (void) - { - unsigned char der[128]; - int ret, der_len, i, j; -diff --git a/grub-core/tests/asn1/tests/octet-string.c b/grub-core/tests/asn1/tests/octet-string.c -index 8e803af41..8c49c6e0c 100644 ---- a/grub-core/tests/asn1/tests/octet-string.c -+++ b/grub-core/tests/asn1/tests/octet-string.c -@@ -108,7 +108,7 @@ static const struct tv tv[] = { - }; - - int --main (int argc, char *argv[]) -+test_octet_string (void) - { - unsigned char str[100]; - unsigned char der[100]; -diff --git a/grub-core/tests/asn1/tests/reproducers.c b/grub-core/tests/asn1/tests/reproducers.c -index ce24e0991..e843b74b9 100644 ---- a/grub-core/tests/asn1/tests/reproducers.c -+++ b/grub-core/tests/asn1/tests/reproducers.c -@@ -49,7 +49,7 @@ const asn1_static_node tab[] = { - }; - - int --main (int argc, char *argv[]) -+test_reproducers (void) - { - int result, verbose = 0; - asn1_node definitions = NULL; --- -2.43.0 - diff --git a/grub-core/lib/libtasn1-patches/0009-asn1_test-return-either-0-or-1-to-reflect-the-result.patch b/grub-core/lib/libtasn1-patches/0009-asn1_test-return-either-0-or-1-to-reflect-the-result.patch deleted file mode 100644 index b76942d84..000000000 --- a/grub-core/lib/libtasn1-patches/0009-asn1_test-return-either-0-or-1-to-reflect-the-result.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 103ec39de5277e2683099017959415e107b885a5 Mon Sep 17 00:00:00 2001 -From: Gary Lin -Date: Fri, 16 Aug 2024 15:32:39 +0800 -Subject: [PATCH 09/13] asn1_test: return either 0 or 1 to reflect the results - -Some testcases use exit() to end the test. Since all the asn1 testcases -are invoked as functions, this commit replaces exit() with return to -reflect the test results, so that the main test function can check the -results. - -Signed-off-by: Daniel Axtens -Signed-off-by: Gary Lin -Reviewed-by: Daniel Kiper ---- - grub-core/tests/asn1/tests/CVE-2018-1000654.c | 6 +++--- - grub-core/tests/asn1/tests/reproducers.c | 6 +++--- - 2 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/grub-core/tests/asn1/tests/CVE-2018-1000654.c b/grub-core/tests/asn1/tests/CVE-2018-1000654.c -index a935ab541..2085b3cd3 100644 ---- a/grub-core/tests/asn1/tests/CVE-2018-1000654.c -+++ b/grub-core/tests/asn1/tests/CVE-2018-1000654.c -@@ -45,7 +45,7 @@ test_CVE_2018_1000654 (void) - { - asn1_perror (result); - printf ("ErrorDescription = %s\n\n", errorDescription); -- exit (1); -+ return 1; - } - - asn1_delete_structure (&definitions); -@@ -59,12 +59,12 @@ test_CVE_2018_1000654 (void) - { - asn1_perror (result); - printf ("ErrorDescription = %s\n\n", errorDescription); -- exit (1); -+ return 1; - } - - asn1_delete_structure (&definitions); - - if (verbose) - printf ("Success\n"); -- exit (0); -+ return 0; - } -diff --git a/grub-core/tests/asn1/tests/reproducers.c b/grub-core/tests/asn1/tests/reproducers.c -index e843b74b9..54a243d51 100644 ---- a/grub-core/tests/asn1/tests/reproducers.c -+++ b/grub-core/tests/asn1/tests/reproducers.c -@@ -63,7 +63,7 @@ test_reproducers (void) - { - asn1_perror (result); - printf ("ErrorDescription = %s\n\n", errorDescription); -- exit (EXIT_FAILURE); -+ return 1; - } - - asn1_delete_structure (&definitions); -@@ -74,7 +74,7 @@ test_reproducers (void) - { - asn1_perror (result); - printf ("ErrorDescription = %s\n\n", errorDescription); -- exit (EXIT_FAILURE); -+ return 1; - } - - asn1_delete_structure (&definitions); -@@ -82,5 +82,5 @@ test_reproducers (void) - if (verbose) - printf ("Success\n"); - -- exit (EXIT_SUCCESS); -+ return 0; - } --- -2.43.0 - diff --git a/grub-core/lib/libtasn1-patches/0010-asn1_test-remove-verbose-and-the-unnecessary-printf.patch b/grub-core/lib/libtasn1-patches/0010-asn1_test-remove-verbose-and-the-unnecessary-printf.patch deleted file mode 100644 index 2bd8ffb48..000000000 --- a/grub-core/lib/libtasn1-patches/0010-asn1_test-remove-verbose-and-the-unnecessary-printf.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 759bc707a924f89b0d32ba7be2f54e100f1d57b7 Mon Sep 17 00:00:00 2001 -From: Gary Lin -Date: Fri, 16 Aug 2024 14:26:38 +0800 -Subject: [PATCH 10/13] asn1_test: remove 'verbose' and the unnecessary - printf() - -This commit removes the 'verbose' variables and the unnecessary printf() -to simplify the output. - -Signed-off-by: Daniel Axtens -Signed-off-by: Gary Lin -Reviewed-by: Daniel Kiper ---- - grub-core/tests/asn1/tests/CVE-2018-1000654.c | 11 +---- - grub-core/tests/asn1/tests/Test_overflow.c | 40 +++---------------- - grub-core/tests/asn1/tests/reproducers.c | 8 +--- - 3 files changed, 7 insertions(+), 52 deletions(-) - -diff --git a/grub-core/tests/asn1/tests/CVE-2018-1000654.c b/grub-core/tests/asn1/tests/CVE-2018-1000654.c -index 2085b3cd3..81448cde8 100644 ---- a/grub-core/tests/asn1/tests/CVE-2018-1000654.c -+++ b/grub-core/tests/asn1/tests/CVE-2018-1000654.c -@@ -29,15 +29,10 @@ - int - test_CVE_2018_1000654 (void) - { -- int result, verbose = 0; -+ int result; - asn1_node definitions = NULL; - char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; - -- if (argc > 1) -- verbose = 1; -- -- printf ("Test 1\n"); -- - result = - asn1_array2tree (CVE_2018_1000654_1_asn1_tab, &definitions, - errorDescription); -@@ -50,8 +45,6 @@ test_CVE_2018_1000654 (void) - - asn1_delete_structure (&definitions); - -- printf ("Test 2\n"); -- - result = - asn1_array2tree (CVE_2018_1000654_2_asn1_tab, &definitions, - errorDescription); -@@ -64,7 +57,5 @@ test_CVE_2018_1000654 (void) - - asn1_delete_structure (&definitions); - -- if (verbose) -- printf ("Success\n"); - return 0; - } -diff --git a/grub-core/tests/asn1/tests/Test_overflow.c b/grub-core/tests/asn1/tests/Test_overflow.c -index bc28d0826..9f9578a1f 100644 ---- a/grub-core/tests/asn1/tests/Test_overflow.c -+++ b/grub-core/tests/asn1/tests/Test_overflow.c -@@ -27,11 +27,6 @@ test_overflow (void) - { - /* Test that values larger than long are rejected. This has worked - fine with all versions of libtasn1. */ -- int verbose = 0; -- -- if (argc > 1) -- verbose = 1; -- - { - unsigned char der[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; - long l; -@@ -39,12 +34,7 @@ test_overflow (void) - - l = asn1_get_length_der (der, sizeof der, &len); - -- if (l == -2L) -- { -- if (verbose) -- puts ("OK: asn1_get_length_der bignum"); -- } -- else -+ if (l != -2L) - { - printf ("ERROR: asn1_get_length_der bignum (l %ld len %d)\n", l, len); - return 1; -@@ -65,12 +55,7 @@ test_overflow (void) - - l = asn1_get_length_der (der, der_len, &len); - -- if (l == -2L) -- { -- if (verbose) -- puts ("OK: asn1_get_length_der intnum"); -- } -- else -+ if (l != -2L) - { - printf ("ERROR: asn1_get_length_der intnum (l %ld len %d)\n", l, - len); -@@ -92,12 +77,7 @@ test_overflow (void) - der_len = sizeof (der); - l = asn1_get_length_der (der, der_len, &len); - -- if (l == -4L) -- { -- if (verbose) -- puts ("OK: asn1_get_length_der overflow-small"); -- } -- else -+ if (l != -4L) - { - printf ("ERROR: asn1_get_length_der overflow-small (l %ld len %d)\n", - l, len); -@@ -119,12 +99,7 @@ test_overflow (void) - der_len = sizeof (der); - l = asn1_get_length_der (der, der_len, &len); - -- if (l == -4L) -- { -- if (verbose) -- puts ("OK: asn1_get_length_der overflow-large1"); -- } -- else -+ if (l != -4L) - { - printf ("ERROR: asn1_get_length_der overflow-large1 (l %ld len %d)\n", - l, len); -@@ -146,12 +121,7 @@ test_overflow (void) - der_len = sizeof (der); - l = asn1_get_length_der (der, der_len, &len); - -- if (l == -2L) -- { -- if (verbose) -- puts ("OK: asn1_get_length_der overflow-large2"); -- } -- else -+ if (l != -2L) - { - printf ("ERROR: asn1_get_length_der overflow-large2 (l %ld len %d)\n", - l, len); -diff --git a/grub-core/tests/asn1/tests/reproducers.c b/grub-core/tests/asn1/tests/reproducers.c -index 54a243d51..fa3cea762 100644 ---- a/grub-core/tests/asn1/tests/reproducers.c -+++ b/grub-core/tests/asn1/tests/reproducers.c -@@ -51,13 +51,10 @@ const asn1_static_node tab[] = { - int - test_reproducers (void) - { -- int result, verbose = 0; -+ int result; - asn1_node definitions = NULL; - char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; - -- if (argc > 1) -- verbose = 1; -- - result = asn1_array2tree (endless_asn1_tab, &definitions, errorDescription); - if (result != ASN1_SUCCESS) - { -@@ -79,8 +76,5 @@ test_reproducers (void) - - asn1_delete_structure (&definitions); - -- if (verbose) -- printf ("Success\n"); -- - return 0; - } --- -2.43.0 - diff --git a/grub-core/lib/libtasn1-patches/0011-asn1_test-print-the-error-messages-with-grub_printf.patch b/grub-core/lib/libtasn1-patches/0011-asn1_test-print-the-error-messages-with-grub_printf.patch deleted file mode 100644 index aadd362cd..000000000 --- a/grub-core/lib/libtasn1-patches/0011-asn1_test-print-the-error-messages-with-grub_printf.patch +++ /dev/null @@ -1,485 +0,0 @@ -From af5f0a651de09e44e78177b988857acd3208c4b6 Mon Sep 17 00:00:00 2001 -From: Gary Lin -Date: Fri, 16 Aug 2024 15:00:42 +0800 -Subject: [PATCH 11/13] asn1_test: print the error messages with grub_printf() - -This commit replaces printf() and fprintf() with grub_printf() to print -the error messages for the testcases. Besides, asn1_strerror() is used -to convert the result code to strings instead of asn1_perror(). - -Signed-off-by: Daniel Axtens -Signed-off-by: Gary Lin -Reviewed-by: Daniel Kiper ---- - grub-core/tests/asn1/tests/CVE-2018-1000654.c | 8 +-- - grub-core/tests/asn1/tests/Test_overflow.c | 14 ++--- - grub-core/tests/asn1/tests/Test_simple.c | 21 ++++---- - grub-core/tests/asn1/tests/Test_strings.c | 21 +++----- - .../tests/asn1/tests/object-id-decoding.c | 16 +++--- - .../tests/asn1/tests/object-id-encoding.c | 26 ++++----- - grub-core/tests/asn1/tests/octet-string.c | 54 ++++++++----------- - grub-core/tests/asn1/tests/reproducers.c | 6 +-- - 8 files changed, 67 insertions(+), 99 deletions(-) - -diff --git a/grub-core/tests/asn1/tests/CVE-2018-1000654.c b/grub-core/tests/asn1/tests/CVE-2018-1000654.c -index 81448cde8..b78667900 100644 ---- a/grub-core/tests/asn1/tests/CVE-2018-1000654.c -+++ b/grub-core/tests/asn1/tests/CVE-2018-1000654.c -@@ -38,8 +38,8 @@ test_CVE_2018_1000654 (void) - errorDescription); - if (result != ASN1_RECURSION) - { -- asn1_perror (result); -- printf ("ErrorDescription = %s\n\n", errorDescription); -+ grub_printf ("Error: %s\nErrorDescription = %s\n\n", -+ asn1_strerror (result), errorDescription); - return 1; - } - -@@ -50,8 +50,8 @@ test_CVE_2018_1000654 (void) - errorDescription); - if (result != ASN1_RECURSION) - { -- asn1_perror (result); -- printf ("ErrorDescription = %s\n\n", errorDescription); -+ grub_printf ("Error: %s\nErrorDescription = %s\n\n", -+ asn1_strerror (result), errorDescription); - return 1; - } - -diff --git a/grub-core/tests/asn1/tests/Test_overflow.c b/grub-core/tests/asn1/tests/Test_overflow.c -index 9f9578a1f..ffac8507a 100644 ---- a/grub-core/tests/asn1/tests/Test_overflow.c -+++ b/grub-core/tests/asn1/tests/Test_overflow.c -@@ -36,7 +36,7 @@ test_overflow (void) - - if (l != -2L) - { -- printf ("ERROR: asn1_get_length_der bignum (l %ld len %d)\n", l, len); -+ grub_printf ("ERROR: asn1_get_length_der bignum (l %ld len %d)\n", l, len); - return 1; - } - } -@@ -57,8 +57,7 @@ test_overflow (void) - - if (l != -2L) - { -- printf ("ERROR: asn1_get_length_der intnum (l %ld len %d)\n", l, -- len); -+ grub_printf ("ERROR: asn1_get_length_der intnum (l %ld len %d)\n", l, len); - return 1; - } - } -@@ -79,8 +78,7 @@ test_overflow (void) - - if (l != -4L) - { -- printf ("ERROR: asn1_get_length_der overflow-small (l %ld len %d)\n", -- l, len); -+ grub_printf ("ERROR: asn1_get_length_der overflow-small (l %ld len %d)\n", l, len); - return 1; - } - } -@@ -101,8 +99,7 @@ test_overflow (void) - - if (l != -4L) - { -- printf ("ERROR: asn1_get_length_der overflow-large1 (l %ld len %d)\n", -- l, len); -+ grub_printf ("ERROR: asn1_get_length_der overflow-large1 (l %ld len %d)\n", l, len); - return 1; - } - } -@@ -123,8 +120,7 @@ test_overflow (void) - - if (l != -2L) - { -- printf ("ERROR: asn1_get_length_der overflow-large2 (l %ld len %d)\n", -- l, len); -+ grub_printf ("ERROR: asn1_get_length_der overflow-large2 (l %ld len %d)\n", l, len); - return 1; - } - } -diff --git a/grub-core/tests/asn1/tests/Test_simple.c b/grub-core/tests/asn1/tests/Test_simple.c -index 12993bfba..dc70db191 100644 ---- a/grub-core/tests/asn1/tests/Test_simple.c -+++ b/grub-core/tests/asn1/tests/Test_simple.c -@@ -94,7 +94,7 @@ test_simple (void) - result = asn1_encode_simple_der (etype, my_str, my_str_len, tl, &tl_len); - if (result != ASN1_VALUE_NOT_VALID) - { -- fprintf (stderr, "asn1_encode_simple_der out of range etype\n"); -+ grub_printf ("asn1_encode_simple_der out of range etype\n"); - return 1; - } - } -@@ -105,7 +105,7 @@ test_simple (void) - result = asn1_get_bit_der (der, 0, &ret_len, str, str_size, &bit_len); - if (result != ASN1_GENERIC_ERROR) - { -- fprintf (stderr, "asn1_get_bit_der zero\n"); -+ grub_printf ("asn1_get_bit_der zero\n"); - return 1; - } - -@@ -129,7 +129,7 @@ test_simple (void) - - if (der_len != tv[i].derlen || memcmp (der, tv[i].der, der_len) != 0) - { -- fprintf (stderr, "asn1_bit_der iter %lu\n", (unsigned long) i); -+ grub_printf ("asn1_bit_der iter %lu\n", (unsigned long) i); - return 1; - } - -@@ -140,8 +140,7 @@ test_simple (void) - if (result != ASN1_SUCCESS || ret_len != tv[i].derlen - || bit_len != tv[i].bitlen) - { -- fprintf (stderr, "asn1_get_bit_der iter %lu, err: %d\n", -- (unsigned long) i, result); -+ grub_printf ("asn1_get_bit_der iter %lu, err: %d\n", (unsigned long) i, result); - return 1; - } - } -@@ -163,7 +162,7 @@ test_simple (void) - if (result != ASN1_SUCCESS || ret_len != 5 - || bit_len != 18 || memcmp (str, "\x6e\x5d\xc0", 3) != 0) - { -- fprintf (stderr, "asn1_get_bit_der example\n"); -+ grub_printf ("asn1_get_bit_der example\n"); - return 1; - } - -@@ -171,7 +170,7 @@ test_simple (void) - asn1_bit_der (str, bit_len, der, &der_len); - if (der_len != 5 || memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0) - { -- fprintf (stderr, "asn1_bit_der example roundtrip\n"); -+ grub_printf ("asn1_bit_der example roundtrip\n"); - return 1; - } - -@@ -184,7 +183,7 @@ test_simple (void) - if (result != ASN1_SUCCESS || ret_len != 5 - || bit_len != 18 || memcmp (str, "\x6e\x5d\xe0", 3) != 0) - { -- fprintf (stderr, "asn1_get_bit_der example padded\n"); -+ grub_printf ("asn1_get_bit_der example padded\n"); - return 1; - } - -@@ -192,7 +191,7 @@ test_simple (void) - asn1_bit_der (str, bit_len, der, &der_len); - if (der_len != 5 || memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0) - { -- fprintf (stderr, "asn1_bit_der example roundtrip\n"); -+ grub_printf ("asn1_bit_der example roundtrip\n"); - return 1; - } - -@@ -206,7 +205,7 @@ test_simple (void) - if (result != ASN1_SUCCESS || ret_len != 6 - || bit_len != 18 || memcmp (str, "\x6e\x5d\xc0", 3) != 0) - { -- fprintf (stderr, "asn1_get_bit_der example long form\n"); -+ grub_printf ("asn1_get_bit_der example long form\n"); - return 1; - } - -@@ -214,7 +213,7 @@ test_simple (void) - asn1_bit_der (str, bit_len, der, &der_len); - if (der_len != 5 || memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0) - { -- fprintf (stderr, "asn1_bit_der example roundtrip\n"); -+ grub_printf ("asn1_bit_der example roundtrip\n"); - return 1; - } - -diff --git a/grub-core/tests/asn1/tests/Test_strings.c b/grub-core/tests/asn1/tests/Test_strings.c -index 2538f2558..65c30937f 100644 ---- a/grub-core/tests/asn1/tests/Test_strings.c -+++ b/grub-core/tests/asn1/tests/Test_strings.c -@@ -89,17 +89,14 @@ test_strings (void) - tl, &tl_len); - if (ret != ASN1_SUCCESS) - { -- fprintf (stderr, "Encoding error in %u: %s\n", i, -- asn1_strerror (ret)); -+ grub_printf ("Encoding error in %u: %s\n", i, asn1_strerror (ret)); - return 1; - } - der_len = tl_len + tv[i].str_len; - - if (der_len != tv[i].der_len || memcmp (tl, tv[i].der, tl_len) != 0) - { -- fprintf (stderr, -- "DER encoding differs in %u! (size: %u, expected: %u)\n", -- i, der_len, tv[i].der_len); -+ grub_printf ("DER encoding differs in %u! (size: %u, expected: %u)\n", i, der_len, tv[i].der_len); - return 1; - } - -@@ -109,16 +106,13 @@ test_strings (void) - &str_len); - if (ret != ASN1_SUCCESS) - { -- fprintf (stderr, "Decoding error in %u: %s\n", i, -- asn1_strerror (ret)); -+ grub_printf ("Decoding error in %u: %s\n", i, asn1_strerror (ret)); - return 1; - } - - if (str_len != tv[i].str_len || memcmp (str, tv[i].str, str_len) != 0) - { -- fprintf (stderr, -- "DER decoded data differ in %u! (size: %u, expected: %u)\n", -- i, der_len, tv[i].str_len); -+ grub_printf ("DER decoded data differ in %u! (size: %u, expected: %u)\n", i, der_len, tv[i].str_len); - return 1; - } - } -@@ -132,16 +126,13 @@ test_strings (void) - &str_len, NULL); - if (ret != ASN1_SUCCESS) - { -- fprintf (stderr, "BER decoding error in %u: %s\n", i, -- asn1_strerror (ret)); -+ grub_printf ("BER decoding error in %u: %s\n", i, asn1_strerror (ret)); - return 1; - } - - if (str_len != ber[i].str_len || memcmp (b, ber[i].str, str_len) != 0) - { -- fprintf (stderr, -- "BER decoded data differ in %u! (size: %u, expected: %u)\n", -- i, str_len, ber[i].str_len); -+ grub_printf ("BER decoded data differ in %u! (size: %u, expected: %u)\n", i, str_len, ber[i].str_len); - return 1; - } - free (b); -diff --git a/grub-core/tests/asn1/tests/object-id-decoding.c b/grub-core/tests/asn1/tests/object-id-decoding.c -index fdbb8ea21..c087b46e3 100644 ---- a/grub-core/tests/asn1/tests/object-id-decoding.c -+++ b/grub-core/tests/asn1/tests/object-id-decoding.c -@@ -85,10 +85,8 @@ test_object_id_decoding (void) - sizeof (str)); - if (ret != tv[i].expected_error) - { -- fprintf (stderr, -- "%d: asn1_get_object_id_der iter %lu: got '%s' expected %d\n", -- __LINE__, (unsigned long) i, asn1_strerror (ret), -- tv[i].expected_error); -+ grub_printf ("%d: asn1_get_object_id_der iter %lu: got '%s' expected %d\n", -+ __LINE__, (unsigned long) i, asn1_strerror (ret), tv[i].expected_error); - return 1; - } - -@@ -97,17 +95,15 @@ test_object_id_decoding (void) - - if (ret_len != tv[i].der_len - 1) - { -- fprintf (stderr, -- "%d: iter %lu: error in DER, length returned is %d, had %d\n", -- __LINE__, (unsigned long) i, ret_len, tv[i].der_len - 1); -+ grub_printf ("%d: iter %lu: error in DER, length returned is %d, had %d\n", -+ __LINE__, (unsigned long) i, ret_len, tv[i].der_len - 1); - return 1; - } - - if (strcmp (tv[i].oid, str) != 0) - { -- fprintf (stderr, -- "%d: strcmp iter %lu: got invalid OID: %s, expected: %s\n", -- __LINE__, (unsigned long) i, str, tv[i].oid); -+ grub_printf ("%d: strcmp iter %lu: got invalid OID: %s, expected: %s\n", -+ __LINE__, (unsigned long) i, str, tv[i].oid); - return 1; - } - -diff --git a/grub-core/tests/asn1/tests/object-id-encoding.c b/grub-core/tests/asn1/tests/object-id-encoding.c -index a497015e3..e3da092cc 100644 ---- a/grub-core/tests/asn1/tests/object-id-encoding.c -+++ b/grub-core/tests/asn1/tests/object-id-encoding.c -@@ -93,33 +93,29 @@ test_object_id_encoding (void) - { - if (ret == tv[i].expected_error) - continue; -- fprintf (stderr, -- "%d: iter %lu, encoding of OID failed: %s\n", -- __LINE__, (unsigned long) i, asn1_strerror (ret)); -+ grub_printf ("%d: iter %lu, encoding of OID failed: %s\n", -+ __LINE__, (unsigned long) i, asn1_strerror (ret)); - return 1; - } - else if (ret != tv[i].expected_error) - { -- fprintf (stderr, -- "%d: iter %lu, encoding of OID %s succeeded when expecting failure\n", -- __LINE__, (unsigned long) i, tv[i].oid); -+ grub_printf ("%d: iter %lu, encoding of OID %s succeeded when expecting failure\n", -+ __LINE__, (unsigned long) i, tv[i].oid); - return 1; - } - - if (der_len != tv[i].der_len || memcmp (der, tv[i].der, der_len) != 0) - { -- fprintf (stderr, -- "%d: iter %lu, re-encoding of OID %s resulted to different string (%d vs %d bytes)\n", -- __LINE__, (unsigned long) i, tv[i].oid, der_len, -- tv[i].der_len); -- fprintf (stderr, "\nGot:\t\t"); -+ grub_printf ("%d: iter %lu, re-encoding of OID %s resulted to different string (%d vs %d bytes)\n", -+ __LINE__, (unsigned long) i, tv[i].oid, der_len, tv[i].der_len); -+ grub_printf ("\nGot:\t\t"); - for (j = 0; j < der_len; j++) -- fprintf (stderr, "%.2x", der[j]); -+ grub_printf ("%.2x", der[j]); - -- fprintf (stderr, "\nExpected:\t"); -+ grub_printf ("\nExpected:\t"); - for (j = 0; j < tv[i].der_len; j++) -- fprintf (stderr, "%.2x", tv[i].der[j]); -- fprintf (stderr, "\n"); -+ grub_printf ("%.2x", tv[i].der[j]); -+ grub_printf ("\n"); - - return 1; - } -diff --git a/grub-core/tests/asn1/tests/octet-string.c b/grub-core/tests/asn1/tests/octet-string.c -index 8c49c6e0c..d3a35dff8 100644 ---- a/grub-core/tests/asn1/tests/octet-string.c -+++ b/grub-core/tests/asn1/tests/octet-string.c -@@ -131,9 +131,8 @@ test_octet_string (void) - sizeof (str), &str_size); - if (ret != tv[i].expected_error) - { -- fprintf (stderr, -- "%d: asn1_get_octet_der: %s: got %d expected %d\n", -- __LINE__, tv[i].name, ret, tv[i].expected_error); -+ grub_printf ("%d: asn1_get_octet_der: %s: got %d expected %d\n", -+ __LINE__, tv[i].name, ret, tv[i].expected_error); - return 1; - } - if (tv[i].expected_error) -@@ -141,27 +140,25 @@ test_octet_string (void) - - if (ret_len != tv[i].der_len - 1) - { -- fprintf (stderr, -- "%d: error in DER, length returned is %d, had %d\n", -- __LINE__, ret_len, tv[i].der_len - 1); -+ grub_printf ("%d: error in DER, length returned is %d, had %d\n", -+ __LINE__, ret_len, tv[i].der_len - 1); - return 1; - } - - if (str_size != tv[i].len - || memcmp (tv[i].string, str, tv[i].len) != 0) - { -- fprintf (stderr, -- "%d: memcmp: %s: got invalid decoding\n", -- __LINE__, tv[i].name); -+ grub_printf ("%d: memcmp: %s: got invalid decoding\n", -+ __LINE__, tv[i].name); - -- fprintf (stderr, "\nGot:\t\t"); -+ grub_printf ("\nGot:\t\t"); - for (j = 0; j < str_size; j++) -- fprintf (stderr, "%.2x", str[j]); -+ grub_printf ("%.2x", str[j]); - -- fprintf (stderr, "\nExpected:\t"); -+ grub_printf ("\nExpected:\t"); - for (j = 0; j < tv[i].len; j++) -- fprintf (stderr, "%.2x", tv[i].string[j]); -- fprintf (stderr, "\n"); -+ grub_printf ("%.2x", tv[i].string[j]); -+ grub_printf ("\n"); - return 1; - } - -@@ -172,8 +169,7 @@ test_octet_string (void) - if (der_len != tv[i].der_len - 1 - || memcmp (tv[i].der_str + 1, der, tv[i].der_len - 1) != 0) - { -- fprintf (stderr, -- "encoding: %s: got invalid encoding\n", tv[i].name); -+ grub_printf ("encoding: %s: got invalid encoding\n", tv[i].name); - return 1; - } - } -@@ -185,10 +181,9 @@ test_octet_string (void) - (unsigned int *) &der_len); - if (ret != tv[i].expected_error) - { -- fprintf (stderr, -- "%d: asn1_decode_simple_ber: %s: got %s expected %s\n", -- __LINE__, tv[i].name, asn1_strerror (ret), -- asn1_strerror (tv[i].expected_error)); -+ grub_printf ("%d: asn1_decode_simple_ber: %s: got %s expected %s\n", -+ __LINE__, tv[i].name, asn1_strerror (ret), -+ asn1_strerror (tv[i].expected_error)); - return 1; - } - if (tv[i].expected_error) -@@ -196,25 +191,22 @@ test_octet_string (void) - - if (der_len != tv[i].der_len) - { -- fprintf (stderr, -- "%d: error: %s: DER, length returned is %d, had %d\n", -- __LINE__, tv[i].name, der_len, tv[i].der_len); -+ grub_printf ("%d: error: %s: DER, length returned is %d, had %d\n", -+ __LINE__, tv[i].name, der_len, tv[i].der_len); - return 1; - } - - if (str_size != tv[i].len || memcmp (tv[i].string, tmp, tv[i].len) != 0) - { -- fprintf (stderr, -- "%d: memcmp: %s: got invalid decoding\n", -- __LINE__, tv[i].name); -- fprintf (stderr, "\nGot:\t\t"); -+ grub_printf ("%d: memcmp: %s: got invalid decoding\n", __LINE__, tv[i].name); -+ grub_printf ("\nGot:\t\t"); - for (j = 0; j < str_size; j++) -- fprintf (stderr, "%.2x", tmp[j]); -+ grub_printf ("%.2x", tmp[j]); - -- fprintf (stderr, "\nExpected:\t"); -+ grub_printf ("\nExpected:\t"); - for (j = 0; j < tv[i].len; j++) -- fprintf (stderr, "%.2x", tv[i].string[j]); -- fprintf (stderr, "\n"); -+ grub_printf ("%.2x", tv[i].string[j]); -+ grub_printf ("\n"); - return 1; - } - free (tmp); -diff --git a/grub-core/tests/asn1/tests/reproducers.c b/grub-core/tests/asn1/tests/reproducers.c -index fa3cea762..0e3c9fd65 100644 ---- a/grub-core/tests/asn1/tests/reproducers.c -+++ b/grub-core/tests/asn1/tests/reproducers.c -@@ -58,8 +58,7 @@ test_reproducers (void) - result = asn1_array2tree (endless_asn1_tab, &definitions, errorDescription); - if (result != ASN1_SUCCESS) - { -- asn1_perror (result); -- printf ("ErrorDescription = %s\n\n", errorDescription); -+ grub_printf ("Error: %s\nErrorDescription = %s\n\n", asn1_strerror (result), errorDescription); - return 1; - } - -@@ -69,8 +68,7 @@ test_reproducers (void) - result = asn1_array2tree (tab, &definitions, errorDescription); - if (result != ASN1_SUCCESS) - { -- asn1_perror (result); -- printf ("ErrorDescription = %s\n\n", errorDescription); -+ grub_printf ("Error: %s\nErrorDescription = %s\n\n", asn1_strerror (result), errorDescription); - return 1; - } - --- -2.43.0 - diff --git a/grub-core/lib/libtasn1-patches/0012-asn1_test-use-the-grub-specific-functions-and-types.patch b/grub-core/lib/libtasn1-patches/0012-asn1_test-use-the-grub-specific-functions-and-types.patch deleted file mode 100644 index ba2715751..000000000 --- a/grub-core/lib/libtasn1-patches/0012-asn1_test-use-the-grub-specific-functions-and-types.patch +++ /dev/null @@ -1,263 +0,0 @@ -From 392da24a8a4b2ab94a93e9e0f74db027a3a9374d Mon Sep 17 00:00:00 2001 -From: Gary Lin -Date: Fri, 16 Aug 2024 15:46:59 +0800 -Subject: [PATCH 12/13] asn1_test: use the grub-specific functions and types - -This commit converts functions and types to the grub-specific ones: - -LONG_MAX -> GRUB_LONG_MAX -INT_MAX -> GRUB_INT_MAX -UINT_MAX -> GRUB_UINT_MAX -size_t -> grub_size_t -memcmp() -> grub_memcmp() -memcpy() -> grub_memcpy() -free() -> grub_free() -strcmp() -> grub_strcmp() - -Signed-off-by: Daniel Axtens -Signed-off-by: Gary Lin -Reviewed-by: Daniel Kiper ---- - grub-core/tests/asn1/tests/Test_overflow.c | 4 ++-- - grub-core/tests/asn1/tests/Test_simple.c | 22 +++++++++---------- - grub-core/tests/asn1/tests/Test_strings.c | 8 +++---- - .../tests/asn1/tests/object-id-decoding.c | 4 ++-- - .../tests/asn1/tests/object-id-encoding.c | 2 +- - grub-core/tests/asn1/tests/octet-string.c | 10 ++++----- - 6 files changed, 25 insertions(+), 25 deletions(-) - -diff --git a/grub-core/tests/asn1/tests/Test_overflow.c b/grub-core/tests/asn1/tests/Test_overflow.c -index ffac8507a..65843abf6 100644 ---- a/grub-core/tests/asn1/tests/Test_overflow.c -+++ b/grub-core/tests/asn1/tests/Test_overflow.c -@@ -43,9 +43,9 @@ test_overflow (void) - - /* Test that values larger than int but smaller than long are - rejected. This limitation was introduced with libtasn1 2.12. */ -- if (LONG_MAX > INT_MAX) -+ if (GRUB_LONG_MAX > GRUB_INT_MAX) - { -- unsigned long num = ((long) UINT_MAX) << 2; -+ unsigned long num = ((long) GRUB_UINT_MAX) << 2; - unsigned char der[20]; - int der_len; - long l; -diff --git a/grub-core/tests/asn1/tests/Test_simple.c b/grub-core/tests/asn1/tests/Test_simple.c -index dc70db191..19613cae8 100644 ---- a/grub-core/tests/asn1/tests/Test_simple.c -+++ b/grub-core/tests/asn1/tests/Test_simple.c -@@ -81,7 +81,7 @@ test_simple (void) - int der_len = sizeof (der); - int str_size = sizeof (str); - int ret_len, bit_len; -- size_t i; -+ grub_size_t i; - - { - unsigned int etype = 38; -@@ -127,7 +127,7 @@ test_simple (void) - } - #endif - -- if (der_len != tv[i].derlen || memcmp (der, tv[i].der, der_len) != 0) -+ if (der_len != tv[i].derlen || grub_memcmp (der, tv[i].der, der_len) != 0) - { - grub_printf ("asn1_bit_der iter %lu\n", (unsigned long) i); - return 1; -@@ -155,12 +155,12 @@ test_simple (void) - - /* 03 04 06 6e 5d c0 DER encoding */ - -- memcpy (der, "\x04\x06\x6e\x5d\xc0", 5); -+ grub_memcpy (der, "\x04\x06\x6e\x5d\xc0", 5); - der_len = 5; - - result = asn1_get_bit_der (der, der_len, &ret_len, str, str_size, &bit_len); - if (result != ASN1_SUCCESS || ret_len != 5 -- || bit_len != 18 || memcmp (str, "\x6e\x5d\xc0", 3) != 0) -+ || bit_len != 18 || grub_memcmp (str, "\x6e\x5d\xc0", 3) != 0) - { - grub_printf ("asn1_get_bit_der example\n"); - return 1; -@@ -168,7 +168,7 @@ test_simple (void) - - der_len = sizeof (der); - asn1_bit_der (str, bit_len, der, &der_len); -- if (der_len != 5 || memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0) -+ if (der_len != 5 || grub_memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0) - { - grub_printf ("asn1_bit_der example roundtrip\n"); - return 1; -@@ -176,12 +176,12 @@ test_simple (void) - - /* 03 04 06 6e 5d e0 padded with "100000" */ - -- memcpy (der, "\x04\x06\x6e\x5d\xe0", 5); -+ grub_memcpy (der, "\x04\x06\x6e\x5d\xe0", 5); - der_len = 5; - - result = asn1_get_bit_der (der, der_len, &ret_len, str, str_size, &bit_len); - if (result != ASN1_SUCCESS || ret_len != 5 -- || bit_len != 18 || memcmp (str, "\x6e\x5d\xe0", 3) != 0) -+ || bit_len != 18 || grub_memcmp (str, "\x6e\x5d\xe0", 3) != 0) - { - grub_printf ("asn1_get_bit_der example padded\n"); - return 1; -@@ -189,7 +189,7 @@ test_simple (void) - - der_len = sizeof (der); - asn1_bit_der (str, bit_len, der, &der_len); -- if (der_len != 5 || memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0) -+ if (der_len != 5 || grub_memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0) - { - grub_printf ("asn1_bit_der example roundtrip\n"); - return 1; -@@ -197,13 +197,13 @@ test_simple (void) - - /* 03 81 04 06 6e 5d c0 long form of length octets */ - -- memcpy (der, "\x81\x04\x06\x6e\x5d\xc0", 6); -+ grub_memcpy (der, "\x81\x04\x06\x6e\x5d\xc0", 6); - der_len = 6; - - result = asn1_get_bit_der (der, der_len, &ret_len, str, str_size, &bit_len); - - if (result != ASN1_SUCCESS || ret_len != 6 -- || bit_len != 18 || memcmp (str, "\x6e\x5d\xc0", 3) != 0) -+ || bit_len != 18 || grub_memcmp (str, "\x6e\x5d\xc0", 3) != 0) - { - grub_printf ("asn1_get_bit_der example long form\n"); - return 1; -@@ -211,7 +211,7 @@ test_simple (void) - - der_len = sizeof (der); - asn1_bit_der (str, bit_len, der, &der_len); -- if (der_len != 5 || memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0) -+ if (der_len != 5 || grub_memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0) - { - grub_printf ("asn1_bit_der example roundtrip\n"); - return 1; -diff --git a/grub-core/tests/asn1/tests/Test_strings.c b/grub-core/tests/asn1/tests/Test_strings.c -index 65c30937f..c7c1afa1b 100644 ---- a/grub-core/tests/asn1/tests/Test_strings.c -+++ b/grub-core/tests/asn1/tests/Test_strings.c -@@ -94,7 +94,7 @@ test_strings (void) - } - der_len = tl_len + tv[i].str_len; - -- if (der_len != tv[i].der_len || memcmp (tl, tv[i].der, tl_len) != 0) -+ if (der_len != tv[i].der_len || grub_memcmp (tl, tv[i].der, tl_len) != 0) - { - grub_printf ("DER encoding differs in %u! (size: %u, expected: %u)\n", i, der_len, tv[i].der_len); - return 1; -@@ -110,7 +110,7 @@ test_strings (void) - return 1; - } - -- if (str_len != tv[i].str_len || memcmp (str, tv[i].str, str_len) != 0) -+ if (str_len != tv[i].str_len || grub_memcmp (str, tv[i].str, str_len) != 0) - { - grub_printf ("DER decoded data differ in %u! (size: %u, expected: %u)\n", i, der_len, tv[i].str_len); - return 1; -@@ -130,12 +130,12 @@ test_strings (void) - return 1; - } - -- if (str_len != ber[i].str_len || memcmp (b, ber[i].str, str_len) != 0) -+ if (str_len != ber[i].str_len || grub_memcmp (b, ber[i].str, str_len) != 0) - { - grub_printf ("BER decoded data differ in %u! (size: %u, expected: %u)\n", i, str_len, ber[i].str_len); - return 1; - } -- free (b); -+ grub_free (b); - } - - -diff --git a/grub-core/tests/asn1/tests/object-id-decoding.c b/grub-core/tests/asn1/tests/object-id-decoding.c -index c087b46e3..91af8cde5 100644 ---- a/grub-core/tests/asn1/tests/object-id-decoding.c -+++ b/grub-core/tests/asn1/tests/object-id-decoding.c -@@ -74,7 +74,7 @@ test_object_id_decoding (void) - { - char str[128]; - int ret, ret_len; -- size_t i; -+ grub_size_t i; - - for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) - { -@@ -100,7 +100,7 @@ test_object_id_decoding (void) - return 1; - } - -- if (strcmp (tv[i].oid, str) != 0) -+ if (grub_strcmp (tv[i].oid, str) != 0) - { - grub_printf ("%d: strcmp iter %lu: got invalid OID: %s, expected: %s\n", - __LINE__, (unsigned long) i, str, tv[i].oid); -diff --git a/grub-core/tests/asn1/tests/object-id-encoding.c b/grub-core/tests/asn1/tests/object-id-encoding.c -index e3da092cc..f8f98ff17 100644 ---- a/grub-core/tests/asn1/tests/object-id-encoding.c -+++ b/grub-core/tests/asn1/tests/object-id-encoding.c -@@ -104,7 +104,7 @@ test_object_id_encoding (void) - return 1; - } - -- if (der_len != tv[i].der_len || memcmp (der, tv[i].der, der_len) != 0) -+ if (der_len != tv[i].der_len || grub_memcmp (der, tv[i].der, der_len) != 0) - { - grub_printf ("%d: iter %lu, re-encoding of OID %s resulted to different string (%d vs %d bytes)\n", - __LINE__, (unsigned long) i, tv[i].oid, der_len, tv[i].der_len); -diff --git a/grub-core/tests/asn1/tests/octet-string.c b/grub-core/tests/asn1/tests/octet-string.c -index d3a35dff8..dcf0fb808 100644 ---- a/grub-core/tests/asn1/tests/octet-string.c -+++ b/grub-core/tests/asn1/tests/octet-string.c -@@ -116,7 +116,7 @@ test_octet_string (void) - int str_size = sizeof (str); - unsigned char *tmp = NULL; - int ret, ret_len, j; -- size_t i; -+ grub_size_t i; - - for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) - { -@@ -146,7 +146,7 @@ test_octet_string (void) - } - - if (str_size != tv[i].len -- || memcmp (tv[i].string, str, tv[i].len) != 0) -+ || grub_memcmp (tv[i].string, str, tv[i].len) != 0) - { - grub_printf ("%d: memcmp: %s: got invalid decoding\n", - __LINE__, tv[i].name); -@@ -167,7 +167,7 @@ test_octet_string (void) - asn1_octet_der (str, str_size, der, &der_len); - - if (der_len != tv[i].der_len - 1 -- || memcmp (tv[i].der_str + 1, der, tv[i].der_len - 1) != 0) -+ || grub_memcmp (tv[i].der_str + 1, der, tv[i].der_len - 1) != 0) - { - grub_printf ("encoding: %s: got invalid encoding\n", tv[i].name); - return 1; -@@ -196,7 +196,7 @@ test_octet_string (void) - return 1; - } - -- if (str_size != tv[i].len || memcmp (tv[i].string, tmp, tv[i].len) != 0) -+ if (str_size != tv[i].len || grub_memcmp (tv[i].string, tmp, tv[i].len) != 0) - { - grub_printf ("%d: memcmp: %s: got invalid decoding\n", __LINE__, tv[i].name); - grub_printf ("\nGot:\t\t"); -@@ -209,7 +209,7 @@ test_octet_string (void) - grub_printf ("\n"); - return 1; - } -- free (tmp); -+ grub_free (tmp); - tmp = NULL; - - } --- -2.43.0 - diff --git a/grub-core/lib/libtasn1-patches/0013-asn1_test-enable-the-testcase-only-when-GRUB_LONG_MA.patch b/grub-core/lib/libtasn1-patches/0013-asn1_test-enable-the-testcase-only-when-GRUB_LONG_MA.patch deleted file mode 100644 index a81a350c9..000000000 --- a/grub-core/lib/libtasn1-patches/0013-asn1_test-enable-the-testcase-only-when-GRUB_LONG_MA.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 6d308d9053447dcc003a9ca740c47c00932d3569 Mon Sep 17 00:00:00 2001 -From: Gary Lin -Date: Mon, 7 Oct 2024 11:33:19 +0800 -Subject: [PATCH 13/13] asn1_test: enable the testcase only when GRUB_LONG_MAX - is larger than GRUB_INT_MAX - -There is a testcase to test the values larger than 'int' but smaller -than 'long'. However, for some architectures, 'long' and 'int' are the -same, and the compiler may issue a warning like this: - -grub-core/tests/asn1/tests/Test_overflow.c:48:50: error: left shift of negative value [-Werror=shift-negative-value] - unsigned long num = ((long) GRUB_UINT_MAX) << 2; - ^~ - -To avoid unnecessary error the testcase is enabled only when -GRUB_LONG_MAX is larger than GRUB_INT_MAX. - -Signed-off-by: Daniel Axtens -Signed-off-by: Gary Lin -Reviewed-by: Daniel Kiper ---- - grub-core/tests/asn1/tests/Test_overflow.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/grub-core/tests/asn1/tests/Test_overflow.c b/grub-core/tests/asn1/tests/Test_overflow.c -index 65843abf6..fdeff5634 100644 ---- a/grub-core/tests/asn1/tests/Test_overflow.c -+++ b/grub-core/tests/asn1/tests/Test_overflow.c -@@ -43,7 +43,7 @@ test_overflow (void) - - /* Test that values larger than int but smaller than long are - rejected. This limitation was introduced with libtasn1 2.12. */ -- if (GRUB_LONG_MAX > GRUB_INT_MAX) -+#if (GRUB_LONG_MAX > GRUB_INT_MAX) - { - unsigned long num = ((long) GRUB_UINT_MAX) << 2; - unsigned char der[20]; -@@ -61,6 +61,7 @@ test_overflow (void) - return 1; - } - } -+#endif - - /* Test that values larger than would fit in the input string are - rejected. This problem was fixed in libtasn1 2.12. */ --- -2.43.0 - diff --git a/grub-core/lib/libtasn1/COPYING b/grub-core/lib/libtasn1/COPYING deleted file mode 100644 index e8b3628db..000000000 --- a/grub-core/lib/libtasn1/COPYING +++ /dev/null @@ -1,16 +0,0 @@ -LICENSING -========= - -The libtasn1 library is released under the GNU Lesser General Public -License (LGPL) version 2.1 or later; see [COPYING.LESSER](doc/COPYING.LESSER) -for the license terms. - -The GNU LGPL applies to the main libtasn1 library, while the -included applications library are under the GNU GPL version 3. -The libtasn1 library is located in the lib directory, while the applications -in src/. - -The documentation in doc/ is under the GNU FDL license 1.3. - -For any copyright year range specified as YYYY-ZZZZ in this package -note that the range specifies every single year in that closed interval. diff --git a/grub-core/lib/libtasn1/README.md b/grub-core/lib/libtasn1/README.md deleted file mode 100644 index b0305b93e..000000000 --- a/grub-core/lib/libtasn1/README.md +++ /dev/null @@ -1,98 +0,0 @@ -# Libtasn1 README -- Introduction information - -This is GNU Libtasn1, a small ASN.1 library. - -The C library (libtasn1.*) is licensed under the GNU Lesser General -Public License version 2.1 or later. See the file COPYING.LIB. - -The command line tool, self tests, examples, and other auxilliary -files, are licensed under the GNU General Public License version 3.0 -or later. See the file COPYING. - -## Building the library - -We require several tools to build the software, including: - -* [Make](https://www.gnu.org/software/make/) -* [Automake](https://www.gnu.org/software/automake/) (use 1.11.3 or later) -* [Autoconf](https://www.gnu.org/software/autoconf/) -* [Libtool](https://www.gnu.org/software/libtool/) -* [Texinfo](https://www.gnu.org/software/texinfo/) -* [help2man](http://www.gnu.org/software/help2man/) -* [Tar](https://www.gnu.org/software/tar/) -* [Gzip](https://www.gnu.org/software/gzip/) -* [bison](https://www.gnu.org/software/bison/) -* [Texlive & epsf](https://www.tug.org/texlive/) (for PDF manual) -* [GTK-DOC](https://www.gtk.org/gtk-doc/) (for API manual) -* [Git](https://git-scm.com/) -* [libabigail](https://pagure.io/libabigail/) (for abi comparison in make dist) -* [Valgrind](https://valgrind.org/) (optional) - -The required software is typically distributed with your operating -system, and the instructions for installing them differ. Here are -some hints: - -Debian/Ubuntu: -``` -sudo apt-get install make git autoconf automake libtool bison -sudo apt-get install texinfo help2man gtk-doc-tools valgrind abigail-tools -``` - -PDF manual - Debian <= stretch: -``` -sudo apt-get install texlive-generic-recommended texlive texlive-extra-utils -``` - -PDF manual - Debian >= buster: -``` -sudo apt-get install texlive-plain-generic texlive texlive-extra-utils -``` - -The next step is to run autoreconf, ./configure, etc: - -``` -$ ./bootstrap -``` - -Then build the project normally: - -``` -$ ./configure -$ make check -``` - -Happy hacking! - - -## Manual - -The manual is in the `doc/` directory of the release. - -You can also browse the manual online at: - - - https://www.gnu.org/software/libtasn1/manual/ - - https://gnutls.gitlab.io/libtasn1/manual/ - - https://gnutls.gitlab.io/libtasn1/manual/libtasn1.html - - https://gnutls.gitlab.io/libtasn1/manual/libtasn1.pdf - - https://gnutls.gitlab.io/libtasn1/reference/ - - https://gnutls.gitlab.io/libtasn1/reference/libtasn1.pdf - - -## Code coverage report - -The coverage report is at: - - - https://gnutls.gitlab.io/libtasn1/coverage - - -## Issue trackers - - - [Main issue tracker](https://gitlab.com/gnutls/libtasn1/issues) - - [oss-fuzz found issues](https://bugs.chromium.org/p/oss-fuzz/issues/list?q=libtasn1&can=2) - - -## Homepage - -The project homepage at the gnu site is at: - -https://www.gnu.org/software/libtasn1/ diff --git a/grub-core/lib/libtasn1/lib/coding.c b/grub-core/lib/libtasn1/lib/coding.c deleted file mode 100644 index ea5bc370e..000000000 --- a/grub-core/lib/libtasn1/lib/coding.c +++ /dev/null @@ -1,1425 +0,0 @@ -/* - * Copyright (C) 2002-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 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 - */ - - -/*****************************************************/ -/* File: coding.c */ -/* Description: Functions to create a DER coding of */ -/* an ASN1 type. */ -/*****************************************************/ - -#include -#include "parser_aux.h" -#include -#include "element.h" -#include "minmax.h" -#include - -#define MAX_TAG_LEN 16 - -/******************************************************/ -/* Function : _asn1_error_description_value_not_found */ -/* Description: creates the ErrorDescription string */ -/* for the ASN1_VALUE_NOT_FOUND error. */ -/* Parameters: */ -/* node: node of the tree where the value is NULL. */ -/* ErrorDescription: string returned. */ -/* Return: */ -/******************************************************/ -static void -_asn1_error_description_value_not_found (asn1_node node, - char *ErrorDescription) -{ - - if (ErrorDescription == NULL) - return; - - Estrcpy (ErrorDescription, ":: value of element '"); - _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription), - ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40); - Estrcat (ErrorDescription, "' not found"); - -} - -/** - * asn1_length_der: - * @len: value to convert. - * @der: buffer to hold the returned encoding (may be %NULL). - * @der_len: number of meaningful bytes of ANS (der[0]..der[der_len-1]). - * - * Creates the DER encoding of the provided length value. - * The @der buffer must have enough room for the output. The maximum - * length this function will encode is %ASN1_MAX_LENGTH_SIZE. - * - * To know the size of the DER encoding use a %NULL value for @der. - **/ -void -asn1_length_der (unsigned long int len, unsigned char *der, int *der_len) -{ - int k; - unsigned char temp[ASN1_MAX_LENGTH_SIZE]; -#if SIZEOF_UNSIGNED_LONG_INT > 8 - len &= 0xFFFFFFFFFFFFFFFF; -#endif - - if (len < 128) - { - /* short form */ - if (der != NULL) - der[0] = (unsigned char) len; - *der_len = 1; - } - else - { - /* Long form */ - k = 0; - while (len) - { - temp[k++] = len & 0xFF; - len = len >> 8; - } - *der_len = k + 1; - if (der != NULL) - { - der[0] = ((unsigned char) k & 0x7F) + 128; - while (k--) - der[*der_len - 1 - k] = temp[k]; - } - } -} - -/******************************************************/ -/* Function : _asn1_tag_der */ -/* Description: creates the DER coding for the CLASS */ -/* and TAG parameters. */ -/* It is limited by the ASN1_MAX_TAG_SIZE variable */ -/* Parameters: */ -/* class: value to convert. */ -/* tag_value: value to convert. */ -/* ans: string returned. */ -/* ans_len: number of meaningful bytes of ANS */ -/* (ans[0]..ans[ans_len-1]). */ -/* Return: */ -/******************************************************/ -static void -_asn1_tag_der (unsigned char class, unsigned int tag_value, - unsigned char ans[ASN1_MAX_TAG_SIZE], int *ans_len) -{ - int k; - unsigned char temp[ASN1_MAX_TAG_SIZE]; - - if (tag_value < 31) - { - /* short form */ - ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F)); - *ans_len = 1; - } - else - { - /* Long form */ - ans[0] = (class & 0xE0) + 31; - k = 0; - while (tag_value != 0) - { - temp[k++] = tag_value & 0x7F; - tag_value >>= 7; - - if (k > ASN1_MAX_TAG_SIZE - 1) - break; /* will not encode larger tags */ - } - *ans_len = k + 1; - while (k--) - ans[*ans_len - 1 - k] = temp[k] + 128; - ans[*ans_len - 1] -= 128; - } -} - -/** - * asn1_octet_der: - * @str: the input data. - * @str_len: STR length (str[0]..str[*str_len-1]). - * @der: encoded string returned. - * @der_len: number of meaningful bytes of DER (der[0]..der[der_len-1]). - * - * Creates a length-value DER encoding for the input data. - * The DER encoding of the input data will be placed in the @der variable. - * - * Note that the OCTET STRING tag is not included in the output. - * - * This function does not return any value because it is expected - * that @der_len will contain enough bytes to store the string - * plus the DER encoding. The DER encoding size can be obtained using - * asn1_length_der(). - **/ -void -asn1_octet_der (const unsigned char *str, int str_len, - unsigned char *der, int *der_len) -{ - int len_len; - - if (der == NULL || str_len < 0) - return; - - asn1_length_der (str_len, der, &len_len); - memcpy (der + len_len, str, str_len); - *der_len = str_len + len_len; -} - - -/** - * asn1_encode_simple_der: - * @etype: The type of the string to be encoded (ASN1_ETYPE_) - * @str: the string data. - * @str_len: the string length - * @tl: the encoded tag and length - * @tl_len: the bytes of the @tl field - * - * Creates the DER encoding for various simple ASN.1 types like strings etc. - * It stores the tag and length in @tl, which should have space for at least - * %ASN1_MAX_TL_SIZE bytes. Initially @tl_len should contain the size of @tl. - * - * The complete DER encoding should consist of the value in @tl appended - * with the provided @str. - * - * Returns: %ASN1_SUCCESS if successful or an error value. - **/ -int -asn1_encode_simple_der (unsigned int etype, const unsigned char *str, - unsigned int str_len, unsigned char *tl, - unsigned int *tl_len) -{ - int tag_len, len_len; - unsigned tlen; - unsigned char der_tag[ASN1_MAX_TAG_SIZE]; - unsigned char der_length[ASN1_MAX_LENGTH_SIZE]; - unsigned char *p; - - if (str == NULL) - return ASN1_VALUE_NOT_VALID; - - if (ETYPE_OK (etype) == 0) - return ASN1_VALUE_NOT_VALID; - - /* doesn't handle constructed classes */ - if (ETYPE_CLASS (etype) != ASN1_CLASS_UNIVERSAL) - return ASN1_VALUE_NOT_VALID; - - _asn1_tag_der (ETYPE_CLASS (etype), ETYPE_TAG (etype), der_tag, &tag_len); - - asn1_length_der (str_len, der_length, &len_len); - - if (tag_len <= 0 || len_len <= 0) - return ASN1_VALUE_NOT_VALID; - - tlen = tag_len + len_len; - - if (*tl_len < tlen) - return ASN1_MEM_ERROR; - - p = tl; - memcpy (p, der_tag, tag_len); - p += tag_len; - memcpy (p, der_length, len_len); - - *tl_len = tlen; - - return ASN1_SUCCESS; -} - -/******************************************************/ -/* Function : _asn1_time_der */ -/* Description: creates the DER coding for a TIME */ -/* type (length included). */ -/* Parameters: */ -/* str: TIME null-terminated string. */ -/* der: string returned. */ -/* der_len: number of meaningful bytes of DER */ -/* (der[0]..der[ans_len-1]). Initially it */ -/* if must store the lenght of DER. */ -/* Return: */ -/* ASN1_MEM_ERROR when DER isn't big enough */ -/* ASN1_SUCCESS otherwise */ -/******************************************************/ -static int -_asn1_time_der (unsigned char *str, int str_len, unsigned char *der, - int *der_len) -{ - int len_len; - int max_len; - - max_len = *der_len; - - asn1_length_der (str_len, (max_len > 0) ? der : NULL, &len_len); - - if ((len_len + str_len) <= max_len) - memcpy (der + len_len, str, str_len); - *der_len = len_len + str_len; - - if ((*der_len) > max_len) - return ASN1_MEM_ERROR; - - return ASN1_SUCCESS; -} - - -/* -void -_asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str) -{ - int len_len,str_len; - char temp[20]; - - if(str==NULL) return; - str_len=asn1_get_length_der(der,*der_len,&len_len); - if (str_len<0) return; - memcpy(temp,der+len_len,str_len); - *der_len=str_len+len_len; - switch(str_len) - { - case 11: - temp[10]=0; - strcat(temp,"00+0000"); - break; - case 13: - temp[12]=0; - strcat(temp,"+0000"); - break; - case 15: - temp[15]=0; - memmove(temp+12,temp+10,6); - temp[10]=temp[11]='0'; - break; - case 17: - temp[17]=0; - break; - default: - return; - } - strcpy(str,temp); -} -*/ - -static void -encode_val (uint64_t val, unsigned char *der, int max_len, int *der_len) -{ - int first, k; - unsigned char bit7; - - first = 0; - for (k = sizeof (val); k >= 0; k--) - { - bit7 = (val >> (k * 7)) & 0x7F; - if (bit7 || first || !k) - { - if (k) - bit7 |= 0x80; - if (max_len > (*der_len)) - der[*der_len] = bit7; - (*der_len)++; - first = 1; - } - } -} - -/******************************************************/ -/* Function : _asn1_object_id_der */ -/* Description: creates the DER coding for an */ -/* OBJECT IDENTIFIER type (length included). */ -/* Parameters: */ -/* str: OBJECT IDENTIFIER null-terminated string. */ -/* der: string returned. */ -/* der_len: number of meaningful bytes of DER */ -/* (der[0]..der[ans_len-1]). Initially it */ -/* must store the length of DER. */ -/* Return: */ -/* ASN1_MEM_ERROR when DER isn't big enough */ -/* ASN1_SUCCESS if succesful */ -/* or an error value. */ -/******************************************************/ -static int -_asn1_object_id_der (const char *str, unsigned char *der, int *der_len) -{ - int len_len, counter, max_len; - char *temp, *n_end, *n_start; - uint64_t val, val1 = 0; - int str_len = _asn1_strlen (str); - - max_len = *der_len; - *der_len = 0; - - if (der == NULL && max_len > 0) - return ASN1_VALUE_NOT_VALID; - - temp = malloc (str_len + 2); - if (temp == NULL) - return ASN1_MEM_ALLOC_ERROR; - - memcpy (temp, str, str_len); - temp[str_len] = '.'; - temp[str_len + 1] = 0; - - counter = 0; - n_start = temp; - while ((n_end = strchr (n_start, '.'))) - { - *n_end = 0; - val = _asn1_strtou64 (n_start, NULL, 10); - counter++; - - if (counter == 1) - { - val1 = val; - } - else if (counter == 2) - { - uint64_t val0; - - if (val1 > 2) - { - free (temp); - return ASN1_VALUE_NOT_VALID; - } - else if ((val1 == 0 || val1 == 1) && val > 39) - { - free (temp); - return ASN1_VALUE_NOT_VALID; - } - - val0 = 40 * val1 + val; - encode_val (val0, der, max_len, der_len); - } - else - { - encode_val (val, der, max_len, der_len); - } - n_start = n_end + 1; - } - - asn1_length_der (*der_len, NULL, &len_len); - if (max_len >= (*der_len + len_len)) - { - memmove (der + len_len, der, *der_len); - asn1_length_der (*der_len, der, &len_len); - } - *der_len += len_len; - - free (temp); - - if (max_len < (*der_len)) - return ASN1_MEM_ERROR; - - return ASN1_SUCCESS; -} - -/** - * asn1_object_id_der: - * @str: An object identifier in numeric, dot format. - * @der: buffer to hold the returned encoding (may be %NULL). - * @der_len: initially the size of @der; will hold the final size. - * @flags: must be zero - * - * Creates the DER encoding of the provided object identifier. - * - * Returns: %ASN1_SUCCESS if DER encoding was OK, %ASN1_VALUE_NOT_VALID - * if @str is not a valid OID, %ASN1_MEM_ERROR if the @der - * vector isn't big enough and in this case @der_len will contain the - * length needed. - **/ -int -asn1_object_id_der (const char *str, unsigned char *der, int *der_len, - unsigned flags) -{ - unsigned char tag_der[MAX_TAG_LEN]; - int tag_len = 0, r; - int max_len = *der_len; - - *der_len = 0; - - _asn1_tag_der (ETYPE_CLASS (ASN1_ETYPE_OBJECT_ID), - ETYPE_TAG (ASN1_ETYPE_OBJECT_ID), tag_der, &tag_len); - - if (max_len > tag_len) - { - memcpy (der, tag_der, tag_len); - } - max_len -= tag_len; - der += tag_len; - - r = _asn1_object_id_der (str, der, &max_len); - if (r == ASN1_MEM_ERROR || r == ASN1_SUCCESS) - { - *der_len = max_len + tag_len; - } - - return r; -} - -static const unsigned char bit_mask[] = - { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 }; - -/** - * asn1_bit_der: - * @str: BIT string. - * @bit_len: number of meaningful bits in STR. - * @der: string returned. - * @der_len: number of meaningful bytes of DER - * (der[0]..der[ans_len-1]). - * - * Creates a length-value DER encoding for the input data - * as it would have been for a BIT STRING. - * The DER encoded data will be copied in @der. - * - * Note that the BIT STRING tag is not included in the output. - * - * This function does not return any value because it is expected - * that @der_len will contain enough bytes to store the string - * plus the DER encoding. The DER encoding size can be obtained using - * asn1_length_der(). - **/ -void -asn1_bit_der (const unsigned char *str, int bit_len, - unsigned char *der, int *der_len) -{ - int len_len, len_byte, len_pad; - - if (der == NULL) - return; - - len_byte = bit_len >> 3; - len_pad = 8 - (bit_len & 7); - if (len_pad == 8) - len_pad = 0; - else - len_byte++; - asn1_length_der (len_byte + 1, der, &len_len); - der[len_len] = len_pad; - - if (str) - memcpy (der + len_len + 1, str, len_byte); - der[len_len + len_byte] &= bit_mask[len_pad]; - *der_len = len_byte + len_len + 1; -} - - -/******************************************************/ -/* Function : _asn1_complete_explicit_tag */ -/* Description: add the length coding to the EXPLICIT */ -/* tags. */ -/* Parameters: */ -/* node: pointer to the tree element. */ -/* der: string with the DER coding of the whole tree*/ -/* counter: number of meaningful bytes of DER */ -/* (der[0]..der[*counter-1]). */ -/* max_len: size of der vector */ -/* Return: */ -/* ASN1_MEM_ERROR if der vector isn't big enough, */ -/* otherwise ASN1_SUCCESS. */ -/******************************************************/ -static int -_asn1_complete_explicit_tag (asn1_node node, unsigned char *der, - int *counter, int *max_len) -{ - asn1_node p; - int is_tag_implicit, len2, len3; - unsigned char temp[SIZEOF_UNSIGNED_INT]; - - if (der == NULL && *max_len > 0) - return ASN1_VALUE_NOT_VALID; - - is_tag_implicit = 0; - - if (node->type & CONST_TAG) - { - p = node->down; - if (p == NULL) - return ASN1_DER_ERROR; - /* When there are nested tags we must complete them reverse to - the order they were created. This is because completing a tag - modifies all data within it, including the incomplete tags - which store buffer positions -- simon@josefsson.org 2002-09-06 - */ - while (p->right) - p = p->right; - while (p && p != node->down->left) - { - if (type_field (p->type) == ASN1_ETYPE_TAG) - { - if (p->type & CONST_EXPLICIT) - { - len2 = strtol (p->name, NULL, 10); - _asn1_set_name (p, NULL); - - asn1_length_der (*counter - len2, temp, &len3); - if (len3 <= (*max_len)) - { - memmove (der + len2 + len3, der + len2, - *counter - len2); - memcpy (der + len2, temp, len3); - } - *max_len -= len3; - *counter += len3; - is_tag_implicit = 0; - } - else - { /* CONST_IMPLICIT */ - if (!is_tag_implicit) - { - is_tag_implicit = 1; - } - } - } - p = p->left; - } - } - - if (*max_len < 0) - return ASN1_MEM_ERROR; - - return ASN1_SUCCESS; -} - -const tag_and_class_st _asn1_tags[] = { - [ASN1_ETYPE_GENERALSTRING] = - {ASN1_TAG_GENERALSTRING, ASN1_CLASS_UNIVERSAL, "type:GENERALSTRING"}, - [ASN1_ETYPE_NUMERIC_STRING] = - {ASN1_TAG_NUMERIC_STRING, ASN1_CLASS_UNIVERSAL, "type:NUMERIC_STR"}, - [ASN1_ETYPE_IA5_STRING] = - {ASN1_TAG_IA5_STRING, ASN1_CLASS_UNIVERSAL, "type:IA5_STR"}, - [ASN1_ETYPE_TELETEX_STRING] = - {ASN1_TAG_TELETEX_STRING, ASN1_CLASS_UNIVERSAL, "type:TELETEX_STR"}, - [ASN1_ETYPE_PRINTABLE_STRING] = - {ASN1_TAG_PRINTABLE_STRING, ASN1_CLASS_UNIVERSAL, "type:PRINTABLE_STR"}, - [ASN1_ETYPE_UNIVERSAL_STRING] = - {ASN1_TAG_UNIVERSAL_STRING, ASN1_CLASS_UNIVERSAL, "type:UNIVERSAL_STR"}, - [ASN1_ETYPE_BMP_STRING] = - {ASN1_TAG_BMP_STRING, ASN1_CLASS_UNIVERSAL, "type:BMP_STR"}, - [ASN1_ETYPE_UTF8_STRING] = - {ASN1_TAG_UTF8_STRING, ASN1_CLASS_UNIVERSAL, "type:UTF8_STR"}, - [ASN1_ETYPE_VISIBLE_STRING] = - {ASN1_TAG_VISIBLE_STRING, ASN1_CLASS_UNIVERSAL, "type:VISIBLE_STR"}, - [ASN1_ETYPE_OCTET_STRING] = - {ASN1_TAG_OCTET_STRING, ASN1_CLASS_UNIVERSAL, "type:OCT_STR"}, - [ASN1_ETYPE_BIT_STRING] = - {ASN1_TAG_BIT_STRING, ASN1_CLASS_UNIVERSAL, "type:BIT_STR"}, - [ASN1_ETYPE_OBJECT_ID] = - {ASN1_TAG_OBJECT_ID, ASN1_CLASS_UNIVERSAL, "type:OBJ_ID"}, - [ASN1_ETYPE_NULL] = {ASN1_TAG_NULL, ASN1_CLASS_UNIVERSAL, "type:NULL"}, - [ASN1_ETYPE_BOOLEAN] = - {ASN1_TAG_BOOLEAN, ASN1_CLASS_UNIVERSAL, "type:BOOLEAN"}, - [ASN1_ETYPE_INTEGER] = - {ASN1_TAG_INTEGER, ASN1_CLASS_UNIVERSAL, "type:INTEGER"}, - [ASN1_ETYPE_ENUMERATED] = - {ASN1_TAG_ENUMERATED, ASN1_CLASS_UNIVERSAL, "type:ENUMERATED"}, - [ASN1_ETYPE_SEQUENCE] = - {ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, - "type:SEQUENCE"}, - [ASN1_ETYPE_SEQUENCE_OF] = - {ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, - "type:SEQ_OF"}, - [ASN1_ETYPE_SET] = - {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, "type:SET"}, - [ASN1_ETYPE_SET_OF] = - {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, - "type:SET_OF"}, - [ASN1_ETYPE_GENERALIZED_TIME] = - {ASN1_TAG_GENERALIZEDTime, ASN1_CLASS_UNIVERSAL, "type:GENERALIZED_TIME"}, - [ASN1_ETYPE_UTC_TIME] = - {ASN1_TAG_UTCTime, ASN1_CLASS_UNIVERSAL, "type:UTC_TIME"}, -}; - -unsigned int _asn1_tags_size = sizeof (_asn1_tags) / sizeof (_asn1_tags[0]); - -/******************************************************/ -/* Function : _asn1_insert_tag_der */ -/* Description: creates the DER coding of tags of one */ -/* NODE. */ -/* Parameters: */ -/* node: pointer to the tree element. */ -/* der: string returned */ -/* counter: number of meaningful bytes of DER */ -/* (counter[0]..der[*counter-1]). */ -/* max_len: size of der vector */ -/* Return: */ -/* ASN1_GENERIC_ERROR if the type is unknown, */ -/* ASN1_MEM_ERROR if der vector isn't big enough, */ -/* otherwise ASN1_SUCCESS. */ -/******************************************************/ -static int -_asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter, - int *max_len) -{ - asn1_node p; - int tag_len, is_tag_implicit; - unsigned char class, class_implicit = - 0, temp[MAX (SIZEOF_UNSIGNED_INT * 3 + 1, LTOSTR_MAX_SIZE)]; - unsigned long tag_implicit = 0; - unsigned char tag_der[MAX_TAG_LEN]; - - is_tag_implicit = 0; - - if (node->type & CONST_TAG) - { - p = node->down; - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_TAG) - { - if (p->type & CONST_APPLICATION) - class = ASN1_CLASS_APPLICATION; - else if (p->type & CONST_UNIVERSAL) - class = ASN1_CLASS_UNIVERSAL; - else if (p->type & CONST_PRIVATE) - class = ASN1_CLASS_PRIVATE; - else - class = ASN1_CLASS_CONTEXT_SPECIFIC; - - if (p->type & CONST_EXPLICIT) - { - if (is_tag_implicit) - _asn1_tag_der (class_implicit, tag_implicit, tag_der, - &tag_len); - else - _asn1_tag_der (class | ASN1_CLASS_STRUCTURED, - _asn1_strtoul (p->value, NULL, 10), - tag_der, &tag_len); - - *max_len -= tag_len; - if (der && *max_len >= 0) - memcpy (der + *counter, tag_der, tag_len); - *counter += tag_len; - - _asn1_ltostr (*counter, (char *) temp); - _asn1_set_name (p, (const char *) temp); - - is_tag_implicit = 0; - } - else - { /* CONST_IMPLICIT */ - if (!is_tag_implicit) - { - if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) || - (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF) - || (type_field (node->type) == ASN1_ETYPE_SET) - || (type_field (node->type) == ASN1_ETYPE_SET_OF)) - class |= ASN1_CLASS_STRUCTURED; - class_implicit = class; - tag_implicit = _asn1_strtoul (p->value, NULL, 10); - is_tag_implicit = 1; - } - } - } - p = p->right; - } - } - - if (is_tag_implicit) - { - _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len); - } - else - { - unsigned type = type_field (node->type); - switch (type) - { - CASE_HANDLED_ETYPES: - _asn1_tag_der (_asn1_tags[type].class, _asn1_tags[type].tag, - tag_der, &tag_len); - break; - case ASN1_ETYPE_TAG: - case ASN1_ETYPE_CHOICE: - case ASN1_ETYPE_ANY: - tag_len = 0; - break; - default: - return ASN1_GENERIC_ERROR; - } - } - - *max_len -= tag_len; - if (der && *max_len >= 0) - memcpy (der + *counter, tag_der, tag_len); - *counter += tag_len; - - if (*max_len < 0) - return ASN1_MEM_ERROR; - - return ASN1_SUCCESS; -} - -/******************************************************/ -/* Function : _asn1_ordering_set */ -/* Description: puts the elements of a SET type in */ -/* the correct order according to DER rules. */ -/* Parameters: */ -/* der: string with the DER coding. */ -/* node: pointer to the SET element. */ -/* Return: */ -/* ASN1_SUCCESS if successful */ -/* or an error value. */ -/******************************************************/ -static int -_asn1_ordering_set (unsigned char *der, int der_len, asn1_node node) -{ - struct vet - { - int end; - unsigned long value; - struct vet *next, *prev; - }; - - int counter, len, len2; - struct vet *first, *last, *p_vet, *p2_vet; - asn1_node p; - unsigned char class, *temp; - unsigned long tag, t; - int err; - - counter = 0; - - if (type_field (node->type) != ASN1_ETYPE_SET) - return ASN1_VALUE_NOT_VALID; - - p = node->down; - while (p && ((type_field (p->type) == ASN1_ETYPE_TAG) || - (type_field (p->type) == ASN1_ETYPE_SIZE))) - p = p->right; - - if ((p == NULL) || (p->right == NULL)) - return ASN1_SUCCESS; - - first = last = NULL; - while (p) - { - p_vet = malloc (sizeof (struct vet)); - if (p_vet == NULL) - { - err = ASN1_MEM_ALLOC_ERROR; - goto error; - } - - p_vet->next = NULL; - p_vet->prev = last; - if (first == NULL) - first = p_vet; - else - last->next = p_vet; - last = p_vet; - - /* tag value calculation */ - err = asn1_get_tag_der (der + counter, der_len - counter, &class, &len2, - &tag); - if (err != ASN1_SUCCESS) - goto error; - - t = ((unsigned int) class) << 24; - p_vet->value = t | tag; - counter += len2; - - /* extraction and length */ - len2 = asn1_get_length_der (der + counter, der_len - counter, &len); - if (len2 < 0) - { - err = ASN1_DER_ERROR; - goto error; - } - counter += len + len2; - - p_vet->end = counter; - p = p->right; - } - - p_vet = first; - - while (p_vet) - { - p2_vet = p_vet->next; - counter = 0; - while (p2_vet) - { - if (p_vet->value > p2_vet->value) - { - /* change position */ - temp = malloc (p_vet->end - counter); - if (temp == NULL) - { - err = ASN1_MEM_ALLOC_ERROR; - goto error; - } - - memcpy (temp, der + counter, p_vet->end - counter); - memcpy (der + counter, der + p_vet->end, - p2_vet->end - p_vet->end); - memcpy (der + counter + p2_vet->end - p_vet->end, temp, - p_vet->end - counter); - free (temp); - - tag = p_vet->value; - p_vet->value = p2_vet->value; - p2_vet->value = tag; - - p_vet->end = counter + (p2_vet->end - p_vet->end); - } - counter = p_vet->end; - - p2_vet = p2_vet->next; - p_vet = p_vet->next; - } - - if (p_vet != first) - p_vet->prev->next = NULL; - else - first = NULL; - free (p_vet); - p_vet = first; - } - return ASN1_SUCCESS; - -error: - while (first != NULL) - { - p_vet = first; - first = first->next; - free (p_vet); - } - return err; -} - -struct vet -{ - unsigned char *ptr; - int size; -}; - -static int -setof_compar (const void *_e1, const void *_e2) -{ - unsigned length; - const struct vet *e1 = _e1, *e2 = _e2; - int rval; - - /* The encodings of the component values of a set-of value shall - * appear in ascending order, the encodings being compared - * as octet strings with the shorter components being - * padded at their trailing end with 0-octets. - * The padding octets are for comparison purposes and - * do not appear in the encodings. - */ - length = MIN (e1->size, e2->size); - - rval = memcmp (e1->ptr, e2->ptr, length); - if (rval == 0 && e1->size != e2->size) - { - if (e1->size > e2->size) - rval = 1; - else if (e2->size > e1->size) - rval = -1; - } - - return rval; -} - -/******************************************************/ -/* Function : _asn1_ordering_set_of */ -/* Description: puts the elements of a SET OF type in */ -/* the correct order according to DER rules. */ -/* Parameters: */ -/* der: string with the DER coding. */ -/* node: pointer to the SET OF element. */ -/* Return: */ -/* ASN1_SUCCESS if successful */ -/* or an error value. */ -/******************************************************/ -static int -_asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node) -{ - int counter, len, len2; - struct vet *list = NULL, *tlist; - unsigned list_size = 0; - struct vet *p_vet; - asn1_node p; - unsigned char class; - unsigned i; - unsigned char *out = NULL; - int err; - - counter = 0; - - if (type_field (node->type) != ASN1_ETYPE_SET_OF) - return ASN1_VALUE_NOT_VALID; - - p = node->down; - while (p && ((type_field (p->type) == ASN1_ETYPE_TAG) || - (type_field (p->type) == ASN1_ETYPE_SIZE))) - p = p->right; - if (p == NULL) - return ASN1_VALUE_NOT_VALID; - p = p->right; - - if ((p == NULL) || (p->right == NULL)) - return ASN1_SUCCESS; - - while (p) - { - list_size++; - tlist = realloc (list, list_size * sizeof (struct vet)); - if (tlist == NULL) - { - err = ASN1_MEM_ALLOC_ERROR; - goto error; - } - list = tlist; - p_vet = &list[list_size - 1]; - - p_vet->ptr = der + counter; - p_vet->size = 0; - - /* extraction of tag and length */ - if (der_len - counter > 0) - { - err = asn1_get_tag_der (der + counter, der_len - counter, &class, - &len, NULL); - if (err != ASN1_SUCCESS) - goto error; - counter += len; - p_vet->size += len; - - len2 = asn1_get_length_der (der + counter, der_len - counter, &len); - if (len2 < 0) - { - err = ASN1_DER_ERROR; - goto error; - } - counter += len + len2; - p_vet->size += len + len2; - - } - else - { - err = ASN1_DER_ERROR; - goto error; - } - p = p->right; - } - - if (counter > der_len) - { - err = ASN1_DER_ERROR; - goto error; - } - - qsort (list, list_size, sizeof (struct vet), setof_compar); - - out = malloc (der_len); - if (out == NULL) - { - err = ASN1_MEM_ERROR; - goto error; - } - - /* the sum of p_vet->size == der_len */ - counter = 0; - for (i = 0; i < list_size; i++) - { - p_vet = &list[i]; - memcpy (out + counter, p_vet->ptr, p_vet->size); - counter += p_vet->size; - } - memcpy (der, out, der_len); - free (out); - - err = ASN1_SUCCESS; - -error: - free (list); - return err; -} - -/** - * asn1_der_coding: - * @element: pointer to an ASN1 element - * @name: the name of the structure you want to encode (it must be - * inside *POINTER). - * @ider: vector that will contain the DER encoding. DER must be a - * pointer to memory cells already allocated. - * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy - * holds the sizeof of der vector. - * @ErrorDescription: return the error description or an empty - * string if success. - * - * Creates the DER encoding for the NAME structure (inside *POINTER - * structure). - * - * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND - * if @name is not a valid element, %ASN1_VALUE_NOT_FOUND if there - * is an element without a value, %ASN1_MEM_ERROR if the @ider - * vector isn't big enough and in this case @len will contain the - * length needed. - **/ -int -asn1_der_coding (asn1_node_const element, const char *name, void *ider, - int *len, char *ErrorDescription) -{ - asn1_node node, p, p2; - unsigned char temp[MAX (LTOSTR_MAX_SIZE, SIZEOF_UNSIGNED_LONG_INT * 3 + 1)]; - int counter, counter_old, len2, len3, move, max_len, max_len_old; - int err; - unsigned char *der = ider; - unsigned char dummy; - - if (ErrorDescription) - ErrorDescription[0] = 0; - - node = asn1_find_node (element, name); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - /* Node is now a locally allocated variable. - * That is because in some point we modify the - * structure, and I don't know why! --nmav - */ - node = _asn1_copy_structure3 (node); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - max_len = *len; - - if (der == NULL && max_len > 0) - { - err = ASN1_VALUE_NOT_VALID; - goto error; - } - - counter = 0; - move = DOWN; - p = node; - - while (1) - { - - counter_old = counter; - max_len_old = max_len; - if (move != UP) - { - p->start = counter; - err = _asn1_insert_tag_der (p, der, &counter, &max_len); - if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) - goto error; - } - switch (type_field (p->type)) - { - case ASN1_ETYPE_NULL: - max_len--; - if (der != NULL && max_len >= 0) - der[counter] = 0; - counter++; - move = RIGHT; - break; - case ASN1_ETYPE_BOOLEAN: - if ((p->type & CONST_DEFAULT) && (p->value == NULL)) - { - counter = counter_old; - max_len = max_len_old; - } - else - { - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, - ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - max_len -= 2; - if (der != NULL && max_len >= 0) - { - der[counter++] = 1; - if (p->value[0] == 'F') - der[counter++] = 0; - else - der[counter++] = 0xFF; - } - else - counter += 2; - } - move = RIGHT; - break; - case ASN1_ETYPE_INTEGER: - case ASN1_ETYPE_ENUMERATED: - if ((p->type & CONST_DEFAULT) && (p->value == NULL)) - { - counter = counter_old; - max_len = max_len_old; - } - else - { - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, - ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - len2 = asn1_get_length_der (p->value, p->value_len, &len3); - if (len2 < 0) - { - err = ASN1_DER_ERROR; - goto error; - } - max_len -= len2 + len3; - if (der != NULL && max_len >= 0) - memcpy (der + counter, p->value, len3 + len2); - counter += len3 + len2; - } - move = RIGHT; - break; - case ASN1_ETYPE_OBJECT_ID: - if ((p->type & CONST_DEFAULT) && (p->value == NULL)) - { - counter = counter_old; - max_len = max_len_old; - } - else - { - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, - ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - len2 = max_len; - err = - _asn1_object_id_der ((char *) p->value, - der ? der + counter : &dummy, &len2); - if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) - goto error; - - max_len -= len2; - counter += len2; - } - move = RIGHT; - break; - case ASN1_ETYPE_GENERALIZED_TIME: - case ASN1_ETYPE_UTC_TIME: - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - len2 = max_len; - err = - _asn1_time_der (p->value, p->value_len, - der ? der + counter : &dummy, &len2); - if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) - goto error; - - max_len -= len2; - counter += len2; - move = RIGHT; - break; - case ASN1_ETYPE_OCTET_STRING: - case ASN1_ETYPE_GENERALSTRING: - case ASN1_ETYPE_NUMERIC_STRING: - case ASN1_ETYPE_IA5_STRING: - case ASN1_ETYPE_TELETEX_STRING: - case ASN1_ETYPE_PRINTABLE_STRING: - case ASN1_ETYPE_UNIVERSAL_STRING: - case ASN1_ETYPE_BMP_STRING: - case ASN1_ETYPE_UTF8_STRING: - case ASN1_ETYPE_VISIBLE_STRING: - case ASN1_ETYPE_BIT_STRING: - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - len2 = asn1_get_length_der (p->value, p->value_len, &len3); - if (len2 < 0) - { - err = ASN1_DER_ERROR; - goto error; - } - max_len -= len2 + len3; - if (der != NULL && max_len >= 0) - memcpy (der + counter, p->value, len3 + len2); - counter += len3 + len2; - move = RIGHT; - break; - case ASN1_ETYPE_SEQUENCE: - case ASN1_ETYPE_SET: - if (move != UP) - { - p->tmp_ival = counter; - if (p->down == NULL) - { - move = UP; - continue; - } - else - { - p2 = p->down; - while (p2 && (type_field (p2->type) == ASN1_ETYPE_TAG)) - p2 = p2->right; - if (p2) - { - p = p2; - move = RIGHT; - continue; - } - move = UP; - continue; - } - } - else - { /* move==UP */ - len2 = p->tmp_ival; - p->tmp_ival = 0; - if ((type_field (p->type) == ASN1_ETYPE_SET) && (max_len >= 0)) - { - err = - _asn1_ordering_set (der ? der + len2 : &dummy, - counter - len2, p); - if (err != ASN1_SUCCESS) - goto error; - } - asn1_length_der (counter - len2, temp, &len3); - max_len -= len3; - if (der != NULL && max_len >= 0) - { - memmove (der + len2 + len3, der + len2, counter - len2); - memcpy (der + len2, temp, len3); - } - counter += len3; - move = RIGHT; - } - break; - case ASN1_ETYPE_SEQUENCE_OF: - case ASN1_ETYPE_SET_OF: - if (move != UP) - { - p->tmp_ival = counter; - p = p->down; - while ((type_field (p->type) == ASN1_ETYPE_TAG) - || (type_field (p->type) == ASN1_ETYPE_SIZE)) - p = p->right; - if (p->right) - { - p = p->right; - move = RIGHT; - continue; - } - else - p = _asn1_find_up (p); - move = UP; - } - if (move == UP) - { - len2 = p->tmp_ival; - p->tmp_ival = 0; - if ((type_field (p->type) == ASN1_ETYPE_SET_OF) - && (counter - len2 > 0) && (max_len >= 0)) - { - err = - _asn1_ordering_set_of (der ? der + len2 : &dummy, - counter - len2, p); - if (err != ASN1_SUCCESS) - goto error; - } - asn1_length_der (counter - len2, temp, &len3); - max_len -= len3; - if (der != NULL && max_len >= 0) - { - memmove (der + len2 + len3, der + len2, counter - len2); - memcpy (der + len2, temp, len3); - } - counter += len3; - move = RIGHT; - } - break; - case ASN1_ETYPE_ANY: - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - len2 = asn1_get_length_der (p->value, p->value_len, &len3); - if (len2 < 0) - { - err = ASN1_DER_ERROR; - goto error; - } - max_len -= len2; - if (der != NULL && max_len >= 0) - memcpy (der + counter, p->value + len3, len2); - counter += len2; - move = RIGHT; - break; - default: - move = (move == UP) ? RIGHT : DOWN; - break; - } - - if ((move != DOWN) && (counter != counter_old)) - { - p->end = counter - 1; - err = _asn1_complete_explicit_tag (p, der, &counter, &max_len); - if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) - goto error; - } - - if (p == node && move != DOWN) - break; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - if (move == RIGHT) - { - if (p->right) - p = p->right; - else - move = UP; - } - if (move == UP) - p = _asn1_find_up (p); - } - - *len = counter; - - if (max_len < 0) - { - err = ASN1_MEM_ERROR; - goto error; - } - - err = ASN1_SUCCESS; - -error: - asn1_delete_structure (&node); - return err; -} diff --git a/grub-core/lib/libtasn1/lib/decoding.c b/grub-core/lib/libtasn1/lib/decoding.c deleted file mode 100644 index b9245c486..000000000 --- a/grub-core/lib/libtasn1/lib/decoding.c +++ /dev/null @@ -1,2501 +0,0 @@ -/* - * Copyright (C) 2002-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 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 - */ - - -/*****************************************************/ -/* File: decoding.c */ -/* Description: Functions to manage DER decoding */ -/*****************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include "c-ctype.h" - -#ifdef DEBUG -# define warn() fprintf(stderr, "%s: %d\n", __func__, __LINE__) -#else -# define warn() -#endif - -#define IS_ERR(len, flags) (len < -1 || ((flags & ASN1_DECODE_FLAG_STRICT_DER) && len < 0)) - -#define HAVE_TWO(x) (x>=2?1:0) - -/* Decoding flags (dflags) used in several decoding functions. - * DECODE_FLAG_HAVE_TAG: The provided buffer includes a tag - * DECODE_FLAG_CONSTRUCTED: The provided buffer is of indefinite encoding (useful - * when no tags are present). - * DECODE_FLAG_LEVEL1: Internal flag to indicate a level of recursion for BER strings. - * DECODE_FLAG_LEVEL2: Internal flag to indicate two levels of recursion for BER strings. - * DECODE_FLAG_LEVEL3: Internal flag to indicate three levels of recursion for BER strings. - * This is the maximum levels of recursion possible to prevent stack - * exhaustion. - */ - -#define DECODE_FLAG_HAVE_TAG 1 -#define DECODE_FLAG_CONSTRUCTED (1<<1) -#define DECODE_FLAG_LEVEL1 (1<<2) -#define DECODE_FLAG_LEVEL2 (1<<3) -#define DECODE_FLAG_LEVEL3 (1<<4) - -#define DECR_LEN(l, s) do { \ - l -= s; \ - if (l < 0) { \ - warn(); \ - result = ASN1_DER_ERROR; \ - goto cleanup; \ - } \ - } while (0) - -static int -_asn1_get_indefinite_length_string (const unsigned char *der, int der_len, - int *len); - -static int -_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, - unsigned int _der_len, unsigned char **str, - unsigned int *str_len, unsigned int *ber_len, - unsigned dflags); - -static int -_asn1_decode_simple_der (unsigned int etype, const unsigned char *der, - unsigned int _der_len, const unsigned char **str, - unsigned int *str_len, unsigned dflags); - -static void -_asn1_error_description_tag_error (asn1_node node, char *ErrorDescription) -{ - - Estrcpy (ErrorDescription, ":: tag error near element '"); - _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription), - ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40); - Estrcat (ErrorDescription, "'"); - -} - -/** - * asn1_get_length_der: - * @der: DER data to decode. - * @der_len: Length of DER data to decode. - * @len: Output variable containing the length of the DER length field. - * - * Extract a length field from DER data. - * - * Returns: Return the decoded length value, or -1 on indefinite - * length, or -2 when the value was too big to fit in a int, or -4 - * when the decoded length value plus @len would exceed @der_len. - **/ -long -asn1_get_length_der (const unsigned char *der, int der_len, int *len) -{ - unsigned int ans; - int k, punt, sum; - - *len = 0; - if (der_len <= 0) - return 0; - - if (!(der[0] & 128)) - { - /* short form */ - *len = 1; - ans = der[0]; - } - else - { - /* Long form */ - k = der[0] & 0x7F; - punt = 1; - if (k) - { /* definite length method */ - ans = 0; - while (punt <= k && punt < der_len) - { - if (INT_MULTIPLY_OVERFLOW (ans, 256)) - return -2; - ans *= 256; - - if (INT_ADD_OVERFLOW (ans, ((unsigned) der[punt]))) - return -2; - ans += der[punt]; - punt++; - } - } - else - { /* indefinite length method */ - *len = punt; - return -1; - } - - *len = punt; - } - - sum = ans; - if (ans >= INT_MAX || INT_ADD_OVERFLOW (sum, (*len))) - return -2; - sum += *len; - - if (sum > der_len) - return -4; - - return ans; -} - -/** - * asn1_get_tag_der: - * @der: DER data to decode. - * @der_len: Length of DER data to decode. - * @cls: Output variable containing decoded class. - * @len: Output variable containing the length of the DER TAG data. - * @tag: Output variable containing the decoded tag (may be %NULL). - * - * Decode the class and TAG from DER code. - * - * Returns: Returns %ASN1_SUCCESS on success, or an error. - **/ -int -asn1_get_tag_der (const unsigned char *der, int der_len, - unsigned char *cls, int *len, unsigned long *tag) -{ - unsigned int ris; - int punt; - - if (der == NULL || der_len < 2 || len == NULL) - return ASN1_DER_ERROR; - - *cls = der[0] & 0xE0; - if ((der[0] & 0x1F) != 0x1F) - { - /* short form */ - *len = 1; - ris = der[0] & 0x1F; - } - else - { - /* Long form */ - punt = 1; - ris = 0; - while (punt < der_len && der[punt] & 128) - { - - if (INT_MULTIPLY_OVERFLOW (ris, 128)) - return ASN1_DER_ERROR; - ris *= 128; - - if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F)))) - return ASN1_DER_ERROR; - ris += (der[punt] & 0x7F); - punt++; - } - - if (punt >= der_len) - return ASN1_DER_ERROR; - - if (INT_MULTIPLY_OVERFLOW (ris, 128)) - return ASN1_DER_ERROR; - ris *= 128; - - if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F)))) - return ASN1_DER_ERROR; - ris += (der[punt] & 0x7F); - punt++; - - *len = punt; - } - - if (tag) - *tag = ris; - return ASN1_SUCCESS; -} - -/** - * asn1_get_length_ber: - * @ber: BER data to decode. - * @ber_len: Length of BER data to decode. - * @len: Output variable containing the length of the BER length field. - * - * Extract a length field from BER data. The difference to - * asn1_get_length_der() is that this function will return a length - * even if the value has indefinite encoding. - * - * Returns: Return the decoded length value, or negative value when - * the value was too big. - * - * Since: 2.0 - **/ -long -asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len) -{ - int ret; - long err; - - ret = asn1_get_length_der (ber, ber_len, len); - - if (ret == -1 && ber_len > 1) - { /* indefinite length method */ - err = _asn1_get_indefinite_length_string (ber + 1, ber_len - 1, &ret); - if (err != ASN1_SUCCESS) - return -3; - } - - return ret; -} - -/** - * asn1_get_octet_der: - * @der: DER data to decode containing the OCTET SEQUENCE. - * @der_len: The length of the @der data to decode. - * @ret_len: Output variable containing the encoded length of the DER data. - * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in. - * @str_size: Length of pre-allocated output buffer. - * @str_len: Output variable containing the length of the contents of the OCTET SEQUENCE. - * - * Extract an OCTET SEQUENCE from DER data. Note that this function - * expects the DER data past the tag field, i.e., the length and - * content octets. - * - * Returns: Returns %ASN1_SUCCESS on success, or an error. - **/ -int -asn1_get_octet_der (const unsigned char *der, int der_len, - int *ret_len, unsigned char *str, int str_size, - int *str_len) -{ - int len_len = 0; - - if (der_len <= 0) - return ASN1_GENERIC_ERROR; - - *str_len = asn1_get_length_der (der, der_len, &len_len); - - if (*str_len < 0) - return ASN1_DER_ERROR; - - *ret_len = *str_len + len_len; - if (str_size >= *str_len) - { - if (*str_len > 0 && str != NULL) - memcpy (str, der + len_len, *str_len); - } - else - { - return ASN1_MEM_ERROR; - } - - return ASN1_SUCCESS; -} - - -/*- - * _asn1_get_time_der: - * @type: %ASN1_ETYPE_GENERALIZED_TIME or %ASN1_ETYPE_UTC_TIME - * @der: DER data to decode containing the time - * @der_len: Length of DER data to decode. - * @ret_len: Output variable containing the length of the DER data. - * @str: Pre-allocated output buffer to put the textual time in. - * @str_size: Length of pre-allocated output buffer. - * @flags: Zero or %ASN1_DECODE_FLAG_STRICT_DER - * - * Performs basic checks in the DER encoded time object and returns its textual form. - * The textual form will be in the YYYYMMDD000000Z format for GeneralizedTime - * and YYMMDD000000Z for UTCTime. - * - * Returns: %ASN1_SUCCESS on success, or an error. - -*/ -static int -_asn1_get_time_der (unsigned type, const unsigned char *der, int der_len, - int *ret_len, char *str, int str_size, unsigned flags) -{ - int len_len, str_len; - unsigned i; - unsigned sign_count = 0; - unsigned dot_count = 0; - const unsigned char *p; - - if (der_len <= 0 || str == NULL) - return ASN1_DER_ERROR; - - str_len = asn1_get_length_der (der, der_len, &len_len); - if (str_len <= 0 || str_size < str_len) - return ASN1_DER_ERROR; - - /* perform some sanity checks on the data */ - if (str_len < 8) - { - warn (); - return ASN1_TIME_ENCODING_ERROR; - } - - if ((flags & ASN1_DECODE_FLAG_STRICT_DER) - && !(flags & ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME)) - { - p = &der[len_len]; - for (i = 0; i < (unsigned) (str_len - 1); i++) - { - if (c_isdigit (p[i]) == 0) - { - if (type == ASN1_ETYPE_GENERALIZED_TIME) - { - /* tolerate lax encodings */ - if (p[i] == '.' && dot_count == 0) - { - dot_count++; - continue; - } - - /* This is not really valid DER, but there are - * structures using that */ - if (!(flags & ASN1_DECODE_FLAG_STRICT_DER) && - (p[i] == '+' || p[i] == '-') && sign_count == 0) - { - sign_count++; - continue; - } - } - - warn (); - return ASN1_TIME_ENCODING_ERROR; - } - } - - if (sign_count == 0 && p[str_len - 1] != 'Z') - { - warn (); - return ASN1_TIME_ENCODING_ERROR; - } - } - memcpy (str, der + len_len, str_len); - str[str_len] = 0; - *ret_len = str_len + len_len; - - return ASN1_SUCCESS; -} - -/** - * asn1_get_object_id_der: - * @der: DER data to decode containing the OBJECT IDENTIFIER - * @der_len: Length of DER data to decode. - * @ret_len: Output variable containing the length of the DER data. - * @str: Pre-allocated output buffer to put the textual object id in. - * @str_size: Length of pre-allocated output buffer. - * - * Converts a DER encoded object identifier to its textual form. This - * function expects the DER object identifier without the tag. - * - * Returns: %ASN1_SUCCESS on success, or an error. - **/ -int -asn1_get_object_id_der (const unsigned char *der, int der_len, int *ret_len, - char *str, int str_size) -{ - int len_len, len, k; - int leading, parsed; - char temp[LTOSTR_MAX_SIZE]; - uint64_t val, val1, val0; - - *ret_len = 0; - if (str && str_size > 0) - str[0] = 0; /* no oid */ - - if (str == NULL || der_len <= 0) - return ASN1_GENERIC_ERROR; - - len = asn1_get_length_der (der, der_len, &len_len); - - if (len <= 0 || len + len_len > der_len) - return ASN1_DER_ERROR; - - /* leading octet can never be 0x80 */ - if (der[len_len] == 0x80) - return ASN1_DER_ERROR; - - val0 = 0; - - for (k = 0; k < len; k++) - { - if (INT_LEFT_SHIFT_OVERFLOW (val0, 7)) - return ASN1_DER_ERROR; - - val0 <<= 7; - val0 |= der[len_len + k] & 0x7F; - if (!(der[len_len + k] & 0x80)) - break; - } - parsed = ++k; - - /* val0 = (X*40) + Y, X={0,1,2}, Y<=39 when X={0,1} */ - /* X = val, Y = val1 */ - - /* check if X == 0 */ - val = 0; - val1 = val0; - if (val1 > 39) - { - val = 1; - val1 = val0 - 40; - if (val1 > 39) - { - val = 2; - val1 = val0 - 80; - } - } - - _asn1_str_cpy (str, str_size, _asn1_ltostr (val, temp)); - _asn1_str_cat (str, str_size, "."); - _asn1_str_cat (str, str_size, _asn1_ltostr (val1, temp)); - - val = 0; - leading = 1; - for (k = parsed; k < len; k++) - { - /* X.690 mandates that the leading byte must never be 0x80 - */ - if (leading != 0 && der[len_len + k] == 0x80) - return ASN1_DER_ERROR; - leading = 0; - - /* check for wrap around */ - if (INT_LEFT_SHIFT_OVERFLOW (val, 7)) - return ASN1_DER_ERROR; - - val = val << 7; - val |= der[len_len + k] & 0x7F; - - if (!(der[len_len + k] & 0x80)) - { - _asn1_str_cat (str, str_size, "."); - _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp)); - val = 0; - leading = 1; - } - } - - if (INT_ADD_OVERFLOW (len, len_len)) - return ASN1_DER_ERROR; - - *ret_len = len + len_len; - - return ASN1_SUCCESS; -} - -/** - * asn1_get_bit_der: - * @der: DER data to decode containing the BIT SEQUENCE. - * @der_len: Length of DER data to decode. - * @ret_len: Output variable containing the length of the DER data. - * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in. - * @str_size: Length of pre-allocated output buffer. - * @bit_len: Output variable containing the size of the BIT SEQUENCE. - * - * Extract a BIT SEQUENCE from DER data. - * - * Returns: %ASN1_SUCCESS on success, or an error. - **/ -int -asn1_get_bit_der (const unsigned char *der, int der_len, - int *ret_len, unsigned char *str, int str_size, - int *bit_len) -{ - int len_len = 0, len_byte; - - if (der_len <= 0) - return ASN1_GENERIC_ERROR; - - len_byte = asn1_get_length_der (der, der_len, &len_len) - 1; - if (len_byte < 0) - return ASN1_DER_ERROR; - - *ret_len = len_byte + len_len + 1; - *bit_len = len_byte * 8 - der[len_len]; - - if (*bit_len < 0) - return ASN1_DER_ERROR; - - if (str_size >= len_byte) - { - if (len_byte > 0 && str) - memcpy (str, der + len_len + 1, len_byte); - } - else - { - return ASN1_MEM_ERROR; - } - - return ASN1_SUCCESS; -} - -/* tag_len: the total tag length (explicit+inner) - * inner_tag_len: the inner_tag length - */ -static int -_asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len, - int *tag_len, int *inner_tag_len, unsigned flags) -{ - asn1_node p; - int counter, len2, len3, is_tag_implicit; - int result; - unsigned long tag, tag_implicit = 0; - unsigned char class, class2, class_implicit = 0; - - if (der_len <= 0) - return ASN1_GENERIC_ERROR; - - counter = is_tag_implicit = 0; - - if (node->type & CONST_TAG) - { - p = node->down; - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_TAG) - { - if (p->type & CONST_APPLICATION) - class2 = ASN1_CLASS_APPLICATION; - else if (p->type & CONST_UNIVERSAL) - class2 = ASN1_CLASS_UNIVERSAL; - else if (p->type & CONST_PRIVATE) - class2 = ASN1_CLASS_PRIVATE; - else - class2 = ASN1_CLASS_CONTEXT_SPECIFIC; - - if (p->type & CONST_EXPLICIT) - { - if (asn1_get_tag_der - (der + counter, der_len, &class, &len2, - &tag) != ASN1_SUCCESS) - return ASN1_DER_ERROR; - - DECR_LEN (der_len, len2); - counter += len2; - - if (flags & ASN1_DECODE_FLAG_STRICT_DER) - len3 = - asn1_get_length_der (der + counter, der_len, &len2); - else - len3 = - asn1_get_length_ber (der + counter, der_len, &len2); - if (len3 < 0) - return ASN1_DER_ERROR; - - DECR_LEN (der_len, len2); - counter += len2; - - if (!is_tag_implicit) - { - if ((class != (class2 | ASN1_CLASS_STRUCTURED)) || - (tag != strtoul ((char *) p->value, NULL, 10))) - return ASN1_TAG_ERROR; - } - else - { /* ASN1_TAG_IMPLICIT */ - if ((class != class_implicit) || (tag != tag_implicit)) - return ASN1_TAG_ERROR; - } - is_tag_implicit = 0; - } - else - { /* ASN1_TAG_IMPLICIT */ - if (!is_tag_implicit) - { - if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) || - (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF) - || (type_field (node->type) == ASN1_ETYPE_SET) - || (type_field (node->type) == ASN1_ETYPE_SET_OF)) - class2 |= ASN1_CLASS_STRUCTURED; - class_implicit = class2; - tag_implicit = strtoul ((char *) p->value, NULL, 10); - is_tag_implicit = 1; - } - } - } - p = p->right; - } - } - - if (is_tag_implicit) - { - if (asn1_get_tag_der - (der + counter, der_len, &class, &len2, &tag) != ASN1_SUCCESS) - return ASN1_DER_ERROR; - - DECR_LEN (der_len, len2); - - if ((class != class_implicit) || (tag != tag_implicit)) - { - if (type_field (node->type) == ASN1_ETYPE_OCTET_STRING) - { - class_implicit |= ASN1_CLASS_STRUCTURED; - if ((class != class_implicit) || (tag != tag_implicit)) - return ASN1_TAG_ERROR; - } - else - return ASN1_TAG_ERROR; - } - } - else - { - unsigned type = type_field (node->type); - if (type == ASN1_ETYPE_TAG) - { - *tag_len = 0; - if (inner_tag_len) - *inner_tag_len = 0; - return ASN1_SUCCESS; - } - - if (asn1_get_tag_der - (der + counter, der_len, &class, &len2, &tag) != ASN1_SUCCESS) - return ASN1_DER_ERROR; - - DECR_LEN (der_len, len2); - - switch (type) - { - case ASN1_ETYPE_NULL: - case ASN1_ETYPE_BOOLEAN: - case ASN1_ETYPE_INTEGER: - case ASN1_ETYPE_ENUMERATED: - case ASN1_ETYPE_OBJECT_ID: - case ASN1_ETYPE_GENERALSTRING: - case ASN1_ETYPE_NUMERIC_STRING: - case ASN1_ETYPE_IA5_STRING: - case ASN1_ETYPE_TELETEX_STRING: - case ASN1_ETYPE_PRINTABLE_STRING: - case ASN1_ETYPE_UNIVERSAL_STRING: - case ASN1_ETYPE_BMP_STRING: - case ASN1_ETYPE_UTF8_STRING: - case ASN1_ETYPE_VISIBLE_STRING: - case ASN1_ETYPE_BIT_STRING: - case ASN1_ETYPE_SEQUENCE: - case ASN1_ETYPE_SEQUENCE_OF: - case ASN1_ETYPE_SET: - case ASN1_ETYPE_SET_OF: - case ASN1_ETYPE_GENERALIZED_TIME: - case ASN1_ETYPE_UTC_TIME: - if ((class != _asn1_tags[type].class) - || (tag != _asn1_tags[type].tag)) - return ASN1_DER_ERROR; - break; - - case ASN1_ETYPE_OCTET_STRING: - /* OCTET STRING is handled differently to allow - * BER encodings (structured class). */ - if (((class != ASN1_CLASS_UNIVERSAL) - && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))) - || (tag != ASN1_TAG_OCTET_STRING)) - return ASN1_DER_ERROR; - break; - case ASN1_ETYPE_ANY: - counter -= len2; - break; - case ASN1_ETYPE_CHOICE: - counter -= len2; - break; - default: - return ASN1_DER_ERROR; - break; - } - } - - counter += len2; - *tag_len = counter; - if (inner_tag_len) - *inner_tag_len = len2; - return ASN1_SUCCESS; - -cleanup: - return result; -} - -static int -extract_tag_der_recursive (asn1_node node, const unsigned char *der, - int der_len, int *ret_len, int *inner_len, - unsigned flags) -{ - asn1_node p; - int ris = ASN1_DER_ERROR; - - if (type_field (node->type) == ASN1_ETYPE_CHOICE) - { - p = node->down; - while (p) - { - ris = - _asn1_extract_tag_der (p, der, der_len, ret_len, inner_len, - flags); - if (ris == ASN1_SUCCESS) - break; - p = p->right; - } - - *ret_len = 0; - return ris; - } - else - return _asn1_extract_tag_der (node, der, der_len, ret_len, inner_len, - flags); -} - -static int -_asn1_delete_not_used (asn1_node node) -{ - asn1_node p, p2; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - while (p) - { - if (p->type & CONST_NOT_USED) - { - p2 = NULL; - if (p != node) - { - p2 = _asn1_find_left (p); - if (!p2) - p2 = _asn1_find_up (p); - } - asn1_delete_structure (&p); - p = p2; - } - - if (!p) - break; /* reach node */ - - if (p->down) - { - p = p->down; - } - else - { - if (p == node) - p = NULL; - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == node) - { - p = NULL; - break; - } - if (p->right) - { - p = p->right; - break; - } - } - } - } - } - return ASN1_SUCCESS; -} - -static int -_asn1_get_indefinite_length_string (const unsigned char *der, - int der_len, int *len) -{ - int len2, len3, counter, indefinite; - int result; - unsigned long tag; - unsigned char class; - - counter = indefinite = 0; - - while (1) - { - if (HAVE_TWO (der_len) && (der[counter] == 0) - && (der[counter + 1] == 0)) - { - counter += 2; - DECR_LEN (der_len, 2); - - indefinite--; - if (indefinite <= 0) - break; - else - continue; - } - - if (asn1_get_tag_der - (der + counter, der_len, &class, &len2, &tag) != ASN1_SUCCESS) - return ASN1_DER_ERROR; - - DECR_LEN (der_len, len2); - counter += len2; - - len2 = asn1_get_length_der (der + counter, der_len, &len3); - if (len2 < -1) - return ASN1_DER_ERROR; - - if (len2 == -1) - { - indefinite++; - counter += 1; - DECR_LEN (der_len, 1); - } - else - { - counter += len2 + len3; - DECR_LEN (der_len, len2 + len3); - } - } - - *len = counter; - return ASN1_SUCCESS; - -cleanup: - return result; -} - -static void -delete_unneeded_choice_fields (asn1_node p) -{ - asn1_node p2; - - while (p->right) - { - p2 = p->right; - asn1_delete_structure (&p2); - } -} - - -/** - * asn1_der_decoding2 - * @element: pointer to an ASN1 structure. - * @ider: vector that contains the DER encoding. - * @max_ider_len: pointer to an integer giving the information about the - * maximal number of bytes occupied by *@ider. The real size of the DER - * encoding is returned through this pointer. - * @flags: flags controlling the behaviour of the function. - * @errorDescription: null-terminated string contains details when an - * error occurred. - * - * Fill the structure *@element with values of a DER encoding string. The - * structure must just be created with function asn1_create_element(). - * - * If %ASN1_DECODE_FLAG_ALLOW_PADDING flag is set then the function will ignore - * padding after the decoded DER data. Upon a successful return the value of - * *@max_ider_len will be set to the number of bytes decoded. - * - * If %ASN1_DECODE_FLAG_STRICT_DER flag is set then the function will - * not decode any BER-encoded elements. - * - * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND - * if @ELEMENT is %NULL, and %ASN1_TAG_ERROR or - * %ASN1_DER_ERROR if the der encoding doesn't match the structure - * name (*@ELEMENT deleted). - **/ -int -asn1_der_decoding2 (asn1_node * element, const void *ider, int *max_ider_len, - unsigned int flags, char *errorDescription) -{ - asn1_node node, p, p2, p3; - char temp[128]; - int counter, len2, len3, len4, move, ris, tlen; - struct node_tail_cache_st tcache = { NULL, NULL }; - unsigned char class; - unsigned long tag; - int tag_len; - int indefinite, result, total_len = *max_ider_len, ider_len = *max_ider_len; - int inner_tag_len; - unsigned char *ptmp; - const unsigned char *ptag; - const unsigned char *der = ider; - - node = *element; - - if (errorDescription != NULL) - errorDescription[0] = 0; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - if (node->type & CONST_OPTION) - { - result = ASN1_GENERIC_ERROR; - warn (); - goto cleanup; - } - - counter = 0; - move = DOWN; - p = node; - while (1) - { - tag_len = 0; - inner_tag_len = 0; - ris = ASN1_SUCCESS; - if (move != UP) - { - if (p->type & CONST_SET) - { - p2 = _asn1_find_up (p); - len2 = p2->tmp_ival; - if (len2 == -1) - { - if (HAVE_TWO (ider_len) && !der[counter] - && !der[counter + 1]) - { - p = p2; - move = UP; - counter += 2; - DECR_LEN (ider_len, 2); - continue; - } - } - else if (counter == len2) - { - p = p2; - move = UP; - continue; - } - else if (counter > len2) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - p2 = p2->down; - while (p2) - { - if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED)) - { - ris = - extract_tag_der_recursive (p2, der + counter, - ider_len, &len2, NULL, - flags); - if (ris == ASN1_SUCCESS) - { - p2->type &= ~CONST_NOT_USED; - p = p2; - break; - } - } - p2 = p2->right; - } - if (p2 == NULL) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - } - - /* the position in the DER structure this starts */ - p->start = counter; - p->end = total_len - 1; - - if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) - { - p2 = _asn1_find_up (p); - len2 = p2->tmp_ival; - if (counter == len2) - { - if (p->right) - { - p2 = p->right; - move = RIGHT; - } - else - move = UP; - - if (p->type & CONST_OPTION) - asn1_delete_structure (&p); - - p = p2; - continue; - } - } - - if (type_field (p->type) == ASN1_ETYPE_CHOICE) - { - while (p->down) - { - ris = - extract_tag_der_recursive (p->down, der + counter, - ider_len, &len2, NULL, flags); - - if (ris == ASN1_SUCCESS) - { - delete_unneeded_choice_fields (p->down); - break; - } - else if (ris == ASN1_ERROR_TYPE_ANY) - { - result = ASN1_ERROR_TYPE_ANY; - warn (); - goto cleanup; - } - else - { - p2 = p->down; - asn1_delete_structure (&p2); - } - } - - if (p->down == NULL) - { - if (!(p->type & CONST_OPTION)) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - } - else if (type_field (p->type) != ASN1_ETYPE_CHOICE) - p = p->down; - - p->start = counter; - } - - if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) - { - p2 = _asn1_find_up (p); - len2 = p2->tmp_ival; - - if ((len2 != -1) && (counter > len2)) - ris = ASN1_TAG_ERROR; - } - - if (ris == ASN1_SUCCESS) - ris = - extract_tag_der_recursive (p, der + counter, ider_len, - &tag_len, &inner_tag_len, flags); - - if (ris != ASN1_SUCCESS) - { - if (p->type & CONST_OPTION) - { - p->type |= CONST_NOT_USED; - move = RIGHT; - } - else if (p->type & CONST_DEFAULT) - { - _asn1_set_value (p, NULL, 0); - move = RIGHT; - } - else - { - if (errorDescription != NULL) - _asn1_error_description_tag_error (p, errorDescription); - - result = ASN1_TAG_ERROR; - warn (); - goto cleanup; - } - } - else - { - DECR_LEN (ider_len, tag_len); - counter += tag_len; - } - } - - if (ris == ASN1_SUCCESS) - { - switch (type_field (p->type)) - { - case ASN1_ETYPE_NULL: - DECR_LEN (ider_len, 1); - if (der[counter]) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - counter++; - move = RIGHT; - break; - case ASN1_ETYPE_BOOLEAN: - DECR_LEN (ider_len, 2); - - if (der[counter++] != 1) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - if (der[counter++] == 0) - _asn1_set_value (p, "F", 1); - else - _asn1_set_value (p, "T", 1); - move = RIGHT; - break; - case ASN1_ETYPE_INTEGER: - case ASN1_ETYPE_ENUMERATED: - len2 = asn1_get_length_der (der + counter, ider_len, &len3); - if (len2 < 0) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - - DECR_LEN (ider_len, len3 + len2); - - _asn1_set_value (p, der + counter, len3 + len2); - counter += len3 + len2; - move = RIGHT; - break; - case ASN1_ETYPE_OBJECT_ID: - result = - asn1_get_object_id_der (der + counter, ider_len, &len2, - temp, sizeof (temp)); - if (result != ASN1_SUCCESS) - { - warn (); - goto cleanup; - } - - DECR_LEN (ider_len, len2); - - tlen = strlen (temp); - if (tlen > 0) - _asn1_set_value (p, temp, tlen + 1); - - counter += len2; - move = RIGHT; - break; - case ASN1_ETYPE_GENERALIZED_TIME: - case ASN1_ETYPE_UTC_TIME: - result = - _asn1_get_time_der (type_field (p->type), der + counter, - ider_len, &len2, temp, sizeof (temp) - 1, - flags); - if (result != ASN1_SUCCESS) - { - warn (); - goto cleanup; - } - - DECR_LEN (ider_len, len2); - - tlen = strlen (temp); - if (tlen > 0) - _asn1_set_value (p, temp, tlen); - - counter += len2; - move = RIGHT; - break; - case ASN1_ETYPE_OCTET_STRING: - if (counter < inner_tag_len) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - - ptag = der + counter - inner_tag_len; - if ((flags & ASN1_DECODE_FLAG_STRICT_DER) - || !(ptag[0] & ASN1_CLASS_STRUCTURED)) - { - if (ptag[0] & ASN1_CLASS_STRUCTURED) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - - len2 = asn1_get_length_der (der + counter, ider_len, &len3); - if (len2 < 0) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - - DECR_LEN (ider_len, len3 + len2); - - _asn1_set_value (p, der + counter, len3 + len2); - counter += len3 + len2; - } - else - { - unsigned dflags = 0, vlen, ber_len; - - if (ptag[0] & ASN1_CLASS_STRUCTURED) - dflags |= DECODE_FLAG_CONSTRUCTED; - - result = - _asn1_decode_simple_ber (type_field (p->type), - der + counter, ider_len, &ptmp, - &vlen, &ber_len, dflags); - if (result != ASN1_SUCCESS) - { - warn (); - goto cleanup; - } - - DECR_LEN (ider_len, ber_len); - - _asn1_set_value_lv (p, ptmp, vlen); - - counter += ber_len; - free (ptmp); - } - move = RIGHT; - break; - case ASN1_ETYPE_GENERALSTRING: - case ASN1_ETYPE_NUMERIC_STRING: - case ASN1_ETYPE_IA5_STRING: - case ASN1_ETYPE_TELETEX_STRING: - case ASN1_ETYPE_PRINTABLE_STRING: - case ASN1_ETYPE_UNIVERSAL_STRING: - case ASN1_ETYPE_BMP_STRING: - case ASN1_ETYPE_UTF8_STRING: - case ASN1_ETYPE_VISIBLE_STRING: - case ASN1_ETYPE_BIT_STRING: - len2 = asn1_get_length_der (der + counter, ider_len, &len3); - if (len2 < 0) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - - DECR_LEN (ider_len, len3 + len2); - - _asn1_set_value (p, der + counter, len3 + len2); - counter += len3 + len2; - move = RIGHT; - break; - case ASN1_ETYPE_SEQUENCE: - case ASN1_ETYPE_SET: - if (move == UP) - { - len2 = p->tmp_ival; - p->tmp_ival = 0; - if (len2 == -1) - { /* indefinite length method */ - DECR_LEN (ider_len, 2); - if ((der[counter]) || der[counter + 1]) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - counter += 2; - } - else - { /* definite length method */ - if (len2 != counter) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - } - move = RIGHT; - } - else - { /* move==DOWN || move==RIGHT */ - len3 = asn1_get_length_der (der + counter, ider_len, &len2); - if (IS_ERR (len3, flags)) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - - DECR_LEN (ider_len, len2); - counter += len2; - - if (len3 > 0) - { - p->tmp_ival = counter + len3; - move = DOWN; - } - else if (len3 == 0) - { - p2 = p->down; - while (p2) - { - if (type_field (p2->type) != ASN1_ETYPE_TAG) - { - p3 = p2->right; - asn1_delete_structure (&p2); - p2 = p3; - } - else - p2 = p2->right; - } - move = RIGHT; - } - else - { /* indefinite length method */ - p->tmp_ival = -1; - move = DOWN; - } - } - break; - case ASN1_ETYPE_SEQUENCE_OF: - case ASN1_ETYPE_SET_OF: - if (move == UP) - { - len2 = p->tmp_ival; - if (len2 == -1) - { /* indefinite length method */ - if (!HAVE_TWO (ider_len) - || ((der[counter]) || der[counter + 1])) - { - result = _asn1_append_sequence_set (p, &tcache); - if (result != 0) - { - warn (); - goto cleanup; - } - p = tcache.tail; - move = RIGHT; - continue; - } - - p->tmp_ival = 0; - tcache.tail = NULL; /* finished decoding this structure */ - tcache.head = NULL; - DECR_LEN (ider_len, 2); - counter += 2; - } - else - { /* definite length method */ - if (len2 > counter) - { - result = _asn1_append_sequence_set (p, &tcache); - if (result != 0) - { - warn (); - goto cleanup; - } - p = tcache.tail; - move = RIGHT; - continue; - } - - p->tmp_ival = 0; - tcache.tail = NULL; /* finished decoding this structure */ - tcache.head = NULL; - - if (len2 != counter) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - } - } - else - { /* move==DOWN || move==RIGHT */ - len3 = asn1_get_length_der (der + counter, ider_len, &len2); - if (IS_ERR (len3, flags)) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - - DECR_LEN (ider_len, len2); - counter += len2; - if (len3) - { - if (len3 > 0) - { /* definite length method */ - p->tmp_ival = counter + len3; - } - else - { /* indefinite length method */ - p->tmp_ival = -1; - } - - p2 = p->down; - if (p2 == NULL) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - - while ((type_field (p2->type) == ASN1_ETYPE_TAG) - || (type_field (p2->type) == ASN1_ETYPE_SIZE)) - p2 = p2->right; - if (p2->right == NULL) - { - result = _asn1_append_sequence_set (p, &tcache); - if (result != 0) - { - warn (); - goto cleanup; - } - } - p = p2; - } - } - move = RIGHT; - break; - case ASN1_ETYPE_ANY: - /* Check indefinite lenth method in an EXPLICIT TAG */ - - if (!(flags & ASN1_DECODE_FLAG_STRICT_DER) - && (p->type & CONST_TAG) && tag_len == 2 - && (der[counter - 1] == 0x80)) - indefinite = 1; - else - indefinite = 0; - - if (asn1_get_tag_der - (der + counter, ider_len, &class, &len2, - &tag) != ASN1_SUCCESS) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - - DECR_LEN (ider_len, len2); - - len4 = - asn1_get_length_der (der + counter + len2, ider_len, &len3); - if (IS_ERR (len4, flags)) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - if (len4 != -1) /* definite */ - { - len2 += len4; - - DECR_LEN (ider_len, len4 + len3); - _asn1_set_value_lv (p, der + counter, len2 + len3); - counter += len2 + len3; - } - else /* == -1 */ - { /* indefinite length */ - ider_len += len2; /* undo DECR_LEN */ - - if (counter == 0) - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - - result = - _asn1_get_indefinite_length_string (der + counter, - ider_len, &len2); - if (result != ASN1_SUCCESS) - { - warn (); - goto cleanup; - } - - DECR_LEN (ider_len, len2); - _asn1_set_value_lv (p, der + counter, len2); - counter += len2; - - } - - /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with - an indefinite length method. */ - if (indefinite) - { - DECR_LEN (ider_len, 2); - if (!der[counter] && !der[counter + 1]) - { - counter += 2; - } - else - { - result = ASN1_DER_ERROR; - warn (); - goto cleanup; - } - } - - move = RIGHT; - break; - default: - move = (move == UP) ? RIGHT : DOWN; - break; - } - } - - if (p) - { - p->end = counter - 1; - } - - if (p == node && move != DOWN) - break; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - if ((move == RIGHT) && !(p->type & CONST_SET)) - { - if (p->right) - p = p->right; - else - move = UP; - } - if (move == UP) - p = _asn1_find_up (p); - } - - _asn1_delete_not_used (*element); - - if ((ider_len < 0) || - (!(flags & ASN1_DECODE_FLAG_ALLOW_PADDING) && (ider_len != 0))) - { - warn (); - result = ASN1_DER_ERROR; - goto cleanup; - } - - *max_ider_len = total_len - ider_len; - - return ASN1_SUCCESS; - -cleanup: - asn1_delete_structure (element); - return result; -} - - -/** - * asn1_der_decoding: - * @element: pointer to an ASN1 structure. - * @ider: vector that contains the DER encoding. - * @ider_len: number of bytes of *@ider: @ider[0]..@ider[len-1]. - * @errorDescription: null-terminated string contains details when an - * error occurred. - * - * Fill the structure *@element with values of a DER encoding - * string. The structure must just be created with function - * asn1_create_element(). - * - * Note that the *@element variable is provided as a pointer for - * historical reasons. - * - * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND - * if @ELEMENT is %NULL, and %ASN1_TAG_ERROR or - * %ASN1_DER_ERROR if the der encoding doesn't match the structure - * name (*@ELEMENT deleted). - **/ -int -asn1_der_decoding (asn1_node * element, const void *ider, int ider_len, - char *errorDescription) -{ - return asn1_der_decoding2 (element, ider, &ider_len, 0, errorDescription); -} - -/** - * asn1_der_decoding_element: - * @structure: pointer to an ASN1 structure - * @elementName: name of the element to fill - * @ider: vector that contains the DER encoding of the whole structure. - * @len: number of bytes of *der: der[0]..der[len-1] - * @errorDescription: null-terminated string contains details when an - * error occurred. - * - * Fill the element named @ELEMENTNAME with values of a DER encoding - * string. The structure must just be created with function - * asn1_create_element(). The DER vector must contain the encoding - * string of the whole @STRUCTURE. If an error occurs during the - * decoding procedure, the *@STRUCTURE is deleted and set equal to - * %NULL. - * - * This function is deprecated and may just be an alias to asn1_der_decoding - * in future versions. Use asn1_der_decoding() instead. - * - * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND - * if ELEMENT is %NULL or @elementName == NULL, and - * %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding doesn't - * match the structure @structure (*ELEMENT deleted). - **/ -int -asn1_der_decoding_element (asn1_node * structure, const char *elementName, - const void *ider, int len, char *errorDescription) -{ - return asn1_der_decoding (structure, ider, len, errorDescription); -} - -/** - * asn1_der_decoding_startEnd: - * @element: pointer to an ASN1 element - * @ider: vector that contains the DER encoding. - * @ider_len: number of bytes of *@ider: @ider[0]..@ider[len-1] - * @name_element: an element of NAME structure. - * @start: the position of the first byte of NAME_ELEMENT decoding - * (@ider[*start]) - * @end: the position of the last byte of NAME_ELEMENT decoding - * (@ider[*end]) - * - * Find the start and end point of an element in a DER encoding - * string. I mean that if you have a der encoding and you have already - * used the function asn1_der_decoding() to fill a structure, it may - * happen that you want to find the piece of string concerning an - * element of the structure. - * - * One example is the sequence "tbsCertificate" inside an X509 - * certificate. - * - * Note that since libtasn1 3.7 the @ider and @ider_len parameters - * can be omitted, if the element is already decoded using asn1_der_decoding(). - * - * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND - * if ELEMENT is %asn1_node EMPTY or @name_element is not a valid - * element, %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding - * doesn't match the structure ELEMENT. - **/ -int -asn1_der_decoding_startEnd (asn1_node element, const void *ider, int ider_len, - const char *name_element, int *start, int *end) -{ - asn1_node node, node_to_find; - int result = ASN1_DER_ERROR; - - node = element; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - node_to_find = asn1_find_node (node, name_element); - - if (node_to_find == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - *start = node_to_find->start; - *end = node_to_find->end; - - if (*start == 0 && *end == 0) - { - if (ider == NULL || ider_len == 0) - return ASN1_GENERIC_ERROR; - - /* it seems asn1_der_decoding() wasn't called before. Do it now */ - result = asn1_der_decoding (&node, ider, ider_len, NULL); - if (result != ASN1_SUCCESS) - { - warn (); - return result; - } - - node_to_find = asn1_find_node (node, name_element); - if (node_to_find == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - *start = node_to_find->start; - *end = node_to_find->end; - } - - if (*end < *start) - return ASN1_GENERIC_ERROR; - - return ASN1_SUCCESS; -} - -/** - * asn1_expand_any_defined_by: - * @definitions: ASN1 definitions - * @element: pointer to an ASN1 structure - * - * Expands every "ANY DEFINED BY" element of a structure created from - * a DER decoding process (asn1_der_decoding function). The element - * ANY must be defined by an OBJECT IDENTIFIER. The type used to - * expand the element ANY is the first one following the definition of - * the actual value of the OBJECT IDENTIFIER. - * - * Returns: %ASN1_SUCCESS if Substitution OK, %ASN1_ERROR_TYPE_ANY if - * some "ANY DEFINED BY" element couldn't be expanded due to a - * problem in OBJECT_ID -> TYPE association, or other error codes - * depending on DER decoding. - **/ -int -asn1_expand_any_defined_by (asn1_node_const definitions, asn1_node * element) -{ - char name[2 * ASN1_MAX_NAME_SIZE + 2], value[ASN1_MAX_NAME_SIZE]; - int retCode = ASN1_SUCCESS, result; - int len, len2, len3; - asn1_node_const p2; - asn1_node p, p3, aux = NULL; - char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; - const char *definitionsName; - - if ((definitions == NULL) || (*element == NULL)) - return ASN1_ELEMENT_NOT_FOUND; - - definitionsName = definitions->name; - - p = *element; - while (p) - { - - switch (type_field (p->type)) - { - case ASN1_ETYPE_ANY: - if ((p->type & CONST_DEFINED_BY) && (p->value)) - { - /* search the "DEF_BY" element */ - p2 = p->down; - while ((p2) && (type_field (p2->type) != ASN1_ETYPE_CONSTANT)) - p2 = p2->right; - - if (!p2) - { - retCode = ASN1_ERROR_TYPE_ANY; - break; - } - - p3 = _asn1_find_up (p); - - if (!p3) - { - retCode = ASN1_ERROR_TYPE_ANY; - break; - } - - p3 = p3->down; - while (p3) - { - if (!(strcmp (p3->name, p2->name))) - break; - p3 = p3->right; - } - - if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) || - (p3->value == NULL)) - { - - p3 = _asn1_find_up (p); - p3 = _asn1_find_up (p3); - - if (!p3) - { - retCode = ASN1_ERROR_TYPE_ANY; - break; - } - - p3 = p3->down; - - while (p3) - { - if (!(strcmp (p3->name, p2->name))) - break; - p3 = p3->right; - } - - if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) - || (p3->value == NULL)) - { - retCode = ASN1_ERROR_TYPE_ANY; - break; - } - } - - /* search the OBJECT_ID into definitions */ - p2 = definitions->down; - while (p2) - { - if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) && - (p2->type & CONST_ASSIGN)) - { - snprintf (name, sizeof (name), "%s.%s", definitionsName, - p2->name); - - len = ASN1_MAX_NAME_SIZE; - result = - asn1_read_value (definitions, name, value, &len); - - if ((result == ASN1_SUCCESS) - && (!_asn1_strcmp (p3->value, value))) - { - p2 = p2->right; /* pointer to the structure to - use for expansion */ - while ((p2) && (p2->type & CONST_ASSIGN)) - p2 = p2->right; - - if (p2) - { - snprintf (name, sizeof (name), "%s.%s", - definitionsName, p2->name); - - result = - asn1_create_element (definitions, name, &aux); - if (result == ASN1_SUCCESS) - { - _asn1_cpy_name (aux, p); - len2 = - asn1_get_length_der (p->value, - p->value_len, &len3); - if (len2 < 0) - return ASN1_DER_ERROR; - - result = - asn1_der_decoding (&aux, p->value + len3, - len2, - errorDescription); - if (result == ASN1_SUCCESS) - { - - _asn1_set_right (aux, p->right); - _asn1_set_right (p, aux); - - result = asn1_delete_structure (&p); - if (result == ASN1_SUCCESS) - { - p = aux; - aux = NULL; - break; - } - else - { /* error with asn1_delete_structure */ - asn1_delete_structure (&aux); - retCode = result; - break; - } - } - else - { /* error with asn1_der_decoding */ - retCode = result; - break; - } - } - else - { /* error with asn1_create_element */ - retCode = result; - break; - } - } - else - { /* error with the pointer to the structure to exapand */ - retCode = ASN1_ERROR_TYPE_ANY; - break; - } - } - } - p2 = p2->right; - } /* end while */ - - if (!p2) - { - retCode = ASN1_ERROR_TYPE_ANY; - break; - } - - } - break; - default: - break; - } - - - if (p->down) - { - p = p->down; - } - else if (p == *element) - { - p = NULL; - break; - } - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == *element) - { - p = NULL; - break; - } - if (p->right) - { - p = p->right; - break; - } - } - } - } - - return retCode; -} - -/** - * asn1_expand_octet_string: - * @definitions: ASN1 definitions - * @element: pointer to an ASN1 structure - * @octetName: name of the OCTECT STRING field to expand. - * @objectName: name of the OBJECT IDENTIFIER field to use to define - * the type for expansion. - * - * Expands an "OCTET STRING" element of a structure created from a DER - * decoding process (the asn1_der_decoding() function). The type used - * for expansion is the first one following the definition of the - * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME. - * - * Returns: %ASN1_SUCCESS if substitution OK, %ASN1_ELEMENT_NOT_FOUND - * if @objectName or @octetName are not correct, - * %ASN1_VALUE_NOT_VALID if it wasn't possible to find the type to - * use for expansion, or other errors depending on DER decoding. - **/ -int -asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element, - const char *octetName, const char *objectName) -{ - char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE]; - int retCode = ASN1_SUCCESS, result; - int len, len2, len3; - asn1_node_const p2; - asn1_node aux = NULL; - asn1_node octetNode = NULL, objectNode = NULL; - char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; - - if ((definitions == NULL) || (*element == NULL)) - return ASN1_ELEMENT_NOT_FOUND; - - octetNode = asn1_find_node (*element, octetName); - if (octetNode == NULL) - return ASN1_ELEMENT_NOT_FOUND; - if (type_field (octetNode->type) != ASN1_ETYPE_OCTET_STRING) - return ASN1_ELEMENT_NOT_FOUND; - if (octetNode->value == NULL) - return ASN1_VALUE_NOT_FOUND; - - objectNode = asn1_find_node (*element, objectName); - if (objectNode == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - if (type_field (objectNode->type) != ASN1_ETYPE_OBJECT_ID) - return ASN1_ELEMENT_NOT_FOUND; - - if (objectNode->value == NULL) - return ASN1_VALUE_NOT_FOUND; - - - /* search the OBJECT_ID into definitions */ - p2 = definitions->down; - while (p2) - { - if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) && - (p2->type & CONST_ASSIGN)) - { - strcpy (name, definitions->name); - strcat (name, "."); - strcat (name, p2->name); - - len = sizeof (value); - result = asn1_read_value (definitions, name, value, &len); - - if ((result == ASN1_SUCCESS) - && (!_asn1_strcmp (objectNode->value, value))) - { - - p2 = p2->right; /* pointer to the structure to - use for expansion */ - while ((p2) && (p2->type & CONST_ASSIGN)) - p2 = p2->right; - - if (p2) - { - strcpy (name, definitions->name); - strcat (name, "."); - strcat (name, p2->name); - - result = asn1_create_element (definitions, name, &aux); - if (result == ASN1_SUCCESS) - { - _asn1_cpy_name (aux, octetNode); - len2 = - asn1_get_length_der (octetNode->value, - octetNode->value_len, &len3); - if (len2 < 0) - return ASN1_DER_ERROR; - - result = - asn1_der_decoding (&aux, octetNode->value + len3, - len2, errorDescription); - if (result == ASN1_SUCCESS) - { - - _asn1_set_right (aux, octetNode->right); - _asn1_set_right (octetNode, aux); - - result = asn1_delete_structure (&octetNode); - if (result == ASN1_SUCCESS) - { - aux = NULL; - break; - } - else - { /* error with asn1_delete_structure */ - asn1_delete_structure (&aux); - retCode = result; - break; - } - } - else - { /* error with asn1_der_decoding */ - retCode = result; - break; - } - } - else - { /* error with asn1_create_element */ - retCode = result; - break; - } - } - else - { /* error with the pointer to the structure to exapand */ - retCode = ASN1_VALUE_NOT_VALID; - break; - } - } - } - - p2 = p2->right; - - } - - if (!p2) - retCode = ASN1_VALUE_NOT_VALID; - - return retCode; -} - -/*- - * _asn1_decode_simple_der: - * @etype: The type of the string to be encoded (ASN1_ETYPE_) - * @der: the encoded string - * @_der_len: the bytes of the encoded string - * @str: a pointer to the data - * @str_len: the length of the data - * @dflags: DECODE_FLAG_* - * - * Decodes a simple DER encoded type (e.g. a string, which is not constructed). - * The output is a pointer inside the @der. - * - * Returns: %ASN1_SUCCESS if successful or an error value. - -*/ -static int -_asn1_decode_simple_der (unsigned int etype, const unsigned char *der, - unsigned int _der_len, const unsigned char **str, - unsigned int *str_len, unsigned dflags) -{ - int tag_len, len_len; - const unsigned char *p; - int der_len = _der_len; - unsigned char class; - unsigned long tag; - long ret; - - if (der == NULL || der_len == 0) - return ASN1_VALUE_NOT_VALID; - - if (ETYPE_OK (etype) == 0 || ETYPE_IS_STRING (etype) == 0) - return ASN1_VALUE_NOT_VALID; - - /* doesn't handle constructed classes */ - class = ETYPE_CLASS (etype); - if (class != ASN1_CLASS_UNIVERSAL) - return ASN1_VALUE_NOT_VALID; - - p = der; - - if (dflags & DECODE_FLAG_HAVE_TAG) - { - ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag); - if (ret != ASN1_SUCCESS) - return ret; - - if (class != ETYPE_CLASS (etype) || tag != ETYPE_TAG (etype)) - { - warn (); - return ASN1_DER_ERROR; - } - - p += tag_len; - der_len -= tag_len; - if (der_len <= 0) - return ASN1_DER_ERROR; - } - - ret = asn1_get_length_der (p, der_len, &len_len); - if (ret < 0) - return ASN1_DER_ERROR; - - p += len_len; - der_len -= len_len; - if (der_len <= 0) - return ASN1_DER_ERROR; - - *str_len = ret; - *str = p; - - return ASN1_SUCCESS; -} - -/** - * asn1_decode_simple_der: - * @etype: The type of the string to be encoded (ASN1_ETYPE_) - * @der: the encoded string - * @_der_len: the bytes of the encoded string - * @str: a pointer to the data - * @str_len: the length of the data - * - * Decodes a simple DER encoded type (e.g. a string, which is not constructed). - * The output is a pointer inside the @der. - * - * Returns: %ASN1_SUCCESS if successful or an error value. - **/ -int -asn1_decode_simple_der (unsigned int etype, const unsigned char *der, - unsigned int _der_len, const unsigned char **str, - unsigned int *str_len) -{ - return _asn1_decode_simple_der (etype, der, _der_len, str, str_len, - DECODE_FLAG_HAVE_TAG); -} - -static int -append (uint8_t ** dst, unsigned *dst_size, const unsigned char *src, - unsigned src_size) -{ - if (src_size == 0) - return ASN1_SUCCESS; - - *dst = _asn1_realloc (*dst, *dst_size + src_size); - if (*dst == NULL) - return ASN1_MEM_ALLOC_ERROR; - memcpy (*dst + *dst_size, src, src_size); - *dst_size += src_size; - return ASN1_SUCCESS; -} - -/*- - * _asn1_decode_simple_ber: - * @etype: The type of the string to be encoded (ASN1_ETYPE_) - * @der: the encoded string - * @_der_len: the bytes of the encoded string - * @str: a pointer to the data - * @str_len: the length of the data - * @ber_len: the total length occupied by BER (may be %NULL) - * @have_tag: whether a DER tag is included - * - * Decodes a BER encoded type. The output is an allocated value - * of the data. This decodes BER STRINGS only. Other types are - * decoded as DER. - * - * Returns: %ASN1_SUCCESS if successful or an error value. - -*/ -static int -_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, - unsigned int _der_len, unsigned char **str, - unsigned int *str_len, unsigned int *ber_len, - unsigned dflags) -{ - int tag_len, len_len; - const unsigned char *p; - int der_len = _der_len; - uint8_t *total = NULL; - unsigned total_size = 0; - unsigned char class; - unsigned long tag; - unsigned char *out = NULL; - const unsigned char *cout = NULL; - unsigned out_len; - long result; - - if (ber_len) - *ber_len = 0; - - if (der == NULL || der_len == 0) - { - warn (); - return ASN1_VALUE_NOT_VALID; - } - - if (ETYPE_OK (etype) == 0) - { - warn (); - return ASN1_VALUE_NOT_VALID; - } - - /* doesn't handle constructed + definite classes */ - class = ETYPE_CLASS (etype); - if (class != ASN1_CLASS_UNIVERSAL) - { - warn (); - return ASN1_VALUE_NOT_VALID; - } - - p = der; - - if (dflags & DECODE_FLAG_HAVE_TAG) - { - result = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag); - if (result != ASN1_SUCCESS) - { - warn (); - return result; - } - - if (tag != ETYPE_TAG (etype)) - { - warn (); - return ASN1_DER_ERROR; - } - - p += tag_len; - - DECR_LEN (der_len, tag_len); - - if (ber_len) - *ber_len += tag_len; - } - - /* indefinite constructed */ - if ((((dflags & DECODE_FLAG_CONSTRUCTED) || class == ASN1_CLASS_STRUCTURED) - && ETYPE_IS_STRING (etype)) && !(dflags & DECODE_FLAG_LEVEL3)) - { - if (der_len == 0) - { - warn (); - result = ASN1_DER_ERROR; - goto cleanup; - } - - if (der_len > 0 && p[0] == 0x80) /* indefinite */ - { - len_len = 1; - DECR_LEN (der_len, len_len); - p += len_len; - - if (ber_len) - *ber_len += len_len; - - /* decode the available octet strings */ - do - { - unsigned tmp_len; - unsigned flags = DECODE_FLAG_HAVE_TAG; - - if (dflags & DECODE_FLAG_LEVEL1) - flags |= DECODE_FLAG_LEVEL2; - else if (dflags & DECODE_FLAG_LEVEL2) - flags |= DECODE_FLAG_LEVEL3; - else - flags |= DECODE_FLAG_LEVEL1; - - result = - _asn1_decode_simple_ber (etype, p, der_len, &out, &out_len, - &tmp_len, flags); - if (result != ASN1_SUCCESS) - { - warn (); - goto cleanup; - } - - p += tmp_len; - DECR_LEN (der_len, tmp_len); - - if (ber_len) - *ber_len += tmp_len; - - DECR_LEN (der_len, 2); /* we need the EOC */ - - result = append (&total, &total_size, out, out_len); - if (result != ASN1_SUCCESS) - { - warn (); - goto cleanup; - } - - free (out); - out = NULL; - - if (p[0] == 0 && p[1] == 0) /* EOC */ - { - if (ber_len) - *ber_len += 2; - break; - } - - /* no EOC */ - der_len += 2; - - if (der_len == 2) - { - warn (); - result = ASN1_DER_ERROR; - goto cleanup; - } - } - while (1); - } - else /* constructed */ - { - long const_len; - - result = asn1_get_length_ber (p, der_len, &len_len); - if (result < 0) - { - warn (); - result = ASN1_DER_ERROR; - goto cleanup; - } - - DECR_LEN (der_len, len_len); - p += len_len; - - const_len = result; - - if (ber_len) - *ber_len += len_len; - - /* decode the available octet strings */ - while (const_len > 0) - { - unsigned tmp_len; - unsigned flags = DECODE_FLAG_HAVE_TAG; - - if (dflags & DECODE_FLAG_LEVEL1) - flags |= DECODE_FLAG_LEVEL2; - else if (dflags & DECODE_FLAG_LEVEL2) - flags |= DECODE_FLAG_LEVEL3; - else - flags |= DECODE_FLAG_LEVEL1; - - result = - _asn1_decode_simple_ber (etype, p, der_len, &out, &out_len, - &tmp_len, flags); - if (result != ASN1_SUCCESS) - { - warn (); - goto cleanup; - } - - p += tmp_len; - DECR_LEN (der_len, tmp_len); - DECR_LEN (const_len, tmp_len); - - if (ber_len) - *ber_len += tmp_len; - - result = append (&total, &total_size, out, out_len); - if (result != ASN1_SUCCESS) - { - warn (); - goto cleanup; - } - - free (out); - out = NULL; - } - } - } - else if (class == ETYPE_CLASS (etype)) - { - if (ber_len) - { - result = asn1_get_length_der (p, der_len, &len_len); - if (result < 0) - { - warn (); - result = ASN1_DER_ERROR; - goto cleanup; - } - *ber_len += result + len_len; - } - - /* non-string values are decoded as DER */ - result = - _asn1_decode_simple_der (etype, der, _der_len, &cout, &out_len, - dflags); - if (result != ASN1_SUCCESS) - { - warn (); - goto cleanup; - } - - result = append (&total, &total_size, cout, out_len); - if (result != ASN1_SUCCESS) - { - warn (); - goto cleanup; - } - } - else - { - warn (); - result = ASN1_DER_ERROR; - goto cleanup; - } - - *str = total; - *str_len = total_size; - - return ASN1_SUCCESS; -cleanup: - free (out); - free (total); - return result; -} - -/** - * asn1_decode_simple_ber: - * @etype: The type of the string to be encoded (ASN1_ETYPE_) - * @der: the encoded string - * @_der_len: the bytes of the encoded string - * @str: a pointer to the data - * @str_len: the length of the data - * @ber_len: the total length occupied by BER (may be %NULL) - * - * Decodes a BER encoded type. The output is an allocated value - * of the data. This decodes BER STRINGS only. Other types are - * decoded as DER. - * - * Returns: %ASN1_SUCCESS if successful or an error value. - **/ -int -asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, - unsigned int _der_len, unsigned char **str, - unsigned int *str_len, unsigned int *ber_len) -{ - return _asn1_decode_simple_ber (etype, der, _der_len, str, str_len, ber_len, - DECODE_FLAG_HAVE_TAG); -} diff --git a/grub-core/lib/libtasn1/lib/element.c b/grub-core/lib/libtasn1/lib/element.c deleted file mode 100644 index d4c558e10..000000000 --- a/grub-core/lib/libtasn1/lib/element.c +++ /dev/null @@ -1,1109 +0,0 @@ -/* - * Copyright (C) 2000-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 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 - */ - -/*****************************************************/ -/* File: element.c */ -/* Description: Functions with the read and write */ -/* functions. */ -/*****************************************************/ - - -#include -#include "parser_aux.h" -#include -#include "structure.h" -#include "c-ctype.h" -#include "element.h" - -void -_asn1_hierarchical_name (asn1_node_const node, char *name, int name_size) -{ - asn1_node_const p; - char tmp_name[64]; - - p = node; - - name[0] = 0; - - while (p != NULL) - { - if (p->name[0] != 0) - { - _asn1_str_cpy (tmp_name, sizeof (tmp_name), name), - _asn1_str_cpy (name, name_size, p->name); - _asn1_str_cat (name, name_size, "."); - _asn1_str_cat (name, name_size, tmp_name); - } - p = _asn1_find_up (p); - } - - if (name[0] == 0) - _asn1_str_cpy (name, name_size, "ROOT"); -} - - -/******************************************************************/ -/* Function : _asn1_convert_integer */ -/* Description: converts an integer from a null terminated string */ -/* to der decoding. The convertion from a null */ -/* terminated string to an integer is made with */ -/* the 'strtol' function. */ -/* Parameters: */ -/* value: null terminated string to convert. */ -/* value_out: convertion result (memory must be already */ -/* allocated). */ -/* value_out_size: number of bytes of value_out. */ -/* len: number of significant byte of value_out. */ -/* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */ -/******************************************************************/ -int -_asn1_convert_integer (const unsigned char *value, unsigned char *value_out, - int value_out_size, int *len) -{ - char negative; - unsigned char val[SIZEOF_UNSIGNED_LONG_INT]; - long valtmp; - int k, k2; - - valtmp = _asn1_strtol (value, NULL, 10); - - for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) - { - val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF; - } - - if (val[0] & 0x80) - negative = 1; - else - negative = 0; - - for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++) - { - if (negative && (val[k] != 0xFF)) - break; - else if (!negative && val[k]) - break; - } - - if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80))) - k--; - - *len = SIZEOF_UNSIGNED_LONG_INT - k; - - if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size) - /* VALUE_OUT is too short to contain the value conversion */ - return ASN1_MEM_ERROR; - - if (value_out != NULL) - { - for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++) - value_out[k2 - k] = val[k2]; - } - -#if 0 - printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len); - for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) - printf (", vOut[%d]=%d", k, value_out[k]); - printf ("\n"); -#endif - - return ASN1_SUCCESS; -} - -/* Appends a new element into the sequence (or set) defined by this - * node. The new element will have a name of '?number', where number - * is a monotonically increased serial number. - * - * The last element in the list may be provided in @pcache, to avoid - * traversing the list, an expensive operation in long lists. - * - * On success it returns in @pcache the added element (which is the - * tail in the list of added elements). - */ -int -_asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcache) -{ - asn1_node p, p2; - char temp[LTOSTR_MAX_SIZE + 1]; - long n; - - if (!node || !(node->down)) - return ASN1_GENERIC_ERROR; - - p = node->down; - while ((type_field (p->type) == ASN1_ETYPE_TAG) - || (type_field (p->type) == ASN1_ETYPE_SIZE)) - p = p->right; - - p2 = _asn1_copy_structure3 (p); - if (p2 == NULL) - return ASN1_GENERIC_ERROR; - - if (pcache == NULL || pcache->tail == NULL || pcache->head != node) - { - while (p->right) - { - p = p->right; - } - } - else - { - p = pcache->tail; - } - - _asn1_set_right (p, p2); - if (pcache) - { - pcache->head = node; - pcache->tail = p2; - } - - if (p->name[0] == 0) - _asn1_str_cpy (temp, sizeof (temp), "?1"); - else - { - n = strtol (p->name + 1, NULL, 0); - n++; - temp[0] = '?'; - _asn1_ltostr (n, temp + 1); - } - _asn1_set_name (p2, temp); - /* p2->type |= CONST_OPTION; */ - - return ASN1_SUCCESS; -} - - -/** - * asn1_write_value: - * @node_root: pointer to a structure - * @name: the name of the element inside the structure that you want to set. - * @ivalue: vector used to specify the value to set. If len is >0, - * VALUE must be a two's complement form integer. if len=0 *VALUE - * must be a null terminated string with an integer value. - * @len: number of bytes of *value to use to set the value: - * value[0]..value[len-1] or 0 if value is a null terminated string - * - * Set the value of one element inside a structure. - * - * If an element is OPTIONAL and you want to delete it, you must use - * the value=NULL and len=0. Using "pkix.asn": - * - * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID", - * NULL, 0); - * - * Description for each type: - * - * INTEGER: VALUE must contain a two's complement form integer. - * - * value[0]=0xFF , len=1 -> integer=-1. - * value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1. - * value[0]=0x01 , len=1 -> integer= 1. - * value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1. - * value="123" , len=0 -> integer= 123. - * - * ENUMERATED: As INTEGER (but only with not negative numbers). - * - * BOOLEAN: VALUE must be the null terminated string "TRUE" or - * "FALSE" and LEN != 0. - * - * value="TRUE" , len=1 -> boolean=TRUE. - * value="FALSE" , len=1 -> boolean=FALSE. - * - * OBJECT IDENTIFIER: VALUE must be a null terminated string with - * each number separated by a dot (e.g. "1.2.3.543.1"). LEN != 0. - * - * value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha. - * - * UTCTime: VALUE must be a null terminated string in one of these - * formats: "YYMMDDhhmmssZ", "YYMMDDhhmmssZ", - * "YYMMDDhhmmss+hh'mm'", "YYMMDDhhmmss-hh'mm'", - * "YYMMDDhhmm+hh'mm'", or "YYMMDDhhmm-hh'mm'". LEN != 0. - * - * value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998 - * at 12h 00m Greenwich Mean Time - * - * GeneralizedTime: VALUE must be in one of this format: - * "YYYYMMDDhhmmss.sZ", "YYYYMMDDhhmmss.sZ", - * "YYYYMMDDhhmmss.s+hh'mm'", "YYYYMMDDhhmmss.s-hh'mm'", - * "YYYYMMDDhhmm+hh'mm'", or "YYYYMMDDhhmm-hh'mm'" where ss.s - * indicates the seconds with any precision like "10.1" or "01.02". - * LEN != 0 - * - * value="2001010112001.12-0700" , len=1 -> time=Jannuary - * 1st, 2001 at 12h 00m 01.12s Pacific Daylight Time - * - * OCTET STRING: VALUE contains the octet string and LEN is the - * number of octets. - * - * value="$\backslash$x01$\backslash$x02$\backslash$x03" , - * len=3 -> three bytes octet string - * - * GeneralString: VALUE contains the generalstring and LEN is the - * number of octets. - * - * value="$\backslash$x01$\backslash$x02$\backslash$x03" , - * len=3 -> three bytes generalstring - * - * BIT STRING: VALUE contains the bit string organized by bytes and - * LEN is the number of bits. - * - * value="$\backslash$xCF" , len=6 -> bit string="110011" (six - * bits) - * - * CHOICE: if NAME indicates a choice type, VALUE must specify one of - * the alternatives with a null terminated string. LEN != 0. Using - * "pkix.asn"\: - * - * result=asn1_write_value(cert, - * "certificate1.tbsCertificate.subject", "rdnSequence", - * 1); - * - * ANY: VALUE indicates the der encoding of a structure. LEN != 0. - * - * SEQUENCE OF: VALUE must be the null terminated string "NEW" and - * LEN != 0. With this instruction another element is appended in - * the sequence. The name of this element will be "?1" if it's the - * first one, "?2" for the second and so on. - * - * Using "pkix.asn"\: - * - * result=asn1_write_value(cert, - * "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1); - * - * SET OF: the same as SEQUENCE OF. Using "pkix.asn": - * - * result=asn1_write_value(cert, - * "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1); - * - * Returns: %ASN1_SUCCESS if the value was set, - * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, and - * %ASN1_VALUE_NOT_VALID if @ivalue has a wrong format. - **/ -int -asn1_write_value (asn1_node node_root, const char *name, - const void *ivalue, int len) -{ - asn1_node node, p, p2; - unsigned char *temp, *value_temp = NULL, *default_temp = NULL; - int len2, k, k2, negative; - size_t i; - const unsigned char *value = ivalue; - unsigned int type; - - node = asn1_find_node (node_root, name); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0)) - { - asn1_delete_structure (&node); - return ASN1_SUCCESS; - } - - type = type_field (node->type); - - if ((type == ASN1_ETYPE_SEQUENCE_OF || type == ASN1_ETYPE_SET_OF) - && (value == NULL) && (len == 0)) - { - p = node->down; - while ((type_field (p->type) == ASN1_ETYPE_TAG) - || (type_field (p->type) == ASN1_ETYPE_SIZE)) - p = p->right; - - while (p->right) - asn1_delete_structure (&p->right); - - return ASN1_SUCCESS; - } - - /* Don't allow element deletion for other types */ - if (value == NULL) - { - return ASN1_VALUE_NOT_VALID; - } - - switch (type) - { - case ASN1_ETYPE_BOOLEAN: - if (!_asn1_strcmp (value, "TRUE")) - { - if (node->type & CONST_DEFAULT) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if (p->type & CONST_TRUE) - _asn1_set_value (node, NULL, 0); - else - _asn1_set_value (node, "T", 1); - } - else - _asn1_set_value (node, "T", 1); - } - else if (!_asn1_strcmp (value, "FALSE")) - { - if (node->type & CONST_DEFAULT) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if (p->type & CONST_FALSE) - _asn1_set_value (node, NULL, 0); - else - _asn1_set_value (node, "F", 1); - } - else - _asn1_set_value (node, "F", 1); - } - else - return ASN1_VALUE_NOT_VALID; - break; - case ASN1_ETYPE_INTEGER: - case ASN1_ETYPE_ENUMERATED: - if (len == 0) - { - if ((c_isdigit (value[0])) || (value[0] == '-')) - { - value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); - if (value_temp == NULL) - return ASN1_MEM_ALLOC_ERROR; - - _asn1_convert_integer (value, value_temp, - SIZEOF_UNSIGNED_LONG_INT, &len); - } - else - { /* is an identifier like v1 */ - if (!(node->type & CONST_LIST)) - return ASN1_VALUE_NOT_VALID; - p = node->down; - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_CONSTANT) - { - if (!_asn1_strcmp (p->name, value)) - { - value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); - if (value_temp == NULL) - return ASN1_MEM_ALLOC_ERROR; - - _asn1_convert_integer (p->value, - value_temp, - SIZEOF_UNSIGNED_LONG_INT, - &len); - break; - } - } - p = p->right; - } - if (p == NULL) - return ASN1_VALUE_NOT_VALID; - } - } - else - { /* len != 0 */ - value_temp = malloc (len); - if (value_temp == NULL) - return ASN1_MEM_ALLOC_ERROR; - memcpy (value_temp, value, len); - } - - if (value_temp[0] & 0x80) - negative = 1; - else - negative = 0; - - if (negative && (type_field (node->type) == ASN1_ETYPE_ENUMERATED)) - { - free (value_temp); - return ASN1_VALUE_NOT_VALID; - } - - for (k = 0; k < len - 1; k++) - if (negative && (value_temp[k] != 0xFF)) - break; - else if (!negative && value_temp[k]) - break; - - if ((negative && !(value_temp[k] & 0x80)) || - (!negative && (value_temp[k] & 0x80))) - k--; - - _asn1_set_value_lv (node, value_temp + k, len - k); - - if (node->type & CONST_DEFAULT) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if ((c_isdigit (p->value[0])) || (p->value[0] == '-')) - { - default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); - if (default_temp == NULL) - { - free (value_temp); - return ASN1_MEM_ALLOC_ERROR; - } - - _asn1_convert_integer (p->value, default_temp, - SIZEOF_UNSIGNED_LONG_INT, &len2); - } - else - { /* is an identifier like v1 */ - if (!(node->type & CONST_LIST)) - { - free (value_temp); - return ASN1_VALUE_NOT_VALID; - } - p2 = node->down; - while (p2) - { - if (type_field (p2->type) == ASN1_ETYPE_CONSTANT) - { - if (!_asn1_strcmp (p2->name, p->value)) - { - default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); - if (default_temp == NULL) - { - free (value_temp); - return ASN1_MEM_ALLOC_ERROR; - } - - _asn1_convert_integer (p2->value, - default_temp, - SIZEOF_UNSIGNED_LONG_INT, - &len2); - break; - } - } - p2 = p2->right; - } - if (p2 == NULL) - { - free (value_temp); - return ASN1_VALUE_NOT_VALID; - } - } - - - if ((len - k) == len2) - { - for (k2 = 0; k2 < len2; k2++) - if (value_temp[k + k2] != default_temp[k2]) - { - break; - } - if (k2 == len2) - _asn1_set_value (node, NULL, 0); - } - free (default_temp); - } - free (value_temp); - break; - case ASN1_ETYPE_OBJECT_ID: - for (i = 0; i < _asn1_strlen (value); i++) - if ((!c_isdigit (value[i])) && (value[i] != '.') && (value[i] != '+')) - return ASN1_VALUE_NOT_VALID; - if (node->type & CONST_DEFAULT) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if (!_asn1_strcmp (value, p->value)) - { - _asn1_set_value (node, NULL, 0); - break; - } - } - _asn1_set_value (node, value, _asn1_strlen (value) + 1); - break; - case ASN1_ETYPE_UTC_TIME: - { - len = _asn1_strlen (value); - if (len < 11) - return ASN1_VALUE_NOT_VALID; - for (k = 0; k < 10; k++) - if (!c_isdigit (value[k])) - return ASN1_VALUE_NOT_VALID; - switch (len) - { - case 11: - if (value[10] != 'Z') - return ASN1_VALUE_NOT_VALID; - break; - case 13: - if ((!c_isdigit (value[10])) || (!c_isdigit (value[11])) || - (value[12] != 'Z')) - return ASN1_VALUE_NOT_VALID; - break; - case 15: - if ((value[10] != '+') && (value[10] != '-')) - return ASN1_VALUE_NOT_VALID; - for (k = 11; k < 15; k++) - if (!c_isdigit (value[k])) - return ASN1_VALUE_NOT_VALID; - break; - case 17: - if ((!c_isdigit (value[10])) || (!c_isdigit (value[11]))) - return ASN1_VALUE_NOT_VALID; - if ((value[12] != '+') && (value[12] != '-')) - return ASN1_VALUE_NOT_VALID; - for (k = 13; k < 17; k++) - if (!c_isdigit (value[k])) - return ASN1_VALUE_NOT_VALID; - break; - default: - return ASN1_VALUE_NOT_FOUND; - } - _asn1_set_value (node, value, len); - } - break; - case ASN1_ETYPE_GENERALIZED_TIME: - len = _asn1_strlen (value); - _asn1_set_value (node, value, len); - break; - case ASN1_ETYPE_OCTET_STRING: - case ASN1_ETYPE_GENERALSTRING: - case ASN1_ETYPE_NUMERIC_STRING: - case ASN1_ETYPE_IA5_STRING: - case ASN1_ETYPE_TELETEX_STRING: - case ASN1_ETYPE_PRINTABLE_STRING: - case ASN1_ETYPE_UNIVERSAL_STRING: - case ASN1_ETYPE_BMP_STRING: - case ASN1_ETYPE_UTF8_STRING: - case ASN1_ETYPE_VISIBLE_STRING: - if (len == 0) - len = _asn1_strlen (value); - _asn1_set_value_lv (node, value, len); - break; - case ASN1_ETYPE_BIT_STRING: - if (len == 0) - len = _asn1_strlen (value); - asn1_length_der ((len >> 3) + 2, NULL, &len2); - temp = malloc ((len >> 3) + 2 + len2); - if (temp == NULL) - return ASN1_MEM_ALLOC_ERROR; - - asn1_bit_der (value, len, temp, &len2); - _asn1_set_value_m (node, temp, len2); - temp = NULL; - break; - case ASN1_ETYPE_CHOICE: - p = node->down; - while (p) - { - if (!_asn1_strcmp (p->name, value)) - { - p2 = node->down; - while (p2) - { - if (p2 != p) - { - asn1_delete_structure (&p2); - p2 = node->down; - } - else - p2 = p2->right; - } - break; - } - p = p->right; - } - if (!p) - return ASN1_ELEMENT_NOT_FOUND; - break; - case ASN1_ETYPE_ANY: - _asn1_set_value_lv (node, value, len); - break; - case ASN1_ETYPE_SEQUENCE_OF: - case ASN1_ETYPE_SET_OF: - if (_asn1_strcmp (value, "NEW")) - return ASN1_VALUE_NOT_VALID; - _asn1_append_sequence_set (node, NULL); - break; - default: - return ASN1_ELEMENT_NOT_FOUND; - break; - } - - return ASN1_SUCCESS; -} - - -#define PUT_VALUE( ptr, ptr_size, data, data_size) \ - *len = data_size; \ - if (ptr_size < data_size) { \ - return ASN1_MEM_ERROR; \ - } else { \ - if (ptr && data_size > 0) \ - memcpy (ptr, data, data_size); \ - } - -#define PUT_STR_VALUE( ptr, ptr_size, data) \ - *len = _asn1_strlen (data) + 1; \ - if (ptr_size < *len) { \ - return ASN1_MEM_ERROR; \ - } else { \ - /* this strcpy is checked */ \ - if (ptr) { \ - _asn1_strcpy (ptr, data); \ - } \ - } - -#define PUT_AS_STR_VALUE( ptr, ptr_size, data, data_size) \ - *len = data_size + 1; \ - if (ptr_size < *len) { \ - return ASN1_MEM_ERROR; \ - } else { \ - /* this strcpy is checked */ \ - if (ptr) { \ - if (data_size > 0) \ - memcpy (ptr, data, data_size); \ - ptr[data_size] = 0; \ - } \ - } - -#define ADD_STR_VALUE( ptr, ptr_size, data) \ - *len += _asn1_strlen(data); \ - if (ptr_size < (int) *len) { \ - (*len)++; \ - return ASN1_MEM_ERROR; \ - } else { \ - /* this strcat is checked */ \ - if (ptr) _asn1_strcat (ptr, data); \ - } - -/** - * asn1_read_value: - * @root: pointer to a structure. - * @name: the name of the element inside a structure that you want to read. - * @ivalue: vector that will contain the element's content, must be a - * pointer to memory cells already allocated (may be %NULL). - * @len: number of bytes of *value: value[0]..value[len-1]. Initialy - * holds the sizeof value. - * - * Returns the value of one element inside a structure. - * If an element is OPTIONAL and this returns - * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present - * in the der encoding that created the structure. The first element - * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and - * so on. If the @root provided is a node to specific sequence element, - * then the keyword "?CURRENT" is also acceptable and indicates the - * current sequence element of this node. - * - * Note that there can be valid values with length zero. In these case - * this function will succeed and @len will be zero. - * - * INTEGER: VALUE will contain a two's complement form integer. - * - * integer=-1 -> value[0]=0xFF , len=1. - * integer=1 -> value[0]=0x01 , len=1. - * - * ENUMERATED: As INTEGER (but only with not negative numbers). - * - * BOOLEAN: VALUE will be the null terminated string "TRUE" or - * "FALSE" and LEN=5 or LEN=6. - * - * OBJECT IDENTIFIER: VALUE will be a null terminated string with - * each number separated by a dot (i.e. "1.2.3.543.1"). - * - * LEN = strlen(VALUE)+1 - * - * UTCTime: VALUE will be a null terminated string in one of these - * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'". - * LEN=strlen(VALUE)+1. - * - * GeneralizedTime: VALUE will be a null terminated string in the - * same format used to set the value. - * - * OCTET STRING: VALUE will contain the octet string and LEN will be - * the number of octets. - * - * GeneralString: VALUE will contain the generalstring and LEN will - * be the number of octets. - * - * BIT STRING: VALUE will contain the bit string organized by bytes - * and LEN will be the number of bits. - * - * CHOICE: If NAME indicates a choice type, VALUE will specify the - * alternative selected. - * - * ANY: If NAME indicates an any type, VALUE will indicate the DER - * encoding of the structure actually used. - * - * Returns: %ASN1_SUCCESS if value is returned, - * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, - * %ASN1_VALUE_NOT_FOUND if there isn't any value for the element - * selected, and %ASN1_MEM_ERROR if The value vector isn't big enough - * to store the result, and in this case @len will contain the number of - * bytes needed. On the occasion that the stored data are of zero-length - * this function may return %ASN1_SUCCESS even if the provided @len is zero. - **/ -int -asn1_read_value (asn1_node_const root, const char *name, void *ivalue, - int *len) -{ - return asn1_read_value_type (root, name, ivalue, len, NULL); -} - -/** - * asn1_read_value_type: - * @root: pointer to a structure. - * @name: the name of the element inside a structure that you want to read. - * @ivalue: vector that will contain the element's content, must be a - * pointer to memory cells already allocated (may be %NULL). - * @len: number of bytes of *value: value[0]..value[len-1]. Initialy - * holds the sizeof value. - * @etype: The type of the value read (ASN1_ETYPE) - * - * Returns the type and value of one element inside a structure. - * If an element is OPTIONAL and this returns - * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present - * in the der encoding that created the structure. The first element - * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and - * so on. If the @root provided is a node to specific sequence element, - * then the keyword "?CURRENT" is also acceptable and indicates the - * current sequence element of this node. - * - * Note that there can be valid values with length zero. In these case - * this function will succeed and @len will be zero. - * - * - * INTEGER: VALUE will contain a two's complement form integer. - * - * integer=-1 -> value[0]=0xFF , len=1. - * integer=1 -> value[0]=0x01 , len=1. - * - * ENUMERATED: As INTEGER (but only with not negative numbers). - * - * BOOLEAN: VALUE will be the null terminated string "TRUE" or - * "FALSE" and LEN=5 or LEN=6. - * - * OBJECT IDENTIFIER: VALUE will be a null terminated string with - * each number separated by a dot (i.e. "1.2.3.543.1"). - * - * LEN = strlen(VALUE)+1 - * - * UTCTime: VALUE will be a null terminated string in one of these - * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'". - * LEN=strlen(VALUE)+1. - * - * GeneralizedTime: VALUE will be a null terminated string in the - * same format used to set the value. - * - * OCTET STRING: VALUE will contain the octet string and LEN will be - * the number of octets. - * - * GeneralString: VALUE will contain the generalstring and LEN will - * be the number of octets. - * - * BIT STRING: VALUE will contain the bit string organized by bytes - * and LEN will be the number of bits. - * - * CHOICE: If NAME indicates a choice type, VALUE will specify the - * alternative selected. - * - * ANY: If NAME indicates an any type, VALUE will indicate the DER - * encoding of the structure actually used. - * - * Returns: %ASN1_SUCCESS if value is returned, - * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, - * %ASN1_VALUE_NOT_FOUND if there isn't any value for the element - * selected, and %ASN1_MEM_ERROR if The value vector isn't big enough - * to store the result, and in this case @len will contain the number of - * bytes needed. On the occasion that the stored data are of zero-length - * this function may return %ASN1_SUCCESS even if the provided @len is zero. - **/ -int -asn1_read_value_type (asn1_node_const root, const char *name, void *ivalue, - int *len, unsigned int *etype) -{ - asn1_node_const node, p, p2; - int len2, len3, result; - int value_size = *len; - unsigned char *value = ivalue; - unsigned type; - - node = asn1_find_node (root, name); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - type = type_field (node->type); - - if ((type != ASN1_ETYPE_NULL) && - (type != ASN1_ETYPE_CHOICE) && - !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) && - (node->value == NULL)) - return ASN1_VALUE_NOT_FOUND; - - if (etype) - *etype = type; - switch (type) - { - case ASN1_ETYPE_NULL: - PUT_STR_VALUE (value, value_size, "NULL"); - break; - case ASN1_ETYPE_BOOLEAN: - if ((node->type & CONST_DEFAULT) && (node->value == NULL)) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if (p->type & CONST_TRUE) - { - PUT_STR_VALUE (value, value_size, "TRUE"); - } - else - { - PUT_STR_VALUE (value, value_size, "FALSE"); - } - } - else if (node->value[0] == 'T') - { - PUT_STR_VALUE (value, value_size, "TRUE"); - } - else - { - PUT_STR_VALUE (value, value_size, "FALSE"); - } - break; - case ASN1_ETYPE_INTEGER: - case ASN1_ETYPE_ENUMERATED: - if ((node->type & CONST_DEFAULT) && (node->value == NULL)) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if ((c_isdigit (p->value[0])) || (p->value[0] == '-') - || (p->value[0] == '+')) - { - result = _asn1_convert_integer - (p->value, value, value_size, len); - if (result != ASN1_SUCCESS) - return result; - } - else - { /* is an identifier like v1 */ - p2 = node->down; - while (p2) - { - if (type_field (p2->type) == ASN1_ETYPE_CONSTANT) - { - if (!_asn1_strcmp (p2->name, p->value)) - { - result = _asn1_convert_integer - (p2->value, value, value_size, len); - if (result != ASN1_SUCCESS) - return result; - break; - } - } - p2 = p2->right; - } - } - } - else - { - len2 = -1; - result = asn1_get_octet_der - (node->value, node->value_len, &len2, value, value_size, len); - if (result != ASN1_SUCCESS) - return result; - } - break; - case ASN1_ETYPE_OBJECT_ID: - if (node->type & CONST_ASSIGN) - { - *len = 0; - if (value) - value[0] = 0; - p = node->down; - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_CONSTANT) - { - ADD_STR_VALUE (value, value_size, p->value); - if (p->right) - { - ADD_STR_VALUE (value, value_size, "."); - } - } - p = p->right; - } - (*len)++; - } - else if ((node->type & CONST_DEFAULT) && (node->value == NULL)) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - PUT_STR_VALUE (value, value_size, p->value); - } - else - { - PUT_STR_VALUE (value, value_size, node->value); - } - break; - case ASN1_ETYPE_GENERALIZED_TIME: - case ASN1_ETYPE_UTC_TIME: - PUT_AS_STR_VALUE (value, value_size, node->value, node->value_len); - break; - case ASN1_ETYPE_OCTET_STRING: - case ASN1_ETYPE_GENERALSTRING: - case ASN1_ETYPE_NUMERIC_STRING: - case ASN1_ETYPE_IA5_STRING: - case ASN1_ETYPE_TELETEX_STRING: - case ASN1_ETYPE_PRINTABLE_STRING: - case ASN1_ETYPE_UNIVERSAL_STRING: - case ASN1_ETYPE_BMP_STRING: - case ASN1_ETYPE_UTF8_STRING: - case ASN1_ETYPE_VISIBLE_STRING: - len2 = -1; - result = asn1_get_octet_der - (node->value, node->value_len, &len2, value, value_size, len); - if (result != ASN1_SUCCESS) - return result; - break; - case ASN1_ETYPE_BIT_STRING: - len2 = -1; - result = asn1_get_bit_der - (node->value, node->value_len, &len2, value, value_size, len); - if (result != ASN1_SUCCESS) - return result; - break; - case ASN1_ETYPE_CHOICE: - PUT_STR_VALUE (value, value_size, node->down->name); - break; - case ASN1_ETYPE_ANY: - len3 = -1; - len2 = asn1_get_length_der (node->value, node->value_len, &len3); - if (len2 < 0) - return ASN1_DER_ERROR; - PUT_VALUE (value, value_size, node->value + len3, len2); - break; - default: - return ASN1_ELEMENT_NOT_FOUND; - break; - } - return ASN1_SUCCESS; -} - - -/** - * asn1_read_tag: - * @root: pointer to a structure - * @name: the name of the element inside a structure. - * @tagValue: variable that will contain the TAG value. - * @classValue: variable that will specify the TAG type. - * - * Returns the TAG and the CLASS of one element inside a structure. - * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION, - * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or - * %ASN1_CLASS_CONTEXT_SPECIFIC. - * - * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if - * @name is not a valid element. - **/ -int -asn1_read_tag (asn1_node_const root, const char *name, int *tagValue, - int *classValue) -{ - asn1_node node, p, pTag; - - node = asn1_find_node (root, name); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node->down; - - /* pTag will points to the IMPLICIT TAG */ - pTag = NULL; - if (node->type & CONST_TAG) - { - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_TAG) - { - if ((p->type & CONST_IMPLICIT) && (pTag == NULL)) - pTag = p; - else if (p->type & CONST_EXPLICIT) - pTag = NULL; - } - p = p->right; - } - } - - if (pTag) - { - *tagValue = _asn1_strtoul (pTag->value, NULL, 10); - - if (pTag->type & CONST_APPLICATION) - *classValue = ASN1_CLASS_APPLICATION; - else if (pTag->type & CONST_UNIVERSAL) - *classValue = ASN1_CLASS_UNIVERSAL; - else if (pTag->type & CONST_PRIVATE) - *classValue = ASN1_CLASS_PRIVATE; - else - *classValue = ASN1_CLASS_CONTEXT_SPECIFIC; - } - else - { - unsigned type = type_field (node->type); - *classValue = ASN1_CLASS_UNIVERSAL; - - switch (type) - { - CASE_HANDLED_ETYPES: - *tagValue = _asn1_tags[type].tag; - break; - case ASN1_ETYPE_TAG: - case ASN1_ETYPE_CHOICE: - case ASN1_ETYPE_ANY: - *tagValue = -1; - break; - default: - break; - } - } - - return ASN1_SUCCESS; -} - -/** - * asn1_read_node_value: - * @node: pointer to a node. - * @data: a point to a asn1_data_node_st - * - * Returns the value a data node inside a asn1_node structure. - * The data returned should be handled as constant values. - * - * Returns: %ASN1_SUCCESS if the node exists. - **/ -int -asn1_read_node_value (asn1_node_const node, asn1_data_node_st * data) -{ - data->name = node->name; - data->value = node->value; - data->value_len = node->value_len; - data->type = type_field (node->type); - - return ASN1_SUCCESS; -} diff --git a/grub-core/lib/libtasn1/lib/element.h b/grub-core/lib/libtasn1/lib/element.h deleted file mode 100644 index 8dd0ceba8..000000000 --- a/grub-core/lib/libtasn1/lib/element.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2000-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 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 _ELEMENT_H -# define _ELEMENT_H - - -struct node_tail_cache_st -{ - asn1_node head; /* the first element of the sequence */ - asn1_node tail; -}; - -int _asn1_append_sequence_set (asn1_node node, - struct node_tail_cache_st *pcached); - -int _asn1_convert_integer (const unsigned char *value, - unsigned char *value_out, - int value_out_size, int *len); - -void _asn1_hierarchical_name (asn1_node_const node, char *name, - int name_size); - -#endif diff --git a/grub-core/lib/libtasn1/lib/errors.c b/grub-core/lib/libtasn1/lib/errors.c deleted file mode 100644 index aef5dfe6f..000000000 --- a/grub-core/lib/libtasn1/lib/errors.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2002-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 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 - */ - -#include -#ifdef STDC_HEADERS -# include -#endif - -#define LIBTASN1_ERROR_ENTRY(name) { #name, name } - -struct libtasn1_error_entry -{ - const char *name; - int number; -}; -typedef struct libtasn1_error_entry libtasn1_error_entry; - -static const libtasn1_error_entry error_algorithms[] = { - LIBTASN1_ERROR_ENTRY (ASN1_SUCCESS), - LIBTASN1_ERROR_ENTRY (ASN1_FILE_NOT_FOUND), - LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_FOUND), - LIBTASN1_ERROR_ENTRY (ASN1_IDENTIFIER_NOT_FOUND), - LIBTASN1_ERROR_ENTRY (ASN1_DER_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_FOUND), - LIBTASN1_ERROR_ENTRY (ASN1_GENERIC_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_VALID), - LIBTASN1_ERROR_ENTRY (ASN1_TAG_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_TAG_IMPLICIT), - LIBTASN1_ERROR_ENTRY (ASN1_ERROR_TYPE_ANY), - LIBTASN1_ERROR_ENTRY (ASN1_SYNTAX_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_MEM_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_MEM_ALLOC_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_DER_OVERFLOW), - LIBTASN1_ERROR_ENTRY (ASN1_NAME_TOO_LONG), - LIBTASN1_ERROR_ENTRY (ASN1_ARRAY_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_EMPTY), - LIBTASN1_ERROR_ENTRY (ASN1_TIME_ENCODING_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_RECURSION), - {0, 0} -}; - -/** - * asn1_perror: - * @error: is an error returned by a libtasn1 function. - * - * Prints a string to stderr with a description of an error. This - * function is like perror(). The only difference is that it accepts - * an error returned by a libtasn1 function. - * - * Since: 1.6 - **/ -void -asn1_perror (int error) -{ - const char *str = asn1_strerror (error); - fprintf (stderr, "LIBTASN1 ERROR: %s\n", str ? str : "(null)"); -} - -/** - * asn1_strerror: - * @error: is an error returned by a libtasn1 function. - * - * Returns a string with a description of an error. This function is - * similar to strerror. The only difference is that it accepts an - * error (number) returned by a libtasn1 function. - * - * Returns: Pointer to static zero-terminated string describing error - * code. - * - * Since: 1.6 - **/ -const char * -asn1_strerror (int error) -{ - const libtasn1_error_entry *p; - - for (p = error_algorithms; p->name != NULL; p++) - if (p->number == error) - return p->name + sizeof ("ASN1_") - 1; - - return NULL; -} diff --git a/grub-core/lib/libtasn1/lib/gstr.c b/grub-core/lib/libtasn1/lib/gstr.c deleted file mode 100644 index eef419554..000000000 --- a/grub-core/lib/libtasn1/lib/gstr.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2002-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 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 - */ - -#include -#include "gstr.h" - -/* These function are like strcat, strcpy. They only - * do bounds checking (they shouldn't cause buffer overruns), - * and they always produce null terminated strings. - * - * They should be used only with null terminated strings. - */ -void -_asn1_str_cat (char *dest, size_t dest_tot_size, const char *src) -{ - size_t str_size = strlen (src); - size_t dest_size = strlen (dest); - - if (dest_tot_size - dest_size > str_size) - { - strcat (dest, src); - } - else - { - if (dest_tot_size > dest_size) - { - strncat (dest, src, (dest_tot_size - dest_size) - 1); - dest[dest_tot_size - 1] = 0; - } - } -} - -/* Returns the bytes copied (not including the null terminator) */ -unsigned int -_asn1_str_cpy (char *dest, size_t dest_tot_size, const char *src) -{ - size_t str_size = strlen (src); - - if (dest_tot_size > str_size) - { - strcpy (dest, src); - return str_size; - } - else - { - if (dest_tot_size > 0) - { - str_size = dest_tot_size - 1; - memcpy (dest, src, str_size); - dest[str_size] = 0; - return str_size; - } - else - return 0; - } -} diff --git a/grub-core/lib/libtasn1/lib/gstr.h b/grub-core/lib/libtasn1/lib/gstr.h deleted file mode 100644 index 99be6c4af..000000000 --- a/grub-core/lib/libtasn1/lib/gstr.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2002-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 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 GSTR_H -# define GSTR_H - -unsigned int _asn1_str_cpy (char *dest, size_t dest_tot_size, - const char *src); -void _asn1_str_cat (char *dest, size_t dest_tot_size, const char *src); - -# define Estrcpy(x,y) _asn1_str_cpy(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y) -# define Estrcat(x,y) _asn1_str_cat(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y) - -inline static void -safe_memset (void *data, int c, size_t size) -{ - volatile unsigned volatile_zero = 0; - volatile char *vdata = (volatile char *) data; - - /* This is based on a nice trick for safe memset, - * sent by David Jacobson in the openssl-dev mailing list. - */ - - if (size > 0) - do - { - memset (data, c, size); - } - while (vdata[volatile_zero] != c); -} - -#endif /* GSTR_H */ diff --git a/grub-core/lib/libtasn1/lib/int.h b/grub-core/lib/libtasn1/lib/int.h deleted file mode 100644 index d94d51c8c..000000000 --- a/grub-core/lib/libtasn1/lib/int.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2002-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 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 INT_H -# define INT_H - -# ifdef HAVE_CONFIG_H -# include -# endif - -# include -# include -# include -# include - -# ifdef HAVE_SYS_TYPES_H -# include -# endif - -# include - -# define ASN1_SMALL_VALUE_SIZE 16 - -/* This structure is also in libtasn1.h, but then contains less - fields. You cannot make any modifications to these first fields - without breaking ABI. */ -struct asn1_node_st -{ - /* public fields: */ - char name[ASN1_MAX_NAME_SIZE + 1]; /* Node name */ - unsigned int name_hash; - unsigned int type; /* Node type */ - unsigned char *value; /* Node value */ - int value_len; - asn1_node down; /* Pointer to the son node */ - asn1_node right; /* Pointer to the brother node */ - asn1_node left; /* Pointer to the next list element */ - /* private fields: */ - unsigned char small_value[ASN1_SMALL_VALUE_SIZE]; /* For small values */ - - /* values used during decoding/coding */ - int tmp_ival; - unsigned start; /* the start of the DER sequence - if decoded */ - unsigned end; /* the end of the DER sequence - if decoded */ -}; - -typedef struct tag_and_class_st -{ - unsigned tag; - unsigned class; - const char *desc; -} tag_and_class_st; - -/* the types that are handled in _asn1_tags */ -# define CASE_HANDLED_ETYPES \ - case ASN1_ETYPE_NULL: \ - case ASN1_ETYPE_BOOLEAN: \ - case ASN1_ETYPE_INTEGER: \ - case ASN1_ETYPE_ENUMERATED: \ - case ASN1_ETYPE_OBJECT_ID: \ - case ASN1_ETYPE_OCTET_STRING: \ - case ASN1_ETYPE_GENERALSTRING: \ - case ASN1_ETYPE_NUMERIC_STRING: \ - case ASN1_ETYPE_IA5_STRING: \ - case ASN1_ETYPE_TELETEX_STRING: \ - case ASN1_ETYPE_PRINTABLE_STRING: \ - case ASN1_ETYPE_UNIVERSAL_STRING: \ - case ASN1_ETYPE_BMP_STRING: \ - case ASN1_ETYPE_UTF8_STRING: \ - case ASN1_ETYPE_VISIBLE_STRING: \ - case ASN1_ETYPE_BIT_STRING: \ - case ASN1_ETYPE_SEQUENCE: \ - case ASN1_ETYPE_SEQUENCE_OF: \ - case ASN1_ETYPE_SET: \ - case ASN1_ETYPE_UTC_TIME: \ - case ASN1_ETYPE_GENERALIZED_TIME: \ - case ASN1_ETYPE_SET_OF - -# define ETYPE_TAG(etype) (_asn1_tags[etype].tag) -# define ETYPE_CLASS(etype) (_asn1_tags[etype].class) -# define ETYPE_OK(etype) (((etype) != ASN1_ETYPE_INVALID && \ - (etype) < _asn1_tags_size && \ - _asn1_tags[(etype)].desc != NULL)?1:0) - -# define ETYPE_IS_STRING(etype) ((etype == ASN1_ETYPE_GENERALSTRING || \ - etype == ASN1_ETYPE_NUMERIC_STRING || etype == ASN1_ETYPE_IA5_STRING || \ - etype == ASN1_ETYPE_TELETEX_STRING || etype == ASN1_ETYPE_PRINTABLE_STRING || \ - etype == ASN1_ETYPE_UNIVERSAL_STRING || etype == ASN1_ETYPE_BMP_STRING || \ - etype == ASN1_ETYPE_UTF8_STRING || etype == ASN1_ETYPE_VISIBLE_STRING || \ - etype == ASN1_ETYPE_OCTET_STRING)?1:0) - -extern unsigned int _asn1_tags_size; -extern const tag_and_class_st _asn1_tags[]; - -# define _asn1_strlen(s) strlen((const char *) s) -# define _asn1_strtol(n,e,b) strtol((const char *) n, e, b) -# define _asn1_strtoul(n,e,b) strtoul((const char *) n, e, b) -# define _asn1_strcmp(a,b) strcmp((const char *)a, (const char *)b) -# define _asn1_strcpy(a,b) strcpy((char *)a, (const char *)b) -# define _asn1_strcat(a,b) strcat((char *)a, (const char *)b) - -# if SIZEOF_UNSIGNED_LONG_INT == 8 -# define _asn1_strtou64(n,e,b) strtoul((const char *) n, e, b) -# else -# define _asn1_strtou64(n,e,b) strtoull((const char *) n, e, b) -# endif - -# define MAX_LOG_SIZE 1024 /* maximum number of characters of a log message */ - -/* Define used for visiting trees. */ -# define UP 1 -# define RIGHT 2 -# define DOWN 3 - -/***********************************************************************/ -/* List of constants to better specify the type of typedef asn1_node_st. */ -/***********************************************************************/ -/* Used with TYPE_TAG */ -# define CONST_UNIVERSAL (1U<<8) -# define CONST_PRIVATE (1U<<9) -# define CONST_APPLICATION (1U<<10) -# define CONST_EXPLICIT (1U<<11) -# define CONST_IMPLICIT (1U<<12) - -# define CONST_TAG (1U<<13) /* Used in ASN.1 assignement */ -# define CONST_OPTION (1U<<14) -# define CONST_DEFAULT (1U<<15) -# define CONST_TRUE (1U<<16) -# define CONST_FALSE (1U<<17) - -# define CONST_LIST (1U<<18) /* Used with TYPE_INTEGER and TYPE_BIT_STRING */ -# define CONST_MIN_MAX (1U<<19) - -# define CONST_1_PARAM (1U<<20) - -# define CONST_SIZE (1U<<21) - -# define CONST_DEFINED_BY (1U<<22) - -/* Those two are deprecated and used for backwards compatibility */ -# define CONST_GENERALIZED (1U<<23) -# define CONST_UTC (1U<<24) - -/* #define CONST_IMPORTS (1U<<25) */ - -# define CONST_NOT_USED (1U<<26) -# define CONST_SET (1U<<27) -# define CONST_ASSIGN (1U<<28) - -# define CONST_DOWN (1U<<29) -# define CONST_RIGHT (1U<<30) - - -# define ASN1_ETYPE_TIME 17 -/****************************************/ -/* Returns the first 8 bits. */ -/* Used with the field type of asn1_node_st */ -/****************************************/ -inline static unsigned int -type_field (unsigned int ntype) -{ - return (ntype & 0xff); -} - -/* To convert old types from a static structure */ -inline static unsigned int -convert_old_type (unsigned int ntype) -{ - unsigned int type = ntype & 0xff; - if (type == ASN1_ETYPE_TIME) - { - if (ntype & CONST_UTC) - type = ASN1_ETYPE_UTC_TIME; - else - type = ASN1_ETYPE_GENERALIZED_TIME; - - ntype &= ~(CONST_UTC | CONST_GENERALIZED); - ntype &= 0xffffff00; - ntype |= type; - - return ntype; - } - else - return ntype; -} - -static inline void * -_asn1_realloc (void *ptr, size_t size) -{ - void *ret; - - if (size == 0) - return ptr; - - ret = realloc (ptr, size); - if (ret == NULL) - { - free (ptr); - } - return ret; -} - -#endif /* INT_H */ diff --git a/grub-core/lib/libtasn1/lib/parser_aux.c b/grub-core/lib/libtasn1/lib/parser_aux.c deleted file mode 100644 index c05bd2339..000000000 --- a/grub-core/lib/libtasn1/lib/parser_aux.c +++ /dev/null @@ -1,1178 +0,0 @@ -/* - * Copyright (C) 2000-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 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 - */ - -#include /* WORD_BIT */ - -#include "int.h" -#include "parser_aux.h" -#include "gstr.h" -#include "structure.h" -#include "element.h" -#include "c-ctype.h" - -char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not found */ - -/* Return a hash of the N bytes of X using the method described by - Bruno Haible in https://www.haible.de/bruno/hashfunc.html. - Note that while many hash functions reduce their result via modulo - to a 0..table_size-1 range, this function does not do that. - - This implementation has been changed from size_t -> unsigned int. */ - -#ifdef __clang__ -__attribute__((no_sanitize ("integer"))) -#endif - _GL_ATTRIBUTE_PURE static unsigned int _asn1_hash_name (const char *x) -{ - const unsigned char *s = (unsigned char *) x; - unsigned h = 0; - - while (*s) - h = (*s++) + ((h << 9) | (h >> (WORD_BIT - 9))); - - return h; -} - -/******************************************************/ -/* Function : _asn1_add_static_node */ -/* Description: creates a new NODE_ASN element and */ -/* puts it in the list pointed by e_list. */ -/* Parameters: */ -/* e_list: of type list_type; must be NULL initially */ -/* type: type of the new element (see ASN1_ETYPE_ */ -/* and CONST_ constants). */ -/* Return: pointer to the new element. */ -/******************************************************/ -asn1_node -_asn1_add_static_node (list_type ** e_list, unsigned int type) -{ - list_type *p; - asn1_node punt; - - punt = calloc (1, sizeof (struct asn1_node_st)); - if (punt == NULL) - return NULL; - - p = malloc (sizeof (list_type)); - if (p == NULL) - { - free (punt); - return NULL; - } - - p->node = punt; - p->next = *e_list; - *e_list = p; - - punt->type = type; - - return punt; -} - -static int -_asn1_add_static_node2 (list_type ** e_list, asn1_node node) -{ - list_type *p; - - p = malloc (sizeof (list_type)); - if (p == NULL) - { - return -1; - } - - p->node = node; - p->next = *e_list; - *e_list = p; - - return 0; -} - -/** - * asn1_find_node: - * @pointer: NODE_ASN element pointer. - * @name: null terminated string with the element's name to find. - * - * Searches for an element called @name starting from @pointer. The - * name is composed by different identifiers separated by dots. When - * *@pointer has a name, the first identifier must be the name of - * *@pointer, otherwise it must be the name of one child of *@pointer. - * - * Returns: the search result, or %NULL if not found. - **/ -asn1_node -asn1_find_node (asn1_node_const pointer, const char *name) -{ - asn1_node_const p; - char *n_end, n[ASN1_MAX_NAME_SIZE + 1]; - const char *n_start; - unsigned int nsize; - unsigned int nhash; - - if (pointer == NULL) - return NULL; - - if (name == NULL) - return NULL; - - p = pointer; - n_start = name; - - if (name[0] == '?' && name[1] == 'C' && p->name[0] == '?') - { /* ?CURRENT */ - n_start = strchr (n_start, '.'); - if (n_start) - n_start++; - } - else if (p->name[0] != 0) - { /* has *pointer got a name ? */ - n_end = strchr (n_start, '.'); /* search the first dot */ - if (n_end) - { - nsize = n_end - n_start; - if (nsize >= sizeof (n)) - return NULL; - - memcpy (n, n_start, nsize); - n[nsize] = 0; - n_start = n_end; - n_start++; - - nhash = _asn1_hash_name (n); - } - else - { - _asn1_str_cpy (n, sizeof (n), n_start); - nhash = _asn1_hash_name (n); - - n_start = NULL; - } - - while (p) - { - if (nhash == p->name_hash && (!strcmp (p->name, n))) - break; - else - p = p->right; - } /* while */ - - if (p == NULL) - return NULL; - } - else - { /* *pointer doesn't have a name */ - if (n_start[0] == 0) - return (asn1_node) p; - } - - while (n_start) - { /* Has the end of NAME been reached? */ - n_end = strchr (n_start, '.'); /* search the next dot */ - if (n_end) - { - nsize = n_end - n_start; - if (nsize >= sizeof (n)) - return NULL; - - memcpy (n, n_start, nsize); - n[nsize] = 0; - n_start = n_end; - n_start++; - - nhash = _asn1_hash_name (n); - } - else - { - _asn1_str_cpy (n, sizeof (n), n_start); - nhash = _asn1_hash_name (n); - n_start = NULL; - } - - if (p->down == NULL) - return NULL; - - p = p->down; - if (p == NULL) - return NULL; - - /* The identifier "?LAST" indicates the last element - in the right chain. */ - if (n[0] == '?' && n[1] == 'L') /* ?LAST */ - { - while (p->right) - p = p->right; - } - else - { /* no "?LAST" */ - while (p) - { - if (p->name_hash == nhash && !strcmp (p->name, n)) - break; - else - p = p->right; - } - } - if (p == NULL) - return NULL; - } /* while */ - - return (asn1_node) p; -} - - -/******************************************************************/ -/* Function : _asn1_set_value */ -/* Description: sets the field VALUE in a NODE_ASN element. The */ -/* previous value (if exist) will be lost */ -/* Parameters: */ -/* node: element pointer. */ -/* value: pointer to the value that you want to set. */ -/* len: character number of value. */ -/* Return: pointer to the NODE_ASN element. */ -/******************************************************************/ -asn1_node -_asn1_set_value (asn1_node node, const void *value, unsigned int len) -{ - if (node == NULL) - return node; - if (node->value) - { - if (node->value != node->small_value) - free (node->value); - node->value = NULL; - node->value_len = 0; - } - - if (!len) - return node; - - if (len < sizeof (node->small_value)) - { - node->value = node->small_value; - } - else - { - node->value = malloc (len); - if (node->value == NULL) - return NULL; - } - node->value_len = len; - - memcpy (node->value, value, len); - return node; -} - -/******************************************************************/ -/* Function : _asn1_set_value_lv */ -/* Description: sets the field VALUE in a NODE_ASN element. The */ -/* previous value (if exist) will be lost. The value */ -/* given is stored as an length-value format (LV */ -/* Parameters: */ -/* node: element pointer. */ -/* value: pointer to the value that you want to set. */ -/* len: character number of value. */ -/* Return: pointer to the NODE_ASN element. */ -/******************************************************************/ -asn1_node -_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len) -{ - int len2; - void *temp; - - if (node == NULL) - return node; - - asn1_length_der (len, NULL, &len2); - temp = malloc (len + len2); - if (temp == NULL) - return NULL; - - asn1_octet_der (value, len, temp, &len2); - return _asn1_set_value_m (node, temp, len2); -} - -/* the same as _asn1_set_value except that it sets an already malloc'ed - * value. - */ -asn1_node -_asn1_set_value_m (asn1_node node, void *value, unsigned int len) -{ - if (node == NULL) - return node; - - if (node->value) - { - if (node->value != node->small_value) - free (node->value); - node->value = NULL; - node->value_len = 0; - } - - if (!len) - return node; - - node->value = value; - node->value_len = len; - - return node; -} - -/******************************************************************/ -/* Function : _asn1_append_value */ -/* Description: appends to the field VALUE in a NODE_ASN element. */ -/* */ -/* Parameters: */ -/* node: element pointer. */ -/* value: pointer to the value that you want to be appended. */ -/* len: character number of value. */ -/* Return: pointer to the NODE_ASN element. */ -/******************************************************************/ -asn1_node -_asn1_append_value (asn1_node node, const void *value, unsigned int len) -{ - if (node == NULL) - return node; - - if (node->value == NULL) - return _asn1_set_value (node, value, len); - - if (len == 0) - return node; - - if (node->value == node->small_value) - { - /* value is in node */ - int prev_len = node->value_len; - node->value_len += len; - node->value = malloc (node->value_len); - if (node->value == NULL) - { - node->value_len = 0; - return NULL; - } - - if (prev_len > 0) - memcpy (node->value, node->small_value, prev_len); - - memcpy (&node->value[prev_len], value, len); - - return node; - } - else /* if (node->value != NULL && node->value != node->small_value) */ - { - /* value is allocated */ - int prev_len = node->value_len; - node->value_len += len; - - node->value = _asn1_realloc (node->value, node->value_len); - if (node->value == NULL) - { - node->value_len = 0; - return NULL; - } - - memcpy (&node->value[prev_len], value, len); - - return node; - } -} - -/******************************************************************/ -/* Function : _asn1_set_name */ -/* Description: sets the field NAME in a NODE_ASN element. The */ -/* previous value (if exist) will be lost */ -/* Parameters: */ -/* node: element pointer. */ -/* name: a null terminated string with the name that you want */ -/* to set. */ -/* Return: pointer to the NODE_ASN element. */ -/******************************************************************/ -asn1_node -_asn1_set_name (asn1_node node, const char *name) -{ - if (node == NULL) - return node; - - _asn1_str_cpy (node->name, sizeof (node->name), name ? name : ""); - node->name_hash = _asn1_hash_name (node->name); - - return node; -} - -/******************************************************************/ -/* Function : _asn1_cpy_name */ -/* Description: copies the field NAME in a NODE_ASN element. */ -/* Parameters: */ -/* dst: a dest element pointer. */ -/* src: a source element pointer. */ -/* Return: pointer to the NODE_ASN element. */ -/******************************************************************/ -asn1_node -_asn1_cpy_name (asn1_node dst, asn1_node_const src) -{ - if (dst == NULL) - return dst; - - if (src == NULL) - { - dst->name[0] = 0; - dst->name_hash = _asn1_hash_name (dst->name); - return dst; - } - - _asn1_str_cpy (dst->name, sizeof (dst->name), src->name); - dst->name_hash = src->name_hash; - - return dst; -} - -/******************************************************************/ -/* Function : _asn1_set_right */ -/* Description: sets the field RIGHT in a NODE_ASN element. */ -/* Parameters: */ -/* node: element pointer. */ -/* right: pointer to a NODE_ASN element that you want be pointed*/ -/* by NODE. */ -/* Return: pointer to *NODE. */ -/******************************************************************/ -asn1_node -_asn1_set_right (asn1_node node, asn1_node right) -{ - if (node == NULL) - return node; - node->right = right; - if (right) - right->left = node; - return node; -} - - -/******************************************************************/ -/* Function : _asn1_get_last_right */ -/* Description: return the last element along the right chain. */ -/* Parameters: */ -/* node: starting element pointer. */ -/* Return: pointer to the last element along the right chain. */ -/******************************************************************/ -asn1_node -_asn1_get_last_right (asn1_node_const node) -{ - asn1_node_const p; - - if (node == NULL) - return NULL; - p = node; - while (p->right) - p = p->right; - return (asn1_node) p; -} - -/******************************************************************/ -/* Function : _asn1_remove_node */ -/* Description: gets free the memory allocated for an NODE_ASN */ -/* element (not the elements pointed by it). */ -/* Parameters: */ -/* node: NODE_ASN element pointer. */ -/* flags: ASN1_DELETE_FLAG_* */ -/******************************************************************/ -void -_asn1_remove_node (asn1_node node, unsigned int flags) -{ - if (node == NULL) - return; - - if (node->value != NULL) - { - if (flags & ASN1_DELETE_FLAG_ZEROIZE) - { - safe_memset (node->value, 0, node->value_len); - } - - if (node->value != node->small_value) - free (node->value); - } - free (node); -} - -/******************************************************************/ -/* Function : _asn1_find_up */ -/* Description: return the father of the NODE_ASN element. */ -/* Parameters: */ -/* node: NODE_ASN element pointer. */ -/* Return: Null if not found. */ -/******************************************************************/ -asn1_node -_asn1_find_up (asn1_node_const node) -{ - asn1_node_const p; - - if (node == NULL) - return NULL; - - p = node; - - while ((p->left != NULL) && (p->left->right == p)) - p = p->left; - - return p->left; -} - -static unsigned -_asn1_is_up (asn1_node_const up_cand, asn1_node_const down) -{ - asn1_node_const d, u; - - if (up_cand == NULL || down == NULL) - return 0; - - d = down; - - while ((u = _asn1_find_up (d)) != NULL && u != d) - { - if (u == up_cand) - return 1; - d = u; - } - - return 0; -} - -/******************************************************************/ -/* Function : _asn1_delete_node_from_list */ -/* Description: deletes the list element given */ -/******************************************************************/ -void -_asn1_delete_node_from_list (list_type * list, asn1_node node) -{ - list_type *p = list; - - while (p) - { - if (p->node == node) - p->node = NULL; - p = p->next; - } -} - -/******************************************************************/ -/* Function : _asn1_delete_list */ -/* Description: deletes the list elements (not the elements */ -/* pointed by them). */ -/******************************************************************/ -void -_asn1_delete_list (list_type * e_list) -{ - list_type *p; - - while (e_list) - { - p = e_list; - e_list = e_list->next; - free (p); - } -} - -/******************************************************************/ -/* Function : _asn1_delete_list_and nodes */ -/* Description: deletes the list elements and the elements */ -/* pointed by them. */ -/******************************************************************/ -void -_asn1_delete_list_and_nodes (list_type * e_list) -{ - list_type *p; - - while (e_list) - { - p = e_list; - e_list = e_list->next; - _asn1_remove_node (p->node, 0); - free (p); - } -} - - -char * -_asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE]) -{ - uint64_t d, r; - char temp[LTOSTR_MAX_SIZE]; - int count, k, start; - uint64_t val; - - if (v < 0) - { - str[0] = '-'; - start = 1; - val = -((uint64_t) v); - } - else - { - val = v; - start = 0; - } - - count = 0; - do - { - d = val / 10; - r = val - d * 10; - temp[start + count] = '0' + (char) r; - count++; - val = d; - } - while (val && ((start + count) < LTOSTR_MAX_SIZE - 1)); - - for (k = 0; k < count; k++) - str[k + start] = temp[start + count - k - 1]; - str[count + start] = 0; - return str; -} - - -/******************************************************************/ -/* Function : _asn1_change_integer_value */ -/* Description: converts into DER coding the value assign to an */ -/* INTEGER constant. */ -/* Parameters: */ -/* node: root of an ASN1element. */ -/* Return: */ -/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ -/* otherwise ASN1_SUCCESS */ -/******************************************************************/ -int -_asn1_change_integer_value (asn1_node node) -{ - asn1_node p; - unsigned char val[SIZEOF_UNSIGNED_LONG_INT]; - unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1]; - int len; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - while (p) - { - if ((type_field (p->type) == ASN1_ETYPE_INTEGER) - && (p->type & CONST_ASSIGN)) - { - if (p->value) - { - _asn1_convert_integer (p->value, val, sizeof (val), &len); - asn1_octet_der (val, len, val2, &len); - _asn1_set_value (p, val2, len); - } - } - - if (p->down) - { - p = p->down; - } - else - { - if (p == node) - p = NULL; - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == node) - { - p = NULL; - break; - } - if (p && p->right) - { - p = p->right; - break; - } - } - } - } - } - - return ASN1_SUCCESS; -} - -#define MAX_CONSTANTS 1024 -/******************************************************************/ -/* Function : _asn1_expand_object_id */ -/* Description: expand the IDs of an OBJECT IDENTIFIER constant. */ -/* Parameters: */ -/* list: root of an object list */ -/* node: root of an ASN1 element. */ -/* Return: */ -/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ -/* otherwise ASN1_SUCCESS */ -/******************************************************************/ -int -_asn1_expand_object_id (list_type ** list, asn1_node node) -{ - asn1_node p, p2, p3, p4, p5; - char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1]; - int move, tlen, tries; - unsigned max_constants; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - _asn1_str_cpy (name_root, sizeof (name_root), node->name); - - p = node; - move = DOWN; - tries = 0; - - while (!((p == node) && (move == UP))) - { - if (move != UP) - { - if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) - && (p->type & CONST_ASSIGN)) - { - p2 = p->down; - if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT)) - { - if (p2->value && !c_isdigit (p2->value[0])) - { - _asn1_str_cpy (name2, sizeof (name2), name_root); - _asn1_str_cat (name2, sizeof (name2), "."); - _asn1_str_cat (name2, sizeof (name2), - (char *) p2->value); - p3 = asn1_find_node (node, name2); - if (!p3 || _asn1_is_up (p2, p3) || - (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) || - !(p3->type & CONST_ASSIGN)) - return ASN1_ELEMENT_NOT_FOUND; - - _asn1_set_down (p, p2->right); - if (p2->down) - _asn1_delete_structure (*list, &p2->down, 0); - _asn1_delete_node_from_list (*list, p2); - _asn1_remove_node (p2, 0); - p2 = p; - p4 = p3->down; - max_constants = 0; - while (p4) - { - if (type_field (p4->type) == ASN1_ETYPE_CONSTANT) - { - max_constants++; - if (max_constants == MAX_CONSTANTS) - return ASN1_RECURSION; - - p5 = - _asn1_add_single_node (ASN1_ETYPE_CONSTANT); - _asn1_set_name (p5, p4->name); - if (p4->value) - { - tlen = _asn1_strlen (p4->value); - if (tlen > 0) - _asn1_set_value (p5, p4->value, tlen + 1); - } - _asn1_add_static_node2 (list, p5); - - if (p2 == p) - { - _asn1_set_right (p5, p->down); - _asn1_set_down (p, p5); - } - else - { - _asn1_set_right (p5, p2->right); - _asn1_set_right (p2, p5); - } - p2 = p5; - } - p4 = p4->right; - } - move = DOWN; - - tries++; - if (tries >= EXPAND_OBJECT_ID_MAX_RECURSION) - return ASN1_RECURSION; - - continue; - } - } - } - move = DOWN; - } - else - move = RIGHT; - - tries = 0; - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - - if (p == node) - { - move = UP; - continue; - } - - if (move == RIGHT) - { - if (p && p->right) - p = p->right; - else - move = UP; - } - if (move == UP) - p = _asn1_find_up (p); - } - - /*******************************/ - /* expand DEFAULT */ - /*******************************/ - p = node; - move = DOWN; - - while (!((p == node) && (move == UP))) - { - if (move != UP) - { - if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && - (p->type & CONST_DEFAULT)) - { - p2 = p->down; - if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT)) - { - _asn1_str_cpy (name2, sizeof (name2), name_root); - _asn1_str_cat (name2, sizeof (name2), "."); - if (p2->value) - _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); - p3 = asn1_find_node (node, name2); - if (!p3 || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) - || !(p3->type & CONST_ASSIGN)) - return ASN1_ELEMENT_NOT_FOUND; - p4 = p3->down; - name2[0] = 0; - while (p4) - { - if (type_field (p4->type) == ASN1_ETYPE_CONSTANT) - { - if (p4->value == NULL) - return ASN1_VALUE_NOT_FOUND; - - if (name2[0]) - _asn1_str_cat (name2, sizeof (name2), "."); - _asn1_str_cat (name2, sizeof (name2), - (char *) p4->value); - } - p4 = p4->right; - } - tlen = strlen (name2); - if (tlen > 0) - _asn1_set_value (p2, name2, tlen + 1); - } - } - move = DOWN; - } - else - move = RIGHT; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - - if (p == node) - { - move = UP; - continue; - } - - if (move == RIGHT) - { - if (p && p->right) - p = p->right; - else - move = UP; - } - if (move == UP) - p = _asn1_find_up (p); - } - - return ASN1_SUCCESS; -} - - -/******************************************************************/ -/* Function : _asn1_type_set_config */ -/* Description: sets the CONST_SET and CONST_NOT_USED properties */ -/* in the fields of the SET elements. */ -/* Parameters: */ -/* node: root of an ASN1 element. */ -/* Return: */ -/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ -/* otherwise ASN1_SUCCESS */ -/******************************************************************/ -int -_asn1_type_set_config (asn1_node node) -{ - asn1_node p, p2; - int move; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - move = DOWN; - - while (!((p == node) && (move == UP))) - { - if (move != UP) - { - if (type_field (p->type) == ASN1_ETYPE_SET) - { - p2 = p->down; - while (p2) - { - if (type_field (p2->type) != ASN1_ETYPE_TAG) - p2->type |= CONST_SET | CONST_NOT_USED; - p2 = p2->right; - } - } - move = DOWN; - } - else - move = RIGHT; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - - if (p == node) - { - move = UP; - continue; - } - - if (move == RIGHT) - { - if (p && p->right) - p = p->right; - else - move = UP; - } - if (move == UP) - p = _asn1_find_up (p); - } - - return ASN1_SUCCESS; -} - - -/******************************************************************/ -/* Function : _asn1_check_identifier */ -/* Description: checks the definitions of all the identifiers */ -/* and the first element of an OBJECT_ID (e.g. {pkix 0 4}). */ -/* The _asn1_identifierMissing global variable is filled if */ -/* necessary. */ -/* Parameters: */ -/* node: root of an ASN1 element. */ -/* Return: */ -/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ -/* ASN1_IDENTIFIER_NOT_FOUND if an identifier is not defined, */ -/* otherwise ASN1_SUCCESS */ -/******************************************************************/ -int -_asn1_check_identifier (asn1_node_const node) -{ - asn1_node_const p, p2; - char name2[ASN1_MAX_NAME_SIZE * 2 + 2]; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - while (p) - { - if (p->value && type_field (p->type) == ASN1_ETYPE_IDENTIFIER) - { - _asn1_str_cpy (name2, sizeof (name2), node->name); - _asn1_str_cat (name2, sizeof (name2), "."); - _asn1_str_cat (name2, sizeof (name2), (char *) p->value); - p2 = asn1_find_node (node, name2); - if (p2 == NULL) - { - if (p->value) - _asn1_str_cpy (_asn1_identifierMissing, - sizeof (_asn1_identifierMissing), - (char *) p->value); - else - _asn1_strcpy (_asn1_identifierMissing, "(null)"); - return ASN1_IDENTIFIER_NOT_FOUND; - } - } - else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && - (p->type & CONST_DEFAULT)) - { - p2 = p->down; - if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT)) - { - _asn1_str_cpy (name2, sizeof (name2), node->name); - if (p2->value) - { - _asn1_str_cat (name2, sizeof (name2), "."); - _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); - _asn1_str_cpy (_asn1_identifierMissing, - sizeof (_asn1_identifierMissing), - (char *) p2->value); - } - else - _asn1_strcpy (_asn1_identifierMissing, "(null)"); - - p2 = asn1_find_node (node, name2); - if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) || - !(p2->type & CONST_ASSIGN)) - return ASN1_IDENTIFIER_NOT_FOUND; - else - _asn1_identifierMissing[0] = 0; - } - } - else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && - (p->type & CONST_ASSIGN)) - { - p2 = p->down; - if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT)) - { - if (p2->value && !c_isdigit (p2->value[0])) - { - _asn1_str_cpy (name2, sizeof (name2), node->name); - _asn1_str_cat (name2, sizeof (name2), "."); - _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); - _asn1_str_cpy (_asn1_identifierMissing, - sizeof (_asn1_identifierMissing), - (char *) p2->value); - - p2 = asn1_find_node (node, name2); - if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) - || !(p2->type & CONST_ASSIGN)) - return ASN1_IDENTIFIER_NOT_FOUND; - else - _asn1_identifierMissing[0] = 0; - } - } - } - - if (p->down) - { - p = p->down; - } - else if (p->right) - p = p->right; - else - { - while (p) - { - p = _asn1_find_up (p); - if (p == node) - { - p = NULL; - break; - } - if (p && p->right) - { - p = p->right; - break; - } - } - } - } - - return ASN1_SUCCESS; -} - - -/******************************************************************/ -/* Function : _asn1_set_default_tag */ -/* Description: sets the default IMPLICIT or EXPLICIT property in */ -/* the tagged elements that don't have this declaration. */ -/* Parameters: */ -/* node: pointer to a DEFINITIONS element. */ -/* Return: */ -/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL or not a pointer to */ -/* a DEFINITIONS element, */ -/* otherwise ASN1_SUCCESS */ -/******************************************************************/ -int -_asn1_set_default_tag (asn1_node node) -{ - asn1_node p; - - if ((node == NULL) || (type_field (node->type) != ASN1_ETYPE_DEFINITIONS)) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - while (p) - { - if ((type_field (p->type) == ASN1_ETYPE_TAG) && - !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT)) - { - if (node->type & CONST_EXPLICIT) - p->type |= CONST_EXPLICIT; - else - p->type |= CONST_IMPLICIT; - } - - if (p->down) - { - p = p->down; - } - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == node) - { - p = NULL; - break; - } - if (p && p->right) - { - p = p->right; - break; - } - } - } - } - - return ASN1_SUCCESS; -} diff --git a/grub-core/lib/libtasn1/lib/parser_aux.h b/grub-core/lib/libtasn1/lib/parser_aux.h deleted file mode 100644 index 3eac1fa30..000000000 --- a/grub-core/lib/libtasn1/lib/parser_aux.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2000-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 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 _PARSER_AUX_H -# define _PARSER_AUX_H - -/***********************************************/ -/* Type: list_type */ -/* Description: type used in the list during */ -/* the structure creation. */ -/***********************************************/ -typedef struct list_struct -{ - asn1_node node; - struct list_struct *next; -} list_type; - -/***************************************/ -/* Functions used by ASN.1 parser */ -/***************************************/ -asn1_node _asn1_add_static_node (list_type ** e_list, unsigned int type); - -void _asn1_delete_list (list_type * e_list); - -void _asn1_delete_list_and_nodes (list_type * e_list); - -void _asn1_delete_node_from_list (list_type * list, asn1_node node); - -asn1_node -_asn1_set_value (asn1_node node, const void *value, unsigned int len); - -asn1_node _asn1_set_value_m (asn1_node node, void *value, unsigned int len); - -asn1_node -_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len); - -asn1_node -_asn1_append_value (asn1_node node, const void *value, unsigned int len); - -asn1_node _asn1_set_name (asn1_node node, const char *name); - -asn1_node _asn1_cpy_name (asn1_node dst, asn1_node_const src); - -asn1_node _asn1_set_right (asn1_node node, asn1_node right); - -asn1_node _asn1_get_last_right (asn1_node_const node); - -void _asn1_remove_node (asn1_node node, unsigned int flags); - -/* Max 64-bit integer length is 20 chars + 1 for sign + 1 for null termination */ -# define LTOSTR_MAX_SIZE 22 -char *_asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE]); - -asn1_node _asn1_find_up (asn1_node_const node); - -int _asn1_change_integer_value (asn1_node node); - -# define EXPAND_OBJECT_ID_MAX_RECURSION 16 -int _asn1_expand_object_id (list_type ** list, asn1_node node); - -int _asn1_type_set_config (asn1_node node); - -int _asn1_check_identifier (asn1_node_const node); - -int _asn1_set_default_tag (asn1_node node); - -/******************************************************************/ -/* Function : _asn1_get_right */ -/* Description: returns the element pointed by the RIGHT field of */ -/* a NODE_ASN element. */ -/* Parameters: */ -/* node: NODE_ASN element pointer. */ -/* Return: field RIGHT of NODE. */ -/******************************************************************/ -inline static asn1_node -_asn1_get_right (asn1_node_const node) -{ - if (node == NULL) - return NULL; - return node->right; -} - -/******************************************************************/ -/* Function : _asn1_set_down */ -/* Description: sets the field DOWN in a NODE_ASN element. */ -/* Parameters: */ -/* node: element pointer. */ -/* down: pointer to a NODE_ASN element that you want be pointed */ -/* by NODE. */ -/* Return: pointer to *NODE. */ -/******************************************************************/ -inline static asn1_node -_asn1_set_down (asn1_node node, asn1_node down) -{ - if (node == NULL) - return node; - node->down = down; - if (down) - down->left = node; - return node; -} - -/******************************************************************/ -/* Function : _asn1_get_down */ -/* Description: returns the element pointed by the DOWN field of */ -/* a NODE_ASN element. */ -/* Parameters: */ -/* node: NODE_ASN element pointer. */ -/* Return: field DOWN of NODE. */ -/******************************************************************/ -inline static asn1_node -_asn1_get_down (asn1_node_const node) -{ - if (node == NULL) - return NULL; - return node->down; -} - -/******************************************************************/ -/* Function : _asn1_get_name */ -/* Description: returns the name of a NODE_ASN element. */ -/* Parameters: */ -/* node: NODE_ASN element pointer. */ -/* Return: a null terminated string. */ -/******************************************************************/ -inline static char * -_asn1_get_name (asn1_node_const node) -{ - if (node == NULL) - return NULL; - return (char *) node->name; -} - -/******************************************************************/ -/* Function : _asn1_mod_type */ -/* Description: change the field TYPE of an NODE_ASN element. */ -/* The new value is the old one | (bitwise or) the */ -/* paramener VALUE. */ -/* Parameters: */ -/* node: NODE_ASN element pointer. */ -/* value: the integer value that must be or-ed with the current */ -/* value of field TYPE. */ -/* Return: NODE pointer. */ -/******************************************************************/ -inline static asn1_node -_asn1_mod_type (asn1_node node, unsigned int value) -{ - if (node == NULL) - return node; - node->type |= value; - return node; -} - -#endif diff --git a/grub-core/lib/libtasn1/lib/structure.c b/grub-core/lib/libtasn1/lib/structure.c deleted file mode 100644 index 512dd601f..000000000 --- a/grub-core/lib/libtasn1/lib/structure.c +++ /dev/null @@ -1,1225 +0,0 @@ -/* - * Copyright (C) 2002-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 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 - */ - - -/*****************************************************/ -/* File: structure.c */ -/* Description: Functions to create and delete an */ -/* ASN1 tree. */ -/*****************************************************/ - - -#include -#include -#include "parser_aux.h" -#include - - -extern char _asn1_identifierMissing[]; - - -/******************************************************/ -/* Function : _asn1_add_single_node */ -/* Description: creates a new NODE_ASN element. */ -/* Parameters: */ -/* type: type of the new element (see ASN1_ETYPE_ */ -/* and CONST_ constants). */ -/* Return: pointer to the new element. */ -/******************************************************/ -asn1_node -_asn1_add_single_node (unsigned int type) -{ - asn1_node punt; - - punt = calloc (1, sizeof (struct asn1_node_st)); - if (punt == NULL) - return NULL; - - punt->type = type; - - return punt; -} - - -/******************************************************************/ -/* Function : _asn1_find_left */ -/* Description: returns the NODE_ASN element with RIGHT field that*/ -/* points the element NODE. */ -/* Parameters: */ -/* node: NODE_ASN element pointer. */ -/* Return: NULL if not found. */ -/******************************************************************/ -asn1_node -_asn1_find_left (asn1_node_const node) -{ - if ((node == NULL) || (node->left == NULL) || (node->left->down == node)) - return NULL; - - return node->left; -} - - -int -_asn1_create_static_structure (asn1_node_const pointer, - char *output_file_name, char *vector_name) -{ - FILE *file; - asn1_node_const p; - unsigned long t; - - file = fopen (output_file_name, "w"); - - if (file == NULL) - return ASN1_FILE_NOT_FOUND; - - fprintf (file, "#if HAVE_CONFIG_H\n"); - fprintf (file, "# include \"config.h\"\n"); - fprintf (file, "#endif\n\n"); - - fprintf (file, "#include \n\n"); - - fprintf (file, "const asn1_static_node %s[] = {\n", vector_name); - - p = pointer; - - while (p) - { - fprintf (file, " { "); - - if (p->name[0] != 0) - fprintf (file, "\"%s\", ", p->name); - else - fprintf (file, "NULL, "); - - t = p->type; - if (p->down) - t |= CONST_DOWN; - if (p->right) - t |= CONST_RIGHT; - - fprintf (file, "%lu, ", t); - - if (p->value) - fprintf (file, "\"%s\"},\n", p->value); - else - fprintf (file, "NULL },\n"); - - if (p->down) - { - p = p->down; - } - else if (p->right) - { - p = p->right; - } - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == pointer) - { - p = NULL; - break; - } - if (p->right) - { - p = p->right; - break; - } - } - } - } - - fprintf (file, " { NULL, 0, NULL }\n};\n"); - - fclose (file); - - return ASN1_SUCCESS; -} - - -/** - * asn1_array2tree: - * @array: specify the array that contains ASN.1 declarations - * @definitions: return the pointer to the structure created by - * *ARRAY ASN.1 declarations - * @errorDescription: return the error description. - * - * Creates the structures needed to manage the ASN.1 definitions. - * @array is a vector created by asn1_parser2array(). - * - * Returns: %ASN1_SUCCESS if structure was created correctly, - * %ASN1_ELEMENT_NOT_EMPTY if *@definitions not NULL, - * %ASN1_IDENTIFIER_NOT_FOUND if in the file there is an identifier - * that is not defined (see @errorDescription for more information), - * %ASN1_ARRAY_ERROR if the array pointed by @array is wrong. - **/ -int -asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, - char *errorDescription) -{ - asn1_node p, p_last = NULL; - unsigned long k; - int move; - int result; - unsigned int type; - list_type *e_list = NULL; - - if (errorDescription) - errorDescription[0] = 0; - - if (*definitions != NULL) - return ASN1_ELEMENT_NOT_EMPTY; - - move = UP; - - for (k = 0; array[k].value || array[k].type || array[k].name; k++) - { - type = convert_old_type (array[k].type); - - p = _asn1_add_static_node (&e_list, type & (~CONST_DOWN)); - if (array[k].name) - _asn1_set_name (p, array[k].name); - if (array[k].value) - _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1); - - if (*definitions == NULL) - *definitions = p; - - if (move == DOWN) - { - if (p_last && p_last->down) - _asn1_delete_structure (e_list, &p_last->down, 0); - _asn1_set_down (p_last, p); - } - else if (move == RIGHT) - { - if (p_last && p_last->right) - _asn1_delete_structure (e_list, &p_last->right, 0); - _asn1_set_right (p_last, p); - } - - p_last = p; - - if (type & CONST_DOWN) - move = DOWN; - else if (type & CONST_RIGHT) - move = RIGHT; - else - { - while (p_last != *definitions) - { - p_last = _asn1_find_up (p_last); - - if (p_last == NULL) - break; - - if (p_last->type & CONST_RIGHT) - { - p_last->type &= ~CONST_RIGHT; - move = RIGHT; - break; - } - } /* while */ - } - } /* while */ - - if (p_last == *definitions) - { - result = _asn1_check_identifier (*definitions); - if (result == ASN1_SUCCESS) - { - _asn1_change_integer_value (*definitions); - result = _asn1_expand_object_id (&e_list, *definitions); - } - } - else - { - result = ASN1_ARRAY_ERROR; - } - - if (errorDescription != NULL) - { - if (result == ASN1_IDENTIFIER_NOT_FOUND) - { - Estrcpy (errorDescription, ":: identifier '"); - Estrcat (errorDescription, _asn1_identifierMissing); - Estrcat (errorDescription, "' not found"); - } - else - errorDescription[0] = 0; - } - - if (result != ASN1_SUCCESS) - { - _asn1_delete_list_and_nodes (e_list); - *definitions = NULL; - } - else - _asn1_delete_list (e_list); - - return result; -} - -/** - * asn1_delete_structure: - * @structure: pointer to the structure that you want to delete. - * - * Deletes the structure *@structure. At the end, *@structure is set - * to NULL. - * - * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if - * *@structure was NULL. - **/ -int -asn1_delete_structure (asn1_node * structure) -{ - return _asn1_delete_structure (NULL, structure, 0); -} - -/** - * asn1_delete_structure2: - * @structure: pointer to the structure that you want to delete. - * @flags: additional flags (see %ASN1_DELETE_FLAG_ZEROIZE) - * - * Deletes the structure *@structure. At the end, *@structure is set - * to NULL. - * - * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if - * *@structure was NULL. - **/ -int -asn1_delete_structure2 (asn1_node * structure, unsigned int flags) -{ - return _asn1_delete_structure (NULL, structure, flags); -} - -int -_asn1_delete_structure (list_type * e_list, asn1_node * structure, - unsigned int flags) -{ - asn1_node p, p2, p3; - - if (*structure == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = *structure; - while (p) - { - if (p->down) - { - p = p->down; - } - else - { /* no down */ - p2 = p->right; - if (p != *structure) - { - p3 = _asn1_find_up (p); - _asn1_set_down (p3, p2); - if (e_list) - _asn1_delete_node_from_list (e_list, p); - _asn1_remove_node (p, flags); - p = p3; - } - else - { /* p==root */ - p3 = _asn1_find_left (p); - if (!p3) - { - p3 = _asn1_find_up (p); - if (p3) - _asn1_set_down (p3, p2); - else - { - if (p->right) - p->right->left = NULL; - } - } - else - _asn1_set_right (p3, p2); - if (e_list) - _asn1_delete_node_from_list (e_list, p); - _asn1_remove_node (p, flags); - p = NULL; - } - } - } - - *structure = NULL; - return ASN1_SUCCESS; -} - - -/** - * asn1_delete_element: - * @structure: pointer to the structure that contains the element you - * want to delete. - * @element_name: element's name you want to delete. - * - * Deletes the element named *@element_name inside *@structure. - * - * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if - * the @element_name was not found. - **/ -int -asn1_delete_element (asn1_node structure, const char *element_name) -{ - asn1_node p2, p3, source_node; - - source_node = asn1_find_node (structure, element_name); - - if (source_node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p2 = source_node->right; - p3 = _asn1_find_left (source_node); - if (!p3) - { - p3 = _asn1_find_up (source_node); - if (p3) - _asn1_set_down (p3, p2); - else if (source_node->right) - source_node->right->left = NULL; - } - else - _asn1_set_right (p3, p2); - - return asn1_delete_structure (&source_node); -} - -#ifndef __clang_analyzer__ -asn1_node -_asn1_copy_structure3 (asn1_node_const source_node) -{ - asn1_node_const p_s; - asn1_node dest_node, p_d, p_d_prev; - int move; - - if (source_node == NULL) - return NULL; - - dest_node = _asn1_add_single_node (source_node->type); - if (dest_node == NULL) - return dest_node; - - p_s = source_node; - p_d = dest_node; - - move = DOWN; - - do - { - if (move != UP) - { - if (p_s->name[0] != 0) - _asn1_cpy_name (p_d, p_s); - if (p_s->value) - _asn1_set_value (p_d, p_s->value, p_s->value_len); - if (p_s->down) - { - p_s = p_s->down; - p_d_prev = p_d; - p_d = _asn1_add_single_node (p_s->type); - _asn1_set_down (p_d_prev, p_d); - continue; - } - p_d->start = p_s->start; - p_d->end = p_s->end; - } - - if (p_s == source_node) - break; - - if (p_s->right) - { - move = RIGHT; - p_s = p_s->right; - p_d_prev = p_d; - p_d = _asn1_add_single_node (p_s->type); - _asn1_set_right (p_d_prev, p_d); - } - else - { - move = UP; - p_s = _asn1_find_up (p_s); - p_d = _asn1_find_up (p_d); - } - } - while (p_s != source_node); - return dest_node; -} -#else - -/* Non-production code */ -asn1_node -_asn1_copy_structure3 (asn1_node_const source_node) -{ - return NULL; -} -#endif /* __clang_analyzer__ */ - - -static asn1_node -_asn1_copy_structure2 (asn1_node_const root, const char *source_name) -{ - asn1_node source_node; - - source_node = asn1_find_node (root, source_name); - - return _asn1_copy_structure3 (source_node); - -} - - -static int -_asn1_type_choice_config (asn1_node node) -{ - asn1_node p, p2, p3, p4; - int move, tlen; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - move = DOWN; - - while (!((p == node) && (move == UP))) - { - if (move != UP) - { - if ((type_field (p->type) == ASN1_ETYPE_CHOICE) - && (p->type & CONST_TAG)) - { - p2 = p->down; - while (p2) - { - if (type_field (p2->type) != ASN1_ETYPE_TAG) - { - p2->type |= CONST_TAG; - p3 = _asn1_find_left (p2); - while (p3) - { - if (type_field (p3->type) == ASN1_ETYPE_TAG) - { - p4 = _asn1_add_single_node (p3->type); - tlen = _asn1_strlen (p3->value); - if (tlen > 0) - _asn1_set_value (p4, p3->value, tlen + 1); - _asn1_set_right (p4, p2->down); - _asn1_set_down (p2, p4); - } - p3 = _asn1_find_left (p3); - } - } - p2 = p2->right; - } - p->type &= ~(CONST_TAG); - p2 = p->down; - while (p2) - { - p3 = p2->right; - if (type_field (p2->type) == ASN1_ETYPE_TAG) - asn1_delete_structure (&p2); - p2 = p3; - } - } - move = DOWN; - } - else - move = RIGHT; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - - if (p == node) - { - move = UP; - continue; - } - - if (move == RIGHT) - { - if (p->right) - p = p->right; - else - move = UP; - } - if (move == UP) - p = _asn1_find_up (p); - } - - return ASN1_SUCCESS; -} - - -static int -_asn1_expand_identifier (asn1_node * node, asn1_node_const root) -{ - asn1_node p, p2, p3; - char name2[ASN1_MAX_NAME_SIZE + 2]; - int move; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = *node; - move = DOWN; - - while (!((p == *node) && (move == UP))) - { - if (move != UP) - { - if (type_field (p->type) == ASN1_ETYPE_IDENTIFIER) - { - snprintf (name2, sizeof (name2), "%s.%s", root->name, p->value); - p2 = _asn1_copy_structure2 (root, name2); - if (p2 == NULL) - { - return ASN1_IDENTIFIER_NOT_FOUND; - } - _asn1_cpy_name (p2, p); - p2->right = p->right; - p2->left = p->left; - if (p->right) - p->right->left = p2; - p3 = p->down; - if (p3) - { - while (p3->right) - p3 = p3->right; - _asn1_set_right (p3, p2->down); - _asn1_set_down (p2, p->down); - } - - p3 = _asn1_find_left (p); - if (p3) - _asn1_set_right (p3, p2); - else - { - p3 = _asn1_find_up (p); - if (p3) - _asn1_set_down (p3, p2); - else - { - p2->left = NULL; - } - } - - if (p->type & CONST_SIZE) - p2->type |= CONST_SIZE; - if (p->type & CONST_TAG) - p2->type |= CONST_TAG; - if (p->type & CONST_OPTION) - p2->type |= CONST_OPTION; - if (p->type & CONST_DEFAULT) - p2->type |= CONST_DEFAULT; - if (p->type & CONST_SET) - p2->type |= CONST_SET; - if (p->type & CONST_NOT_USED) - p2->type |= CONST_NOT_USED; - - if (p == *node) - *node = p2; - _asn1_remove_node (p, 0); - p = p2; - move = DOWN; - continue; - } - move = DOWN; - } - else - move = RIGHT; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - - if (p == *node) - { - move = UP; - continue; - } - - if (move == RIGHT) - { - if (p->right) - p = p->right; - else - move = UP; - } - if (move == UP) - p = _asn1_find_up (p); - } - - return ASN1_SUCCESS; -} - - -/** - * asn1_create_element: - * @definitions: pointer to the structure returned by "parser_asn1" function - * @source_name: the name of the type of the new structure (must be - * inside p_structure). - * @element: pointer to the structure created. - * - * Creates a structure of type @source_name. Example using - * "pkix.asn": - * - * rc = asn1_create_element(cert_def, "PKIX1.Certificate", certptr); - * - * Returns: %ASN1_SUCCESS if creation OK, %ASN1_ELEMENT_NOT_FOUND if - * @source_name is not known. - **/ -int -asn1_create_element (asn1_node_const definitions, const char *source_name, - asn1_node * element) -{ - asn1_node dest_node; - int res; - - dest_node = _asn1_copy_structure2 (definitions, source_name); - - if (dest_node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - _asn1_set_name (dest_node, ""); - - res = _asn1_expand_identifier (&dest_node, definitions); - _asn1_type_choice_config (dest_node); - - *element = dest_node; - - return res; -} - - -/** - * asn1_print_structure: - * @out: pointer to the output file (e.g. stdout). - * @structure: pointer to the structure that you want to visit. - * @name: an element of the structure - * @mode: specify how much of the structure to print, can be - * %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE, - * %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL. - * - * Prints on the @out file descriptor the structure's tree starting - * from the @name element inside the structure @structure. - **/ -void -asn1_print_structure (FILE * out, asn1_node_const structure, const char *name, - int mode) -{ - asn1_node_const p, root; - int k, indent = 0, len, len2, len3; - - if (out == NULL) - return; - - root = asn1_find_node (structure, name); - - if (root == NULL) - return; - - p = root; - while (p) - { - if (mode == ASN1_PRINT_ALL) - { - for (k = 0; k < indent; k++) - fprintf (out, " "); - fprintf (out, "name:"); - if (p->name[0] != 0) - fprintf (out, "%s ", p->name); - else - fprintf (out, "NULL "); - } - else - { - switch (type_field (p->type)) - { - case ASN1_ETYPE_CONSTANT: - case ASN1_ETYPE_TAG: - case ASN1_ETYPE_SIZE: - break; - default: - for (k = 0; k < indent; k++) - fprintf (out, " "); - fprintf (out, "name:"); - if (p->name[0] != 0) - fprintf (out, "%s ", p->name); - else - fprintf (out, "NULL "); - } - } - - if (mode != ASN1_PRINT_NAME) - { - unsigned type = type_field (p->type); - switch (type) - { - case ASN1_ETYPE_CONSTANT: - if (mode == ASN1_PRINT_ALL) - fprintf (out, "type:CONST"); - break; - case ASN1_ETYPE_TAG: - if (mode == ASN1_PRINT_ALL) - fprintf (out, "type:TAG"); - break; - case ASN1_ETYPE_SIZE: - if (mode == ASN1_PRINT_ALL) - fprintf (out, "type:SIZE"); - break; - case ASN1_ETYPE_DEFAULT: - fprintf (out, "type:DEFAULT"); - break; - case ASN1_ETYPE_IDENTIFIER: - fprintf (out, "type:IDENTIFIER"); - break; - case ASN1_ETYPE_ANY: - fprintf (out, "type:ANY"); - break; - case ASN1_ETYPE_CHOICE: - fprintf (out, "type:CHOICE"); - break; - case ASN1_ETYPE_DEFINITIONS: - fprintf (out, "type:DEFINITIONS"); - break; - CASE_HANDLED_ETYPES: - fprintf (out, "%s", _asn1_tags[type].desc); - break; - default: - break; - } - } - - if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL)) - { - switch (type_field (p->type)) - { - case ASN1_ETYPE_CONSTANT: - if (mode == ASN1_PRINT_ALL) - if (p->value) - fprintf (out, " value:%s", p->value); - break; - case ASN1_ETYPE_TAG: - if (mode == ASN1_PRINT_ALL) - if (p->value) - fprintf (out, " value:%s", p->value); - break; - case ASN1_ETYPE_SIZE: - if (mode == ASN1_PRINT_ALL) - if (p->value) - fprintf (out, " value:%s", p->value); - break; - case ASN1_ETYPE_DEFAULT: - if (p->value) - fprintf (out, " value:%s", p->value); - else if (p->type & CONST_TRUE) - fprintf (out, " value:TRUE"); - else if (p->type & CONST_FALSE) - fprintf (out, " value:FALSE"); - break; - case ASN1_ETYPE_IDENTIFIER: - if (p->value) - fprintf (out, " value:%s", p->value); - break; - case ASN1_ETYPE_INTEGER: - if (p->value) - { - len2 = -1; - len = asn1_get_length_der (p->value, p->value_len, &len2); - fprintf (out, " value:0x"); - if (len > 0) - for (k = 0; k < len; k++) - fprintf (out, "%02x", (unsigned) (p->value)[k + len2]); - } - break; - case ASN1_ETYPE_ENUMERATED: - if (p->value) - { - len2 = -1; - len = asn1_get_length_der (p->value, p->value_len, &len2); - fprintf (out, " value:0x"); - if (len > 0) - for (k = 0; k < len; k++) - fprintf (out, "%02x", (unsigned) (p->value)[k + len2]); - } - break; - case ASN1_ETYPE_BOOLEAN: - if (p->value) - { - if (p->value[0] == 'T') - fprintf (out, " value:TRUE"); - else if (p->value[0] == 'F') - fprintf (out, " value:FALSE"); - } - break; - case ASN1_ETYPE_BIT_STRING: - if (p->value) - { - len2 = -1; - len = asn1_get_length_der (p->value, p->value_len, &len2); - if (len > 0) - { - fprintf (out, " value(%i):", - (len - 1) * 8 - (p->value[len2])); - for (k = 1; k < len; k++) - fprintf (out, "%02x", - (unsigned) (p->value)[k + len2]); - } - } - break; - case ASN1_ETYPE_GENERALIZED_TIME: - case ASN1_ETYPE_UTC_TIME: - if (p->value) - { - fprintf (out, " value:"); - for (k = 0; k < p->value_len; k++) - fprintf (out, "%c", (p->value)[k]); - } - break; - case ASN1_ETYPE_GENERALSTRING: - case ASN1_ETYPE_NUMERIC_STRING: - case ASN1_ETYPE_IA5_STRING: - case ASN1_ETYPE_TELETEX_STRING: - case ASN1_ETYPE_PRINTABLE_STRING: - case ASN1_ETYPE_UNIVERSAL_STRING: - case ASN1_ETYPE_UTF8_STRING: - case ASN1_ETYPE_VISIBLE_STRING: - if (p->value) - { - len2 = -1; - len = asn1_get_length_der (p->value, p->value_len, &len2); - fprintf (out, " value:"); - if (len > 0) - for (k = 0; k < len; k++) - fprintf (out, "%c", (p->value)[k + len2]); - } - break; - case ASN1_ETYPE_BMP_STRING: - case ASN1_ETYPE_OCTET_STRING: - if (p->value) - { - len2 = -1; - len = asn1_get_length_der (p->value, p->value_len, &len2); - fprintf (out, " value:"); - if (len > 0) - for (k = 0; k < len; k++) - fprintf (out, "%02x", (unsigned) (p->value)[k + len2]); - } - break; - case ASN1_ETYPE_OBJECT_ID: - if (p->value) - fprintf (out, " value:%s", p->value); - break; - case ASN1_ETYPE_ANY: - if (p->value) - { - len3 = -1; - len2 = asn1_get_length_der (p->value, p->value_len, &len3); - fprintf (out, " value:"); - if (len2 > 0) - for (k = 0; k < len2; k++) - fprintf (out, "%02x", (unsigned) (p->value)[k + len3]); - } - break; - case ASN1_ETYPE_SET: - case ASN1_ETYPE_SET_OF: - case ASN1_ETYPE_CHOICE: - case ASN1_ETYPE_DEFINITIONS: - case ASN1_ETYPE_SEQUENCE_OF: - case ASN1_ETYPE_SEQUENCE: - case ASN1_ETYPE_NULL: - break; - default: - break; - } - } - - if (mode == ASN1_PRINT_ALL) - { - if (p->type & 0x1FFFFF00) - { - fprintf (out, " attr:"); - if (p->type & CONST_UNIVERSAL) - fprintf (out, "UNIVERSAL,"); - if (p->type & CONST_PRIVATE) - fprintf (out, "PRIVATE,"); - if (p->type & CONST_APPLICATION) - fprintf (out, "APPLICATION,"); - if (p->type & CONST_EXPLICIT) - fprintf (out, "EXPLICIT,"); - if (p->type & CONST_IMPLICIT) - fprintf (out, "IMPLICIT,"); - if (p->type & CONST_TAG) - fprintf (out, "TAG,"); - if (p->type & CONST_DEFAULT) - fprintf (out, "DEFAULT,"); - if (p->type & CONST_TRUE) - fprintf (out, "TRUE,"); - if (p->type & CONST_FALSE) - fprintf (out, "FALSE,"); - if (p->type & CONST_LIST) - fprintf (out, "LIST,"); - if (p->type & CONST_MIN_MAX) - fprintf (out, "MIN_MAX,"); - if (p->type & CONST_OPTION) - fprintf (out, "OPTION,"); - if (p->type & CONST_1_PARAM) - fprintf (out, "1_PARAM,"); - if (p->type & CONST_SIZE) - fprintf (out, "SIZE,"); - if (p->type & CONST_DEFINED_BY) - fprintf (out, "DEF_BY,"); - if (p->type & CONST_GENERALIZED) - fprintf (out, "GENERALIZED,"); - if (p->type & CONST_UTC) - fprintf (out, "UTC,"); - if (p->type & CONST_SET) - fprintf (out, "SET,"); - if (p->type & CONST_NOT_USED) - fprintf (out, "NOT_USED,"); - if (p->type & CONST_ASSIGN) - fprintf (out, "ASSIGNMENT,"); - } - } - - if (mode == ASN1_PRINT_ALL) - { - fprintf (out, "\n"); - } - else - { - switch (type_field (p->type)) - { - case ASN1_ETYPE_CONSTANT: - case ASN1_ETYPE_TAG: - case ASN1_ETYPE_SIZE: - break; - default: - fprintf (out, "\n"); - } - } - - if (p->down) - { - p = p->down; - indent += 2; - } - else if (p == root) - { - p = NULL; - break; - } - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == root) - { - p = NULL; - break; - } - indent -= 2; - if (p->right) - { - p = p->right; - break; - } - } - } - } -} - - - -/** - * asn1_number_of_elements: - * @element: pointer to the root of an ASN1 structure. - * @name: the name of a sub-structure of ROOT. - * @num: pointer to an integer where the result will be stored - * - * Counts the number of elements of a sub-structure called NAME with - * names equal to "?1","?2", ... - * - * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if - * @name is not known, %ASN1_GENERIC_ERROR if pointer @num is %NULL. - **/ -int -asn1_number_of_elements (asn1_node_const element, const char *name, int *num) -{ - asn1_node_const node, p; - - if (num == NULL) - return ASN1_GENERIC_ERROR; - - *num = 0; - - node = asn1_find_node (element, name); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node->down; - - while (p) - { - if (p->name[0] == '?') - (*num)++; - p = p->right; - } - - return ASN1_SUCCESS; -} - - -/** - * asn1_find_structure_from_oid: - * @definitions: ASN1 definitions - * @oidValue: value of the OID to search (e.g. "1.2.3.4"). - * - * Search the structure that is defined just after an OID definition. - * - * Returns: %NULL when @oidValue not found, otherwise the pointer to a - * constant string that contains the element name defined just after - * the OID. - **/ -const char * -asn1_find_structure_from_oid (asn1_node_const definitions, - const char *oidValue) -{ - char name[2 * ASN1_MAX_NAME_SIZE + 2]; - char value[ASN1_MAX_NAME_SIZE]; - asn1_node p; - int len; - int result; - const char *definitionsName; - - if ((definitions == NULL) || (oidValue == NULL)) - return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ - - definitionsName = definitions->name; - - /* search the OBJECT_ID into definitions */ - p = definitions->down; - while (p) - { - if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && - (p->type & CONST_ASSIGN)) - { - snprintf (name, sizeof (name), "%s.%s", definitionsName, p->name); - - len = ASN1_MAX_NAME_SIZE; - result = asn1_read_value (definitions, name, value, &len); - - if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value))) - { - p = p->right; - if (p == NULL) /* reach the end of ASN1 definitions */ - return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ - - return p->name; - } - } - p = p->right; - } - - return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ -} - -/** - * asn1_copy_node: - * @dst: Destination asn1 node. - * @dst_name: Field name in destination node. - * @src: Source asn1 node. - * @src_name: Field name in source node. - * - * Create a deep copy of a asn1_node variable. That - * function requires @dst to be expanded using asn1_create_element(). - * - * Returns: Return %ASN1_SUCCESS on success. - **/ -int -asn1_copy_node (asn1_node dst, const char *dst_name, - asn1_node_const src, const char *src_name) -{ - int result; - asn1_node dst_node; - void *data = NULL; - int size = 0; - - result = asn1_der_coding (src, src_name, NULL, &size, NULL); - if (result != ASN1_MEM_ERROR) - return result; - - data = malloc (size); - if (data == NULL) - return ASN1_MEM_ERROR; - - result = asn1_der_coding (src, src_name, data, &size, NULL); - if (result != ASN1_SUCCESS) - { - free (data); - return result; - } - - dst_node = asn1_find_node (dst, dst_name); - if (dst_node == NULL) - { - free (data); - return ASN1_ELEMENT_NOT_FOUND; - } - - result = asn1_der_decoding (&dst_node, data, size, NULL); - - free (data); - - return result; -} - -/** - * asn1_dup_node: - * @src: Source asn1 node. - * @src_name: Field name in source node. - * - * Create a deep copy of a asn1_node variable. This function - * will return an exact copy of the provided structure. - * - * Returns: Return %NULL on failure. - **/ -asn1_node -asn1_dup_node (asn1_node_const src, const char *src_name) -{ - return _asn1_copy_structure2 (src, src_name); -} diff --git a/grub-core/lib/libtasn1/lib/structure.h b/grub-core/lib/libtasn1/lib/structure.h deleted file mode 100644 index b973ce963..000000000 --- a/grub-core/lib/libtasn1/lib/structure.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2002-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 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 - */ - -/*************************************************/ -/* File: structure.h */ -/* Description: list of exported object by */ -/* "structure.c" */ -/*************************************************/ - -#ifndef _STRUCTURE_H -# define _STRUCTURE_H - -# include "parser_aux.h" /* list_type */ - -int _asn1_create_static_structure (asn1_node_const pointer, - char *output_file_name, char *vector_name); - -asn1_node _asn1_copy_structure3 (asn1_node_const source_node); - -asn1_node _asn1_add_single_node (unsigned int type); - -asn1_node _asn1_find_left (asn1_node_const node); - -int -_asn1_delete_structure (list_type * e_list, asn1_node * structure, - unsigned int flags); - -#endif diff --git a/grub-core/lib/libtasn1/libtasn1.h b/grub-core/lib/libtasn1/libtasn1.h deleted file mode 100644 index 51cc7879f..000000000 --- a/grub-core/lib/libtasn1/libtasn1.h +++ /dev/null @@ -1,643 +0,0 @@ -/* - * Copyright (C) 2002-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * LIBTASN1 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. - * - * LIBTASN1 is distributed in the hope that 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 LIBTASN1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -/** - * SECTION:libtasn1 - * @short_description: GNU ASN.1 library - * - * The Libtasn1 library provides Abstract Syntax Notation One (ASN.1, as - * specified by the X.680 ITU-T recommendation) parsing and structures - * management, and Distinguished Encoding Rules (DER, as per X.690) - * encoding and decoding functions. - */ - - -#ifndef LIBTASN1_H -# define LIBTASN1_H - -# ifndef ASN1_API -# if defined ASN1_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY -# define ASN1_API __attribute__((__visibility__("default"))) -# elif defined ASN1_BUILDING && defined _MSC_VER && ! defined ASN1_STATIC -# define ASN1_API __declspec(dllexport) -# elif defined _MSC_VER && ! defined ASN1_STATIC -# define ASN1_API __declspec(dllimport) -# else -# define ASN1_API -# endif -# endif - -# ifdef __GNUC__ -# define __LIBTASN1_CONST__ __attribute__((const)) -# define __LIBTASN1_PURE__ __attribute__((pure)) -# else -# define __LIBTASN1_CONST__ -# define __LIBTASN1_PURE__ -# endif - -# include -# include -# include /* for FILE* */ - -# ifdef __cplusplus -extern "C" -{ -# endif - -/** - * ASN1_VERSION: - * - * Version of the library as a string. - */ -# define ASN1_VERSION "4.19.0" - -/** - * ASN1_VERSION_MAJOR: - * - * Major version number of the library. - */ -# define ASN1_VERSION_MAJOR 4 - -/** - * ASN1_VERSION_MINOR: - * - * Minor version number of the library. - */ -# define ASN1_VERSION_MINOR 19 - -/** - * ASN1_VERSION_PATCH: - * - * Patch version number of the library. - */ -# define ASN1_VERSION_PATCH 0 - -/** - * ASN1_VERSION_NUMBER: - * - * Version number of the library as a number. - */ -# define ASN1_VERSION_NUMBER 0x041300 - - -# if defined __GNUC__ && !defined ASN1_INTERNAL_BUILD -# define _ASN1_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -# if _ASN1_GCC_VERSION >= 30100 -# define _ASN1_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__)) -# endif -# endif - -# ifndef _ASN1_GCC_ATTR_DEPRECATED -# define _ASN1_GCC_ATTR_DEPRECATED -# endif - -/*****************************************/ -/* Errors returned by libtasn1 functions */ -/*****************************************/ -# define ASN1_SUCCESS 0 -# define ASN1_FILE_NOT_FOUND 1 -# define ASN1_ELEMENT_NOT_FOUND 2 -# define ASN1_IDENTIFIER_NOT_FOUND 3 -# define ASN1_DER_ERROR 4 -# define ASN1_VALUE_NOT_FOUND 5 -# define ASN1_GENERIC_ERROR 6 -# define ASN1_VALUE_NOT_VALID 7 -# define ASN1_TAG_ERROR 8 -# define ASN1_TAG_IMPLICIT 9 -# define ASN1_ERROR_TYPE_ANY 10 -# define ASN1_SYNTAX_ERROR 11 -# define ASN1_MEM_ERROR 12 -# define ASN1_MEM_ALLOC_ERROR 13 -# define ASN1_DER_OVERFLOW 14 -# define ASN1_NAME_TOO_LONG 15 -# define ASN1_ARRAY_ERROR 16 -# define ASN1_ELEMENT_NOT_EMPTY 17 -# define ASN1_TIME_ENCODING_ERROR 18 -# define ASN1_RECURSION 19 - -/*************************************/ -/* Constants used in asn1_visit_tree */ -/*************************************/ -# define ASN1_PRINT_NAME 1 -# define ASN1_PRINT_NAME_TYPE 2 -# define ASN1_PRINT_NAME_TYPE_VALUE 3 -# define ASN1_PRINT_ALL 4 - -/*****************************************/ -/* Constants returned by asn1_read_tag */ -/*****************************************/ -# define ASN1_CLASS_UNIVERSAL 0x00 /* old: 1 */ -# define ASN1_CLASS_APPLICATION 0x40 /* old: 2 */ -# define ASN1_CLASS_CONTEXT_SPECIFIC 0x80 /* old: 3 */ -# define ASN1_CLASS_PRIVATE 0xC0 /* old: 4 */ -# define ASN1_CLASS_STRUCTURED 0x20 - -/*****************************************/ -/* Constants returned by asn1_read_tag */ -/*****************************************/ -# define ASN1_TAG_BOOLEAN 0x01 -# define ASN1_TAG_INTEGER 0x02 -# define ASN1_TAG_SEQUENCE 0x10 -# define ASN1_TAG_SET 0x11 -# define ASN1_TAG_OCTET_STRING 0x04 -# define ASN1_TAG_BIT_STRING 0x03 -# define ASN1_TAG_UTCTime 0x17 -# define ASN1_TAG_GENERALIZEDTime 0x18 -# define ASN1_TAG_OBJECT_ID 0x06 -# define ASN1_TAG_ENUMERATED 0x0A -# define ASN1_TAG_NULL 0x05 -# define ASN1_TAG_GENERALSTRING 0x1B -# define ASN1_TAG_NUMERIC_STRING 0x12 -# define ASN1_TAG_IA5_STRING 0x16 -# define ASN1_TAG_TELETEX_STRING 0x14 -# define ASN1_TAG_PRINTABLE_STRING 0x13 -# define ASN1_TAG_UNIVERSAL_STRING 0x1C -# define ASN1_TAG_BMP_STRING 0x1E -# define ASN1_TAG_UTF8_STRING 0x0C -# define ASN1_TAG_VISIBLE_STRING 0x1A - -/** - * asn1_node: - * - * Structure definition used for the node of the tree - * that represents an ASN.1 DEFINITION. - */ - typedef struct asn1_node_st asn1_node_st; - - typedef asn1_node_st *asn1_node; - typedef const asn1_node_st *asn1_node_const; - -/** - * ASN1_MAX_NAME_SIZE: - * - * Maximum number of characters of a name - * inside a file with ASN1 definitions. - */ -# define ASN1_MAX_NAME_SIZE 64 - - -/** - * asn1_static_node: - * @name: Node name - * @type: Node typ - * @value: Node value - * - * For the on-disk format of ASN.1 trees, created by asn1_parser2array(). - */ - typedef struct asn1_static_node_st - { - const char *name; /* Node name */ - unsigned int type; /* Node type */ - const void *value; /* Node value */ - } asn1_static_node; - -/* List of constants for field type of asn1_static_node */ -# define ASN1_ETYPE_INVALID 0 -# define ASN1_ETYPE_CONSTANT 1 -# define ASN1_ETYPE_IDENTIFIER 2 -# define ASN1_ETYPE_INTEGER 3 -# define ASN1_ETYPE_BOOLEAN 4 -# define ASN1_ETYPE_SEQUENCE 5 -# define ASN1_ETYPE_BIT_STRING 6 -# define ASN1_ETYPE_OCTET_STRING 7 -# define ASN1_ETYPE_TAG 8 -# define ASN1_ETYPE_DEFAULT 9 -# define ASN1_ETYPE_SIZE 10 -# define ASN1_ETYPE_SEQUENCE_OF 11 -# define ASN1_ETYPE_OBJECT_ID 12 -# define ASN1_ETYPE_ANY 13 -# define ASN1_ETYPE_SET 14 -# define ASN1_ETYPE_SET_OF 15 -# define ASN1_ETYPE_DEFINITIONS 16 -# define ASN1_ETYPE_CHOICE 18 -# define ASN1_ETYPE_IMPORTS 19 -# define ASN1_ETYPE_NULL 20 -# define ASN1_ETYPE_ENUMERATED 21 -# define ASN1_ETYPE_GENERALSTRING 27 -# define ASN1_ETYPE_NUMERIC_STRING 28 -# define ASN1_ETYPE_IA5_STRING 29 -# define ASN1_ETYPE_TELETEX_STRING 30 -# define ASN1_ETYPE_PRINTABLE_STRING 31 -# define ASN1_ETYPE_UNIVERSAL_STRING 32 -# define ASN1_ETYPE_BMP_STRING 33 -# define ASN1_ETYPE_UTF8_STRING 34 -# define ASN1_ETYPE_VISIBLE_STRING 35 -# define ASN1_ETYPE_UTC_TIME 36 -# define ASN1_ETYPE_GENERALIZED_TIME 37 - -/** - * ASN1_DELETE_FLAG_ZEROIZE: - * - * Used by: asn1_delete_structure2() - * - * Zeroize values prior to deinitialization. - */ -# define ASN1_DELETE_FLAG_ZEROIZE 1 - -/** - * ASN1_DECODE_FLAG_ALLOW_PADDING: - * - * Used by: asn1_der_decoding2() - * - * This flag would allow arbitrary data past the DER data. - */ -# define ASN1_DECODE_FLAG_ALLOW_PADDING 1 -/** - * ASN1_DECODE_FLAG_STRICT_DER: - * - * Used by: asn1_der_decoding2() - * - * This flag would ensure that no BER decoding takes place. - */ -# define ASN1_DECODE_FLAG_STRICT_DER (1<<1) -/** - * ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME: - * - * Used by: asn1_der_decoding2() - * - * This flag will tolerate Time encoding errors when in strict DER. - */ -# define ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME (1<<2) - - /* *INDENT-OFF* */ - -/** - * asn1_data_node_st: - * @name: Node name - * @value: Node value - * @value_len: Node value size - * @type: Node value type (ASN1_ETYPE_*) - * - * Data node inside a #asn1_node structure. - */ - struct asn1_data_node_st - { - const char *name; /* Node name */ - const void *value; /* Node value */ - unsigned int value_len; /* Node value size */ - unsigned int type; /* Node value type (ASN1_ETYPE_*) */ -}; - - /* *INDENT-ON* */ - - typedef struct asn1_data_node_st asn1_data_node_st; - -/***********************************/ -/* Fixed constants */ -/***********************************/ - -/** - * ASN1_MAX_ERROR_DESCRIPTION_SIZE: - * - * Maximum number of characters - * of a description message - * (null character included). - */ -# define ASN1_MAX_ERROR_DESCRIPTION_SIZE 128 - -/***********************************/ -/* Functions definitions */ -/***********************************/ - - extern ASN1_API int - asn1_parser2tree (const char *file, - asn1_node * definitions, char *error_desc); - - extern ASN1_API int - asn1_parser2array (const char *inputFileName, - const char *outputFileName, - const char *vectorName, char *error_desc); - - extern ASN1_API int - asn1_array2tree (const asn1_static_node * array, - asn1_node * definitions, char *errorDescription); - - extern ASN1_API void - asn1_print_structure (FILE * out, asn1_node_const structure, - const char *name, int mode); - - extern ASN1_API int - asn1_create_element (asn1_node_const definitions, - const char *source_name, asn1_node * element); - - extern ASN1_API int asn1_delete_structure (asn1_node * structure); - - extern ASN1_API int asn1_delete_structure2 (asn1_node * structure, - unsigned int flags); - - extern ASN1_API int - asn1_delete_element (asn1_node structure, const char *element_name); - - extern ASN1_API int - asn1_write_value (asn1_node node_root, const char *name, - const void *ivalue, int len); - - extern ASN1_API int - asn1_read_value (asn1_node_const root, const char *name, - void *ivalue, int *len); - - extern ASN1_API int - asn1_read_value_type (asn1_node_const root, const char *name, - void *ivalue, int *len, unsigned int *etype); - - extern ASN1_API int - asn1_read_node_value (asn1_node_const node, asn1_data_node_st * data); - - extern ASN1_API int - asn1_number_of_elements (asn1_node_const element, const char *name, - int *num); - - extern ASN1_API int - asn1_der_coding (asn1_node_const element, const char *name, - void *ider, int *len, char *ErrorDescription); - - extern ASN1_API int - asn1_der_decoding2 (asn1_node * element, const void *ider, - int *max_ider_len, unsigned int flags, - char *errorDescription); - - extern ASN1_API int - asn1_der_decoding (asn1_node * element, const void *ider, - int ider_len, char *errorDescription); - -/* Do not use. Use asn1_der_decoding() instead. */ - extern ASN1_API int - asn1_der_decoding_element (asn1_node * structure, - const char *elementName, - const void *ider, int len, - char *errorDescription) - _ASN1_GCC_ATTR_DEPRECATED; - - extern ASN1_API int - asn1_der_decoding_startEnd (asn1_node element, - const void *ider, int ider_len, - const char *name_element, - int *start, int *end); - - extern ASN1_API int - asn1_expand_any_defined_by (asn1_node_const definitions, - asn1_node * element); - - extern ASN1_API int - asn1_expand_octet_string (asn1_node_const definitions, - asn1_node * element, - const char *octetName, const char *objectName); - - extern ASN1_API int - asn1_read_tag (asn1_node_const root, const char *name, - int *tagValue, int *classValue); - - extern ASN1_API const char *asn1_find_structure_from_oid (asn1_node_const - definitions, - const char - *oidValue); - - __LIBTASN1_PURE__ - extern ASN1_API const char *asn1_check_version (const char *req_version); - - __LIBTASN1_PURE__ extern ASN1_API const char *asn1_strerror (int error); - - extern ASN1_API void asn1_perror (int error); - -# define ASN1_MAX_TAG_SIZE 4 -# define ASN1_MAX_LENGTH_SIZE 9 -# define ASN1_MAX_TL_SIZE (ASN1_MAX_TAG_SIZE+ASN1_MAX_LENGTH_SIZE) - extern ASN1_API long - asn1_get_length_der (const unsigned char *der, int der_len, int *len); - - extern ASN1_API long - asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len); - - extern ASN1_API void - asn1_length_der (unsigned long int len, unsigned char *der, int *der_len); - -/* Other utility functions. */ - - extern ASN1_API - int asn1_decode_simple_der (unsigned int etype, const unsigned char *der, - unsigned int _der_len, - const unsigned char **str, - unsigned int *str_len); - - extern ASN1_API - int asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, - unsigned int _der_len, - unsigned char **str, - unsigned int *str_len, unsigned int *ber_len); - - extern ASN1_API int - asn1_encode_simple_der (unsigned int etype, const unsigned char *str, - unsigned int str_len, unsigned char *tl, - unsigned int *tl_len); - - extern ASN1_API asn1_node - asn1_find_node (asn1_node_const pointer, const char *name); - - extern ASN1_API int - asn1_copy_node (asn1_node dst, const char *dst_name, - asn1_node_const src, const char *src_name); - extern ASN1_API asn1_node - asn1_dup_node (asn1_node_const src, const char *src_name); - -/* Internal and low-level DER utility functions. */ - - extern ASN1_API int - asn1_get_tag_der (const unsigned char *der, int der_len, - unsigned char *cls, int *len, unsigned long *tag); - - extern ASN1_API void - asn1_octet_der (const unsigned char *str, int str_len, - unsigned char *der, int *der_len); - - extern ASN1_API int - asn1_get_octet_der (const unsigned char *der, int der_len, - int *ret_len, unsigned char *str, - int str_size, int *str_len); - - extern ASN1_API void asn1_bit_der (const unsigned char *str, int bit_len, - unsigned char *der, int *der_len); - - extern ASN1_API int - asn1_get_bit_der (const unsigned char *der, int der_len, - int *ret_len, unsigned char *str, - int str_size, int *bit_len); - - extern ASN1_API int - asn1_get_object_id_der (const unsigned char *der, - int der_len, int *ret_len, - char *str, int str_size); - - extern ASN1_API int - asn1_object_id_der (const char *str, unsigned char *der, int *der_len, - unsigned flags); - -/* Compatibility types */ - -/** - * asn1_retCode: - * - * Type formerly returned by libtasn1 functions. - * - * Deprecated: 3.0: Use int instead. - */ - typedef int asn1_retCode _ASN1_GCC_ATTR_DEPRECATED; - -/** - * node_asn_struct: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_node instead. - */ -# ifndef ASN1_DISABLE_DEPRECATED -# if _ASN1_GCC_VERSION >= 30100 -# define node_asn_struct _Pragma ("GCC warning \"'node_asn_struct' macro is deprecated, use 'asn1_node' instead.\"") asn1_node_st -# else -# define node_asn_struct asn1_node_st -# endif -# endif /* !ASN1_DISABLE_DEPRECATED */ - -/** - * node_asn: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_node instead. - */ -# ifndef ASN1_DISABLE_DEPRECATED -# if _ASN1_GCC_VERSION >= 30100 -# define node_asn _Pragma ("GCC warning \"'node_asn' macro is deprecated, use 'asn1_node' instead.\"") asn1_node_st -# else -# define node_asn asn1_node_st -# endif -# endif /* !ASN1_DISABLE_DEPRECATED */ - -/** - * ASN1_TYPE: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_node instead. - */ -# ifndef ASN1_DISABLE_DEPRECATED -# if _ASN1_GCC_VERSION >= 30100 -# define ASN1_TYPE _Pragma ("GCC warning \"'ASN1_TYPE' macro is deprecated, use 'asn1_node' instead.\"") asn1_node -# else -# define ASN1_TYPE asn1_node -# endif -# endif /* !ASN1_DISABLE_DEPRECATED */ - -/** - * ASN1_TYPE_EMPTY: - * - * Compat #define. - * - * Deprecated: 3.0: Use NULL instead. - */ -# ifndef ASN1_DISABLE_DEPRECATED -# if _ASN1_GCC_VERSION >= 30100 -# define ASN1_TYPE_EMPTY _Pragma ("GCC warning \"'ASN1_TYPE_EMPTY' macro is deprecated, use 'NULL' instead.\"") NULL -# else -# define ASN1_TYPE_EMPTY NULL -# endif -# endif /* !ASN1_DISABLE_DEPRECATED */ - -/** - * static_struct_asn: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_static_node instead. - */ -# ifndef ASN1_DISABLE_DEPRECATED -# if _ASN1_GCC_VERSION >= 30100 -# define static_struct_asn _Pragma ("GCC warning \"'static_struct_asn' macro is deprecated, use 'asn1_static_node_st' instead.\"") asn1_static_node_st -# else -# define static_struct_asn asn1_static_node_st -# endif -# endif /* !ASN1_DISABLE_DEPRECATED */ - -/** - * ASN1_ARRAY_TYPE: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_static_node instead. - */ -# ifndef ASN1_DISABLE_DEPRECATED -# if _ASN1_GCC_VERSION >= 30100 -# define ASN1_ARRAY_TYPE _Pragma ("GCC warning \"'ASN1_ARRAY_TYPE' macro is deprecated, use 'asn1_static_node' instead.\"") asn1_static_node -# else -# define ASN1_ARRAY_TYPE asn1_static_node -# endif -# endif /* !ASN1_DISABLE_DEPRECATED */ - -/** - * asn1_static_node_t: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_static_node instead. - */ -# ifndef ASN1_DISABLE_DEPRECATED -# if _ASN1_GCC_VERSION >= 30100 -# define asn1_static_node_t _Pragma ("GCC warning \"'asn1_static_node_t' macro is deprecated, use 'asn1_static_node' instead.\"") asn1_static_node -# else -# define asn1_static_node_t asn1_static_node -# endif -# endif /* !ASN1_DISABLE_DEPRECATED */ - -/** - * node_data_struct: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_data_node_st instead. - */ -# ifndef ASN1_DISABLE_DEPRECATED -# if _ASN1_GCC_VERSION >= 30100 -# define node_data_struct _Pragma ("GCC warning \"'node_data_struct' macro is deprecated, use 'asn1_data_node_st' instead.\"") asn1_data_node_st -# else -# define node_data_struct asn1_data_node_st -# endif -# endif /* !ASN1_DISABLE_DEPRECATED */ - -/** - * ASN1_DATA_NODE: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_data_node_st instead. - */ -# ifndef ASN1_DISABLE_DEPRECATED -# if _ASN1_GCC_VERSION >= 30100 -# define ASN1_DATA_NODE _Pragma ("GCC warning \"'asn1_static_node_t' macro is deprecated, use 'asn1_static_node' instead.\"") asn1_data_node_st -# else -# define ASN1_DATA_NODE asn1_data_node_st -# endif -# endif /* !ASN1_DISABLE_DEPRECATED */ - -# ifdef __cplusplus -} -# endif - -#endif /* LIBTASN1_H */ diff --git a/grub-core/lib/libtasn1/tests/CVE-2018-1000654-1_asn1_tab.h b/grub-core/lib/libtasn1/tests/CVE-2018-1000654-1_asn1_tab.h deleted file mode 100644 index e7930136c..000000000 --- a/grub-core/lib/libtasn1/tests/CVE-2018-1000654-1_asn1_tab.h +++ /dev/null @@ -1,32 +0,0 @@ -#if HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -const asn1_static_node CVE_2018_1000654_1_asn1_tab[] = { - { "TEST_TREE", 536875024, NULL }, - { NULL, 1610612748, NULL }, - { "iso", 1073741825, "1"}, - { "identified-organization", 1073741825, "3"}, - { "dod", 1073741825, "6"}, - { "internet", 1073741825, "1"}, - { "security", 1073741825, "5"}, - { "mechanisms", 1073741825, "5"}, - { "pkix", 1073741825, "7"}, - { "id-mod", 1073741825, "0"}, - { "id-pkix1-implicit-88", 1, "2"}, - { "id-xnyTest", 1879048204, NULL }, - { NULL, 1073741825, "id-ix"}, - { NULL, 1073741825, "29"}, - { NULL, 1, "1"}, - { "id-ix", 1880096780, "OBJECR"}, - { NULL, 1073741825, "id-ix"}, - { NULL, 1073741825, "29"}, - { NULL, 1, "2"}, - { "id-xnyTest", 805306380, NULL }, - { NULL, 1073741825, "id-ix"}, - { NULL, 1073741825, "29"}, - { NULL, 1, "1"}, - { NULL, 0, NULL } -}; diff --git a/grub-core/lib/libtasn1/tests/CVE-2018-1000654-2_asn1_tab.h b/grub-core/lib/libtasn1/tests/CVE-2018-1000654-2_asn1_tab.h deleted file mode 100644 index e8170f5d5..000000000 --- a/grub-core/lib/libtasn1/tests/CVE-2018-1000654-2_asn1_tab.h +++ /dev/null @@ -1,36 +0,0 @@ -#if HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -const asn1_static_node CVE_2018_1000654_2_asn1_tab[] = { - { "TEST_TREE", 536875024, NULL }, - { NULL, 1610612748, NULL }, - { "iso", 1073741825, "1"}, - { "identified-organization", 1073741825, "3"}, - { "dod", 1073741825, "6"}, - { "internet", 1073741825, "1"}, - { "security", 1073741825, "5"}, - { "mechanisms", 1073741825, "5"}, - { "pkix", 1073741825, "7"}, - { "id-mod", 1073741825, "0"}, - { "id-pkix1-implicit-88", 1, "2"}, - { "id-oneTest", 1879048204, NULL }, - { NULL, 1073741825, "id-two"}, - { NULL, 1073741825, "9"}, - { NULL, 1, "1"}, - { "id-two", 1879048204, NULL }, - { NULL, 1073741825, "id-three"}, - { NULL, 1073741825, "2"}, - { NULL, 1, "2"}, - { "id-three", 1879048204, NULL }, - { NULL, 1073741825, "id-four"}, - { NULL, 1073741825, "3"}, - { NULL, 1, "3"}, - { "id-four", 805306380, NULL }, - { NULL, 1073741825, "id-two"}, - { NULL, 1073741825, "3"}, - { NULL, 1, "3"}, - { NULL, 0, NULL } -}; diff --git a/grub-core/lib/libtasn1/tests/CVE-2018-1000654.c b/grub-core/lib/libtasn1/tests/CVE-2018-1000654.c deleted file mode 100644 index 0c22b7012..000000000 --- a/grub-core/lib/libtasn1/tests/CVE-2018-1000654.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2002-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * 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 . - * - */ - -/****************************************************************/ -/* Description: reproducer for CVE-2018-1000654 */ -/****************************************************************/ - -#include -#include -#include -#include "CVE-2018-1000654-1_asn1_tab.h" -#include "CVE-2018-1000654-2_asn1_tab.h" - -int -main (int argc, char *argv[]) -{ - int result, verbose = 0; - asn1_node definitions = NULL; - char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; - - if (argc > 1) - verbose = 1; - - printf ("Test 1\n"); - - result = - asn1_array2tree (CVE_2018_1000654_1_asn1_tab, &definitions, - errorDescription); - if (result != ASN1_RECURSION) - { - asn1_perror (result); - printf ("ErrorDescription = %s\n\n", errorDescription); - exit (1); - } - - asn1_delete_structure (&definitions); - - printf ("Test 2\n"); - - result = - asn1_array2tree (CVE_2018_1000654_2_asn1_tab, &definitions, - errorDescription); - if (result != ASN1_RECURSION) - { - asn1_perror (result); - printf ("ErrorDescription = %s\n\n", errorDescription); - exit (1); - } - - asn1_delete_structure (&definitions); - - if (verbose) - printf ("Success\n"); - exit (0); -} diff --git a/grub-core/lib/libtasn1/tests/Test_overflow.c b/grub-core/lib/libtasn1/tests/Test_overflow.c deleted file mode 100644 index c61dea4bb..000000000 --- a/grub-core/lib/libtasn1/tests/Test_overflow.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2012-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * 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 . - * - */ - -/* Written by Simon Josefsson */ - -#include -#include -#include -#include - -#include "libtasn1.h" - -int -main (int argc, char **argv) -{ - /* Test that values larger than long are rejected. This has worked - fine with all versions of libtasn1. */ - int verbose = 0; - - if (argc > 1) - verbose = 1; - - { - unsigned char der[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; - long l; - int len; - - l = asn1_get_length_der (der, sizeof der, &len); - - if (l == -2L) - { - if (verbose) - puts ("OK: asn1_get_length_der bignum"); - } - else - { - printf ("ERROR: asn1_get_length_der bignum (l %ld len %d)\n", l, len); - return 1; - } - } - - /* Test that values larger than int but smaller than long are - rejected. This limitation was introduced with libtasn1 2.12. */ - if (LONG_MAX > INT_MAX) - { - unsigned long num = ((long) UINT_MAX) << 2; - unsigned char der[20]; - int der_len; - long l; - int len; - - asn1_length_der (num, der, &der_len); - - l = asn1_get_length_der (der, der_len, &len); - - if (l == -2L) - { - if (verbose) - puts ("OK: asn1_get_length_der intnum"); - } - else - { - printf ("ERROR: asn1_get_length_der intnum (l %ld len %d)\n", l, - len); - return 1; - } - } - - /* Test that values larger than would fit in the input string are - rejected. This problem was fixed in libtasn1 2.12. */ - { - unsigned long num = 64; - unsigned char der[20]; - int der_len; - long l; - int len; - - asn1_length_der (num, der, &der_len); - - der_len = sizeof (der); - l = asn1_get_length_der (der, der_len, &len); - - if (l == -4L) - { - if (verbose) - puts ("OK: asn1_get_length_der overflow-small"); - } - else - { - printf ("ERROR: asn1_get_length_der overflow-small (l %ld len %d)\n", - l, len); - return 1; - } - } - - /* Test that values larger than would fit in the input string are - rejected. This problem was fixed in libtasn1 2.12. */ - { - unsigned long num = 1073741824; - unsigned char der[20]; - int der_len; - long l; - int len; - - asn1_length_der (num, der, &der_len); - - der_len = sizeof (der); - l = asn1_get_length_der (der, der_len, &len); - - if (l == -4L) - { - if (verbose) - puts ("OK: asn1_get_length_der overflow-large1"); - } - else - { - printf ("ERROR: asn1_get_length_der overflow-large1 (l %ld len %d)\n", - l, len); - return 1; - } - } - - /* Test that values larger than would fit in the input string are - rejected. This problem was fixed in libtasn1 2.12. */ - { - unsigned long num = 2147483649; - unsigned char der[20]; - int der_len; - long l; - int len; - - asn1_length_der (num, der, &der_len); - - der_len = sizeof (der); - l = asn1_get_length_der (der, der_len, &len); - - if (l == -2L) - { - if (verbose) - puts ("OK: asn1_get_length_der overflow-large2"); - } - else - { - printf ("ERROR: asn1_get_length_der overflow-large2 (l %ld len %d)\n", - l, len); - return 1; - } - } - - return 0; -} diff --git a/grub-core/lib/libtasn1/tests/Test_simple.c b/grub-core/lib/libtasn1/tests/Test_simple.c deleted file mode 100644 index 6cd07e069..000000000 --- a/grub-core/lib/libtasn1/tests/Test_simple.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) 2011-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * 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 . - * - * Written by Simon Josefsson - * - */ - -#include -#include -#include - -#include "libtasn1.h" - -struct tv -{ - int bitlen; - const char *bitstr; - int derlen; - const char *der; -}; - -static const struct tv tv[] = { - {0, "", 2, "\x01\x00"}, - {1, "\x00", 3, "\x02\x07\x00"}, - {2, "\x00", 3, "\x02\x06\x00"}, - {3, "\x00", 3, "\x02\x05\x00"}, - {4, "\x00", 3, "\x02\x04\x00"}, - {5, "\x00", 3, "\x02\x03\x00"}, - {6, "\x00", 3, "\x02\x02\x00"}, - {7, "\x00", 3, "\x02\x01\x00"}, - {8, "\x00\x00", 3, "\x02\x00\x00"}, - {9, "\x00\x00", 4, "\x03\x07\x00\x00"}, - {10, "\x00\x00", 4, "\x03\x06\x00\x00"}, - {11, "\x00\x00", 4, "\x03\x05\x00\x00"}, - {12, "\x00\x00", 4, "\x03\x04\x00\x00"}, - {13, "\x00\x00", 4, "\x03\x03\x00\x00"}, - {14, "\x00\x00", 4, "\x03\x02\x00\x00"}, - {15, "\x00\x00", 4, "\x03\x01\x00\x00"}, - {16, "\x00\x00", 4, "\x03\x00\x00\x00"}, - {17, "\x00\x00\x00", 5, "\x04\x07\x00\x00\x00"}, - {18, "\x00\x00\x00", 5, "\x04\x06\x00\x00\x00"}, - {19, "\x00\x00\x00", 5, "\x04\x05\x00\x00\x00"}, - {1, "\xFF", 3, "\x02\x07\x80"}, - {2, "\xFF", 3, "\x02\x06\xc0"}, - {3, "\xFF", 3, "\x02\x05\xe0"}, - {4, "\xFF", 3, "\x02\x04\xf0"}, - {5, "\xFF", 3, "\x02\x03\xf8"}, - {6, "\xFF", 3, "\x02\x02\xfc"}, - {7, "\xFF", 3, "\x02\x01\xfe"}, - {8, "\xFF\xFF", 3, "\x02\x00\xff"}, - {9, "\xFF\xFF", 4, "\x03\x07\xff\x80"}, - {10, "\xFF\xFF", 4, "\x03\x06\xff\xc0"}, - {11, "\xFF\xFF", 4, "\x03\x05\xff\xe0"}, - {12, "\xFF\xFF", 4, "\x03\x04\xff\xf0"}, - {13, "\xFF\xFF", 4, "\x03\x03\xff\xf8"}, - {14, "\xFF\xFF", 4, "\x03\x02\xff\xfc"}, - {15, "\xFF\xFF", 4, "\x03\x01\xff\xfe"}, - {16, "\xFF\xFF", 4, "\x03\x00\xff\xff"}, - {17, "\xFF\xFF\xFF", 5, "\x04\x07\xff\xff\x80"}, - {18, "\xFF\xFF\xFF", 5, "\x04\x06\xff\xff\xc0"}, - {19, "\xFF\xFF\xFF", 5, "\x04\x05\xff\xff\xe0"}, -}; - -int -main (int argc, char *argv[]) -{ - int result; - unsigned char der[100]; - unsigned char str[100]; - int der_len = sizeof (der); - int str_size = sizeof (str); - int ret_len, bit_len; - size_t i; - - { - unsigned int etype = 38; - unsigned int my_str_len = 10; - unsigned char my_str[10]; - unsigned int tl_len = 10; - unsigned char tl[10]; - - /* https://gitlab.com/gnutls/libtasn1/-/issues/32 */ - result = asn1_encode_simple_der (etype, my_str, my_str_len, tl, &tl_len); - if (result != ASN1_VALUE_NOT_VALID) - { - fprintf (stderr, "asn1_encode_simple_der out of range etype\n"); - return 1; - } - } - - /* Dummy test */ - - asn1_bit_der (NULL, 0, der, &der_len); - result = asn1_get_bit_der (der, 0, &ret_len, str, str_size, &bit_len); - if (result != ASN1_GENERIC_ERROR) - { - fprintf (stderr, "asn1_get_bit_der zero\n"); - return 1; - } - - /* Encode short strings with increasing bit lengths */ - - for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) - { - /* Encode */ - - asn1_bit_der ((const unsigned char *) tv[i].bitstr, tv[i].bitlen, - der, &der_len); - -#if 0 - { - size_t j; - for (j = 0; j < der_len; j++) - printf ("\\x%02x", der[j]); - printf ("\n"); - } -#endif - - if (der_len != tv[i].derlen || memcmp (der, tv[i].der, der_len) != 0) - { - fprintf (stderr, "asn1_bit_der iter %lu\n", (unsigned long) i); - return 1; - } - - /* Decode it */ - - result = asn1_get_bit_der (der, der_len, &ret_len, str, - str_size, &bit_len); - if (result != ASN1_SUCCESS || ret_len != tv[i].derlen - || bit_len != tv[i].bitlen) - { - fprintf (stderr, "asn1_get_bit_der iter %lu, err: %d\n", - (unsigned long) i, result); - return 1; - } - } - - - /* Decode sample from "A Layman's Guide to a Subset of ASN.1, BER, - and DER" section 5.4 "BIT STRING": "The BER encoding of the BIT - STRING value "011011100101110111" can be any of the following, - among others, depending on the choice of padding bits, the form - of length octets [...]". - */ - - /* 03 04 06 6e 5d c0 DER encoding */ - - memcpy (der, "\x04\x06\x6e\x5d\xc0", 5); - der_len = 5; - - result = asn1_get_bit_der (der, der_len, &ret_len, str, str_size, &bit_len); - if (result != ASN1_SUCCESS || ret_len != 5 - || bit_len != 18 || memcmp (str, "\x6e\x5d\xc0", 3) != 0) - { - fprintf (stderr, "asn1_get_bit_der example\n"); - return 1; - } - - der_len = sizeof (der); - asn1_bit_der (str, bit_len, der, &der_len); - if (der_len != 5 || memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0) - { - fprintf (stderr, "asn1_bit_der example roundtrip\n"); - return 1; - } - - /* 03 04 06 6e 5d e0 padded with "100000" */ - - memcpy (der, "\x04\x06\x6e\x5d\xe0", 5); - der_len = 5; - - result = asn1_get_bit_der (der, der_len, &ret_len, str, str_size, &bit_len); - if (result != ASN1_SUCCESS || ret_len != 5 - || bit_len != 18 || memcmp (str, "\x6e\x5d\xe0", 3) != 0) - { - fprintf (stderr, "asn1_get_bit_der example padded\n"); - return 1; - } - - der_len = sizeof (der); - asn1_bit_der (str, bit_len, der, &der_len); - if (der_len != 5 || memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0) - { - fprintf (stderr, "asn1_bit_der example roundtrip\n"); - return 1; - } - - /* 03 81 04 06 6e 5d c0 long form of length octets */ - - memcpy (der, "\x81\x04\x06\x6e\x5d\xc0", 6); - der_len = 6; - - result = asn1_get_bit_der (der, der_len, &ret_len, str, str_size, &bit_len); - - if (result != ASN1_SUCCESS || ret_len != 6 - || bit_len != 18 || memcmp (str, "\x6e\x5d\xc0", 3) != 0) - { - fprintf (stderr, "asn1_get_bit_der example long form\n"); - return 1; - } - - der_len = sizeof (der); - asn1_bit_der (str, bit_len, der, &der_len); - if (der_len != 5 || memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0) - { - fprintf (stderr, "asn1_bit_der example roundtrip\n"); - return 1; - } - - return 0; -} diff --git a/grub-core/lib/libtasn1/tests/Test_strings.c b/grub-core/lib/libtasn1/tests/Test_strings.c deleted file mode 100644 index 27f7215e1..000000000 --- a/grub-core/lib/libtasn1/tests/Test_strings.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2012-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * 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 . - * - * Written by Simon Josefsson - * - */ - -#include -#include -#include - -#include "libtasn1.h" - -struct tv -{ - unsigned int etype; - unsigned int str_len; - const void *str; - unsigned int der_len; - const void *der; -}; - -static const struct tv tv[] = { - {ASN1_ETYPE_IA5_STRING, 20, - "\x63\x73\x63\x61\x40\x70\x61\x73\x73\x70\x6f\x72\x74\x2e\x67\x6f\x76\x2e\x67\x72", - 22, - "\x16\x14\x63\x73\x63\x61\x40\x70\x61\x73\x73\x70\x6f\x72\x74\x2e\x67\x6f\x76\x2e\x67\x72"}, - {ASN1_ETYPE_PRINTABLE_STRING, 5, "\x4e\x69\x6b\x6f\x73", - 7, "\x13\x05\x4e\x69\x6b\x6f\x73"}, - {ASN1_ETYPE_UTF8_STRING, 12, "Αττική", - 14, "\x0c\x0c\xce\x91\xcf\x84\xcf\x84\xce\xb9\xce\xba\xce\xae"}, - {ASN1_ETYPE_TELETEX_STRING, 15, - "\x53\x69\x6d\x6f\x6e\x20\x4a\x6f\x73\x65\x66\x73\x73\x6f\x6e", - 17, - "\x14\x0f\x53\x69\x6d\x6f\x6e\x20\x4a\x6f\x73\x65\x66\x73\x73\x6f\x6e"}, - {ASN1_ETYPE_OCTET_STRING, 36, - "\x30\x22\x80\x0F\x32\x30\x31\x31\x30\x38\x32\x31\x30\x38\x30\x30\x30\x36\x5A\x81\x0F\x32\x30\x31\x31\x30\x38\x32\x33\x32\x30\x35\x39\x35\x39\x5A", - 38, - "\x04\x24\x30\x22\x80\x0F\x32\x30\x31\x31\x30\x38\x32\x31\x30\x38\x30\x30\x30\x36\x5A\x81\x0F\x32\x30\x31\x31\x30\x38\x32\x33\x32\x30\x35\x39\x35\x39\x5A"} -}; - -#define SSTR(x) sizeof(x)-1,x -static const struct tv ber[] = { - {ASN1_ETYPE_OCTET_STRING, - SSTR ("\xa0\xa0"), - SSTR ("\x24\x80\x04\x82\x00\x02\xa0\xa0\x00\x00")}, - {ASN1_ETYPE_OCTET_STRING, - SSTR ("\xa0\xa0\xb0\xb0\xb0"), - SSTR - ("\x24\x80\x04\x82\x00\x02\xa0\xa0\x04\x82\x00\x03\xb0\xb0\xb0\x00\x00")}, - {ASN1_ETYPE_OCTET_STRING, - SSTR ("\xa0\xa0\xb0\xb0\xb0\xa1\xa1"), - SSTR - ("\x24\x80\x04\x82\x00\x02\xa0\xa0\x04\x82\x00\x03\xb0\xb0\xb0\x24\x80\x04\x82\x00\x02\xa1\xa1\x00\x00\x00\x00")}, - {ASN1_ETYPE_OCTET_STRING, - SSTR ("\xa0\xa0\xb0\xb0\xb0\xa1\xa1\xc1"), - SSTR - ("\x24\x80\x04\x82\x00\x02\xa0\xa0\x04\x82\x00\x03\xb0\xb0\xb0\x24\x80\x04\x82\x00\x02\xa1\xa1\x04\x82\x00\x01\xc1\x00\x00\x00\x00")}, -}; - -int -main (int argc, char *argv[]) -{ - int ret; - unsigned char tl[ASN1_MAX_TL_SIZE]; - unsigned int tl_len, der_len, str_len; - const unsigned char *str; - unsigned char *b; - unsigned int i; - - /* Dummy test */ - - for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) - { - /* Encode */ - tl_len = sizeof (tl); - ret = asn1_encode_simple_der (tv[i].etype, tv[i].str, tv[i].str_len, - tl, &tl_len); - if (ret != ASN1_SUCCESS) - { - fprintf (stderr, "Encoding error in %u: %s\n", i, - asn1_strerror (ret)); - return 1; - } - der_len = tl_len + tv[i].str_len; - - if (der_len != tv[i].der_len || memcmp (tl, tv[i].der, tl_len) != 0) - { - fprintf (stderr, - "DER encoding differs in %u! (size: %u, expected: %u)\n", - i, der_len, tv[i].der_len); - return 1; - } - - /* decoding */ - ret = - asn1_decode_simple_der (tv[i].etype, tv[i].der, tv[i].der_len, &str, - &str_len); - if (ret != ASN1_SUCCESS) - { - fprintf (stderr, "Decoding error in %u: %s\n", i, - asn1_strerror (ret)); - return 1; - } - - if (str_len != tv[i].str_len || memcmp (str, tv[i].str, str_len) != 0) - { - fprintf (stderr, - "DER decoded data differ in %u! (size: %u, expected: %u)\n", - i, der_len, tv[i].str_len); - return 1; - } - } - - /* BER decoding */ - for (i = 0; i < sizeof (ber) / sizeof (ber[0]); i++) - { - /* decoding */ - ret = - asn1_decode_simple_ber (ber[i].etype, ber[i].der, ber[i].der_len, &b, - &str_len, NULL); - if (ret != ASN1_SUCCESS) - { - fprintf (stderr, "BER decoding error in %u: %s\n", i, - asn1_strerror (ret)); - return 1; - } - - if (str_len != ber[i].str_len || memcmp (b, ber[i].str, str_len) != 0) - { - fprintf (stderr, - "BER decoded data differ in %u! (size: %u, expected: %u)\n", - i, str_len, ber[i].str_len); - return 1; - } - free (b); - } - - - return 0; -} diff --git a/grub-core/lib/libtasn1/tests/object-id-decoding.c b/grub-core/lib/libtasn1/tests/object-id-decoding.c deleted file mode 100644 index 06a6c52a2..000000000 --- a/grub-core/lib/libtasn1/tests/object-id-decoding.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2016 Red Hat, Inc. - * - * This file is part of LIBTASN1. - * - * 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 . - * - */ - -#include -#include -#include - -#include "libtasn1.h" - -struct tv -{ - int der_len; - const unsigned char *der; - const char *oid; - int expected_error; -}; - -static const struct tv tv[] = { - {.der_len = 5, - .der = (void *) "\x06\x03\x80\x37\x03", - .oid = "2.999.3", - .expected_error = ASN1_DER_ERROR /* leading 0x80 */ - }, - {.der_len = 12, - .der = (void *) "\x06\x0a\x2b\x06\x01\x80\x01\x92\x08\x09\x05\x01", - .oid = "1.3.6.1.4.1.2312.9.5.1", - .expected_error = ASN1_DER_ERROR /* leading 0x80 */ - }, - {.der_len = 6, - .der = (void *) "\x06\x04\x01\x02\x03\x04", - .oid = "0.1.2.3.4", - .expected_error = ASN1_SUCCESS}, - {.der_len = 5, - .der = (void *) "\x06\x03\x51\x02\x03", - .oid = "2.1.2.3", - .expected_error = ASN1_SUCCESS}, - {.der_len = 5, - .der = (void *) "\x06\x03\x88\x37\x03", - .oid = "2.999.3", - .expected_error = ASN1_SUCCESS}, - {.der_len = 12, - .der = (void *) "\x06\x0a\x2b\x06\x01\x04\x01\x92\x08\x09\x05\x01", - .oid = "1.3.6.1.4.1.2312.9.5.1", - .expected_error = ASN1_SUCCESS}, - {.der_len = 19, - .der = - (void *) - "\x06\x11\xfa\x80\x00\x00\x00\x0e\x01\x0e\xfa\x80\x00\x00\x00\x0e\x63\x6f\x6d", - .oid = "2.1998768.0.0.14.1.14.1998848.0.0.14.99.111.109", - .expected_error = ASN1_SUCCESS}, - {.der_len = 19, - .der = - (void *) - "\x06\x11\x2b\x06\x01\x04\x01\x92\x08\x09\x02\xaa\xda\xbe\xbe\xfa\x72\x01\x07", - .oid = "1.3.6.1.4.1.2312.9.2.1467399257458.1.7", - .expected_error = ASN1_SUCCESS}, -}; - -int -main (int argc, char *argv[]) -{ - char str[128]; - int ret, ret_len; - size_t i; - - for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) - { - /* decode */ - ret = - asn1_get_object_id_der (tv[i].der + 1, - tv[i].der_len - 1, &ret_len, str, - sizeof (str)); - if (ret != tv[i].expected_error) - { - fprintf (stderr, - "%d: asn1_get_object_id_der iter %lu: got '%s' expected %d\n", - __LINE__, (unsigned long) i, asn1_strerror (ret), - tv[i].expected_error); - return 1; - } - - if (tv[i].expected_error != ASN1_SUCCESS) - continue; - - if (ret_len != tv[i].der_len - 1) - { - fprintf (stderr, - "%d: iter %lu: error in DER, length returned is %d, had %d\n", - __LINE__, (unsigned long) i, ret_len, tv[i].der_len - 1); - return 1; - } - - if (strcmp (tv[i].oid, str) != 0) - { - fprintf (stderr, - "%d: strcmp iter %lu: got invalid OID: %s, expected: %s\n", - __LINE__, (unsigned long) i, str, tv[i].oid); - return 1; - } - - } - - return 0; -} diff --git a/grub-core/lib/libtasn1/tests/object-id-encoding.c b/grub-core/lib/libtasn1/tests/object-id-encoding.c deleted file mode 100644 index 1a3396986..000000000 --- a/grub-core/lib/libtasn1/tests/object-id-encoding.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2019 Nikos Mavrogiannopoulos - * - * This file is part of LIBTASN1. - * - * 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 . - * - */ - -#include -#include -#include - -#include "libtasn1.h" - -struct tv -{ - int der_len; - const unsigned char *der; - const char *oid; - int expected_error; -}; - -static const struct tv tv[] = { - {.der_len = 0, - .der = (void *) "", - .oid = "5.999.3", - .expected_error = ASN1_VALUE_NOT_VALID /* cannot start with 5 */ - }, - {.der_len = 0, - .der = (void *) "", - .oid = "0.48.9", - .expected_error = ASN1_VALUE_NOT_VALID /* second field cannot be 48 */ - }, - {.der_len = 0, - .der = (void *) "", - .oid = "1.40.9", - .expected_error = ASN1_VALUE_NOT_VALID /* second field cannot be 40 */ - }, - {.der_len = 4, - .der = (void *) "\x06\x02\x4f\x63", - .oid = "1.39.99", - .expected_error = ASN1_SUCCESS, - }, - {.der_len = 6, - .der = (void *) "\x06\x04\x01\x02\x03\x04", - .oid = "0.1.2.3.4", - .expected_error = ASN1_SUCCESS}, - {.der_len = 5, - .der = (void *) "\x06\x03\x51\x02\x03", - .oid = "2.1.2.3", - .expected_error = ASN1_SUCCESS}, - {.der_len = 5, - .der = (void *) "\x06\x03\x88\x37\x03", - .oid = "2.999.3", - .expected_error = ASN1_SUCCESS}, - {.der_len = 12, - .der = (void *) "\x06\x0a\x2b\x06\x01\x04\x01\x92\x08\x09\x05\x01", - .oid = "1.3.6.1.4.1.2312.9.5.1", - .expected_error = ASN1_SUCCESS}, - {.der_len = 19, - .der = - (void *) - "\x06\x11\xfa\x80\x00\x00\x00\x0e\x01\x0e\xfa\x80\x00\x00\x00\x0e\x63\x6f\x6d", - .oid = "2.1998768.0.0.14.1.14.1998848.0.0.14.99.111.109", - .expected_error = ASN1_SUCCESS}, - {.der_len = 19, - .der = - (void *) - "\x06\x11\x2b\x06\x01\x04\x01\x92\x08\x09\x02\xaa\xda\xbe\xbe\xfa\x72\x01\x07", - .oid = "1.3.6.1.4.1.2312.9.2.1467399257458.1.7", - .expected_error = ASN1_SUCCESS}, -}; - -int -main (int argc, char *argv[]) -{ - unsigned char der[128]; - int ret, der_len, i, j; - - for (i = 0; i < (int) (sizeof (tv) / sizeof (tv[0])); i++) - { - der_len = sizeof (der); - ret = asn1_object_id_der (tv[i].oid, der, &der_len, 0); - if (ret != ASN1_SUCCESS) - { - if (ret == tv[i].expected_error) - continue; - fprintf (stderr, - "%d: iter %lu, encoding of OID failed: %s\n", - __LINE__, (unsigned long) i, asn1_strerror (ret)); - return 1; - } - else if (ret != tv[i].expected_error) - { - fprintf (stderr, - "%d: iter %lu, encoding of OID %s succeeded when expecting failure\n", - __LINE__, (unsigned long) i, tv[i].oid); - return 1; - } - - if (der_len != tv[i].der_len || memcmp (der, tv[i].der, der_len) != 0) - { - fprintf (stderr, - "%d: iter %lu, re-encoding of OID %s resulted to different string (%d vs %d bytes)\n", - __LINE__, (unsigned long) i, tv[i].oid, der_len, - tv[i].der_len); - fprintf (stderr, "\nGot:\t\t"); - for (j = 0; j < der_len; j++) - fprintf (stderr, "%.2x", der[j]); - - fprintf (stderr, "\nExpected:\t"); - for (j = 0; j < tv[i].der_len; j++) - fprintf (stderr, "%.2x", tv[i].der[j]); - fprintf (stderr, "\n"); - - return 1; - } - } - - return 0; -} diff --git a/grub-core/lib/libtasn1/tests/octet-string.c b/grub-core/lib/libtasn1/tests/octet-string.c deleted file mode 100644 index 69eb18a62..000000000 --- a/grub-core/lib/libtasn1/tests/octet-string.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (C) 2011-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * 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 . - * - * Written by Simon Josefsson and Nikos Mavrogiannopoulos - * - */ - -#include -#include -#include - -#include "libtasn1.h" - -struct tv -{ - const char *name; - int der_len; - const unsigned char *der_str; - int len; - const unsigned char *string; - int expected_error; - int ber; -}; - -static const struct tv tv[] = { - {.name = "primitive octet strings", - .der_len = 10, - .der_str = (void *) "\x04\x08\x01\x23\x45\x67\x89\xab\xcd\xef", - .len = 8, - .string = (void *) "\x01\x23\x45\x67\x89\xab\xcd\xef", - .ber = 0}, - {.der_len = 22, - .der_str = - (void *) - "\x04\x14\x13\x00\xd9\xa8\x47\xf7\xf2\x1c\xf4\xb0\xec\x5f\xc1\x73\xe5\x1b\x25\xc2\x62\x27", - .len = 20, - .string = - (void *) - "\x13\x00\xD9\xA8\x47\xF7\xF2\x1C\xF4\xB0\xEC\x5F\xC1\x73\xE5\x1B\x25\xC2\x62\x27"}, - - {.name = "long type of length", - .der_len = 23, - .der_str = - (void *) - "\x04\x81\x14\x13\x00\xd9\xa8\x47\xf7\xf2\x1c\xf4\xb0\xec\x5f\xc1\x73\xe5\x1b\x25\xc2\x62\x27", - .len = 20, - .string = - (void *) - "\x13\x00\xD9\xA8\x47\xF7\xF2\x1C\xF4\xB0\xEC\x5F\xC1\x73\xE5\x1B\x25\xC2\x62\x27", - .ber = 1}, - {.der_len = 11, - .der_str = (void *) "\x04\x81\x08\x01\x23\x45\x67\x89\xab\xcd\xef", - .len = 8, - .string = (void *) "\x01\x23\x45\x67\x89\xab\xcd\xef", - .ber = 1}, - - {.name = "constructed - indefinite", - .der_len = 11, - .der_str = (void *) "\x24\x80\x04\x05\x01\x02\x03\x04\x05\x00\x00", - .len = 5, - .string = (void *) "\x01\x02\x03\x04\x05", - .ber = 1, - }, - - {.name = "constructed - definite - concat", - .der_len = 12, - .der_str = (void *) "\x24\x0a\x04\x04\x0a\x0b\x0c\x0d\x04\x02\x0e\x0f", - .len = 6, - .string = (void *) "\x0a\x0b\x0c\x0d\x0e\x0f", - .ber = 1, - }, - {.name = "constructed - definite - recursive", - .der_len = 15, - .der_str = - (void *) "\x24\x0d\x04\x04\x0a\x0b\x0c\x0d\x24\x05\x04\x00\x04\x01\x0f", - .len = 5, - .string = (void *) "\x0a\x0b\x0c\x0d\x0f", - .ber = 1, - }, - {.name = "constructed - definite - single", - .der_len = 7, - .der_str = (void *) "\x24\x05\x04\x03\x01\x02\x03", - .len = 3, - .string = (void *) "\x01\x02\x03", - .ber = 1, - }, - - /* a large amount of recursive indefinite encoding */ - {.name = "a large amount of recursive indefinite encoding", - .der_len = 29325, - .der_str = - (void *) - "\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80", - .len = 0, - .ber = 1, - .expected_error = ASN1_DER_ERROR} -}; - -int -main (int argc, char *argv[]) -{ - unsigned char str[100]; - unsigned char der[100]; - int der_len = sizeof (der); - int str_size = sizeof (str); - unsigned char *tmp = NULL; - int ret, ret_len, j; - size_t i; - - for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) - { - /* Decode */ - - if (tv[i].ber == 0) - { - str_size = sizeof (str); - ret = - asn1_get_octet_der (tv[i].der_str + 1, - tv[i].der_len - 1, &ret_len, str, - sizeof (str), &str_size); - if (ret != tv[i].expected_error) - { - fprintf (stderr, - "%d: asn1_get_octet_der: %s: got %d expected %d\n", - __LINE__, tv[i].name, ret, tv[i].expected_error); - return 1; - } - if (tv[i].expected_error) - continue; - - if (ret_len != tv[i].der_len - 1) - { - fprintf (stderr, - "%d: error in DER, length returned is %d, had %d\n", - __LINE__, ret_len, tv[i].der_len - 1); - return 1; - } - - if (str_size != tv[i].len - || memcmp (tv[i].string, str, tv[i].len) != 0) - { - fprintf (stderr, - "%d: memcmp: %s: got invalid decoding\n", - __LINE__, tv[i].name); - - fprintf (stderr, "\nGot:\t\t"); - for (j = 0; j < str_size; j++) - fprintf (stderr, "%.2x", str[j]); - - fprintf (stderr, "\nExpected:\t"); - for (j = 0; j < tv[i].len; j++) - fprintf (stderr, "%.2x", tv[i].string[j]); - fprintf (stderr, "\n"); - return 1; - } - - /* Encode */ - der_len = sizeof (der); - asn1_octet_der (str, str_size, der, &der_len); - - if (der_len != tv[i].der_len - 1 - || memcmp (tv[i].der_str + 1, der, tv[i].der_len - 1) != 0) - { - fprintf (stderr, - "encoding: %s: got invalid encoding\n", tv[i].name); - return 1; - } - } - - ret = - asn1_decode_simple_ber (ASN1_ETYPE_OCTET_STRING, - tv[i].der_str, tv[i].der_len, - &tmp, (unsigned int *) &str_size, - (unsigned int *) &der_len); - if (ret != tv[i].expected_error) - { - fprintf (stderr, - "%d: asn1_decode_simple_ber: %s: got %s expected %s\n", - __LINE__, tv[i].name, asn1_strerror (ret), - asn1_strerror (tv[i].expected_error)); - return 1; - } - if (tv[i].expected_error) - continue; - - if (der_len != tv[i].der_len) - { - fprintf (stderr, - "%d: error: %s: DER, length returned is %d, had %d\n", - __LINE__, tv[i].name, der_len, tv[i].der_len); - return 1; - } - - if (str_size != tv[i].len || memcmp (tv[i].string, tmp, tv[i].len) != 0) - { - fprintf (stderr, - "%d: memcmp: %s: got invalid decoding\n", - __LINE__, tv[i].name); - fprintf (stderr, "\nGot:\t\t"); - for (j = 0; j < str_size; j++) - fprintf (stderr, "%.2x", tmp[j]); - - fprintf (stderr, "\nExpected:\t"); - for (j = 0; j < tv[i].len; j++) - fprintf (stderr, "%.2x", tv[i].string[j]); - fprintf (stderr, "\n"); - return 1; - } - free (tmp); - tmp = NULL; - - } - - return 0; -} diff --git a/grub-core/lib/libtasn1/tests/reproducers.c b/grub-core/lib/libtasn1/tests/reproducers.c deleted file mode 100644 index a09d8b021..000000000 --- a/grub-core/lib/libtasn1/tests/reproducers.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2019-2022 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * 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 . - * - */ - -/****************************************************************/ -/* Description: run reproducers for several fixed issues */ -/****************************************************************/ - -#include -#include -#include - -#include - -#include - -/* produces endless loop (fixed by d4b624b2): - * The following translates into a single node with all pointers - * (right,left,down) set to NULL. */ -const asn1_static_node endless_asn1_tab[] = { - {"TEST_TREE", 536875024, NULL}, - {NULL, 0, NULL} -}; - -/* produces memory leak (fixed by f16d1ff9): - * 152 bytes in 1 blocks are definitely lost in loss record 1 of 1 - * at 0x4837B65: calloc (vg_replace_malloc.c:762) - * by 0x4851C0D: _asn1_add_static_node (parser_aux.c:71) - * by 0x4853AAC: asn1_array2tree (structure.c:200) - * by 0x10923B: main (single_node.c:67) - */ -const asn1_static_node tab[] = { - {"a", CONST_DOWN, ""}, - {"b", 0, ""}, - {"c", 0, ""}, - {NULL, 0, NULL} -}; - -int -main (int argc, char *argv[]) -{ - int result, verbose = 0; - asn1_node definitions = NULL; - char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; - - if (argc > 1) - verbose = 1; - - result = asn1_array2tree (endless_asn1_tab, &definitions, errorDescription); - if (result != ASN1_SUCCESS) - { - asn1_perror (result); - printf ("ErrorDescription = %s\n\n", errorDescription); - exit (EXIT_FAILURE); - } - - asn1_delete_structure (&definitions); - - definitions = NULL; - result = asn1_array2tree (tab, &definitions, errorDescription); - if (result != ASN1_SUCCESS) - { - asn1_perror (result); - printf ("ErrorDescription = %s\n\n", errorDescription); - exit (EXIT_FAILURE); - } - - asn1_delete_structure (&definitions); - - if (verbose) - printf ("Success\n"); - - exit (EXIT_SUCCESS); -} diff --git a/grub-core/lib/libtasn1_wrap/wrap.c b/grub-core/lib/libtasn1_wrap/wrap.c deleted file mode 100644 index fcada55a8..000000000 --- a/grub-core/lib/libtasn1_wrap/wrap.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2020 IBM Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -/* - * libtasn1 is provided under LGPL2.1+, which is compatible - * with GPL3+. As GRUB as a whole is under GPL3+, this module - * is therefore under GPL3+ also. - */ -GRUB_MOD_LICENSE ("GPLv3+"); diff --git a/grub-core/lib/loongarch64/setjmp.S b/grub-core/lib/loongarch64/setjmp.S deleted file mode 100644 index 2b46c41a3..000000000 --- a/grub-core/lib/loongarch64/setjmp.S +++ /dev/null @@ -1,69 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - - .file "setjmp.S" - -GRUB_MOD_LICENSE "GPLv3+" - - .text - -/* - * int grub_setjmp (jmp_buf env) - */ -FUNCTION(grub_setjmp) - st.d $s0, $a0, 0x0 - st.d $s1, $a0, 0x8 - st.d $s2, $a0, 0x10 - st.d $s3, $a0, 0x18 - st.d $s4, $a0, 0x20 - st.d $s5, $a0, 0x28 - st.d $s6, $a0, 0x30 - st.d $s7, $a0, 0x38 - st.d $s8, $a0, 0x40 - st.d $fp, $a0, 0x48 - st.d $sp, $a0, 0x50 - st.d $ra, $a0, 0x58 - - move $a0, $zero - jr $ra - -/* - * void grub_longjmp (jmp_buf env, int val) - */ -FUNCTION(grub_longjmp) - ld.d $s0, $a0, 0x0 - ld.d $s1, $a0, 0x8 - ld.d $s2, $a0, 0x10 - ld.d $s3, $a0, 0x18 - ld.d $s4, $a0, 0x20 - ld.d $s5, $a0, 0x28 - ld.d $s6, $a0, 0x30 - ld.d $s7, $a0, 0x38 - ld.d $s8, $a0, 0x40 - ld.d $fp, $a0, 0x48 - ld.d $sp, $a0, 0x50 - ld.d $ra, $a0, 0x58 - - /* Return 1 if passed 0, otherwise returns the value in place. */ - li.w $a0, 1 - beqz $a1, 1f - move $a0, $a1 -1: - jr $ra diff --git a/grub-core/lib/minilzo/lzoconf.h b/grub-core/lib/minilzo/lzoconf.h deleted file mode 100644 index f9a8bdbee..000000000 --- a/grub-core/lib/minilzo/lzoconf.h +++ /dev/null @@ -1,453 +0,0 @@ -/* lzoconf.h -- configuration of the LZO data compression library - - This file is part of the LZO real-time data compression library. - - Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer - All Rights Reserved. - - The LZO library is free software; you can 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. - - The LZO 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with the LZO library; see the file COPYING. - If not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - Markus F.X.J. Oberhumer - - http://www.oberhumer.com/opensource/lzo/ - */ - - -#ifndef __LZOCONF_H_INCLUDED -#define __LZOCONF_H_INCLUDED 1 - -#define LZO_VERSION 0x20a0 /* 2.10 */ -#define LZO_VERSION_STRING "2.10" -#define LZO_VERSION_DATE "Mar 01 2017" - -/* internal Autoconf configuration file - only used when building LZO */ -#if defined(LZO_HAVE_CONFIG_H) -# include -#endif -#include -#include - - -/*********************************************************************** -// LZO requires a conforming -************************************************************************/ - -#if !defined(CHAR_BIT) || (CHAR_BIT != 8) -# error "invalid CHAR_BIT" -#endif -#if !defined(UCHAR_MAX) || !defined(USHRT_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX) -# error "check your compiler installation" -#endif -#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1) -# error "your limits.h macros are broken" -#endif - -/* get OS and architecture defines */ -#ifndef __LZODEFS_H_INCLUDED -#include -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - - -/*********************************************************************** -// some core defines -************************************************************************/ - -/* memory checkers */ -#if !defined(__LZO_CHECKER) -# if defined(__BOUNDS_CHECKING_ON) -# define __LZO_CHECKER 1 -# elif defined(__CHECKER__) -# define __LZO_CHECKER 1 -# elif defined(__INSURE__) -# define __LZO_CHECKER 1 -# elif defined(__PURIFY__) -# define __LZO_CHECKER 1 -# endif -#endif - - -/*********************************************************************** -// integral and pointer types -************************************************************************/ - -/* lzo_uint must match size_t */ -#if !defined(LZO_UINT_MAX) -# if (LZO_ABI_LLP64) -# if (LZO_OS_WIN64) - typedef unsigned __int64 lzo_uint; - typedef __int64 lzo_int; -# define LZO_TYPEOF_LZO_INT LZO_TYPEOF___INT64 -# else - typedef lzo_ullong_t lzo_uint; - typedef lzo_llong_t lzo_int; -# define LZO_TYPEOF_LZO_INT LZO_TYPEOF_LONG_LONG -# endif -# define LZO_SIZEOF_LZO_INT 8 -# define LZO_UINT_MAX 0xffffffffffffffffull -# define LZO_INT_MAX 9223372036854775807LL -# define LZO_INT_MIN (-1LL - LZO_INT_MAX) -# elif (LZO_ABI_IP32L64) /* MIPS R5900 */ - typedef unsigned int lzo_uint; - typedef int lzo_int; -# define LZO_SIZEOF_LZO_INT LZO_SIZEOF_INT -# define LZO_TYPEOF_LZO_INT LZO_TYPEOF_INT -# define LZO_UINT_MAX UINT_MAX -# define LZO_INT_MAX INT_MAX -# define LZO_INT_MIN INT_MIN -# elif (ULONG_MAX >= LZO_0xffffffffL) - typedef unsigned long lzo_uint; - typedef long lzo_int; -# define LZO_SIZEOF_LZO_INT LZO_SIZEOF_LONG -# define LZO_TYPEOF_LZO_INT LZO_TYPEOF_LONG -# define LZO_UINT_MAX ULONG_MAX -# define LZO_INT_MAX LONG_MAX -# define LZO_INT_MIN LONG_MIN -# else -# error "lzo_uint" -# endif -#endif - -/* The larger type of lzo_uint and lzo_uint32_t. */ -#if (LZO_SIZEOF_LZO_INT >= 4) -# define lzo_xint lzo_uint -#else -# define lzo_xint lzo_uint32_t -#endif - -typedef int lzo_bool; - -/* sanity checks */ -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int) == LZO_SIZEOF_LZO_INT) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == LZO_SIZEOF_LZO_INT) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_xint) >= sizeof(lzo_uint)) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_xint) >= sizeof(lzo_uint32_t)) - -#ifndef __LZO_MMODEL -#define __LZO_MMODEL /*empty*/ -#endif - -/* no typedef here because of const-pointer issues */ -#define lzo_bytep unsigned char __LZO_MMODEL * -#define lzo_charp char __LZO_MMODEL * -#define lzo_voidp void __LZO_MMODEL * -#define lzo_shortp short __LZO_MMODEL * -#define lzo_ushortp unsigned short __LZO_MMODEL * -#define lzo_intp lzo_int __LZO_MMODEL * -#define lzo_uintp lzo_uint __LZO_MMODEL * -#define lzo_xintp lzo_xint __LZO_MMODEL * -#define lzo_voidpp lzo_voidp __LZO_MMODEL * -#define lzo_bytepp lzo_bytep __LZO_MMODEL * - -#define lzo_int8_tp lzo_int8_t __LZO_MMODEL * -#define lzo_uint8_tp lzo_uint8_t __LZO_MMODEL * -#define lzo_int16_tp lzo_int16_t __LZO_MMODEL * -#define lzo_uint16_tp lzo_uint16_t __LZO_MMODEL * -#define lzo_int32_tp lzo_int32_t __LZO_MMODEL * -#define lzo_uint32_tp lzo_uint32_t __LZO_MMODEL * -#if defined(lzo_int64_t) -#define lzo_int64_tp lzo_int64_t __LZO_MMODEL * -#define lzo_uint64_tp lzo_uint64_t __LZO_MMODEL * -#endif - -/* Older LZO versions used to support ancient systems and memory models - * such as 16-bit MSDOS with __huge pointers or Cray PVP, but these - * obsolete configurations are not supported any longer. - */ -#if defined(__LZO_MMODEL_HUGE) -#error "__LZO_MMODEL_HUGE memory model is unsupported" -#endif -#if (LZO_MM_PVP) -#error "LZO_MM_PVP memory model is unsupported" -#endif -#if (LZO_SIZEOF_INT < 4) -#error "LZO_SIZEOF_INT < 4 is unsupported" -#endif -#if (__LZO_UINTPTR_T_IS_POINTER) -#error "__LZO_UINTPTR_T_IS_POINTER is unsupported" -#endif -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) >= 4) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) >= 4) -/* Strange configurations where sizeof(lzo_uint) != sizeof(size_t) should - * work but have not received much testing lately, so be strict here. - */ -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(size_t)) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(ptrdiff_t)) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(lzo_uintptr_t)) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(void *) == sizeof(lzo_uintptr_t)) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(char *) == sizeof(lzo_uintptr_t)) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long *) == sizeof(lzo_uintptr_t)) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(void *) == sizeof(lzo_voidp)) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(char *) == sizeof(lzo_bytep)) - - -/*********************************************************************** -// function types -************************************************************************/ - -/* name mangling */ -#if !defined(__LZO_EXTERN_C) -# ifdef __cplusplus -# define __LZO_EXTERN_C extern "C" -# else -# define __LZO_EXTERN_C extern -# endif -#endif - -/* calling convention */ -#if !defined(__LZO_CDECL) -# define __LZO_CDECL __lzo_cdecl -#endif - -/* DLL export information */ -#if !defined(__LZO_EXPORT1) -# define __LZO_EXPORT1 /*empty*/ -#endif -#if !defined(__LZO_EXPORT2) -# define __LZO_EXPORT2 /*empty*/ -#endif - -/* __cdecl calling convention for public C and assembly functions */ -#if !defined(LZO_PUBLIC) -# define LZO_PUBLIC(r) __LZO_EXPORT1 r __LZO_EXPORT2 __LZO_CDECL -#endif -#if !defined(LZO_EXTERN) -# define LZO_EXTERN(r) __LZO_EXTERN_C LZO_PUBLIC(r) -#endif -#if !defined(LZO_PRIVATE) -# define LZO_PRIVATE(r) static r __LZO_CDECL -#endif - -/* function types */ -typedef int -(__LZO_CDECL *lzo_compress_t) ( const lzo_bytep src, lzo_uint src_len, - lzo_bytep dst, lzo_uintp dst_len, - lzo_voidp wrkmem ); - -typedef int -(__LZO_CDECL *lzo_decompress_t) ( const lzo_bytep src, lzo_uint src_len, - lzo_bytep dst, lzo_uintp dst_len, - lzo_voidp wrkmem ); - -typedef int -(__LZO_CDECL *lzo_optimize_t) ( lzo_bytep src, lzo_uint src_len, - lzo_bytep dst, lzo_uintp dst_len, - lzo_voidp wrkmem ); - -typedef int -(__LZO_CDECL *lzo_compress_dict_t)(const lzo_bytep src, lzo_uint src_len, - lzo_bytep dst, lzo_uintp dst_len, - lzo_voidp wrkmem, - const lzo_bytep dict, lzo_uint dict_len ); - -typedef int -(__LZO_CDECL *lzo_decompress_dict_t)(const lzo_bytep src, lzo_uint src_len, - lzo_bytep dst, lzo_uintp dst_len, - lzo_voidp wrkmem, - const lzo_bytep dict, lzo_uint dict_len ); - - -/* Callback interface. Currently only the progress indicator ("nprogress") - * is used, but this may change in a future release. */ - -struct lzo_callback_t; -typedef struct lzo_callback_t lzo_callback_t; -#define lzo_callback_p lzo_callback_t __LZO_MMODEL * - -/* malloc & free function types */ -typedef lzo_voidp (__LZO_CDECL *lzo_alloc_func_t) - (lzo_callback_p self, lzo_uint items, lzo_uint size); -typedef void (__LZO_CDECL *lzo_free_func_t) - (lzo_callback_p self, lzo_voidp ptr); - -/* a progress indicator callback function */ -typedef void (__LZO_CDECL *lzo_progress_func_t) - (lzo_callback_p, lzo_uint, lzo_uint, int); - -struct lzo_callback_t -{ - /* custom allocators (set to 0 to disable) */ - lzo_alloc_func_t nalloc; /* [not used right now] */ - lzo_free_func_t nfree; /* [not used right now] */ - - /* a progress indicator callback function (set to 0 to disable) */ - lzo_progress_func_t nprogress; - - /* INFO: the first parameter "self" of the nalloc/nfree/nprogress - * callbacks points back to this struct, so you are free to store - * some extra info in the following variables. */ - lzo_voidp user1; - lzo_xint user2; - lzo_xint user3; -}; - - -/*********************************************************************** -// error codes and prototypes -************************************************************************/ - -/* Error codes for the compression/decompression functions. Negative - * values are errors, positive values will be used for special but - * normal events. - */ -#define LZO_E_OK 0 -#define LZO_E_ERROR (-1) -#define LZO_E_OUT_OF_MEMORY (-2) /* [lzo_alloc_func_t failure] */ -#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */ -#define LZO_E_INPUT_OVERRUN (-4) -#define LZO_E_OUTPUT_OVERRUN (-5) -#define LZO_E_LOOKBEHIND_OVERRUN (-6) -#define LZO_E_EOF_NOT_FOUND (-7) -#define LZO_E_INPUT_NOT_CONSUMED (-8) -#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */ -#define LZO_E_INVALID_ARGUMENT (-10) -#define LZO_E_INVALID_ALIGNMENT (-11) /* pointer argument is not properly aligned */ -#define LZO_E_OUTPUT_NOT_CONSUMED (-12) -#define LZO_E_INTERNAL_ERROR (-99) - - -#ifndef lzo_sizeof_dict_t -# define lzo_sizeof_dict_t ((unsigned)sizeof(lzo_bytep)) -#endif - -/* lzo_init() should be the first function you call. - * Check the return code ! - * - * lzo_init() is a macro to allow checking that the library and the - * compiler's view of various types are consistent. - */ -#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\ - (int)sizeof(long),(int)sizeof(lzo_uint32_t),(int)sizeof(lzo_uint),\ - (int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\ - (int)sizeof(lzo_callback_t)) -LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int); - -/* version functions (useful for shared libraries) */ -LZO_EXTERN(unsigned) lzo_version(void); -LZO_EXTERN(const char *) lzo_version_string(void); -LZO_EXTERN(const char *) lzo_version_date(void); -LZO_EXTERN(const lzo_charp) _lzo_version_string(void); -LZO_EXTERN(const lzo_charp) _lzo_version_date(void); - -/* string functions */ -LZO_EXTERN(int) - lzo_memcmp(const lzo_voidp a, const lzo_voidp b, lzo_uint len); -LZO_EXTERN(lzo_voidp) - lzo_memcpy(lzo_voidp dst, const lzo_voidp src, lzo_uint len); -LZO_EXTERN(lzo_voidp) - lzo_memmove(lzo_voidp dst, const lzo_voidp src, lzo_uint len); -LZO_EXTERN(lzo_voidp) - lzo_memset(lzo_voidp buf, int c, lzo_uint len); - -/* checksum functions */ -LZO_EXTERN(lzo_uint32_t) - lzo_adler32(lzo_uint32_t c, const lzo_bytep buf, lzo_uint len); -LZO_EXTERN(lzo_uint32_t) - lzo_crc32(lzo_uint32_t c, const lzo_bytep buf, lzo_uint len); -LZO_EXTERN(const lzo_uint32_tp) - lzo_get_crc32_table(void); - -/* misc. */ -LZO_EXTERN(int) _lzo_config_check(void); -typedef union { - lzo_voidp a00; lzo_bytep a01; lzo_uint a02; lzo_xint a03; lzo_uintptr_t a04; - void *a05; unsigned char *a06; unsigned long a07; size_t a08; ptrdiff_t a09; -#if defined(lzo_int64_t) - lzo_uint64_t a10; -#endif -} lzo_align_t; - -/* align a char pointer on a boundary that is a multiple of 'size' */ -LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size); -#define LZO_PTR_ALIGN_UP(p,size) \ - ((p) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(p),(lzo_uint)(size))) - - -/*********************************************************************** -// deprecated macros - only for backward compatibility -************************************************************************/ - -/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */ -#define lzo_byte unsigned char -/* deprecated type names */ -#define lzo_int32 lzo_int32_t -#define lzo_uint32 lzo_uint32_t -#define lzo_int32p lzo_int32_t __LZO_MMODEL * -#define lzo_uint32p lzo_uint32_t __LZO_MMODEL * -#define LZO_INT32_MAX LZO_INT32_C(2147483647) -#define LZO_UINT32_MAX LZO_UINT32_C(4294967295) -#if defined(lzo_int64_t) -#define lzo_int64 lzo_int64_t -#define lzo_uint64 lzo_uint64_t -#define lzo_int64p lzo_int64_t __LZO_MMODEL * -#define lzo_uint64p lzo_uint64_t __LZO_MMODEL * -#define LZO_INT64_MAX LZO_INT64_C(9223372036854775807) -#define LZO_UINT64_MAX LZO_UINT64_C(18446744073709551615) -#endif -/* deprecated types */ -typedef union { lzo_bytep a; lzo_uint b; } __lzo_pu_u; -typedef union { lzo_bytep a; lzo_uint32_t b; } __lzo_pu32_u; -/* deprecated defines */ -#if !defined(LZO_SIZEOF_LZO_UINT) -# define LZO_SIZEOF_LZO_UINT LZO_SIZEOF_LZO_INT -#endif - -#if defined(LZO_CFG_COMPAT) - -#define __LZOCONF_H 1 - -#if defined(LZO_ARCH_I086) -# define __LZO_i386 1 -#elif defined(LZO_ARCH_I386) -# define __LZO_i386 1 -#endif - -#if defined(LZO_OS_DOS16) -# define __LZO_DOS 1 -# define __LZO_DOS16 1 -#elif defined(LZO_OS_DOS32) -# define __LZO_DOS 1 -#elif defined(LZO_OS_WIN16) -# define __LZO_WIN 1 -# define __LZO_WIN16 1 -#elif defined(LZO_OS_WIN32) -# define __LZO_WIN 1 -#endif - -#define __LZO_CMODEL /*empty*/ -#define __LZO_DMODEL /*empty*/ -#define __LZO_ENTRY __LZO_CDECL -#define LZO_EXTERN_CDECL LZO_EXTERN -#define LZO_ALIGN LZO_PTR_ALIGN_UP - -#define lzo_compress_asm_t lzo_compress_t -#define lzo_decompress_asm_t lzo_decompress_t - -#endif /* LZO_CFG_COMPAT */ - - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* already included */ - - -/* vim:set ts=4 sw=4 et: */ diff --git a/grub-core/lib/minilzo/lzodefs.h b/grub-core/lib/minilzo/lzodefs.h deleted file mode 100644 index c3e2bcf5d..000000000 --- a/grub-core/lib/minilzo/lzodefs.h +++ /dev/null @@ -1,3268 +0,0 @@ -/* lzodefs.h -- architecture, OS and compiler specific defines - - This file is part of the LZO real-time data compression library. - - Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer - All Rights Reserved. - - The LZO library is free software; you can 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. - - The LZO 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with the LZO library; see the file COPYING. - If not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - Markus F.X.J. Oberhumer - - http://www.oberhumer.com/opensource/lzo/ - */ - - -#ifndef __LZODEFS_H_INCLUDED -#define __LZODEFS_H_INCLUDED 1 - -#if defined(__CYGWIN32__) && !defined(__CYGWIN__) -# define __CYGWIN__ __CYGWIN32__ -#endif -#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) -# define _ALL_SOURCE 1 -#endif -#if defined(__mips__) && defined(__R5900__) -# if !defined(__LONG_MAX__) -# define __LONG_MAX__ 9223372036854775807L -# endif -#endif -#if 0 -#elif !defined(__LZO_LANG_OVERRIDE) -#if (defined(__clang__) || defined(__GNUC__)) && defined(__ASSEMBLER__) -# if (__ASSEMBLER__+0) <= 0 -# error "__ASSEMBLER__" -# else -# define LZO_LANG_ASSEMBLER 1 -# endif -#elif defined(__cplusplus) -# if (__cplusplus+0) <= 0 -# error "__cplusplus" -# elif (__cplusplus < 199711L) -# define LZO_LANG_CXX 1 -# elif defined(_MSC_VER) && defined(_MSVC_LANG) && (_MSVC_LANG+0 >= 201402L) && 1 -# define LZO_LANG_CXX _MSVC_LANG -# else -# define LZO_LANG_CXX __cplusplus -# endif -# define LZO_LANG_CPLUSPLUS LZO_LANG_CXX -#else -# if defined(__STDC_VERSION__) && (__STDC_VERSION__+0 >= 199409L) -# define LZO_LANG_C __STDC_VERSION__ -# else -# define LZO_LANG_C 1 -# endif -#endif -#endif -#if !defined(LZO_CFG_NO_DISABLE_WUNDEF) -#if defined(__ARMCC_VERSION) -# pragma diag_suppress 193 -#elif defined(__clang__) && defined(__clang_minor__) -# pragma clang diagnostic ignored "-Wundef" -#elif defined(__INTEL_COMPILER) -# pragma warning(disable: 193) -#elif defined(__KEIL__) && defined(__C166__) -# pragma warning disable = 322 -#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && !defined(__PATHSCALE__) -# if ((__GNUC__-0) >= 5 || ((__GNUC__-0) == 4 && (__GNUC_MINOR__-0) >= 2)) -# pragma GCC diagnostic ignored "-Wundef" -# endif -#elif defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) -# if ((_MSC_VER-0) >= 1300) -# pragma warning(disable: 4668) -# endif -#endif -#endif -#if 0 && defined(__POCC__) && defined(_WIN32) -# if (__POCC__ >= 400) -# pragma warn(disable: 2216) -# endif -#endif -#if 0 && defined(__WATCOMC__) -# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) -# pragma warning 203 9 -# endif -#endif -#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) -# pragma option -h -#endif -#if !(LZO_CFG_NO_DISABLE_WCRTNONSTDC) -#ifndef _CRT_NONSTDC_NO_DEPRECATE -#define _CRT_NONSTDC_NO_DEPRECATE 1 -#endif -#ifndef _CRT_NONSTDC_NO_WARNINGS -#define _CRT_NONSTDC_NO_WARNINGS 1 -#endif -#ifndef _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif -#ifndef _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_WARNINGS 1 -#endif -#endif -#if 0 -#define LZO_0xffffUL 0xfffful -#define LZO_0xffffffffUL 0xfffffffful -#else -#define LZO_0xffffUL 65535ul -#define LZO_0xffffffffUL 4294967295ul -#endif -#define LZO_0xffffL LZO_0xffffUL -#define LZO_0xffffffffL LZO_0xffffffffUL -#if (LZO_0xffffL == LZO_0xffffffffL) -# error "your preprocessor is broken 1" -#endif -#if (16ul * 16384ul != 262144ul) -# error "your preprocessor is broken 2" -#endif -#if 0 -#if (32767 >= 4294967295ul) -# error "your preprocessor is broken 3" -#endif -#if (65535u >= 4294967295ul) -# error "your preprocessor is broken 4" -#endif -#endif -#if defined(__COUNTER__) -# ifndef LZO_CFG_USE_COUNTER -# define LZO_CFG_USE_COUNTER 1 -# endif -#else -# undef LZO_CFG_USE_COUNTER -#endif -#if (UINT_MAX == LZO_0xffffL) -#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) -# if !defined(MSDOS) -# define MSDOS 1 -# endif -# if !defined(_MSDOS) -# define _MSDOS 1 -# endif -#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) -# if (__VERSION == 520) && (MB_LEN_MAX == 1) -# if !defined(__AZTEC_C__) -# define __AZTEC_C__ __VERSION -# endif -# if !defined(__DOS__) -# define __DOS__ 1 -# endif -# endif -#endif -#endif -#if (UINT_MAX == LZO_0xffffL) -#if defined(_MSC_VER) && defined(M_I86HM) -# define ptrdiff_t long -# define _PTRDIFF_T_DEFINED 1 -#endif -#endif -#if (UINT_MAX == LZO_0xffffL) -# undef __LZO_RENAME_A -# undef __LZO_RENAME_B -# if defined(__AZTEC_C__) && defined(__DOS__) -# define __LZO_RENAME_A 1 -# elif defined(_MSC_VER) && defined(MSDOS) -# if (_MSC_VER < 600) -# define __LZO_RENAME_A 1 -# elif (_MSC_VER < 700) -# define __LZO_RENAME_B 1 -# endif -# elif defined(__TSC__) && defined(__OS2__) -# define __LZO_RENAME_A 1 -# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) -# define __LZO_RENAME_A 1 -# elif defined(__PACIFIC__) && defined(DOS) -# if !defined(__far) -# define __far far -# endif -# if !defined(__near) -# define __near near -# endif -# endif -# if defined(__LZO_RENAME_A) -# if !defined(__cdecl) -# define __cdecl cdecl -# endif -# if !defined(__far) -# define __far far -# endif -# if !defined(__huge) -# define __huge huge -# endif -# if !defined(__near) -# define __near near -# endif -# if !defined(__pascal) -# define __pascal pascal -# endif -# if !defined(__huge) -# define __huge huge -# endif -# elif defined(__LZO_RENAME_B) -# if !defined(__cdecl) -# define __cdecl _cdecl -# endif -# if !defined(__far) -# define __far _far -# endif -# if !defined(__huge) -# define __huge _huge -# endif -# if !defined(__near) -# define __near _near -# endif -# if !defined(__pascal) -# define __pascal _pascal -# endif -# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) -# if !defined(__cdecl) -# define __cdecl cdecl -# endif -# if !defined(__pascal) -# define __pascal pascal -# endif -# endif -# undef __LZO_RENAME_A -# undef __LZO_RENAME_B -#endif -#if (UINT_MAX == LZO_0xffffL) -#if defined(__AZTEC_C__) && defined(__DOS__) -# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 -#elif defined(_MSC_VER) && defined(MSDOS) -# if (_MSC_VER < 600) -# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 -# endif -# if (_MSC_VER < 700) -# define LZO_BROKEN_INTEGRAL_PROMOTION 1 -# define LZO_BROKEN_SIZEOF 1 -# endif -#elif defined(__PACIFIC__) && defined(DOS) -# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 -#elif defined(__TURBOC__) && defined(__MSDOS__) -# if (__TURBOC__ < 0x0150) -# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 -# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 -# define LZO_BROKEN_INTEGRAL_PROMOTION 1 -# endif -# if (__TURBOC__ < 0x0200) -# define LZO_BROKEN_SIZEOF 1 -# endif -# if (__TURBOC__ < 0x0400) && defined(__cplusplus) -# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 -# endif -#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) -# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 -# define LZO_BROKEN_SIZEOF 1 -#endif -#endif -#if defined(__WATCOMC__) && (__WATCOMC__ < 900) -# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 -#endif -#if defined(_CRAY) && defined(_CRAY1) -# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 -#endif -#define LZO_PP_STRINGIZE(x) #x -#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) -#define LZO_PP_CONCAT0() /*empty*/ -#define LZO_PP_CONCAT1(a) a -#define LZO_PP_CONCAT2(a,b) a ## b -#define LZO_PP_CONCAT3(a,b,c) a ## b ## c -#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d -#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e -#define LZO_PP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f -#define LZO_PP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g -#define LZO_PP_ECONCAT0() LZO_PP_CONCAT0() -#define LZO_PP_ECONCAT1(a) LZO_PP_CONCAT1(a) -#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) -#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) -#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) -#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) -#define LZO_PP_ECONCAT6(a,b,c,d,e,f) LZO_PP_CONCAT6(a,b,c,d,e,f) -#define LZO_PP_ECONCAT7(a,b,c,d,e,f,g) LZO_PP_CONCAT7(a,b,c,d,e,f,g) -#define LZO_PP_EMPTY /*empty*/ -#define LZO_PP_EMPTY0() /*empty*/ -#define LZO_PP_EMPTY1(a) /*empty*/ -#define LZO_PP_EMPTY2(a,b) /*empty*/ -#define LZO_PP_EMPTY3(a,b,c) /*empty*/ -#define LZO_PP_EMPTY4(a,b,c,d) /*empty*/ -#define LZO_PP_EMPTY5(a,b,c,d,e) /*empty*/ -#define LZO_PP_EMPTY6(a,b,c,d,e,f) /*empty*/ -#define LZO_PP_EMPTY7(a,b,c,d,e,f,g) /*empty*/ -#if 1 -#define LZO_CPP_STRINGIZE(x) #x -#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) -#define LZO_CPP_CONCAT2(a,b) a ## b -#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c -#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d -#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e -#define LZO_CPP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f -#define LZO_CPP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g -#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) -#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) -#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) -#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) -#define LZO_CPP_ECONCAT6(a,b,c,d,e,f) LZO_CPP_CONCAT6(a,b,c,d,e,f) -#define LZO_CPP_ECONCAT7(a,b,c,d,e,f,g) LZO_CPP_CONCAT7(a,b,c,d,e,f,g) -#endif -#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-((b)!=0))) - (o)) << 1) + (o)*((b)!=0)) -#if 1 && defined(__cplusplus) -# if !defined(__STDC_CONSTANT_MACROS) -# define __STDC_CONSTANT_MACROS 1 -# endif -# if !defined(__STDC_LIMIT_MACROS) -# define __STDC_LIMIT_MACROS 1 -# endif -#endif -#if defined(__cplusplus) -# define LZO_EXTERN_C extern "C" -# define LZO_EXTERN_C_BEGIN extern "C" { -# define LZO_EXTERN_C_END } -#else -# define LZO_EXTERN_C extern -# define LZO_EXTERN_C_BEGIN /*empty*/ -# define LZO_EXTERN_C_END /*empty*/ -#endif -#if !defined(__LZO_OS_OVERRIDE) -#if (LZO_OS_FREESTANDING) -# define LZO_INFO_OS "freestanding" -#elif (LZO_OS_EMBEDDED) -# define LZO_INFO_OS "embedded" -#elif 1 && defined(__IAR_SYSTEMS_ICC__) -# define LZO_OS_EMBEDDED 1 -# define LZO_INFO_OS "embedded" -#elif defined(__CYGWIN__) && defined(__GNUC__) -# define LZO_OS_CYGWIN 1 -# define LZO_INFO_OS "cygwin" -#elif defined(__EMX__) && defined(__GNUC__) -# define LZO_OS_EMX 1 -# define LZO_INFO_OS "emx" -#elif defined(__BEOS__) -# define LZO_OS_BEOS 1 -# define LZO_INFO_OS "beos" -#elif defined(__Lynx__) -# define LZO_OS_LYNXOS 1 -# define LZO_INFO_OS "lynxos" -#elif defined(__OS400__) -# define LZO_OS_OS400 1 -# define LZO_INFO_OS "os400" -#elif defined(__QNX__) -# define LZO_OS_QNX 1 -# define LZO_INFO_OS "qnx" -#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) -# define LZO_OS_DOS32 1 -# define LZO_INFO_OS "dos32" -#elif defined(__BORLANDC__) && defined(__DPMI16__) -# define LZO_OS_DOS16 1 -# define LZO_INFO_OS "dos16" -#elif defined(__ZTC__) && defined(DOS386) -# define LZO_OS_DOS32 1 -# define LZO_INFO_OS "dos32" -#elif defined(__OS2__) || defined(__OS2V2__) -# if (UINT_MAX == LZO_0xffffL) -# define LZO_OS_OS216 1 -# define LZO_INFO_OS "os216" -# elif (UINT_MAX == LZO_0xffffffffL) -# define LZO_OS_OS2 1 -# define LZO_INFO_OS "os2" -# else -# error "check your limits.h header" -# endif -#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) -# define LZO_OS_WIN64 1 -# define LZO_INFO_OS "win64" -#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) -# define LZO_OS_WIN32 1 -# define LZO_INFO_OS "win32" -#elif defined(__MWERKS__) && defined(__INTEL__) -# define LZO_OS_WIN32 1 -# define LZO_INFO_OS "win32" -#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) -# if (UINT_MAX == LZO_0xffffL) -# define LZO_OS_WIN16 1 -# define LZO_INFO_OS "win16" -# elif (UINT_MAX == LZO_0xffffffffL) -# define LZO_OS_WIN32 1 -# define LZO_INFO_OS "win32" -# else -# error "check your limits.h header" -# endif -#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) -# if (UINT_MAX == LZO_0xffffL) -# define LZO_OS_DOS16 1 -# define LZO_INFO_OS "dos16" -# elif (UINT_MAX == LZO_0xffffffffL) -# define LZO_OS_DOS32 1 -# define LZO_INFO_OS "dos32" -# else -# error "check your limits.h header" -# endif -#elif defined(__WATCOMC__) -# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) -# define LZO_OS_DOS16 1 -# define LZO_INFO_OS "dos16" -# elif defined(__NT__) && (__WATCOMC__ < 1100) -# define LZO_OS_WIN32 1 -# define LZO_INFO_OS "win32" -# elif defined(__linux__) || defined(__LINUX__) -# define LZO_OS_POSIX 1 -# define LZO_INFO_OS "posix" -# else -# error "please specify a target using the -bt compiler option" -# endif -#elif defined(__palmos__) -# define LZO_OS_PALMOS 1 -# define LZO_INFO_OS "palmos" -#elif defined(__TOS__) || defined(__atarist__) -# define LZO_OS_TOS 1 -# define LZO_INFO_OS "tos" -#elif defined(macintosh) && !defined(__arm__) && !defined(__i386__) && !defined(__ppc__) && !defined(__x64_64__) -# define LZO_OS_MACCLASSIC 1 -# define LZO_INFO_OS "macclassic" -#elif defined(__VMS) -# define LZO_OS_VMS 1 -# define LZO_INFO_OS "vms" -#elif (defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__) -# define LZO_OS_CONSOLE 1 -# define LZO_OS_CONSOLE_PS2 1 -# define LZO_INFO_OS "console" -# define LZO_INFO_OS_CONSOLE "ps2" -#elif defined(__mips__) && defined(__psp__) -# define LZO_OS_CONSOLE 1 -# define LZO_OS_CONSOLE_PSP 1 -# define LZO_INFO_OS "console" -# define LZO_INFO_OS_CONSOLE "psp" -#else -# define LZO_OS_POSIX 1 -# define LZO_INFO_OS "posix" -#endif -#if (LZO_OS_POSIX) -# if defined(_AIX) || defined(__AIX__) || defined(__aix__) -# define LZO_OS_POSIX_AIX 1 -# define LZO_INFO_OS_POSIX "aix" -# elif defined(__FreeBSD__) -# define LZO_OS_POSIX_FREEBSD 1 -# define LZO_INFO_OS_POSIX "freebsd" -# elif defined(__hpux__) || defined(__hpux) -# define LZO_OS_POSIX_HPUX 1 -# define LZO_INFO_OS_POSIX "hpux" -# elif defined(__INTERIX) -# define LZO_OS_POSIX_INTERIX 1 -# define LZO_INFO_OS_POSIX "interix" -# elif defined(__IRIX__) || defined(__irix__) -# define LZO_OS_POSIX_IRIX 1 -# define LZO_INFO_OS_POSIX "irix" -# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) -# define LZO_OS_POSIX_LINUX 1 -# define LZO_INFO_OS_POSIX "linux" -# elif defined(__APPLE__) && defined(__MACH__) -# if ((__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__-0) >= 20000) -# define LZO_OS_POSIX_DARWIN 1040 -# define LZO_INFO_OS_POSIX "darwin_iphone" -# elif ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) >= 1040) -# define LZO_OS_POSIX_DARWIN __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ -# define LZO_INFO_OS_POSIX "darwin" -# else -# define LZO_OS_POSIX_DARWIN 1 -# define LZO_INFO_OS_POSIX "darwin" -# endif -# define LZO_OS_POSIX_MACOSX LZO_OS_POSIX_DARWIN -# elif defined(__minix__) || defined(__minix) -# define LZO_OS_POSIX_MINIX 1 -# define LZO_INFO_OS_POSIX "minix" -# elif defined(__NetBSD__) -# define LZO_OS_POSIX_NETBSD 1 -# define LZO_INFO_OS_POSIX "netbsd" -# elif defined(__OpenBSD__) -# define LZO_OS_POSIX_OPENBSD 1 -# define LZO_INFO_OS_POSIX "openbsd" -# elif defined(__osf__) -# define LZO_OS_POSIX_OSF 1 -# define LZO_INFO_OS_POSIX "osf" -# elif defined(__solaris__) || defined(__sun) -# if defined(__SVR4) || defined(__svr4__) -# define LZO_OS_POSIX_SOLARIS 1 -# define LZO_INFO_OS_POSIX "solaris" -# else -# define LZO_OS_POSIX_SUNOS 1 -# define LZO_INFO_OS_POSIX "sunos" -# endif -# elif defined(__ultrix__) || defined(__ultrix) -# define LZO_OS_POSIX_ULTRIX 1 -# define LZO_INFO_OS_POSIX "ultrix" -# elif defined(_UNICOS) -# define LZO_OS_POSIX_UNICOS 1 -# define LZO_INFO_OS_POSIX "unicos" -# else -# define LZO_OS_POSIX_UNKNOWN 1 -# define LZO_INFO_OS_POSIX "unknown" -# endif -#endif -#endif -#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) -# if (UINT_MAX != LZO_0xffffL) -# error "unexpected configuration - check your compiler defines" -# endif -# if (ULONG_MAX != LZO_0xffffffffL) -# error "unexpected configuration - check your compiler defines" -# endif -#endif -#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) -# if (UINT_MAX != LZO_0xffffffffL) -# error "unexpected configuration - check your compiler defines" -# endif -# if (ULONG_MAX != LZO_0xffffffffL) -# error "unexpected configuration - check your compiler defines" -# endif -#endif -#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) -# define LZO_CC_CILLY 1 -# define LZO_INFO_CC "Cilly" -# if defined(__CILLY__) -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) -# else -# define LZO_INFO_CCVER "unknown" -# endif -#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) -# define LZO_CC_SDCC 1 -# define LZO_INFO_CC "sdcc" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) -#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) -# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + (__PATHCC_MINOR__-0) * 0x100 + (__PATHCC_PATCHLEVEL__-0)) -# define LZO_INFO_CC "Pathscale C" -# define LZO_INFO_CCVER __PATHSCALE__ -# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) -# define LZO_CC_PATHSCALE_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) -# endif -#elif defined(__INTEL_COMPILER) && ((__INTEL_COMPILER-0) > 0) -# define LZO_CC_INTELC __INTEL_COMPILER -# define LZO_INFO_CC "Intel C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) -# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) -# define LZO_CC_INTELC_MSC _MSC_VER -# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) -# define LZO_CC_INTELC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) -# endif -#elif defined(__POCC__) && defined(_WIN32) -# define LZO_CC_PELLESC 1 -# define LZO_INFO_CC "Pelles C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) -#elif defined(__ARMCC_VERSION) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) -# if defined(__GNUC_PATCHLEVEL__) -# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) -# else -# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) -# endif -# define LZO_CC_ARMCC __ARMCC_VERSION -# define LZO_INFO_CC "ARM C Compiler" -# define LZO_INFO_CCVER __VERSION__ -#elif defined(__clang__) && defined(__c2__) && defined(__c2_version__) && defined(_MSC_VER) -# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) -# define LZO_CC_CLANG_C2 _MSC_VER -# define LZO_CC_CLANG_VENDOR_MICROSOFT 1 -# define LZO_INFO_CC "clang/c2" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__c2_version__) -#elif defined(__clang__) && defined(__llvm__) && defined(__VERSION__) -# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) -# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) -# else -# define LZO_CC_CLANG 0x010000L -# endif -# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) -# define LZO_CC_CLANG_MSC _MSC_VER -# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) -# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) -# endif -# if defined(__APPLE_CC__) -# define LZO_CC_CLANG_VENDOR_APPLE 1 -# define LZO_INFO_CC "clang/apple" -# else -# define LZO_CC_CLANG_VENDOR_LLVM 1 -# define LZO_INFO_CC "clang" -# endif -# if defined(__clang_version__) -# define LZO_INFO_CCVER __clang_version__ -# else -# define LZO_INFO_CCVER __VERSION__ -# endif -#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) -# if defined(__GNUC_PATCHLEVEL__) -# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) -# else -# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) -# endif -# define LZO_CC_LLVM LZO_CC_LLVM_GNUC -# define LZO_INFO_CC "llvm-gcc" -# define LZO_INFO_CCVER __VERSION__ -#elif defined(__ACK__) && defined(_ACK) -# define LZO_CC_ACK 1 -# define LZO_INFO_CC "Amsterdam Compiler Kit C" -# define LZO_INFO_CCVER "unknown" -#elif defined(__ARMCC_VERSION) && !defined(__GNUC__) -# define LZO_CC_ARMCC __ARMCC_VERSION -# define LZO_CC_ARMCC_ARMCC __ARMCC_VERSION -# define LZO_INFO_CC "ARM C Compiler" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ARMCC_VERSION) -#elif defined(__AZTEC_C__) -# define LZO_CC_AZTECC 1 -# define LZO_INFO_CC "Aztec C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) -#elif defined(__CODEGEARC__) -# define LZO_CC_CODEGEARC 1 -# define LZO_INFO_CC "CodeGear C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CODEGEARC__) -#elif defined(__BORLANDC__) -# define LZO_CC_BORLANDC 1 -# define LZO_INFO_CC "Borland C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) -#elif defined(_CRAYC) && defined(_RELEASE) -# define LZO_CC_CRAYC 1 -# define LZO_INFO_CC "Cray C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) -#elif defined(__DMC__) && defined(__SC__) -# define LZO_CC_DMC 1 -# define LZO_INFO_CC "Digital Mars C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) -#elif defined(__DECC) -# define LZO_CC_DECC 1 -# define LZO_INFO_CC "DEC C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) -#elif (defined(__ghs) || defined(__ghs__)) && defined(__GHS_VERSION_NUMBER) && ((__GHS_VERSION_NUMBER-0) > 0) -# define LZO_CC_GHS 1 -# define LZO_INFO_CC "Green Hills C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__GHS_VERSION_NUMBER) -# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) -# define LZO_CC_GHS_MSC _MSC_VER -# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) -# define LZO_CC_GHS_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) -# endif -#elif defined(__HIGHC__) -# define LZO_CC_HIGHC 1 -# define LZO_INFO_CC "MetaWare High C" -# define LZO_INFO_CCVER "unknown" -#elif defined(__HP_aCC) && ((__HP_aCC-0) > 0) -# define LZO_CC_HPACC __HP_aCC -# define LZO_INFO_CC "HP aCC" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__HP_aCC) -#elif defined(__IAR_SYSTEMS_ICC__) -# define LZO_CC_IARC 1 -# define LZO_INFO_CC "IAR C" -# if defined(__VER__) -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) -# else -# define LZO_INFO_CCVER "unknown" -# endif -#elif defined(__IBMC__) && ((__IBMC__-0) > 0) -# define LZO_CC_IBMC __IBMC__ -# define LZO_INFO_CC "IBM C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) -#elif defined(__IBMCPP__) && ((__IBMCPP__-0) > 0) -# define LZO_CC_IBMC __IBMCPP__ -# define LZO_INFO_CC "IBM C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMCPP__) -#elif defined(__KEIL__) && defined(__C166__) -# define LZO_CC_KEILC 1 -# define LZO_INFO_CC "Keil C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) -#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) -# define LZO_CC_LCCWIN32 1 -# define LZO_INFO_CC "lcc-win32" -# define LZO_INFO_CCVER "unknown" -#elif defined(__LCC__) -# define LZO_CC_LCC 1 -# define LZO_INFO_CC "lcc" -# if defined(__LCC_VERSION__) -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) -# else -# define LZO_INFO_CCVER "unknown" -# endif -#elif defined(__MWERKS__) && ((__MWERKS__-0) > 0) -# define LZO_CC_MWERKS __MWERKS__ -# define LZO_INFO_CC "Metrowerks C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) -#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) -# define LZO_CC_NDPC 1 -# define LZO_INFO_CC "Microway NDP C" -# define LZO_INFO_CCVER "unknown" -#elif defined(__PACIFIC__) -# define LZO_CC_PACIFICC 1 -# define LZO_INFO_CC "Pacific C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) -#elif defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) -# if defined(__PGIC_PATCHLEVEL__) -# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100 + (__PGIC_PATCHLEVEL__-0)) -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) "." LZO_PP_MACRO_EXPAND(__PGIC_PATCHLEVEL__) -# else -# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100) -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) ".0" -# endif -# define LZO_INFO_CC "Portland Group PGI C" -#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) -# define LZO_CC_PGI 1 -# define LZO_INFO_CC "Portland Group PGI C" -# define LZO_INFO_CCVER "unknown" -#elif defined(__PUREC__) && defined(__TOS__) -# define LZO_CC_PUREC 1 -# define LZO_INFO_CC "Pure C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) -#elif defined(__SC__) && defined(__ZTC__) -# define LZO_CC_SYMANTECC 1 -# define LZO_INFO_CC "Symantec C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) -#elif defined(__SUNPRO_C) -# define LZO_INFO_CC "SunPro C" -# if ((__SUNPRO_C-0) > 0) -# define LZO_CC_SUNPROC __SUNPRO_C -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) -# else -# define LZO_CC_SUNPROC 1 -# define LZO_INFO_CCVER "unknown" -# endif -#elif defined(__SUNPRO_CC) -# define LZO_INFO_CC "SunPro C" -# if ((__SUNPRO_CC-0) > 0) -# define LZO_CC_SUNPROC __SUNPRO_CC -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) -# else -# define LZO_CC_SUNPROC 1 -# define LZO_INFO_CCVER "unknown" -# endif -#elif defined(__TINYC__) -# define LZO_CC_TINYC 1 -# define LZO_INFO_CC "Tiny C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) -#elif defined(__TSC__) -# define LZO_CC_TOPSPEEDC 1 -# define LZO_INFO_CC "TopSpeed C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) -#elif defined(__WATCOMC__) -# define LZO_CC_WATCOMC 1 -# define LZO_INFO_CC "Watcom C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) -#elif defined(__TURBOC__) -# define LZO_CC_TURBOC 1 -# define LZO_INFO_CC "Turbo C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) -#elif defined(__ZTC__) -# define LZO_CC_ZORTECHC 1 -# define LZO_INFO_CC "Zortech C" -# if ((__ZTC__-0) == 0x310) -# define LZO_INFO_CCVER "0x310" -# else -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) -# endif -#elif defined(__GNUC__) && defined(__VERSION__) -# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) -# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) -# elif defined(__GNUC_MINOR__) -# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) -# else -# define LZO_CC_GNUC (__GNUC__ * 0x10000L) -# endif -# define LZO_INFO_CC "gcc" -# define LZO_INFO_CCVER __VERSION__ -#elif defined(_MSC_VER) && ((_MSC_VER-0) > 0) -# define LZO_CC_MSC _MSC_VER -# define LZO_INFO_CC "Microsoft C" -# if defined(_MSC_FULL_VER) -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) -# else -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) -# endif -#else -# define LZO_CC_UNKNOWN 1 -# define LZO_INFO_CC "unknown" -# define LZO_INFO_CCVER "unknown" -#endif -#if (LZO_CC_GNUC) && defined(__OPEN64__) -# if defined(__OPENCC__) && defined(__OPENCC_MINOR__) && defined(__OPENCC_PATCHLEVEL__) -# define LZO_CC_OPEN64 (__OPENCC__ * 0x10000L + (__OPENCC_MINOR__-0) * 0x100 + (__OPENCC_PATCHLEVEL__-0)) -# define LZO_CC_OPEN64_GNUC LZO_CC_GNUC -# endif -#endif -#if (LZO_CC_GNUC) && defined(__PCC__) -# if defined(__PCC__) && defined(__PCC_MINOR__) && defined(__PCC_MINORMINOR__) -# define LZO_CC_PCC (__PCC__ * 0x10000L + (__PCC_MINOR__-0) * 0x100 + (__PCC_MINORMINOR__-0)) -# define LZO_CC_PCC_GNUC LZO_CC_GNUC -# endif -#endif -#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) -# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" -#endif -#if !defined(__LZO_ARCH_OVERRIDE) && !(LZO_ARCH_GENERIC) && defined(_CRAY) -# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) -# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) -# define LZO_ARCH_CRAY_MPP 1 -# elif defined(_CRAY1) -# define LZO_ARCH_CRAY_PVP 1 -# endif -# endif -#endif -#if !defined(__LZO_ARCH_OVERRIDE) -#if (LZO_ARCH_GENERIC) -# define LZO_INFO_ARCH "generic" -#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) -# define LZO_ARCH_I086 1 -# define LZO_INFO_ARCH "i086" -#elif defined(__aarch64__) || defined(_M_ARM64) -# define LZO_ARCH_ARM64 1 -# define LZO_INFO_ARCH "arm64" -#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) -# define LZO_ARCH_ALPHA 1 -# define LZO_INFO_ARCH "alpha" -#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) -# define LZO_ARCH_ALPHA 1 -# define LZO_INFO_ARCH "alpha" -#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) -# define LZO_ARCH_AMD64 1 -# define LZO_INFO_ARCH "amd64" -#elif defined(__arm__) || defined(_M_ARM) -# define LZO_ARCH_ARM 1 -# define LZO_INFO_ARCH "arm" -#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) -# define LZO_ARCH_ARM 1 -# define LZO_INFO_ARCH "arm" -#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) -# define LZO_ARCH_AVR 1 -# define LZO_INFO_ARCH "avr" -#elif defined(__avr32__) || defined(__AVR32__) -# define LZO_ARCH_AVR32 1 -# define LZO_INFO_ARCH "avr32" -#elif defined(__bfin__) -# define LZO_ARCH_BLACKFIN 1 -# define LZO_INFO_ARCH "blackfin" -#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) -# define LZO_ARCH_C166 1 -# define LZO_INFO_ARCH "c166" -#elif defined(__cris__) -# define LZO_ARCH_CRIS 1 -# define LZO_INFO_ARCH "cris" -#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) -# define LZO_ARCH_EZ80 1 -# define LZO_INFO_ARCH "ez80" -#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) -# define LZO_ARCH_H8300 1 -# define LZO_INFO_ARCH "h8300" -#elif defined(__hppa__) || defined(__hppa) -# define LZO_ARCH_HPPA 1 -# define LZO_INFO_ARCH "hppa" -#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) -# define LZO_ARCH_I386 1 -# define LZO_ARCH_IA32 1 -# define LZO_INFO_ARCH "i386" -#elif (LZO_CC_ZORTECHC && defined(__I86__)) -# define LZO_ARCH_I386 1 -# define LZO_ARCH_IA32 1 -# define LZO_INFO_ARCH "i386" -#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) -# define LZO_ARCH_I386 1 -# define LZO_ARCH_IA32 1 -# define LZO_INFO_ARCH "i386" -#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) -# define LZO_ARCH_IA64 1 -# define LZO_INFO_ARCH "ia64" -#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) -# define LZO_ARCH_M16C 1 -# define LZO_INFO_ARCH "m16c" -#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) -# define LZO_ARCH_M16C 1 -# define LZO_INFO_ARCH "m16c" -#elif defined(__m32r__) -# define LZO_ARCH_M32R 1 -# define LZO_INFO_ARCH "m32r" -#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) -# define LZO_ARCH_M68K 1 -# define LZO_INFO_ARCH "m68k" -#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) -# define LZO_ARCH_MCS251 1 -# define LZO_INFO_ARCH "mcs251" -#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) -# define LZO_ARCH_MCS51 1 -# define LZO_INFO_ARCH "mcs51" -#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) -# define LZO_ARCH_MCS51 1 -# define LZO_INFO_ARCH "mcs51" -#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) -# define LZO_ARCH_MIPS 1 -# define LZO_INFO_ARCH "mips" -#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) -# define LZO_ARCH_MSP430 1 -# define LZO_INFO_ARCH "msp430" -#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) -# define LZO_ARCH_MSP430 1 -# define LZO_INFO_ARCH "msp430" -#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) -# define LZO_ARCH_POWERPC 1 -# define LZO_INFO_ARCH "powerpc" -#elif defined(__powerpc64__) || defined(__powerpc64) || defined(__ppc64__) || defined(__PPC64__) -# define LZO_ARCH_POWERPC 1 -# define LZO_INFO_ARCH "powerpc" -#elif defined(__powerpc64le__) || defined(__powerpc64le) || defined(__ppc64le__) || defined(__PPC64LE__) -# define LZO_ARCH_POWERPC 1 -# define LZO_INFO_ARCH "powerpc" -#elif defined(__riscv) -# define LZO_ARCH_RISCV 1 -# define LZO_INFO_ARCH "riscv" -#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) -# define LZO_ARCH_S390 1 -# define LZO_INFO_ARCH "s390" -#elif defined(__sh__) || defined(_M_SH) -# define LZO_ARCH_SH 1 -# define LZO_INFO_ARCH "sh" -#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) -# define LZO_ARCH_SPARC 1 -# define LZO_INFO_ARCH "sparc" -#elif defined(__SPU__) -# define LZO_ARCH_SPU 1 -# define LZO_INFO_ARCH "spu" -#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) -# define LZO_ARCH_Z80 1 -# define LZO_INFO_ARCH "z80" -#elif (LZO_ARCH_CRAY_PVP) -# if defined(_CRAYSV1) -# define LZO_ARCH_CRAY_SV1 1 -# define LZO_INFO_ARCH "cray_sv1" -# elif (_ADDR64) -# define LZO_ARCH_CRAY_T90 1 -# define LZO_INFO_ARCH "cray_t90" -# elif (_ADDR32) -# define LZO_ARCH_CRAY_YMP 1 -# define LZO_INFO_ARCH "cray_ymp" -# else -# define LZO_ARCH_CRAY_XMP 1 -# define LZO_INFO_ARCH "cray_xmp" -# endif -#else -# define LZO_ARCH_UNKNOWN 1 -# define LZO_INFO_ARCH "unknown" -#endif -#endif -#if !defined(LZO_ARCH_ARM_THUMB2) -#if (LZO_ARCH_ARM) -# if defined(__thumb__) || defined(__thumb) || defined(_M_THUMB) -# if defined(__thumb2__) -# define LZO_ARCH_ARM_THUMB2 1 -# elif 1 && defined(__TARGET_ARCH_THUMB) && ((__TARGET_ARCH_THUMB)+0 >= 4) -# define LZO_ARCH_ARM_THUMB2 1 -# elif 1 && defined(_MSC_VER) && defined(_M_THUMB) && ((_M_THUMB)+0 >= 7) -# define LZO_ARCH_ARM_THUMB2 1 -# endif -# endif -#endif -#endif -#if (LZO_ARCH_ARM_THUMB2) -# undef LZO_INFO_ARCH -# define LZO_INFO_ARCH "arm_thumb2" -#endif -#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) -# error "FIXME - missing define for CPU architecture" -#endif -#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) -# error "FIXME - missing LZO_OS_WIN32 define for CPU architecture" -#endif -#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) -# error "FIXME - missing LZO_OS_WIN64 define for CPU architecture" -#endif -#if (LZO_OS_OS216 || LZO_OS_WIN16) -# define LZO_ARCH_I086PM 1 -#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) -# define LZO_ARCH_I086PM 1 -#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) -# define LZO_ARCH_I086PM 1 -#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) -# define LZO_ARCH_I086PM 1 -#endif -#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) -# define LZO_ARCH_X64 1 -#elif (!LZO_ARCH_AMD64 && LZO_ARCH_X64) && defined(__LZO_ARCH_OVERRIDE) -# define LZO_ARCH_AMD64 1 -#endif -#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) -# define LZO_ARCH_AARCH64 1 -#elif (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) && defined(__LZO_ARCH_OVERRIDE) -# define LZO_ARCH_ARM64 1 -#endif -#if (LZO_ARCH_I386 && !LZO_ARCH_X86) -# define LZO_ARCH_X86 1 -#elif (!LZO_ARCH_I386 && LZO_ARCH_X86) && defined(__LZO_ARCH_OVERRIDE) -# define LZO_ARCH_I386 1 -#endif -#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) || (!LZO_ARCH_AMD64 && LZO_ARCH_X64) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) || (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_I386 && !LZO_ARCH_X86) || (!LZO_ARCH_I386 && LZO_ARCH_X86) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_ARM_THUMB1 && !LZO_ARCH_ARM) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_ARM_THUMB2 && !LZO_ARCH_ARM) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_ARM_THUMB1 && LZO_ARCH_ARM_THUMB2) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_I086PM && !LZO_ARCH_I086) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_I086) -# if (UINT_MAX != LZO_0xffffL) -# error "unexpected configuration - check your compiler defines" -# endif -# if (ULONG_MAX != LZO_0xffffffffL) -# error "unexpected configuration - check your compiler defines" -# endif -#endif -#if (LZO_ARCH_I386) -# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) -# error "unexpected configuration - check your compiler defines" -# endif -# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) -# error "unexpected configuration - check your compiler defines" -# endif -# if (ULONG_MAX != LZO_0xffffffffL) -# error "unexpected configuration - check your compiler defines" -# endif -#endif -#if (LZO_ARCH_AMD64 || LZO_ARCH_I386) -# if !defined(LZO_TARGET_FEATURE_SSE2) -# if defined(__SSE2__) -# define LZO_TARGET_FEATURE_SSE2 1 -# elif defined(_MSC_VER) && (defined(_M_IX86_FP) && ((_M_IX86_FP)+0 >= 2)) -# define LZO_TARGET_FEATURE_SSE2 1 -# elif (LZO_CC_INTELC_MSC || LZO_CC_MSC) && defined(_M_AMD64) -# define LZO_TARGET_FEATURE_SSE2 1 -# endif -# endif -# if !defined(LZO_TARGET_FEATURE_SSSE3) -# if (LZO_TARGET_FEATURE_SSE2) -# if defined(__SSSE3__) -# define LZO_TARGET_FEATURE_SSSE3 1 -# elif defined(_MSC_VER) && defined(__AVX__) -# define LZO_TARGET_FEATURE_SSSE3 1 -# endif -# endif -# endif -# if !defined(LZO_TARGET_FEATURE_SSE4_2) -# if (LZO_TARGET_FEATURE_SSSE3) -# if defined(__SSE4_2__) -# define LZO_TARGET_FEATURE_SSE4_2 1 -# endif -# endif -# endif -# if !defined(LZO_TARGET_FEATURE_AVX) -# if (LZO_TARGET_FEATURE_SSSE3) -# if defined(__AVX__) -# define LZO_TARGET_FEATURE_AVX 1 -# endif -# endif -# endif -# if !defined(LZO_TARGET_FEATURE_AVX2) -# if (LZO_TARGET_FEATURE_AVX) -# if defined(__AVX2__) -# define LZO_TARGET_FEATURE_AVX2 1 -# endif -# endif -# endif -#endif -#if (LZO_TARGET_FEATURE_SSSE3 && !(LZO_TARGET_FEATURE_SSE2)) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_TARGET_FEATURE_SSE4_2 && !(LZO_TARGET_FEATURE_SSSE3)) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_TARGET_FEATURE_AVX && !(LZO_TARGET_FEATURE_SSSE3)) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_TARGET_FEATURE_AVX2 && !(LZO_TARGET_FEATURE_AVX)) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_ARM) -# if !defined(LZO_TARGET_FEATURE_NEON) -# if defined(__ARM_NEON) && ((__ARM_NEON)+0) -# define LZO_TARGET_FEATURE_NEON 1 -# elif 1 && defined(__ARM_NEON__) && ((__ARM_NEON__)+0) -# define LZO_TARGET_FEATURE_NEON 1 -# elif 1 && defined(__TARGET_FEATURE_NEON) && ((__TARGET_FEATURE_NEON)+0) -# define LZO_TARGET_FEATURE_NEON 1 -# endif -# endif -#elif (LZO_ARCH_ARM64) -# if !defined(LZO_TARGET_FEATURE_NEON) -# if 1 -# define LZO_TARGET_FEATURE_NEON 1 -# endif -# endif -#endif -#if 0 -#elif !defined(__LZO_MM_OVERRIDE) -#if (LZO_ARCH_I086) -#if (UINT_MAX != LZO_0xffffL) -# error "unexpected configuration - check your compiler defines" -#endif -#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) -# define LZO_MM_TINY 1 -#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) -# define LZO_MM_HUGE 1 -#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) -# define LZO_MM_SMALL 1 -#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) -# define LZO_MM_MEDIUM 1 -#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) -# define LZO_MM_COMPACT 1 -#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) -# define LZO_MM_LARGE 1 -#elif (LZO_CC_AZTECC) -# if defined(_LARGE_CODE) && defined(_LARGE_DATA) -# define LZO_MM_LARGE 1 -# elif defined(_LARGE_CODE) -# define LZO_MM_MEDIUM 1 -# elif defined(_LARGE_DATA) -# define LZO_MM_COMPACT 1 -# else -# define LZO_MM_SMALL 1 -# endif -#elif (LZO_CC_ZORTECHC && defined(__VCM__)) -# define LZO_MM_LARGE 1 -#else -# error "unknown LZO_ARCH_I086 memory model" -#endif -#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) -#define LZO_HAVE_MM_HUGE_PTR 1 -#define LZO_HAVE_MM_HUGE_ARRAY 1 -#if (LZO_MM_TINY) -# undef LZO_HAVE_MM_HUGE_ARRAY -#endif -#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) -# undef LZO_HAVE_MM_HUGE_PTR -# undef LZO_HAVE_MM_HUGE_ARRAY -#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) -# undef LZO_HAVE_MM_HUGE_ARRAY -#elif (LZO_CC_MSC && defined(_QC)) -# undef LZO_HAVE_MM_HUGE_ARRAY -# if (_MSC_VER < 600) -# undef LZO_HAVE_MM_HUGE_PTR -# endif -#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) -# undef LZO_HAVE_MM_HUGE_ARRAY -#endif -#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR) -# if (LZO_OS_DOS16) -# error "unexpected configuration - check your compiler defines" -# elif (LZO_CC_ZORTECHC) -# else -# error "unexpected configuration - check your compiler defines" -# endif -#endif -#if defined(__cplusplus) -extern "C" { -#endif -#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) - extern void __near __cdecl _AHSHIFT(void); -# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) -#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) - extern void __near __cdecl _AHSHIFT(void); -# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) -#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) - extern void __near __cdecl _AHSHIFT(void); -# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) -#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) - extern void __near __cdecl _AHSHIFT(void); -# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) -#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) -# define LZO_MM_AHSHIFT 12 -#elif (LZO_CC_WATCOMC) - extern unsigned char _HShift; -# define LZO_MM_AHSHIFT ((unsigned) _HShift) -#else -# error "FIXME - implement LZO_MM_AHSHIFT" -#endif -#if defined(__cplusplus) -} -#endif -#endif -#elif (LZO_ARCH_C166) -#if !defined(__MODEL__) -# error "FIXME - LZO_ARCH_C166 __MODEL__" -#elif ((__MODEL__) == 0) -# define LZO_MM_SMALL 1 -#elif ((__MODEL__) == 1) -# define LZO_MM_SMALL 1 -#elif ((__MODEL__) == 2) -# define LZO_MM_LARGE 1 -#elif ((__MODEL__) == 3) -# define LZO_MM_TINY 1 -#elif ((__MODEL__) == 4) -# define LZO_MM_XTINY 1 -#elif ((__MODEL__) == 5) -# define LZO_MM_XSMALL 1 -#else -# error "FIXME - LZO_ARCH_C166 __MODEL__" -#endif -#elif (LZO_ARCH_MCS251) -#if !defined(__MODEL__) -# error "FIXME - LZO_ARCH_MCS251 __MODEL__" -#elif ((__MODEL__) == 0) -# define LZO_MM_SMALL 1 -#elif ((__MODEL__) == 2) -# define LZO_MM_LARGE 1 -#elif ((__MODEL__) == 3) -# define LZO_MM_TINY 1 -#elif ((__MODEL__) == 4) -# define LZO_MM_XTINY 1 -#elif ((__MODEL__) == 5) -# define LZO_MM_XSMALL 1 -#else -# error "FIXME - LZO_ARCH_MCS251 __MODEL__" -#endif -#elif (LZO_ARCH_MCS51) -#if !defined(__MODEL__) -# error "FIXME - LZO_ARCH_MCS51 __MODEL__" -#elif ((__MODEL__) == 1) -# define LZO_MM_SMALL 1 -#elif ((__MODEL__) == 2) -# define LZO_MM_LARGE 1 -#elif ((__MODEL__) == 3) -# define LZO_MM_TINY 1 -#elif ((__MODEL__) == 4) -# define LZO_MM_XTINY 1 -#elif ((__MODEL__) == 5) -# define LZO_MM_XSMALL 1 -#else -# error "FIXME - LZO_ARCH_MCS51 __MODEL__" -#endif -#elif (LZO_ARCH_CRAY_PVP) -# define LZO_MM_PVP 1 -#else -# define LZO_MM_FLAT 1 -#endif -#if (LZO_MM_COMPACT) -# define LZO_INFO_MM "compact" -#elif (LZO_MM_FLAT) -# define LZO_INFO_MM "flat" -#elif (LZO_MM_HUGE) -# define LZO_INFO_MM "huge" -#elif (LZO_MM_LARGE) -# define LZO_INFO_MM "large" -#elif (LZO_MM_MEDIUM) -# define LZO_INFO_MM "medium" -#elif (LZO_MM_PVP) -# define LZO_INFO_MM "pvp" -#elif (LZO_MM_SMALL) -# define LZO_INFO_MM "small" -#elif (LZO_MM_TINY) -# define LZO_INFO_MM "tiny" -#else -# error "unknown memory model" -#endif -#endif -#if !defined(__lzo_gnuc_extension__) -#if (LZO_CC_GNUC >= 0x020800ul) -# define __lzo_gnuc_extension__ __extension__ -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_gnuc_extension__ __extension__ -#elif (LZO_CC_IBMC >= 600) -# define __lzo_gnuc_extension__ __extension__ -#endif -#endif -#if !defined(__lzo_gnuc_extension__) -# define __lzo_gnuc_extension__ /*empty*/ -#endif -#if !defined(lzo_has_builtin) -#if (LZO_CC_CLANG) && defined(__has_builtin) -# define lzo_has_builtin __has_builtin -#endif -#endif -#if !defined(lzo_has_builtin) -# define lzo_has_builtin(x) 0 -#endif -#if !defined(lzo_has_attribute) -#if (LZO_CC_CLANG) && defined(__has_attribute) -# define lzo_has_attribute __has_attribute -#endif -#endif -#if !defined(lzo_has_attribute) -# define lzo_has_attribute(x) 0 -#endif -#if !defined(lzo_has_declspec_attribute) -#if (LZO_CC_CLANG) && defined(__has_declspec_attribute) -# define lzo_has_declspec_attribute __has_declspec_attribute -#endif -#endif -#if !defined(lzo_has_declspec_attribute) -# define lzo_has_declspec_attribute(x) 0 -#endif -#if !defined(lzo_has_feature) -#if (LZO_CC_CLANG) && defined(__has_feature) -# define lzo_has_feature __has_feature -#endif -#endif -#if !defined(lzo_has_feature) -# define lzo_has_feature(x) 0 -#endif -#if !defined(lzo_has_extension) -#if (LZO_CC_CLANG) && defined(__has_extension) -# define lzo_has_extension __has_extension -#elif (LZO_CC_CLANG) && defined(__has_feature) -# define lzo_has_extension __has_feature -#endif -#endif -#if !defined(lzo_has_extension) -# define lzo_has_extension(x) 0 -#endif -#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) && defined(__cplusplus) && 0 -# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) -# define LZO_CFG_USE_NEW_STYLE_CASTS 0 -# elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1200)) -# define LZO_CFG_USE_NEW_STYLE_CASTS 0 -# else -# define LZO_CFG_USE_NEW_STYLE_CASTS 1 -# endif -#endif -#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) -# define LZO_CFG_USE_NEW_STYLE_CASTS 0 -#endif -#if !defined(__cplusplus) -# if defined(LZO_CFG_USE_NEW_STYLE_CASTS) -# undef LZO_CFG_USE_NEW_STYLE_CASTS -# endif -# define LZO_CFG_USE_NEW_STYLE_CASTS 0 -#endif -#if !defined(LZO_REINTERPRET_CAST) -# if (LZO_CFG_USE_NEW_STYLE_CASTS) -# define LZO_REINTERPRET_CAST(t,e) (reinterpret_cast (e)) -# endif -#endif -#if !defined(LZO_REINTERPRET_CAST) -# define LZO_REINTERPRET_CAST(t,e) ((t) (e)) -#endif -#if !defined(LZO_STATIC_CAST) -# if (LZO_CFG_USE_NEW_STYLE_CASTS) -# define LZO_STATIC_CAST(t,e) (static_cast (e)) -# endif -#endif -#if !defined(LZO_STATIC_CAST) -# define LZO_STATIC_CAST(t,e) ((t) (e)) -#endif -#if !defined(LZO_STATIC_CAST2) -# define LZO_STATIC_CAST2(t1,t2,e) LZO_STATIC_CAST(t1, LZO_STATIC_CAST(t2, e)) -#endif -#if !defined(LZO_UNCONST_CAST) -# if (LZO_CFG_USE_NEW_STYLE_CASTS) -# define LZO_UNCONST_CAST(t,e) (const_cast (e)) -# elif (LZO_HAVE_MM_HUGE_PTR) -# define LZO_UNCONST_CAST(t,e) ((t) (e)) -# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((const void *) (e))))) -# endif -#endif -#if !defined(LZO_UNCONST_CAST) -# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((const void *) (e)))) -#endif -#if !defined(LZO_UNCONST_VOLATILE_CAST) -# if (LZO_CFG_USE_NEW_STYLE_CASTS) -# define LZO_UNCONST_VOLATILE_CAST(t,e) (const_cast (e)) -# elif (LZO_HAVE_MM_HUGE_PTR) -# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) (e)) -# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) -# endif -#endif -#if !defined(LZO_UNCONST_VOLATILE_CAST) -# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((volatile const void *) (e)))) -#endif -#if !defined(LZO_UNVOLATILE_CAST) -# if (LZO_CFG_USE_NEW_STYLE_CASTS) -# define LZO_UNVOLATILE_CAST(t,e) (const_cast (e)) -# elif (LZO_HAVE_MM_HUGE_PTR) -# define LZO_UNVOLATILE_CAST(t,e) ((t) (e)) -# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((volatile void *) (e))))) -# endif -#endif -#if !defined(LZO_UNVOLATILE_CAST) -# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((volatile void *) (e)))) -#endif -#if !defined(LZO_UNVOLATILE_CONST_CAST) -# if (LZO_CFG_USE_NEW_STYLE_CASTS) -# define LZO_UNVOLATILE_CONST_CAST(t,e) (const_cast (e)) -# elif (LZO_HAVE_MM_HUGE_PTR) -# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) (e)) -# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) -# endif -#endif -#if !defined(LZO_UNVOLATILE_CONST_CAST) -# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((volatile const void *) (e)))) -#endif -#if !defined(LZO_PCAST) -# if (LZO_HAVE_MM_HUGE_PTR) -# define LZO_PCAST(t,e) ((t) (e)) -# endif -#endif -#if !defined(LZO_PCAST) -# define LZO_PCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(void *, e)) -#endif -#if !defined(LZO_CCAST) -# if (LZO_HAVE_MM_HUGE_PTR) -# define LZO_CCAST(t,e) ((t) (e)) -# endif -#endif -#if !defined(LZO_CCAST) -# define LZO_CCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(const void *, e)) -#endif -#if !defined(LZO_ICONV) -# define LZO_ICONV(t,e) LZO_STATIC_CAST(t, e) -#endif -#if !defined(LZO_ICAST) -# define LZO_ICAST(t,e) LZO_STATIC_CAST(t, e) -#endif -#if !defined(LZO_ITRUNC) -# define LZO_ITRUNC(t,e) LZO_STATIC_CAST(t, e) -#endif -#if !defined(__lzo_cte) -# if (LZO_CC_MSC || LZO_CC_WATCOMC) -# define __lzo_cte(e) ((void)0,(e)) -# elif 1 -# define __lzo_cte(e) ((void)0,(e)) -# endif -#endif -#if !defined(__lzo_cte) -# define __lzo_cte(e) (e) -#endif -#if !defined(LZO_BLOCK_BEGIN) -# define LZO_BLOCK_BEGIN do { -# define LZO_BLOCK_END } while __lzo_cte(0) -#endif -#if !defined(LZO_UNUSED) -# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) -# define LZO_UNUSED(var) ((void) &var) -# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) -# define LZO_UNUSED(var) if (&var) ; else -# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030200ul)) -# define LZO_UNUSED(var) ((void) &var) -# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define LZO_UNUSED(var) ((void) var) -# elif (LZO_CC_MSC && (_MSC_VER < 900)) -# define LZO_UNUSED(var) if (&var) ; else -# elif (LZO_CC_KEILC) -# define LZO_UNUSED(var) {extern int lzo_unused__[1-2*!(sizeof(var)>0)]; (void)lzo_unused__;} -# elif (LZO_CC_PACIFICC) -# define LZO_UNUSED(var) ((void) sizeof(var)) -# elif (LZO_CC_WATCOMC) && defined(__cplusplus) -# define LZO_UNUSED(var) ((void) var) -# else -# define LZO_UNUSED(var) ((void) &var) -# endif -#endif -#if !defined(LZO_UNUSED_RESULT) -# define LZO_UNUSED_RESULT(var) LZO_UNUSED(var) -#endif -#if !defined(LZO_UNUSED_FUNC) -# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) -# define LZO_UNUSED_FUNC(func) ((void) func) -# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) -# define LZO_UNUSED_FUNC(func) if (func) ; else -# elif (LZO_CC_CLANG || LZO_CC_LLVM) -# define LZO_UNUSED_FUNC(func) ((void) &func) -# elif (LZO_CC_MSC && (_MSC_VER < 900)) -# define LZO_UNUSED_FUNC(func) if (func) ; else -# elif (LZO_CC_MSC) -# define LZO_UNUSED_FUNC(func) ((void) &func) -# elif (LZO_CC_KEILC || LZO_CC_PELLESC) -# define LZO_UNUSED_FUNC(func) {extern int lzo_unused__[1-2*!(sizeof((int)func)>0)]; (void)lzo_unused__;} -# else -# define LZO_UNUSED_FUNC(func) ((void) func) -# endif -#endif -#if !defined(LZO_UNUSED_LABEL) -# if (LZO_CC_CLANG >= 0x020800ul) -# define LZO_UNUSED_LABEL(l) (__lzo_gnuc_extension__ ((void) ((const void *) &&l))) -# elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC) -# define LZO_UNUSED_LABEL(l) if __lzo_cte(0) goto l -# else -# define LZO_UNUSED_LABEL(l) switch (0) case 1:goto l -# endif -#endif -#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) -# if 0 -# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var -# elif 0 && (LZO_CC_GNUC) -# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var -# else -# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init -# endif -#endif -#if !defined(__lzo_inline) -#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) -#elif defined(__cplusplus) -# define __lzo_inline inline -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) -# define __lzo_inline inline -#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) -# define __lzo_inline __inline -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) -# define __lzo_inline __inline__ -#elif (LZO_CC_DMC) -# define __lzo_inline __inline -#elif (LZO_CC_GHS) -# define __lzo_inline __inline__ -#elif (LZO_CC_IBMC >= 600) -# define __lzo_inline __inline__ -#elif (LZO_CC_INTELC) -# define __lzo_inline __inline -#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) -# define __lzo_inline __inline -#elif (LZO_CC_MSC && (_MSC_VER >= 900)) -# define __lzo_inline __inline -#elif (LZO_CC_SUNPROC >= 0x5100) -# define __lzo_inline __inline__ -#endif -#endif -#if defined(__lzo_inline) -# ifndef __lzo_HAVE_inline -# define __lzo_HAVE_inline 1 -# endif -#else -# define __lzo_inline /*empty*/ -#endif -#if !defined(__lzo_forceinline) -#if (LZO_CC_GNUC >= 0x030200ul) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#elif (LZO_CC_IBMC >= 700) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) -# define __lzo_forceinline __forceinline -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) -# define __lzo_forceinline __forceinline -#elif (LZO_CC_PGI >= 0x0d0a00ul) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#elif (LZO_CC_SUNPROC >= 0x5100) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#endif -#endif -#if defined(__lzo_forceinline) -# ifndef __lzo_HAVE_forceinline -# define __lzo_HAVE_forceinline 1 -# endif -#else -# define __lzo_forceinline __lzo_inline -#endif -#if !defined(__lzo_noinline) -#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) -# define __lzo_noinline __attribute__((__noinline__,__used__)) -#elif (LZO_CC_GNUC >= 0x030200ul) -# define __lzo_noinline __attribute__((__noinline__)) -#elif (LZO_CC_IBMC >= 700) -# define __lzo_noinline __attribute__((__noinline__)) -#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) -# define __lzo_noinline __declspec(noinline) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) -# define __lzo_noinline __attribute__((__noinline__)) -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_noinline __attribute__((__noinline__)) -#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) -# define __lzo_noinline __declspec(noinline) -#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) -# if defined(__cplusplus) -# else -# define __lzo_noinline __declspec(noinline) -# endif -#elif (LZO_CC_PGI >= 0x0d0a00ul) -# define __lzo_noinline __attribute__((__noinline__)) -#elif (LZO_CC_SUNPROC >= 0x5100) -# define __lzo_noinline __attribute__((__noinline__)) -#endif -#endif -#if defined(__lzo_noinline) -# ifndef __lzo_HAVE_noinline -# define __lzo_HAVE_noinline 1 -# endif -#else -# define __lzo_noinline /*empty*/ -#endif -#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline) -# error "unexpected configuration - check your compiler defines" -#endif -#if !defined(__lzo_static_inline) -#if (LZO_CC_IBMC) -# define __lzo_static_inline __lzo_gnuc_extension__ static __lzo_inline -#endif -#endif -#if !defined(__lzo_static_inline) -# define __lzo_static_inline static __lzo_inline -#endif -#if !defined(__lzo_static_forceinline) -#if (LZO_CC_IBMC) -# define __lzo_static_forceinline __lzo_gnuc_extension__ static __lzo_forceinline -#endif -#endif -#if !defined(__lzo_static_forceinline) -# define __lzo_static_forceinline static __lzo_forceinline -#endif -#if !defined(__lzo_static_noinline) -#if (LZO_CC_IBMC) -# define __lzo_static_noinline __lzo_gnuc_extension__ static __lzo_noinline -#endif -#endif -#if !defined(__lzo_static_noinline) -# define __lzo_static_noinline static __lzo_noinline -#endif -#if !defined(__lzo_c99_extern_inline) -#if defined(__GNUC_GNU_INLINE__) -# define __lzo_c99_extern_inline __lzo_inline -#elif defined(__GNUC_STDC_INLINE__) -# define __lzo_c99_extern_inline extern __lzo_inline -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) -# define __lzo_c99_extern_inline extern __lzo_inline -#endif -#if !defined(__lzo_c99_extern_inline) && (__lzo_HAVE_inline) -# define __lzo_c99_extern_inline __lzo_inline -#endif -#endif -#if defined(__lzo_c99_extern_inline) -# ifndef __lzo_HAVE_c99_extern_inline -# define __lzo_HAVE_c99_extern_inline 1 -# endif -#else -# define __lzo_c99_extern_inline /*empty*/ -#endif -#if !defined(__lzo_may_alias) -#if (LZO_CC_GNUC >= 0x030400ul) -# define __lzo_may_alias __attribute__((__may_alias__)) -#elif (LZO_CC_CLANG >= 0x020900ul) -# define __lzo_may_alias __attribute__((__may_alias__)) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1210)) && 0 -# define __lzo_may_alias __attribute__((__may_alias__)) -#elif (LZO_CC_PGI >= 0x0d0a00ul) && 0 -# define __lzo_may_alias __attribute__((__may_alias__)) -#endif -#endif -#if defined(__lzo_may_alias) -# ifndef __lzo_HAVE_may_alias -# define __lzo_HAVE_may_alias 1 -# endif -#else -# define __lzo_may_alias /*empty*/ -#endif -#if !defined(__lzo_noreturn) -#if (LZO_CC_GNUC >= 0x020700ul) -# define __lzo_noreturn __attribute__((__noreturn__)) -#elif (LZO_CC_IBMC >= 700) -# define __lzo_noreturn __attribute__((__noreturn__)) -#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) -# define __lzo_noreturn __declspec(noreturn) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) -# define __lzo_noreturn __attribute__((__noreturn__)) -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_noreturn __attribute__((__noreturn__)) -#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) -# define __lzo_noreturn __declspec(noreturn) -#elif (LZO_CC_PGI >= 0x0d0a00ul) -# define __lzo_noreturn __attribute__((__noreturn__)) -#endif -#endif -#if defined(__lzo_noreturn) -# ifndef __lzo_HAVE_noreturn -# define __lzo_HAVE_noreturn 1 -# endif -#else -# define __lzo_noreturn /*empty*/ -#endif -#if !defined(__lzo_nothrow) -#if (LZO_CC_GNUC >= 0x030300ul) -# define __lzo_nothrow __attribute__((__nothrow__)) -#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) && defined(__cplusplus) -# define __lzo_nothrow __declspec(nothrow) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 900)) -# define __lzo_nothrow __attribute__((__nothrow__)) -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_nothrow __attribute__((__nothrow__)) -#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) -# define __lzo_nothrow __declspec(nothrow) -#endif -#endif -#if defined(__lzo_nothrow) -# ifndef __lzo_HAVE_nothrow -# define __lzo_HAVE_nothrow 1 -# endif -#else -# define __lzo_nothrow /*empty*/ -#endif -#if !defined(__lzo_restrict) -#if (LZO_CC_GNUC >= 0x030400ul) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_IBMC >= 800) && !defined(__cplusplus) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_IBMC >= 1210) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) -# define __lzo_restrict __restrict -#elif (LZO_CC_PGI >= 0x0d0a00ul) -# define __lzo_restrict __restrict__ -#endif -#endif -#if defined(__lzo_restrict) -# ifndef __lzo_HAVE_restrict -# define __lzo_HAVE_restrict 1 -# endif -#else -# define __lzo_restrict /*empty*/ -#endif -#if !defined(__lzo_alignof) -#if (LZO_CC_ARMCC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) -# define __lzo_alignof(e) __alignof__(e) -#elif (LZO_CC_GHS) && !defined(__cplusplus) -# define __lzo_alignof(e) __alignof__(e) -#elif (LZO_CC_IBMC >= 600) -# define __lzo_alignof(e) (__lzo_gnuc_extension__ __alignof__(e)) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) -# define __lzo_alignof(e) __alignof__(e) -#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) -# define __lzo_alignof(e) __alignof(e) -#elif (LZO_CC_SUNPROC >= 0x5100) -# define __lzo_alignof(e) __alignof__(e) -#endif -#endif -#if defined(__lzo_alignof) -# ifndef __lzo_HAVE_alignof -# define __lzo_HAVE_alignof 1 -# endif -#endif -#if !defined(__lzo_struct_packed) -#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) -#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) -#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) -#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) -#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) -#elif (LZO_CC_GNUC >= 0x030400ul) && !(LZO_CC_PCC_GNUC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) -# define __lzo_struct_packed(s) struct s { -# define __lzo_struct_packed_end() } __attribute__((__gcc_struct__,__packed__)); -# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__gcc_struct__,__packed__)); -#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) -# define __lzo_struct_packed(s) struct s { -# define __lzo_struct_packed_end() } __attribute__((__packed__)); -# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); -#elif (LZO_CC_IBMC >= 700) -# define __lzo_struct_packed(s) __lzo_gnuc_extension__ struct s { -# define __lzo_struct_packed_end() } __attribute__((__packed__)); -# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); -#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) -# define __lzo_struct_packed(s) __pragma(pack(push,1)) struct s { -# define __lzo_struct_packed_end() } __pragma(pack(pop)); -#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) -# define __lzo_struct_packed(s) _Packed struct s { -# define __lzo_struct_packed_end() }; -#endif -#endif -#if defined(__lzo_struct_packed) && !defined(__lzo_struct_packed_ma) -# define __lzo_struct_packed_ma(s) __lzo_struct_packed(s) -#endif -#if defined(__lzo_struct_packed_end) && !defined(__lzo_struct_packed_ma_end) -# define __lzo_struct_packed_ma_end() __lzo_struct_packed_end() -#endif -#if !defined(__lzo_byte_struct) -#if defined(__lzo_struct_packed) -# define __lzo_byte_struct(s,n) __lzo_struct_packed(s) unsigned char a[n]; __lzo_struct_packed_end() -# define __lzo_byte_struct_ma(s,n) __lzo_struct_packed_ma(s) unsigned char a[n]; __lzo_struct_packed_ma_end() -#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_PGI || (LZO_CC_SUNPROC >= 0x5100)) -# define __lzo_byte_struct(s,n) struct s { unsigned char a[n]; } __attribute__((__packed__)); -# define __lzo_byte_struct_ma(s,n) struct s { unsigned char a[n]; } __lzo_may_alias __attribute__((__packed__)); -#endif -#endif -#if defined(__lzo_byte_struct) && !defined(__lzo_byte_struct_ma) -# define __lzo_byte_struct_ma(s,n) __lzo_byte_struct(s,n) -#endif -#if !defined(__lzo_struct_align16) && (__lzo_HAVE_alignof) -#if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul)) -#elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) -#elif (LZO_CC_CILLY || LZO_CC_PCC) -#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) -# define __lzo_struct_align16(s) struct __declspec(align(16)) s { -# define __lzo_struct_align16_end() }; -# define __lzo_struct_align32(s) struct __declspec(align(32)) s { -# define __lzo_struct_align32_end() }; -# define __lzo_struct_align64(s) struct __declspec(align(64)) s { -# define __lzo_struct_align64_end() }; -#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || (LZO_CC_IBMC >= 700) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_struct_align16(s) struct s { -# define __lzo_struct_align16_end() } __attribute__((__aligned__(16))); -# define __lzo_struct_align32(s) struct s { -# define __lzo_struct_align32_end() } __attribute__((__aligned__(32))); -# define __lzo_struct_align64(s) struct s { -# define __lzo_struct_align64_end() } __attribute__((__aligned__(64))); -#endif -#endif -#if !defined(__lzo_union_um) -#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) -#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) -#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER < 810)) -#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) -#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) -#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) -# define __lzo_union_am(s) union s { -# define __lzo_union_am_end() } __lzo_may_alias; -# define __lzo_union_um(s) union s { -# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); -#elif (LZO_CC_IBMC >= 700) -# define __lzo_union_am(s) __lzo_gnuc_extension__ union s { -# define __lzo_union_am_end() } __lzo_may_alias; -# define __lzo_union_um(s) __lzo_gnuc_extension__ union s { -# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); -#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) -# define __lzo_union_um(s) __pragma(pack(push,1)) union s { -# define __lzo_union_um_end() } __pragma(pack(pop)); -#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) -# define __lzo_union_um(s) _Packed union s { -# define __lzo_union_um_end() }; -#endif -#endif -#if !defined(__lzo_union_am) -# define __lzo_union_am(s) union s { -# define __lzo_union_am_end() }; -#endif -#if !defined(__lzo_constructor) -#if (LZO_CC_GNUC >= 0x030400ul) -# define __lzo_constructor __attribute__((__constructor__,__used__)) -#elif (LZO_CC_GNUC >= 0x020700ul) -# define __lzo_constructor __attribute__((__constructor__)) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) -# define __lzo_constructor __attribute__((__constructor__,__used__)) -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_constructor __attribute__((__constructor__)) -#endif -#endif -#if defined(__lzo_constructor) -# ifndef __lzo_HAVE_constructor -# define __lzo_HAVE_constructor 1 -# endif -#endif -#if !defined(__lzo_destructor) -#if (LZO_CC_GNUC >= 0x030400ul) -# define __lzo_destructor __attribute__((__destructor__,__used__)) -#elif (LZO_CC_GNUC >= 0x020700ul) -# define __lzo_destructor __attribute__((__destructor__)) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) -# define __lzo_destructor __attribute__((__destructor__,__used__)) -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_destructor __attribute__((__destructor__)) -#endif -#endif -#if defined(__lzo_destructor) -# ifndef __lzo_HAVE_destructor -# define __lzo_HAVE_destructor 1 -# endif -#endif -#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor) -# error "unexpected configuration - check your compiler defines" -#endif -#if !defined(__lzo_likely) && !defined(__lzo_unlikely) -#if (LZO_CC_GNUC >= 0x030200ul) -# define __lzo_likely(e) (__builtin_expect(!!(e),1)) -# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) -#elif (LZO_CC_IBMC >= 1010) -# define __lzo_likely(e) (__builtin_expect(!!(e),1)) -# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) -# define __lzo_likely(e) (__builtin_expect(!!(e),1)) -# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) -#elif (LZO_CC_CLANG && LZO_CC_CLANG_C2) -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_likely(e) (__builtin_expect(!!(e),1)) -# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) -#endif -#endif -#if defined(__lzo_likely) -# ifndef __lzo_HAVE_likely -# define __lzo_HAVE_likely 1 -# endif -#else -# define __lzo_likely(e) (e) -#endif -#if defined(__lzo_very_likely) -# ifndef __lzo_HAVE_very_likely -# define __lzo_HAVE_very_likely 1 -# endif -#else -# define __lzo_very_likely(e) __lzo_likely(e) -#endif -#if defined(__lzo_unlikely) -# ifndef __lzo_HAVE_unlikely -# define __lzo_HAVE_unlikely 1 -# endif -#else -# define __lzo_unlikely(e) (e) -#endif -#if defined(__lzo_very_unlikely) -# ifndef __lzo_HAVE_very_unlikely -# define __lzo_HAVE_very_unlikely 1 -# endif -#else -# define __lzo_very_unlikely(e) __lzo_unlikely(e) -#endif -#if !defined(__lzo_loop_forever) -# if (LZO_CC_IBMC) -# define __lzo_loop_forever() LZO_BLOCK_BEGIN for (;;) { ; } LZO_BLOCK_END -# else -# define __lzo_loop_forever() do { ; } while __lzo_cte(1) -# endif -#endif -#if !defined(__lzo_unreachable) -#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x020800ul)) && lzo_has_builtin(__builtin_unreachable) -# define __lzo_unreachable() __builtin_unreachable(); -#elif (LZO_CC_GNUC >= 0x040500ul) -# define __lzo_unreachable() __builtin_unreachable(); -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1300)) && 1 -# define __lzo_unreachable() __builtin_unreachable(); -#endif -#endif -#if defined(__lzo_unreachable) -# ifndef __lzo_HAVE_unreachable -# define __lzo_HAVE_unreachable 1 -# endif -#else -# if 0 -# define __lzo_unreachable() ((void)0); -# else -# define __lzo_unreachable() __lzo_loop_forever(); -# endif -#endif -#if !defined(lzo_unused_funcs_impl) -# if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) -# define lzo_unused_funcs_impl(r,f) static r __attribute__((__unused__)) f -# elif 1 && (LZO_CC_BORLANDC || LZO_CC_GNUC) -# define lzo_unused_funcs_impl(r,f) static r f -# else -# define lzo_unused_funcs_impl(r,f) __lzo_static_forceinline r f -# endif -#endif -#ifndef __LZO_CTA_NAME -#if (LZO_CFG_USE_COUNTER) -# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__COUNTER__) -#else -# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__LINE__) -#endif -#endif -#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) -# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) -# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END -# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) -# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1u-2*!(e)]; LZO_EXTERN_C_END -# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) -# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END -# elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020900ul)) && defined(__cplusplus) -# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN int __LZO_CTA_NAME(lzo_cta_f__)(int [1-2*!(e)]); LZO_EXTERN_C_END -# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) -# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__)); LZO_EXTERN_C_END -# else -# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-2*!(e)]; LZO_EXTERN_C_END -# endif -#endif -#if !defined(LZO_COMPILE_TIME_ASSERT) -# if (LZO_CC_AZTECC) -# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-!(e)];} -# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030000ul)) -# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));} -# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) -# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; -# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) -# define LZO_COMPILE_TIME_ASSERT(e) {(void) (0/!!(e));} -# elif (LZO_CC_GNUC >= 0x040700ul) && (LZO_CFG_USE_COUNTER) && defined(__cplusplus) -# define LZO_COMPILE_TIME_ASSERT(e) {enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__));} -# elif (LZO_CC_GNUC >= 0x040700ul) -# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));} -# elif (LZO_CC_MSC && (_MSC_VER < 900)) -# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; -# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) -# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; -# else -# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)];} -# endif -#endif -#if (LZO_LANG_ASSEMBLER) -# undef LZO_COMPILE_TIME_ASSERT_HEADER -# define LZO_COMPILE_TIME_ASSERT_HEADER(e) /*empty*/ -#else -LZO_COMPILE_TIME_ASSERT_HEADER(1 == 1) -#if defined(__cplusplus) -extern "C" { LZO_COMPILE_TIME_ASSERT_HEADER(2 == 2) } -#endif -LZO_COMPILE_TIME_ASSERT_HEADER(3 == 3) -#endif -#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) -# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) -# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) -# define __lzo_cdecl __cdecl -# define __lzo_cdecl_atexit /*empty*/ -# define __lzo_cdecl_main __cdecl -# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) -# define __lzo_cdecl_qsort __pascal -# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) -# define __lzo_cdecl_qsort _stdcall -# else -# define __lzo_cdecl_qsort __cdecl -# endif -# elif (LZO_CC_WATCOMC) -# define __lzo_cdecl __cdecl -# else -# define __lzo_cdecl __cdecl -# define __lzo_cdecl_atexit __cdecl -# define __lzo_cdecl_main __cdecl -# define __lzo_cdecl_qsort __cdecl -# endif -# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) -# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) -# define __lzo_cdecl_sighandler __pascal -# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) -# define __lzo_cdecl_sighandler _stdcall -# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) -# define __lzo_cdecl_sighandler __clrcall -# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) -# if defined(_DLL) -# define __lzo_cdecl_sighandler _far _cdecl _loadds -# elif defined(_MT) -# define __lzo_cdecl_sighandler _far _cdecl -# else -# define __lzo_cdecl_sighandler _cdecl -# endif -# else -# define __lzo_cdecl_sighandler __cdecl -# endif -#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) -# define __lzo_cdecl __cdecl -#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) -# define __lzo_cdecl cdecl -#endif -#if !defined(__lzo_cdecl) -# define __lzo_cdecl /*empty*/ -#endif -#if !defined(__lzo_cdecl_atexit) -# define __lzo_cdecl_atexit /*empty*/ -#endif -#if !defined(__lzo_cdecl_main) -# define __lzo_cdecl_main /*empty*/ -#endif -#if !defined(__lzo_cdecl_qsort) -# define __lzo_cdecl_qsort /*empty*/ -#endif -#if !defined(__lzo_cdecl_sighandler) -# define __lzo_cdecl_sighandler /*empty*/ -#endif -#if !defined(__lzo_cdecl_va) -# define __lzo_cdecl_va __lzo_cdecl -#endif -#if !(LZO_CFG_NO_WINDOWS_H) -#if !defined(LZO_HAVE_WINDOWS_H) -#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) -# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) -# elif ((LZO_OS_WIN32 && defined(__PW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul))) -# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) -# else -# define LZO_HAVE_WINDOWS_H 1 -# endif -#endif -#endif -#endif -#define LZO_SIZEOF_CHAR 1 -#ifndef LZO_SIZEOF_SHORT -#if defined(SIZEOF_SHORT) -# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) -#elif defined(__SIZEOF_SHORT__) -# define LZO_SIZEOF_SHORT (__SIZEOF_SHORT__) -#endif -#endif -#ifndef LZO_SIZEOF_INT -#if defined(SIZEOF_INT) -# define LZO_SIZEOF_INT (SIZEOF_INT) -#elif defined(__SIZEOF_INT__) -# define LZO_SIZEOF_INT (__SIZEOF_INT__) -#endif -#endif -#ifndef LZO_SIZEOF_LONG -#if defined(SIZEOF_LONG) -# define LZO_SIZEOF_LONG (SIZEOF_LONG) -#elif defined(__SIZEOF_LONG__) -# define LZO_SIZEOF_LONG (__SIZEOF_LONG__) -#endif -#endif -#ifndef LZO_SIZEOF_LONG_LONG -#if defined(SIZEOF_LONG_LONG) -# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) -#elif defined(__SIZEOF_LONG_LONG__) -# define LZO_SIZEOF_LONG_LONG (__SIZEOF_LONG_LONG__) -#endif -#endif -#ifndef LZO_SIZEOF___INT16 -#if defined(SIZEOF___INT16) -# define LZO_SIZEOF___INT16 (SIZEOF___INT16) -#endif -#endif -#ifndef LZO_SIZEOF___INT32 -#if defined(SIZEOF___INT32) -# define LZO_SIZEOF___INT32 (SIZEOF___INT32) -#endif -#endif -#ifndef LZO_SIZEOF___INT64 -#if defined(SIZEOF___INT64) -# define LZO_SIZEOF___INT64 (SIZEOF___INT64) -#endif -#endif -#ifndef LZO_SIZEOF_VOID_P -#if defined(SIZEOF_VOID_P) -# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) -#elif defined(__SIZEOF_POINTER__) -# define LZO_SIZEOF_VOID_P (__SIZEOF_POINTER__) -#endif -#endif -#ifndef LZO_SIZEOF_SIZE_T -#if defined(SIZEOF_SIZE_T) -# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) -#elif defined(__SIZEOF_SIZE_T__) -# define LZO_SIZEOF_SIZE_T (__SIZEOF_SIZE_T__) -#endif -#endif -#ifndef LZO_SIZEOF_PTRDIFF_T -#if defined(SIZEOF_PTRDIFF_T) -# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) -#elif defined(__SIZEOF_PTRDIFF_T__) -# define LZO_SIZEOF_PTRDIFF_T (__SIZEOF_PTRDIFF_T__) -#endif -#endif -#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) -#if !defined(LZO_SIZEOF_SHORT) -# if (LZO_ARCH_CRAY_PVP) -# define LZO_SIZEOF_SHORT 8 -# elif (USHRT_MAX == LZO_0xffffL) -# define LZO_SIZEOF_SHORT 2 -# elif (__LZO_LSR(USHRT_MAX,7) == 1) -# define LZO_SIZEOF_SHORT 1 -# elif (__LZO_LSR(USHRT_MAX,15) == 1) -# define LZO_SIZEOF_SHORT 2 -# elif (__LZO_LSR(USHRT_MAX,31) == 1) -# define LZO_SIZEOF_SHORT 4 -# elif (__LZO_LSR(USHRT_MAX,63) == 1) -# define LZO_SIZEOF_SHORT 8 -# elif (__LZO_LSR(USHRT_MAX,127) == 1) -# define LZO_SIZEOF_SHORT 16 -# else -# error "LZO_SIZEOF_SHORT" -# endif -#endif -LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SHORT == sizeof(short)) -#if !defined(LZO_SIZEOF_INT) -# if (LZO_ARCH_CRAY_PVP) -# define LZO_SIZEOF_INT 8 -# elif (UINT_MAX == LZO_0xffffL) -# define LZO_SIZEOF_INT 2 -# elif (UINT_MAX == LZO_0xffffffffL) -# define LZO_SIZEOF_INT 4 -# elif (__LZO_LSR(UINT_MAX,7) == 1) -# define LZO_SIZEOF_INT 1 -# elif (__LZO_LSR(UINT_MAX,15) == 1) -# define LZO_SIZEOF_INT 2 -# elif (__LZO_LSR(UINT_MAX,31) == 1) -# define LZO_SIZEOF_INT 4 -# elif (__LZO_LSR(UINT_MAX,63) == 1) -# define LZO_SIZEOF_INT 8 -# elif (__LZO_LSR(UINT_MAX,127) == 1) -# define LZO_SIZEOF_INT 16 -# else -# error "LZO_SIZEOF_INT" -# endif -#endif -LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_INT == sizeof(int)) -#if !defined(LZO_SIZEOF_LONG) -# if (ULONG_MAX == LZO_0xffffffffL) -# define LZO_SIZEOF_LONG 4 -# elif (__LZO_LSR(ULONG_MAX,7) == 1) -# define LZO_SIZEOF_LONG 1 -# elif (__LZO_LSR(ULONG_MAX,15) == 1) -# define LZO_SIZEOF_LONG 2 -# elif (__LZO_LSR(ULONG_MAX,31) == 1) -# define LZO_SIZEOF_LONG 4 -# elif (__LZO_LSR(ULONG_MAX,39) == 1) -# define LZO_SIZEOF_LONG 5 -# elif (__LZO_LSR(ULONG_MAX,63) == 1) -# define LZO_SIZEOF_LONG 8 -# elif (__LZO_LSR(ULONG_MAX,127) == 1) -# define LZO_SIZEOF_LONG 16 -# else -# error "LZO_SIZEOF_LONG" -# endif -#endif -LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_LONG == sizeof(long)) -#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) -#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) -# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) -# if (LZO_CC_GNUC >= 0x030300ul) -# if ((__LONG_MAX__-0) == (__LONG_LONG_MAX__-0)) -# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG -# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) -# define LZO_SIZEOF_LONG_LONG 4 -# endif -# endif -# endif -#endif -#endif -#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) -#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) -#if (LZO_ARCH_I086 && LZO_CC_DMC) -#elif (LZO_CC_CILLY) && defined(__GNUC__) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define LZO_SIZEOF_LONG_LONG 8 -#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_OS_WIN64 || defined(_WIN64)) -# define LZO_SIZEOF___INT64 8 -#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) -# define LZO_SIZEOF___INT64 8 -#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) -# define LZO_SIZEOF___INT64 8 -#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) -# define LZO_SIZEOF___INT64 8 -#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) -# define LZO_SIZEOF___INT64 8 -#elif (LZO_CC_GHS && defined(__LLONG_BIT) && ((__LLONG_BIT-0) == 64)) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && ((_INTEGRAL_MAX_BITS-0) == 64)) -# define LZO_SIZEOF___INT64 8 -#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (defined(__vms) || defined(__VMS)) && ((__INITIAL_POINTER_SIZE-0) == 64) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) -#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -# define LZO_SIZEOF_LONG_LONG 8 -#endif -#endif -#endif -#if defined(__cplusplus) && (LZO_CC_GNUC) -# if (LZO_CC_GNUC < 0x020800ul) -# undef LZO_SIZEOF_LONG_LONG -# endif -#endif -#if (LZO_CFG_NO_LONG_LONG) -# undef LZO_SIZEOF_LONG_LONG -#elif defined(__NO_LONG_LONG) -# undef LZO_SIZEOF_LONG_LONG -#elif defined(_NO_LONGLONG) -# undef LZO_SIZEOF_LONG_LONG -#endif -#if !defined(LZO_WORDSIZE) -#if (LZO_ARCH_ALPHA) -# define LZO_WORDSIZE 8 -#elif (LZO_ARCH_AMD64) -# define LZO_WORDSIZE 8 -#elif (LZO_ARCH_ARM64) -# define LZO_WORDSIZE 8 -#elif (LZO_ARCH_AVR) -# define LZO_WORDSIZE 1 -#elif (LZO_ARCH_H8300) -# if defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) -# define LZO_WORDSIZE 4 -# else -# define LZO_WORDSIZE 2 -# endif -#elif (LZO_ARCH_I086) -# define LZO_WORDSIZE 2 -#elif (LZO_ARCH_IA64) -# define LZO_WORDSIZE 8 -#elif (LZO_ARCH_M16C) -# define LZO_WORDSIZE 2 -#elif (LZO_ARCH_SPU) -# define LZO_WORDSIZE 4 -#elif (LZO_ARCH_Z80) -# define LZO_WORDSIZE 1 -#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) -# define LZO_WORDSIZE 8 -#elif (LZO_OS_OS400 || defined(__OS400__)) -# define LZO_WORDSIZE 8 -#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) -# define LZO_WORDSIZE 8 -#endif -#endif -#if !defined(LZO_SIZEOF_VOID_P) -#if defined(__ILP32__) || defined(__ILP32) || defined(_ILP32) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) -# define LZO_SIZEOF_VOID_P 4 -#elif defined(__ILP64__) || defined(__ILP64) || defined(_ILP64) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 8) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) -# define LZO_SIZEOF_VOID_P 8 -#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) -# define LZO_SIZEOF_VOID_P 8 -#elif defined(__LP64__) || defined(__LP64) || defined(_LP64) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) -# define LZO_SIZEOF_VOID_P 8 -#elif (LZO_ARCH_AVR) -# define LZO_SIZEOF_VOID_P 2 -#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) -# define LZO_SIZEOF_VOID_P 2 -#elif (LZO_ARCH_H8300) -# if defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) - LZO_COMPILE_TIME_ASSERT_HEADER(LZO_WORDSIZE == 4) -# if defined(__NORMAL_MODE__) -# define LZO_SIZEOF_VOID_P 2 -# else -# define LZO_SIZEOF_VOID_P 4 -# endif -# else - LZO_COMPILE_TIME_ASSERT_HEADER(LZO_WORDSIZE == 2) -# define LZO_SIZEOF_VOID_P 2 -# endif -# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT -# endif -#elif (LZO_ARCH_I086) -# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) -# define LZO_SIZEOF_VOID_P 2 -# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) -# define LZO_SIZEOF_VOID_P 4 -# else -# error "invalid LZO_ARCH_I086 memory model" -# endif -#elif (LZO_ARCH_M16C) -# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) -# define LZO_SIZEOF_VOID_P 4 -# else -# define LZO_SIZEOF_VOID_P 2 -# endif -#elif (LZO_ARCH_SPU) -# define LZO_SIZEOF_VOID_P 4 -#elif (LZO_ARCH_Z80) -# define LZO_SIZEOF_VOID_P 2 -#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) -# define LZO_SIZEOF_VOID_P 4 -#elif (LZO_OS_OS400 || defined(__OS400__)) -# if defined(__LLP64_IFC__) -# define LZO_SIZEOF_VOID_P 8 -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG -# else -# define LZO_SIZEOF_VOID_P 16 -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG -# endif -#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) -# define LZO_SIZEOF_VOID_P 8 -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG -#endif -#endif -#if !defined(LZO_SIZEOF_VOID_P) -# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG -#endif -LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_VOID_P == sizeof(void *)) -#if !defined(LZO_SIZEOF_SIZE_T) -#if (LZO_ARCH_I086 || LZO_ARCH_M16C) -# define LZO_SIZEOF_SIZE_T 2 -#endif -#endif -#if !defined(LZO_SIZEOF_SIZE_T) -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P -#endif -#if defined(offsetof) -LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SIZE_T == sizeof(size_t)) -#endif -#if !defined(LZO_SIZEOF_PTRDIFF_T) -#if (LZO_ARCH_I086) -# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P -# elif (LZO_MM_COMPACT || LZO_MM_LARGE) -# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) -# define LZO_SIZEOF_PTRDIFF_T 4 -# else -# define LZO_SIZEOF_PTRDIFF_T 2 -# endif -# else -# error "invalid LZO_ARCH_I086 memory model" -# endif -#endif -#endif -#if !defined(LZO_SIZEOF_PTRDIFF_T) -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T -#endif -#if defined(offsetof) -LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t)) -#endif -#if !defined(LZO_WORDSIZE) -# define LZO_WORDSIZE LZO_SIZEOF_VOID_P -#endif -#if (LZO_ABI_NEUTRAL_ENDIAN) -# undef LZO_ABI_BIG_ENDIAN -# undef LZO_ABI_LITTLE_ENDIAN -#elif !(LZO_ABI_BIG_ENDIAN) && !(LZO_ABI_LITTLE_ENDIAN) -#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) -# define LZO_ABI_BIG_ENDIAN 1 -#elif (LZO_ARCH_IA64) && (LZO_OS_POSIX_LINUX || LZO_OS_WIN64) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430 || LZO_ARCH_RISCV) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390 || LZO_ARCH_SPU) -# define LZO_ABI_BIG_ENDIAN 1 -#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) -# if (__LITTLE_ENDIAN__ == 1) -# define LZO_ABI_LITTLE_ENDIAN 1 -# else -# define LZO_ABI_BIG_ENDIAN 1 -# endif -#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) -# define LZO_ABI_BIG_ENDIAN 1 -#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM) && defined(__ARM_BIG_ENDIAN) && ((__ARM_BIG_ENDIAN)+0) -# define LZO_ABI_BIG_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) -# define LZO_ABI_BIG_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM) && defined(_MSC_VER) && defined(_WIN32) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM && LZO_CC_ARMCC_ARMCC) -# if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) -# error "unexpected configuration - check your compiler defines" -# elif defined(__BIG_ENDIAN) -# define LZO_ABI_BIG_ENDIAN 1 -# else -# define LZO_ABI_LITTLE_ENDIAN 1 -# endif -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM64) && defined(__ARM_BIG_ENDIAN) && ((__ARM_BIG_ENDIAN)+0) -# define LZO_ABI_BIG_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EB__) && !defined(__AARCH64EL__) -# define LZO_ABI_BIG_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EL__) && !defined(__AARCH64EB__) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM64) && defined(_MSC_VER) && defined(_WIN32) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) -# define LZO_ABI_BIG_ENDIAN 1 -#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) -# define LZO_ABI_LITTLE_ENDIAN 1 -#endif -#endif -#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ABI_BIG_ENDIAN) -# define LZO_INFO_ABI_ENDIAN "be" -#elif (LZO_ABI_LITTLE_ENDIAN) -# define LZO_INFO_ABI_ENDIAN "le" -#elif (LZO_ABI_NEUTRAL_ENDIAN) -# define LZO_INFO_ABI_ENDIAN "neutral" -#endif -#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) -# define LZO_ABI_I8LP16 1 -# define LZO_INFO_ABI_PM "i8lp16" -#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) -# define LZO_ABI_ILP16 1 -# define LZO_INFO_ABI_PM "ilp16" -#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) -# define LZO_ABI_LP32 1 -# define LZO_INFO_ABI_PM "lp32" -#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) -# define LZO_ABI_ILP32 1 -# define LZO_INFO_ABI_PM "ilp32" -#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) -# define LZO_ABI_LLP64 1 -# define LZO_INFO_ABI_PM "llp64" -#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) -# define LZO_ABI_LP64 1 -# define LZO_INFO_ABI_PM "lp64" -#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) -# define LZO_ABI_ILP64 1 -# define LZO_INFO_ABI_PM "ilp64" -#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) -# define LZO_ABI_IP32L64 1 -# define LZO_INFO_ABI_PM "ip32l64" -#endif -#if (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_VOID_P == 4 && LZO_WORDSIZE == 8) -# define LZO_ABI_IP32W64 1 -# ifndef LZO_INFO_ABI_PM -# define LZO_INFO_ABI_PM "ip32w64" -# endif -#endif -#if 0 -#elif !defined(__LZO_LIBC_OVERRIDE) -#if (LZO_LIBC_NAKED) -# define LZO_INFO_LIBC "naked" -#elif (LZO_LIBC_FREESTANDING) -# define LZO_INFO_LIBC "freestanding" -#elif (LZO_LIBC_MOSTLY_FREESTANDING) -# define LZO_INFO_LIBC "mfreestanding" -#elif (LZO_LIBC_ISOC90) -# define LZO_INFO_LIBC "isoc90" -#elif (LZO_LIBC_ISOC99) -# define LZO_INFO_LIBC "isoc99" -#elif (LZO_CC_ARMCC_ARMCC) && defined(__ARMCLIB_VERSION) -# define LZO_LIBC_ISOC90 1 -# define LZO_INFO_LIBC "isoc90" -#elif defined(__dietlibc__) -# define LZO_LIBC_DIETLIBC 1 -# define LZO_INFO_LIBC "dietlibc" -#elif defined(_NEWLIB_VERSION) -# define LZO_LIBC_NEWLIB 1 -# define LZO_INFO_LIBC "newlib" -#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) -# if defined(__UCLIBC_SUBLEVEL__) -# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + (__UCLIBC_MINOR__-0) * 0x100 + (__UCLIBC_SUBLEVEL__-0)) -# else -# define LZO_LIBC_UCLIBC 0x00090bL -# endif -# define LZO_INFO_LIBC "uc" "libc" -#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) -# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + (__GLIBC_MINOR__-0) * 0x100) -# define LZO_INFO_LIBC "glibc" -#elif (LZO_CC_MWERKS) && defined(__MSL__) -# define LZO_LIBC_MSL __MSL__ -# define LZO_INFO_LIBC "msl" -#elif 1 && defined(__IAR_SYSTEMS_ICC__) -# define LZO_LIBC_ISOC90 1 -# define LZO_INFO_LIBC "isoc90" -#else -# define LZO_LIBC_DEFAULT 1 -# define LZO_INFO_LIBC "default" -#endif -#endif -#if (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) -# define LZO_ASM_SYNTAX_MSC 1 -#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) -#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul)) -#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) -# define LZO_ASM_SYNTAX_GNUC 1 -#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) -# define LZO_ASM_SYNTAX_GNUC 1 -#elif (LZO_CC_GNUC) -# define LZO_ASM_SYNTAX_GNUC 1 -#endif -#if (LZO_ASM_SYNTAX_GNUC) -#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) -# define __LZO_ASM_CLOBBER "ax" -# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ -# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY /*empty*/ -# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ -#elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1000)) -# define __LZO_ASM_CLOBBER "memory" -# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ -# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "memory" -# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ -#else -# define __LZO_ASM_CLOBBER "cc", "memory" -# define __LZO_ASM_CLOBBER_LIST_CC : "cc" -# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "cc", "memory" -# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ -#endif -#endif -#if (LZO_ARCH_ALPHA) -# define LZO_OPT_AVOID_UINT_INDEX 1 -#elif (LZO_ARCH_AMD64) -# define LZO_OPT_AVOID_INT_INDEX 1 -# define LZO_OPT_AVOID_UINT_INDEX 1 -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# ifndef LZO_OPT_UNALIGNED64 -# define LZO_OPT_UNALIGNED64 1 -# endif -#elif (LZO_ARCH_ARM) -# if defined(__ARM_FEATURE_UNALIGNED) -# if ((__ARM_FEATURE_UNALIGNED)+0) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# endif -# elif 1 && (LZO_ARCH_ARM_THUMB2) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# elif 1 && defined(__ARM_ARCH) && ((__ARM_ARCH)+0 >= 7) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 7) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 6) && (defined(__TARGET_PROFILE_A) || defined(__TARGET_PROFILE_R)) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# elif 1 && defined(_MSC_VER) && defined(_M_ARM) && ((_M_ARM)+0 >= 7) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# endif -#elif (LZO_ARCH_ARM64) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# ifndef LZO_OPT_UNALIGNED64 -# define LZO_OPT_UNALIGNED64 1 -# endif -#elif (LZO_ARCH_CRIS) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -#elif (LZO_ARCH_I386) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -#elif (LZO_ARCH_IA64) -# define LZO_OPT_AVOID_INT_INDEX 1 -# define LZO_OPT_AVOID_UINT_INDEX 1 -# define LZO_OPT_PREFER_POSTINC 1 -#elif (LZO_ARCH_M68K) -# define LZO_OPT_PREFER_POSTINC 1 -# define LZO_OPT_PREFER_PREDEC 1 -# if defined(__mc68020__) && !defined(__mcoldfire__) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# endif -#elif (LZO_ARCH_MIPS) -# define LZO_OPT_AVOID_UINT_INDEX 1 -#elif (LZO_ARCH_POWERPC) -# define LZO_OPT_PREFER_PREINC 1 -# define LZO_OPT_PREFER_PREDEC 1 -# if (LZO_ABI_BIG_ENDIAN) || (LZO_WORDSIZE == 8) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# if (LZO_WORDSIZE == 8) -# ifndef LZO_OPT_UNALIGNED64 -# define LZO_OPT_UNALIGNED64 1 -# endif -# endif -# endif -#elif (LZO_ARCH_RISCV) -# define LZO_OPT_AVOID_UINT_INDEX 1 -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# if (LZO_WORDSIZE == 8) -# ifndef LZO_OPT_UNALIGNED64 -# define LZO_OPT_UNALIGNED64 1 -# endif -# endif -#elif (LZO_ARCH_S390) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# if (LZO_WORDSIZE == 8) -# ifndef LZO_OPT_UNALIGNED64 -# define LZO_OPT_UNALIGNED64 1 -# endif -# endif -#elif (LZO_ARCH_SH) -# define LZO_OPT_PREFER_POSTINC 1 -# define LZO_OPT_PREFER_PREDEC 1 -#endif -#ifndef LZO_CFG_NO_INLINE_ASM -#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) -# define LZO_CFG_NO_INLINE_ASM 1 -#elif (LZO_CC_LLVM) -# define LZO_CFG_NO_INLINE_ASM 1 -#endif -#endif -#if (LZO_CFG_NO_INLINE_ASM) -# undef LZO_ASM_SYNTAX_MSC -# undef LZO_ASM_SYNTAX_GNUC -# undef __LZO_ASM_CLOBBER -# undef __LZO_ASM_CLOBBER_LIST_CC -# undef __LZO_ASM_CLOBBER_LIST_CC_MEMORY -# undef __LZO_ASM_CLOBBER_LIST_EMPTY -#endif -#ifndef LZO_CFG_NO_UNALIGNED -#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) -# define LZO_CFG_NO_UNALIGNED 1 -#endif -#endif -#if (LZO_CFG_NO_UNALIGNED) -# undef LZO_OPT_UNALIGNED16 -# undef LZO_OPT_UNALIGNED32 -# undef LZO_OPT_UNALIGNED64 -#endif -#if defined(__LZO_INFOSTR_MM) -#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) -# define __LZO_INFOSTR_MM "" -#elif defined(LZO_INFO_MM) -# define __LZO_INFOSTR_MM "." LZO_INFO_MM -#else -# define __LZO_INFOSTR_MM "" -#endif -#if defined(__LZO_INFOSTR_PM) -#elif defined(LZO_INFO_ABI_PM) -# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM -#else -# define __LZO_INFOSTR_PM "" -#endif -#if defined(__LZO_INFOSTR_ENDIAN) -#elif defined(LZO_INFO_ABI_ENDIAN) -# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN -#else -# define __LZO_INFOSTR_ENDIAN "" -#endif -#if defined(__LZO_INFOSTR_OSNAME) -#elif defined(LZO_INFO_OS_CONSOLE) -# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE -#elif defined(LZO_INFO_OS_POSIX) -# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX -#else -# define __LZO_INFOSTR_OSNAME LZO_INFO_OS -#endif -#if defined(__LZO_INFOSTR_LIBC) -#elif defined(LZO_INFO_LIBC) -# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC -#else -# define __LZO_INFOSTR_LIBC "" -#endif -#if defined(__LZO_INFOSTR_CCVER) -#elif defined(LZO_INFO_CCVER) -# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER -#else -# define __LZO_INFOSTR_CCVER "" -#endif -#define LZO_INFO_STRING \ - LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ - " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER -#if !(LZO_CFG_SKIP_LZO_TYPES) -#if (!(LZO_SIZEOF_SHORT+0 > 0 && LZO_SIZEOF_INT+0 > 0 && LZO_SIZEOF_LONG+0 > 0)) -# error "missing defines for sizes" -#endif -#if (!(LZO_SIZEOF_PTRDIFF_T+0 > 0 && LZO_SIZEOF_SIZE_T+0 > 0 && LZO_SIZEOF_VOID_P+0 > 0)) -# error "missing defines for sizes" -#endif -#define LZO_TYPEOF_CHAR 1u -#define LZO_TYPEOF_SHORT 2u -#define LZO_TYPEOF_INT 3u -#define LZO_TYPEOF_LONG 4u -#define LZO_TYPEOF_LONG_LONG 5u -#define LZO_TYPEOF___INT8 17u -#define LZO_TYPEOF___INT16 18u -#define LZO_TYPEOF___INT32 19u -#define LZO_TYPEOF___INT64 20u -#define LZO_TYPEOF___INT128 21u -#define LZO_TYPEOF___INT256 22u -#define LZO_TYPEOF___MODE_QI 33u -#define LZO_TYPEOF___MODE_HI 34u -#define LZO_TYPEOF___MODE_SI 35u -#define LZO_TYPEOF___MODE_DI 36u -#define LZO_TYPEOF___MODE_TI 37u -#define LZO_TYPEOF_CHAR_P 129u -#if !defined(lzo_llong_t) -#if (LZO_SIZEOF_LONG_LONG+0 > 0) -# if !(LZO_LANG_ASSEMBLER) - __lzo_gnuc_extension__ typedef long long lzo_llong_t__; - __lzo_gnuc_extension__ typedef unsigned long long lzo_ullong_t__; -# endif -# define lzo_llong_t lzo_llong_t__ -# define lzo_ullong_t lzo_ullong_t__ -#endif -#endif -#if !defined(lzo_int16e_t) -#if (LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) && (LZO_SIZEOF_SHORT != 2) -# undef LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T -#endif -#if (LZO_SIZEOF_LONG == 2) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) -# define lzo_int16e_t long -# define lzo_uint16e_t unsigned long -# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_LONG -#elif (LZO_SIZEOF_INT == 2) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) -# define lzo_int16e_t int -# define lzo_uint16e_t unsigned int -# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_INT -#elif (LZO_SIZEOF_SHORT == 2) -# define lzo_int16e_t short int -# define lzo_uint16e_t unsigned short int -# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_SHORT -#elif 1 && !(LZO_CFG_TYPE_NO_MODE_HI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) -# if !(LZO_LANG_ASSEMBLER) - typedef int lzo_int16e_hi_t__ __attribute__((__mode__(__HI__))); - typedef unsigned int lzo_uint16e_hi_t__ __attribute__((__mode__(__HI__))); -# endif -# define lzo_int16e_t lzo_int16e_hi_t__ -# define lzo_uint16e_t lzo_uint16e_hi_t__ -# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF___MODE_HI -#elif (LZO_SIZEOF___INT16 == 2) -# define lzo_int16e_t __int16 -# define lzo_uint16e_t unsigned __int16 -# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF___INT16 -#else -#endif -#endif -#if defined(lzo_int16e_t) -# define LZO_SIZEOF_LZO_INT16E_T 2 - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == 2) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == LZO_SIZEOF_LZO_INT16E_T) -#endif -#if !defined(lzo_int32e_t) -#if (LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T == LZO_TYPEOF_INT) && (LZO_SIZEOF_INT != 4) -# undef LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T -#endif -#if (LZO_SIZEOF_LONG == 4) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T == LZO_TYPEOF_INT) -# define lzo_int32e_t long int -# define lzo_uint32e_t unsigned long int -# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_LONG -#elif (LZO_SIZEOF_INT == 4) -# define lzo_int32e_t int -# define lzo_uint32e_t unsigned int -# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_INT -#elif (LZO_SIZEOF_SHORT == 4) -# define lzo_int32e_t short int -# define lzo_uint32e_t unsigned short int -# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_SHORT -#elif (LZO_SIZEOF_LONG_LONG == 4) -# define lzo_int32e_t lzo_llong_t -# define lzo_uint32e_t lzo_ullong_t -# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_LONG_LONG -#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) && (__INT_MAX__+0 > 2147483647L) -# if !(LZO_LANG_ASSEMBLER) - typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); - typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); -# endif -# define lzo_int32e_t lzo_int32e_si_t__ -# define lzo_uint32e_t lzo_uint32e_si_t__ -# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___MODE_SI -#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_GNUC >= 0x025f00ul) && defined(__AVR__) && (__LONG_MAX__+0 == 32767L) -# if !(LZO_LANG_ASSEMBLER) - typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); - typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); -# endif -# define lzo_int32e_t lzo_int32e_si_t__ -# define lzo_uint32e_t lzo_uint32e_si_t__ -# define LZO_INT32_C(c) (c##LL) -# define LZO_UINT32_C(c) (c##ULL) -# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___MODE_SI -#elif (LZO_SIZEOF___INT32 == 4) -# define lzo_int32e_t __int32 -# define lzo_uint32e_t unsigned __int32 -# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___INT32 -#else -#endif -#endif -#if defined(lzo_int32e_t) -# define LZO_SIZEOF_LZO_INT32E_T 4 - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == 4) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == LZO_SIZEOF_LZO_INT32E_T) -#endif -#if !defined(lzo_int64e_t) -#if (LZO_SIZEOF___INT64 == 8) -# if (LZO_CC_BORLANDC) && !defined(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T) -# define LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T LZO_TYPEOF___INT64 -# endif -#endif -#if (LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF_LONG_LONG) && (LZO_SIZEOF_LONG_LONG != 8) -# undef LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T -#endif -#if (LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) && (LZO_SIZEOF___INT64 != 8) -# undef LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T -#endif -#if (LZO_SIZEOF_INT == 8) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) -# define lzo_int64e_t int -# define lzo_uint64e_t unsigned int -# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_INT -#elif (LZO_SIZEOF_LONG == 8) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF_LONG_LONG) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) -# define lzo_int64e_t long int -# define lzo_uint64e_t unsigned long int -# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_LONG -#elif (LZO_SIZEOF_LONG_LONG == 8) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) -# define lzo_int64e_t lzo_llong_t -# define lzo_uint64e_t lzo_ullong_t -# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_LONG_LONG -# if (LZO_CC_BORLANDC) -# define LZO_INT64_C(c) ((c) + 0ll) -# define LZO_UINT64_C(c) ((c) + 0ull) -# elif 0 -# define LZO_INT64_C(c) (__lzo_gnuc_extension__ (c##LL)) -# define LZO_UINT64_C(c) (__lzo_gnuc_extension__ (c##ULL)) -# else -# define LZO_INT64_C(c) (c##LL) -# define LZO_UINT64_C(c) (c##ULL) -# endif -#elif (LZO_SIZEOF___INT64 == 8) -# define lzo_int64e_t __int64 -# define lzo_uint64e_t unsigned __int64 -# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF___INT64 -# if (LZO_CC_BORLANDC) -# define LZO_INT64_C(c) ((c) + 0i64) -# define LZO_UINT64_C(c) ((c) + 0ui64) -# else -# define LZO_INT64_C(c) (c##i64) -# define LZO_UINT64_C(c) (c##ui64) -# endif -#else -#endif -#endif -#if defined(lzo_int64e_t) -# define LZO_SIZEOF_LZO_INT64E_T 8 - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == 8) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == LZO_SIZEOF_LZO_INT64E_T) -#endif -#if !defined(lzo_int32l_t) -#if defined(lzo_int32e_t) -# define lzo_int32l_t lzo_int32e_t -# define lzo_uint32l_t lzo_uint32e_t -# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LZO_INT32E_T -# define LZO_TYPEOF_LZO_INT32L_T LZO_TYPEOF_LZO_INT32E_T -#elif (LZO_SIZEOF_INT >= 4) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) -# define lzo_int32l_t int -# define lzo_uint32l_t unsigned int -# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_INT -# define LZO_TYPEOF_LZO_INT32L_T LZO_SIZEOF_INT -#elif (LZO_SIZEOF_LONG >= 4) -# define lzo_int32l_t long int -# define lzo_uint32l_t unsigned long int -# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LONG -# define LZO_TYPEOF_LZO_INT32L_T LZO_SIZEOF_LONG -#else -# error "lzo_int32l_t" -#endif -#endif -#if 1 - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) >= 4) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) == LZO_SIZEOF_LZO_INT32L_T) -#endif -#if !defined(lzo_int64l_t) -#if defined(lzo_int64e_t) -# define lzo_int64l_t lzo_int64e_t -# define lzo_uint64l_t lzo_uint64e_t -# define LZO_SIZEOF_LZO_INT64L_T LZO_SIZEOF_LZO_INT64E_T -# define LZO_TYPEOF_LZO_INT64L_T LZO_TYPEOF_LZO_INT64E_T -#else -#endif -#endif -#if defined(lzo_int64l_t) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) >= 8) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) == LZO_SIZEOF_LZO_INT64L_T) -#endif -#if !defined(lzo_int32f_t) -#if (LZO_SIZEOF_SIZE_T >= 8) -# define lzo_int32f_t lzo_int64l_t -# define lzo_uint32f_t lzo_uint64l_t -# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT64L_T -# define LZO_TYPEOF_LZO_INT32F_T LZO_TYPEOF_LZO_INT64L_T -#else -# define lzo_int32f_t lzo_int32l_t -# define lzo_uint32f_t lzo_uint32l_t -# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT32L_T -# define LZO_TYPEOF_LZO_INT32F_T LZO_TYPEOF_LZO_INT32L_T -#endif -#endif -#if 1 - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) >= 4) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) == LZO_SIZEOF_LZO_INT32F_T) -#endif -#if !defined(lzo_int64f_t) -#if defined(lzo_int64l_t) -# define lzo_int64f_t lzo_int64l_t -# define lzo_uint64f_t lzo_uint64l_t -# define LZO_SIZEOF_LZO_INT64F_T LZO_SIZEOF_LZO_INT64L_T -# define LZO_TYPEOF_LZO_INT64F_T LZO_TYPEOF_LZO_INT64L_T -#else -#endif -#endif -#if defined(lzo_int64f_t) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) >= 8) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) == LZO_SIZEOF_LZO_INT64F_T) -#endif -#if !defined(lzo_intptr_t) -#if 1 && (LZO_OS_OS400 && (LZO_SIZEOF_VOID_P == 16)) -# define __LZO_INTPTR_T_IS_POINTER 1 -# if !(LZO_LANG_ASSEMBLER) - typedef char * lzo_intptr_t; - typedef char * lzo_uintptr_t; -# endif -# define lzo_intptr_t lzo_intptr_t -# define lzo_uintptr_t lzo_uintptr_t -# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_VOID_P -# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_CHAR_P -#elif (LZO_CC_MSC && (_MSC_VER >= 1300) && (LZO_SIZEOF_VOID_P == 4) && (LZO_SIZEOF_INT == 4)) -# if !(LZO_LANG_ASSEMBLER) - typedef __w64 int lzo_intptr_t; - typedef __w64 unsigned int lzo_uintptr_t; -# endif -# define lzo_intptr_t lzo_intptr_t -# define lzo_uintptr_t lzo_uintptr_t -# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT -# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_INT -#elif (LZO_SIZEOF_SHORT == LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT > LZO_SIZEOF_VOID_P) -# define lzo_intptr_t short -# define lzo_uintptr_t unsigned short -# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_SHORT -# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_SHORT -#elif (LZO_SIZEOF_INT >= LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) -# define lzo_intptr_t int -# define lzo_uintptr_t unsigned int -# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT -# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_INT -#elif (LZO_SIZEOF_LONG >= LZO_SIZEOF_VOID_P) -# define lzo_intptr_t long -# define lzo_uintptr_t unsigned long -# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LONG -# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_LONG -#elif (LZO_SIZEOF_LZO_INT64L_T >= LZO_SIZEOF_VOID_P) -# define lzo_intptr_t lzo_int64l_t -# define lzo_uintptr_t lzo_uint64l_t -# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LZO_INT64L_T -# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_LZO_INT64L_T -#else -# error "lzo_intptr_t" -#endif -#endif -#if 1 - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) >= sizeof(void *)) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) == sizeof(lzo_uintptr_t)) -#endif -#if !defined(lzo_word_t) -#if defined(LZO_WORDSIZE) && (LZO_WORDSIZE+0 > 0) -#if (LZO_WORDSIZE == LZO_SIZEOF_LZO_INTPTR_T) && !(__LZO_INTPTR_T_IS_POINTER) -# define lzo_word_t lzo_uintptr_t -# define lzo_sword_t lzo_intptr_t -# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INTPTR_T -# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_LZO_INTPTR_T -#elif (LZO_WORDSIZE == LZO_SIZEOF_LONG) -# define lzo_word_t unsigned long -# define lzo_sword_t long -# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LONG -# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_LONG -#elif (LZO_WORDSIZE == LZO_SIZEOF_INT) -# define lzo_word_t unsigned int -# define lzo_sword_t int -# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_INT -# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_INT -#elif (LZO_WORDSIZE == LZO_SIZEOF_SHORT) -# define lzo_word_t unsigned short -# define lzo_sword_t short -# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_SHORT -# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_SHORT -#elif (LZO_WORDSIZE == 1) -# define lzo_word_t unsigned char -# define lzo_sword_t signed char -# define LZO_SIZEOF_LZO_WORD_T 1 -# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_CHAR -#elif (LZO_WORDSIZE == LZO_SIZEOF_LZO_INT64L_T) -# define lzo_word_t lzo_uint64l_t -# define lzo_sword_t lzo_int64l_t -# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T -# define LZO_TYPEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T -#elif (LZO_ARCH_SPU) && (LZO_CC_GNUC) -#if 0 -# if !(LZO_LANG_ASSEMBLER) - typedef unsigned lzo_word_t __attribute__((__mode__(__V16QI__))); - typedef int lzo_sword_t __attribute__((__mode__(__V16QI__))); -# endif -# define lzo_word_t lzo_word_t -# define lzo_sword_t lzo_sword_t -# define LZO_SIZEOF_LZO_WORD_T 16 -# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF___MODE_V16QI -#endif -#else -# error "lzo_word_t" -#endif -#endif -#endif -#if 1 && defined(lzo_word_t) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_word_t) == LZO_WORDSIZE) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_sword_t) == LZO_WORDSIZE) -#endif -#if 1 -#define lzo_int8_t signed char -#define lzo_uint8_t unsigned char -#define LZO_SIZEOF_LZO_INT8_T 1 -#define LZO_TYPEOF_LZO_INT8_T LZO_TYPEOF_CHAR -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == sizeof(lzo_uint8_t)) -#endif -#if defined(lzo_int16e_t) -#define lzo_int16_t lzo_int16e_t -#define lzo_uint16_t lzo_uint16e_t -#define LZO_SIZEOF_LZO_INT16_T LZO_SIZEOF_LZO_INT16E_T -#define LZO_TYPEOF_LZO_INT16_T LZO_TYPEOF_LZO_INT16E_T -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == sizeof(lzo_uint16_t)) -#endif -#if defined(lzo_int32e_t) -#define lzo_int32_t lzo_int32e_t -#define lzo_uint32_t lzo_uint32e_t -#define LZO_SIZEOF_LZO_INT32_T LZO_SIZEOF_LZO_INT32E_T -#define LZO_TYPEOF_LZO_INT32_T LZO_TYPEOF_LZO_INT32E_T -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == sizeof(lzo_uint32_t)) -#endif -#if defined(lzo_int64e_t) -#define lzo_int64_t lzo_int64e_t -#define lzo_uint64_t lzo_uint64e_t -#define LZO_SIZEOF_LZO_INT64_T LZO_SIZEOF_LZO_INT64E_T -#define LZO_TYPEOF_LZO_INT64_T LZO_TYPEOF_LZO_INT64E_T -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == sizeof(lzo_uint64_t)) -#endif -#if 1 -#define lzo_int_least32_t lzo_int32l_t -#define lzo_uint_least32_t lzo_uint32l_t -#define LZO_SIZEOF_LZO_INT_LEAST32_T LZO_SIZEOF_LZO_INT32L_T -#define LZO_TYPEOF_LZO_INT_LEAST32_T LZO_TYPEOF_LZO_INT32L_T -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) >= 4) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) == sizeof(lzo_uint_least32_t)) -#endif -#if defined(lzo_int64l_t) -#define lzo_int_least64_t lzo_int64l_t -#define lzo_uint_least64_t lzo_uint64l_t -#define LZO_SIZEOF_LZO_INT_LEAST64_T LZO_SIZEOF_LZO_INT64L_T -#define LZO_TYPEOF_LZO_INT_LEAST64_T LZO_TYPEOF_LZO_INT64L_T -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) >= 8) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) == sizeof(lzo_uint_least64_t)) -#endif -#if 1 -#define lzo_int_fast32_t lzo_int32f_t -#define lzo_uint_fast32_t lzo_uint32f_t -#define LZO_SIZEOF_LZO_INT_FAST32_T LZO_SIZEOF_LZO_INT32F_T -#define LZO_TYPEOF_LZO_INT_FAST32_T LZO_TYPEOF_LZO_INT32F_T -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) >= 4) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) == sizeof(lzo_uint_fast32_t)) -#endif -#if defined(lzo_int64f_t) -#define lzo_int_fast64_t lzo_int64f_t -#define lzo_uint_fast64_t lzo_uint64f_t -#define LZO_SIZEOF_LZO_INT_FAST64_T LZO_SIZEOF_LZO_INT64F_T -#define LZO_TYPEOF_LZO_INT_FAST64_T LZO_TYPEOF_LZO_INT64F_T -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) >= 8) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) == sizeof(lzo_uint_fast64_t)) -#endif -#if !defined(LZO_INT16_C) -# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 2) -# define LZO_INT16_C(c) ((c) + 0) -# define LZO_UINT16_C(c) ((c) + 0U) -# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 2) -# define LZO_INT16_C(c) ((c) + 0L) -# define LZO_UINT16_C(c) ((c) + 0UL) -# elif (LZO_SIZEOF_INT >= 2) -# define LZO_INT16_C(c) (c) -# define LZO_UINT16_C(c) (c##U) -# elif (LZO_SIZEOF_LONG >= 2) -# define LZO_INT16_C(c) (c##L) -# define LZO_UINT16_C(c) (c##UL) -# else -# error "LZO_INT16_C" -# endif -#endif -#if !defined(LZO_INT32_C) -# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 4) -# define LZO_INT32_C(c) ((c) + 0) -# define LZO_UINT32_C(c) ((c) + 0U) -# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 4) -# define LZO_INT32_C(c) ((c) + 0L) -# define LZO_UINT32_C(c) ((c) + 0UL) -# elif (LZO_SIZEOF_INT >= 4) -# define LZO_INT32_C(c) (c) -# define LZO_UINT32_C(c) (c##U) -# elif (LZO_SIZEOF_LONG >= 4) -# define LZO_INT32_C(c) (c##L) -# define LZO_UINT32_C(c) (c##UL) -# elif (LZO_SIZEOF_LONG_LONG >= 4) -# define LZO_INT32_C(c) (c##LL) -# define LZO_UINT32_C(c) (c##ULL) -# else -# error "LZO_INT32_C" -# endif -#endif -#if !defined(LZO_INT64_C) && defined(lzo_int64l_t) -# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 8) -# define LZO_INT64_C(c) ((c) + 0) -# define LZO_UINT64_C(c) ((c) + 0U) -# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 8) -# define LZO_INT64_C(c) ((c) + 0L) -# define LZO_UINT64_C(c) ((c) + 0UL) -# elif (LZO_SIZEOF_INT >= 8) -# define LZO_INT64_C(c) (c) -# define LZO_UINT64_C(c) (c##U) -# elif (LZO_SIZEOF_LONG >= 8) -# define LZO_INT64_C(c) (c##L) -# define LZO_UINT64_C(c) (c##UL) -# else -# error "LZO_INT64_C" -# endif -#endif -#endif - -#endif /* already included */ - -/* vim:set ts=4 sw=4 et: */ diff --git a/grub-core/lib/minilzo/minilzo.c b/grub-core/lib/minilzo/minilzo.c deleted file mode 100644 index 8fd866450..000000000 --- a/grub-core/lib/minilzo/minilzo.c +++ /dev/null @@ -1,6365 +0,0 @@ -/* minilzo.c -- mini subset of the LZO real-time data compression library - - This file is part of the LZO real-time data compression library. - - Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer - All Rights Reserved. - - The LZO library is free software; you can 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. - - The LZO 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with the LZO library; see the file COPYING. - If not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - Markus F.X.J. Oberhumer - - http://www.oberhumer.com/opensource/lzo/ - */ - -/* - * NOTE: - * the full LZO package can be found at - * http://www.oberhumer.com/opensource/lzo/ - */ - -#define __LZO_IN_MINILZO 1 - -#if defined(LZO_CFG_FREESTANDING) -# undef MINILZO_HAVE_CONFIG_H -# define LZO_LIBC_FREESTANDING 1 -# define LZO_OS_FREESTANDING 1 -#endif - -#ifdef MINILZO_HAVE_CONFIG_H -# include -#endif -#include -#include -#if defined(MINILZO_CFG_USE_INTERNAL_LZODEFS) - -#ifndef __LZODEFS_H_INCLUDED -#define __LZODEFS_H_INCLUDED 1 - -#if defined(__CYGWIN32__) && !defined(__CYGWIN__) -# define __CYGWIN__ __CYGWIN32__ -#endif -#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) -# define _ALL_SOURCE 1 -#endif -#if defined(__mips__) && defined(__R5900__) -# if !defined(__LONG_MAX__) -# define __LONG_MAX__ 9223372036854775807L -# endif -#endif -#if 0 -#elif !defined(__LZO_LANG_OVERRIDE) -#if (defined(__clang__) || defined(__GNUC__)) && defined(__ASSEMBLER__) -# if (__ASSEMBLER__+0) <= 0 -# error "__ASSEMBLER__" -# else -# define LZO_LANG_ASSEMBLER 1 -# endif -#elif defined(__cplusplus) -# if (__cplusplus+0) <= 0 -# error "__cplusplus" -# elif (__cplusplus < 199711L) -# define LZO_LANG_CXX 1 -# elif defined(_MSC_VER) && defined(_MSVC_LANG) && (_MSVC_LANG+0 >= 201402L) && 1 -# define LZO_LANG_CXX _MSVC_LANG -# else -# define LZO_LANG_CXX __cplusplus -# endif -# define LZO_LANG_CPLUSPLUS LZO_LANG_CXX -#else -# if defined(__STDC_VERSION__) && (__STDC_VERSION__+0 >= 199409L) -# define LZO_LANG_C __STDC_VERSION__ -# else -# define LZO_LANG_C 1 -# endif -#endif -#endif -#if !defined(LZO_CFG_NO_DISABLE_WUNDEF) -#if defined(__ARMCC_VERSION) -# pragma diag_suppress 193 -#elif defined(__clang__) && defined(__clang_minor__) -# pragma clang diagnostic ignored "-Wundef" -#elif defined(__INTEL_COMPILER) -# pragma warning(disable: 193) -#elif defined(__KEIL__) && defined(__C166__) -# pragma warning disable = 322 -#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && !defined(__PATHSCALE__) -# if ((__GNUC__-0) >= 5 || ((__GNUC__-0) == 4 && (__GNUC_MINOR__-0) >= 2)) -# pragma GCC diagnostic ignored "-Wundef" -# endif -#elif defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) -# if ((_MSC_VER-0) >= 1300) -# pragma warning(disable: 4668) -# endif -#endif -#endif -#if 0 && defined(__POCC__) && defined(_WIN32) -# if (__POCC__ >= 400) -# pragma warn(disable: 2216) -# endif -#endif -#if 0 && defined(__WATCOMC__) -# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) -# pragma warning 203 9 -# endif -#endif -#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) -# pragma option -h -#endif -#if !(LZO_CFG_NO_DISABLE_WCRTNONSTDC) -#ifndef _CRT_NONSTDC_NO_DEPRECATE -#define _CRT_NONSTDC_NO_DEPRECATE 1 -#endif -#ifndef _CRT_NONSTDC_NO_WARNINGS -#define _CRT_NONSTDC_NO_WARNINGS 1 -#endif -#ifndef _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif -#ifndef _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_WARNINGS 1 -#endif -#endif -#if 0 -#define LZO_0xffffUL 0xfffful -#define LZO_0xffffffffUL 0xfffffffful -#else -#define LZO_0xffffUL 65535ul -#define LZO_0xffffffffUL 4294967295ul -#endif -#define LZO_0xffffL LZO_0xffffUL -#define LZO_0xffffffffL LZO_0xffffffffUL -#if (LZO_0xffffL == LZO_0xffffffffL) -# error "your preprocessor is broken 1" -#endif -#if (16ul * 16384ul != 262144ul) -# error "your preprocessor is broken 2" -#endif -#if 0 -#if (32767 >= 4294967295ul) -# error "your preprocessor is broken 3" -#endif -#if (65535u >= 4294967295ul) -# error "your preprocessor is broken 4" -#endif -#endif -#if defined(__COUNTER__) -# ifndef LZO_CFG_USE_COUNTER -# define LZO_CFG_USE_COUNTER 1 -# endif -#else -# undef LZO_CFG_USE_COUNTER -#endif -#if (UINT_MAX == LZO_0xffffL) -#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) -# if !defined(MSDOS) -# define MSDOS 1 -# endif -# if !defined(_MSDOS) -# define _MSDOS 1 -# endif -#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) -# if (__VERSION == 520) && (MB_LEN_MAX == 1) -# if !defined(__AZTEC_C__) -# define __AZTEC_C__ __VERSION -# endif -# if !defined(__DOS__) -# define __DOS__ 1 -# endif -# endif -#endif -#endif -#if (UINT_MAX == LZO_0xffffL) -#if defined(_MSC_VER) && defined(M_I86HM) -# define ptrdiff_t long -# define _PTRDIFF_T_DEFINED 1 -#endif -#endif -#if (UINT_MAX == LZO_0xffffL) -# undef __LZO_RENAME_A -# undef __LZO_RENAME_B -# if defined(__AZTEC_C__) && defined(__DOS__) -# define __LZO_RENAME_A 1 -# elif defined(_MSC_VER) && defined(MSDOS) -# if (_MSC_VER < 600) -# define __LZO_RENAME_A 1 -# elif (_MSC_VER < 700) -# define __LZO_RENAME_B 1 -# endif -# elif defined(__TSC__) && defined(__OS2__) -# define __LZO_RENAME_A 1 -# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) -# define __LZO_RENAME_A 1 -# elif defined(__PACIFIC__) && defined(DOS) -# if !defined(__far) -# define __far far -# endif -# if !defined(__near) -# define __near near -# endif -# endif -# if defined(__LZO_RENAME_A) -# if !defined(__cdecl) -# define __cdecl cdecl -# endif -# if !defined(__far) -# define __far far -# endif -# if !defined(__huge) -# define __huge huge -# endif -# if !defined(__near) -# define __near near -# endif -# if !defined(__pascal) -# define __pascal pascal -# endif -# if !defined(__huge) -# define __huge huge -# endif -# elif defined(__LZO_RENAME_B) -# if !defined(__cdecl) -# define __cdecl _cdecl -# endif -# if !defined(__far) -# define __far _far -# endif -# if !defined(__huge) -# define __huge _huge -# endif -# if !defined(__near) -# define __near _near -# endif -# if !defined(__pascal) -# define __pascal _pascal -# endif -# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) -# if !defined(__cdecl) -# define __cdecl cdecl -# endif -# if !defined(__pascal) -# define __pascal pascal -# endif -# endif -# undef __LZO_RENAME_A -# undef __LZO_RENAME_B -#endif -#if (UINT_MAX == LZO_0xffffL) -#if defined(__AZTEC_C__) && defined(__DOS__) -# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 -#elif defined(_MSC_VER) && defined(MSDOS) -# if (_MSC_VER < 600) -# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 -# endif -# if (_MSC_VER < 700) -# define LZO_BROKEN_INTEGRAL_PROMOTION 1 -# define LZO_BROKEN_SIZEOF 1 -# endif -#elif defined(__PACIFIC__) && defined(DOS) -# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 -#elif defined(__TURBOC__) && defined(__MSDOS__) -# if (__TURBOC__ < 0x0150) -# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 -# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 -# define LZO_BROKEN_INTEGRAL_PROMOTION 1 -# endif -# if (__TURBOC__ < 0x0200) -# define LZO_BROKEN_SIZEOF 1 -# endif -# if (__TURBOC__ < 0x0400) && defined(__cplusplus) -# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 -# endif -#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) -# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 -# define LZO_BROKEN_SIZEOF 1 -#endif -#endif -#if defined(__WATCOMC__) && (__WATCOMC__ < 900) -# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 -#endif -#if defined(_CRAY) && defined(_CRAY1) -# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 -#endif -#define LZO_PP_STRINGIZE(x) #x -#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) -#define LZO_PP_CONCAT0() /*empty*/ -#define LZO_PP_CONCAT1(a) a -#define LZO_PP_CONCAT2(a,b) a ## b -#define LZO_PP_CONCAT3(a,b,c) a ## b ## c -#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d -#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e -#define LZO_PP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f -#define LZO_PP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g -#define LZO_PP_ECONCAT0() LZO_PP_CONCAT0() -#define LZO_PP_ECONCAT1(a) LZO_PP_CONCAT1(a) -#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) -#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) -#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) -#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) -#define LZO_PP_ECONCAT6(a,b,c,d,e,f) LZO_PP_CONCAT6(a,b,c,d,e,f) -#define LZO_PP_ECONCAT7(a,b,c,d,e,f,g) LZO_PP_CONCAT7(a,b,c,d,e,f,g) -#define LZO_PP_EMPTY /*empty*/ -#define LZO_PP_EMPTY0() /*empty*/ -#define LZO_PP_EMPTY1(a) /*empty*/ -#define LZO_PP_EMPTY2(a,b) /*empty*/ -#define LZO_PP_EMPTY3(a,b,c) /*empty*/ -#define LZO_PP_EMPTY4(a,b,c,d) /*empty*/ -#define LZO_PP_EMPTY5(a,b,c,d,e) /*empty*/ -#define LZO_PP_EMPTY6(a,b,c,d,e,f) /*empty*/ -#define LZO_PP_EMPTY7(a,b,c,d,e,f,g) /*empty*/ -#if 1 -#define LZO_CPP_STRINGIZE(x) #x -#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) -#define LZO_CPP_CONCAT2(a,b) a ## b -#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c -#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d -#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e -#define LZO_CPP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f -#define LZO_CPP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g -#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) -#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) -#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) -#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) -#define LZO_CPP_ECONCAT6(a,b,c,d,e,f) LZO_CPP_CONCAT6(a,b,c,d,e,f) -#define LZO_CPP_ECONCAT7(a,b,c,d,e,f,g) LZO_CPP_CONCAT7(a,b,c,d,e,f,g) -#endif -#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-((b)!=0))) - (o)) << 1) + (o)*((b)!=0)) -#if 1 && defined(__cplusplus) -# if !defined(__STDC_CONSTANT_MACROS) -# define __STDC_CONSTANT_MACROS 1 -# endif -# if !defined(__STDC_LIMIT_MACROS) -# define __STDC_LIMIT_MACROS 1 -# endif -#endif -#if defined(__cplusplus) -# define LZO_EXTERN_C extern "C" -# define LZO_EXTERN_C_BEGIN extern "C" { -# define LZO_EXTERN_C_END } -#else -# define LZO_EXTERN_C extern -# define LZO_EXTERN_C_BEGIN /*empty*/ -# define LZO_EXTERN_C_END /*empty*/ -#endif -#if !defined(__LZO_OS_OVERRIDE) -#if (LZO_OS_FREESTANDING) -# define LZO_INFO_OS "freestanding" -#elif (LZO_OS_EMBEDDED) -# define LZO_INFO_OS "embedded" -#elif 1 && defined(__IAR_SYSTEMS_ICC__) -# define LZO_OS_EMBEDDED 1 -# define LZO_INFO_OS "embedded" -#elif defined(__CYGWIN__) && defined(__GNUC__) -# define LZO_OS_CYGWIN 1 -# define LZO_INFO_OS "cygwin" -#elif defined(__EMX__) && defined(__GNUC__) -# define LZO_OS_EMX 1 -# define LZO_INFO_OS "emx" -#elif defined(__BEOS__) -# define LZO_OS_BEOS 1 -# define LZO_INFO_OS "beos" -#elif defined(__Lynx__) -# define LZO_OS_LYNXOS 1 -# define LZO_INFO_OS "lynxos" -#elif defined(__OS400__) -# define LZO_OS_OS400 1 -# define LZO_INFO_OS "os400" -#elif defined(__QNX__) -# define LZO_OS_QNX 1 -# define LZO_INFO_OS "qnx" -#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) -# define LZO_OS_DOS32 1 -# define LZO_INFO_OS "dos32" -#elif defined(__BORLANDC__) && defined(__DPMI16__) -# define LZO_OS_DOS16 1 -# define LZO_INFO_OS "dos16" -#elif defined(__ZTC__) && defined(DOS386) -# define LZO_OS_DOS32 1 -# define LZO_INFO_OS "dos32" -#elif defined(__OS2__) || defined(__OS2V2__) -# if (UINT_MAX == LZO_0xffffL) -# define LZO_OS_OS216 1 -# define LZO_INFO_OS "os216" -# elif (UINT_MAX == LZO_0xffffffffL) -# define LZO_OS_OS2 1 -# define LZO_INFO_OS "os2" -# else -# error "check your limits.h header" -# endif -#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) -# define LZO_OS_WIN64 1 -# define LZO_INFO_OS "win64" -#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) -# define LZO_OS_WIN32 1 -# define LZO_INFO_OS "win32" -#elif defined(__MWERKS__) && defined(__INTEL__) -# define LZO_OS_WIN32 1 -# define LZO_INFO_OS "win32" -#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) -# if (UINT_MAX == LZO_0xffffL) -# define LZO_OS_WIN16 1 -# define LZO_INFO_OS "win16" -# elif (UINT_MAX == LZO_0xffffffffL) -# define LZO_OS_WIN32 1 -# define LZO_INFO_OS "win32" -# else -# error "check your limits.h header" -# endif -#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) -# if (UINT_MAX == LZO_0xffffL) -# define LZO_OS_DOS16 1 -# define LZO_INFO_OS "dos16" -# elif (UINT_MAX == LZO_0xffffffffL) -# define LZO_OS_DOS32 1 -# define LZO_INFO_OS "dos32" -# else -# error "check your limits.h header" -# endif -#elif defined(__WATCOMC__) -# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) -# define LZO_OS_DOS16 1 -# define LZO_INFO_OS "dos16" -# elif defined(__NT__) && (__WATCOMC__ < 1100) -# define LZO_OS_WIN32 1 -# define LZO_INFO_OS "win32" -# elif defined(__linux__) || defined(__LINUX__) -# define LZO_OS_POSIX 1 -# define LZO_INFO_OS "posix" -# else -# error "please specify a target using the -bt compiler option" -# endif -#elif defined(__palmos__) -# define LZO_OS_PALMOS 1 -# define LZO_INFO_OS "palmos" -#elif defined(__TOS__) || defined(__atarist__) -# define LZO_OS_TOS 1 -# define LZO_INFO_OS "tos" -#elif defined(macintosh) && !defined(__arm__) && !defined(__i386__) && !defined(__ppc__) && !defined(__x64_64__) -# define LZO_OS_MACCLASSIC 1 -# define LZO_INFO_OS "macclassic" -#elif defined(__VMS) -# define LZO_OS_VMS 1 -# define LZO_INFO_OS "vms" -#elif (defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__) -# define LZO_OS_CONSOLE 1 -# define LZO_OS_CONSOLE_PS2 1 -# define LZO_INFO_OS "console" -# define LZO_INFO_OS_CONSOLE "ps2" -#elif defined(__mips__) && defined(__psp__) -# define LZO_OS_CONSOLE 1 -# define LZO_OS_CONSOLE_PSP 1 -# define LZO_INFO_OS "console" -# define LZO_INFO_OS_CONSOLE "psp" -#else -# define LZO_OS_POSIX 1 -# define LZO_INFO_OS "posix" -#endif -#if (LZO_OS_POSIX) -# if defined(_AIX) || defined(__AIX__) || defined(__aix__) -# define LZO_OS_POSIX_AIX 1 -# define LZO_INFO_OS_POSIX "aix" -# elif defined(__FreeBSD__) -# define LZO_OS_POSIX_FREEBSD 1 -# define LZO_INFO_OS_POSIX "freebsd" -# elif defined(__hpux__) || defined(__hpux) -# define LZO_OS_POSIX_HPUX 1 -# define LZO_INFO_OS_POSIX "hpux" -# elif defined(__INTERIX) -# define LZO_OS_POSIX_INTERIX 1 -# define LZO_INFO_OS_POSIX "interix" -# elif defined(__IRIX__) || defined(__irix__) -# define LZO_OS_POSIX_IRIX 1 -# define LZO_INFO_OS_POSIX "irix" -# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) -# define LZO_OS_POSIX_LINUX 1 -# define LZO_INFO_OS_POSIX "linux" -# elif defined(__APPLE__) && defined(__MACH__) -# if ((__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__-0) >= 20000) -# define LZO_OS_POSIX_DARWIN 1040 -# define LZO_INFO_OS_POSIX "darwin_iphone" -# elif ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) >= 1040) -# define LZO_OS_POSIX_DARWIN __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ -# define LZO_INFO_OS_POSIX "darwin" -# else -# define LZO_OS_POSIX_DARWIN 1 -# define LZO_INFO_OS_POSIX "darwin" -# endif -# define LZO_OS_POSIX_MACOSX LZO_OS_POSIX_DARWIN -# elif defined(__minix__) || defined(__minix) -# define LZO_OS_POSIX_MINIX 1 -# define LZO_INFO_OS_POSIX "minix" -# elif defined(__NetBSD__) -# define LZO_OS_POSIX_NETBSD 1 -# define LZO_INFO_OS_POSIX "netbsd" -# elif defined(__OpenBSD__) -# define LZO_OS_POSIX_OPENBSD 1 -# define LZO_INFO_OS_POSIX "openbsd" -# elif defined(__osf__) -# define LZO_OS_POSIX_OSF 1 -# define LZO_INFO_OS_POSIX "osf" -# elif defined(__solaris__) || defined(__sun) -# if defined(__SVR4) || defined(__svr4__) -# define LZO_OS_POSIX_SOLARIS 1 -# define LZO_INFO_OS_POSIX "solaris" -# else -# define LZO_OS_POSIX_SUNOS 1 -# define LZO_INFO_OS_POSIX "sunos" -# endif -# elif defined(__ultrix__) || defined(__ultrix) -# define LZO_OS_POSIX_ULTRIX 1 -# define LZO_INFO_OS_POSIX "ultrix" -# elif defined(_UNICOS) -# define LZO_OS_POSIX_UNICOS 1 -# define LZO_INFO_OS_POSIX "unicos" -# else -# define LZO_OS_POSIX_UNKNOWN 1 -# define LZO_INFO_OS_POSIX "unknown" -# endif -#endif -#endif -#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) -# if (UINT_MAX != LZO_0xffffL) -# error "unexpected configuration - check your compiler defines" -# endif -# if (ULONG_MAX != LZO_0xffffffffL) -# error "unexpected configuration - check your compiler defines" -# endif -#endif -#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) -# if (UINT_MAX != LZO_0xffffffffL) -# error "unexpected configuration - check your compiler defines" -# endif -# if (ULONG_MAX != LZO_0xffffffffL) -# error "unexpected configuration - check your compiler defines" -# endif -#endif -#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) -# define LZO_CC_CILLY 1 -# define LZO_INFO_CC "Cilly" -# if defined(__CILLY__) -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) -# else -# define LZO_INFO_CCVER "unknown" -# endif -#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) -# define LZO_CC_SDCC 1 -# define LZO_INFO_CC "sdcc" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) -#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) -# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + (__PATHCC_MINOR__-0) * 0x100 + (__PATHCC_PATCHLEVEL__-0)) -# define LZO_INFO_CC "Pathscale C" -# define LZO_INFO_CCVER __PATHSCALE__ -# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) -# define LZO_CC_PATHSCALE_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) -# endif -#elif defined(__INTEL_COMPILER) && ((__INTEL_COMPILER-0) > 0) -# define LZO_CC_INTELC __INTEL_COMPILER -# define LZO_INFO_CC "Intel C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) -# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) -# define LZO_CC_INTELC_MSC _MSC_VER -# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) -# define LZO_CC_INTELC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) -# endif -#elif defined(__POCC__) && defined(_WIN32) -# define LZO_CC_PELLESC 1 -# define LZO_INFO_CC "Pelles C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) -#elif defined(__ARMCC_VERSION) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) -# if defined(__GNUC_PATCHLEVEL__) -# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) -# else -# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) -# endif -# define LZO_CC_ARMCC __ARMCC_VERSION -# define LZO_INFO_CC "ARM C Compiler" -# define LZO_INFO_CCVER __VERSION__ -#elif defined(__clang__) && defined(__c2__) && defined(__c2_version__) && defined(_MSC_VER) -# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) -# define LZO_CC_CLANG_C2 _MSC_VER -# define LZO_CC_CLANG_VENDOR_MICROSOFT 1 -# define LZO_INFO_CC "clang/c2" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__c2_version__) -#elif defined(__clang__) && defined(__llvm__) && defined(__VERSION__) -# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) -# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) -# else -# define LZO_CC_CLANG 0x010000L -# endif -# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) -# define LZO_CC_CLANG_MSC _MSC_VER -# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) -# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) -# endif -# if defined(__APPLE_CC__) -# define LZO_CC_CLANG_VENDOR_APPLE 1 -# define LZO_INFO_CC "clang/apple" -# else -# define LZO_CC_CLANG_VENDOR_LLVM 1 -# define LZO_INFO_CC "clang" -# endif -# if defined(__clang_version__) -# define LZO_INFO_CCVER __clang_version__ -# else -# define LZO_INFO_CCVER __VERSION__ -# endif -#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) -# if defined(__GNUC_PATCHLEVEL__) -# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) -# else -# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) -# endif -# define LZO_CC_LLVM LZO_CC_LLVM_GNUC -# define LZO_INFO_CC "llvm-gcc" -# define LZO_INFO_CCVER __VERSION__ -#elif defined(__ACK__) && defined(_ACK) -# define LZO_CC_ACK 1 -# define LZO_INFO_CC "Amsterdam Compiler Kit C" -# define LZO_INFO_CCVER "unknown" -#elif defined(__ARMCC_VERSION) && !defined(__GNUC__) -# define LZO_CC_ARMCC __ARMCC_VERSION -# define LZO_CC_ARMCC_ARMCC __ARMCC_VERSION -# define LZO_INFO_CC "ARM C Compiler" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ARMCC_VERSION) -#elif defined(__AZTEC_C__) -# define LZO_CC_AZTECC 1 -# define LZO_INFO_CC "Aztec C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) -#elif defined(__CODEGEARC__) -# define LZO_CC_CODEGEARC 1 -# define LZO_INFO_CC "CodeGear C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CODEGEARC__) -#elif defined(__BORLANDC__) -# define LZO_CC_BORLANDC 1 -# define LZO_INFO_CC "Borland C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) -#elif defined(_CRAYC) && defined(_RELEASE) -# define LZO_CC_CRAYC 1 -# define LZO_INFO_CC "Cray C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) -#elif defined(__DMC__) && defined(__SC__) -# define LZO_CC_DMC 1 -# define LZO_INFO_CC "Digital Mars C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) -#elif defined(__DECC) -# define LZO_CC_DECC 1 -# define LZO_INFO_CC "DEC C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) -#elif (defined(__ghs) || defined(__ghs__)) && defined(__GHS_VERSION_NUMBER) && ((__GHS_VERSION_NUMBER-0) > 0) -# define LZO_CC_GHS 1 -# define LZO_INFO_CC "Green Hills C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__GHS_VERSION_NUMBER) -# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) -# define LZO_CC_GHS_MSC _MSC_VER -# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) -# define LZO_CC_GHS_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) -# endif -#elif defined(__HIGHC__) -# define LZO_CC_HIGHC 1 -# define LZO_INFO_CC "MetaWare High C" -# define LZO_INFO_CCVER "unknown" -#elif defined(__HP_aCC) && ((__HP_aCC-0) > 0) -# define LZO_CC_HPACC __HP_aCC -# define LZO_INFO_CC "HP aCC" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__HP_aCC) -#elif defined(__IAR_SYSTEMS_ICC__) -# define LZO_CC_IARC 1 -# define LZO_INFO_CC "IAR C" -# if defined(__VER__) -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) -# else -# define LZO_INFO_CCVER "unknown" -# endif -#elif defined(__IBMC__) && ((__IBMC__-0) > 0) -# define LZO_CC_IBMC __IBMC__ -# define LZO_INFO_CC "IBM C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) -#elif defined(__IBMCPP__) && ((__IBMCPP__-0) > 0) -# define LZO_CC_IBMC __IBMCPP__ -# define LZO_INFO_CC "IBM C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMCPP__) -#elif defined(__KEIL__) && defined(__C166__) -# define LZO_CC_KEILC 1 -# define LZO_INFO_CC "Keil C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) -#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) -# define LZO_CC_LCCWIN32 1 -# define LZO_INFO_CC "lcc-win32" -# define LZO_INFO_CCVER "unknown" -#elif defined(__LCC__) -# define LZO_CC_LCC 1 -# define LZO_INFO_CC "lcc" -# if defined(__LCC_VERSION__) -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) -# else -# define LZO_INFO_CCVER "unknown" -# endif -#elif defined(__MWERKS__) && ((__MWERKS__-0) > 0) -# define LZO_CC_MWERKS __MWERKS__ -# define LZO_INFO_CC "Metrowerks C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) -#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) -# define LZO_CC_NDPC 1 -# define LZO_INFO_CC "Microway NDP C" -# define LZO_INFO_CCVER "unknown" -#elif defined(__PACIFIC__) -# define LZO_CC_PACIFICC 1 -# define LZO_INFO_CC "Pacific C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) -#elif defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) -# if defined(__PGIC_PATCHLEVEL__) -# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100 + (__PGIC_PATCHLEVEL__-0)) -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) "." LZO_PP_MACRO_EXPAND(__PGIC_PATCHLEVEL__) -# else -# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100) -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) ".0" -# endif -# define LZO_INFO_CC "Portland Group PGI C" -#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) -# define LZO_CC_PGI 1 -# define LZO_INFO_CC "Portland Group PGI C" -# define LZO_INFO_CCVER "unknown" -#elif defined(__PUREC__) && defined(__TOS__) -# define LZO_CC_PUREC 1 -# define LZO_INFO_CC "Pure C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) -#elif defined(__SC__) && defined(__ZTC__) -# define LZO_CC_SYMANTECC 1 -# define LZO_INFO_CC "Symantec C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) -#elif defined(__SUNPRO_C) -# define LZO_INFO_CC "SunPro C" -# if ((__SUNPRO_C-0) > 0) -# define LZO_CC_SUNPROC __SUNPRO_C -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) -# else -# define LZO_CC_SUNPROC 1 -# define LZO_INFO_CCVER "unknown" -# endif -#elif defined(__SUNPRO_CC) -# define LZO_INFO_CC "SunPro C" -# if ((__SUNPRO_CC-0) > 0) -# define LZO_CC_SUNPROC __SUNPRO_CC -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) -# else -# define LZO_CC_SUNPROC 1 -# define LZO_INFO_CCVER "unknown" -# endif -#elif defined(__TINYC__) -# define LZO_CC_TINYC 1 -# define LZO_INFO_CC "Tiny C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) -#elif defined(__TSC__) -# define LZO_CC_TOPSPEEDC 1 -# define LZO_INFO_CC "TopSpeed C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) -#elif defined(__WATCOMC__) -# define LZO_CC_WATCOMC 1 -# define LZO_INFO_CC "Watcom C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) -#elif defined(__TURBOC__) -# define LZO_CC_TURBOC 1 -# define LZO_INFO_CC "Turbo C" -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) -#elif defined(__ZTC__) -# define LZO_CC_ZORTECHC 1 -# define LZO_INFO_CC "Zortech C" -# if ((__ZTC__-0) == 0x310) -# define LZO_INFO_CCVER "0x310" -# else -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) -# endif -#elif defined(__GNUC__) && defined(__VERSION__) -# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) -# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) -# elif defined(__GNUC_MINOR__) -# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) -# else -# define LZO_CC_GNUC (__GNUC__ * 0x10000L) -# endif -# define LZO_INFO_CC "gcc" -# define LZO_INFO_CCVER __VERSION__ -#elif defined(_MSC_VER) && ((_MSC_VER-0) > 0) -# define LZO_CC_MSC _MSC_VER -# define LZO_INFO_CC "Microsoft C" -# if defined(_MSC_FULL_VER) -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) -# else -# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) -# endif -#else -# define LZO_CC_UNKNOWN 1 -# define LZO_INFO_CC "unknown" -# define LZO_INFO_CCVER "unknown" -#endif -#if (LZO_CC_GNUC) && defined(__OPEN64__) -# if defined(__OPENCC__) && defined(__OPENCC_MINOR__) && defined(__OPENCC_PATCHLEVEL__) -# define LZO_CC_OPEN64 (__OPENCC__ * 0x10000L + (__OPENCC_MINOR__-0) * 0x100 + (__OPENCC_PATCHLEVEL__-0)) -# define LZO_CC_OPEN64_GNUC LZO_CC_GNUC -# endif -#endif -#if (LZO_CC_GNUC) && defined(__PCC__) -# if defined(__PCC__) && defined(__PCC_MINOR__) && defined(__PCC_MINORMINOR__) -# define LZO_CC_PCC (__PCC__ * 0x10000L + (__PCC_MINOR__-0) * 0x100 + (__PCC_MINORMINOR__-0)) -# define LZO_CC_PCC_GNUC LZO_CC_GNUC -# endif -#endif -#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) -# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" -#endif -#if !defined(__LZO_ARCH_OVERRIDE) && !(LZO_ARCH_GENERIC) && defined(_CRAY) -# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) -# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) -# define LZO_ARCH_CRAY_MPP 1 -# elif defined(_CRAY1) -# define LZO_ARCH_CRAY_PVP 1 -# endif -# endif -#endif -#if !defined(__LZO_ARCH_OVERRIDE) -#if (LZO_ARCH_GENERIC) -# define LZO_INFO_ARCH "generic" -#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) -# define LZO_ARCH_I086 1 -# define LZO_INFO_ARCH "i086" -#elif defined(__aarch64__) || defined(_M_ARM64) -# define LZO_ARCH_ARM64 1 -# define LZO_INFO_ARCH "arm64" -#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) -# define LZO_ARCH_ALPHA 1 -# define LZO_INFO_ARCH "alpha" -#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) -# define LZO_ARCH_ALPHA 1 -# define LZO_INFO_ARCH "alpha" -#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) -# define LZO_ARCH_AMD64 1 -# define LZO_INFO_ARCH "amd64" -#elif defined(__arm__) || defined(_M_ARM) -# define LZO_ARCH_ARM 1 -# define LZO_INFO_ARCH "arm" -#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) -# define LZO_ARCH_ARM 1 -# define LZO_INFO_ARCH "arm" -#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) -# define LZO_ARCH_AVR 1 -# define LZO_INFO_ARCH "avr" -#elif defined(__avr32__) || defined(__AVR32__) -# define LZO_ARCH_AVR32 1 -# define LZO_INFO_ARCH "avr32" -#elif defined(__bfin__) -# define LZO_ARCH_BLACKFIN 1 -# define LZO_INFO_ARCH "blackfin" -#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) -# define LZO_ARCH_C166 1 -# define LZO_INFO_ARCH "c166" -#elif defined(__cris__) -# define LZO_ARCH_CRIS 1 -# define LZO_INFO_ARCH "cris" -#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) -# define LZO_ARCH_EZ80 1 -# define LZO_INFO_ARCH "ez80" -#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) -# define LZO_ARCH_H8300 1 -# define LZO_INFO_ARCH "h8300" -#elif defined(__hppa__) || defined(__hppa) -# define LZO_ARCH_HPPA 1 -# define LZO_INFO_ARCH "hppa" -#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) -# define LZO_ARCH_I386 1 -# define LZO_ARCH_IA32 1 -# define LZO_INFO_ARCH "i386" -#elif (LZO_CC_ZORTECHC && defined(__I86__)) -# define LZO_ARCH_I386 1 -# define LZO_ARCH_IA32 1 -# define LZO_INFO_ARCH "i386" -#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) -# define LZO_ARCH_I386 1 -# define LZO_ARCH_IA32 1 -# define LZO_INFO_ARCH "i386" -#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) -# define LZO_ARCH_IA64 1 -# define LZO_INFO_ARCH "ia64" -#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) -# define LZO_ARCH_M16C 1 -# define LZO_INFO_ARCH "m16c" -#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) -# define LZO_ARCH_M16C 1 -# define LZO_INFO_ARCH "m16c" -#elif defined(__m32r__) -# define LZO_ARCH_M32R 1 -# define LZO_INFO_ARCH "m32r" -#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) -# define LZO_ARCH_M68K 1 -# define LZO_INFO_ARCH "m68k" -#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) -# define LZO_ARCH_MCS251 1 -# define LZO_INFO_ARCH "mcs251" -#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) -# define LZO_ARCH_MCS51 1 -# define LZO_INFO_ARCH "mcs51" -#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) -# define LZO_ARCH_MCS51 1 -# define LZO_INFO_ARCH "mcs51" -#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) -# define LZO_ARCH_MIPS 1 -# define LZO_INFO_ARCH "mips" -#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) -# define LZO_ARCH_MSP430 1 -# define LZO_INFO_ARCH "msp430" -#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) -# define LZO_ARCH_MSP430 1 -# define LZO_INFO_ARCH "msp430" -#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) -# define LZO_ARCH_POWERPC 1 -# define LZO_INFO_ARCH "powerpc" -#elif defined(__powerpc64__) || defined(__powerpc64) || defined(__ppc64__) || defined(__PPC64__) -# define LZO_ARCH_POWERPC 1 -# define LZO_INFO_ARCH "powerpc" -#elif defined(__powerpc64le__) || defined(__powerpc64le) || defined(__ppc64le__) || defined(__PPC64LE__) -# define LZO_ARCH_POWERPC 1 -# define LZO_INFO_ARCH "powerpc" -#elif defined(__riscv) -# define LZO_ARCH_RISCV 1 -# define LZO_INFO_ARCH "riscv" -#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) -# define LZO_ARCH_S390 1 -# define LZO_INFO_ARCH "s390" -#elif defined(__sh__) || defined(_M_SH) -# define LZO_ARCH_SH 1 -# define LZO_INFO_ARCH "sh" -#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) -# define LZO_ARCH_SPARC 1 -# define LZO_INFO_ARCH "sparc" -#elif defined(__SPU__) -# define LZO_ARCH_SPU 1 -# define LZO_INFO_ARCH "spu" -#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) -# define LZO_ARCH_Z80 1 -# define LZO_INFO_ARCH "z80" -#elif (LZO_ARCH_CRAY_PVP) -# if defined(_CRAYSV1) -# define LZO_ARCH_CRAY_SV1 1 -# define LZO_INFO_ARCH "cray_sv1" -# elif (_ADDR64) -# define LZO_ARCH_CRAY_T90 1 -# define LZO_INFO_ARCH "cray_t90" -# elif (_ADDR32) -# define LZO_ARCH_CRAY_YMP 1 -# define LZO_INFO_ARCH "cray_ymp" -# else -# define LZO_ARCH_CRAY_XMP 1 -# define LZO_INFO_ARCH "cray_xmp" -# endif -#else -# define LZO_ARCH_UNKNOWN 1 -# define LZO_INFO_ARCH "unknown" -#endif -#endif -#if !defined(LZO_ARCH_ARM_THUMB2) -#if (LZO_ARCH_ARM) -# if defined(__thumb__) || defined(__thumb) || defined(_M_THUMB) -# if defined(__thumb2__) -# define LZO_ARCH_ARM_THUMB2 1 -# elif 1 && defined(__TARGET_ARCH_THUMB) && ((__TARGET_ARCH_THUMB)+0 >= 4) -# define LZO_ARCH_ARM_THUMB2 1 -# elif 1 && defined(_MSC_VER) && defined(_M_THUMB) && ((_M_THUMB)+0 >= 7) -# define LZO_ARCH_ARM_THUMB2 1 -# endif -# endif -#endif -#endif -#if (LZO_ARCH_ARM_THUMB2) -# undef LZO_INFO_ARCH -# define LZO_INFO_ARCH "arm_thumb2" -#endif -#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) -# error "FIXME - missing define for CPU architecture" -#endif -#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) -# error "FIXME - missing LZO_OS_WIN32 define for CPU architecture" -#endif -#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) -# error "FIXME - missing LZO_OS_WIN64 define for CPU architecture" -#endif -#if (LZO_OS_OS216 || LZO_OS_WIN16) -# define LZO_ARCH_I086PM 1 -#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) -# define LZO_ARCH_I086PM 1 -#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) -# define LZO_ARCH_I086PM 1 -#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) -# define LZO_ARCH_I086PM 1 -#endif -#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) -# define LZO_ARCH_X64 1 -#elif (!LZO_ARCH_AMD64 && LZO_ARCH_X64) && defined(__LZO_ARCH_OVERRIDE) -# define LZO_ARCH_AMD64 1 -#endif -#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) -# define LZO_ARCH_AARCH64 1 -#elif (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) && defined(__LZO_ARCH_OVERRIDE) -# define LZO_ARCH_ARM64 1 -#endif -#if (LZO_ARCH_I386 && !LZO_ARCH_X86) -# define LZO_ARCH_X86 1 -#elif (!LZO_ARCH_I386 && LZO_ARCH_X86) && defined(__LZO_ARCH_OVERRIDE) -# define LZO_ARCH_I386 1 -#endif -#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) || (!LZO_ARCH_AMD64 && LZO_ARCH_X64) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) || (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_I386 && !LZO_ARCH_X86) || (!LZO_ARCH_I386 && LZO_ARCH_X86) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_ARM_THUMB1 && !LZO_ARCH_ARM) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_ARM_THUMB2 && !LZO_ARCH_ARM) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_ARM_THUMB1 && LZO_ARCH_ARM_THUMB2) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_I086PM && !LZO_ARCH_I086) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_I086) -# if (UINT_MAX != LZO_0xffffL) -# error "unexpected configuration - check your compiler defines" -# endif -# if (ULONG_MAX != LZO_0xffffffffL) -# error "unexpected configuration - check your compiler defines" -# endif -#endif -#if (LZO_ARCH_I386) -# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) -# error "unexpected configuration - check your compiler defines" -# endif -# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) -# error "unexpected configuration - check your compiler defines" -# endif -# if (ULONG_MAX != LZO_0xffffffffL) -# error "unexpected configuration - check your compiler defines" -# endif -#endif -#if (LZO_ARCH_AMD64 || LZO_ARCH_I386) -# if !defined(LZO_TARGET_FEATURE_SSE2) -# if defined(__SSE2__) -# define LZO_TARGET_FEATURE_SSE2 1 -# elif defined(_MSC_VER) && (defined(_M_IX86_FP) && ((_M_IX86_FP)+0 >= 2)) -# define LZO_TARGET_FEATURE_SSE2 1 -# elif (LZO_CC_INTELC_MSC || LZO_CC_MSC) && defined(_M_AMD64) -# define LZO_TARGET_FEATURE_SSE2 1 -# endif -# endif -# if !defined(LZO_TARGET_FEATURE_SSSE3) -# if (LZO_TARGET_FEATURE_SSE2) -# if defined(__SSSE3__) -# define LZO_TARGET_FEATURE_SSSE3 1 -# elif defined(_MSC_VER) && defined(__AVX__) -# define LZO_TARGET_FEATURE_SSSE3 1 -# endif -# endif -# endif -# if !defined(LZO_TARGET_FEATURE_SSE4_2) -# if (LZO_TARGET_FEATURE_SSSE3) -# if defined(__SSE4_2__) -# define LZO_TARGET_FEATURE_SSE4_2 1 -# endif -# endif -# endif -# if !defined(LZO_TARGET_FEATURE_AVX) -# if (LZO_TARGET_FEATURE_SSSE3) -# if defined(__AVX__) -# define LZO_TARGET_FEATURE_AVX 1 -# endif -# endif -# endif -# if !defined(LZO_TARGET_FEATURE_AVX2) -# if (LZO_TARGET_FEATURE_AVX) -# if defined(__AVX2__) -# define LZO_TARGET_FEATURE_AVX2 1 -# endif -# endif -# endif -#endif -#if (LZO_TARGET_FEATURE_SSSE3 && !(LZO_TARGET_FEATURE_SSE2)) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_TARGET_FEATURE_SSE4_2 && !(LZO_TARGET_FEATURE_SSSE3)) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_TARGET_FEATURE_AVX && !(LZO_TARGET_FEATURE_SSSE3)) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_TARGET_FEATURE_AVX2 && !(LZO_TARGET_FEATURE_AVX)) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ARCH_ARM) -# if !defined(LZO_TARGET_FEATURE_NEON) -# if defined(__ARM_NEON) && ((__ARM_NEON)+0) -# define LZO_TARGET_FEATURE_NEON 1 -# elif 1 && defined(__ARM_NEON__) && ((__ARM_NEON__)+0) -# define LZO_TARGET_FEATURE_NEON 1 -# elif 1 && defined(__TARGET_FEATURE_NEON) && ((__TARGET_FEATURE_NEON)+0) -# define LZO_TARGET_FEATURE_NEON 1 -# endif -# endif -#elif (LZO_ARCH_ARM64) -# if !defined(LZO_TARGET_FEATURE_NEON) -# if 1 -# define LZO_TARGET_FEATURE_NEON 1 -# endif -# endif -#endif -#if 0 -#elif !defined(__LZO_MM_OVERRIDE) -#if (LZO_ARCH_I086) -#if (UINT_MAX != LZO_0xffffL) -# error "unexpected configuration - check your compiler defines" -#endif -#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) -# define LZO_MM_TINY 1 -#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) -# define LZO_MM_HUGE 1 -#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) -# define LZO_MM_SMALL 1 -#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) -# define LZO_MM_MEDIUM 1 -#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) -# define LZO_MM_COMPACT 1 -#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) -# define LZO_MM_LARGE 1 -#elif (LZO_CC_AZTECC) -# if defined(_LARGE_CODE) && defined(_LARGE_DATA) -# define LZO_MM_LARGE 1 -# elif defined(_LARGE_CODE) -# define LZO_MM_MEDIUM 1 -# elif defined(_LARGE_DATA) -# define LZO_MM_COMPACT 1 -# else -# define LZO_MM_SMALL 1 -# endif -#elif (LZO_CC_ZORTECHC && defined(__VCM__)) -# define LZO_MM_LARGE 1 -#else -# error "unknown LZO_ARCH_I086 memory model" -#endif -#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) -#define LZO_HAVE_MM_HUGE_PTR 1 -#define LZO_HAVE_MM_HUGE_ARRAY 1 -#if (LZO_MM_TINY) -# undef LZO_HAVE_MM_HUGE_ARRAY -#endif -#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) -# undef LZO_HAVE_MM_HUGE_PTR -# undef LZO_HAVE_MM_HUGE_ARRAY -#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) -# undef LZO_HAVE_MM_HUGE_ARRAY -#elif (LZO_CC_MSC && defined(_QC)) -# undef LZO_HAVE_MM_HUGE_ARRAY -# if (_MSC_VER < 600) -# undef LZO_HAVE_MM_HUGE_PTR -# endif -#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) -# undef LZO_HAVE_MM_HUGE_ARRAY -#endif -#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR) -# if (LZO_OS_DOS16) -# error "unexpected configuration - check your compiler defines" -# elif (LZO_CC_ZORTECHC) -# else -# error "unexpected configuration - check your compiler defines" -# endif -#endif -#if defined(__cplusplus) -extern "C" { -#endif -#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) - extern void __near __cdecl _AHSHIFT(void); -# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) -#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) - extern void __near __cdecl _AHSHIFT(void); -# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) -#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) - extern void __near __cdecl _AHSHIFT(void); -# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) -#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) - extern void __near __cdecl _AHSHIFT(void); -# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) -#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) -# define LZO_MM_AHSHIFT 12 -#elif (LZO_CC_WATCOMC) - extern unsigned char _HShift; -# define LZO_MM_AHSHIFT ((unsigned) _HShift) -#else -# error "FIXME - implement LZO_MM_AHSHIFT" -#endif -#if defined(__cplusplus) -} -#endif -#endif -#elif (LZO_ARCH_C166) -#if !defined(__MODEL__) -# error "FIXME - LZO_ARCH_C166 __MODEL__" -#elif ((__MODEL__) == 0) -# define LZO_MM_SMALL 1 -#elif ((__MODEL__) == 1) -# define LZO_MM_SMALL 1 -#elif ((__MODEL__) == 2) -# define LZO_MM_LARGE 1 -#elif ((__MODEL__) == 3) -# define LZO_MM_TINY 1 -#elif ((__MODEL__) == 4) -# define LZO_MM_XTINY 1 -#elif ((__MODEL__) == 5) -# define LZO_MM_XSMALL 1 -#else -# error "FIXME - LZO_ARCH_C166 __MODEL__" -#endif -#elif (LZO_ARCH_MCS251) -#if !defined(__MODEL__) -# error "FIXME - LZO_ARCH_MCS251 __MODEL__" -#elif ((__MODEL__) == 0) -# define LZO_MM_SMALL 1 -#elif ((__MODEL__) == 2) -# define LZO_MM_LARGE 1 -#elif ((__MODEL__) == 3) -# define LZO_MM_TINY 1 -#elif ((__MODEL__) == 4) -# define LZO_MM_XTINY 1 -#elif ((__MODEL__) == 5) -# define LZO_MM_XSMALL 1 -#else -# error "FIXME - LZO_ARCH_MCS251 __MODEL__" -#endif -#elif (LZO_ARCH_MCS51) -#if !defined(__MODEL__) -# error "FIXME - LZO_ARCH_MCS51 __MODEL__" -#elif ((__MODEL__) == 1) -# define LZO_MM_SMALL 1 -#elif ((__MODEL__) == 2) -# define LZO_MM_LARGE 1 -#elif ((__MODEL__) == 3) -# define LZO_MM_TINY 1 -#elif ((__MODEL__) == 4) -# define LZO_MM_XTINY 1 -#elif ((__MODEL__) == 5) -# define LZO_MM_XSMALL 1 -#else -# error "FIXME - LZO_ARCH_MCS51 __MODEL__" -#endif -#elif (LZO_ARCH_CRAY_PVP) -# define LZO_MM_PVP 1 -#else -# define LZO_MM_FLAT 1 -#endif -#if (LZO_MM_COMPACT) -# define LZO_INFO_MM "compact" -#elif (LZO_MM_FLAT) -# define LZO_INFO_MM "flat" -#elif (LZO_MM_HUGE) -# define LZO_INFO_MM "huge" -#elif (LZO_MM_LARGE) -# define LZO_INFO_MM "large" -#elif (LZO_MM_MEDIUM) -# define LZO_INFO_MM "medium" -#elif (LZO_MM_PVP) -# define LZO_INFO_MM "pvp" -#elif (LZO_MM_SMALL) -# define LZO_INFO_MM "small" -#elif (LZO_MM_TINY) -# define LZO_INFO_MM "tiny" -#else -# error "unknown memory model" -#endif -#endif -#if !defined(__lzo_gnuc_extension__) -#if (LZO_CC_GNUC >= 0x020800ul) -# define __lzo_gnuc_extension__ __extension__ -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_gnuc_extension__ __extension__ -#elif (LZO_CC_IBMC >= 600) -# define __lzo_gnuc_extension__ __extension__ -#endif -#endif -#if !defined(__lzo_gnuc_extension__) -# define __lzo_gnuc_extension__ /*empty*/ -#endif -#if !defined(lzo_has_builtin) -#if (LZO_CC_CLANG) && defined(__has_builtin) -# define lzo_has_builtin __has_builtin -#endif -#endif -#if !defined(lzo_has_builtin) -# define lzo_has_builtin(x) 0 -#endif -#if !defined(lzo_has_attribute) -#if (LZO_CC_CLANG) && defined(__has_attribute) -# define lzo_has_attribute __has_attribute -#endif -#endif -#if !defined(lzo_has_attribute) -# define lzo_has_attribute(x) 0 -#endif -#if !defined(lzo_has_declspec_attribute) -#if (LZO_CC_CLANG) && defined(__has_declspec_attribute) -# define lzo_has_declspec_attribute __has_declspec_attribute -#endif -#endif -#if !defined(lzo_has_declspec_attribute) -# define lzo_has_declspec_attribute(x) 0 -#endif -#if !defined(lzo_has_feature) -#if (LZO_CC_CLANG) && defined(__has_feature) -# define lzo_has_feature __has_feature -#endif -#endif -#if !defined(lzo_has_feature) -# define lzo_has_feature(x) 0 -#endif -#if !defined(lzo_has_extension) -#if (LZO_CC_CLANG) && defined(__has_extension) -# define lzo_has_extension __has_extension -#elif (LZO_CC_CLANG) && defined(__has_feature) -# define lzo_has_extension __has_feature -#endif -#endif -#if !defined(lzo_has_extension) -# define lzo_has_extension(x) 0 -#endif -#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) && defined(__cplusplus) && 0 -# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) -# define LZO_CFG_USE_NEW_STYLE_CASTS 0 -# elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1200)) -# define LZO_CFG_USE_NEW_STYLE_CASTS 0 -# else -# define LZO_CFG_USE_NEW_STYLE_CASTS 1 -# endif -#endif -#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) -# define LZO_CFG_USE_NEW_STYLE_CASTS 0 -#endif -#if !defined(__cplusplus) -# if defined(LZO_CFG_USE_NEW_STYLE_CASTS) -# undef LZO_CFG_USE_NEW_STYLE_CASTS -# endif -# define LZO_CFG_USE_NEW_STYLE_CASTS 0 -#endif -#if !defined(LZO_REINTERPRET_CAST) -# if (LZO_CFG_USE_NEW_STYLE_CASTS) -# define LZO_REINTERPRET_CAST(t,e) (reinterpret_cast (e)) -# endif -#endif -#if !defined(LZO_REINTERPRET_CAST) -# define LZO_REINTERPRET_CAST(t,e) ((t) (e)) -#endif -#if !defined(LZO_STATIC_CAST) -# if (LZO_CFG_USE_NEW_STYLE_CASTS) -# define LZO_STATIC_CAST(t,e) (static_cast (e)) -# endif -#endif -#if !defined(LZO_STATIC_CAST) -# define LZO_STATIC_CAST(t,e) ((t) (e)) -#endif -#if !defined(LZO_STATIC_CAST2) -# define LZO_STATIC_CAST2(t1,t2,e) LZO_STATIC_CAST(t1, LZO_STATIC_CAST(t2, e)) -#endif -#if !defined(LZO_UNCONST_CAST) -# if (LZO_CFG_USE_NEW_STYLE_CASTS) -# define LZO_UNCONST_CAST(t,e) (const_cast (e)) -# elif (LZO_HAVE_MM_HUGE_PTR) -# define LZO_UNCONST_CAST(t,e) ((t) (e)) -# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((const void *) (e))))) -# endif -#endif -#if !defined(LZO_UNCONST_CAST) -# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((const void *) (e)))) -#endif -#if !defined(LZO_UNCONST_VOLATILE_CAST) -# if (LZO_CFG_USE_NEW_STYLE_CASTS) -# define LZO_UNCONST_VOLATILE_CAST(t,e) (const_cast (e)) -# elif (LZO_HAVE_MM_HUGE_PTR) -# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) (e)) -# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) -# endif -#endif -#if !defined(LZO_UNCONST_VOLATILE_CAST) -# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((volatile const void *) (e)))) -#endif -#if !defined(LZO_UNVOLATILE_CAST) -# if (LZO_CFG_USE_NEW_STYLE_CASTS) -# define LZO_UNVOLATILE_CAST(t,e) (const_cast (e)) -# elif (LZO_HAVE_MM_HUGE_PTR) -# define LZO_UNVOLATILE_CAST(t,e) ((t) (e)) -# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((volatile void *) (e))))) -# endif -#endif -#if !defined(LZO_UNVOLATILE_CAST) -# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((volatile void *) (e)))) -#endif -#if !defined(LZO_UNVOLATILE_CONST_CAST) -# if (LZO_CFG_USE_NEW_STYLE_CASTS) -# define LZO_UNVOLATILE_CONST_CAST(t,e) (const_cast (e)) -# elif (LZO_HAVE_MM_HUGE_PTR) -# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) (e)) -# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) -# endif -#endif -#if !defined(LZO_UNVOLATILE_CONST_CAST) -# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((volatile const void *) (e)))) -#endif -#if !defined(LZO_PCAST) -# if (LZO_HAVE_MM_HUGE_PTR) -# define LZO_PCAST(t,e) ((t) (e)) -# endif -#endif -#if !defined(LZO_PCAST) -# define LZO_PCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(void *, e)) -#endif -#if !defined(LZO_CCAST) -# if (LZO_HAVE_MM_HUGE_PTR) -# define LZO_CCAST(t,e) ((t) (e)) -# endif -#endif -#if !defined(LZO_CCAST) -# define LZO_CCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(const void *, e)) -#endif -#if !defined(LZO_ICONV) -# define LZO_ICONV(t,e) LZO_STATIC_CAST(t, e) -#endif -#if !defined(LZO_ICAST) -# define LZO_ICAST(t,e) LZO_STATIC_CAST(t, e) -#endif -#if !defined(LZO_ITRUNC) -# define LZO_ITRUNC(t,e) LZO_STATIC_CAST(t, e) -#endif -#if !defined(__lzo_cte) -# if (LZO_CC_MSC || LZO_CC_WATCOMC) -# define __lzo_cte(e) ((void)0,(e)) -# elif 1 -# define __lzo_cte(e) ((void)0,(e)) -# endif -#endif -#if !defined(__lzo_cte) -# define __lzo_cte(e) (e) -#endif -#if !defined(LZO_BLOCK_BEGIN) -# define LZO_BLOCK_BEGIN do { -# define LZO_BLOCK_END } while __lzo_cte(0) -#endif -#if !defined(LZO_UNUSED) -# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) -# define LZO_UNUSED(var) ((void) &var) -# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) -# define LZO_UNUSED(var) if (&var) ; else -# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030200ul)) -# define LZO_UNUSED(var) ((void) &var) -# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define LZO_UNUSED(var) ((void) var) -# elif (LZO_CC_MSC && (_MSC_VER < 900)) -# define LZO_UNUSED(var) if (&var) ; else -# elif (LZO_CC_KEILC) -# define LZO_UNUSED(var) {extern int lzo_unused__[1-2*!(sizeof(var)>0)]; (void)lzo_unused__;} -# elif (LZO_CC_PACIFICC) -# define LZO_UNUSED(var) ((void) sizeof(var)) -# elif (LZO_CC_WATCOMC) && defined(__cplusplus) -# define LZO_UNUSED(var) ((void) var) -# else -# define LZO_UNUSED(var) ((void) &var) -# endif -#endif -#if !defined(LZO_UNUSED_RESULT) -# define LZO_UNUSED_RESULT(var) LZO_UNUSED(var) -#endif -#if !defined(LZO_UNUSED_FUNC) -# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) -# define LZO_UNUSED_FUNC(func) ((void) func) -# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) -# define LZO_UNUSED_FUNC(func) if (func) ; else -# elif (LZO_CC_CLANG || LZO_CC_LLVM) -# define LZO_UNUSED_FUNC(func) ((void) &func) -# elif (LZO_CC_MSC && (_MSC_VER < 900)) -# define LZO_UNUSED_FUNC(func) if (func) ; else -# elif (LZO_CC_MSC) -# define LZO_UNUSED_FUNC(func) ((void) &func) -# elif (LZO_CC_KEILC || LZO_CC_PELLESC) -# define LZO_UNUSED_FUNC(func) {extern int lzo_unused__[1-2*!(sizeof((int)func)>0)]; (void)lzo_unused__;} -# else -# define LZO_UNUSED_FUNC(func) ((void) func) -# endif -#endif -#if !defined(LZO_UNUSED_LABEL) -# if (LZO_CC_CLANG >= 0x020800ul) -# define LZO_UNUSED_LABEL(l) (__lzo_gnuc_extension__ ((void) ((const void *) &&l))) -# elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC) -# define LZO_UNUSED_LABEL(l) if __lzo_cte(0) goto l -# else -# define LZO_UNUSED_LABEL(l) switch (0) case 1:goto l -# endif -#endif -#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) -# if 0 -# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var -# elif 0 && (LZO_CC_GNUC) -# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var -# else -# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init -# endif -#endif -#if !defined(__lzo_inline) -#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) -#elif defined(__cplusplus) -# define __lzo_inline inline -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) -# define __lzo_inline inline -#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) -# define __lzo_inline __inline -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) -# define __lzo_inline __inline__ -#elif (LZO_CC_DMC) -# define __lzo_inline __inline -#elif (LZO_CC_GHS) -# define __lzo_inline __inline__ -#elif (LZO_CC_IBMC >= 600) -# define __lzo_inline __inline__ -#elif (LZO_CC_INTELC) -# define __lzo_inline __inline -#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) -# define __lzo_inline __inline -#elif (LZO_CC_MSC && (_MSC_VER >= 900)) -# define __lzo_inline __inline -#elif (LZO_CC_SUNPROC >= 0x5100) -# define __lzo_inline __inline__ -#endif -#endif -#if defined(__lzo_inline) -# ifndef __lzo_HAVE_inline -# define __lzo_HAVE_inline 1 -# endif -#else -# define __lzo_inline /*empty*/ -#endif -#if !defined(__lzo_forceinline) -#if (LZO_CC_GNUC >= 0x030200ul) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#elif (LZO_CC_IBMC >= 700) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) -# define __lzo_forceinline __forceinline -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) -# define __lzo_forceinline __forceinline -#elif (LZO_CC_PGI >= 0x0d0a00ul) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#elif (LZO_CC_SUNPROC >= 0x5100) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#endif -#endif -#if defined(__lzo_forceinline) -# ifndef __lzo_HAVE_forceinline -# define __lzo_HAVE_forceinline 1 -# endif -#else -# define __lzo_forceinline __lzo_inline -#endif -#if !defined(__lzo_noinline) -#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) -# define __lzo_noinline __attribute__((__noinline__,__used__)) -#elif (LZO_CC_GNUC >= 0x030200ul) -# define __lzo_noinline __attribute__((__noinline__)) -#elif (LZO_CC_IBMC >= 700) -# define __lzo_noinline __attribute__((__noinline__)) -#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) -# define __lzo_noinline __declspec(noinline) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) -# define __lzo_noinline __attribute__((__noinline__)) -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_noinline __attribute__((__noinline__)) -#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) -# define __lzo_noinline __declspec(noinline) -#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) -# if defined(__cplusplus) -# else -# define __lzo_noinline __declspec(noinline) -# endif -#elif (LZO_CC_PGI >= 0x0d0a00ul) -# define __lzo_noinline __attribute__((__noinline__)) -#elif (LZO_CC_SUNPROC >= 0x5100) -# define __lzo_noinline __attribute__((__noinline__)) -#endif -#endif -#if defined(__lzo_noinline) -# ifndef __lzo_HAVE_noinline -# define __lzo_HAVE_noinline 1 -# endif -#else -# define __lzo_noinline /*empty*/ -#endif -#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline) -# error "unexpected configuration - check your compiler defines" -#endif -#if !defined(__lzo_static_inline) -#if (LZO_CC_IBMC) -# define __lzo_static_inline __lzo_gnuc_extension__ static __lzo_inline -#endif -#endif -#if !defined(__lzo_static_inline) -# define __lzo_static_inline static __lzo_inline -#endif -#if !defined(__lzo_static_forceinline) -#if (LZO_CC_IBMC) -# define __lzo_static_forceinline __lzo_gnuc_extension__ static __lzo_forceinline -#endif -#endif -#if !defined(__lzo_static_forceinline) -# define __lzo_static_forceinline static __lzo_forceinline -#endif -#if !defined(__lzo_static_noinline) -#if (LZO_CC_IBMC) -# define __lzo_static_noinline __lzo_gnuc_extension__ static __lzo_noinline -#endif -#endif -#if !defined(__lzo_static_noinline) -# define __lzo_static_noinline static __lzo_noinline -#endif -#if !defined(__lzo_c99_extern_inline) -#if defined(__GNUC_GNU_INLINE__) -# define __lzo_c99_extern_inline __lzo_inline -#elif defined(__GNUC_STDC_INLINE__) -# define __lzo_c99_extern_inline extern __lzo_inline -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) -# define __lzo_c99_extern_inline extern __lzo_inline -#endif -#if !defined(__lzo_c99_extern_inline) && (__lzo_HAVE_inline) -# define __lzo_c99_extern_inline __lzo_inline -#endif -#endif -#if defined(__lzo_c99_extern_inline) -# ifndef __lzo_HAVE_c99_extern_inline -# define __lzo_HAVE_c99_extern_inline 1 -# endif -#else -# define __lzo_c99_extern_inline /*empty*/ -#endif -#if !defined(__lzo_may_alias) -#if (LZO_CC_GNUC >= 0x030400ul) -# define __lzo_may_alias __attribute__((__may_alias__)) -#elif (LZO_CC_CLANG >= 0x020900ul) -# define __lzo_may_alias __attribute__((__may_alias__)) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1210)) && 0 -# define __lzo_may_alias __attribute__((__may_alias__)) -#elif (LZO_CC_PGI >= 0x0d0a00ul) && 0 -# define __lzo_may_alias __attribute__((__may_alias__)) -#endif -#endif -#if defined(__lzo_may_alias) -# ifndef __lzo_HAVE_may_alias -# define __lzo_HAVE_may_alias 1 -# endif -#else -# define __lzo_may_alias /*empty*/ -#endif -#if !defined(__lzo_noreturn) -#if (LZO_CC_GNUC >= 0x020700ul) -# define __lzo_noreturn __attribute__((__noreturn__)) -#elif (LZO_CC_IBMC >= 700) -# define __lzo_noreturn __attribute__((__noreturn__)) -#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) -# define __lzo_noreturn __declspec(noreturn) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) -# define __lzo_noreturn __attribute__((__noreturn__)) -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_noreturn __attribute__((__noreturn__)) -#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) -# define __lzo_noreturn __declspec(noreturn) -#elif (LZO_CC_PGI >= 0x0d0a00ul) -# define __lzo_noreturn __attribute__((__noreturn__)) -#endif -#endif -#if defined(__lzo_noreturn) -# ifndef __lzo_HAVE_noreturn -# define __lzo_HAVE_noreturn 1 -# endif -#else -# define __lzo_noreturn /*empty*/ -#endif -#if !defined(__lzo_nothrow) -#if (LZO_CC_GNUC >= 0x030300ul) -# define __lzo_nothrow __attribute__((__nothrow__)) -#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) && defined(__cplusplus) -# define __lzo_nothrow __declspec(nothrow) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 900)) -# define __lzo_nothrow __attribute__((__nothrow__)) -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_nothrow __attribute__((__nothrow__)) -#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) -# define __lzo_nothrow __declspec(nothrow) -#endif -#endif -#if defined(__lzo_nothrow) -# ifndef __lzo_HAVE_nothrow -# define __lzo_HAVE_nothrow 1 -# endif -#else -# define __lzo_nothrow /*empty*/ -#endif -#if !defined(__lzo_restrict) -#if (LZO_CC_GNUC >= 0x030400ul) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_IBMC >= 800) && !defined(__cplusplus) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_IBMC >= 1210) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) -# define __lzo_restrict __restrict -#elif (LZO_CC_PGI >= 0x0d0a00ul) -# define __lzo_restrict __restrict__ -#endif -#endif -#if defined(__lzo_restrict) -# ifndef __lzo_HAVE_restrict -# define __lzo_HAVE_restrict 1 -# endif -#else -# define __lzo_restrict /*empty*/ -#endif -#if !defined(__lzo_alignof) -#if (LZO_CC_ARMCC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) -# define __lzo_alignof(e) __alignof__(e) -#elif (LZO_CC_GHS) && !defined(__cplusplus) -# define __lzo_alignof(e) __alignof__(e) -#elif (LZO_CC_IBMC >= 600) -# define __lzo_alignof(e) (__lzo_gnuc_extension__ __alignof__(e)) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) -# define __lzo_alignof(e) __alignof__(e) -#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) -# define __lzo_alignof(e) __alignof(e) -#elif (LZO_CC_SUNPROC >= 0x5100) -# define __lzo_alignof(e) __alignof__(e) -#endif -#endif -#if defined(__lzo_alignof) -# ifndef __lzo_HAVE_alignof -# define __lzo_HAVE_alignof 1 -# endif -#endif -#if !defined(__lzo_struct_packed) -#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) -#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) -#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) -#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) -#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) -#elif (LZO_CC_GNUC >= 0x030400ul) && !(LZO_CC_PCC_GNUC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) -# define __lzo_struct_packed(s) struct s { -# define __lzo_struct_packed_end() } __attribute__((__gcc_struct__,__packed__)); -# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__gcc_struct__,__packed__)); -#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) -# define __lzo_struct_packed(s) struct s { -# define __lzo_struct_packed_end() } __attribute__((__packed__)); -# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); -#elif (LZO_CC_IBMC >= 700) -# define __lzo_struct_packed(s) __lzo_gnuc_extension__ struct s { -# define __lzo_struct_packed_end() } __attribute__((__packed__)); -# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); -#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) -# define __lzo_struct_packed(s) __pragma(pack(push,1)) struct s { -# define __lzo_struct_packed_end() } __pragma(pack(pop)); -#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) -# define __lzo_struct_packed(s) _Packed struct s { -# define __lzo_struct_packed_end() }; -#endif -#endif -#if defined(__lzo_struct_packed) && !defined(__lzo_struct_packed_ma) -# define __lzo_struct_packed_ma(s) __lzo_struct_packed(s) -#endif -#if defined(__lzo_struct_packed_end) && !defined(__lzo_struct_packed_ma_end) -# define __lzo_struct_packed_ma_end() __lzo_struct_packed_end() -#endif -#if !defined(__lzo_byte_struct) -#if defined(__lzo_struct_packed) -# define __lzo_byte_struct(s,n) __lzo_struct_packed(s) unsigned char a[n]; __lzo_struct_packed_end() -# define __lzo_byte_struct_ma(s,n) __lzo_struct_packed_ma(s) unsigned char a[n]; __lzo_struct_packed_ma_end() -#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_PGI || (LZO_CC_SUNPROC >= 0x5100)) -# define __lzo_byte_struct(s,n) struct s { unsigned char a[n]; } __attribute__((__packed__)); -# define __lzo_byte_struct_ma(s,n) struct s { unsigned char a[n]; } __lzo_may_alias __attribute__((__packed__)); -#endif -#endif -#if defined(__lzo_byte_struct) && !defined(__lzo_byte_struct_ma) -# define __lzo_byte_struct_ma(s,n) __lzo_byte_struct(s,n) -#endif -#if !defined(__lzo_struct_align16) && (__lzo_HAVE_alignof) -#if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul)) -#elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) -#elif (LZO_CC_CILLY || LZO_CC_PCC) -#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) -# define __lzo_struct_align16(s) struct __declspec(align(16)) s { -# define __lzo_struct_align16_end() }; -# define __lzo_struct_align32(s) struct __declspec(align(32)) s { -# define __lzo_struct_align32_end() }; -# define __lzo_struct_align64(s) struct __declspec(align(64)) s { -# define __lzo_struct_align64_end() }; -#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || (LZO_CC_IBMC >= 700) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_struct_align16(s) struct s { -# define __lzo_struct_align16_end() } __attribute__((__aligned__(16))); -# define __lzo_struct_align32(s) struct s { -# define __lzo_struct_align32_end() } __attribute__((__aligned__(32))); -# define __lzo_struct_align64(s) struct s { -# define __lzo_struct_align64_end() } __attribute__((__aligned__(64))); -#endif -#endif -#if !defined(__lzo_union_um) -#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) -#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) -#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER < 810)) -#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) -#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) -#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) -# define __lzo_union_am(s) union s { -# define __lzo_union_am_end() } __lzo_may_alias; -# define __lzo_union_um(s) union s { -# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); -#elif (LZO_CC_IBMC >= 700) -# define __lzo_union_am(s) __lzo_gnuc_extension__ union s { -# define __lzo_union_am_end() } __lzo_may_alias; -# define __lzo_union_um(s) __lzo_gnuc_extension__ union s { -# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); -#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) -# define __lzo_union_um(s) __pragma(pack(push,1)) union s { -# define __lzo_union_um_end() } __pragma(pack(pop)); -#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) -# define __lzo_union_um(s) _Packed union s { -# define __lzo_union_um_end() }; -#endif -#endif -#if !defined(__lzo_union_am) -# define __lzo_union_am(s) union s { -# define __lzo_union_am_end() }; -#endif -#if !defined(__lzo_constructor) -#if (LZO_CC_GNUC >= 0x030400ul) -# define __lzo_constructor __attribute__((__constructor__,__used__)) -#elif (LZO_CC_GNUC >= 0x020700ul) -# define __lzo_constructor __attribute__((__constructor__)) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) -# define __lzo_constructor __attribute__((__constructor__,__used__)) -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_constructor __attribute__((__constructor__)) -#endif -#endif -#if defined(__lzo_constructor) -# ifndef __lzo_HAVE_constructor -# define __lzo_HAVE_constructor 1 -# endif -#endif -#if !defined(__lzo_destructor) -#if (LZO_CC_GNUC >= 0x030400ul) -# define __lzo_destructor __attribute__((__destructor__,__used__)) -#elif (LZO_CC_GNUC >= 0x020700ul) -# define __lzo_destructor __attribute__((__destructor__)) -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) -# define __lzo_destructor __attribute__((__destructor__,__used__)) -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_destructor __attribute__((__destructor__)) -#endif -#endif -#if defined(__lzo_destructor) -# ifndef __lzo_HAVE_destructor -# define __lzo_HAVE_destructor 1 -# endif -#endif -#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor) -# error "unexpected configuration - check your compiler defines" -#endif -#if !defined(__lzo_likely) && !defined(__lzo_unlikely) -#if (LZO_CC_GNUC >= 0x030200ul) -# define __lzo_likely(e) (__builtin_expect(!!(e),1)) -# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) -#elif (LZO_CC_IBMC >= 1010) -# define __lzo_likely(e) (__builtin_expect(!!(e),1)) -# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) -# define __lzo_likely(e) (__builtin_expect(!!(e),1)) -# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) -#elif (LZO_CC_CLANG && LZO_CC_CLANG_C2) -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_likely(e) (__builtin_expect(!!(e),1)) -# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) -#endif -#endif -#if defined(__lzo_likely) -# ifndef __lzo_HAVE_likely -# define __lzo_HAVE_likely 1 -# endif -#else -# define __lzo_likely(e) (e) -#endif -#if defined(__lzo_very_likely) -# ifndef __lzo_HAVE_very_likely -# define __lzo_HAVE_very_likely 1 -# endif -#else -# define __lzo_very_likely(e) __lzo_likely(e) -#endif -#if defined(__lzo_unlikely) -# ifndef __lzo_HAVE_unlikely -# define __lzo_HAVE_unlikely 1 -# endif -#else -# define __lzo_unlikely(e) (e) -#endif -#if defined(__lzo_very_unlikely) -# ifndef __lzo_HAVE_very_unlikely -# define __lzo_HAVE_very_unlikely 1 -# endif -#else -# define __lzo_very_unlikely(e) __lzo_unlikely(e) -#endif -#if !defined(__lzo_loop_forever) -# if (LZO_CC_IBMC) -# define __lzo_loop_forever() LZO_BLOCK_BEGIN for (;;) { ; } LZO_BLOCK_END -# else -# define __lzo_loop_forever() do { ; } while __lzo_cte(1) -# endif -#endif -#if !defined(__lzo_unreachable) -#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x020800ul)) && lzo_has_builtin(__builtin_unreachable) -# define __lzo_unreachable() __builtin_unreachable(); -#elif (LZO_CC_GNUC >= 0x040500ul) -# define __lzo_unreachable() __builtin_unreachable(); -#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1300)) && 1 -# define __lzo_unreachable() __builtin_unreachable(); -#endif -#endif -#if defined(__lzo_unreachable) -# ifndef __lzo_HAVE_unreachable -# define __lzo_HAVE_unreachable 1 -# endif -#else -# if 0 -# define __lzo_unreachable() ((void)0); -# else -# define __lzo_unreachable() __lzo_loop_forever(); -# endif -#endif -#if !defined(lzo_unused_funcs_impl) -# if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) -# define lzo_unused_funcs_impl(r,f) static r __attribute__((__unused__)) f -# elif 1 && (LZO_CC_BORLANDC || LZO_CC_GNUC) -# define lzo_unused_funcs_impl(r,f) static r f -# else -# define lzo_unused_funcs_impl(r,f) __lzo_static_forceinline r f -# endif -#endif -#ifndef __LZO_CTA_NAME -#if (LZO_CFG_USE_COUNTER) -# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__COUNTER__) -#else -# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__LINE__) -#endif -#endif -#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) -# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) -# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END -# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) -# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1u-2*!(e)]; LZO_EXTERN_C_END -# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) -# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END -# elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020900ul)) && defined(__cplusplus) -# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN int __LZO_CTA_NAME(lzo_cta_f__)(int [1-2*!(e)]); LZO_EXTERN_C_END -# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) -# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__)); LZO_EXTERN_C_END -# else -# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-2*!(e)]; LZO_EXTERN_C_END -# endif -#endif -#if !defined(LZO_COMPILE_TIME_ASSERT) -# if (LZO_CC_AZTECC) -# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-!(e)];} -# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030000ul)) -# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));} -# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) -# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; -# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) -# define LZO_COMPILE_TIME_ASSERT(e) {(void) (0/!!(e));} -# elif (LZO_CC_GNUC >= 0x040700ul) && (LZO_CFG_USE_COUNTER) && defined(__cplusplus) -# define LZO_COMPILE_TIME_ASSERT(e) {enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__));} -# elif (LZO_CC_GNUC >= 0x040700ul) -# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));} -# elif (LZO_CC_MSC && (_MSC_VER < 900)) -# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; -# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) -# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; -# else -# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)];} -# endif -#endif -#if (LZO_LANG_ASSEMBLER) -# undef LZO_COMPILE_TIME_ASSERT_HEADER -# define LZO_COMPILE_TIME_ASSERT_HEADER(e) /*empty*/ -#else -LZO_COMPILE_TIME_ASSERT_HEADER(1 == 1) -#if defined(__cplusplus) -extern "C" { LZO_COMPILE_TIME_ASSERT_HEADER(2 == 2) } -#endif -LZO_COMPILE_TIME_ASSERT_HEADER(3 == 3) -#endif -#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) -# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) -# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) -# define __lzo_cdecl __cdecl -# define __lzo_cdecl_atexit /*empty*/ -# define __lzo_cdecl_main __cdecl -# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) -# define __lzo_cdecl_qsort __pascal -# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) -# define __lzo_cdecl_qsort _stdcall -# else -# define __lzo_cdecl_qsort __cdecl -# endif -# elif (LZO_CC_WATCOMC) -# define __lzo_cdecl __cdecl -# else -# define __lzo_cdecl __cdecl -# define __lzo_cdecl_atexit __cdecl -# define __lzo_cdecl_main __cdecl -# define __lzo_cdecl_qsort __cdecl -# endif -# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) -# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) -# define __lzo_cdecl_sighandler __pascal -# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) -# define __lzo_cdecl_sighandler _stdcall -# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) -# define __lzo_cdecl_sighandler __clrcall -# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) -# if defined(_DLL) -# define __lzo_cdecl_sighandler _far _cdecl _loadds -# elif defined(_MT) -# define __lzo_cdecl_sighandler _far _cdecl -# else -# define __lzo_cdecl_sighandler _cdecl -# endif -# else -# define __lzo_cdecl_sighandler __cdecl -# endif -#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) -# define __lzo_cdecl __cdecl -#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) -# define __lzo_cdecl cdecl -#endif -#if !defined(__lzo_cdecl) -# define __lzo_cdecl /*empty*/ -#endif -#if !defined(__lzo_cdecl_atexit) -# define __lzo_cdecl_atexit /*empty*/ -#endif -#if !defined(__lzo_cdecl_main) -# define __lzo_cdecl_main /*empty*/ -#endif -#if !defined(__lzo_cdecl_qsort) -# define __lzo_cdecl_qsort /*empty*/ -#endif -#if !defined(__lzo_cdecl_sighandler) -# define __lzo_cdecl_sighandler /*empty*/ -#endif -#if !defined(__lzo_cdecl_va) -# define __lzo_cdecl_va __lzo_cdecl -#endif -#if !(LZO_CFG_NO_WINDOWS_H) -#if !defined(LZO_HAVE_WINDOWS_H) -#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) -# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) -# elif ((LZO_OS_WIN32 && defined(__PW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul))) -# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) -# else -# define LZO_HAVE_WINDOWS_H 1 -# endif -#endif -#endif -#endif -#define LZO_SIZEOF_CHAR 1 -#ifndef LZO_SIZEOF_SHORT -#if defined(SIZEOF_SHORT) -# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) -#elif defined(__SIZEOF_SHORT__) -# define LZO_SIZEOF_SHORT (__SIZEOF_SHORT__) -#endif -#endif -#ifndef LZO_SIZEOF_INT -#if defined(SIZEOF_INT) -# define LZO_SIZEOF_INT (SIZEOF_INT) -#elif defined(__SIZEOF_INT__) -# define LZO_SIZEOF_INT (__SIZEOF_INT__) -#endif -#endif -#ifndef LZO_SIZEOF_LONG -#if defined(SIZEOF_LONG) -# define LZO_SIZEOF_LONG (SIZEOF_LONG) -#elif defined(__SIZEOF_LONG__) -# define LZO_SIZEOF_LONG (__SIZEOF_LONG__) -#endif -#endif -#ifndef LZO_SIZEOF_LONG_LONG -#if defined(SIZEOF_LONG_LONG) -# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) -#elif defined(__SIZEOF_LONG_LONG__) -# define LZO_SIZEOF_LONG_LONG (__SIZEOF_LONG_LONG__) -#endif -#endif -#ifndef LZO_SIZEOF___INT16 -#if defined(SIZEOF___INT16) -# define LZO_SIZEOF___INT16 (SIZEOF___INT16) -#endif -#endif -#ifndef LZO_SIZEOF___INT32 -#if defined(SIZEOF___INT32) -# define LZO_SIZEOF___INT32 (SIZEOF___INT32) -#endif -#endif -#ifndef LZO_SIZEOF___INT64 -#if defined(SIZEOF___INT64) -# define LZO_SIZEOF___INT64 (SIZEOF___INT64) -#endif -#endif -#ifndef LZO_SIZEOF_VOID_P -#if defined(SIZEOF_VOID_P) -# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) -#elif defined(__SIZEOF_POINTER__) -# define LZO_SIZEOF_VOID_P (__SIZEOF_POINTER__) -#endif -#endif -#ifndef LZO_SIZEOF_SIZE_T -#if defined(SIZEOF_SIZE_T) -# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) -#elif defined(__SIZEOF_SIZE_T__) -# define LZO_SIZEOF_SIZE_T (__SIZEOF_SIZE_T__) -#endif -#endif -#ifndef LZO_SIZEOF_PTRDIFF_T -#if defined(SIZEOF_PTRDIFF_T) -# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) -#elif defined(__SIZEOF_PTRDIFF_T__) -# define LZO_SIZEOF_PTRDIFF_T (__SIZEOF_PTRDIFF_T__) -#endif -#endif -#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) -#if !defined(LZO_SIZEOF_SHORT) -# if (LZO_ARCH_CRAY_PVP) -# define LZO_SIZEOF_SHORT 8 -# elif (USHRT_MAX == LZO_0xffffL) -# define LZO_SIZEOF_SHORT 2 -# elif (__LZO_LSR(USHRT_MAX,7) == 1) -# define LZO_SIZEOF_SHORT 1 -# elif (__LZO_LSR(USHRT_MAX,15) == 1) -# define LZO_SIZEOF_SHORT 2 -# elif (__LZO_LSR(USHRT_MAX,31) == 1) -# define LZO_SIZEOF_SHORT 4 -# elif (__LZO_LSR(USHRT_MAX,63) == 1) -# define LZO_SIZEOF_SHORT 8 -# elif (__LZO_LSR(USHRT_MAX,127) == 1) -# define LZO_SIZEOF_SHORT 16 -# else -# error "LZO_SIZEOF_SHORT" -# endif -#endif -LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SHORT == sizeof(short)) -#if !defined(LZO_SIZEOF_INT) -# if (LZO_ARCH_CRAY_PVP) -# define LZO_SIZEOF_INT 8 -# elif (UINT_MAX == LZO_0xffffL) -# define LZO_SIZEOF_INT 2 -# elif (UINT_MAX == LZO_0xffffffffL) -# define LZO_SIZEOF_INT 4 -# elif (__LZO_LSR(UINT_MAX,7) == 1) -# define LZO_SIZEOF_INT 1 -# elif (__LZO_LSR(UINT_MAX,15) == 1) -# define LZO_SIZEOF_INT 2 -# elif (__LZO_LSR(UINT_MAX,31) == 1) -# define LZO_SIZEOF_INT 4 -# elif (__LZO_LSR(UINT_MAX,63) == 1) -# define LZO_SIZEOF_INT 8 -# elif (__LZO_LSR(UINT_MAX,127) == 1) -# define LZO_SIZEOF_INT 16 -# else -# error "LZO_SIZEOF_INT" -# endif -#endif -LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_INT == sizeof(int)) -#if !defined(LZO_SIZEOF_LONG) -# if (ULONG_MAX == LZO_0xffffffffL) -# define LZO_SIZEOF_LONG 4 -# elif (__LZO_LSR(ULONG_MAX,7) == 1) -# define LZO_SIZEOF_LONG 1 -# elif (__LZO_LSR(ULONG_MAX,15) == 1) -# define LZO_SIZEOF_LONG 2 -# elif (__LZO_LSR(ULONG_MAX,31) == 1) -# define LZO_SIZEOF_LONG 4 -# elif (__LZO_LSR(ULONG_MAX,39) == 1) -# define LZO_SIZEOF_LONG 5 -# elif (__LZO_LSR(ULONG_MAX,63) == 1) -# define LZO_SIZEOF_LONG 8 -# elif (__LZO_LSR(ULONG_MAX,127) == 1) -# define LZO_SIZEOF_LONG 16 -# else -# error "LZO_SIZEOF_LONG" -# endif -#endif -LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_LONG == sizeof(long)) -#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) -#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) -# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) -# if (LZO_CC_GNUC >= 0x030300ul) -# if ((__LONG_MAX__-0) == (__LONG_LONG_MAX__-0)) -# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG -# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) -# define LZO_SIZEOF_LONG_LONG 4 -# endif -# endif -# endif -#endif -#endif -#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) -#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) -#if (LZO_ARCH_I086 && LZO_CC_DMC) -#elif (LZO_CC_CILLY) && defined(__GNUC__) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define LZO_SIZEOF_LONG_LONG 8 -#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_OS_WIN64 || defined(_WIN64)) -# define LZO_SIZEOF___INT64 8 -#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) -# define LZO_SIZEOF___INT64 8 -#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) -# define LZO_SIZEOF___INT64 8 -#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) -# define LZO_SIZEOF___INT64 8 -#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) -# define LZO_SIZEOF___INT64 8 -#elif (LZO_CC_GHS && defined(__LLONG_BIT) && ((__LLONG_BIT-0) == 64)) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && ((_INTEGRAL_MAX_BITS-0) == 64)) -# define LZO_SIZEOF___INT64 8 -#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (defined(__vms) || defined(__VMS)) && ((__INITIAL_POINTER_SIZE-0) == 64) -# define LZO_SIZEOF_LONG_LONG 8 -#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) -#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -# define LZO_SIZEOF_LONG_LONG 8 -#endif -#endif -#endif -#if defined(__cplusplus) && (LZO_CC_GNUC) -# if (LZO_CC_GNUC < 0x020800ul) -# undef LZO_SIZEOF_LONG_LONG -# endif -#endif -#if (LZO_CFG_NO_LONG_LONG) -# undef LZO_SIZEOF_LONG_LONG -#elif defined(__NO_LONG_LONG) -# undef LZO_SIZEOF_LONG_LONG -#elif defined(_NO_LONGLONG) -# undef LZO_SIZEOF_LONG_LONG -#endif -#if !defined(LZO_WORDSIZE) -#if (LZO_ARCH_ALPHA) -# define LZO_WORDSIZE 8 -#elif (LZO_ARCH_AMD64) -# define LZO_WORDSIZE 8 -#elif (LZO_ARCH_ARM64) -# define LZO_WORDSIZE 8 -#elif (LZO_ARCH_AVR) -# define LZO_WORDSIZE 1 -#elif (LZO_ARCH_H8300) -# if defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) -# define LZO_WORDSIZE 4 -# else -# define LZO_WORDSIZE 2 -# endif -#elif (LZO_ARCH_I086) -# define LZO_WORDSIZE 2 -#elif (LZO_ARCH_IA64) -# define LZO_WORDSIZE 8 -#elif (LZO_ARCH_M16C) -# define LZO_WORDSIZE 2 -#elif (LZO_ARCH_SPU) -# define LZO_WORDSIZE 4 -#elif (LZO_ARCH_Z80) -# define LZO_WORDSIZE 1 -#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) -# define LZO_WORDSIZE 8 -#elif (LZO_OS_OS400 || defined(__OS400__)) -# define LZO_WORDSIZE 8 -#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) -# define LZO_WORDSIZE 8 -#endif -#endif -#if !defined(LZO_SIZEOF_VOID_P) -#if defined(__ILP32__) || defined(__ILP32) || defined(_ILP32) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) -# define LZO_SIZEOF_VOID_P 4 -#elif defined(__ILP64__) || defined(__ILP64) || defined(_ILP64) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 8) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) -# define LZO_SIZEOF_VOID_P 8 -#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) -# define LZO_SIZEOF_VOID_P 8 -#elif defined(__LP64__) || defined(__LP64) || defined(_LP64) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) -# define LZO_SIZEOF_VOID_P 8 -#elif (LZO_ARCH_AVR) -# define LZO_SIZEOF_VOID_P 2 -#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) -# define LZO_SIZEOF_VOID_P 2 -#elif (LZO_ARCH_H8300) -# if defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) - LZO_COMPILE_TIME_ASSERT_HEADER(LZO_WORDSIZE == 4) -# if defined(__NORMAL_MODE__) -# define LZO_SIZEOF_VOID_P 2 -# else -# define LZO_SIZEOF_VOID_P 4 -# endif -# else - LZO_COMPILE_TIME_ASSERT_HEADER(LZO_WORDSIZE == 2) -# define LZO_SIZEOF_VOID_P 2 -# endif -# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT -# endif -#elif (LZO_ARCH_I086) -# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) -# define LZO_SIZEOF_VOID_P 2 -# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) -# define LZO_SIZEOF_VOID_P 4 -# else -# error "invalid LZO_ARCH_I086 memory model" -# endif -#elif (LZO_ARCH_M16C) -# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) -# define LZO_SIZEOF_VOID_P 4 -# else -# define LZO_SIZEOF_VOID_P 2 -# endif -#elif (LZO_ARCH_SPU) -# define LZO_SIZEOF_VOID_P 4 -#elif (LZO_ARCH_Z80) -# define LZO_SIZEOF_VOID_P 2 -#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) -# define LZO_SIZEOF_VOID_P 4 -#elif (LZO_OS_OS400 || defined(__OS400__)) -# if defined(__LLP64_IFC__) -# define LZO_SIZEOF_VOID_P 8 -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG -# else -# define LZO_SIZEOF_VOID_P 16 -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG -# endif -#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) -# define LZO_SIZEOF_VOID_P 8 -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG -#endif -#endif -#if !defined(LZO_SIZEOF_VOID_P) -# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG -#endif -LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_VOID_P == sizeof(void *)) -#if !defined(LZO_SIZEOF_SIZE_T) -#if (LZO_ARCH_I086 || LZO_ARCH_M16C) -# define LZO_SIZEOF_SIZE_T 2 -#endif -#endif -#if !defined(LZO_SIZEOF_SIZE_T) -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P -#endif -#if defined(offsetof) -LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SIZE_T == sizeof(size_t)) -#endif -#if !defined(LZO_SIZEOF_PTRDIFF_T) -#if (LZO_ARCH_I086) -# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P -# elif (LZO_MM_COMPACT || LZO_MM_LARGE) -# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) -# define LZO_SIZEOF_PTRDIFF_T 4 -# else -# define LZO_SIZEOF_PTRDIFF_T 2 -# endif -# else -# error "invalid LZO_ARCH_I086 memory model" -# endif -#endif -#endif -#if !defined(LZO_SIZEOF_PTRDIFF_T) -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T -#endif -#if defined(offsetof) -LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t)) -#endif -#if !defined(LZO_WORDSIZE) -# define LZO_WORDSIZE LZO_SIZEOF_VOID_P -#endif -#if (LZO_ABI_NEUTRAL_ENDIAN) -# undef LZO_ABI_BIG_ENDIAN -# undef LZO_ABI_LITTLE_ENDIAN -#elif !(LZO_ABI_BIG_ENDIAN) && !(LZO_ABI_LITTLE_ENDIAN) -#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) -# define LZO_ABI_BIG_ENDIAN 1 -#elif (LZO_ARCH_IA64) && (LZO_OS_POSIX_LINUX || LZO_OS_WIN64) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430 || LZO_ARCH_RISCV) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390 || LZO_ARCH_SPU) -# define LZO_ABI_BIG_ENDIAN 1 -#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) -# if (__LITTLE_ENDIAN__ == 1) -# define LZO_ABI_LITTLE_ENDIAN 1 -# else -# define LZO_ABI_BIG_ENDIAN 1 -# endif -#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) -# define LZO_ABI_BIG_ENDIAN 1 -#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM) && defined(__ARM_BIG_ENDIAN) && ((__ARM_BIG_ENDIAN)+0) -# define LZO_ABI_BIG_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) -# define LZO_ABI_BIG_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM) && defined(_MSC_VER) && defined(_WIN32) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM && LZO_CC_ARMCC_ARMCC) -# if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) -# error "unexpected configuration - check your compiler defines" -# elif defined(__BIG_ENDIAN) -# define LZO_ABI_BIG_ENDIAN 1 -# else -# define LZO_ABI_LITTLE_ENDIAN 1 -# endif -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM64) && defined(__ARM_BIG_ENDIAN) && ((__ARM_BIG_ENDIAN)+0) -# define LZO_ABI_BIG_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EB__) && !defined(__AARCH64EL__) -# define LZO_ABI_BIG_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EL__) && !defined(__AARCH64EB__) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif 1 && (LZO_ARCH_ARM64) && defined(_MSC_VER) && defined(_WIN32) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) -# define LZO_ABI_BIG_ENDIAN 1 -#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) -# define LZO_ABI_LITTLE_ENDIAN 1 -#endif -#endif -#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN) -# error "unexpected configuration - check your compiler defines" -#endif -#if (LZO_ABI_BIG_ENDIAN) -# define LZO_INFO_ABI_ENDIAN "be" -#elif (LZO_ABI_LITTLE_ENDIAN) -# define LZO_INFO_ABI_ENDIAN "le" -#elif (LZO_ABI_NEUTRAL_ENDIAN) -# define LZO_INFO_ABI_ENDIAN "neutral" -#endif -#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) -# define LZO_ABI_I8LP16 1 -# define LZO_INFO_ABI_PM "i8lp16" -#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) -# define LZO_ABI_ILP16 1 -# define LZO_INFO_ABI_PM "ilp16" -#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) -# define LZO_ABI_LP32 1 -# define LZO_INFO_ABI_PM "lp32" -#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) -# define LZO_ABI_ILP32 1 -# define LZO_INFO_ABI_PM "ilp32" -#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) -# define LZO_ABI_LLP64 1 -# define LZO_INFO_ABI_PM "llp64" -#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) -# define LZO_ABI_LP64 1 -# define LZO_INFO_ABI_PM "lp64" -#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) -# define LZO_ABI_ILP64 1 -# define LZO_INFO_ABI_PM "ilp64" -#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) -# define LZO_ABI_IP32L64 1 -# define LZO_INFO_ABI_PM "ip32l64" -#endif -#if (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_VOID_P == 4 && LZO_WORDSIZE == 8) -# define LZO_ABI_IP32W64 1 -# ifndef LZO_INFO_ABI_PM -# define LZO_INFO_ABI_PM "ip32w64" -# endif -#endif -#if 0 -#elif !defined(__LZO_LIBC_OVERRIDE) -#if (LZO_LIBC_NAKED) -# define LZO_INFO_LIBC "naked" -#elif (LZO_LIBC_FREESTANDING) -# define LZO_INFO_LIBC "freestanding" -#elif (LZO_LIBC_MOSTLY_FREESTANDING) -# define LZO_INFO_LIBC "mfreestanding" -#elif (LZO_LIBC_ISOC90) -# define LZO_INFO_LIBC "isoc90" -#elif (LZO_LIBC_ISOC99) -# define LZO_INFO_LIBC "isoc99" -#elif (LZO_CC_ARMCC_ARMCC) && defined(__ARMCLIB_VERSION) -# define LZO_LIBC_ISOC90 1 -# define LZO_INFO_LIBC "isoc90" -#elif defined(__dietlibc__) -# define LZO_LIBC_DIETLIBC 1 -# define LZO_INFO_LIBC "dietlibc" -#elif defined(_NEWLIB_VERSION) -# define LZO_LIBC_NEWLIB 1 -# define LZO_INFO_LIBC "newlib" -#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) -# if defined(__UCLIBC_SUBLEVEL__) -# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + (__UCLIBC_MINOR__-0) * 0x100 + (__UCLIBC_SUBLEVEL__-0)) -# else -# define LZO_LIBC_UCLIBC 0x00090bL -# endif -# define LZO_INFO_LIBC "uc" "libc" -#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) -# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + (__GLIBC_MINOR__-0) * 0x100) -# define LZO_INFO_LIBC "glibc" -#elif (LZO_CC_MWERKS) && defined(__MSL__) -# define LZO_LIBC_MSL __MSL__ -# define LZO_INFO_LIBC "msl" -#elif 1 && defined(__IAR_SYSTEMS_ICC__) -# define LZO_LIBC_ISOC90 1 -# define LZO_INFO_LIBC "isoc90" -#else -# define LZO_LIBC_DEFAULT 1 -# define LZO_INFO_LIBC "default" -#endif -#endif -#if (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) -# define LZO_ASM_SYNTAX_MSC 1 -#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) -#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul)) -#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) -# define LZO_ASM_SYNTAX_GNUC 1 -#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) -# define LZO_ASM_SYNTAX_GNUC 1 -#elif (LZO_CC_GNUC) -# define LZO_ASM_SYNTAX_GNUC 1 -#endif -#if (LZO_ASM_SYNTAX_GNUC) -#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) -# define __LZO_ASM_CLOBBER "ax" -# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ -# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY /*empty*/ -# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ -#elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1000)) -# define __LZO_ASM_CLOBBER "memory" -# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ -# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "memory" -# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ -#else -# define __LZO_ASM_CLOBBER "cc", "memory" -# define __LZO_ASM_CLOBBER_LIST_CC : "cc" -# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "cc", "memory" -# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ -#endif -#endif -#if (LZO_ARCH_ALPHA) -# define LZO_OPT_AVOID_UINT_INDEX 1 -#elif (LZO_ARCH_AMD64) -# define LZO_OPT_AVOID_INT_INDEX 1 -# define LZO_OPT_AVOID_UINT_INDEX 1 -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# ifndef LZO_OPT_UNALIGNED64 -# define LZO_OPT_UNALIGNED64 1 -# endif -#elif (LZO_ARCH_ARM) -# if defined(__ARM_FEATURE_UNALIGNED) -# if ((__ARM_FEATURE_UNALIGNED)+0) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# endif -# elif 1 && (LZO_ARCH_ARM_THUMB2) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# elif 1 && defined(__ARM_ARCH) && ((__ARM_ARCH)+0 >= 7) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 7) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 6) && (defined(__TARGET_PROFILE_A) || defined(__TARGET_PROFILE_R)) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# elif 1 && defined(_MSC_VER) && defined(_M_ARM) && ((_M_ARM)+0 >= 7) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# endif -#elif (LZO_ARCH_ARM64) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# ifndef LZO_OPT_UNALIGNED64 -# define LZO_OPT_UNALIGNED64 1 -# endif -#elif (LZO_ARCH_CRIS) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -#elif (LZO_ARCH_I386) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -#elif (LZO_ARCH_IA64) -# define LZO_OPT_AVOID_INT_INDEX 1 -# define LZO_OPT_AVOID_UINT_INDEX 1 -# define LZO_OPT_PREFER_POSTINC 1 -#elif (LZO_ARCH_M68K) -# define LZO_OPT_PREFER_POSTINC 1 -# define LZO_OPT_PREFER_PREDEC 1 -# if defined(__mc68020__) && !defined(__mcoldfire__) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# endif -#elif (LZO_ARCH_MIPS) -# define LZO_OPT_AVOID_UINT_INDEX 1 -#elif (LZO_ARCH_POWERPC) -# define LZO_OPT_PREFER_PREINC 1 -# define LZO_OPT_PREFER_PREDEC 1 -# if (LZO_ABI_BIG_ENDIAN) || (LZO_WORDSIZE == 8) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# if (LZO_WORDSIZE == 8) -# ifndef LZO_OPT_UNALIGNED64 -# define LZO_OPT_UNALIGNED64 1 -# endif -# endif -# endif -#elif (LZO_ARCH_RISCV) -# define LZO_OPT_AVOID_UINT_INDEX 1 -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# if (LZO_WORDSIZE == 8) -# ifndef LZO_OPT_UNALIGNED64 -# define LZO_OPT_UNALIGNED64 1 -# endif -# endif -#elif (LZO_ARCH_S390) -# ifndef LZO_OPT_UNALIGNED16 -# define LZO_OPT_UNALIGNED16 1 -# endif -# ifndef LZO_OPT_UNALIGNED32 -# define LZO_OPT_UNALIGNED32 1 -# endif -# if (LZO_WORDSIZE == 8) -# ifndef LZO_OPT_UNALIGNED64 -# define LZO_OPT_UNALIGNED64 1 -# endif -# endif -#elif (LZO_ARCH_SH) -# define LZO_OPT_PREFER_POSTINC 1 -# define LZO_OPT_PREFER_PREDEC 1 -#endif -#ifndef LZO_CFG_NO_INLINE_ASM -#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) -# define LZO_CFG_NO_INLINE_ASM 1 -#elif (LZO_CC_LLVM) -# define LZO_CFG_NO_INLINE_ASM 1 -#endif -#endif -#if (LZO_CFG_NO_INLINE_ASM) -# undef LZO_ASM_SYNTAX_MSC -# undef LZO_ASM_SYNTAX_GNUC -# undef __LZO_ASM_CLOBBER -# undef __LZO_ASM_CLOBBER_LIST_CC -# undef __LZO_ASM_CLOBBER_LIST_CC_MEMORY -# undef __LZO_ASM_CLOBBER_LIST_EMPTY -#endif -#ifndef LZO_CFG_NO_UNALIGNED -#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) -# define LZO_CFG_NO_UNALIGNED 1 -#endif -#endif -#if (LZO_CFG_NO_UNALIGNED) -# undef LZO_OPT_UNALIGNED16 -# undef LZO_OPT_UNALIGNED32 -# undef LZO_OPT_UNALIGNED64 -#endif -#if defined(__LZO_INFOSTR_MM) -#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) -# define __LZO_INFOSTR_MM "" -#elif defined(LZO_INFO_MM) -# define __LZO_INFOSTR_MM "." LZO_INFO_MM -#else -# define __LZO_INFOSTR_MM "" -#endif -#if defined(__LZO_INFOSTR_PM) -#elif defined(LZO_INFO_ABI_PM) -# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM -#else -# define __LZO_INFOSTR_PM "" -#endif -#if defined(__LZO_INFOSTR_ENDIAN) -#elif defined(LZO_INFO_ABI_ENDIAN) -# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN -#else -# define __LZO_INFOSTR_ENDIAN "" -#endif -#if defined(__LZO_INFOSTR_OSNAME) -#elif defined(LZO_INFO_OS_CONSOLE) -# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE -#elif defined(LZO_INFO_OS_POSIX) -# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX -#else -# define __LZO_INFOSTR_OSNAME LZO_INFO_OS -#endif -#if defined(__LZO_INFOSTR_LIBC) -#elif defined(LZO_INFO_LIBC) -# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC -#else -# define __LZO_INFOSTR_LIBC "" -#endif -#if defined(__LZO_INFOSTR_CCVER) -#elif defined(LZO_INFO_CCVER) -# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER -#else -# define __LZO_INFOSTR_CCVER "" -#endif -#define LZO_INFO_STRING \ - LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ - " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER -#if !(LZO_CFG_SKIP_LZO_TYPES) -#if (!(LZO_SIZEOF_SHORT+0 > 0 && LZO_SIZEOF_INT+0 > 0 && LZO_SIZEOF_LONG+0 > 0)) -# error "missing defines for sizes" -#endif -#if (!(LZO_SIZEOF_PTRDIFF_T+0 > 0 && LZO_SIZEOF_SIZE_T+0 > 0 && LZO_SIZEOF_VOID_P+0 > 0)) -# error "missing defines for sizes" -#endif -#define LZO_TYPEOF_CHAR 1u -#define LZO_TYPEOF_SHORT 2u -#define LZO_TYPEOF_INT 3u -#define LZO_TYPEOF_LONG 4u -#define LZO_TYPEOF_LONG_LONG 5u -#define LZO_TYPEOF___INT8 17u -#define LZO_TYPEOF___INT16 18u -#define LZO_TYPEOF___INT32 19u -#define LZO_TYPEOF___INT64 20u -#define LZO_TYPEOF___INT128 21u -#define LZO_TYPEOF___INT256 22u -#define LZO_TYPEOF___MODE_QI 33u -#define LZO_TYPEOF___MODE_HI 34u -#define LZO_TYPEOF___MODE_SI 35u -#define LZO_TYPEOF___MODE_DI 36u -#define LZO_TYPEOF___MODE_TI 37u -#define LZO_TYPEOF_CHAR_P 129u -#if !defined(lzo_llong_t) -#if (LZO_SIZEOF_LONG_LONG+0 > 0) -# if !(LZO_LANG_ASSEMBLER) - __lzo_gnuc_extension__ typedef long long lzo_llong_t__; - __lzo_gnuc_extension__ typedef unsigned long long lzo_ullong_t__; -# endif -# define lzo_llong_t lzo_llong_t__ -# define lzo_ullong_t lzo_ullong_t__ -#endif -#endif -#if !defined(lzo_int16e_t) -#if (LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) && (LZO_SIZEOF_SHORT != 2) -# undef LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T -#endif -#if (LZO_SIZEOF_LONG == 2) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) -# define lzo_int16e_t long -# define lzo_uint16e_t unsigned long -# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_LONG -#elif (LZO_SIZEOF_INT == 2) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) -# define lzo_int16e_t int -# define lzo_uint16e_t unsigned int -# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_INT -#elif (LZO_SIZEOF_SHORT == 2) -# define lzo_int16e_t short int -# define lzo_uint16e_t unsigned short int -# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_SHORT -#elif 1 && !(LZO_CFG_TYPE_NO_MODE_HI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) -# if !(LZO_LANG_ASSEMBLER) - typedef int lzo_int16e_hi_t__ __attribute__((__mode__(__HI__))); - typedef unsigned int lzo_uint16e_hi_t__ __attribute__((__mode__(__HI__))); -# endif -# define lzo_int16e_t lzo_int16e_hi_t__ -# define lzo_uint16e_t lzo_uint16e_hi_t__ -# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF___MODE_HI -#elif (LZO_SIZEOF___INT16 == 2) -# define lzo_int16e_t __int16 -# define lzo_uint16e_t unsigned __int16 -# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF___INT16 -#else -#endif -#endif -#if defined(lzo_int16e_t) -# define LZO_SIZEOF_LZO_INT16E_T 2 - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == 2) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == LZO_SIZEOF_LZO_INT16E_T) -#endif -#if !defined(lzo_int32e_t) -#if (LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T == LZO_TYPEOF_INT) && (LZO_SIZEOF_INT != 4) -# undef LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T -#endif -#if (LZO_SIZEOF_LONG == 4) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T == LZO_TYPEOF_INT) -# define lzo_int32e_t long int -# define lzo_uint32e_t unsigned long int -# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_LONG -#elif (LZO_SIZEOF_INT == 4) -# define lzo_int32e_t int -# define lzo_uint32e_t unsigned int -# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_INT -#elif (LZO_SIZEOF_SHORT == 4) -# define lzo_int32e_t short int -# define lzo_uint32e_t unsigned short int -# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_SHORT -#elif (LZO_SIZEOF_LONG_LONG == 4) -# define lzo_int32e_t lzo_llong_t -# define lzo_uint32e_t lzo_ullong_t -# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_LONG_LONG -#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) && (__INT_MAX__+0 > 2147483647L) -# if !(LZO_LANG_ASSEMBLER) - typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); - typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); -# endif -# define lzo_int32e_t lzo_int32e_si_t__ -# define lzo_uint32e_t lzo_uint32e_si_t__ -# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___MODE_SI -#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_GNUC >= 0x025f00ul) && defined(__AVR__) && (__LONG_MAX__+0 == 32767L) -# if !(LZO_LANG_ASSEMBLER) - typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); - typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); -# endif -# define lzo_int32e_t lzo_int32e_si_t__ -# define lzo_uint32e_t lzo_uint32e_si_t__ -# define LZO_INT32_C(c) (c##LL) -# define LZO_UINT32_C(c) (c##ULL) -# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___MODE_SI -#elif (LZO_SIZEOF___INT32 == 4) -# define lzo_int32e_t __int32 -# define lzo_uint32e_t unsigned __int32 -# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___INT32 -#else -#endif -#endif -#if defined(lzo_int32e_t) -# define LZO_SIZEOF_LZO_INT32E_T 4 - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == 4) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == LZO_SIZEOF_LZO_INT32E_T) -#endif -#if !defined(lzo_int64e_t) -#if (LZO_SIZEOF___INT64 == 8) -# if (LZO_CC_BORLANDC) && !defined(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T) -# define LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T LZO_TYPEOF___INT64 -# endif -#endif -#if (LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF_LONG_LONG) && (LZO_SIZEOF_LONG_LONG != 8) -# undef LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T -#endif -#if (LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) && (LZO_SIZEOF___INT64 != 8) -# undef LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T -#endif -#if (LZO_SIZEOF_INT == 8) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) -# define lzo_int64e_t int -# define lzo_uint64e_t unsigned int -# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_INT -#elif (LZO_SIZEOF_LONG == 8) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF_LONG_LONG) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) -# define lzo_int64e_t long int -# define lzo_uint64e_t unsigned long int -# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_LONG -#elif (LZO_SIZEOF_LONG_LONG == 8) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) -# define lzo_int64e_t lzo_llong_t -# define lzo_uint64e_t lzo_ullong_t -# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_LONG_LONG -# if (LZO_CC_BORLANDC) -# define LZO_INT64_C(c) ((c) + 0ll) -# define LZO_UINT64_C(c) ((c) + 0ull) -# elif 0 -# define LZO_INT64_C(c) (__lzo_gnuc_extension__ (c##LL)) -# define LZO_UINT64_C(c) (__lzo_gnuc_extension__ (c##ULL)) -# else -# define LZO_INT64_C(c) (c##LL) -# define LZO_UINT64_C(c) (c##ULL) -# endif -#elif (LZO_SIZEOF___INT64 == 8) -# define lzo_int64e_t __int64 -# define lzo_uint64e_t unsigned __int64 -# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF___INT64 -# if (LZO_CC_BORLANDC) -# define LZO_INT64_C(c) ((c) + 0i64) -# define LZO_UINT64_C(c) ((c) + 0ui64) -# else -# define LZO_INT64_C(c) (c##i64) -# define LZO_UINT64_C(c) (c##ui64) -# endif -#else -#endif -#endif -#if defined(lzo_int64e_t) -# define LZO_SIZEOF_LZO_INT64E_T 8 - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == 8) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == LZO_SIZEOF_LZO_INT64E_T) -#endif -#if !defined(lzo_int32l_t) -#if defined(lzo_int32e_t) -# define lzo_int32l_t lzo_int32e_t -# define lzo_uint32l_t lzo_uint32e_t -# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LZO_INT32E_T -# define LZO_TYPEOF_LZO_INT32L_T LZO_TYPEOF_LZO_INT32E_T -#elif (LZO_SIZEOF_INT >= 4) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) -# define lzo_int32l_t int -# define lzo_uint32l_t unsigned int -# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_INT -# define LZO_TYPEOF_LZO_INT32L_T LZO_SIZEOF_INT -#elif (LZO_SIZEOF_LONG >= 4) -# define lzo_int32l_t long int -# define lzo_uint32l_t unsigned long int -# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LONG -# define LZO_TYPEOF_LZO_INT32L_T LZO_SIZEOF_LONG -#else -# error "lzo_int32l_t" -#endif -#endif -#if 1 - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) >= 4) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) == LZO_SIZEOF_LZO_INT32L_T) -#endif -#if !defined(lzo_int64l_t) -#if defined(lzo_int64e_t) -# define lzo_int64l_t lzo_int64e_t -# define lzo_uint64l_t lzo_uint64e_t -# define LZO_SIZEOF_LZO_INT64L_T LZO_SIZEOF_LZO_INT64E_T -# define LZO_TYPEOF_LZO_INT64L_T LZO_TYPEOF_LZO_INT64E_T -#else -#endif -#endif -#if defined(lzo_int64l_t) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) >= 8) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) == LZO_SIZEOF_LZO_INT64L_T) -#endif -#if !defined(lzo_int32f_t) -#if (LZO_SIZEOF_SIZE_T >= 8) -# define lzo_int32f_t lzo_int64l_t -# define lzo_uint32f_t lzo_uint64l_t -# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT64L_T -# define LZO_TYPEOF_LZO_INT32F_T LZO_TYPEOF_LZO_INT64L_T -#else -# define lzo_int32f_t lzo_int32l_t -# define lzo_uint32f_t lzo_uint32l_t -# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT32L_T -# define LZO_TYPEOF_LZO_INT32F_T LZO_TYPEOF_LZO_INT32L_T -#endif -#endif -#if 1 - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) >= 4) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) == LZO_SIZEOF_LZO_INT32F_T) -#endif -#if !defined(lzo_int64f_t) -#if defined(lzo_int64l_t) -# define lzo_int64f_t lzo_int64l_t -# define lzo_uint64f_t lzo_uint64l_t -# define LZO_SIZEOF_LZO_INT64F_T LZO_SIZEOF_LZO_INT64L_T -# define LZO_TYPEOF_LZO_INT64F_T LZO_TYPEOF_LZO_INT64L_T -#else -#endif -#endif -#if defined(lzo_int64f_t) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) >= 8) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) == LZO_SIZEOF_LZO_INT64F_T) -#endif -#if !defined(lzo_intptr_t) -#if 1 && (LZO_OS_OS400 && (LZO_SIZEOF_VOID_P == 16)) -# define __LZO_INTPTR_T_IS_POINTER 1 -# if !(LZO_LANG_ASSEMBLER) - typedef char * lzo_intptr_t; - typedef char * lzo_uintptr_t; -# endif -# define lzo_intptr_t lzo_intptr_t -# define lzo_uintptr_t lzo_uintptr_t -# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_VOID_P -# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_CHAR_P -#elif (LZO_CC_MSC && (_MSC_VER >= 1300) && (LZO_SIZEOF_VOID_P == 4) && (LZO_SIZEOF_INT == 4)) -# if !(LZO_LANG_ASSEMBLER) - typedef __w64 int lzo_intptr_t; - typedef __w64 unsigned int lzo_uintptr_t; -# endif -# define lzo_intptr_t lzo_intptr_t -# define lzo_uintptr_t lzo_uintptr_t -# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT -# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_INT -#elif (LZO_SIZEOF_SHORT == LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT > LZO_SIZEOF_VOID_P) -# define lzo_intptr_t short -# define lzo_uintptr_t unsigned short -# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_SHORT -# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_SHORT -#elif (LZO_SIZEOF_INT >= LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) -# define lzo_intptr_t int -# define lzo_uintptr_t unsigned int -# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT -# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_INT -#elif (LZO_SIZEOF_LONG >= LZO_SIZEOF_VOID_P) -# define lzo_intptr_t long -# define lzo_uintptr_t unsigned long -# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LONG -# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_LONG -#elif (LZO_SIZEOF_LZO_INT64L_T >= LZO_SIZEOF_VOID_P) -# define lzo_intptr_t lzo_int64l_t -# define lzo_uintptr_t lzo_uint64l_t -# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LZO_INT64L_T -# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_LZO_INT64L_T -#else -# error "lzo_intptr_t" -#endif -#endif -#if 1 - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) >= sizeof(void *)) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) == sizeof(lzo_uintptr_t)) -#endif -#if !defined(lzo_word_t) -#if defined(LZO_WORDSIZE) && (LZO_WORDSIZE+0 > 0) -#if (LZO_WORDSIZE == LZO_SIZEOF_LZO_INTPTR_T) && !(__LZO_INTPTR_T_IS_POINTER) -# define lzo_word_t lzo_uintptr_t -# define lzo_sword_t lzo_intptr_t -# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INTPTR_T -# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_LZO_INTPTR_T -#elif (LZO_WORDSIZE == LZO_SIZEOF_LONG) -# define lzo_word_t unsigned long -# define lzo_sword_t long -# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LONG -# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_LONG -#elif (LZO_WORDSIZE == LZO_SIZEOF_INT) -# define lzo_word_t unsigned int -# define lzo_sword_t int -# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_INT -# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_INT -#elif (LZO_WORDSIZE == LZO_SIZEOF_SHORT) -# define lzo_word_t unsigned short -# define lzo_sword_t short -# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_SHORT -# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_SHORT -#elif (LZO_WORDSIZE == 1) -# define lzo_word_t unsigned char -# define lzo_sword_t signed char -# define LZO_SIZEOF_LZO_WORD_T 1 -# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_CHAR -#elif (LZO_WORDSIZE == LZO_SIZEOF_LZO_INT64L_T) -# define lzo_word_t lzo_uint64l_t -# define lzo_sword_t lzo_int64l_t -# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T -# define LZO_TYPEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T -#elif (LZO_ARCH_SPU) && (LZO_CC_GNUC) -#if 0 -# if !(LZO_LANG_ASSEMBLER) - typedef unsigned lzo_word_t __attribute__((__mode__(__V16QI__))); - typedef int lzo_sword_t __attribute__((__mode__(__V16QI__))); -# endif -# define lzo_word_t lzo_word_t -# define lzo_sword_t lzo_sword_t -# define LZO_SIZEOF_LZO_WORD_T 16 -# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF___MODE_V16QI -#endif -#else -# error "lzo_word_t" -#endif -#endif -#endif -#if 1 && defined(lzo_word_t) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_word_t) == LZO_WORDSIZE) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_sword_t) == LZO_WORDSIZE) -#endif -#if 1 -#define lzo_int8_t signed char -#define lzo_uint8_t unsigned char -#define LZO_SIZEOF_LZO_INT8_T 1 -#define LZO_TYPEOF_LZO_INT8_T LZO_TYPEOF_CHAR -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == sizeof(lzo_uint8_t)) -#endif -#if defined(lzo_int16e_t) -#define lzo_int16_t lzo_int16e_t -#define lzo_uint16_t lzo_uint16e_t -#define LZO_SIZEOF_LZO_INT16_T LZO_SIZEOF_LZO_INT16E_T -#define LZO_TYPEOF_LZO_INT16_T LZO_TYPEOF_LZO_INT16E_T -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == sizeof(lzo_uint16_t)) -#endif -#if defined(lzo_int32e_t) -#define lzo_int32_t lzo_int32e_t -#define lzo_uint32_t lzo_uint32e_t -#define LZO_SIZEOF_LZO_INT32_T LZO_SIZEOF_LZO_INT32E_T -#define LZO_TYPEOF_LZO_INT32_T LZO_TYPEOF_LZO_INT32E_T -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == sizeof(lzo_uint32_t)) -#endif -#if defined(lzo_int64e_t) -#define lzo_int64_t lzo_int64e_t -#define lzo_uint64_t lzo_uint64e_t -#define LZO_SIZEOF_LZO_INT64_T LZO_SIZEOF_LZO_INT64E_T -#define LZO_TYPEOF_LZO_INT64_T LZO_TYPEOF_LZO_INT64E_T -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == sizeof(lzo_uint64_t)) -#endif -#if 1 -#define lzo_int_least32_t lzo_int32l_t -#define lzo_uint_least32_t lzo_uint32l_t -#define LZO_SIZEOF_LZO_INT_LEAST32_T LZO_SIZEOF_LZO_INT32L_T -#define LZO_TYPEOF_LZO_INT_LEAST32_T LZO_TYPEOF_LZO_INT32L_T -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) >= 4) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) == sizeof(lzo_uint_least32_t)) -#endif -#if defined(lzo_int64l_t) -#define lzo_int_least64_t lzo_int64l_t -#define lzo_uint_least64_t lzo_uint64l_t -#define LZO_SIZEOF_LZO_INT_LEAST64_T LZO_SIZEOF_LZO_INT64L_T -#define LZO_TYPEOF_LZO_INT_LEAST64_T LZO_TYPEOF_LZO_INT64L_T -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) >= 8) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) == sizeof(lzo_uint_least64_t)) -#endif -#if 1 -#define lzo_int_fast32_t lzo_int32f_t -#define lzo_uint_fast32_t lzo_uint32f_t -#define LZO_SIZEOF_LZO_INT_FAST32_T LZO_SIZEOF_LZO_INT32F_T -#define LZO_TYPEOF_LZO_INT_FAST32_T LZO_TYPEOF_LZO_INT32F_T -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) >= 4) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) == sizeof(lzo_uint_fast32_t)) -#endif -#if defined(lzo_int64f_t) -#define lzo_int_fast64_t lzo_int64f_t -#define lzo_uint_fast64_t lzo_uint64f_t -#define LZO_SIZEOF_LZO_INT_FAST64_T LZO_SIZEOF_LZO_INT64F_T -#define LZO_TYPEOF_LZO_INT_FAST64_T LZO_TYPEOF_LZO_INT64F_T -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) >= 8) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) == sizeof(lzo_uint_fast64_t)) -#endif -#if !defined(LZO_INT16_C) -# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 2) -# define LZO_INT16_C(c) ((c) + 0) -# define LZO_UINT16_C(c) ((c) + 0U) -# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 2) -# define LZO_INT16_C(c) ((c) + 0L) -# define LZO_UINT16_C(c) ((c) + 0UL) -# elif (LZO_SIZEOF_INT >= 2) -# define LZO_INT16_C(c) (c) -# define LZO_UINT16_C(c) (c##U) -# elif (LZO_SIZEOF_LONG >= 2) -# define LZO_INT16_C(c) (c##L) -# define LZO_UINT16_C(c) (c##UL) -# else -# error "LZO_INT16_C" -# endif -#endif -#if !defined(LZO_INT32_C) -# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 4) -# define LZO_INT32_C(c) ((c) + 0) -# define LZO_UINT32_C(c) ((c) + 0U) -# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 4) -# define LZO_INT32_C(c) ((c) + 0L) -# define LZO_UINT32_C(c) ((c) + 0UL) -# elif (LZO_SIZEOF_INT >= 4) -# define LZO_INT32_C(c) (c) -# define LZO_UINT32_C(c) (c##U) -# elif (LZO_SIZEOF_LONG >= 4) -# define LZO_INT32_C(c) (c##L) -# define LZO_UINT32_C(c) (c##UL) -# elif (LZO_SIZEOF_LONG_LONG >= 4) -# define LZO_INT32_C(c) (c##LL) -# define LZO_UINT32_C(c) (c##ULL) -# else -# error "LZO_INT32_C" -# endif -#endif -#if !defined(LZO_INT64_C) && defined(lzo_int64l_t) -# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 8) -# define LZO_INT64_C(c) ((c) + 0) -# define LZO_UINT64_C(c) ((c) + 0U) -# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 8) -# define LZO_INT64_C(c) ((c) + 0L) -# define LZO_UINT64_C(c) ((c) + 0UL) -# elif (LZO_SIZEOF_INT >= 8) -# define LZO_INT64_C(c) (c) -# define LZO_UINT64_C(c) (c##U) -# elif (LZO_SIZEOF_LONG >= 8) -# define LZO_INT64_C(c) (c##L) -# define LZO_UINT64_C(c) (c##UL) -# else -# error "LZO_INT64_C" -# endif -#endif -#endif - -#endif - -#endif - -#undef LZO_HAVE_CONFIG_H -#include "minilzo.h" - -#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x20a0) -# error "version mismatch in miniLZO source files" -#endif - -#ifdef MINILZO_HAVE_CONFIG_H -# define LZO_HAVE_CONFIG_H 1 -#endif - -#ifndef __LZO_CONF_H -#define __LZO_CONF_H 1 - -#if !defined(__LZO_IN_MINILZO) -#if defined(LZO_CFG_FREESTANDING) && (LZO_CFG_FREESTANDING) -# define LZO_LIBC_FREESTANDING 1 -# define LZO_OS_FREESTANDING 1 -#endif -#if defined(LZO_CFG_EXTRA_CONFIG_HEADER) -# include LZO_CFG_EXTRA_CONFIG_HEADER -#endif -#if defined(__LZOCONF_H) || defined(__LZOCONF_H_INCLUDED) -# error "include this file first" -#endif -#if defined(LZO_CFG_BUILD_DLL) && (LZO_CFG_BUILD_DLL+0) && !defined(__LZO_EXPORT1) && !defined(__LZO_EXPORT2) && 0 -#ifndef __LZODEFS_H_INCLUDED -#if defined(LZO_HAVE_CONFIG_H) -# include -#endif -#include -#include -#include -#endif -#endif -#include -#if defined(LZO_CFG_EXTRA_CONFIG_HEADER2) -# include LZO_CFG_EXTRA_CONFIG_HEADER2 -#endif -#endif - -#if !defined(__LZOCONF_H_INCLUDED) || (LZO_VERSION+0 != 0x20a0) -# error "version mismatch" -#endif - -#if (LZO_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1100)) -# pragma warning(disable: 4702) -#endif -#if (LZO_CC_MSC && (_MSC_VER >= 1000)) -# pragma warning(disable: 4127 4701) -# pragma warning(disable: 4514 4710 4711) -#endif -#if (LZO_CC_MSC && (_MSC_VER >= 1300)) -# pragma warning(disable: 4820) -#endif -#if (LZO_CC_MSC && (_MSC_VER >= 1800)) -# pragma warning(disable: 4746) -#endif -#if (LZO_CC_INTELC && (__INTEL_COMPILER >= 900)) -# pragma warning(disable: 1684) -#endif - -#if (LZO_CC_SUNPROC) -#if !defined(__cplusplus) -# pragma error_messages(off,E_END_OF_LOOP_CODE_NOT_REACHED) -# pragma error_messages(off,E_LOOP_NOT_ENTERED_AT_TOP) -# pragma error_messages(off,E_STATEMENT_NOT_REACHED) -#endif -#endif - -#if !defined(__LZO_NOEXPORT1) -# define __LZO_NOEXPORT1 /*empty*/ -#endif -#if !defined(__LZO_NOEXPORT2) -# define __LZO_NOEXPORT2 /*empty*/ -#endif - -#if 1 -# define LZO_PUBLIC_DECL(r) LZO_EXTERN(r) -#endif -#if 1 -# define LZO_PUBLIC_IMPL(r) LZO_PUBLIC(r) -#endif -#if !defined(LZO_LOCAL_DECL) -# define LZO_LOCAL_DECL(r) __LZO_EXTERN_C LZO_LOCAL_IMPL(r) -#endif -#if !defined(LZO_LOCAL_IMPL) -# define LZO_LOCAL_IMPL(r) __LZO_NOEXPORT1 r __LZO_NOEXPORT2 __LZO_CDECL -#endif -#if 1 -# define LZO_STATIC_DECL(r) LZO_PRIVATE(r) -#endif -#if 1 -# define LZO_STATIC_IMPL(r) LZO_PRIVATE(r) -#endif - -#if defined(__LZO_IN_MINILZO) || (LZO_CFG_FREESTANDING) -#elif 1 -# include -#else -# define LZO_WANT_ACC_INCD_H 1 -#endif -#if defined(LZO_HAVE_CONFIG_H) -# define LZO_CFG_NO_CONFIG_HEADER 1 -#endif - -#if 1 && !defined(LZO_CFG_FREESTANDING) -#if 1 && !defined(HAVE_STRING_H) -#define HAVE_STRING_H 1 -#endif -#if 1 && !defined(HAVE_MEMCMP) -#define HAVE_MEMCMP 1 -#endif -#if 1 && !defined(HAVE_MEMCPY) -#define HAVE_MEMCPY 1 -#endif -#if 1 && !defined(HAVE_MEMMOVE) -#define HAVE_MEMMOVE 1 -#endif -#if 1 && !defined(HAVE_MEMSET) -#define HAVE_MEMSET 1 -#endif -#endif - -#if 1 && defined(HAVE_STRING_H) -#include -#endif - -#if 1 || defined(lzo_int8_t) || defined(lzo_uint8_t) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint8_t) == 1) -#endif -#if 1 || defined(lzo_int16_t) || defined(lzo_uint16_t) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint16_t) == 2) -#endif -#if 1 || defined(lzo_int32_t) || defined(lzo_uint32_t) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32_t) == 4) -#endif -#if defined(lzo_int64_t) || defined(lzo_uint64_t) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint64_t) == 8) -#endif - -#if (LZO_CFG_FREESTANDING) -# undef HAVE_MEMCMP -# undef HAVE_MEMCPY -# undef HAVE_MEMMOVE -# undef HAVE_MEMSET -#endif - -#if !(HAVE_MEMCMP) -# undef memcmp -# define memcmp(a,b,c) lzo_memcmp(a,b,c) -#else -# undef lzo_memcmp -# define lzo_memcmp(a,b,c) memcmp(a,b,c) -#endif -#if !(HAVE_MEMCPY) -# undef memcpy -# define memcpy(a,b,c) lzo_memcpy(a,b,c) -#else -# undef lzo_memcpy -# define lzo_memcpy(a,b,c) memcpy(a,b,c) -#endif -#if !(HAVE_MEMMOVE) -# undef memmove -# define memmove(a,b,c) lzo_memmove(a,b,c) -#else -# undef lzo_memmove -# define lzo_memmove(a,b,c) memmove(a,b,c) -#endif -#if !(HAVE_MEMSET) -# undef memset -# define memset(a,b,c) lzo_memset(a,b,c) -#else -# undef lzo_memset -# define lzo_memset(a,b,c) memset(a,b,c) -#endif - -#undef NDEBUG -#if (LZO_CFG_FREESTANDING) -# undef LZO_DEBUG -# define NDEBUG 1 -# undef assert -# define assert(e) ((void)0) -#else -# if !defined(LZO_DEBUG) -# define NDEBUG 1 -# endif -# include -#endif - -#if 0 && defined(__BOUNDS_CHECKING_ON) -# include -#else -# define BOUNDS_CHECKING_OFF_DURING(stmt) stmt -# define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr) -#endif - -#if (LZO_CFG_PGO) -# undef __lzo_likely -# undef __lzo_unlikely -# define __lzo_likely(e) (e) -# define __lzo_unlikely(e) (e) -#endif - -#undef _ -#undef __ -#undef ___ -#undef ____ -#undef _p0 -#undef _p1 -#undef _p2 -#undef _p3 -#undef _p4 -#undef _s0 -#undef _s1 -#undef _s2 -#undef _s3 -#undef _s4 -#undef _ww - -#if 1 -# define LZO_BYTE(x) ((unsigned char) (x)) -#else -# define LZO_BYTE(x) ((unsigned char) ((x) & 0xff)) -#endif - -#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) -#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b)) -#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c)) -#define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c)) - -#define lzo_sizeof(type) ((lzo_uint) (sizeof(type))) - -#define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array)))) - -#define LZO_SIZE(bits) (1u << (bits)) -#define LZO_MASK(bits) (LZO_SIZE(bits) - 1) - -#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits)) -#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1) - -#if !defined(DMUL) -#if 0 - -# define DMUL(a,b) ((lzo_xint) ((lzo_uint32_t)(a) * (lzo_uint32_t)(b))) -#else -# define DMUL(a,b) ((lzo_xint) ((a) * (b))) -#endif -#endif - -#ifndef __LZO_FUNC_H -#define __LZO_FUNC_H 1 - -#if !defined(LZO_BITOPS_USE_ASM_BITSCAN) && !defined(LZO_BITOPS_USE_GNUC_BITSCAN) && !defined(LZO_BITOPS_USE_MSC_BITSCAN) -#if 1 && (LZO_ARCH_AMD64) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_ASM_SYNTAX_GNUC) -#define LZO_BITOPS_USE_ASM_BITSCAN 1 -#elif (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x030400ul) || (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_LLVM && (!defined(__llvm_tools_version__) || (__llvm_tools_version__+0 >= 0x010500ul)))) -#define LZO_BITOPS_USE_GNUC_BITSCAN 1 -#elif (LZO_OS_WIN32 || LZO_OS_WIN64) && ((LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 1010)) || (LZO_CC_MSC && (_MSC_VER >= 1400))) -#define LZO_BITOPS_USE_MSC_BITSCAN 1 -#if (LZO_CC_MSC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) -#include -#endif -#if (LZO_CC_MSC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) -#pragma intrinsic(_BitScanReverse) -#pragma intrinsic(_BitScanForward) -#endif -#if (LZO_CC_MSC) && (LZO_ARCH_AMD64) -#pragma intrinsic(_BitScanReverse64) -#pragma intrinsic(_BitScanForward64) -#endif -#endif -#endif - -__lzo_static_forceinline unsigned lzo_bitops_ctlz32_func(lzo_uint32_t v) -{ -#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) - unsigned long r; (void) _BitScanReverse(&r, v); return (unsigned) r ^ 31; -#define lzo_bitops_ctlz32(v) lzo_bitops_ctlz32_func(v) -#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) && (LZO_ASM_SYNTAX_GNUC) - lzo_uint32_t r; - __asm__("bsr %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); - return (unsigned) r ^ 31; -#define lzo_bitops_ctlz32(v) lzo_bitops_ctlz32_func(v) -#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_INT == 4) - unsigned r; r = (unsigned) __builtin_clz(v); return r; -#define lzo_bitops_ctlz32(v) ((unsigned) __builtin_clz(v)) -#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG == 8) && (LZO_WORDSIZE >= 8) - unsigned r; r = (unsigned) __builtin_clzl(v); return r ^ 32; -#define lzo_bitops_ctlz32(v) (((unsigned) __builtin_clzl(v)) ^ 32) -#else - LZO_UNUSED(v); return 0; -#endif -} - -#if defined(lzo_uint64_t) -__lzo_static_forceinline unsigned lzo_bitops_ctlz64_func(lzo_uint64_t v) -{ -#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64) - unsigned long r; (void) _BitScanReverse64(&r, v); return (unsigned) r ^ 63; -#define lzo_bitops_ctlz64(v) lzo_bitops_ctlz64_func(v) -#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64) && (LZO_ASM_SYNTAX_GNUC) - lzo_uint64_t r; - __asm__("bsr %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); - return (unsigned) r ^ 63; -#define lzo_bitops_ctlz64(v) lzo_bitops_ctlz64_func(v) -#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG == 8) && (LZO_WORDSIZE >= 8) - unsigned r; r = (unsigned) __builtin_clzl(v); return r; -#define lzo_bitops_ctlz64(v) ((unsigned) __builtin_clzl(v)) -#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG_LONG == 8) && (LZO_WORDSIZE >= 8) - unsigned r; r = (unsigned) __builtin_clzll(v); return r; -#define lzo_bitops_ctlz64(v) ((unsigned) __builtin_clzll(v)) -#else - LZO_UNUSED(v); return 0; -#endif -} -#endif - -__lzo_static_forceinline unsigned lzo_bitops_cttz32_func(lzo_uint32_t v) -{ -#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) - unsigned long r; (void) _BitScanForward(&r, v); return (unsigned) r; -#define lzo_bitops_cttz32(v) lzo_bitops_cttz32_func(v) -#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) && (LZO_ASM_SYNTAX_GNUC) - lzo_uint32_t r; - __asm__("bsf %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); - return (unsigned) r; -#define lzo_bitops_cttz32(v) lzo_bitops_cttz32_func(v) -#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_INT >= 4) - unsigned r; r = (unsigned) __builtin_ctz(v); return r; -#define lzo_bitops_cttz32(v) ((unsigned) __builtin_ctz(v)) -#else - LZO_UNUSED(v); return 0; -#endif -} - -#if defined(lzo_uint64_t) -__lzo_static_forceinline unsigned lzo_bitops_cttz64_func(lzo_uint64_t v) -{ -#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64) - unsigned long r; (void) _BitScanForward64(&r, v); return (unsigned) r; -#define lzo_bitops_cttz64(v) lzo_bitops_cttz64_func(v) -#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64) && (LZO_ASM_SYNTAX_GNUC) - lzo_uint64_t r; - __asm__("bsf %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); - return (unsigned) r; -#define lzo_bitops_cttz64(v) lzo_bitops_cttz64_func(v) -#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG >= 8) && (LZO_WORDSIZE >= 8) - unsigned r; r = (unsigned) __builtin_ctzl(v); return r; -#define lzo_bitops_cttz64(v) ((unsigned) __builtin_ctzl(v)) -#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG_LONG >= 8) && (LZO_WORDSIZE >= 8) - unsigned r; r = (unsigned) __builtin_ctzll(v); return r; -#define lzo_bitops_cttz64(v) ((unsigned) __builtin_ctzll(v)) -#else - LZO_UNUSED(v); return 0; -#endif -} -#endif - -lzo_unused_funcs_impl(void, lzo_bitops_unused_funcs)(void) -{ - LZO_UNUSED_FUNC(lzo_bitops_unused_funcs); - LZO_UNUSED_FUNC(lzo_bitops_ctlz32_func); - LZO_UNUSED_FUNC(lzo_bitops_cttz32_func); -#if defined(lzo_uint64_t) - LZO_UNUSED_FUNC(lzo_bitops_ctlz64_func); - LZO_UNUSED_FUNC(lzo_bitops_cttz64_func); -#endif -} - -#if defined(__lzo_alignof) && !(LZO_CFG_NO_UNALIGNED) -#if !defined(lzo_memops_tcheck__) && 0 -#define lzo_memops_tcheck__(t,a,b) ((void)0, sizeof(t) == (a) && __lzo_alignof(t) == (b)) -#endif -#endif -#ifndef lzo_memops_TU0p -#define lzo_memops_TU0p void __LZO_MMODEL * -#endif -#ifndef lzo_memops_TU1p -#define lzo_memops_TU1p unsigned char __LZO_MMODEL * -#endif -#ifndef lzo_memops_TU2p -#if (LZO_OPT_UNALIGNED16) -typedef lzo_uint16_t __lzo_may_alias lzo_memops_TU2; -#define lzo_memops_TU2p volatile lzo_memops_TU2 * -#elif defined(__lzo_byte_struct) -__lzo_byte_struct(lzo_memops_TU2_struct,2) -typedef struct lzo_memops_TU2_struct lzo_memops_TU2; -#else -struct lzo_memops_TU2_struct { unsigned char a[2]; } __lzo_may_alias; -typedef struct lzo_memops_TU2_struct lzo_memops_TU2; -#endif -#ifndef lzo_memops_TU2p -#define lzo_memops_TU2p lzo_memops_TU2 * -#endif -#endif -#ifndef lzo_memops_TU4p -#if (LZO_OPT_UNALIGNED32) -typedef lzo_uint32_t __lzo_may_alias lzo_memops_TU4; -#define lzo_memops_TU4p volatile lzo_memops_TU4 __LZO_MMODEL * -#elif defined(__lzo_byte_struct) -__lzo_byte_struct(lzo_memops_TU4_struct,4) -typedef struct lzo_memops_TU4_struct lzo_memops_TU4; -#else -struct lzo_memops_TU4_struct { unsigned char a[4]; } __lzo_may_alias; -typedef struct lzo_memops_TU4_struct lzo_memops_TU4; -#endif -#ifndef lzo_memops_TU4p -#define lzo_memops_TU4p lzo_memops_TU4 __LZO_MMODEL * -#endif -#endif -#ifndef lzo_memops_TU8p -#if (LZO_OPT_UNALIGNED64) -typedef lzo_uint64_t __lzo_may_alias lzo_memops_TU8; -#define lzo_memops_TU8p volatile lzo_memops_TU8 __LZO_MMODEL * -#elif defined(__lzo_byte_struct) -__lzo_byte_struct(lzo_memops_TU8_struct,8) -typedef struct lzo_memops_TU8_struct lzo_memops_TU8; -#else -struct lzo_memops_TU8_struct { unsigned char a[8]; } __lzo_may_alias; -typedef struct lzo_memops_TU8_struct lzo_memops_TU8; -#endif -#ifndef lzo_memops_TU8p -#define lzo_memops_TU8p lzo_memops_TU8 __LZO_MMODEL * -#endif -#endif -#ifndef lzo_memops_set_TU1p -#define lzo_memops_set_TU1p volatile lzo_memops_TU1p -#endif -#ifndef lzo_memops_move_TU1p -#define lzo_memops_move_TU1p lzo_memops_TU1p -#endif -#define LZO_MEMOPS_SET1(dd,cc) \ - LZO_BLOCK_BEGIN \ - lzo_memops_set_TU1p d__1 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ - d__1[0] = LZO_BYTE(cc); \ - LZO_BLOCK_END -#define LZO_MEMOPS_SET2(dd,cc) \ - LZO_BLOCK_BEGIN \ - lzo_memops_set_TU1p d__2 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ - d__2[0] = LZO_BYTE(cc); d__2[1] = LZO_BYTE(cc); \ - LZO_BLOCK_END -#define LZO_MEMOPS_SET3(dd,cc) \ - LZO_BLOCK_BEGIN \ - lzo_memops_set_TU1p d__3 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ - d__3[0] = LZO_BYTE(cc); d__3[1] = LZO_BYTE(cc); d__3[2] = LZO_BYTE(cc); \ - LZO_BLOCK_END -#define LZO_MEMOPS_SET4(dd,cc) \ - LZO_BLOCK_BEGIN \ - lzo_memops_set_TU1p d__4 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ - d__4[0] = LZO_BYTE(cc); d__4[1] = LZO_BYTE(cc); d__4[2] = LZO_BYTE(cc); d__4[3] = LZO_BYTE(cc); \ - LZO_BLOCK_END -#define LZO_MEMOPS_MOVE1(dd,ss) \ - LZO_BLOCK_BEGIN \ - lzo_memops_move_TU1p d__1 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ - const lzo_memops_move_TU1p s__1 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ - d__1[0] = s__1[0]; \ - LZO_BLOCK_END -#define LZO_MEMOPS_MOVE2(dd,ss) \ - LZO_BLOCK_BEGIN \ - lzo_memops_move_TU1p d__2 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ - const lzo_memops_move_TU1p s__2 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ - d__2[0] = s__2[0]; d__2[1] = s__2[1]; \ - LZO_BLOCK_END -#define LZO_MEMOPS_MOVE3(dd,ss) \ - LZO_BLOCK_BEGIN \ - lzo_memops_move_TU1p d__3 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ - const lzo_memops_move_TU1p s__3 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ - d__3[0] = s__3[0]; d__3[1] = s__3[1]; d__3[2] = s__3[2]; \ - LZO_BLOCK_END -#define LZO_MEMOPS_MOVE4(dd,ss) \ - LZO_BLOCK_BEGIN \ - lzo_memops_move_TU1p d__4 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ - const lzo_memops_move_TU1p s__4 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ - d__4[0] = s__4[0]; d__4[1] = s__4[1]; d__4[2] = s__4[2]; d__4[3] = s__4[3]; \ - LZO_BLOCK_END -#define LZO_MEMOPS_MOVE8(dd,ss) \ - LZO_BLOCK_BEGIN \ - lzo_memops_move_TU1p d__8 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ - const lzo_memops_move_TU1p s__8 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ - d__8[0] = s__8[0]; d__8[1] = s__8[1]; d__8[2] = s__8[2]; d__8[3] = s__8[3]; \ - d__8[4] = s__8[4]; d__8[5] = s__8[5]; d__8[6] = s__8[6]; d__8[7] = s__8[7]; \ - LZO_BLOCK_END -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU1p)0)==1) -#define LZO_MEMOPS_COPY1(dd,ss) LZO_MEMOPS_MOVE1(dd,ss) -#if (LZO_OPT_UNALIGNED16) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU2p)0)==2) -#define LZO_MEMOPS_COPY2(dd,ss) \ - * (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss) -#elif defined(lzo_memops_tcheck__) -#define LZO_MEMOPS_COPY2(dd,ss) \ - LZO_BLOCK_BEGIN if (lzo_memops_tcheck__(lzo_memops_TU2,2,1)) { \ - * (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss); \ - } else { LZO_MEMOPS_MOVE2(dd,ss); } LZO_BLOCK_END -#else -#define LZO_MEMOPS_COPY2(dd,ss) LZO_MEMOPS_MOVE2(dd,ss) -#endif -#if (LZO_OPT_UNALIGNED32) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU4p)0)==4) -#define LZO_MEMOPS_COPY4(dd,ss) \ - * (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss) -#elif defined(lzo_memops_tcheck__) -#define LZO_MEMOPS_COPY4(dd,ss) \ - LZO_BLOCK_BEGIN if (lzo_memops_tcheck__(lzo_memops_TU4,4,1)) { \ - * (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss); \ - } else { LZO_MEMOPS_MOVE4(dd,ss); } LZO_BLOCK_END -#else -#define LZO_MEMOPS_COPY4(dd,ss) LZO_MEMOPS_MOVE4(dd,ss) -#endif -#if (LZO_WORDSIZE != 8) -#define LZO_MEMOPS_COPY8(dd,ss) \ - LZO_BLOCK_BEGIN LZO_MEMOPS_COPY4(dd,ss); LZO_MEMOPS_COPY4((lzo_memops_TU1p)(lzo_memops_TU0p)(dd)+4,(const lzo_memops_TU1p)(const lzo_memops_TU0p)(ss)+4); LZO_BLOCK_END -#else -#if (LZO_OPT_UNALIGNED64) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU8p)0)==8) -#define LZO_MEMOPS_COPY8(dd,ss) \ - * (lzo_memops_TU8p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss) -#elif (LZO_OPT_UNALIGNED32) -#define LZO_MEMOPS_COPY8(dd,ss) \ - LZO_BLOCK_BEGIN LZO_MEMOPS_COPY4(dd,ss); LZO_MEMOPS_COPY4((lzo_memops_TU1p)(lzo_memops_TU0p)(dd)+4,(const lzo_memops_TU1p)(const lzo_memops_TU0p)(ss)+4); LZO_BLOCK_END -#elif defined(lzo_memops_tcheck__) -#define LZO_MEMOPS_COPY8(dd,ss) \ - LZO_BLOCK_BEGIN if (lzo_memops_tcheck__(lzo_memops_TU8,8,1)) { \ - * (lzo_memops_TU8p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss); \ - } else { LZO_MEMOPS_MOVE8(dd,ss); } LZO_BLOCK_END -#else -#define LZO_MEMOPS_COPY8(dd,ss) LZO_MEMOPS_MOVE8(dd,ss) -#endif -#endif -#define LZO_MEMOPS_COPYN(dd,ss,nn) \ - LZO_BLOCK_BEGIN \ - lzo_memops_TU1p d__n = (lzo_memops_TU1p) (lzo_memops_TU0p) (dd); \ - const lzo_memops_TU1p s__n = (const lzo_memops_TU1p) (const lzo_memops_TU0p) (ss); \ - lzo_uint n__n = (nn); \ - while ((void)0, n__n >= 8) { LZO_MEMOPS_COPY8(d__n, s__n); d__n += 8; s__n += 8; n__n -= 8; } \ - if ((void)0, n__n >= 4) { LZO_MEMOPS_COPY4(d__n, s__n); d__n += 4; s__n += 4; n__n -= 4; } \ - if ((void)0, n__n > 0) do { *d__n++ = *s__n++; } while (--n__n > 0); \ - LZO_BLOCK_END - -__lzo_static_forceinline lzo_uint16_t lzo_memops_get_le16(const lzo_voidp ss) -{ - lzo_uint16_t v; -#if (LZO_ABI_LITTLE_ENDIAN) - LZO_MEMOPS_COPY2(&v, ss); -#elif (LZO_OPT_UNALIGNED16 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) - const lzo_memops_TU2p s = (const lzo_memops_TU2p) ss; - unsigned long vv; - __asm__("lhbrx %0,0,%1" : "=r" (vv) : "r" (s), "m" (*s)); - v = (lzo_uint16_t) vv; -#else - const lzo_memops_TU1p s = (const lzo_memops_TU1p) ss; - v = (lzo_uint16_t) (((lzo_uint16_t)s[0]) | ((lzo_uint16_t)s[1] << 8)); -#endif - return v; -} -#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) -#define LZO_MEMOPS_GET_LE16(ss) (* (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss)) -#else -#define LZO_MEMOPS_GET_LE16(ss) lzo_memops_get_le16(ss) -#endif - -__lzo_static_forceinline lzo_uint32_t lzo_memops_get_le32(const lzo_voidp ss) -{ - lzo_uint32_t v; -#if (LZO_ABI_LITTLE_ENDIAN) - LZO_MEMOPS_COPY4(&v, ss); -#elif (LZO_OPT_UNALIGNED32 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) - const lzo_memops_TU4p s = (const lzo_memops_TU4p) ss; - unsigned long vv; - __asm__("lwbrx %0,0,%1" : "=r" (vv) : "r" (s), "m" (*s)); - v = (lzo_uint32_t) vv; -#else - const lzo_memops_TU1p s = (const lzo_memops_TU1p) ss; - v = (lzo_uint32_t) (((lzo_uint32_t)s[0]) | ((lzo_uint32_t)s[1] << 8) | ((lzo_uint32_t)s[2] << 16) | ((lzo_uint32_t)s[3] << 24)); -#endif - return v; -} -#if (LZO_OPT_UNALIGNED32) && (LZO_ABI_LITTLE_ENDIAN) -#define LZO_MEMOPS_GET_LE32(ss) (* (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss)) -#else -#define LZO_MEMOPS_GET_LE32(ss) lzo_memops_get_le32(ss) -#endif - -#if (LZO_OPT_UNALIGNED64) && (LZO_ABI_LITTLE_ENDIAN) -#define LZO_MEMOPS_GET_LE64(ss) (* (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss)) -#endif - -__lzo_static_forceinline lzo_uint16_t lzo_memops_get_ne16(const lzo_voidp ss) -{ - lzo_uint16_t v; - LZO_MEMOPS_COPY2(&v, ss); - return v; -} -#if (LZO_OPT_UNALIGNED16) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU2p)0)==2) -#define LZO_MEMOPS_GET_NE16(ss) (* (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss)) -#else -#define LZO_MEMOPS_GET_NE16(ss) lzo_memops_get_ne16(ss) -#endif - -__lzo_static_forceinline lzo_uint32_t lzo_memops_get_ne32(const lzo_voidp ss) -{ - lzo_uint32_t v; - LZO_MEMOPS_COPY4(&v, ss); - return v; -} -#if (LZO_OPT_UNALIGNED32) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU4p)0)==4) -#define LZO_MEMOPS_GET_NE32(ss) (* (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss)) -#else -#define LZO_MEMOPS_GET_NE32(ss) lzo_memops_get_ne32(ss) -#endif - -#if (LZO_OPT_UNALIGNED64) -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU8p)0)==8) -#define LZO_MEMOPS_GET_NE64(ss) (* (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss)) -#endif - -__lzo_static_forceinline void lzo_memops_put_le16(lzo_voidp dd, lzo_uint16_t vv) -{ -#if (LZO_ABI_LITTLE_ENDIAN) - LZO_MEMOPS_COPY2(dd, &vv); -#elif (LZO_OPT_UNALIGNED16 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) - lzo_memops_TU2p d = (lzo_memops_TU2p) dd; - unsigned long v = vv; - __asm__("sthbrx %2,0,%1" : "=m" (*d) : "r" (d), "r" (v)); -#else - lzo_memops_TU1p d = (lzo_memops_TU1p) dd; - d[0] = LZO_BYTE((vv ) & 0xff); - d[1] = LZO_BYTE((vv >> 8) & 0xff); -#endif -} -#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) -#define LZO_MEMOPS_PUT_LE16(dd,vv) (* (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = (vv)) -#else -#define LZO_MEMOPS_PUT_LE16(dd,vv) lzo_memops_put_le16(dd,vv) -#endif - -__lzo_static_forceinline void lzo_memops_put_le32(lzo_voidp dd, lzo_uint32_t vv) -{ -#if (LZO_ABI_LITTLE_ENDIAN) - LZO_MEMOPS_COPY4(dd, &vv); -#elif (LZO_OPT_UNALIGNED32 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) - lzo_memops_TU4p d = (lzo_memops_TU4p) dd; - unsigned long v = vv; - __asm__("stwbrx %2,0,%1" : "=m" (*d) : "r" (d), "r" (v)); -#else - lzo_memops_TU1p d = (lzo_memops_TU1p) dd; - d[0] = LZO_BYTE((vv ) & 0xff); - d[1] = LZO_BYTE((vv >> 8) & 0xff); - d[2] = LZO_BYTE((vv >> 16) & 0xff); - d[3] = LZO_BYTE((vv >> 24) & 0xff); -#endif -} -#if (LZO_OPT_UNALIGNED32) && (LZO_ABI_LITTLE_ENDIAN) -#define LZO_MEMOPS_PUT_LE32(dd,vv) (* (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = (vv)) -#else -#define LZO_MEMOPS_PUT_LE32(dd,vv) lzo_memops_put_le32(dd,vv) -#endif - -__lzo_static_forceinline void lzo_memops_put_ne16(lzo_voidp dd, lzo_uint16_t vv) -{ - LZO_MEMOPS_COPY2(dd, &vv); -} -#if (LZO_OPT_UNALIGNED16) -#define LZO_MEMOPS_PUT_NE16(dd,vv) (* (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = (vv)) -#else -#define LZO_MEMOPS_PUT_NE16(dd,vv) lzo_memops_put_ne16(dd,vv) -#endif - -__lzo_static_forceinline void lzo_memops_put_ne32(lzo_voidp dd, lzo_uint32_t vv) -{ - LZO_MEMOPS_COPY4(dd, &vv); -} -#if (LZO_OPT_UNALIGNED32) -#define LZO_MEMOPS_PUT_NE32(dd,vv) (* (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = (vv)) -#else -#define LZO_MEMOPS_PUT_NE32(dd,vv) lzo_memops_put_ne32(dd,vv) -#endif - -lzo_unused_funcs_impl(void, lzo_memops_unused_funcs)(void) -{ - LZO_UNUSED_FUNC(lzo_memops_unused_funcs); - LZO_UNUSED_FUNC(lzo_memops_get_le16); - LZO_UNUSED_FUNC(lzo_memops_get_le32); - LZO_UNUSED_FUNC(lzo_memops_get_ne16); - LZO_UNUSED_FUNC(lzo_memops_get_ne32); - LZO_UNUSED_FUNC(lzo_memops_put_le16); - LZO_UNUSED_FUNC(lzo_memops_put_le32); - LZO_UNUSED_FUNC(lzo_memops_put_ne16); - LZO_UNUSED_FUNC(lzo_memops_put_ne32); -} - -#endif - -#ifndef UA_SET1 -#define UA_SET1 LZO_MEMOPS_SET1 -#endif -#ifndef UA_SET2 -#define UA_SET2 LZO_MEMOPS_SET2 -#endif -#ifndef UA_SET3 -#define UA_SET3 LZO_MEMOPS_SET3 -#endif -#ifndef UA_SET4 -#define UA_SET4 LZO_MEMOPS_SET4 -#endif -#ifndef UA_MOVE1 -#define UA_MOVE1 LZO_MEMOPS_MOVE1 -#endif -#ifndef UA_MOVE2 -#define UA_MOVE2 LZO_MEMOPS_MOVE2 -#endif -#ifndef UA_MOVE3 -#define UA_MOVE3 LZO_MEMOPS_MOVE3 -#endif -#ifndef UA_MOVE4 -#define UA_MOVE4 LZO_MEMOPS_MOVE4 -#endif -#ifndef UA_MOVE8 -#define UA_MOVE8 LZO_MEMOPS_MOVE8 -#endif -#ifndef UA_COPY1 -#define UA_COPY1 LZO_MEMOPS_COPY1 -#endif -#ifndef UA_COPY2 -#define UA_COPY2 LZO_MEMOPS_COPY2 -#endif -#ifndef UA_COPY3 -#define UA_COPY3 LZO_MEMOPS_COPY3 -#endif -#ifndef UA_COPY4 -#define UA_COPY4 LZO_MEMOPS_COPY4 -#endif -#ifndef UA_COPY8 -#define UA_COPY8 LZO_MEMOPS_COPY8 -#endif -#ifndef UA_COPYN -#define UA_COPYN LZO_MEMOPS_COPYN -#endif -#ifndef UA_COPYN_X -#define UA_COPYN_X LZO_MEMOPS_COPYN -#endif -#ifndef UA_GET_LE16 -#define UA_GET_LE16 LZO_MEMOPS_GET_LE16 -#endif -#ifndef UA_GET_LE32 -#define UA_GET_LE32 LZO_MEMOPS_GET_LE32 -#endif -#ifdef LZO_MEMOPS_GET_LE64 -#ifndef UA_GET_LE64 -#define UA_GET_LE64 LZO_MEMOPS_GET_LE64 -#endif -#endif -#ifndef UA_GET_NE16 -#define UA_GET_NE16 LZO_MEMOPS_GET_NE16 -#endif -#ifndef UA_GET_NE32 -#define UA_GET_NE32 LZO_MEMOPS_GET_NE32 -#endif -#ifdef LZO_MEMOPS_GET_NE64 -#ifndef UA_GET_NE64 -#define UA_GET_NE64 LZO_MEMOPS_GET_NE64 -#endif -#endif -#ifndef UA_PUT_LE16 -#define UA_PUT_LE16 LZO_MEMOPS_PUT_LE16 -#endif -#ifndef UA_PUT_LE32 -#define UA_PUT_LE32 LZO_MEMOPS_PUT_LE32 -#endif -#ifndef UA_PUT_NE16 -#define UA_PUT_NE16 LZO_MEMOPS_PUT_NE16 -#endif -#ifndef UA_PUT_NE32 -#define UA_PUT_NE32 LZO_MEMOPS_PUT_NE32 -#endif - -#define MEMCPY8_DS(dest,src,len) \ - lzo_memcpy(dest,src,len); dest += len; src += len - -#define BZERO8_PTR(s,l,n) \ - lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n)) - -#define MEMCPY_DS(dest,src,len) \ - do *dest++ = *src++; while (--len > 0) - -LZO_EXTERN(const lzo_bytep) lzo_copyright(void); - -#ifndef __LZO_PTR_H -#define __LZO_PTR_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#if (LZO_ARCH_I086) -#error "LZO_ARCH_I086 is unsupported" -#elif (LZO_MM_PVP) -#error "LZO_MM_PVP is unsupported" -#else -#define PTR(a) ((lzo_uintptr_t) (a)) -#define PTR_LINEAR(a) PTR(a) -#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0) -#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0) -#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0) -#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0) -#endif - -#define PTR_LT(a,b) (PTR(a) < PTR(b)) -#define PTR_GE(a,b) (PTR(a) >= PTR(b)) -#define PTR_DIFF(a,b) (PTR(a) - PTR(b)) -#define pd(a,b) ((lzo_uint) ((a)-(b))) - -LZO_EXTERN(lzo_uintptr_t) -__lzo_ptr_linear(const lzo_voidp ptr); - -typedef union -{ - char a_char; - unsigned char a_uchar; - short a_short; - unsigned short a_ushort; - int a_int; - unsigned int a_uint; - long a_long; - unsigned long a_ulong; - lzo_int a_lzo_int; - lzo_uint a_lzo_uint; - lzo_xint a_lzo_xint; - lzo_int16_t a_lzo_int16_t; - lzo_uint16_t a_lzo_uint16_t; - lzo_int32_t a_lzo_int32_t; - lzo_uint32_t a_lzo_uint32_t; -#if defined(lzo_uint64_t) - lzo_int64_t a_lzo_int64_t; - lzo_uint64_t a_lzo_uint64_t; -#endif - size_t a_size_t; - ptrdiff_t a_ptrdiff_t; - lzo_uintptr_t a_lzo_uintptr_t; - void * a_void_p; - char * a_char_p; - unsigned char * a_uchar_p; - const void * a_c_void_p; - const char * a_c_char_p; - const unsigned char * a_c_uchar_p; - lzo_voidp a_lzo_voidp; - lzo_bytep a_lzo_bytep; - const lzo_voidp a_c_lzo_voidp; - const lzo_bytep a_c_lzo_bytep; -} -lzo_full_align_t; - -#ifdef __cplusplus -} -#endif - -#endif - -#ifndef LZO_DETERMINISTIC -#define LZO_DETERMINISTIC 1 -#endif - -#ifndef LZO_DICT_USE_PTR -#define LZO_DICT_USE_PTR 1 -#endif - -#if (LZO_DICT_USE_PTR) -# define lzo_dict_t const lzo_bytep -# define lzo_dict_p lzo_dict_t * -#else -# define lzo_dict_t lzo_uint -# define lzo_dict_p lzo_dict_t * -#endif - -#endif - -#if !defined(MINILZO_CFG_SKIP_LZO_PTR) - -LZO_PUBLIC(lzo_uintptr_t) -__lzo_ptr_linear(const lzo_voidp ptr) -{ - lzo_uintptr_t p; - -#if (LZO_ARCH_I086) -#error "LZO_ARCH_I086 is unsupported" -#elif (LZO_MM_PVP) -#error "LZO_MM_PVP is unsupported" -#else - p = (lzo_uintptr_t) PTR_LINEAR(ptr); -#endif - - return p; -} - -LZO_PUBLIC(unsigned) -__lzo_align_gap(const lzo_voidp ptr, lzo_uint size) -{ -#if (__LZO_UINTPTR_T_IS_POINTER) -#error "__LZO_UINTPTR_T_IS_POINTER is unsupported" -#else - lzo_uintptr_t p, n; - if (size < 2) return 0; - p = __lzo_ptr_linear(ptr); -#if 0 - n = (((p + size - 1) / size) * size) - p; -#else - if ((size & (size - 1)) != 0) - return 0; - n = size; n = ((p + n - 1) & ~(n - 1)) - p; -#endif -#endif - assert((long)n >= 0); - assert(n <= size); - return (unsigned)n; -} - -#endif -#if !defined(MINILZO_CFG_SKIP_LZO_UTIL) - -/* If you use the LZO library in a product, I would appreciate that you - * keep this copyright string in the executable of your product. - */ - -static const char lzo_copyright_[] = -#if !defined(__LZO_IN_MINLZO) - LZO_VERSION_STRING; -#else - "\r\n\n" - "LZO data compression library.\n" - "$Copyright: LZO Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer\n" - "\n" - "http://www.oberhumer.com $\n\n" - "$Id: LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE " $\n" - "$Info: " LZO_INFO_STRING " $\n"; -#endif -static const char lzo_version_string_[] = LZO_VERSION_STRING; -static const char lzo_version_date_[] = LZO_VERSION_DATE; - -LZO_PUBLIC(const lzo_bytep) -lzo_copyright(void) -{ - return (const lzo_bytep) lzo_copyright_; -} - -LZO_PUBLIC(unsigned) -lzo_version(void) -{ - return LZO_VERSION; -} - -LZO_PUBLIC(const char *) -lzo_version_string(void) -{ - return lzo_version_string_; -} - -LZO_PUBLIC(const char *) -lzo_version_date(void) -{ - return lzo_version_date_; -} - -LZO_PUBLIC(const lzo_charp) -_lzo_version_string(void) -{ - return lzo_version_string_; -} - -LZO_PUBLIC(const lzo_charp) -_lzo_version_date(void) -{ - return lzo_version_date_; -} - -#define LZO_BASE 65521u -#define LZO_NMAX 5552 - -#define LZO_DO1(buf,i) s1 += buf[i]; s2 += s1 -#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1) -#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2) -#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4) -#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8) - -LZO_PUBLIC(lzo_uint32_t) -lzo_adler32(lzo_uint32_t adler, const lzo_bytep buf, lzo_uint len) -{ - lzo_uint32_t s1 = adler & 0xffff; - lzo_uint32_t s2 = (adler >> 16) & 0xffff; - unsigned k; - - if (buf == NULL) - return 1; - - while (len > 0) - { - k = len < LZO_NMAX ? (unsigned) len : LZO_NMAX; - len -= k; - if (k >= 16) do - { - LZO_DO16(buf,0); - buf += 16; - k -= 16; - } while (k >= 16); - if (k != 0) do - { - s1 += *buf++; - s2 += s1; - } while (--k > 0); - s1 %= LZO_BASE; - s2 %= LZO_BASE; - } - return (s2 << 16) | s1; -} - -#undef LZO_DO1 -#undef LZO_DO2 -#undef LZO_DO4 -#undef LZO_DO8 -#undef LZO_DO16 - -#endif -#if !defined(MINILZO_CFG_SKIP_LZO_STRING) -#undef lzo_memcmp -#undef lzo_memcpy -#undef lzo_memmove -#undef lzo_memset -#if !defined(__LZO_MMODEL_HUGE) -# undef LZO_HAVE_MM_HUGE_PTR -#endif -#define lzo_hsize_t lzo_uint -#define lzo_hvoid_p lzo_voidp -#define lzo_hbyte_p lzo_bytep -#define LZOLIB_PUBLIC(r,f) LZO_PUBLIC(r) f -#define lzo_hmemcmp lzo_memcmp -#define lzo_hmemcpy lzo_memcpy -#define lzo_hmemmove lzo_memmove -#define lzo_hmemset lzo_memset -#define __LZOLIB_HMEMCPY_CH_INCLUDED 1 -#if !defined(LZOLIB_PUBLIC) -# define LZOLIB_PUBLIC(r,f) r __LZOLIB_FUNCNAME(f) -#endif -LZOLIB_PUBLIC(int, lzo_hmemcmp) (const lzo_hvoid_p s1, const lzo_hvoid_p s2, lzo_hsize_t len) -{ -#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCMP) - const lzo_hbyte_p p1 = LZO_STATIC_CAST(const lzo_hbyte_p, s1); - const lzo_hbyte_p p2 = LZO_STATIC_CAST(const lzo_hbyte_p, s2); - if __lzo_likely(len > 0) do - { - int d = *p1 - *p2; - if (d != 0) - return d; - p1++; p2++; - } while __lzo_likely(--len > 0); - return 0; -#else - return memcmp(s1, s2, len); -#endif -} -LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemcpy) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) -{ -#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCPY) - lzo_hbyte_p p1 = LZO_STATIC_CAST(lzo_hbyte_p, dest); - const lzo_hbyte_p p2 = LZO_STATIC_CAST(const lzo_hbyte_p, src); - if (!(len > 0) || p1 == p2) - return dest; - do - *p1++ = *p2++; - while __lzo_likely(--len > 0); - return dest; -#else - return memcpy(dest, src, len); -#endif -} -LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemmove) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) -{ -#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMMOVE) - lzo_hbyte_p p1 = LZO_STATIC_CAST(lzo_hbyte_p, dest); - const lzo_hbyte_p p2 = LZO_STATIC_CAST(const lzo_hbyte_p, src); - if (!(len > 0) || p1 == p2) - return dest; - if (p1 < p2) - { - do - *p1++ = *p2++; - while __lzo_likely(--len > 0); - } - else - { - p1 += len; - p2 += len; - do - *--p1 = *--p2; - while __lzo_likely(--len > 0); - } - return dest; -#else - return memmove(dest, src, len); -#endif -} -LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int cc, lzo_hsize_t len) -{ -#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMSET) - lzo_hbyte_p p = LZO_STATIC_CAST(lzo_hbyte_p, s); - unsigned char c = LZO_ITRUNC(unsigned char, cc); - if __lzo_likely(len > 0) do - *p++ = c; - while __lzo_likely(--len > 0); - return s; -#else - return memset(s, cc, len); -#endif -} -#undef LZOLIB_PUBLIC -#endif -#if !defined(MINILZO_CFG_SKIP_LZO_INIT) - -#if !defined(__LZO_IN_MINILZO) - -#define LZO_WANT_ACC_CHK_CH 1 -#undef LZOCHK_ASSERT - - LZOCHK_ASSERT((LZO_UINT32_C(1) << (int)(8*sizeof(LZO_UINT32_C(1))-1)) > 0) - LZOCHK_ASSERT_IS_SIGNED_T(lzo_int) - LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_uint) -#if !(__LZO_UINTPTR_T_IS_POINTER) - LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_uintptr_t) -#endif - LZOCHK_ASSERT(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) - LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_xint) - -#endif -#undef LZOCHK_ASSERT - -union lzo_config_check_union { - lzo_uint a[2]; - unsigned char b[2*LZO_MAX(8,sizeof(lzo_uint))]; -#if defined(lzo_uint64_t) - lzo_uint64_t c[2]; -#endif -}; - -#if 0 -#define u2p(ptr,off) ((lzo_voidp) (((lzo_bytep)(lzo_voidp)(ptr)) + (off))) -#else -static __lzo_noinline lzo_voidp u2p(lzo_voidp ptr, lzo_uint off) -{ - return (lzo_voidp) ((lzo_bytep) ptr + off); -} -#endif - -LZO_PUBLIC(int) -_lzo_config_check(void) -{ -#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030100ul && LZO_CC_CLANG < 0x030300ul)) -# if 0 - volatile -# endif -#endif - union lzo_config_check_union u; - lzo_voidp p; - unsigned r = 1; - - u.a[0] = u.a[1] = 0; - p = u2p(&u, 0); - r &= ((* (lzo_bytep) p) == 0); -#if !(LZO_CFG_NO_CONFIG_CHECK) -#if (LZO_ABI_BIG_ENDIAN) - u.a[0] = u.a[1] = 0; u.b[sizeof(lzo_uint) - 1] = 128; - p = u2p(&u, 0); - r &= ((* (lzo_uintp) p) == 128); -#endif -#if (LZO_ABI_LITTLE_ENDIAN) - u.a[0] = u.a[1] = 0; u.b[0] = 128; - p = u2p(&u, 0); - r &= ((* (lzo_uintp) p) == 128); -#endif - u.a[0] = u.a[1] = 0; - u.b[0] = 1; u.b[3] = 2; - p = u2p(&u, 1); - r &= UA_GET_NE16(p) == 0; - r &= UA_GET_LE16(p) == 0; - u.b[1] = 128; - r &= UA_GET_LE16(p) == 128; - u.b[2] = 129; - r &= UA_GET_LE16(p) == LZO_UINT16_C(0x8180); -#if (LZO_ABI_BIG_ENDIAN) - r &= UA_GET_NE16(p) == LZO_UINT16_C(0x8081); -#endif -#if (LZO_ABI_LITTLE_ENDIAN) - r &= UA_GET_NE16(p) == LZO_UINT16_C(0x8180); -#endif - u.a[0] = u.a[1] = 0; - u.b[0] = 3; u.b[5] = 4; - p = u2p(&u, 1); - r &= UA_GET_NE32(p) == 0; - r &= UA_GET_LE32(p) == 0; - u.b[1] = 128; - r &= UA_GET_LE32(p) == 128; - u.b[2] = 129; u.b[3] = 130; u.b[4] = 131; - r &= UA_GET_LE32(p) == LZO_UINT32_C(0x83828180); -#if (LZO_ABI_BIG_ENDIAN) - r &= UA_GET_NE32(p) == LZO_UINT32_C(0x80818283); -#endif -#if (LZO_ABI_LITTLE_ENDIAN) - r &= UA_GET_NE32(p) == LZO_UINT32_C(0x83828180); -#endif -#if defined(UA_GET_NE64) - u.c[0] = u.c[1] = 0; - u.b[0] = 5; u.b[9] = 6; - p = u2p(&u, 1); - u.c[0] = u.c[1] = 0; - r &= UA_GET_NE64(p) == 0; -#if defined(UA_GET_LE64) - r &= UA_GET_LE64(p) == 0; - u.b[1] = 128; - r &= UA_GET_LE64(p) == 128; -#endif -#endif -#if defined(lzo_bitops_ctlz32) - { unsigned i = 0; lzo_uint32_t v; - for (v = 1; v != 0 && r == 1; v <<= 1, i++) { - r &= lzo_bitops_ctlz32(v) == 31 - i; - r &= lzo_bitops_ctlz32_func(v) == 31 - i; - }} -#endif -#if defined(lzo_bitops_ctlz64) - { unsigned i = 0; lzo_uint64_t v; - for (v = 1; v != 0 && r == 1; v <<= 1, i++) { - r &= lzo_bitops_ctlz64(v) == 63 - i; - r &= lzo_bitops_ctlz64_func(v) == 63 - i; - }} -#endif -#if defined(lzo_bitops_cttz32) - { unsigned i = 0; lzo_uint32_t v; - for (v = 1; v != 0 && r == 1; v <<= 1, i++) { - r &= lzo_bitops_cttz32(v) == i; - r &= lzo_bitops_cttz32_func(v) == i; - }} -#endif -#if defined(lzo_bitops_cttz64) - { unsigned i = 0; lzo_uint64_t v; - for (v = 1; v != 0 && r == 1; v <<= 1, i++) { - r &= lzo_bitops_cttz64(v) == i; - r &= lzo_bitops_cttz64_func(v) == i; - }} -#endif -#endif - LZO_UNUSED_FUNC(lzo_bitops_unused_funcs); - - return r == 1 ? LZO_E_OK : LZO_E_ERROR; -} - -LZO_PUBLIC(int) -__lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5, - int s6, int s7, int s8, int s9) -{ - int r; - -#if defined(__LZO_IN_MINILZO) -#elif (LZO_CC_MSC && ((_MSC_VER) < 700)) -#else -#define LZO_WANT_ACC_CHK_CH 1 -#undef LZOCHK_ASSERT -#define LZOCHK_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr) -#endif -#undef LZOCHK_ASSERT - - if (v == 0) - return LZO_E_ERROR; - - r = (s1 == -1 || s1 == (int) sizeof(short)) && - (s2 == -1 || s2 == (int) sizeof(int)) && - (s3 == -1 || s3 == (int) sizeof(long)) && - (s4 == -1 || s4 == (int) sizeof(lzo_uint32_t)) && - (s5 == -1 || s5 == (int) sizeof(lzo_uint)) && - (s6 == -1 || s6 == (int) lzo_sizeof_dict_t) && - (s7 == -1 || s7 == (int) sizeof(char *)) && - (s8 == -1 || s8 == (int) sizeof(lzo_voidp)) && - (s9 == -1 || s9 == (int) sizeof(lzo_callback_t)); - if (!r) - return LZO_E_ERROR; - - r = _lzo_config_check(); - if (r != LZO_E_OK) - return r; - - return r; -} - -#if !defined(__LZO_IN_MINILZO) - -#if (LZO_OS_WIN16 && LZO_CC_WATCOMC) && defined(__SW_BD) - -#if 0 -BOOL FAR PASCAL LibMain ( HANDLE hInstance, WORD wDataSegment, - WORD wHeapSize, LPSTR lpszCmdLine ) -#else -int __far __pascal LibMain ( int a, short b, short c, long d ) -#endif -{ - LZO_UNUSED(a); LZO_UNUSED(b); LZO_UNUSED(c); LZO_UNUSED(d); - return 1; -} - -#endif - -#endif - -#endif - -#define LZO1X 1 -#define LZO_EOF_CODE 1 -#define M2_MAX_OFFSET 0x0800 - -#if !defined(MINILZO_CFG_SKIP_LZO1X_1_COMPRESS) - -#if 1 && defined(UA_GET_LE32) -#undef LZO_DICT_USE_PTR -#define LZO_DICT_USE_PTR 0 -#undef lzo_dict_t -#define lzo_dict_t lzo_uint16_t -#endif - -#define LZO_NEED_DICT_H 1 -#ifndef D_BITS -#define D_BITS 14 -#endif -#define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5) -#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) -#if 1 -#define DINDEX(dv,p) DM(((DMUL(0x1824429d,dv)) >> (32-D_BITS))) -#else -#define DINDEX(dv,p) DM((dv) + ((dv) >> (32-D_BITS))) -#endif - -#ifndef __LZO_CONFIG1X_H -#define __LZO_CONFIG1X_H 1 - -#if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z) -# define LZO1X 1 -#endif - -#if !defined(__LZO_IN_MINILZO) -#include -#endif - -#ifndef LZO_EOF_CODE -#define LZO_EOF_CODE 1 -#endif -#undef LZO_DETERMINISTIC - -#define M1_MAX_OFFSET 0x0400 -#ifndef M2_MAX_OFFSET -#define M2_MAX_OFFSET 0x0800 -#endif -#define M3_MAX_OFFSET 0x4000 -#define M4_MAX_OFFSET 0xbfff - -#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET) - -#define M1_MIN_LEN 2 -#define M1_MAX_LEN 2 -#define M2_MIN_LEN 3 -#ifndef M2_MAX_LEN -#define M2_MAX_LEN 8 -#endif -#define M3_MIN_LEN 3 -#define M3_MAX_LEN 33 -#define M4_MIN_LEN 3 -#define M4_MAX_LEN 9 - -#define M1_MARKER 0 -#define M2_MARKER 64 -#define M3_MARKER 32 -#define M4_MARKER 16 - -#ifndef MIN_LOOKAHEAD -#define MIN_LOOKAHEAD (M2_MAX_LEN + 1) -#endif - -#if defined(LZO_NEED_DICT_H) - -#ifndef LZO_HASH -#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B -#endif -#define DL_MIN_LEN M2_MIN_LEN - -#ifndef __LZO_DICT_H -#define __LZO_DICT_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined(D_BITS) && defined(DBITS) -# define D_BITS DBITS -#endif -#if !defined(D_BITS) -# error "D_BITS is not defined" -#endif -#if (D_BITS < 16) -# define D_SIZE LZO_SIZE(D_BITS) -# define D_MASK LZO_MASK(D_BITS) -#else -# define D_SIZE LZO_USIZE(D_BITS) -# define D_MASK LZO_UMASK(D_BITS) -#endif -#define D_HIGH ((D_MASK >> 1) + 1) - -#if !defined(DD_BITS) -# define DD_BITS 0 -#endif -#define DD_SIZE LZO_SIZE(DD_BITS) -#define DD_MASK LZO_MASK(DD_BITS) - -#if !defined(DL_BITS) -# define DL_BITS (D_BITS - DD_BITS) -#endif -#if (DL_BITS < 16) -# define DL_SIZE LZO_SIZE(DL_BITS) -# define DL_MASK LZO_MASK(DL_BITS) -#else -# define DL_SIZE LZO_USIZE(DL_BITS) -# define DL_MASK LZO_UMASK(DL_BITS) -#endif - -#if (D_BITS != DL_BITS + DD_BITS) -# error "D_BITS does not match" -#endif -#if (D_BITS < 6 || D_BITS > 18) -# error "invalid D_BITS" -#endif -#if (DL_BITS < 6 || DL_BITS > 20) -# error "invalid DL_BITS" -#endif -#if (DD_BITS < 0 || DD_BITS > 6) -# error "invalid DD_BITS" -#endif - -#if !defined(DL_MIN_LEN) -# define DL_MIN_LEN 3 -#endif -#if !defined(DL_SHIFT) -# define DL_SHIFT ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN) -#endif - -#define LZO_HASH_GZIP 1 -#define LZO_HASH_GZIP_INCREMENTAL 2 -#define LZO_HASH_LZO_INCREMENTAL_A 3 -#define LZO_HASH_LZO_INCREMENTAL_B 4 - -#if !defined(LZO_HASH) -# error "choose a hashing strategy" -#endif - -#undef DM -#undef DX - -#if (DL_MIN_LEN == 3) -# define _DV2_A(p,shift1,shift2) \ - (((( (lzo_xint)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2]) -# define _DV2_B(p,shift1,shift2) \ - (((( (lzo_xint)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0]) -# define _DV3_B(p,shift1,shift2,shift3) \ - ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0]) -#elif (DL_MIN_LEN == 2) -# define _DV2_A(p,shift1,shift2) \ - (( (lzo_xint)(p[0]) << shift1) ^ p[1]) -# define _DV2_B(p,shift1,shift2) \ - (( (lzo_xint)(p[1]) << shift1) ^ p[2]) -#else -# error "invalid DL_MIN_LEN" -#endif -#define _DV_A(p,shift) _DV2_A(p,shift,shift) -#define _DV_B(p,shift) _DV2_B(p,shift,shift) -#define DA2(p,s1,s2) \ - (((((lzo_xint)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0]) -#define DS2(p,s1,s2) \ - (((((lzo_xint)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0]) -#define DX2(p,s1,s2) \ - (((((lzo_xint)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0]) -#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0]) -#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0]) -#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0]) -#define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s))) -#define DM(v) DMS(v,0) - -#if (LZO_HASH == LZO_HASH_GZIP) -# define _DINDEX(dv,p) (_DV_A((p),DL_SHIFT)) - -#elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL) -# define __LZO_HASH_INCREMENTAL 1 -# define DVAL_FIRST(dv,p) dv = _DV_A((p),DL_SHIFT) -# define DVAL_NEXT(dv,p) dv = (((dv) << DL_SHIFT) ^ p[2]) -# define _DINDEX(dv,p) (dv) -# define DVAL_LOOKAHEAD DL_MIN_LEN - -#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A) -# define __LZO_HASH_INCREMENTAL 1 -# define DVAL_FIRST(dv,p) dv = _DV_A((p),5) -# define DVAL_NEXT(dv,p) \ - dv ^= (lzo_xint)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2]) -# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) -# define DVAL_LOOKAHEAD DL_MIN_LEN - -#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B) -# define __LZO_HASH_INCREMENTAL 1 -# define DVAL_FIRST(dv,p) dv = _DV_B((p),5) -# define DVAL_NEXT(dv,p) \ - dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_xint)(p[2]) << (2*5))) -# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) -# define DVAL_LOOKAHEAD DL_MIN_LEN - -#else -# error "choose a hashing strategy" -#endif - -#ifndef DINDEX -#define DINDEX(dv,p) ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS) -#endif -#if !defined(DINDEX1) && defined(D_INDEX1) -#define DINDEX1 D_INDEX1 -#endif -#if !defined(DINDEX2) && defined(D_INDEX2) -#define DINDEX2 D_INDEX2 -#endif - -#if !defined(__LZO_HASH_INCREMENTAL) -# define DVAL_FIRST(dv,p) ((void) 0) -# define DVAL_NEXT(dv,p) ((void) 0) -# define DVAL_LOOKAHEAD 0 -#endif - -#if !defined(DVAL_ASSERT) -#if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG) -#if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) -static void __attribute__((__unused__)) -#else -static void -#endif -DVAL_ASSERT(lzo_xint dv, const lzo_bytep p) -{ - lzo_xint df; - DVAL_FIRST(df,(p)); - assert(DINDEX(dv,p) == DINDEX(df,p)); -} -#else -# define DVAL_ASSERT(dv,p) ((void) 0) -#endif -#endif - -#if (LZO_DICT_USE_PTR) -# define DENTRY(p,in) (p) -# define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex] -#else -# define DENTRY(p,in) ((lzo_dict_t) pd(p, in)) -# define GINDEX(m_pos,m_off,dict,dindex,in) m_off = dict[dindex] -#endif - -#if (DD_BITS == 0) - -# define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in) -# define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in) -# define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in) - -#else - -# define UPDATE_D(dict,drun,dv,p,in) \ - dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK -# define UPDATE_I(dict,drun,index,p,in) \ - dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK -# define UPDATE_P(ptr,drun,p,in) \ - (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK - -#endif - -#if (LZO_DICT_USE_PTR) - -#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ - (m_pos == NULL || (m_off = pd(ip, m_pos)) > max_offset) - -#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ - (BOUNDS_CHECKING_OFF_IN_EXPR(( \ - m_pos = ip - (lzo_uint) PTR_DIFF(ip,m_pos), \ - PTR_LT(m_pos,in) || \ - (m_off = (lzo_uint) PTR_DIFF(ip,m_pos)) == 0 || \ - m_off > max_offset ))) - -#else - -#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ - (m_off == 0 || \ - ((m_off = pd(ip, in) - m_off) > max_offset) || \ - (m_pos = (ip) - (m_off), 0) ) - -#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ - (pd(ip, in) <= m_off || \ - ((m_off = pd(ip, in) - m_off) > max_offset) || \ - (m_pos = (ip) - (m_off), 0) ) - -#endif - -#if (LZO_DETERMINISTIC) -# define LZO_CHECK_MPOS LZO_CHECK_MPOS_DET -#else -# define LZO_CHECK_MPOS LZO_CHECK_MPOS_NON_DET -#endif - -#ifdef __cplusplus -} -#endif - -#endif - -#endif - -#endif - -#define LZO_DETERMINISTIC !(LZO_DICT_USE_PTR) - -#ifndef DO_COMPRESS -#define DO_COMPRESS lzo1x_1_compress -#endif - -#if 1 && defined(DO_COMPRESS) && !defined(do_compress) -# define do_compress LZO_PP_ECONCAT2(DO_COMPRESS,_core) -#endif - -static __lzo_noinline lzo_uint -do_compress ( const lzo_bytep in , lzo_uint in_len, - lzo_bytep out, lzo_uintp out_len, - lzo_uint ti, lzo_voidp wrkmem) -{ - const lzo_bytep ip; - lzo_bytep op; - const lzo_bytep const in_end = in + in_len; - const lzo_bytep const ip_end = in + in_len - 20; - const lzo_bytep ii; - lzo_dict_p const dict = (lzo_dict_p) wrkmem; - - op = out; - ip = in; - ii = ip; - - ip += ti < 4 ? 4 - ti : 0; - for (;;) - { - const lzo_bytep m_pos; -#if !(LZO_DETERMINISTIC) - LZO_DEFINE_UNINITIALIZED_VAR(lzo_uint, m_off, 0); - lzo_uint m_len; - lzo_uint dindex; -next: - if __lzo_unlikely(ip >= ip_end) - break; - DINDEX1(dindex,ip); - GINDEX(m_pos,m_off,dict,dindex,in); - if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) - goto literal; -#if 1 - if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) - goto try_match; - DINDEX2(dindex,ip); -#endif - GINDEX(m_pos,m_off,dict,dindex,in); - if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) - goto literal; - if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) - goto try_match; - goto literal; - -try_match: -#if (LZO_OPT_UNALIGNED32) - if (UA_GET_NE32(m_pos) != UA_GET_NE32(ip)) -#else - if (m_pos[0] != ip[0] || m_pos[1] != ip[1] || m_pos[2] != ip[2] || m_pos[3] != ip[3]) -#endif - { -literal: - UPDATE_I(dict,0,dindex,ip,in); - ip += 1 + ((ip - ii) >> 5); - continue; - } - UPDATE_I(dict,0,dindex,ip,in); -#else - lzo_uint m_off; - lzo_uint m_len; - { - lzo_uint32_t dv; - lzo_uint dindex; -literal: - ip += 1 + ((ip - ii) >> 5); -next: - if __lzo_unlikely(ip >= ip_end) - break; - dv = UA_GET_LE32(ip); - dindex = DINDEX(dv,ip); - GINDEX(m_off,m_pos,in+dict,dindex,in); - UPDATE_I(dict,0,dindex,ip,in); - if __lzo_unlikely(dv != UA_GET_LE32(m_pos)) - goto literal; - } -#endif - - ii -= ti; ti = 0; - { - lzo_uint t = pd(ip,ii); - if (t != 0) - { - if (t <= 3) - { - op[-2] = LZO_BYTE(op[-2] | t); -#if (LZO_OPT_UNALIGNED32) - UA_COPY4(op, ii); - op += t; -#else - { do *op++ = *ii++; while (--t > 0); } -#endif - } -#if (LZO_OPT_UNALIGNED32) || (LZO_OPT_UNALIGNED64) - else if (t <= 16) - { - *op++ = LZO_BYTE(t - 3); - UA_COPY8(op, ii); - UA_COPY8(op+8, ii+8); - op += t; - } -#endif - else - { - if (t <= 18) - *op++ = LZO_BYTE(t - 3); - else - { - lzo_uint tt = t - 18; - *op++ = 0; - while __lzo_unlikely(tt > 255) - { - tt -= 255; - UA_SET1(op, 0); - op++; - } - assert(tt > 0); - *op++ = LZO_BYTE(tt); - } -#if (LZO_OPT_UNALIGNED32) || (LZO_OPT_UNALIGNED64) - do { - UA_COPY8(op, ii); - UA_COPY8(op+8, ii+8); - op += 16; ii += 16; t -= 16; - } while (t >= 16); if (t > 0) -#endif - { do *op++ = *ii++; while (--t > 0); } - } - } - } - m_len = 4; - { -#if (LZO_OPT_UNALIGNED64) - lzo_uint64_t v; - v = UA_GET_NE64(ip + m_len) ^ UA_GET_NE64(m_pos + m_len); - if __lzo_unlikely(v == 0) { - do { - m_len += 8; - v = UA_GET_NE64(ip + m_len) ^ UA_GET_NE64(m_pos + m_len); - if __lzo_unlikely(ip + m_len >= ip_end) - goto m_len_done; - } while (v == 0); - } -#if (LZO_ABI_BIG_ENDIAN) && defined(lzo_bitops_ctlz64) - m_len += lzo_bitops_ctlz64(v) / CHAR_BIT; -#elif (LZO_ABI_BIG_ENDIAN) - if ((v >> (64 - CHAR_BIT)) == 0) do { - v <<= CHAR_BIT; - m_len += 1; - } while ((v >> (64 - CHAR_BIT)) == 0); -#elif (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_cttz64) - m_len += lzo_bitops_cttz64(v) / CHAR_BIT; -#elif (LZO_ABI_LITTLE_ENDIAN) - if ((v & UCHAR_MAX) == 0) do { - v >>= CHAR_BIT; - m_len += 1; - } while ((v & UCHAR_MAX) == 0); -#else - if (ip[m_len] == m_pos[m_len]) do { - m_len += 1; - } while (ip[m_len] == m_pos[m_len]); -#endif -#elif (LZO_OPT_UNALIGNED32) - lzo_uint32_t v; - v = UA_GET_NE32(ip + m_len) ^ UA_GET_NE32(m_pos + m_len); - if __lzo_unlikely(v == 0) { - do { - m_len += 4; - v = UA_GET_NE32(ip + m_len) ^ UA_GET_NE32(m_pos + m_len); - if (v != 0) - break; - m_len += 4; - v = UA_GET_NE32(ip + m_len) ^ UA_GET_NE32(m_pos + m_len); - if __lzo_unlikely(ip + m_len >= ip_end) - goto m_len_done; - } while (v == 0); - } -#if (LZO_ABI_BIG_ENDIAN) && defined(lzo_bitops_ctlz32) - m_len += lzo_bitops_ctlz32(v) / CHAR_BIT; -#elif (LZO_ABI_BIG_ENDIAN) - if ((v >> (32 - CHAR_BIT)) == 0) do { - v <<= CHAR_BIT; - m_len += 1; - } while ((v >> (32 - CHAR_BIT)) == 0); -#elif (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_cttz32) - m_len += lzo_bitops_cttz32(v) / CHAR_BIT; -#elif (LZO_ABI_LITTLE_ENDIAN) - if ((v & UCHAR_MAX) == 0) do { - v >>= CHAR_BIT; - m_len += 1; - } while ((v & UCHAR_MAX) == 0); -#else - if (ip[m_len] == m_pos[m_len]) do { - m_len += 1; - } while (ip[m_len] == m_pos[m_len]); -#endif -#else - if __lzo_unlikely(ip[m_len] == m_pos[m_len]) { - do { - m_len += 1; - if (ip[m_len] != m_pos[m_len]) - break; - m_len += 1; - if (ip[m_len] != m_pos[m_len]) - break; - m_len += 1; - if (ip[m_len] != m_pos[m_len]) - break; - m_len += 1; - if (ip[m_len] != m_pos[m_len]) - break; - m_len += 1; - if (ip[m_len] != m_pos[m_len]) - break; - m_len += 1; - if (ip[m_len] != m_pos[m_len]) - break; - m_len += 1; - if (ip[m_len] != m_pos[m_len]) - break; - m_len += 1; - if __lzo_unlikely(ip + m_len >= ip_end) - goto m_len_done; - } while (ip[m_len] == m_pos[m_len]); - } -#endif - } -m_len_done: - m_off = pd(ip,m_pos); - ip += m_len; - ii = ip; - if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) - { - m_off -= 1; -#if defined(LZO1X) - *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2)); - *op++ = LZO_BYTE(m_off >> 3); -#elif defined(LZO1Y) - *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2)); - *op++ = LZO_BYTE(m_off >> 2); -#endif - } - else if (m_off <= M3_MAX_OFFSET) - { - m_off -= 1; - if (m_len <= M3_MAX_LEN) - *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); - else - { - m_len -= M3_MAX_LEN; - *op++ = M3_MARKER | 0; - while __lzo_unlikely(m_len > 255) - { - m_len -= 255; - UA_SET1(op, 0); - op++; - } - *op++ = LZO_BYTE(m_len); - } - *op++ = LZO_BYTE(m_off << 2); - *op++ = LZO_BYTE(m_off >> 6); - } - else - { - m_off -= 0x4000; - if (m_len <= M4_MAX_LEN) - *op++ = LZO_BYTE(M4_MARKER | ((m_off >> 11) & 8) | (m_len - 2)); - else - { - m_len -= M4_MAX_LEN; - *op++ = LZO_BYTE(M4_MARKER | ((m_off >> 11) & 8)); - while __lzo_unlikely(m_len > 255) - { - m_len -= 255; - UA_SET1(op, 0); - op++; - } - *op++ = LZO_BYTE(m_len); - } - *op++ = LZO_BYTE(m_off << 2); - *op++ = LZO_BYTE(m_off >> 6); - } - goto next; - } - - *out_len = pd(op, out); - return pd(in_end,ii-ti); -} - -LZO_PUBLIC(int) -DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len, - lzo_bytep out, lzo_uintp out_len, - lzo_voidp wrkmem ) -{ - const lzo_bytep ip = in; - lzo_bytep op = out; - lzo_uint l = in_len; - lzo_uint t = 0; - - while (l > 20) - { - lzo_uint ll = l; - lzo_uintptr_t ll_end; -#if 0 || (LZO_DETERMINISTIC) - ll = LZO_MIN(ll, 49152); -#endif - ll_end = (lzo_uintptr_t)ip + ll; - if ((ll_end + ((t + ll) >> 5)) <= ll_end || (const lzo_bytep)(ll_end + ((t + ll) >> 5)) <= ip + ll) - break; -#if (LZO_DETERMINISTIC) - lzo_memset(wrkmem, 0, ((lzo_uint)1 << D_BITS) * sizeof(lzo_dict_t)); -#endif - t = do_compress(ip,ll,op,out_len,t,wrkmem); - ip += ll; - op += *out_len; - l -= ll; - } - t += l; - - if (t > 0) - { - const lzo_bytep ii = in + in_len - t; - - if (op == out && t <= 238) - *op++ = LZO_BYTE(17 + t); - else if (t <= 3) - op[-2] = LZO_BYTE(op[-2] | t); - else if (t <= 18) - *op++ = LZO_BYTE(t - 3); - else - { - lzo_uint tt = t - 18; - - *op++ = 0; - while (tt > 255) - { - tt -= 255; - UA_SET1(op, 0); - op++; - } - assert(tt > 0); - *op++ = LZO_BYTE(tt); - } - UA_COPYN(op, ii, t); - op += t; - } - - *op++ = M4_MARKER | 1; - *op++ = 0; - *op++ = 0; - - *out_len = pd(op, out); - return LZO_E_OK; -} - -#endif - -#undef do_compress -#undef DO_COMPRESS -#undef LZO_HASH - -#undef LZO_TEST_OVERRUN -#undef DO_DECOMPRESS -#define DO_DECOMPRESS lzo1x_decompress - -#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS) - -#if defined(LZO_TEST_OVERRUN) -# if !defined(LZO_TEST_OVERRUN_INPUT) -# define LZO_TEST_OVERRUN_INPUT 2 -# endif -# if !defined(LZO_TEST_OVERRUN_OUTPUT) -# define LZO_TEST_OVERRUN_OUTPUT 2 -# endif -# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) -# define LZO_TEST_OVERRUN_LOOKBEHIND 1 -# endif -#endif - -#undef TEST_IP -#undef TEST_OP -#undef TEST_IP_AND_TEST_OP -#undef TEST_LB -#undef TEST_LBO -#undef NEED_IP -#undef NEED_OP -#undef TEST_IV -#undef TEST_OV -#undef HAVE_TEST_IP -#undef HAVE_TEST_OP -#undef HAVE_NEED_IP -#undef HAVE_NEED_OP -#undef HAVE_ANY_IP -#undef HAVE_ANY_OP - -#if defined(LZO_TEST_OVERRUN_INPUT) -# if (LZO_TEST_OVERRUN_INPUT >= 1) -# define TEST_IP (ip < ip_end) -# endif -# if (LZO_TEST_OVERRUN_INPUT >= 2) -# define NEED_IP(x) \ - if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun -# define TEST_IV(x) if ((x) > (lzo_uint)0 - (511)) goto input_overrun -# endif -#endif - -#if defined(LZO_TEST_OVERRUN_OUTPUT) -# if (LZO_TEST_OVERRUN_OUTPUT >= 1) -# define TEST_OP (op <= op_end) -# endif -# if (LZO_TEST_OVERRUN_OUTPUT >= 2) -# undef TEST_OP -# define NEED_OP(x) \ - if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun -# define TEST_OV(x) if ((x) > (lzo_uint)0 - (511)) goto output_overrun -# endif -#endif - -#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) -# define TEST_LB(m_pos) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op)) goto lookbehind_overrun -# define TEST_LBO(m_pos,o) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op-(o))) goto lookbehind_overrun -#else -# define TEST_LB(m_pos) ((void) 0) -# define TEST_LBO(m_pos,o) ((void) 0) -#endif - -#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) -# define TEST_IP (ip < ip_end) -#endif - -#if defined(TEST_IP) -# define HAVE_TEST_IP 1 -#else -# define TEST_IP 1 -#endif -#if defined(TEST_OP) -# define HAVE_TEST_OP 1 -#else -# define TEST_OP 1 -#endif - -#if defined(HAVE_TEST_IP) && defined(HAVE_TEST_OP) -# define TEST_IP_AND_TEST_OP (TEST_IP && TEST_OP) -#elif defined(HAVE_TEST_IP) -# define TEST_IP_AND_TEST_OP TEST_IP -#elif defined(HAVE_TEST_OP) -# define TEST_IP_AND_TEST_OP TEST_OP -#else -# define TEST_IP_AND_TEST_OP 1 -#endif - -#if defined(NEED_IP) -# define HAVE_NEED_IP 1 -#else -# define NEED_IP(x) ((void) 0) -# define TEST_IV(x) ((void) 0) -#endif -#if defined(NEED_OP) -# define HAVE_NEED_OP 1 -#else -# define NEED_OP(x) ((void) 0) -# define TEST_OV(x) ((void) 0) -#endif - -#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) -# define HAVE_ANY_IP 1 -#endif -#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) -# define HAVE_ANY_OP 1 -#endif - -#if defined(DO_DECOMPRESS) -LZO_PUBLIC(int) -DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, - lzo_bytep out, lzo_uintp out_len, - lzo_voidp wrkmem ) -#endif -{ - lzo_bytep op; - const lzo_bytep ip; - lzo_uint t; -#if defined(COPY_DICT) - lzo_uint m_off; - const lzo_bytep dict_end; -#else - const lzo_bytep m_pos; -#endif - - const lzo_bytep const ip_end = in + in_len; -#if defined(HAVE_ANY_OP) - lzo_bytep const op_end = out + *out_len; -#endif -#if defined(LZO1Z) - lzo_uint last_m_off = 0; -#endif - - LZO_UNUSED(wrkmem); - -#if defined(COPY_DICT) - if (dict) - { - if (dict_len > M4_MAX_OFFSET) - { - dict += dict_len - M4_MAX_OFFSET; - dict_len = M4_MAX_OFFSET; - } - dict_end = dict + dict_len; - } - else - { - dict_len = 0; - dict_end = NULL; - } -#endif - - *out_len = 0; - - op = out; - ip = in; - - NEED_IP(1); - if (*ip > 17) - { - t = *ip++ - 17; - if (t < 4) - goto match_next; - assert(t > 0); NEED_OP(t); NEED_IP(t+3); - do *op++ = *ip++; while (--t > 0); - goto first_literal_run; - } - - for (;;) - { - NEED_IP(3); - t = *ip++; - if (t >= 16) - goto match; - if (t == 0) - { - while (*ip == 0) - { - t += 255; - ip++; - TEST_IV(t); - NEED_IP(1); - } - t += 15 + *ip++; - } - assert(t > 0); NEED_OP(t+3); NEED_IP(t+6); -#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) - t += 3; - if (t >= 8) do - { - UA_COPY8(op,ip); - op += 8; ip += 8; t -= 8; - } while (t >= 8); - if (t >= 4) - { - UA_COPY4(op,ip); - op += 4; ip += 4; t -= 4; - } - if (t > 0) - { - *op++ = *ip++; - if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } - } -#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) -#if !(LZO_OPT_UNALIGNED32) - if (PTR_ALIGNED2_4(op,ip)) - { -#endif - UA_COPY4(op,ip); - op += 4; ip += 4; - if (--t > 0) - { - if (t >= 4) - { - do { - UA_COPY4(op,ip); - op += 4; ip += 4; t -= 4; - } while (t >= 4); - if (t > 0) do *op++ = *ip++; while (--t > 0); - } - else - do *op++ = *ip++; while (--t > 0); - } -#if !(LZO_OPT_UNALIGNED32) - } - else -#endif -#endif -#if !(LZO_OPT_UNALIGNED32) - { - *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; - do *op++ = *ip++; while (--t > 0); - } -#endif - -first_literal_run: - - t = *ip++; - if (t >= 16) - goto match; -#if defined(COPY_DICT) -#if defined(LZO1Z) - m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); - last_m_off = m_off; -#else - m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); -#endif - NEED_OP(3); - t = 3; COPY_DICT(t,m_off) -#else -#if defined(LZO1Z) - t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); - m_pos = op - t; - last_m_off = t; -#else - m_pos = op - (1 + M2_MAX_OFFSET); - m_pos -= t >> 2; - m_pos -= *ip++ << 2; -#endif - TEST_LB(m_pos); NEED_OP(3); - *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; -#endif - goto match_done; - - for (;;) { -match: - if (t >= 64) - { -#if defined(COPY_DICT) -#if defined(LZO1X) - m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); - t = (t >> 5) - 1; -#elif defined(LZO1Y) - m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); - t = (t >> 4) - 3; -#elif defined(LZO1Z) - m_off = t & 0x1f; - if (m_off >= 0x1c) - m_off = last_m_off; - else - { - m_off = 1 + (m_off << 6) + (*ip++ >> 2); - last_m_off = m_off; - } - t = (t >> 5) - 1; -#endif -#else -#if defined(LZO1X) - m_pos = op - 1; - m_pos -= (t >> 2) & 7; - m_pos -= *ip++ << 3; - t = (t >> 5) - 1; -#elif defined(LZO1Y) - m_pos = op - 1; - m_pos -= (t >> 2) & 3; - m_pos -= *ip++ << 2; - t = (t >> 4) - 3; -#elif defined(LZO1Z) - { - lzo_uint off = t & 0x1f; - m_pos = op; - if (off >= 0x1c) - { - assert(last_m_off > 0); - m_pos -= last_m_off; - } - else - { - off = 1 + (off << 6) + (*ip++ >> 2); - m_pos -= off; - last_m_off = off; - } - } - t = (t >> 5) - 1; -#endif - TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); - goto copy_match; -#endif - } - else if (t >= 32) - { - t &= 31; - if (t == 0) - { - while (*ip == 0) - { - t += 255; - ip++; - TEST_OV(t); - NEED_IP(1); - } - t += 31 + *ip++; - NEED_IP(2); - } -#if defined(COPY_DICT) -#if defined(LZO1Z) - m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); - last_m_off = m_off; -#else - m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); -#endif -#else -#if defined(LZO1Z) - { - lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); - m_pos = op - off; - last_m_off = off; - } -#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) - m_pos = op - 1; - m_pos -= UA_GET_LE16(ip) >> 2; -#else - m_pos = op - 1; - m_pos -= (ip[0] >> 2) + (ip[1] << 6); -#endif -#endif - ip += 2; - } - else if (t >= 16) - { -#if defined(COPY_DICT) - m_off = (t & 8) << 11; -#else - m_pos = op; - m_pos -= (t & 8) << 11; -#endif - t &= 7; - if (t == 0) - { - while (*ip == 0) - { - t += 255; - ip++; - TEST_OV(t); - NEED_IP(1); - } - t += 7 + *ip++; - NEED_IP(2); - } -#if defined(COPY_DICT) -#if defined(LZO1Z) - m_off += (ip[0] << 6) + (ip[1] >> 2); -#else - m_off += (ip[0] >> 2) + (ip[1] << 6); -#endif - ip += 2; - if (m_off == 0) - goto eof_found; - m_off += 0x4000; -#if defined(LZO1Z) - last_m_off = m_off; -#endif -#else -#if defined(LZO1Z) - m_pos -= (ip[0] << 6) + (ip[1] >> 2); -#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) - m_pos -= UA_GET_LE16(ip) >> 2; -#else - m_pos -= (ip[0] >> 2) + (ip[1] << 6); -#endif - ip += 2; - if (m_pos == op) - goto eof_found; - m_pos -= 0x4000; -#if defined(LZO1Z) - last_m_off = pd((const lzo_bytep)op, m_pos); -#endif -#endif - } - else - { -#if defined(COPY_DICT) -#if defined(LZO1Z) - m_off = 1 + (t << 6) + (*ip++ >> 2); - last_m_off = m_off; -#else - m_off = 1 + (t >> 2) + (*ip++ << 2); -#endif - NEED_OP(2); - t = 2; COPY_DICT(t,m_off) -#else -#if defined(LZO1Z) - t = 1 + (t << 6) + (*ip++ >> 2); - m_pos = op - t; - last_m_off = t; -#else - m_pos = op - 1; - m_pos -= t >> 2; - m_pos -= *ip++ << 2; -#endif - TEST_LB(m_pos); NEED_OP(2); - *op++ = *m_pos++; *op++ = *m_pos; -#endif - goto match_done; - } - -#if defined(COPY_DICT) - - NEED_OP(t+3-1); - t += 3-1; COPY_DICT(t,m_off) - -#else - - TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); -#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) - if (op - m_pos >= 8) - { - t += (3 - 1); - if (t >= 8) do - { - UA_COPY8(op,m_pos); - op += 8; m_pos += 8; t -= 8; - } while (t >= 8); - if (t >= 4) - { - UA_COPY4(op,m_pos); - op += 4; m_pos += 4; t -= 4; - } - if (t > 0) - { - *op++ = m_pos[0]; - if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } - } - } - else -#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) -#if !(LZO_OPT_UNALIGNED32) - if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) - { - assert((op - m_pos) >= 4); -#else - if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) - { -#endif - UA_COPY4(op,m_pos); - op += 4; m_pos += 4; t -= 4 - (3 - 1); - do { - UA_COPY4(op,m_pos); - op += 4; m_pos += 4; t -= 4; - } while (t >= 4); - if (t > 0) do *op++ = *m_pos++; while (--t > 0); - } - else -#endif - { -copy_match: - *op++ = *m_pos++; *op++ = *m_pos++; - do *op++ = *m_pos++; while (--t > 0); - } - -#endif - -match_done: -#if defined(LZO1Z) - t = ip[-1] & 3; -#else - t = ip[-2] & 3; -#endif - if (t == 0) - break; - -match_next: - assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); -#if 0 - do *op++ = *ip++; while (--t > 0); -#else - *op++ = *ip++; - if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } -#endif - t = *ip++; - } - } - -eof_found: - *out_len = pd(op, out); - return (ip == ip_end ? LZO_E_OK : - (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); - -#if defined(HAVE_NEED_IP) -input_overrun: - *out_len = pd(op, out); - return LZO_E_INPUT_OVERRUN; -#endif - -#if defined(HAVE_NEED_OP) -output_overrun: - *out_len = pd(op, out); - return LZO_E_OUTPUT_OVERRUN; -#endif - -#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) -lookbehind_overrun: - *out_len = pd(op, out); - return LZO_E_LOOKBEHIND_OVERRUN; -#endif -} - -#endif - -#define LZO_TEST_OVERRUN 1 -#undef DO_DECOMPRESS -#define DO_DECOMPRESS lzo1x_decompress_safe - -#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS_SAFE) - -#if defined(LZO_TEST_OVERRUN) -# if !defined(LZO_TEST_OVERRUN_INPUT) -# define LZO_TEST_OVERRUN_INPUT 2 -# endif -# if !defined(LZO_TEST_OVERRUN_OUTPUT) -# define LZO_TEST_OVERRUN_OUTPUT 2 -# endif -# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) -# define LZO_TEST_OVERRUN_LOOKBEHIND 1 -# endif -#endif - -#undef TEST_IP -#undef TEST_OP -#undef TEST_IP_AND_TEST_OP -#undef TEST_LB -#undef TEST_LBO -#undef NEED_IP -#undef NEED_OP -#undef TEST_IV -#undef TEST_OV -#undef HAVE_TEST_IP -#undef HAVE_TEST_OP -#undef HAVE_NEED_IP -#undef HAVE_NEED_OP -#undef HAVE_ANY_IP -#undef HAVE_ANY_OP - -#if defined(LZO_TEST_OVERRUN_INPUT) -# if (LZO_TEST_OVERRUN_INPUT >= 1) -# define TEST_IP (ip < ip_end) -# endif -# if (LZO_TEST_OVERRUN_INPUT >= 2) -# define NEED_IP(x) \ - if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun -# define TEST_IV(x) if ((x) > (lzo_uint)0 - (511)) goto input_overrun -# endif -#endif - -#if defined(LZO_TEST_OVERRUN_OUTPUT) -# if (LZO_TEST_OVERRUN_OUTPUT >= 1) -# define TEST_OP (op <= op_end) -# endif -# if (LZO_TEST_OVERRUN_OUTPUT >= 2) -# undef TEST_OP -# define NEED_OP(x) \ - if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun -# define TEST_OV(x) if ((x) > (lzo_uint)0 - (511)) goto output_overrun -# endif -#endif - -#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) -# define TEST_LB(m_pos) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op)) goto lookbehind_overrun -# define TEST_LBO(m_pos,o) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op-(o))) goto lookbehind_overrun -#else -# define TEST_LB(m_pos) ((void) 0) -# define TEST_LBO(m_pos,o) ((void) 0) -#endif - -#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) -# define TEST_IP (ip < ip_end) -#endif - -#if defined(TEST_IP) -# define HAVE_TEST_IP 1 -#else -# define TEST_IP 1 -#endif -#if defined(TEST_OP) -# define HAVE_TEST_OP 1 -#else -# define TEST_OP 1 -#endif - -#if defined(HAVE_TEST_IP) && defined(HAVE_TEST_OP) -# define TEST_IP_AND_TEST_OP (TEST_IP && TEST_OP) -#elif defined(HAVE_TEST_IP) -# define TEST_IP_AND_TEST_OP TEST_IP -#elif defined(HAVE_TEST_OP) -# define TEST_IP_AND_TEST_OP TEST_OP -#else -# define TEST_IP_AND_TEST_OP 1 -#endif - -#if defined(NEED_IP) -# define HAVE_NEED_IP 1 -#else -# define NEED_IP(x) ((void) 0) -# define TEST_IV(x) ((void) 0) -#endif -#if defined(NEED_OP) -# define HAVE_NEED_OP 1 -#else -# define NEED_OP(x) ((void) 0) -# define TEST_OV(x) ((void) 0) -#endif - -#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) -# define HAVE_ANY_IP 1 -#endif -#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) -# define HAVE_ANY_OP 1 -#endif - -#if defined(DO_DECOMPRESS) -LZO_PUBLIC(int) -DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, - lzo_bytep out, lzo_uintp out_len, - lzo_voidp wrkmem ) -#endif -{ - lzo_bytep op; - const lzo_bytep ip; - lzo_uint t; -#if defined(COPY_DICT) - lzo_uint m_off; - const lzo_bytep dict_end; -#else - const lzo_bytep m_pos; -#endif - - const lzo_bytep const ip_end = in + in_len; -#if defined(HAVE_ANY_OP) - lzo_bytep const op_end = out + *out_len; -#endif -#if defined(LZO1Z) - lzo_uint last_m_off = 0; -#endif - - LZO_UNUSED(wrkmem); - -#if defined(COPY_DICT) - if (dict) - { - if (dict_len > M4_MAX_OFFSET) - { - dict += dict_len - M4_MAX_OFFSET; - dict_len = M4_MAX_OFFSET; - } - dict_end = dict + dict_len; - } - else - { - dict_len = 0; - dict_end = NULL; - } -#endif - - *out_len = 0; - - op = out; - ip = in; - - NEED_IP(1); - if (*ip > 17) - { - t = *ip++ - 17; - if (t < 4) - goto match_next; - assert(t > 0); NEED_OP(t); NEED_IP(t+3); - do *op++ = *ip++; while (--t > 0); - goto first_literal_run; - } - - for (;;) - { - NEED_IP(3); - t = *ip++; - if (t >= 16) - goto match; - if (t == 0) - { - while (*ip == 0) - { - t += 255; - ip++; - TEST_IV(t); - NEED_IP(1); - } - t += 15 + *ip++; - } - assert(t > 0); NEED_OP(t+3); NEED_IP(t+6); -#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) - t += 3; - if (t >= 8) do - { - UA_COPY8(op,ip); - op += 8; ip += 8; t -= 8; - } while (t >= 8); - if (t >= 4) - { - UA_COPY4(op,ip); - op += 4; ip += 4; t -= 4; - } - if (t > 0) - { - *op++ = *ip++; - if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } - } -#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) -#if !(LZO_OPT_UNALIGNED32) - if (PTR_ALIGNED2_4(op,ip)) - { -#endif - UA_COPY4(op,ip); - op += 4; ip += 4; - if (--t > 0) - { - if (t >= 4) - { - do { - UA_COPY4(op,ip); - op += 4; ip += 4; t -= 4; - } while (t >= 4); - if (t > 0) do *op++ = *ip++; while (--t > 0); - } - else - do *op++ = *ip++; while (--t > 0); - } -#if !(LZO_OPT_UNALIGNED32) - } - else -#endif -#endif -#if !(LZO_OPT_UNALIGNED32) - { - *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; - do *op++ = *ip++; while (--t > 0); - } -#endif - -first_literal_run: - - t = *ip++; - if (t >= 16) - goto match; -#if defined(COPY_DICT) -#if defined(LZO1Z) - m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); - last_m_off = m_off; -#else - m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); -#endif - NEED_OP(3); - t = 3; COPY_DICT(t,m_off) -#else -#if defined(LZO1Z) - t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); - m_pos = op - t; - last_m_off = t; -#else - m_pos = op - (1 + M2_MAX_OFFSET); - m_pos -= t >> 2; - m_pos -= *ip++ << 2; -#endif - TEST_LB(m_pos); NEED_OP(3); - *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; -#endif - goto match_done; - - for (;;) { -match: - if (t >= 64) - { -#if defined(COPY_DICT) -#if defined(LZO1X) - m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); - t = (t >> 5) - 1; -#elif defined(LZO1Y) - m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); - t = (t >> 4) - 3; -#elif defined(LZO1Z) - m_off = t & 0x1f; - if (m_off >= 0x1c) - m_off = last_m_off; - else - { - m_off = 1 + (m_off << 6) + (*ip++ >> 2); - last_m_off = m_off; - } - t = (t >> 5) - 1; -#endif -#else -#if defined(LZO1X) - m_pos = op - 1; - m_pos -= (t >> 2) & 7; - m_pos -= *ip++ << 3; - t = (t >> 5) - 1; -#elif defined(LZO1Y) - m_pos = op - 1; - m_pos -= (t >> 2) & 3; - m_pos -= *ip++ << 2; - t = (t >> 4) - 3; -#elif defined(LZO1Z) - { - lzo_uint off = t & 0x1f; - m_pos = op; - if (off >= 0x1c) - { - assert(last_m_off > 0); - m_pos -= last_m_off; - } - else - { - off = 1 + (off << 6) + (*ip++ >> 2); - m_pos -= off; - last_m_off = off; - } - } - t = (t >> 5) - 1; -#endif - TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); - goto copy_match; -#endif - } - else if (t >= 32) - { - t &= 31; - if (t == 0) - { - while (*ip == 0) - { - t += 255; - ip++; - TEST_OV(t); - NEED_IP(1); - } - t += 31 + *ip++; - NEED_IP(2); - } -#if defined(COPY_DICT) -#if defined(LZO1Z) - m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); - last_m_off = m_off; -#else - m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); -#endif -#else -#if defined(LZO1Z) - { - lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); - m_pos = op - off; - last_m_off = off; - } -#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) - m_pos = op - 1; - m_pos -= UA_GET_LE16(ip) >> 2; -#else - m_pos = op - 1; - m_pos -= (ip[0] >> 2) + (ip[1] << 6); -#endif -#endif - ip += 2; - } - else if (t >= 16) - { -#if defined(COPY_DICT) - m_off = (t & 8) << 11; -#else - m_pos = op; - m_pos -= (t & 8) << 11; -#endif - t &= 7; - if (t == 0) - { - while (*ip == 0) - { - t += 255; - ip++; - TEST_OV(t); - NEED_IP(1); - } - t += 7 + *ip++; - NEED_IP(2); - } -#if defined(COPY_DICT) -#if defined(LZO1Z) - m_off += (ip[0] << 6) + (ip[1] >> 2); -#else - m_off += (ip[0] >> 2) + (ip[1] << 6); -#endif - ip += 2; - if (m_off == 0) - goto eof_found; - m_off += 0x4000; -#if defined(LZO1Z) - last_m_off = m_off; -#endif -#else -#if defined(LZO1Z) - m_pos -= (ip[0] << 6) + (ip[1] >> 2); -#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) - m_pos -= UA_GET_LE16(ip) >> 2; -#else - m_pos -= (ip[0] >> 2) + (ip[1] << 6); -#endif - ip += 2; - if (m_pos == op) - goto eof_found; - m_pos -= 0x4000; -#if defined(LZO1Z) - last_m_off = pd((const lzo_bytep)op, m_pos); -#endif -#endif - } - else - { -#if defined(COPY_DICT) -#if defined(LZO1Z) - m_off = 1 + (t << 6) + (*ip++ >> 2); - last_m_off = m_off; -#else - m_off = 1 + (t >> 2) + (*ip++ << 2); -#endif - NEED_OP(2); - t = 2; COPY_DICT(t,m_off) -#else -#if defined(LZO1Z) - t = 1 + (t << 6) + (*ip++ >> 2); - m_pos = op - t; - last_m_off = t; -#else - m_pos = op - 1; - m_pos -= t >> 2; - m_pos -= *ip++ << 2; -#endif - TEST_LB(m_pos); NEED_OP(2); - *op++ = *m_pos++; *op++ = *m_pos; -#endif - goto match_done; - } - -#if defined(COPY_DICT) - - NEED_OP(t+3-1); - t += 3-1; COPY_DICT(t,m_off) - -#else - - TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); -#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) - if (op - m_pos >= 8) - { - t += (3 - 1); - if (t >= 8) do - { - UA_COPY8(op,m_pos); - op += 8; m_pos += 8; t -= 8; - } while (t >= 8); - if (t >= 4) - { - UA_COPY4(op,m_pos); - op += 4; m_pos += 4; t -= 4; - } - if (t > 0) - { - *op++ = m_pos[0]; - if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } - } - } - else -#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) -#if !(LZO_OPT_UNALIGNED32) - if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) - { - assert((op - m_pos) >= 4); -#else - if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) - { -#endif - UA_COPY4(op,m_pos); - op += 4; m_pos += 4; t -= 4 - (3 - 1); - do { - UA_COPY4(op,m_pos); - op += 4; m_pos += 4; t -= 4; - } while (t >= 4); - if (t > 0) do *op++ = *m_pos++; while (--t > 0); - } - else -#endif - { -copy_match: - *op++ = *m_pos++; *op++ = *m_pos++; - do *op++ = *m_pos++; while (--t > 0); - } - -#endif - -match_done: -#if defined(LZO1Z) - t = ip[-1] & 3; -#else - t = ip[-2] & 3; -#endif - if (t == 0) - break; - -match_next: - assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); -#if 0 - do *op++ = *ip++; while (--t > 0); -#else - *op++ = *ip++; - if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } -#endif - t = *ip++; - } - } - -eof_found: - *out_len = pd(op, out); - return (ip == ip_end ? LZO_E_OK : - (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); - -#if defined(HAVE_NEED_IP) -input_overrun: - *out_len = pd(op, out); - return LZO_E_INPUT_OVERRUN; -#endif - -#if defined(HAVE_NEED_OP) -output_overrun: - *out_len = pd(op, out); - return LZO_E_OUTPUT_OVERRUN; -#endif - -#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) -lookbehind_overrun: - *out_len = pd(op, out); - return LZO_E_LOOKBEHIND_OVERRUN; -#endif -} - -#endif - -/***** End of minilzo.c *****/ diff --git a/grub-core/lib/minilzo/minilzo.h b/grub-core/lib/minilzo/minilzo.h deleted file mode 100644 index c1c229757..000000000 --- a/grub-core/lib/minilzo/minilzo.h +++ /dev/null @@ -1,106 +0,0 @@ -/* minilzo.h -- mini subset of the LZO real-time data compression library - - This file is part of the LZO real-time data compression library. - - Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer - All Rights Reserved. - - The LZO library is free software; you can 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. - - The LZO 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with the LZO library; see the file COPYING. - If not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - Markus F.X.J. Oberhumer - - http://www.oberhumer.com/opensource/lzo/ - */ - -/* - * NOTE: - * the full LZO package can be found at - * http://www.oberhumer.com/opensource/lzo/ - */ - - -#ifndef __MINILZO_H_INCLUDED -#define __MINILZO_H_INCLUDED 1 - -#define MINILZO_VERSION 0x20a0 /* 2.10 */ - -#if defined(__LZOCONF_H_INCLUDED) -# error "you cannot use both LZO and miniLZO" -#endif - -/* internal Autoconf configuration file - only used when building miniLZO */ -#ifdef MINILZO_HAVE_CONFIG_H -# include -#endif -#include -#include - -#ifndef __LZODEFS_H_INCLUDED -#include "lzodefs.h" -#endif -#undef LZO_HAVE_CONFIG_H -#include "lzoconf.h" - -#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION) -# error "version mismatch in header files" -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - - -/*********************************************************************** -// -************************************************************************/ - -/* Memory required for the wrkmem parameter. - * When the required size is 0, you can also pass a NULL pointer. - */ - -#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS -#define LZO1X_1_MEM_COMPRESS ((lzo_uint32_t) (16384L * lzo_sizeof_dict_t)) -#define LZO1X_MEM_DECOMPRESS (0) - - -/* compression */ -LZO_EXTERN(int) -lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len, - lzo_bytep dst, lzo_uintp dst_len, - lzo_voidp wrkmem ); - -/* decompression */ -LZO_EXTERN(int) -lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len, - lzo_bytep dst, lzo_uintp dst_len, - lzo_voidp wrkmem /* NOT USED */ ); - -/* safe decompression with overrun testing */ -LZO_EXTERN(int) -lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len, - lzo_bytep dst, lzo_uintp dst_len, - lzo_voidp wrkmem /* NOT USED */ ); - - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* already included */ - - -/* vim:set ts=4 sw=4 et: */ diff --git a/grub-core/lib/mips/arc/reboot.c b/grub-core/lib/mips/arc/reboot.c deleted file mode 100644 index ecf12a7ed..000000000 --- a/grub-core/lib/mips/arc/reboot.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include - -void -grub_reboot (void) -{ - GRUB_ARC_FIRMWARE_VECTOR->restart (); - - grub_millisleep (1500); - - grub_puts_ (N_("Reboot failed")); - grub_refresh (); - while (1); -} diff --git a/grub-core/lib/mips/loongson/reboot.c b/grub-core/lib/mips/loongson/reboot.c deleted file mode 100644 index 7317e5868..000000000 --- a/grub-core/lib/mips/loongson/reboot.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void -grub_reboot (void) -{ - switch (grub_arch_machine) - { - case GRUB_ARCH_MACHINE_FULOONG2E: - grub_outl (grub_inl (0xbfe00104) & ~4, 0xbfe00104); - grub_outl (grub_inl (0xbfe00104) | 4, 0xbfe00104); - break; - case GRUB_ARCH_MACHINE_FULOONG2F: - { - grub_pci_device_t dev; - if (!grub_cs5536_find (&dev)) - break; - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_RESET, - grub_cs5536_read_msr (dev, - GRUB_CS5536_MSR_DIVIL_RESET) - | 1); - break; - } - case GRUB_ARCH_MACHINE_YEELOONG: - grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT); - break; - case GRUB_ARCH_MACHINE_YEELOONG_3A: - grub_millisleep (1); - grub_outb (0x4e, GRUB_MACHINE_PCI_IO_BASE_3A | 0x66); - grub_millisleep (1); - grub_outb (1, GRUB_MACHINE_PCI_IO_BASE_3A | 0x62); - grub_millisleep (5000); - } - grub_millisleep (1500); - - grub_puts_ (N_("Reboot failed")); - grub_refresh (); - while (1); -} diff --git a/grub-core/lib/mips/relocator.c b/grub-core/lib/mips/relocator.c deleted file mode 100644 index 773f3b769..000000000 --- a/grub-core/lib/mips/relocator.c +++ /dev/null @@ -1,147 +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 . - */ - -#include -#include - -#include -#include -#include -#include - -#include -#include - -/* Do we need mips64? */ - -extern grub_uint8_t grub_relocator_forward_start; -extern grub_uint8_t grub_relocator_forward_end; -extern grub_uint8_t grub_relocator_backward_start; -extern grub_uint8_t grub_relocator_backward_end; - -#define REGW_SIZEOF (2 * sizeof (grub_uint32_t)) -#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t)) - -#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator_##x##_end \ - - &grub_relocator_##x##_start) -#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \ - + REGW_SIZEOF * 3) -grub_size_t grub_relocator_align = sizeof (grub_uint32_t); -grub_size_t grub_relocator_forward_size; -grub_size_t grub_relocator_backward_size; -grub_size_t grub_relocator_jumper_size = JUMP_SIZEOF + REGW_SIZEOF; - -void -grub_cpu_relocator_init (void) -{ - grub_relocator_forward_size = RELOCATOR_SIZEOF(forward); - grub_relocator_backward_size = RELOCATOR_SIZEOF(backward); -} - -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; -} - -void -grub_cpu_relocator_jumper (void *rels, grub_addr_t addr) -{ - write_reg (1, addr, &rels); - write_jump (1, &rels); -} - -void -grub_cpu_relocator_backward (void *ptr0, void *src, void *dest, - grub_size_t size) -{ - void *ptr = ptr0; - write_reg (8, (grub_uint32_t) src, &ptr); - write_reg (9, (grub_uint32_t) dest, &ptr); - write_reg (10, (grub_uint32_t) size, &ptr); - grub_memcpy (ptr, &grub_relocator_backward_start, - RELOCATOR_SRC_SIZEOF (backward)); -} - -void -grub_cpu_relocator_forward (void *ptr0, void *src, void *dest, - grub_size_t size) -{ - void *ptr = ptr0; - write_reg (8, (grub_uint32_t) src, &ptr); - write_reg (9, (grub_uint32_t) dest, &ptr); - write_reg (10, (grub_uint32_t) size, &ptr); - grub_memcpy (ptr, &grub_relocator_forward_start, - RELOCATOR_SRC_SIZEOF (forward)); -} - -grub_err_t -grub_relocator32_boot (struct grub_relocator *rel, - struct grub_relocator32_state state) -{ - grub_relocator_chunk_t ch; - void *ptr; - grub_err_t err; - void *relst; - grub_size_t relsize; - grub_size_t stateset_size = 31 * REGW_SIZEOF + JUMP_SIZEOF; - unsigned i; - grub_addr_t vtarget; - - err = grub_relocator_alloc_chunk_align (rel, &ch, 0, UP_TO_TOP32 (stateset_size), - stateset_size, sizeof (grub_uint32_t), - GRUB_RELOCATOR_PREFERENCE_NONE, 0); - if (err) - return err; - - ptr = get_virtual_current_address (ch); - for (i = 1; i < 32; i++) - write_reg (i, state.gpr[i], &ptr); - write_jump (state.jumpreg, &ptr); - - vtarget = (grub_addr_t) grub_map_memory (get_physical_target_address (ch), - stateset_size); - - err = grub_relocator_prepare_relocs (rel, vtarget, &relst, &relsize); - if (err) - return err; - - grub_arch_sync_caches ((void *) relst, relsize); - - ((void (*) (void)) relst) (); - - /* Not reached. */ - return GRUB_ERR_NONE; -} diff --git a/grub-core/lib/mips/setjmp.S b/grub-core/lib/mips/setjmp.S deleted file mode 100644 index 895235b78..000000000 --- a/grub-core/lib/mips/setjmp.S +++ /dev/null @@ -1,71 +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 . - */ - -#include -#include -#include - - .file "setjmp.S" - -GRUB_MOD_LICENSE "GPLv3+" - - .text - -/* - * int grub_setjmp (grub_jmp_buf env) - */ -FUNCTION(grub_setjmp) - GRUB_ASM_REG_S $s0, 0($a0) - GRUB_ASM_REG_S $s1, 8($a0) - GRUB_ASM_REG_S $s2, 16($a0) - GRUB_ASM_REG_S $s3, 24($a0) - GRUB_ASM_REG_S $s4, 32($a0) - GRUB_ASM_REG_S $s5, 40($a0) - GRUB_ASM_REG_S $s6, 48($a0) - GRUB_ASM_REG_S $s7, 56($a0) - GRUB_ASM_REG_S $s8, 64($a0) - GRUB_ASM_REG_S $gp, 72($a0) - GRUB_ASM_REG_S $sp, 80($a0) - GRUB_ASM_REG_S $ra, 88($a0) - move $v0, $zero - move $v1, $zero - jr $ra - nop -/* - * int grub_longjmp (grub_jmp_buf env, int val) - */ -FUNCTION(grub_longjmp) - GRUB_ASM_REG_L $s0, 0($a0) - GRUB_ASM_REG_L $s1, 8($a0) - GRUB_ASM_REG_L $s2, 16($a0) - GRUB_ASM_REG_L $s3, 24($a0) - GRUB_ASM_REG_L $s4, 32($a0) - GRUB_ASM_REG_L $s5, 40($a0) - GRUB_ASM_REG_L $s6, 48($a0) - GRUB_ASM_REG_L $s7, 56($a0) - GRUB_ASM_REG_L $s8, 64($a0) - GRUB_ASM_REG_L $gp, 72($a0) - GRUB_ASM_REG_L $sp, 80($a0) - GRUB_ASM_REG_L $ra, 88($a0) - move $v0, $a1 - bne $v0, $zero, 1f - addiu $v0, $v0, 1 -1: - move $v1, $zero - jr $ra - nop diff --git a/grub-core/lib/posix_wrap/assert.h b/grub-core/lib/posix_wrap/assert.h deleted file mode 100644 index 6b00a0ba3..000000000 --- a/grub-core/lib/posix_wrap/assert.h +++ /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 . - */ - -#ifndef GRUB_POSIX_ASSERT_H -#define GRUB_POSIX_ASSERT_H 1 - -#include - -#define assert(x) assert_real(__FILE__, __LINE__, x) - -static inline void -assert_real (const char *file, int line, int cond) -{ - if (!cond) - grub_printf ("Assertion failed at %s:%d\n", file, line); -} - -#endif diff --git a/grub-core/lib/posix_wrap/c-ctype.h b/grub-core/lib/posix_wrap/c-ctype.h deleted file mode 100644 index 5f8fc8ce3..000000000 --- a/grub-core/lib/posix_wrap/c-ctype.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_POSIX_C_CTYPE_H -#define GRUB_POSIX_C_CTYPE_H 1 - -#include - -static inline bool -c_isspace (int c) -{ - return !!grub_isspace (c); -} - -static inline bool -c_isdigit (int c) -{ - return !!grub_isdigit (c); -} - -static inline bool -c_islower (int c) -{ - return !!grub_islower (c); -} - -static inline bool -c_isascii (int c) -{ - return !(c & ~0x7f); -} - -static inline bool -c_isupper (int c) -{ - return !!grub_isupper (c); -} - -static inline bool -c_isxdigit (int c) -{ - return !!grub_isxdigit (c); -} - -static inline bool -c_isprint (int c) -{ - return !!grub_isprint (c); -} - -static inline bool -c_iscntrl (int c) -{ - return !grub_isprint (c); -} - -static inline bool -c_isgraph (int c) -{ - return grub_isprint (c) && !grub_isspace (c); -} - -static inline bool -c_isalnum (int c) -{ - return grub_isalpha (c) || grub_isdigit (c); -} - -static inline bool -c_ispunct (int c) -{ - return grub_isprint (c) && !grub_isspace (c) && !c_isalnum (c); -} - -static inline bool -c_isalpha (int c) -{ - return !!grub_isalpha (c); -} - -static inline bool -c_isblank (int c) -{ - return c == ' ' || c == '\t'; -} - -static inline int -c_tolower (int c) -{ - return grub_tolower (c); -} - -static inline int -c_toupper (int c) -{ - return grub_toupper (c); -} - -#endif diff --git a/grub-core/lib/posix_wrap/ctype.h b/grub-core/lib/posix_wrap/ctype.h deleted file mode 100644 index 67bcaac68..000000000 --- a/grub-core/lib/posix_wrap/ctype.h +++ /dev/null @@ -1,108 +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 . - */ - -#ifndef GRUB_POSIX_CTYPE_H -#define GRUB_POSIX_CTYPE_H 1 - -#include - -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 grub_islower (c); -} - -static inline int -isascii (int c) -{ - return !(c & ~0x7f); -} - -static inline int -isupper (int c) -{ - return grub_isupper (c); -} - -static inline int -isxdigit (int c) -{ - return grub_isxdigit (c); -} - -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 deleted file mode 100644 index 5ede4fe69..000000000 --- a/grub-core/lib/posix_wrap/errno.h +++ /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 . - */ - -#ifndef GRUB_POSIX_ERRNO_H -#define GRUB_POSIX_ERRNO_H 1 - -#include - -#undef errno -#define errno grub_errno -#define EINVAL GRUB_ERR_BAD_NUMBER -#define ENOMEM GRUB_ERR_OUT_OF_MEMORY - -/* From glibc . */ -#ifndef __set_errno -# define __set_errno(val) (grub_errno = (val)) -#endif -#endif diff --git a/grub-core/lib/posix_wrap/inttypes.h b/grub-core/lib/posix_wrap/inttypes.h deleted file mode 100644 index a12c43b15..000000000 --- a/grub-core/lib/posix_wrap/inttypes.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/grub-core/lib/posix_wrap/langinfo.h b/grub-core/lib/posix_wrap/langinfo.h deleted file mode 100644 index ab75af15d..000000000 --- a/grub-core/lib/posix_wrap/langinfo.h +++ /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 . - */ - -#ifndef GRUB_POSIX_LANGINFO_H -#define GRUB_POSIX_LANGINFO_H 1 - -#include - -typedef enum { CODESET } nl_item; - -static inline const char * -nl_langinfo (nl_item item) -{ - switch (item) - { - case CODESET: - return "UTF-8"; - default: - return ""; - } -} - -#endif diff --git a/grub-core/lib/posix_wrap/limits.h b/grub-core/lib/posix_wrap/limits.h deleted file mode 100644 index 4be7b4080..000000000 --- a/grub-core/lib/posix_wrap/limits.h +++ /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 . - */ - -#ifndef GRUB_POSIX_LIMITS_H -#define GRUB_POSIX_LIMITS_H - -#include - -#define UCHAR_MAX GRUB_UCHAR_MAX -#define USHRT_MAX GRUB_USHRT_MAX -#define UINT_MAX GRUB_UINT_MAX -#define ULONG_MAX GRUB_ULONG_MAX - -/* gnulib also defines this type */ -#ifndef SIZE_MAX -# define SIZE_MAX GRUB_SIZE_MAX -#endif - -#define SCHAR_MIN GRUB_SCHAR_MIN -#define SCHAR_MAX GRUB_SCHAR_MAX -#define SHRT_MIN GRUB_SHRT_MIN -#define SHRT_MAX GRUB_SHRT_MAX -#define INT_MIN GRUB_INT_MIN -#define INT_MAX GRUB_INT_MAX -#define LONG_MIN GRUB_LONG_MIN -#define LONG_MAX GRUB_LONG_MAX - -#define CHAR_BIT 8 -#define WORD_BIT 32 - -#endif diff --git a/grub-core/lib/posix_wrap/locale.h b/grub-core/lib/posix_wrap/locale.h deleted file mode 100644 index 569a76517..000000000 --- a/grub-core/lib/posix_wrap/locale.h +++ /dev/null @@ -1,3 +0,0 @@ -#ifdef GRUB_UTIL -#include_next -#endif diff --git a/grub-core/lib/posix_wrap/stdint.h b/grub-core/lib/posix_wrap/stdint.h deleted file mode 100644 index a12c43b15..000000000 --- a/grub-core/lib/posix_wrap/stdint.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/grub-core/lib/posix_wrap/stdio.h b/grub-core/lib/posix_wrap/stdio.h deleted file mode 100644 index d5a8b7503..000000000 --- a/grub-core/lib/posix_wrap/stdio.h +++ /dev/null @@ -1,43 +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 . - */ - -#ifndef GRUB_POSIX_STDIO_H -#define GRUB_POSIX_STDIO_H 1 - -#include -#include -#include - -typedef struct grub_file FILE; - -#define EOF -1 - -static inline int -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; -} - -#endif diff --git a/grub-core/lib/posix_wrap/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h deleted file mode 100644 index 14e4efdd0..000000000 --- a/grub-core/lib/posix_wrap/stdlib.h +++ /dev/null @@ -1,75 +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 . - */ - -#ifndef GRUB_POSIX_STDLIB_H -#define GRUB_POSIX_STDLIB_H 1 - -#include -#include -#include - -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) -{ - grub_size_t sz; - - if (grub_mul (size, nelem, &sz)) - return NULL; - - return grub_zalloc (sz); -} - -static inline void * -realloc (void *ptr, grub_size_t size) -{ - return grub_realloc (ptr, size); -} - -static inline int -abs (int c) -{ - return (c >= 0) ? c : -c; -} - -static inline void __attribute__ ((noreturn)) -abort (void) -{ - grub_abort (); -} - -#define strtol grub_strtol - -/* for libgcrypt */ -#define HAVE_STRTOUL -#define strtoul grub_strtoul - -#define strtoull grub_strtoull - -#endif diff --git a/grub-core/lib/posix_wrap/string.h b/grub-core/lib/posix_wrap/string.h deleted file mode 100644 index d3e400d50..000000000 --- a/grub-core/lib/posix_wrap/string.h +++ /dev/null @@ -1,113 +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 . - */ - -#ifndef GRUB_POSIX_STRING_H -#define GRUB_POSIX_STRING_H 1 - -#include -#include - -#define HAVE_STRCASECMP 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); -} - -static inline void -bcopy (const void *src, void *dest, grub_size_t n) -{ - grub_memcpy (dest, src, n); -} - -static inline char * -strcpy (char *dest, const char *src) -{ - return grub_strcpy (dest, src); -} - -static inline char * -strstr (const char *haystack, const char *needle) -{ - return grub_strstr (haystack, needle); -} - -static inline char * -strchr (const char *s, int c) -{ - return grub_strchr (s, c); -} - -static inline char * -strncpy (char *dest, const char *src, grub_size_t n) -{ - return grub_strncpy (dest, src, n); -} - -static inline int -strcoll (const char *s1, const char *s2) -{ - return grub_strcmp (s1, s2); -} - -static inline void * -memchr (const void *s, int c, grub_size_t n) -{ - return grub_memchr (s, c, n); -} - -static inline char * -strncat (char *dest, const char *src, grub_size_t n) -{ - const char *end; - char *str = dest; - grub_size_t src_len; - - dest += grub_strlen (dest); - - end = grub_memchr (src, '\0', n); - if (end != NULL) - src_len = (grub_size_t) (end - src); - else - src_len = n; - - dest[src_len] = '\0'; - grub_memcpy (dest, src, src_len); - - return str; -} - -#define memcmp grub_memcmp -#define memcpy grub_memcpy -#define memmove grub_memmove -#define memset grub_memset - -#endif diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h deleted file mode 100644 index 2f3e86549..000000000 --- a/grub-core/lib/posix_wrap/sys/types.h +++ /dev/null @@ -1,65 +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 . - */ - -#ifndef GRUB_POSIX_SYS_TYPES_H -#define GRUB_POSIX_SYS_TYPES_H 1 - -#include - -#include - -/* Provided by gnulib if not present. */ -#include - -typedef grub_ssize_t ssize_t; - -typedef grub_uint8_t uint8_t; -typedef grub_uint16_t uint16_t; -typedef grub_uint32_t uint32_t; -typedef grub_uint64_t uint64_t; - -typedef grub_int8_t int8_t; -typedef grub_int16_t int16_t; -typedef grub_int32_t int32_t; -typedef grub_int64_t int64_t; - -#define HAVE_U64_TYPEDEF 1 -typedef grub_uint64_t u64; -#define HAVE_U32_TYPEDEF 1 -typedef grub_uint32_t u32; -#define HAVE_U16_TYPEDEF 1 -typedef grub_uint16_t u16; -#define HAVE_BYTE_TYPEDEF 1 -typedef grub_uint8_t byte; - -typedef grub_addr_t uintptr_t; - -#define SIZEOF_UNSIGNED_LONG GRUB_CPU_SIZEOF_LONG -#define SIZEOF_UNSIGNED_LONG_INT GRUB_CPU_SIZEOF_LONG -#define SIZEOF_UNSIGNED_INT 4 -#define SIZEOF_UNSIGNED_LONG_LONG 8 -#define SIZEOF_UNSIGNED_SHORT 2 -#define SIZEOF_UINT64_T 8 - -#ifdef GRUB_CPU_WORDS_BIGENDIAN -#define WORDS_BIGENDIAN 1 -#else -#undef WORDS_BIGENDIAN -#endif - -#endif diff --git a/grub-core/lib/posix_wrap/unistd.h b/grub-core/lib/posix_wrap/unistd.h deleted file mode 100644 index a12c43b15..000000000 --- a/grub-core/lib/posix_wrap/unistd.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/grub-core/lib/posix_wrap/wchar.h b/grub-core/lib/posix_wrap/wchar.h deleted file mode 100644 index e0e04a6a0..000000000 --- a/grub-core/lib/posix_wrap/wchar.h +++ /dev/null @@ -1,119 +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 . - */ - -#ifndef GRUB_POSIX_WCHAR_H -#define GRUB_POSIX_WCHAR_H 1 - -#include - -#define wint_t grub_posix_wint_t -#define wchar_t grub_posix_wchar_t -#define mbstate_t grub_posix_mbstate_t - -/* UCS-4. */ -typedef grub_int32_t wint_t; -enum - { - WEOF = -1 - }; - -/* UCS-4. */ -typedef grub_int32_t wchar_t; - -typedef struct mbstate { - grub_uint32_t code; - int count; -} mbstate_t; - -/* UTF-8. */ -#define MB_CUR_MAX 4 -#define MB_LEN_MAX 4 - -static inline size_t -mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) -{ - const char *ptr; - if (!s) - { - pwc = 0; - s = ""; - n = 1; - } - - if (pwc) - *pwc = 0; - - for (ptr = s; ptr < s + n; ptr++) - { - if (!grub_utf8_process (*ptr, &ps->code, &ps->count)) - return -1; - if (ps->count) - continue; - if (pwc) - *pwc = ps->code; - if (ps->code == 0) - return 0; - return ptr - s + 1; - } - return -2; -} - -static inline int -mbsinit(const mbstate_t *ps) -{ - return ps->count == 0; -} - -static inline size_t -wcrtomb (char *s, wchar_t wc, mbstate_t *ps __attribute__ ((unused))) -{ - if (s == 0) - return 1; - return grub_encode_utf8_character ((grub_uint8_t *) s, - (grub_uint8_t *) s + MB_LEN_MAX, - wc); -} - -static inline wint_t btowc (int c) -{ - if (c & ~0x7f) - return WEOF; - return c; -} - - -static inline int -wcscoll (const wchar_t *s1, const wchar_t *s2) -{ - while (*s1 && *s2) - { - if (*s1 != *s2) - break; - - s1++; - s2++; - } - - if (*s1 < *s2) - return -1; - if (*s1 > *s2) - return +1; - return 0; -} - -#endif diff --git a/grub-core/lib/posix_wrap/wctype.h b/grub-core/lib/posix_wrap/wctype.h deleted file mode 100644 index cc9faf554..000000000 --- a/grub-core/lib/posix_wrap/wctype.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_POSIX_WCTYPE_H -#define GRUB_POSIX_WCTYPE_H 1 - -#include -#include - -#define wctype_t grub_posix_wctype_t - -typedef enum { GRUB_CTYPE_INVALID, - GRUB_CTYPE_ALNUM, GRUB_CTYPE_CNTRL, GRUB_CTYPE_LOWER, - GRUB_CTYPE_SPACE, GRUB_CTYPE_ALPHA, GRUB_CTYPE_DIGIT, - GRUB_CTYPE_PRINT, GRUB_CTYPE_UPPER, GRUB_CTYPE_BLANK, - GRUB_CTYPE_GRAPH, GRUB_CTYPE_PUNCT, GRUB_CTYPE_XDIGIT, - GRUB_CTYPE_MAX} wctype_t; - -#define CHARCLASS_NAME_MAX (sizeof ("xdigit") - 1) - -static inline wctype_t -wctype (const char *name) -{ - wctype_t i; - static const char names[][10] = { "", - "alnum", "cntrl", "lower", - "space", "alpha", "digit", - "print", "upper", "blank", - "graph", "punct", "xdigit" }; - for (i = GRUB_CTYPE_INVALID; i < GRUB_CTYPE_MAX; i++) - if (grub_strcmp (names[i], name) == 0) - return i; - return GRUB_CTYPE_INVALID; -} - -/* FIXME: take into account international lowercase characters. */ -static inline int -iswlower (wint_t wc) -{ - return grub_islower (wc); -} - -static inline wint_t -towlower (wint_t c) -{ - return grub_tolower (c); -} - -static inline wint_t -towupper (wint_t c) -{ - return grub_toupper (c); -} - -static inline int -iswalnum (wint_t c) -{ - return grub_isalpha (c) || grub_isdigit (c); -} - -static inline int -iswctype (wint_t wc, wctype_t desc) -{ - switch (desc) - { - case GRUB_CTYPE_ALNUM: - return iswalnum (wc); - case GRUB_CTYPE_CNTRL: - return grub_iscntrl (wc); - case GRUB_CTYPE_LOWER: - return iswlower (wc); - case GRUB_CTYPE_SPACE: - return grub_isspace (wc); - case GRUB_CTYPE_ALPHA: - return grub_isalpha (wc); - case GRUB_CTYPE_DIGIT: - return grub_isdigit (wc); - case GRUB_CTYPE_PRINT: - return grub_isprint (wc); - case GRUB_CTYPE_UPPER: - return grub_isupper (wc); - case GRUB_CTYPE_BLANK: - return wc == ' ' || wc == '\t'; - case GRUB_CTYPE_GRAPH: - return grub_isgraph (wc); - case GRUB_CTYPE_PUNCT: - return grub_isprint (wc) && !grub_isspace (wc) && !iswalnum (wc); - case GRUB_CTYPE_XDIGIT: - return grub_isxdigit (wc); - default: - return 0; - } -} - -#endif diff --git a/grub-core/lib/powerpc/relocator.c b/grub-core/lib/powerpc/relocator.c deleted file mode 100644 index 15aeb0246..000000000 --- a/grub-core/lib/powerpc/relocator.c +++ /dev/null @@ -1,140 +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 . - */ - -#include -#include - -#include -#include -#include -#include - -#include -#include - -extern grub_uint8_t grub_relocator_forward_start; -extern grub_uint8_t grub_relocator_forward_end; -extern grub_uint8_t grub_relocator_backward_start; -extern grub_uint8_t grub_relocator_backward_end; - -#define REGW_SIZEOF (2 * sizeof (grub_uint32_t)) -#define JUMP_SIZEOF (sizeof (grub_uint32_t)) - -#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator_##x##_end \ - - &grub_relocator_##x##_start) -#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \ - + REGW_SIZEOF * 3) -grub_size_t grub_relocator_align = sizeof (grub_uint32_t); -grub_size_t grub_relocator_forward_size; -grub_size_t grub_relocator_backward_size; -grub_size_t grub_relocator_jumper_size = JUMP_SIZEOF + REGW_SIZEOF; - -void -grub_cpu_relocator_init (void) -{ - grub_relocator_forward_size = RELOCATOR_SIZEOF(forward); - grub_relocator_backward_size = RELOCATOR_SIZEOF(backward); -} - -static void -write_reg (int regn, grub_uint32_t val, void **target) -{ - /* lis r, val >> 16 */ - *(grub_uint32_t *) *target = - ((0x3c00 | (regn << 5)) << 16) | (val >> 16); - *target = ((grub_uint32_t *) *target) + 1; - /* ori r, r, val & 0xffff. */ - *(grub_uint32_t *) *target = (((0x6000 | regn << 5 | regn) << 16) - | (val & 0xffff)); - *target = ((grub_uint32_t *) *target) + 1; -} - -static void -write_jump (void **target) -{ - /* blr. */ - *(grub_uint32_t *) *target = 0x4e800020; - *target = ((grub_uint32_t *) *target) + 1; -} - -void -grub_cpu_relocator_jumper (void *rels, grub_addr_t addr) -{ - write_reg (GRUB_PPC_JUMP_REGISTER, addr, &rels); - write_jump (&rels); -} - -void -grub_cpu_relocator_backward (void *ptr0, void *src, void *dest, - grub_size_t size) -{ - void *ptr = ptr0; - write_reg (8, (grub_uint32_t) src, &ptr); - write_reg (9, (grub_uint32_t) dest, &ptr); - write_reg (10, (grub_uint32_t) size, &ptr); - grub_memcpy (ptr, &grub_relocator_backward_start, - RELOCATOR_SRC_SIZEOF (backward)); -} - -void -grub_cpu_relocator_forward (void *ptr0, void *src, void *dest, - grub_size_t size) -{ - void *ptr = ptr0; - write_reg (8, (grub_uint32_t) src, &ptr); - write_reg (9, (grub_uint32_t) dest, &ptr); - write_reg (10, (grub_uint32_t) size, &ptr); - grub_memcpy (ptr, &grub_relocator_forward_start, - RELOCATOR_SRC_SIZEOF (forward)); -} - -grub_err_t -grub_relocator32_boot (struct grub_relocator *rel, - struct grub_relocator32_state state) -{ - void *ptr; - grub_err_t err; - void *relst; - grub_size_t relsize; - grub_size_t stateset_size = 32 * REGW_SIZEOF + JUMP_SIZEOF; - unsigned i; - grub_relocator_chunk_t ch; - - err = grub_relocator_alloc_chunk_align (rel, &ch, 0, UP_TO_TOP32 (stateset_size), - stateset_size, sizeof (grub_uint32_t), - GRUB_RELOCATOR_PREFERENCE_NONE, 0); - if (err) - return err; - - ptr = get_virtual_current_address (ch); - for (i = 0; i < 32; i++) - write_reg (i, state.gpr[i], &ptr); - write_jump (&ptr); - - err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch), - &relst, &relsize); - if (err) - return err; - - grub_arch_sync_caches ((void *) relst, relsize); - - ((void (*) (void)) relst) (); - - /* Not reached. */ - return GRUB_ERR_NONE; -} diff --git a/grub-core/lib/powerpc/relocator_asm.S b/grub-core/lib/powerpc/relocator_asm.S deleted file mode 100644 index 355e9c8b4..000000000 --- a/grub-core/lib/powerpc/relocator_asm.S +++ /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 . - */ - -#include - - .p2align 4 /* force 16-byte alignment */ - -VARIABLE (grub_relocator_forward_start) - mr 3, 9 - mr 4, 10 - -copycont1: - lbz 11,0(8) - stb 11,0(9) - addi 8, 8, 0x1 - addi 9, 9, 0x1 - addi 10, 10, -1 - cmpwi 10, 0 - bne copycont1 - -#include "../../kern/powerpc/cache_flush.S" - -VARIABLE (grub_relocator_forward_end) - -VARIABLE (grub_relocator_backward_start) - mr 3, 9 - mr 4, 10 - - add 9, 9, 10 - add 8, 8, 10 - /* Backward movsl is implicitly off-by-one. compensate that. */ - addi 9, 9, -1 - addi 8, 8, -1 -copycont2: - lbz 11,0(8) - stb 11,0(9) - addi 8, 8, -1 - addi 9, 9, -1 - addi 10, 10, -1 - cmpwi 10, 0 - bne copycont2 - -#include "../../kern/powerpc/cache_flush.S" - -VARIABLE (grub_relocator_backward_end) diff --git a/grub-core/lib/priority_queue.c b/grub-core/lib/priority_queue.c deleted file mode 100644 index ba59dda79..000000000 --- a/grub-core/lib/priority_queue.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct grub_priority_queue -{ - grub_size_t elsize; - grub_size_t allocated; - grub_size_t used; - grub_comparator_t cmp; - void *els; -}; - -static inline void * -element (struct grub_priority_queue *pq, grub_size_t k) -{ - return ((grub_uint8_t *) pq->els) + k * pq->elsize; -} - -static inline void -swap (struct grub_priority_queue *pq, grub_size_t m, grub_size_t n) -{ - grub_uint8_t *p1, *p2; - grub_size_t l; - p1 = (grub_uint8_t *) element (pq, m); - p2 = (grub_uint8_t *) element (pq, n); - for (l = pq->elsize; l; l--, p1++, p2++) - { - grub_uint8_t t; - t = *p1; - *p1 = *p2; - *p2 = t; - } -} - -static inline grub_size_t -parent (grub_size_t v) -{ - return (v - 1) / 2; -} - -static inline grub_size_t -left_child (grub_size_t v) -{ - return 2 * v + 1; -} - -static inline grub_size_t -right_child (grub_size_t v) -{ - return 2 * v + 2; -} - -void * -grub_priority_queue_top (grub_priority_queue_t pq) -{ - if (!pq->used) - return 0; - return element (pq, 0); -} - -void -grub_priority_queue_destroy (grub_priority_queue_t pq) -{ - grub_free (pq->els); - grub_free (pq); -} - -grub_priority_queue_t -grub_priority_queue_new (grub_size_t elsize, - grub_comparator_t cmp) -{ - struct grub_priority_queue *ret; - void *els; - els = grub_calloc (8, elsize); - if (!els) - return 0; - ret = (struct grub_priority_queue *) grub_malloc (sizeof (*ret)); - if (!ret) - { - grub_free (els); - return 0; - } - ret->elsize = elsize; - ret->allocated = 8; - ret->used = 0; - ret->cmp = cmp; - ret->els = els; - return ret; -} - -/* Heap property: pq->cmp (element (pq, p), element (pq, parent (p))) <= 0. */ -grub_err_t -grub_priority_queue_push (grub_priority_queue_t pq, const void *el) -{ - grub_size_t p; - if (pq->used == pq->allocated) - { - void *els; - els = grub_realloc (pq->els, pq->elsize * 2 * pq->allocated); - if (!els) - return grub_errno; - pq->allocated *= 2; - pq->els = els; - } - pq->used++; - grub_memcpy (element (pq, pq->used - 1), el, pq->elsize); - for (p = pq->used - 1; p; p = parent (p)) - { - if (pq->cmp (element (pq, p), element (pq, parent (p))) <= 0) - break; - swap (pq, p, parent (p)); - } - - return GRUB_ERR_NONE; -} - -void -grub_priority_queue_pop (grub_priority_queue_t pq) -{ - grub_size_t p; - - swap (pq, 0, pq->used - 1); - pq->used--; - for (p = 0; left_child (p) < pq->used; ) - { - grub_size_t c; - if (pq->cmp (element (pq, left_child (p)), element (pq, p)) <= 0 - && (right_child (p) >= pq->used - || pq->cmp (element (pq, right_child (p)), element (pq, p)) <= 0)) - break; - if (right_child (p) >= pq->used - || pq->cmp (element (pq, left_child (p)), - element (pq, right_child (p))) > 0) - c = left_child (p); - else - c = right_child (p); - swap (pq, p, c); - p = c; - } -} - - diff --git a/grub-core/lib/progress.c b/grub-core/lib/progress.c deleted file mode 100644 index 4f4389dd5..000000000 --- a/grub-core/lib/progress.c +++ /dev/null @@ -1,148 +0,0 @@ -/* progress.c - show loading progress */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define UPDATE_INTERVAL 800 - -static grub_err_t -grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)), - unsigned offset __attribute__ ((unused)), - unsigned length, - char *buf __attribute__ ((unused)), void *data) -{ - static int call_depth = 0; - grub_uint64_t now; - static grub_uint64_t last_progress_update_time; - grub_file_t file = data; - const char *e; - file->progress_offset += length; - - if (call_depth) - return GRUB_ERR_NONE; - - e = grub_env_get ("enable_progress_indicator"); - if (e && e[0] == '0') { - return GRUB_ERR_NONE; - } - - call_depth = 1; - now = grub_get_time_ms (); - - if (((now - last_progress_update_time > UPDATE_INTERVAL) && - (file->progress_offset - file->offset > 0)) || - (file->progress_offset == file->size)) - { - static char buffer[80]; - struct grub_term_output *term; - const char *partial_file_name; - - unsigned long long percent; - grub_uint64_t current_speed; - - if (now - file->last_progress_time < 10) - current_speed = 0; - else - current_speed = grub_divmod64 ((file->progress_offset - - file->last_progress_offset) - * 100ULL * 1000ULL, - now - file->last_progress_time, 0); - - if (file->size == 0) - percent = 100; - else - percent = grub_divmod64 (100 * file->progress_offset, - file->size, 0); - - /* grub_net_fs_open() saves off partial file structure before name is initialized. - It already saves passed file name in net structure so just use it in this case. - */ - if (file->device->net) - partial_file_name = grub_strrchr (file->device->net->name, '/'); - else if (file->name) /* grub_file_open() may leave it as NULL */ - partial_file_name = grub_strrchr (file->name, '/'); - else - partial_file_name = NULL; - if (partial_file_name) - partial_file_name++; - else - partial_file_name = ""; - - file->estimated_speed = (file->estimated_speed + current_speed) >> 1; - - grub_snprintf (buffer, sizeof (buffer), " [ %.20s %s %llu%% ", - partial_file_name, - grub_get_human_size (file->progress_offset, - GRUB_HUMAN_SIZE_NORMAL), - (unsigned long long) percent); - - char *ptr = buffer + grub_strlen (buffer); - grub_snprintf (ptr, sizeof (buffer) - (ptr - buffer), "%s ]", - grub_get_human_size (file->estimated_speed, - GRUB_HUMAN_SIZE_SPEED)); - - grub_size_t len = grub_strlen (buffer); - FOR_ACTIVE_TERM_OUTPUTS (term) - { - if (term->progress_update_counter++ > term->progress_update_divisor - || (file->progress_offset == file->size - && term->progress_update_divisor - != (unsigned) GRUB_PROGRESS_NO_UPDATE)) - { - struct grub_term_coordinate old_pos = grub_term_getxy (term); - struct grub_term_coordinate new_pos = old_pos; - new_pos.x = grub_term_width (term) - len - 1; - - grub_term_gotoxy (term, new_pos); - grub_puts_terminal (buffer, term); - grub_term_gotoxy (term, old_pos); - - term->progress_update_counter = 0; - - if (term->refresh) - term->refresh (term); - } - } - - file->last_progress_offset = file->progress_offset; - file->last_progress_time = now; - last_progress_update_time = now; - } - call_depth = 0; - - return GRUB_ERR_NONE; -} - -GRUB_MOD_INIT(progress) -{ - grub_file_progress_hook = grub_file_progress_hook_real; -} - -GRUB_MOD_FINI(progress) -{ - grub_file_progress_hook = 0; -} diff --git a/grub-core/lib/random.c b/grub-core/lib/random.c deleted file mode 100644 index 43b966438..000000000 --- a/grub-core/lib/random.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2016 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -grub_err_t -grub_crypto_get_random (void *buffer, grub_size_t sz) -{ - /* This is an arbitrer between different methods. - TODO: Add more methods in the future. */ - /* TODO: Add some PRNG smartness to reduce damage from bad entropy. */ - if (grub_crypto_arch_get_random (buffer, sz)) - return GRUB_ERR_NONE; - return grub_error (GRUB_ERR_IO, "no random sources found"); -} - -static int -get_num_digits (int val) -{ - int ret = 0; - while (val != 0) - { - ret++; - val /= 10; - } - if (ret == 0) - return 1; - return ret; -} - -#pragma GCC diagnostic ignored "-Wformat-nonliteral" - -static grub_err_t -grub_cmd_hexdump_random (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) -{ - grub_size_t length = 64; - grub_err_t err; - void *buffer; - grub_uint8_t *ptr; - int stats[256]; - int i, digits = 2; - char template[10]; - - if (argc >= 1) - length = grub_strtoull (args[0], 0, 0); - - if (length == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "length pust be positive"); - - buffer = grub_malloc (length); - if (!buffer) - return grub_errno; - - err = grub_crypto_get_random (buffer, length); - if (err) - { - grub_free (buffer); - return err; - } - - hexdump (0, buffer, length); - grub_memset(stats, 0, sizeof(stats)); - for (ptr = buffer; ptr < (grub_uint8_t *) buffer + length; ptr++) - stats[*ptr]++; - grub_printf ("Statistics:\n"); - for (i = 0; i < 256; i++) - { - int z = get_num_digits (stats[i]); - if (z > digits) - digits = z; - } - - grub_snprintf (template, sizeof (template), "%%0%dd ", digits); - - for (i = 0; i < 256; i++) - { - grub_printf ("%s", template);//, stats[i]); - if ((i & 0xf) == 0xf) - grub_printf ("\n"); - } - - grub_free (buffer); - - return 0; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT (random) -{ - cmd = grub_register_command ("hexdump_random", grub_cmd_hexdump_random, - N_("[LENGTH]"), - N_("Hexdump random data.")); -} - -GRUB_MOD_FINI (random) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c deleted file mode 100644 index 562bd2e3e..000000000 --- a/grub-core/lib/reed_solomon.c +++ /dev/null @@ -1,502 +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 . - */ - -#ifdef TEST -#include -#include -#include -#define xcalloc calloc -#define xmalloc malloc -#define grub_memset memset -#define grub_memcpy memcpy -#endif - -#ifndef STANDALONE -#include -#endif - -#ifndef STANDALONE -#ifdef TEST -typedef unsigned int grub_size_t; -typedef unsigned char grub_uint8_t; -#else -#include -#include -#include -#include -#endif -#endif - -#define SECTOR_SIZE 512 -#define MAX_BLOCK_SIZE (200 * SECTOR_SIZE) - -#ifdef STANDALONE -#ifdef TEST -typedef unsigned int grub_size_t; -typedef unsigned char grub_uint8_t; -#else -#include -#include -#endif -#ifdef __i386__ -#define REED_SOLOMON_ATTRIBUTE __attribute__ ((regparm(3))) -#else -#define REED_SOLOMON_ATTRIBUTE -#endif -void -grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs) - REED_SOLOMON_ATTRIBUTE; -#else -#define REED_SOLOMON_ATTRIBUTE -#endif - -#define GF_SIZE 8 -typedef grub_uint8_t gf_single_t; -#define GF_POLYNOMIAL 0x1d -#define GF_INVERT2 0x8e -#if defined (STANDALONE) && !defined (TEST) - -#ifdef __APPLE__ -#define ATTRIBUTE_TEXT __attribute__ ((section("_text,_text"))) -#else -#define ATTRIBUTE_TEXT __attribute__ ((section(".text"))) -#endif - -static gf_single_t * const gf_powx ATTRIBUTE_TEXT = (void *) 0x100000; -static gf_single_t * const gf_powx_inv ATTRIBUTE_TEXT = (void *) 0x100200; -static int *const chosenstat ATTRIBUTE_TEXT = (void *) 0x100300; -static gf_single_t *const sigma ATTRIBUTE_TEXT = (void *) 0x100700; -static gf_single_t *const errpot ATTRIBUTE_TEXT = (void *) 0x100800; -static int *const errpos ATTRIBUTE_TEXT = (void *) 0x100900; -static gf_single_t *const sy ATTRIBUTE_TEXT = (void *) 0x100d00; -static gf_single_t *const mstat ATTRIBUTE_TEXT = (void *) 0x100e00; -static gf_single_t *const errvals ATTRIBUTE_TEXT = (void *) 0x100f00; -static gf_single_t *const eqstat ATTRIBUTE_TEXT = (void *) 0x101000; -/* Next available address: (void *) 0x112000. */ -#else - -static gf_single_t gf_powx[255 * 2]; -static gf_single_t gf_powx_inv[256]; -static int chosenstat[256]; -static gf_single_t sigma[256]; -static gf_single_t errpot[256]; -static int errpos[256]; -static gf_single_t sy[256]; -static gf_single_t mstat[256]; -static gf_single_t errvals[256]; -static gf_single_t eqstat[65536 + 256]; -#endif - -#if __GNUC__ == 12 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Warray-bounds" -#endif - -static gf_single_t -gf_mul (gf_single_t a, gf_single_t b) -{ - if (a == 0 || b == 0) - return 0; - return gf_powx[(int) gf_powx_inv[a] + (int) gf_powx_inv[b]]; -} - -static inline gf_single_t -gf_invert (gf_single_t a) -{ - return gf_powx[255 - (int) gf_powx_inv[a]]; -} - -static void -init_powx (void) -{ - int i; - grub_uint8_t cur = 1; - - gf_powx_inv[0] = 0; - for (i = 0; i < 255; i++) - { - gf_powx[i] = cur; - gf_powx[i + 255] = cur; - gf_powx_inv[cur] = i; - if (cur & (1ULL << (GF_SIZE - 1))) - cur = (cur << 1) ^ GF_POLYNOMIAL; - else - cur <<= 1; - } -} - -static gf_single_t -pol_evaluate (gf_single_t *pol, grub_size_t degree, int log_x) -{ - int i; - gf_single_t s = 0; - int log_xn = 0; - for (i = degree; i >= 0; i--) - { - if (pol[i]) - s ^= gf_powx[(int) gf_powx_inv[pol[i]] + log_xn]; - log_xn += log_x; - if (log_xn >= ((1 << GF_SIZE) - 1)) - log_xn -= ((1 << GF_SIZE) - 1); - } - return s; -} - -#if !defined (STANDALONE) -static void -rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs) -{ - gf_single_t *rs_polynomial; - int i, j; - gf_single_t *m; - m = xcalloc (s + rs, sizeof (gf_single_t)); - grub_memcpy (m, data, s * sizeof (gf_single_t)); - rs_polynomial = xcalloc (rs + 1, sizeof (gf_single_t)); - rs_polynomial[rs] = 1; - /* Multiply with X - a^r */ - for (j = 0; j < rs; j++) - { - for (i = 0; i < rs; i++) - if (rs_polynomial[i]) - rs_polynomial[i] = (rs_polynomial[i + 1] - ^ gf_powx[j + (int) gf_powx_inv[rs_polynomial[i]]]); - else - rs_polynomial[i] = rs_polynomial[i + 1]; - if (rs_polynomial[rs]) - rs_polynomial[rs] = gf_powx[j + (int) gf_powx_inv[rs_polynomial[rs]]]; - } - for (j = 0; j < s; j++) - if (m[j]) - { - gf_single_t f = m[j]; - for (i = 0; i <= rs; i++) - m[i+j] ^= gf_mul (rs_polynomial[i], f); - } - free (rs_polynomial); - grub_memcpy (data + s, m + s, rs * sizeof (gf_single_t)); - free (m); -} -#endif - -static void -gauss_eliminate (gf_single_t *eq, int n, int m, int *chosen) -{ - int i, j; - - for (i = 0 ; i < n; i++) - { - int nzidx; - int k; - gf_single_t r; - for (nzidx = 0; nzidx < m && (eq[i * (m + 1) + nzidx] == 0); - nzidx++); - if (nzidx == m) - continue; - chosen[i] = nzidx; - r = gf_invert (eq[i * (m + 1) + nzidx]); - for (j = 0; j < m + 1; j++) - eq[i * (m + 1) + j] = gf_mul (eq[i * (m + 1) + j], r); - for (j = i + 1; j < n; j++) - { - gf_single_t rr = eq[j * (m + 1) + nzidx]; - for (k = 0; k < m + 1; k++) - eq[j * (m + 1) + k] ^= gf_mul (eq[i * (m + 1) + k], rr); - } - } -} - -static void -gauss_solve (gf_single_t *eq, int n, int m, gf_single_t *sol) -{ - int i, j; - - for (i = 0; i < n; i++) - chosenstat[i] = -1; - for (i = 0; i < m; i++) - sol[i] = 0; - gauss_eliminate (eq, n, m, chosenstat); - for (i = n - 1; i >= 0; i--) - { - gf_single_t s = 0; - if (chosenstat[i] == -1) - continue; - for (j = 0; j < m; j++) - s ^= gf_mul (eq[i * (m + 1) + j], sol[j]); - s ^= eq[i * (m + 1) + m]; - sol[chosenstat[i]] = s; - } -} - -static void -rs_recover (gf_single_t *mm, grub_size_t s, grub_size_t rs) -{ - grub_size_t rs2 = rs / 2; - int errnum = 0; - int i, j; - - for (i = 0; i < (int) rs; i++) - sy[i] = pol_evaluate (mm, s + rs - 1, i); - - for (i = 0; i < (int) rs; i++) - if (sy[i] != 0) - break; - - /* No error detected. */ - if (i == (int) rs) - return; - - { - - for (i = 0; i < (int) rs2; i++) - for (j = 0; j < (int) rs2 + 1; j++) - eqstat[i * (rs2 + 1) + j] = sy[i+j]; - - for (i = 0; i < (int) rs2; i++) - sigma[i] = 0; - - gauss_solve (eqstat, rs2, rs2, sigma); - } - - for (i = 0; i < (int) (rs + s); i++) - if (pol_evaluate (sigma, rs2 - 1, 255 - i) == gf_powx[i]) - { - errpot[errnum] = gf_powx[i]; - errpos[errnum++] = s + rs - i - 1; - } - { - for (j = 0; j < errnum; j++) - eqstat[j] = 1; - eqstat[errnum] = sy[0]; - for (i = 1; i < (int) rs; i++) - { - for (j = 0; j < (int) errnum; j++) - eqstat[(errnum + 1) * i + j] = gf_mul (errpot[j], - eqstat[(errnum + 1) * (i - 1) - + j]); - eqstat[(errnum + 1) * i + errnum] = sy[i]; - } - - gauss_solve (eqstat, rs, errnum, errvals); - - for (i = 0; i < (int) errnum; i++) - mm[errpos[i]] ^= errvals[i]; - } -} - -static void -decode_block (gf_single_t *ptr, grub_size_t s, - gf_single_t *rptr, grub_size_t rs) -{ - int i, j; - for (i = 0; i < SECTOR_SIZE; i++) - { - grub_size_t ds = (s + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; - grub_size_t rr = (rs + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; - - /* Nothing to do. */ - if (!ds || !rr) - continue; - - for (j = 0; j < (int) ds; j++) - mstat[j] = ptr[SECTOR_SIZE * j + i]; - for (j = 0; j < (int) rr; j++) - mstat[j + ds] = rptr[SECTOR_SIZE * j + i]; - - rs_recover (mstat, ds, rr); - - for (j = 0; j < (int) ds; j++) - ptr[SECTOR_SIZE * j + i] = mstat[j]; - } -} - -#if __GNUC__ == 12 -#pragma GCC diagnostic pop -#endif - -#if !defined (STANDALONE) -static void -encode_block (gf_single_t *ptr, grub_size_t s, - gf_single_t *rptr, grub_size_t rs) -{ - int i, j; - for (i = 0; i < SECTOR_SIZE; i++) - { - grub_size_t ds = (s + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; - grub_size_t rr = (rs + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; - gf_single_t *m; - - if (!ds || !rr) - continue; - - m = xmalloc (ds + rr); - for (j = 0; j < ds; j++) - m[j] = ptr[SECTOR_SIZE * j + i]; - rs_encode (m, ds, rr); - for (j = 0; j < rr; j++) - rptr[SECTOR_SIZE * j + i] = m[j + ds]; - free (m); - } -} -#endif - -#if !defined (STANDALONE) -void -grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size, - grub_size_t redundancy) -{ - grub_size_t s = data_size; - grub_size_t rs = redundancy; - gf_single_t *ptr = buffer; - gf_single_t *rptr = ptr + s; - void *tmp; - - tmp = xmalloc (data_size); - grub_memcpy (tmp, buffer, data_size); - - /* Nothing to do. */ - if (!rs) - goto exit; - - init_powx (); - - while (s > 0) - { - grub_size_t tt; - grub_size_t cs, crs; - cs = s; - crs = rs; - tt = cs + crs; - if (tt > MAX_BLOCK_SIZE) - { - cs = ((cs * (MAX_BLOCK_SIZE / 512)) / tt) * 512; - crs = ((crs * (MAX_BLOCK_SIZE / 512)) / tt) * 512; - } - encode_block (ptr, cs, rptr, crs); - ptr += cs; - rptr += crs; - s -= cs; - rs -= crs; - } - -#ifndef TEST - assert (grub_memcmp (tmp, buffer, data_size) == 0); -#endif -exit: - free (tmp); -} -#endif - -void REED_SOLOMON_ATTRIBUTE -grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs) -{ - gf_single_t *ptr = ptr_; - gf_single_t *rptr = ptr + s; - grub_uint8_t *cptr; - - /* Nothing to do. */ - if (!rs) - return; - - for (cptr = rptr + rs - 1; cptr >= rptr; cptr--) - if (*cptr) - break; - if (rptr + rs - 1 - cptr > (grub_ssize_t) rs / 2) - return; - - init_powx (); - - while (s > 0) - { - grub_size_t tt; - grub_size_t cs, crs; - cs = s; - crs = rs; - tt = cs + crs; - if (tt > MAX_BLOCK_SIZE) - { - cs = ((cs * (MAX_BLOCK_SIZE / 512)) / tt) * 512; - crs = ((crs * (MAX_BLOCK_SIZE / 512)) / tt) * 512; - } - decode_block (ptr, cs, rptr, crs); - ptr += cs; - rptr += crs; - s -= cs; - rs -= crs; - } -} - -#ifdef TEST -int -main (int argc, char **argv) -{ - FILE *in, *out; - grub_size_t s, rs; - char *buf; - - grub_memset (gf_powx, 0xee, sizeof (gf_powx)); - grub_memset (gf_powx_inv, 0xdd, sizeof (gf_powx_inv)); - -#ifndef STANDALONE - init_powx (); -#endif - -#ifndef STANDALONE - in = grub_util_fopen ("tst.bin", "rb"); - if (!in) - return 1; - fseek (in, 0, SEEK_END); - s = ftell (in); - fseek (in, 0, SEEK_SET); - rs = 0x7007; - buf = xmalloc (s + rs + SECTOR_SIZE); - fread (buf, 1, s, in); - fclose (in); - - grub_reed_solomon_add_redundancy (buf, s, rs); - - out = grub_util_fopen ("tst_rs.bin", "wb"); - fwrite (buf, 1, s + rs, out); - fclose (out); -#else - out = grub_util_fopen ("tst_rs.bin", "rb"); - fseek (out, 0, SEEK_END); - s = ftell (out); - fseek (out, 0, SEEK_SET); - rs = 0x7007; - s -= rs; - - buf = xmalloc (s + rs + SECTOR_SIZE); - fread (buf, 1, s + rs, out); - fclose (out); -#endif -#if 1 - grub_memset (buf + 512 * 15, 0, 512); -#endif - - out = grub_util_fopen ("tst_dam.bin", "wb"); - fwrite (buf, 1, s + rs, out); - fclose (out); - grub_reed_solomon_recover (buf, s, rs); - - out = grub_util_fopen ("tst_rec.bin", "wb"); - fwrite (buf, 1, s, out); - fclose (out); - - return 0; -} -#endif diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c deleted file mode 100644 index 3306a1bb7..000000000 --- a/grub-core/lib/relocator.c +++ /dev/null @@ -1,1665 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct grub_relocator -{ - struct grub_relocator_chunk *chunks; - grub_phys_addr_t postchunks; - grub_phys_addr_t highestaddr; - grub_phys_addr_t highestnonpostaddr; - grub_size_t relocators_size; -}; - -struct grub_relocator_subchunk -{ - enum {CHUNK_TYPE_IN_REGION, CHUNK_TYPE_REGION_START, -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - CHUNK_TYPE_FIRMWARE, CHUNK_TYPE_LEFTOVER -#endif - } type; - grub_mm_region_t reg; - grub_phys_addr_t start; - grub_size_t size; - grub_size_t pre_size; - struct grub_relocator_extra_block *extra; -#if GRUB_RELOCATOR_HAVE_LEFTOVERS - struct grub_relocator_fw_leftover *pre, *post; -#endif -}; - -struct grub_relocator_chunk -{ - struct grub_relocator_chunk *next; - grub_phys_addr_t src; - void *srcv; - grub_phys_addr_t target; - grub_size_t size; - struct grub_relocator_subchunk *subchunks; - unsigned nsubchunks; -}; - -struct grub_relocator_extra_block -{ - struct grub_relocator_extra_block *next; - struct grub_relocator_extra_block **prev; - grub_phys_addr_t start; - grub_phys_addr_t end; -}; - -#if GRUB_RELOCATOR_HAVE_LEFTOVERS -struct grub_relocator_fw_leftover -{ - struct grub_relocator_fw_leftover *next; - struct grub_relocator_fw_leftover **prev; - grub_phys_addr_t quantstart; - grub_uint8_t freebytes[GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT / 8]; -}; - -static struct grub_relocator_fw_leftover *leftovers; -#endif - -static struct grub_relocator_extra_block *extra_blocks; - -void * -get_virtual_current_address (grub_relocator_chunk_t in) -{ - return in->srcv; -} - -grub_phys_addr_t -get_physical_target_address (grub_relocator_chunk_t in) -{ - return in->target; -} - -struct grub_relocator * -grub_relocator_new (void) -{ - struct grub_relocator *ret; - - grub_cpu_relocator_init (); - - ret = grub_zalloc (sizeof (struct grub_relocator)); - if (!ret) - return NULL; - - ret->postchunks = ~(grub_phys_addr_t) 0; - ret->relocators_size = grub_relocator_jumper_size; - grub_dprintf ("relocator", "relocators_size=%lu\n", - (unsigned long) ret->relocators_size); - return ret; -} - -#define DIGITSORT_BITS 8 -#define DIGITSORT_MASK ((1 << DIGITSORT_BITS) - 1) -#define BITS_IN_BYTE 8 - -#define max(a, b) (((a) > (b)) ? (a) : (b)) -#define min(a, b) (((a) < (b)) ? (a) : (b)) - -static inline int -is_start (int type) -{ - return !(type & 1) && (type != COLLISION_START); -} - -static void -allocate_regstart (grub_phys_addr_t addr, grub_size_t size, grub_mm_region_t rb, - grub_mm_region_t *regancestor, grub_mm_header_t hancestor) -{ - grub_addr_t newreg_start, newreg_raw_start - = (grub_addr_t) rb + (addr - grub_vtop (rb)) + size; - grub_addr_t newreg_size, newreg_presize; - grub_mm_header_t new_header; - grub_mm_header_t hb = (grub_mm_header_t) (rb + 1); - -#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF - grub_dprintf ("relocator", "ra = %p, rb = %p\n", regancestor, rb); -#endif - newreg_start = ALIGN_UP (newreg_raw_start, GRUB_MM_ALIGN); - newreg_presize = newreg_start - newreg_raw_start; - newreg_size = rb->size - (newreg_start - (grub_addr_t) rb); - if ((hb->size << GRUB_MM_ALIGN_LOG2) >= newreg_start - - (grub_addr_t) rb) - { - grub_mm_header_t newhnext = hb->next; - grub_size_t newhsize = ((hb->size << GRUB_MM_ALIGN_LOG2) - - (newreg_start - - (grub_addr_t) rb)) >> GRUB_MM_ALIGN_LOG2; - new_header = (void *) (newreg_start + sizeof (*rb)); - if (newhnext == hb) - newhnext = new_header; - new_header->next = newhnext; - new_header->size = newhsize; - new_header->magic = GRUB_MM_FREE_MAGIC; - } - else - { - new_header = hb->next; - if (new_header == hb) - new_header = (void *) (newreg_start + sizeof (*rb)); - } - { - struct grub_mm_header *newregfirst = rb->first; - struct grub_mm_region *newregnext = rb->next; - struct grub_mm_region *newreg = (void *) newreg_start; - hancestor->next = new_header; - if (newregfirst == hb) - newregfirst = new_header; - newreg->first = newregfirst; - newreg->next = newregnext; - newreg->pre_size = newreg_presize; - newreg->size = newreg_size; - *regancestor = newreg; - { - grub_mm_header_t h = newreg->first, hp = NULL; - do - { - if ((void *) h < (void *) (newreg + 1)) - grub_fatal ("Failed to adjust memory region: %p, %p, %p, %p, %p", - newreg, newreg->first, h, hp, hb); -#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF - if ((void *) h == (void *) (newreg + 1)) - grub_dprintf ("relocator", - "Free start memory region: %p, %p, %p, %p, %p", - newreg, newreg->first, h, hp, hb); -#endif - hp = h; - h = h->next; - } - while (h != newreg->first); - } - } -} - -static void -allocate_inreg (grub_phys_addr_t paddr, grub_size_t size, - grub_mm_header_t hb, grub_mm_header_t hbp, - grub_mm_region_t rb) -{ - struct grub_mm_header *foll = NULL; - grub_addr_t vaddr = (grub_addr_t) hb + (paddr - grub_vtop (hb)); - -#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF - grub_dprintf ("relocator", "inreg paddr = 0x%lx, size = %lu," - " hb = %p, hbp = %p, rb = %p, vaddr = 0x%lx\n", - (unsigned long) paddr, (unsigned long) size, hb, hbp, - rb, (unsigned long) vaddr); -#endif - - if (ALIGN_UP (vaddr + size, GRUB_MM_ALIGN) + GRUB_MM_ALIGN - <= (grub_addr_t) (hb + hb->size)) - { - foll = (void *) ALIGN_UP (vaddr + size, GRUB_MM_ALIGN); - foll->magic = GRUB_MM_FREE_MAGIC; - foll->size = hb + hb->size - foll; -#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF - grub_dprintf ("relocator", "foll = %p, foll->size = %lu\n", foll, - (unsigned long) foll->size); -#endif - } - - if (vaddr - (grub_addr_t) hb >= sizeof (*hb)) - { - hb->size = ((vaddr - (grub_addr_t) hb) >> GRUB_MM_ALIGN_LOG2); - if (foll) - { - foll->next = hb; - hbp->next = foll; - if (rb->first == hb) - { - rb->first = foll; - } - } - } - else - { - if (foll) - { - foll->next = hb->next; - } - else - foll = hb->next; - - hbp->next = foll; - if (rb->first == hb) - { - rb->first = foll; - } - if (rb->first == hb) - { - rb->first = (void *) (rb + 1); - } - } -} - -#if GRUB_RELOCATOR_HAVE_LEFTOVERS -static void -check_leftover (struct grub_relocator_fw_leftover *lo) -{ - unsigned i; - for (i = 0; i < sizeof (lo->freebytes); i++) - if (lo->freebytes[i] != 0xff) - return; - grub_relocator_firmware_free_region (lo->quantstart, - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); - *lo->prev = lo->next; - if (lo->next) - lo->next->prev = lo->prev; -} -#endif - -static void -free_subchunk (const struct grub_relocator_subchunk *subchu) -{ - switch (subchu->type) - { - case CHUNK_TYPE_REGION_START: - { - grub_mm_region_t r1, r2, *rp; - grub_mm_header_t h; - grub_size_t pre_size; - r1 = subchu->reg; - r2 = (grub_mm_region_t) ALIGN_UP ((grub_addr_t) subchu->reg - + (grub_vtop (subchu->reg) - - subchu->start) + subchu->size, - GRUB_MM_ALIGN); - for (rp = &grub_mm_base; *rp && *rp != r2; rp = &((*rp)->next)); - pre_size = subchu->pre_size; - - if (*rp) - { - grub_mm_header_t h2, *hp; - r1->first = r2->first; - r1->next = r2->next; - r1->pre_size = pre_size; - r1->size = r2->size + (r2 - r1) * sizeof (*r2); - *rp = r1; - h = (grub_mm_header_t) (r1 + 1); - h->next = r2->first; - h->magic = GRUB_MM_FREE_MAGIC; - h->size = (r2 - r1 - 1); - for (hp = &r2->first, h2 = *hp; h2->next != r2->first; - hp = &(h2->next), h2 = *hp) - if (h2 == (grub_mm_header_t) (r2 + 1)) - break; - if (h2 == (grub_mm_header_t) (r2 + 1)) - { - h->size = h2->size + (h2 - h); - h->next = h2->next; - *hp = h; - if (hp == &r2->first) - { - for (h2 = r2->first; h2->next != r2->first; h2 = h2->next); - h2->next = h; - } - } - else - { - h2->next = h; - } - } - else - { - r1->pre_size = pre_size; - r1->size = (r2 - r1) * sizeof (*r2); - /* Find where to insert this region. - Put a smaller one before bigger ones, - to prevent fragmentation. */ - for (rp = &grub_mm_base; *rp; rp = &((*rp)->next)) - if ((*rp)->size > r1->size) - break; - r1->next = *rp; - *rp = r1->next; - h = (grub_mm_header_t) (r1 + 1); - r1->first = h; - h->next = h; - h->magic = GRUB_MM_FREE_MAGIC; - h->size = (r2 - r1 - 1); - } - for (r2 = grub_mm_base; r2; r2 = r2->next) - if ((grub_addr_t) r2 + r2->size == (grub_addr_t) r1) - break; - if (r2) - { - grub_mm_header_t hl2, hl, g; - g = (grub_mm_header_t) ((grub_addr_t) r2 + r2->size); - g->size = (grub_mm_header_t) r1 - g; - r2->size += r1->size; - for (hl = r2->first; hl->next != r2->first; hl = hl->next); - for (hl2 = r1->first; hl2->next != r1->first; hl2 = hl2->next); - hl2->next = r2->first; - r2->first = r1->first; - hl->next = r2->first; - *rp = (*rp)->next; - grub_free (g + 1); - } - break; - } - case CHUNK_TYPE_IN_REGION: - { - grub_mm_header_t h = (grub_mm_header_t) ALIGN_DOWN ((grub_addr_t) subchu->start, - GRUB_MM_ALIGN); - h->size - = ((subchu->start + subchu->size + GRUB_MM_ALIGN - 1) / GRUB_MM_ALIGN) - - (subchu->start / GRUB_MM_ALIGN) - 1; - h->next = h; - h->magic = GRUB_MM_ALLOC_MAGIC; - grub_free (h + 1); - break; - } -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - case CHUNK_TYPE_FIRMWARE: - case CHUNK_TYPE_LEFTOVER: - { - grub_addr_t fstart, fend; - fstart = ALIGN_UP (subchu->start, - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); - fend = ALIGN_DOWN (subchu->start + subchu->size, - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); - if (fstart < fend) - grub_relocator_firmware_free_region (fstart, fend - fstart); -#if GRUB_RELOCATOR_HAVE_LEFTOVERS - if (subchu->pre) - { - int off = subchu->start - fstart - - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; - grub_memset (subchu->pre->freebytes + off / 8 + 1, - 0xff, sizeof (subchu->pre->freebytes) - off / 8 - 1); - subchu->pre->freebytes[off / 8] |= ~((1 << (off % 8)) - 1); - check_leftover (subchu->pre); - } - if (subchu->post) - { - int off = subchu->start + subchu->size - fend; - grub_memset (subchu->pre->freebytes, - 0xff, sizeof (subchu->pre->freebytes) - off / 8); - subchu->pre->freebytes[off / 8] |= ((1 << (8 - (off % 8))) - 1); - check_leftover (subchu->post); - } -#endif - *subchu->extra->prev = subchu->extra->next; - grub_free (subchu->extra); - } - break; -#endif - } -} - -static int -malloc_in_range (struct grub_relocator *rel, - grub_addr_t start, grub_addr_t end, grub_addr_t align, - grub_size_t size, struct grub_relocator_chunk *res, - int from_low_priv, int collisioncheck) -{ - grub_mm_region_t r, *ra, base_saved; - struct grub_relocator_mmap_event *events = NULL, *eventt = NULL, *t; - /* 128 is just in case of additional malloc (shouldn't happen). */ - unsigned maxevents = 2 + 128; - grub_mm_header_t p, pa; - unsigned *counter; - int nallocs = 0; - unsigned j, N = 0; - grub_addr_t target = 0; - - grub_dprintf ("relocator", - "trying to allocate in 0x%lx-0x%lx aligned 0x%lx size 0x%lx\n", - (unsigned long) start, (unsigned long) end, - (unsigned long) align, (unsigned long) size); - - start = ALIGN_UP (start, align); - end = ALIGN_DOWN (end - size, align) + size; - - if (end < start + size) - return 0; - - /* We have to avoid any allocations when filling scanline events. - Hence 2-stages. - */ - for (r = grub_mm_base; r; r = r->next) - { - p = r->first; - do - { - if ((grub_addr_t) p < (grub_addr_t) (r + 1) - || (grub_addr_t) p >= (grub_addr_t) (r + 1) + r->size) - grub_fatal ("%d: out of range pointer: %p\n", __LINE__, p); - maxevents += 2; - p = p->next; - } - while (p != r->first); - maxevents += 4; - } - - if (collisioncheck && rel) - { - struct grub_relocator_chunk *chunk; - for (chunk = rel->chunks; chunk; chunk = chunk->next) - maxevents += 2; - } - -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - { - struct grub_relocator_extra_block *cur; - for (cur = extra_blocks; cur; cur = cur->next) - maxevents += 2; - } - for (r = grub_mm_base; r; r = r->next) - maxevents += 2; - - maxevents += grub_relocator_firmware_get_max_events (); -#endif - -#if GRUB_RELOCATOR_HAVE_LEFTOVERS - { - COMPILE_TIME_ASSERT (GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT % 8 == 0); - - struct grub_relocator_fw_leftover *cur; - for (cur = leftovers; cur; cur = cur->next) - { - int l = 0; - unsigned i; - for (i = 0; i < GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; i++) - { - if (l != ((cur->freebytes[i / 8] >> (i % 8)) & 1)) - maxevents++; - l = ((cur->freebytes[i / 8] >> (i % 8)) & 1); - } - if (l) - maxevents++; - } - } -#endif - - eventt = grub_calloc (maxevents, sizeof (events[0])); - counter = grub_malloc ((DIGITSORT_MASK + 2) * sizeof (counter[0])); - events = grub_calloc (maxevents, sizeof (events[0])); - if (!events || !eventt || !counter) - { - grub_dprintf ("relocator", "events or counter allocation failed %d\n", - maxevents); - grub_free (events); - grub_free (eventt); - grub_free (counter); - return 0; - } - - if (collisioncheck && rel) - { - struct grub_relocator_chunk *chunk; - for (chunk = rel->chunks; chunk; chunk = chunk->next) - { - events[N].type = COLLISION_START; - events[N].pos = chunk->target; - N++; - events[N].type = COLLISION_END; - events[N].pos = chunk->target + chunk->size; - N++; - } - } - -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - for (r = grub_mm_base; r; r = r->next) - { -#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF - grub_dprintf ("relocator", "Blocking at 0x%lx-0x%lx\n", - (unsigned long) r - r->pre_size, - (unsigned long) (r + 1) + r->size); -#endif - events[N].type = FIRMWARE_BLOCK_START; - events[N].pos = (grub_addr_t) r - r->pre_size; - N++; - events[N].type = FIRMWARE_BLOCK_END; - events[N].pos = (grub_addr_t) (r + 1) + r->size; - N++; - } - { - struct grub_relocator_extra_block *cur; - for (cur = extra_blocks; cur; cur = cur->next) - { -#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF - grub_dprintf ("relocator", "Blocking at 0x%lx-0x%lx\n", - (unsigned long) cur->start, (unsigned long) cur->end); -#endif - events[N].type = FIRMWARE_BLOCK_START; - events[N].pos = cur->start; - N++; - events[N].type = FIRMWARE_BLOCK_END; - events[N].pos = cur->end; - N++; - } - } - - N += grub_relocator_firmware_fill_events (events + N); - -#if GRUB_RELOCATOR_HAVE_LEFTOVERS - { - struct grub_relocator_fw_leftover *cur; - for (cur = leftovers; cur; cur = cur->next) - { - unsigned i; - int l = 0; - for (i = 0; i < GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; i++) - { - if (l != ((cur->freebytes[i / 8] >> (i % 8)) & 1)) - { - events[N].type = l ? REG_LEFTOVER_END : REG_LEFTOVER_START; - events[N].pos = cur->quantstart + i; - events[N].leftover = cur; - N++; - } - l = ((cur->freebytes[i / 8] >> (i % 8)) & 1); - } - if (l) - { - events[N].type = REG_LEFTOVER_END; - events[N].pos = cur->quantstart + i; - events[N].leftover = cur; - N++; - } - } - } -#endif -#endif - - /* No malloc from this point. */ - base_saved = grub_mm_base; - grub_mm_base = NULL; - - for (ra = &base_saved, r = *ra; r; ra = &(r->next), r = *ra) - { - pa = r->first; - p = pa->next; - if (p->magic == GRUB_MM_ALLOC_MAGIC) - continue; - do - { - if (p->magic != GRUB_MM_FREE_MAGIC) - grub_fatal ("%s:%d free magic broken at %p (0x%x)\n", - __FILE__, - __LINE__, p, p->magic); - if (p == (grub_mm_header_t) (r + 1)) - { - events[N].type = REG_BEG_START; - events[N].pos = grub_vtop (r) - r->pre_size; - events[N].reg = r; - events[N].regancestor = ra; - events[N].head = p; - events[N].hancestor = pa; - N++; - events[N].type = REG_BEG_END; - events[N].pos = grub_vtop (p + p->size) - sizeof (*r) - - sizeof (struct grub_mm_header); - N++; - } - else - { - events[N].type = IN_REG_START; - events[N].pos = grub_vtop (p); - events[N].head = p; - events[N].hancestor = pa; - events[N].reg = r; - N++; - events[N].type = IN_REG_END; - events[N].pos = grub_vtop (p + p->size); - N++; - } - pa = p; - p = pa->next; - } - while (pa != r->first); - } - - /* Put ending events after starting events. */ - { - int st = 0, e = N / 2; - for (j = 0; j < N; j++) - if (is_start (events[j].type) || events[j].type == COLLISION_START) - eventt[st++] = events[j]; - else - eventt[e++] = events[j]; - t = eventt; - eventt = events; - events = t; - } - - { - unsigned i; - for (i = 0; i < (BITS_IN_BYTE * sizeof (grub_addr_t) / DIGITSORT_BITS); - i++) - { - grub_memset (counter, 0, (1 + (1 << DIGITSORT_BITS)) * sizeof (counter[0])); - for (j = 0; j < N; j++) - counter[((events[j].pos >> (DIGITSORT_BITS * i)) - & DIGITSORT_MASK) + 1]++; - for (j = 0; j <= DIGITSORT_MASK; j++) - counter[j+1] += counter[j]; - for (j = 0; j < N; j++) - eventt[counter[((events[j].pos >> (DIGITSORT_BITS * i)) - & DIGITSORT_MASK)]++] = events[j]; - t = eventt; - eventt = events; - events = t; - } - } - -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - retry: -#endif - - /* Now events are nicely sorted. */ - { - int nstarted = 0, ncollisions = 0, nstartedfw = 0, nblockfw = 0; -#if GRUB_RELOCATOR_HAVE_LEFTOVERS - int nlefto = 0; -#else - const int nlefto = 0; -#endif - grub_addr_t starta = 0; - for (j = from_low_priv ? 0 : N - 1; from_low_priv ? j < N : (j + 1); - from_low_priv ? j++ : j--) - { - int isinsidebefore, isinsideafter; - isinsidebefore = (!ncollisions && (nstarted || (((nlefto || nstartedfw) - && !nblockfw)))); - switch (events[j].type) - { -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - case REG_FIRMWARE_START: - nstartedfw++; - break; - - case REG_FIRMWARE_END: - nstartedfw--; - break; - - case FIRMWARE_BLOCK_START: - nblockfw++; - break; - - case FIRMWARE_BLOCK_END: - nblockfw--; - break; -#endif - -#if GRUB_RELOCATOR_HAVE_LEFTOVERS - case REG_LEFTOVER_START: - nlefto++; - break; - - case REG_LEFTOVER_END: - nlefto--; - break; -#endif - - case COLLISION_START: - ncollisions++; - break; - - case COLLISION_END: - ncollisions--; - break; - - case IN_REG_START: - case REG_BEG_START: - nstarted++; - break; - - case IN_REG_END: - case REG_BEG_END: - nstarted--; - break; - } - isinsideafter = (!ncollisions && (nstarted || ((nlefto || nstartedfw) - && !nblockfw))); - if (from_low_priv) { - if (!isinsidebefore && isinsideafter) - starta = ALIGN_UP (events[j].pos, align); - - if (isinsidebefore && !isinsideafter) - { - target = starta; - if (target < start) - target = ALIGN_UP (start, align); - if (target + size <= end && target + size <= events[j].pos) - /* Found an usable address. */ - goto found; - } - } else { - if (!isinsidebefore && isinsideafter) - { - if (events[j].pos >= size) - starta = ALIGN_DOWN (events[j].pos - size, align) + size; - else - starta = 0; - } - if (isinsidebefore && !isinsideafter && starta >= size) - { - target = starta - size; - if (target > end - size) - target = ALIGN_DOWN (end - size, align); - if (target >= start && target >= events[j].pos) - goto found; - } - } - } - } - - grub_mm_base = base_saved; - grub_free (events); - grub_free (eventt); - grub_free (counter); - return 0; - - found: - { - int inreg = 0, regbeg = 0, ncol = 0; -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - int fwin = 0, fwb = 0, fwlefto = 0; -#endif -#if GRUB_RELOCATOR_HAVE_LEFTOVERS - int last_lo = 0; -#endif - int last_start = 0; - for (j = 0; j < N; j++) - { - int typepre; - if (ncol) - typepre = -1; - else if (regbeg) - typepre = CHUNK_TYPE_REGION_START; - else if (inreg) - typepre = CHUNK_TYPE_IN_REGION; -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - else if (fwin && !fwb) - typepre = CHUNK_TYPE_FIRMWARE; - else if (fwlefto && !fwb) - typepre = CHUNK_TYPE_LEFTOVER; -#endif - else - typepre = -1; - - if (j != 0 && events[j - 1].pos != events[j].pos) - { - grub_addr_t alloc_start, alloc_end; - alloc_start = max (events[j - 1].pos, target); - alloc_end = min (events[j].pos, target + size); - if (alloc_end > alloc_start) - { - switch (typepre) - { - case CHUNK_TYPE_REGION_START: - allocate_regstart (alloc_start, alloc_end - alloc_start, - events[last_start].reg, - events[last_start].regancestor, - events[last_start].hancestor); - /* TODO: maintain a reverse lookup tree for hancestor. */ - { - unsigned k; - for (k = 0; k < N; k++) - if (events[k].hancestor == events[last_start].head) - events[k].hancestor = events[last_start].hancestor; - } - break; - case CHUNK_TYPE_IN_REGION: - allocate_inreg (alloc_start, alloc_end - alloc_start, - events[last_start].head, - events[last_start].hancestor, - events[last_start].reg); - { - unsigned k; - for (k = 0; k < N; k++) - if (events[k].hancestor == events[last_start].head) - events[k].hancestor = events[last_start].hancestor; - } - break; -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - case CHUNK_TYPE_FIRMWARE: - { - grub_addr_t fstart, fend; - fstart - = ALIGN_DOWN (alloc_start, - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); - fend - = ALIGN_UP (alloc_end, - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); -#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF - grub_dprintf ("relocator", "requesting %lx-%lx\n", - (unsigned long) fstart, - (unsigned long) fend); -#endif - /* The failure here can be very expensive. */ - if (!grub_relocator_firmware_alloc_region (fstart, - fend - fstart)) - { - if (from_low_priv) - start = fend; - else - end = fstart; - goto retry; - } - break; - } -#endif - -#if GRUB_RELOCATOR_HAVE_LEFTOVERS - case CHUNK_TYPE_LEFTOVER: - { - unsigned offstart = alloc_start - % GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; - unsigned offend = alloc_end - % GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; - struct grub_relocator_fw_leftover *lo - = events[last_lo].leftover; - if (offend == 0 && alloc_end != alloc_start) - offend = GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; - lo->freebytes[offstart / 8] - &= ((1 << (8 - (start % 8))) - 1); - if (offend / 8 > (offstart + 7) / 8) - grub_memset (lo->freebytes + (offstart + 7) / 8, 0, - offend / 8 - (offstart + 7) / 8); - if (offend < GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT) - lo->freebytes[offend / 8] &= ~((1 << (offend % 8)) - 1); - } - break; -#endif - } - nallocs++; - } - } - - switch (events[j].type) - { - case REG_BEG_START: - case IN_REG_START: - if (events[j].type == REG_BEG_START && - (grub_addr_t) (events[j].reg + 1) > target) - regbeg++; - else - inreg++; - last_start = j; - break; - - case REG_BEG_END: - case IN_REG_END: - if (regbeg) - regbeg--; - else - inreg--; - break; - -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - case REG_FIRMWARE_START: - fwin++; - break; - - case REG_FIRMWARE_END: - fwin--; - break; - - case FIRMWARE_BLOCK_START: - fwb++; - break; - - case FIRMWARE_BLOCK_END: - fwb--; - break; -#endif - -#if GRUB_RELOCATOR_HAVE_LEFTOVERS - case REG_LEFTOVER_START: - fwlefto++; - last_lo = j; - break; - - case REG_LEFTOVER_END: - fwlefto--; - break; -#endif - case COLLISION_START: - ncol++; - break; - case COLLISION_END: - ncol--; - break; - } - - } - } - - /* Malloc is available again. */ - grub_mm_base = base_saved; - - grub_free (eventt); - grub_free (counter); - - { - int last_start = 0; - int inreg = 0, regbeg = 0, ncol = 0; -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - int fwin = 0, fwlefto = 0, fwb = 0; -#endif - unsigned cural = 0; - int oom = 0; - res->subchunks = grub_calloc (nallocs, sizeof (res->subchunks[0])); - if (!res->subchunks) - oom = 1; - res->nsubchunks = nallocs; - - for (j = 0; j < N; j++) - { - int typepre; - if (ncol) - typepre = -1; - else if (regbeg) - typepre = CHUNK_TYPE_REGION_START; - else if (inreg) - typepre = CHUNK_TYPE_IN_REGION; -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - else if (fwin && !fwb) - typepre = CHUNK_TYPE_FIRMWARE; - else if (fwlefto && !fwb) - typepre = CHUNK_TYPE_LEFTOVER; -#endif - else - typepre = -1; - - if (j != 0 && events[j - 1].pos != events[j].pos) - { - grub_addr_t alloc_start, alloc_end; - struct grub_relocator_subchunk tofree = {0}; - struct grub_relocator_subchunk *curschu = &tofree; - if (!oom) - curschu = &res->subchunks[cural]; - alloc_start = max (events[j - 1].pos, target); - alloc_end = min (events[j].pos, target + size); - if (alloc_end > alloc_start) - { -#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF - grub_dprintf ("relocator", "subchunk 0x%lx-0x%lx, %d\n", - (unsigned long) alloc_start, - (unsigned long) alloc_end, typepre); -#endif - curschu->type = typepre; - curschu->start = alloc_start; - curschu->size = alloc_end - alloc_start; - if (typepre == CHUNK_TYPE_REGION_START - || typepre == CHUNK_TYPE_IN_REGION) - { - curschu->reg = events[last_start].reg; - curschu->pre_size = alloc_start - events[j - 1].pos; - } - if (!oom && (typepre == CHUNK_TYPE_REGION_START -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - || typepre == CHUNK_TYPE_FIRMWARE -#endif - )) - { - struct grub_relocator_extra_block *ne; - ne = grub_malloc (sizeof (*ne)); - if (!ne) - { - oom = 1; - grub_memcpy (&tofree, curschu, sizeof (tofree)); - } - else - { - ne->start = alloc_start; - ne->end = alloc_end; - ne->next = extra_blocks; - ne->prev = &extra_blocks; - if (extra_blocks) - extra_blocks->prev = &(ne->next); - extra_blocks = ne; - curschu->extra = ne; - } - } - -#if GRUB_RELOCATOR_HAVE_LEFTOVERS - if (!oom && typepre == CHUNK_TYPE_FIRMWARE) - { - grub_addr_t fstart, fend; - - fstart - = ALIGN_DOWN (alloc_start, - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); - fend - = ALIGN_UP (alloc_end, - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); - - { - struct grub_relocator_fw_leftover *lo1 = NULL; - struct grub_relocator_fw_leftover *lo2 = NULL; - if (fstart != alloc_start) - lo1 = grub_malloc (sizeof (*lo1)); - if (fend != alloc_end) - lo2 = grub_malloc (sizeof (*lo2)); - if ((!lo1 && fstart != alloc_start) - || (!lo2 && fend != alloc_end)) - { - struct grub_relocator_extra_block *ne; - grub_free (lo1); - grub_free (lo2); - lo1 = NULL; - lo2 = NULL; - oom = 1; - grub_memcpy (&tofree, curschu, sizeof (tofree)); - ne = extra_blocks; - extra_blocks = extra_blocks->next; - grub_free (ne); - } - if (lo1) - { - lo1->quantstart = fstart; - grub_memset (lo1->freebytes, 0xff, - (alloc_start - fstart) / 8); - lo1->freebytes[(alloc_start - fstart) / 8] - = (1 << ((alloc_start - fstart) % 8)) - 1; - grub_memset (lo1->freebytes - + ((alloc_start - fstart) / 8) + 1, 0, - sizeof (lo1->freebytes) - - (alloc_start - fstart) / 8 - 1); - lo1->next = leftovers; - lo1->prev = &leftovers; - if (leftovers) - leftovers->prev = &lo1->next; - leftovers = lo1; - } - if (lo2) - { - lo2->quantstart - = fend - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; - grub_memset (lo2->freebytes, 0, - (alloc_end - lo2->quantstart) / 8); - lo2->freebytes[(alloc_end - lo2->quantstart) / 8] - = ~((1 << ((alloc_end - lo2->quantstart) % 8)) - 1); - grub_memset (lo2->freebytes - + ((alloc_end - lo2->quantstart) / 8) - + 1, 0, sizeof (lo2->freebytes) - - (alloc_end - lo2->quantstart) / 8 - 1); - lo2->prev = &leftovers; - if (leftovers) - leftovers->prev = &lo2->next; - lo2->next = leftovers; - leftovers = lo2; - } - curschu->pre = lo1; - curschu->post = lo2; - } - } - - if (typepre == CHUNK_TYPE_LEFTOVER) - { - curschu->pre = events[last_start].leftover; - curschu->post = events[last_start].leftover; - } -#endif - - if (!oom) - cural++; - else - free_subchunk (&tofree); - } - } - - switch (events[j].type) - { - case REG_BEG_START: - case IN_REG_START: - if (events[j].type == REG_BEG_START && - (grub_addr_t) (events[j].reg + 1) > target) - regbeg++; - else - inreg++; - last_start = j; - break; - - case REG_BEG_END: - case IN_REG_END: - inreg = regbeg = 0; - break; - -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - case REG_FIRMWARE_START: - fwin++; - break; - - case REG_FIRMWARE_END: - fwin--; - break; - - case FIRMWARE_BLOCK_START: - fwb++; - break; - - case FIRMWARE_BLOCK_END: - fwb--; - break; -#endif - -#if GRUB_RELOCATOR_HAVE_LEFTOVERS - case REG_LEFTOVER_START: - fwlefto++; - break; - - case REG_LEFTOVER_END: - fwlefto--; - break; -#endif - case COLLISION_START: - ncol++; - break; - case COLLISION_END: - ncol--; - break; - } - } - if (oom) - { - unsigned i; - for (i = 0; i < cural; i++) - free_subchunk (&res->subchunks[i]); - grub_free (res->subchunks); - grub_dprintf ("relocator", "allocation failed with out-of-memory\n"); - grub_free (events); - - return 0; - } - } - - res->src = target; - res->size = size; - - grub_free (events); - - grub_dprintf ("relocator", "allocated: 0x%lx+0x%lx\n", (unsigned long) target, - (unsigned long) size); - - return 1; -} - -static void -adjust_limits (struct grub_relocator *rel, - grub_phys_addr_t *min_addr, grub_phys_addr_t *max_addr, - grub_phys_addr_t in_min, grub_phys_addr_t in_max) -{ - struct grub_relocator_chunk *chunk; - - *min_addr = 0; - *max_addr = rel->postchunks; - - /* Keep chunks in memory in the same order as they'll be after relocation. */ - for (chunk = rel->chunks; chunk; chunk = chunk->next) - { - if (chunk->target > in_max && chunk->src < *max_addr - && chunk->src < rel->postchunks) - *max_addr = chunk->src; - if (chunk->target + chunk->size <= in_min - && chunk->src + chunk->size > *min_addr - && chunk->src < rel->postchunks) - *min_addr = chunk->src + chunk->size; - } -} - -grub_err_t -grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, - grub_relocator_chunk_t *out, - grub_phys_addr_t target, grub_size_t size) -{ - struct grub_relocator_chunk *chunk; - grub_phys_addr_t min_addr = 0, max_addr; - - if (target > ~size) - return grub_error (GRUB_ERR_BUG, "address is out of range"); - - adjust_limits (rel, &min_addr, &max_addr, target, target); - - for (chunk = rel->chunks; chunk; chunk = chunk->next) - if ((chunk->target <= target && target < chunk->target + chunk->size) - || (target <= chunk->target && chunk->target < target + size)) - return grub_error (GRUB_ERR_BUG, "overlap detected"); - - chunk = grub_malloc (sizeof (struct grub_relocator_chunk)); - if (!chunk) - return grub_errno; - - grub_dprintf ("relocator", - "min_addr = 0x%llx, max_addr = 0x%llx, target = 0x%llx\n", - (unsigned long long) min_addr, (unsigned long long) max_addr, - (unsigned long long) target); - - do - { - /* A trick to improve Linux allocation. */ -#if defined (__i386__) || defined (__x86_64__) - if (target < 0x100000) - if (malloc_in_range (rel, rel->highestnonpostaddr, ~(grub_addr_t)0, 1, - size, chunk, 0, 1)) - { - if (rel->postchunks > chunk->src) - rel->postchunks = chunk->src; - break; - } -#endif - if (malloc_in_range (rel, target, max_addr, 1, size, chunk, 1, 0)) - break; - - if (malloc_in_range (rel, min_addr, target, 1, size, chunk, 0, 0)) - break; - - if (malloc_in_range (rel, rel->highestnonpostaddr, ~(grub_addr_t)0, 1, - size, chunk, 0, 1)) - { - if (rel->postchunks > chunk->src) - rel->postchunks = chunk->src; - break; - } - - grub_dprintf ("relocator", "not allocated\n"); - grub_free (chunk); - return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - } - while (0); - - grub_dprintf ("relocator", "allocated 0x%llx/0x%llx\n", - (unsigned long long) chunk->src, (unsigned long long) target); - - if (rel->highestaddr < target + size) - rel->highestaddr = target + size; - - if (rel->highestaddr < chunk->src + size) - rel->highestaddr = chunk->src + size; - - if (chunk->src < rel->postchunks) - { - if (rel->highestnonpostaddr < target + size) - rel->highestnonpostaddr = target + size; - - if (rel->highestnonpostaddr < chunk->src + size) - rel->highestnonpostaddr = chunk->src + size; - } - - grub_dprintf ("relocator", "relocators_size=%ld\n", - (unsigned long) rel->relocators_size); - - if (chunk->src < target) - rel->relocators_size += grub_relocator_backward_size; - if (chunk->src > target) - rel->relocators_size += grub_relocator_forward_size; - - grub_dprintf ("relocator", "relocators_size=%ld\n", - (unsigned long) rel->relocators_size); - - chunk->target = target; - chunk->size = size; - chunk->next = rel->chunks; - rel->chunks = chunk; - grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks, - rel->chunks->next); - - chunk->srcv = grub_map_memory (chunk->src, chunk->size); - *out = chunk; -#ifdef DEBUG_RELOCATOR - grub_memset (chunk->srcv, 0xfa, chunk->size); - grub_mm_check (); -#endif - return GRUB_ERR_NONE; -} - -/* Context for grub_relocator_alloc_chunk_align. */ -struct grub_relocator_alloc_chunk_align_ctx -{ - grub_phys_addr_t min_addr, max_addr; - grub_size_t size, align; - int preference; - struct grub_relocator_chunk *chunk; - int found; -}; - -/* Helper for grub_relocator_alloc_chunk_align. */ -static int -grub_relocator_alloc_chunk_align_iter (grub_uint64_t addr, grub_uint64_t sz, - grub_memory_type_t type, void *data) -{ - struct grub_relocator_alloc_chunk_align_ctx *ctx = data; - grub_uint64_t candidate; - - if (type != GRUB_MEMORY_AVAILABLE) - return 0; - candidate = ALIGN_UP (addr, ctx->align); - if (candidate < ctx->min_addr) - candidate = ALIGN_UP (ctx->min_addr, ctx->align); - if (candidate + ctx->size > addr + sz - || candidate > ALIGN_DOWN (ctx->max_addr, ctx->align)) - return 0; - if (ctx->preference == GRUB_RELOCATOR_PREFERENCE_HIGH) - candidate = ALIGN_DOWN (min (addr + sz - ctx->size, ctx->max_addr), - ctx->align); - if (!ctx->found || (ctx->preference == GRUB_RELOCATOR_PREFERENCE_HIGH - && candidate > ctx->chunk->target)) - ctx->chunk->target = candidate; - if (!ctx->found || (ctx->preference == GRUB_RELOCATOR_PREFERENCE_LOW - && candidate < ctx->chunk->target)) - ctx->chunk->target = candidate; - ctx->found = 1; - return 0; -} - -grub_err_t -grub_relocator_alloc_chunk_align (struct grub_relocator *rel, - grub_relocator_chunk_t *out, - grub_phys_addr_t min_addr, - grub_phys_addr_t max_addr, - grub_size_t size, grub_size_t align, - int preference, - int avoid_efi_boot_services) -{ - struct grub_relocator_alloc_chunk_align_ctx ctx = { - .min_addr = min_addr, - .max_addr = max_addr, - .size = size, - .align = align, - .preference = preference, - .found = 0 - }; - grub_addr_t min_addr2 = 0, max_addr2; - - if (size && (max_addr > ~size)) - max_addr = ~size + 1; - -#ifdef GRUB_MACHINE_PCBIOS - if (min_addr < 0x1000) - min_addr = 0x1000; -#endif - - grub_dprintf ("relocator", "chunks = %p\n", rel->chunks); - - ctx.chunk = grub_malloc (sizeof (struct grub_relocator_chunk)); - if (!ctx.chunk) - return grub_errno; - - if (malloc_in_range (rel, min_addr, max_addr, align, - size, ctx.chunk, - preference != GRUB_RELOCATOR_PREFERENCE_HIGH, 1)) - { - grub_dprintf ("relocator", "allocated 0x%llx/0x%llx\n", - (unsigned long long) ctx.chunk->src, - (unsigned long long) ctx.chunk->src); - grub_dprintf ("relocator", "chunks = %p\n", rel->chunks); - ctx.chunk->target = ctx.chunk->src; - ctx.chunk->size = size; - ctx.chunk->next = rel->chunks; - rel->chunks = ctx.chunk; - ctx.chunk->srcv = grub_map_memory (ctx.chunk->src, ctx.chunk->size); - *out = ctx.chunk; - return GRUB_ERR_NONE; - } - - adjust_limits (rel, &min_addr2, &max_addr2, min_addr, max_addr); - grub_dprintf ("relocator", "Adjusted limits from %lx-%lx to %lx-%lx\n", - (unsigned long) min_addr, (unsigned long) max_addr, - (unsigned long) min_addr2, (unsigned long) max_addr2); - - do - { - if (malloc_in_range (rel, min_addr2, max_addr2, align, - size, ctx.chunk, 1, 1)) - break; - - if (malloc_in_range (rel, rel->highestnonpostaddr, ~(grub_addr_t)0, 1, - size, ctx.chunk, 0, 1)) - { - if (rel->postchunks > ctx.chunk->src) - rel->postchunks = ctx.chunk->src; - break; - } - - grub_free (ctx.chunk); - return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - } - while (0); - - { -#ifdef GRUB_MACHINE_EFI - grub_efi_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx, - avoid_efi_boot_services); -#elif defined (__powerpc__) || defined (GRUB_MACHINE_XEN) - (void) avoid_efi_boot_services; - grub_machine_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx); -#else - (void) avoid_efi_boot_services; - grub_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx); -#endif - if (!ctx.found) - { - grub_free (ctx.chunk); - return grub_error (GRUB_ERR_BAD_OS, "couldn't find suitable memory target"); - } - } - while (1) - { - struct grub_relocator_chunk *chunk2; - for (chunk2 = rel->chunks; chunk2; chunk2 = chunk2->next) - if ((chunk2->target <= ctx.chunk->target - && ctx.chunk->target < chunk2->target + chunk2->size) - || (ctx.chunk->target <= chunk2->target && chunk2->target - < ctx.chunk->target + size)) - { - if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH) - ctx.chunk->target = ALIGN_DOWN (chunk2->target, align); - else - ctx.chunk->target = ALIGN_UP (chunk2->target + chunk2->size, - align); - break; - } - if (!chunk2) - break; - } - - grub_dprintf ("relocator", "relocators_size=%ld\n", - (unsigned long) rel->relocators_size); - - if (ctx.chunk->src < ctx.chunk->target) - rel->relocators_size += grub_relocator_backward_size; - if (ctx.chunk->src > ctx.chunk->target) - rel->relocators_size += grub_relocator_forward_size; - - grub_dprintf ("relocator", "relocators_size=%ld\n", - (unsigned long) rel->relocators_size); - - ctx.chunk->size = size; - ctx.chunk->next = rel->chunks; - rel->chunks = ctx.chunk; - grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks, - rel->chunks->next); - ctx.chunk->srcv = grub_map_memory (ctx.chunk->src, ctx.chunk->size); - *out = ctx.chunk; -#ifdef DEBUG_RELOCATOR - grub_memset (ctx.chunk->srcv, 0xfa, ctx.chunk->size); - grub_mm_check (); -#endif - return GRUB_ERR_NONE; -} - -void -grub_relocator_unload (struct grub_relocator *rel) -{ - struct grub_relocator_chunk *chunk, *next; - if (!rel) - return; - for (chunk = rel->chunks; chunk; chunk = next) - { - unsigned i; - for (i = 0; i < chunk->nsubchunks; i++) - free_subchunk (&chunk->subchunks[i]); - grub_unmap_memory (chunk->srcv, chunk->size); - next = chunk->next; - grub_free (chunk->subchunks); - grub_free (chunk); - } - grub_free (rel); -} - -grub_err_t -grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr, - void **relstart, grub_size_t *relsize) -{ - grub_uint8_t *rels; - grub_uint8_t *rels0; - struct grub_relocator_chunk *sorted; - grub_size_t nchunks = 0; - unsigned j; - struct grub_relocator_chunk movers_chunk; - - grub_dprintf ("relocator", "Preparing relocs (size=%ld)\n", - (unsigned long) rel->relocators_size); - - if (!malloc_in_range (rel, 0, ~(grub_addr_t)0 - rel->relocators_size + 1, - grub_relocator_align, - rel->relocators_size, &movers_chunk, 1, 1)) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - movers_chunk.srcv = rels = rels0 - = grub_map_memory (movers_chunk.src, movers_chunk.size); - - if (relsize) - *relsize = rel->relocators_size; - - grub_dprintf ("relocator", "Relocs allocated at %p\n", movers_chunk.srcv); - - { - unsigned i; - grub_size_t count[257]; - struct grub_relocator_chunk *from, *to, *tmp; - - grub_memset (count, 0, sizeof (count)); - - { - struct grub_relocator_chunk *chunk; - for (chunk = rel->chunks; chunk; chunk = chunk->next) - { - grub_dprintf ("relocator", "chunk %p->%p, 0x%lx\n", - (void *) chunk->src, (void *) chunk->target, - (unsigned long) chunk->size); - nchunks++; - count[(chunk->src & 0xff) + 1]++; - } - } - from = grub_calloc (nchunks, sizeof (sorted[0])); - to = grub_calloc (nchunks, sizeof (sorted[0])); - if (!from || !to) - { - grub_free (from); - grub_free (to); - return grub_errno; - } - - for (j = 0; j < 256; j++) - count[j+1] += count[j]; - - { - struct grub_relocator_chunk *chunk; - for (chunk = rel->chunks; chunk; chunk = chunk->next) - from[count[chunk->src & 0xff]++] = *chunk; - } - - for (i = 1; i < GRUB_CPU_SIZEOF_VOID_P; i++) - { - grub_memset (count, 0, sizeof (count)); - for (j = 0; j < nchunks; j++) - count[((from[j].src >> (8 * i)) & 0xff) + 1]++; - for (j = 0; j < 256; j++) - count[j+1] += count[j]; - for (j = 0; j < nchunks; j++) - to[count[(from[j].src >> (8 * i)) & 0xff]++] = from[j]; - tmp = to; - to = from; - from = tmp; - } - sorted = from; - grub_free (to); - } - - for (j = 0; j < nchunks; j++) - { - grub_dprintf ("relocator", "sorted chunk %p->%p, 0x%lx\n", - (void *) sorted[j].src, (void *) sorted[j].target, - (unsigned long) sorted[j].size); - if (sorted[j].src < sorted[j].target) - { - grub_cpu_relocator_backward ((void *) rels, - sorted[j].srcv, - grub_map_memory (sorted[j].target, - sorted[j].size), - sorted[j].size); - rels += grub_relocator_backward_size; - } - if (sorted[j].src > sorted[j].target) - { - grub_cpu_relocator_forward ((void *) rels, - sorted[j].srcv, - grub_map_memory (sorted[j].target, - sorted[j].size), - sorted[j].size); - rels += grub_relocator_forward_size; - } - if (sorted[j].src == sorted[j].target) - grub_arch_sync_caches (sorted[j].srcv, sorted[j].size); - } - grub_cpu_relocator_jumper ((void *) rels, (grub_addr_t) addr); - *relstart = rels0; - grub_free (sorted); - return GRUB_ERR_NONE; -} - -void -grub_mm_check_real (const char *file, int line) -{ - grub_mm_region_t r; - grub_mm_header_t p, pa; - - for (r = grub_mm_base; r; r = r->next) - { - pa = r->first; - p = pa->next; - if (p->magic == GRUB_MM_ALLOC_MAGIC) - continue; - do - { - if ((grub_addr_t) p < (grub_addr_t) (r + 1) - || (grub_addr_t) p >= (grub_addr_t) (r + 1) + r->size) - grub_fatal ("%s:%d: out of range pointer: %p\n", file, line, p); - if (p->magic != GRUB_MM_FREE_MAGIC) - grub_fatal ("%s:%d free magic broken at %p (0x%x)\n", file, - line, p, p->magic); - pa = p; - p = pa->next; - } - while (pa != r->first); - } -} diff --git a/grub-core/lib/riscv/setjmp.S b/grub-core/lib/riscv/setjmp.S deleted file mode 100644 index b48ef29ea..000000000 --- a/grub-core/lib/riscv/setjmp.S +++ /dev/null @@ -1,84 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - - .file "setjmp.S" - -GRUB_MOD_LICENSE "GPLv3+" - - .text - -#if __riscv_xlen == 64 -#define STORE_IDX(reg, idx) sd reg, (idx*8)(a0) -#define LOAD_IDX(reg, idx) ld reg, (idx*8)(a0) -#else -#define STORE_IDX(reg, idx) sw reg, (idx*4)(a0) -#define LOAD_IDX(reg, idx) lw reg, (idx*4)(a0) -#endif - -/* - * int grub_setjmp (grub_jmp_buf env) - */ -FUNCTION(grub_setjmp) - /* Preserve all callee-saved registers and the SP */ - STORE_IDX(s0, 0) - STORE_IDX(s1, 1) - STORE_IDX(s2, 2) - STORE_IDX(s3, 3) - STORE_IDX(s4, 4) - STORE_IDX(s5, 5) - STORE_IDX(s6, 6) - STORE_IDX(s7, 7) - STORE_IDX(s8, 8) - STORE_IDX(s9, 9) - STORE_IDX(s10, 10) - STORE_IDX(s11, 11) - STORE_IDX(ra, 12) - STORE_IDX(sp, 13) - li a0, 0 - ret - -/* - * int grub_longjmp (grub_jmp_buf env, int val) - */ -FUNCTION(grub_longjmp) - LOAD_IDX(s0, 0) - LOAD_IDX(s1, 1) - LOAD_IDX(s2, 2) - LOAD_IDX(s3, 3) - LOAD_IDX(s4, 4) - LOAD_IDX(s5, 5) - LOAD_IDX(s6, 6) - LOAD_IDX(s7, 7) - LOAD_IDX(s8, 8) - LOAD_IDX(s9, 9) - LOAD_IDX(s10, 10) - LOAD_IDX(s11, 11) - LOAD_IDX(ra, 12) - LOAD_IDX(sp, 13) - - /* Move the return value in place, but return 1 if passed 0. */ - beq a1, zero, longjmp_1 - mv a0, a1 - ret - - longjmp_1: - li a0, 1 - ret diff --git a/grub-core/lib/setjmp.S b/grub-core/lib/setjmp.S deleted file mode 100644 index ffb26df79..000000000 --- a/grub-core/lib/setjmp.S +++ /dev/null @@ -1,28 +0,0 @@ -/* An executable stack is not required for these functions. */ -#if defined (__linux__) && defined (__ELF__) -.section .note.GNU-stack,"",%progbits -#endif -#if defined(__i386__) -#include "./i386/setjmp.S" -#elif defined(__x86_64__) -#include "./x86_64/setjmp.S" -#elif defined(__sparc__) -#include "./sparc64/setjmp.S" -#elif defined(__mips__) -#include "./mips/setjmp.S" -#elif defined(__powerpc__) || defined(__PPC__) -#include "./powerpc/setjmp.S" -#elif defined(__ia64__) -#include "./ia64/setjmp.S" -#include "./ia64/longjmp.S" -#elif defined(__arm__) -#include "./arm/setjmp.S" -#elif defined(__aarch64__) -#include "./arm64/setjmp.S" -#elif defined(__loongarch_lp64) -#include "./loongarch64/setjmp.S" -#elif defined(__riscv) -#include "./riscv/setjmp.S" -#else -#error "Unknown target cpu type" -#endif diff --git a/grub-core/lib/syslinux_parse.c b/grub-core/lib/syslinux_parse.c deleted file mode 100644 index ae61a96dd..000000000 --- a/grub-core/lib/syslinux_parse.c +++ /dev/null @@ -1,1555 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -struct syslinux_say -{ - struct syslinux_say *next; - struct syslinux_say *prev; - char msg[0]; -}; - -struct initrd_list -{ - struct initrd_list *next; - char *file; -}; - -struct syslinux_menuentry -{ - struct syslinux_menuentry *next; - struct syslinux_menuentry *prev; - char *label; - char *extlabel; - char *kernel_file; - struct initrd_list *initrds; - struct initrd_list *initrds_last; - char *append; - char *argument; - char *help; - char *comments; - grub_size_t commentslen; - char hotkey; - int make_default; - struct syslinux_say *say; - - enum { KERNEL_NO_KERNEL, KERNEL_LINUX, KERNEL_CHAINLOADER, - KERNEL_BIN, KERNEL_PXE, KERNEL_CHAINLOADER_BPB, - KERNEL_COM32, KERNEL_COM, KERNEL_IMG, KERNEL_CONFIG, LOCALBOOT } - entry_type; -}; - -struct syslinux_menu -{ - struct syslinux_menu *parent; - struct syslinux_menuentry *entries; - char *def; - char *comments; - char *background; - const char *root_read_directory; - const char *root_target_directory; - const char *current_read_directory; - const char *current_target_directory; - const char *filename; - grub_size_t commentslen; - unsigned long timeout; - struct syslinux_say *say; - grub_syslinux_flavour_t flavour; -}; - -struct output_buffer -{ - grub_size_t alloc; - grub_size_t ptr; - char *buf; -}; - -static grub_err_t -syslinux_parse_real (struct syslinux_menu *menu); -static grub_err_t -config_file (struct output_buffer *outbuf, - const char *root, const char *target_root, - const char *cwd, const char *target_cwd, - const char *fname, struct syslinux_menu *parent, - grub_syslinux_flavour_t flav); -static grub_err_t -print_entry (struct output_buffer *outbuf, - struct syslinux_menu *menu, - const char *str); - -static grub_err_t -ensure_space (struct output_buffer *outbuf, grub_size_t len) -{ - grub_size_t newlen; - char *newbuf; - if (len < outbuf->alloc - outbuf->ptr) - return GRUB_ERR_NONE; - newlen = (outbuf->ptr + len + 10) * 2; - newbuf = grub_realloc (outbuf->buf, newlen); - if (!newbuf) - return grub_errno; - outbuf->alloc = newlen; - outbuf->buf = newbuf; - return GRUB_ERR_NONE; -} - -static grub_err_t -print (struct output_buffer *outbuf, const char *str, grub_size_t len) -{ - grub_err_t err; - err = ensure_space (outbuf, len); - if (err) - return err; - grub_memcpy (&outbuf->buf[outbuf->ptr], str, len); - outbuf->ptr += len; - return GRUB_ERR_NONE; -} - -static grub_err_t -add_comment (struct syslinux_menu *menu, const char *comment, int nl) -{ - if (menu->entries) - { - if (menu->entries->commentslen == 0 && *comment == 0) - return GRUB_ERR_NONE; - menu->entries->comments = grub_realloc (menu->entries->comments, - menu->entries->commentslen - + 2 + grub_strlen (comment)); - if (!menu->entries->comments) - return grub_errno; - menu->entries->commentslen - += grub_stpcpy (menu->entries->comments + menu->entries->commentslen, - comment) - - (menu->entries->comments + menu->entries->commentslen); - if (nl) - menu->entries->comments[menu->entries->commentslen++] = '\n'; - menu->entries->comments[menu->entries->commentslen] = '\0'; - } - else - { - if (menu->commentslen == 0 && *comment == 0) - return GRUB_ERR_NONE; - menu->comments = grub_realloc (menu->comments, menu->commentslen - + 2 + grub_strlen (comment)); - if (!menu->comments) - return grub_errno; - menu->commentslen += grub_stpcpy (menu->comments + menu->commentslen, - comment) - - (menu->comments + menu->commentslen); - if (nl) - menu->comments[menu->commentslen++] = '\n'; - menu->comments[menu->commentslen] = '\0'; - } - return GRUB_ERR_NONE; -} - - -#define print_string(x) do { err = print (outbuf, x, sizeof (x) - 1); if (err) return err; } while (0) - -static grub_err_t -print_num (struct output_buffer *outbuf, int n) -{ - char buf[20]; - grub_snprintf (buf, sizeof (buf), "%d", n); - return print (outbuf, buf, grub_strlen (buf)); -} - -static grub_err_t -label (const char *line, struct syslinux_menu *menu) -{ - struct syslinux_menuentry *entry; - - entry = grub_malloc (sizeof (*entry)); - if (!entry) - return grub_errno; - grub_memset (entry, 0, sizeof (*entry)); - entry->label = grub_strdup (line); - if (!entry->label) - { - grub_free (entry); - return grub_errno; - } - entry->next = menu->entries; - entry->prev = NULL; - if (menu->entries) - menu->entries->prev = entry; - menu->entries = entry; - return GRUB_ERR_NONE; -} - -static grub_err_t -kernel (const char *line, struct syslinux_menu *menu) -{ - const char *end = line + grub_strlen (line); - - if (!menu->entries) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); - - menu->entries->kernel_file = grub_strdup (line); - if (!menu->entries->kernel_file) - return grub_errno; - - menu->entries->entry_type = KERNEL_LINUX; - - if (end - line >= 2 && grub_strcmp (end - 2, ".0") == 0) - menu->entries->entry_type = KERNEL_PXE; - - if (end - line >= 4 && grub_strcasecmp (end - 4, ".bin") == 0) - menu->entries->entry_type = KERNEL_BIN; - - if (end - line >= 3 && grub_strcasecmp (end - 3, ".bs") == 0) - menu->entries->entry_type = KERNEL_CHAINLOADER; - - if (end - line >= 4 && grub_strcasecmp (end - 4, ".bss") == 0) - menu->entries->entry_type = KERNEL_CHAINLOADER_BPB; - - if (end - line >= 4 && grub_strcasecmp (end - 4, ".c32") == 0) - menu->entries->entry_type = KERNEL_COM32; - - if (end - line >= 4 && grub_strcasecmp (end - 4, ".cbt") == 0) - menu->entries->entry_type = KERNEL_COM; - - if (end - line >= 4 && grub_strcasecmp (end - 4, ".com") == 0) - menu->entries->entry_type = KERNEL_COM; - - if (end - line >= 4 && grub_strcasecmp (end - 4, ".img") == 0) - menu->entries->entry_type = KERNEL_IMG; - - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_linux (const char *line, struct syslinux_menu *menu) -{ - if (!menu->entries) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); - - menu->entries->kernel_file = grub_strdup (line); - if (!menu->entries->kernel_file) - return grub_errno; - menu->entries->entry_type = KERNEL_LINUX; - - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_boot (const char *line, struct syslinux_menu *menu) -{ - if (!menu->entries) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); - - menu->entries->kernel_file = grub_strdup (line); - if (!menu->entries->kernel_file) - return grub_errno; - menu->entries->entry_type = KERNEL_CHAINLOADER; - - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_bss (const char *line, struct syslinux_menu *menu) -{ - if (!menu->entries) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); - - menu->entries->kernel_file = grub_strdup (line); - if (!menu->entries->kernel_file) - return grub_errno; - menu->entries->entry_type = KERNEL_CHAINLOADER_BPB; - - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_pxe (const char *line, struct syslinux_menu *menu) -{ - if (!menu->entries) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); - - menu->entries->kernel_file = grub_strdup (line); - if (!menu->entries->kernel_file) - return grub_errno; - menu->entries->entry_type = KERNEL_PXE; - - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_fdimage (const char *line, struct syslinux_menu *menu) -{ - if (!menu->entries) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); - - menu->entries->kernel_file = grub_strdup (line); - if (!menu->entries->kernel_file) - return grub_errno; - menu->entries->entry_type = KERNEL_IMG; - - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_comboot (const char *line, struct syslinux_menu *menu) -{ - if (!menu->entries) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); - - menu->entries->kernel_file = grub_strdup (line); - if (!menu->entries->kernel_file) - return grub_errno; - menu->entries->entry_type = KERNEL_COM; - - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_com32 (const char *line, struct syslinux_menu *menu) -{ - if (!menu->entries) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); - - menu->entries->kernel_file = grub_strdup (line); - if (!menu->entries->kernel_file) - return grub_errno; - menu->entries->entry_type = KERNEL_COM32; - - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_config (const char *line, struct syslinux_menu *menu) -{ - const char *space; - if (!menu->entries) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); - - for (space = line; *space && !grub_isspace (*space); space++); - menu->entries->kernel_file = grub_strndup (line, space - line); - if (!menu->entries->kernel_file) - return grub_errno; - for (; *space && grub_isspace (*space); space++); - if (*space) - { - menu->entries->argument = grub_strdup (space); - if (!menu->entries->argument) - return grub_errno; - } - menu->entries->entry_type = KERNEL_CONFIG; - - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_append (const char *line, struct syslinux_menu *menu) -{ - if (!menu->entries) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); - - menu->entries->append = grub_strdup (line); - if (!menu->entries->append) - return grub_errno; - - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_initrd (const char *line, struct syslinux_menu *menu) -{ - struct initrd_list *ninitrd; - const char *comma; - if (!menu->entries) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); - - while (*line) - { - for (comma = line; *comma && *comma != ','; comma++); - - ninitrd = grub_malloc (sizeof (*ninitrd)); - if (!ninitrd) - return grub_errno; - ninitrd->file = grub_strndup (line, comma - line); - if (!ninitrd->file) - { - grub_free (ninitrd); - return grub_errno; - } - ninitrd->next = NULL; - if (menu->entries->initrds_last) - menu->entries->initrds_last->next = ninitrd; - else - { - menu->entries->initrds_last = ninitrd; - menu->entries->initrds = ninitrd; - } - - line = comma; - while (*line == ',') - line++; - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_default (const char *line, struct syslinux_menu *menu) -{ - menu->def = grub_strdup (line); - if (!menu->def) - return grub_errno; - - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_timeout (const char *line, struct syslinux_menu *menu) -{ - menu->timeout = grub_strtoul (line, NULL, 0); - - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_menudefault (const char *line __attribute__ ((unused)), - struct syslinux_menu *menu) -{ - if (!menu->entries) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); - - menu->entries->make_default = 1; - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_menubackground (const char *line, - struct syslinux_menu *menu) -{ - menu->background = grub_strdup (line); - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_localboot (const char *line, - struct syslinux_menu *menu) -{ - if (!menu->entries) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); - - menu->entries->kernel_file = grub_strdup (line); - if (!menu->entries->kernel_file) - return grub_errno; - menu->entries->entry_type = LOCALBOOT; - - return GRUB_ERR_NONE; -} - -static grub_err_t -cmd_extlabel (const char *line, struct syslinux_menu *menu) -{ - const char *in; - char *out; - - if (!menu->entries) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); - - menu->entries->extlabel = grub_malloc (grub_strlen (line) + 1); - if (!menu->entries->extlabel) - return grub_errno; - in = line; - out = menu->entries->extlabel; - while (*in) - { - if (in[0] == '^' && in[1]) - { - menu->entries->hotkey = grub_tolower (in[1]); - in++; - } - *out++ = *in++; - } - *out = 0; - - return GRUB_ERR_NONE; -} - - -static grub_err_t -cmd_say (const char *line, struct syslinux_menu *menu) -{ - struct syslinux_say *nsay; - nsay = grub_malloc (sizeof (*nsay) + grub_strlen (line) + 1); - if (!nsay) - return grub_errno; - nsay->prev = NULL; - if (menu->entries) - { - nsay->next = menu->entries->say; - menu->entries->say = nsay; - } - else - { - nsay->next = menu->say; - menu->say = nsay; - } - - if (nsay->next) - nsay->next->prev = nsay; - - grub_memcpy (nsay->msg, line, grub_strlen (line) + 1); - return GRUB_ERR_NONE; -} - -static char * -get_read_filename (struct syslinux_menu *menu, - const char *filename) -{ - return grub_xasprintf ("%s/%s", - filename[0] == '/' ? menu->root_read_directory - : menu->current_read_directory, filename); -} - -static char * -get_target_filename (struct syslinux_menu *menu, - const char *filename) -{ - return grub_xasprintf ("%s/%s", - filename[0] == '/' ? menu->root_target_directory - : menu->current_target_directory, filename); -} - -static grub_err_t -syslinux_parse (const char *filename, - struct syslinux_menu *menu) -{ - const char *old_filename = menu->filename; - grub_err_t ret; - char *nf; - nf = get_read_filename (menu, filename); - if (!nf) - return grub_errno; - menu->filename = nf; - ret = syslinux_parse_real (menu); - if (ret == GRUB_ERR_FILE_NOT_FOUND - || ret == GRUB_ERR_BAD_FILENAME) - { - grub_errno = ret = GRUB_ERR_NONE; - add_comment (menu, "# File ", 0); - add_comment (menu, nf, 0); - add_comment (menu, " not found", 1); - } - grub_free (nf); - menu->filename = old_filename; - return ret; -} - -struct -{ - const char *name1; - const char *name2; - grub_err_t (*parse) (const char *line, struct syslinux_menu *menu); -} commands[] = { - /* FIXME: support tagname. */ - {"include", NULL, syslinux_parse}, - {"menu", "include", syslinux_parse}, - {"label", NULL, label}, - {"kernel", NULL, kernel}, - {"linux", NULL, cmd_linux}, - {"boot", NULL, cmd_boot}, - {"bss", NULL, cmd_bss}, - {"pxe", NULL, cmd_pxe}, - {"fdimage", NULL, cmd_fdimage}, - {"comboot", NULL, cmd_comboot}, - {"com32", NULL, cmd_com32}, - {"config", NULL, cmd_config}, - {"append", NULL, cmd_append}, - /* FIXME: ipappend not supported. */ - {"localboot", NULL, cmd_localboot}, - {"initrd", NULL, cmd_initrd}, - {"default", NULL, cmd_default}, - {"menu", "label", cmd_extlabel}, - /* FIXME: MENU LABEL not supported. */ - /* FIXME: MENU HIDDEN not supported. */ - /* FIXME: MENU SEPARATOR not supported. */ - /* FIXME: MENU INDENT not supported. */ - /* FIXME: MENU DISABLE not supported. */ - /* FIXME: MENU HIDE not supported. */ - {"menu", "default", cmd_menudefault}, - /* FIXME: MENU PASSWD not supported. */ - /* FIXME: MENU MASTER PASSWD not supported. */ - {"menu", "background", cmd_menubackground}, - /* FIXME: MENU BEGIN not supported. */ - /* FIXME: MENU GOTO not supported. */ - /* FIXME: MENU EXIT not supported. */ - /* FIXME: MENU QUIT not supported. */ - /* FIXME: MENU START not supported. */ - /* FIXME: MENU AUTOBOOT not supported. */ - /* FIXME: MENU TABMSG not supported. */ - /* FIXME: MENU NOTABMSG not supported. */ - /* FIXME: MENU PASSPROMPT not supported. */ - /* FIXME: MENU COLOR not supported. */ - /* FIXME: MENU MSGCOLOR not supported. */ - /* FIXME: MENU WIDTH not supported. */ - /* FIXME: MENU MARGIN not supported. */ - /* FIXME: MENU PASSWORDMARGIN not supported. */ - /* FIXME: MENU ROWS not supported. */ - /* FIXME: MENU TABMSGROW not supported. */ - /* FIXME: MENU CMDLINEROW not supported. */ - /* FIXME: MENU ENDROW not supported. */ - /* FIXME: MENU PASSWORDROW not supported. */ - /* FIXME: MENU TIMEOUTROW not supported. */ - /* FIXME: MENU HELPMSGROW not supported. */ - /* FIXME: MENU HELPMSGENDROW not supported. */ - /* FIXME: MENU HIDDENROW not supported. */ - /* FIXME: MENU HSHIFT not supported. */ - /* FIXME: MENU VSHIFT not supported. */ - {"timeout", NULL, cmd_timeout}, - /* FIXME: TOTALTIMEOUT not supported. */ - /* FIXME: ONTIMEOUT not supported. */ - /* FIXME: ONERROR not supported. */ - /* FIXME: SERIAL not supported. */ - /* FIXME: CONSOLE not supported. */ - /* FIXME: FONT not supported. */ - /* FIXME: KBDMAP not supported. */ - {"say", NULL, cmd_say}, - /* FIXME: DISPLAY not supported. */ - /* FIXME: F* not supported. */ - - /* Commands to control interface behaviour which aren't needed with GRUB. - If they are important in your environment please contact GRUB team. - */ - {"prompt", NULL, NULL}, - {"nocomplete", NULL, NULL}, - {"noescape", NULL, NULL}, - {"implicit", NULL, NULL}, - {"allowoptions", NULL, NULL} -}; - -static grub_err_t -helptext (const char *line, grub_file_t file, struct syslinux_menu *menu) -{ - char *help; - char *buf = NULL; - grub_size_t helplen, alloclen = 0; - - help = grub_strdup (line); - if (!help) - return grub_errno; - helplen = grub_strlen (line); - while ((grub_free (buf), buf = grub_file_getline (file))) - { - char *ptr; - grub_size_t needlen; - for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); - if (grub_strncasecmp (ptr, "endtext", sizeof ("endtext") - 1) == 0) - { - ptr += sizeof ("endtext") - 1; - for (; *ptr && (grub_isspace (*ptr) || *ptr == '\n' || *ptr == '\r'); - ptr++); - if (!*ptr) - { - menu->entries->help = help; - grub_free (buf); - return GRUB_ERR_NONE; - } - } - needlen = helplen + 1 + grub_strlen (buf); - if (alloclen < needlen) - { - alloclen = 2 * needlen; - help = grub_realloc (help, alloclen); - if (!help) - { - grub_free (buf); - return grub_errno; - } - } - helplen += grub_stpcpy (help + helplen, buf) - (help + helplen); - } - - grub_free (buf); - grub_free (help); - return grub_errno; -} - - -static grub_err_t -syslinux_parse_real (struct syslinux_menu *menu) -{ - grub_file_t file; - char *buf = NULL; - grub_err_t err = GRUB_ERR_NONE; - - file = grub_file_open (menu->filename, GRUB_FILE_TYPE_CONFIG); - if (!file) - return grub_errno; - while ((grub_free (buf), buf = grub_file_getline (file))) - { - const char *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; - char *end; - unsigned i; - end = buf + grub_strlen (buf); - while (end > buf && (end[-1] == '\n' || end[-1] == '\r')) - end--; - *end = 0; - for (ptr1 = buf; *ptr1 && grub_isspace (*ptr1); ptr1++); - if (*ptr1 == '#' || *ptr1 == 0) - { - err = add_comment (menu, ptr1, 1); - if (err) - goto fail; - continue; - } - for (ptr2 = ptr1; !grub_isspace (*ptr2) && *ptr2; ptr2++); - for (ptr3 = ptr2; grub_isspace (*ptr3) && *ptr3; ptr3++); - for (ptr4 = ptr3; !grub_isspace (*ptr4) && *ptr4; ptr4++); - for (ptr5 = ptr4; grub_isspace (*ptr5) && *ptr5; ptr5++); - for (i = 0; i < ARRAY_SIZE(commands); i++) - if (grub_strlen (commands[i].name1) == (grub_size_t) (ptr2 - ptr1) - && grub_strncasecmp (commands[i].name1, ptr1, ptr2 - ptr1) == 0 - && (commands[i].name2 == NULL - || (grub_strlen (commands[i].name2) - == (grub_size_t) (ptr4 - ptr3) - && grub_strncasecmp (commands[i].name2, ptr3, ptr4 - ptr3) - == 0))) - break; - if (i == ARRAY_SIZE(commands)) - { - if (sizeof ("text") - 1 == ptr2 - ptr1 - && grub_strncasecmp ("text", ptr1, ptr2 - ptr1) == 0 - && (sizeof ("help") - 1 == ptr4 - ptr3 - && grub_strncasecmp ("help", ptr3, ptr4 - ptr3) == 0)) - { - if (helptext (ptr5, file, menu)) - { - grub_free (buf); - return 1; - } - continue; - } - - add_comment (menu, " # UNSUPPORTED command '", 0); - add_comment (menu, ptr1, 0); - add_comment (menu, "'", 1); - - continue; - } - if (commands[i].parse) - { - err = commands[i].parse (commands[i].name2 - ? ptr5 : ptr3, menu); - if (err) - goto fail; - } - } - fail: - grub_file_close (file); - grub_free (buf); - return err; -} - -static grub_err_t -print_escaped (struct output_buffer *outbuf, - const char *from, const char *to) -{ - const char *ptr; - grub_err_t err; - if (!to) - to = from + grub_strlen (from); - err = ensure_space (outbuf, (to - from) * 4 + 2); - if (err) - return err; - outbuf->buf[outbuf->ptr++] = '\''; - for (ptr = from; *ptr && ptr < to; ptr++) - { - if (*ptr == '\'') - { - outbuf->buf[outbuf->ptr++] = '\''; - outbuf->buf[outbuf->ptr++] = '\\'; - outbuf->buf[outbuf->ptr++] = '\''; - outbuf->buf[outbuf->ptr++] = '\''; - } - else - outbuf->buf[outbuf->ptr++] = *ptr; - } - outbuf->buf[outbuf->ptr++] = '\''; - return GRUB_ERR_NONE; -} - -static grub_err_t -print_file (struct output_buffer *outbuf, - struct syslinux_menu *menu, const char *from, const char *to) -{ - grub_err_t err; - if (!to) - to = from + grub_strlen (from); - err = print_escaped (outbuf, from[0] == '/' - ? menu->root_target_directory - : menu->current_target_directory, NULL); - if (err) - return err; - - err = print (outbuf, "/", 1); - if (err) - return err; - return print_escaped (outbuf, from, to); -} - -/* - * Makefile.am mimics this when generating tests/syslinux/ubuntu10.04_grub.cfg, - * so changes here may need to be reflected there too. - */ -static void -simplify_filename (char *str) -{ - char *iptr, *optr = str; - for (iptr = str; *iptr; iptr++) - { - if (*iptr == '/' && optr != str && optr[-1] == '/') - continue; - if (iptr[0] == '/' && iptr[1] == '.' && iptr[2] == '/') - { - iptr += 2; - continue; - } - if (iptr[0] == '/' && iptr[1] == '.' && iptr[2] == '.' - && iptr[3] == '/') - { - iptr += 3; - while (optr >= str && *optr != '/') - optr--; - if (optr < str) - { - str[0] = '/'; - optr = str; - } - optr++; - continue; - } - *optr++ = *iptr; - } - *optr = '\0'; -} - -static grub_err_t -print_config (struct output_buffer *outbuf, - struct syslinux_menu *menu, - const char *filename, const char *basedir) -{ - struct syslinux_menu *menuptr; - grub_err_t err = GRUB_ERR_NONE; - char *new_cwd = NULL; - char *new_target_cwd = NULL; - char *newname = NULL; - int depth = 0; - - new_cwd = get_read_filename (menu, basedir); - if (!new_cwd) - { - err = grub_errno; - goto out; - } - new_target_cwd = get_target_filename (menu, basedir); - if (!new_target_cwd) - { - err = grub_errno; - goto out; - } - newname = get_read_filename (menu, filename); - if (!newname) - { - err = grub_errno; - goto out; - } - simplify_filename (newname); - - print_string ("#"); - print_file (outbuf, menu, filename, NULL); - print_string (" "); - err = print (outbuf, newname, grub_strlen (newname)); - if (err) - return err; - print_string (":\n"); - - for (menuptr = menu; menuptr; menuptr = menuptr->parent, depth++) - if (grub_strcmp (menuptr->filename, newname) == 0 - || depth > 20) - break; - if (menuptr) - { - print_string (" syslinux_configfile -r "); - print_file (outbuf, menu, "/", NULL); - print_string (" -c "); - print_file (outbuf, menu, basedir, NULL); - print_string (" "); - print_file (outbuf, menu, filename, NULL); - print_string ("\n"); - } - else - { - err = config_file (outbuf, menu->root_read_directory, - menu->root_target_directory, new_cwd, new_target_cwd, - newname, menu, menu->flavour); - if (err == GRUB_ERR_FILE_NOT_FOUND - || err == GRUB_ERR_BAD_FILENAME) - { - grub_errno = err = GRUB_ERR_NONE; - print_string ("# File "); - err = print (outbuf, newname, grub_strlen (newname)); - if (err) - goto out; - print_string (" not found\n"); - } - } - - out: - grub_free (newname); - grub_free (new_cwd); - grub_free (new_target_cwd); - return err; -} - -static grub_err_t -write_entry (struct output_buffer *outbuf, - struct syslinux_menu *menu, - struct syslinux_menuentry *curentry) -{ - grub_err_t err; - if (curentry->comments) - { - err = print (outbuf, curentry->comments, - grub_strlen (curentry->comments)); - if (err) - return err; - } - { - struct syslinux_say *say; - for (say = curentry->say; say && say->next; say = say->next); - for (; say && say->prev; say = say->prev) - { - print_string ("echo "); - if (print_escaped (outbuf, say->msg, NULL)) return grub_errno; - print_string ("\n"); - } - } - - /* FIXME: support help text. */ - switch (curentry->entry_type) - { - case KERNEL_LINUX: - { - const char *ptr; - const char *initrd = NULL, *initrde= NULL; - for (ptr = curentry->append; ptr && *ptr; ptr++) - if ((ptr == curentry->append || grub_isspace (ptr[-1])) - && grub_strncasecmp (ptr, "initrd=", sizeof ("initrd=") - 1) - == 0) - break; - if (ptr && *ptr) - { - initrd = ptr + sizeof ("initrd=") - 1; - for (initrde = initrd; *initrde && !grub_isspace (*initrde); initrde++); - } - print_string (" if test x$grub_platform = xpc; then " - "linux_suffix=16; else linux_suffix= ; fi\n"); - print_string (" linux$linux_suffix "); - print_file (outbuf, menu, curentry->kernel_file, NULL); - print_string (" "); - if (curentry->append) - { - err = print (outbuf, curentry->append, grub_strlen (curentry->append)); - if (err) - return err; - } - print_string ("\n"); - if (initrd || curentry->initrds) - { - struct initrd_list *lst; - print_string (" initrd$linux_suffix "); - if (initrd) - { - print_file (outbuf, menu, initrd, initrde); - print_string (" "); - } - for (lst = curentry->initrds; lst; lst = lst->next) - { - print_file (outbuf, menu, lst->file, NULL); - print_string (" "); - } - - print_string ("\n"); - } - } - break; - case KERNEL_CHAINLOADER: - print_string (" chainloader "); - print_file (outbuf, menu, curentry->kernel_file, NULL); - print_string ("\n"); - break; - case KERNEL_CHAINLOADER_BPB: - print_string (" chainloader --bpb "); - print_file (outbuf, menu, curentry->kernel_file, NULL); - print_string ("\n"); - break; - case LOCALBOOT: - /* FIXME: support -1. */ - /* FIXME: PXELINUX. */ - { - int n = grub_strtol (curentry->kernel_file, NULL, 0); - if (n >= 0 && n <= 0x02) - { - print_string (" root=fd"); - if (print_num (outbuf, n)) - return grub_errno; - print_string (";\n chainloader +1;\n"); - - break; - } - if (n >= 0x80 && n < 0x8a) - { - print_string (" root=hd"); - if (print_num (outbuf, n - 0x80)) - return grub_errno; - print_string (";\n chainloader +1;\n"); - break; - } - print_string (" # UNSUPPORTED localboot type "); - print_string ("\ntrue;\n"); - if (print_num (outbuf, n)) - return grub_errno; - print_string ("\n"); - break; - } - case KERNEL_COM32: - case KERNEL_COM: - { - char *basename = NULL; - - { - char *ptr; - for (ptr = curentry->kernel_file; *ptr; ptr++) - if (*ptr == '/' || *ptr == '\\') - basename = ptr; - } - if (!basename) - basename = curentry->kernel_file; - else - basename++; - if (grub_strcasecmp (basename, "chain.c32") == 0) - { - char *file = NULL; - int is_fd = -1, devn = 0; - int part = -1; - int swap = 0; - char *ptr; - for (ptr = curentry->append; *ptr; ) - { - while (grub_isspace (*ptr)) - ptr++; - /* FIXME: support mbr: and boot. */ - if (ptr[0] == 'h' && ptr[1] == 'd') - { - is_fd = 0; - devn = grub_strtoul (ptr + 2, (const char **)&ptr, 0); - continue; - } - if (grub_strncasecmp (ptr, "file=", 5) == 0) - { - file = ptr + 5; - for (ptr = file; *ptr && !grub_isspace (*ptr); ptr++); - if (*ptr) - { - *ptr = 0; - ptr++; - } - continue; - } - if (grub_strncasecmp (ptr, "swap", sizeof ("swap") - 1) == 0) - { - swap = 1; - ptr += sizeof ("swap") - 1; - continue; - } - - if (ptr[0] == 'f' && ptr[1] == 'd') - { - is_fd = 1; - devn = grub_strtoul (ptr + 2, (const char **)&ptr, 0); - continue; - } - if (grub_isdigit (ptr[0])) - { - part = grub_strtoul (ptr, (const char **)&ptr, 0); - continue; - } - /* FIXME: isolinux, ntldr, cmldr, *dos, seg, hide - FIXME: sethidden. */ - print_string (" # UNSUPPORTED option "); - if (print (outbuf, ptr, grub_strlen (ptr))) - return 0; - print_string ("\n"); - break; - } - if (is_fd == -1) - { - print_string (" # no drive specified\n"); - break; - } - if (!*ptr) - { - print_string (is_fd ? " root=fd": " root=hd"); - if (print_num (outbuf, devn)) - return grub_errno; - if (part != -1) - { - print_string (","); - if (print_num (outbuf, part + 1)) - return grub_errno; - } - print_string (";\n"); - if (file) - { - print_string (" chainloader "); - print_file (outbuf, menu, file, NULL); - print_string (";\n"); - } - else - print_string (" chainloader +1;\n"); - if (swap) - print_string (" drivemap -s hd0 \"root\";\n"); - } - break; - } - - if (grub_strcasecmp (basename, "mboot.c32") == 0) - { - char *ptr; - int first = 1; - int is_kernel = 1; - for (ptr = curentry->append; *ptr; ) - { - char *ptrr = ptr; - while (*ptr && !grub_isspace (*ptr)) - ptr++; - if (ptrr + 2 == ptr && ptrr[0] == '-' && ptrr[1] == '-') - { - print_string ("\n"); - first = 1; - continue; - } - if (first) - { - if (is_kernel) - print_string (" multiboot "); - else - print_string (" module "); - first = 0; - is_kernel = 0; - if (print_file (outbuf, menu, ptrr, ptr)) - return grub_errno; - continue; - } - if (print_escaped (outbuf, ptrr, ptr)) - return grub_errno; - } - break; - } - - if (grub_strcasecmp (basename, "ifcpu64.c32") == 0) - { - char *lm, *lme, *pae = 0, *paee = 0, *i386s = 0, *i386e = 0; - char *ptr; - ptr = curentry->append; - while (grub_isspace (*ptr)) - ptr++; - lm = ptr; - while (*ptr && !grub_isspace (*ptr)) - ptr++; - lme = ptr; - while (grub_isspace (*ptr)) - ptr++; - if (ptr[0] == '-' && ptr[1] == '-') - { - ptr += 2; - while (grub_isspace (*ptr)) - ptr++; - pae = ptr; - while (*ptr && !grub_isspace (*ptr)) - ptr++; - paee = ptr; - } - while (grub_isspace (*ptr)) - ptr++; - if (ptr[0] == '-' && ptr[1] == '-') - { - ptr += 2; - while (grub_isspace (*ptr)) - ptr++; - i386s = ptr; - while (*ptr && !grub_isspace (*ptr)) - ptr++; - i386e = ptr; - } - *lme = '\0'; - if (paee) - *paee = '\0'; - if (i386e) - *i386e = '\0'; - if (!i386s) - { - i386s = pae; - pae = 0; - } - print_string ("if cpuid --long-mode; then true;\n"); - if (print_entry (outbuf, menu, lm)) - return grub_errno; - if (pae) - { - print_string ("elif cpuid --pae; then true;\n"); - if (print_entry (outbuf, menu, pae)) - return grub_errno; - } - print_string ("else\n"); - if (print_entry (outbuf, menu, i386s)) - return grub_errno; - print_string ("fi\n"); - break; - } - - if (grub_strcasecmp (basename, "reboot.c32") == 0) - { - print_string (" reboot\n"); - break; - } - - if (grub_strcasecmp (basename, "poweroff.com") == 0) - { - print_string (" halt\n"); - break; - } - - if (grub_strcasecmp (basename, "whichsys.c32") == 0) - { - grub_syslinux_flavour_t flavour = GRUB_SYSLINUX_ISOLINUX; - const char *flav[] = - { - [GRUB_SYSLINUX_ISOLINUX] = "iso", - [GRUB_SYSLINUX_PXELINUX] = "pxe", - [GRUB_SYSLINUX_SYSLINUX] = "sys" - }; - char *ptr; - for (ptr = curentry->append; *ptr; ) - { - char *bptr, c; - while (grub_isspace (*ptr)) - ptr++; - if (grub_strncasecmp (ptr, "-iso-", 5) == 0) - { - ptr += sizeof ("-iso-") - 1; - flavour = GRUB_SYSLINUX_ISOLINUX; - continue; - } - if (grub_strncasecmp (ptr, "-pxe-", 5) == 0) - { - ptr += sizeof ("-pxe-") - 1; - flavour = GRUB_SYSLINUX_PXELINUX; - continue; - } - if (grub_strncasecmp (ptr, "-sys-", 5) == 0) - { - ptr += sizeof ("-sys-") - 1; - flavour = GRUB_SYSLINUX_SYSLINUX; - continue; - } - bptr = ptr; - while (*ptr && !grub_isspace (*ptr)) - ptr++; - c = *ptr; - *ptr = '\0'; - if (menu->flavour == GRUB_SYSLINUX_UNKNOWN - && flavour == GRUB_SYSLINUX_ISOLINUX) - { - print_string ("if [ x$syslinux_flavour = xiso -o x$syslinux_flavour = x ]; then true;\n"); - menu->flavour = GRUB_SYSLINUX_ISOLINUX; - print_entry (outbuf, menu, bptr); - menu->flavour = GRUB_SYSLINUX_UNKNOWN; - print_string ("fi\n"); - } - else if (menu->flavour == GRUB_SYSLINUX_UNKNOWN) - { - print_string ("if [ x$syslinux_flavour = x"); - err = print (outbuf, flav[flavour], grub_strlen (flav[flavour])); - if (err) - return err; - print_string (" ]; then true;\n"); - menu->flavour = flavour; - print_entry (outbuf, menu, bptr); - menu->flavour = GRUB_SYSLINUX_UNKNOWN; - print_string ("fi\n"); - } - if (menu->flavour != GRUB_SYSLINUX_UNKNOWN - && menu->flavour == flavour) - print_entry (outbuf, menu, bptr); - *ptr = c; - } - break; - } - - if (grub_strcasecmp (basename, "menu.c32") == 0 || - grub_strcasecmp (basename, "vesamenu.c32") == 0) - { - char *ptr; - char *end; - - ptr = curentry->append; - if (!ptr) - return grub_errno; - - while (*ptr) - { - end = ptr; - for (end = ptr; *end && !grub_isspace (*end); end++); - if (*end) - *end++ = '\0'; - - /* "~" is supposed to be current file, so let's skip it */ - if (grub_strcmp (ptr, "~") != 0) - { - err = print_config (outbuf, menu, ptr, ""); - if (err != GRUB_ERR_NONE) - break; - } - for (ptr = end; *ptr && grub_isspace (*ptr); ptr++); - } - err = GRUB_ERR_NONE; - break; - } - - /* FIXME: gdb, GFXBoot, Hdt, Ifcpu, Ifplop, Kbdmap, - FIXME: Linux, Lua, Meminfo, rosh, Sanbboot */ - - print_string (" # UNSUPPORTED com(32) "); - err = print (outbuf, basename, grub_strlen (basename)); - if (err) - return err; - print_string ("\ntrue;\n"); - break; - } - case KERNEL_CONFIG: - { - const char *ap; - ap = curentry->append; - if (!ap) - ap = curentry->argument; - if (!ap) - ap = ""; - print_config (outbuf, menu, curentry->kernel_file, ap); - } - break; - case KERNEL_NO_KERNEL: - /* FIXME: support this. */ - case KERNEL_BIN: - case KERNEL_PXE: - case KERNEL_IMG: - print_string (" # UNSUPPORTED entry type "); - if (print_num (outbuf, curentry->entry_type)) - return grub_errno; - print_string ("\ntrue;\n"); - break; - } - return GRUB_ERR_NONE; -} - -static grub_err_t -print_entry (struct output_buffer *outbuf, - struct syslinux_menu *menu, - const char *str) -{ - struct syslinux_menuentry *curentry; - for (curentry = menu->entries; curentry; curentry = curentry->next) - if (grub_strcasecmp (curentry->label, str) == 0) - { - grub_err_t err; - err = write_entry (outbuf, menu, curentry); - if (err) - return err; - } - return GRUB_ERR_NONE; -} - -static void -free_menu (struct syslinux_menu *menu) -{ - struct syslinux_say *say, *nsay; - struct syslinux_menuentry *entry, *nentry; - - grub_free (menu->def); - grub_free (menu->comments); - grub_free (menu->background); - for (say = menu->say; say ; say = nsay) - { - nsay = say->next; - grub_free (say); - } - - for (entry = menu->entries; entry ; entry = nentry) - { - nentry = entry->next; - struct initrd_list *initrd, *ninitrd; - - for (initrd = entry->initrds; initrd ; initrd = ninitrd) - { - ninitrd = initrd->next; - grub_free (initrd->file); - grub_free (initrd); - } - - grub_free (entry->comments); - grub_free (entry->kernel_file); - grub_free (entry->label); - grub_free (entry->extlabel); - grub_free (entry->append); - grub_free (entry->help); - grub_free (entry); - } -} - -static grub_err_t -config_file (struct output_buffer *outbuf, - const char *root, const char *target_root, - const char *cwd, const char *target_cwd, - const char *fname, struct syslinux_menu *parent, - grub_syslinux_flavour_t flav) -{ - grub_err_t err; - struct syslinux_menu menu; - struct syslinux_menuentry *curentry, *lentry; - struct syslinux_say *say; - - grub_memset (&menu, 0, sizeof (menu)); - menu.flavour = flav; - menu.root_read_directory = root; - menu.root_target_directory = target_root; - menu.current_read_directory = cwd; - menu.current_target_directory = target_cwd; - - menu.filename = fname; - menu.parent = parent; - err = syslinux_parse_real (&menu); - if (err) - return err; - - for (say = menu.say; say && say->next; say = say->next); - for (; say && say->prev; say = say->prev) - { - print_string ("echo "); - err = print_escaped (outbuf, say->msg, NULL); - if (err) - return err; - print_string ("\n"); - } - - if (menu.background) - { - print_string (" background_image "); - err = print_file (outbuf, &menu, menu.background, NULL); - if (err) - return err; - print_string ("\n"); - } - - if (menu.comments) - { - err = print (outbuf, menu.comments, grub_strlen (menu.comments)); - if (err) - return err; - } - - if (menu.timeout == 0 && menu.entries && menu.def) - { - err = print_entry (outbuf, &menu, menu.def); - if (err) - return err; - } - else if (menu.entries) - { - for (curentry = menu.entries; curentry->next; curentry = curentry->next); - lentry = curentry; - - print_string ("set timeout="); - err = print_num (outbuf, (menu.timeout + 9) / 10); - if (err) - return err; - print_string ("\n"); - - if (menu.def) - { - print_string (" default="); - err = print_escaped (outbuf, menu.def, NULL); - if (err) - return err; - print_string ("\n"); - } - for (curentry = lentry; curentry; curentry = curentry->prev) - { - print_string ("menuentry "); - err = print_escaped (outbuf, - curentry->extlabel ? : curentry->label, NULL); - if (err) - return err; - if (curentry->hotkey) - { - char hk[] = { curentry->hotkey, '\0' }; - print_string (" --hotkey '"); - print_string (hk); - print_string ("'"); - } - print_string (" --id "); - err = print_escaped (outbuf, curentry->label, NULL); - if (err) - return err; - print_string (" {\n"); - - err = write_entry (outbuf, &menu, curentry); - if (err) - return err; - - print_string ("}\n"); - } - } - free_menu (&menu); - return GRUB_ERR_NONE; -} - -char * -grub_syslinux_config_file (const char *base, const char *target_base, - const char *cwd, const char *target_cwd, - const char *fname, grub_syslinux_flavour_t flav) -{ - struct output_buffer outbuf = { 0, 0, 0 }; - grub_err_t err; - err = config_file (&outbuf, base, target_base, cwd, target_cwd, - fname, NULL, flav); - if (err) - return NULL; - err = print (&outbuf, "\0", 1); - if (err) - return NULL; - return outbuf.buf; -} diff --git a/grub-core/lib/tss2/buffer.c b/grub-core/lib/tss2/buffer.c deleted file mode 100644 index 16d59a8f5..000000000 --- a/grub-core/lib/tss2/buffer.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include - -void grub_tpm2_buffer_init (grub_tpm2_buffer_t buffer) -{ - grub_memset (buffer->data, 0, sizeof (buffer->data)); - buffer->size = 0; - buffer->offset = 0; - buffer->cap = sizeof (buffer->data); - buffer->error = 0; -} - -void -grub_tpm2_buffer_pack (grub_tpm2_buffer_t buffer, const void *data, grub_size_t size) -{ - grub_uint32_t r = buffer->cap - buffer->size; - - if (buffer->error) - return; - - if (size > r) - { - buffer->error = 1; - return; - } - - grub_memcpy (&buffer->data[buffer->size], (void *) data, size); - buffer->size += size; -} - -void -grub_tpm2_buffer_pack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t value) -{ - grub_tpm2_buffer_pack (buffer, (const void *) &value, sizeof (value)); -} - -void -grub_tpm2_buffer_pack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t value) -{ - grub_uint16_t tmp = grub_cpu_to_be16 (value); - - grub_tpm2_buffer_pack (buffer, (const void *) &tmp, sizeof (tmp)); -} - -void -grub_tpm2_buffer_pack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t value) -{ - grub_uint32_t tmp = grub_cpu_to_be32 (value); - - grub_tpm2_buffer_pack (buffer, (const void *) &tmp, sizeof (tmp)); -} - -void -grub_tpm2_buffer_unpack (grub_tpm2_buffer_t buffer, void *data, grub_size_t size) -{ - grub_uint32_t r = buffer->size - buffer->offset; - - if (buffer->error) - return; - - if (size > r) - { - buffer->error = 1; - return; - } - - grub_memcpy (data, &buffer->data[buffer->offset], size); - buffer->offset += size; -} - -void -grub_tpm2_buffer_unpack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t *value) -{ - grub_uint32_t r = buffer->size - buffer->offset; - - if (buffer->error) - return; - - if (sizeof (*value) > r) - { - buffer->error = 1; - return; - } - - grub_memcpy (value, &buffer->data[buffer->offset], sizeof (*value)); - buffer->offset += sizeof (*value); -} - -void -grub_tpm2_buffer_unpack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t *value) -{ - grub_uint16_t tmp; - grub_uint32_t r = buffer->size - buffer->offset; - - if (buffer->error) - return; - - if (sizeof (tmp) > r) - { - buffer->error = 1; - return; - } - - grub_memcpy (&tmp, &buffer->data[buffer->offset], sizeof (tmp)); - buffer->offset += sizeof (tmp); - *value = grub_be_to_cpu16 (tmp); -} - -void -grub_tpm2_buffer_unpack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t *value) -{ - grub_uint32_t tmp; - grub_uint32_t r = buffer->size - buffer->offset; - - if (buffer->error) - return; - - if (sizeof (tmp) > r) - { - buffer->error = 1; - return; - } - - grub_memcpy (&tmp, &buffer->data[buffer->offset], sizeof (tmp)); - buffer->offset += sizeof (tmp); - *value = grub_be_to_cpu32 (tmp); -} diff --git a/grub-core/lib/tss2/tcg2.h b/grub-core/lib/tss2/tcg2.h deleted file mode 100644 index 3d26373dd..000000000 --- a/grub-core/lib/tss2/tcg2.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_TPM2_TCG2_HEADER -#define GRUB_TPM2_TCG2_HEADER 1 - -#include -#include - -extern grub_err_t -grub_tcg2_get_max_output_size (grub_size_t *size); - -extern grub_err_t -grub_tcg2_submit_command (grub_size_t input_size, - grub_uint8_t *input, - grub_size_t output_size, - grub_uint8_t *output); - -#endif /* ! GRUB_TPM2_TCG2_HEADER */ diff --git a/grub-core/lib/tss2/tcg2_emu.c b/grub-core/lib/tss2/tcg2_emu.c deleted file mode 100644 index cab930d2b..000000000 --- a/grub-core/lib/tss2/tcg2_emu.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2024 SUSE LLC - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include - -grub_err_t -grub_tcg2_get_max_output_size (grub_size_t *size) -{ - if (size == NULL) - return GRUB_ERR_BAD_ARGUMENT; - - *size = GRUB_TPM2_BUFFER_CAPACITY; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_tcg2_submit_command (grub_size_t input_size, grub_uint8_t *input, - grub_size_t output_size, grub_uint8_t *output) -{ - if (grub_util_tpm_write (input, input_size) != input_size) - return GRUB_ERR_BAD_DEVICE; - - if (grub_util_tpm_read (output, output_size) < sizeof (TPM_RESPONSE_HEADER_t)) - return GRUB_ERR_BAD_DEVICE; - - return GRUB_ERR_NONE; -} diff --git a/grub-core/lib/tss2/tpm2_cmd.c b/grub-core/lib/tss2/tpm2_cmd.c deleted file mode 100644 index 6d25db1ab..000000000 --- a/grub-core/lib/tss2/tpm2_cmd.c +++ /dev/null @@ -1,1248 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -static TPM_RC_t -tpm2_submit_command_real (const TPMI_ST_COMMAND_TAG_t tag, - const TPM_CC_t commandCode, - TPM_RC_t *responseCode, - const struct grub_tpm2_buffer *in, - struct grub_tpm2_buffer *out) -{ - grub_err_t err; - struct grub_tpm2_buffer buf; - TPMI_ST_COMMAND_TAG_t tag_out; - grub_uint32_t command_size; - grub_size_t max_output_size; - - /* Marshal */ - grub_tpm2_buffer_init (&buf); - grub_tpm2_buffer_pack_u16 (&buf, tag); - grub_tpm2_buffer_pack_u32 (&buf, 0); - grub_tpm2_buffer_pack_u32 (&buf, commandCode); - grub_tpm2_buffer_pack (&buf, in->data, in->size); - - if (buf.error != 0) - return TPM_RC_FAILURE; - - /* Convert the command size to big endian to fill the u32 buffer below 'tag' */ - command_size = grub_cpu_to_be32 (buf.size); - grub_memcpy (&buf.data[sizeof (grub_uint16_t)], &command_size, sizeof (command_size)); - - /* Stay within output block limits */ - err = grub_tcg2_get_max_output_size (&max_output_size); - if (err != GRUB_ERR_NONE || max_output_size > out->cap) - max_output_size = out->cap - 1; - - /* Submit */ - err = grub_tcg2_submit_command (buf.size, buf.data, max_output_size, out->data); - if (err != GRUB_ERR_NONE) - return TPM_RC_FAILURE; - - /* Unmarshal */ - out->size = sizeof (grub_uint16_t) + sizeof (grub_uint32_t) + sizeof (grub_uint32_t); - grub_tpm2_buffer_unpack_u16 (out, &tag_out); - grub_tpm2_buffer_unpack_u32 (out, &command_size); - grub_tpm2_buffer_unpack_u32 (out, responseCode); - out->size = command_size; - if (out->error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -static TPM_RC_t -tpm2_submit_command (const TPMI_ST_COMMAND_TAG_t tag, - const TPM_CC_t commandCode, - TPM_RC_t *responseCode, - const struct grub_tpm2_buffer *in, - struct grub_tpm2_buffer *out) -{ - TPM_RC_t err; - int retry_cnt = 0; - - /* Catch TPM_RC_RETRY and send the command again */ - do { - err = tpm2_submit_command_real (tag, commandCode, responseCode, in, out); - if (*responseCode != TPM_RC_RETRY) - break; - - retry_cnt++; - } while (retry_cnt < 3); - - return err; -} - -TPM_RC_t -grub_tpm2_createprimary (const TPMI_RH_HIERARCHY_t primaryHandle, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_SENSITIVE_CREATE_t *inSensitive, - const TPM2B_PUBLIC_t *inPublic, - const TPM2B_DATA_t *outsideInfo, - const TPML_PCR_SELECTION_t *creationPCR, - TPM_HANDLE_t *objectHandle, - TPM2B_PUBLIC_t *outPublic, - TPM2B_CREATION_DATA_t *creationData, - TPM2B_DIGEST_t *creationHash, - TPMT_TK_CREATION_t *creationTicket, - TPM2B_NAME_t *name, - TPMS_AUTH_RESPONSE_t *authResponse) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPM_HANDLE_t objectHandleTmp; - TPM2B_PUBLIC_t outPublicTmp; - TPM2B_CREATION_DATA_t creationDataTmp; - TPM2B_DIGEST_t creationHashTmp; - TPMT_TK_CREATION_t creationTicketTmp; - TPM2B_NAME_t nameTmp; - TPMS_AUTH_RESPONSE_t authResponseTmp; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - grub_uint32_t parameterSize; - - if (inSensitive == NULL || inPublic == NULL || outsideInfo == NULL || - creationPCR == NULL) - return TPM_RC_VALUE; - - if (objectHandle == NULL) - objectHandle = &objectHandleTmp; - if (outPublic == NULL) - outPublic = &outPublicTmp; - if (creationData == NULL) - creationData = &creationDataTmp; - if (creationHash == NULL) - creationHash = &creationHashTmp; - if (creationTicket == NULL) - creationTicket = &creationTicketTmp; - if (name == NULL) - name = &nameTmp; - if (authResponse == NULL) - authResponse = &authResponseTmp; - - grub_memset (outPublic, 0, sizeof (*outPublic)); - grub_memset (creationData, 0, sizeof (*creationData)); - grub_memset (creationHash, 0, sizeof (*creationHash)); - grub_memset (creationTicket, 0, sizeof (*creationTicket)); - grub_memset (name, 0, sizeof (*name)); - grub_memset (authResponse, 0, sizeof (*authResponse)); - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, primaryHandle); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - grub_Tss2_MU_TPM2B_SENSITIVE_CREATE_Marshal (&in, inSensitive); - grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&in, inPublic); - grub_Tss2_MU_TPM2B_Marshal (&in, outsideInfo->size, outsideInfo->buffer); - grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&in, creationPCR); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_CreatePrimary, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - grub_tpm2_buffer_unpack_u32 (&out, objectHandle); - if (tag == TPM_ST_SESSIONS) - grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); - grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (&out, outPublic); - grub_Tss2_MU_TPM2B_CREATION_DATA_Unmarshal (&out, creationData); - grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (&out, creationHash); - grub_Tss2_MU_TPMT_TK_CREATION_Unmarshal (&out, creationTicket); - grub_Tss2_MU_TPM2B_NAME_Unmarshal (&out, name); - if (tag == TPM_ST_SESSIONS) - grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_startauthsession (const TPMI_DH_OBJECT_t tpmKey, - const TPMI_DH_ENTITY_t bind, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_NONCE_t *nonceCaller, - const TPM2B_ENCRYPTED_SECRET_t *encryptedSalt, - const TPM_SE_t sessionType, - const TPMT_SYM_DEF_t *symmetric, - const TPMI_ALG_HASH_t authHash, - TPMI_SH_AUTH_SESSION_t *sessionHandle, - TPM2B_NONCE_t *nonceTpm, - TPMS_AUTH_RESPONSE_t *authResponse) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPMI_SH_AUTH_SESSION_t sessionHandleTmp; - TPM2B_NONCE_t nonceTpmTmp; - TPMS_AUTH_RESPONSE_t authResponseTmp; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - grub_uint32_t param_size; - - if (nonceCaller == NULL || symmetric == NULL) - return TPM_RC_VALUE; - - if (tpmKey == TPM_RH_NULL && - (encryptedSalt && encryptedSalt->size != 0)) - return TPM_RC_VALUE; - - if (sessionHandle == NULL) - sessionHandle = &sessionHandleTmp; - if (nonceTpm == NULL) - nonceTpm = &nonceTpmTmp; - if (authResponse == NULL) - authResponse = &authResponseTmp; - - grub_memset (sessionHandle, 0, sizeof (*sessionHandle)); - grub_memset (nonceTpm, 0, sizeof (*nonceTpm)); - grub_memset (authResponse, 0, sizeof (*authResponse)); - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, tpmKey); - grub_tpm2_buffer_pack_u32 (&in, bind); - if (tag == TPM_ST_SESSIONS) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - grub_Tss2_MU_TPM2B_Marshal (&in, nonceCaller->size, nonceCaller->buffer); - if (encryptedSalt != NULL) - grub_Tss2_MU_TPM2B_Marshal (&in, encryptedSalt->size, encryptedSalt->secret); - else - grub_tpm2_buffer_pack_u16 (&in, 0); - grub_tpm2_buffer_pack_u8 (&in, sessionType); - grub_Tss2_MU_TPMT_SYM_DEF_Marshal (&in, symmetric); - grub_tpm2_buffer_pack_u16 (&in, authHash); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_StartAuthSession, &responseCode, - &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - grub_tpm2_buffer_unpack_u32 (&out, sessionHandle); - if (tag == TPM_ST_SESSIONS) - grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); - grub_Tss2_MU_TPM2B_NONCE_Unmarshal (&out, nonceTpm); - if (tag == TPM_ST_SESSIONS) - grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_policypcr (const TPMI_SH_POLICY_t policySessions, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_DIGEST_t *pcrDigest, - const TPML_PCR_SELECTION_t *pcrs, - TPMS_AUTH_RESPONSE_t *authResponse) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPMS_AUTH_RESPONSE_t authResponseTmp; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - grub_uint32_t param_size; - - if (pcrs == NULL) - return TPM_RC_VALUE; - - if (authResponse == NULL) - authResponse = &authResponseTmp; - - grub_memset (authResponse, 0, sizeof (*authResponse)); - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, policySessions); - if (tag == TPM_ST_SESSIONS) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - if (pcrDigest != NULL) - grub_Tss2_MU_TPM2B_Marshal (&in, pcrDigest->size, pcrDigest->buffer); - else - grub_tpm2_buffer_pack_u16 (&in, 0); - grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&in, pcrs); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_PolicyPCR, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal*/ - if (tag == TPM_ST_SESSIONS) - grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); - if (tag == TPM_ST_SESSIONS) - grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_readpublic (const TPMI_DH_OBJECT_t objectHandle, - const TPMS_AUTH_COMMAND_t *authCommand, - TPM2B_PUBLIC_t *outPublic) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - grub_uint32_t parameterSize; - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, objectHandle); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_ReadPublic, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (tag == TPM_ST_SESSIONS) - grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); - grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (&out, outPublic); - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_load (const TPMI_DH_OBJECT_t parent_handle, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_PRIVATE_t *inPrivate, - const TPM2B_PUBLIC_t *inPublic, - TPM_HANDLE_t *objectHandle, - TPM2B_NAME_t *name, - TPMS_AUTH_RESPONSE_t *authResponse) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPM_HANDLE_t objectHandleTmp; - TPM2B_NAME_t nameTmp; - TPMS_AUTH_RESPONSE_t authResponseTmp; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - grub_uint32_t param_size; - - if (inPrivate == NULL || inPublic == NULL) - return TPM_RC_VALUE; - - if (objectHandle == NULL) - objectHandle = &objectHandleTmp; - if (name == NULL) - name = &nameTmp; - if (authResponse == NULL) - authResponse = &authResponseTmp; - - grub_memset (objectHandle, 0, sizeof (*objectHandle)); - grub_memset (name, 0, sizeof (*name)); - grub_memset (authResponse, 0, sizeof (*authResponse)); - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, parent_handle); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - grub_Tss2_MU_TPM2B_Marshal (&in, inPrivate->size, inPrivate->buffer); - grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&in, inPublic); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_Load, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - grub_tpm2_buffer_unpack_u32 (&out, objectHandle); - if (tag == TPM_ST_SESSIONS) - grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); - grub_Tss2_MU_TPM2B_NAME_Unmarshal (&out, name); - if (tag == TPM_ST_SESSIONS) - grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_loadexternal (const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_SENSITIVE_t *inPrivate, - const TPM2B_PUBLIC_t *inPublic, - const TPMI_RH_HIERARCHY_t hierarchy, - TPM_HANDLE_t *objectHandle, - TPM2B_NAME_t *name, - TPMS_AUTH_RESPONSE_t *authResponse) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPM_HANDLE_t objectHandleTmp; - TPM2B_NAME_t nameTmp; - TPMS_AUTH_RESPONSE_t authResponseTmp; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - grub_uint32_t param_size; - - if (inPublic == NULL) - return TPM_RC_VALUE; - - if (objectHandle == NULL) - objectHandle = &objectHandleTmp; - if (name == NULL) - name = &nameTmp; - if (authResponse == NULL) - authResponse = &authResponseTmp; - - grub_memset (objectHandle, 0, sizeof (*objectHandle)); - grub_memset (name, 0, sizeof (*name)); - grub_memset (authResponse, 0, sizeof (*authResponse)); - - /* Marshal */ - grub_tpm2_buffer_init (&in); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - if (inPrivate != NULL) - grub_Tss2_MU_TPM2B_SENSITIVE_Marshal (&in, inPrivate); - else - grub_tpm2_buffer_pack_u16 (&in, 0); - grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&in, inPublic); - grub_tpm2_buffer_pack_u32 (&in, hierarchy); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_LoadExternal, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - grub_tpm2_buffer_unpack_u32 (&out, objectHandle); - if (tag == TPM_ST_SESSIONS) - grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); - grub_Tss2_MU_TPM2B_NAME_Unmarshal (&out, name); - if (tag == TPM_ST_SESSIONS) - grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_unseal (const TPMI_DH_OBJECT_t itemHandle, - const TPMS_AUTH_COMMAND_t *authCommand, - TPM2B_SENSITIVE_DATA_t *outData, - TPMS_AUTH_RESPONSE_t *authResponse) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPM2B_SENSITIVE_DATA_t outDataTmp; - TPMS_AUTH_RESPONSE_t authResponseTmp; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - grub_uint32_t param_size; - - if (outData == NULL) - outData = &outDataTmp; - if (authResponse == NULL) - authResponse = &authResponseTmp; - - grub_memset (outData, 0, sizeof (*outData)); - grub_memset (authResponse, 0, sizeof (*authResponse)); - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, itemHandle); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_Unseal, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (tag == TPM_ST_SESSIONS) - grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); - grub_Tss2_MU_TPM2B_SENSITIVE_DATA_Unmarshal (&out, outData); - if (tag == TPM_ST_SESSIONS) - grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_flushcontext (const TPMI_DH_CONTEXT_t handle) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPM_RC_t responseCode; - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, handle); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (TPM_ST_NO_SESSIONS, TPM_CC_FlushContext, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_pcr_read (const TPMS_AUTH_COMMAND_t *authCommand, - const TPML_PCR_SELECTION_t *pcrSelectionIn, - grub_uint32_t *pcrUpdateCounter, - TPML_PCR_SELECTION_t *pcrSelectionOut, - TPML_DIGEST_t *pcrValues, - TPMS_AUTH_RESPONSE_t *authResponse) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - grub_uint32_t pcrUpdateCounterTmp; - TPML_PCR_SELECTION_t pcrSelectionOutTmp; - TPML_DIGEST_t pcrValuesTmp; - TPMS_AUTH_RESPONSE_t authResponseTmp; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - grub_uint32_t parameterSize; - - if (pcrSelectionIn == NULL) - return TPM_RC_VALUE; - - if (pcrUpdateCounter == NULL) - pcrUpdateCounter = &pcrUpdateCounterTmp; - if (pcrSelectionOut == NULL) - pcrSelectionOut = &pcrSelectionOutTmp; - if (pcrValues == NULL) - pcrValues = &pcrValuesTmp; - if (authResponse == NULL) - authResponse = &authResponseTmp; - - /* Marshal */ - grub_tpm2_buffer_init (&in); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&in, pcrSelectionIn); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_PCR_Read, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (tag == TPM_ST_SESSIONS) - grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); - grub_tpm2_buffer_unpack_u32 (&out, pcrUpdateCounter); - grub_Tss2_MU_TPML_PCR_SELECTION_Unmarshal (&out, pcrSelectionOut); - grub_Tss2_MU_TPML_DIGEST_Unmarshal (&out, pcrValues); - if (tag == TPM_ST_SESSIONS) - grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_policygetdigest (const TPMI_SH_POLICY_t policySession, - const TPMS_AUTH_COMMAND_t *authCommand, - TPM2B_DIGEST_t *policyDigest, - TPMS_AUTH_RESPONSE_t *authResponse) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPMS_AUTH_RESPONSE_t authResponseTmp; - TPM2B_DIGEST_t policyDigestTmp; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - grub_uint32_t parameterSize; - - if (authResponse == NULL) - authResponse = &authResponseTmp; - if (policyDigest == NULL) - policyDigest = &policyDigestTmp; - - grub_memset (authResponse, 0, sizeof (*authResponse)); - grub_memset (policyDigest, 0, sizeof (*policyDigest)); - - /* Submit */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, policySession); - if (tag == TPM_ST_SESSIONS) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_PolicyGetDigest, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (tag == TPM_ST_SESSIONS) - grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); - grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (&out, policyDigest); - if (tag == TPM_ST_SESSIONS) - grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_create (const TPMI_DH_OBJECT_t parentHandle, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_SENSITIVE_CREATE_t *inSensitive, - const TPM2B_PUBLIC_t *inPublic, - const TPM2B_DATA_t *outsideInfo, - const TPML_PCR_SELECTION_t *creationPCR, - TPM2B_PRIVATE_t *outPrivate, - TPM2B_PUBLIC_t *outPublic, - TPM2B_CREATION_DATA_t *creationData, - TPM2B_DIGEST_t *creationHash, - TPMT_TK_CREATION_t *creationTicket, - TPMS_AUTH_RESPONSE_t *authResponse) -{ - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPM2B_PUBLIC_t outPublicTmp; - TPM2B_PRIVATE_t outPrivateTmp; - TPM2B_CREATION_DATA_t creationDataTmp; - TPM2B_DIGEST_t creationHashTmp; - TPMT_TK_CREATION_t creationTicketTmp; - TPMS_AUTH_RESPONSE_t authResponseTmp; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS:TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - TPM_RC_t rc; - grub_uint32_t parameterSize; - - if (inSensitive == NULL || inPublic == NULL || outsideInfo == NULL || - creationPCR == NULL) - return TPM_RC_VALUE; - - if (outPrivate == NULL) - outPrivate = &outPrivateTmp; - if (outPublic == NULL) - outPublic = &outPublicTmp; - if (creationData == NULL) - creationData = &creationDataTmp; - if (creationHash == NULL) - creationHash = &creationHashTmp; - if (creationTicket == NULL) - creationTicket = &creationTicketTmp; - if (authResponse == NULL) - authResponse = &authResponseTmp; - - grub_memset (outPrivate, 0, sizeof (*outPrivate)); - grub_memset (outPublic, 0, sizeof (*outPublic)); - grub_memset (creationData, 0, sizeof (*creationData)); - grub_memset (creationHash, 0, sizeof (*creationHash)); - grub_memset (creationTicket, 0, sizeof (*creationTicket)); - grub_memset (authResponse, 0, sizeof (*authResponse)); - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, parentHandle); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - grub_Tss2_MU_TPM2B_SENSITIVE_CREATE_Marshal (&in, inSensitive); - grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&in, inPublic); - grub_Tss2_MU_TPM2B_Marshal (&in, outsideInfo->size, outsideInfo->buffer); - grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&in, creationPCR); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_Create, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (tag == TPM_ST_SESSIONS) - grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); - grub_Tss2_MU_TPM2B_PRIVATE_Unmarshal (&out, outPrivate); - grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (&out, outPublic); - grub_Tss2_MU_TPM2B_CREATION_DATA_Unmarshal (&out, creationData); - grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (&out, creationHash); - grub_Tss2_MU_TPMT_TK_CREATION_Unmarshal (&out, creationTicket); - if (tag == TPM_ST_SESSIONS) - grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse); - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_evictcontrol (const TPMI_RH_PROVISION_t auth, - const TPMI_DH_OBJECT_t objectHandle, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPMI_DH_PERSISTENT_t persistentHandle, - TPMS_AUTH_RESPONSE_t *authResponse) -{ - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPMS_AUTH_RESPONSE_t authResponseTmp; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - TPM_RC_t rc; - grub_uint32_t parameterSize; - - if (authResponse == NULL) - authResponse = &authResponseTmp; - - grub_memset (authResponse, 0, sizeof (*authResponse)); - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, auth); - grub_tpm2_buffer_pack_u32 (&in, objectHandle); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - grub_tpm2_buffer_pack_u32 (&in, persistentHandle); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_EvictControl, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (tag == TPM_ST_SESSIONS) - { - grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); - grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse); - } - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_hash (const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_MAX_BUFFER_t *data, - const TPMI_ALG_HASH_t hashAlg, - const TPMI_RH_HIERARCHY_t hierarchy, - TPM2B_DIGEST_t *outHash, - TPMT_TK_HASHCHECK_t *validation, - TPMS_AUTH_RESPONSE_t *authResponse) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPMS_AUTH_RESPONSE_t authResponseTmp; - TPM2B_DIGEST_t outHashTmp; - TPMT_TK_HASHCHECK_t validationTmp; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - grub_uint32_t param_size; - - if (hashAlg == TPM_ALG_NULL) - return TPM_RC_VALUE; - - if (outHash == NULL) - outHash = &outHashTmp; - if (validation == NULL) - validation = &validationTmp; - if (authResponse == NULL) - authResponse = &authResponseTmp; - - grub_memset (outHash, 0, sizeof (*outHash)); - grub_memset (validation, 0, sizeof (*validation)); - grub_memset (authResponse, 0, sizeof (*authResponse)); - - /* Marshal */ - grub_tpm2_buffer_init (&in); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - if (data != NULL) - grub_Tss2_MU_TPM2B_Marshal (&in, data->size, data->buffer); - else - grub_tpm2_buffer_pack_u16 (&in, 0); - grub_tpm2_buffer_pack_u16 (&in, hashAlg); - grub_tpm2_buffer_pack_u32 (&in, hierarchy); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_Hash, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (tag == TPM_ST_SESSIONS) - grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); - grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (&out, outHash); - grub_Tss2_MU_TPMT_TK_HASHCHECK_Unmarshal (&out, validation); - if (tag == TPM_ST_SESSIONS) - grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_verifysignature (const TPMI_DH_OBJECT_t keyHandle, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_DIGEST_t *digest, - const TPMT_SIGNATURE_t *signature, - TPMT_TK_VERIFIED_t *validation, - TPMS_AUTH_RESPONSE_t *authResponse) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPMS_AUTH_RESPONSE_t authResponseTmp; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPMT_TK_VERIFIED_t validationTmp; - TPM_RC_t responseCode; - grub_uint32_t param_size; - - if (digest == NULL || signature == NULL) - return TPM_RC_VALUE; - - if (validation == NULL) - validation = &validationTmp; - if (authResponse == NULL) - authResponse = &authResponseTmp; - - grub_memset (validation, 0, sizeof (*validation)); - grub_memset (authResponse, 0, sizeof (*authResponse)); - - /* Marshal */ - grub_tpm2_buffer_init (&in); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - grub_tpm2_buffer_pack_u32 (&in, keyHandle); - grub_Tss2_MU_TPM2B_Marshal (&in, digest->size, digest->buffer); - grub_Tss2_MU_TPMT_SIGNATURE_Marshal (&in, signature); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_VerifySignature, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (tag == TPM_ST_SESSIONS) - grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); - grub_Tss2_MU_TPMT_TK_VERIFIED_Unmarshal (&out, validation); - if (tag == TPM_ST_SESSIONS) - grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_policyauthorize (const TPMI_SH_POLICY_t policySession, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_DIGEST_t *approvedPolicy, - const TPM2B_NONCE_t *policyRef, - const TPM2B_NAME_t *keySign, - const TPMT_TK_VERIFIED_t *checkTicket, - TPMS_AUTH_RESPONSE_t *authResponse) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPMS_AUTH_RESPONSE_t authResponseTmp; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - grub_uint32_t param_size; - - if (approvedPolicy == NULL || keySign == NULL || checkTicket == NULL) - return TPM_RC_VALUE; - - if (authResponse == NULL) - authResponse = &authResponseTmp; - - grub_memset (authResponse, 0, sizeof (*authResponse)); - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, policySession); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - grub_Tss2_MU_TPM2B_Marshal (&in, approvedPolicy->size, approvedPolicy->buffer); - if (policyRef != NULL) - grub_Tss2_MU_TPM2B_Marshal (&in, policyRef->size, policyRef->buffer); - else - grub_tpm2_buffer_pack_u16 (&in, 0); - grub_Tss2_MU_TPM2B_Marshal (&in, keySign->size, keySign->name); - grub_Tss2_MU_TPMT_TK_VERIFIED_Marshal (&in, checkTicket); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_PolicyAuthorize, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (tag == TPM_ST_SESSIONS) - { - grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); - grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); - } - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_testparms (const TPMT_PUBLIC_PARMS_t *parms, - const TPMS_AUTH_COMMAND_t *authCommand) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - - if (parms == NULL) - return TPM_RC_VALUE; - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_Tss2_MU_TPMT_PUBLIC_PARMS_Marshal (&in, parms); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_TestParms, &responseCode, &in, - &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_nv_definespace (const TPMI_RH_PROVISION_t authHandle, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_AUTH_t *auth, - const TPM2B_NV_PUBLIC_t *publicInfo) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - - if (publicInfo == NULL) - return TPM_RC_VALUE; - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, authHandle); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - if (auth != NULL) - grub_Tss2_MU_TPM2B_Marshal (&in, auth->size, auth->buffer); - else - grub_tpm2_buffer_pack_u16 (&in, 0); - grub_Tss2_MU_TPM2B_NV_PUBLIC_Marshal (&in, publicInfo); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_NV_DefineSpace, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_nv_undefinespace (const TPMI_RH_PROVISION_t authHandle, - const TPMI_RH_NV_INDEX_t nvIndex, - const TPMS_AUTH_COMMAND_t *authCommand) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, authHandle); - grub_tpm2_buffer_pack_u32 (&in, nvIndex); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_NV_UndefineSpace, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_nv_readpublic (const TPMI_RH_NV_INDEX_t nvIndex, - const TPMS_AUTH_COMMAND_t *authCommand, - TPM2B_NV_PUBLIC_t *nvPublic, - TPM2B_NAME_t *nvName) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - grub_uint32_t param_size; - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, nvIndex); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_NV_ReadPublic, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (tag == TPM_ST_SESSIONS) - grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); - grub_Tss2_MU_TPM2B_NV_PUBLIC_Unmarshal (&out, nvPublic); - grub_Tss2_MU_TPM2B_NAME_Unmarshal (&out, nvName); - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_nv_read (const TPMI_RH_NV_AUTH_t authHandle, - const TPMI_RH_NV_INDEX_t nvIndex, - const TPMS_AUTH_COMMAND_t *authCommand, - const grub_uint16_t size, - const grub_uint16_t offset, - TPM2B_MAX_NV_BUFFER_t *data) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - grub_uint32_t param_size; - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, authHandle); - grub_tpm2_buffer_pack_u32 (&in, nvIndex); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - grub_tpm2_buffer_pack_u16 (&in, size); - grub_tpm2_buffer_pack_u16 (&in, offset); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_NV_Read, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (tag == TPM_ST_SESSIONS) - grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); - grub_Tss2_MU_TPM2B_NAX_NV_BUFFER_Unmarshal (&out, data); - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} - -TPM_RC_t -grub_tpm2_nv_write (const TPMI_RH_NV_AUTH_t authHandle, - const TPMI_RH_NV_INDEX_t nvIndex, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_MAX_NV_BUFFER_t *data, - const grub_uint16_t offset) -{ - TPM_RC_t rc; - struct grub_tpm2_buffer in; - struct grub_tpm2_buffer out; - TPMI_ST_COMMAND_TAG_t tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; - TPM_RC_t responseCode; - - /* Marshal */ - grub_tpm2_buffer_init (&in); - grub_tpm2_buffer_pack_u32 (&in, authHandle); - grub_tpm2_buffer_pack_u32 (&in, nvIndex); - if (authCommand != NULL) - grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); - grub_Tss2_MU_TPM2B_Marshal (&in, data->size, data->buffer); - grub_tpm2_buffer_pack_u16 (&in, offset); - if (in.error != 0) - return TPM_RC_FAILURE; - - /* Submit */ - grub_tpm2_buffer_init (&out); - rc = tpm2_submit_command (tag, TPM_CC_NV_Write, &responseCode, &in, &out); - if (rc != TPM_RC_SUCCESS) - return rc; - if (responseCode != TPM_RC_SUCCESS) - return responseCode; - - /* Unmarshal */ - if (out.error != 0) - return TPM_RC_FAILURE; - - return TPM_RC_SUCCESS; -} diff --git a/grub-core/lib/tss2/tpm2_cmd.h b/grub-core/lib/tss2/tpm2_cmd.h deleted file mode 100644 index 90b42efec..000000000 --- a/grub-core/lib/tss2/tpm2_cmd.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_TPM2_COMMANDS_HEADER -#define GRUB_TPM2_COMMANDS_HEADER 1 - -#include - -extern TPM_RC_t -grub_tpm2_createprimary (const TPMI_RH_HIERARCHY_t primaryHandle, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_SENSITIVE_CREATE_t *inSensitive, - const TPM2B_PUBLIC_t *inPublic, - const TPM2B_DATA_t *outsideInfo, - const TPML_PCR_SELECTION_t *creationPCR, - TPM_HANDLE_t *objectHandle, - TPM2B_PUBLIC_t *outPublic, - TPM2B_CREATION_DATA_t *creationData, - TPM2B_DIGEST_t *creationHash, - TPMT_TK_CREATION_t *creationTicket, - TPM2B_NAME_t *name, - TPMS_AUTH_RESPONSE_t *authResponse); - -extern TPM_RC_t -grub_tpm2_startauthsession (const TPMI_DH_OBJECT_t tpmKey, - const TPMI_DH_ENTITY_t bind, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_NONCE_t *nonceCaller, - const TPM2B_ENCRYPTED_SECRET_t *encryptedSalt, - const TPM_SE_t sessionType, - const TPMT_SYM_DEF_t *symmetric, - const TPMI_ALG_HASH_t authHash, - TPMI_SH_AUTH_SESSION_t *sessionHandle, - TPM2B_NONCE_t *nonceTpm, - TPMS_AUTH_RESPONSE_t *authResponse); - -extern TPM_RC_t -grub_tpm2_policypcr (const TPMI_SH_POLICY_t policySession, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_DIGEST_t *pcrDigest, - const TPML_PCR_SELECTION_t *pcrs, - TPMS_AUTH_RESPONSE_t *authResponse); - -extern TPM_RC_t -grub_tpm2_readpublic (const TPMI_DH_OBJECT_t objectHandle, - const TPMS_AUTH_COMMAND_t *authCommand, - TPM2B_PUBLIC_t *outPublic); - -extern TPM_RC_t -grub_tpm2_load (const TPMI_DH_OBJECT_t parent_handle, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_PRIVATE_t *inPrivate, - const TPM2B_PUBLIC_t *inPublic, - TPM_HANDLE_t *objectHandle, - TPM2B_NAME_t *name, - TPMS_AUTH_RESPONSE_t *authResponse); - -extern TPM_RC_t -grub_tpm2_loadexternal (const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_SENSITIVE_t *inPrivate, - const TPM2B_PUBLIC_t *inPublic, - const TPMI_RH_HIERARCHY_t hierarchy, - TPM_HANDLE_t *objectHandle, - TPM2B_NAME_t *name, - TPMS_AUTH_RESPONSE_t *authResponse); - -extern TPM_RC_t -grub_tpm2_unseal (const TPMI_DH_OBJECT_t item_handle, - const TPMS_AUTH_COMMAND_t *authCommand, - TPM2B_SENSITIVE_DATA_t *outData, - TPMS_AUTH_RESPONSE_t *authResponse); - -extern TPM_RC_t -grub_tpm2_flushcontext (const TPMI_DH_CONTEXT_t handle); - -extern TPM_RC_t -grub_tpm2_pcr_read (const TPMS_AUTH_COMMAND_t *authCommand, - const TPML_PCR_SELECTION_t *pcrSelectionIn, - grub_uint32_t *pcrUpdateCounter, - TPML_PCR_SELECTION_t *pcrSelectionOut, - TPML_DIGEST_t *pcrValues, - TPMS_AUTH_RESPONSE_t *authResponse); - -extern TPM_RC_t -grub_tpm2_policygetdigest (const TPMI_SH_POLICY_t policySession, - const TPMS_AUTH_COMMAND_t *authCommand, - TPM2B_DIGEST_t *policyDigest, - TPMS_AUTH_RESPONSE_t *authResponse); - -extern TPM_RC_t -grub_tpm2_create (const TPMI_DH_OBJECT_t parentHandle, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_SENSITIVE_CREATE_t *inSensitive, - const TPM2B_PUBLIC_t *inPublic, - const TPM2B_DATA_t *outsideInfo, - const TPML_PCR_SELECTION_t *creationPCR, - TPM2B_PRIVATE_t *outPrivate, - TPM2B_PUBLIC_t *outPublic, - TPM2B_CREATION_DATA_t *creationData, - TPM2B_DIGEST_t *creationHash, - TPMT_TK_CREATION_t *creationTicket, - TPMS_AUTH_RESPONSE_t *authResponse); - -extern TPM_RC_t -grub_tpm2_evictcontrol (const TPMI_RH_PROVISION_t auth, - const TPMI_DH_OBJECT_t objectHandle, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPMI_DH_PERSISTENT_t persistentHandle, - TPMS_AUTH_RESPONSE_t *authResponse); - -extern TPM_RC_t -grub_tpm2_hash (const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_MAX_BUFFER_t *data, - const TPMI_ALG_HASH_t hashAlg, - const TPMI_RH_HIERARCHY_t hierarchy, - TPM2B_DIGEST_t *outHash, - TPMT_TK_HASHCHECK_t *validation, - TPMS_AUTH_RESPONSE_t *authResponse); - -extern TPM_RC_t -grub_tpm2_verifysignature (const TPMI_DH_OBJECT_t keyHandle, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_DIGEST_t *digest, - const TPMT_SIGNATURE_t *signature, - TPMT_TK_VERIFIED_t *validation, - TPMS_AUTH_RESPONSE_t *authResponse); - -extern TPM_RC_t -grub_tpm2_policyauthorize (const TPMI_SH_POLICY_t policySession, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_DIGEST_t *approvedPolicy, - const TPM2B_NONCE_t *policyRef, - const TPM2B_NAME_t *keySign, - const TPMT_TK_VERIFIED_t *checkTicket, - TPMS_AUTH_RESPONSE_t *authResponse); - -extern TPM_RC_t -grub_tpm2_testparms (const TPMT_PUBLIC_PARMS_t *parms, - const TPMS_AUTH_COMMAND_t *authCommand); - -extern TPM_RC_t -grub_tpm2_nv_definespace (const TPMI_RH_PROVISION_t authHandle, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_AUTH_t *auth, - const TPM2B_NV_PUBLIC_t *publicInfo); - -extern TPM_RC_t -grub_tpm2_nv_undefinespace (const TPMI_RH_PROVISION_t authHandle, - const TPMI_RH_NV_INDEX_t nvIndex, - const TPMS_AUTH_COMMAND_t *authCommand); - -extern TPM_RC_t -grub_tpm2_nv_readpublic (const TPMI_RH_NV_INDEX_t nvIndex, - const TPMS_AUTH_COMMAND_t *authCommand, - TPM2B_NV_PUBLIC_t *nvPublic, - TPM2B_NAME_t *nvName); - -extern TPM_RC_t -grub_tpm2_nv_read (const TPMI_RH_NV_AUTH_t authHandle, - const TPMI_RH_NV_INDEX_t nvIndex, - const TPMS_AUTH_COMMAND_t *authCommand, - const grub_uint16_t size, - const grub_uint16_t offset, - TPM2B_MAX_NV_BUFFER_t *data); - -extern TPM_RC_t -grub_tpm2_nv_write (const TPMI_RH_NV_AUTH_t authHandle, - const TPMI_RH_NV_INDEX_t nvIndex, - const TPMS_AUTH_COMMAND_t *authCommand, - const TPM2B_MAX_NV_BUFFER_t *data, - const grub_uint16_t offset); - -#endif /* ! GRUB_TPM2_COMMANDS_HEADER */ diff --git a/grub-core/lib/tss2/tss2.c b/grub-core/lib/tss2/tss2.c deleted file mode 100644 index 48251e9b4..000000000 --- a/grub-core/lib/tss2/tss2.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -GRUB_MOD_LICENSE ("GPLv3+"); diff --git a/grub-core/lib/tss2/tss2_buffer.h b/grub-core/lib/tss2/tss2_buffer.h deleted file mode 100644 index fb9db1aed..000000000 --- a/grub-core/lib/tss2/tss2_buffer.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_TPM2_BUFFER_HEADER -#define GRUB_TPM2_BUFFER_HEADER 1 - -#include - -#define GRUB_TPM2_BUFFER_CAPACITY 4096 - -struct grub_tpm2_buffer -{ - grub_uint8_t data[GRUB_TPM2_BUFFER_CAPACITY]; - grub_size_t size; - grub_size_t offset; - grub_size_t cap; - bool error; -}; -typedef struct grub_tpm2_buffer *grub_tpm2_buffer_t; - -extern void -grub_tpm2_buffer_init (grub_tpm2_buffer_t buffer); - -extern void -grub_tpm2_buffer_pack (grub_tpm2_buffer_t buffer, const void *data, grub_size_t size); - -extern void -grub_tpm2_buffer_pack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t value); - -extern void -grub_tpm2_buffer_pack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t value); - -extern void -grub_tpm2_buffer_pack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t value); - -extern void -grub_tpm2_buffer_unpack (grub_tpm2_buffer_t buffer, void *data, grub_size_t size); - -extern void -grub_tpm2_buffer_unpack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t *value); - -extern void -grub_tpm2_buffer_unpack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t *value); - -extern void -grub_tpm2_buffer_unpack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t *value); - -#endif /* ! GRUB_TPM2_BUFFER_HEADER */ diff --git a/grub-core/lib/tss2/tss2_mu.c b/grub-core/lib/tss2/tss2_mu.c deleted file mode 100644 index 816e5b37f..000000000 --- a/grub-core/lib/tss2/tss2_mu.c +++ /dev/null @@ -1,1213 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include - -void -grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_AUTH_COMMAND_t *authCommand) -{ - grub_uint32_t start; - grub_uint32_t tmp; - - grub_tpm2_buffer_pack_u32 (buffer, 0); - start = buffer->size; - - grub_tpm2_buffer_pack_u32 (buffer, authCommand->sessionHandle); - - grub_tpm2_buffer_pack_u16 (buffer, authCommand->nonce.size); - grub_tpm2_buffer_pack (buffer, authCommand->nonce.buffer, authCommand->nonce.size); - - grub_tpm2_buffer_pack_u8 (buffer, *((const grub_uint8_t *) &authCommand->sessionAttributes)); - - grub_tpm2_buffer_pack_u16 (buffer, authCommand->hmac.size); - grub_tpm2_buffer_pack (buffer, authCommand->hmac.buffer, authCommand->hmac.size); - - tmp = grub_cpu_to_be32 (buffer->size - start); - grub_memcpy (&buffer->data[start - sizeof (grub_uint32_t)], &tmp, sizeof (tmp)); -} - -void -grub_Tss2_MU_TPM2B_Marshal (grub_tpm2_buffer_t buffer, - const grub_uint16_t size, - const grub_uint8_t *b) -{ - grub_uint16_t i; - - grub_tpm2_buffer_pack_u16 (buffer, size); - - for (i = 0; i < size; i++) - grub_tpm2_buffer_pack_u8 (buffer, b[i]); -} - -void -grub_Tss2_MU_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_SYM_OBJECT_t algorithm, - const TPMU_SYM_KEY_BITS_t *p) -{ - switch (algorithm) - { - case TPM_ALG_AES: - case TPM_ALG_SM4: - case TPM_ALG_CAMELLIA: - case TPM_ALG_XOR: - grub_tpm2_buffer_pack_u16 (buffer, *((const grub_uint16_t *) p)); - break; - case TPM_ALG_NULL: - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_SYM_OBJECT_t algorithm, - const TPMU_SYM_MODE_t *p) -{ - switch (algorithm) - { - case TPM_ALG_AES: - case TPM_ALG_SM4: - case TPM_ALG_CAMELLIA: - grub_tpm2_buffer_pack_u16 (buffer, *((const grub_uint16_t *) p)); - break; - case TPM_ALG_XOR: - case TPM_ALG_NULL: - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_SYM_DEF_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->algorithm); - grub_Tss2_MU_TPMU_SYM_KEY_BITS_Marshal (buffer, p->algorithm, &p->keyBits); - grub_Tss2_MU_TPMU_SYM_MODE_Marshal (buffer, p->algorithm, &p->mode); -} - -void -grub_Tss2_MU_TPMS_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_PCR_SELECTION_t *pcrSelection) -{ - grub_uint32_t i; - - grub_tpm2_buffer_pack_u16 (buffer, pcrSelection->hash); - grub_tpm2_buffer_pack_u8 (buffer, pcrSelection->sizeOfSelect); - - for (i = 0; i < pcrSelection->sizeOfSelect; i++) - grub_tpm2_buffer_pack_u8 (buffer, pcrSelection->pcrSelect[i]); -} - -void -grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer, - const TPML_PCR_SELECTION_t *pcrSelection) -{ - grub_uint32_t i; - - grub_tpm2_buffer_pack_u32 (buffer, pcrSelection->count); - - for (i = 0; i < pcrSelection->count; i++) - grub_Tss2_MU_TPMS_PCR_SELECTION_Marshal (buffer, &pcrSelection->pcrSelections[i]); -} - -void -grub_Tss2_MU_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buffer, - const TPMA_OBJECT_t *p) -{ - grub_tpm2_buffer_pack_u32 (buffer, *((const grub_uint32_t *) p)); -} - -void -grub_Tss2_MU_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_SCHEME_XOR_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg); - grub_tpm2_buffer_pack_u16 (buffer, p->kdf); -} - -void -grub_Tss2_MU_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_SCHEME_HMAC_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg); -} - -void -grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_KEYEDHASH_SCHEME_t scheme, - const TPMU_SCHEME_KEYEDHASH_t *p) -{ - switch (scheme) - { - case TPM_ALG_HMAC: - grub_Tss2_MU_TPMS_SCHEME_HMAC_Marshal (buffer, &p->hmac); - break; - case TPM_ALG_XOR: - grub_Tss2_MU_TPMS_SCHEME_XOR_Marshal (buffer, &p->exclusiveOr); - break; - case TPM_ALG_NULL: - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_KEYEDHASH_SCHEME_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->scheme); - grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Marshal (buffer, p->scheme, &p->details); -} - -void -grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_KEYEDHASH_PARMS_t *p) -{ - grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Marshal (buffer, &p->scheme); -} - -void -grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_SYM_DEF_OBJECT_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->algorithm); - grub_Tss2_MU_TPMU_SYM_KEY_BITS_Marshal (buffer, p->algorithm, &p->keyBits); - grub_Tss2_MU_TPMU_SYM_MODE_Marshal (buffer, p->algorithm, &p->mode); -} - -void -grub_Tss2_MU_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_RSA_DECRYPT_t scheme, - const TPMU_ASYM_SCHEME_t *p __attribute__ ((unused))) -{ - switch (scheme) - { - case TPM_ALG_NULL: - break; - default: - /* Unsupported */ - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_RSA_SCHEME_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->scheme); - grub_Tss2_MU_TPMU_ASYM_SCHEME_Marshal (buffer, p->scheme, &p->details); -} - -void -grub_Tss2_MU_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_RSA_PARMS_t *p) -{ - grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->symmetric); - grub_Tss2_MU_TPMT_RSA_SCHEME_Marshal (buffer, &p->scheme); - grub_tpm2_buffer_pack_u16 (buffer, p->keyBits); - grub_tpm2_buffer_pack_u32 (buffer, p->exponent); -} - -void -grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_SYMCIPHER_PARMS_t *p) -{ - grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->sym); -} - -void -grub_Tss2_MU_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_ECC_SCHEME_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->scheme); - grub_Tss2_MU_TPMU_ASYM_SCHEME_Marshal (buffer, p->scheme, &p->details); -} - -void -grub_Tss2_MU_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_KDF_t scheme, - const TPMU_KDF_SCHEME_t *p) -{ - switch (scheme) - { - case TPM_ALG_MGF1: - grub_tpm2_buffer_pack_u16 (buffer, p->mgf1.hashAlg); - break; - case TPM_ALG_KDF1_SP800_56A: - grub_tpm2_buffer_pack_u16 (buffer, p->kdf1_sp800_56a.hashAlg); - break; - case TPM_ALG_KDF2: - grub_tpm2_buffer_pack_u16 (buffer, p->kdf2.hashAlg); - break; - case TPM_ALG_KDF1_SP800_108: - grub_tpm2_buffer_pack_u16 (buffer, p->kdf1_sp800_108.hashAlg); - break; - case TPM_ALG_NULL: - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_KDF_SCHEME_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->scheme); - grub_Tss2_MU_TPMU_KDF_SCHEME_Marshal (buffer, p->scheme, &p->details); -} - -void -grub_Tss2_MU_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_ECC_PARMS_t *p) -{ - grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->symmetric); - grub_Tss2_MU_TPMT_ECC_SCHEME_Marshal (buffer, &p->scheme); - grub_tpm2_buffer_pack_u16 (buffer, p->curveID); - grub_Tss2_MU_TPMT_KDF_SCHEME_Marshal (buffer, &p->kdf); -} - -void -grub_Tss2_MU_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer, - const grub_uint32_t type, - const TPMU_PUBLIC_PARMS_t *p) -{ - switch (type) - { - case TPM_ALG_KEYEDHASH: - grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Marshal (buffer, &p->keyedHashDetail); - break; - case TPM_ALG_SYMCIPHER: - grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Marshal (buffer, &p->symDetail); - break; - case TPM_ALG_RSA: - grub_Tss2_MU_TPMS_RSA_PARMS_Marshal (buffer, &p->rsaDetail); - break; - case TPM_ALG_ECC: - grub_Tss2_MU_TPMS_ECC_PARMS_Marshal (buffer, &p->eccDetail); - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_ECC_POINT_t *p) -{ - grub_Tss2_MU_TPM2B_Marshal (buffer, p->x.size, p->x.buffer); - grub_Tss2_MU_TPM2B_Marshal (buffer, p->y.size, p->y.buffer); -} - -void -grub_Tss2_MU_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_PUBLIC_t type, - const TPMU_PUBLIC_ID_t *p) -{ - switch(type) - { - case TPM_ALG_KEYEDHASH: - grub_Tss2_MU_TPM2B_Marshal (buffer, p->keyedHash.size, p->keyedHash.buffer); - break; - case TPM_ALG_SYMCIPHER: - grub_Tss2_MU_TPM2B_Marshal (buffer, p->sym.size, p->sym.buffer); - break; - case TPM_ALG_RSA: - grub_Tss2_MU_TPM2B_Marshal (buffer, p->rsa.size, p->rsa.buffer); - break; - case TPM_ALG_ECC: - grub_Tss2_MU_TPMS_ECC_POINT_Marshal (buffer, &p->ecc); - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMT_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_PUBLIC_PARMS_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->type); - grub_Tss2_MU_TPMU_PUBLIC_PARMS_Marshal (buffer, p->type, &p->parameters); -} - -void -grub_Tss2_MU_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_PUBLIC_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->type); - grub_tpm2_buffer_pack_u16 (buffer, p->nameAlg); - grub_Tss2_MU_TPMA_OBJECT_Marshal (buffer, &p->objectAttributes); - grub_Tss2_MU_TPM2B_Marshal (buffer, p->authPolicy.size, p->authPolicy.buffer); - grub_Tss2_MU_TPMU_PUBLIC_PARMS_Marshal (buffer, p->type, &p->parameters); - grub_Tss2_MU_TPMU_PUBLIC_ID_Marshal (buffer, p->type, &p->unique); -} - -void -grub_Tss2_MU_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, - const TPM2B_PUBLIC_t *p) -{ - grub_uint32_t start; - grub_uint16_t size; - - if (p) - { - grub_tpm2_buffer_pack_u16 (buffer, p->size); - - start = buffer->size; - grub_Tss2_MU_TPMT_PUBLIC_Marshal (buffer, &p->publicArea); - size = grub_cpu_to_be16 (buffer->size - start); - grub_memcpy (&buffer->data[start - sizeof (grub_uint16_t)], &size, sizeof (size)); - } - else - grub_tpm2_buffer_pack_u16 (buffer, 0); -} - -void -grub_Tss2_MU_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_SENSITIVE_CREATE_t *p) -{ - grub_Tss2_MU_TPM2B_Marshal (buffer, p->userAuth.size, p->userAuth.buffer); - grub_Tss2_MU_TPM2B_Marshal (buffer, p->data.size, p->data.buffer); -} - -void -grub_Tss2_MU_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_PUBLIC_t type, - const TPMU_SENSITIVE_COMPOSITE_t *p) -{ - switch(type) - { - case TPM_ALG_RSA: - grub_Tss2_MU_TPM2B_Marshal (buffer, p->rsa.size, p->rsa.buffer); - break; - case TPM_ALG_ECC: - grub_Tss2_MU_TPM2B_Marshal (buffer, p->ecc.size, p->ecc.buffer); - break; - case TPM_ALG_KEYEDHASH: - grub_Tss2_MU_TPM2B_Marshal (buffer, p->bits.size, p->bits.buffer); - break; - case TPM_ALG_SYMCIPHER: - grub_Tss2_MU_TPM2B_Marshal (buffer, p->sym.size, p->sym.buffer); - break; - default: - buffer->error = 1; - } -} - -void -grub_Tss2_MU_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_SENSITIVE_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->sensitiveType); - grub_Tss2_MU_TPM2B_Marshal (buffer, p->authValue.size, p->authValue.buffer); - grub_Tss2_MU_TPM2B_Marshal (buffer, p->seedValue.size, p->seedValue.buffer); - grub_Tss2_MU_TPMU_SENSITIVE_COMPOSITE_Marshal (buffer, p->sensitiveType, &p->sensitive); -} - -void -grub_Tss2_MU_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, - const TPM2B_SENSITIVE_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->size); - grub_Tss2_MU_TPMT_SENSITIVE_Marshal (buffer, &p->sensitiveArea); -} - -void -grub_Tss2_MU_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, - const TPM2B_SENSITIVE_CREATE_t *sensitiveCreate) -{ - grub_uint32_t start; - grub_uint16_t size; - - if (sensitiveCreate) - { - grub_tpm2_buffer_pack_u16 (buffer, sensitiveCreate->size); - start = buffer->size; - grub_Tss2_MU_TPMS_SENSITIVE_CREATE_Marshal (buffer, &sensitiveCreate->sensitive); - size = grub_cpu_to_be16 (buffer->size - start); - - grub_memcpy (&buffer->data[start - sizeof (grub_uint16_t)], &size, sizeof (size)); - } - else - grub_tpm2_buffer_pack_u16 (buffer, 0); -} - -void -grub_Tss2_MU_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_SIGNATURE_RSA_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->hash); - grub_Tss2_MU_TPM2B_Marshal (buffer, p->sig.size, p->sig.buffer); -} - -void -grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_SIGNATURE_ECC_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->hash); - grub_Tss2_MU_TPM2B_Marshal (buffer, p->signatureR.size, p->signatureR.buffer); - grub_Tss2_MU_TPM2B_Marshal (buffer, p->signatureS.size, p->signatureS.buffer); -} - -void -grub_Tss2_MU_TPMU_HA_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_HASH_t hashAlg, - const TPMU_HA_t *p) -{ - grub_uint16_t i; - - switch (hashAlg) - { - case TPM_ALG_SHA1: - for (i = 0; i < TPM_SHA1_DIGEST_SIZE; i++) - grub_tpm2_buffer_pack_u8 (buffer, p->sha1[i]); - break; - case TPM_ALG_SHA256: - for (i = 0; i < TPM_SHA256_DIGEST_SIZE; i++) - grub_tpm2_buffer_pack_u8 (buffer, p->sha256[i]); - break; - case TPM_ALG_SHA384: - for (i = 0; i < TPM_SHA384_DIGEST_SIZE; i++) - grub_tpm2_buffer_pack_u8 (buffer, p->sha384[i]); - break; - case TPM_ALG_SHA512: - for (i = 0; i < TPM_SHA512_DIGEST_SIZE; i++) - grub_tpm2_buffer_pack_u8 (buffer, p->sha512[i]); - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMT_HA_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_HA_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg); - grub_Tss2_MU_TPMU_HA_Marshal (buffer, p->hashAlg, &p->digest); -} - -void -grub_Tss2_MU_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_SIG_SCHEME_t sigAlg, - const TPMU_SIGNATURE_t *p) -{ - switch (sigAlg) - { - case TPM_ALG_RSASSA: - grub_Tss2_MU_TPMS_SIGNATURE_RSA_Marshal (buffer, (TPMS_SIGNATURE_RSA_t *) &p->rsassa); - break; - case TPM_ALG_RSAPSS: - grub_Tss2_MU_TPMS_SIGNATURE_RSA_Marshal (buffer, (TPMS_SIGNATURE_RSA_t *) &p->rsapss); - break; - case TPM_ALG_ECDSA: - grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC_t *) &p->ecdsa); - break; - case TPM_ALG_ECDAA: - grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC_t *) &p->ecdaa); - break; - case TPM_ALG_SM2: - grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC_t *) &p->sm2); - break; - case TPM_ALG_ECSCHNORR: - grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC_t *) &p->ecschnorr); - break; - case TPM_ALG_HMAC: - grub_Tss2_MU_TPMT_HA_Marshal (buffer, &p->hmac); - break; - case TPM_ALG_NULL: - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_SIGNATURE_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->sigAlg); - grub_Tss2_MU_TPMU_SIGNATURE_Marshal (buffer, p->sigAlg, &p->signature); -} - -void -grub_Tss2_MU_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_TK_VERIFIED_t *p) -{ - grub_tpm2_buffer_pack_u16 (buffer, p->tag); - grub_tpm2_buffer_pack_u32 (buffer, p->hierarchy); - grub_Tss2_MU_TPM2B_Marshal (buffer, p->digest.size, p->digest.buffer); -} - -void -grub_Tss2_MU_TPMS_NV_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_NV_PUBLIC_t *p) -{ - grub_tpm2_buffer_pack_u32 (buffer, p->nvIndex); - grub_tpm2_buffer_pack_u16 (buffer, p->nameAlg); - grub_tpm2_buffer_pack_u32 (buffer, p->attributes); - grub_Tss2_MU_TPM2B_Marshal (buffer, p->authPolicy.size, p->authPolicy.buffer); - grub_tpm2_buffer_pack_u16 (buffer, p->dataSize); -} - -void -grub_Tss2_MU_TPM2B_NV_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, - const TPM2B_NV_PUBLIC_t *p) -{ - grub_uint32_t start; - grub_uint16_t size; - - if (p != NULL) - { - grub_tpm2_buffer_pack_u16 (buffer, p->size); - - start = buffer->size; - grub_Tss2_MU_TPMS_NV_PUBLIC_Marshal (buffer, &p->nvPublic); - size = grub_cpu_to_be16 (buffer->size - start); - grub_memcpy (&buffer->data[start - sizeof (grub_uint16_t)], &size, sizeof (size)); - } - else - grub_tpm2_buffer_pack_u16 (buffer, 0); -} - -static void -__Tss2_MU_TPM2B_BUFFER_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_t *p, grub_uint16_t bound) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->size); - - if (p->size > bound) - { - buffer->error = 1; - return; - } - - grub_tpm2_buffer_unpack (buffer, &p->buffer, p->size); -} - -#define TPM2B_BUFFER_UNMARSHAL(buffer, type, data) \ - __Tss2_MU_TPM2B_BUFFER_Unmarshal(buffer, (TPM2B_t *)data, sizeof(type) - sizeof(grub_uint16_t)) - -void -grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_AUTH_RESPONSE_t *p) -{ - grub_uint8_t tmp; - grub_uint32_t tmp32; - - grub_tpm2_buffer_unpack_u16 (buffer, &p->nonce.size); - - if (p->nonce.size) - grub_tpm2_buffer_unpack (buffer, &p->nonce.buffer, p->nonce.size); - - grub_tpm2_buffer_unpack_u8 (buffer, &tmp); - tmp32 = tmp; - grub_memcpy (&p->sessionAttributes, &tmp32, sizeof (grub_uint32_t)); - - grub_tpm2_buffer_unpack_u16 (buffer, &p->hmac.size); - - if (p->hmac.size) - grub_tpm2_buffer_unpack (buffer, &p->hmac.buffer, p->hmac.size); -} - -void -grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_DIGEST_t *digest) -{ - TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_DIGEST_t, digest); -} - -void -grub_Tss2_MU_TPM2B_NONCE_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_NONCE_t *nonce) -{ - TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_NONCE_t, nonce); -} - -void -grub_Tss2_MU_TPM2B_DATA_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_DATA_t *data) -{ - TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_DATA_t, data); -} - -void -grub_Tss2_MU_TPMS_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_CREATION_DATA_t *data) -{ - grub_Tss2_MU_TPML_PCR_SELECTION_Unmarshal (buffer, &data->pcrSelect); - grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &data->pcrDigest); - grub_tpm2_buffer_unpack_u8 (buffer, (grub_uint8_t *)&data->locality); - grub_tpm2_buffer_unpack_u16 (buffer, &data->parentNameAlg); - grub_Tss2_MU_TPM2B_NAME_Unmarshal (buffer, &data->parentName); - grub_Tss2_MU_TPM2B_NAME_Unmarshal (buffer, &data->parentQualifiedName); - grub_Tss2_MU_TPM2B_DATA_Unmarshal (buffer, &data->outsideInfo); -} - -void -grub_Tss2_MU_TPM2B_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_CREATION_DATA_t *data) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &data->size); - grub_Tss2_MU_TPMS_CREATION_DATA_Unmarshal (buffer, &data->creationData); -} - -void -grub_Tss2_MU_TPM2B_PRIVATE_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_PRIVATE_t *private) -{ - TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_PRIVATE_t, private); -} - -void -grub_Tss2_MU_TPM2B_SENSITIVE_DATA_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_SENSITIVE_DATA_t *data) -{ - TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_SENSITIVE_DATA_t, data); -} - -void -grub_Tss2_MU_TPM2B_PUBLIC_KEY_RSA_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_PUBLIC_KEY_RSA_t *rsa) -{ - TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_PUBLIC_KEY_RSA_t, rsa); -} - -void -grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_ECC_PARAMETER_t *param) -{ - TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_ECC_PARAMETER_t, param); -} - -void -grub_Tss2_MU_TPMA_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer, - TPMA_OBJECT_t *p) -{ - grub_tpm2_buffer_unpack_u32 (buffer, (grub_uint32_t *) p); -} - -void -grub_Tss2_MU_TPMS_SCHEME_HMAC_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_SCHEME_HMAC_t *p) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg); -} - -void -grub_Tss2_MU_TPMS_SCHEME_XOR_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_SCHEME_XOR_t *p) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg); - grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf); -} - -void -grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_KEYEDHASH_SCHEME_t scheme, - TPMU_SCHEME_KEYEDHASH_t *p) -{ - switch (scheme) - { - case TPM_ALG_HMAC: - grub_Tss2_MU_TPMS_SCHEME_HMAC_Unmarshal (buffer, &p->hmac); - break; - case TPM_ALG_XOR: - grub_Tss2_MU_TPMS_SCHEME_XOR_Unmarshal (buffer, &p->exclusiveOr); - break; - case TPM_ALG_NULL: - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_KEYEDHASH_SCHEME_t *p) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); - grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Unmarshal (buffer, p->scheme, &p->details); -} - -void -grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_KEYEDHASH_PARMS_t *p) -{ - grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Unmarshal (buffer, &p->scheme); -} - -void -grub_Tss2_MU_TPMU_SYM_KEY_BITS_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_SYM_OBJECT_t algorithm, - TPMU_SYM_KEY_BITS_t *p) -{ - switch (algorithm) - { - case TPM_ALG_AES: - case TPM_ALG_SM4: - case TPM_ALG_CAMELLIA: - case TPM_ALG_XOR: - grub_tpm2_buffer_unpack_u16 (buffer, (grub_uint16_t *) p); - break; - case TPM_ALG_NULL: - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMU_SYM_MODE_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_SYM_OBJECT_t algorithm, - TPMU_SYM_MODE_t *p) -{ - switch (algorithm) - { - case TPM_ALG_AES: - case TPM_ALG_SM4: - case TPM_ALG_CAMELLIA: - grub_tpm2_buffer_unpack_u16 (buffer, (grub_uint16_t *) p); - break; - case TPM_ALG_XOR: - case TPM_ALG_NULL: - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_SYM_DEF_OBJECT_t *p) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->algorithm); - grub_Tss2_MU_TPMU_SYM_KEY_BITS_Unmarshal (buffer, p->algorithm, &p->keyBits); - grub_Tss2_MU_TPMU_SYM_MODE_Unmarshal (buffer, p->algorithm, &p->mode); -} - -void -grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_SYMCIPHER_PARMS_t *p) -{ - grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->sym); -} - -void -grub_Tss2_MU_TPMU_ASYM_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_RSA_DECRYPT_t scheme, - TPMU_ASYM_SCHEME_t *p __attribute__((unused))) -{ - switch (scheme) - { - case TPM_ALG_NULL: - break; - default: - /* Unsupported */ - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMT_RSA_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_RSA_SCHEME_t *p) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); - grub_Tss2_MU_TPMU_ASYM_SCHEME_Unmarshal (buffer, p->scheme, &p->details); -} - -void -grub_Tss2_MU_TPMS_RSA_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_RSA_PARMS_t *p) -{ - grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->symmetric); - grub_Tss2_MU_TPMT_RSA_SCHEME_Unmarshal (buffer, &p->scheme); - grub_tpm2_buffer_unpack_u16 (buffer, &p->keyBits); - grub_tpm2_buffer_unpack_u32 (buffer, &p->exponent); -} - -void -grub_Tss2_MU_TPMT_ECC_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_ECC_SCHEME_t *p) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); - grub_Tss2_MU_TPMU_ASYM_SCHEME_Unmarshal (buffer, p->scheme, &p->details); -} - -void -grub_Tss2_MU_TPMU_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_KDF_t scheme, - TPMU_KDF_SCHEME_t *p) -{ - switch (scheme) - { - case TPM_ALG_MGF1: - grub_tpm2_buffer_unpack_u16 (buffer, &p->mgf1.hashAlg); - break; - case TPM_ALG_KDF1_SP800_56A: - grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf1_sp800_56a.hashAlg); - break; - case TPM_ALG_KDF2: - grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf2.hashAlg); - break; - case TPM_ALG_KDF1_SP800_108: - grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf1_sp800_108.hashAlg); - break; - case TPM_ALG_NULL: - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMT_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_KDF_SCHEME_t *p) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); - grub_Tss2_MU_TPMU_KDF_SCHEME_Unmarshal (buffer, p->scheme, &p->details); -} - -void -grub_Tss2_MU_TPMS_ECC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_ECC_PARMS_t *p) -{ - grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->symmetric); - grub_Tss2_MU_TPMT_ECC_SCHEME_Unmarshal (buffer, &p->scheme ); - grub_tpm2_buffer_unpack_u16 (buffer, &p->curveID); - grub_Tss2_MU_TPMT_KDF_SCHEME_Unmarshal (buffer, &p->kdf); -} - -void -grub_Tss2_MU_TPMU_PUBLIC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, - grub_uint32_t type, - TPMU_PUBLIC_PARMS_t *p) -{ - switch (type) - { - case TPM_ALG_KEYEDHASH: - grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Unmarshal (buffer, &p->keyedHashDetail); - break; - case TPM_ALG_SYMCIPHER: - grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Unmarshal (buffer, &p->symDetail); - break; - case TPM_ALG_RSA: - grub_Tss2_MU_TPMS_RSA_PARMS_Unmarshal (buffer, &p->rsaDetail); - break; - case TPM_ALG_ECC: - grub_Tss2_MU_TPMS_ECC_PARMS_Unmarshal (buffer, &p->eccDetail); - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMS_ECC_POINT_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_ECC_POINT_t *p) -{ - grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &p->x); - grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &p->y); -} - -void -grub_Tss2_MU_TPMU_PUBLIC_ID_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_PUBLIC_t type, - TPMU_PUBLIC_ID_t *p) -{ - switch(type) - { - case TPM_ALG_KEYEDHASH: - grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->keyedHash); - break; - case TPM_ALG_SYMCIPHER: - grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->sym); - break; - case TPM_ALG_RSA: - grub_Tss2_MU_TPM2B_PUBLIC_KEY_RSA_Unmarshal (buffer, &p->rsa); - break; - case TPM_ALG_ECC: - grub_Tss2_MU_TPMS_ECC_POINT_Unmarshal (buffer, &p->ecc); - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMT_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_PUBLIC_t *p) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->type); - grub_tpm2_buffer_unpack_u16 (buffer, &p->nameAlg); - grub_Tss2_MU_TPMA_OBJECT_Unmarshal (buffer, &p->objectAttributes); - grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->authPolicy); - grub_Tss2_MU_TPMU_PUBLIC_PARMS_Unmarshal (buffer, p->type, &p->parameters); - grub_Tss2_MU_TPMU_PUBLIC_ID_Unmarshal (buffer, p->type, &p->unique); -} - -void -grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_PUBLIC_t *p) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->size); - grub_Tss2_MU_TPMT_PUBLIC_Unmarshal (buffer, &p->publicArea); -} - -void -grub_Tss2_MU_TPMS_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_NV_PUBLIC_t *p) -{ - grub_tpm2_buffer_unpack_u32 (buffer, &p->nvIndex); - grub_tpm2_buffer_unpack_u16 (buffer, &p->nameAlg); - grub_tpm2_buffer_unpack_u32 (buffer, &p->attributes); - grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->authPolicy); - grub_tpm2_buffer_unpack_u16 (buffer, &p->dataSize); -} - -void -grub_Tss2_MU_TPM2B_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_NV_PUBLIC_t *p) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->size); - grub_Tss2_MU_TPMS_NV_PUBLIC_Unmarshal (buffer, &p->nvPublic); -} - -void -grub_Tss2_MU_TPM2B_NAX_NV_BUFFER_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_MAX_NV_BUFFER_t *p) -{ - TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_MAX_NV_BUFFER_t, p); -} - -void -grub_Tss2_MU_TPM2B_NAME_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_NAME_t *n) -{ - TPM2B_BUFFER_UNMARSHAL (buffer, TPM2B_NAME_t, n); -} - -void -grub_Tss2_MU_TPMS_TAGGED_PROPERTY_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_TAGGED_PROPERTY_t *property) -{ - grub_tpm2_buffer_unpack_u32 (buffer, &property->property); - grub_tpm2_buffer_unpack_u32 (buffer, &property->value); -} - -void -grub_Tss2_MU_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_TK_CREATION_t *p) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->tag); - grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy); - grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->digest); -} - -void -grub_Tss2_MU_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_TK_HASHCHECK_t *p) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->tag); - grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy); - grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->digest); -} - -void -grub_Tss2_MU_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_TK_VERIFIED_t *p) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->tag); - grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy); - grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &p->digest); -} - -void -grub_Tss2_MU_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_PCR_SELECTION_t *pcrSelection) -{ - grub_uint32_t i; - - grub_tpm2_buffer_unpack_u16 (buffer, &pcrSelection->hash); - grub_tpm2_buffer_unpack_u8 (buffer, &pcrSelection->sizeOfSelect); - - if (pcrSelection->sizeOfSelect > TPM_PCR_SELECT_MAX) - { - buffer->error = 1; - return; - } - - for (i = 0; i < pcrSelection->sizeOfSelect; i++) - grub_tpm2_buffer_unpack_u8 (buffer, &pcrSelection->pcrSelect[i]); -} - -void -grub_Tss2_MU_TPML_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer, - TPML_PCR_SELECTION_t *pcrSelection) -{ - grub_uint32_t i; - - grub_tpm2_buffer_unpack_u32 (buffer, &pcrSelection->count); - - if (pcrSelection->count > TPM_NUM_PCR_BANKS) - { - buffer->error = 1; - return; - } - - for (i = 0; i < pcrSelection->count; i++) - grub_Tss2_MU_TPMS_PCR_SELECTION_Unmarshal (buffer, &pcrSelection->pcrSelections[i]); -} - -void -grub_Tss2_MU_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer, - TPML_DIGEST_t *digest) -{ - grub_uint32_t i; - - grub_tpm2_buffer_unpack_u32 (buffer, &digest->count); - - if (digest->count > 8) - { - buffer->error = 1; - return; - } - - for (i = 0; i < digest->count; i++) - grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (buffer, &digest->digests[i]); -} - -void -grub_Tss2_MU_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_SIGNATURE_RSA_t *rsa) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &rsa->hash); - grub_Tss2_MU_TPM2B_PUBLIC_KEY_RSA_Unmarshal (buffer, &rsa->sig); -} - -void -grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_SIGNATURE_ECC_t *ecc) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &ecc->hash); - grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &ecc->signatureR); - grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (buffer, &ecc->signatureS); -} - -void -grub_Tss2_MU_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_HASH_t hashAlg, - TPMU_HA_t *p) -{ - switch (hashAlg) - { - case TPM_ALG_SHA1: - grub_tpm2_buffer_unpack (buffer, &p->sha1, TPM_SHA1_DIGEST_SIZE); - break; - case TPM_ALG_SHA256: - grub_tpm2_buffer_unpack (buffer, &p->sha256, TPM_SHA256_DIGEST_SIZE); - break; - case TPM_ALG_SHA384: - grub_tpm2_buffer_unpack (buffer, &p->sha384, TPM_SHA384_DIGEST_SIZE); - break; - case TPM_ALG_SHA512: - grub_tpm2_buffer_unpack (buffer, &p->sha512, TPM_SHA512_DIGEST_SIZE); - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_HA_t *p) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg); - grub_Tss2_MU_TPMU_HA_Unmarshal (buffer, p->hashAlg, &p->digest); -} - -void -grub_Tss2_MU_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_SIG_SCHEME_t sigAlg, - TPMU_SIGNATURE_t *p) -{ - switch (sigAlg) - { - case TPM_ALG_RSASSA: - grub_Tss2_MU_TPMS_SIGNATURE_RSA_Unmarshal (buffer, (TPMS_SIGNATURE_RSA_t *)&p->rsassa); - break; - case TPM_ALG_RSAPSS: - grub_Tss2_MU_TPMS_SIGNATURE_RSA_Unmarshal (buffer, (TPMS_SIGNATURE_RSA_t *)&p->rsapss); - break; - case TPM_ALG_ECDSA: - grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC_t *)&p->ecdsa); - break; - case TPM_ALG_ECDAA: - grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC_t *)&p->ecdaa); - break; - case TPM_ALG_SM2: - grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC_t *)&p->sm2); - break; - case TPM_ALG_ECSCHNORR: - grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC_t *)&p->ecschnorr); - break; - case TPM_ALG_HMAC: - grub_Tss2_MU_TPMT_HA_Unmarshal (buffer, &p->hmac); - break; - case TPM_ALG_NULL: - break; - default: - buffer->error = 1; - break; - } -} - -void -grub_Tss2_MU_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_SIGNATURE_t *p) -{ - grub_tpm2_buffer_unpack_u16 (buffer, &p->sigAlg); - grub_Tss2_MU_TPMU_SIGNATURE_Unmarshal (buffer, p->sigAlg, &p->signature); -} diff --git a/grub-core/lib/tss2/tss2_mu.h b/grub-core/lib/tss2/tss2_mu.h deleted file mode 100644 index 6440de57c..000000000 --- a/grub-core/lib/tss2/tss2_mu.h +++ /dev/null @@ -1,409 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_TPM2_MU_HEADER -#define GRUB_TPM2_MU_HEADER 1 - -#include -#include - -extern void -grub_Tss2_MU_TPMS_AUTH_COMMAND_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_AUTH_COMMAND_t *authCommand); - -extern void -grub_Tss2_MU_TPM2B_Marshal (grub_tpm2_buffer_t buffer, - const grub_uint16_t size, - const grub_uint8_t *b); - -extern void -grub_Tss2_MU_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_SYM_OBJECT_t algorithm, - const TPMU_SYM_KEY_BITS_t *p); - -extern void -grub_Tss2_MU_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_SYM_OBJECT_t algorithm, - const TPMU_SYM_MODE_t *p); - -extern void -grub_Tss2_MU_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_SYM_DEF_t *p); - -extern void -grub_Tss2_MU_TPMS_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_PCR_SELECTION_t *pcrSelection); - -extern void -grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer, - const TPML_PCR_SELECTION_t *pcrSelection); - -extern void -grub_Tss2_MU_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buffer, - const TPMA_OBJECT_t *p); - -extern void -grub_Tss2_MU_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_SCHEME_XOR_t *p); - -extern void -grub_Tss2_MU_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_SCHEME_HMAC_t *p); - -extern void -grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_KEYEDHASH_SCHEME_t scheme, - const TPMU_SCHEME_KEYEDHASH_t *p); - -extern void -grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_KEYEDHASH_SCHEME_t *p); - -extern void -grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_KEYEDHASH_PARMS_t *p); - -extern void -grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_SYM_DEF_OBJECT_t *p); - -extern void -grub_Tss2_MU_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_RSA_DECRYPT_t scheme, - const TPMU_ASYM_SCHEME_t *p); - -extern void -grub_Tss2_MU_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_RSA_SCHEME_t *p); - -extern void -grub_Tss2_MU_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_RSA_PARMS_t *p); - -extern void -grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_SYMCIPHER_PARMS_t *p); - -extern void -grub_Tss2_MU_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_ECC_SCHEME_t *p); - -extern void -grub_Tss2_MU_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_KDF_t scheme, - const TPMU_KDF_SCHEME_t *p); - -extern void -grub_Tss2_MU_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_KDF_SCHEME_t *p); - -extern void -grub_Tss2_MU_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_ECC_PARMS_t *p); - -extern void -grub_Tss2_MU_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer, - const grub_uint32_t type, - const TPMU_PUBLIC_PARMS_t *p); - -extern void -grub_Tss2_MU_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_ECC_POINT_t *p); - -extern void -grub_Tss2_MU_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_PUBLIC_t type, - const TPMU_PUBLIC_ID_t *p); - -extern void -grub_Tss2_MU_TPMT_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_PUBLIC_PARMS_t *p); - -extern void -grub_Tss2_MU_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_PUBLIC_t *p); - -extern void -grub_Tss2_MU_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, - const TPM2B_PUBLIC_t *p); - -extern void -grub_Tss2_MU_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_SENSITIVE_CREATE_t *p); - -extern void -grub_Tss2_MU_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, - const TPM2B_SENSITIVE_CREATE_t *sensitiveCreate); - -extern void -grub_Tss2_MU_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_PUBLIC_t type, - const TPMU_SENSITIVE_COMPOSITE_t *p); -extern void -grub_Tss2_MU_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_SENSITIVE_t *p); - -extern void -grub_Tss2_MU_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, - const TPM2B_SENSITIVE_t *p); - -extern void -grub_Tss2_MU_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_SIGNATURE_RSA_t *p); - -extern void -grub_Tss2_MU_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_SIGNATURE_ECC_t *p); - -extern void -grub_Tss2_MU_TPMU_HA_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_HASH_t hashAlg, - const TPMU_HA_t *p); - -extern void -grub_Tss2_MU_TPMT_HA_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_HA_t *p); - -extern void -grub_Tss2_MU_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, - const TPMI_ALG_SIG_SCHEME_t sigAlg, - const TPMU_SIGNATURE_t *p); - -extern void -grub_Tss2_MU_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_SIGNATURE_t *p); - -extern void -grub_Tss2_MU_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buffer, - const TPMT_TK_VERIFIED_t *p); - -extern void -grub_Tss2_MU_TPMS_NV_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, - const TPMS_NV_PUBLIC_t *p); - -extern void -grub_Tss2_MU_TPM2B_NV_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, - const TPM2B_NV_PUBLIC_t *p); - -extern void -grub_Tss2_MU_TPMS_AUTH_RESPONSE_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_AUTH_RESPONSE_t *p); - -extern void -grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_DIGEST_t *digest); - -extern void -grub_Tss2_MU_TPM2B_NONCE_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_NONCE_t *nonce); - -extern void -grub_Tss2_MU_TPM2B_DATA_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_DATA_t *data); - -extern void -grub_Tss2_MU_TPMS_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_CREATION_DATA_t *data); - -extern void -grub_Tss2_MU_TPM2B_CREATION_DATA_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_CREATION_DATA_t *data); - -extern void -grub_Tss2_MU_TPM2B_PRIVATE_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_PRIVATE_t *private); - -extern void -grub_Tss2_MU_TPM2B_SENSITIVE_DATA_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_SENSITIVE_DATA_t *data); - -extern void -grub_Tss2_MU_TPM2B_PUBLIC_KEY_RSA_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_PUBLIC_KEY_RSA_t *rsa); - -extern void -grub_Tss2_MU_TPM2B_ECC_PARAMETER_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_ECC_PARAMETER_t *param); - -extern void -grub_Tss2_MU_TPMA_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer, - TPMA_OBJECT_t *p); - -extern void -grub_Tss2_MU_TPMS_SCHEME_HMAC_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_SCHEME_HMAC_t *p); - -extern void -grub_Tss2_MU_TPMS_SCHEME_XOR_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_SCHEME_XOR_t *p); - -extern void -grub_Tss2_MU_TPMU_SCHEME_KEYEDHASH_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_KEYEDHASH_SCHEME_t scheme, - TPMU_SCHEME_KEYEDHASH_t *p); - -extern void -grub_Tss2_MU_TPMT_KEYEDHASH_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_KEYEDHASH_SCHEME_t *p); - -extern void -grub_Tss2_MU_TPMS_KEYEDHASH_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_KEYEDHASH_PARMS_t *p); - -extern void -grub_Tss2_MU_TPMU_SYM_KEY_BITS_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_SYM_OBJECT_t algorithm, - TPMU_SYM_KEY_BITS_t *p); - -extern void -grub_Tss2_MU_TPMU_SYM_MODE_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_SYM_OBJECT_t algorithm, - TPMU_SYM_MODE_t *p); - -extern void -grub_Tss2_MU_TPMT_SYM_DEF_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_SYM_DEF_OBJECT_t *p); - -extern void -grub_Tss2_MU_TPMS_SYMCIPHER_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_SYMCIPHER_PARMS_t *p); - -extern void -grub_Tss2_MU_TPMU_ASYM_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_RSA_DECRYPT_t scheme, - TPMU_ASYM_SCHEME_t *p); - -extern void -grub_Tss2_MU_TPMT_RSA_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_RSA_SCHEME_t *p); - -extern void -grub_Tss2_MU_TPMS_RSA_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_RSA_PARMS_t *p); - -extern void -grub_Tss2_MU_TPMT_ECC_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_ECC_SCHEME_t *p); - -extern void -grub_Tss2_MU_TPMU_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_KDF_t scheme, - TPMU_KDF_SCHEME_t *p); - -extern void -grub_Tss2_MU_TPMT_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_KDF_SCHEME_t *p); - -extern void -grub_Tss2_MU_TPMS_ECC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_ECC_PARMS_t *p); - -extern void -grub_Tss2_MU_TPMU_PUBLIC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, - grub_uint32_t type, - TPMU_PUBLIC_PARMS_t *p); - -extern void -grub_Tss2_MU_TPMS_ECC_POINT_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_ECC_POINT_t *p); - -extern void -grub_Tss2_MU_TPMU_PUBLIC_ID_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_PUBLIC_t type, - TPMU_PUBLIC_ID_t *p); - -extern void -grub_Tss2_MU_TPMT_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_PUBLIC_t *p); - -extern void -grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_PUBLIC_t *p); - -extern void -grub_Tss2_MU_TPMS_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_NV_PUBLIC_t *p); - -extern void -grub_Tss2_MU_TPM2B_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_NV_PUBLIC_t *p); - -extern void -grub_Tss2_MU_TPM2B_NAX_NV_BUFFER_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_MAX_NV_BUFFER_t *p); - -extern void -grub_Tss2_MU_TPM2B_NAME_Unmarshal (grub_tpm2_buffer_t buffer, - TPM2B_NAME_t *n); - -extern void -grub_Tss2_MU_TPMS_TAGGED_PROPERTY_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_TAGGED_PROPERTY_t *property); - -extern void -grub_Tss2_MU_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_TK_CREATION_t *p); - -extern void -grub_Tss2_MU_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_TK_HASHCHECK_t *p); - -extern void -grub_Tss2_MU_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_TK_VERIFIED_t *p); - -extern void -grub_Tss2_MU_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_PCR_SELECTION_t *pcrSelection); - -extern void -grub_Tss2_MU_TPML_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buffer, - TPML_PCR_SELECTION_t *pcrSelection); - -extern void -grub_Tss2_MU_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer, - TPML_DIGEST_t *digest); - -extern void -grub_Tss2_MU_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_SIGNATURE_RSA_t *p); - -extern void -grub_Tss2_MU_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buffer, - TPMS_SIGNATURE_ECC_t *p); - -extern void -grub_Tss2_MU_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_HASH_t hashAlg, - TPMU_HA_t *p); - -extern void -grub_Tss2_MU_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_HA_t *p); - -extern void -grub_Tss2_MU_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, - TPMI_ALG_SIG_SCHEME_t sigAlg, - TPMU_SIGNATURE_t *p); - -extern void -grub_Tss2_MU_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, - TPMT_SIGNATURE_t *p); - -#endif /* ! GRUB_TPM2_MU_HEADER */ diff --git a/grub-core/lib/tss2/tss2_structs.h b/grub-core/lib/tss2/tss2_structs.h deleted file mode 100644 index 2eefba87c..000000000 --- a/grub-core/lib/tss2/tss2_structs.h +++ /dev/null @@ -1,833 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_TPM2_INTERNAL_STRUCTS_HEADER -#define GRUB_TPM2_INTERNAL_STRUCTS_HEADER 1 - -#include - -/* - * TPM response header - * This struct is used to calculate the minimum size of the TPM 2.0 response. - * The format of the response: - * - * +----------------------+ - * | UINT16 tag | - * +----------------------+ - * | UINT32 repsonse_size | - * +----------------------+ - * | UINT32 response_code | - * +======================+ - * | response_data | (optional) - * +======================+ - */ -struct __attribute__ ((__packed__)) TPM_RESPONSE_HEADER -{ - grub_uint16_t tag; - grub_uint32_t response_size; - TPM_RC_t response_code; -}; -typedef struct TPM_RESPONSE_HEADER TPM_RESPONSE_HEADER_t; - -/* TPMS_TAGGED_PROPERTY Structure */ -struct TPMS_TAGGED_PROPERTY -{ - TPM_PT_t property; - grub_uint32_t value; -}; -typedef struct TPMS_TAGGED_PROPERTY TPMS_TAGGED_PROPERTY_t; - -/* TPML_TAGGED_TPM_PROPERTY Structure */ -struct TPML_TAGGED_TPM_PROPERTY -{ - grub_uint32_t count; - TPMS_TAGGED_PROPERTY_t tpmProperty[TPM_MAX_TPM_PROPERTIES]; -}; -typedef struct TPML_TAGGED_TPM_PROPERTY TPML_TAGGED_TPM_PROPERTY_t; - -/* TPMU_CAPABILITIES Structure */ -union TPMU_CAPABILITIES -{ - TPML_TAGGED_TPM_PROPERTY_t tpmProperties; -}; -typedef union TPMU_CAPABILITIES TPMU_CAPABILITIES_t; - -/* TPMS_CAPABILITY_DATA Structure */ -struct TPMS_CAPABILITY_DATA -{ - TPM_CAP_t capability; - TPMU_CAPABILITIES_t data; -}; -typedef struct TPMS_CAPABILITY_DATA TPMS_CAPABILITY_DATA_t; - -/* TPMS_PCR_SELECT Structure */ -struct TPMS_PCR_SELECT -{ - grub_uint8_t sizeOfSelect; - grub_uint8_t pcrSelect[TPM_PCR_SELECT_MAX]; -}; -typedef struct TPMS_PCR_SELECT TPMS_PCR_SELECT_t; - -/* TPMS_PCR_SELECTION Structure */ -struct TPMS_PCR_SELECTION -{ - TPMI_ALG_HASH_t hash; - grub_uint8_t sizeOfSelect; - grub_uint8_t pcrSelect[TPM_PCR_SELECT_MAX]; -}; -typedef struct TPMS_PCR_SELECTION TPMS_PCR_SELECTION_t; - -static inline void TPMS_PCR_SELECTION_SelectPCR(TPMS_PCR_SELECTION_t *self, grub_uint32_t n) -{ - self->pcrSelect[(n / 8)] |= (1 << (n % 8)); -} - -/* TPML_PCR_SELECTION Structure */ -struct TPML_PCR_SELECTION -{ - grub_uint32_t count; - TPMS_PCR_SELECTION_t pcrSelections[TPM_NUM_PCR_BANKS]; -}; -typedef struct TPML_PCR_SELECTION TPML_PCR_SELECTION_t; - -/* TPMU_HA Structure */ -union TPMU_HA -{ - grub_uint8_t sha1[TPM_SHA1_DIGEST_SIZE]; - grub_uint8_t sha256[TPM_SHA256_DIGEST_SIZE]; - grub_uint8_t sha384[TPM_SHA384_DIGEST_SIZE]; - grub_uint8_t sha512[TPM_SHA512_DIGEST_SIZE]; - grub_uint8_t sm3_256[TPM_SM3_256_DIGEST_SIZE]; -}; -typedef union TPMU_HA TPMU_HA_t; - -/* TPM2B Structure */ -struct TPM2B -{ - grub_uint16_t size; - grub_uint8_t buffer[1]; -}; -typedef struct TPM2B TPM2B_t; - -/* TPM2B_DIGEST Structure */ -struct TPM2B_DIGEST -{ - grub_uint16_t size; - grub_uint8_t buffer[sizeof(TPMU_HA_t)]; -}; -typedef struct TPM2B_DIGEST TPM2B_DIGEST_t; - -/* TPML_DIGEST Structure */ -struct TPML_DIGEST -{ - grub_uint32_t count; - TPM2B_DIGEST_t digests[8]; -}; -typedef struct TPML_DIGEST TPML_DIGEST_t; - -/* TPM2B_NONCE Type */ -typedef TPM2B_DIGEST_t TPM2B_NONCE_t; - -/* TPMA_SESSION Structure */ -struct TPMA_SESSION -{ -#ifdef GRUB_TARGET_WORDS_BIGENDIAN - grub_uint8_t audit:1; - grub_uint8_t encrypt:1; - grub_uint8_t decrypt:1; - grub_uint8_t reserved:2; - grub_uint8_t auditReset:1; - grub_uint8_t auditExclusive:1; - grub_uint8_t continueSession:1; -#else - grub_uint8_t continueSession:1; - grub_uint8_t auditExclusive:1; - grub_uint8_t auditReset:1; - grub_uint8_t reserved:2; - grub_uint8_t decrypt:1; - grub_uint8_t encrypt:1; - grub_uint8_t audit:1; -#endif -}; -typedef struct TPMA_SESSION TPMA_SESSION_t; - -/* TPM2B_AUTH Type */ -typedef TPM2B_DIGEST_t TPM2B_AUTH_t; - -/* TPMS_AUTH_COMMAND Structure */ -struct TPMS_AUTH_COMMAND -{ - TPMI_SH_AUTH_SESSION_t sessionHandle; - TPM2B_NONCE_t nonce; - TPMA_SESSION_t sessionAttributes; - TPM2B_AUTH_t hmac; -}; -typedef struct TPMS_AUTH_COMMAND TPMS_AUTH_COMMAND_t; - -/* TPMS_AUTH_RESPONSE Structure */ -struct TPMS_AUTH_RESPONSE -{ - TPM2B_NONCE_t nonce; - TPMA_SESSION_t sessionAttributes; - TPM2B_AUTH_t hmac; -}; -typedef struct TPMS_AUTH_RESPONSE TPMS_AUTH_RESPONSE_t; - -/* TPM2B_SENSITIVE_DATA Structure */ -struct TPM2B_SENSITIVE_DATA -{ - grub_uint16_t size; - grub_uint8_t buffer[TPM_MAX_SYM_DATA]; -}; -typedef struct TPM2B_SENSITIVE_DATA TPM2B_SENSITIVE_DATA_t; - -/* TPMS_SENSITIVE_CREATE Structure */ -struct TPMS_SENSITIVE_CREATE -{ - TPM2B_AUTH_t userAuth; - TPM2B_SENSITIVE_DATA_t data; -}; -typedef struct TPMS_SENSITIVE_CREATE TPMS_SENSITIVE_CREATE_t; - -/* TPM2B_SENSITIVE_CREATE Structure */ -struct TPM2B_SENSITIVE_CREATE -{ - grub_uint16_t size; - TPMS_SENSITIVE_CREATE_t sensitive; -}; -typedef struct TPM2B_SENSITIVE_CREATE TPM2B_SENSITIVE_CREATE_t; - -/* TPMA_OBJECT Structure */ -struct TPMA_OBJECT -{ -#ifdef GRUB_TARGET_WORDS_BIGENDIAN - grub_uint32_t reserved5:13; - grub_uint32_t sign:1; - grub_uint32_t decrypt:1; - grub_uint32_t restricted:1; - grub_uint32_t reserved4:4; - grub_uint32_t encryptedDuplication:1; - grub_uint32_t noDA:1; - grub_uint32_t reserved3:2; - grub_uint32_t adminWithPolicy:1; - grub_uint32_t userWithAuth:1; - grub_uint32_t sensitiveDataOrigin:1; - grub_uint32_t fixedParent:1; - grub_uint32_t reserved2:1; - grub_uint32_t stClear:1; - grub_uint32_t fixedTPM:1; - grub_uint32_t reserved1:1; -#else - grub_uint32_t reserved1:1; - grub_uint32_t fixedTPM:1; - grub_uint32_t stClear:1; - grub_uint32_t reserved2:1; - grub_uint32_t fixedParent:1; - grub_uint32_t sensitiveDataOrigin:1; - grub_uint32_t userWithAuth:1; - grub_uint32_t adminWithPolicy:1; - grub_uint32_t reserved3:2; - grub_uint32_t noDA:1; - grub_uint32_t encryptedDuplication:1; - grub_uint32_t reserved4:4; - grub_uint32_t restricted:1; - grub_uint32_t decrypt:1; - grub_uint32_t sign:1; - grub_uint32_t reserved5:13; -#endif -}; -typedef struct TPMA_OBJECT TPMA_OBJECT_t; - -/* TPMS_SCHEME_HASH Structure */ -struct TPMS_SCHEME_HASH -{ - TPMI_ALG_HASH_t hashAlg; -}; -typedef struct TPMS_SCHEME_HASH TPMS_SCHEME_HASH_t; - -/* TPMS_SCHEME_HASH Types */ -typedef TPMS_SCHEME_HASH_t TPMS_KEY_SCHEME_ECDH_t; -typedef TPMS_SCHEME_HASH_t TPMS_KEY_SCHEME_ECMQV_t; -typedef TPMS_SCHEME_HASH_t TPMS_SIG_SCHEME_RSASSA_t; -typedef TPMS_SCHEME_HASH_t TPMS_SIG_SCHEME_RSAPSS_t; -typedef TPMS_SCHEME_HASH_t TPMS_SIG_SCHEME_ECDSA_t; -typedef TPMS_SCHEME_HASH_t TPMS_SIG_SCHEME_ECDAA_t; -typedef TPMS_SCHEME_HASH_t TPMS_SIG_SCHEME_SM2_t; -typedef TPMS_SCHEME_HASH_t TPMS_SIG_SCHEME_ECSCHNORR_t; -typedef TPMS_SCHEME_HASH_t TPMS_ENC_SCHEME_RSAES_t; -typedef TPMS_SCHEME_HASH_t TPMS_ENC_SCHEME_OAEP_t; -typedef TPMS_SCHEME_HASH_t TPMS_SCHEME_KDF2_t; -typedef TPMS_SCHEME_HASH_t TPMS_SCHEME_MGF1_t; -typedef TPMS_SCHEME_HASH_t TPMS_SCHEME_KDF1_SP800_56A_t; -typedef TPMS_SCHEME_HASH_t TPMS_SCHEME_KDF1_SP800_108_t; - -/* TPMS_SCHEME_HMAC Type */ -typedef TPMS_SCHEME_HASH_t TPMS_SCHEME_HMAC_t; - -/* TPMS_SCHEME_XOR Structure */ -struct TPMS_SCHEME_XOR -{ - TPMI_ALG_HASH_t hashAlg; - TPMI_ALG_KDF_t kdf; -}; -typedef struct TPMS_SCHEME_XOR TPMS_SCHEME_XOR_t; - -/* TPMU_SCHEME_KEYEDHASH Union */ -union TPMU_SCHEME_KEYEDHASH -{ - TPMS_SCHEME_HMAC_t hmac; - TPMS_SCHEME_XOR_t exclusiveOr; -}; -typedef union TPMU_SCHEME_KEYEDHASH TPMU_SCHEME_KEYEDHASH_t; - -/* TPMT_KEYEDHASH_SCHEME Structure */ -struct TPMT_KEYEDHASH_SCHEME -{ - TPMI_ALG_KEYEDHASH_SCHEME_t scheme; - TPMU_SCHEME_KEYEDHASH_t details; -}; -typedef struct TPMT_KEYEDHASH_SCHEME TPMT_KEYEDHASH_SCHEME_t; - -/* TPMS_KEYEDHASH_PARMS Structure */ -struct TPMS_KEYEDHASH_PARMS -{ - TPMT_KEYEDHASH_SCHEME_t scheme; -}; -typedef struct TPMS_KEYEDHASH_PARMS TPMS_KEYEDHASH_PARMS_t; - -/* TPMU_SYM_KEY_BITS Union */ -union TPMU_SYM_KEY_BITS -{ - TPM_KEY_BITS_t aes; - TPM_KEY_BITS_t exclusiveOr; - TPM_KEY_BITS_t sm4; - TPM_KEY_BITS_t camellia; -}; -typedef union TPMU_SYM_KEY_BITS TPMU_SYM_KEY_BITS_t; - -/* TPMU_SYM_MODE Union */ -union TPMU_SYM_MODE -{ - TPMI_ALG_SYM_MODE_t aes; - TPMI_ALG_SYM_MODE_t sm4; - TPMI_ALG_SYM_MODE_t camellia; - TPMI_ALG_SYM_MODE_t sym; -}; -typedef union TPMU_SYM_MODE TPMU_SYM_MODE_t; - -/* TPMT_SYM_DEF_OBJECT Structure */ -struct TPMT_SYM_DEF_OBJECT -{ - TPMI_ALG_SYM_OBJECT_t algorithm; - TPMU_SYM_KEY_BITS_t keyBits; - TPMU_SYM_MODE_t mode; -}; -typedef struct TPMT_SYM_DEF_OBJECT TPMT_SYM_DEF_OBJECT_t; - -/* TPMS_SYMCIPHER_PARMS Structure */ -struct TPMS_SYMCIPHER_PARMS -{ - TPMT_SYM_DEF_OBJECT_t sym; -}; -typedef struct TPMS_SYMCIPHER_PARMS TPMS_SYMCIPHER_PARMS_t; - -/* TPMU_ASYM_SCHEME Union */ -union TPMU_ASYM_SCHEME -{ - TPMS_KEY_SCHEME_ECDH_t ecdh; - TPMS_KEY_SCHEME_ECMQV_t ecmqv; - TPMS_SIG_SCHEME_RSASSA_t rsassa; - TPMS_SIG_SCHEME_RSAPSS_t rsapss; - TPMS_SIG_SCHEME_ECDSA_t ecdsa; - TPMS_SIG_SCHEME_ECDAA_t ecdaa; - TPMS_SIG_SCHEME_SM2_t sm2; - TPMS_SIG_SCHEME_ECSCHNORR_t ecschnorr; - TPMS_ENC_SCHEME_RSAES_t rsaes; - TPMS_ENC_SCHEME_OAEP_t oaep; - TPMS_SCHEME_HASH_t anySig; - unsigned char padding[4]; -}; -typedef union TPMU_ASYM_SCHEME TPMU_ASYM_SCHEME_t; - -/* TPMT_RSA_SCHEME Structure */ -struct TPMT_RSA_SCHEME -{ - TPMI_ALG_RSA_SCHEME_t scheme; - TPMU_ASYM_SCHEME_t details; -}; -typedef struct TPMT_RSA_SCHEME TPMT_RSA_SCHEME_t; - -/* TPMS_RSA_PARMS Structure */ -struct TPMS_RSA_PARMS -{ - TPMT_SYM_DEF_OBJECT_t symmetric; - TPMT_RSA_SCHEME_t scheme; - TPM_KEY_BITS_t keyBits; - grub_uint32_t exponent; -}; -typedef struct TPMS_RSA_PARMS TPMS_RSA_PARMS_t; - -/* TPMT_ECC_SCHEME Structure */ -struct TPMT_ECC_SCHEME -{ - TPMI_ALG_ECC_SCHEME_t scheme; - TPMU_ASYM_SCHEME_t details; -}; -typedef struct TPMT_ECC_SCHEME TPMT_ECC_SCHEME_t; - -/* TPMU_KDF_SCHEME Union */ -union TPMU_KDF_SCHEME -{ - TPMS_SCHEME_MGF1_t mgf1; - TPMS_SCHEME_KDF1_SP800_56A_t kdf1_sp800_56a; - TPMS_SCHEME_KDF2_t kdf2; - TPMS_SCHEME_KDF1_SP800_108_t kdf1_sp800_108; -}; -typedef union TPMU_KDF_SCHEME TPMU_KDF_SCHEME_t; - -/* TPMT_KDF_SCHEME Structure */ -struct TPMT_KDF_SCHEME -{ - TPMI_ALG_KDF_t scheme; - TPMU_KDF_SCHEME_t details; -}; -typedef struct TPMT_KDF_SCHEME TPMT_KDF_SCHEME_t; - -/* TPMS_ECC_PARMS Structure */ -struct TPMS_ECC_PARMS -{ - TPMT_SYM_DEF_OBJECT_t symmetric; - TPMT_ECC_SCHEME_t scheme; - TPMI_ECC_CURVE_t curveID; - TPMT_KDF_SCHEME_t kdf; -}; -typedef struct TPMS_ECC_PARMS TPMS_ECC_PARMS_t; - -/* TPMT_ASYM_SCHEME Structure */ -struct TPMT_ASYM_SCHEME -{ - TPMI_ALG_ASYM_SCHEME_t scheme; - TPMU_ASYM_SCHEME_t details; -}; -typedef struct TPMT_ASYM_SCHEME TPMT_ASYM_SCHEME_t; - -/* TPMS_ASYM_PARMS Structure */ -struct TPMS_ASYM_PARMS -{ - TPMT_SYM_DEF_OBJECT_t symmetric; - TPMT_ASYM_SCHEME_t scheme; -}; -typedef struct TPMS_ASYM_PARMS TPMS_ASYM_PARMS_t; - -/* TPMU_PUBLIC_PARMS Union */ -union TPMU_PUBLIC_PARMS -{ - TPMS_KEYEDHASH_PARMS_t keyedHashDetail; - TPMS_SYMCIPHER_PARMS_t symDetail; - TPMS_RSA_PARMS_t rsaDetail; - TPMS_ECC_PARMS_t eccDetail; - TPMS_ASYM_PARMS_t asymDetail; -}; -typedef union TPMU_PUBLIC_PARMS TPMU_PUBLIC_PARMS_t; - -/* TPMT_PUBLIC_PARMS Structure */ -struct TPMT_PUBLIC_PARMS { - TPMI_ALG_PUBLIC_t type; - TPMU_PUBLIC_PARMS_t parameters; -}; -typedef struct TPMT_PUBLIC_PARMS TPMT_PUBLIC_PARMS_t; - -/* TPM2B_PUBLIC_KEY_RSA Structure */ -struct TPM2B_PUBLIC_KEY_RSA -{ - grub_uint16_t size; - grub_uint8_t buffer[TPM_MAX_RSA_KEY_BYTES]; -}; -typedef struct TPM2B_PUBLIC_KEY_RSA TPM2B_PUBLIC_KEY_RSA_t; - -/* TPM2B_ECC_PARAMETER Structure */ -struct TPM2B_ECC_PARAMETER -{ - grub_uint16_t size; - grub_uint8_t buffer[TPM_MAX_ECC_KEY_BYTES]; -}; -typedef struct TPM2B_ECC_PARAMETER TPM2B_ECC_PARAMETER_t; - -/* TPMS_ECC_POINT Structure */ -struct TPMS_ECC_POINT -{ - TPM2B_ECC_PARAMETER_t x; - TPM2B_ECC_PARAMETER_t y; -}; -typedef struct TPMS_ECC_POINT TPMS_ECC_POINT_t; - -/* TPMU_ENCRYPTED_SECRET Union */ -union TPMU_ENCRYPTED_SECRET -{ - grub_uint8_t ecc[sizeof(TPMS_ECC_POINT_t)]; - grub_uint8_t rsa[TPM_MAX_RSA_KEY_BYTES]; - grub_uint8_t symmetric[sizeof(TPM2B_DIGEST_t)]; - grub_uint8_t keyedHash[sizeof(TPM2B_DIGEST_t)]; -}; -typedef union TPMU_ENCRYPTED_SECRET TPMU_ENCRYPTED_SECRET_t; - -/* TPM2B_ENCRYPTED_SECRET Structure */ -struct TPM2B_ENCRYPTED_SECRET -{ - grub_uint16_t size; - grub_uint8_t secret[sizeof(TPMU_ENCRYPTED_SECRET_t)]; -}; -typedef struct TPM2B_ENCRYPTED_SECRET TPM2B_ENCRYPTED_SECRET_t; - -/* TPMU_PUBLIC_ID Union */ -union TPMU_PUBLIC_ID -{ - TPM2B_DIGEST_t keyedHash; - TPM2B_DIGEST_t sym; - TPM2B_PUBLIC_KEY_RSA_t rsa; - TPMS_ECC_POINT_t ecc; -}; -typedef union TPMU_PUBLIC_ID TPMU_PUBLIC_ID_t; - -/* TPMT_PUBLIC Structure */ -struct TPMT_PUBLIC -{ - TPMI_ALG_PUBLIC_t type; - TPMI_ALG_HASH_t nameAlg; - TPMA_OBJECT_t objectAttributes; - TPM2B_DIGEST_t authPolicy; - TPMU_PUBLIC_PARMS_t parameters; - TPMU_PUBLIC_ID_t unique; -}; -typedef struct TPMT_PUBLIC TPMT_PUBLIC_t; - -/* TPM2B_PUBLIC Structure */ -struct TPM2B_PUBLIC -{ - grub_uint16_t size; - TPMT_PUBLIC_t publicArea; -}; -typedef struct TPM2B_PUBLIC TPM2B_PUBLIC_t; - -/* TPMT_HA Structure */ -struct TPMT_HA -{ - TPMI_ALG_HASH_t hashAlg; - TPMU_HA_t digest; -}; -typedef struct TPMT_HA TPMT_HA_t; - -/* TPM2B_DATA Structure */ -struct TPM2B_DATA -{ - grub_uint16_t size; - grub_uint8_t buffer[sizeof(TPMT_HA_t)]; -}; -typedef struct TPM2B_DATA TPM2B_DATA_t; - -/* TPMA_LOCALITY Structure */ -struct TPMA_LOCALITY -{ -#ifdef GRUB_TARGET_WORDS_BIGENDIAN - grub_uint8_t Extended:3; - grub_uint8_t TPM_LOC_FOUR:1; - grub_uint8_t TPM_LOC_THREE:1; - grub_uint8_t TPM_LOC_TWO:1; - grub_uint8_t TPM_LOC_ONE:1; - grub_uint8_t TPM_LOC_ZERO:1; -#else - grub_uint8_t TPM_LOC_ZERO:1; - grub_uint8_t TPM_LOC_ONE:1; - grub_uint8_t TPM_LOC_TWO:1; - grub_uint8_t TPM_LOC_THREE:1; - grub_uint8_t TPM_LOC_FOUR:1; - grub_uint8_t Extended:3; -#endif -}; -typedef struct TPMA_LOCALITY TPMA_LOCALITY_t; - -/* TPMU_NAME Union */ -union TPMU_NAME -{ - TPMT_HA_t digest; - TPM_HANDLE_t handle; -}; -typedef union TPMU_NAME TPMU_NAME_t; - -/* TPM2B_NAME Structure */ -struct TPM2B_NAME -{ - grub_uint16_t size; - grub_uint8_t name[sizeof(TPMU_NAME_t)]; -}; -typedef struct TPM2B_NAME TPM2B_NAME_t; - -/* TPMS_CREATION_DATA Structure */ -struct TPMS_CREATION_DATA -{ - TPML_PCR_SELECTION_t pcrSelect; - TPM2B_DIGEST_t pcrDigest; - TPMA_LOCALITY_t locality; - TPM_ALG_ID_t parentNameAlg; - TPM2B_NAME_t parentName; - TPM2B_NAME_t parentQualifiedName; - TPM2B_DATA_t outsideInfo; -}; -typedef struct TPMS_CREATION_DATA TPMS_CREATION_DATA_t; - -/* TPM2B_CREATION_DATA Structure */ -struct TPM2B_CREATION_DATA -{ - grub_uint16_t size; - TPMS_CREATION_DATA_t creationData; -}; -typedef struct TPM2B_CREATION_DATA TPM2B_CREATION_DATA_t; - -/* TPMT_SYM_DEF Structure */ -struct TPMT_SYM_DEF -{ - TPMI_ALG_SYM_t algorithm; - TPMU_SYM_KEY_BITS_t keyBits; - TPMU_SYM_MODE_t mode; -}; -typedef struct TPMT_SYM_DEF TPMT_SYM_DEF_t; - -/* TPM2B_MAX_BUFFER Structure */ -struct TPM2B_MAX_BUFFER -{ - grub_uint16_t size; - grub_uint8_t buffer[TPM_MAX_DIGEST_BUFFER]; -}; -typedef struct TPM2B_MAX_BUFFER TPM2B_MAX_BUFFER_t; - -/* TPMT_TK_HASHCHECK Structure */ -struct TPMT_TK_HASHCHECK -{ - TPM_ST_t tag; - TPMI_RH_HIERARCHY_t hierarchy; - TPM2B_DIGEST_t digest; -}; -typedef struct TPMT_TK_HASHCHECK TPMT_TK_HASHCHECK_t; - -/* TPM2B_SYM_KEY Structure */ -struct TPM2B_SYM_KEY -{ - grub_uint16_t size; - grub_uint8_t buffer[TPM_MAX_SYM_KEY_BYTES]; -}; -typedef struct TPM2B_SYM_KEY TPM2B_SYM_KEY_t; - -/* TPM2B_PRIVATE_KEY_RSA Structure */ -struct TPM2B_PRIVATE_KEY_RSA -{ - grub_uint16_t size; - grub_uint8_t buffer[TPM_MAX_RSA_KEY_BYTES/2]; -}; -typedef struct TPM2B_PRIVATE_KEY_RSA TPM2B_PRIVATE_KEY_RSA_t; - -/* TPM2B_PRIVATE_VENDOR_SPECIFIC Structure */ -struct TPM2B_PRIVATE_VENDOR_SPECIFIC -{ - grub_uint16_t size; - grub_uint8_t buffer[TPM_PRIVATE_VENDOR_SPECIFIC_BYTES]; -}; -typedef struct TPM2B_PRIVATE_VENDOR_SPECIFIC TPM2B_PRIVATE_VENDOR_SPECIFIC_t; - -/* TPM2B_PRIVATE_VENDOR_SPECIFIC Union */ -union TPMU_SENSITIVE_COMPOSITE -{ - TPM2B_PRIVATE_KEY_RSA_t rsa; - TPM2B_ECC_PARAMETER_t ecc; - TPM2B_SENSITIVE_DATA_t bits; - TPM2B_SYM_KEY_t sym; - TPM2B_PRIVATE_VENDOR_SPECIFIC_t any; -}; -typedef union TPMU_SENSITIVE_COMPOSITE TPMU_SENSITIVE_COMPOSITE_t; - -/* TPMT_SENSITIVE Structure */ -struct TPMT_SENSITIVE -{ - TPMI_ALG_PUBLIC_t sensitiveType; - TPM2B_AUTH_t authValue; - TPM2B_DIGEST_t seedValue; - TPMU_SENSITIVE_COMPOSITE_t sensitive; -}; -typedef struct TPMT_SENSITIVE TPMT_SENSITIVE_t; - -/* TPM2B_SENSITIVE Structure */ -struct TPM2B_SENSITIVE -{ - grub_uint16_t size; - TPMT_SENSITIVE_t sensitiveArea; -}; -typedef struct TPM2B_SENSITIVE TPM2B_SENSITIVE_t; - -/* - * _PRIVATE Structure - * - * Although '_PRIVATE' is the name defined in the TPM2 SPEC, it is too generic, - * so here we add the '__TPM2B' prefix to make the struct specific for 'TPM2B_PRIVATE'. - */ -struct __TPM2B_PRIVATE -{ - TPM2B_DIGEST_t integrityOuter; - TPM2B_DIGEST_t integrityInner; - TPM2B_SENSITIVE_t sensitive; -}; -typedef struct __TPM2B_PRIVATE __TPM2B_PRIVATE_t; - -/* TPM2B_PRIVATE Structure */ -struct TPM2B_PRIVATE -{ - grub_uint16_t size; - grub_uint8_t buffer[sizeof(__TPM2B_PRIVATE_t)]; -}; -typedef struct TPM2B_PRIVATE TPM2B_PRIVATE_t; - -/* TPML_DIGEST_VALUES Structure */ -struct TPML_DIGEST_VALUES -{ - grub_uint32_t count; - TPMT_HA_t digests[TPM_NUM_PCR_BANKS]; -}; -typedef struct TPML_DIGEST_VALUES TPML_DIGEST_VALUES_t; - -/* TPM2B_MAX_NV_BUFFER Structure */ -struct TPM2B_MAX_NV_BUFFER -{ - grub_uint16_t size; - grub_uint8_t buffer[TPM_MAX_NV_BUFFER_SIZE]; -}; -typedef struct TPM2B_MAX_NV_BUFFER TPM2B_MAX_NV_BUFFER_t; - -/* TPMS_NV_PUBLIC Structure */ -struct TPMS_NV_PUBLIC -{ - TPMI_RH_NV_INDEX_t nvIndex; - TPMI_ALG_HASH_t nameAlg; - TPMA_NV_t attributes; - TPM2B_DIGEST_t authPolicy; - grub_uint16_t dataSize; -}; -typedef struct TPMS_NV_PUBLIC TPMS_NV_PUBLIC_t; - -/* TPM2B_NV_PUBLIC Structure */ -struct TPM2B_NV_PUBLIC -{ - grub_uint16_t size; - TPMS_NV_PUBLIC_t nvPublic; -}; -typedef struct TPM2B_NV_PUBLIC TPM2B_NV_PUBLIC_t; - -/* TPMT_TK_CREATION Structure */ -struct TPMT_TK_CREATION -{ - TPM_ST_t tag; - TPMI_RH_HIERARCHY_t hierarchy; - TPM2B_DIGEST_t digest; -}; -typedef struct TPMT_TK_CREATION TPMT_TK_CREATION_t; - -/* TPMS_EMPTY Structure */ -struct TPMS_EMPTY { - grub_uint8_t empty[1]; /* a structure with no member */ -}; -typedef struct TPMS_EMPTY TPMS_EMPTY_t; - -/* TPMS_SIGNATURE_RSA Structure */ -struct TPMS_SIGNATURE_RSA { - TPMI_ALG_HASH_t hash; - TPM2B_PUBLIC_KEY_RSA_t sig; -}; -typedef struct TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSA_t; - -/* Definition of Types for RSA Signature */ -typedef TPMS_SIGNATURE_RSA_t TPMS_SIGNATURE_RSASSA_t; -typedef TPMS_SIGNATURE_RSA_t TPMS_SIGNATURE_RSAPSS_t; - -/* TPMS_SIGNATURE_ECC Structure */ -struct TPMS_SIGNATURE_ECC { - TPMI_ALG_HASH_t hash; - TPM2B_ECC_PARAMETER_t signatureR; - TPM2B_ECC_PARAMETER_t signatureS; -}; -typedef struct TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECC_t; - -/* Definition of Types for ECC TPMS_SIGNATURE_ECC */ -typedef TPMS_SIGNATURE_ECC_t TPMS_SIGNATURE_ECDSA_t; -typedef TPMS_SIGNATURE_ECC_t TPMS_SIGNATURE_ECDAA_t; -typedef TPMS_SIGNATURE_ECC_t TPMS_SIGNATURE_SM2_t; -typedef TPMS_SIGNATURE_ECC_t TPMS_SIGNATURE_ECSCHNORR_t; - -/* TPMU_SIGNATURE Structure */ -union TPMU_SIGNATURE { - TPMS_SIGNATURE_RSASSA_t rsassa; - TPMS_SIGNATURE_RSAPSS_t rsapss; - TPMS_SIGNATURE_ECDSA_t ecdsa; - TPMS_SIGNATURE_ECDAA_t ecdaa; - TPMS_SIGNATURE_SM2_t sm2; - TPMS_SIGNATURE_ECSCHNORR_t ecschnorr; - TPMT_HA_t hmac; - TPMS_SCHEME_HASH_t any; - TPMS_EMPTY_t null; -}; -typedef union TPMU_SIGNATURE TPMU_SIGNATURE_t; - -/* TPMT_SIGNATURE Structure */ -struct TPMT_SIGNATURE { - TPMI_ALG_SIG_SCHEME_t sigAlg; - TPMU_SIGNATURE_t signature; -}; -typedef struct TPMT_SIGNATURE TPMT_SIGNATURE_t; - -static inline TPMI_ALG_HASH_t -TPMT_SIGNATURE_get_hash_alg (TPMT_SIGNATURE_t *sig) -{ - switch (sig->sigAlg) - { - case TPM_ALG_RSASSA: - return sig->signature.rsassa.hash; - case TPM_ALG_RSAPSS: - return sig->signature.rsapss.hash; - case TPM_ALG_ECDSA: - return sig->signature.ecdsa.hash; - case TPM_ALG_ECDAA: - return sig->signature.ecdaa.hash; - case TPM_ALG_SM2: - return sig->signature.sm2.hash; - case TPM_ALG_ECSCHNORR: - return sig->signature.ecschnorr.hash; - case TPM_ALG_HMAC: - return sig->signature.hmac.hashAlg; - default: - break; - } - - return TPM_ALG_NULL; -} - -/* TPMT_TK_VERIFIED Structure */ -struct TPMT_TK_VERIFIED { - TPM_ST_t tag; - TPMI_RH_HIERARCHY_t hierarchy; - TPM2B_DIGEST_t digest; -}; -typedef struct TPMT_TK_VERIFIED TPMT_TK_VERIFIED_t; - -#endif /* ! GRUB_TPM2_INTERNAL_STRUCTS_HEADER */ diff --git a/grub-core/lib/tss2/tss2_types.h b/grub-core/lib/tss2/tss2_types.h deleted file mode 100644 index bddde7191..000000000 --- a/grub-core/lib/tss2/tss2_types.h +++ /dev/null @@ -1,410 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_TPM2_INTERNAL_TYPES_HEADER -#define GRUB_TPM2_INTERNAL_TYPES_HEADER 1 - -#include - -/* TPM2_RC Constants */ -typedef grub_uint32_t TPM_RC_t; - -#define TPM_RC_1 ((TPM_RC_t) 0x100) -#define TPM_RC_2 ((TPM_RC_t) 0x200) -#define TPM_RC_3 ((TPM_RC_t) 0x300) -#define TPM_RC_4 ((TPM_RC_t) 0x400) -#define TPM_RC_5 ((TPM_RC_t) 0x500) -#define TPM_RC_6 ((TPM_RC_t) 0x600) -#define TPM_RC_7 ((TPM_RC_t) 0x700) -#define TPM_RC_8 ((TPM_RC_t) 0x800) -#define TPM_RC_9 ((TPM_RC_t) 0x900) -#define TPM_RC_A ((TPM_RC_t) 0xA00) -#define TPM_RC_ASYMMETRIC ((TPM_RC_t) 0x081) -#define TPM_RC_ATTRIBUTES ((TPM_RC_t) 0x082) -#define TPM_RC_AUTH_CONTEXT ((TPM_RC_t) 0x145) -#define TPM_RC_AUTH_FAIL ((TPM_RC_t) 0x08E) -#define TPM_RC_AUTH_MISSING ((TPM_RC_t) 0x125) -#define TPM_RC_AUTHSIZE ((TPM_RC_t) 0x144) -#define TPM_RC_AUTH_TYPE ((TPM_RC_t) 0x124) -#define TPM_RC_AUTH_UNAVAILABLE ((TPM_RC_t) 0x12F) -#define TPM_RC_B ((TPM_RC_t) 0xB00) -#define TPM_RC_BAD_AUTH ((TPM_RC_t) 0x0A2) -#define TPM_RC_BAD_CONTEXT ((TPM_RC_t) 0x150) -#define TPM_RC_BAD_TAG ((TPM_RC_t) 0x01E) -#define TPM_RC_BINDING ((TPM_RC_t) 0x0A5) -#define TPM_RC_C ((TPM_RC_t) 0xC00) -#define TPM_RC_CANCELED ((TPM_RC_t) 0x909) -#define TPM_RC_COMMAND_CODE ((TPM_RC_t) 0x143) -#define TPM_RC_COMMAND_SIZE ((TPM_RC_t) 0x142) -#define TPM_RC_CONTEXT_GAP ((TPM_RC_t) 0x901) -#define TPM_RC_CPHASH ((TPM_RC_t) 0x151) -#define TPM_RC_CURVE ((TPM_RC_t) 0x0A6) -#define TPM_RC_D ((TPM_RC_t) 0xD00) -#define TPM_RC_DISABLED ((TPM_RC_t) 0x120) -#define TPM_RC_E ((TPM_RC_t) 0xE00) -#define TPM_RC_ECC_POINT ((TPM_RC_t) 0x0A7) -#define TPM_RC_EXCLUSIVE ((TPM_RC_t) 0x121) -#define TPM_RC_EXPIRED ((TPM_RC_t) 0x0A3) -#define TPM_RC_F ((TPM_RC_t) 0xF00) -#define TPM_RC_FAILURE ((TPM_RC_t) 0x101) -#define TPM_RC_H ((TPM_RC_t) 0x000) -#define TPM_RC_HANDLE ((TPM_RC_t) 0x08B) -#define TPM_RC_HASH ((TPM_RC_t) 0x083) -#define TPM_RC_HIERARCHY ((TPM_RC_t) 0x085) -#define TPM_RC_HMAC ((TPM_RC_t) 0x119) -#define TPM_RC_INITIALIZE ((TPM_RC_t) 0x100) -#define TPM_RC_INSUFFICIENT ((TPM_RC_t) 0x09A) -#define TPM_RC_INTEGRITY ((TPM_RC_t) 0x09F) -#define TPM_RC_KDF ((TPM_RC_t) 0x08C) -#define TPM_RC_KEY ((TPM_RC_t) 0x09C) -#define TPM_RC_KEY_SIZE ((TPM_RC_t) 0x087) -#define TPM_RC_LOCALITY ((TPM_RC_t) 0x907) -#define TPM_RC_LOCKOUT ((TPM_RC_t) 0x921) -#define TPM_RC_MEMORY ((TPM_RC_t) 0x904) -#define TPM_RC_MGF ((TPM_RC_t) 0x088) -#define TPM_RC_MODE ((TPM_RC_t) 0x089) -#define TPM_RC_NEEDS_TEST ((TPM_RC_t) 0x153) -#define TPM_RC_N_MASK ((TPM_RC_t) 0xF00) -#define TPM_RC_NONCE ((TPM_RC_t) 0x08F) -#define TPM_RC_NO_RESULT ((TPM_RC_t) 0x154) -#define TPM_RC_NOT_USED ((TPM_RC_t) 0x97F) -#define TPM_RC_NV_AUTHORIZATION ((TPM_RC_t) 0x149) -#define TPM_RC_NV_DEFINED ((TPM_RC_t) 0x14C) -#define TPM_RC_NV_LOCKED ((TPM_RC_t) 0x148) -#define TPM_RC_NV_RANGE ((TPM_RC_t) 0x146) -#define TPM_RC_NV_RATE ((TPM_RC_t) 0x920) -#define TPM_RC_NV_SIZE ((TPM_RC_t) 0x147) -#define TPM_RC_NV_SPACE ((TPM_RC_t) 0x14B) -#define TPM_RC_NV_UNAVAILABLE ((TPM_RC_t) 0x923) -#define TPM_RC_NV_UNINITIALIZED ((TPM_RC_t) 0x14A) -#define TPM_RC_OBJECT_HANDLES ((TPM_RC_t) 0x906) -#define TPM_RC_OBJECT_MEMORY ((TPM_RC_t) 0x902) -#define TPM_RC_P ((TPM_RC_t) 0x040) -#define TPM_RC_PARENT ((TPM_RC_t) 0x152) -#define TPM_RC_PCR ((TPM_RC_t) 0x127) -#define TPM_RC_PCR_CHANGED ((TPM_RC_t) 0x128) -#define TPM_RC_POLICY ((TPM_RC_t) 0x126) -#define TPM_RC_POLICY_CC ((TPM_RC_t) 0x0A4) -#define TPM_RC_POLICY_FAIL ((TPM_RC_t) 0x09D) -#define TPM_RC_PP ((TPM_RC_t) 0x090) -#define TPM_RC_PRIVATE ((TPM_RC_t) 0x10B) -#define TPM_RC_RANGE ((TPM_RC_t) 0x08D) -#define TPM_RC_REBOOT ((TPM_RC_t) 0x130) -#define TPM_RC_REFERENCE_H0 ((TPM_RC_t) 0x910) -#define TPM_RC_REFERENCE_H1 ((TPM_RC_t) 0x911) -#define TPM_RC_REFERENCE_H2 ((TPM_RC_t) 0x912) -#define TPM_RC_REFERENCE_H3 ((TPM_RC_t) 0x913) -#define TPM_RC_REFERENCE_H4 ((TPM_RC_t) 0x914) -#define TPM_RC_REFERENCE_H5 ((TPM_RC_t) 0x915) -#define TPM_RC_REFERENCE_H6 ((TPM_RC_t) 0x916) -#define TPM_RC_REFERENCE_S0 ((TPM_RC_t) 0x918) -#define TPM_RC_REFERENCE_S1 ((TPM_RC_t) 0x919) -#define TPM_RC_REFERENCE_S2 ((TPM_RC_t) 0x91A) -#define TPM_RC_REFERENCE_S3 ((TPM_RC_t) 0x91B) -#define TPM_RC_REFERENCE_S4 ((TPM_RC_t) 0x91C) -#define TPM_RC_REFERENCE_S5 ((TPM_RC_t) 0x91D) -#define TPM_RC_REFERENCE_S6 ((TPM_RC_t) 0x91E) -#define TPM_RC_RESERVED_BITS ((TPM_RC_t) 0x0A1) -#define TPM_RC_RETRY ((TPM_RC_t) 0x922) -#define TPM_RC_S ((TPM_RC_t) 0x800) -#define TPM_RC_SCHEME ((TPM_RC_t) 0x092) -#define TPM_RC_SELECTOR ((TPM_RC_t) 0x098) -#define TPM_RC_SENSITIVE ((TPM_RC_t) 0x155) -#define TPM_RC_SEQUENCE ((TPM_RC_t) 0x103) -#define TPM_RC_SESSION_HANDLES ((TPM_RC_t) 0x905) -#define TPM_RC_SESSION_MEMORY ((TPM_RC_t) 0x903) -#define TPM_RC_SIGNATURE ((TPM_RC_t) 0x09B) -#define TPM_RC_SIZE ((TPM_RC_t) 0x095) -#define TPM_RC_SUCCESS ((TPM_RC_t) 0x000) -#define TPM_RC_SYMMETRIC ((TPM_RC_t) 0x096) -#define TPM_RC_TAG ((TPM_RC_t) 0x097) -#define TPM_RC_TESTING ((TPM_RC_t) 0x90A) -#define TPM_RC_TICKET ((TPM_RC_t) 0x0A0) -#define TPM_RC_TOO_MANY_CONTEXTS ((TPM_RC_t) 0x12E) -#define TPM_RC_TYPE ((TPM_RC_t) 0x08A) -#define TPM_RC_UNBALANCED ((TPM_RC_t) 0x131) -#define TPM_RC_UPGRADE ((TPM_RC_t) 0x12D) -#define TPM_RC_VALUE ((TPM_RC_t) 0x084) -#define TPM_RC_YIELDED ((TPM_RC_t) 0x908) - -/* TPMA_NV_t Constants */ -typedef grub_uint32_t TPMA_NV_t; - -#define TPMA_NV_PPWRITE ((TPMA_NV_t) 0x00000001) -#define TPMA_NV_OWNERWRITE ((TPMA_NV_t) 0x00000002) -#define TPMA_NV_AUTHWRITE ((TPMA_NV_t) 0x00000004) -#define TPMA_NV_POLICYWRITE ((TPMA_NV_t) 0x00000008) -#define TPMA_NV_TPM2_NT_MASK ((TPMA_NV_t) 0x000000F0) -#define TPMA_NV_TPM2_NT_SHIFT (4) -#define TPMA_NV_RESERVED1_MASK ((TPMA_NV_t) 0x00000300) -#define TPMA_NV_POLICY_DELETE ((TPMA_NV_t) 0x00000400) -#define TPMA_NV_WRITELOCKED ((TPMA_NV_t) 0x00000800) -#define TPMA_NV_WRITEALL ((TPMA_NV_t) 0x00001000) -#define TPMA_NV_WRITEDEFINE ((TPMA_NV_t) 0x00002000) -#define TPMA_NV_WRITE_STCLEAR ((TPMA_NV_t) 0x00004000) -#define TPMA_NV_GLOBALLOCK ((TPMA_NV_t) 0x00008000) -#define TPMA_NV_PPREAD ((TPMA_NV_t) 0x00010000) -#define TPMA_NV_OWNERREAD ((TPMA_NV_t) 0x00020000) -#define TPMA_NV_AUTHREAD ((TPMA_NV_t) 0x00040000) -#define TPMA_NV_POLICYREAD ((TPMA_NV_t) 0x00080000) -#define TPMA_NV_RESERVED2_MASK ((TPMA_NV_t) 0x01F00000) -#define TPMA_NV_NO_DA ((TPMA_NV_t) 0x02000000) -#define TPMA_NV_ORDERLY ((TPMA_NV_t) 0x04000000) -#define TPMA_NV_CLEAR_STCLEAR ((TPMA_NV_t) 0x08000000) -#define TPMA_NV_READLOCKED ((TPMA_NV_t) 0x10000000) -#define TPMA_NV_WRITTEN ((TPMA_NV_t) 0x20000000) -#define TPMA_NV_PLATFORMCREATE ((TPMA_NV_t) 0x40000000) -#define TPMA_NV_READ_STCLEAR ((TPMA_NV_t) 0x80000000) - -/* TPM_ALG_ID_t Constants */ -typedef grub_uint16_t TPM_ALG_ID_t; - -#define TPM_ALG_ERROR ((TPM_ALG_ID_t) 0x0000) -#define TPM_ALG_AES ((TPM_ALG_ID_t) 0x0006) -#define TPM_ALG_CAMELLIA ((TPM_ALG_ID_t) 0x0026) -#define TPM_ALG_CBC ((TPM_ALG_ID_t) 0x0042) -#define TPM_ALG_CFB ((TPM_ALG_ID_t) 0x0043) -#define TPM_ALG_ECB ((TPM_ALG_ID_t) 0x0044) -#define TPM_ALG_ECC ((TPM_ALG_ID_t) 0x0023) -#define TPM_ALG_ECDAA ((TPM_ALG_ID_t) 0x001A) -#define TPM_ALG_ECDSA ((TPM_ALG_ID_t) 0x0018) -#define TPM_ALG_ECSCHNORR ((TPM_ALG_ID_t) 0x001C) -#define TPM_ALG_HMAC ((TPM_ALG_ID_t) 0x0005) -#define TPM_ALG_KDF1_SP800_108 ((TPM_ALG_ID_t) 0x0022) -#define TPM_ALG_KDF1_SP800_56A ((TPM_ALG_ID_t) 0x0020) -#define TPM_ALG_KDF2 ((TPM_ALG_ID_t) 0x0021) -#define TPM_ALG_KEYEDHASH ((TPM_ALG_ID_t) 0x0008) -#define TPM_ALG_MGF1 ((TPM_ALG_ID_t) 0x0007) -#define TPM_ALG_NULL ((TPM_ALG_ID_t) 0x0010) -#define TPM_ALG_RSA ((TPM_ALG_ID_t) 0x0001) -#define TPM_ALG_RSASSA ((TPM_ALG_ID_t) 0x0014) -#define TPM_ALG_RSAPSS ((TPM_ALG_ID_t) 0x0016) -#define TPM_ALG_SHA1 ((TPM_ALG_ID_t) 0x0004) -#define TPM_ALG_SHA256 ((TPM_ALG_ID_t) 0x000B) -#define TPM_ALG_SHA384 ((TPM_ALG_ID_t) 0x000C) -#define TPM_ALG_SHA512 ((TPM_ALG_ID_t) 0x000D) -#define TPM_ALG_SM2 ((TPM_ALG_ID_t) 0x001B) -#define TPM_ALG_SM3_256 ((TPM_ALG_ID_t) 0x0012) -#define TPM_ALG_SM4 ((TPM_ALG_ID_t) 0x0013) -#define TPM_ALG_SYMCIPHER ((TPM_ALG_ID_t) 0x0025) -#define TPM_ALG_XOR ((TPM_ALG_ID_t) 0x000A) - -/* TPM_CAP_t Constants */ -typedef grub_uint32_t TPM_CAP_t; - -#define TPM_CAP_FIRST ((TPM_CAP_t) 0x00000000) -#define TPM_CAP_ALGS ((TPM_CAP_t) 0x00000000) -#define TPM_CAP_HANDLES ((TPM_CAP_t) 0x00000001) -#define TPM_CAP_COMMANDS ((TPM_CAP_t) 0x00000002) -#define TPM_CAP_PP_COMMANDS ((TPM_CAP_t) 0x00000003) -#define TPM_CAP_AUDIT_COMMANDS ((TPM_CAP_t) 0x00000004) -#define TPM_CAP_PCRS ((TPM_CAP_t) 0x00000005) -#define TPM_CAP_TPM_PROPERTIES ((TPM_CAP_t) 0x00000006) -#define TPM_CAP_PCR_PROPERTIES ((TPM_CAP_t) 0x00000007) -#define TPM_CAP_ECC_CURVES ((TPM_CAP_t) 0x00000008) -#define TPM_CAP_LAST ((TPM_CAP_t) 0x00000008) -#define TPM_CAP_VENDOR_PROPERTY ((TPM_CAP_t) 0x00000100) - -/* TPM_PT_t Constants */ -typedef grub_uint32_t TPM_PT_t; - -#define TPM_PT_NONE ((TPM_PT_t) 0x00000000) -#define PT_GROUP ((TPM_PT_t) 0x00000100) -#define PT_FIXED ((TPM_PT_t) (PT_GROUP * 1)) -#define TPM_PT_FAMILY_INDICATOR ((TPM_PT_t) (PT_FIXED + 0)) -#define TPM_PT_LEVEL ((TPM_PT_t) (PT_FIXED + 1)) -#define TPM_PT_REVISION ((TPM_PT_t) (PT_FIXED + 2)) -#define TPM_PT_DAY_OF_YEAR ((TPM_PT_t) (PT_FIXED + 3)) -#define TPM_PT_YEAR ((TPM_PT_t) (PT_FIXED + 4)) -#define TPM_PT_PCR_COUNT ((TPM_PT_t) (PT_FIXED + 18)) - -/* TPM_SE_t Constants */ -typedef grub_uint8_t TPM_SE_t; - -#define TPM_SE_HMAC ((TPM_SE_t) 0x00) -#define TPM_SE_POLICY ((TPM_SE_t) 0x01) -#define TPM_SE_TRIAL ((TPM_SE_t) 0x03) - -/* TPMI_YES_NO_t Constants */ -typedef grub_uint8_t TPMI_YES_NO_t; - -#define TPM_NO ((TPMI_YES_NO_t)0) -#define TPM_YES ((TPMI_YES_NO_t)1) - -/* TPM_ST_t Constants */ -typedef grub_uint16_t TPM_ST_t; -typedef TPM_ST_t TPMI_ST_COMMAND_TAG_t; - -#define TPM_ST_NO_SESSIONS ((TPMI_ST_COMMAND_TAG_t) 0x8001) -#define TPM_ST_SESSIONS ((TPMI_ST_COMMAND_TAG_t) 0x8002) - -/* TPM_HANDLE_t Types */ -typedef grub_uint32_t TPM_HANDLE_t; - -typedef TPM_HANDLE_t TPMI_RH_HIERARCHY_t; -typedef TPM_HANDLE_t TPMI_RH_LOCKOUT_t; -typedef TPM_HANDLE_t TPMI_SH_AUTH_SESSION_t; -typedef TPM_HANDLE_t TPMI_DH_CONTEXT_t; -typedef TPM_HANDLE_t TPMI_DH_OBJECT_t; -typedef TPM_HANDLE_t TPMI_DH_ENTITY_t; -typedef TPM_HANDLE_t TPMI_SH_POLICY_t; -typedef TPM_HANDLE_t TPMI_DH_PCR_t; -typedef TPM_HANDLE_t TPMI_RH_NV_AUTH_t; -typedef TPM_HANDLE_t TPMI_RH_NV_INDEX_t; - -/* TPM_HT_t Constants */ -typedef grub_uint8_t TPM_HT_t; -#define TPM_HT_NV_INDEX ((TPM_HT_t) 0x01) -#define TPM_HT_PERMANENT ((TPM_HT_t) 0x40) -#define TPM_HT_PERSISTENT ((TPM_HT_t) 0x81) - -/* TPM_RH_t Constants */ -typedef TPM_HANDLE_t TPM_RH_t; - -#define TPM_RH_FIRST ((TPM_RH_t) 0x40000000) -#define TPM_RH_SRK ((TPM_RH_t) 0x40000000) -#define TPM_RH_OWNER ((TPM_RH_t) 0x40000001) -#define TPM_RH_REVOKE ((TPM_RH_t) 0x40000002) -#define TPM_RH_TRANSPORT ((TPM_RH_t) 0x40000003) -#define TPM_RH_OPERATOR ((TPM_RH_t) 0x40000004) -#define TPM_RH_ADMIN ((TPM_RH_t) 0x40000005) -#define TPM_RH_EK ((TPM_RH_t) 0x40000006) -#define TPM_RH_NULL ((TPM_RH_t) 0x40000007) -#define TPM_RH_UNASSIGNED ((TPM_RH_t) 0x40000008) -#define TPM_RS_PW ((TPM_RH_t) 0x40000009) -#define TPM_RH_LOCKOUT ((TPM_RH_t) 0x4000000A) -#define TPM_RH_ENDORSEMENT ((TPM_RH_t) 0x4000000B) -#define TPM_RH_PLATFORM ((TPM_RH_t) 0x4000000C) -#define TPM_RH_PLATFORM_NV ((TPM_RH_t) 0x4000000D) -#define TPM_RH_AUTH_00 ((TPM_RH_t) 0x40000010) -#define TPM_RH_AUTH_FF ((TPM_RH_t) 0x4000010F) -#define TPM_RH_LAST ((TPM_RH_t) 0x4000010F) - -/* TPM_HC_t Constants */ -typedef TPM_HANDLE_t TPM_HC_t; -#define TPM_HR_HANDLE_MASK ((TPM_HC_t) 0x00FFFFFF) -#define TPM_HR_RANGE_MASK ((TPM_HC_t) 0xFF000000) -#define TPM_HR_SHIFT ((TPM_HC_t) 24) -#define TPM_HR_NV_INDEX ((TPM_HC_t) (TPM_HT_NV_INDEX << TPM_HR_SHIFT)) -#define TPM_HR_PERSISTENT ((TPM_HC_t) (TPM_HT_PERSISTENT << TPM_HR_SHIFT)) -#define TPM_HR_PERMANENT ((TPM_HC_t) (TPM_HT_PERMANENT << TPM_HR_SHIFT)) -#define TPM_PERSISTENT_FIRST ((TPM_HC_t) (TPM_HR_PERSISTENT + 0)) -#define TPM_PERSISTENT_LAST ((TPM_HC_t) (TPM_PERSISTENT_FIRST + 0x00FFFFFF)) -#define TPM_PERMANENT_FIRST ((TPM_HC_t) TPM_RH_FIRST) -#define TPM_PERMANENT_LAST ((TPM_HC_t) TPM_RH_LAST) - -/* TPM Handle Type Checks */ -#define TPM_HT_IS_NVINDEX(HANDLE) (((HANDLE) >> TPM_HR_SHIFT) == TPM_HT_NV_INDEX) -#define TPM_HT_IS_PERMANENT(HANDLE) (((HANDLE) >> TPM_HR_SHIFT) == TPM_HT_PERMANENT) -#define TPM_HT_IS_PERSISTENT(HANDLE) (((HANDLE) >> TPM_HR_SHIFT) == TPM_HT_PERSISTENT) - -/* TPM_ECC_CURVE_t Constants */ -typedef grub_uint16_t TPM_ECC_CURVE_t; - -#define TPM_ECC_NONE ((TPM_ECC_CURVE_t) 0x0000) -#define TPM_ECC_NIST_P192 ((TPM_ECC_CURVE_t) 0x0001) -#define TPM_ECC_NIST_P224 ((TPM_ECC_CURVE_t) 0x0002) -#define TPM_ECC_NIST_P256 ((TPM_ECC_CURVE_t) 0x0003) -#define TPM_ECC_NIST_P384 ((TPM_ECC_CURVE_t) 0x0004) -#define TPM_ECC_NIST_P521 ((TPM_ECC_CURVE_t) 0x0005) -#define TPM_ECC_BN_P256 ((TPM_ECC_CURVE_t) 0x0010) -#define TPM_ECC_BN_P638 ((TPM_ECC_CURVE_t) 0x0011) -#define TPM_ECC_SM2_P256 ((TPM_ECC_CURVE_t) 0x0020) - -/* TPM_CC_t Constants */ -typedef grub_uint32_t TPM_CC_t; - -#define TPM_CC_EvictControl ((TPM_CC_t) 0x00000120) -#define TPM_CC_CreatePrimary ((TPM_CC_t) 0x00000131) -#define TPM_CC_Create ((TPM_CC_t) 0x00000153) -#define TPM_CC_FlushContext ((TPM_CC_t) 0x00000165) -#define TPM_CC_ReadPublic ((TPM_CC_t) 0x00000173) -#define TPM_CC_StartAuthSession ((TPM_CC_t) 0x00000176) -#define TPM_CC_PolicyPCR ((TPM_CC_t) 0x0000017f) -#define TPM_CC_NV_DefineSpace ((TPM_CC_t) 0x0000012a) -#define TPM_CC_NV_Read ((TPM_CC_t) 0x0000014e) -#define TPM_CC_NV_ReadPublic ((TPM_CC_t) 0x00000169) -#define TPM_CC_NV_Write ((TPM_CC_t) 0x00000137) -#define TPM_CC_NV_UndefineSpace ((TPM_CC_t) 0x00000122) -#define TPM_CC_GetCapability ((TPM_CC_t) 0x0000017a) -#define TPM_CC_PCR_Read ((TPM_CC_t) 0x0000017e) -#define TPM_CC_Load ((TPM_CC_t) 0x00000157) -#define TPM_CC_LoadExternal ((TPM_CC_t) 0x00000167) -#define TPM_CC_Unseal ((TPM_CC_t) 0x0000015e) -#define TPM_CC_PolicyGetDigest ((TPM_CC_t) 0x00000189) -#define TPM_CC_Hash ((TPM_CC_t) 0x0000017d) -#define TPM_CC_VerifySignature ((TPM_CC_t) 0x00000177) -#define TPM_CC_PolicyAuthorize ((TPM_CC_t) 0x0000016a) -#define TPM_CC_TestParms ((TPM_CC_t) 0x0000018a) - -/* Hash algorithm sizes */ -#define TPM_SHA1_DIGEST_SIZE 20 -#define TPM_SHA256_DIGEST_SIZE 32 -#define TPM_SM3_256_DIGEST_SIZE 32 -#define TPM_SHA384_DIGEST_SIZE 48 -#define TPM_SHA512_DIGEST_SIZE 64 - -/* Encryption algorithm sizes */ -#define TPM_MAX_SYM_BLOCK_SIZE 16 -#define TPM_MAX_SYM_DATA 256 -#define TPM_MAX_ECC_KEY_BYTES 128 -#define TPM_MAX_SYM_KEY_BYTES 32 -#define TPM_MAX_RSA_KEY_BYTES 512 - -/* Buffer Size Constants */ -#define TPM_MAX_PCRS 24 -#define TPM_NUM_PCR_BANKS 16 -#define TPM_PCR_SELECT_MAX ((TPM_MAX_PCRS + 7) / 8) -#define TPM_MAX_DIGEST_BUFFER 1024 -#define TPM_MAX_TPM_PROPERTIES 8 -#define TPM_MAX_NV_BUFFER_SIZE 2048 -#define TPM_PRIVATE_VENDOR_SPECIFIC_BYTES 1280 - -/* TPM_GENERATED_t Constants */ -typedef grub_uint32_t TPM_GENERATED_t; - -#define TPM_GENERATED_VALUE ((TPM_GENERATED_t) 0xff544347) - -/* TPM_ALG_ID_t Types */ -typedef TPM_ALG_ID_t TPMI_ALG_PUBLIC_t; -typedef TPM_ALG_ID_t TPMI_ALG_HASH_t; -typedef TPM_ALG_ID_t TPMI_ALG_KEYEDHASH_SCHEME_t; -typedef TPM_ALG_ID_t TPMI_ALG_KDF_t; -typedef TPM_ALG_ID_t TPMI_ALG_SYM_OBJECT_t; -typedef TPM_ALG_ID_t TPMI_ALG_SYM_MODE_t; -typedef TPM_ALG_ID_t TPMI_ALG_RSA_DECRYPT_t; -typedef TPM_ALG_ID_t TPMI_ALG_ECC_SCHEME_t; -typedef TPM_ALG_ID_t TPMI_ALG_ASYM_SCHEME_t; -typedef TPM_ALG_ID_t TPMI_ALG_RSA_SCHEME_t; -typedef TPM_ALG_ID_t TPMI_ALG_SYM_t; -typedef TPM_ALG_ID_t TPMI_ALG_SIG_SCHEME_t; - -/* TPM_KEY_BITS_t Type */ -typedef grub_uint16_t TPM_KEY_BITS_t; - -/* TPMI_ECC_CURVE_t Types */ -typedef TPM_ECC_CURVE_t TPMI_ECC_CURVE_t; - -/* TPMI_RH_PROVISION_t Type */ -typedef TPM_HANDLE_t TPMI_RH_PROVISION_t; - -/* TPMI_RH_PROVISION_t Type */ -typedef TPM_HANDLE_t TPMI_DH_PERSISTENT_t; - -#endif /* ! GRUB_TPM2_INTERNAL_TYPES_HEADER */ diff --git a/grub-core/lib/uboot/reboot.c b/grub-core/lib/uboot/reboot.c deleted file mode 100644 index 00a2507f0..000000000 --- a/grub-core/lib/uboot/reboot.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -void -grub_reboot (void) -{ - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); - - grub_uboot_reset (); - while (1); -} diff --git a/grub-core/lib/x86_64/efi/relocator.c b/grub-core/lib/x86_64/efi/relocator.c deleted file mode 100644 index 7d200a125..000000000 --- a/grub-core/lib/x86_64/efi/relocator.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * Copyright (C) 2016 Oracle and/or its affiliates. All rights reserved. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include - -#include -#include - -extern grub_uint64_t grub_relocator64_rax; -extern grub_uint64_t grub_relocator64_rbx; -extern grub_uint64_t grub_relocator64_rcx; -extern grub_uint64_t grub_relocator64_rdx; -extern grub_uint64_t grub_relocator64_rip; -extern grub_uint64_t grub_relocator64_rsi; - -extern grub_uint8_t grub_relocator64_efi_start; -extern grub_uint8_t grub_relocator64_efi_end; - -#define RELOCATOR_SIZEOF(x) (&grub_relocator##x##_end - &grub_relocator##x##_start) - -grub_err_t -grub_relocator64_efi_boot (struct grub_relocator *rel, - struct grub_relocator64_efi_state state) -{ - grub_err_t err; - void *relst; - grub_relocator_chunk_t ch; - - /* - * 64-bit relocator code may live above 4 GiB quite well. - * However, I do not want ask for problems. Just in case. - */ - err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0, 0x100000000, - RELOCATOR_SIZEOF (64_efi), 16, - GRUB_RELOCATOR_PREFERENCE_NONE, 1); - if (err) - return err; - - /* Do not touch %rsp! It points to EFI created stack. */ - grub_relocator64_rax = state.rax; - grub_relocator64_rbx = state.rbx; - grub_relocator64_rcx = state.rcx; - grub_relocator64_rdx = state.rdx; - grub_relocator64_rip = state.rip; - grub_relocator64_rsi = state.rsi; - - grub_memmove (get_virtual_current_address (ch), &grub_relocator64_efi_start, - RELOCATOR_SIZEOF (64_efi)); - - err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch), - &relst, NULL); - if (err) - return err; - - ((void (*) (void)) relst) (); - - /* Not reached. */ - return GRUB_ERR_NONE; -} diff --git a/grub-core/lib/x86_64/relocator_asm.S b/grub-core/lib/x86_64/relocator_asm.S deleted file mode 100644 index 12728d8e1..000000000 --- a/grub-core/lib/x86_64/relocator_asm.S +++ /dev/null @@ -1,85 +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 . - */ - -#include -#include - - .p2align 2 - -VARIABLE(grub_relocator_backward_start) - /* mov imm64, %rax */ - .byte 0x48 - .byte 0xb8 -VARIABLE(grub_relocator_backward_dest) - .quad 0 - movq %rax, %rdi - - /* mov imm64, %rax */ - .byte 0x48 - .byte 0xb8 -VARIABLE(grub_relocator_backward_src) - .quad 0 - movq %rax, %rsi - - /* mov imm64, %rcx */ - .byte 0x48 - .byte 0xb9 -VARIABLE(grub_relocator_backward_chunk_size) - .quad 0 - - add %rcx, %rsi - add %rcx, %rdi - - /* Backward movsb is implicitly off-by-one. compensate that. */ - sub $1, %rsi - sub $1, %rdi - - /* Backward copy. */ - std - - rep - movsb -VARIABLE(grub_relocator_backward_end) - - -VARIABLE(grub_relocator_forward_start) - /* mov imm64, %rax */ - .byte 0x48 - .byte 0xb8 -VARIABLE(grub_relocator_forward_dest) - .quad 0 - movq %rax, %rdi - - /* mov imm64, %rax */ - .byte 0x48 - .byte 0xb8 -VARIABLE(grub_relocator_forward_src) - .quad 0 - movq %rax, %rsi - - /* mov imm64, %rcx */ - .byte 0x48 - .byte 0xb9 -VARIABLE(grub_relocator_forward_chunk_size) - .quad 0 - - /* Forward copy. */ - cld - rep - movsb -VARIABLE(grub_relocator_forward_end) diff --git a/grub-core/lib/x86_64/xen/relocator.S b/grub-core/lib/x86_64/xen/relocator.S deleted file mode 100644 index 852cd40aa..000000000 --- a/grub-core/lib/x86_64/xen/relocator.S +++ /dev/null @@ -1,133 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -/* Macro to load an imm64 value stored by the C-part into %rax: */ -#define MOV_IMM64_RAX(var) .byte 0x48, 0xb8; VARIABLE(var); .quad 0 - - .p2align 4 /* force 16-byte alignment */ - -VARIABLE(grub_relocator_xen_remap_start) -LOCAL(base): - /* Remap the remapper to it's new address. */ - MOV_IMM64_RAX(grub_relocator_xen_remapper_virt) - - movq %rax, %rdi /* %rdi: new virtual address of remapper */ - movq %rax, %rbx /* Remember new virtual address */ - - MOV_IMM64_RAX(grub_relocator_xen_remapper_map) - - movq %rax, %rsi /* %rsi: page table entry */ - - movq $UVMF_INVLPG, %rdx /* %rdx: flags (inv. single entry) */ - movq $__HYPERVISOR_update_va_mapping, %rax - syscall /* Do the remap operation */ - - addq $(LOCAL(cont) - LOCAL(base)), %rbx - - jmp *%rbx /* Continue with new virtual address */ - -LOCAL(cont): - /* Modify mappings of new page tables to be read-only. */ - MOV_IMM64_RAX(grub_relocator_xen_mfn_list) - - movq %rax, %rbx /* %rbx is the base of the p2m list */ - leaq EXT_C(grub_relocator_xen_paging_areas) (%rip), %r8 - -1: - movq 0(%r8), %r12 /* Get start pfn of the current area */ - movq GRUB_TARGET_SIZEOF_LONG(%r8), %rcx /* Get # of pg tables */ - testq %rcx, %rcx /* 0 -> last area reached */ - jz 3f -2: - movq %r12, %rdi - shlq $GRUB_PAGE_SHIFT, %rdi /* virtual address (1:1 mapping) */ - movq (%rbx, %r12, 8), %rsi /* mfn */ - shlq $GRUB_PAGE_SHIFT, %rsi - orq $(GRUB_PAGE_PRESENT | GRUB_PAGE_USER), %rsi /* Build pte */ - movq $UVMF_INVLPG, %rdx - movq %rcx, %r9 /* %rcx clobbered by hypercall */ - movq $__HYPERVISOR_update_va_mapping, %rax - syscall - - movq %r9, %rcx - incq %r12 /* next pfn */ - - loop 2b - - addq $(2 * GRUB_TARGET_SIZEOF_LONG), %r8 /* next pg table area */ - jmp 1b - -3: - /* Switch page tables: pin new L4 pt, load cr3, unpin old L4. */ - leaq EXT_C(grub_relocator_xen_mmu_op) (%rip), %rdi - movq $3, %rsi /* 3 mmu ops */ - movq $0, %rdx /* pdone (not used) */ - movq $DOMID_SELF, %r10 - movq $__HYPERVISOR_mmuext_op, %rax - syscall - - /* Continue in virtual kernel mapping. */ - MOV_IMM64_RAX(grub_relocator_xen_remap_continue) - - jmp *%rax - -VARIABLE(grub_relocator_xen_paging_areas) - /* array of start, size pairs, size 0 is end marker */ - .quad 0, 0, 0, 0, 0, 0, 0, 0 - -VARIABLE(grub_relocator_xen_mmu_op) - .space 256 - -VARIABLE(grub_relocator_xen_remap_end) - - -VARIABLE(grub_relocator_xen_start) - /* Unmap old remapper area. */ - MOV_IMM64_RAX(grub_relocator_xen_remapper_virt2) - - movq %rax, %rdi - - xorq %rax, %rax /* Invalid pte */ - movq %rax, %rsi - - movq $UVMF_INVLPG, %rdx - movq $__HYPERVISOR_update_va_mapping, %rax - syscall - - /* Prepare registers for starting kernel. */ - MOV_IMM64_RAX(grub_relocator_xen_stack) - - movq %rax, %rsp - - MOV_IMM64_RAX(grub_relocator_xen_start_info) - - movq %rax, %rsi - - cld - - MOV_IMM64_RAX(grub_relocator_xen_entry_point) - - /* Now start the new kernel. */ - jmp *%rax - -VARIABLE(grub_relocator_xen_end) diff --git a/grub-core/lib/xen/datetime.c b/grub-core/lib/xen/datetime.c deleted file mode 100644 index d96176ec6..000000000 --- a/grub-core/lib/xen/datetime.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -grub_err_t -grub_get_datetime (struct grub_datetime *datetime) -{ - long long nix; - nix = (grub_xen_shared_info->wc_sec - + grub_divmod64 (grub_xen_shared_info->vcpu_info[0].time.system_time, 1000000000, 0)); - grub_unixtime2datetime (nix, datetime); - return GRUB_ERR_NONE; -} - -grub_err_t -grub_set_datetime (struct grub_datetime *datetime __attribute__ ((unused))) -{ - return grub_error (GRUB_ERR_IO, "setting time isn't supported"); -} diff --git a/grub-core/lib/xen/halt.c b/grub-core/lib/xen/halt.c deleted file mode 100644 index 2aceead6e..000000000 --- a/grub-core/lib/xen/halt.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -void -grub_halt (void) -{ - struct sched_shutdown arg; - - arg.reason = SHUTDOWN_poweroff; - grub_xen_sched_op (SCHEDOP_shutdown, &arg); - for (;;); -} diff --git a/grub-core/lib/xen/reboot.c b/grub-core/lib/xen/reboot.c deleted file mode 100644 index fd7609a7d..000000000 --- a/grub-core/lib/xen/reboot.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -void -grub_reboot (void) -{ - struct sched_shutdown arg; - - arg.reason = SHUTDOWN_reboot; - grub_xen_sched_op (SCHEDOP_shutdown, &arg); - for (;;); -} diff --git a/grub-core/lib/xen/relocator.c b/grub-core/lib/xen/relocator.c deleted file mode 100644 index 4d0cbcadb..000000000 --- a/grub-core/lib/xen/relocator.c +++ /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 . - */ - -#include -#include - -#include -#include -#include -#include - -#include -#include - -typedef grub_addr_t grub_xen_reg_t; - -struct grub_relocator_xen_paging_area { - grub_xen_reg_t start; - grub_xen_reg_t size; -} GRUB_PACKED; - -extern grub_uint8_t grub_relocator_xen_start; -extern grub_uint8_t grub_relocator_xen_end; -extern grub_uint8_t grub_relocator_xen_remap_start; -extern grub_uint8_t grub_relocator_xen_remap_end; -extern grub_xen_reg_t grub_relocator_xen_stack; -extern grub_xen_reg_t grub_relocator_xen_start_info; -extern grub_xen_reg_t grub_relocator_xen_entry_point; -extern grub_xen_reg_t grub_relocator_xen_remapper_virt; -extern grub_xen_reg_t grub_relocator_xen_remapper_virt2; -extern grub_xen_reg_t grub_relocator_xen_remapper_map; -extern grub_xen_reg_t grub_relocator_xen_mfn_list; -extern struct grub_relocator_xen_paging_area - grub_relocator_xen_paging_areas[XEN_MAX_MAPPINGS]; -extern grub_xen_reg_t grub_relocator_xen_remap_continue; -#ifdef __i386__ -extern grub_xen_reg_t grub_relocator_xen_mmu_op_addr; -extern grub_xen_reg_t grub_relocator_xen_paging_areas_addr; -extern grub_xen_reg_t grub_relocator_xen_remapper_map_high; -#endif -extern mmuext_op_t grub_relocator_xen_mmu_op[3]; - -#define RELOCATOR_SIZEOF(x) (&grub_relocator##x##_end - &grub_relocator##x##_start) - -grub_err_t -grub_relocator_xen_boot (struct grub_relocator *rel, - struct grub_relocator_xen_state state, - grub_uint64_t remapper_pfn, - grub_addr_t remapper_virt, - grub_uint64_t trampoline_pfn, - grub_addr_t trampoline_virt) -{ - grub_err_t err; - void *relst; - int i; - grub_relocator_chunk_t ch, ch_tramp; - grub_xen_mfn_t *mfn_list = - (grub_xen_mfn_t *) grub_xen_start_page_addr->mfn_list; - - err = grub_relocator_alloc_chunk_addr (rel, &ch, remapper_pfn << 12, - RELOCATOR_SIZEOF (_xen_remap)); - if (err) - return err; - err = grub_relocator_alloc_chunk_addr (rel, &ch_tramp, trampoline_pfn << 12, - RELOCATOR_SIZEOF (_xen)); - if (err) - return err; - - grub_relocator_xen_stack = state.stack; - grub_relocator_xen_start_info = state.start_info; - grub_relocator_xen_entry_point = state.entry_point; - for (i = 0; i < XEN_MAX_MAPPINGS; i++) - { - grub_relocator_xen_paging_areas[i].start = state.paging_start[i]; - grub_relocator_xen_paging_areas[i].size = state.paging_size[i]; - } - grub_relocator_xen_remapper_virt = remapper_virt; - grub_relocator_xen_remapper_virt2 = remapper_virt; - grub_relocator_xen_remap_continue = trampoline_virt; - - grub_relocator_xen_remapper_map = (mfn_list[remapper_pfn] << 12) | 5; -#ifdef __i386__ - grub_relocator_xen_remapper_map_high = (mfn_list[remapper_pfn] >> 20); - grub_relocator_xen_mmu_op_addr = (char *) &grub_relocator_xen_mmu_op - - (char *) &grub_relocator_xen_remap_start + remapper_virt; - grub_relocator_xen_paging_areas_addr = - (char *) &grub_relocator_xen_paging_areas - - (char *) &grub_relocator_xen_remap_start + remapper_virt; -#endif - - grub_relocator_xen_mfn_list = state.mfn_list; - - grub_memset (grub_relocator_xen_mmu_op, 0, - sizeof (grub_relocator_xen_mmu_op)); -#ifdef __i386__ - grub_relocator_xen_mmu_op[0].cmd = MMUEXT_PIN_L3_TABLE; -#else - grub_relocator_xen_mmu_op[0].cmd = MMUEXT_PIN_L4_TABLE; -#endif - grub_relocator_xen_mmu_op[0].arg1.mfn = mfn_list[state.paging_start[0]]; - grub_relocator_xen_mmu_op[1].cmd = MMUEXT_NEW_BASEPTR; - grub_relocator_xen_mmu_op[1].arg1.mfn = mfn_list[state.paging_start[0]]; - grub_relocator_xen_mmu_op[2].cmd = MMUEXT_UNPIN_TABLE; - grub_relocator_xen_mmu_op[2].arg1.mfn = - mfn_list[grub_xen_start_page_addr->pt_base >> 12]; - - grub_memmove (get_virtual_current_address (ch), - &grub_relocator_xen_remap_start, - RELOCATOR_SIZEOF (_xen_remap)); - grub_memmove (get_virtual_current_address (ch_tramp), - &grub_relocator_xen_start, RELOCATOR_SIZEOF (_xen)); - - err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch), - &relst, NULL); - if (err) - return err; - - ((void (*)(void)) relst) (); - - /* Not reached. */ - return GRUB_ERR_NONE; -} diff --git a/grub-core/lib/xzembed/xz.h b/grub-core/lib/xzembed/xz.h deleted file mode 100644 index d1417039a..000000000 --- a/grub-core/lib/xzembed/xz.h +++ /dev/null @@ -1,185 +0,0 @@ -/* xz.h - XZ decompressor */ -/* - * 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 . - */ -/* - * This file is based on code from XZ embedded project - * http://tukaani.org/xz/embedded.html - */ - -#ifndef XZ_H -#define XZ_H - -#include -#include -#include -#include -#include -#include - -/** - * enum xz_ret - Return codes - * @XZ_OK: Everything is OK so far. More input or more output - * space is required to continue. - * @XZ_STREAM_END: Operation finished successfully. - * @XZ_MEMLIMIT_ERROR: Not enough memory was preallocated at decoder - * initialization time. - * @XZ_FORMAT_ERROR: File format was not recognized (wrong magic bytes). - * @XZ_OPTIONS_ERROR: This implementation doesn't support the requested - * compression options. In the decoder this means that - * the header CRC32 matches, but the header itself - * specifies something that we don't support. - * @XZ_DATA_ERROR: Compressed data is corrupt. - * @XZ_BUF_ERROR: Cannot make any progress. Details are slightly - * different between multi-call and single-call mode; - * more information below. - * - * In multi-call mode, XZ_BUF_ERROR is returned when two consecutive calls - * to XZ code cannot consume any input and cannot produce any new output. - * This happens when there is no new input available, or the output buffer - * is full while at least one output byte is still pending. Assuming your - * code is not buggy, you can get this error only when decoding a compressed - * stream that is truncated or otherwise corrupt. - * - * In single-call mode, XZ_BUF_ERROR is returned only when the output buffer - * is too small, or the compressed input is corrupt in a way that makes the - * decoder produce more output than the caller expected. When it is - * (relatively) clear that the compressed input is truncated, XZ_DATA_ERROR - * is used instead of XZ_BUF_ERROR. - */ -enum xz_ret { - XZ_OK, - XZ_STREAM_END, - XZ_MEMLIMIT_ERROR, - XZ_FORMAT_ERROR, - XZ_OPTIONS_ERROR, - XZ_DATA_ERROR, - XZ_BUF_ERROR -}; - -/** - * struct xz_buf - Passing input and output buffers to XZ code - * @in: Beginning of the input buffer. This may be NULL if and only - * if in_pos is equal to in_size. - * @in_pos: Current position in the input buffer. This must not exceed - * in_size. - * @in_size: Size of the input buffer - * @out: Beginning of the output buffer. This may be NULL if and only - * if out_pos is equal to out_size. - * @out_pos: Current position in the output buffer. This must not exceed - * out_size. - * @out_size: Size of the output buffer - * - * Only the contents of the output buffer from out[out_pos] onward, and - * the variables in_pos and out_pos are modified by the XZ code. - */ -struct xz_buf { - const uint8_t *in; - size_t in_pos; - size_t in_size; - - uint8_t *out; - size_t out_pos; - size_t out_size; -}; - -/** - * struct xz_dec - Opaque type to hold the XZ decoder state - */ -struct xz_dec; - -/** - * xz_dec_init() - Allocate and initialize a XZ decoder state - * @dict_max: Maximum size of the LZMA2 dictionary (history buffer) for - * multi-call decoding, or special value of zero to indicate - * single-call decoding mode. - * - * If dict_max > 0, the decoder is initialized to work in multi-call mode. - * dict_max number of bytes of memory is preallocated for the LZMA2 - * dictionary. This way there is no risk that xz_dec_run() could run out - * of memory, since xz_dec_run() will never allocate any memory. Instead, - * if the preallocated dictionary is too small for decoding the given input - * stream, xz_dec_run() will return XZ_MEMLIMIT_ERROR. Thus, it is important - * to know what kind of data will be decoded to avoid allocating excessive - * amount of memory for the dictionary. - * - * LZMA2 dictionary is always 2^n bytes or 2^n + 2^(n-1) bytes (the latter - * sizes are less common in practice). In the kernel, dictionary sizes of - * 64 KiB, 128 KiB, 256 KiB, 512 KiB, and 1 MiB are probably the only - * reasonable values. - * - * If dict_max == 0, the decoder is initialized to work in single-call mode. - * In single-call mode, xz_dec_run() decodes the whole stream at once. The - * caller must provide enough output space or the decoding will fail. The - * output space is used as the dictionary buffer, which is why there is - * no need to allocate the dictionary as part of the decoder's internal - * state. - * - * Because the output buffer is used as the workspace, streams encoded using - * a big dictionary are not a problem in single-call. It is enough that the - * output buffer is is big enough to hold the actual uncompressed data; it - * can be smaller than the dictionary size stored in the stream headers. - * - * On success, xz_dec_init() returns a pointer to struct xz_dec, which is - * ready to be used with xz_dec_run(). On error, xz_dec_init() returns NULL. - */ -struct xz_dec * xz_dec_init(uint32_t dict_max); - -/** - * xz_dec_run() - Run the XZ decoder - * @s: Decoder state allocated using xz_dec_init() - * @b: Input and output buffers - * - * In multi-call mode, this function may return any of the values listed in - * enum xz_ret. - * - * In single-call mode, this function never returns XZ_OK. If an error occurs - * in single-call mode (return value is not XZ_STREAM_END), b->in_pos and - * b->out_pos are not modified, and the contents of the output buffer from - * b->out[b->out_pos] onward are undefined. - * - * NOTE: In single-call mode, the contents of the output buffer are undefined - * also after XZ_BUF_ERROR. This is because with some filter chains, there - * may be a second pass over the output buffer, and this pass cannot be - * properly done if the output buffer is truncated. Thus, you cannot give - * the single-call decoder a too small buffer and then expect to get that - * amount valid data from the beginning of the stream. You must use the - * multi-call decoder if you don't want to uncompress the whole stream. - */ -enum xz_ret xz_dec_run(struct xz_dec *s, struct xz_buf *b); - -/** - * xz_dec_reset() - Reset an already allocated decoder state - * @s: Decoder state allocated using xz_dec_init() - * - * This function can be used to reset the multi-call decoder state without - * freeing and reallocating memory with xz_dec_end() and xz_dec_init(). - * - * In single-call mode, xz_dec_reset() is always called in the beginning of - * xz_dec_run(). Thus, explicit call to xz_dec_reset() is useful only in - * multi-call mode. - */ -void xz_dec_reset(struct xz_dec *s); - -/** - * xz_dec_end() - Free the memory allocated for the decoder state - * @s: Decoder state allocated using xz_dec_init(). If s is NULL, - * this function does nothing. - */ -void xz_dec_end(struct xz_dec *s); - -#endif diff --git a/grub-core/lib/xzembed/xz_config.h b/grub-core/lib/xzembed/xz_config.h deleted file mode 100644 index 24d570f2b..000000000 --- a/grub-core/lib/xzembed/xz_config.h +++ /dev/null @@ -1,152 +0,0 @@ -/* xz_config.h - Private includes and definitions for userspace use */ -/* - * 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 . - */ -/* - * This file is based on code from XZ embedded project - * http://tukaani.org/xz/embedded.html - */ - -#ifndef XZ_CONFIG_H -#define XZ_CONFIG_H - -/* Enable BCJ filter decoders. */ - -#ifndef GRUB_EMBED_DECOMPRESSOR - -#define XZ_DEC_X86 -#define XZ_DEC_POWERPC -#define XZ_DEC_IA64 -#define XZ_DEC_ARM -#define XZ_DEC_ARMTHUMB -#define XZ_DEC_SPARC - -#else - -#if defined(__i386__) || defined(__x86_64__) - #define XZ_DEC_X86 -#endif - -#ifdef __powerpc__ - #define XZ_DEC_POWERPC -#endif - -#ifdef __ia64__ - #define XZ_DEC_IA64 -#endif - -#ifdef __arm__ - #define XZ_DEC_ARM -#endif - -#ifdef __arm__ - #define XZ_DEC_ARMTHUMB -#endif - -#ifdef __sparc__ - #define XZ_DEC_SPARC -#endif -#endif - -#include "xz.h" -#include - -#define kmalloc(size, flags) malloc(size) -#define kfree(ptr) free(ptr) -#define vmalloc(size) malloc(size) -#define vfree(ptr) free(ptr) - -#define memeq(a, b, size) (memcmp(a, b, size) == 0) -#define memzero(buf, size) memset(buf, 0, size) - -#define min(x, y) ((x) < (y) ? (x) : (y)) -#define min_t(type, x, y) min(x, y) - -/* - * Some functions have been marked with __always_inline to keep the - * performance reasonable even when the compiler is optimizing for - * small code size. You may be able to save a few bytes by #defining - * __always_inline to plain inline, but don't complain if the code - * becomes slow. - * - * NOTE: System headers on GNU/Linux may #define this macro already, - * so if you want to change it, it you need to #undef it first. - */ -#ifndef __always_inline -# ifdef __GNUC__ -# define __always_inline \ - inline __attribute__((__always_inline__)) -# else -# define __always_inline inline -# endif -#endif - -/* - * Some functions are marked to never be inlined to reduce stack usage. - * If you don't care about stack usage, you may want to modify this so - * that noinline_for_stack is #defined to be empty even when using GCC. - * Doing so may save a few bytes in binary size. - */ -#ifndef noinline_for_stack -# ifdef __GNUC__ -# define noinline_for_stack __attribute__((__noinline__)) -# else -# define noinline_for_stack -# endif -#endif - -/* Inline functions to access unaligned unsigned 32-bit integers */ -static inline uint32_t get_unaligned_le32(const uint8_t *buf) -{ - return (uint32_t)buf[0] - | ((uint32_t)buf[1] << 8) - | ((uint32_t)buf[2] << 16) - | ((uint32_t)buf[3] << 24); -} - -static inline uint32_t get_unaligned_be32(const uint8_t *buf) -{ - return (uint32_t)(buf[0] << 24) - | ((uint32_t)buf[1] << 16) - | ((uint32_t)buf[2] << 8) - | (uint32_t)buf[3]; -} - -static inline void put_unaligned_le32(uint32_t val, uint8_t *buf) -{ - buf[0] = (uint8_t)val; - buf[1] = (uint8_t)(val >> 8); - buf[2] = (uint8_t)(val >> 16); - buf[3] = (uint8_t)(val >> 24); -} - -static inline void put_unaligned_be32(uint32_t val, uint8_t *buf) -{ - buf[0] = (uint8_t)(val >> 24); - buf[1] = (uint8_t)(val >> 16); - buf[2] = (uint8_t)(val >> 8); - buf[3] = (uint8_t)val; -} - -/* - * Use get_unaligned_le32() also for aligned access for simplicity. On - * little endian systems, #define get_le32(ptr) (*(const uint32_t *)(ptr)) - * could save a few bytes in code size. - */ -#define get_le32 get_unaligned_le32 - -#endif diff --git a/grub-core/lib/xzembed/xz_dec_bcj.c b/grub-core/lib/xzembed/xz_dec_bcj.c deleted file mode 100644 index aef4638d4..000000000 --- a/grub-core/lib/xzembed/xz_dec_bcj.c +++ /dev/null @@ -1,578 +0,0 @@ -/* xz_dec_bcj.c - Branch/Call/Jump (BCJ) filter decoders */ -/* - * 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 . - */ -/* - * This file is based on code from XZ embedded project - * http://tukaani.org/xz/embedded.html - */ - -#include "xz_private.h" - -struct xz_dec_bcj { - /* Type of the BCJ filter being used */ - enum { - BCJ_X86 = 4, /* x86 or x86-64 */ - BCJ_POWERPC = 5, /* Big endian only */ - BCJ_IA64 = 6, /* Big or little endian */ - BCJ_ARM = 7, /* Little endian only */ - BCJ_ARMTHUMB = 8, /* Little endian only */ - BCJ_SPARC = 9 /* Big or little endian */ - } type; - - /* - * Return value of the next filter in the chain. We need to preserve - * this information across calls, because we must not call the next - * filter anymore once it has returned XZ_STREAM_END. - */ - enum xz_ret ret; - - /* True if we are operating in single-call mode. */ - bool single_call; - - /* - * Absolute position relative to the beginning of the uncompressed - * data (in a single .xz Block). We care only about the lowest 32 - * bits so this doesn't need to be uint64_t even with big files. - */ - uint32_t pos; - - /* x86 filter state */ - uint32_t x86_prev_mask; - - /* Temporary space to hold the variables from struct xz_buf */ - uint8_t *out; - size_t out_pos; - size_t out_size; - - struct { - /* Amount of already filtered data in the beginning of buf */ - size_t filtered; - - /* Total amount of data currently stored in buf */ - size_t size; - - /* - * Buffer to hold a mix of filtered and unfiltered data. This - * needs to be big enough to hold Alignment + 2 * Look-ahead: - * - * Type Alignment Look-ahead - * x86 1 4 - * PowerPC 4 0 - * IA-64 16 0 - * ARM 4 0 - * ARM-Thumb 2 2 - * SPARC 4 0 - */ - uint8_t buf[16]; - } temp; -}; - -#ifdef XZ_DEC_X86 -/* - * This is macro used to test the most significant byte of a memory address - * in an x86 instruction. - */ -#define bcj_x86_test_msbyte(b) ((b) == 0x00 || (b) == 0xFF) - -static noinline_for_stack size_t bcj_x86( - struct xz_dec_bcj *s, uint8_t *buf, size_t size) -{ - static const bool mask_to_allowed_status[8] - = { true, true, true, false, true, false, false, false }; - - static const uint8_t mask_to_bit_num[8] = { 0, 1, 2, 2, 3, 3, 3, 3 }; - - size_t i; - size_t prev_pos = (size_t)-1; - uint32_t prev_mask = s->x86_prev_mask; - uint32_t src; - uint32_t dest; - uint32_t j; - uint8_t b; - - if (size <= 4) - return 0; - - size -= 4; - for (i = 0; i < size; ++i) { - if ((buf[i] & 0xFE) != 0xE8) - continue; - - prev_pos = i - prev_pos; - if (prev_pos > 3) { - prev_mask = 0; - } else { - prev_mask = (prev_mask << (prev_pos - 1)) & 7; - if (prev_mask != 0) { - b = buf[i + 4 - mask_to_bit_num[prev_mask]]; - if (!mask_to_allowed_status[prev_mask] - || bcj_x86_test_msbyte(b)) { - prev_pos = i; - prev_mask = (prev_mask << 1) | 1; - continue; - } - } - } - - prev_pos = i; - - if (bcj_x86_test_msbyte(buf[i + 4])) { - src = get_unaligned_le32(buf + i + 1); - while (true) { - dest = src - (s->pos + (uint32_t)i + 5); - if (prev_mask == 0) - break; - - j = mask_to_bit_num[prev_mask] * 8; - b = (uint8_t)(dest >> (24 - j)); - if (!bcj_x86_test_msbyte(b)) - break; - - src = dest ^ (((uint32_t)1 << (32 - j)) - 1); - } - - dest &= 0x01FFFFFF; - dest |= (uint32_t)0 - (dest & 0x01000000); - put_unaligned_le32(dest, buf + i + 1); - i += 4; - } else { - prev_mask = (prev_mask << 1) | 1; - } - } - - prev_pos = i - prev_pos; - s->x86_prev_mask = prev_pos > 3 ? 0 : prev_mask << (prev_pos - 1); - return i; -} -#endif - -#ifdef XZ_DEC_POWERPC -static noinline_for_stack size_t bcj_powerpc( - struct xz_dec_bcj *s, uint8_t *buf, size_t size) -{ - size_t i; - uint32_t instr; - - for (i = 0; i + 3 < size; i += 4) { - instr = get_unaligned_be32(buf + i); - if ((instr & 0xFC000003) == 0x48000001) { - instr &= 0x03FFFFFC; - instr -= s->pos + (uint32_t)i; - instr &= 0x03FFFFFC; - instr |= 0x48000001; - put_unaligned_be32(instr, buf + i); - } - } - - return i; -} -#endif - -#ifdef XZ_DEC_IA64 -static noinline_for_stack size_t bcj_ia64( - struct xz_dec_bcj *s, uint8_t *buf, size_t size) -{ - static const uint8_t branch_table[32] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 4, 4, 6, 6, 0, 0, 7, 7, - 4, 4, 0, 0, 4, 4, 0, 0 - }; - - /* - * The local variables take a little bit stack space, but it's less - * than what LZMA2 decoder takes, so it doesn't make sense to reduce - * stack usage here without doing that for the LZMA2 decoder too. - */ - - /* Loop counters */ - size_t i; - size_t j; - - /* Instruction slot (0, 1, or 2) in the 128-bit instruction word */ - uint32_t slot; - - /* Bitwise offset of the instruction indicated by slot */ - uint32_t bit_pos; - - /* bit_pos split into byte and bit parts */ - uint32_t byte_pos; - uint32_t bit_res; - - /* Address part of an instruction */ - uint32_t addr; - - /* Mask used to detect which instructions to convert */ - uint32_t mask; - - /* 41-bit instruction stored somewhere in the lowest 48 bits */ - uint64_t instr; - - /* Instruction normalized with bit_res for easier manipulation */ - uint64_t norm; - - for (i = 0; i + 16 <= size; i += 16) { - mask = branch_table[buf[i] & 0x1F]; - for (slot = 0, bit_pos = 5; slot < 3; ++slot, bit_pos += 41) { - if (((mask >> slot) & 1) == 0) - continue; - - byte_pos = bit_pos >> 3; - bit_res = bit_pos & 7; - instr = 0; - for (j = 0; j < 6; ++j) - instr |= (uint64_t)(buf[i + j + byte_pos]) - << (8 * j); - - norm = instr >> bit_res; - - if (((norm >> 37) & 0x0F) == 0x05 - && ((norm >> 9) & 0x07) == 0) { - addr = (norm >> 13) & 0x0FFFFF; - addr |= ((uint32_t)(norm >> 36) & 1) << 20; - addr <<= 4; - addr -= s->pos + (uint32_t)i; - addr >>= 4; - - norm &= ~((uint64_t)0x8FFFFF << 13); - norm |= (uint64_t)(addr & 0x0FFFFF) << 13; - norm |= (uint64_t)(addr & 0x100000) - << (36 - 20); - - instr &= (1 << bit_res) - 1; - instr |= norm << bit_res; - - for (j = 0; j < 6; j++) - buf[i + j + byte_pos] - = (uint8_t)(instr >> (8 * j)); - } - } - } - - return i; -} -#endif - -#ifdef XZ_DEC_ARM -static noinline_for_stack size_t bcj_arm( - struct xz_dec_bcj *s, uint8_t *buf, size_t size) -{ - size_t i; - uint32_t addr; - - for (i = 0; i + 4 <= size; i += 4) { - if (buf[i + 3] == 0xEB) { - addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8) - | ((uint32_t)buf[i + 2] << 16); - addr <<= 2; - addr -= s->pos + (uint32_t)i + 8; - addr >>= 2; - buf[i] = (uint8_t)addr; - buf[i + 1] = (uint8_t)(addr >> 8); - buf[i + 2] = (uint8_t)(addr >> 16); - } - } - - return i; -} -#endif - -#ifdef XZ_DEC_ARMTHUMB -static noinline_for_stack size_t bcj_armthumb( - struct xz_dec_bcj *s, uint8_t *buf, size_t size) -{ - size_t i; - uint32_t addr; - - for (i = 0; i + 4 <= size; i += 2) { - if ((buf[i + 1] & 0xF8) == 0xF0 - && (buf[i + 3] & 0xF8) == 0xF8) { - addr = (((uint32_t)buf[i + 1] & 0x07) << 19) - | ((uint32_t)buf[i] << 11) - | (((uint32_t)buf[i + 3] & 0x07) << 8) - | (uint32_t)buf[i + 2]; - addr <<= 1; - addr -= s->pos + (uint32_t)i + 4; - addr >>= 1; - buf[i + 1] = (uint8_t)(0xF0 | ((addr >> 19) & 0x07)); - buf[i] = (uint8_t)(addr >> 11); - buf[i + 3] = (uint8_t)(0xF8 | ((addr >> 8) & 0x07)); - buf[i + 2] = (uint8_t)addr; - i += 2; - } - } - - return i; -} -#endif - -#ifdef XZ_DEC_SPARC -static noinline_for_stack size_t bcj_sparc( - struct xz_dec_bcj *s, uint8_t *buf, size_t size) -{ - size_t i; - uint32_t instr; - - for (i = 0; i + 4 <= size; i += 4) { - instr = get_unaligned_be32(buf + i); - if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF) { - instr <<= 2; - instr -= s->pos + (uint32_t)i; - instr >>= 2; - instr = ((uint32_t)0x40000000 - (instr & 0x400000)) - | 0x40000000 | (instr & 0x3FFFFF); - put_unaligned_be32(instr, buf + i); - } - } - - return i; -} -#endif - -/* - * Apply the selected BCJ filter. Update *pos and s->pos to match the amount - * of data that got filtered. - * - * NOTE: This is implemented as a switch statement to avoid using function - * pointers, which could be problematic in the kernel boot code, which must - * avoid pointers to static data (at least on x86). - */ -static void bcj_apply(struct xz_dec_bcj *s, - uint8_t *buf __attribute__((unused)), size_t *pos, size_t size __attribute__((unused))) -{ - size_t filtered; - - buf += *pos; - size -= *pos; - - switch (s->type) { -#ifdef XZ_DEC_X86 - case BCJ_X86: - filtered = bcj_x86(s, buf, size); - break; -#endif -#ifdef XZ_DEC_POWERPC - case BCJ_POWERPC: - filtered = bcj_powerpc(s, buf, size); - break; -#endif -#ifdef XZ_DEC_IA64 - case BCJ_IA64: - filtered = bcj_ia64(s, buf, size); - break; -#endif -#ifdef XZ_DEC_ARM - case BCJ_ARM: - filtered = bcj_arm(s, buf, size); - break; -#endif -#ifdef XZ_DEC_ARMTHUMB - case BCJ_ARMTHUMB: - filtered = bcj_armthumb(s, buf, size); - break; -#endif -#ifdef XZ_DEC_SPARC - case BCJ_SPARC: - filtered = bcj_sparc(s, buf, size); - break; -#endif - default: - /* Never reached but silence compiler warnings. */ - filtered = 0; - break; - } - - *pos += filtered; - s->pos += filtered; -} - -/* - * Flush pending filtered data from temp to the output buffer. - * Move the remaining mixture of possibly filtered and unfiltered - * data to the beginning of temp. - */ -static void bcj_flush(struct xz_dec_bcj *s, struct xz_buf *b) -{ - size_t copy_size; - - copy_size = min_t(size_t, s->temp.filtered, b->out_size - b->out_pos); - memcpy(b->out + b->out_pos, s->temp.buf, copy_size); - b->out_pos += copy_size; - - s->temp.filtered -= copy_size; - s->temp.size -= copy_size; - memmove(s->temp.buf, s->temp.buf + copy_size, s->temp.size); -} - -/* - * The BCJ filter functions are primitive in sense that they process the - * data in chunks of 1-16 bytes. To hide this issue, this function does - * some buffering. - */ -enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, - struct xz_dec_lzma2 *lzma2, struct xz_buf *b) -{ - size_t out_start; - - /* - * Flush pending already filtered data to the output buffer. Return - * immediatelly if we couldn't flush everything, or if the next - * filter in the chain had already returned XZ_STREAM_END. - */ - if (s->temp.filtered > 0) { - bcj_flush(s, b); - if (s->temp.filtered > 0) - return XZ_OK; - - if (s->ret == XZ_STREAM_END) - return XZ_STREAM_END; - } - - /* - * If we have more output space than what is currently pending in - * temp, copy the unfiltered data from temp to the output buffer - * and try to fill the output buffer by decoding more data from the - * next filter in the chain. Apply the BCJ filter on the new data - * in the output buffer. If everything cannot be filtered, copy it - * to temp and rewind the output buffer position accordingly. - */ - if (s->temp.size < b->out_size - b->out_pos) { - out_start = b->out_pos; - memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size); - b->out_pos += s->temp.size; - - s->ret = xz_dec_lzma2_run(lzma2, b); - if (s->ret != XZ_STREAM_END - && (s->ret != XZ_OK || s->single_call)) - return s->ret; - - bcj_apply(s, b->out, &out_start, b->out_pos); - - /* - * As an exception, if the next filter returned XZ_STREAM_END, - * we can do that too, since the last few bytes that remain - * unfiltered are meant to remain unfiltered. - */ - if (s->ret == XZ_STREAM_END) - return XZ_STREAM_END; - - s->temp.size = b->out_pos - out_start; - b->out_pos -= s->temp.size; - memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size); - } - - /* - * If we have unfiltered data in temp, try to fill by decoding more - * data from the next filter. Apply the BCJ filter on temp. Then we - * hopefully can fill the actual output buffer by copying filtered - * data from temp. A mix of filtered and unfiltered data may be left - * in temp; it will be taken care on the next call to this function. - */ - if (s->temp.size > 0) { - /* Make b->out{,_pos,_size} temporarily point to s->temp. */ - s->out = b->out; - s->out_pos = b->out_pos; - s->out_size = b->out_size; - b->out = s->temp.buf; - b->out_pos = s->temp.size; - b->out_size = sizeof(s->temp.buf); - - s->ret = xz_dec_lzma2_run(lzma2, b); - - s->temp.size = b->out_pos; - b->out = s->out; - b->out_pos = s->out_pos; - b->out_size = s->out_size; - - if (s->ret != XZ_OK && s->ret != XZ_STREAM_END) - return s->ret; - - bcj_apply(s, s->temp.buf, &s->temp.filtered, s->temp.size); - - /* - * If the next filter returned XZ_STREAM_END, we mark that - * everything is filtered, since the last unfiltered bytes - * of the stream are meant to be left as is. - */ - if (s->ret == XZ_STREAM_END) - s->temp.filtered = s->temp.size; - - bcj_flush(s, b); - if (s->temp.filtered > 0) - return XZ_OK; - } - - return s->ret; -} - -#ifdef GRUB_EMBED_DECOMPRESSOR -struct xz_dec_bcj bcj; -#endif - -struct xz_dec_bcj * xz_dec_bcj_create(bool single_call) -{ - struct xz_dec_bcj *s; -#ifdef GRUB_EMBED_DECOMPRESSOR - s = &bcj; -#else - s = kmalloc(sizeof(*s), GFP_KERNEL); -#endif - if (s != NULL) - s->single_call = single_call; - - return s; -} - -enum xz_ret xz_dec_bcj_reset( - struct xz_dec_bcj *s, uint8_t id) -{ - switch (id) { -#ifdef XZ_DEC_X86 - case BCJ_X86: -#endif -#ifdef XZ_DEC_POWERPC - case BCJ_POWERPC: -#endif -#ifdef XZ_DEC_IA64 - case BCJ_IA64: -#endif -#ifdef XZ_DEC_ARM - case BCJ_ARM: -#endif -#ifdef XZ_DEC_ARMTHUMB - case BCJ_ARMTHUMB: -#endif -#ifdef XZ_DEC_SPARC - case BCJ_SPARC: -#endif - break; - - default: - /* Unsupported Filter ID */ - return XZ_OPTIONS_ERROR; - } - - s->type = id; - s->ret = XZ_OK; - s->pos = 0; - s->x86_prev_mask = 0; - s->temp.filtered = 0; - s->temp.size = 0; - - return XZ_OK; -} diff --git a/grub-core/lib/xzembed/xz_dec_lzma2.c b/grub-core/lib/xzembed/xz_dec_lzma2.c deleted file mode 100644 index af7b77079..000000000 --- a/grub-core/lib/xzembed/xz_dec_lzma2.c +++ /dev/null @@ -1,1188 +0,0 @@ -/* xz_dec_lzma2.c - LZMA2 decoder */ -/* - * 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 . - */ -/* - * This file is based on code from XZ embedded project - * http://tukaani.org/xz/embedded.html - */ - -#include "xz_private.h" -#include "xz_lzma2.h" - -#pragma GCC diagnostic warning "-Wattributes" - -/* - * Range decoder initialization eats the first five bytes of each LZMA chunk. - */ -#define RC_INIT_BYTES 5 - -/* - * Minimum number of usable input buffer to safely decode one LZMA symbol. - * The worst case is that we decode 22 bits using probabilities and 26 - * direct bits. This may decode at maximum of 20 bytes of input. However, - * lzma_main() does an extra normalization before returning, thus we - * need to put 21 here. - */ -#define LZMA_IN_REQUIRED 21 - -/* - * Dictionary (history buffer) - * - * These are always true: - * start <= pos <= full <= end - * pos <= limit <= end - * - * In multi-call mode, also these are true: - * end == size - * size <= allocated - * - * Most of these variables are size_t to support single-call mode, - * in which the dictionary variables address the actual output - * buffer directly. - */ -struct dictionary { - /* Beginning of the history buffer */ - uint8_t *buf; - - /* Old position in buf (before decoding more data) */ - size_t start; - - /* Position in buf */ - size_t pos; - - /* - * How full dictionary is. This is used to detect corrupt input that - * would read beyond the beginning of the uncompressed stream. - */ - size_t full; - - /* Write limit; we don't write to buf[limit] or later bytes. */ - size_t limit; - - /* - * End of the dictionary buffer. In multi-call mode, this is - * the same as the dictionary size. In single-call mode, this - * indicates the size of the output buffer. - */ - size_t end; - - /* - * Size of the dictionary as specified in Block Header. This is used - * together with "full" to detect corrupt input that would make us - * read beyond the beginning of the uncompressed stream. - */ - uint32_t size; - - /* - * Amount of memory allocated for the dictionary. A special - * value of zero indicates that we are in single-call mode, - * where the output buffer works as the dictionary. - */ - uint32_t allocated; -}; - -/* Range decoder */ -struct rc_dec { - uint32_t range; - uint32_t code; - - /* - * Number of initializing bytes remaining to be read - * by rc_read_init(). - */ - uint32_t init_bytes_left; - - /* - * Buffer from which we read our input. It can be either - * temp.buf or the caller-provided input buffer. - */ - const uint8_t *in; - size_t in_pos; - size_t in_limit; -}; - -/* Probabilities for a length decoder. */ -struct lzma_len_dec { - /* Probability of match length being at least 10 */ - uint16_t choice; - - /* Probability of match length being at least 18 */ - uint16_t choice2; - - /* Probabilities for match lengths 2-9 */ - uint16_t low[POS_STATES_MAX][LEN_LOW_SYMBOLS]; - - /* Probabilities for match lengths 10-17 */ - uint16_t mid[POS_STATES_MAX][LEN_MID_SYMBOLS]; - - /* Probabilities for match lengths 18-273 */ - uint16_t high[LEN_HIGH_SYMBOLS]; -}; - -struct lzma_dec { - /* - * LZMA properties or related bit masks (number of literal - * context bits, a mask dervied from the number of literal - * position bits, and a mask dervied from the number - * position bits) - */ - uint32_t lc; - uint32_t literal_pos_mask; /* (1 << lp) - 1 */ - uint32_t pos_mask; /* (1 << pb) - 1 */ - - /* Types of the most recently seen LZMA symbols */ - enum lzma_state state; - - /* Distances of latest four matches */ - uint32_t rep0; - uint32_t rep1; - uint32_t rep2; - uint32_t rep3; - - /* - * Length of a match. This is updated so that dict_repeat can - * be called again to finish repeating the whole match. - */ - uint32_t len; - - /* If 1, it's a match. Otherwise it's a single 8-bit literal. */ - uint16_t is_match[STATES][POS_STATES_MAX]; - - /* If 1, it's a repeated match. The distance is one of rep0 .. rep3. */ - uint16_t is_rep[STATES]; - - /* - * If 0, distance of a repeated match is rep0. - * Otherwise check is_rep1. - */ - uint16_t is_rep0[STATES]; - - /* - * If 0, distance of a repeated match is rep1. - * Otherwise check is_rep2. - */ - uint16_t is_rep1[STATES]; - - /* If 0, distance of a repeated match is rep2. Otherwise it is rep3. */ - uint16_t is_rep2[STATES]; - - /* - * If 1, the repeated match has length of one byte. Otherwise - * the length is decoded from rep_len_decoder. - */ - uint16_t is_rep0_long[STATES][POS_STATES_MAX]; - - /* - * Probability tree for the highest two bits of the match - * distance. There is a separate probability tree for match - * lengths of 2 (i.e. MATCH_LEN_MIN), 3, 4, and [5, 273]. - */ - uint16_t dist_slot[DIST_STATES][DIST_SLOTS]; - - /* - * Probility trees for additional bits for match distance - * when the distance is in the range [4, 127]. - */ - uint16_t dist_special[FULL_DISTANCES - DIST_MODEL_END]; - - /* - * Probability tree for the lowest four bits of a match - * distance that is equal to or greater than 128. - */ - uint16_t dist_align[ALIGN_SIZE]; - - /* Length of a normal match */ - struct lzma_len_dec match_len_dec; - - /* Length of a repeated match */ - struct lzma_len_dec rep_len_dec; - - /* Probabilities of literals */ - uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE]; -}; - -struct xz_dec_lzma2 { - /* LZMA2 */ - struct { - /* Position in xz_dec_lzma2_run(). */ - enum lzma2_seq { - SEQ_CONTROL, - SEQ_UNCOMPRESSED_1, - SEQ_UNCOMPRESSED_2, - SEQ_COMPRESSED_0, - SEQ_COMPRESSED_1, - SEQ_PROPERTIES, - SEQ_LZMA_PREPARE, - SEQ_LZMA_RUN, - SEQ_COPY - } sequence; - - /* - * Next position after decoding the compressed size of - * the chunk. - */ - enum lzma2_seq next_sequence; - - /* Uncompressed size of LZMA chunk (2 MiB at maximum) */ - uint32_t uncompressed; - - /* - * Compressed size of LZMA chunk or compressed/uncompressed - * size of uncompressed chunk (64 KiB at maximum) - */ - uint32_t compressed; - - /* - * True if dictionary reset is needed. This is false before - * the first chunk (LZMA or uncompressed). - */ - bool need_dict_reset; - - /* - * True if new LZMA properties are needed. This is false - * before the first LZMA chunk. - */ - bool need_props; - } lzma2; - - /* - * Temporary buffer which holds small number of input bytes between - * decoder calls. See lzma2_lzma() for details. - */ - struct { - uint32_t size; - uint8_t buf[3 * LZMA_IN_REQUIRED]; - } temp; - - struct dictionary dict; - struct rc_dec rc; - struct lzma_dec lzma; -}; - -/************** - * Dictionary * - **************/ - -/* - * Reset the dictionary state. When in single-call mode, set up the beginning - * of the dictionary to point to the actual output buffer. - */ -static void dict_reset(struct dictionary *dict, struct xz_buf *b) -{ - if (dict->allocated == 0) { - dict->buf = b->out + b->out_pos; - dict->end = b->out_size - b->out_pos; - } - dict->start = 0; - dict->pos = 0; - dict->limit = 0; - dict->full = 0; -} - -/* Set dictionary write limit */ -static void dict_limit(struct dictionary *dict, size_t out_max) -{ - if (dict->end - dict->pos <= out_max) - dict->limit = dict->end; - else - dict->limit = dict->pos + out_max; -} - -/* Return true if at least one byte can be written into the dictionary. */ -static inline bool dict_has_space(const struct dictionary *dict) -{ - return dict->pos < dict->limit; -} - -/* - * Get a byte from the dictionary at the given distance. The distance is - * assumed to valid, or as a special case, zero when the dictionary is - * still empty. This special case is needed for single-call decoding to - * avoid writing a '\0' to the end of the destination buffer. - */ -static inline uint32_t dict_get( - const struct dictionary *dict, uint32_t dist) -{ - size_t offset = dict->pos - dist - 1; - - if (dist >= dict->pos) - offset += dict->end; - - return dict->full > 0 ? dict->buf[offset] : 0; -} - -/* - * Put one byte into the dictionary. It is assumed that there is space for it. - */ -static inline void dict_put(struct dictionary *dict, uint8_t b) -{ - dict->buf[dict->pos++] = b; - - if (dict->full < dict->pos) - dict->full = dict->pos; -} - -/* - * Repeat given number of bytes from the given distance. If the distance is - * invalid, false is returned. On success, true is returned and *len is - * updated to indicate how many bytes were left to be repeated. - */ -static bool dict_repeat( - struct dictionary *dict, uint32_t *len, uint32_t dist) -{ - size_t back; - uint32_t left; - - if (dist >= dict->full || dist >= dict->size) - return false; - - left = min_t(size_t, dict->limit - dict->pos, *len); - *len -= left; - - back = dict->pos - dist - 1; - if (dist >= dict->pos) - back += dict->end; - - do { - dict->buf[dict->pos++] = dict->buf[back++]; - if (back == dict->end) - back = 0; - } while (--left > 0); - - if (dict->full < dict->pos) - dict->full = dict->pos; - - return true; -} - -/* Copy uncompressed data as is from input to dictionary and output buffers. */ -static void dict_uncompressed( - struct dictionary *dict, struct xz_buf *b, uint32_t *left) -{ - size_t copy_size; - - while (*left > 0 && b->in_pos < b->in_size - && b->out_pos < b->out_size) { - copy_size = min(b->in_size - b->in_pos, - b->out_size - b->out_pos); - if (copy_size > dict->end - dict->pos) - copy_size = dict->end - dict->pos; - if (copy_size > *left) - copy_size = *left; - - *left -= copy_size; - - memcpy(dict->buf + dict->pos, b->in + b->in_pos, copy_size); - dict->pos += copy_size; - - if (dict->full < dict->pos) - dict->full = dict->pos; - - if (dict->allocated != 0) { - if (dict->pos == dict->end) - dict->pos = 0; - - memcpy(b->out + b->out_pos, b->in + b->in_pos, - copy_size); - } - - dict->start = dict->pos; - - b->out_pos += copy_size; - b->in_pos += copy_size; - - } -} - -/* - * Flush pending data from dictionary to b->out. It is assumed that there is - * enough space in b->out. This is guaranteed because caller uses dict_limit() - * before decoding data into the dictionary. - */ -static uint32_t dict_flush(struct dictionary *dict, struct xz_buf *b) -{ - size_t copy_size = dict->pos - dict->start; - - if (dict->allocated != 0) { - if (dict->pos == dict->end) - dict->pos = 0; - - memcpy(b->out + b->out_pos, dict->buf + dict->start, - copy_size); - } - - dict->start = dict->pos; - b->out_pos += copy_size; - return copy_size; -} - -/***************** - * Range decoder * - *****************/ - -/* Reset the range decoder. */ -static void rc_reset(struct rc_dec *rc) -{ - rc->range = (uint32_t)-1; - rc->code = 0; - rc->init_bytes_left = RC_INIT_BYTES; -} - -/* - * Read the first five initial bytes into rc->code if they haven't been - * read already. (Yes, the first byte gets completely ignored.) - */ -static bool rc_read_init(struct rc_dec *rc, struct xz_buf *b) -{ - while (rc->init_bytes_left > 0) { - if (b->in_pos == b->in_size) - return false; - - rc->code = (rc->code << 8) + b->in[b->in_pos++]; - --rc->init_bytes_left; - } - - return true; -} - -/* Return true if there may not be enough input for the next decoding loop. */ -static inline bool rc_limit_exceeded(const struct rc_dec *rc) -{ - return rc->in_pos > rc->in_limit; -} - -/* - * Return true if it is possible (from point of view of range decoder) that - * we have reached the end of the LZMA chunk. - */ -static inline bool rc_is_finished(const struct rc_dec *rc) -{ - return rc->code == 0; -} - -/* Read the next input byte if needed. */ -static __always_inline void rc_normalize(struct rc_dec *rc) -{ - if (rc->range < RC_TOP_VALUE) { - rc->range <<= RC_SHIFT_BITS; - rc->code = (rc->code << RC_SHIFT_BITS) + rc->in[rc->in_pos++]; - } -} - -/* - * Decode one bit. In some versions, this function has been splitted in three - * functions so that the compiler is supposed to be able to more easily avoid - * an extra branch. In this particular version of the LZMA decoder, this - * doesn't seem to be a good idea (tested with GCC 3.3.6, 3.4.6, and 4.3.3 - * on x86). Using a non-splitted version results in nicer looking code too. - * - * NOTE: This must return an int. Do not make it return a bool or the speed - * of the code generated by GCC 3.x decreases 10-15 %. (GCC 4.3 doesn't care, - * and it generates 10-20 % faster code than GCC 3.x from this file anyway.) - */ -static __always_inline int rc_bit(struct rc_dec *rc, uint16_t *prob) -{ - uint32_t bound; - int bit; - - rc_normalize(rc); - bound = (rc->range >> RC_BIT_MODEL_TOTAL_BITS) * *prob; - if (rc->code < bound) { - rc->range = bound; - *prob += (RC_BIT_MODEL_TOTAL - *prob) >> RC_MOVE_BITS; - bit = 0; - } else { - rc->range -= bound; - rc->code -= bound; - *prob -= *prob >> RC_MOVE_BITS; - bit = 1; - } - - return bit; -} - -/* Decode a bittree starting from the most significant bit. */ -static __always_inline uint32_t rc_bittree( - struct rc_dec *rc, uint16_t *probs, uint32_t limit) -{ - uint32_t symbol = 1; - - do { - if (rc_bit(rc, &probs[symbol])) - symbol = (symbol << 1) + 1; - else - symbol <<= 1; - } while (symbol < limit); - - return symbol; -} - -/* Decode a bittree starting from the least significant bit. */ -static __always_inline void rc_bittree_reverse(struct rc_dec *rc, - uint16_t *probs, uint32_t *dest, uint32_t limit) -{ - uint32_t symbol = 1; - uint32_t i = 0; - - do { - if (rc_bit(rc, &probs[symbol])) { - symbol = (symbol << 1) + 1; - *dest += 1 << i; - } else { - symbol <<= 1; - } - } while (++i < limit); -} - -/* Decode direct bits (fixed fifty-fifty probability) */ -static inline void rc_direct( - struct rc_dec *rc, uint32_t *dest, uint32_t limit) -{ - uint32_t mask; - - do { - rc_normalize(rc); - rc->range >>= 1; - rc->code -= rc->range; - mask = (uint32_t)0 - (rc->code >> 31); - rc->code += rc->range & mask; - *dest = (*dest << 1) + (mask + 1); - } while (--limit > 0); -} - -/******** - * LZMA * - ********/ - -/* Get pointer to literal coder probability array. */ -static uint16_t * lzma_literal_probs(struct xz_dec_lzma2 *s) -{ - uint32_t prev_byte = dict_get(&s->dict, 0); - uint32_t low = prev_byte >> (8 - s->lzma.lc); - uint32_t high = (s->dict.pos & s->lzma.literal_pos_mask) << s->lzma.lc; - return s->lzma.literal[low + high]; -} - -/* Decode a literal (one 8-bit byte) */ -static void lzma_literal(struct xz_dec_lzma2 *s) -{ - uint16_t *probs; - uint32_t symbol; - uint32_t match_byte; - uint32_t match_bit; - uint32_t offset; - uint32_t i; - - probs = lzma_literal_probs(s); - - if (lzma_state_is_literal(s->lzma.state)) { - symbol = rc_bittree(&s->rc, probs, 0x100); - } else { - symbol = 1; - match_byte = dict_get(&s->dict, s->lzma.rep0) << 1; - offset = 0x100; - - do { - match_bit = match_byte & offset; - match_byte <<= 1; - i = offset + match_bit + symbol; - - if (rc_bit(&s->rc, &probs[i])) { - symbol = (symbol << 1) + 1; - offset &= match_bit; - } else { - symbol <<= 1; - offset &= ~match_bit; - } - } while (symbol < 0x100); - } - - dict_put(&s->dict, (uint8_t)symbol); - lzma_state_literal(&s->lzma.state); -} - -/* Decode the length of the match into s->lzma.len. */ -static void lzma_len(struct xz_dec_lzma2 *s, struct lzma_len_dec *l, - uint32_t pos_state) -{ - uint16_t *probs; - uint32_t limit; - - if (!rc_bit(&s->rc, &l->choice)) { - probs = l->low[pos_state]; - limit = LEN_LOW_SYMBOLS; - s->lzma.len = MATCH_LEN_MIN; - } else { - if (!rc_bit(&s->rc, &l->choice2)) { - probs = l->mid[pos_state]; - limit = LEN_MID_SYMBOLS; - s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS; - } else { - probs = l->high; - limit = LEN_HIGH_SYMBOLS; - s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS - + LEN_MID_SYMBOLS; - } - } - - s->lzma.len += rc_bittree(&s->rc, probs, limit) - limit; -} - -/* Decode a match. The distance will be stored in s->lzma.rep0. */ -static void lzma_match(struct xz_dec_lzma2 *s, uint32_t pos_state) -{ - uint16_t *probs; - uint32_t dist_slot; - uint32_t limit; - - lzma_state_match(&s->lzma.state); - - s->lzma.rep3 = s->lzma.rep2; - s->lzma.rep2 = s->lzma.rep1; - s->lzma.rep1 = s->lzma.rep0; - - lzma_len(s, &s->lzma.match_len_dec, pos_state); - - probs = s->lzma.dist_slot[lzma_get_dist_state(s->lzma.len)]; - dist_slot = rc_bittree(&s->rc, probs, DIST_SLOTS) - DIST_SLOTS; - - if (dist_slot < DIST_MODEL_START) { - s->lzma.rep0 = dist_slot; - } else { - limit = (dist_slot >> 1) - 1; - s->lzma.rep0 = 2 + (dist_slot & 1); - - if (dist_slot < DIST_MODEL_END) { - s->lzma.rep0 <<= limit; - probs = s->lzma.dist_special + s->lzma.rep0 - - dist_slot - 1; - rc_bittree_reverse(&s->rc, probs, - &s->lzma.rep0, limit); - } else { - rc_direct(&s->rc, &s->lzma.rep0, limit - ALIGN_BITS); - s->lzma.rep0 <<= ALIGN_BITS; - rc_bittree_reverse(&s->rc, s->lzma.dist_align, - &s->lzma.rep0, ALIGN_BITS); - } - } -} - -/* - * Decode a repeated match. The distance is one of the four most recently - * seen matches. The distance will be stored in s->lzma.rep0. - */ -static void lzma_rep_match(struct xz_dec_lzma2 *s, uint32_t pos_state) -{ - uint32_t tmp; - - if (!rc_bit(&s->rc, &s->lzma.is_rep0[s->lzma.state])) { - if (!rc_bit(&s->rc, &s->lzma.is_rep0_long[ - s->lzma.state][pos_state])) { - lzma_state_short_rep(&s->lzma.state); - s->lzma.len = 1; - return; - } - } else { - if (!rc_bit(&s->rc, &s->lzma.is_rep1[s->lzma.state])) { - tmp = s->lzma.rep1; - } else { - if (!rc_bit(&s->rc, &s->lzma.is_rep2[s->lzma.state])) { - tmp = s->lzma.rep2; - } else { - tmp = s->lzma.rep3; - s->lzma.rep3 = s->lzma.rep2; - } - - s->lzma.rep2 = s->lzma.rep1; - } - - s->lzma.rep1 = s->lzma.rep0; - s->lzma.rep0 = tmp; - } - - lzma_state_long_rep(&s->lzma.state); - lzma_len(s, &s->lzma.rep_len_dec, pos_state); -} - -/* LZMA decoder core */ -static bool lzma_main(struct xz_dec_lzma2 *s) -{ - uint32_t pos_state; - - /* - * If the dictionary was reached during the previous call, try to - * finish the possibly pending repeat in the dictionary. - */ - if (dict_has_space(&s->dict) && s->lzma.len > 0) - dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0); - - /* - * Decode more LZMA symbols. One iteration may consume up to - * LZMA_IN_REQUIRED - 1 bytes. - */ - while (dict_has_space(&s->dict) && !rc_limit_exceeded(&s->rc)) { - pos_state = s->dict.pos & s->lzma.pos_mask; - - if (!rc_bit(&s->rc, &s->lzma.is_match[ - s->lzma.state][pos_state])) { - lzma_literal(s); - } else { - if (rc_bit(&s->rc, &s->lzma.is_rep[s->lzma.state])) - lzma_rep_match(s, pos_state); - else - lzma_match(s, pos_state); - - if (!dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0)) - return false; - } - } - - /* - * Having the range decoder always normalized when we are outside - * this function makes it easier to correctly handle end of the chunk. - */ - rc_normalize(&s->rc); - - return true; -} - -/* - * Reset the LZMA decoder and range decoder state. Dictionary is nore reset - * here, because LZMA state may be reset without resetting the dictionary. - */ -static void lzma_reset(struct xz_dec_lzma2 *s) -{ - uint16_t *probs; - size_t i; - - s->lzma.state = STATE_LIT_LIT; - s->lzma.rep0 = 0; - s->lzma.rep1 = 0; - s->lzma.rep2 = 0; - s->lzma.rep3 = 0; - - /* - * All probabilities are initialized to the same value. This hack - * makes the code smaller by avoiding a separate loop for each - * probability array. - * - * This could be optimized so that only that part of literal - * probabilities that are actually required. In the common case - * we would write 12 KiB less. - */ - probs = s->lzma.is_match[0]; - for (i = 0; i < PROBS_TOTAL; ++i) - probs[i] = RC_BIT_MODEL_TOTAL / 2; - - rc_reset(&s->rc); -} - -/* - * Decode and validate LZMA properties (lc/lp/pb) and calculate the bit masks - * from the decoded lp and pb values. On success, the LZMA decoder state is - * reset and true is returned. - */ -static bool lzma_props(struct xz_dec_lzma2 *s, uint8_t props) -{ - if (props > (4 * 5 + 4) * 9 + 8) - return false; - - s->lzma.pos_mask = 0; - while (props >= 9 * 5) { - props -= 9 * 5; - ++s->lzma.pos_mask; - } - - s->lzma.pos_mask = (1 << s->lzma.pos_mask) - 1; - - s->lzma.literal_pos_mask = 0; - while (props >= 9) { - props -= 9; - ++s->lzma.literal_pos_mask; - } - - s->lzma.lc = props; - - if (s->lzma.lc + s->lzma.literal_pos_mask > 4) - return false; - - s->lzma.literal_pos_mask = (1 << s->lzma.literal_pos_mask) - 1; - - lzma_reset(s); - - return true; -} - -/********* - * LZMA2 * - *********/ - -/* - * The LZMA decoder assumes that if the input limit (s->rc.in_limit) hasn't - * been exceeded, it is safe to read up to LZMA_IN_REQUIRED bytes. This - * wrapper function takes care of making the LZMA decoder's assumption safe. - * - * As long as there is plenty of input left to be decoded in the current LZMA - * chunk, we decode directly from the caller-supplied input buffer until - * there's LZMA_IN_REQUIRED bytes left. Those remaining bytes are copied into - * s->temp.buf, which (hopefully) gets filled on the next call to this - * function. We decode a few bytes from the temporary buffer so that we can - * continue decoding from the caller-supplied input buffer again. - */ -static bool lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b) -{ - size_t in_avail; - uint32_t tmp; - - in_avail = b->in_size - b->in_pos; - if (s->temp.size > 0 || s->lzma2.compressed == 0) { - tmp = 2 * LZMA_IN_REQUIRED - s->temp.size; - if (tmp > s->lzma2.compressed - s->temp.size) - tmp = s->lzma2.compressed - s->temp.size; - if (tmp > in_avail) - tmp = in_avail; - - memcpy(s->temp.buf + s->temp.size, b->in + b->in_pos, tmp); - - if (s->temp.size + tmp == s->lzma2.compressed) { - memzero(s->temp.buf + s->temp.size + tmp, - sizeof(s->temp.buf) - - s->temp.size - tmp); - s->rc.in_limit = s->temp.size + tmp; - } else if (s->temp.size + tmp < LZMA_IN_REQUIRED) { - s->temp.size += tmp; - b->in_pos += tmp; - return true; - } else { - s->rc.in_limit = s->temp.size + tmp - LZMA_IN_REQUIRED; - } - - s->rc.in = s->temp.buf; - s->rc.in_pos = 0; - - if (!lzma_main(s) || s->rc.in_pos > s->temp.size + tmp) - return false; - - s->lzma2.compressed -= s->rc.in_pos; - - if (s->rc.in_pos < s->temp.size) { - s->temp.size -= s->rc.in_pos; - memmove(s->temp.buf, s->temp.buf + s->rc.in_pos, - s->temp.size); - return true; - } - - b->in_pos += s->rc.in_pos - s->temp.size; - s->temp.size = 0; - } - - in_avail = b->in_size - b->in_pos; - if (in_avail >= LZMA_IN_REQUIRED) { - s->rc.in = b->in; - s->rc.in_pos = b->in_pos; - - if (in_avail >= s->lzma2.compressed + LZMA_IN_REQUIRED) - s->rc.in_limit = b->in_pos + s->lzma2.compressed; - else - s->rc.in_limit = b->in_size - LZMA_IN_REQUIRED; - - if (!lzma_main(s)) - return false; - - in_avail = s->rc.in_pos - b->in_pos; - if (in_avail > s->lzma2.compressed) - return false; - - s->lzma2.compressed -= in_avail; - b->in_pos = s->rc.in_pos; - } - - in_avail = b->in_size - b->in_pos; - if (in_avail < LZMA_IN_REQUIRED) { - if (in_avail > s->lzma2.compressed) - in_avail = s->lzma2.compressed; - - memcpy(s->temp.buf, b->in + b->in_pos, in_avail); - s->temp.size = in_avail; - b->in_pos += in_avail; - } - - return true; -} - -/* - * Take care of the LZMA2 control layer, and forward the job of actual LZMA - * decoding or copying of uncompressed chunks to other functions. - */ -enum xz_ret xz_dec_lzma2_run( - struct xz_dec_lzma2 *s, struct xz_buf *b) -{ - uint32_t tmp; - - while (b->in_pos < b->in_size || s->lzma2.sequence == SEQ_LZMA_RUN) { - switch (s->lzma2.sequence) { - case SEQ_CONTROL: - /* - * LZMA2 control byte - * - * Exact values: - * 0x00 End marker - * 0x01 Dictionary reset followed by - * an uncompressed chunk - * 0x02 Uncompressed chunk (no dictionary reset) - * - * Highest three bits (s->control & 0xE0): - * 0xE0 Dictionary reset, new properties and state - * reset, followed by LZMA compressed chunk - * 0xC0 New properties and state reset, followed - * by LZMA compressed chunk (no dictionary - * reset) - * 0xA0 State reset using old properties, - * followed by LZMA compressed chunk (no - * dictionary reset) - * 0x80 LZMA chunk (no dictionary or state reset) - * - * For LZMA compressed chunks, the lowest five bits - * (s->control & 1F) are the highest bits of the - * uncompressed size (bits 16-20). - * - * A new LZMA2 stream must begin with a dictionary - * reset. The first LZMA chunk must set new - * properties and reset the LZMA state. - * - * Values that don't match anything described above - * are invalid and we return XZ_DATA_ERROR. - */ - tmp = b->in[b->in_pos++]; - - if (tmp >= 0xE0 || tmp == 0x01) { - s->lzma2.need_props = true; - s->lzma2.need_dict_reset = false; - dict_reset(&s->dict, b); - } else if (s->lzma2.need_dict_reset) { - return XZ_DATA_ERROR; - } - - if (tmp >= 0x80) { - s->lzma2.uncompressed = (tmp & 0x1F) << 16; - s->lzma2.sequence = SEQ_UNCOMPRESSED_1; - - if (tmp >= 0xC0) { - /* - * When there are new properties, - * state reset is done at - * SEQ_PROPERTIES. - */ - s->lzma2.need_props = false; - s->lzma2.next_sequence - = SEQ_PROPERTIES; - - } else if (s->lzma2.need_props) { - return XZ_DATA_ERROR; - - } else { - s->lzma2.next_sequence - = SEQ_LZMA_PREPARE; - if (tmp >= 0xA0) - lzma_reset(s); - } - } else { - if (tmp == 0x00) - return XZ_STREAM_END; - - if (tmp > 0x02) - return XZ_DATA_ERROR; - - s->lzma2.sequence = SEQ_COMPRESSED_0; - s->lzma2.next_sequence = SEQ_COPY; - } - - break; - - case SEQ_UNCOMPRESSED_1: - s->lzma2.uncompressed - += (uint32_t)b->in[b->in_pos++] << 8; - s->lzma2.sequence = SEQ_UNCOMPRESSED_2; - break; - - case SEQ_UNCOMPRESSED_2: - s->lzma2.uncompressed - += (uint32_t)b->in[b->in_pos++] + 1; - s->lzma2.sequence = SEQ_COMPRESSED_0; - break; - - case SEQ_COMPRESSED_0: - s->lzma2.compressed - = (uint32_t)b->in[b->in_pos++] << 8; - s->lzma2.sequence = SEQ_COMPRESSED_1; - break; - - case SEQ_COMPRESSED_1: - s->lzma2.compressed - += (uint32_t)b->in[b->in_pos++] + 1; - s->lzma2.sequence = s->lzma2.next_sequence; - break; - - case SEQ_PROPERTIES: - if (!lzma_props(s, b->in[b->in_pos++])) - return XZ_DATA_ERROR; - - s->lzma2.sequence = SEQ_LZMA_PREPARE; - - /* Fall through */ - - case SEQ_LZMA_PREPARE: - if (s->lzma2.compressed < RC_INIT_BYTES) - return XZ_DATA_ERROR; - - if (!rc_read_init(&s->rc, b)) - return XZ_OK; - - s->lzma2.compressed -= RC_INIT_BYTES; - s->lzma2.sequence = SEQ_LZMA_RUN; - - /* Fall through */ - - case SEQ_LZMA_RUN: - /* - * Set dictionary limit to indicate how much we want - * to be encoded at maximum. Decode new data into the - * dictionary. Flush the new data from dictionary to - * b->out. Check if we finished decoding this chunk. - * In case the dictionary got full but we didn't fill - * the output buffer yet, we may run this loop - * multiple times without changing s->lzma2.sequence. - */ - dict_limit(&s->dict, min_t(size_t, - b->out_size - b->out_pos, - s->lzma2.uncompressed)); - if (!lzma2_lzma(s, b)) - return XZ_DATA_ERROR; - - s->lzma2.uncompressed -= dict_flush(&s->dict, b); - - if (s->lzma2.uncompressed == 0) { - if (s->lzma2.compressed > 0 || s->lzma.len > 0 - || !rc_is_finished(&s->rc)) - return XZ_DATA_ERROR; - - rc_reset(&s->rc); - s->lzma2.sequence = SEQ_CONTROL; - - } else if (b->out_pos == b->out_size - || (b->in_pos == b->in_size - && s->temp.size - < s->lzma2.compressed)) { - return XZ_OK; - } - - break; - - case SEQ_COPY: - dict_uncompressed(&s->dict, b, &s->lzma2.compressed); - if (s->lzma2.compressed > 0) - return XZ_OK; - - s->lzma2.sequence = SEQ_CONTROL; - break; - } - } - - return XZ_OK; -} - -#ifdef GRUB_EMBED_DECOMPRESSOR -#include -static struct xz_dec_lzma2 lzma2; -#endif - -struct xz_dec_lzma2 * xz_dec_lzma2_create(uint32_t dict_max) -{ - struct xz_dec_lzma2 *s; - -#ifndef GRUB_EMBED_DECOMPRESSOR - /* Maximum supported dictionary by this implementation is 3 GiB. */ - if (dict_max > ((uint32_t)3 << 30)) - return NULL; - - s = kmalloc(sizeof(*s), GFP_KERNEL); - if (s == NULL) - return NULL; - - if (dict_max > 0) { - s->dict.buf = vmalloc(dict_max); - if (s->dict.buf == NULL) { - kfree(s); - return NULL; - } - } - -#else - s = &lzma2; - s->dict.buf = grub_decompressor_scratch; -#endif - - s->dict.allocated = dict_max; - - return s; -} - -enum xz_ret xz_dec_lzma2_reset( - struct xz_dec_lzma2 *s, uint8_t props) -{ - /* This limits dictionary size to 3 GiB (39) to keep parsing simpler. */ - if (props > ( min (DICT_BIT_SIZE,39)) ) - return XZ_OPTIONS_ERROR; - - s->dict.size = 2 + (props & 1); - s->dict.size <<= (props >> 1) + 11; - -#ifndef GRUB_EMBED_DECOMPRESSOR - if (s->dict.allocated > 0 && s->dict.allocated < s->dict.size) - { - /* enlarge dictionary buffer */ - uint8_t * newdict = realloc(s->dict.buf,s->dict.size); - - if (! newdict) - return XZ_MEMLIMIT_ERROR; - - s->dict.buf = newdict; - s->dict.allocated = s->dict.size; - } -#endif - s->dict.end = s->dict.size; - - s->lzma.len = 0; - - s->lzma2.sequence = SEQ_CONTROL; - s->lzma2.need_dict_reset = true; - - s->temp.size = 0; - - return XZ_OK; -} - -void xz_dec_lzma2_end(struct xz_dec_lzma2 *s __attribute__ ((unused))) -{ -#ifndef GRUB_EMBED_DECOMPRESSOR - if (s->dict.allocated > 0) - vfree(s->dict.buf); - - kfree(s); -#endif -} diff --git a/grub-core/lib/xzembed/xz_dec_stream.c b/grub-core/lib/xzembed/xz_dec_stream.c deleted file mode 100644 index 832d8af9a..000000000 --- a/grub-core/lib/xzembed/xz_dec_stream.c +++ /dev/null @@ -1,1042 +0,0 @@ -/* xz_dec_stream.c - .xz Stream decoder */ -/* - * 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 . - */ -/* - * This file is based on code from XZ embedded project - * http://tukaani.org/xz/embedded.html - */ - -#include "xz_config.h" -#include "xz_private.h" -#include "xz_stream.h" - -#include - -/* Hash used to validate the Index field */ -struct xz_dec_hash { - vli_type unpadded; - vli_type uncompressed; -#ifndef GRUB_EMBED_DECOMPRESSOR - uint64_t *hash_context; -#endif -}; - -/* Enough for up to 512 bits. */ -#define MAX_HASH_SIZE 64 - -struct xz_dec { - /* Position in dec_main() */ - enum { - SEQ_STREAM_HEADER, - SEQ_BLOCK_START, - SEQ_BLOCK_HEADER, - SEQ_BLOCK_UNCOMPRESS, - SEQ_BLOCK_PADDING, - SEQ_BLOCK_CHECK, - SEQ_INDEX, - SEQ_INDEX_PADDING, - SEQ_INDEX_CRC32, - SEQ_STREAM_FOOTER - } sequence; - - /* Position in variable-length integers and Check fields */ - uint32_t pos; - - /* Variable-length integer decoded by dec_vli() */ - vli_type vli; - - /* Saved in_pos and out_pos */ - size_t in_start; - size_t out_start; - - /* CRC32 value in Block or Index */ -#ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t hash_value[MAX_HASH_SIZE]; /* need for crc32_validate*/ -#endif - int have_hash_value; -#ifndef GRUB_EMBED_DECOMPRESSOR - uint64_t *hash_context; - uint64_t *crc32_context; -#endif - - /* Hash function calculated from uncompressed data */ -#ifndef GRUB_EMBED_DECOMPRESSOR - const gcry_md_spec_t *hash; - const gcry_md_spec_t *crc32; - grub_uint8_t hash_id; -#endif - grub_size_t hash_size; - - /* True if we are operating in single-call mode. */ - bool single_call; - - /* - * True if the next call to xz_dec_run() is allowed to return - * XZ_BUF_ERROR. - */ - bool allow_buf_error; - - /* Information stored in Block Header */ - struct { - /* - * Value stored in the Compressed Size field, or - * VLI_UNKNOWN if Compressed Size is not present. - */ - vli_type compressed; - - /* - * Value stored in the Uncompressed Size field, or - * VLI_UNKNOWN if Uncompressed Size is not present. - */ - vli_type uncompressed; - - /* Size of the Block Header field */ - uint32_t size; - } block_header; - - /* Information collected when decoding Blocks */ - struct { - /* Observed compressed size of the current Block */ - vli_type compressed; - - /* Observed uncompressed size of the current Block */ - vli_type uncompressed; - - /* Number of Blocks decoded so far */ - vli_type count; - - /* - * Hash calculated from the Block sizes. This is used to - * validate the Index field. - */ - struct xz_dec_hash hash; - } block; - - /* Variables needed when verifying the Index field */ - struct { - /* Position in dec_index() */ - enum { - SEQ_INDEX_COUNT, - SEQ_INDEX_UNPADDED, - SEQ_INDEX_UNCOMPRESSED - } sequence; - - /* Size of the Index in bytes */ - vli_type size; - - /* Number of Records (matches block.count in valid files) */ - vli_type count; - - /* - * Hash calculated from the Records (matches block.hash in - * valid files). - */ - struct xz_dec_hash hash; - } index; - - /* - * Temporary buffer needed to hold Stream Header, Block Header, - * and Stream Footer. The Block Header is the biggest (1 KiB) - * so we reserve space according to that. buf[] has to be aligned - * to a multiple of four bytes; the size_t variables before it - * should guarantee this. - */ - struct { - size_t pos; - size_t size; - uint8_t buf[1024]; - } temp; - - struct xz_dec_lzma2 *lzma2; - -#ifdef XZ_DEC_BCJ - struct xz_dec_bcj *bcj; - bool bcj_active; -#endif -}; - -/* - * Fill s->temp by copying data starting from b->in[b->in_pos]. Caller - * must have set s->temp.pos to indicate how much data we are supposed - * to copy into s->temp.buf. Return true once s->temp.pos has reached - * s->temp.size. - */ -static bool fill_temp(struct xz_dec *s, struct xz_buf *b) -{ - size_t copy_size = min_t(size_t, - b->in_size - b->in_pos, s->temp.size - s->temp.pos); - - memcpy(s->temp.buf + s->temp.pos, b->in + b->in_pos, copy_size); - b->in_pos += copy_size; - s->temp.pos += copy_size; - - if (s->temp.pos == s->temp.size) { - s->temp.pos = 0; - return true; - } - - return false; -} - -/* Decode a variable-length integer (little-endian base-128 encoding) */ -static enum xz_ret dec_vli(struct xz_dec *s, - const uint8_t *in, size_t *in_pos, size_t in_size) -{ - uint8_t b; - - if (s->pos == 0) - s->vli = 0; - - while (*in_pos < in_size) { - b = in[*in_pos]; - ++*in_pos; - - s->vli |= (vli_type)(b & 0x7F) << s->pos; - - if ((b & 0x80) == 0) { - /* Don't allow non-minimal encodings. */ - if (b == 0 && s->pos != 0) - return XZ_DATA_ERROR; - - s->pos = 0; - return XZ_STREAM_END; - } - - s->pos += 7; - if (s->pos == 7 * VLI_BYTES_MAX) - return XZ_DATA_ERROR; - } - - return XZ_OK; -} - -/* - * Decode the Compressed Data field from a Block. Update and validate - * the observed compressed and uncompressed sizes of the Block so that - * they don't exceed the values possibly stored in the Block Header - * (validation assumes that no integer overflow occurs, since vli_type - * is normally uint64_t). Update the CRC32 if presence of the CRC32 - * field was indicated in Stream Header. - * - * Once the decoding is finished, validate that the observed sizes match - * the sizes possibly stored in the Block Header. Update the hash and - * Block count, which are later used to validate the Index field. - */ -static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b) -{ - enum xz_ret ret; - - s->in_start = b->in_pos; - s->out_start = b->out_pos; - -#ifdef XZ_DEC_BCJ - if (s->bcj_active) - ret = xz_dec_bcj_run(s->bcj, s->lzma2, b); - else -#endif - ret = xz_dec_lzma2_run(s->lzma2, b); - - s->block.compressed += b->in_pos - s->in_start; - s->block.uncompressed += b->out_pos - s->out_start; - - /* - * There is no need to separately check for VLI_UNKNOWN, since - * the observed sizes are always smaller than VLI_UNKNOWN. - */ - if (s->block.compressed > s->block_header.compressed - || s->block.uncompressed - > s->block_header.uncompressed) - return XZ_DATA_ERROR; - -#ifndef GRUB_EMBED_DECOMPRESSOR - if (s->hash) - s->hash->write(s->hash_context,b->out + s->out_start, - b->out_pos - s->out_start); - if (s->crc32) - s->crc32->write(s->crc32_context,b->out + s->out_start, - b->out_pos - s->out_start); -#endif - - if (ret == XZ_STREAM_END) { - if (s->block_header.compressed != VLI_UNKNOWN - && s->block_header.compressed - != s->block.compressed) - return XZ_DATA_ERROR; - - if (s->block_header.uncompressed != VLI_UNKNOWN - && s->block_header.uncompressed - != s->block.uncompressed) - return XZ_DATA_ERROR; - - s->block.hash.unpadded += s->block_header.size - + s->block.compressed; - s->block.hash.unpadded += s->hash_size; - - s->block.hash.uncompressed += s->block.uncompressed; - -#ifndef GRUB_EMBED_DECOMPRESSOR - if (s->hash) - s->hash->write(s->block.hash.hash_context, - (const uint8_t *)&s->block.hash, - 2 * sizeof(vli_type)); -#endif - - ++s->block.count; - } - - return ret; -} - -/* Update the Index size and the CRC32 value. */ -static void index_update(struct xz_dec *s, const struct xz_buf *b) -{ - size_t in_used = b->in_pos - s->in_start; - s->index.size += in_used; -#ifndef GRUB_EMBED_DECOMPRESSOR - if (s->hash) - s->hash->write(s->hash_context,b->in + s->in_start, in_used); - if (s->crc32) - s->crc32->write(s->crc32_context,b->in + s->in_start, in_used); -#endif -} - -/* - * Decode the Number of Records, Unpadded Size, and Uncompressed Size - * fields from the Index field. That is, Index Padding and CRC32 are not - * decoded by this function. - * - * This can return XZ_OK (more input needed), XZ_STREAM_END (everything - * successfully decoded), or XZ_DATA_ERROR (input is corrupt). - */ -static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b) -{ - enum xz_ret ret; - - do { - ret = dec_vli(s, b->in, &b->in_pos, b->in_size); - if (ret != XZ_STREAM_END) { - index_update(s, b); - return ret; - } - - switch (s->index.sequence) { - case SEQ_INDEX_COUNT: - s->index.count = s->vli; - - /* - * Validate that the Number of Records field - * indicates the same number of Records as - * there were Blocks in the Stream. - */ - if (s->index.count != s->block.count) - return XZ_DATA_ERROR; - - s->index.sequence = SEQ_INDEX_UNPADDED; - break; - - case SEQ_INDEX_UNPADDED: - s->index.hash.unpadded += s->vli; - s->index.sequence = SEQ_INDEX_UNCOMPRESSED; - break; - - case SEQ_INDEX_UNCOMPRESSED: - s->index.hash.uncompressed += s->vli; - -#ifndef GRUB_EMBED_DECOMPRESSOR - if (s->hash) - s->hash->write(s->index.hash.hash_context, - (const uint8_t *)&s->index.hash, 2 * sizeof(vli_type)); -#endif - - --s->index.count; - s->index.sequence = SEQ_INDEX_UNPADDED; - break; - } - } while (s->index.count > 0); - - return XZ_STREAM_END; -} - -/* - * Validate that the next four input bytes match the value of s->crc32. - * s->pos must be zero when starting to validate the first byte. - */ -static enum xz_ret hash_validate(struct xz_dec *s, struct xz_buf *b, - int crc32) -{ -#ifndef GRUB_EMBED_DECOMPRESSOR - const gcry_md_spec_t *hash = crc32 ? s->crc32 : s->hash; - void *hash_context = crc32 ? s->crc32_context - : s->hash_context; - if(!s->have_hash_value && hash - && sizeof (s->hash_value) >= hash->mdlen) - { - hash->final(hash_context); - grub_memcpy (s->hash_value, hash->read(hash_context), - hash->mdlen); - s->have_hash_value = 1; - if (s->hash_id == 1 || crc32) - { - grub_uint8_t t; - t = s->hash_value[0]; - s->hash_value[0] = s->hash_value[3]; - s->hash_value[3] = t; - t = s->hash_value[1]; - s->hash_value[1] = s->hash_value[2]; - s->hash_value[2] = t; - } - } -#endif - - if (b->in_pos == b->in_size) - return XZ_OK; - - if (!crc32 && s->hash_size == 0) - s->pos += 8; - - while (s->pos < (crc32 ? 32 : s->hash_size * 8)) { - if (b->in_pos == b->in_size) - return XZ_OK; - -#ifndef GRUB_EMBED_DECOMPRESSOR - if (hash && s->hash_value[s->pos / 8] != b->in[b->in_pos]) - return XZ_DATA_ERROR; -#endif - b->in_pos++; - - s->pos += 8; - - } - -#ifndef GRUB_EMBED_DECOMPRESSOR - if (s->hash) - s->hash->init(s->hash_context); - if (s->crc32) - s->crc32->init(s->crc32_context); -#endif - s->have_hash_value = 0; - s->pos = 0; - - return XZ_STREAM_END; -} - -static const struct -{ - const char *name; - grub_size_t size; -} hashes[] = { - [0x01] = { "CRC32", 4}, - [0x04] = { "CRC64", 8}, - [0x0A] = { "SHA256", 32}, -}; - -/* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */ -static enum xz_ret dec_stream_header(struct xz_dec *s) -{ - if (! memeq(s->temp.buf, HEADER_MAGIC, HEADER_MAGIC_SIZE)) - return XZ_FORMAT_ERROR; - -#ifndef GRUB_EMBED_DECOMPRESSOR - s->crc32 = grub_crypto_lookup_md_by_name ("CRC32"); - - if (s->crc32) - { - uint8_t readhash[4]; - uint8_t computed_hash[4]; - - if(4 != s->crc32->mdlen) - return XZ_DATA_ERROR; - - grub_crypto_hash (s->crc32, computed_hash, - s->temp.buf + HEADER_MAGIC_SIZE, 2); - - readhash[0] = s->temp.buf[HEADER_MAGIC_SIZE + 5]; - readhash[1] = s->temp.buf[HEADER_MAGIC_SIZE + 4]; - readhash[2] = s->temp.buf[HEADER_MAGIC_SIZE + 3]; - readhash[3] = s->temp.buf[HEADER_MAGIC_SIZE + 2]; - - if (grub_memcmp (readhash, computed_hash, - s->crc32->mdlen) != 0) - return XZ_DATA_ERROR; - } -#endif - -#ifndef GRUB_EMBED_DECOMPRESSOR - /* - * Decode the Stream Flags field. - */ - if (s->temp.buf[HEADER_MAGIC_SIZE] != 0 - || s->temp.buf[HEADER_MAGIC_SIZE + 1] >= ARRAY_SIZE (hashes) - || (hashes[s->temp.buf[HEADER_MAGIC_SIZE + 1]].name == 0 - && s->temp.buf[HEADER_MAGIC_SIZE + 1] != 0)) - return XZ_OPTIONS_ERROR; - - s->hash_id = s->temp.buf[HEADER_MAGIC_SIZE + 1]; - - if (s->crc32) - { - s->crc32_context = kmalloc(s->crc32->contextsize, GFP_KERNEL); - if (s->crc32_context == NULL) - return XZ_MEMLIMIT_ERROR; - s->crc32->init(s->crc32_context); - } -#endif - - if (s->temp.buf[HEADER_MAGIC_SIZE + 1]) - { - s->hash_size = hashes[s->temp.buf[HEADER_MAGIC_SIZE + 1]].size; -#ifndef GRUB_EMBED_DECOMPRESSOR - s->hash = grub_crypto_lookup_md_by_name (hashes[s->temp.buf[HEADER_MAGIC_SIZE + 1]].name); - if (s->hash) - { - if (s->hash->mdlen != s->hash_size) - return XZ_OPTIONS_ERROR; - s->hash_context = kmalloc(s->hash->contextsize, GFP_KERNEL); - if (s->hash_context == NULL) - { - kfree(s->crc32_context); - return XZ_MEMLIMIT_ERROR; - } - - s->index.hash.hash_context = kmalloc(s->hash->contextsize, - GFP_KERNEL); - if (s->index.hash.hash_context == NULL) - { - kfree(s->hash_context); - kfree(s->crc32_context); - return XZ_MEMLIMIT_ERROR; - } - - s->block.hash.hash_context = kmalloc(s->hash->contextsize, GFP_KERNEL); - if (s->block.hash.hash_context == NULL) - { - kfree(s->index.hash.hash_context); - kfree(s->hash_context); - kfree(s->crc32_context); - return XZ_MEMLIMIT_ERROR; - } - - s->hash->init(s->hash_context); - s->hash->init(s->index.hash.hash_context); - s->hash->init(s->block.hash.hash_context); - } -#endif - } - else - { -#ifndef GRUB_EMBED_DECOMPRESSOR - s->hash = 0; -#endif - s->hash_size = 0; - } - - s->have_hash_value = 0; - - - return XZ_OK; -} - -/* Decode the Stream Footer field (the last 12 bytes of the .xz Stream) */ -static enum xz_ret dec_stream_footer(struct xz_dec *s) -{ - if (! memeq(s->temp.buf + 10, FOOTER_MAGIC, FOOTER_MAGIC_SIZE)) - return XZ_DATA_ERROR; - -#ifndef GRUB_EMBED_DECOMPRESSOR - if (s->crc32) - { - uint8_t readhash[4]; - uint8_t computed_hash[4]; - - if (4 != s->crc32->mdlen) - return XZ_DATA_ERROR; - - grub_crypto_hash (s->crc32, computed_hash, - s->temp.buf + 4, 6); - - readhash[0] = s->temp.buf[3]; - readhash[1] = s->temp.buf[2]; - readhash[2] = s->temp.buf[1]; - readhash[3] = s->temp.buf[0]; - - if(grub_memcmp (readhash, computed_hash, - s->crc32->mdlen) != 0) - return XZ_DATA_ERROR; - } -#endif - - - /* - * Validate Backward Size. Note that we never added the size of the - * Index CRC32 field to s->index.size, thus we use s->index.size / 4 - * instead of s->index.size / 4 - 1. - */ - if ((s->index.size >> 2) != get_le32(s->temp.buf + 4)) - return XZ_DATA_ERROR; - -#ifndef GRUB_EMBED_DECOMPRESSOR - if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->hash_id) - return XZ_DATA_ERROR; -#endif - - /* - * Use XZ_STREAM_END instead of XZ_OK to be more convenient - * for the caller. - */ - return XZ_STREAM_END; -} - -/* Decode the Block Header and initialize the filter chain. */ -static enum xz_ret dec_block_header(struct xz_dec *s) -{ - enum xz_ret ret; - - /* - * Validate the CRC32. We know that the temp buffer is at least - * eight bytes so this is safe. - */ - s->temp.size -= 4; -#ifndef GRUB_EMBED_DECOMPRESSOR - if (s->crc32) - { - uint8_t readhash[4], computed_hash[4]; - - if(4 != s->crc32->mdlen) - return XZ_DATA_ERROR; - - grub_crypto_hash (s->crc32, computed_hash, - s->temp.buf, s->temp.size); - - readhash[3] = s->temp.buf[s->temp.size]; - readhash[2] = s->temp.buf[s->temp.size + 1]; - readhash[1] = s->temp.buf[s->temp.size + 2]; - readhash[0] = s->temp.buf[s->temp.size + 3]; - - if(grub_memcmp (readhash, computed_hash, - s->crc32->mdlen) != 0) - return XZ_DATA_ERROR; - } -#endif - - s->temp.pos = 2; - - /* - * Catch unsupported Block Flags. We support only one or two filters - * in the chain, so we catch that with the same test. - */ -#ifdef XZ_DEC_BCJ - if (s->temp.buf[1] & 0x3E) -#else - if (s->temp.buf[1] & 0x3F) -#endif - return XZ_OPTIONS_ERROR; - - /* Compressed Size */ - if (s->temp.buf[1] & 0x40) { - if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size) - != XZ_STREAM_END) - return XZ_DATA_ERROR; - - s->block_header.compressed = s->vli; - } else { - s->block_header.compressed = VLI_UNKNOWN; - } - - /* Uncompressed Size */ - if (s->temp.buf[1] & 0x80) { - if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size) - != XZ_STREAM_END) - return XZ_DATA_ERROR; - - s->block_header.uncompressed = s->vli; - } else { - s->block_header.uncompressed = VLI_UNKNOWN; - } - -#ifdef XZ_DEC_BCJ - /* If there are two filters, the first one must be a BCJ filter. */ - s->bcj_active = s->temp.buf[1] & 0x01; - if (s->bcj_active) { - if (s->temp.size - s->temp.pos < 2) - return XZ_OPTIONS_ERROR; - - ret = xz_dec_bcj_reset(s->bcj, s->temp.buf[s->temp.pos++]); - if (ret != XZ_OK) - return ret; - - /* - * We don't support custom start offset, - * so Size of Properties must be zero. - */ - if (s->temp.buf[s->temp.pos++] != 0x00) - return XZ_OPTIONS_ERROR; - } -#endif - - /* Valid Filter Flags always take at least two bytes. */ - if (s->temp.size - s->temp.pos < 2) - return XZ_DATA_ERROR; - - /* Filter ID = LZMA2 */ - if (s->temp.buf[s->temp.pos++] != 0x21) - return XZ_OPTIONS_ERROR; - - /* Size of Properties = 1-byte Filter Properties */ - if (s->temp.buf[s->temp.pos++] != 0x01) - return XZ_OPTIONS_ERROR; - - /* Filter Properties contains LZMA2 dictionary size. */ - if (s->temp.size - s->temp.pos < 1) - return XZ_DATA_ERROR; - - ret = xz_dec_lzma2_reset(s->lzma2, s->temp.buf[s->temp.pos++]); - if (ret != XZ_OK) - return ret; - - /* The rest must be Header Padding. */ - while (s->temp.pos < s->temp.size) - if (s->temp.buf[s->temp.pos++] != 0x00) - return XZ_OPTIONS_ERROR; - - s->temp.pos = 0; - s->block.compressed = 0; - s->block.uncompressed = 0; - - return XZ_OK; -} - -static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) -{ - enum xz_ret ret; - - /* - * Store the start position for the case when we are in the middle - * of the Index field. - */ - s->in_start = b->in_pos; - - while (true) { - switch (s->sequence) { - case SEQ_STREAM_HEADER: - /* - * Stream Header is copied to s->temp, and then - * decoded from there. This way if the caller - * gives us only little input at a time, we can - * still keep the Stream Header decoding code - * simple. Similar approach is used in many places - * in this file. - */ - if (!fill_temp(s, b)) - return XZ_OK; - - ret = dec_stream_header(s); - if (ret != XZ_OK) - return ret; - - s->sequence = SEQ_BLOCK_START; - - /* FALLTHROUGH */ - case SEQ_BLOCK_START: - /* We need one byte of input to continue. */ - if (b->in_pos == b->in_size) - return XZ_OK; - - /* See if this is the beginning of the Index field. */ - if (b->in[b->in_pos] == 0) { - s->in_start = b->in_pos++; - s->sequence = SEQ_INDEX; - break; - } - - /* - * Calculate the size of the Block Header and - * prepare to decode it. - */ - s->block_header.size - = ((uint32_t)b->in[b->in_pos] + 1) * 4; - - s->temp.size = s->block_header.size; - s->temp.pos = 0; - s->sequence = SEQ_BLOCK_HEADER; - - /* FALLTHROUGH */ - case SEQ_BLOCK_HEADER: - if (!fill_temp(s, b)) - return XZ_OK; - - ret = dec_block_header(s); - if (ret != XZ_OK) - return ret; - - s->sequence = SEQ_BLOCK_UNCOMPRESS; - - /* FALLTHROUGH */ - case SEQ_BLOCK_UNCOMPRESS: - ret = dec_block(s, b); - if (ret != XZ_STREAM_END) - return ret; - - s->sequence = SEQ_BLOCK_PADDING; - - case SEQ_BLOCK_PADDING: - /* - * Size of Compressed Data + Block Padding - * must be a multiple of four. We don't need - * s->block.compressed for anything else - * anymore, so we use it here to test the size - * of the Block Padding field. - */ - while (s->block.compressed & 3) { - if (b->in_pos == b->in_size) - return XZ_OK; - - if (b->in[b->in_pos++] != 0) - return XZ_DATA_ERROR; - - ++s->block.compressed; - } - - s->sequence = SEQ_BLOCK_CHECK; - - /* FALLTHROUGH */ - case SEQ_BLOCK_CHECK: - ret = hash_validate(s, b, 0); - if (ret != XZ_STREAM_END) - return ret; - - s->sequence = SEQ_BLOCK_START; - break; - - case SEQ_INDEX: - ret = dec_index(s, b); - if (ret != XZ_STREAM_END) - return ret; - - s->sequence = SEQ_INDEX_PADDING; - - case SEQ_INDEX_PADDING: - while ((s->index.size + (b->in_pos - s->in_start)) - & 3) { - if (b->in_pos == b->in_size) { - index_update(s, b); - return XZ_OK; - } - - if (b->in[b->in_pos++] != 0) - return XZ_DATA_ERROR; - } - - /* Finish the CRC32 value and Index size. */ - index_update(s, b); - -#ifndef GRUB_EMBED_DECOMPRESSOR - if (s->hash) - { - /* Compare the hashes to validate the Index field. */ - s->hash->final(s->block.hash.hash_context); - s->hash->final(s->index.hash.hash_context); - - if (s->block.hash.unpadded != s->index.hash.unpadded - || s->block.hash.uncompressed != s->index.hash.uncompressed - || grub_memcmp (s->hash->read(s->block.hash.hash_context), - s->hash->read(s->index.hash.hash_context), - s->hash->mdlen) != 0) - return XZ_DATA_ERROR; - } -#endif - - s->sequence = SEQ_INDEX_CRC32; - - /* FALLTHROUGH */ - case SEQ_INDEX_CRC32: - ret = hash_validate(s, b, 1); - if (ret != XZ_STREAM_END) - return ret; - - s->temp.size = STREAM_HEADER_SIZE; - s->sequence = SEQ_STREAM_FOOTER; - - /* FALLTHROUGH */ - case SEQ_STREAM_FOOTER: - if (!fill_temp(s, b)) - return XZ_OK; - - return dec_stream_footer(s); - } - } - - /* Never reached */ -} - -/* - * xz_dec_run() is a wrapper for dec_main() to handle some special cases in - * multi-call and single-call decoding. - * - * In multi-call mode, we must return XZ_BUF_ERROR when it seems clear that we - * are not going to make any progress anymore. This is to prevent the caller - * from calling us infinitely when the input file is truncated or otherwise - * corrupt. Since zlib-style API allows that the caller fills the input buffer - * only when the decoder doesn't produce any new output, we have to be careful - * to avoid returning XZ_BUF_ERROR too easily: XZ_BUF_ERROR is returned only - * after the second consecutive call to xz_dec_run() that makes no progress. - * - * In single-call mode, if we couldn't decode everything and no error - * occurred, either the input is truncated or the output buffer is too small. - * Since we know that the last input byte never produces any output, we know - * that if all the input was consumed and decoding wasn't finished, the file - * must be corrupt. Otherwise the output buffer has to be too small or the - * file is corrupt in a way that decoding it produces too big output. - * - * If single-call decoding fails, we reset b->in_pos and b->out_pos back to - * their original values. This is because with some filter chains there won't - * be any valid uncompressed data in the output buffer unless the decoding - * actually succeeds (that's the price to pay of using the output buffer as - * the workspace). - */ -enum xz_ret xz_dec_run(struct xz_dec *s, struct xz_buf *b) -{ - size_t in_start; - size_t out_start; - enum xz_ret ret; - - if (s->single_call) - xz_dec_reset(s); - - in_start = b->in_pos; - out_start = b->out_pos; - ret = dec_main(s, b); - - if (s->single_call) { - if (ret == XZ_OK) - ret = b->in_pos == b->in_size - ? XZ_DATA_ERROR : XZ_BUF_ERROR; - - if (ret != XZ_STREAM_END) { - b->in_pos = in_start; - b->out_pos = out_start; - } - - } else if (ret == XZ_OK && in_start == b->in_pos - && out_start == b->out_pos) { - if (s->allow_buf_error) - ret = XZ_BUF_ERROR; - - s->allow_buf_error = true; - } else { - s->allow_buf_error = false; - } - - return ret; -} - -#ifdef GRUB_EMBED_DECOMPRESSOR -struct xz_dec decoder; -#endif - -struct xz_dec * xz_dec_init(uint32_t dict_max) -{ - struct xz_dec *s; -#ifdef GRUB_EMBED_DECOMPRESSOR - s = &decoder; -#else - s = kmalloc(sizeof(*s), GFP_KERNEL); - if (s == NULL) - return NULL; -#endif - - memset (s, 0, sizeof (*s)); - - s->single_call = dict_max == 0; - -#ifdef XZ_DEC_BCJ - s->bcj = xz_dec_bcj_create(s->single_call); - if (s->bcj == NULL) - goto error_bcj; -#endif - - s->lzma2 = xz_dec_lzma2_create(dict_max); - if (s->lzma2 == NULL) - goto error_lzma2; - - xz_dec_reset(s); - return s; - -error_lzma2: -#ifdef XZ_DEC_BCJ - xz_dec_bcj_end(s->bcj); -error_bcj: -#endif -#ifndef GRUB_EMBED_DECOMPRESSOR - kfree(s); -#endif - return NULL; -} - -void xz_dec_reset(struct xz_dec *s) -{ - s->sequence = SEQ_STREAM_HEADER; - s->allow_buf_error = false; - s->pos = 0; - - { -#ifndef GRUB_EMBED_DECOMPRESSOR - uint64_t *t; - t = s->block.hash.hash_context; -#endif - memzero(&s->block, sizeof(s->block)); -#ifndef GRUB_EMBED_DECOMPRESSOR - s->block.hash.hash_context = t; - t = s->index.hash.hash_context; -#endif - memzero(&s->index, sizeof(s->index)); -#ifndef GRUB_EMBED_DECOMPRESSOR - s->index.hash.hash_context = t; -#endif - } - s->temp.pos = 0; - s->temp.size = STREAM_HEADER_SIZE; - -#ifndef GRUB_EMBED_DECOMPRESSOR - if (s->hash) - { - s->hash->init(s->hash_context); - s->hash->init(s->index.hash.hash_context); - s->hash->init(s->block.hash.hash_context); - } -#endif - s->have_hash_value = 0; -} - -void xz_dec_end(struct xz_dec *s) -{ - if (s != NULL) { - xz_dec_lzma2_end(s->lzma2); -#ifndef GRUB_EMBED_DECOMPRESSOR - kfree(s->index.hash.hash_context); - kfree(s->block.hash.hash_context); - kfree(s->hash_context); - kfree(s->crc32_context); -#endif -#ifdef XZ_DEC_BCJ - xz_dec_bcj_end(s->bcj); -#endif -#ifndef GRUB_EMBED_DECOMPRESSOR - kfree(s); -#endif - } -} diff --git a/grub-core/lib/xzembed/xz_lzma2.h b/grub-core/lib/xzembed/xz_lzma2.h deleted file mode 100644 index 15e553dc0..000000000 --- a/grub-core/lib/xzembed/xz_lzma2.h +++ /dev/null @@ -1,236 +0,0 @@ -/* xz_lzma2.h - LZMA2 definitions */ -/* - * 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 . - */ -/* - * This file is based on code from XZ embedded project - * http://tukaani.org/xz/embedded.html - */ - -#ifndef XZ_LZMA2_H -#define XZ_LZMA2_H - -/* dictionary size hard limit - * actual size limit is calculated as shown in 5.3.1 - * http://tukaani.org/xz/xz-file-format.txt - * - * if bits > 39 dictionary_size = UINT32_MAX - * else - * dictionary_size = 2 | (bits & 1); - * dictionary_size <<= bits / 2 + 11; - * - * i.e. - * 0 - 4 KiB - * 6 - 32 KiB - * 30 - 128MiB - * 39 - 3072 MiB - * 40 - 4096 MiB - 1 B - * note: implementation supports 39 at maximum - */ -#define DICT_BIT_SIZE 30 - -/* Range coder constants */ -#define RC_SHIFT_BITS 8 -#define RC_TOP_BITS 24 -#define RC_TOP_VALUE (1 << RC_TOP_BITS) -#define RC_BIT_MODEL_TOTAL_BITS 11 -#define RC_BIT_MODEL_TOTAL (1 << RC_BIT_MODEL_TOTAL_BITS) -#define RC_MOVE_BITS 5 - -/* - * Maximum number of position states. A position state is the lowest pb - * number of bits of the current uncompressed offset. In some places there - * are different sets of probabilities for different position states. - */ -#define POS_STATES_MAX (1 << 4) - -/* - * This enum is used to track which LZMA symbols have occurred most recently - * and in which order. This information is used to predict the next symbol. - * - * Symbols: - * - Literal: One 8-bit byte - * - Match: Repeat a chunk of data at some distance - * - Long repeat: Multi-byte match at a recently seen distance - * - Short repeat: One-byte repeat at a recently seen distance - * - * The symbol names are in from STATE_oldest_older_previous. REP means - * either short or long repeated match, and NONLIT means any non-literal. - */ -enum lzma_state { - STATE_LIT_LIT, - STATE_MATCH_LIT_LIT, - STATE_REP_LIT_LIT, - STATE_SHORTREP_LIT_LIT, - STATE_MATCH_LIT, - STATE_REP_LIT, - STATE_SHORTREP_LIT, - STATE_LIT_MATCH, - STATE_LIT_LONGREP, - STATE_LIT_SHORTREP, - STATE_NONLIT_MATCH, - STATE_NONLIT_REP -}; - -/* Total number of states */ -#define STATES 12 - -/* The lowest 7 states indicate that the previous state was a literal. */ -#define LIT_STATES 7 - -/* Indicate that the latest symbol was a literal. */ -static inline void lzma_state_literal(enum lzma_state *state) -{ - if (*state <= STATE_SHORTREP_LIT_LIT) - *state = STATE_LIT_LIT; - else if (*state <= STATE_LIT_SHORTREP) - *state -= 3; - else - *state -= 6; -} - -/* Indicate that the latest symbol was a match. */ -static inline void lzma_state_match(enum lzma_state *state) -{ - *state = *state < LIT_STATES ? STATE_LIT_MATCH : STATE_NONLIT_MATCH; -} - -/* Indicate that the latest state was a long repeated match. */ -static inline void lzma_state_long_rep(enum lzma_state *state) -{ - *state = *state < LIT_STATES ? STATE_LIT_LONGREP : STATE_NONLIT_REP; -} - -/* Indicate that the latest symbol was a short match. */ -static inline void lzma_state_short_rep(enum lzma_state *state) -{ - *state = *state < LIT_STATES ? STATE_LIT_SHORTREP : STATE_NONLIT_REP; -} - -/* Test if the previous symbol was a literal. */ -static inline bool lzma_state_is_literal(enum lzma_state state) -{ - return state < LIT_STATES; -} - -/* Each literal coder is divided in three sections: - * - 0x001-0x0FF: Without match byte - * - 0x101-0x1FF: With match byte; match bit is 0 - * - 0x201-0x2FF: With match byte; match bit is 1 - * - * Match byte is used when the previous LZMA symbol was something else than - * a literal (that is, it was some kind of match). - */ -#define LITERAL_CODER_SIZE 0x300 - -/* Maximum number of literal coders */ -#define LITERAL_CODERS_MAX (1 << 4) - -/* Minimum length of a match is two bytes. */ -#define MATCH_LEN_MIN 2 - -/* Match length is encoded with 4, 5, or 10 bits. - * - * Length Bits - * 2-9 4 = Choice=0 + 3 bits - * 10-17 5 = Choice=1 + Choice2=0 + 3 bits - * 18-273 10 = Choice=1 + Choice2=1 + 8 bits - */ -#define LEN_LOW_BITS 3 -#define LEN_LOW_SYMBOLS (1 << LEN_LOW_BITS) -#define LEN_MID_BITS 3 -#define LEN_MID_SYMBOLS (1 << LEN_MID_BITS) -#define LEN_HIGH_BITS 8 -#define LEN_HIGH_SYMBOLS (1 << LEN_HIGH_BITS) -#define LEN_SYMBOLS (LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS + LEN_HIGH_SYMBOLS) - -/* - * Maximum length of a match is 273 which is a result of the encoding - * described above. - */ -#define MATCH_LEN_MAX (MATCH_LEN_MIN + LEN_SYMBOLS - 1) - -/* - * Different sets of probabilities are used for match distances that have - * very short match length: Lengths of 2, 3, and 4 bytes have a separate - * set of probabilities for each length. The matches with longer length - * use a shared set of probabilities. - */ -#define DIST_STATES 4 - -/* - * Get the index of the appropriate probability array for decoding - * the distance slot. - */ -static inline uint32_t lzma_get_dist_state(uint32_t len) -{ - return len < DIST_STATES + MATCH_LEN_MIN - ? len - MATCH_LEN_MIN : DIST_STATES - 1; -} - -/* - * The highest two bits of a 32-bit match distance are encoded using six bits. - * This six-bit value is called a distance slot. This way encoding a 32-bit - * value takes 6-36 bits, larger values taking more bits. - */ -#define DIST_SLOT_BITS 6 -#define DIST_SLOTS (1 << DIST_SLOT_BITS) - -/* Match distances up to 127 are fully encoded using probabilities. Since - * the highest two bits (distance slot) are always encoded using six bits, - * the distances 0-3 don't need any additional bits to encode, since the - * distance slot itself is the same as the actual distance. DIST_MODEL_START - * indicates the first distance slot where at least one additional bit is - * needed. - */ -#define DIST_MODEL_START 4 - -/* - * Match distances greater than 127 are encoded in three pieces: - * - distance slot: the highest two bits - * - direct bits: 2-26 bits below the highest two bits - * - alignment bits: four lowest bits - * - * Direct bits don't use any probabilities. - * - * The distance slot value of 14 is for distances 128-191. - */ -#define DIST_MODEL_END 14 - -/* Distance slots that indicate a distance <= 127. */ -#define FULL_DISTANCES_BITS (DIST_MODEL_END / 2) -#define FULL_DISTANCES (1 << FULL_DISTANCES_BITS) - -/* - * For match distances greater than 127, only the highest two bits and the - * lowest four bits (alignment) is encoded using probabilities. - */ -#define ALIGN_BITS 4 -#define ALIGN_SIZE (1 << ALIGN_BITS) -#define ALIGN_MASK (ALIGN_SIZE - 1) - -/* Total number of all probability variables */ -#define PROBS_TOTAL (1846 + LITERAL_CODERS_MAX * LITERAL_CODER_SIZE) - -/* - * LZMA remembers the four most recent match distances. Reusing these - * distances tends to take less space than re-encoding the actual - * distance value. - */ -#define REPS 4 - -#endif diff --git a/grub-core/lib/xzembed/xz_private.h b/grub-core/lib/xzembed/xz_private.h deleted file mode 100644 index fc845c92d..000000000 --- a/grub-core/lib/xzembed/xz_private.h +++ /dev/null @@ -1,96 +0,0 @@ -/* xz_private.h - Private includes and definitions */ -/* - * 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 . - */ -/* - * This file is based on code from XZ embedded project - * http://tukaani.org/xz/embedded.html - */ - -#ifndef XZ_PRIVATE_H -#define XZ_PRIVATE_H - -/* - * For userspace builds, use a separate header to define the required - * macros and functions. This makes it easier to adapt the code into - * different environments and avoids clutter in the Linux kernel tree. - */ -#include "xz_config.h" - -/* - * If any of the BCJ filter decoders are wanted, define XZ_DEC_BCJ. - * XZ_DEC_BCJ is used to enable generic support for BCJ decoders. - */ -#ifndef XZ_DEC_BCJ -# if defined(XZ_DEC_X86) || defined(XZ_DEC_POWERPC) \ - || defined(XZ_DEC_IA64) || defined(XZ_DEC_ARM) \ - || defined(XZ_DEC_ARM) || defined(XZ_DEC_ARMTHUMB) \ - || defined(XZ_DEC_SPARC) -# define XZ_DEC_BCJ -# endif -#endif - -/* - * Allocate memory for LZMA2 decoder. xz_dec_lzma2_reset() must be used - * before calling xz_dec_lzma2_run(). - */ -struct xz_dec_lzma2 * xz_dec_lzma2_create( - uint32_t dict_max); - -/* - * Decode the LZMA2 properties (one byte) and reset the decoder. Return - * XZ_OK on success, XZ_MEMLIMIT_ERROR if the preallocated dictionary is not - * big enough, and XZ_OPTIONS_ERROR if props indicates something that this - * decoder doesn't support. - */ -enum xz_ret xz_dec_lzma2_reset( - struct xz_dec_lzma2 *s, uint8_t props); - -/* Decode raw LZMA2 stream from b->in to b->out. */ -enum xz_ret xz_dec_lzma2_run( - struct xz_dec_lzma2 *s, struct xz_buf *b); - -/* Free the memory allocated for the LZMA2 decoder. */ -void xz_dec_lzma2_end(struct xz_dec_lzma2 *s); - -/* - * Allocate memory for BCJ decoders. xz_dec_bcj_reset() must be used before - * calling xz_dec_bcj_run(). - */ -struct xz_dec_bcj * xz_dec_bcj_create(bool single_call); - -/* - * Decode the Filter ID of a BCJ filter. This implementation doesn't - * support custom start offsets, so no decoding of Filter Properties - * is needed. Returns XZ_OK if the given Filter ID is supported. - * Otherwise XZ_OPTIONS_ERROR is returned. - */ -enum xz_ret xz_dec_bcj_reset( - struct xz_dec_bcj *s, uint8_t id); - -/* - * Decode raw BCJ + LZMA2 stream. This must be used only if there actually is - * a BCJ filter in the chain. If the chain has only LZMA2, xz_dec_lzma2_run() - * must be called directly. - */ -enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, - struct xz_dec_lzma2 *lzma2, struct xz_buf *b); - -/* Free the memory allocated for the BCJ filters. */ -#define xz_dec_bcj_end(s) kfree(s) - -#endif diff --git a/grub-core/lib/xzembed/xz_stream.h b/grub-core/lib/xzembed/xz_stream.h deleted file mode 100644 index f58397a15..000000000 --- a/grub-core/lib/xzembed/xz_stream.h +++ /dev/null @@ -1,53 +0,0 @@ -/* xz_stream.h - Definitions for handling the .xz file format */ -/* - * 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 . - */ -/* - * This file is based on code from XZ embedded project - * http://tukaani.org/xz/embedded.html - */ - -#ifndef XZ_STREAM_H -#define XZ_STREAM_H - -/* - * See the .xz file format specification at - * http://tukaani.org/xz/xz-file-format.txt - * to understand the container format. - */ - -#define STREAM_HEADER_SIZE 12 - -#define HEADER_MAGIC "\3757zXZ\0" -#define HEADER_MAGIC_SIZE 6 - -#define FOOTER_MAGIC "YZ" -#define FOOTER_MAGIC_SIZE 2 - -/* - * Variable-length integer can hold a 63-bit unsigned integer, or a special - * value to indicate that the value is unknown. - */ -typedef uint64_t vli_type; - -#define VLI_MAX ((vli_type)-1 / 2) -#define VLI_UNKNOWN ((vli_type)-1) - -/* Maximum encoded size of a VLI */ -#define VLI_BYTES_MAX (sizeof(vli_type) * 8 / 7) - -#endif diff --git a/grub-core/lib/zstd/bitstream.h b/grub-core/lib/zstd/bitstream.h deleted file mode 100644 index 2f91460c5..000000000 --- a/grub-core/lib/zstd/bitstream.h +++ /dev/null @@ -1,458 +0,0 @@ -/* ****************************************************************** - bitstream - Part of FSE library - Copyright (C) 2013-present, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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 COPYRIGHT HOLDERS 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 COPYRIGHT - OWNER 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. - - You can contact the author at : - - Source repository : https://github.com/Cyan4973/FiniteStateEntropy -****************************************************************** */ -#ifndef BITSTREAM_H_MODULE -#define BITSTREAM_H_MODULE - -#if defined (__cplusplus) -extern "C" { -#endif - -/* -* This API consists of small unitary functions, which must be inlined for best performance. -* Since link-time-optimization is not available for all compilers, -* these functions are defined into a .h to be included. -*/ - -/*-**************************************** -* Dependencies -******************************************/ -#include "mem.h" /* unaligned access routines */ -#include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */ -#include "error_private.h" /* error codes and messages */ - - -/*========================================= -* Target specific -=========================================*/ -#if defined(__BMI__) && defined(__GNUC__) -# include /* support for bextr (experimental) */ -#endif - -#define STREAM_ACCUMULATOR_MIN_32 25 -#define STREAM_ACCUMULATOR_MIN_64 57 -#define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64)) - - -/*-****************************************** -* bitStream encoding API (write forward) -********************************************/ -/* bitStream can mix input from multiple sources. - * A critical property of these streams is that they encode and decode in **reverse** direction. - * So the first bit sequence you add will be the last to be read, like a LIFO stack. - */ -typedef struct { - size_t bitContainer; - unsigned bitPos; - char* startPtr; - char* ptr; - char* endPtr; -} BIT_CStream_t; - -MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity); -MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits); -MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC); -MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC); - -/* Start with initCStream, providing the size of buffer to write into. -* bitStream will never write outside of this buffer. -* `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code. -* -* bits are first added to a local register. -* Local register is size_t, hence 64-bits on 64-bits systems, or 32-bits on 32-bits systems. -* Writing data into memory is an explicit operation, performed by the flushBits function. -* Hence keep track how many bits are potentially stored into local register to avoid register overflow. -* After a flushBits, a maximum of 7 bits might still be stored into local register. -* -* Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers. -* -* Last operation is to close the bitStream. -* The function returns the final size of CStream in bytes. -* If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable) -*/ - - -/*-******************************************** -* bitStream decoding API (read backward) -**********************************************/ -typedef struct { - size_t bitContainer; - unsigned bitsConsumed; - const char* ptr; - const char* start; - const char* limitPtr; -} BIT_DStream_t; - -typedef enum { BIT_DStream_unfinished = 0, - BIT_DStream_endOfBuffer = 1, - BIT_DStream_completed = 2, - BIT_DStream_overflow = 3 } BIT_DStream_status; /* result of BIT_reloadDStream() */ - /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */ - -MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize); -MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits); -MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD); -MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD); - - -/* Start by invoking BIT_initDStream(). -* A chunk of the bitStream is then stored into a local register. -* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t). -* You can then retrieve bitFields stored into the local register, **in reverse order**. -* Local register is explicitly reloaded from memory by the BIT_reloadDStream() method. -* A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished. -* Otherwise, it can be less than that, so proceed accordingly. -* Checking if DStream has reached its end can be performed with BIT_endOfDStream(). -*/ - - -/*-**************************************** -* unsafe API -******************************************/ -MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits); -/* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */ - -MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC); -/* unsafe version; does not check buffer overflow */ - -MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits); -/* faster, but works only if nbBits >= 1 */ - - - -/*-************************************************************** -* Internal functions -****************************************************************/ -MEM_STATIC unsigned BIT_highbit32 (U32 val) -{ - assert(val != 0); - { -# if defined(_MSC_VER) /* Visual */ - unsigned long r=0; - _BitScanReverse ( &r, val ); - return (unsigned) r; -# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ - return 31 - __builtin_clz (val); -# else /* Software version */ - static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, - 11, 14, 16, 18, 22, 25, 3, 30, - 8, 12, 20, 28, 15, 17, 24, 7, - 19, 27, 23, 6, 26, 5, 4, 31 }; - U32 v = val; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27]; -# endif - } -} - -/*===== Local Constants =====*/ -static const unsigned BIT_mask[] = { - 0, 1, 3, 7, 0xF, 0x1F, - 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, - 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, - 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, - 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF, - 0x3FFFFFFF, 0x7FFFFFFF}; /* up to 31 bits */ -#define BIT_MASK_SIZE (sizeof(BIT_mask) / sizeof(BIT_mask[0])) - -/*-************************************************************** -* bitStream encoding -****************************************************************/ -/*! BIT_initCStream() : - * `dstCapacity` must be > sizeof(size_t) - * @return : 0 if success, - * otherwise an error code (can be tested using ERR_isError()) */ -MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, - void* startPtr, size_t dstCapacity) -{ - bitC->bitContainer = 0; - bitC->bitPos = 0; - bitC->startPtr = (char*)startPtr; - bitC->ptr = bitC->startPtr; - bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer); - if (dstCapacity <= sizeof(bitC->bitContainer)) return ERROR(dstSize_tooSmall); - return 0; -} - -/*! BIT_addBits() : - * can add up to 31 bits into `bitC`. - * Note : does not check for register overflow ! */ -MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, - size_t value, unsigned nbBits) -{ - MEM_STATIC_ASSERT(BIT_MASK_SIZE == 32); - assert(nbBits < BIT_MASK_SIZE); - assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); - bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos; - bitC->bitPos += nbBits; -} - -/*! BIT_addBitsFast() : - * works only if `value` is _clean_, - * meaning all high bits above nbBits are 0 */ -MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, - size_t value, unsigned nbBits) -{ - assert((value>>nbBits) == 0); - assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); - bitC->bitContainer |= value << bitC->bitPos; - bitC->bitPos += nbBits; -} - -/*! BIT_flushBitsFast() : - * assumption : bitContainer has not overflowed - * unsafe version; does not check buffer overflow */ -MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC) -{ - size_t const nbBytes = bitC->bitPos >> 3; - assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8); - MEM_writeLEST(bitC->ptr, bitC->bitContainer); - bitC->ptr += nbBytes; - assert(bitC->ptr <= bitC->endPtr); - bitC->bitPos &= 7; - bitC->bitContainer >>= nbBytes*8; -} - -/*! BIT_flushBits() : - * assumption : bitContainer has not overflowed - * safe version; check for buffer overflow, and prevents it. - * note : does not signal buffer overflow. - * overflow will be revealed later on using BIT_closeCStream() */ -MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC) -{ - size_t const nbBytes = bitC->bitPos >> 3; - assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8); - MEM_writeLEST(bitC->ptr, bitC->bitContainer); - bitC->ptr += nbBytes; - if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr; - bitC->bitPos &= 7; - bitC->bitContainer >>= nbBytes*8; -} - -/*! BIT_closeCStream() : - * @return : size of CStream, in bytes, - * or 0 if it could not fit into dstBuffer */ -MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC) -{ - BIT_addBitsFast(bitC, 1, 1); /* endMark */ - BIT_flushBits(bitC); - if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */ - return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0); -} - - -/*-******************************************************** -* bitStream decoding -**********************************************************/ -/*! BIT_initDStream() : - * Initialize a BIT_DStream_t. - * `bitD` : a pointer to an already allocated BIT_DStream_t structure. - * `srcSize` must be the *exact* size of the bitStream, in bytes. - * @return : size of stream (== srcSize), or an errorCode if a problem is detected - */ -MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize) -{ - if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); } - - bitD->start = (const char*)srcBuffer; - bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer); - - if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */ - bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer); - bitD->bitContainer = MEM_readLEST(bitD->ptr); - { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; - bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */ - if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ } - } else { - bitD->ptr = bitD->start; - bitD->bitContainer = *(const BYTE*)(bitD->start); - switch(srcSize) - { - case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16); - /* fall-through */ - - case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24); - /* fall-through */ - - case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32); - /* fall-through */ - - case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24; - /* fall-through */ - - case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16; - /* fall-through */ - - case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8; - /* fall-through */ - - default: break; - } - { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; - bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; - if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */ - } - bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8; - } - - return srcSize; -} - -MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start) -{ - return bitContainer >> start; -} - -MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits) -{ -#if defined(__BMI__) && defined(__GNUC__) && __GNUC__*1000+__GNUC_MINOR__ >= 4008 /* experimental */ -# if defined(__x86_64__) - if (sizeof(bitContainer)==8) - return _bextr_u64(bitContainer, start, nbBits); - else -# endif - return _bextr_u32(bitContainer, start, nbBits); -#else - assert(nbBits < BIT_MASK_SIZE); - return (bitContainer >> start) & BIT_mask[nbBits]; -#endif -} - -MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) -{ - assert(nbBits < BIT_MASK_SIZE); - return bitContainer & BIT_mask[nbBits]; -} - -/*! BIT_lookBits() : - * Provides next n bits from local register. - * local register is not modified. - * On 32-bits, maxNbBits==24. - * On 64-bits, maxNbBits==56. - * @return : value extracted */ -MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits) -{ -#if defined(__BMI__) && defined(__GNUC__) /* experimental; fails if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8 */ - return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits); -#else - U32 const regMask = sizeof(bitD->bitContainer)*8 - 1; - return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask); -#endif -} - -/*! BIT_lookBitsFast() : - * unsafe version; only works if nbBits >= 1 */ -MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits) -{ - U32 const regMask = sizeof(bitD->bitContainer)*8 - 1; - assert(nbBits >= 1); - return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask); -} - -MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) -{ - bitD->bitsConsumed += nbBits; -} - -/*! BIT_readBits() : - * Read (consume) next n bits from local register and update. - * Pay attention to not read more than nbBits contained into local register. - * @return : extracted value. */ -MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits) -{ - size_t const value = BIT_lookBits(bitD, nbBits); - BIT_skipBits(bitD, nbBits); - return value; -} - -/*! BIT_readBitsFast() : - * unsafe version; only works only if nbBits >= 1 */ -MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits) -{ - size_t const value = BIT_lookBitsFast(bitD, nbBits); - assert(nbBits >= 1); - BIT_skipBits(bitD, nbBits); - return value; -} - -/*! BIT_reloadDStream() : - * Refill `bitD` from buffer previously set in BIT_initDStream() . - * This function is safe, it guarantees it will not read beyond src buffer. - * @return : status of `BIT_DStream_t` internal register. - * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */ -MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD) -{ - if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */ - return BIT_DStream_overflow; - - if (bitD->ptr >= bitD->limitPtr) { - bitD->ptr -= bitD->bitsConsumed >> 3; - bitD->bitsConsumed &= 7; - bitD->bitContainer = MEM_readLEST(bitD->ptr); - return BIT_DStream_unfinished; - } - if (bitD->ptr == bitD->start) { - if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer; - return BIT_DStream_completed; - } - /* start < ptr < limitPtr */ - { U32 nbBytes = bitD->bitsConsumed >> 3; - BIT_DStream_status result = BIT_DStream_unfinished; - if (bitD->ptr - nbBytes < bitD->start) { - nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */ - result = BIT_DStream_endOfBuffer; - } - bitD->ptr -= nbBytes; - bitD->bitsConsumed -= nbBytes*8; - bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD->bitContainer), otherwise bitD->ptr == bitD->start */ - return result; - } -} - -/*! BIT_endOfDStream() : - * @return : 1 if DStream has _exactly_ reached its end (all bits consumed). - */ -MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream) -{ - return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8)); -} - -#if defined (__cplusplus) -} -#endif - -#endif /* BITSTREAM_H_MODULE */ diff --git a/grub-core/lib/zstd/compiler.h b/grub-core/lib/zstd/compiler.h deleted file mode 100644 index 07f875e4d..000000000 --- a/grub-core/lib/zstd/compiler.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ - -#ifndef ZSTD_COMPILER_H -#define ZSTD_COMPILER_H - -/*-******************************************************* -* Compiler specifics -*********************************************************/ -/* force inlining */ -#if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ -# define INLINE_KEYWORD inline -#else -# define INLINE_KEYWORD -#endif - -#if defined(__GNUC__) -# define FORCE_INLINE_ATTR __attribute__((always_inline)) -#elif defined(_MSC_VER) -# define FORCE_INLINE_ATTR __forceinline -#else -# define FORCE_INLINE_ATTR -#endif - -/** - * FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant - * parameters. They must be inlined for the compiler to elimininate the constant - * branches. - */ -#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR -/** - * HINT_INLINE is used to help the compiler generate better code. It is *not* - * used for "templates", so it can be tweaked based on the compilers - * performance. - * - * gcc-4.8 and gcc-4.9 have been shown to benefit from leaving off the - * always_inline attribute. - * - * clang up to 5.0.0 (trunk) benefit tremendously from the always_inline - * attribute. - */ -#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5 -# define HINT_INLINE static INLINE_KEYWORD -#else -# define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR -#endif - -/* force no inlining */ -#ifdef _MSC_VER -# define FORCE_NOINLINE static __declspec(noinline) -#else -# ifdef __GNUC__ -# define FORCE_NOINLINE static __attribute__((__noinline__)) -# else -# define FORCE_NOINLINE static -# endif -#endif - -/* target attribute */ -#ifndef __has_attribute - #define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ -#endif -#if defined(__GNUC__) -# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target))) -#else -# define TARGET_ATTRIBUTE(target) -#endif - -/* Enable runtime BMI2 dispatch based on the CPU. - * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default. - */ -#ifndef DYNAMIC_BMI2 - #if ((defined(__clang__) && __has_attribute(__target__)) \ - || (defined(__GNUC__) \ - && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \ - && (defined(__x86_64__) || defined(_M_X86)) \ - && !defined(__BMI2__) - # define DYNAMIC_BMI2 1 - #else - # define DYNAMIC_BMI2 0 - #endif -#endif - -/* prefetch - * can be disabled, by declaring NO_PREFETCH macro - * All prefetch invocations use a single default locality 2, - * generating instruction prefetcht1, - * which, according to Intel, means "load data into L2 cache". - * This is a good enough "middle ground" for the time being, - * though in theory, it would be better to specialize locality depending on data being prefetched. - * Tests could not determine any sensible difference based on locality value. */ -#if defined(NO_PREFETCH) -# define PREFETCH(ptr) (void)(ptr) /* disabled */ -#else -# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */ -# include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ -# define PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1) -# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) -# define PREFETCH(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */) -# else -# define PREFETCH(ptr) (void)(ptr) /* disabled */ -# endif -#endif /* NO_PREFETCH */ - -#define CACHELINE_SIZE 64 - -#define PREFETCH_AREA(p, s) { \ - const char* const _ptr = (const char*)(p); \ - size_t const _size = (size_t)(s); \ - size_t _pos; \ - for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \ - PREFETCH(_ptr + _pos); \ - } \ -} - -/* disable warnings */ -#ifdef _MSC_VER /* Visual Studio */ -# include /* For Visual 2005 */ -# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */ -# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ -# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */ -# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */ -# pragma warning(disable : 4324) /* disable: C4324: padded structure */ -#endif - -#endif /* ZSTD_COMPILER_H */ diff --git a/grub-core/lib/zstd/cpu.h b/grub-core/lib/zstd/cpu.h deleted file mode 100644 index eeb428ad5..000000000 --- a/grub-core/lib/zstd/cpu.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2018-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ - -#ifndef ZSTD_COMMON_CPU_H -#define ZSTD_COMMON_CPU_H - -/** - * Implementation taken from folly/CpuId.h - * https://github.com/facebook/folly/blob/master/folly/CpuId.h - */ - -#include - -#include "mem.h" - -#ifdef _MSC_VER -#include -#endif - -typedef struct { - U32 f1c; - U32 f1d; - U32 f7b; - U32 f7c; -} ZSTD_cpuid_t; - -MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) { - U32 f1c = 0; - U32 f1d = 0; - U32 f7b = 0; - U32 f7c = 0; -#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) - int reg[4]; - __cpuid((int*)reg, 0); - { - int const n = reg[0]; - if (n >= 1) { - __cpuid((int*)reg, 1); - f1c = (U32)reg[2]; - f1d = (U32)reg[3]; - } - if (n >= 7) { - __cpuidex((int*)reg, 7, 0); - f7b = (U32)reg[1]; - f7c = (U32)reg[2]; - } - } -#elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__) - /* The following block like the normal cpuid branch below, but gcc - * reserves ebx for use of its pic register so we must specially - * handle the save and restore to avoid clobbering the register - */ - U32 n; - __asm__( - "pushl %%ebx\n\t" - "cpuid\n\t" - "popl %%ebx\n\t" - : "=a"(n) - : "a"(0) - : "ecx", "edx"); - if (n >= 1) { - U32 f1a; - __asm__( - "pushl %%ebx\n\t" - "cpuid\n\t" - "popl %%ebx\n\t" - : "=a"(f1a), "=c"(f1c), "=d"(f1d) - : "a"(1)); - } - if (n >= 7) { - __asm__( - "pushl %%ebx\n\t" - "cpuid\n\t" - "movl %%ebx, %%eax\n\r" - "popl %%ebx" - : "=a"(f7b), "=c"(f7c) - : "a"(7), "c"(0) - : "edx"); - } -#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386__) - U32 n; - __asm__("cpuid" : "=a"(n) : "a"(0) : "ebx", "ecx", "edx"); - if (n >= 1) { - U32 f1a; - __asm__("cpuid" : "=a"(f1a), "=c"(f1c), "=d"(f1d) : "a"(1) : "ebx"); - } - if (n >= 7) { - U32 f7a; - __asm__("cpuid" - : "=a"(f7a), "=b"(f7b), "=c"(f7c) - : "a"(7), "c"(0) - : "edx"); - } -#endif - { - ZSTD_cpuid_t cpuid; - cpuid.f1c = f1c; - cpuid.f1d = f1d; - cpuid.f7b = f7b; - cpuid.f7c = f7c; - return cpuid; - } -} - -#define X(name, r, bit) \ - MEM_STATIC int ZSTD_cpuid_##name(ZSTD_cpuid_t const cpuid) { \ - return ((cpuid.r) & (1U << bit)) != 0; \ - } - -/* cpuid(1): Processor Info and Feature Bits. */ -#define C(name, bit) X(name, f1c, bit) - C(sse3, 0) - C(pclmuldq, 1) - C(dtes64, 2) - C(monitor, 3) - C(dscpl, 4) - C(vmx, 5) - C(smx, 6) - C(eist, 7) - C(tm2, 8) - C(ssse3, 9) - C(cnxtid, 10) - C(fma, 12) - C(cx16, 13) - C(xtpr, 14) - C(pdcm, 15) - C(pcid, 17) - C(dca, 18) - C(sse41, 19) - C(sse42, 20) - C(x2apic, 21) - C(movbe, 22) - C(popcnt, 23) - C(tscdeadline, 24) - C(aes, 25) - C(xsave, 26) - C(osxsave, 27) - C(avx, 28) - C(f16c, 29) - C(rdrand, 30) -#undef C -#define D(name, bit) X(name, f1d, bit) - D(fpu, 0) - D(vme, 1) - D(de, 2) - D(pse, 3) - D(tsc, 4) - D(msr, 5) - D(pae, 6) - D(mce, 7) - D(cx8, 8) - D(apic, 9) - D(sep, 11) - D(mtrr, 12) - D(pge, 13) - D(mca, 14) - D(cmov, 15) - D(pat, 16) - D(pse36, 17) - D(psn, 18) - D(clfsh, 19) - D(ds, 21) - D(acpi, 22) - D(mmx, 23) - D(fxsr, 24) - D(sse, 25) - D(sse2, 26) - D(ss, 27) - D(htt, 28) - D(tm, 29) - D(pbe, 31) -#undef D - -/* cpuid(7): Extended Features. */ -#define B(name, bit) X(name, f7b, bit) - B(bmi1, 3) - B(hle, 4) - B(avx2, 5) - B(smep, 7) - B(bmi2, 8) - B(erms, 9) - B(invpcid, 10) - B(rtm, 11) - B(mpx, 14) - B(avx512f, 16) - B(avx512dq, 17) - B(rdseed, 18) - B(adx, 19) - B(smap, 20) - B(avx512ifma, 21) - B(pcommit, 22) - B(clflushopt, 23) - B(clwb, 24) - B(avx512pf, 26) - B(avx512er, 27) - B(avx512cd, 28) - B(sha, 29) - B(avx512bw, 30) - B(avx512vl, 31) -#undef B -#define C(name, bit) X(name, f7c, bit) - C(prefetchwt1, 0) - C(avx512vbmi, 1) -#undef C - -#undef X - -#endif /* ZSTD_COMMON_CPU_H */ diff --git a/grub-core/lib/zstd/debug.c b/grub-core/lib/zstd/debug.c deleted file mode 100644 index 3ebdd1cb1..000000000 --- a/grub-core/lib/zstd/debug.c +++ /dev/null @@ -1,44 +0,0 @@ -/* ****************************************************************** - debug - Part of FSE library - Copyright (C) 2013-present, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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 COPYRIGHT HOLDERS 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 COPYRIGHT - OWNER 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. - - You can contact the author at : - - Source repository : https://github.com/Cyan4973/FiniteStateEntropy -****************************************************************** */ - - -/* - * This module only hosts one global variable - * which can be used to dynamically influence the verbosity of traces, - * such as DEBUGLOG and RAWLOG - */ - -#include "debug.h" - -int g_debuglevel = DEBUGLEVEL; diff --git a/grub-core/lib/zstd/debug.h b/grub-core/lib/zstd/debug.h deleted file mode 100644 index 0c04ad2cc..000000000 --- a/grub-core/lib/zstd/debug.h +++ /dev/null @@ -1,123 +0,0 @@ -/* ****************************************************************** - debug - Part of FSE library - Copyright (C) 2013-present, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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 COPYRIGHT HOLDERS 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 COPYRIGHT - OWNER 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. - - You can contact the author at : - - Source repository : https://github.com/Cyan4973/FiniteStateEntropy -****************************************************************** */ - - -/* - * The purpose of this header is to enable debug functions. - * They regroup assert(), DEBUGLOG() and RAWLOG() for run-time, - * and DEBUG_STATIC_ASSERT() for compile-time. - * - * By default, DEBUGLEVEL==0, which means run-time debug is disabled. - * - * Level 1 enables assert() only. - * Starting level 2, traces can be generated and pushed to stderr. - * The higher the level, the more verbose the traces. - * - * It's possible to dynamically adjust level using variable g_debug_level, - * which is only declared if DEBUGLEVEL>=2, - * and is a global variable, not multi-thread protected (use with care) - */ - -#ifndef DEBUG_H_12987983217 -#define DEBUG_H_12987983217 - -#if defined (__cplusplus) -extern "C" { -#endif - - -/* static assert is triggered at compile time, leaving no runtime artefact, - * but can only work with compile-time constants. - * This variant can only be used inside a function. */ -#define DEBUG_STATIC_ASSERT(c) (void)sizeof(char[(c) ? 1 : -1]) - - -/* DEBUGLEVEL is expected to be defined externally, - * typically through compiler command line. - * Value must be a number. */ -#ifndef DEBUGLEVEL -# define DEBUGLEVEL 0 -#endif - -/* recommended values for DEBUGLEVEL : - * 0 : no debug, all run-time functions disabled - * 1 : no display, enables assert() only - * 2 : reserved, for currently active debug path - * 3 : events once per object lifetime (CCtx, CDict, etc.) - * 4 : events once per frame - * 5 : events once per block - * 6 : events once per sequence (verbose) - * 7+: events at every position (*very* verbose) - * - * It's generally inconvenient to output traces > 5. - * In which case, it's possible to selectively enable higher verbosity levels - * by modifying g_debug_level. - */ - -#if (DEBUGLEVEL>=1) -# include -#else -# ifndef assert /* assert may be already defined, due to prior #include */ -# define assert(condition) ((void)0) /* disable assert (default) */ -# endif -#endif - -#if (DEBUGLEVEL>=2) -# include -extern int g_debuglevel; /* here, this variable is only declared, - it actually lives in debug.c, - and is shared by the whole process. - It's typically used to enable very verbose levels - on selective conditions (such as position in src) */ - -# define RAWLOG(l, ...) { \ - if (l<=g_debuglevel) { \ - fprintf(stderr, __VA_ARGS__); \ - } } -# define DEBUGLOG(l, ...) { \ - if (l<=g_debuglevel) { \ - fprintf(stderr, __FILE__ ": " __VA_ARGS__); \ - fprintf(stderr, " \n"); \ - } } -#else -# define RAWLOG(l, ...) {} /* disabled */ -# define DEBUGLOG(l, ...) {} /* disabled */ -#endif - - -#if defined (__cplusplus) -} -#endif - -#endif /* DEBUG_H_12987983217 */ diff --git a/grub-core/lib/zstd/entropy_common.c b/grub-core/lib/zstd/entropy_common.c deleted file mode 100644 index b12944e1d..000000000 --- a/grub-core/lib/zstd/entropy_common.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - Common functions of New Generation Entropy library - Copyright (C) 2016, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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 COPYRIGHT HOLDERS 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 COPYRIGHT - OWNER 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. - - You can contact the author at : - - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy - - Public forum : https://groups.google.com/forum/#!forum/lz4c -*************************************************************************** */ - -/* ************************************* -* Dependencies -***************************************/ -#include "mem.h" -#include "error_private.h" /* ERR_*, ERROR */ -#define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */ -#include "fse.h" -#define HUF_STATIC_LINKING_ONLY /* HUF_TABLELOG_ABSOLUTEMAX */ -#include "huf.h" - - -/*=== Version ===*/ -unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; } - - -/*=== Error Management ===*/ -unsigned FSE_isError(size_t code) { return ERR_isError(code); } -const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); } - -unsigned HUF_isError(size_t code) { return ERR_isError(code); } -const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); } - - -/*-************************************************************** -* FSE NCount encoding-decoding -****************************************************************/ -size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, - const void* headerBuffer, size_t hbSize) -{ - const BYTE* const istart = (const BYTE*) headerBuffer; - const BYTE* const iend = istart + hbSize; - const BYTE* ip = istart; - int nbBits; - int remaining; - int threshold; - U32 bitStream; - int bitCount; - unsigned charnum = 0; - int previous0 = 0; - - if (hbSize < 4) { - /* This function only works when hbSize >= 4 */ - char buffer[4]; - memset(buffer, 0, sizeof(buffer)); - memcpy(buffer, headerBuffer, hbSize); - { size_t const countSize = FSE_readNCount(normalizedCounter, maxSVPtr, tableLogPtr, - buffer, sizeof(buffer)); - if (FSE_isError(countSize)) return countSize; - if (countSize > hbSize) return ERROR(corruption_detected); - return countSize; - } } - assert(hbSize >= 4); - - /* init */ - memset(normalizedCounter, 0, (*maxSVPtr+1) * sizeof(normalizedCounter[0])); /* all symbols not present in NCount have a frequency of 0 */ - bitStream = MEM_readLE32(ip); - nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */ - if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge); - bitStream >>= 4; - bitCount = 4; - *tableLogPtr = nbBits; - remaining = (1<1) & (charnum<=*maxSVPtr)) { - if (previous0) { - unsigned n0 = charnum; - while ((bitStream & 0xFFFF) == 0xFFFF) { - n0 += 24; - if (ip < iend-5) { - ip += 2; - bitStream = MEM_readLE32(ip) >> bitCount; - } else { - bitStream >>= 16; - bitCount += 16; - } } - while ((bitStream & 3) == 3) { - n0 += 3; - bitStream >>= 2; - bitCount += 2; - } - n0 += bitStream & 3; - bitCount += 2; - if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall); - while (charnum < n0) normalizedCounter[charnum++] = 0; - if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { - assert((bitCount >> 3) <= 3); /* For first condition to work */ - ip += bitCount>>3; - bitCount &= 7; - bitStream = MEM_readLE32(ip) >> bitCount; - } else { - bitStream >>= 2; - } } - { int const max = (2*threshold-1) - remaining; - int count; - - if ((bitStream & (threshold-1)) < (U32)max) { - count = bitStream & (threshold-1); - bitCount += nbBits-1; - } else { - count = bitStream & (2*threshold-1); - if (count >= threshold) count -= max; - bitCount += nbBits; - } - - count--; /* extra accuracy */ - remaining -= count < 0 ? -count : count; /* -1 means +1 */ - normalizedCounter[charnum++] = (short)count; - previous0 = !count; - while (remaining < threshold) { - nbBits--; - threshold >>= 1; - } - - if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { - ip += bitCount>>3; - bitCount &= 7; - } else { - bitCount -= (int)(8 * (iend - 4 - ip)); - ip = iend - 4; - } - bitStream = MEM_readLE32(ip) >> (bitCount & 31); - } } /* while ((remaining>1) & (charnum<=*maxSVPtr)) */ - if (remaining != 1) return ERROR(corruption_detected); - if (bitCount > 32) return ERROR(corruption_detected); - *maxSVPtr = charnum-1; - - ip += (bitCount+7)>>3; - return ip-istart; -} - - -/*! HUF_readStats() : - Read compact Huffman tree, saved by HUF_writeCTable(). - `huffWeight` is destination buffer. - `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32. - @return : size read from `src` , or an error Code . - Note : Needed by HUF_readCTable() and HUF_readDTableX?() . -*/ -size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, - U32* nbSymbolsPtr, U32* tableLogPtr, - const void* src, size_t srcSize) -{ - U32 weightTotal; - const BYTE* ip = (const BYTE*) src; - size_t iSize; - size_t oSize; - - if (!srcSize) return ERROR(srcSize_wrong); - iSize = ip[0]; - /* memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */ - - if (iSize >= 128) { /* special header */ - oSize = iSize - 127; - iSize = ((oSize+1)/2); - if (iSize+1 > srcSize) return ERROR(srcSize_wrong); - if (oSize >= hwSize) return ERROR(corruption_detected); - ip += 1; - { U32 n; - for (n=0; n> 4; - huffWeight[n+1] = ip[n/2] & 15; - } } } - else { /* header compressed with FSE (normal case) */ - FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */ - if (iSize+1 > srcSize) return ERROR(srcSize_wrong); - oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */ - if (FSE_isError(oSize)) return oSize; - } - - /* collect weight stats */ - memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32)); - weightTotal = 0; - { U32 n; for (n=0; n= HUF_TABLELOG_MAX) return ERROR(corruption_detected); - rankStats[huffWeight[n]]++; - weightTotal += (1 << huffWeight[n]) >> 1; - } } - if (weightTotal == 0) return ERROR(corruption_detected); - - /* get last non-null symbol weight (implied, total must be 2^n) */ - { U32 const tableLog = BIT_highbit32(weightTotal) + 1; - if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected); - *tableLogPtr = tableLog; - /* determine last weight */ - { U32 const total = 1 << tableLog; - U32 const rest = total - weightTotal; - U32 const verif = 1 << BIT_highbit32(rest); - U32 const lastWeight = BIT_highbit32(rest) + 1; - if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */ - huffWeight[oSize] = (BYTE)lastWeight; - rankStats[lastWeight]++; - } } - - /* check tree construction validity */ - if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */ - - /* results */ - *nbSymbolsPtr = (U32)(oSize+1); - return iSize+1; -} diff --git a/grub-core/lib/zstd/error_private.c b/grub-core/lib/zstd/error_private.c deleted file mode 100644 index d004ee636..000000000 --- a/grub-core/lib/zstd/error_private.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ - -/* The purpose of this file is to have a single list of error strings embedded in binary */ - -#include "error_private.h" - -const char* ERR_getErrorString(ERR_enum code) -{ - static const char* const notErrorCode = "Unspecified error code"; - switch( code ) - { - case PREFIX(no_error): return "No error detected"; - case PREFIX(GENERIC): return "Error (generic)"; - case PREFIX(prefix_unknown): return "Unknown frame descriptor"; - case PREFIX(version_unsupported): return "Version not supported"; - case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter"; - case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding"; - case PREFIX(corruption_detected): return "Corrupted block detected"; - case PREFIX(checksum_wrong): return "Restored data doesn't match checksum"; - case PREFIX(parameter_unsupported): return "Unsupported parameter"; - case PREFIX(parameter_outOfBound): return "Parameter is out of bound"; - case PREFIX(init_missing): return "Context should be init first"; - case PREFIX(memory_allocation): return "Allocation error : not enough memory"; - case PREFIX(workSpace_tooSmall): return "workSpace buffer is not large enough"; - case PREFIX(stage_wrong): return "Operation not authorized at current processing stage"; - case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported"; - case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large"; - case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small"; - case PREFIX(dictionary_corrupted): return "Dictionary is corrupted"; - case PREFIX(dictionary_wrong): return "Dictionary mismatch"; - case PREFIX(dictionaryCreation_failed): return "Cannot create Dictionary from provided samples"; - case PREFIX(dstSize_tooSmall): return "Destination buffer is too small"; - case PREFIX(srcSize_wrong): return "Src size is incorrect"; - /* following error codes are not stable and may be removed or changed in a future version */ - case PREFIX(frameIndex_tooLarge): return "Frame index is too large"; - case PREFIX(seekableIO): return "An I/O error occurred when reading/seeking"; - case PREFIX(maxCode): - default: return notErrorCode; - } -} diff --git a/grub-core/lib/zstd/error_private.h b/grub-core/lib/zstd/error_private.h deleted file mode 100644 index 0d2fa7e34..000000000 --- a/grub-core/lib/zstd/error_private.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ - -/* Note : this module is expected to remain private, do not expose it */ - -#ifndef ERROR_H_MODULE -#define ERROR_H_MODULE - -#if defined (__cplusplus) -extern "C" { -#endif - - -/* **************************************** -* Dependencies -******************************************/ -#include /* size_t */ -#include "zstd_errors.h" /* enum list */ - - -/* **************************************** -* Compiler-specific -******************************************/ -#if defined(__GNUC__) -# define ERR_STATIC static __attribute__((unused)) -#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) -# define ERR_STATIC static inline -#elif defined(_MSC_VER) -# define ERR_STATIC static __inline -#else -# define ERR_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ -#endif - - -/*-**************************************** -* Customization (error_public.h) -******************************************/ -typedef ZSTD_ErrorCode ERR_enum; -#define PREFIX(name) ZSTD_error_##name - - -/*-**************************************** -* Error codes handling -******************************************/ -#undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */ -#define ERROR(name) ZSTD_ERROR(name) -#define ZSTD_ERROR(name) ((size_t)-PREFIX(name)) - -ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); } - -ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); } - - -/*-**************************************** -* Error Strings -******************************************/ - -const char* ERR_getErrorString(ERR_enum code); /* error_private.c */ - -ERR_STATIC const char* ERR_getErrorName(size_t code) -{ - return ERR_getErrorString(ERR_getErrorCode(code)); -} - -#if defined (__cplusplus) -} -#endif - -#endif /* ERROR_H_MODULE */ diff --git a/grub-core/lib/zstd/fse.h b/grub-core/lib/zstd/fse.h deleted file mode 100644 index a5a6b6d4d..000000000 --- a/grub-core/lib/zstd/fse.h +++ /dev/null @@ -1,708 +0,0 @@ -/* ****************************************************************** - FSE : Finite State Entropy codec - Public Prototypes declaration - Copyright (C) 2013-2016, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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 COPYRIGHT HOLDERS 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 COPYRIGHT - OWNER 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. - - You can contact the author at : - - Source repository : https://github.com/Cyan4973/FiniteStateEntropy -****************************************************************** */ - -#if defined (__cplusplus) -extern "C" { -#endif - -#ifndef FSE_H -#define FSE_H - - -/*-***************************************** -* Dependencies -******************************************/ -#include /* size_t, ptrdiff_t */ - - -/*-***************************************** -* FSE_PUBLIC_API : control library symbols visibility -******************************************/ -#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4) -# define FSE_PUBLIC_API __attribute__ ((visibility ("default"))) -#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */ -# define FSE_PUBLIC_API __declspec(dllexport) -#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1) -# define FSE_PUBLIC_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ -#else -# define FSE_PUBLIC_API -#endif - -/*------ Version ------*/ -#define FSE_VERSION_MAJOR 0 -#define FSE_VERSION_MINOR 9 -#define FSE_VERSION_RELEASE 0 - -#define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE -#define FSE_QUOTE(str) #str -#define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str) -#define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION) - -#define FSE_VERSION_NUMBER (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE) -FSE_PUBLIC_API unsigned FSE_versionNumber(void); /**< library version number; to be used when checking dll version */ - - -/*-**************************************** -* FSE simple functions -******************************************/ -/*! FSE_compress() : - Compress content of buffer 'src', of size 'srcSize', into destination buffer 'dst'. - 'dst' buffer must be already allocated. Compression runs faster is dstCapacity >= FSE_compressBound(srcSize). - @return : size of compressed data (<= dstCapacity). - Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!! - if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression instead. - if FSE_isError(return), compression failed (more details using FSE_getErrorName()) -*/ -FSE_PUBLIC_API size_t FSE_compress(void* dst, size_t dstCapacity, - const void* src, size_t srcSize); - -/*! FSE_decompress(): - Decompress FSE data from buffer 'cSrc', of size 'cSrcSize', - into already allocated destination buffer 'dst', of size 'dstCapacity'. - @return : size of regenerated data (<= maxDstSize), - or an error code, which can be tested using FSE_isError() . - - ** Important ** : FSE_decompress() does not decompress non-compressible nor RLE data !!! - Why ? : making this distinction requires a header. - Header management is intentionally delegated to the user layer, which can better manage special cases. -*/ -FSE_PUBLIC_API size_t FSE_decompress(void* dst, size_t dstCapacity, - const void* cSrc, size_t cSrcSize); - - -/*-***************************************** -* Tool functions -******************************************/ -FSE_PUBLIC_API size_t FSE_compressBound(size_t size); /* maximum compressed size */ - -/* Error Management */ -FSE_PUBLIC_API unsigned FSE_isError(size_t code); /* tells if a return value is an error code */ -FSE_PUBLIC_API const char* FSE_getErrorName(size_t code); /* provides error code string (useful for debugging) */ - - -/*-***************************************** -* FSE advanced functions -******************************************/ -/*! FSE_compress2() : - Same as FSE_compress(), but allows the selection of 'maxSymbolValue' and 'tableLog' - Both parameters can be defined as '0' to mean : use default value - @return : size of compressed data - Special values : if return == 0, srcData is not compressible => Nothing is stored within cSrc !!! - if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression. - if FSE_isError(return), it's an error code. -*/ -FSE_PUBLIC_API size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); - - -/*-***************************************** -* FSE detailed API -******************************************/ -/*! -FSE_compress() does the following: -1. count symbol occurrence from source[] into table count[] (see hist.h) -2. normalize counters so that sum(count[]) == Power_of_2 (2^tableLog) -3. save normalized counters to memory buffer using writeNCount() -4. build encoding table 'CTable' from normalized counters -5. encode the data stream using encoding table 'CTable' - -FSE_decompress() does the following: -1. read normalized counters with readNCount() -2. build decoding table 'DTable' from normalized counters -3. decode the data stream using decoding table 'DTable' - -The following API allows targeting specific sub-functions for advanced tasks. -For example, it's possible to compress several blocks using the same 'CTable', -or to save and provide normalized distribution using external method. -*/ - -/* *** COMPRESSION *** */ - -/*! FSE_optimalTableLog(): - dynamically downsize 'tableLog' when conditions are met. - It saves CPU time, by using smaller tables, while preserving or even improving compression ratio. - @return : recommended tableLog (necessarily <= 'maxTableLog') */ -FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); - -/*! FSE_normalizeCount(): - normalize counts so that sum(count[]) == Power_of_2 (2^tableLog) - 'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1). - @return : tableLog, - or an errorCode, which can be tested using FSE_isError() */ -FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, - const unsigned* count, size_t srcSize, unsigned maxSymbolValue); - -/*! FSE_NCountWriteBound(): - Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'. - Typically useful for allocation purpose. */ -FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog); - -/*! FSE_writeNCount(): - Compactly save 'normalizedCounter' into 'buffer'. - @return : size of the compressed table, - or an errorCode, which can be tested using FSE_isError(). */ -FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize, - const short* normalizedCounter, - unsigned maxSymbolValue, unsigned tableLog); - -/*! Constructor and Destructor of FSE_CTable. - Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */ -typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */ -FSE_PUBLIC_API FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog); -FSE_PUBLIC_API void FSE_freeCTable (FSE_CTable* ct); - -/*! FSE_buildCTable(): - Builds `ct`, which must be already allocated, using FSE_createCTable(). - @return : 0, or an errorCode, which can be tested using FSE_isError() */ -FSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); - -/*! FSE_compress_usingCTable(): - Compress `src` using `ct` into `dst` which must be already allocated. - @return : size of compressed data (<= `dstCapacity`), - or 0 if compressed data could not fit into `dst`, - or an errorCode, which can be tested using FSE_isError() */ -FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct); - -/*! -Tutorial : ----------- -The first step is to count all symbols. FSE_count() does this job very fast. -Result will be saved into 'count', a table of unsigned int, which must be already allocated, and have 'maxSymbolValuePtr[0]+1' cells. -'src' is a table of bytes of size 'srcSize'. All values within 'src' MUST be <= maxSymbolValuePtr[0] -maxSymbolValuePtr[0] will be updated, with its real value (necessarily <= original value) -FSE_count() will return the number of occurrence of the most frequent symbol. -This can be used to know if there is a single symbol within 'src', and to quickly evaluate its compressibility. -If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). - -The next step is to normalize the frequencies. -FSE_normalizeCount() will ensure that sum of frequencies is == 2 ^'tableLog'. -It also guarantees a minimum of 1 to any Symbol with frequency >= 1. -You can use 'tableLog'==0 to mean "use default tableLog value". -If you are unsure of which tableLog value to use, you can ask FSE_optimalTableLog(), -which will provide the optimal valid tableLog given sourceSize, maxSymbolValue, and a user-defined maximum (0 means "default"). - -The result of FSE_normalizeCount() will be saved into a table, -called 'normalizedCounter', which is a table of signed short. -'normalizedCounter' must be already allocated, and have at least 'maxSymbolValue+1' cells. -The return value is tableLog if everything proceeded as expected. -It is 0 if there is a single symbol within distribution. -If there is an error (ex: invalid tableLog value), the function will return an ErrorCode (which can be tested using FSE_isError()). - -'normalizedCounter' can be saved in a compact manner to a memory area using FSE_writeNCount(). -'buffer' must be already allocated. -For guaranteed success, buffer size must be at least FSE_headerBound(). -The result of the function is the number of bytes written into 'buffer'. -If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError(); ex : buffer size too small). - -'normalizedCounter' can then be used to create the compression table 'CTable'. -The space required by 'CTable' must be already allocated, using FSE_createCTable(). -You can then use FSE_buildCTable() to fill 'CTable'. -If there is an error, both functions will return an ErrorCode (which can be tested using FSE_isError()). - -'CTable' can then be used to compress 'src', with FSE_compress_usingCTable(). -Similar to FSE_count(), the convention is that 'src' is assumed to be a table of char of size 'srcSize' -The function returns the size of compressed data (without header), necessarily <= `dstCapacity`. -If it returns '0', compressed data could not fit into 'dst'. -If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). -*/ - - -/* *** DECOMPRESSION *** */ - -/*! FSE_readNCount(): - Read compactly saved 'normalizedCounter' from 'rBuffer'. - @return : size read from 'rBuffer', - or an errorCode, which can be tested using FSE_isError(). - maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */ -FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter, - unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, - const void* rBuffer, size_t rBuffSize); - -/*! Constructor and Destructor of FSE_DTable. - Note that its size depends on 'tableLog' */ -typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */ -FSE_PUBLIC_API FSE_DTable* FSE_createDTable(unsigned tableLog); -FSE_PUBLIC_API void FSE_freeDTable(FSE_DTable* dt); - -/*! FSE_buildDTable(): - Builds 'dt', which must be already allocated, using FSE_createDTable(). - return : 0, or an errorCode, which can be tested using FSE_isError() */ -FSE_PUBLIC_API size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); - -/*! FSE_decompress_usingDTable(): - Decompress compressed source `cSrc` of size `cSrcSize` using `dt` - into `dst` which must be already allocated. - @return : size of regenerated data (necessarily <= `dstCapacity`), - or an errorCode, which can be tested using FSE_isError() */ -FSE_PUBLIC_API size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt); - -/*! -Tutorial : ----------- -(Note : these functions only decompress FSE-compressed blocks. - If block is uncompressed, use memcpy() instead - If block is a single repeated byte, use memset() instead ) - -The first step is to obtain the normalized frequencies of symbols. -This can be performed by FSE_readNCount() if it was saved using FSE_writeNCount(). -'normalizedCounter' must be already allocated, and have at least 'maxSymbolValuePtr[0]+1' cells of signed short. -In practice, that means it's necessary to know 'maxSymbolValue' beforehand, -or size the table to handle worst case situations (typically 256). -FSE_readNCount() will provide 'tableLog' and 'maxSymbolValue'. -The result of FSE_readNCount() is the number of bytes read from 'rBuffer'. -Note that 'rBufferSize' must be at least 4 bytes, even if useful information is less than that. -If there is an error, the function will return an error code, which can be tested using FSE_isError(). - -The next step is to build the decompression tables 'FSE_DTable' from 'normalizedCounter'. -This is performed by the function FSE_buildDTable(). -The space required by 'FSE_DTable' must be already allocated using FSE_createDTable(). -If there is an error, the function will return an error code, which can be tested using FSE_isError(). - -`FSE_DTable` can then be used to decompress `cSrc`, with FSE_decompress_usingDTable(). -`cSrcSize` must be strictly correct, otherwise decompression will fail. -FSE_decompress_usingDTable() result will tell how many bytes were regenerated (<=`dstCapacity`). -If there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small) -*/ - -#endif /* FSE_H */ - -#if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY) -#define FSE_H_FSE_STATIC_LINKING_ONLY - -/* *** Dependency *** */ -#include "bitstream.h" - - -/* ***************************************** -* Static allocation -*******************************************/ -/* FSE buffer bounds */ -#define FSE_NCOUNTBOUND 512 -#define FSE_BLOCKBOUND(size) (size + (size>>7)) -#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ - -/* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */ -#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2)) -#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1< 12) ? (1 << (maxTableLog - 2)) : 1024) ) -size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); - -size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits); -/**< build a fake FSE_CTable, designed for a flat distribution, where each symbol uses nbBits */ - -size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue); -/**< build a fake FSE_CTable, designed to compress always the same symbolValue */ - -/* FSE_buildCTable_wksp() : - * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). - * `wkspSize` must be >= `(1<= BIT_DStream_completed - -When it's done, verify decompression is fully completed, by checking both DStream and the relevant states. -Checking if DStream has reached its end is performed by : - BIT_endOfDStream(&DStream); -Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible. - FSE_endOfDState(&DState); -*/ - - -/* ***************************************** -* FSE unsafe API -*******************************************/ -static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD); -/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */ - - -/* ***************************************** -* Implementation of inlined functions -*******************************************/ -typedef struct { - int deltaFindState; - U32 deltaNbBits; -} FSE_symbolCompressionTransform; /* total 8 bytes */ - -MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct) -{ - const void* ptr = ct; - const U16* u16ptr = (const U16*) ptr; - const U32 tableLog = MEM_read16(ptr); - statePtr->value = (ptrdiff_t)1<stateTable = u16ptr+2; - statePtr->symbolTT = ((const U32*)ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1)); - statePtr->stateLog = tableLog; -} - - -/*! FSE_initCState2() : -* Same as FSE_initCState(), but the first symbol to include (which will be the last to be read) -* uses the smallest state value possible, saving the cost of this symbol */ -MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol) -{ - FSE_initCState(statePtr, ct); - { const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; - const U16* stateTable = (const U16*)(statePtr->stateTable); - U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16); - statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits; - statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; - } -} - -MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, U32 symbol) -{ - FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; - const U16* const stateTable = (const U16*)(statePtr->stateTable); - U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16); - BIT_addBits(bitC, statePtr->value, nbBitsOut); - statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; -} - -MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr) -{ - BIT_addBits(bitC, statePtr->value, statePtr->stateLog); - BIT_flushBits(bitC); -} - - -/* FSE_getMaxNbBits() : - * Approximate maximum cost of a symbol, in bits. - * Fractional get rounded up (i.e : a symbol with a normalized frequency of 3 gives the same result as a frequency of 2) - * note 1 : assume symbolValue is valid (<= maxSymbolValue) - * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */ -MEM_STATIC U32 FSE_getMaxNbBits(const void* symbolTTPtr, U32 symbolValue) -{ - const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr; - return (symbolTT[symbolValue].deltaNbBits + ((1<<16)-1)) >> 16; -} - -/* FSE_bitCost() : - * Approximate symbol cost, as fractional value, using fixed-point format (accuracyLog fractional bits) - * note 1 : assume symbolValue is valid (<= maxSymbolValue) - * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */ -MEM_STATIC U32 FSE_bitCost(const void* symbolTTPtr, U32 tableLog, U32 symbolValue, U32 accuracyLog) -{ - const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr; - U32 const minNbBits = symbolTT[symbolValue].deltaNbBits >> 16; - U32 const threshold = (minNbBits+1) << 16; - assert(tableLog < 16); - assert(accuracyLog < 31-tableLog); /* ensure enough room for renormalization double shift */ - { U32 const tableSize = 1 << tableLog; - U32 const deltaFromThreshold = threshold - (symbolTT[symbolValue].deltaNbBits + tableSize); - U32 const normalizedDeltaFromThreshold = (deltaFromThreshold << accuracyLog) >> tableLog; /* linear interpolation (very approximate) */ - U32 const bitMultiplier = 1 << accuracyLog; - assert(symbolTT[symbolValue].deltaNbBits + tableSize <= threshold); - assert(normalizedDeltaFromThreshold <= bitMultiplier); - return (minNbBits+1)*bitMultiplier - normalizedDeltaFromThreshold; - } -} - - -/* ====== Decompression ====== */ - -typedef struct { - U16 tableLog; - U16 fastMode; -} FSE_DTableHeader; /* sizeof U32 */ - -typedef struct -{ - unsigned short newState; - unsigned char symbol; - unsigned char nbBits; -} FSE_decode_t; /* size == U32 */ - -MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt) -{ - const void* ptr = dt; - const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr; - DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog); - BIT_reloadDStream(bitD); - DStatePtr->table = dt + 1; -} - -MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr) -{ - FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; - return DInfo.symbol; -} - -MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) -{ - FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; - U32 const nbBits = DInfo.nbBits; - size_t const lowBits = BIT_readBits(bitD, nbBits); - DStatePtr->state = DInfo.newState + lowBits; -} - -MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) -{ - FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; - U32 const nbBits = DInfo.nbBits; - BYTE const symbol = DInfo.symbol; - size_t const lowBits = BIT_readBits(bitD, nbBits); - - DStatePtr->state = DInfo.newState + lowBits; - return symbol; -} - -/*! FSE_decodeSymbolFast() : - unsafe, only works if no symbol has a probability > 50% */ -MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) -{ - FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; - U32 const nbBits = DInfo.nbBits; - BYTE const symbol = DInfo.symbol; - size_t const lowBits = BIT_readBitsFast(bitD, nbBits); - - DStatePtr->state = DInfo.newState + lowBits; - return symbol; -} - -MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr) -{ - return DStatePtr->state == 0; -} - - - -#ifndef FSE_COMMONDEFS_ONLY - -/* ************************************************************** -* Tuning parameters -****************************************************************/ -/*!MEMORY_USAGE : -* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) -* Increasing memory usage improves compression ratio -* Reduced memory usage can improve speed, due to cache effect -* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */ -#ifndef FSE_MAX_MEMORY_USAGE -# define FSE_MAX_MEMORY_USAGE 14 -#endif -#ifndef FSE_DEFAULT_MEMORY_USAGE -# define FSE_DEFAULT_MEMORY_USAGE 13 -#endif - -/*!FSE_MAX_SYMBOL_VALUE : -* Maximum symbol value authorized. -* Required for proper stack allocation */ -#ifndef FSE_MAX_SYMBOL_VALUE -# define FSE_MAX_SYMBOL_VALUE 255 -#endif - -/* ************************************************************** -* template functions type & suffix -****************************************************************/ -#define FSE_FUNCTION_TYPE BYTE -#define FSE_FUNCTION_EXTENSION -#define FSE_DECODE_TYPE FSE_decode_t - - -#endif /* !FSE_COMMONDEFS_ONLY */ - - -/* *************************************************************** -* Constants -*****************************************************************/ -#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2) -#define FSE_MAX_TABLESIZE (1U< FSE_TABLELOG_ABSOLUTE_MAX -# error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported" -#endif - -#define FSE_TABLESTEP(tableSize) ((tableSize>>1) + (tableSize>>3) + 3) - - -#endif /* FSE_STATIC_LINKING_ONLY */ - - -#if defined (__cplusplus) -} -#endif diff --git a/grub-core/lib/zstd/fse_decompress.c b/grub-core/lib/zstd/fse_decompress.c deleted file mode 100644 index 2227b84bc..000000000 --- a/grub-core/lib/zstd/fse_decompress.c +++ /dev/null @@ -1,309 +0,0 @@ -/* ****************************************************************** - FSE : Finite State Entropy decoder - Copyright (C) 2013-2015, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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 COPYRIGHT HOLDERS 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 COPYRIGHT - OWNER 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. - - You can contact the author at : - - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy - - Public forum : https://groups.google.com/forum/#!forum/lz4c -****************************************************************** */ - - -/* ************************************************************** -* Includes -****************************************************************/ -#include /* malloc, free, qsort */ -#include /* memcpy, memset */ -#include "bitstream.h" -#include "compiler.h" -#define FSE_STATIC_LINKING_ONLY -#include "fse.h" -#include "error_private.h" - - -/* ************************************************************** -* Error Management -****************************************************************/ -#define FSE_isError ERR_isError -#define FSE_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */ - -/* check and forward error code */ -#define CHECK_F(f) { size_t const e = f; if (FSE_isError(e)) return e; } - - -/* ************************************************************** -* Templates -****************************************************************/ -/* - designed to be included - for type-specific functions (template emulation in C) - Objective is to write these functions only once, for improved maintenance -*/ - -/* safety checks */ -#ifndef FSE_FUNCTION_EXTENSION -# error "FSE_FUNCTION_EXTENSION must be defined" -#endif -#ifndef FSE_FUNCTION_TYPE -# error "FSE_FUNCTION_TYPE must be defined" -#endif - -/* Function names */ -#define FSE_CAT(X,Y) X##Y -#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) -#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) - - -/* Function templates */ -FSE_DTable* FSE_createDTable (unsigned tableLog) -{ - if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; - return (FSE_DTable*)calloc( FSE_DTABLE_SIZE_U32(tableLog), sizeof (U32) ); -} - -void FSE_freeDTable (FSE_DTable* dt) -{ - free(dt); -} - -size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) -{ - void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ - FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr); - U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1]; - - U32 const maxSV1 = maxSymbolValue + 1; - U32 const tableSize = 1 << tableLog; - U32 highThreshold = tableSize-1; - - /* Sanity Checks */ - if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge); - if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); - - /* Init, lay down lowprob symbols */ - { FSE_DTableHeader DTableH; - DTableH.tableLog = (U16)tableLog; - DTableH.fastMode = 1; - { S16 const largeLimit= (S16)(1 << (tableLog-1)); - U32 s; - for (s=0; s= largeLimit) DTableH.fastMode=0; - symbolNext[s] = normalizedCounter[s]; - } } } - memcpy(dt, &DTableH, sizeof(DTableH)); - } - - /* Spread symbols */ - { U32 const tableMask = tableSize-1; - U32 const step = FSE_TABLESTEP(tableSize); - U32 s, position = 0; - for (s=0; s highThreshold) position = (position + step) & tableMask; /* lowprob area */ - } } - if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ - } - - /* Build Decoding table */ - { U32 u; - for (u=0; utableLog = 0; - DTableH->fastMode = 0; - - cell->newState = 0; - cell->symbol = symbolValue; - cell->nbBits = 0; - - return 0; -} - - -size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits) -{ - void* ptr = dt; - FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr; - void* dPtr = dt + 1; - FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr; - const unsigned tableSize = 1 << nbBits; - const unsigned tableMask = tableSize - 1; - const unsigned maxSV1 = tableMask+1; - unsigned s; - - /* Sanity checks */ - if (nbBits < 1) return ERROR(GENERIC); /* min size */ - - /* Build Decoding Table */ - DTableH->tableLog = (U16)nbBits; - DTableH->fastMode = 1; - for (s=0; s sizeof(bitD.bitContainer)*8) /* This test must be static */ - BIT_reloadDStream(&bitD); - - op[1] = FSE_GETSYMBOL(&state2); - - if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ - { if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } } - - op[2] = FSE_GETSYMBOL(&state1); - - if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ - BIT_reloadDStream(&bitD); - - op[3] = FSE_GETSYMBOL(&state2); - } - - /* tail */ - /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */ - while (1) { - if (op>(omax-2)) return ERROR(dstSize_tooSmall); - *op++ = FSE_GETSYMBOL(&state1); - if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { - *op++ = FSE_GETSYMBOL(&state2); - break; - } - - if (op>(omax-2)) return ERROR(dstSize_tooSmall); - *op++ = FSE_GETSYMBOL(&state2); - if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { - *op++ = FSE_GETSYMBOL(&state1); - break; - } } - - return op-ostart; -} - - -size_t FSE_decompress_usingDTable(void* dst, size_t originalSize, - const void* cSrc, size_t cSrcSize, - const FSE_DTable* dt) -{ - const void* ptr = dt; - const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr; - const U32 fastMode = DTableH->fastMode; - - /* select fast mode (static) */ - if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1); - return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0); -} - - -size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog) -{ - const BYTE* const istart = (const BYTE*)cSrc; - const BYTE* ip = istart; - short counting[FSE_MAX_SYMBOL_VALUE+1]; - unsigned tableLog; - unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; - - /* normal FSE decoding mode */ - size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize); - if (FSE_isError(NCountLength)) return NCountLength; - //if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */ - if (tableLog > maxLog) return ERROR(tableLog_tooLarge); - ip += NCountLength; - cSrcSize -= NCountLength; - - CHECK_F( FSE_buildDTable (workSpace, counting, maxSymbolValue, tableLog) ); - - return FSE_decompress_usingDTable (dst, dstCapacity, ip, cSrcSize, workSpace); /* always return, even if it is an error code */ -} - - -typedef FSE_DTable DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)]; - -size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize) -{ - DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */ - return FSE_decompress_wksp(dst, dstCapacity, cSrc, cSrcSize, dt, FSE_MAX_TABLELOG); -} - - - -#endif /* FSE_COMMONDEFS_ONLY */ diff --git a/grub-core/lib/zstd/huf.h b/grub-core/lib/zstd/huf.h deleted file mode 100644 index de9464111..000000000 --- a/grub-core/lib/zstd/huf.h +++ /dev/null @@ -1,334 +0,0 @@ -/* ****************************************************************** - huff0 huffman codec, - part of Finite State Entropy library - Copyright (C) 2013-present, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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 COPYRIGHT HOLDERS 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 COPYRIGHT - OWNER 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. - - You can contact the author at : - - Source repository : https://github.com/Cyan4973/FiniteStateEntropy -****************************************************************** */ - -#if defined (__cplusplus) -extern "C" { -#endif - -#ifndef HUF_H_298734234 -#define HUF_H_298734234 - -/* *** Dependencies *** */ -#include /* size_t */ - - -/* *** library symbols visibility *** */ -/* Note : when linking with -fvisibility=hidden on gcc, or by default on Visual, - * HUF symbols remain "private" (internal symbols for library only). - * Set macro FSE_DLL_EXPORT to 1 if you want HUF symbols visible on DLL interface */ -#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4) -# define HUF_PUBLIC_API __attribute__ ((visibility ("default"))) -#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */ -# define HUF_PUBLIC_API __declspec(dllexport) -#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1) -# define HUF_PUBLIC_API __declspec(dllimport) /* not required, just to generate faster code (saves a function pointer load from IAT and an indirect jump) */ -#else -# define HUF_PUBLIC_API -#endif - - -/* ========================== */ -/* *** simple functions *** */ -/* ========================== */ - -/** HUF_compress() : - * Compress content from buffer 'src', of size 'srcSize', into buffer 'dst'. - * 'dst' buffer must be already allocated. - * Compression runs faster if `dstCapacity` >= HUF_compressBound(srcSize). - * `srcSize` must be <= `HUF_BLOCKSIZE_MAX` == 128 KB. - * @return : size of compressed data (<= `dstCapacity`). - * Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!! - * if HUF_isError(return), compression failed (more details using HUF_getErrorName()) - */ -HUF_PUBLIC_API size_t HUF_compress(void* dst, size_t dstCapacity, - const void* src, size_t srcSize); - -/** HUF_decompress() : - * Decompress HUF data from buffer 'cSrc', of size 'cSrcSize', - * into already allocated buffer 'dst', of minimum size 'dstSize'. - * `originalSize` : **must** be the ***exact*** size of original (uncompressed) data. - * Note : in contrast with FSE, HUF_decompress can regenerate - * RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data, - * because it knows size to regenerate (originalSize). - * @return : size of regenerated data (== originalSize), - * or an error code, which can be tested using HUF_isError() - */ -HUF_PUBLIC_API size_t HUF_decompress(void* dst, size_t originalSize, - const void* cSrc, size_t cSrcSize); - - -/* *** Tool functions *** */ -#define HUF_BLOCKSIZE_MAX (128 * 1024) /**< maximum input size for a single block compressed with HUF_compress */ -HUF_PUBLIC_API size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */ - -/* Error Management */ -HUF_PUBLIC_API unsigned HUF_isError(size_t code); /**< tells if a return value is an error code */ -HUF_PUBLIC_API const char* HUF_getErrorName(size_t code); /**< provides error code string (useful for debugging) */ - - -/* *** Advanced function *** */ - -/** HUF_compress2() : - * Same as HUF_compress(), but offers control over `maxSymbolValue` and `tableLog`. - * `maxSymbolValue` must be <= HUF_SYMBOLVALUE_MAX . - * `tableLog` must be `<= HUF_TABLELOG_MAX` . */ -HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - unsigned maxSymbolValue, unsigned tableLog); - -/** HUF_compress4X_wksp() : - * Same as HUF_compress2(), but uses externally allocated `workSpace`. - * `workspace` must have minimum alignment of 4, and be at least as large as HUF_WORKSPACE_SIZE */ -#define HUF_WORKSPACE_SIZE (6 << 10) -#define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32)) -HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - unsigned maxSymbolValue, unsigned tableLog, - void* workSpace, size_t wkspSize); - -#endif /* HUF_H_298734234 */ - -/* ****************************************************************** - * WARNING !! - * The following section contains advanced and experimental definitions - * which shall never be used in the context of a dynamic library, - * because they are not guaranteed to remain stable in the future. - * Only consider them in association with static linking. - * *****************************************************************/ -#if defined(HUF_STATIC_LINKING_ONLY) && !defined(HUF_H_HUF_STATIC_LINKING_ONLY) -#define HUF_H_HUF_STATIC_LINKING_ONLY - -/* *** Dependencies *** */ -#include "mem.h" /* U32 */ - - -/* *** Constants *** */ -#define HUF_TABLELOG_MAX 12 /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */ -#define HUF_TABLELOG_DEFAULT 11 /* default tableLog value when none specified */ -#define HUF_SYMBOLVALUE_MAX 255 - -#define HUF_TABLELOG_ABSOLUTEMAX 15 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */ -#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX) -# error "HUF_TABLELOG_MAX is too large !" -#endif - - -/* **************************************** -* Static allocation -******************************************/ -/* HUF buffer bounds */ -#define HUF_CTABLEBOUND 129 -#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true when incompressible is pre-filtered with fast heuristic */ -#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ - -/* static allocation of HUF's Compression Table */ -#define HUF_CTABLE_SIZE_U32(maxSymbolValue) ((maxSymbolValue)+1) /* Use tables of U32, for proper alignment */ -#define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_U32(maxSymbolValue) * sizeof(U32)) -#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \ - U32 name##hb[HUF_CTABLE_SIZE_U32(maxSymbolValue)]; \ - void* name##hv = &(name##hb); \ - HUF_CElt* name = (HUF_CElt*)(name##hv) /* no final ; */ - -/* static allocation of HUF's DTable */ -typedef U32 HUF_DTable; -#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog))) -#define HUF_CREATE_STATIC_DTABLEX1(DTable, maxTableLog) \ - HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) } -#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \ - HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) } - - -/* **************************************** -* Advanced decompression functions -******************************************/ -size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ -size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ - -size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< decodes RLE and uncompressed */ -size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< considers RLE and uncompressed as errors */ -size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< considers RLE and uncompressed as errors */ -size_t HUF_decompress4X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ -size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol decoder */ -size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ -size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols decoder */ - - -/* **************************************** - * HUF detailed API - * ****************************************/ - -/*! HUF_compress() does the following: - * 1. count symbol occurrence from source[] into table count[] using FSE_count() (exposed within "fse.h") - * 2. (optional) refine tableLog using HUF_optimalTableLog() - * 3. build Huffman table from count using HUF_buildCTable() - * 4. save Huffman table to memory buffer using HUF_writeCTable() - * 5. encode the data stream using HUF_compress4X_usingCTable() - * - * The following API allows targeting specific sub-functions for advanced tasks. - * For example, it's possible to compress several blocks using the same 'CTable', - * or to save and regenerate 'CTable' using external methods. - */ -unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); -typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */ -size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits); /* @return : maxNbBits; CTable and count can overlap. In which case, CTable will overwrite count content */ -size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog); -size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); - -typedef enum { - HUF_repeat_none, /**< Cannot use the previous table */ - HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, 4}X_repeat */ - HUF_repeat_valid /**< Can use the previous table and it is assumed to be valid */ - } HUF_repeat; -/** HUF_compress4X_repeat() : - * Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. - * If it uses hufTable it does not modify hufTable or repeat. - * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. - * If preferRepeat then the old table will always be used if valid. */ -size_t HUF_compress4X_repeat(void* dst, size_t dstSize, - const void* src, size_t srcSize, - unsigned maxSymbolValue, unsigned tableLog, - void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ - HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2); - -/** HUF_buildCTable_wksp() : - * Same as HUF_buildCTable(), but using externally allocated scratch buffer. - * `workSpace` must be aligned on 4-bytes boundaries, and its size must be >= HUF_CTABLE_WORKSPACE_SIZE. - */ -#define HUF_CTABLE_WORKSPACE_SIZE_U32 (2*HUF_SYMBOLVALUE_MAX +1 +1) -#define HUF_CTABLE_WORKSPACE_SIZE (HUF_CTABLE_WORKSPACE_SIZE_U32 * sizeof(unsigned)) -size_t HUF_buildCTable_wksp (HUF_CElt* tree, - const U32* count, U32 maxSymbolValue, U32 maxNbBits, - void* workSpace, size_t wkspSize); - -/*! HUF_readStats() : - * Read compact Huffman tree, saved by HUF_writeCTable(). - * `huffWeight` is destination buffer. - * @return : size read from `src` , or an error Code . - * Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */ -size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, - U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr, - const void* src, size_t srcSize); - -/** HUF_readCTable() : - * Loading a CTable saved with HUF_writeCTable() */ -size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize); - -/** HUF_getNbBits() : - * Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX - * Note 1 : is not inlined, as HUF_CElt definition is private - * Note 2 : const void* used, so that it can provide a statically allocated table as argument (which uses type U32) */ -U32 HUF_getNbBits(const void* symbolTable, U32 symbolValue); - -/* - * HUF_decompress() does the following: - * 1. select the decompression algorithm (X1, X2) based on pre-computed heuristics - * 2. build Huffman table from save, using HUF_readDTableX?() - * 3. decode 1 or 4 segments in parallel using HUF_decompress?X?_usingDTable() - */ - -/** HUF_selectDecoder() : - * Tells which decoder is likely to decode faster, - * based on a set of pre-computed metrics. - * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 . - * Assumption : 0 < dstSize <= 128 KB */ -U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize); - -/** - * The minimum workspace size for the `workSpace` used in - * HUF_readDTableX1_wksp() and HUF_readDTableX2_wksp(). - * - * The space used depends on HUF_TABLELOG_MAX, ranging from ~1500 bytes when - * HUF_TABLE_LOG_MAX=12 to ~1850 bytes when HUF_TABLE_LOG_MAX=15. - * Buffer overflow errors may potentially occur if code modifications result in - * a required workspace size greater than that specified in the following - * macro. - */ -#define HUF_DECOMPRESS_WORKSPACE_SIZE (2 << 10) -#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32)) - -size_t HUF_readDTableX1 (HUF_DTable* DTable, const void* src, size_t srcSize); -size_t HUF_readDTableX1_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize); -size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize); -size_t HUF_readDTableX2_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize); - -size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); -size_t HUF_decompress4X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); -size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); - - -/* ====================== */ -/* single stream variants */ -/* ====================== */ - -size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); -size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */ -size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); -/** HUF_compress1X_repeat() : - * Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. - * If it uses hufTable it does not modify hufTable or repeat. - * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. - * If preferRepeat then the old table will always be used if valid. */ -size_t HUF_compress1X_repeat(void* dst, size_t dstSize, - const void* src, size_t srcSize, - unsigned maxSymbolValue, unsigned tableLog, - void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ - HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2); - -size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */ -size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */ - -size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); -size_t HUF_decompress1X_DCtx_wksp (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); -size_t HUF_decompress1X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ -size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol decoder */ -size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ -size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols decoder */ - -size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); /**< automatic selection of sing or double symbol decoder, based on DTable */ -size_t HUF_decompress1X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); -size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); - -/* BMI2 variants. - * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0. - */ -size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2); -size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2); -size_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2); -size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2); - -#endif /* HUF_STATIC_LINKING_ONLY */ - -#if defined (__cplusplus) -} -#endif diff --git a/grub-core/lib/zstd/huf_decompress.c b/grub-core/lib/zstd/huf_decompress.c deleted file mode 100644 index 83ecaff01..000000000 --- a/grub-core/lib/zstd/huf_decompress.c +++ /dev/null @@ -1,1096 +0,0 @@ -/* ****************************************************************** - huff0 huffman decoder, - part of Finite State Entropy library - Copyright (C) 2013-present, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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 COPYRIGHT HOLDERS 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 COPYRIGHT - OWNER 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. - - You can contact the author at : - - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy -****************************************************************** */ - -/* ************************************************************** -* Dependencies -****************************************************************/ -#include /* memcpy, memset */ -#include "compiler.h" -#include "bitstream.h" /* BIT_* */ -#include "fse.h" /* to compress headers */ -#define HUF_STATIC_LINKING_ONLY -#include "huf.h" -#include "error_private.h" - - -/* ************************************************************** -* Error Management -****************************************************************/ -#define HUF_isError ERR_isError -#define CHECK_F(f) { size_t const err_ = (f); if (HUF_isError(err_)) return err_; } - - -/* ************************************************************** -* Byte alignment for workSpace management -****************************************************************/ -#define HUF_ALIGN(x, a) HUF_ALIGN_MASK((x), (a) - 1) -#define HUF_ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) - - -/*-***************************/ -/* generic DTableDesc */ -/*-***************************/ -typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc; - -static DTableDesc HUF_getDTableDesc(const HUF_DTable* table) -{ - DTableDesc dtd; - memcpy(&dtd, table, sizeof(dtd)); - return dtd; -} - - -/*-***************************/ -/* single-symbol decoding */ -/*-***************************/ -typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX1; /* single-symbol decoding */ - -size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize) -{ - U32 tableLog = 0; - U32 nbSymbols = 0; - size_t iSize; - void* const dtPtr = DTable + 1; - HUF_DEltX1* const dt = (HUF_DEltX1*)dtPtr; - - U32* rankVal; - BYTE* huffWeight; - size_t spaceUsed32 = 0; - - rankVal = (U32 *)workSpace + spaceUsed32; - spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1; - huffWeight = (BYTE *)((U32 *)workSpace + spaceUsed32); - spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; - - if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge); - - DEBUG_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable)); - /* memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */ - - iSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize); - if (HUF_isError(iSize)) return iSize; - - /* Table header */ - { DTableDesc dtd = HUF_getDTableDesc(DTable); - if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */ - dtd.tableType = 0; - dtd.tableLog = (BYTE)tableLog; - memcpy(DTable, &dtd, sizeof(dtd)); - } - - /* Calculate starting value for each rank */ - { U32 n, nextRankStart = 0; - for (n=1; n> 1; - U32 u; - HUF_DEltX1 D; - D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w); - for (u = rankVal[w]; u < rankVal[w] + length; u++) - dt[u] = D; - rankVal[w] += length; - } } - - return iSize; -} - -size_t HUF_readDTableX1(HUF_DTable* DTable, const void* src, size_t srcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_readDTableX1_wksp(DTable, src, srcSize, - workSpace, sizeof(workSpace)); -} - -FORCE_INLINE_TEMPLATE BYTE -HUF_decodeSymbolX1(BIT_DStream_t* Dstream, const HUF_DEltX1* dt, const U32 dtLog) -{ - size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */ - BYTE const c = dt[val].byte; - BIT_skipBits(Dstream, dt[val].nbBits); - return c; -} - -#define HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) \ - *ptr++ = HUF_decodeSymbolX1(DStreamPtr, dt, dtLog) - -#define HUF_DECODE_SYMBOLX1_1(ptr, DStreamPtr) \ - if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \ - HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) - -#define HUF_DECODE_SYMBOLX1_2(ptr, DStreamPtr) \ - if (MEM_64bits()) \ - HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) - -HINT_INLINE size_t -HUF_decodeStreamX1(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX1* const dt, const U32 dtLog) -{ - BYTE* const pStart = p; - - /* up to 4 symbols at a time */ - while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-3)) { - HUF_DECODE_SYMBOLX1_2(p, bitDPtr); - HUF_DECODE_SYMBOLX1_1(p, bitDPtr); - HUF_DECODE_SYMBOLX1_2(p, bitDPtr); - HUF_DECODE_SYMBOLX1_0(p, bitDPtr); - } - - /* [0-3] symbols remaining */ - if (MEM_32bits()) - while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd)) - HUF_DECODE_SYMBOLX1_0(p, bitDPtr); - - /* no more data to retrieve from bitstream, no need to reload */ - while (p < pEnd) - HUF_DECODE_SYMBOLX1_0(p, bitDPtr); - - return pEnd-pStart; -} - -FORCE_INLINE_TEMPLATE size_t -HUF_decompress1X1_usingDTable_internal_body( - void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize, - const HUF_DTable* DTable) -{ - BYTE* op = (BYTE*)dst; - BYTE* const oend = op + dstSize; - const void* dtPtr = DTable + 1; - const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr; - BIT_DStream_t bitD; - DTableDesc const dtd = HUF_getDTableDesc(DTable); - U32 const dtLog = dtd.tableLog; - - CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) ); - - HUF_decodeStreamX1(op, &bitD, oend, dt, dtLog); - - if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected); - - return dstSize; -} - -FORCE_INLINE_TEMPLATE size_t -HUF_decompress4X1_usingDTable_internal_body( - void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize, - const HUF_DTable* DTable) -{ - /* Check */ - if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ - - { const BYTE* const istart = (const BYTE*) cSrc; - BYTE* const ostart = (BYTE*) dst; - BYTE* const oend = ostart + dstSize; - const void* const dtPtr = DTable + 1; - const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr; - - /* Init */ - BIT_DStream_t bitD1; - BIT_DStream_t bitD2; - BIT_DStream_t bitD3; - BIT_DStream_t bitD4; - size_t const length1 = MEM_readLE16(istart); - size_t const length2 = MEM_readLE16(istart+2); - size_t const length3 = MEM_readLE16(istart+4); - size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6); - const BYTE* const istart1 = istart + 6; /* jumpTable */ - const BYTE* const istart2 = istart1 + length1; - const BYTE* const istart3 = istart2 + length2; - const BYTE* const istart4 = istart3 + length3; - const size_t segmentSize = (dstSize+3) / 4; - BYTE* const opStart2 = ostart + segmentSize; - BYTE* const opStart3 = opStart2 + segmentSize; - BYTE* const opStart4 = opStart3 + segmentSize; - BYTE* op1 = ostart; - BYTE* op2 = opStart2; - BYTE* op3 = opStart3; - BYTE* op4 = opStart4; - U32 endSignal = BIT_DStream_unfinished; - DTableDesc const dtd = HUF_getDTableDesc(DTable); - U32 const dtLog = dtd.tableLog; - - if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ - CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); - CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); - CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); - CHECK_F( BIT_initDStream(&bitD4, istart4, length4) ); - - /* up to 16 symbols per loop (4 symbols per stream) in 64-bit mode */ - endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); - while ( (endSignal==BIT_DStream_unfinished) && (op4<(oend-3)) ) { - HUF_DECODE_SYMBOLX1_2(op1, &bitD1); - HUF_DECODE_SYMBOLX1_2(op2, &bitD2); - HUF_DECODE_SYMBOLX1_2(op3, &bitD3); - HUF_DECODE_SYMBOLX1_2(op4, &bitD4); - HUF_DECODE_SYMBOLX1_1(op1, &bitD1); - HUF_DECODE_SYMBOLX1_1(op2, &bitD2); - HUF_DECODE_SYMBOLX1_1(op3, &bitD3); - HUF_DECODE_SYMBOLX1_1(op4, &bitD4); - HUF_DECODE_SYMBOLX1_2(op1, &bitD1); - HUF_DECODE_SYMBOLX1_2(op2, &bitD2); - HUF_DECODE_SYMBOLX1_2(op3, &bitD3); - HUF_DECODE_SYMBOLX1_2(op4, &bitD4); - HUF_DECODE_SYMBOLX1_0(op1, &bitD1); - HUF_DECODE_SYMBOLX1_0(op2, &bitD2); - HUF_DECODE_SYMBOLX1_0(op3, &bitD3); - HUF_DECODE_SYMBOLX1_0(op4, &bitD4); - BIT_reloadDStream(&bitD1); - BIT_reloadDStream(&bitD2); - BIT_reloadDStream(&bitD3); - BIT_reloadDStream(&bitD4); - } - - /* check corruption */ - /* note : should not be necessary : op# advance in lock step, and we control op4. - * but curiously, binary generated by gcc 7.2 & 7.3 with -mbmi2 runs faster when >=1 test is present */ - if (op1 > opStart2) return ERROR(corruption_detected); - if (op2 > opStart3) return ERROR(corruption_detected); - if (op3 > opStart4) return ERROR(corruption_detected); - /* note : op4 supposed already verified within main loop */ - - /* finish bitStreams one by one */ - HUF_decodeStreamX1(op1, &bitD1, opStart2, dt, dtLog); - HUF_decodeStreamX1(op2, &bitD2, opStart3, dt, dtLog); - HUF_decodeStreamX1(op3, &bitD3, opStart4, dt, dtLog); - HUF_decodeStreamX1(op4, &bitD4, oend, dt, dtLog); - - /* check */ - { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4); - if (!endCheck) return ERROR(corruption_detected); } - - /* decoded size */ - return dstSize; - } -} - - -typedef size_t (*HUF_decompress_usingDTable_t)(void *dst, size_t dstSize, - const void *cSrc, - size_t cSrcSize, - const HUF_DTable *DTable); -#if DYNAMIC_BMI2 - -#define HUF_DGEN(fn) \ - \ - static size_t fn##_default( \ - void* dst, size_t dstSize, \ - const void* cSrc, size_t cSrcSize, \ - const HUF_DTable* DTable) \ - { \ - return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ - } \ - \ - static TARGET_ATTRIBUTE("bmi2") size_t fn##_bmi2( \ - void* dst, size_t dstSize, \ - const void* cSrc, size_t cSrcSize, \ - const HUF_DTable* DTable) \ - { \ - return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ - } \ - \ - static size_t fn(void* dst, size_t dstSize, void const* cSrc, \ - size_t cSrcSize, HUF_DTable const* DTable, int bmi2) \ - { \ - if (bmi2) { \ - return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable); \ - } \ - return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable); \ - } - -#else - -#define HUF_DGEN(fn) \ - static size_t fn(void* dst, size_t dstSize, void const* cSrc, \ - size_t cSrcSize, HUF_DTable const* DTable, int bmi2) \ - { \ - (void)bmi2; \ - return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ - } - -#endif - -HUF_DGEN(HUF_decompress1X1_usingDTable_internal) -HUF_DGEN(HUF_decompress4X1_usingDTable_internal) - - - -size_t HUF_decompress1X1_usingDTable( - void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize, - const HUF_DTable* DTable) -{ - DTableDesc dtd = HUF_getDTableDesc(DTable); - if (dtd.tableType != 0) return ERROR(GENERIC); - return HUF_decompress1X1_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0); -} - -size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize, - void* workSpace, size_t wkspSize) -{ - const BYTE* ip = (const BYTE*) cSrc; - - size_t const hSize = HUF_readDTableX1_wksp(DCtx, cSrc, cSrcSize, workSpace, wkspSize); - if (HUF_isError(hSize)) return hSize; - if (hSize >= cSrcSize) return ERROR(srcSize_wrong); - ip += hSize; cSrcSize -= hSize; - - return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, /* bmi2 */ 0); -} - - -size_t HUF_decompress1X1_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_decompress1X1_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize, - workSpace, sizeof(workSpace)); -} - -size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ - HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX); - return HUF_decompress1X1_DCtx (DTable, dst, dstSize, cSrc, cSrcSize); -} - -size_t HUF_decompress4X1_usingDTable( - void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize, - const HUF_DTable* DTable) -{ - DTableDesc dtd = HUF_getDTableDesc(DTable); - if (dtd.tableType != 0) return ERROR(GENERIC); - return HUF_decompress4X1_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0); -} - -static size_t HUF_decompress4X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize, - void* workSpace, size_t wkspSize, int bmi2) -{ - const BYTE* ip = (const BYTE*) cSrc; - - size_t const hSize = HUF_readDTableX1_wksp (dctx, cSrc, cSrcSize, - workSpace, wkspSize); - if (HUF_isError(hSize)) return hSize; - if (hSize >= cSrcSize) return ERROR(srcSize_wrong); - ip += hSize; cSrcSize -= hSize; - - return HUF_decompress4X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, bmi2); -} - -size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize, - void* workSpace, size_t wkspSize) -{ - return HUF_decompress4X1_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, 0); -} - - -size_t HUF_decompress4X1_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, - workSpace, sizeof(workSpace)); -} -size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ - HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX); - return HUF_decompress4X1_DCtx(DTable, dst, dstSize, cSrc, cSrcSize); -} - - -/* *************************/ -/* double-symbols decoding */ -/* *************************/ - -typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX2; /* double-symbols decoding */ -typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t; -typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1]; -typedef rankValCol_t rankVal_t[HUF_TABLELOG_MAX]; - - -/* HUF_fillDTableX2Level2() : - * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */ -static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 sizeLog, const U32 consumed, - const U32* rankValOrigin, const int minWeight, - const sortedSymbol_t* sortedSymbols, const U32 sortedListSize, - U32 nbBitsBaseline, U16 baseSeq) -{ - HUF_DEltX2 DElt; - U32 rankVal[HUF_TABLELOG_MAX + 1]; - - /* get pre-calculated rankVal */ - memcpy(rankVal, rankValOrigin, sizeof(rankVal)); - - /* fill skipped values */ - if (minWeight>1) { - U32 i, skipSize = rankVal[minWeight]; - MEM_writeLE16(&(DElt.sequence), baseSeq); - DElt.nbBits = (BYTE)(consumed); - DElt.length = 1; - for (i = 0; i < skipSize; i++) - DTable[i] = DElt; - } - - /* fill DTable */ - { U32 s; for (s=0; s= 1 */ - - rankVal[weight] += length; - } } -} - - -static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog, - const sortedSymbol_t* sortedList, const U32 sortedListSize, - const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight, - const U32 nbBitsBaseline) -{ - U32 rankVal[HUF_TABLELOG_MAX + 1]; - const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */ - const U32 minBits = nbBitsBaseline - maxWeight; - U32 s; - - memcpy(rankVal, rankValOrigin, sizeof(rankVal)); - - /* fill DTable */ - for (s=0; s= minBits) { /* enough room for a second symbol */ - U32 sortedRank; - int minWeight = nbBits + scaleLog; - if (minWeight < 1) minWeight = 1; - sortedRank = rankStart[minWeight]; - HUF_fillDTableX2Level2(DTable+start, targetLog-nbBits, nbBits, - rankValOrigin[nbBits], minWeight, - sortedList+sortedRank, sortedListSize-sortedRank, - nbBitsBaseline, symbol); - } else { - HUF_DEltX2 DElt; - MEM_writeLE16(&(DElt.sequence), symbol); - DElt.nbBits = (BYTE)(nbBits); - DElt.length = 1; - { U32 const end = start + length; - U32 u; - for (u = start; u < end; u++) DTable[u] = DElt; - } } - rankVal[weight] += length; - } -} - -size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, - const void* src, size_t srcSize, - void* workSpace, size_t wkspSize) -{ - U32 tableLog, maxW, sizeOfSort, nbSymbols; - DTableDesc dtd = HUF_getDTableDesc(DTable); - U32 const maxTableLog = dtd.maxTableLog; - size_t iSize; - void* dtPtr = DTable+1; /* force compiler to avoid strict-aliasing */ - HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr; - U32 *rankStart; - - rankValCol_t* rankVal; - U32* rankStats; - U32* rankStart0; - sortedSymbol_t* sortedSymbol; - BYTE* weightList; - size_t spaceUsed32 = 0; - - rankVal = (rankValCol_t *)((U32 *)workSpace + spaceUsed32); - spaceUsed32 += (sizeof(rankValCol_t) * HUF_TABLELOG_MAX) >> 2; - rankStats = (U32 *)workSpace + spaceUsed32; - spaceUsed32 += HUF_TABLELOG_MAX + 1; - rankStart0 = (U32 *)workSpace + spaceUsed32; - spaceUsed32 += HUF_TABLELOG_MAX + 2; - sortedSymbol = (sortedSymbol_t *)workSpace + (spaceUsed32 * sizeof(U32)) / sizeof(sortedSymbol_t); - spaceUsed32 += HUF_ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2; - weightList = (BYTE *)((U32 *)workSpace + spaceUsed32); - spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; - - if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge); - - rankStart = rankStart0 + 1; - memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1)); - - DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */ - if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); - /* memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */ - - iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize); - if (HUF_isError(iSize)) return iSize; - - /* check result */ - if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */ - - /* find maxWeight */ - for (maxW = tableLog; rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */ - - /* Get start index of each weight */ - { U32 w, nextRankStart = 0; - for (w=1; w> consumed; - } } } } - - HUF_fillDTableX2(dt, maxTableLog, - sortedSymbol, sizeOfSort, - rankStart0, rankVal, maxW, - tableLog+1); - - dtd.tableLog = (BYTE)maxTableLog; - dtd.tableType = 1; - memcpy(DTable, &dtd, sizeof(dtd)); - return iSize; -} - -size_t HUF_readDTableX2(HUF_DTable* DTable, const void* src, size_t srcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_readDTableX2_wksp(DTable, src, srcSize, - workSpace, sizeof(workSpace)); -} - - -FORCE_INLINE_TEMPLATE U32 -HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog) -{ - size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ - memcpy(op, dt+val, 2); - BIT_skipBits(DStream, dt[val].nbBits); - return dt[val].length; -} - -FORCE_INLINE_TEMPLATE U32 -HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog) -{ - size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ - memcpy(op, dt+val, 1); - if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits); - else { - if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) { - BIT_skipBits(DStream, dt[val].nbBits); - if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8)) - /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */ - DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8); - } } - return 1; -} - -#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \ - ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog) - -#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \ - if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \ - ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog) - -#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \ - if (MEM_64bits()) \ - ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog) - -HINT_INLINE size_t -HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, - const HUF_DEltX2* const dt, const U32 dtLog) -{ - BYTE* const pStart = p; - - /* up to 8 symbols at a time */ - while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) { - HUF_DECODE_SYMBOLX2_2(p, bitDPtr); - HUF_DECODE_SYMBOLX2_1(p, bitDPtr); - HUF_DECODE_SYMBOLX2_2(p, bitDPtr); - HUF_DECODE_SYMBOLX2_0(p, bitDPtr); - } - - /* closer to end : up to 2 symbols at a time */ - while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2)) - HUF_DECODE_SYMBOLX2_0(p, bitDPtr); - - while (p <= pEnd-2) - HUF_DECODE_SYMBOLX2_0(p, bitDPtr); /* no need to reload : reached the end of DStream */ - - if (p < pEnd) - p += HUF_decodeLastSymbolX2(p, bitDPtr, dt, dtLog); - - return p-pStart; -} - -FORCE_INLINE_TEMPLATE size_t -HUF_decompress1X2_usingDTable_internal_body( - void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize, - const HUF_DTable* DTable) -{ - BIT_DStream_t bitD; - - /* Init */ - CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) ); - - /* decode */ - { BYTE* const ostart = (BYTE*) dst; - BYTE* const oend = ostart + dstSize; - const void* const dtPtr = DTable+1; /* force compiler to not use strict-aliasing */ - const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr; - DTableDesc const dtd = HUF_getDTableDesc(DTable); - HUF_decodeStreamX2(ostart, &bitD, oend, dt, dtd.tableLog); - } - - /* check */ - if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected); - - /* decoded size */ - return dstSize; -} - - -FORCE_INLINE_TEMPLATE size_t -HUF_decompress4X2_usingDTable_internal_body( - void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize, - const HUF_DTable* DTable) -{ - if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ - - { const BYTE* const istart = (const BYTE*) cSrc; - BYTE* const ostart = (BYTE*) dst; - BYTE* const oend = ostart + dstSize; - const void* const dtPtr = DTable+1; - const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr; - - /* Init */ - BIT_DStream_t bitD1; - BIT_DStream_t bitD2; - BIT_DStream_t bitD3; - BIT_DStream_t bitD4; - size_t const length1 = MEM_readLE16(istart); - size_t const length2 = MEM_readLE16(istart+2); - size_t const length3 = MEM_readLE16(istart+4); - size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6); - const BYTE* const istart1 = istart + 6; /* jumpTable */ - const BYTE* const istart2 = istart1 + length1; - const BYTE* const istart3 = istart2 + length2; - const BYTE* const istart4 = istart3 + length3; - size_t const segmentSize = (dstSize+3) / 4; - BYTE* const opStart2 = ostart + segmentSize; - BYTE* const opStart3 = opStart2 + segmentSize; - BYTE* const opStart4 = opStart3 + segmentSize; - BYTE* op1 = ostart; - BYTE* op2 = opStart2; - BYTE* op3 = opStart3; - BYTE* op4 = opStart4; - U32 endSignal; - DTableDesc const dtd = HUF_getDTableDesc(DTable); - U32 const dtLog = dtd.tableLog; - - if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ - CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); - CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); - CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); - CHECK_F( BIT_initDStream(&bitD4, istart4, length4) ); - - /* 16-32 symbols per loop (4-8 symbols per stream) */ - endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); - for ( ; (endSignal==BIT_DStream_unfinished) & (op4<(oend-(sizeof(bitD4.bitContainer)-1))) ; ) { - HUF_DECODE_SYMBOLX2_2(op1, &bitD1); - HUF_DECODE_SYMBOLX2_2(op2, &bitD2); - HUF_DECODE_SYMBOLX2_2(op3, &bitD3); - HUF_DECODE_SYMBOLX2_2(op4, &bitD4); - HUF_DECODE_SYMBOLX2_1(op1, &bitD1); - HUF_DECODE_SYMBOLX2_1(op2, &bitD2); - HUF_DECODE_SYMBOLX2_1(op3, &bitD3); - HUF_DECODE_SYMBOLX2_1(op4, &bitD4); - HUF_DECODE_SYMBOLX2_2(op1, &bitD1); - HUF_DECODE_SYMBOLX2_2(op2, &bitD2); - HUF_DECODE_SYMBOLX2_2(op3, &bitD3); - HUF_DECODE_SYMBOLX2_2(op4, &bitD4); - HUF_DECODE_SYMBOLX2_0(op1, &bitD1); - HUF_DECODE_SYMBOLX2_0(op2, &bitD2); - HUF_DECODE_SYMBOLX2_0(op3, &bitD3); - HUF_DECODE_SYMBOLX2_0(op4, &bitD4); - - endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); - } - - /* check corruption */ - if (op1 > opStart2) return ERROR(corruption_detected); - if (op2 > opStart3) return ERROR(corruption_detected); - if (op3 > opStart4) return ERROR(corruption_detected); - /* note : op4 already verified within main loop */ - - /* finish bitStreams one by one */ - HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog); - HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog); - HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog); - HUF_decodeStreamX2(op4, &bitD4, oend, dt, dtLog); - - /* check */ - { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4); - if (!endCheck) return ERROR(corruption_detected); } - - /* decoded size */ - return dstSize; - } -} - -HUF_DGEN(HUF_decompress1X2_usingDTable_internal) -HUF_DGEN(HUF_decompress4X2_usingDTable_internal) - -size_t HUF_decompress1X2_usingDTable( - void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize, - const HUF_DTable* DTable) -{ - DTableDesc dtd = HUF_getDTableDesc(DTable); - if (dtd.tableType != 1) return ERROR(GENERIC); - return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0); -} - -size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize, - void* workSpace, size_t wkspSize) -{ - const BYTE* ip = (const BYTE*) cSrc; - - size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize, - workSpace, wkspSize); - if (HUF_isError(hSize)) return hSize; - if (hSize >= cSrcSize) return ERROR(srcSize_wrong); - ip += hSize; cSrcSize -= hSize; - - return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, /* bmi2 */ 0); -} - - -size_t HUF_decompress1X2_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_decompress1X2_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize, - workSpace, sizeof(workSpace)); -} - -size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ - HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX); - return HUF_decompress1X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize); -} - -size_t HUF_decompress4X2_usingDTable( - void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize, - const HUF_DTable* DTable) -{ - DTableDesc dtd = HUF_getDTableDesc(DTable); - if (dtd.tableType != 1) return ERROR(GENERIC); - return HUF_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0); -} - -static size_t HUF_decompress4X2_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize, - void* workSpace, size_t wkspSize, int bmi2) -{ - const BYTE* ip = (const BYTE*) cSrc; - - size_t hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize, - workSpace, wkspSize); - if (HUF_isError(hSize)) return hSize; - if (hSize >= cSrcSize) return ERROR(srcSize_wrong); - ip += hSize; cSrcSize -= hSize; - - return HUF_decompress4X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, bmi2); -} - -size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize, - void* workSpace, size_t wkspSize) -{ - return HUF_decompress4X2_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, /* bmi2 */ 0); -} - - -size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, - workSpace, sizeof(workSpace)); -} - -size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ - HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX); - return HUF_decompress4X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize); -} - - -/* ***********************************/ -/* Universal decompression selectors */ -/* ***********************************/ - -size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, - const void* cSrc, size_t cSrcSize, - const HUF_DTable* DTable) -{ - DTableDesc const dtd = HUF_getDTableDesc(DTable); - return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0) : - HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0); -} - -size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, - const void* cSrc, size_t cSrcSize, - const HUF_DTable* DTable) -{ - DTableDesc const dtd = HUF_getDTableDesc(DTable); - return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0) : - HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0); -} - - -typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t; -static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] = -{ - /* single, double, quad */ - {{0,0}, {1,1}, {2,2}}, /* Q==0 : impossible */ - {{0,0}, {1,1}, {2,2}}, /* Q==1 : impossible */ - {{ 38,130}, {1313, 74}, {2151, 38}}, /* Q == 2 : 12-18% */ - {{ 448,128}, {1353, 74}, {2238, 41}}, /* Q == 3 : 18-25% */ - {{ 556,128}, {1353, 74}, {2238, 47}}, /* Q == 4 : 25-32% */ - {{ 714,128}, {1418, 74}, {2436, 53}}, /* Q == 5 : 32-38% */ - {{ 883,128}, {1437, 74}, {2464, 61}}, /* Q == 6 : 38-44% */ - {{ 897,128}, {1515, 75}, {2622, 68}}, /* Q == 7 : 44-50% */ - {{ 926,128}, {1613, 75}, {2730, 75}}, /* Q == 8 : 50-56% */ - {{ 947,128}, {1729, 77}, {3359, 77}}, /* Q == 9 : 56-62% */ - {{1107,128}, {2083, 81}, {4006, 84}}, /* Q ==10 : 62-69% */ - {{1177,128}, {2379, 87}, {4785, 88}}, /* Q ==11 : 69-75% */ - {{1242,128}, {2415, 93}, {5155, 84}}, /* Q ==12 : 75-81% */ - {{1349,128}, {2644,106}, {5260,106}}, /* Q ==13 : 81-87% */ - {{1455,128}, {2422,124}, {4174,124}}, /* Q ==14 : 87-93% */ - {{ 722,128}, {1891,145}, {1936,146}}, /* Q ==15 : 93-99% */ -}; - -/** HUF_selectDecoder() : - * Tells which decoder is likely to decode faster, - * based on a set of pre-computed metrics. - * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 . - * Assumption : 0 < dstSize <= 128 KB */ -U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize) -{ - assert(dstSize > 0); - assert(dstSize <= 128*1024); - /* decoder timing evaluation */ - { U32 const Q = (cSrcSize >= dstSize) ? 15 : (U32)(cSrcSize * 16 / dstSize); /* Q < 16 */ - U32 const D256 = (U32)(dstSize >> 8); - U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256); - U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256); - DTime1 += DTime1 >> 3; /* advantage to algorithm using less memory, to reduce cache eviction */ - return DTime1 < DTime0; -} } - - -typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); - -size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ - static const decompressionAlgo decompress[2] = { HUF_decompress4X1, HUF_decompress4X2 }; - - /* validation checks */ - if (dstSize == 0) return ERROR(dstSize_tooSmall); - if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */ - if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */ - if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ - - { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); - return decompress[algoNb](dst, dstSize, cSrc, cSrcSize); - } -} - -size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ - /* validation checks */ - if (dstSize == 0) return ERROR(dstSize_tooSmall); - if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */ - if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */ - if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ - - { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); - return algoNb ? HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) : - HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ; - } -} - -size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_decompress4X_hufOnly_wksp(dctx, dst, dstSize, cSrc, cSrcSize, - workSpace, sizeof(workSpace)); -} - - -size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, - size_t dstSize, const void* cSrc, - size_t cSrcSize, void* workSpace, - size_t wkspSize) -{ - /* validation checks */ - if (dstSize == 0) return ERROR(dstSize_tooSmall); - if (cSrcSize == 0) return ERROR(corruption_detected); - - { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); - return algoNb ? HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize): - HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize); - } -} - -size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize, - void* workSpace, size_t wkspSize) -{ - /* validation checks */ - if (dstSize == 0) return ERROR(dstSize_tooSmall); - if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */ - if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */ - if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ - - { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); - return algoNb ? HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc, - cSrcSize, workSpace, wkspSize): - HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc, - cSrcSize, workSpace, wkspSize); - } -} - -size_t HUF_decompress1X_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, - const void* cSrc, size_t cSrcSize) -{ - U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; - return HUF_decompress1X_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, - workSpace, sizeof(workSpace)); -} - - -size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2) -{ - DTableDesc const dtd = HUF_getDTableDesc(DTable); - return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2) : - HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2); -} - -size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2) -{ - const BYTE* ip = (const BYTE*) cSrc; - - size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize); - if (HUF_isError(hSize)) return hSize; - if (hSize >= cSrcSize) return ERROR(srcSize_wrong); - ip += hSize; cSrcSize -= hSize; - - return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, bmi2); -} - -size_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2) -{ - DTableDesc const dtd = HUF_getDTableDesc(DTable); - return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2) : - HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2); -} - -size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2) -{ - /* validation checks */ - if (dstSize == 0) return ERROR(dstSize_tooSmall); - if (cSrcSize == 0) return ERROR(corruption_detected); - - { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); - return algoNb ? HUF_decompress4X2_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2) : - HUF_decompress4X1_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2); - } -} diff --git a/grub-core/lib/zstd/mem.h b/grub-core/lib/zstd/mem.h deleted file mode 100644 index 2051bcad1..000000000 --- a/grub-core/lib/zstd/mem.h +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ - -#ifndef MEM_H_MODULE -#define MEM_H_MODULE - -#if defined (__cplusplus) -extern "C" { -#endif - -/*-**************************************** -* Dependencies -******************************************/ -#include /* size_t, ptrdiff_t */ -#include /* memcpy */ - - -/*-**************************************** -* Compiler specifics -******************************************/ -#if defined(_MSC_VER) /* Visual Studio */ -# include /* _byteswap_ulong */ -# include /* _byteswap_* */ -#endif -#if defined(__GNUC__) -# define MEM_STATIC static __inline __attribute__((unused)) -#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) -# define MEM_STATIC static inline -#elif defined(_MSC_VER) -# define MEM_STATIC static __inline -#else -# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ -#endif - -/* code only tested on 32 and 64 bits systems */ -#define MEM_STATIC_ASSERT(c) { enum { MEM_static_assert = 1/(int)(!!(c)) }; } -MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); } - - -/*-************************************************************** -* Basic Types -*****************************************************************/ -#if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include - typedef uint8_t BYTE; - typedef uint16_t U16; - typedef int16_t S16; - typedef uint32_t U32; - typedef int32_t S32; - typedef uint64_t U64; - typedef int64_t S64; -#else -# include -#if CHAR_BIT != 8 -# error "this implementation requires char to be exactly 8-bit type" -#endif - typedef unsigned char BYTE; -#if USHRT_MAX != 65535 -# error "this implementation requires short to be exactly 16-bit type" -#endif - typedef unsigned short U16; - typedef signed short S16; -#if UINT_MAX != 4294967295 -# error "this implementation requires int to be exactly 32-bit type" -#endif - typedef unsigned int U32; - typedef signed int S32; -/* note : there are no limits defined for long long type in C90. - * limits exist in C99, however, in such case, is preferred */ - typedef unsigned long long U64; - typedef signed long long S64; -#endif - - -/*-************************************************************** -* Memory I/O -*****************************************************************/ -/* MEM_FORCE_MEMORY_ACCESS : - * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. - * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. - * The below switch allow to select different access method for improved performance. - * Method 0 (default) : use `memcpy()`. Safe and portable. - * Method 1 : `__packed` statement. It depends on compiler extension (i.e., not portable). - * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. - * Method 2 : direct access. This method is portable but violate C standard. - * It can generate buggy code on targets depending on alignment. - * In some circumstances, it's the only known way to get the most performance (i.e. GCC + ARMv6) - * See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. - * Prefer these methods in priority order (0 > 1 > 2) - */ -#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) -# define MEM_FORCE_MEMORY_ACCESS 2 -# elif defined(__INTEL_COMPILER) || defined(__GNUC__) -# define MEM_FORCE_MEMORY_ACCESS 1 -# endif -#endif - -MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; } -MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; } - -MEM_STATIC unsigned MEM_isLittleEndian(void) -{ - const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ - return one.c[0]; -} - -#if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) - -/* violates C standard, by lying on structure alignment. -Only use if no other choice to achieve best performance on target platform */ -MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; } -MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; } -MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; } -MEM_STATIC size_t MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; } - -MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } -MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } -MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; } - -#elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1) - -/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ -/* currently only defined for gcc and icc */ -#if defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(WIN32)) - __pragma( pack(push, 1) ) - typedef struct { U16 v; } unalign16; - typedef struct { U32 v; } unalign32; - typedef struct { U64 v; } unalign64; - typedef struct { size_t v; } unalignArch; - __pragma( pack(pop) ) -#else - typedef struct { U16 v; } __attribute__((packed)) unalign16; - typedef struct { U32 v; } __attribute__((packed)) unalign32; - typedef struct { U64 v; } __attribute__((packed)) unalign64; - typedef struct { size_t v; } __attribute__((packed)) unalignArch; -#endif - -MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign16*)ptr)->v; } -MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign32*)ptr)->v; } -MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign64*)ptr)->v; } -MEM_STATIC size_t MEM_readST(const void* ptr) { return ((const unalignArch*)ptr)->v; } - -MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign16*)memPtr)->v = value; } -MEM_STATIC void MEM_write32(void* memPtr, U32 value) { ((unalign32*)memPtr)->v = value; } -MEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((unalign64*)memPtr)->v = value; } - -#else - -/* default method, safe and standard. - can sometimes prove slower */ - -MEM_STATIC U16 MEM_read16(const void* memPtr) -{ - U16 val; memcpy(&val, memPtr, sizeof(val)); return val; -} - -MEM_STATIC U32 MEM_read32(const void* memPtr) -{ - U32 val; memcpy(&val, memPtr, sizeof(val)); return val; -} - -MEM_STATIC U64 MEM_read64(const void* memPtr) -{ - U64 val; memcpy(&val, memPtr, sizeof(val)); return val; -} - -MEM_STATIC size_t MEM_readST(const void* memPtr) -{ - size_t val; memcpy(&val, memPtr, sizeof(val)); return val; -} - -MEM_STATIC void MEM_write16(void* memPtr, U16 value) -{ - memcpy(memPtr, &value, sizeof(value)); -} - -MEM_STATIC void MEM_write32(void* memPtr, U32 value) -{ - memcpy(memPtr, &value, sizeof(value)); -} - -MEM_STATIC void MEM_write64(void* memPtr, U64 value) -{ - memcpy(memPtr, &value, sizeof(value)); -} - -#endif /* MEM_FORCE_MEMORY_ACCESS */ - -MEM_STATIC U32 MEM_swap32(U32 in) -{ -#if defined(_MSC_VER) /* Visual Studio */ - return _byteswap_ulong(in); -#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403) - return __builtin_bswap32(in); -#else - return ((in << 24) & 0xff000000 ) | - ((in << 8) & 0x00ff0000 ) | - ((in >> 8) & 0x0000ff00 ) | - ((in >> 24) & 0x000000ff ); -#endif -} - -MEM_STATIC U64 MEM_swap64(U64 in) -{ -#if defined(_MSC_VER) /* Visual Studio */ - return _byteswap_uint64(in); -#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403) - return __builtin_bswap64(in); -#else - return ((in << 56) & 0xff00000000000000ULL) | - ((in << 40) & 0x00ff000000000000ULL) | - ((in << 24) & 0x0000ff0000000000ULL) | - ((in << 8) & 0x000000ff00000000ULL) | - ((in >> 8) & 0x00000000ff000000ULL) | - ((in >> 24) & 0x0000000000ff0000ULL) | - ((in >> 40) & 0x000000000000ff00ULL) | - ((in >> 56) & 0x00000000000000ffULL); -#endif -} - -MEM_STATIC size_t MEM_swapST(size_t in) -{ - if (MEM_32bits()) - return (size_t)MEM_swap32((U32)in); - else - return (size_t)MEM_swap64((U64)in); -} - -/*=== Little endian r/w ===*/ - -MEM_STATIC U16 MEM_readLE16(const void* memPtr) -{ - if (MEM_isLittleEndian()) - return MEM_read16(memPtr); - else { - const BYTE* p = (const BYTE*)memPtr; - return (U16)(p[0] + (p[1]<<8)); - } -} - -MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val) -{ - if (MEM_isLittleEndian()) { - MEM_write16(memPtr, val); - } else { - BYTE* p = (BYTE*)memPtr; - p[0] = (BYTE)val; - p[1] = (BYTE)(val>>8); - } -} - -MEM_STATIC U32 MEM_readLE24(const void* memPtr) -{ - return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16); -} - -MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val) -{ - MEM_writeLE16(memPtr, (U16)val); - ((BYTE*)memPtr)[2] = (BYTE)(val>>16); -} - -MEM_STATIC U32 MEM_readLE32(const void* memPtr) -{ - if (MEM_isLittleEndian()) - return MEM_read32(memPtr); - else - return MEM_swap32(MEM_read32(memPtr)); -} - -MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32) -{ - if (MEM_isLittleEndian()) - MEM_write32(memPtr, val32); - else - MEM_write32(memPtr, MEM_swap32(val32)); -} - -MEM_STATIC U64 MEM_readLE64(const void* memPtr) -{ - if (MEM_isLittleEndian()) - return MEM_read64(memPtr); - else - return MEM_swap64(MEM_read64(memPtr)); -} - -MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64) -{ - if (MEM_isLittleEndian()) - MEM_write64(memPtr, val64); - else - MEM_write64(memPtr, MEM_swap64(val64)); -} - -MEM_STATIC size_t MEM_readLEST(const void* memPtr) -{ - if (MEM_32bits()) - return (size_t)MEM_readLE32(memPtr); - else - return (size_t)MEM_readLE64(memPtr); -} - -MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val) -{ - if (MEM_32bits()) - MEM_writeLE32(memPtr, (U32)val); - else - MEM_writeLE64(memPtr, (U64)val); -} - -/*=== Big endian r/w ===*/ - -MEM_STATIC U32 MEM_readBE32(const void* memPtr) -{ - if (MEM_isLittleEndian()) - return MEM_swap32(MEM_read32(memPtr)); - else - return MEM_read32(memPtr); -} - -MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32) -{ - if (MEM_isLittleEndian()) - MEM_write32(memPtr, MEM_swap32(val32)); - else - MEM_write32(memPtr, val32); -} - -MEM_STATIC U64 MEM_readBE64(const void* memPtr) -{ - if (MEM_isLittleEndian()) - return MEM_swap64(MEM_read64(memPtr)); - else - return MEM_read64(memPtr); -} - -MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64) -{ - if (MEM_isLittleEndian()) - MEM_write64(memPtr, MEM_swap64(val64)); - else - MEM_write64(memPtr, val64); -} - -MEM_STATIC size_t MEM_readBEST(const void* memPtr) -{ - if (MEM_32bits()) - return (size_t)MEM_readBE32(memPtr); - else - return (size_t)MEM_readBE64(memPtr); -} - -MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val) -{ - if (MEM_32bits()) - MEM_writeBE32(memPtr, (U32)val); - else - MEM_writeBE64(memPtr, (U64)val); -} - - -#if defined (__cplusplus) -} -#endif - -#endif /* MEM_H_MODULE */ diff --git a/grub-core/lib/zstd/module.c b/grub-core/lib/zstd/module.c deleted file mode 100644 index e64d068f4..000000000 --- a/grub-core/lib/zstd/module.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -GRUB_MOD_LICENSE ("GPLv3"); diff --git a/grub-core/lib/zstd/xxhash.c b/grub-core/lib/zstd/xxhash.c deleted file mode 100644 index 532b81619..000000000 --- a/grub-core/lib/zstd/xxhash.c +++ /dev/null @@ -1,876 +0,0 @@ -/* -* xxHash - Fast Hash algorithm -* Copyright (C) 2012-2016, Yann Collet -* -* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * 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 COPYRIGHT HOLDERS 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 COPYRIGHT -* OWNER 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. -* -* You can contact the author at : -* - xxHash homepage: http://www.xxhash.com -* - xxHash source repository : https://github.com/Cyan4973/xxHash -*/ - - -/* ************************************* -* Tuning parameters -***************************************/ -/*!XXH_FORCE_MEMORY_ACCESS : - * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. - * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. - * The below switch allow to select different access method for improved performance. - * Method 0 (default) : use `memcpy()`. Safe and portable. - * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). - * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. - * Method 2 : direct access. This method doesn't depend on compiler but violate C standard. - * It can generate buggy code on targets which do not support unaligned memory accesses. - * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) - * See http://stackoverflow.com/a/32095106/646947 for details. - * Prefer these methods in priority order (0 > 1 > 2) - */ -#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) -# define XXH_FORCE_MEMORY_ACCESS 2 -# elif (defined(__INTEL_COMPILER) && !defined(WIN32)) || \ - (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) -# define XXH_FORCE_MEMORY_ACCESS 1 -# endif -#endif - -/*!XXH_ACCEPT_NULL_INPUT_POINTER : - * If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer. - * When this option is enabled, xxHash output for null input pointers will be the same as a null-length input. - * By default, this option is disabled. To enable it, uncomment below define : - */ -/* #define XXH_ACCEPT_NULL_INPUT_POINTER 1 */ - -/*!XXH_FORCE_NATIVE_FORMAT : - * By default, xxHash library provides endian-independant Hash values, based on little-endian convention. - * Results are therefore identical for little-endian and big-endian CPU. - * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. - * Should endian-independance be of no importance for your application, you may set the #define below to 1, - * to improve speed for Big-endian CPU. - * This option has no impact on Little_Endian CPU. - */ -#ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */ -# define XXH_FORCE_NATIVE_FORMAT 0 -#endif - -/*!XXH_FORCE_ALIGN_CHECK : - * This is a minor performance trick, only useful with lots of very small keys. - * It means : check for aligned/unaligned input. - * The check costs one initial branch per hash; set to 0 when the input data - * is guaranteed to be aligned. - */ -#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ -# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) -# define XXH_FORCE_ALIGN_CHECK 0 -# else -# define XXH_FORCE_ALIGN_CHECK 1 -# endif -#endif - - -/* ************************************* -* Includes & Memory related functions -***************************************/ -/* Modify the local functions below should you wish to use some other memory routines */ -/* for malloc(), free() */ -#include -#include /* size_t */ -static void* XXH_malloc(size_t s) { return malloc(s); } -static void XXH_free (void* p) { free(p); } -/* for memcpy() */ -#include -static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); } - -#ifndef XXH_STATIC_LINKING_ONLY -# define XXH_STATIC_LINKING_ONLY -#endif -#include "xxhash.h" - - -/* ************************************* -* Compiler Specific Options -***************************************/ -#if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ -# define INLINE_KEYWORD inline -#else -# define INLINE_KEYWORD -#endif - -#if defined(__GNUC__) -# define FORCE_INLINE_ATTR __attribute__((always_inline)) -#elif defined(_MSC_VER) -# define FORCE_INLINE_ATTR __forceinline -#else -# define FORCE_INLINE_ATTR -#endif - -#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR - - -#ifdef _MSC_VER -# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ -#endif - - -/* ************************************* -* Basic Types -***************************************/ -#ifndef MEM_MODULE -# define MEM_MODULE -# if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include - typedef uint8_t BYTE; - typedef uint16_t U16; - typedef uint32_t U32; - typedef int32_t S32; - typedef uint64_t U64; -# else - typedef unsigned char BYTE; - typedef unsigned short U16; - typedef unsigned int U32; - typedef signed int S32; - typedef unsigned long long U64; /* if your compiler doesn't support unsigned long long, replace by another 64-bit type here. Note that xxhash.h will also need to be updated. */ -# endif -#endif - - -#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) - -/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ -static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; } -static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; } - -#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) - -/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ -/* currently only defined for gcc and icc */ -typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign; - -static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } -static U64 XXH_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } - -#else - -/* portable and safe solution. Generally efficient. - * see : http://stackoverflow.com/a/32095106/646947 - */ - -static U32 XXH_read32(const void* memPtr) -{ - U32 val; - memcpy(&val, memPtr, sizeof(val)); - return val; -} - -static U64 XXH_read64(const void* memPtr) -{ - U64 val; - memcpy(&val, memPtr, sizeof(val)); - return val; -} - -#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ - - -/* **************************************** -* Compiler-specific Functions and Macros -******************************************/ -#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) - -/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */ -#if defined(_MSC_VER) -# define XXH_rotl32(x,r) _rotl(x,r) -# define XXH_rotl64(x,r) _rotl64(x,r) -#else -# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) -# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r))) -#endif - -#if defined(_MSC_VER) /* Visual Studio */ -# define XXH_swap32 _byteswap_ulong -# define XXH_swap64 _byteswap_uint64 -#elif GCC_VERSION >= 403 -# define XXH_swap32 __builtin_bswap32 -# define XXH_swap64 __builtin_bswap64 -#else -static U32 XXH_swap32 (U32 x) -{ - return ((x << 24) & 0xff000000 ) | - ((x << 8) & 0x00ff0000 ) | - ((x >> 8) & 0x0000ff00 ) | - ((x >> 24) & 0x000000ff ); -} -static U64 XXH_swap64 (U64 x) -{ - return ((x << 56) & 0xff00000000000000ULL) | - ((x << 40) & 0x00ff000000000000ULL) | - ((x << 24) & 0x0000ff0000000000ULL) | - ((x << 8) & 0x000000ff00000000ULL) | - ((x >> 8) & 0x00000000ff000000ULL) | - ((x >> 24) & 0x0000000000ff0000ULL) | - ((x >> 40) & 0x000000000000ff00ULL) | - ((x >> 56) & 0x00000000000000ffULL); -} -#endif - - -/* ************************************* -* Architecture Macros -***************************************/ -typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; - -/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */ -#ifndef XXH_CPU_LITTLE_ENDIAN - static const int g_one = 1; -# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&g_one)) -#endif - - -/* *************************** -* Memory reads -*****************************/ -typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; - -FORCE_INLINE_TEMPLATE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align) -{ - if (align==XXH_unaligned) - return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)); - else - return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr); -} - -FORCE_INLINE_TEMPLATE U32 XXH_readLE32(const void* ptr, XXH_endianess endian) -{ - return XXH_readLE32_align(ptr, endian, XXH_unaligned); -} - -static U32 XXH_readBE32(const void* ptr) -{ - return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr); -} - -FORCE_INLINE_TEMPLATE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align) -{ - if (align==XXH_unaligned) - return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr)); - else - return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr); -} - -FORCE_INLINE_TEMPLATE U64 XXH_readLE64(const void* ptr, XXH_endianess endian) -{ - return XXH_readLE64_align(ptr, endian, XXH_unaligned); -} - -static U64 XXH_readBE64(const void* ptr) -{ - return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr); -} - - -/* ************************************* -* Macros -***************************************/ -#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ - - -/* ************************************* -* Constants -***************************************/ -static const U32 PRIME32_1 = 2654435761U; -static const U32 PRIME32_2 = 2246822519U; -static const U32 PRIME32_3 = 3266489917U; -static const U32 PRIME32_4 = 668265263U; -static const U32 PRIME32_5 = 374761393U; - -static const U64 PRIME64_1 = 11400714785074694791ULL; -static const U64 PRIME64_2 = 14029467366897019727ULL; -static const U64 PRIME64_3 = 1609587929392839161ULL; -static const U64 PRIME64_4 = 9650029242287828579ULL; -static const U64 PRIME64_5 = 2870177450012600261ULL; - -XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } - - -/* ************************** -* Utils -****************************/ -XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dstState, const XXH32_state_t* restrict srcState) -{ - memcpy(dstState, srcState, sizeof(*dstState)); -} - -XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dstState, const XXH64_state_t* restrict srcState) -{ - memcpy(dstState, srcState, sizeof(*dstState)); -} - - -/* *************************** -* Simple Hash Functions -*****************************/ - -static U32 XXH32_round(U32 seed, U32 input) -{ - seed += input * PRIME32_2; - seed = XXH_rotl32(seed, 13); - seed *= PRIME32_1; - return seed; -} - -FORCE_INLINE_TEMPLATE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* bEnd = p + len; - U32 h32; -#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align) - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) { - len=0; - bEnd=p=(const BYTE*)(size_t)16; - } -#endif - - if (len>=16) { - const BYTE* const limit = bEnd - 16; - U32 v1 = seed + PRIME32_1 + PRIME32_2; - U32 v2 = seed + PRIME32_2; - U32 v3 = seed + 0; - U32 v4 = seed - PRIME32_1; - - do { - v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4; - v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4; - v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4; - v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4; - } while (p<=limit); - - h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); - } else { - h32 = seed + PRIME32_5; - } - - h32 += (U32) len; - - while (p+4<=bEnd) { - h32 += XXH_get32bits(p) * PRIME32_3; - h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; - p+=4; - } - - while (p> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - - return h32; -} - - -XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed) -{ -#if 0 - /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ - XXH32_CREATESTATE_STATIC(state); - XXH32_reset(state, seed); - XXH32_update(state, input, len); - return XXH32_digest(state); -#else - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if (XXH_FORCE_ALIGN_CHECK) { - if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */ - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); - else - return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); - } } - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); - else - return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); -#endif -} - - -static U64 XXH64_round(U64 acc, U64 input) -{ - acc += input * PRIME64_2; - acc = XXH_rotl64(acc, 31); - acc *= PRIME64_1; - return acc; -} - -static U64 XXH64_mergeRound(U64 acc, U64 val) -{ - val = XXH64_round(0, val); - acc ^= val; - acc = acc * PRIME64_1 + PRIME64_4; - return acc; -} - -FORCE_INLINE_TEMPLATE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - U64 h64; -#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align) - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) { - len=0; - bEnd=p=(const BYTE*)(size_t)32; - } -#endif - - if (len>=32) { - const BYTE* const limit = bEnd - 32; - U64 v1 = seed + PRIME64_1 + PRIME64_2; - U64 v2 = seed + PRIME64_2; - U64 v3 = seed + 0; - U64 v4 = seed - PRIME64_1; - - do { - v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8; - v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8; - v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8; - v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8; - } while (p<=limit); - - h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); - h64 = XXH64_mergeRound(h64, v1); - h64 = XXH64_mergeRound(h64, v2); - h64 = XXH64_mergeRound(h64, v3); - h64 = XXH64_mergeRound(h64, v4); - - } else { - h64 = seed + PRIME64_5; - } - - h64 += (U64) len; - - while (p+8<=bEnd) { - U64 const k1 = XXH64_round(0, XXH_get64bits(p)); - h64 ^= k1; - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; - p+=8; - } - - if (p+4<=bEnd) { - h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; - h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; - p+=4; - } - - while (p> 33; - h64 *= PRIME64_2; - h64 ^= h64 >> 29; - h64 *= PRIME64_3; - h64 ^= h64 >> 32; - - return h64; -} - - -XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed) -{ -#if 0 - /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ - XXH64_CREATESTATE_STATIC(state); - XXH64_reset(state, seed); - XXH64_update(state, input, len); - return XXH64_digest(state); -#else - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if (XXH_FORCE_ALIGN_CHECK) { - if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */ - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); - else - return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); - } } - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); - else - return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); -#endif -} - - -/* ************************************************** -* Advanced Hash Functions -****************************************************/ - -XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void) -{ - return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); -} -XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) -{ - XXH_free(statePtr); - return XXH_OK; -} - -XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void) -{ - return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); -} -XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) -{ - XXH_free(statePtr); - return XXH_OK; -} - - -/*** Hash feed ***/ - -XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed) -{ - XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ - memset(&state, 0, sizeof(state)-4); /* do not write into reserved, for future removal */ - state.v1 = seed + PRIME32_1 + PRIME32_2; - state.v2 = seed + PRIME32_2; - state.v3 = seed + 0; - state.v4 = seed - PRIME32_1; - memcpy(statePtr, &state, sizeof(state)); - return XXH_OK; -} - - -XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed) -{ - XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ - memset(&state, 0, sizeof(state)-8); /* do not write into reserved, for future removal */ - state.v1 = seed + PRIME64_1 + PRIME64_2; - state.v2 = seed + PRIME64_2; - state.v3 = seed + 0; - state.v4 = seed - PRIME64_1; - memcpy(statePtr, &state, sizeof(state)); - return XXH_OK; -} - - -FORCE_INLINE_TEMPLATE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (input==NULL) return XXH_ERROR; -#endif - - state->total_len_32 += (unsigned)len; - state->large_len |= (len>=16) | (state->total_len_32>=16); - - if (state->memsize + len < 16) { /* fill in tmp buffer */ - XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len); - state->memsize += (unsigned)len; - return XXH_OK; - } - - if (state->memsize) { /* some data left from previous update */ - XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize); - { const U32* p32 = state->mem32; - state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++; - state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++; - state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++; - state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); p32++; - } - p += 16-state->memsize; - state->memsize = 0; - } - - if (p <= bEnd-16) { - const BYTE* const limit = bEnd - 16; - U32 v1 = state->v1; - U32 v2 = state->v2; - U32 v3 = state->v3; - U32 v4 = state->v4; - - do { - v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4; - v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4; - v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4; - v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4; - } while (p<=limit); - - state->v1 = v1; - state->v2 = v2; - state->v3 = v3; - state->v4 = v4; - } - - if (p < bEnd) { - XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); - } - - return XXH_OK; -} - -XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_update_endian(state_in, input, len, XXH_littleEndian); - else - return XXH32_update_endian(state_in, input, len, XXH_bigEndian); -} - - - -FORCE_INLINE_TEMPLATE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian) -{ - const BYTE * p = (const BYTE*)state->mem32; - const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize; - U32 h32; - - if (state->large_len) { - h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); - } else { - h32 = state->v3 /* == seed */ + PRIME32_5; - } - - h32 += state->total_len_32; - - while (p+4<=bEnd) { - h32 += XXH_readLE32(p, endian) * PRIME32_3; - h32 = XXH_rotl32(h32, 17) * PRIME32_4; - p+=4; - } - - while (p> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - - return h32; -} - - -XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_digest_endian(state_in, XXH_littleEndian); - else - return XXH32_digest_endian(state_in, XXH_bigEndian); -} - - - -/* **** XXH64 **** */ - -FORCE_INLINE_TEMPLATE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (input==NULL) return XXH_ERROR; -#endif - - state->total_len += len; - - if (state->memsize + len < 32) { /* fill in tmp buffer */ - XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len); - state->memsize += (U32)len; - return XXH_OK; - } - - if (state->memsize) { /* tmp buffer is full */ - XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize); - state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian)); - state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian)); - state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian)); - state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian)); - p += 32-state->memsize; - state->memsize = 0; - } - - if (p+32 <= bEnd) { - const BYTE* const limit = bEnd - 32; - U64 v1 = state->v1; - U64 v2 = state->v2; - U64 v3 = state->v3; - U64 v4 = state->v4; - - do { - v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8; - v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8; - v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8; - v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8; - } while (p<=limit); - - state->v1 = v1; - state->v2 = v2; - state->v3 = v3; - state->v4 = v4; - } - - if (p < bEnd) { - XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); - } - - return XXH_OK; -} - -XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_update_endian(state_in, input, len, XXH_littleEndian); - else - return XXH64_update_endian(state_in, input, len, XXH_bigEndian); -} - - - -FORCE_INLINE_TEMPLATE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian) -{ - const BYTE * p = (const BYTE*)state->mem64; - const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize; - U64 h64; - - if (state->total_len >= 32) { - U64 const v1 = state->v1; - U64 const v2 = state->v2; - U64 const v3 = state->v3; - U64 const v4 = state->v4; - - h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); - h64 = XXH64_mergeRound(h64, v1); - h64 = XXH64_mergeRound(h64, v2); - h64 = XXH64_mergeRound(h64, v3); - h64 = XXH64_mergeRound(h64, v4); - } else { - h64 = state->v3 + PRIME64_5; - } - - h64 += (U64) state->total_len; - - while (p+8<=bEnd) { - U64 const k1 = XXH64_round(0, XXH_readLE64(p, endian)); - h64 ^= k1; - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; - p+=8; - } - - if (p+4<=bEnd) { - h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1; - h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; - p+=4; - } - - while (p> 33; - h64 *= PRIME64_2; - h64 ^= h64 >> 29; - h64 *= PRIME64_3; - h64 ^= h64 >> 32; - - return h64; -} - - -XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_digest_endian(state_in, XXH_littleEndian); - else - return XXH64_digest_endian(state_in, XXH_bigEndian); -} - - -/* ************************** -* Canonical representation -****************************/ - -/*! Default XXH result types are basic unsigned 32 and 64 bits. -* The canonical representation follows human-readable write convention, aka big-endian (large digits first). -* These functions allow transformation of hash result into and from its canonical format. -* This way, hash values can be written into a file or buffer, and remain comparable across different systems and programs. -*/ - -XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) -{ - XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); - if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); - memcpy(dst, &hash, sizeof(*dst)); -} - -XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash) -{ - XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); - if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); - memcpy(dst, &hash, sizeof(*dst)); -} - -XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src) -{ - return XXH_readBE32(src); -} - -XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src) -{ - return XXH_readBE64(src); -} diff --git a/grub-core/lib/zstd/xxhash.h b/grub-core/lib/zstd/xxhash.h deleted file mode 100644 index 9bad1f59f..000000000 --- a/grub-core/lib/zstd/xxhash.h +++ /dev/null @@ -1,305 +0,0 @@ -/* - xxHash - Extremely Fast Hash algorithm - Header File - Copyright (C) 2012-2016, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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 COPYRIGHT HOLDERS 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 COPYRIGHT - OWNER 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. - - You can contact the author at : - - xxHash source repository : https://github.com/Cyan4973/xxHash -*/ - -/* Notice extracted from xxHash homepage : - -xxHash is an extremely fast Hash algorithm, running at RAM speed limits. -It also successfully passes all tests from the SMHasher suite. - -Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) - -Name Speed Q.Score Author -xxHash 5.4 GB/s 10 -CrapWow 3.2 GB/s 2 Andrew -MumurHash 3a 2.7 GB/s 10 Austin Appleby -SpookyHash 2.0 GB/s 10 Bob Jenkins -SBox 1.4 GB/s 9 Bret Mulvey -Lookup3 1.2 GB/s 9 Bob Jenkins -SuperFastHash 1.2 GB/s 1 Paul Hsieh -CityHash64 1.05 GB/s 10 Pike & Alakuijala -FNV 0.55 GB/s 5 Fowler, Noll, Vo -CRC32 0.43 GB/s 9 -MD5-32 0.33 GB/s 10 Ronald L. Rivest -SHA1-32 0.28 GB/s 10 - -Q.Score is a measure of quality of the hash function. -It depends on successfully passing SMHasher test set. -10 is a perfect score. - -A 64-bits version, named XXH64, is available since r35. -It offers much better speed, but for 64-bits applications only. -Name Speed on 64 bits Speed on 32 bits -XXH64 13.8 GB/s 1.9 GB/s -XXH32 6.8 GB/s 6.0 GB/s -*/ - -#if defined (__cplusplus) -extern "C" { -#endif - -#ifndef XXHASH_H_5627135585666179 -#define XXHASH_H_5627135585666179 1 - - -/* **************************** -* Definitions -******************************/ -#include /* size_t */ -typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; - - -/* **************************** -* API modifier -******************************/ -/** XXH_PRIVATE_API -* This is useful if you want to include xxhash functions in `static` mode -* in order to inline them, and remove their symbol from the public list. -* Methodology : -* #define XXH_PRIVATE_API -* #include "xxhash.h" -* `xxhash.c` is automatically included. -* It's not useful to compile and link it as a separate module anymore. -*/ -#ifdef XXH_PRIVATE_API -# ifndef XXH_STATIC_LINKING_ONLY -# define XXH_STATIC_LINKING_ONLY -# endif -# if defined(__GNUC__) -# define XXH_PUBLIC_API static __inline __attribute__((unused)) -# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) -# define XXH_PUBLIC_API static inline -# elif defined(_MSC_VER) -# define XXH_PUBLIC_API static __inline -# else -# define XXH_PUBLIC_API static /* this version may generate warnings for unused static functions; disable the relevant warning */ -# endif -#else -# define XXH_PUBLIC_API /* do nothing */ -#endif /* XXH_PRIVATE_API */ - -/*!XXH_NAMESPACE, aka Namespace Emulation : - -If you want to include _and expose_ xxHash functions from within your own library, -but also want to avoid symbol collisions with another library which also includes xxHash, - -you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library -with the value of XXH_NAMESPACE (so avoid to keep it NULL and avoid numeric values). - -Note that no change is required within the calling program as long as it includes `xxhash.h` : -regular symbol name will be automatically translated by this header. -*/ -#ifdef XXH_NAMESPACE -# define XXH_CAT(A,B) A##B -# define XXH_NAME2(A,B) XXH_CAT(A,B) -# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) -# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) -# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber) -# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) -# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) -# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) -# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) -# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) -# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) -# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) -# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) -# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) -# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) -# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState) -# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) -# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash) -# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash) -# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical) -# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical) -#endif - - -/* ************************************* -* Version -***************************************/ -#define XXH_VERSION_MAJOR 0 -#define XXH_VERSION_MINOR 6 -#define XXH_VERSION_RELEASE 2 -#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) -XXH_PUBLIC_API unsigned XXH_versionNumber (void); - - -/* **************************** -* Simple Hash Functions -******************************/ -typedef unsigned int XXH32_hash_t; -typedef unsigned long long XXH64_hash_t; - -XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed); -XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed); - -/*! -XXH32() : - Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input". - The memory between input & input+length must be valid (allocated and read-accessible). - "seed" can be used to alter the result predictably. - Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s -XXH64() : - Calculate the 64-bits hash of sequence of length "len" stored at memory address "input". - "seed" can be used to alter the result predictably. - This function runs 2x faster on 64-bits systems, but slower on 32-bits systems (see benchmark). -*/ - - -/* **************************** -* Streaming Hash Functions -******************************/ -typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */ -typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ - -/*! State allocation, compatible with dynamic libraries */ - -XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void); -XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); - -XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void); -XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); - - -/* hash streaming */ - -XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed); -XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); -XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); - -XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed); -XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); -XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr); - -/* -These functions generate the xxHash of an input provided in multiple segments. -Note that, for small input, they are slower than single-call functions, due to state management. -For small input, prefer `XXH32()` and `XXH64()` . - -XXH state must first be allocated, using XXH*_createState() . - -Start a new hash by initializing state with a seed, using XXH*_reset(). - -Then, feed the hash state by calling XXH*_update() as many times as necessary. -Obviously, input must be allocated and read accessible. -The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. - -Finally, a hash value can be produced anytime, by using XXH*_digest(). -This function returns the nn-bits hash as an int or long long. - -It's still possible to continue inserting input into the hash state after a digest, -and generate some new hashes later on, by calling again XXH*_digest(). - -When done, free XXH state space if it was allocated dynamically. -*/ - - -/* ************************** -* Utils -****************************/ -#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* ! C99 */ -# define restrict /* disable restrict */ -#endif - -XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dst_state, const XXH32_state_t* restrict src_state); -XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dst_state, const XXH64_state_t* restrict src_state); - - -/* ************************** -* Canonical representation -****************************/ -/* Default result type for XXH functions are primitive unsigned 32 and 64 bits. -* The canonical representation uses human-readable write convention, aka big-endian (large digits first). -* These functions allow transformation of hash result into and from its canonical format. -* This way, hash values can be written into a file / memory, and remain comparable on different systems and programs. -*/ -typedef struct { unsigned char digest[4]; } XXH32_canonical_t; -typedef struct { unsigned char digest[8]; } XXH64_canonical_t; - -XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); -XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash); - -XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); -XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src); - -#endif /* XXHASH_H_5627135585666179 */ - - - -/* ================================================================================================ - This section contains definitions which are not guaranteed to remain stable. - They may change in future versions, becoming incompatible with a different version of the library. - They shall only be used with static linking. - Never use these definitions in association with dynamic linking ! -=================================================================================================== */ -#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXH_STATIC_H_3543687687345) -#define XXH_STATIC_H_3543687687345 - -/* These definitions are only meant to allow allocation of XXH state - statically, on stack, or in a struct for example. - Do not use members directly. */ - - struct XXH32_state_s { - unsigned total_len_32; - unsigned large_len; - unsigned v1; - unsigned v2; - unsigned v3; - unsigned v4; - unsigned mem32[4]; /* buffer defined as U32 for alignment */ - unsigned memsize; - unsigned reserved; /* never read nor write, will be removed in a future version */ - }; /* typedef'd to XXH32_state_t */ - - struct XXH64_state_s { - unsigned long long total_len; - unsigned long long v1; - unsigned long long v2; - unsigned long long v3; - unsigned long long v4; - unsigned long long mem64[4]; /* buffer defined as U64 for alignment */ - unsigned memsize; - unsigned reserved[2]; /* never read nor write, will be removed in a future version */ - }; /* typedef'd to XXH64_state_t */ - - -# ifdef XXH_PRIVATE_API -# include "xxhash.c" /* include xxhash functions as `static`, for inlining */ -# endif - -#endif /* XXH_STATIC_LINKING_ONLY && XXH_STATIC_H_3543687687345 */ - - -#if defined (__cplusplus) -} -#endif diff --git a/grub-core/lib/zstd/zstd.h b/grub-core/lib/zstd/zstd.h deleted file mode 100644 index 7b6964be3..000000000 --- a/grub-core/lib/zstd/zstd.h +++ /dev/null @@ -1,1516 +0,0 @@ -/* - * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ -#if defined (__cplusplus) -extern "C" { -#endif - -#ifndef ZSTD_H_235446 -#define ZSTD_H_235446 - -/* ====== Dependency ======*/ -#include /* size_t */ - - -/* ===== ZSTDLIB_API : control library symbols visibility ===== */ -#ifndef ZSTDLIB_VISIBILITY -# if defined(__GNUC__) && (__GNUC__ >= 4) -# define ZSTDLIB_VISIBILITY __attribute__ ((visibility ("default"))) -# else -# define ZSTDLIB_VISIBILITY -# endif -#endif -#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) -# define ZSTDLIB_API __declspec(dllexport) ZSTDLIB_VISIBILITY -#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) -# define ZSTDLIB_API __declspec(dllimport) ZSTDLIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ -#else -# define ZSTDLIB_API ZSTDLIB_VISIBILITY -#endif - - -/******************************************************************************* - Introduction - - zstd, short for Zstandard, is a fast lossless compression algorithm, targeting - real-time compression scenarios at zlib-level and better compression ratios. - The zstd compression library provides in-memory compression and decompression - functions. - - The library supports regular compression levels from 1 up to ZSTD_maxCLevel(), - which is currently 22. Levels >= 20, labeled `--ultra`, should be used with - caution, as they require more memory. The library also offers negative - compression levels, which extend the range of speed vs. ratio preferences. - The lower the level, the faster the speed (at the cost of compression). - - Compression can be done in: - - a single step (described as Simple API) - - a single step, reusing a context (described as Explicit context) - - unbounded multiple steps (described as Streaming compression) - - The compression ratio achievable on small data can be highly improved using - a dictionary. Dictionary compression can be performed in: - - a single step (described as Simple dictionary API) - - a single step, reusing a dictionary (described as Bulk-processing - dictionary API) - - Advanced experimental functions can be accessed using - `#define ZSTD_STATIC_LINKING_ONLY` before including zstd.h. - - Advanced experimental APIs should never be used with a dynamically-linked - library. They are not "stable"; their definitions or signatures may change in - the future. Only static linking is allowed. -*******************************************************************************/ - -/*------ Version ------*/ -#define ZSTD_VERSION_MAJOR 1 -#define ZSTD_VERSION_MINOR 3 -#define ZSTD_VERSION_RELEASE 6 - -#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) -ZSTDLIB_API unsigned ZSTD_versionNumber(void); /**< useful to check dll version */ - -#define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE -#define ZSTD_QUOTE(str) #str -#define ZSTD_EXPAND_AND_QUOTE(str) ZSTD_QUOTE(str) -#define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION) -ZSTDLIB_API const char* ZSTD_versionString(void); /* v1.3.0+ */ - -/*************************************** -* Default constant -***************************************/ -#ifndef ZSTD_CLEVEL_DEFAULT -# define ZSTD_CLEVEL_DEFAULT 3 -#endif - -/*************************************** -* Simple API -***************************************/ -/*! ZSTD_compress() : - * Compresses `src` content as a single zstd compressed frame into already allocated `dst`. - * Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`. - * @return : compressed size written into `dst` (<= `dstCapacity), - * or an error code if it fails (which can be tested using ZSTD_isError()). */ -ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - int compressionLevel); - -/*! ZSTD_decompress() : - * `compressedSize` : must be the _exact_ size of some number of compressed and/or skippable frames. - * `dstCapacity` is an upper bound of originalSize to regenerate. - * If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data. - * @return : the number of bytes decompressed into `dst` (<= `dstCapacity`), - * or an errorCode if it fails (which can be tested using ZSTD_isError()). */ -ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity, - const void* src, size_t compressedSize); - -/*! ZSTD_getFrameContentSize() : added in v1.3.0 - * `src` should point to the start of a ZSTD encoded frame. - * `srcSize` must be at least as large as the frame header. - * hint : any size >= `ZSTD_frameHeaderSize_max` is large enough. - * @return : - decompressed size of `src` frame content, if known - * - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined - * - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) - * note 1 : a 0 return value means the frame is valid but "empty". - * note 2 : decompressed size is an optional field, it may not be present, typically in streaming mode. - * When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size. - * In which case, it's necessary to use streaming mode to decompress data. - * Optionally, application can rely on some implicit limit, - * as ZSTD_decompress() only needs an upper bound of decompressed size. - * (For example, data could be necessarily cut into blocks <= 16 KB). - * note 3 : decompressed size is always present when compression is completed using single-pass functions, - * such as ZSTD_compress(), ZSTD_compressCCtx() ZSTD_compress_usingDict() or ZSTD_compress_usingCDict(). - * note 4 : decompressed size can be very large (64-bits value), - * potentially larger than what local system can handle as a single memory segment. - * In which case, it's necessary to use streaming mode to decompress data. - * note 5 : If source is untrusted, decompressed size could be wrong or intentionally modified. - * Always ensure return value fits within application's authorized limits. - * Each application can set its own limits. - * note 6 : This function replaces ZSTD_getDecompressedSize() */ -#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1) -#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2) -ZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize); - -/*! ZSTD_getDecompressedSize() : - * NOTE: This function is now obsolete, in favor of ZSTD_getFrameContentSize(). - * Both functions work the same way, but ZSTD_getDecompressedSize() blends - * "empty", "unknown" and "error" results to the same return value (0), - * while ZSTD_getFrameContentSize() gives them separate return values. - * @return : decompressed size of `src` frame content _if known and not empty_, 0 otherwise. */ -ZSTDLIB_API unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize); - - -/*====== Helper functions ======*/ -#define ZSTD_COMPRESSBOUND(srcSize) ((srcSize) + ((srcSize)>>8) + (((srcSize) < (128<<10)) ? (((128<<10) - (srcSize)) >> 11) /* margin, from 64 to 0 */ : 0)) /* this formula ensures that bound(A) + bound(B) <= bound(A+B) as long as A and B >= 128 KB */ -ZSTDLIB_API size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case single-pass scenario */ -ZSTDLIB_API unsigned ZSTD_isError(size_t code); /*!< tells if a `size_t` function result is an error code */ -ZSTDLIB_API const char* ZSTD_getErrorName(size_t code); /*!< provides readable string from an error code */ -ZSTDLIB_API int ZSTD_maxCLevel(void); /*!< maximum compression level available */ - - -/*************************************** -* Explicit context -***************************************/ -/*= Compression context - * When compressing many times, - * it is recommended to allocate a context just once, and re-use it for each successive compression operation. - * This will make workload friendlier for system's memory. - * Use one context per thread for parallel execution in multi-threaded environments. */ -typedef struct ZSTD_CCtx_s ZSTD_CCtx; -ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void); -ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); - -/*! ZSTD_compressCCtx() : - * Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()). */ -ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - int compressionLevel); - -/*= Decompression context - * When decompressing many times, - * it is recommended to allocate a context only once, - * and re-use it for each successive compression operation. - * This will make workload friendlier for system's memory. - * Use one context per thread for parallel execution. */ -typedef struct ZSTD_DCtx_s ZSTD_DCtx; -ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void); -ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); - -/*! ZSTD_decompressDCtx() : - * Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()) */ -ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize); - - -/************************** -* Simple dictionary API -***************************/ -/*! ZSTD_compress_usingDict() : - * Compression using a predefined Dictionary (see dictBuilder/zdict.h). - * Note : This function loads the dictionary, resulting in significant startup delay. - * Note : When `dict == NULL || dictSize < 8` no dictionary is used. */ -ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - const void* dict,size_t dictSize, - int compressionLevel); - -/*! ZSTD_decompress_usingDict() : - * Decompression using a predefined Dictionary (see dictBuilder/zdict.h). - * Dictionary must be identical to the one used during compression. - * Note : This function loads the dictionary, resulting in significant startup delay. - * Note : When `dict == NULL || dictSize < 8` no dictionary is used. */ -ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - const void* dict,size_t dictSize); - - -/********************************** - * Bulk processing dictionary API - *********************************/ -typedef struct ZSTD_CDict_s ZSTD_CDict; - -/*! ZSTD_createCDict() : - * When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once. - * ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay. - * ZSTD_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only. - * `dictBuffer` can be released after ZSTD_CDict creation, since its content is copied within CDict - * Note : A ZSTD_CDict can be created with an empty dictionary, but it is inefficient for small data. */ -ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize, - int compressionLevel); - -/*! ZSTD_freeCDict() : - * Function frees memory allocated by ZSTD_createCDict(). */ -ZSTDLIB_API size_t ZSTD_freeCDict(ZSTD_CDict* CDict); - -/*! ZSTD_compress_usingCDict() : - * Compression using a digested Dictionary. - * Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times. - * Note that compression level is decided during dictionary creation. - * Frame parameters are hardcoded (dictID=yes, contentSize=yes, checksum=no) - * Note : ZSTD_compress_usingCDict() can be used with a ZSTD_CDict created from an empty dictionary. - * But it is inefficient for small data, and it is recommended to use ZSTD_compressCCtx(). */ -ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - const ZSTD_CDict* cdict); - - -typedef struct ZSTD_DDict_s ZSTD_DDict; - -/*! ZSTD_createDDict() : - * Create a digested dictionary, ready to start decompression operation without startup delay. - * dictBuffer can be released after DDict creation, as its content is copied inside DDict */ -ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict(const void* dictBuffer, size_t dictSize); - -/*! ZSTD_freeDDict() : - * Function frees memory allocated with ZSTD_createDDict() */ -ZSTDLIB_API size_t ZSTD_freeDDict(ZSTD_DDict* ddict); - -/*! ZSTD_decompress_usingDDict() : - * Decompression using a digested Dictionary. - * Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times. */ -ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - const ZSTD_DDict* ddict); - - -/**************************** -* Streaming -****************************/ - -typedef struct ZSTD_inBuffer_s { - const void* src; /**< start of input buffer */ - size_t size; /**< size of input buffer */ - size_t pos; /**< position where reading stopped. Will be updated. Necessarily 0 <= pos <= size */ -} ZSTD_inBuffer; - -typedef struct ZSTD_outBuffer_s { - void* dst; /**< start of output buffer */ - size_t size; /**< size of output buffer */ - size_t pos; /**< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */ -} ZSTD_outBuffer; - - - -/*-*********************************************************************** -* Streaming compression - HowTo -* -* A ZSTD_CStream object is required to track streaming operation. -* Use ZSTD_createCStream() and ZSTD_freeCStream() to create/release resources. -* ZSTD_CStream objects can be reused multiple times on consecutive compression operations. -* It is recommended to re-use ZSTD_CStream in situations where many streaming operations will be achieved consecutively, -* since it will play nicer with system's memory, by re-using already allocated memory. -* Use one separate ZSTD_CStream per thread for parallel execution. -* -* Start a new compression by initializing ZSTD_CStream context. -* Use ZSTD_initCStream() to start a new compression operation. -* Use variants ZSTD_initCStream_usingDict() or ZSTD_initCStream_usingCDict() for streaming with dictionary (experimental section) -* -* Use ZSTD_compressStream() as many times as necessary to consume input stream. -* The function will automatically update both `pos` fields within `input` and `output`. -* Note that the function may not consume the entire input, -* for example, because the output buffer is already full, -* in which case `input.pos < input.size`. -* The caller must check if input has been entirely consumed. -* If not, the caller must make some room to receive more compressed data, -* typically by emptying output buffer, or allocating a new output buffer, -* and then present again remaining input data. -* @return : a size hint, preferred nb of bytes to use as input for next function call -* or an error code, which can be tested using ZSTD_isError(). -* Note 1 : it's just a hint, to help latency a little, any other value will work fine. -* Note 2 : size hint is guaranteed to be <= ZSTD_CStreamInSize() -* -* At any moment, it's possible to flush whatever data might remain stuck within internal buffer, -* using ZSTD_flushStream(). `output->pos` will be updated. -* Note that, if `output->size` is too small, a single invocation of ZSTD_flushStream() might not be enough (return code > 0). -* In which case, make some room to receive more compressed data, and call again ZSTD_flushStream(). -* @return : 0 if internal buffers are entirely flushed, -* >0 if some data still present within internal buffer (the value is minimal estimation of remaining size), -* or an error code, which can be tested using ZSTD_isError(). -* -* ZSTD_endStream() instructs to finish a frame. -* It will perform a flush and write frame epilogue. -* The epilogue is required for decoders to consider a frame completed. -* flush() operation is the same, and follows same rules as ZSTD_flushStream(). -* @return : 0 if frame fully completed and fully flushed, -* >0 if some data still present within internal buffer (the value is minimal estimation of remaining size), -* or an error code, which can be tested using ZSTD_isError(). -* -* *******************************************************************/ - -typedef ZSTD_CCtx ZSTD_CStream; /**< CCtx and CStream are now effectively same object (>= v1.3.0) */ - /* Continue to distinguish them for compatibility with older versions <= v1.2.0 */ -/*===== ZSTD_CStream management functions =====*/ -ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream(void); -ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream* zcs); - -/*===== Streaming compression functions =====*/ -ZSTDLIB_API size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel); -ZSTDLIB_API size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input); -ZSTDLIB_API size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output); -ZSTDLIB_API size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output); - -ZSTDLIB_API size_t ZSTD_CStreamInSize(void); /**< recommended size for input buffer */ -ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block in all circumstances. */ - - - -/*-*************************************************************************** -* Streaming decompression - HowTo -* -* A ZSTD_DStream object is required to track streaming operations. -* Use ZSTD_createDStream() and ZSTD_freeDStream() to create/release resources. -* ZSTD_DStream objects can be re-used multiple times. -* -* Use ZSTD_initDStream() to start a new decompression operation, -* or ZSTD_initDStream_usingDict() if decompression requires a dictionary. -* @return : recommended first input size -* -* Use ZSTD_decompressStream() repetitively to consume your input. -* The function will update both `pos` fields. -* If `input.pos < input.size`, some input has not been consumed. -* It's up to the caller to present again remaining data. -* If `output.pos < output.size`, decoder has flushed everything it could. -* @return : 0 when a frame is completely decoded and fully flushed, -* an error code, which can be tested using ZSTD_isError(), -* any other value > 0, which means there is still some decoding to do to complete current frame. -* The return value is a suggested next input size (a hint to improve latency) that will never load more than the current frame. -* *******************************************************************************/ - -typedef ZSTD_DCtx ZSTD_DStream; /**< DCtx and DStream are now effectively same object (>= v1.3.0) */ - /* For compatibility with versions <= v1.2.0, continue to consider them separated. */ -/*===== ZSTD_DStream management functions =====*/ -ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream(void); -ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream* zds); - -/*===== Streaming decompression functions =====*/ -ZSTDLIB_API size_t ZSTD_initDStream(ZSTD_DStream* zds); -ZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input); - -ZSTDLIB_API size_t ZSTD_DStreamInSize(void); /*!< recommended size for input buffer */ -ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */ - -#endif /* ZSTD_H_235446 */ - - - - -#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY) -#define ZSTD_H_ZSTD_STATIC_LINKING_ONLY - -/**************************************************************************************** - * ADVANCED AND EXPERIMENTAL FUNCTIONS - **************************************************************************************** - * The definitions in this section are considered experimental. - * They should never be used with a dynamic library, as prototypes may change in the future. - * They are provided for advanced scenarios. - * Use them only in association with static linking. - * ***************************************************************************************/ - -ZSTDLIB_API int ZSTD_minCLevel(void); /*!< minimum negative compression level allowed */ - -/* --- Constants ---*/ -#define ZSTD_MAGICNUMBER 0xFD2FB528 /* v0.8+ */ -#define ZSTD_MAGIC_DICTIONARY 0xEC30A437 /* v0.7+ */ -#define ZSTD_MAGIC_SKIPPABLE_START 0x184D2A50U - -#define ZSTD_BLOCKSIZELOG_MAX 17 -#define ZSTD_BLOCKSIZE_MAX (1<= first frame size - * @return : the compressed size of the first frame starting at `src`, - * suitable to pass to `ZSTD_decompress` or similar, - * or an error code if input is invalid */ -ZSTDLIB_API size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize); - -/*! ZSTD_findDecompressedSize() : - * `src` should point the start of a series of ZSTD encoded and/or skippable frames - * `srcSize` must be the _exact_ size of this series - * (i.e. there should be a frame boundary exactly at `srcSize` bytes after `src`) - * @return : - decompressed size of all data in all successive frames - * - if the decompressed size cannot be determined: ZSTD_CONTENTSIZE_UNKNOWN - * - if an error occurred: ZSTD_CONTENTSIZE_ERROR - * - * note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode. - * When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size. - * In which case, it's necessary to use streaming mode to decompress data. - * note 2 : decompressed size is always present when compression is done with ZSTD_compress() - * note 3 : decompressed size can be very large (64-bits value), - * potentially larger than what local system can handle as a single memory segment. - * In which case, it's necessary to use streaming mode to decompress data. - * note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified. - * Always ensure result fits within application's authorized limits. - * Each application can set its own limits. - * note 5 : ZSTD_findDecompressedSize handles multiple frames, and so it must traverse the input to - * read each contained frame header. This is fast as most of the data is skipped, - * however it does mean that all frame data must be present and valid. */ -ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize); - -/*! ZSTD_frameHeaderSize() : - * srcSize must be >= ZSTD_frameHeaderSize_prefix. - * @return : size of the Frame Header, - * or an error code (if srcSize is too small) */ -ZSTDLIB_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize); - - -/*************************************** -* Memory management -***************************************/ - -/*! ZSTD_sizeof_*() : - * These functions give the current memory usage of selected object. - * Object memory usage can evolve when re-used. */ -ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx); -ZSTDLIB_API size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx); -ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs); -ZSTDLIB_API size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds); -ZSTDLIB_API size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict); -ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict); - -/*! ZSTD_estimate*() : - * These functions make it possible to estimate memory usage - * of a future {D,C}Ctx, before its creation. - * ZSTD_estimateCCtxSize() will provide a budget large enough for any compression level up to selected one. - * It will also consider src size to be arbitrarily "large", which is worst case. - * If srcSize is known to always be small, ZSTD_estimateCCtxSize_usingCParams() can provide a tighter estimation. - * ZSTD_estimateCCtxSize_usingCParams() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. - * ZSTD_estimateCCtxSize_usingCCtxParams() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return an error code if ZSTD_p_nbWorkers is >= 1. - * Note : CCtx size estimation is only correct for single-threaded compression. */ -ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel); -ZSTDLIB_API size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams); -ZSTDLIB_API size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params); -ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void); - -/*! ZSTD_estimateCStreamSize() : - * ZSTD_estimateCStreamSize() will provide a budget large enough for any compression level up to selected one. - * It will also consider src size to be arbitrarily "large", which is worst case. - * If srcSize is known to always be small, ZSTD_estimateCStreamSize_usingCParams() can provide a tighter estimation. - * ZSTD_estimateCStreamSize_usingCParams() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. - * ZSTD_estimateCStreamSize_usingCCtxParams() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return an error code if ZSTD_p_nbWorkers is >= 1. - * Note : CStream size estimation is only correct for single-threaded compression. - * ZSTD_DStream memory budget depends on window Size. - * This information can be passed manually, using ZSTD_estimateDStreamSize, - * or deducted from a valid frame Header, using ZSTD_estimateDStreamSize_fromFrame(); - * Note : if streaming is init with function ZSTD_init?Stream_usingDict(), - * an internal ?Dict will be created, which additional size is not estimated here. - * In this case, get total size by adding ZSTD_estimate?DictSize */ -ZSTDLIB_API size_t ZSTD_estimateCStreamSize(int compressionLevel); -ZSTDLIB_API size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams); -ZSTDLIB_API size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params); -ZSTDLIB_API size_t ZSTD_estimateDStreamSize(size_t windowSize); -ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize); - -/*! ZSTD_estimate?DictSize() : - * ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict(). - * ZSTD_estimateCDictSize_advanced() makes it possible to control compression parameters precisely, like ZSTD_createCDict_advanced(). - * Note : dictionaries created by reference (`ZSTD_dlm_byRef`) are logically smaller. - */ -ZSTDLIB_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel); -ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, ZSTD_dictLoadMethod_e dictLoadMethod); -ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod); - -/*! ZSTD_initStatic*() : - * Initialize an object using a pre-allocated fixed-size buffer. - * workspace: The memory area to emplace the object into. - * Provided pointer *must be 8-bytes aligned*. - * Buffer must outlive object. - * workspaceSize: Use ZSTD_estimate*Size() to determine - * how large workspace must be to support target scenario. - * @return : pointer to object (same address as workspace, just different type), - * or NULL if error (size too small, incorrect alignment, etc.) - * Note : zstd will never resize nor malloc() when using a static buffer. - * If the object requires more memory than available, - * zstd will just error out (typically ZSTD_error_memory_allocation). - * Note 2 : there is no corresponding "free" function. - * Since workspace is allocated externally, it must be freed externally too. - * Note 3 : cParams : use ZSTD_getCParams() to convert a compression level - * into its associated cParams. - * Limitation 1 : currently not compatible with internal dictionary creation, triggered by - * ZSTD_CCtx_loadDictionary(), ZSTD_initCStream_usingDict() or ZSTD_initDStream_usingDict(). - * Limitation 2 : static cctx currently not compatible with multi-threading. - * Limitation 3 : static dctx is incompatible with legacy support. - */ -ZSTDLIB_API ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize); -ZSTDLIB_API ZSTD_CStream* ZSTD_initStaticCStream(void* workspace, size_t workspaceSize); /**< same as ZSTD_initStaticCCtx() */ - -ZSTDLIB_API ZSTD_DCtx* ZSTD_initStaticDCtx(void* workspace, size_t workspaceSize); -ZSTDLIB_API ZSTD_DStream* ZSTD_initStaticDStream(void* workspace, size_t workspaceSize); /**< same as ZSTD_initStaticDCtx() */ - -ZSTDLIB_API const ZSTD_CDict* ZSTD_initStaticCDict( - void* workspace, size_t workspaceSize, - const void* dict, size_t dictSize, - ZSTD_dictLoadMethod_e dictLoadMethod, - ZSTD_dictContentType_e dictContentType, - ZSTD_compressionParameters cParams); - -ZSTDLIB_API const ZSTD_DDict* ZSTD_initStaticDDict( - void* workspace, size_t workspaceSize, - const void* dict, size_t dictSize, - ZSTD_dictLoadMethod_e dictLoadMethod, - ZSTD_dictContentType_e dictContentType); - -/*! Custom memory allocation : - * These prototypes make it possible to pass your own allocation/free functions. - * ZSTD_customMem is provided at creation time, using ZSTD_create*_advanced() variants listed below. - * All allocation/free operations will be completed using these custom variants instead of regular ones. - */ -typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size); -typedef void (*ZSTD_freeFunction) (void* opaque, void* address); -typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem; -static ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */ - -ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem); -ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem); -ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem); -ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem); - -ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, - ZSTD_dictLoadMethod_e dictLoadMethod, - ZSTD_dictContentType_e dictContentType, - ZSTD_compressionParameters cParams, - ZSTD_customMem customMem); - -ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, - ZSTD_dictLoadMethod_e dictLoadMethod, - ZSTD_dictContentType_e dictContentType, - ZSTD_customMem customMem); - - - -/*************************************** -* Advanced compression functions -***************************************/ - -/*! ZSTD_createCDict_byReference() : - * Create a digested dictionary for compression - * Dictionary content is simply referenced, and therefore stays in dictBuffer. - * It is important that dictBuffer outlives CDict, it must remain read accessible throughout the lifetime of CDict */ -ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel); - -/*! ZSTD_getCParams() : -* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize. -* `estimatedSrcSize` value is optional, select 0 if not known */ -ZSTDLIB_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); - -/*! ZSTD_getParams() : -* same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of sub-component `ZSTD_compressionParameters`. -* All fields of `ZSTD_frameParameters` are set to default : contentSize=1, checksum=0, noDictID=0 */ -ZSTDLIB_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); - -/*! ZSTD_checkCParams() : -* Ensure param values remain within authorized range */ -ZSTDLIB_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params); - -/*! ZSTD_adjustCParams() : - * optimize params for a given `srcSize` and `dictSize`. - * both values are optional, select `0` if unknown. */ -ZSTDLIB_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize); - -/*! ZSTD_compress_advanced() : -* Same as ZSTD_compress_usingDict(), with fine-tune control over each compression parameter */ -ZSTDLIB_API size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - const void* dict,size_t dictSize, - ZSTD_parameters params); - -/*! ZSTD_compress_usingCDict_advanced() : -* Same as ZSTD_compress_usingCDict(), with fine-tune control over frame parameters */ -ZSTDLIB_API size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - const ZSTD_CDict* cdict, ZSTD_frameParameters fParams); - - -/*--- Advanced decompression functions ---*/ - -/*! ZSTD_isFrame() : - * Tells if the content of `buffer` starts with a valid Frame Identifier. - * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. - * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. - * Note 3 : Skippable Frame Identifiers are considered valid. */ -ZSTDLIB_API unsigned ZSTD_isFrame(const void* buffer, size_t size); - -/*! ZSTD_createDDict_byReference() : - * Create a digested dictionary, ready to start decompression operation without startup delay. - * Dictionary content is referenced, and therefore stays in dictBuffer. - * It is important that dictBuffer outlives DDict, - * it must remain read accessible throughout the lifetime of DDict */ -ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize); - - -/*! ZSTD_getDictID_fromDict() : - * Provides the dictID stored within dictionary. - * if @return == 0, the dictionary is not conformant with Zstandard specification. - * It can still be loaded, but as a content-only dictionary. */ -ZSTDLIB_API unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize); - -/*! ZSTD_getDictID_fromDDict() : - * Provides the dictID of the dictionary loaded into `ddict`. - * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. - * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ -ZSTDLIB_API unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict); - -/*! ZSTD_getDictID_fromFrame() : - * Provides the dictID required to decompressed the frame stored within `src`. - * If @return == 0, the dictID could not be decoded. - * This could for one of the following reasons : - * - The frame does not require a dictionary to be decoded (most common case). - * - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information. - * Note : this use case also happens when using a non-conformant dictionary. - * - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`). - * - This is not a Zstandard frame. - * When identifying the exact failure cause, it's possible to use ZSTD_getFrameHeader(), which will provide a more precise error code. */ -ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize); - - -/******************************************************************** -* Advanced streaming functions -********************************************************************/ - -/*===== Advanced Streaming compression functions =====*/ -ZSTDLIB_API size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize); /**< pledgedSrcSize must be correct. If it is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN. Note that, for compatibility with older programs, "0" also disables frame content size field. It may be enabled in the future. */ -ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< creates of an internal CDict (incompatible with static CCtx), except if dict == NULL or dictSize < 8, in which case no dict is used. Note: dict is loaded with ZSTD_dm_auto (treated as a full zstd dictionary if it begins with ZSTD_MAGIC_DICTIONARY, else as raw content) and ZSTD_dlm_byCopy.*/ -ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize, - ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize must be correct. If srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN. dict is loaded with ZSTD_dm_auto and ZSTD_dlm_byCopy. */ -ZSTDLIB_API size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict); /**< note : cdict will just be referenced, and must outlive compression session */ -ZSTDLIB_API size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, ZSTD_frameParameters fParams, unsigned long long pledgedSrcSize); /**< same as ZSTD_initCStream_usingCDict(), with control over frame parameters. pledgedSrcSize must be correct. If srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN. */ - -/*! ZSTD_resetCStream() : - * start a new compression job, using same parameters from previous job. - * This is typically useful to skip dictionary loading stage, since it will re-use it in-place. - * Note that zcs must be init at least once before using ZSTD_resetCStream(). - * If pledgedSrcSize is not known at reset time, use macro ZSTD_CONTENTSIZE_UNKNOWN. - * If pledgedSrcSize > 0, its value must be correct, as it will be written in header, and controlled at the end. - * For the time being, pledgedSrcSize==0 is interpreted as "srcSize unknown" for compatibility with older programs, - * but it will change to mean "empty" in future version, so use macro ZSTD_CONTENTSIZE_UNKNOWN instead. - * @return : 0, or an error code (which can be tested using ZSTD_isError()) - */ -ZSTDLIB_API size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize); - - -typedef struct { - unsigned long long ingested; /* nb input bytes read and buffered */ - unsigned long long consumed; /* nb input bytes actually compressed */ - unsigned long long produced; /* nb of compressed bytes generated and buffered */ - unsigned long long flushed; /* nb of compressed bytes flushed : not provided; can be tracked from caller side */ - unsigned currentJobID; /* MT only : latest started job nb */ - unsigned nbActiveWorkers; /* MT only : nb of workers actively compressing at probe time */ -} ZSTD_frameProgression; - -/* ZSTD_getFrameProgression() : - * tells how much data has been ingested (read from input) - * consumed (input actually compressed) and produced (output) for current frame. - * Note : (ingested - consumed) is amount of input data buffered internally, not yet compressed. - * Aggregates progression inside active worker threads. - */ -ZSTDLIB_API ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx); - -/*! ZSTD_toFlushNow() : - * Tell how many bytes are ready to be flushed immediately. - * Useful for multithreading scenarios (nbWorkers >= 1). - * Probe the oldest active job, defined as oldest job not yet entirely flushed, - * and check its output buffer. - * @return : amount of data stored in oldest job and ready to be flushed immediately. - * if @return == 0, it means either : - * + there is no active job (could be checked with ZSTD_frameProgression()), or - * + oldest job is still actively compressing data, - * but everything it has produced has also been flushed so far, - * therefore flushing speed is currently limited by production speed of oldest job - * irrespective of the speed of concurrent newer jobs. - */ -ZSTDLIB_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx); - - - -/*===== Advanced Streaming decompression functions =====*/ -typedef enum { DStream_p_maxWindowSize } ZSTD_DStreamParameter_e; -ZSTDLIB_API size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue); /* obsolete : this API will be removed in a future version */ -ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); /**< note: no dictionary will be used if dict == NULL or dictSize < 8 */ -ZSTDLIB_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict); /**< note : ddict is referenced, it must outlive decompression session */ -ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds); /**< re-use decompression parameters from previous init; saves dictionary loading */ - - -/********************************************************************* -* Buffer-less and synchronous inner streaming functions -* -* This is an advanced API, giving full control over buffer management, for users which need direct control over memory. -* But it's also a complex one, with several restrictions, documented below. -* Prefer normal streaming API for an easier experience. -********************************************************************* */ - -/** - Buffer-less streaming compression (synchronous mode) - - A ZSTD_CCtx object is required to track streaming operations. - Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource. - ZSTD_CCtx object can be re-used multiple times within successive compression operations. - - Start by initializing a context. - Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression, - or ZSTD_compressBegin_advanced(), for finer parameter control. - It's also possible to duplicate a reference context which has already been initialized, using ZSTD_copyCCtx() - - Then, consume your input using ZSTD_compressContinue(). - There are some important considerations to keep in mind when using this advanced function : - - ZSTD_compressContinue() has no internal buffer. It uses externally provided buffers only. - - Interface is synchronous : input is consumed entirely and produces 1+ compressed blocks. - - Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario. - Worst case evaluation is provided by ZSTD_compressBound(). - ZSTD_compressContinue() doesn't guarantee recover after a failed compression. - - ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog). - It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks) - - ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps. - In which case, it will "discard" the relevant memory section from its history. - - Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum. - It's possible to use srcSize==0, in which case, it will write a final empty block to end the frame. - Without last block mark, frames are considered unfinished (hence corrupted) by compliant decoders. - - `ZSTD_CCtx` object can be re-used (ZSTD_compressBegin()) to compress again. -*/ - -/*===== Buffer-less streaming compression functions =====*/ -ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel); -ZSTDLIB_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); -ZSTDLIB_API size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize : If srcSize is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN */ -ZSTDLIB_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */ -ZSTDLIB_API size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize); /* compression parameters are already set within cdict. pledgedSrcSize must be correct. If srcSize is not known, use macro ZSTD_CONTENTSIZE_UNKNOWN */ -ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */ - -ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); -ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); - - -/*- - Buffer-less streaming decompression (synchronous mode) - - A ZSTD_DCtx object is required to track streaming operations. - Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it. - A ZSTD_DCtx object can be re-used multiple times. - - First typical operation is to retrieve frame parameters, using ZSTD_getFrameHeader(). - Frame header is extracted from the beginning of compressed frame, so providing only the frame's beginning is enough. - Data fragment must be large enough to ensure successful decoding. - `ZSTD_frameHeaderSize_max` bytes is guaranteed to always be large enough. - @result : 0 : successful decoding, the `ZSTD_frameHeader` structure is correctly filled. - >0 : `srcSize` is too small, please provide at least @result bytes on next attempt. - errorCode, which can be tested using ZSTD_isError(). - - It fills a ZSTD_frameHeader structure with important information to correctly decode the frame, - such as the dictionary ID, content size, or maximum back-reference distance (`windowSize`). - Note that these values could be wrong, either because of data corruption, or because a 3rd party deliberately spoofs false information. - As a consequence, check that values remain within valid application range. - For example, do not allocate memory blindly, check that `windowSize` is within expectation. - Each application can set its own limits, depending on local restrictions. - For extended interoperability, it is recommended to support `windowSize` of at least 8 MB. - - ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize` bytes. - ZSTD_decompressContinue() is very sensitive to contiguity, - if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place, - or that previous contiguous segment is large enough to properly handle maximum back-reference distance. - There are multiple ways to guarantee this condition. - - The most memory efficient way is to use a round buffer of sufficient size. - Sufficient size is determined by invoking ZSTD_decodingBufferSize_min(), - which can @return an error code if required value is too large for current system (in 32-bits mode). - In a round buffer methodology, ZSTD_decompressContinue() decompresses each block next to previous one, - up to the moment there is not enough room left in the buffer to guarantee decoding another full block, - which maximum size is provided in `ZSTD_frameHeader` structure, field `blockSizeMax`. - At which point, decoding can resume from the beginning of the buffer. - Note that already decoded data stored in the buffer should be flushed before being overwritten. - - There are alternatives possible, for example using two or more buffers of size `windowSize` each, though they consume more memory. - - Finally, if you control the compression process, you can also ignore all buffer size rules, - as long as the encoder and decoder progress in "lock-step", - aka use exactly the same buffer sizes, break contiguity at the same place, etc. - - Once buffers are setup, start decompression, with ZSTD_decompressBegin(). - If decompression requires a dictionary, use ZSTD_decompressBegin_usingDict() or ZSTD_decompressBegin_usingDDict(). - - Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively. - ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue(). - ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail. - - @result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity). - It can be zero : it just means ZSTD_decompressContinue() has decoded some metadata item. - It can also be an error code, which can be tested with ZSTD_isError(). - - A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero. - Context can then be reset to start a new decompression. - - Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType(). - This information is not required to properly decode a frame. - - == Special case : skippable frames == - - Skippable frames allow integration of user-defined data into a flow of concatenated frames. - Skippable frames will be ignored (skipped) by decompressor. - The format of skippable frames is as follows : - a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F - b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits - c) Frame Content - any content (User Data) of length equal to Frame Size - For skippable frames ZSTD_getFrameHeader() returns zfhPtr->frameType==ZSTD_skippableFrame. - For skippable frames ZSTD_decompressContinue() always returns 0 : it only skips the content. -*/ - -/*===== Buffer-less streaming decompression functions =====*/ -typedef enum { ZSTD_frame, ZSTD_skippableFrame } ZSTD_frameType_e; -typedef struct { - unsigned long long frameContentSize; /* if == ZSTD_CONTENTSIZE_UNKNOWN, it means this field is not available. 0 means "empty" */ - unsigned long long windowSize; /* can be very large, up to <= frameContentSize */ - unsigned blockSizeMax; - ZSTD_frameType_e frameType; /* if == ZSTD_skippableFrame, frameContentSize is the size of skippable content */ - unsigned headerSize; - unsigned dictID; - unsigned checksumFlag; -} ZSTD_frameHeader; -/** ZSTD_getFrameHeader() : - * decode Frame Header, or requires larger `srcSize`. - * @return : 0, `zfhPtr` is correctly filled, - * >0, `srcSize` is too small, value is wanted `srcSize` amount, - * or an error code, which can be tested using ZSTD_isError() */ -ZSTDLIB_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize); /**< doesn't consume input */ -ZSTDLIB_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize); /**< when frame content size is not known, pass in frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN */ - -ZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx); -ZSTDLIB_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); -ZSTDLIB_API size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); - -ZSTDLIB_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx); -ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); - -/* misc */ -ZSTDLIB_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx); -typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e; -ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx); - - - -/* ============================================ */ -/** New advanced API (experimental) */ -/* ============================================ */ - -/* API design : - * In this advanced API, parameters are pushed one by one into an existing context, - * using ZSTD_CCtx_set*() functions. - * Pushed parameters are sticky : they are applied to next job, and any subsequent job. - * It's possible to reset parameters to "default" using ZSTD_CCtx_reset(). - * Important : "sticky" parameters only work with `ZSTD_compress_generic()` ! - * For any other entry point, "sticky" parameters are ignored ! - * - * This API is intended to replace all others advanced / experimental API entry points. - */ - -/* note on enum design : - * All enum will be pinned to explicit values before reaching "stable API" status */ - -typedef enum { - /* Opened question : should we have a format ZSTD_f_auto ? - * Today, it would mean exactly the same as ZSTD_f_zstd1. - * But, in the future, should several formats become supported, - * on the compression side, it would mean "default format". - * On the decompression side, it would mean "automatic format detection", - * so that ZSTD_f_zstd1 would mean "accept *only* zstd frames". - * Since meaning is a little different, another option could be to define different enums for compression and decompression. - * This question could be kept for later, when there are actually multiple formats to support, - * but there is also the question of pinning enum values, and pinning value `0` is especially important */ - ZSTD_f_zstd1 = 0, /* zstd frame format, specified in zstd_compression_format.md (default) */ - ZSTD_f_zstd1_magicless, /* Variant of zstd frame format, without initial 4-bytes magic number. - * Useful to save 4 bytes per generated frame. - * Decoder cannot recognise automatically this format, requiring instructions. */ -} ZSTD_format_e; - -typedef enum { - /* compression format */ - ZSTD_p_format = 10, /* See ZSTD_format_e enum definition. - * Cast selected format as unsigned for ZSTD_CCtx_setParameter() compatibility. */ - - /* compression parameters */ - ZSTD_p_compressionLevel=100, /* Update all compression parameters according to pre-defined cLevel table - * Default level is ZSTD_CLEVEL_DEFAULT==3. - * Special: value 0 means default, which is controlled by ZSTD_CLEVEL_DEFAULT. - * Note 1 : it's possible to pass a negative compression level by casting it to unsigned type. - * Note 2 : setting a level sets all default values of other compression parameters. - * Note 3 : setting compressionLevel automatically updates ZSTD_p_compressLiterals. */ - ZSTD_p_windowLog, /* Maximum allowed back-reference distance, expressed as power of 2. - * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX. - * Special: value 0 means "use default windowLog". - * Note: Using a window size greater than ZSTD_MAXWINDOWSIZE_DEFAULT (default: 2^27) - * requires explicitly allowing such window size during decompression stage. */ - ZSTD_p_hashLog, /* Size of the initial probe table, as a power of 2. - * Resulting table size is (1 << (hashLog+2)). - * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX. - * Larger tables improve compression ratio of strategies <= dFast, - * and improve speed of strategies > dFast. - * Special: value 0 means "use default hashLog". */ - ZSTD_p_chainLog, /* Size of the multi-probe search table, as a power of 2. - * Resulting table size is (1 << (chainLog+2)). - * Must be clamped between ZSTD_CHAINLOG_MIN and ZSTD_CHAINLOG_MAX. - * Larger tables result in better and slower compression. - * This parameter is useless when using "fast" strategy. - * Note it's still useful when using "dfast" strategy, - * in which case it defines a secondary probe table. - * Special: value 0 means "use default chainLog". */ - ZSTD_p_searchLog, /* Number of search attempts, as a power of 2. - * More attempts result in better and slower compression. - * This parameter is useless when using "fast" and "dFast" strategies. - * Special: value 0 means "use default searchLog". */ - ZSTD_p_minMatch, /* Minimum size of searched matches (note : repCode matches can be smaller). - * Larger values make faster compression and decompression, but decrease ratio. - * Must be clamped between ZSTD_SEARCHLENGTH_MIN and ZSTD_SEARCHLENGTH_MAX. - * Note that currently, for all strategies < btopt, effective minimum is 4. - * , for all strategies > fast, effective maximum is 6. - * Special: value 0 means "use default minMatchLength". */ - ZSTD_p_targetLength, /* Impact of this field depends on strategy. - * For strategies btopt & btultra: - * Length of Match considered "good enough" to stop search. - * Larger values make compression stronger, and slower. - * For strategy fast: - * Distance between match sampling. - * Larger values make compression faster, and weaker. - * Special: value 0 means "use default targetLength". */ - ZSTD_p_compressionStrategy, /* See ZSTD_strategy enum definition. - * Cast selected strategy as unsigned for ZSTD_CCtx_setParameter() compatibility. - * The higher the value of selected strategy, the more complex it is, - * resulting in stronger and slower compression. - * Special: value 0 means "use default strategy". */ - - ZSTD_p_enableLongDistanceMatching=160, /* Enable long distance matching. - * This parameter is designed to improve compression ratio - * for large inputs, by finding large matches at long distance. - * It increases memory usage and window size. - * Note: enabling this parameter increases ZSTD_p_windowLog to 128 MB - * except when expressly set to a different value. */ - ZSTD_p_ldmHashLog, /* Size of the table for long distance matching, as a power of 2. - * Larger values increase memory usage and compression ratio, - * but decrease compression speed. - * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX - * default: windowlog - 7. - * Special: value 0 means "automatically determine hashlog". */ - ZSTD_p_ldmMinMatch, /* Minimum match size for long distance matcher. - * Larger/too small values usually decrease compression ratio. - * Must be clamped between ZSTD_LDM_MINMATCH_MIN and ZSTD_LDM_MINMATCH_MAX. - * Special: value 0 means "use default value" (default: 64). */ - ZSTD_p_ldmBucketSizeLog, /* Log size of each bucket in the LDM hash table for collision resolution. - * Larger values improve collision resolution but decrease compression speed. - * The maximum value is ZSTD_LDM_BUCKETSIZELOG_MAX . - * Special: value 0 means "use default value" (default: 3). */ - ZSTD_p_ldmHashEveryLog, /* Frequency of inserting/looking up entries in the LDM hash table. - * Must be clamped between 0 and (ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN). - * Default is MAX(0, (windowLog - ldmHashLog)), optimizing hash table usage. - * Larger values improve compression speed. - * Deviating far from default value will likely result in a compression ratio decrease. - * Special: value 0 means "automatically determine hashEveryLog". */ - - /* frame parameters */ - ZSTD_p_contentSizeFlag=200, /* Content size will be written into frame header _whenever known_ (default:1) - * Content size must be known at the beginning of compression, - * it is provided using ZSTD_CCtx_setPledgedSrcSize() */ - ZSTD_p_checksumFlag, /* A 32-bits checksum of content is written at end of frame (default:0) */ - ZSTD_p_dictIDFlag, /* When applicable, dictionary's ID is written into frame header (default:1) */ - - /* multi-threading parameters */ - /* These parameters are only useful if multi-threading is enabled (ZSTD_MULTITHREAD). - * They return an error otherwise. */ - ZSTD_p_nbWorkers=400, /* Select how many threads will be spawned to compress in parallel. - * When nbWorkers >= 1, triggers asynchronous mode : - * ZSTD_compress_generic() consumes some input, flush some output if possible, and immediately gives back control to caller, - * while compression work is performed in parallel, within worker threads. - * (note : a strong exception to this rule is when first invocation sets ZSTD_e_end : it becomes a blocking call). - * More workers improve speed, but also increase memory usage. - * Default value is `0`, aka "single-threaded mode" : no worker is spawned, compression is performed inside Caller's thread, all invocations are blocking */ - ZSTD_p_jobSize, /* Size of a compression job. This value is enforced only in non-blocking mode. - * Each compression job is completed in parallel, so this value indirectly controls the nb of active threads. - * 0 means default, which is dynamically determined based on compression parameters. - * Job size must be a minimum of overlapSize, or 1 MB, whichever is largest. - * The minimum size is automatically and transparently enforced */ - ZSTD_p_overlapSizeLog, /* Size of previous input reloaded at the beginning of each job. - * 0 => no overlap, 6(default) => use 1/8th of windowSize, >=9 => use full windowSize */ - - /* =================================================================== */ - /* experimental parameters - no stability guaranteed */ - /* =================================================================== */ - - ZSTD_p_forceMaxWindow=1100, /* Force back-reference distances to remain < windowSize, - * even when referencing into Dictionary content (default:0) */ - ZSTD_p_forceAttachDict, /* ZSTD supports usage of a CDict in-place - * (avoiding having to copy the compression tables - * from the CDict into the working context). Using - * a CDict in this way saves an initial setup step, - * but comes at the cost of more work per byte of - * input. ZSTD has a simple internal heuristic that - * guesses which strategy will be faster. You can - * use this flag to override that guess. - * - * Note that the by-reference, in-place strategy is - * only used when reusing a compression context - * with compatible compression parameters. (If - * incompatible / uninitialized, the working - * context needs to be cleared anyways, which is - * about as expensive as overwriting it with the - * dictionary context, so there's no savings in - * using the CDict by-ref.) - * - * Values greater than 0 force attaching the dict. - * Values less than 0 force copying the dict. - * 0 selects the default heuristic-guided behavior. - */ - -} ZSTD_cParameter; - - -/*! ZSTD_CCtx_setParameter() : - * Set one compression parameter, selected by enum ZSTD_cParameter. - * Setting a parameter is generally only possible during frame initialization (before starting compression). - * Exception : when using multi-threading mode (nbThreads >= 1), - * following parameters can be updated _during_ compression (within same frame): - * => compressionLevel, hashLog, chainLog, searchLog, minMatch, targetLength and strategy. - * new parameters will be active on next job, or after a flush(). - * Note : when `value` type is not unsigned (int, or enum), cast it to unsigned for proper type checking. - * @result : informational value (typically, value being set, correctly clamped), - * or an error code (which can be tested with ZSTD_isError()). */ -ZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value); - -/*! ZSTD_CCtx_getParameter() : - * Get the requested value of one compression parameter, selected by enum ZSTD_cParameter. - * @result : 0, or an error code (which can be tested with ZSTD_isError()). - */ -ZSTDLIB_API size_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned* value); - -/*! ZSTD_CCtx_setPledgedSrcSize() : - * Total input data size to be compressed as a single frame. - * This value will be controlled at the end, and result in error if not respected. - * @result : 0, or an error code (which can be tested with ZSTD_isError()). - * Note 1 : 0 means zero, empty. - * In order to mean "unknown content size", pass constant ZSTD_CONTENTSIZE_UNKNOWN. - * ZSTD_CONTENTSIZE_UNKNOWN is default value for any new compression job. - * Note 2 : If all data is provided and consumed in a single round, - * this value is overriden by srcSize instead. */ -ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize); - -/*! ZSTD_CCtx_loadDictionary() : - * Create an internal CDict from `dict` buffer. - * Decompression will have to use same dictionary. - * @result : 0, or an error code (which can be tested with ZSTD_isError()). - * Special: Adding a NULL (or 0-size) dictionary invalidates previous dictionary, - * meaning "return to no-dictionary mode". - * Note 1 : Dictionary will be used for all future compression jobs. - * To return to "no-dictionary" situation, load a NULL dictionary - * Note 2 : Loading a dictionary involves building tables, which are dependent on compression parameters. - * For this reason, compression parameters cannot be changed anymore after loading a dictionary. - * It's also a CPU consuming operation, with non-negligible impact on latency. - * Note 3 :`dict` content will be copied internally. - * Use ZSTD_CCtx_loadDictionary_byReference() to reference dictionary content instead. - * In such a case, dictionary buffer must outlive its users. - * Note 4 : Use ZSTD_CCtx_loadDictionary_advanced() - * to precisely select how dictionary content must be interpreted. */ -ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); -ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); -ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType); - - -/*! ZSTD_CCtx_refCDict() : - * Reference a prepared dictionary, to be used for all next compression jobs. - * Note that compression parameters are enforced from within CDict, - * and supercede any compression parameter previously set within CCtx. - * The dictionary will remain valid for future compression jobs using same CCtx. - * @result : 0, or an error code (which can be tested with ZSTD_isError()). - * Special : adding a NULL CDict means "return to no-dictionary mode". - * Note 1 : Currently, only one dictionary can be managed. - * Adding a new dictionary effectively "discards" any previous one. - * Note 2 : CDict is just referenced, its lifetime must outlive CCtx. */ -ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); - -/*! ZSTD_CCtx_refPrefix() : - * Reference a prefix (single-usage dictionary) for next compression job. - * Decompression will need same prefix to properly regenerate data. - * Compressing with a prefix is similar in outcome as performing a diff and compressing it, - * but performs much faster, especially during decompression (compression speed is tunable with compression level). - * Note that prefix is **only used once**. Tables are discarded at end of compression job (ZSTD_e_end). - * @result : 0, or an error code (which can be tested with ZSTD_isError()). - * Special: Adding any prefix (including NULL) invalidates any previous prefix or dictionary - * Note 1 : Prefix buffer is referenced. It **must** outlive compression job. - * Its contain must remain unmodified up to end of compression (ZSTD_e_end). - * Note 2 : If the intention is to diff some large src data blob with some prior version of itself, - * ensure that the window size is large enough to contain the entire source. - * See ZSTD_p_windowLog. - * Note 3 : Referencing a prefix involves building tables, which are dependent on compression parameters. - * It's a CPU consuming operation, with non-negligible impact on latency. - * If there is a need to use same prefix multiple times, consider loadDictionary instead. - * Note 4 : By default, the prefix is treated as raw content (ZSTD_dm_rawContent). - * Use ZSTD_CCtx_refPrefix_advanced() to alter dictMode. */ -ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, - const void* prefix, size_t prefixSize); -ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, - const void* prefix, size_t prefixSize, - ZSTD_dictContentType_e dictContentType); - -/*! ZSTD_CCtx_reset() : - * Return a CCtx to clean state. - * Useful after an error, or to interrupt an ongoing compression job and start a new one. - * Any internal data not yet flushed is cancelled. - * The parameters and dictionary are kept unchanged, to reset them use ZSTD_CCtx_resetParameters(). - */ -ZSTDLIB_API void ZSTD_CCtx_reset(ZSTD_CCtx* cctx); - -/*! ZSTD_CCtx_resetParameters() : - * All parameters are back to default values (compression level is ZSTD_CLEVEL_DEFAULT). - * Dictionary (if any) is dropped. - * Resetting parameters is only possible during frame initialization (before starting compression). - * To reset the context use ZSTD_CCtx_reset(). - * @return 0 or an error code (which can be checked with ZSTD_isError()). - */ -ZSTDLIB_API size_t ZSTD_CCtx_resetParameters(ZSTD_CCtx* cctx); - - - -typedef enum { - ZSTD_e_continue=0, /* collect more data, encoder decides when to output compressed result, for optimal conditions */ - ZSTD_e_flush, /* flush any data provided so far - frame will continue, future data can still reference previous data for better compression */ - ZSTD_e_end /* flush any remaining data and close current frame. Any additional data starts a new frame. */ -} ZSTD_EndDirective; - -/*! ZSTD_compress_generic() : - * Behave about the same as ZSTD_compressStream. To note : - * - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_setParameter() - * - Compression parameters cannot be changed once compression is started. - * - outpot->pos must be <= dstCapacity, input->pos must be <= srcSize - * - outpot->pos and input->pos will be updated. They are guaranteed to remain below their respective limit. - * - In single-thread mode (default), function is blocking : it completed its job before returning to caller. - * - In multi-thread mode, function is non-blocking : it just acquires a copy of input, and distribute job to internal worker threads, - * and then immediately returns, just indicating that there is some data remaining to be flushed. - * The function nonetheless guarantees forward progress : it will return only after it reads or write at least 1+ byte. - * - Exception : in multi-threading mode, if the first call requests a ZSTD_e_end directive, it is blocking : it will complete compression before giving back control to caller. - * - @return provides a minimum amount of data remaining to be flushed from internal buffers - * or an error code, which can be tested using ZSTD_isError(). - * if @return != 0, flush is not fully completed, there is still some data left within internal buffers. - * This is useful for ZSTD_e_flush, since in this case more flushes are necessary to empty all buffers. - * For ZSTD_e_end, @return == 0 when internal buffers are fully flushed and frame is completed. - * - after a ZSTD_e_end directive, if internal buffer is not fully flushed (@return != 0), - * only ZSTD_e_end or ZSTD_e_flush operations are allowed. - * Before starting a new compression job, or changing compression parameters, - * it is required to fully flush internal buffers. - */ -ZSTDLIB_API size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, - ZSTD_outBuffer* output, - ZSTD_inBuffer* input, - ZSTD_EndDirective endOp); - - -/*! ZSTD_compress_generic_simpleArgs() : - * Same as ZSTD_compress_generic(), - * but using only integral types as arguments. - * Argument list is larger than ZSTD_{in,out}Buffer, - * but can be helpful for binders from dynamic languages - * which have troubles handling structures containing memory pointers. - */ -ZSTDLIB_API size_t ZSTD_compress_generic_simpleArgs ( - ZSTD_CCtx* cctx, - void* dst, size_t dstCapacity, size_t* dstPos, - const void* src, size_t srcSize, size_t* srcPos, - ZSTD_EndDirective endOp); - - -/*! ZSTD_CCtx_params : - * Quick howto : - * - ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure - * - ZSTD_CCtxParam_setParameter() : Push parameters one by one into - * an existing ZSTD_CCtx_params structure. - * This is similar to - * ZSTD_CCtx_setParameter(). - * - ZSTD_CCtx_setParametersUsingCCtxParams() : Apply parameters to - * an existing CCtx. - * These parameters will be applied to - * all subsequent compression jobs. - * - ZSTD_compress_generic() : Do compression using the CCtx. - * - ZSTD_freeCCtxParams() : Free the memory. - * - * This can be used with ZSTD_estimateCCtxSize_advanced_usingCCtxParams() - * for static allocation for single-threaded compression. - */ -ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void); -ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params); - - -/*! ZSTD_CCtxParams_reset() : - * Reset params to default values. - */ -ZSTDLIB_API size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params); - -/*! ZSTD_CCtxParams_init() : - * Initializes the compression parameters of cctxParams according to - * compression level. All other parameters are reset to their default values. - */ -ZSTDLIB_API size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel); - -/*! ZSTD_CCtxParams_init_advanced() : - * Initializes the compression and frame parameters of cctxParams according to - * params. All other parameters are reset to their default values. - */ -ZSTDLIB_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params); - - -/*! ZSTD_CCtxParam_setParameter() : - * Similar to ZSTD_CCtx_setParameter. - * Set one compression parameter, selected by enum ZSTD_cParameter. - * Parameters must be applied to a ZSTD_CCtx using ZSTD_CCtx_setParametersUsingCCtxParams(). - * Note : when `value` is an enum, cast it to unsigned for proper type checking. - * @result : 0, or an error code (which can be tested with ZSTD_isError()). - */ -ZSTDLIB_API size_t ZSTD_CCtxParam_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned value); - -/*! ZSTD_CCtxParam_getParameter() : - * Similar to ZSTD_CCtx_getParameter. - * Get the requested value of one compression parameter, selected by enum ZSTD_cParameter. - * @result : 0, or an error code (which can be tested with ZSTD_isError()). - */ -ZSTDLIB_API size_t ZSTD_CCtxParam_getParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned* value); - -/*! ZSTD_CCtx_setParametersUsingCCtxParams() : - * Apply a set of ZSTD_CCtx_params to the compression context. - * This can be done even after compression is started, - * if nbWorkers==0, this will have no impact until a new compression is started. - * if nbWorkers>=1, new parameters will be picked up at next job, - * with a few restrictions (windowLog, pledgedSrcSize, nbWorkers, jobSize, and overlapLog are not updated). - */ -ZSTDLIB_API size_t ZSTD_CCtx_setParametersUsingCCtxParams( - ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params); - - -/* ==================================== */ -/*=== Advanced decompression API ===*/ -/* ==================================== */ - -/* The following API works the same way as the advanced compression API : - * a context is created, parameters are pushed into it one by one, - * then the context can be used to decompress data using an interface similar to the straming API. - */ - -/*! ZSTD_DCtx_loadDictionary() : - * Create an internal DDict from dict buffer, - * to be used to decompress next frames. - * @result : 0, or an error code (which can be tested with ZSTD_isError()). - * Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary, - * meaning "return to no-dictionary mode". - * Note 1 : `dict` content will be copied internally. - * Use ZSTD_DCtx_loadDictionary_byReference() - * to reference dictionary content instead. - * In which case, the dictionary buffer must outlive its users. - * Note 2 : Loading a dictionary involves building tables, - * which has a non-negligible impact on CPU usage and latency. - * Note 3 : Use ZSTD_DCtx_loadDictionary_advanced() to select - * how dictionary content will be interpreted and loaded. - */ -ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); -ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); -ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType); - - -/*! ZSTD_DCtx_refDDict() : - * Reference a prepared dictionary, to be used to decompress next frames. - * The dictionary remains active for decompression of future frames using same DCtx. - * @result : 0, or an error code (which can be tested with ZSTD_isError()). - * Note 1 : Currently, only one dictionary can be managed. - * Referencing a new dictionary effectively "discards" any previous one. - * Special : adding a NULL DDict means "return to no-dictionary mode". - * Note 2 : DDict is just referenced, its lifetime must outlive its usage from DCtx. - */ -ZSTDLIB_API size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); - - -/*! ZSTD_DCtx_refPrefix() : - * Reference a prefix (single-usage dictionary) for next compression job. - * This is the reverse operation of ZSTD_CCtx_refPrefix(), - * and must use the same prefix as the one used during compression. - * Prefix is **only used once**. Reference is discarded at end of frame. - * End of frame is reached when ZSTD_DCtx_decompress_generic() returns 0. - * @result : 0, or an error code (which can be tested with ZSTD_isError()). - * Note 1 : Adding any prefix (including NULL) invalidates any previously set prefix or dictionary - * Note 2 : Prefix buffer is referenced. It **must** outlive decompression job. - * Prefix buffer must remain unmodified up to the end of frame, - * reached when ZSTD_DCtx_decompress_generic() returns 0. - * Note 3 : By default, the prefix is treated as raw content (ZSTD_dm_rawContent). - * Use ZSTD_CCtx_refPrefix_advanced() to alter dictMode. - * Note 4 : Referencing a raw content prefix has almost no cpu nor memory cost. - * A fulldict prefix is more costly though. - */ -ZSTDLIB_API size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, - const void* prefix, size_t prefixSize); -ZSTDLIB_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, - const void* prefix, size_t prefixSize, - ZSTD_dictContentType_e dictContentType); - - -/*! ZSTD_DCtx_setMaxWindowSize() : - * Refuses allocating internal buffers for frames requiring a window size larger than provided limit. - * This is useful to prevent a decoder context from reserving too much memory for itself (potential attack scenario). - * This parameter is only useful in streaming mode, since no internal buffer is allocated in direct mode. - * By default, a decompression context accepts all window sizes <= (1 << ZSTD_WINDOWLOG_MAX) - * @return : 0, or an error code (which can be tested using ZSTD_isError()). - */ -ZSTDLIB_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize); - - -/*! ZSTD_DCtx_setFormat() : - * Instruct the decoder context about what kind of data to decode next. - * This instruction is mandatory to decode data without a fully-formed header, - * such ZSTD_f_zstd1_magicless for example. - * @return : 0, or an error code (which can be tested using ZSTD_isError()). - */ -ZSTDLIB_API size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format); - - -/*! ZSTD_getFrameHeader_advanced() : - * same as ZSTD_getFrameHeader(), - * with added capability to select a format (like ZSTD_f_zstd1_magicless) */ -ZSTDLIB_API size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, - const void* src, size_t srcSize, ZSTD_format_e format); - - -/*! ZSTD_decompress_generic() : - * Behave the same as ZSTD_decompressStream. - * Decompression parameters cannot be changed once decompression is started. - * @return : an error code, which can be tested using ZSTD_isError() - * if >0, a hint, nb of expected input bytes for next invocation. - * `0` means : a frame has just been fully decoded and flushed. - */ -ZSTDLIB_API size_t ZSTD_decompress_generic(ZSTD_DCtx* dctx, - ZSTD_outBuffer* output, - ZSTD_inBuffer* input); - - -/*! ZSTD_decompress_generic_simpleArgs() : - * Same as ZSTD_decompress_generic(), - * but using only integral types as arguments. - * Argument list is larger than ZSTD_{in,out}Buffer, - * but can be helpful for binders from dynamic languages - * which have troubles handling structures containing memory pointers. - */ -ZSTDLIB_API size_t ZSTD_decompress_generic_simpleArgs ( - ZSTD_DCtx* dctx, - void* dst, size_t dstCapacity, size_t* dstPos, - const void* src, size_t srcSize, size_t* srcPos); - - -/*! ZSTD_DCtx_reset() : - * Return a DCtx to clean state. - * If a decompression was ongoing, any internal data not yet flushed is cancelled. - * All parameters are back to default values, including sticky ones. - * Dictionary (if any) is dropped. - * Parameters can be modified again after a reset. - */ -ZSTDLIB_API void ZSTD_DCtx_reset(ZSTD_DCtx* dctx); - - - -/* ============================ */ -/** Block level API */ -/* ============================ */ - -/*! - Block functions produce and decode raw zstd blocks, without frame metadata. - Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes). - User will have to take in charge required information to regenerate data, such as compressed and content sizes. - - A few rules to respect : - - Compressing and decompressing require a context structure - + Use ZSTD_createCCtx() and ZSTD_createDCtx() - - It is necessary to init context before starting - + compression : any ZSTD_compressBegin*() variant, including with dictionary - + decompression : any ZSTD_decompressBegin*() variant, including with dictionary - + copyCCtx() and copyDCtx() can be used too - - Block size is limited, it must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX == 128 KB - + If input is larger than a block size, it's necessary to split input data into multiple blocks - + For inputs larger than a single block size, consider using the regular ZSTD_compress() instead. - Frame metadata is not that costly, and quickly becomes negligible as source size grows larger. - - When a block is considered not compressible enough, ZSTD_compressBlock() result will be zero. - In which case, nothing is produced into `dst`. - + User must test for such outcome and deal directly with uncompressed data - + ZSTD_decompressBlock() doesn't accept uncompressed data as input !!! - + In case of multiple successive blocks, should some of them be uncompressed, - decoder must be informed of their existence in order to follow proper history. - Use ZSTD_insertBlock() for such a case. -*/ - -/*===== Raw zstd block functions =====*/ -ZSTDLIB_API size_t ZSTD_getBlockSize (const ZSTD_CCtx* cctx); -ZSTDLIB_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); -ZSTDLIB_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); -ZSTDLIB_API size_t ZSTD_insertBlock (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */ - - -#endif /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */ - -#if defined (__cplusplus) -} -#endif diff --git a/grub-core/lib/zstd/zstd_common.c b/grub-core/lib/zstd/zstd_common.c deleted file mode 100644 index 6f05d240e..000000000 --- a/grub-core/lib/zstd/zstd_common.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ - - - -/*-************************************* -* Dependencies -***************************************/ -#include /* malloc, calloc, free */ -#include /* memset */ -#include "error_private.h" -#include "zstd_internal.h" - - -/*-**************************************** -* Version -******************************************/ -unsigned ZSTD_versionNumber(void) { return ZSTD_VERSION_NUMBER; } - -const char* ZSTD_versionString(void) { return ZSTD_VERSION_STRING; } - - -/*-**************************************** -* ZSTD Error Management -******************************************/ -/*! ZSTD_isError() : - * tells if a return value is an error code */ -unsigned ZSTD_isError(size_t code) { return ERR_isError(code); } - -/*! ZSTD_getErrorName() : - * provides error code string from function result (useful for debugging) */ -const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); } - -/*! ZSTD_getError() : - * convert a `size_t` function result into a proper ZSTD_errorCode enum */ -ZSTD_ErrorCode ZSTD_getErrorCode(size_t code) { return ERR_getErrorCode(code); } - -/*! ZSTD_getErrorString() : - * provides error code string from enum */ -const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString(code); } - - - -/*=************************************************************** -* Custom allocator -****************************************************************/ -void* ZSTD_malloc(size_t size, ZSTD_customMem customMem) -{ - if (customMem.customAlloc) - return customMem.customAlloc(customMem.opaque, size); - return malloc(size); -} - -void* ZSTD_calloc(size_t size, ZSTD_customMem customMem) -{ - if (customMem.customAlloc) { - /* calloc implemented as malloc+memset; - * not as efficient as calloc, but next best guess for custom malloc */ - void* const ptr = customMem.customAlloc(customMem.opaque, size); - memset(ptr, 0, size); - return ptr; - } - return calloc(1, size); -} - -void ZSTD_free(void* ptr, ZSTD_customMem customMem) -{ - if (ptr!=NULL) { - if (customMem.customFree) - customMem.customFree(customMem.opaque, ptr); - else - free(ptr); - } -} diff --git a/grub-core/lib/zstd/zstd_decompress.c b/grub-core/lib/zstd/zstd_decompress.c deleted file mode 100644 index e4b5670c2..000000000 --- a/grub-core/lib/zstd/zstd_decompress.c +++ /dev/null @@ -1,3108 +0,0 @@ -/* - * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ - - -/* *************************************************************** -* Tuning parameters -*****************************************************************/ -/*! - * HEAPMODE : - * Select how default decompression function ZSTD_decompress() allocates its context, - * on stack (0), or into heap (1, default; requires malloc()). - * Note that functions with explicit context such as ZSTD_decompressDCtx() are unaffected. - */ -#ifndef ZSTD_HEAPMODE -# define ZSTD_HEAPMODE 1 -#endif - -/*! -* LEGACY_SUPPORT : -* if set to 1+, ZSTD_decompress() can decode older formats (v0.1+) -*/ -#ifndef ZSTD_LEGACY_SUPPORT -# define ZSTD_LEGACY_SUPPORT 0 -#endif - -/*! - * MAXWINDOWSIZE_DEFAULT : - * maximum window size accepted by DStream __by default__. - * Frames requiring more memory will be rejected. - * It's possible to set a different limit using ZSTD_DCtx_setMaxWindowSize(). - */ -#ifndef ZSTD_MAXWINDOWSIZE_DEFAULT -# define ZSTD_MAXWINDOWSIZE_DEFAULT (((U32)1 << ZSTD_WINDOWLOG_DEFAULTMAX) + 1) -#endif - -/*! - * NO_FORWARD_PROGRESS_MAX : - * maximum allowed nb of calls to ZSTD_decompressStream() and ZSTD_decompress_generic() - * without any forward progress - * (defined as: no byte read from input, and no byte flushed to output) - * before triggering an error. - */ -#ifndef ZSTD_NO_FORWARD_PROGRESS_MAX -# define ZSTD_NO_FORWARD_PROGRESS_MAX 16 -#endif - - -/*-******************************************************* -* Dependencies -*********************************************************/ -#include /* memcpy, memmove, memset */ -#include "compiler.h" /* prefetch */ -#include "cpu.h" /* bmi2 */ -#include "mem.h" /* low level memory routines */ -#define FSE_STATIC_LINKING_ONLY -#include "fse.h" -#define HUF_STATIC_LINKING_ONLY -#include "huf.h" -#include "zstd_internal.h" - -#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) -# include "zstd_legacy.h" -#endif - -static const void* ZSTD_DDictDictContent(const ZSTD_DDict* ddict); -static size_t ZSTD_DDictDictSize(const ZSTD_DDict* ddict); - - -/*-************************************* -* Errors -***************************************/ -#define ZSTD_isError ERR_isError /* for inlining */ -#define FSE_isError ERR_isError -#define HUF_isError ERR_isError - - -/*_******************************************************* -* Memory operations -**********************************************************/ -static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); } - - -/*-************************************************************* -* Context management -***************************************************************/ -typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader, - ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock, - ZSTDds_decompressLastBlock, ZSTDds_checkChecksum, - ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage; - -typedef enum { zdss_init=0, zdss_loadHeader, - zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage; - - -typedef struct { - U32 fastMode; - U32 tableLog; -} ZSTD_seqSymbol_header; - -typedef struct { - U16 nextState; - BYTE nbAdditionalBits; - BYTE nbBits; - U32 baseValue; -} ZSTD_seqSymbol; - -#define SEQSYMBOL_TABLE_SIZE(log) (1 + (1 << (log))) - -typedef struct { - ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)]; /* Note : Space reserved for FSE Tables */ - ZSTD_seqSymbol OFTable[SEQSYMBOL_TABLE_SIZE(OffFSELog)]; /* is also used as temporary workspace while building hufTable during DDict creation */ - ZSTD_seqSymbol MLTable[SEQSYMBOL_TABLE_SIZE(MLFSELog)]; /* and therefore must be at least HUF_DECOMPRESS_WORKSPACE_SIZE large */ - HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */ - U32 rep[ZSTD_REP_NUM]; -} ZSTD_entropyDTables_t; - -struct ZSTD_DCtx_s -{ - const ZSTD_seqSymbol* LLTptr; - const ZSTD_seqSymbol* MLTptr; - const ZSTD_seqSymbol* OFTptr; - const HUF_DTable* HUFptr; - ZSTD_entropyDTables_t entropy; - U32 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; /* space needed when building huffman tables */ - const void* previousDstEnd; /* detect continuity */ - const void* prefixStart; /* start of current segment */ - const void* virtualStart; /* virtual start of previous segment if it was just before current one */ - const void* dictEnd; /* end of previous segment */ - size_t expected; - ZSTD_frameHeader fParams; - U64 decodedSize; - blockType_e bType; /* used in ZSTD_decompressContinue(), store blockType between block header decoding and block decompression stages */ - ZSTD_dStage stage; - U32 litEntropy; - U32 fseEntropy; - XXH64_state_t xxhState; - size_t headerSize; - ZSTD_format_e format; - const BYTE* litPtr; - ZSTD_customMem customMem; - size_t litSize; - size_t rleSize; - size_t staticSize; - int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */ - - /* dictionary */ - ZSTD_DDict* ddictLocal; - const ZSTD_DDict* ddict; /* set by ZSTD_initDStream_usingDDict(), or ZSTD_DCtx_refDDict() */ - U32 dictID; - int ddictIsCold; /* if == 1 : dictionary is "new" for working context, and presumed "cold" (not in cpu cache) */ - - /* streaming */ - ZSTD_dStreamStage streamStage; - char* inBuff; - size_t inBuffSize; - size_t inPos; - size_t maxWindowSize; - char* outBuff; - size_t outBuffSize; - size_t outStart; - size_t outEnd; - size_t lhSize; - void* legacyContext; - U32 previousLegacyVersion; - U32 legacyVersion; - U32 hostageByte; - int noForwardProgress; - - /* workspace */ - BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH]; - BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; -}; /* typedef'd to ZSTD_DCtx within "zstd.h" */ - -size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx) -{ - if (dctx==NULL) return 0; /* support sizeof NULL */ - return sizeof(*dctx) - + ZSTD_sizeof_DDict(dctx->ddictLocal) - + dctx->inBuffSize + dctx->outBuffSize; -} - -size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); } - - -static size_t ZSTD_startingInputLength(ZSTD_format_e format) -{ - size_t const startingInputLength = (format==ZSTD_f_zstd1_magicless) ? - ZSTD_frameHeaderSize_prefix - ZSTD_FRAMEIDSIZE : - ZSTD_frameHeaderSize_prefix; - ZSTD_STATIC_ASSERT(ZSTD_FRAMEHEADERSIZE_PREFIX >= ZSTD_FRAMEIDSIZE); - /* only supports formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless */ - assert( (format == ZSTD_f_zstd1) || (format == ZSTD_f_zstd1_magicless) ); - return startingInputLength; -} - -static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx) -{ - dctx->format = ZSTD_f_zstd1; /* ZSTD_decompressBegin() invokes ZSTD_startingInputLength() with argument dctx->format */ - dctx->staticSize = 0; - dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT; - dctx->ddict = NULL; - dctx->ddictLocal = NULL; - dctx->dictEnd = NULL; - dctx->ddictIsCold = 0; - dctx->inBuff = NULL; - dctx->inBuffSize = 0; - dctx->outBuffSize = 0; - dctx->streamStage = zdss_init; - dctx->legacyContext = NULL; - dctx->previousLegacyVersion = 0; - dctx->noForwardProgress = 0; - dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); -} - -ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize) -{ - ZSTD_DCtx* const dctx = (ZSTD_DCtx*) workspace; - - if ((size_t)workspace & 7) return NULL; /* 8-aligned */ - if (workspaceSize < sizeof(ZSTD_DCtx)) return NULL; /* minimum size */ - - ZSTD_initDCtx_internal(dctx); - dctx->staticSize = workspaceSize; - dctx->inBuff = (char*)(dctx+1); - return dctx; -} - -ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem) -{ - if (!customMem.customAlloc ^ !customMem.customFree) return NULL; - - { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(*dctx), customMem); - if (!dctx) return NULL; - dctx->customMem = customMem; - ZSTD_initDCtx_internal(dctx); - return dctx; - } -} - -ZSTD_DCtx* ZSTD_createDCtx(void) -{ - DEBUGLOG(3, "ZSTD_createDCtx"); - return ZSTD_createDCtx_advanced(ZSTD_defaultCMem); -} - -size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx) -{ - if (dctx==NULL) return 0; /* support free on NULL */ - if (dctx->staticSize) return ERROR(memory_allocation); /* not compatible with static DCtx */ - { ZSTD_customMem const cMem = dctx->customMem; - ZSTD_freeDDict(dctx->ddictLocal); - dctx->ddictLocal = NULL; - ZSTD_free(dctx->inBuff, cMem); - dctx->inBuff = NULL; -#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) - if (dctx->legacyContext) - ZSTD_freeLegacyStreamContext(dctx->legacyContext, dctx->previousLegacyVersion); -#endif - ZSTD_free(dctx, cMem); - return 0; - } -} - -/* no longer useful */ -void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx) -{ - size_t const toCopy = (size_t)((char*)(&dstDCtx->inBuff) - (char*)dstDCtx); - memcpy(dstDCtx, srcDCtx, toCopy); /* no need to copy workspace */ -} - - -/*-************************************************************* - * Frame header decoding - ***************************************************************/ - -/*! ZSTD_isFrame() : - * Tells if the content of `buffer` starts with a valid Frame Identifier. - * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. - * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. - * Note 3 : Skippable Frame Identifiers are considered valid. */ -unsigned ZSTD_isFrame(const void* buffer, size_t size) -{ - if (size < ZSTD_FRAMEIDSIZE) return 0; - { U32 const magic = MEM_readLE32(buffer); - if (magic == ZSTD_MAGICNUMBER) return 1; - if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1; - } -#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) - if (ZSTD_isLegacy(buffer, size)) return 1; -#endif - return 0; -} - -/** ZSTD_frameHeaderSize_internal() : - * srcSize must be large enough to reach header size fields. - * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless. - * @return : size of the Frame Header - * or an error code, which can be tested with ZSTD_isError() */ -static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZSTD_format_e format) -{ - size_t const minInputSize = ZSTD_startingInputLength(format); - if (srcSize < minInputSize) return ERROR(srcSize_wrong); - - { BYTE const fhd = ((const BYTE*)src)[minInputSize-1]; - U32 const dictID= fhd & 3; - U32 const singleSegment = (fhd >> 5) & 1; - U32 const fcsId = fhd >> 6; - return minInputSize + !singleSegment - + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId] - + (singleSegment && !fcsId); - } -} - -/** ZSTD_frameHeaderSize() : - * srcSize must be >= ZSTD_frameHeaderSize_prefix. - * @return : size of the Frame Header, - * or an error code (if srcSize is too small) */ -size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize) -{ - return ZSTD_frameHeaderSize_internal(src, srcSize, ZSTD_f_zstd1); -} - - -/** ZSTD_getFrameHeader_advanced() : - * decode Frame Header, or require larger `srcSize`. - * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless - * @return : 0, `zfhPtr` is correctly filled, - * >0, `srcSize` is too small, value is wanted `srcSize` amount, - * or an error code, which can be tested using ZSTD_isError() */ -size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format) -{ - const BYTE* ip = (const BYTE*)src; - size_t const minInputSize = ZSTD_startingInputLength(format); - - memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzer do not understand that zfhPtr is only going to be read only if return value is zero, since they are 2 different signals */ - if (srcSize < minInputSize) return minInputSize; - if (src==NULL) return ERROR(GENERIC); /* invalid parameter */ - - if ( (format != ZSTD_f_zstd1_magicless) - && (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) { - if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { - /* skippable frame */ - if (srcSize < ZSTD_skippableHeaderSize) - return ZSTD_skippableHeaderSize; /* magic number + frame length */ - memset(zfhPtr, 0, sizeof(*zfhPtr)); - zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE); - zfhPtr->frameType = ZSTD_skippableFrame; - return 0; - } - return ERROR(prefix_unknown); - } - - /* ensure there is enough `srcSize` to fully read/decode frame header */ - { size_t const fhsize = ZSTD_frameHeaderSize_internal(src, srcSize, format); - if (srcSize < fhsize) return fhsize; - zfhPtr->headerSize = (U32)fhsize; - } - - { BYTE const fhdByte = ip[minInputSize-1]; - size_t pos = minInputSize; - U32 const dictIDSizeCode = fhdByte&3; - U32 const checksumFlag = (fhdByte>>2)&1; - U32 const singleSegment = (fhdByte>>5)&1; - U32 const fcsID = fhdByte>>6; - U64 windowSize = 0; - U32 dictID = 0; - U64 frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN; - if ((fhdByte & 0x08) != 0) - return ERROR(frameParameter_unsupported); /* reserved bits, must be zero */ - - if (!singleSegment) { - BYTE const wlByte = ip[pos++]; - U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN; - if (windowLog > ZSTD_WINDOWLOG_MAX) - return ERROR(frameParameter_windowTooLarge); - windowSize = (1ULL << windowLog); - windowSize += (windowSize >> 3) * (wlByte&7); - } - switch(dictIDSizeCode) - { - default: assert(0); /* impossible */ - case 0 : break; - case 1 : dictID = ip[pos]; pos++; break; - case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break; - case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break; - } - switch(fcsID) - { - default: assert(0); /* impossible */ - case 0 : if (singleSegment) frameContentSize = ip[pos]; break; - case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break; - case 2 : frameContentSize = MEM_readLE32(ip+pos); break; - case 3 : frameContentSize = MEM_readLE64(ip+pos); break; - } - if (singleSegment) windowSize = frameContentSize; - - zfhPtr->frameType = ZSTD_frame; - zfhPtr->frameContentSize = frameContentSize; - zfhPtr->windowSize = windowSize; - zfhPtr->blockSizeMax = (unsigned) MIN(windowSize, ZSTD_BLOCKSIZE_MAX); - zfhPtr->dictID = dictID; - zfhPtr->checksumFlag = checksumFlag; - } - return 0; -} - -/** ZSTD_getFrameHeader() : - * decode Frame Header, or require larger `srcSize`. - * note : this function does not consume input, it only reads it. - * @return : 0, `zfhPtr` is correctly filled, - * >0, `srcSize` is too small, value is wanted `srcSize` amount, - * or an error code, which can be tested using ZSTD_isError() */ -size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize) -{ - return ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, ZSTD_f_zstd1); -} - - -/** ZSTD_getFrameContentSize() : - * compatible with legacy mode - * @return : decompressed size of the single frame pointed to be `src` if known, otherwise - * - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined - * - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */ -unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize) -{ -#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) - if (ZSTD_isLegacy(src, srcSize)) { - unsigned long long const ret = ZSTD_getDecompressedSize_legacy(src, srcSize); - return ret == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : ret; - } -#endif - { ZSTD_frameHeader zfh; - if (ZSTD_getFrameHeader(&zfh, src, srcSize) != 0) - return ZSTD_CONTENTSIZE_ERROR; - if (zfh.frameType == ZSTD_skippableFrame) { - return 0; - } else { - return zfh.frameContentSize; - } } -} - -/** ZSTD_findDecompressedSize() : - * compatible with legacy mode - * `srcSize` must be the exact length of some number of ZSTD compressed and/or - * skippable frames - * @return : decompressed size of the frames contained */ -unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize) -{ - unsigned long long totalDstSize = 0; - - while (srcSize >= ZSTD_frameHeaderSize_prefix) { - U32 const magicNumber = MEM_readLE32(src); - - if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { - size_t skippableSize; - if (srcSize < ZSTD_skippableHeaderSize) - return ERROR(srcSize_wrong); - skippableSize = MEM_readLE32((const BYTE *)src + ZSTD_FRAMEIDSIZE) - + ZSTD_skippableHeaderSize; - if (srcSize < skippableSize) { - return ZSTD_CONTENTSIZE_ERROR; - } - - src = (const BYTE *)src + skippableSize; - srcSize -= skippableSize; - continue; - } - - { unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize); - if (ret >= ZSTD_CONTENTSIZE_ERROR) return ret; - - /* check for overflow */ - if (totalDstSize + ret < totalDstSize) return ZSTD_CONTENTSIZE_ERROR; - totalDstSize += ret; - } - { size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize); - if (ZSTD_isError(frameSrcSize)) { - return ZSTD_CONTENTSIZE_ERROR; - } - - src = (const BYTE *)src + frameSrcSize; - srcSize -= frameSrcSize; - } - } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */ - - if (srcSize) return ZSTD_CONTENTSIZE_ERROR; - - return totalDstSize; -} - -/** ZSTD_getDecompressedSize() : -* compatible with legacy mode -* @return : decompressed size if known, 0 otherwise - note : 0 can mean any of the following : - - frame content is empty - - decompressed size field is not present in frame header - - frame header unknown / not supported - - frame header not complete (`srcSize` too small) */ -unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize) -{ - unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize); - ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_ERROR < ZSTD_CONTENTSIZE_UNKNOWN); - return (ret >= ZSTD_CONTENTSIZE_ERROR) ? 0 : ret; -} - - -/** ZSTD_decodeFrameHeader() : -* `headerSize` must be the size provided by ZSTD_frameHeaderSize(). -* @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */ -static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize) -{ - size_t const result = ZSTD_getFrameHeader_advanced(&(dctx->fParams), src, headerSize, dctx->format); - if (ZSTD_isError(result)) return result; /* invalid header */ - if (result>0) return ERROR(srcSize_wrong); /* headerSize too small */ - if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID)) - return ERROR(dictionary_wrong); - if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0); - return 0; -} - - -/*-************************************************************* - * Block decoding - ***************************************************************/ - -/*! ZSTD_getcBlockSize() : -* Provides the size of compressed block from block header `src` */ -size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, - blockProperties_t* bpPtr) -{ - if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong); - { U32 const cBlockHeader = MEM_readLE24(src); - U32 const cSize = cBlockHeader >> 3; - bpPtr->lastBlock = cBlockHeader & 1; - bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3); - bpPtr->origSize = cSize; /* only useful for RLE */ - if (bpPtr->blockType == bt_rle) return 1; - if (bpPtr->blockType == bt_reserved) return ERROR(corruption_detected); - return cSize; - } -} - - -static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity, - const void* src, size_t srcSize) -{ - if (dst==NULL) return ERROR(dstSize_tooSmall); - if (srcSize > dstCapacity) return ERROR(dstSize_tooSmall); - memcpy(dst, src, srcSize); - return srcSize; -} - - -static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - size_t regenSize) -{ - if (srcSize != 1) return ERROR(srcSize_wrong); - if (regenSize > dstCapacity) return ERROR(dstSize_tooSmall); - memset(dst, *(const BYTE*)src, regenSize); - return regenSize; -} - -/* Hidden declaration for fullbench */ -size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, - const void* src, size_t srcSize); -/*! ZSTD_decodeLiteralsBlock() : - * @return : nb of bytes read from src (< srcSize ) - * note : symbol not declared but exposed for fullbench */ -size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, - const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */ -{ - if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected); - - { const BYTE* const istart = (const BYTE*) src; - symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3); - - switch(litEncType) - { - case set_repeat: - if (dctx->litEntropy==0) return ERROR(dictionary_corrupted); - /* fall-through */ - - case set_compressed: - if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */ - { size_t lhSize, litSize, litCSize; - U32 singleStream=0; - U32 const lhlCode = (istart[0] >> 2) & 3; - U32 const lhc = MEM_readLE32(istart); - switch(lhlCode) - { - case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */ - /* 2 - 2 - 10 - 10 */ - singleStream = !lhlCode; - lhSize = 3; - litSize = (lhc >> 4) & 0x3FF; - litCSize = (lhc >> 14) & 0x3FF; - break; - case 2: - /* 2 - 2 - 14 - 14 */ - lhSize = 4; - litSize = (lhc >> 4) & 0x3FFF; - litCSize = lhc >> 18; - break; - case 3: - /* 2 - 2 - 18 - 18 */ - lhSize = 5; - litSize = (lhc >> 4) & 0x3FFFF; - litCSize = (lhc >> 22) + (istart[4] << 10); - break; - } - if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected); - if (litCSize + lhSize > srcSize) return ERROR(corruption_detected); - - /* prefetch huffman table if cold */ - if (dctx->ddictIsCold && (litSize > 768 /* heuristic */)) { - PREFETCH_AREA(dctx->HUFptr, sizeof(dctx->entropy.hufTable)); - } - - if (HUF_isError((litEncType==set_repeat) ? - ( singleStream ? - HUF_decompress1X_usingDTable_bmi2(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr, dctx->bmi2) : - HUF_decompress4X_usingDTable_bmi2(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr, dctx->bmi2) ) : - ( singleStream ? - HUF_decompress1X1_DCtx_wksp_bmi2(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize, - dctx->workspace, sizeof(dctx->workspace), dctx->bmi2) : - HUF_decompress4X_hufOnly_wksp_bmi2(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize, - dctx->workspace, sizeof(dctx->workspace), dctx->bmi2)))) - return ERROR(corruption_detected); - - dctx->litPtr = dctx->litBuffer; - dctx->litSize = litSize; - dctx->litEntropy = 1; - if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable; - memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); - return litCSize + lhSize; - } - - case set_basic: - { size_t litSize, lhSize; - U32 const lhlCode = ((istart[0]) >> 2) & 3; - switch(lhlCode) - { - case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */ - lhSize = 1; - litSize = istart[0] >> 3; - break; - case 1: - lhSize = 2; - litSize = MEM_readLE16(istart) >> 4; - break; - case 3: - lhSize = 3; - litSize = MEM_readLE24(istart) >> 4; - break; - } - - if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */ - if (litSize+lhSize > srcSize) return ERROR(corruption_detected); - memcpy(dctx->litBuffer, istart+lhSize, litSize); - dctx->litPtr = dctx->litBuffer; - dctx->litSize = litSize; - memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); - return lhSize+litSize; - } - /* direct reference into compressed stream */ - dctx->litPtr = istart+lhSize; - dctx->litSize = litSize; - return lhSize+litSize; - } - - case set_rle: - { U32 const lhlCode = ((istart[0]) >> 2) & 3; - size_t litSize, lhSize; - switch(lhlCode) - { - case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */ - lhSize = 1; - litSize = istart[0] >> 3; - break; - case 1: - lhSize = 2; - litSize = MEM_readLE16(istart) >> 4; - break; - case 3: - lhSize = 3; - litSize = MEM_readLE24(istart) >> 4; - if (srcSize<4) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */ - break; - } - if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected); - memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH); - dctx->litPtr = dctx->litBuffer; - dctx->litSize = litSize; - return lhSize+1; - } - default: - return ERROR(corruption_detected); /* impossible */ - } - } -} - -/* Default FSE distribution tables. - * These are pre-calculated FSE decoding tables using default distributions as defined in specification : - * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#default-distributions - * They were generated programmatically with following method : - * - start from default distributions, present in /lib/common/zstd_internal.h - * - generate tables normally, using ZSTD_buildFSETable() - * - printout the content of tables - * - pretify output, report below, test with fuzzer to ensure it's correct */ - -/* Default FSE distribution table for Literal Lengths */ -static const ZSTD_seqSymbol LL_defaultDTable[(1<tableLog = 0; - DTableH->fastMode = 0; - - cell->nbBits = 0; - cell->nextState = 0; - assert(nbAddBits < 255); - cell->nbAdditionalBits = (BYTE)nbAddBits; - cell->baseValue = baseValue; -} - - -/* ZSTD_buildFSETable() : - * generate FSE decoding table for one symbol (ll, ml or off) */ -static void -ZSTD_buildFSETable(ZSTD_seqSymbol* dt, - const short* normalizedCounter, unsigned maxSymbolValue, - const U32* baseValue, const U32* nbAdditionalBits, - unsigned tableLog) -{ - ZSTD_seqSymbol* const tableDecode = dt+1; - U16 symbolNext[MaxSeq+1]; - - U32 const maxSV1 = maxSymbolValue + 1; - U32 const tableSize = 1 << tableLog; - U32 highThreshold = tableSize-1; - - /* Sanity Checks */ - assert(maxSymbolValue <= MaxSeq); - assert(tableLog <= MaxFSELog); - - /* Init, lay down lowprob symbols */ - { ZSTD_seqSymbol_header DTableH; - DTableH.tableLog = tableLog; - DTableH.fastMode = 1; - { S16 const largeLimit= (S16)(1 << (tableLog-1)); - U32 s; - for (s=0; s= largeLimit) DTableH.fastMode=0; - symbolNext[s] = normalizedCounter[s]; - } } } - memcpy(dt, &DTableH, sizeof(DTableH)); - } - - /* Spread symbols */ - { U32 const tableMask = tableSize-1; - U32 const step = FSE_TABLESTEP(tableSize); - U32 s, position = 0; - for (s=0; s highThreshold) position = (position + step) & tableMask; /* lowprob area */ - } } - assert(position == 0); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ - } - - /* Build Decoding table */ - { U32 u; - for (u=0; u max) return ERROR(corruption_detected); - { U32 const symbol = *(const BYTE*)src; - U32 const baseline = baseValue[symbol]; - U32 const nbBits = nbAdditionalBits[symbol]; - ZSTD_buildSeqTable_rle(DTableSpace, baseline, nbBits); - } - *DTablePtr = DTableSpace; - return 1; - case set_basic : - *DTablePtr = defaultTable; - return 0; - case set_repeat: - if (!flagRepeatTable) return ERROR(corruption_detected); - /* prefetch FSE table if used */ - if (ddictIsCold && (nbSeq > 24 /* heuristic */)) { - const void* const pStart = *DTablePtr; - size_t const pSize = sizeof(ZSTD_seqSymbol) * (SEQSYMBOL_TABLE_SIZE(maxLog)); - PREFETCH_AREA(pStart, pSize); - } - return 0; - case set_compressed : - { U32 tableLog; - S16 norm[MaxSeq+1]; - size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize); - if (FSE_isError(headerSize)) return ERROR(corruption_detected); - if (tableLog > maxLog) return ERROR(corruption_detected); - ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog); - *DTablePtr = DTableSpace; - return headerSize; - } - default : /* impossible */ - assert(0); - return ERROR(GENERIC); - } -} - -static const U32 LL_base[MaxLL+1] = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 18, 20, 22, 24, 28, 32, 40, - 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, - 0x2000, 0x4000, 0x8000, 0x10000 }; - -static const U32 OF_base[MaxOff+1] = { - 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, - 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, - 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, - 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD }; - -static const U32 OF_bits[MaxOff+1] = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31 }; - -static const U32 ML_base[MaxML+1] = { - 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, - 35, 37, 39, 41, 43, 47, 51, 59, - 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, - 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; - -/* Hidden delcaration for fullbench */ -size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, - const void* src, size_t srcSize); - -size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, - const void* src, size_t srcSize) -{ - const BYTE* const istart = (const BYTE* const)src; - const BYTE* const iend = istart + srcSize; - const BYTE* ip = istart; - int nbSeq; - DEBUGLOG(5, "ZSTD_decodeSeqHeaders"); - - /* check */ - if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong); - - /* SeqHead */ - nbSeq = *ip++; - if (!nbSeq) { *nbSeqPtr=0; return 1; } - if (nbSeq > 0x7F) { - if (nbSeq == 0xFF) { - if (ip+2 > iend) return ERROR(srcSize_wrong); - nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2; - } else { - if (ip >= iend) return ERROR(srcSize_wrong); - nbSeq = ((nbSeq-0x80)<<8) + *ip++; - } - } - *nbSeqPtr = nbSeq; - - /* FSE table descriptors */ - if (ip+4 > iend) return ERROR(srcSize_wrong); /* minimum possible size */ - { symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6); - symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3); - symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3); - ip++; - - /* Build DTables */ - { size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr, - LLtype, MaxLL, LLFSELog, - ip, iend-ip, - LL_base, LL_bits, - LL_defaultDTable, dctx->fseEntropy, - dctx->ddictIsCold, nbSeq); - if (ZSTD_isError(llhSize)) return ERROR(corruption_detected); - ip += llhSize; - } - - { size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr, - OFtype, MaxOff, OffFSELog, - ip, iend-ip, - OF_base, OF_bits, - OF_defaultDTable, dctx->fseEntropy, - dctx->ddictIsCold, nbSeq); - if (ZSTD_isError(ofhSize)) return ERROR(corruption_detected); - ip += ofhSize; - } - - { size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr, - MLtype, MaxML, MLFSELog, - ip, iend-ip, - ML_base, ML_bits, - ML_defaultDTable, dctx->fseEntropy, - dctx->ddictIsCold, nbSeq); - if (ZSTD_isError(mlhSize)) return ERROR(corruption_detected); - ip += mlhSize; - } - } - - /* prefetch dictionary content */ - if (dctx->ddictIsCold) { - size_t const dictSize = (const char*)dctx->prefixStart - (const char*)dctx->virtualStart; - size_t const psmin = MIN(dictSize, (size_t)(64*nbSeq) /* heuristic */ ); - size_t const pSize = MIN(psmin, 128 KB /* protection */ ); - const void* const pStart = (const char*)dctx->dictEnd - pSize; - PREFETCH_AREA(pStart, pSize); - dctx->ddictIsCold = 0; - } - - return ip-istart; -} - - -typedef struct { - size_t litLength; - size_t matchLength; - size_t offset; - const BYTE* match; -} seq_t; - -typedef struct { - size_t state; - const ZSTD_seqSymbol* table; -} ZSTD_fseState; - -typedef struct { - BIT_DStream_t DStream; - ZSTD_fseState stateLL; - ZSTD_fseState stateOffb; - ZSTD_fseState stateML; - size_t prevOffset[ZSTD_REP_NUM]; - const BYTE* prefixStart; - const BYTE* dictEnd; - size_t pos; -} seqState_t; - - -FORCE_NOINLINE -size_t ZSTD_execSequenceLast7(BYTE* op, - BYTE* const oend, seq_t sequence, - const BYTE** litPtr, const BYTE* const litLimit, - const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) -{ - BYTE* const oLitEnd = op + sequence.litLength; - size_t const sequenceLength = sequence.litLength + sequence.matchLength; - BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ - BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; - const BYTE* const iLitEnd = *litPtr + sequence.litLength; - const BYTE* match = oLitEnd - sequence.offset; - - /* check */ - if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ - if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ - if (oLitEnd <= oend_w) return ERROR(GENERIC); /* Precondition */ - - /* copy literals */ - if (op < oend_w) { - ZSTD_wildcopy(op, *litPtr, oend_w - op); - *litPtr += oend_w - op; - op = oend_w; - } - while (op < oLitEnd) *op++ = *(*litPtr)++; - - /* copy Match */ - if (sequence.offset > (size_t)(oLitEnd - base)) { - /* offset beyond prefix */ - if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected); - match = dictEnd - (base-match); - if (match + sequence.matchLength <= dictEnd) { - memmove(oLitEnd, match, sequence.matchLength); - return sequenceLength; - } - /* span extDict & currentPrefixSegment */ - { size_t const length1 = dictEnd - match; - memmove(oLitEnd, match, length1); - op = oLitEnd + length1; - sequence.matchLength -= length1; - match = base; - } } - while (op < oMatchEnd) *op++ = *match++; - return sequenceLength; -} - - -HINT_INLINE -size_t ZSTD_execSequence(BYTE* op, - BYTE* const oend, seq_t sequence, - const BYTE** litPtr, const BYTE* const litLimit, - const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) -{ - BYTE* const oLitEnd = op + sequence.litLength; - size_t const sequenceLength = sequence.litLength + sequence.matchLength; - BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ - BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; - const BYTE* const iLitEnd = *litPtr + sequence.litLength; - const BYTE* match = oLitEnd - sequence.offset; - - /* check */ - if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ - if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ - if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd); - - /* copy Literals */ - ZSTD_copy8(op, *litPtr); - if (sequence.litLength > 8) - ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ - op = oLitEnd; - *litPtr = iLitEnd; /* update for next sequence */ - - /* copy Match */ - if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { - /* offset beyond prefix -> go into extDict */ - if (sequence.offset > (size_t)(oLitEnd - virtualStart)) - return ERROR(corruption_detected); - match = dictEnd + (match - prefixStart); - if (match + sequence.matchLength <= dictEnd) { - memmove(oLitEnd, match, sequence.matchLength); - return sequenceLength; - } - /* span extDict & currentPrefixSegment */ - { size_t const length1 = dictEnd - match; - memmove(oLitEnd, match, length1); - op = oLitEnd + length1; - sequence.matchLength -= length1; - match = prefixStart; - if (op > oend_w || sequence.matchLength < MINMATCH) { - U32 i; - for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; - return sequenceLength; - } - } } - /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */ - - /* match within prefix */ - if (sequence.offset < 8) { - /* close range match, overlap */ - static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ - static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */ - int const sub2 = dec64table[sequence.offset]; - op[0] = match[0]; - op[1] = match[1]; - op[2] = match[2]; - op[3] = match[3]; - match += dec32table[sequence.offset]; - ZSTD_copy4(op+4, match); - match -= sub2; - } else { - ZSTD_copy8(op, match); - } - op += 8; match += 8; - - if (oMatchEnd > oend-(16-MINMATCH)) { - if (op < oend_w) { - ZSTD_wildcopy(op, match, oend_w - op); - match += oend_w - op; - op = oend_w; - } - while (op < oMatchEnd) *op++ = *match++; - } else { - ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */ - } - return sequenceLength; -} - - -HINT_INLINE -size_t ZSTD_execSequenceLong(BYTE* op, - BYTE* const oend, seq_t sequence, - const BYTE** litPtr, const BYTE* const litLimit, - const BYTE* const prefixStart, const BYTE* const dictStart, const BYTE* const dictEnd) -{ - BYTE* const oLitEnd = op + sequence.litLength; - size_t const sequenceLength = sequence.litLength + sequence.matchLength; - BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ - BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; - const BYTE* const iLitEnd = *litPtr + sequence.litLength; - const BYTE* match = sequence.match; - - /* check */ - if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ - if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ - if (oLitEnd > oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, prefixStart, dictStart, dictEnd); - - /* copy Literals */ - ZSTD_copy8(op, *litPtr); /* note : op <= oLitEnd <= oend_w == oend - 8 */ - if (sequence.litLength > 8) - ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ - op = oLitEnd; - *litPtr = iLitEnd; /* update for next sequence */ - - /* copy Match */ - if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { - /* offset beyond prefix */ - if (sequence.offset > (size_t)(oLitEnd - dictStart)) return ERROR(corruption_detected); - if (match + sequence.matchLength <= dictEnd) { - memmove(oLitEnd, match, sequence.matchLength); - return sequenceLength; - } - /* span extDict & currentPrefixSegment */ - { size_t const length1 = dictEnd - match; - memmove(oLitEnd, match, length1); - op = oLitEnd + length1; - sequence.matchLength -= length1; - match = prefixStart; - if (op > oend_w || sequence.matchLength < MINMATCH) { - U32 i; - for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; - return sequenceLength; - } - } } - assert(op <= oend_w); - assert(sequence.matchLength >= MINMATCH); - - /* match within prefix */ - if (sequence.offset < 8) { - /* close range match, overlap */ - static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ - static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */ - int const sub2 = dec64table[sequence.offset]; - op[0] = match[0]; - op[1] = match[1]; - op[2] = match[2]; - op[3] = match[3]; - match += dec32table[sequence.offset]; - ZSTD_copy4(op+4, match); - match -= sub2; - } else { - ZSTD_copy8(op, match); - } - op += 8; match += 8; - - if (oMatchEnd > oend-(16-MINMATCH)) { - if (op < oend_w) { - ZSTD_wildcopy(op, match, oend_w - op); - match += oend_w - op; - op = oend_w; - } - while (op < oMatchEnd) *op++ = *match++; - } else { - ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */ - } - return sequenceLength; -} - -static void -ZSTD_initFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqSymbol* dt) -{ - const void* ptr = dt; - const ZSTD_seqSymbol_header* const DTableH = (const ZSTD_seqSymbol_header*)ptr; - DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog); - DEBUGLOG(6, "ZSTD_initFseState : val=%u using %u bits", - (U32)DStatePtr->state, DTableH->tableLog); - BIT_reloadDStream(bitD); - DStatePtr->table = dt + 1; -} - -FORCE_INLINE_TEMPLATE void -ZSTD_updateFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD) -{ - ZSTD_seqSymbol const DInfo = DStatePtr->table[DStatePtr->state]; - U32 const nbBits = DInfo.nbBits; - size_t const lowBits = BIT_readBits(bitD, nbBits); - DStatePtr->state = DInfo.nextState + lowBits; -} - -/* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum - * offset bits. But we can only read at most (STREAM_ACCUMULATOR_MIN_32 - 1) - * bits before reloading. This value is the maximum number of bytes we read - * after reloading when we are decoding long offets. - */ -#define LONG_OFFSETS_MAX_EXTRA_BITS_32 \ - (ZSTD_WINDOWLOG_MAX_32 > STREAM_ACCUMULATOR_MIN_32 \ - ? ZSTD_WINDOWLOG_MAX_32 - STREAM_ACCUMULATOR_MIN_32 \ - : 0) - -typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e; - -FORCE_INLINE_TEMPLATE seq_t -ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) -{ - seq_t seq = {0}; - U32 const llBits = seqState->stateLL.table[seqState->stateLL.state].nbAdditionalBits; - U32 const mlBits = seqState->stateML.table[seqState->stateML.state].nbAdditionalBits; - U32 const ofBits = seqState->stateOffb.table[seqState->stateOffb.state].nbAdditionalBits; - U32 const totalBits = llBits+mlBits+ofBits; - U32 const llBase = seqState->stateLL.table[seqState->stateLL.state].baseValue; - U32 const mlBase = seqState->stateML.table[seqState->stateML.state].baseValue; - U32 const ofBase = seqState->stateOffb.table[seqState->stateOffb.state].baseValue; - - /* sequence */ - { size_t offset; - if (!ofBits) - offset = 0; - else { - ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1); - ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5); - assert(ofBits <= MaxOff); - if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) { - U32 const extraBits = ofBits - MIN(ofBits, 32 - seqState->DStream.bitsConsumed); - offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits); - BIT_reloadDStream(&seqState->DStream); - if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits); - assert(extraBits <= LONG_OFFSETS_MAX_EXTRA_BITS_32); /* to avoid another reload */ - } else { - offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ - if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); - } - } - - if (ofBits <= 1) { - offset += (llBase==0); - if (offset) { - size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; - temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ - if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset = temp; - } else { /* offset == 0 */ - offset = seqState->prevOffset[0]; - } - } else { - seqState->prevOffset[2] = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset; - } - seq.offset = offset; - } - - seq.matchLength = mlBase - + ((mlBits>0) ? BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/) : 0); /* <= 16 bits */ - if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32)) - BIT_reloadDStream(&seqState->DStream); - if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog))) - BIT_reloadDStream(&seqState->DStream); - /* Ensure there are enough bits to read the rest of data in 64-bit mode. */ - ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64); - - seq.litLength = llBase - + ((llBits>0) ? BIT_readBitsFast(&seqState->DStream, llBits/*>0*/) : 0); /* <= 16 bits */ - if (MEM_32bits()) - BIT_reloadDStream(&seqState->DStream); - - DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u", - (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); - - /* ANS state update */ - ZSTD_updateFseState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ - ZSTD_updateFseState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ - if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ - ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ - - return seq; -} - -FORCE_INLINE_TEMPLATE size_t -ZSTD_decompressSequences_body( ZSTD_DCtx* dctx, - void* dst, size_t maxDstSize, - const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset) -{ - const BYTE* ip = (const BYTE*)seqStart; - const BYTE* const iend = ip + seqSize; - BYTE* const ostart = (BYTE* const)dst; - BYTE* const oend = ostart + maxDstSize; - BYTE* op = ostart; - const BYTE* litPtr = dctx->litPtr; - const BYTE* const litEnd = litPtr + dctx->litSize; - const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart); - const BYTE* const vBase = (const BYTE*) (dctx->virtualStart); - const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); - DEBUGLOG(5, "ZSTD_decompressSequences_body"); - - /* Regen sequences */ - if (nbSeq) { - seqState_t seqState; - dctx->fseEntropy = 1; - { U32 i; for (i=0; ientropy.rep[i]; } - CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); - ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); - ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); - ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); - - for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) { - nbSeq--; - { seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset); - size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd); - DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); - if (ZSTD_isError(oneSeqSize)) return oneSeqSize; - op += oneSeqSize; - } } - - /* check if reached exact end */ - DEBUGLOG(5, "ZSTD_decompressSequences_body: after decode loop, remaining nbSeq : %i", nbSeq); - if (nbSeq) return ERROR(corruption_detected); - /* save reps for next block */ - { U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); } - } - - /* last literal segment */ - { size_t const lastLLSize = litEnd - litPtr; - if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall); - memcpy(op, litPtr, lastLLSize); - op += lastLLSize; - } - - return op-ostart; -} - -static size_t -ZSTD_decompressSequences_default(ZSTD_DCtx* dctx, - void* dst, size_t maxDstSize, - const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset) -{ - return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); -} - - - -FORCE_INLINE_TEMPLATE seq_t -ZSTD_decodeSequenceLong(seqState_t* seqState, ZSTD_longOffset_e const longOffsets) -{ - seq_t seq; - U32 const llBits = seqState->stateLL.table[seqState->stateLL.state].nbAdditionalBits; - U32 const mlBits = seqState->stateML.table[seqState->stateML.state].nbAdditionalBits; - U32 const ofBits = seqState->stateOffb.table[seqState->stateOffb.state].nbAdditionalBits; - U32 const totalBits = llBits+mlBits+ofBits; - U32 const llBase = seqState->stateLL.table[seqState->stateLL.state].baseValue; - U32 const mlBase = seqState->stateML.table[seqState->stateML.state].baseValue; - U32 const ofBase = seqState->stateOffb.table[seqState->stateOffb.state].baseValue; - - /* sequence */ - { size_t offset; - if (!ofBits) - offset = 0; - else { - ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1); - ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5); - assert(ofBits <= MaxOff); - if (MEM_32bits() && longOffsets) { - U32 const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN_32-1); - offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits); - if (MEM_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream); - if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits); - } else { - offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ - if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); - } - } - - if (ofBits <= 1) { - offset += (llBase==0); - if (offset) { - size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; - temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ - if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset = temp; - } else { - offset = seqState->prevOffset[0]; - } - } else { - seqState->prevOffset[2] = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset; - } - seq.offset = offset; - } - - seq.matchLength = mlBase + ((mlBits>0) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ - if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32)) - BIT_reloadDStream(&seqState->DStream); - if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog))) - BIT_reloadDStream(&seqState->DStream); - /* Verify that there is enough bits to read the rest of the data in 64-bit mode. */ - ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64); - - seq.litLength = llBase + ((llBits>0) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */ - if (MEM_32bits()) - BIT_reloadDStream(&seqState->DStream); - - { size_t const pos = seqState->pos + seq.litLength; - const BYTE* const matchBase = (seq.offset > pos) ? seqState->dictEnd : seqState->prefixStart; - seq.match = matchBase + pos - seq.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted. - * No consequence though : no memory access will occur, overly large offset will be detected in ZSTD_execSequenceLong() */ - seqState->pos = pos + seq.matchLength; - } - - /* ANS state update */ - ZSTD_updateFseState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ - ZSTD_updateFseState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ - if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ - ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ - - return seq; -} - -FORCE_INLINE_TEMPLATE size_t -ZSTD_decompressSequencesLong_body( - ZSTD_DCtx* dctx, - void* dst, size_t maxDstSize, - const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset) -{ - const BYTE* ip = (const BYTE*)seqStart; - const BYTE* const iend = ip + seqSize; - BYTE* const ostart = (BYTE* const)dst; - BYTE* const oend = ostart + maxDstSize; - BYTE* op = ostart; - const BYTE* litPtr = dctx->litPtr; - const BYTE* const litEnd = litPtr + dctx->litSize; - const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart); - const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart); - const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); - - /* Regen sequences */ - if (nbSeq) { -#define STORED_SEQS 4 -#define STOSEQ_MASK (STORED_SEQS-1) -#define ADVANCED_SEQS 4 - seq_t sequences[STORED_SEQS]; - int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); - seqState_t seqState; - int seqNb; - dctx->fseEntropy = 1; - { U32 i; for (i=0; ientropy.rep[i]; } - seqState.prefixStart = prefixStart; - seqState.pos = (size_t)(op-prefixStart); - seqState.dictEnd = dictEnd; - CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); - ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); - ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); - ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); - - /* prepare in advance */ - for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && (seqNbentropy.rep[i] = (U32)(seqState.prevOffset[i]); } -#undef STORED_SEQS -#undef STOSEQ_MASK -#undef ADVANCED_SEQS - } - - /* last literal segment */ - { size_t const lastLLSize = litEnd - litPtr; - if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall); - memcpy(op, litPtr, lastLLSize); - op += lastLLSize; - } - - return op-ostart; -} - -static size_t -ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx, - void* dst, size_t maxDstSize, - const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset) -{ - return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); -} - - - -#if DYNAMIC_BMI2 - -static TARGET_ATTRIBUTE("bmi2") size_t -ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx, - void* dst, size_t maxDstSize, - const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset) -{ - return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); -} - -static TARGET_ATTRIBUTE("bmi2") size_t -ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx, - void* dst, size_t maxDstSize, - const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset) -{ - return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); -} - -#endif - -typedef size_t (*ZSTD_decompressSequences_t)( - ZSTD_DCtx *dctx, void *dst, size_t maxDstSize, - const void *seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset); - -static size_t ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, - const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset) -{ - DEBUGLOG(5, "ZSTD_decompressSequences"); -#if DYNAMIC_BMI2 - if (dctx->bmi2) { - return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); - } -#endif - return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); -} - -static size_t ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx, - void* dst, size_t maxDstSize, - const void* seqStart, size_t seqSize, int nbSeq, - const ZSTD_longOffset_e isLongOffset) -{ - DEBUGLOG(5, "ZSTD_decompressSequencesLong"); -#if DYNAMIC_BMI2 - if (dctx->bmi2) { - return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); - } -#endif - return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); -} - -/* ZSTD_getLongOffsetsShare() : - * condition : offTable must be valid - * @return : "share" of long offsets (arbitrarily defined as > (1<<23)) - * compared to maximum possible of (1< 22) total += 1; - } - - assert(tableLog <= OffFSELog); - total <<= (OffFSELog - tableLog); /* scale to OffFSELog */ - - return total; -} - - -static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, const int frame) -{ /* blockType == blockCompressed */ - const BYTE* ip = (const BYTE*)src; - /* isLongOffset must be true if there are long offsets. - * Offsets are long if they are larger than 2^STREAM_ACCUMULATOR_MIN. - * We don't expect that to be the case in 64-bit mode. - * In block mode, window size is not known, so we have to be conservative. - * (note: but it could be evaluated from current-lowLimit) - */ - ZSTD_longOffset_e const isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (!frame || dctx->fParams.windowSize > (1ULL << STREAM_ACCUMULATOR_MIN))); - DEBUGLOG(5, "ZSTD_decompressBlock_internal (size : %u)", (U32)srcSize); - - if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); - - /* Decode literals section */ - { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize); - DEBUGLOG(5, "ZSTD_decodeLiteralsBlock : %u", (U32)litCSize); - if (ZSTD_isError(litCSize)) return litCSize; - ip += litCSize; - srcSize -= litCSize; - } - - /* Build Decoding Tables */ - { int nbSeq; - size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, srcSize); - if (ZSTD_isError(seqHSize)) return seqHSize; - ip += seqHSize; - srcSize -= seqHSize; - - if ( (!frame || dctx->fParams.windowSize > (1<<24)) - && (nbSeq>0) ) { /* could probably use a larger nbSeq limit */ - U32 const shareLongOffsets = ZSTD_getLongOffsetsShare(dctx->OFTptr); - U32 const minShare = MEM_64bits() ? 7 : 20; /* heuristic values, correspond to 2.73% and 7.81% */ - if (shareLongOffsets >= minShare) - return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); - } - - return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); - } -} - - -static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst) -{ - if (dst != dctx->previousDstEnd) { /* not contiguous */ - dctx->dictEnd = dctx->previousDstEnd; - dctx->virtualStart = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart)); - dctx->prefixStart = dst; - dctx->previousDstEnd = dst; - } -} - -size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize) -{ - size_t dSize; - ZSTD_checkContinuity(dctx, dst); - dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0); - dctx->previousDstEnd = (char*)dst + dSize; - return dSize; -} - - -/** ZSTD_insertBlock() : - insert `src` block into `dctx` history. Useful to track uncompressed blocks. */ -ZSTDLIB_API size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize) -{ - ZSTD_checkContinuity(dctx, blockStart); - dctx->previousDstEnd = (const char*)blockStart + blockSize; - return blockSize; -} - - -static size_t ZSTD_generateNxBytes(void* dst, size_t dstCapacity, BYTE value, size_t length) -{ - if (length > dstCapacity) return ERROR(dstSize_tooSmall); - memset(dst, value, length); - return length; -} - -/** ZSTD_findFrameCompressedSize() : - * compatible with legacy mode - * `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame - * `srcSize` must be at least as large as the frame contained - * @return : the compressed size of the frame starting at `src` */ -size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize) -{ -#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) - if (ZSTD_isLegacy(src, srcSize)) - return ZSTD_findFrameCompressedSizeLegacy(src, srcSize); -#endif - if ( (srcSize >= ZSTD_skippableHeaderSize) - && (MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START ) { - return ZSTD_skippableHeaderSize + MEM_readLE32((const BYTE*)src + ZSTD_FRAMEIDSIZE); - } else { - const BYTE* ip = (const BYTE*)src; - const BYTE* const ipstart = ip; - size_t remainingSize = srcSize; - ZSTD_frameHeader zfh; - - /* Extract Frame Header */ - { size_t const ret = ZSTD_getFrameHeader(&zfh, src, srcSize); - if (ZSTD_isError(ret)) return ret; - if (ret > 0) return ERROR(srcSize_wrong); - } - - ip += zfh.headerSize; - remainingSize -= zfh.headerSize; - - /* Loop on each block */ - while (1) { - blockProperties_t blockProperties; - size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties); - if (ZSTD_isError(cBlockSize)) return cBlockSize; - - if (ZSTD_blockHeaderSize + cBlockSize > remainingSize) - return ERROR(srcSize_wrong); - - ip += ZSTD_blockHeaderSize + cBlockSize; - remainingSize -= ZSTD_blockHeaderSize + cBlockSize; - - if (blockProperties.lastBlock) break; - } - - if (zfh.checksumFlag) { /* Final frame content checksum */ - if (remainingSize < 4) return ERROR(srcSize_wrong); - ip += 4; - } - - return ip - ipstart; - } -} - -/*! ZSTD_decompressFrame() : -* @dctx must be properly initialized */ -static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, - void* dst, size_t dstCapacity, - const void** srcPtr, size_t *srcSizePtr) -{ - const BYTE* ip = (const BYTE*)(*srcPtr); - BYTE* const ostart = (BYTE* const)dst; - BYTE* const oend = ostart + dstCapacity; - BYTE* op = ostart; - size_t remainingSize = *srcSizePtr; - - /* check */ - if (remainingSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) - return ERROR(srcSize_wrong); - - /* Frame Header */ - { size_t const frameHeaderSize = ZSTD_frameHeaderSize(ip, ZSTD_frameHeaderSize_prefix); - if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize; - if (remainingSize < frameHeaderSize+ZSTD_blockHeaderSize) - return ERROR(srcSize_wrong); - CHECK_F( ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize) ); - ip += frameHeaderSize; remainingSize -= frameHeaderSize; - } - - /* Loop on each block */ - while (1) { - size_t decodedSize; - blockProperties_t blockProperties; - size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties); - if (ZSTD_isError(cBlockSize)) return cBlockSize; - - ip += ZSTD_blockHeaderSize; - remainingSize -= ZSTD_blockHeaderSize; - if (cBlockSize > remainingSize) return ERROR(srcSize_wrong); - - switch(blockProperties.blockType) - { - case bt_compressed: - decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize, /* frame */ 1); - break; - case bt_raw : - decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize); - break; - case bt_rle : - decodedSize = ZSTD_generateNxBytes(op, oend-op, *ip, blockProperties.origSize); - break; - case bt_reserved : - default: - return ERROR(corruption_detected); - } - - if (ZSTD_isError(decodedSize)) return decodedSize; - if (dctx->fParams.checksumFlag) - XXH64_update(&dctx->xxhState, op, decodedSize); - op += decodedSize; - ip += cBlockSize; - remainingSize -= cBlockSize; - if (blockProperties.lastBlock) break; - } - - if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) { - if ((U64)(op-ostart) != dctx->fParams.frameContentSize) { - return ERROR(corruption_detected); - } } - if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */ - U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState); - U32 checkRead; - if (remainingSize<4) return ERROR(checksum_wrong); - checkRead = MEM_readLE32(ip); - if (checkRead != checkCalc) return ERROR(checksum_wrong); - ip += 4; - remainingSize -= 4; - } - - /* Allow caller to get size read */ - *srcPtr = ip; - *srcSizePtr = remainingSize; - return op-ostart; -} - -static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - const void* dict, size_t dictSize, - const ZSTD_DDict* ddict) -{ - void* const dststart = dst; - int moreThan1Frame = 0; - - DEBUGLOG(5, "ZSTD_decompressMultiFrame"); - assert(dict==NULL || ddict==NULL); /* either dict or ddict set, not both */ - - if (ddict) { - dict = ZSTD_DDictDictContent(ddict); - dictSize = ZSTD_DDictDictSize(ddict); - } - - while (srcSize >= ZSTD_frameHeaderSize_prefix) { - -#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) - if (ZSTD_isLegacy(src, srcSize)) { - size_t decodedSize; - size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize); - if (ZSTD_isError(frameSize)) return frameSize; - /* legacy support is not compatible with static dctx */ - if (dctx->staticSize) return ERROR(memory_allocation); - - decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize); - - dst = (BYTE*)dst + decodedSize; - dstCapacity -= decodedSize; - - src = (const BYTE*)src + frameSize; - srcSize -= frameSize; - - continue; - } -#endif - - { U32 const magicNumber = MEM_readLE32(src); - DEBUGLOG(4, "reading magic number %08X (expecting %08X)", - (U32)magicNumber, (U32)ZSTD_MAGICNUMBER); - if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { - size_t skippableSize; - if (srcSize < ZSTD_skippableHeaderSize) - return ERROR(srcSize_wrong); - skippableSize = MEM_readLE32((const BYTE*)src + ZSTD_FRAMEIDSIZE) - + ZSTD_skippableHeaderSize; - if (srcSize < skippableSize) return ERROR(srcSize_wrong); - - src = (const BYTE *)src + skippableSize; - srcSize -= skippableSize; - continue; - } } - - if (ddict) { - /* we were called from ZSTD_decompress_usingDDict */ - CHECK_F(ZSTD_decompressBegin_usingDDict(dctx, ddict)); - } else { - /* this will initialize correctly with no dict if dict == NULL, so - * use this in all cases but ddict */ - CHECK_F(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize)); - } - ZSTD_checkContinuity(dctx, dst); - - { const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity, - &src, &srcSize); - if ( (ZSTD_getErrorCode(res) == ZSTD_error_prefix_unknown) - && (moreThan1Frame==1) ) { - /* at least one frame successfully completed, - * but following bytes are garbage : - * it's more likely to be a srcSize error, - * specifying more bytes than compressed size of frame(s). - * This error message replaces ERROR(prefix_unknown), - * which would be confusing, as the first header is actually correct. - * Note that one could be unlucky, it might be a corruption error instead, - * happening right at the place where we expect zstd magic bytes. - * But this is _much_ less likely than a srcSize field error. */ - return ERROR(srcSize_wrong); - } - if (ZSTD_isError(res)) return res; - /* no need to bound check, ZSTD_decompressFrame already has */ - dst = (BYTE*)dst + res; - dstCapacity -= res; - } - moreThan1Frame = 1; - } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */ - - if (srcSize) return ERROR(srcSize_wrong); /* input not entirely consumed */ - - return (BYTE*)dst - (BYTE*)dststart; -} - -size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - const void* dict, size_t dictSize) -{ - return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, dict, dictSize, NULL); -} - - -size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) -{ - return ZSTD_decompress_usingDict(dctx, dst, dstCapacity, src, srcSize, NULL, 0); -} - - -size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t srcSize) -{ -#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE>=1) - size_t regenSize; - ZSTD_DCtx* const dctx = ZSTD_createDCtx(); - if (dctx==NULL) return ERROR(memory_allocation); - regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize); - ZSTD_freeDCtx(dctx); - return regenSize; -#else /* stack mode */ - ZSTD_DCtx dctx; - ZSTD_initDCtx_internal(&dctx); - return ZSTD_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize); -#endif -} - - -/*-************************************** -* Advanced Streaming Decompression API -* Bufferless and synchronous -****************************************/ -size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; } - -ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) { - switch(dctx->stage) - { - default: /* should not happen */ - assert(0); - case ZSTDds_getFrameHeaderSize: - case ZSTDds_decodeFrameHeader: - return ZSTDnit_frameHeader; - case ZSTDds_decodeBlockHeader: - return ZSTDnit_blockHeader; - case ZSTDds_decompressBlock: - return ZSTDnit_block; - case ZSTDds_decompressLastBlock: - return ZSTDnit_lastBlock; - case ZSTDds_checkChecksum: - return ZSTDnit_checksum; - case ZSTDds_decodeSkippableHeader: - case ZSTDds_skipFrame: - return ZSTDnit_skippableFrame; - } -} - -static int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; } - -/** ZSTD_decompressContinue() : - * srcSize : must be the exact nb of bytes expected (see ZSTD_nextSrcSizeToDecompress()) - * @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity) - * or an error code, which can be tested using ZSTD_isError() */ -size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) -{ - DEBUGLOG(5, "ZSTD_decompressContinue (srcSize:%u)", (U32)srcSize); - /* Sanity check */ - if (srcSize != dctx->expected) return ERROR(srcSize_wrong); /* not allowed */ - if (dstCapacity) ZSTD_checkContinuity(dctx, dst); - - switch (dctx->stage) - { - case ZSTDds_getFrameHeaderSize : - assert(src != NULL); - if (dctx->format == ZSTD_f_zstd1) { /* allows header */ - assert(srcSize >= ZSTD_FRAMEIDSIZE); /* to read skippable magic number */ - if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */ - memcpy(dctx->headerBuffer, src, srcSize); - dctx->expected = ZSTD_skippableHeaderSize - srcSize; /* remaining to load to get full skippable frame header */ - dctx->stage = ZSTDds_decodeSkippableHeader; - return 0; - } } - dctx->headerSize = ZSTD_frameHeaderSize_internal(src, srcSize, dctx->format); - if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize; - memcpy(dctx->headerBuffer, src, srcSize); - dctx->expected = dctx->headerSize - srcSize; - dctx->stage = ZSTDds_decodeFrameHeader; - return 0; - - case ZSTDds_decodeFrameHeader: - assert(src != NULL); - memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize); - CHECK_F(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize)); - dctx->expected = ZSTD_blockHeaderSize; - dctx->stage = ZSTDds_decodeBlockHeader; - return 0; - - case ZSTDds_decodeBlockHeader: - { blockProperties_t bp; - size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp); - if (ZSTD_isError(cBlockSize)) return cBlockSize; - dctx->expected = cBlockSize; - dctx->bType = bp.blockType; - dctx->rleSize = bp.origSize; - if (cBlockSize) { - dctx->stage = bp.lastBlock ? ZSTDds_decompressLastBlock : ZSTDds_decompressBlock; - return 0; - } - /* empty block */ - if (bp.lastBlock) { - if (dctx->fParams.checksumFlag) { - dctx->expected = 4; - dctx->stage = ZSTDds_checkChecksum; - } else { - dctx->expected = 0; /* end of frame */ - dctx->stage = ZSTDds_getFrameHeaderSize; - } - } else { - dctx->expected = ZSTD_blockHeaderSize; /* jump to next header */ - dctx->stage = ZSTDds_decodeBlockHeader; - } - return 0; - } - - case ZSTDds_decompressLastBlock: - case ZSTDds_decompressBlock: - DEBUGLOG(5, "ZSTD_decompressContinue: case ZSTDds_decompressBlock"); - { size_t rSize; - switch(dctx->bType) - { - case bt_compressed: - DEBUGLOG(5, "ZSTD_decompressContinue: case bt_compressed"); - rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1); - break; - case bt_raw : - rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize); - break; - case bt_rle : - rSize = ZSTD_setRleBlock(dst, dstCapacity, src, srcSize, dctx->rleSize); - break; - case bt_reserved : /* should never happen */ - default: - return ERROR(corruption_detected); - } - if (ZSTD_isError(rSize)) return rSize; - DEBUGLOG(5, "ZSTD_decompressContinue: decoded size from block : %u", (U32)rSize); - dctx->decodedSize += rSize; - if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize); - - if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */ - DEBUGLOG(4, "ZSTD_decompressContinue: decoded size from frame : %u", (U32)dctx->decodedSize); - if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) { - if (dctx->decodedSize != dctx->fParams.frameContentSize) { - return ERROR(corruption_detected); - } } - if (dctx->fParams.checksumFlag) { /* another round for frame checksum */ - dctx->expected = 4; - dctx->stage = ZSTDds_checkChecksum; - } else { - dctx->expected = 0; /* ends here */ - dctx->stage = ZSTDds_getFrameHeaderSize; - } - } else { - dctx->stage = ZSTDds_decodeBlockHeader; - dctx->expected = ZSTD_blockHeaderSize; - dctx->previousDstEnd = (char*)dst + rSize; - } - return rSize; - } - - case ZSTDds_checkChecksum: - assert(srcSize == 4); /* guaranteed by dctx->expected */ - { U32 const h32 = (U32)XXH64_digest(&dctx->xxhState); - U32 const check32 = MEM_readLE32(src); - DEBUGLOG(4, "ZSTD_decompressContinue: checksum : calculated %08X :: %08X read", h32, check32); - if (check32 != h32) return ERROR(checksum_wrong); - dctx->expected = 0; - dctx->stage = ZSTDds_getFrameHeaderSize; - return 0; - } - - case ZSTDds_decodeSkippableHeader: - assert(src != NULL); - assert(srcSize <= ZSTD_skippableHeaderSize); - memcpy(dctx->headerBuffer + (ZSTD_skippableHeaderSize - srcSize), src, srcSize); /* complete skippable header */ - dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_FRAMEIDSIZE); /* note : dctx->expected can grow seriously large, beyond local buffer size */ - dctx->stage = ZSTDds_skipFrame; - return 0; - - case ZSTDds_skipFrame: - dctx->expected = 0; - dctx->stage = ZSTDds_getFrameHeaderSize; - return 0; - - default: - return ERROR(GENERIC); /* impossible */ - } -} - - -static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) -{ - dctx->dictEnd = dctx->previousDstEnd; - dctx->virtualStart = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart)); - dctx->prefixStart = dict; - dctx->previousDstEnd = (const char*)dict + dictSize; - return 0; -} - -/*! ZSTD_loadEntropy() : - * dict : must point at beginning of a valid zstd dictionary. - * @return : size of entropy tables read */ -static size_t ZSTD_loadEntropy(ZSTD_entropyDTables_t* entropy, - const void* const dict, size_t const dictSize) -{ - const BYTE* dictPtr = (const BYTE*)dict; - const BYTE* const dictEnd = dictPtr + dictSize; - - if (dictSize <= 8) return ERROR(dictionary_corrupted); - assert(MEM_readLE32(dict) == ZSTD_MAGIC_DICTIONARY); /* dict must be valid */ - dictPtr += 8; /* skip header = magic + dictID */ - - ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, OFTable) == offsetof(ZSTD_entropyDTables_t, LLTable) + sizeof(entropy->LLTable)); - ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, MLTable) == offsetof(ZSTD_entropyDTables_t, OFTable) + sizeof(entropy->OFTable)); - ZSTD_STATIC_ASSERT(sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable) >= HUF_DECOMPRESS_WORKSPACE_SIZE); - { void* const workspace = &entropy->LLTable; /* use fse tables as temporary workspace; implies fse tables are grouped together */ - size_t const workspaceSize = sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable); - size_t const hSize = HUF_readDTableX2_wksp(entropy->hufTable, - dictPtr, dictEnd - dictPtr, - workspace, workspaceSize); - if (HUF_isError(hSize)) return ERROR(dictionary_corrupted); - dictPtr += hSize; - } - - { short offcodeNCount[MaxOff+1]; - U32 offcodeMaxValue = MaxOff, offcodeLog; - size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr); - if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted); - if (offcodeMaxValue > MaxOff) return ERROR(dictionary_corrupted); - if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted); - ZSTD_buildFSETable( entropy->OFTable, - offcodeNCount, offcodeMaxValue, - OF_base, OF_bits, - offcodeLog); - dictPtr += offcodeHeaderSize; - } - - { short matchlengthNCount[MaxML+1]; - unsigned matchlengthMaxValue = MaxML, matchlengthLog; - size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr); - if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted); - if (matchlengthMaxValue > MaxML) return ERROR(dictionary_corrupted); - if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted); - ZSTD_buildFSETable( entropy->MLTable, - matchlengthNCount, matchlengthMaxValue, - ML_base, ML_bits, - matchlengthLog); - dictPtr += matchlengthHeaderSize; - } - - { short litlengthNCount[MaxLL+1]; - unsigned litlengthMaxValue = MaxLL, litlengthLog; - size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr); - if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted); - if (litlengthMaxValue > MaxLL) return ERROR(dictionary_corrupted); - if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted); - ZSTD_buildFSETable( entropy->LLTable, - litlengthNCount, litlengthMaxValue, - LL_base, LL_bits, - litlengthLog); - dictPtr += litlengthHeaderSize; - } - - if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted); - { int i; - size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12)); - for (i=0; i<3; i++) { - U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4; - if (rep==0 || rep >= dictContentSize) return ERROR(dictionary_corrupted); - entropy->rep[i] = rep; - } } - - return dictPtr - (const BYTE*)dict; -} - -static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) -{ - if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize); - { U32 const magic = MEM_readLE32(dict); - if (magic != ZSTD_MAGIC_DICTIONARY) { - return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */ - } } - dctx->dictID = MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE); - - /* load entropy tables */ - { size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize); - if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted); - dict = (const char*)dict + eSize; - dictSize -= eSize; - } - dctx->litEntropy = dctx->fseEntropy = 1; - - /* reference dictionary content */ - return ZSTD_refDictContent(dctx, dict, dictSize); -} - -size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx) -{ - assert(dctx != NULL); - dctx->expected = ZSTD_startingInputLength(dctx->format); /* dctx->format must be properly set */ - dctx->stage = ZSTDds_getFrameHeaderSize; - dctx->decodedSize = 0; - dctx->previousDstEnd = NULL; - dctx->prefixStart = NULL; - dctx->virtualStart = NULL; - dctx->dictEnd = NULL; - dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */ - dctx->litEntropy = dctx->fseEntropy = 0; - dctx->dictID = 0; - ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue)); - memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */ - dctx->LLTptr = dctx->entropy.LLTable; - dctx->MLTptr = dctx->entropy.MLTable; - dctx->OFTptr = dctx->entropy.OFTable; - dctx->HUFptr = dctx->entropy.hufTable; - return 0; -} - -size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) -{ - CHECK_F( ZSTD_decompressBegin(dctx) ); - if (dict && dictSize) - CHECK_E(ZSTD_decompress_insertDictionary(dctx, dict, dictSize), dictionary_corrupted); - return 0; -} - - -/* ====== ZSTD_DDict ====== */ - -struct ZSTD_DDict_s { - void* dictBuffer; - const void* dictContent; - size_t dictSize; - ZSTD_entropyDTables_t entropy; - U32 dictID; - U32 entropyPresent; - ZSTD_customMem cMem; -}; /* typedef'd to ZSTD_DDict within "zstd.h" */ - -static const void* ZSTD_DDictDictContent(const ZSTD_DDict* ddict) -{ - assert(ddict != NULL); - return ddict->dictContent; -} - -static size_t ZSTD_DDictDictSize(const ZSTD_DDict* ddict) -{ - assert(ddict != NULL); - return ddict->dictSize; -} - -size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict) -{ - DEBUGLOG(4, "ZSTD_decompressBegin_usingDDict"); - assert(dctx != NULL); - if (ddict) { - dctx->ddictIsCold = (dctx->dictEnd != (const char*)ddict->dictContent + ddict->dictSize); - DEBUGLOG(4, "DDict is %s", - dctx->ddictIsCold ? "~cold~" : "hot!"); - } - CHECK_F( ZSTD_decompressBegin(dctx) ); - if (ddict) { /* NULL ddict is equivalent to no dictionary */ - dctx->dictID = ddict->dictID; - dctx->prefixStart = ddict->dictContent; - dctx->virtualStart = ddict->dictContent; - dctx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize; - dctx->previousDstEnd = dctx->dictEnd; - if (ddict->entropyPresent) { - dctx->litEntropy = 1; - dctx->fseEntropy = 1; - dctx->LLTptr = ddict->entropy.LLTable; - dctx->MLTptr = ddict->entropy.MLTable; - dctx->OFTptr = ddict->entropy.OFTable; - dctx->HUFptr = ddict->entropy.hufTable; - dctx->entropy.rep[0] = ddict->entropy.rep[0]; - dctx->entropy.rep[1] = ddict->entropy.rep[1]; - dctx->entropy.rep[2] = ddict->entropy.rep[2]; - } else { - dctx->litEntropy = 0; - dctx->fseEntropy = 0; - } - } - return 0; -} - -static size_t -ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict, - ZSTD_dictContentType_e dictContentType) -{ - ddict->dictID = 0; - ddict->entropyPresent = 0; - if (dictContentType == ZSTD_dct_rawContent) return 0; - - if (ddict->dictSize < 8) { - if (dictContentType == ZSTD_dct_fullDict) - return ERROR(dictionary_corrupted); /* only accept specified dictionaries */ - return 0; /* pure content mode */ - } - { U32 const magic = MEM_readLE32(ddict->dictContent); - if (magic != ZSTD_MAGIC_DICTIONARY) { - if (dictContentType == ZSTD_dct_fullDict) - return ERROR(dictionary_corrupted); /* only accept specified dictionaries */ - return 0; /* pure content mode */ - } - } - ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + ZSTD_FRAMEIDSIZE); - - /* load entropy tables */ - CHECK_E( ZSTD_loadEntropy(&ddict->entropy, - ddict->dictContent, ddict->dictSize), - dictionary_corrupted ); - ddict->entropyPresent = 1; - return 0; -} - - -static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, - const void* dict, size_t dictSize, - ZSTD_dictLoadMethod_e dictLoadMethod, - ZSTD_dictContentType_e dictContentType) -{ - if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dict) || (!dictSize)) { - ddict->dictBuffer = NULL; - ddict->dictContent = dict; - if (!dict) dictSize = 0; - } else { - void* const internalBuffer = ZSTD_malloc(dictSize, ddict->cMem); - ddict->dictBuffer = internalBuffer; - ddict->dictContent = internalBuffer; - if (!internalBuffer) return ERROR(memory_allocation); - memcpy(internalBuffer, dict, dictSize); - } - ddict->dictSize = dictSize; - ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */ - - /* parse dictionary content */ - CHECK_F( ZSTD_loadEntropy_inDDict(ddict, dictContentType) ); - - return 0; -} - -ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, - ZSTD_dictLoadMethod_e dictLoadMethod, - ZSTD_dictContentType_e dictContentType, - ZSTD_customMem customMem) -{ - if (!customMem.customAlloc ^ !customMem.customFree) return NULL; - - { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem); - if (ddict == NULL) return NULL; - ddict->cMem = customMem; - { size_t const initResult = ZSTD_initDDict_internal(ddict, - dict, dictSize, - dictLoadMethod, dictContentType); - if (ZSTD_isError(initResult)) { - ZSTD_freeDDict(ddict); - return NULL; - } } - return ddict; - } -} - -/*! ZSTD_createDDict() : -* Create a digested dictionary, to start decompression without startup delay. -* `dict` content is copied inside DDict. -* Consequently, `dict` can be released after `ZSTD_DDict` creation */ -ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize) -{ - ZSTD_customMem const allocator = { NULL, NULL, NULL }; - return ZSTD_createDDict_advanced(dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto, allocator); -} - -/*! ZSTD_createDDict_byReference() : - * Create a digested dictionary, to start decompression without startup delay. - * Dictionary content is simply referenced, it will be accessed during decompression. - * Warning : dictBuffer must outlive DDict (DDict must be freed before dictBuffer) */ -ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize) -{ - ZSTD_customMem const allocator = { NULL, NULL, NULL }; - return ZSTD_createDDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto, allocator); -} - - -const ZSTD_DDict* ZSTD_initStaticDDict( - void* sBuffer, size_t sBufferSize, - const void* dict, size_t dictSize, - ZSTD_dictLoadMethod_e dictLoadMethod, - ZSTD_dictContentType_e dictContentType) -{ - size_t const neededSpace = sizeof(ZSTD_DDict) - + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize); - ZSTD_DDict* const ddict = (ZSTD_DDict*)sBuffer; - assert(sBuffer != NULL); - assert(dict != NULL); - if ((size_t)sBuffer & 7) return NULL; /* 8-aligned */ - if (sBufferSize < neededSpace) return NULL; - if (dictLoadMethod == ZSTD_dlm_byCopy) { - memcpy(ddict+1, dict, dictSize); /* local copy */ - dict = ddict+1; - } - if (ZSTD_isError( ZSTD_initDDict_internal(ddict, - dict, dictSize, - ZSTD_dlm_byRef, dictContentType) )) - return NULL; - return ddict; -} - - -size_t ZSTD_freeDDict(ZSTD_DDict* ddict) -{ - if (ddict==NULL) return 0; /* support free on NULL */ - { ZSTD_customMem const cMem = ddict->cMem; - ZSTD_free(ddict->dictBuffer, cMem); - ZSTD_free(ddict, cMem); - return 0; - } -} - -/*! ZSTD_estimateDDictSize() : - * Estimate amount of memory that will be needed to create a dictionary for decompression. - * Note : dictionary created by reference using ZSTD_dlm_byRef are smaller */ -size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod) -{ - return sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize); -} - -size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict) -{ - if (ddict==NULL) return 0; /* support sizeof on NULL */ - return sizeof(*ddict) + (ddict->dictBuffer ? ddict->dictSize : 0) ; -} - -/*! ZSTD_getDictID_fromDict() : - * Provides the dictID stored within dictionary. - * if @return == 0, the dictionary is not conformant with Zstandard specification. - * It can still be loaded, but as a content-only dictionary. */ -unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize) -{ - if (dictSize < 8) return 0; - if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) return 0; - return MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE); -} - -/*! ZSTD_getDictID_fromDDict() : - * Provides the dictID of the dictionary loaded into `ddict`. - * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. - * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ -unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict) -{ - if (ddict==NULL) return 0; - return ZSTD_getDictID_fromDict(ddict->dictContent, ddict->dictSize); -} - -/*! ZSTD_getDictID_fromFrame() : - * Provides the dictID required to decompresse frame stored within `src`. - * If @return == 0, the dictID could not be decoded. - * This could for one of the following reasons : - * - The frame does not require a dictionary (most common case). - * - The frame was built with dictID intentionally removed. - * Needed dictionary is a hidden information. - * Note : this use case also happens when using a non-conformant dictionary. - * - `srcSize` is too small, and as a result, frame header could not be decoded. - * Note : possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`. - * - This is not a Zstandard frame. - * When identifying the exact failure cause, it's possible to use - * ZSTD_getFrameHeader(), which will provide a more precise error code. */ -unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize) -{ - ZSTD_frameHeader zfp = { 0, 0, 0, ZSTD_frame, 0, 0, 0 }; - size_t const hError = ZSTD_getFrameHeader(&zfp, src, srcSize); - if (ZSTD_isError(hError)) return 0; - return zfp.dictID; -} - - -/*! ZSTD_decompress_usingDDict() : -* Decompression using a pre-digested Dictionary -* Use dictionary without significant overhead. */ -size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - const ZSTD_DDict* ddict) -{ - /* pass content and size in case legacy frames are encountered */ - return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, - NULL, 0, - ddict); -} - - -/*===================================== -* Streaming decompression -*====================================*/ - -ZSTD_DStream* ZSTD_createDStream(void) -{ - DEBUGLOG(3, "ZSTD_createDStream"); - return ZSTD_createDStream_advanced(ZSTD_defaultCMem); -} - -ZSTD_DStream* ZSTD_initStaticDStream(void *workspace, size_t workspaceSize) -{ - return ZSTD_initStaticDCtx(workspace, workspaceSize); -} - -ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem) -{ - return ZSTD_createDCtx_advanced(customMem); -} - -size_t ZSTD_freeDStream(ZSTD_DStream* zds) -{ - return ZSTD_freeDCtx(zds); -} - - -/* *** Initialization *** */ - -size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize; } -size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_MAX; } - -size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, - const void* dict, size_t dictSize, - ZSTD_dictLoadMethod_e dictLoadMethod, - ZSTD_dictContentType_e dictContentType) -{ - if (dctx->streamStage != zdss_init) return ERROR(stage_wrong); - ZSTD_freeDDict(dctx->ddictLocal); - if (dict && dictSize >= 8) { - dctx->ddictLocal = ZSTD_createDDict_advanced(dict, dictSize, dictLoadMethod, dictContentType, dctx->customMem); - if (dctx->ddictLocal == NULL) return ERROR(memory_allocation); - } else { - dctx->ddictLocal = NULL; - } - dctx->ddict = dctx->ddictLocal; - return 0; -} - -size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) -{ - return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto); -} - -size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) -{ - return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto); -} - -size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType) -{ - return ZSTD_DCtx_loadDictionary_advanced(dctx, prefix, prefixSize, ZSTD_dlm_byRef, dictContentType); -} - -size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize) -{ - return ZSTD_DCtx_refPrefix_advanced(dctx, prefix, prefixSize, ZSTD_dct_rawContent); -} - - -/* ZSTD_initDStream_usingDict() : - * return : expected size, aka ZSTD_frameHeaderSize_prefix. - * this function cannot fail */ -size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize) -{ - DEBUGLOG(4, "ZSTD_initDStream_usingDict"); - zds->streamStage = zdss_init; - zds->noForwardProgress = 0; - CHECK_F( ZSTD_DCtx_loadDictionary(zds, dict, dictSize) ); - return ZSTD_frameHeaderSize_prefix; -} - -/* note : this variant can't fail */ -size_t ZSTD_initDStream(ZSTD_DStream* zds) -{ - DEBUGLOG(4, "ZSTD_initDStream"); - return ZSTD_initDStream_usingDict(zds, NULL, 0); -} - -/* ZSTD_initDStream_usingDDict() : - * ddict will just be referenced, and must outlive decompression session - * this function cannot fail */ -size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict) -{ - size_t const initResult = ZSTD_initDStream(dctx); - dctx->ddict = ddict; - return initResult; -} - -/* ZSTD_resetDStream() : - * return : expected size, aka ZSTD_frameHeaderSize_prefix. - * this function cannot fail */ -size_t ZSTD_resetDStream(ZSTD_DStream* dctx) -{ - DEBUGLOG(4, "ZSTD_resetDStream"); - dctx->streamStage = zdss_loadHeader; - dctx->lhSize = dctx->inPos = dctx->outStart = dctx->outEnd = 0; - dctx->legacyVersion = 0; - dctx->hostageByte = 0; - return ZSTD_frameHeaderSize_prefix; -} - -size_t ZSTD_setDStreamParameter(ZSTD_DStream* dctx, - ZSTD_DStreamParameter_e paramType, unsigned paramValue) -{ - if (dctx->streamStage != zdss_init) return ERROR(stage_wrong); - switch(paramType) - { - default : return ERROR(parameter_unsupported); - case DStream_p_maxWindowSize : - DEBUGLOG(4, "setting maxWindowSize = %u KB", paramValue >> 10); - dctx->maxWindowSize = paramValue ? paramValue : (U32)(-1); - break; - } - return 0; -} - -size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict) -{ - if (dctx->streamStage != zdss_init) return ERROR(stage_wrong); - dctx->ddict = ddict; - return 0; -} - -size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize) -{ - if (dctx->streamStage != zdss_init) return ERROR(stage_wrong); - dctx->maxWindowSize = maxWindowSize; - return 0; -} - -size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format) -{ - DEBUGLOG(4, "ZSTD_DCtx_setFormat : %u", (unsigned)format); - if (dctx->streamStage != zdss_init) return ERROR(stage_wrong); - dctx->format = format; - return 0; -} - - -size_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx) -{ - return ZSTD_sizeof_DCtx(dctx); -} - -size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize) -{ - size_t const blockSize = (size_t) MIN(windowSize, ZSTD_BLOCKSIZE_MAX); - unsigned long long const neededRBSize = windowSize + blockSize + (WILDCOPY_OVERLENGTH * 2); - unsigned long long const neededSize = MIN(frameContentSize, neededRBSize); - size_t const minRBSize = (size_t) neededSize; - if ((unsigned long long)minRBSize != neededSize) return ERROR(frameParameter_windowTooLarge); - return minRBSize; -} - -size_t ZSTD_estimateDStreamSize(size_t windowSize) -{ - size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX); - size_t const inBuffSize = blockSize; /* no block can be larger */ - size_t const outBuffSize = ZSTD_decodingBufferSize_min(windowSize, ZSTD_CONTENTSIZE_UNKNOWN); - return ZSTD_estimateDCtxSize() + inBuffSize + outBuffSize; -} - -size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize) -{ - U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX; /* note : should be user-selectable */ - ZSTD_frameHeader zfh; - size_t const err = ZSTD_getFrameHeader(&zfh, src, srcSize); - if (ZSTD_isError(err)) return err; - if (err>0) return ERROR(srcSize_wrong); - if (zfh.windowSize > windowSizeMax) - return ERROR(frameParameter_windowTooLarge); - return ZSTD_estimateDStreamSize((size_t)zfh.windowSize); -} - - -/* ***** Decompression ***** */ - -MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize) -{ - size_t const length = MIN(dstCapacity, srcSize); - memcpy(dst, src, length); - return length; -} - - -size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input) -{ - const char* const istart = (const char*)(input->src) + input->pos; - const char* const iend = (const char*)(input->src) + input->size; - const char* ip = istart; - char* const ostart = (char*)(output->dst) + output->pos; - char* const oend = (char*)(output->dst) + output->size; - char* op = ostart; - U32 someMoreWork = 1; - - DEBUGLOG(5, "ZSTD_decompressStream"); - if (input->pos > input->size) { /* forbidden */ - DEBUGLOG(5, "in: pos: %u vs size: %u", - (U32)input->pos, (U32)input->size); - return ERROR(srcSize_wrong); - } - if (output->pos > output->size) { /* forbidden */ - DEBUGLOG(5, "out: pos: %u vs size: %u", - (U32)output->pos, (U32)output->size); - return ERROR(dstSize_tooSmall); - } - DEBUGLOG(5, "input size : %u", (U32)(input->size - input->pos)); - - while (someMoreWork) { - switch(zds->streamStage) - { - case zdss_init : - DEBUGLOG(5, "stage zdss_init => transparent reset "); - ZSTD_resetDStream(zds); /* transparent reset on starting decoding a new frame */ - /* fall-through */ - - case zdss_loadHeader : - DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip)); -#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) - if (zds->legacyVersion) { - /* legacy support is incompatible with static dctx */ - if (zds->staticSize) return ERROR(memory_allocation); - { size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input); - if (hint==0) zds->streamStage = zdss_init; - return hint; - } } -#endif - { size_t const hSize = ZSTD_getFrameHeader_advanced(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format); - DEBUGLOG(5, "header size : %u", (U32)hSize); - if (ZSTD_isError(hSize)) { -#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) - U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart); - if (legacyVersion) { - const void* const dict = zds->ddict ? zds->ddict->dictContent : NULL; - size_t const dictSize = zds->ddict ? zds->ddict->dictSize : 0; - DEBUGLOG(5, "ZSTD_decompressStream: detected legacy version v0.%u", legacyVersion); - /* legacy support is incompatible with static dctx */ - if (zds->staticSize) return ERROR(memory_allocation); - CHECK_F(ZSTD_initLegacyStream(&zds->legacyContext, - zds->previousLegacyVersion, legacyVersion, - dict, dictSize)); - zds->legacyVersion = zds->previousLegacyVersion = legacyVersion; - { size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, legacyVersion, output, input); - if (hint==0) zds->streamStage = zdss_init; /* or stay in stage zdss_loadHeader */ - return hint; - } } -#endif - return hSize; /* error */ - } - if (hSize != 0) { /* need more input */ - size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */ - size_t const remainingInput = (size_t)(iend-ip); - assert(iend >= ip); - if (toLoad > remainingInput) { /* not enough input to load full header */ - if (remainingInput > 0) { - memcpy(zds->headerBuffer + zds->lhSize, ip, remainingInput); - zds->lhSize += remainingInput; - } - input->pos = input->size; - return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */ - } - assert(ip != NULL); - memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad; - break; - } } - - /* check for single-pass mode opportunity */ - if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */ - && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) { - size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart); - if (cSize <= (size_t)(iend-istart)) { - /* shortcut : using single-pass mode */ - size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, oend-op, istart, cSize, zds->ddict); - if (ZSTD_isError(decompressedSize)) return decompressedSize; - DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()") - ip = istart + cSize; - op += decompressedSize; - zds->expected = 0; - zds->streamStage = zdss_init; - someMoreWork = 0; - break; - } } - - /* Consume header (see ZSTDds_decodeFrameHeader) */ - DEBUGLOG(4, "Consume header"); - CHECK_F(ZSTD_decompressBegin_usingDDict(zds, zds->ddict)); - - if ((MEM_readLE32(zds->headerBuffer) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */ - zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_FRAMEIDSIZE); - zds->stage = ZSTDds_skipFrame; - } else { - CHECK_F(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize)); - zds->expected = ZSTD_blockHeaderSize; - zds->stage = ZSTDds_decodeBlockHeader; - } - - /* control buffer memory usage */ - DEBUGLOG(4, "Control max memory usage (%u KB <= max %u KB)", - (U32)(zds->fParams.windowSize >>10), - (U32)(zds->maxWindowSize >> 10) ); - zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN); - if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge); - - /* Adapt buffer sizes to frame header instructions */ - { size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */); - size_t const neededOutBuffSize = ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize); - if ((zds->inBuffSize < neededInBuffSize) || (zds->outBuffSize < neededOutBuffSize)) { - size_t const bufferSize = neededInBuffSize + neededOutBuffSize; - DEBUGLOG(4, "inBuff : from %u to %u", - (U32)zds->inBuffSize, (U32)neededInBuffSize); - DEBUGLOG(4, "outBuff : from %u to %u", - (U32)zds->outBuffSize, (U32)neededOutBuffSize); - if (zds->staticSize) { /* static DCtx */ - DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize); - assert(zds->staticSize >= sizeof(ZSTD_DCtx)); /* controlled at init */ - if (bufferSize > zds->staticSize - sizeof(ZSTD_DCtx)) - return ERROR(memory_allocation); - } else { - ZSTD_free(zds->inBuff, zds->customMem); - zds->inBuffSize = 0; - zds->outBuffSize = 0; - zds->inBuff = (char*)ZSTD_malloc(bufferSize, zds->customMem); - if (zds->inBuff == NULL) return ERROR(memory_allocation); - } - zds->inBuffSize = neededInBuffSize; - zds->outBuff = zds->inBuff + zds->inBuffSize; - zds->outBuffSize = neededOutBuffSize; - } } - zds->streamStage = zdss_read; - /* fall-through */ - - case zdss_read: - DEBUGLOG(5, "stage zdss_read"); - { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds); - DEBUGLOG(5, "neededInSize = %u", (U32)neededInSize); - if (neededInSize==0) { /* end of frame */ - zds->streamStage = zdss_init; - someMoreWork = 0; - break; - } - if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */ - int const isSkipFrame = ZSTD_isSkipFrame(zds); - size_t const decodedSize = ZSTD_decompressContinue(zds, - zds->outBuff + zds->outStart, (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart), - ip, neededInSize); - if (ZSTD_isError(decodedSize)) return decodedSize; - ip += neededInSize; - if (!decodedSize && !isSkipFrame) break; /* this was just a header */ - zds->outEnd = zds->outStart + decodedSize; - zds->streamStage = zdss_flush; - break; - } } - if (ip==iend) { someMoreWork = 0; break; } /* no more input */ - zds->streamStage = zdss_load; - /* fall-through */ - - case zdss_load: - { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds); - size_t const toLoad = neededInSize - zds->inPos; - int const isSkipFrame = ZSTD_isSkipFrame(zds); - size_t loadedSize; - if (isSkipFrame) { - loadedSize = MIN(toLoad, (size_t)(iend-ip)); - } else { - if (toLoad > zds->inBuffSize - zds->inPos) return ERROR(corruption_detected); /* should never happen */ - loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend-ip); - } - ip += loadedSize; - zds->inPos += loadedSize; - if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */ - - /* decode loaded input */ - { size_t const decodedSize = ZSTD_decompressContinue(zds, - zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart, - zds->inBuff, neededInSize); - if (ZSTD_isError(decodedSize)) return decodedSize; - zds->inPos = 0; /* input is consumed */ - if (!decodedSize && !isSkipFrame) { zds->streamStage = zdss_read; break; } /* this was just a header */ - zds->outEnd = zds->outStart + decodedSize; - } } - zds->streamStage = zdss_flush; - /* fall-through */ - - case zdss_flush: - { size_t const toFlushSize = zds->outEnd - zds->outStart; - size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize); - op += flushedSize; - zds->outStart += flushedSize; - if (flushedSize == toFlushSize) { /* flush completed */ - zds->streamStage = zdss_read; - if ( (zds->outBuffSize < zds->fParams.frameContentSize) - && (zds->outStart + zds->fParams.blockSizeMax > zds->outBuffSize) ) { - DEBUGLOG(5, "restart filling outBuff from beginning (left:%i, needed:%u)", - (int)(zds->outBuffSize - zds->outStart), - (U32)zds->fParams.blockSizeMax); - zds->outStart = zds->outEnd = 0; - } - break; - } } - /* cannot complete flush */ - someMoreWork = 0; - break; - - default: return ERROR(GENERIC); /* impossible */ - } } - - /* result */ - input->pos = (size_t)(ip - (const char*)(input->src)); - output->pos = (size_t)(op - (char*)(output->dst)); - if ((ip==istart) && (op==ostart)) { /* no forward progress */ - zds->noForwardProgress ++; - if (zds->noForwardProgress >= ZSTD_NO_FORWARD_PROGRESS_MAX) { - if (op==oend) return ERROR(dstSize_tooSmall); - if (ip==iend) return ERROR(srcSize_wrong); - assert(0); - } - } else { - zds->noForwardProgress = 0; - } - { size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds); - if (!nextSrcSizeHint) { /* frame fully decoded */ - if (zds->outEnd == zds->outStart) { /* output fully flushed */ - if (zds->hostageByte) { - if (input->pos >= input->size) { - /* can't release hostage (not present) */ - zds->streamStage = zdss_read; - return 1; - } - input->pos++; /* release hostage */ - } /* zds->hostageByte */ - return 0; - } /* zds->outEnd == zds->outStart */ - if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */ - input->pos--; /* note : pos > 0, otherwise, impossible to finish reading last block */ - zds->hostageByte=1; - } - return 1; - } /* nextSrcSizeHint==0 */ - nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds) == ZSTDnit_block); /* preload header of next block */ - assert(zds->inPos <= nextSrcSizeHint); - nextSrcSizeHint -= zds->inPos; /* part already loaded*/ - return nextSrcSizeHint; - } -} - - -size_t ZSTD_decompress_generic(ZSTD_DCtx* dctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input) -{ - return ZSTD_decompressStream(dctx, output, input); -} - -size_t ZSTD_decompress_generic_simpleArgs ( - ZSTD_DCtx* dctx, - void* dst, size_t dstCapacity, size_t* dstPos, - const void* src, size_t srcSize, size_t* srcPos) -{ - ZSTD_outBuffer output = { dst, dstCapacity, *dstPos }; - ZSTD_inBuffer input = { src, srcSize, *srcPos }; - /* ZSTD_compress_generic() will check validity of dstPos and srcPos */ - size_t const cErr = ZSTD_decompress_generic(dctx, &output, &input); - *dstPos = output.pos; - *srcPos = input.pos; - return cErr; -} - -void ZSTD_DCtx_reset(ZSTD_DCtx* dctx) -{ - (void)ZSTD_initDStream(dctx); - dctx->format = ZSTD_f_zstd1; - dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT; -} diff --git a/grub-core/lib/zstd/zstd_errors.h b/grub-core/lib/zstd/zstd_errors.h deleted file mode 100644 index 57533f286..000000000 --- a/grub-core/lib/zstd/zstd_errors.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ - -#ifndef ZSTD_ERRORS_H_398273423 -#define ZSTD_ERRORS_H_398273423 - -#if defined (__cplusplus) -extern "C" { -#endif - -/*===== dependency =====*/ -#include /* size_t */ - - -/* ===== ZSTDERRORLIB_API : control library symbols visibility ===== */ -#ifndef ZSTDERRORLIB_VISIBILITY -# if defined(__GNUC__) && (__GNUC__ >= 4) -# define ZSTDERRORLIB_VISIBILITY __attribute__ ((visibility ("default"))) -# else -# define ZSTDERRORLIB_VISIBILITY -# endif -#endif -#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) -# define ZSTDERRORLIB_API __declspec(dllexport) ZSTDERRORLIB_VISIBILITY -#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) -# define ZSTDERRORLIB_API __declspec(dllimport) ZSTDERRORLIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ -#else -# define ZSTDERRORLIB_API ZSTDERRORLIB_VISIBILITY -#endif - -/*-********************************************* - * Error codes list - *-********************************************* - * Error codes _values_ are pinned down since v1.3.1 only. - * Therefore, don't rely on values if you may link to any version < v1.3.1. - * - * Only values < 100 are considered stable. - * - * note 1 : this API shall be used with static linking only. - * dynamic linking is not yet officially supported. - * note 2 : Prefer relying on the enum than on its value whenever possible - * This is the only supported way to use the error list < v1.3.1 - * note 3 : ZSTD_isError() is always correct, whatever the library version. - **********************************************/ -typedef enum { - ZSTD_error_no_error = 0, - ZSTD_error_GENERIC = 1, - ZSTD_error_prefix_unknown = 10, - ZSTD_error_version_unsupported = 12, - ZSTD_error_frameParameter_unsupported = 14, - ZSTD_error_frameParameter_windowTooLarge = 16, - ZSTD_error_corruption_detected = 20, - ZSTD_error_checksum_wrong = 22, - ZSTD_error_dictionary_corrupted = 30, - ZSTD_error_dictionary_wrong = 32, - ZSTD_error_dictionaryCreation_failed = 34, - ZSTD_error_parameter_unsupported = 40, - ZSTD_error_parameter_outOfBound = 42, - ZSTD_error_tableLog_tooLarge = 44, - ZSTD_error_maxSymbolValue_tooLarge = 46, - ZSTD_error_maxSymbolValue_tooSmall = 48, - ZSTD_error_stage_wrong = 60, - ZSTD_error_init_missing = 62, - ZSTD_error_memory_allocation = 64, - ZSTD_error_workSpace_tooSmall= 66, - ZSTD_error_dstSize_tooSmall = 70, - ZSTD_error_srcSize_wrong = 72, - /* following error codes are __NOT STABLE__, they can be removed or changed in future versions */ - ZSTD_error_frameIndex_tooLarge = 100, - ZSTD_error_seekableIO = 102, - ZSTD_error_maxCode = 120 /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */ -} ZSTD_ErrorCode; - -/*! ZSTD_getErrorCode() : - convert a `size_t` function result into a `ZSTD_ErrorCode` enum type, - which can be used to compare with enum list published above */ -ZSTDERRORLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult); -ZSTDERRORLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code); /**< Same as ZSTD_getErrorName, but using a `ZSTD_ErrorCode` enum argument */ - - -#if defined (__cplusplus) -} -#endif - -#endif /* ZSTD_ERRORS_H_398273423 */ diff --git a/grub-core/lib/zstd/zstd_internal.h b/grub-core/lib/zstd/zstd_internal.h deleted file mode 100644 index e75adfa61..000000000 --- a/grub-core/lib/zstd/zstd_internal.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under both the BSD-style license (found in the - * LICENSE file in the root directory of this source tree) and the GPLv2 (found - * in the COPYING file in the root directory of this source tree). - * You may select, at your option, one of the above-listed licenses. - */ - -#ifndef ZSTD_CCOMMON_H_MODULE -#define ZSTD_CCOMMON_H_MODULE - -/* this module contains definitions which must be identical - * across compression, decompression and dictBuilder. - * It also contains a few functions useful to at least 2 of them - * and which benefit from being inlined */ - -/*-************************************* -* Dependencies -***************************************/ -#include "compiler.h" -#include "mem.h" -#include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */ -#include "error_private.h" -#define ZSTD_STATIC_LINKING_ONLY -#include "zstd.h" -#define FSE_STATIC_LINKING_ONLY -#include "fse.h" -#define HUF_STATIC_LINKING_ONLY -#include "huf.h" -#ifndef XXH_STATIC_LINKING_ONLY -# define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */ -#endif -#include "xxhash.h" /* XXH_reset, update, digest */ - - -#if defined (__cplusplus) -extern "C" { -#endif - -/* ---- static assert (debug) --- */ -#define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) - - -/*-************************************* -* shared macros -***************************************/ -#undef MIN -#undef MAX -#define MIN(a,b) ((a)<(b) ? (a) : (b)) -#define MAX(a,b) ((a)>(b) ? (a) : (b)) -#define CHECK_F(f) { size_t const errcod = f; if (ERR_isError(errcod)) return errcod; } /* check and Forward error code */ -#define CHECK_E(f, e) { size_t const errcod = f; if (ERR_isError(errcod)) return ERROR(e); } /* check and send Error code */ - - -/*-************************************* -* Common constants -***************************************/ -#define ZSTD_OPT_NUM (1<<12) - -#define ZSTD_REP_NUM 3 /* number of repcodes */ -#define ZSTD_REP_MOVE (ZSTD_REP_NUM-1) -static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 }; - -#define KB *(1 <<10) -#define MB *(1 <<20) -#define GB *(1U<<30) - -#define BIT7 128 -#define BIT6 64 -#define BIT5 32 -#define BIT4 16 -#define BIT1 2 -#define BIT0 1 - -#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10 -#define ZSTD_WINDOWLOG_DEFAULTMAX 27 /* Default maximum allowed window log */ -static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 }; -static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 }; - -#define ZSTD_FRAMEIDSIZE 4 /* magic number size */ - -#define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */ -static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE; -typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e; - -#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */ -#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */ - -#define HufLog 12 -typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e; - -#define LONGNBSEQ 0x7F00 - -#define MINMATCH 3 - -#define Litbits 8 -#define MaxLit ((1<= 3) /* GCC Intrinsic */ - return 31 - __builtin_clz(val); -# else /* Software version */ - static const U32 DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 }; - U32 v = val; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - return DeBruijnClz[(v * 0x07C4ACDDU) >> 27]; -# endif - } -} - - -/* ZSTD_invalidateRepCodes() : - * ensures next compression will not use repcodes from previous block. - * Note : only works with regular variant; - * do not use with extDict variant ! */ -void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); /* zstdmt, adaptive_compression (shouldn't get this definition from here) */ - - -typedef struct { - blockType_e blockType; - U32 lastBlock; - U32 origSize; -} blockProperties_t; - -/*! ZSTD_getcBlockSize() : - * Provides the size of compressed block from block header `src` */ -/* Used by: decompress, fullbench (does not get its definition from here) */ -size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, - blockProperties_t* bpPtr); - -#if defined (__cplusplus) -} -#endif - -#endif /* ZSTD_CCOMMON_H_MODULE */ diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c deleted file mode 100644 index 19ddedbc2..000000000 --- a/grub-core/loader/arm/linux.c +++ /dev/null @@ -1,510 +0,0 @@ -/* linux.c - boot Linux */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_dl_t my_mod; - -static grub_addr_t initrd_start; -static grub_addr_t initrd_end; - -static grub_addr_t linux_addr; -static grub_size_t linux_size; - -static char *linux_args; - -static grub_uint32_t machine_type; -static const void *current_fdt; - -typedef void (*kernel_entry_t) (int, unsigned long, void *); - -#define LINUX_PHYS_OFFSET (0x00008000) -#define LINUX_INITRD_PHYS_OFFSET (LINUX_PHYS_OFFSET + 0x03000000) -#define LINUX_FDT_PHYS_OFFSET (LINUX_INITRD_PHYS_OFFSET - 0x10000) - -static grub_size_t -get_atag_size (const grub_uint32_t *atag) -{ - const grub_uint32_t *atag0 = atag; - while (atag[0] && atag[1]) - atag += atag[0]; - return atag - atag0; -} - -/* - * linux_prepare_fdt(): - * Prepares a loaded FDT for being passed to Linux. - * Merges in command line parameters and sets up initrd addresses. - */ -static grub_err_t -linux_prepare_atag (void *target_atag) -{ - const grub_uint32_t *atag_orig = (const grub_uint32_t *) current_fdt; - grub_uint32_t *tmp_atag, *to; - const grub_uint32_t *from; - grub_size_t tmp_size; - grub_size_t arg_size = grub_strlen (linux_args); - char *cmdline_orig = NULL; - grub_size_t cmdline_orig_len = 0; - - /* some place for cmdline, initrd and terminator. */ - tmp_size = get_atag_size (atag_orig) + 20 + (arg_size) / 4; - tmp_atag = grub_calloc (tmp_size, sizeof (grub_uint32_t)); - if (!tmp_atag) - return grub_errno; - - for (from = atag_orig, to = tmp_atag; from[0] && from[1]; - from += from[0]) - switch (from[1]) - { - case 0x54410004: - case 0x54410005: - case 0x54420005: - break; - case 0x54410009: - if (*(char *) (from + 2)) - { - cmdline_orig = (char *) (from + 2); - cmdline_orig_len = grub_strlen (cmdline_orig) + 1; - } - break; - default: - grub_memcpy (to, from, sizeof (grub_uint32_t) * from[0]); - to += from[0]; - break; - } - - grub_dprintf ("linux", "linux inherited args: '%s'\n", - cmdline_orig ? : ""); - grub_dprintf ("linux", "linux_args: '%s'\n", linux_args); - - /* Generate and set command line */ - to[0] = 3 + (arg_size + cmdline_orig_len) / 4; - to[1] = 0x54410009; - if (cmdline_orig) - { - grub_memcpy ((char *) to + 8, cmdline_orig, cmdline_orig_len - 1); - *((char *) to + 8 + cmdline_orig_len - 1) = ' '; - } - grub_memcpy ((char *) to + 8 + cmdline_orig_len, linux_args, arg_size); - grub_memset ((char *) to + 8 + cmdline_orig_len + arg_size, 0, - 4 - ((arg_size + cmdline_orig_len) & 3)); - to += to[0]; - - if (initrd_start && initrd_end) - { - /* - * We're using physical addresses, so even if we have LPAE, we're - * restricted to a 32-bit address space. - */ - grub_dprintf ("loader", "Initrd @ 0x%08x-0x%08x\n", - initrd_start, initrd_end); - - to[0] = 4; - to[1] = 0x54420005; - to[2] = initrd_start; - to[3] = initrd_end - initrd_start; - to += 4; - } - - to[0] = 0; - to[1] = 0; - to += 2; - - /* Copy updated FDT to its launch location */ - grub_memcpy (target_atag, tmp_atag, sizeof (grub_uint32_t) * (to - tmp_atag)); - grub_free (tmp_atag); - - grub_dprintf ("loader", "ATAG updated for Linux boot\n"); - - return GRUB_ERR_NONE; -} - -/* - * linux_prepare_fdt(): - * Prepares a loaded FDT for being passed to Linux. - * Merges in command line parameters and sets up initrd addresses. - */ -static grub_err_t -linux_prepare_fdt (void *target_fdt) -{ - int node; - int retval; - int tmp_size; - void *tmp_fdt; - - tmp_size = grub_fdt_get_totalsize (current_fdt) + 0x100 + grub_strlen (linux_args); - tmp_fdt = grub_malloc (tmp_size); - if (!tmp_fdt) - return grub_errno; - - grub_memcpy (tmp_fdt, current_fdt, grub_fdt_get_totalsize (current_fdt)); - grub_fdt_set_totalsize (tmp_fdt, tmp_size); - - /* Find or create '/chosen' node */ - node = grub_fdt_find_subnode (tmp_fdt, 0, "chosen"); - if (node < 0) - { - grub_dprintf ("linux", "No 'chosen' node in FDT - creating.\n"); - node = grub_fdt_add_subnode (tmp_fdt, 0, "chosen"); - if (node < 0) - goto failure; - } - - grub_dprintf ("linux", "linux_args: '%s'\n", linux_args); - - /* Generate and set command line */ - retval = grub_fdt_set_prop (tmp_fdt, node, "bootargs", linux_args, - grub_strlen (linux_args) + 1); - if (retval) - goto failure; - - if (initrd_start && initrd_end) - { - /* - * We're using physical addresses, so even if we have LPAE, we're - * restricted to a 32-bit address space. - */ - grub_dprintf ("loader", "Initrd @ 0x%08x-0x%08x\n", - initrd_start, initrd_end); - - retval = grub_fdt_set_prop32 (tmp_fdt, node, "linux,initrd-start", - initrd_start); - if (retval) - goto failure; - retval = grub_fdt_set_prop32 (tmp_fdt, node, "linux,initrd-end", - initrd_end); - if (retval) - goto failure; - } - - /* Copy updated FDT to its launch location */ - grub_memcpy (target_fdt, tmp_fdt, tmp_size); - grub_free (tmp_fdt); - - grub_dprintf ("loader", "FDT updated for Linux boot\n"); - - return GRUB_ERR_NONE; - -failure: - grub_free (tmp_fdt); - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unable to prepare FDT"); -} - -static grub_err_t -linux_boot (void) -{ - kernel_entry_t linuxmain; - int fdt_valid, atag_valid; - void *target_fdt = 0; - - fdt_valid = (current_fdt && grub_fdt_check_header_nosize (current_fdt) == 0); - atag_valid = ((((const grub_uint16_t *) current_fdt)[3] & ~3) == 0x5440 - && *((const grub_uint32_t *) current_fdt)); - grub_dprintf ("loader", "atag: %p, %x, %x, %s, %s\n", - current_fdt, - ((const grub_uint16_t *) current_fdt)[3], - *((const grub_uint32_t *) current_fdt), - (const char *) current_fdt, - (const char *) current_fdt + 1); - - if (!fdt_valid && machine_type == GRUB_ARM_MACHINE_TYPE_FDT) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, - N_("device tree must be supplied (see `devicetree' command)")); - - grub_arch_sync_caches ((void *) linux_addr, linux_size); - - grub_dprintf ("loader", "Kernel at: 0x%x\n", linux_addr); - - if (fdt_valid || atag_valid) - { -#ifdef GRUB_MACHINE_EFI - grub_size_t size; - if (fdt_valid) - size = grub_fdt_get_totalsize (current_fdt); - else - size = 4 * get_atag_size (current_fdt); - size += grub_strlen (linux_args) + 256; - target_fdt = grub_efi_allocate_loader_memory (LINUX_FDT_PHYS_OFFSET, size); - if (!target_fdt) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -#else - target_fdt = (void *) LINUX_FDT_ADDRESS; -#endif - } - - if (fdt_valid) - { - grub_err_t err; - - err = linux_prepare_fdt (target_fdt); - if (err) - return err; - grub_dprintf ("loader", "FDT @ %p\n", target_fdt); - } - else if (atag_valid) - { - grub_err_t err; - - err = linux_prepare_atag (target_fdt); - if (err) - return err; - grub_dprintf ("loader", "ATAG @ %p\n", target_fdt); - } - - grub_dprintf ("loader", "Jumping to Linux...\n"); - - /* Boot the kernel. - * Arguments to kernel: - * r0 - 0 - * r1 - machine type - * r2 - address of DTB - */ - linuxmain = (kernel_entry_t) linux_addr; - - grub_arm_disable_caches_mmu (); - - linuxmain (0, machine_type, target_fdt); - - return grub_error (GRUB_ERR_BAD_OS, "Linux call returned"); -} - -/* - * Only support zImage, so no relocations necessary - */ -static grub_err_t -linux_load (const char *filename, grub_file_t file) -{ - struct linux_arch_kernel_header *lh; - int size; - - size = grub_file_size (file); - - linux_addr = LINUX_ADDRESS; - grub_dprintf ("loader", "Loading Linux to 0x%08x\n", - (grub_addr_t) linux_addr); - - if (grub_file_read (file, (void *) linux_addr, size) != size) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - return grub_errno; - } - - lh = (void *) linux_addr; - - if ((grub_size_t) size > sizeof (*lh) && - lh->magic == GRUB_LINUX_ARM_MAGIC_SIGNATURE) - ; - else if (size > 0x8000 && *(grub_uint32_t *) (linux_addr) == 0xea000006 - && machine_type == GRUB_ARM_MACHINE_TYPE_RASPBERRY_PI) - grub_memmove ((void *) linux_addr, (void *) (linux_addr + 0x8000), - size - 0x8000); - else - return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("invalid zImage")); - - linux_size = size; - - return GRUB_ERR_NONE; -} - -static grub_err_t -linux_unload (void) -{ - grub_dl_unref (my_mod); - - grub_free (linux_args); - linux_args = NULL; - - initrd_start = initrd_end = 0; - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - int size; - grub_err_t err; - grub_file_t file; - grub_dl_ref (my_mod); - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); - if (!file) - goto fail; - - err = linux_load (argv[0], file); - grub_file_close (file); - if (err) - goto fail; - - grub_loader_set (linux_boot, linux_unload, 0); - - size = grub_loader_cmdline_size (argc, argv); - linux_args = grub_malloc (size + sizeof (LINUX_IMAGE)); - if (!linux_args) - { - grub_loader_unset(); - goto fail; - } - - /* Create kernel command line. */ - grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - err = grub_create_loader_cmdline (argc, argv, - linux_args + sizeof (LINUX_IMAGE) - 1, size, - GRUB_VERIFY_KERNEL_CMDLINE); - if (err) - goto fail; - - return GRUB_ERR_NONE; - -fail: - 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; - grub_size_t size = 0; - struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_INITRD); - if (!file) - return grub_errno; - - if (grub_initrd_init (argc, argv, &initrd_ctx)) - goto fail; - - size = grub_get_initrd_size (&initrd_ctx); - - initrd_start = LINUX_INITRD_ADDRESS; - - grub_dprintf ("loader", "Loading initrd to 0x%08x\n", - (grub_addr_t) initrd_start); - - if (grub_initrd_load (&initrd_ctx, (void *) initrd_start)) - goto fail; - - initrd_end = initrd_start + size; - - return GRUB_ERR_NONE; - -fail: - grub_file_close (file); - - return grub_errno; -} - -static grub_err_t -load_dtb (grub_file_t dtb, int size) -{ - void *new_fdt = grub_zalloc (size); - if (!new_fdt) - return grub_errno; - grub_dprintf ("loader", "Loading device tree to %p\n", - new_fdt); - if ((grub_file_read (dtb, new_fdt, size) != size) - || (grub_fdt_check_header (new_fdt, size) != 0)) - { - grub_free (new_fdt); - return grub_error (GRUB_ERR_BAD_OS, N_("invalid device tree")); - } - - grub_fdt_set_totalsize (new_fdt, size); - current_fdt = new_fdt; - /* - * We've successfully loaded an FDT, so any machine type passed - * from firmware is now obsolete. - */ - machine_type = GRUB_ARM_MACHINE_TYPE_FDT; - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_file_t dtb; - int size; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - dtb = grub_file_open (argv[0], GRUB_FILE_TYPE_DEVICE_TREE_IMAGE); - if (!dtb) - return grub_errno; - - size = grub_file_size (dtb); - if (size == 0) - grub_error (GRUB_ERR_BAD_OS, "empty file"); - else - load_dtb (dtb, size); - grub_file_close (dtb); - - return grub_errno; -} - -static grub_command_t cmd_linux, cmd_initrd, cmd_devicetree; - -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.")); - cmd_devicetree = grub_register_command_lockdown ("devicetree", grub_cmd_devicetree, - /* TRANSLATORS: DTB stands for device tree blob. */ - 0, N_("Load DTB file.")); - my_mod = mod; - current_fdt = (const void *) grub_arm_firmware_get_boot_data (); - machine_type = grub_arm_firmware_get_machine_type (); -} - -GRUB_MOD_FINI (linux) -{ - grub_unregister_command (cmd_linux); - grub_unregister_command (cmd_initrd); - grub_unregister_command (cmd_devicetree); -} diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c deleted file mode 100644 index 26e1472c9..000000000 --- a/grub-core/loader/arm64/xen_boot.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2014 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define XEN_HYPERVISOR_NAME "xen_hypervisor" -#define MODULE_CUSTOM_COMPATIBLE "multiboot,module" - -/* This maximum size is defined in Power.org ePAPR V1.1 - * https://www.power.org/documentation/epapr-version-1-1/ - * 2.2.1.1 Node Name Requirements - * node-name@unit-address - * 31 + 1(@) + 16(64bit address in hex format) + 1(\0) = 49 - */ -#define FDT_NODE_NAME_MAX_SIZE (49) - -struct compat_string_struct -{ - grub_size_t size; - const char *compat_string; -}; -typedef struct compat_string_struct compat_string_struct_t; -#define FDT_COMPATIBLE(x) {.size = sizeof(x), .compat_string = (x)} - -enum module_type -{ - MODULE_IMAGE, - MODULE_INITRD, - MODULE_XSM, - MODULE_CUSTOM -}; -typedef enum module_type module_type_t; - -struct xen_boot_binary -{ - struct xen_boot_binary *next; - struct xen_boot_binary **prev; - int is_hypervisor; - - grub_addr_t start; - grub_size_t size; - grub_size_t align; - - char *cmdline; - int cmdline_size; -}; - -static grub_dl_t my_mod; - -static int loaded; - -static struct xen_boot_binary *xen_hypervisor; -static struct xen_boot_binary *module_head; - -static __inline grub_addr_t -xen_boot_address_align (grub_addr_t start, grub_size_t align) -{ - return (align ? (ALIGN_UP (start, align)) : start); -} - -static grub_err_t -prepare_xen_hypervisor_params (void *xen_boot_fdt) -{ - int chosen_node = 0; - int retval; - - chosen_node = grub_fdt_find_subnode (xen_boot_fdt, 0, "chosen"); - if (chosen_node < 0) - chosen_node = grub_fdt_add_subnode (xen_boot_fdt, 0, "chosen"); - if (chosen_node < 1) - return grub_error (GRUB_ERR_IO, "failed to get chosen node in FDT"); - - /* - * The address and size are always written using 64-bits value. Set - * #address-cells and #size-cells accordingly. - */ - retval = grub_fdt_set_prop32 (xen_boot_fdt, chosen_node, "#address-cells", 2); - if (retval) - return grub_error (GRUB_ERR_IO, "failed to set #address-cells"); - retval = grub_fdt_set_prop32 (xen_boot_fdt, chosen_node, "#size-cells", 2); - if (retval) - return grub_error (GRUB_ERR_IO, "failed to set #size-cells"); - - grub_dprintf ("xen_loader", - "Xen Hypervisor cmdline : %s @ %p size:%d\n", - xen_hypervisor->cmdline, xen_hypervisor->cmdline, - xen_hypervisor->cmdline_size); - - retval = grub_fdt_set_prop (xen_boot_fdt, chosen_node, "bootargs", - xen_hypervisor->cmdline, - xen_hypervisor->cmdline_size); - if (retval) - return grub_error (GRUB_ERR_IO, "failed to install/update FDT"); - - return GRUB_ERR_NONE; -} - -static grub_err_t -prepare_xen_module_params (struct xen_boot_binary *module, void *xen_boot_fdt) -{ - int retval, chosen_node = 0, module_node = 0; - char module_name[FDT_NODE_NAME_MAX_SIZE]; - - retval = grub_snprintf (module_name, FDT_NODE_NAME_MAX_SIZE, "module@%lx", - xen_boot_address_align (module->start, - module->align)); - grub_dprintf ("xen_loader", "Module node name %s \n", module_name); - - if (retval < (int) sizeof ("module@")) - return grub_error (GRUB_ERR_IO, N_("failed to get FDT")); - - chosen_node = grub_fdt_find_subnode (xen_boot_fdt, 0, "chosen"); - if (chosen_node < 0) - chosen_node = grub_fdt_add_subnode (xen_boot_fdt, 0, "chosen"); - if (chosen_node < 1) - return grub_error (GRUB_ERR_IO, "failed to get chosen node in FDT"); - - module_node = - grub_fdt_find_subnode (xen_boot_fdt, chosen_node, module_name); - if (module_node < 0) - module_node = - grub_fdt_add_subnode (xen_boot_fdt, chosen_node, module_name); - - retval = grub_fdt_set_prop (xen_boot_fdt, module_node, "compatible", - MODULE_CUSTOM_COMPATIBLE, sizeof(MODULE_CUSTOM_COMPATIBLE)); - if (retval) - return grub_error (GRUB_ERR_IO, "failed to update FDT"); - - grub_dprintf ("xen_loader", "Module\n"); - - retval = grub_fdt_set_reg64 (xen_boot_fdt, module_node, - xen_boot_address_align (module->start, - module->align), - module->size); - if (retval) - return grub_error (GRUB_ERR_IO, "failed to update FDT"); - - if (module->cmdline && module->cmdline_size > 0) - { - grub_dprintf ("xen_loader", - "Module cmdline : %s @ %p size:%d\n", - module->cmdline, module->cmdline, module->cmdline_size); - - retval = grub_fdt_set_prop (xen_boot_fdt, module_node, "bootargs", - module->cmdline, module->cmdline_size + 1); - if (retval) - return grub_error (GRUB_ERR_IO, "failed to update FDT"); - } - else - { - grub_dprintf ("xen_loader", "Module has no bootargs!\n"); - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -finalize_params_xen_boot (void) -{ - struct xen_boot_binary *module; - void *xen_boot_fdt; - grub_size_t additional_size = 0x1000; - - /* Hypervisor. */ - additional_size += FDT_NODE_NAME_MAX_SIZE + xen_hypervisor->cmdline_size; - FOR_LIST_ELEMENTS (module, module_head) - { - additional_size += 6 * FDT_NODE_NAME_MAX_SIZE + sizeof(MODULE_CUSTOM_COMPATIBLE) - 1 - + module->cmdline_size; - } - - xen_boot_fdt = grub_fdt_load (additional_size); - if (!xen_boot_fdt) - return grub_error (GRUB_ERR_IO, "failed to get FDT"); - - if (xen_hypervisor) - { - if (prepare_xen_hypervisor_params (xen_boot_fdt) != GRUB_ERR_NONE) - goto fail; - } - else - { - grub_dprintf ("xen_loader", "Failed to get Xen Hypervisor info!\n"); - goto fail; - } - - /* Set module params info */ - FOR_LIST_ELEMENTS (module, module_head) - { - if (module->start && module->size > 0) - { - grub_dprintf ("xen_loader", "Module @ 0x%lx size:0x%lx\n", - xen_boot_address_align (module->start, module->align), - module->size); - if (prepare_xen_module_params (module, xen_boot_fdt) != GRUB_ERR_NONE) - goto fail; - } - else - { - grub_dprintf ("xen_loader", "Module info error!\n"); - goto fail; - } - } - - if (grub_fdt_install() == GRUB_ERR_NONE) - return GRUB_ERR_NONE; - -fail: - grub_fdt_unload (); - - return grub_error (GRUB_ERR_IO, "failed to install/update FDT"); -} - - -static grub_err_t -xen_boot (void) -{ - grub_err_t err = finalize_params_xen_boot (); - if (err) - return err; - - return grub_arch_efi_linux_boot_image (xen_hypervisor->start, - xen_hypervisor->size, - xen_hypervisor->cmdline); -} - -static void -single_binary_unload (struct xen_boot_binary *binary) -{ - if (!binary) - return; - - if (binary->start && binary->size > 0) - { - grub_efi_free_pages ((grub_efi_physical_address_t) binary->start, - GRUB_EFI_BYTES_TO_PAGES (binary->size + binary->align)); - } - - if (binary->cmdline && binary->cmdline_size > 0) - { - grub_free (binary->cmdline); - grub_dprintf ("xen_loader", - "Module cmdline memory free @ %p size: %d\n", - binary->cmdline, binary->cmdline_size); - } - - if (!binary->is_hypervisor) - grub_list_remove (GRUB_AS_LIST (binary)); - - grub_dprintf ("xen_loader", - "Module struct memory free @ %p size: 0x%lx\n", - binary, sizeof (binary)); - grub_free (binary); - - return; -} - -static void -all_binaries_unload (void) -{ - struct xen_boot_binary *binary; - - FOR_LIST_ELEMENTS (binary, module_head) - { - single_binary_unload (binary); - } - - if (xen_hypervisor) - single_binary_unload (xen_hypervisor); - - return; -} - -static grub_err_t -xen_unload (void) -{ - loaded = 0; - all_binaries_unload (); - grub_fdt_unload (); - grub_dl_unref (my_mod); - - return GRUB_ERR_NONE; -} - -static void -xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file, - int argc, char *argv[]) -{ - binary->size = grub_file_size (file); - grub_dprintf ("xen_loader", "Xen_boot file size: 0x%lx\n", binary->size); - - binary->start - = (grub_addr_t) grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES - (binary->size + - binary->align)); - if (!binary->start) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - return; - } - - grub_dprintf ("xen_loader", "Xen_boot numpages: 0x%lx\n", - GRUB_EFI_BYTES_TO_PAGES (binary->size + binary->align)); - - if (grub_file_read (file, (void *) xen_boot_address_align (binary->start, - binary->align), - binary->size) != (grub_ssize_t) binary->size) - { - single_binary_unload (binary); - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); - return; - } - - if (argc > 1) - { - binary->cmdline_size = grub_loader_cmdline_size (argc - 1, argv + 1); - binary->cmdline = grub_zalloc (binary->cmdline_size); - if (!binary->cmdline) - { - single_binary_unload (binary); - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - return; - } - grub_create_loader_cmdline (argc - 1, argv + 1, binary->cmdline, - binary->cmdline_size, - GRUB_VERIFY_KERNEL_CMDLINE); - grub_dprintf ("xen_loader", - "Xen_boot cmdline @ %p %s, size: %d\n", - binary->cmdline, binary->cmdline, binary->cmdline_size); - } - else - { - binary->cmdline_size = 0; - binary->cmdline = NULL; - } - - grub_errno = GRUB_ERR_NONE; - return; -} - -static grub_err_t -grub_cmd_xen_module (grub_command_t cmd __attribute__((unused)), - int argc, char *argv[]) -{ - - struct xen_boot_binary *module = NULL; - grub_file_t file = 0; - int nounzip = 0; - - if (!argc) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - if (grub_strcmp (argv[0], "--nounzip") == 0) - { - argv++; - argc--; - nounzip = 1; - } - - if (!argc) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - if (!loaded) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("you need to load the Xen Hypervisor first")); - goto fail; - } - - module = - (struct xen_boot_binary *) grub_zalloc (sizeof (struct xen_boot_binary)); - if (!module) - return grub_errno; - - module->is_hypervisor = 0; - module->align = 4096; - - grub_dprintf ("xen_loader", "Init module and node info\n"); - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_XEN_MODULE - | (nounzip ? GRUB_FILE_TYPE_NO_DECOMPRESS - : GRUB_FILE_TYPE_NONE)); - if (!file) - goto fail; - - xen_boot_binary_load (module, file, argc, argv); - if (grub_errno == GRUB_ERR_NONE) - grub_list_push (GRUB_AS_LIST_P (&module_head), GRUB_AS_LIST (module)); - - fail: - if (file) - grub_file_close (file); - if (grub_errno != GRUB_ERR_NONE) - single_binary_unload (module); - - return grub_errno; -} - -static grub_err_t -grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - struct linux_arch_kernel_header lh; - grub_file_t file = NULL; - - grub_dl_ref (my_mod); - - if (!argc) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_XEN_HYPERVISOR); - if (!file) - goto fail; - - if (grub_arch_efi_linux_load_image_header (file, &lh) != GRUB_ERR_NONE) - goto fail; - grub_file_seek (file, 0); - - /* if another module has called grub_loader_set, - we need to make sure that another module is unloaded properly */ - grub_loader_unset (); - - xen_hypervisor = - (struct xen_boot_binary *) grub_zalloc (sizeof (struct xen_boot_binary)); - if (!xen_hypervisor) - return grub_errno; - - xen_hypervisor->is_hypervisor = 1; - xen_hypervisor->align - = (grub_size_t) lh.pe_image_header.optional_header.section_alignment; - - xen_boot_binary_load (xen_hypervisor, file, argc, argv); - if (grub_errno == GRUB_ERR_NONE) - { - grub_loader_set (xen_boot, xen_unload, 0); - loaded = 1; - } - -fail: - if (file) - grub_file_close (file); - if (grub_errno != GRUB_ERR_NONE) - { - loaded = 0; - all_binaries_unload (); - grub_dl_unref (my_mod); - } - - return grub_errno; -} - -static grub_command_t cmd_xen_hypervisor; -static grub_command_t cmd_xen_module; - -GRUB_MOD_INIT (xen_boot) -{ - cmd_xen_hypervisor = - grub_register_command ("xen_hypervisor", grub_cmd_xen_hypervisor, 0, - N_("Load a xen hypervisor.")); - cmd_xen_module = - grub_register_command ("xen_module", grub_cmd_xen_module, 0, - N_("Load a xen module.")); - my_mod = mod; -} - -GRUB_MOD_FINI (xen_boot) -{ - grub_unregister_command (cmd_xen_hypervisor); - grub_unregister_command (cmd_xen_module); -} diff --git a/grub-core/loader/efi/appleloader.c b/grub-core/loader/efi/appleloader.c deleted file mode 100644 index a0b61a240..000000000 --- a/grub-core/loader/efi/appleloader.c +++ /dev/null @@ -1,242 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -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; - 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; - 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; -}; - -#define MAKE_PIWG_PATH(st, en) \ - { \ - .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) \ - }, \ - .memory_type = GRUB_EFI_MEMORY_MAPPED_IO, \ - .start_address = st, \ - .end_address = en \ - }, \ - .comp2 = \ - { \ - .header = { \ - .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE, \ - .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE, \ - .length = sizeof (struct grub_efi_piwg_device_path) \ - }, \ - .guid = GRUB_EFI_VENDOR_APPLE_GUID \ - }, \ - .end = \ - { \ - .type = GRUB_EFI_END_DEVICE_PATH_TYPE, \ - .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE, \ - .length = sizeof (struct grub_efi_device_path) \ - } \ - } - -/* early 2006 Core Duo / Core Solo models */ -static struct piwg_full_device_path devpath_1 = MAKE_PIWG_PATH (0xffe00000, - 0xfff9ffff); - -/* mid-2006 Mac Pro (and probably other Core 2 models) */ -static struct piwg_full_device_path devpath_2 = MAKE_PIWG_PATH (0xffe00000, - 0xfff7ffff); - -/* mid-2007 MBP ("Santa Rosa" based models) */ -static struct piwg_full_device_path devpath_3 = MAKE_PIWG_PATH (0xffe00000, - 0xfff8ffff); - -/* early-2008 MBA */ -static struct piwg_full_device_path devpath_4 = MAKE_PIWG_PATH (0xffc00000, - 0xfff8ffff); - -/* late-2008 MB/MBP (NVidia chipset) */ -static struct piwg_full_device_path devpath_5 = MAKE_PIWG_PATH (0xffcb4000, - 0xffffbfff); - -/* mid-2010 MB/MBP (NVidia chipset) */ -static struct piwg_full_device_path devpath_6 = MAKE_PIWG_PATH (0xffcc4000, - 0xffffbfff); - -static struct piwg_full_device_path devpath_7 = MAKE_PIWG_PATH (0xff981000, - 0xffc8ffff); - -/* mid-2012 MBP retina (MacBookPro10,1) */ -static struct piwg_full_device_path devpath_8 = MAKE_PIWG_PATH (0xff990000, - 0xffb2ffff); - -struct devdata -{ - const 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}, - {"MB NV2", (grub_efi_device_path_t *) &devpath_6}, - {"MBP2011", (grub_efi_device_path_t *) &devpath_7}, - {"MBP2012", (grub_efi_device_path_t *) &devpath_8}, - {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 (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_dprintf ("appleload", "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, - N_("[OPTS]"), - /* TRANSLATORS: This command is used on EFI to - switch to BIOS mode and boot the OS requiring - BIOS. */ - N_("Boot BIOS-based system.")); - my_mod = mod; -} - -GRUB_MOD_FINI(appleloader) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c deleted file mode 100644 index e510b3491..000000000 --- a/grub-core/loader/efi/fdt.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013-2015 Free Software Foundation, Inc. - * Copyright (C) 2024 Canonical, Ltd. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void *loaded_fdt; -static void *fdt; - -#define FDT_ADDR_CELLS_STRING "#address-cells" -#define FDT_SIZE_CELLS_STRING "#size-cells" -#define FDT_ADDR_SIZE_EXTRA ((2 * grub_fdt_prop_entry_size (sizeof(grub_uint32_t))) + \ - sizeof (FDT_ADDR_CELLS_STRING) + \ - sizeof (FDT_SIZE_CELLS_STRING)) - -static const struct grub_arg_option options_fdtdump[] = { - {"prop", 'p', 0, N_("Get property."), N_("prop"), ARG_TYPE_STRING}, - {"set", '\0', 0, N_("Store the value in the given variable name."), - N_("variable"), ARG_TYPE_STRING}, - {0, 0, 0, 0, 0, 0} -}; - -void * -grub_fdt_load (grub_size_t additional_size) -{ - void *raw_fdt; - unsigned int size; - - if (fdt) - { - size = GRUB_EFI_BYTES_TO_PAGES (grub_fdt_get_totalsize (fdt)); - grub_efi_free_pages ((grub_addr_t) fdt, size); - } - - if (loaded_fdt) - raw_fdt = loaded_fdt; - else - raw_fdt = grub_efi_get_firmware_fdt(); - - if (raw_fdt) - size = grub_fdt_get_totalsize (raw_fdt); - else - size = GRUB_FDT_EMPTY_TREE_SZ + FDT_ADDR_SIZE_EXTRA; - - size += additional_size; - - grub_dprintf ("linux", "allocating %d bytes for fdt\n", size); - fdt = grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, - GRUB_EFI_BYTES_TO_PAGES (size), - GRUB_EFI_ALLOCATE_MAX_ADDRESS, - GRUB_EFI_ACPI_RECLAIM_MEMORY); - if (!fdt) - return NULL; - - if (raw_fdt) - { - grub_memmove (fdt, raw_fdt, size - additional_size); - grub_fdt_set_totalsize (fdt, size); - } - else - { - grub_fdt_create_empty_tree (fdt, size); - grub_fdt_set_prop32 (fdt, 0, FDT_ADDR_CELLS_STRING, 2); - grub_fdt_set_prop32 (fdt, 0, FDT_SIZE_CELLS_STRING, 2); - } - return fdt; -} - -grub_err_t -grub_fdt_install (void) -{ - grub_efi_boot_services_t *b; - static grub_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID; - grub_efi_status_t status; - - if (fdt == NULL && loaded_fdt == NULL) - return GRUB_ERR_NONE; - - b = grub_efi_system_table->boot_services; - status = b->install_configuration_table (&fdt_guid, fdt ? fdt : loaded_fdt); - if (status != GRUB_EFI_SUCCESS) - return grub_error (GRUB_ERR_IO, "failed to install FDT"); - - grub_dprintf ("fdt", "Installed/updated FDT configuration table @ %p\n", - fdt ? fdt : loaded_fdt); - return GRUB_ERR_NONE; -} - -void -grub_fdt_unload (void) { - if (!fdt) { - return; - } - grub_efi_free_pages ((grub_addr_t) fdt, - GRUB_EFI_BYTES_TO_PAGES (grub_fdt_get_totalsize (fdt))); - fdt = NULL; -} - -static grub_err_t -grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_file_t dtb; - void *blob = NULL; - int size; - - if (loaded_fdt) - grub_free (loaded_fdt); - loaded_fdt = NULL; - - /* No arguments means "use firmware FDT". */ - if (argc == 0) - { - return GRUB_ERR_NONE; - } - - dtb = grub_file_open (argv[0], GRUB_FILE_TYPE_DEVICE_TREE_IMAGE); - if (!dtb) - goto out; - - size = grub_file_size (dtb); - blob = grub_malloc (size); - if (!blob) - goto out; - - if (grub_file_read (dtb, blob, size) < size) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); - goto out; - } - - if (grub_fdt_check_header (blob, size) != 0) - { - grub_error (GRUB_ERR_BAD_OS, N_("invalid device tree")); - goto out; - } - -out: - if (dtb) - grub_file_close (dtb); - - if (blob) - { - if (grub_errno == GRUB_ERR_NONE) - loaded_fdt = blob; - else - grub_free (blob); - } - - return grub_errno; -} - -static grub_err_t -grub_cmd_fdtdump (grub_extcmd_context_t ctxt, - int argc __attribute__ ((unused)), - char **argv __attribute__ ((unused))) -{ - struct grub_arg_list *state = ctxt->state; - const char *value = NULL; - void *fw_fdt; - - fw_fdt = grub_efi_get_firmware_fdt (); - if (fw_fdt == NULL) - return grub_error (GRUB_ERR_IO, - N_("No device tree found")); - - if (state[0].set) - value = grub_fdt_get_prop (fw_fdt, 0, state[0].arg, NULL); - - if (value == NULL) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("failed to retrieve the prop field")); - - if (state[1].set) - grub_env_set (state[1].arg, value); - else - grub_printf ("%s\n", value); - - return GRUB_ERR_NONE; -} - -static grub_command_t cmd_devicetree; -static grub_extcmd_t cmd_fdtdump; - -GRUB_MOD_INIT (fdt) -{ - cmd_fdtdump = - grub_register_extcmd ("fdtdump", grub_cmd_fdtdump, 0, - N_("[-p] [--set variable]"), - N_("Retrieve device tree information."), - options_fdtdump); - cmd_devicetree = - grub_register_command_lockdown ("devicetree", grub_cmd_devicetree, 0, - N_("Load DTB file.")); -} - -GRUB_MOD_FINI (fdt) -{ - grub_unregister_command (cmd_devicetree); - grub_unregister_extcmd (cmd_fdtdump); -} diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c deleted file mode 100644 index 36dea2931..000000000 --- a/grub-core/loader/efi/linux.c +++ /dev/null @@ -1,597 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_dl_t my_mod; -static int loaded; - -static void *kernel_addr; -static grub_uint64_t kernel_size; - -static char *linux_args; -static grub_uint32_t cmdline_size; - -static grub_addr_t initrd_start; -static grub_addr_t initrd_end; - -static struct grub_linux_initrd_context initrd_ctx = {0, 0, 0}; -static grub_efi_handle_t initrd_lf2_handle = NULL; -static bool initrd_use_loadfile2 = false; - -static grub_guid_t load_file2_guid = GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID; -static grub_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID; - -static initrd_media_device_path_t initrd_lf2_device_path = { - { - { - GRUB_EFI_MEDIA_DEVICE_PATH_TYPE, - GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE, - sizeof(grub_efi_vendor_media_device_path_t), - }, - LINUX_EFI_INITRD_MEDIA_GUID - }, { - GRUB_EFI_END_DEVICE_PATH_TYPE, - GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE, - sizeof(grub_efi_device_path_t) - } -}; - -extern grub_err_t -grub_cmd_linux_x86_legacy (grub_command_t cmd, int argc, char *argv[]); - -extern grub_err_t -grub_cmd_initrd_x86_legacy (grub_command_t cmd, int argc, char *argv[]); - -static grub_efi_status_t __grub_efi_api -grub_efi_initrd_load_file2 (grub_efi_load_file2_t *this, - grub_efi_device_path_t *device_path, - grub_efi_boolean_t boot_policy, - grub_efi_uintn_t *buffer_size, - void *buffer); - -static grub_efi_load_file2_t initrd_lf2 = { - grub_efi_initrd_load_file2 -}; - -grub_err_t -grub_arch_efi_linux_load_image_header (grub_file_t file, - struct linux_arch_kernel_header * lh) -{ - grub_file_seek (file, 0); - if (grub_file_read (file, lh, sizeof (*lh)) < (grub_ssize_t) sizeof (*lh)) - return grub_error(GRUB_ERR_FILE_READ_ERROR, "failed to read Linux image header"); - - if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled")); - - grub_dprintf ("linux", "UEFI stub kernel:\n"); - grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset); - - /* - * The PE/COFF spec permits the COFF header to appear anywhere in the file, so - * we need to double check whether it was where we expected it, and if not, we - * must load it from the correct offset into the pe_image_header field of - * struct linux_arch_kernel_header. - */ - if ((grub_uint8_t *) lh + lh->hdr_offset != (grub_uint8_t *) &lh->pe_image_header) - { - if (grub_file_seek (file, lh->hdr_offset) == (grub_off_t) -1 - || grub_file_read (file, &lh->pe_image_header, - sizeof (struct grub_pe_image_header)) - != sizeof (struct grub_pe_image_header)) - return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image header"); - } - - if (lh->pe_image_header.optional_header.magic != GRUB_PE32_NATIVE_MAGIC) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "non-native image not supported"); - - /* - * Linux kernels built for any architecture are guaranteed to support the - * LoadFile2 based initrd loading protocol if the image version is >= 1. - */ - if (lh->pe_image_header.optional_header.major_image_version >= 1) - initrd_use_loadfile2 = true; - else - initrd_use_loadfile2 = false; - - grub_dprintf ("linux", "LoadFile2 initrd loading %sabled\n", - initrd_use_loadfile2 ? "en" : "dis"); - - return GRUB_ERR_NONE; -} - -#if !defined(__i386__) && !defined(__x86_64__) -static grub_err_t -finalize_params_linux (void) -{ - int node, retval; - - void *fdt; - - /* Set initrd info */ - if (initrd_start && initrd_end > initrd_start) - { - fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE); - - if (!fdt) - goto failure; - - node = grub_fdt_find_subnode (fdt, 0, "chosen"); - if (node < 0) - node = grub_fdt_add_subnode (fdt, 0, "chosen"); - - if (node < 1) - goto failure; - - grub_dprintf ("linux", "Initrd @ %p-%p\n", - (void *) initrd_start, (void *) initrd_end); - - retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start", - initrd_start); - if (retval) - goto failure; - retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end", - initrd_end); - if (retval) - goto failure; - } - - if (grub_fdt_install() != GRUB_ERR_NONE) - goto failure; - - return GRUB_ERR_NONE; - -failure: - grub_fdt_unload(); - return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); -} -#endif - -grub_err_t -grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args) -{ - grub_efi_memory_mapped_device_path_t *mempath; - grub_efi_handle_t image_handle; - grub_efi_boot_services_t *b; - grub_efi_status_t status; - grub_efi_loaded_image_t *loaded_image; - grub_size_t len; - grub_size_t args_len; - - mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t)); - if (!mempath) - return grub_errno; - - mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE; - mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE; - mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath)); - mempath[0].memory_type = GRUB_EFI_LOADER_DATA; - mempath[0].start_address = addr; - mempath[0].end_address = addr + size; - - mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE; - mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; - mempath[1].header.length = sizeof (grub_efi_device_path_t); - - b = grub_efi_system_table->boot_services; - status = b->load_image (0, grub_efi_image_handle, - (grub_efi_device_path_t *) mempath, - (void *) addr, size, &image_handle); - if (status != GRUB_EFI_SUCCESS) - return grub_error (GRUB_ERR_BAD_OS, "cannot load image"); - - grub_dprintf ("linux", "linux command line: '%s'\n", args); - - /* Convert command line to UTF-16. */ - loaded_image = grub_efi_get_loaded_image (image_handle); - if (loaded_image == NULL) - { - grub_error (GRUB_ERR_BAD_FIRMWARE, "missing loaded_image proto"); - goto unload; - } - args_len = grub_strlen (args); - len = (args_len + 1) * sizeof (grub_efi_char16_t); - loaded_image->load_options = - grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (len)); - if (!loaded_image->load_options) - return grub_errno; - - len = grub_utf8_to_utf16 (loaded_image->load_options, len, - (grub_uint8_t *) args, args_len, NULL); - /* NUL terminate. */ - ((grub_efi_char16_t *) loaded_image->load_options)[len++] = 0; - loaded_image->load_options_size = len * sizeof (grub_efi_char16_t); - - grub_dprintf ("linux", "starting image %p\n", image_handle); - status = b->start_image (image_handle, 0, NULL); - - /* When successful, not reached */ - grub_error (GRUB_ERR_BAD_OS, "start_image() returned 0x%" PRIxGRUB_EFI_UINTN_T, status); - grub_efi_free_pages ((grub_addr_t) loaded_image->load_options, - GRUB_EFI_BYTES_TO_PAGES (len)); - loaded_image->load_options = NULL; -unload: - b->unload_image (image_handle); - - return grub_errno; -} - -static grub_err_t -grub_linux_boot (void) -{ -#if !defined(__i386__) && !defined(__x86_64__) - if (finalize_params_linux () != GRUB_ERR_NONE) - return grub_errno; -#endif - - return grub_arch_efi_linux_boot_image ((grub_addr_t) kernel_addr, - kernel_size, linux_args); -} - -static grub_err_t -grub_linux_unload (void) -{ - grub_efi_boot_services_t *b = grub_efi_system_table->boot_services; - - grub_dl_unref (my_mod); - loaded = 0; - if (initrd_start) - grub_efi_free_pages ((grub_efi_physical_address_t) initrd_start, - GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start)); - initrd_start = initrd_end = 0; - grub_free (linux_args); - if (kernel_addr) - grub_efi_free_pages ((grub_addr_t) kernel_addr, - GRUB_EFI_BYTES_TO_PAGES (kernel_size)); -#if !defined(__i386__) && !defined(__x86_64__) - grub_fdt_unload (); -#endif - - if (initrd_lf2_handle != NULL) - { - b->uninstall_multiple_protocol_interfaces (initrd_lf2_handle, - &load_file2_guid, - &initrd_lf2, - &device_path_guid, - &initrd_lf2_device_path, - NULL); - initrd_lf2_handle = NULL; - initrd_use_loadfile2 = false; - } - return GRUB_ERR_NONE; -} - -#if !defined(__i386__) && !defined(__x86_64__) -/* - * As per linux/Documentation/arm/Booting - * ARM initrd needs to be covered by kernel linear mapping, - * so place it in the first 512MB of DRAM. - * - * As per linux/Documentation/arm64/booting.txt - * ARM64 initrd needs to be contained entirely within a 1GB aligned window - * of up to 32GB of size that covers the kernel image as well. - * Since the EFI stub loader will attempt to load the kernel near start of - * RAM, place the buffer in the first 32GB of RAM. - */ -#ifdef __arm__ -#define INITRD_MAX_ADDRESS_OFFSET (512U * 1024 * 1024) -#else /* __aarch64__ */ -#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024) -#endif - -/* - * This function returns a pointer to a legally allocated initrd buffer, - * or NULL if unsuccessful - */ -static void * -allocate_initrd_mem (int initrd_pages) -{ - grub_addr_t max_addr; - - if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE) - return NULL; - - max_addr += INITRD_MAX_ADDRESS_OFFSET - 1; - - return grub_efi_allocate_pages_real (max_addr, initrd_pages, - GRUB_EFI_ALLOCATE_MAX_ADDRESS, - GRUB_EFI_LOADER_DATA); -} -#endif - -static grub_efi_status_t __grub_efi_api -grub_efi_initrd_load_file2 (grub_efi_load_file2_t *this, - grub_efi_device_path_t *device_path, - grub_efi_boolean_t boot_policy, - grub_efi_uintn_t *buffer_size, - void *buffer) -{ - grub_efi_status_t status = GRUB_EFI_SUCCESS; - grub_efi_uintn_t initrd_size; - - if (this != &initrd_lf2 || buffer_size == NULL) - return GRUB_EFI_INVALID_PARAMETER; - - if (device_path->type != GRUB_EFI_END_DEVICE_PATH_TYPE || - device_path->subtype != GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE) - return GRUB_EFI_NOT_FOUND; - - if (boot_policy) - return GRUB_EFI_UNSUPPORTED; - - initrd_size = grub_get_initrd_size (&initrd_ctx); - if (buffer == NULL || *buffer_size < initrd_size) - { - *buffer_size = initrd_size; - return GRUB_EFI_BUFFER_TOO_SMALL; - } - - grub_dprintf ("linux", "Providing initrd via EFI_LOAD_FILE2_PROTOCOL\n"); - - if (grub_initrd_load (&initrd_ctx, buffer)) - status = GRUB_EFI_DEVICE_ERROR; - - grub_initrd_close (&initrd_ctx); - return status; -} - -static grub_err_t -grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - int __attribute__ ((unused)) initrd_size, initrd_pages; - void *__attribute__ ((unused)) initrd_mem = NULL; - grub_efi_boot_services_t *b = grub_efi_system_table->boot_services; - grub_efi_status_t status; - - if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - -#if defined(__i386__) || defined(__x86_64__) - if (!initrd_use_loadfile2) - return grub_cmd_initrd_x86_legacy (cmd, argc, argv); -#endif - - if (!loaded) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("you need to load the kernel first")); - goto fail; - } - - if (grub_initrd_init (argc, argv, &initrd_ctx)) - goto fail; - - if (initrd_use_loadfile2) - { - if (initrd_lf2_handle == NULL) - { - status = b->install_multiple_protocol_interfaces (&initrd_lf2_handle, - &load_file2_guid, - &initrd_lf2, - &device_path_guid, - &initrd_lf2_device_path, - NULL); - if (status == GRUB_EFI_OUT_OF_RESOURCES) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - goto fail; - } - else if (status != GRUB_EFI_SUCCESS) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("failed to install protocols")); - goto fail; - } - } - grub_dprintf ("linux", "Using LoadFile2 initrd loading protocol\n"); - return GRUB_ERR_NONE; - } - -#if !defined(__i386__) && !defined(__x86_64__) - initrd_size = grub_get_initrd_size (&initrd_ctx); - grub_dprintf ("linux", "Loading initrd\n"); - - initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size)); - initrd_mem = allocate_initrd_mem (initrd_pages); - - if (!initrd_mem) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - goto fail; - } - - if (grub_initrd_load (&initrd_ctx, initrd_mem)) - { - grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages); - goto fail; - } - - initrd_start = (grub_addr_t) initrd_mem; - initrd_end = initrd_start + initrd_size; - grub_dprintf ("linux", "[addr=%p, size=0x%x]\n", - (void *) initrd_start, initrd_size); -#endif - - fail: - grub_initrd_close (&initrd_ctx); - - return grub_errno; -} - -static grub_err_t -grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_file_t file = 0; - struct linux_arch_kernel_header lh; - grub_err_t err; - - grub_dl_ref (my_mod); - - if (grub_is_shim_lock_enabled () == true) - { -#if defined(__i386__) || defined(__x86_64__) - grub_dprintf ("linux", "shim_lock enabled, falling back to legacy Linux kernel loader\n"); - - err = grub_cmd_linux_x86_legacy (cmd, argc, argv); - - if (err == GRUB_ERR_NONE) - return GRUB_ERR_NONE; - else - goto fail; -#else - grub_dprintf ("linux", "shim_lock enabled, trying Linux kernel EFI stub loader\n"); -#endif - } - - if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); - if (!file) - goto fail; - - grub_loader_unset(); - - kernel_size = grub_file_size (file); - - if (grub_arch_efi_linux_load_image_header (file, &lh) != GRUB_ERR_NONE) -#if !defined(__i386__) && !defined(__x86_64__) - goto fail; -#else - goto fallback; - - if (!initrd_use_loadfile2) - { - /* - * This is a EFI stub image but it is too old to implement the LoadFile2 - * based initrd loading scheme, and Linux/x86 does not support the DT - * based method either. So fall back to the x86-specific loader that - * enters Linux in EFI mode but without going through its EFI stub. - */ -fallback: - grub_file_close (file); - return grub_cmd_linux_x86_legacy (cmd, argc, argv); - } -#endif - - grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size); - kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size)); - grub_dprintf ("linux", "kernel numpages: %lld\n", - (long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size)); - if (!kernel_addr) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - goto fail; - } - - grub_file_seek (file, 0); - if (grub_file_read (file, kernel_addr, kernel_size) - < (grub_int64_t) kernel_size) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); - goto fail; - } - - grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); - - cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); - linux_args = grub_malloc (cmdline_size); - if (!linux_args) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - goto fail; - } - grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - err = grub_create_loader_cmdline (argc, argv, - linux_args + sizeof (LINUX_IMAGE) - 1, - cmdline_size, - GRUB_VERIFY_KERNEL_CMDLINE); - if (err) - goto fail; - - if (grub_errno == GRUB_ERR_NONE) - { - grub_loader_set (grub_linux_boot, grub_linux_unload, 0); - loaded = 1; - } - -fail: - if (file) - grub_file_close (file); - - if (grub_errno != GRUB_ERR_NONE) - { - grub_dl_unref (my_mod); - loaded = 0; - } - - if (linux_args && !loaded) - grub_free (linux_args); - - if (kernel_addr && !loaded) - grub_efi_free_pages ((grub_addr_t) kernel_addr, - GRUB_EFI_BYTES_TO_PAGES (kernel_size)); - - 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/emu/linux.c b/grub-core/loader/emu/linux.c deleted file mode 100644 index 638c55bf8..000000000 --- a/grub-core/loader/emu/linux.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_dl_t my_mod; - -static char *kernel_path; -static char *initrd_path; -static char *boot_cmdline; - -static grub_err_t -grub_linux_boot (void) -{ - grub_err_t rc = GRUB_ERR_NONE; - char *initrd_param; - const char *kexec[] = {"kexec", "-la", kernel_path, boot_cmdline, NULL, NULL}; - const char *systemctl[] = {"systemctl", "kexec", NULL}; - int kexecute = grub_util_get_kexecute (); - - if (initrd_path) - { - initrd_param = grub_xasprintf ("--initrd=%s", initrd_path); - kexec[3] = initrd_param; - kexec[4] = boot_cmdline; - } - else - initrd_param = grub_xasprintf ("%s", ""); - - grub_dprintf ("linux", "%serforming 'kexec -la %s %s %s'\n", - (kexecute) ? "P" : "Not p", - kernel_path, initrd_param, boot_cmdline); - - if (kexecute) - rc = grub_util_exec (kexec); - - grub_free (initrd_param); - - if (rc != GRUB_ERR_NONE) - { - grub_error (rc, N_("error trying to perform kexec load operation")); - grub_sleep (3); - return rc; - } - - if (kexecute < 1) - grub_fatal (N_("use '%s %s' to force a system restart"), program_name, "--kexec"); - - grub_dprintf ("linux", "Performing 'systemctl kexec' (%s) ", - (kexecute==1) ? "do-or-die" : "just-in-case"); - rc = grub_util_exec (systemctl); - - /* `systemctl kexec` is "asynchronous" and will return even on success. */ - if (rc == 0) - grub_sleep (10); - - if (kexecute == 1) - grub_fatal (N_("error trying to perform 'systemctl kexec': %d"), rc); - - /* - * WARNING: forcible reset should only be used in read-only environments. - * grub-emu cannot check for these - users beware. - */ - grub_dprintf ("linux", "Performing 'kexec -ex'"); - kexec[1] = "-ex"; - kexec[2] = NULL; - rc = grub_util_exec (kexec); - if (rc != GRUB_ERR_NONE) - grub_fatal (N_("error trying to directly perform 'kexec -ex': %d"), rc); - - return rc; -} - -static grub_err_t -grub_linux_unload (void) -{ - /* Unloading: we're no longer in use. */ - grub_dl_unref (my_mod); - grub_free (boot_cmdline); - boot_cmdline = NULL; - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc, - char *argv[]) -{ - int i; - char *tempstr; - - /* Mark ourselves as in-use. */ - grub_dl_ref (my_mod); - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - if (!grub_util_is_regular (argv[0])) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, - N_("cannot find kernel file %s"), argv[0]); - - grub_free (kernel_path); - kernel_path = grub_xasprintf ("%s", argv[0]); - - grub_free (boot_cmdline); - boot_cmdline = NULL; - - if (argc > 1) - { - boot_cmdline = grub_xasprintf ("--command-line=%s", argv[1]); - for (i = 2; i < argc; i++) - { - tempstr = grub_xasprintf ("%s %s", boot_cmdline, argv[i]); - grub_free (boot_cmdline); - boot_cmdline = tempstr; - } - } - - grub_loader_set (grub_linux_boot, grub_linux_unload, 0); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, - char *argv[]) -{ - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - if (!grub_util_is_regular (argv[0])) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, - N_("Cannot find initrd file %s"), argv[0]); - - grub_free (initrd_path); - initrd_path = grub_xasprintf ("%s", argv[0]); - - /* We are done - mark ourselves as on longer in use. */ - grub_dl_unref (my_mod); - - return GRUB_ERR_NONE; -} - -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/bsd.c b/grub-core/loader/i386/bsd.c deleted file mode 100644 index 4b7c436d4..000000000 --- a/grub-core/loader/i386/bsd.c +++ /dev/null @@ -1,2195 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef GRUB_MACHINE_PCBIOS -#include -#endif - -GRUB_MOD_LICENSE ("GPLv3+"); - -#include -#ifdef GRUB_MACHINE_PCBIOS -#include -#endif -#ifdef GRUB_MACHINE_EFI -#include -#define NETBSD_DEFAULT_VIDEO_MODE "800x600" -#else -#define NETBSD_DEFAULT_VIDEO_MODE "text" -#include -#endif -#include - -#include -#include -#include -#include -#include - -#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) - -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 void *kern_chunk_src; -static grub_uint32_t bootflags; -static int is_elf_kernel, is_64bit; -static grub_uint32_t openbsd_root; -static struct grub_relocator *relocator = NULL; -static struct grub_openbsd_ramdisk_descriptor openbsd_ramdisk; - -struct bsd_tag -{ - struct bsd_tag *next; - grub_size_t len; - grub_uint32_t type; - union { - grub_uint8_t a; - grub_uint16_t b; - grub_uint32_t c; - } data[0]; -}; - -static struct bsd_tag *tags, *tags_last; - -struct netbsd_module -{ - struct netbsd_module *next; - struct grub_netbsd_btinfo_module mod; -}; - -static struct netbsd_module *netbsd_mods, *netbsd_mods_last; - -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 CD-ROM 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 root device."), 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}, - {"serial", 'h', GRUB_ARG_OPTION_OPTIONAL, - N_("Use serial console."), - /* TRANSLATORS: "com" is static and not to be translated. It refers to - serial ports e.g. com1. - */ - N_("comUNIT[,SPEED]"), 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) -#define OPENBSD_SERIAL_ARG (ARRAY_SIZE (openbsd_flags)) - -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_("Suppress normal output (warnings remain)."), 0, 0}, - {"root", 'r', 0, N_("Set root device."), N_("DEVICE"), ARG_TYPE_STRING}, - {"serial", 'h', GRUB_ARG_OPTION_OPTIONAL, - N_("Use serial console."), - /* TRANSLATORS: "com" is static and not to be translated. It refers to - serial ports e.g. com1. - */ - N_("[ADDR|comUNIT][,SPEED]"), 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) -#define NETBSD_SERIAL_ARG (ARRAY_SIZE (netbsd_flags)) - -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); -} - -static grub_err_t -grub_bsd_add_meta_ptr (grub_uint32_t type, void **ptr, grub_uint32_t len) -{ - struct bsd_tag *newtag; - - newtag = grub_malloc (len + sizeof (struct bsd_tag)); - if (!newtag) - return grub_errno; - newtag->len = len; - newtag->type = type; - newtag->next = NULL; - *ptr = newtag->data; - - if (kernel_type == KERNEL_TYPE_FREEBSD - && type == (FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_SMAP)) - { - struct bsd_tag *p; - for (p = tags; - p && p->type != (FREEBSD_MODINFO_METADATA - | FREEBSD_MODINFOMD_KERNEND); - p = p->next); - - if (p) - { - newtag->next = p->next; - p->next = newtag; - if (newtag->next == NULL) - tags_last = newtag; - return GRUB_ERR_NONE; - } - } - - if (tags_last) - tags_last->next = newtag; - else - tags = newtag; - tags_last = newtag; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_bsd_add_meta (grub_uint32_t type, const void *data, grub_uint32_t len) -{ - grub_err_t err; - void *ptr = NULL; - - err = grub_bsd_add_meta_ptr (type, &ptr, len); - if (err) - return err; - if (len) - grub_memcpy (ptr, data, len); - return GRUB_ERR_NONE; -} - - -struct grub_e820_mmap -{ - grub_uint64_t addr; - grub_uint64_t size; - grub_uint32_t type; -} GRUB_PACKED; -#define GRUB_E820_RAM 1 -#define GRUB_E820_RESERVED 2 -#define GRUB_E820_ACPI 3 -#define GRUB_E820_NVS 4 -#define GRUB_E820_BADRAM 5 -#define GRUB_E820_COREBOOT_TABLES 0x10 - -/* Context for generate_e820_mmap. */ -struct generate_e820_mmap_ctx -{ - int count; - struct grub_e820_mmap *mmap; - struct grub_e820_mmap prev, cur; -}; - -/* Helper for generate_e820_mmap. */ -static int -generate_e820_mmap_iter (grub_uint64_t addr, grub_uint64_t size, - grub_memory_type_t type, void *data) -{ - struct generate_e820_mmap_ctx *ctx = data; - - ctx->cur.addr = addr; - ctx->cur.size = size; - - if (type == GRUB_MEMORY_COREBOOT_TABLES - && addr == 0) - /* Nowadays the tables at 0 don't contain anything important but - *BSD needs the memory at 0 for own needs. - */ - type = GRUB_E820_RAM; - - ctx->cur.type = type; - - /* Merge regions if possible. */ - if (ctx->count && ctx->cur.type == ctx->prev.type - && ctx->cur.addr == ctx->prev.addr + ctx->prev.size) - { - ctx->prev.size += ctx->cur.size; - if (ctx->mmap) - ctx->mmap[-1] = ctx->prev; - } - else - { - if (ctx->mmap) - *ctx->mmap++ = ctx->cur; - ctx->prev = ctx->cur; - ctx->count++; - } - - if (kernel_type == KERNEL_TYPE_OPENBSD && ctx->prev.addr < 0x100000 - && ctx->prev.addr + ctx->prev.size > 0x100000) - { - ctx->cur.addr = 0x100000; - ctx->cur.size = ctx->prev.addr + ctx->prev.size - 0x100000; - ctx->cur.type = ctx->prev.type; - ctx->prev.size = 0x100000 - ctx->prev.addr; - if (ctx->mmap) - { - ctx->mmap[-1] = ctx->prev; - ctx->mmap[0] = ctx->cur; - ctx->mmap++; - } - ctx->prev = ctx->cur; - ctx->count++; - } - - return 0; -} - -static void -generate_e820_mmap (grub_size_t *len, grub_size_t *cnt, void *buf) -{ - struct generate_e820_mmap_ctx ctx = { - .count = 0, - .mmap = buf - }; - - grub_mmap_iterate (generate_e820_mmap_iter, &ctx); - - if (len) - *len = ctx.count * sizeof (struct grub_e820_mmap); - *cnt = ctx.count; - - return; -} - -static grub_err_t -grub_bsd_add_mmap (void) -{ - grub_size_t len, cnt; - void *buf = NULL, *buf0; - - generate_e820_mmap (&len, &cnt, buf); - - if (kernel_type == KERNEL_TYPE_NETBSD) - len += sizeof (grub_uint32_t); - - if (kernel_type == KERNEL_TYPE_OPENBSD) - len += sizeof (struct grub_e820_mmap); - - buf = grub_malloc (len); - if (!buf) - return grub_errno; - - buf0 = buf; - if (kernel_type == KERNEL_TYPE_NETBSD) - { - *(grub_uint32_t *) buf = cnt; - buf = ((grub_uint32_t *) buf + 1); - } - - generate_e820_mmap (NULL, &cnt, buf); - - if (kernel_type == KERNEL_TYPE_OPENBSD) - grub_memset ((grub_uint8_t *) buf + len - sizeof (struct grub_e820_mmap), 0, - sizeof (struct grub_e820_mmap)); - - grub_dprintf ("bsd", "%u entries in smap\n", (unsigned) cnt); - if (kernel_type == KERNEL_TYPE_NETBSD) - grub_bsd_add_meta (NETBSD_BTINFO_MEMMAP, buf0, len); - else if (kernel_type == KERNEL_TYPE_OPENBSD) - grub_bsd_add_meta (OPENBSD_BOOTARG_MMAP, buf0, len); - else - grub_bsd_add_meta (FREEBSD_MODINFO_METADATA | - FREEBSD_MODINFOMD_SMAP, buf0, len); - - grub_free (buf0); - - return grub_errno; -} - -grub_err_t -grub_freebsd_add_meta_module (const char *filename, const char *type, - int argc, char **argv, - grub_addr_t addr, grub_uint32_t size) -{ - const char *name; - grub_err_t err; - - 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_bsd_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_bsd_add_meta (FREEBSD_MODINFO_TYPE, type, grub_strlen (type) + 1) - || grub_bsd_add_meta (FREEBSD_MODINFO_ADDR, &addr64, sizeof (addr64)) - || grub_bsd_add_meta (FREEBSD_MODINFO_SIZE, &size64, sizeof (size64))) - return grub_errno; - } - else - { - if (grub_bsd_add_meta (FREEBSD_MODINFO_TYPE, type, grub_strlen (type) + 1) - || grub_bsd_add_meta (FREEBSD_MODINFO_ADDR, &addr, sizeof (addr)) - || grub_bsd_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) - { - void *cmdline; - char *p; - - if (grub_bsd_add_meta_ptr (FREEBSD_MODINFO_ARGS, &cmdline, n)) - return grub_errno; - - p = cmdline; - for (i = 0; i < argc; i++) - { - grub_strcpy (p, argv[i]); - p += grub_strlen (argv[i]); - *(p++) = ' '; - } - *p = 0; - err = grub_verify_string (cmdline, GRUB_VERIFY_MODULE_CMDLINE); - if (err) - return err; - } - } - - return GRUB_ERR_NONE; -} - -static void -grub_freebsd_list_modules (void) -{ - struct bsd_tag *tag; - - grub_printf (" %-18s %-18s%14s%14s\n", _("name"), _("type"), _("addr"), - _("size")); - - for (tag = tags; tag; tag = tag->next) - { - switch (tag->type) - { - case FREEBSD_MODINFO_NAME: - case FREEBSD_MODINFO_TYPE: - grub_printf (" %-18s", (char *) tag->data); - break; - case FREEBSD_MODINFO_ADDR: - { - grub_uint32_t addr; - - addr = *((grub_uint32_t *) tag->data); - grub_printf (" 0x%08x", addr); - break; - } - case FREEBSD_MODINFO_SIZE: - { - grub_uint32_t len; - - len = *((grub_uint32_t *) tag->data); - grub_printf (" 0x%08x\n", len); - } - } - } -} - -static grub_err_t -grub_netbsd_add_meta_module (char *filename, grub_uint32_t type, - grub_addr_t addr, grub_uint32_t size) -{ - char *name; - struct netbsd_module *mod; - name = grub_strrchr (filename, '/'); - - if (name) - name++; - else - name = filename; - - mod = grub_zalloc (sizeof (*mod)); - if (!mod) - return grub_errno; - - grub_strncpy (mod->mod.name, name, sizeof (mod->mod.name) - 1); - mod->mod.addr = addr; - mod->mod.type = type; - mod->mod.size = size; - - if (netbsd_mods_last) - netbsd_mods_last->next = mod; - else - netbsd_mods = mod; - netbsd_mods_last = mod; - - return GRUB_ERR_NONE; -} - -static void -grub_netbsd_list_modules (void) -{ - struct netbsd_module *mod; - - grub_printf (" %-18s%14s%14s%14s\n", _("name"), _("type"), _("addr"), - _("size")); - - for (mod = netbsd_mods; mod; mod = mod->next) - grub_printf (" %-18s 0x%08x 0x%08x 0x%08x", mod->mod.name, - mod->mod.type, mod->mod.addr, mod->mod.size); -} - -/* This function would be here but it's under different license. */ -#include "bsd_pagetable.c" - -static grub_uint32_t freebsd_bootdev, freebsd_biosdev; -static grub_uint64_t freebsd_zfsguid; - -static void -freebsd_get_zfs (void) -{ - grub_device_t dev; - grub_fs_t fs; - char *uuid; - grub_err_t err; - - dev = grub_device_open (0); - if (!dev) - return; - fs = grub_fs_probe (dev); - if (!fs) - return; - if (!fs->fs_uuid || grub_strcmp (fs->name, "zfs") != 0) - return; - err = fs->fs_uuid (dev, &uuid); - if (err) - return; - if (!uuid) - return; - freebsd_zfsguid = grub_strtoull (uuid, 0, 16); - grub_free (uuid); -} - -static grub_err_t -grub_freebsd_boot (void) -{ - struct grub_freebsd_bootinfo bi; - grub_uint8_t *p, *p0; - grub_addr_t p_target; - grub_size_t p_size = 0; - grub_err_t err; - grub_size_t tag_buf_len = 0; - - struct grub_env_var *var; - - grub_memset (&bi, 0, sizeof (bi)); - bi.version = FREEBSD_BOOTINFO_VERSION; - bi.length = sizeof (bi); - - bi.boot_device = freebsd_biosdev; - - p_size = 0; - FOR_SORTED_ENV (var) - if ((grub_memcmp (var->name, "kFreeBSD.", sizeof("kFreeBSD.") - 1) == 0) && (var->name[sizeof("kFreeBSD.") - 1])) - { - p_size += grub_strlen (&var->name[sizeof("kFreeBSD.") - 1]); - p_size++; - p_size += grub_strlen (var->value) + 1; - } - - if (p_size) - p_size = ALIGN_PAGE (kern_end + p_size + 1) - kern_end; - - if (is_elf_kernel) - { - struct bsd_tag *tag; - - err = grub_bsd_add_mmap (); - if (err) - return err; - - err = grub_bsd_add_meta (FREEBSD_MODINFO_END, 0, 0); - if (err) - return err; - - tag_buf_len = 0; - for (tag = tags; tag; tag = tag->next) - tag_buf_len = ALIGN_VAR (tag_buf_len - + sizeof (struct freebsd_tag_header) - + tag->len); - p_size = ALIGN_PAGE (kern_end + p_size + tag_buf_len) - kern_end; - } - - if (is_64bit) - p_size += 4096 * 3; - - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, - kern_end, p_size); - if (err) - return err; - p = get_virtual_current_address (ch); - } - p_target = kern_end; - p0 = p; - kern_end += p_size; - - FOR_SORTED_ENV (var) - if ((grub_memcmp (var->name, "kFreeBSD.", sizeof("kFreeBSD.") - 1) == 0) && (var->name[sizeof("kFreeBSD.") - 1])) - { - grub_strcpy ((char *) p, &var->name[sizeof("kFreeBSD.") - 1]); - p += grub_strlen ((char *) p); - *(p++) = '='; - grub_strcpy ((char *) p, var->value); - p += grub_strlen ((char *) p) + 1; - } - - if (p != p0) - { - *(p++) = 0; - - bi.environment = p_target; - } - - if (is_elf_kernel) - { - grub_uint8_t *p_tag = p; - struct bsd_tag *tag; - - for (tag = tags; tag; tag = tag->next) - { - struct freebsd_tag_header *head - = (struct freebsd_tag_header *) p_tag; - head->type = tag->type; - head->len = tag->len; - p_tag += sizeof (struct freebsd_tag_header); - switch (tag->type) - { - case FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_HOWTO: - if (is_64bit) - *(grub_uint64_t *) p_tag = bootflags; - else - *(grub_uint32_t *) p_tag = bootflags; - break; - - case FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_ENVP: - if (is_64bit) - *(grub_uint64_t *) p_tag = bi.environment; - else - *(grub_uint32_t *) p_tag = bi.environment; - break; - - case FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_KERNEND: - if (is_64bit) - *(grub_uint64_t *) p_tag = kern_end; - else - *(grub_uint32_t *) p_tag = kern_end; - break; - - default: - grub_memcpy (p_tag, tag->data, tag->len); - break; - } - p_tag += tag->len; - p_tag = ALIGN_VAR (p_tag - p) + p; - } - - bi.tags = (p - p0) + p_target; - - p = (ALIGN_PAGE ((p_tag - p0) + p_target) - p_target) + p0; - } - - bi.kern_end = kern_end; - - grub_video_set_mode ("text", 0, 0); - - if (is_64bit) - { - struct grub_relocator64_state state = {0}; - grub_uint8_t *pagetable; - grub_uint32_t *stack; - grub_addr_t stack_target; - - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_align (relocator, &ch, - 0x10000, 0x90000, - 3 * sizeof (grub_uint32_t) - + sizeof (bi), 4, - GRUB_RELOCATOR_PREFERENCE_NONE, - 0); - if (err) - return err; - stack = get_virtual_current_address (ch); - stack_target = get_physical_target_address (ch); - } - -#ifdef GRUB_MACHINE_EFI - err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL); - if (err) - return err; -#endif - - pagetable = p; - fill_bsd64_pagetable (pagetable, (pagetable - p0) + p_target); - - state.cr3 = (pagetable - p0) + p_target; - state.rsp = stack_target; - state.rip = (((grub_uint64_t) entry_hi) << 32) | entry; - - stack[0] = entry; - stack[1] = bi.tags; - stack[2] = kern_end; - return grub_relocator64_boot (relocator, state, 0, 0x40000000); - } - else - { - struct grub_relocator32_state state = {0}; - grub_uint32_t *stack; - grub_addr_t stack_target; - - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_align (relocator, &ch, - 0x10000, 0x90000, - 9 * sizeof (grub_uint32_t) - + sizeof (bi), 4, - GRUB_RELOCATOR_PREFERENCE_NONE, - 0); - if (err) - return err; - stack = get_virtual_current_address (ch); - stack_target = get_physical_target_address (ch); - } - -#ifdef GRUB_MACHINE_EFI - err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL); - if (err) - return err; -#endif - - grub_memcpy (&stack[9], &bi, sizeof (bi)); - state.eip = entry; - state.esp = stack_target; - state.ebp = stack_target; - stack[0] = entry; /* "Return" address. */ - stack[1] = bootflags | FREEBSD_RB_BOOTINFO; - stack[2] = freebsd_bootdev; - stack[3] = freebsd_zfsguid ? 4 : 0; - stack[4] = freebsd_zfsguid; - stack[5] = freebsd_zfsguid >> 32; - stack[6] = stack_target + 9 * sizeof (grub_uint32_t); - stack[7] = bi.tags; - stack[8] = kern_end; - return grub_relocator32_boot (relocator, state, 0); - } - - /* Not reached. */ - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_openbsd_boot (void) -{ - grub_uint32_t *stack; - struct grub_relocator32_state state; - void *curarg, *buf0, *arg0; - grub_addr_t buf_target; - grub_err_t err; - grub_size_t tag_buf_len; - - err = grub_bsd_add_mmap (); - if (err) - return err; - -#ifdef GRUB_MACHINE_PCBIOS - { - struct grub_bios_int_registers regs; - - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - - regs.ebx = 0; - regs.ecx = 0; - regs.eax = 0xb101; - regs.es = 0; - regs.edi = 0; - regs.edx = 0; - - grub_bios_interrupt (0x1a, ®s); - if (regs.edx == 0x20494350) - { - struct grub_openbsd_bootarg_pcibios pcibios; - - pcibios.characteristics = regs.eax & 0xff; - pcibios.revision = regs.ebx & 0xffff; - pcibios.pm_entry = regs.edi; - pcibios.last_bus = regs.ecx & 0xff; - - grub_bsd_add_meta (OPENBSD_BOOTARG_PCIBIOS, &pcibios, - sizeof (pcibios)); - } - } -#endif - - { - struct bsd_tag *tag; - tag_buf_len = 0; - for (tag = tags; tag; tag = tag->next) - tag_buf_len = ALIGN_VAR (tag_buf_len - + sizeof (struct grub_openbsd_bootargs) - + tag->len); - } - - buf_target = GRUB_BSD_TEMP_BUFFER - 9 * sizeof (grub_uint32_t); - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, buf_target, - tag_buf_len - + sizeof (struct grub_openbsd_bootargs) - + 9 * sizeof (grub_uint32_t)); - if (err) - return err; - buf0 = get_virtual_current_address (ch); - } - - stack = (grub_uint32_t *) buf0; - arg0 = curarg = stack + 9; - - { - struct bsd_tag *tag; - struct grub_openbsd_bootargs *head; - - for (tag = tags; tag; tag = tag->next) - { - head = curarg; - head->ba_type = tag->type; - head->ba_size = tag->len + sizeof (*head); - curarg = head + 1; - grub_memcpy (curarg, tag->data, tag->len); - curarg = (grub_uint8_t *) curarg + tag->len; - head->ba_next = (grub_uint8_t *) curarg - (grub_uint8_t *) buf0 - + buf_target; - } - head = curarg; - head->ba_type = OPENBSD_BOOTARG_END; - head->ba_size = 0; - head->ba_next = 0; - } - - grub_video_set_mode ("text", 0, 0); - -#ifdef GRUB_MACHINE_EFI - err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL); - if (err) - return err; -#endif - - state.eip = entry; - state.ebp = state.esp - = ((grub_uint8_t *) stack - (grub_uint8_t *) buf0) + buf_target; - stack[0] = entry; - stack[1] = bootflags; - stack[2] = openbsd_root; - stack[3] = OPENBSD_BOOTARG_APIVER; - stack[4] = 0; - stack[5] = grub_mmap_get_upper () >> 10; - stack[6] = grub_mmap_get_lower () >> 10; - stack[7] = (grub_uint8_t *) curarg - (grub_uint8_t *) arg0; - stack[8] = ((grub_uint8_t *) arg0 - (grub_uint8_t *) buf0) + buf_target; - - return grub_relocator32_boot (relocator, state, 0); -} - -static grub_err_t -grub_netbsd_setup_video (void) -{ - struct grub_video_mode_info mode_info; - void *framebuffer; - const char *modevar; - struct grub_netbsd_btinfo_framebuf params = {0}; - grub_err_t err; - grub_video_driver_id_t driv_id; - - 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) - { - char *tmp; - tmp = grub_xasprintf ("%s;" NETBSD_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 (NETBSD_DEFAULT_VIDEO_MODE, 0, 0); - - if (err) - return err; - - 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; - - params.width = mode_info.width; - params.height = mode_info.height; - params.bpp = mode_info.bpp; - params.pitch = mode_info.pitch; - params.flags = 0; - - params.fbaddr = (grub_addr_t) framebuffer; - - 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; - -#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 && driv_id == GRUB_VIDEO_DRIVER_VBE) - { - 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; - } -#endif - - err = grub_bsd_add_meta (NETBSD_BTINFO_FRAMEBUF, ¶ms, sizeof (params)); - return err; -} - -static grub_err_t -grub_netbsd_add_modules (void) -{ - struct netbsd_module *mod; - unsigned modcnt = 0; - struct grub_netbsd_btinfo_modules *mods; - unsigned i; - grub_err_t err; - grub_size_t sz; - - for (mod = netbsd_mods; mod; mod = mod->next) - modcnt++; - - if (grub_mul (modcnt, sizeof (mods->mods[0]), &sz) || - grub_add (sz, sizeof (*mods), &sz)) - return GRUB_ERR_OUT_OF_RANGE; - - mods = grub_malloc (sz); - if (!mods) - return grub_errno; - - mods->num = modcnt; - mods->last_addr = kern_end; - for (mod = netbsd_mods, i = 0; mod; i++, mod = mod->next) - mods->mods[i] = mod->mod; - - err = grub_bsd_add_meta (NETBSD_BTINFO_MODULES, mods, - sizeof (*mods) + sizeof (mods->mods[0]) * modcnt); - grub_free (mods); - return err; -} - -/* - * Adds NetBSD bootinfo bootdisk and bootwedge. The partition identified - * in these bootinfo fields is the root device. - */ -static void -grub_netbsd_add_boot_disk_and_wedge (void) -{ - grub_device_t dev; - grub_disk_t disk; - grub_partition_t part; - grub_uint32_t biosdev; - grub_uint32_t partmapsector; - union { - grub_uint64_t raw[GRUB_DISK_SECTOR_SIZE / 8]; - struct grub_partition_bsd_disk_label label; - } buf; - - if (GRUB_MD_MD5->mdlen > GRUB_CRYPTO_MAX_MDLEN) - { - grub_error (GRUB_ERR_BUG, "mdlen too long"); - return; - } - - dev = grub_device_open (0); - if (! (dev && dev->disk && dev->disk->partition)) - goto fail; - - disk = dev->disk; - part = disk->partition; - - if (disk->dev && disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID) - biosdev = (grub_uint32_t) disk->id & 0xff; - else - biosdev = 0xff; - - /* Absolute sector of the partition map describing this partition. */ - partmapsector = grub_partition_get_start (part->parent) + part->offset; - - disk->partition = part->parent; - if (grub_disk_read (disk, part->offset, 0, GRUB_DISK_SECTOR_SIZE, buf.raw) - != GRUB_ERR_NONE) - goto fail; - disk->partition = part; - - /* Fill bootwedge. */ - { - struct grub_netbsd_btinfo_bootwedge biw; - grub_uint8_t hash[GRUB_CRYPTO_MAX_MDLEN]; - - grub_memset (&biw, 0, sizeof (biw)); - biw.biosdev = biosdev; - biw.startblk = grub_partition_get_start (part); - biw.nblks = part->len; - biw.matchblk = partmapsector; - biw.matchnblks = 1; - - grub_crypto_hash (GRUB_MD_MD5, hash, - buf.raw, GRUB_DISK_SECTOR_SIZE); - grub_memcpy (biw.matchhash, hash, 16); - - grub_bsd_add_meta (NETBSD_BTINFO_BOOTWEDGE, &biw, sizeof (biw)); - } - - /* Fill bootdisk. */ - { - struct grub_netbsd_btinfo_bootdisk bid; - - grub_memset (&bid, 0, sizeof (bid)); - /* Check for a NetBSD disk label. */ - if (part->partmap != NULL && - (grub_strcmp (part->partmap->name, "netbsd") == 0 || - (part->parent == NULL && grub_strcmp (part->partmap->name, "bsd") == 0))) - { - bid.labelsector = partmapsector; - bid.label.type = buf.label.type; - bid.label.checksum = buf.label.checksum; - grub_memcpy (bid.label.packname, buf.label.packname, 16); - } - else - { - bid.labelsector = -1; - } - bid.biosdev = biosdev; - bid.partition = part->number; - - grub_bsd_add_meta (NETBSD_BTINFO_BOOTDISK, &bid, sizeof (bid)); - } - -fail: - if (dev) - grub_device_close (dev); -} - -static grub_err_t -grub_netbsd_boot (void) -{ - struct grub_netbsd_bootinfo *bootinfo; - void *curarg, *arg0; - grub_addr_t arg_target, stack_target; - grub_uint32_t *stack; - grub_err_t err; - struct grub_relocator32_state state; - grub_size_t tag_buf_len = 0; - int tag_count = 0; - - err = grub_bsd_add_mmap (); - if (err) - return err; - - err = grub_netbsd_setup_video (); - if (err) - { - grub_print_error (); - grub_puts_ (N_("Booting in blind mode")); - grub_errno = GRUB_ERR_NONE; - } - - err = grub_netbsd_add_modules (); - if (err) - return err; - -#ifdef GRUB_MACHINE_EFI - err = grub_bsd_add_meta (NETBSD_BTINFO_EFI, - &grub_efi_system_table, - sizeof (grub_efi_system_table)); - if (err) - return err; -#endif - - { - struct bsd_tag *tag; - tag_buf_len = 0; - for (tag = tags; tag; tag = tag->next) - { - tag_buf_len = ALIGN_VAR (tag_buf_len - + sizeof (struct grub_netbsd_btinfo_common) - + tag->len); - tag_count++; - } - } - - arg_target = kern_end; - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, - arg_target, tag_buf_len - + sizeof (struct grub_netbsd_bootinfo) - + tag_count * sizeof (grub_uint32_t)); - if (err) - return err; - curarg = get_virtual_current_address (ch); - } - - arg0 = curarg; - bootinfo = (void *) ((grub_uint8_t *) arg0 + tag_buf_len); - - { - struct bsd_tag *tag; - unsigned i; - - bootinfo->bi_count = tag_count; - for (tag = tags, i = 0; tag; i++, tag = tag->next) - { - struct grub_netbsd_btinfo_common *head = curarg; - bootinfo->bi_data[i] = ((grub_uint8_t *) curarg - (grub_uint8_t *) arg0) - + arg_target; - head->type = tag->type; - head->len = tag->len + sizeof (*head); - curarg = head + 1; - grub_memcpy (curarg, tag->data, tag->len); - curarg = (grub_uint8_t *) curarg + tag->len; - } - } - - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x10000, 0x90000, - 7 * sizeof (grub_uint32_t), 4, - GRUB_RELOCATOR_PREFERENCE_NONE, - 0); - if (err) - return err; - stack = get_virtual_current_address (ch); - stack_target = get_physical_target_address (ch); - } - -#ifdef GRUB_MACHINE_EFI - err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL); - if (err) - return err; -#endif - - state.eip = entry; - state.esp = stack_target; - state.ebp = stack_target; - stack[0] = entry; - stack[1] = bootflags; - stack[2] = 0; - stack[3] = ((grub_uint8_t *) bootinfo - (grub_uint8_t *) arg0) + arg_target; - stack[4] = 0; - stack[5] = grub_mmap_get_upper () >> 10; - stack[6] = grub_mmap_get_lower () >> 10; - - return grub_relocator32_boot (relocator, state, 0); -} - -static grub_err_t -grub_bsd_unload (void) -{ - struct bsd_tag *tag, *next; - for (tag = tags; tag; tag = next) - { - next = tag->next; - grub_free (tag); - } - tags = NULL; - tags_last = NULL; - - kernel_type = KERNEL_TYPE_NONE; - grub_dl_unref (my_mod); - - grub_relocator_unload (relocator); - relocator = NULL; - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_bsd_load_aout (grub_file_t file, const char *filename) -{ - grub_addr_t load_addr, load_end; - int ofs, align_page; - union grub_aout_header ah; - grub_err_t err; - grub_size_t bss_size; - - if ((grub_file_seek (file, 0)) == (grub_off_t) - 1) - return grub_errno; - - if (grub_file_read (file, &ah, sizeof (ah)) != sizeof (ah)) - { - if (!grub_errno) - grub_error (GRUB_ERR_READ_ERROR, N_("premature end of file %s"), - filename); - return grub_errno; - } - - 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; - load_end = 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_size = kern_end - load_end; - } - else - bss_size = 0; - - { - grub_relocator_chunk_t ch; - - err = grub_relocator_alloc_chunk_addr (relocator, &ch, - kern_start, kern_end - kern_start); - if (err) - return err; - kern_chunk_src = get_virtual_current_address (ch); - } - - return grub_aout_load (file, ofs, kern_chunk_src, - ah.aout32.a_text + ah.aout32.a_data, - bss_size); -} - -static grub_err_t -grub_bsd_load_elf (grub_elf_t elf, const char *filename) -{ - grub_err_t err; - grub_size_t sz; - - kern_end = 0; - kern_start = ~0; - - if (grub_elf_is_elf32 (elf)) - { - grub_relocator_chunk_t ch; - Elf32_Phdr *phdr; - - entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFFF; - - FOR_ELF32_PHDRS (elf, phdr) - { - Elf32_Addr paddr; - - if (phdr->p_type != PT_LOAD - && phdr->p_type != PT_DYNAMIC) - continue; - - paddr = phdr->p_paddr & 0xFFFFFFF; - - if (paddr < kern_start) - kern_start = paddr; - - if (paddr + phdr->p_memsz > kern_end) - kern_end = paddr + phdr->p_memsz; - } - - if (grub_errno) - return grub_errno; - - if (grub_sub (kern_end, kern_start, &sz)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "underflow detected while determining size of kernel for relocator"); - - err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_start, sz); - if (err) - return err; - - kern_chunk_src = get_virtual_current_address (ch); - - err = grub_elf32_load (elf, filename, (grub_uint8_t *) kern_chunk_src - kern_start, GRUB_ELF_LOAD_FLAGS_LOAD_PT_DYNAMIC | GRUB_ELF_LOAD_FLAGS_28BITS, 0, 0); - if (err) - return err; - if (kernel_type != KERNEL_TYPE_OPENBSD) - return GRUB_ERR_NONE; - return grub_openbsd_find_ramdisk32 (elf->file, filename, kern_start, - kern_chunk_src, &openbsd_ramdisk); - } - else if (grub_elf_is_elf64 (elf)) - { - Elf64_Phdr *phdr; - - 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; - } - - FOR_ELF64_PHDRS (elf, phdr) - { - Elf64_Addr paddr; - - if (phdr->p_type != PT_LOAD - && phdr->p_type != PT_DYNAMIC) - continue; - - paddr = phdr->p_paddr & 0xFFFFFFF; - - if (paddr < kern_start) - kern_start = paddr; - - if (paddr + phdr->p_memsz > kern_end) - kern_end = paddr + phdr->p_memsz; - } - - if (grub_errno) - return grub_errno; - - grub_dprintf ("bsd", "kern_start = %lx, kern_end = %lx\n", - (unsigned long) kern_start, (unsigned long) kern_end); - { - grub_relocator_chunk_t ch; - - if (grub_sub (kern_end, kern_start, &sz)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "underflow detected while determining size of kernel for relocator"); - - err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_start, sz); - if (err) - return err; - kern_chunk_src = get_virtual_current_address (ch); - } - - err = grub_elf64_load (elf, filename, - (grub_uint8_t *) kern_chunk_src - kern_start, GRUB_ELF_LOAD_FLAGS_LOAD_PT_DYNAMIC | GRUB_ELF_LOAD_FLAGS_28BITS, 0, 0); - if (err) - return err; - if (kernel_type != KERNEL_TYPE_OPENBSD) - return GRUB_ERR_NONE; - return grub_openbsd_find_ramdisk64 (elf->file, filename, kern_start, - kern_chunk_src, &openbsd_ramdisk); - } - else - return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); -} - -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 (); - - grub_memset (&openbsd_ramdisk, 0, sizeof (openbsd_ramdisk)); - - if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_BSD_KERNEL); - if (!file) - goto fail; - - relocator = grub_relocator_new (); - if (!relocator) - { - grub_file_close (file); - goto fail; - } - - elf = grub_elf_file (file, argv[0]); - if (elf) - { - is_elf_kernel = 1; - grub_bsd_load_elf (elf, argv[0]); - grub_elf_close (elf); - } - else - { - is_elf_kernel = 0; - grub_errno = 0; - grub_bsd_load_aout (file, argv[0]); - grub_file_close (file); - } - - kern_end = ALIGN_PAGE (kern_end); - -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_context_t ctxt, int argc, char *argv[]) -{ - kernel_type = KERNEL_TYPE_FREEBSD; - bootflags = grub_bsd_parse_flags (ctxt->state, freebsd_flags); - - if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE) - { - grub_uint32_t unit, slice, part; - - 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], FREEBSD_MODTYPE_KERNEL, - argc - 1, argv + 1, - kern_start, - kern_end - kern_start); - if (err) - return err; - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_BSD_KERNEL); - if (! file) - return grub_errno; - - if (is_64bit) - err = grub_freebsd_load_elf_meta64 (relocator, file, argv[0], - &kern_end); - else - err = grub_freebsd_load_elf_meta32 (relocator, file, argv[0], - &kern_end); - if (err) - return err; - - err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA | - FREEBSD_MODINFOMD_HOWTO, &data, 4); - if (err) - return err; - - err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA | - FREEBSD_MODINFOMD_ENVP, &data, len); - if (err) - return err; - - err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA | - FREEBSD_MODINFOMD_KERNEND, &data, len); - if (err) - return err; - } - grub_bsd_get_device (&freebsd_biosdev, &unit, &slice, &part); - freebsd_zfsguid = 0; - if (!is_64bit) - freebsd_get_zfs (); - grub_print_error (); - freebsd_bootdev = (FREEBSD_B_DEVMAGIC + ((slice + 1) << FREEBSD_B_SLICESHIFT) + - (unit << FREEBSD_B_UNITSHIFT) + (part << FREEBSD_B_PARTSHIFT)); - - grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 0); - } - - return grub_errno; -} - -static const char *types[] = { - [0] = "wd", - [2] = "fd", - [4] = "sd", - [6] = "cd", - [14] = "vnd", - [17] = "rd" -}; - -static grub_err_t -grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) -{ - grub_uint32_t bootdev; - - kernel_type = KERNEL_TYPE_OPENBSD; - bootflags = grub_bsd_parse_flags (ctxt->state, openbsd_flags); - - if (ctxt->state[OPENBSD_ROOT_ARG].set && ctxt->state[OPENBSD_ROOT_ARG].arg != NULL) - { - const char *arg = ctxt->state[OPENBSD_ROOT_ARG].arg; - unsigned type, unit, part; - for (type = 0; type < ARRAY_SIZE (types); type++) - if (types[type] - && grub_strncmp (arg, types[type], - grub_strlen (types[type])) == 0) - { - arg += grub_strlen (types[type]); - break; - } - if (type == ARRAY_SIZE (types)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "unknown disk type name"); - - unit = grub_strtoul (arg, &arg, 10); - if (! (*arg >= 'a' && *arg <= 'z')) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "only device specifications of form " - " are supported"); - - part = *arg - 'a'; - - bootdev = (OPENBSD_B_DEVMAGIC | (type << OPENBSD_B_TYPESHIFT) - | (unit << OPENBSD_B_UNITSHIFT) - | (part << OPENBSD_B_PARTSHIFT)); - } - else - bootdev = 0; - - if (ctxt->state[OPENBSD_SERIAL_ARG].set) - { - struct grub_openbsd_bootarg_console serial; - const char *ptr; - unsigned port = 0; - unsigned speed = 9600; - - grub_memset (&serial, 0, sizeof (serial)); - - if (ctxt->state[OPENBSD_SERIAL_ARG].arg) - { - ptr = ctxt->state[OPENBSD_SERIAL_ARG].arg; - if (grub_memcmp (ptr, "com", sizeof ("com") - 1) != 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "only com0-com3 are supported"); - ptr += sizeof ("com") - 1; - port = grub_strtoul (ptr, &ptr, 0); - if (port >= 4) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "only com0-com3 are supported"); - if (*ptr == ',') - { - ptr++; - speed = grub_strtoul (ptr, &ptr, 0); - if (grub_errno) - return grub_errno; - } - } - - serial.device = (GRUB_OPENBSD_COM_MAJOR << 8) | port; - serial.speed = speed; - serial.addr = grub_ns8250_hw_get_port (port); - - grub_bsd_add_meta (OPENBSD_BOOTARG_CONSOLE, &serial, sizeof (serial)); - bootflags |= OPENBSD_RB_SERCONS; - } - else - { - struct grub_openbsd_bootarg_console serial; - - grub_memset (&serial, 0, sizeof (serial)); - serial.device = (GRUB_OPENBSD_VGA_MAJOR << 8); - serial.addr = 0xffffffff; - grub_bsd_add_meta (OPENBSD_BOOTARG_CONSOLE, &serial, sizeof (serial)); - bootflags &= ~OPENBSD_RB_SERCONS; - } - - if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE) - { - grub_loader_set (grub_openbsd_boot, grub_bsd_unload, 0); - openbsd_root = bootdev; - } - - return grub_errno; -} - -static grub_err_t -grub_cmd_netbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) -{ - grub_err_t err; - kernel_type = KERNEL_TYPE_NETBSD; - bootflags = grub_bsd_parse_flags (ctxt->state, netbsd_flags); - - if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE) - { - if (is_elf_kernel) - { - grub_file_t file; - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_BSD_KERNEL); - if (! file) - return grub_errno; - - if (is_64bit) - err = grub_netbsd_load_elf_meta64 (relocator, file, argv[0], &kern_end); - else - err = grub_netbsd_load_elf_meta32 (relocator, file, argv[0], &kern_end); - if (err) - return err; - } - - { - char bootpath[GRUB_NETBSD_MAX_BOOTPATH_LEN]; - char *name; - name = grub_strrchr (argv[0], '/'); - if (name) - name++; - else - name = argv[0]; - grub_memset (bootpath, 0, sizeof (bootpath)); - grub_strncpy (bootpath, name, sizeof (bootpath) - 1); - grub_bsd_add_meta (NETBSD_BTINFO_BOOTPATH, bootpath, sizeof (bootpath)); - } - - if (ctxt->state[NETBSD_ROOT_ARG].set) - { - char root[GRUB_NETBSD_MAX_ROOTDEVICE_LEN]; - grub_memset (root, 0, sizeof (root)); - grub_strncpy (root, ctxt->state[NETBSD_ROOT_ARG].arg, - sizeof (root) - 1); - grub_bsd_add_meta (NETBSD_BTINFO_ROOTDEVICE, root, sizeof (root)); - } - if (ctxt->state[NETBSD_SERIAL_ARG].set) - { - struct grub_netbsd_btinfo_serial serial; - const char *ptr; - - grub_memset (&serial, 0, sizeof (serial)); - grub_strcpy (serial.devname, "com"); - - serial.addr = grub_ns8250_hw_get_port (0); - serial.speed = 9600; - - if (ctxt->state[NETBSD_SERIAL_ARG].arg) - { - ptr = ctxt->state[NETBSD_SERIAL_ARG].arg; - if (grub_memcmp (ptr, "com", sizeof ("com") - 1) == 0) - { - ptr += sizeof ("com") - 1; - serial.addr - = grub_ns8250_hw_get_port (grub_strtoul (ptr, &ptr, 0)); - } - else - serial.addr = grub_strtoul (ptr, &ptr, 0); - if (grub_errno) - return grub_errno; - - if (*ptr == ',') - { - ptr++; - serial.speed = grub_strtoul (ptr, &ptr, 0); - if (grub_errno) - return grub_errno; - } - } - - grub_bsd_add_meta (NETBSD_BTINFO_CONSOLE, &serial, sizeof (serial)); - } - else - { - struct grub_netbsd_btinfo_serial cons; - - grub_memset (&cons, 0, sizeof (cons)); - grub_strcpy (cons.devname, "pc"); - - grub_bsd_add_meta (NETBSD_BTINFO_CONSOLE, &cons, sizeof (cons)); - } - - grub_netbsd_add_boot_disk_and_wedge (); - - grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 0); - } - - 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 (! grub_loader_is_loaded ()) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("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, N_("filename expected")); - goto fail; - } - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_FREEBSD_ENV); - 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; - int modargc; - char **modargv; - const char *type; - grub_err_t err; - void *src; - - if (! grub_loader_is_loaded ()) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("you need to load the kernel first")); - - if (kernel_type != KERNEL_TYPE_FREEBSD) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no FreeBSD loaded"); - - 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_file_open (argv[0], GRUB_FILE_TYPE_FREEBSD_MODULE); - if ((!file) || (!file->size)) - goto fail; - - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end, - file->size); - if (err) - goto fail; - src = get_virtual_current_address (ch); - } - - - grub_file_read (file, src, 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_netbsd_module_load (char *filename, grub_uint32_t type) -{ - grub_file_t file = 0; - void *src; - grub_err_t err; - - file = grub_file_open (filename, GRUB_FILE_TYPE_NETBSD_MODULE); - if ((!file) || (!file->size)) - goto fail; - - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end, - file->size); - if (err) - goto fail; - - src = get_virtual_current_address (ch); - } - - grub_file_read (file, src, file->size); - if (grub_errno) - goto fail; - - err = grub_netbsd_add_meta_module (filename, type, 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_netbsd_module (grub_command_t cmd, - int argc, char *argv[]) -{ - grub_uint32_t type; - - if (! grub_loader_is_loaded ()) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("you need to load the kernel first")); - - if (kernel_type != KERNEL_TYPE_NETBSD) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no NetBSD loaded"); - - 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_netbsd_list_modules (); - return 0; - } - - if (grub_strcmp (cmd->name, "knetbsd_module_elf") == 0) - type = GRUB_NETBSD_MODULE_ELF; - else - type = GRUB_NETBSD_MODULE_RAW; - - return grub_netbsd_module_load (argv[0], type); -} - -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 (! grub_loader_is_loaded ()) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("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_file_open (argv[0], GRUB_FILE_TYPE_FREEBSD_MODULE_ELF); - if (!file) - return grub_errno; - if (!file->size) - { - grub_file_close (file); - return grub_errno; - } - - if (is_64bit) - err = grub_freebsd_load_elfmodule_obj64 (relocator, file, - argc, argv, &kern_end); - else - err = grub_freebsd_load_elfmodule32 (relocator, file, - argc, argv, &kern_end); - grub_file_close (file); - - return err; -} - -static grub_err_t -grub_cmd_openbsd_ramdisk (grub_command_t cmd __attribute__ ((unused)), - int argc, char *args[]) -{ - grub_file_t file; - grub_size_t size; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - if (! grub_loader_is_loaded ()) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("you need to load the kernel first")); - - if (kernel_type != KERNEL_TYPE_OPENBSD) - return grub_error (GRUB_ERR_BAD_OS, "no kOpenBSD loaded"); - - if (!openbsd_ramdisk.max_size) - return grub_error (GRUB_ERR_BAD_OS, "your kOpenBSD doesn't support ramdisk"); - - file = grub_file_open (args[0], GRUB_FILE_TYPE_OPENBSD_RAMDISK); - if (! file) - return grub_errno; - - size = grub_file_size (file); - - if (size > openbsd_ramdisk.max_size) - { - grub_file_close (file); - return grub_error (GRUB_ERR_BAD_OS, "your kOpenBSD supports ramdisk only" - " up to %" PRIuGRUB_SIZE " bytes, however you supplied" - " a %" PRIuGRUB_SIZE " bytes one", - openbsd_ramdisk.max_size, size); - } - - if (grub_file_read (file, openbsd_ramdisk.target, size) - != (grub_ssize_t) (size)) - { - grub_file_close (file); - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), args[0]); - return grub_errno; - } - grub_memset (openbsd_ramdisk.target + size, 0, - openbsd_ramdisk.max_size - size); - *openbsd_ramdisk.size = ALIGN_UP (size, 512); - - return GRUB_ERR_NONE; -} - -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_netbsd_module, cmd_freebsd_module_elf; -static grub_command_t cmd_netbsd_module_elf, cmd_openbsd_ramdisk; - -GRUB_MOD_INIT (bsd) -{ - /* Net and OpenBSD kernels are often compressed. */ - grub_dl_load ("gzio"); - - cmd_freebsd = grub_register_extcmd ("kfreebsd", grub_cmd_freebsd, 0, - N_("FILE"), N_("Load kernel of FreeBSD."), - freebsd_opts); - cmd_openbsd = grub_register_extcmd ("kopenbsd", grub_cmd_openbsd, 0, - N_("FILE"), N_("Load kernel of OpenBSD."), - openbsd_opts); - cmd_netbsd = grub_register_extcmd ("knetbsd", grub_cmd_netbsd, 0, - 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_netbsd_module = - grub_register_command ("knetbsd_module", grub_cmd_netbsd_module, - 0, N_("Load NetBSD kernel module.")); - cmd_netbsd_module_elf = - grub_register_command ("knetbsd_module_elf", grub_cmd_netbsd_module, - 0, N_("Load NetBSD kernel module (ELF).")); - cmd_freebsd_module_elf = - grub_register_command ("kfreebsd_module_elf", grub_cmd_freebsd_module_elf, - 0, N_("Load FreeBSD kernel module (ELF).")); - - cmd_openbsd_ramdisk = grub_register_command ("kopenbsd_ramdisk", - grub_cmd_openbsd_ramdisk, 0, - /* TRANSLATORS: ramdisk isn't identifier, - it can be translated. */ - N_("Load kOpenBSD ramdisk.")); - - 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_netbsd_module); - grub_unregister_command (cmd_freebsd_module_elf); - grub_unregister_command (cmd_netbsd_module_elf); - grub_unregister_command (cmd_openbsd_ramdisk); - - grub_bsd_unload (); -} diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c deleted file mode 100644 index d3de8a29b..000000000 --- a/grub-core/loader/i386/bsdXX.c +++ /dev/null @@ -1,711 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#define ALIGN_PAGE(a) ALIGN_UP (a, 4096) - -static inline grub_err_t -load (grub_file_t file, const char *filename, void *where, grub_off_t off, grub_size_t size) -{ - 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; - return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - } - return GRUB_ERR_NONE; -} - -static inline grub_err_t -read_headers (grub_file_t file, const char *filename, Elf_Ehdr *e, Elf_Shdr **shdr) -{ - Elf_Shnum shnum; - grub_err_t err; - - 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; - return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - } - - 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, N_("invalid arch-independent ELF magic")); - - if (e->e_ident[EI_CLASS] != SUFFIX (ELFCLASS)) - return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); - - err = grub_elf_get_shnum (e, &shnum); - if (err != GRUB_ERR_NONE) - return err; - - *shdr = grub_calloc (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, shnum * e->e_shentsize) - != ((grub_ssize_t) shnum * e->e_shentsize)) - { - if (grub_errno) - return grub_errno; - return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - } - - 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) (struct grub_relocator *relocator, - grub_file_t file, int argc, - char *argv[], grub_addr_t *kern_end) -{ - Elf_Ehdr e; - Elf_Shdr *s, *shdr = NULL; - Elf_Shnum shnum; - grub_addr_t curload, module; - grub_err_t err; - void *chunk_src; - - module = ALIGN_PAGE (*kern_end); - - err = read_headers (file, argv[0], &e, &shdr); - if (err != GRUB_ERR_NONE) - goto out; - - err = grub_elf_get_shnum (&e, &shnum); - if (err != GRUB_ERR_NONE) - goto out; - - curload = module; - - for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * e.e_shentsize); - s = (Elf_Shdr *) ((grub_uint8_t *) s + e.e_shentsize)) - { - if (s->sh_size == 0) - continue; - - if (s->sh_addralign) - curload = ALIGN_UP (curload, s->sh_addralign); - - curload += s->sh_size; - } - - *kern_end = ALIGN_PAGE (curload); - - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, - module, curload - module); - if (err != GRUB_ERR_NONE) - goto out; - chunk_src = get_virtual_current_address (ch); - } - - curload = module; - - for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * e.e_shentsize); - s = (Elf_Shdr *) ((grub_uint8_t *) 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, argv[0], (grub_uint8_t *) chunk_src + curload - module, - s->sh_offset, s->sh_size); - if (err != GRUB_ERR_NONE) - goto out; - break; - case SHT_NOBITS: - grub_memset ((grub_uint8_t *) chunk_src + curload - module, 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 == GRUB_ERR_NONE) - err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA - | FREEBSD_MODINFOMD_ELFHDR, - &e, sizeof (e)); - if (err == GRUB_ERR_NONE) - err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA - | FREEBSD_MODINFOMD_SHDR, - shdr, shnum * e.e_shentsize); - -out: - grub_free (shdr); - return err; -} - -#else - -grub_err_t -SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator, - grub_file_t file, int argc, char *argv[], - grub_addr_t *kern_end) -{ - Elf_Ehdr e; - Elf_Shdr *s, *shdr = NULL; - Elf_Shnum shnum; - Elf_Word phnum; - grub_addr_t curload, module; - grub_err_t err; - grub_size_t chunk_size = 0; - void *chunk_src; - - curload = module = ALIGN_PAGE (*kern_end); - - err = read_headers (file, argv[0], &e, &shdr); - if (err != GRUB_ERR_NONE) - goto out; - - err = grub_elf_get_shnum (&e, &shnum); - if (err != GRUB_ERR_NONE) - goto out; - - err = grub_elf_get_phnum (&e, &phnum); - if (err != GRUB_ERR_NONE) - goto out; - - for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * e.e_shentsize); - s = (Elf_Shdr *) ((grub_uint8_t *) s + e.e_shentsize)) - { - if (s->sh_size == 0) - continue; - - if (! (s->sh_flags & SHF_ALLOC)) - continue; - if (chunk_size < s->sh_addr + s->sh_size) - chunk_size = s->sh_addr + s->sh_size; - } - - if (chunk_size < sizeof (e)) - chunk_size = sizeof (e); - chunk_size += (grub_size_t) phnum * e.e_phentsize; - chunk_size += (grub_size_t) shnum * e.e_shentsize; - - { - grub_relocator_chunk_t ch; - - err = grub_relocator_alloc_chunk_addr (relocator, &ch, - module, chunk_size); - if (err != GRUB_ERR_NONE) - goto out; - - chunk_src = get_virtual_current_address (ch); - } - - for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * e.e_shentsize); - s = (Elf_Shdr *) ((grub_uint8_t *) 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, argv[0], - (grub_uint8_t *) chunk_src + module - + s->sh_addr - *kern_end, - s->sh_offset, s->sh_size); - if (err != GRUB_ERR_NONE) - goto out; - break; - case SHT_NOBITS: - grub_memset ((grub_uint8_t *) chunk_src + module - + s->sh_addr - *kern_end, 0, s->sh_size); - break; - } - if (curload < module + s->sh_addr + s->sh_size) - curload = module + s->sh_addr + s->sh_size; - } - - load (file, argv[0], (grub_uint8_t *) chunk_src + module - *kern_end, 0, sizeof (e)); - if (curload < module + sizeof (e)) - curload = module + sizeof (e); - - load (file, argv[0], (grub_uint8_t *) chunk_src + curload - *kern_end, e.e_shoff, - (grub_size_t) shnum * e.e_shentsize); - e.e_shoff = curload - module; - curload += (grub_addr_t) shnum * e.e_shentsize; - - load (file, argv[0], (grub_uint8_t *) chunk_src + curload - *kern_end, e.e_phoff, - (grub_size_t) phnum * e.e_phentsize); - e.e_phoff = curload - module; - curload += (grub_addr_t) 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); -out: - grub_free (shdr); - if (err != GRUB_ERR_NONE) - return err; - return SUFFIX (grub_freebsd_load_elf_meta) (relocator, file, argv[0], kern_end); -} - -#endif - -grub_err_t -SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator, - grub_file_t file, - const char *filename, - grub_addr_t *kern_end) -{ - grub_err_t err; - Elf_Ehdr e; - Elf_Shdr *s, *shdr = NULL; - Elf_Shnum shnum; - unsigned symoff, stroff, symsize, strsize; - grub_freebsd_addr_t symstart, symend, symentsize, dynamic; - Elf_Sym *sym; - void *sym_chunk; - grub_uint8_t *curload; - grub_freebsd_addr_t symtarget; - const char *str; - unsigned i; - grub_size_t chunk_size; - - err = read_headers (file, filename, &e, &shdr); - if (err != GRUB_ERR_NONE) - goto out; - - err = grub_elf_get_shnum (&e, &shnum); - if (err != GRUB_ERR_NONE) - goto out; - - err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA | - FREEBSD_MODINFOMD_ELFHDR, &e, - sizeof (e)); - if (err != GRUB_ERR_NONE) - goto out; - - for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * e.e_shentsize); - s = (Elf_Shdr *) ((grub_uint8_t *) s + e.e_shentsize)) - if (s->sh_type == SHT_SYMTAB) - break; - if (s >= (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * e.e_shentsize)) - { - err = grub_error (GRUB_ERR_BAD_OS, N_("no symbol table")); - goto out; - } - symoff = s->sh_offset; - symsize = s->sh_size; - symentsize = s->sh_entsize; - s = (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shentsize * s->sh_link); - stroff = s->sh_offset; - strsize = s->sh_size; - - chunk_size = ALIGN_UP (symsize + strsize, sizeof (grub_freebsd_addr_t)) - + 2 * sizeof (grub_freebsd_addr_t); - - symtarget = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t)); - - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, - symtarget, chunk_size); - if (err != GRUB_ERR_NONE) - goto out; - sym_chunk = get_virtual_current_address (ch); - } - - symstart = symtarget; - symend = symstart + chunk_size; - - curload = sym_chunk; - *((grub_freebsd_addr_t *) curload) = symsize; - curload += sizeof (grub_freebsd_addr_t); - - if (grub_file_seek (file, symoff) == (grub_off_t) -1) - { - err = grub_errno; - goto out; - } - sym = (Elf_Sym *) curload; - if (grub_file_read (file, curload, symsize) != (grub_ssize_t) symsize) - { - if (! grub_errno) - err = grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - else - err = grub_errno; - goto out; - } - curload += symsize; - - *((grub_freebsd_addr_t *) curload) = strsize; - curload += sizeof (grub_freebsd_addr_t); - if (grub_file_seek (file, stroff) == (grub_off_t) -1) - { - err = grub_errno; - goto out; - } - str = (char *) curload; - if (grub_file_read (file, curload, strsize) != (grub_ssize_t) strsize) - { - if (! grub_errno) - err = grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - else - err = grub_errno; - goto out; - } - - 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_bsd_add_meta (FREEBSD_MODINFO_METADATA | - FREEBSD_MODINFOMD_DYNAMIC, &dynamic, - sizeof (dynamic)); - if (err != GRUB_ERR_NONE) - goto out; - } - - err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA | - FREEBSD_MODINFOMD_SSYM, &symstart, - sizeof (symstart)); - if (err != GRUB_ERR_NONE) - goto out; - - err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA | - FREEBSD_MODINFOMD_ESYM, &symend, - sizeof (symend)); -out: - grub_free (shdr); - if (err != GRUB_ERR_NONE) - return err; - - *kern_end = ALIGN_PAGE (symend); - - return GRUB_ERR_NONE; -} - -grub_err_t -SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator, - grub_file_t file, const char *filename, - grub_addr_t *kern_end) -{ - grub_err_t err; - Elf_Ehdr e; - Elf_Shdr *s, *symsh, *strsh, *shdr = NULL; - Elf_Shnum shnum; - unsigned symsize, strsize; - void *sym_chunk; - grub_uint8_t *curload; - grub_size_t chunk_size; - Elf_Ehdr *e2; - struct grub_netbsd_btinfo_symtab symtab; - grub_addr_t symtarget; - - err = read_headers (file, filename, &e, &shdr); - if (err != GRUB_ERR_NONE) - { - grub_free (shdr); - return grub_errno; - } - - err = grub_elf_get_shnum (&e, &shnum); - if (err != GRUB_ERR_NONE) - { - grub_free (shdr); - return err; - } - - for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * e.e_shentsize); - s = (Elf_Shdr *) ((grub_uint8_t *) s + e.e_shentsize)) - if (s->sh_type == SHT_SYMTAB) - break; - if (s >= (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * e.e_shentsize)) - { - grub_free (shdr); - return GRUB_ERR_NONE; - } - symsize = s->sh_size; - symsh = s; - s = (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shentsize * s->sh_link); - strsize = s->sh_size; - strsh = s; - - chunk_size = ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t)) - + ALIGN_UP (strsize, sizeof (grub_freebsd_addr_t)) - + sizeof (e) + shnum * e.e_shentsize; - - symtarget = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t)); - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, - symtarget, chunk_size); - if (err != GRUB_ERR_NONE) - goto out; - sym_chunk = get_virtual_current_address (ch); - } - - symtab.nsyms = 1; - symtab.ssyms = symtarget; - symtab.esyms = symtarget + chunk_size; - - curload = sym_chunk; - - e2 = (Elf_Ehdr *) curload; - grub_memcpy (curload, &e, sizeof (e)); - e2->e_phoff = 0; - e2->e_phnum = 0; - e2->e_phentsize = 0; - e2->e_shstrndx = 0; - e2->e_shoff = sizeof (e); - - curload += sizeof (e); - - for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * e.e_shentsize); - s = (Elf_Shdr *) ((grub_uint8_t *) s + e.e_shentsize)) - { - Elf_Shdr *s2; - s2 = (Elf_Shdr *) curload; - grub_memcpy (curload, s, e.e_shentsize); - if (s == symsh) - s2->sh_offset = sizeof (e) + shnum * e.e_shentsize; - else if (s == strsh) - s2->sh_offset = ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t)) - + sizeof (e) + shnum * e.e_shentsize; - else - s2->sh_offset = 0; - s2->sh_addr = s2->sh_offset; - curload += e.e_shentsize; - } - - if (grub_file_seek (file, symsh->sh_offset) == (grub_off_t) -1) - { - err = grub_errno; - goto out; - } - if (grub_file_read (file, curload, symsize) != (grub_ssize_t) symsize) - { - if (! grub_errno) - err = grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - else - err = grub_errno; - goto out; - } - curload += ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t)); - - if (grub_file_seek (file, strsh->sh_offset) == (grub_off_t) -1) - { - err = grub_errno; - goto out; - } - if (grub_file_read (file, curload, strsize) != (grub_ssize_t) strsize) - { - if (! grub_errno) - err = grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - else - err = grub_errno; - goto out; - } - - err = grub_bsd_add_meta (NETBSD_BTINFO_SYMTAB, - &symtab, - sizeof (symtab)); -out: - grub_free (shdr); - if (err != GRUB_ERR_NONE) - return err; - - *kern_end = ALIGN_PAGE (symtarget + chunk_size); - - return GRUB_ERR_NONE; -} - -grub_err_t -SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file, - const char *filename, - grub_addr_t kern_start, - void *kern_chunk_src, - struct grub_openbsd_ramdisk_descriptor *desc) -{ - unsigned symoff, stroff, symsize, strsize, symentsize; - - { - grub_err_t err; - Elf_Ehdr e; - Elf_Shdr *s, *shdr = NULL; - Elf_Shnum shnum; - - err = read_headers (file, filename, &e, &shdr); - if (err != GRUB_ERR_NONE) - { - grub_free (shdr); - return err; - } - - err = grub_elf_get_shnum (&e, &shnum); - if (err != GRUB_ERR_NONE) - { - grub_free (shdr); - return err; - } - - for (s = shdr; s < (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * e.e_shentsize); - s = (Elf_Shdr *) ((grub_uint8_t *) s + e.e_shentsize)) - if (s->sh_type == SHT_SYMTAB) - break; - if (s >= (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * e.e_shentsize)) - { - grub_free (shdr); - return GRUB_ERR_NONE; - } - - symsize = s->sh_size; - symentsize = s->sh_entsize; - symoff = s->sh_offset; - - s = (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shentsize * s->sh_link); - stroff = s->sh_offset; - strsize = s->sh_size; - grub_free (shdr); - } - { - Elf_Sym *syms, *sym, *imagesym = NULL, *sizesym = NULL; - unsigned i; - char *strs; - - syms = grub_malloc (symsize); - if (!syms) - return grub_errno; - - if (grub_file_seek (file, symoff) == (grub_off_t) -1) - { - grub_free (syms); - return grub_errno; - } - if (grub_file_read (file, syms, symsize) != (grub_ssize_t) symsize) - { - grub_free (syms); - if (! grub_errno) - return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - return grub_errno; - } - - strs = grub_malloc (strsize); - if (!strs) - { - grub_free (syms); - return grub_errno; - } - - if (grub_file_seek (file, stroff) == (grub_off_t) -1) - { - grub_free (syms); - grub_free (strs); - return grub_errno; - } - if (grub_file_read (file, strs, strsize) != (grub_ssize_t) strsize) - { - grub_free (syms); - grub_free (strs); - if (! grub_errno) - return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - return grub_errno; - } - - for (i = 0, sym = syms; i * symentsize < symsize; - i++, sym = (Elf_Sym *) ((char *) sym + symentsize)) - { - if (ELF_ST_TYPE (sym->st_info) != STT_OBJECT) - continue; - if (!sym->st_name) - continue; - if (grub_strcmp (strs + sym->st_name, "rd_root_image") == 0) - imagesym = sym; - if (grub_strcmp (strs + sym->st_name, "rd_root_size") == 0) - sizesym = sym; - if (imagesym && sizesym) - break; - } - if (!imagesym || !sizesym) - { - grub_free (syms); - grub_free (strs); - return GRUB_ERR_NONE; - } - if (sizeof (*desc->size) != sizesym->st_size) - { - grub_free (syms); - grub_free (strs); - return grub_error (GRUB_ERR_BAD_OS, "unexpected size of rd_root_size"); - } - desc->max_size = imagesym->st_size; - desc->target = (imagesym->st_value & 0xFFFFFF) - kern_start - + (grub_uint8_t *) kern_chunk_src; - desc->size = (grub_uint32_t *) ((sizesym->st_value & 0xFFFFFF) - kern_start - + (grub_uint8_t *) kern_chunk_src); - grub_free (syms); - grub_free (strs); - - return GRUB_ERR_NONE; - } -} diff --git a/grub-core/loader/i386/coreboot/chainloader.c b/grub-core/loader/i386/coreboot/chainloader.c deleted file mode 100644 index 4a5179806..000000000 --- a/grub-core/loader/i386/coreboot/chainloader.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_addr_t entry; -static struct grub_relocator *relocator = NULL; - -static grub_err_t -grub_chain_boot (void) -{ - struct grub_relocator32_state state; - - grub_video_set_mode ("text", 0, 0); - - state.eip = entry; - return grub_relocator32_boot (relocator, state, 0); -} - -static grub_err_t -grub_chain_unload (void) -{ - grub_relocator_unload (relocator); - relocator = NULL; - - return GRUB_ERR_NONE; -} - -static grub_err_t -load_elf (grub_file_t file, const char *filename) -{ - grub_elf_t elf; - Elf32_Phdr *phdr; - grub_err_t err; - - elf = grub_elf_file (file, filename); - if (!elf) - return grub_errno; - - if (!grub_elf_is_elf32 (elf)) - return grub_error (GRUB_ERR_BAD_OS, "only ELF32 can be coreboot payload"); - - entry = elf->ehdr.ehdr32.e_entry; - - FOR_ELF32_PHDRS(elf, phdr) - { - grub_uint8_t *load_addr; - grub_relocator_chunk_t ch; - - if (phdr->p_type != PT_LOAD) - continue; - - err = grub_relocator_alloc_chunk_addr (relocator, &ch, - phdr->p_paddr, phdr->p_memsz); - if (err) - { - elf->file = 0; - grub_elf_close (elf); - return err; - } - - load_addr = get_virtual_current_address (ch); - - if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1) - { - elf->file = 0; - grub_elf_close (elf); - return grub_errno; - } - - if (phdr->p_filesz) - { - grub_ssize_t read; - read = grub_file_read (elf->file, load_addr, phdr->p_filesz); - if (read != (grub_ssize_t) phdr->p_filesz) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, - N_("premature end of file %s"), - filename); - elf->file = 0; - grub_elf_close (elf); - return grub_errno; - } - } - - if (phdr->p_filesz < phdr->p_memsz) - grub_memset ((load_addr + phdr->p_filesz), - 0, phdr->p_memsz - phdr->p_filesz); - } - - elf->file = 0; - grub_elf_close (elf); - return GRUB_ERR_NONE; -} - -static void *SzAlloc(void *p __attribute__ ((unused)), size_t size) { return grub_malloc (size); } -static void SzFree(void *p __attribute__ ((unused)), void *address) { grub_free (address); } -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; - - -static grub_err_t -load_segment (grub_file_t file, const char *filename, - void *load_addr, grub_uint32_t comp, - grub_size_t *size, grub_size_t max_size) -{ - switch (comp) - { - case grub_cpu_to_be32_compile_time (CBFS_COMPRESS_NONE): - if (grub_file_read (file, load_addr, *size) - != (grub_ssize_t) *size) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, - N_("premature end of file %s"), - filename); - return grub_errno; - } - return GRUB_ERR_NONE; - case grub_cpu_to_be32_compile_time (CBFS_COMPRESS_LZMA): - { - grub_uint8_t *buf; - grub_size_t outsize, insize; - SRes res; - SizeT src_len, dst_len; - ELzmaStatus status; - if (*size < 13) - return grub_error (GRUB_ERR_BAD_OS, "invalid compressed chunk"); - buf = grub_malloc (*size); - if (!buf) - return grub_errno; - if (grub_file_read (file, buf, *size) - != (grub_ssize_t) *size) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, - N_("premature end of file %s"), - filename); - grub_free (buf); - return grub_errno; - } - outsize = grub_get_unaligned64 (buf + 5); - if (outsize > max_size) - { - grub_free (buf); - return grub_error (GRUB_ERR_BAD_OS, "invalid compressed chunk"); - } - insize = *size - 13; - - src_len = insize; - dst_len = outsize; - res = LzmaDecode (load_addr, &dst_len, buf + 13, &src_len, - buf, 5, LZMA_FINISH_END, &status, &g_Alloc); - /* ELzmaFinishMode finishMode, - ELzmaStatus *status, ISzAlloc *alloc)*/ - grub_free (buf); - grub_dprintf ("chain", "%x, %x, %x, %x\n", - insize, src_len, outsize, dst_len); - if (res != SZ_OK - || src_len != insize || dst_len != outsize) - return grub_error (GRUB_ERR_BAD_OS, "decompression failure %d", res); - *size = outsize; - } - return GRUB_ERR_NONE; - default: - return grub_error (GRUB_ERR_BAD_OS, "unsupported compression %d", - grub_be_to_cpu32 (comp)); - } -} - -static grub_err_t -load_tianocore (grub_file_t file) -{ - grub_uint16_t header_length; - grub_uint32_t section_head; - grub_uint8_t mz[2], pe[4]; - struct grub_pe32_coff_header coff_head; - struct file_header - { - grub_uint8_t unused[18]; - grub_uint8_t type; - grub_uint8_t unused2; - grub_uint8_t size[3]; - grub_uint8_t unused3; - } file_head; - grub_relocator_chunk_t ch; - - if (grub_file_seek (file, 48) == (grub_off_t) -1 - || grub_file_read (file, &header_length, sizeof (header_length)) - != sizeof (header_length) - || grub_file_seek (file, header_length) == (grub_off_t) -1) - goto fail; - - while (1) - { - grub_off_t off; - if (grub_file_read (file, &file_head, sizeof (file_head)) - != sizeof (file_head)) - goto fail; - if (file_head.type != 0xf0) - break; - off = grub_get_unaligned32 (file_head.size) & 0xffffff; - if (off < sizeof (file_head)) - goto fail; - if (grub_file_seek (file, grub_file_tell (file) + off - - sizeof (file_head)) == (grub_off_t) -1) - goto fail; - } - - if (file_head.type != 0x03) - goto fail; - - while (1) - { - if (grub_file_read (file, §ion_head, sizeof (section_head)) - != sizeof (section_head)) - goto fail; - if ((section_head >> 24) != 0x19) - break; - - if ((section_head & 0xffffff) < sizeof (section_head)) - goto fail; - - if (grub_file_seek (file, grub_file_tell (file) - + (section_head & 0xffffff) - - sizeof (section_head)) == (grub_off_t) -1) - goto fail; - } - - if ((section_head >> 24) != 0x10) - goto fail; - - grub_off_t exe_start = grub_file_tell (file); - - if (grub_file_read (file, &mz, sizeof (mz)) != sizeof (mz)) - goto fail; - if (mz[0] != 'M' || mz[1] != 'Z') - goto fail; - - if (grub_file_seek (file, grub_file_tell (file) + 0x3a) == (grub_off_t) -1) - goto fail; - - if (grub_file_read (file, §ion_head, sizeof (section_head)) - != sizeof (section_head)) - goto fail; - if (section_head < 0x40) - goto fail; - - if (grub_file_seek (file, grub_file_tell (file) - + section_head - 0x40) == (grub_off_t) -1) - goto fail; - - if (grub_file_read (file, &pe, sizeof (pe)) - != sizeof (pe)) - goto fail; - - if (pe[0] != 'P' || pe[1] != 'E' || pe[2] != '\0' || pe[3] != '\0') - goto fail; - - if (grub_file_read (file, &coff_head, sizeof (coff_head)) - != sizeof (coff_head)) - goto fail; - - grub_uint32_t loadaddr; - - switch (coff_head.machine) - { - case GRUB_PE32_MACHINE_I386: - { - struct grub_pe32_optional_header oh; - if (grub_file_read (file, &oh, sizeof (oh)) - != sizeof (oh)) - goto fail; - if (oh.magic != GRUB_PE32_PE32_MAGIC) - goto fail; - loadaddr = oh.image_base - exe_start; - entry = oh.image_base + oh.entry_addr; - break; - } - case GRUB_PE32_MACHINE_X86_64: - { - struct grub_pe64_optional_header oh; - if (! grub_cpuid_has_longmode) - { - grub_error (GRUB_ERR_BAD_OS, "your CPU does not implement AMD64 architecture"); - goto fail; - } - - if (grub_file_read (file, &oh, sizeof (oh)) - != sizeof (oh)) - goto fail; - if (oh.magic != GRUB_PE32_PE64_MAGIC) - goto fail; - loadaddr = oh.image_base - exe_start; - entry = oh.image_base + oh.entry_addr; - break; - } - default: - goto fail; - } - if (grub_file_seek (file, 0) == (grub_off_t) -1) - goto fail; - - grub_size_t fz = grub_file_size (file); - - if (grub_relocator_alloc_chunk_addr (relocator, &ch, - loadaddr, fz)) - goto fail; - - if (grub_file_read (file, get_virtual_current_address (ch), fz) - != (grub_ssize_t) fz) - goto fail; - - return GRUB_ERR_NONE; - - fail: - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, "fv volume is invalid"); - return grub_errno; -} - -static grub_err_t -load_chewed (grub_file_t file, const char *filename) -{ - grub_size_t i; - for (i = 0;; i++) - { - struct cbfs_payload_segment segment; - grub_err_t err; - - if (grub_file_seek (file, sizeof (segment) * i) == (grub_off_t) -1 - || grub_file_read (file, &segment, sizeof (segment)) - != sizeof (segment)) - { - if (!grub_errno) - return grub_error (GRUB_ERR_BAD_OS, - "payload is too short"); - return grub_errno; - } - - switch (segment.type) - { - case PAYLOAD_SEGMENT_PARAMS: - break; - - case PAYLOAD_SEGMENT_ENTRY: - entry = grub_be_to_cpu64 (segment.load_addr); - return GRUB_ERR_NONE; - - case PAYLOAD_SEGMENT_BSS: - segment.len = 0; - segment.offset = 0; - segment.len = 0; - /* Fallthrough. */ - case PAYLOAD_SEGMENT_CODE: - case PAYLOAD_SEGMENT_DATA: - { - grub_uint32_t target = grub_be_to_cpu64 (segment.load_addr); - grub_uint32_t memsize = grub_be_to_cpu32 (segment.mem_len); - grub_uint32_t filesize = grub_be_to_cpu32 (segment.len); - grub_uint8_t *load_addr; - grub_relocator_chunk_t ch; - - if (memsize < filesize) - memsize = filesize; - - grub_dprintf ("chain", "%x+%x\n", target, memsize); - - err = grub_relocator_alloc_chunk_addr (relocator, &ch, - target, memsize); - if (err) - return err; - - load_addr = get_virtual_current_address (ch); - - if (filesize) - { - if (grub_file_seek (file, grub_be_to_cpu32 (segment.offset)) - == (grub_off_t) -1) - return grub_errno; - - err = load_segment (file, filename, load_addr, - segment.compression, &filesize, memsize); - if (err) - return err; - } - - if (filesize < memsize) - grub_memset ((load_addr + filesize), - 0, memsize - filesize); - } - } - } -} - -static grub_err_t -grub_cmd_chain (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_err_t err; - grub_file_t file; - grub_uint32_t head; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - grub_loader_unset (); - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_COREBOOT_CHAINLOADER); - if (!file) - return grub_errno; - - relocator = grub_relocator_new (); - if (!relocator) - { - grub_file_close (file); - return grub_errno; - } - - if (grub_file_read (file, &head, sizeof (head)) != sizeof (head) - || grub_file_seek (file, 0) == (grub_off_t) -1) - { - grub_file_close (file); - grub_relocator_unload (relocator); - relocator = 0; - if (!grub_errno) - return grub_error (GRUB_ERR_BAD_OS, - "payload is too short"); - return grub_errno; - } - - switch (head) - { - case ELFMAG0 | (ELFMAG1 << 8) | (ELFMAG2 << 16) | (ELFMAG3 << 24): - err = load_elf (file, argv[0]); - break; - case PAYLOAD_SEGMENT_CODE: - case PAYLOAD_SEGMENT_DATA: - case PAYLOAD_SEGMENT_PARAMS: - case PAYLOAD_SEGMENT_BSS: - case PAYLOAD_SEGMENT_ENTRY: - err = load_chewed (file, argv[0]); - break; - - default: - if (grub_file_seek (file, 40) == (grub_off_t) -1 - || grub_file_read (file, &head, sizeof (head)) != sizeof (head) - || grub_file_seek (file, 0) == (grub_off_t) -1 - || head != 0x4856465f) - err = grub_error (GRUB_ERR_BAD_OS, "unrecognised payload type"); - else - err = load_tianocore (file); - break; - } - grub_file_close (file); - if (err) - { - grub_relocator_unload (relocator); - relocator = 0; - return err; - } - - grub_loader_set (grub_chain_boot, grub_chain_unload, 0); - return GRUB_ERR_NONE; -} - -static grub_command_t cmd_chain; - -GRUB_MOD_INIT (chain) -{ - cmd_chain = grub_register_command ("chainloader", grub_cmd_chain, - N_("FILE"), - /* TRANSLATORS: "payload" is a term used - by coreboot and must be translated in - sync with coreboot. If unsure, - let it untranslated. */ - N_("Load another coreboot payload")); -} - -GRUB_MOD_FINI (chain) -{ - grub_unregister_command (cmd_chain); - grub_chain_unload (); -} diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c deleted file mode 100644 index 12731feb2..000000000 --- a/grub-core/loader/i386/linux.c +++ /dev/null @@ -1,1175 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#ifdef GRUB_MACHINE_PCBIOS -#include -#endif - -#ifdef GRUB_MACHINE_EFI -#include -#include -#define HAS_VGA_TEXT 0 -#define DEFAULT_VIDEO_MODE "auto" -#define ACCEPTS_PURE_TEXT 0 -#elif defined (GRUB_MACHINE_IEEE1275) -#include -#define HAS_VGA_TEXT 0 -#define DEFAULT_VIDEO_MODE "text" -#define ACCEPTS_PURE_TEXT 1 -#else -#include -#include -#define HAS_VGA_TEXT 1 -#define DEFAULT_VIDEO_MODE "text" -#define ACCEPTS_PURE_TEXT 1 -#endif - -static grub_dl_t my_mod; - -static grub_size_t linux_mem_size; -static int loaded; -static void *prot_mode_mem; -static grub_addr_t prot_mode_target; -static void *initrd_mem; -static grub_addr_t initrd_mem_target; -static grub_size_t prot_init_space; -static struct grub_relocator *relocator = NULL; -static void *efi_mmap_buf; -static grub_size_t maximal_cmdline_size; -static struct linux_kernel_params linux_params; -static char *linux_cmdline; -#ifdef GRUB_MACHINE_EFI -static grub_efi_uintn_t efi_mmap_size; -#else -static const grub_size_t efi_mmap_size = 0; -#endif - -/* FIXME */ -#if 0 -struct idt_descriptor -{ - grub_uint16_t limit; - void *base; -} GRUB_PACKED; - -static struct idt_descriptor idt_desc = - { - 0, - 0 - }; -#endif - -static inline grub_size_t -page_align (grub_size_t size) -{ - return (size + (1 << 12) - 1) & (~((1 << 12) - 1)); -} - -/* Helper for find_mmap_size. */ -static int -count_hook (grub_uint64_t addr __attribute__ ((unused)), - grub_uint64_t size __attribute__ ((unused)), - grub_memory_type_t type __attribute__ ((unused)), void *data) -{ - grub_size_t *count = data; - - (*count)++; - return 0; -} - -/* 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; - - grub_mmap_iterate (count_hook, &count); - - mmap_size = count * sizeof (struct grub_boot_e820_entry); - - /* 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) -{ - grub_relocator_unload (relocator); - relocator = NULL; - prot_mode_mem = initrd_mem = 0; - prot_mode_target = initrd_mem_target = 0; -} - -/* Allocate pages for the real mode code and the protected mode code - for linux as well as a memory map buffer. */ -static grub_err_t -allocate_pages (grub_size_t prot_size, grub_size_t *align, - grub_size_t min_align, int relocatable, - grub_uint64_t preferred_address) -{ - grub_err_t err; - - if (prot_size == 0) - prot_size = 1; - - prot_size = page_align (prot_size); - - /* Initialize the memory pointers with NULL for convenience. */ - free_pages (); - - relocator = grub_relocator_new (); - if (!relocator) - { - err = grub_errno; - goto fail; - } - - /* FIXME: Should request low memory from the heap when this feature is - implemented. */ - - { - grub_relocator_chunk_t ch; - if (relocatable) - { - err = grub_relocator_alloc_chunk_align (relocator, &ch, - preferred_address, - preferred_address, - prot_size, 1, - GRUB_RELOCATOR_PREFERENCE_LOW, - 1); - for (; err && *align + 1 > min_align; (*align)--) - { - grub_errno = GRUB_ERR_NONE; - err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000, - UP_TO_TOP32 (prot_size), - prot_size, 1 << *align, - GRUB_RELOCATOR_PREFERENCE_LOW, - 1); - } - if (err) - goto fail; - } - else - err = grub_relocator_alloc_chunk_addr (relocator, &ch, - preferred_address, - prot_size); - if (err) - goto fail; - prot_mode_mem = get_virtual_current_address (ch); - prot_mode_target = get_physical_target_address (ch); - } - - grub_dprintf ("linux", "prot_mode_mem = %p, prot_mode_target = %lx, prot_size = %x\n", - prot_mode_mem, (unsigned long) prot_mode_target, - (unsigned) prot_size); - return GRUB_ERR_NONE; - - fail: - free_pages (); - return err; -} - -static grub_err_t -grub_e820_add_region (struct grub_boot_e820_entry *e820_entry, int *e820_num, - grub_uint64_t start, grub_uint64_t size, - grub_uint32_t type) -{ - int n = *e820_num; - - if ((n > 0) && (e820_entry[n - 1].addr + e820_entry[n - 1].size == start) && - (e820_entry[n - 1].type == type)) - e820_entry[n - 1].size += size; - else - { - e820_entry[n].addr = start; - e820_entry[n].size = size; - e820_entry[n].type = type; - (*e820_num)++; - } - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_linux_setup_video (struct linux_kernel_params *params) -{ - struct grub_video_mode_info mode_info; - void *framebuffer; - grub_err_t err; - grub_video_driver_id_t driver_id; - const char *gfxlfbvar = grub_env_get ("gfxpayloadforcelfb"); - - driver_id = grub_video_get_driver_id (); - - if (driver_id == GRUB_VIDEO_DRIVER_NONE) - return 1; - - err = grub_video_get_info_and_fini (&mode_info, &framebuffer); - - if (err) - { - grub_errno = GRUB_ERR_NONE; - return 1; - } - - params->screen_info.lfb_width = mode_info.width; - params->screen_info.lfb_height = mode_info.height; - params->screen_info.lfb_depth = mode_info.bpp; - params->screen_info.lfb_linelength = mode_info.pitch; - - params->screen_info.lfb_base = (grub_size_t) framebuffer; - -#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__) - params->screen_info.ext_lfb_base = (grub_size_t) (((grub_uint64_t)(grub_size_t) framebuffer) >> 32); - params->screen_info.capabilities |= VIDEO_CAPABILITY_64BIT_BASE; -#endif - - params->screen_info.lfb_size = ALIGN_UP (params->screen_info.lfb_linelength * params->screen_info.lfb_height, 65536); - - params->screen_info.red_size = mode_info.red_mask_size; - params->screen_info.red_pos = mode_info.red_field_pos; - params->screen_info.green_size = mode_info.green_mask_size; - params->screen_info.green_pos = mode_info.green_field_pos; - params->screen_info.blue_size = mode_info.blue_mask_size; - params->screen_info.blue_pos = mode_info.blue_field_pos; - params->screen_info.rsvd_size = mode_info.reserved_mask_size; - params->screen_info.rsvd_pos = mode_info.reserved_field_pos; - - if (gfxlfbvar && (gfxlfbvar[0] == '1' || gfxlfbvar[0] == 'y')) - params->screen_info.orig_video_isVGA = GRUB_VIDEO_LINUX_TYPE_SIMPLE; - else - { - switch (driver_id) - { - case GRUB_VIDEO_DRIVER_VBE: - params->screen_info.lfb_size >>= 16; - params->screen_info.orig_video_isVGA = GRUB_VIDEO_LINUX_TYPE_VESA; - break; - - case GRUB_VIDEO_DRIVER_EFI_UGA: - case GRUB_VIDEO_DRIVER_EFI_GOP: - params->screen_info.orig_video_isVGA = GRUB_VIDEO_LINUX_TYPE_EFIFB; - break; - - /* FIXME: check if better id is available. */ - case GRUB_VIDEO_DRIVER_SM712: - case GRUB_VIDEO_DRIVER_SIS315PRO: - case GRUB_VIDEO_DRIVER_VGA: - case GRUB_VIDEO_DRIVER_CIRRUS: - case GRUB_VIDEO_DRIVER_BOCHS: - case GRUB_VIDEO_DRIVER_RADEON_FULOONG2E: - case GRUB_VIDEO_DRIVER_RADEON_YEELOONG3A: - case GRUB_VIDEO_DRIVER_IEEE1275: - case GRUB_VIDEO_DRIVER_COREBOOT: - /* Make gcc happy. */ - case GRUB_VIDEO_DRIVER_XEN: - case GRUB_VIDEO_DRIVER_SDL: - case GRUB_VIDEO_DRIVER_NONE: - case GRUB_VIDEO_ADAPTER_CAPTURE: - params->screen_info.orig_video_isVGA = GRUB_VIDEO_LINUX_TYPE_SIMPLE; - break; - } - } - -#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 (driver_id == GRUB_VIDEO_DRIVER_VBE && 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->screen_info.red_size = params->screen_info.green_size - = params->screen_info.blue_size = width; - params->screen_info.rsvd_size = 0; - } -#endif - - return GRUB_ERR_NONE; -} - -/* Context for grub_linux_boot. */ -struct grub_linux_boot_ctx -{ - grub_addr_t real_mode_target; - grub_size_t real_size; - struct linux_kernel_params *params; - int e820_num; -}; - -/* Helper for grub_linux_boot. */ -static int -grub_linux_boot_mmap_find (grub_uint64_t addr, grub_uint64_t size, - grub_memory_type_t type, void *data) -{ - struct grub_linux_boot_ctx *ctx = data; - - /* We must put real mode code in the traditional space. */ - if (type != GRUB_MEMORY_AVAILABLE || addr > 0x90000) - return 0; - - if (addr + size < 0x10000) - return 0; - - if (addr < 0x10000) - { - size += addr - 0x10000; - addr = 0x10000; - } - - if (addr + size > 0x90000) - size = 0x90000 - addr; - - if (ctx->real_size + efi_mmap_size > size) - return 0; - - grub_dprintf ("linux", "addr = %lx, size = %x, need_size = %x\n", - (unsigned long) addr, - (unsigned) size, - (unsigned) (ctx->real_size + efi_mmap_size)); - ctx->real_mode_target = ((addr + size) - (ctx->real_size + efi_mmap_size)); - return 1; -} - -/* GRUB types conveniently match E820 types. */ -static int -grub_linux_boot_mmap_fill (grub_uint64_t addr, grub_uint64_t size, - grub_memory_type_t type, void *data) -{ - struct grub_linux_boot_ctx *ctx = data; - - if (grub_e820_add_region (ctx->params->e820_table, &ctx->e820_num, - addr, size, type)) - return 1; - - return 0; -} - -static grub_err_t -grub_linux_boot (void) -{ - grub_err_t err = 0; - const char *modevar; - char *tmp; - struct grub_relocator32_state state; - void *real_mode_mem; - struct grub_linux_boot_ctx ctx = { - .real_mode_target = 0 - }; - grub_size_t mmap_size; - grub_size_t cl_offset; - -#ifdef GRUB_MACHINE_IEEE1275 - { - const 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); - linux_params.olpc_ofw_header.ofw_magic = GRUB_LINUX_OFW_SIGNATURE; - linux_params.olpc_ofw_header.ofw_version = 1; - linux_params.olpc_ofw_header.cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn; - linux_params.olpc_ofw_header.irq_desc_table = 0; - } -#endif - - 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;" DEFAULT_VIDEO_MODE, modevar); - if (! tmp) - return grub_errno; -#if ACCEPTS_PURE_TEXT - err = grub_video_set_mode (tmp, 0, 0); -#else - err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); -#endif - grub_free (tmp); - } - else /* We can't go back to text mode from coreboot fb. */ -#ifdef GRUB_MACHINE_COREBOOT - if (grub_video_get_driver_id () == GRUB_VIDEO_DRIVER_COREBOOT) - err = GRUB_ERR_NONE; - else -#endif - { -#if ACCEPTS_PURE_TEXT - err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0); -#else - err = grub_video_set_mode (DEFAULT_VIDEO_MODE, - GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); -#endif - } - - if (err) - { - grub_print_error (); - grub_puts_ (N_("Booting in blind mode")); - grub_errno = GRUB_ERR_NONE; - } - - if (grub_linux_setup_video (&linux_params)) - { -#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) - linux_params.screen_info.orig_video_isVGA = GRUB_VIDEO_LINUX_TYPE_TEXT; - linux_params.screen_info.orig_video_mode = 0x3; -#else - linux_params.screen_info.orig_video_isVGA = 0; - linux_params.screen_info.orig_video_mode = 0; - linux_params.screen_info.orig_video_cols = 0; - linux_params.screen_info.orig_video_lines = 0; -#endif - } - - -#ifndef GRUB_MACHINE_IEEE1275 - if (linux_params.screen_info.orig_video_isVGA == GRUB_VIDEO_LINUX_TYPE_TEXT) -#endif - { - 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_strcmp (term->name, "ofconsole") == 0) - { - struct grub_term_coordinate pos = grub_term_getxy (term); - linux_params.screen_info.orig_x = pos.x; - linux_params.screen_info.orig_y = pos.y; - linux_params.screen_info.orig_video_cols = grub_term_width (term); - linux_params.screen_info.orig_video_lines = grub_term_height (term); - found = 1; - break; - } - if (!found) - { - linux_params.screen_info.orig_x = 0; - linux_params.screen_info.orig_y = 0; - linux_params.screen_info.orig_video_cols = 80; - linux_params.screen_info.orig_video_lines = 25; - } - } - -#ifdef GRUB_KERNEL_USE_RSDP_ADDR - linux_params.acpi_rsdp_addr = grub_le_to_cpu64 (grub_rsdp_addr); -#endif - - mmap_size = find_mmap_size (); - /* Make sure that each size is aligned to a page boundary. */ - cl_offset = ALIGN_UP (mmap_size + sizeof (linux_params), 4096); - if (cl_offset < ((grub_size_t) linux_params.hdr.setup_sects << GRUB_DISK_SECTOR_BITS)) - cl_offset = ALIGN_UP ((grub_size_t) (linux_params.hdr.setup_sects - << GRUB_DISK_SECTOR_BITS), 4096); - ctx.real_size = ALIGN_UP (cl_offset + maximal_cmdline_size, 4096); - -#ifdef GRUB_MACHINE_EFI - efi_mmap_size = grub_efi_find_mmap_size (); - if (efi_mmap_size == 0) - return grub_errno; -#endif - - grub_dprintf ("linux", "real_size = %x, mmap_size = %x\n", - (unsigned) ctx.real_size, (unsigned) mmap_size); - -#ifdef GRUB_MACHINE_EFI - grub_efi_mmap_iterate (grub_linux_boot_mmap_find, &ctx, 1); - if (! ctx.real_mode_target) - grub_efi_mmap_iterate (grub_linux_boot_mmap_find, &ctx, 0); -#else - grub_mmap_iterate (grub_linux_boot_mmap_find, &ctx); -#endif - grub_dprintf ("linux", "real_mode_target = %lx, real_size = %x, efi_mmap_size = %x\n", - (unsigned long) ctx.real_mode_target, - (unsigned) ctx.real_size, - (unsigned) efi_mmap_size); - - if (! ctx.real_mode_target) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages"); - - { - grub_relocator_chunk_t ch; - grub_size_t sz; - - if (grub_add (ctx.real_size, efi_mmap_size, &sz)) - return GRUB_ERR_OUT_OF_RANGE; - - err = grub_relocator_alloc_chunk_addr (relocator, &ch, - ctx.real_mode_target, sz); - if (err) - return err; - real_mode_mem = get_virtual_current_address (ch); - } - efi_mmap_buf = (grub_uint8_t *) real_mode_mem + ctx.real_size; - - grub_dprintf ("linux", "real_mode_mem = %p\n", - real_mode_mem); - - ctx.params = real_mode_mem; - - *ctx.params = linux_params; - ctx.params->hdr.cmd_line_ptr = ctx.real_mode_target + cl_offset; - grub_memcpy ((char *) ctx.params + cl_offset, linux_cmdline, - maximal_cmdline_size); - - grub_dprintf ("linux", "code32_start = %x\n", - (unsigned) ctx.params->hdr.code32_start); - - ctx.e820_num = 0; - if (grub_mmap_iterate (grub_linux_boot_mmap_fill, &ctx)) - return grub_errno; - ctx.params->e820_entries = ctx.e820_num; - -#ifdef GRUB_MACHINE_EFI - { - grub_efi_uintn_t efi_desc_size; - grub_size_t efi_mmap_target; - grub_efi_uint32_t efi_desc_version; - - ctx.params->secure_boot = grub_efi_get_secureboot (); - - err = grub_efi_finish_boot_services (&efi_mmap_size, efi_mmap_buf, NULL, - &efi_desc_size, &efi_desc_version); - if (err) - return err; - - /* Note that no boot services are available from here. */ - efi_mmap_target = ctx.real_mode_target - + ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem); - /* Pass EFI parameters. */ - if (grub_le_to_cpu16 (ctx.params->hdr.version) >= 0x0208) - { - ctx.params->efi_info.v0208.efi_memdesc_size = efi_desc_size; - ctx.params->efi_info.v0208.efi_memdesc_version = efi_desc_version; - ctx.params->efi_info.v0208.efi_memmap = efi_mmap_target; - ctx.params->efi_info.v0208.efi_memmap_size = efi_mmap_size; - -#ifdef __x86_64__ - ctx.params->efi_info.v0208.efi_memmap_hi = (efi_mmap_target >> 32); -#endif - } - else if (grub_le_to_cpu16 (ctx.params->hdr.version) >= 0x0206) - { - ctx.params->efi_info.v0206.efi_memdesc_size = efi_desc_size; - ctx.params->efi_info.v0206.efi_memdesc_version = efi_desc_version; - ctx.params->efi_info.v0206.efi_memmap = efi_mmap_target; - ctx.params->efi_info.v0206.efi_memmap_size = efi_mmap_size; - } - else if (grub_le_to_cpu16 (ctx.params->hdr.version) >= 0x0204) - { - ctx.params->efi_info.v0204.efi_memdesc_size = efi_desc_size; - ctx.params->efi_info.v0204.efi_memdesc_version = efi_desc_version; - ctx.params->efi_info.v0204.efi_memmap = efi_mmap_target; - ctx.params->efi_info.v0204.efi_memmap_size = efi_mmap_size; - } - } -#endif - -#if defined (__x86_64__) && defined (GRUB_MACHINE_EFI) - if (grub_le_to_cpu16 (ctx.params->hdr.version) >= 0x020c && - (linux_params.hdr.xloadflags & LINUX_X86_XLF_KERNEL_64) != 0) - { - struct grub_relocator64_efi_state state64; - - state64.rsi = ctx.real_mode_target; - state64.rip = ctx.params->hdr.code32_start + LINUX_X86_STARTUP64_OFFSET; - return grub_relocator64_efi_boot (relocator, state64); - } -#endif - - /* FIXME. */ - /* asm volatile ("lidt %0" : : "m" (idt_desc)); */ - state.ebp = state.edi = state.ebx = 0; - state.esi = ctx.real_mode_target; - state.esp = ctx.real_mode_target; - state.eip = ctx.params->hdr.code32_start; - return grub_relocator32_boot (relocator, state, 0); -} - -static grub_err_t -grub_linux_unload (void) -{ - grub_dl_unref (my_mod); - loaded = 0; - grub_free (linux_cmdline); - linux_cmdline = 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_i386_kernel_header lh; - grub_uint8_t setup_sects; - grub_size_t real_size, prot_size, prot_file_size; - grub_ssize_t len; - int i; - grub_size_t align, min_align; - int relocatable; - grub_uint64_t preferred_address = GRUB_LINUX_BZIMAGE_ADDR; - - grub_dl_ref (my_mod); - - if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); - if (! file) - goto fail; - - if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - argv[0]); - goto fail; - } - - if (lh.boot_flag != grub_cpu_to_le16_compile_time (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; - } - - /* 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_compile_time (GRUB_LINUX_I386_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; - } - - 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; - } - - if (grub_le_to_cpu16 (lh.version) >= 0x0206) - maximal_cmdline_size = grub_le_to_cpu32 (lh.cmdline_size) + 1; - else - maximal_cmdline_size = 256; - - if (maximal_cmdline_size < 128) - maximal_cmdline_size = 128; - - 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_file_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE; - - if (grub_le_to_cpu16 (lh.version) >= 0x205 - && lh.kernel_alignment != 0 - && ((lh.kernel_alignment - 1) & lh.kernel_alignment) == 0) - { - for (align = 0; align < 32; align++) - if (grub_le_to_cpu32 (lh.kernel_alignment) & (1 << align)) - break; - relocatable = lh.relocatable; - } - else - { - align = 0; - relocatable = 0; - } - - if (grub_le_to_cpu16 (lh.version) >= 0x020a) - { - min_align = lh.min_alignment; - prot_size = grub_le_to_cpu32 (lh.init_size); - prot_init_space = page_align (prot_size); - if (relocatable) - preferred_address = grub_le_to_cpu64 (lh.pref_address); - } - else - { - min_align = align; - prot_size = prot_file_size; - /* Usually, the compression ratio is about 50%. */ - prot_init_space = page_align (prot_size) * 3; - } - - if (allocate_pages (prot_size, &align, - min_align, relocatable, - preferred_address)) - goto fail; - - grub_memset (&linux_params, 0, sizeof (linux_params)); - - /* - * The Linux 32-bit boot protocol defines the setup header end - * to be at 0x202 + the byte value at 0x201. - */ - len = 0x202 + *((char *) &lh.jump + 1); - - /* Verify the struct is big enough so we do not write past the end. */ - if (len > (char *) &linux_params.edd_mbr_sig_buffer - (char *) &linux_params) { - grub_error (GRUB_ERR_BAD_OS, "Linux setup header too big"); - goto fail; - } - - grub_memcpy (&linux_params.hdr.setup_sects, &lh.setup_sects, len - 0x1F1); - - /* We've already read lh so there is no need to read it second time. */ - len -= sizeof(lh); - - if ((len > 0) && - (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len)) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - argv[0]); - goto fail; - } - - linux_params.hdr.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR; - linux_params.hdr.kernel_alignment = ((grub_uint32_t) 1 << align); - linux_params.hdr.boot_flag = 0; - linux_params.hdr.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE; - - /* These two are used (instead of cmd_line_ptr) by older versions of Linux, - and otherwise ignored. */ - linux_params.screen_info.cl_magic = GRUB_LINUX_CL_MAGIC; - linux_params.screen_info.cl_offset = 0x1000; - - linux_params.hdr.ramdisk_image = 0; - linux_params.hdr.ramdisk_size = 0; - - linux_params.hdr.heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET; - linux_params.hdr.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. */ - linux_params.screen_info.ext_mem_k = ((32 * 0x100000) >> 10); - linux_params.alt_mem_k = ((32 * 0x100000) >> 10); - - /* Ignored by Linux. */ - linux_params.screen_info.orig_video_page = 0; - - /* Only used when `video_mode == 0x7', otherwise ignored. */ - linux_params.screen_info.orig_video_ega_bx = 0; - - linux_params.screen_info.orig_video_points = 16; /* XXX */ - -#ifdef GRUB_MACHINE_EFI -#ifdef __x86_64__ - if (grub_le_to_cpu16 (linux_params.hdr.version) < 0x0208 && - ((grub_addr_t) grub_efi_system_table >> 32) != 0) { - grub_errno = grub_error (GRUB_ERR_BAD_OS, "kernel does not support 64-bit addressing"); - goto fail; - } -#endif - - if (grub_le_to_cpu16 (linux_params.hdr.version) >= 0x0208) - { - linux_params.efi_info.v0208.efi_loader_signature = GRUB_LINUX_EFI_SIGNATURE; - linux_params.efi_info.v0208.efi_systab = (grub_uint32_t) (grub_addr_t) grub_efi_system_table; -#ifdef __x86_64__ - linux_params.efi_info.v0208.efi_systab_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32); -#endif - } - else if (grub_le_to_cpu16 (linux_params.hdr.version) >= 0x0206) - { - linux_params.efi_info.v0206.efi_loader_signature = GRUB_LINUX_EFI_SIGNATURE; - linux_params.efi_info.v0206.efi_systab = (grub_uint32_t) (grub_addr_t) grub_efi_system_table; - } - else if (grub_le_to_cpu16 (linux_params.hdr.version) >= 0x0204) - { - linux_params.efi_info.v0204.efi_loader_signature = GRUB_LINUX_EFI_SIGNATURE_0204; - linux_params.efi_info.v0204.efi_systab = (grub_uint32_t) (grub_addr_t) grub_efi_system_table; - } -#endif - - /* 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 grub_vesa_mode_table_entry *linux_mode; - grub_err_t err; - char *buf; - - grub_dl_load ("vbe"); - - 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_puts_ (N_("Legacy `ask' parameter no longer supported.")); - - /* 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_ (N_("%s is deprecated. " - "Use set gfxpayload=%s before " - "linux command instead.\n"), - argv[i], "text"); - break; - - case 1: - case GRUB_LINUX_VID_MODE_EXTENDED: - /* FIXME: support 80x50 text. */ - grub_env_set ("gfxpayload", "text"); - grub_printf_ (N_("%s is deprecated. " - "Use set gfxpayload=%s before " - "linux command instead.\n"), - argv[i], "text"); - break; - default: - /* Ignore invalid values. */ - if (vid_mode < GRUB_VESA_MODE_TABLE_START || - vid_mode > GRUB_VESA_MODE_TABLE_END) - { - grub_env_set ("gfxpayload", "text"); - /* TRANSLATORS: "x" has to be entered in, like an identifier, - so please don't use better Unicode codepoints. */ - grub_printf_ (N_("%s is deprecated. VGA mode %d isn't recognized. " - "Use set gfxpayload=WIDTHxHEIGHT[xDEPTH] " - "before linux command instead.\n"), - argv[i], vid_mode); - break; - } - - linux_mode = &grub_vesa_mode_table[vid_mode - - GRUB_VESA_MODE_TABLE_START]; - - buf = grub_xasprintf ("%ux%ux%u,%ux%u", - linux_mode->width, linux_mode->height, - linux_mode->depth, - linux_mode->width, linux_mode->height); - if (! buf) - goto fail; - - grub_printf_ (N_("%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) - { - const 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; - /* FALLTHROUGH */ - case 'm': - shift += 10; - /* FALLTHROUGH */ - case 'k': - shift += 10; - /* FALLTHROUGH */ - 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) - { - linux_params.hdr.loadflags |= GRUB_LINUX_FLAG_QUIET; - } - - /* Create kernel command line. */ - linux_cmdline = grub_zalloc (maximal_cmdline_size + 1); - if (!linux_cmdline) - goto fail; - grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - { - grub_err_t err; - err = grub_create_loader_cmdline (argc, argv, - linux_cmdline - + sizeof (LINUX_IMAGE) - 1, - maximal_cmdline_size - - (sizeof (LINUX_IMAGE) - 1), - GRUB_VERIFY_KERNEL_CMDLINE); - if (err) - goto fail; - } - - len = prot_file_size; - if (grub_file_read (file, prot_mode_mem, len) != len && !grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - argv[0]); - - 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_size_t size = 0, aligned_size = 0; - grub_addr_t addr_min, addr_max; - grub_addr_t addr; - grub_err_t err; - struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; - - if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - if (! loaded) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); - goto fail; - } - - if (grub_initrd_init (argc, argv, &initrd_ctx)) - goto fail; - - size = grub_get_initrd_size (&initrd_ctx); - aligned_size = ALIGN_UP (size, 4096); - - /* Get the highest address available for the initrd. */ - if (grub_le_to_cpu16 (linux_params.hdr.version) >= 0x0203) - { - addr_max = grub_cpu_to_le32 (linux_params.hdr.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; - - addr_min = (grub_addr_t) prot_mode_target + prot_init_space; - - /* Make sure the maximum address is able to store the initrd. */ - if (addr_max < aligned_size) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("the size of initrd is bigger than addr_max")); - goto fail; - } - - /* Put the initrd as high as possible, 4KiB aligned. */ - addr = (addr_max - aligned_size) & ~0xFFF; - - grub_dprintf ("linux", - "Initrd at addr 0x%" PRIxGRUB_ADDR " which is expected in" - " ranger 0x%" PRIxGRUB_ADDR " ~ 0x%" PRIxGRUB_ADDR "\n", - addr, addr_min, addr_max); - - if (addr < addr_min) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "the initrd is too big"); - goto fail; - } - - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_align (relocator, &ch, - addr_min, addr, aligned_size, - 0x1000, - GRUB_RELOCATOR_PREFERENCE_HIGH, - 1); - if (err) - goto fail; - initrd_mem = get_virtual_current_address (ch); - initrd_mem_target = get_physical_target_address (ch); - } - - if (grub_initrd_load (&initrd_ctx, initrd_mem)) - goto fail; - - grub_dprintf ("linux", "Initrd (%p) at 0x%" PRIxGRUB_ADDR ", size=0x%" PRIxGRUB_SIZE "\n", - initrd_mem, initrd_mem_target, size); - - linux_params.hdr.ramdisk_image = initrd_mem_target; - linux_params.hdr.ramdisk_size = size; - linux_params.hdr.root_dev = 0x0100; /* XXX */ - - fail: - grub_initrd_close (&initrd_ctx); - - return grub_errno; -} - -#ifndef GRUB_MACHINE_EFI -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); -} -#else -extern grub_err_t __attribute__((alias("grub_cmd_linux"))) -grub_cmd_linux_x86_legacy (grub_command_t cmd, int argc, char *argv[]); - -extern grub_err_t __attribute__((alias("grub_cmd_initrd"))) -grub_cmd_initrd_x86_legacy (grub_command_t cmd, int argc, char *argv[]); -#endif diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c deleted file mode 100644 index bdaf67ad0..000000000 --- a/grub-core/loader/i386/multiboot_mbi.c +++ /dev/null @@ -1,759 +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 . - */ - -#include -#ifdef GRUB_MACHINE_PCBIOS -#include -#include -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef GRUB_MACHINE_EFI -#include -#endif - -/* 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; -}; - -static 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; -static grub_size_t elf_sec_num, elf_sec_entsize; -static unsigned elf_sec_shstrndx; -static void *elf_sections; -grub_multiboot_quirks_t grub_multiboot_quirks; - -static grub_err_t -load_kernel (grub_file_t file, const char *filename, - char *buffer, struct multiboot_header *header) -{ - mbi_load_data_t mld; - - mld.file = file; - mld.filename = filename; - mld.buffer = buffer; - mld.mbi_ver = 1; - mld.relocatable = 0; - mld.avoid_efi_boot_services = 0; - - if (grub_multiboot_quirks & GRUB_MULTIBOOT_QUIRK_BAD_KLUDGE) - { - grub_err_t err = grub_multiboot_load_elf (&mld); - - if (err == GRUB_ERR_NONE) { - return GRUB_ERR_NONE; - } - if (err == GRUB_ERR_UNKNOWN_OS && (header->flags & MULTIBOOT_AOUT_KLUDGE)) - grub_errno = err = GRUB_ERR_NONE; - if (err != GRUB_ERR_NONE) - return err; - } - 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; - void *source; - grub_relocator_chunk_t ch; - grub_err_t err; - - if (header->bss_end_addr) - code_size = (header->bss_end_addr - header->load_addr); - else - code_size = load_size; - - err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, - &ch, header->load_addr, - code_size); - if (err) - { - grub_dprintf ("multiboot_loader", "Error loading aout kludge\n"); - return err; - } - source = get_virtual_current_address (ch); - - if ((grub_file_seek (file, offset)) == (grub_off_t) -1) - { - return grub_errno; - } - - grub_file_read (file, source, load_size); - if (grub_errno) - return grub_errno; - - if (header->bss_end_addr) - grub_memset ((grub_uint8_t *) source + load_size, 0, - header->bss_end_addr - header->load_addr - load_size); - - grub_multiboot_payload_eip = header->entry_addr; - return GRUB_ERR_NONE; - } - - return grub_multiboot_load_elf (&mld); -} - -static struct multiboot_header * -find_header (char *buffer, grub_ssize_t len) -{ - struct multiboot_header *header; - - /* 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 = (struct multiboot_header *) ((char *) header + MULTIBOOT_HEADER_ALIGN)) - { - if (header->magic == MULTIBOOT_HEADER_MAGIC - && !(header->magic + header->flags + header->checksum)) - return header; - } - return NULL; -} - -grub_err_t -grub_multiboot_load (grub_file_t file, const char *filename) -{ - 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); - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - return grub_errno; - } - - header = find_header (buffer, len); - - 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); - } - - err = load_kernel (file, filename, buffer, header); - 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; -} - -#if GRUB_MACHINE_HAS_VBE || GRUB_MACHINE_HAS_VGA_TEXT -#include -#endif - -static grub_size_t -grub_multiboot_get_mbi_size (void) -{ - grub_size_t ret; - struct grub_net_network_level_interface *net; - - ret = sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4) - + modcnt * sizeof (struct multiboot_mod_list) + total_modcmd - + ALIGN_UP (sizeof(PACKAGE_STRING), 4) - + grub_multiboot_get_mmap_count () * sizeof (struct multiboot_mmap_entry) - + elf_sec_entsize * elf_sec_num - + 256 * sizeof (struct multiboot_color) -#if GRUB_MACHINE_HAS_VBE || GRUB_MACHINE_HAS_VGA_TEXT - + sizeof (struct grub_vbe_info_block) - + sizeof (struct grub_vbe_mode_info_block) -#endif - + ALIGN_UP (sizeof (struct multiboot_apm_info), 4); - - FOR_NET_NETWORK_LEVEL_INTERFACES(net) - if (net->dhcp_ack) - { - ret += net->dhcp_acklen; - break; - } - - return ret; -} - -/* Helper for grub_fill_multiboot_mmap. */ -static int -grub_fill_multiboot_mmap_iter (grub_uint64_t addr, grub_uint64_t size, - grub_memory_type_t type, void *data) -{ - struct multiboot_mmap_entry **mmap_entry = data; - - (*mmap_entry)->addr = addr; - (*mmap_entry)->len = size; - (*mmap_entry)->type = type; - (*mmap_entry)->size = sizeof (struct multiboot_mmap_entry) - sizeof ((*mmap_entry)->size); - (*mmap_entry)++; - - return 0; -} - -/* 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; - - grub_mmap_iterate (grub_fill_multiboot_mmap_iter, &mmap_entry); -} - -#if GRUB_MACHINE_HAS_VBE || GRUB_MACHINE_HAS_VGA_TEXT - -static grub_err_t -fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, - grub_uint32_t ptrdest, int fill_generic) -{ - grub_uint32_t vbe_mode; - struct grub_vbe_mode_info_block *mode_info; -#if GRUB_MACHINE_HAS_VBE - grub_vbe_status_t status; - void *scratch = grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); - - status = grub_vbe_bios_get_controller_info (scratch); - if (status != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_IO, "Can't get controller info."); - - mbi->vbe_control_info = ptrdest; - grub_memcpy (ptrorig, scratch, sizeof (struct grub_vbe_info_block)); - ptrorig += sizeof (struct grub_vbe_info_block); - ptrdest += sizeof (struct grub_vbe_info_block); -#else - mbi->vbe_control_info = 0; -#endif - -#if GRUB_MACHINE_HAS_VBE - status = grub_vbe_bios_get_mode (scratch); - vbe_mode = *(grub_uint32_t *) scratch; - if (status != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_IO, "can't get VBE mode"); -#else - vbe_mode = 3; -#endif - mbi->vbe_mode = vbe_mode; - - mode_info = (struct grub_vbe_mode_info_block *) ptrorig; - mbi->vbe_mode_info = ptrdest; - /* get_mode_info isn't available for mode 3. */ - if (vbe_mode == 3) - { - grub_memset (mode_info, 0, sizeof (struct grub_vbe_mode_info_block)); - mode_info->memory_model = GRUB_VBE_MEMORY_MODEL_TEXT; - mode_info->x_resolution = 80; - mode_info->y_resolution = 25; - } - else - { -#if GRUB_MACHINE_HAS_VBE - status = grub_vbe_bios_get_mode_info (vbe_mode, scratch); - if (status != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_IO, "can't get mode info"); - grub_memcpy (mode_info, scratch, - sizeof (struct grub_vbe_mode_info_block)); -#endif - } - ptrorig += sizeof (struct grub_vbe_mode_info_block); - ptrdest += sizeof (struct grub_vbe_mode_info_block); - -#if GRUB_MACHINE_HAS_VBE - grub_vbe_bios_get_pm_interface (&mbi->vbe_interface_seg, - &mbi->vbe_interface_off, - &mbi->vbe_interface_len); -#endif - - mbi->flags |= MULTIBOOT_INFO_VBE_INFO; - - if (fill_generic && mode_info->memory_model == GRUB_VBE_MEMORY_MODEL_TEXT) - { - mbi->framebuffer_addr = 0xb8000; - - mbi->framebuffer_pitch = 2 * mode_info->x_resolution; - mbi->framebuffer_width = mode_info->x_resolution; - mbi->framebuffer_height = mode_info->y_resolution; - - mbi->framebuffer_bpp = 16; - - mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT; - - mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO; - } - - return GRUB_ERR_NONE; -} -#endif - -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 GRUB_MACHINE_HAS_VGA_TEXT - if (driv_id == GRUB_VIDEO_DRIVER_NONE) - return fill_vbe_info (mbi, ptrorig, ptrdest, 1); -#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; - - 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.red_field_pos; - mbi->framebuffer_red_mask_size = mode_info.red_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; - -#if GRUB_MACHINE_HAS_VBE - if (driv_id == GRUB_VIDEO_DRIVER_VBE) - return fill_vbe_info (mbi, ptrorig, ptrdest, 0); -#endif - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_multiboot_make_mbi (grub_uint32_t *target) -{ - struct multiboot_info *mbi; - struct multiboot_mod_list *modlist; - unsigned i; - struct module *cur; - grub_size_t mmap_size; - grub_uint8_t *ptrorig; - grub_addr_t ptrdest; - - grub_err_t err; - grub_size_t bufsize; - grub_relocator_chunk_t ch; - - bufsize = grub_multiboot_get_mbi_size (); - - err = grub_relocator_alloc_chunk_align_safe (grub_multiboot_relocator, &ch, - 0x10000, 0xa0000, bufsize, 4, - GRUB_RELOCATOR_PREFERENCE_NONE, 0); - if (err) - return err; - ptrorig = get_virtual_current_address (ch); - ptrdest = get_physical_target_address (ch); - - *target = ptrdest; - - 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); - -#ifdef GRUB_MACHINE_PCBIOS - { - struct grub_apm_info info; - if (grub_apm_get_info (&info)) - { - struct multiboot_apm_info *mbinfo = (void *) ptrorig; - - mbinfo->cseg = info.cseg; - mbinfo->offset = info.offset; - mbinfo->cseg_16 = info.cseg_16; - mbinfo->dseg = info.dseg; - mbinfo->flags = info.flags; - mbinfo->cseg_len = info.cseg_len; - mbinfo->dseg_len = info.dseg_len; - mbinfo->cseg_16_len = info.cseg_16_len; - mbinfo->version = info.version; - - ptrorig += ALIGN_UP (sizeof (struct multiboot_apm_info), 4); - ptrdest += ALIGN_UP (sizeof (struct multiboot_apm_info), 4); - } - } -#endif - - 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_multiboot_get_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; - } - - { - struct grub_net_network_level_interface *net; - FOR_NET_NETWORK_LEVEL_INTERFACES(net) - if (net->dhcp_ack) - { - grub_memcpy (ptrorig, net->dhcp_ack, net->dhcp_acklen); - mbi->drives_addr = ptrdest; - mbi->drives_length = net->dhcp_acklen; - ptrorig += net->dhcp_acklen; - ptrdest += net->dhcp_acklen; - break; - } - } - - if (elf_sec_num) - { - mbi->u.elf_sec.addr = ptrdest; - grub_memcpy (ptrorig, elf_sections, elf_sec_entsize * elf_sec_num); - mbi->u.elf_sec.num = elf_sec_num; - mbi->u.elf_sec.size = elf_sec_entsize; - mbi->u.elf_sec.shndx = elf_sec_shstrndx; - - mbi->flags |= MULTIBOOT_INFO_ELF_SHDR; - - ptrorig += elf_sec_entsize * elf_sec_num; - ptrdest += elf_sec_entsize * elf_sec_num; - } - - err = retrieve_video_parameters (mbi, ptrorig, ptrdest); - if (err) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - } - - if ((mbi->flags & MULTIBOOT_INFO_FRAMEBUFFER_INFO) - && mbi->framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED) - { - ptrorig += mbi->framebuffer_palette_num_colors - * sizeof (struct multiboot_color); - ptrdest += mbi->framebuffer_palette_num_colors - * sizeof (struct multiboot_color); - } - -#if GRUB_MACHINE_HAS_VBE - ptrorig += sizeof (struct grub_vbe_info_block); - ptrdest += sizeof (struct grub_vbe_info_block); - ptrorig += sizeof (struct grub_vbe_mode_info_block); - ptrdest += sizeof (struct grub_vbe_mode_info_block); -#endif - -#ifdef GRUB_MACHINE_EFI - err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL); - if (err) - return err; -#endif - - return GRUB_ERR_NONE; -} - -void -grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize, - unsigned shndx, void *data) -{ - elf_sec_num = num; - elf_sec_shstrndx = shndx; - elf_sec_entsize = entsize; - elf_sections = data; -} - -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_free (elf_sections); - elf_sections = NULL; - elf_sec_entsize = 0; - elf_sec_num = 0; -} - -grub_err_t -grub_multiboot_init_mbi (int argc, char *argv[]) -{ - grub_ssize_t len = 0; - - grub_multiboot_free_mbi (); - - len = grub_loader_cmdline_size (argc, argv); - - cmdline = grub_malloc (len); - if (! cmdline) - return grub_errno; - cmdline_size = len; - - return grub_create_loader_cmdline (argc, argv, cmdline, - cmdline_size, GRUB_VERIFY_KERNEL_CMDLINE); -} - -grub_err_t -grub_multiboot_add_module (grub_addr_t start, grub_size_t size, - int argc, char *argv[]) -{ - struct module *newmod; - grub_size_t len = 0; - grub_err_t err; - - newmod = grub_malloc (sizeof (*newmod)); - if (!newmod) - return grub_errno; - newmod->start = start; - newmod->size = size; - newmod->next = 0; - - len = grub_loader_cmdline_size (argc, argv); - - newmod->cmdline = grub_malloc (len); - if (! newmod->cmdline) - { - grub_free (newmod); - return grub_errno; - } - newmod->cmdline_size = len; - total_modcmd += ALIGN_UP (len, 4); - - err = grub_create_loader_cmdline (argc, argv, newmod->cmdline, - newmod->cmdline_size, GRUB_VERIFY_MODULE_CMDLINE); - if (err) - { - grub_free (newmod); - return grub_errno; - } - - if (modules_last) - modules_last->next = newmod; - else - modules = newmod; - 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 deleted file mode 100644 index a38389999..000000000 --- a/grub-core/loader/i386/pc/chainloader.c +++ /dev/null @@ -1,310 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_dl_t my_mod; -static int boot_drive; -static grub_addr_t boot_part_addr; -static struct grub_relocator *rel; - -typedef enum - { - GRUB_CHAINLOADER_FORCE = 0x1, - GRUB_CHAINLOADER_BPB = 0x2, - } grub_chainloader_flags_t; - -static grub_err_t -grub_chainloader_boot (void) -{ - struct grub_relocator16_state state = { - .edx = boot_drive, - .esi = boot_part_addr, - .ds = 0, - .es = 0, - .fs = 0, - .gs = 0, - .ss = 0, - .cs = 0, - .sp = GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR, - .ip = GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR, - .a20 = 0 - }; - grub_video_set_mode ("text", 0, 0); - - return grub_relocator16_boot (rel, state); -} - -static grub_err_t -grub_chainloader_unload (void) -{ - grub_relocator_unload (rel); - rel = NULL; - grub_dl_unref (my_mod); - return GRUB_ERR_NONE; -} - -void -grub_chainloader_patch_bpb (void *bs, grub_device_t dev, grub_uint8_t dl) -{ - grub_uint32_t part_start = 0, heads = 0, sectors = 0; - if (dev && dev->disk) - { - part_start = grub_partition_get_start (dev->disk->partition); - if (dev->disk->data) - { - heads = ((struct grub_biosdisk_data *)(dev->disk->data))->heads; - sectors = ((struct grub_biosdisk_data *)(dev->disk->data))->sectors; - } - } - if (grub_memcmp ((char *) &((struct grub_ntfs_bpb *) bs)->oem_name, - "NTFS", 4) == 0) - { - struct grub_ntfs_bpb *bpb = (struct grub_ntfs_bpb *) bs; - bpb->num_hidden_sectors = grub_cpu_to_le32 (part_start); - bpb->bios_drive = dl; - return; - } - - do - { - struct grub_fat_bpb *bpb = (struct grub_fat_bpb *) bs; - 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)) - break; - - if (grub_le_to_cpu16 (bpb->bytes_per_sector) < 512 - || (grub_le_to_cpu16 (bpb->bytes_per_sector) - & (grub_le_to_cpu16 (bpb->bytes_per_sector) - 1))) - break; - - if (bpb->sectors_per_cluster == 0 - || (bpb->sectors_per_cluster & (bpb->sectors_per_cluster - 1))) - break; - - if (bpb->num_reserved_sectors == 0) - break; - if (bpb->num_total_sectors_16 == 0 && bpb->num_total_sectors_32 == 0) - break; - - if (bpb->num_fats == 0) - break; - - if (bpb->sectors_per_fat_16) - { - bpb->num_hidden_sectors = grub_cpu_to_le32 (part_start); - bpb->version_specific.fat12_or_fat16.num_ph_drive = dl; - if (sectors) - bpb->sectors_per_track = grub_cpu_to_le16 (sectors); - if (heads) - bpb->num_heads = grub_cpu_to_le16 (heads); - return; - } - if (bpb->version_specific.fat32.sectors_per_fat_32) - { - bpb->num_hidden_sectors = grub_cpu_to_le32 (part_start); - bpb->version_specific.fat32.num_ph_drive = dl; - if (sectors) - bpb->sectors_per_track = grub_cpu_to_le16 (sectors); - if (heads) - bpb->num_heads = grub_cpu_to_le16 (heads); - return; - } - break; - } - while (0); -} - -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; - grub_addr_t part_addr = 0; - grub_uint8_t *bs, *ptable; - - rel = grub_relocator_new (); - if (!rel) - goto fail; - - grub_dl_ref (my_mod); - - file = grub_file_open (filename, GRUB_FILE_TYPE_PCCHAINLOADER - | GRUB_FILE_TYPE_NO_DECOMPRESS); - if (! file) - goto fail; - - { - grub_relocator_chunk_t ch; - grub_err_t err; - - err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7C00, - GRUB_DISK_SECTOR_SIZE); - if (err) - goto fail; - bs = get_virtual_current_address (ch); - err = grub_relocator_alloc_chunk_addr (rel, &ch, - GRUB_MEMORY_MACHINE_PART_TABLE_ADDR, - 64); - if (err) - goto fail; - ptable = get_virtual_current_address (ch); - } - - /* Read the first block. */ - if (grub_file_read (file, bs, GRUB_DISK_SECTOR_SIZE) - != GRUB_DISK_SECTOR_SIZE) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - - goto fail; - } - - /* Check the signature. */ - signature = *((grub_uint16_t *) (bs + 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, ptable); - part_addr = (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR - + (p->index << 4)); - disk->partition = p; - } - } - } - - if (flags & GRUB_CHAINLOADER_BPB) - grub_chainloader_patch_bpb ((void *) 0x7C00, dev, drive); - - 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; - - while (argc > 0) - { - if (grub_strcmp (argv[0], "--force") == 0) - { - flags |= GRUB_CHAINLOADER_FORCE; - argc--; - argv++; - continue; - } - if (grub_strcmp (argv[0], "--bpb") == 0) - { - flags |= GRUB_CHAINLOADER_BPB; - argc--; - argv++; - continue; - } - break; - } - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - 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, - N_("[--force|--bpb] FILE"), - N_("Load another boot loader.")); - my_mod = mod; -} - -GRUB_MOD_FINI(chainloader) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/loader/i386/pc/freedos.c b/grub-core/loader/i386/pc/freedos.c deleted file mode 100644 index f2242dc51..000000000 --- a/grub-core/loader/i386/pc/freedos.c +++ /dev/null @@ -1,190 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_dl_t my_mod; -static struct grub_relocator *rel; -static grub_uint32_t ebx = 0xffffffff; - -#define GRUB_FREEDOS_SEGMENT 0x60 -#define GRUB_FREEDOS_ADDR (GRUB_FREEDOS_SEGMENT << 4) -#define GRUB_FREEDOS_STACK_SEGMENT 0x1fe0 -#define GRUB_FREEDOS_STACK_BPB_POINTER 0x7c00 -#define GRUB_FREEDOS_BPB_ADDR ((GRUB_FREEDOS_STACK_SEGMENT << 4) \ - + GRUB_FREEDOS_STACK_BPB_POINTER) - -/* FreeDOS boot.asm passes register sp as exactly this. Importantly, - it must point below the BPB (to avoid overwriting any of it). */ -#define GRUB_FREEDOS_STACK_POINTER (GRUB_FREEDOS_STACK_BPB_POINTER \ - - 0x60) - -/* In this, the additional 8192 bytes are the stack reservation; the - remaining parts trivially give the maximum allowed size. */ -#define GRUB_FREEDOS_MAX_SIZE ((GRUB_FREEDOS_STACK_SEGMENT << 4) \ - + GRUB_FREEDOS_STACK_POINTER \ - - GRUB_FREEDOS_ADDR \ - - 8192) - -static grub_err_t -grub_freedos_boot (void) -{ - struct grub_relocator16_state state = { - .cs = GRUB_FREEDOS_SEGMENT, - .ip = 0, - - .ds = GRUB_FREEDOS_STACK_SEGMENT, - .es = 0, - .fs = 0, - .gs = 0, - .ss = GRUB_FREEDOS_STACK_SEGMENT, - .sp = GRUB_FREEDOS_STACK_POINTER, - .ebp = GRUB_FREEDOS_STACK_BPB_POINTER, - .ebx = ebx, - .edx = ebx, - .a20 = 1 - }; - grub_video_set_mode ("text", 0, 0); - - return grub_relocator16_boot (rel, state); -} - -static grub_err_t -grub_freedos_unload (void) -{ - grub_relocator_unload (rel); - rel = NULL; - grub_dl_unref (my_mod); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_file_t file = 0; - grub_err_t err; - void *bs, *kernelsys; - grub_size_t kernelsyssize; - grub_device_t dev; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - grub_dl_ref (my_mod); - - rel = grub_relocator_new (); - if (!rel) - goto fail; - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_FREEDOS); - if (! file) - goto fail; - - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_FREEDOS_BPB_ADDR, - GRUB_DISK_SECTOR_SIZE); - if (err) - goto fail; - bs = get_virtual_current_address (ch); - } - - ebx = grub_get_root_biosnumber (); - dev = grub_device_open (0); - - if (dev && dev->disk) - { - err = grub_disk_read (dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, bs); - if (err) - { - grub_device_close (dev); - goto fail; - } - grub_chainloader_patch_bpb (bs, dev, ebx); - } - - if (dev) - grub_device_close (dev); - - kernelsyssize = grub_file_size (file); - - if (kernelsyssize > GRUB_FREEDOS_MAX_SIZE) - { - grub_error (GRUB_ERR_BAD_OS, - N_("the size of `%s' is too large"), argv[0]); - goto fail; - } - - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_FREEDOS_ADDR, - kernelsyssize); - if (err) - goto fail; - kernelsys = get_virtual_current_address (ch); - } - - if (grub_file_read (file, kernelsys, kernelsyssize) - != (grub_ssize_t) kernelsyssize) - goto fail; - - grub_loader_set (grub_freedos_boot, grub_freedos_unload, 1); - return GRUB_ERR_NONE; - - fail: - - if (file) - grub_file_close (file); - - grub_freedos_unload (); - - return grub_errno; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(freedos) -{ - cmd = grub_register_command ("freedos", grub_cmd_freedos, - 0, N_("Load FreeDOS kernel.sys.")); - my_mod = mod; -} - -GRUB_MOD_FINI(freedos) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c deleted file mode 100644 index 0c2a4ae51..000000000 --- a/grub-core/loader/i386/pc/linux.c +++ /dev/null @@ -1,494 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define GRUB_LINUX_CL_OFFSET 0x9000 - -static grub_dl_t my_mod; - -static grub_size_t linux_mem_size; -static int loaded; -static struct grub_relocator *relocator = NULL; -static grub_addr_t grub_linux_real_target; -static char *grub_linux_real_chunk; -static grub_size_t grub_linux16_prot_size; -static grub_size_t maximal_cmdline_size; - -static grub_err_t -grub_linux16_boot (void) -{ - grub_uint16_t segment; - struct grub_relocator16_state state = {0}; - - segment = grub_linux_real_target >> 4; - state.gs = state.fs = state.es = state.ds = state.ss = segment; - state.sp = GRUB_LINUX_SETUP_STACK; - state.cs = segment + 0x20; - state.ip = 0; - state.a20 = 1; - - grub_video_set_mode ("text", 0, 0); - - grub_stop_floppy (); - - return grub_relocator16_boot (relocator, state); -} - -static grub_err_t -grub_linux_unload (void) -{ - grub_dl_unref (my_mod); - loaded = 0; - grub_relocator_unload (relocator); - relocator = NULL; - return GRUB_ERR_NONE; -} - -static int -target_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, - void *data) -{ - grub_uint64_t *result = data; - grub_uint64_t candidate; - - if (type != GRUB_MEMORY_AVAILABLE) - return 0; - if (addr >= 0xa0000) - return 0; - if (addr + size >= 0xa0000) - size = 0xa0000 - addr; - - /* Put the real mode part at as a high location as possible. */ - candidate = addr + size - (GRUB_LINUX_CL_OFFSET + maximal_cmdline_size); - /* But it must not exceed the traditional area. */ - if (candidate > GRUB_LINUX_OLD_REAL_MODE_ADDR) - candidate = GRUB_LINUX_OLD_REAL_MODE_ADDR; - if (candidate < addr) - return 0; - - if (candidate > *result || *result == (grub_uint64_t) -1) - *result = candidate; - return 0; -} - -static grub_addr_t -grub_find_real_target (void) -{ - grub_uint64_t result = (grub_uint64_t) -1; - - grub_mmap_iterate (target_hook, &result); - return result; -} - -static grub_err_t -grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_file_t file = 0; - struct linux_i386_kernel_header lh; - grub_uint8_t setup_sects; - grub_size_t real_size; - grub_ssize_t len; - int i; - char *grub_linux_prot_chunk; - int grub_linux_is_bzimage; - grub_addr_t grub_linux_prot_target; - grub_err_t err; - - grub_dl_ref (my_mod); - - if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); - if (! file) - goto fail; - - if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - argv[0]); - goto fail; - } - - if (lh.boot_flag != grub_cpu_to_le16_compile_time (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; - - maximal_cmdline_size = 256; - - if (lh.header == grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_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; - - if (grub_le_to_cpu16 (lh.version) >= 0x0206) - maximal_cmdline_size = grub_le_to_cpu32 (lh.cmdline_size) + 1; - - grub_linux_real_target = grub_find_real_target (); - if (grub_linux_real_target == (grub_addr_t)-1) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, - "no appropriate low memory found"); - goto fail; - } - - if (grub_le_to_cpu16 (lh.version) >= 0x0201) - { - lh.heap_end_ptr = grub_cpu_to_le16_compile_time (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_target + GRUB_LINUX_CL_OFFSET; - else - { - lh.cl_magic = grub_cpu_to_le16_compile_time (GRUB_LINUX_CL_MAGIC); - lh.cl_offset = grub_cpu_to_le16_compile_time (GRUB_LINUX_CL_OFFSET); - lh.setup_move_size = grub_cpu_to_le16_compile_time (GRUB_LINUX_CL_OFFSET - + maximal_cmdline_size); - } - } - else - { - /* Your kernel is quite old... */ - lh.cl_magic = grub_cpu_to_le16_compile_time (GRUB_LINUX_CL_MAGIC); - lh.cl_offset = grub_cpu_to_le16_compile_time (GRUB_LINUX_CL_OFFSET); - - setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS; - - grub_linux_real_target = 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; - if (grub_sub (grub_file_size (file), real_size, &grub_linux16_prot_size) || - grub_sub (grub_linux16_prot_size, GRUB_DISK_SECTOR_SIZE, &grub_linux16_prot_size)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); - goto fail; - } - - if (! grub_linux_is_bzimage - && GRUB_LINUX_ZIMAGE_ADDR + grub_linux16_prot_size - > grub_linux_real_target) - { - grub_error (GRUB_ERR_BAD_OS, "too big zImage (0x%" PRIxGRUB_SIZE - " > 0x%" PRIxGRUB_ADDR "), use bzImage instead", - GRUB_LINUX_ZIMAGE_ADDR + grub_linux16_prot_size, - grub_linux_real_target); - goto fail; - } - - grub_dprintf ("linux", "[Linux-%s, setup=0x%x, size=0x%x]\n", - grub_linux_is_bzimage ? "bzImage" : "zImage", - (unsigned) real_size, - (unsigned) grub_linux16_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) - { - const 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; - /* Fallthrough. */ - case 'm': - shift += 10; - /* Fallthrough. */ - case 'k': - shift += 10; - /* Fallthrough. */ - default: - break; - } - - /* Check an overflow. */ - if (linux_mem_size > (~0UL >> shift)) - linux_mem_size = 0; - else - linux_mem_size <<= shift; - } - } - - relocator = grub_relocator_new (); - if (!relocator) - goto fail; - - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, - grub_linux_real_target, - GRUB_LINUX_CL_OFFSET - + maximal_cmdline_size); - if (err) - return err; - grub_linux_real_chunk = get_virtual_current_address (ch); - } - - /* Put the real mode code at the temporary address. */ - grub_memmove (grub_linux_real_chunk, &lh, sizeof (lh)); - - len = real_size + GRUB_DISK_SECTOR_SIZE - sizeof (lh); - if (grub_file_read (file, grub_linux_real_chunk + sizeof (lh), len) != len) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - argv[0]); - goto fail; - } - - if (lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) - || grub_le_to_cpu16 (lh.version) < 0x0200) - /* Clear the heap space. */ - grub_memset (grub_linux_real_chunk - + ((setup_sects + 1) << GRUB_DISK_SECTOR_BITS), - 0, - ((GRUB_LINUX_MAX_SETUP_SECTS - setup_sects - 1) - << GRUB_DISK_SECTOR_BITS)); - - /* Create kernel command line. */ - grub_memcpy ((char *)grub_linux_real_chunk + GRUB_LINUX_CL_OFFSET, - LINUX_IMAGE, sizeof (LINUX_IMAGE)); - err = grub_create_loader_cmdline (argc, argv, - (char *)grub_linux_real_chunk - + GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1, - maximal_cmdline_size - - (sizeof (LINUX_IMAGE) - 1), - GRUB_VERIFY_KERNEL_CMDLINE); - if (err) - goto fail; - - if (grub_linux_is_bzimage) - grub_linux_prot_target = GRUB_LINUX_BZIMAGE_ADDR; - else - grub_linux_prot_target = GRUB_LINUX_ZIMAGE_ADDR; - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, - grub_linux_prot_target, - grub_linux16_prot_size); - if (err) - return err; - grub_linux_prot_chunk = get_virtual_current_address (ch); - } - - len = grub_linux16_prot_size; - if (grub_file_read (file, grub_linux_prot_chunk, len) != len && !grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - argv[0]); - - if (grub_errno == GRUB_ERR_NONE) - { - grub_loader_set (grub_linux16_boot, grub_linux_unload, 0); - loaded = 1; - } - - fail: - - if (file) - grub_file_close (file); - - if (grub_errno != GRUB_ERR_NONE) - { - grub_dl_unref (my_mod); - loaded = 0; - grub_relocator_unload (relocator); - } - - return grub_errno; -} - -static grub_err_t -grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_size_t size = 0; - grub_addr_t addr_max, addr_min; - struct linux_i386_kernel_header *lh; - grub_uint8_t *initrd_chunk; - grub_addr_t initrd_addr; - grub_err_t err; - struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; - - if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - if (!loaded) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); - goto fail; - } - - lh = (struct linux_i386_kernel_header *) grub_linux_real_chunk; - - if (!(lh->header == grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_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; - - addr_min = GRUB_LINUX_BZIMAGE_ADDR + grub_linux16_prot_size; - - if (grub_initrd_init (argc, argv, &initrd_ctx)) - goto fail; - - size = grub_get_initrd_size (&initrd_ctx); - - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_align_safe (relocator, &ch, addr_min, addr_max, size, - 0x1000, GRUB_RELOCATOR_PREFERENCE_HIGH, 0); - if (err) - goto fail; - initrd_chunk = get_virtual_current_address (ch); - initrd_addr = get_physical_target_address (ch); - } - - if (grub_initrd_load (&initrd_ctx, initrd_chunk)) - goto fail; - - lh->ramdisk_image = initrd_addr; - lh->ramdisk_size = size; - - fail: - grub_initrd_close (&initrd_ctx); - - 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/ntldr.c b/grub-core/loader/i386/pc/ntldr.c deleted file mode 100644 index 2b1dec62a..000000000 --- a/grub-core/loader/i386/pc/ntldr.c +++ /dev/null @@ -1,162 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_dl_t my_mod; -static struct grub_relocator *rel; -static grub_uint32_t edx = 0xffffffff; - -#define GRUB_NTLDR_SEGMENT 0x2000 - -static grub_err_t -grub_ntldr_boot (void) -{ - struct grub_relocator16_state state = { - .cs = GRUB_NTLDR_SEGMENT, - .ip = 0, - .ds = 0, - .es = 0, - .fs = 0, - .gs = 0, - .ss = 0, - .sp = 0x7c00, - .edx = edx, - .a20 = 1 - }; - grub_video_set_mode ("text", 0, 0); - - return grub_relocator16_boot (rel, state); -} - -static grub_err_t -grub_ntldr_unload (void) -{ - grub_relocator_unload (rel); - rel = NULL; - grub_dl_unref (my_mod); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_file_t file = 0; - grub_err_t err; - void *bs, *ntldr; - grub_size_t ntldrsize; - grub_device_t dev; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - grub_dl_ref (my_mod); - - rel = grub_relocator_new (); - if (!rel) - goto fail; - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_NTLDR); - if (! file) - goto fail; - - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7C00, - GRUB_DISK_SECTOR_SIZE); - if (err) - goto fail; - bs = get_virtual_current_address (ch); - } - - edx = grub_get_root_biosnumber (); - dev = grub_device_open (0); - - if (dev && dev->disk) - { - err = grub_disk_read (dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, bs); - if (err) - { - grub_device_close (dev); - goto fail; - } - grub_chainloader_patch_bpb (bs, dev, edx); - } - - if (dev) - grub_device_close (dev); - - ntldrsize = grub_file_size (file); - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_NTLDR_SEGMENT << 4, - ntldrsize); - if (err) - goto fail; - ntldr = get_virtual_current_address (ch); - } - - if (grub_file_read (file, ntldr, ntldrsize) - != (grub_ssize_t) ntldrsize) - goto fail; - - grub_loader_set (grub_ntldr_boot, grub_ntldr_unload, 1); - return GRUB_ERR_NONE; - - fail: - - if (file) - grub_file_close (file); - - grub_ntldr_unload (); - - return grub_errno; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(ntldr) -{ - cmd = grub_register_command ("ntldr", grub_cmd_ntldr, - 0, N_("Load NTLDR or BootMGR.")); - my_mod = mod; -} - -GRUB_MOD_FINI(ntldr) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c deleted file mode 100644 index 960e866f4..000000000 --- a/grub-core/loader/i386/pc/plan9.c +++ /dev/null @@ -1,607 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_dl_t my_mod; -static struct grub_relocator *rel; -static grub_uint32_t eip = 0xffffffff; - -#define GRUB_PLAN9_TARGET 0x100000 -#define GRUB_PLAN9_ALIGN 4096 -#define GRUB_PLAN9_CONFIG_ADDR 0x001200 -#define GRUB_PLAN9_CONFIG_PATH_SIZE 0x000040 -#define GRUB_PLAN9_CONFIG_MAGIC "ZORT 0\r\n" - -static const struct grub_arg_option options[] = - { - {"map", 'm', GRUB_ARG_OPTION_REPEATABLE, - /* TRANSLATORS: it's about guessing which GRUB disk - is which Plan9 disk. If your language has no - word "mapping" you can use another word which - means that the GRUBDEVICE and PLAN9DEVICE are - actually the same device, just named differently - in OS and GRUB. */ - N_("Override guessed mapping of Plan9 devices."), - N_("GRUBDEVICE=PLAN9DEVICE"), - ARG_TYPE_STRING}, - {0, 0, 0, 0, 0, 0} - }; - -struct grub_plan9_header -{ - grub_uint32_t magic; -#define GRUB_PLAN9_MAGIC 0x1eb - grub_uint32_t text_size; - grub_uint32_t data_size; - grub_uint32_t bss_size; - grub_uint32_t sectiona; - grub_uint32_t entry_addr; - grub_uint32_t zero; - grub_uint32_t sectionb; -}; - -static grub_err_t -grub_plan9_boot (void) -{ - struct grub_relocator32_state state = { - .eax = 0, - .eip = eip, - .ebx = 0, - .ecx = 0, - .edx = 0, - .edi = 0, - .esp = 0, - .ebp = 0, - .esi = 0 - }; - grub_video_set_mode ("text", 0, 0); - - return grub_relocator32_boot (rel, state, 0); -} - -static grub_err_t -grub_plan9_unload (void) -{ - grub_relocator_unload (rel); - rel = NULL; - grub_dl_unref (my_mod); - return GRUB_ERR_NONE; -} - -/* Context for grub_cmd_plan9. */ -struct grub_cmd_plan9_ctx -{ - grub_extcmd_context_t ctxt; - grub_file_t file; - char *pmap; - grub_size_t pmapalloc; - grub_size_t pmapptr; - int noslash; - int prefixescnt[5]; - char *bootdisk, *bootpart; -}; - -static const char prefixes[5][10] = { - "dos", "plan9", "ntfs", "linux", "linuxswap" -}; - -#include - -static inline grub_err_t -grub_extend_alloc (grub_size_t sz, grub_size_t *allocated, char **ptr) -{ - void *n; - if (sz < *allocated) - return GRUB_ERR_NONE; - - *allocated = 2 * sz; - n = grub_realloc (*ptr, *allocated); - if (!n) - return grub_errno; - *ptr = n; - return GRUB_ERR_NONE; -} - -/* Helper for grub_cmd_plan9. */ -static int -fill_partition (grub_disk_t disk, const grub_partition_t partition, void *data) -{ - struct grub_cmd_plan9_ctx *fill_ctx = data; - int file_disk = 0; - int pstart, pend; - - if (!fill_ctx->noslash) - { - if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc, - &fill_ctx->pmap)) - return 1; - fill_ctx->pmap[fill_ctx->pmapptr++] = '/'; - } - fill_ctx->noslash = 0; - - file_disk = fill_ctx->file->device->disk - && disk->id == fill_ctx->file->device->disk->id - && disk->dev->id == fill_ctx->file->device->disk->dev->id; - - pstart = fill_ctx->pmapptr; - if (grub_strcmp (partition->partmap->name, "plan") == 0) - { - unsigned ptr = partition->index + sizeof ("part ") - 1; - grub_err_t err; - disk->partition = partition->parent; - do - { - if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc, - &fill_ctx->pmap)) - return 1; - err = grub_disk_read (disk, 1, ptr, 1, - fill_ctx->pmap + fill_ctx->pmapptr); - if (err) - { - disk->partition = 0; - return err; - } - ptr++; - fill_ctx->pmapptr++; - } - while (grub_isalpha (fill_ctx->pmap[fill_ctx->pmapptr - 1]) - || grub_isdigit (fill_ctx->pmap[fill_ctx->pmapptr - 1])); - fill_ctx->pmapptr--; - } - else - { - char name[50]; - int c = 0; - if (grub_strcmp (partition->partmap->name, "msdos") == 0) - { - switch (partition->msdostype) - { - case GRUB_PC_PARTITION_TYPE_PLAN9: - c = 1; - break; - case GRUB_PC_PARTITION_TYPE_NTFS: - c = 2; - break; - case GRUB_PC_PARTITION_TYPE_MINIX: - case GRUB_PC_PARTITION_TYPE_LINUX_MINIX: - case GRUB_PC_PARTITION_TYPE_EXT2FS: - c = 3; - break; - case GRUB_PC_PARTITION_TYPE_LINUX_SWAP: - c = 4; - break; - } - } - - if (fill_ctx->prefixescnt[c] == 0) - grub_strcpy (name, prefixes[c]); - else - grub_snprintf (name, sizeof (name), "%s.%d", prefixes[c], - fill_ctx->prefixescnt[c]); - fill_ctx->prefixescnt[c]++; - if (grub_extend_alloc (fill_ctx->pmapptr + grub_strlen (name) + 1, - &fill_ctx->pmapalloc, &fill_ctx->pmap)) - return 1; - grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, name); - fill_ctx->pmapptr += grub_strlen (name); - } - pend = fill_ctx->pmapptr; - if (grub_extend_alloc (fill_ctx->pmapptr + 2 + 25 + 5 + 25, - &fill_ctx->pmapalloc, &fill_ctx->pmap)) - return 1; - fill_ctx->pmap[fill_ctx->pmapptr++] = ' '; - grub_snprintf (fill_ctx->pmap + fill_ctx->pmapptr, 25 + 5 + 25, - "%" PRIuGRUB_UINT64_T " %" PRIuGRUB_UINT64_T, - grub_partition_get_start (partition), - grub_partition_get_start (partition) - + grub_partition_get_len (partition)); - if (file_disk && grub_partition_get_start (partition) - == grub_partition_get_start (fill_ctx->file->device->disk->partition) - && grub_partition_get_len (partition) - == grub_partition_get_len (fill_ctx->file->device->disk->partition)) - { - grub_free (fill_ctx->bootpart); - fill_ctx->bootpart = grub_strndup (fill_ctx->pmap + pstart, - pend - pstart); - } - - fill_ctx->pmapptr += grub_strlen (fill_ctx->pmap + fill_ctx->pmapptr); - return 0; -} - -/* Helper for grub_cmd_plan9. */ -static int -fill_disk (const char *name, void *data) -{ - struct grub_cmd_plan9_ctx *fill_ctx = data; - grub_device_t dev; - char *plan9name = NULL; - unsigned i; - int file_disk = 0; - - dev = grub_device_open (name); - if (!dev) - { - grub_print_error (); - return 0; - } - if (!dev->disk) - { - grub_device_close (dev); - return 0; - } - file_disk = fill_ctx->file->device->disk - && dev->disk->id == fill_ctx->file->device->disk->id - && dev->disk->dev->id == fill_ctx->file->device->disk->dev->id; - for (i = 0; - fill_ctx->ctxt->state[0].args && fill_ctx->ctxt->state[0].args[i]; i++) - if (grub_strncmp (name, fill_ctx->ctxt->state[0].args[i], - grub_strlen (name)) == 0 - && fill_ctx->ctxt->state[0].args[i][grub_strlen (name)] == '=') - break; - if (fill_ctx->ctxt->state[0].args && fill_ctx->ctxt->state[0].args[i]) - plan9name = grub_strdup (fill_ctx->ctxt->state[0].args[i] - + grub_strlen (name) + 1); - else - switch (dev->disk->dev->id) - { - case GRUB_DISK_DEVICE_BIOSDISK_ID: - if (dev->disk->id & 0x80) - plan9name = grub_xasprintf ("sdB%u", - (unsigned) (dev->disk->id & 0x7f)); - else - plan9name = grub_xasprintf ("fd%u", - (unsigned) (dev->disk->id & 0x7f)); - break; - /* Shouldn't happen as Plan9 doesn't work on these platforms. */ - case GRUB_DISK_DEVICE_OFDISK_ID: - case GRUB_DISK_DEVICE_EFIDISK_ID: - - /* Plan9 doesn't see those. */ - default: - - /* Not sure how to handle those. */ - case GRUB_DISK_DEVICE_NAND_ID: - if (!file_disk) - { - grub_device_close (dev); - return 0; - } - - /* if it's the disk the kernel is loaded from we need to name - it nevertheless. */ - plan9name = grub_strdup ("sdZ0"); - break; - - case GRUB_DISK_DEVICE_ATA_ID: - { - unsigned unit; - if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) - unit = 0; - else - unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0); - plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); - } - break; - case GRUB_DISK_DEVICE_SCSI_ID: - if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff) - == GRUB_SCSI_SUBSYSTEM_PATA) - { - unsigned unit; - if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) - unit = 0; - else - unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, - 0, 0); - plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); - break; - } - - /* FIXME: how does Plan9 number controllers? - We probably need save the SCSI devices and sort them */ - plan9name - = grub_xasprintf ("sd0%u", (unsigned) - ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT) - & 0xf)); - break; - } - if (!plan9name) - { - grub_print_error (); - grub_device_close (dev); - return 0; - } - if (grub_extend_alloc (fill_ctx->pmapptr + grub_strlen (plan9name) - + sizeof ("part="), &fill_ctx->pmapalloc, - &fill_ctx->pmap)) - { - grub_free (plan9name); - grub_device_close (dev); - return 1; - } - grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, plan9name); - fill_ctx->pmapptr += grub_strlen (plan9name); - if (!file_disk) - grub_free (plan9name); - else - { - grub_free (fill_ctx->bootdisk); - fill_ctx->bootdisk = plan9name; - } - grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, "part="); - fill_ctx->pmapptr += sizeof ("part=") - 1; - - fill_ctx->noslash = 1; - grub_memset (fill_ctx->prefixescnt, 0, sizeof (fill_ctx->prefixescnt)); - if (grub_partition_iterate (dev->disk, fill_partition, fill_ctx)) - { - grub_device_close (dev); - return 1; - } - if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc, - &fill_ctx->pmap)) - { - grub_device_close (dev); - return 1; - } - fill_ctx->pmap[fill_ctx->pmapptr++] = '\n'; - - grub_device_close (dev); - return 0; -} - -static grub_err_t -grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) -{ - struct grub_cmd_plan9_ctx fill_ctx = { - .ctxt = ctxt, - .file = 0, - .pmap = NULL, - .pmapalloc = 256, - .pmapptr = 0, - .noslash = 1, - .bootdisk = NULL, - .bootpart = NULL - }; - void *mem; - grub_size_t memsize, padsize; - struct grub_plan9_header hdr; - char *config, *configptr; - grub_size_t configsize; - char *bootpath = NULL; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - grub_dl_ref (my_mod); - - rel = grub_relocator_new (); - if (!rel) - goto fail; - - fill_ctx.file = grub_file_open (argv[0], GRUB_FILE_TYPE_PLAN9_KERNEL); - if (! fill_ctx.file) - goto fail; - - fill_ctx.pmap = grub_malloc (fill_ctx.pmapalloc); - if (!fill_ctx.pmap) - goto fail; - - if (grub_disk_dev_iterate (fill_disk, &fill_ctx)) - goto fail; - - if (grub_extend_alloc (fill_ctx.pmapptr + 1, &fill_ctx.pmapalloc, - &fill_ctx.pmap)) - goto fail; - fill_ctx.pmap[fill_ctx.pmapptr] = 0; - - { - char *file_name = grub_strchr (argv[0], ')'); - if (file_name) - file_name++; - else - file_name = argv[0]; - if (*file_name) - file_name++; - - if (fill_ctx.bootpart) - bootpath = grub_xasprintf ("%s!%s!%s", fill_ctx.bootdisk, - fill_ctx.bootpart, file_name); - else - bootpath = grub_xasprintf ("%s!%s", fill_ctx.bootdisk, file_name); - grub_free (fill_ctx.bootdisk); - grub_free (fill_ctx.bootpart); - } - if (!bootpath) - goto fail; - - if (grub_file_read (fill_ctx.file, &hdr, - sizeof (hdr)) != (grub_ssize_t) sizeof (hdr)) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - argv[0]); - goto fail; - } - - if (grub_be_to_cpu32 (hdr.magic) != GRUB_PLAN9_MAGIC - || hdr.zero) - { - grub_error (GRUB_ERR_BAD_OS, "unsupported Plan9"); - goto fail; - } - - memsize = ALIGN_UP (grub_be_to_cpu32 (hdr.text_size) + sizeof (hdr), - GRUB_PLAN9_ALIGN); - memsize += ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), GRUB_PLAN9_ALIGN); - memsize += ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), GRUB_PLAN9_ALIGN); - eip = grub_be_to_cpu32 (hdr.entry_addr) & 0xfffffff; - - /* path */ - configsize = GRUB_PLAN9_CONFIG_PATH_SIZE; - /* magic */ - configsize += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; - { - int i; - for (i = 1; i < argc; i++) - configsize += grub_strlen (argv[i]) + 1; - } - configsize += (sizeof ("bootfile=") - 1) + grub_strlen (bootpath) + 1; - configsize += fill_ctx.pmapptr; - /* Terminating \0. */ - configsize++; - - { - grub_relocator_chunk_t ch; - grub_err_t err; - err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_PLAN9_CONFIG_ADDR, - configsize); - if (err) - goto fail; - config = get_virtual_current_address (ch); - } - - grub_memset (config, 0, GRUB_PLAN9_CONFIG_PATH_SIZE); - grub_strncpy (config, bootpath, GRUB_PLAN9_CONFIG_PATH_SIZE - 1); - - configptr = config + GRUB_PLAN9_CONFIG_PATH_SIZE; - grub_memcpy (configptr, GRUB_PLAN9_CONFIG_MAGIC, - sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1); - configptr += sizeof (GRUB_PLAN9_CONFIG_MAGIC) - 1; - configptr = grub_stpcpy (configptr, "bootfile="); - configptr = grub_stpcpy (configptr, bootpath); - *configptr++ = '\n'; - char *cmdline = configptr; - { - int i; - for (i = 1; i < argc; i++) - { - configptr = grub_stpcpy (configptr, argv[i]); - *configptr++ = '\n'; - } - } - - { - grub_err_t err; - *configptr = '\0'; - err = grub_verify_string (cmdline, GRUB_VERIFY_KERNEL_CMDLINE); - if (err) - goto fail; - } - - configptr = grub_stpcpy (configptr, fill_ctx.pmap); - - { - grub_relocator_chunk_t ch; - grub_err_t err; - - err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_PLAN9_TARGET, - memsize); - if (err) - goto fail; - mem = get_virtual_current_address (ch); - } - - { - grub_uint8_t *ptr; - ptr = mem; - grub_memcpy (ptr, &hdr, sizeof (hdr)); - ptr += sizeof (hdr); - - if (grub_file_read (fill_ctx.file, ptr, grub_be_to_cpu32 (hdr.text_size)) - != (grub_ssize_t) grub_be_to_cpu32 (hdr.text_size)) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - argv[0]); - goto fail; - } - ptr += grub_be_to_cpu32 (hdr.text_size); - padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.text_size) + sizeof (hdr), - GRUB_PLAN9_ALIGN) - grub_be_to_cpu32 (hdr.text_size) - - sizeof (hdr); - - grub_memset (ptr, 0, padsize); - ptr += padsize; - - if (grub_file_read (fill_ctx.file, ptr, grub_be_to_cpu32 (hdr.data_size)) - != (grub_ssize_t) grub_be_to_cpu32 (hdr.data_size)) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - argv[0]); - goto fail; - } - ptr += grub_be_to_cpu32 (hdr.data_size); - padsize = ALIGN_UP (grub_be_to_cpu32 (hdr.data_size), GRUB_PLAN9_ALIGN) - - grub_be_to_cpu32 (hdr.data_size); - - grub_memset (ptr, 0, padsize); - ptr += padsize; - grub_memset (ptr, 0, ALIGN_UP(grub_be_to_cpu32 (hdr.bss_size), - GRUB_PLAN9_ALIGN)); - } - grub_loader_set (grub_plan9_boot, grub_plan9_unload, 1); - return GRUB_ERR_NONE; - - fail: - grub_free (fill_ctx.pmap); - - if (fill_ctx.file) - grub_file_close (fill_ctx.file); - - grub_plan9_unload (); - - return grub_errno; -} - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT(plan9) -{ - cmd = grub_register_extcmd ("plan9", grub_cmd_plan9, - GRUB_COMMAND_OPTIONS_AT_START, - N_("KERNEL ARGS"), N_("Load Plan9 kernel."), - options); - my_mod = mod; -} - -GRUB_MOD_FINI(plan9) -{ - grub_unregister_extcmd (cmd); -} diff --git a/grub-core/loader/i386/pc/pxechainloader.c b/grub-core/loader/i386/pc/pxechainloader.c deleted file mode 100644 index df4f7c60b..000000000 --- a/grub-core/loader/i386/pc/pxechainloader.c +++ /dev/null @@ -1,168 +0,0 @@ -/* chainloader.c - boot another boot loader */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2004,2007,2009,2010,2012 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static grub_dl_t my_mod; -static struct grub_relocator *rel; -static grub_uint32_t edx = 0xffffffff; -static char boot_file[128]; -static char server_name[64]; - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -grub_pxechain_boot (void) -{ - struct grub_relocator16_state state = { - .cs = 0, - .ip = 0x7c00, - .ds = 0, - .es = 0, - .fs = 0, - .gs = 0, - .ss = 0, - .sp = 0x7c00, - .edx = edx - }; - struct grub_net_bootp_packet *bp; - - bp = grub_pxe_get_cached (GRUB_PXENV_PACKET_TYPE_DHCP_ACK); - - grub_video_set_mode ("text", 0, 0); - - if (bp && boot_file[0]) - grub_memcpy (bp->boot_file, boot_file, sizeof (bp->boot_file)); - if (bp && server_name[0]) - grub_memcpy (bp->server_name, server_name, sizeof (bp->server_name)); - - return grub_relocator16_boot (rel, state); -} - -static grub_err_t -grub_pxechain_unload (void) -{ - grub_relocator_unload (rel); - rel = NULL; - grub_dl_unref (my_mod); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_pxechain (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_file_t file = 0; - grub_err_t err; - void *image; - grub_size_t imagesize; - char *fname; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - grub_dl_ref (my_mod); - - rel = grub_relocator_new (); - if (!rel) - goto fail; - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_PXECHAINLOADER); - if (! file) - goto fail; - - if (file->device->net && file->device->net->name) - fname = file->device->net->name; - else - { - fname = argv[0]; - if (fname[0] == '(') - { - fname = grub_strchr (fname, ')'); - if (fname) - fname++; - else - fname = argv[0]; - } - } - - grub_memset (boot_file, 0, sizeof (boot_file)); - grub_strncpy (boot_file, fname, sizeof (boot_file)); - - grub_memset (server_name, 0, sizeof (server_name)); - if (file->device->net && file->device->net->server) - grub_strncpy (server_name, file->device->net->server, sizeof (server_name)); - - edx = grub_get_root_biosnumber (); - - imagesize = grub_file_size (file); - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7c00, imagesize); - if (err) - goto fail; - image = get_virtual_current_address (ch); - } - - if (grub_file_read (file, image, imagesize) != (grub_ssize_t) imagesize) - goto fail; - - grub_loader_set (grub_pxechain_boot, grub_pxechain_unload, - GRUB_LOADER_FLAG_NORETURN | GRUB_LOADER_FLAG_PXE_NOT_UNLOAD); - return GRUB_ERR_NONE; - - fail: - - if (file) - grub_file_close (file); - - grub_pxechain_unload (); - - return grub_errno; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(pxechainloader) -{ - cmd = grub_register_command ("pxechainloader", grub_cmd_pxechain, - 0, N_("Load a PXE image.")); - my_mod = mod; -} - -GRUB_MOD_FINI(pxechainloader) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/loader/i386/pc/truecrypt.c b/grub-core/loader/i386/pc/truecrypt.c deleted file mode 100644 index bae1ad031..000000000 --- a/grub-core/loader/i386/pc/truecrypt.c +++ /dev/null @@ -1,233 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_dl_t my_mod; -static struct grub_relocator *rel; -static grub_uint32_t edx = 0xffffffff; -static grub_uint16_t sp; -static grub_uint32_t destaddr; - -#define GRUB_TRUECRYPT_SEGMENT 0x2000 - -static grub_err_t -grub_truecrypt_boot (void) -{ - grub_uint16_t segment = destaddr >> 4; - struct grub_relocator16_state state = { - .cs = segment, - .ds = segment, - .es = segment, - .fs = segment, - .gs = segment, - .ss = segment, - .ip = 0x100, - .sp = sp, - .edx = edx, - .a20 = 1 - }; - grub_video_set_mode ("text", 0, 0); - - return grub_relocator16_boot (rel, state); -} - -static grub_err_t -grub_truecrypt_unload (void) -{ - grub_relocator_unload (rel); - rel = NULL; - grub_dl_unref (my_mod); - return GRUB_ERR_NONE; -} - -/* Information on protocol supplied by Attila Lendvai. */ -#define MAGIC "\0CD001\1EL TORITO SPECIFICATION" - -static grub_err_t -grub_cmd_truecrypt (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_file_t file = 0; - grub_err_t err; - void *truecrypt; - grub_size_t truecryptsize; - const grub_size_t truecryptmemsize = 42 * 1024; - grub_uint8_t dh; - grub_uint32_t catalog, rba; - grub_uint8_t buf[128]; - char *compressed = NULL; - char *uncompressed = NULL; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - rel = NULL; - - grub_dl_ref (my_mod); - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_TRUECRYPT); - if (! file) - goto fail; - - if (grub_file_seek (file, 17 * 2048) == (grub_size_t) -1) - goto fail; - - if (grub_file_read (file, buf, sizeof (buf)) - != sizeof (buf)) - goto fail; - - if (grub_memcmp (buf, MAGIC, sizeof (MAGIC)) != 0) - { - grub_error (GRUB_ERR_BAD_OS, "invalid eltorito signature"); - goto fail; - } - - catalog = grub_get_unaligned32 (buf + 0x47); - - if (grub_file_seek (file, catalog * 2048) == (grub_size_t)-1) - goto fail; - - if (grub_file_read (file, buf, sizeof (buf)) - != sizeof (buf)) - goto fail; - - if (buf[0] != 1 || buf[1] != 0 || buf[0x1e] != 0x55 - || buf[0x1f] != 0xaa || buf[0x20] != 0x88 - || buf[0x26] != 1 || buf[0x27] != 0) - { - grub_error (GRUB_ERR_BAD_OS, "invalid eltorito catalog"); - goto fail; - } - - rba = grub_get_unaligned32 (buf + 0x28); - - if (grub_file_seek (file, rba * 2048 + 0x1b7) == (grub_size_t) -1) - goto fail; - - if (grub_file_read (file, &dh, 1) - != 1) - goto fail; - - if (grub_file_seek (file, rba * 2048 + 512 + 2048) == (grub_size_t) -1) - goto fail; - - compressed = grub_malloc (57 * 512); - if (!compressed) - goto fail; - - if (grub_file_read (file, compressed, 57 * 512) - != 57 * 512) - goto fail; - - uncompressed = grub_malloc (truecryptmemsize); - if (!uncompressed) - goto fail; - - /* It's actually gzip but our gzip decompressor isn't able to handle - trailing garbage, hence let's use raw decompressor. */ - truecryptsize = grub_deflate_decompress (compressed + 10, 57 * 512 - 10, - 0, uncompressed, truecryptmemsize); - if ((grub_ssize_t) truecryptsize < 0) - goto fail; - - if (truecryptmemsize <= truecryptsize + 0x100) - { - grub_error (GRUB_ERR_BAD_OS, "file is too big"); - goto fail; - } - - rel = grub_relocator_new (); - if (!rel) - goto fail; - - edx = (dh << 8) | grub_get_root_biosnumber (); - - destaddr = ALIGN_DOWN (grub_min (0x90000, grub_mmap_get_lower ()) - - truecryptmemsize, 64 * 1024); - - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (rel, &ch, destaddr, - truecryptmemsize); - if (err) - goto fail; - truecrypt = get_virtual_current_address (ch); - } - - grub_memset (truecrypt, 0, 0x100); - grub_memcpy ((char *) truecrypt + 0x100, uncompressed, truecryptsize); - - grub_memset ((char *) truecrypt + truecryptsize + 0x100, - 0, truecryptmemsize - truecryptsize - 0x100); - sp = truecryptmemsize - 4; - - grub_loader_set (grub_truecrypt_boot, grub_truecrypt_unload, 1); - - grub_free (uncompressed); - grub_free (compressed); - - return GRUB_ERR_NONE; - - fail: - - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, "bad truecrypt ISO"); - - if (file) - grub_file_close (file); - - grub_truecrypt_unload (); - - grub_free (uncompressed); - grub_free (compressed); - - return grub_errno; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(truecrypt) -{ - cmd = grub_register_command ("truecrypt", grub_cmd_truecrypt, - 0, N_("Load Truecrypt ISO.")); - my_mod = mod; -} - -GRUB_MOD_FINI(truecrypt) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c deleted file mode 100644 index dcdf005df..000000000 --- a/grub-core/loader/i386/xen.c +++ /dev/null @@ -1,984 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#ifdef __x86_64__ -#define NUMBER_OF_LEVELS 4 -#define INTERMEDIATE_OR (GRUB_PAGE_PRESENT | GRUB_PAGE_RW | GRUB_PAGE_USER) -#define VIRT_MASK 0x0000ffffffffffffULL -#else -#define NUMBER_OF_LEVELS 3 -#define INTERMEDIATE_OR (GRUB_PAGE_PRESENT | GRUB_PAGE_RW) -#define VIRT_MASK 0x00000000ffffffffULL -#define HYPERVISOR_PUD_ADDRESS 0xc0000000ULL -#endif - -struct grub_xen_mapping_lvl { - grub_uint64_t virt_start; - grub_uint64_t virt_end; - grub_uint64_t pfn_start; - grub_uint64_t n_pt_pages; -}; - -struct grub_xen_mapping { - grub_uint64_t *where; - struct grub_xen_mapping_lvl area; - struct grub_xen_mapping_lvl lvls[NUMBER_OF_LEVELS]; -}; - -struct xen_loader_state { - struct grub_relocator *relocator; - struct grub_relocator_xen_state state; - struct start_info next_start; - struct grub_xen_file_info xen_inf; - grub_xen_mfn_t *virt_mfn_list; - struct start_info *virt_start_info; - grub_xen_mfn_t console_pfn; - grub_uint64_t max_addr; - grub_uint64_t pgtbl_end; - struct xen_multiboot_mod_list *module_info_page; - grub_uint64_t modules_target_start; - grub_size_t n_modules; - struct grub_xen_mapping *map_reloc; - struct grub_xen_mapping mappings[XEN_MAX_MAPPINGS]; - int n_mappings; - int loaded; -}; - -static struct xen_loader_state xen_state; - -static grub_dl_t my_mod; - -#define MAX_MODULES (GRUB_PAGE_SIZE / sizeof (struct xen_multiboot_mod_list)) -#define STACK_SIZE 1048576 -#define ADDITIONAL_SIZE (1 << 19) -#define ALIGN_SIZE (1 << 22) -#define LOG_POINTERS_PER_PAGE 9 -#define POINTERS_PER_PAGE (1 << LOG_POINTERS_PER_PAGE) - -static grub_uint64_t -page2offset (grub_uint64_t page) -{ - return page << GRUB_PAGE_SHIFT; -} - -static grub_err_t -get_pgtable_size (grub_uint64_t from, grub_uint64_t to, grub_uint64_t pfn) -{ - struct grub_xen_mapping *map, *map_cmp; - grub_uint64_t mask, bits; - int i, m; - - if (xen_state.n_mappings == XEN_MAX_MAPPINGS) - return grub_error (GRUB_ERR_BUG, "too many mapped areas"); - - grub_dprintf ("xen", "get_pgtable_size %d from=%llx, to=%llx, pfn=%llx\n", - xen_state.n_mappings, (unsigned long long) from, - (unsigned long long) to, (unsigned long long) pfn); - - map = xen_state.mappings + xen_state.n_mappings; - grub_memset (map, 0, sizeof (*map)); - - map->area.virt_start = from & VIRT_MASK; - map->area.virt_end = (to - 1) & VIRT_MASK; - map->area.n_pt_pages = 0; - - for (i = NUMBER_OF_LEVELS - 1; i >= 0; i--) - { - map->lvls[i].pfn_start = pfn + map->area.n_pt_pages; - if (i == NUMBER_OF_LEVELS - 1) - { - if (xen_state.n_mappings == 0) - { - map->lvls[i].virt_start = 0; - map->lvls[i].virt_end = VIRT_MASK; - map->lvls[i].n_pt_pages = 1; - map->area.n_pt_pages++; - } - continue; - } - - bits = GRUB_PAGE_SHIFT + (i + 1) * LOG_POINTERS_PER_PAGE; - mask = (1ULL << bits) - 1; - map->lvls[i].virt_start = map->area.virt_start & ~mask; - map->lvls[i].virt_end = map->area.virt_end | mask; -#ifdef __i386__ - /* PAE wants last root directory present. */ - if (i == 1 && to <= HYPERVISOR_PUD_ADDRESS && xen_state.n_mappings == 0) - map->lvls[i].virt_end = VIRT_MASK; -#endif - for (m = 0; m < xen_state.n_mappings; m++) - { - map_cmp = xen_state.mappings + m; - if (map_cmp->lvls[i].virt_start == map_cmp->lvls[i].virt_end) - continue; - if (map->lvls[i].virt_start >= map_cmp->lvls[i].virt_start && - map->lvls[i].virt_end <= map_cmp->lvls[i].virt_end) - { - map->lvls[i].virt_start = 0; - map->lvls[i].virt_end = 0; - break; - } - if (map->lvls[i].virt_start >= map_cmp->lvls[i].virt_start && - map->lvls[i].virt_start <= map_cmp->lvls[i].virt_end) - map->lvls[i].virt_start = map_cmp->lvls[i].virt_end + 1; - if (map->lvls[i].virt_end >= map_cmp->lvls[i].virt_start && - map->lvls[i].virt_end <= map_cmp->lvls[i].virt_end) - map->lvls[i].virt_end = map_cmp->lvls[i].virt_start - 1; - } - if (map->lvls[i].virt_start < map->lvls[i].virt_end) - map->lvls[i].n_pt_pages = - ((map->lvls[i].virt_end - map->lvls[i].virt_start) >> bits) + 1; - map->area.n_pt_pages += map->lvls[i].n_pt_pages; - grub_dprintf ("xen", "get_pgtable_size level %d: virt %llx-%llx %d pts\n", - i, (unsigned long long) map->lvls[i].virt_start, - (unsigned long long) map->lvls[i].virt_end, - (int) map->lvls[i].n_pt_pages); - } - - grub_dprintf ("xen", "get_pgtable_size return: %d page tables\n", - (int) map->area.n_pt_pages); - - xen_state.state.paging_start[xen_state.n_mappings] = pfn; - xen_state.state.paging_size[xen_state.n_mappings] = map->area.n_pt_pages; - - return GRUB_ERR_NONE; -} - -static grub_uint64_t * -get_pg_table_virt (int mapping, int level) -{ - grub_uint64_t pfn; - struct grub_xen_mapping *map; - - map = xen_state.mappings + mapping; - pfn = map->lvls[level].pfn_start - map->lvls[NUMBER_OF_LEVELS - 1].pfn_start; - return map->where + pfn * POINTERS_PER_PAGE; -} - -static grub_uint64_t -get_pg_table_prot (int level, grub_uint64_t pfn) -{ - int m; - grub_uint64_t pfn_s, pfn_e; - - if (level > 0) - return INTERMEDIATE_OR; - for (m = 0; m < xen_state.n_mappings; m++) - { - pfn_s = xen_state.mappings[m].lvls[NUMBER_OF_LEVELS - 1].pfn_start; - pfn_e = xen_state.mappings[m].area.n_pt_pages + pfn_s; - if (pfn >= pfn_s && pfn < pfn_e) - return GRUB_PAGE_PRESENT | GRUB_PAGE_USER; - } - return GRUB_PAGE_PRESENT | GRUB_PAGE_RW | GRUB_PAGE_USER; -} - -static void -generate_page_table (grub_xen_mfn_t *mfn_list) -{ - int l, m1, m2; - long p, p_s, p_e; - grub_uint64_t start, end, pfn; - grub_uint64_t *pg; - struct grub_xen_mapping_lvl *lvl; - - for (m1 = 0; m1 < xen_state.n_mappings; m1++) - grub_memset (xen_state.mappings[m1].where, 0, - xen_state.mappings[m1].area.n_pt_pages * GRUB_PAGE_SIZE); - - for (l = NUMBER_OF_LEVELS - 1; l >= 0; l--) - { - for (m1 = 0; m1 < xen_state.n_mappings; m1++) - { - start = xen_state.mappings[m1].lvls[l].virt_start; - end = xen_state.mappings[m1].lvls[l].virt_end; - pg = get_pg_table_virt(m1, l); - for (m2 = 0; m2 < xen_state.n_mappings; m2++) - { - lvl = (l > 0) ? xen_state.mappings[m2].lvls + l - 1 - : &xen_state.mappings[m2].area; - if (l > 0 && lvl->n_pt_pages == 0) - continue; - if (lvl->virt_start >= end || lvl->virt_end <= start) - continue; - p_s = (grub_max (start, lvl->virt_start) - start) >> - (GRUB_PAGE_SHIFT + l * LOG_POINTERS_PER_PAGE); - p_e = (grub_min (end, lvl->virt_end) - start) >> - (GRUB_PAGE_SHIFT + l * LOG_POINTERS_PER_PAGE); - pfn = ((grub_max (start, lvl->virt_start) - lvl->virt_start) >> - (GRUB_PAGE_SHIFT + l * LOG_POINTERS_PER_PAGE)) + lvl->pfn_start; - grub_dprintf ("xen", "write page table entries level %d pg %p " - "mapping %d/%d index %lx-%lx pfn %llx\n", - l, pg, m1, m2, p_s, p_e, (unsigned long long) pfn); - for (p = p_s; p <= p_e; p++) - { - pg[p] = page2offset (mfn_list[pfn]) | - get_pg_table_prot (l, pfn); - pfn++; - } - } - } - } -} - -static grub_err_t -set_mfns (grub_xen_mfn_t pfn) -{ - grub_xen_mfn_t i, t; - grub_xen_mfn_t cn_pfn = -1, st_pfn = -1; - struct mmu_update m2p_updates[4]; - - - for (i = 0; i < grub_xen_start_page_addr->nr_pages; i++) - { - if (xen_state.virt_mfn_list[i] == - grub_xen_start_page_addr->console.domU.mfn) - cn_pfn = i; - if (xen_state.virt_mfn_list[i] == grub_xen_start_page_addr->store_mfn) - st_pfn = i; - } - if (cn_pfn == (grub_xen_mfn_t)-1) - return grub_error (GRUB_ERR_BUG, "no console"); - if (st_pfn == (grub_xen_mfn_t)-1) - return grub_error (GRUB_ERR_BUG, "no store"); - t = xen_state.virt_mfn_list[pfn]; - xen_state.virt_mfn_list[pfn] = xen_state.virt_mfn_list[cn_pfn]; - xen_state.virt_mfn_list[cn_pfn] = t; - t = xen_state.virt_mfn_list[pfn + 1]; - xen_state.virt_mfn_list[pfn + 1] = xen_state.virt_mfn_list[st_pfn]; - xen_state.virt_mfn_list[st_pfn] = t; - - m2p_updates[0].ptr = - page2offset (xen_state.virt_mfn_list[pfn]) | MMU_MACHPHYS_UPDATE; - m2p_updates[0].val = pfn; - m2p_updates[1].ptr = - page2offset (xen_state.virt_mfn_list[pfn + 1]) | MMU_MACHPHYS_UPDATE; - m2p_updates[1].val = pfn + 1; - m2p_updates[2].ptr = - page2offset (xen_state.virt_mfn_list[cn_pfn]) | MMU_MACHPHYS_UPDATE; - m2p_updates[2].val = cn_pfn; - m2p_updates[3].ptr = - page2offset (xen_state.virt_mfn_list[st_pfn]) | MMU_MACHPHYS_UPDATE; - m2p_updates[3].val = st_pfn; - - grub_xen_mmu_update (m2p_updates, 4, NULL, DOMID_SELF); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_xen_p2m_alloc (void) -{ - grub_relocator_chunk_t ch; - grub_size_t p2msize, p2malloc; - grub_err_t err; - struct grub_xen_mapping *map; - - if (xen_state.virt_mfn_list) - return GRUB_ERR_NONE; - - map = xen_state.mappings + xen_state.n_mappings; - p2msize = ALIGN_UP (sizeof (grub_xen_mfn_t) * - grub_xen_start_page_addr->nr_pages, GRUB_PAGE_SIZE); - if (xen_state.xen_inf.has_p2m_base) - { - err = get_pgtable_size (xen_state.xen_inf.p2m_base, - xen_state.xen_inf.p2m_base + p2msize, - (xen_state.max_addr + p2msize) >> GRUB_PAGE_SHIFT); - if (err) - return err; - - map->area.pfn_start = xen_state.max_addr >> GRUB_PAGE_SHIFT; - p2malloc = p2msize + page2offset (map->area.n_pt_pages); - xen_state.n_mappings++; - xen_state.next_start.mfn_list = xen_state.xen_inf.p2m_base; - xen_state.next_start.first_p2m_pfn = map->area.pfn_start; - xen_state.next_start.nr_p2m_frames = p2malloc >> GRUB_PAGE_SHIFT; - } - else - { - xen_state.next_start.mfn_list = - xen_state.max_addr + xen_state.xen_inf.virt_base; - p2malloc = p2msize; - } - - xen_state.state.mfn_list = xen_state.max_addr; - err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, - xen_state.max_addr, p2malloc); - if (err) - return err; - xen_state.virt_mfn_list = get_virtual_current_address (ch); - if (xen_state.xen_inf.has_p2m_base) - map->where = (grub_uint64_t *) xen_state.virt_mfn_list + - p2msize / sizeof (grub_uint64_t); - grub_memcpy (xen_state.virt_mfn_list, - (void *) grub_xen_start_page_addr->mfn_list, p2msize); - xen_state.max_addr += p2malloc; - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_xen_special_alloc (void) -{ - grub_relocator_chunk_t ch; - grub_err_t err; - - if (xen_state.virt_start_info) - return GRUB_ERR_NONE; - - err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, - xen_state.max_addr, - sizeof (xen_state.next_start)); - if (err) - return err; - xen_state.state.start_info = xen_state.max_addr + xen_state.xen_inf.virt_base; - xen_state.virt_start_info = get_virtual_current_address (ch); - xen_state.max_addr = - ALIGN_UP (xen_state.max_addr + sizeof (xen_state.next_start), GRUB_PAGE_SIZE); - xen_state.console_pfn = xen_state.max_addr >> GRUB_PAGE_SHIFT; - xen_state.max_addr += 2 * GRUB_PAGE_SIZE; - - xen_state.next_start.nr_pages = grub_xen_start_page_addr->nr_pages; - grub_memcpy (xen_state.next_start.magic, grub_xen_start_page_addr->magic, - sizeof (xen_state.next_start.magic)); - xen_state.next_start.store_mfn = grub_xen_start_page_addr->store_mfn; - xen_state.next_start.store_evtchn = grub_xen_start_page_addr->store_evtchn; - xen_state.next_start.console.domU = grub_xen_start_page_addr->console.domU; - xen_state.next_start.shared_info = grub_xen_start_page_addr->shared_info; - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_xen_pt_alloc (void) -{ - grub_relocator_chunk_t ch; - grub_err_t err; - grub_uint64_t nr_info_pages; - grub_uint64_t nr_need_pages; - grub_uint64_t try_virt_end; - struct grub_xen_mapping *map; - - if (xen_state.pgtbl_end) - return GRUB_ERR_NONE; - - map = xen_state.mappings + xen_state.n_mappings; - xen_state.map_reloc = map + 1; - - xen_state.next_start.pt_base = - xen_state.max_addr + xen_state.xen_inf.virt_base; - nr_info_pages = xen_state.max_addr >> GRUB_PAGE_SHIFT; - nr_need_pages = nr_info_pages; - - while (1) - { - try_virt_end = ALIGN_UP (xen_state.xen_inf.virt_base + - page2offset (nr_need_pages) + - ADDITIONAL_SIZE + STACK_SIZE, ALIGN_SIZE); - - err = get_pgtable_size (xen_state.xen_inf.virt_base, try_virt_end, - nr_info_pages); - if (err) - return err; - xen_state.n_mappings++; - - /* Map the relocator page either at virtual 0 or after end of area. */ - nr_need_pages = nr_info_pages + map->area.n_pt_pages; - if (xen_state.xen_inf.virt_base) - err = get_pgtable_size (0, GRUB_PAGE_SIZE, nr_need_pages); - else - err = get_pgtable_size (try_virt_end, try_virt_end + GRUB_PAGE_SIZE, - nr_need_pages); - if (err) - return err; - nr_need_pages += xen_state.map_reloc->area.n_pt_pages; - - if (xen_state.xen_inf.virt_base + page2offset (nr_need_pages) <= - try_virt_end) - break; - - xen_state.n_mappings--; - } - - xen_state.n_mappings++; - nr_need_pages = map->area.n_pt_pages + xen_state.map_reloc->area.n_pt_pages; - err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, - xen_state.max_addr, - page2offset (nr_need_pages)); - if (err) - return err; - - map->where = get_virtual_current_address (ch); - map->area.pfn_start = 0; - xen_state.max_addr += page2offset (nr_need_pages); - xen_state.state.stack = - xen_state.max_addr + STACK_SIZE + xen_state.xen_inf.virt_base; - xen_state.next_start.nr_pt_frames = nr_need_pages; - xen_state.max_addr = try_virt_end - xen_state.xen_inf.virt_base; - xen_state.pgtbl_end = xen_state.max_addr >> GRUB_PAGE_SHIFT; - xen_state.map_reloc->where = (grub_uint64_t *) ((char *) map->where + - page2offset (map->area.n_pt_pages)); - - return GRUB_ERR_NONE; -} - -/* Allocate all not yet allocated areas mapped by initial page tables. */ -static grub_err_t -grub_xen_alloc_boot_data (void) -{ - grub_err_t err; - - if (!xen_state.xen_inf.has_p2m_base) - { - err = grub_xen_p2m_alloc (); - if (err) - return err; - } - err = grub_xen_special_alloc (); - if (err) - return err; - err = grub_xen_pt_alloc (); - if (err) - return err; - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_xen_boot (void) -{ - grub_err_t err; - grub_uint64_t nr_pages; - struct gnttab_set_version gnttab_setver; - grub_size_t i; - - if (grub_xen_n_allocated_shared_pages) - return grub_error (GRUB_ERR_BUG, "active grants"); - - err = grub_xen_alloc_boot_data (); - if (err) - return err; - if (xen_state.xen_inf.has_p2m_base) - { - err = grub_xen_p2m_alloc (); - if (err) - return err; - } - - err = set_mfns (xen_state.console_pfn); - if (err) - return err; - - nr_pages = xen_state.max_addr >> GRUB_PAGE_SHIFT; - - grub_dprintf ("xen", "bootstrap domain %llx+%llx\n", - (unsigned long long) xen_state.xen_inf.virt_base, - (unsigned long long) page2offset (nr_pages)); - - xen_state.map_reloc->area.pfn_start = nr_pages; - generate_page_table (xen_state.virt_mfn_list); - - xen_state.state.entry_point = xen_state.xen_inf.entry_point; - - *xen_state.virt_start_info = xen_state.next_start; - - grub_memset (&gnttab_setver, 0, sizeof (gnttab_setver)); - - gnttab_setver.version = 1; - grub_xen_grant_table_op (GNTTABOP_set_version, &gnttab_setver, 1); - - for (i = 0; i < ARRAY_SIZE (grub_xen_shared_info->evtchn_pending); i++) - grub_xen_shared_info->evtchn_pending[i] = 0; - - return grub_relocator_xen_boot (xen_state.relocator, xen_state.state, nr_pages, - xen_state.xen_inf.virt_base < - GRUB_PAGE_SIZE ? page2offset (nr_pages) : 0, - xen_state.pgtbl_end - 1, - page2offset (xen_state.pgtbl_end - 1) + - xen_state.xen_inf.virt_base); -} - -static void -grub_xen_reset (void) -{ - grub_relocator_unload (xen_state.relocator); - - grub_memset (&xen_state, 0, sizeof (xen_state)); -} - -static grub_err_t -grub_xen_unload (void) -{ - grub_xen_reset (); - grub_dl_unref (my_mod); - return GRUB_ERR_NONE; -} - -#define HYPERCALL_INTERFACE_SIZE 32 - -#ifdef __x86_64__ -static grub_uint8_t template[] = - { - 0x51, /* push %rcx */ - 0x41, 0x53, /* push %r11 */ - 0x48, 0xc7, 0xc0, 0xbb, 0xaa, 0x00, 0x00, /* mov $0xaabb,%rax */ - 0x0f, 0x05, /* syscall */ - 0x41, 0x5b, /* pop %r11 */ - 0x59, /* pop %rcx */ - 0xc3 /* ret */ - }; - -static grub_uint8_t template_iret[] = - { - 0x51, /* push %rcx */ - 0x41, 0x53, /* push %r11 */ - 0x50, /* push %rax */ - 0x48, 0xc7, 0xc0, 0x17, 0x00, 0x00, 0x00, /* mov $0x17,%rax */ - 0x0f, 0x05 /* syscall */ - }; -#define CALLNO_OFFSET 6 -#else - -static grub_uint8_t template[] = - { - 0xb8, 0xbb, 0xaa, 0x00, 0x00, /* mov imm32, %eax */ - 0xcd, 0x82, /* int $0x82 */ - 0xc3 /* ret */ - }; - -static grub_uint8_t template_iret[] = - { - 0x50, /* push %eax */ - 0xb8, 0x17, 0x00, 0x00, 0x00, /* mov $0x17,%eax */ - 0xcd, 0x82, /* int $0x82 */ - }; -#define CALLNO_OFFSET 1 - -#endif - - -static void -set_hypercall_interface (grub_uint8_t *tgt, unsigned callno) -{ - if (callno == 0x17) - { - grub_memcpy (tgt, template_iret, ARRAY_SIZE (template_iret)); - grub_memset (tgt + ARRAY_SIZE (template_iret), 0xcc, - HYPERCALL_INTERFACE_SIZE - ARRAY_SIZE (template_iret)); - return; - } - grub_memcpy (tgt, template, ARRAY_SIZE (template)); - grub_memset (tgt + ARRAY_SIZE (template), 0xcc, - HYPERCALL_INTERFACE_SIZE - ARRAY_SIZE (template)); - tgt[CALLNO_OFFSET] = callno & 0xff; - tgt[CALLNO_OFFSET + 1] = callno >> 8; -} - -#ifdef __x86_64__ -#define grub_elfXX_load grub_elf64_load -#else -#define grub_elfXX_load grub_elf32_load -#endif - -static grub_err_t -grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_file_t file; - grub_elf_t elf; - grub_err_t err; - void *kern_chunk_src; - grub_relocator_chunk_t ch; - grub_addr_t kern_start; - grub_addr_t kern_end; - grub_size_t sz; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - /* Call grub_loader_unset early to avoid it being called by grub_loader_set */ - grub_loader_unset (); - - grub_xen_reset (); - - err = grub_create_loader_cmdline (argc - 1, argv + 1, - (char *) xen_state.next_start.cmd_line, - sizeof (xen_state.next_start.cmd_line) - 1, - GRUB_VERIFY_KERNEL_CMDLINE); - if (err) - return err; - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); - if (!file) - return grub_errno; - - elf = grub_xen_file (file); - if (!elf) - goto fail; - - err = grub_xen_get_info (elf, &xen_state.xen_inf); - if (err) - goto fail; -#ifdef __x86_64__ - if (xen_state.xen_inf.arch != GRUB_XEN_FILE_X86_64) -#else - if (xen_state.xen_inf.arch != GRUB_XEN_FILE_I386_PAE - && xen_state.xen_inf.arch != GRUB_XEN_FILE_I386_PAE_BIMODE) -#endif - { - grub_error (GRUB_ERR_BAD_OS, "incompatible architecture: %d", - xen_state.xen_inf.arch); - goto fail; - } - - if (xen_state.xen_inf.virt_base & (GRUB_PAGE_SIZE - 1)) - { - grub_error (GRUB_ERR_BAD_OS, "unaligned virt_base"); - goto fail; - } - grub_dprintf ("xen", "virt_base = %llx, entry = %llx\n", - (unsigned long long) xen_state.xen_inf.virt_base, - (unsigned long long) xen_state.xen_inf.entry_point); - - xen_state.relocator = grub_relocator_new (); - if (!xen_state.relocator) - goto fail; - - kern_start = xen_state.xen_inf.kern_start - xen_state.xen_inf.paddr_offset; - kern_end = xen_state.xen_inf.kern_end - xen_state.xen_inf.paddr_offset; - - if (xen_state.xen_inf.has_hypercall_page) - { - grub_dprintf ("xen", "hypercall page at 0x%llx\n", - (unsigned long long) xen_state.xen_inf.hypercall_page); - kern_start = grub_min (kern_start, xen_state.xen_inf.hypercall_page - - xen_state.xen_inf.virt_base); - kern_end = grub_max (kern_end, xen_state.xen_inf.hypercall_page - - xen_state.xen_inf.virt_base + GRUB_PAGE_SIZE); - } - - xen_state.max_addr = ALIGN_UP (kern_end, GRUB_PAGE_SIZE); - - - if (grub_sub (kern_end, kern_start, &sz)) - { - err = GRUB_ERR_OUT_OF_RANGE; - goto fail; - } - - err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, kern_start, sz); - if (err) - goto fail; - kern_chunk_src = get_virtual_current_address (ch); - - grub_dprintf ("xen", "paddr_offset = 0x%llx\n", - (unsigned long long) xen_state.xen_inf.paddr_offset); - grub_dprintf ("xen", "kern_start = 0x%llx, kern_end = 0x%llx\n", - (unsigned long long) xen_state.xen_inf.kern_start, - (unsigned long long) xen_state.xen_inf.kern_end); - - err = grub_elfXX_load (elf, argv[0], - (grub_uint8_t *) kern_chunk_src - kern_start - - xen_state.xen_inf.paddr_offset, 0, 0, 0); - - if (xen_state.xen_inf.has_hypercall_page) - { - unsigned i; - for (i = 0; i < GRUB_PAGE_SIZE / HYPERCALL_INTERFACE_SIZE; i++) - set_hypercall_interface ((grub_uint8_t *) kern_chunk_src + - i * HYPERCALL_INTERFACE_SIZE + - xen_state.xen_inf.hypercall_page - - xen_state.xen_inf.virt_base - kern_start, i); - } - - if (err) - goto fail; - - grub_dl_ref (my_mod); - xen_state.loaded = 1; - - grub_loader_set (grub_xen_boot, grub_xen_unload, 0); - - goto fail; - -fail: - /* grub_errno might be clobbered by further calls, save the error reason. */ - err = grub_errno; - - if (elf) - grub_elf_close (elf); - else if (file) - grub_file_close (file); - - if (err != GRUB_ERR_NONE) - grub_xen_reset (); - - return err; -} - -static grub_err_t -grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_size_t size = 0; - grub_err_t err; - struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; - grub_relocator_chunk_t ch; - - if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - if (!xen_state.loaded) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("you need to load the kernel first")); - goto fail; - } - - if (xen_state.next_start.mod_start || xen_state.next_start.mod_len) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("initrd already loaded")); - goto fail; - } - - if (xen_state.xen_inf.unmapped_initrd) - { - err = grub_xen_alloc_boot_data (); - if (err) - goto fail; - } - - if (grub_initrd_init (argc, argv, &initrd_ctx)) - goto fail; - - size = grub_get_initrd_size (&initrd_ctx); - - if (size) - { - err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, - xen_state.max_addr, size); - if (err) - goto fail; - - if (grub_initrd_load (&initrd_ctx, get_virtual_current_address (ch))) - goto fail; - } - - xen_state.next_start.mod_len = size; - - if (xen_state.xen_inf.unmapped_initrd) - { - xen_state.next_start.flags |= SIF_MOD_START_PFN; - xen_state.next_start.mod_start = xen_state.max_addr >> GRUB_PAGE_SHIFT; - } - else - xen_state.next_start.mod_start = - xen_state.max_addr + xen_state.xen_inf.virt_base; - - grub_dprintf ("xen", "Initrd, addr=0x%x, size=0x%x\n", - (unsigned) (xen_state.max_addr + xen_state.xen_inf.virt_base), - (unsigned) size); - - xen_state.max_addr = ALIGN_UP (xen_state.max_addr + size, GRUB_PAGE_SIZE); - -fail: - grub_initrd_close (&initrd_ctx); - - return grub_errno; -} - -static grub_err_t -grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_size_t size = 0; - grub_err_t err; - grub_relocator_chunk_t ch; - grub_size_t cmdline_len; - int nounzip = 0; - grub_file_t file; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - if (grub_strcmp (argv[0], "--nounzip") == 0) - { - argv++; - argc--; - nounzip = 1; - } - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - if (!xen_state.loaded) - { - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("you need to load the kernel first")); - } - - if ((xen_state.next_start.mod_start || xen_state.next_start.mod_len) && - !xen_state.module_info_page) - { - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("initrd already loaded")); - } - - /* Leave one space for terminator. */ - if (xen_state.n_modules >= MAX_MODULES - 1) - { - return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many modules"); - } - - if (!xen_state.module_info_page) - { - xen_state.xen_inf.unmapped_initrd = 0; - xen_state.n_modules = 0; - xen_state.max_addr = ALIGN_UP (xen_state.max_addr, GRUB_PAGE_SIZE); - xen_state.modules_target_start = xen_state.max_addr; - xen_state.next_start.mod_start = - xen_state.max_addr + xen_state.xen_inf.virt_base; - xen_state.next_start.flags |= SIF_MULTIBOOT_MOD; - - err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, - xen_state.max_addr, MAX_MODULES - * - sizeof (xen_state.module_info_page - [0])); - if (err) - return err; - xen_state.module_info_page = get_virtual_current_address (ch); - grub_memset (xen_state.module_info_page, 0, MAX_MODULES - * sizeof (xen_state.module_info_page[0])); - xen_state.max_addr += - MAX_MODULES * sizeof (xen_state.module_info_page[0]); - } - - xen_state.max_addr = ALIGN_UP (xen_state.max_addr, GRUB_PAGE_SIZE); - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_INITRD | - (nounzip ? GRUB_FILE_TYPE_NO_DECOMPRESS : GRUB_FILE_TYPE_NONE)); - if (!file) - return grub_errno; - size = grub_file_size (file); - - cmdline_len = grub_loader_cmdline_size (argc - 1, argv + 1); - - err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, - xen_state.max_addr, cmdline_len); - if (err) - goto fail; - - err = grub_create_loader_cmdline (argc - 1, argv + 1, - get_virtual_current_address (ch), cmdline_len, - GRUB_VERIFY_MODULE_CMDLINE); - if (err) - goto fail; - - xen_state.module_info_page[xen_state.n_modules].cmdline = - xen_state.max_addr - xen_state.modules_target_start; - xen_state.max_addr = ALIGN_UP (xen_state.max_addr + cmdline_len, GRUB_PAGE_SIZE); - - if (size) - { - err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, - xen_state.max_addr, size); - if (err) - goto fail; - if (grub_file_read (file, get_virtual_current_address (ch), size) - != (grub_ssize_t) size) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, - N_("premature end of file %s"), argv[0]); - goto fail; - } - } - xen_state.next_start.mod_len = - xen_state.max_addr + size - xen_state.modules_target_start; - xen_state.module_info_page[xen_state.n_modules].mod_start = - xen_state.max_addr - xen_state.modules_target_start; - xen_state.module_info_page[xen_state.n_modules].mod_end = - xen_state.max_addr + size - xen_state.modules_target_start; - - xen_state.n_modules++; - grub_dprintf ("xen", "module, addr=0x%x, size=0x%x\n", - (unsigned) xen_state.max_addr, (unsigned) size); - xen_state.max_addr = ALIGN_UP (xen_state.max_addr + size, GRUB_PAGE_SIZE); - - -fail: - grub_file_close (file); - - return grub_errno; -} - -static grub_command_t cmd_xen, cmd_initrd, cmd_module, cmd_multiboot; - -GRUB_MOD_INIT (xen) -{ - cmd_xen = grub_register_command ("linux", grub_cmd_xen, - 0, N_("Load Linux.")); - cmd_multiboot = grub_register_command ("multiboot", grub_cmd_xen, - 0, N_("Load Linux.")); - cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, - 0, N_("Load initrd.")); - cmd_module = grub_register_command ("module", grub_cmd_module, - 0, N_("Load module.")); - my_mod = mod; -} - -GRUB_MOD_FINI (xen) -{ - grub_unregister_command (cmd_xen); - grub_unregister_command (cmd_initrd); - grub_unregister_command (cmd_multiboot); - grub_unregister_command (cmd_module); -} diff --git a/grub-core/loader/i386/xen_file.c b/grub-core/loader/i386/xen_file.c deleted file mode 100644 index 9af5d66df..000000000 --- a/grub-core/loader/i386/xen_file.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -#define XZ_MAGIC "\3757zXZ\0" - -grub_elf_t -grub_xen_file (grub_file_t file) -{ - grub_elf_t elf; - struct linux_i386_kernel_header lh; - grub_file_t off_file; - grub_uint32_t payload_offset, payload_length; - grub_uint8_t magic[6]; - - elf = grub_elf_file (file, file->name); - if (elf) - return elf; - grub_errno = GRUB_ERR_NONE; - - if (grub_file_seek (file, 0) == (grub_off_t) -1) - goto fail; - - if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) - goto fail; - - if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55) - || lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) - || grub_le_to_cpu16 (lh.version) < 0x0208) - { - grub_error (GRUB_ERR_BAD_OS, "version too old for xen boot"); - return NULL; - } - - payload_length = lh.payload_length; - payload_offset = (lh.setup_sects + 1) * 512 - + lh.payload_offset; - - if (payload_length < sizeof (magic)) - { - grub_error (GRUB_ERR_BAD_OS, "payload too short"); - return NULL; - } - - grub_dprintf ("xen", "found bzimage payload 0x%llx-0x%llx\n", - (unsigned long long) payload_offset, - (unsigned long long) lh.payload_length); - - grub_file_seek (file, payload_offset); - - if (grub_file_read (file, &magic, sizeof (magic)) != sizeof (magic)) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - file->name); - goto fail; - } - - /* Kernel suffixes xz payload with their uncompressed size. - Trim it. */ - if (grub_memcmp (magic, XZ_MAGIC, sizeof (XZ_MAGIC) - 1) == 0) - payload_length -= 4; - off_file = grub_file_offset_open (file, GRUB_FILE_TYPE_LINUX_KERNEL, payload_offset, - payload_length); - if (!off_file) - goto fail; - - elf = grub_elf_file (off_file, file->name); - if (elf) - return elf; - grub_file_offset_close (off_file); - -fail: - grub_error (GRUB_ERR_BAD_OS, "not xen image"); - return NULL; -} - -grub_err_t -grub_xen_get_info (grub_elf_t elf, struct grub_xen_file_info * xi) -{ - grub_memset (xi, 0, sizeof (*xi)); - - if (grub_elf_is_elf64 (elf) - && elf->ehdr.ehdr64.e_machine - == grub_cpu_to_le16_compile_time (EM_X86_64) - && elf->ehdr.ehdr64.e_ident[EI_DATA] == ELFDATA2LSB) - { - xi->arch = GRUB_XEN_FILE_X86_64; - return grub_xen_get_info64 (elf, xi); - } - if (grub_elf_is_elf32 (elf) - && elf->ehdr.ehdr32.e_machine == grub_cpu_to_le16_compile_time (EM_386) - && elf->ehdr.ehdr32.e_ident[EI_DATA] == ELFDATA2LSB) - { - xi->arch = GRUB_XEN_FILE_I386; - return grub_xen_get_info32 (elf, xi); - } - return grub_error (GRUB_ERR_BAD_OS, "unknown ELF type"); -} diff --git a/grub-core/loader/i386/xen_file32.c b/grub-core/loader/i386/xen_file32.c deleted file mode 100644 index 340d44569..000000000 --- a/grub-core/loader/i386/xen_file32.c +++ /dev/null @@ -1,7 +0,0 @@ -#define GRUB_TARGET_WORDSIZE 32 -#define XX 32 -#define grub_le_to_cpu_addr grub_le_to_cpu32 -#define ehdrXX ehdr32 -#define grub_xen_get_infoXX grub_xen_get_info32 -#define FOR_ELF_PHDRS FOR_ELF32_PHDRS -#include "xen_fileXX.c" diff --git a/grub-core/loader/i386/xen_file64.c b/grub-core/loader/i386/xen_file64.c deleted file mode 100644 index c41049369..000000000 --- a/grub-core/loader/i386/xen_file64.c +++ /dev/null @@ -1,7 +0,0 @@ -#define GRUB_TARGET_WORDSIZE 64 -#define XX 64 -#define grub_le_to_cpu_addr grub_le_to_cpu64 -#define ehdrXX ehdr64 -#define grub_xen_get_infoXX grub_xen_get_info64 -#define FOR_ELF_PHDRS FOR_ELF64_PHDRS -#include "xen_fileXX.c" diff --git a/grub-core/loader/i386/xen_fileXX.c b/grub-core/loader/i386/xen_fileXX.c deleted file mode 100644 index 27afcaacb..000000000 --- a/grub-core/loader/i386/xen_fileXX.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -static grub_err_t -parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi, - grub_off_t off, grub_size_t sz) -{ - char *buf; - const char *ptr; - int has_paddr = 0; - - grub_errno = GRUB_ERR_NONE; - if (grub_file_seek (elf->file, off) == (grub_off_t) -1) - return grub_errno; - buf = grub_malloc (sz); - if (!buf) - return grub_errno; - - if (grub_file_read (elf->file, buf, sz) != (grub_ssize_t) sz) - { - if (grub_errno) - goto out; - grub_free (buf); - return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - elf->file->name); - } - xi->has_xen_guest = 1; - for (ptr = buf; ptr && ptr - buf < (grub_ssize_t) sz; - ptr = grub_strchr (ptr, ','), (ptr ? ptr++ : 0)) - { - if (grub_strncmp (ptr, "PAE=no,", sizeof ("PAE=no,") - 1) == 0) - { - if (xi->arch != GRUB_XEN_FILE_I386 - && xi->arch != GRUB_XEN_FILE_I386_PAE - && xi->arch != GRUB_XEN_FILE_I386_PAE_BIMODE) - continue; - xi->arch = GRUB_XEN_FILE_I386; - continue; - } - - if (grub_strncmp (ptr, "PAE=yes,", sizeof ("PAE=yes,") - 1) == 0) - { - if (xi->arch != GRUB_XEN_FILE_I386 - && xi->arch != GRUB_XEN_FILE_I386_PAE - && xi->arch != GRUB_XEN_FILE_I386_PAE_BIMODE) - continue; - xi->arch = GRUB_XEN_FILE_I386_PAE; - continue; - } - - if (grub_strncmp (ptr, "PAE=yes[extended-cr3],", - sizeof ("PAE=yes[extended-cr3],") - 1) == 0) - { - if (xi->arch != GRUB_XEN_FILE_I386 - && xi->arch != GRUB_XEN_FILE_I386_PAE - && xi->arch != GRUB_XEN_FILE_I386_PAE_BIMODE) - continue; - xi->arch = GRUB_XEN_FILE_I386_PAE; - xi->extended_cr3 = 1; - continue; - } - - if (grub_strncmp (ptr, "PAE=bimodal,", sizeof ("PAE=bimodal,") - 1) == 0) - { - if (xi->arch != GRUB_XEN_FILE_I386 - && xi->arch != GRUB_XEN_FILE_I386_PAE - && xi->arch != GRUB_XEN_FILE_I386_PAE_BIMODE) - continue; - xi->arch = GRUB_XEN_FILE_I386_PAE_BIMODE; - continue; - } - - if (grub_strncmp (ptr, "PAE=bimodal[extended-cr3],", - sizeof ("PAE=bimodal[extended-cr3],") - 1) == 0) - { - if (xi->arch != GRUB_XEN_FILE_I386 - && xi->arch != GRUB_XEN_FILE_I386_PAE - && xi->arch != GRUB_XEN_FILE_I386_PAE_BIMODE) - continue; - xi->arch = GRUB_XEN_FILE_I386_PAE_BIMODE; - xi->extended_cr3 = 1; - continue; - } - - if (grub_strncmp (ptr, "PAE=yes,bimodal,", sizeof ("PAE=yes,bimodal,") - 1) == 0) - { - if (xi->arch != GRUB_XEN_FILE_I386 - && xi->arch != GRUB_XEN_FILE_I386_PAE - && xi->arch != GRUB_XEN_FILE_I386_PAE_BIMODE) - continue; - xi->arch = GRUB_XEN_FILE_I386_PAE_BIMODE; - continue; - } - - if (grub_strncmp (ptr, "PAE=yes[extended-cr3],bimodal,", - sizeof ("PAE=yes[extended-cr3],bimodal,") - 1) == 0) - { - if (xi->arch != GRUB_XEN_FILE_I386 - && xi->arch != GRUB_XEN_FILE_I386_PAE - && xi->arch != GRUB_XEN_FILE_I386_PAE_BIMODE) - continue; - xi->arch = GRUB_XEN_FILE_I386_PAE_BIMODE; - xi->extended_cr3 = 1; - continue; - } - - if (grub_strncmp (ptr, "VIRT_BASE=", sizeof ("VIRT_BASE=") - 1) == 0) - { - xi->virt_base = grub_strtoull (ptr + sizeof ("VIRT_BASE=") - 1, &ptr, 16); - if (grub_errno) - goto out; - continue; - } - if (grub_strncmp (ptr, "VIRT_ENTRY=", sizeof ("VIRT_ENTRY=") - 1) == 0) - { - xi->entry_point = grub_strtoull (ptr + sizeof ("VIRT_ENTRY=") - 1, &ptr, 16); - if (grub_errno) - goto out; - continue; - } - if (grub_strncmp (ptr, "HYPERCALL_PAGE=", sizeof ("HYPERCALL_PAGE=") - 1) == 0) - { - xi->hypercall_page = grub_strtoull (ptr + sizeof ("HYPERCALL_PAGE=") - 1, &ptr, 16); - xi->has_hypercall_page = 1; - if (grub_errno) - goto out; - continue; - } - if (grub_strncmp (ptr, "ELF_PADDR_OFFSET=", sizeof ("ELF_PADDR_OFFSET=") - 1) == 0) - { - xi->paddr_offset = grub_strtoull (ptr + sizeof ("ELF_PADDR_OFFSET=") - 1, &ptr, 16); - has_paddr = 1; - if (grub_errno) - goto out; - continue; - } - } - if (xi->has_hypercall_page) - xi->hypercall_page = (xi->hypercall_page << 12) + xi->virt_base; - if (!has_paddr) - xi->paddr_offset = xi->virt_base; - -out: - grub_free (buf); - - return grub_errno; -} - -#pragma GCC diagnostic ignored "-Wcast-align" - -static grub_err_t -parse_note (grub_elf_t elf, struct grub_xen_file_info *xi, - grub_off_t off, grub_size_t sz) -{ - grub_uint32_t *buf; - grub_uint32_t *ptr; - if (grub_file_seek (elf->file, off) == (grub_off_t) -1) - return grub_errno; - buf = grub_malloc (sz); - if (!buf) - return grub_errno; - - if (grub_file_read (elf->file, buf, sz) != (grub_ssize_t) sz) - { - if (grub_errno) - return grub_errno; - return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - elf->file->name); - } - for (ptr = buf; ptr - buf < (grub_ssize_t) (sz / sizeof (grub_uint32_t));) - { - Elf_Nhdr *nh = (Elf_Nhdr *) ptr; - char *name; - grub_uint32_t *desc; - grub_uint32_t namesz, descsz; - ptr += sizeof (*nh) / sizeof (grub_uint32_t); - name = (char *) ptr; - namesz = grub_le_to_cpu32 (nh->n_namesz); - descsz = grub_le_to_cpu32 (nh->n_descsz); - ptr += (namesz + 3) / 4; - desc = ptr; - ptr += (grub_le_to_cpu32 (nh->n_descsz) + 3) / 4; - if ((namesz < 3) || grub_memcmp (name, "Xen", namesz == 3 ? 3 : 4) != 0) - continue; - xi->has_note = 1; - switch (nh->n_type) - { - case XEN_ELFNOTE_ENTRY: - xi->entry_point = grub_le_to_cpu_addr (*(Elf_Addr *) desc); - break; - case XEN_ELFNOTE_HYPERCALL_PAGE: - xi->hypercall_page = grub_le_to_cpu_addr (*(Elf_Addr *) desc); - xi->has_hypercall_page = 1; - break; - case XEN_ELFNOTE_VIRT_BASE: - xi->virt_base = grub_le_to_cpu_addr (*(Elf_Addr *) desc); - break; - case XEN_ELFNOTE_PADDR_OFFSET: - xi->paddr_offset = grub_le_to_cpu_addr (*(Elf_Addr *) desc); - break; - case XEN_ELFNOTE_XEN_VERSION: - grub_dprintf ("xen", "xenversion = `%s'\n", (char *) desc); - break; - case XEN_ELFNOTE_GUEST_OS: - grub_dprintf ("xen", "name = `%s'\n", (char *) desc); - break; - case XEN_ELFNOTE_GUEST_VERSION: - grub_dprintf ("xen", "version = `%s'\n", (char *) desc); - break; - case XEN_ELFNOTE_LOADER: - if (descsz < 7 - || grub_memcmp (desc, "generic", descsz == 7 ? 7 : 8) != 0) - return grub_error (GRUB_ERR_BAD_OS, "invalid loader"); - break; - /* PAE */ - case XEN_ELFNOTE_PAE_MODE: - grub_dprintf ("xen", "pae = `%s', %d, %d\n", (char *) desc, - xi->arch, descsz); - if (xi->arch != GRUB_XEN_FILE_I386 - && xi->arch != GRUB_XEN_FILE_I386_PAE - && xi->arch != GRUB_XEN_FILE_I386_PAE_BIMODE) - break; - if (descsz >= 3 && grub_memcmp (desc, "yes", - descsz == 3 ? 3 : 4) == 0) - { - xi->extended_cr3 = 1; - xi->arch = GRUB_XEN_FILE_I386_PAE; - } - if (descsz >= 7 && grub_memcmp (desc, "bimodal", - descsz == 7 ? 7 : 8) == 0) - { - xi->extended_cr3 = 1; - xi->arch = GRUB_XEN_FILE_I386_PAE_BIMODE; - } - if (descsz >= 11 && grub_memcmp (desc, "yes,bimodal", - descsz == 11 ? 11 : 12) == 0) - { - xi->extended_cr3 = 1; - xi->arch = GRUB_XEN_FILE_I386_PAE_BIMODE; - } - if (descsz >= 2 && grub_memcmp (desc, "no", - descsz == 2 ? 2 : 3) == 0) - xi->arch = GRUB_XEN_FILE_I386; - break; - case XEN_ELFNOTE_INIT_P2M: - xi->p2m_base = grub_le_to_cpu_addr (*(Elf_Addr *) desc); - xi->has_p2m_base = 1; - break; - case XEN_ELFNOTE_MOD_START_PFN: - xi->unmapped_initrd = !!grub_le_to_cpu32(*(grub_uint32_t *) desc); - break; - default: - grub_dprintf ("xen", "unknown note type %d\n", nh->n_type); - break; - } - } - return GRUB_ERR_NONE; -} - -grub_err_t -grub_xen_get_infoXX (grub_elf_t elf, struct grub_xen_file_info *xi) -{ - Elf_Shdr *s, *s0; - grub_size_t shnum = elf->ehdr.ehdrXX.e_shnum; - grub_size_t shentsize = elf->ehdr.ehdrXX.e_shentsize; - grub_size_t shsize = shnum * shentsize; - grub_off_t stroff; - grub_err_t err; - Elf_Phdr *phdr; - - xi->kern_end = 0; - xi->kern_start = ~0; - xi->entry_point = elf->ehdr.ehdrXX.e_entry; - - /* FIXME: check note. */ - FOR_ELF_PHDRS (elf, phdr) - { - Elf_Addr paddr; - - if (phdr->p_type == PT_NOTE) - { - err = parse_note (elf, xi, phdr->p_offset, phdr->p_filesz); - if (err) - return err; - } - - if (phdr->p_type != PT_LOAD) - continue; - - paddr = phdr->p_paddr; - - if (paddr < xi->kern_start) - xi->kern_start = paddr; - - if (paddr + phdr->p_memsz > xi->kern_end) - xi->kern_end = paddr + phdr->p_memsz; - } - - if (xi->has_note) - return GRUB_ERR_NONE; - - if (!shnum || !shentsize) - return grub_error (GRUB_ERR_BAD_OS, "no XEN note"); - - s0 = grub_malloc (shsize); - if (!s0) - return grub_errno; - - if (grub_file_seek (elf->file, elf->ehdr.ehdrXX.e_shoff) == (grub_off_t) -1) - { - err = grub_errno; - goto cleanup; - } - - if (grub_file_read (elf->file, s0, shsize) != (grub_ssize_t) shsize) - { - if (grub_errno) - err = grub_errno; - else - err = grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - elf->file->name); - goto cleanup; - } - - s = (Elf_Shdr *) ((char *) s0 + elf->ehdr.ehdrXX.e_shstrndx * shentsize); - stroff = s->sh_offset; - - for (s = s0; s < (Elf_Shdr *) ((char *) s0 + shnum * shentsize); - s = (Elf_Shdr *) ((char *) s + shentsize)) - { - if (s->sh_type == SHT_NOTE) - { - err = parse_note (elf, xi, s->sh_offset, s->sh_size); - if (err) - goto cleanup; - } - } - - if (xi->has_note) - { - err = GRUB_ERR_NONE; - goto cleanup; - } - - for (s = s0; s < (Elf_Shdr *) ((char *) s0 + shnum * shentsize); - s = (Elf_Shdr *) ((char *) s + shentsize)) - { - char name[sizeof("__xen_guest")]; - grub_memset (name, 0, sizeof (name)); - if (grub_file_seek (elf->file, stroff + s->sh_name) == (grub_off_t) -1) - { - err = grub_errno; - goto cleanup; - } - - if (grub_file_read (elf->file, name, sizeof (name)) != (grub_ssize_t) sizeof (name)) - { - if (grub_errno) - { - err = grub_errno; - goto cleanup; - } - continue; - } - if (grub_memcmp (name, "__xen_guest", - sizeof("__xen_guest")) != 0) - continue; - err = parse_xen_guest (elf, xi, s->sh_offset, s->sh_size); - goto cleanup; - } - err = grub_error (GRUB_ERR_BAD_OS, "no XEN note found"); - -cleanup: - grub_free (s0); - return err; -} diff --git a/grub-core/loader/ia64/efi/linux.c b/grub-core/loader/ia64/efi/linux.c deleted file mode 100644 index 99cb244d8..000000000 --- a/grub-core/loader/ia64/efi/linux.c +++ /dev/null @@ -1,608 +0,0 @@ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#pragma GCC diagnostic ignored "-Wcast-align" - -#define ALIGN_MIN (256*1024*1024) - -#define GRUB_ELF_SEARCH 1024 - -#define BOOT_PARAM_SIZE 16384 - -struct ia64_boot_param -{ - grub_uint64_t command_line; /* physical address of command line. */ - grub_uint64_t efi_systab; /* physical address of EFI system table */ - grub_uint64_t efi_memmap; /* physical address of EFI memory map */ - grub_uint64_t efi_memmap_size; /* size of EFI memory map */ - grub_uint64_t efi_memdesc_size; /* size of an EFI memory map descriptor */ - grub_uint32_t efi_memdesc_version; /* memory descriptor version */ - struct - { - grub_uint16_t num_cols; /* number of columns on console output dev */ - grub_uint16_t num_rows; /* number of rows on console output device */ - grub_uint16_t orig_x; /* cursor's x position */ - grub_uint16_t orig_y; /* cursor's y position */ - } console_info; - grub_uint64_t fpswa; /* physical address of the fpswa interface */ - grub_uint64_t initrd_start; - grub_uint64_t initrd_size; -}; - -typedef struct -{ - grub_uint32_t revision; - grub_uint32_t reserved; - void *fpswa; -} fpswa_interface_t; -static fpswa_interface_t *fpswa; - -#define NEXT_MEMORY_DESCRIPTOR(desc, size) \ - ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) - -static grub_dl_t my_mod; - -static int loaded; - -/* Kernel base and size. */ -static void *kernel_mem; -static grub_efi_uintn_t kernel_pages; -static grub_uint64_t entry; - -/* Initrd base and size. */ -static void *initrd_mem; -static grub_efi_uintn_t initrd_pages; -static grub_efi_uintn_t initrd_size; - -static struct ia64_boot_param *boot_param; -static grub_efi_uintn_t boot_param_pages; - -static inline grub_size_t -page_align (grub_size_t size) -{ - return (size + (1 << 12) - 1) & (~((1 << 12) - 1)); -} - -static void -query_fpswa (void) -{ - grub_efi_handle_t fpswa_image; - grub_efi_boot_services_t *bs; - grub_efi_status_t status; - grub_efi_uintn_t size; - static const grub_guid_t fpswa_protocol = - { 0xc41b6531, 0x97b9, 0x11d3, - {0x9a, 0x29, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }; - - if (fpswa != NULL) - return; - - size = sizeof(grub_efi_handle_t); - - bs = grub_efi_system_table->boot_services; - status = bs->locate_handle (GRUB_EFI_BY_PROTOCOL, - (void *) &fpswa_protocol, - NULL, &size, &fpswa_image); - if (status != GRUB_EFI_SUCCESS) - { - grub_printf ("%s\n", _("Could not locate FPSWA driver")); - return; - } - status = bs->handle_protocol (fpswa_image, - (void *) &fpswa_protocol, (void *) &fpswa); - if (status != GRUB_EFI_SUCCESS) - { - grub_printf ("%s\n", - _("FPSWA protocol wasn't able to find the interface")); - return; - } -} - -static void -free_pages (void) -{ - if (kernel_mem) - { - grub_efi_free_pages ((grub_addr_t) kernel_mem, kernel_pages); - kernel_mem = 0; - } - - if (initrd_mem) - { - grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages); - initrd_mem = 0; - } - - if (boot_param) - { - /* Free bootparam. */ - grub_efi_free_pages ((grub_efi_physical_address_t) boot_param, - boot_param_pages); - boot_param = 0; - } -} - -static void * -allocate_pages (grub_uint64_t align, grub_uint64_t size_pages, - grub_uint64_t nobase) -{ - grub_uint64_t 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; - void *mem = NULL; - - size = size_pages << 12; - - mmap_size = grub_efi_find_mmap_size (); - if (!mmap_size) - return 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_error (GRUB_ERR_IO, "cannot get memory map"); - goto fail; - } - - 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)) - { - grub_uint64_t start, end; - grub_uint64_t aligned_start; - - if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY) - continue; - - start = desc->physical_start; - end = start + (desc->num_pages << 12); - /* Align is a power of 2. */ - aligned_start = (start + align - 1) & ~(align - 1); - if (aligned_start + size > end) - continue; - if (aligned_start == nobase) - aligned_start += align; - if (aligned_start + size > end) - continue; - mem = grub_efi_allocate_fixed (aligned_start, size_pages); - if (! mem) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory"); - goto fail; - } - break; - } - - if (! mem) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory"); - goto fail; - } - - grub_free (mmap); - return mem; - - fail: - grub_free (mmap); - free_pages (); - return 0; -} - -static void -set_boot_param_console (void) -{ - grub_efi_simple_text_output_interface_t *conout; - grub_efi_uintn_t cols, rows; - - conout = grub_efi_system_table->con_out; - if (conout->query_mode (conout, conout->mode->mode, &cols, &rows) - != GRUB_EFI_SUCCESS) - return; - - grub_dprintf ("linux", - "Console info: cols=%lu rows=%lu x=%u y=%u\n", - cols, rows, - conout->mode->cursor_column, conout->mode->cursor_row); - - boot_param->console_info.num_cols = cols; - boot_param->console_info.num_rows = rows; - boot_param->console_info.orig_x = conout->mode->cursor_column; - boot_param->console_info.orig_y = conout->mode->cursor_row; -} - -static grub_err_t -grub_linux_boot (void) -{ - grub_efi_uintn_t mmap_size; - grub_efi_uintn_t map_key; - grub_efi_uintn_t desc_size; - grub_efi_uint32_t desc_version; - grub_efi_memory_descriptor_t *mmap_buf; - grub_err_t err; - - /* FPSWA. */ - query_fpswa (); - boot_param->fpswa = (grub_uint64_t)fpswa; - - /* Initrd. */ - boot_param->initrd_start = (grub_uint64_t)initrd_mem; - boot_param->initrd_size = (grub_uint64_t)initrd_size; - - set_boot_param_console (); - - grub_dprintf ("linux", "Jump to %016lx\n", entry); - - /* MDT. - Must be done after grub_machine_fini because map_key is used by - exit_boot_services. */ - mmap_size = grub_efi_find_mmap_size (); - if (! mmap_size) - return grub_errno; - mmap_buf = grub_efi_allocate_any_pages (page_align (mmap_size) >> 12); - if (! mmap_buf) - return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); - err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, &map_key, - &desc_size, &desc_version); - if (err) - return err; - - boot_param->efi_memmap = (grub_uint64_t)mmap_buf; - boot_param->efi_memmap_size = mmap_size; - boot_param->efi_memdesc_size = desc_size; - boot_param->efi_memdesc_version = desc_version; - - /* See you next boot. */ - asm volatile ("mov r28=%1; br.sptk.few %0" :: "b"(entry),"r"(boot_param)); - - /* 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_err_t -grub_load_elf64 (grub_file_t file, void *buffer, const char *filename) -{ - Elf64_Ehdr *ehdr = (Elf64_Ehdr *) buffer; - Elf64_Phdr *phdr; - int i; - grub_uint64_t low_addr; - grub_uint64_t high_addr; - grub_uint64_t align; - grub_uint64_t reloc_offset; - const char *relocate; - - 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_ident[EI_DATA] != ELFDATA2LSB) - return grub_error(GRUB_ERR_UNKNOWN_OS, - N_("invalid arch-independent ELF magic")); - - if (ehdr->e_ident[EI_CLASS] != ELFCLASS64 - || ehdr->e_version != EV_CURRENT - || ehdr->e_machine != EM_IA_64) - return grub_error (GRUB_ERR_UNKNOWN_OS, - N_("invalid arch-dependent ELF magic")); - - if (ehdr->e_type != ET_EXEC) - return grub_error (GRUB_ERR_UNKNOWN_OS, - N_("this ELF file is not of the right type")); - - /* FIXME: Should we support program headers at strange locations? */ - if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > GRUB_ELF_SEARCH) - return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset"); - - entry = ehdr->e_entry; - - /* Compute low, high and align addresses. */ - low_addr = ~0UL; - high_addr = 0; - align = 0; - for (i = 0; i < ehdr->e_phnum; i++) - { - phdr = (Elf64_Phdr *) ((char *) buffer + ehdr->e_phoff - + i * ehdr->e_phentsize); - if (phdr->p_type == PT_LOAD) - { - if (phdr->p_paddr < low_addr) - low_addr = phdr->p_paddr; - if (phdr->p_paddr + phdr->p_memsz > high_addr) - high_addr = phdr->p_paddr + phdr->p_memsz; - if (phdr->p_align > align) - align = phdr->p_align; - } - } - - if (align < ALIGN_MIN) - align = ALIGN_MIN; - - if (high_addr == 0) - return grub_error (GRUB_ERR_BAD_OS, "no program entries"); - - kernel_pages = page_align (high_addr - low_addr) >> 12; - - /* Undocumented on purpose. */ - relocate = grub_env_get ("linux_relocate"); - if (!relocate || grub_strcmp (relocate, "force") != 0) - { - kernel_mem = grub_efi_allocate_fixed (low_addr, kernel_pages); - reloc_offset = 0; - grub_errno = GRUB_ERR_NONE; - } - /* Try to relocate. */ - if (! kernel_mem && (!relocate || grub_strcmp (relocate, "off") != 0)) - { - kernel_mem = allocate_pages (align, kernel_pages, low_addr); - if (kernel_mem) - { - reloc_offset = (grub_uint64_t)kernel_mem - low_addr; - grub_dprintf ("linux", " Relocated at %p (offset=%016lx)\n", - kernel_mem, reloc_offset); - entry += reloc_offset; - } - } - if (! kernel_mem) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "cannot allocate memory for OS"); - - /* Load every loadable segment in memory. */ - for (i = 0; i < ehdr->e_phnum; i++) - { - phdr = (Elf64_Phdr *) ((char *) buffer + ehdr->e_phoff - + i * ehdr->e_phentsize); - if (phdr->p_type == PT_LOAD) - { - grub_dprintf ("linux", " [paddr=%lx load=%lx memsz=%08lx " - "off=%lx flags=%x]\n", - phdr->p_paddr, phdr->p_paddr + reloc_offset, - phdr->p_memsz, phdr->p_offset, phdr->p_flags); - - if (grub_file_seek (file, phdr->p_offset) == (grub_off_t)-1) - return grub_errno; - - if (grub_file_read (file, (void *) (phdr->p_paddr + reloc_offset), - phdr->p_filesz) - != (grub_ssize_t) phdr->p_filesz) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - return grub_errno; - } - - if (phdr->p_filesz < phdr->p_memsz) - grub_memset - ((char *)(phdr->p_paddr + reloc_offset + phdr->p_filesz), - 0, phdr->p_memsz - phdr->p_filesz); - - /* Sync caches if necessary. */ - if (phdr->p_flags & PF_X) - grub_arch_sync_caches - ((void *)(phdr->p_paddr + reloc_offset), phdr->p_memsz); - } - } - loaded = 1; - return 0; -} - -static grub_err_t -grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_file_t file = 0; - char buffer[GRUB_ELF_SEARCH]; - char *cmdline, *p; - grub_ssize_t len; - int i; - - grub_dl_ref (my_mod); - - grub_loader_unset (); - - if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); - if (! file) - goto fail; - - len = grub_file_read (file, buffer, sizeof (buffer)); - if (len < (grub_ssize_t) sizeof (Elf64_Ehdr)) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - argv[0]); - goto fail; - } - - grub_dprintf ("linux", "Loading linux: %s\n", argv[0]); - - if (grub_load_elf64 (file, buffer, argv[0])) - goto fail; - - len = sizeof("BOOT_IMAGE=") + 8; - for (i = 0; i < argc; i++) - len += grub_strlen (argv[i]) + 1; - len += sizeof (struct ia64_boot_param) + 512; /* Room for extensions. */ - boot_param_pages = page_align (len) >> 12; - boot_param = grub_efi_allocate_any_pages (boot_param_pages); - if (boot_param == 0) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, - "cannot allocate memory for bootparams"); - goto fail; - } - - grub_memset (boot_param, 0, len); - cmdline = ((char *)(boot_param + 1)) + 256; - - /* Build cmdline. */ - p = grub_stpcpy (cmdline, "BOOT_IMAGE"); - for (i = 0; i < argc; i++) - { - *p++ = ' '; - p = grub_stpcpy (p, argv[i]); - } - cmdline[10] = '='; - - *p = '\0'; - - if (grub_verify_string (cmdline, GRUB_VERIFY_KERNEL_CMDLINE)) - goto fail; - - boot_param->command_line = (grub_uint64_t) cmdline; - boot_param->efi_systab = (grub_uint64_t) grub_efi_system_table; - - grub_errno = GRUB_ERR_NONE; - - grub_loader_set (grub_linux_boot, grub_linux_unload, 0); - - fail: - if (file) - grub_file_close (file); - - if (grub_errno != GRUB_ERR_NONE) - { - grub_efi_free_pages ((grub_efi_physical_address_t) boot_param, - boot_param_pages); - 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[]) -{ - struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; - - if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - if (! loaded) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); - goto fail; - } - - if (grub_initrd_init (argc, argv, &initrd_ctx)) - goto fail; - - initrd_size = grub_get_initrd_size (&initrd_ctx); - grub_dprintf ("linux", "Loading initrd\n"); - - initrd_pages = (page_align (initrd_size) >> 12); - initrd_mem = grub_efi_allocate_any_pages (initrd_pages); - if (! initrd_mem) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate pages"); - goto fail; - } - - grub_dprintf ("linux", "[addr=0x%lx, size=0x%lx]\n", - (grub_uint64_t) initrd_mem, initrd_size); - - if (grub_initrd_load (&initrd_ctx, initrd_mem)) - goto fail; - fail: - grub_initrd_close (&initrd_ctx); - return grub_errno; -} - -static grub_err_t -grub_cmd_fpswa (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__((unused)), - char *argv[] __attribute__((unused))) -{ - query_fpswa (); - if (fpswa == NULL) - grub_puts_ (N_("No FPSWA found")); - else - grub_printf (_("FPSWA revision: %x\n"), fpswa->revision); - return GRUB_ERR_NONE; -} - -static grub_command_t cmd_linux, cmd_initrd, cmd_fpswa; - -GRUB_MOD_INIT(linux) -{ - cmd_linux = grub_register_command ("linux", grub_cmd_linux, - N_("FILE [ARGS...]"), N_("Load Linux.")); - - cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, - N_("FILE"), N_("Load initrd.")); - - cmd_fpswa = grub_register_command ("fpswa", grub_cmd_fpswa, - "", N_("Display FPSWA version.")); - - my_mod = mod; -} - -GRUB_MOD_FINI(linux) -{ - grub_unregister_command (cmd_linux); - grub_unregister_command (cmd_initrd); - grub_unregister_command (cmd_fpswa); -} diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c deleted file mode 100644 index 56bc1be58..000000000 --- a/grub-core/loader/linux.c +++ /dev/null @@ -1,348 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -struct newc_head -{ - char magic[6]; - char ino[8]; - char mode[8]; - char uid[8]; - char gid[8]; - char nlink[8]; - char mtime[8]; - char filesize[8]; - char devmajor[8]; - char devminor[8]; - char rdevmajor[8]; - char rdevminor[8]; - char namesize[8]; - char check[8]; -} GRUB_PACKED; - -struct grub_linux_initrd_component -{ - grub_file_t file; - char *newc_name; - grub_off_t size; -}; - -struct dir -{ - char *name; - struct dir *next; - struct dir *child; -}; - -static char -hex (grub_uint8_t val) -{ - if (val < 10) - return '0' + val; - return 'a' + val - 10; -} - -static void -set_field (char *var, grub_uint32_t val) -{ - int i; - char *ptr = var; - for (i = 28; i >= 0; i -= 4) - *ptr++ = hex((val >> i) & 0xf); -} - -static grub_uint8_t * -make_header (grub_uint8_t *ptr, - const char *name, grub_size_t len, - grub_uint32_t mode, - grub_off_t fsize) -{ - struct newc_head *head = (struct newc_head *) ptr; - grub_uint8_t *optr; - grub_size_t oh = 0; - - grub_dprintf ("linux", "newc: Creating path '%s', mode=%s%o, size=%" PRIuGRUB_OFFSET "\n", name, (mode == 0) ? "" : "0", mode, fsize); - grub_memcpy (head->magic, "070701", 6); - set_field (head->ino, 0); - set_field (head->mode, mode); - set_field (head->uid, 0); - set_field (head->gid, 0); - set_field (head->nlink, 1); - set_field (head->mtime, 0); - set_field (head->filesize, fsize); - set_field (head->devmajor, 0); - set_field (head->devminor, 0); - set_field (head->rdevmajor, 0); - set_field (head->rdevminor, 0); - set_field (head->namesize, len); - set_field (head->check, 0); - optr = ptr; - ptr += sizeof (struct newc_head); - grub_memcpy (ptr, name, len); - ptr += len; - oh = ALIGN_UP_OVERHEAD (ptr - optr, 4); - grub_memset (ptr, 0, oh); - ptr += oh; - return ptr; -} - -static void -free_dir (struct dir *root) -{ - if (!root) - return; - free_dir (root->next); - free_dir (root->child); - grub_free (root->name); - grub_free (root); -} - -static grub_err_t -insert_dir (const char *name, struct dir **root, - grub_uint8_t *ptr, grub_size_t *size) -{ - struct dir *cur, **head = root; - const char *cb, *ce = name; - *size = 0; - - while (1) - { - for (cb = ce; *cb == '/'; cb++); - for (ce = cb; *ce && *ce != '/'; ce++); - if (!*ce) - break; - - for (cur = *root; cur; cur = cur->next) - if (grub_memcmp (cur->name, cb, ce - cb) == 0 - && cur->name[ce - cb] == 0) - break; - if (!cur) - { - struct dir *n; - n = grub_zalloc (sizeof (*n)); - if (!n) - return 0; - n->next = *head; - n->name = grub_strndup (cb, ce - cb); - if (ptr) - { - /* - * Create the substring with the trailing NUL byte - * to be included in the cpio header. - */ - char *tmp_name = grub_strndup (name, ce - name); - if (!tmp_name) { - grub_free (n->name); - grub_free (n); - return grub_errno; - } - ptr = make_header (ptr, tmp_name, ce - name + 1, - 040777, 0); - grub_free (tmp_name); - } - if (grub_add (*size, - ALIGN_UP ((ce - (char *) name + 1) - + sizeof (struct newc_head), 4), - size)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); - grub_free (n->name); - grub_free (n); - return grub_errno; - } - *head = n; - cur = n; - } - root = &cur->next; - } - return GRUB_ERR_NONE; -} - -grub_err_t -grub_initrd_init (int argc, char *argv[], - struct grub_linux_initrd_context *initrd_ctx) -{ - int i; - int newc = 0; - struct dir *root = 0; - - initrd_ctx->nfiles = 0; - initrd_ctx->components = 0; - - initrd_ctx->components = grub_calloc (argc, sizeof (initrd_ctx->components[0])); - if (!initrd_ctx->components) - return grub_errno; - - initrd_ctx->size = 0; - - for (i = 0; i < argc; i++) - { - const char *fname = argv[i]; - - initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); - - if (grub_memcmp (argv[i], "newc:", 5) == 0) - { - const char *ptr, *eptr; - ptr = argv[i] + 5; - while (*ptr == '/') - ptr++; - eptr = grub_strchr (ptr, ':'); - if (eptr) - { - grub_size_t dir_size, name_len; - - initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr); - if (!initrd_ctx->components[i].newc_name || - insert_dir (initrd_ctx->components[i].newc_name, &root, 0, - &dir_size)) - { - grub_initrd_close (initrd_ctx); - return grub_errno; - } - name_len = grub_strlen (initrd_ctx->components[i].newc_name) + 1; - if (grub_add (initrd_ctx->size, - ALIGN_UP (sizeof (struct newc_head) + name_len, 4), - &initrd_ctx->size) || - grub_add (initrd_ctx->size, dir_size, &initrd_ctx->size)) - goto overflow; - newc = 1; - fname = eptr + 1; - } - } - else if (newc) - { - if (grub_add (initrd_ctx->size, - ALIGN_UP (sizeof (struct newc_head) - + sizeof ("TRAILER!!!"), 4), - &initrd_ctx->size)) - goto overflow; - free_dir (root); - root = 0; - newc = 0; - } - initrd_ctx->components[i].file = grub_file_open (fname, - GRUB_FILE_TYPE_LINUX_INITRD - | GRUB_FILE_TYPE_NO_DECOMPRESS); - if (!initrd_ctx->components[i].file) - { - grub_initrd_close (initrd_ctx); - return grub_errno; - } - initrd_ctx->nfiles++; - initrd_ctx->components[i].size - = grub_file_size (initrd_ctx->components[i].file); - if (grub_add (initrd_ctx->size, initrd_ctx->components[i].size, - &initrd_ctx->size)) - goto overflow; - } - - if (newc) - { - initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); - if (grub_add (initrd_ctx->size, - ALIGN_UP (sizeof (struct newc_head) - + sizeof ("TRAILER!!!"), 4), - &initrd_ctx->size)) - goto overflow; - free_dir (root); - root = 0; - } - - return GRUB_ERR_NONE; - - overflow: - free_dir (root); - grub_initrd_close (initrd_ctx); - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); -} - -grub_size_t -grub_get_initrd_size (struct grub_linux_initrd_context *initrd_ctx) -{ - return initrd_ctx->size; -} - -void -grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx) -{ - int i; - if (!initrd_ctx->components) - return; - for (i = 0; i < initrd_ctx->nfiles; i++) - { - grub_free (initrd_ctx->components[i].newc_name); - grub_file_close (initrd_ctx->components[i].file); - } - grub_free (initrd_ctx->components); - initrd_ctx->components = 0; -} - -grub_err_t -grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, - void *target) -{ - grub_uint8_t *ptr = target; - int i; - int newc = 0; - struct dir *root = 0; - grub_ssize_t cursize = 0; - - for (i = 0; i < initrd_ctx->nfiles; i++) - { - grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); - ptr += ALIGN_UP_OVERHEAD (cursize, 4); - - if (initrd_ctx->components[i].newc_name) - { - grub_size_t dir_size; - - if (insert_dir (initrd_ctx->components[i].newc_name, &root, ptr, - &dir_size)) - { - free_dir (root); - grub_initrd_close (initrd_ctx); - return grub_errno; - } - ptr += dir_size; - ptr = make_header (ptr, initrd_ctx->components[i].newc_name, - grub_strlen (initrd_ctx->components[i].newc_name) + 1, - 0100777, - initrd_ctx->components[i].size); - newc = 1; - } - else if (newc) - { - ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!"), - 0, 0); - free_dir (root); - root = 0; - newc = 0; - } - - cursize = initrd_ctx->components[i].size; - if (grub_file_read (initrd_ctx->components[i].file, ptr, cursize) - != cursize) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - initrd_ctx->components[i].file->name); - grub_initrd_close (initrd_ctx); - return grub_errno; - } - ptr += cursize; - } - if (newc) - { - grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); - ptr += ALIGN_UP_OVERHEAD (cursize, 4); - ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!"), 0, 0); - } - free_dir (root); - root = 0; - return GRUB_ERR_NONE; -} diff --git a/grub-core/loader/lzss.c b/grub-core/loader/lzss.c deleted file mode 100644 index 2c3e4507f..000000000 --- a/grub-core/loader/lzss.c +++ /dev/null @@ -1,56 +0,0 @@ -/************************************************************** - LZSS.C -- A Data Compression Program - (tab = 4 spaces) -*************************************************************** - 4/6/1989 Haruhiko Okumura - Use, distribute, and modify this program freely. - Please send me your improved versions. - PC-VAN SCIENCE - NIFTY-Serve PAF01022 - CompuServe 74050,1022 -**************************************************************/ - -#include -#include - -#define N 4096 /* size of ring buffer */ -#define F 18 /* upper limit for match_length */ -#define THRESHOLD 2 /* encode string into position and length - if match_length is greater than this */ -#define NIL N /* index for root of binary search trees */ - -#define EOF -1 -#define getc(file) ((src < srcend) ? *src++ : EOF) -#define putc(c, file) (dst < dstend) ? (*dst++ = (c)) : 0; - -grub_size_t -grub_decompress_lzss (grub_uint8_t *dst, grub_uint8_t *dstend, - grub_uint8_t *src, grub_uint8_t *srcend) -{ - int i, j, k, r, c; - unsigned int flags; - static unsigned char text_buf[N + F - 1]; - grub_uint8_t *dst0 = dst; - - for (i = 0; i < N - F; i++) text_buf[i] = ' '; - r = N - F; flags = 0; - for ( ; ; ) { - if (((flags >>= 1) & 256) == 0) { - if ((c = getc(infile)) == EOF) break; - flags = c | 0xff00; /* uses higher byte cleverly */ - } /* to count eight */ - if (flags & 1) { - if ((c = getc(infile)) == EOF) break; - putc(c, outfile); text_buf[r++] = c; r &= (N - 1); - } else { - if ((i = getc(infile)) == EOF) break; - if ((j = getc(infile)) == EOF) break; - i |= ((j & 0xf0) << 4); j = (j & 0x0f) + THRESHOLD; - for (k = 0; k <= j; k++) { - c = text_buf[(i + k) & (N - 1)]; - putc(c, outfile); text_buf[r++] = c; r &= (N - 1); - } - } - } - return dst - dst0; -} diff --git a/grub-core/loader/machoXX.c b/grub-core/loader/machoXX.c deleted file mode 100644 index 95c3fe564..000000000 --- a/grub-core/loader/machoXX.c +++ /dev/null @@ -1,384 +0,0 @@ - -#include -#include -#include -#include - -#define min(a,b) (((a) < (b)) ? (a) : (b)) - -static int -SUFFIX (grub_macho_contains_macho) (grub_macho_t macho) -{ - return macho->offsetXX != -1; -} - -void -SUFFIX (grub_macho_parse) (grub_macho_t macho, const char *filename) -{ - union { - struct grub_macho_lzss_header lzss; - grub_macho_header_t macho; - } 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)) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - macho->offsetXX = -1; - return; - } - if (grub_memcmp (head.lzss.magic, GRUB_MACHO_LZSS_MAGIC, - sizeof (head.lzss.magic)) == 0) - { - macho->compressed_sizeXX = grub_be_to_cpu32 (head.lzss.compressed_size); - macho->uncompressed_sizeXX - = grub_be_to_cpu32 (head.lzss.uncompressed_size); - if (macho->uncompressed_sizeXX < sizeof (head.macho)) - { - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - macho->offsetXX = -1; - return; - } - /* Skip header check. */ - macho->compressedXX = 1; - return; - } - - if (head.macho.magic != GRUB_MACHO_MAGIC) - { - grub_error (GRUB_ERR_BAD_OS, "invalid Mach-O header"); - macho->offsetXX = -1; - return; - } - - /* Read commands. */ - macho->ncmdsXX = head.macho.ncmds; - macho->cmdsizeXX = head.macho.sizeofcmds; - macho->cmdsXX = grub_malloc (macho->cmdsizeXX); - if (! macho->cmdsXX) - return; - if (grub_file_seek (macho->file, macho->offsetXX - + sizeof (grub_macho_header_t)) == (grub_off_t) -1 - || grub_file_read (macho->file, macho->cmdsXX, - (grub_size_t) macho->cmdsizeXX) - != (grub_ssize_t) macho->cmdsizeXX) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - macho->offsetXX = -1; - } -} - -typedef int (*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, - const char *filename) -{ - grub_uint8_t *hdrs; - int i; - - if (macho->compressedXX && !macho->uncompressedXX) - { - grub_uint8_t *tmp; - grub_macho_header_t *head; - macho->uncompressedXX = grub_malloc (macho->uncompressed_sizeXX); - if (!macho->uncompressedXX) - return grub_errno; - tmp = grub_malloc (macho->compressed_sizeXX); - if (!tmp) - { - grub_free (macho->uncompressedXX); - macho->uncompressedXX = 0; - return grub_errno; - } - if (grub_file_seek (macho->file, macho->offsetXX - + GRUB_MACHO_LZSS_OFFSET) == (grub_off_t) -1 - || grub_file_read (macho->file, tmp, - (grub_size_t) macho->compressed_sizeXX) - != (grub_ssize_t) macho->compressed_sizeXX) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - grub_free (tmp); - grub_free (macho->uncompressedXX); - macho->uncompressedXX = 0; - macho->offsetXX = -1; - return grub_errno; - } - if (grub_decompress_lzss (macho->uncompressedXX, - macho->uncompressedXX - + macho->uncompressed_sizeXX, - tmp, tmp + macho->compressed_sizeXX) - != macho->uncompressed_sizeXX) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - grub_free (tmp); - grub_free (macho->uncompressedXX); - macho->uncompressedXX = 0; - macho->offsetXX = -1; - return grub_errno; - } - grub_free (tmp); - head = (grub_macho_header_t *) macho->uncompressedXX; - macho->ncmdsXX = head->ncmds; - macho->cmdsizeXX = head->sizeofcmds; - macho->cmdsXX = macho->uncompressedXX + sizeof (grub_macho_header_t); - if (sizeof (grub_macho_header_t) + macho->cmdsizeXX - >= macho->uncompressed_sizeXX) - { - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - grub_free (macho->uncompressedXX); - macho->uncompressedXX = 0; - macho->offsetXX = -1; - return grub_errno; - } - } - - if (! macho->cmdsXX) - return grub_error (GRUB_ERR_BAD_OS, "couldn't find Mach-O commands"); - hdrs = macho->cmdsXX; - 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, - const char *filename, - 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) - return grub_errno; - - read = grub_file_read (macho->file, dest, - macho->endXX - macho->offsetXX); - if (read != (grub_ssize_t) (macho->endXX - macho->offsetXX)) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - return grub_errno; - } - return GRUB_ERR_NONE; -} - -struct calcsize_ctx -{ - int flags; - int nr_phdrs; - grub_macho_addr_t *segments_start; - grub_macho_addr_t *segments_end; -}; - -/* Run through the program headers to calculate the total memory size we - should claim. */ -static int -calcsize (grub_macho_t _macho __attribute__ ((unused)), - struct grub_macho_cmd *hdr0, - void *_arg) -{ - grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0; - struct calcsize_ctx *ctx = _arg; - if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT) - return 0; - - if (! hdr->vmsize) - return 0; - - if (! hdr->filesize && (ctx->flags & GRUB_MACHO_NOBSS)) - return 0; - - ctx->nr_phdrs++; - if (hdr->vmaddr < *ctx->segments_start) - *ctx->segments_start = hdr->vmaddr; - if (hdr->vmaddr + hdr->vmsize > *ctx->segments_end) - *ctx->segments_end = hdr->vmaddr + hdr->vmsize; - return 0; -} - -/* 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, - const char *filename) -{ - struct calcsize_ctx ctx = { - .flags = flags, - .nr_phdrs = 0, - .segments_start = segments_start, - .segments_end = segments_end, - }; - - *segments_start = (grub_macho_addr_t) -1; - *segments_end = 0; - - grub_macho_cmds_iterate (macho, calcsize, &ctx, filename); - - if (ctx.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; -} - -struct do_load_ctx -{ - int flags; - char *offset; - const char *filename; - int *darwin_version; -}; - -static int -do_load(grub_macho_t _macho, - struct grub_macho_cmd *hdr0, - void *_arg) -{ - grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0; - struct do_load_ctx *ctx = _arg; - - if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT) - return 0; - - if (! hdr->filesize && (ctx->flags & GRUB_MACHO_NOBSS)) - return 0; - if (! hdr->vmsize) - return 0; - - if (hdr->filesize) - { - grub_ssize_t read, toread = min (hdr->filesize, hdr->vmsize); - if (_macho->uncompressedXX) - { - if (hdr->fileoff + (grub_size_t) toread - > _macho->uncompressed_sizeXX) - read = -1; - else - { - read = toread; - grub_memcpy (ctx->offset + hdr->vmaddr, - _macho->uncompressedXX + hdr->fileoff, read); - } - } - else - { - if (grub_file_seek (_macho->file, hdr->fileoff - + _macho->offsetXX) == (grub_off_t) -1) - return 1; - read = grub_file_read (_macho->file, ctx->offset + hdr->vmaddr, - toread); - } - - if (read != toread) - { - /* XXX How can we free memory from `load_hook'? */ - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - ctx->filename); - - return 1; - } - if (ctx->darwin_version) - { - const char *ptr = ctx->offset + hdr->vmaddr; - const char *end = ptr + min (hdr->filesize, hdr->vmsize) - - (sizeof ("Darwin Kernel Version ") - 1); - for (; ptr < end; ptr++) - if (grub_memcmp (ptr, "Darwin Kernel Version ", - sizeof ("Darwin Kernel Version ") - 1) == 0) - { - ptr += sizeof ("Darwin Kernel Version ") - 1; - *ctx->darwin_version = 0; - end += (sizeof ("Darwin Kernel Version ") - 1); - while (ptr < end && grub_isdigit (*ptr)) - *ctx->darwin_version = (*ptr++ - '0') + *ctx->darwin_version * 10; - break; - } - } - } - - if (hdr->filesize < hdr->vmsize) - grub_memset (ctx->offset + hdr->vmaddr + hdr->filesize, - 0, hdr->vmsize - hdr->filesize); - return 0; -} - -/* Load every loadable segment into memory specified by `_load_hook'. */ -grub_err_t -SUFFIX (grub_macho_load) (grub_macho_t macho, const char *filename, - char *offset, int flags, int *darwin_version) -{ - struct do_load_ctx ctx = { - .flags = flags, - .offset = offset, - .filename = filename, - .darwin_version = darwin_version - }; - - if (darwin_version) - *darwin_version = 0; - - grub_macho_cmds_iterate (macho, do_load, &ctx, filename); - - return grub_errno; -} - -static int -find_entry_point (grub_macho_t _macho __attribute__ ((unused)), - struct grub_macho_cmd *hdr, - void *_arg) -{ - grub_macho_addr_t *entry_point = _arg; - if (hdr->cmd == GRUB_MACHO_CMD_THREAD) - *entry_point = ((grub_macho_thread_t *) hdr)->entry_point; - return 0; -} - -grub_macho_addr_t -SUFFIX (grub_macho_get_entry_point) (grub_macho_t macho, const char *filename) -{ - grub_macho_addr_t entry_point = 0; - grub_macho_cmds_iterate (macho, find_entry_point, &entry_point, filename); - return entry_point; -} diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c deleted file mode 100644 index 36b27a906..000000000 --- a/grub-core/loader/multiboot.c +++ /dev/null @@ -1,463 +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 . - */ - -/* - * FIXME: The following features from the Multiboot specification still - * need to be implemented: - * - drives table - * - ROM configuration table - * - SMBIOS tables - * - Networking information - */ - -#include -#include -#ifdef GRUB_USE_MULTIBOOT2 -#include -#define GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER GRUB_MULTIBOOT2_CONSOLE_FRAMEBUFFER -#define GRUB_MULTIBOOT_CONSOLE_EGA_TEXT GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT -#define GRUB_MULTIBOOT(x) grub_multiboot2_ ## x -#else -#include -#define GRUB_MULTIBOOT(x) grub_multiboot_ ## x -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#ifdef GRUB_MACHINE_EFI -#include -#endif - -struct grub_relocator *GRUB_MULTIBOOT (relocator) = NULL; -grub_uint32_t GRUB_MULTIBOOT (payload_eip); -#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 - -static int accepts_video; -static int accepts_ega_text; -static int console_required; -static grub_dl_t my_mod; - - -/* Helper for grub_get_multiboot_mmap_count. */ -static int -count_hook (grub_uint64_t addr __attribute__ ((unused)), - grub_uint64_t size __attribute__ ((unused)), - grub_memory_type_t type __attribute__ ((unused)), void *data) -{ - grub_size_t *count = data; - - (*count)++; - return 0; -} - -/* Return the length of the Multiboot mmap that will be needed to allocate - our platform's map. */ -grub_uint32_t -GRUB_MULTIBOOT (get_mmap_count) (void) -{ - grub_size_t count = 0; - - grub_mmap_iterate (count_hook, &count); - - return count; -} - -grub_err_t -GRUB_MULTIBOOT (set_video_mode) (void) -{ - grub_err_t err; - const char *modevar; - -#if GRUB_MACHINE_HAS_VGA_TEXT - if (accepts_video) -#endif - { - 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); - } - } -#if GRUB_MACHINE_HAS_VGA_TEXT - else - err = grub_video_set_mode ("text", 0, 0); -#endif - - return err; -} - -#ifdef GRUB_MACHINE_EFI -#ifdef __x86_64__ -#define grub_relocator_efi_boot grub_relocator64_efi_boot -#define grub_relocator_efi_state grub_relocator64_efi_state -#endif -#endif - -#ifdef grub_relocator_efi_boot -static void -efi_boot (struct grub_relocator *rel, - grub_uint32_t target) -{ -#ifdef GRUB_USE_MULTIBOOT2 - struct grub_relocator_efi_state state_efi = MULTIBOOT2_EFI_INITIAL_STATE; -#else - struct grub_relocator_efi_state state_efi = MULTIBOOT_EFI_INITIAL_STATE; -#endif - state_efi.MULTIBOOT_EFI_ENTRY_REGISTER = GRUB_MULTIBOOT (payload_eip); - state_efi.MULTIBOOT_EFI_MBI_REGISTER = target; - - grub_relocator_efi_boot (rel, state_efi); -} -#else -#define grub_efi_is_finished 1 -static void -efi_boot (struct grub_relocator *rel __attribute__ ((unused)), - grub_uint32_t target __attribute__ ((unused))) -{ -} -#endif - -#if defined (__i386__) || defined (__x86_64__) -static void -normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state) -{ - grub_relocator32_boot (rel, state, 0); -} -#else -static void -normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state) -{ - grub_relocator32_boot (rel, state); -} -#endif - -static grub_err_t -grub_multiboot_boot (void) -{ - grub_err_t err; - -#ifdef GRUB_USE_MULTIBOOT2 - struct grub_relocator32_state state = MULTIBOOT2_INITIAL_STATE; -#else - struct grub_relocator32_state state = MULTIBOOT_INITIAL_STATE; -#endif - state.MULTIBOOT_ENTRY_REGISTER = GRUB_MULTIBOOT (payload_eip); - - err = GRUB_MULTIBOOT (make_mbi) (&state.MULTIBOOT_MBI_REGISTER); - - if (err) - return err; - - if (grub_efi_is_finished) - normal_boot (GRUB_MULTIBOOT (relocator), state); - else - efi_boot (GRUB_MULTIBOOT (relocator), state.MULTIBOOT_MBI_REGISTER); - - /* Not reached. */ - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_multiboot_unload (void) -{ - GRUB_MULTIBOOT (free_mbi) (); - - grub_relocator_unload (GRUB_MULTIBOOT (relocator)); - GRUB_MULTIBOOT (relocator) = NULL; - - grub_dl_unref (my_mod); - - return GRUB_ERR_NONE; -} - -static grub_uint64_t highest_load; - -#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) (mbi_load_data_t *mld) -{ - if (grub_multiboot_is_elf32 (mld->buffer)) - return grub_multiboot_load_elf32 (mld); - else if (grub_multiboot_is_elf64 (mld->buffer)) - return grub_multiboot_load_elf64 (mld); - - return grub_error (GRUB_ERR_UNKNOWN_OS, N_("invalid arch-dependent ELF magic")); -} - -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_puts_ (N_("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 - { -#if GRUB_MACHINE_HAS_VGA_TEXT - grub_env_set ("gfxpayload", "text"); -#else - /* Always use video if no VGA text is available. */ - grub_env_set ("gfxpayload", "auto"); -#endif - } - - 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 (); - - highest_load = 0; - -#ifndef GRUB_USE_MULTIBOOT2 - grub_multiboot_quirks = GRUB_MULTIBOOT_QUIRKS_NONE; - int option_found = 0; - - do - { - option_found = 0; - if (argc != 0 && grub_strcmp (argv[0], "--quirk-bad-kludge") == 0) - { - argc--; - argv++; - option_found = 1; - grub_multiboot_quirks |= GRUB_MULTIBOOT_QUIRK_BAD_KLUDGE; - } - - if (argc != 0 && grub_strcmp (argv[0], "--quirk-modules-after-kernel") == 0) - { - argc--; - argv++; - option_found = 1; - grub_multiboot_quirks |= GRUB_MULTIBOOT_QUIRK_MODULES_AFTER_KERNEL; - } - } while (option_found); -#endif - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_MULTIBOOT_KERNEL); - if (! file) - return grub_errno; - - grub_dl_ref (my_mod); - - /* Skip filename. */ - GRUB_MULTIBOOT (init_mbi) (argc - 1, argv + 1); - - grub_relocator_unload (GRUB_MULTIBOOT (relocator)); - GRUB_MULTIBOOT (relocator) = grub_relocator_new (); - - if (!GRUB_MULTIBOOT (relocator)) - goto fail; - - err = GRUB_MULTIBOOT (load) (file, argv[0]); - 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_relocator_unload (GRUB_MULTIBOOT (relocator)); - GRUB_MULTIBOOT (relocator) = NULL; - 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; - void *module = NULL; - grub_addr_t target; - grub_err_t err; - int nounzip = 0; - grub_uint64_t lowest_addr = 0; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - if (grub_strcmp (argv[0], "--nounzip") == 0) - { - argv++; - argc--; - nounzip = 1; - } - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - - if (!GRUB_MULTIBOOT (relocator)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("you need to load the kernel first")); - - file = grub_file_open (argv[0], GRUB_FILE_TYPE_MULTIBOOT_MODULE - | (nounzip ? GRUB_FILE_TYPE_NO_DECOMPRESS : GRUB_FILE_TYPE_NONE)); - if (! file) - return grub_errno; - -#ifndef GRUB_USE_MULTIBOOT2 - lowest_addr = 0x100000; - if (grub_multiboot_quirks & GRUB_MULTIBOOT_QUIRK_MODULES_AFTER_KERNEL) - lowest_addr = ALIGN_UP (highest_load + 1048576, 4096); -#endif - - size = grub_file_size (file); - if (size) - { - grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch, - lowest_addr, UP_TO_TOP32 (size), - size, MULTIBOOT_MOD_ALIGN, - GRUB_RELOCATOR_PREFERENCE_NONE, 1); - if (err) - { - grub_file_close (file); - return err; - } - module = get_virtual_current_address (ch); - target = get_physical_target_address (ch); - } - else - { - module = 0; - target = 0; - } - - if (size && grub_file_read (file, module, size) != size) - { - grub_file_close (file); - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - argv[0]); - return grub_errno; - } - - grub_file_close (file); - - return GRUB_MULTIBOOT (add_module) (target, size, argc - 1, argv + 1); -} - -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 deleted file mode 100644 index 1edad0594..000000000 --- a/grub-core/loader/multiboot_elfxx.c +++ /dev/null @@ -1,344 +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 . - */ - -#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 -# define Elf_Shdr Elf32_Shdr -# define Elf_Word Elf32_Word -# define Elf_Shnum Elf32_Shnum -# define grub_multiboot_elf_get_shnum grub_elf32_get_shnum -# define grub_multiboot_elf_get_shstrndx grub_elf32_get_shstrndx -# define grub_multiboot_elf_get_phnum grub_elf32_get_phnum -#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 -# define Elf_Shdr Elf64_Shdr -# define Elf_Word Elf64_Word -# define Elf_Shnum Elf64_Shnum -# define grub_multiboot_elf_get_shnum grub_elf64_get_shnum -# define grub_multiboot_elf_get_shstrndx grub_elf64_get_shstrndx -# define grub_multiboot_elf_get_phnum grub_elf64_get_phnum -#else -#error "I'm confused" -#endif - -#include - -#define CONCAT(a,b) CONCAT_(a, b) -#define CONCAT_(a,b) a ## b - -#pragma GCC diagnostic ignored "-Wcast-align" - -/* 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) (mbi_load_data_t *mld) -{ - Elf_Ehdr *ehdr = (Elf_Ehdr *) mld->buffer; - char *phdr_base; - grub_err_t err; - grub_relocator_chunk_t ch; - grub_uint32_t load_offset = 0, load_size = 0; - Elf_Shnum shnum; - Elf_Word shstrndx, phnum; - grub_off_t phlimit; - unsigned int i; - void *source = NULL; - - 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_ident[EI_DATA] != ELFDATA2LSB) - return grub_error(GRUB_ERR_UNKNOWN_OS, N_("invalid arch-independent ELF magic")); - - if (ehdr->e_ident[EI_CLASS] != ELFCLASSXX || ehdr->e_machine != E_MACHINE - || ehdr->e_version != EV_CURRENT) - return grub_error (GRUB_ERR_UNKNOWN_OS, N_("invalid arch-dependent ELF magic")); - - if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) - return grub_error (GRUB_ERR_UNKNOWN_OS, N_("this ELF file is not of the right type")); - - err = grub_multiboot_elf_get_shnum (ehdr, &shnum); - if (err != GRUB_ERR_NONE) - return err; - - err = grub_multiboot_elf_get_shstrndx (ehdr, &shstrndx); - if (err != GRUB_ERR_NONE) - return err; - - err = grub_multiboot_elf_get_phnum (ehdr, &phnum); - if (err != GRUB_ERR_NONE) - return err; - - /* FIXME: Should we support program headers at strange locations? */ - phlimit = grub_min (MULTIBOOT_SEARCH, grub_file_size (mld->file)); - if ((grub_off_t) ehdr->e_phoff + phnum * ehdr->e_phentsize > phlimit) - return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset"); - - phdr_base = (char *) mld->buffer + ehdr->e_phoff; -#define phdr(i) ((Elf_Phdr *) (phdr_base + (i) * ehdr->e_phentsize)) - - mld->link_base_addr = ~0; - - /* Calculate lowest and highest load address. */ - for (i = 0; i < phnum; i++) - if (phdr(i)->p_type == PT_LOAD) - { - mld->link_base_addr = grub_min (mld->link_base_addr, phdr(i)->p_paddr); - highest_load = grub_max (highest_load, phdr(i)->p_paddr + phdr(i)->p_memsz); - } - -#ifdef MULTIBOOT_LOAD_ELF64 - if (highest_load >= 0x100000000) - return grub_error (GRUB_ERR_BAD_OS, "segment crosses 4 GiB border"); -#endif - - if (mld->relocatable) - { - load_size = highest_load - mld->link_base_addr; - - grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, " - "load_size=0x%x, avoid_efi_boot_services=%d\n", - (long) mld->align, mld->preference, load_size, - mld->avoid_efi_boot_services); - - if (load_size > mld->max_addr || mld->min_addr > mld->max_addr - load_size) - return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size"); - - err = grub_relocator_alloc_chunk_align_safe (GRUB_MULTIBOOT (relocator), &ch, - mld->min_addr, mld->max_addr, - load_size, mld->align ? mld->align : 1, - mld->preference, mld->avoid_efi_boot_services); - - if (err != GRUB_ERR_NONE) - { - grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n"); - return err; - } - - mld->load_base_addr = get_physical_target_address (ch); - source = get_virtual_current_address (ch); - } - else - mld->load_base_addr = mld->link_base_addr; - - grub_dprintf ("multiboot_loader", "relocatable=%d, link_base_addr=0x%x, " - "load_base_addr=0x%x\n", mld->relocatable, - mld->link_base_addr, mld->load_base_addr); - - /* Load every loadable segment in memory. */ - for (i = 0; i < phnum; i++) - { - if (phdr(i)->p_type == PT_LOAD) - { - - 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 (mld->relocatable) - { - load_offset = phdr(i)->p_paddr - mld->link_base_addr; - grub_dprintf ("multiboot_loader", "segment %d: load_offset=0x%x\n", i, load_offset); - } - else - { - load_size = phdr(i)->p_memsz; - err = grub_relocator_alloc_chunk_addr (GRUB_MULTIBOOT (relocator), &ch, - phdr(i)->p_paddr, load_size); - - if (err != GRUB_ERR_NONE) - { - grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n"); - return err; - } - - source = get_virtual_current_address (ch); - } - - if (phdr(i)->p_filesz != 0) - { - if (grub_file_seek (mld->file, (grub_off_t) phdr(i)->p_offset) - == (grub_off_t) -1) - return grub_errno; - - if (grub_file_read (mld->file, (grub_uint8_t *) source + load_offset, phdr(i)->p_filesz) - != (grub_ssize_t) phdr(i)->p_filesz) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - mld->filename); - return grub_errno; - } - } - - if (phdr(i)->p_filesz < phdr(i)->p_memsz) - { - /* Need to insure that the memory being set isn't larger than the allocated memory. */ - if (load_offset + phdr(i)->p_memsz - phdr(i)->p_filesz > load_size) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("memory being set is larger than allocated memory")); - - grub_memset ((grub_uint8_t *) source + load_offset + phdr(i)->p_filesz, 0, - phdr(i)->p_memsz - phdr(i)->p_filesz); - } - } - } - - for (i = 0; i < 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) = (ehdr->e_entry - phdr(i)->p_vaddr) - + phdr(i)->p_paddr; -#ifdef MULTIBOOT_LOAD_ELF64 -# ifdef __mips - /* We still in 32-bit mode. */ - if ((ehdr->e_entry - phdr(i)->p_vaddr) - + phdr(i)->p_paddr < 0xffffffff80000000ULL) - return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64"); -# else - /* We still in 32-bit mode. */ - if ((ehdr->e_entry - phdr(i)->p_vaddr) - + phdr(i)->p_paddr > 0xffffffff) - return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64"); -# endif -#endif - break; - } - - if (i == phnum) - return grub_error (GRUB_ERR_BAD_OS, "entry point isn't in a segment"); - -#if defined (__i386__) || defined (__x86_64__) - -#elif defined (__mips) - GRUB_MULTIBOOT (payload_eip) |= 0x80000000; -#else -#error Please complete this -#endif - - if (shnum) - { - grub_uint8_t *shdr, *shdrptr; - - if ((grub_off_t) ehdr->e_shoff + shnum * ehdr->e_shentsize > grub_file_size (mld->file)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ELF section header region is larger than the file size")); - - shdr = grub_calloc (shnum, ehdr->e_shentsize); - if (!shdr) - return grub_errno; - - if (grub_file_seek (mld->file, ehdr->e_shoff) == (grub_off_t) -1) - goto fail; - - if (grub_file_read (mld->file, shdr, shnum * ehdr->e_shentsize) - != (grub_ssize_t) shnum * ehdr->e_shentsize) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - mld->filename); - goto fail; - } - - for (shdrptr = shdr, i = 0; i < shnum; - shdrptr += ehdr->e_shentsize, i++) - { - Elf_Shdr *sh = (Elf_Shdr *) shdrptr; - void *src; - grub_addr_t target; - - if (mld->mbi_ver >= 2 && (sh->sh_type == SHT_REL || sh->sh_type == SHT_RELA)) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "ELF files with relocs are not supported yet"); - goto fail; - } - - /* This section is a loaded section, - so we don't care. */ - if (sh->sh_addr != 0) - continue; - - /* This section is empty, so we don't care. */ - if (sh->sh_size == 0) - continue; - - err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch, 0, - UP_TO_TOP32 (sh->sh_size), - sh->sh_size, sh->sh_addralign, - GRUB_RELOCATOR_PREFERENCE_NONE, - mld->avoid_efi_boot_services); - if (err != GRUB_ERR_NONE) - { - grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i); - grub_errno = err; - goto fail; - } - src = get_virtual_current_address (ch); - target = get_physical_target_address (ch); - - if (grub_file_seek (mld->file, sh->sh_offset) == (grub_off_t) -1) - goto fail; - - if (grub_file_read (mld->file, src, sh->sh_size) - != (grub_ssize_t) sh->sh_size) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - mld->filename); - goto fail; - } - sh->sh_addr = target; - } - GRUB_MULTIBOOT (add_elfsyms) (shnum, ehdr->e_shentsize, - shstrndx, shdr); - return GRUB_ERR_NONE; - - fail: - grub_free (shdr); - } - -#undef phdr - - return grub_errno; -} - -#undef XX -#undef E_MACHINE -#undef ELFCLASSXX -#undef Elf_Ehdr -#undef Elf_Phdr -#undef Elf_Shdr -#undef Elf_Word -#undef Elf_Shnum -#undef grub_multiboot_elf_get_shnum -#undef grub_multiboot_elf_get_shstrndx -#undef grub_multiboot_elf_get_phnum diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c deleted file mode 100644 index 00a48413c..000000000 --- a/grub-core/loader/multiboot_mbi2.c +++ /dev/null @@ -1,1128 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#ifdef GRUB_MACHINE_PCBIOS -#include -#include -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined (GRUB_MACHINE_EFI) -#include -#endif - -#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) -#include -#define HAS_VGA_TEXT 1 -#else -#define HAS_VGA_TEXT 0 -#endif - -#if defined (__i386__) || defined (__x86_64__) -#define MBI_MIN_ADDR 0x1000 -#else -#define MBI_MIN_ADDR 0 -#endif - -struct module -{ - struct module *next; - grub_addr_t start; - grub_size_t size; - char *cmdline; - int cmdline_size; -}; - -static 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; -static grub_size_t elf_sec_num, elf_sec_entsize; -static unsigned elf_sec_shstrndx; -static void *elf_sections; -static int keep_bs = 0; -static grub_uint32_t load_base_addr; - -void -grub_multiboot2_add_elfsyms (grub_size_t num, grub_size_t entsize, - unsigned shndx, void *data) -{ - elf_sec_num = num; - elf_sec_shstrndx = shndx; - elf_sec_entsize = entsize; - elf_sections = data; -} - -static struct multiboot_header * -find_header (grub_properly_aligned_t *buffer, grub_ssize_t len) -{ - struct multiboot_header *header; - /* 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 <= (char *) buffer + len - 12); - header = (struct multiboot_header *) ((grub_uint32_t *) header + MULTIBOOT_HEADER_ALIGN / 4)) - { - if (header->magic == MULTIBOOT2_HEADER_MAGIC - && !(header->magic + header->architecture - + header->header_length + header->checksum) - && header->architecture == MULTIBOOT2_ARCHITECTURE_CURRENT) - return header; - } - return NULL; -} - -grub_err_t -grub_multiboot2_load (grub_file_t file, const char *filename) -{ - 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; - struct multiboot_header_tag_relocatable *rel_tag; - int entry_specified = 0, efi_entry_specified = 0; - grub_addr_t entry = 0, efi_entry = 0; - grub_uint32_t console_required = 0; - struct multiboot_header_tag_framebuffer *fbtag = NULL; - int accepted_consoles = GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT; - mbi_load_data_t mld; - - mld.mbi_ver = 2; - mld.relocatable = 0; - - mld.buffer = grub_malloc (MULTIBOOT_SEARCH); - if (!mld.buffer) - return grub_errno; - - len = grub_file_read (file, mld.buffer, MULTIBOOT_SEARCH); - if (len < 32) - { - grub_free (mld.buffer); - return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), filename); - } - - COMPILE_TIME_ASSERT (MULTIBOOT_HEADER_ALIGN % 4 == 0); - - header = find_header (mld.buffer, len); - - if (header == 0) - { - grub_free (mld.buffer); - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found"); - } - - COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % 4 == 0); - - keep_bs = 0; - - for (tag = (struct multiboot_header_tag *) (header + 1); - tag->type != MULTIBOOT_TAG_TYPE_END; - tag = (struct multiboot_header_tag *) ((grub_uint32_t *) tag + ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) / 4)) - 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: - case MULTIBOOT_TAG_TYPE_VBE: - case MULTIBOOT_TAG_TYPE_ELF_SECTIONS: - case MULTIBOOT_TAG_TYPE_APM: - case MULTIBOOT_TAG_TYPE_EFI32: - case MULTIBOOT_TAG_TYPE_EFI64: - case MULTIBOOT_TAG_TYPE_ACPI_OLD: - case MULTIBOOT_TAG_TYPE_ACPI_NEW: - case MULTIBOOT_TAG_TYPE_NETWORK: - case MULTIBOOT_TAG_TYPE_EFI_MMAP: - case MULTIBOOT_TAG_TYPE_EFI_BS: - case MULTIBOOT_TAG_TYPE_EFI32_IH: - case MULTIBOOT_TAG_TYPE_EFI64_IH: - case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR: - break; - - default: - grub_free (mld.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_ENTRY_ADDRESS_EFI64: -#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__) - efi_entry_specified = 1; - efi_entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr; -#endif - 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_MULTIBOOT2_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_MULTIBOOT2_CONSOLE_FRAMEBUFFER; - break; - - case MULTIBOOT_HEADER_TAG_RELOCATABLE: - mld.relocatable = 1; - rel_tag = (struct multiboot_header_tag_relocatable *) tag; - mld.min_addr = rel_tag->min_addr; - mld.max_addr = rel_tag->max_addr; - mld.align = rel_tag->align; - switch (rel_tag->preference) - { - case MULTIBOOT_LOAD_PREFERENCE_LOW: - mld.preference = GRUB_RELOCATOR_PREFERENCE_LOW; - break; - - case MULTIBOOT_LOAD_PREFERENCE_HIGH: - mld.preference = GRUB_RELOCATOR_PREFERENCE_HIGH; - break; - - default: - mld.preference = GRUB_RELOCATOR_PREFERENCE_NONE; - } - break; - - /* GRUB always page-aligns modules. */ - case MULTIBOOT_HEADER_TAG_MODULE_ALIGN: - break; - - case MULTIBOOT_HEADER_TAG_EFI_BS: -#ifdef GRUB_MACHINE_EFI - keep_bs = 1; -#endif - break; - - default: - if (! (tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL)) - { - grub_free (mld.buffer); - return grub_error (GRUB_ERR_UNKNOWN_OS, - "unsupported tag: 0x%x", tag->type); - } - break; - } - - if (addr_tag && !entry_specified && !(keep_bs && efi_entry_specified)) - { - grub_free (mld.buffer); - return grub_error (GRUB_ERR_UNKNOWN_OS, - "load address tag without entry address tag"); - } - - if (addr_tag) - { - grub_uint64_t load_addr = (addr_tag->load_addr + 1) - ? addr_tag->load_addr : (addr_tag->header_addr - - ((char *) header - (char *) mld.buffer)); - int offset = ((char *) header - (char *) mld.buffer - - (addr_tag->header_addr - 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; - void *source; - grub_relocator_chunk_t ch; - - if (addr_tag->bss_end_addr) - code_size = (addr_tag->bss_end_addr - load_addr); - else - code_size = load_size; - - if (mld.relocatable) - { - if (code_size > mld.max_addr || mld.min_addr > mld.max_addr - code_size) - { - grub_free (mld.buffer); - return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size"); - } - - err = grub_relocator_alloc_chunk_align_safe (grub_multiboot2_relocator, &ch, - mld.min_addr, mld.max_addr, - code_size, mld.align ? mld.align : 1, - mld.preference, keep_bs); - } - else - err = grub_relocator_alloc_chunk_addr (grub_multiboot2_relocator, - &ch, load_addr, code_size); - if (err) - { - grub_dprintf ("multiboot_loader", "Error loading aout kludge\n"); - grub_free (mld.buffer); - return err; - } - mld.link_base_addr = load_addr; - mld.load_base_addr = get_physical_target_address (ch); - source = get_virtual_current_address (ch); - - grub_dprintf ("multiboot_loader", "link_base_addr=0x%x, load_base_addr=0x%x, " - "load_size=0x%lx, relocatable=%d\n", mld.link_base_addr, - mld.load_base_addr, (long) code_size, mld.relocatable); - - if (mld.relocatable) - grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, avoid_efi_boot_services=%d\n", - (long) mld.align, mld.preference, keep_bs); - - if ((grub_file_seek (file, offset)) == (grub_off_t) -1) - { - grub_free (mld.buffer); - return grub_errno; - } - - grub_file_read (file, source, load_size); - if (grub_errno) - { - grub_free (mld.buffer); - return grub_errno; - } - - if (addr_tag->bss_end_addr) - grub_memset ((grub_uint8_t *) source + load_size, 0, - addr_tag->bss_end_addr - load_addr - load_size); - } - else - { - mld.file = file; - mld.filename = filename; - mld.avoid_efi_boot_services = keep_bs; - err = grub_multiboot2_load_elf (&mld); - if (err) - { - grub_free (mld.buffer); - return err; - } - } - - load_base_addr = mld.load_base_addr; - - if (keep_bs && efi_entry_specified) - grub_multiboot2_payload_eip = efi_entry; - else if (entry_specified) - grub_multiboot2_payload_eip = entry; - - if (mld.relocatable) - { - /* - * Both branches are mathematically equivalent. However, it looks - * that real life (C?) is more complicated. I am trying to avoid - * wrap around here if mld.load_base_addr < mld.link_base_addr. - * If you look at C operator precedence then everything should work. - * However, I am not 100% sure that a given compiler will not - * optimize/break this stuff. So, maybe we should use signed - * 64-bit int here. - */ - if (mld.load_base_addr >= mld.link_base_addr) - grub_multiboot2_payload_eip += mld.load_base_addr - mld.link_base_addr; - else - grub_multiboot2_payload_eip -= mld.link_base_addr - mld.load_base_addr; - } - - if (fbtag) - err = grub_multiboot2_set_console (GRUB_MULTIBOOT2_CONSOLE_FRAMEBUFFER, - accepted_consoles, - fbtag->width, fbtag->height, - fbtag->depth, console_required); - else - err = grub_multiboot2_set_console (GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT, - accepted_consoles, - 0, 0, 0, console_required); - return err; -} - -static grub_size_t -acpiv2_size (void) -{ -#if GRUB_MACHINE_HAS_ACPI - struct grub_acpi_rsdp_v20 *p = grub_acpi_get_rsdpv2 (); - - if (!p) - return 0; - - return ALIGN_UP (sizeof (struct multiboot_tag_old_acpi) - + p->length, MULTIBOOT_TAG_ALIGN); -#else - return 0; -#endif -} - -#ifdef GRUB_MACHINE_EFI - -static grub_efi_uintn_t efi_mmap_size = 0; - -#endif - -static grub_size_t -net_size (void) -{ - struct grub_net_network_level_interface *net; - grub_size_t ret = 0; - - FOR_NET_NETWORK_LEVEL_INTERFACES(net) - if (net->dhcp_ack) - ret += ALIGN_UP (sizeof (struct multiboot_tag_network) + net->dhcp_acklen, - MULTIBOOT_TAG_ALIGN); - return ret; -} - -static grub_size_t -grub_multiboot2_get_mbi_size (void) -{ -#ifdef GRUB_MACHINE_EFI - if (!keep_bs && !efi_mmap_size) - efi_mmap_size = grub_efi_find_mmap_size (); -#endif - return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag) - + 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) - + ALIGN_UP (sizeof (struct multiboot_tag_basic_meminfo), - MULTIBOOT_TAG_ALIGN) - + ALIGN_UP (sizeof (struct multiboot_tag_bootdev), MULTIBOOT_TAG_ALIGN) - + ALIGN_UP (sizeof (struct multiboot_tag_elf_sections), MULTIBOOT_TAG_ALIGN) - + ALIGN_UP (elf_sec_entsize * elf_sec_num, MULTIBOOT_TAG_ALIGN) - + ALIGN_UP ((sizeof (struct multiboot_tag_mmap) - + grub_multiboot2_get_mmap_count () - * sizeof (struct multiboot_mmap_entry)), MULTIBOOT_TAG_ALIGN) - + ALIGN_UP (sizeof (struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN) - + ALIGN_UP (sizeof (struct multiboot_tag_old_acpi) - + sizeof (struct grub_acpi_rsdp_v10), MULTIBOOT_TAG_ALIGN) - + ALIGN_UP (sizeof (struct multiboot_tag_load_base_addr), MULTIBOOT_TAG_ALIGN) - + acpiv2_size () - + net_size () -#ifdef GRUB_MACHINE_EFI - + ALIGN_UP (sizeof (struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN) - + ALIGN_UP (sizeof (struct multiboot_tag_efi32_ih), MULTIBOOT_TAG_ALIGN) - + ALIGN_UP (sizeof (struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN) - + ALIGN_UP (sizeof (struct multiboot_tag_efi64_ih), MULTIBOOT_TAG_ALIGN) - + ALIGN_UP (sizeof (struct multiboot_tag_efi_mmap) - + efi_mmap_size, MULTIBOOT_TAG_ALIGN) -#endif - + sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1 - + sizeof (struct multiboot_tag_apm) + MULTIBOOT_TAG_ALIGN - 1; -} - -/* Helper for grub_fill_multiboot_mmap. */ -static int -grub_fill_multiboot_mmap_iter (grub_uint64_t addr, grub_uint64_t size, - grub_memory_type_t type, void *data) -{ - struct multiboot_mmap_entry **mmap_entry = data; - - (*mmap_entry)->addr = addr; - (*mmap_entry)->len = size; - (*mmap_entry)->type = type; - (*mmap_entry)->zero = 0; - (*mmap_entry)++; - - return 0; -} - -/* Fill previously allocated Multiboot mmap. */ -static void -grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag) -{ - struct multiboot_mmap_entry *mmap_entry = tag->entries; - - tag->type = MULTIBOOT_TAG_TYPE_MMAP; - tag->size = sizeof (struct multiboot_tag_mmap) - + sizeof (struct multiboot_mmap_entry) * grub_multiboot2_get_mmap_count (); - tag->entry_size = sizeof (struct multiboot_mmap_entry); - tag->entry_version = 0; - - grub_mmap_iterate (grub_fill_multiboot_mmap_iter, &mmap_entry); -} - -#if defined (GRUB_MACHINE_PCBIOS) -static void -fill_vbe_tag (struct multiboot_tag_vbe *tag) -{ - grub_vbe_status_t status; - void *scratch = grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); - - tag->type = MULTIBOOT_TAG_TYPE_VBE; - tag->size = 0; - - status = grub_vbe_bios_get_controller_info (scratch); - if (status != GRUB_VBE_STATUS_OK) - return; - - grub_memcpy (&tag->vbe_control_info, scratch, - sizeof (struct grub_vbe_info_block)); - - status = grub_vbe_bios_get_mode (scratch); - tag->vbe_mode = *(grub_uint32_t *) scratch; - if (status != GRUB_VBE_STATUS_OK) - return; - - /* get_mode_info isn't available for mode 3. */ - if (tag->vbe_mode == 3) - { - struct grub_vbe_mode_info_block *mode_info = (void *) &tag->vbe_mode_info; - grub_memset (mode_info, 0, - sizeof (struct grub_vbe_mode_info_block)); - mode_info->memory_model = GRUB_VBE_MEMORY_MODEL_TEXT; - mode_info->x_resolution = 80; - mode_info->y_resolution = 25; - } - else - { - status = grub_vbe_bios_get_mode_info (tag->vbe_mode, scratch); - if (status != GRUB_VBE_STATUS_OK) - return; - grub_memcpy (&tag->vbe_mode_info, scratch, - sizeof (struct grub_vbe_mode_info_block)); - } - grub_vbe_bios_get_pm_interface (&tag->vbe_interface_seg, - &tag->vbe_interface_off, - &tag->vbe_interface_len); - - tag->size = sizeof (*tag); -} -#endif - -static grub_err_t -retrieve_video_parameters (grub_properly_aligned_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_multiboot2_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 = grub_absolute_pointer (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) - / sizeof (grub_properly_aligned_t); - } - return GRUB_ERR_NONE; - } -#else - if (driv_id == GRUB_VIDEO_DRIVER_NONE) - return GRUB_ERR_NONE; -#endif - -#if GRUB_MACHINE_HAS_VBE - { - struct multiboot_tag_vbe *tag_vbe = (struct multiboot_tag_vbe *) *ptrorig; - - fill_vbe_tag (tag_vbe); - - *ptrorig += ALIGN_UP (tag_vbe->size, MULTIBOOT_TAG_ALIGN) - / sizeof (grub_properly_aligned_t); - } -#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->framebuffer_red_field_position = mode_info.red_field_pos; - tag->framebuffer_red_mask_size = mode_info.red_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) - / sizeof (grub_properly_aligned_t); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_multiboot2_make_mbi (grub_uint32_t *target) -{ - grub_properly_aligned_t *ptrorig; - grub_properly_aligned_t *mbistart; - grub_err_t err; - grub_size_t bufsize; - grub_relocator_chunk_t ch; - - bufsize = grub_multiboot2_get_mbi_size (); - - COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % sizeof (grub_properly_aligned_t) == 0); - - err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch, - MBI_MIN_ADDR, UP_TO_TOP32 (bufsize), - bufsize, MULTIBOOT_TAG_ALIGN, - GRUB_RELOCATOR_PREFERENCE_NONE, 1); - if (err) - return err; - - ptrorig = get_virtual_current_address (ch); -#if defined (__i386__) || defined (__x86_64__) - *target = get_physical_target_address (ch); -#elif defined (__mips) - *target = get_physical_target_address (ch) | 0x80000000; -#else -#error Please complete this -#endif - - mbistart = ptrorig; - COMPILE_TIME_ASSERT ((2 * sizeof (grub_uint32_t)) - % sizeof (grub_properly_aligned_t) == 0); - COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN - % sizeof (grub_properly_aligned_t) == 0); - ptrorig += (2 * sizeof (grub_uint32_t)) / sizeof (grub_properly_aligned_t); - - { - struct multiboot_tag_load_base_addr *tag = (struct multiboot_tag_load_base_addr *) ptrorig; - tag->type = MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR; - tag->size = sizeof (struct multiboot_tag_load_base_addr); - tag->load_base_addr = load_base_addr; - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) - / sizeof (grub_properly_aligned_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) - / sizeof (grub_properly_aligned_t); - } - - { - 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) - / sizeof (grub_properly_aligned_t); - } - -#ifdef GRUB_MACHINE_PCBIOS - { - struct grub_apm_info info; - if (grub_apm_get_info (&info)) - { - struct multiboot_tag_apm *tag = (struct multiboot_tag_apm *) ptrorig; - - tag->type = MULTIBOOT_TAG_TYPE_APM; - tag->size = sizeof (struct multiboot_tag_apm); - - tag->cseg = info.cseg; - tag->offset = info.offset; - tag->cseg_16 = info.cseg_16; - tag->dseg = info.dseg; - tag->flags = info.flags; - tag->cseg_len = info.cseg_len; - tag->dseg_len = info.dseg_len; - tag->cseg_16_len = info.cseg_16_len; - tag->version = info.version; - - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) - / sizeof (grub_properly_aligned_t); - } - } -#endif - - { - 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 = 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) - / sizeof (grub_properly_aligned_t); - } - } - - if (!keep_bs) - { - struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig; - grub_fill_multiboot_mmap (tag); - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) - / sizeof (grub_properly_aligned_t); - } - - { - struct multiboot_tag_elf_sections *tag - = (struct multiboot_tag_elf_sections *) ptrorig; - tag->type = MULTIBOOT_TAG_TYPE_ELF_SECTIONS; - tag->size = sizeof (struct multiboot_tag_elf_sections) - + elf_sec_entsize * elf_sec_num; - grub_memcpy (tag->sections, elf_sections, elf_sec_entsize * elf_sec_num); - tag->num = elf_sec_num; - tag->entsize = elf_sec_entsize; - tag->shndx = elf_sec_shstrndx; - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) - / sizeof (grub_properly_aligned_t); - } - - if (!keep_bs) - { - 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) - / sizeof (grub_properly_aligned_t); - } - - { - struct grub_net_network_level_interface *net; - - FOR_NET_NETWORK_LEVEL_INTERFACES(net) - if (net->dhcp_ack) - { - struct multiboot_tag_network *tag - = (struct multiboot_tag_network *) ptrorig; - tag->type = MULTIBOOT_TAG_TYPE_NETWORK; - tag->size = sizeof (struct multiboot_tag_network) + net->dhcp_acklen; - grub_memcpy (tag->dhcpack, net->dhcp_ack, net->dhcp_acklen); - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) - / sizeof (grub_properly_aligned_t); - } - } - - 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) - / sizeof (grub_properly_aligned_t); - } - - { - err = retrieve_video_parameters (&ptrorig); - if (err) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - } - } - -#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__) - { - struct multiboot_tag_efi64 *tag = (struct multiboot_tag_efi64 *) ptrorig; - tag->type = MULTIBOOT_TAG_TYPE_EFI64; - tag->size = sizeof (*tag); - tag->pointer = (grub_addr_t) grub_efi_system_table; - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) - / sizeof (grub_properly_aligned_t); - } -#endif - -#if defined (GRUB_MACHINE_EFI) && defined (__i386__) - { - struct multiboot_tag_efi32 *tag = (struct multiboot_tag_efi32 *) ptrorig; - tag->type = MULTIBOOT_TAG_TYPE_EFI32; - tag->size = sizeof (*tag); - tag->pointer = (grub_addr_t) grub_efi_system_table; - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) - / sizeof (grub_properly_aligned_t); - } -#endif - -#if GRUB_MACHINE_HAS_ACPI - { - struct multiboot_tag_old_acpi *tag = (struct multiboot_tag_old_acpi *) - ptrorig; - struct grub_acpi_rsdp_v10 *a = grub_acpi_get_rsdpv1 (); - if (a) - { - tag->type = MULTIBOOT_TAG_TYPE_ACPI_OLD; - tag->size = sizeof (*tag) + sizeof (*a); - grub_memcpy (tag->rsdp, a, sizeof (*a)); - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) - / sizeof (grub_properly_aligned_t); - } - } - - { - struct multiboot_tag_new_acpi *tag = (struct multiboot_tag_new_acpi *) - ptrorig; - struct grub_acpi_rsdp_v20 *a = grub_acpi_get_rsdpv2 (); - if (a) - { - tag->type = MULTIBOOT_TAG_TYPE_ACPI_NEW; - tag->size = sizeof (*tag) + a->length; - grub_memcpy (tag->rsdp, a, a->length); - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) - / sizeof (grub_properly_aligned_t); - } - } -#endif - -#ifdef GRUB_MACHINE_EFI - { - struct multiboot_tag_efi_mmap *tag = (struct multiboot_tag_efi_mmap *) ptrorig; - grub_efi_uintn_t efi_desc_size; - grub_efi_uint32_t efi_desc_version; - - if (!keep_bs) - { - tag->type = MULTIBOOT_TAG_TYPE_EFI_MMAP; - tag->size = sizeof (*tag) + efi_mmap_size; - - err = grub_efi_finish_boot_services (&efi_mmap_size, tag->efi_mmap, NULL, - &efi_desc_size, &efi_desc_version); - - if (err) - return err; - - tag->descr_size = efi_desc_size; - tag->descr_vers = efi_desc_version; - tag->size = sizeof (*tag) + efi_mmap_size; - - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) - / sizeof (grub_properly_aligned_t); - } - } - - if (keep_bs) - { - { - struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig; - tag->type = MULTIBOOT_TAG_TYPE_EFI_BS; - tag->size = sizeof (struct multiboot_tag); - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) - / sizeof (grub_properly_aligned_t); - } - -#ifdef __i386__ - { - struct multiboot_tag_efi32_ih *tag = (struct multiboot_tag_efi32_ih *) ptrorig; - tag->type = MULTIBOOT_TAG_TYPE_EFI32_IH; - tag->size = sizeof (struct multiboot_tag_efi32_ih); - tag->pointer = (grub_addr_t) grub_efi_image_handle; - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) - / sizeof (grub_properly_aligned_t); - } -#endif - -#ifdef __x86_64__ - { - struct multiboot_tag_efi64_ih *tag = (struct multiboot_tag_efi64_ih *) ptrorig; - tag->type = MULTIBOOT_TAG_TYPE_EFI64_IH; - tag->size = sizeof (struct multiboot_tag_efi64_ih); - tag->pointer = (grub_addr_t) grub_efi_image_handle; - ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) - / sizeof (grub_properly_aligned_t); - } -#endif - } -#endif - - { - 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) - / sizeof (grub_properly_aligned_t); - } - - ((grub_uint32_t *) mbistart)[0] = (char *) ptrorig - (char *) mbistart; - ((grub_uint32_t *) mbistart)[1] = 0; - - return GRUB_ERR_NONE; -} - -void -grub_multiboot2_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_multiboot2_init_mbi (int argc, char *argv[]) -{ - grub_ssize_t len = 0; - - grub_multiboot2_free_mbi (); - - len = grub_loader_cmdline_size (argc, argv); - - cmdline = grub_malloc (len); - if (! cmdline) - return grub_errno; - cmdline_size = len; - - return grub_create_loader_cmdline (argc, argv, cmdline, cmdline_size, - GRUB_VERIFY_KERNEL_CMDLINE); -} - -grub_err_t -grub_multiboot2_add_module (grub_addr_t start, grub_size_t size, - int argc, char *argv[]) -{ - struct module *newmod; - grub_size_t len = 0; - grub_err_t err; - - newmod = grub_malloc (sizeof (*newmod)); - if (!newmod) - return grub_errno; - newmod->start = start; - newmod->size = size; - - len = grub_loader_cmdline_size (argc, argv); - - newmod->cmdline = grub_malloc (len); - if (! newmod->cmdline) - { - grub_free (newmod); - return grub_errno; - } - newmod->cmdline_size = len; - total_modcmd += ALIGN_UP (len, MULTIBOOT_TAG_ALIGN); - - err = grub_create_loader_cmdline (argc, argv, newmod->cmdline, - newmod->cmdline_size, GRUB_VERIFY_MODULE_CMDLINE); - if (err) - { - grub_free (newmod->cmdline); - grub_free (newmod); - return err; - } - - if (modules_last) - modules_last->next = newmod; - else - modules = newmod; - modules_last = newmod; - - modcnt++; - - return GRUB_ERR_NONE; -} - -void -grub_multiboot2_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 deleted file mode 100644 index 4864e5fb0..000000000 --- a/grub-core/loader/powerpc/ieee1275/linux.c +++ /dev/null @@ -1,416 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#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_addr_t linux_entry; -static grub_size_t linux_size; - -static char *linux_args; - -typedef void (*kernel_entry_t) (void *, unsigned long, int (void *), - unsigned long, unsigned long); - -/* Context for grub_linux_claimmap_iterate. */ -struct grub_linux_claimmap_iterate_ctx -{ - grub_addr_t target; - grub_size_t size; - grub_size_t align; - grub_addr_t found_addr; -}; - -/* Helper for grub_linux_claimmap_iterate. */ -static int -alloc_mem (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - void *data) -{ - struct grub_linux_claimmap_iterate_ctx *ctx = data; - - grub_uint64_t end = addr + len; - addr = ALIGN_UP (addr, ctx->align); - ctx->target = ALIGN_UP (ctx->target, ctx->align); - - /* Target above the memory chunk. */ - if (type != GRUB_MEMORY_AVAILABLE || ctx->target > end) - return 0; - - /* Target inside the memory chunk. */ - if (ctx->target >= addr && ctx->target < end && - ctx->size <= end - ctx->target) - { - if (grub_claimmap (ctx->target, ctx->size) == GRUB_ERR_NONE) - { - ctx->found_addr = ctx->target; - return 1; - } - grub_print_error (); - } - /* Target below the memory chunk. */ - if (ctx->target < addr && addr + ctx->size <= end) - { - if (grub_claimmap (addr, ctx->size) == GRUB_ERR_NONE) - { - ctx->found_addr = addr; - return 1; - } - grub_print_error (); - } - return 0; -} - -static grub_addr_t -grub_linux_claimmap_iterate (grub_addr_t target, grub_size_t size, - grub_size_t align) -{ - struct grub_linux_claimmap_iterate_ctx ctx = { - .target = target, - .size = size, - .align = align, - .found_addr = (grub_addr_t) -1 - }; - - grub_machine_mmap_iterate (alloc_mem, &ctx); - - return ctx.found_addr; -} - -static grub_addr_t -grub_linux_claimmap_iterate_restricted (grub_size_t size, grub_size_t align) -{ - struct regions_claim_request rcr = { - .flags = GRUB_MM_ADD_REGION_CONSECUTIVE, - .total = size, - .init_region = false, - .addr = (grub_uint64_t) -1, - .align = align, - }; - - grub_machine_mmap_iterate (grub_regions_claim, &rcr); - - return rcr.addr; -} - -static grub_err_t -grub_linux_boot (void) -{ - kernel_entry_t linuxmain; - grub_ssize_t actual; - - grub_arch_sync_caches ((void *) linux_addr, linux_size); - /* 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_entry); - 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_entry; - 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, const char *filename) -{ - Elf32_Addr base_addr; - grub_addr_t seg_addr; - grub_uint32_t align; - grub_uint32_t offset; - Elf32_Addr entry; - - linux_size = grub_elf32_size (elf, &base_addr, &align); - if (linux_size == 0) - return grub_errno; - /* Pad it; the kernel scribbles over memory beyond its load address. */ - linux_size += 0x100000; - - /* Linux's entry point incorrectly contains a virtual address. */ - entry = elf->ehdr.ehdr32.e_entry & ~ELF32_LOADMASK; - - /* Linux's incorrectly contains a virtual address. */ - base_addr &= ~ELF32_LOADMASK; - offset = entry - base_addr; - - /* 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. */ - seg_addr = grub_linux_claimmap_iterate (base_addr & ~ELF32_LOADMASK, linux_size, align); - if (seg_addr == (grub_addr_t) -1) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't claim memory"); - - linux_entry = seg_addr + offset; - linux_addr = seg_addr; - - /* Now load the segments into the area we claimed. */ - return grub_elf32_load (elf, filename, (void *) (seg_addr - base_addr), GRUB_ELF_LOAD_FLAGS_30BITS, 0, 0); -} - -static grub_err_t -grub_linux_load64 (grub_elf_t elf, const char *filename) -{ - Elf64_Addr base_addr; - grub_addr_t seg_addr; - grub_uint64_t align; - grub_uint64_t offset; - Elf64_Addr entry; - - linux_size = grub_elf64_size (elf, &base_addr, &align); - if (linux_size == 0) - return grub_errno; - /* Pad it; the kernel scribbles over memory beyond its load address. */ - linux_size += 0x100000; - - base_addr &= ~ELF64_LOADMASK; - entry = elf->ehdr.ehdr64.e_entry & ~ELF64_LOADMASK; - offset = entry - base_addr; - /* Linux's incorrectly contains a virtual address. */ - - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_POWER_VM) || - grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_POWER_KVM)) - { - seg_addr = grub_linux_claimmap_iterate_restricted (linux_size, align); - } - else - { - /* 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. */ - seg_addr = grub_linux_claimmap_iterate (base_addr & ~ELF64_LOADMASK, linux_size, align); - } - if (seg_addr == (grub_addr_t) -1) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't claim memory"); - - linux_entry = seg_addr + offset; - linux_addr = seg_addr; - - /* Now load the segments into the area we claimed. */ - return grub_elf64_load (elf, filename, (void *) (grub_addr_t) (seg_addr - base_addr), GRUB_ELF_LOAD_FLAGS_62BITS, 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 size; - - grub_dl_ref (my_mod); - - if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto out; - } - - elf = grub_elf_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); - if (! elf) - goto out; - - if (elf->ehdr.ehdr32.e_type != ET_EXEC && elf->ehdr.ehdr32.e_type != ET_DYN) - { - grub_error (GRUB_ERR_UNKNOWN_OS, - N_("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, argv[0]); - else - if (grub_elf_is_elf64 (elf)) - grub_linux_load64 (elf, argv[0]); - else - { - grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("invalid arch-dependent ELF magic")); - goto out; - } - - size = grub_loader_cmdline_size(argc, argv); - linux_args = grub_malloc (size + sizeof (LINUX_IMAGE)); - if (! linux_args) - goto out; - - /* Create kernel command line. */ - grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - if (grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1, - size, GRUB_VERIFY_KERNEL_CMDLINE)) - goto out; - -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_size_t size = 0; - grub_addr_t first_addr; - grub_addr_t addr; - struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; - - if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - if (!loaded) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); - goto fail; - } - - if (grub_initrd_init (argc, argv, &initrd_ctx)) - goto fail; - - size = grub_get_initrd_size (&initrd_ctx); - - - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_POWER_VM) || - grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_POWER_KVM)) - { - addr = grub_linux_claimmap_iterate_restricted (size, 0x100000); - } - else - { - /* Attempt to claim at a series of addresses until successful in - the same way that grub_rescue_cmd_linux does. */ - first_addr = linux_addr + linux_size; - addr = grub_linux_claimmap_iterate (first_addr, size, 0x100000); - } - - if (addr == (grub_addr_t) -1) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); - goto fail; - } - - grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size); - - if (grub_initrd_load (&initrd_ctx, (void *) addr)) - goto fail; - - initrd_addr = addr; - initrd_size = size; - - fail: - grub_initrd_close (&initrd_ctx); - - 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/mmap/mmap.c b/grub-core/mmap/mmap.c deleted file mode 100644 index c8c8312c5..000000000 --- a/grub-core/mmap/mmap.c +++ /dev/null @@ -1,554 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE - -struct grub_mmap_region *grub_mmap_overlays = 0; -static int curhandle = 1; - -#endif - -static int current_priority = 1; - -/* 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? */ - grub_memory_type_t memtype; - /* Priority. 0 means coming from firmware. */ - int priority; -}; - -/* Context for grub_mmap_iterate. */ -struct grub_mmap_iterate_ctx -{ - struct grub_mmap_scan *scanline_events; - int i; -}; - -/* Helper for grub_mmap_iterate. */ -static int -count_hook (grub_uint64_t addr __attribute__ ((unused)), - grub_uint64_t size __attribute__ ((unused)), - grub_memory_type_t type __attribute__ ((unused)), void *data) -{ - int *mmap_num = data; - - (*mmap_num)++; - return 0; -} - -/* Helper for grub_mmap_iterate. */ -static int -fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, - void *data) -{ - struct grub_mmap_iterate_ctx *ctx = data; - - if (type == GRUB_MEMORY_HOLE) - { - grub_dprintf ("mmap", "Unknown memory type %d. Assuming unusable\n", - type); - type = GRUB_MEMORY_RESERVED; - } - - ctx->scanline_events[ctx->i].pos = addr; - ctx->scanline_events[ctx->i].type = 0; - ctx->scanline_events[ctx->i].memtype = type; - ctx->scanline_events[ctx->i].priority = 0; - - ctx->i++; - - ctx->scanline_events[ctx->i].pos = addr + size; - ctx->scanline_events[ctx->i].type = 1; - ctx->scanline_events[ctx->i].memtype = type; - ctx->scanline_events[ctx->i].priority = 0; - ctx->i++; - - return 0; -} - -struct mm_list -{ - struct mm_list *next; - grub_memory_type_t val; - int present; -}; - -grub_err_t -grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data) -{ - /* This function resolves overlapping regions and sorts the memory map. - It uses scanline (sweeping) algorithm. - */ - struct grub_mmap_iterate_ctx ctx; - int i, done; - - 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/priority overlap at current location? */ - /* Normally there shouldn't be more than one region per priority but be robust. */ - struct mm_list *present; - /* Number of mmap chunks. */ - int mmap_num; - -#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE - struct grub_mmap_region *cur; -#endif - - 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, &mmap_num); - - /* Initialize variables. */ - ctx.scanline_events = (struct grub_mmap_scan *) - grub_calloc (mmap_num, sizeof (struct grub_mmap_scan) * 2); - - present = grub_calloc (current_priority, sizeof (present[0])); - - if (! ctx.scanline_events || !present) - { - grub_free (ctx.scanline_events); - grub_free (present); - return grub_errno; - } - - ctx.i = 0; -#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE - /* Register scanline events. */ - for (cur = grub_mmap_overlays; cur; cur = cur->next) - { - ctx.scanline_events[ctx.i].pos = cur->start; - ctx.scanline_events[ctx.i].type = 0; - ctx.scanline_events[ctx.i].memtype = cur->type; - ctx.scanline_events[ctx.i].priority = cur->priority; - ctx.i++; - - ctx.scanline_events[ctx.i].pos = cur->end; - ctx.scanline_events[ctx.i].type = 1; - ctx.scanline_events[ctx.i].memtype = cur->type; - ctx.scanline_events[ctx.i].priority = cur->priority; - ctx.i++; - } -#endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */ - - grub_machine_mmap_iterate (fill_hook, &ctx); - - /* 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 (ctx.scanline_events[i + 1].pos < ctx.scanline_events[i].pos - || (ctx.scanline_events[i + 1].pos == ctx.scanline_events[i].pos - && ctx.scanline_events[i + 1].type == 0 - && ctx.scanline_events[i].type == 1)) - { - t = ctx.scanline_events[i + 1]; - ctx.scanline_events[i + 1] = ctx.scanline_events[i]; - ctx.scanline_events[i] = t; - done = 1; - } - } - - lastaddr = ctx.scanline_events[0].pos; - lasttype = ctx.scanline_events[0].memtype; - for (i = 0; i < 2 * mmap_num; i++) - { - /* Process event. */ - if (ctx.scanline_events[i].type) - { - if (present[ctx.scanline_events[i].priority].present) - { - if (present[ctx.scanline_events[i].priority].val == ctx.scanline_events[i].memtype) - { - if (present[ctx.scanline_events[i].priority].next) - { - struct mm_list *p = present[ctx.scanline_events[i].priority].next; - present[ctx.scanline_events[i].priority] = *p; - grub_free (p); - } - else - { - present[ctx.scanline_events[i].priority].present = 0; - } - } - else - { - struct mm_list **q = &(present[ctx.scanline_events[i].priority].next), *p; - for (; *q; q = &((*q)->next)) - if ((*q)->val == ctx.scanline_events[i].memtype) - { - p = *q; - *q = p->next; - grub_free (p); - break; - } - } - } - } - else - { - if (!present[ctx.scanline_events[i].priority].present) - { - present[ctx.scanline_events[i].priority].present = 1; - present[ctx.scanline_events[i].priority].val = ctx.scanline_events[i].memtype; - } - else - { - struct mm_list *n = grub_malloc (sizeof (*n)); - n->val = ctx.scanline_events[i].memtype; - n->present = 1; - n->next = present[ctx.scanline_events[i].priority].next; - present[ctx.scanline_events[i].priority].next = n; - } - } - - /* Determine current region type. */ - curtype = -1; - { - int k; - for (k = current_priority - 1; k >= 0; k--) - if (present[k].present) - { - curtype = present[k].val; - break; - } - } - - /* Announce region to the hook if necessary. */ - if ((curtype == -1 || curtype != lasttype) - && lastaddr != ctx.scanline_events[i].pos - && lasttype != -1 - && lasttype != GRUB_MEMORY_HOLE - && hook (lastaddr, ctx.scanline_events[i].pos - lastaddr, lasttype, - hook_data)) - { - grub_free (ctx.scanline_events); - grub_free (present); - return GRUB_ERR_NONE; - } - - /* Update last values if necessary. */ - if (curtype == -1 || curtype != lasttype) - { - lasttype = curtype; - lastaddr = ctx.scanline_events[i].pos; - } - } - - grub_free (ctx.scanline_events); - grub_free (present); - 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) - return 0; - - cur->next = grub_mmap_overlays; - cur->start = start; - cur->end = start + size; - cur->type = type; - cur->handle = curhandle++; - cur->priority = current_priority++; - 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; - err = grub_machine_mmap_unregister (handle); - if (err) - 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_BUG, "mmap overlay not found"); -} - -#endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */ - -#define CHUNK_SIZE 0x400 - -struct badram_entry { - grub_uint64_t addr, mask; -}; - -static inline grub_uint64_t -fill_mask (struct badram_entry *entry, grub_uint64_t iterator) -{ - int i, j; - grub_uint64_t ret = (entry->addr & entry->mask); - - /* Find first fixed bit. */ - for (i = 0; i < 64; i++) - if ((entry->mask & (1ULL << i)) != 0) - break; - j = 0; - for (; i < 64; i++) - if ((entry->mask & (1ULL << i)) == 0) - { - if ((iterator & (1ULL << j)) != 0) - ret |= 1ULL << i; - j++; - } - return ret; -} - -/* Helper for grub_cmd_badram. */ -static int -badram_iter (grub_uint64_t addr, grub_uint64_t size, - grub_memory_type_t type __attribute__ ((unused)), void *data) -{ - struct badram_entry *entry = data; - 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; ! (entry->mask & (1ULL << tail)); tail++); - - /* How many zeros in mask? */ - var = 0; - for (i = 0; i < 64; i++) - if (! (entry->mask & (1ULL << i))) - var++; - - if (fill_mask (entry, 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 (entry, cur) >= addr) - high = cur; - else - low = cur; - } - iterator = high; - } - - for (; iterator < (1ULL << (var - tail)) - && (cur = fill_mask (entry, 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_MEMORY_HOLE); - } - return 0; -} - -static grub_err_t -grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) -{ - const char *str; - struct badram_entry entry; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - - grub_dprintf ("badram", "executing badram\n"); - - str = args[0]; - - while (1) - { - /* Parse address and mask. */ - entry.addr = grub_strtoull (str, &str, 16); - if (*str == ',') - str++; - entry.mask = 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. */ - entry.mask &= ~(CHUNK_SIZE - 1); - - grub_dprintf ("badram", "badram %llx:%llx\n", - (unsigned long long) entry.addr, - (unsigned long long) entry.mask); - - grub_mmap_iterate (badram_iter, &entry); - } -} - -static grub_uint64_t -parsemem (const char *str) -{ - grub_uint64_t ret; - const char *ptr; - - ret = grub_strtoul (str, &ptr, 0); - - switch (*ptr) - { - case 'K': - return ret << 10; - case 'M': - return ret << 20; - case 'G': - return ret << 30; - case 'T': - return ret << 40; - } - return ret; -} - -struct cutmem_range { - grub_uint64_t from, to; -}; - -/* Helper for grub_cmd_cutmem. */ -static int -cutmem_iter (grub_uint64_t addr, grub_uint64_t size, - grub_memory_type_t type __attribute__ ((unused)), void *data) -{ - struct cutmem_range *range = data; - grub_uint64_t end = addr + size; - - if (addr <= range->from) - addr = range->from; - if (end >= range->to) - end = range->to; - - if (end <= addr) - return 0; - - grub_mmap_register (addr, end - addr, GRUB_MEMORY_HOLE); - return 0; -} - -static grub_err_t -grub_cmd_cutmem (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) -{ - struct cutmem_range range; - - if (argc != 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); - - range.from = parsemem (args[0]); - if (grub_errno) - return grub_errno; - - range.to = parsemem (args[1]); - if (grub_errno) - return grub_errno; - - grub_mmap_iterate (cutmem_iter, &range); - - return GRUB_ERR_NONE; -} - -static grub_command_t cmd, cmd_cut; - - -GRUB_MOD_INIT(mmap) -{ - cmd = grub_register_command_lockdown ("badram", grub_cmd_badram, - N_("ADDR1,MASK1[,ADDR2,MASK2[,...]]"), - N_("Declare memory regions as faulty (badram).")); - cmd_cut = grub_register_command_lockdown ("cutmem", grub_cmd_cutmem, - N_("FROM[K|M|G] TO[K|M|G]"), - N_("Remove any memory regions in specified range.")); - -} - -GRUB_MOD_FINI(mmap) -{ - grub_unregister_command (cmd); - grub_unregister_command (cmd_cut); -} - diff --git a/grub-core/modinfo.sh.in b/grub-core/modinfo.sh.in deleted file mode 100644 index f6cd657ce..000000000 --- a/grub-core/modinfo.sh.in +++ /dev/null @@ -1,40 +0,0 @@ -#!@BUILD_SHEBANG@ - -# User-controllable options -grub_modinfo_target_cpu=@target_cpu@ -grub_modinfo_platform=@platform@ -grub_disk_cache_stats=@DISK_CACHE_STATS@ -grub_boot_time_stats=@BOOT_TIME_STATS@ -grub_have_font_source=@HAVE_FONT_SOURCE@ - -# Autodetected config -grub_have_asm_uscore=@HAVE_ASM_USCORE@ -grub_bss_start_symbol="@BSS_START_SYMBOL@" -grub_end_symbol="@END_SYMBOL@" - -# Build environment -grub_target_cc='@TARGET_CC@' -grub_target_cc_version='@TARGET_CC_VERSION@' -grub_target_cflags='@TARGET_CFLAGS@' -grub_target_cppflags='@TARGET_CPPFLAGS@' -grub_target_ccasflags='@TARGET_CCASFLAGS@' -grub_target_ldflags='@TARGET_LDFLAGS@' -grub_cflags='@CFLAGS@' -grub_cppflags='@CPPFLAGS@' -grub_ccasflags='@CCASFLAGS@' -grub_ldflags='@LDFLAGS@' -grub_target_strip='@TARGET_STRIP@' -grub_target_nm='@TARGET_NM@' -grub_target_ranlib='@TARGET_RANLIB@' -grub_target_objconf='@TARGET_OBJCONV@' -grub_target_obj2elf='@TARGET_OBJ2ELF@' -grub_target_img_base_ldopt='@TARGET_IMG_BASE_LDOPT@' -grub_target_img_ldflags='@TARGET_IMG_BASE_LDFLAGS@' - -# Version -grub_version="@VERSION@" -grub_package="@PACKAGE@" -grub_package_string="@PACKAGE_STRING@" -grub_package_version="@PACKAGE_VERSION@" -grub_package_name="@PACKAGE_NAME@" -grub_package_bugreport="@PACKAGE_BUGREPORT@" diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c deleted file mode 100644 index 1d367436c..000000000 --- a/grub-core/net/arp.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -/* ARP header operation codes */ -enum - { - ARP_REQUEST = 1, - ARP_REPLY = 2 - }; - -enum - { - /* IANA ARP constant to define hardware type as ethernet. */ - GRUB_NET_ARPHRD_ETHERNET = 1 - }; - -struct arppkt { - grub_uint16_t hrd; - grub_uint16_t pro; - grub_uint8_t hln; - grub_uint8_t pln; - grub_uint16_t op; - grub_uint8_t sender_mac[6]; - grub_uint32_t sender_ip; - grub_uint8_t recv_mac[6]; - grub_uint32_t recv_ip; -} GRUB_PACKED; - -static int have_pending; -static grub_uint32_t pending_req; - -grub_err_t -grub_net_arp_send_request (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *proto_addr) -{ - struct grub_net_buff nb; - struct arppkt *arp_packet; - grub_net_link_level_address_t target_mac_addr; - grub_err_t err; - int i; - grub_uint8_t *nbd; - grub_uint8_t arp_data[128]; - - if (proto_addr->type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4) - return grub_error (GRUB_ERR_BUG, "unsupported address family"); - - /* Build a request packet. */ - nb.head = arp_data; - nb.end = arp_data + sizeof (arp_data); - grub_netbuff_clear (&nb); - grub_netbuff_reserve (&nb, 128); - - err = grub_netbuff_push (&nb, sizeof (*arp_packet)); - if (err) - return err; - - arp_packet = (struct arppkt *) nb.data; - arp_packet->hrd = grub_cpu_to_be16_compile_time (GRUB_NET_ARPHRD_ETHERNET); - arp_packet->hln = 6; - arp_packet->pro = grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP); - arp_packet->pln = 4; - arp_packet->op = grub_cpu_to_be16_compile_time (ARP_REQUEST); - /* Sender hardware address. */ - grub_memcpy (arp_packet->sender_mac, &inf->hwaddress.mac, 6); - arp_packet->sender_ip = inf->address.ipv4; - grub_memset (arp_packet->recv_mac, 0, 6); - arp_packet->recv_ip = proto_addr->ipv4; - /* Target protocol address */ - grub_memset (&target_mac_addr.mac, 0xff, 6); - - nbd = nb.data; - send_ethernet_packet (inf, &nb, target_mac_addr, GRUB_NET_ETHERTYPE_ARP); - for (i = 0; i < GRUB_NET_TRIES; i++) - { - if (grub_net_link_layer_resolve_check (inf, proto_addr)) - return GRUB_ERR_NONE; - pending_req = proto_addr->ipv4; - have_pending = 0; - grub_net_poll_cards (GRUB_NET_INTERVAL + (i * GRUB_NET_INTERVAL_ADDITION), - &have_pending); - if (grub_net_link_layer_resolve_check (inf, proto_addr)) - return GRUB_ERR_NONE; - nb.data = nbd; - send_ethernet_packet (inf, &nb, target_mac_addr, GRUB_NET_ETHERTYPE_ARP); - } - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card, - grub_uint16_t *vlantag) -{ - struct arppkt *arp_packet = (struct arppkt *) nb->data; - grub_net_network_level_address_t sender_addr, target_addr; - grub_net_link_level_address_t sender_mac_addr; - struct grub_net_network_level_interface *inf; - - if (arp_packet->pro != grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP) - || arp_packet->pln != 4 || arp_packet->hln != 6 - || nb->tail - nb->data < (int) sizeof (*arp_packet)) - return GRUB_ERR_NONE; - - sender_addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - target_addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - sender_addr.ipv4 = arp_packet->sender_ip; - target_addr.ipv4 = arp_packet->recv_ip; - sender_addr.option = 0; - target_addr.option = 0; - if (arp_packet->sender_ip == pending_req) - have_pending = 1; - - sender_mac_addr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - grub_memcpy (sender_mac_addr.mac, arp_packet->sender_mac, - sizeof (sender_mac_addr.mac)); - grub_net_link_layer_add_address (card, &sender_addr, &sender_mac_addr, 1); - - FOR_NET_NETWORK_LEVEL_INTERFACES (inf) - { - /* Verify vlantag id */ - if (inf->card == card && inf->vlantag != *vlantag) - { - grub_dprintf ("net", "invalid vlantag! %x != %x\n", - inf->vlantag, *vlantag); - break; - } - - /* Am I the protocol address target? */ - if (grub_net_addr_cmp (&inf->address, &target_addr) == 0 - && arp_packet->op == grub_cpu_to_be16_compile_time (ARP_REQUEST)) - { - grub_net_link_level_address_t target; - struct grub_net_buff nb_reply; - struct arppkt *arp_reply; - grub_uint8_t arp_data[128]; - grub_err_t err; - - nb_reply.head = arp_data; - nb_reply.end = arp_data + sizeof (arp_data); - grub_netbuff_clear (&nb_reply); - grub_netbuff_reserve (&nb_reply, 128); - - err = grub_netbuff_push (&nb_reply, sizeof (*arp_packet)); - if (err) - return err; - - arp_reply = (struct arppkt *) nb_reply.data; - - arp_reply->hrd = grub_cpu_to_be16_compile_time (GRUB_NET_ARPHRD_ETHERNET); - arp_reply->pro = grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP); - arp_reply->pln = 4; - arp_reply->hln = 6; - arp_reply->op = grub_cpu_to_be16_compile_time (ARP_REPLY); - arp_reply->sender_ip = arp_packet->recv_ip; - arp_reply->recv_ip = arp_packet->sender_ip; - arp_reply->hln = 6; - - target.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - grub_memcpy (target.mac, arp_packet->sender_mac, 6); - grub_memcpy (arp_reply->sender_mac, inf->hwaddress.mac, 6); - grub_memcpy (arp_reply->recv_mac, arp_packet->sender_mac, 6); - - /* Change operation to REPLY and send packet */ - send_ethernet_packet (inf, &nb_reply, target, GRUB_NET_ETHERTYPE_ARP); - } - } - return GRUB_ERR_NONE; -} diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c deleted file mode 100644 index 2f45a3cc2..000000000 --- a/grub-core/net/bootp.c +++ /dev/null @@ -1,940 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct grub_dhcp_discover_options -{ - grub_uint8_t magic[4]; - struct - { - grub_uint8_t code; - grub_uint8_t len; - grub_uint8_t data; - } GRUB_PACKED message_type; - grub_uint8_t end; -} GRUB_PACKED; - -struct grub_dhcp_request_options -{ - grub_uint8_t magic[4]; - struct - { - grub_uint8_t code; - grub_uint8_t len; - grub_uint8_t data; - } GRUB_PACKED message_type; - struct - { - grub_uint8_t type; - grub_uint8_t len; - grub_uint32_t data; - } GRUB_PACKED server_identifier; - struct - { - grub_uint8_t type; - grub_uint8_t len; - grub_uint32_t data; - } GRUB_PACKED requested_ip; - struct - { - grub_uint8_t type; - grub_uint8_t len; - grub_uint8_t data[7]; - } GRUB_PACKED parameter_request; - grub_uint8_t end; -} GRUB_PACKED; - -enum -{ - GRUB_DHCP_OPT_OVERLOAD_FILE = 1, - GRUB_DHCP_OPT_OVERLOAD_SNAME = 2, -}; -enum -{ - GRUB_DHCP_MESSAGE_UNKNOWN, - GRUB_DHCP_MESSAGE_DISCOVER, - GRUB_DHCP_MESSAGE_OFFER, - GRUB_DHCP_MESSAGE_REQUEST, - GRUB_DHCP_MESSAGE_DECLINE, - GRUB_DHCP_MESSAGE_ACK, - GRUB_DHCP_MESSAGE_NAK, - GRUB_DHCP_MESSAGE_RELEASE, - GRUB_DHCP_MESSAGE_INFORM, -}; - -#define GRUB_BOOTP_MAX_OPTIONS_SIZE 64 - -/* Max timeout when waiting for BOOTP/DHCP reply */ -#define GRUB_DHCP_MAX_PACKET_TIMEOUT 32 - -#define GRUB_BOOTP_MAX_OPTIONS_SIZE 64 - -/* Max timeout when waiting for BOOTP/DHCP reply */ -#define GRUB_DHCP_MAX_PACKET_TIMEOUT 32 - -static char -hexdigit (grub_uint8_t val) -{ - if (val < 10) - return val + '0'; - return val + 'a' - 10; -} - -static const void * -find_dhcp_option (const struct grub_net_bootp_packet *bp, grub_size_t size, - grub_uint8_t opt_code, grub_uint8_t *opt_len) -{ - const grub_uint8_t *ptr; - grub_uint8_t overload = 0; - int end = 0; - grub_size_t i; - - if (opt_len) - *opt_len = 0; - - /* Is the packet big enough to hold at least the magic cookie? */ - if (size < sizeof (*bp) + sizeof (grub_uint32_t)) - return NULL; - - /* - * Pointer arithmetic to point behind the common stub packet, where - * the options start. - */ - ptr = (grub_uint8_t *) (bp + 1); - - if (ptr[0] != GRUB_NET_BOOTP_RFC1048_MAGIC_0 - || ptr[1] != GRUB_NET_BOOTP_RFC1048_MAGIC_1 - || ptr[2] != GRUB_NET_BOOTP_RFC1048_MAGIC_2 - || ptr[3] != GRUB_NET_BOOTP_RFC1048_MAGIC_3) - return NULL; - - size -= sizeof (*bp); - i = sizeof (grub_uint32_t); - -again: - while (i < size) - { - grub_uint8_t tagtype; - grub_uint8_t taglength; - - tagtype = ptr[i++]; - - /* Pad tag. */ - if (tagtype == GRUB_NET_BOOTP_PAD) - continue; - - /* End tag. */ - if (tagtype == GRUB_NET_BOOTP_END) - { - end = 1; - break; - } - - if (i >= size) - return NULL; - - taglength = ptr[i++]; - if (i + taglength >= size) - return NULL; - - grub_dprintf("net", "DHCP option %u (0x%02x) found with length %u.\n", - tagtype, tagtype, taglength); - - /* FIXME RFC 3396 options concatentation */ - if (tagtype == opt_code) - { - if (opt_len) - *opt_len = taglength; - return &ptr[i]; - } - - if (tagtype == GRUB_NET_DHCP_OVERLOAD && taglength == 1) - overload = ptr[i]; - - i += taglength; - } - - if (!end) - return NULL; - - /* RFC2131, 4.1, 23ff: - * If the options in a DHCP message extend into the 'sname' and 'file' - * fields, the 'option overload' option MUST appear in the 'options' - * field, with value 1, 2 or 3, as specified in RFC 1533. If the - * 'option overload' option is present in the 'options' field, the - * options in the 'options' field MUST be terminated by an 'end' option, - * and MAY contain one or more 'pad' options to fill the options field. - * The options in the 'sname' and 'file' fields (if in use as indicated - * by the 'options overload' option) MUST begin with the first octet of - * the field, MUST be terminated by an 'end' option, and MUST be - * followed by 'pad' options to fill the remainder of the field. Any - * individual option in the 'options', 'sname' and 'file' fields MUST be - * entirely contained in that field. The options in the 'options' field - * MUST be interpreted first, so that any 'option overload' options may - * be interpreted. The 'file' field MUST be interpreted next (if the - * 'option overload' option indicates that the 'file' field contains - * DHCP options), followed by the 'sname' field. - * - * FIXME: We do not explicitly check for trailing 'pad' options here. - */ - end = 0; - if (overload & GRUB_DHCP_OPT_OVERLOAD_FILE) - { - overload &= ~GRUB_DHCP_OPT_OVERLOAD_FILE; - ptr = (grub_uint8_t *) &bp->boot_file[0]; - size = sizeof (bp->boot_file); - i = 0; - goto again; - } - - if (overload & GRUB_DHCP_OPT_OVERLOAD_SNAME) - { - overload &= ~GRUB_DHCP_OPT_OVERLOAD_SNAME; - ptr = (grub_uint8_t *) &bp->server_name[0]; - size = sizeof (bp->server_name); - i = 0; - goto again; - } - - return NULL; -} - -#define OFFSET_OF(x, y) ((grub_size_t)((grub_uint8_t *)((y)->x) - (grub_uint8_t *)(y))) - -struct grub_net_network_level_interface * -grub_net_configure_by_dhcp_ack (const char *name, - struct grub_net_card *card, - grub_net_interface_flags_t flags, - const struct grub_net_bootp_packet *bp, - grub_size_t size, - int is_def, char **device, char **path) -{ - grub_net_network_level_address_t addr; - grub_net_link_level_address_t hwaddr; - struct grub_net_network_level_interface *inter; - int mask = -1; - char server_ip[sizeof ("xxx.xxx.xxx.xxx")]; - const grub_uint8_t *opt; - grub_uint8_t opt_len, overload = 0; - const char *boot_file = 0, *server_name = 0; - grub_size_t boot_file_len, server_name_len; - - addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - addr.ipv4 = bp->your_ip; - addr.option = 0; - - if (device) - *device = 0; - if (path) - *path = 0; - - grub_memcpy (hwaddr.mac, bp->mac_addr, - bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len - : sizeof (hwaddr.mac)); - hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - - inter = grub_net_add_addr (name, card, &addr, &hwaddr, flags); - if (!inter) - return 0; - - opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_OVERLOAD, &opt_len); - if (opt && opt_len == 1) - overload = *opt; - - opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_TFTP_SERVER_NAME, &opt_len); - if (opt && opt_len) - { - server_name = (const char *) opt; - server_name_len = opt_len; - } - else if (size > OFFSET_OF (server_name, bp) && !(overload & GRUB_DHCP_OPT_OVERLOAD_SNAME) && - bp->server_name[0]) - { - server_name = bp->server_name; - server_name_len = sizeof (bp->server_name); - } - - opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_BOOTFILE_NAME, &opt_len); - if (opt && opt_len) - { - boot_file = (const char *) opt; - boot_file_len = opt_len; - } - else if (size > OFFSET_OF (boot_file, bp) && !(overload && GRUB_DHCP_OPT_OVERLOAD_FILE) && - bp->boot_file[0]) - { - boot_file = bp->boot_file; - boot_file_len = sizeof (bp->boot_file); - } - - if (bp->server_ip) - { - grub_snprintf (server_ip, sizeof (server_ip), "%d.%d.%d.%d", - ((grub_uint8_t *) &bp->server_ip)[0], - ((grub_uint8_t *) &bp->server_ip)[1], - ((grub_uint8_t *) &bp->server_ip)[2], - ((grub_uint8_t *) &bp->server_ip)[3]); - grub_env_set_net_property (name, "next_server", server_ip, sizeof (server_ip)); - grub_print_error (); - } - - if (is_def) - grub_net_default_server = 0; - if (is_def && !grub_net_default_server && bp->server_ip) - { - grub_net_default_server = grub_strdup (server_ip); - grub_print_error (); - } - - if (is_def) - { - grub_env_set ("net_default_interface", name); - grub_env_export ("net_default_interface"); - } - - if (device && !*device && bp->server_ip) - { - *device = grub_xasprintf ("tftp,%s", server_ip); - grub_print_error (); - } - - if (server_name) - { - grub_env_set_net_property (name, "dhcp_server_name", server_name, server_name_len); - if (is_def && !grub_net_default_server) - { - grub_net_default_server = grub_strdup (server_name); - grub_print_error (); - } - if (device && !*device) - { - *device = grub_xasprintf ("tftp,%s", server_name); - grub_print_error (); - } - } - - if (boot_file) - { - grub_env_set_net_property (name, "boot_file", boot_file, boot_file_len); - if (path) - { - *path = grub_strndup (boot_file, boot_file_len); - grub_print_error (); - if (*path) - { - char *slash; - slash = grub_strrchr (*path, '/'); - if (slash) - *slash = 0; - else - **path = 0; - } - } - } - - opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_NETMASK, &opt_len); - if (opt && opt_len == 4) - { - int i; - for (i = 0; i < 32; i++) - if (!(opt[i / 8] & (1 << (7 - (i % 8))))) - break; - mask = i; - } - grub_net_add_ipv4_local (inter, mask); - - /* We do not implement dead gateway detection and the first entry SHOULD - be preferred one */ - opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_ROUTER, &opt_len); - if (opt && opt_len && !(opt_len & 3)) - { - grub_net_network_level_netaddress_t target; - grub_net_network_level_address_t gw; - char *rname; - - target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - target.ipv4.base = 0; - target.ipv4.masksize = 0; - gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - gw.ipv4 = grub_get_unaligned32 (opt); - rname = grub_xasprintf ("%s:default", name); - if (rname) - grub_net_add_route_gw (rname, target, gw, 0); - grub_free (rname); - } - - opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_DNS, &opt_len); - if (opt && opt_len && !(opt_len & 3)) - { - int i; - for (i = 0; i < opt_len / 4; i++) - { - struct grub_net_network_level_address s; - - s.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - s.ipv4 = grub_get_unaligned32 (opt); - s.option = DNS_OPTION_PREFER_IPV4; - grub_net_add_dns_server (&s); - opt += 4; - } - } - - opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_HOSTNAME, &opt_len); - if (opt && opt_len) - grub_env_set_net_property (name, "hostname", (const char *) opt, opt_len); - - opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_DOMAIN, &opt_len); - if (opt && opt_len) - grub_env_set_net_property (name, "domain", (const char *) opt, opt_len); - - opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_ROOT_PATH, &opt_len); - if (opt && opt_len) - grub_env_set_net_property (name, "rootpath", (const char *) opt, opt_len); - - opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_EXTENSIONS_PATH, &opt_len); - if (opt && opt_len) - grub_env_set_net_property (name, "extensionspath", (const char *) opt, opt_len); - - opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_CLIENT_ID, &opt_len); - if (opt && opt_len) - grub_env_set_net_property (name, "clientid", (const char *) opt, opt_len); - - opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_CLIENT_UUID, &opt_len); - if (opt && opt_len == 17) - { - /* The format is 9cfe245e-d0c8-bd45-a79f-54ea5fbd3d97 */ - char *val; - int i, j = 0; - - opt += 1; - opt_len -= 1; - - val = grub_malloc (2 * opt_len + 4 + 1); - if (!val) - return inter; - - for (i = 0; i < opt_len; i++) - { - val[2 * i + j] = hexdigit (opt[i] >> 4); - val[2 * i + 1 + j] = hexdigit (opt[i] & 0xf); - - if ((i == 3) || (i == 5) || (i == 7) || (i == 9)) - { - j++; - val[2 * i + 1+ j] = '-'; - } - } - grub_env_set_net_property (name, "clientuuid", (char *) val, 2 * opt_len + 4); - grub_free (val); - } - - inter->dhcp_ack = grub_malloc (size); - if (inter->dhcp_ack) - { - grub_memcpy (inter->dhcp_ack, bp, size); - inter->dhcp_acklen = size; - } - else - grub_errno = GRUB_ERR_NONE; - - return inter; -} - -static grub_err_t -send_dhcp_packet (struct grub_net_network_level_interface *iface) -{ - grub_err_t err; - struct grub_net_bootp_packet *pack; - struct grub_datetime date; - grub_int64_t t = 0; - struct grub_net_buff *nb; - struct udphdr *udph; - grub_net_network_level_address_t target; - grub_net_link_level_address_t ll_target; - - static struct grub_dhcp_discover_options discover_options = - { - { - GRUB_NET_BOOTP_RFC1048_MAGIC_0, - GRUB_NET_BOOTP_RFC1048_MAGIC_1, - GRUB_NET_BOOTP_RFC1048_MAGIC_2, - GRUB_NET_BOOTP_RFC1048_MAGIC_3, - }, - { - GRUB_NET_DHCP_MESSAGE_TYPE, - sizeof (discover_options.message_type.data), - GRUB_DHCP_MESSAGE_DISCOVER, - }, - GRUB_NET_BOOTP_END, - }; - - static struct grub_dhcp_request_options request_options = - { - { - GRUB_NET_BOOTP_RFC1048_MAGIC_0, - GRUB_NET_BOOTP_RFC1048_MAGIC_1, - GRUB_NET_BOOTP_RFC1048_MAGIC_2, - GRUB_NET_BOOTP_RFC1048_MAGIC_3, - }, - { - GRUB_NET_DHCP_MESSAGE_TYPE, - sizeof (request_options.message_type.data), - GRUB_DHCP_MESSAGE_REQUEST, - }, - { - GRUB_NET_DHCP_SERVER_IDENTIFIER, - sizeof (request_options.server_identifier.data), - 0, - }, - { - GRUB_NET_DHCP_REQUESTED_IP_ADDRESS, - sizeof (request_options.requested_ip.data), - 0, - }, - { - GRUB_NET_DHCP_PARAMETER_REQUEST_LIST, - sizeof (request_options.parameter_request.data), - { - GRUB_NET_BOOTP_NETMASK, - GRUB_NET_BOOTP_ROUTER, - GRUB_NET_BOOTP_DNS, - GRUB_NET_BOOTP_DOMAIN, - GRUB_NET_BOOTP_HOSTNAME, - GRUB_NET_BOOTP_ROOT_PATH, - GRUB_NET_BOOTP_EXTENSIONS_PATH, - }, - }, - GRUB_NET_BOOTP_END, - }; - - COMPILE_TIME_ASSERT (sizeof (discover_options) <= GRUB_BOOTP_MAX_OPTIONS_SIZE); - COMPILE_TIME_ASSERT (sizeof (request_options) <= GRUB_BOOTP_MAX_OPTIONS_SIZE); - - nb = grub_netbuff_alloc (sizeof (*pack) + GRUB_BOOTP_MAX_OPTIONS_SIZE + 128); - if (!nb) - return grub_errno; - - err = grub_netbuff_reserve (nb, sizeof (*pack) + GRUB_BOOTP_MAX_OPTIONS_SIZE + 128); - if (err) - goto out; - - err = grub_netbuff_push (nb, GRUB_BOOTP_MAX_OPTIONS_SIZE); - if (err) - goto out; - - grub_memset (nb->data, 0, GRUB_BOOTP_MAX_OPTIONS_SIZE); - if (!iface->srv_id) - { - grub_memcpy (nb->data, &discover_options, sizeof (discover_options)); - } - else - { - struct grub_dhcp_request_options *ro = (struct grub_dhcp_request_options *) nb->data; - - grub_memcpy (nb->data, &request_options, sizeof (request_options)); - /* my_ip and srv_id are stored in network order so do not need conversion. */ - grub_set_unaligned32 (&ro->server_identifier.data, iface->srv_id); - grub_set_unaligned32 (&ro->requested_ip.data, iface->my_ip); - } - - err = grub_netbuff_push (nb, sizeof (*pack)); - if (err) - goto out; - - pack = (void *) nb->data; - grub_memset (pack, 0, sizeof (*pack)); - pack->opcode = 1; - pack->hw_type = 1; - pack->hw_len = 6; - err = grub_get_datetime (&date); - if (err || !grub_datetime2unixtime (&date, &t)) - { - grub_errno = GRUB_ERR_NONE; - t = 0; - } - pack->seconds = grub_cpu_to_be16 (t); - if (!iface->srv_id) - iface->xid = pack->ident = grub_cpu_to_be32 (t); - else - pack->ident = iface->xid; - - grub_memcpy (&pack->mac_addr, &iface->hwaddress.mac, 6); - - err = grub_netbuff_push (nb, sizeof (*udph)); - if (err) - goto out; - - udph = (struct udphdr *) nb->data; - udph->src = grub_cpu_to_be16_compile_time (68); - udph->dst = grub_cpu_to_be16_compile_time (67); - udph->chksum = 0; - udph->len = grub_cpu_to_be16 (nb->tail - nb->data); - target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - target.ipv4 = 0xffffffff; - err = grub_net_link_layer_resolve (iface, &target, &ll_target); - if (err) - goto out; - - udph->chksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_UDP, - &iface->address, - &target); - - err = grub_net_send_ip_packet (iface, &target, &ll_target, nb, - GRUB_NET_IP_UDP); - -out: - grub_netbuff_free (nb); - return err; -} - -/* - * This is called directly from net/ip.c:handle_dgram(), because those - * BOOTP/DHCP packets are a bit special due to their improper - * sender/receiver IP fields. - */ -void -grub_net_process_dhcp (struct grub_net_buff *nb, - struct grub_net_network_level_interface *iface) -{ - char *name; - struct grub_net_card *card = iface->card; - const struct grub_net_bootp_packet *bp = (const struct grub_net_bootp_packet *) nb->data; - grub_size_t size = nb->tail - nb->data; - const grub_uint8_t *opt; - grub_uint8_t opt_len, type; - grub_uint32_t srv_id = 0; - - opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_MESSAGE_TYPE, &opt_len); - if (opt && opt_len == 1) - type = *opt; - else - type = GRUB_DHCP_MESSAGE_UNKNOWN; - - opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_SERVER_IDENTIFIER, &opt_len); - if (opt && opt_len == sizeof (srv_id)) - srv_id = grub_get_unaligned32 (opt); - - /* - * If we received BOOTP reply or DHCPACK, proceed with configuration. - * Otherwise store offered address and server id for later processing - * of DHCPACK. - * xid and srv_id are stored in network order so do not need conversion. - */ - if ((!iface->srv_id && type == GRUB_DHCP_MESSAGE_UNKNOWN) - || (iface->srv_id && type == GRUB_DHCP_MESSAGE_ACK - && bp->ident == iface->xid - && srv_id == iface->srv_id)) - { - name = grub_xasprintf ("%s:dhcp", card->name); - if (!name) - { - grub_print_error (); - return; - } - grub_net_configure_by_dhcp_ack (name, card, 0, bp, size, 0, 0, 0); - grub_free (name); - if (grub_errno) - grub_print_error (); - else - grub_net_network_level_interface_unregister (iface); - } - else if (!iface->srv_id && type == GRUB_DHCP_MESSAGE_OFFER && srv_id) - { - iface->srv_id = srv_id; - iface->my_ip = bp->your_ip; - /* Reset retransmission timer */ - iface->dhcp_tmo = iface->dhcp_tmo_left = 1; - } - else if (iface->srv_id && type == GRUB_DHCP_MESSAGE_NAK - && bp->ident == iface->xid - && srv_id == iface->srv_id) - { - iface->xid = iface->srv_id = iface->my_ip = 0; - /* Reset retransmission timer */ - iface->dhcp_tmo = iface->dhcp_tmo_left = 1; - } -} - -static grub_err_t -grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - struct grub_net_network_level_interface *inter; - unsigned num; - const grub_uint8_t *ptr; - grub_uint8_t taglength; - grub_uint8_t len; - - if (argc < 4) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("four arguments expected")); - - FOR_NET_NETWORK_LEVEL_INTERFACES (inter) - if (grub_strcmp (inter->name, args[1]) == 0) - break; - - if (!inter) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unrecognised network interface `%s'"), args[1]); - - if (!inter->dhcp_ack) - return grub_error (GRUB_ERR_IO, N_("no DHCP info found")); - - ptr = inter->dhcp_ack->vendor; - - /* This duplicates check in find_dhcp_option to preserve previous error return */ - if (inter->dhcp_acklen < OFFSET_OF (vendor, inter->dhcp_ack) + sizeof (grub_uint32_t) - || ptr[0] != GRUB_NET_BOOTP_RFC1048_MAGIC_0 - || ptr[1] != GRUB_NET_BOOTP_RFC1048_MAGIC_1 - || ptr[2] != GRUB_NET_BOOTP_RFC1048_MAGIC_2 - || ptr[3] != GRUB_NET_BOOTP_RFC1048_MAGIC_3) - return grub_error (GRUB_ERR_IO, N_("no DHCP options found")); - - num = grub_strtoul (args[2], 0, 0); - if (grub_errno) - return grub_errno; - - /* Exclude PAD (0) and END (255) option codes */ - if (num == 0 || num > 254) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid DHCP option code")); - - ptr = find_dhcp_option (inter->dhcp_ack, inter->dhcp_acklen, num, &taglength); - if (!ptr) - return grub_error (GRUB_ERR_IO, N_("no DHCP option %u found"), num); - - if (grub_strcmp (args[3], "string") == 0) - { - grub_err_t err = GRUB_ERR_NONE; - char *val; - - if (grub_add (taglength, 1, &len)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("tag length overflow")); - - val = grub_malloc (len); - if (!val) - return grub_errno; - grub_memcpy (val, ptr, taglength); - val[taglength] = 0; - if (args[0][0] == '-' && args[0][1] == 0) - grub_printf ("%s\n", val); - else - err = grub_env_set (args[0], val); - grub_free (val); - return err; - } - - if (grub_strcmp (args[3], "number") == 0) - { - grub_uint64_t val = 0; - int i; - for (i = 0; i < taglength; i++) - val = (val << 8) | ptr[i]; - if (args[0][0] == '-' && args[0][1] == 0) - grub_printf ("%llu\n", (unsigned long long) val); - else - { - char valn[64]; - grub_snprintf (valn, sizeof (valn), "%lld\n", (unsigned long long) val); - return grub_env_set (args[0], valn); - } - return GRUB_ERR_NONE; - } - - if (grub_strcmp (args[3], "hex") == 0) - { - grub_err_t err = GRUB_ERR_NONE; - char *val; - - if (grub_mul (taglength, 2, &len) || grub_add (len, 1, &len)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("tag length overflow")); - - val = grub_malloc (len); - int i; - if (!val) - return grub_errno; - for (i = 0; i < taglength; i++) - { - val[2 * i] = hexdigit (ptr[i] >> 4); - val[2 * i + 1] = hexdigit (ptr[i] & 0xf); - } - val[2 * taglength] = 0; - if (args[0][0] == '-' && args[0][1] == 0) - grub_printf ("%s\n", val); - else - err = grub_env_set (args[0], val); - grub_free (val); - return err; - } - - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unrecognised DHCP option format specification `%s'"), - args[3]); -} - -/* FIXME: allow to specify mac address. */ -static grub_err_t -grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - struct grub_net_card *card; - struct grub_net_network_level_interface *ifaces; - grub_size_t ncards = 0; - unsigned j = 0; - grub_err_t err; - unsigned i; - - FOR_NET_CARDS (card) - { - if (argc > 0 && grub_strcmp (card->name, args[0]) != 0) - continue; - ncards++; - } - - if (ncards == 0) - return grub_error (GRUB_ERR_NET_NO_CARD, N_("no network card found")); - - ifaces = grub_calloc (ncards, sizeof (ifaces[0])); - if (!ifaces) - return grub_errno; - - j = 0; - FOR_NET_CARDS (card) - { - if (argc > 0 && grub_strcmp (card->name, args[0]) != 0) - continue; - ifaces[j].card = card; - ifaces[j].next = &ifaces[j+1]; - if (j) - ifaces[j].prev = &ifaces[j-1].next; - ifaces[j].name = grub_xasprintf ("%s:dhcp_tmp", card->name); - card->num_ifaces++; - if (!ifaces[j].name) - { - for (i = 0; i < j; i++) - grub_free (ifaces[i].name); - grub_free (ifaces); - return grub_errno; - } - ifaces[j].address.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV; - grub_memcpy (&ifaces[j].hwaddress, &card->default_address, - sizeof (ifaces[j].hwaddress)); - ifaces[j].dhcp_tmo = ifaces[j].dhcp_tmo_left = 1; - j++; - } - ifaces[ncards - 1].next = grub_net_network_level_interfaces; - if (grub_net_network_level_interfaces) - grub_net_network_level_interfaces->prev = & ifaces[ncards - 1].next; - grub_net_network_level_interfaces = &ifaces[0]; - ifaces[0].prev = &grub_net_network_level_interfaces; - - /* - * Running DHCP restransmission timer is kept per interface in dhcp_tmo_left. - * When it runs off, dhcp_tmo is increased exponentionally and dhcp_tmo_left - * initialized to it. Max value is 32 which gives approximately 12s total per - * packet timeout assuming 200ms poll tick. Timeout is reset when DHCP OFFER - * is received, so total timeout is 25s in the worst case. - * - * DHCP NAK also resets timer and transaction starts again. - * - * Total wait time is limited to ~25s to prevent endless loop in case of - * permanent NAK - */ - for (i = 0; i < GRUB_DHCP_MAX_PACKET_TIMEOUT * 4; i++) - { - int need_poll = 0; - for (j = 0; j < ncards; j++) - { - if (!ifaces[j].prev || - ifaces[j].dhcp_tmo > GRUB_DHCP_MAX_PACKET_TIMEOUT) - continue; - - if (--ifaces[j].dhcp_tmo_left) - { - need_poll = 1; - continue; - } - - ifaces[j].dhcp_tmo *= 2; - if (ifaces[j].dhcp_tmo > GRUB_DHCP_MAX_PACKET_TIMEOUT) - continue; - - err = send_dhcp_packet (&ifaces[j]); - if (err) - { - grub_print_error (); - /* To ignore it during next poll */ - ifaces[j].dhcp_tmo = GRUB_DHCP_MAX_PACKET_TIMEOUT + 1; - continue; - } - ifaces[j].dhcp_tmo_left = ifaces[j].dhcp_tmo; - need_poll = 1; - } - if (!need_poll) - break; - grub_net_poll_cards (200, 0); - } - - err = GRUB_ERR_NONE; - for (j = 0; j < ncards; j++) - { - grub_free (ifaces[j].name); - if (!ifaces[j].prev) - continue; - grub_error_push (); - grub_net_network_level_interface_unregister (&ifaces[j]); - err = grub_error (GRUB_ERR_FILE_NOT_FOUND, - N_("couldn't autoconfigure %s"), - ifaces[j].card->name); - } - - grub_free (ifaces); - return err; -} - -static grub_command_t cmd_getdhcp, cmd_bootp, cmd_dhcp; - -void -grub_bootp_init (void) -{ - cmd_bootp = grub_register_command ("net_bootp", grub_cmd_bootp, - N_("[CARD]"), - N_("perform a bootp autoconfiguration")); - cmd_dhcp = grub_register_command ("net_dhcp", grub_cmd_bootp, - N_("[CARD]"), - N_("perform a DHCP autoconfiguration")); - cmd_getdhcp = grub_register_command ("net_get_dhcp_option", grub_cmd_dhcpopt, - N_("VAR INTERFACE NUMBER DESCRIPTION"), - N_("retrieve DHCP option and save it into VAR. If VAR is - then print the value.")); -} - -void -grub_bootp_fini (void) -{ - grub_unregister_command (cmd_getdhcp); - grub_unregister_command (cmd_bootp); - grub_unregister_command (cmd_dhcp); -} diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c deleted file mode 100644 index f20cd6f83..000000000 --- a/grub-core/net/dns.c +++ /dev/null @@ -1,786 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -struct dns_cache_element -{ - char *name; - grub_size_t naddresses; - struct grub_net_network_level_address *addresses; - grub_uint64_t limit_time; -}; - -#define DNS_CACHE_SIZE 1021 -#define DNS_HASH_BASE 423 - -typedef enum grub_dns_qtype_id - { - GRUB_DNS_QTYPE_A = 1, - GRUB_DNS_QTYPE_AAAA = 28 - } grub_dns_qtype_id_t; - -static struct dns_cache_element dns_cache[DNS_CACHE_SIZE]; -static struct grub_net_network_level_address *dns_servers; -static grub_size_t dns_nservers, dns_servers_alloc; - -grub_err_t -grub_net_add_dns_server (const struct grub_net_network_level_address *s) -{ - if (dns_servers_alloc <= dns_nservers) - { - int na = dns_servers_alloc * 2; - struct grub_net_network_level_address *ns; - grub_size_t sz; - - if (na < 8) - na = 8; - - if (grub_mul (na, sizeof (ns[0]), &sz)) - return GRUB_ERR_OUT_OF_RANGE; - - ns = grub_realloc (dns_servers, sz); - if (!ns) - return grub_errno; - dns_servers_alloc = na; - dns_servers = ns; - } - dns_servers[dns_nservers++] = *s; - return GRUB_ERR_NONE; -} - -void -grub_net_remove_dns_server (const struct grub_net_network_level_address *s) -{ - grub_size_t i; - for (i = 0; i < dns_nservers; i++) - if (grub_net_addr_cmp (s, &dns_servers[i]) == 0) - break; - if (i < dns_nservers) - { - dns_servers[i] = dns_servers[dns_nservers - 1]; - dns_nservers--; - } -} - -struct dns_header -{ - grub_uint16_t id; - grub_uint8_t flags; - grub_uint8_t ra_z_r_code; - grub_uint16_t qdcount; - grub_uint16_t ancount; - grub_uint16_t nscount; - grub_uint16_t arcount; -} GRUB_PACKED; - -enum - { - FLAGS_RESPONSE = 0x80, - FLAGS_OPCODE = 0x78, - FLAGS_RD = 0x01 - }; - -enum - { - ERRCODE_MASK = 0x0f - }; - -enum - { - DNS_PORT = 53 - }; - -struct recv_data -{ - grub_size_t *naddresses; - struct grub_net_network_level_address **addresses; - int cache; - grub_uint16_t id; - int dns_err; - char *name; - const char *oname; - int stop; -}; - -static inline int -hash (const char *str) -{ - unsigned v = 0, xn = 1; - const char *ptr; - for (ptr = str; *ptr; ) - { - v = (v + xn * *ptr); - xn = (DNS_HASH_BASE * xn) % DNS_CACHE_SIZE; - ptr++; - if (((ptr - str) & 0x3ff) == 0) - v %= DNS_CACHE_SIZE; - } - return v % DNS_CACHE_SIZE; -} - -static int -check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head, - const grub_uint8_t *tail, const char *check_with, - int *length, char *set) -{ - const char *readable_ptr = check_with; - int readable_len; - const grub_uint8_t *ptr; - char *optr = set; - int bytes_processed = 0; - if (length) - *length = 0; - - if (readable_ptr != NULL) - readable_len = grub_strlen (readable_ptr); - else - readable_len = 0; - - for (ptr = name_at; ptr < tail && bytes_processed < tail - head + 2; ) - { - /* End marker. */ - if (!*ptr) - { - if (length && *length) - (*length)--; - if (optr && optr != set) - optr--; - if (optr) - *optr = 0; - return !readable_ptr || (*readable_ptr == 0); - } - if (*ptr & 0xc0) - { - bytes_processed += 2; - if (ptr + 1 >= tail) - return 0; - ptr = head + (((ptr[0] & 0x3f) << 8) | ptr[1]); - continue; - } - if (readable_ptr != NULL && (*ptr > readable_len || grub_memcmp (ptr + 1, readable_ptr, *ptr) != 0)) - return 0; - if (grub_memchr (ptr + 1, 0, *ptr) - || grub_memchr (ptr + 1, '.', *ptr)) - return 0; - if (readable_ptr) - { - readable_ptr += *ptr; - readable_len -= *ptr; - } - if (readable_ptr && *readable_ptr != '.' && *readable_ptr != 0) - return 0; - bytes_processed += *ptr + 1; - if (length) - *length += *ptr + 1; - if (optr) - { - grub_memcpy (optr, ptr + 1, *ptr); - optr += *ptr; - } - if (optr) - *optr++ = '.'; - if (readable_ptr && *readable_ptr) - { - readable_ptr++; - readable_len--; - } - ptr += *ptr + 1; - } - return 0; -} - -static int -check_name (const grub_uint8_t *name_at, const grub_uint8_t *head, - const grub_uint8_t *tail, const char *check_with) -{ - return check_name_real (name_at, head, tail, check_with, NULL, NULL); -} - -static char * -get_name (const grub_uint8_t *name_at, const grub_uint8_t *head, - const grub_uint8_t *tail) -{ - int length; - char *ret; - int len; - - if (!check_name_real (name_at, head, tail, NULL, &length, NULL)) - return NULL; - - if (grub_add (length, 1, &len)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("name length overflow")); - return NULL; - } - ret = grub_malloc (len); - if (!ret) - return NULL; - if (!check_name_real (name_at, head, tail, NULL, NULL, ret)) - { - grub_free (ret); - return NULL; - } - return ret; -} - -enum - { - DNS_CLASS_A = 1, - DNS_CLASS_CNAME = 5, - DNS_CLASS_AAAA = 28 - }; - -static grub_err_t -recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), - struct grub_net_buff *nb, - void *data_) -{ - struct dns_header *head; - struct recv_data *data = data_; - int i, j; - grub_uint8_t *ptr, *reparse_ptr; - int redirect_cnt = 0; - char *redirect_save = NULL; - grub_uint32_t ttl_all = ~0U; - - /* Code apparently assumed that only one packet is received as response. - We may get multiple responses due to network condition, so check here - and quit early. */ - if (*data->naddresses) - goto out; - - head = (struct dns_header *) nb->data; - ptr = (grub_uint8_t *) (head + 1); - if (ptr >= nb->tail) - goto out; - - if (head->id != data->id) - goto out; - if (!(head->flags & FLAGS_RESPONSE) || (head->flags & FLAGS_OPCODE)) - goto out; - if (head->ra_z_r_code & ERRCODE_MASK) - { - data->dns_err = 1; - goto out; - } - for (i = 0; i < grub_be_to_cpu16 (head->qdcount); i++) - { - if (ptr >= nb->tail) - goto out; - while (ptr < nb->tail && !((*ptr & 0xc0) || *ptr == 0)) - ptr += *ptr + 1; - if (ptr < nb->tail && (*ptr & 0xc0)) - ptr++; - ptr++; - ptr += 4; - } - *data->addresses = grub_calloc (grub_be_to_cpu16 (head->ancount), - sizeof ((*data->addresses)[0])); - if (!*data->addresses) - { - grub_errno = GRUB_ERR_NONE; - goto out; - } - reparse_ptr = ptr; - reparse: - for (i = 0, ptr = reparse_ptr; i < grub_be_to_cpu16 (head->ancount); i++) - { - int ignored = 0; - grub_uint8_t class; - grub_uint32_t ttl = 0; - grub_uint16_t length; - if (ptr >= nb->tail) - goto out; - ignored = !check_name (ptr, nb->data, nb->tail, data->name); - while (ptr < nb->tail && !((*ptr & 0xc0) || *ptr == 0)) - ptr += *ptr + 1; - if (ptr < nb->tail && (*ptr & 0xc0)) - ptr++; - ptr++; - if (ptr + 10 >= nb->tail) - goto out; - if (*ptr++ != 0) - ignored = 1; - class = *ptr++; - if (*ptr++ != 0) - ignored = 1; - if (*ptr++ != 1) - ignored = 1; - for (j = 0; j < 4; j++) - { - ttl <<= 8; - ttl |= *ptr++; - } - length = *ptr++ << 8; - length |= *ptr++; - if (ptr + length > nb->tail) - goto out; - if (!ignored) - { - if (ttl_all > ttl) - ttl_all = ttl; - switch (class) - { - case DNS_CLASS_A: - if (length != 4) - break; - (*data->addresses)[*data->naddresses].type - = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - grub_memcpy (&(*data->addresses)[*data->naddresses].ipv4, - ptr, 4); - grub_dprintf ("dns", "got A 0x%x\n", (*data->addresses)[*data->naddresses].ipv4); - (*data->naddresses)++; - data->stop = 1; - break; - case DNS_CLASS_AAAA: - if (length != 16) - break; - (*data->addresses)[*data->naddresses].type - = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; - grub_memcpy (&(*data->addresses)[*data->naddresses].ipv6, - ptr, 16); - grub_dprintf ("dns", "got AAAA 0x%" PRIxGRUB_UINT64_T "%" PRIxGRUB_UINT64_T "\n", - (*data->addresses)[*data->naddresses].ipv6[0], - (*data->addresses)[*data->naddresses].ipv6[1]); - (*data->naddresses)++; - data->stop = 1; - break; - case DNS_CLASS_CNAME: - if (!(redirect_cnt & (redirect_cnt - 1))) - { - grub_free (redirect_save); - redirect_save = data->name; - } - else - grub_free (data->name); - redirect_cnt++; - data->name = get_name (ptr, nb->data, nb->tail); - if (!data->name) - { - data->dns_err = 1; - grub_errno = GRUB_ERR_NONE; - goto out; - } - grub_dprintf ("dns", "CNAME %s\n", data->name); - if (grub_strcmp (redirect_save, data->name) == 0) - { - data->dns_err = 1; - goto out; - } - goto reparse; - } - } - ptr += length; - } - if (ttl_all && *data->naddresses && data->cache) - { - int h; - grub_dprintf ("dns", "caching for %d seconds\n", ttl_all); - h = hash (data->oname); - grub_free (dns_cache[h].name); - dns_cache[h].name = 0; - grub_free (dns_cache[h].addresses); - dns_cache[h].addresses = 0; - dns_cache[h].name = grub_strdup (data->oname); - dns_cache[h].naddresses = *data->naddresses; - dns_cache[h].addresses = grub_calloc (*data->naddresses, - sizeof (dns_cache[h].addresses[0])); - dns_cache[h].limit_time = grub_get_time_ms () + 1000 * ttl_all; - if (!dns_cache[h].addresses || !dns_cache[h].name) - { - grub_free (dns_cache[h].name); - dns_cache[h].name = 0; - grub_free (dns_cache[h].addresses); - dns_cache[h].addresses = 0; - } - grub_memcpy (dns_cache[h].addresses, *data->addresses, - *data->naddresses - * sizeof (dns_cache[h].addresses[0])); - } - - out: - grub_netbuff_free (nb); - grub_free (redirect_save); - if (!*data->naddresses) - grub_free (*data->addresses); - return GRUB_ERR_NONE; -} - -grub_err_t -grub_net_dns_lookup (const char *name, - const struct grub_net_network_level_address *servers, - grub_size_t n_servers, - grub_size_t *naddresses, - struct grub_net_network_level_address **addresses, - int cache) -{ - grub_size_t send_servers = 0; - grub_size_t i, j; - struct grub_net_buff *nb; - grub_net_udp_socket_t *sockets; - grub_uint8_t *optr; - const char *iptr; - struct dns_header *head; - static grub_uint16_t id = 1; - grub_uint8_t *qtypeptr; - grub_err_t err = GRUB_ERR_NONE; - struct recv_data data = {naddresses, addresses, cache, - grub_cpu_to_be16 (id++), 0, 0, name, 0}; - grub_uint8_t *nbd; - grub_size_t try_server = 0; - - if (!servers) - { - servers = dns_servers; - n_servers = dns_nservers; - } - - if (!n_servers) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("no DNS servers configured")); - - *naddresses = 0; - if (cache) - { - int h; - h = hash (name); - if (dns_cache[h].name && grub_strcmp (dns_cache[h].name, name) == 0 - && grub_get_time_ms () < dns_cache[h].limit_time) - { - grub_dprintf ("dns", "retrieved from cache\n"); - *addresses = grub_calloc (dns_cache[h].naddresses, - sizeof ((*addresses)[0])); - if (!*addresses) - return grub_errno; - *naddresses = dns_cache[h].naddresses; - grub_memcpy (*addresses, dns_cache[h].addresses, - dns_cache[h].naddresses - * sizeof ((*addresses)[0])); - return GRUB_ERR_NONE; - } - } - - sockets = grub_calloc (n_servers, sizeof (sockets[0])); - if (!sockets) - return grub_errno; - - data.name = grub_strdup (name); - if (!data.name) - { - grub_free (sockets); - return grub_errno; - } - - nb = grub_netbuff_alloc (GRUB_NET_OUR_MAX_IP_HEADER_SIZE - + GRUB_NET_MAX_LINK_HEADER_SIZE - + GRUB_NET_UDP_HEADER_SIZE - + sizeof (struct dns_header) - + grub_strlen (name) + 2 + 4); - if (!nb) - { - grub_free (sockets); - grub_free (data.name); - return grub_errno; - } - grub_netbuff_reserve (nb, GRUB_NET_OUR_MAX_IP_HEADER_SIZE - + GRUB_NET_MAX_LINK_HEADER_SIZE - + GRUB_NET_UDP_HEADER_SIZE); - grub_netbuff_put (nb, sizeof (struct dns_header) - + grub_strlen (name) + 2 + 4); - head = (struct dns_header *) nb->data; - optr = (grub_uint8_t *) (head + 1); - for (iptr = name; *iptr; ) - { - const char *dot; - dot = grub_strchr (iptr, '.'); - if (!dot) - dot = iptr + grub_strlen (iptr); - if ((dot - iptr) >= 64) - { - grub_free (sockets); - grub_free (data.name); - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("domain name component is too long")); - } - *optr = (dot - iptr); - optr++; - grub_memcpy (optr, iptr, dot - iptr); - optr += dot - iptr; - iptr = dot; - if (*iptr) - iptr++; - } - *optr++ = 0; - - /* Type. */ - *optr++ = 0; - qtypeptr = optr++; - - /* Class. */ - *optr++ = 0; - *optr++ = 1; - - head->id = data.id; - head->flags = FLAGS_RD; - head->ra_z_r_code = 0; - head->qdcount = grub_cpu_to_be16_compile_time (1); - head->ancount = grub_cpu_to_be16_compile_time (0); - head->nscount = grub_cpu_to_be16_compile_time (0); - head->arcount = grub_cpu_to_be16_compile_time (0); - - nbd = nb->data; - - for (i = 0; i < n_servers * 4; i++) - { - /* Connect to a next server. */ - while (!(i & 1) && try_server < n_servers) - { - sockets[send_servers] = grub_net_udp_open (servers[try_server++], - DNS_PORT, - recv_hook, - &data); - if (!sockets[send_servers]) - { - err = grub_errno; - grub_errno = GRUB_ERR_NONE; - } - else - { - send_servers++; - break; - } - } - if (!send_servers) - goto out; - if (*data.naddresses) - goto out; - for (j = 0; j < send_servers; j++) - { - grub_err_t err2; - - grub_size_t t = 0; - do - { - nb->data = nbd; - if (servers[j].option == DNS_OPTION_IPV4 || - ((servers[j].option == DNS_OPTION_PREFER_IPV4) && (t++ == 0)) || - ((servers[j].option == DNS_OPTION_PREFER_IPV6) && (t++ == 1))) - *qtypeptr = GRUB_DNS_QTYPE_A; - else - *qtypeptr = GRUB_DNS_QTYPE_AAAA; - - grub_dprintf ("dns", "QTYPE: %u QNAME: %s\n", *qtypeptr, name); - - err2 = grub_net_send_udp_packet (sockets[j], nb); - if (err2) - { - grub_errno = GRUB_ERR_NONE; - err = err2; - } - if (*data.naddresses) - goto out; - } - while (t == 1); - } - grub_net_poll_cards (200, &data.stop); - } - out: - grub_free (data.name); - grub_netbuff_free (nb); - for (j = 0; j < send_servers; j++) - grub_net_udp_close (sockets[j]); - - grub_free (sockets); - - if (*data.naddresses) - return GRUB_ERR_NONE; - if (data.dns_err) - return grub_error (GRUB_ERR_NET_NO_DOMAIN, - N_("no DNS record found")); - - if (err) - { - grub_errno = err; - return err; - } - return grub_error (GRUB_ERR_TIMEOUT, - N_("no DNS reply received")); -} - -static grub_err_t -grub_cmd_nslookup (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - grub_err_t err; - struct grub_net_network_level_address cmd_server; - struct grub_net_network_level_address *servers; - grub_size_t nservers, i, naddresses = 0; - struct grub_net_network_level_address *addresses = 0; - if (argc != 2 && argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); - if (argc == 2) - { - err = grub_net_resolve_address (args[1], &cmd_server); - if (err) - return err; - servers = &cmd_server; - nservers = 1; - } - else - { - servers = dns_servers; - nservers = dns_nservers; - } - - grub_net_dns_lookup (args[0], servers, nservers, &naddresses, - &addresses, 0); - - for (i = 0; i < naddresses; i++) - { - char buf[GRUB_NET_MAX_STR_ADDR_LEN]; - grub_net_addr_to_str (&addresses[i], buf); - grub_printf ("%s\n", buf); - } - if (naddresses) - { - grub_free (addresses); - return GRUB_ERR_NONE; - } - return grub_error (GRUB_ERR_NET_NO_DOMAIN, N_("no DNS record found")); -} - -static grub_err_t -grub_cmd_list_dns (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - grub_size_t i; - const char *strtype = ""; - - for (i = 0; i < dns_nservers; i++) - { - switch (dns_servers[i].option) - { - case DNS_OPTION_IPV4: - strtype = _("only ipv4"); - break; - - case DNS_OPTION_IPV6: - strtype = _("only ipv6"); - break; - - case DNS_OPTION_PREFER_IPV4: - strtype = _("prefer ipv4"); - break; - - case DNS_OPTION_PREFER_IPV6: - strtype = _("prefer ipv6"); - break; - } - - char buf[GRUB_NET_MAX_STR_ADDR_LEN]; - grub_net_addr_to_str (&dns_servers[i], buf); - grub_printf ("%s (%s)\n", buf, strtype); - } - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_add_dns (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - grub_err_t err; - struct grub_net_network_level_address server; - - if ((argc < 1) || (argc > 2)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - else if (argc == 1) - server.option = DNS_OPTION_PREFER_IPV4; - else - { - if (grub_strcmp (args[1], "--only-ipv4") == 0) - server.option = DNS_OPTION_IPV4; - else if (grub_strcmp (args[1], "--only-ipv6") == 0) - server.option = DNS_OPTION_IPV6; - else if (grub_strcmp (args[1], "--prefer-ipv4") == 0) - server.option = DNS_OPTION_PREFER_IPV4; - else if (grub_strcmp (args[1], "--prefer-ipv6") == 0) - server.option = DNS_OPTION_PREFER_IPV6; - else - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument")); - } - - err = grub_net_resolve_address (args[0], &server); - if (err) - return err; - - return grub_net_add_dns_server (&server); -} - -static grub_err_t -grub_cmd_del_dns (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - grub_err_t err; - struct grub_net_network_level_address server; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - - err = grub_net_resolve_address (args[0], &server); - if (err) - return err; - - grub_net_remove_dns_server (&server); - - return GRUB_ERR_NONE; -} - -static grub_command_t cmd, cmd_add, cmd_del, cmd_list; - -void -grub_dns_init (void) -{ - cmd = grub_register_command ("net_nslookup", grub_cmd_nslookup, - N_("ADDRESS DNSSERVER"), - N_("Perform a DNS lookup")); - cmd_add = grub_register_command ("net_add_dns", grub_cmd_add_dns, - N_("DNSSERVER"), - N_("Add a DNS server")); - cmd_del = grub_register_command ("net_del_dns", grub_cmd_del_dns, - N_("DNSSERVER"), - N_("Remove a DNS server")); - cmd_list = grub_register_command ("net_ls_dns", grub_cmd_list_dns, - NULL, N_("List DNS servers")); -} - -void -grub_dns_fini (void) -{ - grub_unregister_command (cmd); - grub_unregister_command (cmd_add); - grub_unregister_command (cmd_del); - grub_unregister_command (cmd_list); -} diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c deleted file mode 100644 index 58fe381ab..000000000 --- a/grub-core/net/drivers/efi/efinet.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* GUID. */ -static grub_guid_t net_io_guid = GRUB_EFI_SIMPLE_NETWORK_GUID; -static grub_guid_t pxe_io_guid = GRUB_EFI_PXE_GUID; - -static grub_err_t -send_card_buffer (struct grub_net_card *dev, - struct grub_net_buff *pack) -{ - grub_efi_status_t st; - grub_efi_simple_network_t *net = dev->efi_net; - grub_uint64_t limit_time = grub_get_time_ms () + 4000; - void *txbuf; - - if (net == NULL) - return grub_error (GRUB_ERR_IO, - N_("network protocol not available, can't send packet")); - if (dev->txbusy) - while (1) - { - txbuf = NULL; - st = net->get_status (net, 0, &txbuf); - if (st != GRUB_EFI_SUCCESS) - return grub_error (GRUB_ERR_IO, - N_("couldn't send network packet")); - /* - Some buggy firmware could return an arbitrary address instead of the - txbuf address we trasmitted, so just check that txbuf is non NULL - for success. This is ok because we open the SNP protocol in - exclusive mode so we know we're the only ones transmitting on this - box and since we only transmit one packet at a time we know our - transmit was successfull. - */ - if (txbuf) - { - dev->txbusy = 0; - break; - } - if (limit_time < grub_get_time_ms ()) - return grub_error (GRUB_ERR_TIMEOUT, - N_("couldn't send network packet")); - } - - dev->last_pkt_size = (pack->tail - pack->data); - if (dev->last_pkt_size > dev->mtu) - dev->last_pkt_size = dev->mtu; - - grub_memcpy (dev->txbuf, pack->data, dev->last_pkt_size); - - st = net->transmit (net, 0, dev->last_pkt_size, - dev->txbuf, NULL, NULL, NULL); - if (st != GRUB_EFI_SUCCESS) - return grub_error (GRUB_ERR_IO, N_("couldn't send network packet")); - - /* - The card may have sent out the packet immediately - set txbusy - to 0 in this case. - Cases were observed where checking txbuf at the next call - of send_card_buffer() is too late: 0 is returned in txbuf and - we run in the GRUB_ERR_TIMEOUT case above. - Perhaps a timeout in the FW has discarded the recycle buffer. - */ - txbuf = NULL; - st = net->get_status (net, 0, &txbuf); - dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf); - - return GRUB_ERR_NONE; -} - -static struct grub_net_buff * -get_card_packet (struct grub_net_card *dev) -{ - grub_efi_simple_network_t *net = dev->efi_net; - grub_err_t err; - grub_efi_status_t st; - grub_efi_uintn_t bufsize = dev->rcvbufsize; - struct grub_net_buff *nb; - int i; - - if (net == NULL) - return NULL; - - for (i = 0; i < 2; i++) - { - if (!dev->rcvbuf) - dev->rcvbuf = grub_malloc (dev->rcvbufsize); - if (!dev->rcvbuf) - return NULL; - - st = net->receive (net, NULL, &bufsize, - dev->rcvbuf, NULL, NULL, NULL); - if (st != GRUB_EFI_BUFFER_TOO_SMALL) - break; - dev->rcvbufsize = 2 * ALIGN_UP (dev->rcvbufsize > bufsize - ? dev->rcvbufsize : bufsize, 64); - grub_free (dev->rcvbuf); - dev->rcvbuf = 0; - } - - if (st != GRUB_EFI_SUCCESS) - return NULL; - - nb = grub_netbuff_alloc (bufsize + 2); - if (!nb) - return NULL; - - /* Reserve 2 bytes so that 2 + 14/18 bytes of ethernet header is divisible - by 4. So that IP header is aligned on 4 bytes. */ - if (grub_netbuff_reserve (nb, 2)) - { - grub_netbuff_free (nb); - return NULL; - } - grub_memcpy (nb->data, dev->rcvbuf, bufsize); - err = grub_netbuff_put (nb, bufsize); - if (err) - { - grub_netbuff_free (nb); - return NULL; - } - - return nb; -} - -static grub_err_t -open_card (struct grub_net_card *dev) -{ - grub_efi_simple_network_t *net; - - if (dev->efi_net != NULL) - { - grub_efi_close_protocol (dev->efi_handle, &net_io_guid); - dev->efi_net = NULL; - } - /* - * Try to reopen SNP exlusively to close any active MNP protocol instance - * that may compete for packet polling. - */ - net = grub_efi_open_protocol (dev->efi_handle, &net_io_guid, - GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE); - if (net != NULL) - { - if (net->mode->state == GRUB_EFI_NETWORK_STOPPED - && net->start (net) != GRUB_EFI_SUCCESS) - return grub_error (GRUB_ERR_NET_NO_CARD, "%s: net start failed", - dev->name); - - if (net->mode->state == GRUB_EFI_NETWORK_STOPPED) - return grub_error (GRUB_ERR_NET_NO_CARD, "%s: card stopped", - dev->name); - - if (net->mode->state == GRUB_EFI_NETWORK_STARTED - && net->initialize (net, 0, 0) != GRUB_EFI_SUCCESS) - return grub_error (GRUB_ERR_NET_NO_CARD, "%s: net initialize failed", - dev->name); - - /* Enable hardware receive filters if driver declares support for it. - We need unicast and broadcast and additionaly all nodes and - solicited multicast for IPv6. Solicited multicast is per-IPv6 - address and we currently do not have API to do it so simply - try to enable receive of all multicast packets or evertyhing in - the worst case (i386 PXE driver always enables promiscuous too). - - This does trust firmware to do what it claims to do. - */ - if (net->mode->receive_filter_mask) - { - grub_uint32_t filters = GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST | - GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST | - GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST; - - filters &= net->mode->receive_filter_mask; - if (!(filters & GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST)) - filters |= (net->mode->receive_filter_mask & - GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS); - - net->receive_filters (net, filters, 0, 0, 0, NULL); - } - - dev->efi_net = net; - } else { - return grub_error (GRUB_ERR_NET_NO_CARD, "%s: can't open protocol", - dev->name); - } - - return GRUB_ERR_NONE; -} - -static void -close_card (struct grub_net_card *dev) -{ - dev->efi_net->shutdown (dev->efi_net); - dev->efi_net->stop (dev->efi_net); - grub_efi_close_protocol (dev->efi_handle, &net_io_guid); -} - -static struct grub_net_card_driver efidriver = - { - .name = "efinet", - .open = open_card, - .close = close_card, - .send = send_card_buffer, - .recv = get_card_packet - }; - -grub_efi_handle_t -grub_efinet_get_device_handle (struct grub_net_card *card) -{ - if (!card || card->driver != &efidriver) - return 0; - return card->efi_handle; -} - -static void -grub_efinet_findcards (void) -{ - grub_efi_uintn_t num_handles; - grub_efi_handle_t *handles; - grub_efi_handle_t *handle; - int i = 0; - - /* Find handles which support the disk io interface. */ - handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &net_io_guid, - 0, &num_handles); - if (! handles) - return; - for (handle = handles; num_handles--; handle++) - { - grub_efi_simple_network_t *net; - struct grub_net_card *card; - grub_efi_device_path_t *dp, *parent = NULL, *child = NULL; - - /* EDK2 UEFI PXE driver creates IPv4 and IPv6 messaging devices as - children of main MAC messaging device. We only need one device with - bound SNP per physical card, otherwise they compete with each other - when polling for incoming packets. - */ - dp = grub_efi_get_device_path (*handle); - if (!dp) - continue; - for (; ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp); dp = GRUB_EFI_NEXT_DEVICE_PATH (dp)) - { - parent = child; - child = dp; - } - if (child - && GRUB_EFI_DEVICE_PATH_TYPE (child) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE - && (GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE - || GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE) - && parent - && GRUB_EFI_DEVICE_PATH_TYPE (parent) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE - && (GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE - || GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE)) - continue; - - net = grub_efi_open_protocol (*handle, &net_io_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (! net) - /* This should not happen... Why? */ - continue; - - if (net->mode->state == GRUB_EFI_NETWORK_STOPPED - && net->start (net) != GRUB_EFI_SUCCESS) - continue; - - if (net->mode->state == GRUB_EFI_NETWORK_STOPPED) - continue; - - if (net->mode->state == GRUB_EFI_NETWORK_STARTED - && net->initialize (net, 0, 0) != GRUB_EFI_SUCCESS) - continue; - - card = grub_zalloc (sizeof (struct grub_net_card)); - if (!card) - { - grub_print_error (); - grub_free (handles); - return; - } - - card->mtu = net->mode->max_packet_size; - card->txbufsize = ALIGN_UP (card->mtu, 64) + 256; - card->txbuf = grub_zalloc (card->txbufsize); - if (!card->txbuf) - { - grub_print_error (); - grub_free (handles); - grub_free (card); - return; - } - card->txbusy = 0; - - card->rcvbufsize = ALIGN_UP (card->mtu, 64) + 256; - - card->name = grub_xasprintf ("efinet%d", i++); - card->driver = &efidriver; - /* - * EFI network devices are abstract SNP protocol instances, and the - * firmware is in charge of ensuring that they will be torn down when the - * OS loader hands off to the OS proper. Closing them as part of the - * preboot cleanup is therefore unnecessary, and undesirable, as it - * prevents us from using the network connection in a protocal callback - * such as LoadFile2 for initrd loading. - */ - card->flags = GRUB_NET_CARD_NO_CLOSE_ON_FINI_HW; - card->default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - grub_memcpy (card->default_address.mac, - net->mode->current_address, - sizeof (card->default_address.mac)); - card->efi_net = net; - card->efi_handle = *handle; - - grub_net_card_register (card); - } - grub_free (handles); -} - -static void -grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - char **path) -{ - struct grub_net_card *card; - grub_efi_device_path_t *dp; - struct grub_net_network_level_interface *inter; - grub_efi_device_path_t *vlan_dp; - grub_efi_uint16_t vlan_dp_len; - grub_efi_vlan_device_path_t *vlan; - - dp = grub_efi_get_device_path (hnd); - if (! dp) - return; - - FOR_NET_CARDS (card) - { - grub_efi_device_path_t *cdp; - struct grub_efi_pxe *pxe; - struct grub_efi_pxe_mode *pxe_mode; - if (card->driver != &efidriver) - continue; - cdp = grub_efi_get_device_path (card->efi_handle); - if (! cdp) - continue; - if (grub_efi_compare_device_paths (dp, cdp) != 0) - { - grub_efi_device_path_t *ldp, *dup_dp, *dup_ldp; - int match; - - /* EDK2 UEFI PXE driver creates pseudo devices with type IPv4/IPv6 - as children of Ethernet card and binds PXE and Load File protocols - to it. Loaded Image Device Path protocol will point to these pseudo - devices. We skip them when enumerating cards, so here we need to - find matching MAC device. - */ - ldp = grub_efi_find_last_device_path (dp); - if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE - || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE - && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)) - continue; - dup_dp = grub_efi_duplicate_device_path (dp); - if (!dup_dp) - continue; - dup_ldp = grub_efi_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 = sizeof (*dup_ldp); - - dup_ldp = grub_efi_find_last_device_path (dup_dp); - if (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE) - { - dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; - dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; - dup_ldp->length = sizeof (*dup_ldp); - } - - match = grub_efi_compare_device_paths (dup_dp, cdp) == 0; - grub_free (dup_dp); - if (!match) - continue; - } - pxe = grub_efi_open_protocol (hnd, &pxe_io_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (! pxe) - continue; - pxe_mode = pxe->mode; - - inter = grub_net_configure_by_dhcp_ack (card->name, card, 0, - (struct grub_net_bootp_packet *) - &pxe_mode->dhcp_ack, - sizeof (pxe_mode->dhcp_ack), - 1, device, path); - - if (inter != NULL) - { - /* - * Search the device path for any VLAN subtype and use it - * to configure the interface. - */ - vlan_dp = dp; - - while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (vlan_dp)) - { - if (GRUB_EFI_DEVICE_PATH_TYPE (vlan_dp) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE && - GRUB_EFI_DEVICE_PATH_SUBTYPE (vlan_dp) == GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE) - { - vlan = (grub_efi_vlan_device_path_t *) vlan_dp; - inter->vlantag = vlan->vlan_id; - break; - } - - vlan_dp_len = GRUB_EFI_DEVICE_PATH_LENGTH (vlan_dp); - vlan_dp = (grub_efi_device_path_t *) ((grub_efi_uint8_t *) vlan_dp + vlan_dp_len); - } - } - return; - } -} - -GRUB_MOD_INIT(efinet) -{ - grub_efinet_findcards (); - grub_efi_net_config = grub_efi_net_config_real; -} - -GRUB_MOD_FINI(efinet) -{ - struct grub_net_card *card, *next; - - FOR_NET_CARDS_SAFE (card, next) - if (card->driver == &efidriver) - grub_net_card_unregister (card); -} - diff --git a/grub-core/net/drivers/emu/emunet.c b/grub-core/net/drivers/emu/emunet.c deleted file mode 100644 index 5f311d40f..000000000 --- a/grub-core/net/drivers/emu/emunet.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -send_card_buffer (struct grub_net_card *dev __attribute__ ((unused)), - struct grub_net_buff *pack); - -static struct grub_net_buff * -get_card_packet (struct grub_net_card *dev __attribute__ ((unused))); - -static struct grub_net_card_driver emudriver = - { - .name = "emu", - .send = send_card_buffer, - .recv = get_card_packet - }; - -static struct grub_net_card emucard = - { - .name = "emu0", - .driver = &emudriver, - .mtu = 1500, - .default_address = { - .type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET, - {.mac = {0, 1, 2, 3, 4, 5}} - }, - .flags = 0 - }; - -static grub_err_t -send_card_buffer (struct grub_net_card *dev __attribute__ ((unused)), - struct grub_net_buff *pack) -{ - grub_ssize_t actual; - - actual = grub_emunet_send (pack->data, pack->tail - pack->data); - if (actual < 0) - return grub_error (GRUB_ERR_IO, N_("couldn't send network packet")); - - return GRUB_ERR_NONE; -} - -static struct grub_net_buff * -get_card_packet (struct grub_net_card *dev __attribute__ ((unused))) -{ - grub_ssize_t actual; - struct grub_net_buff *nb; - - nb = grub_netbuff_alloc (emucard.mtu + 36 + 2); - if (!nb) - return NULL; - - /* Reserve 2 bytes so that 2 + 14/18 bytes of ethernet header is divisible - by 4. So that IP header is aligned on 4 bytes. */ - grub_netbuff_reserve (nb, 2); - if (!nb) - { - grub_netbuff_free (nb); - return NULL; - } - - actual = grub_emunet_receive (nb->data, emucard.mtu + 36); - if (actual < 0) - { - grub_netbuff_free (nb); - return NULL; - } - grub_netbuff_put (nb, actual); - - return nb; -} - -static int registered = 0; - -GRUB_MOD_INIT(emunet) -{ - if (!grub_emunet_create (&emucard.mtu)) - { - grub_net_card_register (&emucard); - registered = 1; - } -} - -GRUB_MOD_FINI(emunet) -{ - if (registered) - { - grub_emunet_close (); - grub_net_card_unregister (&emucard); - registered = 0; - } -} diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c deleted file mode 100644 index db17186ee..000000000 --- a/grub-core/net/drivers/i386/pc/pxe.c +++ /dev/null @@ -1,419 +0,0 @@ -/* pxe.c - Driver to provide access to the pxe filesystem */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008,2009,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#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_undi_open -{ - grub_uint16_t status; - grub_uint16_t open_flag; - grub_uint16_t pkt_filter; - grub_uint16_t mcast_count; - grub_uint8_t mcast[8][6]; -} GRUB_PACKED; - -struct grub_pxe_undi_info -{ - grub_uint16_t status; - grub_uint16_t base_io; - grub_uint16_t int_number; - grub_uint16_t mtu; - grub_uint16_t hwtype; - grub_uint16_t hwaddrlen; - grub_uint8_t current_addr[16]; - grub_uint8_t permanent_addr[16]; - grub_uint32_t romaddr; - grub_uint16_t rxbufct; - grub_uint16_t txbufct; -} GRUB_PACKED; - - -struct grub_pxe_undi_isr -{ - grub_uint16_t status; - grub_uint16_t func_flag; - grub_uint16_t buffer_len; - grub_uint16_t frame_len; - grub_uint16_t frame_hdr_len; - grub_uint32_t buffer; - grub_uint8_t prot_type; - grub_uint8_t pkt_type; -} GRUB_PACKED; - -enum - { - GRUB_PXE_ISR_IN_START = 1, - GRUB_PXE_ISR_IN_PROCESS, - GRUB_PXE_ISR_IN_GET_NEXT - }; - -enum - { - GRUB_PXE_ISR_OUT_OURS = 0, - GRUB_PXE_ISR_OUT_NOT_OURS = 1 - }; - -enum - { - GRUB_PXE_ISR_OUT_DONE = 0, - GRUB_PXE_ISR_OUT_TRANSMIT = 2, - GRUB_PXE_ISR_OUT_RECEIVE = 3, - GRUB_PXE_ISR_OUT_BUSY = 4, - }; - -struct grub_pxe_undi_transmit -{ - grub_uint16_t status; - grub_uint8_t protocol; - grub_uint8_t xmitflag; - grub_uint32_t dest; - grub_uint32_t tbd; - grub_uint32_t reserved[2]; -} GRUB_PACKED; - -struct grub_pxe_undi_tbd -{ - grub_uint16_t len; - grub_uint32_t buf; - grub_uint16_t blk_count; - struct - { - grub_uint8_t ptr_type; - grub_uint8_t reserved; - grub_uint16_t len; - grub_uint32_t ptr; - } blocks[8]; -} GRUB_PACKED; - -struct grub_pxe_bangpxe *grub_pxe_pxenv; -static grub_uint32_t pxe_rm_entry = 0; - -static struct grub_pxe_bangpxe * -grub_pxe_scan (void) -{ - struct grub_bios_int_registers regs; - struct grub_pxenv *pxenv; - struct grub_pxe_bangpxe *bangpxe; - - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - - regs.ebx = 0; - regs.ecx = 0; - regs.eax = 0x5650; - regs.es = 0; - - grub_bios_interrupt (0x1a, ®s); - - if ((regs.eax & 0xffff) != 0x564e) - return NULL; - - pxenv = (struct grub_pxenv *) ((regs.es << 4) + (regs.ebx & 0xffff)); - if (grub_memcmp (pxenv->signature, GRUB_PXE_SIGNATURE, - sizeof (pxenv->signature)) - != 0) - return NULL; - - if (pxenv->version < 0x201) - return NULL; - - bangpxe = (void *) ((((pxenv->pxe_ptr & 0xffff0000) >> 16) << 4) - + (pxenv->pxe_ptr & 0xffff)); - - if (!bangpxe) - return NULL; - - if (grub_memcmp (bangpxe->signature, GRUB_PXE_BANGPXE_SIGNATURE, - sizeof (bangpxe->signature)) != 0) - return NULL; - - pxe_rm_entry = bangpxe->rm_entry; - - return bangpxe; -} - -static struct grub_net_buff * -grub_pxe_recv (struct grub_net_card *dev __attribute__ ((unused))) -{ - struct grub_pxe_undi_isr *isr; - static int in_progress = 0; - grub_uint8_t *ptr, *end; - struct grub_net_buff *buf; - - isr = (void *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); - - if (!in_progress) - { - grub_memset (isr, 0, sizeof (*isr)); - isr->func_flag = GRUB_PXE_ISR_IN_START; - grub_pxe_call (GRUB_PXENV_UNDI_ISR, isr, pxe_rm_entry); - /* Normally according to the specification we should also check - that isr->func_flag != GRUB_PXE_ISR_OUT_OURS but unfortunately it - breaks on intel cards. - */ - if (isr->status) - { - in_progress = 0; - return NULL; - } - grub_memset (isr, 0, sizeof (*isr)); - isr->func_flag = GRUB_PXE_ISR_IN_PROCESS; - grub_pxe_call (GRUB_PXENV_UNDI_ISR, isr, pxe_rm_entry); - } - else - { - grub_memset (isr, 0, sizeof (*isr)); - isr->func_flag = GRUB_PXE_ISR_IN_GET_NEXT; - grub_pxe_call (GRUB_PXENV_UNDI_ISR, isr, pxe_rm_entry); - } - - while (isr->func_flag != GRUB_PXE_ISR_OUT_RECEIVE) - { - if (isr->status || isr->func_flag == GRUB_PXE_ISR_OUT_DONE) - { - in_progress = 0; - return NULL; - } - grub_memset (isr, 0, sizeof (*isr)); - isr->func_flag = GRUB_PXE_ISR_IN_GET_NEXT; - grub_pxe_call (GRUB_PXENV_UNDI_ISR, isr, pxe_rm_entry); - } - - buf = grub_netbuff_alloc (isr->frame_len + 2); - if (!buf) - return NULL; - /* Reserve 2 bytes so that 2 + 14/18 bytes of ethernet header is divisible - by 4. So that IP header is aligned on 4 bytes. */ - if (grub_netbuff_reserve (buf, 2)) - { - grub_netbuff_free (buf); - return NULL; - } - ptr = buf->data; - end = ptr + isr->frame_len; - grub_netbuff_put (buf, isr->frame_len); - grub_memcpy (ptr, LINEAR (isr->buffer), isr->buffer_len); - ptr += isr->buffer_len; - while (ptr < end) - { - grub_memset (isr, 0, sizeof (*isr)); - isr->func_flag = GRUB_PXE_ISR_IN_GET_NEXT; - grub_pxe_call (GRUB_PXENV_UNDI_ISR, isr, pxe_rm_entry); - if (isr->status || isr->func_flag != GRUB_PXE_ISR_OUT_RECEIVE) - { - in_progress = 1; - grub_netbuff_free (buf); - return NULL; - } - - grub_memcpy (ptr, LINEAR (isr->buffer), isr->buffer_len); - ptr += isr->buffer_len; - } - in_progress = 1; - - return buf; -} - -static grub_err_t -grub_pxe_send (struct grub_net_card *dev __attribute__ ((unused)), - struct grub_net_buff *pack) -{ - struct grub_pxe_undi_transmit *trans; - struct grub_pxe_undi_tbd *tbd; - char *buf; - - trans = (void *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); - grub_memset (trans, 0, sizeof (*trans)); - tbd = (void *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 128); - grub_memset (tbd, 0, sizeof (*tbd)); - buf = (void *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 256); - grub_memcpy (buf, pack->data, pack->tail - pack->data); - - trans->tbd = SEGOFS ((grub_addr_t) tbd); - trans->protocol = 0; - tbd->len = pack->tail - pack->data; - tbd->buf = SEGOFS ((grub_addr_t) buf); - - grub_pxe_call (GRUB_PXENV_UNDI_TRANSMIT, trans, pxe_rm_entry); - if (trans->status) - return grub_error (GRUB_ERR_IO, N_("couldn't send network packet")); - return 0; -} - -static void -grub_pxe_close (struct grub_net_card *dev __attribute__ ((unused))) -{ - if (pxe_rm_entry) - grub_pxe_call (GRUB_PXENV_UNDI_CLOSE, - (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, - pxe_rm_entry); -} - -static grub_err_t -grub_pxe_open (struct grub_net_card *dev __attribute__ ((unused))) -{ - struct grub_pxe_undi_open *ou; - ou = (void *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); - grub_memset (ou, 0, sizeof (*ou)); - ou->pkt_filter = 4; - grub_pxe_call (GRUB_PXENV_UNDI_OPEN, ou, pxe_rm_entry); - - if (ou->status) - return grub_error (GRUB_ERR_IO, "can't open UNDI"); - return GRUB_ERR_NONE; -} - -struct grub_net_card_driver grub_pxe_card_driver = -{ - .open = grub_pxe_open, - .close = grub_pxe_close, - .send = grub_pxe_send, - .recv = grub_pxe_recv -}; - -struct grub_net_card grub_pxe_card = -{ - .driver = &grub_pxe_card_driver, - .name = "pxe" -}; - -static grub_err_t -grub_pxe_shutdown (int flags) -{ - if (flags & GRUB_LOADER_FLAG_PXE_NOT_UNLOAD) - return GRUB_ERR_NONE; - if (!pxe_rm_entry) - return GRUB_ERR_NONE; - - grub_pxe_call (GRUB_PXENV_UNDI_CLOSE, - (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, - pxe_rm_entry); - grub_pxe_call (GRUB_PXENV_UNDI_SHUTDOWN, - (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, - pxe_rm_entry); - grub_pxe_call (GRUB_PXENV_UNLOAD_STACK, - (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, - pxe_rm_entry); - pxe_rm_entry = 0; - grub_net_card_unregister (&grub_pxe_card); - - return GRUB_ERR_NONE; -} - -/* Nothing we can do. */ -static grub_err_t -grub_pxe_restore (void) -{ - return GRUB_ERR_NONE; -} - -void * -grub_pxe_get_cached (grub_uint16_t type) -{ - struct grub_pxenv_get_cached_info ci; - ci.packet_type = type; - ci.buffer = 0; - ci.buffer_size = 0; - grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci, pxe_rm_entry); - if (ci.status) - return 0; - - return LINEAR (ci.buffer); -} - -static void -grub_pc_net_config_real (char **device, char **path) -{ - struct grub_net_bootp_packet *bp; - - bp = grub_pxe_get_cached (GRUB_PXENV_PACKET_TYPE_DHCP_ACK); - - if (!bp) - return; - grub_net_configure_by_dhcp_ack ("pxe", &grub_pxe_card, 0, - bp, GRUB_PXE_BOOTP_SIZE, - 1, device, path); - -} - -static struct grub_preboot *fini_hnd; - -GRUB_MOD_INIT(pxe) -{ - struct grub_pxe_bangpxe *pxenv; - struct grub_pxe_undi_info *ui; - unsigned i; - - pxenv = grub_pxe_scan (); - if (! pxenv) - return; - - ui = (void *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); - grub_memset (ui, 0, sizeof (*ui)); - grub_pxe_call (GRUB_PXENV_UNDI_GET_INFORMATION, ui, pxe_rm_entry); - - grub_memcpy (grub_pxe_card.default_address.mac, ui->current_addr, - sizeof (grub_pxe_card.default_address.mac)); - for (i = 0; i < sizeof (grub_pxe_card.default_address.mac); i++) - if (grub_pxe_card.default_address.mac[i] != 0) - break; - if (i != sizeof (grub_pxe_card.default_address.mac)) - { - for (i = 0; i < sizeof (grub_pxe_card.default_address.mac); i++) - if (grub_pxe_card.default_address.mac[i] != 0xff) - break; - } - if (i == sizeof (grub_pxe_card.default_address.mac)) - grub_memcpy (grub_pxe_card.default_address.mac, ui->permanent_addr, - sizeof (grub_pxe_card.default_address.mac)); - grub_pxe_card.mtu = ui->mtu; - - grub_pxe_card.default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - - grub_net_card_register (&grub_pxe_card); - grub_pc_net_config = grub_pc_net_config_real; - fini_hnd = grub_loader_register_preboot_hook (grub_pxe_shutdown, - grub_pxe_restore, - GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); -} - -GRUB_MOD_FINI(pxe) -{ - grub_pc_net_config = 0; - grub_pxe_shutdown (0); - grub_loader_unregister_preboot_hook (fini_hnd); -} diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c deleted file mode 100644 index e5be362a9..000000000 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ /dev/null @@ -1,567 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct grub_ofnetcard_data -{ - char *path; - char *suffix; - grub_ieee1275_ihandle_t handle; -}; - -static grub_err_t -card_open (struct grub_net_card *dev) -{ - int status; - struct grub_ofnetcard_data *data = dev->data; - - status = grub_ieee1275_open (data->path, &(data->handle)); - - if (status) - return grub_error (GRUB_ERR_IO, "Couldn't open network card."); - - return GRUB_ERR_NONE; -} - -static void -card_close (struct grub_net_card *dev) -{ - struct grub_ofnetcard_data *data = dev->data; - - if (data->handle) - grub_ieee1275_close (data->handle); -} - -static grub_err_t -send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) -{ - grub_ssize_t actual; - int status; - struct grub_ofnetcard_data *data = dev->data; - grub_size_t len; - - len = (pack->tail - pack->data); - if (len > dev->mtu) - len = dev->mtu; - - grub_memcpy (dev->txbuf, pack->data, len); - status = grub_ieee1275_write (data->handle, dev->txbuf, - len, &actual); - - if (status) - return grub_error (GRUB_ERR_IO, N_("couldn't send network packet")); - return GRUB_ERR_NONE; -} - -static struct grub_net_buff * -get_card_packet (struct grub_net_card *dev) -{ - grub_ssize_t actual; - int rc; - struct grub_ofnetcard_data *data = dev->data; - struct grub_net_buff *nb; - - rc = grub_ieee1275_read (data->handle, dev->rcvbuf, dev->rcvbufsize, &actual); - - if (actual <= 0 || rc < 0) - return NULL; - - nb = grub_netbuff_alloc (actual + 2); - if (!nb) - return NULL; - /* Reserve 2 bytes so that 2 + 14/18 bytes of ethernet header is divisible - by 4. So that IP header is aligned on 4 bytes. */ - grub_netbuff_reserve (nb, 2); - - grub_memcpy (nb->data, dev->rcvbuf, actual); - - if (grub_netbuff_put (nb, actual)) - { - grub_netbuff_free (nb); - return NULL; - } - - return nb; -} - -static struct grub_net_card_driver ofdriver = - { - .name = "ofnet", - .open = card_open, - .close = card_close, - .send = send_card_buffer, - .recv = get_card_packet - }; - -static const struct -{ - const char *name; - int offset; -} - -bootp_response_properties[] = - { - { .name = "bootp-response", .offset = 0}, - { .name = "dhcp-response", .offset = 0}, - { .name = "bootpreply-packet", .offset = 0x2a}, - }; - -enum -{ - BOOTARGS_SERVER_ADDR, - BOOTARGS_FILENAME, - BOOTARGS_CLIENT_ADDR, - BOOTARGS_GATEWAY_ADDR, - BOOTARGS_BOOTP_RETRIES, - BOOTARGS_TFTP_RETRIES, - BOOTARGS_SUBNET_MASK, - BOOTARGS_BLOCKSIZE -}; - -static int -grub_ieee1275_parse_bootpath (const char *devpath, char *bootpath, - char **device, struct grub_net_card **card) -{ - char *args; - char *comma_char = 0; - char *equal_char = 0; - grub_size_t field_counter = 0; - grub_net_network_level_address_t client_addr = {0, {0}, 0}, gateway_addr = {0, {0}, 0}, subnet_mask = {0, {0}, 0}; - grub_net_link_level_address_t hw_addr = {0, {{0, 0, 0, 0, 0, 0}}}; - grub_net_interface_flags_t flags = 0; - struct grub_net_network_level_interface *inter = NULL; - grub_uint16_t vlantag = 0; - - hw_addr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - - args = bootpath + grub_strlen (devpath) + 1; - do - { - comma_char = grub_strchr (args, ','); - if (comma_char != 0) - *comma_char = 0; - - /* Check if it's an option (like speed=auto) and not a default parameter */ - equal_char = grub_strchr (args, '='); - if (equal_char != 0) - { - *equal_char = 0; - grub_env_set_net_property ((*card)->name, args, equal_char + 1, - grub_strlen(equal_char + 1)); - - if ((grub_strcmp (args, "vtag") == 0) && - (grub_strlen (equal_char + 1) == 8)) - vlantag = grub_strtoul (equal_char + 1 + 4, 0, 16); - - *equal_char = '='; - } - else - { - switch (field_counter++) - { - case BOOTARGS_SERVER_ADDR: - *device = grub_xasprintf ("tftp,%s", args); - if (!*device) - return grub_errno; - break; - - case BOOTARGS_CLIENT_ADDR: - grub_net_resolve_address (args, &client_addr); - break; - - case BOOTARGS_GATEWAY_ADDR: - grub_net_resolve_address (args, &gateway_addr); - break; - - case BOOTARGS_SUBNET_MASK: - grub_net_resolve_address (args, &subnet_mask); - break; - } - } - args = comma_char + 1; - if (comma_char != 0) - *comma_char = ','; - } while (comma_char != 0); - - if ((client_addr.ipv4 != 0) && (subnet_mask.ipv4 != 0)) - { - grub_ieee1275_phandle_t devhandle; - grub_ieee1275_finddevice (devpath, &devhandle); - grub_ieee1275_get_property (devhandle, "mac-address", - hw_addr.mac, sizeof(hw_addr.mac), 0); - inter = grub_net_add_addr ((*card)->name, *card, &client_addr, &hw_addr, - flags); - inter->vlantag = vlantag; - grub_net_add_ipv4_local (inter, - __builtin_clz (~grub_be_to_cpu32 (subnet_mask.ipv4))); - } - - if (gateway_addr.ipv4 != 0) - { - grub_net_network_level_netaddress_t target; - char *rname; - - target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - target.ipv4.base = 0; - target.ipv4.masksize = 0; - rname = grub_xasprintf ("%s:default", ((*card)->name)); - if (rname) - grub_net_add_route_gw (rname, target, gateway_addr, inter); - else - return grub_errno; - } - - return 0; -} - -static void -grub_ieee1275_net_config_real (const char *devpath, char **device, char **path, - char *bootpath) -{ - struct grub_net_card *card; - - /* FIXME: Check that it's the right card. */ - FOR_NET_CARDS (card) - { - char *bootp_response; - char *canon; - char c; - struct grub_ofnetcard_data *data; - - grub_ssize_t size = -1; - unsigned int i; - - if (card->driver != &ofdriver) - continue; - - data = card->data; - c = *data->suffix; - *data->suffix = '\0'; - canon = grub_ieee1275_canonicalise_devname (data->path); - *data->suffix = c; - if (grub_strcmp (devpath, canon) != 0) - { - grub_free (canon); - continue; - } - grub_free (canon); - - grub_ieee1275_parse_bootpath (devpath, bootpath, device, &card); - - for (i = 0; i < ARRAY_SIZE (bootp_response_properties); i++) - if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, - bootp_response_properties[i].name, - &size) >= 0) - break; - - if (size < 0) - return; - - bootp_response = grub_malloc (size); - if (!bootp_response) - { - grub_print_error (); - return; - } - if (grub_ieee1275_get_property (grub_ieee1275_chosen, - bootp_response_properties[i].name, - bootp_response, size, 0) < 0) - return; - - grub_net_configure_by_dhcp_ack (card->name, card, 0, - (struct grub_net_bootp_packet *) - (bootp_response - + bootp_response_properties[i].offset), - size - bootp_response_properties[i].offset, - 1, device, path); - grub_free (bootp_response); - return; - } -} - -/* Allocate memory with alloc-mem */ -static void * -grub_ieee1275_alloc_mem (grub_size_t len) -{ - struct alloc_args - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t method; - grub_ieee1275_cell_t len; - grub_ieee1275_cell_t catch; - grub_ieee1275_cell_t result; - } - args; - - INIT_IEEE1275_COMMON (&args.common, "interpret", 2, 2); - args.len = len; - args.method = (grub_ieee1275_cell_t) "alloc-mem"; - - if (IEEE1275_CALL_ENTRY_FN (&args) == -1 || args.catch) - { - grub_error (GRUB_ERR_INVALID_COMMAND, N_("alloc-mem failed")); - return NULL; - } - else - return (void *)args.result; -} - -/* Free memory allocated by alloc-mem */ -static grub_err_t -grub_ieee1275_free_mem (void *addr, grub_size_t len) -{ - struct free_args - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t method; - grub_ieee1275_cell_t len; - grub_ieee1275_cell_t addr; - grub_ieee1275_cell_t catch; - } - args; - - INIT_IEEE1275_COMMON (&args.common, "interpret", 3, 1); - args.addr = (grub_ieee1275_cell_t)addr; - args.len = len; - args.method = (grub_ieee1275_cell_t) "free-mem"; - - if (IEEE1275_CALL_ENTRY_FN(&args) == -1 || args.catch) - { - grub_error (GRUB_ERR_INVALID_COMMAND, N_("free-mem failed")); - return grub_errno; - } - - return GRUB_ERR_NONE; -} - -static void * -ofnet_alloc_netbuf (grub_size_t len) -{ - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN)) - return grub_ieee1275_alloc_mem (len); - else - return grub_zalloc (len); -} - -static void -ofnet_free_netbuf (void *addr, grub_size_t len) -{ - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN)) - grub_ieee1275_free_mem (addr, len); - else - grub_free (addr); -} - -static int -search_net_devices (struct grub_ieee1275_devalias *alias) -{ - struct grub_ofnetcard_data *ofdata; - struct grub_net_card *card; - grub_ieee1275_phandle_t devhandle; - grub_net_link_level_address_t lla; - grub_ssize_t prop_size; - grub_uint64_t prop; - grub_uint8_t *pprop; - char *shortname; - char need_suffix = 1; - grub_size_t sz; - - if (grub_strcmp (alias->type, "network") != 0) - return 0; - - ofdata = grub_malloc (sizeof (struct grub_ofnetcard_data)); - if (!ofdata) - { - grub_print_error (); - return 1; - } - card = grub_zalloc (sizeof (struct grub_net_card)); - if (!card) - { - grub_free (ofdata); - grub_print_error (); - return 1; - } - -#define SUFFIX ":speed=auto,duplex=auto,1.1.1.1,dummy,1.1.1.1,1.1.1.1,5,5,1.1.1.1,512" - - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_OFNET_SUFFIX)) - need_suffix = 0; - - /* sun4v vnet devices do not support setting duplex/speed */ - { - char *ptr; - - grub_ieee1275_finddevice (alias->path, &devhandle); - - grub_ieee1275_get_property_length (devhandle, "compatible", &prop_size); - if (prop_size > 0) - { - pprop = grub_malloc (prop_size); - if (!pprop) - { - grub_free (card); - grub_free (ofdata); - grub_print_error (); - return 1; - } - - if (!grub_ieee1275_get_property (devhandle, "compatible", - pprop, prop_size, NULL)) - { - for (ptr = (char *) pprop; ptr - (char *) pprop < prop_size; - ptr += grub_strlen (ptr) + 1) - { - if (!grub_strcmp(ptr, "SUNW,sun4v-network")) - need_suffix = 0; - } - } - - grub_free (pprop); - } - } - - if (need_suffix) - { - if (grub_add (grub_strlen (alias->path), sizeof (SUFFIX), &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obatining size of ofdata path")); - grub_print_error (); - return 0; - } - } - else - { - if (grub_add (grub_strlen (alias->path), 1, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obatining size of ofdata path")); - grub_print_error (); - return 0; - } - } - - ofdata->path = grub_malloc (sz); - - if (!ofdata->path) - { - grub_print_error (); - return 0; - } - ofdata->suffix = grub_stpcpy (ofdata->path, alias->path); - if (need_suffix) - grub_memcpy (ofdata->suffix, SUFFIX, sizeof (SUFFIX)); - else - *ofdata->suffix = '\0'; - - grub_ieee1275_finddevice (ofdata->path, &devhandle); - - { - grub_uint32_t t; - if (grub_ieee1275_get_integer_property (devhandle, - "max-frame-size", &t, - sizeof (t), 0)) - card->mtu = 1500; - else - card->mtu = t; - } - - pprop = (grub_uint8_t *) ∝ - if (grub_ieee1275_get_property (devhandle, "mac-address", - pprop, sizeof(prop), &prop_size) - && grub_ieee1275_get_property (devhandle, "local-mac-address", - pprop, sizeof(prop), &prop_size)) - { - grub_error (GRUB_ERR_IO, "Couldn't retrieve mac address."); - grub_print_error (); - return 0; - } - - if (prop_size == 8) - grub_memcpy (&lla.mac, pprop+2, 6); - else - grub_memcpy (&lla.mac, pprop, 6); - - lla.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - card->default_address = lla; - - card->txbufsize = ALIGN_UP (card->mtu, 64) + 256; - card->rcvbufsize = ALIGN_UP (card->mtu, 64) + 256; - - card->txbuf = ofnet_alloc_netbuf (card->txbufsize); - if (!card->txbuf) - goto fail_netbuf; - - card->rcvbuf = ofnet_alloc_netbuf (card->rcvbufsize); - if (!card->rcvbuf) - { - grub_error_push (); - ofnet_free_netbuf (card->txbuf, card->txbufsize); - grub_error_pop (); - goto fail_netbuf; - } - card->driver = NULL; - card->data = ofdata; - card->flags = 0; - shortname = grub_ieee1275_get_devname (alias->path); - card->name = grub_xasprintf ("ofnet_%s", shortname ? : alias->path); - card->idle_poll_delay_ms = 10; - grub_free (shortname); - - card->driver = &ofdriver; - grub_net_card_register (card); - return 0; - -fail_netbuf: - grub_free (ofdata->path); - grub_free (ofdata); - grub_free (card); - grub_print_error (); - return 0; -} - -static void -grub_ofnet_findcards (void) -{ - /* Look at all nodes for devices of the type network. */ - grub_ieee1275_devices_iterate (search_net_devices); -} - -GRUB_MOD_INIT(ofnet) -{ - grub_ofnet_findcards (); - grub_ieee1275_net_config = grub_ieee1275_net_config_real; -} - -GRUB_MOD_FINI(ofnet) -{ - struct grub_net_card *card, *next; - - FOR_NET_CARDS_SAFE (card, next) - if (card->driver && grub_strcmp (card->driver->name, "ofnet") == 0) - grub_net_card_unregister (card); - grub_ieee1275_net_config = 0; -} diff --git a/grub-core/net/drivers/uboot/ubootnet.c b/grub-core/net/drivers/uboot/ubootnet.c deleted file mode 100644 index b9d5a0cd4..000000000 --- a/grub-core/net/drivers/uboot/ubootnet.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -card_open (struct grub_net_card *dev) -{ - int status; - - status = grub_uboot_dev_open (dev->data); - if (status) - return grub_error (GRUB_ERR_IO, "Couldn't open network card."); - - return GRUB_ERR_NONE; -} - -static void -card_close (struct grub_net_card *dev) -{ - grub_uboot_dev_close (dev->data); -} - -static grub_err_t -send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) -{ - int status; - grub_size_t len; - - len = (pack->tail - pack->data); - if (len > dev->mtu) - len = dev->mtu; - - grub_memcpy (dev->txbuf, pack->data, len); - status = grub_uboot_dev_send (dev->data, dev->txbuf, len); - - if (status) - return grub_error (GRUB_ERR_IO, N_("couldn't send network packet")); - return GRUB_ERR_NONE; -} - -static struct grub_net_buff * -get_card_packet (struct grub_net_card *dev) -{ - int rc; - grub_uint64_t start_time; - struct grub_net_buff *nb; - int actual; - - nb = grub_netbuff_alloc (dev->mtu + 64 + 2); - if (!nb) - return NULL; - /* Reserve 2 bytes so that 2 + 14/18 bytes of ethernet header is divisible - by 4. So that IP header is aligned on 4 bytes. */ - grub_netbuff_reserve (nb, 2); - - start_time = grub_get_time_ms (); - do - { - rc = grub_uboot_dev_recv (dev->data, nb->data, dev->mtu + 64, &actual); - grub_dprintf ("net", "rc=%d, actual=%d, time=%lld\n", rc, actual, - grub_get_time_ms () - start_time); - } - while ((actual <= 0 || rc < 0) && (grub_get_time_ms () - start_time < 200)); - if (actual > 0) - { - grub_netbuff_put (nb, actual); - return nb; - } - grub_netbuff_free (nb); - return NULL; -} - -static struct grub_net_card_driver ubootnet = - { - .name = "ubnet", - .open = card_open, - .close = card_close, - .send = send_card_buffer, - .recv = get_card_packet - }; - -GRUB_MOD_INIT (ubootnet) -{ - int devcount, i; - int nfound = 0; - - devcount = grub_uboot_dev_enum (); - - for (i = 0; i < devcount; i++) - { - struct device_info *devinfo = grub_uboot_dev_get (i); - struct grub_net_card *card; - - if (!(devinfo->type & DEV_TYP_NET)) - continue; - - card = grub_zalloc (sizeof (struct grub_net_card)); - if (!card) - { - grub_print_error (); - return; - } - - /* FIXME: Any way to check this? */ - card->mtu = 1500; - - grub_memcpy (&(card->default_address.mac), &devinfo->di_net.hwaddr, 6); - card->default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - - card->txbufsize = ALIGN_UP (card->mtu, 64) + 256; - card->txbuf = grub_zalloc (card->txbufsize); - if (!card->txbuf) - { - grub_free (card); - grub_print_error (); - continue; - } - - card->data = devinfo; - card->flags = 0; - card->name = grub_xasprintf ("ubnet_%d", ++nfound); - card->idle_poll_delay_ms = 10; - - card->driver = &ubootnet; - grub_net_card_register (card); - } -} - -GRUB_MOD_FINI (ubootnet) -{ - struct grub_net_card *card, *next; - - FOR_NET_CARDS_SAFE (card, next) - if (card->driver && grub_strcmp (card->driver->name, "ubnet") == 0) - grub_net_card_unregister (card); -} diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c deleted file mode 100644 index 707bbb12c..000000000 --- a/grub-core/net/ethernet.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LLCADDRMASK 0x7f - -struct etherhdr -{ - grub_uint8_t dst[6]; - grub_uint8_t src[6]; - grub_uint16_t type; -} GRUB_PACKED; - -struct llchdr -{ - grub_uint8_t dsap; - grub_uint8_t ssap; - grub_uint8_t ctrl; -} GRUB_PACKED; - -struct snaphdr -{ - grub_uint8_t oui[3]; - grub_uint16_t type; -} GRUB_PACKED; - -grub_err_t -send_ethernet_packet (struct grub_net_network_level_interface *inf, - struct grub_net_buff *nb, - grub_net_link_level_address_t target_addr, - grub_net_ethertype_t ethertype) -{ - struct etherhdr *eth; - grub_err_t err; - grub_uint8_t etherhdr_size; - grub_uint16_t vlantag_id = grub_cpu_to_be16_compile_time (VLANTAG_IDENTIFIER); - - etherhdr_size = sizeof (*eth); - COMPILE_TIME_ASSERT (sizeof (*eth) + 4 < GRUB_NET_MAX_LINK_HEADER_SIZE); - - /* Increase ethernet header in case of vlantag */ - if (inf->vlantag != 0) - etherhdr_size += 4; - - err = grub_netbuff_push (nb, etherhdr_size); - if (err) - return err; - eth = (struct etherhdr *) nb->data; - grub_memcpy (eth->dst, target_addr.mac, 6); - grub_memcpy (eth->src, inf->hwaddress.mac, 6); - - eth->type = grub_cpu_to_be16 (ethertype); - if (!inf->card->opened) - { - err = GRUB_ERR_NONE; - if (inf->card->driver->open) - err = inf->card->driver->open (inf->card); - if (err) - return err; - inf->card->opened = 1; - } - - /* Check and add a vlan-tag if needed. */ - if (inf->vlantag != 0) - { - /* Move eth type to the right */ - grub_memcpy ((char *) nb->data + etherhdr_size - 2, - (char *) nb->data + etherhdr_size - 6, 2); - - /* Add the tag in the middle */ - grub_uint16_t vlan = grub_cpu_to_be16 (inf->vlantag); - grub_memcpy ((char *) nb->data + etherhdr_size - 6, &vlantag_id, 2); - grub_memcpy ((char *) nb->data + etherhdr_size - 4, &vlan, 2); - } - - return inf->card->driver->send (inf->card, nb); -} - -grub_err_t -grub_net_recv_ethernet_packet (struct grub_net_buff *nb, - struct grub_net_card *card) -{ - struct etherhdr *eth; - struct llchdr *llch; - struct snaphdr *snaph; - grub_net_ethertype_t type; - grub_net_link_level_address_t hwaddress; - grub_net_link_level_address_t src_hwaddress; - grub_err_t err; - grub_uint8_t etherhdr_size = sizeof (*eth); - grub_uint16_t vlantag = 0; - - - /* Check if a vlan-tag is present. If so, the ethernet header is 4 bytes */ - /* longer than the original one. The vlantag id is extracted and the header */ - /* is reseted to the original size. */ - if (grub_get_unaligned16 (nb->data + etherhdr_size - 2) == grub_cpu_to_be16_compile_time (VLANTAG_IDENTIFIER)) - { - vlantag = grub_be_to_cpu16 (grub_get_unaligned16 (nb->data + etherhdr_size)); - etherhdr_size += 4; - /* Move eth type to the original position */ - grub_memcpy((char *) nb->data + etherhdr_size - 6, - (char *) nb->data + etherhdr_size - 2, 2); - } - - eth = (struct etherhdr *) nb->data; - type = grub_be_to_cpu16 (eth->type); - err = grub_netbuff_pull (nb, etherhdr_size); - if (err) - return err; - - if (type <= 1500) - { - llch = (struct llchdr *) nb->data; - type = llch->dsap & LLCADDRMASK; - - if (llch->dsap == 0xaa && llch->ssap == 0xaa && llch->ctrl == 0x3) - { - err = grub_netbuff_pull (nb, sizeof (*llch)); - if (err) - return err; - snaph = (struct snaphdr *) nb->data; - type = snaph->type; - } - } - - hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - grub_memcpy (hwaddress.mac, eth->dst, sizeof (hwaddress.mac)); - src_hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - grub_memcpy (src_hwaddress.mac, eth->src, sizeof (src_hwaddress.mac)); - - switch (type) - { - /* ARP packet. */ - case GRUB_NET_ETHERTYPE_ARP: - grub_net_arp_receive (nb, card, &vlantag); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - /* IP packet. */ - case GRUB_NET_ETHERTYPE_IP: - case GRUB_NET_ETHERTYPE_IP6: - return grub_net_recv_ip_packets (nb, card, &hwaddress, &src_hwaddress, - &vlantag); - } - grub_netbuff_free (nb); - return GRUB_ERR_NONE; -} diff --git a/grub-core/net/http.c b/grub-core/net/http.c deleted file mode 100644 index f389bf03d..000000000 --- a/grub-core/net/http.c +++ /dev/null @@ -1,575 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define HTTP_PORT ((grub_uint16_t) 80) - -typedef struct http_data -{ - char *current_line; - grub_size_t current_line_len; - int headers_recv; - int first_line_recv; - int size_recv; - grub_net_tcp_socket_t sock; - char *filename; - grub_err_t err; - char *errmsg; - int chunked; - grub_size_t chunk_rem; - int in_chunk_len; -} *http_data_t; - -static grub_off_t -have_ahead (struct grub_file *file) -{ - grub_net_t net = file->device->net; - grub_off_t ret = net->offset; - struct grub_net_packet *pack; - for (pack = net->packs.first; pack; pack = pack->next) - ret += pack->nb->tail - pack->nb->data; - return ret; -} - -static grub_err_t -parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len) -{ - char *end = ptr + len; - while (end > ptr && *(end - 1) == '\r') - end--; - - /* LF without CR. */ - if (end == ptr + len) - { - data->errmsg = grub_strdup (_("invalid HTTP header - LF without CR")); - return GRUB_ERR_NONE; - } - *end = 0; - - /* Trailing CRLF. */ - if (data->in_chunk_len == 1) - { - data->in_chunk_len = 2; - return GRUB_ERR_NONE; - } - if (data->in_chunk_len == 2) - { - data->chunk_rem = grub_strtoul (ptr, 0, 16); - grub_errno = GRUB_ERR_NONE; - if (data->chunk_rem == 0) - { - file->device->net->eof = 1; - file->device->net->stall = 1; - if (file->size == GRUB_FILE_SIZE_UNKNOWN) - file->size = have_ahead (file); - } - data->in_chunk_len = 0; - return GRUB_ERR_NONE; - } - if (ptr == end) - { - data->headers_recv = 1; - if (data->chunked) - data->in_chunk_len = 2; - return GRUB_ERR_NONE; - } - - if (!data->first_line_recv) - { - int code; - if (grub_memcmp (ptr, "HTTP/1.1 ", sizeof ("HTTP/1.1 ") - 1) != 0) - { - data->errmsg = grub_strdup (_("unsupported HTTP response")); - data->first_line_recv = 1; - return GRUB_ERR_NONE; - } - ptr += sizeof ("HTTP/1.1 ") - 1; - code = grub_strtoul (ptr, (const char **)&ptr, 10); - if (grub_errno) - return grub_errno; - switch (code) - { - case 200: - case 206: - break; - case 404: - data->err = GRUB_ERR_FILE_NOT_FOUND; - data->errmsg = grub_xasprintf (_("file `%s' not found"), data->filename); - return GRUB_ERR_NONE; - default: - data->err = GRUB_ERR_NET_UNKNOWN_ERROR; - /* TRANSLATORS: GRUB HTTP code is pretty young. So even perfectly - valid answers like 403 will trigger this very generic message. */ - data->errmsg = grub_xasprintf (_("unsupported HTTP error %d: %s"), - code, ptr); - return GRUB_ERR_NONE; - } - data->first_line_recv = 1; - return GRUB_ERR_NONE; - } - if (grub_memcmp (ptr, "Content-Length: ", sizeof ("Content-Length: ") - 1) - == 0 && !data->size_recv) - { - ptr += sizeof ("Content-Length: ") - 1; - file->size = grub_strtoull (ptr, (const char **)&ptr, 10); - data->size_recv = 1; - return GRUB_ERR_NONE; - } - if (grub_memcmp (ptr, "Transfer-Encoding: chunked", - sizeof ("Transfer-Encoding: chunked") - 1) == 0) - { - data->chunked = 1; - return GRUB_ERR_NONE; - } - - return GRUB_ERR_NONE; -} - -static void -http_err (grub_net_tcp_socket_t sock __attribute__ ((unused)), - void *f) -{ - grub_file_t file = f; - http_data_t data = file->data; - - if (data->sock) - grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); - data->sock = 0; - if (data->current_line) - grub_free (data->current_line); - data->current_line = 0; - file->device->net->eof = 1; - file->device->net->stall = 1; - if (file->size == GRUB_FILE_SIZE_UNKNOWN) - file->size = have_ahead (file); -} - -static grub_err_t -http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)), - struct grub_net_buff *nb, - void *f) -{ - grub_file_t file = f; - http_data_t data = file->data; - grub_err_t err; - - if (!data->sock) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - - while (1) - { - char *ptr = (char *) nb->data; - if ((!data->headers_recv || data->in_chunk_len) && data->current_line) - { - int have_line = 1; - char *t; - ptr = grub_memchr (nb->data, '\n', nb->tail - nb->data); - if (ptr == NULL) - { - have_line = 0; - ptr = (char *) nb->tail; - } - t = grub_realloc (data->current_line, - data->current_line_len + (ptr - (char *) nb->data)); - if (!t) - { - grub_netbuff_free (nb); - grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); - return grub_errno; - } - - data->current_line = t; - grub_memcpy (data->current_line + data->current_line_len, - nb->data, ptr - (char *) nb->data); - data->current_line_len += ptr - (char *) nb->data; - if (!have_line) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - err = parse_line (file, data, data->current_line, - data->current_line_len); - grub_free (data->current_line); - data->current_line = 0; - data->current_line_len = 0; - if (err) - { - grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); - grub_netbuff_free (nb); - return err; - } - } - - while (ptr < (char *) nb->tail && (!data->headers_recv - || data->in_chunk_len)) - { - char *ptr2; - ptr2 = grub_memchr (ptr, '\n', (char *) nb->tail - ptr); - if (!ptr2) - { - data->current_line = grub_malloc ((char *) nb->tail - ptr); - if (!data->current_line) - { - grub_netbuff_free (nb); - grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); - return grub_errno; - } - data->current_line_len = (char *) nb->tail - ptr; - grub_memcpy (data->current_line, ptr, data->current_line_len); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - err = parse_line (file, data, ptr, ptr2 - ptr); - if (err) - { - grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); - grub_netbuff_free (nb); - return err; - } - ptr = ptr2 + 1; - } - - if (((char *) nb->tail - ptr) <= 0) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - err = grub_netbuff_pull (nb, ptr - (char *) nb->data); - if (err) - { - grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); - grub_netbuff_free (nb); - return err; - } - if (!(data->chunked && (grub_ssize_t) data->chunk_rem - < nb->tail - nb->data)) - { - grub_net_put_packet (&file->device->net->packs, nb); - if (file->device->net->packs.count >= 20) - file->device->net->stall = 1; - - if (file->device->net->packs.count >= 100) - grub_net_tcp_stall (data->sock); - - if (data->chunked) - data->chunk_rem -= nb->tail - nb->data; - return GRUB_ERR_NONE; - } - if (data->chunk_rem) - { - struct grub_net_buff *nb2; - nb2 = grub_netbuff_alloc (data->chunk_rem); - if (!nb2) - return grub_errno; - grub_netbuff_put (nb2, data->chunk_rem); - grub_memcpy (nb2->data, nb->data, data->chunk_rem); - if (file->device->net->packs.count >= 20) - { - file->device->net->stall = 1; - grub_net_tcp_stall (data->sock); - } - - grub_net_put_packet (&file->device->net->packs, nb2); - grub_netbuff_pull (nb, data->chunk_rem); - } - data->in_chunk_len = 1; - } -} - -static grub_err_t -http_establish (struct grub_file *file, grub_off_t offset, int initial) -{ - http_data_t data = file->data; - grub_uint8_t *ptr; - int i; - struct grub_net_buff *nb; - grub_err_t err; - char *server = file->device->net->server; - grub_uint16_t port = file->device->net->port; - - nb = grub_netbuff_alloc (GRUB_NET_TCP_RESERVE_SIZE - + sizeof ("GET ") - 1 - + grub_strlen (data->filename) - + sizeof (" HTTP/1.1\r\nHost: ") - 1 - + grub_strlen (server) + sizeof (":XXXXXXXXXX") - + sizeof ("\r\nUser-Agent: " PACKAGE_STRING - "\r\n") - 1 - + sizeof ("Range: bytes=XXXXXXXXXXXXXXXXXXXX" - "-\r\n\r\n")); - if (!nb) - return grub_errno; - - grub_netbuff_reserve (nb, GRUB_NET_TCP_RESERVE_SIZE); - ptr = nb->tail; - err = grub_netbuff_put (nb, sizeof ("GET ") - 1); - if (err) - { - grub_netbuff_free (nb); - return err; - } - grub_memcpy (ptr, "GET ", sizeof ("GET ") - 1); - - ptr = nb->tail; - - err = grub_netbuff_put (nb, grub_strlen (data->filename)); - if (err) - { - grub_netbuff_free (nb); - return err; - } - grub_memcpy (ptr, data->filename, grub_strlen (data->filename)); - - ptr = nb->tail; - err = grub_netbuff_put (nb, sizeof (" HTTP/1.1\r\nHost: ") - 1); - if (err) - { - grub_netbuff_free (nb); - return err; - } - grub_memcpy (ptr, " HTTP/1.1\r\nHost: ", - sizeof (" HTTP/1.1\r\nHost: ") - 1); - - ptr = nb->tail; - err = grub_netbuff_put (nb, grub_strlen (server)); - if (err) - { - grub_netbuff_free (nb); - return err; - } - grub_memcpy (ptr, file->device->net->server, - grub_strlen (file->device->net->server)); - - if (port) - { - ptr = nb->tail; - grub_snprintf ((char *) ptr, sizeof (":XXXXXXXXXX"), ":%d", port); - } - - ptr = nb->tail; - err = grub_netbuff_put (nb, - sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n") - - 1); - if (err) - { - grub_netbuff_free (nb); - return err; - } - grub_memcpy (ptr, "\r\nUser-Agent: " PACKAGE_STRING "\r\n", - sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n") - 1); - if (!initial) - { - ptr = nb->tail; - grub_snprintf ((char *) ptr, - sizeof ("Range: bytes=XXXXXXXXXXXXXXXXXXXX-" - "\r\n"), - "Range: bytes=%" PRIuGRUB_UINT64_T "-\r\n", - offset); - grub_netbuff_put (nb, grub_strlen ((char *) ptr)); - } - ptr = nb->tail; - grub_netbuff_put (nb, 2); - grub_memcpy (ptr, "\r\n", 2); - - grub_dprintf ("http", "opening path %s on host %s TCP port %d\n", - data->filename, server, port ? port : HTTP_PORT); - data->sock = grub_net_tcp_open (server, - port ? port : HTTP_PORT, http_receive, - http_err, NULL, - file); - if (!data->sock) - { - grub_netbuff_free (nb); - return grub_errno; - } - - // grub_net_poll_cards (5000); - - err = grub_net_send_tcp_packet (data->sock, nb, 1); - if (err) - { - grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); - return err; - } - - for (i = 0; data->sock && !data->headers_recv && i < 100; i++) - { - grub_net_tcp_retransmit (); - grub_net_poll_cards (300, &data->headers_recv); - } - - if (!data->headers_recv) - { - if (data->sock) - grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); - if (data->err) - { - char *str = data->errmsg; - err = grub_error (data->err, "%s", str); - grub_free (str); - data->errmsg = 0; - return data->err; - } - return grub_error (GRUB_ERR_TIMEOUT, N_("time out opening `%s'"), data->filename); - } - return GRUB_ERR_NONE; -} - -static grub_err_t -http_seek (struct grub_file *file, grub_off_t off) -{ - struct http_data *old_data, *data; - grub_err_t err; - old_data = file->data; - /* FIXME: Reuse socket? */ - if (old_data->sock) - grub_net_tcp_close (old_data->sock, GRUB_NET_TCP_ABORT); - old_data->sock = 0; - - while (file->device->net->packs.first) - { - grub_netbuff_free (file->device->net->packs.first->nb); - grub_net_remove_packet (file->device->net->packs.first); - } - - file->device->net->stall = 0; - file->device->net->eof = 0; - file->device->net->offset = off; - - data = grub_zalloc (sizeof (*data)); - if (!data) - return grub_errno; - - data->size_recv = 1; - data->filename = old_data->filename; - if (!data->filename) - { - grub_free (data); - file->data = 0; - return grub_errno; - } - grub_free (old_data); - - file->data = data; - err = http_establish (file, off, 0); - if (err) - { - grub_free (data->filename); - grub_free (data); - file->data = 0; - return err; - } - return GRUB_ERR_NONE; -} - -static grub_err_t -http_open (struct grub_file *file, const char *filename) -{ - grub_err_t err; - struct http_data *data; - - data = grub_zalloc (sizeof (*data)); - if (!data) - return grub_errno; - file->size = GRUB_FILE_SIZE_UNKNOWN; - - data->filename = grub_strdup (filename); - if (!data->filename) - { - grub_free (data); - return grub_errno; - } - - file->not_easily_seekable = 0; - file->data = data; - - err = http_establish (file, 0, 1); - if (err) - { - grub_free (data->filename); - grub_free (data); - return err; - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -http_close (struct grub_file *file) -{ - http_data_t data = file->data; - - if (!data) - return GRUB_ERR_NONE; - - if (data->sock) - grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); - if (data->current_line) - grub_free (data->current_line); - grub_free (data->filename); - grub_free (data); - return GRUB_ERR_NONE; -} - -static grub_err_t -http_packets_pulled (struct grub_file *file) -{ - http_data_t data = file->data; - - if (file->device->net->packs.count >= 20) - return 0; - - if (!file->device->net->eof) - file->device->net->stall = 0; - if (data && data->sock) - grub_net_tcp_unstall (data->sock); - return 0; -} - -static struct grub_net_app_protocol grub_http_protocol = - { - .name = "http", - .open = http_open, - .close = http_close, - .seek = http_seek, - .packets_pulled = http_packets_pulled - }; - -GRUB_MOD_INIT (http) -{ - grub_net_app_level_register (&grub_http_protocol); -} - -GRUB_MOD_FINI (http) -{ - grub_net_app_level_unregister (&grub_http_protocol); -} diff --git a/grub-core/net/icmp.c b/grub-core/net/icmp.c deleted file mode 100644 index b1eef114e..000000000 --- a/grub-core/net/icmp.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -struct icmp_header -{ - grub_uint8_t type; - grub_uint8_t code; - grub_uint16_t checksum; -} GRUB_PACKED; - -struct ping_header -{ - grub_uint16_t id; - grub_uint16_t seq; -} GRUB_PACKED; - -enum - { - ICMP_ECHO_REPLY = 0, - ICMP_ECHO = 8, - }; - -grub_err_t -grub_net_recv_icmp_packet (struct grub_net_buff *nb, - struct grub_net_network_level_interface *inf, - const grub_net_link_level_address_t *ll_src, - const grub_net_network_level_address_t *src) -{ - struct icmp_header *icmph; - grub_err_t err; - grub_uint16_t checksum; - - /* Ignore broadcast. */ - if (!inf) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - - icmph = (struct icmp_header *) nb->data; - - if (nb->tail - nb->data < (grub_ssize_t) sizeof (*icmph)) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - - checksum = icmph->checksum; - icmph->checksum = 0; - if (checksum != grub_net_ip_chksum (nb->data, nb->tail - nb->data)) - { - icmph->checksum = checksum; - return GRUB_ERR_NONE; - } - icmph->checksum = checksum; - - err = grub_netbuff_pull (nb, sizeof (*icmph)); - if (err) - return err; - - switch (icmph->type) - { - case ICMP_ECHO: - { - struct grub_net_buff *nb_reply; - struct icmp_header *icmphr; - if (icmph->code) - break; - nb_reply = grub_netbuff_make_pkt (nb->tail - nb->data + sizeof (*icmphr)); - if (!nb_reply) - { - grub_netbuff_free (nb); - return grub_errno; - } - grub_memcpy (nb_reply->data + sizeof (*icmphr), nb->data, nb->tail - nb->data); - icmphr = (struct icmp_header *) nb_reply->data; - icmphr->type = ICMP_ECHO_REPLY; - icmphr->code = 0; - icmphr->checksum = 0; - icmphr->checksum = grub_net_ip_chksum ((void *) nb_reply->data, - nb_reply->tail - nb_reply->data); - err = grub_net_send_ip_packet (inf, src, ll_src, - nb_reply, GRUB_NET_IP_ICMP); - - grub_netbuff_free (nb); - grub_netbuff_free (nb_reply); - return err; - } - }; - - grub_netbuff_free (nb); - return GRUB_ERR_NONE; -} diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c deleted file mode 100644 index 9a8c45112..000000000 --- a/grub-core/net/icmp6.c +++ /dev/null @@ -1,679 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -struct icmp_header -{ - grub_uint8_t type; - grub_uint8_t code; - grub_uint16_t checksum; -} GRUB_PACKED; - -struct ping_header -{ - grub_uint16_t id; - grub_uint16_t seq; -} GRUB_PACKED; - -struct router_adv -{ - grub_uint8_t ttl; - grub_uint8_t flags; - grub_uint16_t router_lifetime; - grub_uint32_t reachable_time; - grub_uint32_t retrans_timer; - grub_uint8_t options[0]; -} GRUB_PACKED; - -struct option_header -{ - grub_uint8_t type; - grub_uint8_t len; -} GRUB_PACKED; - -struct prefix_option -{ - struct option_header header; - grub_uint8_t prefixlen; - grub_uint8_t flags; - grub_uint32_t valid_lifetime; - grub_uint32_t preferred_lifetime; - grub_uint32_t reserved; - grub_uint64_t prefix[2]; -} GRUB_PACKED; - -struct neighbour_solicit -{ - grub_uint32_t reserved; - grub_uint64_t target[2]; -} GRUB_PACKED; - -struct neighbour_advertise -{ - grub_uint32_t flags; - grub_uint64_t target[2]; -} GRUB_PACKED; - -struct router_solicit -{ - grub_uint32_t reserved; -} GRUB_PACKED; - -enum - { - FLAG_SLAAC = 0x40 - }; - -enum - { - ICMP6_ECHO = 128, - ICMP6_ECHO_REPLY = 129, - ICMP6_ROUTER_SOLICIT = 133, - ICMP6_ROUTER_ADVERTISE = 134, - ICMP6_NEIGHBOUR_SOLICIT = 135, - ICMP6_NEIGHBOUR_ADVERTISE = 136, - }; - -enum - { - OPTION_SOURCE_LINK_LAYER_ADDRESS = 1, - OPTION_TARGET_LINK_LAYER_ADDRESS = 2, - OPTION_PREFIX = 3 - }; - -enum - { - FLAG_SOLICITED = (1 << 30), - FLAG_OVERRIDE = (1 << 29) - }; - -grub_err_t -grub_net_recv_icmp6_packet (struct grub_net_buff *nb, - struct grub_net_card *card, - struct grub_net_network_level_interface *inf, - const grub_net_link_level_address_t *ll_src, - const grub_net_network_level_address_t *source, - const grub_net_network_level_address_t *dest, - grub_uint8_t ttl) -{ - struct icmp_header *icmph; - struct grub_net_network_level_interface *orig_inf = inf; - grub_err_t err; - grub_uint16_t checksum; - - icmph = (struct icmp_header *) nb->data; - - if (nb->tail - nb->data < (grub_ssize_t) sizeof (*icmph)) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - - checksum = icmph->checksum; - icmph->checksum = 0; - if (checksum != grub_net_ip_transport_checksum (nb, - GRUB_NET_IP_ICMPV6, - source, - dest)) - { - grub_dprintf ("net", "invalid ICMPv6 checksum: %04x instead of %04x\n", - checksum, - grub_net_ip_transport_checksum (nb, - GRUB_NET_IP_ICMPV6, - source, - dest)); - icmph->checksum = checksum; - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - icmph->checksum = checksum; - - err = grub_netbuff_pull (nb, sizeof (*icmph)); - if (err) - { - grub_netbuff_free (nb); - return err; - } - - grub_dprintf ("net", "ICMPv6 message: %02x, %02x\n", - icmph->type, icmph->code); - switch (icmph->type) - { - case ICMP6_ECHO: - /* Don't accept multicast pings. */ - if (!inf) - break; - { - struct grub_net_buff *nb_reply; - struct icmp_header *icmphr; - if (icmph->code) - break; - nb_reply = grub_netbuff_alloc (nb->tail - nb->data + 512); - if (!nb_reply) - { - grub_netbuff_free (nb); - return grub_errno; - } - err = grub_netbuff_reserve (nb_reply, nb->tail - nb->data + 512); - if (err) - goto ping_fail; - err = grub_netbuff_push (nb_reply, nb->tail - nb->data); - if (err) - goto ping_fail; - grub_memcpy (nb_reply->data, nb->data, nb->tail - nb->data); - err = grub_netbuff_push (nb_reply, sizeof (*icmphr)); - if (err) - goto ping_fail; - icmphr = (struct icmp_header *) nb_reply->data; - icmphr->type = ICMP6_ECHO_REPLY; - icmphr->code = 0; - icmphr->checksum = 0; - icmphr->checksum = grub_net_ip_transport_checksum (nb_reply, - GRUB_NET_IP_ICMPV6, - &inf->address, - source); - err = grub_net_send_ip_packet (inf, source, ll_src, nb_reply, - GRUB_NET_IP_ICMPV6); - - ping_fail: - grub_netbuff_free (nb); - grub_netbuff_free (nb_reply); - return err; - } - case ICMP6_NEIGHBOUR_SOLICIT: - { - struct neighbour_solicit *nbh; - struct grub_net_buff *nb_reply; - struct option_header *ohdr; - struct neighbour_advertise *adv; - struct icmp_header *icmphr; - grub_uint8_t *ptr; - - if (icmph->code) - break; - if (ttl != 0xff) - break; - nbh = (struct neighbour_solicit *) nb->data; - err = grub_netbuff_pull (nb, sizeof (*nbh)); - if (err) - { - grub_netbuff_free (nb); - return err; - } - for (ptr = (grub_uint8_t *) nb->data; ptr < nb->tail; - ptr += ohdr->len * 8) - { - ohdr = (struct option_header *) ptr; - if (ohdr->len == 0 || ptr + 8 * ohdr->len > nb->tail) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - if (ohdr->type == OPTION_SOURCE_LINK_LAYER_ADDRESS - && ohdr->len == 1) - { - grub_net_link_level_address_t ll_address; - ll_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - grub_memcpy (ll_address.mac, ohdr + 1, sizeof (ll_address.mac)); - grub_net_link_layer_add_address (card, source, &ll_address, 0); - } - } - FOR_NET_NETWORK_LEVEL_INTERFACES (inf) - { - if (inf->card == card - && inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6 - && grub_memcmp (&inf->address.ipv6, &nbh->target, 16) == 0) - break; - } - if (!inf) - break; - - nb_reply = grub_netbuff_alloc (sizeof (struct neighbour_advertise) - + sizeof (struct option_header) - + 6 - + sizeof (struct icmp_header) - + GRUB_NET_OUR_IPV6_HEADER_SIZE - + GRUB_NET_MAX_LINK_HEADER_SIZE); - if (!nb_reply) - { - grub_netbuff_free (nb); - return grub_errno; - } - err = grub_netbuff_reserve (nb_reply, - sizeof (struct neighbour_advertise) - + sizeof (struct option_header) - + 6 - + sizeof (struct icmp_header) - + GRUB_NET_OUR_IPV6_HEADER_SIZE - + GRUB_NET_MAX_LINK_HEADER_SIZE); - if (err) - goto ndp_fail; - - err = grub_netbuff_push (nb_reply, 6); - if (err) - goto ndp_fail; - grub_memcpy (nb_reply->data, inf->hwaddress.mac, 6); - err = grub_netbuff_push (nb_reply, sizeof (*ohdr)); - if (err) - goto ndp_fail; - ohdr = (struct option_header *) nb_reply->data; - ohdr->type = OPTION_TARGET_LINK_LAYER_ADDRESS; - ohdr->len = 1; - err = grub_netbuff_push (nb_reply, sizeof (*adv)); - if (err) - goto ndp_fail; - adv = (struct neighbour_advertise *) nb_reply->data; - adv->flags = grub_cpu_to_be32_compile_time (FLAG_SOLICITED - | FLAG_OVERRIDE); - grub_memcpy (&adv->target, &nbh->target, 16); - - err = grub_netbuff_push (nb_reply, sizeof (*icmphr)); - if (err) - goto ndp_fail; - icmphr = (struct icmp_header *) nb_reply->data; - icmphr->type = ICMP6_NEIGHBOUR_ADVERTISE; - icmphr->code = 0; - icmphr->checksum = 0; - icmphr->checksum = grub_net_ip_transport_checksum (nb_reply, - GRUB_NET_IP_ICMPV6, - &inf->address, - source); - err = grub_net_send_ip_packet (inf, source, ll_src, nb_reply, - GRUB_NET_IP_ICMPV6); - - ndp_fail: - grub_netbuff_free (nb); - grub_netbuff_free (nb_reply); - return err; - } - case ICMP6_NEIGHBOUR_ADVERTISE: - { - struct neighbour_advertise *nbh; - grub_uint8_t *ptr; - struct option_header *ohdr; - - if (icmph->code) - break; - if (ttl != 0xff) - break; - nbh = (struct neighbour_advertise *) nb->data; - err = grub_netbuff_pull (nb, sizeof (*nbh)); - if (err) - { - grub_netbuff_free (nb); - return err; - } - - for (ptr = (grub_uint8_t *) nb->data; ptr < nb->tail; - ptr += ohdr->len * 8) - { - ohdr = (struct option_header *) ptr; - if (ohdr->len == 0 || ptr + 8 * ohdr->len > nb->tail) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - if (ohdr->type == OPTION_TARGET_LINK_LAYER_ADDRESS - && ohdr->len == 1) - { - grub_net_link_level_address_t ll_address; - ll_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - grub_memcpy (ll_address.mac, ohdr + 1, sizeof (ll_address.mac)); - grub_net_link_layer_add_address (card, source, &ll_address, 0); - } - } - break; - } - case ICMP6_ROUTER_ADVERTISE: - { - grub_uint8_t *ptr; - struct option_header *ohdr; - struct router_adv *radv; - struct grub_net_network_level_interface *route_inf = NULL; - int default_route = 0; - if (icmph->code) - break; - radv = (struct router_adv *)nb->data; - err = grub_netbuff_pull (nb, sizeof (struct router_adv)); - if (err) - { - grub_netbuff_free (nb); - return err; - } - if (grub_be_to_cpu16 (radv->router_lifetime) > 0) - { - struct grub_net_route *route; - - FOR_NET_ROUTES (route) - { - if (!grub_memcmp (&route->gw, source, sizeof (route->gw))) - break; - } - if (route == NULL) - default_route = 1; - } - - for (ptr = (grub_uint8_t *) nb->data; ptr < nb->tail; - ptr += ohdr->len * 8) - { - ohdr = (struct option_header *) ptr; - if (ohdr->len == 0 || ptr + 8 * ohdr->len > nb->tail) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - if (ohdr->type == OPTION_SOURCE_LINK_LAYER_ADDRESS - && ohdr->len == 1) - { - grub_net_link_level_address_t ll_address; - ll_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - grub_memcpy (ll_address.mac, ohdr + 1, sizeof (ll_address.mac)); - grub_net_link_layer_add_address (card, source, &ll_address, 0); - } - if (ohdr->type == OPTION_PREFIX && ohdr->len == 4) - { - struct prefix_option *opt = (struct prefix_option *) ptr; - struct grub_net_slaac_mac_list *slaac; - if (!(opt->flags & FLAG_SLAAC) - || (grub_be_to_cpu64 (opt->prefix[0]) >> 48) == 0xfe80 - || (grub_be_to_cpu32 (opt->preferred_lifetime) - > grub_be_to_cpu32 (opt->valid_lifetime)) - || opt->prefixlen != 64) - { - grub_dprintf ("net", "discarded prefix: %d, %d, %d, %d\n", - !(opt->flags & FLAG_SLAAC), - (grub_be_to_cpu64 (opt->prefix[0]) >> 48) == 0xfe80, - (grub_be_to_cpu32 (opt->preferred_lifetime) - > grub_be_to_cpu32 (opt->valid_lifetime)), - opt->prefixlen != 64); - continue; - } - for (slaac = card->slaac_list; slaac; slaac = slaac->next) - { - grub_net_network_level_address_t addr; - grub_net_network_level_netaddress_t netaddr; - - if (slaac->address.type - != GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET) - continue; - addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; - addr.ipv6[0] = opt->prefix[0]; - addr.ipv6[1] = grub_net_ipv6_get_id (&slaac->address); - netaddr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; - netaddr.ipv6.base[0] = opt->prefix[0]; - netaddr.ipv6.base[1] = 0; - netaddr.ipv6.masksize = 64; - - FOR_NET_NETWORK_LEVEL_INTERFACES (inf) - { - if (inf->card == card - && grub_net_addr_cmp (&inf->address, &addr) == 0) - break; - } - /* Update lease time if needed here once we have - lease times. */ - if (inf) - { - if (!route_inf) - route_inf = inf; - continue; - } - - grub_dprintf ("net", "creating slaac\n"); - - { - char *name; - name = grub_xasprintf ("%s:%d", - slaac->name, slaac->slaac_counter++); - if (!name) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - inf = grub_net_add_addr (name, - card, &addr, - &slaac->address, 0); - if (!route_inf) - route_inf = inf; - grub_net_add_route (name, netaddr, inf); - grub_free (name); - } - } - } - } - if (default_route) - { - char *name; - grub_net_network_level_netaddress_t netaddr; - name = grub_xasprintf ("%s:ra:default6", card->name); - if (!name) - { - grub_errno = GRUB_ERR_NONE; - goto next; - } - /* Default routes take alll of the traffic, so make the mask huge */ - netaddr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; - netaddr.ipv6.masksize = 0; - netaddr.ipv6.base[0] = 0; - netaddr.ipv6.base[1] = 0; - - /* May not have gotten slaac info, find a global address on this - card. */ - if (route_inf == NULL && orig_inf != NULL) - { - FOR_NET_NETWORK_LEVEL_INTERFACES (inf) - { - if (inf->card == card && inf != orig_inf - && inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6 - && grub_net_hwaddr_cmp(&inf->hwaddress, - &orig_inf->hwaddress) == 0) - { - route_inf = inf; - break; - } - } - } - if (route_inf != NULL) - grub_net_add_route_gw (name, netaddr, *source, route_inf); - grub_free (name); - } -next: - if (ptr != nb->tail) - break; - } - }; - - grub_netbuff_free (nb); - return GRUB_ERR_NONE; -} - -grub_err_t -grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *proto_addr) -{ - struct grub_net_buff *nb; - grub_err_t err = GRUB_ERR_NONE; - int i; - struct option_header *ohdr; - struct neighbour_solicit *sol; - struct icmp_header *icmphr; - grub_net_network_level_address_t multicast; - grub_net_link_level_address_t ll_multicast; - grub_uint8_t *nbd; - multicast.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; - multicast.ipv6[0] = grub_be_to_cpu64_compile_time (0xff02ULL << 48); - multicast.ipv6[1] = (grub_be_to_cpu64_compile_time (0x01ff000000ULL) - | (proto_addr->ipv6[1] - & grub_be_to_cpu64_compile_time (0xffffff))); - - err = grub_net_link_layer_resolve (inf, &multicast, &ll_multicast); - if (err) - return err; - - nb = grub_netbuff_alloc (sizeof (struct neighbour_solicit) - + sizeof (struct option_header) - + 6 - + sizeof (struct icmp_header) - + GRUB_NET_OUR_IPV6_HEADER_SIZE - + GRUB_NET_MAX_LINK_HEADER_SIZE); - if (!nb) - return grub_errno; - err = grub_netbuff_reserve (nb, - sizeof (struct neighbour_solicit) - + sizeof (struct option_header) - + 6 - + sizeof (struct icmp_header) - + GRUB_NET_OUR_IPV6_HEADER_SIZE - + GRUB_NET_MAX_LINK_HEADER_SIZE); - err = grub_netbuff_push (nb, 6); - if (err) - goto fail; - - grub_memcpy (nb->data, inf->hwaddress.mac, 6); - err = grub_netbuff_push (nb, sizeof (*ohdr)); - if (err) - goto fail; - - ohdr = (struct option_header *) nb->data; - ohdr->type = OPTION_SOURCE_LINK_LAYER_ADDRESS; - ohdr->len = 1; - err = grub_netbuff_push (nb, sizeof (*sol)); - if (err) - goto fail; - - sol = (struct neighbour_solicit *) nb->data; - sol->reserved = 0; - grub_memcpy (&sol->target, &proto_addr->ipv6, 16); - - err = grub_netbuff_push (nb, sizeof (*icmphr)); - if (err) - goto fail; - - icmphr = (struct icmp_header *) nb->data; - icmphr->type = ICMP6_NEIGHBOUR_SOLICIT; - icmphr->code = 0; - icmphr->checksum = 0; - icmphr->checksum = grub_net_ip_transport_checksum (nb, - GRUB_NET_IP_ICMPV6, - &inf->address, - &multicast); - nbd = nb->data; - err = grub_net_send_ip_packet (inf, &multicast, &ll_multicast, nb, - GRUB_NET_IP_ICMPV6); - if (err) - goto fail; - - for (i = 0; i < GRUB_NET_TRIES; i++) - { - if (grub_net_link_layer_resolve_check (inf, proto_addr)) - break; - grub_net_poll_cards (GRUB_NET_INTERVAL + (i * GRUB_NET_INTERVAL_ADDITION), - 0); - if (grub_net_link_layer_resolve_check (inf, proto_addr)) - break; - nb->data = nbd; - err = grub_net_send_ip_packet (inf, &multicast, &ll_multicast, nb, - GRUB_NET_IP_ICMPV6); - if (err) - break; - } - - fail: - grub_netbuff_free (nb); - return err; -} - -grub_err_t -grub_net_icmp6_send_router_solicit (struct grub_net_network_level_interface *inf) -{ - struct grub_net_buff *nb; - grub_err_t err = GRUB_ERR_NONE; - grub_net_network_level_address_t multicast; - grub_net_link_level_address_t ll_multicast; - struct option_header *ohdr; - struct router_solicit *sol; - struct icmp_header *icmphr; - - multicast.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; - multicast.ipv6[0] = grub_cpu_to_be64_compile_time (0xff02ULL << 48); - multicast.ipv6[1] = grub_cpu_to_be64_compile_time (0x02ULL); - - err = grub_net_link_layer_resolve (inf, &multicast, &ll_multicast); - if (err) - return err; - - nb = grub_netbuff_alloc (sizeof (struct router_solicit) - + sizeof (struct option_header) - + 6 - + sizeof (struct icmp_header) - + GRUB_NET_OUR_IPV6_HEADER_SIZE - + GRUB_NET_MAX_LINK_HEADER_SIZE); - if (!nb) - return grub_errno; - err = grub_netbuff_reserve (nb, - sizeof (struct router_solicit) - + sizeof (struct option_header) - + 6 - + sizeof (struct icmp_header) - + GRUB_NET_OUR_IPV6_HEADER_SIZE - + GRUB_NET_MAX_LINK_HEADER_SIZE); - if (err) - goto fail; - - err = grub_netbuff_push (nb, 6); - if (err) - goto fail; - - grub_memcpy (nb->data, inf->hwaddress.mac, 6); - - err = grub_netbuff_push (nb, sizeof (*ohdr)); - if (err) - goto fail; - - ohdr = (struct option_header *) nb->data; - ohdr->type = OPTION_SOURCE_LINK_LAYER_ADDRESS; - ohdr->len = 1; - - err = grub_netbuff_push (nb, sizeof (*sol)); - if (err) - goto fail; - - sol = (struct router_solicit *) nb->data; - sol->reserved = 0; - - err = grub_netbuff_push (nb, sizeof (*icmphr)); - if (err) - goto fail; - - icmphr = (struct icmp_header *) nb->data; - icmphr->type = ICMP6_ROUTER_SOLICIT; - icmphr->code = 0; - icmphr->checksum = 0; - icmphr->checksum = grub_net_ip_transport_checksum (nb, - GRUB_NET_IP_ICMPV6, - &inf->address, - &multicast); - err = grub_net_send_ip_packet (inf, &multicast, &ll_multicast, nb, - GRUB_NET_IP_ICMPV6); - fail: - grub_netbuff_free (nb); - return err; -} diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c deleted file mode 100644 index 3c3d0be0e..000000000 --- a/grub-core/net/ip.c +++ /dev/null @@ -1,747 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct iphdr { - grub_uint8_t verhdrlen; - grub_uint8_t service; - grub_uint16_t len; - grub_uint16_t ident; - grub_uint16_t frags; - grub_uint8_t ttl; - grub_uint8_t protocol; - grub_uint16_t chksum; - grub_uint32_t src; - grub_uint32_t dest; -} GRUB_PACKED ; - -enum -{ - DONT_FRAGMENT = 0x4000, - MORE_FRAGMENTS = 0x2000, - OFFSET_MASK = 0x1fff -}; - -typedef grub_uint64_t ip6addr[2]; - -struct ip6hdr { - grub_uint32_t version_class_flow; - grub_uint16_t len; - grub_uint8_t protocol; - grub_uint8_t ttl; - ip6addr src; - ip6addr dest; -} GRUB_PACKED ; - -static int -cmp (const void *a__, const void *b__) -{ - struct grub_net_buff *a_ = *(struct grub_net_buff **) a__; - struct grub_net_buff *b_ = *(struct grub_net_buff **) b__; - struct iphdr *a = (struct iphdr *) a_->data; - struct iphdr *b = (struct iphdr *) b_->data; - /* We want the first elements to be on top. */ - if ((grub_be_to_cpu16 (a->frags) & OFFSET_MASK) - < (grub_be_to_cpu16 (b->frags) & OFFSET_MASK)) - return +1; - if ((grub_be_to_cpu16 (a->frags) & OFFSET_MASK) - > (grub_be_to_cpu16 (b->frags) & OFFSET_MASK)) - return -1; - return 0; -} - -struct reassemble -{ - struct reassemble *next; - grub_uint32_t source; - grub_uint32_t dest; - grub_uint16_t id; - grub_uint8_t proto; - grub_uint64_t last_time; - grub_priority_queue_t pq; - struct grub_net_buff *asm_netbuff; - grub_size_t total_len; - grub_size_t cur_ptr; - grub_uint8_t ttl; -}; - -static struct reassemble *reassembles; - -grub_uint16_t -grub_net_ip_chksum (void *ipv, grub_size_t len) -{ - grub_uint16_t *ip = (grub_uint16_t *) ipv; - grub_uint32_t sum = 0; - - for (; len >= 2; len -= 2) - { - sum += grub_be_to_cpu16 (grub_get_unaligned16 (ip++)); - if (sum > 0xFFFF) - sum -= 0xFFFF; - } - if (len) - { - sum += *((grub_uint8_t *) ip) << 8; - if (sum > 0xFFFF) - sum -= 0xFFFF; - } - - if (sum >= 0xFFFF) - sum -= 0xFFFF; - - return grub_cpu_to_be16 ((~sum) & 0x0000FFFF); -} - -static int id = 0x2400; - -static grub_err_t -send_fragmented (struct grub_net_network_level_interface * inf, - const grub_net_network_level_address_t * target, - struct grub_net_buff * nb, - grub_net_ip_protocol_t proto, - grub_net_link_level_address_t ll_target_addr) -{ - grub_size_t off = 0; - grub_size_t fraglen; - grub_err_t err; - - fraglen = (inf->card->mtu - sizeof (struct iphdr)) & ~7; - id++; - - while (nb->tail - nb->data) - { - grub_size_t len = fraglen; - struct grub_net_buff *nb2; - struct iphdr *iph; - - if ((grub_ssize_t) len > nb->tail - nb->data) - len = nb->tail - nb->data; - nb2 = grub_netbuff_alloc (fraglen + sizeof (struct iphdr) - + GRUB_NET_MAX_LINK_HEADER_SIZE); - if (!nb2) - return grub_errno; - err = grub_netbuff_reserve (nb2, GRUB_NET_MAX_LINK_HEADER_SIZE); - if (err) - return err; - err = grub_netbuff_put (nb2, sizeof (struct iphdr)); - if (err) - return err; - - iph = (struct iphdr *) nb2->data; - iph->verhdrlen = ((4 << 4) | 5); - iph->service = 0; - iph->len = grub_cpu_to_be16 (len + sizeof (struct iphdr)); - iph->ident = grub_cpu_to_be16 (id); - iph->frags = grub_cpu_to_be16 (off | (((grub_ssize_t) len - == nb->tail - nb->data) - ? 0 : MORE_FRAGMENTS)); - iph->ttl = 0xff; - iph->protocol = proto; - iph->src = inf->address.ipv4; - iph->dest = target->ipv4; - off += len / 8; - - iph->chksum = 0; - iph->chksum = grub_net_ip_chksum ((void *) nb2->data, sizeof (*iph)); - err = grub_netbuff_put (nb2, len); - if (err) - return err; - grub_memcpy (iph + 1, nb->data, len); - err = grub_netbuff_pull (nb, len); - if (err) - return err; - err = send_ethernet_packet (inf, nb2, ll_target_addr, - GRUB_NET_ETHERTYPE_IP); - if (err) - return err; - } - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_net_send_ip4_packet (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *target, - const grub_net_link_level_address_t *ll_target_addr, - struct grub_net_buff *nb, - grub_net_ip_protocol_t proto) -{ - struct iphdr *iph; - grub_err_t err; - - COMPILE_TIME_ASSERT (GRUB_NET_OUR_IPV4_HEADER_SIZE == sizeof (*iph)); - - if (nb->tail - nb->data + sizeof (struct iphdr) > inf->card->mtu) - return send_fragmented (inf, target, nb, proto, *ll_target_addr); - - err = grub_netbuff_push (nb, sizeof (*iph)); - if (err) - return err; - - iph = (struct iphdr *) nb->data; - iph->verhdrlen = ((4 << 4) | 5); - iph->service = 0; - iph->len = grub_cpu_to_be16 (nb->tail - nb->data); - iph->ident = grub_cpu_to_be16 (++id); - iph->frags = 0; - iph->ttl = 0xff; - iph->protocol = proto; - iph->src = inf->address.ipv4; - iph->dest = target->ipv4; - - iph->chksum = 0; - iph->chksum = grub_net_ip_chksum ((void *) nb->data, sizeof (*iph)); - - return send_ethernet_packet (inf, nb, *ll_target_addr, - GRUB_NET_ETHERTYPE_IP); -} - -static grub_err_t -handle_dgram (struct grub_net_buff *nb, - struct grub_net_card *card, - const grub_net_link_level_address_t *source_hwaddress, - const grub_net_link_level_address_t *hwaddress, - grub_net_ip_protocol_t proto, - const grub_net_network_level_address_t *source, - const grub_net_network_level_address_t *dest, - grub_uint16_t *vlantag, - grub_uint8_t ttl) -{ - struct grub_net_network_level_interface *inf = NULL; - grub_err_t err; - int multicast = 0; - - /* DHCP needs special treatment since we don't know IP yet. */ - { - struct udphdr *udph; - udph = (struct udphdr *) nb->data; - if (proto == GRUB_NET_IP_UDP && grub_be_to_cpu16 (udph->dst) == 68) - { - const struct grub_net_bootp_packet *bootp; - if (udph->chksum) - { - grub_uint16_t chk, expected; - chk = udph->chksum; - udph->chksum = 0; - expected = grub_net_ip_transport_checksum (nb, - GRUB_NET_IP_UDP, - source, - dest); - if (expected != chk) - { - grub_dprintf ("net", "Invalid UDP checksum. " - "Expected %x, got %x\n", - grub_be_to_cpu16 (expected), - grub_be_to_cpu16 (chk)); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - udph->chksum = chk; - } - - err = grub_netbuff_pull (nb, sizeof (*udph)); - if (err) - { - grub_netbuff_free (nb); - return err; - } - - bootp = (const struct grub_net_bootp_packet *) nb->data; - - FOR_NET_NETWORK_LEVEL_INTERFACES (inf) - if (inf->card == card - && inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV - && inf->hwaddress.type == GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET - && grub_memcmp (inf->hwaddress.mac, &bootp->mac_addr, - sizeof (inf->hwaddress.mac)) == 0) - { - grub_net_process_dhcp (nb, inf); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - } - - FOR_NET_NETWORK_LEVEL_INTERFACES (inf) - { - if (inf->card == card - && grub_net_addr_cmp (&inf->address, dest) == 0 - && grub_net_hwaddr_cmp (&inf->hwaddress, hwaddress) == 0) - break; - - /* Verify vlantag id */ - if (inf->card == card && inf->vlantag != *vlantag) - { - grub_dprintf ("net", "invalid vlantag! %x != %x\n", - inf->vlantag, *vlantag); - break; - } - - /* Solicited node multicast. */ - if (inf->card == card - && inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6 - && dest->type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6 - && dest->ipv6[0] == grub_be_to_cpu64_compile_time (0xff02ULL << 48) - && dest->ipv6[1] == (grub_be_to_cpu64_compile_time (0x01ff000000ULL) - | (inf->address.ipv6[1] - & grub_be_to_cpu64_compile_time (0xffffff))) - && hwaddress->type == GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET - && hwaddress->mac[0] == 0x33 && hwaddress->mac[1] == 0x33 - && hwaddress->mac[2] == 0xff - && hwaddress->mac[3] == ((grub_be_to_cpu64 (inf->address.ipv6[1]) - >> 16) & 0xff) - && hwaddress->mac[4] == ((grub_be_to_cpu64 (inf->address.ipv6[1]) - >> 8) & 0xff) - && hwaddress->mac[5] == ((grub_be_to_cpu64 (inf->address.ipv6[1]) - >> 0) & 0xff)) - { - multicast = 1; - break; - } - } - - if (!inf && !(dest->type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6 - && dest->ipv6[0] == grub_be_to_cpu64_compile_time (0xff02ULL - << 48) - && dest->ipv6[1] == grub_be_to_cpu64_compile_time (1))) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - if (multicast) - inf = NULL; - - switch (proto) - { - case GRUB_NET_IP_UDP: - return grub_net_recv_udp_packet (nb, inf, source); - case GRUB_NET_IP_TCP: - return grub_net_recv_tcp_packet (nb, inf, source); - case GRUB_NET_IP_ICMP: - return grub_net_recv_icmp_packet (nb, inf, source_hwaddress, source); - case GRUB_NET_IP_ICMPV6: - return grub_net_recv_icmp6_packet (nb, card, inf, source_hwaddress, - source, dest, ttl); - default: - grub_netbuff_free (nb); - break; - } - return GRUB_ERR_NONE; -} - -static void -free_rsm (struct reassemble *rsm) -{ - struct grub_net_buff **nb; - while ((nb = grub_priority_queue_top (rsm->pq))) - { - grub_netbuff_free (*nb); - grub_priority_queue_pop (rsm->pq); - } - grub_netbuff_free (rsm->asm_netbuff); - grub_priority_queue_destroy (rsm->pq); - grub_free (rsm); -} - -static void -free_old_fragments (void) -{ - struct reassemble *rsm, **prev; - grub_uint64_t limit_time = grub_get_time_ms (); - - limit_time = (limit_time > 90000) ? limit_time - 90000 : 0; - - for (prev = &reassembles, rsm = *prev; rsm; rsm = *prev) - if (rsm->last_time < limit_time) - { - *prev = rsm->next; - free_rsm (rsm); - } - else - { - prev = &rsm->next; - } -} - -static grub_err_t -grub_net_recv_ip4_packets (struct grub_net_buff *nb, - struct grub_net_card *card, - const grub_net_link_level_address_t *hwaddress, - const grub_net_link_level_address_t *src_hwaddress, - grub_uint16_t *vlantag) -{ - struct iphdr *iph = (struct iphdr *) nb->data; - grub_err_t err; - struct reassemble *rsm, **prev; - - if ((iph->verhdrlen >> 4) != 4) - { - grub_dprintf ("net", "Bad IP version: %d\n", (iph->verhdrlen >> 4)); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - - if ((iph->verhdrlen & 0xf) < 5) - { - grub_dprintf ("net", "IP header too short: %d\n", - (iph->verhdrlen & 0xf)); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - - if (nb->tail - nb->data < (grub_ssize_t) ((iph->verhdrlen & 0xf) - * sizeof (grub_uint32_t))) - { - grub_dprintf ("net", "IP packet too short: %" PRIdGRUB_SSIZE "\n", - (grub_ssize_t) (nb->tail - nb->data)); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - - /* Check size. */ - { - grub_size_t expected_size = grub_be_to_cpu16 (iph->len); - grub_size_t actual_size = (nb->tail - nb->data); - if (actual_size > expected_size) - { - err = grub_netbuff_unput (nb, actual_size - expected_size); - if (err) - { - grub_netbuff_free (nb); - return err; - } - } - if (actual_size < expected_size) - { - grub_dprintf ("net", "Cut IP packet actual: %" PRIuGRUB_SIZE - ", expected %" PRIuGRUB_SIZE "\n", actual_size, - expected_size); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - } - - /* Unfragmented packet. Good. */ - if (((grub_be_to_cpu16 (iph->frags) & MORE_FRAGMENTS) == 0) - && (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK) == 0) - { - grub_net_network_level_address_t source; - grub_net_network_level_address_t dest; - - err = grub_netbuff_pull (nb, ((iph->verhdrlen & 0xf) - * sizeof (grub_uint32_t))); - if (err) - { - grub_netbuff_free (nb); - return err; - } - - source.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - source.ipv4 = iph->src; - - dest.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - dest.ipv4 = iph->dest; - - return handle_dgram (nb, card, src_hwaddress, hwaddress, iph->protocol, - &source, &dest, vlantag, iph->ttl); - } - - for (prev = &reassembles, rsm = *prev; rsm; prev = &rsm->next, rsm = *prev) - if (rsm->source == iph->src && rsm->dest == iph->dest - && rsm->id == iph->ident && rsm->proto == iph->protocol) - break; - if (!rsm) - { - rsm = grub_malloc (sizeof (*rsm)); - if (!rsm) - return grub_errno; - rsm->source = iph->src; - rsm->dest = iph->dest; - rsm->id = iph->ident; - rsm->proto = iph->protocol; - rsm->next = reassembles; - reassembles = rsm; - prev = &reassembles; - rsm->pq = grub_priority_queue_new (sizeof (struct grub_net_buff **), cmp); - if (!rsm->pq) - { - grub_free (rsm); - return grub_errno; - } - rsm->asm_netbuff = 0; - rsm->total_len = 0; - rsm->cur_ptr = 0; - rsm->ttl = 0xff; - } - if (rsm->ttl > iph->ttl) - rsm->ttl = iph->ttl; - rsm->last_time = grub_get_time_ms (); - free_old_fragments (); - - err = grub_priority_queue_push (rsm->pq, &nb); - if (err) - return err; - - if (!(grub_be_to_cpu16 (iph->frags) & MORE_FRAGMENTS)) - { - rsm->total_len = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK) - + (nb->tail - nb->data)); - - if (grub_sub (rsm->total_len, (iph->verhdrlen & 0xf) * sizeof (grub_uint32_t), - &rsm->total_len)) - { - grub_dprintf ("net", "IP reassembly size underflow\n"); - return GRUB_ERR_NONE; - } - - rsm->asm_netbuff = grub_netbuff_alloc (rsm->total_len); - if (!rsm->asm_netbuff) - { - *prev = rsm->next; - free_rsm (rsm); - return grub_errno; - } - } - if (!rsm->asm_netbuff) - return GRUB_ERR_NONE; - - while (1) - { - struct grub_net_buff **nb_top_p, *nb_top; - grub_size_t copy; - grub_size_t res_len; - struct grub_net_buff *ret; - grub_net_ip_protocol_t proto; - grub_uint32_t src; - grub_uint32_t dst; - grub_net_network_level_address_t source; - grub_net_network_level_address_t dest; - grub_uint8_t ttl; - - nb_top_p = grub_priority_queue_top (rsm->pq); - if (!nb_top_p) - return GRUB_ERR_NONE; - nb_top = *nb_top_p; - grub_priority_queue_pop (rsm->pq); - iph = (struct iphdr *) nb_top->data; - err = grub_netbuff_pull (nb_top, ((iph->verhdrlen & 0xf) - * sizeof (grub_uint32_t))); - if (err) - { - grub_netbuff_free (nb_top); - return err; - } - if (rsm->cur_ptr < (grub_size_t) 8 * (grub_be_to_cpu16 (iph->frags) - & OFFSET_MASK)) - { - grub_netbuff_free (nb_top); - return GRUB_ERR_NONE; - } - - rsm->cur_ptr = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK) - + (nb_top->tail - nb_top->head)); - if ((grub_size_t) 8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK) - >= rsm->total_len) - { - grub_netbuff_free (nb_top); - continue; - } - copy = nb_top->tail - nb_top->data; - if (rsm->total_len - 8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK) - < copy) - copy = rsm->total_len - 8 * (grub_be_to_cpu16 (iph->frags) - & OFFSET_MASK); - grub_memcpy (&rsm->asm_netbuff->data[8 * (grub_be_to_cpu16 (iph->frags) - & OFFSET_MASK)], - nb_top->data, copy); - - if ((grub_be_to_cpu16 (iph->frags) & MORE_FRAGMENTS)) - { - grub_netbuff_free (nb_top); - continue; - } - grub_netbuff_free (nb_top); - - ret = rsm->asm_netbuff; - proto = rsm->proto; - src = rsm->source; - dst = rsm->dest; - ttl = rsm->ttl; - - rsm->asm_netbuff = 0; - res_len = rsm->total_len; - *prev = rsm->next; - free_rsm (rsm); - - if (grub_netbuff_put (ret, res_len)) - { - grub_netbuff_free (ret); - return GRUB_ERR_NONE; - } - - source.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - source.ipv4 = src; - - dest.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - dest.ipv4 = dst; - - return handle_dgram (ret, card, src_hwaddress, - hwaddress, proto, &source, &dest, vlantag, - ttl); - } -} - -static grub_err_t -grub_net_send_ip6_packet (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *target, - const grub_net_link_level_address_t *ll_target_addr, - struct grub_net_buff *nb, - grub_net_ip_protocol_t proto) -{ - struct ip6hdr *iph; - grub_err_t err; - - COMPILE_TIME_ASSERT (GRUB_NET_OUR_IPV6_HEADER_SIZE == sizeof (*iph)); - - if (nb->tail - nb->data + sizeof (struct iphdr) > inf->card->mtu) - return grub_error (GRUB_ERR_NET_PACKET_TOO_BIG, "packet too big"); - - err = grub_netbuff_push (nb, sizeof (*iph)); - if (err) - return err; - - iph = (struct ip6hdr *) nb->data; - iph->version_class_flow = grub_cpu_to_be32_compile_time ((6 << 28)); - iph->len = grub_cpu_to_be16 (nb->tail - nb->data - sizeof (*iph)); - iph->protocol = proto; - iph->ttl = 0xff; - grub_memcpy (&iph->src, inf->address.ipv6, sizeof (iph->src)); - grub_memcpy (&iph->dest, target->ipv6, sizeof (iph->dest)); - - return send_ethernet_packet (inf, nb, *ll_target_addr, - GRUB_NET_ETHERTYPE_IP6); -} - -grub_err_t -grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *target, - const grub_net_link_level_address_t *ll_target_addr, - struct grub_net_buff *nb, - grub_net_ip_protocol_t proto) -{ - switch (target->type) - { - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: - return grub_net_send_ip4_packet (inf, target, ll_target_addr, nb, proto); - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6: - return grub_net_send_ip6_packet (inf, target, ll_target_addr, nb, proto); - default: - return grub_error (GRUB_ERR_BUG, "not an IP"); - } -} - -static grub_err_t -grub_net_recv_ip6_packets (struct grub_net_buff *nb, - struct grub_net_card *card, - const grub_net_link_level_address_t *hwaddress, - const grub_net_link_level_address_t *src_hwaddress, - grub_uint16_t *vlantag) -{ - struct ip6hdr *iph = (struct ip6hdr *) nb->data; - grub_err_t err; - grub_net_network_level_address_t source; - grub_net_network_level_address_t dest; - - if (nb->tail - nb->data < (grub_ssize_t) sizeof (*iph)) - { - grub_dprintf ("net", "IP packet too short: %" PRIdGRUB_SSIZE "\n", - (grub_ssize_t) (nb->tail - nb->data)); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - - err = grub_netbuff_pull (nb, sizeof (*iph)); - if (err) - { - grub_netbuff_free (nb); - return err; - } - - /* Check size. */ - { - grub_size_t expected_size = grub_be_to_cpu16 (iph->len); - grub_size_t actual_size = (nb->tail - nb->data); - if (actual_size > expected_size) - { - err = grub_netbuff_unput (nb, actual_size - expected_size); - if (err) - { - grub_netbuff_free (nb); - return err; - } - } - if (actual_size < expected_size) - { - grub_dprintf ("net", "Cut IP packet actual: %" PRIuGRUB_SIZE - ", expected %" PRIuGRUB_SIZE "\n", actual_size, - expected_size); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - } - - source.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; - dest.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; - grub_memcpy (source.ipv6, &iph->src, sizeof (source.ipv6)); - grub_memcpy (dest.ipv6, &iph->dest, sizeof (dest.ipv6)); - - return handle_dgram (nb, card, src_hwaddress, hwaddress, iph->protocol, - &source, &dest, vlantag, iph->ttl); -} - -grub_err_t -grub_net_recv_ip_packets (struct grub_net_buff *nb, - struct grub_net_card *card, - const grub_net_link_level_address_t *hwaddress, - const grub_net_link_level_address_t *src_hwaddress, - grub_uint16_t *vlantag) -{ - struct iphdr *iph = (struct iphdr *) nb->data; - - if ((iph->verhdrlen >> 4) == 4) - return grub_net_recv_ip4_packets (nb, card, hwaddress, src_hwaddress, - vlantag); - if ((iph->verhdrlen >> 4) == 6) - return grub_net_recv_ip6_packets (nb, card, hwaddress, src_hwaddress, - vlantag); - grub_dprintf ("net", "Bad IP version: %d\n", (iph->verhdrlen >> 4)); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; -} diff --git a/grub-core/net/net.c b/grub-core/net/net.c deleted file mode 100644 index 6ea33d1cd..000000000 --- a/grub-core/net/net.c +++ /dev/null @@ -1,2158 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -char *grub_net_default_server; - -struct grub_net_route *grub_net_routes = NULL; -struct grub_net_network_level_interface *grub_net_network_level_interfaces = NULL; -struct grub_net_card *grub_net_cards = NULL; -struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL; -static struct grub_fs grub_net_fs; - -struct grub_net_link_layer_entry { - int avail; - grub_net_network_level_address_t nl_address; - grub_net_link_level_address_t ll_address; -}; - -#define LINK_LAYER_CACHE_SIZE 256 - -static struct grub_net_link_layer_entry * -link_layer_find_entry (const grub_net_network_level_address_t *proto, - const struct grub_net_card *card) -{ - unsigned i; - if (!card->link_layer_table) - return NULL; - for (i = 0; i < LINK_LAYER_CACHE_SIZE; i++) - { - if (card->link_layer_table[i].avail == 1 - && grub_net_addr_cmp (&card->link_layer_table[i].nl_address, - proto) == 0) - return &card->link_layer_table[i]; - } - return NULL; -} - -void -grub_net_link_layer_add_address (struct grub_net_card *card, - const grub_net_network_level_address_t *nl, - const grub_net_link_level_address_t *ll, - int override) -{ - struct grub_net_link_layer_entry *entry; - - /* Check if the sender is in the cache table. */ - entry = link_layer_find_entry (nl, card); - /* Update sender hardware address. */ - if (entry && override) - grub_memcpy (&entry->ll_address, ll, sizeof (entry->ll_address)); - if (entry) - return; - - /* Add sender to cache table. */ - if (card->link_layer_table == NULL) - { - card->link_layer_table = grub_calloc (LINK_LAYER_CACHE_SIZE, - sizeof (card->link_layer_table[0])); - if (card->link_layer_table == NULL) - return; - } - - entry = &(card->link_layer_table[card->new_ll_entry]); - entry->avail = 1; - grub_memcpy (&entry->ll_address, ll, sizeof (entry->ll_address)); - grub_memcpy (&entry->nl_address, nl, sizeof (entry->nl_address)); - card->new_ll_entry++; - if (card->new_ll_entry == LINK_LAYER_CACHE_SIZE) - card->new_ll_entry = 0; -} - -int -grub_net_link_layer_resolve_check (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *proto_addr) -{ - struct grub_net_link_layer_entry *entry; - - if (proto_addr->type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 - && proto_addr->ipv4 == 0xffffffff) - return 1; - entry = link_layer_find_entry (proto_addr, inf->card); - if (entry) - return 1; - return 0; -} - -grub_err_t -grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *proto_addr, - grub_net_link_level_address_t *hw_addr) -{ - struct grub_net_link_layer_entry *entry; - grub_err_t err; - - if ((proto_addr->type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 - && proto_addr->ipv4 == 0xffffffff) - || proto_addr->type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV - || (proto_addr->type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6 - && proto_addr->ipv6[0] == grub_be_to_cpu64_compile_time (0xff02ULL - << 48) - && proto_addr->ipv6[1] == (grub_be_to_cpu64_compile_time (1)))) - { - hw_addr->type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - grub_memset (hw_addr->mac, -1, 6); - return GRUB_ERR_NONE; - } - - if (proto_addr->type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6 - && ((grub_be_to_cpu64 (proto_addr->ipv6[0]) >> 56) == 0xff)) - { - hw_addr->type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - hw_addr->mac[0] = 0x33; - hw_addr->mac[1] = 0x33; - hw_addr->mac[2] = ((grub_be_to_cpu64 (proto_addr->ipv6[1]) >> 24) & 0xff); - hw_addr->mac[3] = ((grub_be_to_cpu64 (proto_addr->ipv6[1]) >> 16) & 0xff); - hw_addr->mac[4] = ((grub_be_to_cpu64 (proto_addr->ipv6[1]) >> 8) & 0xff); - hw_addr->mac[5] = ((grub_be_to_cpu64 (proto_addr->ipv6[1]) >> 0) & 0xff); - return GRUB_ERR_NONE; - } - - /* Check cache table. */ - entry = link_layer_find_entry (proto_addr, inf->card); - if (entry) - { - *hw_addr = entry->ll_address; - return GRUB_ERR_NONE; - } - switch (proto_addr->type) - { - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: - err = grub_net_arp_send_request (inf, proto_addr); - break; - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6: - err = grub_net_icmp6_send_request (inf, proto_addr); - break; - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV: - return grub_error (GRUB_ERR_BUG, "shouldn't reach here"); - default: - return grub_error (GRUB_ERR_BUG, - "unsupported address type %d", proto_addr->type); - } - if (err) - return err; - entry = link_layer_find_entry (proto_addr, inf->card); - if (entry) - { - *hw_addr = entry->ll_address; - return GRUB_ERR_NONE; - } - return grub_error (GRUB_ERR_TIMEOUT, - N_("timeout: could not resolve hardware address")); -} - -void -grub_net_card_unregister (struct grub_net_card *card) -{ - struct grub_net_network_level_interface *inf, *next; - FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE(inf, next) - if (inf->card == card) - grub_net_network_level_interface_unregister (inf); - if (card->opened) - { - if (card->driver->close) - card->driver->close (card); - card->opened = 0; - } - grub_list_remove (GRUB_AS_LIST (card)); -} - -static struct grub_net_slaac_mac_list * -grub_net_ipv6_get_slaac (struct grub_net_card *card, - const grub_net_link_level_address_t *hwaddr) -{ - struct grub_net_slaac_mac_list *slaac; - char *ptr; - grub_size_t sz; - - for (slaac = card->slaac_list; slaac; slaac = slaac->next) - if (grub_net_hwaddr_cmp (&slaac->address, hwaddr) == 0) - return slaac; - - slaac = grub_zalloc (sizeof (*slaac)); - if (!slaac) - return NULL; - - if (grub_add (grub_strlen (card->name), - (GRUB_NET_MAX_STR_HWADDR_LEN + sizeof (":slaac")), &sz)) - { - grub_free (slaac); - grub_error (GRUB_ERR_OUT_OF_RANGE, - "overflow detected while obtaining size of slaac name"); - return NULL; - } - - slaac->name = grub_malloc (sz); - if (slaac->name == NULL) - { - grub_free (slaac); - return NULL; - } - ptr = grub_stpcpy (slaac->name, card->name); - if (grub_net_hwaddr_cmp (&card->default_address, hwaddr) != 0) - { - ptr = grub_stpcpy (ptr, ":"); - grub_net_hwaddr_to_str (hwaddr, ptr); - ptr += grub_strlen (ptr); - } - ptr = grub_stpcpy (ptr, ":slaac"); - - grub_memcpy (&slaac->address, hwaddr, sizeof (slaac->address)); - slaac->next = card->slaac_list; - card->slaac_list = slaac; - return slaac; -} - -static void -grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter); - -static struct grub_net_network_level_interface * -grub_net_add_addr_real (char *name, - struct grub_net_card *card, - const grub_net_network_level_address_t *addr, - const grub_net_link_level_address_t *hwaddress, - grub_net_interface_flags_t flags) -{ - struct grub_net_network_level_interface *inter; - - inter = grub_zalloc (sizeof (*inter)); - if (!inter) - return NULL; - - inter->name = name; - grub_memcpy (&(inter->address), addr, sizeof (inter->address)); - grub_memcpy (&(inter->hwaddress), hwaddress, sizeof (inter->hwaddress)); - inter->flags = flags; - inter->card = card; - inter->dhcp_ack = NULL; - inter->dhcp_acklen = 0; - - grub_net_network_level_interface_register (inter); - - return inter; -} - -struct grub_net_network_level_interface * -grub_net_add_addr (const char *name, - struct grub_net_card *card, - const grub_net_network_level_address_t *addr, - const grub_net_link_level_address_t *hwaddress, - grub_net_interface_flags_t flags) -{ - char *name_dup = grub_strdup (name); - struct grub_net_network_level_interface *ret; - - if (!name_dup) - return NULL; - ret = grub_net_add_addr_real (name_dup, card, addr, hwaddress, flags); - if (!ret) - grub_free (name_dup); - return ret; -} - -struct grub_net_network_level_interface * -grub_net_ipv6_get_link_local (struct grub_net_card *card, - const grub_net_link_level_address_t *hwaddr) -{ - struct grub_net_network_level_interface *inf; - char *name; - char *ptr; - grub_net_network_level_address_t addr; - grub_size_t sz; - - addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; - addr.ipv6[0] = grub_cpu_to_be64_compile_time (0xfe80ULL << 48); - addr.ipv6[1] = grub_net_ipv6_get_id (hwaddr); - addr.option = 0; - - FOR_NET_NETWORK_LEVEL_INTERFACES (inf) - { - if (inf->card == card - && grub_net_hwaddr_cmp (&inf->hwaddress, hwaddr) == 0 - && grub_net_addr_cmp (&inf->address, &addr) == 0) - return inf; - } - - if (grub_add (grub_strlen (card->name), - (GRUB_NET_MAX_STR_HWADDR_LEN + sizeof (":link")), &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, - "overflow detected while obtaining size of link name"); - return NULL; - } - name = grub_malloc (sz); - if (!name) - return NULL; - - ptr = grub_stpcpy (name, card->name); - if (grub_net_hwaddr_cmp (&card->default_address, hwaddr) != 0) - { - ptr = grub_stpcpy (ptr, ":"); - grub_net_hwaddr_to_str (hwaddr, ptr); - ptr += grub_strlen (ptr); - } - ptr = grub_stpcpy (ptr, ":link"); - return grub_net_add_addr_real (name, card, &addr, hwaddr, 0); -} - -/* FIXME: allow to specify mac address. */ -static grub_err_t -grub_cmd_ipv6_autoconf (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - struct grub_net_card *card; - struct grub_net_network_level_interface **ifaces; - grub_size_t ncards = 0; - unsigned j = 0; - int interval; - grub_err_t err; - struct grub_net_slaac_mac_list **slaacs; - - FOR_NET_CARDS (card) - { - if (argc > 0 && grub_strcmp (card->name, args[0]) != 0) - continue; - ncards++; - } - - ifaces = grub_calloc (ncards, sizeof (ifaces[0])); - slaacs = grub_calloc (ncards, sizeof (slaacs[0])); - if (!ifaces || !slaacs) - { - grub_free (ifaces); - grub_free (slaacs); - return grub_errno; - } - - FOR_NET_CARDS (card) - { - if (argc > 0 && grub_strcmp (card->name, args[0]) != 0) - continue; - ifaces[j] = grub_net_ipv6_get_link_local (card, &card->default_address); - if (!ifaces[j]) - { - grub_free (ifaces); - grub_free (slaacs); - return grub_errno; - } - slaacs[j] = grub_net_ipv6_get_slaac (card, &card->default_address); - if (!slaacs[j]) - { - grub_free (ifaces); - grub_free (slaacs); - return grub_errno; - } - j++; - } - - for (interval = 200; interval < 10000; interval *= 2) - { - int done = 1; - for (j = 0; j < ncards; j++) - { - if (slaacs[j]->slaac_counter) - continue; - err = grub_net_icmp6_send_router_solicit (ifaces[j]); - if (err) - err = GRUB_ERR_NONE; - done = 0; - } - if (done) - break; - grub_net_poll_cards (interval, 0); - } - - err = GRUB_ERR_NONE; - for (j = 0; j < ncards; j++) - { - if (slaacs[j]->slaac_counter) - continue; - err = grub_error (GRUB_ERR_FILE_NOT_FOUND, - N_("couldn't autoconfigure %s"), - ifaces[j]->card->name); - } - - grub_free (ifaces); - grub_free (slaacs); - return err; -} - - -static int -parse_ip (const char *val, grub_uint32_t *ip, const char **rest) -{ - grub_uint32_t newip = 0; - int i; - const char *ptr = val; - - for (i = 0; i < 4; i++) - { - unsigned long t; - t = grub_strtoul (ptr, &ptr, 0); - if (grub_errno) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - if (*ptr != '.' && i == 0) - { - newip = t; - break; - } - if (t & ~0xff) - return 0; - newip >>= 8; - newip |= (t << 24); - if (i != 3 && *ptr != '.') - return 0; - ptr++; - } - *ip = grub_cpu_to_le32 (newip); - if (rest) - *rest = (ptr - 1); - return 1; -} - -static int -parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest) -{ - grub_uint16_t newip[8]; - const char *ptr = val; - int word, quaddot = -1; - bool bracketed = false; - - if (ptr[0] == '[') - { - bracketed = true; - ptr++; - } - - if (ptr[0] == ':' && ptr[1] != ':') - return 0; - if (ptr[0] == ':') - ptr++; - - for (word = 0; word < 8; word++) - { - unsigned long t; - if (*ptr == ':') - { - quaddot = word; - word--; - ptr++; - continue; - } - t = grub_strtoul (ptr, &ptr, 16); - if (grub_errno) - { - grub_errno = GRUB_ERR_NONE; - break; - } - if (t & ~0xffff) - return 0; - newip[word] = grub_cpu_to_be16 (t); - if (*ptr != ':') - break; - ptr++; - } - if (quaddot == -1 && word < 7) - return 0; - if (quaddot != -1) - { - grub_memmove (&newip[quaddot + 7 - word], &newip[quaddot], - (word - quaddot + 1) * sizeof (newip[0])); - grub_memset (&newip[quaddot], 0, (7 - word) * sizeof (newip[0])); - } - grub_memcpy (ip, newip, 16); - if (bracketed && *ptr == ']') - ptr++; - if (rest) - *rest = ptr; - return 1; -} - -static int -match_net (const grub_net_network_level_netaddress_t *net, - const grub_net_network_level_address_t *addr) -{ - if (net->type != addr->type) - return 0; - switch (net->type) - { - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV: - return 0; - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: - { - grub_uint32_t mask = (0xffffffffU << (32 - net->ipv4.masksize)); - if (net->ipv4.masksize == 0) - mask = 0; - return ((grub_be_to_cpu32 (net->ipv4.base) & mask) - == (grub_be_to_cpu32 (addr->ipv4) & mask)); - } - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6: - { - grub_uint64_t mask[2]; - if (net->ipv6.masksize == 0) - return 1; - if (net->ipv6.masksize <= 64) - { - mask[0] = 0xffffffffffffffffULL << (64 - net->ipv6.masksize); - mask[1] = 0; - } - else - { - mask[0] = 0xffffffffffffffffULL; - mask[1] = 0xffffffffffffffffULL << (128 - net->ipv6.masksize); - } - return (((grub_be_to_cpu64 (net->ipv6.base[0]) & mask[0]) - == (grub_be_to_cpu64 (addr->ipv6[0]) & mask[0])) - && ((grub_be_to_cpu64 (net->ipv6.base[1]) & mask[1]) - == (grub_be_to_cpu64 (addr->ipv6[1]) & mask[1]))); - } - } - return 0; -} - -grub_err_t -grub_net_resolve_address (const char *name, - grub_net_network_level_address_t *addr) -{ - const char *rest; - grub_err_t err; - grub_size_t naddresses; - struct grub_net_network_level_address *addresses = 0; - - if (parse_ip (name, &addr->ipv4, &rest) && *rest == 0) - { - addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - return GRUB_ERR_NONE; - } - if (parse_ip6 (name, addr->ipv6, &rest) && *rest == 0) - { - addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; - return GRUB_ERR_NONE; - } - err = grub_net_dns_lookup (name, 0, 0, &naddresses, &addresses, 1); - if (err) - return err; - if (!naddresses) - grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("unresolvable address %s"), - name); - /* FIXME: use other results as well. */ - *addr = addresses[0]; - grub_free (addresses); - return GRUB_ERR_NONE; -} - -grub_err_t -grub_net_resolve_net_address (const char *name, - grub_net_network_level_netaddress_t *addr) -{ - const char *rest; - if (parse_ip (name, &addr->ipv4.base, &rest)) - { - addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - if (*rest == '/') - { - addr->ipv4.masksize = grub_strtoul (rest + 1, &rest, 0); - if (!grub_errno && *rest == 0) - return GRUB_ERR_NONE; - grub_errno = GRUB_ERR_NONE; - } - else if (*rest == 0) - { - addr->ipv4.masksize = 32; - return GRUB_ERR_NONE; - } - } - if (parse_ip6 (name, addr->ipv6.base, &rest)) - { - addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; - if (*rest == '/') - { - addr->ipv6.masksize = grub_strtoul (rest + 1, &rest, 0); - if (!grub_errno && *rest == 0) - return GRUB_ERR_NONE; - grub_errno = GRUB_ERR_NONE; - } - else if (*rest == 0) - { - addr->ipv6.masksize = 128; - return GRUB_ERR_NONE; - } - } - return grub_error (GRUB_ERR_NET_BAD_ADDRESS, - N_("unrecognised network address `%s'"), - name); -} - -static int -route_cmp (const struct grub_net_route *a, const struct grub_net_route *b) -{ - if (a == NULL && b == NULL) - return 0; - if (b == NULL) - return +1; - if (a == NULL) - return -1; - if (a->target.type < b->target.type) - return -1; - if (a->target.type > b->target.type) - return +1; - switch (a->target.type) - { - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV: - break; - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6: - if (a->target.ipv6.masksize > b->target.ipv6.masksize) - return +1; - if (a->target.ipv6.masksize < b->target.ipv6.masksize) - return -1; - break; - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: - if (a->target.ipv4.masksize > b->target.ipv4.masksize) - return +1; - if (a->target.ipv4.masksize < b->target.ipv4.masksize) - return -1; - break; - } - return 0; -} - -grub_err_t -grub_net_route_address (grub_net_network_level_address_t addr, - grub_net_network_level_address_t *gateway, - struct grub_net_network_level_interface **interf) -{ - struct grub_net_route *route; - unsigned int depth = 0; - unsigned int routecnt = 0; - struct grub_net_network_level_protocol *prot = NULL; - grub_net_network_level_address_t curtarget = addr; - - *gateway = addr; - - FOR_NET_ROUTES(route) - routecnt++; - - for (depth = 0; depth < routecnt + 2 && depth < GRUB_UINT_MAX; depth++) - { - struct grub_net_route *bestroute = NULL; - FOR_NET_ROUTES(route) - { - if (depth && prot != route->prot) - continue; - if (!match_net (&route->target, &curtarget)) - continue; - if (route_cmp (route, bestroute) > 0) - bestroute = route; - } - if (bestroute == NULL) - return grub_error (GRUB_ERR_NET_NO_ROUTE, - N_("destination unreachable")); - - if (!bestroute->is_gateway) - { - *interf = bestroute->interface; - return GRUB_ERR_NONE; - } - if (depth == 0) - { - *gateway = bestroute->gw; - if (bestroute->interface != NULL) - { - *interf = bestroute->interface; - return GRUB_ERR_NONE; - } - } - curtarget = bestroute->gw; - } - - return grub_error (GRUB_ERR_NET_ROUTE_LOOP, - /* TRANSLATORS: route loop is a condition when e.g. - to contact server A you need to go through B - and to contact B you need to go through A. */ - N_("route loop detected")); -} - -static grub_err_t -grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - struct grub_net_network_level_interface *inter; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - - FOR_NET_NETWORK_LEVEL_INTERFACES (inter) - if (grub_strcmp (inter->name, args[0]) == 0) - break; - if (inter == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("address not found")); - - if (inter->flags & GRUB_NET_INTERFACE_PERMANENT) - return grub_error (GRUB_ERR_IO, - N_("you can't delete this address")); - - grub_net_network_level_interface_unregister (inter); - grub_free (inter->name); - grub_free (inter); - - return GRUB_ERR_NONE; -} - -void -grub_net_addr_to_str (const grub_net_network_level_address_t *target, char *buf) -{ - switch (target->type) - { - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV: - COMPILE_TIME_ASSERT (sizeof ("temporary") < GRUB_NET_MAX_STR_ADDR_LEN); - grub_strcpy (buf, "temporary"); - return; - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6: - { - char *ptr = buf; - grub_uint64_t n = grub_be_to_cpu64 (target->ipv6[0]); - int i; - for (i = 0; i < 4; i++) - { - grub_snprintf (ptr, 6, "%" PRIxGRUB_UINT64_T ":", - (n >> (48 - 16 * i)) & 0xffff); - ptr += grub_strlen (ptr); - } - n = grub_be_to_cpu64 (target->ipv6[1]); - for (i = 0; i < 3; i++) - { - grub_snprintf (ptr, 6, "%" PRIxGRUB_UINT64_T ":", - (n >> (48 - 16 * i)) & 0xffff); - ptr += grub_strlen (ptr); - } - grub_snprintf (ptr, 5, "%" PRIxGRUB_UINT64_T, n & 0xffff); - return; - } - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: - { - grub_uint32_t n = grub_be_to_cpu32 (target->ipv4); - grub_snprintf (buf, GRUB_NET_MAX_STR_ADDR_LEN, "%d.%d.%d.%d", - ((n >> 24) & 0xff), ((n >> 16) & 0xff), - ((n >> 8) & 0xff), ((n >> 0) & 0xff)); - } - return; - } - grub_snprintf (buf, GRUB_NET_MAX_STR_ADDR_LEN, - "Unknown address type %d", target->type); -} - - -void -grub_net_hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str) -{ - str[0] = 0; - switch (addr->type) - { - case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET: - { - char *ptr; - unsigned i; - for (ptr = str, i = 0; i < ARRAY_SIZE (addr->mac); i++) - { - grub_snprintf (ptr, GRUB_NET_MAX_STR_HWADDR_LEN - (ptr - str), - "%02x:", addr->mac[i] & 0xff); - ptr += (sizeof ("XX:") - 1); - } - return; - } - } - grub_printf (_("Unsupported hw address type %d\n"), addr->type); -} - -void -grub_net_vlan_to_str (grub_uint16_t vlantag, char *str) -{ - str[0] = 0; - - /* 12 bits are used to identify the vlan in 802.1Q. */ - vlantag = vlantag & 0x0fff; - - if (vlantag == 0) - return; - - grub_snprintf (str, GRUB_NET_MAX_STR_VLAN_LEN, "vlan%u", vlantag); -} - -int -grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a, - const grub_net_link_level_address_t *b) -{ - if (a->type < b->type) - return -1; - if (a->type > b->type) - return +1; - switch (a->type) - { - case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET: - return grub_memcmp (a->mac, b->mac, sizeof (a->mac)); - } - grub_printf (_("Unsupported hw address type %d\n"), a->type); - return 1; -} - -int -grub_net_addr_cmp (const grub_net_network_level_address_t *a, - const grub_net_network_level_address_t *b) -{ - if (a->type < b->type) - return -1; - if (a->type > b->type) - return +1; - switch (a->type) - { - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: - return grub_memcmp (&a->ipv4, &b->ipv4, sizeof (a->ipv4)); - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6: - return grub_memcmp (&a->ipv6, &b->ipv6, sizeof (a->ipv6)); - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV: - return 0; - } - grub_printf (_("Unsupported address type %d\n"), a->type); - return 1; -} - -/* FIXME: implement this. */ -static char * -hwaddr_set_env (struct grub_env_var *var __attribute__ ((unused)), - const char *val __attribute__ ((unused))) -{ - return NULL; -} - -/* FIXME: implement this. */ -static char * -addr_set_env (struct grub_env_var *var __attribute__ ((unused)), - const char *val __attribute__ ((unused))) -{ - return NULL; -} - -static char * -defserver_set_env (struct grub_env_var *var __attribute__ ((unused)), - const char *val) -{ - grub_free (grub_net_default_server); - grub_net_default_server = grub_strdup (val); - return grub_strdup (val); -} - -static const char * -defserver_get_env (struct grub_env_var *var __attribute__ ((unused)), - const char *val __attribute__ ((unused))) -{ - return grub_net_default_server ? : ""; -} - -static const char * -defip_get_env (struct grub_env_var *var __attribute__ ((unused)), - const char *val __attribute__ ((unused))) -{ - const char *intf = grub_env_get ("net_default_interface"); - const char *ret = NULL; - if (intf) - { - char *buf = grub_xasprintf ("net_%s_ip", intf); - if (buf) - ret = grub_env_get (buf); - grub_free (buf); - } - return ret; -} - -static char * -defip_set_env (struct grub_env_var *var __attribute__ ((unused)), - const char *val) -{ - const char *intf = grub_env_get ("net_default_interface"); - if (intf) - { - char *buf = grub_xasprintf ("net_%s_ip", intf); - if (buf) - grub_env_set (buf, val); - grub_free (buf); - } - return NULL; -} - - -static const char * -defmac_get_env (struct grub_env_var *var __attribute__ ((unused)), - const char *val __attribute__ ((unused))) -{ - const char *intf = grub_env_get ("net_default_interface"); - const char *ret = NULL; - if (intf) - { - char *buf = grub_xasprintf ("net_%s_mac", intf); - if (buf) - ret = grub_env_get (buf); - grub_free (buf); - } - return ret; -} - -static char * -defmac_set_env (struct grub_env_var *var __attribute__ ((unused)), - const char *val) -{ - const char *intf = grub_env_get ("net_default_interface"); - if (intf) - { - char *buf = grub_xasprintf ("net_%s_mac", intf); - if (buf) - grub_env_set (buf, val); - grub_free (buf); - } - return NULL; -} - - -static void -grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter) -{ - { - char buf[GRUB_NET_MAX_STR_HWADDR_LEN]; - char *name; - char *ptr; - grub_net_hwaddr_to_str (&inter->hwaddress, buf); - name = grub_xasprintf ("net_%s_mac", inter->name); - if (!name) - return; - for (ptr = name; *ptr; ptr++) - if (*ptr == ':') - *ptr = '_'; - grub_env_set (name, buf); - grub_register_variable_hook (name, 0, hwaddr_set_env); - grub_env_export (name); - grub_free (name); - } - - { - char buf[GRUB_NET_MAX_STR_ADDR_LEN]; - char *name; - char *ptr; - grub_net_addr_to_str (&inter->address, buf); - name = grub_xasprintf ("net_%s_ip", inter->name); - if (!name) - return; - for (ptr = name; *ptr; ptr++) - if (*ptr == ':') - *ptr = '_'; - grub_env_set (name, buf); - grub_register_variable_hook (name, 0, addr_set_env); - grub_env_export (name); - grub_free (name); - } - - inter->card->num_ifaces++; - inter->prev = &grub_net_network_level_interfaces; - inter->next = grub_net_network_level_interfaces; - if (inter->next) - inter->next->prev = &inter->next; - grub_net_network_level_interfaces = inter; -} - -void -grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) -{ - char *name; - - { - char buf[GRUB_NET_MAX_STR_HWADDR_LEN]; - - grub_net_hwaddr_to_str (&inter->hwaddress, buf); - name = grub_xasprintf ("net_%s_mac", inter->name); - if (name != NULL) - grub_register_variable_hook (name, NULL, NULL); - grub_free (name); - } - - { - char buf[GRUB_NET_MAX_STR_ADDR_LEN]; - - grub_net_addr_to_str (&inter->address, buf); - name = grub_xasprintf ("net_%s_ip", inter->name); - if (name != NULL) - grub_register_variable_hook (name, NULL, NULL); - grub_free (name); - } - - inter->card->num_ifaces--; - *inter->prev = inter->next; - if (inter->next) - inter->next->prev = inter->prev; - inter->next = 0; - inter->prev = 0; -} - -grub_err_t -grub_net_add_ipv4_local (struct grub_net_network_level_interface *inter, - int mask) -{ - grub_uint32_t ip_cpu; - struct grub_net_route *route; - - if (inter->address.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4) - return 0; - - ip_cpu = grub_be_to_cpu32 (inter->address.ipv4); - - if (mask == -1) - { - if (!(ip_cpu & 0x80000000)) - mask = 8; - else if (!(ip_cpu & 0x40000000)) - mask = 16; - else if (!(ip_cpu & 0x20000000)) - mask = 24; - } - if (mask == -1) - return 0; - - route = grub_zalloc (sizeof (*route)); - if (!route) - return grub_errno; - - route->name = grub_xasprintf ("%s:local", inter->name); - if (!route->name) - { - grub_free (route); - return grub_errno; - } - - route->target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - route->target.ipv4.base = grub_cpu_to_be32 (ip_cpu & (0xffffffff << (32 - mask))); - route->target.ipv4.masksize = mask; - route->is_gateway = 0; - route->interface = inter; - - grub_net_route_register (route); - - return 0; -} - -/* FIXME: support MAC specifying. */ -static grub_err_t -grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - struct grub_net_card *card; - grub_net_network_level_address_t addr; - grub_err_t err; - grub_net_interface_flags_t flags = 0; - struct grub_net_network_level_interface *inf; - - if (argc != 3) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("three arguments expected")); - - FOR_NET_CARDS (card) - if (grub_strcmp (card->name, args[1]) == 0) - break; - if (card == NULL) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("card not found")); - - err = grub_net_resolve_address (args[2], &addr); - if (err) - return err; - - if (card->flags & GRUB_NET_CARD_NO_MANUAL_INTERFACES) - return grub_error (GRUB_ERR_IO, - "this card doesn't support address addition"); - - if (card->flags & GRUB_NET_CARD_HWADDRESS_IMMUTABLE) - flags |= GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE; - - inf = grub_net_add_addr (args[0], card, &addr, &card->default_address, - flags); - if (inf) - grub_net_add_ipv4_local (inf, -1); - - return grub_errno; -} - -static grub_err_t -grub_cmd_delroute (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - struct grub_net_route *route; - struct grub_net_route **prev; - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - - for (prev = &grub_net_routes, route = *prev; route; prev = &((*prev)->next), - route = *prev) - if (grub_strcmp (route->name, args[0]) == 0) - { - *prev = route->next; - grub_free (route->name); - grub_free (route); - if (!*prev) - break; - } - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_net_add_route (const char *name, - grub_net_network_level_netaddress_t target, - struct grub_net_network_level_interface *inter) -{ - struct grub_net_route *route; - - route = grub_zalloc (sizeof (*route)); - if (!route) - return grub_errno; - - route->name = grub_strdup (name); - if (!route->name) - { - grub_free (route); - return grub_errno; - } - - route->target = target; - route->is_gateway = 0; - route->interface = inter; - - grub_net_route_register (route); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_net_add_route_gw (const char *name, - grub_net_network_level_netaddress_t target, - grub_net_network_level_address_t gw, - struct grub_net_network_level_interface *inter) -{ - struct grub_net_route *route; - - route = grub_zalloc (sizeof (*route)); - if (!route) - return grub_errno; - - route->name = grub_strdup (name); - if (!route->name) - { - grub_free (route); - return grub_errno; - } - - route->target = target; - route->is_gateway = 1; - route->gw = gw; - route->interface = inter; - - grub_net_route_register (route); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - grub_net_network_level_netaddress_t target; - if (argc < 3) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("three arguments expected")); - - grub_net_resolve_net_address (args[1], &target); - - if (grub_strcmp (args[2], "gw") == 0 && argc >= 4) - { - grub_err_t err; - grub_net_network_level_address_t gw; - - err = grub_net_resolve_address (args[3], &gw); - if (err) - return err; - return grub_net_add_route_gw (args[0], target, gw, NULL); - } - else - { - struct grub_net_network_level_interface *inter; - - FOR_NET_NETWORK_LEVEL_INTERFACES (inter) - if (grub_strcmp (inter->name, args[2]) == 0) - break; - - if (!inter) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unrecognised network interface `%s'"), args[2]); - return grub_net_add_route (args[0], target, inter); - } -} - -static grub_err_t -grub_cmd_setvlan (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - const char *vlan_string, *vlan_string_end; - unsigned long vlantag; - struct grub_net_network_level_interface *inter; - - if (argc != 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); - - vlan_string = args[1]; - vlantag = grub_strtoul (vlan_string, &vlan_string_end, 10); - - if (*vlan_string == '\0' || *vlan_string_end != '\0') - return grub_error (GRUB_ERR_BAD_NUMBER, - N_("non-numeric or invalid number `%s'"), vlan_string); - - if (vlantag > 4094) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("vlan id `%s' not in the valid range of 0-4094"), - vlan_string); - - FOR_NET_NETWORK_LEVEL_INTERFACES (inter) - { - if (grub_strcmp (inter->name, args[0]) != 0) - continue; - - inter->vlantag = vlantag; - return GRUB_ERR_NONE; - } - - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("network interface not found")); -} - -static void -print_net_address (const grub_net_network_level_netaddress_t *target) -{ - switch (target->type) - { - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV: - /* TRANSLATORS: it refers to the network address. */ - grub_printf ("%s\n", _("temporary")); - return; - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: - { - grub_uint32_t n = grub_be_to_cpu32 (target->ipv4.base); - grub_printf ("%d.%d.%d.%d/%d ", ((n >> 24) & 0xff), - ((n >> 16) & 0xff), - ((n >> 8) & 0xff), - ((n >> 0) & 0xff), - target->ipv4.masksize); - } - return; - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6: - { - char buf[GRUB_NET_MAX_STR_ADDR_LEN]; - struct grub_net_network_level_address base; - base.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; - grub_memcpy (&base.ipv6, &target->ipv6, 16); - grub_net_addr_to_str (&base, buf); - grub_printf ("%s/%d ", buf, target->ipv6.masksize); - } - return; - } - grub_printf (_("Unknown address type %d\n"), target->type); -} - -static void -print_address (const grub_net_network_level_address_t *target) -{ - char buf[GRUB_NET_MAX_STR_ADDR_LEN]; - grub_net_addr_to_str (target, buf); - grub_xputs (buf); -} - -static grub_err_t -grub_cmd_listroutes (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - struct grub_net_route *route; - FOR_NET_ROUTES(route) - { - grub_printf ("%s ", route->name); - print_net_address (&route->target); - if (route->is_gateway) - { - grub_printf ("gw "); - print_address (&route->gw); - } - else - grub_printf ("%s", route->interface->name); - grub_printf ("\n"); - } - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_listcards (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - struct grub_net_card *card; - FOR_NET_CARDS(card) - { - char buf[GRUB_NET_MAX_STR_HWADDR_LEN]; - grub_net_hwaddr_to_str (&card->default_address, buf); - grub_printf ("%s %s\n", card->name, buf); - } - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_listaddrs (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - struct grub_net_network_level_interface *inf; - FOR_NET_NETWORK_LEVEL_INTERFACES (inf) - { - char bufh[GRUB_NET_MAX_STR_HWADDR_LEN]; - char bufn[GRUB_NET_MAX_STR_ADDR_LEN]; - char bufv[GRUB_NET_MAX_STR_VLAN_LEN]; - - grub_net_hwaddr_to_str (&inf->hwaddress, bufh); - grub_net_addr_to_str (&inf->address, bufn); - grub_net_vlan_to_str (inf->vlantag, bufv); - grub_printf ("%s %s %s %s\n", inf->name, bufh, bufn, bufv); - } - return GRUB_ERR_NONE; -} - -grub_net_app_level_t grub_net_app_level_list; -struct grub_net_socket *grub_net_sockets; - -static grub_net_t -grub_net_open_real (const char *name) -{ - grub_net_app_level_t proto; - const char *protname, *server; - char *host, *port_start; - grub_size_t protnamelen; - int try; - int port = 0; - - if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0) - { - protname = "tftp"; - protnamelen = sizeof ("tftp") - 1; - server = name + sizeof ("pxe:") - 1; - } - else if (grub_strcmp (name, "pxe") == 0) - { - protname = "tftp"; - protnamelen = sizeof ("tftp") - 1; - server = grub_net_default_server; - } - else - { - const char *comma; - comma = grub_strchr (name, ','); - if (comma) - { - protnamelen = comma - name; - server = comma + 1; - protname = name; - } - else - { - protnamelen = grub_strlen (name); - server = grub_net_default_server; - protname = name; - } - } - if (!server) - { - grub_error (GRUB_ERR_NET_BAD_ADDRESS, - N_("no server is specified")); - return NULL; - } - - /* IPv6 or port specified? */ - if ((port_start = grub_strchr (server, ':'))) - { - char *ipv6_begin; - - if ((ipv6_begin = grub_strchr (server, '['))) - { - char *ipv6_end = grub_strchr (server, ']'); - - if (!ipv6_end) - { - grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("mismatched [ in address")); - return NULL; - } - - /* Port number after bracketed IPv6 addr. */ - if (ipv6_end[1] == ':') - { - port = grub_strtoul (ipv6_end + 2, NULL, 10); - if (port == 0 || port > 65535) - { - grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("bad port number")); - return NULL; - } - } - - host = grub_strndup (ipv6_begin, (ipv6_end - ipv6_begin) + 1); - } - else - { - if (grub_strchr (port_start + 1, ':')) - { - int iplen = grub_strlen (server); - grub_size_t sz; - - /* Bracket bare IPv6 addr. */ - if (grub_add (iplen, 3, &sz)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining length of host")); - return NULL; - } - host = grub_malloc (sz); - if (!host) - return NULL; - - host[0] = '['; - grub_memcpy (host + 1, server, iplen); - host[iplen + 1] = ']'; - host[iplen + 2] = '\0'; - } - else - { - /* hostname:port or IPv4:port */ - port = grub_strtol (port_start + 1, NULL, 10); - if (port == 0 || port > 65535) - { - grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("bad port number")); - return NULL; - } - - host = grub_strndup (server, port_start - server); - } - } - } - else - host = grub_strdup (server); - if (!host) - return NULL; - - for (try = 0; try < 2; try++) - { - FOR_NET_APP_LEVEL (proto) - { - if (grub_memcmp (proto->name, protname, protnamelen) == 0 - && proto->name[protnamelen] == 0) - { - grub_net_t ret = grub_zalloc (sizeof (*ret)); - if (!ret) - { - grub_free (host); - return NULL; - } - ret->protocol = proto; - ret->port = port; - ret->server = host; - ret->fs = &grub_net_fs; - return ret; - } - } - if (try == 0) - { - const char *prefix, *root; - char *prefdev, *comma; - int skip = 0; - grub_size_t devlen; - - /* Do not attempt to load module if it requires protocol provided - by this module - it results in infinite recursion. Just continue, - fail and cleanup on next iteration. - */ - prefix = grub_env_get ("prefix"); - if (!prefix) - continue; - - prefdev = grub_file_get_device_name (prefix); - if (!prefdev) - { - root = grub_env_get ("root"); - if (!root) - continue; - prefdev = grub_strdup (root); - if (!prefdev) - continue; - } - - if (grub_strncmp (prefdev, "pxe", sizeof ("pxe") - 1) == 0 && - (!prefdev[sizeof ("pxe") - 1] || (prefdev[sizeof("pxe") - 1] == ':'))) - { - grub_free (prefdev); - prefdev = grub_strdup ("tftp"); - if (!prefdev) - continue; - } - - comma = grub_strchr (prefdev, ','); - if (comma) - *comma = '\0'; - devlen = grub_strlen (prefdev); - - if (protnamelen == devlen && grub_memcmp (prefdev, protname, devlen) == 0) - skip = 1; - - grub_free (prefdev); - - if (skip) - continue; - - if (sizeof ("http") - 1 == protnamelen - && grub_memcmp ("http", protname, protnamelen) == 0) - { - grub_dl_load ("http"); - grub_errno = GRUB_ERR_NONE; - continue; - } - if (sizeof ("tftp") - 1 == protnamelen - && grub_memcmp ("tftp", protname, protnamelen) == 0) - { - grub_dl_load ("tftp"); - grub_errno = GRUB_ERR_NONE; - continue; - } - } - break; - } - - /* Restore original error. */ - grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("disk `%s' not found"), - name); - - grub_free (host); - return NULL; -} - -static grub_err_t -grub_net_fs_dir (grub_device_t device, const char *path __attribute__ ((unused)), - grub_fs_dir_hook_t hook __attribute__ ((unused)), - void *hook_data __attribute__ ((unused))) -{ - if (!device->net) - return grub_error (GRUB_ERR_BUG, "invalid net device"); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_net_fs_open (struct grub_file *file_out, const char *name) -{ - grub_err_t err; - struct grub_file *file, *bufio; - - file = grub_malloc (sizeof (*file)); - if (!file) - return grub_errno; - - grub_memcpy (file, file_out, sizeof (struct grub_file)); - file->device->net->packs.first = NULL; - file->device->net->packs.last = NULL; - file->device->net->name = grub_strdup (name); - if (!file->device->net->name) - { - grub_free (file); - return grub_errno; - } - - err = file->device->net->protocol->open (file, name); - if (err) - { - while (file->device->net->packs.first) - { - grub_netbuff_free (file->device->net->packs.first->nb); - grub_net_remove_packet (file->device->net->packs.first); - } - grub_free (file->device->net->name); - grub_free (file); - return err; - } - bufio = grub_bufio_open (file, 32768); - if (! bufio) - { - while (file->device->net->packs.first) - { - grub_netbuff_free (file->device->net->packs.first->nb); - grub_net_remove_packet (file->device->net->packs.first); - } - file->device->net->protocol->close (file); - grub_free (file->device->net->name); - grub_free (file); - return grub_errno; - } - - grub_memcpy (file_out, bufio, sizeof (struct grub_file)); - grub_free (bufio); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_net_fs_close (grub_file_t file) -{ - while (file->device->net->packs.first) - { - grub_netbuff_free (file->device->net->packs.first->nb); - grub_net_remove_packet (file->device->net->packs.first); - } - if (!file->device->net->broken) - file->device->net->protocol->close (file); - grub_free (file->device->net->name); - return GRUB_ERR_NONE; -} - -static void -receive_packets (struct grub_net_card *card, int *stop_condition) -{ - int received = 0; - if (card->num_ifaces == 0) - return; - if (!card->opened) - { - grub_err_t err = GRUB_ERR_NONE; - if (card->driver->open) - err = card->driver->open (card); - if (err) - { - grub_errno = GRUB_ERR_NONE; - return; - } - card->opened = 1; - } - while (received < 100) - { - /* Maybe should be better have a fixed number of packets for each card - and just mark them as used and not used. */ - struct grub_net_buff *nb; - - if (received > 10 && stop_condition && *stop_condition) - break; - - nb = card->driver->recv (card); - if (!nb) - { - card->last_poll = grub_get_time_ms (); - break; - } - received++; - grub_net_recv_ethernet_packet (nb, card); - if (grub_errno) - { - grub_dprintf ("net", "error receiving: %d: %s\n", grub_errno, - grub_errmsg); - grub_errno = GRUB_ERR_NONE; - } - } - grub_print_error (); -} - -static char * -grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)), - const char *val __attribute__ ((unused))) -{ - return NULL; -} - -grub_err_t -grub_env_set_net_property (const char *intername, const char *suffix, - const char *value, grub_size_t len) -{ - char *varname, *varvalue; - char *ptr; - grub_size_t sz; - - varname = grub_xasprintf ("net_%s_%s", intername, suffix); - if (!varname) - return grub_errno; - for (ptr = varname; *ptr; ptr++) - if (*ptr == ':') - *ptr = '_'; - if (grub_add (len, 1, &sz)) - { - grub_free (varname); - return grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while obtaining the size of an env variable"); - } - varvalue = grub_malloc (sz); - if (!varvalue) - { - grub_free (varname); - return grub_errno; - } - - grub_memcpy (varvalue, value, len); - varvalue[len] = 0; - grub_err_t ret = grub_env_set (varname, varvalue); - grub_register_variable_hook (varname, 0, grub_env_write_readonly); - grub_env_export (varname); - grub_free (varname); - grub_free (varvalue); - - return ret; -} - -void -grub_net_poll_cards (unsigned time, int *stop_condition) -{ - struct grub_net_card *card; - grub_uint64_t start_time; - start_time = grub_get_time_ms (); - while ((grub_get_time_ms () - start_time) < time - && (!stop_condition || !*stop_condition)) - FOR_NET_CARDS (card) - receive_packets (card, stop_condition); - grub_net_tcp_retransmit (); -} - -static void -grub_net_poll_cards_idle_real (void) -{ - struct grub_net_card *card; - FOR_NET_CARDS (card) - { - grub_uint64_t ctime = grub_get_time_ms (); - - if (ctime < card->last_poll - || ctime >= card->last_poll + card->idle_poll_delay_ms) - receive_packets (card, 0); - } - if (grub_net_cards != NULL) - grub_net_tcp_retransmit (); -} - -/* Read from the packets list*/ -static grub_ssize_t -grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len) -{ - grub_net_t net = file->device->net; - struct grub_net_buff *nb; - char *ptr = buf; - grub_size_t amount, total = 0; - int try = 0; - - while (try <= GRUB_NET_TRIES) - { - while (net->packs.first) - { - try = 0; - nb = net->packs.first->nb; - amount = nb->tail - nb->data; - if (amount > len) - amount = len; - len -= amount; - total += amount; - file->device->net->offset += amount; - if (grub_file_progress_hook) - grub_file_progress_hook (0, 0, amount, NULL, file); - if (buf) - { - grub_memcpy (ptr, nb->data, amount); - ptr += amount; - } - if (amount == (grub_size_t) (nb->tail - nb->data)) - { - grub_netbuff_free (nb); - grub_net_remove_packet (net->packs.first); - } - else - nb->data += amount; - - if (!len) - { - if (net->protocol->packets_pulled) - net->protocol->packets_pulled (file); - return total; - } - } - if (net->protocol->packets_pulled) - net->protocol->packets_pulled (file); - - if (!net->eof) - { - try++; - grub_net_poll_cards (GRUB_NET_INTERVAL + - (try * GRUB_NET_INTERVAL_ADDITION), &net->stall); - } - else - return total; - } - grub_error (GRUB_ERR_TIMEOUT, N_("timeout reading `%s'"), net->name); - return -1; -} - -static grub_off_t -have_ahead (struct grub_file *file) -{ - grub_net_t net = file->device->net; - grub_off_t ret = net->offset; - struct grub_net_packet *pack; - for (pack = net->packs.first; pack; pack = pack->next) - ret += pack->nb->tail - pack->nb->data; - return ret; -} - -static grub_err_t -grub_net_seek_real (struct grub_file *file, grub_off_t offset) -{ - if (offset == file->device->net->offset) - return GRUB_ERR_NONE; - - if (offset > file->device->net->offset) - { - if (!file->device->net->protocol->seek || have_ahead (file) >= offset) - { - grub_net_fs_read_real (file, NULL, - offset - file->device->net->offset); - return grub_errno; - } - return file->device->net->protocol->seek (file, offset); - } - - { - grub_err_t err; - if (file->device->net->protocol->seek) - return file->device->net->protocol->seek (file, offset); - while (file->device->net->packs.first) - { - grub_netbuff_free (file->device->net->packs.first->nb); - grub_net_remove_packet (file->device->net->packs.first); - } - file->device->net->protocol->close (file); - - file->device->net->packs.first = NULL; - file->device->net->packs.last = NULL; - file->device->net->offset = 0; - file->device->net->eof = 0; - file->device->net->stall = 0; - err = file->device->net->protocol->open (file, file->device->net->name); - if (err) - { - file->device->net->broken = 1; - return err; - } - grub_net_fs_read_real (file, NULL, offset); - return grub_errno; - } -} - -static grub_ssize_t -grub_net_fs_read (grub_file_t file, char *buf, grub_size_t len) -{ - if (file->device->net->broken) - return -1; - - if (file->offset != file->device->net->offset) - { - grub_err_t err; - err = grub_net_seek_real (file, file->offset); - if (err) - return err; - } - return grub_net_fs_read_real (file, buf, len); -} - -static struct grub_fs grub_net_fs = - { - .name = "netfs", - .fs_dir = grub_net_fs_dir, - .fs_open = grub_net_fs_open, - .fs_read = grub_net_fs_read, - .fs_close = grub_net_fs_close, - .fs_label = NULL, - .fs_uuid = NULL, - .fs_mtime = NULL, - }; - -static grub_err_t -grub_net_fini_hw (int noreturn __attribute__ ((unused))) -{ - struct grub_net_card *card; - FOR_NET_CARDS (card) - if (card->opened && !(card->flags & GRUB_NET_CARD_NO_CLOSE_ON_FINI_HW)) - { - if (card->driver->close) - card->driver->close (card); - card->opened = 0; - } - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_net_restore_hw (void) -{ - return GRUB_ERR_NONE; -} - -static int -grub_config_search_through (char *config, char *suffix, - grub_size_t num_tries, grub_size_t slice_size) -{ - while (num_tries-- > 0) - { - grub_file_t file; - - grub_dprintf ("net", "attempt to fetch config %s\n", config); - - file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); - - if (file) - { - grub_file_close (file); - return 0; - } - else - { - if (grub_errno == GRUB_ERR_IO) - grub_errno = GRUB_ERR_NONE; - } - - if (grub_strlen (suffix) < slice_size) - break; - - config[grub_strlen (config) - slice_size] = '\0'; - } - - return 1; -} - -grub_err_t -grub_net_search_config_file (char *config, grub_size_t config_buf_len) -{ - grub_size_t config_len, suffix_len; - char *suffix; - - config_len = grub_strlen (config); - config[config_len] = '-'; - suffix = config + config_len + 1; - suffix_len = config_buf_len - (config_len + 1); - - struct grub_net_network_level_interface *inf; - FOR_NET_NETWORK_LEVEL_INTERFACES (inf) - { - /* By the Client UUID. */ - char *ptr; - int client_uuid_len; - char *client_uuid_var; - const char *client_uuid; - - client_uuid_len = sizeof ("net_") + grub_strlen (inf->name) + - sizeof ("_clientuuid") + 1; - - client_uuid_var = grub_zalloc (client_uuid_len); - if (!client_uuid_var) - return grub_errno; - - grub_snprintf (client_uuid_var, client_uuid_len, - "net_%s_clientuuid", inf->name); - - client_uuid = grub_env_get (client_uuid_var); - grub_free (client_uuid_var); - - if (client_uuid) - { - grub_strlcpy (suffix, client_uuid, suffix_len); - if (grub_config_search_through (config, suffix, 1, 0) == 0) - return GRUB_ERR_NONE; - } - - /* By the MAC address. */ - - /* Add ethernet type */ - grub_strcpy (suffix, "01-"); - - grub_net_hwaddr_to_str (&inf->hwaddress, suffix + 3); - - for (ptr = suffix; *ptr; ptr++) - if (*ptr == ':') - *ptr = '-'; - - if (grub_config_search_through (config, suffix, 1, 0) == 0) - return GRUB_ERR_NONE; - - /* By IP address */ - - switch ((&inf->address)->type) - { - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: - { - grub_uint32_t n = grub_be_to_cpu32 ((&inf->address)->ipv4); - - grub_snprintf (suffix, GRUB_NET_MAX_STR_ADDR_LEN, "%02X%02X%02X%02X", \ - ((n >> 24) & 0xff), ((n >> 16) & 0xff), \ - ((n >> 8) & 0xff), ((n >> 0) & 0xff)); - - if (grub_config_search_through (config, suffix, 8, 1) == 0) - return GRUB_ERR_NONE; - break; - } - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6: - { - char buf[GRUB_NET_MAX_STR_ADDR_LEN]; - struct grub_net_network_level_address base; - base.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; - grub_memcpy (&base.ipv6, ((&inf->address)->ipv6), 16); - grub_net_addr_to_str (&base, buf); - - for (ptr = buf; *ptr; ptr++) - if (*ptr == ':') - *ptr = '-'; - - grub_snprintf (suffix, GRUB_NET_MAX_STR_ADDR_LEN, "%s", buf); - if (grub_config_search_through (config, suffix, 1, 0) == 0) - return GRUB_ERR_NONE; - break; - } - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV: - return grub_error (GRUB_ERR_BUG, "shouldn't reach here"); - default: - return grub_error (GRUB_ERR_BUG, - "unsupported address type %d", (&inf->address)->type); - } - } - - /* Remove the remaining minus sign at the end. */ - config[config_len] = '\0'; - - return GRUB_ERR_NONE; -} - -static struct grub_preboot *fini_hnd; - -static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; -static grub_command_t cmd_setvlan, cmd_lsroutes, cmd_lscards; -static grub_command_t cmd_lsaddr, cmd_slaac; - -GRUB_MOD_INIT(net) -{ - grub_register_variable_hook ("net_default_server", defserver_get_env, - defserver_set_env); - grub_env_export ("net_default_server"); - grub_register_variable_hook ("pxe_default_server", defserver_get_env, - defserver_set_env); - grub_env_export ("pxe_default_server"); - grub_register_variable_hook ("net_default_ip", defip_get_env, - defip_set_env); - grub_env_export ("net_default_ip"); - grub_register_variable_hook ("net_default_mac", defmac_get_env, - defmac_set_env); - grub_env_export ("net_default_mac"); - - cmd_addaddr = grub_register_command ("net_add_addr", grub_cmd_addaddr, - /* TRANSLATORS: HWADDRESS stands for - "hardware address". */ - N_("SHORTNAME CARD ADDRESS [HWADDRESS]"), - N_("Add a network address.")); - cmd_slaac = grub_register_command ("net_ipv6_autoconf", - grub_cmd_ipv6_autoconf, - N_("[CARD [HWADDRESS]]"), - N_("Perform an IPV6 autoconfiguration")); - - cmd_deladdr = grub_register_command ("net_del_addr", grub_cmd_deladdr, - N_("SHORTNAME"), - N_("Delete a network address.")); - cmd_addroute = grub_register_command ("net_add_route", grub_cmd_addroute, - /* TRANSLATORS: "gw" is a keyword. */ - N_("SHORTNAME NET [INTERFACE| gw GATEWAY]"), - N_("Add a network route.")); - cmd_delroute = grub_register_command ("net_del_route", grub_cmd_delroute, - N_("SHORTNAME"), - N_("Delete a network route.")); - cmd_setvlan = grub_register_command ("net_set_vlan", grub_cmd_setvlan, - N_("SHORTNAME VLANID"), - N_("Set an interface's vlan id.")); - cmd_lsroutes = grub_register_command ("net_ls_routes", grub_cmd_listroutes, - "", N_("list network routes")); - cmd_lscards = grub_register_command ("net_ls_cards", grub_cmd_listcards, - "", N_("list network cards")); - cmd_lsaddr = grub_register_command ("net_ls_addr", grub_cmd_listaddrs, - "", N_("list network addresses")); - grub_bootp_init (); - grub_dns_init (); - - grub_net_open = grub_net_open_real; - fini_hnd = grub_loader_register_preboot_hook (grub_net_fini_hw, - grub_net_restore_hw, - GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); - grub_net_poll_cards_idle = grub_net_poll_cards_idle_real; -} - -GRUB_MOD_FINI(net) -{ - grub_register_variable_hook ("net_default_server", 0, 0); - grub_register_variable_hook ("pxe_default_server", 0, 0); - grub_register_variable_hook ("net_default_ip", 0, 0); - grub_register_variable_hook ("net_default_mac", 0, 0); - - grub_bootp_fini (); - grub_dns_fini (); - grub_unregister_command (cmd_addaddr); - grub_unregister_command (cmd_deladdr); - grub_unregister_command (cmd_addroute); - grub_unregister_command (cmd_delroute); - grub_unregister_command (cmd_lsroutes); - grub_unregister_command (cmd_lscards); - grub_unregister_command (cmd_lsaddr); - grub_unregister_command (cmd_slaac); - grub_fs_unregister (&grub_net_fs); - grub_net_open = NULL; - grub_net_fini_hw (0); - grub_loader_unregister_preboot_hook (fini_hnd); - grub_net_poll_cards_idle = NULL; -} diff --git a/grub-core/net/netbuff.c b/grub-core/net/netbuff.c deleted file mode 100644 index 8da327bfd..000000000 --- a/grub-core/net/netbuff.c +++ /dev/null @@ -1,146 +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 . - */ - -#include -#include -#include -#include - -grub_err_t -grub_netbuff_put (struct grub_net_buff *nb, grub_size_t len) -{ - nb->tail += len; - if (nb->tail > nb->end) - return grub_error (GRUB_ERR_BUG, "put out of the packet range."); - return GRUB_ERR_NONE; -} - -grub_err_t -grub_netbuff_unput (struct grub_net_buff *nb, grub_size_t len) -{ - nb->tail -= len; - if (nb->tail < nb->head) - return grub_error (GRUB_ERR_BUG, - "unput out of the packet range."); - return GRUB_ERR_NONE; -} - -grub_err_t -grub_netbuff_push (struct grub_net_buff *nb, grub_size_t len) -{ - nb->data -= len; - if (nb->data < nb->head) - return grub_error (GRUB_ERR_BUG, - "push out of the packet range."); - return GRUB_ERR_NONE; -} - -grub_err_t -grub_netbuff_pull (struct grub_net_buff *nb, grub_size_t len) -{ - nb->data += len; - if (nb->data > nb->end || nb->data > nb->tail) - return grub_error (GRUB_ERR_BUG, - "pull out of the packet range."); - return GRUB_ERR_NONE; -} - -grub_err_t -grub_netbuff_reserve (struct grub_net_buff *nb, grub_size_t len) -{ - nb->data += len; - nb->tail += len; - if ((nb->tail > nb->end) || (nb->data > nb->end)) - return grub_error (GRUB_ERR_BUG, - "reserve out of the packet range."); - return GRUB_ERR_NONE; -} - -struct grub_net_buff * -grub_netbuff_alloc (grub_size_t len) -{ - struct grub_net_buff *nb; - void *data; - - COMPILE_TIME_ASSERT (NETBUFF_ALIGN % sizeof (grub_properly_aligned_t) == 0); - - /* - * The largest size of a TCP packet is 64 KiB, and everything else - * should be a lot smaller - most MTUs are 1500 or less. Cap data - * size at 64 KiB + a buffer. - */ - if (len > 0xffffUL + 0x1000UL) - { - grub_error (GRUB_ERR_BUG, - "attempted to allocate a packet that is too big"); - return NULL; - } - - if (len < NETBUFFMINLEN) - len = NETBUFFMINLEN; - - len = ALIGN_UP (len, NETBUFF_ALIGN); - -#ifdef GRUB_MACHINE_EMU - data = grub_malloc (len + sizeof (*nb)); -#else - data = grub_memalign (NETBUFF_ALIGN, len + sizeof (*nb)); -#endif - if (!data) - return NULL; - nb = (struct grub_net_buff *) ((grub_properly_aligned_t *) data - + len / sizeof (grub_properly_aligned_t)); - nb->head = nb->data = nb->tail = data; - nb->end = (grub_uint8_t *) nb; - return nb; -} - -struct grub_net_buff * -grub_netbuff_make_pkt (grub_size_t len) -{ - struct grub_net_buff *nb; - grub_err_t err; - nb = grub_netbuff_alloc (len + 512); - if (!nb) - return NULL; - err = grub_netbuff_reserve (nb, len + 512); - if (err) - goto fail; - err = grub_netbuff_push (nb, len); - if (err) - goto fail; - return nb; - fail: - grub_netbuff_free (nb); - return NULL; -} - -void -grub_netbuff_free (struct grub_net_buff *nb) -{ - if (!nb) - return; - grub_free (nb->head); -} - -grub_err_t -grub_netbuff_clear (struct grub_net_buff *nb) -{ - nb->data = nb->tail = nb->head; - return GRUB_ERR_NONE; -} diff --git a/grub-core/net/tcp.c b/grub-core/net/tcp.c deleted file mode 100644 index 93dee0caa..000000000 --- a/grub-core/net/tcp.c +++ /dev/null @@ -1,1025 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#define TCP_SYN_RETRANSMISSION_TIMEOUT GRUB_NET_INTERVAL -#define TCP_SYN_RETRANSMISSION_COUNT GRUB_NET_TRIES -#define TCP_RETRANSMISSION_TIMEOUT GRUB_NET_INTERVAL -#define TCP_RETRANSMISSION_COUNT GRUB_NET_TRIES - -struct unacked -{ - struct unacked *next; - struct unacked **prev; - struct grub_net_buff *nb; - grub_uint64_t last_try; - int try_count; -}; - -enum - { - TCP_FIN = 0x1, - TCP_SYN = 0x2, - TCP_RST = 0x4, - TCP_PUSH = 0x8, - TCP_ACK = 0x10, - TCP_URG = 0x20, - }; - -struct grub_net_tcp_socket -{ - struct grub_net_tcp_socket *next; - struct grub_net_tcp_socket **prev; - - int established; - int i_closed; - int they_closed; - int in_port; - int out_port; - int errors; - int they_reseted; - int i_reseted; - int i_stall; - grub_uint32_t my_start_seq; - grub_uint32_t my_cur_seq; - grub_uint32_t their_start_seq; - grub_uint32_t their_cur_seq; - grub_uint16_t my_window; - struct unacked *unack_first; - struct unacked *unack_last; - grub_err_t (*recv_hook) (grub_net_tcp_socket_t sock, struct grub_net_buff *nb, - void *recv); - void (*error_hook) (grub_net_tcp_socket_t sock, void *recv); - void (*fin_hook) (grub_net_tcp_socket_t sock, void *recv); - void *hook_data; - grub_net_network_level_address_t out_nla; - grub_net_link_level_address_t ll_target_addr; - struct grub_net_network_level_interface *inf; - grub_net_packets_t packs; - grub_priority_queue_t pq; -}; - -struct grub_net_tcp_listen -{ - struct grub_net_tcp_listen *next; - struct grub_net_tcp_listen **prev; - - grub_uint16_t port; - const struct grub_net_network_level_interface *inf; - - grub_err_t (*listen_hook) (grub_net_tcp_listen_t listen, - grub_net_tcp_socket_t sock, - void *data); - void *hook_data; -}; - -struct tcphdr -{ - grub_uint16_t src; - grub_uint16_t dst; - grub_uint32_t seqnr; - grub_uint32_t ack; - grub_uint16_t flags; - grub_uint16_t window; - grub_uint16_t checksum; - grub_uint16_t urgent; -} GRUB_PACKED; - -struct tcp_pseudohdr -{ - grub_uint32_t src; - grub_uint32_t dst; - grub_uint8_t zero; - grub_uint8_t proto; - grub_uint16_t tcp_length; -} GRUB_PACKED; - -struct tcp6_pseudohdr -{ - grub_uint64_t src[2]; - grub_uint64_t dst[2]; - grub_uint32_t tcp_length; - grub_uint8_t zero[3]; - grub_uint8_t proto; -} GRUB_PACKED; - -static struct grub_net_tcp_socket *tcp_sockets; -static struct grub_net_tcp_listen *tcp_listens; - -#define FOR_TCP_SOCKETS(var) FOR_LIST_ELEMENTS (var, tcp_sockets) -#define FOR_TCP_LISTENS(var) FOR_LIST_ELEMENTS (var, tcp_listens) - -grub_net_tcp_listen_t -grub_net_tcp_listen (grub_uint16_t port, - const struct grub_net_network_level_interface *inf, - grub_err_t (*listen_hook) (grub_net_tcp_listen_t listen, - grub_net_tcp_socket_t sock, - void *data), - void *hook_data) -{ - grub_net_tcp_listen_t ret; - ret = grub_malloc (sizeof (*ret)); - if (!ret) - return NULL; - ret->listen_hook = listen_hook; - ret->hook_data = hook_data; - ret->port = port; - ret->inf = inf; - grub_list_push (GRUB_AS_LIST_P (&tcp_listens), GRUB_AS_LIST (ret)); - return ret; -} - -void -grub_net_tcp_stop_listen (grub_net_tcp_listen_t listen) -{ - grub_list_remove (GRUB_AS_LIST (listen)); -} - -static inline void -tcp_socket_register (grub_net_tcp_socket_t sock) -{ - grub_list_push (GRUB_AS_LIST_P (&tcp_sockets), - GRUB_AS_LIST (sock)); -} - -static void -error (grub_net_tcp_socket_t sock) -{ - struct unacked *unack, *next; - - if (sock->error_hook) - sock->error_hook (sock, sock->hook_data); - - for (unack = sock->unack_first; unack; unack = next) - { - next = unack->next; - grub_netbuff_free (unack->nb); - grub_free (unack); - } - - sock->unack_first = NULL; - sock->unack_last = NULL; -} - -static grub_err_t -tcp_send (struct grub_net_buff *nb, grub_net_tcp_socket_t socket) -{ - grub_err_t err; - grub_uint8_t *nbd; - struct unacked *unack; - struct tcphdr *tcph; - grub_size_t size; - - tcph = (struct tcphdr *) nb->data; - - tcph->seqnr = grub_cpu_to_be32 (socket->my_cur_seq); - size = (nb->tail - nb->data - (grub_be_to_cpu16 (tcph->flags) >> 12) * 4); - if (grub_be_to_cpu16 (tcph->flags) & TCP_FIN) - size++; - socket->my_cur_seq += size; - tcph->src = grub_cpu_to_be16 (socket->in_port); - tcph->dst = grub_cpu_to_be16 (socket->out_port); - tcph->checksum = 0; - tcph->checksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_TCP, - &socket->inf->address, - &socket->out_nla); - nbd = nb->data; - if (size) - { - unack = grub_malloc (sizeof (*unack)); - if (!unack) - return grub_errno; - - unack->next = NULL; - unack->nb = nb; - unack->try_count = 1; - unack->last_try = grub_get_time_ms (); - if (!socket->unack_last) - socket->unack_first = socket->unack_last = unack; - else - socket->unack_last->next = unack; - } - - err = grub_net_send_ip_packet (socket->inf, &(socket->out_nla), - &(socket->ll_target_addr), nb, - GRUB_NET_IP_TCP); - if (err) - return err; - nb->data = nbd; - if (!size) - grub_netbuff_free (nb); - return GRUB_ERR_NONE; -} - -void -grub_net_tcp_close (grub_net_tcp_socket_t sock, - int discard_received) -{ - struct grub_net_buff *nb_fin; - struct tcphdr *tcph_fin; - grub_err_t err; - - if (discard_received != GRUB_NET_TCP_CONTINUE_RECEIVING) - { - sock->recv_hook = NULL; - sock->error_hook = NULL; - sock->fin_hook = NULL; - } - - if (discard_received == GRUB_NET_TCP_ABORT) - sock->i_reseted = 1; - - if (sock->i_closed) - return; - - sock->i_closed = 1; - - nb_fin = grub_netbuff_alloc (sizeof (*tcph_fin) - + GRUB_NET_OUR_MAX_IP_HEADER_SIZE - + GRUB_NET_MAX_LINK_HEADER_SIZE); - if (!nb_fin) - return; - err = grub_netbuff_reserve (nb_fin, GRUB_NET_OUR_MAX_IP_HEADER_SIZE - + GRUB_NET_MAX_LINK_HEADER_SIZE); - if (err) - { - grub_netbuff_free (nb_fin); - grub_dprintf ("net", "error closing socket\n"); - grub_errno = GRUB_ERR_NONE; - return; - } - - err = grub_netbuff_put (nb_fin, sizeof (*tcph_fin)); - if (err) - { - grub_netbuff_free (nb_fin); - grub_dprintf ("net", "error closing socket\n"); - grub_errno = GRUB_ERR_NONE; - return; - } - tcph_fin = (void *) nb_fin->data; - tcph_fin->ack = grub_cpu_to_be32 (sock->their_cur_seq); - tcph_fin->flags = grub_cpu_to_be16_compile_time ((5 << 12) | TCP_FIN - | TCP_ACK); - tcph_fin->window = grub_cpu_to_be16_compile_time (0); - tcph_fin->urgent = 0; - err = tcp_send (nb_fin, sock); - if (err) - { - grub_netbuff_free (nb_fin); - grub_dprintf ("net", "error closing socket\n"); - grub_errno = GRUB_ERR_NONE; - } - return; -} - -static void -ack_real (grub_net_tcp_socket_t sock, int res) -{ - struct grub_net_buff *nb_ack; - struct tcphdr *tcph_ack; - grub_err_t err; - - nb_ack = grub_netbuff_alloc (sizeof (*tcph_ack) + 128); - if (!nb_ack) - return; - err = grub_netbuff_reserve (nb_ack, 128); - if (err) - { - grub_netbuff_free (nb_ack); - grub_dprintf ("net", "error closing socket\n"); - grub_errno = GRUB_ERR_NONE; - return; - } - - err = grub_netbuff_put (nb_ack, sizeof (*tcph_ack)); - if (err) - { - grub_netbuff_free (nb_ack); - grub_dprintf ("net", "error closing socket\n"); - grub_errno = GRUB_ERR_NONE; - return; - } - tcph_ack = (void *) nb_ack->data; - if (res) - { - tcph_ack->ack = grub_cpu_to_be32_compile_time (0); - tcph_ack->flags = grub_cpu_to_be16_compile_time ((5 << 12) | TCP_RST); - tcph_ack->window = grub_cpu_to_be16_compile_time (0); - } - else - { - tcph_ack->ack = grub_cpu_to_be32 (sock->their_cur_seq); - tcph_ack->flags = grub_cpu_to_be16_compile_time ((5 << 12) | TCP_ACK); - tcph_ack->window = !sock->i_stall ? grub_cpu_to_be16 (sock->my_window) - : 0; - } - tcph_ack->urgent = 0; - tcph_ack->src = grub_cpu_to_be16 (sock->in_port); - tcph_ack->dst = grub_cpu_to_be16 (sock->out_port); - err = tcp_send (nb_ack, sock); - if (err) - { - grub_dprintf ("net", "error acking socket\n"); - grub_errno = GRUB_ERR_NONE; - } -} - -static void -ack (grub_net_tcp_socket_t sock) -{ - ack_real (sock, 0); -} - -static void -reset (grub_net_tcp_socket_t sock) -{ - ack_real (sock, 1); -} - -void -grub_net_tcp_retransmit (void) -{ - grub_net_tcp_socket_t sock; - grub_uint64_t ctime = 0, limit_time = 0; - - if (tcp_sockets != NULL) - { - ctime = grub_get_time_ms (); - limit_time = ctime - TCP_RETRANSMISSION_TIMEOUT; - } - - FOR_TCP_SOCKETS (sock) - { - struct unacked *unack; - for (unack = sock->unack_first; unack; unack = unack->next) - { - struct tcphdr *tcph; - grub_uint8_t *nbd; - grub_err_t err; - - if (unack->last_try > limit_time) - continue; - - if (unack->try_count > TCP_RETRANSMISSION_COUNT) - { - error (sock); - break; - } - unack->try_count++; - unack->last_try = ctime; - nbd = unack->nb->data; - tcph = (struct tcphdr *) nbd; - - if ((tcph->flags & grub_cpu_to_be16_compile_time (TCP_ACK)) - && tcph->ack != grub_cpu_to_be32 (sock->their_cur_seq)) - { - tcph->checksum = 0; - tcph->checksum = grub_net_ip_transport_checksum (unack->nb, - GRUB_NET_IP_TCP, - &sock->inf->address, - &sock->out_nla); - } - - err = grub_net_send_ip_packet (sock->inf, &(sock->out_nla), - &(sock->ll_target_addr), unack->nb, - GRUB_NET_IP_TCP); - unack->nb->data = nbd; - if (err) - { - grub_dprintf ("net", "TCP retransmit failed: %s\n", grub_errmsg); - grub_errno = GRUB_ERR_NONE; - } - } - } -} - -grub_uint16_t -grub_net_ip_transport_checksum (struct grub_net_buff *nb, - grub_uint16_t proto, - const grub_net_network_level_address_t *src, - const grub_net_network_level_address_t *dst) -{ - grub_uint16_t a, b = 0; - grub_uint32_t c; - a = ~grub_be_to_cpu16 (grub_net_ip_chksum ((void *) nb->data, - nb->tail - nb->data)); - - switch (dst->type) - { - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: - { - struct tcp_pseudohdr ph; - ph.src = src->ipv4; - ph.dst = dst->ipv4; - ph.zero = 0; - ph.tcp_length = grub_cpu_to_be16 (nb->tail - nb->data); - ph.proto = proto; - b = ~grub_be_to_cpu16 (grub_net_ip_chksum ((void *) &ph, sizeof (ph))); - break; - } - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6: - { - struct tcp6_pseudohdr ph; - grub_memcpy (ph.src, src->ipv6, sizeof (ph.src)); - grub_memcpy (ph.dst, dst->ipv6, sizeof (ph.dst)); - grub_memset (ph.zero, 0, sizeof (ph.zero)); - ph.tcp_length = grub_cpu_to_be32 (nb->tail - nb->data); - ph.proto = proto; - b = ~grub_be_to_cpu16 (grub_net_ip_chksum ((void *) &ph, sizeof (ph))); - break; - } - case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV: - b = 0; - break; - } - c = (grub_uint32_t) a + (grub_uint32_t) b; - if (c >= 0xffff) - c -= 0xffff; - return grub_cpu_to_be16 (~c); -} - -/* FIXME: overflow. */ -static int -cmp (const void *a__, const void *b__) -{ - struct grub_net_buff *a_ = *(struct grub_net_buff **) a__; - struct grub_net_buff *b_ = *(struct grub_net_buff **) b__; - struct tcphdr *a = (struct tcphdr *) a_->data; - struct tcphdr *b = (struct tcphdr *) b_->data; - /* We want the first elements to be on top. */ - if (grub_be_to_cpu32 (a->seqnr) < grub_be_to_cpu32 (b->seqnr)) - return +1; - if (grub_be_to_cpu32 (a->seqnr) > grub_be_to_cpu32 (b->seqnr)) - return -1; - return 0; -} - -static void -destroy_pq (grub_net_tcp_socket_t sock) -{ - struct grub_net_buff **nb_p; - while ((nb_p = grub_priority_queue_top (sock->pq))) - { - grub_netbuff_free (*nb_p); - grub_priority_queue_pop (sock->pq); - } - - grub_priority_queue_destroy (sock->pq); -} - -grub_err_t -grub_net_tcp_accept (grub_net_tcp_socket_t sock, - grub_err_t (*recv_hook) (grub_net_tcp_socket_t sock, - struct grub_net_buff *nb, - void *data), - void (*error_hook) (grub_net_tcp_socket_t sock, - void *data), - void (*fin_hook) (grub_net_tcp_socket_t sock, - void *data), - void *hook_data) -{ - struct grub_net_buff *nb_ack; - struct tcphdr *tcph; - grub_err_t err; - grub_net_network_level_address_t gateway; - struct grub_net_network_level_interface *inf; - - sock->recv_hook = recv_hook; - sock->error_hook = error_hook; - sock->fin_hook = fin_hook; - sock->hook_data = hook_data; - - err = grub_net_route_address (sock->out_nla, &gateway, &inf); - if (err) - return err; - - err = grub_net_link_layer_resolve (sock->inf, &gateway, &(sock->ll_target_addr)); - if (err) - return err; - - nb_ack = grub_netbuff_alloc (sizeof (*tcph) - + GRUB_NET_OUR_MAX_IP_HEADER_SIZE - + GRUB_NET_MAX_LINK_HEADER_SIZE); - if (!nb_ack) - return grub_errno; - err = grub_netbuff_reserve (nb_ack, GRUB_NET_OUR_MAX_IP_HEADER_SIZE - + GRUB_NET_MAX_LINK_HEADER_SIZE); - if (err) - { - grub_netbuff_free (nb_ack); - return err; - } - - err = grub_netbuff_put (nb_ack, sizeof (*tcph)); - if (err) - { - grub_netbuff_free (nb_ack); - return err; - } - tcph = (void *) nb_ack->data; - tcph->ack = grub_cpu_to_be32 (sock->their_cur_seq); - tcph->flags = grub_cpu_to_be16_compile_time ((5 << 12) | TCP_SYN | TCP_ACK); - tcph->window = grub_cpu_to_be16 (sock->my_window); - tcph->urgent = 0; - sock->established = 1; - tcp_socket_register (sock); - err = tcp_send (nb_ack, sock); - if (err) - return err; - sock->my_cur_seq++; - return GRUB_ERR_NONE; -} - -grub_net_tcp_socket_t -grub_net_tcp_open (char *server, - grub_uint16_t out_port, - grub_err_t (*recv_hook) (grub_net_tcp_socket_t sock, - struct grub_net_buff *nb, - void *data), - void (*error_hook) (grub_net_tcp_socket_t sock, - void *data), - void (*fin_hook) (grub_net_tcp_socket_t sock, - void *data), - void *hook_data) -{ - grub_err_t err; - grub_net_network_level_address_t addr; - struct grub_net_network_level_interface *inf; - grub_net_network_level_address_t gateway; - grub_net_tcp_socket_t socket; - static grub_uint16_t in_port = 21550; - struct grub_net_buff *nb; - struct tcphdr *tcph; - int i; - grub_uint8_t *nbd; - grub_net_link_level_address_t ll_target_addr; - - err = grub_net_resolve_address (server, &addr); - if (err) - return NULL; - - if (addr.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 - && addr.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6) - { - grub_error (GRUB_ERR_BUG, "not an IP address"); - return NULL; - } - - err = grub_net_route_address (addr, &gateway, &inf); - if (err) - return NULL; - - err = grub_net_link_layer_resolve (inf, &gateway, &ll_target_addr); - if (err) - return NULL; - - socket = grub_zalloc (sizeof (*socket)); - if (socket == NULL) - return NULL; - - socket->out_port = out_port; - socket->inf = inf; - socket->out_nla = addr; - socket->ll_target_addr = ll_target_addr; - socket->in_port = in_port++; - socket->recv_hook = recv_hook; - socket->error_hook = error_hook; - socket->fin_hook = fin_hook; - socket->hook_data = hook_data; - - nb = grub_netbuff_alloc (sizeof (*tcph) + 128); - if (!nb) - { - grub_free (socket); - return NULL; - } - - err = grub_netbuff_reserve (nb, 128); - if (err) - { - grub_free (socket); - grub_netbuff_free (nb); - return NULL; - } - - err = grub_netbuff_put (nb, sizeof (*tcph)); - if (err) - { - grub_free (socket); - grub_netbuff_free (nb); - return NULL; - } - socket->pq = grub_priority_queue_new (sizeof (struct grub_net_buff *), cmp); - if (!socket->pq) - { - grub_free (socket); - grub_netbuff_free (nb); - return NULL; - } - - tcph = (void *) nb->data; - socket->my_start_seq = grub_get_time_ms (); - socket->my_cur_seq = socket->my_start_seq + 1; - socket->my_window = 8192; - tcph->seqnr = grub_cpu_to_be32 (socket->my_start_seq); - tcph->ack = grub_cpu_to_be32_compile_time (0); - tcph->flags = grub_cpu_to_be16_compile_time ((5 << 12) | TCP_SYN); - tcph->window = grub_cpu_to_be16 (socket->my_window); - tcph->urgent = 0; - tcph->src = grub_cpu_to_be16 (socket->in_port); - tcph->dst = grub_cpu_to_be16 (socket->out_port); - tcph->checksum = 0; - tcph->checksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_TCP, - &socket->inf->address, - &socket->out_nla); - - tcp_socket_register (socket); - - nbd = nb->data; - for (i = 0; i < TCP_SYN_RETRANSMISSION_COUNT; i++) - { - int j; - nb->data = nbd; - err = grub_net_send_ip_packet (socket->inf, &(socket->out_nla), - &(socket->ll_target_addr), nb, - GRUB_NET_IP_TCP); - if (err) - { - grub_list_remove (GRUB_AS_LIST (socket)); - grub_free (socket); - grub_netbuff_free (nb); - return NULL; - } - for (j = 0; (j < TCP_SYN_RETRANSMISSION_TIMEOUT / 50 - && !socket->established); j++) - grub_net_poll_cards (50, &socket->established); - if (socket->established) - break; - } - if (!socket->established) - { - grub_list_remove (GRUB_AS_LIST (socket)); - if (socket->they_reseted) - grub_error (GRUB_ERR_NET_PORT_CLOSED, - N_("connection refused")); - else - grub_error (GRUB_ERR_NET_NO_ANSWER, - N_("connection timeout")); - - grub_netbuff_free (nb); - destroy_pq (socket); - grub_free (socket); - return NULL; - } - - grub_netbuff_free (nb); - return socket; -} - -grub_err_t -grub_net_send_tcp_packet (const grub_net_tcp_socket_t socket, - struct grub_net_buff *nb, int push) -{ - struct tcphdr *tcph; - grub_err_t err; - grub_ssize_t fraglen; - COMPILE_TIME_ASSERT (sizeof (struct tcphdr) == GRUB_NET_TCP_HEADER_SIZE); - if (socket->out_nla.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4) - fraglen = (socket->inf->card->mtu - GRUB_NET_OUR_IPV4_HEADER_SIZE - - sizeof (*tcph)); - else - fraglen = 1280 - GRUB_NET_OUR_IPV6_HEADER_SIZE; - - while (nb->tail - nb->data > fraglen) - { - struct grub_net_buff *nb2; - - nb2 = grub_netbuff_alloc (fraglen + sizeof (*tcph) - + GRUB_NET_OUR_MAX_IP_HEADER_SIZE - + GRUB_NET_MAX_LINK_HEADER_SIZE); - if (!nb2) - return grub_errno; - err = grub_netbuff_reserve (nb2, GRUB_NET_MAX_LINK_HEADER_SIZE - + GRUB_NET_OUR_MAX_IP_HEADER_SIZE); - if (err) - return err; - err = grub_netbuff_put (nb2, sizeof (*tcph)); - if (err) - return err; - - tcph = (struct tcphdr *) nb2->data; - tcph->ack = grub_cpu_to_be32 (socket->their_cur_seq); - tcph->flags = grub_cpu_to_be16_compile_time ((5 << 12) | TCP_ACK); - tcph->window = !socket->i_stall ? grub_cpu_to_be16 (socket->my_window) - : 0; - tcph->urgent = 0; - err = grub_netbuff_put (nb2, fraglen); - if (err) - return err; - grub_memcpy (tcph + 1, nb->data, fraglen); - err = grub_netbuff_pull (nb, fraglen); - if (err) - return err; - - err = tcp_send (nb2, socket); - if (err) - return err; - } - - err = grub_netbuff_push (nb, sizeof (*tcph)); - if (err) - return err; - - tcph = (struct tcphdr *) nb->data; - tcph->ack = grub_cpu_to_be32 (socket->their_cur_seq); - tcph->flags = (grub_cpu_to_be16_compile_time ((5 << 12) | TCP_ACK) - | (push ? grub_cpu_to_be16_compile_time (TCP_PUSH) : 0)); - tcph->window = !socket->i_stall ? grub_cpu_to_be16 (socket->my_window) : 0; - tcph->urgent = 0; - return tcp_send (nb, socket); -} - -grub_err_t -grub_net_recv_tcp_packet (struct grub_net_buff *nb, - struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *source) -{ - struct tcphdr *tcph; - grub_net_tcp_socket_t sock; - grub_err_t err; - - /* Ignore broadcast. */ - if (!inf) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - - tcph = (struct tcphdr *) nb->data; - if ((grub_be_to_cpu16 (tcph->flags) >> 12) < 5) - { - grub_dprintf ("net", "TCP header too short: %u\n", - grub_be_to_cpu16 (tcph->flags) >> 12); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - if (nb->tail - nb->data < (grub_ssize_t) ((grub_be_to_cpu16 (tcph->flags) - >> 12) * sizeof (grub_uint32_t))) - { - grub_dprintf ("net", "TCP packet too short: %" PRIuGRUB_SIZE "\n", - (grub_size_t) (nb->tail - nb->data)); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - - FOR_TCP_SOCKETS (sock) - { - if (!(grub_be_to_cpu16 (tcph->dst) == sock->in_port - && grub_be_to_cpu16 (tcph->src) == sock->out_port - && inf == sock->inf - && grub_net_addr_cmp (source, &sock->out_nla) == 0)) - continue; - if (tcph->checksum) - { - grub_uint16_t chk, expected; - chk = tcph->checksum; - tcph->checksum = 0; - expected = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_TCP, - &sock->out_nla, - &sock->inf->address); - if (expected != chk) - { - grub_dprintf ("net", "Invalid TCP checksum. " - "Expected %x, got %x\n", - grub_be_to_cpu16 (expected), - grub_be_to_cpu16 (chk)); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - tcph->checksum = chk; - } - - if ((grub_be_to_cpu16 (tcph->flags) & TCP_SYN) - && (grub_be_to_cpu16 (tcph->flags) & TCP_ACK) - && !sock->established) - { - sock->their_start_seq = grub_be_to_cpu32 (tcph->seqnr); - sock->their_cur_seq = sock->their_start_seq + 1; - sock->established = 1; - } - - if (grub_be_to_cpu16 (tcph->flags) & TCP_RST) - { - sock->they_reseted = 1; - - error (sock); - - grub_netbuff_free (nb); - - return GRUB_ERR_NONE; - } - - if (grub_be_to_cpu16 (tcph->flags) & TCP_ACK) - { - struct unacked *unack, *next; - grub_uint32_t acked = grub_be_to_cpu32 (tcph->ack); - for (unack = sock->unack_first; unack; unack = next) - { - grub_uint32_t seqnr; - struct tcphdr *unack_tcph; - next = unack->next; - seqnr = grub_be_to_cpu32 (((struct tcphdr *) unack->nb->data) - ->seqnr); - unack_tcph = (struct tcphdr *) unack->nb->data; - seqnr += (unack->nb->tail - unack->nb->data - - (grub_be_to_cpu16 (unack_tcph->flags) >> 12) * 4); - if (grub_be_to_cpu16 (unack_tcph->flags) & TCP_FIN) - seqnr++; - - if (seqnr > acked) - break; - grub_netbuff_free (unack->nb); - grub_free (unack); - } - sock->unack_first = unack; - if (!sock->unack_first) - sock->unack_last = NULL; - } - - if (grub_be_to_cpu32 (tcph->seqnr) < sock->their_cur_seq) - { - ack (sock); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - if (sock->i_reseted && (nb->tail - nb->data - - (grub_be_to_cpu16 (tcph->flags) - >> 12) * sizeof (grub_uint32_t)) > 0) - { - reset (sock); - } - - err = grub_priority_queue_push (sock->pq, &nb); - if (err) - { - grub_netbuff_free (nb); - return err; - } - - { - struct grub_net_buff **nb_top_p, *nb_top; - int do_ack = 0; - int just_closed = 0; - while (1) - { - nb_top_p = grub_priority_queue_top (sock->pq); - if (!nb_top_p) - return GRUB_ERR_NONE; - nb_top = *nb_top_p; - tcph = (struct tcphdr *) nb_top->data; - if (grub_be_to_cpu32 (tcph->seqnr) >= sock->their_cur_seq) - break; - grub_netbuff_free (nb_top); - grub_priority_queue_pop (sock->pq); - } - if (grub_be_to_cpu32 (tcph->seqnr) != sock->their_cur_seq) - { - ack (sock); - return GRUB_ERR_NONE; - } - while (1) - { - nb_top_p = grub_priority_queue_top (sock->pq); - if (!nb_top_p) - break; - nb_top = *nb_top_p; - tcph = (struct tcphdr *) nb_top->data; - - if (grub_be_to_cpu32 (tcph->seqnr) != sock->their_cur_seq) - break; - grub_priority_queue_pop (sock->pq); - - err = grub_netbuff_pull (nb_top, (grub_be_to_cpu16 (tcph->flags) - >> 12) * sizeof (grub_uint32_t)); - if (err) - { - grub_netbuff_free (nb_top); - return err; - } - - sock->their_cur_seq += (nb_top->tail - nb_top->data); - if (grub_be_to_cpu16 (tcph->flags) & TCP_FIN) - { - sock->they_closed = 1; - just_closed = 1; - sock->their_cur_seq++; - do_ack = 1; - } - /* If there is data, puts packet in socket list. */ - if ((nb_top->tail - nb_top->data) > 0) - { - grub_net_put_packet (&sock->packs, nb_top); - do_ack = 1; - } - else - grub_netbuff_free (nb_top); - } - if (do_ack) - ack (sock); - while (sock->packs.first) - { - nb = sock->packs.first->nb; - if (sock->recv_hook) - sock->recv_hook (sock, sock->packs.first->nb, sock->hook_data); - else - grub_netbuff_free (nb); - grub_net_remove_packet (sock->packs.first); - } - - if (sock->fin_hook && just_closed) - sock->fin_hook (sock, sock->hook_data); - } - - return GRUB_ERR_NONE; - } - if (grub_be_to_cpu16 (tcph->flags) & TCP_SYN) - { - grub_net_tcp_listen_t listen; - - FOR_TCP_LISTENS (listen) - { - if (!(grub_be_to_cpu16 (tcph->dst) == listen->port - && (inf == listen->inf || listen->inf == NULL))) - continue; - sock = grub_zalloc (sizeof (*sock)); - if (sock == NULL) - return grub_errno; - - sock->out_port = grub_be_to_cpu16 (tcph->src); - sock->in_port = grub_be_to_cpu16 (tcph->dst); - sock->inf = inf; - sock->out_nla = *source; - sock->their_start_seq = grub_be_to_cpu32 (tcph->seqnr); - sock->their_cur_seq = sock->their_start_seq + 1; - sock->my_cur_seq = sock->my_start_seq = grub_get_time_ms (); - sock->my_window = 8192; - - sock->pq = grub_priority_queue_new (sizeof (struct grub_net_buff *), - cmp); - if (!sock->pq) - { - grub_free (sock); - grub_netbuff_free (nb); - return grub_errno; - } - - err = listen->listen_hook (listen, sock, listen->hook_data); - - grub_netbuff_free (nb); - return err; - - } - } - grub_netbuff_free (nb); - return GRUB_ERR_NONE; -} - -void -grub_net_tcp_stall (grub_net_tcp_socket_t sock) -{ - if (sock->i_stall) - return; - sock->i_stall = 1; - ack (sock); -} - -void -grub_net_tcp_unstall (grub_net_tcp_socket_t sock) -{ - if (!sock->i_stall) - return; - sock->i_stall = 0; - ack (sock); -} diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c deleted file mode 100644 index 336b78691..000000000 --- a/grub-core/net/tftp.c +++ /dev/null @@ -1,494 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* IP port for the MTFTP server used for Intel's PXE */ -enum - { - MTFTP_SERVER_PORT = 75, - MTFTP_CLIENT_PORT = 76, - /* IP port for the TFTP server */ - TFTP_SERVER_PORT = 69 - }; - -enum - { - TFTP_DEFAULTSIZE_PACKET = 512, - }; - -enum - { - TFTP_CODE_EOF = 1, - TFTP_CODE_MORE = 2, - TFTP_CODE_ERROR = 3, - TFTP_CODE_BOOT = 4, - TFTP_CODE_CFG = 5 - }; - -enum - { - TFTP_RRQ = 1, - TFTP_WRQ = 2, - TFTP_DATA = 3, - TFTP_ACK = 4, - TFTP_ERROR = 5, - TFTP_OACK = 6 - }; - -enum - { - TFTP_EUNDEF = 0, /* not defined */ - TFTP_ENOTFOUND = 1, /* file not found */ - TFTP_EACCESS = 2, /* access violation */ - TFTP_ENOSPACE = 3, /* disk full or allocation exceeded */ - TFTP_EBADOP = 4, /* illegal TFTP operation */ - TFTP_EBADID = 5, /* unknown transfer ID */ - TFTP_EEXISTS = 6, /* file already exists */ - TFTP_ENOUSER = 7 /* no such user */ - }; - -struct tftphdr { - grub_uint16_t opcode; - union { - grub_int8_t rrq[TFTP_DEFAULTSIZE_PACKET]; - struct { - grub_uint16_t block; - grub_int8_t download[0]; - } data; - struct { - grub_uint16_t block; - } ack; - struct { - grub_uint16_t errcode; - grub_int8_t errmsg[TFTP_DEFAULTSIZE_PACKET]; - } err; - struct { - grub_int8_t data[TFTP_DEFAULTSIZE_PACKET+2]; - } oack; - } u; -} GRUB_PACKED ; - - -typedef struct tftp_data -{ - grub_uint64_t file_size; - grub_uint64_t block; - grub_uint32_t block_size; - grub_uint64_t ack_sent; - int have_oack; - struct grub_error_saved save_err; - grub_net_udp_socket_t sock; -} *tftp_data_t; - -static grub_err_t -ack (tftp_data_t data, grub_uint64_t block) -{ - struct tftphdr *tftph_ack; - grub_uint8_t nbdata[512]; - struct grub_net_buff nb_ack; - grub_err_t err; - - nb_ack.head = nbdata; - nb_ack.end = nbdata + sizeof (nbdata); - grub_netbuff_clear (&nb_ack); - grub_netbuff_reserve (&nb_ack, 512); - err = grub_netbuff_push (&nb_ack, sizeof (tftph_ack->opcode) - + sizeof (tftph_ack->u.ack.block)); - if (err) - return err; - - tftph_ack = (struct tftphdr *) nb_ack.data; - tftph_ack->opcode = grub_cpu_to_be16_compile_time (TFTP_ACK); - tftph_ack->u.ack.block = grub_cpu_to_be16 (block); - - err = grub_net_send_udp_packet (data->sock, &nb_ack); - if (err) - return err; - data->ack_sent = block; - return GRUB_ERR_NONE; -} - -static grub_err_t -tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)), - struct grub_net_buff *nb, - void *f) -{ - grub_file_t file = f; - struct tftphdr *tftph = (void *) nb->data; - tftp_data_t data = file->data; - grub_err_t err; - grub_uint8_t *ptr; - - if (nb->tail - nb->data < (grub_ssize_t) sizeof (tftph->opcode)) - { - grub_dprintf ("tftp", "TFTP packet too small\n"); - return GRUB_ERR_NONE; - } - - tftph = (struct tftphdr *) nb->data; - switch (grub_be_to_cpu16 (tftph->opcode)) - { - case TFTP_OACK: - data->block_size = TFTP_DEFAULTSIZE_PACKET; - data->have_oack = 1; - for (ptr = nb->data + sizeof (tftph->opcode); ptr < nb->tail;) - { - if (grub_memcmp (ptr, "tsize\0", sizeof ("tsize\0") - 1) == 0) - data->file_size = grub_strtoul ((char *) ptr + sizeof ("tsize\0") - - 1, 0, 0); - if (grub_memcmp (ptr, "blksize\0", sizeof ("blksize\0") - 1) == 0) - data->block_size = grub_strtoul ((char *) ptr + sizeof ("blksize\0") - - 1, 0, 0); - while (ptr < nb->tail && *ptr) - ptr++; - ptr++; - } - data->block = 0; - grub_netbuff_free (nb); - err = ack (data, 0); - grub_error_save (&data->save_err); - return GRUB_ERR_NONE; - case TFTP_DATA: - if (nb->tail - nb->data < (grub_ssize_t) (sizeof (tftph->opcode) - + sizeof (tftph->u.data.block))) - { - grub_dprintf ("tftp", "TFTP packet too small\n"); - return GRUB_ERR_NONE; - } - - /* - * Ack old/retransmitted block. - * - * The block number is a 16-bit counter, thus the maximum file size that - * could be transfered is 65535 * block size. Most TFTP hosts support to - * roll-over the block counter to allow unlimited transfer file size. - * - * This behavior is not defined in the RFC 1350 [0] but is implemented by - * most TFTP clients and hosts. - * - * [0]: https://tools.ietf.org/html/rfc1350 - */ - if (grub_be_to_cpu16 (tftph->u.data.block) < ((grub_uint16_t) (data->block + 1))) - ack (data, grub_be_to_cpu16 (tftph->u.data.block)); - /* Ignore unexpected block. */ - else if (grub_be_to_cpu16 (tftph->u.data.block) > ((grub_uint16_t) (data->block + 1))) - grub_dprintf ("tftp", "TFTP unexpected block # %d\n", tftph->u.data.block); - else - { - unsigned size; - - if (file->device->net->packs.count < 50) - { - err = ack (data, data->block + 1); - if (err) - return err; - } - else - file->device->net->stall = 1; - - err = grub_netbuff_pull (nb, sizeof (tftph->opcode) + - sizeof (tftph->u.data.block)); - if (err) - return err; - size = nb->tail - nb->data; - - data->block++; - if (size < data->block_size) - { - if (data->ack_sent < data->block) - ack (data, data->block); - file->device->net->eof = 1; - file->device->net->stall = 1; - grub_net_udp_close (data->sock); - data->sock = NULL; - } - /* - * Prevent garbage in broken cards. Is it still necessary - * given that IP implementation has been fixed? - */ - if (size > data->block_size) - { - err = grub_netbuff_unput (nb, size - data->block_size); - if (err) - return err; - } - /* If there is data, puts packet in socket list. */ - if ((nb->tail - nb->data) > 0) - { - grub_net_put_packet (&file->device->net->packs, nb); - /* Do not free nb. */ - return GRUB_ERR_NONE; - } - } - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - case TFTP_ERROR: - data->have_oack = 1; - grub_error (GRUB_ERR_IO, "%s", tftph->u.err.errmsg); - grub_error_save (&data->save_err); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - default: - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } -} - -/* - * Create a normalized copy of the filename. Compress any string of consecutive - * forward slashes to a single forward slash. - */ -static void -grub_normalize_filename (char *normalized, const char *filename, int c) -{ - char *dest = normalized; - const char *src = filename; - - while (*src != '\0' && c > 0) - { - if (src[0] == '/' && src[1] == '/') - src++; - else { - c--; - *dest++ = *src++; - } - } - *dest = '\0'; -} - -static grub_err_t -tftp_open (struct grub_file *file, const char *filename) -{ - struct tftphdr *tftph; - char *rrq; - int i; - int rrqlen, rrqsize; - int hdrlen; - grub_uint8_t open_data[1500]; - struct grub_net_buff nb; - tftp_data_t data; - grub_err_t err; - grub_uint8_t *nbd; - grub_net_network_level_address_t addr; - int port = file->device->net->port; - - data = grub_zalloc (sizeof (*data)); - if (!data) - return grub_errno; - - nb.head = open_data; - nb.end = open_data + sizeof (open_data); - grub_netbuff_clear (&nb); - - grub_netbuff_reserve (&nb, 1500); - err = grub_netbuff_push (&nb, sizeof (*tftph)); - if (err) - { - grub_free (data); - return err; - } - - tftph = (struct tftphdr *) nb.data; - - tftph->opcode = grub_cpu_to_be16_compile_time (TFTP_RRQ); - - rrq = (char *) tftph->u.rrq; - rrqsize = sizeof (tftph->u.rrq); - - /* - * Copy and normalize the filename to work-around issues on some TFTP - * servers when file names are being matched for remapping. - */ - grub_normalize_filename (rrq, filename, rrqsize); - - rrqlen = grub_strlen (rrq) + 1; - rrq += grub_strlen (rrq) + 1; - - /* Verify there is enough space for the remaining components. */ - rrqlen += grub_strlen ("octet") + 1; - rrqlen += grub_strlen ("blksize") + 1; - rrqlen += grub_strlen ("1024") + 1; - rrqlen += grub_strlen ("tsize") + 1; - rrqlen += grub_strlen ("0") + 1; - - if (rrqlen >= rrqsize) { - grub_free (data); - return grub_error (GRUB_ERR_BAD_FILENAME, N_("filename too long")); - } - - grub_strcpy (rrq, "octet"); - rrq += grub_strlen ("octet") + 1; - - grub_strcpy (rrq, "blksize"); - rrq += grub_strlen ("blksize") + 1; - - grub_strcpy (rrq, "1024"); - rrq += grub_strlen ("1024") + 1; - - grub_strcpy (rrq, "tsize"); - rrq += grub_strlen ("tsize") + 1; - - grub_strcpy (rrq, "0"); - rrq += grub_strlen ("0") + 1; - hdrlen = sizeof (tftph->opcode) + rrqlen; - - err = grub_netbuff_unput (&nb, nb.tail - (nb.data + hdrlen)); - if (err) - { - grub_free (data); - return err; - } - - file->not_easily_seekable = 1; - file->data = data; - - err = grub_net_resolve_address (file->device->net->server, &addr); - if (err) - { - grub_dprintf ("tftp", "Address resolution failed: %d\n", err); - grub_dprintf ("tftp", "file_size is %" PRIuGRUB_UINT64_T ", block_size is %" PRIuGRUB_UINT32_T "\n", - data->file_size, data->block_size); - grub_free (data); - return err; - } - - data->sock = grub_net_udp_open (addr, - port ? port : TFTP_SERVER_PORT, tftp_receive, - file); - if (!data->sock) - { - grub_free (data); - return grub_errno; - } - - /* Receive OACK packet. */ - nbd = nb.data; - for (i = 0; i < GRUB_NET_TRIES; i++) - { - nb.data = nbd; - err = grub_net_send_udp_packet (data->sock, &nb); - if (err) - { - grub_net_udp_close (data->sock); - grub_free (data); - return err; - } - grub_net_poll_cards (GRUB_NET_INTERVAL + (i * GRUB_NET_INTERVAL_ADDITION), - &data->have_oack); - if (data->have_oack) - break; - } - - if (!data->have_oack) - grub_error (GRUB_ERR_TIMEOUT, N_("time out opening `%s'"), filename); - else - grub_error_load (&data->save_err); - if (grub_errno) - { - grub_net_udp_close (data->sock); - grub_free (data); - file->data = NULL; - return grub_errno; - } - - file->size = data->file_size; - - return GRUB_ERR_NONE; -} - -static grub_err_t -tftp_close (struct grub_file *file) -{ - tftp_data_t data = file->data; - - if (data->sock) - { - grub_uint8_t nbdata[512]; - grub_err_t err; - struct grub_net_buff nb_err; - struct tftphdr *tftph; - - nb_err.head = nbdata; - nb_err.end = nbdata + sizeof (nbdata); - - grub_netbuff_clear (&nb_err); - grub_netbuff_reserve (&nb_err, 512); - err = grub_netbuff_push (&nb_err, sizeof (tftph->opcode) - + sizeof (tftph->u.err.errcode) - + sizeof ("closed")); - if (!err) - { - tftph = (struct tftphdr *) nb_err.data; - tftph->opcode = grub_cpu_to_be16_compile_time (TFTP_ERROR); - tftph->u.err.errcode = grub_cpu_to_be16_compile_time (TFTP_EUNDEF); - grub_memcpy (tftph->u.err.errmsg, "closed", sizeof ("closed")); - - err = grub_net_send_udp_packet (data->sock, &nb_err); - } - if (err) - grub_print_error (); - grub_net_udp_close (data->sock); - } - grub_free (data); - file->data = NULL; - return GRUB_ERR_NONE; -} - -static grub_err_t -tftp_packets_pulled (struct grub_file *file) -{ - tftp_data_t data = file->data; - if (file->device->net->packs.count >= 50) - return 0; - - if (!file->device->net->eof) - file->device->net->stall = 0; - if (data->ack_sent >= data->block) - return 0; - return ack (data, data->block); -} - -static struct grub_net_app_protocol grub_tftp_protocol = - { - .name = "tftp", - .open = tftp_open, - .close = tftp_close, - .packets_pulled = tftp_packets_pulled - }; - -GRUB_MOD_INIT (tftp) -{ - grub_net_app_level_register (&grub_tftp_protocol); -} - -GRUB_MOD_FINI (tftp) -{ - grub_net_app_level_unregister (&grub_tftp_protocol); -} diff --git a/grub-core/net/udp.c b/grub-core/net/udp.c deleted file mode 100644 index 91e2a017a..000000000 --- a/grub-core/net/udp.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include - -struct grub_net_udp_socket -{ - struct grub_net_udp_socket *next; - struct grub_net_udp_socket **prev; - - enum { GRUB_NET_SOCKET_START, - GRUB_NET_SOCKET_ESTABLISHED, - GRUB_NET_SOCKET_CLOSED } status; - int in_port; - int out_port; - grub_err_t (*recv_hook) (grub_net_udp_socket_t sock, struct grub_net_buff *nb, - void *recv); - void *recv_hook_data; - grub_net_network_level_address_t out_nla; - grub_net_link_level_address_t ll_target_addr; - struct grub_net_network_level_interface *inf; -}; - -static struct grub_net_udp_socket *udp_sockets; - -#define FOR_UDP_SOCKETS(var) for (var = udp_sockets; var; var = var->next) - -static inline void -udp_socket_register (grub_net_udp_socket_t sock) -{ - grub_list_push (GRUB_AS_LIST_P (&udp_sockets), - GRUB_AS_LIST (sock)); -} - -void -grub_net_udp_close (grub_net_udp_socket_t sock) -{ - grub_list_remove (GRUB_AS_LIST (sock)); - grub_free (sock); -} - -grub_net_udp_socket_t -grub_net_udp_open (grub_net_network_level_address_t addr, - grub_uint16_t out_port, - grub_err_t (*recv_hook) (grub_net_udp_socket_t sock, - struct grub_net_buff *nb, - void *data), - void *recv_hook_data) -{ - grub_err_t err; - struct grub_net_network_level_interface *inf; - grub_net_network_level_address_t gateway; - grub_net_udp_socket_t socket; - static int in_port = 25300; - grub_net_link_level_address_t ll_target_addr; - - if (addr.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4 - && addr.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6) - { - grub_error (GRUB_ERR_BUG, "not an IP address"); - return NULL; - } - - err = grub_net_route_address (addr, &gateway, &inf); - if (err) - return NULL; - - err = grub_net_link_layer_resolve (inf, &gateway, &ll_target_addr); - if (err) - return NULL; - - socket = grub_zalloc (sizeof (*socket)); - if (socket == NULL) - return NULL; - - socket->out_port = out_port; - socket->inf = inf; - socket->out_nla = addr; - socket->ll_target_addr = ll_target_addr; - socket->in_port = in_port++; - socket->status = GRUB_NET_SOCKET_START; - socket->recv_hook = recv_hook; - socket->recv_hook_data = recv_hook_data; - - udp_socket_register (socket); - - return socket; -} - -grub_err_t -grub_net_send_udp_packet (const grub_net_udp_socket_t socket, - struct grub_net_buff *nb) -{ - struct udphdr *udph; - grub_err_t err; - - COMPILE_TIME_ASSERT (GRUB_NET_UDP_HEADER_SIZE == sizeof (*udph)); - - err = grub_netbuff_push (nb, sizeof (*udph)); - if (err) - return err; - - udph = (struct udphdr *) nb->data; - udph->src = grub_cpu_to_be16 (socket->in_port); - udph->dst = grub_cpu_to_be16 (socket->out_port); - - udph->chksum = 0; - udph->len = grub_cpu_to_be16 (nb->tail - nb->data); - - udph->chksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_UDP, - &socket->inf->address, - &socket->out_nla); - - return grub_net_send_ip_packet (socket->inf, &(socket->out_nla), - &(socket->ll_target_addr), nb, - GRUB_NET_IP_UDP); -} - -grub_err_t -grub_net_recv_udp_packet (struct grub_net_buff *nb, - struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *source) -{ - struct udphdr *udph; - grub_net_udp_socket_t sock; - grub_err_t err; - - /* Ignore broadcast. */ - if (!inf) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - - udph = (struct udphdr *) nb->data; - if (nb->tail - nb->data < (grub_ssize_t) sizeof (*udph)) - { - grub_dprintf ("net", "UDP packet too short: %" PRIuGRUB_SIZE "\n", - (grub_size_t) (nb->tail - nb->data)); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - - FOR_UDP_SOCKETS (sock) - { - if (grub_be_to_cpu16 (udph->dst) == sock->in_port - && inf == sock->inf - && grub_net_addr_cmp (source, &sock->out_nla) == 0 - && (sock->status == GRUB_NET_SOCKET_START - || grub_be_to_cpu16 (udph->src) == sock->out_port)) - { - if (udph->chksum) - { - grub_uint16_t chk, expected; - chk = udph->chksum; - udph->chksum = 0; - expected = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_UDP, - &sock->out_nla, - &sock->inf->address); - if (expected != chk) - { - grub_dprintf ("net", "Invalid UDP checksum. " - "Expected %x, got %x\n", - grub_be_to_cpu16 (expected), - grub_be_to_cpu16 (chk)); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - udph->chksum = chk; - } - - if (sock->status == GRUB_NET_SOCKET_START) - { - sock->out_port = grub_be_to_cpu16 (udph->src); - sock->status = GRUB_NET_SOCKET_ESTABLISHED; - } - - err = grub_netbuff_pull (nb, sizeof (*udph)); - if (err) - return err; - - /* App protocol remove its own reader. */ - if (sock->recv_hook) - sock->recv_hook (sock, nb, sock->recv_hook_data); - else - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - } - grub_netbuff_free (nb); - return GRUB_ERR_NONE; -} diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c deleted file mode 100644 index a321c8438..000000000 --- a/grub-core/normal/charset.c +++ /dev/null @@ -1,1317 +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 . - */ - -/* - Current problems with Unicode rendering: - - B and BN bidi type characters (ignored) - - Mc type characters with combining class 0 (poorly combined) - - Mn type characters with combining class 0 (poorly combined) - - Me type characters with combining class 0 (poorly combined) - - Cf type characters (ignored) - - Cc type characters (ignored) - - Line-breaking rules (e.g. Zs type characters) - - Indic languages - - non-Semitic shaping (rarely used) - - Zl and Zp characters - - Combining characters of types 7, 8, 9, 21, 35, 36, 84, 91, 103, 107, - 118, 122, 129, 130, 132, 218, 224, 226, 233, 234 - - Private use characters (not really a problem) - - Variations (no font support) - - Vertical text - - Ligatures - Font information ignored: - - Kerning - - Justification data - - Glyph posititioning - - Baseline data - Most underline diacritics aren't displayed in gfxterm - */ - -#include -#include -#include -#include -#include -#include -#include - -#if HAVE_FONT_SOURCE -#include "widthspec.h" -#endif - -/* Returns -2 if not enough space, -1 on invalid character. */ -grub_ssize_t -grub_encode_utf8_character (grub_uint8_t *dest, grub_uint8_t *destend, - grub_uint32_t code) -{ - if (dest >= destend) - return -2; - if (code <= 0x007F) - { - *dest++ = code; - return 1; - } - if (code <= 0x07FF) - { - if (dest + 1 >= destend) - return -2; - *dest++ = (code >> 6) | 0xC0; - *dest++ = (code & 0x3F) | 0x80; - return 2; - } - if ((code >= 0xDC00 && code <= 0xDFFF) - || (code >= 0xD800 && code <= 0xDBFF)) - { - /* No surrogates in UCS-4... */ - return -1; - } - if (code < 0x10000) - { - if (dest + 2 >= destend) - return -2; - *dest++ = (code >> 12) | 0xE0; - *dest++ = ((code >> 6) & 0x3F) | 0x80; - *dest++ = (code & 0x3F) | 0x80; - return 3; - } - { - if (dest + 3 >= destend) - return -2; - *dest++ = (code >> 18) | 0xF0; - *dest++ = ((code >> 12) & 0x3F) | 0x80; - *dest++ = ((code >> 6) & 0x3F) | 0x80; - *dest++ = (code & 0x3F) | 0x80; - return 4; - } - -} - -/* Convert UCS-4 to UTF-8. */ -grub_size_t -grub_ucs4_to_utf8 (const grub_uint32_t *src, grub_size_t size, - grub_uint8_t *dest, grub_size_t destsize) -{ - /* Keep last char for \0. */ - grub_uint8_t *destend = dest + destsize - 1; - grub_uint8_t *dest0 = dest; - - while (size-- && dest < destend) - { - grub_uint32_t code = *src++; - grub_ssize_t s; - s = grub_encode_utf8_character (dest, destend, code); - if (s == -2) - break; - if (s == -1) - { - *dest++ = '?'; - continue; - } - dest += s; - } - *dest = 0; - return dest - dest0; -} - -/* Returns the number of bytes the string src would occupy is converted - to UTF-8, excluding trailing \0. */ -grub_size_t -grub_get_num_of_utf8_bytes (const grub_uint32_t *src, grub_size_t size) -{ - grub_size_t remaining; - const grub_uint32_t *ptr; - grub_size_t cnt = 0; - - 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 if (code < 0x10000) - cnt += 3; - else - cnt += 4; - } - return cnt; -} - -/* Convert UCS-4 to UTF-8. */ -char * -grub_ucs4_to_utf8_alloc (const grub_uint32_t *src, grub_size_t size) -{ - grub_uint8_t *ret; - grub_size_t cnt = grub_get_num_of_utf8_bytes (src, size) + 1; - - ret = grub_malloc (cnt); - if (!ret) - return 0; - - grub_ucs4_to_utf8 (src, size, ret, cnt); - - return (char *) ret; -} - -int -grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize) -{ - int count = 0; - grub_uint32_t code = 0; - - while (srcsize) - { - if (srcsize != (grub_size_t)-1) - srcsize--; - if (!grub_utf8_process (*src++, &code, &count)) - return 0; - if (count != 0) - continue; - if (code == 0) - return 1; - if (code > GRUB_UNICODE_LAST_VALID) - return 0; - } - - return 1; -} - -grub_ssize_t -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_calloc (msg_len, sizeof (grub_uint32_t)); - - if (!*unicode_msg) - return -1; - - msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len, - (grub_uint8_t *) msg, -1, 0); - - if (last_position) - *last_position = *unicode_msg + msg_len; - - return msg_len; -} - -/* 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) - { - int was_count = count; - if (srcsize != (grub_size_t)-1) - srcsize--; - if (!grub_utf8_process (*src++, &code, &count)) - { - code = '?'; - count = 0; - /* Character c may be valid, don't eat it. */ - if (was_count) - src--; - } - if (count != 0) - continue; - if (code == 0) - break; - *p++ = code; - destsize--; - } - - if (srcend) - *srcend = src; - return p - dest; -} - -static grub_uint8_t *join_types = NULL; - -static void -unpack_join (void) -{ - unsigned i; - struct grub_unicode_compact_range *cur; - - join_types = grub_zalloc (GRUB_UNICODE_MAX_CACHED_CHAR); - if (!join_types) - { - grub_errno = GRUB_ERR_NONE; - return; - } - for (cur = grub_unicode_compact; cur->len; cur++) - for (i = cur->start; i < cur->start + (unsigned) cur->len - && i < GRUB_UNICODE_MAX_CACHED_CHAR; i++) - join_types[i] = cur->join_type; -} - -static grub_uint8_t *bidi_types = NULL; - -static void -unpack_bidi (void) -{ - unsigned i; - struct grub_unicode_compact_range *cur; - - bidi_types = grub_zalloc (GRUB_UNICODE_MAX_CACHED_CHAR); - if (!bidi_types) - { - grub_errno = GRUB_ERR_NONE; - return; - } - for (cur = grub_unicode_compact; cur->len; cur++) - for (i = cur->start; i < cur->start + (unsigned) cur->len - && i < GRUB_UNICODE_MAX_CACHED_CHAR; i++) - if (cur->bidi_mirror) - bidi_types[i] = cur->bidi_type | 0x80; - else - bidi_types[i] = cur->bidi_type | 0x00; -} - -static inline enum grub_bidi_type -get_bidi_type (grub_uint32_t c) -{ - struct grub_unicode_compact_range *cur; - - if (!bidi_types) - unpack_bidi (); - - if (bidi_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) - return bidi_types[c] & 0x7f; - - for (cur = grub_unicode_compact; cur->len; cur++) - if (cur->start <= c && c < cur->start + (unsigned) cur->len) - return cur->bidi_type; - - return GRUB_BIDI_TYPE_L; -} - -static inline enum grub_join_type -get_join_type (grub_uint32_t c) -{ - struct grub_unicode_compact_range *cur; - - if (!join_types) - unpack_join (); - - if (join_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) - return join_types[c]; - - for (cur = grub_unicode_compact; cur->len; cur++) - if (cur->start <= c && c < cur->start + (unsigned) cur->len) - return cur->join_type; - - return GRUB_JOIN_TYPE_NONJOINING; -} - -static inline int -is_mirrored (grub_uint32_t c) -{ - struct grub_unicode_compact_range *cur; - - if (!bidi_types) - unpack_bidi (); - - if (bidi_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) - return !!(bidi_types[c] & 0x80); - - for (cur = grub_unicode_compact; cur->len; cur++) - if (cur->start <= c && c < cur->start + (unsigned) cur->len) - return cur->bidi_mirror; - - return 0; -} - -enum grub_comb_type -grub_unicode_get_comb_type (grub_uint32_t c) -{ - static grub_uint8_t *comb_types = NULL; - struct grub_unicode_compact_range *cur; - - if (!comb_types) - { - unsigned i; - comb_types = grub_zalloc (GRUB_UNICODE_MAX_CACHED_CHAR); - if (comb_types) - for (cur = grub_unicode_compact; cur->len; cur++) - for (i = cur->start; i < cur->start + (unsigned) cur->len - && i < GRUB_UNICODE_MAX_CACHED_CHAR; i++) - comb_types[i] = cur->comb_type; - else - grub_errno = GRUB_ERR_NONE; - } - - if (comb_types && c < GRUB_UNICODE_MAX_CACHED_CHAR) - return comb_types[c]; - - for (cur = grub_unicode_compact; cur->len; cur++) - if (cur->start <= c && c < cur->start + (unsigned) cur->len) - return cur->comb_type; - - return GRUB_UNICODE_COMB_NONE; -} - -#if HAVE_FONT_SOURCE - -grub_size_t -grub_unicode_estimate_width (const struct grub_unicode_glyph *c) -{ - if (grub_unicode_get_comb_type (c->base)) - return 0; - if (((unsigned long) (c->base >> 3)) >= ARRAY_SIZE (widthspec)) - return 1; - if (widthspec[c->base >> 3] & (1 << (c->base & 7))) - return 2; - else - return 1; -} - -#endif - -static inline int -is_type_after (enum grub_comb_type a, enum grub_comb_type b) -{ - /* Shadda is numerically higher than most of Arabic diacritics but has - to be rendered before them. */ - if (a == GRUB_UNICODE_COMB_ARABIC_SHADDA - && b <= GRUB_UNICODE_COMB_ARABIC_KASRA - && b >= GRUB_UNICODE_COMB_ARABIC_FATHATAN) - return 0; - if (b == GRUB_UNICODE_COMB_ARABIC_SHADDA - && a <= GRUB_UNICODE_COMB_ARABIC_KASRA - && a >= GRUB_UNICODE_COMB_ARABIC_FATHATAN) - return 1; - return a > b; -} - -grub_size_t -grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, - struct grub_unicode_glyph *out) -{ - int haveout = 0; - const grub_uint32_t *ptr; - unsigned last_comb_pointer = 0; - - grub_memset (out, 0, sizeof (*out)); - - if (inlen && grub_iscntrl (*in)) - { - out->base = *in; - out->variant = 0; - out->attributes = 0; - out->ncomb = 0; - out->estimated_width = 1; - return 1; - } - - for (ptr = in; ptr < in + inlen; ptr++) - { - /* Variation selectors >= 17 are outside of BMP and SMP. - Handle variation selectors first to avoid potentially costly lookups. - */ - if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_1 - && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_16) - { - if (haveout) - out->variant = *ptr - GRUB_UNICODE_VARIATION_SELECTOR_1 + 1; - continue; - } - if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_17 - && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_256) - { - if (haveout) - out->variant = *ptr - GRUB_UNICODE_VARIATION_SELECTOR_17 + 17; - continue; - } - - enum grub_comb_type comb_type; - comb_type = grub_unicode_get_comb_type (*ptr); - if (comb_type) - { - struct grub_unicode_combining *n; - unsigned j; - grub_size_t sz; - - if (!haveout) - continue; - - if (out->ncomb == GRUB_UNICODE_NCOMB_MAX) - continue; - - if (comb_type == GRUB_UNICODE_COMB_MC - || comb_type == GRUB_UNICODE_COMB_ME - || comb_type == GRUB_UNICODE_COMB_MN) - last_comb_pointer = out->ncomb; - - if (out->ncomb + 1 <= (int) ARRAY_SIZE (out->combining_inline)) - n = out->combining_inline; - else if (out->ncomb > (int) ARRAY_SIZE (out->combining_inline)) - { - if (grub_add (out->ncomb, 1, &sz) || - grub_mul (sz, sizeof (n[0]), &sz)) - goto fail; - - n = grub_realloc (out->combining_ptr, sz); - if (!n) - { - fail: - grub_errno = GRUB_ERR_NONE; - continue; - } - out->combining_ptr = n; - } - else - { - n = grub_calloc (out->ncomb + 1, sizeof (n[0])); - if (!n) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - grub_memcpy (n, out->combining_inline, - sizeof (out->combining_inline)); - out->combining_ptr = n; - } - - for (j = last_comb_pointer; j < out->ncomb; j++) - if (is_type_after (n[j].type, comb_type)) - break; - grub_memmove (n + j + 1, - n + j, - (out->ncomb - j) - * sizeof (n[0])); - n[j].code = *ptr; - n[j].type = comb_type; - out->ncomb++; - continue; - } - if (haveout) - return ptr - in; - haveout = 1; - out->base = *ptr; - out->variant = 0; - out->attributes = 0; - out->ncomb = 0; - out->estimated_width = 1; - } - return ptr - in; -} - -static void -revert (struct grub_unicode_glyph *visual, - struct grub_term_pos *pos, - unsigned start, unsigned end) -{ - struct grub_unicode_glyph t; - unsigned i; - int a = 0, b = 0; - if (pos) - { - a = pos[visual[start].orig_pos].x; - b = pos[visual[end].orig_pos].x; - } - for (i = 0; i < (end - start) / 2 + 1; i++) - { - t = visual[start + i]; - visual[start + i] = visual[end - i]; - visual[end - i] = t; - - if (pos) - { - pos[visual[start + i].orig_pos].x = a + b - pos[visual[start + i].orig_pos].x; - pos[visual[end - i].orig_pos].x = a + b - pos[visual[end - i].orig_pos].x; - } - } -} - - -static grub_ssize_t -bidi_line_wrap (struct grub_unicode_glyph *visual_out, - struct grub_unicode_glyph *visual, - grub_size_t visual_len, - grub_size_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg), - void *getcharwidth_arg, - grub_size_t maxwidth, grub_size_t startwidth, - grub_uint32_t contchar, - struct grub_term_pos *pos, int primitive_wrap, - grub_size_t log_end) -{ - struct grub_unicode_glyph *outptr = visual_out; - unsigned line_start = 0; - grub_ssize_t line_width; - unsigned k; - grub_ssize_t last_space = -1; - grub_ssize_t last_space_width = 0; - int lines = 0; - - if (!visual_len) - return 0; - - if (startwidth >= maxwidth && (grub_ssize_t) maxwidth > 0) - { - if (contchar) - { - grub_memset (outptr, 0, sizeof (visual[0])); - outptr->base = contchar; - outptr++; - } - grub_memset (outptr, 0, sizeof (visual[0])); - outptr->base = '\n'; - outptr++; - startwidth = 0; - } - - line_width = startwidth; - - for (k = 0; k <= visual_len; k++) - { - grub_ssize_t last_width = 0; - - if (pos && k != visual_len) - { - pos[visual[k].orig_pos].x = line_width; - pos[visual[k].orig_pos].y = lines; - pos[visual[k].orig_pos].valid = 1; - } - - if (k == visual_len && pos) - { - pos[log_end].x = line_width; - pos[log_end].y = lines; - pos[log_end].valid = 1; - } - - if (getcharwidth && k != visual_len) - line_width += last_width = getcharwidth (&visual[k], getcharwidth_arg); - - if (k != visual_len && (visual[k].base == ' ' - || visual[k].base == '\t') - && !primitive_wrap) - { - last_space = k; - last_space_width = line_width; - } - - if (((grub_ssize_t) maxwidth > 0 - && line_width > (grub_ssize_t) maxwidth) || k == visual_len) - { - unsigned min_odd_level = 0xffffffff; - unsigned max_level = 0; - unsigned kk = k; - - lines++; - - if (k != visual_len && last_space > (signed) line_start) - { - kk = last_space; - line_width -= last_space_width; - } - else if (k != visual_len && line_start == 0 && startwidth != 0 - && !primitive_wrap && lines == 1 - && line_width - startwidth < maxwidth) - { - kk = 0; - line_width -= startwidth; - } - else - line_width = last_width; - - { - unsigned i; - for (i = line_start; i < kk; i++) - { - if (visual[i].bidi_level > max_level) - max_level = visual[i].bidi_level; - if (visual[i].bidi_level < min_odd_level && (visual[i].bidi_level & 1)) - min_odd_level = visual[i].bidi_level; - } - } - - { - unsigned j; - /* FIXME: can be optimized. */ - for (j = max_level; j > min_odd_level - 1; j--) - { - unsigned in = line_start; - unsigned i; - for (i = line_start; i < kk; i++) - { - if (i != line_start && visual[i].bidi_level >= j - && visual[i-1].bidi_level < j) - in = i; - if (visual[i].bidi_level >= j && (i + 1 == kk - || visual[i+1].bidi_level < j)) - revert (visual, pos, in, i); - } - } - } - - { - unsigned i; - for (i = line_start; i < kk; i++) - { - if (is_mirrored (visual[i].base) && visual[i].bidi_level) - visual[i].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR; - if ((visual[i].attributes & GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN) - && visual[i].bidi_level) - { - int left, right; - left = visual[i].attributes - & (GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED - | GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT); - right = visual[i].attributes - & (GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED - | GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT); - visual[i].attributes &= ~GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN; - left <<= GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT; - right >>= GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT; - visual[i].attributes |= (left | right); - } - } - } - - { - int left_join = 0; - unsigned i; - for (i = line_start; i < kk; i++) - { - enum grub_join_type join_type = get_join_type (visual[i].base); - if (!(visual[i].attributes - & GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT) - && (join_type == GRUB_JOIN_TYPE_LEFT - || join_type == GRUB_JOIN_TYPE_DUAL)) - { - if (left_join) - visual[i].attributes - |= GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED; - else - visual[i].attributes - &= ~GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED; - } - if (join_type == GRUB_JOIN_TYPE_NONJOINING - || join_type == GRUB_JOIN_TYPE_LEFT) - left_join = 0; - if (join_type == GRUB_JOIN_TYPE_RIGHT - || join_type == GRUB_JOIN_TYPE_DUAL - || join_type == GRUB_JOIN_TYPE_CAUSING) - left_join = 1; - } - } - - { - int right_join = 0; - signed i; - for (i = (signed) kk - 1; i >= 0 && (unsigned) i + 1 > line_start; - i--) - { - enum grub_join_type join_type = get_join_type (visual[i].base); - if (!(visual[i].attributes - & GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT) - && (join_type == GRUB_JOIN_TYPE_RIGHT - || join_type == GRUB_JOIN_TYPE_DUAL)) - { - if (right_join) - visual[i].attributes - |= GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED; - else - visual[i].attributes - &= ~GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED; - } - if (join_type == GRUB_JOIN_TYPE_NONJOINING - || join_type == GRUB_JOIN_TYPE_RIGHT) - right_join = 0; - if (join_type == GRUB_JOIN_TYPE_LEFT - || join_type == GRUB_JOIN_TYPE_DUAL - || join_type == GRUB_JOIN_TYPE_CAUSING) - right_join = 1; - } - } - - grub_memcpy (outptr, &visual[line_start], - (kk - line_start) * sizeof (visual[0])); - outptr += kk - line_start; - if (kk != visual_len) - { - if (contchar) - { - grub_memset (outptr, 0, sizeof (visual[0])); - outptr->base = contchar; - outptr++; - } - grub_memset (outptr, 0, sizeof (visual[0])); - outptr->base = '\n'; - outptr++; - } - - if ((signed) kk == last_space) - kk++; - - line_start = kk; - if (pos && kk != visual_len) - { - pos[visual[kk].orig_pos].x = 0; - pos[visual[kk].orig_pos].y = lines; - } - } - } - - return outptr - visual_out; -} - - -static grub_ssize_t -grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, - grub_size_t logical_len, - struct grub_unicode_glyph *visual_out, - grub_size_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg), - void *getcharwidth_arg, - grub_size_t maxwidth, grub_size_t startwidth, - grub_uint32_t contchar, - struct grub_term_pos *pos, - int primitive_wrap, - grub_size_t log_end) -{ - enum grub_bidi_type type = GRUB_BIDI_TYPE_L; - enum override_status {OVERRIDE_NEUTRAL = 0, OVERRIDE_R, OVERRIDE_L}; - unsigned base_level; - enum override_status cur_override; - unsigned i; - unsigned stack_level[GRUB_BIDI_MAX_EXPLICIT_LEVEL + 3]; - enum override_status stack_override[GRUB_BIDI_MAX_EXPLICIT_LEVEL + 3]; - unsigned stack_depth = 0; - unsigned invalid_pushes = 0; - unsigned visual_len = 0; - unsigned run_start, run_end; - struct grub_unicode_glyph *visual; - unsigned cur_level; - int bidi_needed = 0; - -#define push_stack(new_override, new_level) \ - { \ - if (new_level > GRUB_BIDI_MAX_EXPLICIT_LEVEL) \ - { \ - invalid_pushes++; \ - } \ - else \ - { \ - stack_level[stack_depth] = cur_level; \ - stack_override[stack_depth] = cur_override; \ - stack_depth++; \ - cur_level = new_level; \ - cur_override = new_override; \ - } \ - } - -#define pop_stack() \ - { \ - if (invalid_pushes) \ - { \ - invalid_pushes--; \ - } \ - else if (stack_depth) \ - { \ - stack_depth--; \ - cur_level = stack_level[stack_depth]; \ - cur_override = stack_override[stack_depth]; \ - } \ - } - - visual = grub_calloc (logical_len, sizeof (visual[0])); - if (!visual) - return -1; - - for (i = 0; i < logical_len; i++) - { - type = get_bidi_type (logical[i]); - if (type == GRUB_BIDI_TYPE_L || type == GRUB_BIDI_TYPE_AL - || type == GRUB_BIDI_TYPE_R) - break; - } - if (type == GRUB_BIDI_TYPE_R || type == GRUB_BIDI_TYPE_AL) - base_level = 1; - else - base_level = 0; - - cur_level = base_level; - cur_override = OVERRIDE_NEUTRAL; - { - const grub_uint32_t *lptr; - enum {JOIN_DEFAULT, NOJOIN, JOIN_FORCE} join_state = JOIN_DEFAULT; - int zwj_propagate_to_previous = 0; - for (lptr = logical; lptr < logical + logical_len;) - { - grub_size_t p; - - if (*lptr == GRUB_UNICODE_ZWJ) - { - if (zwj_propagate_to_previous) - { - visual[visual_len - 1].attributes - |= GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT - | GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED; - } - zwj_propagate_to_previous = 0; - join_state = JOIN_FORCE; - lptr++; - continue; - } - - if (*lptr == GRUB_UNICODE_ZWNJ) - { - if (zwj_propagate_to_previous) - { - visual[visual_len - 1].attributes - |= GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT; - visual[visual_len - 1].attributes - &= ~GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED; - } - zwj_propagate_to_previous = 0; - join_state = NOJOIN; - lptr++; - continue; - } - - /* The tags: deprecated, never used. */ - if (*lptr >= GRUB_UNICODE_TAG_START && *lptr <= GRUB_UNICODE_TAG_END) - continue; - - p = grub_unicode_aglomerate_comb (lptr, logical + logical_len - lptr, - &visual[visual_len]); - visual[visual_len].orig_pos = lptr - logical; - type = get_bidi_type (visual[visual_len].base); - switch (type) - { - case GRUB_BIDI_TYPE_RLE: - bidi_needed = 1; - push_stack (cur_override, (cur_level | 1) + 1); - break; - case GRUB_BIDI_TYPE_RLO: - bidi_needed = 1; - push_stack (OVERRIDE_R, (cur_level | 1) + 1); - break; - case GRUB_BIDI_TYPE_LRE: - push_stack (cur_override, (cur_level & ~1) + 2); - break; - case GRUB_BIDI_TYPE_LRO: - push_stack (OVERRIDE_L, (cur_level & ~1) + 2); - break; - case GRUB_BIDI_TYPE_PDF: - pop_stack (); - break; - case GRUB_BIDI_TYPE_BN: - break; - case GRUB_BIDI_TYPE_R: - case GRUB_BIDI_TYPE_AL: - bidi_needed = 1; - /* Fallthrough. */ - default: - { - if (join_state == JOIN_FORCE) - { - visual[visual_len].attributes - |= GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT - | GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED; - } - - if (join_state == NOJOIN) - { - visual[visual_len].attributes - |= GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT; - visual[visual_len].attributes - &= ~GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED; - } - - join_state = JOIN_DEFAULT; - zwj_propagate_to_previous = 1; - - visual[visual_len].bidi_level = cur_level; - if (cur_override != OVERRIDE_NEUTRAL) - visual[visual_len].bidi_type = - (cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L - : GRUB_BIDI_TYPE_R; - else - visual[visual_len].bidi_type = type; - visual_len++; - } - } - lptr += p; - } - } - - if (bidi_needed) - { - for (run_start = 0; run_start < visual_len; run_start = run_end) - { - unsigned prev_level, next_level, cur_run_level; - unsigned last_type, last_strong_type; - for (run_end = run_start; run_end < visual_len && - visual[run_end].bidi_level == visual[run_start].bidi_level; run_end++); - if (run_start == 0) - prev_level = base_level; - else - prev_level = visual[run_start - 1].bidi_level; - if (run_end == visual_len) - next_level = base_level; - else - next_level = visual[run_end].bidi_level; - cur_run_level = visual[run_start].bidi_level; - if (prev_level & 1) - last_type = GRUB_BIDI_TYPE_R; - else - last_type = GRUB_BIDI_TYPE_L; - last_strong_type = last_type; - for (i = run_start; i < run_end; i++) - { - switch (visual[i].bidi_type) - { - case GRUB_BIDI_TYPE_NSM: - visual[i].bidi_type = last_type; - break; - case GRUB_BIDI_TYPE_EN: - if (last_strong_type == GRUB_BIDI_TYPE_AL) - visual[i].bidi_type = GRUB_BIDI_TYPE_AN; - break; - case GRUB_BIDI_TYPE_L: - case GRUB_BIDI_TYPE_R: - last_strong_type = visual[i].bidi_type; - break; - case GRUB_BIDI_TYPE_ES: - if (last_type == GRUB_BIDI_TYPE_EN - && i + 1 < run_end - && visual[i + 1].bidi_type == GRUB_BIDI_TYPE_EN) - visual[i].bidi_type = GRUB_BIDI_TYPE_EN; - else - visual[i].bidi_type = GRUB_BIDI_TYPE_ON; - break; - case GRUB_BIDI_TYPE_ET: - { - unsigned j; - if (last_type == GRUB_BIDI_TYPE_EN) - { - visual[i].bidi_type = GRUB_BIDI_TYPE_EN; - break; - } - for (j = i; j < run_end - && visual[j].bidi_type == GRUB_BIDI_TYPE_ET; j++); - if (j != run_end && visual[j].bidi_type == GRUB_BIDI_TYPE_EN) - { - for (; i < run_end - && visual[i].bidi_type == GRUB_BIDI_TYPE_ET; i++) - visual[i].bidi_type = GRUB_BIDI_TYPE_EN; - i--; - break; - } - for (; i < run_end - && visual[i].bidi_type == GRUB_BIDI_TYPE_ET; i++) - visual[i].bidi_type = GRUB_BIDI_TYPE_ON; - i--; - break; - } - break; - case GRUB_BIDI_TYPE_CS: - if (last_type == GRUB_BIDI_TYPE_EN - && i + 1 < run_end - && visual[i + 1].bidi_type == GRUB_BIDI_TYPE_EN) - { - visual[i].bidi_type = GRUB_BIDI_TYPE_EN; - break; - } - if (last_type == GRUB_BIDI_TYPE_AN - && i + 1 < run_end - && (visual[i + 1].bidi_type == GRUB_BIDI_TYPE_AN - || (visual[i + 1].bidi_type == GRUB_BIDI_TYPE_EN - && last_strong_type == GRUB_BIDI_TYPE_AL))) - { - visual[i].bidi_type = GRUB_BIDI_TYPE_EN; - break; - } - visual[i].bidi_type = GRUB_BIDI_TYPE_ON; - break; - case GRUB_BIDI_TYPE_AL: - last_strong_type = visual[i].bidi_type; - visual[i].bidi_type = GRUB_BIDI_TYPE_R; - break; - default: /* Make GCC happy. */ - break; - } - last_type = visual[i].bidi_type; - if (visual[i].bidi_type == GRUB_BIDI_TYPE_EN - && last_strong_type == GRUB_BIDI_TYPE_L) - visual[i].bidi_type = GRUB_BIDI_TYPE_L; - } - if (prev_level & 1) - last_type = GRUB_BIDI_TYPE_R; - else - last_type = GRUB_BIDI_TYPE_L; - for (i = run_start; i < run_end; ) - { - unsigned j; - unsigned next_type; - for (j = i; j < run_end && - (visual[j].bidi_type == GRUB_BIDI_TYPE_B - || visual[j].bidi_type == GRUB_BIDI_TYPE_S - || visual[j].bidi_type == GRUB_BIDI_TYPE_WS - || visual[j].bidi_type == GRUB_BIDI_TYPE_ON); j++); - if (j == i) - { - if (visual[i].bidi_type == GRUB_BIDI_TYPE_L) - last_type = GRUB_BIDI_TYPE_L; - else - last_type = GRUB_BIDI_TYPE_R; - i++; - continue; - } - if (j == run_end) - next_type = (next_level & 1) ? GRUB_BIDI_TYPE_R : GRUB_BIDI_TYPE_L; - else - { - if (visual[j].bidi_type == GRUB_BIDI_TYPE_L) - next_type = GRUB_BIDI_TYPE_L; - else - next_type = GRUB_BIDI_TYPE_R; - } - if (next_type == last_type) - for (; i < j; i++) - visual[i].bidi_type = last_type; - else - for (; i < j; i++) - visual[i].bidi_type = (cur_run_level & 1) ? GRUB_BIDI_TYPE_R - : GRUB_BIDI_TYPE_L; - } - } - - for (i = 0; i < visual_len; i++) - { - if (!(visual[i].bidi_level & 1) && visual[i].bidi_type == GRUB_BIDI_TYPE_R) - { - visual[i].bidi_level++; - continue; - } - if (!(visual[i].bidi_level & 1) && (visual[i].bidi_type == GRUB_BIDI_TYPE_AN - || visual[i].bidi_type == GRUB_BIDI_TYPE_EN)) - { - visual[i].bidi_level += 2; - continue; - } - if ((visual[i].bidi_level & 1) && (visual[i].bidi_type == GRUB_BIDI_TYPE_L - || visual[i].bidi_type == GRUB_BIDI_TYPE_AN - || visual[i].bidi_type == GRUB_BIDI_TYPE_EN)) - { - visual[i].bidi_level++; - continue; - } - } - } - else - { - for (i = 0; i < visual_len; i++) - visual[i].bidi_level = 0; - } - - { - grub_ssize_t ret; - ret = bidi_line_wrap (visual_out, visual, visual_len, - getcharwidth, getcharwidth_arg, maxwidth, startwidth, contchar, - pos, primitive_wrap, log_end); - grub_free (visual); - return ret; - } -} - -static int -is_visible (const struct grub_unicode_glyph *gl) -{ - if (gl->ncomb) - return 1; - if (gl->base == GRUB_UNICODE_LRM || gl->base == GRUB_UNICODE_RLM) - return 0; - return 1; -} - -grub_ssize_t -grub_bidi_logical_to_visual (const grub_uint32_t *logical, - grub_size_t logical_len, - struct grub_unicode_glyph **visual_out, - grub_size_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg), - void *getcharwidth_arg, - grub_size_t max_length, grub_size_t startwidth, - grub_uint32_t contchar, struct grub_term_pos *pos, int primitive_wrap) -{ - const grub_uint32_t *line_start = logical, *ptr; - struct grub_unicode_glyph *visual_ptr; - *visual_out = visual_ptr = grub_calloc (logical_len + 2, - 3 * sizeof (visual_ptr[0])); - if (!visual_ptr) - return -1; - for (ptr = logical; ptr <= logical + logical_len; ptr++) - { - if (ptr == logical + logical_len || *ptr == '\n') - { - grub_ssize_t ret; - grub_ssize_t i, j; - ret = grub_bidi_line_logical_to_visual (line_start, - ptr - line_start, - visual_ptr, - getcharwidth, - getcharwidth_arg, - max_length, - startwidth, - contchar, - pos, - primitive_wrap, - logical_len); - startwidth = 0; - - if (ret < 0) - { - grub_free (*visual_out); - return ret; - } - for (i = 0, j = 0; i < ret; i++) - if (is_visible(&visual_ptr[i])) - visual_ptr[j++] = visual_ptr[i]; - visual_ptr += j; - line_start = ptr; - if (ptr != logical + logical_len) - { - grub_memset (visual_ptr, 0, sizeof (visual_ptr[0])); - visual_ptr->base = '\n'; - visual_ptr++; - line_start++; - } - } - } - return visual_ptr - *visual_out; -} - -grub_uint32_t -grub_unicode_mirror_code (grub_uint32_t in) -{ - int i; - for (i = 0; grub_unicode_bidi_pairs[i].key; i++) - if (grub_unicode_bidi_pairs[i].key == in) - return grub_unicode_bidi_pairs[i].replace; - return in; -} - -grub_uint32_t -grub_unicode_shape_code (grub_uint32_t in, grub_uint8_t attr) -{ - int i; - if (!(in >= GRUB_UNICODE_ARABIC_START - && in < GRUB_UNICODE_ARABIC_END)) - return in; - - for (i = 0; grub_unicode_arabic_shapes[i].code; i++) - if (grub_unicode_arabic_shapes[i].code == in) - { - grub_uint32_t out = 0; - switch (attr & (GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED - | GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED)) - { - case 0: - out = grub_unicode_arabic_shapes[i].isolated; - break; - case GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED: - out = grub_unicode_arabic_shapes[i].right_linked; - break; - case GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED: - out = grub_unicode_arabic_shapes[i].left_linked; - break; - case GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED - |GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED: - out = grub_unicode_arabic_shapes[i].both_linked; - break; - } - if (out) - return out; - } - - return in; -} - -const grub_uint32_t * -grub_unicode_get_comb_start (const grub_uint32_t *str, - const grub_uint32_t *cur) -{ - const grub_uint32_t *ptr; - for (ptr = cur; ptr >= str; ptr--) - { - if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_1 - && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_16) - continue; - - if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_17 - && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_256) - continue; - - enum grub_comb_type comb_type; - comb_type = grub_unicode_get_comb_type (*ptr); - if (comb_type) - continue; - return ptr; - } - return str; -} - -const grub_uint32_t * -grub_unicode_get_comb_end (const grub_uint32_t *end, - const grub_uint32_t *cur) -{ - const grub_uint32_t *ptr; - for (ptr = cur; ptr < end; ptr++) - { - if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_1 - && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_16) - continue; - - if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_17 - && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_256) - continue; - - enum grub_comb_type comb_type; - comb_type = grub_unicode_get_comb_type (*ptr); - if (comb_type) - continue; - return ptr; - } - return end; -} - diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c deleted file mode 100644 index 96abfda2f..000000000 --- a/grub-core/normal/main.c +++ /dev/null @@ -1,595 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define GRUB_DEFAULT_HISTORY_SIZE 50 - -static int nested_level = 0; -int grub_normal_exit_level = 0; - -void -grub_normal_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_size_t i; - - if (entry->classes) - { - struct grub_menu_entry_class *class; - for (class = entry->classes; class; class = class->next) - grub_free (class->name); - grub_free (entry->classes); - } - - if (entry->args) - { - for (i = 0; entry->args[i]; i++) - grub_free (entry->args[i]); - grub_free (entry->args); - } - - grub_free ((void *) entry->id); - grub_free ((void *) entry->users); - grub_free ((void *) entry->title); - grub_free ((void *) entry->sourcecode); - grub_free (entry); - entry = next_entry; - } - - grub_free (menu); - grub_env_unset_menu (); -} - -/* Helper for read_config_file. */ -static grub_err_t -read_config_file_getline (char **line, int cont __attribute__ ((unused)), - void *data) -{ - grub_file_t file = data; - - while (1) - { - char *buf; - - *line = buf = grub_file_getline (file); - if (! buf) - return grub_errno; - - if (buf[0] == '#') - grub_free (*line); - else - break; - } - - return GRUB_ERR_NONE; -} - -static grub_menu_t -read_config_file (const char *config) -{ - grub_file_t rawfile, file; - char *old_file = 0, *old_dir = 0; - char *config_dir, *ptr = 0; - const char *ctmp; - - 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. */ - rawfile = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); - if (! rawfile) - return 0; - - file = grub_bufio_open (rawfile, 0); - if (! file) - { - grub_file_close (rawfile); - return 0; - } - - ctmp = grub_env_get ("config_file"); - if (ctmp) - old_file = grub_strdup (ctmp); - ctmp = grub_env_get ("config_directory"); - if (ctmp) - old_dir = grub_strdup (ctmp); - if (*config == '(') - { - grub_env_set ("config_file", config); - config_dir = grub_strdup (config); - } - else - { - /* $root is guranteed to be defined, otherwise open above would fail */ - config_dir = grub_xasprintf ("(%s)%s", grub_env_get ("root"), config); - if (config_dir) - grub_env_set ("config_file", config_dir); - } - if (config_dir) - { - ptr = grub_strrchr (config_dir, '/'); - if (ptr) - *ptr = 0; - grub_env_set ("config_directory", config_dir); - grub_free (config_dir); - } - - grub_env_export ("config_file"); - grub_env_export ("config_directory"); - - while (1) - { - char *line; - - /* Print an error, if any. */ - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - - if ((read_config_file_getline (&line, 0, file)) || (! line)) - break; - - grub_normal_parse_line (line, read_config_file_getline, file); - grub_free (line); - } - - if (old_file) - grub_env_set ("config_file", old_file); - else - grub_env_unset ("config_file"); - if (old_dir) - grub_env_set ("config_directory", old_dir); - else - grub_env_unset ("config_directory"); - grub_free (old_file); - grub_free (old_dir); - - grub_file_close (file); - - return newmenu; -} - -/* Initialize the screen. */ -void -grub_normal_init_page (struct grub_term_output *term, - int y) -{ - grub_ssize_t msg_len; - int posx; - char *msg_formatted; - grub_uint32_t *unicode_msg; - grub_uint32_t *last_position; - - grub_term_cls (term); - - msg_formatted = grub_xasprintf (_("GNU GRUB version %s"), 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 = ((int) grub_term_width (term) - posx) / 2; - if (posx < 0) - posx = 0; - grub_term_gotoxy (term, (struct grub_term_coordinate) { posx, y }); - - grub_print_ucs4 (unicode_msg, last_position, 0, 0, term); - grub_putcode ('\n', term); - grub_putcode ('\n', term); - grub_free (unicode_msg); -} - -static void -read_lists (const char *val) -{ - if (! grub_no_modules) - { - read_command_list (val); - read_fs_list (val); - read_crypto_list (val); - read_terminal_list (val); - } - grub_gettext_reread_prefix (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; - - if (! nested) - { - prefix = grub_env_get ("prefix"); - read_lists (prefix); - grub_register_variable_hook ("prefix", NULL, read_lists_hook); - } - - grub_boot_time ("Executing config file"); - - if (config) - { - menu = read_config_file (config); - - /* Ignore any error. */ - grub_errno = GRUB_ERR_NONE; - } - - grub_boot_time ("Executed config file"); - - if (! batch) - { - if (menu && menu->size) - { - - grub_boot_time ("Entering menu"); - grub_show_menu (menu, nested, 0); - if (nested) - grub_normal_free_menu (menu); - } - } -} - -/* This starts the normal mode. */ -void -grub_enter_normal_mode (const char *config) -{ - grub_boot_time ("Entering normal mode"); - nested_level++; - grub_normal_execute (config, 0, 0); - grub_boot_time ("Entering shell"); - grub_cmdline_run (0, 1); - nested_level--; - if (grub_normal_exit_level) - grub_normal_exit_level--; - grub_boot_time ("Exiting normal mode"); -} - -/* 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) - { - grub_size_t config_len; - int disable_net_search = 0; - const char *net_search_cfg; - - config_len = grub_strlen (prefix) + - sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); - config = grub_malloc (config_len); - - if (!config) - goto quit; - - grub_snprintf (config, config_len, "%s/grub.cfg", prefix); - - net_search_cfg = grub_env_get ("feature_net_search_cfg"); - if (net_search_cfg && net_search_cfg[0] == 'n') - disable_net_search = 1; - - if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && - !disable_net_search) - grub_net_search_config_file (config, config_len); - - 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_esc = _("ESC at any time exits."); - char *msg_formatted; - - msg_formatted = grub_xasprintf (_("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. To enable " - "less(1)-like paging, \"set pager=1\". %s"), - nested ? msg_esc : ""); - if (!msg_formatted) - return grub_errno; - - FOR_ACTIVE_TERM_OUTPUTS(term) - { - grub_normal_init_page (term, 1); - grub_term_setcursor (term, 1); - - if (grub_term_width (term) > 3 + STANDARD_MARGIN + 20) - grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN, term); - else - grub_print_message_indented (msg_formatted, 0, 0, term); - grub_putcode ('\n', term); - grub_putcode ('\n', term); - grub_putcode ('\n', term); - } - grub_free (msg_formatted); - - return 0; -} - -static grub_err_t -grub_normal_read_line_real (char **line, int cont, int nested) -{ - const char *prompt; - - if (cont) - /* TRANSLATORS: it's command line prompt. */ - prompt = _(">"); - else - /* TRANSLATORS: it's command line prompt. */ - prompt = _("grub>"); - - if (!prompt) - return grub_errno; - - while (1) - { - *line = grub_cmdline_get (prompt); - if (*line) - return 0; - - if (cont || nested) - { - grub_free (*line); - *line = 0; - return grub_errno; - } - } - -} - -static grub_err_t -grub_normal_read_line (char **line, int cont, - void *data __attribute__ ((unused))) -{ - return grub_normal_read_line_real (line, cont, 0); -} - -void -grub_cmdline_run (int nested, int force_auth) -{ - grub_err_t err = GRUB_ERR_NONE; - - do - { - err = grub_auth_check_authentication (NULL); - } - while (err && force_auth); - - if (err == GRUB_ERR_NONE) - err = grub_auth_check_cli_access (); - - if (err) - { - grub_print_error (); - grub_wait_after_message (); - grub_errno = GRUB_ERR_NONE; - return; - } - - grub_normal_reader_init (nested); - - while (1) - { - char *line = NULL; - - 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_normal_parse_line (line, grub_normal_read_line, NULL); - 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); -} - -/* 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_clear; - -static void (*grub_xputs_saved) (const char *str); -static const char *features[] = { - "feature_chainloader_bpb", "feature_ntldr", "feature_platform_search_hint", - "feature_default_font_path", "feature_all_video_module", - "feature_menuentry_id", "feature_menuentry_options", "feature_200_final", - "feature_nativedisk_cmd", "feature_timeout_style", - "feature_search_cryptodisk_only" -}; - -GRUB_MOD_INIT(normal) -{ - unsigned i; - - grub_boot_time ("Preparing normal module"); - - /* Previously many modules depended on gzio. Be nice to user and load it. */ - grub_dl_load ("gzio"); - grub_errno = 0; - - grub_normal_auth_init (); - grub_context_init (); - grub_script_init (); - grub_menu_init (); - - grub_xputs_saved = grub_xputs; - grub_xputs = grub_xputs_normal; - - /* Normal mode shouldn't be unloaded. */ - if (mod) - grub_dl_ref (mod); - - cmd_clear = - grub_register_command ("clear", grub_mini_cmd_clear, - 0, N_("Clear the screen.")); - - grub_set_history (GRUB_DEFAULT_HISTORY_SIZE); - - grub_register_variable_hook ("pager", 0, grub_env_write_pager); - grub_env_export ("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"); - - /* Set default color names. */ - grub_env_set ("color_normal", "light-gray/black"); - grub_env_set ("color_highlight", "black/light-gray"); - - for (i = 0; i < ARRAY_SIZE (features); i++) - { - grub_env_set (features[i], "y"); - grub_env_export (features[i]); - } - grub_env_set ("grub_cpu", GRUB_TARGET_CPU); - grub_env_export ("grub_cpu"); - grub_env_set ("grub_platform", GRUB_PLATFORM); - grub_env_export ("grub_platform"); - - grub_boot_time ("Normal module prepared"); -} - -GRUB_MOD_FINI(normal) -{ - grub_context_fini (); - grub_script_fini (); - grub_menu_fini (); - grub_normal_auth_fini (); - - grub_xputs = grub_xputs_saved; - - grub_set_history (0); - grub_register_variable_hook ("pager", NULL, NULL); - grub_register_variable_hook ("color_normal", NULL, NULL); - grub_register_variable_hook ("color_highlight", NULL, NULL); - grub_fs_autoload_hook = 0; - grub_unregister_command (cmd_clear); -} diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c deleted file mode 100644 index 9c383e64a..000000000 --- a/grub-core/normal/menu_text.c +++ /dev/null @@ -1,605 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static grub_uint8_t grub_color_menu_normal; -static grub_uint8_t grub_color_menu_highlight; - -struct menu_viewer_data -{ - int first, offset; - struct grub_term_screen_geometry geo; - enum { - TIMEOUT_UNKNOWN, - TIMEOUT_NORMAL, - TIMEOUT_TERSE, - TIMEOUT_TERSE_NO_MARGIN - } timeout_msg; - grub_menu_t menu; - struct grub_term_output *term; -}; - -static inline int -grub_term_cursor_x (const struct grub_term_screen_geometry *geo) -{ - return (geo->first_entry_x + geo->entry_width); -} - -grub_size_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) - { - struct grub_unicode_glyph glyph; - glyph.ncomb = 0; - str += grub_unicode_aglomerate_comb (str, last_position - str, &glyph); - width += grub_term_getcharwidth (term, &glyph); - grub_unicode_destroy_glyph (&glyph); - } - return width; -} - -static int -grub_print_message_indented_real (const char *msg, int margin_left, - int margin_right, - struct grub_term_output *term, int dry_run) -{ - grub_uint32_t *unicode_msg; - grub_uint32_t *last_position; - grub_size_t msg_len = grub_strlen (msg) + 2; - int ret = 0; - - unicode_msg = grub_calloc (msg_len, sizeof (grub_uint32_t)); - - if (!unicode_msg) - return 0; - - msg_len = grub_utf8_to_ucs4 (unicode_msg, msg_len, - (grub_uint8_t *) msg, -1, 0); - - last_position = unicode_msg + msg_len; - *last_position = 0; - - if (dry_run) - ret = grub_ucs4_count_lines (unicode_msg, last_position, margin_left, - margin_right, term); - else - grub_print_ucs4_menu (unicode_msg, last_position, margin_left, - margin_right, term, 0, -1, 0, 0); - - grub_free (unicode_msg); - - return ret; -} - -void -grub_print_message_indented (const char *msg, int margin_left, int margin_right, - struct grub_term_output *term) -{ - grub_print_message_indented_real (msg, margin_left, margin_right, term, 0); -} - -static void -draw_border (struct grub_term_output *term, const struct grub_term_screen_geometry *geo) -{ - int i; - - grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); - - grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1, - geo->first_entry_y - 1 }); - grub_putcode (GRUB_UNICODE_CORNER_UL, term); - for (i = 0; i < geo->entry_width + 1; i++) - grub_putcode (GRUB_UNICODE_HLINE, term); - grub_putcode (GRUB_UNICODE_CORNER_UR, term); - - for (i = 0; i < geo->num_entries; i++) - { - grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1, - geo->first_entry_y + i }); - grub_putcode (GRUB_UNICODE_VLINE, term); - grub_term_gotoxy (term, - (struct grub_term_coordinate) { geo->first_entry_x + geo->entry_width + 1, - geo->first_entry_y + i }); - grub_putcode (GRUB_UNICODE_VLINE, term); - } - - grub_term_gotoxy (term, - (struct grub_term_coordinate) { geo->first_entry_x - 1, - geo->first_entry_y - 1 + geo->num_entries + 1 }); - grub_putcode (GRUB_UNICODE_CORNER_LL, term); - for (i = 0; i < geo->entry_width + 1; i++) - grub_putcode (GRUB_UNICODE_HLINE, term); - grub_putcode (GRUB_UNICODE_CORNER_LR, term); - - grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); - - grub_term_gotoxy (term, - (struct grub_term_coordinate) { geo->first_entry_x - 1, - (geo->first_entry_y - 1 + geo->num_entries - + GRUB_TERM_MARGIN + 1) }); -} - -static int -print_message (int nested, int edit, struct grub_term_output *term, int dry_run) -{ - int ret = 0; - grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); - - if (edit) - { - ret += grub_print_message_indented_real (_("Minimum Emacs-like screen editing is \ -supported. TAB lists completions. Press Ctrl-x or F10 to boot, Ctrl-c or F2 for a \ -command-line or ESC to discard edits and return to the GRUB menu."), - STANDARD_MARGIN, STANDARD_MARGIN, - term, dry_run); - } - else - { - char *msg_translated; - - msg_translated = grub_xasprintf (_("Use the %C and %C keys to select which " - "entry is highlighted."), - GRUB_UNICODE_UPARROW, - GRUB_UNICODE_DOWNARROW); - if (!msg_translated) - return 0; - ret += grub_print_message_indented_real (msg_translated, STANDARD_MARGIN, - STANDARD_MARGIN, term, dry_run); - - grub_free (msg_translated); - - if (!grub_is_cli_disabled ()) - { - if (nested) - { - ret += grub_print_message_indented_real - (_("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."), - STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); - } - else - { - ret += grub_print_message_indented_real - (_("Press enter to boot the selected OS, " - "`e' to edit the commands before booting " - "or `c' for a command-line."), - STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); - } - } - } - return ret; -} - -static void -print_entry (int y, int highlight, grub_menu_entry_t entry, - const struct menu_viewer_data *data) -{ - 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_calloc (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; - } - - old_color_normal = grub_term_normal_color; - old_color_highlight = grub_term_highlight_color; - grub_term_normal_color = grub_color_menu_normal; - grub_term_highlight_color = grub_color_menu_highlight; - grub_term_setcolorstate (data->term, highlight - ? GRUB_TERM_COLOR_HIGHLIGHT - : GRUB_TERM_COLOR_NORMAL); - - grub_term_gotoxy (data->term, (struct grub_term_coordinate) { - data->geo.first_entry_x, y }); - - for (i = 0; i < len; i++) - if (unicode_title[i] == '\n' || unicode_title[i] == '\b' - || unicode_title[i] == '\r' || unicode_title[i] == '\e') - unicode_title[i] = ' '; - - if (data->geo.num_entries > 1) - grub_putcode (highlight ? '*' : ' ', data->term); - - grub_print_ucs4_menu (unicode_title, - unicode_title + len, - 0, - data->geo.right_margin, - data->term, 0, 1, - GRUB_UNICODE_RIGHTARROW, 0); - - grub_term_setcolorstate (data->term, GRUB_TERM_COLOR_NORMAL); - grub_term_gotoxy (data->term, - (struct grub_term_coordinate) { - grub_term_cursor_x (&data->geo), y }); - - grub_term_normal_color = old_color_normal; - grub_term_highlight_color = old_color_highlight; - - grub_term_setcolorstate (data->term, GRUB_TERM_COLOR_NORMAL); - grub_free (unicode_title); -} - -static void -print_entries (grub_menu_t menu, const struct menu_viewer_data *data) -{ - grub_menu_entry_t e; - int i; - - grub_term_gotoxy (data->term, - (struct grub_term_coordinate) { - data->geo.first_entry_x + data->geo.entry_width - + data->geo.border + 1, - data->geo.first_entry_y }); - - if (data->geo.num_entries != 1) - { - if (data->first) - grub_putcode (GRUB_UNICODE_UPARROW, data->term); - else - grub_putcode (' ', data->term); - } - e = grub_menu_get_entry (menu, data->first); - - for (i = 0; i < data->geo.num_entries; i++) - { - print_entry (data->geo.first_entry_y + i, data->offset == i, - e, data); - if (e) - e = e->next; - } - - grub_term_gotoxy (data->term, - (struct grub_term_coordinate) { data->geo.first_entry_x + data->geo.entry_width - + data->geo.border + 1, - data->geo.first_entry_y + data->geo.num_entries - 1 }); - if (data->geo.num_entries == 1) - { - if (data->first && e) - grub_putcode (GRUB_UNICODE_UPDOWNARROW, data->term); - else if (data->first) - grub_putcode (GRUB_UNICODE_UPARROW, data->term); - else if (e) - grub_putcode (GRUB_UNICODE_DOWNARROW, data->term); - else - grub_putcode (' ', data->term); - } - else - { - if (e) - grub_putcode (GRUB_UNICODE_DOWNARROW, data->term); - else - grub_putcode (' ', data->term); - } - - grub_term_gotoxy (data->term, - (struct grub_term_coordinate) { grub_term_cursor_x (&data->geo), - data->geo.first_entry_y + data->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_screen_geometry *geo, - struct grub_term_output *term) -{ - grub_uint8_t old_color_normal, old_color_highlight; - int msg_num_lines; - int bottom_message = 1; - int empty_lines = 1; - int version_msg = 1; - - geo->border = 1; - geo->first_entry_x = 1 /* margin */ + 1 /* border */; - geo->entry_width = grub_term_width (term) - 5; - - geo->first_entry_y = 2 /* two empty lines*/ - + 1 /* GNU GRUB version text */ + 1 /* top border */; - - geo->timeout_lines = 2; - - /* 3 lines for timeout message and bottom margin. 2 lines for the border. */ - geo->num_entries = grub_term_height (term) - geo->first_entry_y - - 1 /* bottom border */ - - 1 /* empty line before info message*/ - - geo->timeout_lines /* timeout */ - - 1 /* empty final line */; - msg_num_lines = print_message (nested, edit, term, 1); - if (geo->num_entries - msg_num_lines < 3 - || geo->entry_width < 10) - { - geo->num_entries += 4; - geo->first_entry_y -= 2; - empty_lines = 0; - geo->first_entry_x -= 1; - geo->entry_width += 1; - } - if (geo->num_entries - msg_num_lines < 3 - || geo->entry_width < 10) - { - geo->num_entries += 2; - geo->first_entry_y -= 1; - geo->first_entry_x -= 1; - geo->entry_width += 2; - geo->border = 0; - } - - if (geo->entry_width <= 0) - geo->entry_width = 1; - - if (geo->num_entries - msg_num_lines < 3 - && geo->timeout_lines == 2) - { - geo->timeout_lines = 1; - geo->num_entries++; - } - - if (geo->num_entries - msg_num_lines < 3) - { - geo->num_entries += 1; - geo->first_entry_y -= 1; - version_msg = 0; - } - - if (geo->num_entries - msg_num_lines >= 2) - geo->num_entries -= msg_num_lines; - else - bottom_message = 0; - - /* By default, use the same colors for the menu. */ - old_color_normal = grub_term_normal_color; - old_color_highlight = grub_term_highlight_color; - grub_color_menu_normal = grub_term_normal_color; - grub_color_menu_highlight = grub_term_highlight_color; - - /* 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")); - - if (version_msg) - grub_normal_init_page (term, empty_lines); - else - grub_term_cls (term); - - grub_term_normal_color = grub_color_menu_normal; - grub_term_highlight_color = grub_color_menu_highlight; - if (geo->border) - draw_border (term, geo); - grub_term_normal_color = old_color_normal; - grub_term_highlight_color = old_color_highlight; - geo->timeout_y = geo->first_entry_y + geo->num_entries - + geo->border + empty_lines; - if (bottom_message) - { - grub_term_gotoxy (term, - (struct grub_term_coordinate) { GRUB_TERM_MARGIN, - geo->timeout_y }); - - print_message (nested, edit, term, 0); - geo->timeout_y += msg_num_lines; - } - geo->right_margin = grub_term_width (term) - - geo->first_entry_x - - geo->entry_width - 1; -} - -static void -menu_text_print_timeout (int timeout, void *dataptr) -{ - struct menu_viewer_data *data = dataptr; - char *msg_translated = 0; - - grub_term_gotoxy (data->term, - (struct grub_term_coordinate) { 0, data->geo.timeout_y }); - - if (data->timeout_msg == TIMEOUT_TERSE - || data->timeout_msg == TIMEOUT_TERSE_NO_MARGIN) - msg_translated = grub_xasprintf (_("%ds"), timeout); - else - msg_translated = grub_xasprintf (_("The highlighted entry will be executed automatically in %ds."), timeout); - if (!msg_translated) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - return; - } - - if (data->timeout_msg == TIMEOUT_UNKNOWN) - { - data->timeout_msg = grub_print_message_indented_real (msg_translated, - 3, 1, data->term, 1) - <= data->geo.timeout_lines ? TIMEOUT_NORMAL : TIMEOUT_TERSE; - if (data->timeout_msg == TIMEOUT_TERSE) - { - grub_free (msg_translated); - msg_translated = grub_xasprintf (_("%ds"), timeout); - if (grub_term_width (data->term) < 10) - data->timeout_msg = TIMEOUT_TERSE_NO_MARGIN; - } - } - - grub_print_message_indented (msg_translated, - data->timeout_msg == TIMEOUT_TERSE_NO_MARGIN ? 0 : 3, - data->timeout_msg == TIMEOUT_TERSE_NO_MARGIN ? 0 : 1, - data->term); - grub_free (msg_translated); - - grub_term_gotoxy (data->term, - (struct grub_term_coordinate) { - grub_term_cursor_x (&data->geo), - data->geo.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 > data->geo.num_entries - 1) - { - data->first = entry - (data->geo.num_entries - 1); - data->offset = data->geo.num_entries - 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); - else - { - print_entry (data->geo.first_entry_y + oldoffset, 0, - grub_menu_get_entry (data->menu, data->first + oldoffset), - data); - print_entry (data->geo.first_entry_y + data->offset, 1, - grub_menu_get_entry (data->menu, data->first + data->offset), - data); - } - 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); - grub_free (data); -} - -static void -menu_text_clear_timeout (void *dataptr) -{ - struct menu_viewer_data *data = dataptr; - int i; - - for (i = 0; i < data->geo.timeout_lines;i++) - { - grub_term_gotoxy (data->term, (struct grub_term_coordinate) { - 0, data->geo.timeout_y + i }); - grub_print_spaces (data->term, grub_term_width (data->term) - 1); - } - if (data->geo.num_entries <= 5 && !data->geo.border) - { - grub_term_gotoxy (data->term, - (struct grub_term_coordinate) { - data->geo.first_entry_x + data->geo.entry_width - + data->geo.border + 1, - data->geo.first_entry_y + data->geo.num_entries - 1 - }); - grub_putcode (' ', data->term); - - data->geo.timeout_lines = 0; - data->geo.num_entries++; - print_entries (data->menu, data); - } - grub_term_gotoxy (data->term, - (struct grub_term_coordinate) { - grub_term_cursor_x (&data->geo), - data->geo.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; - - grub_term_setcursor (data->term, 0); - grub_menu_init_page (nested, 0, &data->geo, data->term); - - if (data->offset > data->geo.num_entries - 1) - { - data->first = data->offset - (data->geo.num_entries - 1); - data->offset = data->geo.num_entries - 1; - } - - print_entries (menu, data); - 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 deleted file mode 100644 index 66f988042..000000000 --- a/grub-core/normal/misc.c +++ /dev/null @@ -1,194 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const char *grub_human_sizes[3][6] = - { - /* This algorithm in reality would work only up to (2^64) / 100 B = 81 PiB. - Put here all possible suffixes it can produce so no array bounds check - is needed. - */ - /* TRANSLATORS: that's the list of binary unit prefixes. */ - { N_("B"), N_("KiB"), N_("MiB"), N_("GiB"), N_("TiB"), N_("PiB")}, - /* TRANSLATORS: that's the list of binary unit prefixes. */ - { "", N_("K"), N_("M"), N_("G"), N_("T"), N_("P") }, - /* TRANSLATORS: that's the list of binary unit prefixes. */ - { N_("B/s"), N_("KiB/s"), N_("MiB/s"), N_("GiB/s"), N_("TiB/s"), N_("PiB/s"), }, - }; - -const char * -grub_get_human_size (grub_uint64_t size, enum grub_human_size_type type) -{ - grub_uint64_t fsize; - unsigned units = 0; - static char buf[30]; - const char *umsg; - - if (type != GRUB_HUMAN_SIZE_SPEED) - fsize = size * 100ULL; - else - fsize = size; - - /* Since 2^64 / 1024^5 < 102400, this can give at most 5 iterations. - So units <=5, so impossible to go past the end of array. - */ - while (fsize >= 102400) - { - fsize = (fsize + 512) / 1024; - units++; - } - - umsg = _(grub_human_sizes[type][units]); - - if (units || type == GRUB_HUMAN_SIZE_SPEED) - { - grub_uint64_t whole, fraction; - - whole = grub_divmod64 (fsize, 100, &fraction); - grub_snprintf (buf, sizeof (buf), - "%" PRIuGRUB_UINT64_T - ".%02" PRIuGRUB_UINT64_T "%s", whole, fraction, - umsg); - } - else - grub_snprintf (buf, sizeof (buf), "%llu%s", (unsigned long long) size, - umsg); - return buf; -} - -/* 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_xputs ("\t"); - grub_printf_ (N_("Partition %s:"), name); - grub_xputs (" "); - } - else - { - grub_printf_ (N_("Device %s:"), name); - grub_xputs (" "); - } - - 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) - { - const char *fsname = fs->name; - if (grub_strcmp (fsname, "ext2") == 0) - fsname = "ext*"; - grub_printf_ (N_("Filesystem type %s"), fsname); - if (fs->fs_label) - { - char *label; - (fs->fs_label) (dev, &label); - if (grub_errno == GRUB_ERR_NONE) - { - if (label && grub_strlen (label)) - { - grub_xputs (" "); - grub_printf_ (N_("- Label `%s'"), label); - } - grub_free (label); - } - grub_errno = GRUB_ERR_NONE; - } - if (fs->fs_mtime) - { - grub_int64_t tm; - struct grub_datetime datetime; - (fs->fs_mtime) (dev, &tm); - if (grub_errno == GRUB_ERR_NONE) - { - grub_unixtime2datetime (tm, &datetime); - grub_xputs (" "); - /* TRANSLATORS: Arguments are year, month, day, hour, minute, - second, day of the week (translated). */ - 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->fs_uuid) - { - char *uuid; - (fs->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 - grub_printf ("%s", _("No known filesystem detected")); - - if (dev->disk->partition) - grub_printf (_(" - Partition start at %llu%sKiB"), - (unsigned long long) (grub_partition_get_start (dev->disk->partition) >> 1), - (grub_partition_get_start (dev->disk->partition) & 1) ? ".5" : "" ); - else - grub_printf_ (N_(" - Sector size %uB"), 1 << dev->disk->log_sector_size); - if (grub_disk_native_sectors (dev->disk) == GRUB_DISK_SIZE_UNKNOWN) - grub_puts_ (N_(" - Total size unknown")); - else - grub_printf (_(" - Total size %llu%sKiB"), - (unsigned long long) (grub_disk_native_sectors (dev->disk) >> 1), - /* TRANSLATORS: Replace dot with appropriate decimal separator for - your language. */ - (grub_disk_native_sectors (dev->disk) & 1) ? _(".5") : ""); - } - - if (dev) - grub_device_close (dev); - - grub_xputs ("\n"); - return grub_errno; -} diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c deleted file mode 100644 index c073eb489..000000000 --- a/grub-core/normal/term.c +++ /dev/null @@ -1,1098 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct term_state -{ - struct term_state *next; - struct grub_unicode_glyph *backlog_glyphs; - const grub_uint32_t *backlog_ucs4; - int backlog_fixed_tab; - grub_size_t backlog_len; - - int bidi_stack_depth; - grub_uint8_t bidi_stack[GRUB_BIDI_MAX_EXPLICIT_LEVEL]; - int invalid_pushes; - - void *free; - int num_lines; - char *term_name; -}; - -static int -print_ucs4_real (const grub_uint32_t * str, - const grub_uint32_t * last_position, - int margin_left, int margin_right, - struct grub_term_output *term, int backlog, - int dry_run, int fixed_tab, unsigned skip_lines, - unsigned max_lines, - grub_uint32_t contchar, int fill_right, - struct grub_term_pos *pos); - -static struct term_state *term_states = NULL; - -/* If the more pager is active. */ -static int grub_more; - -static void -putcode_real (grub_uint32_t code, struct grub_term_output *term, int fixed_tab); - -void -grub_normal_reset_more (void) -{ - static struct term_state *state; - for (state = term_states; state; state = state->next) - state->num_lines = 0; -} - -static void -print_more (void) -{ - char key; - struct grub_term_coordinate *pos; - grub_term_output_t term; - grub_uint32_t *unicode_str, *unicode_last_position; - - /* TRANSLATORS: This has to fit on one line. It's ok to include few - words but don't write poems. */ - grub_utf8_to_ucs4_alloc (_("--MORE--"), &unicode_str, - &unicode_last_position); - - if (!unicode_str) - { - grub_errno = GRUB_ERR_NONE; - return; - } - - pos = grub_term_save_pos (); - - grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); - - FOR_ACTIVE_TERM_OUTPUTS(term) - { - grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term); - } - grub_setcolorstate (GRUB_TERM_COLOR_NORMAL); - - grub_free (unicode_str); - - key = grub_getkey (); - - /* Remove the message. */ - grub_term_restore_pos (pos); - FOR_ACTIVE_TERM_OUTPUTS(term) - grub_print_spaces (term, 8); - grub_term_restore_pos (pos); - grub_free (pos); - - /* Scroll one line or an entire page, depending on the key. */ - - if (key == '\r' || key =='\n') - { - static struct term_state *state; - for (state = term_states; state; state = state->next) - state->num_lines--; - } - else - grub_normal_reset_more (); -} - -void -grub_set_more (int onoff) -{ - grub_more = !!onoff; - grub_normal_reset_more (); -} - -enum - { - GRUB_CP437_UPDOWNARROW = 0x12, - GRUB_CP437_UPARROW = 0x18, - GRUB_CP437_DOWNARROW = 0x19, - GRUB_CP437_RIGHTARROW = 0x1a, - GRUB_CP437_LEFTARROW = 0x1b, - GRUB_CP437_VLINE = 0xb3, - GRUB_CP437_CORNER_UR = 0xbf, - GRUB_CP437_CORNER_LL = 0xc0, - GRUB_CP437_HLINE = 0xc4, - GRUB_CP437_CORNER_LR = 0xd9, - GRUB_CP437_CORNER_UL = 0xda, - }; - -static grub_uint32_t -map_code (grub_uint32_t in, struct grub_term_output *term) -{ - if (in <= 0x7f) - return in; - - switch (term->flags & GRUB_TERM_CODE_TYPE_MASK) - { - case GRUB_TERM_CODE_TYPE_CP437: - switch (in) - { - case GRUB_UNICODE_LEFTARROW: - return GRUB_CP437_LEFTARROW; - case GRUB_UNICODE_UPARROW: - return GRUB_CP437_UPARROW; - case GRUB_UNICODE_UPDOWNARROW: - return GRUB_CP437_UPDOWNARROW; - case GRUB_UNICODE_RIGHTARROW: - return GRUB_CP437_RIGHTARROW; - case GRUB_UNICODE_DOWNARROW: - return GRUB_CP437_DOWNARROW; - case GRUB_UNICODE_HLINE: - return GRUB_CP437_HLINE; - case GRUB_UNICODE_VLINE: - return GRUB_CP437_VLINE; - case GRUB_UNICODE_CORNER_UL: - return GRUB_CP437_CORNER_UL; - case GRUB_UNICODE_CORNER_UR: - return GRUB_CP437_CORNER_UR; - case GRUB_UNICODE_CORNER_LL: - return GRUB_CP437_CORNER_LL; - case GRUB_UNICODE_CORNER_LR: - return GRUB_CP437_CORNER_LR; - } - return '?'; - case GRUB_TERM_CODE_TYPE_ASCII: - /* Better than nothing. */ - switch (in) - { - case GRUB_UNICODE_LEFTARROW: - return '<'; - - case GRUB_UNICODE_UPARROW: - return '^'; - - case GRUB_UNICODE_RIGHTARROW: - return '>'; - - case GRUB_UNICODE_DOWNARROW: - return 'v'; - - case GRUB_UNICODE_HLINE: - return '-'; - - case GRUB_UNICODE_VLINE: - return '|'; - - case GRUB_UNICODE_CORNER_UL: - case GRUB_UNICODE_CORNER_UR: - case GRUB_UNICODE_CORNER_LL: - case GRUB_UNICODE_CORNER_LR: - return '+'; - - } - return '?'; - } - return in; -} - -void -grub_puts_terminal (const char *str, struct grub_term_output *term) -{ - grub_uint32_t *unicode_str, *unicode_last_position; - grub_error_push (); - grub_utf8_to_ucs4_alloc (str, &unicode_str, - &unicode_last_position); - grub_error_pop (); - if (!unicode_str) - { - for (; *str; str++) - { - struct grub_unicode_glyph c = - { - .variant = 0, - .attributes = 0, - .ncomb = 0, - .estimated_width = 1, - .base = *str - }; - - FOR_ACTIVE_TERM_OUTPUTS(term) - { - (term->putchar) (term, &c); - } - if (*str == '\n') - { - c.base = '\r'; - FOR_ACTIVE_TERM_OUTPUTS(term) - { - (term->putchar) (term, &c); - } - } - } - return; - } - - print_ucs4_real (unicode_str, unicode_last_position, 0, 0, term, - 0, 0, 0, 0, -1, 0, 0, 0); - grub_free (unicode_str); -} - -struct grub_term_coordinate * -grub_term_save_pos (void) -{ - struct grub_term_output *cur; - unsigned cnt = 0; - struct grub_term_coordinate *ret, *ptr; - - FOR_ACTIVE_TERM_OUTPUTS(cur) - cnt++; - - ret = grub_calloc (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 (struct grub_term_coordinate *pos) -{ - struct grub_term_output *cur; - struct grub_term_coordinate *ptr = pos; - - if (!pos) - return; - - FOR_ACTIVE_TERM_OUTPUTS(cur) - { - grub_term_gotoxy (cur, *ptr); - 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/" GRUB_TARGET_CPU "-" GRUB_PLATFORM - "/terminal.lst", prefix); - if (!filename) - { - grub_errno = GRUB_ERR_NONE; - return; - } - - file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE_LIST); - 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; - - p = buf; - while (grub_isspace (p[0])) - p++; - - switch (p[0]) - { - case 'i': - target = &grub_term_input_autoload; - break; - - case 'o': - target = &grub_term_output_autoload; - break; - } - if (!target) - continue; - - name = p + 1; - - p = grub_strchr (name, ':'); - if (! p) - continue; - *p = 0; - - p++; - while (*p == ' ' || *p == '\t') - p++; - - cur = grub_malloc (sizeof (*cur)); - if (!cur) - { - grub_errno = GRUB_ERR_NONE; - continue; - } - - cur->name = grub_strdup (name); - if (! cur->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->name); - grub_free (cur); - continue; - } - cur->next = *target; - *target = cur; - } - - grub_file_close (file); - - grub_errno = GRUB_ERR_NONE; -} - -static void -putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term, - int fixed_tab) -{ - struct grub_unicode_glyph c2 = - { - .variant = 0, - .attributes = 0, - .ncomb = 0, - .estimated_width = 1 - }; - - if (c->base == '\t' && fixed_tab) - { - int n; - - n = GRUB_TERM_TAB_WIDTH; - c2.base = ' '; - while (n--) - (term->putchar) (term, &c2); - - return; - } - - if (c->base == '\t' && term->getxy) - { - int n; - - n = GRUB_TERM_TAB_WIDTH - ((term->getxy (term).x) - % GRUB_TERM_TAB_WIDTH); - c2.base = ' '; - while (n--) - (term->putchar) (term, &c2); - - return; - } - - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UTF8_LOGICAL - || (term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) - { - int i; - c2.estimated_width = grub_term_getcharwidth (term, c); - for (i = -1; i < (int) c->ncomb; i++) - { - grub_uint8_t u8[20], *ptr; - grub_uint32_t code; - - if (i == -1) - { - code = c->base; - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) - { - if ((c->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR)) - code = grub_unicode_mirror_code (code); - code = grub_unicode_shape_code (code, c->attributes); - } - } - else - code = grub_unicode_get_comb (c) [i].code; - - grub_ucs4_to_utf8 (&code, 1, u8, sizeof (u8)); - - for (ptr = u8; *ptr; ptr++) - { - c2.base = *ptr; - (term->putchar) (term, &c2); - c2.estimated_width = 0; - } - } - c2.estimated_width = 1; - } - else - (term->putchar) (term, c); - - if (c->base == '\n') - { - c2.base = '\r'; - (term->putchar) (term, &c2); - } -} - -static void -putcode_real (grub_uint32_t code, struct grub_term_output *term, int fixed_tab) -{ - struct grub_unicode_glyph c = - { - .variant = 0, - .attributes = 0, - .ncomb = 0, - .estimated_width = 1 - }; - - c.base = map_code (code, term); - putglyph (&c, term, fixed_tab); -} - -/* Put a Unicode character. */ -void -grub_putcode (grub_uint32_t code, struct grub_term_output *term) -{ - /* Combining character by itself? */ - if (grub_unicode_get_comb_type (code) != GRUB_UNICODE_COMB_NONE) - return; - - putcode_real (code, term, 0); -} - -static grub_ssize_t -get_maxwidth (struct grub_term_output *term, - int margin_left, int margin_right) -{ - struct grub_unicode_glyph space_glyph = { - .base = ' ', - .variant = 0, - .attributes = 0, - .ncomb = 0, - }; - return (grub_term_width (term) - - grub_term_getcharwidth (term, &space_glyph) - * (margin_left + margin_right) - 1); -} - -static grub_ssize_t -get_startwidth (struct grub_term_output *term, - int margin_left) -{ - return (term->getxy (term).x) - margin_left; -} - -static void -fill_margin (struct grub_term_output *term, int r) -{ - int sp = (term->getwh (term).x) - - (term->getxy (term).x) - r; - if (sp > 0) - grub_print_spaces (term, sp); -} - -static int -print_ucs4_terminal (const grub_uint32_t * str, - const grub_uint32_t * last_position, - int margin_left, int margin_right, - struct grub_term_output *term, - struct term_state *state, - int dry_run, int fixed_tab, unsigned skip_lines, - unsigned max_lines, - grub_uint32_t contchar, - int primitive_wrap, int fill_right, struct grub_term_pos *pos) -{ - const grub_uint32_t *ptr; - grub_ssize_t startwidth = dry_run ? 0 : get_startwidth (term, margin_left); - grub_ssize_t line_width = startwidth; - grub_ssize_t lastspacewidth = 0; - grub_ssize_t max_width = get_maxwidth (term, margin_left, margin_right); - const grub_uint32_t *line_start = str, *last_space = str - 1; - int lines = 0; - int i; - struct term_state local_state; - - if (!state) - { - grub_memset (&local_state, 0, sizeof (local_state)); - state = &local_state; - } - - for (i = 0; i < state->bidi_stack_depth; i++) - putcode_real (state->bidi_stack[i] | (GRUB_UNICODE_LRE & ~0xff), - term, fixed_tab); - - for (ptr = str; ptr < last_position; ptr++) - { - grub_ssize_t last_width = 0; - - switch (*ptr) - { - case GRUB_UNICODE_LRE: - case GRUB_UNICODE_RLE: - case GRUB_UNICODE_LRO: - case GRUB_UNICODE_RLO: - if (state->bidi_stack_depth >= (int) ARRAY_SIZE (state->bidi_stack)) - state->invalid_pushes++; - else - state->bidi_stack[state->bidi_stack_depth++] = *ptr; - break; - case GRUB_UNICODE_PDF: - if (state->invalid_pushes) - state->invalid_pushes--; - else if (state->bidi_stack_depth) - state->bidi_stack_depth--; - break; - } - if (grub_unicode_get_comb_type (*ptr) == GRUB_UNICODE_COMB_NONE) - { - struct grub_unicode_glyph c = { - .variant = 0, - .attributes = 0, - .ncomb = 0, - }; - c.base = *ptr; - if (pos) - { - pos[ptr - str].x = line_width; - pos[ptr - str].y = lines; - pos[ptr - str].valid = 1; - } - line_width += last_width = grub_term_getcharwidth (term, &c); - } - - if (*ptr == ' ' && !primitive_wrap) - { - lastspacewidth = line_width; - last_space = ptr; - } - - if (line_width > max_width || *ptr == '\n') - { - const grub_uint32_t *ptr2; - int wasn = (*ptr == '\n'); - - if (wasn) - { - state->bidi_stack_depth = 0; - state->invalid_pushes = 0; - } - - if (line_width > max_width && last_space > line_start) - ptr = last_space; - else if (line_width > max_width - && line_start == str && line_width - lastspacewidth < max_width - 5) - { - ptr = str; - lastspacewidth = startwidth; - } - else - lastspacewidth = line_width - last_width; - - lines++; - - if (!skip_lines && !dry_run) - { - for (ptr2 = line_start; ptr2 < ptr; ptr2++) - { - /* Skip combining characters on non-UTF8 terminals. */ - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL - && grub_unicode_get_comb_type (*ptr2) - != GRUB_UNICODE_COMB_NONE) - continue; - putcode_real (*ptr2, term, fixed_tab); - } - - if (!wasn && contchar) - putcode_real (contchar, term, fixed_tab); - if (fill_right) - fill_margin (term, margin_right); - - if (!contchar || max_lines != 1) - grub_putcode ('\n', term); - if (state != &local_state && ++state->num_lines - >= (grub_ssize_t) grub_term_height (term) - 2) - { - state->backlog_ucs4 = (ptr == last_space || *ptr == '\n') - ? ptr + 1 : ptr; - state->backlog_len = last_position - state->backlog_ucs4; - state->backlog_fixed_tab = fixed_tab; - return 1; - } - } - - line_width -= lastspacewidth; - if (ptr == last_space || *ptr == '\n') - ptr++; - else if (pos) - { - pos[ptr - str].x = line_width - last_width; - pos[ptr - str].y = lines; - pos[ptr - str].valid = 1; - } - - line_start = ptr; - - if (skip_lines) - skip_lines--; - else if (max_lines != (unsigned) -1) - { - max_lines--; - if (!max_lines) - break; - } - if (!skip_lines && !dry_run) - { - if (!contchar) - grub_print_spaces (term, margin_left); - else - grub_term_gotoxy (term, (struct grub_term_coordinate) - { margin_left, grub_term_getxy (term).y }); - for (i = 0; i < state->bidi_stack_depth; i++) - putcode_real (state->bidi_stack[i] | (GRUB_UNICODE_LRE & ~0xff), - term, fixed_tab); - } - } - } - - if (pos) - { - pos[ptr - str].x = line_width; - pos[ptr - str].y = lines; - pos[ptr - str].valid = 1; - } - - if (line_start < last_position) - lines++; - if (!dry_run && !skip_lines && max_lines) - { - const grub_uint32_t *ptr2; - - for (ptr2 = line_start; ptr2 < last_position; ptr2++) - { - /* Skip combining characters on non-UTF8 terminals. */ - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL - && grub_unicode_get_comb_type (*ptr2) - != GRUB_UNICODE_COMB_NONE) - continue; - putcode_real (*ptr2, term, fixed_tab); - } - - if (fill_right) - fill_margin (term, margin_right); - } - return dry_run ? lines : 0; -} - -static struct term_state * -find_term_state (struct grub_term_output *term) -{ - struct term_state *state; - for (state = term_states; state; state = state->next) - if (grub_strcmp (state->term_name, term->name) == 0) - return state; - - state = grub_zalloc (sizeof (*state)); - if (!state) - { - grub_errno = GRUB_ERR_NONE; - return NULL; - } - - state->term_name = grub_strdup (term->name); - state->next = term_states; - term_states = state; - - return state; -} - -static int -put_glyphs_terminal (struct grub_unicode_glyph *visual, - grub_ssize_t visual_len, - int margin_left, int margin_right, - struct grub_term_output *term, - struct term_state *state, int fixed_tab, - grub_uint32_t contchar, - int fill_right) -{ - struct grub_unicode_glyph *visual_ptr; - int since_last_nl = 1; - for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++) - { - if (visual_ptr->base == '\n' && fill_right) - fill_margin (term, margin_right); - - putglyph (visual_ptr, term, fixed_tab); - since_last_nl++; - if (visual_ptr->base == '\n') - { - since_last_nl = 0; - if (state && ++state->num_lines - >= (grub_ssize_t) grub_term_height (term) - 2) - { - state->backlog_glyphs = visual_ptr + 1; - state->backlog_len = visual_len - (visual_ptr - visual) - 1; - state->backlog_fixed_tab = fixed_tab; - return 1; - } - - if (!contchar) - grub_print_spaces (term, margin_left); - else - grub_term_gotoxy (term, - (struct grub_term_coordinate) - { margin_left, grub_term_getxy (term).y }); - } - grub_unicode_destroy_glyph (visual_ptr); - } - if (fill_right && since_last_nl) - fill_margin (term, margin_right); - - return 0; -} - -static int -print_backlog (struct grub_term_output *term, - int margin_left, int margin_right) -{ - struct term_state *state = find_term_state (term); - - if (!state) - return 0; - - if (state->backlog_ucs4) - { - int ret; - ret = print_ucs4_terminal (state->backlog_ucs4, - state->backlog_ucs4 + state->backlog_len, - margin_left, margin_right, term, state, 0, - state->backlog_fixed_tab, 0, -1, 0, 0, - 0, 0); - if (!ret) - { - grub_free (state->free); - state->free = NULL; - state->backlog_len = 0; - state->backlog_ucs4 = 0; - } - return ret; - } - - if (state->backlog_glyphs) - { - int ret; - ret = put_glyphs_terminal (state->backlog_glyphs, - state->backlog_len, - margin_left, margin_right, term, state, - state->backlog_fixed_tab, 0, 0); - if (!ret) - { - grub_free (state->free); - state->free = NULL; - state->backlog_len = 0; - state->backlog_glyphs = 0; - } - return ret; - } - - return 0; -} - -static grub_size_t -getcharwidth (const struct grub_unicode_glyph *c, void *term) -{ - return grub_term_getcharwidth (term, c); -} - -static int -print_ucs4_real (const grub_uint32_t * str, - const grub_uint32_t * last_position, - int margin_left, int margin_right, - struct grub_term_output *term, int backlog, - int dry_run, int fixed_tab, unsigned skip_lines, - unsigned max_lines, - grub_uint32_t contchar, int fill_right, - struct grub_term_pos *pos) -{ - struct term_state *state = NULL; - - if (!dry_run) - { - struct grub_term_coordinate xy; - if (backlog) - state = find_term_state (term); - - xy = term->getxy (term); - - if (xy.x < margin_left) - { - if (!contchar) - grub_print_spaces (term, margin_left - xy.x); - else - grub_term_gotoxy (term, (struct grub_term_coordinate) {margin_left, - xy.y}); - } - } - - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS - || (term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) - { - grub_ssize_t visual_len; - struct grub_unicode_glyph *visual; - grub_ssize_t visual_len_show; - struct grub_unicode_glyph *visual_show; - int ret; - struct grub_unicode_glyph *vptr; - - visual_len = grub_bidi_logical_to_visual (str, last_position - str, - &visual, getcharwidth, term, - get_maxwidth (term, - margin_left, - margin_right), - dry_run ? 0 : get_startwidth (term, - margin_left), - contchar, pos, !!contchar); - if (visual_len < 0) - { - grub_print_error (); - return 0; - } - visual_show = visual; - for (; skip_lines && visual_show < visual + visual_len; visual_show++) - if (visual_show->base == '\n') - skip_lines--; - if (max_lines != (unsigned) -1) - { - for (vptr = visual_show; - max_lines && vptr < visual + visual_len; vptr++) - if (vptr->base == '\n') - max_lines--; - - visual_len_show = vptr - visual_show; - } - else - visual_len_show = visual + visual_len - visual_show; - - if (dry_run) - { - ret = 0; - for (vptr = visual_show; vptr < visual_show + visual_len_show; vptr++) - if (vptr->base == '\n') - ret++; - if (visual_len_show && visual[visual_len_show - 1].base != '\n') - ret++; - for (vptr = visual; vptr < visual + visual_len; vptr++) - grub_unicode_destroy_glyph (vptr); - grub_free (visual); - } - else - { - ret = put_glyphs_terminal (visual_show, visual_len_show, margin_left, - margin_right, - term, state, fixed_tab, contchar, fill_right); - - if (!ret) - grub_free (visual); - else - state->free = visual; - } - return ret; - } - return print_ucs4_terminal (str, last_position, margin_left, margin_right, - term, state, dry_run, fixed_tab, skip_lines, - max_lines, contchar, !!contchar, fill_right, pos); -} - -void -grub_print_ucs4_menu (const grub_uint32_t * str, - const grub_uint32_t * last_position, - int margin_left, int margin_right, - struct grub_term_output *term, - int skip_lines, int max_lines, - grub_uint32_t contchar, - struct grub_term_pos *pos) -{ - print_ucs4_real (str, last_position, margin_left, margin_right, - term, 0, 0, 1, skip_lines, max_lines, - contchar, 1, pos); -} - -void -grub_print_ucs4 (const grub_uint32_t * str, - const grub_uint32_t * last_position, - int margin_left, int margin_right, - struct grub_term_output *term) -{ - print_ucs4_real (str, last_position, margin_left, margin_right, - term, 0, 0, 1, 0, -1, 0, 0, 0); -} - -int -grub_ucs4_count_lines (const grub_uint32_t * str, - const grub_uint32_t * last_position, - int margin_left, int margin_right, - struct grub_term_output *term) -{ - return print_ucs4_real (str, last_position, margin_left, margin_right, - term, 0, 1, 1, 0, -1, 0, 0, 0); -} - -void -grub_xnputs (const char *str, grub_size_t msg_len) -{ - grub_uint32_t *unicode_str = NULL, *unicode_last_position; - int backlog = 0; - grub_term_output_t term; - - grub_error_push (); - - unicode_str = grub_calloc (msg_len, sizeof (grub_uint32_t)); - - grub_error_pop (); - - if (!unicode_str) - { - for (; msg_len--; str++, msg_len++) - { - struct grub_unicode_glyph c = - { - .variant = 0, - .attributes = 0, - .ncomb = 0, - .estimated_width = 1, - .base = *str - }; - - FOR_ACTIVE_TERM_OUTPUTS(term) - { - (term->putchar) (term, &c); - } - if (*str == '\n') - { - c.base = '\r'; - FOR_ACTIVE_TERM_OUTPUTS(term) - { - (term->putchar) (term, &c); - } - } - } - - return; - } - - msg_len = grub_utf8_to_ucs4 (unicode_str, msg_len, - (grub_uint8_t *) str, -1, 0); - unicode_last_position = unicode_str + msg_len; - - FOR_ACTIVE_TERM_OUTPUTS(term) - { - int cur; - cur = print_ucs4_real (unicode_str, unicode_last_position, 0, 0, - term, grub_more, 0, 0, 0, -1, 0, 0, 0); - if (cur) - backlog = 1; - } - while (backlog) - { - print_more (); - backlog = 0; - FOR_ACTIVE_TERM_OUTPUTS(term) - { - int cur; - cur = print_backlog (term, 0, 0); - if (cur) - backlog = 1; - } - } - grub_free (unicode_str); -} - -void -grub_xputs_normal (const char *str) -{ - grub_xnputs (str, grub_strlen (str)); -} - -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) (term); - } -} diff --git a/grub-core/osdep/apple/getroot.c b/grub-core/osdep/apple/getroot.c deleted file mode 100644 index 2091dedfe..000000000 --- a/grub-core/osdep/apple/getroot.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIMITS_H -#include -#endif - -#include - -#include - -#include -#include -#include -#include -#include - -#include - -# include -# include -# include -# include - -char * -grub_util_part_to_disk (const char *os_dev, struct stat *st, - int *is_part) -{ - char *path = xstrdup (os_dev); - - if (! S_ISCHR (st->st_mode)) - { - *is_part = 0; - return path; - } - - if (strncmp ("/dev/", path, 5) == 0) - { - char *p; - for (p = path + 5; *p; ++p) - if (grub_isdigit(*p)) - { - p = strpbrk (p, "sp"); - if (p) - { - *is_part = 1; - *p = '\0'; - } - break; - } - } - return path; -} - -enum grub_dev_abstraction_types -grub_util_get_dev_abstraction_os (const char *os_dev __attribute__((unused))) -{ - return GRUB_DEV_ABSTRACTION_NONE; -} - -int -grub_util_pull_device_os (const char *os_dev __attribute__ ((unused)), - enum grub_dev_abstraction_types ab __attribute__ ((unused))) -{ - return 0; -} - -char * -grub_util_get_grub_dev_os (const char *os_dev __attribute__ ((unused))) -{ - return NULL; -} - - -grub_disk_addr_t -grub_util_find_partition_start_os (const char *dev __attribute__ ((unused))) -{ - return 0; -} diff --git a/grub-core/osdep/apple/hostdisk.c b/grub-core/osdep/apple/hostdisk.c deleted file mode 100644 index 638e8ba86..000000000 --- a/grub-core/osdep/apple/hostdisk.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -# include - -grub_int64_t -grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize) -{ - unsigned long long nr; - unsigned sector_size, log_sector_size; - - if (ioctl (fd, DKIOCGETBLOCKCOUNT, &nr)) - return -1; - - if (ioctl (fd, DKIOCGETBLOCKSIZE, §or_size)) - return -1; - - if (sector_size & (sector_size - 1) || !sector_size) - return -1; - log_sector_size = grub_log2ull (sector_size); - - if (log_secsize) - *log_secsize = log_sector_size; - - return nr << log_sector_size; -} - -grub_util_fd_t -grub_util_fd_open (const char *os_dev, int flags) -{ - grub_util_fd_t ret; - -#ifdef O_LARGEFILE - flags |= O_LARGEFILE; -#endif -#ifdef O_BINARY - flags |= O_BINARY; -#endif - - ret = open (os_dev, flags, S_IROTH | S_IRGRP | S_IRUSR | S_IWUSR); - - /* If we can't have exclusive access, try shared access */ - if (ret < 0) - ret = open (os_dev, flags | O_SHLOCK, S_IROTH | S_IRGRP | S_IRUSR | S_IWUSR); - - return ret; -} - -void -grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused))) -{ -} diff --git a/grub-core/osdep/aros/config.c b/grub-core/osdep/aros/config.c deleted file mode 100644 index 55f5728ef..000000000 --- a/grub-core/osdep/aros/config.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const char * -grub_util_get_config_filename (void) -{ - static char *value = NULL; - if (!value) - value = grub_util_path_concat (3, GRUB_SYSCONFDIR, - "default", "grub"); - return value; -} - -const char * -grub_util_get_pkgdatadir (void) -{ - const char *ret = getenv ("pkgdatadir"); - if (ret) - return ret; - return GRUB_DATADIR "/" PACKAGE; -} - -const char * -grub_util_get_pkglibdir (void) -{ - return GRUB_LIBDIR "/" PACKAGE; -} - -const char * -grub_util_get_localedir (void) -{ - return LOCALEDIR; -} - -void -grub_util_load_config (struct grub_util_config *cfg) -{ - const char *cfgfile; - FILE *f = NULL; - const char *v; - - memset (cfg, 0, sizeof (*cfg)); - - v = getenv ("GRUB_ENABLE_CRYPTODISK"); - if (v && v[0] == 'y' && v[1] == '\0') - cfg->is_cryptodisk_enabled = 1; - - v = getenv ("GRUB_DISTRIBUTOR"); - if (v) - cfg->grub_distributor = xstrdup (v); - - cfgfile = grub_util_get_config_filename (); - if (!grub_util_is_regular (cfgfile)) - return; - - f = grub_util_fopen (cfgfile, "r"); - if (f) - { - grub_util_parse_config (f, cfg, 0); - fclose (f); - } - else - grub_util_warn (_("cannot open configuration file `%s': %s"), - cfgfile, strerror (errno)); -} diff --git a/grub-core/osdep/aros/getroot.c b/grub-core/osdep/aros/getroot.c deleted file mode 100644 index aff6dc53e..000000000 --- a/grub-core/osdep/aros/getroot.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -char * -grub_util_part_to_disk (const char *dev, - struct stat *st __attribute__ ((unused)), - int *is_part) -{ - const char *dname; - char *ret; - struct DosList *dl; - struct DeviceNode *dn; - struct FileSysStartupMsg *fm; - struct DosEnvec *envec; - - if (dev[0] != '/' || dev[1] != '/' || dev[2] != ':') - return xstrdup (dev); - - dname = dev + 3; - dl = LockDosList(LDF_READ); - - if (!dl) - { - return xstrdup (dev); - } - - dn = (struct DeviceNode *) FindDosEntry (dl, (unsigned char *) dname, - LDF_DEVICES); - UnLockDosList (LDF_READ); - if (!dn) - return xstrdup (dev); - - fm = (struct FileSysStartupMsg *) BADDR(dn->dn_Startup); - envec = (struct DosEnvec *) fm->fssm_Environ; - - if (envec->de_LowCyl == 0) - return xstrdup (dev); - - *is_part = 1; - - ret = xasprintf ("//:%s/%lx/%lx", fm->fssm_Device, fm->fssm_Unit, (unsigned long) fm->fssm_Flags); - - return ret; -} - -enum grub_dev_abstraction_types -grub_util_get_dev_abstraction_os (const char *os_dev __attribute__((unused))) -{ - return GRUB_DEV_ABSTRACTION_NONE; -} - -int -grub_util_pull_device_os (const char *os_dev __attribute__ ((unused)), - enum grub_dev_abstraction_types ab __attribute__ ((unused))) -{ - return 0; -} - -char * -grub_util_get_grub_dev_os (const char *os_dev __attribute__ ((unused))) -{ - return NULL; -} - - -grub_disk_addr_t -grub_util_find_partition_start_os (const char *dev) -{ - const char *dname; - struct DosList *dl; - struct DeviceNode *dn; - struct FileSysStartupMsg *fm; - struct DosEnvec *envec; - - if (dev[0] != '/' || dev[1] != '/' || dev[2] != ':') - return 0; - - dname = dev + 3; - dl = LockDosList(LDF_READ); - if (!dl) - { - return 0; - } - dn = (struct DeviceNode *) FindDosEntry (dl, (unsigned char *) dname, - LDF_DEVICES); - UnLockDosList (LDF_READ); - if (!dn) - return 0; - - fm = (struct FileSysStartupMsg *) BADDR(dn->dn_Startup); - envec = (struct DosEnvec *) fm->fssm_Environ; - - return (((grub_uint64_t) envec->de_Surfaces - * (grub_uint64_t) envec->de_BlocksPerTrack - * (grub_uint64_t) envec->de_LowCyl) - * (grub_uint64_t) envec->de_SizeBlock) >> 7; -} - -char ** -grub_guess_root_devices (const char *path) -{ - char **os_dev = NULL; - struct InfoData id; - BPTR lck; - struct DeviceList *dl; - struct DosList *dl2; - size_t sz; - const char *nm; - - lck = Lock ((const unsigned char *) path, SHARED_LOCK); - if (!lck) - grub_util_info ("Lock(%s) failed", path); - if (!lck || !Info (lck, &id)) - { - char *p; - if (lck) - UnLock (lck); - grub_util_info ("Info(%s) failed", path); - os_dev = xmalloc (2 * sizeof (os_dev[0])); - sz = strlen (path); - os_dev[0] = xmalloc (sz + 5); - os_dev[0][0] = '/'; - os_dev[0][1] = '/'; - os_dev[0][2] = ':'; - memcpy (os_dev[0] + 3, path, sz); - os_dev[0][sz + 3] = ':'; - os_dev[0][sz + 4] = '\0'; - p = strchr (os_dev[0] + 3, ':'); - *p = '\0'; - os_dev[1] = NULL; - return os_dev; - } - dl = BADDR (id.id_VolumeNode); - - if (!dl->dl_Task) - grub_util_error ("unsupported device %s", dl->dl_Name); - - grub_util_info ("dl=%p, dl->dl_Name=%s, dl->dl_Task=%p", - dl, dl->dl_Name, - dl->dl_Task); - - for (dl2 = LockDosList(LDF_READ | LDF_DEVICES); - dl2; - dl2 = NextDosEntry (dl2, LDF_DEVICES)) - { - if (dl2->dol_Task == dl->dl_Task) - break; - } - - if (lck) - UnLock (lck); - - if (dl2) - nm = (char *) dl2->dol_Name; - else - nm = (char *) dl->dl_Name; - - grub_util_info ("dl2=%p, nm=%s", dl2, nm); - - os_dev = xmalloc (2 * sizeof (os_dev[0])); - sz = strlen (nm); - - os_dev[0] = xmalloc (sz + 4); - os_dev[0][0] = '/'; - os_dev[0][1] = '/'; - os_dev[0][2] = ':'; - memcpy (os_dev[0] + 3, nm, sz); - os_dev[0][sz+3] = '\0'; - os_dev[1] = NULL; - - UnLockDosList (LDF_READ | LDF_DEVICES); - - return os_dev; -} - -int -grub_util_biosdisk_is_floppy (grub_disk_t disk) -{ - const char *dname; - - dname = grub_util_biosdisk_get_osdev (disk); - - if (dname[0] != '/' || dname[1] != '/' || dname[2] != ':') - return 0; - - dname += 3; - - if (strncmp (dname, TD_NAME, sizeof (TD_NAME) - 1) == 0 - && (TD_NAME[sizeof (TD_NAME) - 1] == '/' - || TD_NAME[sizeof (TD_NAME) - 1] == '\0')) - return 1; - return 0; -} - diff --git a/grub-core/osdep/aros/hostdisk.c b/grub-core/osdep/aros/hostdisk.c deleted file mode 100644 index 08723bd45..000000000 --- a/grub-core/osdep/aros/hostdisk.c +++ /dev/null @@ -1,615 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BOUNCE_SIZE 1048576 - -static ULONG *bounce; - -char * -grub_canonicalize_file_name (const char *path) -{ - char *ret; - BPTR lck; - - if (path[0] == '/' && path[1] == '/' && path[2] == ':') - return xstrdup (path); - - ret = xmalloc (2048); - lck = Lock ((const unsigned char *) path, SHARED_LOCK); - - if (!lck || !NameFromLock (lck, (unsigned char *) ret, 2040)) - { - free (ret); - ret = xstrdup (path); - } - if (lck) - UnLock (lck); - - return ret; -} - -static grub_uint64_t -grub_util_get_fd_size_volume (grub_util_fd_t fd __attribute__ ((unused)), - const char *dev, - unsigned *log_secsize) -{ - struct DriveGeometry *geo; - LONG err; - unsigned sector_size, log_sector_size; - - if (!bounce) - bounce = AllocVec (BOUNCE_SIZE, MEMF_PUBLIC | MEMF_CLEAR); - if (!bounce) - grub_util_error ("out of memory"); - - fd->ioreq->iotd_Req.io_Command = TD_GETGEOMETRY; - fd->ioreq->iotd_Req.io_Length = sizeof (*geo); - fd->ioreq->iotd_Req.io_Data = bounce; - fd->ioreq->iotd_Req.io_Offset = 0; - fd->ioreq->iotd_Req.io_Actual = 0; - err = DoIO ((struct IORequest *) fd->ioreq); - if (err) - { - grub_util_info ("I/O failed with error %d, IoErr=%d", (int)err, (int) IoErr ()); - return -1; - } - - geo = (struct DriveGeometry *) bounce; - - sector_size = geo->dg_SectorSize; - - if (sector_size & (sector_size - 1) || !sector_size) - return -1; - - log_sector_size = grub_log2ull (sector_size); - - if (log_secsize) - *log_secsize = log_sector_size; - - return (grub_uint64_t) geo->dg_TotalSectors * (grub_uint64_t) geo->dg_SectorSize; -} - -static grub_uint64_t -grub_util_get_fd_size_file (grub_util_fd_t fd, - const char *dev __attribute__ ((unused)), - unsigned *log_secsize) -{ - off_t oo, ro; - *log_secsize = 9; - /* FIXME: support 64-bit offsets. */ - oo = lseek (fd->fd, 0, SEEK_CUR); - ro = lseek (fd->fd, 0, SEEK_END); - lseek (fd->fd, oo, SEEK_SET); - return ro; -} - -int -grub_util_fd_seek (grub_util_fd_t fd, grub_uint64_t off) -{ - switch (fd->type) - { - case GRUB_UTIL_FD_FILE: - if (lseek (fd->fd, 0, SEEK_SET) == (off_t) -1) - return -1; - fd->off = off; - return 0; - case GRUB_UTIL_FD_DISK: - fd->off = off; - return 0; - } - - return -1; -} - -grub_util_fd_t -grub_util_fd_open (const char *dev, int flg) -{ - grub_util_fd_t ret = xmalloc (sizeof (*ret)); - const char *p1, *p2; - const char *dname; - char *tmp; - IPTR unit = 0; - ULONG flags = 0; - -#ifdef O_LARGEFILE - flg |= O_LARGEFILE; -#endif -#ifdef O_BINARY - flg |= O_BINARY; -#endif - - ret->off = 0; - - if (dev[0] != '/' || dev[1] != '/' || dev[2] != ':') - { - ret->type = GRUB_UTIL_FD_FILE; - ret->fd = open (dev, flg, S_IROTH | S_IRGRP | S_IRUSR | S_IWUSR); - if (ret->fd < 0) - { - free (ret); - return NULL; - } - return ret; - } - - p1 = strchr (dev + 3, '/'); - if (!p1) - p1 = dev + strlen (dev); - else - { - unit = grub_strtoul (p1 + 1, &p2, 16); - if (p2 && *p2 == '/') - flags = grub_strtoul (p2 + 1, 0, 16); - } - - ret->mp = CreateMsgPort(); - if (!ret->mp) - { - free (ret); - return NULL; - } - ret->ioreq = (struct IOExtTD *) CreateIORequest(ret->mp, - sizeof(struct IOExtTD)); - if (!ret->ioreq) - { - free (ret); - DeleteMsgPort (ret->mp); - return NULL; - } - - dname = dev + 3; - ret->type = GRUB_UTIL_FD_DISK; - - tmp = xmalloc (p1 - dname + 1); - memcpy (tmp, dname, p1 - dname); - tmp[p1 - dname] = '\0'; - - ret->is_floppy = (strcmp (tmp, TD_NAME) == 0); - ret->is_64 = 1; - - if (OpenDevice ((unsigned char *) tmp, unit, - (struct IORequest *) ret->ioreq, flags)) - { - free (tmp); - free (ret); - DeleteMsgPort (ret->mp); - return NULL; - } - free (tmp); - return ret; -} - -static ssize_t -grub_util_fd_read_file (grub_util_fd_t fd, char *buf, size_t len) -{ - ssize_t size = len; - - while (len) - { - ssize_t ret = read (fd->fd, buf, len); - - if (ret <= 0) - { - if (errno == EINTR) - continue; - else - return ret; - } - - fd->off += 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 -grub_util_fd_write_file (grub_util_fd_t fd, const char *buf, size_t len) -{ - ssize_t size = len; - - while (len) - { - ssize_t ret = write (fd->fd, buf, len); - - if (ret <= 0) - { - if (errno == EINTR) - continue; - else - return ret; - } - - fd->off += ret; - len -= ret; - buf += ret; - } - - return size; -} - -static void -stop_motor (grub_util_fd_t fd) -{ - if (!fd->is_floppy) - return; - fd->ioreq->iotd_Req.io_Command = TD_MOTOR; - fd->ioreq->iotd_Req.io_Length = 0; - fd->ioreq->iotd_Req.io_Data = 0; - fd->ioreq->iotd_Req.io_Offset = 0; - fd->ioreq->iotd_Req.io_Actual = 0; - DoIO ((struct IORequest *) fd->ioreq); -} - -static ssize_t -grub_util_fd_read_volume (grub_util_fd_t fd, char *buf, size_t len) -{ - grub_uint64_t adj = 0; - - if (!bounce) - bounce = AllocVec (BOUNCE_SIZE, MEMF_PUBLIC | MEMF_CLEAR); - if (!bounce) - grub_util_error ("out of memory"); - - while (len) - { - size_t cr = len; - LONG err; - if (cr > BOUNCE_SIZE) - cr = BOUNCE_SIZE; - retry: - if (fd->is_64) - fd->ioreq->iotd_Req.io_Command = NSCMD_TD_READ64; - else - fd->ioreq->iotd_Req.io_Command = CMD_READ; - fd->ioreq->iotd_Req.io_Length = cr; - fd->ioreq->iotd_Req.io_Data = bounce; - fd->ioreq->iotd_Req.io_Offset = fd->off & 0xFFFFFFFF; - fd->ioreq->iotd_Req.io_Actual = fd->off >> 32; - err = DoIO ((struct IORequest *) fd->ioreq); - if (err == IOERR_NOCMD && fd->is_64) - { - fd->is_64 = 0; - goto retry; - } - if (err) - { - grub_util_info ("I/O failed with error %d, IoErr=%d", (int)err, (int) IoErr ()); - stop_motor (fd); - return -1; - } - memcpy (buf, bounce, cr); - adj += cr; - len -= cr; - buf += cr; - } - - fd->off += adj; - stop_motor (fd); - return adj; -} - -static ssize_t -grub_util_fd_write_volume (grub_util_fd_t fd, const char *buf, size_t len) -{ - grub_uint64_t adj = 0; - if (!bounce) - bounce = AllocVec (BOUNCE_SIZE, MEMF_PUBLIC | MEMF_CLEAR); - if (!bounce) - grub_util_error ("out of memory"); - - while (len) - { - size_t cr = len; - LONG err; - if (cr > BOUNCE_SIZE) - cr = BOUNCE_SIZE; - retry: - if (fd->is_64) - fd->ioreq->iotd_Req.io_Command = NSCMD_TD_WRITE64; - else - fd->ioreq->iotd_Req.io_Command = CMD_WRITE; - fd->ioreq->iotd_Req.io_Length = cr; - fd->ioreq->iotd_Req.io_Data = bounce; - fd->ioreq->iotd_Req.io_Offset = fd->off & 0xFFFFFFFF; - fd->ioreq->iotd_Req.io_Actual = fd->off >> 32; - memcpy (bounce, buf, cr); - err = DoIO ((struct IORequest *) fd->ioreq); - if (err == IOERR_NOCMD && fd->is_64) - { - fd->is_64 = 0; - goto retry; - } - if (err) - { - grub_util_info ("I/O failed with error %d", err); - stop_motor (fd); - return -1; - } - - adj += cr; - len -= cr; - buf += cr; - } - - fd->off += adj; - stop_motor (fd); - return adj; -} - -ssize_t -grub_util_fd_read (grub_util_fd_t fd, char *buf, size_t len) -{ - switch (fd->type) - { - case GRUB_UTIL_FD_FILE: - return grub_util_fd_read_file (fd, buf, len); - case GRUB_UTIL_FD_DISK: - return grub_util_fd_read_volume (fd, buf, len); - } - return -1; -} - -ssize_t -grub_util_fd_write (grub_util_fd_t fd, const char *buf, size_t len) -{ - switch (fd->type) - { - case GRUB_UTIL_FD_FILE: - return grub_util_fd_write_file (fd, buf, len); - case GRUB_UTIL_FD_DISK: - return grub_util_fd_write_volume (fd, buf, len); - } - return -1; -} - -grub_uint64_t -grub_util_get_fd_size (grub_util_fd_t fd, - const char *dev, - unsigned *log_secsize) -{ - switch (fd->type) - { - case GRUB_UTIL_FD_FILE: - return grub_util_get_fd_size_file (fd, dev, log_secsize); - - case GRUB_UTIL_FD_DISK: - return grub_util_get_fd_size_volume (fd, dev, log_secsize); - } - return -1; -} - -int -grub_util_fd_close (grub_util_fd_t fd) -{ - switch (fd->type) - { - case GRUB_UTIL_FD_FILE: - return close (fd->fd); - case GRUB_UTIL_FD_DISK: - CloseDevice ((struct IORequest *) fd->ioreq); - DeleteIORequest((struct IORequest *) fd->ioreq); - DeleteMsgPort (fd->mp); - return 0; - } - return 0; -} - -static int allow_fd_syncs = 1; - -static int -grub_util_fd_sync_volume (grub_util_fd_t fd) -{ - LONG err; - - fd->ioreq->iotd_Req.io_Command = CMD_UPDATE; - fd->ioreq->iotd_Req.io_Length = 0; - fd->ioreq->iotd_Req.io_Data = 0; - fd->ioreq->iotd_Req.io_Offset = 0; - fd->ioreq->iotd_Req.io_Actual = 0; - err = DoIO ((struct IORequest *) fd->ioreq); - if (err) - { - grub_util_info ("I/O failed with error %d, IoErr=%d", (int)err, (int) IoErr ()); - return -1; - } - return 0; -} - -int -grub_util_fd_sync (grub_util_fd_t fd) -{ - if (allow_fd_syncs) - { - switch (fd->type) - { - case GRUB_UTIL_FD_FILE: - return fsync (fd->fd); - case GRUB_UTIL_FD_DISK: - return grub_util_fd_sync_volume (fd); - } - } - return 0; -} - -int -grub_util_file_sync (FILE *f) -{ - if (fflush (f) != 0) - return -1; - if (!allow_fd_syncs) - return 0; - return fsync (fileno (f)); -} - -void -grub_util_disable_fd_syncs (void) -{ - allow_fd_syncs = 0; -} - -void -grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused))) -{ -} - - -const char * -grub_util_fd_strerror (void) -{ - static char buf[201]; - LONG err = IoErr (); - if (!err) - return _("Success"); - memset (buf, '\0', sizeof (buf)); - Fault (err, (const unsigned char *) "", (STRPTR) buf, sizeof (buf)); - if (buf[0] == ':') - return buf + 1; - return buf; -} - -FILE * -grub_util_fopen (const char *path, const char *mode) -{ - return fopen (path, mode); -} - -int -grub_util_is_directory (const char *path) -{ - struct stat st; - - if (stat (path, &st) == -1) - return 0; - - return S_ISDIR (st.st_mode); -} - -int -grub_util_is_regular (const char *path) -{ - struct stat st; - - if (stat (path, &st) == -1) - return 0; - - return S_ISREG (st.st_mode); -} - -int -grub_util_is_special_file (const char *path) -{ - struct stat st; - - if (lstat (path, &st) == -1) - return 1; - return (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode)); -} - -static char * -get_temp_name (void) -{ - static int ctr = 0; - char *t; - struct stat st; - - while (1) - { - t = xasprintf ("T:grub.%d.%d.%d.%d", (int) getpid (), (int) getppid (), - ctr++, time (0)); - if (stat (t, &st) == -1) - return t; - free (t); - } -} - -char * -grub_util_make_temporary_file (void) -{ - char *ret = get_temp_name (); - FILE *f; - - f = grub_util_fopen (ret, "wb"); - if (f) - fclose (f); - return ret; -} - -char * -grub_util_make_temporary_dir (void) -{ - char *ret = get_temp_name (); - - grub_util_mkdir (ret); - - return ret; -} - -grub_uint32_t -grub_util_get_mtime (const char *path) -{ - struct stat st; - - if (stat (path, &st) == -1) - return 0; - - return st.st_mtime; -} diff --git a/grub-core/osdep/aros/relpath.c b/grub-core/osdep/aros/relpath.c deleted file mode 100644 index 9c2328d5f..000000000 --- a/grub-core/osdep/aros/relpath.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -char * -grub_make_system_path_relative_to_its_root (const char *path) -{ - char *p; - unsigned char *tmp; - char *ret; - BPTR lck; - - if (path[0] == '/' && path[1] == '/' && path[2] == ':') - return xstrdup (path); - - tmp = xmalloc (2048); - - lck = Lock ((const unsigned char *) path, SHARED_LOCK); - if (!lck || !NameFromLock (lck, tmp, 2040)) - { - free (tmp); - tmp = (unsigned char *) xstrdup (path); - } - if (lck) - UnLock (lck); - p = strchr ((char *) tmp, ':'); - if (!p) - return (char *) tmp; - if (p[1] == '/' || p[1] == '\0') - { - ret = xstrdup (p + 1); - } - else - { - ret = xmalloc (strlen (p + 1) + 2); - ret[0] = '/'; - strcpy (ret + 1, p + 1); - } - - free (tmp); - return ret; -} diff --git a/grub-core/osdep/basic/compress.c b/grub-core/osdep/basic/compress.c deleted file mode 100644 index dbca2906d..000000000 --- a/grub-core/osdep/basic/compress.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include - -int -grub_install_compress_gzip (const char *src, const char *dest) -{ - grub_util_error (_("no compression is available for your platform")); -} - -int -grub_install_compress_xz (const char *src, const char *dest) -{ - grub_util_error (_("no compression is available for your platform")); -} - -int -grub_install_compress_lzop (const char *src, const char *dest) -{ - grub_util_error (_("no compression is available for your platform")); -} diff --git a/grub-core/osdep/basic/emunet.c b/grub-core/osdep/basic/emunet.c deleted file mode 100644 index dbfd316d6..000000000 --- a/grub-core/osdep/basic/emunet.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include - -grub_ssize_t -grub_emunet_send (const void *packet __attribute__ ((unused)), - grub_size_t sz __attribute__ ((unused))) -{ - return -1; -} - -grub_ssize_t -grub_emunet_receive (void *packet __attribute__ ((unused)), - grub_size_t sz __attribute__ ((unused))) -{ - return -1; -} - -int -grub_emunet_create (grub_size_t *mtu) -{ - *mtu = 1500; - return -1; -} - -void -grub_emunet_close (void) -{ - return; -} diff --git a/grub-core/osdep/basic/getroot.c b/grub-core/osdep/basic/getroot.c deleted file mode 100644 index 8831eb3af..000000000 --- a/grub-core/osdep/basic/getroot.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIMITS_H -#include -#endif - -#include - -#include - -#include -#include -#include -#include -#include - - -char * -grub_util_part_to_disk (const char *os_dev, - struct stat *st __attribute__ ((unused)), - int *is_part) -{ - *is_part = 0; - return xstrdup (os_dev); -} - -enum grub_dev_abstraction_types -grub_util_get_dev_abstraction_os (const char *os_dev __attribute__((unused))) -{ - return GRUB_DEV_ABSTRACTION_NONE; -} - -int -grub_util_pull_device_os (const char *os_dev __attribute__ ((unused)), - enum grub_dev_abstraction_types ab __attribute__ ((unused))) -{ - return 0; -} - -char * -grub_util_get_grub_dev_os (const char *os_dev __attribute__ ((unused))) -{ - return NULL; -} - - -grub_disk_addr_t -grub_util_find_partition_start_os (const char *dev __attribute__ ((unused))) -{ - return 0; -} diff --git a/grub-core/osdep/basic/hostdisk.c b/grub-core/osdep/basic/hostdisk.c deleted file mode 100644 index 529bf29f3..000000000 --- a/grub-core/osdep/basic/hostdisk.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -grub_int64_t -grub_util_get_fd_size_os (grub_util_fd_t fd __attribute__ ((unused)), - const char *name __attribute__ ((unused)), - unsigned *log_secsize __attribute__ ((unused))) -{ -# warning "No special routine to get the size of a block device is implemented for your OS. This is not possibly fatal." - - return -1; -} - -void -grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused))) -{ -} diff --git a/grub-core/osdep/basic/init.c b/grub-core/osdep/basic/init.c deleted file mode 100644 index b104c7e16..000000000 --- a/grub-core/osdep/basic/init.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include - -#include "progname.h" - -void -grub_util_host_init (int *argc __attribute__ ((unused)), - char ***argv) -{ - set_program_name ((*argv)[0]); - -#if (defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); -#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ -} diff --git a/grub-core/osdep/basic/no_platform.c b/grub-core/osdep/basic/no_platform.c deleted file mode 100644 index d76c34c14..000000000 --- a/grub-core/osdep/basic/no_platform.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -#include "platform.c" - -void -grub_install_register_ieee1275 (int is_prep, const char *install_device, - int partno, const char *relpath) -{ - grub_util_error ("%s", _("no IEEE1275 routines are available for your platform")); -} - -void -grub_install_register_efi (grub_device_t efidir_grub_dev, - const char *efifile_path, - const char *efi_distributor) -{ - grub_util_error ("%s", _("no EFI routines are available for your platform")); -} - -void -grub_install_sgi_setup (const char *install_device, - const char *imgfile, const char *destname) -{ - grub_util_error ("%s", _("no SGI routines are available for your platform")); -} diff --git a/grub-core/osdep/basic/ofpath.c b/grub-core/osdep/basic/ofpath.c deleted file mode 100644 index c3fe06f68..000000000 --- a/grub-core/osdep/basic/ofpath.c +++ /dev/null @@ -1,29 +0,0 @@ -/* ofpath.c - calculate OpenFirmware path names given an OS device */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009, 2011,2012, 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -char * -grub_util_devname_to_ofpath (const char *sys_devname __attribute__ ((unused))) -{ - return NULL; -} - - diff --git a/grub-core/osdep/basic/platform.c b/grub-core/osdep/basic/platform.c deleted file mode 100644 index 68813de9a..000000000 --- a/grub-core/osdep/basic/platform.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -const char * -grub_install_get_default_arm_platform (void) -{ - return "arm-uboot"; -} - -const char * -grub_install_get_default_x86_platform (void) -{ - return "i386-pc"; -} - diff --git a/grub-core/osdep/basic/random.c b/grub-core/osdep/basic/random.c deleted file mode 100644 index b5ccad4ad..000000000 --- a/grub-core/osdep/basic/random.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1992-1999,2001,2003,2004,2005,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -int -grub_get_random (void *out, grub_size_t len) -{ -#warning "No random number generator is available for your OS. \ -Some functions like grub-mkpaswd and installing on UUID-less disks will be \ -disabled." - grub_util_error ("%s", - /* TRANSLATORS: The OS itself may very well have a random - number generator but GRUB doesn't know how to access it. */ - _("no random number generator is available for your OS")); -} diff --git a/grub-core/osdep/blocklist.c b/grub-core/osdep/blocklist.c deleted file mode 100644 index 1f58b0f3a..000000000 --- a/grub-core/osdep/blocklist.c +++ /dev/null @@ -1,7 +0,0 @@ -#ifdef __linux__ -#include "linux/blocklist.c" -#elif defined (__MINGW32__) || defined (__CYGWIN__) -#include "windows/blocklist.c" -#else -#include "generic/blocklist.c" -#endif diff --git a/grub-core/osdep/bsd/getroot.c b/grub-core/osdep/bsd/getroot.c deleted file mode 100644 index 8793d1e30..000000000 --- a/grub-core/osdep/bsd/getroot.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIMITS_H -#include -#endif - -#include - -#include - -#include -#include -#include -#include -#include - -#include - -# include -# include /* struct disklabel */ -# include /* struct dkwedge_info */ -# ifdef HAVE_GETRAWPARTITION -# include /* getrawpartition */ -# endif /* HAVE_GETRAWPARTITION */ -#if defined(__NetBSD__) -# include -#endif -#if defined(__OpenBSD__) -# include -#endif - -char * -grub_util_part_to_disk (const char *os_dev, struct stat *st, - int *is_part) -{ - int rawpart = -1; - - if (! S_ISCHR (st->st_mode)) - { - *is_part = 0; - return xstrdup (os_dev); - } - -# ifdef HAVE_GETRAWPARTITION - rawpart = getrawpartition(); -# endif /* HAVE_GETRAWPARTITION */ - if (rawpart < 0) - return xstrdup (os_dev); - -#if defined(__NetBSD__) - /* NetBSD disk wedges are of the form "/dev/rdk.*". */ - if (strncmp ("/dev/rdk", os_dev, sizeof("/dev/rdk") - 1) == 0) - { - struct dkwedge_info dkw; - int fd; - - fd = open (os_dev, O_RDONLY); - if (fd == -1) - { - grub_error (GRUB_ERR_BAD_DEVICE, - N_("cannot open `%s': %s"), os_dev, - strerror (errno)); - return xstrdup (os_dev); - } - if (ioctl (fd, DIOCGWEDGEINFO, &dkw) == -1) - { - grub_error (GRUB_ERR_BAD_DEVICE, - "cannot get disk wedge info of `%s'", os_dev); - close (fd); - return xstrdup (os_dev); - } - *is_part = (dkw.dkw_offset != 0); - close (fd); - return xasprintf ("/dev/r%s%c", dkw.dkw_parent, 'a' + rawpart); - } -#endif - - /* NetBSD (disk label) partitions are of the form "/dev/r[a-z]+[0-9][a-z]". */ - if (strncmp ("/dev/r", os_dev, sizeof("/dev/r") - 1) == 0 && - (os_dev[sizeof("/dev/r") - 1] >= 'a' && os_dev[sizeof("/dev/r") - 1] <= 'z') && - strncmp ("fd", os_dev + sizeof("/dev/r") - 1, sizeof("fd") - 1) != 0) /* not a floppy device name */ - { - char *path = xstrdup (os_dev); - char *p; - for (p = path + sizeof("/dev/r"); *p >= 'a' && *p <= 'z'; p++); - if (grub_isdigit(*p)) - { - p++; - if ((*p >= 'a' && *p <= 'z') && (*(p+1) == '\0')) - { - if (*p != 'a' + rawpart) - *is_part = 1; - /* path matches the required regular expression and - p points to its last character. */ - *p = 'a' + rawpart; - } - } - return path; - } - - return xstrdup (os_dev); -} - -enum grub_dev_abstraction_types -grub_util_get_dev_abstraction_os (const char *os_dev __attribute__((unused))) -{ - return GRUB_DEV_ABSTRACTION_NONE; -} - -int -grub_util_pull_device_os (const char *os_dev __attribute__ ((unused)), - enum grub_dev_abstraction_types ab __attribute__ ((unused))) -{ - return 0; -} - -char * -grub_util_get_grub_dev_os (const char *os_dev __attribute__ ((unused))) -{ - return NULL; -} - - -grub_disk_addr_t -grub_util_find_partition_start_os (const char *dev) -{ - int fd; -# if defined(__NetBSD__) - struct dkwedge_info dkw; -# endif /* defined(__NetBSD__) */ - struct disklabel label; - int p_index; - - fd = grub_util_fd_open (dev, O_RDONLY); - if (fd == -1) - { - grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot open `%s': %s"), - dev, strerror (errno)); - return 0; - } - -# if defined(__NetBSD__) - /* First handle the case of disk wedges. */ - if (ioctl (fd, DIOCGWEDGEINFO, &dkw) == 0) - { - close (fd); - return (grub_disk_addr_t) dkw.dkw_offset; - } -# endif /* defined(__NetBSD__) */ - - if (ioctl (fd, DIOCGDINFO, &label) == -1) - { - grub_error (GRUB_ERR_BAD_DEVICE, - "cannot get disk label of `%s'", dev); - close (fd); - return 0; - } - - close (fd); - - if (dev[0]) - p_index = dev[strlen(dev) - 1] - 'a'; - else - p_index = -1; - - if (p_index >= label.d_npartitions || p_index < 0) - { - grub_error (GRUB_ERR_BAD_DEVICE, - "no disk label entry for `%s'", dev); - return 0; - } - return (grub_disk_addr_t) label.d_partitions[p_index].p_offset; -} diff --git a/grub-core/osdep/bsd/hostdisk.c b/grub-core/osdep/bsd/hostdisk.c deleted file mode 100644 index 1a7ea97b4..000000000 --- a/grub-core/osdep/bsd/hostdisk.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -# include -# include /* struct disklabel */ -# include /* struct dkwedge_info */ -# ifdef HAVE_GETRAWPARTITION -# include /* getrawpartition */ -# endif /* HAVE_GETRAWPARTITION */ -# if defined(__NetBSD__) -# include -# endif -# if defined(__OpenBSD__) -# include -# endif - -#if defined(__NetBSD__) -# ifndef RAW_FLOPPY_MAJOR -# define RAW_FLOPPY_MAJOR 9 -# endif /* ! RAW_FLOPPY_MAJOR */ - -/* 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 (grub_util_fd_t 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; - } -} -grub_util_fd_t -grub_util_fd_open (const char *os_dev, int flags) -{ - grub_util_fd_t ret; - -#ifdef O_LARGEFILE - flags |= O_LARGEFILE; -#endif -#ifdef O_BINARY - flags |= O_BINARY; -#endif - - ret = open (os_dev, flags, S_IROTH | S_IRGRP | S_IRUSR | S_IWUSR); - if (ret >= 0) - configure_device_driver (ret); - return ret; -} - -#endif - -grub_int64_t -grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize) -{ - struct disklabel label; - unsigned sector_size, log_sector_size; - -#if defined(__NetBSD__) - configure_device_driver (fd); -#endif - - if (ioctl (fd, DIOCGDINFO, &label) == -1) - return -1; - - sector_size = label.d_secsize; - if (sector_size & (sector_size - 1) || !sector_size) - return -1; - log_sector_size = grub_log2ull (sector_size); - - if (log_secsize) - *log_secsize = log_sector_size; - - return (grub_uint64_t) label.d_secperunit << log_sector_size; -} - -void -grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused))) -{ -} diff --git a/grub-core/osdep/compress.c b/grub-core/osdep/compress.c deleted file mode 100644 index cc808d029..000000000 --- a/grub-core/osdep/compress.c +++ /dev/null @@ -1,5 +0,0 @@ -#if !defined (__MINGW32__) && !defined (__CYGWIN__) && !defined (__AROS__) -#include "unix/compress.c" -#else -#include "basic/compress.c" -#endif diff --git a/grub-core/osdep/config.c b/grub-core/osdep/config.c deleted file mode 100644 index b9f781972..000000000 --- a/grub-core/osdep/config.c +++ /dev/null @@ -1,7 +0,0 @@ -#if defined (__MINGW32__) && !defined (__CYGWIN__) -#include "windows/config.c" -#elif defined (__AROS__) -#include "aros/config.c" -#else -#include "unix/config.c" -#endif diff --git a/grub-core/osdep/cputime.c b/grub-core/osdep/cputime.c deleted file mode 100644 index d3ee4c865..000000000 --- a/grub-core/osdep/cputime.c +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef __MINGW32__ -#include "windows/cputime.c" -#else -#include "unix/cputime.c" -#endif diff --git a/grub-core/osdep/devmapper/getroot.c b/grub-core/osdep/devmapper/getroot.c deleted file mode 100644 index 5fb21aff9..000000000 --- a/grub-core/osdep/devmapper/getroot.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include - -#ifdef HAVE_DEVICE_MAPPER - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIMITS_H -#include -#endif - -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -static int -grub_util_open_dm (const char *os_dev, struct dm_tree **tree, - struct dm_tree_node **node) -{ - uint32_t maj, min; - struct stat st; - - *node = NULL; - *tree = NULL; - - if (stat (os_dev, &st) < 0) - return 0; - - maj = major (st.st_rdev); - min = minor (st.st_rdev); - - if (!dm_is_dm_major (maj)) - return 0; - - *tree = dm_tree_create (); - if (! *tree) - { - grub_puts_ (N_("Failed to create `device-mapper' tree")); - grub_dprintf ("hostdisk", "dm_tree_create failed\n"); - return 0; - } - - if (! dm_tree_add_dev (*tree, maj, min)) - { - grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n"); - dm_tree_free (*tree); - *tree = NULL; - return 0; - } - - *node = dm_tree_find_node (*tree, maj, min); - if (! *node) - { - grub_dprintf ("hostdisk", "dm_tree_find_node failed\n"); - dm_tree_free (*tree); - *tree = NULL; - return 0; - } - return 1; -} - -static char * -get_dm_uuid (const char *os_dev) -{ - struct dm_tree *tree; - struct dm_tree_node *node; - const char *node_uuid; - char *ret; - - if (!grub_util_open_dm (os_dev, &tree, &node)) - return NULL; - - node_uuid = dm_tree_node_get_uuid (node); - if (! node_uuid) - { - grub_dprintf ("hostdisk", "%s has no DM uuid\n", os_dev); - dm_tree_free (tree); - return NULL; - } - - ret = grub_strdup (node_uuid); - - dm_tree_free (tree); - - return ret; -} - -enum grub_dev_abstraction_types -grub_util_get_dm_abstraction (const char *os_dev) -{ - char *uuid; - - uuid = get_dm_uuid (os_dev); - - if (uuid == NULL) - return GRUB_DEV_ABSTRACTION_NONE; - - if (strncmp (uuid, "LVM-", 4) == 0) - { - grub_free (uuid); - return GRUB_DEV_ABSTRACTION_LVM; - } - if (strncmp (uuid, "CRYPT-LUKS1-", sizeof ("CRYPT-LUKS1-") - 1) == 0 - || strncmp (uuid, "CRYPT-LUKS2-", sizeof ("CRYPT-LUKS2-") - 1) == 0) - { - grub_free (uuid); - return GRUB_DEV_ABSTRACTION_LUKS; - } - - grub_free (uuid); - return GRUB_DEV_ABSTRACTION_NONE; -} - -void -grub_util_pull_devmapper (const char *os_dev) -{ - struct dm_tree *tree; - struct dm_tree_node *node; - struct dm_tree_node *child; - void *handle = NULL; - char *lastsubdev = NULL; - char *uuid; - - uuid = get_dm_uuid (os_dev); - - if (!grub_util_open_dm (os_dev, &tree, &node)) - { - grub_free (uuid); - return; - } - - while ((child = dm_tree_next_child (&handle, node, 0))) - { - const struct dm_info *dm = dm_tree_node_get_info (child); - char *subdev; - if (!dm) - continue; - subdev = grub_find_device ("/dev", makedev (dm->major, dm->minor)); - if (subdev) - { - lastsubdev = subdev; - grub_util_pull_device (subdev); - } - } - if (uuid - && (strncmp (uuid, "CRYPT-LUKS1-", sizeof ("CRYPT-LUKS1-") - 1) == 0 - || strncmp (uuid, "CRYPT-LUKS2-", sizeof ("CRYPT-LUKS2-") - 1) == 0) - && lastsubdev) - { - char *grdev = grub_util_get_grub_dev (lastsubdev); - if (grdev) - { - grub_err_t err; - err = grub_cryptodisk_cheat_mount (grdev, os_dev); - if (err) - grub_util_error (_("can't mount encrypted volume `%s': %s"), - lastsubdev, grub_errmsg); - if (strncmp (uuid, "CRYPT-LUKS2-", sizeof ("CRYPT-LUKS2-") - 1) == 0) - { - /* - * Set LUKS2 cipher from dm parameters, since it is not - * possible to determine the correct one without - * unlocking, as there might be multiple segments. - */ - grub_disk_t source; - grub_cryptodisk_t cryptodisk; - grub_uint64_t start, length; - char *target_type; - char *params; - const char *name; - char *cipher, *cipher_mode; - struct dm_task *dmt; - char *seek_head, *c; - unsigned int remaining; - - source = grub_disk_open (grdev); - if (! source) - grub_util_error (_("cannot open grub disk `%s'"), grdev); - cryptodisk = grub_cryptodisk_get_by_source_disk (source); - if (! cryptodisk) - grub_util_error (_("cannot get cryptodisk from source disk `%s'"), grdev); - grub_disk_close (source); - - /* - * The following function always returns a non-NULL pointer, - * but the string may be empty if the relevant info is not present. - */ - name = dm_tree_node_get_name (node); - if (*name == '\0') - grub_util_error (_("cannot get dm node name for grub dev `%s'"), grdev); - - grub_util_info ("populating parameters of cryptomount `%s' from DM device `%s'", - uuid, name); - - dmt = dm_task_create (DM_DEVICE_TABLE); - if (dmt == NULL) - grub_util_error (_("can't create dm task DM_DEVICE_TABLE")); - if (dm_task_set_name (dmt, name) == 0) - grub_util_error (_("can't set dm task name to `%s'"), name); - if (dm_task_run (dmt) == 0) - grub_util_error (_("can't run dm task for `%s'"), name); - /* - * dm_get_next_target() doesn't have any error modes, everything has - * been handled by dm_task_run(). - */ - dm_get_next_target (dmt, NULL, &start, &length, - &target_type, ¶ms); - if (strncmp (target_type, "crypt", sizeof ("crypt")) != 0) - grub_util_error (_("dm target of type `%s' is not `crypt'"), target_type); - - /* - * The dm target parameters for dm-crypt are - * [<#opt_params> ...] - */ - c = params; - remaining = grub_strlen (c); - - /* First, get the cipher name from the cipher. */ - seek_head = grub_memchr (c, '-', remaining); - if (seek_head == NULL) - grub_util_error (_("can't get cipher from dm-crypt parameters `%s'"), - params); - cipher = grub_strndup (c, seek_head - c); - if (cipher == NULL) - grub_util_error ("could not strndup cipher of length `%" PRIuGRUB_SIZE "'", (grub_size_t) (seek_head - c)); - remaining -= seek_head - c + 1; - c = seek_head + 1; - - /* Now, the cipher mode. */ - seek_head = grub_memchr (c, ' ', remaining); - if (seek_head == NULL) - grub_util_error (_("can't get cipher mode from dm-crypt parameters `%s'"), - params); - cipher_mode = grub_strndup (c, seek_head - c); - if (cipher_mode == NULL) - grub_util_error ("could not strndup cipher_mode of length `%" PRIuGRUB_SIZE "'", (grub_size_t) (seek_head - c)); - - remaining -= seek_head - c + 1; - c = seek_head + 1; - - err = grub_cryptodisk_setcipher (cryptodisk, cipher, cipher_mode); - if (err) - grub_util_error (_("can't set cipher of cryptodisk `%s' to `%s' with mode `%s'"), - uuid, cipher, cipher_mode); - - grub_free (cipher); - grub_free (cipher_mode); - - /* - * This is the only hash usable by PBKDF2, and we don't - * have Argon2 support yet, so set it by default, - * otherwise grub-probe would miss the required - * abstraction. - */ - cryptodisk->hash = grub_crypto_lookup_md_by_name ("sha256"); - if (cryptodisk->hash == NULL) - grub_util_error (_("can't lookup hash sha256 by name")); - - dm_task_destroy (dmt); - } - } - dm_tree_free (tree); - grub_free (grdev); - } - else - dm_tree_free (tree); - grub_free (uuid); -} - -char * -grub_util_devmapper_part_to_disk (struct stat *st, - int *is_part, const char *path) -{ - int major, minor; - - if (grub_util_get_dm_node_linear_info (st->st_rdev, - &major, &minor, 0)) - { - *is_part = 1; - return grub_find_device ("/dev", makedev (major, minor)); - } - *is_part = 0; - return xstrdup (path); -} - -char * -grub_util_get_devmapper_grub_dev (const char *os_dev) -{ - char *uuid, *optr; - char *grub_dev; - - uuid = get_dm_uuid (os_dev); - if (!uuid) - return NULL; - - switch (grub_util_get_dev_abstraction (os_dev)) - { - case GRUB_DEV_ABSTRACTION_LVM: - { - unsigned i; - int dashes[] = { 0, 6, 10, 14, 18, 22, 26, 32, 38, 42, 46, 50, 54, 58}; - - grub_dev = xmalloc (grub_strlen (uuid) + 40); - optr = grub_stpcpy (grub_dev, "lvmid/"); - for (i = 0; i < ARRAY_SIZE (dashes) - 1; i++) - { - memcpy (optr, uuid + sizeof ("LVM-") - 1 + dashes[i], - dashes[i+1] - dashes[i]); - optr += dashes[i+1] - dashes[i]; - *optr++ = '-'; - } - optr = stpcpy (optr, uuid + sizeof ("LVM-") - 1 + dashes[i]); - *optr = '\0'; - grub_dev[sizeof("lvmid/xxxxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxxxx") - 1] - = '/'; - free (uuid); - return grub_dev; - } - - case GRUB_DEV_ABSTRACTION_LUKS: - { - char *dash; - - dash = grub_strchr (uuid + sizeof ("CRYPT-LUKS*-") - 1, '-'); - if (dash) - *dash = 0; - grub_dev = grub_xasprintf ("cryptouuid/%s", - uuid + sizeof ("CRYPT-LUKS*-") - 1); - grub_free (uuid); - return grub_dev; - } - - default: - grub_free (uuid); - return NULL; - } -} - -char * -grub_util_get_vg_uuid (const char *os_dev) -{ - char *uuid, *vgid; - int dashes[] = { 0, 6, 10, 14, 18, 22, 26, 32}; - unsigned i; - char *optr; - - uuid = get_dm_uuid (os_dev); - if (!uuid) - return NULL; - - vgid = xmalloc (grub_strlen (uuid)); - optr = vgid; - for (i = 0; i < ARRAY_SIZE (dashes) - 1; i++) - { - memcpy (optr, uuid + sizeof ("LVM-") - 1 + dashes[i], - dashes[i+1] - dashes[i]); - optr += dashes[i+1] - dashes[i]; - *optr++ = '-'; - } - optr--; - *optr = '\0'; - grub_free (uuid); - return vgid; -} - -void -grub_util_devmapper_cleanup (void) -{ - dm_lib_release (); -} - -#else -void -grub_util_pull_devmapper (const char *os_dev __attribute__ ((unused))) -{ - return; -} - -void -grub_util_devmapper_cleanup (void) -{ -} - -enum grub_dev_abstraction_types -grub_util_get_dm_abstraction (const char *os_dev __attribute__ ((unused))) -{ - return GRUB_DEV_ABSTRACTION_NONE; -} - -char * -grub_util_get_vg_uuid (const char *os_dev __attribute__ ((unused))) -{ - return NULL; -} - -char * -grub_util_devmapper_part_to_disk (struct stat *st __attribute__ ((unused)), - int *is_part __attribute__ ((unused)), - const char *os_dev __attribute__ ((unused))) -{ - return NULL; -} - -char * -grub_util_get_devmapper_grub_dev (const char *os_dev __attribute__ ((unused))) -{ - return NULL; -} - -#endif diff --git a/grub-core/osdep/devmapper/hostdisk.c b/grub-core/osdep/devmapper/hostdisk.c deleted file mode 100644 index f98ecc53c..000000000 --- a/grub-core/osdep/devmapper/hostdisk.c +++ /dev/null @@ -1,225 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_DEVICE_MAPPER -# include - -static void device_mapper_null_log (int level __attribute__ ((unused)), - const char *file __attribute__ ((unused)), - int line __attribute__ ((unused)), - int dm_errno __attribute__ ((unused)), - const char *f __attribute__ ((unused)), - ...) -{ -} - -int -grub_device_mapper_supported (void) -{ - static int supported = -1; - - if (supported == -1) - { - struct dm_task *dmt; - - /* Suppress annoying log messages. */ - dm_log_with_errno_init (&device_mapper_null_log); - - dmt = dm_task_create (DM_DEVICE_VERSION); - supported = (dmt != NULL); - if (dmt) - dm_task_destroy (dmt); - - /* Restore the original logger. */ - dm_log_with_errno_init (NULL); - } - - return supported; -} - -int -grub_util_device_is_mapped (const char *dev) -{ - struct stat st; - - if (!grub_device_mapper_supported ()) - return 0; - - if (stat (dev, &st) < 0) - return 0; - -#if GRUB_DISK_DEVS_ARE_CHAR - if (! S_ISCHR (st.st_mode)) -#else - if (! S_ISBLK (st.st_mode)) -#endif - return 0; - - return dm_is_dm_major (major (st.st_rdev)); -} - -int -grub_util_device_is_mapped_stat (struct stat *st) -{ -#if GRUB_DISK_DEVS_ARE_CHAR - if (! S_ISCHR (st->st_mode)) -#else - if (! S_ISBLK (st->st_mode)) -#endif - return 0; - - if (!grub_device_mapper_supported ()) - return 0; - - return dm_is_dm_major (major (st->st_rdev)); -} - - -int -grub_util_get_dm_node_linear_info (dev_t dev, - int *maj, int *min, - grub_disk_addr_t *st) -{ - struct dm_task *dmt; - void *next = NULL; - uint64_t length, start; - char *target, *params; - const char *ptr; - int major = 0, minor = 0; - int first = 1; - grub_disk_addr_t partstart = 0; - const char *node_uuid; - - major = major (dev); - minor = minor (dev); - - while (1) - { - dmt = dm_task_create(DM_DEVICE_TABLE); - if (!dmt) - break; - - if (! (dm_task_set_major_minor (dmt, major, minor, 0))) - { - dm_task_destroy (dmt); - break; - } - dm_task_no_open_count(dmt); - if (!dm_task_run(dmt)) - { - dm_task_destroy (dmt); - break; - } - node_uuid = dm_task_get_uuid (dmt); - if (node_uuid && (strncmp (node_uuid, "LVM-", 4) == 0 - || strncmp (node_uuid, "mpath-", 6) == 0)) - { - dm_task_destroy (dmt); - break; - } - - next = dm_get_next_target(dmt, next, &start, &length, - &target, ¶ms); - if (grub_strcmp (target, "linear") != 0) - { - dm_task_destroy (dmt); - break; - } - major = grub_strtoul (params, &ptr, 10); - if (grub_errno) - { - dm_task_destroy (dmt); - grub_errno = GRUB_ERR_NONE; - return 0; - } - if (*ptr != ':') - { - dm_task_destroy (dmt); - return 0; - } - ptr++; - minor = grub_strtoul (ptr, &ptr, 10); - if (grub_errno) - { - grub_errno = GRUB_ERR_NONE; - dm_task_destroy (dmt); - return 0; - } - - if (*ptr != ' ') - { - dm_task_destroy (dmt); - return 0; - } - ptr++; - partstart += grub_strtoull (ptr, &ptr, 10); - if (grub_errno) - { - grub_errno = GRUB_ERR_NONE; - dm_task_destroy (dmt); - return 0; - } - - dm_task_destroy (dmt); - first = 0; - if (!dm_is_dm_major (major)) - break; - } - if (first) - return 0; - if (maj) - *maj = major; - if (min) - *min = minor; - if (st) - *st = partstart; - return 1; -} -#else - -int -grub_util_device_is_mapped (const char *dev __attribute__ ((unused))) -{ - return 0; -} - -int -grub_util_get_dm_node_linear_info (dev_t dev __attribute__ ((unused)), - int *maj __attribute__ ((unused)), - int *min __attribute__ ((unused)), - grub_disk_addr_t *st __attribute__ ((unused))) -{ - return 0; -} - -int -grub_util_device_is_mapped_stat (struct stat *st __attribute__ ((unused))) -{ - return 0; -} - -#endif diff --git a/grub-core/osdep/dl.c b/grub-core/osdep/dl.c deleted file mode 100644 index c51174763..000000000 --- a/grub-core/osdep/dl.c +++ /dev/null @@ -1,5 +0,0 @@ -#if defined (__MINGW32__) || defined (__CYGWIN__) -#include "windows/dl.c" -#else -#include "unix/dl.c" -#endif diff --git a/grub-core/osdep/emuconsole.c b/grub-core/osdep/emuconsole.c deleted file mode 100644 index 13ede31d1..000000000 --- a/grub-core/osdep/emuconsole.c +++ /dev/null @@ -1,5 +0,0 @@ -#if defined (__MINGW32__) && !defined (__CYGWIN__) -#include "windows/emuconsole.c" -#else -#include "unix/emuconsole.c" -#endif diff --git a/grub-core/osdep/emunet.c b/grub-core/osdep/emunet.c deleted file mode 100644 index 4b0bac4a8..000000000 --- a/grub-core/osdep/emunet.c +++ /dev/null @@ -1,5 +0,0 @@ -#if defined (__linux__) -#include "linux/emunet.c" -#else -#include "basic/emunet.c" -#endif diff --git a/grub-core/osdep/exec.c b/grub-core/osdep/exec.c deleted file mode 100644 index 9dcd926c1..000000000 --- a/grub-core/osdep/exec.c +++ /dev/null @@ -1,3 +0,0 @@ -#if (!defined (__MINGW32__) || defined (__CYGWIN__)) && !defined (__AROS__) -#include "unix/exec.c" -#endif diff --git a/grub-core/osdep/freebsd/getroot.c b/grub-core/osdep/freebsd/getroot.c deleted file mode 100644 index 2ff6bfa36..000000000 --- a/grub-core/osdep/freebsd/getroot.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIMITS_H -#include -#endif - -#include -# include -# include -# include /* DIOCGMEDIASIZE */ -# include -# include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#define LVM_DEV_MAPPER_STRING "/dev/linux_lvm/" - -static const char * -grub_util_get_geom_abstraction (const char *dev) -{ - char *whole; - struct gmesh mesh; - struct gclass *class; - const char *name; - int err; - - if (strncmp (dev, "/dev/", sizeof ("/dev/") - 1) != 0) - return 0; - name = dev + sizeof ("/dev/") - 1; - grub_util_follow_gpart_up (name, NULL, &whole); - - grub_util_info ("following geom '%s'", name); - - err = geom_gettree (&mesh); - if (err != 0) - /* TRANSLATORS: geom is the name of (k)FreeBSD device framework. - Usually left untranslated. - */ - grub_util_error ("%s", _("couldn't open geom")); - - LIST_FOREACH (class, &mesh.lg_class, lg_class) - { - struct ggeom *geom; - LIST_FOREACH (geom, &class->lg_geom, lg_geom) - { - struct gprovider *provider; - LIST_FOREACH (provider, &geom->lg_provider, lg_provider) - if (strcmp (provider->lg_name, name) == 0) - return class->lg_name; - } - } - return NULL; -} - -enum grub_dev_abstraction_types -grub_util_get_dev_abstraction_os (const char *os_dev) -{ - const char *abstrac; - abstrac = grub_util_get_geom_abstraction (os_dev); - grub_util_info ("abstraction of %s is %s", os_dev, abstrac); - if (abstrac && grub_strcasecmp (abstrac, "eli") == 0) - return GRUB_DEV_ABSTRACTION_GELI; - - /* Check for LVM. */ - if (!strncmp (os_dev, LVM_DEV_MAPPER_STRING, sizeof(LVM_DEV_MAPPER_STRING)-1)) - return GRUB_DEV_ABSTRACTION_LVM; - return GRUB_DEV_ABSTRACTION_NONE; -} - -char * -grub_util_part_to_disk (const char *os_dev, struct stat *st, - int *is_part) -{ - char *out, *out2; - - if (! S_ISCHR (st->st_mode)) - { - *is_part = 0; - return xstrdup (os_dev); - } - - if (strncmp (os_dev, "/dev/", sizeof ("/dev/") - 1) != 0) - return xstrdup (os_dev); - grub_util_follow_gpart_up (os_dev + sizeof ("/dev/") - 1, NULL, &out); - - if (grub_strcmp (os_dev + sizeof ("/dev/") - 1, out) != 0) - *is_part = 1; - out2 = xasprintf ("/dev/%s", out); - free (out); - - return out2; -} - -int -grub_util_pull_device_os (const char *os_dev, - enum grub_dev_abstraction_types ab) -{ - switch (ab) - { - case GRUB_DEV_ABSTRACTION_GELI: - { - char *whole; - struct gmesh mesh; - struct gclass *class; - const char *name; - int err; - char *lastsubdev = NULL; - - if (strncmp (os_dev, "/dev/", sizeof ("/dev/") - 1) != 0) - return 1; - name = os_dev + sizeof ("/dev/") - 1; - grub_util_follow_gpart_up (name, NULL, &whole); - - grub_util_info ("following geom '%s'", name); - - err = geom_gettree (&mesh); - if (err != 0) - /* TRANSLATORS: geom is the name of (k)FreeBSD device framework. - Usually left untranslated. - */ - grub_util_error ("%s", _("couldn't open geom")); - - LIST_FOREACH (class, &mesh.lg_class, lg_class) - { - struct ggeom *geom; - LIST_FOREACH (geom, &class->lg_geom, lg_geom) - { - struct gprovider *provider; - LIST_FOREACH (provider, &geom->lg_provider, lg_provider) - if (strcmp (provider->lg_name, name) == 0) - { - struct gconsumer *consumer; - char *fname; - - LIST_FOREACH (consumer, &geom->lg_consumer, lg_consumer) - break; - if (!consumer) - grub_util_error ("%s", - _("couldn't find geli consumer")); - fname = xasprintf ("/dev/%s", consumer->lg_provider->lg_name); - grub_util_info ("consumer %s", consumer->lg_provider->lg_name); - lastsubdev = consumer->lg_provider->lg_name; - grub_util_pull_device (fname); - free (fname); - } - } - } - if (ab == GRUB_DEV_ABSTRACTION_GELI && lastsubdev) - { - char *fname = xasprintf ("/dev/%s", lastsubdev); - char *grdev = grub_util_get_grub_dev (fname); - free (fname); - - if (grdev) - { - grub_err_t gr_err; - gr_err = grub_cryptodisk_cheat_mount (grdev, os_dev); - if (gr_err) - grub_util_error (_("can't mount encrypted volume `%s': %s"), - lastsubdev, grub_errmsg); - } - - grub_free (grdev); - } - } - return 1; - default: - return 0; - } -} - -char * -grub_util_get_grub_dev_os (const char *os_dev) -{ - char *grub_dev = NULL; - - switch (grub_util_get_dev_abstraction (os_dev)) - { - /* Fallback for non-devmapper build. In devmapper-builds LVM is handled - in rub_util_get_devmapper_grub_dev and this point isn't reached. - */ - case GRUB_DEV_ABSTRACTION_LVM: - { - unsigned short len; - grub_size_t offset = sizeof (LVM_DEV_MAPPER_STRING) - 1; - - len = strlen (os_dev) - offset + 1; - grub_dev = xmalloc (len + sizeof ("lvm/")); - - grub_memcpy (grub_dev, "lvm/", sizeof ("lvm/") - 1); - grub_memcpy (grub_dev + sizeof ("lvm/") - 1, os_dev + offset, len); - } - break; - - case GRUB_DEV_ABSTRACTION_GELI: - { - char *whole; - struct gmesh mesh; - struct gclass *class; - const char *name; - int err; - - if (strncmp (os_dev, "/dev/", sizeof ("/dev/") - 1) != 0) - return 0; - name = os_dev + sizeof ("/dev/") - 1; - grub_util_follow_gpart_up (name, NULL, &whole); - - grub_util_info ("following geom '%s'", name); - - err = geom_gettree (&mesh); - if (err != 0) - /* TRANSLATORS: geom is the name of (k)FreeBSD device framework. - Usually left untranslated. - */ - grub_util_error ("%s", _("couldn't open geom")); - - LIST_FOREACH (class, &mesh.lg_class, lg_class) - { - struct ggeom *geom; - LIST_FOREACH (geom, &class->lg_geom, lg_geom) - { - struct gprovider *provider; - LIST_FOREACH (provider, &geom->lg_provider, lg_provider) - if (strcmp (provider->lg_name, name) == 0) - { - struct gconsumer *consumer; - char *fname; - char *uuid; - - LIST_FOREACH (consumer, &geom->lg_consumer, lg_consumer) - break; - if (!consumer) - grub_util_error ("%s", - _("couldn't find geli consumer")); - fname = xasprintf ("/dev/%s", consumer->lg_provider->lg_name); - uuid = grub_util_get_geli_uuid (fname); - if (!uuid) - grub_util_error ("%s", - _("couldn't retrieve geli UUID")); - grub_dev = xasprintf ("cryptouuid/%s", uuid); - free (fname); - free (uuid); - } - } - } - } - break; - - default: - break; - } - - return grub_dev; -} - -/* FIXME: geom actually gives us the whole container hierarchy. - It can be used more efficiently than this. */ -void -grub_util_follow_gpart_up (const char *name, grub_disk_addr_t *off_out, char **name_out) -{ - struct gmesh mesh; - struct gclass *class; - int err; - struct ggeom *geom; - - grub_util_info ("following geom '%s'", name); - - err = geom_gettree (&mesh); - if (err != 0) - /* TRANSLATORS: geom is the name of (k)FreeBSD device framework. - Usually left untranslated. - */ - grub_util_error ("%s", _("couldn't open geom")); - - LIST_FOREACH (class, &mesh.lg_class, lg_class) - if (strcasecmp (class->lg_name, "part") == 0) - break; - if (!class) - /* TRANSLATORS: geom is the name of (k)FreeBSD device framework. - Usually left untranslated. "part" is the identifier of one of its - classes. */ - grub_util_error ("%s", _("couldn't find geom `part' class")); - - LIST_FOREACH (geom, &class->lg_geom, lg_geom) - { - struct gprovider *provider; - LIST_FOREACH (provider, &geom->lg_provider, lg_provider) - if (strcmp (provider->lg_name, name) == 0) - { - char *name_tmp = xstrdup (geom->lg_name); - grub_disk_addr_t off = 0; - struct gconfig *config; - grub_util_info ("geom '%s' has parent '%s'", name, geom->lg_name); - - grub_util_follow_gpart_up (name_tmp, &off, name_out); - free (name_tmp); - LIST_FOREACH (config, &provider->lg_config, lg_config) - if (strcasecmp (config->lg_name, "offset") == 0) - off += strtoull (config->lg_val, 0, 10) / provider->lg_sectorsize; - if (off_out) - *off_out = off; - return; - } - } - grub_util_info ("geom '%s' has no parent", name); - if (name_out) - *name_out = xstrdup (name); - if (off_out) - *off_out = 0; -} - -grub_disk_addr_t -grub_util_find_partition_start_os (const char *dev) -{ - grub_disk_addr_t out; - if (strncmp (dev, "/dev/", sizeof ("/dev/") - 1) != 0) - return 0; - grub_util_follow_gpart_up (dev + sizeof ("/dev/") - 1, &out, NULL); - - return out; -} diff --git a/grub-core/osdep/freebsd/hostdisk.c b/grub-core/osdep/freebsd/hostdisk.c deleted file mode 100644 index 8bfe7d488..000000000 --- a/grub-core/osdep/freebsd/hostdisk.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -# include /* DIOCGMEDIASIZE */ -# include -# include -# include -# include - -grub_int64_t -grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize) -{ - unsigned long long nr; - unsigned sector_size, log_sector_size; - - if (ioctl (fd, DIOCGMEDIASIZE, &nr)) - return -1; - - if (ioctl (fd, DIOCGSECTORSIZE, §or_size)) - return -1; - if (sector_size & (sector_size - 1) || !sector_size) - return -1; - log_sector_size = grub_log2ull (sector_size); - - if (log_secsize) - *log_secsize = log_sector_size; - - if (nr & (sector_size - 1)) - grub_util_error ("%s", _("unaligned device size")); - - return nr; -} - -void -grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused))) -{ -} - -grub_util_fd_t -grub_util_fd_open (const char *os_dev, int flags) -{ - grub_util_fd_t ret; - int sysctl_flags, sysctl_oldflags; - size_t sysctl_size = sizeof (sysctl_flags); - -#ifdef O_LARGEFILE - flags |= O_LARGEFILE; -#endif -#ifdef O_BINARY - flags |= O_BINARY; -#endif - - 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 GRUB_UTIL_FD_INVALID; - } - sysctl_flags = sysctl_oldflags | 0x10; - if (! (sysctl_oldflags & 0x10) - && sysctlbyname ("kern.geom.debugflags", NULL , 0, &sysctl_flags, sysctl_size)) - { - if (errno == EPERM) - /* Running as an unprivileged user; don't worry about restoring - flags, although if we try to write to anything interesting such - as the MBR then we may fail later. */ - sysctl_oldflags = 0x10; - else - { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot set flags of sysctl kern.geom.debugflags"); - return GRUB_UTIL_FD_INVALID; - } - } - - ret = open (os_dev, flags, S_IROTH | S_IRGRP | S_IRUSR | S_IWUSR); - - 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"); - close (ret); - return GRUB_UTIL_FD_INVALID; - } - - return ret; -} diff --git a/grub-core/osdep/generic/blocklist.c b/grub-core/osdep/generic/blocklist.c deleted file mode 100644 index 9ff8e44c6..000000000 --- a/grub-core/osdep/generic/blocklist.c +++ /dev/null @@ -1,156 +0,0 @@ -/* grub-setup.c - make GRUB usable */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#define MAX_TRIES 5 - -struct wrapper_hook_data -{ - void (*callback) (grub_disk_addr_t sector, - unsigned int offset, - unsigned int length, - void *data); - void *callback_data; -}; - -static grub_err_t -callback_wrapper (grub_disk_addr_t sector, - unsigned int offset, unsigned int length, - char *buf, void *data) -{ - struct wrapper_hook_data *wrap = data; - - wrap->callback (sector, offset, length, wrap->callback_data); - return GRUB_ERR_NONE; -} - -void -grub_install_get_blocklist (grub_device_t root_dev, - const char *core_path, const char *core_img, - size_t core_size, - void (*callback) (grub_disk_addr_t sector, - unsigned offset, - unsigned length, - void *data), - void *hook_data) -{ - int i; - char *tmp_img; - char *core_path_dev; - struct wrapper_hook_data wrap_hook_data = { - .callback = callback, - .callback_data = hook_data - }; - - core_path_dev = grub_make_system_path_relative_to_its_root (core_path); - - /* Make sure that GRUB reads the identical image as the OS. */ - tmp_img = xmalloc (core_size); - - for (i = 0; i < MAX_TRIES; i++) - { - grub_file_t file; - - grub_util_info ((i == 0) ? _("attempting to read the core image `%s' from GRUB") - : _("attempting to read the core image `%s' from GRUB again"), - core_path_dev); - - grub_disk_cache_invalidate_all (); - - file = grub_file_open (core_path_dev, GRUB_FILE_TYPE_NONE | GRUB_FILE_TYPE_NO_DECOMPRESS); - if (file) - { - if (grub_file_size (file) != core_size) - grub_util_info ("succeeded in opening the core image but the size is different (%d != %d)", - (int) grub_file_size (file), (int) core_size); - else if (grub_file_read (file, tmp_img, core_size) - != (grub_ssize_t) core_size) - grub_util_info ("succeeded in opening the core image but cannot read %d bytes", - (int) core_size); - else if (memcmp (core_img, tmp_img, core_size) != 0) - { -#if 0 - FILE *dump; - FILE *dump2; - - dump = fopen ("dump.img", "wb"); - if (dump) - { - fwrite (tmp_img, 1, core_size, dump); - fclose (dump); - } - - dump2 = fopen ("dump2.img", "wb"); - if (dump2) - { - fwrite (core_img, 1, core_size, dump2); - fclose (dump2); - } - -#endif - grub_util_info ("succeeded in opening the core image but the data is different"); - } - else - { - grub_file_close (file); - break; - } - - grub_file_close (file); - } - else - grub_util_info ("couldn't open the core image"); - - if (grub_errno) - grub_util_info ("error message = %s", grub_errmsg); - - grub_errno = GRUB_ERR_NONE; - grub_util_biosdisk_flush (root_dev->disk); - sleep (1); - } - - if (i == MAX_TRIES) - grub_util_error (_("cannot read `%s' correctly"), core_path_dev); - - grub_file_t file; - /* Now read the core image to determine where the sectors are. */ - file = grub_file_open (core_path_dev, GRUB_FILE_TYPE_NONE | GRUB_FILE_TYPE_NO_DECOMPRESS); - if (! file) - grub_util_error ("%s", grub_errmsg); - - file->read_hook = callback_wrapper; - file->read_hook_data = &wrap_hook_data; - if (grub_file_read (file, tmp_img, core_size) != (grub_ssize_t) core_size) - grub_util_error ("%s", _("failed to read the sectors of the core image")); - - grub_file_close (file); - free (tmp_img); - - free (core_path_dev); -} diff --git a/grub-core/osdep/getroot.c b/grub-core/osdep/getroot.c deleted file mode 100644 index 69a80e9a8..000000000 --- a/grub-core/osdep/getroot.c +++ /dev/null @@ -1,22 +0,0 @@ -#ifdef __linux__ -#include "linux/getroot.c" -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#include "freebsd/getroot.c" -#elif defined(__NetBSD__) || defined(__OpenBSD__) -#include "bsd/getroot.c" -#elif defined(__APPLE__) -#include "apple/getroot.c" -#elif defined(__sun__) -#include "sun/getroot.c" -#elif defined(__GNU__) -#include "hurd/getroot.c" -#elif defined(__CYGWIN__) || defined (__MINGW32__) -#include "windows/getroot.c" -#elif defined(__AROS__) -#include "aros/getroot.c" -#elif defined (__HAIKU__) -#include "haiku/getroot.c" -#else -# warning "No getroot OS-specific functions is available for your system. Device detection may not work properly." -#include "basic/getroot.c" -#endif diff --git a/grub-core/osdep/haiku/getroot.c b/grub-core/osdep/haiku/getroot.c deleted file mode 100644 index 2539a58c2..000000000 --- a/grub-core/osdep/haiku/getroot.c +++ /dev/null @@ -1,105 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -enum grub_dev_abstraction_types -grub_util_get_dev_abstraction_os (const char *os_dev __attribute__((unused))) -{ - return GRUB_DEV_ABSTRACTION_NONE; -} - -int -grub_util_pull_device_os (const char *os_dev __attribute__ ((unused)), - enum grub_dev_abstraction_types ab __attribute__ ((unused))) -{ - return 0; -} - -char * -grub_util_get_grub_dev_os (const char *os_dev __attribute__ ((unused))) -{ - return NULL; -} - -char ** -grub_guess_root_devices (const char *dir_in) -{ - dev_t dv = dev_for_path (dir_in); - fs_info inf; - char **ret; - if (fs_stat_dev (dv, &inf) != B_OK) - return NULL; - ret = xmalloc (2 * sizeof (ret[0])); - ret[0] = xstrdup (inf.device_name); - ret[1] = NULL; - return ret; -} - -grub_disk_addr_t -grub_util_find_partition_start_os (const char *dev) -{ - partition_info part; - grub_disk_addr_t ret; - int fd = open (dev, O_RDONLY); - if (fd < 0) - return 0; - if (ioctl (fd, B_GET_PARTITION_INFO, &part, sizeof (part)) < 0) - { - close (fd); - return 0; - } - ret = part.offset; - close (fd); - fd = open (part.device, O_RDONLY); - - device_geometry geo; - if (ioctl (fd, B_GET_GEOMETRY, &geo, sizeof (geo)) < 0) - return 0; - ret /= geo.bytes_per_sector ? : 512; - close (fd); - return ret; -} - -char * -grub_util_part_to_disk (const char *os_dev, - struct stat *st __attribute__ ((unused)), - int *is_part) -{ - char *ret; - partition_info part; - int fd = open (os_dev, O_RDONLY); - *is_part = 0; - - if (fd < 0) - return xstrdup (os_dev); - if (ioctl (fd, B_GET_PARTITION_INFO, &part, sizeof (part)) < 0) - { - close (fd); - return xstrdup (os_dev); - } - ret = xstrdup (part.device); - close (fd); - *is_part=1; - return ret; -} - -int -grub_util_biosdisk_is_floppy (grub_disk_t disk) -{ - const char *dname; - - dname = grub_util_biosdisk_get_osdev (disk); - - return (strncmp (dname, "/dev/disk/floppy/", sizeof ("/dev/disk/floppy/") - 1) - == 0); -} diff --git a/grub-core/osdep/haiku/hostdisk.c b/grub-core/osdep/haiku/hostdisk.c deleted file mode 100644 index 62d4d5b4c..000000000 --- a/grub-core/osdep/haiku/hostdisk.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -grub_int64_t -grub_util_get_fd_size_os (grub_util_fd_t fd, - const char *name __attribute__ ((unused)), - unsigned *log_secsize) -{ - device_geometry part; - unsigned lg; - if (ioctl (fd, B_GET_GEOMETRY, &part, sizeof (part)) < 0) - return -1; - for (lg = 0; (1 << lg) < part.bytes_per_sector; lg++); - if (log_secsize) - *log_secsize= lg; - return ((grub_uint64_t) part.cylinder_count - * (grub_uint64_t) part.head_count - * (grub_uint64_t) part.sectors_per_track - * (grub_uint64_t) part.bytes_per_sector); -} - -void -grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused))) -{ -} diff --git a/grub-core/osdep/hostdisk.c b/grub-core/osdep/hostdisk.c deleted file mode 100644 index 185397915..000000000 --- a/grub-core/osdep/hostdisk.c +++ /dev/null @@ -1,22 +0,0 @@ -#ifdef __linux__ -#include "linux/hostdisk.c" -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#include "freebsd/hostdisk.c" -#elif defined(__NetBSD__) || defined(__OpenBSD__) -#include "bsd/hostdisk.c" -#elif defined(__APPLE__) -#include "apple/hostdisk.c" -#elif defined(__sun__) -#include "sun/hostdisk.c" -#elif defined(__GNU__) -#include "hurd/hostdisk.c" -#elif defined(__CYGWIN__) || defined(__MINGW32__) -#include "windows/hostdisk.c" -#elif defined(__AROS__) -#include "aros/hostdisk.c" -#elif defined (__HAIKU__) -#include "haiku/hostdisk.c" -#else -# warning "No hostdisk OS-specific functions is available for your system. Device detection may not work properly." -#include "basic/hostdisk.c" -#endif diff --git a/grub-core/osdep/hurd/getroot.c b/grub-core/osdep/hurd/getroot.c deleted file mode 100644 index b849700e6..000000000 --- a/grub-core/osdep/hurd/getroot.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIMITS_H -#include -#endif - -#include - -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -static char * -grub_util_find_hurd_root_device (const char *path) -{ - file_t file; - error_t err; - char *argz = NULL, *name = NULL, *ret; - mach_msg_type_number_t argz_len = 0; - int i; - - file = file_name_lookup (path, 0, 0); - if (file == MACH_PORT_NULL) - /* TRANSLATORS: The first %s is the file being looked at, the second %s is - the error message. */ - grub_util_error (_("cannot open `%s': %s"), path, strerror (errno)); - - /* This returns catenated 0-terminated strings. */ - err = file_get_fs_options (file, &argz, &argz_len); - if (err) - /* TRANSLATORS: On GNU/Hurd, a "translator" is similar to a filesystem - mount, but handled by a userland daemon, whose invocation command line - is being fetched here. First %s is the file being looked at (for which - we are fetching the "translator" command line), second %s is the error - message. - */ - grub_util_error (_("cannot get translator command line " - "for path `%s': %s"), path, strerror(err)); - if (argz_len == 0) - grub_util_error (_("translator command line is empty for path `%s'"), path); - - /* Make sure the string is terminated. */ - argz[argz_len-1] = 0; - - /* Skip first word (translator path) and options. */ - for (i = strlen (argz) + 1; i < argz_len; i += strlen (argz + i) + 1) - { - if (argz[i] != '-') - { - /* Non-option. Only accept one, assumed to be the FS path. */ - /* XXX: this should be replaced by an RPC to the translator. */ - if (name) - /* TRANSLATORS: we expect to get something like - /hurd/foobar --option1 --option2=baz /dev/something - */ - grub_util_error (_("translator `%s' for path `%s' has several " - "non-option words, at least `%s' and `%s'"), - argz, path, name, argz + i); - name = argz + i; - } - } - - if (!name) - /* TRANSLATORS: we expect to get something like - /hurd/foobar --option1 --option2=baz /dev/something - */ - grub_util_error (_("translator `%s' for path `%s' is given only options, " - "cannot find device part"), argz, path); - - int part = -1; - if (strncmp (name, "part:", sizeof ("part:") - 1) == 0) - { - char *next = strchr (name + sizeof ("part:") - 1, ':'); - if (next) - { - part = atoi (name + sizeof ("part:") - 1); - name = next + 1; - } - } - if (strncmp (name, "device:", sizeof ("device:") - 1) == 0) - { - char *dev_name = name + sizeof ("device:") - 1; - - if (dev_name[0] == '@') - { - /* - * Non-bootstrap disk driver, the /dev/ entry is normally set up with - * the same @. - */ - char *next_name = strchr (dev_name, ':'); - - if (next_name) - dev_name = next_name + 1; - } - - if (part >= 0) - ret = xasprintf("/dev/%ss%u", dev_name, part); - else - ret = xasprintf("/dev/%s", dev_name); - } - else if (!strncmp (name, "file:", sizeof ("file:") - 1)) - ret = strdup (name + sizeof ("file:") - 1); - else - ret = strdup (name); - - munmap (argz, argz_len); - return ret; -} - -static int -is_fulldisk (const char *child, const char *parent) -{ - if (strcmp (parent, child) == 0) - return 1; - if (strncmp (parent, "/dev/", sizeof ("/dev/") - 1) == 0 - && child[0] !=0 && strcmp (parent + sizeof ("/dev/") - 1, child) == 0) - return 1; - if (strncmp (child, "/dev/", sizeof ("/dev/") - 1) == 0 - && parent[0] != 0 && strcmp (child + sizeof ("/dev/") - 1, parent) == 0) - return 1; - return 0; -} - -char * -grub_util_part_to_disk (const char *os_dev, - struct stat *st, - int *is_part) -{ - char *path; - grub_disk_addr_t offset; - char *p; - - if (! S_ISBLK (st->st_mode)) - { - *is_part = 0; - return xstrdup (os_dev); - } - - if (!grub_util_hurd_get_disk_info (os_dev, NULL, &offset, NULL, &path)) - return xstrdup (os_dev); - - /* Some versions of Hurd use badly glued Linux code to handle partitions - resulting in partitions being promoted to disks. */ - if (path && !(offset == 0 && is_fulldisk (path, os_dev) - && (strncmp ("/dev/sd", os_dev, 7) == 0 - || strncmp ("/dev/hd", os_dev, 7) == 0))) - { - *is_part = !is_fulldisk (path, os_dev); - if (path[0] != '/') - { - char *n = xasprintf ("/dev/%s", path); - free (path); - path = n; - } - return path; - } - free (path); - - path = xstrdup (os_dev); - - p = strchr (path + 7, 's'); - if (p) - { - *is_part = 1; - *p = '\0'; - } - return path; -} - -enum grub_dev_abstraction_types -grub_util_get_dev_abstraction_os (const char *os_dev __attribute__((unused))) -{ - return GRUB_DEV_ABSTRACTION_NONE; -} - -int -grub_util_pull_device_os (const char *os_dev __attribute__ ((unused)), - enum grub_dev_abstraction_types ab __attribute__ ((unused))) -{ - return 0; -} - -char * -grub_util_get_grub_dev_os (const char *os_dev __attribute__ ((unused))) -{ - return NULL; -} - -grub_disk_addr_t -grub_util_find_partition_start_os (const char *dev) -{ - grub_uint32_t secsize; - grub_disk_addr_t offset; - char *path; - if (!grub_util_hurd_get_disk_info (dev, &secsize, &offset, NULL, &path)) - return 0; - if (path && !(offset == 0 && is_fulldisk (path, dev) - && (strncmp ("/dev/sd", dev, 7) == 0 - || strncmp ("/dev/hd", dev, 7) == 0))) - { - free (path); - return (secsize / 512) * offset; - } - free (path); - return -1; -} - -char ** -grub_guess_root_devices (const char *dir) -{ - char **os_dev = NULL; - - os_dev = xmalloc (2 * sizeof (os_dev[0])); - - /* GNU/Hurd specific function. */ - os_dev[0] = grub_util_find_hurd_root_device (dir); - - if (!os_dev[0]) - { - free (os_dev); - return 0; - } - - os_dev[1] = 0; - - return os_dev; -} diff --git a/grub-core/osdep/hurd/hostdisk.c b/grub-core/osdep/hurd/hostdisk.c deleted file mode 100644 index 17463950b..000000000 --- a/grub-core/osdep/hurd/hostdisk.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -int -grub_util_hurd_get_disk_info (const char *dev, grub_uint32_t *secsize, grub_disk_addr_t *offset, - grub_disk_addr_t *size, char **parent) -{ - 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; - - file = file_name_lookup (dev, 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 information for `%s' does not include type"), dev); - if (ints[0] != STORAGE_DEVICE) - grub_util_error (_("`%s' is not a local disk"), dev); - - if (num_offsets != 2) - grub_util_error (_("Storage information for `%s' indicates neither a plain partition nor a plain disk"), dev); - if (parent) - { - *parent = NULL; - if (num_ints >= 5) - { - size_t len = ints[4]; - if (len > data_len) - len = data_len; - *parent = xmalloc (len+1); - memcpy (*parent, data, len); - (*parent)[len] = '\0'; - - if ((*parent)[0] == '@') - { - /* - * Non-bootstrap disk driver, the /dev/ entry is normally set up with - * the same @. - */ - char *next_path = strchr (*parent, ':'); - - if (next_path) - { - char *n = xstrdup (next_path + 1); - - free (*parent); - *parent = n; - } - } - } - } - if (offset) - *offset = offsets[0]; - if (size) - *size = offsets[1]; - if (secsize) - *secsize = ints[2]; - 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); - - return 1; -} - -grub_int64_t -grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize) -{ - grub_uint32_t sector_size; - grub_disk_addr_t size; - unsigned log_sector_size; - - if (!grub_util_hurd_get_disk_info (name, §or_size, NULL, &size, NULL)) - return -1; - - if (sector_size & (sector_size - 1) || !sector_size) - return -1; - log_sector_size = grub_log2ull (sector_size); - - if (log_secsize) - *log_secsize = log_sector_size; - - return size << log_sector_size; -} - -void -grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused))) -{ -} diff --git a/grub-core/osdep/init.c b/grub-core/osdep/init.c deleted file mode 100644 index 207f67085..000000000 --- a/grub-core/osdep/init.c +++ /dev/null @@ -1,5 +0,0 @@ -#if defined (__MINGW32__) -#include "windows/init.c" -#else -#include "basic/init.c" -#endif diff --git a/grub-core/osdep/linux/blocklist.c b/grub-core/osdep/linux/blocklist.c deleted file mode 100644 index 2efee2c2a..000000000 --- a/grub-core/osdep/linux/blocklist.c +++ /dev/null @@ -1,136 +0,0 @@ -/* grub-setup.c - make GRUB usable */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -void -grub_install_get_blocklist (grub_device_t root_dev, - const char *core_path, - const char *core_img __attribute__ ((unused)), - size_t core_size, - void (*callback) (grub_disk_addr_t sector, - unsigned offset, - unsigned length, - void *data), - void *hook_data) -{ - grub_partition_t container = root_dev->disk->partition; - grub_uint64_t container_start = grub_partition_get_start (container); - struct fiemap fie1; - int fd; - - /* Write the first two sectors of the core image onto the disk. */ - grub_util_info ("opening the core image `%s'", core_path); - fd = open (core_path, O_RDONLY); - if (fd < 0) - grub_util_error (_("cannot open `%s': %s"), core_path, - strerror (errno)); - - grub_memset (&fie1, 0, sizeof (fie1)); - fie1.fm_length = core_size; - fie1.fm_flags = FIEMAP_FLAG_SYNC; - - if (ioctl (fd, FS_IOC_FIEMAP, &fie1) < 0) - { - int nblocks, i; - int bsize; - int mul; - - grub_util_info ("FIEMAP failed. Reverting to FIBMAP"); - - if (ioctl (fd, FIGETBSZ, &bsize) < 0) - grub_util_error (_("can't retrieve blocklists: %s"), - strerror (errno)); - if (bsize & (GRUB_DISK_SECTOR_SIZE - 1)) - grub_util_error ("%s", _("blocksize is not divisible by 512")); - if (!bsize) - grub_util_error ("%s", _("invalid zero blocksize")); - mul = bsize >> GRUB_DISK_SECTOR_BITS; - nblocks = (core_size + bsize - 1) / bsize; - if (mul == 0 || nblocks == 0) - grub_util_error ("%s", _("can't retrieve blocklists")); - for (i = 0; i < nblocks; i++) - { - unsigned blk = i; - int rest; - if (ioctl (fd, FIBMAP, &blk) < 0) - grub_util_error (_("can't retrieve blocklists: %s"), - strerror (errno)); - - rest = core_size - ((i * mul) << GRUB_DISK_SECTOR_BITS); - if (rest <= 0) - break; - if (rest > GRUB_DISK_SECTOR_SIZE * mul) - rest = GRUB_DISK_SECTOR_SIZE * mul; - callback (((grub_uint64_t) blk) * mul - + container_start, - 0, rest, hook_data); - } - } - else - { - struct fiemap *fie2; - int i; - fie2 = xmalloc (sizeof (*fie2) - + fie1.fm_mapped_extents - * sizeof (fie1.fm_extents[1])); - memset (fie2, 0, sizeof (*fie2) - + fie1.fm_mapped_extents * sizeof (fie2->fm_extents[1])); - fie2->fm_length = core_size; - fie2->fm_flags = FIEMAP_FLAG_SYNC; - fie2->fm_extent_count = fie1.fm_mapped_extents; - if (ioctl (fd, FS_IOC_FIEMAP, fie2) < 0) - grub_util_error (_("can't retrieve blocklists: %s"), - strerror (errno)); - for (i = 0; i < fie2->fm_mapped_extents; i++) - { - callback ((fie2->fm_extents[i].fe_physical - >> GRUB_DISK_SECTOR_BITS) - + container_start, - fie2->fm_extents[i].fe_physical - & (GRUB_DISK_SECTOR_SIZE - 1), - fie2->fm_extents[i].fe_length, hook_data); - } - free (fie2); - } - close (fd); -} diff --git a/grub-core/osdep/linux/emunet.c b/grub-core/osdep/linux/emunet.c deleted file mode 100644 index d5a641735..000000000 --- a/grub-core/osdep/linux/emunet.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static int fd; - -grub_ssize_t -grub_emunet_send (const void *packet, grub_size_t sz) -{ - return write (fd, packet, sz); -} - -grub_ssize_t -grub_emunet_receive (void *packet, grub_size_t sz) -{ - return read (fd, packet, sz); -} - -int -grub_emunet_create (grub_size_t *mtu) -{ - struct ifreq ifr; - *mtu = 1500; - fd = open ("/dev/net/tun", O_RDWR | O_NONBLOCK); - if (fd < 0) - return -1; - memset (&ifr, 0, sizeof (ifr)); - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - if (ioctl (fd, TUNSETIFF, &ifr) < 0) - { - close (fd); - fd = -1; - return -1; - } - return 0; -} - -void -grub_emunet_close (void) -{ - if (fd < 0) - return; - - close (fd); - fd = -1; -} diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c deleted file mode 100644 index 7872a8d03..000000000 --- a/grub-core/osdep/linux/getroot.c +++ /dev/null @@ -1,1171 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIMITS_H -#include -#endif - -#include -#include -#include /* ioctl */ -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#define LVM_DEV_MAPPER_STRING "/dev/mapper/" - -/* Defines taken from btrfs/ioctl.h. */ - -struct btrfs_ioctl_dev_info_args -{ - grub_uint64_t devid; - grub_uint8_t uuid[16]; - grub_uint64_t bytes_used; - grub_uint64_t total_bytes; - grub_uint64_t unused[379]; - grub_uint8_t path[1024]; -}; - -struct btrfs_ioctl_fs_info_args -{ - grub_uint64_t max_id; - grub_uint64_t num_devices; - grub_uint8_t fsid[16]; - grub_uint64_t reserved[124]; -}; - -struct btrfs_ioctl_ino_lookup_args -{ - grub_uint64_t treeid; - grub_uint64_t objectid; - char name[4080]; -}; - -struct btrfs_ioctl_search_key -{ - grub_uint64_t tree_id; - grub_uint64_t min_objectid; - grub_uint64_t max_objectid; - grub_uint64_t min_offset; - grub_uint64_t max_offset; - grub_uint64_t min_transid; - grub_uint64_t max_transid; - grub_uint32_t min_type; - grub_uint32_t max_type; - grub_uint32_t nr_items; - grub_uint32_t unused[9]; -}; - -struct btrfs_ioctl_search_args { - struct btrfs_ioctl_search_key key; - grub_uint64_t buf[(4096 - sizeof(struct btrfs_ioctl_search_key)) - / sizeof (grub_uint64_t)]; -}; - -#define BTRFS_IOC_TREE_SEARCH _IOWR(0x94, 17, \ - struct btrfs_ioctl_search_args) -#define BTRFS_IOC_INO_LOOKUP _IOWR(0x94, 18, \ - struct btrfs_ioctl_ino_lookup_args) -#define BTRFS_IOC_DEV_INFO _IOWR(0x94, 30, \ - struct btrfs_ioctl_dev_info_args) -#define BTRFS_IOC_FS_INFO _IOR(0x94, 31, \ - struct btrfs_ioctl_fs_info_args) - -static int -grub_util_is_imsm_or_ddf (const char *os_dev); - - -#define ESCAPED_PATH_MAX (4 * PATH_MAX) -struct mountinfo_entry -{ - int id; - int major, minor; - char enc_root[ESCAPED_PATH_MAX + 1], enc_path[ESCAPED_PATH_MAX + 1]; - char fstype[ESCAPED_PATH_MAX + 1], device[ESCAPED_PATH_MAX + 1]; -}; - -static char ** -grub_util_raid_getmembers (const char *name, int bootable) -{ - int fd, ret, i, j; - int remaining; - char **devicelist; - mdu_version_t version; - mdu_array_info_t info; - mdu_disk_info_t disk; - - fd = open (name, O_RDONLY); - - if (fd == -1) - grub_util_error (_("cannot open `%s': %s"), name, strerror (errno)); - - ret = ioctl (fd, RAID_VERSION, &version); - if (ret != 0) - grub_util_error (_("ioctl RAID_VERSION error: %s"), strerror (errno)); - - if ((version.major != 0 || version.minor != 90) - && (version.major != 1 || version.minor != 0) - && (version.major != 1 || version.minor != 1) - && (version.major != 1 || version.minor != 2)) - grub_util_error (_("unsupported RAID version: %d.%d"), - version.major, version.minor); - - if (bootable && (version.major != 0 || version.minor != 90)) - grub_util_error (_("unsupported RAID version: %d.%d"), - version.major, version.minor); - - ret = ioctl (fd, GET_ARRAY_INFO, &info); - if (ret != 0) - grub_util_error (_("ioctl GET_ARRAY_INFO error: %s"), strerror (errno)); - - devicelist = xcalloc (info.nr_disks + 1, sizeof (char *)); - - remaining = info.nr_disks; - for (i = 0, j = 0; i < GRUB_MDRAID_MAX_DISKS && remaining > 0; i++) - { - disk.number = i; - ret = ioctl (fd, GET_DISK_INFO, &disk); - if (ret != 0) - grub_util_error (_("ioctl GET_DISK_INFO error: %s"), strerror (errno)); - - /* Skip: MD_DISK_REMOVED slots don't contribute to "remaining" count. */ - if (disk.state & (1 << MD_DISK_REMOVED)) - continue; - remaining--; - - /* Only record disks that are actively participating in the array. */ - if (disk.state & (1 << MD_DISK_ACTIVE)) - devicelist[j++] = grub_find_device (NULL, makedev (disk.major, disk.minor)); - } - - devicelist[j] = NULL; - - close (fd); - - return devicelist; -} - -/* Statting something on a btrfs filesystem always returns a virtual device - major/minor pair rather than the real underlying device, because btrfs - can span multiple underlying devices (and even if it's currently only - using a single device it can be dynamically extended onto another). We - can't deal with the multiple-device case yet, but in the meantime, we can - at least cope with the single-device case by scanning - /proc/self/mountinfo. */ -static void -unescape (char *str) -{ - char *optr; - const char *iptr; - for (iptr = optr = str; *iptr; optr++) - { - if (iptr[0] == '\\' && iptr[1] >= '0' && iptr[1] < '8' - && iptr[2] >= '0' && iptr[2] < '8' - && iptr[3] >= '0' && iptr[3] < '8') - { - *optr = (((iptr[1] - '0') << 6) | ((iptr[2] - '0') << 3) - | (iptr[3] - '0')); - iptr += 4; - } - else - *optr = *iptr++; - } - *optr = 0; -} - -static char ** -grub_find_root_devices_from_btrfs (const char *dir) -{ - int fd; - struct btrfs_ioctl_fs_info_args fsi; - int i, j = 0; - char **ret; - - fd = open (dir, 0); - if (fd < 0) - return NULL; - - if (ioctl (fd, BTRFS_IOC_FS_INFO, &fsi) < 0) - { - close (fd); - return NULL; - } - - ret = xcalloc (fsi.num_devices + 1, sizeof (ret[0])); - - for (i = 1; i <= fsi.max_id && j < fsi.num_devices; i++) - { - struct btrfs_ioctl_dev_info_args devi; - memset (&devi, 0, sizeof (devi)); - devi.devid = i; - if (ioctl (fd, BTRFS_IOC_DEV_INFO, &devi) < 0) - { - close (fd); - free (ret); - return NULL; - } - ret[j++] = xstrdup ((char *) devi.path); - if (j >= fsi.num_devices) - break; - } - close (fd); - ret[j] = 0; - return ret; -} - -static char * -get_btrfs_fs_prefix (const char *mount_path) -{ - struct btrfs_ioctl_ino_lookup_args args; - struct stat st; - int fd; - grub_uint64_t tree_id, inode_id; - char *ret = NULL; - - fd = open (mount_path, O_RDONLY); - - if (fd < 0) - return NULL; - memset (&args, 0, sizeof(args)); - args.objectid = GRUB_BTRFS_TREE_ROOT_OBJECTID; - - if (ioctl (fd, BTRFS_IOC_INO_LOOKUP, &args) < 0) - goto fail; - tree_id = args.treeid; - - if (fstat (fd, &st) < 0) - goto fail; - inode_id = st.st_ino; - - while (tree_id != GRUB_BTRFS_ROOT_VOL_OBJECTID - || inode_id != GRUB_BTRFS_TREE_ROOT_OBJECTID) - { - const char *name; - size_t namelen; - struct btrfs_ioctl_search_args sargs; - char *old; - - memset (&sargs, 0, sizeof(sargs)); - - if (inode_id == GRUB_BTRFS_TREE_ROOT_OBJECTID) - { - struct grub_btrfs_root_backref *br; - - sargs.key.tree_id = 1; - sargs.key.min_objectid = tree_id; - sargs.key.max_objectid = tree_id; - - sargs.key.min_offset = 0; - sargs.key.max_offset = ~0ULL; - sargs.key.min_transid = 0; - sargs.key.max_transid = ~0ULL; - sargs.key.min_type = GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF; - sargs.key.max_type = GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF; - - sargs.key.nr_items = 1; - - if (ioctl (fd, BTRFS_IOC_TREE_SEARCH, &sargs) < 0) - goto fail; - - if (sargs.key.nr_items == 0) - goto fail; - - tree_id = sargs.buf[2]; - br = (struct grub_btrfs_root_backref *) (sargs.buf + 4); - inode_id = grub_le_to_cpu64 (br->inode_id); - name = br->name; - namelen = grub_le_to_cpu16 (br->n); - } - else - { - struct grub_btrfs_inode_ref *ir; - - sargs.key.tree_id = tree_id; - sargs.key.min_objectid = inode_id; - sargs.key.max_objectid = inode_id; - - sargs.key.min_offset = 0; - sargs.key.max_offset = ~0ULL; - sargs.key.min_transid = 0; - sargs.key.max_transid = ~0ULL; - sargs.key.min_type = GRUB_BTRFS_ITEM_TYPE_INODE_REF; - sargs.key.max_type = GRUB_BTRFS_ITEM_TYPE_INODE_REF; - - if (ioctl (fd, BTRFS_IOC_TREE_SEARCH, &sargs) < 0) - goto fail; - - if (sargs.key.nr_items == 0) - goto fail; - - inode_id = sargs.buf[2]; - - ir = (struct grub_btrfs_inode_ref *) (sargs.buf + 4); - name = ir->name; - namelen = grub_le_to_cpu16 (ir->n); - } - old = ret; - ret = xmalloc (namelen + (old ? strlen (old) : 0) + 2); - ret[0] = '/'; - memcpy (ret + 1, name, namelen); - if (old) - { - strcpy (ret + 1 + namelen, old); - free (old); - } - else - ret[1+namelen] = '\0'; - } - if (!ret) - ret = xstrdup ("/"); - close (fd); - return ret; - - fail: - free (ret); - close (fd); - return NULL; -} - - -char ** -grub_find_root_devices_from_mountinfo (const char *dir, char **relroot) -{ - FILE *fp = NULL; - char *buf = NULL; - size_t len = 0; - grub_size_t entry_len, entry_max = 4; - struct mountinfo_entry *entries; - struct mountinfo_entry parent_entry = { 0, 0, 0, "", "", "", "" }; - int i; - int retry = 0; - int dir_fd = -1; - char **ret = NULL; - - if (! *dir) - dir = "/"; - if (relroot) - *relroot = NULL; - - entries = xcalloc (entry_max, sizeof (*entries)); - -again: - fp = grub_util_fopen ("/proc/self/mountinfo", "r"); - if (! fp) - goto out; /* fall through to other methods */ - - entry_len = 0; - - /* First, build a list of relevant visible mounts. */ - while (getline (&buf, &len, fp) > 0) - { - struct mountinfo_entry entry; - int count; - size_t enc_path_len; - const char *sep; - - if (sscanf (buf, "%d %d %u:%u %s %s%n", - &entry.id, &parent_entry.id, &entry.major, &entry.minor, - entry.enc_root, entry.enc_path, &count) < 6) - continue; - - unescape (entry.enc_root); - unescape (entry.enc_path); - - enc_path_len = strlen (entry.enc_path); - /* Check that enc_path is a prefix of dir. The prefix must either be - the entire string, or end with a slash, or be immediately followed - by a slash. */ - if (strncmp (dir, entry.enc_path, enc_path_len) != 0 || - (enc_path_len && dir[enc_path_len - 1] != '/' && - dir[enc_path_len] && dir[enc_path_len] != '/')) - continue; - - sep = strstr (buf + count, " - "); - if (!sep) - continue; - - sep += sizeof (" - ") - 1; - if (sscanf (sep, "%s %s", entry.fstype, entry.device) != 2) - continue; - - unescape (entry.device); - - /* Using the mount IDs, find out where this fits in the list of - visible mount entries we've seen so far. There are three - interesting cases. Firstly, it may be inserted at the end: this is - the usual case of /foo/bar being mounted after /foo. Secondly, it - may be inserted at the start: for example, this can happen for - filesystems that are mounted before / and later moved under it. - Thirdly, it may occlude part or all of the existing filesystem - tree, in which case the end of the list needs to be pruned and this - new entry will be inserted at the end. */ - if (entry_len >= entry_max) - { - entry_max <<= 1; - entries = xrealloc (entries, entry_max * sizeof (*entries)); - } - - if (!entry_len) - { - /* Initialise list. */ - entry_len = 2; - entries[0] = parent_entry; - entries[1] = entry; - } - else - { - for (i = entry_len - 1; i >= 0; i--) - { - if (entries[i].id == parent_entry.id) - { - /* Insert at end, pruning anything previously above this. */ - entry_len = i + 2; - entries[i + 1] = entry; - break; - } - else if (i == 0 && entries[i].id == entry.id) - { - /* Insert at start. */ - entry_len++; - memmove (entries + 1, entries, - (entry_len - 1) * sizeof (*entries)); - entries[0] = parent_entry; - entries[1] = entry; - break; - } - } - } - } - - if (!entry_len) - goto out; - - /* Now scan visible mounts for the ones we're interested in. */ - for (i = entry_len - 1; i >= 0; i--) - { - char *fs_prefix = NULL; - if (!*entries[i].device) - continue; - - if (grub_strcmp (entries[i].fstype, "fuse.zfs") == 0 - || grub_strcmp (entries[i].fstype, "zfs") == 0) - { - char *slash; - slash = strchr (entries[i].device, '/'); - if (slash) - *slash = 0; - ret = grub_util_find_root_devices_from_poolname (entries[i].device); - if (slash) - *slash = '/'; - if (relroot) - { - if (!slash) - fs_prefix = xasprintf ("/@%s", entries[i].enc_root); - else if (strchr (slash + 1, '@')) - fs_prefix = xasprintf ("/%s%s", slash + 1, entries[i].enc_root); - else - fs_prefix = xasprintf ("/%s@%s", slash + 1, - entries[i].enc_root); - } - } - else if (grub_strcmp (entries[i].fstype, "btrfs") == 0) - { - ret = grub_find_root_devices_from_btrfs (dir); - fs_prefix = get_btrfs_fs_prefix (entries[i].enc_path); - } - else if (!retry && grub_strcmp (entries[i].fstype, "autofs") == 0) - { - /* If the best match is automounted, try to trigger mount. We cannot - simply return here because stat() on automounted directory does not - trigger mount and returns bogus (pseudo)device number instead. - We keep mountpoint open until end of scan to prevent timeout. */ - - int flags = O_RDONLY|O_DIRECTORY; - - fclose (fp); -#ifdef O_LARGEFILE - flags |= O_LARGEFILE; -#endif - dir_fd = open (entries[i].enc_path, flags); - retry = 1; - goto again; - } - if (!ret) - { - ret = xmalloc (2 * sizeof (ret[0])); - ret[0] = strdup (entries[i].device); - ret[1] = 0; - } - if (!fs_prefix) - fs_prefix = entries[i].enc_root; - if (relroot) - { - char *ptr; - grub_size_t enc_root_len = strlen (fs_prefix); - grub_size_t enc_path_len = strlen (entries[i].enc_path); - grub_size_t dir_strlen = strlen (dir); - *relroot = xmalloc (enc_root_len + - 2 + dir_strlen); - ptr = grub_stpcpy (*relroot, fs_prefix); - if (dir_strlen > enc_path_len) - { - while (ptr > *relroot && *(ptr - 1) == '/') - ptr--; - if (dir[enc_path_len] != '/') - *ptr++ = '/'; - ptr = grub_stpcpy (ptr, dir + enc_path_len); - } - *ptr = 0; - } - if (fs_prefix != entries[i].enc_root) - free (fs_prefix); - break; - } - -out: - free (buf); - free (entries); - if (fp) - fclose (fp); - if (dir_fd != -1) - close (dir_fd); - return ret; -} - -static char * -get_mdadm_uuid (const char *os_dev) -{ - const char *argv[5]; - int fd; - pid_t pid; - FILE *mdadm; - char *buf = NULL; - size_t len = 0; - char *name = NULL; - - argv[0] = "mdadm"; - argv[1] = "--detail"; - argv[2] = "--export"; - argv[3] = os_dev; - argv[4] = NULL; - - pid = grub_util_exec_pipe (argv, &fd); - - if (!pid) - return NULL; - - /* Parent. Read mdadm's output. */ - mdadm = fdopen (fd, "r"); - if (! mdadm) - { - grub_util_warn (_("Unable to open stream from %s: %s"), - "mdadm", strerror (errno)); - goto out; - } - - while (getline (&buf, &len, mdadm) > 0) - { - if (strncmp (buf, "MD_UUID=", sizeof ("MD_UUID=") - 1) == 0) - { - char *name_start, *ptri, *ptro; - - free (name); - name_start = buf + sizeof ("MD_UUID=") - 1; - ptro = name = xmalloc (strlen (name_start) + 1); - for (ptri = name_start; *ptri && *ptri != '\n' && *ptri != '\r'; - ptri++) - if ((*ptri >= '0' && *ptri <= '9') - || (*ptri >= 'a' && *ptri <= 'f') - || (*ptri >= 'A' && *ptri <= 'F')) - *ptro++ = *ptri; - *ptro = 0; - } - } - -out: - close (fd); - waitpid (pid, NULL, 0); - free (buf); - - return name; -} - -static int -grub_util_is_imsm_or_ddf (const char *os_dev) -{ - int retry; - int is_imsm_or_ddf = 0; - int container_seen = 0; - const char *dev = os_dev; - - do - { - const char *argv[5]; - int fd; - pid_t pid; - FILE *mdadm; - char *buf = NULL; - size_t len = 0; - - retry = 0; /* We'll do one more pass if device is part of container */ - - argv[0] = "mdadm"; - argv[1] = "--detail"; - argv[2] = "--export"; - argv[3] = dev; - argv[4] = NULL; - - pid = grub_util_exec_pipe (argv, &fd); - - if (!pid) - { - if (dev != os_dev) - free ((void *) dev); - return 0; - } - - /* Parent. Read mdadm's output. */ - mdadm = fdopen (fd, "r"); - if (! mdadm) - { - grub_util_warn (_("Unable to open stream from %s: %s"), - "mdadm", strerror (errno)); - close (fd); - waitpid (pid, NULL, 0); - if (dev != os_dev) - free ((void *) dev); - return 0; - } - - while (getline (&buf, &len, mdadm) > 0) - { - if (strncmp (buf, "MD_CONTAINER=", sizeof ("MD_CONTAINER=") - 1) == 0 - && !container_seen) - { - char *newdev, *ptr; - newdev = xstrdup (buf + sizeof ("MD_CONTAINER=") - 1); - ptr = newdev + strlen (newdev) - 1; - for (; ptr >= newdev && (*ptr == '\n' || *ptr == '\r'); ptr--); - ptr[1] = 0; - grub_util_info ("Container of %s is %s", dev, newdev); - dev = newdev; - container_seen = retry = 1; - break; - } - if (strncmp (buf, "MD_METADATA=imsm", - sizeof ("MD_METADATA=imsm") - 1) == 0) - { - is_imsm_or_ddf = 1; - grub_util_info ("%s is imsm", dev); - break; - } - if (strncmp (buf, "MD_METADATA=ddf", - sizeof ("MD_METADATA=ddf") - 1) == 0) - { - is_imsm_or_ddf = 1; - grub_util_info ("%s is ddf", dev); - break; - } - } - - free (buf); - close (fd); - waitpid (pid, NULL, 0); - } - while (retry); - - if (dev != os_dev) - free ((void *) dev); - return is_imsm_or_ddf; -} - -char * -grub_util_part_to_disk (const char *os_dev, struct stat *st, - int *is_part) -{ - char *path; - - if (! S_ISBLK (st->st_mode)) - { - *is_part = 0; - return xstrdup (os_dev); - } - - 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) - { - *is_part = 1; - strcpy (p, "disc"); - } - - return path; - } - - /* If this is a SCSI disk. */ - if (strncmp ("scsi/", p, 5) == 0) - { - p = strstr (p, "part"); - if (p) - { - *is_part = 1; - 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) - { - *is_part = 1; - *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) - { - *is_part = 1; - *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) - { - *is_part = 1; - *p = '\0'; - } - - return path; - } - - /* If this is an AOE disk. */ - if (strncmp ("etherd/e", p, sizeof ("etherd/e") - 1) == 0) - { - /* /dev/etherd/e[0-9]+\.[0-9]+(p[0-9]+)? */ - p = strchr (p, 'p'); - if (p) - { - *is_part = 1; - *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) - { - *is_part = 1; - *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]+)? */ - if (p[sizeof ("i2o/hda") - 1]) - *is_part = 1; - 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) - { - *is_part = 1; - *p = '\0'; - } - - return path; - } - - if (strncmp ("md", p, 2) == 0 - && p[2] >= '0' && p[2] <= '9') - { - char *ptr = p + 2; - while (*ptr >= '0' && *ptr <= '9') - ptr++; - if (*ptr) - *is_part = 1; - *ptr = 0; - return path; - } - - if (strncmp ("nbd", p, 3) == 0 - && p[3] >= '0' && p[3] <= '9') - { - char *ptr = p + 3; - while (*ptr >= '0' && *ptr <= '9') - ptr++; - if (*ptr) - *is_part = 1; - *ptr = 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]* */ - if (p[6]) - *is_part = 1; - 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') - { - char *pp = p + 2; - while (*pp >= 'a' && *pp <= 'z') - pp++; - if (*pp) - *is_part = 1; - /* /dev/[hsv]d[a-z]+[0-9]* */ - *pp = '\0'; - return path; - } - - /* If this is a Xen virtual block device. */ - if ((strncmp ("xvd", p, 3) == 0) && p[3] >= 'a' && p[3] <= 'z') - { - char *pp = p + 3; - while (*pp >= 'a' && *pp <= 'z') - pp++; - if (*pp) - *is_part = 1; - /* /dev/xvd[a-z]+[0-9]* */ - *pp = '\0'; - return path; - } - - /* If this is an rssd device. */ - if ((strncmp ("rssd", p, 4) == 0) && p[4] >= 'a' && p[4] <= 'z') - { - char *pp = p + 4; - while (*pp >= 'a' && *pp <= 'z') - pp++; - if (*pp) - *is_part = 1; - /* /dev/rssd[a-z]+[0-9]* */ - *pp = '\0'; - return path; - } - - /* If this is a loop device */ - if ((strncmp ("loop", p, 4) == 0) && p[4] >= '0' && p[4] <= '9') - { - char *pp = p + 4; - while (*pp >= '0' && *pp <= '9') - pp++; - if (*pp == 'p') - *is_part = 1; - /* /dev/loop[0-9]+p[0-9]* */ - *pp = '\0'; - return path; - } - - /* If this is a NVMe device */ - if ((strncmp ("nvme", p, 4) == 0) && p[4] >= '0' && p[4] <= '9') - { - char *pp = p + 4; - while (*pp >= '0' && *pp <= '9') - pp++; - if (*pp == 'n') - pp++; - while (*pp >= '0' && *pp <= '9') - pp++; - if (*pp == 'p') - *is_part = 1; - /* /dev/nvme[0-9]+n[0-9]+p[0-9]* */ - *pp = '\0'; - return path; - } - } - - return path; -} - -static char * -grub_util_get_raid_grub_dev (const char *os_dev) -{ - char *grub_dev = NULL; - 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 if (os_dev[7] == '/') - { - /* mdraid 1.x with a free name. */ - 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); - - { - char *mdadm_name = get_mdadm_uuid (os_dev); - - if (mdadm_name) - { - const char *q; - - for (q = os_dev + strlen (os_dev) - 1; q >= os_dev - && grub_isdigit (*q); q--); - - if (q >= os_dev && *q == 'p') - { - free (grub_dev); - grub_dev = xasprintf ("mduuid/%s,%s", mdadm_name, q + 1); - goto done; - } - free (grub_dev); - grub_dev = xasprintf ("mduuid/%s", mdadm_name); - - done: - free (mdadm_name); - } - } - return grub_dev; -} - -enum grub_dev_abstraction_types -grub_util_get_dev_abstraction_os (const char *os_dev) -{ -#ifndef HAVE_DEVICE_MAPPER - if ((strncmp ("/dev/mapper/", os_dev, 12) == 0)) - return GRUB_DEV_ABSTRACTION_LVM; -#endif - - /* Check for RAID. */ - if (!strncmp (os_dev, "/dev/md", 7) && ! grub_util_device_is_mapped (os_dev) - && !grub_util_is_imsm_or_ddf (os_dev)) - return GRUB_DEV_ABSTRACTION_RAID; - return GRUB_DEV_ABSTRACTION_NONE; -} - -int -grub_util_pull_device_os (const char *os_dev, - enum grub_dev_abstraction_types ab) -{ - switch (ab) - { - case GRUB_DEV_ABSTRACTION_RAID: - { - char **devicelist = grub_util_raid_getmembers (os_dev, 0); - int i; - for (i = 0; devicelist[i];i++) - { - grub_util_pull_device (devicelist[i]); - free (devicelist[i]); - } - free (devicelist); - } - return 1; - default: - return 0; - } -} - -char * -grub_util_get_grub_dev_os (const char *os_dev) -{ - char *grub_dev = NULL; - - switch (grub_util_get_dev_abstraction (os_dev)) - { - /* Fallback for non-devmapper build. In devmapper-builds LVM is handled - in grub_util_get_devmapper_grub_dev and this point isn't reached. - */ - case GRUB_DEV_ABSTRACTION_LVM: - { - unsigned short len; - grub_size_t offset = sizeof (LVM_DEV_MAPPER_STRING) - 1; - - len = strlen (os_dev) - offset + 1; - grub_dev = xmalloc (len + sizeof ("lvm/")); - - grub_memcpy (grub_dev, "lvm/", sizeof ("lvm/") - 1); - grub_memcpy (grub_dev + sizeof ("lvm/") - 1, os_dev + offset, len); - } - break; - - case GRUB_DEV_ABSTRACTION_RAID: - grub_dev = grub_util_get_raid_grub_dev (os_dev); - break; - - default: /* GRUB_DEV_ABSTRACTION_NONE */ - break; - } - - return grub_dev; -} - -char * -grub_make_system_path_relative_to_its_root_os (const char *path) -{ - char *bind = NULL; - grub_size_t len; - grub_free (grub_find_root_devices_from_mountinfo (path, &bind)); - if (bind && bind[0]) - { - len = strlen (bind); - while (len > 0 && bind[len - 1] == '/') - { - bind[len - 1] = '\0'; - len--; - } - return bind; - } - grub_free (bind); - return NULL; -} diff --git a/grub-core/osdep/linux/hostdisk.c b/grub-core/osdep/linux/hostdisk.c deleted file mode 100644 index 7e24ae62c..000000000 --- a/grub-core/osdep/linux/hostdisk.c +++ /dev/null @@ -1,424 +0,0 @@ -/* hostdisk.c - emulate biosdisk */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -# include /* ioctl */ -# include -# ifndef BLKFLSBUF -# define BLKFLSBUF _IO (0x12,97) /* flush buffer cache */ -# endif /* ! BLKFLSBUF */ -# include /* 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 */ - - -grub_int64_t -grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize) -{ - unsigned long long nr; - unsigned sector_size, log_sector_size; - - if (ioctl (fd, BLKGETSIZE64, &nr)) - return -1; - - if (ioctl (fd, BLKSSZGET, §or_size)) - return -1; - - if (sector_size & (sector_size - 1) || !sector_size) - return -1; - log_sector_size = grub_log2ull (sector_size); - - if (log_secsize) - *log_secsize = log_sector_size; - - if (nr & ((1 << log_sector_size) - 1)) - grub_util_error ("%s", _("unaligned device size")); - - return nr; -} - -static char * -sysfs_partition_path (const char *dev, const char *entry) -{ - struct stat st; - - if (stat (dev, &st) == 0 && S_ISBLK (st.st_mode)) - return xasprintf ("/sys/dev/block/%u:%u/%s", - major (st.st_rdev), minor (st.st_rdev), entry); - - return NULL; -} - -static int -sysfs_partition_start (const char *dev, grub_disk_addr_t *start) -{ - char *path; - FILE *fp; - unsigned long long val; - int ret = 0; - - path = sysfs_partition_path (dev, "start"); - if (!path) - return 0; - - fp = grub_util_fopen (path, "r"); - if (!fp) - goto out; - - if (fscanf (fp, "%llu", &val) == 1) - { - *start = (grub_disk_addr_t) val; - ret = 1; - } - -out: - free (path); - if (fp) - fclose (fp); - - return ret; -} - -grub_disk_addr_t -grub_util_find_partition_start_os (const char *dev) -{ - grub_disk_addr_t start = 0; - grub_util_fd_t fd; - struct hd_geometry hdg; - - if (sysfs_partition_start (dev, &start)) - return start; - - fd = open (dev, O_RDONLY); - if (fd == -1) - { - grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot open `%s': %s"), - dev, strerror (errno)); - return 0; - } - - if (ioctl (fd, HDIO_GETGEO, &hdg)) - { - grub_error (GRUB_ERR_BAD_DEVICE, - "cannot get disk geometry of `%s'", dev); - close (fd); - return 0; - } - - close (fd); - - return hdg.start; -} - -/* Cache of partition start sectors for each disk. */ -struct linux_partition_cache -{ - struct linux_partition_cache *next; - struct linux_partition_cache **prev; - char *dev; - unsigned long start; - int partno; -}; - -struct linux_partition_cache *linux_partition_cache_list; - -/* 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; -} - -#pragma GCC diagnostic ignored "-Wformat-nonliteral" - -static int -grub_hostdisk_linux_find_partition (const grub_disk_t disk, char *dev, - grub_disk_addr_t sector) -{ - size_t len = strlen (dev); - const char *format; - char *p; - int i; - char real_dev[PATH_MAX]; - struct linux_partition_cache *cache; - int missing = 0; - - strcpy(real_dev, dev); - - if (have_devfs () && strcmp (real_dev + len - 5, "/disc") == 0) - { - p = real_dev + len - 4; - format = "part%d"; - } - else if (strncmp (real_dev, "/dev/disk/by-id/", - sizeof ("/dev/disk/by-id/") - 1) == 0) - { - p = real_dev + len; - 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++) - { - grub_util_fd_t fd; - grub_disk_addr_t start; - struct stat st; - - sprintf (p, format, i); - - fd = open (real_dev, O_RDONLY); - if (fd == -1) - { - if (missing++ < 10) - continue; - else - return 0; - } - missing = 0; - - if (fstat (fd, &st) < 0 - || !grub_util_device_is_mapped_stat (&st) - || !grub_util_get_dm_node_linear_info (st.st_rdev, 0, 0, &start)) - start = grub_disk_to_native_sector (disk, grub_util_find_partition_start_os (real_dev)); - /* We don't care about errors here. */ - grub_errno = GRUB_ERR_NONE; - - close (fd); - - if (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 = 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; -} - -#pragma GCC diagnostic error "-Wformat-nonliteral" - -void -grub_hostdisk_flush_initial_buffer (const char *os_dev) -{ - grub_util_fd_t fd; - struct stat st; - - fd = open (os_dev, O_RDONLY); - if (fd >= 0 && fstat (fd, &st) >= 0 && S_ISBLK (st.st_mode)) - ioctl (fd, BLKFLSBUF, 0); - if (fd >= 0) - close (fd); -} - -int -grub_util_fd_open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags, - grub_disk_addr_t *max) -{ - grub_util_fd_t fd; - struct grub_util_hostdisk_data *data = disk->data; - - *max = ~0ULL; - -#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 O_CLOEXEC - flags |= O_CLOEXEC; -#endif - - /* 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) - >> (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); - - strncpy (dev, grub_util_biosdisk_get_osdev (disk), sizeof (dev) - 1); - dev[sizeof(dev) - 1] = '\0'; - if (disk->partition - && strncmp (dev, "/dev/", 5) == 0) - { - if (sector >= part_start) - is_partition = grub_hostdisk_linux_find_partition (disk, dev, part_start); - else - *max = part_start - sector; - } - - reopen: - - 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); - data->dev = 0; - if (data->fd != -1) - { - if (data->access_mode == O_RDWR || data->access_mode == O_WRONLY) - { - fsync (data->fd); - if (data->is_disk) - ioctl (data->fd, BLKFLSBUF, 0); - } - - close (data->fd); - data->fd = -1; - } - - /* 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, N_("cannot open `%s': %s"), - dev, strerror (errno)); - return -1; - } - - data->dev = xstrdup (dev); - data->access_mode = (flags & O_ACCMODE); - data->fd = fd; - - if (data->is_disk) - ioctl (data->fd, BLKFLSBUF, 0); - } - - if (is_partition) - { - *max = grub_util_get_fd_size (fd, dev, 0); - *max >>= disk->log_sector_size; - if (sector - part_start >= *max) - { - *max = disk->partition->len - (sector - part_start); - if (*max == 0) - *max = ~0ULL; - is_partition = 0; - strncpy (dev, grub_util_biosdisk_get_osdev (disk), sizeof (dev) - 1); - dev[sizeof(dev) - 1] = '\0'; - goto reopen; - } - sector -= part_start; - *max -= sector; - } - } - - if (grub_util_fd_seek (fd, sector << disk->log_sector_size)) - { - close (fd); - grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"), - grub_util_biosdisk_get_osdev (disk), strerror (errno)); - return -1; - } - - return fd; -} diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c deleted file mode 100644 index a6153d359..000000000 --- a/grub-core/osdep/linux/ofpath.c +++ /dev/null @@ -1,769 +0,0 @@ -/* ofpath.c - calculate OpenFirmware path names given an OS device */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009, 2011,2012, 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#undef OFPATH_STANDALONE - -#ifndef OFPATH_STANDALONE -#include -#include -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __sparc__ -typedef enum - { - GRUB_OFPATH_SPARC_WWN_ADDR = 1, - GRUB_OFPATH_SPARC_TGT_LUN, - } ofpath_sparc_addressing; - -struct ofpath_sparc_hba -{ - grub_uint32_t device_id; - ofpath_sparc_addressing addressing; -}; - -static struct ofpath_sparc_hba sparc_lsi_hba[] = { - /* Rhea, Jasper 320, LSI53C1020/1030. */ - {0x30, GRUB_OFPATH_SPARC_TGT_LUN}, - /* SAS-1068E. */ - {0x50, GRUB_OFPATH_SPARC_TGT_LUN}, - /* SAS-1064E. */ - {0x56, GRUB_OFPATH_SPARC_TGT_LUN}, - /* Pandora SAS-1068E. */ - {0x58, GRUB_OFPATH_SPARC_TGT_LUN}, - /* Aspen, Invader, LSI SAS-3108. */ - {0x5d, GRUB_OFPATH_SPARC_TGT_LUN}, - /* Niwot, SAS 2108. */ - {0x79, GRUB_OFPATH_SPARC_TGT_LUN}, - /* Erie, Falcon, LSI SAS 2008. */ - {0x72, GRUB_OFPATH_SPARC_WWN_ADDR}, - /* LSI WarpDrive 6203. */ - {0x7e, GRUB_OFPATH_SPARC_WWN_ADDR}, - /* LSI SAS 2308. */ - {0x87, GRUB_OFPATH_SPARC_WWN_ADDR}, - /* LSI SAS 3008. */ - {0x97, GRUB_OFPATH_SPARC_WWN_ADDR}, - {0, 0} -}; - -static const int LSI_VENDOR_ID = 0x1000; -#endif - -#ifdef OFPATH_STANDALONE -#define xmalloc malloc -void -grub_util_error (const char *fmt, ...) -{ - va_list ap; - - fprintf (stderr, "ofpath: error: "); - va_start (ap, fmt); - vfprintf (stderr, fmt, ap); - va_end (ap); - fputc ('\n', stderr); - exit (1); -} - -void -grub_util_info (const char *fmt, ...) -{ - va_list ap; - - fprintf (stderr, "ofpath: info: "); - va_start (ap, fmt); - vfprintf (stderr, fmt, ap); - va_end (ap); - fputc ('\n', stderr); -} - -#define grub_util_warn grub_util_info -#define _(x) x -#define xstrdup strdup -#endif - -static void -kill_trailing_dir(char *path) -{ - char *end = path + strlen(path) - 1; - - while (end >= path) - { - if (*end != '/') - { - end--; - continue; - } - *end = '\0'; - break; - } -} - -static void -trim_newline (char *path) -{ - char *end = path + strlen(path) - 1; - - while (*end == '\n') - *end-- = '\0'; -} - -#define MAX_DISK_CAT 64 - -static char * -find_obppath (const char *sysfs_path_orig) -{ - char *sysfs_path, *path; - size_t path_size = strlen (sysfs_path_orig) + sizeof ("/obppath"); - - sysfs_path = xstrdup (sysfs_path_orig); - path = xmalloc (path_size); - - while (1) - { - int fd; - char *of_path; - struct stat st; - size_t size; - - snprintf(path, path_size, "%s/obppath", sysfs_path); -#if 0 - printf("Trying %s\n", path); -#endif - - fd = open(path, O_RDONLY); - -#ifndef __sparc__ - if (fd < 0 || fstat (fd, &st) < 0) - { - if (fd >= 0) - close (fd); - snprintf(path, path_size, "%s/devspec", sysfs_path); - fd = open(path, O_RDONLY); - } -#endif - - if (fd < 0 || fstat (fd, &st) < 0) - { - if (fd >= 0) - close (fd); - kill_trailing_dir(sysfs_path); - if (!strcmp(sysfs_path, "/sys")) - { - grub_util_info (_("`obppath' not found in parent dirs of `%s'," - " no IEEE1275 name discovery"), - sysfs_path_orig); - free (path); - free (sysfs_path); - return NULL; - } - continue; - } - size = st.st_size; - of_path = xmalloc (size + MAX_DISK_CAT + 1); - memset(of_path, 0, size + MAX_DISK_CAT + 1); - if (read(fd, of_path, size) < 0) - { - grub_util_info (_("cannot read `%s': %s"), path, strerror (errno)); - close(fd); - free (path); - free (of_path); - free (sysfs_path); - return NULL; - } - close(fd); - - trim_newline(of_path); - free (path); - free (sysfs_path); - return of_path; - } -} - -static char * -xrealpath (const char *in) -{ - char *out; -#ifdef PATH_MAX - out = xmalloc (PATH_MAX); - out = realpath (in, out); -#else - out = realpath (in, NULL); -#endif - if (!out) - grub_util_error (_("failed to get canonical path of `%s'"), in); - return out; -} - -static char * -block_device_get_sysfs_path_and_link(const char *devicenode) -{ - char *rpath; - char *rpath2; - char *ret; - size_t tmp_size = strlen (devicenode) + sizeof ("/sys/block/"); - char *tmp = xmalloc (tmp_size); - - memcpy (tmp, "/sys/block/", sizeof ("/sys/block/")); - strcat (tmp, devicenode); - - rpath = xrealpath (tmp); - rpath2 = xmalloc (strlen (rpath) + sizeof ("/device")); - strcpy (rpath2, rpath); - strcat (rpath2, "/device"); - - ret = xrealpath (rpath2); - - free (tmp); - free (rpath); - free (rpath2); - return ret; -} - -static inline int -my_isdigit (int c) -{ - return (c >= '0' && c <= '9'); -} - -static const char * -trailing_digits (const char *p) -{ - const char *end; - - end = p + strlen(p) - 1; - while (end >= p) - { - if (! my_isdigit(*end)) - break; - end--; - } - - return end + 1; -} - -static char * -__of_path_common(char *sysfs_path, - const char *device, int devno) -{ - const char *digit_string; - char disk[MAX_DISK_CAT]; - char *of_path = find_obppath(sysfs_path); - - if (!of_path) - return NULL; - - digit_string = trailing_digits (device); - if (*digit_string == '\0') - { - snprintf(disk, sizeof (disk), "/disk@%d", devno); - } - else - { - int part; - - sscanf(digit_string, "%d", &part); - snprintf(disk, sizeof (disk), "/disk@%d:%c", devno, 'a' + (part - 1)); - } - strcat(of_path, disk); - return of_path; -} - -static char * -get_basename(char *p) -{ - char *ret = p; - - while (*p) - { - if (*p == '/') - ret = p + 1; - p++; - } - - return ret; -} - -static char * -of_path_of_vdisk(const char *sys_devname __attribute__((unused)), - const char *device, - const char *devnode __attribute__((unused)), - const char *devicenode) -{ - char *sysfs_path, *p; - int devno, junk; - char *ret; - - sysfs_path = block_device_get_sysfs_path_and_link(devicenode); - p = get_basename (sysfs_path); - sscanf(p, "vdc-port-%d-%d", &devno, &junk); - ret = __of_path_common (sysfs_path, device, devno); - - free (sysfs_path); - return ret; -} - -static char * -of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *device, - const char *devnode __attribute__((unused)), - const char *devicenode) -{ - char *sysfs_path, *p; - int chan, devno; - char *ret; - - sysfs_path = block_device_get_sysfs_path_and_link(devicenode); - p = get_basename (sysfs_path); - sscanf(p, "%d.%d", &chan, &devno); - - ret = __of_path_common(sysfs_path, device, 2 * chan + devno); - - free (sysfs_path); - return ret; -} - -#ifdef __sparc__ -static char * -of_path_of_nvme(const char *sys_devname __attribute__((unused)), - const char *device, - const char *devnode __attribute__((unused)), - const char *devicenode) -{ - char *sysfs_path, *of_path, disk[MAX_DISK_CAT]; - const char *digit_string, *part_end; - - digit_string = trailing_digits (device); - part_end = devicenode + strlen (devicenode) - 1; - - if ((*digit_string != '\0') && (*part_end == 'p')) - { - /* We have a partition number, strip it off. */ - int part; - char *nvmedev, *end; - - nvmedev = strdup (devicenode); - - if (!nvmedev) - return NULL; - - end = nvmedev + strlen (nvmedev) - 1; - /* Remove the p. */ - *end = '\0'; - sscanf (digit_string, "%d", &part); - snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1)); - sysfs_path = block_device_get_sysfs_path_and_link (nvmedev); - free (nvmedev); - } - else - { - /* We do not have the parition. */ - snprintf (disk, sizeof (disk), "/disk@1"); - sysfs_path = block_device_get_sysfs_path_and_link (device); - } - - of_path = find_obppath (sysfs_path); - - if (of_path) - strcat (of_path, disk); - - free (sysfs_path); - return of_path; -} -#endif - -static int -vendor_is_ATA(const char *path) -{ - int fd, err; - char *bufname; - char bufcont[3]; - size_t path_size; - - path_size = strlen (path) + sizeof ("/vendor"); - - bufname = xmalloc (path_size); - - snprintf (bufname, path_size, "%s/vendor", path); - fd = open (bufname, O_RDONLY); - if (fd < 0) - grub_util_error (_("cannot open `%s': %s"), bufname, strerror (errno)); - - memset(bufcont, 0, sizeof (bufcont)); - err = read(fd, bufcont, sizeof (bufcont)); - if (err < 0) - grub_util_error (_("cannot open `%s': %s"), bufname, strerror (errno)); - - close(fd); - free (bufname); - - return (memcmp(bufcont, "ATA", 3) == 0); -} - -#ifdef __sparc__ -static void -check_hba_identifiers (const char *sysfs_path, int *vendor, int *device_id) -{ - char *ed = strstr (sysfs_path, "host"); - size_t path_size; - char *p, *path; - char buf[8]; - int fd; - - if (!ed) - return; - - p = xstrdup (sysfs_path); - ed = strstr (p, "host"); - - *ed = '\0'; - - path_size = (strlen (p) + sizeof ("vendor")); - path = xmalloc (path_size); - - if (!path) - goto out; - - snprintf (path, path_size, "%svendor", p); - fd = open (path, O_RDONLY); - - if (fd < 0) - goto out; - - memset (buf, 0, sizeof (buf)); - - if (read (fd, buf, sizeof (buf) - 1) < 0) - goto out; - - close (fd); - sscanf (buf, "%x", vendor); - - snprintf (path, path_size, "%sdevice", p); - fd = open (path, O_RDONLY); - - if (fd < 0) - goto out; - - memset (buf, 0, sizeof (buf)); - - if (read (fd, buf, sizeof (buf) - 1) < 0) - goto out; - - close (fd); - sscanf (buf, "%x", device_id); - - out: - free (path); - free (p); -} -#endif - -static void -check_sas (const char *sysfs_path, int *tgt, unsigned long int *sas_address) -{ - char *ed = strstr (sysfs_path, "end_device"); - char *p, *q, *path; - char phy[21]; - int fd; - size_t path_size; - - if (!ed) - return; - - /* SAS devices are identified using disk@$PHY_ID */ - p = xstrdup (sysfs_path); - ed = strstr(p, "end_device"); - if (!ed) - return; - - q = ed; - while (*q && *q != '/') - q++; - *q = '\0'; - - path_size = (strlen (p) + strlen (ed) - + sizeof ("%s/sas_device/%s/phy_identifier")); - path = xmalloc (path_size); - snprintf (path, path_size, "%s/sas_device/%s/phy_identifier", p, ed); - fd = open (path, O_RDONLY); - if (fd < 0) - grub_util_error (_("cannot open `%s': %s"), path, strerror (errno)); - - memset (phy, 0, sizeof (phy)); - if (read (fd, phy, sizeof (phy) - 1) < 0) - grub_util_error (_("cannot read `%s': %s"), path, strerror (errno)); - - close (fd); - - sscanf (phy, "%d", tgt); - - snprintf (path, path_size, "%s/sas_device/%s/sas_address", p, ed); - fd = open (path, O_RDONLY); - if (fd < 0) - grub_util_error (_("cannot open `%s': %s"), path, strerror (errno)); - - memset (phy, 0, sizeof (phy)); - if (read (fd, phy, sizeof (phy) - 1) < 0) - grub_util_error (_("cannot read `%s': %s"), path, strerror (errno)); - sscanf (phy, "%lx", sas_address); - - free (path); - free (p); - close (fd); -} - -static char * -of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *device, - const char *devnode __attribute__((unused)), - const char *devicenode) -{ - const char *p, *digit_string, *disk_name; - int host, bus, tgt, lun; - unsigned long int sas_address = 0; - char *sysfs_path, disk[MAX_DISK_CAT - sizeof ("/fp@0,0")]; - char *of_path; - - sysfs_path = block_device_get_sysfs_path_and_link(devicenode); - p = get_basename (sysfs_path); - sscanf(p, "%d:%d:%d:%d", &host, &bus, &tgt, &lun); - check_sas (sysfs_path, &tgt, &sas_address); - - if (vendor_is_ATA(sysfs_path)) - { - of_path = __of_path_common(sysfs_path, device, tgt); - free (sysfs_path); - return of_path; - } - - of_path = find_obppath(sysfs_path); - if (!of_path) - goto out; - - if (strstr (of_path, "qlc")) - strcat (of_path, "/fp@0,0"); - - if (strstr (of_path, "sbus")) - disk_name = "sd"; - else - disk_name = "disk"; - - digit_string = trailing_digits (device); - if (strncmp (of_path, "/vdevice/", sizeof ("/vdevice/") - 1) == 0) - { - unsigned long id = 0x8000 | (tgt << 8) | (bus << 5) | lun; - if (*digit_string == '\0') - { - snprintf(disk, sizeof (disk), "/%s@%04lx000000000000", disk_name, id); - } - else - { - int part; - - sscanf(digit_string, "%d", &part); - snprintf(disk, sizeof (disk), - "/%s@%04lx000000000000:%c", disk_name, id, 'a' + (part - 1)); - } - } - else - { -#ifdef __sparc__ - ofpath_sparc_addressing addressing = GRUB_OFPATH_SPARC_TGT_LUN; - int vendor = 0, device_id = 0; - char *optr = disk; - - check_hba_identifiers (sysfs_path, &vendor, &device_id); - - if (vendor == LSI_VENDOR_ID) - { - struct ofpath_sparc_hba *lsi_hba; - - /* - * Over time different OF addressing schemes have been supported. - * There is no generic addressing scheme that works across - * every HBA. - */ - for (lsi_hba = sparc_lsi_hba; lsi_hba->device_id; lsi_hba++) - if (lsi_hba->device_id == device_id) - { - addressing = lsi_hba->addressing; - break; - } - } - - if (addressing == GRUB_OFPATH_SPARC_WWN_ADDR) - optr += snprintf (disk, sizeof (disk), "/%s@w%lx,%x", disk_name, - sas_address, lun); - else - optr += snprintf (disk, sizeof (disk), "/%s@%x,%x", disk_name, tgt, - lun); - - if (*digit_string != '\0') - { - int part; - - sscanf (digit_string, "%d", &part); - snprintf (optr, sizeof (disk) - (optr - disk - 1), ":%c", 'a' - + (part - 1)); - } -#else - if (lun == 0) - { - int sas_id = 0; - sas_id = bus << 16 | tgt << 8 | lun; - - if (*digit_string == '\0') - { - snprintf(disk, sizeof (disk), "/sas/%s@%x", disk_name, sas_id); - } - else - { - int part; - - sscanf(digit_string, "%d", &part); - snprintf(disk, sizeof (disk), - "/sas/%s@%x:%c", disk_name, sas_id, 'a' + (part - 1)); - } - } - else - { - char *lunstr; - int lunpart[4]; - - lunstr = xmalloc (20); - - lunpart[0] = (lun >> 8) & 0xff; - lunpart[1] = lun & 0xff; - lunpart[2] = (lun >> 24) & 0xff; - lunpart[3] = (lun >> 16) & 0xff; - - sprintf(lunstr, "%02x%02x%02x%02x00000000", lunpart[0], lunpart[1], lunpart[2], lunpart[3]); - long int longlun = atol(lunstr); - - if (*digit_string == '\0') - { - snprintf(disk, sizeof (disk), "/sas/%s@%lx,%lu", disk_name, sas_address, longlun); - } - else - { - int part; - - sscanf(digit_string, "%d", &part); - snprintf(disk, sizeof (disk), - "/sas/%s@%lx,%lu:%c", disk_name, sas_address, longlun, 'a' + (part - 1)); - } - free (lunstr); - } -#endif - } - strcat(of_path, disk); - - out: - free (sysfs_path); - return of_path; -} - -static char * -strip_trailing_digits (const char *p) -{ - char *new, *end; - - new = strdup (p); - end = new + strlen(new) - 1; - while (end >= new) - { - if (! my_isdigit(*end)) - break; - *end-- = '\0'; - } - - return new; -} - -char * -grub_util_devname_to_ofpath (const char *sys_devname) -{ - char *name_buf, *device, *devnode, *devicenode, *ofpath; - - name_buf = xrealpath (sys_devname); - - device = get_basename (name_buf); - devnode = strip_trailing_digits (name_buf); - devicenode = strip_trailing_digits (device); - - if (device[0] == 'h' && device[1] == 'd') - ofpath = of_path_of_ide(name_buf, device, devnode, devicenode); - else if (device[0] == 's' - && (device[1] == 'd' || device[1] == 'r')) - ofpath = of_path_of_scsi(name_buf, device, devnode, devicenode); - else if (device[0] == 'v' && device[1] == 'd' && device[2] == 'i' - && device[3] == 's' && device[4] == 'k') - ofpath = of_path_of_vdisk(name_buf, device, devnode, devicenode); - else if (device[0] == 'f' && device[1] == 'd' - && device[2] == '0' && device[3] == '\0') - /* All the models I've seen have a devalias "floppy". - New models have no floppy at all. */ - ofpath = xstrdup ("floppy"); -#ifdef __sparc__ - else if (device[0] == 'n' && device[1] == 'v' && device[2] == 'm' - && device[3] == 'e') - ofpath = of_path_of_nvme (name_buf, device, devnode, devicenode); -#endif - else - { - grub_util_warn (_("unknown device type %s"), device); - ofpath = NULL; - } - - free (devnode); - free (devicenode); - free (name_buf); - - return ofpath; -} - -#ifdef OFPATH_STANDALONE -int main(int argc, char **argv) -{ - char *of_path; - - if (argc != 2) - { - printf(_("Usage: %s DEVICE\n"), argv[0]); - return 1; - } - - of_path = grub_util_devname_to_ofpath (argv[1]); - if (of_path) - printf("%s\n", of_path); - free (of_path); - - return 0; -} -#endif diff --git a/grub-core/osdep/linux/platform.c b/grub-core/osdep/linux/platform.c deleted file mode 100644 index e28a79dab..000000000 --- a/grub-core/osdep/linux/platform.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include - -static int -is_not_empty_directory (const char *dir) -{ - DIR *d; - struct dirent *de; - - d = opendir (dir); - if (!d) - return 0; - while ((de = readdir (d))) - { - if (strcmp (de->d_name, ".") == 0 - || strcmp (de->d_name, "..") == 0) - continue; - closedir (d); - return 1; - } - - closedir (d); - return 0; -} - -static int -is_64_kernel (void) -{ - struct utsname un; - - if (uname (&un) < 0) - return 0; - - return strcmp (un.machine, "x86_64") == 0; -} - -static int -read_platform_size (void) -{ - FILE *fp; - char *buf = NULL; - size_t len = 0; - int ret = 0; - - /* Newer kernels can tell us directly about the size of the - * underlying firmware - let's see if that interface is there. */ - fp = grub_util_fopen ("/sys/firmware/efi/fw_platform_size", "r"); - if (fp != NULL) - { - if (getline (&buf, &len, fp) >= 3) /* 2 digits plus newline */ - { - if (strncmp (buf, "32", 2) == 0) - ret = 32; - else if (strncmp (buf, "64", 2) == 0) - ret = 64; - } - free (buf); - fclose (fp); - } - - if (ret == 0) - { - /* Unrecognised - fall back to matching the kernel size - * instead */ - if (is_64_kernel ()) - ret = 64; - else - ret = 32; - } - - return ret; -} - -/* Are we running on an EFI-based system? */ -static int -is_efi_system (void) -{ - /* - * Linux uses efivarfs (mounted on /sys/firmware/efi/efivars) to access the - * EFI variable store. Some legacy systems may still use the deprecated - * efivars interface (accessed through /sys/firmware/efi/vars). Where both - * are present, libefivar will use the former in preference, so attempting - * to load efivars will not interfere with later operations. - */ - grub_util_exec_redirect_all ((const char * []){ "modprobe", "efivars", NULL }, - NULL, NULL, "/dev/null"); - - grub_util_info ("Looking for /sys/firmware/efi .."); - if (is_not_empty_directory ("/sys/firmware/efi")) - { - grub_util_info ("...found"); - return 1; - } - else - { - grub_util_info ("... not found"); - return 0; - } -} - -const char * -grub_install_get_default_arm_platform (void) -{ - if (is_efi_system()) - return "arm-efi"; - else - return "arm-uboot"; -} - -const char * -grub_install_get_default_x86_platform (void) -{ - if (is_efi_system()) - { - if (read_platform_size() == 64) - return "x86_64-efi"; - else - return "i386-efi"; - } - - grub_util_info ("Looking for /proc/device-tree .."); - if (is_not_empty_directory ("/proc/device-tree")) - { - grub_util_info ("...found"); - return "i386-ieee1275"; - } - - grub_util_info ("... not found"); - return "i386-pc"; -} diff --git a/grub-core/osdep/ofpath.c b/grub-core/osdep/ofpath.c deleted file mode 100644 index 1389b1d49..000000000 --- a/grub-core/osdep/ofpath.c +++ /dev/null @@ -1,5 +0,0 @@ -#if defined (__linux__) -#include "linux/ofpath.c" -#else -#include "basic/ofpath.c" -#endif diff --git a/grub-core/osdep/password.c b/grub-core/osdep/password.c deleted file mode 100644 index 1a7615ecd..000000000 --- a/grub-core/osdep/password.c +++ /dev/null @@ -1,5 +0,0 @@ -#if defined (__MINGW32__) && !defined (__CYGWIN__) -#include "windows/password.c" -#else -#include "unix/password.c" -#endif diff --git a/grub-core/osdep/platform.c b/grub-core/osdep/platform.c deleted file mode 100644 index 441d152d2..000000000 --- a/grub-core/osdep/platform.c +++ /dev/null @@ -1,9 +0,0 @@ -#ifdef __linux__ -#include "linux/platform.c" -#elif defined (__MINGW32__) || defined (__CYGWIN__) -#include "windows/platform.c" -#elif defined (__MINGW32__) || defined (__CYGWIN__) || defined (__AROS__) -#include "basic/no_platform.c" -#else -#include "basic/platform.c" -#endif diff --git a/grub-core/osdep/platform_unix.c b/grub-core/osdep/platform_unix.c deleted file mode 100644 index db6a02dd1..000000000 --- a/grub-core/osdep/platform_unix.c +++ /dev/null @@ -1,3 +0,0 @@ -#if !defined (__MINGW32__) && !defined (__CYGWIN__) && !defined (__AROS__) -#include "unix/platform.c" -#endif diff --git a/grub-core/osdep/random.c b/grub-core/osdep/random.c deleted file mode 100644 index c6f9bc5e4..000000000 --- a/grub-core/osdep/random.c +++ /dev/null @@ -1,10 +0,0 @@ -#if defined (_WIN32) || defined (__CYGWIN__) -#include "windows/random.c" -#elif defined (__linux__) || defined (__FreeBSD__) \ - || defined (__FreeBSD_kernel__) || defined (__OpenBSD__) \ - || defined (__GNU__) || defined (__NetBSD__) \ - || defined (__APPLE__) || defined(__sun__) || defined (__HAIKU__) -#include "unix/random.c" -#else -#include "basic/random.c" -#endif diff --git a/grub-core/osdep/relpath.c b/grub-core/osdep/relpath.c deleted file mode 100644 index 4e10d8ac1..000000000 --- a/grub-core/osdep/relpath.c +++ /dev/null @@ -1,7 +0,0 @@ -#if defined (__MINGW32__) || defined (__CYGWIN__) -#include "windows/relpath.c" -#elif defined (__AROS__) -#include "aros/relpath.c" -#else -#include "unix/relpath.c" -#endif diff --git a/grub-core/osdep/sleep.c b/grub-core/osdep/sleep.c deleted file mode 100644 index c4ff1724e..000000000 --- a/grub-core/osdep/sleep.c +++ /dev/null @@ -1,5 +0,0 @@ -#if defined (__MINGW32__) || defined (__CYGWIN__) -#include "windows/sleep.c" -#else -#include "unix/sleep.c" -#endif diff --git a/grub-core/osdep/sun/getroot.c b/grub-core/osdep/sun/getroot.c deleted file mode 100644 index 611603769..000000000 --- a/grub-core/osdep/sun/getroot.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIMITS_H -#include -#endif - -#include - -#include - -#include -#include -#include -#include -#include - -#include - -# include -# include -# include - - -char * -grub_util_part_to_disk (const char *os_dev, - struct stat *st, - int *is_part) -{ - char *colon = grub_strrchr (os_dev, ':'); - - if (! S_ISCHR (st->st_mode)) - { - *is_part = 0; - return xstrdup (os_dev); - } - - if (grub_memcmp (os_dev, "/devices", sizeof ("/devices") - 1) == 0 - && colon) - { - char *ret = xmalloc (colon - os_dev + sizeof (":q,raw")); - if (grub_strcmp (colon, ":q,raw") != 0) - *is_part = 1; - grub_memcpy (ret, os_dev, colon - os_dev); - grub_memcpy (ret + (colon - os_dev), ":q,raw", sizeof (":q,raw")); - return ret; - } - else - return xstrdup (os_dev); -} - -enum grub_dev_abstraction_types -grub_util_get_dev_abstraction_os (const char *os_dev __attribute__((unused))) -{ - return GRUB_DEV_ABSTRACTION_NONE; -} - -int -grub_util_pull_device_os (const char *os_dev __attribute__ ((unused)), - enum grub_dev_abstraction_types ab __attribute__ ((unused))) -{ - return 0; -} - -char * -grub_util_get_grub_dev_os (const char *os_dev __attribute__ ((unused))) -{ - return NULL; -} - -grub_disk_addr_t -grub_util_find_partition_start_os (const char *dev) -{ - int fd; - struct extpart_info pinfo; - - fd = open (dev, O_RDONLY); - if (fd == -1) - { - grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot open `%s': %s"), - dev, strerror (errno)); - return 0; - } - - if (ioctl (fd, DKIOCEXTPARTINFO, &pinfo)) - { - grub_error (GRUB_ERR_BAD_DEVICE, - "cannot get disk geometry of `%s'", dev); - close (fd); - return 0; - } - - close (fd); - - return pinfo.p_start; -} diff --git a/grub-core/osdep/sun/hostdisk.c b/grub-core/osdep/sun/hostdisk.c deleted file mode 100644 index a6d4c733e..000000000 --- a/grub-core/osdep/sun/hostdisk.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -# include - -grub_int64_t -grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize) -{ - struct dk_minfo minfo; - unsigned sector_size, log_sector_size; - - if (!ioctl (fd, DKIOCGMEDIAINFO, &minfo)) - return -1; - - sector_size = minfo.dki_lbsize; - - if (sector_size & (sector_size - 1) || !sector_size) - return -1; - log_sector_size = grub_log2ull (sector_size); - - if (log_secsize) - *log_secsize = log_sector_size; - - return minfo.dki_capacity << log_sector_size; -} - -void -grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused))) -{ -} diff --git a/grub-core/osdep/unix/compress.c b/grub-core/osdep/unix/compress.c deleted file mode 100644 index a6e40086b..000000000 --- a/grub-core/osdep/unix/compress.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -int -grub_install_compress_gzip (const char *src, const char *dest) -{ - return grub_util_exec_redirect ((const char * []) { "gzip", "--best", - "--stdout", NULL }, src, dest); -} - -int -grub_install_compress_xz (const char *src, const char *dest) -{ - return grub_util_exec_redirect ((const char * []) { "xz", - "--lzma2=dict=128KiB", "--check=none", "--stdout", NULL }, src, dest); -} - -int -grub_install_compress_lzop (const char *src, const char *dest) -{ - return grub_util_exec_redirect ((const char * []) { "lzop", "-9", "-c", - NULL }, src, dest); -} diff --git a/grub-core/osdep/unix/config.c b/grub-core/osdep/unix/config.c deleted file mode 100644 index 0b1f7618d..000000000 --- a/grub-core/osdep/unix/config.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const char * -grub_util_get_config_filename (void) -{ - static char *value = NULL; - if (!value) - value = grub_util_path_concat (3, GRUB_SYSCONFDIR, - "default", "grub"); - return value; -} - -const char * -grub_util_get_pkgdatadir (void) -{ - const char *ret = getenv ("pkgdatadir"); - if (ret) - return ret; - return GRUB_DATADIR "/" PACKAGE; -} - -const char * -grub_util_get_pkglibdir (void) -{ - return GRUB_LIBDIR "/" PACKAGE; -} - -const char * -grub_util_get_localedir (void) -{ - return LOCALEDIR; -} - -void -grub_util_load_config (struct grub_util_config *cfg) -{ - pid_t pid; - const char *argv[4]; - char *script, *ptr; - const char *cfgfile, *iptr; - FILE *f = NULL; - int fd; - const char *v; - - memset (cfg, 0, sizeof (*cfg)); - - v = getenv ("GRUB_ENABLE_CRYPTODISK"); - if (v && v[0] == 'y' && v[1] == '\0') - cfg->is_cryptodisk_enabled = 1; - - v = getenv ("GRUB_DISTRIBUTOR"); - if (v) - cfg->grub_distributor = xstrdup (v); - - cfgfile = grub_util_get_config_filename (); - if (!grub_util_is_regular (cfgfile)) - return; - - argv[0] = "sh"; - argv[1] = "-c"; - - script = xcalloc (4, strlen (cfgfile) + 300); - - ptr = script; - memcpy (ptr, ". '", 3); - ptr += 3; - for (iptr = cfgfile; *iptr; iptr++) - { - if (*iptr == '\\') - { - memcpy (ptr, "'\\''", 4); - ptr += 4; - continue; - } - *ptr++ = *iptr; - } - - strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\n\" " - "\"$GRUB_ENABLE_CRYPTODISK\" \"$GRUB_DISTRIBUTOR\""); - - argv[2] = script; - argv[3] = '\0'; - - pid = grub_util_exec_pipe (argv, &fd); - if (pid) - f = fdopen (fd, "r"); - if (f) - { - grub_util_parse_config (f, cfg, 1); - fclose (f); - } - if (pid) - { - close (fd); - waitpid (pid, NULL, 0); - } - if (f) - return; - - f = grub_util_fopen (cfgfile, "r"); - if (f) - { - grub_util_parse_config (f, cfg, 0); - fclose (f); - } - else - grub_util_warn (_("cannot open configuration file `%s': %s"), - cfgfile, strerror (errno)); -} diff --git a/grub-core/osdep/unix/cputime.c b/grub-core/osdep/unix/cputime.c deleted file mode 100644 index d43e625f2..000000000 --- a/grub-core/osdep/unix/cputime.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include - -#include -#include -#include - -grub_uint64_t -grub_util_get_cpu_time_ms (void) -{ - struct tms tm; - static long sc_clk_tck; - if (!sc_clk_tck) - { - sc_clk_tck = sysconf(_SC_CLK_TCK); - if (sc_clk_tck <= 0) - sc_clk_tck = 1000; - } - - times (&tm); - return (tm.tms_utime * 1000ULL) / sc_clk_tck; -} diff --git a/grub-core/osdep/unix/dl.c b/grub-core/osdep/unix/dl.c deleted file mode 100644 index 99b189bc1..000000000 --- a/grub-core/osdep/unix/dl.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -void * -grub_osdep_dl_memalign (grub_size_t align, grub_size_t size) -{ - void *ret; - if (align < 8192 * 16) - align = 8192 * 16; - size = ALIGN_UP (size, 8192 * 16); - -#if defined(HAVE_POSIX_MEMALIGN) - if (posix_memalign (&ret, align, size) != 0) - ret = 0; -#elif defined(HAVE_MEMALIGN) - ret = memalign (align, size); -#else -#error "Complete this" -#endif - - if (!ret) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - return NULL; - } - - mprotect (ret, size, PROT_READ | PROT_WRITE | PROT_EXEC); - return ret; -} - -void -grub_dl_osdep_dl_free (void *ptr) -{ - if (ptr) - free (ptr); -} diff --git a/grub-core/osdep/unix/emuconsole.c b/grub-core/osdep/unix/emuconsole.c deleted file mode 100644 index cac159424..000000000 --- a/grub-core/osdep/unix/emuconsole.c +++ /dev/null @@ -1,184 +0,0 @@ -/* console.c -- console for GRUB. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -extern struct grub_terminfo_output_state grub_console_terminfo_output; -static int original_fl; -static int saved_orig; -static struct termios orig_tty; -static struct termios new_tty; - -static void -put (struct grub_term_output *term __attribute__ ((unused)), const int c) -{ - char chr = c; - ssize_t actual; - - actual = write (STDOUT_FILENO, &chr, 1); - if (actual < 1) - { - /* We cannot do anything about this, but some systems require us to at - least pretend to check the result. */ - } -} - -static int -readkey (struct grub_term_input *term __attribute__ ((unused))) -{ - grub_uint8_t c; - ssize_t actual; - - actual = read (STDIN_FILENO, &c, 1); - if (actual > 0) - return c; - return -1; -} - -static grub_err_t -grub_console_init_input (struct grub_term_input *term) -{ - if (!saved_orig) - { - original_fl = fcntl (STDIN_FILENO, F_GETFL); - fcntl (STDIN_FILENO, F_SETFL, original_fl | O_NONBLOCK); - } - - saved_orig = 1; - - tcgetattr(STDIN_FILENO, &orig_tty); - new_tty = orig_tty; - new_tty.c_lflag &= ~(ICANON | ECHO); - new_tty.c_cc[VMIN] = 1; - tcsetattr(STDIN_FILENO, TCSANOW, &new_tty); - - return grub_terminfo_input_init (term); -} - -static grub_err_t -grub_console_fini_input (struct grub_term_input *term - __attribute__ ((unused))) -{ - fcntl (STDIN_FILENO, F_SETFL, original_fl); - tcsetattr(STDIN_FILENO, TCSANOW, &orig_tty); - saved_orig = 0; - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_console_init_output (struct grub_term_output *term) -{ - struct winsize size; - if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &size) >= 0) - { - grub_console_terminfo_output.size.x = size.ws_col; - grub_console_terminfo_output.size.y = size.ws_row; - } - else - { - grub_console_terminfo_output.size.x = 80; - grub_console_terminfo_output.size.y = 24; - } - - grub_terminfo_output_init (term); - - return 0; -} - - - -struct grub_terminfo_input_state grub_console_terminfo_input = - { - .readkey = readkey - }; - -struct grub_terminfo_output_state grub_console_terminfo_output = - { - .put = put, - .size = { 80, 24 } - }; - -static struct grub_term_input grub_console_term_input = - { - .name = "console", - .init = grub_console_init_input, - .fini = grub_console_fini_input, - .getkey = grub_terminfo_getkey, - .data = &grub_console_terminfo_input - }; - -static struct grub_term_output grub_console_term_output = - { - .name = "console", - .init = grub_console_init_output, - .putchar = grub_terminfo_putchar, - .getxy = grub_terminfo_getxy, - .getwh = grub_terminfo_getwh, - .gotoxy = grub_terminfo_gotoxy, - .cls = grub_terminfo_cls, - .setcolorstate = grub_terminfo_setcolorstate, - .setcursor = grub_terminfo_setcursor, - .data = &grub_console_terminfo_output, - .progress_update_divisor = GRUB_PROGRESS_FAST - }; - -void -grub_console_init (void) -{ - const char *cs = nl_langinfo (CODESET); - if (cs && grub_strcasecmp (cs, "UTF-8")) - grub_console_term_output.flags = GRUB_TERM_CODE_TYPE_UTF8_LOGICAL; - else - grub_console_term_output.flags = GRUB_TERM_CODE_TYPE_ASCII; - grub_term_register_input ("console", &grub_console_term_input); - grub_term_register_output ("console", &grub_console_term_output); - grub_terminfo_init (); - grub_terminfo_output_register (&grub_console_term_output, "vt100-color"); -} - -void -grub_console_fini (void) -{ - if (saved_orig) - { - fcntl (STDIN_FILENO, F_SETFL, original_fl); - tcsetattr(STDIN_FILENO, TCSANOW, &orig_tty); - } - saved_orig = 0; -} diff --git a/grub-core/osdep/unix/exec.c b/grub-core/osdep/unix/exec.c deleted file mode 100644 index c44ff3360..000000000 --- a/grub-core/osdep/unix/exec.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int -grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file, - const char *stdout_file, const char *stderr_file) -{ - pid_t pid; - int status = -1; - char *str, *pstr; - const char *const *ptr; - grub_size_t strl = 0; - for (ptr = argv; *ptr; ptr++) - strl += grub_strlen (*ptr) + 1; - if (stdin_file) - strl += grub_strlen (stdin_file) + 2; - if (stdout_file) - strl += grub_strlen (stdout_file) + 2; - if (stderr_file) - strl += grub_strlen (stderr_file) + 3; - - pstr = str = xmalloc (strl); - for (ptr = argv; *ptr; ptr++) - { - pstr = grub_stpcpy (pstr, *ptr); - *pstr++ = ' '; - } - if (stdin_file) - { - *pstr++ = '<'; - pstr = grub_stpcpy (pstr, stdin_file); - *pstr++ = ' '; - } - if (stdout_file) - { - *pstr++ = '>'; - pstr = grub_stpcpy (pstr, stdout_file); - *pstr++ = ' '; - } - if (stderr_file) - { - *pstr++ = '2'; - *pstr++ = '>'; - pstr = grub_stpcpy (pstr, stderr_file); - pstr++; - } - *--pstr = '\0'; - - grub_util_info ("executing %s", str); - grub_free (str); - - pid = fork (); - if (pid < 0) - grub_util_error (_("Unable to fork: %s"), strerror (errno)); - else if (pid == 0) - { - int fd; - /* Child. */ - - /* Close fd's. */ -#ifdef GRUB_UTIL - grub_util_devmapper_cleanup (); - grub_diskfilter_fini (); -#endif - - if (stdin_file) - { - fd = open (stdin_file, O_RDONLY); - if (fd < 0) - _exit (127); - dup2 (fd, STDIN_FILENO); - close (fd); - } - - if (stdout_file) - { - fd = open (stdout_file, O_WRONLY | O_CREAT, 0700); - if (fd < 0) - _exit (127); - dup2 (fd, STDOUT_FILENO); - close (fd); - } - - if (stderr_file) - { - fd = open (stderr_file, O_WRONLY | O_CREAT, 0700); - if (fd < 0) - _exit (127); - dup2 (fd, STDERR_FILENO); - close (fd); - } - - /* Ensure child is not localised. */ - setenv ("LC_ALL", "C", 1); - - execvp ((char *) argv[0], (char **) argv); - _exit (127); - } - waitpid (pid, &status, 0); - if (!WIFEXITED (status)) - return -1; - return WEXITSTATUS (status); -} - -int -grub_util_exec (const char *const *argv) -{ - return grub_util_exec_redirect_all (argv, NULL, NULL, NULL); -} - -int -grub_util_exec_redirect (const char *const *argv, const char *stdin_file, - const char *stdout_file) -{ - return grub_util_exec_redirect_all (argv, stdin_file, stdout_file, NULL); -} - -int -grub_util_exec_redirect_null (const char *const *argv) -{ - return grub_util_exec_redirect_all (argv, "/dev/null", "/dev/null", NULL); -} - -pid_t -grub_util_exec_pipe (const char *const *argv, int *fd) -{ - int pipe_fd[2]; - pid_t pid; - - *fd = 0; - - if (pipe (pipe_fd) < 0) - { - grub_util_warn (_("Unable to create pipe: %s"), - strerror (errno)); - return 0; - } - pid = fork (); - if (pid < 0) - grub_util_error (_("Unable to fork: %s"), strerror (errno)); - else if (pid == 0) - { - /* Child. */ - - /* Close fd's. */ -#ifdef GRUB_UTIL - grub_util_devmapper_cleanup (); - grub_diskfilter_fini (); -#endif - - /* Ensure child is not localised. */ - setenv ("LC_ALL", "C", 1); - - close (pipe_fd[0]); - dup2 (pipe_fd[1], STDOUT_FILENO); - close (pipe_fd[1]); - - execvp ((char *) argv[0], (char **) argv); - _exit (127); - } - else - { - close (pipe_fd[1]); - *fd = pipe_fd[0]; - return pid; - } -} - -pid_t -grub_util_exec_pipe_stderr (const char *const *argv, int *fd) -{ - int pipe_fd[2]; - pid_t pid; - - *fd = 0; - - if (pipe (pipe_fd) < 0) - { - grub_util_warn (_("Unable to create pipe: %s"), - strerror (errno)); - return 0; - } - pid = fork (); - if (pid < 0) - grub_util_error (_("Unable to fork: %s"), strerror (errno)); - else if (pid == 0) - { - /* Child. */ - - /* Close fd's. */ -#ifdef GRUB_UTIL - grub_util_devmapper_cleanup (); - grub_diskfilter_fini (); -#endif - - /* Ensure child is not localised. */ - setenv ("LC_ALL", "C", 1); - - close (pipe_fd[0]); - dup2 (pipe_fd[1], STDOUT_FILENO); - dup2 (pipe_fd[1], STDERR_FILENO); - close (pipe_fd[1]); - - execvp ((char *) argv[0], (char **) argv); - _exit (127); - } - else - { - close (pipe_fd[1]); - *fd = pipe_fd[0]; - return pid; - } -} diff --git a/grub-core/osdep/unix/getroot.c b/grub-core/osdep/unix/getroot.c deleted file mode 100644 index c7aa202ab..000000000 --- a/grub-core/osdep/unix/getroot.c +++ /dev/null @@ -1,782 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIMITS_H -#include -#endif - -#include -#include - -#include -#include - -#if !defined (__MINGW32__) && !defined (__CYGWIN__) && !defined (__AROS__) && !defined (__HAIKU__) - -#ifdef __linux__ -#include /* ioctl */ -#include -#ifndef FLOPPY_MAJOR -# define FLOPPY_MAJOR 2 -#endif /* ! FLOPPY_MAJOR */ -#endif - -#include - -#ifdef USE_LIBZFS -# include -# include -#endif - -#include -#include -#include -#include -#include - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -# define FLOPPY_MAJOR 2 -#endif - -#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) -#include -#endif - -#if defined(__NetBSD__) || defined(__OpenBSD__) -# include -# include /* struct disklabel */ -# include /* struct dkwedge_info */ -#include -#include -#endif /* defined(__NetBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) */ - -#if defined(__NetBSD__) || defined(__OpenBSD__) -# ifdef HAVE_GETRAWPARTITION -# include /* getrawpartition */ -# endif /* HAVE_GETRAWPARTITION */ -#if defined(__NetBSD__) -# include -#endif -# ifndef FLOPPY_MAJOR -# define FLOPPY_MAJOR 2 -# endif /* ! FLOPPY_MAJOR */ -# ifndef RAW_FLOPPY_MAJOR -# define RAW_FLOPPY_MAJOR 9 -# endif /* ! RAW_FLOPPY_MAJOR */ -#endif /* defined(__NetBSD__) */ - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#define LVM_DEV_MAPPER_STRING "/dev/linux_lvm/" -#else -#define LVM_DEV_MAPPER_STRING "/dev/mapper/" -#endif - -#include -#include - -#if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) && defined(HAVE_STRUCT_STATFS_F_MNTFROMNAME) -#include -#include -#endif - -#include "save-cwd.h" - -#if !defined (__GNU__) -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; -} - -char ** -grub_util_find_root_devices_from_poolname (char *poolname) -{ - char **devices = 0; - size_t ndevices = 0; - size_t devices_allocated = 0; - -#ifdef USE_LIBZFS - zpool_handle_t *zpool; - libzfs_handle_t *libzfs; - nvlist_t *config, *vdev_tree; - nvlist_t **children; - unsigned int nvlist_count; - unsigned int i; - char *device = 0; - - libzfs = grub_get_libzfs_handle (); - if (! libzfs) - return NULL; - - zpool = zpool_open (libzfs, poolname); - config = zpool_get_config (zpool, NULL); - - if (NVLIST(lookup_nvlist) (config, "vdev_tree", &vdev_tree) != 0) - error (1, errno, "nvlist_lookup_nvlist (\"vdev_tree\")"); - - if (NVLIST(lookup_nvlist_array) (vdev_tree, "children", &children, &nvlist_count) != 0) - error (1, errno, "nvlist_lookup_nvlist_array (\"children\")"); - assert (nvlist_count > 0); - - while (NVLIST(lookup_nvlist_array) (children[0], "children", - &children, &nvlist_count) == 0) - assert (nvlist_count > 0); - - for (i = 0; i < nvlist_count; i++) - { - if (NVLIST(lookup_string) (children[i], "path", &device) != 0) - error (1, errno, "nvlist_lookup_string (\"path\")"); - - struct stat st; - if (stat (device, &st) == 0) - { -#ifdef __sun__ - if (grub_memcmp (device, "/dev/dsk/", sizeof ("/dev/dsk/") - 1) - == 0) - device = xasprintf ("/dev/rdsk/%s", - device + sizeof ("/dev/dsk/") - 1); - else if (grub_memcmp (device, "/devices", sizeof ("/devices") - 1) - == 0 - && grub_memcmp (device + strlen (device) - 4, - ",raw", 4) != 0) - device = xasprintf ("%s,raw", device); - else -#endif - device = xstrdup (device); - if (ndevices >= devices_allocated) - { - devices_allocated = 2 * (devices_allocated + 8); - devices = xrealloc (devices, sizeof (devices[0]) - * devices_allocated); - } - devices[ndevices++] = device; - } - - device = NULL; - } - - zpool_close (zpool); -#else - FILE *fp; - int ret; - char *line; - size_t len; - int st; - - char name[PATH_MAX + 1], state[257], readlen[257], writelen[257]; - char cksum[257], notes[257]; - unsigned int dummy; - const char *argv[5]; - pid_t pid; - int fd; - - argv[0] = "zpool"; - argv[1] = "status"; - argv[2] = "-P"; - argv[3] = poolname; - argv[4] = NULL; - - pid = grub_util_exec_pipe (argv, &fd); - if (!pid) - return NULL; - - fp = fdopen (fd, "r"); - if (!fp) - { - grub_util_warn (_("Unable to open stream from %s: %s"), - "zpool", strerror (errno)); - goto out; - } - - st = 0; - while (1) - { - line = NULL; - ret = getline (&line, &len, fp); - if (ret == -1) - break; - - if (sscanf (line, " %s %256s %256s %256s %256s %256s", - name, state, readlen, writelen, cksum, notes) >= 5) - switch (st) - { - case 0: - if (!strcmp (name, "NAME") - && !strcmp (state, "STATE") - && !strcmp (readlen, "READ") - && !strcmp (writelen, "WRITE") - && !strcmp (cksum, "CKSUM")) - st++; - break; - case 1: - { - char *ptr = line; - while (1) - { - if (strncmp (ptr, poolname, strlen (poolname)) == 0 - && grub_isspace(ptr[strlen (poolname)])) - st++; - if (!grub_isspace (*ptr)) - break; - ptr++; - } - } - break; - case 2: - if (strcmp (name, "mirror") && !sscanf (name, "mirror-%u", &dummy) - && !sscanf (name, "raidz%u", &dummy) - && !sscanf (name, "raidz1%u", &dummy) - && !sscanf (name, "raidz2%u", &dummy) - && !sscanf (name, "raidz3%u", &dummy) - && !strcmp (state, "ONLINE")) - { - if (ndevices >= devices_allocated) - { - devices_allocated = 2 * (devices_allocated + 8); - devices = xrealloc (devices, sizeof (devices[0]) - * devices_allocated); - } - if (name[0] == '/') - devices[ndevices++] = xstrdup (name); - else - devices[ndevices++] = xasprintf ("/dev/%s", name); - } - break; - } - - free (line); - } - - out: - close (fd); - waitpid (pid, NULL, 0); -#endif - if (devices) - { - if (ndevices >= devices_allocated) - { - devices_allocated = 2 * (devices_allocated + 8); - devices = xrealloc (devices, sizeof (devices[0]) - * devices_allocated); - } - devices[ndevices++] = 0; - } - return devices; -} - -static char ** -find_root_devices_from_libzfs (const char *dir) -{ - char **devices = NULL; - char *poolname; - char *poolfs; - - grub_find_zpool_from_dir (dir, &poolname, &poolfs); - if (! poolname) - return NULL; - - devices = grub_util_find_root_devices_from_poolname (poolname); - - free (poolname); - if (poolfs) - free (poolfs); - - return devices; -} - -char * -grub_find_device (const char *dir, dev_t dev) -{ - DIR *dp; - struct saved_cwd saved_cwd; - struct dirent *ent; - - if (! dir) - dir = "/dev"; - - dp = opendir (dir); - if (! dp) - return 0; - - if (save_cwd (&saved_cwd) < 0) - { - grub_util_error ("%s", _("cannot save the original directory")); - closedir (dp); - return 0; - } - - grub_util_info ("changing current directory to %s", dir); - if (chdir (dir) < 0) - { - free_cwd (&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)) { -#ifdef __linux__ - if (strcmp (dir, "mapper") == 0 || strcmp (dir, "/dev/mapper") == 0) { - /* Follow symbolic links under /dev/mapper/; the canonical name - may be something like /dev/dm-0, but the names under - /dev/mapper/ are more human-readable and so we prefer them if - we can get them. */ - if (stat (ent->d_name, &st) < 0) - continue; - } else -#endif /* __linux__ */ - /* Don't follow other symbolic links. */ - continue; - } - - if (S_ISDIR (st.st_mode)) - { - /* Find it recursively. */ - char *res; - - res = grub_find_device (ent->d_name, dev); - - if (res) - { - if (restore_cwd (&saved_cwd) < 0) - grub_util_error ("%s", - _("cannot restore the original directory")); - - free_cwd (&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. - Also, don't skip devices which names start with dm-[0-9] in - directories below /dev, e.g. /dev/mapper/dm-0-luks. */ - if (strcmp (dir, "/dev") == 0 && - 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; - - cwd = xgetcwd (); - res = xmalloc (strlen (cwd) + strlen (ent->d_name) + 3); - sprintf (res, -#if defined(__NetBSD__) || defined(__OpenBSD__) - /* Convert this block device to its character (raw) device. */ - "%s/r%s", -#else - /* Keep the device name as it is. */ - "%s/%s", -#endif - 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) - { - free (res); - continue; - } - - if (restore_cwd (&saved_cwd) < 0) - grub_util_error ("%s", _("cannot restore the original directory")); - - free_cwd (&saved_cwd); - closedir (dp); - return res; - } - } - - if (restore_cwd (&saved_cwd) < 0) - grub_util_error ("%s", _("cannot restore the original directory")); - - free_cwd (&saved_cwd); - closedir (dp); - return 0; -} - -char ** -grub_guess_root_devices (const char *dir_in) -{ - char **os_dev = NULL; - struct stat st; - dev_t dev; - char *dir = grub_canonicalize_file_name (dir_in); - - if (!dir) - grub_util_error (_("failed to get canonical path of `%s'"), dir_in); - -#ifdef __linux__ - if (!os_dev) - os_dev = grub_find_root_devices_from_mountinfo (dir, NULL); -#endif /* __linux__ */ - - if (!os_dev) - os_dev = find_root_devices_from_libzfs (dir); - - if (os_dev) - { - char **cur; - for (cur = os_dev; *cur; cur++) - { - char *tmp = *cur; - int root, dm; - if (strcmp (*cur, "/dev/root") == 0 - || strncmp (*cur, "/dev/dm-", sizeof ("/dev/dm-") - 1) == 0) - *cur = tmp; - else - { - *cur = grub_canonicalize_file_name (tmp); - if (*cur == NULL) - grub_util_error (_("failed to get canonical path of `%s'"), tmp); - free (tmp); - } - root = (strcmp (*cur, "/dev/root") == 0); - dm = (strncmp (*cur, "/dev/dm-", sizeof ("/dev/dm-") - 1) == 0); - if (!dm && !root) - continue; - if (stat (*cur, &st) < 0) - break; - free (*cur); - dev = st.st_rdev; - *cur = grub_find_device (dm ? "/dev/mapper" : "/dev", dev); - } - if (!*cur) - return os_dev; - for (cur = os_dev; *cur; cur++) - free (*cur); - free (os_dev); - } - - if (stat (dir, &st) < 0) - grub_util_error (_("cannot stat `%s': %s"), dir, strerror (errno)); - free (dir); - - dev = st.st_dev; - - os_dev = xmalloc (2 * sizeof (os_dev[0])); - - /* This might be truly slow, but is there any better way? */ - os_dev[0] = grub_find_device ("/dev", dev); - - if (!os_dev[0]) - { - free (os_dev); - return 0; - } - - os_dev[1] = 0; - - return os_dev; -} - -#endif - -void -grub_util_pull_lvm_by_command (const char *os_dev) -{ - const char *argv[8]; - int fd; - pid_t pid; - FILE *vgs; - char *buf = NULL; - size_t len = 0; - char *vgname = NULL; - const char *iptr; - char *optr; - char *vgid = NULL; - grub_size_t vgidlen = 0; - - vgid = grub_util_get_vg_uuid (os_dev); - if (vgid) - vgidlen = grub_strlen (vgid); - - if (!vgid) - { - if (strncmp (os_dev, LVM_DEV_MAPPER_STRING, - sizeof (LVM_DEV_MAPPER_STRING) - 1) - != 0) - return; - - vgname = xmalloc (strlen (os_dev + sizeof (LVM_DEV_MAPPER_STRING) - 1) + 1); - for (iptr = os_dev + sizeof (LVM_DEV_MAPPER_STRING) - 1, optr = vgname; *iptr; ) - if (*iptr != '-') - *optr++ = *iptr++; - else if (iptr[0] == '-' && iptr[1] == '-') - { - iptr += 2; - *optr++ = '-'; - } - else - break; - *optr = '\0'; - } - - /* by default PV name is left aligned in 10 character field, meaning that - we do not know where name ends. Using dummy --separator disables - alignment. We have a single field, so separator itself is not output */ - argv[0] = "vgs"; - argv[1] = "--options"; - if (vgid) - argv[2] = "vg_uuid,pv_name"; - else - argv[2] = "pv_name"; - argv[3] = "--noheadings"; - argv[4] = "--separator"; - argv[5] = ":"; - argv[6] = vgname; - argv[7] = NULL; - - pid = grub_util_exec_pipe (argv, &fd); - free (vgname); - - if (!pid) - { - free (vgid); - return; - } - - /* Parent. Read vgs' output. */ - vgs = fdopen (fd, "r"); - if (! vgs) - { - grub_util_warn (_("Unable to open stream from %s: %s"), - "vgs", strerror (errno)); - goto out; - } - - while (getline (&buf, &len, vgs) > 0) - { - char *ptr; - /* LVM adds two spaces as standard prefix */ - for (ptr = buf; ptr < buf + 2 && *ptr == ' '; ptr++); - - if (vgid && (grub_strncmp (vgid, ptr, vgidlen) != 0 - || ptr[vgidlen] != ':')) - continue; - if (vgid) - ptr += vgidlen + 1; - if (*ptr == '\0') - continue; - *(ptr + strlen (ptr) - 1) = '\0'; - grub_util_pull_device (ptr); - } - -out: - close (fd); - waitpid (pid, NULL, 0); - free (buf); - free (vgid); -} - -/* ZFS has similar problems to those of btrfs (see above). */ -void -grub_find_zpool_from_dir (const char *dir, char **poolname, char **poolfs) -{ - char *slash; - - *poolname = *poolfs = NULL; - -#if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) && defined(HAVE_STRUCT_STATFS_F_MNTFROMNAME) - /* FreeBSD and GNU/kFreeBSD. */ - { - struct statfs mnt; - - if (statfs (dir, &mnt) != 0) - return; - - if (strcmp (mnt.f_fstypename, "zfs") != 0) - return; - - *poolname = xstrdup (mnt.f_mntfromname); - } -#elif defined(HAVE_GETEXTMNTENT) - /* Solaris. */ - { - struct stat st; - struct extmnttab mnt; - - if (stat (dir, &st) != 0) - return; - - FILE *mnttab = grub_util_fopen ("/etc/mnttab", "r"); - if (! mnttab) - return; - - while (getextmntent (mnttab, &mnt, sizeof (mnt)) == 0) - { - if (makedev (mnt.mnt_major, mnt.mnt_minor) == st.st_dev - && !strcmp (mnt.mnt_fstype, "zfs")) - { - *poolname = xstrdup (mnt.mnt_special); - break; - } - } - - fclose (mnttab); - } -#endif - - if (! *poolname) - return; - - slash = strchr (*poolname, '/'); - if (slash) - { - *slash = '\0'; - *poolfs = xstrdup (slash + 1); - } - else - *poolfs = xstrdup (""); -} - -int -grub_util_biosdisk_is_floppy (grub_disk_t disk) -{ - struct stat st; - int fd; - const char *dname; - - dname = grub_util_biosdisk_get_osdev (disk); - - if (!dname) - return 0; - - fd = open (dname, O_RDONLY); - /* Shouldn't happen. */ - if (fd == -1) - return 0; - - /* Shouldn't happen either. */ - if (fstat (fd, &st) < 0) - { - close (fd); - return 0; - } - - close (fd); - -#if defined(__NetBSD__) - if (major(st.st_rdev) == RAW_FLOPPY_MAJOR) - return 1; -#endif - -#if defined(FLOPPY_MAJOR) - if (major(st.st_rdev) == FLOPPY_MAJOR) -#else - /* Some kernels (e.g. kFreeBSD) don't have a static major number - for floppies, but they still use a "fd[0-9]" pathname. */ - if (dname[5] == 'f' - && dname[6] == 'd' - && dname[7] >= '0' - && dname[7] <= '9') -#endif - return 1; - - return 0; -} - -#else - -#include - -void -grub_util_pull_lvm_by_command (const char *os_dev __attribute__ ((unused))) -{ -} - -#endif diff --git a/grub-core/osdep/unix/hostdisk.c b/grub-core/osdep/unix/hostdisk.c deleted file mode 100644 index 353db01f6..000000000 --- a/grub-core/osdep/unix/hostdisk.c +++ /dev/null @@ -1,325 +0,0 @@ -/* hostdisk.c - emulate biosdisk */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined (__CYGWIN__) && !defined (__MINGW32__) && !defined (__AROS__) - -#ifdef __linux__ -# include /* ioctl */ -# include -#endif /* __linux__ */ - -grub_uint64_t -grub_util_get_fd_size (grub_util_fd_t fd, const char *name, unsigned *log_secsize) -{ - struct stat st; - grub_int64_t ret = -1; - - if (fstat (fd, &st) < 0) - /* TRANSLATORS: "stat" comes from the name of POSIX function. */ - grub_util_error (_("cannot stat `%s': %s"), name, strerror (errno)); -#if GRUB_DISK_DEVS_ARE_CHAR - if (S_ISCHR (st.st_mode)) -#else - if (S_ISBLK (st.st_mode)) -#endif - ret = grub_util_get_fd_size_os (fd, name, log_secsize); - if (ret != -1LL) - return ret; - - if (log_secsize) - *log_secsize = 9; - - return st.st_size; -} - -int -grub_util_fd_seek (grub_util_fd_t fd, grub_uint64_t off) -{ -#if SIZEOF_OFF_T == 8 - off_t offset = (off_t) off; - - if (lseek (fd, offset, SEEK_SET) != offset) - return -1; -#elif SIZEOF_OFF64_T == 8 - off64_t offset = (off64_t) off; - - if (lseek64 (fd, offset, SEEK_SET) != offset) - return -1; -#else -#error "No large file support" -#endif - return 0; -} - - -/* Read LEN bytes from FD in BUF. Return less than or equal to zero if an - error occurs, otherwise return LEN. */ -ssize_t -grub_util_fd_read (grub_util_fd_t fd, char *buf, size_t len) -{ - ssize_t size = 0; - - if (len > SSIZE_MAX) - return -1; - - while (len) - { - ssize_t ret = read (fd, buf, len); - - if (ret == 0) - break; - - if (ret < 0) - { - if (errno == EINTR) - continue; - else - return ret; - } - - len -= ret; - buf += ret; - size += ret; - } - - return size; -} - -/* Write LEN bytes from BUF to FD. Return less than or equal to zero if an - error occurs, otherwise return LEN. */ -ssize_t -grub_util_fd_write (grub_util_fd_t fd, const char *buf, size_t len) -{ - ssize_t size = 0; - - if (len > SSIZE_MAX) - return -1; - - while (len) - { - ssize_t ret = write (fd, buf, len); - - if (ret == 0) - break; - - if (ret < 0) - { - if (errno == EINTR) - continue; - else - return ret; - } - - len -= ret; - buf += ret; - size += ret; - } - - return size; -} - -#if !defined (__NetBSD__) && !defined (__APPLE__) && !defined (__FreeBSD__) && !defined(__FreeBSD_kernel__) -grub_util_fd_t -grub_util_fd_open (const char *os_dev, int flags) -{ -#ifdef O_LARGEFILE - flags |= O_LARGEFILE; -#endif -#ifdef O_BINARY - flags |= O_BINARY; -#endif -#ifdef O_CLOEXEC - flags |= O_CLOEXEC; -#endif - - return open (os_dev, flags, S_IROTH | S_IRGRP | S_IRUSR | S_IWUSR); -} -#endif - -const char * -grub_util_fd_strerror (void) -{ - return strerror (errno); -} - -static int allow_fd_syncs = 1; - -int -grub_util_fd_sync (grub_util_fd_t fd) -{ - if (allow_fd_syncs) - return fsync (fd); - return 0; -} - -int -grub_util_file_sync (FILE *f) -{ - if (fflush (f) != 0) - return -1; - if (!allow_fd_syncs) - return 0; - return fsync (fileno (f)); -} - -void -grub_util_disable_fd_syncs (void) -{ - allow_fd_syncs = 0; -} - -int -grub_util_fd_close (grub_util_fd_t fd) -{ - return close (fd); -} - -char * -grub_canonicalize_file_name (const char *path) -{ -#if defined (PATH_MAX) - char *ret; - - ret = xmalloc (PATH_MAX); - if (!realpath (path, ret)) - return NULL; - return ret; -#else - return realpath (path, NULL); -#endif -} - -FILE * -grub_util_fopen (const char *path, const char *mode) -{ - return fopen (path, mode); -} - -int -grub_util_is_directory (const char *path) -{ - struct stat st; - - if (stat (path, &st) == -1) - return 0; - - return S_ISDIR (st.st_mode); -} - -int -grub_util_is_regular (const char *path) -{ - struct stat st; - - if (stat (path, &st) == -1) - return 0; - - return S_ISREG (st.st_mode); -} - -grub_uint32_t -grub_util_get_mtime (const char *path) -{ - struct stat st; - - if (stat (path, &st) == -1) - return 0; - - return st.st_mtime; -} - -#endif - -#if defined (__CYGWIN__) || (!defined (__MINGW32__) && !defined (__AROS__)) - -int -grub_util_is_special_file (const char *path) -{ - struct stat st; - - if (lstat (path, &st) == -1) - return 1; - return (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode)); -} - - -char * -grub_util_make_temporary_file (void) -{ - const char *t = getenv ("TMPDIR"); - size_t tl; - char *tmp; - if (!t) - t = "/tmp"; - tl = strlen (t); - tmp = xmalloc (tl + sizeof ("/grub.XXXXXX")); - memcpy (tmp, t, tl); - memcpy (tmp + tl, "/grub.XXXXXX", - sizeof ("/grub.XXXXXX")); - if (mkstemp (tmp) == -1) - grub_util_error (_("cannot make temporary file: %s"), strerror (errno)); - return tmp; -} - -char * -grub_util_make_temporary_dir (void) -{ - const char *t = getenv ("TMPDIR"); - size_t tl; - char *tmp; - if (!t) - t = "/tmp"; - tl = strlen (t); - tmp = xmalloc (tl + sizeof ("/grub.XXXXXX")); - memcpy (tmp, t, tl); - memcpy (tmp + tl, "/grub.XXXXXX", - sizeof ("/grub.XXXXXX")); - if (!mkdtemp (tmp)) - grub_util_error (_("cannot make temporary directory: %s"), - strerror (errno)); - return tmp; -} - -#endif diff --git a/grub-core/osdep/unix/password.c b/grub-core/osdep/unix/password.c deleted file mode 100644 index 9996b244b..000000000 --- a/grub-core/osdep/unix/password.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 - * 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -#include -#include -#include -#include - -int -grub_password_get (char buf[], unsigned buf_size) -{ - FILE *in; - struct termios s, t; - int tty_changed = 0; - char *ptr; - - grub_refresh (); - - /* Disable echoing. Based on glibc. */ - in = fopen ("/dev/tty", "w+c"); - if (in == NULL) - in = stdin; - - if (tcgetattr (fileno (in), &t) == 0) - { - /* Save the old one. */ - s = t; - /* Tricky, tricky. */ - t.c_lflag &= ~(ECHO|ISIG); - tty_changed = (tcsetattr (fileno (in), TCSAFLUSH, &t) == 0); - } - else - tty_changed = 0; - grub_memset (buf, 0, buf_size); - if (!fgets (buf, buf_size, stdin)) - { - if (in != stdin) - fclose (in); - return 0; - } - ptr = buf + strlen (buf) - 1; - while (buf <= ptr && (*ptr == '\n' || *ptr == '\r')) - *ptr-- = 0; - /* Restore the original setting. */ - if (tty_changed) - (void) tcsetattr (fileno (in), TCSAFLUSH, &s); - - grub_xputs ("\n"); - grub_refresh (); - - if (in != stdin) - fclose (in); - - return 1; -} diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c deleted file mode 100644 index de712211c..000000000 --- a/grub-core/osdep/unix/platform.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static char * -get_ofpathname (const char *dev) -{ - size_t alloced = 4096; - char *ret = xmalloc (alloced); - size_t offset = 0; - int fd; - pid_t pid; - - pid = grub_util_exec_pipe ((const char * []){ "ofpathname", dev, NULL }, &fd); - if (!pid) - goto fail; - - FILE *fp = fdopen (fd, "r"); - if (!fp) - goto fail; - - while (!feof (fp)) - { - size_t r; - if (alloced == offset) - { - alloced *= 2; - ret = xrealloc (ret, alloced); - } - r = fread (ret + offset, 1, alloced - offset, fp); - offset += r; - } - - if (offset > 0 && ret[offset - 1] == '\n') - offset--; - if (offset > 0 && ret[offset - 1] == '\r') - offset--; - if (alloced == offset) - { - alloced++; - ret = xrealloc (ret, alloced); - } - ret[offset] = '\0'; - - fclose (fp); - - return ret; - - fail: - grub_util_error (_("couldn't find IEEE1275 device path for %s.\nYou will have to set `boot-device' variable manually"), - dev); -} - -static int -grub_install_remove_efi_entries_by_distributor (const char *efi_distributor) -{ - int fd; - pid_t pid = grub_util_exec_pipe ((const char * []){ "efibootmgr", NULL }, &fd); - char *line = NULL; - size_t len = 0; - int rc = 0; - - if (!pid) - { - grub_util_warn (_("Unable to open stream from %s: %s"), - "efibootmgr", strerror (errno)); - return errno; - } - - FILE *fp = fdopen (fd, "r"); - if (!fp) - { - grub_util_warn (_("Unable to open stream from %s: %s"), - "efibootmgr", strerror (errno)); - return errno; - } - - line = xmalloc (80); - len = 80; - while (1) - { - int ret; - char *bootnum; - ret = getline (&line, &len, fp); - if (ret == -1) - break; - if (grub_memcmp (line, "Boot", sizeof ("Boot") - 1) != 0 - || line[sizeof ("Boot") - 1] < '0' - || line[sizeof ("Boot") - 1] > '9') - continue; - if (!strcasestr (line, efi_distributor)) - continue; - bootnum = line + sizeof ("Boot") - 1; - bootnum[4] = '\0'; - if (!verbosity) - rc = grub_util_exec ((const char * []){ "efibootmgr", "-q", - "-b", bootnum, "-B", NULL }); - else - rc = grub_util_exec ((const char * []){ "efibootmgr", - "-b", bootnum, "-B", NULL }); - } - - free (line); - return rc; -} - -int -grub_install_register_efi (grub_device_t efidir_grub_dev, - const char *efifile_path, - const char *efi_distributor) -{ - const char * efidir_disk; - int efidir_part; - int ret; - efidir_disk = grub_util_biosdisk_get_osdev (efidir_grub_dev->disk); - efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1; - - if (grub_util_exec_redirect_null ((const char * []){ "efibootmgr", "--version", NULL })) - { - /* TRANSLATORS: This message is shown when required executable `%s' - isn't found. */ - grub_util_error (_("%s: not found"), "efibootmgr"); - } - - /* On Linux, we need the efivars kernel modules. */ -#ifdef __linux__ - grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL }); -#endif - /* Delete old entries from the same distributor. */ - ret = grub_install_remove_efi_entries_by_distributor (efi_distributor); - if (ret) - return ret; - - char *efidir_part_str = xasprintf ("%d", efidir_part); - - if (!verbosity) - ret = grub_util_exec ((const char * []){ "efibootmgr", "-q", - "-c", "-d", efidir_disk, - "-p", efidir_part_str, "-w", - "-L", efi_distributor, "-l", - efifile_path, NULL }); - else - ret = grub_util_exec ((const char * []){ "efibootmgr", - "-c", "-d", efidir_disk, - "-p", efidir_part_str, "-w", - "-L", efi_distributor, "-l", - efifile_path, NULL }); - free (efidir_part_str); - return ret; -} - -void -grub_install_register_ieee1275 (int is_prep, const char *install_device, - int partno, const char *relpath) -{ - char *boot_device; - - if (grub_util_exec_redirect_null ((const char * []){ "ofpathname", "--version", NULL })) - { - /* TRANSLATORS: This message is shown when required executable `%s' - isn't found. */ - grub_util_error (_("%s: not found"), "ofpathname"); - } - - /* Get the Open Firmware device tree path translation. */ - if (!is_prep) - { - char *ptr; - char *ofpath; - const char *iptr; - - ofpath = get_ofpathname (install_device); - boot_device = xmalloc (strlen (ofpath) + 1 - + sizeof ("XXXXXXXXXXXXXXXXXXXX") - + 1 + strlen (relpath) + 1); - ptr = grub_stpcpy (boot_device, ofpath); - *ptr++ = ':'; - grub_snprintf (ptr, sizeof ("XXXXXXXXXXXXXXXXXXXX"), "%d", - partno); - ptr += strlen (ptr); - *ptr++ = ','; - for (iptr = relpath; *iptr; iptr++, ptr++) - { - if (*iptr == '/') - *ptr = '\\'; - else - *ptr = *iptr; - } - *ptr = '\0'; - } - else - boot_device = get_ofpathname (install_device); - - if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device", - boot_device, NULL })) - { - char *cmd = xasprintf ("setenv boot-device %s", boot_device); - grub_util_error (_("`nvsetenv' failed. \nYou will have to set `boot-device' variable manually. At the IEEE1275 prompt, type:\n %s\n"), - cmd); - free (cmd); - } - - free (boot_device); -} - -void -grub_install_sgi_setup (const char *install_device, - const char *imgfile, const char *destname) -{ - grub_util_exec ((const char * []){ "dvhtool", "-d", - install_device, "--unix-to-vh", - imgfile, destname, NULL }); - grub_util_warn ("%s", _("You will have to set `SystemPartition' and `OSLoader' manually.")); -} diff --git a/grub-core/osdep/unix/relpath.c b/grub-core/osdep/unix/relpath.c deleted file mode 100644 index f8430481e..000000000 --- a/grub-core/osdep/unix/relpath.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* 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, *ret; - uintptr_t offset = 0; - dev_t num; - size_t len; - char *poolfs = NULL; - - /* canonicalize. */ - p = grub_canonicalize_file_name (path); - if (p == NULL) - grub_util_error (_("failed to get canonical path of `%s'"), path); - -#ifdef __linux__ - ret = grub_make_system_path_relative_to_its_root_os (p); - if (ret) - { - free (p); - return ret; - } -#endif - - /* For ZFS sub-pool filesystems. */ -#ifndef __HAIKU__ - { - char *dummy; - grub_find_zpool_from_dir (p, &dummy, &poolfs); - } -#endif - - 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 ("%s", - /* TRANSLATORS: canonical pathname is the - complete one e.g. /etc/fstab. It has - to contain `/' normally, if it doesn't - we're in trouble and throw this error. */ - _("no `/' in canonical filename")); - 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); - if (poolfs) - return xasprintf ("/%s/@", poolfs); - 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); - buf2[offset] = 0; - - free (buf2); - - /* Remove trailing slashes, return empty string if root directory. */ - len = strlen (buf3); - while (len > 0 && buf3[len - 1] == '/') - { - buf3[len - 1] = '\0'; - len--; - } - - if (poolfs) - { - ret = xasprintf ("/%s/@%s", poolfs, buf3); - free (buf3); - } - else - ret = buf3; - - return ret; -} diff --git a/grub-core/osdep/unix/sleep.c b/grub-core/osdep/unix/sleep.c deleted file mode 100644 index 5b00a38cd..000000000 --- a/grub-core/osdep/unix/sleep.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -void -grub_millisleep (grub_uint32_t ms) -{ - struct timespec ts; - - ts.tv_sec = ms / 1000; - ts.tv_nsec = (ms % 1000) * 1000000; - nanosleep (&ts, NULL); -} diff --git a/grub-core/osdep/windows/blocklist.c b/grub-core/osdep/windows/blocklist.c deleted file mode 100644 index 6d0809a48..000000000 --- a/grub-core/osdep/windows/blocklist.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -void -grub_install_get_blocklist (grub_device_t root_dev, - const char *core_path, - const char *core_img __attribute__ ((unused)), - size_t core_size, - void (*callback) (grub_disk_addr_t sector, - unsigned offset, - unsigned length, - void *data), - void *hook_data) -{ - grub_disk_addr_t first_lcn = 0; - HANDLE filehd; - DWORD rets; - RETRIEVAL_POINTERS_BUFFER *extbuf; - size_t extbuf_size; - DWORD i; - grub_uint64_t sec_per_lcn; - grub_uint64_t curvcn = 0; - STARTING_VCN_INPUT_BUFFER start_vcn; - grub_fs_t fs; - grub_err_t err; - - fs = grub_fs_probe (root_dev); - if (!fs) - grub_util_error ("%s", grub_errmsg); - - /* This is ugly but windows doesn't give all needed data. Or does anyone - have a pointer how to retrieve it? - */ - if (grub_strcmp (fs->name, "ntfs") == 0) - { - struct grub_ntfs_bpb bpb; - err = grub_disk_read (root_dev->disk, 0, 0, sizeof (bpb), &bpb); - if (err) - grub_util_error ("%s", grub_errmsg); - sec_per_lcn = ((grub_uint32_t) bpb.sectors_per_cluster - * (grub_uint32_t) grub_le_to_cpu16 (bpb.bytes_per_sector)) - >> 9; - first_lcn = 0; - } - else if (grub_strcmp (fs->name, "exfat") == 0) - first_lcn = grub_exfat_get_cluster_sector (root_dev->disk, &sec_per_lcn); - else if (grub_strcmp (fs->name, "fat") == 0) - first_lcn = grub_fat_get_cluster_sector (root_dev->disk, &sec_per_lcn); - else if (grub_strcmp (fs->name, "udf") == 0) - first_lcn = grub_udf_get_cluster_sector (root_dev->disk, &sec_per_lcn); - else - grub_util_error ("unsupported fs for blocklist on windows: %s", - fs->name); - - grub_util_info ("sec_per_lcn = %" GRUB_HOST_PRIuLONG_LONG - ", first_lcn=%" GRUB_HOST_PRIuLONG_LONG, - (unsigned long long) sec_per_lcn, - (unsigned long long) first_lcn); - - first_lcn += grub_partition_get_start (root_dev->disk->partition); - - start_vcn.StartingVcn.QuadPart = 0; - - filehd = grub_util_fd_open (core_path, GRUB_UTIL_FD_O_RDONLY); - if (!GRUB_UTIL_FD_IS_VALID (filehd)) - grub_util_error (_("cannot open `%s': %s"), core_path, - grub_util_fd_strerror ()); - - extbuf_size = sizeof (*extbuf) + sizeof (extbuf->Extents[0]) - * ((core_size + 511) / 512); - extbuf = xmalloc (extbuf_size); - - if (!DeviceIoControl(filehd, FSCTL_GET_RETRIEVAL_POINTERS, - &start_vcn, sizeof (start_vcn), - extbuf, extbuf_size, &rets, NULL)) - grub_util_error ("FSCTL_GET_RETRIEVAL_POINTERS fails: %s", - grub_util_fd_strerror ()); - - CloseHandle (filehd); - - for (i = 0; i < extbuf->ExtentCount; i++) - callback (extbuf->Extents[i].Lcn.QuadPart - * sec_per_lcn + first_lcn, - 0, 512 * sec_per_lcn * (extbuf->Extents[i].NextVcn.QuadPart - curvcn), hook_data); - free (extbuf); -} diff --git a/grub-core/osdep/windows/config.c b/grub-core/osdep/windows/config.c deleted file mode 100644 index 2bb8a2fd8..000000000 --- a/grub-core/osdep/windows/config.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include - -void -grub_util_load_config (struct grub_util_config *cfg) -{ - const char *cfgfile; - FILE *f = NULL; - const char *v; - - cfgfile = grub_util_get_config_filename (); - if (!grub_util_is_regular (cfgfile)) - return; - - memset (cfg, 0, sizeof (*cfg)); - - v = getenv ("GRUB_ENABLE_CRYPTODISK"); - if (v && v[0] == 'y' && v[1] == '\0') - cfg->is_cryptodisk_enabled = 1; - - v = getenv ("GRUB_DISTRIBUTOR"); - if (v) - cfg->grub_distributor = xstrdup (v); - - f = grub_util_fopen (cfgfile, "r"); - if (f) - { - grub_util_parse_config (f, cfg, 0); - fclose (f); - } - else - grub_util_warn (_("cannot open configuration file `%s': %s"), - cfgfile, strerror (errno)); -} diff --git a/grub-core/osdep/windows/cputime.c b/grub-core/osdep/windows/cputime.c deleted file mode 100644 index 5d06d79dd..000000000 --- a/grub-core/osdep/windows/cputime.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include - -#include -#include - -grub_uint64_t -grub_util_get_cpu_time_ms (void) -{ - FILETIME cr, ex, ke, us; - ULARGE_INTEGER us_ul; - - GetProcessTimes (GetCurrentProcess (), &cr, &ex, &ke, &us); - us_ul.LowPart = us.dwLowDateTime; - us_ul.HighPart = us.dwHighDateTime; - - return us_ul.QuadPart / 10000; -} - diff --git a/grub-core/osdep/windows/dl.c b/grub-core/osdep/windows/dl.c deleted file mode 100644 index 8eab7057e..000000000 --- a/grub-core/osdep/windows/dl.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -void * -grub_osdep_dl_memalign (grub_size_t align, grub_size_t size) -{ - void *ret; - if (align > 4096) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "too large alignment"); - return NULL; - } - - size = ALIGN_UP (size, 4096); - - ret = VirtualAlloc (NULL, size, MEM_COMMIT | MEM_RESERVE, - PAGE_EXECUTE_READWRITE); - - if (!ret) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - return NULL; - } - - return ret; -} - -void -grub_dl_osdep_dl_free (void *ptr) -{ - if (!ptr) - return; - VirtualFree (ptr, 0, MEM_RELEASE); -} diff --git a/grub-core/osdep/windows/emuconsole.c b/grub-core/osdep/windows/emuconsole.c deleted file mode 100644 index 17a44de46..000000000 --- a/grub-core/osdep/windows/emuconsole.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2008,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include - -#include - -#include - -static HANDLE hStdin, hStdout; -static DWORD orig_mode; -static int saved_orig; - - -static void -grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), - const struct grub_unicode_glyph *c) -{ - TCHAR str[2 + 30]; - unsigned i, j; - DWORD written; - - /* For now, do not try to use a surrogate pair. */ - if (c->base > 0xffff) - str[0] = '?'; - else - str[0] = (c->base & 0xffff); - j = 1; - for (i = 0; i < c->ncomb && j+1 < ARRAY_SIZE (str); i++) - if (c->base < 0xffff) - str[j++] = grub_unicode_get_comb (c)[i].code; - str[j] = 0; - - WriteConsole (hStdout, str, j, &written, NULL); -} - -const unsigned windows_codes[] = - { - /* 0x21 */ [VK_PRIOR] = GRUB_TERM_KEY_PPAGE, - /* 0x22 */ [VK_NEXT] = GRUB_TERM_KEY_NPAGE, - /* 0x23 */ [VK_END] = GRUB_TERM_KEY_END, - /* 0x24 */ [VK_HOME] = GRUB_TERM_KEY_HOME, - /* 0x25 */ [VK_LEFT] = GRUB_TERM_KEY_LEFT, - /* 0x26 */ [VK_UP] = GRUB_TERM_KEY_UP, - /* 0x27 */ [VK_RIGHT] = GRUB_TERM_KEY_RIGHT, - /* 0x28 */ [VK_DOWN] = GRUB_TERM_KEY_DOWN, - /* 0x2e */ [VK_DELETE] = GRUB_TERM_KEY_DC, - /* 0x70 */ [VK_F1] = GRUB_TERM_KEY_F1, - /* 0x71 */ [VK_F2] = GRUB_TERM_KEY_F2, - /* 0x72 */ [VK_F3] = GRUB_TERM_KEY_F3, - /* 0x73 */ [VK_F4] = GRUB_TERM_KEY_F4, - /* 0x74 */ [VK_F5] = GRUB_TERM_KEY_F5, - /* 0x75 */ [VK_F6] = GRUB_TERM_KEY_F6, - /* 0x76 */ [VK_F7] = GRUB_TERM_KEY_F7, - /* 0x77 */ [VK_F8] = GRUB_TERM_KEY_F8, - /* 0x78 */ [VK_F9] = GRUB_TERM_KEY_F9, - /* 0x79 */ [VK_F10] = GRUB_TERM_KEY_F10, - /* 0x7a */ [VK_F11] = GRUB_TERM_KEY_F11, - /* 0x7b */ [VK_F12] = GRUB_TERM_KEY_F12, - }; - - -static int -grub_console_getkey (struct grub_term_input *term __attribute__ ((unused))) -{ - while (1) - { - DWORD nev; - INPUT_RECORD ir; - int ret; - - if (!GetNumberOfConsoleInputEvents (hStdin, &nev)) - return GRUB_TERM_NO_KEY; - - if (nev == 0) - return GRUB_TERM_NO_KEY; - - if (!ReadConsoleInput (hStdin, &ir, 1, - &nev)) - return GRUB_TERM_NO_KEY; - - if (ir.EventType != KEY_EVENT) - continue; - - if (!ir.Event.KeyEvent.bKeyDown) - continue; - ret = ir.Event.KeyEvent.uChar.UnicodeChar; - if (ret == 0) - { - unsigned kc = ir.Event.KeyEvent.wVirtualKeyCode; - if (kc < ARRAY_SIZE (windows_codes) && windows_codes[kc]) - ret = windows_codes[kc]; - else - continue; - if (ir.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) - ret |= GRUB_TERM_SHIFT; - } - /* Workaround for AltGr bug. */ - if (ir.Event.KeyEvent.dwControlKeyState & RIGHT_ALT_PRESSED) - return ret; - if (ir.Event.KeyEvent.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) - ret |= GRUB_TERM_ALT; - if (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) - ret |= GRUB_TERM_CTRL; - return ret; - } -} - -static struct grub_term_coordinate -grub_console_getwh (struct grub_term_output *term __attribute__ ((unused))) -{ - CONSOLE_SCREEN_BUFFER_INFO csbi; - - csbi.dwSize.X = 80; - csbi.dwSize.Y = 25; - - GetConsoleScreenBufferInfo (hStdout, &csbi); - - return (struct grub_term_coordinate) { csbi.dwSize.X, csbi.dwSize.Y }; -} - -static struct grub_term_coordinate -grub_console_getxy (struct grub_term_output *term __attribute__ ((unused))) -{ - CONSOLE_SCREEN_BUFFER_INFO csbi; - - GetConsoleScreenBufferInfo (hStdout, &csbi); - - return (struct grub_term_coordinate) { csbi.dwCursorPosition.X, csbi.dwCursorPosition.Y }; -} - -static void -grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)), - struct grub_term_coordinate pos) -{ - COORD coord = { pos.x, pos.y }; - - SetConsoleCursorPosition (hStdout, coord); -} - -static void -grub_console_cls (struct grub_term_output *term) -{ - int tsz; - CONSOLE_SCREEN_BUFFER_INFO csbi; - - struct grub_unicode_glyph c = - { - .base = ' ', - .variant = 0, - .attributes = 0, - .ncomb = 0, - .estimated_width = 1 - }; - - GetConsoleScreenBufferInfo (hStdout, &csbi); - - SetConsoleTextAttribute (hStdout, 0); - grub_console_gotoxy (term, (struct grub_term_coordinate) { 0, 0 }); - tsz = csbi.dwSize.X * csbi.dwSize.Y; - - while (tsz--) - grub_console_putchar (term, &c); - - grub_console_gotoxy (term, (struct grub_term_coordinate) { 0, 0 }); - SetConsoleTextAttribute (hStdout, csbi.wAttributes); -} - -static void -grub_console_setcolorstate (struct grub_term_output *term - __attribute__ ((unused)), - grub_term_color_state state) -{ - - - switch (state) { - case GRUB_TERM_COLOR_STANDARD: - SetConsoleTextAttribute (hStdout, GRUB_TERM_DEFAULT_STANDARD_COLOR - & 0x7f); - break; - case GRUB_TERM_COLOR_NORMAL: - SetConsoleTextAttribute (hStdout, grub_term_normal_color & 0x7f); - break; - case GRUB_TERM_COLOR_HIGHLIGHT: - SetConsoleTextAttribute (hStdout, grub_term_highlight_color & 0x7f); - break; - default: - break; - } -} - -static void -grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)), - int on) -{ - CONSOLE_CURSOR_INFO ci; - ci.dwSize = 5; - ci.bVisible = on; - SetConsoleCursorInfo (hStdout, &ci); -} - -static grub_err_t -grub_efi_console_init (struct grub_term_output *term) -{ - grub_console_setcursor (term, 1); - return 0; -} - -static grub_err_t -grub_efi_console_fini (struct grub_term_output *term) -{ - grub_console_setcursor (term, 1); - return 0; -} - - -static grub_err_t -grub_console_init_input (struct grub_term_input *term) -{ - if (!saved_orig) - { - GetConsoleMode (hStdin, &orig_mode); - } - - saved_orig = 1; - - SetConsoleMode (hStdin, orig_mode & ~ENABLE_ECHO_INPUT - & ~ENABLE_LINE_INPUT & ~ENABLE_PROCESSED_INPUT); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_console_fini_input (struct grub_term_input *term - __attribute__ ((unused))) -{ - SetConsoleMode (hStdin, orig_mode); - saved_orig = 0; - return GRUB_ERR_NONE; -} - - -static struct grub_term_input grub_console_term_input = - { - .name = "console", - .getkey = grub_console_getkey, - .init = grub_console_init_input, - .fini = grub_console_fini_input, - }; - -static struct grub_term_output grub_console_term_output = - { - .name = "console", - .init = grub_efi_console_init, - .fini = grub_efi_console_fini, - .putchar = grub_console_putchar, - .getwh = grub_console_getwh, - .getxy = grub_console_getxy, - .gotoxy = grub_console_gotoxy, - .cls = grub_console_cls, - .setcolorstate = grub_console_setcolorstate, - .setcursor = grub_console_setcursor, - .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS, - .progress_update_divisor = GRUB_PROGRESS_FAST - }; - -void -grub_console_init (void) -{ - hStdin = GetStdHandle (STD_INPUT_HANDLE); - hStdout = GetStdHandle (STD_OUTPUT_HANDLE); - - grub_term_register_input ("console", &grub_console_term_input); - grub_term_register_output ("console", &grub_console_term_output); -} - -void -grub_console_fini (void) -{ - if (saved_orig) - { - SetConsoleMode (hStdin, orig_mode); - saved_orig = 0; - } - grub_term_unregister_input (&grub_console_term_input); - grub_term_unregister_output (&grub_console_term_output); -} diff --git a/grub-core/osdep/windows/getroot.c b/grub-core/osdep/windows/getroot.c deleted file mode 100644 index 73c912664..000000000 --- a/grub-core/osdep/windows/getroot.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LIMITS_H -#include -#endif - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -TCHAR * -grub_get_mount_point (const TCHAR *path) -{ - const TCHAR *ptr; - TCHAR *out; - TCHAR letter = 0; - size_t allocsize; - - for (ptr = path; *ptr; ptr++); - allocsize = (ptr - path + 10) * 2; - out = xcalloc (allocsize, sizeof (out[0])); - - /* When pointing to EFI system partition GetVolumePathName fails - for ESP root and returns abberant information for everything - else. Since GetVolumePathName shouldn't fail for any valid - //?/X: we use it as indicator. */ - if ((path[0] == '/' || path[0] == '\\') - && (path[1] == '/' || path[1] == '\\') - && (path[2] == '?' || path[2] == '.') - && (path[3] == '/' || path[3] == '\\') - && path[4] - && (path[5] == ':')) - letter = path[4]; - if (path[0] && path[1] == ':') - letter = path[0]; - if (letter) - { - TCHAR letterpath[10] = TEXT("\\\\?\\#:"); - letterpath[4] = letter; - if (!GetVolumePathName (letterpath, out, allocsize)) - { - if (path[1] == ':') - { - out[0] = path[0]; - out[1] = ':'; - out[2] = '\0'; - return out; - } - memcpy (out, path, sizeof (out[0]) * 6); - out[6] = '\0'; - return out; - } - } - - if (!GetVolumePathName (path, out, allocsize)) - { - free (out); - return NULL; - } - return out; -} - -char ** -grub_guess_root_devices (const char *dir) -{ - char **os_dev = NULL; - TCHAR *dirwindows, *mntpointwindows; - TCHAR *ptr; - TCHAR volumename[100]; - - dirwindows = grub_util_get_windows_path (dir); - if (!dirwindows) - return 0; - - mntpointwindows = grub_get_mount_point (dirwindows); - - if (!mntpointwindows) - { - free (dirwindows); - grub_util_info ("can't get volume path name: %d", (int) GetLastError ()); - return 0; - } - - if (!mntpointwindows[0]) - { - free (dirwindows); - free (mntpointwindows); - return 0; - } - - for (ptr = mntpointwindows; *ptr; ptr++); - if (*(ptr - 1) != '\\') - { - *ptr = '\\'; - *(ptr + 1) = '\0'; - } - - if (!GetVolumeNameForVolumeMountPoint (mntpointwindows, - volumename, - ARRAY_SIZE (volumename))) - { - TCHAR letter = 0; - if ((mntpointwindows[0] == '/' || mntpointwindows[0] == '\\') - && (mntpointwindows[1] == '/' || mntpointwindows[1] == '\\') - && (mntpointwindows[2] == '?' || mntpointwindows[2] == '.') - && (mntpointwindows[3] == '/' || mntpointwindows[3] == '\\') - && mntpointwindows[4] - && (mntpointwindows[5] == ':')) - letter = mntpointwindows[4]; - if (mntpointwindows[0] && mntpointwindows[1] == ':') - letter = mntpointwindows[0]; - if (!letter) - { - free (dirwindows); - free (mntpointwindows); - return 0; - } - volumename[0] = '\\'; - volumename[1] = '\\'; - volumename[2] = '?'; - volumename[3] = '\\'; - volumename[4] = letter; - volumename[5] = ':'; - volumename[6] = '\0'; - } - os_dev = xmalloc (2 * sizeof (os_dev[0])); - - for (ptr = volumename; *ptr; ptr++); - while (ptr > volumename && *(ptr - 1) == '\\') - *--ptr = '\0'; - - os_dev[0] = grub_util_tchar_to_utf8 (volumename); - free (dirwindows); - free (mntpointwindows); - - if (!os_dev[0]) - { - free (os_dev); - return 0; - } - - os_dev[1] = 0; - - return os_dev; -} - -static int tcharncasecmp (LPCTSTR a, const char *b, size_t sz) -{ - for (; sz; sz--, a++, b++) - { - char ac, bc; - if(*a >= 0x80) - return +1; - if (*b & 0x80) - return -1; - if (*a == '\0' && *b == '\0') - return 0; - ac = *a; - bc = *b; - if (ac >= 'A' && ac <= 'Z') - ac -= 'A' - 'a'; - if (bc >= 'A' && bc <= 'Z') - bc -= 'A' - 'a'; - if (ac > bc) - return +1; - if (ac < bc) - return -1; - } - return 0; -} - -char * -grub_util_part_to_disk (const char *os_dev, - struct stat *st __attribute__ ((unused)), - int *is_part) -{ - HANDLE hd; - LPTSTR name = grub_util_get_windows_path (os_dev); - VOLUME_DISK_EXTENTS exts; - DWORD extsbytes; - char *ret; - - if (((name[0] == '/') || (name[0] == '\\')) && - ((name[1] == '/') || (name[1] == '\\')) && - ((name[2] == '.') || (name[2] == '?')) && - ((name[3] == '/') || (name[3] == '\\')) - && (tcharncasecmp (name + 4, "PhysicalDrive", sizeof ("PhysicalDrive") - 1) == 0 - || tcharncasecmp (name + 4, "Harddisk", sizeof ("Harddisk") - 1) == 0 - || ((name[4] == 'A' || name[4] == 'a' || name[4] == 'B' || name[4] == 'b') - && name[5] == ':' && name[6] == '\0'))) - { - grub_util_info ("Matches full disk pattern"); - ret = grub_util_tchar_to_utf8 (name); - free (name); - return ret; - } - - hd = CreateFile (name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, OPEN_EXISTING, 0, 0); - if (hd == INVALID_HANDLE_VALUE) - { - grub_util_info ("CreateFile failed"); - ret = grub_util_tchar_to_utf8 (name); - free (name); - return ret; - } - - if (!DeviceIoControl(hd, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, - NULL, 0, &exts, sizeof (exts), &extsbytes, NULL)) - { - grub_util_info ("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed"); - ret = grub_util_tchar_to_utf8 (name); - CloseHandle (hd); - free (name); - return ret; - } - - CloseHandle (hd); - - *is_part = 1; - free (name); - return xasprintf ("\\\\?\\PhysicalDrive%lu", (unsigned long) exts.Extents[0].DiskNumber); -} - -enum grub_dev_abstraction_types -grub_util_get_dev_abstraction_os (const char *os_dev __attribute__((unused))) -{ - return GRUB_DEV_ABSTRACTION_NONE; -} - -int -grub_util_pull_device_os (const char *os_dev __attribute__ ((unused)), - enum grub_dev_abstraction_types ab __attribute__ ((unused))) -{ - return 0; -} - -char * -grub_util_get_grub_dev_os (const char *os_dev __attribute__ ((unused))) -{ - return NULL; -} - - -grub_disk_addr_t -grub_util_find_partition_start_os (const char *os_dev) -{ - HANDLE hd; - LPTSTR name = grub_util_get_windows_path (os_dev); - VOLUME_DISK_EXTENTS exts; - DWORD extsbytes; - char *ret; - - if (((name[0] == '/') || (name[0] == '\\')) && - ((name[1] == '/') || (name[1] == '\\')) && - ((name[2] == '.') || (name[2] == '?')) && - ((name[3] == '/') || (name[3] == '\\')) - && (tcharncasecmp (name + 4, "PhysicalDrive", sizeof ("PhysicalDrive") - 1) == 0 - || tcharncasecmp (name + 4, "Harddisk", sizeof ("Harddisk") - 1) == 0 - || ((name[4] == 'A' || name[4] == 'a' || name[4] == 'B' || name[4] == 'b') - && name[5] == ':' && name[6] == '\0'))) - { - ret = grub_util_tchar_to_utf8 (name); - free (name); - return 0; - } - - hd = CreateFile (name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, OPEN_EXISTING, 0, 0); - if (hd == INVALID_HANDLE_VALUE) - { - ret = grub_util_tchar_to_utf8 (name); - free (name); - return 0; - } - - if (!DeviceIoControl(hd, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, - NULL, 0, &exts, sizeof (exts), &extsbytes, NULL)) - { - ret = grub_util_tchar_to_utf8 (name); - CloseHandle (hd); - free (name); - return 0; - } - - CloseHandle (hd); - free (name); - return exts.Extents[0].StartingOffset.QuadPart / 512; -} - -int -grub_util_biosdisk_is_floppy (grub_disk_t disk) -{ - int ret; - const char *dname; - LPTSTR name; - - dname = grub_util_biosdisk_get_osdev (disk); - - if (!dname) - return 0; - - name = grub_util_get_windows_path (dname); - - ret = (((name[0] == '/') || (name[0] == '\\')) && - ((name[1] == '/') || (name[1] == '\\')) && - ((name[2] == '.') || (name[2] == '?')) && - ((name[3] == '/') || (name[3] == '\\')) - && (name[4] == 'A' || name[4] == 'a' || name[4] == 'B' || name[4] == 'b') - && name[5] == ':' && name[6] == '\0'); - free (name); - - return ret; -} diff --git a/grub-core/osdep/windows/hostdisk.c b/grub-core/osdep/windows/hostdisk.c deleted file mode 100644 index aaa6e2f8e..000000000 --- a/grub-core/osdep/windows/hostdisk.c +++ /dev/null @@ -1,687 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#ifdef __CYGWIN__ -#include -#endif - -#if SIZEOF_TCHAR == 1 - -LPTSTR -grub_util_utf8_to_tchar (const char *in) -{ - return xstrdup (in); -} - -char * -grub_util_tchar_to_utf8 (LPCTSTR in) -{ - return xstrdup (in); -} - -#elif SIZEOF_TCHAR == 2 - -LPTSTR -grub_util_utf8_to_tchar (const char *in) -{ - LPTSTR ret; - size_t ssz = strlen (in); - size_t tsz = 2 * (GRUB_MAX_UTF16_PER_UTF8 * ssz + 1); - ret = xmalloc (tsz); - tsz = grub_utf8_to_utf16 (ret, tsz, - (const grub_uint8_t *) in, ssz, NULL); - ret[tsz] = 0; - return ret; -} - -char * -grub_util_tchar_to_utf8 (LPCTSTR in) -{ - size_t ssz; - for (ssz = 0; in[ssz]; ssz++); - - size_t tsz = GRUB_MAX_UTF8_PER_UTF16 * ssz + 1; - grub_uint8_t *ret = xmalloc (tsz); - *grub_utf16_to_utf8 (ret, in, ssz) = '\0'; - return (char *) ret; -} - -#else -#error "Unsupported TCHAR size" -#endif - - -static LPTSTR -grub_util_get_windows_path_real (const char *path) -{ - LPTSTR fpa; - LPTSTR tpath; - size_t alloc, len; - - tpath = grub_util_utf8_to_tchar (path); - - alloc = PATH_MAX; - - while (1) - { - fpa = xcalloc (alloc, sizeof (fpa[0])); - - len = GetFullPathName (tpath, alloc, fpa, NULL); - if (len >= alloc) - { - free (fpa); - alloc = 2 * (len + 2); - continue; - } - if (len == 0) - { - free (fpa); - return tpath; - } - - free (tpath); - return fpa; - } -} - -#ifdef __CYGWIN__ -LPTSTR -grub_util_get_windows_path (const char *path) -{ - LPTSTR winpath; - /* Workaround cygwin bugs with //?/. */ - if ((path[0] == '\\' || path[0] == '/') - && (path[1] == '\\' || path[1] == '/') - && (path[2] == '?' || path[2] == '.') - && (path[3] == '\\' || path[3] == '/')) - return grub_util_get_windows_path_real (path); - - winpath = xmalloc (sizeof (winpath[0]) * PATH_MAX); - memset (winpath, 0, sizeof (winpath[0]) * PATH_MAX); - if (cygwin_conv_path ((sizeof (winpath[0]) == 1 ? CCP_POSIX_TO_WIN_A - : CCP_POSIX_TO_WIN_W) | CCP_ABSOLUTE, path, winpath, - sizeof (winpath[0]) * PATH_MAX)) - grub_util_error ("%s", _("cygwin_conv_path() failed")); - return winpath; -} -#else -LPTSTR -grub_util_get_windows_path (const char *path) -{ - return grub_util_get_windows_path_real (path); -} -#endif - -grub_uint64_t -grub_util_get_fd_size (grub_util_fd_t hd, const char *name_in, - unsigned *log_secsize) -{ - grub_int64_t size = -1LL; - int log_sector_size = 9; - LPTSTR name = grub_util_get_windows_path (name_in); - - if (log_secsize) - *log_secsize = log_sector_size; - - if (((name[0] == '/') || (name[0] == '\\')) && - ((name[1] == '/') || (name[1] == '\\')) && - ((name[2] == '.') || (name[2] == '?')) && - ((name[3] == '/') || (name[3] == '\\'))) - { - DWORD nr; - DISK_GEOMETRY g; - - if (! DeviceIoControl (hd, IOCTL_DISK_GET_DRIVE_GEOMETRY, - 0, 0, &g, sizeof (g), &nr, 0)) - goto fail; - - size = g.Cylinders.QuadPart; - size *= g.TracksPerCylinder * g.SectorsPerTrack * g.BytesPerSector; - - log_sector_size = grub_log2ull (g.BytesPerSector); - } - else - { - ULARGE_INTEGER s; - - s.LowPart = GetFileSize (hd, &s.HighPart); - size = s.QuadPart; - } - - fail: - - if (log_secsize) - *log_secsize = log_sector_size; - - free (name); - - return size; -} - -void -grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused))) -{ -} - -int -grub_util_fd_seek (grub_util_fd_t fd, grub_uint64_t off) -{ - LARGE_INTEGER offset; - offset.QuadPart = off; - - if (!SetFilePointerEx (fd, offset, NULL, FILE_BEGIN)) - return -1; - return 0; -} - -grub_util_fd_t -grub_util_fd_open (const char *os_dev, int flags) -{ - DWORD flg = 0, crt; - LPTSTR dev = grub_util_get_windows_path (os_dev); - grub_util_fd_t ret; - - if (flags & GRUB_UTIL_FD_O_WRONLY) - flg |= GENERIC_WRITE; - if (flags & GRUB_UTIL_FD_O_RDONLY) - flg |= GENERIC_READ; - - if (flags & GRUB_UTIL_FD_O_CREATTRUNC) - crt = CREATE_ALWAYS; - else - crt = OPEN_EXISTING; - - ret = CreateFile (dev, flg, FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, crt, 0, 0); - free (dev); - return ret; -} - -ssize_t -grub_util_fd_read (grub_util_fd_t fd, char *buf, size_t len) -{ - DWORD real_read; - if (!ReadFile(fd, buf, len, &real_read, NULL)) - { - grub_util_info ("read err %x", (int) GetLastError ()); - return -1; - } - grub_util_info ("successful read"); - return real_read; -} - -ssize_t -grub_util_fd_write (grub_util_fd_t fd, const char *buf, size_t len) -{ - DWORD real_read; - if (!WriteFile(fd, buf, len, &real_read, NULL)) - { - grub_util_info ("write err %x", (int) GetLastError ()); - return -1; - } - - grub_util_info ("successful write"); - return real_read; -} - -static int allow_fd_syncs = 1; - -int -grub_util_fd_sync (grub_util_fd_t fd) -{ - if (allow_fd_syncs) - { - if (!FlushFileBuffers (fd)) - { - grub_util_info ("flush err %x", (int) GetLastError ()); - return -1; - } - } - return 0; -} - -void -grub_util_disable_fd_syncs (void) -{ - allow_fd_syncs = 0; -} - -int -grub_util_fd_close (grub_util_fd_t fd) -{ - if (!CloseHandle (fd)) - { - grub_util_info ("close err %x", (int) GetLastError ()); - return -1; - } - return 0; -} - -const char * -grub_util_fd_strerror (void) -{ - DWORD err = GetLastError (); - LPTSTR tstr = NULL; - static char *last; - char *ret, *ptr; - - free (last); - last = 0; - - FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, 0, (void *) &tstr, - 0, NULL); - - if (!tstr) - return "unknown error"; - - ret = grub_util_tchar_to_utf8 (tstr); - - LocalFree (tstr); - - last = ret; - - for (ptr = ret + strlen (ret) - 1; - ptr >= ret && (*ptr == '\n' || *ptr == '\r'); - ptr--); - ptr[1] = '\0'; - - return ret; -} - -char * -grub_canonicalize_file_name (const char *path) -{ - char *ret; - LPTSTR windows_path; - ret = xmalloc (PATH_MAX); - - windows_path = grub_util_get_windows_path (path); - if (!windows_path) - return NULL; - ret = grub_util_tchar_to_utf8 (windows_path); - free (windows_path); - - return ret; -} - -void -grub_util_mkdir (const char *dir) -{ - LPTSTR windows_name; - - windows_name = grub_util_get_windows_path (dir); - CreateDirectory (windows_name, NULL); - free (windows_name); -} - -int -grub_util_rename (const char *from, const char *to) -{ - LPTSTR windows_from, windows_to; - int ret; - - windows_from = grub_util_get_windows_path (from); - windows_to = grub_util_get_windows_path (to); - ret = !MoveFile (windows_from, windows_to); - free (windows_from); - free (windows_to); - return ret; -} - -struct grub_util_fd_dir -{ - WIN32_FIND_DATA fd; - HANDLE hnd; - int is_end; - char *last; -}; - -grub_util_fd_dir_t -grub_util_fd_opendir (const char *name) -{ - struct grub_util_fd_dir *ret; - LPTSTR name_windows; - LPTSTR pattern; - ssize_t l; - - name_windows = grub_util_get_windows_path (name); - for (l = 0; name_windows[l]; l++); - for (l--; l >= 0 && (name_windows[l] == '\\' || name_windows[l] == '/'); l--); - l++; - pattern = xcalloc (l + 3, sizeof (pattern[0])); - memcpy (pattern, name_windows, l * sizeof (pattern[0])); - pattern[l] = '\\'; - pattern[l + 1] = '*'; - pattern[l + 2] = '\0'; - - ret = xmalloc (sizeof (*ret)); - memset (ret, 0, sizeof (*ret)); - - ret->hnd = FindFirstFile (pattern, &ret->fd); - - free (name_windows); - free (pattern); - - if (ret->hnd == INVALID_HANDLE_VALUE) - { - DWORD err = GetLastError (); - if (err == ERROR_FILE_NOT_FOUND) - { - ret->is_end = 1; - return ret; - } - return NULL; - } - return ret; -} - -void -grub_util_fd_closedir (grub_util_fd_dir_t dirp) -{ - if (dirp->hnd != INVALID_HANDLE_VALUE) - CloseHandle (dirp->hnd); - free (dirp->last); - free (dirp); -} - -grub_util_fd_dirent_t -grub_util_fd_readdir (grub_util_fd_dir_t dirp) -{ - char *ret; - free (dirp->last); - dirp->last = NULL; - - if (dirp->is_end) - return NULL; - - ret = grub_util_tchar_to_utf8 (dirp->fd.cFileName); - dirp->last = ret; - - if (!FindNextFile (dirp->hnd, &dirp->fd)) - dirp->is_end = 1; - return (grub_util_fd_dirent_t) ret; -} - -int -grub_util_unlink (const char *name) -{ - LPTSTR name_windows; - int ret; - - name_windows = grub_util_get_windows_path (name); - - ret = !DeleteFile (name_windows); - free (name_windows); - return ret; -} - -int -grub_util_rmdir (const char *name) -{ - LPTSTR name_windows; - int ret; - - name_windows = grub_util_get_windows_path (name); - - ret = !RemoveDirectory (name_windows); - free (name_windows); - return ret; -} - -#ifndef __CYGWIN__ - -static char * -get_temp_name (void) -{ - TCHAR rt[1024]; - TCHAR *ptr; - HCRYPTPROV hCryptProv; - grub_uint8_t rnd[5]; - int i; - - GetTempPath (ARRAY_SIZE (rt) - 100, rt); - - if (!CryptAcquireContext (&hCryptProv, - NULL, - MS_DEF_PROV, - PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT) - || !CryptGenRandom (hCryptProv, 5, rnd)) - grub_util_error ("%s", _("couldn't retrieve random data")); - - CryptReleaseContext (hCryptProv, 0); - - for (ptr = rt; *ptr; ptr++); - memcpy (ptr, TEXT("\\GRUB."), sizeof (TEXT("\\GRUB."))); - ptr += sizeof ("\\GRUB.") - 1; - - for (i = 0; i < 8; i++) - { - grub_size_t b = i * 5; - grub_uint8_t r; - grub_size_t f1 = GRUB_CHAR_BIT - b % GRUB_CHAR_BIT; - grub_size_t f2; - if (f1 > 5) - f1 = 5; - f2 = 5 - f1; - r = (rnd[b / GRUB_CHAR_BIT] >> (b % GRUB_CHAR_BIT)) & ((1 << f1) - 1); - if (f2) - r |= (rnd[b / GRUB_CHAR_BIT + 1] & ((1 << f2) - 1)) << f1; - if (r < 10) - *ptr++ = '0' + r; - else - *ptr++ = 'a' + (r - 10); - } - *ptr = '\0'; - - return grub_util_tchar_to_utf8 (rt); -} - -char * -grub_util_make_temporary_file (void) -{ - char *ret = get_temp_name (); - FILE *f; - - f = grub_util_fopen (ret, "wb"); - if (f) - fclose (f); - return ret; -} - -char * -grub_util_make_temporary_dir (void) -{ - char *ret = get_temp_name (); - - grub_util_mkdir (ret); - - return ret; -} - -#endif - -int -grub_util_is_directory (const char *name) -{ - LPTSTR name_windows; - DWORD attr; - - name_windows = grub_util_get_windows_path (name); - if (!name_windows) - return 0; - - attr = GetFileAttributes (name_windows); - grub_free (name_windows); - - return !!(attr & FILE_ATTRIBUTE_DIRECTORY); -} - -int -grub_util_is_regular (const char *name) -{ - LPTSTR name_windows; - DWORD attr; - - name_windows = grub_util_get_windows_path (name); - if (!name_windows) - return 0; - - attr = GetFileAttributes (name_windows); - grub_free (name_windows); - - return !(attr & FILE_ATTRIBUTE_DIRECTORY) - && !(attr & FILE_ATTRIBUTE_REPARSE_POINT) && attr; -} - -grub_uint32_t -grub_util_get_mtime (const char *path) -{ - LPTSTR name_windows; - BOOL b; - WIN32_FILE_ATTRIBUTE_DATA attr; - ULARGE_INTEGER us_ul; - - name_windows = grub_util_get_windows_path (path); - if (!name_windows) - return 0; - - b = GetFileAttributesEx (name_windows, GetFileExInfoStandard, &attr); - grub_free (name_windows); - - if (!b) - return 0; - - us_ul.LowPart = attr.ftLastWriteTime.dwLowDateTime; - us_ul.HighPart = attr.ftLastWriteTime.dwHighDateTime; - - return (us_ul.QuadPart / 10000000) - - 86400ULL * 365 * (1970 - 1601) - - 86400ULL * ((1970 - 1601) / 4) + 86400ULL * ((1970 - 1601) / 100); -} - - -#ifdef __MINGW32__ - -FILE * -grub_util_fopen (const char *path, const char *mode) -{ - LPTSTR tpath; - FILE *ret; - tpath = grub_util_get_windows_path (path); -#if SIZEOF_TCHAR == 1 - ret = fopen (tpath, tmode); -#else - LPTSTR tmode; - tmode = grub_util_utf8_to_tchar (mode); - ret = _wfopen (tpath, tmode); - free (tmode); -#endif - free (tpath); - return ret; -} - -int -grub_util_file_sync (FILE *f) -{ - HANDLE hnd; - - if (fflush (f) != 0) - { - grub_util_info ("fflush err %x", (int) GetLastError ()); - return -1; - } - if (!allow_fd_syncs) - return 0; - hnd = (HANDLE) _get_osfhandle (fileno (f)); - if (!FlushFileBuffers (hnd)) - { - grub_util_info ("flush err %x", (int) GetLastError ()); - return -1; - } - return 0; -} - -int -grub_util_is_special_file (const char *name) -{ - LPTSTR name_windows; - DWORD attr; - - name_windows = grub_util_get_windows_path (name); - if (!name_windows) - return 1; - - attr = GetFileAttributes (name_windows); - grub_free (name_windows); - - return !!(attr & FILE_ATTRIBUTE_REPARSE_POINT) || !attr; -} - -#else - -void -grub_util_file_sync (FILE *f) -{ - fflush (f); - if (!allow_fd_syncs) - return; - fsync (fileno (f)); -} - -FILE * -grub_util_fopen (const char *path, const char *mode) -{ - return fopen (path, mode); -} - -#endif diff --git a/grub-core/osdep/windows/init.c b/grub-core/osdep/windows/init.c deleted file mode 100644 index b67c73c59..000000000 --- a/grub-core/osdep/windows/init.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "progname.h" - -struct grub_windows_console_font_infoex { - ULONG cbSize; - DWORD nFont; - COORD dwFontSize; - UINT FontFamily; - UINT FontWeight; - WCHAR FaceName[LF_FACESIZE]; -}; - -static int -check_is_raster (HMODULE kernel32, HANDLE hnd) -{ - CONSOLE_FONT_INFO console_font_info; - BOOL (WINAPI * func_GetCurrentConsoleFont) (HANDLE, BOOL, - PCONSOLE_FONT_INFO); - - func_GetCurrentConsoleFont = (void *) - GetProcAddress (kernel32, "GetCurrentConsoleFont"); - - if (!func_GetCurrentConsoleFont) - return 1; - - if (!func_GetCurrentConsoleFont (hnd, FALSE, &console_font_info)) - return 1; - return console_font_info.nFont < 12; -} - -static void -set_console_unicode_font (void) -{ - BOOL (WINAPI * func_SetCurrentConsoleFontEx) (HANDLE, BOOL, - struct grub_windows_console_font_infoex *); - BOOL (WINAPI * func_SetConsoleFont)(HANDLE, DWORD); - HMODULE kernel32; - HANDLE out_handle = GetStdHandle (STD_OUTPUT_HANDLE); - HANDLE err_handle = GetStdHandle (STD_ERROR_HANDLE); - int out_raster, err_raster; - - kernel32 = GetModuleHandle(TEXT("kernel32.dll")); - if (!kernel32) - return; - - out_raster = check_is_raster (kernel32, out_handle); - err_raster = check_is_raster (kernel32, err_handle); - - if (!out_raster && !err_raster) - return; - - func_SetCurrentConsoleFontEx = (void *) GetProcAddress (kernel32, "SetCurrentConsoleFontEx"); - - /* Newer windows versions. */ - if (func_SetCurrentConsoleFontEx) - { - struct grub_windows_console_font_infoex new_console_font_info; - new_console_font_info.cbSize = sizeof (new_console_font_info); - new_console_font_info.nFont = 12; - new_console_font_info.dwFontSize.X = 7; - new_console_font_info.dwFontSize.Y = 12; - new_console_font_info.FontFamily = FF_DONTCARE; - new_console_font_info.FontWeight = 400; - memcpy (new_console_font_info.FaceName, TEXT("Lucida Console"), - sizeof (TEXT("Lucida Console"))); - if (out_raster) - func_SetCurrentConsoleFontEx (out_handle, FALSE, - &new_console_font_info); - if (err_raster) - func_SetCurrentConsoleFontEx (err_handle, FALSE, - &new_console_font_info); - return; - } - - /* Fallback for older versions. */ - func_SetConsoleFont = (void *) GetProcAddress (kernel32, "SetConsoleFont"); - if (func_SetConsoleFont) - { - if (out_raster) - func_SetConsoleFont (out_handle, 12); - if (err_raster) - func_SetConsoleFont (err_handle, 12); - } -} - -static char *grub_util_base_directory; -static char *locale_dir; - -const char * -grub_util_get_config_filename (void) -{ - static char *value = NULL; - if (!value) - value = grub_util_path_concat (2, grub_util_base_directory, "grub.cfg"); - return value; -} - -const char * -grub_util_get_pkgdatadir (void) -{ - return grub_util_base_directory; -} - -const char * -grub_util_get_localedir (void) -{ - return locale_dir; -} - -const char * -grub_util_get_pkglibdir (void) -{ - return grub_util_base_directory; -} - -void -grub_util_host_init (int *argc __attribute__ ((unused)), - char ***argv) -{ - char *ptr; - - SetConsoleOutputCP (CP_UTF8); - SetConsoleCP (CP_UTF8); - - set_console_unicode_font (); - -#if SIZEOF_TCHAR == 1 - -#elif SIZEOF_TCHAR == 2 - LPWSTR tcmdline = GetCommandLineW (); - int i; - LPWSTR *targv; - - targv = CommandLineToArgvW (tcmdline, argc); - *argv = xcalloc (*argc + 1, sizeof (argv[0])); - - for (i = 0; i < *argc; i++) - (*argv)[i] = grub_util_tchar_to_utf8 (targv[i]); - (*argv)[i] = NULL; -#else -#error "Unsupported TCHAR size" -#endif - - grub_util_base_directory = grub_canonicalize_file_name ((*argv)[0]); - if (!grub_util_base_directory) - grub_util_base_directory = xstrdup ((*argv)[0]); - for (ptr = grub_util_base_directory + strlen (grub_util_base_directory) - 1; - ptr >= grub_util_base_directory && *ptr != '/' && *ptr != '\\'; ptr--); - if (ptr >= grub_util_base_directory) - *ptr = '\0'; - - locale_dir = grub_util_path_concat (2, grub_util_base_directory, "locale"); - - set_program_name ((*argv)[0]); - -#if (defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, locale_dir); - textdomain (PACKAGE); -#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ -} diff --git a/grub-core/osdep/windows/password.c b/grub-core/osdep/windows/password.c deleted file mode 100644 index a98c7f9ad..000000000 --- a/grub-core/osdep/windows/password.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 - * 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -#include -#include -#include -#include - -int -grub_password_get (char buf[], unsigned buf_size) -{ - HANDLE hStdin = GetStdHandle (STD_INPUT_HANDLE); - DWORD mode = 0; - char *ptr; - - grub_refresh (); - - GetConsoleMode (hStdin, &mode); - SetConsoleMode (hStdin, mode & (~ENABLE_ECHO_INPUT)); - - fgets (buf, buf_size, stdin); - ptr = buf + strlen (buf) - 1; - while (buf <= ptr && (*ptr == '\n' || *ptr == '\r')) - *ptr-- = 0; - - SetConsoleMode (hStdin, mode); - - grub_refresh (); - - return 1; -} diff --git a/grub-core/osdep/windows/platform.c b/grub-core/osdep/windows/platform.c deleted file mode 100644 index af04c1a1e..000000000 --- a/grub-core/osdep/windows/platform.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include - -#define GRUB_EFI_GLOBAL_VARIABLE_GUID_WINDOWS_STR L"{8be4df61-93ca-11d2-aa0d-00e098032b8c}" - -static enum { PLAT_UNK, PLAT_BIOS, PLAT_EFI } platform; -static DWORD (WINAPI * func_GetFirmwareEnvironmentVariableW) (LPCWSTR lpName, - LPCWSTR lpGuid, - PVOID pBuffer, - DWORD nSize); -static BOOL (WINAPI * func_SetFirmwareEnvironmentVariableW) (LPCWSTR lpName, - LPCWSTR lpGuid, - PVOID pBuffer, - DWORD nSize); -static void (WINAPI * func_GetNativeSystemInfo) (LPSYSTEM_INFO lpSystemInfo); - -static int -get_efi_privilegies (void) -{ - int ret = 1; - HANDLE hSelf; - TOKEN_PRIVILEGES tkp; - - if (!OpenProcessToken (GetCurrentProcess(), - TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hSelf)) - return 0; - - LookupPrivilegeValue (NULL, SE_SYSTEM_ENVIRONMENT_NAME, - &tkp.Privileges[0].Luid); - tkp.PrivilegeCount = 1; - tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - if (!AdjustTokenPrivileges (hSelf, FALSE, &tkp, 0, NULL, 0)) - ret = 0; - if (GetLastError () != ERROR_SUCCESS) - ret = 0; - CloseHandle (hSelf); - return 1; -} - -static void -get_platform (void) -{ - HMODULE kernel32; - char buffer[256]; - - if (platform != PLAT_UNK) - return; - - kernel32 = GetModuleHandle(TEXT("kernel32.dll")); - if (!kernel32) - { - platform = PLAT_BIOS; - return; - } - - func_GetFirmwareEnvironmentVariableW = (void *) - GetProcAddress (kernel32, "GetFirmwareEnvironmentVariableW"); - func_SetFirmwareEnvironmentVariableW = (void *) - GetProcAddress (kernel32, "SetFirmwareEnvironmentVariableW"); - func_GetNativeSystemInfo = (void *) - GetProcAddress (kernel32, "GetNativeSystemInfo"); - if (!func_GetNativeSystemInfo) - func_GetNativeSystemInfo = GetSystemInfo; - if (!func_GetFirmwareEnvironmentVariableW - || !func_SetFirmwareEnvironmentVariableW) - { - platform = PLAT_BIOS; - return; - } - - if (!get_efi_privilegies ()) - { - grub_util_warn (_("Insufficient privileges to access firmware, assuming BIOS")); - platform = PLAT_BIOS; - } - - if (!func_GetFirmwareEnvironmentVariableW (L"BootOrder", GRUB_EFI_GLOBAL_VARIABLE_GUID_WINDOWS_STR, - buffer, sizeof (buffer)) - && GetLastError () == ERROR_INVALID_FUNCTION) - { - platform = PLAT_BIOS; - return; - } - platform = PLAT_EFI; - return; -} - -const char * -grub_install_get_default_x86_platform (void) -{ - SYSTEM_INFO si; - - get_platform (); - if (platform != PLAT_EFI) - return "i386-pc"; - - /* EFI */ - /* Assume 64-bit in case of failure. */ - si.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64; - func_GetNativeSystemInfo (&si); - if (si.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_INTEL) - return "x86_64-efi"; - else - return "i386-efi"; -} - -static void * -get_efi_variable (const wchar_t *varname, ssize_t *len) -{ - void *ret = NULL; - size_t alloc_size = 256, read_size; - get_platform (); - while (1) - { - DWORD err; - ret = xmalloc (alloc_size); - read_size = func_GetFirmwareEnvironmentVariableW (varname, GRUB_EFI_GLOBAL_VARIABLE_GUID_WINDOWS_STR, - ret, alloc_size); - err = GetLastError (); - if (read_size) - { - *len = read_size; - return ret; - } - if (err == ERROR_INSUFFICIENT_BUFFER - && alloc_size * 2 != 0) - { - alloc_size *= 2; - free (ret); - continue; - } - if (err == ERROR_ENVVAR_NOT_FOUND) - { - *len = -1; - return NULL; - } - *len = -2; - return NULL; - } -} - -static void -set_efi_variable (const wchar_t *varname, void *in, grub_size_t len) -{ - get_platform (); - func_SetFirmwareEnvironmentVariableW (varname, GRUB_EFI_GLOBAL_VARIABLE_GUID_WINDOWS_STR, - in, len); -} - -static char -bin2hex (int v) -{ - if (v < 10) - return '0' + v; - return 'A' + v - 10; -} - -static void * -get_efi_variable_bootn (grub_uint16_t n, ssize_t *len) -{ - wchar_t varname[20] = L"Boot0000"; - varname[7] = bin2hex (n & 0xf); - varname[6] = bin2hex ((n >> 4) & 0xf); - varname[5] = bin2hex ((n >> 8) & 0xf); - varname[4] = bin2hex ((n >> 12) & 0xf); - return get_efi_variable (varname, len); -} - -static void -set_efi_variable_bootn (grub_uint16_t n, void *in, grub_size_t len) -{ - wchar_t varname[20] = L"Boot0000"; - varname[7] = bin2hex (n & 0xf); - varname[6] = bin2hex ((n >> 4) & 0xf); - varname[5] = bin2hex ((n >> 8) & 0xf); - varname[4] = bin2hex ((n >> 12) & 0xf); - set_efi_variable (varname, in, len); -} - -int -grub_install_register_efi (grub_device_t efidir_grub_dev, - const char *efifile_path, - const char *efi_distributor) -{ - grub_uint16_t *boot_order, *new_boot_order; - grub_uint16_t *distributor16; - grub_uint8_t *entry; - grub_size_t distrib8_len, distrib16_len, path16_len, path8_len; - ssize_t boot_order_len, new_boot_order_len; - grub_uint16_t order_num = 0; - int have_order_num = 0; - grub_size_t max_path_length; - grub_uint8_t *path; - void *pathptr; - struct grub_efi_hard_drive_device_path *hddp; - struct grub_efi_file_path_device_path *filep; - struct grub_efi_device_path *endp; - - get_platform (); - if (platform != PLAT_EFI) - grub_util_error ("%s", _("no EFI routines are available when running in BIOS mode")); - - distrib8_len = grub_strlen (efi_distributor); - distributor16 = xcalloc (distrib8_len + 1, - GRUB_MAX_UTF16_PER_UTF8 * sizeof (grub_uint16_t)); - distrib16_len = grub_utf8_to_utf16 (distributor16, distrib8_len * GRUB_MAX_UTF16_PER_UTF8, - (const grub_uint8_t *) efi_distributor, - distrib8_len, 0); - distributor16[distrib16_len] = 0; - - /* Windows doesn't allow to list variables so first look for bootorder to - find if there is an entry from the same distributor. If not try sequentially - until we find same distributor or empty spot. */ - boot_order = get_efi_variable (L"BootOrder", &boot_order_len); - if (boot_order_len < -1) - grub_util_error ("%s", _("unexpected EFI error")); - if (boot_order_len > 0) - { - size_t i; - for (i = 0; i < boot_order_len / 2; i++) - { - void *current = NULL; - ssize_t current_len; - current = get_efi_variable_bootn (i, ¤t_len); - if (current_len < 0) - continue; /* FIXME Should we abort on error? */ - if (current_len < (distrib16_len + 1) * sizeof (grub_uint16_t) - + 6) - { - grub_free (current); - continue; - } - if (grub_memcmp ((grub_uint16_t *) current + 3, - distributor16, - (distrib16_len + 1) * sizeof (grub_uint16_t)) != 0) - { - grub_free (current); - continue; - } - order_num = i; - have_order_num = 1; - grub_util_info ("Found matching distributor at Boot%04x", - order_num); - grub_free (current); - break; - } - } - if (!have_order_num) - { - size_t i; - for (i = 0; i < 0x10000; i++) - { - void *current = NULL; - ssize_t current_len; - current = get_efi_variable_bootn (i, ¤t_len); - if (current_len < -1) - continue; /* FIXME Should we abort on error? */ - if (current_len == -1) - { - if (!have_order_num) - { - order_num = i; - have_order_num = 1; - grub_util_info ("Creating new entry at Boot%04x", - order_num); - } - continue; - } - if (current_len < (distrib16_len + 1) * sizeof (grub_uint16_t) - + 6) - { - grub_free (current); - continue; - } - if (grub_memcmp ((grub_uint16_t *) current + 3, - distributor16, - (distrib16_len + 1) * sizeof (grub_uint16_t)) != 0) - { - grub_free (current); - continue; - } - order_num = i; - have_order_num = 1; - grub_util_info ("Found matching distributor at Boot%04x", - order_num); - grub_free (current); - break; - } - } - if (!have_order_num) - grub_util_error ("%s", _("Couldn't find a free BootNNNN slot")); - path8_len = grub_strlen (efifile_path); - max_path_length = sizeof (*hddp) + sizeof (*filep) + (path8_len * GRUB_MAX_UTF16_PER_UTF8 + 1) * sizeof (grub_uint16_t) + sizeof (*endp); - entry = xmalloc (6 + (distrib16_len + 1) * sizeof (grub_uint16_t) + max_path_length); - /* attributes: active. */ - entry[0] = 1; - entry[1] = 0; - entry[2] = 0; - entry[3] = 0; - grub_memcpy (entry + 6, - distributor16, - (distrib16_len + 1) * sizeof (grub_uint16_t)); - - path = entry + 6 + (distrib16_len + 1) * sizeof (grub_uint16_t); - pathptr = path; - - hddp = pathptr; - grub_memset (hddp, 0, sizeof (*hddp)); - hddp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE; - hddp->header.subtype = GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE; - hddp->header.length = sizeof (*hddp); - hddp->partition_number = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1; - if (efidir_grub_dev->disk->partition - && grub_strcmp (efidir_grub_dev->disk->partition->partmap->name, "msdos") == 0) - { - grub_partition_t p; - - p = efidir_grub_dev->disk->partition; - efidir_grub_dev->disk->partition = p->parent; - if (grub_disk_read (efidir_grub_dev->disk, 0, 440, - 4, hddp->partition_signature)) - grub_util_error ("%s", grub_errmsg); - efidir_grub_dev->disk->partition = p; - - hddp->partmap_type = 1; - hddp->signature_type = 1; - } - else if (efidir_grub_dev->disk->partition - && grub_strcmp (efidir_grub_dev->disk->partition->partmap->name, "gpt") == 0) - { - struct grub_gpt_partentry gptdata; - grub_partition_t p; - - p = efidir_grub_dev->disk->partition; - efidir_grub_dev->disk->partition = p->parent; - if (grub_disk_read (efidir_grub_dev->disk, - p->offset, p->index, - sizeof (gptdata), &gptdata)) - grub_util_error ("%s", grub_errmsg); - efidir_grub_dev->disk->partition = p; - grub_memcpy (hddp->partition_signature, - &gptdata.guid, 16); - - hddp->partmap_type = 2; - hddp->signature_type = 2; - } - - hddp->partition_start = grub_partition_get_start (efidir_grub_dev->disk->partition) - >> (efidir_grub_dev->disk->log_sector_size - GRUB_DISK_SECTOR_BITS); - hddp->partition_size = grub_disk_native_sectors (efidir_grub_dev->disk) - >> (efidir_grub_dev->disk->log_sector_size - GRUB_DISK_SECTOR_BITS); - - pathptr = hddp + 1; - filep = pathptr; - filep->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE; - filep->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE; - -#if __GNUC__ >= 9 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Waddress-of-packed-member" -#endif - - path16_len = grub_utf8_to_utf16 (filep->path_name, - path8_len * GRUB_MAX_UTF16_PER_UTF8, - (const grub_uint8_t *) efifile_path, - path8_len, 0); - -#if __GNUC__ >= 9 -#pragma GCC diagnostic pop -#endif - - filep->path_name[path16_len] = 0; - filep->header.length = sizeof (*filep) + (path16_len + 1) * sizeof (grub_uint16_t); - pathptr = &filep->path_name[path16_len + 1]; - endp = pathptr; - endp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; - endp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; - endp->length = sizeof (*endp); - pathptr = endp + 1; - - entry[4] = (grub_uint8_t *) pathptr - path; - entry[5] = ((grub_uint8_t *) pathptr - path) >> 8; - - new_boot_order = xmalloc ((boot_order_len > 0 ? boot_order_len : 0) + 2); - new_boot_order[0] = order_num; - new_boot_order_len = 1; - { - ssize_t i; - for (i = 0; i < boot_order_len / 2; i++) - if (boot_order[i] != order_num) - new_boot_order[new_boot_order_len++] = boot_order[i]; - } - - set_efi_variable_bootn (order_num, entry, (grub_uint8_t *) pathptr - entry); - set_efi_variable (L"BootOrder", new_boot_order, new_boot_order_len * sizeof (grub_uint16_t)); - - return 0; -} - -void -grub_install_register_ieee1275 (int is_prep, const char *install_device, - int partno, const char *relpath) -{ - grub_util_error ("%s", _("no IEEE1275 routines are available for your platform")); -} - -void -grub_install_sgi_setup (const char *install_device, - const char *imgfile, const char *destname) -{ - grub_util_error ("%s", _("no SGI routines are available for your platform")); -} diff --git a/grub-core/osdep/windows/random.c b/grub-core/osdep/windows/random.c deleted file mode 100644 index 78f508202..000000000 --- a/grub-core/osdep/windows/random.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1992-1999,2001,2003,2004,2005,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -int -grub_get_random (void *out, grub_size_t len) -{ - HCRYPTPROV hCryptProv; - if (!CryptAcquireContext (&hCryptProv, - NULL, - MS_DEF_PROV, - PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) - return 1; - if (!CryptGenRandom (hCryptProv, len, out)) - { - CryptReleaseContext (hCryptProv, 0); - return 1; - } - - CryptReleaseContext (hCryptProv, 0); - - return 0; -} diff --git a/grub-core/osdep/windows/relpath.c b/grub-core/osdep/windows/relpath.c deleted file mode 100644 index 478e8ef14..000000000 --- a/grub-core/osdep/windows/relpath.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static size_t -tclen (const TCHAR *s) -{ - const TCHAR *s0 = s; - while (*s) - s++; - return s - s0; -} - -char * -grub_make_system_path_relative_to_its_root (const char *path) -{ - TCHAR *dirwindows, *mntpointwindows; - TCHAR *ptr; - size_t offset, flen; - TCHAR *ret; - char *cret; - - dirwindows = grub_util_get_windows_path (path); - if (!dirwindows) - return xstrdup (path); - - mntpointwindows = grub_get_mount_point (dirwindows); - - if (!mntpointwindows) - { - offset = 0; - if (dirwindows[0] && dirwindows[1] == ':') - offset = 2; - } - offset = tclen (mntpointwindows); - free (mntpointwindows); - flen = tclen (dirwindows); - if (offset > flen) - { - offset = 0; - if (dirwindows[0] && dirwindows[1] == ':') - offset = 2; - } - ret = xcalloc (flen - offset + 2, sizeof (ret[0])); - if (dirwindows[offset] != '\\' - && dirwindows[offset] != '/' - && dirwindows[offset]) - { - ret[0] = '\\'; - memcpy (ret + 1, dirwindows + offset, (flen - offset + 1) * sizeof (ret[0])); - } - else - memcpy (ret, dirwindows + offset, (flen - offset + 1) * sizeof (ret[0])); - - free (dirwindows); - - for (ptr = ret; *ptr; ptr++) - if (*ptr == '\\') - *ptr = '/'; - - cret = grub_util_tchar_to_utf8 (ret); - free (ret); - - return cret; -} diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c deleted file mode 100644 index 4e93faf1c..000000000 --- a/grub-core/partmap/bsdlabel.c +++ /dev/null @@ -1,271 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#ifdef GRUB_UTIL -#include -#endif - -static struct grub_partition_map grub_bsdlabel_partition_map; -static struct grub_partition_map grub_netbsdlabel_partition_map; -static struct grub_partition_map grub_openbsdlabel_partition_map; - - - -static grub_err_t -iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, - struct grub_partition_map *pmap, - grub_partition_iterate_hook_t hook, void *hook_data) -{ - struct grub_partition_bsd_disk_label label; - struct grub_partition p; - grub_disk_addr_t delta = 0; - grub_disk_addr_t pos; - - /* Read the BSD label. */ - if (grub_disk_read (disk, sector, 0, sizeof (label), &label)) - return grub_errno; - - /* Check if it is valid. */ - if (label.magic != grub_cpu_to_le32_compile_time (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature"); - - /* A kludge to determine a base of be.offset. */ - if (GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION - < grub_cpu_to_le16 (label.num_partitions) && freebsd) - { - struct grub_partition_bsd_entry whole_disk_be; - - pos = sizeof (label) + sector * GRUB_DISK_SECTOR_SIZE - + sizeof (struct grub_partition_bsd_entry) - * GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION; - - if (grub_disk_read (disk, pos / GRUB_DISK_SECTOR_SIZE, - pos % GRUB_DISK_SECTOR_SIZE, sizeof (whole_disk_be), - &whole_disk_be)) - return grub_errno; - - delta = grub_le_to_cpu32 (whole_disk_be.offset); - } - - pos = sizeof (label) + sector * GRUB_DISK_SECTOR_SIZE; - - for (p.number = 0; - p.number < grub_cpu_to_le16 (label.num_partitions); - p.number++, pos += sizeof (struct grub_partition_bsd_entry)) - { - struct grub_partition_bsd_entry be; - - if (p.number == GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION) - continue; - - 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); - p.len = grub_le_to_cpu32 (be.size); - p.partmap = pmap; - - if (p.len == 0) - continue; - - if (p.start < delta) - { -#ifdef GRUB_UTIL - char *partname; - /* disk->partition != NULL as 0 < delta */ - partname = disk->partition ? grub_partition_get_name (disk->partition) - : 0; - grub_util_warn (_("Discarding improperly nested partition (%s,%s,%s%d)"), - disk->name, partname ? : "", p.partmap->name, - p.number + 1); - grub_free (partname); -#endif - continue; - } - - p.start -= delta; - - if (hook (disk, &p, hook_data)) - return grub_errno; - } - return GRUB_ERR_NONE; -} - -static grub_err_t -bsdlabel_partition_map_iterate (grub_disk_t disk, - grub_partition_iterate_hook_t hook, - void *hook_data) -{ - - if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos") - == 0 && disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_FREEBSD) - return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 1, - &grub_bsdlabel_partition_map, hook, hook_data); - - if (disk->partition - && (grub_strcmp (disk->partition->partmap->name, "msdos") == 0 - || disk->partition->partmap == &grub_bsdlabel_partition_map - || disk->partition->partmap == &grub_netbsdlabel_partition_map - || disk->partition->partmap == &grub_openbsdlabel_partition_map)) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported"); - - return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, - &grub_bsdlabel_partition_map, hook, hook_data); -} - -/* Context for netopenbsdlabel_partition_map_iterate. */ -struct netopenbsdlabel_ctx -{ - grub_uint8_t type; - struct grub_partition_map *pmap; - grub_partition_iterate_hook_t hook; - void *hook_data; - int count; -}; - -/* Helper for netopenbsdlabel_partition_map_iterate. */ -static int -check_msdos (grub_disk_t dsk, const grub_partition_t partition, void *data) -{ - struct netopenbsdlabel_ctx *ctx = data; - grub_err_t err; - - if (partition->msdostype != ctx->type) - return 0; - - err = iterate_real (dsk, partition->start - + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, ctx->pmap, - ctx->hook, ctx->hook_data); - if (err == GRUB_ERR_NONE) - { - ctx->count++; - return 1; - } - if (err == GRUB_ERR_BAD_PART_TABLE) - { - grub_errno = GRUB_ERR_NONE; - return 0; - } - grub_print_error (); - return 0; -} - -/* This is a total breakage. Even when net-/openbsd label is inside partition - it actually describes the whole disk. - */ -static grub_err_t -netopenbsdlabel_partition_map_iterate (grub_disk_t disk, grub_uint8_t type, - struct grub_partition_map *pmap, - grub_partition_iterate_hook_t hook, - void *hook_data) -{ - if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos") - == 0) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported"); - - { - struct netopenbsdlabel_ctx ctx = { - .type = type, - .pmap = pmap, - .hook = hook, - .hook_data = hook_data, - .count = 0 - }; - grub_err_t err; - - err = grub_partition_msdos_iterate (disk, check_msdos, &ctx); - - if (err) - return err; - if (!ctx.count) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "no bsdlabel found"); - } - return GRUB_ERR_NONE; -} - -static grub_err_t -netbsdlabel_partition_map_iterate (grub_disk_t disk, - grub_partition_iterate_hook_t hook, - void *hook_data) -{ - return netopenbsdlabel_partition_map_iterate (disk, - GRUB_PC_PARTITION_TYPE_NETBSD, - &grub_netbsdlabel_partition_map, - hook, hook_data); -} - -static grub_err_t -openbsdlabel_partition_map_iterate (grub_disk_t disk, - grub_partition_iterate_hook_t hook, - void *hook_data) -{ - return netopenbsdlabel_partition_map_iterate (disk, - GRUB_PC_PARTITION_TYPE_OPENBSD, - &grub_openbsdlabel_partition_map, - hook, hook_data); -} - - -static struct grub_partition_map grub_bsdlabel_partition_map = - { - .name = "bsd", - .iterate = bsdlabel_partition_map_iterate, - }; - -static struct grub_partition_map grub_openbsdlabel_partition_map = - { - .name = "openbsd", - .iterate = openbsdlabel_partition_map_iterate, - }; - -static struct grub_partition_map grub_netbsdlabel_partition_map = - { - .name = "netbsd", - .iterate = netbsdlabel_partition_map_iterate, - }; - - - -GRUB_MOD_INIT(part_bsd) -{ - grub_partition_map_register (&grub_bsdlabel_partition_map); - grub_partition_map_register (&grub_netbsdlabel_partition_map); - grub_partition_map_register (&grub_openbsdlabel_partition_map); -} - -GRUB_MOD_FINI(part_bsd) -{ - grub_partition_map_unregister (&grub_bsdlabel_partition_map); - grub_partition_map_unregister (&grub_netbsdlabel_partition_map); - grub_partition_map_unregister (&grub_openbsdlabel_partition_map); -} diff --git a/grub-core/partmap/dfly.c b/grub-core/partmap/dfly.c deleted file mode 100644 index d30da8624..000000000 --- a/grub-core/partmap/dfly.c +++ /dev/null @@ -1,132 +0,0 @@ -/* dfly.c - Read DragonFly BSD disklabel64. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static struct grub_partition_map grub_dfly_partition_map; - -#define GRUB_PARTITION_DISKLABEL64_HEADER_SIZE 200 - -/* Full entry is 64 bytes however we really care only - about offset and size which are in first 16 bytes. - Avoid using too much stack. */ -#define GRUB_PARTITION_DISKLABEL64_ENTRY_SIZE 64 -struct grub_partition_disklabel64_entry -{ - grub_uint64_t boffset; - grub_uint64_t bsize; -}; - -/* Full entry is 200 bytes however we really care only - about magic and number of partitions which are in first 16 bytes. - Avoid using too much stack. */ -struct grub_partition_disklabel64 -{ - grub_uint32_t magic; -#define GRUB_DISKLABEL64_MAGIC ((grub_uint32_t)0xc4464c59) - grub_uint32_t crc; - grub_uint32_t unused; - grub_uint32_t npartitions; -}; - -static grub_err_t -dfly_partition_map_iterate (grub_disk_t disk, - grub_partition_iterate_hook_t hook, - void *hook_data) -{ - struct grub_partition part; - unsigned partno, pos; - struct grub_partition_disklabel64 label; - - part.partmap = &grub_dfly_partition_map; - - if (grub_disk_read (disk, 1, 0, sizeof (label), &label)) - return grub_errno; - - if (label.magic != grub_cpu_to_le32_compile_time (GRUB_DISKLABEL64_MAGIC)) - { - grub_dprintf ("partition", - "bad magic (found 0x%x; wanted 0x%x)\n", - (unsigned int) grub_le_to_cpu32 (label.magic), - (unsigned int) GRUB_DISKLABEL64_MAGIC); - return grub_error (GRUB_ERR_BAD_PART_TABLE, "disklabel64 not found"); - } - - pos = GRUB_PARTITION_DISKLABEL64_HEADER_SIZE + GRUB_DISK_SECTOR_SIZE; - - for (partno = 0; - partno < grub_le_to_cpu32 (label.npartitions); ++partno) - { - grub_disk_addr_t sector = pos >> GRUB_DISK_SECTOR_BITS; - grub_off_t offset = pos & (GRUB_DISK_SECTOR_SIZE - 1); - struct grub_partition_disklabel64_entry dpart; - - pos += GRUB_PARTITION_DISKLABEL64_ENTRY_SIZE; - if (grub_disk_read (disk, sector, offset, sizeof (dpart), &dpart)) - return grub_errno; - - grub_dprintf ("partition", - "partition %2d: offset 0x%llx, " - "size 0x%llx\n", - partno, - (unsigned long long) grub_le_to_cpu64 (dpart.boffset), - (unsigned long long) grub_le_to_cpu64 (dpart.bsize)); - - /* Is partition initialized? */ - if (dpart.bsize == 0) - continue; - - part.number = partno; - part.start = grub_le_to_cpu64 (dpart.boffset) >> GRUB_DISK_SECTOR_BITS; - part.len = grub_le_to_cpu64 (dpart.bsize) >> GRUB_DISK_SECTOR_BITS; - - /* This is counter-intuitive, but part.offset and sector have - * the same type, and offset (NOT part.offset) is guaranteed - * to fit into part.index. */ - part.offset = sector; - part.index = offset; - - if (hook (disk, &part, hook_data)) - return grub_errno; - } - - return GRUB_ERR_NONE; -} - -/* Partition map type. */ -static struct grub_partition_map grub_dfly_partition_map = -{ - .name = "dfly", - .iterate = dfly_partition_map_iterate, -}; - -GRUB_MOD_INIT(part_dfly) -{ - grub_partition_map_register (&grub_dfly_partition_map); -} - -GRUB_MOD_FINI(part_dfly) -{ - grub_partition_map_unregister (&grub_dfly_partition_map); -} diff --git a/grub-core/partmap/dvh.c b/grub-core/partmap/dvh.c deleted file mode 100644 index b25ae0d3b..000000000 --- a/grub-core/partmap/dvh.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2005,2006,2007,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define DVH_MAGIC 0x0be5a941 - -struct grub_dvh_partition_descriptor -{ - grub_uint32_t length; - grub_uint32_t start; - grub_uint32_t type; -} GRUB_PACKED; - -struct grub_dvh_block -{ - grub_uint32_t magic; - grub_uint8_t unused[308]; - struct grub_dvh_partition_descriptor parts[16]; - grub_uint32_t checksum; - grub_uint32_t unused2; -} GRUB_PACKED; - -static struct grub_partition_map grub_dvh_partition_map; - -/* Verify checksum (true=ok). */ -static int -grub_dvh_is_valid (grub_uint32_t *label) -{ - grub_uint32_t *pos; - grub_uint32_t sum = 0; - - for (pos = label; - pos < (label + sizeof (struct grub_dvh_block) / 4); - pos++) - sum += grub_be_to_cpu32 (*pos); - - return ! sum; -} - -static grub_err_t -dvh_partition_map_iterate (grub_disk_t disk, - grub_partition_iterate_hook_t hook, void *hook_data) -{ - struct grub_partition p; - union - { - struct grub_dvh_block dvh; - grub_uint32_t raw[0]; - } block; - unsigned partnum; - grub_err_t err; - - p.partmap = &grub_dvh_partition_map; - err = grub_disk_read (disk, 0, 0, sizeof (struct grub_dvh_block), - &block); - if (err) - return err; - - if (DVH_MAGIC != grub_be_to_cpu32 (block.dvh.magic)) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a dvh partition table"); - - if (! grub_dvh_is_valid (block.raw)) - 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 < ARRAY_SIZE (block.dvh.parts); partnum++) - { - if (block.dvh.parts[partnum].length == 0) - continue; - - if (partnum == 10) - continue; - - p.start = grub_be_to_cpu32 (block.dvh.parts[partnum].start); - p.len = grub_be_to_cpu32 (block.dvh.parts[partnum].length); - p.number = p.index = partnum; - if (hook (disk, &p, hook_data)) - break; - } - - return grub_errno; -} - - -/* Partition map type. */ -static struct grub_partition_map grub_dvh_partition_map = - { - .name = "dvh", - .iterate = dvh_partition_map_iterate, - }; - -GRUB_MOD_INIT(part_dvh) -{ - grub_partition_map_register (&grub_dvh_partition_map); -} - -GRUB_MOD_FINI(part_dvh) -{ - grub_partition_map_unregister (&grub_dvh_partition_map); -} - diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c deleted file mode 100644 index 426f616ae..000000000 --- a/grub-core/partmap/gpt.c +++ /dev/null @@ -1,241 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef GRUB_UTIL -#include -#endif - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_uint8_t grub_gpt_magic[8] = - { - 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54 - }; - -static const grub_guid_t grub_gpt_partition_type_empty = GRUB_GPT_PARTITION_TYPE_EMPTY; - -#ifdef GRUB_UTIL -static const grub_guid_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT; -#endif - -/* 512 << 7 = 65536 byte sectors. */ -#define MAX_SECTOR_LOG 7 - -static struct grub_partition_map grub_gpt_partition_map; - - - -grub_err_t -grub_gpt_partition_map_iterate (grub_disk_t disk, - grub_partition_iterate_hook_t hook, - void *hook_data) -{ - 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; - int sector_log = 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_compile_time (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. */ - for (i = 0; i < 4; i++) - if (mbr.entries[i].type == GRUB_PC_PARTITION_TYPE_GPT_DISK) - break; - if (i == 4) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "no GPT partition map found"); - - /* Read the GPT header. */ - for (sector_log = 0; sector_log < MAX_SECTOR_LOG; sector_log++) - { - if (grub_disk_read (disk, 1 << sector_log, 0, sizeof (gpt), &gpt)) - return grub_errno; - - if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic)) == 0) - break; - } - if (sector_log == MAX_SECTOR_LOG) - 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) << sector_log; - 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) << sector_log; - part.len = (grub_le_to_cpu64 (entry.end) - - grub_le_to_cpu64 (entry.start) + 1) << sector_log; - part.offset = entries; - part.number = i; - part.index = last_offset; - part.partmap = &grub_gpt_partition_map; - part.parent = disk->partition; - - 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, hook_data)) - 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; -} - -#ifdef GRUB_UTIL -/* Context for gpt_partition_map_embed. */ -struct gpt_partition_map_embed_ctx -{ - grub_disk_addr_t start, len; -}; - -/* Helper for gpt_partition_map_embed. */ -static int -find_usable_region (grub_disk_t disk __attribute__ ((unused)), - const grub_partition_t p, void *data) -{ - struct gpt_partition_map_embed_ctx *ctx = data; - struct grub_gpt_partentry gptdata; - grub_partition_t p2; - - p2 = disk->partition; - disk->partition = p->parent; - if (grub_disk_read (disk, p->offset, p->index, - sizeof (gptdata), &gptdata)) - { - disk->partition = p2; - return 0; - } - disk->partition = p2; - - /* If there's an embed region, it is in a dedicated partition. */ - if (! grub_memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16)) - { - ctx->start = p->start; - ctx->len = p->len; - return 1; - } - - return 0; -} - -static grub_err_t -gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, - unsigned int max_nsectors, - grub_embed_type_t embed_type, - grub_disk_addr_t **sectors, - int warn_short) -{ - struct gpt_partition_map_embed_ctx ctx = { - .start = 0, - .len = 0 - }; - unsigned i; - grub_err_t err; - - if (embed_type != GRUB_EMBED_PCBIOS) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "GPT currently supports only PC-BIOS embedding"); - - err = grub_gpt_partition_map_iterate (disk, find_usable_region, &ctx); - if (err) - return err; - - if (ctx.len == 0) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, - N_("this GPT partition label contains no BIOS Boot Partition;" - " embedding won't be possible")); - - if (ctx.len < GRUB_MIN_RECOMMENDED_MBR_GAP) - grub_util_warn ("Your BIOS Boot Partition is under 1 MiB, please increase its size."); - - if (ctx.len < *nsectors) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("your BIOS Boot Partition is too small;" - " embedding won't be possible")); - - *nsectors = ctx.len; - if (*nsectors > max_nsectors) - *nsectors = max_nsectors; - *sectors = grub_calloc (*nsectors, sizeof (**sectors)); - if (!*sectors) - return grub_errno; - for (i = 0; i < *nsectors; i++) - (*sectors)[i] = ctx.start + i; - - return GRUB_ERR_NONE; -} -#endif - - -/* Partition map type. */ -static struct grub_partition_map grub_gpt_partition_map = - { - .name = "gpt", - .iterate = grub_gpt_partition_map_iterate, -#ifdef GRUB_UTIL - .embed = gpt_partition_map_embed -#endif - }; - -GRUB_MOD_INIT(part_gpt) -{ - COMPILE_TIME_ASSERT(sizeof(grub_guid_t) == 16); - COMPILE_TIME_ASSERT(sizeof(grub_packed_guid_t) == 16); - COMPILE_TIME_ASSERT(sizeof(struct grub_gpt_partentry) == 128); - 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 deleted file mode 100644 index c85bb74be..000000000 --- a/grub-core/partmap/msdos.c +++ /dev/null @@ -1,435 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static struct grub_partition_map grub_msdos_partition_map; - - -#ifdef GRUB_UTIL -#include - -struct embed_signature -{ - const char *name; - const char *signature; - int signature_len; - enum { TYPE_SOFTWARE, TYPE_RAID } type; -}; - -const char message_warn[][200] = { - /* TRANSLATORS: MBR gap and boot track is the same thing and is the space - between MBR and first partitition. If your language translates well only - "boot track", you can just use it everywhere. Next two messages are about - RAID controllers/software bugs which GRUB has to live with. Please spread - the message that these are bugs in other software and not merely - suboptimal behaviour. */ - [TYPE_RAID] = N_("Sector %llu is already in use by raid controller `%s';" - " avoiding it. " - "Please ask the manufacturer not to store data in MBR gap"), - [TYPE_SOFTWARE] = N_("Sector %llu is already in use by the program `%s';" - " avoiding it. " - "This software may cause boot or other problems in " - "future. Please ask its authors not to store data " - "in the boot track") -}; - - -/* Signatures of other software that may be using sectors in the embedding - area. */ -struct embed_signature embed_signatures[] = - { - { - .name = "ZISD", - .signature = "ZISD", - .signature_len = 4, - .type = TYPE_SOFTWARE - }, - { - .name = "FlexNet", - .signature = "\xd4\x41\xa0\xf5\x03\x00\x03\x00", - .signature_len = 8, - .type = TYPE_SOFTWARE - }, - { - .name = "FlexNet", - .signature = "\xd8\x41\xa0\xf5\x02\x00\x02\x00", - .signature_len = 8, - .type = TYPE_SOFTWARE - }, - { - /* from Ryan Perkins */ - .name = "HP Backup and Recovery Manager (?)", - .signature = "\x70\x8a\x5d\x46\x35\xc5\x1b\x93" - "\xae\x3d\x86\xfd\xb1\x55\x3e\xe0", - .signature_len = 16, - .type = TYPE_SOFTWARE - }, - { - .name = "HighPoint RAID controller", - .signature = "ycgl", - .signature_len = 4, - .type = TYPE_RAID - }, - { - /* https://bugs.launchpad.net/bugs/987022 */ - .name = "Acer registration utility (?)", - .signature = "GREGRegDone.Tag\x00", - .signature_len = 16, - .type = TYPE_SOFTWARE - } - }; -#endif - -grub_err_t -grub_partition_msdos_iterate (grub_disk_t disk, - grub_partition_iterate_hook_t hook, - void *hook_data) -{ - struct grub_partition p; - struct grub_msdos_partition_mbr mbr; - int labeln = 0; - grub_disk_addr_t lastaddr; - grub_disk_addr_t ext_offset; - grub_disk_addr_t delta = 0; - - if (disk->partition && disk->partition->partmap == &grub_msdos_partition_map) - { - if (disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_LINUX_MINIX) - delta = disk->partition->start; - else - return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported"); - } - - 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; - - /* If this is a GPT partition, this MBR is just a dummy. */ - if (p.offset == 0) - for (i = 0; i < 4; i++) - if (mbr.entries[i].type == GRUB_PC_PARTITION_TYPE_GPT_DISK) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "dummy mbr"); - - /* 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_compile_time (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_disk_addr_t)grub_le_to_cpu32 (e->start) - << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)) - delta; - p.len = (grub_uint64_t)grub_le_to_cpu32 (e->length) - << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); - p.msdostype = e->type; - - 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 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, hook_data)) - return grub_errno; - } - else if (p.number < 3) - /* 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_disk_addr_t)grub_le_to_cpu32 (e->start) - << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); - if (! ext_offset) - ext_offset = p.offset; - - break; - } - } - - /* If no extended partition, the end. */ - if (i == 4) - break; - } - - finish: - return grub_errno; -} - -#ifdef GRUB_UTIL - -#pragma GCC diagnostic ignored "-Wformat-nonliteral" - -static grub_err_t -pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, - unsigned int max_nsectors, - grub_embed_type_t embed_type, - grub_disk_addr_t **sectors, - int warn_short) -{ - grub_disk_addr_t end = ~0ULL; - struct grub_msdos_partition_mbr mbr; - int labeln = 0; - /* Any value different than `p.offset' will satisfy the check during - first loop. */ - grub_disk_addr_t lastaddr = 1; - grub_disk_addr_t ext_offset = 0; - grub_disk_addr_t offset = 0; - - if (embed_type != GRUB_EMBED_PCBIOS) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "PC-style partitions currently support " - "only PC-BIOS embedding"); - - if (disk->partition) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - "Embedding on MSDOS subpartition isn't supported"); - - while (1) - { - int i; - struct grub_msdos_partition_entry *e; - grub_err_t err; - - /* Read the MBR. */ - err = grub_disk_read (disk, offset, 0, sizeof (mbr), &mbr); - if (err) - return err; - - /* 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 == offset) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "loop detected"); - - labeln++; - if ((labeln & (labeln - 1)) == 0) - lastaddr = offset; - - /* Check if it is valid. */ - if (mbr.signature != grub_cpu_to_le16_compile_time (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 (i = 0; i < 4; i++) - { - e = mbr.entries + i; - - if (!grub_msdos_partition_is_empty (e->type) - && end > offset - + ((grub_disk_addr_t)grub_le_to_cpu32 (e->start) - << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS))) - end = offset + ((grub_disk_addr_t)grub_le_to_cpu32 (e->start) - << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); - - /* If this is a GPT partition, this MBR is just a dummy. */ - if (e->type == GRUB_PC_PARTITION_TYPE_GPT_DISK && i == 0) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "dummy mbr"); - } - - /* Find an extended partition. */ - for (i = 0; i < 4; i++) - { - e = mbr.entries + i; - - if (grub_msdos_partition_is_extended (e->type)) - { - offset = ext_offset - + ((grub_disk_addr_t)grub_le_to_cpu32 (e->start) - << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); - if (! ext_offset) - ext_offset = offset; - - break; - } - } - - /* If no extended partition, the end. */ - if (i == 4) - break; - } - - if (end >= *nsectors + 1) - { - unsigned i, j; - char *embed_signature_check; - unsigned int orig_nsectors, avail_nsectors; - - orig_nsectors = *nsectors; - *nsectors = end - 1; - avail_nsectors = *nsectors; - if (*nsectors > max_nsectors) - *nsectors = max_nsectors; - *sectors = grub_calloc (*nsectors, sizeof (**sectors)); - if (!*sectors) - return grub_errno; - for (i = 0; i < *nsectors; i++) - (*sectors)[i] = 1 + i; - - /* Check for software that is already using parts of the embedding - * area. - */ - embed_signature_check = grub_malloc (GRUB_DISK_SECTOR_SIZE); - for (i = 0; i < *nsectors; i++) - { - if (grub_disk_read (disk, (*sectors)[i], 0, GRUB_DISK_SECTOR_SIZE, - embed_signature_check)) - continue; - - for (j = 0; j < ARRAY_SIZE (embed_signatures); j++) - if (! grub_memcmp (embed_signatures[j].signature, - embed_signature_check, - embed_signatures[j].signature_len)) - break; - if (j == ARRAY_SIZE (embed_signatures)) - continue; - grub_util_warn (_(message_warn[embed_signatures[j].type]), - (*sectors)[i], embed_signatures[j].name); - avail_nsectors--; - if (avail_nsectors < *nsectors) - *nsectors = avail_nsectors; - - /* Avoid this sector. */ - for (j = i; j < *nsectors; j++) - (*sectors)[j]++; - - /* Have we run out of space? */ - if (avail_nsectors < orig_nsectors) - break; - - /* Make sure to check the next sector. */ - i--; - } - grub_free (embed_signature_check); - - if (*nsectors < orig_nsectors) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("other software is using the embedding area, and " - "there is not enough room for core.img. Such " - "software is often trying to store data in a way " - "that avoids detection. We recommend you " - "investigate")); - - return GRUB_ERR_NONE; - } - - if (end < GRUB_MIN_RECOMMENDED_MBR_GAP && warn_short) - grub_util_warn ("You have a short MBR gap and use advanced config. Please increase post-MBR gap."); - - if (end <= 1) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, - N_("this msdos-style partition label has no " - "post-MBR gap; embedding won't be possible")); - - if (*nsectors > 62) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("your core.img is unusually large. " - "It won't fit in the embedding area")); - - return grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("your embedding area is unusually small. " - "core.img won't fit in it.")); -} - -#pragma GCC diagnostic error "-Wformat-nonliteral" - -#endif - - -/* Partition map type. */ -static struct grub_partition_map grub_msdos_partition_map = - { - .name = "msdos", - .iterate = grub_partition_msdos_iterate, -#ifdef GRUB_UTIL - .embed = pc_partition_map_embed -#endif - }; - -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/plan.c b/grub-core/partmap/plan.c deleted file mode 100644 index 83db2241c..000000000 --- a/grub-core/partmap/plan.c +++ /dev/null @@ -1,120 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static struct grub_partition_map grub_plan_partition_map; - -static grub_err_t -plan_partition_map_iterate (grub_disk_t disk, - grub_partition_iterate_hook_t hook, - void *hook_data) -{ - struct grub_partition p; - int ptr = 0; - grub_err_t err; - - p.partmap = &grub_plan_partition_map; - p.msdostype = 0; - - for (p.number = 0; ; p.number++) - { - char sig[sizeof ("part ") - 1]; - char c; - - p.offset = (ptr >> GRUB_DISK_SECTOR_BITS) + 1; - p.index = ptr & (GRUB_DISK_SECTOR_SIZE - 1); - - err = grub_disk_read (disk, 1, ptr, sizeof (sig), sig); - if (err) - return err; - if (grub_memcmp (sig, "part ", sizeof ("part ") - 1) != 0) - break; - ptr += sizeof (sig); - do - { - err = grub_disk_read (disk, 1, ptr, 1, &c); - if (err) - return err; - ptr++; - } - while (grub_isdigit (c) || grub_isalpha (c)); - if (c != ' ') - break; - p.start = 0; - while (1) - { - err = grub_disk_read (disk, 1, ptr, 1, &c); - if (err) - return err; - ptr++; - if (!grub_isdigit (c)) - break; - p.start = p.start * 10 + (c - '0'); - } - if (c != ' ') - break; - p.len = 0; - while (1) - { - err = grub_disk_read (disk, 1, ptr, 1, &c); - if (err) - return err; - ptr++; - if (!grub_isdigit (c)) - break; - p.len = p.len * 10 + (c - '0'); - } - if (c != '\n') - break; - p.len -= p.start; - if (hook (disk, &p, hook_data)) - return grub_errno; - } - if (p.number == 0) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a plan partition table"); - - return GRUB_ERR_NONE; -} - -/* Partition map type. */ -static struct grub_partition_map grub_plan_partition_map = - { - .name = "plan", - .iterate = plan_partition_map_iterate, - }; - -GRUB_MOD_INIT(part_plan) -{ - grub_partition_map_register (&grub_plan_partition_map); -} - -GRUB_MOD_FINI(part_plan) -{ - grub_partition_map_unregister (&grub_plan_partition_map); -} - diff --git a/grub-core/partmap/sunpc.c b/grub-core/partmap/sunpc.c deleted file mode 100644 index fe9552e21..000000000 --- a/grub-core/partmap/sunpc.c +++ /dev/null @@ -1,151 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#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; -} GRUB_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. */ -} GRUB_PACKED; - -static struct grub_partition_map grub_sun_pc_partition_map; - -/* Verify checksum (true=ok). */ -static int -grub_sun_is_valid (grub_uint16_t *label) -{ - grub_uint16_t *pos; - grub_uint16_t sum = 0; - - for (pos = label; - pos < (label + sizeof (struct grub_sun_pc_block) / 2); - pos++) - sum ^= *pos; - - return ! sum; -} - -static grub_err_t -sun_pc_partition_map_iterate (grub_disk_t disk, - grub_partition_iterate_hook_t hook, - void *hook_data) -{ - grub_partition_t p; - union - { - struct grub_sun_pc_block sun_block; - grub_uint16_t raw[0]; - } 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.sun_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.raw)) - { - 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.sun_block.partitions[partnum].id == 0 - || block.sun_block.partitions[partnum].id - == GRUB_PARTMAP_SUN_PC_WHOLE_DISK_ID) - continue; - - desc = &block.sun_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, hook_data)) - 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/script/argv.c b/grub-core/script/argv.c deleted file mode 100644 index 5751fdd57..000000000 --- a/grub-core/script/argv.c +++ /dev/null @@ -1,165 +0,0 @@ -/* argv.c - methods for constructing argument vector */ -/* - * 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 . - */ - -#include -#include -#include -#include - -/* Return nearest power of two that is >= v. */ -static unsigned -round_up_exp (unsigned v) -{ - COMPILE_TIME_ASSERT (sizeof (v) == 4); - - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - - v++; - v += (v == 0); - - return v; -} - -void -grub_script_argv_free (struct grub_script_argv *argv) -{ - unsigned i; - - if (argv->args) - { - for (i = 0; i < argv->argc; i++) - grub_free (argv->args[i]); - - grub_free (argv->args); - } - - argv->argc = 0; - argv->args = 0; - argv->script = 0; -} - -/* Make argv from argc, args pair. */ -int -grub_script_argv_make (struct grub_script_argv *argv, int argc, char **args) -{ - int i; - struct grub_script_argv r = { 0, 0, 0 }; - - for (i = 0; i < argc; i++) - if (grub_script_argv_next (&r) - || grub_script_argv_append (&r, args[i], grub_strlen (args[i]))) - { - grub_script_argv_free (&r); - return 1; - } - *argv = r; - return 0; -} - -/* Prepare for next argc. */ -int -grub_script_argv_next (struct grub_script_argv *argv) -{ - char **p = argv->args; - grub_size_t sz; - - if (argv->args && argv->argc && argv->args[argv->argc - 1] == 0) - return 0; - - if (grub_add (argv->argc, 2, &sz) || - grub_mul (sz, sizeof (char *), &sz)) - return 1; - - p = grub_realloc (p, round_up_exp (sz)); - if (! p) - return 1; - - argv->argc++; - argv->args = p; - - if (argv->argc == 1) - argv->args[0] = 0; - argv->args[argv->argc] = 0; - return 0; -} - -/* Append `s' to the last argument. */ -int -grub_script_argv_append (struct grub_script_argv *argv, const char *s, - grub_size_t slen) -{ - grub_size_t a; - char *p = argv->args[argv->argc - 1]; - grub_size_t sz; - - if (! s) - return 0; - - a = p ? grub_strlen (p) : 0; - - if (grub_add (a, slen, &sz) || - grub_add (sz, 1, &sz) || - grub_mul (sz, sizeof (char), &sz)) - return 1; - - p = grub_realloc (p, round_up_exp (sz)); - if (! p) - return 1; - - grub_memcpy (p + a, s, slen); - p[a+slen] = 0; - argv->args[argv->argc - 1] = p; - - return 0; -} - -/* Split `s' and append words as multiple arguments. */ -int -grub_script_argv_split_append (struct grub_script_argv *argv, const char *s) -{ - const char *p; - int errors = 0; - - if (! s) - return 0; - - while (*s && grub_isspace (*s)) - s++; - - while (! errors && *s) - { - p = s; - while (*s && ! grub_isspace (*s)) - s++; - - errors += grub_script_argv_append (argv, p, s - p); - - while (*s && grub_isspace (*s)) - s++; - - if (*s) - errors += grub_script_argv_next (argv); - } - return errors; -} diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c deleted file mode 100644 index da99dfa05..000000000 --- a/grub-core/script/execute.c +++ /dev/null @@ -1,1212 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* 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) - -/* - * A limit on recursion, to avoid colliding with the heap. UEFI defines a baseline - * stack size of 128 KiB. So, assuming at most 1-2 KiB per iteration this should - * keep us safe. - */ -#define MAX_RECURSION_DEPTH 64 - -static unsigned long is_continue; -static unsigned long active_loops; -static unsigned long active_breaks; -static unsigned long function_return; -static unsigned long recursion_depth; - -#define GRUB_SCRIPT_SCOPE_MALLOCED 1 -#define GRUB_SCRIPT_SCOPE_ARGS_MALLOCED 2 - -/* Scope for grub script functions. */ -struct grub_script_scope -{ - unsigned flags; - unsigned shifts; - struct grub_script_argv argv; -}; -static struct grub_script_scope *scope = 0; - -/* Wildcard translator for GRUB script. */ -struct grub_script_wildcard_translator *grub_wildcard_translator; - -static char* -wildcard_escape (const char *s) -{ - int i; - int len; - char ch; - char *p; - - len = grub_strlen (s); - p = grub_malloc (len * 2 + 1); - if (! p) - return NULL; - - i = 0; - while ((ch = *s++)) - { - if (ch == '*' || ch == '\\' || ch == '?') - p[i++] = '\\'; - p[i++] = ch; - } - p[i] = '\0'; - return p; -} - -static char* -wildcard_unescape (const char *s) -{ - int i; - int len; - char ch; - char *p; - - len = grub_strlen (s); - p = grub_malloc (len + 1); - if (! p) - return NULL; - - i = 0; - while ((ch = *s++)) - { - if (ch == '\\') - p[i++] = *s++; - else - p[i++] = ch; - } - p[i] = '\0'; - return p; -} - -static void -replace_scope (struct grub_script_scope *new_scope) -{ - if (scope) - { - scope->argv.argc += scope->shifts; - scope->argv.args -= scope->shifts; - - if (scope->flags & GRUB_SCRIPT_SCOPE_ARGS_MALLOCED) - grub_script_argv_free (&scope->argv); - - if (scope->flags & GRUB_SCRIPT_SCOPE_MALLOCED) - grub_free (scope); - } - scope = new_scope; -} - -grub_err_t -grub_script_break (grub_command_t cmd, int argc, char *argv[]) -{ - const char *p = NULL; - unsigned long count; - - if (argc == 0) - count = 1; - else if (argc > 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - else - { - count = grub_strtoul (argv[0], &p, 10); - if (grub_errno) - return grub_errno; - if (*p != '\0') - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unrecognized number")); - if (count == 0) - /* TRANSLATORS: 0 is a quantifier. "break" (similar to bash) - can be used e.g. to break 3 loops at once. - But asking it to break 0 loops makes no sense. */ - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't break 0 loops")); - } - - is_continue = grub_strcmp (cmd->name, "break") ? 1 : 0; - active_breaks = count; - if (active_breaks > active_loops) - active_breaks = active_loops; - return GRUB_ERR_NONE; -} - -grub_err_t -grub_script_shift (grub_command_t cmd __attribute__((unused)), - int argc, char *argv[]) -{ - const char *p = NULL; - unsigned long n = 0; - - if (! scope) - return GRUB_ERR_NONE; - - if (argc == 0) - n = 1; - - else if (argc > 1) - return GRUB_ERR_BAD_ARGUMENT; - - else - { - n = grub_strtoul (argv[0], &p, 10); - if (*p != '\0') - return GRUB_ERR_BAD_ARGUMENT; - } - - if (n > scope->argv.argc) - return GRUB_ERR_BAD_ARGUMENT; - - scope->shifts += n; - scope->argv.argc -= n; - scope->argv.args += n; - return GRUB_ERR_NONE; -} - -grub_err_t -grub_script_setparams (grub_command_t cmd __attribute__((unused)), - int argc, char **args) -{ - struct grub_script_scope *new_scope; - struct grub_script_argv argv = { 0, 0, 0 }; - - if (! scope) - return GRUB_ERR_INVALID_COMMAND; - - new_scope = grub_malloc (sizeof (*new_scope)); - if (! new_scope) - return grub_errno; - - if (grub_script_argv_make (&argv, argc, args)) - { - grub_free (new_scope); - return grub_errno; - } - - new_scope->shifts = 0; - new_scope->argv = argv; - new_scope->flags = GRUB_SCRIPT_SCOPE_MALLOCED | - GRUB_SCRIPT_SCOPE_ARGS_MALLOCED; - - replace_scope (new_scope); - return GRUB_ERR_NONE; -} - -grub_err_t -grub_script_return (grub_command_t cmd __attribute__((unused)), - int argc, char *argv[]) -{ - const char *p = NULL; - unsigned long n; - - if (! scope || argc > 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - /* TRANSLATORS: It's about not being - inside a function. "return" can be used only - in a function and this error occurs if it's used - anywhere else. */ - N_("not in function body")); - - if (argc == 0) - { - const char *t; - function_return = 1; - t = grub_env_get ("?"); - if (!t) - return GRUB_ERR_NONE; - return grub_strtoul (t, NULL, 10); - } - - n = grub_strtoul (argv[0], &p, 10); - if (grub_errno) - return grub_errno; - if (*p != '\0') - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unrecognized number")); - - function_return = 1; - return n ? grub_error (n, N_("false")) : GRUB_ERR_NONE; -} - -static int -grub_env_special (const char *name) -{ - if (grub_isdigit (name[0]) || - grub_strcmp (name, "#") == 0 || - grub_strcmp (name, "*") == 0 || - grub_strcmp (name, "@") == 0) - return 1; - return 0; -} - -static char ** -grub_script_env_get (const char *name, grub_script_arg_type_t type) -{ - unsigned i; - struct grub_script_argv result = { 0, 0, 0 }; - - if (grub_script_argv_next (&result)) - goto fail; - - if (! grub_env_special (name)) - { - const char *v = grub_env_get (name); - if (v && v[0]) - { - if (type == GRUB_SCRIPT_ARG_TYPE_VAR) - { - if (grub_script_argv_split_append (&result, v)) - goto fail; - } - else - if (grub_script_argv_append (&result, v, grub_strlen (v))) - goto fail; - } - } - else if (! scope) - { - if (grub_script_argv_append (&result, 0, 0)) - goto fail; - } - else if (grub_strcmp (name, "#") == 0) - { - char buffer[ERRNO_DIGITS_MAX + 1]; - grub_snprintf (buffer, sizeof (buffer), "%u", scope->argv.argc); - if (grub_script_argv_append (&result, buffer, grub_strlen (buffer))) - goto fail; - } - else if (grub_strcmp (name, "*") == 0) - { - for (i = 0; i < scope->argv.argc; i++) - if (type == GRUB_SCRIPT_ARG_TYPE_VAR) - { - if (i != 0 && grub_script_argv_next (&result)) - goto fail; - - if (grub_script_argv_split_append (&result, scope->argv.args[i])) - goto fail; - } - else - { - if (i != 0 && grub_script_argv_append (&result, " ", 1)) - goto fail; - - if (grub_script_argv_append (&result, scope->argv.args[i], - grub_strlen (scope->argv.args[i]))) - goto fail; - } - } - else if (grub_strcmp (name, "@") == 0) - { - for (i = 0; i < scope->argv.argc; i++) - { - if (i != 0 && grub_script_argv_next (&result)) - goto fail; - - if (type == GRUB_SCRIPT_ARG_TYPE_VAR) - { - if (grub_script_argv_split_append (&result, scope->argv.args[i])) - goto fail; - } - else - if (grub_script_argv_append (&result, scope->argv.args[i], - grub_strlen (scope->argv.args[i]))) - goto fail; - } - } - else - { - unsigned long num = grub_strtoul (name, 0, 10); - if (num == 0) - ; /* XXX no file name, for now. */ - - else if (num <= scope->argv.argc) - { - if (type == GRUB_SCRIPT_ARG_TYPE_VAR) - { - if (grub_script_argv_split_append (&result, - scope->argv.args[num - 1])) - goto fail; - } - else - if (grub_script_argv_append (&result, scope->argv.args[num - 1], - grub_strlen (scope->argv.args[num - 1]) - )) - goto fail; - } - } - - return result.args; - - fail: - - grub_script_argv_free (&result); - return 0; -} - -static grub_err_t -grub_script_env_set (const char *name, const char *val) -{ - if (grub_env_special (name)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("invalid variable name `%s'"), name); - - return grub_env_set (name, val); -} - -struct gettext_context -{ - char **allowed_strings; - grub_size_t nallowed_strings; - grub_size_t additional_len; -}; - -static int -parse_string (const char *str, - int (*hook) (const char *var, grub_size_t varlen, - char **ptr, struct gettext_context *ctx), - struct gettext_context *ctx, - char *put) -{ - const char *ptr; - int escaped = 0; - const char *optr; - - for (ptr = str; ptr && *ptr; ) - switch (*ptr) - { - case '\\': - escaped = !escaped; - if (!escaped && put) - *(put++) = '\\'; - ptr++; - break; - case '$': - if (escaped) - { - escaped = 0; - if (put) - *(put++) = *ptr; - ptr++; - break; - } - - ptr++; - switch (*ptr) - { - case '{': - { - optr = ptr + 1; - ptr = grub_strchr (optr, '}'); - if (!ptr) - break; - if (hook (optr, ptr - optr, &put, ctx)) - return 1; - ptr++; - break; - } - case '0' ... '9': - optr = ptr; - while (*ptr >= '0' && *ptr <= '9') - ptr++; - if (hook (optr, ptr - optr, &put, ctx)) - return 1; - break; - case 'a' ... 'z': - case 'A' ... 'Z': - case '_': - optr = ptr; - while ((*ptr >= '0' && *ptr <= '9') - || (*ptr >= 'a' && *ptr <= 'z') - || (*ptr >= 'A' && *ptr <= 'Z') - || *ptr == '_') - ptr++; - if (hook (optr, ptr - optr, &put, ctx)) - return 1; - break; - case '?': - case '#': - if (hook (ptr, 1, &put, ctx)) - return 1; - ptr++; - break; - default: - if (put) - *(put++) = '$'; - } - break; - default: - if (escaped && put) - *(put++) = '\\'; - escaped = 0; - if (put) - *(put++) = *ptr; - ptr++; - break; - } - if (put) - *(put++) = 0; - return 0; -} - -static int -gettext_putvar (const char *str, grub_size_t len, - char **ptr, struct gettext_context *ctx) -{ - const char *var; - grub_size_t i; - - for (i = 0; i < ctx->nallowed_strings; i++) - if (grub_strncmp (ctx->allowed_strings[i], str, len) == 0 - && ctx->allowed_strings[i][len] == 0) - { - break; - } - if (i == ctx->nallowed_strings) - return 0; - - /* Enough for any number. */ - if (len == 1 && str[0] == '#' && scope != NULL) - { - grub_snprintf (*ptr, 30, "%u", scope->argv.argc); - *ptr += grub_strlen (*ptr); - return 0; - } - var = grub_env_get (ctx->allowed_strings[i]); - if (var) - *ptr = grub_stpcpy (*ptr, var); - return 0; -} - -static int -gettext_save_allow (const char *str, grub_size_t len, - char **ptr __attribute__ ((unused)), - struct gettext_context *ctx) -{ - ctx->allowed_strings[ctx->nallowed_strings++] = grub_strndup (str, len); - if (!ctx->allowed_strings[ctx->nallowed_strings - 1]) - return 1; - return 0; -} - -static int -gettext_getlen (const char *str, grub_size_t len, - char **ptr __attribute__ ((unused)), - struct gettext_context *ctx) -{ - const char *var; - grub_size_t i; - - for (i = 0; i < ctx->nallowed_strings; i++) - if (grub_strncmp (ctx->allowed_strings[i], str, len) == 0 - && ctx->allowed_strings[i][len] == 0) - break; - if (i == ctx->nallowed_strings) - return 0; - - /* Enough for any number. */ - if (len == 1 && str[0] == '#') - { - ctx->additional_len += 30; - return 0; - } - var = grub_env_get (ctx->allowed_strings[i]); - if (var) - ctx->additional_len += grub_strlen (var); - return 0; -} - -static int -gettext_append (struct grub_script_argv *result, const char *orig_str) -{ - const char *template; - char *res = 0; - struct gettext_context ctx = { - .allowed_strings = 0, - .nallowed_strings = 0, - .additional_len = 1 - }; - int rval = 1; - const char *iptr; - - grub_size_t dollar_cnt = 0; - - for (iptr = orig_str; *iptr; iptr++) - if (*iptr == '$') - dollar_cnt++; - ctx.allowed_strings = grub_calloc (dollar_cnt, sizeof (ctx.allowed_strings[0])); - - if (parse_string (orig_str, gettext_save_allow, &ctx, 0)) - goto fail; - - template = _(orig_str); - - if (parse_string (template, gettext_getlen, &ctx, 0)) - goto fail; - - res = grub_malloc (grub_strlen (template) + ctx.additional_len); - if (!res) - goto fail; - - if (parse_string (template, gettext_putvar, &ctx, res)) - goto fail; - - char *escaped = 0; - escaped = wildcard_escape (res); - if (grub_script_argv_append (result, escaped, grub_strlen (escaped))) - { - grub_free (escaped); - goto fail; - } - grub_free (escaped); - - rval = 0; - fail: - grub_free (res); - { - grub_size_t i; - for (i = 0; i < ctx.nallowed_strings; i++) - grub_free (ctx.allowed_strings[i]); - } - grub_free (ctx.allowed_strings); - return rval; -} - -static int -append (struct grub_script_argv *result, - const char *s, int escape_type) -{ - int r; - char *p = 0; - - if (escape_type == 0) - return grub_script_argv_append (result, s, grub_strlen (s)); - - if (escape_type > 0) - p = wildcard_escape (s); - else if (escape_type < 0) - p = wildcard_unescape (s); - - if (! p) - return 1; - - r = grub_script_argv_append (result, p, grub_strlen (p)); - grub_free (p); - return r; -} - -/* Convert arguments in ARGLIST into ARGV form. */ -static int -grub_script_arglist_to_argv (struct grub_script_arglist *arglist, - struct grub_script_argv *argv) -{ - int i; - char **values = 0; - struct grub_script_arg *arg = 0; - struct grub_script_argv result = { 0, 0, 0 }; - - if (arglist == NULL) - return 1; - - for (; arglist && arglist->arg; arglist = arglist->next) - { - if (grub_script_argv_next (&result)) - goto fail; - - arg = arglist->arg; - while (arg) - { - switch (arg->type) - { - case GRUB_SCRIPT_ARG_TYPE_VAR: - case GRUB_SCRIPT_ARG_TYPE_DQVAR: - { - int need_cleanup = 0; - - values = grub_script_env_get (arg->str, arg->type); - for (i = 0; values && values[i]; i++) - { - if (!need_cleanup) - { - if (i != 0 && grub_script_argv_next (&result)) - { - need_cleanup = 1; - goto cleanup; - } - - if (arg->type == GRUB_SCRIPT_ARG_TYPE_VAR) - { - int len; - char ch; - char *p; - char *op; - const char *s = values[i]; - - len = grub_strlen (values[i]); - /* \? -> \\\? */ - /* \* -> \\\* */ - /* \ -> \\ */ - p = grub_malloc (len * 2 + 1); - if (! p) - { - need_cleanup = 1; - goto cleanup; - } - - op = p; - while ((ch = *s++)) - { - if (ch == '\\') - { - *op++ = '\\'; - if (*s == '?' || *s == '*') - *op++ = '\\'; - } - *op++ = ch; - } - *op = '\0'; - - need_cleanup = grub_script_argv_append (&result, p, op - p); - grub_free (p); - /* Fall through to cleanup */ - } - else - { - need_cleanup = append (&result, values[i], 1); - /* Fall through to cleanup */ - } - } - -cleanup: - grub_free (values[i]); - } - grub_free (values); - - if (need_cleanup) - goto fail; - - break; - } - - case GRUB_SCRIPT_ARG_TYPE_BLOCK: - { - char *p; - if (grub_script_argv_append (&result, "{", 1)) - goto fail; - p = wildcard_escape (arg->str); - if (!p) - goto fail; - if (grub_script_argv_append (&result, p, - grub_strlen (p))) - { - grub_free (p); - goto fail; - } - grub_free (p); - if (grub_script_argv_append (&result, "}", 1)) - goto fail; - } - result.script = arg->script; - break; - - case GRUB_SCRIPT_ARG_TYPE_TEXT: - if (arg->str[0] && - grub_script_argv_append (&result, arg->str, - grub_strlen (arg->str))) - goto fail; - break; - - case GRUB_SCRIPT_ARG_TYPE_GETTEXT: - { - if (gettext_append (&result, arg->str)) - goto fail; - } - break; - - case GRUB_SCRIPT_ARG_TYPE_DQSTR: - case GRUB_SCRIPT_ARG_TYPE_SQSTR: - if (append (&result, arg->str, 1)) - goto fail; - break; - } - arg = arg->next; - } - } - - if (result.args == NULL || result.argc == 0) - goto fail; - - if (! result.args[result.argc - 1]) - result.argc--; - - /* Perform wildcard expansion. */ - - int j; - int failed = 0; - struct grub_script_argv unexpanded = result; - - result.argc = 0; - result.args = 0; - for (i = 0; unexpanded.args[i]; i++) - { - char **expansions = 0; - if (grub_wildcard_translator - && grub_wildcard_translator->expand (unexpanded.args[i], - &expansions)) - { - grub_script_argv_free (&unexpanded); - goto fail; - } - - if (! expansions) - { - grub_script_argv_next (&result); - append (&result, unexpanded.args[i], -1); - } - else - { - for (j = 0; expansions[j]; j++) - { - failed = (failed || grub_script_argv_next (&result) || - append (&result, expansions[j], 0)); - grub_free (expansions[j]); - } - grub_free (expansions); - - if (failed) - { - grub_script_argv_free (&unexpanded); - goto fail; - } - } - } - grub_script_argv_free (&unexpanded); - - *argv = result; - return 0; - - fail: - - grub_script_argv_free (&result); - return 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; - - recursion_depth++; - - if (recursion_depth >= MAX_RECURSION_DEPTH) - return grub_error (GRUB_ERR_RECURSION_DEPTH, N_("maximum recursion depth exceeded")); - - ret = cmd->exec (cmd); - recursion_depth--; - - grub_snprintf (errnobuf, sizeof (errnobuf), "%d", ret); - grub_env_set ("?", errnobuf); - return ret; -} - -/* Execute a function call. */ -grub_err_t -grub_script_function_call (grub_script_function_t func, int argc, char **args) -{ - grub_err_t ret = 0; - unsigned long loops = active_loops; - struct grub_script_scope *old_scope; - struct grub_script_scope new_scope; - - active_loops = 0; - new_scope.flags = 0; - new_scope.shifts = 0; - new_scope.argv.argc = argc; - new_scope.argv.args = args; - - old_scope = scope; - scope = &new_scope; - - func->executing++; - ret = grub_script_execute (func->func); - func->executing--; - - function_return = 0; - active_loops = loops; - replace_scope (old_scope); /* free any scopes by setparams */ - return ret; -} - -/* Helper for grub_script_execute_sourcecode. */ -static grub_err_t -grub_script_execute_sourcecode_getline (char **line, - int cont __attribute__ ((unused)), - void *data) -{ - const char **source = data; - const 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; -} - -/* Execute a source script. */ -grub_err_t -grub_script_execute_sourcecode (const char *source) -{ - grub_err_t ret = 0; - struct grub_script *parsed_script; - - while (source) - { - char *line; - - grub_script_execute_sourcecode_getline (&line, 0, &source); - parsed_script = grub_script_parse - (line, grub_script_execute_sourcecode_getline, &source); - if (! parsed_script) - { - ret = grub_errno; - grub_free (line); - break; - } - - /* Don't let trailing blank lines determine the return code. */ - if (parsed_script->cmd) - ret = grub_script_execute (parsed_script); - - grub_script_free (parsed_script); - grub_free (line); - } - - return ret; -} - -/* Execute a source script in new scope. */ -grub_err_t -grub_script_execute_new_scope (const char *source, int argc, char **args) -{ - grub_err_t ret = 0; - struct grub_script_scope new_scope; - struct grub_script_scope *old_scope; - - new_scope.argv.argc = argc; - new_scope.argv.args = args; - new_scope.flags = 0; - - old_scope = scope; - scope = &new_scope; - - ret = grub_script_execute_sourcecode (source); - - scope = old_scope; - return ret; -} - -/* 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; - grub_command_t grubcmd; - grub_err_t ret = 0; - grub_script_function_t func = 0; - char errnobuf[18]; - char *cmdname, *cmdstring; - int argc, offset = 0, cmdlen = 0; - unsigned int i; - char **args; - int invert; - struct grub_script_argv argv = { 0, 0, 0 }; - - /* Lookup the command. */ - if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args || ! argv.args[0]) - return grub_errno; - - for (i = 0; i < argv.argc; i++) - { - cmdlen += grub_strlen (argv.args[i]) + 1; - } - - cmdstring = grub_malloc (cmdlen); - if (!cmdstring) - { - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - N_("cannot allocate command buffer")); - } - - for (i = 0; i < argv.argc; i++) - { - offset += grub_snprintf (cmdstring + offset, cmdlen - offset, "%s ", - argv.args[i]); - } - cmdstring[cmdlen - 1] = '\0'; - grub_verify_string (cmdstring, GRUB_VERIFY_COMMAND); - grub_free (cmdstring); - invert = 0; - argc = argv.argc - 1; - args = argv.args + 1; - cmdname = argv.args[0]; - if (grub_strcmp (cmdname, "!") == 0) - { - if (argv.argc < 2 || ! argv.args[1]) - { - grub_script_argv_free (&argv); - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("no command is specified")); - } - - invert = 1; - argc = argv.argc - 2; - args = argv.args + 2; - cmdname = argv.args[1]; - } - 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_script_env_set (assign, eq); - } - grub_free (assign); - - grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno); - grub_script_env_set ("?", errnobuf); - - grub_script_argv_free (&argv); - grub_print_error (); - - return 0; - } - } - - /* Execute the GRUB command or function. */ - if (grubcmd) - { - if (grub_extractor_level && !(grubcmd->flags - & GRUB_COMMAND_FLAG_EXTRACTOR)) - ret = grub_error (GRUB_ERR_EXTRACTOR, - "%s isn't allowed to execute in an extractor", - cmdname); - else if ((grubcmd->flags & GRUB_COMMAND_FLAG_BLOCKS) && - (grubcmd->flags & GRUB_COMMAND_FLAG_EXTCMD)) - ret = grub_extcmd_dispatcher (grubcmd, argc, args, argv.script); - else - ret = (grubcmd->func) (grubcmd, argc, args); - } - else - ret = grub_script_function_call (func, argc, args); - - if (invert) - { - if (ret == GRUB_ERR_TEST_FAILURE) - grub_errno = ret = GRUB_ERR_NONE; - else if (ret == GRUB_ERR_NONE) - ret = grub_error (GRUB_ERR_TEST_FAILURE, N_("false")); - else - { - grub_print_error (); - ret = GRUB_ERR_NONE; - } - } - - /* Free arguments. */ - grub_script_argv_free (&argv); - - 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_cmdlist (struct grub_script_cmd *list) -{ - int ret = 0; - struct grub_script_cmd *cmd; - - /* Loop over every command and execute it. */ - for (cmd = list->next; cmd; cmd = cmd->next) - { - if (active_breaks) - break; - - ret = grub_script_execute_cmd (cmd); - - if (function_return) - break; - } - - return ret; -} - -/* Execute an if statement. */ -grub_err_t -grub_script_execute_cmdif (struct grub_script_cmd *cmd) -{ - int ret; - const char *result; - struct grub_script_cmdif *cmdif = (struct grub_script_cmdif *) cmd; - - /* Check if the commands results in a true or a false. The value is - read from the env variable `?'. */ - ret = grub_script_execute_cmd (cmdif->exec_to_evaluate); - if (function_return) - return ret; - - 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) -{ - unsigned i; - grub_err_t result; - struct grub_script_argv argv = { 0, 0, 0 }; - struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd; - - if (grub_script_arglist_to_argv (cmdfor->words, &argv)) - return grub_errno; - - active_loops++; - result = 0; - for (i = 0; i < argv.argc; i++) - { - if (is_continue && active_breaks == 1) - active_breaks = 0; - - if (! active_breaks) - { - grub_script_env_set (cmdfor->name->str, argv.args[i]); - result = grub_script_execute_cmd (cmdfor->list); - if (function_return) - break; - } - } - - if (active_breaks) - active_breaks--; - - active_loops--; - grub_script_argv_free (&argv); - return result; -} - -/* Execute a "while" or "until" command. */ -grub_err_t -grub_script_execute_cmdwhile (struct grub_script_cmd *cmd) -{ - int result; - struct grub_script_cmdwhile *cmdwhile = (struct grub_script_cmdwhile *) cmd; - - active_loops++; - do { - result = grub_script_execute_cmd (cmdwhile->cond); - if (function_return) - break; - - if (cmdwhile->until ? !result : result) - break; - - result = grub_script_execute_cmd (cmdwhile->list); - if (function_return) - break; - - if (active_breaks == 1 && is_continue) - active_breaks = 0; - - if (active_breaks) - break; - - } while (1); /* XXX Put a check for ^C here */ - - if (active_breaks) - active_breaks--; - - active_loops--; - return result; -} - -/* 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/lexer.c b/grub-core/script/lexer.c deleted file mode 100644 index b6812b66c..000000000 --- a/grub-core/script/lexer.c +++ /dev/null @@ -1,356 +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 . - */ - -#include - -#include -#include -#include -#include -#include -#include - -#define yytext_ptr char * -#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. */ -unsigned -grub_script_lexer_record_start (struct grub_parser_param *parser) -{ - struct grub_lexer_param *lexer = parser->lexerstate; - - lexer->record++; - if (lexer->recording) - return lexer->recordpos; - - lexer->recordpos = 0; - lexer->recordlen = GRUB_LEXER_INITIAL_RECORD_SIZE; - lexer->recording = grub_malloc (lexer->recordlen); - if (!lexer->recording) - { - grub_script_yyerror (parser, 0); - lexer->recordlen = 0; - } - return lexer->recordpos; -} - -char * -grub_script_lexer_record_stop (struct grub_parser_param *parser, unsigned offset) -{ - int count; - char *result; - struct grub_lexer_param *lexer = parser->lexerstate; - - if (!lexer->record) - return 0; - - lexer->record--; - if (!lexer->recording) - return 0; - - count = lexer->recordpos - offset; - result = grub_script_malloc (parser, count + 1); - if (result) { - grub_strncpy (result, lexer->recording + offset, count); - result[count] = '\0'; - } - - if (lexer->record == 0) - { - grub_free (lexer->recording); - lexer->recording = 0; - lexer->recordlen = 0; - lexer->recordpos = 0; - } - return result; -} - -/* 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 || !lexer->recording) - return; - - len = grub_strlen (str); - if (lexer->recordpos + len + 1 > lexer->recordlen) - { - old = lexer->recording; - if (lexer->recordlen < len) - lexer->recordlen = len; - - if (grub_mul (lexer->recordlen, 2, &lexer->recordlen)) - goto fail; - - lexer->recording = grub_realloc (lexer->recording, lexer->recordlen); - if (!lexer->recording) - { - fail: - grub_free (old); - lexer->recordpos = 0; - lexer->recordlen = 0; - grub_script_yyerror (parser, 0); - return; - } - } - grub_strcpy (lexer->recording + lexer->recordpos, str); - lexer->recordpos += len; -} - -/* Read next line of input if necessary, and set yyscanner buffers. */ -int -grub_script_lexer_yywrap (struct grub_parser_param *parserstate, - const char *input) -{ - grub_size_t len = 0, sz; - char *p = 0; - char *line = 0; - YY_BUFFER_STATE buffer; - struct grub_lexer_param *lexerstate = parserstate->lexerstate; - - if (! lexerstate->refs && ! lexerstate->prefix && ! input) - return 1; - - if (! lexerstate->getline && ! input) - { - grub_script_yyerror (parserstate, N_("unexpected end of file")); - return 1; - } - - line = 0; - if (! input) - lexerstate->getline (&line, 1, lexerstate->getline_data); - else - line = grub_strdup (input); - - if (! line) - { - grub_script_yyerror (parserstate, N_("out of memory")); - return 1; - } - - len = grub_strlen (line); - - /* Ensure '\n' at the end. */ - if (line[0] == '\0') - { - grub_free (line); - line = grub_strdup ("\n"); - len = 1; - } - else if (len && line[len - 1] != '\n') - { - if (grub_add (len, 2, &sz)) - { - grub_free (line); - grub_script_yyerror (parserstate, N_("overflow is detected")); - return 1; - } - - p = grub_realloc (line, sz); - if (p) - { - p[len++] = '\n'; - p[len] = '\0'; - } - else - grub_free (line); - - line = p; - } - - if (! line) - { - grub_script_yyerror (parserstate, N_("out of memory")); - return 1; - } - - /* Prepend any left over unput-text. */ - if (lexerstate->prefix) - { - int plen = grub_strlen (lexerstate->prefix); - - p = grub_malloc (len + plen + 1); - if (! p) - { - grub_free (line); - return 1; - } - grub_strcpy (p, lexerstate->prefix); - lexerstate->prefix = 0; - - grub_strcpy (p + plen, line); - grub_free (line); - - line = p; - len = len + plen; - } - - buffer = yy_scan_string (line, lexerstate->yyscanner); - grub_free (line); - - if (! buffer) - { - grub_script_yyerror (parserstate, 0); - return 1; - } - return 0; -} - -struct grub_lexer_param * -grub_script_lexer_init (struct grub_parser_param *parser, char *script, - grub_reader_getline_t arg_getline, void *getline_data) -{ - 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 = arg_getline; - lexerstate->getline_data = getline_data; - /* The other elements of lexerstate are all zeros already. */ - - if (yylex_init (&lexerstate->yyscanner)) - { - grub_free (lexerstate->text); - grub_free (lexerstate); - return 0; - } - - yyset_extra (parser, lexerstate->yyscanner); - parser->lexerstate = lexerstate; - - if (grub_script_lexer_yywrap (parser, script ?: "\n")) - { - parser->lexerstate = 0; - yylex_destroy (lexerstate->yyscanner); - grub_free (lexerstate->text); - grub_free (lexerstate); - return 0; - } - - 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, const char *err) -{ - if (err) - grub_error (GRUB_ERR_INVALID_COMMAND, "%s", err); - - grub_print_error (); - state->err++; -} diff --git a/grub-core/script/main.c b/grub-core/script/main.c deleted file mode 100644 index 854a25a06..000000000 --- a/grub-core/script/main.c +++ /dev/null @@ -1,98 +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 . - */ - -#include -#include -#include -#include - -grub_err_t -grub_normal_parse_line (char *line, - grub_reader_getline_t getline, void *getline_data) -{ - struct grub_script *parsed_script; - - /* Parse the script. */ - parsed_script = grub_script_parse (line, getline, getline_data); - - if (parsed_script) - { - /* Execute the command(s). */ - grub_script_execute (parsed_script); - - /* The parsed script was executed, throw it away. */ - grub_script_unref (parsed_script); - } - - return grub_errno; -} - -static grub_command_t cmd_break; -static grub_command_t cmd_continue; -static grub_command_t cmd_shift; -static grub_command_t cmd_setparams; -static grub_command_t cmd_return; - -void -grub_script_init (void) -{ - cmd_break = grub_register_command ("break", grub_script_break, - N_("[NUM]"), N_("Exit from loops")); - cmd_continue = grub_register_command ("continue", grub_script_break, - N_("[NUM]"), N_("Continue loops")); - cmd_shift = grub_register_command ("shift", grub_script_shift, - N_("[NUM]"), - /* TRANSLATORS: Positional arguments are - arguments $0, $1, $2, ... */ - N_("Shift positional parameters.")); - cmd_setparams = grub_register_command ("setparams", grub_script_setparams, - N_("[VALUE]..."), - N_("Set positional parameters.")); - cmd_return = grub_register_command ("return", grub_script_return, - N_("[NUM]"), - /* TRANSLATORS: It's a command description - and "Return" is a verb, not a noun. The - command in question is "return" and - has exactly the same semanics as bash - equivalent. */ - N_("Return from a function.")); -} - -void -grub_script_fini (void) -{ - if (cmd_break) - grub_unregister_command (cmd_break); - cmd_break = 0; - - if (cmd_continue) - grub_unregister_command (cmd_continue); - cmd_continue = 0; - - if (cmd_shift) - grub_unregister_command (cmd_shift); - cmd_shift = 0; - - if (cmd_setparams) - grub_unregister_command (cmd_setparams); - cmd_setparams = 0; - - if (cmd_return) - grub_unregister_command (cmd_return); - cmd_return = 0; -} diff --git a/grub-core/script/parser.y b/grub-core/script/parser.y deleted file mode 100644 index 4a18ab7ba..000000000 --- a/grub-core/script/parser.y +++ /dev/null @@ -1,356 +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 . - */ - -%{ -#include -#include -#include -#include - -#define YYFREE grub_free -#define YYMALLOC grub_malloc -#define YYLTYPE_IS_TRIVIAL 0 -#define YYENABLE_NLS 0 - -#include "grub_script.tab.h" - -#pragma GCC diagnostic ignored "-Wmissing-declarations" - -%} - -%union { - struct grub_script_cmd *cmd; - struct grub_script_arglist *arglist; - struct grub_script_arg *arg; - char *string; - struct { - unsigned offset; - struct grub_script_mem *memory; - struct grub_script *scripts; - }; -} - -%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 GRUB_PARSER_TOKEN_CASE "case" -%token GRUB_PARSER_TOKEN_DO "do" -%token GRUB_PARSER_TOKEN_DONE "done" -%token GRUB_PARSER_TOKEN_ELIF "elif" -%token GRUB_PARSER_TOKEN_ELSE "else" -%token GRUB_PARSER_TOKEN_ESAC "esac" -%token GRUB_PARSER_TOKEN_FI "fi" -%token GRUB_PARSER_TOKEN_FOR "for" -%token GRUB_PARSER_TOKEN_IF "if" -%token GRUB_PARSER_TOKEN_IN "in" -%token GRUB_PARSER_TOKEN_SELECT "select" -%token GRUB_PARSER_TOKEN_THEN "then" -%token GRUB_PARSER_TOKEN_UNTIL "until" -%token GRUB_PARSER_TOKEN_WHILE "while" -%token GRUB_PARSER_TOKEN_FUNCTION "function" -%token GRUB_PARSER_TOKEN_NAME "name" -%token GRUB_PARSER_TOKEN_WORD "word" - -%type block block0 -%type word argument arguments0 arguments1 - -%type script_init script -%type grubcmd ifclause ifcmd forcmd whilecmd untilcmd -%type command commands1 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 - { - $$ = grub_script_append_cmd (state, $1, $2); - } - | error - { - $$ = 0; - yyerror (state, N_("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; } -; - -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); } - | word { $$ = $1; } -; - -/* - Block parameter is passed to commands in two forms: as unparsed - string and as pre-parsed grub_script object. Passing as grub_script - object makes memory management difficult, because: - - (1) Command may want to keep a reference to grub_script objects for - later use, so script framework may not free the grub_script - object after command completes. - - (2) Command may get called multiple times with same grub_script - object under loops, so we should not let command implementation - to free the grub_script object. - - To solve above problems, we rely on reference counting for - grub_script objects. Commands that want to keep the grub_script - object must take a reference to it. - - Other complexity comes with arbitrary nesting of grub_script - objects: a grub_script object may have commands with several block - parameters, and each block parameter may further contain multiple - block parameters nested. We use temporary variable, state->scripts - to collect nested child scripts (that are linked by siblings and - children members), and will build grub_scripts tree from bottom. - */ -block: "{" - { - grub_script_lexer_ref (state->lexerstate); - $$ = grub_script_lexer_record_start (state); - $$ = grub_script_mem_record (state); - - /* save currently known scripts. */ - $$ = state->scripts; - state->scripts = 0; - } - commands1 delimiters0 "}" - { - char *p; - struct grub_script_mem *memory; - struct grub_script *s = $2; - - memory = grub_script_mem_record_stop (state, $2); - if ((p = grub_script_lexer_record_stop (state, $2))) - *grub_strrchr (p, '}') = '\0'; - - $$ = grub_script_arg_add (state, 0, GRUB_SCRIPT_ARG_TYPE_BLOCK, p); - if (! $$ || ! ($$->script = grub_script_create ($3, memory))) - grub_script_mem_free (memory); - - else { - /* attach nested scripts to $$->script as children */ - $$->script->children = state->scripts; - - /* restore old scripts; append $$->script to siblings. */ - state->scripts = $2 ?: $$->script; - if (s) { - while (s->next_siblings) - s = s->next_siblings; - s->next_siblings = $$->script; - } - } - - grub_script_lexer_deref (state->lexerstate); - } -; -block0: /* Empty */ { $$ = 0; } - | block { $$ = $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 block0 - { - struct grub_script_arglist *x = $2; - - if ($3) - x = grub_script_add_arglist (state, $2, $3); - - if ($1 && x) { - $1->next = x; - $1->argcount += x->argcount; - x->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_append_cmd (state, 0, $2); - } - | commands1 delimiters1 command - { - $$ = grub_script_append_cmd (state, $1, $3); - } -; - -function: "function" "name" - { - grub_script_lexer_ref (state->lexerstate); - state->func_mem = grub_script_mem_record (state); - - $$ = state->scripts; - state->scripts = 0; - } - newlines0 "{" 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_mem_free (state->func_mem); - else { - script->children = state->scripts; - if (!grub_script_function_create ($2, script)) - grub_script_free (script); - } - - state->scripts = $3; - grub_script_lexer_deref (state->lexerstate); - } -; - -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/yylex.l b/grub-core/script/yylex.l deleted file mode 100644 index b7203c823..000000000 --- a/grub-core/script/yylex.l +++ /dev/null @@ -1,393 +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 . - */ - -#include -#include -#include -#include -#include -#include "grub_script.tab.h" - -#pragma GCC diagnostic ignored "-Wunused-parameter" -#pragma GCC diagnostic ignored "-Wmissing-prototypes" -#pragma GCC diagnostic ignored "-Wmissing-declarations" -#pragma GCC diagnostic ignored "-Wunused-function" -#pragma GCC diagnostic ignored "-Wsign-compare" - -#define yyalloc(size, scanner) (grub_malloc((size))) -#define yyfree(ptr, scanner) (grub_free((ptr))) -#define yyrealloc(ptr, size, scanner) (grub_realloc((ptr), (size))) - -/* - * As we don't have access to yyscanner, we cannot do much except to - * print the fatal error and exit. - */ -#define YY_FATAL_ERROR(msg) \ - do { \ - grub_fatal (_("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 int grub_lexer_unput (const char *input, yyscan_t yyscanner); -static int grub_lexer_resplit (const char *input, yyscan_t yyscanner); - -static void copy_string (struct grub_parser_param *, const char *, - unsigned hint); - -%} - -%top{ - -#include - -#include - -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(...) (void)0 -#define exit(...) grub_fatal("fatal error in lexer") -#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 - -/* 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:]_]* - -ESC \\(.|\n) -SQCHR [^\'] -DQCHR {ESC}|[^\\\"] -DQSTR \"{DQCHR}*\" -I18NSTR \$\"{DQCHR}*\" -SQSTR \'{SQCHR}*\' -SPECIAL \?|\#|\*|\@ -VARIABLE ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|${SPECIAL}|$\{{SPECIAL}\} -WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE}|{I18NSTR})+ - -MULTILINE {WORD}?((\"{DQCHR}*)|(\$\"{DQCHR}*)|(\'{SQCHR}*)) -POS_MULTILINE {WORD}?\\\n - -%x SPLIT -%x DQUOTE -%x I18NQUOTE -%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_LBR; } -"}" { RECORD; return GRUB_PARSER_TOKEN_RBR; } -"[[" { RECORD; return GRUB_PARSER_TOKEN_LSQBR2; } -"]]" { RECORD; return GRUB_PARSER_TOKEN_RSQBR2; } -"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; } - -{MULTILINE} { - if (grub_lexer_unput (yytext, yyscanner)) - return GRUB_PARSER_TOKEN_BAD; - } - -{POS_MULTILINE} { - if (yyg->yy_c_buf_p + 1 == &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) - { - if (grub_lexer_unput (yytext, yyscanner)) - return GRUB_PARSER_TOKEN_BAD; - } - else - { - RECORD; - yypush_buffer_state (YY_CURRENT_BUFFER, yyscanner); - if (grub_lexer_resplit (yytext, yyscanner)) - { - yypop_buffer_state (yyscanner); - return GRUB_PARSER_TOKEN_WORD; - } - yyextra->lexerstate->resplit = 1; - } - } - - -{NAME} { RECORD; return GRUB_PARSER_TOKEN_NAME; } -{WORD} { - RECORD; - yypush_buffer_state (YY_CURRENT_BUFFER, yyscanner); - if (grub_lexer_resplit (yytext, yyscanner)) - { - yypop_buffer_state (yyscanner); - return GRUB_PARSER_TOKEN_WORD; - } - yyextra->lexerstate->resplit = 1; - } -. { - grub_script_yyerror (yyextra, yytext); - return GRUB_PARSER_TOKEN_BAD; - } - - /* Split word into multiple args */ - -{ - \\. { COPY (yytext, yyleng); } - \\\n { /* ignore */ } - \" { - 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 (I18NQUOTE, yyscanner); - ARG (GRUB_SCRIPT_ARG_TYPE_GETTEXT); - } - \$ { - yy_push_state (VAR, yyscanner); - ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); - } - \\ | - [^\"\'\$\\]+ { COPY (yytext, yyleng); } - <> { - yy_pop_state (yyscanner); - yypop_buffer_state (yyscanner); - yyextra->lexerstate->resplit = 0; - yyextra->lexerstate->merge_end = 1; - ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); - } -} - -{ - {SPECIAL} | - {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); - } - \{{SPECIAL}\} | - \{{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; } -} - -{ - \' { - yy_pop_state (yyscanner); - ARG (GRUB_SCRIPT_ARG_TYPE_SQSTR); - } - [^\']+ { COPY (yytext, yyleng); } -} - -{ - \\\$ { 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); } -} - -{ - \\\\ { COPY ("\\\\", 2); } - \\\" { COPY ("\"", 1); } - \\\n { /* ignore */ } - [^\"\\\n]+ { COPY (yytext, yyleng); } - \" { - yy_pop_state (yyscanner); - ARG (GRUB_SCRIPT_ARG_TYPE_GETTEXT); - } - \\ { COPY ("\\", 1); } - (.|\n) { COPY (yytext, yyleng); } -} - -<> { - yypop_buffer_state (yyscanner); - yyextra->lexerstate->eof = 1; - return GRUB_PARSER_TOKEN_EOF; - } -%% - -int -yywrap (yyscan_t yyscanner) -{ - if (yyget_extra (yyscanner)->lexerstate->resplit) - return 1; - - return grub_script_lexer_yywrap (yyget_extra (yyscanner), 0); -} - -static void copy_string (struct grub_parser_param *parser, const char *str, unsigned hint) -{ - grub_size_t size; - char *ptr; - unsigned len; - - len = hint ? hint : grub_strlen (str); - if (parser->lexerstate->used + len >= parser->lexerstate->size) - { - size = len * 2; - if (size < parser->lexerstate->size * 2) - size = 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; -} - -static int -grub_lexer_resplit (const char *text, yyscan_t yyscanner) -{ - /* resplit text */ - if (yy_scan_string (text, yyscanner)) - { - yyget_extra (yyscanner)->lexerstate->merge_start = 1; - yy_push_state (SPLIT, yyscanner); - return 0; - } - grub_script_yyerror (yyget_extra (yyscanner), 0); - return 1; -} - -static int -grub_lexer_unput (const char *text, yyscan_t yyscanner) -{ - struct grub_lexer_param *lexerstate = yyget_extra (yyscanner)->lexerstate; - - grub_free (lexerstate->prefix); - - lexerstate->prefix = grub_strdup (text); - if (! lexerstate->prefix) - { - grub_script_yyerror (yyget_extra (yyscanner), N_("out of memory")); - return 1; - } - return 0; -} diff --git a/grub-core/term/arc/console.c b/grub-core/term/arc/console.c deleted file mode 100644 index 5591cb0e2..000000000 --- a/grub-core/term/arc/console.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -/* FIXME: use unicode. */ - -static int -readkey (struct grub_term_input *term __attribute__ ((unused))) -{ - unsigned long count; - char chr; - - if (GRUB_ARC_FIRMWARE_VECTOR->get_read_status (GRUB_ARC_STDIN)) - return -1; - - if (GRUB_ARC_FIRMWARE_VECTOR->read (GRUB_ARC_STDIN, &chr, 1, &count)) - return -1; - if (!count) - return -1; - return chr; -} - -static void -put (struct grub_term_output *term __attribute__ ((unused)), const int c) -{ - unsigned long count; - char chr = c; - - GRUB_ARC_FIRMWARE_VECTOR->write (GRUB_ARC_STDOUT, &chr, 1, &count); -} - -static struct grub_terminfo_output_state grub_console_terminfo_output; - -int -grub_arc_is_device_serial (const char *name, int alt_names) -{ - if (name[0] == '\0') - return 0; - - const char *ptr = name + grub_strlen (name) - 1; - int i; - /* - Recognize: - serial(N) - serial(N)line(M) - */ - for (i = 0; i < 2; i++) - { - if (!alt_names) - { - if (*ptr != ')') - return 0; - ptr--; - } - for (; ptr >= name && grub_isdigit (*ptr); ptr--); - if (ptr < name) - return 0; - if (!alt_names) - { - if (*ptr != '(') - return 0; - ptr--; - } - if (ptr + 1 >= name + sizeof ("serial") - 1 - && grub_memcmp (ptr + 1 - (sizeof ("serial") - 1), - "serial", sizeof ("serial") - 1) == 0) - return 1; - if (!(ptr + 1 >= name + sizeof ("line") - 1 - && grub_memcmp (ptr + 1 - (sizeof ("line") - 1), - "line", sizeof ("line") - 1) == 0)) - return 0; - ptr -= sizeof ("line") - 1; - if (alt_names) - { - if (*ptr != '/') - return 0; - ptr--; - } - } - return 0; -} - -static int -check_is_serial (void) -{ - static int is_serial = -1; - - if (is_serial != -1) - return is_serial; - - const char *consout = 0; - - /* Check for serial. It works unless user manually overrides ConsoleOut - variable. If he does there is nothing we can do. Fortunately failure - isn't critical. - */ - if (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmware_vector_length - >= (unsigned) ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable + 1) - - (char *) GRUB_ARC_FIRMWARE_VECTOR) - && GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable) - consout = GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable ("ConsoleOut"); - if (!consout) - return is_serial = 0; - return is_serial = grub_arc_is_device_serial (consout, 0); -} - -static void -set_console_dimensions (void) -{ - struct grub_arc_display_status *info = NULL; - - if (check_is_serial ()) - { - grub_console_terminfo_output.size.x = 80; - grub_console_terminfo_output.size.y = 24; - return; - } - - if (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmware_vector_length - >= (unsigned) ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus + 1) - - (char *) GRUB_ARC_FIRMWARE_VECTOR) - && GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus) - info = GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus (GRUB_ARC_STDOUT); - if (info) - { - grub_console_terminfo_output.size.x = info->w + 1; - grub_console_terminfo_output.size.y = info->h + 1; - } -} - -static grub_err_t -grub_console_init_output (struct grub_term_output *term) -{ - set_console_dimensions (); - grub_terminfo_output_init (term); - - return 0; -} - -static struct grub_terminfo_input_state grub_console_terminfo_input = - { - .readkey = readkey - }; - -static struct grub_terminfo_output_state grub_console_terminfo_output = - { - .put = put, - .size = { 80, 20 } - }; - -static struct grub_term_input grub_console_term_input = - { - .name = "console", - .init = grub_terminfo_input_init, - .getkey = grub_terminfo_getkey, - .data = &grub_console_terminfo_input - }; - -static struct grub_term_output grub_console_term_output = - { - .name = "console", - .init = grub_console_init_output, - .putchar = grub_terminfo_putchar, - .getxy = grub_terminfo_getxy, - .getwh = grub_terminfo_getwh, - .gotoxy = grub_terminfo_gotoxy, - .cls = grub_terminfo_cls, - .setcolorstate = grub_terminfo_setcolorstate, - .setcursor = grub_terminfo_setcursor, - .flags = GRUB_TERM_CODE_TYPE_ASCII, - .data = &grub_console_terminfo_output, - .progress_update_divisor = GRUB_PROGRESS_FAST - }; - -void -grub_console_init_early (void) -{ - grub_term_register_input ("console", &grub_console_term_input); - grub_term_register_output ("console", &grub_console_term_output); -} - -void -grub_console_init_lately (void) -{ - grub_terminfo_init (); - if (check_is_serial ()) - grub_terminfo_output_register (&grub_console_term_output, "vt100"); - else - grub_terminfo_output_register (&grub_console_term_output, "arc"); -} diff --git a/grub-core/term/arc/serial.c b/grub-core/term/arc/serial.c deleted file mode 100644 index 487aa1b30..000000000 --- a/grub-core/term/arc/serial.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -static void -do_real_config (struct grub_serial_port *port) -{ - char *name; - if (port->configured) - return; - - name = grub_arc_alt_name_to_norm (port->name, ""); - - if (GRUB_ARC_FIRMWARE_VECTOR->open (name,GRUB_ARC_FILE_ACCESS_OPEN_RW, - &port->handle)) - port->handle_valid = 0; - else - port->handle_valid = 1; - - port->configured = 1; -} - -/* Fetch a key. */ -static int -serial_hw_fetch (struct grub_serial_port *port) -{ - unsigned long actual; - char c; - - do_real_config (port); - - if (!port->handle_valid) - return -1; - if (GRUB_ARC_FIRMWARE_VECTOR->read (port->handle, &c, - 1, &actual) || actual <= 0) - return -1; - return c; -} - -/* Put a character. */ -static void -serial_hw_put (struct grub_serial_port *port, const int c) -{ - unsigned long actual; - char c0 = c; - - do_real_config (port); - - if (!port->handle_valid) - return; - - GRUB_ARC_FIRMWARE_VECTOR->write (port->handle, &c0, - 1, &actual); -} - -/* 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_configure (struct grub_serial_port *port __attribute__ ((unused)), - struct grub_serial_config *config __attribute__ ((unused))) -{ - /* FIXME: no ARC serial config available. */ - - return GRUB_ERR_NONE; -} - -struct grub_serial_driver grub_arcserial_driver = - { - .configure = serial_hw_configure, - .fetch = serial_hw_fetch, - .put = serial_hw_put - }; - -struct grub_serial_port * -grub_arcserial_add_port (const char *path) -{ - struct grub_serial_port *port; - grub_err_t err; - - FOR_SERIAL_PORTS (port) - if (grub_strcmp(path, port->name) == 0) - return port; - - port = grub_zalloc (sizeof (*port)); - if (!port) - return NULL; - port->name = grub_strdup (path); - if (!port->name) - return NULL; - - port->driver = &grub_arcserial_driver; - err = grub_serial_config_defaults (port); - if (err) - grub_print_error (); - - grub_serial_register (port); - - return port; -} - -static int -dev_iterate (const char *name, - const struct grub_arc_component *comp __attribute__ ((unused)), - void *data __attribute__ ((unused))) -{ - /* We should check consolein/consoleout flags as - well but some implementations are buggy. */ - if ((comp->flags & (GRUB_ARC_COMPONENT_FLAG_IN | GRUB_ARC_COMPONENT_FLAG_OUT)) - != (GRUB_ARC_COMPONENT_FLAG_IN | GRUB_ARC_COMPONENT_FLAG_OUT)) - return 0; - if (!grub_arc_is_device_serial (name, 1)) - return 0; - grub_arcserial_add_port (name); - return 0; -} - -void -grub_arcserial_init (void) -{ - grub_arc_iterate_devs (dev_iterate, 0, 1); -} - diff --git a/grub-core/term/arm/cros.c b/grub-core/term/arm/cros.c deleted file mode 100644 index a17e49c32..000000000 --- a/grub-core/term/arm/cros.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * - * Copyright (C) 2012 Google Inc. - * Copyright (C) 2016 Free Software Foundation, Inc. - * - * This is based on depthcharge code. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct grub_ps2_state ps2_state; - -struct grub_cros_ec_keyscan old_scan; - -static const struct grub_fdtbus_dev *cros_ec; - -static grub_uint8_t map_code[GRUB_CROS_EC_KEYSCAN_COLS][GRUB_CROS_EC_KEYSCAN_ROWS]; - -static grub_uint8_t e0_translate[16] = - { - 0x1c, 0x1d, 0x35, 0x00, - 0x38, 0x00, 0x47, 0x48, - 0x49, 0x4b, 0x4d, 0x4f, - 0x50, 0x51, 0x52, 0x53, - }; - -/* If there is a character pending, return it; - otherwise return GRUB_TERM_NO_KEY. */ -static int -grub_cros_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) -{ - struct grub_cros_ec_keyscan scan; - int i, j; - if (grub_cros_ec_scan_keyboard (cros_ec, &scan) < 0) - return GRUB_TERM_NO_KEY; - for (i = 0; i < GRUB_CROS_EC_KEYSCAN_COLS; i++) - if (scan.data[i] ^ old_scan.data[i]) - for (j = 0; j < GRUB_CROS_EC_KEYSCAN_ROWS; j++) - if ((scan.data[i] ^ old_scan.data[i]) & (1 << j)) - { - grub_uint8_t code = map_code[i][j]; - int ret; - grub_uint8_t brk = 0; - if (!(scan.data[i] & (1 << j))) - brk = 0x80; - grub_dprintf ("cros_keyboard", "key <%d, %d> code %x\n", i, j, code); - if (code < 0x60) - ret = grub_ps2_process_incoming_byte (&ps2_state, code | brk); - else if (code >= 0x60 && code < 0x70 && e0_translate[code - 0x60]) - { - grub_ps2_process_incoming_byte (&ps2_state, 0xe0); - ret = grub_ps2_process_incoming_byte (&ps2_state, e0_translate[code - 0x60] | brk); - } - else - ret = GRUB_TERM_NO_KEY; - old_scan.data[i] ^= (1 << j); - if (ret != GRUB_TERM_NO_KEY) - return ret; - } - return GRUB_TERM_NO_KEY; -} - -static struct grub_term_input grub_cros_keyboard_term = - { - .name = "cros_keyboard", - .getkey = grub_cros_keyboard_getkey - }; - -static grub_err_t -cros_attach (const struct grub_fdtbus_dev *dev) -{ - grub_size_t keymap_size, i; - const grub_uint8_t *keymap = grub_fdtbus_get_prop (dev, "linux,keymap", &keymap_size); - - if (!dev->parent || !grub_cros_ec_validate (dev->parent)) - return GRUB_ERR_IO; - - if (keymap) - { - for (i = 0; i + 3 < keymap_size; i += 4) - if (keymap[i+1] < GRUB_CROS_EC_KEYSCAN_COLS && keymap[i] < GRUB_CROS_EC_KEYSCAN_ROWS - && keymap[i+2] == 0 && keymap[i+3] < 0x80) - map_code[keymap[i+1]][keymap[i]] = keymap[i+3]; - } - - cros_ec = dev->parent; - ps2_state.current_set = 1; - ps2_state.at_keyboard_status = 0; - grub_term_register_input ("cros_keyboard", &grub_cros_keyboard_term); - return GRUB_ERR_NONE; -} - -static struct grub_fdtbus_driver cros = -{ - .compatible = "google,cros-ec-keyb", - .attach = cros_attach -}; - -void -grub_cros_init (void) -{ - grub_fdtbus_register (&cros); -} diff --git a/grub-core/term/arm/cros_ec.c b/grub-core/term/arm/cros_ec.c deleted file mode 100644 index f4144818b..000000000 --- a/grub-core/term/arm/cros_ec.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * - * Copyright (C) 2012 Google Inc. - * Copyright (C) 2016 Free Software Foundation, Inc. - * - * This is based on depthcharge code. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include - -static const grub_uint64_t FRAMING_TIMEOUT_MS = 300; - -static const grub_uint8_t EC_FRAMING_BYTE = 0xec; - -#define EC_CMD_MKBP_STATE 0x60 -#define EC_CMD_VERSION0 0xdc - -static grub_uint64_t last_transfer; - -static void -stop_bus (const struct grub_fdtbus_dev *spi) -{ - spi->driver->stop (spi); - last_transfer = grub_get_time_ms (); -} - -static int -wait_for_frame (const struct grub_fdtbus_dev *spi) -{ - grub_uint64_t start = grub_get_time_ms (); - grub_uint8_t byte; - do - { - if (spi->driver->receive (spi, &byte, 1)) - return -1; - if (byte != EC_FRAMING_BYTE && - grub_get_time_ms () - start > FRAMING_TIMEOUT_MS) - { - grub_dprintf ("cros", "Timeout waiting for framing byte.\n"); - return -1; - } - } - while (byte != EC_FRAMING_BYTE); - return 0; -} - -/* - * Calculate a simple 8-bit checksum of a data block - * - * @param data Data block to checksum - * @param size Size of data block in bytes - * @return checksum value (0 to 255) - */ -static grub_uint8_t -cros_ec_calc_checksum (const void *data, int size) -{ - grub_uint8_t csum; - const grub_uint8_t *bytes = data; - int i; - - for (i = csum = 0; i < size; i++) - csum += bytes[i]; - return csum & 0xff; -} - -enum -{ - /* response, arglen */ - CROS_EC_SPI_IN_HDR_SIZE = 2, - /* version, cmd, arglen */ - CROS_EC_SPI_OUT_HDR_SIZE = 3 -}; - -static grub_uint8_t busbuf[256]; -#define MSG_BYTES ((int)sizeof (busbuf)) - -static int -ec_command (const struct grub_fdtbus_dev *dev, int cmd, int cmd_version, - const void *dout, int dout_len, void *din, int din_len) -{ - const struct grub_fdtbus_dev *spi = dev->parent; - grub_uint8_t *bytes; - - /* Header + data + checksum. */ - grub_uint32_t out_bytes = CROS_EC_SPI_OUT_HDR_SIZE + dout_len + 1; - grub_uint32_t in_bytes = CROS_EC_SPI_IN_HDR_SIZE + din_len + 1; - - /* - * Sanity-check I/O sizes given transaction overhead in internal - * buffers. - */ - if (out_bytes > MSG_BYTES) - { - grub_dprintf ("cros", "Cannot send %d bytes\n", dout_len); - return -1; - } - if (in_bytes > MSG_BYTES) - { - grub_dprintf ("cros", "Cannot receive %d bytes\n", din_len); - return -1; - } - - /* Prepare the output. */ - bytes = busbuf; - *bytes++ = EC_CMD_VERSION0 + cmd_version; - *bytes++ = cmd; - *bytes++ = dout_len; - grub_memcpy (bytes, dout, dout_len); - bytes += dout_len; - - *bytes++ = cros_ec_calc_checksum (busbuf, - CROS_EC_SPI_OUT_HDR_SIZE + dout_len); - - /* Depthcharge uses 200 us here but GRUB timer resolution is only 1ms, - decrease this when we increase timer resolution. */ - while (grub_get_time_ms () - last_transfer < 1) - ; - - if (spi->driver->start (spi)) - return -1; - - /* Allow EC to ramp up clock after being awoken. */ - /* Depthcharge only waits 100 us here but GRUB timer resolution is only 1ms, - decrease this when we increase timer resolution. */ - grub_millisleep (1); - - if (spi->driver->send (spi, busbuf, out_bytes)) - { - stop_bus (spi); - return -1; - } - - /* Wait until the EC is ready. */ - if (wait_for_frame (spi)) - { - stop_bus (spi); - return -1; - } - - /* Read the response code and the data length. */ - bytes = busbuf; - if (spi->driver->receive (spi, bytes, 2)) - { - stop_bus (spi); - return -1; - } - grub_uint8_t result = *bytes++; - grub_uint8_t length = *bytes++; - - /* Make sure there's enough room for the data. */ - if (CROS_EC_SPI_IN_HDR_SIZE + length + 1 > MSG_BYTES) - { - grub_dprintf ("cros", "Received length %#02x too large\n", length); - stop_bus (spi); - return -1; - } - - /* Read the data and the checksum, and finish up. */ - if (spi->driver->receive (spi, bytes, length + 1)) - { - stop_bus (spi); - return -1; - } - bytes += length; - int expected = *bytes++; - stop_bus (spi); - - /* Check the integrity of the response. */ - if (result != 0) - { - grub_dprintf ("cros", "Received bad result code %d\n", result); - return -result; - } - - int csum = cros_ec_calc_checksum (busbuf, - CROS_EC_SPI_IN_HDR_SIZE + length); - - if (csum != expected) - { - grub_dprintf ("cros", "Invalid checksum rx %#02x, calced %#02x\n", - expected, csum); - return -1; - } - - /* If the caller wants the response, copy it out for them. */ - if (length < din_len) - din_len = length; - if (din) - { - grub_memcpy (din, (grub_uint8_t *) busbuf + CROS_EC_SPI_IN_HDR_SIZE, din_len); - } - - return din_len; -} - -int -grub_cros_ec_scan_keyboard (const struct grub_fdtbus_dev *dev, struct grub_cros_ec_keyscan *scan) -{ - if (ec_command (dev, EC_CMD_MKBP_STATE, 0, NULL, 0, scan, - sizeof (*scan)) < (int) sizeof (*scan)) - return -1; - - return 0; -} - -int -grub_cros_ec_validate (const struct grub_fdtbus_dev *dev) -{ - if (!grub_fdtbus_is_compatible("google,cros-ec-spi", dev)) - return 0; - if (!dev->parent) - return 0; - if (!dev->parent->driver) - return 0; - if (!dev->parent->driver->send - || !dev->parent->driver->receive) - return 0; - return 1; -} - diff --git a/grub-core/term/arm/pl050.c b/grub-core/term/arm/pl050.c deleted file mode 100644 index b082243b0..000000000 --- a/grub-core/term/arm/pl050.c +++ /dev/null @@ -1,189 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static volatile grub_uint32_t *pl050_regs; - -static struct grub_ps2_state ps2_state; - -static void -keyboard_controller_wait_until_ready (void) -{ - while (! (pl050_regs[1] & 0x40)); -} - -static grub_uint8_t -wait_ack (void) -{ - grub_uint64_t endtime; - grub_uint8_t ack; - - endtime = grub_get_time_ms () + 20; - do - ack = pl050_regs[2]; - while (ack != GRUB_AT_ACK && ack != GRUB_AT_NACK - && grub_get_time_ms () < endtime); - return ack; -} - - -static int -write_mode (int mode) -{ - unsigned i; - for (i = 0; i < GRUB_AT_TRIES; i++) - { - grub_uint8_t ack; - keyboard_controller_wait_until_ready (); - pl050_regs[2] = 0xf0; - keyboard_controller_wait_until_ready (); - pl050_regs[2] = mode; - keyboard_controller_wait_until_ready (); - ack = wait_ack (); - if (ack == GRUB_AT_NACK) - continue; - if (ack == GRUB_AT_ACK) - break; - return 0; - } - - return (i != GRUB_AT_TRIES); -} - -static int -query_mode (void) -{ - grub_uint8_t ret; - int e; - - e = write_mode (0); - if (!e) - return 0; - - keyboard_controller_wait_until_ready (); - - do - ret = pl050_regs[2]; - while (ret == GRUB_AT_ACK); - - /* QEMU translates the set even in no-translate mode. */ - if (ret == 0x43 || ret == 1) - return 1; - if (ret == 0x41 || ret == 2) - return 2; - if (ret == 0x3f || ret == 3) - return 3; - return 0; -} - -static void -set_scancodes (void) -{ - write_mode (2); - ps2_state.current_set = query_mode (); - grub_dprintf ("atkeyb", "returned set %d\n", ps2_state.current_set); - if (ps2_state.current_set == 2) - return; - - write_mode (1); - ps2_state.current_set = query_mode (); - grub_dprintf ("atkeyb", "returned set %d\n", ps2_state.current_set); - if (ps2_state.current_set == 1) - return; - grub_dprintf ("atkeyb", "no supported scancode set found\n"); -} - -static void -keyboard_controller_led (grub_uint8_t leds) -{ - keyboard_controller_wait_until_ready (); - pl050_regs[2] = 0xed; - keyboard_controller_wait_until_ready (); - pl050_regs[2] = leds & 0x7; -} - -/* If there is a character pending, return it; - otherwise return GRUB_TERM_NO_KEY. */ -static int -grub_pl050_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) -{ - grub_uint8_t at_key; - int ret; - grub_uint8_t old_led; - - if (!(pl050_regs[1] & 0x10)) - return -1; - at_key = pl050_regs[2]; - old_led = ps2_state.led_status; - - ret = grub_ps2_process_incoming_byte (&ps2_state, at_key); - if (old_led != ps2_state.led_status) - keyboard_controller_led (ps2_state.led_status); - return ret; -} - -static struct grub_term_input grub_pl050_keyboard_term = - { - .name = "pl050_keyboard", - .getkey = grub_pl050_keyboard_getkey - }; - -static grub_err_t -pl050_attach(const struct grub_fdtbus_dev *dev) -{ - const grub_uint32_t *reg; - reg = grub_fdtbus_get_prop (dev, "reg", 0); - - /* Mouse. Nothing to do. */ - if (grub_be_to_cpu32 (*reg) == 0x7000) - return 0; - - pl050_regs = grub_fdtbus_map_reg (dev, 0, 0); - - if (!grub_fdtbus_is_mapping_valid (pl050_regs)) - return grub_error (GRUB_ERR_IO, "could not map pl050"); - - ps2_state.at_keyboard_status = 0; - set_scancodes (); - keyboard_controller_led (ps2_state.led_status); - - grub_term_register_input ("pl050_keyboard", &grub_pl050_keyboard_term); - return GRUB_ERR_NONE; -} - -struct grub_fdtbus_driver pl050 = -{ - .compatible = "arm,pl050", - .attach = pl050_attach -}; - -void -grub_pl050_init (void) -{ - grub_fdtbus_register (&pl050); -} diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c deleted file mode 100644 index f8a129eb7..000000000 --- a/grub-core/term/at_keyboard.c +++ /dev/null @@ -1,342 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_uint8_t grub_keyboard_controller_orig; -static grub_uint8_t grub_keyboard_orig_set; -struct grub_ps2_state ps2_state; - -static int ping_sent; - -static void -grub_keyboard_controller_init (void); - -static void -keyboard_controller_wait_until_ready (void) -{ - unsigned int i = 200; - - /* 50 us would be enough but our current time resolution is 1ms. */ - grub_millisleep (1); - - while (!KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) - { - grub_millisleep (1); - - /* Timeout. */ - if (!i--) - break; - } -} - -static grub_uint8_t -wait_ack (void) -{ - grub_uint64_t endtime; - grub_uint8_t ack; - - endtime = grub_get_time_ms () + 20; - do { - keyboard_controller_wait_until_ready (); - ack = grub_inb (KEYBOARD_REG_DATA); - } while (ack != GRUB_AT_ACK && ack != GRUB_AT_NACK - && grub_get_time_ms () < endtime); - return ack; -} - -static int -at_command (grub_uint8_t data) -{ - unsigned i; - for (i = 0; i < GRUB_AT_TRIES; i++) - { - grub_uint8_t ack; - keyboard_controller_wait_until_ready (); - grub_outb (data, KEYBOARD_REG_STATUS); - ack = wait_ack (); - if (ack == GRUB_AT_NACK) - continue; - if (ack == GRUB_AT_ACK) - break; - return 0; - } - return (i != GRUB_AT_TRIES); -} - -static void -grub_keyboard_controller_write (grub_uint8_t c) -{ - at_command (KEYBOARD_COMMAND_WRITE); - keyboard_controller_wait_until_ready (); - grub_outb (c, KEYBOARD_REG_DATA); -} - -#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) -#define USE_SCANCODE_SET 1 -#else -#define USE_SCANCODE_SET 0 -#endif - -#if !USE_SCANCODE_SET - -static grub_uint8_t -grub_keyboard_controller_read (void) -{ - at_command (KEYBOARD_COMMAND_READ); - keyboard_controller_wait_until_ready (); - return grub_inb (KEYBOARD_REG_DATA); -} - -#endif - -static int -write_mode (int mode) -{ - unsigned i; - for (i = 0; i < GRUB_AT_TRIES; i++) - { - grub_uint8_t ack; - keyboard_controller_wait_until_ready (); - grub_outb (0xf0, KEYBOARD_REG_DATA); - keyboard_controller_wait_until_ready (); - grub_outb (mode, KEYBOARD_REG_DATA); - keyboard_controller_wait_until_ready (); - ack = wait_ack (); - if (ack == GRUB_AT_NACK) - continue; - if (ack == GRUB_AT_ACK) - break; - return 0; - } - - return (i != GRUB_AT_TRIES); -} - -static int -query_mode (void) -{ - grub_uint8_t ret; - int e; - - e = write_mode (0); - if (!e) - return 0; - - do { - keyboard_controller_wait_until_ready (); - ret = grub_inb (KEYBOARD_REG_DATA); - } while (ret == GRUB_AT_ACK); - /* QEMU translates the set even in no-translate mode. */ - if (ret == 0x43 || ret == 1) - return 1; - if (ret == 0x41 || ret == 2) - return 2; - if (ret == 0x3f || ret == 3) - return 3; - return 0; -} - -static void -set_scancodes (void) -{ - /* You must have visited computer museum. Keyboard without scancode set - knowledge. Assume XT. */ - if (!grub_keyboard_orig_set) - { - grub_dprintf ("atkeyb", "No sets support assumed\n"); - ps2_state.current_set = 1; - return; - } - -#if !USE_SCANCODE_SET - ps2_state.current_set = 1; - return; -#else - - grub_keyboard_controller_write (grub_keyboard_controller_orig - & ~KEYBOARD_AT_TRANSLATE - & ~KEYBOARD_AT_DISABLE); - - keyboard_controller_wait_until_ready (); - grub_outb (KEYBOARD_COMMAND_ENABLE, KEYBOARD_REG_DATA); - - write_mode (2); - ps2_state.current_set = query_mode (); - grub_dprintf ("atkeyb", "returned set %d\n", ps2_state.current_set); - if (ps2_state.current_set == 2) - return; - - write_mode (1); - ps2_state.current_set = query_mode (); - grub_dprintf ("atkeyb", "returned set %d\n", ps2_state.current_set); - if (ps2_state.current_set == 1) - return; - grub_dprintf ("atkeyb", "no supported scancode set found\n"); -#endif -} - -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); -} - -int -grub_at_keyboard_is_alive (void) -{ - if (ps2_state.current_set != 0) - return 1; - if (ping_sent - && KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS)) - && grub_inb (KEYBOARD_REG_DATA) == 0x55) - { - grub_keyboard_controller_init (); - return 1; - } - - if (KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) - { - grub_outb (0xaa, KEYBOARD_REG_STATUS); - ping_sent = 1; - } - return 0; -} - -/* If there is a character pending, return it; - otherwise return GRUB_TERM_NO_KEY. */ -static int -grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) -{ - grub_uint8_t at_key; - int ret; - grub_uint8_t old_led; - - if (!grub_at_keyboard_is_alive ()) - return GRUB_TERM_NO_KEY; - - if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) - return GRUB_TERM_NO_KEY; - at_key = grub_inb (KEYBOARD_REG_DATA); - old_led = ps2_state.led_status; - - ret = grub_ps2_process_incoming_byte (&ps2_state, at_key); - if (old_led != ps2_state.led_status) - keyboard_controller_led (ps2_state.led_status); - return ret; -} - -static void -grub_keyboard_controller_init (void) -{ - ps2_state.at_keyboard_status = 0; - /* Drain input buffer. */ - while (1) - { - keyboard_controller_wait_until_ready (); - if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) - break; - keyboard_controller_wait_until_ready (); - grub_inb (KEYBOARD_REG_DATA); - } -#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) - grub_keyboard_controller_orig = 0; - grub_keyboard_orig_set = 2; -#elif defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_COREBOOT) - /* *BSD relies on those settings. */ - grub_keyboard_controller_orig = KEYBOARD_AT_TRANSLATE; - grub_keyboard_orig_set = 2; -#else - grub_keyboard_controller_orig = grub_keyboard_controller_read (); - grub_keyboard_orig_set = query_mode (); -#endif - set_scancodes (); - keyboard_controller_led (ps2_state.led_status); -} - -static grub_err_t -grub_keyboard_controller_fini (struct grub_term_input *term __attribute__ ((unused))) -{ - if (ps2_state.current_set == 0) - return GRUB_ERR_NONE; - if (grub_keyboard_orig_set) - write_mode (grub_keyboard_orig_set); - grub_keyboard_controller_write (grub_keyboard_controller_orig); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_at_fini_hw (int noreturn __attribute__ ((unused))) -{ - return grub_keyboard_controller_fini (NULL); -} - -static grub_err_t -grub_at_restore_hw (void) -{ - if (ps2_state.current_set == 0) - return GRUB_ERR_NONE; - - /* Drain input buffer. */ - while (1) - { - keyboard_controller_wait_until_ready (); - if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) - break; - keyboard_controller_wait_until_ready (); - grub_inb (KEYBOARD_REG_DATA); - } - set_scancodes (); - keyboard_controller_led (ps2_state.led_status); - - return GRUB_ERR_NONE; -} - - -static struct grub_term_input grub_at_keyboard_term = - { - .name = "at_keyboard", - .fini = grub_keyboard_controller_fini, - .getkey = grub_at_keyboard_getkey - }; - -GRUB_MOD_INIT(at_keyboard) -{ - grub_term_register_input ("at_keyboard", &grub_at_keyboard_term); - grub_loader_register_preboot_hook (grub_at_fini_hw, grub_at_restore_hw, - GRUB_LOADER_PREBOOT_HOOK_PRIO_CONSOLE); -} - -GRUB_MOD_FINI(at_keyboard) -{ - grub_keyboard_controller_fini (NULL); - grub_term_unregister_input (&grub_at_keyboard_term); -} diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c deleted file mode 100644 index 258b52737..000000000 --- a/grub-core/term/efi/console.c +++ /dev/null @@ -1,492 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -typedef enum { - GRUB_TEXT_MODE_UNDEFINED = -1, - GRUB_TEXT_MODE_UNAVAILABLE = 0, - GRUB_TEXT_MODE_AVAILABLE -} -grub_text_mode; - -typedef enum { - GRUB_CURSOR_MODE_UNDEFINED = -1, - GRUB_CURSOR_MODE_OFF = 0, - GRUB_CURSUR_MODE_ON -} -grub_cursor_mode; - -static grub_text_mode text_mode = GRUB_TEXT_MODE_UNDEFINED; -static grub_cursor_mode cursor_mode = GRUB_CURSOR_MODE_UNDEFINED; -static grub_term_color_state text_colorstate = GRUB_TERM_COLOR_UNDEFINED; - -static grub_uint32_t -map_char (grub_uint32_t c) -{ - /* Map some unicode characters to the EFI character. */ - switch (c) - { - case GRUB_UNICODE_LEFTARROW: - c = GRUB_UNICODE_BLACK_LEFT_TRIANGLE; - break; - case GRUB_UNICODE_UPARROW: - c = GRUB_UNICODE_BLACK_UP_TRIANGLE; - break; - case GRUB_UNICODE_RIGHTARROW: - c = GRUB_UNICODE_BLACK_RIGHT_TRIANGLE; - break; - case GRUB_UNICODE_DOWNARROW: - c = GRUB_UNICODE_BLACK_DOWN_TRIANGLE; - break; - case GRUB_UNICODE_HLINE: - c = GRUB_UNICODE_LIGHT_HLINE; - break; - case GRUB_UNICODE_VLINE: - c = GRUB_UNICODE_LIGHT_VLINE; - break; - case GRUB_UNICODE_CORNER_UL: - c = GRUB_UNICODE_LIGHT_CORNER_UL; - break; - case GRUB_UNICODE_CORNER_UR: - c = GRUB_UNICODE_LIGHT_CORNER_UR; - break; - case GRUB_UNICODE_CORNER_LL: - c = GRUB_UNICODE_LIGHT_CORNER_LL; - break; - case GRUB_UNICODE_CORNER_LR: - c = GRUB_UNICODE_LIGHT_CORNER_LR; - break; - } - - return c; -} - -static void -grub_console_setcolorstate (struct grub_term_output *term - __attribute__ ((unused)), - grub_term_color_state state) -{ - grub_efi_simple_text_output_interface_t *o; - - if (grub_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE) - { - /* - * Cache colorstate changes before the first text-output, this avoids - * "color_normal" environment writes causing a switch to textmode. - */ - text_colorstate = state; - return; - } - - if (grub_efi_is_finished) - return; - - o = grub_efi_system_table->con_out; - - switch (state) { - case GRUB_TERM_COLOR_STANDARD: - o->set_attributes (o, GRUB_TERM_DEFAULT_STANDARD_COLOR & 0x7f); - break; - case GRUB_TERM_COLOR_NORMAL: - o->set_attributes (o, grub_term_normal_color & 0x7f); - break; - case GRUB_TERM_COLOR_HIGHLIGHT: - o->set_attributes (o, grub_term_highlight_color & 0x7f); - break; - default: - break; - } -} - -static void -grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)), - int on) -{ - grub_efi_simple_text_output_interface_t *o; - - if (grub_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE) - { - /* Cache cursor changes before the first text-output */ - cursor_mode = on; - return; - } - - o = grub_efi_system_table->con_out; - o->enable_cursor (o, on); -} - -static grub_err_t -grub_prepare_for_text_output (struct grub_term_output *term) -{ - if (grub_efi_is_finished) - return GRUB_ERR_BAD_DEVICE; - - if (text_mode != GRUB_TEXT_MODE_UNDEFINED) - return text_mode ? GRUB_ERR_NONE : GRUB_ERR_BAD_DEVICE; - - if (! grub_efi_set_text_mode (1)) - { - /* This really should never happen */ - grub_error (GRUB_ERR_BAD_DEVICE, "cannot set text mode"); - text_mode = GRUB_TEXT_MODE_UNAVAILABLE; - return GRUB_ERR_BAD_DEVICE; - } - - if (cursor_mode != GRUB_CURSOR_MODE_UNDEFINED) - grub_console_setcursor (term, cursor_mode); - if (text_colorstate != GRUB_TERM_COLOR_UNDEFINED) - grub_console_setcolorstate (term, text_colorstate); - text_mode = GRUB_TEXT_MODE_AVAILABLE; - return GRUB_ERR_NONE; -} - -static void -grub_console_putchar (struct grub_term_output *term, - const struct grub_unicode_glyph *c) -{ - grub_efi_char16_t str[2 + 30]; - grub_efi_simple_text_output_interface_t *o; - unsigned i, j; - - if (grub_prepare_for_text_output (term) != GRUB_ERR_NONE) - return; - - o = grub_efi_system_table->con_out; - - /* For now, do not try to use a surrogate pair. */ - if (c->base > 0xffff) - str[0] = '?'; - else - str[0] = (grub_efi_char16_t) map_char (c->base & 0xffff); - j = 1; - for (i = 0; i < c->ncomb && j + 1 < ARRAY_SIZE (str); i++) - if (c->base < 0xffff) - str[j++] = grub_unicode_get_comb (c)[i].code; - str[j] = 0; - - /* Should this test be cached? */ - if ((c->base > 0x7f || c->ncomb) - && o->test_string (o, str) != GRUB_EFI_SUCCESS) - return; - - o->output_string (o, str); -} - -const unsigned efi_codes[] = - { - 0, GRUB_TERM_KEY_UP, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_RIGHT, - GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_END, GRUB_TERM_KEY_INSERT, - GRUB_TERM_KEY_DC, GRUB_TERM_KEY_PPAGE, GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_F1, - GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, - GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, - GRUB_TERM_KEY_F10, GRUB_TERM_KEY_F11, GRUB_TERM_KEY_F12, GRUB_TERM_ESC - }; - -static int -grub_efi_translate_key (grub_efi_input_key_t key) -{ - if (key.scan_code == 0) - { - /* Some firmware implementations use VT100-style codes against the spec. - This is especially likely if driven by serial. - */ - if (key.unicode_char < 0x20 && key.unicode_char != 0 - && key.unicode_char != '\t' && key.unicode_char != '\b' - && key.unicode_char != '\n' && key.unicode_char != '\r') - return GRUB_TERM_CTRL | (key.unicode_char - 1 + 'a'); - else - return key.unicode_char; - } - /* Some devices send enter with scan_code 0x0d (F3) and unicode_char 0x0d. */ - else if (key.scan_code == '\r' && key.unicode_char == '\r') - return key.unicode_char; - else if (key.scan_code < ARRAY_SIZE (efi_codes)) - return efi_codes[key.scan_code]; - - if ((key.unicode_char >= 0x20 && key.unicode_char <= 0x7f) - || key.unicode_char == '\t' || key.unicode_char == '\b' - || key.unicode_char == '\n' || key.unicode_char == '\r') - return key.unicode_char; - - return GRUB_TERM_NO_KEY; -} - -static int -grub_console_getkey_con (struct grub_term_input *term __attribute__ ((unused))) -{ - grub_efi_simple_input_interface_t *i; - grub_efi_input_key_t key; - grub_efi_status_t status; - - i = grub_efi_system_table->con_in; - status = i->read_key_stroke (i, &key); - - if (status != GRUB_EFI_SUCCESS) - return GRUB_TERM_NO_KEY; - - return grub_efi_translate_key(key); -} - -/* - * When more then just modifiers are pressed, our getkeystatus() consumes a - * press from the queue, this function buffers the press for the regular - * getkey() so that it does not get lost. - */ -static grub_err_t -grub_console_read_key_stroke ( - grub_efi_simple_text_input_ex_interface_t *text_input, - grub_efi_key_data_t *key_data_ret, int *key_ret, - int consume) -{ - static grub_efi_key_data_t key_data; - grub_efi_status_t status; - int key; - - if (!text_input) - return GRUB_ERR_EOF; - - key = grub_efi_translate_key (key_data.key); - if (key == GRUB_TERM_NO_KEY) { - status = text_input->read_key_stroke (text_input, &key_data); - if (status != GRUB_EFI_SUCCESS) - return GRUB_ERR_EOF; - - key = grub_efi_translate_key (key_data.key); - } - - *key_data_ret = key_data; - *key_ret = key; - - if (consume) { - key_data.key.scan_code = 0; - key_data.key.unicode_char = 0; - } - - return GRUB_ERR_NONE; -} - -static int -grub_console_getkey_ex (struct grub_term_input *term) -{ - grub_efi_key_data_t key_data; - grub_efi_uint32_t kss; - grub_err_t err; - int key = -1; - - err = grub_console_read_key_stroke (term->data, &key_data, &key, 1); - if (err != GRUB_ERR_NONE || key == GRUB_TERM_NO_KEY) - return GRUB_TERM_NO_KEY; - - kss = key_data.key_state.key_shift_state; - if (kss & GRUB_EFI_SHIFT_STATE_VALID) - { - if ((kss & GRUB_EFI_LEFT_SHIFT_PRESSED - || kss & GRUB_EFI_RIGHT_SHIFT_PRESSED) - && (key & GRUB_TERM_EXTENDED)) - key |= GRUB_TERM_SHIFT; - if (kss & GRUB_EFI_LEFT_ALT_PRESSED || kss & GRUB_EFI_RIGHT_ALT_PRESSED) - key |= GRUB_TERM_ALT; - if (kss & GRUB_EFI_LEFT_CONTROL_PRESSED - || kss & GRUB_EFI_RIGHT_CONTROL_PRESSED) - key |= GRUB_TERM_CTRL; - } - - return key; -} - -static int -grub_console_getkeystatus (struct grub_term_input *term) -{ - grub_efi_key_data_t key_data; - grub_efi_uint32_t kss; - int key, mods = 0; - - if (grub_efi_is_finished) - return 0; - - if (grub_console_read_key_stroke (term->data, &key_data, &key, 0)) - return 0; - - kss = key_data.key_state.key_shift_state; - if (kss & GRUB_EFI_SHIFT_STATE_VALID) - { - if (kss & GRUB_EFI_LEFT_SHIFT_PRESSED) - mods |= GRUB_TERM_STATUS_LSHIFT; - if (kss & GRUB_EFI_RIGHT_SHIFT_PRESSED) - mods |= GRUB_TERM_STATUS_RSHIFT; - if (kss & GRUB_EFI_LEFT_ALT_PRESSED) - mods |= GRUB_TERM_STATUS_LALT; - if (kss & GRUB_EFI_RIGHT_ALT_PRESSED) - mods |= GRUB_TERM_STATUS_RALT; - if (kss & GRUB_EFI_LEFT_CONTROL_PRESSED) - mods |= GRUB_TERM_STATUS_LCTRL; - if (kss & GRUB_EFI_RIGHT_CONTROL_PRESSED) - mods |= GRUB_TERM_STATUS_RCTRL; - } - - return mods; -} - -static grub_err_t -grub_efi_console_input_init (struct grub_term_input *term) -{ - static grub_guid_t text_input_ex_guid = - GRUB_EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID; - - if (grub_efi_is_finished) - return 0; - - grub_efi_simple_text_input_ex_interface_t *text_input = term->data; - if (text_input) - return 0; - - text_input = grub_efi_open_protocol(grub_efi_system_table->console_in_handler, - &text_input_ex_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - term->data = (void *)text_input; - - return 0; -} - -static int -grub_console_getkey (struct grub_term_input *term) -{ - if (grub_efi_is_finished) - return 0; - - if (term->data) - return grub_console_getkey_ex(term); - else - return grub_console_getkey_con(term); -} - -static struct grub_term_coordinate -grub_console_getwh (struct grub_term_output *term) -{ - grub_efi_simple_text_output_interface_t *o; - grub_efi_uintn_t columns, rows; - - o = grub_efi_system_table->con_out; - if (grub_prepare_for_text_output (term) != GRUB_ERR_NONE || - o->query_mode (o, o->mode->mode, - &columns, &rows) != GRUB_EFI_SUCCESS) - { - /* Why does this fail? */ - columns = 80; - rows = 25; - } - - return (struct grub_term_coordinate) { columns, rows }; -} - -static struct grub_term_coordinate -grub_console_getxy (struct grub_term_output *term __attribute__ ((unused))) -{ - grub_efi_simple_text_output_interface_t *o; - - if (grub_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE) - return (struct grub_term_coordinate) { 0, 0 }; - - o = grub_efi_system_table->con_out; - return (struct grub_term_coordinate) { o->mode->cursor_column, o->mode->cursor_row }; -} - -static void -grub_console_gotoxy (struct grub_term_output *term, - struct grub_term_coordinate pos) -{ - grub_efi_simple_text_output_interface_t *o; - - if (grub_prepare_for_text_output (term) != GRUB_ERR_NONE) - return; - - o = grub_efi_system_table->con_out; - o->set_cursor_position (o, pos.x, pos.y); -} - -static void -grub_console_cls (struct grub_term_output *term __attribute__ ((unused))) -{ - grub_efi_simple_text_output_interface_t *o; - grub_efi_int32_t orig_attr; - - if (grub_prepare_for_text_output (term) != GRUB_ERR_NONE) - return; - - o = grub_efi_system_table->con_out; - orig_attr = o->mode->attribute; - o->set_attributes (o, GRUB_EFI_BACKGROUND_BLACK); - o->clear_screen (o); - o->set_attributes (o, orig_attr); -} - -static grub_err_t -grub_efi_console_output_fini (struct grub_term_output *term) -{ - if (text_mode != GRUB_TEXT_MODE_AVAILABLE) - return 0; - - grub_console_setcursor (term, 0); - grub_efi_set_text_mode (0); - text_mode = GRUB_TEXT_MODE_UNDEFINED; - return 0; -} - -static struct grub_term_input grub_console_term_input = - { - .name = "console", - .getkey = grub_console_getkey, - .getkeystatus = grub_console_getkeystatus, - .init = grub_efi_console_input_init, - }; - -static struct grub_term_output grub_console_term_output = - { - .name = "console", - .fini = grub_efi_console_output_fini, - .putchar = grub_console_putchar, - .getwh = grub_console_getwh, - .getxy = grub_console_getxy, - .gotoxy = grub_console_gotoxy, - .cls = grub_console_cls, - .setcolorstate = grub_console_setcolorstate, - .setcursor = grub_console_setcursor, - .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS, - .progress_update_divisor = GRUB_PROGRESS_FAST - }; - -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/efi/serial.c b/grub-core/term/efi/serial.c deleted file mode 100644 index 5dfd2d86c..000000000 --- a/grub-core/term/efi/serial.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2008,2012 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* GUID. */ -static grub_guid_t serial_io_guid = GRUB_EFI_SERIAL_IO_GUID; - -static void -do_real_config (struct grub_serial_port *port) -{ - grub_efi_status_t status = GRUB_EFI_SUCCESS; - const grub_efi_parity_type_t parities[] = { - [GRUB_SERIAL_PARITY_NONE] = GRUB_EFI_SERIAL_NO_PARITY, - [GRUB_SERIAL_PARITY_ODD] = GRUB_EFI_SERIAL_ODD_PARITY, - [GRUB_SERIAL_PARITY_EVEN] = GRUB_EFI_SERIAL_EVEN_PARITY - }; - const grub_efi_stop_bits_t stop_bits[] = { - [GRUB_SERIAL_STOP_BITS_1] = GRUB_EFI_SERIAL_1_STOP_BIT, - [GRUB_SERIAL_STOP_BITS_1_5] = GRUB_EFI_SERIAL_1_5_STOP_BITS, - [GRUB_SERIAL_STOP_BITS_2] = GRUB_EFI_SERIAL_2_STOP_BITS, - }; - - if (port->configured) - return; - - status = port->interface->set_attributes (port->interface, - port->config.speed, - 0, 0, parities[port->config.parity], - port->config.word_len, - stop_bits[port->config.stop_bits]); - if (status != GRUB_EFI_SUCCESS) - port->broken = 1; - - status = port->interface->set_control_bits (port->interface, - port->config.rtscts ? 0x4002 : 0x2); - - port->configured = 1; -} - -/* Fetch a key. */ -static int -serial_hw_fetch (struct grub_serial_port *port) -{ - grub_efi_uintn_t bufsize = 1; - char c; - grub_efi_status_t status = GRUB_EFI_SUCCESS; - do_real_config (port); - if (port->broken) - return -1; - - status = port->interface->read (port->interface, &bufsize, &c); - if (status != GRUB_EFI_SUCCESS || bufsize == 0) - return -1; - - return c; -} - -/* Put a character. */ -static void -serial_hw_put (struct grub_serial_port *port, const int c) -{ - grub_efi_uintn_t bufsize = 1; - char c0 = c; - - do_real_config (port); - - if (port->broken) - return; - - port->interface->write (port->interface, &bufsize, &c0); -} - -/* 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_configure (struct grub_serial_port *port, - struct grub_serial_config *config) -{ - if (config->parity != GRUB_SERIAL_PARITY_NONE - && config->parity != GRUB_SERIAL_PARITY_ODD - && config->parity != GRUB_SERIAL_PARITY_EVEN) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port parity")); - - if (config->stop_bits != GRUB_SERIAL_STOP_BITS_1 - && config->stop_bits != GRUB_SERIAL_STOP_BITS_1_5 - && config->stop_bits != GRUB_SERIAL_STOP_BITS_2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port stop bits number")); - - if (config->word_len < 5 || config->word_len > 8) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port word length")); - - port->config = *config; - port->configured = 0; - - /* FIXME: should check if the serial terminal was found. */ - - return GRUB_ERR_NONE; -} - -struct grub_serial_driver grub_efiserial_driver = - { - .configure = serial_hw_configure, - .fetch = serial_hw_fetch, - .put = serial_hw_put - }; - -void -grub_efiserial_init (void) -{ - grub_efi_uintn_t num_handles; - grub_efi_handle_t *handles; - grub_efi_handle_t *handle; - int num_serial = 0; - grub_err_t err; - - /* Find handles which support the disk io interface. */ - handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &serial_io_guid, - 0, &num_handles); - if (! handles) - return; - - /* Make a linked list of devices. */ - for (handle = handles; num_handles--; handle++) - { - struct grub_serial_port *port; - struct grub_efi_serial_io_interface *sio; - - sio = grub_efi_open_protocol (*handle, &serial_io_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (! sio) - /* This should not happen... Why? */ - continue; - - port = grub_zalloc (sizeof (*port)); - if (!port) - return; - - port->name = grub_malloc (sizeof ("efiXXXXXXXXXXXXXXXXXXXX")); - if (!port->name) - { - grub_free (port); - return; - } - grub_snprintf (port->name, sizeof ("efiXXXXXXXXXXXXXXXXXXXX"), - "efi%d", num_serial++); - - port->driver = &grub_efiserial_driver; - port->interface = sio; - err = grub_serial_config_defaults (port); - if (err) - grub_print_error (); - - grub_serial_register (port); - } - - grub_free (handles); - - return; -} diff --git a/grub-core/term/gfxterm_background.c b/grub-core/term/gfxterm_background.c deleted file mode 100644 index a0e2d5118..000000000 --- a/grub-core/term/gfxterm_background.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2008,2009,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* Option array indices. */ -enum - { - BACKGROUND_CMD_ARGINDEX_MODE = 0 - }; - -static const struct grub_arg_option background_image_cmd_options[] = - { - {"mode", 'm', 0, N_("Background image mode."), - /* TRANSLATORS: This refers to background image mode (stretched or - in left-top corner). Note that GRUB will accept only original - keywords stretch and normal, not the translated ones. - So please put both in translation - e.g. stretch(=%STRETCH%)|normal(=%NORMAL%). - The percents mark the translated version. Since many people - may not know the word stretch or normal I recommend - putting the translation either here or in "Background image mode." - string. */ - N_("stretch|normal"), - ARG_TYPE_STRING}, - {0, 0, 0, 0, 0, 0} - }; - -static grub_err_t -grub_gfxterm_background_image_cmd (grub_extcmd_context_t ctxt, - int argc, char **args) -{ - struct grub_arg_list *state = ctxt->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 (grub_gfxterm_background.bitmap) - { - grub_video_bitmap_destroy (grub_gfxterm_background.bitmap); - grub_gfxterm_background.bitmap = 0; - grub_gfxterm_background.blend_text_bg = 0; - - /* Mark whole screen as dirty. */ - grub_gfxterm_schedule_repaint (); - } - - /* If filename was provided, try to load that. */ - if (argc >= 1) - { - /* Try to load new one. */ - grub_video_bitmap_load (&grub_gfxterm_background.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) - { - unsigned int width, height; - grub_gfxterm_get_dimensions (&width, &height); - if (width - != grub_video_bitmap_get_width (grub_gfxterm_background.bitmap) - || height - != grub_video_bitmap_get_height (grub_gfxterm_background.bitmap)) - { - struct grub_video_bitmap *scaled_bitmap; - grub_video_bitmap_create_scaled (&scaled_bitmap, - width, - height, - grub_gfxterm_background.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 (grub_gfxterm_background.bitmap); - grub_gfxterm_background.bitmap = scaled_bitmap; - } - } - } - - /* If bitmap was loaded correctly, display it. */ - if (grub_gfxterm_background.bitmap) - { - grub_gfxterm_background.blend_text_bg = 1; - - /* Mark whole screen as dirty. */ - grub_gfxterm_schedule_repaint (); - } - } - - /* All was ok. */ - grub_errno = GRUB_ERR_NONE; - return grub_errno; -} - -static grub_err_t -grub_gfxterm_background_color_cmd (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) -{ - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - - /* Check that we have video adapter active. */ - if (grub_video_get_info (NULL) != GRUB_ERR_NONE) - return grub_errno; - - if (grub_video_parse_color (args[0], - &grub_gfxterm_background.default_bg_color) - != GRUB_ERR_NONE) - return grub_errno; - - /* Destroy existing background bitmap if loaded. */ - if (grub_gfxterm_background.bitmap) - { - grub_video_bitmap_destroy (grub_gfxterm_background.bitmap); - grub_gfxterm_background.bitmap = 0; - - /* Mark whole screen as dirty. */ - grub_gfxterm_schedule_repaint (); - } - - /* Set the background and border colors. The background color needs to be - compatible with the text layer. */ - grub_gfxterm_video_update_color (); - grub_gfxterm_background.blend_text_bg = 1; - - /* Mark whole screen as dirty. */ - grub_gfxterm_schedule_repaint (); - - return GRUB_ERR_NONE; -} - -static grub_extcmd_t background_image_cmd_handle; -static grub_command_t background_color_cmd_handle; - -GRUB_MOD_INIT(gfxterm_background) -{ - background_image_cmd_handle = - grub_register_extcmd ("background_image", - grub_gfxterm_background_image_cmd, 0, - N_("[-m (stretch|normal)] FILE"), - N_("Load background image for active terminal."), - background_image_cmd_options); - background_color_cmd_handle = - grub_register_command ("background_color", - grub_gfxterm_background_color_cmd, - N_("COLOR"), - N_("Set background color for active terminal.")); -} - -GRUB_MOD_FINI(gfxterm_background) -{ - grub_unregister_command (background_color_cmd_handle); - grub_unregister_extcmd (background_image_cmd_handle); -} diff --git a/grub-core/term/i386/coreboot/cbmemc.c b/grub-core/term/i386/coreboot/cbmemc.c deleted file mode 100644 index cea9b8431..000000000 --- a/grub-core/term/i386/coreboot/cbmemc.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define CURSOR_MASK ((1 << 28) - 1) -#define OVERFLOW (1 << 31) - -struct grub_linuxbios_cbmemc -{ - grub_uint32_t size; - grub_uint32_t cursor; - char body[0]; -}; - -static struct grub_linuxbios_cbmemc *cbmemc; - -static void -put (struct grub_term_output *term __attribute__ ((unused)), const int c) -{ - grub_uint32_t flags, cursor; - if (!cbmemc) - return; - flags = cbmemc->cursor & ~CURSOR_MASK; - cursor = cbmemc->cursor & CURSOR_MASK; - if (cursor >= cbmemc->size) - return; - cbmemc->body[cursor++] = c; - if (cursor >= cbmemc->size) - { - cursor = 0; - flags |= OVERFLOW; - } - cbmemc->cursor = flags | cursor; -} - -struct grub_terminfo_output_state grub_cbmemc_terminfo_output = - { - .put = put, - .size = { 80, 24 } - }; - -static struct grub_term_output grub_cbmemc_term_output = - { - .name = "cbmemc", - .init = grub_terminfo_output_init, - .fini = 0, - .putchar = grub_terminfo_putchar, - .getxy = grub_terminfo_getxy, - .getwh = grub_terminfo_getwh, - .gotoxy = grub_terminfo_gotoxy, - .cls = grub_terminfo_cls, - .setcolorstate = grub_terminfo_setcolorstate, - .setcursor = grub_terminfo_setcursor, - .flags = GRUB_TERM_CODE_TYPE_ASCII, - .data = &grub_cbmemc_terminfo_output, - .progress_update_divisor = GRUB_PROGRESS_NO_UPDATE - }; - -static int -iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, - void *data __attribute__ ((unused))) -{ - if (table_item->tag != GRUB_LINUXBIOS_MEMBER_CBMEMC) - return 0; - cbmemc = (struct grub_linuxbios_cbmemc *) (grub_addr_t) - *(grub_uint64_t *) (table_item + 1); - return 1; -} - -static grub_err_t -grub_cmd_cbmemc (struct grub_command *cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char *argv[] __attribute__ ((unused))) -{ - grub_size_t size, cursor; - struct grub_linuxbios_cbmemc *real_cbmemc; - - if (!cbmemc) - return grub_error (GRUB_ERR_IO, "no CBMEM console found"); - - real_cbmemc = cbmemc; - cbmemc = 0; - cursor = real_cbmemc->cursor & CURSOR_MASK; - if (!(real_cbmemc->cursor & OVERFLOW) && cursor < real_cbmemc->size) - size = cursor; - else - size = real_cbmemc->size; - if (real_cbmemc->cursor & OVERFLOW) - { - if (cursor > size) - cursor = 0; - grub_xnputs(real_cbmemc->body + cursor, size - cursor); - grub_xnputs(real_cbmemc->body, cursor); - } - else - grub_xnputs(real_cbmemc->body, size); - cbmemc = real_cbmemc; - return 0; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT (cbmemc) -{ - grub_linuxbios_table_iterate (iterate_linuxbios_table, 0); - - if (cbmemc) - grub_term_register_output ("cbmemc", &grub_cbmemc_term_output); - - cmd = - grub_register_command ("cbmemc", grub_cmd_cbmemc, - 0, N_("Show CBMEM console content.")); -} - - -GRUB_MOD_FINI (cbmemc) -{ - grub_term_unregister_output (&grub_cbmemc_term_output); - grub_unregister_command (cmd); -} diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c deleted file mode 100644 index 9403390f1..000000000 --- a/grub-core/term/i386/pc/console.c +++ /dev/null @@ -1,309 +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 . - */ - -#include -#include -#include -#include -#include - -static grub_uint8_t grub_console_cur_color = 0x7; - -static void -int10_9 (grub_uint8_t ch, grub_uint16_t n) -{ - struct grub_bios_int_registers regs; - - regs.eax = ch | 0x0900; - regs.ebx = grub_console_cur_color & 0xff; - regs.ecx = n; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); -} - -/* - * 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) - */ - - -static struct grub_term_coordinate -grub_console_getxy (struct grub_term_output *term __attribute__ ((unused))) -{ - struct grub_bios_int_registers regs; - - regs.eax = 0x0300; - regs.ebx = 0; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - - return (struct grub_term_coordinate) { - (regs.edx & 0xff), ((regs.edx & 0xff00) >> 8) }; -} - -/* - * 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) - */ -static void -grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)), - struct grub_term_coordinate pos) -{ - struct grub_bios_int_registers regs; - - /* set page to 0 */ - regs.ebx = 0; - regs.eax = 0x0200; - regs.edx = (pos.y << 8) | pos.x; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); -} - -/* - * - * 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, use INT 10, AH = 9 to write character - * with attributes and advance cursor. If we are on the last column, - * let BIOS to wrap line correctly. - */ -static void -grub_console_putchar_real (grub_uint8_t c) -{ - struct grub_bios_int_registers regs; - struct grub_term_coordinate pos; - - if (c == 7 || c == 8 || c == 0xa || c == 0xd) - { - regs.eax = c | 0x0e00; - regs.ebx = 0x0001; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - return; - } - - /* get the current position */ - pos = grub_console_getxy (NULL); - - /* write the character with the attribute */ - int10_9 (c, 1); - - /* check the column with the width */ - if (pos.x >= 79) - { - grub_console_putchar_real (0x0d); - grub_console_putchar_real (0x0a); - } - else - grub_console_gotoxy (NULL, (struct grub_term_coordinate) { pos.x + 1, - pos.y }); -} - -static void -grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), - const struct grub_unicode_glyph *c) -{ - grub_console_putchar_real (c->base); -} - -/* - * 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) - */ -static void -grub_console_cls (struct grub_term_output *term) -{ - /* move the cursor to the beginning */ - grub_console_gotoxy (term, (struct grub_term_coordinate) { 0, 0 }); - - /* write spaces to the entire screen */ - int10_9 (' ', 80 * 25); - - /* move back the cursor */ - grub_console_gotoxy (term, (struct grub_term_coordinate) { 0, 0 }); -} - -/* - * 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 - */ -static void -grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)), - int on) -{ - static grub_uint16_t console_cursor_shape = 0; - struct grub_bios_int_registers regs; - - /* check if the standard cursor shape has already been saved */ - if (!console_cursor_shape) - { - regs.eax = 0x0300; - regs.ebx = 0; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - console_cursor_shape = regs.ecx; - if ((console_cursor_shape >> 8) >= (console_cursor_shape & 0xff)) - console_cursor_shape = 0x0d0e; - } - /* set %cx to the designated cursor shape */ - regs.ecx = on ? console_cursor_shape : 0x2000; - regs.eax = 0x0100; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); -} - -/* - * 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 - * BIOS call "INT 16H Function 00H" to read character from keyboard - * Call with %ah = 0x0 - * Return: %ah = keyboard scan code - * %al = ASCII character - */ - -static int -grub_console_getkey (struct grub_term_input *term __attribute__ ((unused))) -{ - const grub_uint16_t bypass_table[] = { - 0x0100 | GRUB_TERM_ESC, 0x0f00 | GRUB_TERM_TAB, 0x0e00 | GRUB_TERM_BACKSPACE, 0x1c00 | '\r', 0x1c00 | '\n' - }; - struct grub_bios_int_registers regs; - unsigned i; - - /* - * 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. - */ - - regs.eax = 0x0100; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x16, ®s); - if (regs.flags & GRUB_CPU_INT_FLAGS_ZERO) - return GRUB_TERM_NO_KEY; - - regs.eax = 0x0000; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x16, ®s); - if (!(regs.eax & 0xff)) - return ((regs.eax >> 8) & 0xff) | GRUB_TERM_EXTENDED; - - if ((regs.eax & 0xff) >= ' ') - return regs.eax & 0xff; - - for (i = 0; i < ARRAY_SIZE (bypass_table); i++) - if (bypass_table[i] == (regs.eax & 0xffff)) - return regs.eax & 0xff; - - return (regs.eax & 0xff) + (('a' - 1) | GRUB_TERM_CTRL); -} - -static int -grub_console_getkeystatus (struct grub_term_input *term __attribute__ ((unused))) -{ - const struct grub_machine_bios_data_area *bios_data_area = - (struct grub_machine_bios_data_area *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR); - /* conveniently GRUB keystatus is modelled after BIOS one. */ - return bios_data_area->keyboard_flag_lower & ~0x80; -} - -static struct grub_term_coordinate -grub_console_getwh (struct grub_term_output *term __attribute__ ((unused))) -{ - return (struct grub_term_coordinate) { 80, 25 }; -} - -static void -grub_console_setcolorstate (struct grub_term_output *term - __attribute__ ((unused)), - grub_term_color_state state) -{ - switch (state) { - case GRUB_TERM_COLOR_STANDARD: - grub_console_cur_color = GRUB_TERM_DEFAULT_STANDARD_COLOR & 0x7f; - break; - case GRUB_TERM_COLOR_NORMAL: - grub_console_cur_color = grub_term_normal_color & 0x7f; - break; - case GRUB_TERM_COLOR_HIGHLIGHT: - grub_console_cur_color = grub_term_highlight_color & 0x7f; - break; - default: - break; - } -} - -static struct grub_term_input grub_console_term_input = - { - .name = "console", - .getkey = grub_console_getkey, - .getkeystatus = grub_console_getkeystatus - }; - -static struct grub_term_output grub_console_term_output = - { - .name = "console", - .putchar = grub_console_putchar, - .getwh = grub_console_getwh, - .getxy = grub_console_getxy, - .gotoxy = grub_console_gotoxy, - .cls = grub_console_cls, - .setcolorstate = grub_console_setcolorstate, - .setcursor = grub_console_setcursor, - .flags = GRUB_TERM_CODE_TYPE_CP437, - .progress_update_divisor = GRUB_PROGRESS_FAST - }; - -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/mda_text.c b/grub-core/term/i386/pc/mda_text.c deleted file mode 100644 index c3a5a1788..000000000 --- a/grub-core/term/i386/pc/mda_text.c +++ /dev/null @@ -1,13 +0,0 @@ -#define MODE_MDA 1 -#include "vga_text.c" - -GRUB_MOD_INIT(mda_text) -{ - grub_term_register_output ("mda_text", &grub_vga_text_term); -} - -GRUB_MOD_FINI(mda_text) -{ - grub_term_unregister_output (&grub_vga_text_term); -} - diff --git a/grub-core/term/i386/pc/vga_text.c b/grub-core/term/i386/pc/vga_text.c deleted file mode 100644 index b88fa9d2e..000000000 --- a/grub-core/term/i386/pc/vga_text.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 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 . - */ - -#include -#include -#include -#include -#include - -#if defined (GRUB_MACHINE_COREBOOT) -#include -#endif - -/* MODESET is used for testing to force monochrome or colour mode. - You shouldn't use mda_text on vga. - */ -#ifdef MODESET -#include -#endif - -#if defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_MULTIBOOT) -#include -#endif - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define COLS 80 -#define ROWS 25 - -static struct grub_term_coordinate grub_curr_pos; - -#ifdef __mips__ -#define VGA_TEXT_SCREEN ((grub_uint16_t *) grub_absolute_pointer (0xb00b8000)) -#define cr_read grub_vga_cr_read -#define cr_write grub_vga_cr_write -#elif defined (MODE_MDA) -#define VGA_TEXT_SCREEN ((grub_uint16_t *) grub_absolute_pointer (0xb0000)) -#define cr_read grub_vga_cr_bw_read -#define cr_write grub_vga_cr_bw_write -#else -#define VGA_TEXT_SCREEN ((grub_uint16_t *) grub_absolute_pointer (0xb8000)) -#define cr_read grub_vga_cr_read -#define cr_write grub_vga_cr_write -#endif - -static grub_uint8_t cur_color = 0x7; - -static void -screen_write_char (int x, int y, short c) -{ - if (x < COLS && y < ROWS && x >= 0 && y >= 0) - VGA_TEXT_SCREEN[y * COLS + x] = grub_cpu_to_le16 (c); -} - -static short -screen_read_char (int x, int y) -{ - return grub_le_to_cpu16 (VGA_TEXT_SCREEN[y * COLS + x]); -} - -static void -update_cursor (void) -{ - unsigned int pos = grub_curr_pos.y * COLS + grub_curr_pos.x; - cr_write (pos >> 8, GRUB_VGA_CR_CURSOR_ADDR_HIGH); - cr_write (pos & 0xFF, GRUB_VGA_CR_CURSOR_ADDR_LOW); -} - -static void -inc_y (void) -{ - grub_curr_pos.x = 0; - if (grub_curr_pos.y < ROWS - 1) - grub_curr_pos.y++; - else - { - int x, y; - for (y = 0; y < ROWS - 1; y++) - for (x = 0; x < COLS; x++) - screen_write_char (x, y, screen_read_char (x, y + 1)); - for (x = 0; x < COLS; x++) - screen_write_char (x, ROWS - 1, ' ' | (cur_color << 8)); - } -} - -static void -inc_x (void) -{ - if (grub_curr_pos.x >= COLS - 1) - inc_y (); - else - grub_curr_pos.x++; -} - -static void -grub_vga_text_putchar (struct grub_term_output *term __attribute__ ((unused)), - const struct grub_unicode_glyph *c) -{ - switch (c->base) - { - case '\b': - if (grub_curr_pos.x != 0) - screen_write_char (grub_curr_pos.x--, grub_curr_pos.y, ' '); - break; - case '\n': - inc_y (); - break; - case '\r': - grub_curr_pos.x = 0; - break; - default: - screen_write_char (grub_curr_pos.x, grub_curr_pos.y, - c->base | (cur_color << 8)); - inc_x (); - } - - update_cursor (); -} - -static struct grub_term_coordinate -grub_vga_text_getxy (struct grub_term_output *term __attribute__ ((unused))) -{ - return grub_curr_pos; -} - -static void -grub_vga_text_gotoxy (struct grub_term_output *term __attribute__ ((unused)), - struct grub_term_coordinate pos) -{ - grub_curr_pos = pos; - update_cursor (); -} - -static void -grub_vga_text_cls (struct grub_term_output *term) -{ - int i; - for (i = 0; i < ROWS * COLS; i++) - VGA_TEXT_SCREEN[i] = grub_cpu_to_le16 (' ' | (cur_color << 8)); - grub_vga_text_gotoxy (term, (struct grub_term_coordinate) { 0, 0 }); -} - -static void -grub_vga_text_setcursor (struct grub_term_output *term __attribute__ ((unused)), - int on) -{ - grub_uint8_t old; - old = cr_read (GRUB_VGA_CR_CURSOR_START); - if (on) - cr_write (old & ~GRUB_VGA_CR_CURSOR_START_DISABLE, - GRUB_VGA_CR_CURSOR_START); - else - cr_write (old | GRUB_VGA_CR_CURSOR_START_DISABLE, - GRUB_VGA_CR_CURSOR_START); -} - -static grub_err_t -grub_vga_text_init_real (struct grub_term_output *term) -{ -#ifdef MODESET - struct grub_bios_int_registers regs; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - -#ifdef MODE_MDA - regs.eax = 7; -#else - regs.eax = 3; -#endif - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); -#endif - grub_vga_text_cls (term); - return 0; -} - -static grub_err_t -grub_vga_text_fini_real (struct grub_term_output *term) -{ -#ifdef MODESET - struct grub_bios_int_registers regs; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - - regs.eax = 3; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); -#endif - grub_vga_text_cls (term); - return 0; -} - -static struct grub_term_coordinate -grub_vga_text_getwh (struct grub_term_output *term __attribute__ ((unused))) -{ - return (struct grub_term_coordinate) { 80, 25 }; -} - -#ifndef MODE_MDA - -static void -grub_vga_text_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), - grub_term_color_state state) -{ - switch (state) { - case GRUB_TERM_COLOR_STANDARD: - cur_color = GRUB_TERM_DEFAULT_STANDARD_COLOR & 0x7f; - break; - case GRUB_TERM_COLOR_NORMAL: - cur_color = grub_term_normal_color & 0x7f; - break; - case GRUB_TERM_COLOR_HIGHLIGHT: - cur_color = grub_term_highlight_color & 0x7f; - break; - default: - break; - } -} - -#else -static void -grub_vga_text_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), - grub_term_color_state state) -{ - switch (state) { - case GRUB_TERM_COLOR_STANDARD: - cur_color = 0x07; - break; - case GRUB_TERM_COLOR_NORMAL: - cur_color = 0x07; - break; - case GRUB_TERM_COLOR_HIGHLIGHT: - cur_color = 0x70; - break; - default: - break; - } -} -#endif - -static struct grub_term_output grub_vga_text_term = - { -#ifdef MODE_MDA - .name = "mda_text", -#else - .name = "vga_text", -#endif - .init = grub_vga_text_init_real, - .fini = grub_vga_text_fini_real, - .putchar = grub_vga_text_putchar, - .getwh = grub_vga_text_getwh, - .getxy = grub_vga_text_getxy, - .gotoxy = grub_vga_text_gotoxy, - .cls = grub_vga_text_cls, - .setcolorstate = grub_vga_text_setcolorstate, - .setcursor = grub_vga_text_setcursor, - .flags = GRUB_TERM_CODE_TYPE_CP437, - .progress_update_divisor = GRUB_PROGRESS_FAST - }; - -#ifndef MODE_MDA - -GRUB_MOD_INIT(vga_text) -{ -#ifdef GRUB_MACHINE_COREBOOT - if (!grub_video_coreboot_fbtable) -#endif - grub_term_register_output ("vga_text", &grub_vga_text_term); -} - -GRUB_MOD_FINI(vga_text) -{ - grub_term_unregister_output (&grub_vga_text_term); -} - -#endif diff --git a/grub-core/term/ieee1275/console.c b/grub-core/term/ieee1275/console.c deleted file mode 100644 index 7231e1824..000000000 --- a/grub-core/term/ieee1275/console.c +++ /dev/null @@ -1,262 +0,0 @@ -/* console.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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static grub_ieee1275_ihandle_t stdout_ihandle; -static grub_ieee1275_ihandle_t stdin_ihandle; - -extern struct grub_terminfo_output_state grub_console_terminfo_output; - -struct color -{ - int red; - int green; - int blue; -}; - -/* Use serial colors as they are default on most firmwares and some firmwares - ignore set-color!. Additionally output may be redirected to serial. */ -static struct color colors[] = - { - // {R, G, B} - {0x00, 0x00, 0x00}, // 0 = black - {0xA8, 0x00, 0x00}, // 1 = red - {0x00, 0xA8, 0x00}, // 2 = green - {0xFE, 0xFE, 0x54}, // 3 = yellow - {0x00, 0x00, 0xA8}, // 4 = blue - {0xA8, 0x00, 0xA8}, // 5 = magenta - {0x00, 0xA8, 0xA8}, // 6 = cyan - {0xFE, 0xFE, 0xFE} // 7 = white - }; - -static void -put (struct grub_term_output *term __attribute__ ((unused)), const int c) -{ - char chr = c; - - grub_ieee1275_write (stdout_ihandle, &chr, 1, 0); -} - -static int -readkey (struct grub_term_input *term __attribute__ ((unused))) -{ - grub_uint8_t c; - grub_ssize_t actual = 0; - - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - if (actual > 0) - return c; - return -1; -} - -static void -grub_console_dimensions (void) -{ - grub_ieee1275_ihandle_t options; - grub_ieee1275_phandle_t stdout_phandle; - char val[1024]; - - /* Always assume 80x24 on serial since screen-#rows/screen-#columns is often - garbage for such devices. */ - if (! grub_ieee1275_instance_to_package (stdout_ihandle, - &stdout_phandle) - && ! grub_ieee1275_package_to_path (stdout_phandle, - val, sizeof (val) - 1, 0)) - { - grub_ieee1275_ihandle_t stdout_options; - val[sizeof (val) - 1] = 0; - - if (! grub_ieee1275_finddevice (val, &stdout_options) - && ! grub_ieee1275_get_property (stdout_options, "device_type", - val, sizeof (val) - 1, 0)) - { - val[sizeof (val) - 1] = 0; - if (grub_strcmp (val, "serial") == 0) - { - grub_console_terminfo_output.size.x = 80; - grub_console_terminfo_output.size.y = 24; - return; - } - } - } - - if (! grub_ieee1275_finddevice ("/options", &options) - && options != (grub_ieee1275_ihandle_t) -1) - { - if (! grub_ieee1275_get_property (options, "screen-#columns", - val, sizeof (val) - 1, 0)) - { - val[sizeof (val) - 1] = 0; - grub_console_terminfo_output.size.x - = (grub_uint8_t) grub_strtoul (val, 0, 10); - } - if (! grub_ieee1275_get_property (options, "screen-#rows", - val, sizeof (val) - 1, 0)) - { - val[sizeof (val) - 1] = 0; - grub_console_terminfo_output.size.y - = (grub_uint8_t) grub_strtoul (val, 0, 10); - } - } - - /* Bogus default value on SLOF in QEMU. */ - if (grub_console_terminfo_output.size.x == 200 - && grub_console_terminfo_output.size.y == 200) - { - grub_console_terminfo_output.size.x = 80; - grub_console_terminfo_output.size.y = 24; - } - - /* Use a small console by default. */ - if (! grub_console_terminfo_output.size.x) - grub_console_terminfo_output.size.x = 80; - if (! grub_console_terminfo_output.size.y) - grub_console_terminfo_output.size.y = 24; -} - -static void -grub_console_setcursor (struct grub_term_output *term, - int on) -{ - grub_terminfo_setcursor (term, on); - - if (!grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF)) - return; - - /* Understood by the Open Firmware flavour in OLPC. */ - if (on) - grub_ieee1275_interpret ("cursor-on", 0); - else - grub_ieee1275_interpret ("cursor-off", 0); -} - -static grub_err_t -grub_console_init_input (struct grub_term_input *term) -{ - 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 grub_terminfo_input_init (term); -} - -static grub_err_t -grub_console_init_output (struct grub_term_output *term) -{ - grub_ssize_t actual; - unsigned int col; - - /* 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. */ - 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_terminfo_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); - - grub_console_dimensions (); - - grub_terminfo_output_init (term); - - return 0; -} - - - -struct grub_terminfo_input_state grub_console_terminfo_input = - { - .readkey = readkey - }; - -struct grub_terminfo_output_state grub_console_terminfo_output = - { - .put = put, - .size = { 80, 24 } - }; - -static struct grub_term_input grub_console_term_input = - { - .name = "console", - .init = grub_console_init_input, - .getkey = grub_terminfo_getkey, - .data = &grub_console_terminfo_input - }; - -static struct grub_term_output grub_console_term_output = - { - .name = "console", - .init = grub_console_init_output, - .putchar = grub_terminfo_putchar, - .getxy = grub_terminfo_getxy, - .getwh = grub_terminfo_getwh, - .gotoxy = grub_terminfo_gotoxy, - .cls = grub_terminfo_cls, - .setcolorstate = grub_terminfo_setcolorstate, - .setcursor = grub_console_setcursor, - .flags = GRUB_TERM_CODE_TYPE_ASCII, - .data = &grub_console_terminfo_output, - .progress_update_divisor = GRUB_PROGRESS_FAST - }; - -void -grub_console_init_early (void) -{ - grub_term_register_input ("console", &grub_console_term_input); - grub_term_register_output ("console", &grub_console_term_output); -} - -void -grub_console_init_lately (void) -{ - const char *type; - - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN)) - type = "ieee1275-nocursor"; - else - type = "ieee1275"; - grub_terminfo_init (); - grub_terminfo_output_register (&grub_console_term_output, type); -} - -void -grub_console_fini (void) -{ -} diff --git a/grub-core/term/ieee1275/escc.c b/grub-core/term/ieee1275/escc.c deleted file mode 100644 index 6ffffbd13..000000000 --- a/grub-core/term/ieee1275/escc.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2012 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -struct grub_escc_descriptor -{ - volatile grub_uint8_t *escc_ctrl; - volatile grub_uint8_t *escc_data; -}; - -static void -do_real_config (struct grub_serial_port *port) -{ - grub_uint8_t bitsspec; - grub_uint8_t parity_stop_spec; - if (port->configured) - return; - - /* Make sure the port is waiting for address now. */ - (void) *port->escc_desc->escc_ctrl; - switch (port->config.speed) - { - case 57600: - *port->escc_desc->escc_ctrl = 13; - *port->escc_desc->escc_ctrl = 0; - *port->escc_desc->escc_ctrl = 12; - *port->escc_desc->escc_ctrl = 0; - *port->escc_desc->escc_ctrl = 14; - *port->escc_desc->escc_ctrl = 1; - *port->escc_desc->escc_ctrl = 11; - *port->escc_desc->escc_ctrl = 0x50; - break; - case 38400: - *port->escc_desc->escc_ctrl = 13; - *port->escc_desc->escc_ctrl = 0; - *port->escc_desc->escc_ctrl = 12; - *port->escc_desc->escc_ctrl = 1; - *port->escc_desc->escc_ctrl = 14; - *port->escc_desc->escc_ctrl = 1; - *port->escc_desc->escc_ctrl = 11; - *port->escc_desc->escc_ctrl = 0x50; - break; - } - - parity_stop_spec = 0; - switch (port->config.parity) - { - case GRUB_SERIAL_PARITY_NONE: - parity_stop_spec |= 0; - break; - case GRUB_SERIAL_PARITY_ODD: - parity_stop_spec |= 1; - break; - case GRUB_SERIAL_PARITY_EVEN: - parity_stop_spec |= 3; - break; - } - - switch (port->config.stop_bits) - { - case GRUB_SERIAL_STOP_BITS_1: - parity_stop_spec |= 0x4; - break; - case GRUB_SERIAL_STOP_BITS_1_5: - parity_stop_spec |= 0x8; - break; - case GRUB_SERIAL_STOP_BITS_2: - parity_stop_spec |= 0xc; - break; - } - - *port->escc_desc->escc_ctrl = 4; - *port->escc_desc->escc_ctrl = 0x40 | parity_stop_spec; - - bitsspec = port->config.word_len - 5; - bitsspec = ((bitsspec >> 1) | (bitsspec << 1)) & 3; - - *port->escc_desc->escc_ctrl = 3; - *port->escc_desc->escc_ctrl = (bitsspec << 6) | 0x1; - - port->configured = 1; - - return; -} - -/* Fetch a key. */ -static int -serial_hw_fetch (struct grub_serial_port *port) -{ - do_real_config (port); - - *port->escc_desc->escc_ctrl = 0; - if (*port->escc_desc->escc_ctrl & 1) - return *port->escc_desc->escc_data; - return -1; -} - -/* Put a character. */ -static void -serial_hw_put (struct grub_serial_port *port, const int c) -{ - grub_uint64_t endtime; - - do_real_config (port); - - if (port->broken > 5) - endtime = grub_get_time_ms (); - else if (port->broken > 1) - endtime = grub_get_time_ms () + 50; - else - endtime = grub_get_time_ms () + 200; - /* Wait until the transmitter holding register is empty. */ - while (1) - { - *port->escc_desc->escc_ctrl = 0; - if (*port->escc_desc->escc_ctrl & 4) - break; - if (grub_get_time_ms () > endtime) - { - port->broken++; - /* There is something wrong. But what can I do? */ - return; - } - } - - if (port->broken) - port->broken--; - - *port->escc_desc->escc_data = 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_configure (struct grub_serial_port *port __attribute__ ((unused)), - struct grub_serial_config *config __attribute__ ((unused))) -{ - if (config->speed != 38400 && config->speed != 57600) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port speed")); - - if (config->parity != GRUB_SERIAL_PARITY_NONE - && config->parity != GRUB_SERIAL_PARITY_ODD - && config->parity != GRUB_SERIAL_PARITY_EVEN) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port parity")); - - if (config->stop_bits != GRUB_SERIAL_STOP_BITS_1 - && config->stop_bits != GRUB_SERIAL_STOP_BITS_1_5 - && config->stop_bits != GRUB_SERIAL_STOP_BITS_2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port stop bits number")); - - if (config->word_len < 5 || config->word_len > 8) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port word length")); - - port->config = *config; - port->configured = 0; - - /* FIXME: should check if the serial terminal was found. */ - - return GRUB_ERR_NONE; -} - -struct grub_serial_driver grub_escc_driver = - { - .configure = serial_hw_configure, - .fetch = serial_hw_fetch, - .put = serial_hw_put - }; - -static struct grub_escc_descriptor escc_descs[2]; -static char *macio = 0; - -static void -add_device (grub_addr_t addr, int channel) -{ - struct grub_serial_port *port; - grub_err_t err; - struct grub_serial_config config = - { - .speed = 38400, - .word_len = 8, - .parity = GRUB_SERIAL_PARITY_NONE, - .stop_bits = GRUB_SERIAL_STOP_BITS_1 - }; - - escc_descs[channel].escc_ctrl - = (volatile grub_uint8_t *) (grub_addr_t) addr; - escc_descs[channel].escc_data = escc_descs[channel].escc_ctrl + 16; - - port = grub_zalloc (sizeof (*port)); - if (!port) - { - grub_errno = 0; - return; - } - - port->name = grub_xasprintf ("escc-ch-%c", channel + 'a'); - if (!port->name) - { - grub_errno = 0; - return; - } - - port->escc_desc = &escc_descs[channel]; - - port->driver = &grub_escc_driver; - - err = port->driver->configure (port, &config); - if (err) - grub_print_error (); - - grub_serial_register (port); -} - -static int -find_macio (struct grub_ieee1275_devalias *alias) -{ - if (grub_strcmp (alias->type, "mac-io") != 0) - return 0; - macio = grub_strdup (alias->path); - return 1; -} - -GRUB_MOD_INIT (escc) -{ - grub_uint32_t macio_addr[4]; - grub_uint32_t escc_addr[2]; - grub_ieee1275_phandle_t dev; - struct grub_ieee1275_devalias alias; - char *escc = 0; - - grub_ieee1275_devices_iterate (find_macio); - if (!macio) - return; - - FOR_IEEE1275_DEVCHILDREN(macio, alias) - if (grub_strcmp (alias.type, "escc") == 0) - { - escc = grub_strdup (alias.path); - break; - } - grub_ieee1275_devalias_free (&alias); - if (!escc) - { - grub_free (macio); - return; - } - - if (grub_ieee1275_finddevice (macio, &dev)) - { - grub_free (macio); - grub_free (escc); - return; - } - if (grub_ieee1275_get_integer_property (dev, "assigned-addresses", - macio_addr, sizeof (macio_addr), 0)) - { - grub_free (macio); - grub_free (escc); - return; - } - - if (grub_ieee1275_finddevice (escc, &dev)) - { - grub_free (macio); - grub_free (escc); - return; - } - - if (grub_ieee1275_get_integer_property (dev, "reg", - escc_addr, sizeof (escc_addr), 0)) - { - grub_free (macio); - grub_free (escc); - return; - } - - add_device (macio_addr[2] + escc_addr[0] + 32, 0); - add_device (macio_addr[2] + escc_addr[0], 1); - - grub_free (macio); - grub_free (escc); -} - -GRUB_MOD_FINI (escc) -{ -} diff --git a/grub-core/term/ieee1275/serial.c b/grub-core/term/ieee1275/serial.c deleted file mode 100644 index ac2a8f827..000000000 --- a/grub-core/term/ieee1275/serial.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2012 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct ofserial_hash_ent -{ - char *devpath; - /* Pointer to shortest available name on nodes representing canonical names, - otherwise NULL. */ - const char *shortest; - struct ofserial_hash_ent *next; -}; - -static void -do_real_config (struct grub_serial_port *port) -{ - if (port->configured) - return; - - if (grub_ieee1275_open (port->elem->devpath, &port->handle) - || port->handle == (grub_ieee1275_ihandle_t) -1) - port->handle = GRUB_IEEE1275_IHANDLE_INVALID; - - port->configured = 1; -} - -/* Fetch a key. */ -static int -serial_hw_fetch (struct grub_serial_port *port) -{ - grub_ssize_t actual; - char c; - - do_real_config (port); - - if (port->handle == GRUB_IEEE1275_IHANDLE_INVALID) - return -1; - grub_ieee1275_read (port->handle, &c, 1, &actual); - - if (actual <= 0) - return -1; - return c; -} - -/* Put a character. */ -static void -serial_hw_put (struct grub_serial_port *port, const int c) -{ - grub_ssize_t actual; - char c0 = c; - - do_real_config (port); - - if (port->handle == GRUB_IEEE1275_IHANDLE_INVALID) - return; - - grub_ieee1275_write (port->handle, &c0, 1, &actual); -} - -/* 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_configure (struct grub_serial_port *port __attribute__ ((unused)), - struct grub_serial_config *config __attribute__ ((unused))) -{ - /* FIXME: no IEEE1275 serial config available. */ - - return GRUB_ERR_NONE; -} - -struct grub_serial_driver grub_ofserial_driver = - { - .configure = serial_hw_configure, - .fetch = serial_hw_fetch, - .put = serial_hw_put - }; - -#define OFSERIAL_HASH_SZ 8 -static struct ofserial_hash_ent *ofserial_hash[OFSERIAL_HASH_SZ]; - -static int -ofserial_hash_fn (const char *devpath) -{ - int hash = 0; - while (*devpath) - hash ^= *devpath++; - return (hash & (OFSERIAL_HASH_SZ - 1)); -} - -static struct ofserial_hash_ent * -ofserial_hash_find (const char *devpath) -{ - struct ofserial_hash_ent *p = ofserial_hash[ofserial_hash_fn(devpath)]; - - while (p) - { - if (!grub_strcmp (p->devpath, devpath)) - break; - p = p->next; - } - return p; -} - -static struct ofserial_hash_ent * -ofserial_hash_add_real (char *devpath) -{ - struct ofserial_hash_ent *p; - struct ofserial_hash_ent **head = &ofserial_hash[ofserial_hash_fn(devpath)]; - - p = grub_malloc(sizeof (*p)); - if (!p) - return NULL; - - p->devpath = devpath; - p->next = *head; - p->shortest = 0; - *head = p; - return p; -} - -static struct ofserial_hash_ent * -ofserial_hash_add (char *devpath, char *curcan) -{ - struct ofserial_hash_ent *p, *pcan; - - p = ofserial_hash_add_real (devpath); - - grub_dprintf ("serial", "devpath = %s, canonical = %s\n", devpath, curcan); - - if (!curcan) - { - p->shortest = devpath; - return p; - } - - pcan = ofserial_hash_find (curcan); - if (!pcan) - pcan = ofserial_hash_add_real (curcan); - else - grub_free (curcan); - - if (!pcan) - grub_errno = GRUB_ERR_NONE; - else - { - if (!pcan->shortest - || grub_strlen (pcan->shortest) > grub_strlen (devpath)) - pcan->shortest = devpath; - } - - return p; -} - -static void -dev_iterate_real (struct grub_ieee1275_devalias *alias, - int use_name) -{ - struct ofserial_hash_ent *op; - - if (grub_strcmp (alias->type, "serial") != 0) - return; - - grub_dprintf ("serial", "serial name = %s, path = %s\n", alias->name, - alias->path); - - op = ofserial_hash_find (alias->path); - if (!op) - { - char *name = grub_strdup (use_name ? alias->name : alias->path); - char *can = grub_strdup (alias->path); - if (!name || !can) - { - grub_errno = GRUB_ERR_NONE; - grub_free (name); - grub_free (can); - return; - } - op = ofserial_hash_add (name, can); - } - return; -} - -static int -dev_iterate (struct grub_ieee1275_devalias *alias) -{ - dev_iterate_real (alias, 0); - return 0; -} - -static struct grub_serial_port * -add_port (struct ofserial_hash_ent *ent) -{ - struct grub_serial_port *port; - char *ptr; - grub_err_t err; - - if (!ent->shortest) - return NULL; - - FOR_SERIAL_PORTS (port) - if (port->elem == ent) - return port; - - port = grub_zalloc (sizeof (*port)); - if (!port) - return NULL; - port->name = grub_malloc (sizeof ("ieee1275/") - + grub_strlen (ent->shortest)); - port->elem = ent; - if (!port->name) - return NULL; - ptr = grub_stpcpy (port->name, "ieee1275/"); - grub_strcpy (ptr, ent->shortest); - - port->driver = &grub_ofserial_driver; - err = grub_serial_config_defaults (port); - if (err) - grub_print_error (); - - grub_serial_register (port); - - return port; -} - -struct grub_serial_port * -grub_ofserial_add_port (const char *path) -{ - struct ofserial_hash_ent *ent; - char *name = grub_strdup (path); - char *can = grub_strdup (path); - - if (!name || ! can) - { - grub_free (name); - grub_free (can); - return NULL; - } - - ent = ofserial_hash_add (name, can); - return add_port (ent); -} - -void -grub_ofserial_init (void) -{ - unsigned i; - struct grub_ieee1275_devalias alias; - - FOR_IEEE1275_DEVALIASES(alias) - dev_iterate_real (&alias, 1); - - grub_ieee1275_devices_iterate (dev_iterate); - - for (i = 0; i < ARRAY_SIZE (ofserial_hash); i++) - { - struct ofserial_hash_ent *ent; - for (ent = ofserial_hash[i]; ent; ent = ent->next) - add_port (ent); - } -} - diff --git a/grub-core/term/morse.c b/grub-core/term/morse.c deleted file mode 100644 index 13b8e863e..000000000 --- a/grub-core/term/morse.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define BASE_TIME 250 -#define DIH 1 -#define DAH 3 -#define END 0 - -static const char codes[0x80][6] = - { - ['0'] = { DAH, DAH, DAH, DAH, DAH, END }, - ['1'] = { DIH, DAH, DAH, DAH, DAH, END }, - ['2'] = { DIH, DIH, DAH, DAH, DAH, END }, - ['3'] = { DIH, DIH, DIH, DAH, DAH, END }, - ['4'] = { DIH, DIH, DIH, DIH, DAH, END }, - ['5'] = { DIH, DIH, DIH, DIH, DIH, END }, - ['6'] = { DAH, DIH, DIH, DIH, DIH, END }, - ['7'] = { DAH, DAH, DIH, DIH, DIH, END }, - ['8'] = { DAH, DAH, DAH, DIH, DIH, END }, - ['9'] = { DAH, DAH, DAH, DAH, DIH, END }, - ['a'] = { DIH, DAH, END }, - ['b'] = { DAH, DIH, DIH, DIH, END }, - ['c'] = { DAH, DIH, DAH, DIH, END }, - ['d'] = { DAH, DIH, DIH, END }, - ['e'] = { DIH, END }, - ['f'] = { DIH, DIH, DAH, DIH, END }, - ['g'] = { DAH, DAH, DIH, END }, - ['h'] = { DIH, DIH, DIH, DIH, END }, - ['i'] = { DIH, DIH, END }, - ['j'] = { DIH, DAH, DAH, DAH, END }, - ['k'] = { DAH, DIH, DAH, END }, - ['l'] = { DIH, DAH, DIH, DIH, END }, - ['m'] = { DAH, DAH, END }, - ['n'] = { DAH, DIH, END }, - ['o'] = { DAH, DAH, DAH, END }, - ['p'] = { DIH, DAH, DAH, DIH, END }, - ['q'] = { DAH, DAH, DIH, DAH, END }, - ['r'] = { DIH, DAH, DIH, END }, - ['s'] = { DIH, DIH, DIH, END }, - ['t'] = { DAH, END }, - ['u'] = { DIH, DIH, DAH, END }, - ['v'] = { DIH, DIH, DIH, DAH, END }, - ['w'] = { DIH, DAH, DAH, END }, - ['x'] = { DAH, DIH, DIH, DAH, END }, - ['y'] = { DAH, DIH, DAH, DAH, END }, - ['z'] = { DAH, DAH, DIH, DIH, END } - }; - -static void -grub_audio_tone (int length) -{ - grub_speaker_beep_on (1000); - grub_millisleep (length); - grub_speaker_beep_off (); -} - -static void -grub_audio_putchar (struct grub_term_output *term __attribute__ ((unused)), - const struct grub_unicode_glyph *c_in) -{ - grub_uint8_t c; - int i; - - /* For now, do not try to use a surrogate pair. */ - if (c_in->base > 0x7f) - c = '?'; - else - c = grub_tolower (c_in->base); - for (i = 0; codes[c][i]; i++) - { - grub_audio_tone (codes[c][i] * BASE_TIME); - grub_millisleep (BASE_TIME); - } - grub_millisleep (2 * BASE_TIME); -} - - -static int -dummy (void) -{ - return 0; -} - -static struct grub_term_output grub_audio_term_output = - { - .name = "morse", - .init = (void *) dummy, - .fini = (void *) dummy, - .putchar = grub_audio_putchar, - .getwh = (void *) dummy, - .getxy = (void *) dummy, - .gotoxy = (void *) dummy, - .cls = (void *) dummy, - .setcolorstate = (void *) dummy, - .setcursor = (void *) dummy, - .flags = GRUB_TERM_CODE_TYPE_ASCII | GRUB_TERM_DUMB, - .progress_update_divisor = GRUB_PROGRESS_NO_UPDATE - }; - -GRUB_MOD_INIT (morse) -{ - grub_term_register_output ("audio", &grub_audio_term_output); -} - -GRUB_MOD_FINI (morse) -{ - grub_term_unregister_output (&grub_audio_term_output); -} diff --git a/grub-core/term/ns8250-spcr.c b/grub-core/term/ns8250-spcr.c deleted file mode 100644 index 428b2d59a..000000000 --- a/grub-core/term/ns8250-spcr.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#if !defined(GRUB_MACHINE_IEEE1275) && !defined(GRUB_MACHINE_QEMU) - -#include -#include -#include -#include -#include -#include - -struct grub_serial_port * -grub_ns8250_spcr_init (void) -{ - struct grub_acpi_spcr *spcr; - struct grub_serial_config config; - - spcr = grub_acpi_find_table (GRUB_ACPI_SPCR_SIGNATURE); - if (spcr == NULL) - return NULL; - if (spcr->hdr.revision < 2) - grub_dprintf ("serial", "SPCR table revision %d < 2, continuing anyway\n", - (int) spcr->hdr.revision); - if (spcr->intf_type != GRUB_ACPI_SPCR_INTF_TYPE_16550 && - spcr->intf_type != GRUB_ACPI_SPCR_INTF_TYPE_16550_DBGP && - spcr->intf_type != GRUB_ACPI_SPCR_INTF_TYPE_16550_DBG2) - return NULL; - /* For now, we only support byte accesses. */ - if (spcr->base_addr.access_size != GRUB_ACPI_GENADDR_SIZE_BYTE && - spcr->base_addr.access_size != GRUB_ACPI_GENADDR_SIZE_LGCY) - return NULL; - config.word_len = 8; - config.parity = GRUB_SERIAL_PARITY_NONE; - config.stop_bits = GRUB_SERIAL_STOP_BITS_1; - config.base_clock = UART_DEFAULT_BASE_CLOCK; - if (spcr->flow_control & GRUB_ACPI_SPCR_FC_RTSCTS) - config.rtscts = 1; - else - config.rtscts = 0; - switch (spcr->baud_rate) - { - case GRUB_ACPI_SPCR_BAUD_9600: - config.speed = 9600; - break; - case GRUB_ACPI_SPCR_BAUD_19200: - config.speed = 19200; - break; - case GRUB_ACPI_SPCR_BAUD_57600: - config.speed = 57600; - break; - case GRUB_ACPI_SPCR_BAUD_115200: - config.speed = 115200; - break; - case GRUB_ACPI_SPCR_BAUD_CURRENT: - default: - /* - * We don't (yet) have a way to read the currently - * configured speed in HW, so let's use a sane default. - */ - config.speed = 115200; - break; - }; - - /* If base address is 0 it means redirection is disabled. */ - if (spcr->base_addr.addr == 0) - return NULL; - - switch (spcr->base_addr.space_id) - { - case GRUB_ACPI_GENADDR_MEM_SPACE: - return grub_serial_ns8250_add_mmio (spcr->base_addr.addr, - spcr->base_addr.access_size, &config); - case GRUB_ACPI_GENADDR_IO_SPACE: - return grub_serial_ns8250_add_port (spcr->base_addr.addr, &config); - default: - return NULL; - }; -} - -#endif diff --git a/grub-core/term/ns8250.c b/grub-core/term/ns8250.c deleted file mode 100644 index 23e8e0904..000000000 --- a/grub-core/term/ns8250.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef GRUB_MACHINE_PCBIOS -#include -#define GRUB_SERIAL_PORT_NUM 4 -#else -#include -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 - -static int dead_ports = 0; - -static grub_uint8_t -ns8250_reg_read (struct grub_serial_port *port, grub_addr_t reg) -{ - asm volatile("" : : : "memory"); - if (port->use_mmio == true) - { - /* - * Note: we assume MMIO UARTs are little endian. This is not true of all - * embedded platforms but will do for now. - */ - switch(port->mmio.access_size) - { - default: - /* ACPI tables occasionally uses "0" (legacy) as equivalent to "1" (byte). */ - case 1: - return *((volatile grub_uint8_t *) (port->mmio.base + reg)); - case 2: - return grub_le_to_cpu16 (*((volatile grub_uint16_t *) (port->mmio.base + (reg << 1)))); - case 3: - return grub_le_to_cpu32 (*((volatile grub_uint32_t *) (port->mmio.base + (reg << 2)))); - case 4: - /* - * This will only work properly on 64-bit systems since 64-bit - * accessors aren't atomic on 32-bit hardware. Thankfully the - * case of a UART with a 64-bit register spacing on 32-bit - * also probably doesn't exist. - */ - return grub_le_to_cpu64 (*((volatile grub_uint64_t *) (port->mmio.base + (reg << 3)))); - } - } - return grub_inb (port->port + reg); -} - -static void -ns8250_reg_write (struct grub_serial_port *port, grub_uint8_t value, grub_addr_t reg) -{ - asm volatile("" : : : "memory"); - if (port->use_mmio == true) - { - switch(port->mmio.access_size) - { - default: - /* ACPI tables occasionally uses "0" (legacy) as equivalent to "1" (byte). */ - case 1: - *((volatile grub_uint8_t *) (port->mmio.base + reg)) = value; - break; - case 2: - *((volatile grub_uint16_t *) (port->mmio.base + (reg << 1))) = grub_cpu_to_le16 (value); - break; - case 3: - *((volatile grub_uint32_t *) (port->mmio.base + (reg << 2))) = grub_cpu_to_le32 (value); - break; - case 4: - /* See commment in ns8250_reg_read(). */ - *((volatile grub_uint64_t *) (port->mmio.base + (reg << 3))) = grub_cpu_to_le64 (value); - break; - } - } - else - grub_outb (value, port->port + reg); -} - -/* Convert speed to divisor. */ -static unsigned short -serial_get_divisor (const struct grub_serial_port *port __attribute__ ((unused)), - const struct grub_serial_config *config) -{ - grub_uint32_t base_clock; - grub_uint32_t divisor; - grub_uint32_t actual_speed, error; - - /* Get the UART input clock frequency. */ - base_clock = config->base_clock ? config->base_clock : UART_DEFAULT_BASE_CLOCK; - - /* - * The UART uses 16 times oversampling for the BRG, so adjust the value - * accordingly to calculate the divisor. - */ - base_clock >>= 4; - - divisor = (base_clock + (config->speed / 2)) / config->speed; - if (config->speed == 0) - return 0; - if (divisor > 0xffff || divisor == 0) - return 0; - actual_speed = base_clock / divisor; - error = actual_speed > config->speed ? (actual_speed - config->speed) - : (config->speed - actual_speed); - if (error > (config->speed / 30 + 1)) - return 0; - return divisor; -} - -static void -do_real_config (struct grub_serial_port *port) -{ - int divisor; - unsigned char status = 0; - grub_uint64_t endtime; - - const unsigned char parities[] = { - [GRUB_SERIAL_PARITY_NONE] = UART_NO_PARITY, - [GRUB_SERIAL_PARITY_ODD] = UART_ODD_PARITY, - [GRUB_SERIAL_PARITY_EVEN] = UART_EVEN_PARITY - }; - const unsigned char stop_bits[] = { - [GRUB_SERIAL_STOP_BITS_1] = UART_1_STOP_BIT, - [GRUB_SERIAL_STOP_BITS_2] = UART_2_STOP_BITS, - }; - - if (port->configured) - return; - - port->broken = 0; - - divisor = serial_get_divisor (port, &port->config); - - /* Turn off the interrupt. */ - ns8250_reg_write (port, 0, UART_IER); - - /* Set DLAB. */ - ns8250_reg_write (port, UART_DLAB, UART_LCR); - - ns8250_reg_write (port, divisor & 0xFF, UART_DLL); - ns8250_reg_write (port, divisor >> 8, UART_DLH); - - /* Set the line status. */ - status |= (parities[port->config.parity] - | (port->config.word_len - 5) - | stop_bits[port->config.stop_bits]); - ns8250_reg_write (port, status, UART_LCR); - - if (port->config.rtscts) - { - /* Enable the FIFO. */ - ns8250_reg_write (port, UART_ENABLE_FIFO_TRIGGER1, UART_FCR); - - /* Turn on DTR and RTS. */ - ns8250_reg_write (port, UART_ENABLE_DTRRTS, UART_MCR); - } - else - { - /* Enable the FIFO. */ - ns8250_reg_write (port, UART_ENABLE_FIFO_TRIGGER14, UART_FCR); - - /* Turn on DTR, RTS, and OUT2. */ - ns8250_reg_write (port, UART_ENABLE_DTRRTS | UART_ENABLE_OUT2, UART_MCR); - } - - /* Drain the input buffer. */ - endtime = grub_get_time_ms () + 1000; - while (ns8250_reg_read (port, UART_LSR) & UART_DATA_READY) - { - ns8250_reg_read (port, UART_RX); - if (grub_get_time_ms () > endtime) - { - port->broken = 1; - break; - } - } - - port->configured = 1; -} - -/* Fetch a key. */ -static int -serial_hw_fetch (struct grub_serial_port *port) -{ - do_real_config (port); - if (ns8250_reg_read (port, UART_LSR) & UART_DATA_READY) - return ns8250_reg_read (port, UART_RX); - - return -1; -} - -/* Put a character. */ -static void -serial_hw_put (struct grub_serial_port *port, const int c) -{ - grub_uint64_t endtime; - - do_real_config (port); - - if (port->broken > 5) - endtime = grub_get_time_ms (); - else if (port->broken > 1) - endtime = grub_get_time_ms () + 50; - else - endtime = grub_get_time_ms () + 200; - /* Wait until the transmitter holding register is empty. */ - while ((ns8250_reg_read (port, UART_LSR) & UART_EMPTY_TRANSMITTER) == 0) - { - if (grub_get_time_ms () > endtime) - { - port->broken++; - /* There is something wrong. But what can I do? */ - return; - } - } - - if (port->broken) - port->broken--; - - ns8250_reg_write (port, c, UART_TX); -} - -/* 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_configure (struct grub_serial_port *port, - struct grub_serial_config *config) -{ - unsigned short divisor; - - divisor = serial_get_divisor (port, config); - if (divisor == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port speed")); - - if (config->parity != GRUB_SERIAL_PARITY_NONE - && config->parity != GRUB_SERIAL_PARITY_ODD - && config->parity != GRUB_SERIAL_PARITY_EVEN) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port parity")); - - if (config->stop_bits != GRUB_SERIAL_STOP_BITS_1 - && config->stop_bits != GRUB_SERIAL_STOP_BITS_2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port stop bits number")); - - if (config->word_len < 5 || config->word_len > 8) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port word length")); - - port->config = *config; - port->configured = 0; - - /* FIXME: should check if the serial terminal was found. */ - - return GRUB_ERR_NONE; -} - -struct grub_serial_driver grub_ns8250_driver = - { - .configure = serial_hw_configure, - .fetch = serial_hw_fetch, - .put = serial_hw_put - }; - -static char com_names[GRUB_SERIAL_PORT_NUM][20]; -static struct grub_serial_port com_ports[GRUB_SERIAL_PORT_NUM]; - -void -grub_ns8250_init (void) -{ -#ifdef GRUB_MACHINE_PCBIOS - const unsigned short *serial_hw_io_addr = (const unsigned short *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR); -#endif - unsigned i; - for (i = 0; i < GRUB_SERIAL_PORT_NUM; i++) - if (serial_hw_io_addr[i]) - { - grub_err_t err; - - grub_outb (0x5a, serial_hw_io_addr[i] + UART_SR); - if (grub_inb (serial_hw_io_addr[i] + UART_SR) != 0x5a) - { - dead_ports |= (1 << i); - continue; - } - grub_outb (0xa5, serial_hw_io_addr[i] + UART_SR); - if (grub_inb (serial_hw_io_addr[i] + UART_SR) != 0xa5) - { - dead_ports |= (1 << i); - continue; - } - - grub_snprintf (com_names[i], sizeof (com_names[i]), "com%d", i); - com_ports[i].name = com_names[i]; - com_ports[i].driver = &grub_ns8250_driver; - com_ports[i].port = serial_hw_io_addr[i]; - com_ports[i].use_mmio = false; - err = grub_serial_config_defaults (&com_ports[i]); - if (err) - grub_print_error (); - - grub_serial_register (&com_ports[i]); - } -} - -/* Return the port number for the UNITth serial device. */ -grub_port_t -grub_ns8250_hw_get_port (const unsigned int unit) -{ -#ifdef GRUB_MACHINE_PCBIOS - const unsigned short *serial_hw_io_addr = (const unsigned short *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR); -#endif - if (unit < GRUB_SERIAL_PORT_NUM - && !(dead_ports & (1 << unit))) - return serial_hw_io_addr[unit]; - else - return 0; -} - -struct grub_serial_port * -grub_serial_ns8250_add_port (grub_port_t port, struct grub_serial_config *config) -{ - struct grub_serial_port *p; - unsigned i; - - for (i = 0; i < GRUB_SERIAL_PORT_NUM; i++) - if (com_ports[i].port == port) - { - if (dead_ports & (1 << i)) - return NULL; - /* Give the opportunity for SPCR to configure a default com port. */ - if (config != NULL) - grub_serial_port_configure (&com_ports[i], config); - return &com_ports[i]; - } - - FOR_SERIAL_PORTS (p) - if (p->use_mmio == false && p->port == port) - { - if (config != NULL) - grub_serial_port_configure (p, config); - return p; - } - - grub_outb (0x5a, port + UART_SR); - if (grub_inb (port + UART_SR) != 0x5a) - return NULL; - - grub_outb (0xa5, port + UART_SR); - if (grub_inb (port + UART_SR) != 0xa5) - return NULL; - - p = grub_malloc (sizeof (*p)); - if (p == NULL) - return NULL; - p->name = grub_xasprintf ("port%lx", (unsigned long) port); - if (p->name == NULL) - { - grub_free (p); - return NULL; - } - p->driver = &grub_ns8250_driver; - p->use_mmio = false; - p->port = port; - if (config != NULL) - grub_serial_port_configure (p, config); - else - grub_serial_config_defaults (p); - grub_serial_register (p); - - return p; -} - -struct grub_serial_port * -grub_serial_ns8250_add_mmio (grub_addr_t addr, unsigned int acc_size, - struct grub_serial_config *config) -{ - struct grub_serial_port *p; - unsigned i; - - for (i = 0; i < GRUB_SERIAL_PORT_NUM; i++) - if (com_ports[i].use_mmio == true && com_ports[i].mmio.base == addr) - { - if (config != NULL) - grub_serial_port_configure (&com_ports[i], config); - return &com_ports[i]; - } - - FOR_SERIAL_PORTS (p) - if (p->use_mmio == true && p->mmio.base == addr) - { - if (config != NULL) - grub_serial_port_configure (p, config); - return p; - } - - p = grub_malloc (sizeof (*p)); - if (p == NULL) - return NULL; - p->name = grub_xasprintf ("mmio,%llx", (unsigned long long) addr); - if (p->name == NULL) - { - grub_free (p); - return NULL; - } - p->driver = &grub_ns8250_driver; - p->use_mmio = true; - p->mmio.base = addr; - p->mmio.access_size = acc_size; - if (config != NULL) - grub_serial_port_configure (p, config); - else - grub_serial_config_defaults (p); - grub_serial_register (p); - - return p; -} diff --git a/grub-core/term/pci/serial.c b/grub-core/term/pci/serial.c deleted file mode 100644 index 4b7a4a862..000000000 --- a/grub-core/term/pci/serial.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -static int -find_pciserial (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)), void *data __attribute__ ((unused))) -{ - grub_pci_address_t cmd_addr, class_addr, bar_addr; - struct grub_serial_port *port; - grub_uint32_t class, bar; - grub_uint16_t cmdreg; - grub_err_t err; - - cmd_addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - cmdreg = grub_pci_read (cmd_addr); - - class_addr = grub_pci_make_address (dev, GRUB_PCI_REG_REVISION); - class = grub_pci_read (class_addr); - - bar_addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - bar = grub_pci_read (bar_addr); - - /* 16550 compatible MODEM or SERIAL. */ - if (((class >> 16) != GRUB_PCI_CLASS_COMMUNICATION_MODEM && - (class >> 16) != GRUB_PCI_CLASS_COMMUNICATION_SERIAL) || - ((class >> 8) & 0xff) != GRUB_PCI_SERIAL_16550_COMPATIBLE) - return 0; - - if ((bar & GRUB_PCI_ADDR_SPACE_MASK) != GRUB_PCI_ADDR_SPACE_IO) - return 0; - - port = grub_zalloc (sizeof (*port)); - if (port == NULL) - return 0; - - port->name = grub_xasprintf ("pci,%02x:%02x.%x", - grub_pci_get_bus (dev), - grub_pci_get_device (dev), - grub_pci_get_function (dev)); - if (port->name == NULL) - goto fail; - - grub_pci_write (cmd_addr, cmdreg | GRUB_PCI_COMMAND_IO_ENABLED); - - port->driver = &grub_ns8250_driver; - port->port = bar & GRUB_PCI_ADDR_IO_MASK; - err = grub_serial_config_defaults (port); - if (err != GRUB_ERR_NONE) - { - grub_print_error (); - goto fail; - } - - err = grub_serial_register (port); - if (err != GRUB_ERR_NONE) - goto fail; - - return 0; - - fail: - grub_free (port->name); - grub_free (port); - return 0; -} - -void -grub_pciserial_init (void) -{ - grub_pci_iterate (find_pciserial, NULL); -} diff --git a/grub-core/term/ps2.c b/grub-core/term/ps2.c deleted file mode 100644 index c7a09a821..000000000 --- a/grub-core/term/ps2.c +++ /dev/null @@ -1,387 +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 . - */ - -#include -#include -#include -#include -#include - -#define KEYBOARD_LED_SCROLL (1 << 0) -#define KEYBOARD_LED_NUM (1 << 1) -#define KEYBOARD_LED_CAPS (1 << 2) - -static const grub_uint8_t set1_mapping[128] = - { - /* 0x00 */ 0 /* Unused */, GRUB_KEYBOARD_KEY_ESCAPE, - /* 0x02 */ GRUB_KEYBOARD_KEY_1, GRUB_KEYBOARD_KEY_2, - /* 0x04 */ GRUB_KEYBOARD_KEY_3, GRUB_KEYBOARD_KEY_4, - /* 0x06 */ GRUB_KEYBOARD_KEY_5, GRUB_KEYBOARD_KEY_6, - /* 0x08 */ GRUB_KEYBOARD_KEY_7, GRUB_KEYBOARD_KEY_8, - /* 0x0a */ GRUB_KEYBOARD_KEY_9, GRUB_KEYBOARD_KEY_0, - /* 0x0c */ GRUB_KEYBOARD_KEY_DASH, GRUB_KEYBOARD_KEY_EQUAL, - /* 0x0e */ GRUB_KEYBOARD_KEY_BACKSPACE, GRUB_KEYBOARD_KEY_TAB, - /* 0x10 */ GRUB_KEYBOARD_KEY_Q, GRUB_KEYBOARD_KEY_W, - /* 0x12 */ GRUB_KEYBOARD_KEY_E, GRUB_KEYBOARD_KEY_R, - /* 0x14 */ GRUB_KEYBOARD_KEY_T, GRUB_KEYBOARD_KEY_Y, - /* 0x16 */ GRUB_KEYBOARD_KEY_U, GRUB_KEYBOARD_KEY_I, - /* 0x18 */ GRUB_KEYBOARD_KEY_O, GRUB_KEYBOARD_KEY_P, - /* 0x1a */ GRUB_KEYBOARD_KEY_LBRACKET, GRUB_KEYBOARD_KEY_RBRACKET, - /* 0x1c */ GRUB_KEYBOARD_KEY_ENTER, GRUB_KEYBOARD_KEY_LEFT_CTRL, - /* 0x1e */ GRUB_KEYBOARD_KEY_A, GRUB_KEYBOARD_KEY_S, - /* 0x20 */ GRUB_KEYBOARD_KEY_D, GRUB_KEYBOARD_KEY_F, - /* 0x22 */ GRUB_KEYBOARD_KEY_G, GRUB_KEYBOARD_KEY_H, - /* 0x24 */ GRUB_KEYBOARD_KEY_J, GRUB_KEYBOARD_KEY_K, - /* 0x26 */ GRUB_KEYBOARD_KEY_L, GRUB_KEYBOARD_KEY_SEMICOLON, - /* 0x28 */ GRUB_KEYBOARD_KEY_DQUOTE, GRUB_KEYBOARD_KEY_RQUOTE, - /* 0x2a */ GRUB_KEYBOARD_KEY_LEFT_SHIFT, GRUB_KEYBOARD_KEY_BACKSLASH, - /* 0x2c */ GRUB_KEYBOARD_KEY_Z, GRUB_KEYBOARD_KEY_X, - /* 0x2e */ GRUB_KEYBOARD_KEY_C, GRUB_KEYBOARD_KEY_V, - /* 0x30 */ GRUB_KEYBOARD_KEY_B, GRUB_KEYBOARD_KEY_N, - /* 0x32 */ GRUB_KEYBOARD_KEY_M, GRUB_KEYBOARD_KEY_COMMA, - /* 0x34 */ GRUB_KEYBOARD_KEY_DOT, GRUB_KEYBOARD_KEY_SLASH, - /* 0x36 */ GRUB_KEYBOARD_KEY_RIGHT_SHIFT, GRUB_KEYBOARD_KEY_NUMMUL, - /* 0x38 */ GRUB_KEYBOARD_KEY_LEFT_ALT, GRUB_KEYBOARD_KEY_SPACE, - /* 0x3a */ GRUB_KEYBOARD_KEY_CAPS_LOCK, GRUB_KEYBOARD_KEY_F1, - /* 0x3c */ GRUB_KEYBOARD_KEY_F2, GRUB_KEYBOARD_KEY_F3, - /* 0x3e */ GRUB_KEYBOARD_KEY_F4, GRUB_KEYBOARD_KEY_F5, - /* 0x40 */ GRUB_KEYBOARD_KEY_F6, GRUB_KEYBOARD_KEY_F7, - /* 0x42 */ GRUB_KEYBOARD_KEY_F8, GRUB_KEYBOARD_KEY_F9, - /* 0x44 */ GRUB_KEYBOARD_KEY_F10, GRUB_KEYBOARD_KEY_NUM_LOCK, - /* 0x46 */ GRUB_KEYBOARD_KEY_SCROLL_LOCK, GRUB_KEYBOARD_KEY_NUM7, - /* 0x48 */ GRUB_KEYBOARD_KEY_NUM8, GRUB_KEYBOARD_KEY_NUM9, - /* 0x4a */ GRUB_KEYBOARD_KEY_NUMMINUS, GRUB_KEYBOARD_KEY_NUM4, - /* 0x4c */ GRUB_KEYBOARD_KEY_NUM5, GRUB_KEYBOARD_KEY_NUM6, - /* 0x4e */ GRUB_KEYBOARD_KEY_NUMPLUS, GRUB_KEYBOARD_KEY_NUM1, - /* 0x50 */ GRUB_KEYBOARD_KEY_NUM2, GRUB_KEYBOARD_KEY_NUM3, - /* 0x52 */ GRUB_KEYBOARD_KEY_NUM0, GRUB_KEYBOARD_KEY_NUMDOT, - /* 0x54 */ 0, 0, - /* 0x56 */ GRUB_KEYBOARD_KEY_102ND, GRUB_KEYBOARD_KEY_F11, - /* 0x58 */ GRUB_KEYBOARD_KEY_F12, 0, - /* 0x5a */ 0, 0, - /* 0x5c */ 0, 0, - /* 0x5e */ 0, 0, - /* 0x60 */ 0, 0, - /* 0x62 */ 0, 0, - /* OLPC keys. Just mapped to normal keys. */ - /* 0x64 */ 0, GRUB_KEYBOARD_KEY_UP, - /* 0x66 */ GRUB_KEYBOARD_KEY_DOWN, GRUB_KEYBOARD_KEY_LEFT, - /* 0x68 */ GRUB_KEYBOARD_KEY_RIGHT, 0, - /* 0x6a */ 0, 0, - /* 0x6c */ 0, 0, - /* 0x6e */ 0, 0, - /* 0x70 */ 0, 0, - /* 0x72 */ 0, GRUB_KEYBOARD_KEY_JP_RO, - /* 0x74 */ 0, 0, - /* 0x76 */ 0, 0, - /* 0x78 */ 0, 0, - /* 0x7a */ 0, 0, - /* 0x7c */ 0, GRUB_KEYBOARD_KEY_JP_YEN, - /* 0x7e */ GRUB_KEYBOARD_KEY_KPCOMMA - }; - -static const struct -{ - grub_uint8_t from, to; -} set1_e0_mapping[] = - { - {0x1c, GRUB_KEYBOARD_KEY_NUMENTER}, - {0x1d, GRUB_KEYBOARD_KEY_RIGHT_CTRL}, - {0x35, GRUB_KEYBOARD_KEY_NUMSLASH }, - {0x38, GRUB_KEYBOARD_KEY_RIGHT_ALT}, - {0x47, GRUB_KEYBOARD_KEY_HOME}, - {0x48, GRUB_KEYBOARD_KEY_UP}, - {0x49, GRUB_KEYBOARD_KEY_PPAGE}, - {0x4b, GRUB_KEYBOARD_KEY_LEFT}, - {0x4d, GRUB_KEYBOARD_KEY_RIGHT}, - {0x4f, GRUB_KEYBOARD_KEY_END}, - {0x50, GRUB_KEYBOARD_KEY_DOWN}, - {0x51, GRUB_KEYBOARD_KEY_NPAGE}, - {0x52, GRUB_KEYBOARD_KEY_INSERT}, - {0x53, GRUB_KEYBOARD_KEY_DELETE}, - }; - -static const grub_uint8_t set2_mapping[256] = - { - /* 0x00 */ 0, GRUB_KEYBOARD_KEY_F9, - /* 0x02 */ 0, GRUB_KEYBOARD_KEY_F5, - /* 0x04 */ GRUB_KEYBOARD_KEY_F3, GRUB_KEYBOARD_KEY_F1, - /* 0x06 */ GRUB_KEYBOARD_KEY_F2, GRUB_KEYBOARD_KEY_F12, - /* 0x08 */ 0, GRUB_KEYBOARD_KEY_F10, - /* 0x0a */ GRUB_KEYBOARD_KEY_F8, GRUB_KEYBOARD_KEY_F6, - /* 0x0c */ GRUB_KEYBOARD_KEY_F4, GRUB_KEYBOARD_KEY_TAB, - /* 0x0e */ GRUB_KEYBOARD_KEY_RQUOTE, 0, - /* 0x10 */ 0, GRUB_KEYBOARD_KEY_LEFT_ALT, - /* 0x12 */ GRUB_KEYBOARD_KEY_LEFT_SHIFT, 0, - /* 0x14 */ GRUB_KEYBOARD_KEY_LEFT_CTRL, GRUB_KEYBOARD_KEY_Q, - /* 0x16 */ GRUB_KEYBOARD_KEY_1, 0, - /* 0x18 */ 0, 0, - /* 0x1a */ GRUB_KEYBOARD_KEY_Z, GRUB_KEYBOARD_KEY_S, - /* 0x1c */ GRUB_KEYBOARD_KEY_A, GRUB_KEYBOARD_KEY_W, - /* 0x1e */ GRUB_KEYBOARD_KEY_2, 0, - /* 0x20 */ 0, GRUB_KEYBOARD_KEY_C, - /* 0x22 */ GRUB_KEYBOARD_KEY_X, GRUB_KEYBOARD_KEY_D, - /* 0x24 */ GRUB_KEYBOARD_KEY_E, GRUB_KEYBOARD_KEY_4, - /* 0x26 */ GRUB_KEYBOARD_KEY_3, 0, - /* 0x28 */ 0, GRUB_KEYBOARD_KEY_SPACE, - /* 0x2a */ GRUB_KEYBOARD_KEY_V, GRUB_KEYBOARD_KEY_F, - /* 0x2c */ GRUB_KEYBOARD_KEY_T, GRUB_KEYBOARD_KEY_R, - /* 0x2e */ GRUB_KEYBOARD_KEY_5, 0, - /* 0x30 */ 0, GRUB_KEYBOARD_KEY_N, - /* 0x32 */ GRUB_KEYBOARD_KEY_B, GRUB_KEYBOARD_KEY_H, - /* 0x34 */ GRUB_KEYBOARD_KEY_G, GRUB_KEYBOARD_KEY_Y, - /* 0x36 */ GRUB_KEYBOARD_KEY_6, 0, - /* 0x38 */ 0, 0, - /* 0x3a */ GRUB_KEYBOARD_KEY_M, GRUB_KEYBOARD_KEY_J, - /* 0x3c */ GRUB_KEYBOARD_KEY_U, GRUB_KEYBOARD_KEY_7, - /* 0x3e */ GRUB_KEYBOARD_KEY_8, 0, - /* 0x40 */ 0, GRUB_KEYBOARD_KEY_COMMA, - /* 0x42 */ GRUB_KEYBOARD_KEY_K, GRUB_KEYBOARD_KEY_I, - /* 0x44 */ GRUB_KEYBOARD_KEY_O, GRUB_KEYBOARD_KEY_0, - /* 0x46 */ GRUB_KEYBOARD_KEY_9, 0, - /* 0x48 */ 0, GRUB_KEYBOARD_KEY_DOT, - /* 0x4a */ GRUB_KEYBOARD_KEY_SLASH, GRUB_KEYBOARD_KEY_L, - /* 0x4c */ GRUB_KEYBOARD_KEY_SEMICOLON, GRUB_KEYBOARD_KEY_P, - /* 0x4e */ GRUB_KEYBOARD_KEY_DASH, 0, - /* 0x50 */ 0, GRUB_KEYBOARD_KEY_JP_RO, - /* 0x52 */ GRUB_KEYBOARD_KEY_DQUOTE, 0, - /* 0x54 */ GRUB_KEYBOARD_KEY_LBRACKET, GRUB_KEYBOARD_KEY_EQUAL, - /* 0x56 */ 0, 0, - /* 0x58 */ GRUB_KEYBOARD_KEY_CAPS_LOCK, GRUB_KEYBOARD_KEY_RIGHT_SHIFT, - /* 0x5a */ GRUB_KEYBOARD_KEY_ENTER, GRUB_KEYBOARD_KEY_RBRACKET, - /* 0x5c */ 0, GRUB_KEYBOARD_KEY_BACKSLASH, - /* 0x5e */ 0, 0, - /* 0x60 */ 0, GRUB_KEYBOARD_KEY_102ND, - /* 0x62 */ 0, 0, - /* 0x64 */ 0, 0, - /* 0x66 */ GRUB_KEYBOARD_KEY_BACKSPACE, 0, - /* 0x68 */ 0, GRUB_KEYBOARD_KEY_NUM1, - /* 0x6a */ GRUB_KEYBOARD_KEY_JP_YEN, GRUB_KEYBOARD_KEY_NUM4, - /* 0x6c */ GRUB_KEYBOARD_KEY_NUM7, GRUB_KEYBOARD_KEY_KPCOMMA, - /* 0x6e */ 0, 0, - /* 0x70 */ GRUB_KEYBOARD_KEY_NUM0, GRUB_KEYBOARD_KEY_NUMDOT, - /* 0x72 */ GRUB_KEYBOARD_KEY_NUM2, GRUB_KEYBOARD_KEY_NUM5, - /* 0x74 */ GRUB_KEYBOARD_KEY_NUM6, GRUB_KEYBOARD_KEY_NUM8, - /* 0x76 */ GRUB_KEYBOARD_KEY_ESCAPE, GRUB_KEYBOARD_KEY_NUM_LOCK, - /* 0x78 */ GRUB_KEYBOARD_KEY_F11, GRUB_KEYBOARD_KEY_NUMPLUS, - /* 0x7a */ GRUB_KEYBOARD_KEY_NUM3, GRUB_KEYBOARD_KEY_NUMMINUS, - /* 0x7c */ GRUB_KEYBOARD_KEY_NUMMUL, GRUB_KEYBOARD_KEY_NUM9, - /* 0x7e */ GRUB_KEYBOARD_KEY_SCROLL_LOCK, 0, - /* 0x80 */ 0, 0, - /* 0x82 */ 0, GRUB_KEYBOARD_KEY_F7, - }; - -static const struct -{ - grub_uint8_t from, to; -} set2_e0_mapping[] = - { - {0x11, GRUB_KEYBOARD_KEY_RIGHT_ALT}, - {0x14, GRUB_KEYBOARD_KEY_RIGHT_CTRL}, - {0x4a, GRUB_KEYBOARD_KEY_NUMSLASH}, - {0x5a, GRUB_KEYBOARD_KEY_NUMENTER}, - {0x69, GRUB_KEYBOARD_KEY_END}, - {0x6b, GRUB_KEYBOARD_KEY_LEFT}, - {0x6c, GRUB_KEYBOARD_KEY_HOME}, - {0x70, GRUB_KEYBOARD_KEY_INSERT}, - {0x71, GRUB_KEYBOARD_KEY_DELETE}, - {0x72, GRUB_KEYBOARD_KEY_DOWN}, - {0x74, GRUB_KEYBOARD_KEY_RIGHT}, - {0x75, GRUB_KEYBOARD_KEY_UP}, - {0x7a, GRUB_KEYBOARD_KEY_NPAGE}, - {0x7d, GRUB_KEYBOARD_KEY_PPAGE}, - }; - -static int -fetch_key (struct grub_ps2_state *ps2_state, grub_uint8_t at_key, int *is_break) -{ - int was_ext = 0; - int ret = 0; - - /* May happen if no keyboard is connected. Just ignore this. */ - if (at_key == 0xff) - return -1; - if (at_key == 0xe0) - { - ps2_state->e0_received = 1; - return -1; - } - - if ((ps2_state->current_set == 2 || ps2_state->current_set == 3) && at_key == 0xf0) - { - ps2_state->f0_received = 1; - return -1; - } - - /* Setting LEDs may generate ACKs. */ - if (at_key == GRUB_AT_ACK) - return -1; - - was_ext = ps2_state->e0_received; - ps2_state->e0_received = 0; - - switch (ps2_state->current_set) - { - case 1: - *is_break = !!(at_key & 0x80); - if (!was_ext) - ret = set1_mapping[at_key & 0x7f]; - else - { - unsigned i; - for (i = 0; i < ARRAY_SIZE (set1_e0_mapping); i++) - if (set1_e0_mapping[i].from == (at_key & 0x7f)) - { - ret = set1_e0_mapping[i].to; - break; - } - } - break; - case 2: - *is_break = ps2_state->f0_received; - ps2_state->f0_received = 0; - if (!was_ext) - ret = set2_mapping[at_key]; - else - { - unsigned i; - for (i = 0; i < ARRAY_SIZE (set2_e0_mapping); i++) - if (set2_e0_mapping[i].from == at_key) - { - ret = set2_e0_mapping[i].to; - break; - } - } - break; - default: - return -1; - } - if (!ret) - { - if (was_ext) - grub_dprintf ("atkeyb", "Unknown key 0xe0+0x%02x from set %d\n", - at_key, ps2_state->current_set); - else - grub_dprintf ("atkeyb", "Unknown key 0x%02x from set %d\n", - at_key, ps2_state->current_set); - return -1; - } - return ret; -} - -/* FIXME: This should become an interrupt service routine. For now - it's just used to catch events from control keys. */ -static int -grub_keyboard_isr (struct grub_ps2_state *ps2_state, - grub_keyboard_key_t key, int is_break) -{ - if (!is_break) - switch (key) - { - case GRUB_KEYBOARD_KEY_LEFT_SHIFT: - ps2_state->at_keyboard_status |= GRUB_TERM_STATUS_LSHIFT; - return 1; - case GRUB_KEYBOARD_KEY_RIGHT_SHIFT: - ps2_state->at_keyboard_status |= GRUB_TERM_STATUS_RSHIFT; - return 1; - case GRUB_KEYBOARD_KEY_LEFT_CTRL: - ps2_state->at_keyboard_status |= GRUB_TERM_STATUS_LCTRL; - return 1; - case GRUB_KEYBOARD_KEY_RIGHT_CTRL: - ps2_state->at_keyboard_status |= GRUB_TERM_STATUS_RCTRL; - return 1; - case GRUB_KEYBOARD_KEY_RIGHT_ALT: - ps2_state->at_keyboard_status |= GRUB_TERM_STATUS_RALT; - return 1; - case GRUB_KEYBOARD_KEY_LEFT_ALT: - ps2_state->at_keyboard_status |= GRUB_TERM_STATUS_LALT; - return 1; - default: - return 0; - } - else - switch (key) - { - case GRUB_KEYBOARD_KEY_LEFT_SHIFT: - ps2_state->at_keyboard_status &= ~GRUB_TERM_STATUS_LSHIFT; - return 1; - case GRUB_KEYBOARD_KEY_RIGHT_SHIFT: - ps2_state->at_keyboard_status &= ~GRUB_TERM_STATUS_RSHIFT; - return 1; - case GRUB_KEYBOARD_KEY_LEFT_CTRL: - ps2_state->at_keyboard_status &= ~GRUB_TERM_STATUS_LCTRL; - return 1; - case GRUB_KEYBOARD_KEY_RIGHT_CTRL: - ps2_state->at_keyboard_status &= ~GRUB_TERM_STATUS_RCTRL; - return 1; - case GRUB_KEYBOARD_KEY_RIGHT_ALT: - ps2_state->at_keyboard_status &= ~GRUB_TERM_STATUS_RALT; - return 1; - case GRUB_KEYBOARD_KEY_LEFT_ALT: - ps2_state->at_keyboard_status &= ~GRUB_TERM_STATUS_LALT; - return 1; - default: - return 0; - } -} - -/* If there is a key pending, return it; otherwise return GRUB_TERM_NO_KEY. */ -int -grub_ps2_process_incoming_byte (struct grub_ps2_state *ps2_state, - grub_uint8_t at_key) -{ - int code; - int is_break = 0; - - code = fetch_key (ps2_state, at_key, &is_break); - if (code == -1) - return GRUB_TERM_NO_KEY; - - if (grub_keyboard_isr (ps2_state, code, is_break)) - return GRUB_TERM_NO_KEY; - if (is_break) - return GRUB_TERM_NO_KEY; -#ifdef DEBUG_AT_KEYBOARD - grub_dprintf ("atkeyb", "Detected key 0x%x\n", code); -#endif - switch (code) - { - case GRUB_KEYBOARD_KEY_CAPS_LOCK: - ps2_state->at_keyboard_status ^= GRUB_TERM_STATUS_CAPS; - ps2_state->led_status ^= KEYBOARD_LED_CAPS; - -#ifdef DEBUG_AT_KEYBOARD - grub_dprintf ("atkeyb", "caps_lock = %d\n", !!(ps2_state->at_keyboard_status & GRUB_KEYBOARD_STATUS_CAPS_LOCK)); -#endif - return GRUB_TERM_NO_KEY; - case GRUB_KEYBOARD_KEY_NUM_LOCK: - ps2_state->at_keyboard_status ^= GRUB_TERM_STATUS_NUM; - ps2_state->led_status ^= KEYBOARD_LED_NUM; - -#ifdef DEBUG_AT_KEYBOARD - grub_dprintf ("atkeyb", "num_lock = %d\n", !!(ps2_state->at_keyboard_status & GRUB_KEYBOARD_STATUS_NUM_LOCK)); -#endif - return GRUB_TERM_NO_KEY; - case GRUB_KEYBOARD_KEY_SCROLL_LOCK: - ps2_state->at_keyboard_status ^= GRUB_TERM_STATUS_SCROLL; - ps2_state->led_status ^= KEYBOARD_LED_SCROLL; - return GRUB_TERM_NO_KEY; - default: - return grub_term_map_key (code, ps2_state->at_keyboard_status); - } -} diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c deleted file mode 100644 index 8260dcb7a..000000000 --- a/grub-core/term/serial.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 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 . - */ - -#include -#include -#include -#include -#include -#include -#if !defined (GRUB_MACHINE_EMU) && (defined(__mips__) || defined (__i386__) || defined (__x86_64__)) -#include -#endif -#include -#include -#include -#ifdef GRUB_MACHINE_MIPS_LOONGSON -#include -#endif -#ifdef GRUB_MACHINE_IEEE1275 -#include -#endif - -GRUB_MOD_LICENSE ("GPLv3+"); - -enum - { - OPTION_UNIT, - OPTION_PORT, - OPTION_SPEED, - OPTION_WORD, - OPTION_PARITY, - OPTION_STOP, - OPTION_BASE_CLOCK, - OPTION_RTSCTS - }; - -/* 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}, - {"base-clock", 'b', 0, N_("Set the base frequency."), 0, ARG_TYPE_STRING}, - {"rtscts", 'f', 0, N_("Enable/disable RTS/CTS."), "on|off", ARG_TYPE_STRING}, - {0, 0, 0, 0, 0, 0} -}; - -struct grub_serial_port *grub_serial_ports; - -struct grub_serial_output_state -{ - struct grub_terminfo_output_state tinfo; - struct grub_serial_port *port; -}; - -struct grub_serial_input_state -{ - struct grub_terminfo_input_state tinfo; - struct grub_serial_port *port; -}; - -static void -serial_put (grub_term_output_t term, const int c) -{ - struct grub_serial_output_state *data = term->data; - data->port->driver->put (data->port, c); -} - -static int -serial_fetch (grub_term_input_t term) -{ - struct grub_serial_input_state *data = term->data; - return data->port->driver->fetch (data->port); -} - -static const struct grub_serial_input_state grub_serial_terminfo_input_template = - { - .tinfo = - { - .readkey = serial_fetch - } - }; - -static const struct grub_serial_output_state grub_serial_terminfo_output_template = - { - .tinfo = - { - .put = serial_put, - .size = { 80, 24 } - } - }; - -static struct grub_serial_input_state grub_serial_terminfo_input; - -static struct grub_serial_output_state grub_serial_terminfo_output; - -static int registered = 0; - -static struct grub_term_input grub_serial_term_input = -{ - .name = "serial", - .init = grub_terminfo_input_init, - .getkey = grub_terminfo_getkey, - .data = &grub_serial_terminfo_input -}; - -static struct grub_term_output grub_serial_term_output = -{ - .name = "serial", - .init = grub_terminfo_output_init, - .putchar = grub_terminfo_putchar, - .getwh = grub_terminfo_getwh, - .getxy = grub_terminfo_getxy, - .gotoxy = grub_terminfo_gotoxy, - .cls = grub_terminfo_cls, - .setcolorstate = grub_terminfo_setcolorstate, - .setcursor = grub_terminfo_setcursor, - .flags = GRUB_TERM_CODE_TYPE_ASCII, - .data = &grub_serial_terminfo_output, - .progress_update_divisor = GRUB_PROGRESS_SLOW -}; - - - -struct grub_serial_port * -grub_serial_find (const char *name) -{ - struct grub_serial_port *port; - - /* - * First look for an exact match by name, this will take care of - * things like "com0" which have already been created and that - * this function cannot re-create. - */ - FOR_SERIAL_PORTS (port) - if (grub_strcmp (port->name, name) == 0) - return port; - -#if (defined(__mips__) || defined (__i386__) || defined (__x86_64__)) && !defined(GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) - if (grub_strncmp (name, "port", sizeof ("port") - 1) == 0 - && grub_isxdigit (name [sizeof ("port") - 1])) - { - port = grub_serial_ns8250_add_port (grub_strtoul (&name[sizeof ("port") - 1], - 0, 16), NULL); - if (port != NULL) - return port; - } - if (grub_strncmp (name, "mmio,", sizeof ("mmio,") - 1) == 0 - && grub_isxdigit (name [sizeof ("mmio,") - 1])) - { - const char *p1, *p = &name[sizeof ("mmio,") - 1]; - grub_addr_t addr = grub_strtoul (p, &p1, 16); - unsigned int acc_size = 1; - - /* - * If we reach here, we know there's a digit after "mmio,", so - * all we need to check is the validity of the character following - * the number, which should be a termination, or a dot followed by - * an access size. - */ - if (p1[0] != '\0' && p1[0] != '.') - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("incorrect MMIO address syntax")); - return NULL; - } - if (p1[0] == '.') - switch(p1[1]) - { - case 'w': - acc_size = 2; - break; - case 'l': - acc_size = 3; - break; - case 'q': - acc_size = 4; - break; - case 'b': - acc_size = 1; - break; - default: - /* - * Should we abort for an unknown size? Let's just default - * to 1 byte, it would increase the chance that the user who - * did a typo can actually see the console. - */ - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("incorrect MMIO access size")); - } - - port = grub_serial_ns8250_add_mmio (addr, acc_size, NULL); - if (port != NULL) - return port; - } - -#if (defined(__i386__) || defined(__x86_64__)) && !defined(GRUB_MACHINE_IEEE1275) && !defined(GRUB_MACHINE_QEMU) - if (grub_strcmp (name, "auto") == 0) - { - /* Look for an SPCR if any. If not, default to com0. */ - port = grub_ns8250_spcr_init (); - if (port != NULL) - return port; - FOR_SERIAL_PORTS (port) - if (grub_strcmp (port->name, "com0") == 0) - return port; - } -#endif -#endif - -#ifdef GRUB_MACHINE_IEEE1275 - if (grub_strncmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) == 0) - { - port = grub_ofserial_add_port (&name[sizeof ("ieee1275/") - 1]); - if (port != NULL) - return port; - } -#endif - - return NULL; -} - -static grub_err_t -grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_arg_list *state = ctxt->state; - char pname[40]; - const char *name = NULL; - struct grub_serial_port *port; - struct grub_serial_config config; - grub_err_t err; - - if (state[OPTION_UNIT].set) - { - grub_snprintf (pname, sizeof (pname), "com%ld", - grub_strtoul (state[0].arg, 0, 0)); - name = pname; - } - - if (state[OPTION_PORT].set) - { - if (grub_strncmp (state[OPTION_PORT].arg, "mmio,", sizeof ("mmio,") - 1) == 0 || - grub_strncmp (state[OPTION_PORT].arg, "pci,", sizeof ("pci,") - 1) == 0) - { - grub_strncpy (pname, state[1].arg, sizeof (pname)); - pname[sizeof (pname) - 1] = '\0'; - } - else - grub_snprintf (pname, sizeof (pname), "port%lx", - grub_strtoul (state[1].arg, 0, 0)); - name = pname; - } - - if (argc >= 1) - name = args[0]; - - if (!name) - name = "auto"; - - port = grub_serial_find (name); - if (!port) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("serial port `%s' isn't found"), - name); - - config = port->config; - - if (state[OPTION_SPEED].set) { - config.speed = grub_strtoul (state[OPTION_SPEED].arg, 0, 0); - if (config.speed == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port parity")); - } - - if (state[OPTION_WORD].set) - config.word_len = grub_strtoul (state[OPTION_WORD].arg, 0, 0); - - if (state[OPTION_PARITY].set) - { - if (! grub_strcmp (state[OPTION_PARITY].arg, "no")) - config.parity = GRUB_SERIAL_PARITY_NONE; - else if (! grub_strcmp (state[OPTION_PARITY].arg, "odd")) - config.parity = GRUB_SERIAL_PARITY_ODD; - else if (! grub_strcmp (state[OPTION_PARITY].arg, "even")) - config.parity = GRUB_SERIAL_PARITY_EVEN; - else - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port parity")); - } - - if (state[OPTION_RTSCTS].set) - { - if (grub_strcmp (state[OPTION_RTSCTS].arg, "on") == 0) - config.rtscts = 1; - else if (grub_strcmp (state[OPTION_RTSCTS].arg, "off") == 0) - config.rtscts = 0; - else - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port flow control")); - } - - if (state[OPTION_STOP].set) - { - if (! grub_strcmp (state[OPTION_STOP].arg, "1")) - config.stop_bits = GRUB_SERIAL_STOP_BITS_1; - else if (! grub_strcmp (state[OPTION_STOP].arg, "2")) - config.stop_bits = GRUB_SERIAL_STOP_BITS_2; - else if (! grub_strcmp (state[OPTION_STOP].arg, "1.5")) - config.stop_bits = GRUB_SERIAL_STOP_BITS_1_5; - else - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("unsupported serial port stop bits number")); - } - - if (state[OPTION_BASE_CLOCK].set) - { - const char *ptr; - config.base_clock = grub_strtoull (state[OPTION_BASE_CLOCK].arg, &ptr, 0); - if (grub_errno) - return grub_errno; - if (ptr && *ptr == 'M') - config.base_clock *= 1000000; - if (ptr && (*ptr == 'k' || *ptr == 'K')) - config.base_clock *= 1000; - } - - if (config.speed == 0) - config.speed = 9600; - - /* Initialize with new settings. */ - err = port->driver->configure (port, &config); - if (err) - return err; -#if !defined (GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) && (defined(__mips__) || defined (__i386__) || defined (__x86_64__)) - - /* Compatibility kludge. */ - if (port->driver == &grub_ns8250_driver) - { - if (!registered) - { - grub_terminfo_output_register (&grub_serial_term_output, "vt100"); - - grub_term_register_input ("serial", &grub_serial_term_input); - grub_term_register_output ("serial", &grub_serial_term_output); - } - grub_serial_terminfo_output.port = port; - grub_serial_terminfo_input.port = port; - registered = 1; - } -#endif - return GRUB_ERR_NONE; -} - -#ifdef GRUB_MACHINE_MIPS_LOONGSON -const char loongson_defserial[][6] = - { - [GRUB_ARCH_MACHINE_YEELOONG] = "com0", - [GRUB_ARCH_MACHINE_FULOONG2F] = "com2", - [GRUB_ARCH_MACHINE_FULOONG2E] = "com1" - }; -#endif - -grub_err_t -grub_serial_register (struct grub_serial_port *port) -{ - struct grub_term_input *in; - struct grub_term_output *out; - struct grub_serial_input_state *indata; - struct grub_serial_output_state *outdata; - - in = grub_malloc (sizeof (*in)); - if (!in) - return grub_errno; - - indata = grub_malloc (sizeof (*indata)); - if (!indata) - { - grub_free (in); - return grub_errno; - } - - grub_memcpy (in, &grub_serial_term_input, sizeof (*in)); - in->data = indata; - in->name = grub_xasprintf ("serial_%s", port->name); - grub_memcpy (indata, &grub_serial_terminfo_input, sizeof (*indata)); - - if (!in->name) - { - grub_free (in); - grub_free (indata); - return grub_errno; - } - - out = grub_zalloc (sizeof (*out)); - if (!out) - { - grub_free (indata); - grub_free ((char *) in->name); - grub_free (in); - return grub_errno; - } - - outdata = grub_malloc (sizeof (*outdata)); - if (!outdata) - { - grub_free (indata); - grub_free ((char *) in->name); - grub_free (out); - grub_free (in); - return grub_errno; - } - - grub_memcpy (out, &grub_serial_term_output, sizeof (*out)); - out->data = outdata; - out->name = in->name; - grub_memcpy (outdata, &grub_serial_terminfo_output, sizeof (*outdata)); - - grub_list_push (GRUB_AS_LIST_P (&grub_serial_ports), GRUB_AS_LIST (port)); - ((struct grub_serial_input_state *) in->data)->port = port; - ((struct grub_serial_output_state *) out->data)->port = port; - port->term_in = in; - port->term_out = out; - grub_terminfo_output_register (out, "vt100"); -#ifdef GRUB_MACHINE_MIPS_LOONGSON - if (grub_strcmp (port->name, loongson_defserial[grub_arch_machine]) == 0) - { - grub_term_register_input_active ("serial_*", in); - grub_term_register_output_active ("serial_*", out); - } - else - { - grub_term_register_input_inactive ("serial_*", in); - grub_term_register_output_inactive ("serial_*", out); - } -#else - grub_term_register_input ("serial_*", in); - grub_term_register_output ("serial_*", out); -#endif - - return GRUB_ERR_NONE; -} - -void -grub_serial_unregister (struct grub_serial_port *port) -{ - if (port->driver->fini) - port->driver->fini (port); - - if (port->term_in) - grub_term_unregister_input (port->term_in); - if (port->term_out) - grub_term_unregister_output (port->term_out); - - grub_list_remove (GRUB_AS_LIST (port)); -} - -void -grub_serial_unregister_driver (struct grub_serial_driver *driver) -{ - struct grub_serial_port *port, *next; - for (port = grub_serial_ports; port; port = next) - { - next = port->next; - if (port->driver == driver) - grub_serial_unregister (port); - } -} - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT(serial) -{ - cmd = grub_register_extcmd ("serial", grub_cmd_serial, 0, - N_("[OPTIONS...]"), - N_("Configure serial port."), options); - grub_memcpy (&grub_serial_terminfo_output, - &grub_serial_terminfo_output_template, - sizeof (grub_serial_terminfo_output)); - - grub_memcpy (&grub_serial_terminfo_input, - &grub_serial_terminfo_input_template, - sizeof (grub_serial_terminfo_input)); - -#if !defined (GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) && (defined(__mips__) || defined (__i386__) || defined (__x86_64__)) - grub_ns8250_init (); -#endif -#ifdef GRUB_MACHINE_IEEE1275 - grub_ofserial_init (); -#endif -#ifdef GRUB_MACHINE_EFI - grub_efiserial_init (); -#endif -#ifdef GRUB_MACHINE_ARC - grub_arcserial_init (); -#endif -#if defined(__i386__) || defined(__x86_64__) - grub_pciserial_init (); -#endif -} - -GRUB_MOD_FINI(serial) -{ - while (grub_serial_ports) - grub_serial_unregister (grub_serial_ports); - if (registered) - { - grub_term_unregister_input (&grub_serial_term_input); - grub_term_unregister_output (&grub_serial_term_output); - } - grub_unregister_extcmd (cmd); -} diff --git a/grub-core/term/spkmodem.c b/grub-core/term/spkmodem.c deleted file mode 100644 index 75c8a0f82..000000000 --- a/grub-core/term/spkmodem.c +++ /dev/null @@ -1,141 +0,0 @@ -/* console.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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -extern struct grub_terminfo_output_state grub_spkmodem_terminfo_output; - -static void -make_tone (grub_uint16_t freq_count, unsigned int duration) -{ - /* Program timer 2. */ - grub_outb (GRUB_PIT_CTRL_SELECT_2 - | GRUB_PIT_CTRL_READLOAD_WORD - | GRUB_PIT_CTRL_SQUAREWAVE_GEN - | GRUB_PIT_CTRL_COUNT_BINARY, GRUB_PIT_CTRL); - grub_outb (freq_count & 0xff, GRUB_PIT_COUNTER_2); /* LSB */ - grub_outb ((freq_count >> 8) & 0xff, GRUB_PIT_COUNTER_2); /* MSB */ - - /* Start speaker. */ - grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT) - | GRUB_PIT_SPK_TMR2 | GRUB_PIT_SPK_DATA, - GRUB_PIT_SPEAKER_PORT); - - for (; duration; duration--) - { - unsigned short counter, previous_counter = 0xffff; - while (1) - { - counter = grub_inb (GRUB_PIT_COUNTER_2); - counter |= ((grub_uint16_t) grub_inb (GRUB_PIT_COUNTER_2)) << 8; - if (counter > previous_counter) - { - previous_counter = counter; - break; - } - previous_counter = counter; - } - } -} - -static int inited; - -static void -put (struct grub_term_output *term __attribute__ ((unused)), const int c) -{ - int i; - - make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 200, 4); - for (i = 7; i >= 0; i--) - { - if ((c >> i) & 1) - make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 2000, 20); - else - make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 4000, 40); - make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 1000, 10); - } - make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 200, 0); -} - -static grub_err_t -grub_spkmodem_init_output (struct grub_term_output *term) -{ - /* Some models shutdown sound when not in use and it takes for it - around 30 ms to come back on which loses 3 bits. So generate a base - 200 Hz continously. */ - - make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 200, 0); - grub_terminfo_output_init (term); - - return 0; -} - -static grub_err_t -grub_spkmodem_fini_output (struct grub_term_output *term __attribute__ ((unused))) -{ - grub_speaker_beep_off (); - inited = 0; - return 0; -} - - - - -struct grub_terminfo_output_state grub_spkmodem_terminfo_output = - { - .put = put, - .size = { 80, 24 } - }; - -static struct grub_term_output grub_spkmodem_term_output = - { - .name = "spkmodem", - .init = grub_spkmodem_init_output, - .fini = grub_spkmodem_fini_output, - .putchar = grub_terminfo_putchar, - .getxy = grub_terminfo_getxy, - .getwh = grub_terminfo_getwh, - .gotoxy = grub_terminfo_gotoxy, - .cls = grub_terminfo_cls, - .setcolorstate = grub_terminfo_setcolorstate, - .setcursor = grub_terminfo_setcursor, - .flags = GRUB_TERM_CODE_TYPE_ASCII, - .data = &grub_spkmodem_terminfo_output, - .progress_update_divisor = GRUB_PROGRESS_NO_UPDATE - }; - -GRUB_MOD_INIT (spkmodem) -{ - grub_term_register_output ("spkmodem", &grub_spkmodem_term_output); -} - - -GRUB_MOD_FINI (spkmodem) -{ - grub_term_unregister_output (&grub_spkmodem_term_output); -} diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c deleted file mode 100644 index 4e534c683..000000000 --- a/grub-core/term/terminfo.c +++ /dev/null @@ -1,796 +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 . - */ - -/* - * This file contains various functions dealing with different - * terminal capabilities. For example, vt52 and vt100. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275) -#include -#endif - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define ANSI_CSI 0x9b -#define ANSI_CSI_STR "\x9b" - -static struct grub_term_output *terminfo_outputs; - -/* Get current terminfo name. */ -char * -grub_terminfo_get_current (struct grub_term_output *term) -{ - struct grub_terminfo_output_state *data - = (struct grub_terminfo_output_state *) term->data; - return data->name; -} - -/* Free *PTR and set *PTR to NULL, to prevent double-free. */ -static void -grub_terminfo_free (char **ptr) -{ - grub_free (*ptr); - *ptr = 0; -} - -static void -grub_terminfo_all_free (struct grub_term_output *term) -{ - struct grub_terminfo_output_state *data - = (struct grub_terminfo_output_state *) term->data; - - /* Free previously allocated memory. */ - grub_terminfo_free (&data->name); - grub_terminfo_free (&data->gotoxy); - grub_terminfo_free (&data->cls); - grub_terminfo_free (&data->reverse_video_on); - grub_terminfo_free (&data->reverse_video_off); - grub_terminfo_free (&data->cursor_on); - grub_terminfo_free (&data->cursor_off); -} - -/* Set current terminfo type. */ -grub_err_t -grub_terminfo_set_current (struct grub_term_output *term, - const char *str) -{ - struct grub_terminfo_output_state *data - = (struct grub_terminfo_output_state *) term->data; - /* 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. - */ - - grub_terminfo_all_free (term); - - if (grub_strcmp ("vt100", str) == 0) - { - data->name = grub_strdup ("vt100"); - data->gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH"); - data->cls = grub_strdup ("\e[H\e[J"); - data->reverse_video_on = grub_strdup ("\e[7m"); - data->reverse_video_off = grub_strdup ("\e[m"); - data->cursor_on = grub_strdup ("\e[?25h"); - data->cursor_off = grub_strdup ("\e[?25l"); - data->setcolor = NULL; - return grub_errno; - } - - if (grub_strcmp ("vt100-color", str) == 0) - { - data->name = grub_strdup ("vt100-color"); - data->gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH"); - data->cls = grub_strdup ("\e[H\e[J"); - data->reverse_video_on = grub_strdup ("\e[7m"); - data->reverse_video_off = grub_strdup ("\e[m"); - data->cursor_on = grub_strdup ("\e[?25h"); - data->cursor_off = grub_strdup ("\e[?25l"); - data->setcolor = grub_strdup ("\e[3%p1%dm\e[4%p2%dm"); - return grub_errno; - } - - if (grub_strcmp ("arc", str) == 0) - { - data->name = grub_strdup ("arc"); - data->gotoxy = grub_strdup (ANSI_CSI_STR "%i%p1%d;%p2%dH"); - data->cls = grub_strdup (ANSI_CSI_STR "2J"); - data->reverse_video_on = grub_strdup (ANSI_CSI_STR "7m"); - data->reverse_video_off = grub_strdup (ANSI_CSI_STR "0m"); - data->cursor_on = 0; - data->cursor_off = 0; - data->setcolor = grub_strdup (ANSI_CSI_STR "3%p1%dm" - ANSI_CSI_STR "4%p2%dm"); - return grub_errno; - } - - if (grub_strcmp ("ieee1275", str) == 0 - || grub_strcmp ("ieee1275-nocursor", str) == 0) - { - data->name = grub_strdup ("ieee1275"); - data->gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH"); - /* 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. */ - data->cls = grub_strdup (" \e[2J"); - data->reverse_video_on = grub_strdup ("\e[7m"); - data->reverse_video_off = grub_strdup ("\e[m"); - if (grub_strcmp ("ieee1275", str) == 0) - { - data->cursor_on = grub_strdup ("\e[?25h"); - data->cursor_off = grub_strdup ("\e[?25l"); - } - else - { - data->cursor_on = 0; - data->cursor_off = 0; - } - data->setcolor = grub_strdup ("\e[3%p1%dm\e[4%p2%dm"); - return grub_errno; - } - - if (grub_strcmp ("dumb", str) == 0) - { - data->name = grub_strdup ("dumb"); - data->gotoxy = NULL; - data->cls = NULL; - data->reverse_video_on = NULL; - data->reverse_video_off = NULL; - data->cursor_on = NULL; - data->cursor_off = NULL; - data->setcolor = NULL; - return grub_errno; - } - - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unknown terminfo type `%s'"), - str); -} - -grub_err_t -grub_terminfo_output_register (struct grub_term_output *term, - const char *type) -{ - grub_err_t err; - struct grub_terminfo_output_state *data; - - err = grub_terminfo_set_current (term, type); - - if (err) - return err; - - data = (struct grub_terminfo_output_state *) term->data; - data->next = terminfo_outputs; - terminfo_outputs = term; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_terminfo_output_unregister (struct grub_term_output *term) -{ - struct grub_term_output **ptr; - - for (ptr = &terminfo_outputs; *ptr; - ptr = &((struct grub_terminfo_output_state *) (*ptr)->data)->next) - if (*ptr == term) - { - grub_terminfo_all_free (term); - *ptr = ((struct grub_terminfo_output_state *) (*ptr)->data)->next; - return GRUB_ERR_NONE; - } - return grub_error (GRUB_ERR_BUG, "terminal not found"); -} - -/* Wrapper for grub_putchar to write strings. */ -static void -putstr (struct grub_term_output *term, const char *str) -{ - struct grub_terminfo_output_state *data - = (struct grub_terminfo_output_state *) term->data; - while (*str) - data->put (term, *str++); -} - -struct grub_term_coordinate -grub_terminfo_getxy (struct grub_term_output *term) -{ - struct grub_terminfo_output_state *data - = (struct grub_terminfo_output_state *) term->data; - - return data->pos; -} - -void -grub_terminfo_gotoxy (struct grub_term_output *term, - struct grub_term_coordinate pos) -{ - struct grub_terminfo_output_state *data - = (struct grub_terminfo_output_state *) term->data; - - if (pos.x > grub_term_width (term) || pos.y > grub_term_height (term)) - { - grub_error (GRUB_ERR_BUG, "invalid point (%u,%u)", pos.x, pos.y); - return; - } - - if (data->gotoxy) - putstr (term, grub_terminfo_tparm (data->gotoxy, pos.y, pos.x)); - else - { - if ((pos.y == data->pos.y) && (pos.x == data->pos.x - 1)) - data->put (term, '\b'); - } - - data->pos = pos; -} - -/* Clear the screen. */ -void -grub_terminfo_cls (struct grub_term_output *term) -{ - struct grub_terminfo_output_state *data - = (struct grub_terminfo_output_state *) term->data; - - putstr (term, grub_terminfo_tparm (data->cls)); - grub_terminfo_gotoxy (term, (struct grub_term_coordinate) { 0, 0 }); -} - -void -grub_terminfo_setcolorstate (struct grub_term_output *term, - const grub_term_color_state state) -{ - struct grub_terminfo_output_state *data - = (struct grub_terminfo_output_state *) term->data; - - if (data->setcolor) - { - int fg; - int bg; - /* Map from VGA to terminal colors. */ - const int colormap[8] - = { 0, /* Black. */ - 4, /* Blue. */ - 2, /* Green. */ - 6, /* Cyan. */ - 1, /* Red. */ - 5, /* Magenta. */ - 3, /* Yellow. */ - 7, /* White. */ - }; - - switch (state) - { - case GRUB_TERM_COLOR_STANDARD: - case GRUB_TERM_COLOR_NORMAL: - fg = grub_term_normal_color & 0x0f; - bg = grub_term_normal_color >> 4; - break; - case GRUB_TERM_COLOR_HIGHLIGHT: - fg = grub_term_highlight_color & 0x0f; - bg = grub_term_highlight_color >> 4; - break; - default: - return; - } - - putstr (term, grub_terminfo_tparm (data->setcolor, colormap[fg & 7], - colormap[bg & 7])); - return; - } - - switch (state) - { - case GRUB_TERM_COLOR_STANDARD: - case GRUB_TERM_COLOR_NORMAL: - putstr (term, grub_terminfo_tparm (data->reverse_video_off)); - break; - case GRUB_TERM_COLOR_HIGHLIGHT: - putstr (term, grub_terminfo_tparm (data->reverse_video_on)); - break; - default: - break; - } -} - -void -grub_terminfo_setcursor (struct grub_term_output *term, const int on) -{ - struct grub_terminfo_output_state *data - = (struct grub_terminfo_output_state *) term->data; - - if (on) - putstr (term, grub_terminfo_tparm (data->cursor_on)); - else - putstr (term, grub_terminfo_tparm (data->cursor_off)); -} - -/* The terminfo version of putchar. */ -void -grub_terminfo_putchar (struct grub_term_output *term, - const struct grub_unicode_glyph *c) -{ - struct grub_terminfo_output_state *data - = (struct grub_terminfo_output_state *) term->data; - - /* Keep track of the cursor. */ - switch (c->base) - { - case '\a': - break; - - case '\b': - case 127: - if (data->pos.x > 0) - data->pos.x--; - break; - - case '\n': - if (data->pos.y < grub_term_height (term) - 1) - data->pos.y++; - break; - - case '\r': - data->pos.x = 0; - break; - - default: - if ((int) data->pos.x + c->estimated_width >= (int) grub_term_width (term) + 1) - { - data->pos.x = 0; - if (data->pos.y < grub_term_height (term) - 1) - data->pos.y++; - data->put (term, '\r'); - data->put (term, '\n'); - } - data->pos.x += c->estimated_width; - break; - } - - data->put (term, c->base); -} - -struct grub_term_coordinate -grub_terminfo_getwh (struct grub_term_output *term) -{ - struct grub_terminfo_output_state *data - = (struct grub_terminfo_output_state *) term->data; - - return data->size; -} - -static void -grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, int max_len, - int (*readkey) (struct grub_term_input *term)) -{ - int c; - -#define CONTINUE_READ \ - { \ - grub_uint64_t start; \ - /* On 9600 we have to wait up to 12 milliseconds. */ \ - start = grub_get_time_ms (); \ - do \ - c = readkey (term); \ - while (c == -1 && grub_get_time_ms () - start < 100); \ - if (c == -1) \ - return; \ - \ - if (*len >= max_len) \ - return; \ - \ - keys[*len] = c; \ - (*len)++; \ - } - - c = readkey (term); - if (c < 0) - { - *len = 0; - return; - } - *len = 1; - keys[0] = c; - if (c != ANSI_CSI && c != GRUB_TERM_ESC) - { - /* Backspace: Ctrl-h. */ - if (c == 0x7f) - c = GRUB_TERM_BACKSPACE; - if (c < 0x20 && c != GRUB_TERM_TAB && c!= GRUB_TERM_BACKSPACE && c != '\n' && c != '\r') - c = GRUB_TERM_CTRL | (c - 1 + 'a'); - *len = 1; - keys[0] = c; - return; - } - - { - static struct - { - char key; - unsigned ascii; - } - three_code_table[] = - { - {'4', GRUB_TERM_KEY_DC}, - {'A', GRUB_TERM_KEY_UP}, - {'B', GRUB_TERM_KEY_DOWN}, - {'C', GRUB_TERM_KEY_RIGHT}, - {'D', GRUB_TERM_KEY_LEFT}, - {'F', GRUB_TERM_KEY_END}, - {'H', GRUB_TERM_KEY_HOME}, - {'K', GRUB_TERM_KEY_END}, - {'P', GRUB_TERM_KEY_DC}, - {'?', GRUB_TERM_KEY_PPAGE}, - {'/', GRUB_TERM_KEY_NPAGE}, - {'@', GRUB_TERM_KEY_INSERT}, - }; - - static unsigned four_code_table[] = - { - [1] = GRUB_TERM_KEY_HOME, - [3] = GRUB_TERM_KEY_DC, - [5] = GRUB_TERM_KEY_PPAGE, - [6] = GRUB_TERM_KEY_NPAGE, - [7] = GRUB_TERM_KEY_HOME, - [8] = GRUB_TERM_KEY_END, - [17] = GRUB_TERM_KEY_F6, - [18] = GRUB_TERM_KEY_F7, - [19] = GRUB_TERM_KEY_F8, - [20] = GRUB_TERM_KEY_F9, - [21] = GRUB_TERM_KEY_F10, - [23] = GRUB_TERM_KEY_F11, - [24] = GRUB_TERM_KEY_F12, - }; - char fx_key[] = - { 'P', 'Q', 'w', 'x', 't', 'u', - 'q', 'r', 'p', 'M', 'A', 'B', 'H', 'F' }; - unsigned fx_code[] = - { GRUB_TERM_KEY_F1, GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, - GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, GRUB_TERM_KEY_F6, - GRUB_TERM_KEY_F7, GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, - GRUB_TERM_KEY_F10, GRUB_TERM_KEY_F11, GRUB_TERM_KEY_F12, - GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_END }; - unsigned i; - - if (c == GRUB_TERM_ESC) - { - CONTINUE_READ; - - if (c == 'O') - { - CONTINUE_READ; - - for (i = 0; i < ARRAY_SIZE (fx_key); i++) - if (fx_key[i] == c) - { - keys[0] = fx_code[i]; - *len = 1; - return; - } - } - - if (c != '[') - return; - } - - CONTINUE_READ; - - for (i = 0; i < ARRAY_SIZE (three_code_table); i++) - if (three_code_table[i].key == c) - { - keys[0] = three_code_table[i].ascii; - *len = 1; - return; - } - - switch (c) - { - case '[': - CONTINUE_READ; - if (c >= 'A' && c <= 'E') - { - keys[0] = GRUB_TERM_KEY_F1 + c - 'A'; - *len = 1; - return; - } - return; - case 'O': - CONTINUE_READ; - for (i = 0; i < ARRAY_SIZE (fx_key); i++) - if (fx_key[i] == c) - { - keys[0] = fx_code[i]; - *len = 1; - return; - } - return; - - case '0': - { - int num = 0; - CONTINUE_READ; - if (c != '0' && c != '1') - return; - num = (c - '0') * 10; - CONTINUE_READ; - if (c < '0' || c > '9') - return; - num += (c - '0'); - if (num == 0 || num > 12) - return; - CONTINUE_READ; - if (c != 'q') - return; - keys[0] = fx_code[num - 1]; - *len = 1; - return; - } - - case '1' ... '9': - { - unsigned val = c - '0'; - CONTINUE_READ; - if (c >= '0' && c <= '9') - { - val = val * 10 + (c - '0'); - CONTINUE_READ; - } - if (c != '~') - return; - if (val >= ARRAY_SIZE (four_code_table) - || four_code_table[val] == 0) - return; - keys[0] = four_code_table[val]; - *len = 1; - return; - } - default: - return; - } - } -#undef CONTINUE_READ -} - -/* The terminfo version of getkey. */ -int -grub_terminfo_getkey (struct grub_term_input *termi) -{ - struct grub_terminfo_input_state *data - = (struct grub_terminfo_input_state *) (termi->data); - if (data->npending) - { - int ret; - data->npending--; - ret = data->input_buf[0]; - grub_memmove (data->input_buf, data->input_buf + 1, data->npending - * sizeof (data->input_buf[0])); - return ret; - } - - grub_terminfo_readkey (termi, data->input_buf, &data->npending, - GRUB_TERMINFO_READKEY_MAX_LEN, data->readkey); - -#if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275) - if (data->npending == 1 && data->input_buf[0] == GRUB_TERM_ESC - && grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_REPEAT) - && grub_get_time_ms () - data->last_key_time < 1000 - && (data->last_key & GRUB_TERM_EXTENDED)) - { - data->npending = 0; - data->last_key_time = grub_get_time_ms (); - return data->last_key; - } -#endif - - if (data->npending) - { - int ret; - data->npending--; - ret = data->input_buf[0]; -#if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275) - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_REPEAT)) - { - data->last_key = ret; - data->last_key_time = grub_get_time_ms (); - } -#endif - grub_memmove (data->input_buf, data->input_buf + 1, data->npending - * sizeof (data->input_buf[0])); - return ret; - } - - return GRUB_TERM_NO_KEY; -} - -grub_err_t -grub_terminfo_input_init (struct grub_term_input *termi) -{ - struct grub_terminfo_input_state *data - = (struct grub_terminfo_input_state *) (termi->data); - data->npending = 0; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_terminfo_output_init (struct grub_term_output *term) -{ - grub_terminfo_cls (term); - return GRUB_ERR_NONE; -} - -/* GRUB Command. */ - -static grub_err_t -print_terminfo (void) -{ - const char *encoding_names[(GRUB_TERM_CODE_TYPE_MASK - >> GRUB_TERM_CODE_TYPE_SHIFT) + 1] - = { - /* VGA and glyph descriptor types are just for completeness, - they are not used on terminfo terminals. - */ - [GRUB_TERM_CODE_TYPE_ASCII >> GRUB_TERM_CODE_TYPE_SHIFT] = _("ASCII"), - [GRUB_TERM_CODE_TYPE_CP437 >> GRUB_TERM_CODE_TYPE_SHIFT] = "CP-437", - [GRUB_TERM_CODE_TYPE_UTF8_LOGICAL >> GRUB_TERM_CODE_TYPE_SHIFT] - = _("UTF-8"), - [GRUB_TERM_CODE_TYPE_UTF8_VISUAL >> GRUB_TERM_CODE_TYPE_SHIFT] - /* TRANSLATORS: visually ordered UTF-8 is a non-compliant encoding - based on UTF-8 with right-to-left languages written in reverse. - Used on some terminals. Normal UTF-8 is refered as - "logically-ordered UTF-8" by opposition. */ - = _("visually-ordered UTF-8"), - [GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS >> GRUB_TERM_CODE_TYPE_SHIFT] - = "Glyph descriptors", - _("Unknown encoding"), _("Unknown encoding"), _("Unknown encoding") - }; - struct grub_term_output *cur; - - grub_puts_ (N_("Current terminfo types:")); - for (cur = terminfo_outputs; cur; - cur = ((struct grub_terminfo_output_state *) cur->data)->next) - grub_printf ("%s: %s\t%s\t%dx%d\n", cur->name, - grub_terminfo_get_current(cur), - encoding_names[(cur->flags & GRUB_TERM_CODE_TYPE_MASK) - >> GRUB_TERM_CODE_TYPE_SHIFT], - ((struct grub_terminfo_output_state *) cur->data)->pos.x, - ((struct grub_terminfo_output_state *) cur->data)->pos.y); - - return GRUB_ERR_NONE; -} - -static const struct grub_arg_option options[] = -{ - {"ascii", 'a', 0, N_("Terminal is ASCII-only [default]."), 0, ARG_TYPE_NONE}, - {"utf8", 'u', 0, N_("Terminal is logical-ordered UTF-8."), 0, ARG_TYPE_NONE}, - {"visual-utf8", 'v', 0, N_("Terminal is visually-ordered UTF-8."), 0, - ARG_TYPE_NONE}, - {"geometry", 'g', 0, N_("Terminal has specified geometry."), - /* TRANSLATORS: "x" has to be entered in, like an identifier, so please don't - use better Unicode codepoints. */ - N_("WIDTHxHEIGHT."), ARG_TYPE_STRING}, - {0, 0, 0, 0, 0, 0} -}; - -enum - { - OPTION_ASCII, - OPTION_UTF8, - OPTION_VISUAL_UTF8, - OPTION_GEOMETRY - }; - -static grub_err_t -grub_cmd_terminfo (grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_term_output *cur; - int encoding = GRUB_TERM_CODE_TYPE_ASCII; - struct grub_arg_list *state = ctxt->state; - int w = 0, h = 0; - - if (argc == 0) - return print_terminfo (); - - if (state[OPTION_ASCII].set) - encoding = GRUB_TERM_CODE_TYPE_ASCII; - - if (state[OPTION_UTF8].set) - encoding = GRUB_TERM_CODE_TYPE_UTF8_LOGICAL; - - if (state[OPTION_VISUAL_UTF8].set) - encoding = GRUB_TERM_CODE_TYPE_UTF8_VISUAL; - - if (state[OPTION_GEOMETRY].set) - { - const char *ptr = state[OPTION_GEOMETRY].arg; - w = grub_strtoul (ptr, &ptr, 0); - if (grub_errno) - return grub_errno; - if (*ptr != 'x') - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("incorrect terminal dimensions specification")); - ptr++; - h = grub_strtoul (ptr, &ptr, 0); - if (grub_errno) - return grub_errno; - } - - for (cur = terminfo_outputs; cur; - cur = ((struct grub_terminfo_output_state *) cur->data)->next) - if (grub_strcmp (args[0], cur->name) == 0 - || (grub_strcmp (args[0], "ofconsole") == 0 - && grub_strcmp ("console", cur->name) == 0)) - { - cur->flags = (cur->flags & ~GRUB_TERM_CODE_TYPE_MASK) | encoding; - - if (w && h) - { - struct grub_terminfo_output_state *data - = (struct grub_terminfo_output_state *) cur->data; - data->size.x = w; - data->size.y = h; - } - - if (argc == 1) - return GRUB_ERR_NONE; - - return grub_terminfo_set_current (cur, args[1]); - } - - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("terminal %s isn't found or it's not handled by terminfo"), - args[0]); -} - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT(terminfo) -{ - cmd = grub_register_extcmd ("terminfo", grub_cmd_terminfo, 0, - N_("[[-a|-u|-v] [-g WxH] [TERM] [TYPE]]"), - N_("Set terminfo type of TERM to TYPE.\n"), - options); -} - -GRUB_MOD_FINI(terminfo) -{ - grub_unregister_extcmd (cmd); -} diff --git a/grub-core/term/uboot/console.c b/grub-core/term/uboot/console.c deleted file mode 100644 index ff5a0d48f..000000000 --- a/grub-core/term/uboot/console.c +++ /dev/null @@ -1,132 +0,0 @@ -/* console.c - console interface layer for U-Boot platforms */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -static void -put (struct grub_term_output *term __attribute__ ((unused)), const int c) -{ - grub_uboot_putc (c); -} - -static int -readkey (struct grub_term_input *term __attribute__ ((unused))) -{ - if (grub_uboot_tstc () > 0) - return grub_uboot_getc (); - - return -1; -} - -static void -uboot_console_setcursor (struct grub_term_output *term - __attribute__ ((unused)), int on - __attribute__ ((unused))) -{ - grub_terminfo_setcursor (term, on); -} - -static grub_err_t -uboot_console_init_input (struct grub_term_input *term) -{ - return grub_terminfo_input_init (term); -} - -extern struct grub_terminfo_output_state uboot_console_terminfo_output; - - -static grub_err_t -uboot_console_init_output (struct grub_term_output *term) -{ - grub_terminfo_output_init (term); - - return 0; -} - -struct grub_terminfo_input_state uboot_console_terminfo_input = { - .readkey = readkey -}; - -struct grub_terminfo_output_state uboot_console_terminfo_output = { - .put = put, - /* FIXME: In rare cases when console isn't serial, - determine real width. */ - .size = { 80, 24 } -}; - -static struct grub_term_input uboot_console_term_input = { - .name = "console", - .init = uboot_console_init_input, - .getkey = grub_terminfo_getkey, - .data = &uboot_console_terminfo_input -}; - -static struct grub_term_output uboot_console_term_output = { - .name = "console", - .init = uboot_console_init_output, - .putchar = grub_terminfo_putchar, - .getwh = grub_terminfo_getwh, - .getxy = grub_terminfo_getxy, - .gotoxy = grub_terminfo_gotoxy, - .cls = grub_terminfo_cls, - .setcolorstate = grub_terminfo_setcolorstate, - .setcursor = uboot_console_setcursor, - .flags = GRUB_TERM_CODE_TYPE_ASCII, - .data = &uboot_console_terminfo_output, - .progress_update_divisor = GRUB_PROGRESS_FAST -}; - -void -grub_console_init_early (void) -{ - grub_term_register_input ("console", &uboot_console_term_input); - grub_term_register_output ("console", &uboot_console_term_output); -} - - -/* - * grub_console_init_lately(): - * Initializes terminfo formatting by registering terminal type. - * Called after heap has been configured. - * - */ -void -grub_console_init_lately (void) -{ - const char *type; - - /* See if explicitly set by U-Boot environment */ - type = grub_uboot_env_get ("grub_term"); - if (!type) - type = "vt100"; - - grub_terminfo_init (); - grub_terminfo_output_register (&uboot_console_term_output, type); -} - -void -grub_console_fini (void) -{ -} diff --git a/grub-core/term/usb_keyboard.c b/grub-core/term/usb_keyboard.c deleted file mode 100644 index 7322d8dff..000000000 --- a/grub-core/term/usb_keyboard.c +++ /dev/null @@ -1,471 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - - - -enum - { - KEY_NO_KEY = 0x00, - KEY_ERR_BUFFER = 0x01, - KEY_ERR_POST = 0x02, - KEY_ERR_UNDEF = 0x03, - KEY_CAPS_LOCK = 0x39, - KEY_NUM_LOCK = 0x53, - }; - -enum - { - LED_NUM_LOCK = 0x01, - LED_CAPS_LOCK = 0x02 - }; - -/* 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 - -#define USB_HID_BOOT_SUBCLASS 0x01 -#define USB_HID_KBD_PROTOCOL 0x01 - -#define GRUB_USB_KEYBOARD_LEFT_CTRL 0x01 -#define GRUB_USB_KEYBOARD_LEFT_SHIFT 0x02 -#define GRUB_USB_KEYBOARD_LEFT_ALT 0x04 -#define GRUB_USB_KEYBOARD_RIGHT_CTRL 0x10 -#define GRUB_USB_KEYBOARD_RIGHT_SHIFT 0x20 -#define GRUB_USB_KEYBOARD_RIGHT_ALT 0x40 - -struct grub_usb_keyboard_data -{ - grub_usb_device_t usbdev; - grub_uint8_t status; - grub_uint16_t mods; - int interfno; - struct grub_usb_desc_endp *endp; - grub_usb_transfer_t transfer; - grub_uint8_t report[8]; - int dead; - int last_key; - grub_uint64_t repeat_time; - grub_uint8_t current_report[8]; - grub_uint8_t last_report[8]; - int index; - int max_index; -}; - -static int grub_usb_keyboard_getkey (struct grub_term_input *term); -static int grub_usb_keyboard_getkeystatus (struct grub_term_input *term); - -static struct grub_term_input grub_usb_keyboard_term = - { - .getkey = grub_usb_keyboard_getkey, - .getkeystatus = grub_usb_keyboard_getkeystatus, - .next = 0 - }; - -static struct grub_term_input grub_usb_keyboards[16]; - -static int -interpret_status (grub_uint8_t data0) -{ - int mods = 0; - - /* Check Shift, Control, and Alt status. */ - if (data0 & GRUB_USB_KEYBOARD_LEFT_SHIFT) - mods |= GRUB_TERM_STATUS_LSHIFT; - if (data0 & GRUB_USB_KEYBOARD_RIGHT_SHIFT) - mods |= GRUB_TERM_STATUS_RSHIFT; - if (data0 & GRUB_USB_KEYBOARD_LEFT_CTRL) - mods |= GRUB_TERM_STATUS_LCTRL; - if (data0 & GRUB_USB_KEYBOARD_RIGHT_CTRL) - mods |= GRUB_TERM_STATUS_RCTRL; - if (data0 & GRUB_USB_KEYBOARD_LEFT_ALT) - mods |= GRUB_TERM_STATUS_LALT; - if (data0 & GRUB_USB_KEYBOARD_RIGHT_ALT) - mods |= GRUB_TERM_STATUS_RALT; - - return mods; -} - -static void -grub_usb_keyboard_detach (grub_usb_device_t usbdev, - int config __attribute__ ((unused)), - int interface __attribute__ ((unused))) -{ - unsigned i; - for (i = 0; i < ARRAY_SIZE (grub_usb_keyboards); i++) - { - struct grub_usb_keyboard_data *data = grub_usb_keyboards[i].data; - - if (!data) - continue; - - if (data->usbdev != usbdev) - continue; - - if (data->transfer) - grub_usb_cancel_transfer (data->transfer); - - grub_term_unregister_input (&grub_usb_keyboards[i]); - grub_free ((char *) grub_usb_keyboards[i].name); - grub_usb_keyboards[i].name = NULL; - grub_free (grub_usb_keyboards[i].data); - grub_usb_keyboards[i].data = 0; - } -} - -static int -grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno) -{ - unsigned curnum; - struct grub_usb_keyboard_data *data; - struct grub_usb_desc_endp *endp = NULL; - int j; - - grub_dprintf ("usb_keyboard", "%x %x %x %d %d\n", - usbdev->descdev.class, usbdev->descdev.subclass, - usbdev->descdev.protocol, configno, interfno); - - for (curnum = 0; curnum < ARRAY_SIZE (grub_usb_keyboards); curnum++) - if (!grub_usb_keyboards[curnum].data) - break; - - if (curnum == ARRAY_SIZE (grub_usb_keyboards)) - return 0; - - if (usbdev->descdev.class != 0 - || usbdev->descdev.subclass != 0 || usbdev->descdev.protocol != 0) - return 0; - - if (usbdev->config[configno].interf[interfno].descif->subclass - != USB_HID_BOOT_SUBCLASS - || usbdev->config[configno].interf[interfno].descif->protocol - != USB_HID_KBD_PROTOCOL) - return 0; - - for (j = 0; j < usbdev->config[configno].interf[interfno].descif->endpointcnt; - j++) - { - endp = &usbdev->config[configno].interf[interfno].descendp[j]; - - if ((endp->endp_addr & 128) && grub_usb_get_ep_type(endp) - == GRUB_USB_EP_INTERRUPT) - break; - } - if (j == usbdev->config[configno].interf[interfno].descif->endpointcnt) - return 0; - - grub_dprintf ("usb_keyboard", "HID found!\n"); - - data = grub_malloc (sizeof (*data)); - if (!data) - { - grub_print_error (); - return 0; - } - - data->usbdev = usbdev; - data->interfno = interfno; - data->endp = endp; - - /* Configure device */ - grub_usb_set_configuration (usbdev, configno + 1); - - /* Place the device in boot mode. */ - grub_usb_control_msg (usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT, - USB_HID_SET_PROTOCOL, 0, interfno, 0, 0); - - /* Reports every time an event occurs and not more often than that. */ - grub_usb_control_msg (usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT, - USB_HID_SET_IDLE, 0<<8, interfno, 0, 0); - - grub_memcpy (&grub_usb_keyboards[curnum], &grub_usb_keyboard_term, - sizeof (grub_usb_keyboards[curnum])); - grub_usb_keyboards[curnum].data = data; - usbdev->config[configno].interf[interfno].detach_hook - = grub_usb_keyboard_detach; - grub_usb_keyboards[curnum].name = grub_xasprintf ("usb_keyboard%d", curnum); - if (!grub_usb_keyboards[curnum].name) - { - grub_print_error (); - return 0; - } - - /* Test showed that getting report may make the keyboard go nuts. - Moreover since we're reattaching keyboard it usually sends - an initial message on interrupt pipe and so we retrieve - the same keystatus. - */ -#if 0 - { - grub_uint8_t report[8]; - grub_usb_err_t err; - grub_memset (report, 0, sizeof (report)); - err = grub_usb_control_msg (usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_IN, - USB_HID_GET_REPORT, 0x0100, interfno, - sizeof (report), (char *) report); - if (err) - data->status = 0; - else - data->status = report[0]; - } -#else - data->status = 0; -#endif - - data->transfer = grub_usb_bulk_read_background (usbdev, - data->endp, - sizeof (data->report), - (char *) data->report); - if (!data->transfer) - { - grub_print_error (); - return 0; - } - - data->last_key = -1; - data->mods = 0; - data->dead = 0; - - grub_term_register_input_active ("usb_keyboard", &grub_usb_keyboards[curnum]); - - return 1; -} - - - -static void -send_leds (struct grub_usb_keyboard_data *termdata) -{ - char report[1]; - report[0] = 0; - if (termdata->mods & GRUB_TERM_STATUS_CAPS) - report[0] |= LED_CAPS_LOCK; - if (termdata->mods & GRUB_TERM_STATUS_NUM) - report[0] |= LED_NUM_LOCK; - grub_usb_control_msg (termdata->usbdev, GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT, - USB_HID_SET_REPORT, 0x0200, termdata->interfno, - sizeof (report), (char *) report); - grub_errno = GRUB_ERR_NONE; -} - -static int -parse_keycode (struct grub_usb_keyboard_data *termdata) -{ - int index = termdata->index; - int i, keycode; - - /* Sanity check */ - if (index < 2) - index = 2; - - for ( ; index < termdata->max_index; index++) - { - keycode = termdata->current_report[index]; - - if (keycode == KEY_NO_KEY - || keycode == KEY_ERR_BUFFER - || keycode == KEY_ERR_POST - || keycode == KEY_ERR_UNDEF) - { - /* Don't parse (rest of) this report */ - termdata->index = 0; - if (keycode != KEY_NO_KEY) - /* Don't replace last report with current faulty report - * in future ! */ - grub_memcpy (termdata->current_report, - termdata->last_report, - sizeof (termdata->report)); - return GRUB_TERM_NO_KEY; - } - - /* Try to find current keycode in last report. */ - for (i = 2; i < 8; i++) - if (keycode == termdata->last_report[i]) - break; - if (i < 8) - /* Keycode is in last report, it means it was not released, - * ignore it. */ - continue; - - if (keycode == KEY_CAPS_LOCK) - { - termdata->mods ^= GRUB_TERM_STATUS_CAPS; - send_leds (termdata); - continue; - } - - if (keycode == KEY_NUM_LOCK) - { - termdata->mods ^= GRUB_TERM_STATUS_NUM; - send_leds (termdata); - continue; - } - - termdata->last_key = grub_term_map_key (keycode, - interpret_status (termdata->current_report[0]) - | termdata->mods); - termdata->repeat_time = grub_get_time_ms () + GRUB_TERM_REPEAT_PRE_INTERVAL; - - grub_errno = GRUB_ERR_NONE; - - index++; - if (index >= termdata->max_index) - termdata->index = 0; - else - termdata->index = index; - - return termdata->last_key; - } - - /* All keycodes parsed */ - termdata->index = 0; - return GRUB_TERM_NO_KEY; -} - -static int -grub_usb_keyboard_getkey (struct grub_term_input *term) -{ - grub_usb_err_t err; - struct grub_usb_keyboard_data *termdata = term->data; - grub_size_t actual; - int keycode = GRUB_TERM_NO_KEY; - - if (termdata->dead) - return GRUB_TERM_NO_KEY; - - if (termdata->index) - keycode = parse_keycode (termdata); - if (keycode != GRUB_TERM_NO_KEY) - return keycode; - - /* Poll interrupt pipe. */ - err = grub_usb_check_transfer (termdata->transfer, &actual); - - if (err == GRUB_USB_ERR_WAIT) - { - if (termdata->last_key != -1 - && grub_get_time_ms () > termdata->repeat_time) - { - termdata->repeat_time = grub_get_time_ms () - + GRUB_TERM_REPEAT_INTERVAL; - return termdata->last_key; - } - return GRUB_TERM_NO_KEY; - } - - if (!err && (actual >= 3)) - grub_memcpy (termdata->last_report, - termdata->current_report, - sizeof (termdata->report)); - - grub_memcpy (termdata->current_report, - termdata->report, - sizeof (termdata->report)); - - termdata->transfer = grub_usb_bulk_read_background (termdata->usbdev, - termdata->endp, - sizeof (termdata->report), - (char *) termdata->report); - if (!termdata->transfer) - { - grub_printf ("%s failed. Stopped\n", term->name); - termdata->dead = 1; - } - - termdata->last_key = -1; - - grub_dprintf ("usb_keyboard", - "err = %d, actual = %" PRIuGRUB_SIZE - " report: 0x%02x 0x%02x 0x%02x 0x%02x" - " 0x%02x 0x%02x 0x%02x 0x%02x\n", - err, actual, - termdata->current_report[0], termdata->current_report[1], - termdata->current_report[2], termdata->current_report[3], - termdata->current_report[4], termdata->current_report[5], - termdata->current_report[6], termdata->current_report[7]); - - if (err || actual < 1) - return GRUB_TERM_NO_KEY; - - termdata->status = termdata->current_report[0]; - - if (actual < 3) - return GRUB_TERM_NO_KEY; - - termdata->index = 2; /* New data received. */ - termdata->max_index = actual; - - return parse_keycode (termdata); -} - -static int -grub_usb_keyboard_getkeystatus (struct grub_term_input *term) -{ - struct grub_usb_keyboard_data *termdata = term->data; - - return interpret_status (termdata->status) | termdata->mods; -} - -static struct grub_usb_attach_desc attach_hook = -{ - .class = GRUB_USB_CLASS_HID, - .hook = grub_usb_keyboard_attach -}; - -GRUB_MOD_INIT(usb_keyboard) -{ - grub_usb_register_attach_hook_class (&attach_hook); -} - -GRUB_MOD_FINI(usb_keyboard) -{ - unsigned i; - for (i = 0; i < ARRAY_SIZE (grub_usb_keyboards); i++) - if (grub_usb_keyboards[i].data) - { - struct grub_usb_keyboard_data *data = grub_usb_keyboards[i].data; - - if (!data) - continue; - - if (data->transfer) - grub_usb_cancel_transfer (data->transfer); - - grub_term_unregister_input (&grub_usb_keyboards[i]); - grub_free ((char *) grub_usb_keyboards[i].name); - grub_usb_keyboards[i].name = NULL; - grub_free (grub_usb_keyboards[i].data); - grub_usb_keyboards[i].data = 0; - } - grub_usb_unregister_attach_hook_class (&attach_hook); -} diff --git a/grub-core/term/xen/console.c b/grub-core/term/xen/console.c deleted file mode 100644 index a1f15f71a..000000000 --- a/grub-core/term/xen/console.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -static int -readkey (struct grub_term_input *term __attribute__ ((unused))) -{ - grub_size_t prod, cons; - int r; - mb (); - prod = grub_xen_xcons->in_prod; - cons = grub_xen_xcons->in_cons; - if (prod <= cons) - return -1; - r = grub_xen_xcons->in[cons]; - cons++; - mb (); - grub_xen_xcons->in_cons = cons; - return r; -} - -static int signal_sent = 1; - -static void -refresh (struct grub_term_output *term __attribute__ ((unused))) -{ - struct evtchn_send send; - send.port = grub_xen_start_page_addr->console.domU.evtchn; - grub_xen_event_channel_op (EVTCHNOP_send, &send); - signal_sent = 1; - while (grub_xen_xcons->out_prod != grub_xen_xcons->out_cons) - { - grub_xen_sched_op (SCHEDOP_yield, 0); - } -} - -static void -put (struct grub_term_output *term __attribute__ ((unused)), const int c) -{ - grub_size_t prod, cons; - - while (1) - { - mb (); - prod = grub_xen_xcons->out_prod; - cons = grub_xen_xcons->out_cons; - if (prod < cons + sizeof (grub_xen_xcons->out)) - break; - if (!signal_sent) - refresh (term); - grub_xen_sched_op (SCHEDOP_yield, 0); - } - grub_xen_xcons->out[prod++ & (sizeof (grub_xen_xcons->out) - 1)] = c; - mb (); - grub_xen_xcons->out_prod = prod; - signal_sent = 0; -} - - -struct grub_terminfo_input_state grub_console_terminfo_input = { - .readkey = readkey -}; - -struct grub_terminfo_output_state grub_console_terminfo_output = { - .put = put, - .size = {80, 24} -}; - -static struct grub_term_input grub_console_term_input = { - .name = "console", - .init = 0, - .getkey = grub_terminfo_getkey, - .data = &grub_console_terminfo_input -}; - -static struct grub_term_output grub_console_term_output = { - .name = "console", - .init = 0, - .putchar = grub_terminfo_putchar, - .getxy = grub_terminfo_getxy, - .getwh = grub_terminfo_getwh, - .gotoxy = grub_terminfo_gotoxy, - .cls = grub_terminfo_cls, - .refresh = refresh, - .setcolorstate = grub_terminfo_setcolorstate, - .setcursor = grub_terminfo_setcursor, - .flags = GRUB_TERM_CODE_TYPE_ASCII, - .data = &grub_console_terminfo_output, -}; - - -void -grub_console_init (void) -{ - grub_term_register_input ("console", &grub_console_term_input); - grub_term_register_output ("console", &grub_console_term_output); - - grub_terminfo_init (); - grub_terminfo_output_register (&grub_console_term_output, "vt100-color"); -} diff --git a/grub-core/tests/asn1/asn1_test.c b/grub-core/tests/asn1/asn1_test.c deleted file mode 100644 index 69606b004..000000000 --- a/grub-core/tests/asn1/asn1_test.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2020 IBM Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include "asn1_test.h" - -/* - * libtasn1 tests - from which this is derived - are provided under GPL3+. - */ -GRUB_MOD_LICENSE ("GPLv3+"); - -static void -asn1_test (void) -{ - grub_test_assert (test_CVE_2018_1000654 () == 0, "CVE-2018-1000654 test failed"); - - grub_test_assert (test_object_id_encoding () == 0, "ASN.1 object ID encoding test failed"); - - grub_test_assert (test_object_id_decoding () == 0, "ASN.1 object ID decoding test failed"); - - grub_test_assert (test_octet_string () == 0, "ASN.1 octet string test failed"); - - grub_test_assert (test_overflow () == 0, "ASN.1 overflow test failed"); - - grub_test_assert (test_reproducers () == 0, "ASN.1 reproducers test failed"); - - grub_test_assert (test_simple () == 0, "ASN.1 simple test failed"); - - grub_test_assert (test_strings () == 0, "ASN.1 strings test fail" ); -} - -/* Register asn1_test method as a functional test. */ -GRUB_FUNCTIONAL_TEST (asn1_test, asn1_test); diff --git a/grub-core/tests/asn1/asn1_test.h b/grub-core/tests/asn1/asn1_test.h deleted file mode 100644 index 8e83d70f5..000000000 --- a/grub-core/tests/asn1/asn1_test.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2020 IBM Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef LIBTASN1_WRAP_TESTS_H -#define LIBTASN1_WRAP_TESTS_H - -#include -#include -#include -#include -#include - -extern int test_CVE_2018_1000654 (void); - -extern int test_object_id_encoding (void); - -extern int test_object_id_decoding (void); - -extern int test_octet_string (void); - -extern int test_overflow (void); - -extern int test_reproducers (void); - -extern int test_simple (void); - -extern int test_strings (void); - -#endif diff --git a/grub-core/tests/boot/kbsd.init-i386.S b/grub-core/tests/boot/kbsd.init-i386.S deleted file mode 100644 index 72ddb7c16..000000000 --- a/grub-core/tests/boot/kbsd.init-i386.S +++ /dev/null @@ -1,107 +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 . - */ - -#ifdef TARGET_NETBSD -#define SYSCALL_RESET 208 -#elif defined (TARGET_OPENBSD) -#define SYSCALL_RESET 55 -#else -#error unknown target -#endif - -#define MODE_RDRW 2 -#define FLAGS_NONE 0 -#define SYSCALL_OPEN 5 -#define SYSCALL_WRITE 4 -#define SYSCALL_EXIT 1 -#define SYSCALL_ARCH 165 -#define SYSCALL_INT 0x80 -#define SYSCALL_ARCH_IOPL 2 - -#define RESET_NOSYNC 0x4 -#define RESET_HALT 0x8 -#define RESET_POWEROFF 0x800 - - .section ".init", "ax" - .global start,_start -start: -_start: - /* open. */ - movl $SYSCALL_OPEN, %eax - pushl $FLAGS_NONE - pushl $MODE_RDRW - leal device, %ebx - pushl %ebx - pushl $0 - int $SYSCALL_INT - addl $16, %esp - movl %eax, %ecx - - /* write. */ - movl $SYSCALL_WRITE, %eax - pushl $(messageend-message) - leal message, %ebx - pushl %ebx - pushl %ecx - pushl $0 - int $SYSCALL_INT - addl $16, %esp - - /* IOPL. */ - movl $SYSCALL_ARCH, %eax - pushl $iopl_arg - pushl $SYSCALL_ARCH_IOPL - pushl $0 - int $SYSCALL_INT - addl $12, %esp - -#include "qemu-shutdown-x86.S" - - /* shutdown. */ - movl $SYSCALL_RESET, %eax - pushl $0 - pushl $(RESET_POWEROFF|RESET_HALT|RESET_NOSYNC) - pushl $0 - int $SYSCALL_INT - addl $8, %esp - - /* exit (1). Shouldn't be reached. */ - movl $SYSCALL_EXIT, %eax - pushl $1 - pushl $0 - int $SYSCALL_INT - .section ".fini", "ax" -1: jmp 1b - .section ".text", "ax" -1: jmp 1b - /* This section is needed for NetBSD to identify the binary. */ - .section ".note.netbsd.ident", "a" - .long 0x7 - .long 0x4 - .long 0x1 - .ascii "NetBSD" - .byte 0 - .data -device: - .ascii "/dev/console" - .byte 0 -message: - .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" -messageend: -iopl_arg: - .long 3 diff --git a/grub-core/tests/boot/kbsd.init-x86_64.S b/grub-core/tests/boot/kbsd.init-x86_64.S deleted file mode 100644 index 7486bc312..000000000 --- a/grub-core/tests/boot/kbsd.init-x86_64.S +++ /dev/null @@ -1,94 +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 . - */ - -#define MODE_RDRW 2 -#define FLAGS_NONE 0 -#define SYSCALL_OPEN 5 -#define SYSCALL_WRITE 4 -#ifdef TARGET_NETBSD -#define SYSCALL_RESET 208 -#elif defined (TARGET_OPENBSD) -#define SYSCALL_RESET 55 -#else -#error unknown target -#endif -#define SYSCALL_EXIT 1 -#define SYSCALL_ARCH 165 -#define SYSCALL_INT 0x80 -#define SYSCALL_ARCH_IOPL 2 - -#define RESET_NOSYNC 0x4 -#define RESET_HALT 0x8 -#define RESET_POWEROFF 0x800 - - .section ".init", "ax" - .global start,_start -start: -_start: - /* open. */ - movq $SYSCALL_OPEN, %rax - leaq device, %rdi - movq $MODE_RDRW, %rsi - movq $FLAGS_NONE, %rdx - syscall - movq %rax, %rdi - - /* write. */ - movq $SYSCALL_WRITE, %rax - movq $(messageend-message), %rdx - leaq message, %rsi - syscall - - /* IOPL. */ - movq $SYSCALL_ARCH, %rax - movq $SYSCALL_ARCH_IOPL, %rdi - leaq iopl_arg, %rsi - syscall - -#include "qemu-shutdown-x86.S" - - /* shutdown. */ - movq $SYSCALL_RESET, %rax - movq $(RESET_POWEROFF|RESET_HALT|RESET_NOSYNC), %rdi - movq $0, %rsi - syscall - - /* exit (1). Shouldn't be reached. */ - movq $SYSCALL_EXIT, %rax - movq $1, %rdi - syscall - .section ".fini", "ax" -1: jmp 1b - .section ".text", "ax" -1: jmp 1b - /* This section is needed for NetBSD to identify the binary. */ - .section ".note.netbsd.ident", "a" - .long 0x7 - .long 0x4 - .long 0x1 - .ascii "NetBSD" - .byte 0 - .data -device: - .ascii "/dev/console" - .byte 0 -message: - .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" -messageend: -iopl_arg: - .long 3 diff --git a/grub-core/tests/boot/kbsd.spec.txt b/grub-core/tests/boot/kbsd.spec.txt deleted file mode 100644 index af171bc56..000000000 --- a/grub-core/tests/boot/kbsd.spec.txt +++ /dev/null @@ -1,3 +0,0 @@ -. type=dir - dev type=dir - console type=char device=0 mode=666 gid=0 uid=0 diff --git a/grub-core/tests/boot/kernel-8086.S b/grub-core/tests/boot/kernel-8086.S deleted file mode 100644 index 5ec5368ff..000000000 --- a/grub-core/tests/boot/kernel-8086.S +++ /dev/null @@ -1,50 +0,0 @@ - - .text - .globl _start -_start: -base: - .code16 - jmp cont - -serialmsg: -1: - movb 0(%si), %bl - testb %bl, %bl - jz 1f - movw $0x3fd, %dx -2: - inb %dx, %al - testb $0x20, %al - jz 2b - - movw $0x3f8, %dx - movb %bl, %al - outb %al, %dx - incw %si - jmp 1b -1: - ret - -cont: -#ifdef TARGET_NTLDR - movw $0x2000, %ax -#elif defined (TARGET_CHAINLOADER) - xorw %ax, %ax -#else -#error unsupported target -#endif - movw %ax, %ds - lea message, %si - call serialmsg -#include "qemu-shutdown-x86.S" - -1: - hlt - jmp 1b - -message: - .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" - .byte 0 - - .org 510 - .short 0xaa55 diff --git a/grub-core/tests/boot/kernel-i386.S b/grub-core/tests/boot/kernel-i386.S deleted file mode 100644 index 2154d3b2d..000000000 --- a/grub-core/tests/boot/kernel-i386.S +++ /dev/null @@ -1,72 +0,0 @@ -#define ASM_FILE 1 -#ifdef TARGET_MULTIBOOT2 -#include -#elif defined (TARGET_MULTIBOOT) -#include -#endif - - .text - /* Align 32 bits boundary. */ - .align 8 - -#ifdef TARGET_MULTIBOOT2 - /* Multiboot header. */ -multiboot_header: - /* magic */ - .long MULTIBOOT2_HEADER_MAGIC - /* ISA: i386 */ - .long MULTIBOOT_ARCHITECTURE_I386 - /* Header length. */ - .long multiboot_header_end - multiboot_header - /* checksum */ - .long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (multiboot_header_end - multiboot_header)) - .short MULTIBOOT_HEADER_TAG_END - .short 0 - .long 8 -multiboot_header_end: -#elif defined (TARGET_MULTIBOOT) - /* Multiboot header. */ -multiboot_header: - /* magic */ - .long MULTIBOOT_HEADER_MAGIC - /* flags */ - .long 0 - /* checksum */ - .long -MULTIBOOT_HEADER_MAGIC -#endif - - .global start - -serialmsg: -1: - movb 0(%esi), %bl - testb %bl, %bl - jz 1f - movw $0x3fd, %dx -2: - inb %dx, %al - testb $0x20, %al - jz 2b - - movw $0x3f8, %dx - movb %bl, %al - outb %al, %dx - incl %esi - jmp 1b -1: - ret - - .globl _start -_start: - lea message, %esi - call serialmsg - -#include "qemu-shutdown-x86.S" - -1: - hlt - jmp 1b - -message: - .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" - .byte 0 diff --git a/grub-core/tests/boot/kfreebsd-aout.cfg b/grub-core/tests/boot/kfreebsd-aout.cfg deleted file mode 100644 index 31e34b4ee..000000000 --- a/grub-core/tests/boot/kfreebsd-aout.cfg +++ /dev/null @@ -1,4 +0,0 @@ -kfreebsd /kfreebsd.aout -boot -# Shouln't happen -halt diff --git a/grub-core/tests/boot/kfreebsd.cfg b/grub-core/tests/boot/kfreebsd.cfg deleted file mode 100644 index f28ee7998..000000000 --- a/grub-core/tests/boot/kfreebsd.cfg +++ /dev/null @@ -1,8 +0,0 @@ -kfreebsd /kfreebsd -hv -kfreebsd_loadenv /kfreebsd_env -kfreebsd_module /mfsroot.gz type=mfs_root -set kFreeBSD.hw.hasbrokenint12=1 -fakebios -boot -# Shouln't happen -halt diff --git a/grub-core/tests/boot/kfreebsd.init-i386.S b/grub-core/tests/boot/kfreebsd.init-i386.S deleted file mode 100644 index 7a4babaf9..000000000 --- a/grub-core/tests/boot/kfreebsd.init-i386.S +++ /dev/null @@ -1,109 +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 . - */ - -#define MODE_RDRW 2 -#define FLAGS_NONE 0 -#define SYSCALL_OPEN 5 -#define SYSCALL_WRITE 4 -#define SYSCALL_RESET 55 -#define SYSCALL_FSYNC 95 -#define SYSCALL_ARCH 165 -#define SYSCALL_EXIT 1 -#define SYSCALL_ARCH_IOPERM 4 -#define SYSCALL_INT 0x80 - -#define RESET_NOSYNC 0x4 -#define RESET_HALT 0x8 -#define RESET_POWEROFF 0x4000 - - .section ".init", "ax" - .global start,_start -start: -_start: - /* open. */ - movl $SYSCALL_OPEN, %eax - pushl $FLAGS_NONE - pushl $MODE_RDRW - leal device, %ebx - pushl %ebx - pushl $0 - int $SYSCALL_INT - addl $16, %esp - movl %eax, %ecx - - /* write. */ - movl $SYSCALL_WRITE, %eax - pushl $(messageend-message) - leal message, %ebx - pushl %ebx - pushl %ecx - pushl $0 - int $SYSCALL_INT - addl $16, %esp - - /* fsync. */ - movl $SYSCALL_FSYNC, %eax - pushl %ecx - pushl $0 - int $SYSCALL_INT - addl $8, %esp - - /* IOPERM. */ - movl $SYSCALL_ARCH, %eax - pushl $ioperm_arg1 - pushl $SYSCALL_ARCH_IOPERM - pushl $0 - int $SYSCALL_INT - addl $12, %esp - - /* IOPERM. */ - movl $SYSCALL_ARCH, %eax - pushl $ioperm_arg2 - pushl $SYSCALL_ARCH_IOPERM - pushl $0 - int $SYSCALL_INT - addl $12, %esp - -#include "qemu-shutdown-x86.S" - - /* shutdown. */ - movl $SYSCALL_RESET, %eax - pushl $(RESET_POWEROFF|RESET_HALT|RESET_NOSYNC) - pushl $0 - int $SYSCALL_INT - addl $8, %esp - - /* exit (1). Shouldn't be reached. */ - movl $SYSCALL_EXIT, %eax - pushl $1 - pushl $0 - int $SYSCALL_INT -device: - .ascii "/dev/console" - .byte 0 -message: - .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" -messageend: -ioperm_arg1: - .long 0xcf8 - .long 8 - .long 1 -ioperm_arg2: - .long 0x7000 - .long 8 - .long 1 diff --git a/grub-core/tests/boot/kfreebsd.init-x86_64.S b/grub-core/tests/boot/kfreebsd.init-x86_64.S deleted file mode 100644 index 05e5760e0..000000000 --- a/grub-core/tests/boot/kfreebsd.init-x86_64.S +++ /dev/null @@ -1,90 +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 . - */ - -#define MODE_RDRW 2 -#define FLAGS_NONE 0 -#define SYSCALL_ARCH 165 -#define SYSCALL_OPEN 5 -#define SYSCALL_WRITE 4 -#define SYSCALL_RESET 55 -#define SYSCALL_EXIT 1 -#define SYSCALL_ARCH_IOPERM 4 -#define SYSCALL_FSYNC 95 - -#define RESET_NOSYNC 0x4 -#define RESET_HALT 0x8 -#define RESET_POWEROFF 0x4000 - - .section ".init", "ax" - .global start,_start -start: -_start: - /* open. */ - movq $SYSCALL_OPEN, %rax - leaq device, %rdi - movq $MODE_RDRW, %rsi - movq $FLAGS_NONE, %rdx - syscall - movq %rax, %rdi - - /* write. */ - leaq message, %rsi - movq $SYSCALL_WRITE, %rax - movq $(messageend - message), %rdx - syscall - - /* fsync. */ - movq $SYSCALL_FSYNC, %rax - syscall - - /* IOPERM. */ - movq $SYSCALL_ARCH, %rax - movq $SYSCALL_ARCH_IOPERM, %rdi - leaq ioperm_arg1, %rsi - syscall - - movq $SYSCALL_ARCH, %rax - movq $SYSCALL_ARCH_IOPERM, %rdi - leaq ioperm_arg2, %rsi - syscall - -#include "qemu-shutdown-x86.S" - - /* shutdown. */ - movq $SYSCALL_RESET, %rax - movq $(RESET_POWEROFF|RESET_HALT|RESET_NOSYNC), %rdi - syscall - - /* exit (1). Shouldn't be reached. */ - movq $SYSCALL_EXIT, %rax - movq $1, %rdi - syscall -device: - .ascii "/dev/console" - .byte 0 -message: - .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" -messageend: -ioperm_arg1: - .long 0xcf8 - .long 8 - .long 1 -ioperm_arg2: - .long 0x7000 - .long 8 - .long 1 diff --git a/grub-core/tests/boot/knetbsd.cfg b/grub-core/tests/boot/knetbsd.cfg deleted file mode 100644 index f88a846e1..000000000 --- a/grub-core/tests/boot/knetbsd.cfg +++ /dev/null @@ -1,5 +0,0 @@ -knetbsd /knetbsd -h -knetbsd_module_elf /miniroot.gz -boot -# Shouln't happen -halt diff --git a/grub-core/tests/boot/kopenbsd.cfg b/grub-core/tests/boot/kopenbsd.cfg deleted file mode 100644 index 132bec4b6..000000000 --- a/grub-core/tests/boot/kopenbsd.cfg +++ /dev/null @@ -1,5 +0,0 @@ -kopenbsd /kopenbsd -h -kopenbsd_ramdisk /ramdisk -boot -# Shouln't happen -halt diff --git a/grub-core/tests/boot/kopenbsdlabel.txt b/grub-core/tests/boot/kopenbsdlabel.txt deleted file mode 100644 index bb141133b..000000000 --- a/grub-core/tests/boot/kopenbsdlabel.txt +++ /dev/null @@ -1,3 +0,0 @@ -# size offset fstype [fsize bsize bps/cpg] - a: 256 0 4.2BSD 0 0 1 - c: 256 0 unused 0 0 # "raw" part, don't edit diff --git a/grub-core/tests/boot/linux-ppc.cfg b/grub-core/tests/boot/linux-ppc.cfg deleted file mode 100644 index 3ceabc369..000000000 --- a/grub-core/tests/boot/linux-ppc.cfg +++ /dev/null @@ -1,5 +0,0 @@ -linux /linux console=ttyPZ1 root=/dev/ram0 -initrd /initrd -boot -# Shouln't happen -halt diff --git a/grub-core/tests/boot/linux.cfg b/grub-core/tests/boot/linux.cfg deleted file mode 100644 index f5bf6ac7d..000000000 --- a/grub-core/tests/boot/linux.cfg +++ /dev/null @@ -1,5 +0,0 @@ -linux /linux console=ttyS0 root=/dev/ram0 -initrd /initrd -boot -# Shouln't happen -halt diff --git a/grub-core/tests/boot/linux.init-i386.S b/grub-core/tests/boot/linux.init-i386.S deleted file mode 100644 index c0983ac0a..000000000 --- a/grub-core/tests/boot/linux.init-i386.S +++ /dev/null @@ -1,61 +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 . - */ - -#define SYSCALL_WRITE 4 -#define SYSCALL_RESET 88 -#define SYSCALL_IOPL 110 -#define SYSCALL_EXIT 1 -#define SYSCALL_INT 0x80 - -#define STDOUT 1 -#define SHUTDOWN_MAGIC1 0xfee1dead -#define SHUTDOWN_MAGIC2 0x28121969 -#define SHUTDOWN_MAGIC3 0x4321fedc - - .text - .global start, _start -_start: -start: - /* write. */ - movl $SYSCALL_WRITE, %eax - movl $STDOUT, %ebx - leal message, %ecx - movl $(messageend-message), %edx - int $SYSCALL_INT - - movl $SYSCALL_IOPL, %eax - movl $3, %ebx - int $SYSCALL_INT - -#include "qemu-shutdown-x86.S" - - /* shutdown. */ - movl $SYSCALL_RESET, %eax - movl $SHUTDOWN_MAGIC1, %ebx - movl $SHUTDOWN_MAGIC2, %ecx - movl $SHUTDOWN_MAGIC3, %edx - int $SYSCALL_INT - - /* exit (1). Shouldn't be reached. */ - movl $SYSCALL_EXIT, %eax - movl $1, %ebx - int $SYSCALL_INT - .data -message: - .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" -messageend: diff --git a/grub-core/tests/boot/linux.init-mips.S b/grub-core/tests/boot/linux.init-mips.S deleted file mode 100644 index 5ef4c3794..000000000 --- a/grub-core/tests/boot/linux.init-mips.S +++ /dev/null @@ -1,61 +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 . - */ - -#define SYSCALL_WRITE 4004 -#define SYSCALL_RESET 4088 -#define SYSCALL_EXIT 4001 - -#define STDOUT 1 -#define SHUTDOWN_MAGIC1 0xfee1dead -#define SHUTDOWN_MAGIC2 0x28121969 -#ifdef REBOOT -#define SHUTDOWN_MAGIC3 0x01234567 -#else -#define SHUTDOWN_MAGIC3 0x4321fedc -#endif - .text - .global start, _start, __start -__start: -_start: -start: - /* write. */ - li $v0, SYSCALL_WRITE - li $a0, STDOUT - lui $a1, %hi(message) - addiu $a1, %lo(message) - lui $a2, %hi(messageend) - addiu $a2, %lo(messageend) - subu $a2, $a2, $a1 - syscall - - /* shutdown. */ - li $v0, SYSCALL_RESET - li $a0, SHUTDOWN_MAGIC1 - li $a1, SHUTDOWN_MAGIC2 - li $a2, SHUTDOWN_MAGIC3 - syscall - - /* exit(1). Shouldn't be reached. */ - li $v0, SYSCALL_EXIT - li $a0, 1 - syscall - - .data -message: - .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" -messageend: diff --git a/grub-core/tests/boot/linux.init-ppc.S b/grub-core/tests/boot/linux.init-ppc.S deleted file mode 100644 index 8c9aa441f..000000000 --- a/grub-core/tests/boot/linux.init-ppc.S +++ /dev/null @@ -1,61 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2012 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#define SYSCALL_WRITE 4 -#define SYSCALL_RESET 88 -#define SYSCALL_EXIT 1 - -#define STDOUT 1 -#define SHUTDOWN_MAGIC1 0xfee1dead -#define SHUTDOWN_MAGIC2 0x28121969 -#define SHUTDOWN_MAGIC3 0x4321fedc - - .text - .global start, _start, __start -__start: -_start: -start: - /* write. */ - li %r0, SYSCALL_WRITE - li %r3, STDOUT - lis %r4, message@h - ori %r4, %r4, message@l - lis %r5, messageend@h - ori %r5, %r5, messageend@l - sub %r5, %r5, %r4 - sc - - /* shutdown. */ - li %r0, SYSCALL_RESET - lis %r3, SHUTDOWN_MAGIC1@h - ori %r3, %r3, SHUTDOWN_MAGIC1@l - lis %r4, SHUTDOWN_MAGIC2@h - ori %r4, %r4, SHUTDOWN_MAGIC2@l - lis %r5, SHUTDOWN_MAGIC3@h - ori %r5, %r5, SHUTDOWN_MAGIC3@l - sc - - /* exit(1). Shouldn't be reached. */ - li %r0, SYSCALL_EXIT - li %r3, 1 - sc - - .data -message: - .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" -messageend: diff --git a/grub-core/tests/boot/linux.init-x86_64.S b/grub-core/tests/boot/linux.init-x86_64.S deleted file mode 100644 index 90bdcc356..000000000 --- a/grub-core/tests/boot/linux.init-x86_64.S +++ /dev/null @@ -1,60 +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 . - */ - -#define SYSCALL_WRITE 1 -#define SYSCALL_RESET 169 -#define SYSCALL_IOPL 172 -#define SYSCALL_EXIT 60 - -#define STDOUT 1 -#define SHUTDOWN_MAGIC1 0xfee1dead -#define SHUTDOWN_MAGIC2 0x28121969 -#define SHUTDOWN_MAGIC3 0x4321fedc - - .text - .global start, _start -_start: -start: - /* write. */ - movq $SYSCALL_WRITE, %rax - movq $STDOUT, %rdi - leaq message, %rsi - movq $(messageend-message), %rdx - syscall - - movq $SYSCALL_IOPL, %rax - movq $3, %rdi - syscall - -#include "qemu-shutdown-x86.S" - - /* shutdown. */ - movq $SYSCALL_RESET, %rax - movq $SHUTDOWN_MAGIC1, %rdi - movq $SHUTDOWN_MAGIC2, %rsi - movq $SHUTDOWN_MAGIC3, %rdx - syscall - - /* exit(1). Shouldn't be reached. */ - movq $SYSCALL_EXIT, %rax - movq $1, %rdi - syscall - .data -message: - .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" -messageend: diff --git a/grub-core/tests/boot/linux16.cfg b/grub-core/tests/boot/linux16.cfg deleted file mode 100644 index d7fbf961c..000000000 --- a/grub-core/tests/boot/linux16.cfg +++ /dev/null @@ -1,5 +0,0 @@ -linux16 /linux console=ttyS0 root=/dev/ram0 -initrd16 /initrd -boot -# Shouln't happen -halt diff --git a/grub-core/tests/boot/multiboot.cfg b/grub-core/tests/boot/multiboot.cfg deleted file mode 100644 index 0942ec67c..000000000 --- a/grub-core/tests/boot/multiboot.cfg +++ /dev/null @@ -1,4 +0,0 @@ -multiboot /multiboot.elf -boot -# Shouln't happen -halt diff --git a/grub-core/tests/boot/multiboot2.cfg b/grub-core/tests/boot/multiboot2.cfg deleted file mode 100644 index 2bec9e6d1..000000000 --- a/grub-core/tests/boot/multiboot2.cfg +++ /dev/null @@ -1,4 +0,0 @@ -multiboot2 /multiboot2.elf -boot -# Shouln't happen -halt diff --git a/grub-core/tests/boot/ntldr.cfg b/grub-core/tests/boot/ntldr.cfg deleted file mode 100644 index cd438a4bc..000000000 --- a/grub-core/tests/boot/ntldr.cfg +++ /dev/null @@ -1,4 +0,0 @@ -ntldr /ntldr.bin -boot -# Shouln't happen -halt diff --git a/grub-core/tests/boot/pc-chainloader.cfg b/grub-core/tests/boot/pc-chainloader.cfg deleted file mode 100644 index 1e80a5b96..000000000 --- a/grub-core/tests/boot/pc-chainloader.cfg +++ /dev/null @@ -1,4 +0,0 @@ -chainloader /pc-chainloader.bin -boot -# Shouln't happen -halt diff --git a/grub-core/tests/boot/qemu-shutdown-x86.S b/grub-core/tests/boot/qemu-shutdown-x86.S deleted file mode 100644 index e37f5df79..000000000 --- a/grub-core/tests/boot/qemu-shutdown-x86.S +++ /dev/null @@ -1,17 +0,0 @@ - movl $0x80000b80, %eax - movw $0xcf8, %dx - outl %eax, %dx - movw $0xcfc, %dx - inb %dx, %al - orb $1, %al - outb %al, %dx - - movl $0x80000b40, %eax - movw $0xcf8, %dx - outl %eax, %dx - movl $0x7001, %eax - movw $0xcfc, %dx - outl %eax, %dx - movw $0x2000, %ax - movw $0x7004, %dx - outw %ax, %dx diff --git a/grub-core/tests/bswap_test.c b/grub-core/tests/bswap_test.c deleted file mode 100644 index 4eb3a9814..000000000 --- a/grub-core/tests/bswap_test.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2015 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_uint64_t vectors[] = { - 0xffffffffffffffffULL, 1, 2, 0, 0x0102030405060708ULL -}; - -static void -test16 (grub_uint16_t a) -{ - grub_uint16_t b, c; - grub_uint8_t *ap, *bp; - int i; - b = grub_swap_bytes16 (a); - c = grub_swap_bytes16 (b); - grub_test_assert (a == c, "bswap not idempotent: 0x%llx, 0x%llx, 0x%llx", - (long long) a, (long long) b, (long long) c); - ap = (grub_uint8_t *) &a; - bp = (grub_uint8_t *) &b; - for (i = 0; i < 2; i++) - { - grub_test_assert (ap[i] == bp[1 - i], - "bswap bytes wrong: 0x%llx, 0x%llx", - (long long) a, (long long) b); - } -} - -static void -test32 (grub_uint32_t a) -{ - grub_uint32_t b, c; - grub_uint8_t *ap, *bp; - int i; - b = grub_swap_bytes32 (a); - c = grub_swap_bytes32 (b); - grub_test_assert (a == c, "bswap not idempotent: 0x%llx, 0x%llx, 0x%llx", - (long long) a, (long long) b, (long long) c); - ap = (grub_uint8_t *) &a; - bp = (grub_uint8_t *) &b; - for (i = 0; i < 4; i++) - { - grub_test_assert (ap[i] == bp[3 - i], - "bswap bytes wrong: 0x%llx, 0x%llx", - (long long) a, (long long) b); - } -} - -static void -test64 (grub_uint64_t a) -{ - grub_uint64_t b, c; - grub_uint8_t *ap, *bp; - int i; - b = grub_swap_bytes64 (a); - c = grub_swap_bytes64 (b); - grub_test_assert (a == c, "bswap not idempotent: 0x%llx, 0x%llx, 0x%llx", - (long long) a, (long long) b, (long long) c); - ap = (grub_uint8_t *) &a; - bp = (grub_uint8_t *) &b; - for (i = 0; i < 4; i++) - { - grub_test_assert (ap[i] == bp[7 - i], - "bswap bytes wrong: 0x%llx, 0x%llx", - (long long) a, (long long) b); - } -} - -static void -test_all(grub_uint64_t a) -{ - test64 (a); - test32 (a); - test16 (a); -} - -static void -bswap_test (void) -{ - grub_uint64_t a = 404, b = 7; - grub_size_t i; - - for (i = 0; i < ARRAY_SIZE (vectors); i++) - { - test_all (vectors[i]); - } - for (i = 0; i < 40000; i++) - { - a = 17 * a + 13 * b; - b = 23 * a + 29 * b; - if (b == 0) - b = 1; - if (a == 0) - a = 1; - test_all (a); - test_all (b); - } -} - -/* Register example_test method as a functional test. */ -GRUB_FUNCTIONAL_TEST (bswap_test, bswap_test); diff --git a/grub-core/tests/checksums.h b/grub-core/tests/checksums.h deleted file mode 100644 index 8273bd105..000000000 --- a/grub-core/tests/checksums.h +++ /dev/null @@ -1,129 +0,0 @@ - { "cmdline_cat", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xc69be699, 0xc69be699, 0xe17fc97c, 0xe17fc97c, 0xc2512486, 0xc2512486, 0x20260761, 0x20260761, 0xe3485349, 0xe3485349, 0x6020b4d9, 0x6020b4d9, 0x1605db98, 0x1605db98, 0xdca51b58, 0xdca51b58, 0xf3d66441, 0xf3d66441, 0x18cb7ce2, 0x18cb7ce2, 0x23b616d9, 0x23b616d9, 0xa1bf5dbf, 0xa1bf5dbf, 0x5e4a8b3d, 0x5e4a8b3d, 0x9933b3d8, 0x9933b3d8, 0xce7be2de, 0xce7be2de, 0x62531729, 0x62531729, 0xc39d3788, 0xc39d3788, 0xf7aee2fe, 0xf7aee2fe, 0xc66f4903, 0xc66f4903, 0x536c922f, 0x536c922f, 0xcb231652, 0x4ae07b67, 0x146816d5, 0x146816d5, }, 45 }, - { "cmdline_cat", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x29d0cfb7, 0x29d0cfb7, 0x4d57ad88, 0x4d57ad88, 0xaf7591cb, 0xaf7591cb, 0xb88e3c0, 0xb88e3c0, 0x5d55a031, 0x5d55a031, 0x4363bcff, 0x4363bcff, 0xe1142833, 0xe1142833, 0x9578c80d, 0x9578c80d, 0xff1f5174, 0xff1f5174, 0x6828d47, 0x6828d47, 0x2a849ae3, 0x2a849ae3, 0x27a811d9, 0x27a811d9, 0x6c42e1cb, 0x6c42e1cb, 0x5bba61f5, 0x5bba61f5, 0xc02ab705, 0xc02ab705, 0xeb3e0e05, 0xeb3e0e05, 0x6f4ce3c, 0x6f4ce3c, 0x2075c50e, 0x2075c50e, 0x54ac7fba, 0x54ac7fba, 0x335d1c21, 0x335d1c21, 0xf923fbd1, 0x1b489d4d, 0x1253eb5e, 0x1253eb5e, }, 45 }, - { "cmdline_cat", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x6ff92a98, 0x6ff92a98, 0xbd8264b3, 0xbd8264b3, 0x5c50282c, 0x5c50282c, 0xd18d6a5a, 0xd18d6a5a, 0x99cea139, 0x99cea139, 0x2590c545, 0x2590c545, 0x55c86045, 0x55c86045, 0xad53ef1e, 0xad53ef1e, 0x5b44a23a, 0x5b44a23a, 0xa255f863, 0xa255f863, 0x85b0bdca, 0x85b0bdca, 0x4220ee1f, 0x4220ee1f, 0xeb991a9f, 0xeb991a9f, 0x86f366dd, 0x86f366dd, 0xfa176b7d, 0xfa176b7d, 0xd7384ca9, 0xd7384ca9, 0xceebf5c1, 0xceebf5c1, 0xae62b268, 0xae62b268, 0x6e89bbd6, 0x6e89bbd6, 0x3fe07c8e, 0x3fe07c8e, 0xee5358fe, 0x162d1a8a, 0x876f8d10, 0x876f8d10, }, 45 }, - { "cmdline_cat", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0xb96afaea, 0xb96afaea, 0xaa16ab1e, 0xaa16ab1e, 0x51ff382, 0x51ff382, 0xec74f127, 0xec74f127, 0xde4bca99, 0xde4bca99, 0x8ef3e8a5, 0x8ef3e8a5, 0x2daeb0b4, 0x2daeb0b4, 0x7cf5e243, 0x7cf5e243, 0x11fd57c6, 0x11fd57c6, 0x140723af, 0x140723af, 0x2bd93833, 0x2bd93833, 0xd731f4ac, 0xd731f4ac, 0x5fcd7114, 0x5fcd7114, 0xd1fea24a, 0xd1fea24a, 0x4083d53a, 0x4083d53a, 0x2e372605, 0x2e372605, 0x8e6316a7, 0x8e6316a7, 0x283ef6cc, 0x283ef6cc, 0x20cee9de, 0x20cee9de, 0xad6fa187, 0xad6fa187, 0xd691f438, 0xf3257e63, 0x4786ba7, 0x4786ba7, }, 45 }, - { "cmdline_cat", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x48acf1bf, 0x48acf1bf, 0xb8777469, 0xb8777469, 0xad2fad44, 0xad2fad44, 0xa415ac59, 0xa415ac59, 0x5a7bfb26, 0x5a7bfb26, 0xccb6016, 0xccb6016, 0x77a80cb3, 0x77a80cb3, 0x2034c102, 0x2034c102, 0x444b4ccd, 0x444b4ccd, 0xe6c31bea, 0xe6c31bea, 0x8408036e, 0x8408036e, 0x9e7c556f, 0x9e7c556f, 0x445dc388, 0x445dc388, 0x94b3f850, 0x94b3f850, 0xf6f15341, 0xf6f15341, 0xcb939b5f, 0xcb939b5f, 0xbe88067d, 0xbe88067d, 0x1efc4734, 0x1efc4734, 0x7f5dfca8, 0x7f5dfca8, 0xb7b10eb9, 0xb7b10eb9, 0xb94cb441, 0x9571329, 0x8a26912b, 0x8a26912b, }, 45 }, - { "cmdline_cat", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xc508d04e, 0xc508d04e, 0x6dbccbfe, 0x6dbccbfe, 0xbf06ff60, 0xbf06ff60, 0xbc5ab06, 0xbc5ab06, 0x97eeab3c, 0x97eeab3c, 0x62663589, 0x62663589, 0xb03e21e2, 0xb03e21e2, 0xea196bb6, 0xea196bb6, 0x672c16c4, 0x672c16c4, 0xefbca2cd, 0xefbca2cd, 0x1af5b410, 0x1af5b410, 0xc7a80569, 0xc7a80569, 0x4926a16, 0x4926a16, 0xee29c99c, 0xee29c99c, 0xffb15985, 0xffb15985, 0x4f608e46, 0x4f608e46, 0x3e450fd2, 0x3e450fd2, 0xac45215f, 0xac45215f, 0x789b0ce7, 0x789b0ce7, 0x4cedfe22, 0x4cedfe22, 0xa005588c, 0x701da05c, 0x6f25cec1, 0x6f25cec1, }, 45 }, - { "cmdline_cat", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x29e7a7f, 0x29e7a7f, 0xbd221052, 0xbd221052, 0x3b18b64, 0x3b18b64, 0x7f1e8462, 0x7f1e8462, 0xf28d5124, 0xf28d5124, 0xc336f170, 0xc336f170, 0xfe3bf988, 0xfe3bf988, 0x7bf89e05, 0x7bf89e05, 0x7857a3f8, 0x7857a3f8, 0x272c1a36, 0x272c1a36, 0xe8adb445, 0xe8adb445, 0x70cfe280, 0x70cfe280, 0x4f2b6120, 0x4f2b6120, 0xbaf5caa5, 0xbaf5caa5, 0x4b6bcab2, 0x4b6bcab2, 0x2bef7b92, 0x2bef7b92, 0x17b381dc, 0x17b381dc, 0x884c9c35, 0x884c9c35, 0x2f9eb909, 0x2f9eb909, 0xa811b3af, 0xa811b3af, 0x4c39478f, 0x5a72c3ab, 0x8071678a, 0x8071678a, }, 45 }, - { "gfxterm_menu", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xd9f04953, 0xbf3fa5d0, 0xd9f04953, 0x9a068414, 0x59c36f00, 0x59c36f00, 0x620c0067, 0x620c0067, 0x620c0067, 0x1c8c6d01, 0x1c8c6d01, 0x1c8c6d01, 0xc3269013, 0xc3269013, 0xc3269013, 0x59c36f00, 0x9a068414, 0x9a068414, 0x59c36f00, }, 20 }, - { "gfxterm_menu", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x9254157f, 0x367e92c7, 0x9254157f, 0xbc519000, 0xaa4593fe, 0xaa4593fe, 0xa8a596c8, 0xa8a596c8, 0xa8a596c8, 0xe509baf, 0xe509baf, 0xe509baf, 0x16f0dc06, 0x16f0dc06, 0x16f0dc06, 0xaa4593fe, 0xbc519000, 0xbc519000, 0xaa4593fe, }, 20 }, - { "gfxterm_menu", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x354b1976, 0x8fc746ae, 0x354b1976, 0x685c74f2, 0xc9cbf769, 0xc9cbf769, 0x3ce35e1d, 0x3ce35e1d, 0x3ce35e1d, 0xc23b9fd1, 0xc23b9fd1, 0xc23b9fd1, 0x5b18528e, 0x5b18528e, 0x5b18528e, 0xc9cbf769, 0x685c74f2, 0x685c74f2, 0xc9cbf769, }, 20 }, - { "gfxterm_menu", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x1c9ec014, 0xaf3ec923, 0x1c9ec014, 0x43f5296, 0x9813a416, 0x9813a416, 0x43fda3fa, 0x43fda3fa, 0x43fda3fa, 0xd22625c9, 0xd22625c9, 0xd22625c9, 0x76a62c0a, 0x76a62c0a, 0x76a62c0a, 0x9813a416, 0x43f5296, 0x43f5296, 0x9813a416, }, 20 }, - { "gfxterm_menu", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xa704f7ea, 0xb7f2ec8b, 0xa704f7ea, 0xb279bf59, 0x5fcf013d, 0x5fcf013d, 0xf3582c48, 0xf3582c48, 0xf3582c48, 0x2148343e, 0x2148343e, 0x2148343e, 0x9c719024, 0x9c719024, 0x9c719024, 0x5fcf013d, 0xb279bf59, 0xb279bf59, 0x5fcf013d, }, 20 }, - { "gfxterm_menu", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xf293ce36, 0xa6eb6ae8, 0xf293ce36, 0xcd87647e, 0xdd28f52b, 0xdd28f52b, 0xb3c7ef80, 0xb3c7ef80, 0xb3c7ef80, 0x92fb1664, 0x92fb1664, 0x92fb1664, 0xd15b5e2e, 0xd15b5e2e, 0xd15b5e2e, 0xdd28f52b, 0xcd87647e, 0xcd87647e, 0xdd28f52b, }, 20 }, - { "gfxterm_menu", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x31e75bd7, 0x9a768c6a, 0x31e75bd7, 0xa8fc31a6, 0x43d1f34, 0x43d1f34, 0xa0717008, 0xa0717008, 0xa0717008, 0xdf7bd9a0, 0xdf7bd9a0, 0xdf7bd9a0, 0x8e5a9312, 0x8e5a9312, 0x8e5a9312, 0x43d1f34, 0xa8fc31a6, 0xa8fc31a6, 0x43d1f34, }, 20 }, - { "gfxmenu", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x1ce7bd78, 0x682580f5, 0x1ce7bd78, 0x490ad6fe, 0x9a2e0d26, 0x64eb71ba, 0x64eb71ba, 0x64eb71ba, 0x3833877a, 0x3833877a, 0x3833877a, 0xcfc14f0a, 0xcfc14f0a, 0xcfc14f0a, 0x59c36f00, 0x490ad6fe, 0x490ad6fe, }, 18 }, - { "gfxmenu", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x2b6ff87d, 0x63ce2ca2, 0x2b6ff87d, 0xf00f044e, 0xa9d58ccd, 0xe2c46577, 0xe2c46577, 0xe2c46577, 0xb79bcf7d, 0xb79bcf7d, 0xb79bcf7d, 0xbc30ed71, 0xbc30ed71, 0xbc30ed71, 0xaa4593fe, 0xf00f044e, 0xf00f044e, }, 18 }, - { "gfxmenu", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xe61cadba, 0x9880b727, 0xe61cadba, 0xdf5f2fc0, 0x5411be8b, 0x4449774e, 0x4449774e, 0x4449774e, 0x3bf7d1da, 0x3bf7d1da, 0x3bf7d1da, 0xd2ddee01, 0xd2ddee01, 0xd2ddee01, 0xc9cbf769, 0xdf5f2fc0, 0xdf5f2fc0, }, 18 }, - { "gfxmenu", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x1c3742c9, 0xbe54acf7, 0x9b4ce770, 0xbe54acf7, 0x3111489, 0x740d78cf, 0x314c4c59, 0x314c4c59, 0x314c4c59, 0xdae9a625, 0xdae9a625, 0xdae9a625, 0xcbf8af57, 0xcbf8af57, 0xcbf8af57, 0x1c3742c9, 0x3111489, 0x3111489, }, 18 }, - { "gfxmenu", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0xcc5a7bed, 0xee571de5, 0x568aaeff, 0xee571de5, 0xe328b7a7, 0xbcda144c, 0xf56e1b60, 0xf56e1b60, 0xf56e1b60, 0x9a27c771, 0x9a27c771, 0x9a27c771, 0xd6d05397, 0xd6d05397, 0xd6d05397, 0xcc5a7bed, 0xe328b7a7, 0xe328b7a7, }, 18 }, - { "gfxmenu", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xef4a3312, 0x1db9877c, 0x7e1afeae, 0x1db9877c, 0x8fc0c430, 0x5d55a141, 0x96f335c6, 0x96f335c6, 0x96f335c6, 0x504171d8, 0x504171d8, 0x504171d8, 0x69f71c0, 0x69f71c0, 0x69f71c0, 0xef4a3312, 0x8fc0c430, 0x8fc0c430, }, 18 }, - { "gfxmenu", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x54e48d80, 0x151819bd, 0xea8d4865, 0x151819bd, 0x11d75fd2, 0x6d6bb4bc, 0x650ccd09, 0x650ccd09, 0x650ccd09, 0xe4ff3bd8, 0xe4ff3bd8, 0xe4ff3bd8, 0xc5308b73, 0xc5308b73, 0xc5308b73, 0x54e48d80, 0x11d75fd2, 0x11d75fd2, }, 18 }, - { "gfxterm_ar", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xd0b06c3d, 0xde50d1a5, 0xd0b06c3d, 0x9346a17a, 0x59c36f00, 0x59c36f00, 0xacff5d47, 0xacff5d47, 0xacff5d47, 0xd27f3021, 0xd27f3021, 0xd27f3021, 0xdd5cd33, 0xdd5cd33, 0xdd5cd33, 0x59c36f00, 0x9346a17a, 0x9346a17a, 0x59c36f00, }, 20 }, - { "gfxterm_ar", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xf32d50c1, 0x730a7ed, 0xf32d50c1, 0xdd28d5be, 0xaa4593fe, 0xaa4593fe, 0xba8a2d4c, 0xba8a2d4c, 0xba8a2d4c, 0x1c7f202b, 0x1c7f202b, 0x1c7f202b, 0x4df6782, 0x4df6782, 0x4df6782, 0xaa4593fe, 0xdd28d5be, 0xdd28d5be, 0xaa4593fe, }, 20 }, - { "gfxterm_ar", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x711a4ac1, 0x6396f14c, 0x711a4ac1, 0x2c0d2745, 0xc9cbf769, 0xc9cbf769, 0x6b6ccbb0, 0x6b6ccbb0, 0x6b6ccbb0, 0x95b40a7c, 0x95b40a7c, 0x95b40a7c, 0xc97c723, 0xc97c723, 0xc97c723, 0xc9cbf769, 0x2c0d2745, 0x2c0d2745, 0xc9cbf769, }, 20 }, - { "gfxterm_ar", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x29baad6a, 0x348b1f2b, 0x29baad6a, 0x311b3fe8, 0x9813a416, 0x9813a416, 0xe8e982cc, 0xe8e982cc, 0xe8e982cc, 0x793204ff, 0x793204ff, 0x793204ff, 0xddb20d3c, 0xddb20d3c, 0xddb20d3c, 0x9813a416, 0x311b3fe8, 0x311b3fe8, 0x9813a416, }, 20 }, - { "gfxterm_ar", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xf834b3bb, 0x3951bd1a, 0xf834b3bb, 0xed49fb08, 0x5fcf013d, 0x5fcf013d, 0x5aefa2a7, 0x5aefa2a7, 0x5aefa2a7, 0x88ffbad1, 0x88ffbad1, 0x88ffbad1, 0x35c61ecb, 0x35c61ecb, 0x35c61ecb, 0x5fcf013d, 0xed49fb08, 0xed49fb08, 0x5fcf013d, }, 20 }, - { "gfxterm_ar", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x7e9a7a47, 0xb1651b5a, 0x7e9a7a47, 0x418ed00f, 0xdd28f52b, 0xdd28f52b, 0x83f9db69, 0x83f9db69, 0x83f9db69, 0xa2c5228d, 0xa2c5228d, 0xa2c5228d, 0xe1656ac7, 0xe1656ac7, 0xe1656ac7, 0xdd28f52b, 0x418ed00f, 0x418ed00f, 0xdd28f52b, }, 20 }, - { "gfxterm_ar", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xc6a0340, 0x7dd5855c, 0xc6a0340, 0x95716931, 0x43d1f34, 0x43d1f34, 0x5f1c24c0, 0x5f1c24c0, 0x5f1c24c0, 0x20168d68, 0x20168d68, 0x20168d68, 0x7137c7da, 0x7137c7da, 0x7137c7da, 0x43d1f34, 0x95716931, 0x95716931, 0x43d1f34, }, 20 }, - { "gfxterm_cyr", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xd3798aaa, 0xab48784c, 0xd3798aaa, 0x908f47ed, 0x59c36f00, 0x59c36f00, 0x1688ec7c, 0x1688ec7c, 0x1688ec7c, 0x6808811a, 0x6808811a, 0x6808811a, 0xb7a27c08, 0xb7a27c08, 0xb7a27c08, 0x59c36f00, 0x908f47ed, 0x908f47ed, 0x59c36f00, }, 20 }, - { "gfxterm_cyr", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xc30d9d2a, 0x60b9ed26, 0xc30d9d2a, 0xed081855, 0xaa4593fe, 0xaa4593fe, 0x3eba2192, 0x3eba2192, 0x3eba2192, 0x984f2cf5, 0x984f2cf5, 0x984f2cf5, 0x80ef6b5c, 0x80ef6b5c, 0x80ef6b5c, 0xaa4593fe, 0xed081855, 0xed081855, 0xaa4593fe, }, 20 }, - { "gfxterm_cyr", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xe469e6af, 0x46ac2012, 0xe469e6af, 0xb97e8b2b, 0xc9cbf769, 0xc9cbf769, 0x60f0d993, 0x60f0d993, 0x60f0d993, 0x9e28185f, 0x9e28185f, 0x9e28185f, 0x70bd500, 0x70bd500, 0x70bd500, 0xc9cbf769, 0xb97e8b2b, 0xb97e8b2b, 0xc9cbf769, }, 20 }, - { "gfxterm_cyr", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x8538d2ef, 0xab143284, 0x8538d2ef, 0x9d99406d, 0x9813a416, 0x9813a416, 0x7e8326ec, 0x7e8326ec, 0x7e8326ec, 0xef58a0df, 0xef58a0df, 0xef58a0df, 0x4bd8a91c, 0x4bd8a91c, 0x4bd8a91c, 0x9813a416, 0x9d99406d, 0x9d99406d, 0x9813a416, }, 20 }, - { "gfxterm_cyr", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x8115198c, 0x1abdaee1, 0x8115198c, 0x9468513f, 0x5fcf013d, 0x5fcf013d, 0xa5e86484, 0xa5e86484, 0xa5e86484, 0x77f87cf2, 0x77f87cf2, 0x77f87cf2, 0xcac1d8e8, 0xcac1d8e8, 0xcac1d8e8, 0x5fcf013d, 0x9468513f, 0x9468513f, 0x5fcf013d, }, 20 }, - { "gfxterm_cyr", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xea03b805, 0x74148290, 0xea03b805, 0xd517124d, 0xdd28f52b, 0xdd28f52b, 0x8f6eee40, 0x8f6eee40, 0x8f6eee40, 0xae5217a4, 0xae5217a4, 0xae5217a4, 0xedf25fee, 0xedf25fee, 0xedf25fee, 0xdd28f52b, 0xd517124d, 0xd517124d, 0xdd28f52b, }, 20 }, - { "gfxterm_cyr", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xa044490f, 0xe23458db, 0xa044490f, 0x395f237e, 0x43d1f34, 0x43d1f34, 0xe1ca82c2, 0xe1ca82c2, 0xe1ca82c2, 0x9ec02b6a, 0x9ec02b6a, 0x9ec02b6a, 0xcfe161d8, 0xcfe161d8, 0xcfe161d8, 0x43d1f34, 0x395f237e, 0x395f237e, 0x43d1f34, }, 20 }, - { "gfxterm_heb", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xf3259b30, 0xf1f01411, 0xf3259b30, 0xb0d35677, 0x59c36f00, 0x59c36f00, 0x97895f8e, 0x97895f8e, 0x97895f8e, 0xe90932e8, 0xe90932e8, 0xe90932e8, 0x36a3cffa, 0x36a3cffa, 0x36a3cffa, 0x59c36f00, 0xb0d35677, 0xb0d35677, 0x59c36f00, }, 20 }, - { "gfxterm_heb", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x53a43759, 0xe0f26bfa, 0x53a43759, 0x7da1b226, 0xaa4593fe, 0xaa4593fe, 0xbf482a4e, 0xbf482a4e, 0xbf482a4e, 0x19bd2729, 0x19bd2729, 0x19bd2729, 0x11d6080, 0x11d6080, 0x11d6080, 0xaa4593fe, 0x7da1b226, 0x7da1b226, 0xaa4593fe, }, 20 }, - { "gfxterm_heb", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xd7ff8d53, 0x665b2728, 0xd7ff8d53, 0x8ae8e0d7, 0xc9cbf769, 0xc9cbf769, 0x5a693e73, 0x5a693e73, 0x5a693e73, 0xa4b1ffbf, 0xa4b1ffbf, 0xa4b1ffbf, 0x3d9232e0, 0x3d9232e0, 0x3d9232e0, 0xc9cbf769, 0x8ae8e0d7, 0x8ae8e0d7, 0xc9cbf769, }, 20 }, - { "gfxterm_heb", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x99fddcbe, 0x6d5c8895, 0x99fddcbe, 0x815c4e3c, 0x9813a416, 0x9813a416, 0x9bcf9821, 0x9bcf9821, 0x9bcf9821, 0xa141e12, 0xa141e12, 0xa141e12, 0xae9417d1, 0xae9417d1, 0xae9417d1, 0x9813a416, 0x815c4e3c, 0x815c4e3c, 0x9813a416, }, 20 }, - { "gfxterm_heb", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x5797846, 0x25a6ad40, 0x5797846, 0x100430f5, 0x5fcf013d, 0x5fcf013d, 0xddc86daf, 0xddc86daf, 0xddc86daf, 0xfd875d9, 0xfd875d9, 0xfd875d9, 0xb2e1d1c3, 0xb2e1d1c3, 0xb2e1d1c3, 0x5fcf013d, 0x100430f5, 0x100430f5, 0x5fcf013d, }, 20 }, - { "gfxterm_heb", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x30653ae8, 0x7fcd187, 0x30653ae8, 0xf7190a0, 0xdd28f52b, 0xdd28f52b, 0x24c3d325, 0x24c3d325, 0x24c3d325, 0x5ff2ac1, 0x5ff2ac1, 0x5ff2ac1, 0x465f628b, 0x465f628b, 0x465f628b, 0xdd28f52b, 0xf7190a0, 0xf7190a0, 0xdd28f52b, }, 20 }, - { "gfxterm_heb", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x3bd91638, 0x1d74dd4a, 0x3bd91638, 0xa2c27c49, 0x43d1f34, 0x43d1f34, 0x53d1ad3d, 0x53d1ad3d, 0x53d1ad3d, 0x2cdb0495, 0x2cdb0495, 0x2cdb0495, 0x7dfa4e27, 0x7dfa4e27, 0x7dfa4e27, 0x43d1f34, 0xa2c27c49, 0xa2c27c49, 0x43d1f34, }, 20 }, - { "gfxterm_gre", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xbe2c351a, 0x2692720, 0xbe2c351a, 0xfddaf85d, 0x59c36f00, 0x59c36f00, 0x1b2e2301, 0x1b2e2301, 0x1b2e2301, 0x65ae4e67, 0x65ae4e67, 0x65ae4e67, 0xba04b375, 0xba04b375, 0xba04b375, 0x59c36f00, 0xfddaf85d, 0xfddaf85d, 0x59c36f00, }, 20 }, - { "gfxterm_gre", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x1eca82e1, 0xe8fa59cc, 0x1eca82e1, 0x30cf079e, 0xaa4593fe, 0xaa4593fe, 0xaf27ddc5, 0xaf27ddc5, 0xaf27ddc5, 0x9d2d0a2, 0x9d2d0a2, 0x9d2d0a2, 0x1172970b, 0x1172970b, 0x1172970b, 0xaa4593fe, 0x30cf079e, 0x30cf079e, 0xaa4593fe, }, 20 }, - { "gfxterm_gre", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xa9ccd435, 0x1ac646eb, 0xa9ccd435, 0xf4dbb9b1, 0xc9cbf769, 0xc9cbf769, 0x86d69aa0, 0x86d69aa0, 0x86d69aa0, 0x780e5b6c, 0x780e5b6c, 0x780e5b6c, 0xe12d9633, 0xe12d9633, 0xe12d9633, 0xc9cbf769, 0xf4dbb9b1, 0xf4dbb9b1, 0xc9cbf769, }, 20 }, - { "gfxterm_gre", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0xf96d568, 0x7ad05c1b, 0xf96d568, 0x173747ea, 0x9813a416, 0x9813a416, 0xacf9792a, 0xacf9792a, 0xacf9792a, 0x3d22ff19, 0x3d22ff19, 0x3d22ff19, 0x99a2f6da, 0x99a2f6da, 0x99a2f6da, 0x9813a416, 0x173747ea, 0x173747ea, 0x9813a416, }, 20 }, - { "gfxterm_gre", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xa0dc6b9c, 0xc2761148, 0xa0dc6b9c, 0xb5a1232f, 0x5fcf013d, 0x5fcf013d, 0x4e05748b, 0x4e05748b, 0x4e05748b, 0x9c156cfd, 0x9c156cfd, 0x9c156cfd, 0x212cc8e7, 0x212cc8e7, 0x212cc8e7, 0x5fcf013d, 0xb5a1232f, 0xb5a1232f, 0x5fcf013d, }, 20 }, - { "gfxterm_gre", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xcd722f7d, 0xe4df8d6b, 0xcd722f7d, 0xf2668535, 0xdd28f52b, 0xdd28f52b, 0xbdbb8019, 0xbdbb8019, 0xbdbb8019, 0x9c8779fd, 0x9c8779fd, 0x9c8779fd, 0xdf2731b7, 0xdf2731b7, 0xdf2731b7, 0xdd28f52b, 0xf2668535, 0xf2668535, 0xdd28f52b, }, 20 }, - { "gfxterm_gre", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xa6c99d2f, 0x1de04317, 0xa6c99d2f, 0x3fd2f75e, 0x43d1f34, 0x43d1f34, 0x3f85b7d3, 0x3f85b7d3, 0x3f85b7d3, 0x408f1e7b, 0x408f1e7b, 0x408f1e7b, 0x11ae54c9, 0x11ae54c9, 0x11ae54c9, 0x43d1f34, 0x3fd2f75e, 0x3fd2f75e, 0x43d1f34, }, 20 }, - { "gfxterm_ru", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x1e35b709, 0x2683bf92, 0x1e35b709, 0x5dc37a4e, 0x59c36f00, 0x59c36f00, 0xd697967f, 0xd697967f, 0xd697967f, 0xa817fb19, 0xa817fb19, 0xa817fb19, 0x77bd060b, 0x77bd060b, 0x77bd060b, 0x59c36f00, 0x5dc37a4e, 0x5dc37a4e, 0x59c36f00, }, 20 }, - { "gfxterm_ru", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x53ff7735, 0x8cbf197c, 0x53ff7735, 0x7dfaf24a, 0xaa4593fe, 0xaa4593fe, 0x389a922, 0x389a922, 0x389a922, 0xa57ca445, 0xa57ca445, 0xa57ca445, 0xbddce3ec, 0xbddce3ec, 0xbddce3ec, 0xaa4593fe, 0x7dfaf24a, 0x7dfaf24a, 0xaa4593fe, }, 20 }, - { "gfxterm_ru", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x5217c47d, 0x7c8ae63e, 0x5217c47d, 0xf00a9f9, 0xc9cbf769, 0xc9cbf769, 0x3995409, 0x3995409, 0x3995409, 0xfd4195c5, 0xfd4195c5, 0xfd4195c5, 0x6462589a, 0x6462589a, 0x6462589a, 0xc9cbf769, 0xf00a9f9, 0xf00a9f9, 0xc9cbf769, }, 20 }, - { "gfxterm_ru", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x45b67706, 0x375fb5db, 0x45b67706, 0x5d17e584, 0x9813a416, 0x9813a416, 0x8195719b, 0x8195719b, 0x8195719b, 0x104ef7a8, 0x104ef7a8, 0x104ef7a8, 0xb4cefe6b, 0xb4cefe6b, 0xb4cefe6b, 0x9813a416, 0x5d17e584, 0x5d17e584, 0x9813a416, }, 20 }, - { "gfxterm_ru", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xfc209a25, 0xd5c20779, 0xfc209a25, 0xe95dd296, 0x5fcf013d, 0x5fcf013d, 0xe5699efe, 0xe5699efe, 0xe5699efe, 0x37798688, 0x37798688, 0x37798688, 0x8a402292, 0x8a402292, 0x8a402292, 0x5fcf013d, 0xe95dd296, 0xe95dd296, 0x5fcf013d, }, 20 }, - { "gfxterm_ru", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x77f956f0, 0xfb0cc079, 0x77f956f0, 0x48edfcb8, 0xdd28f52b, 0xdd28f52b, 0xd51b1dc9, 0xd51b1dc9, 0xd51b1dc9, 0xf427e42d, 0xf427e42d, 0xf427e42d, 0xb787ac67, 0xb787ac67, 0xb787ac67, 0xdd28f52b, 0x48edfcb8, 0x48edfcb8, 0xdd28f52b, }, 20 }, - { "gfxterm_ru", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x1d9ac82a, 0xa254aa53, 0x1d9ac82a, 0x8481a25b, 0x43d1f34, 0x43d1f34, 0xc304df68, 0xc304df68, 0xc304df68, 0xbc0e76c0, 0xbc0e76c0, 0xbc0e76c0, 0xed2f3c72, 0xed2f3c72, 0xed2f3c72, 0x43d1f34, 0x8481a25b, 0x8481a25b, 0x43d1f34, }, 20 }, - { "gfxterm_fr", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xa6239a89, 0x8dc4bfbb, 0xa6239a89, 0xe5d557ce, 0x59c36f00, 0x59c36f00, 0x244cf807, 0x244cf807, 0x244cf807, 0x5acc9561, 0x5acc9561, 0x5acc9561, 0x85666873, 0x85666873, 0x85666873, 0x59c36f00, 0xe5d557ce, 0xe5d557ce, 0x59c36f00, }, 20 }, - { "gfxterm_fr", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x742cede9, 0x83bb7a50, 0x742cede9, 0x5a296896, 0xaa4593fe, 0xaa4593fe, 0xd83f8aeb, 0xd83f8aeb, 0xd83f8aeb, 0x7eca878c, 0x7eca878c, 0x7eca878c, 0x666ac025, 0x666ac025, 0x666ac025, 0xaa4593fe, 0x5a296896, 0x5a296896, 0xaa4593fe, }, 20 }, - { "gfxterm_fr", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xe20a98b0, 0x7e8cedef, 0xe20a98b0, 0xbf1df534, 0xc9cbf769, 0xc9cbf769, 0x2748b88c, 0x2748b88c, 0x2748b88c, 0xd9907940, 0xd9907940, 0xd9907940, 0x40b3b41f, 0x40b3b41f, 0x40b3b41f, 0xc9cbf769, 0xbf1df534, 0xbf1df534, 0xc9cbf769, }, 20 }, - { "gfxterm_fr", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x8f911ca4, 0xcbf1d895, 0x8f911ca4, 0x97308e26, 0x9813a416, 0x9813a416, 0x5b359bf4, 0x5b359bf4, 0x5b359bf4, 0xcaee1dc7, 0xcaee1dc7, 0xcaee1dc7, 0x6e6e1404, 0x6e6e1404, 0x6e6e1404, 0x9813a416, 0x97308e26, 0x97308e26, 0x9813a416, }, 20 }, - { "gfxterm_fr", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x1bf82c82, 0xc7b39627, 0x1bf82c82, 0xe856431, 0x5fcf013d, 0x5fcf013d, 0xa9dbae99, 0xa9dbae99, 0xa9dbae99, 0x7bcbb6ef, 0x7bcbb6ef, 0x7bcbb6ef, 0xc6f212f5, 0xc6f212f5, 0xc6f212f5, 0x5fcf013d, 0xe856431, 0xe856431, 0x5fcf013d, }, 20 }, - { "gfxterm_fr", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xfae19a5c, 0xd1e8fabb, 0xfae19a5c, 0xc5f53014, 0xdd28f52b, 0xdd28f52b, 0xfa2c5565, 0xfa2c5565, 0xfa2c5565, 0xdb10ac81, 0xdb10ac81, 0xdb10ac81, 0x98b0e4cb, 0x98b0e4cb, 0x98b0e4cb, 0xdd28f52b, 0xc5f53014, 0xc5f53014, 0xdd28f52b, }, 20 }, - { "gfxterm_fr", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x9a18f7bc, 0x5fcecc43, 0x9a18f7bc, 0x3039dcd, 0x43d1f34, 0x43d1f34, 0x287a2b96, 0x287a2b96, 0x287a2b96, 0x5770823e, 0x5770823e, 0x5770823e, 0x651c88c, 0x651c88c, 0x651c88c, 0x43d1f34, 0x3039dcd, 0x3039dcd, 0x43d1f34, }, 20 }, - { "gfxterm_quot", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x65112dfc, 0x3dec17f, 0x65112dfc, 0x26e7e0bb, 0x59c36f00, 0x59c36f00, 0x620c0067, 0x620c0067, 0x620c0067, 0x1c8c6d01, 0x1c8c6d01, 0x1c8c6d01, 0xc3269013, 0xc3269013, 0xc3269013, 0x59c36f00, 0x26e7e0bb, 0x26e7e0bb, 0x59c36f00, }, 20 }, - { "gfxterm_quot", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x2b3430fb, 0x8f1eb743, 0x2b3430fb, 0x531b584, 0xaa4593fe, 0xaa4593fe, 0xa8a596c8, 0xa8a596c8, 0xa8a596c8, 0xe509baf, 0xe509baf, 0xe509baf, 0x16f0dc06, 0x16f0dc06, 0x16f0dc06, 0xaa4593fe, 0x531b584, 0x531b584, 0xaa4593fe, }, 20 }, - { "gfxterm_quot", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xb523e920, 0xfafb6f8, 0xb523e920, 0xe83484a4, 0xc9cbf769, 0xc9cbf769, 0x3ce35e1d, 0x3ce35e1d, 0x3ce35e1d, 0xc23b9fd1, 0xc23b9fd1, 0xc23b9fd1, 0x5b18528e, 0x5b18528e, 0x5b18528e, 0xc9cbf769, 0xe83484a4, 0xe83484a4, 0xc9cbf769, }, 20 }, - { "gfxterm_quot", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0xa9bf7336, 0x1a1f7a01, 0xa9bf7336, 0xb11ee1b4, 0x9813a416, 0x9813a416, 0x43fda3fa, 0x43fda3fa, 0x43fda3fa, 0xd22625c9, 0xd22625c9, 0xd22625c9, 0x76a62c0a, 0x76a62c0a, 0x76a62c0a, 0x9813a416, 0xb11ee1b4, 0xb11ee1b4, 0x9813a416, }, 20 }, - { "gfxterm_quot", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xe5271912, 0xf5d10273, 0xe5271912, 0xf05a51a1, 0x5fcf013d, 0x5fcf013d, 0xf3582c48, 0xf3582c48, 0xf3582c48, 0x2148343e, 0x2148343e, 0x2148343e, 0x9c719024, 0x9c719024, 0x9c719024, 0x5fcf013d, 0xf05a51a1, 0xf05a51a1, 0x5fcf013d, }, 20 }, - { "gfxterm_quot", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x66a34f49, 0x32dbeb97, 0x66a34f49, 0x59b7e501, 0xdd28f52b, 0xdd28f52b, 0xb3c7ef80, 0xb3c7ef80, 0xb3c7ef80, 0x92fb1664, 0x92fb1664, 0x92fb1664, 0xd15b5e2e, 0xd15b5e2e, 0xd15b5e2e, 0xdd28f52b, 0x59b7e501, 0x59b7e501, 0xdd28f52b, }, 20 }, - { "gfxterm_quot", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x7c2f19da, 0xd7bece67, 0x7c2f19da, 0xe53473ab, 0x43d1f34, 0x43d1f34, 0xa0717008, 0xa0717008, 0xa0717008, 0xdf7bd9a0, 0xdf7bd9a0, 0xdf7bd9a0, 0x8e5a9312, 0x8e5a9312, 0x8e5a9312, 0x43d1f34, 0xe53473ab, 0xe53473ab, 0x43d1f34, }, 20 }, - { "gfxterm_piglatin", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x37943894, 0x78248c70, 0x37943894, 0x7462f5d3, 0x59c36f00, 0x59c36f00, 0xf4be229a, 0xf4be229a, 0xf4be229a, 0x8a3e4ffc, 0x8a3e4ffc, 0x8a3e4ffc, 0x5594b2ee, 0x5594b2ee, 0x5594b2ee, 0x59c36f00, 0x7462f5d3, 0x7462f5d3, 0x59c36f00, }, 20 }, - { "gfxterm_piglatin", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xd5158e6c, 0xdc71ba0f, 0xd5158e6c, 0xfb100b13, 0xaa4593fe, 0xaa4593fe, 0xd3ed72a3, 0xd3ed72a3, 0xd3ed72a3, 0x75187fc4, 0x75187fc4, 0x75187fc4, 0x6db8386d, 0x6db8386d, 0x6db8386d, 0xaa4593fe, 0xfb100b13, 0xfb100b13, 0xaa4593fe, }, 20 }, - { "gfxterm_piglatin", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x6277a9e6, 0xa3265ffb, 0x6277a9e6, 0x3f60c462, 0xc9cbf769, 0xc9cbf769, 0x2dcf8a8d, 0x2dcf8a8d, 0x2dcf8a8d, 0xd3174b41, 0xd3174b41, 0xd3174b41, 0x4a34861e, 0x4a34861e, 0x4a34861e, 0xc9cbf769, 0x3f60c462, 0x3f60c462, 0xc9cbf769, }, 20 }, - { "gfxterm_piglatin", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x81115dc4, 0xddf3f768, 0x81115dc4, 0x99b0cf46, 0x9813a416, 0x9813a416, 0x9b9d96df, 0x9b9d96df, 0x9b9d96df, 0xa4610ec, 0xa4610ec, 0xa4610ec, 0xaec6192f, 0xaec6192f, 0xaec6192f, 0x9813a416, 0x99b0cf46, 0x99b0cf46, 0x9813a416, }, 20 }, - { "gfxterm_piglatin", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x5e96a904, 0x27864d3d, 0x5e96a904, 0x4bebe1b7, 0x5fcf013d, 0x5fcf013d, 0x18cae7f4, 0x18cae7f4, 0x18cae7f4, 0xcadaff82, 0xcadaff82, 0xcadaff82, 0x77e35b98, 0x77e35b98, 0x77e35b98, 0x5fcf013d, 0x4bebe1b7, 0x4bebe1b7, 0x5fcf013d, }, 20 }, - { "gfxterm_piglatin", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xd00b19f8, 0xba73a9c6, 0xd00b19f8, 0xef1fb3b0, 0xdd28f52b, 0xdd28f52b, 0xb660046d, 0xb660046d, 0xb660046d, 0x975cfd89, 0x975cfd89, 0x975cfd89, 0xd4fcb5c3, 0xd4fcb5c3, 0xd4fcb5c3, 0xdd28f52b, 0xef1fb3b0, 0xef1fb3b0, 0xdd28f52b, }, 20 }, - { "gfxterm_piglatin", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x8b4b98cd, 0x78ddc6e4, 0x8b4b98cd, 0x1250f2bc, 0x43d1f34, 0x43d1f34, 0x4889d3fd, 0x4889d3fd, 0x4889d3fd, 0x37837a55, 0x37837a55, 0x37837a55, 0x66a230e7, 0x66a230e7, 0x66a230e7, 0x43d1f34, 0x1250f2bc, 0x1250f2bc, 0x43d1f34, }, 20 }, - { "gfxterm_ch", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xfecb570e, 0xccb97a7a, 0xfecb570e, 0xbd3d9a49, 0x59c36f00, 0x59c36f00, 0x40281258, 0x40281258, 0x40281258, 0x3ea87f3e, 0x3ea87f3e, 0x3ea87f3e, 0xe102822c, 0xe102822c, 0xe102822c, 0x59c36f00, 0xbd3d9a49, 0xbd3d9a49, 0x59c36f00, }, 20 }, - { "gfxterm_ch", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x897d1fac, 0xaa982529, 0x897d1fac, 0xa7789ad3, 0xaa4593fe, 0xaa4593fe, 0xa482510, 0xa482510, 0xa482510, 0xacbd2877, 0xacbd2877, 0xacbd2877, 0xb41d6fde, 0xb41d6fde, 0xb41d6fde, 0xaa4593fe, 0xa7789ad3, 0xa7789ad3, 0xaa4593fe, }, 20 }, - { "gfxterm_ch", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xd02a5297, 0xe627ab58, 0xd02a5297, 0x8d3d3f13, 0xc9cbf769, 0xc9cbf769, 0xbf0a8b7f, 0xbf0a8b7f, 0xbf0a8b7f, 0x41d24ab3, 0x41d24ab3, 0x41d24ab3, 0xd8f187ec, 0xd8f187ec, 0xd8f187ec, 0xc9cbf769, 0x8d3d3f13, 0x8d3d3f13, 0xc9cbf769, }, 20 }, - { "gfxterm_ch", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0xa653dcda, 0x3392e976, 0xa653dcda, 0xbef24e58, 0x9813a416, 0x9813a416, 0x4f2bc106, 0x4f2bc106, 0x4f2bc106, 0xdef04735, 0xdef04735, 0xdef04735, 0x7a704ef6, 0x7a704ef6, 0x7a704ef6, 0x9813a416, 0xbef24e58, 0xbef24e58, 0x9813a416, }, 20 }, - { "gfxterm_ch", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xe2d7b585, 0x35241f36, 0xe2d7b585, 0xf7aafd36, 0x5fcf013d, 0x5fcf013d, 0xf2bd04db, 0xf2bd04db, 0xf2bd04db, 0x20ad1cad, 0x20ad1cad, 0x20ad1cad, 0x9d94b8b7, 0x9d94b8b7, 0x9d94b8b7, 0x5fcf013d, 0xf7aafd36, 0xf7aafd36, 0x5fcf013d, }, 20 }, - { "gfxterm_ch", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x72ff749c, 0xeda8c283, 0x72ff749c, 0x4debded4, 0xdd28f52b, 0xdd28f52b, 0xb8c9cc22, 0xb8c9cc22, 0xb8c9cc22, 0x99f535c6, 0x99f535c6, 0x99f535c6, 0xda557d8c, 0xda557d8c, 0xda557d8c, 0xdd28f52b, 0x4debded4, 0x4debded4, 0xdd28f52b, }, 20 }, - { "gfxterm_ch", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xb7cac764, 0xeb4bf417, 0xb7cac764, 0x2ed1ad15, 0x43d1f34, 0x43d1f34, 0xce718801, 0xce718801, 0xce718801, 0xb17b21a9, 0xb17b21a9, 0xb17b21a9, 0xe05a6b1b, 0xe05a6b1b, 0xe05a6b1b, 0x43d1f34, 0x2ed1ad15, 0x2ed1ad15, 0x43d1f34, }, 20 }, - { "gfxterm_red", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x930e8e13, 0xf5c16290, 0x930e8e13, 0x27f5f1c0, 0x59c36f00, 0x59c36f00, 0xbad4e11, 0xbad4e11, 0xbad4e11, 0x752d2377, 0x752d2377, 0x752d2377, 0xaa87de65, 0xaa87de65, 0xaa87de65, 0x59c36f00, 0x27f5f1c0, 0x27f5f1c0, 0x59c36f00, }, 20 }, - { "gfxterm_red", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xff9301f2, 0x5bb9864a, 0xff9301f2, 0x31c145de, 0xaa4593fe, 0xaa4593fe, 0x23bf2c32, 0x23bf2c32, 0x23bf2c32, 0x854a2155, 0x854a2155, 0x854a2155, 0x9dea66fc, 0x9dea66fc, 0x9dea66fc, 0xaa4593fe, 0x31c145de, 0x31c145de, 0xaa4593fe, }, 20 }, - { "gfxterm_red", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xfc5938ef, 0x46d56737, 0xfc5938ef, 0x23cf2668, 0xc9cbf769, 0xc9cbf769, 0xa8c549aa, 0xa8c549aa, 0xa8c549aa, 0x561d8866, 0x561d8866, 0x561d8866, 0xcf3e4539, 0xcf3e4539, 0xcf3e4539, 0xc9cbf769, 0x23cf2668, 0x23cf2668, 0xc9cbf769, }, 20 }, - { "gfxterm_red", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0xe7160822, 0x54b60115, 0xe7160822, 0x168efa6f, 0x9813a416, 0x9813a416, 0xb774a5aa, 0xb774a5aa, 0xb774a5aa, 0x26af2399, 0x26af2399, 0x26af2399, 0x822f2a5a, 0x822f2a5a, 0x822f2a5a, 0x9813a416, 0x168efa6f, 0x168efa6f, 0x9813a416, }, 20 }, - { "gfxterm_red", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xf655f9b2, 0xe6a3e2d3, 0xf655f9b2, 0xd1d7405f, 0x5fcf013d, 0x5fcf013d, 0x2accaa08, 0x2accaa08, 0x2accaa08, 0xf8dcb27e, 0xf8dcb27e, 0xf8dcb27e, 0x45e51664, 0x45e51664, 0x45e51664, 0x5fcf013d, 0xd1d7405f, 0xd1d7405f, 0x5fcf013d, }, 20 }, - { "gfxterm_red", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x2d85ebdc, 0x79fd4f02, 0x2d85ebdc, 0xc48ae2b6, 0xdd28f52b, 0xdd28f52b, 0x76b28a95, 0x76b28a95, 0x76b28a95, 0x578e7371, 0x578e7371, 0x578e7371, 0x142e3b3b, 0x142e3b3b, 0x142e3b3b, 0xdd28f52b, 0xc48ae2b6, 0xc48ae2b6, 0xdd28f52b, }, 20 }, - { "gfxterm_red", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x29c00f98, 0x8251d825, 0x29c00f98, 0x35a750d1, 0x43d1f34, 0x43d1f34, 0x48b70bc8, 0x48b70bc8, 0x48b70bc8, 0x37bda260, 0x37bda260, 0x37bda260, 0x669ce8d2, 0x669ce8d2, 0x669ce8d2, 0x43d1f34, 0x35a750d1, 0x35a750d1, 0x43d1f34, }, 20 }, - { "gfxterm_high", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x4afab717, 0x2c355b94, 0x4afab717, 0x1166d9d0, 0x59c36f00, 0x59c36f00, 0x620c0067, 0x620c0067, 0x620c0067, 0x1c8c6d01, 0x1c8c6d01, 0x1c8c6d01, 0xc3269013, 0xc3269013, 0xc3269013, 0x59c36f00, 0x1166d9d0, 0x1166d9d0, 0x59c36f00, }, 20 }, - { "gfxterm_high", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xe3daadd4, 0x47f02a6c, 0xe3daadd4, 0x5ea9fb21, 0xaa4593fe, 0xaa4593fe, 0xa8a596c8, 0xa8a596c8, 0xa8a596c8, 0xe509baf, 0xe509baf, 0xe509baf, 0x16f0dc06, 0x16f0dc06, 0x16f0dc06, 0xaa4593fe, 0x5ea9fb21, 0x5ea9fb21, 0xaa4593fe, }, 20 }, - { "gfxterm_high", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xf140d1df, 0x4bcc8e07, 0xf140d1df, 0x7c962dcb, 0xc9cbf769, 0xc9cbf769, 0x3ce35e1d, 0x3ce35e1d, 0x3ce35e1d, 0xc23b9fd1, 0xc23b9fd1, 0xc23b9fd1, 0x5b18528e, 0x5b18528e, 0x5b18528e, 0xc9cbf769, 0x7c962dcb, 0x7c962dcb, 0xc9cbf769, }, 20 }, - { "gfxterm_high", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0xe709a12d, 0x54a9a81a, 0xe709a12d, 0xde04d65c, 0x9813a416, 0x9813a416, 0x43fda3fa, 0x43fda3fa, 0x43fda3fa, 0xd22625c9, 0xd22625c9, 0xd22625c9, 0x76a62c0a, 0x76a62c0a, 0x76a62c0a, 0x9813a416, 0xde04d65c, 0xde04d65c, 0x9813a416, }, 20 }, - { "gfxterm_high", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x65eff77c, 0x7519ec1d, 0x65eff77c, 0x1cd7d353, 0x5fcf013d, 0x5fcf013d, 0xf3582c48, 0xf3582c48, 0xf3582c48, 0x2148343e, 0x2148343e, 0x2148343e, 0x9c719024, 0x9c719024, 0x9c719024, 0x5fcf013d, 0x1cd7d353, 0x1cd7d353, 0x5fcf013d, }, 20 }, - { "gfxterm_high", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x7318831a, 0x276027c4, 0x7318831a, 0xd7e4f5bb, 0xdd28f52b, 0xdd28f52b, 0xb3c7ef80, 0xb3c7ef80, 0xb3c7ef80, 0x92fb1664, 0x92fb1664, 0x92fb1664, 0xd15b5e2e, 0xd15b5e2e, 0xd15b5e2e, 0xdd28f52b, 0xd7e4f5bb, 0xd7e4f5bb, 0xdd28f52b, }, 20 }, - { "gfxterm_high", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x6927a7d4, 0xc2b67069, 0x6927a7d4, 0xfc345163, 0x43d1f34, 0x43d1f34, 0xa0717008, 0xa0717008, 0xa0717008, 0xdf7bd9a0, 0xdf7bd9a0, 0xdf7bd9a0, 0x8e5a9312, 0x8e5a9312, 0x8e5a9312, 0x43d1f34, 0xfc345163, 0xfc345163, 0x43d1f34, }, 20 }, - { "videotest", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0xe6012f70, 0xe6012f70, 0xe6012f70, 0xe6012f70, 0xe6012f70, }, 5 }, - { "videotest", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xfb6be77b, 0xfb6be77b, 0xfb6be77b, 0xfb6be77b, 0xfb6be77b, }, 5 }, - { "videotest", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0x67c0629f, 0x67c0629f, 0x67c0629f, 0x67c0629f, 0x67c0629f, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x8f20afbb, 0xd8f7abc, 0x8f937344, 0xd3ca643, 0x8e471645, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0xdca764da, 0x9f76da9a, 0x5b04185a, 0x18d5a61a, 0xd60deb2b, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0x7b87af36, 0x7cb96093, 0x75fa307c, 0x72c4ffd9, 0x677c91a2, }, 5 }, - { "videotest", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x72981c65, 0x50120635, 0x378c28c5, 0x15063295, 0xf8b07525, }, 5 }, - { "videotest", 640, 480, 0x2, 256, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi256 */, (grub_uint32_t []) { 0xc8f64b58, 0xc8f64b58, 0xc8f64b58, 0xc8f64b58, 0xc8f64b58, }, 5 }, - { "videotest", 800, 600, 0x2, 256, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi256 */, (grub_uint32_t []) { 0x2b499dfa, 0x2b499dfa, 0x2b499dfa, 0x2b499dfa, 0x2b499dfa, }, 5 }, - { "videotest", 1024, 768, 0x2, 256, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi256 */, (grub_uint32_t []) { 0x6156b420, 0x6156b420, 0x6156b420, 0x6156b420, 0x6156b420, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 640x480xrgba5550 */, (grub_uint32_t []) { 0x363285ca, 0x363285ca, 0x363285ca, 0x363285ca, 0x363285ca, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 800x600xrgba5550 */, (grub_uint32_t []) { 0x25bb37f4, 0x25bb37f4, 0x25bb37f4, 0x25bb37f4, 0x25bb37f4, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 1024x768xrgba5550 */, (grub_uint32_t []) { 0xeeab9e91, 0xeeab9e91, 0xeeab9e91, 0xeeab9e91, 0xeeab9e91, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 16, 2, 11, 5, 5, 6, 0, 5, 0, 0 /* 640x480xrgba5650 */, (grub_uint32_t []) { 0x26a9a50b, 0x26a9a50b, 0x26a9a50b, 0x26a9a50b, 0x26a9a50b, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 16, 2, 11, 5, 5, 6, 0, 5, 0, 0 /* 800x600xrgba5650 */, (grub_uint32_t []) { 0x2c0f4fe7, 0x2c0f4fe7, 0x2c0f4fe7, 0x2c0f4fe7, 0x2c0f4fe7, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 16, 2, 11, 5, 5, 6, 0, 5, 0, 0 /* 1024x768xrgba5650 */, (grub_uint32_t []) { 0x46c11052, 0x46c11052, 0x46c11052, 0x46c11052, 0x46c11052, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 24, 3, 16, 8, 8, 8, 0, 8, 0, 0 /* 640x480xrgba8880 */, (grub_uint32_t []) { 0xe56cf615, 0xcd2be572, 0xb5e2d0db, 0x9da5c3bc, 0x4470bb89, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 24, 3, 16, 8, 8, 8, 0, 8, 0, 0 /* 800x600xrgba8880 */, (grub_uint32_t []) { 0x2a25b871, 0x4bf85361, 0xe99e6e51, 0x88438541, 0xa8be62c0, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 24, 3, 16, 8, 8, 8, 0, 8, 0, 0 /* 1024x768xrgba8880 */, (grub_uint32_t []) { 0x81523037, 0xd8c0bfd3, 0x32772fff, 0x6be5a01b, 0xe2f47956, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 15, 2, 0, 5, 5, 5, 10, 5, 0, 0 /* 640x480xbgra5550 */, (grub_uint32_t []) { 0x1833bb41, 0x1833bb41, 0x1833bb41, 0x1833bb41, 0x1833bb41, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 15, 2, 0, 5, 5, 5, 10, 5, 0, 0 /* 800x600xbgra5550 */, (grub_uint32_t []) { 0x2c39a0e8, 0x2c39a0e8, 0x2c39a0e8, 0x2c39a0e8, 0x2c39a0e8, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 15, 2, 0, 5, 5, 5, 10, 5, 0, 0 /* 1024x768xbgra5550 */, (grub_uint32_t []) { 0xf0d4c23, 0xf0d4c23, 0xf0d4c23, 0xf0d4c23, 0xf0d4c23, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 16, 2, 0, 5, 5, 6, 11, 5, 0, 0 /* 640x480xbgra5650 */, (grub_uint32_t []) { 0x456d063c, 0x456d063c, 0x456d063c, 0x456d063c, 0x456d063c, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 16, 2, 0, 5, 5, 6, 11, 5, 0, 0 /* 800x600xbgra5650 */, (grub_uint32_t []) { 0x47e15a2e, 0x47e15a2e, 0x47e15a2e, 0x47e15a2e, 0x47e15a2e, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 16, 2, 0, 5, 5, 6, 11, 5, 0, 0 /* 1024x768xbgra5650 */, (grub_uint32_t []) { 0x54d7300d, 0x54d7300d, 0x54d7300d, 0x54d7300d, 0x54d7300d, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 24, 3, 0, 8, 8, 8, 16, 8, 0, 0 /* 640x480xbgra8880 */, (grub_uint32_t []) { 0x770da211, 0x8ef2528e, 0x811e35de, 0x78e1c541, 0x9ec6fb7e, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 24, 3, 0, 8, 8, 8, 16, 8, 0, 0 /* 800x600xbgra8880 */, (grub_uint32_t []) { 0xeb181fbc, 0xae648cc1, 0x61e13946, 0x249daa3b, 0xfb0624b9, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 24, 3, 0, 8, 8, 8, 16, 8, 0, 0 /* 1024x768xbgra8880 */, (grub_uint32_t []) { 0x2b6f64dc, 0xc25f8431, 0xfce2d3f7, 0x15d2331a, 0x81987c7b, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 32, 4, 0, 8, 8, 8, 16, 8, 24, 8 /* 640x480xbgra8888 */, (grub_uint32_t []) { 0xa260f7dd, 0x3e2f4980, 0x9f13fd96, 0x35c43cb, 0xd886e34b, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 32, 4, 0, 8, 8, 8, 16, 8, 24, 8 /* 800x600xbgra8888 */, (grub_uint32_t []) { 0x41a9bff8, 0xa0d3f7c3, 0x86b1597f, 0x67cb1144, 0xca740407, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 32, 4, 0, 8, 8, 8, 16, 8, 24, 8 /* 1024x768xbgra8888 */, (grub_uint32_t []) { 0x8f7a3b6d, 0xcb84c6e3, 0x687c071, 0x42793dff, 0x996dbba4, }, 5 }, diff --git a/grub-core/tests/cmdline_cat_test.c b/grub-core/tests/cmdline_cat_test.c deleted file mode 100644 index 4748d1bb0..000000000 --- a/grub-core/tests/cmdline_cat_test.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -/* All tests need to include test.h for GRUB testing framework. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - - -static const char testfile[] = - /* Chinese & UTF-8 test from Carbon Jiao. */ - "ä»ç¡¬ç›˜ç„第一主分区å¯å¨\n" - "The quick brown fox jumped over the lazy dog.\n" - /* 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+2286 subset symbol E2 8A 86 - U+211D set 'R' symbol (real numbers) E2 84 9D */ - "Unicode test: happy\xE2\x98\xBA \xC2\xA3 5.00" - " \xC2\xA1\xCF\x84\xC3\xA4u! " - " \xE2\x84\xA4\xE2\x8A\x86\xE2\x84\x9D\n" - /* Test handling of bad (non-UTF8) sequences*/ - "\x99Hello\xc2Hello\xc1\x81Hello\n"; -; - -static char * -get_test_txt (grub_size_t *sz) -{ - *sz = grub_strlen (testfile); - return grub_strdup (testfile); -} - -struct grub_procfs_entry test_txt = -{ - .name = "test.txt", - .get_contents = get_test_txt -}; - -#define FONT_NAME "Unknown Regular 16" - -/* Functional test main method. */ -static void -cmdline_cat_test (void) -{ - unsigned i; - grub_font_t font; - - grub_dl_load ("gfxterm"); - grub_errno = GRUB_ERR_NONE; - - font = grub_font_get (FONT_NAME); - if (font && grub_strcmp (font->name, FONT_NAME) != 0) - font = 0; - if (!font) - font = grub_font_load ("unicode"); - - if (!font) - { - grub_test_assert (0, "unicode font not found: %s", grub_errmsg); - return; - } - - grub_procfs_register ("test.txt", &test_txt); - - for (i = 0; i < GRUB_TEST_VIDEO_SMALL_N_MODES; i++) - { - grub_video_capture_start (&grub_test_video_modes[i], - grub_video_fbstd_colors, - grub_test_video_modes[i].number_of_colors); - grub_terminal_input_fake_sequence ((int []) - { 'c', 'a', 't', ' ', - '(', 'p', 'r', 'o', 'c', ')', - '/', 't', 'e', 's', 't', '.', - 't', 'x', 't', '\n', - GRUB_TERM_NO_KEY, - GRUB_TERM_NO_KEY, GRUB_TERM_ESC}, - 23); - - grub_video_checksum ("cmdline_cat"); - - if (!grub_test_use_gfxterm ()) - grub_cmdline_run (1, 0); - - grub_test_use_gfxterm_end (); - - grub_terminal_input_fake_sequence_end (); - grub_video_checksum_end (); - grub_video_capture_end (); - } - - grub_procfs_unregister (&test_txt); -} - -/* Register example_test method as a functional test. */ -GRUB_FUNCTIONAL_TEST (cmdline_cat_test, cmdline_cat_test); diff --git a/grub-core/tests/cmp_test.c b/grub-core/tests/cmp_test.c deleted file mode 100644 index af5b39576..000000000 --- a/grub-core/tests/cmp_test.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2015 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_uint64_t vectors[][2] = { - { 0xffffffffffffffffULL, 1}, - { 1, 0xffffffffffffffffULL}, - { 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - { 1, 1 }, - { 2, 1 } -}; - -/* Don't change those to use shift as shift may call to compile rt - functions and we're not testing them now. - */ -static int -leading_bit64 (grub_uint64_t a) -{ - return !!(a & 0x8000000000000000LL); -} - -static int -leading_bit32 (grub_uint32_t a) -{ - return !!(a & 0x80000000); -} - -/* Computes (a < b) without involving comparison operator. */ -static int -is_less32 (grub_uint32_t a, grub_uint32_t b) -{ - if (leading_bit32(a) && !leading_bit32(b)) - return 0; - if (!leading_bit32(a) && leading_bit32(b)) - return 1; - return leading_bit32(a - b); -} - -static void -test32 (grub_uint32_t a, grub_uint32_t b) -{ - grub_test_assert ((a < b) == is_less32(a, b), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert ((a > b) == is_less32(b, a), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert ((b < a) == is_less32(b, a), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert ((b > a) == is_less32(a, b), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert (!(is_less32(a, b) && is_less32(b, a)), "comparison inconsistent: %lld, %lld", - (long long) a, (long long) b); -} - -/* Computes (a > b) without involving comparison operator. */ -static int -is_less32s (grub_int32_t a, grub_int32_t b) -{ - if (leading_bit32(a) && !leading_bit32(b)) - return 1; /* a < 0 && b >= 0. */ - if (!leading_bit32(a) && leading_bit32(b)) - return 0; /* b < 0 && a >= 0. */ - return leading_bit32(a - b); -} - -static void -test32s (grub_int32_t a, grub_int32_t b) -{ - grub_test_assert ((a < b) == is_less32s(a, b), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert ((a > b) == is_less32s(b, a), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert ((b < a) == is_less32s(b, a), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert ((b > a) == is_less32s(a, b), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert (!(is_less32s(a, b) && is_less32s(b, a)), "comparison inconsistent: %lld, %lld", - (long long) a, (long long) b); -} - -/* Computes (a > b) without involving comparison operator. */ -static int -is_less64 (grub_uint64_t a, grub_uint64_t b) -{ - if (leading_bit64(a) && !leading_bit64(b)) - return 0; - if (!leading_bit64(a) && leading_bit64(b)) - return 1; - return leading_bit64(a - b); -} - -static void -test64 (grub_uint64_t a, grub_uint64_t b) -{ - grub_test_assert ((a < b) == is_less64(a, b), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert ((a > b) == is_less64(b, a), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert ((b < a) == is_less64(b, a), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert ((b > a) == is_less64(a, b), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert (!(is_less64(a, b) && is_less64(b, a)), "comparison inconsistent: %lld, %lld", - (long long) a, (long long) b); -} - -/* Computes (a > b) without involving comparison operator. */ -static int -is_less64s (grub_int64_t a, grub_int64_t b) -{ - if (leading_bit64(a) && !leading_bit64(b)) - return 1; /* a < 0 && b >= 0. */ - if (!leading_bit64(a) && leading_bit64(b)) - return 0; /* b < 0 && a >= 0. */ - return leading_bit64(a - b); -} - -static void -test64s (grub_int64_t a, grub_int64_t b) -{ - grub_test_assert ((a < b) == is_less64s(a, b), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert ((a > b) == is_less64s(b, a), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert ((b < a) == is_less64s(b, a), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert ((b > a) == is_less64s(a, b), "comparison result mismatch: %lld, %lld", - (long long) a, (long long) b); - grub_test_assert (!(is_less64s(a, b) && is_less64s(b, a)), "comparison inconsistent: %lld, %lld", - (long long) a, (long long) b); -} - -static void -test_all(grub_uint64_t a, grub_uint64_t b) -{ - test64 (a, b); - test32 (a, b); - test64s (a, b); - test32s (a, b); - test64s (a, -b); - test32s (a, -b); - test64s (-a, b); - test32s (-a, b); - test64s (-a, -b); - test32s (-a, -b); -} - -static void -cmp_test (void) -{ - grub_uint64_t a = 404, b = 7; - grub_size_t i; - - for (i = 0; i < ARRAY_SIZE (vectors); i++) - { - test_all (vectors[i][0], vectors[i][1]); - } - for (i = 0; i < 40000; i++) - { - a = 17 * a + 13 * b; - b = 23 * a + 29 * b; - if (b == 0) - b = 1; - if (a == 0) - a = 1; - test_all (a, b); - } -} - -/* Register example_test method as a functional test. */ -GRUB_FUNCTIONAL_TEST (cmp_test, cmp_test); diff --git a/grub-core/tests/ctz_test.c b/grub-core/tests/ctz_test.c deleted file mode 100644 index eb7a1df38..000000000 --- a/grub-core/tests/ctz_test.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* ull version is not used on i386 other than in this test. - Avoid requiring extra function. - */ -#if defined (__i386__) -#define SKIP_ULL 1 -#endif - -static grub_uint64_t vectors[] = { - 0xffffffffffffffffULL, 1, 2, 0, 0x0102030405060708ULL -}; - -static void -test_ui (unsigned int a) -{ - int i; - a |= 1; - for (i = 0; i < (int) (8 * sizeof (a)); i++) - { - grub_test_assert (__builtin_ctz(a << i) == i, - "ctz mismatch: ctz(0x%llx) != 0x%x", - (long long) (a << i), __builtin_ctz(a << i)); - } -} - -static void -test_ul (unsigned long a) -{ - int i; - a |= 1; - for (i = 0; i < (int) (8 * sizeof (a)); i++) - { - grub_test_assert (__builtin_ctzl(a << i) == i, - "ctzl mismatch: ctzl(0x%llx) != 0x%x", - (long long) (a << i), __builtin_ctz(a << i)); - } -} - -#ifndef SKIP_ULL -static void -test_ull (unsigned long long a) -{ - int i; - a |= 1; - for (i = 0; i < (int) (8 * sizeof (a)); i++) - { - grub_test_assert (__builtin_ctzll(a << i) == i, - "ctzll mismatch: ctzll(0x%llx) != 0x%x", - (long long) (a << i), __builtin_ctz(a << i)); - } -} -#endif - -static void -test_all(grub_uint64_t a) -{ - test_ui (a); - test_ul (a); -#ifndef SKIP_ULL - test_ull (a); -#endif -} - -static void -ctz_test (void) -{ - grub_uint64_t a = 404, b = 7; - grub_size_t i; - - for (i = 0; i < ARRAY_SIZE (vectors); i++) - { - test_all (vectors[i]); - } - for (i = 0; i < 40000; i++) - { - a = 17 * a + 13 * b; - b = 23 * a + 29 * b; - if (b == 0) - b = 1; - if (a == 0) - a = 1; - test_all (a); - test_all (b); - } -} - -/* Register example_test method as a functional test. */ -GRUB_FUNCTIONAL_TEST (ctz_test, ctz_test); diff --git a/grub-core/tests/div_test.c b/grub-core/tests/div_test.c deleted file mode 100644 index 9abc6d5c4..000000000 --- a/grub-core/tests/div_test.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_uint64_t vectors[][2] = { - { 0xffffffffffffffffULL, 1}, - { 1, 0xffffffffffffffffULL}, - { 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - { 1, 1 }, - { 2, 1 } -}; - -static void -test32 (grub_uint32_t a, grub_uint32_t b) -{ - grub_uint64_t q, r; - if (b == 0) - return; - q = grub_divmod64 (a, b, &r); - grub_test_assert (r < b, "remainder is larger than dividend: 0x%llx %% 0x%llx = 0x%llx", - (long long) a, (long long) b, (long long) r); - grub_test_assert (q * b + r == a, "division doesn't satisfy base property: 0x%llx * 0x%llx + 0x%llx != 0x%llx", (long long) q, (long long) b, (long long) r, - (long long) a); - /* Overflow check. */ - grub_test_assert ((q >> 32) == 0, - "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b); - grub_test_assert ((r >> 32) == 0, - "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b); - /* q * b + r is at most: - 0xffffffff * 0xffffffff + 0xffffffff = 0xffffffff00000000 - so no overflow - */ - grub_test_assert (q == (a / b), - "C compiler division failure in 0x%llx, 0x%llx", (long long) a, (long long) b); - grub_test_assert (r == (a % b), - "C compiler modulo failure in 0x%llx, 0x%llx", (long long) a, (long long) b); -} - -static void -test64 (grub_uint64_t a, grub_uint64_t b) -{ - grub_uint64_t q, r; - grub_uint64_t x1, x2; - q = grub_divmod64 (a, b, &r); - grub_test_assert (r < b, "remainder is larger than dividend: 0x%llx %% 0x%llx = 0x%llx", - (long long) a, (long long) b, (long long) r); - grub_test_assert (q * b + r == a, "division doesn't satisfy base property: 0x%llx * 0x%llx + 0x%llx != 0x%llx", (long long) q, (long long) b, (long long) r, - (long long) a); - /* Overflow checks. */ - grub_test_assert ((q >> 32) * (b >> 32) == 0, - "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b); - x1 = (q >> 32) * (b & 0xffffffff); - grub_test_assert (x1 < (1LL << 32), - "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b); - x1 <<= 32; - x2 = (b >> 32) * (q & 0xffffffff); - grub_test_assert (x2 < (1LL << 32), - "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b); - x2 <<= 32; - grub_test_assert (x1 <= ~x2, - "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b); - x1 += x2; - x2 = (q & 0xffffffff) * (b & 0xffffffff); - grub_test_assert (x1 <= ~x2, - "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b); - x1 += x2; - grub_test_assert (x1 <= ~r, - "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b); - x1 += r; - grub_test_assert (a == x1, - "division overflow test failure in 0x%llx, 0x%llx", (long long) a, (long long) b); -#if GRUB_TARGET_SIZEOF_VOID_P == 8 - grub_test_assert (q == (a / b), - "C compiler division failure in 0x%llx, 0x%llx", (long long) a, (long long) b); - grub_test_assert (r == (a % b), - "C compiler modulo failure in 0x%llx, 0x%llx", (long long) a, (long long) b); -#endif -} - -static grub_int64_t -abs64(grub_int64_t a) -{ - return a > 0 ? a : -a; -} - -static void -test32s (grub_int32_t a, grub_int32_t b) -{ - grub_int64_t q, r; - if (b == 0) - return; - - q = grub_divmod64s (a, b, &r); - grub_test_assert (a > 0 ? r >= 0 : r <= 0, "remainder sign mismatch: %lld %% %lld = %lld", - (long long) a, (long long) b, (long long) r); - grub_test_assert (((a > 0) == (b > 0)) ? q >= 0 : q <= 0, "quotient sign mismatch: %lld / %lld = %lld", - (long long) a, (long long) b, (long long) q); - grub_test_assert (abs64(r) < abs64(b), "remainder is larger than dividend: %lld %% %lld = %lld", - (long long) a, (long long) b, (long long) r); - grub_test_assert (q * b + r == a, "division doesn't satisfy base property: %lld * %lld + %lld != %lld", (long long) q, (long long) b, (long long) r, - (long long) a); - if (0) { grub_test_assert (q == (a / b), - "C compiler division failure in 0x%llx, 0x%llx", (long long) a, (long long) b); - grub_test_assert (r == (a % b), - "C compiler modulo failure in 0x%llx, 0x%llx", (long long) a, (long long) b); - } -} - -static void -test64s (grub_int64_t a, grub_int64_t b) -{ - grub_int64_t q, r; - q = grub_divmod64s (a, b, &r); - - grub_test_assert (a > 0 ? r >= 0 : r <= 0, "remainder sign mismatch: %lld %% %lld = %lld", - (long long) a, (long long) b, (long long) r); - grub_test_assert (((a > 0) == (b > 0)) ? q >= 0 : q <= 0, "quotient sign mismatch: %lld / %lld = %lld", - (long long) a, (long long) b, (long long) q); - grub_test_assert (abs64(r) < abs64(b), "remainder is larger than dividend: %lld %% %lld = %lld", - (long long) a, (long long) b, (long long) r); - grub_test_assert (q * b + r == a, "division doesn't satisfy base property: 0x%llx * 0x%llx + 0x%llx != 0x%llx", (long long) q, (long long) b, (long long) r, - (long long) a); -#if GRUB_TARGET_SIZEOF_VOID_P == 8 - grub_test_assert (q == (a / b), - "C compiler division failure in 0x%llx, 0x%llx", (long long) a, (long long) b); - grub_test_assert (r == (a % b), - "C compiler modulo failure in 0x%llx, 0x%llx", (long long) a, (long long) b); -#endif -} - -static void -test_all(grub_uint64_t a, grub_uint64_t b) -{ - test64 (a, b); - test32 (a, b); - test64s (a, b); - test32s (a, b); - test64s (a, -b); - test32s (a, -b); - test64s (-a, b); - test32s (-a, b); - test64s (-a, -b); - test32s (-a, -b); -} - -static void -div_test (void) -{ - grub_uint64_t a = 404, b = 7; - grub_size_t i; - - for (i = 0; i < ARRAY_SIZE (vectors); i++) - { - test_all (vectors[i][0], vectors[i][1]); - } - for (i = 0; i < 40000; i++) - { - a = 17 * a + 13 * b; - b = 23 * a + 29 * b; - if (b == 0) - b = 1; - if (a == 0) - a = 1; - test_all (a, b); - } -} - -/* Register example_test method as a functional test. */ -GRUB_FUNCTIONAL_TEST (div_test, div_test); diff --git a/grub-core/tests/fake_input.c b/grub-core/tests/fake_input.c deleted file mode 100644 index b5eb516be..000000000 --- a/grub-core/tests/fake_input.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static int *seq; -static int seqptr, nseq; -static struct grub_term_input *saved; -static int fake_input; - -static int -fake_getkey (struct grub_term_input *term __attribute__ ((unused))) -{ - if (seq && seqptr < nseq) - return seq[seqptr++]; - return -1; -} - -static struct grub_term_input fake_input_term = - { - .name = "fake", - .getkey = fake_getkey - }; - -void -grub_terminal_input_fake_sequence (int *seq_in, int nseq_in) -{ - if (!fake_input) - saved = grub_term_inputs; - if (seq) - grub_free (seq); - seq = grub_calloc (nseq_in, sizeof (seq[0])); - if (!seq) - return; - - grub_term_inputs = &fake_input_term; - grub_memcpy (seq, seq_in, nseq_in * sizeof (seq[0])); - - nseq = nseq_in; - seqptr = 0; - fake_input = 1; -} - -void -grub_terminal_input_fake_sequence_end (void) -{ - if (!fake_input) - return; - fake_input = 0; - grub_term_inputs = saved; - grub_free (seq); - seq = 0; - nseq = 0; - seqptr = 0; -} diff --git a/grub-core/tests/gfxterm_menu.c b/grub-core/tests/gfxterm_menu.c deleted file mode 100644 index ea4352703..000000000 --- a/grub-core/tests/gfxterm_menu.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -/* All tests need to include test.h for GRUB testing framework. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - - -static const char testfile[] = - "menuentry \"test\" {\n" - "\ttrue\n" - "}\n" - "menuentry \"s̀› ò› t ò’ s̀’ u ò•̀ 8.04 m̀‚ǹƒàh̀z̀†x̀£ à¡ b̀¢g̀¢ uá·oá·̀‚ ò‚á· Ò· à–̀£ à‘̀\" --class ubuntu --class linux --class os {\n" - "\ttrue\n" - "}\n" - "menuentry \" הַר×לל(טוֹבָ) לֶ×Ö°\" --class opensuse --class linux --class os {\n" - "\ttrue\n" - "}\n" - "menuentry \"الرملل Ø¬ÙØ¯Ø§Ù‹ Ù„ÙÙƒÙ\" --class gentoo --class linux --class os {\n" - "\ttrue\n" - "}\n" - "menuentry \"ὑπόγυͅον\" --class kubuntu --class linux --class os {\n" - "\ttrue\n" - "}\n" - "menuentry \"سّ٠نّ٠نÙÙ‘ نٌّ نّْ\" --class linuxmint --class linux --class os {\n" - "\ttrue\n" - "}\n" - /* Chinese & UTF-8 test from Carbon Jiao. */ - "menuentry \"ä»ç¡¬ç›˜ç„第一主分区å¯å¨\" --class \"windows xp\" --class windows --class os {\n" - "\ttrue\n" - "}\n" - "timeout=3\n"; - -static char * -get_test_cfg (grub_size_t *sz) -{ - *sz = grub_strlen (testfile); - return grub_strdup (testfile); -} - -struct grub_procfs_entry test_cfg = -{ - .name = "test.cfg", - .get_contents = get_test_cfg -}; - -struct -{ - const char *name; - const char *var; - const char *val; -} tests[] = - { - { "gfxterm_menu", NULL, NULL }, - { "gfxmenu", "theme", "starfield/theme.txt" }, - { "gfxterm_ar", "lang", "en@arabic" }, - { "gfxterm_cyr", "lang", "en@cyrillic" }, - { "gfxterm_heb", "lang", "en@hebrew" }, - { "gfxterm_gre", "lang", "en@greek" }, - { "gfxterm_ru", "lang", "ru" }, - { "gfxterm_fr", "lang", "fr" }, - { "gfxterm_quot", "lang", "en@quot" }, - { "gfxterm_piglatin", "lang", "en@piglatin" }, - { "gfxterm_ch", "lang", "de_CH" }, - { "gfxterm_red", "menu_color_normal", "red/blue" }, - { "gfxterm_high", "menu_color_highlight", "blue/red" }, - }; - -#define FONT_NAME "Unknown Regular 16" - -/* Functional test main method. */ -static void -gfxterm_menu (void) -{ - unsigned i, j; - grub_font_t font; - - grub_dl_load ("png"); - grub_dl_load ("gettext"); - grub_dl_load ("gfxterm"); - - grub_errno = GRUB_ERR_NONE; - - grub_dl_load ("gfxmenu"); - - font = grub_font_get (FONT_NAME); - if (font && grub_strcmp (font->name, FONT_NAME) != 0) - font = 0; - if (!font) - font = grub_font_load ("unicode"); - - if (!font) - { - grub_test_assert (0, "unicode font not found: %s", grub_errmsg); - return; - } - - grub_procfs_register ("test.cfg", &test_cfg); - - for (j = 0; j < ARRAY_SIZE (tests); j++) - for (i = 0; i < GRUB_TEST_VIDEO_SMALL_N_MODES; i++) - { - grub_uint64_t start; - -#if defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_IEEE1275) - if (grub_test_video_modes[i].width > 1024) - continue; - if (grub_strcmp (tests[j].name, "gfxmenu") == 0 - && grub_test_video_modes[i].width > 800) - continue; -#endif - start = grub_get_time_ms (); - - grub_video_capture_start (&grub_test_video_modes[i], - grub_video_fbstd_colors, - grub_test_video_modes[i].number_of_colors); - if (grub_errno) - { - grub_test_assert (0, "can't start capture: %d: %s", - grub_errno, grub_errmsg); - return; - } - grub_terminal_input_fake_sequence ((int []) { -1, -1, -1, GRUB_TERM_KEY_DOWN, -1, 'e', - -1, GRUB_TERM_KEY_RIGHT, -1, 'x', -1, GRUB_TERM_ESC, -1, GRUB_TERM_ESC }, 14); - - grub_video_checksum (tests[j].name); - - if (grub_test_use_gfxterm ()) - return; - - grub_env_context_open (); - if (tests[j].var) - grub_env_set (tests[j].var, tests[j].val); - grub_normal_execute ("(proc)/test.cfg", 1, 0); - grub_env_context_close (); - - grub_test_use_gfxterm_end (); - - grub_terminal_input_fake_sequence_end (); - grub_video_checksum_end (); - grub_video_capture_end (); - - if (tests[j].var) - grub_env_unset (tests[j].var); - grub_printf ("%s %dx%dx%s done %lld ms\n", tests[j].name, - grub_test_video_modes[i].width, - grub_test_video_modes[i].height, - grub_video_checksum_get_modename (), (long long) (grub_get_time_ms () - start)); - } - - grub_procfs_unregister (&test_cfg); -} - -/* Register example_test method as a functional test. */ -GRUB_FUNCTIONAL_TEST (gfxterm_menu, gfxterm_menu); diff --git a/grub-core/tests/legacy_password_test.c b/grub-core/tests/legacy_password_test.c deleted file mode 100644 index 25460338e..000000000 --- a/grub-core/tests/legacy_password_test.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static struct -{ - char **args; - int argc; - char entered[GRUB_AUTH_MAX_PASSLEN]; - int exp; -} vectors[] = { - { (char * []) { (char *) "hello", NULL }, 1, "hello", 1 }, - { (char * []) { (char *) "hello", NULL }, 1, "hi", 0 }, - { (char * []) { (char *) "hello", NULL }, 1, "hillo", 0 }, - { (char * []) { (char *) "hello", NULL }, 1, "hellw", 0 }, - { (char * []) { (char *) "hello", NULL }, 1, "hell", 0 }, - { (char * []) { (char *) "hello", NULL }, 1, "h", 0 }, - { (char * []) { (char *) "--md5", (char *) "$1$maL$OKEF0PD2k6eQ0Po8u4Gjr/", - NULL }, 2, "hello", 1 }, - { (char * []) { (char *) "--md5", (char *) "$1$maL$OKEF0PD2k6eQ0Po8u4Gjr/", - NULL }, 2, "hell", 0 }, - { (char * []) { (char *) "--md5", (char *) "$1$naL$BaFO8zGgmss1E76GsrAec1", - NULL }, 2, "hello", 1 }, - { (char * []) { (char *) "--md5", (char *) "$1$naL$BaFO8zGgmss1E76GsrAec1", - NULL }, 2, "hell", 0 }, - { (char * []) { (char *) "--md5", (char *) "$1$oaL$eyrazuM7TkxVkKgBim1WH1", - NULL }, 2, "hi", 1 }, - { (char * []) { (char *) "--md5", (char *) "$1$oaL$eyrazuM7TkxVkKgBim1WH1", - NULL }, 2, "hello", 0 }, -}; - -static void -legacy_password_test (void) -{ - grub_size_t i; - - for (i = 0; i < ARRAY_SIZE (vectors); i++) - grub_test_assert (grub_legacy_check_md5_password (vectors[i].argc, - vectors[i].args, - vectors[i].entered) - == vectors[i].exp, "Bad password check (%d)", (int) i); -} - -/* Register example_test method as a functional test. */ -GRUB_FUNCTIONAL_TEST (legacy_password_test, legacy_password_test); diff --git a/grub-core/tests/lib/functional_test.c b/grub-core/tests/lib/functional_test.c deleted file mode 100644 index 38e981f2c..000000000 --- a/grub-core/tests/lib/functional_test.c +++ /dev/null @@ -1,106 +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 . - */ - -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -grub_functional_test (grub_extcmd_context_t ctxt __attribute__ ((unused)), - int argc, - char **args) -{ - grub_test_t test; - int ok = 1; - int i; - - FOR_LIST_ELEMENTS (test, grub_test_list) - { - if (argc != 0) - { - for (i = 0; i < argc; i++) - if (grub_strcmp(args[i], test->name) == 0) - break; - if (i == argc) - continue; - } - grub_errno = 0; - ok = ok && !grub_test_run (test); - grub_errno = 0; - } - if (ok) - grub_printf ("ALL TESTS PASSED\n"); - else - grub_printf ("TEST FAILURE\n"); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_functional_all_tests (grub_extcmd_context_t ctxt __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - grub_test_t test; - int ok = 1; - - grub_dl_load ("legacy_password_test"); - grub_errno = GRUB_ERR_NONE; - grub_dl_load ("exfctest"); - grub_dl_load ("videotest_checksum"); - grub_dl_load ("gfxterm_menu"); - grub_dl_load ("setjmp_test"); - grub_dl_load ("cmdline_cat_test"); - grub_dl_load ("div_test"); - grub_dl_load ("xnu_uuid_test"); - grub_dl_load ("pbkdf2_test"); - grub_dl_load ("signature_test"); - grub_dl_load ("sleep_test"); - grub_dl_load ("bswap_test"); - grub_dl_load ("ctz_test"); - grub_dl_load ("cmp_test"); - grub_dl_load ("mul_test"); - grub_dl_load ("shift_test"); - grub_dl_load ("asn1_test"); - - FOR_LIST_ELEMENTS (test, grub_test_list) - ok = !grub_test_run (test) && ok; - if (ok) - grub_printf ("ALL TESTS PASSED\n"); - else - grub_printf ("TEST FAILURE\n"); - return GRUB_ERR_NONE; -} - -static grub_extcmd_t cmd; - -GRUB_MOD_INIT (functional_test) -{ - cmd = grub_register_extcmd ("functional_test", grub_functional_test, 0, 0, - "Run all loaded functional tests.", 0); - cmd = grub_register_extcmd ("all_functional_test", grub_functional_all_tests, 0, 0, - "Run all functional tests.", 0); -} - -GRUB_MOD_FINI (functional_test) -{ - grub_unregister_extcmd (cmd); -} diff --git a/grub-core/tests/mul_test.c b/grub-core/tests/mul_test.c deleted file mode 100644 index cd6423192..000000000 --- a/grub-core/tests/mul_test.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_uint64_t vectors[][2] = { - { 0xffffffffffffffffULL, 1}, - { 1, 0xffffffffffffffffULL}, - { 0xffffffffffffffffULL, 0xffffffffffffffffULL}, - { 1, 1 }, - { 2, 1 } -}; - -static void -test64(grub_uint64_t a, grub_uint64_t b) -{ - grub_uint64_t r1 = a * b, r2 = 0, r3; - int i; - for (i = 0; i < 64; i++) - if ((a & (1LL << i))) - r2 += b << i; - r3 = ((grub_int64_t) a) * ((grub_int64_t) b); - grub_test_assert (r1 == r2, - "multiplication mismatch (u): 0x%llx x 0x%llx = 0x%llx != 0x%llx", - (long long) a, (long long) b, (long long) r2, (long long) r1); - grub_test_assert (r3 == r2, - "multiplication mismatch (s): 0x%llx x 0x%llx = 0x%llx != 0x%llx", - (long long) a, (long long) b, (long long) r2, (long long) r3); -} - -static void -mul_test (void) -{ - grub_uint64_t a = 404, b = 7; - grub_size_t i; - - for (i = 0; i < ARRAY_SIZE (vectors); i++) - { - test64 (vectors[i][0], vectors[i][1]); - } - for (i = 0; i < 40000; i++) - { - a = 17 * a + 13 * b; - b = 23 * a + 29 * b; - if (b == 0) - b = 1; - if (a == 0) - a = 1; - test64 (a, b); - } -} - -/* Register example_test method as a functional test. */ -GRUB_FUNCTIONAL_TEST (mul_test, mul_test); diff --git a/grub-core/tests/pbkdf2_test.c b/grub-core/tests/pbkdf2_test.c deleted file mode 100644 index 4eeb8b89f..000000000 --- a/grub-core/tests/pbkdf2_test.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static struct -{ - const char *P; - grub_size_t Plen; - const char *S; - grub_size_t Slen; - unsigned int c; - grub_size_t dkLen; - const char *DK; -} vectors[] = { - /* RFC6070. */ - { - "password", 8, - "salt", 4, - 1, 20, - "\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9\xb5\x24\xaf\x60\x12" - "\x06\x2f\xe0\x37\xa6" - }, - { - "password", 8, - "salt", 4, - 2, 20, - "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c" - "\xcd\x1e\xd9\x2a\xce\x1d\x41\xf0" - "\xd8\xde\x89\x57" - }, - { - "password", 8, - "salt", 4, - 4096, 20, - "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26\xf7" - "\x21\xd0\x65\xa4\x29\xc1" - }, - { - "passwordPASSWORDpassword", 24, - "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, - 4096, 25, - "\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62\xc0" - "\xe4\x4a\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38" - }, - { - "pass\0word", 9, - "sa\0lt", 5, - 4096, 16, - "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34\x25\xe0\xc3" - } -}; - -static void -pbkdf2_test (void) -{ - grub_size_t i; - - for (i = 0; i < ARRAY_SIZE (vectors); i++) - { - gcry_err_code_t err; - grub_uint8_t DK[32]; - err = grub_crypto_pbkdf2 (GRUB_MD_SHA1, - (const grub_uint8_t *) vectors[i].P, - vectors[i].Plen, - (const grub_uint8_t *) vectors[i].S, - vectors[i].Slen, - vectors[i].c, - DK, vectors[i].dkLen); - grub_test_assert (err == 0, "gcry error %d", err); - grub_test_assert (grub_memcmp (DK, vectors[i].DK, vectors[i].dkLen) == 0, - "PBKDF2 mismatch"); - } -} - -/* Register example_test method as a functional test. */ -GRUB_FUNCTIONAL_TEST (pbkdf2_test, pbkdf2_test); diff --git a/grub-core/tests/setjmp_test.c b/grub-core/tests/setjmp_test.c deleted file mode 100644 index 604a6ce8f..000000000 --- a/grub-core/tests/setjmp_test.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_jmp_buf jmp_point; -static int expected, ctr; - -/* This fixes GCC7 "unintentional fallthrough" warning */ -static void jmp0 (void) __attribute__ ((noreturn)); -static void jmp1 (void) __attribute__ ((noreturn)); -static void jmp2 (void) __attribute__ ((noreturn)); - -static void -jmp0 (void) -{ - grub_longjmp (jmp_point, 0); -} - -static void -jmp1 (void) -{ - grub_longjmp (jmp_point, 1); -} - -static void -jmp2 (void) -{ - grub_longjmp (jmp_point, 2); -} - -static void -setjmp_test (void) -{ - int val; - - expected = 0; - ctr = 0; - val = grub_setjmp (jmp_point); - - grub_test_assert (val == expected, "setjmp returned %d instead of %d", - val, expected); - switch (ctr++) - { - case 0: - expected = 1; - jmp0 (); - case 1: - expected = 1; - jmp1 (); - case 2: - expected = 2; - jmp2 (); - case 3: - return; - } - grub_test_assert (0, "setjmp didn't return enough times"); -} - -/* Register example_test method as a functional test. */ -GRUB_FUNCTIONAL_TEST (setjmp_test, setjmp_test); diff --git a/grub-core/tests/shift_test.c b/grub-core/tests/shift_test.c deleted file mode 100644 index 3d0110a06..000000000 --- a/grub-core/tests/shift_test.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2015 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_uint64_t vectors[] = { - 0xffffffffffffffffULL, 1, 2, 0, 0x0102030405060708ULL -}; - -/* We're testing shifts, don't replace access to this with a shift. */ -static const grub_uint8_t bitmask[] = - { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; - -typedef union { - grub_uint64_t v64; - grub_uint8_t v8[8]; -} grub_raw_u64_t; - -static int -get_bit64 (grub_uint64_t v, int b) -{ - grub_raw_u64_t vr = { .v64 = v }; - grub_uint8_t *p = vr.v8; - if (b >= 64) - return 0; -#ifdef GRUB_CPU_WORDS_BIGENDIAN - p += 7 - b / 8; -#else - p += b / 8; -#endif - return !!(*p & bitmask[b % 8]); -} - -static grub_uint64_t -set_bit64 (grub_uint64_t v, int b) -{ - grub_raw_u64_t vr = { .v64 = v }; - grub_uint8_t *p = vr.v8; - if (b >= 64) - return v; -#ifdef GRUB_CPU_WORDS_BIGENDIAN - p += 7 - b / 8; -#else - p += b / 8; -#endif - *p |= bitmask[b % 8]; - return vr.v64; -} - -static grub_uint64_t -left_shift64 (grub_uint64_t v, int s) -{ - grub_uint64_t r = 0; - int i; - for (i = 0; i + s < 64; i++) - if (get_bit64 (v, i)) - r = set_bit64 (r, i + s); - return r; -} - -static grub_uint64_t -right_shift64 (grub_uint64_t v, int s) -{ - grub_uint64_t r = 0; - int i; - for (i = s; i < 64; i++) - if (get_bit64 (v, i)) - r = set_bit64 (r, i - s); - return r; -} - -static grub_uint64_t -arithmetic_right_shift64 (grub_uint64_t v, int s) -{ - grub_uint64_t r = 0; - int i; - for (i = s; i < 64; i++) - if (get_bit64 (v, i)) - r = set_bit64 (r, i - s); - if (get_bit64 (v, 63)) - for (i -= s; i < 64; i++) - r = set_bit64 (r, i); - - return r; -} - -static void -test64 (grub_uint64_t v) -{ - int i; - for (i = 0; i < 64; i++) - { - grub_test_assert ((v << i) == left_shift64 (v, i), - "lshift wrong: 0x%llx << %d: 0x%llx, 0x%llx", - (long long) v, i, - (long long) (v << i), (long long) left_shift64 (v, i)); - grub_test_assert ((v >> i) == right_shift64 (v, i), - "rshift wrong: 0x%llx >> %d: 0x%llx, 0x%llx", - (long long) v, i, - (long long) (v >> i), (long long) right_shift64 (v, i)); - grub_test_assert ((((grub_int64_t) v) >> i) == (grub_int64_t) arithmetic_right_shift64 (v, i), - "arithmetic rshift wrong: ((grub_int64_t) 0x%llx) >> %d: 0x%llx, 0x%llx", - (long long) v, i, - (long long) (((grub_int64_t) v) >> i), (long long) arithmetic_right_shift64 (v, i)); - } -} - -static void -test_all(grub_uint64_t a) -{ - test64 (a); -} - -static void -shift_test (void) -{ - grub_uint64_t a = 404, b = 7; - grub_size_t i; - - for (i = 0; i < ARRAY_SIZE (vectors); i++) - { - test_all (vectors[i]); - } - for (i = 0; i < 4000; i++) - { - a = 17 * a + 13 * b; - b = 23 * a + 29 * b; - if (b == 0) - b = 1; - if (a == 0) - a = 1; - test_all (a); - test_all (b); - } -} - -/* Register example_test method as a functional test. */ -GRUB_FUNCTIONAL_TEST (shift_test, shift_test); diff --git a/grub-core/tests/signature_test.c b/grub-core/tests/signature_test.c deleted file mode 100644 index 07a913a62..000000000 --- a/grub-core/tests/signature_test.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "signatures.h" - -GRUB_MOD_LICENSE ("GPLv3+"); - -static char * -get_hi_dsa_sig (grub_size_t *sz) -{ - char *ret; - *sz = sizeof (hi_dsa_sig); - ret = grub_malloc (sizeof (hi_dsa_sig)); - if (ret) - grub_memcpy (ret, hi_dsa_sig, sizeof (hi_dsa_sig)); - return ret; -} - -static struct grub_procfs_entry hi_dsa_sig_entry = -{ - .name = "hi_dsa.sig", - .get_contents = get_hi_dsa_sig -}; - -static char * -get_hi_dsa_pub (grub_size_t *sz) -{ - char *ret; - *sz = sizeof (hi_dsa_pub); - ret = grub_malloc (sizeof (hi_dsa_pub)); - if (ret) - grub_memcpy (ret, hi_dsa_pub, sizeof (hi_dsa_pub)); - return ret; -} - -static struct grub_procfs_entry hi_dsa_pub_entry = -{ - .name = "hi_dsa.pub", - .get_contents = get_hi_dsa_pub -}; - -static char * -get_hi_rsa_sig (grub_size_t *sz) -{ - char *ret; - *sz = sizeof (hi_rsa_sig); - ret = grub_malloc (sizeof (hi_rsa_sig)); - if (ret) - grub_memcpy (ret, hi_rsa_sig, sizeof (hi_rsa_sig)); - return ret; -} - -static struct grub_procfs_entry hi_rsa_sig_entry = -{ - .name = "hi_rsa.sig", - .get_contents = get_hi_rsa_sig -}; - -static char * -get_hi_rsa_pub (grub_size_t *sz) -{ - char *ret; - *sz = sizeof (hi_rsa_pub); - ret = grub_malloc (sizeof (hi_rsa_pub)); - if (ret) - grub_memcpy (ret, hi_rsa_pub, sizeof (hi_rsa_pub)); - return ret; -} - -static struct grub_procfs_entry hi_rsa_pub_entry = -{ - .name = "hi_rsa.pub", - .get_contents = get_hi_rsa_pub -}; - -static char * -get_hi (grub_size_t *sz) -{ - *sz = 3; - return grub_strdup ("hi\n"); -} - -struct grub_procfs_entry hi = -{ - .name = "hi", - .get_contents = get_hi -}; - -static char * -get_hj (grub_size_t *sz) -{ - *sz = 3; - return grub_strdup ("hj\n"); -} - -struct grub_procfs_entry hj = -{ - .name = "hj", - .get_contents = get_hj -}; - -static void -do_verify (const char *f, const char *sig, const char *pub, int is_valid) -{ - grub_command_t cmd; - char *args[] = { (char *) f, (char *) sig, - (char *) pub, NULL }; - grub_err_t err; - - cmd = grub_command_find ("verify_detached"); - if (!cmd) - { - grub_test_assert (0, "can't find command `%s'", "verify_detached"); - return; - } - err = (cmd->func) (cmd, 3, args); - - grub_test_assert (err == (is_valid ? 0 : GRUB_ERR_BAD_SIGNATURE), - "verification failed: %d: %s", grub_errno, grub_errmsg); - grub_errno = GRUB_ERR_NONE; - -} -static void -signature_test (void) -{ - grub_procfs_register ("hi", &hi); - grub_procfs_register ("hj", &hj); - grub_procfs_register ("hi_dsa.pub", &hi_dsa_pub_entry); - grub_procfs_register ("hi_dsa.sig", &hi_dsa_sig_entry); - grub_procfs_register ("hi_rsa.pub", &hi_rsa_pub_entry); - grub_procfs_register ("hi_rsa.sig", &hi_rsa_sig_entry); - - do_verify ("(proc)/hi", "(proc)/hi_dsa.sig", "(proc)/hi_dsa.pub", 1); - do_verify ("(proc)/hi", "(proc)/hi_dsa.sig", "(proc)/hi_dsa.pub", 1); - do_verify ("(proc)/hj", "(proc)/hi_dsa.sig", "(proc)/hi_dsa.pub", 0); - - do_verify ("(proc)/hi", "(proc)/hi_rsa.sig", "(proc)/hi_rsa.pub", 1); - do_verify ("(proc)/hj", "(proc)/hi_rsa.sig", "(proc)/hi_rsa.pub", 0); - - grub_procfs_unregister (&hi); - grub_procfs_unregister (&hj); - grub_procfs_unregister (&hi_dsa_sig_entry); - grub_procfs_unregister (&hi_dsa_pub_entry); -} - -GRUB_FUNCTIONAL_TEST (signature_test, signature_test); diff --git a/grub-core/tests/signatures.h b/grub-core/tests/signatures.h deleted file mode 100644 index d78c2b6c1..000000000 --- a/grub-core/tests/signatures.h +++ /dev/null @@ -1,211 +0,0 @@ -static unsigned char hi_rsa_sig[] = -{ -0x89, 0x02, 0x1c, 0x04, 0x00, 0x01, 0x02, 0x00, 0x06, 0x05, 0x02, 0x52, 0x82, 0x2d, 0x16, 0x00, -0x0a, 0x09, 0x10, 0x0f, 0xcc, 0xf3, 0x21, 0x77, 0x83, 0x6a, 0x0d, 0xdb, 0x5e, 0x10, 0x00, 0x80, -0x36, 0x2c, 0xb0, 0xbf, 0x26, 0x36, 0xf2, 0x9d, 0x93, 0xa0, 0xbf, 0xcb, 0xa7, 0x0d, 0xbe, 0x67, -0x33, 0xf6, 0xba, 0xec, 0x2b, 0xe9, 0x7e, 0x0e, 0xec, 0x51, 0xd5, 0xdd, 0x2d, 0x9a, 0x96, 0x09, -0x8a, 0x7f, 0x02, 0xd5, 0xbc, 0xdb, 0xc9, 0xef, 0xd8, 0x90, 0x8a, 0xa8, 0x71, 0x6f, 0xaf, 0x8c, -0xe5, 0x6a, 0xc4, 0xda, 0x2a, 0x1f, 0x17, 0xb1, 0x70, 0x69, 0x06, 0x2b, 0x2f, 0x18, 0x72, 0x72, -0x28, 0xd6, 0x32, 0xa1, 0x96, 0x14, 0xd5, 0x2a, 0x52, 0x35, 0x4a, 0x3b, 0x8b, 0x6f, 0x0c, 0x24, -0x97, 0xb7, 0x7f, 0xf6, 0x15, 0x8c, 0xbf, 0x69, 0x73, 0xee, 0x15, 0x0f, 0x07, 0x7e, 0x5e, 0x07, -0x9b, 0x81, 0x28, 0x74, 0x49, 0x94, 0xd3, 0x05, 0xeb, 0xc9, 0x63, 0x70, 0x89, 0x91, 0x68, 0xe6, -0x20, 0x32, 0x95, 0x00, 0x00, 0xc8, 0xba, 0xbd, 0x45, 0x77, 0x6b, 0x60, 0xa4, 0xa3, 0x05, 0x6b, -0x70, 0x38, 0x07, 0x08, 0x8d, 0x09, 0xff, 0x5a, 0x55, 0xb2, 0x1f, 0xe2, 0xdf, 0xf0, 0x1b, 0x8d, -0x40, 0xed, 0x52, 0x16, 0x3a, 0x7b, 0xb2, 0xbc, 0x3f, 0x21, 0x14, 0x58, 0xb0, 0x64, 0x6c, 0x33, -0xcf, 0xdb, 0x93, 0x5a, 0x56, 0xa4, 0x3a, 0xd2, 0xcd, 0x22, 0x4a, 0x2f, 0x8e, 0x77, 0x2b, 0x0a, -0x57, 0x43, 0x4b, 0x15, 0xab, 0xee, 0x3e, 0xa5, 0xf8, 0xff, 0xb9, 0xb2, 0x7d, 0x59, 0x84, 0x36, -0x0a, 0x3b, 0x17, 0xda, 0x78, 0x50, 0x66, 0x62, 0xb9, 0x78, 0xad, 0x61, 0x3b, 0x26, 0xe9, 0x00, -0x67, 0xd7, 0x3c, 0x75, 0xa4, 0xf3, 0x3a, 0x51, 0x4f, 0xd3, 0x0d, 0x04, 0xb8, 0x07, 0x7c, 0x06, -0xcb, 0x22, 0x23, 0x4c, 0x1c, 0xa3, 0xb0, 0x03, 0x23, 0xdd, 0x50, 0xee, 0xd1, 0xc8, 0xff, 0xa0, -0xc4, 0xa4, 0x68, 0x0d, 0xfc, 0xc5, 0x2e, 0x53, 0x33, 0x30, 0xb0, 0x56, 0x62, 0xb3, 0x9b, 0xa6, -0x7f, 0x68, 0xb0, 0xbb, 0x67, 0x02, 0x41, 0x52, 0x05, 0x49, 0x9b, 0x4f, 0x61, 0x63, 0x48, 0xc4, -0x5d, 0x62, 0x65, 0xef, 0xd1, 0xbf, 0xb5, 0x46, 0x96, 0xdc, 0x9a, 0xdf, 0xb9, 0xe9, 0x8f, 0xd3, -0x6e, 0x12, 0x96, 0x31, 0x3c, 0x1a, 0xab, 0x04, 0xcf, 0x5e, 0x8d, 0x8c, 0xe4, 0x09, 0x6f, 0xcf, -0xd7, 0xe8, 0x2e, 0x43, 0x53, 0x6a, 0x84, 0x3e, 0x28, 0x5b, 0xcc, 0x03, 0xb2, 0xae, 0xff, 0xc3, -0xe4, 0x8a, 0x37, 0xa1, 0x88, 0xca, 0x0d, 0xa0, 0x2b, 0x64, 0xbd, 0x78, 0x78, 0x2a, 0x6e, 0x26, -0x8f, 0x85, 0x69, 0x6a, 0xa9, 0xf2, 0xc4, 0xba, 0xf0, 0xed, 0xe9, 0xb9, 0x74, 0xbb, 0x95, 0xde, -0x1c, 0xdc, 0x80, 0xf3, 0x46, 0x28, 0xf6, 0x4c, 0x01, 0x7a, 0x6d, 0x9a, 0x9a, 0xe1, 0xb8, 0x1b, -0x9e, 0x4a, 0x28, 0x6c, 0x96, 0x59, 0xc6, 0x53, 0xe3, 0xc9, 0x7c, 0xaf, 0xf0, 0x22, 0x08, 0xb5, -0xef, 0xad, 0xc8, 0x8d, 0x3a, 0x6c, 0x27, 0xf7, 0xfb, 0x3c, 0x4f, 0x9d, 0x05, 0x9a, 0x4b, 0x6b, -0x88, 0xb3, 0x74, 0xca, 0xac, 0x9d, 0x76, 0x00, 0x58, 0x97, 0x69, 0x0d, 0x98, 0xe3, 0x40, 0x42, -0xfc, 0xe8, 0x42, 0x38, 0xae, 0x04, 0x3b, 0xc1, 0x96, 0xf1, 0xd9, 0x19, 0x92, 0xc4, 0xb5, 0xeb, -0x39, 0xd0, 0x7a, 0x5a, 0x3e, 0xf0, 0x0d, 0xba, 0x2f, 0x1e, 0x6e, 0xc7, 0xe4, 0x46, 0xe6, 0x3d, -0x7c, 0x08, 0x6b, 0xea, 0xff, 0xf1, 0x78, 0xdf, 0x3b, 0xe9, 0xcb, 0x06, 0x5e, 0x30, 0xbd, 0x47, -0xe3, 0x5c, 0xe2, 0x18, 0x01, 0xa5, 0xd5, 0x80, 0x74, 0x4e, 0x93, 0xe5, 0x86, 0xdb, 0x7c, 0x5f, -0x0d, 0xd2, 0x6b, 0xdc, 0xa9, 0x91, 0x24, 0x2c, 0x09, 0x4f, 0xd1, 0xfa, 0xab, 0x96, 0x99, 0x2b, -0x91, 0xda, 0xe1, 0x69, 0x6f, 0xd8, 0x1b, 0x28, 0x73, 0xb2, 0x51, 0xfa, 0xcf, 0xa7, 0x9e -}; - -static unsigned char hi_rsa_pub[] = -{ -0x99, 0x02, 0x0d, 0x04, 0x52, 0x82, 0x2c, 0xee, 0x01, 0x10, 0x00, 0xbe, 0x0d, 0x60, 0xa0, 0x12, -0x2f, 0x3c, 0x6a, 0x72, 0x29, 0x61, 0x26, 0xdd, 0x2e, 0x4e, 0x62, 0xad, 0xa6, 0xb3, 0x2b, 0x45, -0x94, 0x94, 0x99, 0x2a, 0x6e, 0xd0, 0xda, 0x5f, 0xf6, 0x99, 0xee, 0xbe, 0x0e, 0x10, 0x42, 0xea, -0x0b, 0x44, 0xac, 0x76, 0x06, 0x0b, 0x30, 0xd0, 0x2e, 0xd9, 0xe9, 0x2d, 0xfb, 0x5a, 0x3f, 0xfb, -0xb5, 0xbc, 0xea, 0x8a, 0x2a, 0xfa, 0xe9, 0xef, 0x77, 0x94, 0x81, 0xc6, 0xbb, 0x4b, 0x12, 0x78, -0xf3, 0xfe, 0x06, 0x93, 0x37, 0xa7, 0x38, 0x52, 0xab, 0xaa, 0xa3, 0xb4, 0x11, 0xbe, 0x5e, 0x77, -0xdd, 0xe4, 0x98, 0x4c, 0x74, 0x4e, 0x1c, 0x62, 0xa8, 0x7a, 0x65, 0x6b, 0x09, 0xd7, 0x29, 0xae, -0xaf, 0xe9, 0x7f, 0x94, 0x07, 0x01, 0x76, 0xfb, 0x7d, 0x2c, 0xf8, 0xe5, 0xce, 0x33, 0xb2, 0x7e, -0x4c, 0x28, 0x41, 0x2c, 0xba, 0x73, 0x83, 0x2f, 0x61, 0x5e, 0xd9, 0x5c, 0xa6, 0x44, 0x54, 0x40, -0xae, 0x7c, 0xa8, 0x0b, 0x01, 0x0f, 0x84, 0x1f, 0xfe, 0x72, 0x06, 0x51, 0xda, 0x15, 0x88, 0xa4, -0x9e, 0x85, 0x06, 0x21, 0x2c, 0xe4, 0xe7, 0x2a, 0x04, 0x66, 0x3c, 0x31, 0x13, 0x02, 0x08, 0x1f, -0x6c, 0x9b, 0xab, 0x97, 0xf8, 0x29, 0x51, 0xb5, 0x85, 0x76, 0x53, 0x83, 0x1f, 0x08, 0x46, 0xe7, -0x03, 0x96, 0xa2, 0x64, 0x8a, 0xef, 0xc2, 0x52, 0xd8, 0x7e, 0xb9, 0x96, 0xc7, 0xbe, 0xbe, 0x81, -0x4f, 0x22, 0x6a, 0xa6, 0xa9, 0xf8, 0x68, 0x11, 0x72, 0xb1, 0x5d, 0x5b, 0xe4, 0xc2, 0xeb, 0x09, -0xb3, 0xb7, 0x0d, 0xc9, 0x1b, 0xfe, 0x39, 0x7b, 0x45, 0x96, 0xec, 0xd6, 0x37, 0x34, 0x4d, 0x1d, -0xcc, 0x86, 0xfa, 0x2b, 0x69, 0x9c, 0x67, 0x55, 0x55, 0x56, 0xb4, 0x68, 0xf2, 0x0c, 0xf2, 0x84, -0xd8, 0x27, 0x53, 0x4d, 0xae, 0xb1, 0xec, 0x5e, 0xdc, 0x24, 0x09, 0xb9, 0x2b, 0x3d, 0x28, 0x79, -0xa0, 0x5d, 0x14, 0x4a, 0xe7, 0xff, 0x8b, 0x6f, 0xdf, 0xaf, 0x8b, 0x01, 0xc0, 0xac, 0xb6, 0xfb, -0x6f, 0x98, 0xca, 0x20, 0x89, 0x22, 0x4e, 0x7d, 0x20, 0x62, 0x2a, 0xa0, 0x7c, 0xe2, 0xf4, 0xa7, -0x1c, 0xfa, 0x3f, 0xc8, 0x8e, 0xd0, 0x54, 0x07, 0x73, 0xec, 0x8c, 0xb5, 0x4b, 0x4c, 0x50, 0x38, -0x86, 0x27, 0x53, 0x39, 0x9f, 0x71, 0x3c, 0x5e, 0xd4, 0x03, 0x59, 0x22, 0x24, 0x62, 0x5d, 0x28, -0x1b, 0x69, 0x75, 0x98, 0xfe, 0x01, 0xc2, 0x8c, 0x12, 0xc0, 0x25, 0x9c, 0x1e, 0xa0, 0x89, 0x15, -0x26, 0x19, 0x15, 0x76, 0x2d, 0xdc, 0x69, 0x44, 0x49, 0x3e, 0x2d, 0xca, 0x1a, 0x14, 0x98, 0xf4, -0x12, 0x52, 0xff, 0x38, 0x2e, 0x46, 0xfc, 0xed, 0x01, 0x4d, 0x40, 0x8a, 0x39, 0x57, 0x8e, 0x65, -0xe9, 0x26, 0x0e, 0x27, 0x8a, 0x10, 0x99, 0x5d, 0x1f, 0xbd, 0xec, 0xbc, 0x63, 0xf8, 0x85, 0xcf, -0xa0, 0x34, 0xb8, 0xe9, 0xd5, 0x4b, 0xf1, 0x4a, 0x47, 0xe7, 0xbe, 0x27, 0x9e, 0xe8, 0x3f, 0x96, -0xcd, 0x6d, 0x11, 0x03, 0xd3, 0x08, 0xab, 0xdf, 0x32, 0x59, 0x16, 0x9c, 0xda, 0x68, 0xd7, 0x5d, -0x30, 0x48, 0xbe, 0xa3, 0xe4, 0x0d, 0x95, 0xde, 0x5b, 0x54, 0xee, 0x10, 0x39, 0x5a, 0xc8, 0xb4, -0x82, 0xde, 0x1c, 0xe5, 0x32, 0xc0, 0x73, 0x31, 0x3a, 0x25, 0xfe, 0xae, 0x1c, 0xca, 0x0d, 0x6d, -0x5e, 0xf2, 0x1b, 0x95, 0x18, 0x88, 0xc3, 0x0a, 0x21, 0xc3, 0x5e, 0x0d, 0x2f, 0xc0, 0x30, 0xf5, -0x53, 0xee, 0x0b, 0x0d, 0xb1, 0x99, 0x52, 0x47, 0xf0, 0x26, 0x4a, 0xfa, 0x61, 0x15, 0x2a, 0xbb, -0xc4, 0x60, 0x23, 0xbe, 0x21, 0x2f, 0xff, 0x21, 0x34, 0x64, 0xb0, 0x17, 0x28, 0x61, 0x31, 0xf8, -0xe4, 0xb2, 0x00, 0x3e, 0xb6, 0x89, 0x5f, 0x19, 0x03, 0x2e, 0x67, 0x00, 0x11, 0x01, 0x00, 0x01, -0xb4, 0x22, 0x47, 0x4e, 0x55, 0x20, 0x47, 0x52, 0x55, 0x42, 0x20, 0x52, 0x53, 0x41, 0x20, 0x73, -0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, -0x20, 0x6b, 0x65, 0x79, 0x89, 0x02, 0x38, 0x04, 0x13, 0x01, 0x02, 0x00, 0x22, 0x05, 0x02, 0x52, -0x82, 0x2c, 0xee, 0x02, 0x1b, 0x03, 0x06, 0x0b, 0x09, 0x08, 0x07, 0x03, 0x02, 0x06, 0x15, 0x08, -0x02, 0x09, 0x0a, 0x0b, 0x04, 0x16, 0x02, 0x03, 0x01, 0x02, 0x1e, 0x01, 0x02, 0x17, 0x80, 0x00, -0x0a, 0x09, 0x10, 0x0f, 0xcc, 0xf3, 0x21, 0x77, 0x83, 0x6a, 0x0d, 0x14, 0x0a, 0x0f, 0xff, 0x45, -0x11, 0xf5, 0x1a, 0x37, 0x13, 0xe8, 0x9a, 0x51, 0x1d, 0x77, 0x67, 0xa4, 0x71, 0xf1, 0x74, 0xaa, -0xcf, 0xc7, 0xab, 0x34, 0x11, 0x01, 0x9b, 0xab, 0x45, 0x6d, 0xf6, 0x5e, 0xd4, 0x74, 0x42, 0x37, -0x22, 0x8b, 0x8b, 0xb3, 0xf1, 0x36, 0x33, 0x25, 0xf0, 0x7d, 0x9b, 0xa7, 0xb6, 0x9b, 0x4e, 0xc2, -0x22, 0xab, 0x02, 0x66, 0x60, 0x4a, 0xd3, 0xe9, 0xcb, 0xe6, 0xde, 0x72, 0x7a, 0x33, 0x62, 0x84, -0x5e, 0x7b, 0xd8, 0x1f, 0xce, 0x7d, 0x37, 0x17, 0xee, 0xbe, 0x4b, 0x31, 0xe2, 0x1a, 0xf9, 0x8e, -0x9b, 0xec, 0xc2, 0x9f, 0x35, 0xa6, 0x28, 0xc1, 0x81, 0x76, 0xdd, 0x0d, 0xaf, 0xc3, 0x62, 0xe8, -0xf3, 0xa5, 0xd0, 0x4c, 0x10, 0x4c, 0xa4, 0x0b, 0x3e, 0xab, 0xd7, 0xcf, 0x7d, 0x99, 0x5a, 0x44, -0xdd, 0xda, 0x62, 0x22, 0x41, 0x7f, 0x3f, 0x92, 0x9f, 0x49, 0xb0, 0xb7, 0x2d, 0x01, 0x1f, 0xbc, -0xc9, 0xf7, 0x0a, 0xab, 0xe3, 0xe6, 0x17, 0xac, 0x4b, 0xcf, 0x65, 0x6d, 0xae, 0x51, 0x3d, 0xf1, -0x0c, 0x94, 0x07, 0xfe, 0xc2, 0x4c, 0x10, 0x95, 0x5c, 0x9b, 0xfd, 0xfe, 0xed, 0x05, 0x4a, 0xfe, -0xdf, 0xe6, 0x21, 0x12, 0x6f, 0x37, 0x5e, 0x52, 0xee, 0x15, 0x0b, 0x18, 0xf7, 0x74, 0x39, 0xac, -0xab, 0x31, 0xfa, 0x52, 0x4c, 0x72, 0xa5, 0xb0, 0x5e, 0xc5, 0x69, 0xf2, 0x20, 0xd5, 0x0b, 0x4c, -0x4c, 0xe8, 0xf0, 0xbc, 0xf6, 0x4f, 0x33, 0x75, 0x64, 0xcf, 0x93, 0x1b, 0x01, 0xdb, 0x02, 0xfb, -0x81, 0x42, 0xa0, 0x24, 0x18, 0x21, 0x16, 0xb0, 0xe5, 0x3b, 0x22, 0xe4, 0xd7, 0x91, 0x1e, 0x07, -0x37, 0x36, 0x52, 0x22, 0x8e, 0x49, 0x7a, 0xcf, 0xf2, 0x85, 0x20, 0x09, 0xc2, 0xc5, 0x31, 0x6b, -0xcd, 0xe1, 0x87, 0x8b, 0xc1, 0xae, 0x20, 0x27, 0xa8, 0x59, 0x9f, 0x37, 0xc3, 0xe0, 0xbf, 0x40, -0xe9, 0x9c, 0xe2, 0x77, 0xca, 0xa8, 0x5e, 0x46, 0x20, 0x88, 0xbd, 0x45, 0xbf, 0x60, 0xa7, 0x40, -0x80, 0x28, 0x74, 0xd6, 0x34, 0x4c, 0xd4, 0x5c, 0x60, 0x1e, 0xf9, 0xbc, 0xa7, 0x6a, 0x8d, 0x08, -0x99, 0xec, 0xb6, 0x5c, 0xdb, 0x1f, 0xf9, 0xe0, 0x06, 0x26, 0x1d, 0x04, 0x6f, 0x1d, 0x84, 0x0c, -0x8b, 0x6e, 0x8d, 0x06, 0xc0, 0x83, 0x2b, 0x7c, 0xdf, 0x2c, 0x4a, 0xac, 0x2d, 0xe4, 0xcd, 0xa4, -0x55, 0xd1, 0xcd, 0x54, 0x8a, 0xaa, 0x04, 0x53, 0x23, 0xa8, 0x9c, 0x67, 0x28, 0xa7, 0x11, 0x76, -0xd3, 0x2f, 0x17, 0x2a, 0x40, 0xac, 0x06, 0xe1, 0x47, 0x30, 0xd0, 0x9c, 0xba, 0x9c, 0x9c, 0xaf, -0x22, 0xe0, 0x68, 0xa5, 0x72, 0xf0, 0xf1, 0x8c, 0xe3, 0xbe, 0xc6, 0xed, 0xfa, 0xad, 0x72, 0xf8, -0xab, 0x49, 0x5e, 0x4d, 0xed, 0x88, 0x41, 0xb2, 0x7c, 0x95, 0x69, 0x63, 0x1c, 0xd8, 0x90, 0x9d, -0xc6, 0x4a, 0x42, 0x30, 0x91, 0x7b, 0x58, 0x30, 0xfa, 0x32, 0xf6, 0xd6, 0xc2, 0xe9, 0x74, 0xfa, -0xe8, 0x81, 0x3d, 0xdc, 0xb6, 0x3f, 0xbc, 0x88, 0x3e, 0x01, 0xbc, 0x47, 0x75, 0x36, 0xf0, 0x28, -0x4f, 0x14, 0xd6, 0xa1, 0xc5, 0x3d, 0xb2, 0x74, 0x82, 0xfd, 0xad, 0x94, 0xb3, 0x14, 0x16, 0x61, -0xef, 0x77, 0x77, 0x25, 0x03, 0xc1, 0x8e, 0x71, 0x55, 0xa5, 0x31, 0x40, 0x50, 0x49, 0x3f, 0xf5, -0x40, 0x7f, 0x97, 0x4f, 0xef, 0x47, 0xa2, 0x12, 0x0c, 0x1d, 0x23, 0x51, 0x47, 0x53, 0x0b, 0x72, -0xc2, 0xd3, 0x39, 0xbb, 0xa9, 0xea, 0x8c, 0x16, 0x93, 0x67, 0xb1, 0xcf, 0x8a, 0x96, 0xba, 0x1e, -0xef, 0x20, 0x3f, 0xee, 0xda, 0x69, 0xd1, 0x4d, 0xf4, 0x9c, 0x41, 0x73, 0xcb, 0xaf, 0x1b, 0x29, -0x22, 0x1f, 0x94, 0xa4, 0x67, 0xd7, 0x53, 0xb1, 0x65, 0x23, 0x69, 0x05, 0x31, 0x2e, 0xd4 -}; - -static unsigned char hi_dsa_sig[] = -{ -0x88, 0x5e, 0x04, 0x00, 0x11, 0x08, 0x00, 0x06, 0x05, 0x02, 0x52, 0x82, 0x2c, 0x7f, 0x00, 0x0a, -0x09, 0x10, 0xef, 0xe0, 0xfc, 0x1f, 0xf6, 0xe7, 0xf5, 0xad, 0xb0, 0x47, 0x01, 0x00, 0xcd, 0xfd, -0x1f, 0x8b, 0x16, 0x7f, 0x31, 0x7f, 0xc3, 0xe1, 0x6d, 0xcd, 0xc5, 0x4f, 0xf4, 0x1b, 0xf5, 0x4e, -0x61, 0x79, 0xb5, 0x14, 0xdd, 0xf5, 0xe5, 0x27, 0x21, 0xf6, 0xc7, 0x95, 0xc6, 0x9b, 0x00, 0xff, -0x61, 0x4d, 0x01, 0x6f, 0xbb, 0x88, 0xf9, 0x38, 0x84, 0x00, 0xab, 0xab, 0x2f, 0x16, 0x53, 0x5c, -0xe9, 0x3d, 0x85, 0x34, 0x0d, 0x36, 0x80, 0x77, 0x62, 0x4e, 0x4f, 0xdb, 0x48, 0x64, 0x58, 0x82 -}; - -static unsigned char hi_dsa_pub[] = -{ -0x99, 0x04, 0xae, 0x04, 0x52, 0x82, 0x2b, 0xe6, 0x11, 0x0c, 0x00, 0xcc, 0x6b, 0xfe, 0xc3, 0xed, -0x23, 0xb8, 0x09, 0xa8, 0xcd, 0x00, 0x8a, 0xd7, 0x4d, 0xe5, 0x37, 0x03, 0xab, 0x99, 0x64, 0xc5, -0xde, 0xef, 0x47, 0xfd, 0x06, 0xe1, 0xc2, 0x70, 0x77, 0x5f, 0x78, 0x46, 0x62, 0x9e, 0x5e, 0x84, -0x48, 0xdf, 0xc2, 0xef, 0xd3, 0xf3, 0xc3, 0x97, 0x92, 0x83, 0xa7, 0xad, 0xf7, 0x4e, 0x43, 0xac, -0x06, 0xcb, 0x18, 0x4b, 0xe4, 0x05, 0x45, 0x01, 0x3d, 0x34, 0x51, 0x59, 0xf5, 0xfb, 0x42, 0xad, -0xe5, 0x7c, 0xf4, 0xe3, 0xd6, 0x6d, 0x4e, 0xd7, 0x3d, 0xbc, 0x87, 0x0b, 0x94, 0xe7, 0x70, 0x55, -0x3c, 0x7c, 0xef, 0x1e, 0x9c, 0xa1, 0x0b, 0x17, 0x8c, 0x0d, 0x62, 0x08, 0x8f, 0x5a, 0x93, 0x2a, -0x0e, 0xde, 0xad, 0x7d, 0x60, 0xe7, 0x5c, 0xe7, 0xf3, 0xb0, 0x2f, 0xef, 0xc1, 0xc9, 0x5f, 0x71, -0xf9, 0xa7, 0x33, 0x30, 0x78, 0x3a, 0xb2, 0x83, 0xd9, 0xe5, 0xc1, 0x6b, 0xb4, 0xaa, 0x13, 0xe0, -0xdb, 0x2a, 0xd8, 0x81, 0xfc, 0x96, 0xd6, 0x3a, 0x73, 0xba, 0x34, 0xe4, 0xf8, 0xc1, 0xf5, 0xac, -0x2e, 0x4c, 0x95, 0x52, 0x28, 0x03, 0xe7, 0x01, 0xc8, 0x5e, 0x1c, 0x1c, 0xbd, 0xd3, 0xe5, 0xf8, -0xf2, 0xc5, 0xbf, 0x61, 0x01, 0x22, 0x3c, 0x57, 0xd5, 0x6a, 0x17, 0x29, 0x3e, 0x00, 0xfc, 0xb4, -0x97, 0x7f, 0x45, 0xa4, 0x6c, 0x53, 0xd5, 0xd2, 0x56, 0xce, 0x4f, 0x1b, 0xcf, 0xc2, 0x0b, 0x83, -0x09, 0xf6, 0xc1, 0x95, 0xea, 0x2a, 0x47, 0xe0, 0xa6, 0x8e, 0xc5, 0x74, 0x6e, 0x8e, 0xa4, 0x10, -0x3a, 0x99, 0xfb, 0x9e, 0xcc, 0x06, 0xa7, 0x70, 0xef, 0xe8, 0xf6, 0x72, 0xba, 0xd4, 0x0c, 0x11, -0x47, 0x17, 0x6b, 0x2d, 0xde, 0xa1, 0xfd, 0x41, 0x87, 0x18, 0x33, 0x6c, 0x26, 0xd2, 0xdc, 0xc7, -0x8f, 0x4f, 0x91, 0xc1, 0x02, 0x38, 0x42, 0xe5, 0x35, 0xaf, 0xef, 0x90, 0xde, 0x94, 0xa3, 0x3c, -0xde, 0x61, 0x67, 0xb3, 0x26, 0xe2, 0xfc, 0x2d, 0x96, 0x35, 0xfd, 0x00, 0xb1, 0x02, 0xe7, 0xb4, -0xd4, 0xf4, 0xb7, 0x67, 0xaa, 0xd4, 0x00, 0xfa, 0xcf, 0x9b, 0xbe, 0xbb, 0xad, 0xac, 0x8e, 0xe3, -0xab, 0xf1, 0x80, 0xaf, 0xe2, 0xb1, 0x93, 0x09, 0xd0, 0x40, 0xde, 0xab, 0x53, 0xcf, 0xa7, 0x45, -0x1a, 0x8b, 0xdb, 0x0f, 0xff, 0xd4, 0xdf, 0x6b, 0xe9, 0x2c, 0x40, 0x8e, 0x24, 0x03, 0x62, 0x75, -0x0f, 0x2c, 0x8b, 0x8e, 0x9e, 0xd0, 0x91, 0x5a, 0x91, 0x68, 0xcb, 0x16, 0x45, 0xca, 0x8f, 0xdd, -0x5e, 0x61, 0x71, 0xa7, 0x8d, 0xa3, 0xf4, 0xf7, 0xa3, 0xee, 0x5d, 0x4c, 0x8a, 0xee, 0x5b, 0x5f, -0x1e, 0xfc, 0xbe, 0x3d, 0x94, 0xab, 0x30, 0x02, 0x6f, 0x72, 0x57, 0x03, 0x2a, 0xaf, 0x9c, 0x28, -0x12, 0x55, 0x00, 0xd5, 0x0a, 0x2a, 0x02, 0x4e, 0xf0, 0xc0, 0x67, 0x01, 0x00, 0xd3, 0xaf, 0x3f, -0xcf, 0x8c, 0x64, 0x59, 0x9d, 0xe5, 0x7b, 0x0b, 0xa0, 0xa0, 0x46, 0xb3, 0xc0, 0xf6, 0x25, 0xde, -0x2d, 0xfa, 0x27, 0xf6, 0xf1, 0xca, 0x3c, 0xd3, 0x56, 0x6e, 0xc0, 0xd4, 0x49, 0x0b, 0xfc, 0x0f, -0x23, 0xbf, 0xe1, 0x00, 0x63, 0xb5, 0x04, 0x40, 0x04, 0x5c, 0x9e, 0xce, 0x0b, 0x75, 0xca, 0xfe, -0xd9, 0xb7, 0xe1, 0xcc, 0x27, 0x20, 0xf4, 0x4c, 0x61, 0x10, 0x17, 0x2b, 0xb7, 0x5d, 0x0d, 0xc2, -0xac, 0x37, 0x4e, 0x7f, 0x81, 0x4a, 0xde, 0x06, 0x6f, 0xb7, 0x61, 0xcc, 0x9e, 0xdd, 0x6a, 0x3e, -0x88, 0x55, 0x66, 0x8a, 0x87, 0xc1, 0x26, 0xf3, 0xe2, 0xd8, 0xdf, 0x80, 0xfa, 0x82, 0x6f, 0x25, -0x89, 0x94, 0xe7, 0xff, 0x79, 0xb6, 0x08, 0x5e, 0x45, 0x46, 0x9a, 0x74, 0xde, 0xa8, 0xa3, 0xc8, -0x8f, 0x6f, 0x8f, 0x8e, 0xf5, 0x1f, 0xab, 0x3d, 0x21, 0xd5, 0xec, 0x34, 0x86, 0x6c, 0xbd, 0x92, -0x44, 0x9d, 0x73, 0x46, 0xcb, 0xa0, 0x5c, 0x05, 0xd5, 0x12, 0xf0, 0xe9, 0xc7, 0x65, 0xa7, 0xe3, -0x4d, 0x82, 0x8f, 0x54, 0x7e, 0x7b, 0x51, 0x46, 0xca, 0x50, 0x22, 0x24, 0x2e, 0x90, 0x5e, 0x33, -0xd7, 0x0f, 0xca, 0x42, 0x82, 0x7e, 0x74, 0x20, 0xae, 0x49, 0xa4, 0x0a, 0xc5, 0x90, 0xd5, 0xf8, -0x45, 0x32, 0x5f, 0xda, 0xf8, 0xf5, 0xb0, 0xa2, 0x43, 0x77, 0x7a, 0x65, 0xf9, 0x59, 0xaa, 0x91, -0xe1, 0xd9, 0x7f, 0xbc, 0x8c, 0xa6, 0xb6, 0x71, 0x68, 0xc3, 0xe5, 0x36, 0xee, 0xa3, 0x47, 0xe0, -0x4f, 0x48, 0xb3, 0xf1, 0x8d, 0x41, 0xb0, 0xbc, 0x14, 0xb0, 0x15, 0x21, 0x35, 0xc3, 0x2c, 0xc7, -0x37, 0x23, 0x03, 0xb9, 0xfb, 0xb9, 0xdc, 0x7b, 0x7a, 0x89, 0x44, 0x01, 0x1b, 0xa7, 0x87, 0x5f, -0xe2, 0xc1, 0x02, 0x53, 0xcd, 0xd5, 0x56, 0xcd, 0x8c, 0x56, 0x6d, 0xa6, 0x90, 0xf6, 0x26, 0xff, -0x8e, 0x6d, 0x5f, 0x60, 0x9e, 0x8f, 0x2c, 0x71, 0xa5, 0xff, 0xd9, 0x77, 0x67, 0x9e, 0x09, 0x93, -0xa4, 0x7c, 0x23, 0x1d, 0x55, 0x18, 0x5a, 0x54, 0x41, 0x88, 0x8e, 0x2d, 0xc6, 0x87, 0x67, 0x43, -0xd4, 0x3d, 0xaf, 0x85, 0x3b, 0xda, 0x46, 0x02, 0x4a, 0x33, 0x46, 0x62, 0x1e, 0x9e, 0x66, 0xc9, -0x5a, 0x96, 0xf8, 0xa9, 0xbd, 0x4a, 0x81, 0x92, 0x40, 0x9e, 0xc3, 0xa5, 0x3d, 0x99, 0xc5, 0xf1, -0xd7, 0x6d, 0xc9, 0x29, 0x7d, 0x2c, 0xdf, 0x1e, 0xc9, 0xe4, 0x6d, 0x83, 0xd1, 0xc4, 0xaa, 0x9f, -0xe3, 0x0e, 0x0a, 0x87, 0x49, 0x89, 0x6a, 0xc0, 0xc7, 0x73, 0x19, 0x91, 0x2d, 0xa5, 0x0b, 0xbf, -0x4f, 0x52, 0x46, 0x54, 0xd7, 0x9c, 0x97, 0x77, 0x32, 0xab, 0xd3, 0x74, 0x14, 0x9d, 0xbc, 0xa9, -0x4a, 0xd9, 0x5f, 0x8b, 0xd7, 0xf8, 0x63, 0xf4, 0x3e, 0xde, 0x79, 0x8a, 0xae, 0x65, 0x0c, 0x18, -0xe3, 0x8d, 0x21, 0x7d, 0x95, 0x59, 0xf1, 0xe0, 0xb6, 0xa3, 0x52, 0xa3, 0x46, 0x91, 0x94, 0x31, -0x0e, 0x6c, 0xb3, 0x84, 0xa2, 0x26, 0x49, 0x06, 0xb7, 0x2b, 0x4c, 0x93, 0xf3, 0x60, 0xaa, 0x0c, -0x00, 0x97, 0x4f, 0x05, 0x06, 0xc3, 0x97, 0x32, 0x4b, 0xbe, 0x18, 0x84, 0x7a, 0x51, 0x1b, 0xb0, -0xe6, 0x94, 0x3a, 0xd7, 0x7b, 0xa8, 0xd0, 0x21, 0x19, 0x54, 0x78, 0x19, 0x2b, 0xe5, 0xc6, 0x92, -0xb7, 0xc5, 0x1e, 0x72, 0x33, 0x78, 0xe8, 0x13, 0x11, 0x14, 0x43, 0x9e, 0x3c, 0x6b, 0x3f, 0x25, -0x67, 0xe4, 0x6e, 0x5e, 0xe0, 0x7a, 0x3c, 0x06, 0xdc, 0x2e, 0x06, 0x6e, 0x9c, 0x8e, 0xf0, 0xc6, -0xfb, 0xc6, 0x2d, 0x63, 0x1b, 0x4f, 0x66, 0x72, 0x7d, 0xc9, 0x0e, 0x38, 0xc4, 0x17, 0x07, 0x49, -0xc9, 0x7d, 0xab, 0x3a, 0xed, 0xf2, 0xeb, 0xeb, 0x6d, 0xa7, 0xb0, 0x97, 0x88, 0x08, 0x0d, 0x0b, -0xdc, 0x07, 0x32, 0xe2, 0x62, 0xf5, 0x4e, 0x46, 0xe7, 0x13, 0x85, 0x01, 0x92, 0xee, 0x26, 0x67, -0x0d, 0xb0, 0x85, 0xa8, 0xa1, 0x26, 0x49, 0x14, 0xa3, 0xde, 0x95, 0xd7, 0xeb, 0xcf, 0x85, 0xb2, -0xdf, 0x3f, 0x76, 0x16, 0x75, 0x20, 0x47, 0xb1, 0x80, 0x04, 0x1e, 0x2f, 0xa2, 0xde, 0xb2, 0x5f, -0x50, 0x83, 0xd2, 0x45, 0xad, 0x8d, 0x08, 0xf4, 0xe2, 0xfb, 0xac, 0x13, 0x2b, 0x6f, 0x3a, 0xfe, -0xa7, 0x18, 0xfc, 0x11, 0xe0, 0x46, 0xdd, 0x53, 0x82, 0x3b, 0xd4, 0x0b, 0xf2, 0xec, 0x6c, 0xd0, -0xbd, 0xea, 0xdf, 0xfa, 0xd2, 0x52, 0xf8, 0xa5, 0x4a, 0x49, 0xae, 0x2f, 0x1e, 0xb0, 0x9d, 0x61, -0x7a, 0x26, 0x6f, 0x0e, 0x97, 0xe6, 0x74, 0xa8, 0x39, 0x51, 0x6d, 0xe6, 0x4a, 0xbf, 0x7f, 0xb1, -0x4f, 0xa1, 0x2e, 0xaf, 0x1d, 0x0c, 0x20, 0x69, 0xac, 0xd1, 0x0c, 0xa0, 0x5e, 0x97, 0x8f, 0xa0, -0x9c, 0x22, 0x72, 0x96, 0x05, 0x34, 0xf2, 0x7c, 0xc8, 0xda, 0x71, 0x00, 0xf4, 0x82, 0x5f, 0xac, -0x36, 0x8e, 0x2b, 0xf7, 0xa6, 0xac, 0x94, 0x97, 0x75, 0xef, 0x8b, 0xfa, 0xaf, 0xb7, 0x19, 0x7f, -0x10, 0xaa, 0x38, 0x11, 0x2b, 0x81, 0x81, 0xbf, 0x78, 0x93, 0xa7, 0x8e, 0xda, 0x57, 0xc8, 0xfc, -0xbc, 0x85, 0xa6, 0x26, 0x0b, 0xcd, 0xce, 0xbf, 0xa5, 0x3f, 0x29, 0x03, 0x85, 0x2d, 0xd4, 0xa0, -0x26, 0xad, 0x9c, 0x9a, 0x6b, 0xb3, 0x01, 0xd0, 0x1c, 0x7a, 0xf2, 0x48, 0x31, 0x04, 0x40, 0x09, -0x02, 0x0b, 0xe3, 0x3c, 0x65, 0xf5, 0x39, 0xae, 0x25, 0x2e, 0x42, 0xa3, 0x43, 0x50, 0x80, 0xbb, -0x36, 0x4c, 0xf9, 0x04, 0xec, 0x52, 0x37, 0xc1, 0x00, 0x92, 0x4a, 0x5a, 0x56, 0xfb, 0x50, 0x54, -0x26, 0x3c, 0xa5, 0x3a, 0x22, 0x4f, 0x6b, 0x17, 0x5b, 0x64, 0xd5, 0xfd, 0xa4, 0x1b, 0x32, 0x22, -0x16, 0x97, 0x0e, 0xfd, 0x92, 0xae, 0x5e, 0xd0, 0x5b, 0x4b, 0xf9, 0x26, 0x2e, 0x46, 0x12, 0x8d, -0x91, 0x80, 0xe8, 0x71, 0xbf, 0xf7, 0xc2, 0x8e, 0xed, 0x60, 0xd2, 0x17, 0x53, 0xd1, 0x8b, 0xc9, -0x08, 0xb4, 0x1d, 0x47, 0x4e, 0x55, 0x20, 0x47, 0x52, 0x55, 0x42, 0x20, 0x44, 0x53, 0x41, 0x20, -0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x6b, 0x65, 0x79, -0x88, 0x7a, 0x04, 0x13, 0x11, 0x08, 0x00, 0x22, 0x05, 0x02, 0x52, 0x82, 0x2b, 0xe6, 0x02, 0x1b, -0x03, 0x06, 0x0b, 0x09, 0x08, 0x07, 0x03, 0x02, 0x06, 0x15, 0x08, 0x02, 0x09, 0x0a, 0x0b, 0x04, -0x16, 0x02, 0x03, 0x01, 0x02, 0x1e, 0x01, 0x02, 0x17, 0x80, 0x00, 0x0a, 0x09, 0x10, 0xef, 0xe0, -0xfc, 0x1f, 0xf6, 0xe7, 0xf5, 0xad, 0xd6, 0x91, 0x01, 0x00, 0x94, 0x10, 0x43, 0xf9, 0xc9, 0x37, -0x40, 0x47, 0xe1, 0xba, 0xf7, 0x92, 0x4b, 0xe1, 0xea, 0x94, 0xee, 0x81, 0x90, 0x8f, 0xe7, 0x76, -0xc8, 0x30, 0x3d, 0x7e, 0xa0, 0xf5, 0xad, 0x2a, 0x52, 0x60, 0x00, 0xff, 0x75, 0x6c, 0x2d, 0xf5, -0xab, 0x41, 0x83, 0x29, 0x4f, 0x37, 0x16, 0x1b, 0x26, 0x28, 0x55, 0x03, 0xfe, 0x30, 0x89, 0xce, -0x70, 0x6e, 0x1a, 0x11, 0x4a, 0xb6, 0xa5, 0x17, 0x9f, 0xbe, 0x3d, 0x1d -}; diff --git a/grub-core/tests/sleep_test.c b/grub-core/tests/sleep_test.c deleted file mode 100644 index ffb268114..000000000 --- a/grub-core/tests/sleep_test.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static void -sleep_test (void) -{ - struct grub_datetime st, en; - grub_int64_t stu = 0, enu = 0; - int is_delayok; - grub_test_assert (!grub_get_datetime (&st), "Couldn't retrieve start time"); - grub_millisleep (10000); - grub_test_assert (!grub_get_datetime (&en), "Couldn't retrieve end time"); - grub_test_assert (grub_datetime2unixtime (&st, &stu), "Invalid date"); - grub_test_assert (grub_datetime2unixtime (&en, &enu), "Invalid date"); - is_delayok = (enu - stu >= 9 && enu - stu <= 11); -#ifdef __arm__ - /* Ignore QEMU bug */ - if (enu - stu >= 15 && enu - stu <= 17) - is_delayok = 1; -#endif - grub_test_assert (is_delayok, "Interval out of range: %" PRIdGRUB_INT64_T, enu - stu); -} - -GRUB_FUNCTIONAL_TEST (sleep_test, sleep_test); diff --git a/grub-core/tests/strtoull_test.c b/grub-core/tests/strtoull_test.c deleted file mode 100644 index 5488ab26b..000000000 --- a/grub-core/tests/strtoull_test.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2016 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static void -strtoull_testcase (const char *input, int base, unsigned long long expected, - int num_digits, grub_err_t error) -{ - const char *output; - unsigned long long value; - grub_errno = 0; - value = grub_strtoull(input, &output, base); - grub_test_assert (grub_errno == error, - "unexpected error. Expected %d, got %d. Input \"%s\"", - error, grub_errno, input); - if (grub_errno) - { - grub_errno = 0; - return; - } - grub_test_assert (input + num_digits == output, - "unexpected number of digits. Expected %d, got %d, input \"%s\"", - num_digits, (int) (output - input), input); - grub_test_assert (value == expected, - "unexpected return value. Expected %llu, got %llu, input \"\%s\"", - expected, value, input); -} - -static void -strtoull_test (void) -{ - strtoull_testcase ("9", 0, 9, 1, GRUB_ERR_NONE); - strtoull_testcase ("0xaa", 0, 0xaa, 4, GRUB_ERR_NONE); - strtoull_testcase ("0xff", 0, 0xff, 4, GRUB_ERR_NONE); - strtoull_testcase ("0", 10, 0, 1, GRUB_ERR_NONE); - strtoull_testcase ("8", 8, 0, 0, GRUB_ERR_BAD_NUMBER); - strtoull_testcase ("38", 8, 3, 1, GRUB_ERR_NONE); - strtoull_testcase ("7", 8, 7, 1, GRUB_ERR_NONE); - strtoull_testcase ("1]", 16, 1, 1, GRUB_ERR_NONE); - strtoull_testcase ("18446744073709551616", 10, 0, 0, GRUB_ERR_OUT_OF_RANGE); -} - - -GRUB_FUNCTIONAL_TEST (strtoull_test, strtoull_test); diff --git a/grub-core/tests/video_checksum.c b/grub-core/tests/video_checksum.c deleted file mode 100644 index 39053e0eb..000000000 --- a/grub-core/tests/video_checksum.c +++ /dev/null @@ -1,813 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -/* All tests need to include test.h for GRUB testing framework. */ - -#include - -#include -#include -#include -#include -#include -#include -#ifdef GRUB_MACHINE_EMU -#include -#include -#endif - -GRUB_MOD_LICENSE ("GPLv3+"); - -static int ctr; -static int nchk; -static char *basename; -static const grub_uint32_t *checksums; -static struct grub_video_mode_info capt_mode_info; - -struct grub_video_mode_info grub_test_video_modes[GRUB_TEST_VIDEO_ALL_N_MODES] = { - { - .width = 640, - .height = 480, - .pitch = 640, - .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, - .bpp = 8, - .bytes_per_pixel = 1, - .number_of_colors = GRUB_VIDEO_FBSTD_NUMCOLORS - }, - { - .width = 800, - .height = 600, - .pitch = 800, - .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, - .bpp = 8, - .bytes_per_pixel = 1, - .number_of_colors = GRUB_VIDEO_FBSTD_NUMCOLORS - }, - { - .width = 1024, - .height = 768, - .pitch = 1024, - .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, - .bpp = 8, - .bytes_per_pixel = 1, - .number_of_colors = GRUB_VIDEO_FBSTD_NUMCOLORS - }, - { - .width = 640, - .height = 480, - .pitch = 640 * 4, - GRUB_VIDEO_MI_RGBA8888() - }, - { - .width = 800, - .height = 600, - .pitch = 800 * 4, - GRUB_VIDEO_MI_RGBA8888() - }, - { - .width = 1024, - .height = 768, - .pitch = 1024 * 4, - GRUB_VIDEO_MI_RGBA8888() - }, - { - .width = 2560, - .height = 1440, - .pitch = 2560 * 4, - GRUB_VIDEO_MI_RGBA8888() - }, - { - .width = 640, - .height = 480, - .pitch = 640, - .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, - .bpp = 8, - .bytes_per_pixel = 1, - .number_of_colors = GRUB_VIDEO_FBSTD_EXT_NUMCOLORS - }, - { - .width = 800, - .height = 600, - .pitch = 800, - .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, - .bpp = 8, - .bytes_per_pixel = 1, - .number_of_colors = GRUB_VIDEO_FBSTD_EXT_NUMCOLORS - }, - { - .width = 1024, - .height = 768, - .pitch = 1024, - .mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, - .bpp = 8, - .bytes_per_pixel = 1, - .number_of_colors = GRUB_VIDEO_FBSTD_EXT_NUMCOLORS - }, - - - - - { - .width = 640, - .height = 480, - .pitch = 1280, - GRUB_VIDEO_MI_RGB555 () - }, - { - .width = 800, - .height = 600, - .pitch = 1600, - GRUB_VIDEO_MI_RGB555 () - }, - { - .width = 1024, - .height = 768, - .pitch = 2048, - GRUB_VIDEO_MI_RGB555 () - }, - { - .width = 640, - .height = 480, - .pitch = 1280, - GRUB_VIDEO_MI_RGB565 () - }, - { - .width = 800, - .height = 600, - .pitch = 1600, - GRUB_VIDEO_MI_RGB565 () - }, - { - .width = 1024, - .height = 768, - .pitch = 2048, - GRUB_VIDEO_MI_RGB565 () - }, - { - .width = 640, - .height = 480, - .pitch = 640 * 3, - GRUB_VIDEO_MI_RGB888 () - }, - { - .width = 800, - .height = 600, - .pitch = 800 * 3, - GRUB_VIDEO_MI_RGB888 () - }, - { - .width = 1024, - .height = 768, - .pitch = 1024 * 3, - GRUB_VIDEO_MI_RGB888 () - }, - { - .width = 640, - .height = 480, - .pitch = 1280, - GRUB_VIDEO_MI_BGR555 () - }, - { - .width = 800, - .height = 600, - .pitch = 1600, - GRUB_VIDEO_MI_BGR555 () - }, - { - .width = 1024, - .height = 768, - .pitch = 2048, - GRUB_VIDEO_MI_BGR555 () - }, - { - .width = 640, - .height = 480, - .pitch = 1280, - GRUB_VIDEO_MI_BGR565 () - }, - { - .width = 800, - .height = 600, - .pitch = 1600, - GRUB_VIDEO_MI_BGR565 () - }, - { - .width = 1024, - .height = 768, - .pitch = 2048, - GRUB_VIDEO_MI_BGR565 () - }, - { - .width = 640, - .height = 480, - .pitch = 640 * 3, - GRUB_VIDEO_MI_BGR888 () - }, - { - .width = 800, - .height = 600, - .pitch = 800 * 3, - GRUB_VIDEO_MI_BGR888 () - }, - { - .width = 1024, - .height = 768, - .pitch = 1024 * 3, - GRUB_VIDEO_MI_BGR888 () - }, - { - .width = 640, - .height = 480, - .pitch = 640 * 4, - GRUB_VIDEO_MI_BGRA8888() - }, - { - .width = 800, - .height = 600, - .pitch = 800 * 4, - GRUB_VIDEO_MI_BGRA8888() - }, - { - .width = 1024, - .height = 768, - .pitch = 1024 * 4, - GRUB_VIDEO_MI_BGRA8888() - }, -}; - -#ifdef GRUB_MACHINE_EMU -#include - -struct bmp_header -{ - grub_uint8_t magic[2]; - grub_uint32_t filesize; - grub_uint32_t reserved; - grub_uint32_t bmp_off; - grub_uint32_t head_size; - grub_uint16_t width; - grub_uint16_t height; - grub_uint16_t planes; - grub_uint16_t bpp; -} GRUB_PACKED; - -static void -grub_video_capture_write_bmp (const char *fname, - void *ptr, - const struct grub_video_mode_info *mode_info) -{ - grub_util_fd_t fd = grub_util_fd_open (fname, GRUB_UTIL_FD_O_WRONLY | GRUB_UTIL_FD_O_CREATTRUNC); - struct bmp_header head; - - if (!GRUB_UTIL_FD_IS_VALID (fd)) - { - grub_printf (_("cannot open `%s': %s"), - fname, grub_util_fd_strerror ()); - } - - grub_memset (&head, 0, sizeof (head)); - - head.magic[0] = 'B'; - head.magic[1] = 'M'; - - if (mode_info->mode_type & GRUB_VIDEO_MODE_TYPE_RGB) - { - head.filesize = grub_cpu_to_le32 (sizeof (head) + mode_info->width * mode_info->height * 3); - head.bmp_off = grub_cpu_to_le32_compile_time (sizeof (head)); - head.bpp = grub_cpu_to_le16_compile_time (24); - } - else - { - head.filesize = grub_cpu_to_le32 (sizeof (head) + 3 * 256 + mode_info->width * mode_info->height); - head.bmp_off = grub_cpu_to_le32_compile_time (sizeof (head) + 3 * 256); - head.bpp = grub_cpu_to_le16_compile_time (8); - } - head.head_size = grub_cpu_to_le32_compile_time (sizeof (head) - 14); - head.width = grub_cpu_to_le16 (mode_info->width); - head.height = grub_cpu_to_le16 (mode_info->height); - head.planes = grub_cpu_to_le16_compile_time (1); - - head.width = grub_cpu_to_le16 (mode_info->width); - head.height = grub_cpu_to_le16 (mode_info->height); - - grub_util_fd_write (fd, (char *) &head, sizeof (head)); - - if (!(mode_info->mode_type & GRUB_VIDEO_MODE_TYPE_RGB)) - { - struct grub_video_palette_data palette_data[256]; - int i; - int palette_len = mode_info->number_of_colors; - grub_memset (palette_data, 0, sizeof (palette_data)); - if (palette_len > 256) - palette_len = 256; - grub_video_get_palette (0, palette_len, palette_data); - for (i = 0; i < 256; i++) - { - grub_uint8_t r, g, b; - r = palette_data[i].r; - g = palette_data[i].g; - b = palette_data[i].b; - - grub_util_fd_write (fd, (char *) &b, 1); - grub_util_fd_write (fd, (char *) &g, 1); - grub_util_fd_write (fd, (char *) &r, 1); - } - } - - /* This does essentialy the same as some fbblit functions yet using - them would mean testing them against themselves so keep this - implemetation separate. */ - switch (mode_info->bytes_per_pixel) - { - case 4: - { - grub_uint8_t *buffer = xcalloc (3, mode_info->width); - grub_uint32_t rmask = ((1 << mode_info->red_mask_size) - 1); - grub_uint32_t gmask = ((1 << mode_info->green_mask_size) - 1); - grub_uint32_t bmask = ((1 << mode_info->blue_mask_size) - 1); - int rshift = mode_info->red_field_pos; - int gshift = mode_info->green_field_pos; - int bshift = mode_info->blue_field_pos; - int mulrshift = (8 - mode_info->red_mask_size); - int mulgshift = (8 - mode_info->green_mask_size); - int mulbshift = (8 - mode_info->blue_mask_size); - int y; - - for (y = mode_info->height - 1; y >= 0; y--) - { - grub_uint32_t *iptr = (grub_uint32_t *) ptr + (mode_info->pitch / 4) * y; - int x; - grub_uint8_t *optr = buffer; - for (x = 0; x < (int) mode_info->width; x++) - { - grub_uint32_t val = *iptr++; - *optr++ = ((val >> bshift) & bmask) << mulbshift; - *optr++ = ((val >> gshift) & gmask) << mulgshift; - *optr++ = ((val >> rshift) & rmask) << mulrshift; - } - grub_util_fd_write (fd, (char *) buffer, mode_info->width * 3); - } - grub_free (buffer); - break; - } - case 3: - { - grub_uint8_t *buffer = xcalloc (3, mode_info->width); - grub_uint32_t rmask = ((1 << mode_info->red_mask_size) - 1); - grub_uint32_t gmask = ((1 << mode_info->green_mask_size) - 1); - grub_uint32_t bmask = ((1 << mode_info->blue_mask_size) - 1); - int rshift = mode_info->red_field_pos; - int gshift = mode_info->green_field_pos; - int bshift = mode_info->blue_field_pos; - int mulrshift = (8 - mode_info->red_mask_size); - int mulgshift = (8 - mode_info->green_mask_size); - int mulbshift = (8 - mode_info->blue_mask_size); - int y; - - for (y = mode_info->height - 1; y >= 0; y--) - { - grub_uint8_t *iptr = ((grub_uint8_t *) ptr + mode_info->pitch * y); - int x; - grub_uint8_t *optr = buffer; - for (x = 0; x < (int) mode_info->width; x++) - { - grub_uint32_t val = 0; -#ifdef GRUB_CPU_WORDS_BIGENDIAN - val |= *iptr++ << 16; - val |= *iptr++ << 8; - val |= *iptr++; -#else - val |= *iptr++; - val |= *iptr++ << 8; - val |= *iptr++ << 16; -#endif - *optr++ = ((val >> bshift) & bmask) << mulbshift; - *optr++ = ((val >> gshift) & gmask) << mulgshift; - *optr++ = ((val >> rshift) & rmask) << mulrshift; - } - grub_util_fd_write (fd, (char *) buffer, mode_info->width * 3); - } - grub_free (buffer); - break; - } - case 2: - { - grub_uint8_t *buffer = xcalloc (3, mode_info->width); - grub_uint16_t rmask = ((1 << mode_info->red_mask_size) - 1); - grub_uint16_t gmask = ((1 << mode_info->green_mask_size) - 1); - grub_uint16_t bmask = ((1 << mode_info->blue_mask_size) - 1); - int rshift = mode_info->red_field_pos; - int gshift = mode_info->green_field_pos; - int bshift = mode_info->blue_field_pos; - int mulrshift = (8 - mode_info->red_mask_size); - int mulgshift = (8 - mode_info->green_mask_size); - int mulbshift = (8 - mode_info->blue_mask_size); - int y; - - for (y = mode_info->height - 1; y >= 0; y--) - { - grub_uint16_t *iptr = (grub_uint16_t *) ptr + (mode_info->pitch / 2) * y; - int x; - grub_uint8_t *optr = buffer; - for (x = 0; x < (int) mode_info->width; x++) - { - grub_uint16_t val = *iptr++; - *optr++ = ((val >> bshift) & bmask) << mulbshift; - *optr++ = ((val >> gshift) & gmask) << mulgshift; - *optr++ = ((val >> rshift) & rmask) << mulrshift; - } - grub_util_fd_write (fd, (char *) buffer, mode_info->width * 3); - } - grub_free (buffer); - break; - } - case 1: - { - int y; - - for (y = mode_info->height - 1; y >= 0; y--) - grub_util_fd_write (fd, ((char *) ptr + mode_info->pitch * y), - mode_info->width); - break; - } - } - grub_util_fd_close (fd); -} - -#endif - -const char * -grub_video_checksum_get_modename (void) -{ - static char buf[40]; - if (capt_mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) - { - grub_snprintf (buf, sizeof (buf), "i%d", capt_mode_info.number_of_colors); - return buf; - } - if (capt_mode_info.red_field_pos == 0) - { - grub_snprintf (buf, sizeof (buf), "bgra%d%d%d%d", capt_mode_info.blue_mask_size, - capt_mode_info.green_mask_size, - capt_mode_info.red_mask_size, - capt_mode_info.reserved_mask_size); - return buf; - } - grub_snprintf (buf, sizeof (buf), "rgba%d%d%d%d", capt_mode_info.red_mask_size, - capt_mode_info.green_mask_size, - capt_mode_info.blue_mask_size, - capt_mode_info.reserved_mask_size); - return buf; -} - -#define GENERATE_MODE 1 -//#define SAVE_ALL_IMAGES -//#define COLLECT_TIME_STATISTICS 1 - -#if defined (GENERATE_MODE) && defined (GRUB_MACHINE_EMU) -grub_util_fd_t genfd = GRUB_UTIL_FD_INVALID; -#endif - -#include - -static void -write_time (void) -{ -#if defined (GRUB_MACHINE_EMU) && defined (COLLECT_TIME_STATISTICS) - char buf[60]; - static grub_uint64_t prev; - grub_uint64_t cur; - static grub_util_fd_t tmrfd = GRUB_UTIL_FD_INVALID; - if (!GRUB_UTIL_FD_IS_VALID (tmrfd)) - tmrfd = grub_util_fd_open ("time.txt", GRUB_UTIL_FD_O_WRONLY - | GRUB_UTIL_FD_O_CREATTRUNC); - - cur = grub_util_get_cpu_time_ms (); - grub_snprintf (buf, sizeof (buf), "%s_%dx%dx%s:%d: %" PRIuGRUB_UINT64_T " ms\n", - basename, - capt_mode_info.width, - capt_mode_info.height, - grub_video_checksum_get_modename (), ctr, - cur - prev); - prev = cur; - if (GRUB_UTIL_FD_IS_VALID (tmrfd)) - grub_util_fd_write (tmrfd, buf, grub_strlen (buf)); -#endif -} - - -static void -checksum (void) -{ - void *ptr; - grub_uint32_t crc = 0; - - ptr = grub_video_capture_get_framebuffer (); - - write_time (); - -#ifdef GRUB_CPU_WORDS_BIGENDIAN - switch (capt_mode_info.bytes_per_pixel) - { - case 1: - crc = grub_getcrc32c (0, ptr, capt_mode_info.pitch - * capt_mode_info.height); - break; - case 2: - { - unsigned x, y, rowskip; - grub_uint8_t *iptr = ptr; - crc = 0; - rowskip = capt_mode_info.pitch - capt_mode_info.width * 2; - for (y = 0; y < capt_mode_info.height; y++) - { - for (x = 0; x < capt_mode_info.width; x++) - { - crc = grub_getcrc32c (crc, iptr + 1, 1); - crc = grub_getcrc32c (crc, iptr, 1); - iptr += 2; - } - crc = grub_getcrc32c (crc, iptr, rowskip); - iptr += rowskip; - } - break; - } - case 3: - { - unsigned x, y, rowskip; - grub_uint8_t *iptr = ptr; - crc = 0; - rowskip = capt_mode_info.pitch - capt_mode_info.width * 3; - for (y = 0; y < capt_mode_info.height; y++) - { - for (x = 0; x < capt_mode_info.width; x++) - { - crc = grub_getcrc32c (crc, iptr + 2, 1); - crc = grub_getcrc32c (crc, iptr + 1, 1); - crc = grub_getcrc32c (crc, iptr, 1); - iptr += 3; - } - crc = grub_getcrc32c (crc, iptr, rowskip); - iptr += rowskip; - } - break; - } - case 4: - { - unsigned x, y, rowskip; - grub_uint8_t *iptr = ptr; - crc = 0; - rowskip = capt_mode_info.pitch - capt_mode_info.width * 4; - for (y = 0; y < capt_mode_info.height; y++) - { - for (x = 0; x < capt_mode_info.width; x++) - { - crc = grub_getcrc32c (crc, iptr + 3, 1); - crc = grub_getcrc32c (crc, iptr + 2, 1); - crc = grub_getcrc32c (crc, iptr + 1, 1); - crc = grub_getcrc32c (crc, iptr, 1); - iptr += 4; - } - crc = grub_getcrc32c (crc, iptr, rowskip); - iptr += rowskip; - } - break; - } - } -#else - crc = grub_getcrc32c (0, ptr, capt_mode_info.pitch * capt_mode_info.height); -#endif - -#if defined (GENERATE_MODE) && defined (GRUB_MACHINE_EMU) - if (GRUB_UTIL_FD_IS_VALID (genfd)) - { - char buf[20]; - grub_snprintf (buf, sizeof (buf), "0x%x, ", crc); - grub_util_fd_write (genfd, buf, grub_strlen (buf)); - } -#endif - - if (!checksums || ctr >= nchk) - { - grub_test_assert (0, "Unexpected checksum %s_%dx%dx%s:%d: 0x%x", - basename, - capt_mode_info.width, - capt_mode_info.height, - grub_video_checksum_get_modename (), ctr, crc); - } - else if (crc != checksums[ctr]) - { - grub_test_assert (0, "Checksum %s_%dx%dx%s:%d failed: 0x%x vs 0x%x", - basename, - capt_mode_info.width, - capt_mode_info.height, - grub_video_checksum_get_modename (), - ctr, crc, checksums[ctr]); - } -#if !(defined (SAVE_ALL_IMAGES) && defined (GRUB_MACHINE_EMU)) - else - { - write_time (); - ctr++; - return; - } -#endif -#ifdef GRUB_MACHINE_EMU - char *name = grub_xasprintf ("%s_%dx%dx%s_%d.bmp", basename, - capt_mode_info.width, - capt_mode_info.height, - grub_video_checksum_get_modename (), - ctr); - grub_video_capture_write_bmp (name, ptr, &capt_mode_info); - grub_free (name); -#endif - - write_time (); - - ctr++; -} - -struct checksum_desc -{ - const char *name; - unsigned width; - unsigned height; - unsigned mode_type; - unsigned number_of_colors; - unsigned bpp; - unsigned bytes_per_pixel; - unsigned red_field_pos; - unsigned red_mask_size; - unsigned green_field_pos; - unsigned green_mask_size; - unsigned blue_field_pos; - unsigned blue_mask_size; - unsigned reserved_field_pos; - unsigned reserved_mask_size; - const grub_uint32_t *checksums; - int nchk; -}; - -const struct checksum_desc checksum_table[] = { -#include "checksums.h" -}; - -void -grub_video_checksum (const char *basename_in) -{ - unsigned i; - - grub_video_get_info (&capt_mode_info); - -#if defined (GENERATE_MODE) && defined (GRUB_MACHINE_EMU) - if (!GRUB_UTIL_FD_IS_VALID (genfd)) - genfd = grub_util_fd_open ("checksums.h", GRUB_UTIL_FD_O_WRONLY - | GRUB_UTIL_FD_O_CREATTRUNC); - if (GRUB_UTIL_FD_IS_VALID (genfd)) - { - char buf[400]; - - grub_snprintf (buf, sizeof (buf), "\", %d, %d, 0x%x, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d /* %dx%dx%s */, (grub_uint32_t []) { ", - capt_mode_info.width, - capt_mode_info.height, - capt_mode_info.mode_type, - capt_mode_info.number_of_colors, - capt_mode_info.bpp, - capt_mode_info.bytes_per_pixel, - capt_mode_info.red_field_pos, - capt_mode_info.red_mask_size, - capt_mode_info.green_field_pos, - capt_mode_info.green_mask_size, - capt_mode_info.blue_field_pos, - capt_mode_info.blue_mask_size, - capt_mode_info.reserved_field_pos, - capt_mode_info.reserved_mask_size, - capt_mode_info.width, - capt_mode_info.height, - grub_video_checksum_get_modename ()); - - grub_util_fd_write (genfd, " { \"", 5); - grub_util_fd_write (genfd, basename_in, grub_strlen (basename_in)); - grub_util_fd_write (genfd, buf, grub_strlen (buf)); - } -#endif - - basename = grub_strdup (basename_in); - nchk = 0; - checksums = 0; - /* FIXME: optimize this. */ - for (i = 0; i < ARRAY_SIZE (checksum_table); i++) - if (grub_strcmp (checksum_table[i].name, basename_in) == 0 - && capt_mode_info.width == checksum_table[i].width - && capt_mode_info.height == checksum_table[i].height - && capt_mode_info.mode_type == checksum_table[i].mode_type - && capt_mode_info.number_of_colors == checksum_table[i].number_of_colors - && capt_mode_info.bpp == checksum_table[i].bpp - && capt_mode_info.bytes_per_pixel == checksum_table[i].bytes_per_pixel - && capt_mode_info.red_field_pos == checksum_table[i].red_field_pos - && capt_mode_info.red_mask_size == checksum_table[i].red_mask_size - && capt_mode_info.green_field_pos == checksum_table[i].green_field_pos - && capt_mode_info.green_mask_size == checksum_table[i].green_mask_size - && capt_mode_info.blue_field_pos == checksum_table[i].blue_field_pos - && capt_mode_info.blue_mask_size == checksum_table[i].blue_mask_size - && capt_mode_info.reserved_field_pos == checksum_table[i].reserved_field_pos - && capt_mode_info.reserved_mask_size == checksum_table[i].reserved_mask_size) - { - nchk = checksum_table[i].nchk; - checksums = checksum_table[i].checksums; - break; - } - - ctr = 0; - grub_video_capture_refresh_cb = checksum; -} - -void -grub_video_checksum_end (void) -{ -#if defined (GENERATE_MODE) && defined (GRUB_MACHINE_EMU) - if (GRUB_UTIL_FD_IS_VALID (genfd)) - { - char buf[40]; - grub_snprintf (buf, sizeof (buf), "}, %d },\n", ctr); - grub_util_fd_write (genfd, buf, grub_strlen (buf)); - } -#endif - grub_test_assert (ctr == nchk, "Not enough checksums %s_%dx%dx%s: %d vs %d", - basename, - capt_mode_info.width, - capt_mode_info.height, - grub_video_checksum_get_modename (), - ctr, nchk); - grub_free (basename); - basename = 0; - nchk = 0; - checksums = 0; - ctr = 0; - grub_video_capture_refresh_cb = 0; -} - -static struct grub_term_output *saved_outputs; -static struct grub_term_output *saved_gfxnext; -static struct grub_term_output *gfxterm; -static int use_gfxterm = 0; - -int -grub_test_use_gfxterm (void) -{ - FOR_ACTIVE_TERM_OUTPUTS (gfxterm) - if (grub_strcmp (gfxterm->name, "gfxterm") == 0) - break; - if (!gfxterm) - FOR_DISABLED_TERM_OUTPUTS (gfxterm) - if (grub_strcmp (gfxterm->name, "gfxterm") == 0) - break; - - if (!gfxterm) - { - grub_test_assert (0, "terminal `%s' isn't found", "gfxterm"); - return 1; - } - - if (gfxterm->init (gfxterm)) - { - grub_test_assert (0, "terminal `%s' failed: %s", "gfxterm", grub_errmsg); - return 1; - } - - saved_outputs = grub_term_outputs; - saved_gfxnext = gfxterm->next; - grub_term_outputs = gfxterm; - gfxterm->next = 0; - use_gfxterm = 1; - - return 0; -} - -void -grub_test_use_gfxterm_end (void) -{ - if (!use_gfxterm) - return; - use_gfxterm = 0; - gfxterm->fini (gfxterm); - gfxterm->next = saved_gfxnext; - grub_term_outputs = saved_outputs; - saved_outputs = 0; - saved_gfxnext = 0; -} diff --git a/grub-core/tests/videotest_checksum.c b/grub-core/tests/videotest_checksum.c deleted file mode 100644 index a4bff5ed8..000000000 --- a/grub-core/tests/videotest_checksum.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -/* All tests need to include test.h for GRUB testing framework. */ -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define FONT_NAME "Unknown Regular 16" - -/* Functional test main method. */ -static void -videotest_checksum (void) -{ - unsigned i; - grub_font_t font; - - font = grub_font_get (FONT_NAME); - if (font && grub_strcmp (font->name, FONT_NAME) != 0) - font = 0; - if (!font) - font = grub_font_load ("unicode"); - - if (!font) - { - grub_test_assert (0, "unicode font not found: %s", grub_errmsg); - return; - } - - for (i = 0; i < ARRAY_SIZE (grub_test_video_modes); i++) - { - grub_err_t err; -#if defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_IEEE1275) - if (grub_test_video_modes[i].width > 1024) - continue; -#endif - err = grub_video_capture_start (&grub_test_video_modes[i], - grub_video_fbstd_colors, - grub_test_video_modes[i].number_of_colors); - if (err) - { - grub_test_assert (0, "can't start capture: %s", grub_errmsg); - grub_print_error (); - continue; - } - grub_terminal_input_fake_sequence ((int []) { '\n' }, 1); - - grub_video_checksum ("videotest"); - - char *args[] = { 0 }; - grub_command_execute ("videotest", 0, args); - - grub_terminal_input_fake_sequence_end (); - grub_video_checksum_end (); - grub_video_capture_end (); - } -} - -/* Register example_test method as a functional test. */ -GRUB_FUNCTIONAL_TEST (videotest_checksum, videotest_checksum); diff --git a/grub-core/tests/xnu_uuid_test.c b/grub-core/tests/xnu_uuid_test.c deleted file mode 100644 index d500145f9..000000000 --- a/grub-core/tests/xnu_uuid_test.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static void -xnu_uuid_test (void) -{ - grub_command_t cmd; - cmd = grub_command_find ("xnu_uuid"); - char *args[] = { (char *) "fedcba98", (char *) "tstvar", NULL }; - const char *val; - - if (!cmd) - { - grub_test_assert (0, "can't find command `%s'", "xnu_uuid"); - return; - } - if ((cmd->func) (cmd, 2, args)) - { - grub_test_assert (0, "%d: %s", grub_errno, grub_errmsg); - return; - } - - val = grub_env_get ("tstvar"); - if (!val) - { - grub_test_assert (0, "tstvar isn't set"); - return; - } - grub_test_assert (grub_strcmp (val, "944F9DED-DBED-391C-9402-77C8CEE04173") - == 0, "UUIDs don't match"); -} - -GRUB_FUNCTIONAL_TEST (xnu_uuid_test, xnu_uuid_test); diff --git a/grub-core/video/bitmap_scale.c b/grub-core/video/bitmap_scale.c deleted file mode 100644 index 70c32f029..000000000 --- a/grub-core/video/bitmap_scale.c +++ /dev/null @@ -1,515 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* 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); - -static grub_err_t -verify_source_bitmap (struct grub_video_bitmap *src) -{ - /* Verify the simplifying assumptions. */ - if (src == 0) - return grub_error (GRUB_ERR_BUG, - "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_BUG, - "src format not supported for scale"); - if (src->mode_info.width == 0 || src->mode_info.height == 0) - return grub_error (GRUB_ERR_BUG, - "source bitmap has a zero dimension"); - if (src->mode_info.bytes_per_pixel * 8 != src->mode_info.bpp) - return grub_error (GRUB_ERR_BUG, - "bitmap to scale has inconsistent Bpp and bpp"); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_bitmap_scale (struct grub_video_bitmap *dst, - struct grub_video_bitmap *src, - enum grub_video_bitmap_scale_method scale_method) -{ - switch (scale_method) - { - case GRUB_VIDEO_BITMAP_SCALE_METHOD_FASTEST: - case GRUB_VIDEO_BITMAP_SCALE_METHOD_NEAREST: - return scale_nn (dst, src); - case GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST: - case GRUB_VIDEO_BITMAP_SCALE_METHOD_BILINEAR: - return scale_bilinear (dst, src); - default: - return grub_error (GRUB_ERR_BUG, "Invalid scale_method value"); - } -} - -/* 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; - - grub_err_t err = verify_source_bitmap(src); - if (err != GRUB_ERR_NONE) - return err; - if (dst_width <= 0 || dst_height <= 0) - return grub_error (GRUB_ERR_BUG, - "requested to scale to a size w/ a zero dimension"); - - /* 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. */ - - ret = grub_video_bitmap_scale (*dst, src, scale_method); - - 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; - } -} - -static grub_err_t -make_h_align (unsigned *x, unsigned *w, unsigned new_w, - grub_video_bitmap_h_align_t h_align) -{ - grub_err_t ret = GRUB_ERR_NONE; - if (new_w >= *w) - { - *x = 0; - *w = new_w; - return GRUB_ERR_NONE; - } - switch (h_align) - { - case GRUB_VIDEO_BITMAP_H_ALIGN_LEFT: - *x = 0; - break; - case GRUB_VIDEO_BITMAP_H_ALIGN_CENTER: - *x = (*w - new_w) / 2; - break; - case GRUB_VIDEO_BITMAP_H_ALIGN_RIGHT: - *x = *w - new_w; - break; - default: - ret = grub_error (GRUB_ERR_BUG, "Invalid h_align value"); - break; - } - *w = new_w; - return ret; -} - -static grub_err_t -make_v_align (unsigned *y, unsigned *h, unsigned new_h, - grub_video_bitmap_v_align_t v_align) -{ - grub_err_t ret = GRUB_ERR_NONE; - if (new_h >= *h) - { - *y = 0; - *h = new_h; - return GRUB_ERR_NONE; - } - switch (v_align) - { - case GRUB_VIDEO_BITMAP_V_ALIGN_TOP: - *y = 0; - break; - case GRUB_VIDEO_BITMAP_V_ALIGN_CENTER: - *y = (*h - new_h) / 2; - break; - case GRUB_VIDEO_BITMAP_V_ALIGN_BOTTOM: - *y = *h - new_h; - break; - default: - ret = grub_error (GRUB_ERR_BUG, "Invalid v_align value"); - break; - } - *h = new_h; - return ret; -} - -grub_err_t -grub_video_bitmap_scale_proportional (struct grub_video_bitmap **dst, - int dst_width, int dst_height, - struct grub_video_bitmap *src, - enum grub_video_bitmap_scale_method - scale_method, - grub_video_bitmap_selection_method_t - selection_method, - grub_video_bitmap_v_align_t v_align, - grub_video_bitmap_h_align_t h_align) -{ - *dst = 0; - grub_err_t ret = verify_source_bitmap(src); - if (ret != GRUB_ERR_NONE) - return ret; - if (dst_width <= 0 || dst_height <= 0) - return grub_error (GRUB_ERR_BUG, - "requested to scale to a size w/ a zero dimension"); - - ret = grub_video_bitmap_create (dst, dst_width, dst_height, - src->mode_info.blit_format); - if (ret != GRUB_ERR_NONE) - return ret; /* Error. */ - - unsigned dx0 = 0; - unsigned dy0 = 0; - unsigned dw = dst_width; - unsigned dh = dst_height; - unsigned sx0 = 0; - unsigned sy0 = 0; - unsigned sw = src->mode_info.width; - unsigned sh = src->mode_info.height; - - switch (selection_method) - { - case GRUB_VIDEO_BITMAP_SELECTION_METHOD_CROP: - /* Comparing sw/sh VS dw/dh. */ - if (sw * dh < dw * sh) - ret = make_v_align (&sy0, &sh, sw * dh / dw, v_align); - else - ret = make_h_align (&sx0, &sw, sh * dw / dh, h_align); - break; - case GRUB_VIDEO_BITMAP_SELECTION_METHOD_PADDING: - if (sw * dh < dw * sh) - ret = make_h_align (&dx0, &dw, sw * dh / sh, h_align); - else - ret = make_v_align (&dy0, &dh, sh * dw / sw, v_align); - break; - case GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITWIDTH: - if (sw * dh < dw * sh) - ret = make_v_align (&sy0, &sh, sw * dh / dw, v_align); - else - ret = make_v_align (&dy0, &dh, sh * dw / sw, v_align); - break; - case GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITHEIGHT: - if (sw * dh < dw * sh) - ret = make_h_align (&dx0, &dw, sw * dh / sh, h_align); - else - ret = make_h_align (&sx0, &sw, sh * dw / dh, h_align); - break; - default: - ret = grub_error (GRUB_ERR_BUG, "Invalid selection_method value"); - break; - } - - if (ret == GRUB_ERR_NONE) - { - /* Backup original data. */ - int src_width_orig = src->mode_info.width; - int src_height_orig = src->mode_info.height; - grub_uint8_t *src_data_orig = src->data; - int dst_width_orig = (*dst)->mode_info.width; - int dst_height_orig = (*dst)->mode_info.height; - grub_uint8_t *dst_data_orig = (*dst)->data; - - 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 = src->mode_info.bytes_per_pixel; - - /* Crop src and dst. */ - src->mode_info.width = sw; - src->mode_info.height = sh; - src->data = (grub_uint8_t *) src->data + sx0 * bytes_per_pixel - + sy0 * sstride; - (*dst)->mode_info.width = dw; - (*dst)->mode_info.height = dh; - (*dst)->data = (grub_uint8_t *) (*dst)->data + dx0 * bytes_per_pixel - + dy0 * dstride; - - /* Scale our image. */ - ret = grub_video_bitmap_scale (*dst, src, scale_method); - - /* Restore original data. */ - src->mode_info.width = src_width_orig; - src->mode_info.height = src_height_orig; - src->data = src_data_orig; - (*dst)->mode_info.width = dst_width_orig; - (*dst)->mode_info.height = dst_height_orig; - (*dst)->data = dst_data_orig; - } - - 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; - } -} - -static grub_err_t -verify_bitmaps (struct grub_video_bitmap *dst, struct grub_video_bitmap *src) -{ - /* Verify the simplifying assumptions. */ - if (dst == 0 || src == 0) - return grub_error (GRUB_ERR_BUG, "null bitmap in scale function"); - 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_BUG, - "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_BUG, - "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_BUG, - "dst and src not compatible"); - if (dst->mode_info.bytes_per_pixel != src->mode_info.bytes_per_pixel) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "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_BUG, "bitmap has a zero dimension"); - - return GRUB_ERR_NONE; -} - -/* 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) -{ - grub_err_t err = verify_bitmaps(dst, src); - if (err != GRUB_ERR_NONE) - return err; - - grub_uint8_t *ddata = dst->data; - grub_uint8_t *sdata = src->data; - unsigned dw = dst->mode_info.width; - unsigned dh = dst->mode_info.height; - unsigned sw = src->mode_info.width; - unsigned 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; - unsigned dy, sy, ystep, yfrac, yover; - unsigned sx, xstep, xfrac, xover; - grub_uint8_t *dptr, *dline_end, *sline; - - xstep = sw / dw; - xover = sw % dw; - ystep = sh / dh; - yover = sh % dh; - - for (dy = 0, sy = 0, yfrac = 0; dy < dh; dy++, sy += ystep, yfrac += yover) - { - if (yfrac >= dh) - { - yfrac -= dh; - sy++; - } - dptr = ddata + dy * dstride; - dline_end = dptr + dw * bytes_per_pixel; - sline = sdata + sy * sstride; - for (sx = 0, xfrac = 0; dptr < dline_end; sx += xstep, xfrac += xover, dptr += bytes_per_pixel) - { - grub_uint8_t *sptr; - int comp; - - if (xfrac >= dw) - { - xfrac -= dw; - sx++; - } - - /* Get the address of the pixels in src and dst. */ - sptr = sline + 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) -{ - grub_err_t err = verify_bitmaps(dst, src); - if (err != GRUB_ERR_NONE) - return err; - - grub_uint8_t *ddata = dst->data; - grub_uint8_t *sdata = src->data; - unsigned dw = dst->mode_info.width; - unsigned dh = dst->mode_info.height; - unsigned sw = src->mode_info.width; - unsigned 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; - unsigned dy, syf, sy, ystep, yfrac, yover; - unsigned sxf, sx, xstep, xfrac, xover; - grub_uint8_t *dptr, *dline_end, *sline; - - xstep = (sw << 8) / dw; - xover = (sw << 8) % dw; - ystep = (sh << 8) / dh; - yover = (sh << 8) % dh; - - for (dy = 0, syf = 0, yfrac = 0; dy < dh; dy++, syf += ystep, yfrac += yover) - { - if (yfrac >= dh) - { - yfrac -= dh; - syf++; - } - sy = syf >> 8; - dptr = ddata + dy * dstride; - dline_end = dptr + dw * bytes_per_pixel; - sline = sdata + sy * sstride; - for (sxf = 0, xfrac = 0; dptr < dline_end; sxf += xstep, xfrac += xover, dptr += bytes_per_pixel) - { - grub_uint8_t *sptr; - int comp; - - if (xfrac >= dw) - { - xfrac -= dw; - sxf++; - } - - /* Get the address of the pixels in src and dst. */ - sx = sxf >> 8; - sptr = sline + 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. */ - unsigned u = sxf & 0xff; - unsigned v = syf & 0xff; - - for (comp = 0; comp < bytes_per_pixel; comp++) - { - /* Get the component's values for the - four source corner pixels. */ - unsigned f00 = sptr[comp]; - unsigned f10 = sptr[comp + bytes_per_pixel]; - unsigned f01 = sptr[comp + sstride]; - unsigned f11 = sptr[comp + sstride + bytes_per_pixel]; - - /* Count coeffecients. */ - unsigned c00 = (256 - u) * (256 - v); - unsigned c10 = u * (256 - v); - unsigned c01 = (256 - u) * v; - unsigned c11 = u * v; - - /* Interpolate. */ - unsigned fxy = c00 * f00 + c01 * f01 + c10 * f10 + c11 * f11; - fxy = fxy >> 16; - - 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/bochs.c b/grub-core/video/bochs.c deleted file mode 100644 index edc651697..000000000 --- a/grub-core/video/bochs.c +++ /dev/null @@ -1,439 +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 . - */ - -#define grub_video_render_target grub_video_fbrender_target - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static struct -{ - struct grub_video_mode_info mode_info; - - grub_uint8_t *ptr; - int mapped; - grub_uint32_t base; - grub_pci_device_t dev; -} framebuffer; - -#define BOCHS_APERTURE_SIZE 0x800000 -#define BOCHS_MAX_WIDTH 1600 -#define BOCHS_MAX_HEIGHT 1200 -#define BOCHS_WIDTH_ALIGN 8 - -enum - { - BOCHS_VBE_INDEX = 0x1ce, - BOCHS_VBE_DATA = 0x1cf, - }; - -enum - { - BOCHS_VBE_WIDTH = 1, - BOCHS_VBE_HEIGHT = 2, - BOCHS_VBE_BPP = 3, - BOCHS_VBE_ENABLE = 4, - BOCHS_VBE_Y_OFFSET = 9, - BOCHS_VBE_MAX - }; - -static void -vbe_write (grub_uint16_t val, grub_uint16_t addr) -{ - grub_outw (addr, BOCHS_VBE_INDEX); - grub_outw (val, BOCHS_VBE_DATA); -} - -static grub_uint16_t -vbe_read (grub_uint16_t addr) -{ - grub_outw (addr, BOCHS_VBE_INDEX); - return grub_inw (BOCHS_VBE_DATA); -} - -struct saved_state -{ - grub_uint8_t cr[256]; - grub_uint8_t gr[256]; - grub_uint8_t sr[256]; - grub_uint8_t r[256]; - grub_uint8_t g[256]; - grub_uint8_t b[256]; - grub_uint8_t vbe[BOCHS_VBE_MAX]; - int vbe_enable; - /* We need to preserve VGA font and VGA text. */ - grub_uint8_t vram[32 * 4 * 256]; -}; - -static struct saved_state initial_state; -static int state_saved = 0; - -static void -save_state (struct saved_state *st) -{ - unsigned i; - - for (i = 0; i < ARRAY_SIZE (st->cr); i++) - st->cr[i] = grub_vga_cr_read (i); - for (i = 0; i < ARRAY_SIZE (st->gr); i++) - st->gr[i] = grub_vga_gr_read (i); - for (i = 0; i < ARRAY_SIZE (st->sr); i++) - st->sr[i] = grub_vga_sr_read (i); - - for (i = 0; i < 256; i++) - grub_vga_palette_read (i, st->r + i, st->g + i, st->b + i); - - st->vbe_enable = vbe_read (BOCHS_VBE_ENABLE) & 1; - if (st->vbe_enable) - for (i = 0; i < ARRAY_SIZE (st->vbe); i++) - st->vbe[i] = vbe_read (i); - - grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4, GRUB_VGA_SR_MEMORY_MODE); - grub_memcpy (st->vram, framebuffer.ptr, sizeof (st->vram)); - grub_vga_sr_write (st->sr[GRUB_VGA_SR_MEMORY_MODE], GRUB_VGA_SR_MEMORY_MODE); -} - -static void -restore_state (struct saved_state *st) -{ - unsigned i; - - if (st->vbe_enable) - for (i = 0; i < ARRAY_SIZE (st->vbe); i++) - vbe_write (st->vbe[i], i); - else - vbe_write (0, BOCHS_VBE_ENABLE); - - grub_vga_cr_write (0, 0x11); - for (i = 0; i < ARRAY_SIZE (st->cr); i++) - grub_vga_cr_write (st->cr[i], i); - for (i = 0; i < ARRAY_SIZE (st->sr); i++) - grub_vga_sr_write (st->sr[i], i); - for (i = 0; i < ARRAY_SIZE (st->gr); i++) - grub_vga_gr_write (st->gr[i], i); - - for (i = 0; i < 256; i++) - grub_vga_palette_write (i, st->r[i], st->g[i], st->b[i]); - - grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4, GRUB_VGA_SR_MEMORY_MODE); - grub_memcpy (framebuffer.ptr, st->vram, sizeof (st->vram)); - grub_vga_sr_write (st->sr[GRUB_VGA_SR_MEMORY_MODE], GRUB_VGA_SR_MEMORY_MODE); -} - -static grub_err_t -grub_video_bochs_video_init (void) -{ - /* Reset frame buffer. */ - grub_memset (&framebuffer, 0, sizeof(framebuffer)); - - return grub_video_fb_init (); -} - -static grub_err_t -grub_video_bochs_video_fini (void) -{ - if (framebuffer.mapped) - grub_pci_device_unmap_range (framebuffer.dev, framebuffer.ptr, - BOCHS_APERTURE_SIZE); - - if (state_saved) - { - restore_state (&initial_state); - state_saved = 0; - } - - return grub_video_fb_fini (); -} - -static grub_err_t -doublebuf_pageflipping_set_page (int page) -{ - int start = framebuffer.mode_info.height * page; - - vbe_write (start, BOCHS_VBE_Y_OFFSET); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_bochs_set_palette (unsigned int start, unsigned int count, - struct grub_video_palette_data *palette_data) -{ - if (framebuffer.mode_info.mode_type == GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) - { - unsigned i; - if (start >= 0x100) - return GRUB_ERR_NONE; - if (start + count >= 0x100) - count = 0x100 - start; - - for (i = 0; i < count; i++) - grub_vga_palette_write (start + i, palette_data[i].r, palette_data[i].g, - palette_data[i].b); - } - - /* Then set color to emulated palette. */ - return grub_video_fb_set_palette (start, count, palette_data); -} - -/* Helper for grub_video_bochs_setup. */ -static int -find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) -{ - int *found = data; - 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 != 0x11111234) - return 0; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; - if (!framebuffer.base) - return 0; - *found = 1; - framebuffer.dev = dev; - - /* Enable address spaces. */ - addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_COMMAND); - grub_pci_write (addr, 0x7); - - return 1; -} - -static grub_err_t -grub_video_bochs_setup (unsigned int width, unsigned int height, - grub_video_mode_type_t mode_type, - grub_video_mode_type_t mode_mask) -{ - int depth; - grub_err_t err; - int found = 0; - int pitch, bytes_per_pixel; - grub_size_t page_size; /* The size of a page in bytes. */ - - /* 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 == 0 || height == 0) - { - width = 800; - height = 600; - } - - if (width > BOCHS_MAX_WIDTH) - return grub_error (GRUB_ERR_IO, "width must be at most %d", - BOCHS_MAX_WIDTH); - - if (height > BOCHS_MAX_HEIGHT) - return grub_error (GRUB_ERR_IO, "height must be at most %d", - BOCHS_MAX_HEIGHT); - - if (width & (BOCHS_WIDTH_ALIGN - 1)) - return grub_error (GRUB_ERR_IO, "width must be a multiple of %d", - BOCHS_WIDTH_ALIGN); - - if (depth == 0 - && !grub_video_check_mode_flag (mode_type, mode_mask, - GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, 0)) - depth = 24; - - if (depth == 0) - depth = 8; - - if (depth != 32 && depth != 24 && depth != 16 && depth != 15 && depth != 8 - && depth != 4) - return grub_error (GRUB_ERR_IO, "only 32, 24, 16, 15 and 8-bpp are" - " supported by bochs video"); - - if (depth == 4) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "4-bpp isn't supported"); - - bytes_per_pixel = (depth + 7) / 8; - if (depth == 4) - pitch = width / 2; - else - pitch = width * bytes_per_pixel; - - page_size = pitch * height; - - if (page_size > BOCHS_APERTURE_SIZE) - return grub_error (GRUB_ERR_IO, "Not enough video memory for this mode"); - - grub_pci_iterate (find_card, &found); - if (!found) - return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); - - if (found && framebuffer.base == 0) - { - /* FIXME: change framebuffer base */ - return grub_error (GRUB_ERR_IO, "PCI BAR not set"); - } - - /* We can safely discard volatile attribute. */ - framebuffer.ptr = (void *) grub_pci_device_map_range (framebuffer.dev, - framebuffer.base, - BOCHS_APERTURE_SIZE); - framebuffer.mapped = 1; - - if (!state_saved) - { - save_state (&initial_state); - state_saved = 1; - } - - { - vbe_write (0, BOCHS_VBE_ENABLE); - - vbe_write (width, BOCHS_VBE_WIDTH); - vbe_write (height, BOCHS_VBE_HEIGHT); - vbe_write (depth, BOCHS_VBE_BPP); - - vbe_write (1, BOCHS_VBE_ENABLE); - doublebuf_pageflipping_set_page (0); - } - - /* Fill mode info details. */ - framebuffer.mode_info.width = width; - framebuffer.mode_info.height = height; - framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB; - framebuffer.mode_info.bpp = depth; - framebuffer.mode_info.bytes_per_pixel = bytes_per_pixel; - framebuffer.mode_info.pitch = pitch; - framebuffer.mode_info.number_of_colors = 256; - framebuffer.mode_info.reserved_mask_size = 0; - framebuffer.mode_info.reserved_field_pos = 0; - - switch (depth) - { - case 4: - case 8: - framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; - framebuffer.mode_info.number_of_colors = 16; - break; - case 16: - 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; - break; - - case 15: - framebuffer.mode_info.red_mask_size = 5; - framebuffer.mode_info.red_field_pos = 10; - framebuffer.mode_info.green_mask_size = 5; - framebuffer.mode_info.green_field_pos = 5; - framebuffer.mode_info.blue_mask_size = 5; - framebuffer.mode_info.blue_field_pos = 0; - break; - - case 32: - framebuffer.mode_info.reserved_mask_size = 8; - framebuffer.mode_info.reserved_field_pos = 24; - /* Fallthrough. */ - - case 24: - 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; - break; - } - - framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); - - if (BOCHS_APERTURE_SIZE >= 2 * page_size) - err = grub_video_fb_setup (mode_type, mode_mask, - &framebuffer.mode_info, - framebuffer.ptr, - doublebuf_pageflipping_set_page, - framebuffer.ptr + page_size); - else - err = grub_video_fb_setup (mode_type, mode_mask, - &framebuffer.mode_info, - framebuffer.ptr, 0, 0); - - - /* Copy default palette to initialize emulated palette. */ - err = grub_video_bochs_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, - grub_video_fbstd_colors); - return err; -} - -static struct grub_video_adapter grub_video_bochs_adapter = - { - .name = "Bochs PCI Video Driver", - .id = GRUB_VIDEO_DRIVER_BOCHS, - - .prio = GRUB_VIDEO_ADAPTER_PRIO_NATIVE, - - .init = grub_video_bochs_video_init, - .fini = grub_video_bochs_video_fini, - .setup = grub_video_bochs_setup, - .get_info = grub_video_fb_get_info, - .get_info_and_fini = grub_video_fb_get_info_and_fini, - .set_palette = grub_video_bochs_set_palette, - .get_palette = grub_video_fb_get_palette, - .set_viewport = grub_video_fb_set_viewport, - .get_viewport = grub_video_fb_get_viewport, - .set_region = grub_video_fb_set_region, - .get_region = grub_video_fb_get_region, - .set_area_status = grub_video_fb_set_area_status, - .get_area_status = grub_video_fb_get_area_status, - .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_fb_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_fb_set_active_render_target, - .get_active_render_target = grub_video_fb_get_active_render_target, - - .next = 0 - }; - -GRUB_MOD_INIT(video_bochs) -{ - grub_video_register (&grub_video_bochs_adapter); -} - -GRUB_MOD_FINI(video_bochs) -{ - grub_video_unregister (&grub_video_bochs_adapter); -} diff --git a/grub-core/video/capture.c b/grub-core/video/capture.c deleted file mode 100644 index c653d89f9..000000000 --- a/grub-core/video/capture.c +++ /dev/null @@ -1,140 +0,0 @@ - -#define grub_video_render_target grub_video_fbrender_target - -#include -#include -#include -#include - -static struct -{ - struct grub_video_mode_info mode_info; - struct grub_video_render_target *render_target; - grub_uint8_t *ptr; -} framebuffer; - -void (*grub_video_capture_refresh_cb) (void); - -static grub_err_t -grub_video_capture_swap_buffers (void) -{ - if (grub_video_capture_refresh_cb) - grub_video_capture_refresh_cb (); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_capture_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_capture_fini (void) -{ - return GRUB_ERR_NONE; -} - -static struct grub_video_adapter grub_video_capture_adapter = - { - .name = "Render capture", - - .prio = 0, - .id = GRUB_VIDEO_ADAPTER_CAPTURE, - - .fini = grub_video_capture_fini, - .get_info = grub_video_fb_get_info, - .get_info_and_fini = 0, - .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, - .set_region = grub_video_fb_set_region, - .get_region = grub_video_fb_get_region, - .set_area_status = grub_video_fb_set_area_status, - .get_area_status = grub_video_fb_get_area_status, - .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_capture_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_capture_set_active_render_target, - .get_active_render_target = grub_video_fb_get_active_render_target, - - .next = 0 - }; - -static struct grub_video_adapter *saved; -static struct grub_video_mode_info saved_mode_info; - -grub_err_t -grub_video_capture_start (const struct grub_video_mode_info *mode_info, - struct grub_video_palette_data *palette, - unsigned int palette_size) -{ - grub_err_t err; - grub_memset (&framebuffer, 0, sizeof (framebuffer)); - - grub_video_fb_init (); - - framebuffer.mode_info = *mode_info; - framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); - - framebuffer.ptr = grub_calloc (framebuffer.mode_info.height, framebuffer.mode_info.pitch); - if (!framebuffer.ptr) - return grub_errno; - - 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, palette_size, palette); - if (err) - return err; - - saved = grub_video_adapter_active; - if (saved) - { - grub_video_get_info (&saved_mode_info); - if (saved->fini) - saved->fini (); - } - grub_video_adapter_active = &grub_video_capture_adapter; - - return GRUB_ERR_NONE; -} - -void * -grub_video_capture_get_framebuffer (void) -{ - return framebuffer.ptr; -} - -void -grub_video_capture_end (void) -{ - grub_video_fb_delete_render_target (framebuffer.render_target); - grub_free (framebuffer.ptr); - grub_video_fb_fini (); - grub_video_adapter_active = saved; - if (saved) - { - if (saved->init) - saved->init (); - if (saved->setup) - saved->setup (saved_mode_info.width, saved_mode_info.height, 0, 0); - } -} diff --git a/grub-core/video/cirrus.c b/grub-core/video/cirrus.c deleted file mode 100644 index f5542ccdc..000000000 --- a/grub-core/video/cirrus.c +++ /dev/null @@ -1,520 +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 . - */ - -#define grub_video_render_target grub_video_fbrender_target - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static struct -{ - struct grub_video_mode_info mode_info; - grub_size_t page_size; /* The size of a page in bytes. */ - - grub_uint8_t *ptr; - int mapped; - grub_uint32_t base; - grub_pci_device_t dev; -} framebuffer; - -#define CIRRUS_APERTURE_SIZE 0x1000000 - -#define CIRRUS_MAX_WIDTH 0x800 -#define CIRRUS_MAX_HEIGHT 0x800 -#define CIRRUS_MAX_PITCH (0x1ff * GRUB_VGA_CR_PITCH_DIVISOR) - -enum - { - CIRRUS_CR_EXTENDED_DISPLAY = 0x1b, - CIRRUS_CR_EXTENDED_OVERLAY = 0x1d, - CIRRUS_CR_MAX - }; - -#define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_MASK 0x10 -#define CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT 4 -#define CIRRUS_CR_EXTENDED_DISPLAY_START_MASK1 0x1 -#define CIRRUS_CR_EXTENDED_DISPLAY_START_SHIFT1 16 -#define CIRRUS_CR_EXTENDED_DISPLAY_START_MASK2 0xc -#define CIRRUS_CR_EXTENDED_DISPLAY_START_SHIFT2 15 - -#define CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_MASK 0x80 -#define CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_SHIFT 12 - -enum - { - CIRRUS_SR_EXTENDED_MODE = 7, - CIRRUS_SR_MAX - }; - -#define CIRRUS_SR_EXTENDED_MODE_LFB_ENABLE 0xf0 -#define CIRRUS_SR_EXTENDED_MODE_ENABLE_EXT 0x01 -#define CIRRUS_SR_EXTENDED_MODE_8BPP 0x00 -#define CIRRUS_SR_EXTENDED_MODE_16BPP 0x06 -#define CIRRUS_SR_EXTENDED_MODE_24BPP 0x04 -#define CIRRUS_SR_EXTENDED_MODE_32BPP 0x08 - -#define CIRRUS_HIDDEN_DAC_ENABLE_EXT 0x80 -#define CIRRUS_HIDDEN_DAC_ENABLE_ALL 0x40 -#define CIRRUS_HIDDEN_DAC_8BPP 0 -#define CIRRUS_HIDDEN_DAC_15BPP (CIRRUS_HIDDEN_DAC_ENABLE_EXT \ - | CIRRUS_HIDDEN_DAC_ENABLE_ALL | 0) -#define CIRRUS_HIDDEN_DAC_16BPP (CIRRUS_HIDDEN_DAC_ENABLE_EXT \ - | CIRRUS_HIDDEN_DAC_ENABLE_ALL | 1) -#define CIRRUS_HIDDEN_DAC_888COLOR (CIRRUS_HIDDEN_DAC_ENABLE_EXT \ - | CIRRUS_HIDDEN_DAC_ENABLE_ALL | 5) - -static void -write_hidden_dac (grub_uint8_t data) -{ - grub_inb (GRUB_VGA_IO_PALLETTE_WRITE_INDEX); - grub_inb (GRUB_VGA_IO_PIXEL_MASK); - grub_inb (GRUB_VGA_IO_PIXEL_MASK); - grub_inb (GRUB_VGA_IO_PIXEL_MASK); - grub_inb (GRUB_VGA_IO_PIXEL_MASK); - grub_outb (data, GRUB_VGA_IO_PIXEL_MASK); -} - -static grub_uint8_t -read_hidden_dac (void) -{ - grub_inb (GRUB_VGA_IO_PALLETTE_WRITE_INDEX); - grub_inb (GRUB_VGA_IO_PIXEL_MASK); - grub_inb (GRUB_VGA_IO_PIXEL_MASK); - grub_inb (GRUB_VGA_IO_PIXEL_MASK); - grub_inb (GRUB_VGA_IO_PIXEL_MASK); - return grub_inb (GRUB_VGA_IO_PIXEL_MASK); -} - -struct saved_state -{ - grub_uint8_t cr[CIRRUS_CR_MAX]; - grub_uint8_t gr[GRUB_VGA_GR_MAX]; - grub_uint8_t sr[CIRRUS_SR_MAX]; - grub_uint8_t hidden_dac; - /* We need to preserve VGA font and VGA text. */ - grub_uint8_t vram[32 * 4 * 256]; - grub_uint8_t r[256]; - grub_uint8_t g[256]; - grub_uint8_t b[256]; -}; - -static struct saved_state initial_state; -static int state_saved = 0; - -static void -save_state (struct saved_state *st) -{ - unsigned i; - for (i = 0; i < ARRAY_SIZE (st->cr); i++) - st->cr[i] = grub_vga_cr_read (i); - for (i = 0; i < ARRAY_SIZE (st->sr); i++) - st->sr[i] = grub_vga_sr_read (i); - for (i = 0; i < ARRAY_SIZE (st->gr); i++) - st->gr[i] = grub_vga_gr_read (i); - for (i = 0; i < 256; i++) - grub_vga_palette_read (i, st->r + i, st->g + i, st->b + i); - - st->hidden_dac = read_hidden_dac (); - grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4, GRUB_VGA_SR_MEMORY_MODE); - grub_memcpy (st->vram, framebuffer.ptr, sizeof (st->vram)); -} - -static void -restore_state (struct saved_state *st) -{ - unsigned i; - grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4, GRUB_VGA_SR_MEMORY_MODE); - grub_memcpy (framebuffer.ptr, st->vram, sizeof (st->vram)); - for (i = 0; i < ARRAY_SIZE (st->cr); i++) - grub_vga_cr_write (st->cr[i], i); - for (i = 0; i < ARRAY_SIZE (st->sr); i++) - grub_vga_sr_write (st->sr[i], i); - for (i = 0; i < ARRAY_SIZE (st->gr); i++) - grub_vga_gr_write (st->gr[i], i); - for (i = 0; i < 256; i++) - grub_vga_palette_write (i, st->r[i], st->g[i], st->b[i]); - - write_hidden_dac (st->hidden_dac); -} - -static grub_err_t -grub_video_cirrus_video_init (void) -{ - /* Reset frame buffer. */ - grub_memset (&framebuffer, 0, sizeof(framebuffer)); - - return grub_video_fb_init (); -} - -static grub_err_t -grub_video_cirrus_video_fini (void) -{ - if (framebuffer.mapped) - grub_pci_device_unmap_range (framebuffer.dev, framebuffer.ptr, - CIRRUS_APERTURE_SIZE); - - if (state_saved) - { - restore_state (&initial_state); - state_saved = 0; - } - - return grub_video_fb_fini (); -} - -static grub_err_t -doublebuf_pageflipping_set_page (int page) -{ - int start = framebuffer.page_size * page / 4; - grub_uint8_t cr_ext, cr_overlay; - - grub_vga_cr_write (start & 0xff, GRUB_VGA_CR_START_ADDR_LOW_REGISTER); - grub_vga_cr_write ((start & 0xff00) >> 8, - GRUB_VGA_CR_START_ADDR_HIGH_REGISTER); - - cr_ext = grub_vga_cr_read (CIRRUS_CR_EXTENDED_DISPLAY); - cr_ext &= ~(CIRRUS_CR_EXTENDED_DISPLAY_START_MASK1 - | CIRRUS_CR_EXTENDED_DISPLAY_START_MASK2); - cr_ext |= ((start >> CIRRUS_CR_EXTENDED_DISPLAY_START_SHIFT1) - & CIRRUS_CR_EXTENDED_DISPLAY_START_MASK1); - cr_ext |= ((start >> CIRRUS_CR_EXTENDED_DISPLAY_START_SHIFT2) - & CIRRUS_CR_EXTENDED_DISPLAY_START_MASK2); - grub_vga_cr_write (cr_ext, CIRRUS_CR_EXTENDED_DISPLAY); - - cr_overlay = grub_vga_cr_read (CIRRUS_CR_EXTENDED_OVERLAY); - cr_overlay &= ~(CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_MASK); - cr_overlay |= ((start >> CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_SHIFT) - & CIRRUS_CR_EXTENDED_OVERLAY_DISPLAY_START_MASK); - grub_vga_cr_write (cr_overlay, CIRRUS_CR_EXTENDED_OVERLAY); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_cirrus_set_palette (unsigned int start, unsigned int count, - struct grub_video_palette_data *palette_data) -{ - if (framebuffer.mode_info.mode_type == GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) - { - unsigned i; - if (start >= 0x100) - return GRUB_ERR_NONE; - if (start + count >= 0x100) - count = 0x100 - start; - - for (i = 0; i < count; i++) - grub_vga_palette_write (start + i, palette_data[i].r, palette_data[i].g, - palette_data[i].b); - } - - /* Then set color to emulated palette. */ - return grub_video_fb_set_palette (start, count, palette_data); -} - -/* Helper for grub_video_cirrus_setup. */ -static int -find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) -{ - int *found = data; - 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 != 0x00b81013) - return 0; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; - if (!framebuffer.base) - return 0; - - *found = 1; - - /* Enable address spaces. */ - addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_COMMAND); - grub_pci_write (addr, 0x7); - - framebuffer.dev = dev; - - return 1; -} - -static grub_err_t -grub_video_cirrus_setup (unsigned int width, unsigned int height, - grub_video_mode_type_t mode_type, - grub_video_mode_type_t mode_mask) -{ - int depth; - grub_err_t err; - int found = 0; - int pitch, bytes_per_pixel; - - /* 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 == 0 || height == 0) - { - width = 800; - height = 600; - } - - if (width & (GRUB_VGA_CR_WIDTH_DIVISOR - 1)) - return grub_error (GRUB_ERR_IO, - "screen width must be a multiple of %d", - GRUB_VGA_CR_WIDTH_DIVISOR); - - if (width > CIRRUS_MAX_WIDTH) - return grub_error (GRUB_ERR_IO, - "screen width must be at most %d", CIRRUS_MAX_WIDTH); - - if (height > CIRRUS_MAX_HEIGHT) - return grub_error (GRUB_ERR_IO, - "screen height must be at most %d", CIRRUS_MAX_HEIGHT); - - if (depth == 0 - && !grub_video_check_mode_flag (mode_type, mode_mask, - GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, 0)) - depth = 24; - else if (depth == 0) - depth = 8; - - if (depth != 32 && depth != 24 && depth != 16 && depth != 15 && depth != 8) - return grub_error (GRUB_ERR_IO, "only 32, 24, 16, 15 and 8-bit bpp are" - " supported by cirrus video"); - - bytes_per_pixel = (depth + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT; - pitch = width * bytes_per_pixel; - - if (pitch > CIRRUS_MAX_PITCH) - return grub_error (GRUB_ERR_IO, - "screen width must be at most %d at bitdepth %d", - CIRRUS_MAX_PITCH / bytes_per_pixel, depth); - - framebuffer.page_size = pitch * height; - - if (framebuffer.page_size > CIRRUS_APERTURE_SIZE) - return grub_error (GRUB_ERR_IO, "Not enough video memory for this mode"); - - grub_pci_iterate (find_card, &found); - if (!found) - return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); - - if (found && framebuffer.base == 0) - { - /* FIXME: change framebuffer base */ - return grub_error (GRUB_ERR_IO, "PCI BAR not set"); - } - - /* We can safely discard volatile attribute. */ - framebuffer.ptr = (void *) grub_pci_device_map_range (framebuffer.dev, - framebuffer.base, - CIRRUS_APERTURE_SIZE); - framebuffer.mapped = 1; - - if (!state_saved) - { - save_state (&initial_state); - state_saved = 1; - } - - { - struct grub_video_hw_config config = { - .pitch = pitch / GRUB_VGA_CR_PITCH_DIVISOR, - .line_compare = 0x3ff, - .vdisplay_end = height - 1, - .horizontal_end = width / GRUB_VGA_CR_WIDTH_DIVISOR - }; - grub_uint8_t sr_ext = 0, hidden_dac = 0; - - grub_vga_set_geometry (&config, grub_vga_cr_write); - - grub_vga_gr_write (GRUB_VGA_GR_MODE_256_COLOR | GRUB_VGA_GR_MODE_READ_MODE1, - GRUB_VGA_GR_MODE); - grub_vga_gr_write (GRUB_VGA_GR_GR6_GRAPHICS_MODE, GRUB_VGA_GR_GR6); - - grub_vga_sr_write (GRUB_VGA_SR_MEMORY_MODE_NORMAL, GRUB_VGA_SR_MEMORY_MODE); - - grub_vga_cr_write ((config.pitch >> CIRRUS_CR_EXTENDED_DISPLAY_PITCH_SHIFT) - & CIRRUS_CR_EXTENDED_DISPLAY_PITCH_MASK, - CIRRUS_CR_EXTENDED_DISPLAY); - - grub_vga_cr_write (GRUB_VGA_CR_MODE_TIMING_ENABLE - | GRUB_VGA_CR_MODE_BYTE_MODE - | GRUB_VGA_CR_MODE_NO_HERCULES | GRUB_VGA_CR_MODE_NO_CGA, - GRUB_VGA_CR_MODE); - - doublebuf_pageflipping_set_page (0); - - sr_ext = CIRRUS_SR_EXTENDED_MODE_LFB_ENABLE - | CIRRUS_SR_EXTENDED_MODE_ENABLE_EXT; - switch (depth) - { - /* FIXME: support 8-bit grayscale and 8-bit RGB. */ - case 32: - hidden_dac = CIRRUS_HIDDEN_DAC_888COLOR; - sr_ext |= CIRRUS_SR_EXTENDED_MODE_32BPP; - break; - case 24: - hidden_dac = CIRRUS_HIDDEN_DAC_888COLOR; - sr_ext |= CIRRUS_SR_EXTENDED_MODE_24BPP; - break; - case 16: - hidden_dac = CIRRUS_HIDDEN_DAC_16BPP; - sr_ext |= CIRRUS_SR_EXTENDED_MODE_16BPP; - break; - case 15: - hidden_dac = CIRRUS_HIDDEN_DAC_15BPP; - sr_ext |= CIRRUS_SR_EXTENDED_MODE_16BPP; - break; - case 8: - hidden_dac = CIRRUS_HIDDEN_DAC_8BPP; - sr_ext |= CIRRUS_SR_EXTENDED_MODE_8BPP; - break; - } - grub_vga_sr_write (sr_ext, CIRRUS_SR_EXTENDED_MODE); - write_hidden_dac (hidden_dac); - } - - /* Fill mode info details. */ - framebuffer.mode_info.width = width; - framebuffer.mode_info.height = height; - framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB; - framebuffer.mode_info.bpp = depth; - framebuffer.mode_info.bytes_per_pixel = bytes_per_pixel; - framebuffer.mode_info.pitch = pitch; - framebuffer.mode_info.number_of_colors = 256; - framebuffer.mode_info.reserved_mask_size = 0; - framebuffer.mode_info.reserved_field_pos = 0; - - switch (depth) - { - case 8: - framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; - framebuffer.mode_info.number_of_colors = 16; - break; - case 16: - 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; - break; - - case 15: - framebuffer.mode_info.red_mask_size = 5; - framebuffer.mode_info.red_field_pos = 10; - framebuffer.mode_info.green_mask_size = 5; - framebuffer.mode_info.green_field_pos = 5; - framebuffer.mode_info.blue_mask_size = 5; - framebuffer.mode_info.blue_field_pos = 0; - break; - - case 32: - framebuffer.mode_info.reserved_mask_size = 8; - framebuffer.mode_info.reserved_field_pos = 24; - /* Fallthrough. */ - - case 24: - 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; - break; - } - - framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); - - if (CIRRUS_APERTURE_SIZE >= 2 * framebuffer.page_size) - err = grub_video_fb_setup (mode_type, mode_mask, - &framebuffer.mode_info, - framebuffer.ptr, - doublebuf_pageflipping_set_page, - framebuffer.ptr + framebuffer.page_size); - else - err = grub_video_fb_setup (mode_type, mode_mask, - &framebuffer.mode_info, - framebuffer.ptr, 0, 0); - - - /* Copy default palette to initialize emulated palette. */ - err = grub_video_cirrus_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, - grub_video_fbstd_colors); - return err; -} - -static struct grub_video_adapter grub_video_cirrus_adapter = - { - .name = "Cirrus CLGD 5446 PCI Video Driver", - .id = GRUB_VIDEO_DRIVER_CIRRUS, - - .prio = GRUB_VIDEO_ADAPTER_PRIO_NATIVE, - - .init = grub_video_cirrus_video_init, - .fini = grub_video_cirrus_video_fini, - .setup = grub_video_cirrus_setup, - .get_info = grub_video_fb_get_info, - .get_info_and_fini = grub_video_fb_get_info_and_fini, - .set_palette = grub_video_cirrus_set_palette, - .get_palette = grub_video_fb_get_palette, - .set_viewport = grub_video_fb_set_viewport, - .get_viewport = grub_video_fb_get_viewport, - .set_region = grub_video_fb_set_region, - .get_region = grub_video_fb_get_region, - .set_area_status = grub_video_fb_set_area_status, - .get_area_status = grub_video_fb_get_area_status, - .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_fb_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_fb_set_active_render_target, - .get_active_render_target = grub_video_fb_get_active_render_target, - - .next = 0 - }; - -GRUB_MOD_INIT(video_cirrus) -{ - grub_video_register (&grub_video_cirrus_adapter); -} - -GRUB_MOD_FINI(video_cirrus) -{ - grub_video_unregister (&grub_video_cirrus_adapter); -} diff --git a/grub-core/video/coreboot/cbfb.c b/grub-core/video/coreboot/cbfb.c deleted file mode 100644 index 986003c51..000000000 --- a/grub-core/video/coreboot/cbfb.c +++ /dev/null @@ -1,190 +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 . - */ - -#define grub_video_render_target grub_video_fbrender_target - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct grub_linuxbios_table_framebuffer *grub_video_coreboot_fbtable; - -static struct -{ - struct grub_video_mode_info mode_info; - grub_uint8_t *ptr; -} framebuffer; - -static grub_err_t -grub_video_cbfb_init (void) -{ - grub_memset (&framebuffer, 0, sizeof(framebuffer)); - - return grub_video_fb_init (); -} - -static grub_err_t -grub_video_cbfb_fill_mode_info (struct grub_video_mode_info *out) -{ - grub_memset (out, 0, sizeof (*out)); - - out->width = grub_video_coreboot_fbtable->width; - out->height = grub_video_coreboot_fbtable->height; - out->pitch = grub_video_coreboot_fbtable->pitch; - - out->red_field_pos = grub_video_coreboot_fbtable->red_field_pos; - out->red_mask_size = grub_video_coreboot_fbtable->red_mask_size; - out->green_field_pos = grub_video_coreboot_fbtable->green_field_pos; - out->green_mask_size = grub_video_coreboot_fbtable->green_mask_size; - out->blue_field_pos = grub_video_coreboot_fbtable->blue_field_pos; - out->blue_mask_size = grub_video_coreboot_fbtable->blue_mask_size; - out->reserved_field_pos = grub_video_coreboot_fbtable->reserved_field_pos; - out->reserved_mask_size = grub_video_coreboot_fbtable->reserved_mask_size; - - out->mode_type = GRUB_VIDEO_MODE_TYPE_RGB; - out->bpp = grub_video_coreboot_fbtable->bpp; - out->bytes_per_pixel = (grub_video_coreboot_fbtable->bpp + 7) / 8; - out->number_of_colors = 256; - - out->blit_format = grub_video_get_blit_format (out); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_cbfb_setup (unsigned int width, unsigned int height, - unsigned int mode_type __attribute__ ((unused)), - unsigned int mode_mask __attribute__ ((unused))) -{ - grub_err_t err; - - if (!grub_video_coreboot_fbtable) - return grub_error (GRUB_ERR_IO, "Couldn't find display device."); - - if (!((width == grub_video_coreboot_fbtable->width && height == grub_video_coreboot_fbtable->height) - || (width == 0 && height == 0))) - return grub_error (GRUB_ERR_IO, "can't set mode %dx%d", width, height); - - err = grub_video_cbfb_fill_mode_info (&framebuffer.mode_info); - if (err) - { - grub_dprintf ("video", "CBFB: couldn't fill mode info\n"); - return err; - } - - framebuffer.ptr = (void *) (grub_addr_t) grub_video_coreboot_fbtable->lfb; - - grub_dprintf ("video", "CBFB: 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_setup (mode_type, mode_mask, - &framebuffer.mode_info, - framebuffer.ptr, NULL, NULL); - if (err) - return err; - - grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, - grub_video_fbstd_colors); - - return err; -} - -static grub_err_t -grub_video_cbfb_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_cbfb_adapter = - { - .name = "Coreboot video driver", - - .prio = GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE_DIRTY, - .id = GRUB_VIDEO_DRIVER_COREBOOT, - - .init = grub_video_cbfb_init, - .fini = grub_video_fb_fini, - .setup = grub_video_cbfb_setup, - .get_info = grub_video_fb_get_info, - .get_info_and_fini = grub_video_cbfb_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, - .set_region = grub_video_fb_set_region, - .get_region = grub_video_fb_get_region, - .set_area_status = grub_video_fb_set_area_status, - .get_area_status = grub_video_fb_get_area_status, - .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_fb_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_fb_set_active_render_target, - .get_active_render_target = grub_video_fb_get_active_render_target, - - .next = 0 - }; - -static int -iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, - void *data __attribute__ ((unused))) -{ - if (table_item->tag != GRUB_LINUXBIOS_MEMBER_FRAMEBUFFER) - return 0; - grub_video_coreboot_fbtable = (struct grub_linuxbios_table_framebuffer *) (table_item + 1); - return 1; -} - -void -grub_video_coreboot_fb_early_init (void) -{ - grub_linuxbios_table_iterate (iterate_linuxbios_table, 0); -} - -void -grub_video_coreboot_fb_late_init (void) -{ - if (grub_video_coreboot_fbtable) - grub_video_register (&grub_video_cbfb_adapter); -} - -void -grub_video_coreboot_fb_fini (void) -{ - if (grub_video_coreboot_fbtable) - grub_video_unregister (&grub_video_cbfb_adapter); -} diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c deleted file mode 100644 index fa4ebde26..000000000 --- a/grub-core/video/fb/video_fb.c +++ /dev/null @@ -1,1709 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -typedef grub_err_t (*grub_video_fb_doublebuf_update_screen_t) (void); -typedef volatile void *framebuf_t; - -struct dirty -{ - int first_line; - int last_line; -}; - -static struct -{ - struct grub_video_fbrender_target *render_target; - struct grub_video_fbrender_target *back_target; - struct grub_video_palette_data *palette; - framebuf_t pages[2]; - - unsigned int palette_size; - - struct dirty current_dirty; - struct dirty previous_dirty; - - /* For page flipping strategy. */ - int displayed_page; /* The page # that is the front buffer. */ - int render_page; /* The page # that is the back buffer. */ - grub_video_fb_set_page_t set_page; - char *offscreen_buffer; - grub_video_fb_doublebuf_update_screen_t update_screen; -} framebuffer; - -/* 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_EXT_NUMCOLORS] = - { - /* Standard (3-bit) colors. */ - - // {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 - - /* Bright (4-bit) colors. */ - {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 - - /* Extended (8-bit) colors. Completes preceding colors to full RGB332. */ - {0x00, 0x00, 0x55, 0xFF}, // RGB332 = (0, 0, 1) - {0x00, 0x00, 0xFF, 0xFF}, // RGB332 = (0, 0, 3) - {0x00, 0x24, 0x00, 0xFF}, // RGB332 = (0, 1, 0) - {0x00, 0x24, 0x55, 0xFF}, // RGB332 = (0, 1, 1) - {0x00, 0x24, 0xAA, 0xFF}, // RGB332 = (0, 1, 2) - {0x00, 0x24, 0xFF, 0xFF}, // RGB332 = (0, 1, 3) - {0x00, 0x48, 0x00, 0xFF}, // RGB332 = (0, 2, 0) - {0x00, 0x48, 0x55, 0xFF}, // RGB332 = (0, 2, 1) - {0x00, 0x48, 0xAA, 0xFF}, // RGB332 = (0, 2, 2) - {0x00, 0x48, 0xFF, 0xFF}, // RGB332 = (0, 2, 3) - {0x00, 0x6C, 0x00, 0xFF}, // RGB332 = (0, 3, 0) - {0x00, 0x6C, 0x55, 0xFF}, // RGB332 = (0, 3, 1) - {0x00, 0x6C, 0xAA, 0xFF}, // RGB332 = (0, 3, 2) - {0x00, 0x6C, 0xFF, 0xFF}, // RGB332 = (0, 3, 3) - {0x00, 0x90, 0x00, 0xFF}, // RGB332 = (0, 4, 0) - {0x00, 0x90, 0x55, 0xFF}, // RGB332 = (0, 4, 1) - {0x00, 0x90, 0xAA, 0xFF}, // RGB332 = (0, 4, 2) - {0x00, 0x90, 0xFF, 0xFF}, // RGB332 = (0, 4, 3) - {0x00, 0xB4, 0x55, 0xFF}, // RGB332 = (0, 5, 1) - {0x00, 0xB4, 0xFF, 0xFF}, // RGB332 = (0, 5, 3) - {0x00, 0xD8, 0x00, 0xFF}, // RGB332 = (0, 6, 0) - {0x00, 0xD8, 0x55, 0xFF}, // RGB332 = (0, 6, 1) - {0x00, 0xD8, 0xAA, 0xFF}, // RGB332 = (0, 6, 2) - {0x00, 0xD8, 0xFF, 0xFF}, // RGB332 = (0, 6, 3) - {0x00, 0xFC, 0x00, 0xFF}, // RGB332 = (0, 7, 0) - {0x00, 0xFC, 0x55, 0xFF}, // RGB332 = (0, 7, 1) - {0x00, 0xFC, 0xAA, 0xFF}, // RGB332 = (0, 7, 2) - {0x00, 0xFC, 0xFF, 0xFF}, // RGB332 = (0, 7, 3) - {0x24, 0x00, 0x00, 0xFF}, // RGB332 = (1, 0, 0) - {0x24, 0x00, 0x55, 0xFF}, // RGB332 = (1, 0, 1) - {0x24, 0x00, 0xAA, 0xFF}, // RGB332 = (1, 0, 2) - {0x24, 0x00, 0xFF, 0xFF}, // RGB332 = (1, 0, 3) - {0x24, 0x24, 0x00, 0xFF}, // RGB332 = (1, 1, 0) - {0x24, 0x24, 0x55, 0xFF}, // RGB332 = (1, 1, 1) - {0x24, 0x24, 0xAA, 0xFF}, // RGB332 = (1, 1, 2) - {0x24, 0x24, 0xFF, 0xFF}, // RGB332 = (1, 1, 3) - {0x24, 0x48, 0x00, 0xFF}, // RGB332 = (1, 2, 0) - {0x24, 0x48, 0x55, 0xFF}, // RGB332 = (1, 2, 1) - {0x24, 0x48, 0xAA, 0xFF}, // RGB332 = (1, 2, 2) - {0x24, 0x48, 0xFF, 0xFF}, // RGB332 = (1, 2, 3) - {0x24, 0x6C, 0x00, 0xFF}, // RGB332 = (1, 3, 0) - {0x24, 0x6C, 0x55, 0xFF}, // RGB332 = (1, 3, 1) - {0x24, 0x6C, 0xAA, 0xFF}, // RGB332 = (1, 3, 2) - {0x24, 0x6C, 0xFF, 0xFF}, // RGB332 = (1, 3, 3) - {0x24, 0x90, 0x00, 0xFF}, // RGB332 = (1, 4, 0) - {0x24, 0x90, 0x55, 0xFF}, // RGB332 = (1, 4, 1) - {0x24, 0x90, 0xAA, 0xFF}, // RGB332 = (1, 4, 2) - {0x24, 0x90, 0xFF, 0xFF}, // RGB332 = (1, 4, 3) - {0x24, 0xB4, 0x00, 0xFF}, // RGB332 = (1, 5, 0) - {0x24, 0xB4, 0x55, 0xFF}, // RGB332 = (1, 5, 1) - {0x24, 0xB4, 0xAA, 0xFF}, // RGB332 = (1, 5, 2) - {0x24, 0xB4, 0xFF, 0xFF}, // RGB332 = (1, 5, 3) - {0x24, 0xD8, 0x00, 0xFF}, // RGB332 = (1, 6, 0) - {0x24, 0xD8, 0x55, 0xFF}, // RGB332 = (1, 6, 1) - {0x24, 0xD8, 0xAA, 0xFF}, // RGB332 = (1, 6, 2) - {0x24, 0xD8, 0xFF, 0xFF}, // RGB332 = (1, 6, 3) - {0x24, 0xFC, 0x00, 0xFF}, // RGB332 = (1, 7, 0) - {0x24, 0xFC, 0x55, 0xFF}, // RGB332 = (1, 7, 1) - {0x24, 0xFC, 0xAA, 0xFF}, // RGB332 = (1, 7, 2) - {0x24, 0xFC, 0xFF, 0xFF}, // RGB332 = (1, 7, 3) - {0x48, 0x00, 0x00, 0xFF}, // RGB332 = (2, 0, 0) - {0x48, 0x00, 0x55, 0xFF}, // RGB332 = (2, 0, 1) - {0x48, 0x00, 0xAA, 0xFF}, // RGB332 = (2, 0, 2) - {0x48, 0x00, 0xFF, 0xFF}, // RGB332 = (2, 0, 3) - {0x48, 0x24, 0x00, 0xFF}, // RGB332 = (2, 1, 0) - {0x48, 0x24, 0x55, 0xFF}, // RGB332 = (2, 1, 1) - {0x48, 0x24, 0xAA, 0xFF}, // RGB332 = (2, 1, 2) - {0x48, 0x24, 0xFF, 0xFF}, // RGB332 = (2, 1, 3) - {0x48, 0x48, 0x00, 0xFF}, // RGB332 = (2, 2, 0) - {0x48, 0x48, 0xAA, 0xFF}, // RGB332 = (2, 2, 2) - {0x48, 0x6C, 0x00, 0xFF}, // RGB332 = (2, 3, 0) - {0x48, 0x6C, 0x55, 0xFF}, // RGB332 = (2, 3, 1) - {0x48, 0x6C, 0xAA, 0xFF}, // RGB332 = (2, 3, 2) - {0x48, 0x6C, 0xFF, 0xFF}, // RGB332 = (2, 3, 3) - {0x48, 0x90, 0x00, 0xFF}, // RGB332 = (2, 4, 0) - {0x48, 0x90, 0x55, 0xFF}, // RGB332 = (2, 4, 1) - {0x48, 0x90, 0xAA, 0xFF}, // RGB332 = (2, 4, 2) - {0x48, 0x90, 0xFF, 0xFF}, // RGB332 = (2, 4, 3) - {0x48, 0xB4, 0x00, 0xFF}, // RGB332 = (2, 5, 0) - {0x48, 0xB4, 0x55, 0xFF}, // RGB332 = (2, 5, 1) - {0x48, 0xB4, 0xAA, 0xFF}, // RGB332 = (2, 5, 2) - {0x48, 0xB4, 0xFF, 0xFF}, // RGB332 = (2, 5, 3) - {0x48, 0xD8, 0x00, 0xFF}, // RGB332 = (2, 6, 0) - {0x48, 0xD8, 0x55, 0xFF}, // RGB332 = (2, 6, 1) - {0x48, 0xD8, 0xAA, 0xFF}, // RGB332 = (2, 6, 2) - {0x48, 0xD8, 0xFF, 0xFF}, // RGB332 = (2, 6, 3) - {0x48, 0xFC, 0x00, 0xFF}, // RGB332 = (2, 7, 0) - {0x48, 0xFC, 0xAA, 0xFF}, // RGB332 = (2, 7, 2) - {0x6C, 0x00, 0x00, 0xFF}, // RGB332 = (3, 0, 0) - {0x6C, 0x00, 0x55, 0xFF}, // RGB332 = (3, 0, 1) - {0x6C, 0x00, 0xAA, 0xFF}, // RGB332 = (3, 0, 2) - {0x6C, 0x00, 0xFF, 0xFF}, // RGB332 = (3, 0, 3) - {0x6C, 0x24, 0x00, 0xFF}, // RGB332 = (3, 1, 0) - {0x6C, 0x24, 0x55, 0xFF}, // RGB332 = (3, 1, 1) - {0x6C, 0x24, 0xAA, 0xFF}, // RGB332 = (3, 1, 2) - {0x6C, 0x24, 0xFF, 0xFF}, // RGB332 = (3, 1, 3) - {0x6C, 0x48, 0x00, 0xFF}, // RGB332 = (3, 2, 0) - {0x6C, 0x48, 0x55, 0xFF}, // RGB332 = (3, 2, 1) - {0x6C, 0x48, 0xAA, 0xFF}, // RGB332 = (3, 2, 2) - {0x6C, 0x48, 0xFF, 0xFF}, // RGB332 = (3, 2, 3) - {0x6C, 0x6C, 0x00, 0xFF}, // RGB332 = (3, 3, 0) - {0x6C, 0x6C, 0x55, 0xFF}, // RGB332 = (3, 3, 1) - {0x6C, 0x6C, 0xAA, 0xFF}, // RGB332 = (3, 3, 2) - {0x6C, 0x6C, 0xFF, 0xFF}, // RGB332 = (3, 3, 3) - {0x6C, 0x90, 0x00, 0xFF}, // RGB332 = (3, 4, 0) - {0x6C, 0x90, 0x55, 0xFF}, // RGB332 = (3, 4, 1) - {0x6C, 0x90, 0xAA, 0xFF}, // RGB332 = (3, 4, 2) - {0x6C, 0x90, 0xFF, 0xFF}, // RGB332 = (3, 4, 3) - {0x6C, 0xB4, 0x00, 0xFF}, // RGB332 = (3, 5, 0) - {0x6C, 0xB4, 0x55, 0xFF}, // RGB332 = (3, 5, 1) - {0x6C, 0xB4, 0xAA, 0xFF}, // RGB332 = (3, 5, 2) - {0x6C, 0xB4, 0xFF, 0xFF}, // RGB332 = (3, 5, 3) - {0x6C, 0xD8, 0x00, 0xFF}, // RGB332 = (3, 6, 0) - {0x6C, 0xD8, 0x55, 0xFF}, // RGB332 = (3, 6, 1) - {0x6C, 0xD8, 0xAA, 0xFF}, // RGB332 = (3, 6, 2) - {0x6C, 0xD8, 0xFF, 0xFF}, // RGB332 = (3, 6, 3) - {0x6C, 0xFC, 0x00, 0xFF}, // RGB332 = (3, 7, 0) - {0x6C, 0xFC, 0x55, 0xFF}, // RGB332 = (3, 7, 1) - {0x6C, 0xFC, 0xAA, 0xFF}, // RGB332 = (3, 7, 2) - {0x6C, 0xFC, 0xFF, 0xFF}, // RGB332 = (3, 7, 3) - {0x90, 0x00, 0x00, 0xFF}, // RGB332 = (4, 0, 0) - {0x90, 0x00, 0x55, 0xFF}, // RGB332 = (4, 0, 1) - {0x90, 0x00, 0xAA, 0xFF}, // RGB332 = (4, 0, 2) - {0x90, 0x00, 0xFF, 0xFF}, // RGB332 = (4, 0, 3) - {0x90, 0x24, 0x00, 0xFF}, // RGB332 = (4, 1, 0) - {0x90, 0x24, 0x55, 0xFF}, // RGB332 = (4, 1, 1) - {0x90, 0x24, 0xAA, 0xFF}, // RGB332 = (4, 1, 2) - {0x90, 0x24, 0xFF, 0xFF}, // RGB332 = (4, 1, 3) - {0x90, 0x48, 0x00, 0xFF}, // RGB332 = (4, 2, 0) - {0x90, 0x48, 0x55, 0xFF}, // RGB332 = (4, 2, 1) - {0x90, 0x48, 0xAA, 0xFF}, // RGB332 = (4, 2, 2) - {0x90, 0x48, 0xFF, 0xFF}, // RGB332 = (4, 2, 3) - {0x90, 0x6C, 0x00, 0xFF}, // RGB332 = (4, 3, 0) - {0x90, 0x6C, 0x55, 0xFF}, // RGB332 = (4, 3, 1) - {0x90, 0x6C, 0xAA, 0xFF}, // RGB332 = (4, 3, 2) - {0x90, 0x6C, 0xFF, 0xFF}, // RGB332 = (4, 3, 3) - {0x90, 0x90, 0x00, 0xFF}, // RGB332 = (4, 4, 0) - {0x90, 0x90, 0x55, 0xFF}, // RGB332 = (4, 4, 1) - {0x90, 0x90, 0xAA, 0xFF}, // RGB332 = (4, 4, 2) - {0x90, 0x90, 0xFF, 0xFF}, // RGB332 = (4, 4, 3) - {0x90, 0xB4, 0x00, 0xFF}, // RGB332 = (4, 5, 0) - {0x90, 0xB4, 0x55, 0xFF}, // RGB332 = (4, 5, 1) - {0x90, 0xB4, 0xAA, 0xFF}, // RGB332 = (4, 5, 2) - {0x90, 0xB4, 0xFF, 0xFF}, // RGB332 = (4, 5, 3) - {0x90, 0xD8, 0x00, 0xFF}, // RGB332 = (4, 6, 0) - {0x90, 0xD8, 0x55, 0xFF}, // RGB332 = (4, 6, 1) - {0x90, 0xD8, 0xAA, 0xFF}, // RGB332 = (4, 6, 2) - {0x90, 0xD8, 0xFF, 0xFF}, // RGB332 = (4, 6, 3) - {0x90, 0xFC, 0x00, 0xFF}, // RGB332 = (4, 7, 0) - {0x90, 0xFC, 0x55, 0xFF}, // RGB332 = (4, 7, 1) - {0x90, 0xFC, 0xAA, 0xFF}, // RGB332 = (4, 7, 2) - {0x90, 0xFC, 0xFF, 0xFF}, // RGB332 = (4, 7, 3) - {0xB4, 0x00, 0x55, 0xFF}, // RGB332 = (5, 0, 1) - {0xB4, 0x00, 0xFF, 0xFF}, // RGB332 = (5, 0, 3) - {0xB4, 0x24, 0x00, 0xFF}, // RGB332 = (5, 1, 0) - {0xB4, 0x24, 0x55, 0xFF}, // RGB332 = (5, 1, 1) - {0xB4, 0x24, 0xAA, 0xFF}, // RGB332 = (5, 1, 2) - {0xB4, 0x24, 0xFF, 0xFF}, // RGB332 = (5, 1, 3) - {0xB4, 0x48, 0x55, 0xFF}, // RGB332 = (5, 2, 1) - {0xB4, 0x48, 0xAA, 0xFF}, // RGB332 = (5, 2, 2) - {0xB4, 0x48, 0xFF, 0xFF}, // RGB332 = (5, 2, 3) - {0xB4, 0x6C, 0x00, 0xFF}, // RGB332 = (5, 3, 0) - {0xB4, 0x6C, 0x55, 0xFF}, // RGB332 = (5, 3, 1) - {0xB4, 0x6C, 0xAA, 0xFF}, // RGB332 = (5, 3, 2) - {0xB4, 0x6C, 0xFF, 0xFF}, // RGB332 = (5, 3, 3) - {0xB4, 0x90, 0x00, 0xFF}, // RGB332 = (5, 4, 0) - {0xB4, 0x90, 0x55, 0xFF}, // RGB332 = (5, 4, 1) - {0xB4, 0x90, 0xAA, 0xFF}, // RGB332 = (5, 4, 2) - {0xB4, 0x90, 0xFF, 0xFF}, // RGB332 = (5, 4, 3) - {0xB4, 0xB4, 0x00, 0xFF}, // RGB332 = (5, 5, 0) - {0xB4, 0xB4, 0x55, 0xFF}, // RGB332 = (5, 5, 1) - {0xB4, 0xB4, 0xFF, 0xFF}, // RGB332 = (5, 5, 3) - {0xB4, 0xD8, 0x00, 0xFF}, // RGB332 = (5, 6, 0) - {0xB4, 0xD8, 0x55, 0xFF}, // RGB332 = (5, 6, 1) - {0xB4, 0xD8, 0xAA, 0xFF}, // RGB332 = (5, 6, 2) - {0xB4, 0xD8, 0xFF, 0xFF}, // RGB332 = (5, 6, 3) - {0xB4, 0xFC, 0x00, 0xFF}, // RGB332 = (5, 7, 0) - {0xB4, 0xFC, 0x55, 0xFF}, // RGB332 = (5, 7, 1) - {0xB4, 0xFC, 0xAA, 0xFF}, // RGB332 = (5, 7, 2) - {0xB4, 0xFC, 0xFF, 0xFF}, // RGB332 = (5, 7, 3) - {0xD8, 0x00, 0x00, 0xFF}, // RGB332 = (6, 0, 0) - {0xD8, 0x00, 0x55, 0xFF}, // RGB332 = (6, 0, 1) - {0xD8, 0x00, 0xAA, 0xFF}, // RGB332 = (6, 0, 2) - {0xD8, 0x00, 0xFF, 0xFF}, // RGB332 = (6, 0, 3) - {0xD8, 0x24, 0x00, 0xFF}, // RGB332 = (6, 1, 0) - {0xD8, 0x24, 0x55, 0xFF}, // RGB332 = (6, 1, 1) - {0xD8, 0x24, 0xAA, 0xFF}, // RGB332 = (6, 1, 2) - {0xD8, 0x24, 0xFF, 0xFF}, // RGB332 = (6, 1, 3) - {0xD8, 0x48, 0x00, 0xFF}, // RGB332 = (6, 2, 0) - {0xD8, 0x48, 0x55, 0xFF}, // RGB332 = (6, 2, 1) - {0xD8, 0x48, 0xAA, 0xFF}, // RGB332 = (6, 2, 2) - {0xD8, 0x48, 0xFF, 0xFF}, // RGB332 = (6, 2, 3) - {0xD8, 0x6C, 0x00, 0xFF}, // RGB332 = (6, 3, 0) - {0xD8, 0x6C, 0x55, 0xFF}, // RGB332 = (6, 3, 1) - {0xD8, 0x6C, 0xAA, 0xFF}, // RGB332 = (6, 3, 2) - {0xD8, 0x6C, 0xFF, 0xFF}, // RGB332 = (6, 3, 3) - {0xD8, 0x90, 0x00, 0xFF}, // RGB332 = (6, 4, 0) - {0xD8, 0x90, 0x55, 0xFF}, // RGB332 = (6, 4, 1) - {0xD8, 0x90, 0xAA, 0xFF}, // RGB332 = (6, 4, 2) - {0xD8, 0x90, 0xFF, 0xFF}, // RGB332 = (6, 4, 3) - {0xD8, 0xB4, 0x00, 0xFF}, // RGB332 = (6, 5, 0) - {0xD8, 0xB4, 0x55, 0xFF}, // RGB332 = (6, 5, 1) - {0xD8, 0xB4, 0xAA, 0xFF}, // RGB332 = (6, 5, 2) - {0xD8, 0xB4, 0xFF, 0xFF}, // RGB332 = (6, 5, 3) - {0xD8, 0xD8, 0x00, 0xFF}, // RGB332 = (6, 6, 0) - {0xD8, 0xD8, 0x55, 0xFF}, // RGB332 = (6, 6, 1) - {0xD8, 0xD8, 0xAA, 0xFF}, // RGB332 = (6, 6, 2) - {0xD8, 0xD8, 0xFF, 0xFF}, // RGB332 = (6, 6, 3) - {0xD8, 0xFC, 0x00, 0xFF}, // RGB332 = (6, 7, 0) - {0xD8, 0xFC, 0x55, 0xFF}, // RGB332 = (6, 7, 1) - {0xD8, 0xFC, 0xAA, 0xFF}, // RGB332 = (6, 7, 2) - {0xD8, 0xFC, 0xFF, 0xFF}, // RGB332 = (6, 7, 3) - {0xFC, 0x00, 0x00, 0xFF}, // RGB332 = (7, 0, 0) - {0xFC, 0x00, 0x55, 0xFF}, // RGB332 = (7, 0, 1) - {0xFC, 0x00, 0xAA, 0xFF}, // RGB332 = (7, 0, 2) - {0xFC, 0x00, 0xFF, 0xFF}, // RGB332 = (7, 0, 3) - {0xFC, 0x24, 0x00, 0xFF}, // RGB332 = (7, 1, 0) - {0xFC, 0x24, 0x55, 0xFF}, // RGB332 = (7, 1, 1) - {0xFC, 0x24, 0xAA, 0xFF}, // RGB332 = (7, 1, 2) - {0xFC, 0x24, 0xFF, 0xFF}, // RGB332 = (7, 1, 3) - {0xFC, 0x48, 0x00, 0xFF}, // RGB332 = (7, 2, 0) - {0xFC, 0x48, 0xAA, 0xFF}, // RGB332 = (7, 2, 2) - {0xFC, 0x6C, 0x00, 0xFF}, // RGB332 = (7, 3, 0) - {0xFC, 0x6C, 0x55, 0xFF}, // RGB332 = (7, 3, 1) - {0xFC, 0x6C, 0xAA, 0xFF}, // RGB332 = (7, 3, 2) - {0xFC, 0x6C, 0xFF, 0xFF}, // RGB332 = (7, 3, 3) - {0xFC, 0x90, 0x00, 0xFF}, // RGB332 = (7, 4, 0) - {0xFC, 0x90, 0x55, 0xFF}, // RGB332 = (7, 4, 1) - {0xFC, 0x90, 0xAA, 0xFF}, // RGB332 = (7, 4, 2) - {0xFC, 0x90, 0xFF, 0xFF}, // RGB332 = (7, 4, 3) - {0xFC, 0xB4, 0x00, 0xFF}, // RGB332 = (7, 5, 0) - {0xFC, 0xB4, 0x55, 0xFF}, // RGB332 = (7, 5, 1) - {0xFC, 0xB4, 0xAA, 0xFF}, // RGB332 = (7, 5, 2) - {0xFC, 0xB4, 0xFF, 0xFF}, // RGB332 = (7, 5, 3) - {0xFC, 0xD8, 0x00, 0xFF}, // RGB332 = (7, 6, 0) - {0xFC, 0xD8, 0x55, 0xFF}, // RGB332 = (7, 6, 1) - {0xFC, 0xD8, 0xAA, 0xFF}, // RGB332 = (7, 6, 2) - {0xFC, 0xD8, 0xFF, 0xFF}, // RGB332 = (7, 6, 3) - {0xFC, 0xFC, 0x00, 0xFF}, // RGB332 = (7, 7, 0) - {0xFC, 0xFC, 0xAA, 0xFF}, // RGB332 = (7, 7, 2) - }; - -grub_err_t -grub_video_fb_init (void) -{ - grub_free (framebuffer.palette); - framebuffer.render_target = 0; - framebuffer.back_target = 0; - framebuffer.palette = 0; - framebuffer.palette_size = 0; - framebuffer.set_page = 0; - return GRUB_ERR_NONE; -} - -grub_err_t -grub_video_fb_fini (void) -{ - /* TODO: destroy render targets. */ - - grub_free (framebuffer.offscreen_buffer); - grub_free (framebuffer.palette); - framebuffer.render_target = 0; - framebuffer.back_target = 0; - framebuffer.palette = 0; - framebuffer.palette_size = 0; - framebuffer.set_page = 0; - framebuffer.offscreen_buffer = 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, &framebuffer.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) < framebuffer.palette_size); i++) - palette_data[i] = framebuffer.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 > framebuffer.palette_size) - { - framebuffer.palette_size = start + count; - framebuffer.palette = grub_realloc (framebuffer.palette, - sizeof (framebuffer.palette[0]) - * framebuffer.palette_size); - if (!framebuffer.palette) - { - grub_video_fb_fini (); - return grub_errno; - } - } - for (i = 0; (i < count) && ((i + start) < framebuffer.palette_size); i++) - framebuffer.palette[start + i] = palette_data[i]; - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_fb_set_area (void) -{ - unsigned int viewport_x1 = framebuffer.render_target->viewport.x; - unsigned int viewport_y1 = framebuffer.render_target->viewport.y; - unsigned int viewport_width = framebuffer.render_target->viewport.width; - unsigned int viewport_height = framebuffer.render_target->viewport.height; - unsigned int viewport_x2 = viewport_x1 + viewport_width; - unsigned int viewport_y2 = viewport_y1 + viewport_height; - - unsigned int region_x1 = framebuffer.render_target->region.x; - unsigned int region_y1 = framebuffer.render_target->region.y; - unsigned int region_width = framebuffer.render_target->region.width; - unsigned int region_height = framebuffer.render_target->region.height; - unsigned int region_x2 = region_x1 + region_width; - unsigned int region_y2 = region_y1 + region_height; - - unsigned int max_x1 = grub_max (viewport_x1, region_x1); - unsigned int min_x2 = grub_min (viewport_x2, region_x2); - unsigned int max_y1 = grub_max (viewport_y1, region_y1); - unsigned int min_y2 = grub_min (viewport_y2, region_y2); - - /* Viewport and region do not intersect. */ - if (viewport_width == 0 || viewport_height == 0 || region_width == 0 - || region_height == 0 || max_x1 >= min_x2 || max_y1 >= min_y2) - { - framebuffer.render_target->area.x = 0; - framebuffer.render_target->area.y = 0; - framebuffer.render_target->area.width = 0; - framebuffer.render_target->area.height = 0; - framebuffer.render_target->area_offset_x = 0; - framebuffer.render_target->area_offset_y = 0; - return GRUB_ERR_NONE; - } - - /* There is non-zero intersection. */ - framebuffer.render_target->area.x = max_x1; - framebuffer.render_target->area.y = max_y1; - framebuffer.render_target->area.width = min_x2 - max_x1; - framebuffer.render_target->area.height = min_y2 - max_y1; - - if (region_x1 > viewport_x1) - framebuffer.render_target->area_offset_x = (int)region_x1 - - (int)viewport_x1; - else - framebuffer.render_target->area_offset_x = 0; - if (region_y1 > viewport_y1) - framebuffer.render_target->area_offset_y = (int)region_y1 - - (int)viewport_y1; - else - framebuffer.render_target->area_offset_y = 0; - - 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 within screen dimensions. If viewport was set - to be out of the screen, mark its size as zero. */ - if (x > framebuffer.render_target->mode_info.width) - { - x = 0; - width = 0; - } - - if (y > framebuffer.render_target->mode_info.height) - { - y = 0; - height = 0; - } - - if (x + width > framebuffer.render_target->mode_info.width) - width = framebuffer.render_target->mode_info.width - x; - - if (y + height > framebuffer.render_target->mode_info.height) - height = framebuffer.render_target->mode_info.height - y; - - framebuffer.render_target->viewport.x = x; - framebuffer.render_target->viewport.y = y; - framebuffer.render_target->viewport.width = width; - framebuffer.render_target->viewport.height = height; - - /* Count drawing area only if needed. */ - if (framebuffer.render_target->area_enabled) - grub_video_fb_set_area (); - - 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 = framebuffer.render_target->viewport.x; - if (y) *y = framebuffer.render_target->viewport.y; - if (width) *width = framebuffer.render_target->viewport.width; - if (height) *height = framebuffer.render_target->viewport.height; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_video_fb_set_region (unsigned int x, unsigned int y, - unsigned int width, unsigned int height) -{ - /* Make sure region is within screen dimensions. If region was set - to be out of the screen, mark its size as zero. */ - if (x > framebuffer.render_target->mode_info.width) - { - x = 0; - width = 0; - } - - if (y > framebuffer.render_target->mode_info.height) - { - y = 0; - height = 0; - } - - if (x + width > framebuffer.render_target->mode_info.width) - width = framebuffer.render_target->mode_info.width - x; - - if (y + height > framebuffer.render_target->mode_info.height) - height = framebuffer.render_target->mode_info.height - y; - - framebuffer.render_target->region.x = x; - framebuffer.render_target->region.y = y; - framebuffer.render_target->region.width = width; - framebuffer.render_target->region.height = height; - - /* If we have called set_region then area is needed. */ - grub_video_fb_set_area (); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_video_fb_get_region (unsigned int *x, unsigned int *y, - unsigned int *width, unsigned int *height) -{ - if (x) *x = framebuffer.render_target->region.x; - if (y) *y = framebuffer.render_target->region.y; - if (width) *width = framebuffer.render_target->region.width; - if (height) *height = framebuffer.render_target->region.height; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_video_fb_set_area_status (grub_video_area_status_t area_status) -{ - if (area_status == GRUB_VIDEO_AREA_ENABLED) - framebuffer.render_target->area_enabled = 1; - else - framebuffer.render_target->area_enabled = 0; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_video_fb_get_area_status (grub_video_area_status_t *area_status) -{ - if (!area_status) - return GRUB_ERR_NONE; - - if (framebuffer.render_target->area_enabled) - *area_status = GRUB_VIDEO_AREA_ENABLED; - else - *area_status = GRUB_VIDEO_AREA_DISABLED; - - 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 < framebuffer.palette_size) - { - if ((framebuffer.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 (framebuffer.palette[color_name].r, - framebuffer.palette[color_name].g, - framebuffer.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 ((framebuffer.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 < framebuffer.palette_size; i++) - { - val = framebuffer.palette[i].r - red; - tmp = val * val; - val = framebuffer.palette[i].g - green; - tmp += val * val; - val = framebuffer.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 ((framebuffer.render_target->mode_info.mode_type - & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0) - { - if (red == framebuffer.render_target->mode_info.fg_red - && green == framebuffer.render_target->mode_info.fg_green - && blue == framebuffer.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 - framebuffer.render_target->mode_info.red_mask_size; - green >>= 8 - framebuffer.render_target->mode_info.green_mask_size; - blue >>= 8 - framebuffer.render_target->mode_info.blue_mask_size; - alpha >>= 8 - framebuffer.render_target->mode_info.reserved_mask_size; - - value = red << framebuffer.render_target->mode_info.red_field_pos; - value |= green << framebuffer.render_target->mode_info.green_field_pos; - value |= blue << framebuffer.render_target->mode_info.blue_field_pos; - value |= alpha << framebuffer.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 ((framebuffer.render_target->mode_info.mode_type - & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0) - { - if ((framebuffer.render_target->mode_info.mode_type - & GRUB_VIDEO_MODE_TYPE_ALPHA) != 0 - && alpha == 0) - return 0xf0; - /* 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 ((framebuffer.render_target->mode_info.mode_type - & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0) - { - if (red == framebuffer.render_target->mode_info.fg_red - && green == framebuffer.render_target->mode_info.fg_green - && blue == framebuffer.render_target->mode_info.fg_blue - && alpha == framebuffer.render_target->mode_info.fg_alpha) - return 1; - else - return 0; - } - else - { - grub_uint32_t value; - - red >>= 8 - framebuffer.render_target->mode_info.red_mask_size; - green >>= 8 - framebuffer.render_target->mode_info.green_mask_size; - blue >>= 8 - framebuffer.render_target->mode_info.blue_mask_size; - alpha >>= 8 - framebuffer.render_target->mode_info.reserved_mask_size; - - value = red << framebuffer.render_target->mode_info.red_field_pos; - value |= green << framebuffer.render_target->mode_info.green_field_pos; - value |= blue << framebuffer.render_target->mode_info.blue_field_pos; - value |= alpha << framebuffer.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 = &framebuffer.render_target->mode_info; - target_info.data = framebuffer.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 ((mode_info->mode_type - & GRUB_VIDEO_MODE_TYPE_ALPHA) != 0 - && color == 0xf0) - { - *red = 0; - *green = 0; - *blue = 0; - *alpha = 0; - return; - } - - /* If we have an out-of-bounds color, return transparent black. */ - if (color > 255) - { - *red = 0; - *green = 0; - *blue = 0; - *alpha = 0; - return; - } - - *red = framebuffer.palette[color].r; - *green = framebuffer.palette[color].g; - *blue = framebuffer.palette[color].b; - *alpha = framebuffer.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; - } -} - -static void -dirty (int y, int height) -{ - if (framebuffer.render_target != framebuffer.back_target) - return; - if (framebuffer.current_dirty.first_line > y) - framebuffer.current_dirty.first_line = y; - if (framebuffer.current_dirty.last_line < y + height) - framebuffer.current_dirty.last_line = y + height; -} - -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; - unsigned int area_x; - unsigned int area_y; - unsigned int area_width; - unsigned int area_height; - if (framebuffer.render_target->area_enabled) - { - area_x = framebuffer.render_target->area.x; - area_y = framebuffer.render_target->area.y; - area_width = framebuffer.render_target->area.width; - area_height = framebuffer.render_target->area.height; - x -= framebuffer.render_target->area_offset_x; - y -= framebuffer.render_target->area_offset_y; - } - else - { - area_x = framebuffer.render_target->viewport.x; - area_y = framebuffer.render_target->viewport.y; - area_width = framebuffer.render_target->viewport.width; - area_height = framebuffer.render_target->viewport.height; - } - - /* Make sure there is something to do. */ - if ((area_width == 0) || (area_height == 0)) - return GRUB_ERR_NONE; - if ((x >= (int)area_width) || (x + (int)width < 0)) - return GRUB_ERR_NONE; - if ((y >= (int)area_height) || (y + (int)height < 0)) - return GRUB_ERR_NONE; - - /* Do not allow drawing out of area. */ - if (x < 0) - { - width += x; - x = 0; - } - if (y < 0) - { - height += y; - y = 0; - } - - if ((x + width) > area_width) - width = area_width - x; - if ((y + height) > area_height) - height = area_height - y; - - /* Add area offset. */ - x += area_x; - y += area_y; - - dirty (y, height); - - /* Use fbblit_info to encapsulate rendering. */ - target.mode_info = &framebuffer.render_target->mode_info; - target.data = framebuffer.render_target->data; - - grub_video_fb_fill_dispatch (&target, color, x, y, - width, height); - return GRUB_ERR_NONE; -} - -static inline grub_err_t __attribute__ ((always_inline)) -grub_video_fb_blit_source (struct grub_video_fbblit_info *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 target; - unsigned int area_x; - unsigned int area_y; - unsigned int area_width; - unsigned int area_height; - if (framebuffer.render_target->area_enabled) - { - area_x = framebuffer.render_target->area.x; - area_y = framebuffer.render_target->area.y; - area_width = framebuffer.render_target->area.width; - area_height = framebuffer.render_target->area.height; - x -= framebuffer.render_target->area_offset_x; - y -= framebuffer.render_target->area_offset_y; - } - else - { - area_x = framebuffer.render_target->viewport.x; - area_y = framebuffer.render_target->viewport.y; - area_width = framebuffer.render_target->viewport.width; - area_height = framebuffer.render_target->viewport.height; - } - - /* Make sure there is something to do. */ - if ((area_width == 0) || (area_height == 0) || (width == 0) || (height == 0)) - return GRUB_ERR_NONE; - if ((x >= (int)area_width) || (x + (int)width < 0)) - return GRUB_ERR_NONE; - if ((y >= (int)area_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 area. */ - if ((x + width) > area_width) - width = area_width - x; - if ((y + height) > area_height) - height = area_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 += area_x; - y += area_y; - - /* Use fbblit_info to encapsulate rendering. */ - target.mode_info = &framebuffer.render_target->mode_info; - target.data = framebuffer.render_target->data; - - /* Do actual blitting. */ - dirty (y, height); - grub_video_fb_dispatch_blit (&target, source, oper, x, y, width, height, - offset_x, offset_y); - - return GRUB_ERR_NONE; -} - -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_info; - source_info.mode_info = &bitmap->mode_info; - source_info.data = bitmap->data; - - return grub_video_fb_blit_source (&source_info, oper, x, y, - offset_x, offset_y, width, 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) -{ - struct grub_video_fbblit_info source_info; - source_info.mode_info = &source->mode_info; - source_info.data = source->data; - - return grub_video_fb_blit_source (&source_info, oper, x, y, - offset_x, offset_y, width, height); -} - -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 = framebuffer.render_target->viewport.width - grub_abs (dx); - height = framebuffer.render_target->viewport.height - grub_abs (dy); - - dirty (framebuffer.render_target->viewport.y, - framebuffer.render_target->viewport.height); - - if (dx < 0) - { - src_x = framebuffer.render_target->viewport.x - dx; - dst_x = framebuffer.render_target->viewport.x; - } - else - { - src_x = framebuffer.render_target->viewport.x; - dst_x = framebuffer.render_target->viewport.x + dx; - } - - if (dy < 0) - { - src_y = framebuffer.render_target->viewport.y - dy; - dst_y = framebuffer.render_target->viewport.y; - } - else - { - src_y = framebuffer.render_target->viewport.y; - dst_y = framebuffer.render_target->viewport.y + dy; - } - - /* 2. Check if there is need to copy data. */ - if ((grub_abs (dx) < framebuffer.render_target->viewport.width) - && (grub_abs (dy) < framebuffer.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 = &framebuffer.render_target->mode_info; - target.data = framebuffer.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, framebuffer.render_target->viewport.width, dy); - else if (dy < 0) - { - if (framebuffer.render_target->viewport.height < grub_abs (dy)) - dy = -framebuffer.render_target->viewport.height; - - grub_video_fb_fill_rect (color, 0, framebuffer.render_target->viewport.height + dy, - framebuffer.render_target->viewport.width, -dy); - } - - /* 4b. Fill left & right parts. */ - if (dx > 0) - grub_video_fb_fill_rect (color, 0, 0, - dx, framebuffer.render_target->viewport.height); - else if (dx < 0) - { - if (framebuffer.render_target->viewport.width < grub_abs (dx)) - dx = -framebuffer.render_target->viewport.width; - - grub_video_fb_fill_rect (color, framebuffer.render_target->viewport.width + dx, 0, - -dx, framebuffer.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_BUG, - "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, region and area. */ - target->viewport.x = 0; - target->viewport.y = 0; - target->viewport.width = width; - target->viewport.height = height; - - target->region.x = 0; - target->region.y = 0; - target->region.width = width; - target->region.height = height; - - target->area_enabled = 0; - target->area.x = 0; - target->area.y = 0; - target->area.width = width; - target->area.height = height; - target->area_offset_x = 0; - target->area_offset_y = 0; - - /* Setup render target format. */ - target->mode_info.width = width; - target->mode_info.height = height; - switch (mode_type) - { - case GRUB_VIDEO_MODE_TYPE_INDEX_COLOR - | GRUB_VIDEO_MODE_TYPE_ALPHA: - target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR - | GRUB_VIDEO_MODE_TYPE_ALPHA; - target->mode_info.bpp = 8; - target->mode_info.bytes_per_pixel = 1; - target->mode_info.number_of_colors = 16; - target->mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR_ALPHA; - break; - default: - 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.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.number_of_colors = framebuffer.palette_size; /* Emulated palette. */ - target->mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_RGBA_8888; - break; - } - target->mode_info.pitch = target->mode_info.bytes_per_pixel * width; - - /* 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. */ - if (mode_type == (GRUB_VIDEO_MODE_TYPE_INDEX_COLOR - | GRUB_VIDEO_MODE_TYPE_ALPHA)) - grub_memset (target->data, 0xf0, size); - else - 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; - -#ifndef GRUB_HAVE_UNALIGNED_ACCESS - if (!(mode_info->bytes_per_pixel & (mode_info->bytes_per_pixel - 1)) - && ((grub_addr_t) ptr & (mode_info->bytes_per_pixel - 1))) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unaligned pointer"); - if (!(mode_info->bytes_per_pixel & (mode_info->bytes_per_pixel - 1)) - && (mode_info->pitch & (mode_info->bytes_per_pixel - 1))) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unaligned pitch"); -#endif - - /* 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, region and area to match new mode. */ - target->viewport.x = 0; - target->viewport.y = 0; - target->viewport.width = mode_info->width; - target->viewport.height = mode_info->height; - - target->region.x = 0; - target->region.y = 0; - target->region.width = mode_info->width; - target->region.height = mode_info->height; - - target->area_enabled = 0; - target->area.x = 0; - target->area.y = 0; - target->area.width = mode_info->width; - target->area.height = mode_info->height; - target->area_offset_x = 0; - target->area_offset_y = 0; - - /* 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 == (struct grub_video_fbrender_target *) - GRUB_VIDEO_RENDER_TARGET_DISPLAY) - target = framebuffer.back_target; - - if (! target->data) - return grub_error (GRUB_ERR_BUG, - "invalid render target given"); - - framebuffer.render_target = target; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **target) -{ - *target = framebuffer.render_target; - - if (*target == framebuffer.back_target) - *target = (struct grub_video_fbrender_target *) GRUB_VIDEO_RENDER_TARGET_DISPLAY; - - return GRUB_ERR_NONE; -} - -static grub_err_t -doublebuf_blit_update_screen (void) -{ - if (framebuffer.current_dirty.first_line - <= framebuffer.current_dirty.last_line) - { - grub_size_t copy_size; - - if (grub_sub (framebuffer.current_dirty.last_line, - framebuffer.current_dirty.first_line, ©_size) || - grub_mul (framebuffer.back_target->mode_info.pitch, copy_size, ©_size)) - { - /* Shouldn't happen, but if it does we've a bug. */ - return GRUB_ERR_BUG; - } - - grub_memcpy ((char *) framebuffer.pages[0] + framebuffer.current_dirty.first_line * - framebuffer.back_target->mode_info.pitch, - (char *) framebuffer.back_target->data + framebuffer.current_dirty.first_line * - framebuffer.back_target->mode_info.pitch, - copy_size); - } - framebuffer.current_dirty.first_line - = framebuffer.back_target->mode_info.height; - framebuffer.current_dirty.last_line = 0; - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **back, - struct grub_video_mode_info mode_info, - volatile void *framebuf) -{ - grub_err_t err; - grub_size_t page_size = (grub_size_t) mode_info.pitch * mode_info.height; - - framebuffer.offscreen_buffer = grub_zalloc (page_size); - if (! framebuffer.offscreen_buffer) - return grub_errno; - - err = grub_video_fb_create_render_target_from_pointer (&framebuffer.back_target, - &mode_info, - framebuffer.offscreen_buffer); - - if (err) - { - grub_free (framebuffer.offscreen_buffer); - framebuffer.offscreen_buffer = 0; - return grub_errno; - } - (*back)->is_allocated = 1; - - framebuffer.update_screen = doublebuf_blit_update_screen; - framebuffer.pages[0] = framebuf; - framebuffer.displayed_page = 0; - framebuffer.render_page = 0; - framebuffer.current_dirty.first_line = mode_info.height; - framebuffer.current_dirty.last_line = 0; - - return GRUB_ERR_NONE; -} - -static grub_err_t -doublebuf_pageflipping_update_screen (void) -{ - int new_displayed_page; - grub_err_t err; - int first_line, last_line; - - first_line = framebuffer.current_dirty.first_line; - last_line = framebuffer.current_dirty.last_line; - if (first_line > framebuffer.previous_dirty.first_line) - first_line = framebuffer.previous_dirty.first_line; - if (last_line < framebuffer.previous_dirty.last_line) - last_line = framebuffer.previous_dirty.last_line; - - if (first_line <= last_line) - { - grub_size_t copy_size; - - if (grub_sub (last_line, first_line, ©_size) || - grub_mul (framebuffer.back_target->mode_info.pitch, copy_size, ©_size)) - { - /* Shouldn't happen, but if it does we've a bug. */ - return GRUB_ERR_BUG; - } - - grub_memcpy ((char *) framebuffer.pages[framebuffer.render_page] + first_line * - framebuffer.back_target->mode_info.pitch, - (char *) framebuffer.back_target->data + first_line * - framebuffer.back_target->mode_info.pitch, - copy_size); - } - - framebuffer.previous_dirty = framebuffer.current_dirty; - framebuffer.current_dirty.first_line - = framebuffer.back_target->mode_info.height; - framebuffer.current_dirty.last_line = 0; - - /* 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 = framebuffer.set_page (framebuffer.displayed_page); - if (err) - { - /* Restore previous state. */ - framebuffer.render_page = framebuffer.displayed_page; - framebuffer.displayed_page = new_displayed_page; - return err; - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -doublebuf_pageflipping_init (struct grub_video_mode_info *mode_info, - volatile void *page0_ptr, - grub_video_fb_set_page_t set_page_in, - volatile void *page1_ptr) -{ - grub_err_t err; - grub_size_t page_size = 0; - - if (grub_mul (mode_info->pitch, mode_info->height, &page_size)) - { - /* Shouldn't happen, but if it does we've a bug. */ - return GRUB_ERR_BUG; - } - - framebuffer.offscreen_buffer = grub_malloc (page_size); - if (! framebuffer.offscreen_buffer) - { - return grub_errno; - } - - err = grub_video_fb_create_render_target_from_pointer (&framebuffer.back_target, - mode_info, - framebuffer.offscreen_buffer); - - if (err) - { - grub_free (framebuffer.offscreen_buffer); - framebuffer.offscreen_buffer = 0; - return grub_errno; - } - framebuffer.back_target->is_allocated = 1; - - framebuffer.displayed_page = 0; - framebuffer.render_page = 1; - - framebuffer.update_screen = doublebuf_pageflipping_update_screen; - framebuffer.pages[0] = page0_ptr; - framebuffer.pages[1] = page1_ptr; - - framebuffer.current_dirty.first_line - = framebuffer.back_target->mode_info.height; - framebuffer.current_dirty.last_line = 0; - framebuffer.previous_dirty.first_line - = framebuffer.back_target->mode_info.height; - framebuffer.previous_dirty.last_line = 0; - - /* Set the framebuffer memory data pointer and display the right page. */ - err = set_page_in (framebuffer.displayed_page); - if (err) - { - grub_video_fb_delete_render_target (framebuffer.back_target); - return err; - } - framebuffer.set_page = set_page_in; - - return GRUB_ERR_NONE; -} - -/* Select the best double buffering mode available. */ -grub_err_t -grub_video_fb_setup (unsigned int mode_type, unsigned int mode_mask, - struct grub_video_mode_info *mode_info, - volatile void *page0_ptr, - grub_video_fb_set_page_t set_page_in, - volatile void *page1_ptr) -{ - grub_err_t err; - - /* Do double buffering only if it's either requested or efficient. */ - if (set_page_in && grub_video_check_mode_flag (mode_type, mode_mask, - GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED, - 1)) - { - mode_info->mode_type |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; - mode_info->mode_type |= GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP; - - err = doublebuf_pageflipping_init (mode_info, page0_ptr, - set_page_in, - page1_ptr); - if (!err) - { - framebuffer.render_target = framebuffer.back_target; - return GRUB_ERR_NONE; - } - - 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, - 1)) - { - /* It was much nicer with the cast directly at function call but - some older gcc versions don't accept it properly.*/ - void *tmp = (void *) page0_ptr; - mode_info->mode_type |= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED - | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); - - err = grub_video_fb_doublebuf_blit_init (&framebuffer.back_target, - *mode_info, - tmp); - - if (!err) - { - framebuffer.render_target = framebuffer.back_target; - return GRUB_ERR_NONE; - } - - 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.back_target, - mode_info, - (void *) page0_ptr); - - if (err) - return err; - - framebuffer.update_screen = 0; - framebuffer.pages[0] = page0_ptr; - framebuffer.displayed_page = 0; - framebuffer.render_page = 0; - framebuffer.set_page = 0; - framebuffer.current_dirty.first_line - = framebuffer.back_target->mode_info.height; - framebuffer.current_dirty.last_line = 0; - - mode_info->mode_type &= ~GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; - - framebuffer.render_target = framebuffer.back_target; - - return GRUB_ERR_NONE; -} - - -grub_err_t -grub_video_fb_swap_buffers (void) -{ - grub_err_t err; - if (!framebuffer.update_screen) - return GRUB_ERR_NONE; - - err = framebuffer.update_screen (); - if (err) - return err; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_video_fb_get_info_and_fini (struct grub_video_mode_info *mode_info, - void **framebuf) -{ - grub_memcpy (mode_info, &(framebuffer.back_target->mode_info), - sizeof (*mode_info)); - - /* We are about to load a kernel. Switch back to page zero, since some - kernel drivers expect that. */ - if (framebuffer.set_page && framebuffer.displayed_page != 0) - { - framebuffer.update_screen (); - } - - *framebuf = (void *) framebuffer.pages[framebuffer.displayed_page]; - - grub_video_fb_fini (); - - return GRUB_ERR_NONE; -} diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c deleted file mode 100644 index a0bb9af09..000000000 --- a/grub-core/video/i386/pc/vbe.c +++ /dev/null @@ -1,1250 +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 . - */ - -#define grub_video_render_target grub_video_fbrender_target - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static int vbe_detected = -1; - -static struct grub_vbe_info_block controller_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; - - grub_uint8_t *ptr; - int mtrr; -} 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)); -} - -#define rdmsr(num,a,d) \ - asm volatile ("rdmsr" : "=a" (a), "=d" (d) : "c" (num)) - -#define wrmsr(num,lo,hi) \ - asm volatile ("wrmsr" : : "c" (num), "a" (lo), "d" (hi) : "memory") - -#define mtrr_base(reg) (0x200 + (reg) * 2) -#define mtrr_mask(reg) (0x200 + (reg) * 2 + 1) - -/* Try to set up a variable-range write-combining MTRR for a memory region. - This is best-effort; if it seems too hard, we just accept the performance - degradation rather than risking undefined behaviour. It is intended - exclusively to work around BIOS bugs, as the BIOS should already be - setting up a suitable MTRR. */ -static void -grub_vbe_enable_mtrr_entry (int mtrr) -{ - grub_uint32_t eax, edx; - grub_uint32_t mask_lo, mask_hi; - - rdmsr (mtrr_mask (mtrr), eax, edx); - mask_lo = eax; - mask_hi = edx; - - mask_lo |= 0x800 /* valid */; - wrmsr (mtrr_mask (mtrr), mask_lo, mask_hi); -} - -static void -grub_vbe_enable_mtrr (grub_uint8_t *base, grub_size_t size) -{ - grub_uint32_t eax, ebx, ecx, edx; - grub_uint32_t features; - grub_uint32_t mtrrcap; - int var_mtrrs; - grub_uint32_t max_extended_cpuid; - grub_uint32_t maxphyaddr; - grub_uint64_t fb_base, fb_size; - grub_uint64_t size_bits, fb_mask; - grub_uint32_t bits_lo, bits_hi; - grub_uint64_t bits; - int i, first_unused = -1; - grub_uint32_t base_lo, base_hi, mask_lo, mask_hi; - - fb_base = (grub_uint64_t) (grub_size_t) base; - fb_size = (grub_uint64_t) size; - - /* Check that fb_base and fb_size can be represented using a single - MTRR. */ - - if (fb_base < (1 << 20)) - return; /* under 1MB, so covered by fixed-range MTRRs */ - if (fb_base >= (1LL << 36)) - return; /* over 36 bits, so out of range */ - if (fb_size < (1 << 12)) - return; /* variable-range MTRRs must cover at least 4KB */ - - size_bits = fb_size; - while (size_bits > 1) - size_bits >>= 1; - if (size_bits != 1) - return; /* not a power of two */ - - if (fb_base & (fb_size - 1)) - return; /* not aligned on size boundary */ - - fb_mask = ~(fb_size - 1); - - /* Check CPU capabilities. */ - - if (! grub_cpu_is_cpuid_supported ()) - return; - - grub_cpuid (1, eax, ebx, ecx, edx); - features = edx; - if (! (features & 0x00001000)) /* MTRR */ - return; - - rdmsr (0xFE, eax, edx); - mtrrcap = eax; - if (! (mtrrcap & 0x00000400)) /* write-combining */ - return; - var_mtrrs = (mtrrcap & 0xFF); - - grub_cpuid (0x80000000, eax, ebx, ecx, edx); - max_extended_cpuid = eax; - if (max_extended_cpuid >= 0x80000008) - { - grub_cpuid (0x80000008, eax, ebx, ecx, edx); - maxphyaddr = (eax & 0xFF); - } - else - maxphyaddr = 36; - bits_lo = 0xFFFFF000; /* assume maxphyaddr >= 36 */ - bits_hi = (1 << (maxphyaddr - 32)) - 1; - bits = bits_lo | ((grub_uint64_t) bits_hi << 32); - - /* Check whether an MTRR already covers this region. If not, take an - unused one if possible. */ - for (i = 0; i < var_mtrrs; i++) - { - rdmsr (mtrr_mask (i), eax, edx); - mask_lo = eax; - mask_hi = edx; - if (mask_lo & 0x800) /* valid */ - { - grub_uint64_t real_base, real_mask; - - rdmsr (mtrr_base (i), eax, edx); - base_lo = eax; - base_hi = edx; - - real_base = ((grub_uint64_t) (base_hi & bits_hi) << 32) | - (base_lo & bits_lo); - real_mask = ((grub_uint64_t) (mask_hi & bits_hi) << 32) | - (mask_lo & bits_lo); - if (real_base < (fb_base + fb_size) && - real_base + (~real_mask & bits) >= fb_base) - return; /* existing MTRR overlaps this region */ - } - else if (first_unused < 0) - first_unused = i; - } - - if (first_unused < 0) - return; /* all MTRRs in use */ - - /* Set up the first unused MTRR we found. */ - rdmsr (mtrr_base (first_unused), eax, edx); - base_lo = eax; - base_hi = edx; - rdmsr (mtrr_mask (first_unused), eax, edx); - mask_lo = eax; - mask_hi = edx; - - base_lo = (base_lo & ~bits_lo & ~0xFF) | - (fb_base & bits_lo) | 0x01 /* WC */; - base_hi = (base_hi & ~bits_hi) | ((fb_base >> 32) & bits_hi); - wrmsr (mtrr_base (first_unused), base_lo, base_hi); - mask_lo = (mask_lo & ~bits_lo) | (fb_mask & bits_lo) | 0x800 /* valid */; - mask_hi = (mask_hi & ~bits_hi) | ((fb_mask >> 32) & bits_hi); - wrmsr (mtrr_mask (first_unused), mask_lo, mask_hi); - - framebuffer.mtrr = first_unused; -} - -static void -grub_vbe_disable_mtrr (int mtrr) -{ - grub_uint32_t eax, edx; - grub_uint32_t mask_lo, mask_hi; - - rdmsr (mtrr_mask (mtrr), eax, edx); - mask_lo = eax; - mask_hi = edx; - - mask_lo &= ~0x800 /* valid */; - wrmsr (mtrr_mask (mtrr), mask_lo, mask_hi); -} - -/* Call VESA BIOS 0x4f09 to set palette data, return status. */ -static 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) -{ - struct grub_bios_int_registers regs; - regs.eax = 0x4f09; - regs.ebx = 0; - regs.ecx = color_count; - regs.edx = start_index; - regs.es = (((grub_addr_t) palette_data) & 0xffff0000) >> 4; - regs.edi = ((grub_addr_t) palette_data) & 0xffff; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - return regs.eax & 0xffff; -} - -/* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status. */ -grub_vbe_status_t -grub_vbe_bios_get_controller_info (struct grub_vbe_info_block *ci) -{ - struct grub_bios_int_registers regs; - /* Store *controller_info to %es:%di. */ - regs.es = (((grub_addr_t) ci) & 0xffff0000) >> 4; - regs.edi = ((grub_addr_t) ci) & 0xffff; - regs.eax = 0x4f00; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - return regs.eax & 0xffff; -} - -/* Call VESA BIOS 0x4f01 to get VBE Mode Information, return status. */ -grub_vbe_status_t -grub_vbe_bios_get_mode_info (grub_uint32_t mode, - struct grub_vbe_mode_info_block *mode_info) -{ - struct grub_bios_int_registers regs; - regs.eax = 0x4f01; - regs.ecx = mode; - /* Store *mode_info to %es:%di. */ - regs.es = ((grub_addr_t) mode_info & 0xffff0000) >> 4; - regs.edi = (grub_addr_t) mode_info & 0x0000ffff; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - return regs.eax & 0xffff; -} - -/* Call VESA BIOS 0x4f02 to set video mode, return status. */ -static grub_vbe_status_t -grub_vbe_bios_set_mode (grub_uint32_t mode, - struct grub_vbe_crtc_info_block *crtc_info) -{ - struct grub_bios_int_registers regs; - - regs.eax = 0x4f02; - regs.ebx = mode; - /* Store *crtc_info to %es:%di. */ - regs.es = (((grub_addr_t) crtc_info) & 0xffff0000) >> 4; - regs.edi = ((grub_addr_t) crtc_info) & 0xffff; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - - return regs.eax & 0xffff; -} - -/* Call VESA BIOS 0x4f03 to return current VBE Mode, return status. */ -grub_vbe_status_t -grub_vbe_bios_get_mode (grub_uint32_t *mode) -{ - struct grub_bios_int_registers regs; - - regs.eax = 0x4f03; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - *mode = regs.ebx & 0xffff; - - return regs.eax & 0xffff; -} - -grub_vbe_status_t -grub_vbe_bios_getset_dac_palette_width (int set, int *dac_mask_size) -{ - struct grub_bios_int_registers regs; - - regs.eax = 0x4f08; - regs.ebx = ((*dac_mask_size & 0xff) << 8) | (set ? 1 : 0); - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - *dac_mask_size = (regs.ebx >> 8) & 0xff; - - return regs.eax & 0xffff; -} - -/* Call VESA BIOS 0x4f05 to set memory window, return status. */ -grub_vbe_status_t -grub_vbe_bios_set_memory_window (grub_uint32_t window, - grub_uint32_t position) -{ - struct grub_bios_int_registers regs; - - /* BL = window, BH = 0, Set memory window. */ - regs.ebx = window & 0x00ff; - regs.edx = position; - regs.eax = 0x4f05; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - return regs.eax & 0xffff; -} - -/* Call VESA BIOS 0x4f05 to return memory window, return status. */ -grub_vbe_status_t -grub_vbe_bios_get_memory_window (grub_uint32_t window, - grub_uint32_t *position) -{ - struct grub_bios_int_registers regs; - - regs.eax = 0x4f05; - /* BH = 1, Get memory window. BL = window. */ - regs.ebx = (window & 0x00ff) | 0x100; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - - *position = regs.edx & 0xffff; - return regs.eax & 0xffff; -} - -/* Call VESA BIOS 0x4f06 to set scanline length (in bytes), return status. */ -grub_vbe_status_t -grub_vbe_bios_set_scanline_length (grub_uint32_t length) -{ - struct grub_bios_int_registers regs; - - regs.ecx = length; - regs.eax = 0x4f06; - /* BL = 2, Set Scan Line in Bytes. */ - regs.ebx = 0x0002; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - return regs.eax & 0xffff; -} - -/* Call VESA BIOS 0x4f06 to return scanline length (in bytes), return status. */ -grub_vbe_status_t -grub_vbe_bios_get_scanline_length (grub_uint32_t *length) -{ - struct grub_bios_int_registers regs; - - regs.eax = 0x4f06; - regs.ebx = 0x0001; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - /* BL = 1, Get Scan Line Length (in bytes). */ - grub_bios_interrupt (0x10, ®s); - - *length = regs.ebx & 0xffff; - return regs.eax & 0xffff; -} - -/* Call VESA BIOS 0x4f07 to set display start, return status. */ -static grub_vbe_status_t -grub_vbe_bios_set_display_start (grub_uint32_t x, grub_uint32_t y) -{ - struct grub_bios_int_registers regs; - - if (framebuffer.mtrr >= 0) - grub_vbe_disable_mtrr (framebuffer.mtrr); - - /* Store x in %ecx. */ - regs.ecx = x; - regs.edx = y; - regs.eax = 0x4f07; - /* BL = 80h, Set Display Start during Vertical Retrace. */ - regs.ebx = 0x0080; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - - if (framebuffer.mtrr >= 0) - grub_vbe_enable_mtrr_entry (framebuffer.mtrr); - - return regs.eax & 0xffff; -} - -/* Call VESA BIOS 0x4f07 to get display start, return status. */ -grub_vbe_status_t -grub_vbe_bios_get_display_start (grub_uint32_t *x, - grub_uint32_t *y) -{ - struct grub_bios_int_registers regs; - - regs.eax = 0x4f07; - /* BL = 1, Get Display Start. */ - regs.ebx = 0x0001; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - - *x = regs.ecx & 0xffff; - *y = regs.edx & 0xffff; - return regs.eax & 0xffff; -} - -/* Call VESA BIOS 0x4f0a. */ -grub_vbe_status_t -grub_vbe_bios_get_pm_interface (grub_uint16_t *segment, grub_uint16_t *offset, - grub_uint16_t *length) -{ - struct grub_bios_int_registers regs; - - regs.eax = 0x4f0a; - regs.ebx = 0x0000; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - - if ((regs.eax & 0xffff) != GRUB_VBE_STATUS_OK) - { - *segment = 0; - *offset = 0; - *length = 0; - } - - *segment = regs.es & 0xffff; - *offset = regs.edi & 0xffff; - *length = regs.ecx & 0xffff; - return regs.eax & 0xffff; -} - -/* Call VESA BIOS 0x4f11 to get flat panel information, return status. */ -static grub_vbe_status_t -grub_vbe_bios_get_flat_panel_info (struct grub_vbe_flat_panel_info *flat_panel_info) -{ - struct grub_bios_int_registers regs; - - regs.eax = 0x4f11; - regs.ebx = 0x0001; - regs.es = (((grub_addr_t) flat_panel_info) & 0xffff0000) >> 4; - regs.edi = ((grub_addr_t) flat_panel_info) & 0xffff; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - return regs.eax & 0xffff; -} - -/* Call VESA BIOS 0x4f15 to get DDC availability, return status. */ -static grub_vbe_status_t -grub_vbe_bios_get_ddc_capabilities (grub_uint8_t *level) -{ - struct grub_bios_int_registers regs; - - regs.eax = 0x4f15; - regs.ebx = 0x0000; - regs.ecx = 0x0000; - regs.es = 0x0000; - regs.edi = 0x0000; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - - *level = regs.ebx & 0xff; - return regs.eax & 0xffff; -} - -/* Call VESA BIOS 0x4f15 to read EDID information, return status. */ -static grub_vbe_status_t -grub_vbe_bios_read_edid (struct grub_video_edid_info *edid_info) -{ - struct grub_bios_int_registers regs; - - regs.eax = 0x4f15; - regs.ebx = 0x0001; - regs.ecx = 0x0000; - regs.edx = 0x0000; - regs.es = (((grub_addr_t) edid_info) & 0xffff0000) >> 4; - regs.edi = ((grub_addr_t) edid_info) & 0xffff; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - return regs.eax & 0xffff; -} - -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_absolute_pointer (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; -} - -static grub_err_t -grub_video_vbe_get_edid (struct grub_video_edid_info *edid_info) -{ - struct grub_video_edid_info *edid_info_lowmem; - - /* Use low memory scratch area as temporary storage for VESA BIOS calls. */ - edid_info_lowmem = - (struct grub_video_edid_info *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; - grub_memset (edid_info_lowmem, 0, sizeof (*edid_info_lowmem)); - - if (grub_vbe_bios_read_edid (edid_info_lowmem) != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_BAD_DEVICE, "EDID information not available"); - - grub_memcpy (edid_info, edid_info_lowmem, sizeof (*edid_info)); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height) -{ - grub_vbe_status_t status; - grub_uint8_t ddc_level; - struct grub_video_edid_info edid_info; - struct grub_vbe_flat_panel_info *flat_panel_info; - - /* Use low memory scratch area as temporary storage for VESA BIOS calls. */ - flat_panel_info = (struct grub_vbe_flat_panel_info *) - grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + sizeof (struct grub_video_edid_info)); - - if (controller_info.version >= 0x200 - && (grub_vbe_bios_get_ddc_capabilities (&ddc_level) & 0xff) - == GRUB_VBE_STATUS_OK) - { - if (grub_video_vbe_get_edid (&edid_info) == GRUB_ERR_NONE - && grub_video_edid_checksum (&edid_info) == GRUB_ERR_NONE - && grub_video_edid_preferred_mode (&edid_info, width, height) - == GRUB_ERR_NONE && *width < 4096 && *height < 4096) - return GRUB_ERR_NONE; - - grub_errno = GRUB_ERR_NONE; - } - - grub_memset (flat_panel_info, 0, sizeof (*flat_panel_info)); - status = grub_vbe_bios_get_flat_panel_info (flat_panel_info); - if (status == GRUB_VBE_STATUS_OK - && flat_panel_info->horizontal_size && flat_panel_info->vertical_size - && flat_panel_info->horizontal_size < 4096 - && flat_panel_info->vertical_size < 4096) - { - *width = flat_panel_info->horizontal_size; - *height = flat_panel_info->vertical_size; - return GRUB_ERR_NONE; - } - - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot get preferred mode"); -} - -static 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. */ - if (new_vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL - && new_vbe_mode_info.memory_model - != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR) - 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; - - if (vbe_mode < 0x100) - { - /* If this is not a VESA mode, guess address. */ - framebuffer.ptr = (grub_uint8_t *) 0xa0000; - } - else - { - framebuffer.ptr = (grub_uint8_t *) new_vbe_mode_info.phys_base_addr; - } - - /* 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. */ - - /* If video mode is in indexed color, setup default VGA palette. */ - if (vbe_mode < 0x100 || new_vbe_mode_info.memory_model - == GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL) - { - struct grub_vbe_palette_data *palette - = (struct grub_vbe_palette_data *) grub_absolute_pointer (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)); - framebuffer.mtrr = -1; - - 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. */ - if (last_set_mode != initial_vbe_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 (); - if (framebuffer.mtrr >= 0) - { - grub_vbe_disable_mtrr (framebuffer.mtrr); - framebuffer.mtrr = -1; - } - 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_set_page (int page) -{ - /* Tell the video adapter to display the new front page. */ - int display_start_line - = framebuffer.mode_info.height * 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 void -vbe2videoinfo (grub_uint32_t mode, - const struct grub_vbe_mode_info_block *vbeinfo, - struct grub_video_mode_info *mode_info) -{ - mode_info->mode_number = mode; - - mode_info->width = vbeinfo->x_resolution; - mode_info->height = vbeinfo->y_resolution; - mode_info->mode_type = 0; - switch (vbeinfo->memory_model) - { - case GRUB_VBE_MEMORY_MODEL_TEXT: - mode_info->mode_type |= GRUB_VIDEO_MODE_TYPE_PURE_TEXT; - break; - - /* CGA is basically 4-bit packed pixel. */ - case GRUB_VBE_MEMORY_MODEL_CGA: - mode_info->mode_type |= GRUB_VIDEO_MODE_TYPE_CGA; - /* Fallthrough. */ - case GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL: - mode_info->mode_type |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; - break; - - case GRUB_VBE_MEMORY_MODEL_HERCULES: - mode_info->mode_type |= GRUB_VIDEO_MODE_TYPE_HERCULES - | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP; - break; - - /* Non chain 4 is a special case of planar. */ - case GRUB_VBE_MEMORY_MODEL_NONCHAIN4_256: - mode_info->mode_type |= GRUB_VIDEO_MODE_TYPE_NONCHAIN4; - /* Fallthrough. */ - case GRUB_VBE_MEMORY_MODEL_PLANAR: - mode_info->mode_type |= GRUB_VIDEO_MODE_TYPE_PLANAR - | GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; - break; - - case GRUB_VBE_MEMORY_MODEL_YUV: - mode_info->mode_type |= GRUB_VIDEO_MODE_TYPE_YUV; - break; - - case GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR: - mode_info->mode_type |= GRUB_VIDEO_MODE_TYPE_RGB; - break; - default: - mode_info->mode_type |= GRUB_VIDEO_MODE_TYPE_UNKNOWN; - break; - } - - mode_info->bpp = vbeinfo->bits_per_pixel; - /* Calculate bytes_per_pixel value. */ - switch(vbeinfo->bits_per_pixel) - { - case 32: - mode_info->bytes_per_pixel = 4; - break; - case 24: - mode_info->bytes_per_pixel = 3; - break; - case 16: - mode_info->bytes_per_pixel = 2; - break; - case 15: - mode_info->bytes_per_pixel = 2; - break; - case 8: - mode_info->bytes_per_pixel = 1; - break; - case 4: - mode_info->bytes_per_pixel = 0; - break; - } - - if (controller_info.version >= 0x300) - mode_info->pitch = vbeinfo->lin_bytes_per_scan_line; - else - mode_info->pitch = vbeinfo->bytes_per_scan_line; - - if (mode_info->mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) - mode_info->number_of_colors = 16; - else - mode_info->number_of_colors = 256; - mode_info->red_mask_size = vbeinfo->red_mask_size; - mode_info->red_field_pos = vbeinfo->red_field_position; - mode_info->green_mask_size = vbeinfo->green_mask_size; - mode_info->green_field_pos = vbeinfo->green_field_position; - mode_info->blue_mask_size = vbeinfo->blue_mask_size; - mode_info->blue_field_pos = vbeinfo->blue_field_position; - mode_info->reserved_mask_size = vbeinfo->rsvd_mask_size; - mode_info->reserved_field_pos = vbeinfo->rsvd_field_position; - - mode_info->blit_format = grub_video_get_blit_format (mode_info); -} - -static int -grub_video_vbe_iterate (int (*hook) (const struct grub_video_mode_info *info, void *hook_arg), void *hook_arg) -{ - grub_uint16_t *p; - struct grub_vbe_mode_info_block vbe_mode_info; - struct grub_video_mode_info mode_info; - - for (p = vbe_mode_list; *p != 0xFFFF; p++) - { - grub_vbe_get_video_mode_info (*p, &vbe_mode_info); - if (grub_errno != GRUB_ERR_NONE) - { - /* Could not retrieve mode info, retreat. */ - grub_errno = GRUB_ERR_NONE; - break; - } - - vbe2videoinfo (*p, &vbe_mode_info, &mode_info); - if (hook (&mode_info, hook_arg)) - return 1; - } - return 0; -} - -static grub_err_t -grub_video_vbe_setup (unsigned int width, unsigned int height, - grub_video_mode_type_t mode_type, - grub_video_mode_type_t 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; - int preferred_mode = 0; - - /* 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 == 0 && height == 0) - { - grub_vbe_get_preferred_mode (&width, &height); - if (grub_errno == GRUB_ERR_NONE) - preferred_mode = 1; - else - { - /* Fall back to 640x480. This is conservative, but the largest - mode supported by the graphics card may not be safe for the - display device. */ - grub_errno = GRUB_ERR_NONE; - width = 640; - height = 480; - } - } - - /* 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 & GRUB_VBE_MODEATTR_SUPPORTED) == 0) - /* If not available, skip it. */ - continue; - - if ((vbe_mode_info.mode_attributes & GRUB_VBE_MODEATTR_COLOR) == 0) - /* Monochrome is unusable. */ - continue; - - if ((vbe_mode_info.mode_attributes & GRUB_VBE_MODEATTR_LFB_AVAIL) == 0) - /* We support only linear frame buffer modes. */ - continue; - - if ((vbe_mode_info.mode_attributes & GRUB_VBE_MODEATTR_GRAPHICS) == 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.bits_per_pixel != 8 - && vbe_mode_info.bits_per_pixel != 15 - && vbe_mode_info.bits_per_pixel != 16 - && vbe_mode_info.bits_per_pixel != 24 - && vbe_mode_info.bits_per_pixel != 32) - /* Unsupported bitdepth . */ - continue; - - if (preferred_mode) - { - if (vbe_mode_info.x_resolution > width - || vbe_mode_info.y_resolution > height) - /* Resolution exceeds that of preferred mode. */ - continue; - } - else - { - 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; - static struct grub_vbe_mode_info_block active_vbe_mode_info; - /* If this fails, then we have mode selection heuristics problem, - or adapter failure. */ - grub_vbe_set_video_mode (best_vbe_mode, &active_vbe_mode_info); - if (grub_errno != GRUB_ERR_NONE) - return grub_errno; - - /* Fill mode info details. */ - vbe2videoinfo (best_vbe_mode, &active_vbe_mode_info, - &framebuffer.mode_info); - - { - /* Get video RAM size in bytes. */ - grub_size_t vram_size = controller_info.total_memory << 16; - grub_size_t page_size; /* The size of a page in bytes. */ - - page_size = framebuffer.mode_info.pitch * framebuffer.mode_info.height; - - if (vram_size >= 2 * page_size) - err = grub_video_fb_setup (mode_type, mode_mask, - &framebuffer.mode_info, - framebuffer.ptr, - doublebuf_pageflipping_set_page, - framebuffer.ptr + page_size); - else - err = grub_video_fb_setup (mode_type, mode_mask, - &framebuffer.mode_info, - framebuffer.ptr, 0, 0); - } - - /* Copy default palette to initialize emulated palette. */ - err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, - grub_video_fbstd_colors); - - grub_vbe_enable_mtrr (framebuffer.ptr, - controller_info.total_memory << 16); - - 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.mode_info.mode_type == GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) - { - /* 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_get_info_and_fini (struct grub_video_mode_info *mode_info, - void **framebuf) -{ - grub_err_t err; - grub_free (vbe_mode_list); - vbe_mode_list = NULL; - err = grub_video_fb_get_info_and_fini (mode_info, framebuf); - if (err) - return err; - if (framebuffer.mtrr >= 0) - { - grub_vbe_disable_mtrr (framebuffer.mtrr); - framebuffer.mtrr = -1; - } - return GRUB_ERR_NONE; -} - -static void -grub_video_vbe_print_adapter_specific_info (void) -{ - grub_printf_ (N_(" 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_ (N_(" total memory: %d KiB\n"), - (controller_info.total_memory << 6)); -} - -static struct grub_video_adapter grub_video_vbe_adapter = - { - .name = "VESA BIOS Extension Video Driver", - .id = GRUB_VIDEO_DRIVER_VBE, - - .prio = GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE, - - .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, - .set_region = grub_video_fb_set_region, - .get_region = grub_video_fb_get_region, - .set_area_status = grub_video_fb_set_area_status, - .get_area_status = grub_video_fb_get_area_status, - .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_fb_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_fb_set_active_render_target, - .get_active_render_target = grub_video_fb_get_active_render_target, - .iterate = grub_video_vbe_iterate, - .get_edid = grub_video_vbe_get_edid, - .print_adapter_specific_info = grub_video_vbe_print_adapter_specific_info, - - .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/i386/pc/vga.c b/grub-core/video/i386/pc/vga.c deleted file mode 100644 index 50d0b5e02..000000000 --- a/grub-core/video/i386/pc/vga.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 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 . - */ - -#define grub_video_render_target grub_video_fbrender_target - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define VGA_WIDTH 640 -#define VGA_MEM ((grub_uint8_t *) 0xa0000) -#define PAGE_OFFSET(x) ((x) * (VGA_WIDTH * vga_height / 8)) - -static unsigned char text_mode; -static unsigned char saved_map_mask; -static int vga_height; - -static struct -{ - struct grub_video_mode_info mode_info; - struct grub_video_render_target *render_target; - grub_uint8_t *temporary_buffer; - int front_page; - int back_page; -} framebuffer; - -static unsigned char -grub_vga_set_mode (unsigned char mode) -{ - struct grub_bios_int_registers regs; - unsigned char ret; - /* get current mode */ - regs.eax = 0x0f00; - regs.ebx = 0; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - - ret = regs.eax & 0xff; - regs.eax = mode; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - grub_bios_interrupt (0x10, ®s); - - return ret; -} - -static inline void -wait_vretrace (void) -{ - /* Wait until there is a vertical retrace. */ - while (! (grub_inb (GRUB_VGA_IO_INPUT_STATUS1_REGISTER) - & GRUB_VGA_IO_INPUT_STATUS1_VERTR_BIT)); -} - -/* Get Map Mask Register. */ -static unsigned char -get_map_mask (void) -{ - return grub_vga_sr_read (GRUB_VGA_SR_MAP_MASK_REGISTER); -} - -/* Set Map Mask Register. */ -static void -set_map_mask (unsigned char mask) -{ - grub_vga_sr_write (mask, GRUB_VGA_SR_MAP_MASK_REGISTER); -} - -#if 0 -/* Set Read Map Register. */ -static void -set_read_map (unsigned char map) -{ - grub_vga_gr_write (map, GRUB_VGA_GR_READ_MAP_REGISTER); -} -#endif - -/* Set start address. */ -static void -set_start_address (unsigned int start) -{ - grub_vga_cr_write (start & 0xFF, GRUB_VGA_CR_START_ADDR_LOW_REGISTER); - grub_vga_cr_write (start >> 8, GRUB_VGA_CR_START_ADDR_HIGH_REGISTER); -} - -static int setup = 0; -static int is_target = 0; - -static grub_err_t -grub_video_vga_init (void) -{ - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_vga_setup (unsigned int width, unsigned int height, - grub_video_mode_type_t mode_type, - grub_video_mode_type_t mode_mask) -{ - grub_err_t err; - - if ((width && width != VGA_WIDTH) || (height && height != 350 && height != 480)) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found"); - - vga_height = height ? : 480; - - framebuffer.temporary_buffer = grub_calloc (vga_height, VGA_WIDTH); - framebuffer.front_page = 0; - framebuffer.back_page = 0; - if (!framebuffer.temporary_buffer) - return grub_errno; - - saved_map_mask = get_map_mask (); - - text_mode = grub_vga_set_mode (vga_height == 480 ? 0x12 : 0x10); - setup = 1; - set_map_mask (0x0f); - set_start_address (PAGE_OFFSET (framebuffer.front_page)); - - framebuffer.mode_info.width = VGA_WIDTH; - framebuffer.mode_info.height = vga_height; - - framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; - - if (grub_video_check_mode_flag (mode_type, mode_mask, - GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED, - (VGA_WIDTH * vga_height <= (1 << 18)))) - { - framebuffer.back_page = 1; - framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED - | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP; - } - - framebuffer.mode_info.bpp = 8; - framebuffer.mode_info.bytes_per_pixel = 1; - framebuffer.mode_info.pitch = VGA_WIDTH; - framebuffer.mode_info.number_of_colors = 16; - framebuffer.mode_info.red_mask_size = 0; - framebuffer.mode_info.red_field_pos = 0; - framebuffer.mode_info.green_mask_size = 0; - framebuffer.mode_info.green_field_pos = 0; - framebuffer.mode_info.blue_mask_size = 0; - 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); - - err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, - &framebuffer.mode_info, - framebuffer.temporary_buffer); - - if (err) - { - grub_dprintf ("video", "Couldn't create FB target\n"); - return err; - } - - is_target = 1; - 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 GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_vga_fini (void) -{ - if (setup) - { - set_map_mask (saved_map_mask); - grub_vga_set_mode (text_mode); - } - setup = 0; - grub_free (framebuffer.temporary_buffer); - framebuffer.temporary_buffer = 0; - return GRUB_ERR_NONE; -} - -static inline void -update_target (void) -{ - int plane; - - if (!is_target) - return; - - for (plane = 0x01; plane <= 0x08; plane <<= 1) - { - grub_uint8_t *ptr; - volatile grub_uint8_t *ptr2; - unsigned cbyte = 0; - int shift = 7; - set_map_mask (plane); - for (ptr = framebuffer.temporary_buffer, - ptr2 = VGA_MEM + PAGE_OFFSET (framebuffer.back_page); - ptr < framebuffer.temporary_buffer + VGA_WIDTH * vga_height; ptr++) - { - cbyte |= (!!(plane & *ptr)) << shift; - shift--; - if (shift == -1) - { - *ptr2++ = cbyte; - shift = 7; - cbyte = 0; - } - } - } -} - -static grub_err_t -grub_video_vga_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 ret; - ret = grub_video_fb_blit_bitmap (bitmap, oper, x, y, offset_x, offset_y, - width, height); - if (!(framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)) - update_target (); - return ret; -} - -static grub_err_t -grub_video_vga_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 ret; - - ret = grub_video_fb_blit_render_target (source, oper, x, y, - offset_x, offset_y, width, height); - if (!(framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)) - update_target (); - - return ret; -} - -static grub_err_t -grub_video_vga_set_active_render_target (struct grub_video_render_target *target) -{ - if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY) - { - is_target = 1; - target = framebuffer.render_target; - } - else - is_target = 0; - - return grub_video_fb_set_active_render_target (target); -} - -static grub_err_t -grub_video_vga_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.render_target) - *target = GRUB_VIDEO_RENDER_TARGET_DISPLAY; - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_vga_swap_buffers (void) -{ - if (!(framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)) - return GRUB_ERR_NONE; - - update_target (); - - if ((VGA_WIDTH * vga_height <= (1 << 18))) - { - /* Activate the other page. */ - framebuffer.front_page = !framebuffer.front_page; - framebuffer.back_page = !framebuffer.back_page; - wait_vretrace (); - set_start_address (PAGE_OFFSET (framebuffer.front_page)); - } - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_vga_set_palette (unsigned int start __attribute__ ((unused)), - unsigned int count __attribute__ ((unused)), - struct grub_video_palette_data *palette_data __attribute__ ((unused))) -{ - return grub_error (GRUB_ERR_IO, "can't change palette"); -} - -static grub_err_t -grub_video_vga_get_info_and_fini (struct grub_video_mode_info *mode_info, - void **framebuf) -{ - set_map_mask (0xf); - - grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info)); - mode_info->bpp = 1; - mode_info->bytes_per_pixel = 0; - mode_info->pitch = VGA_WIDTH / 8; - mode_info->number_of_colors = 1; - - mode_info->bg_red = 0; - mode_info->bg_green = 0; - mode_info->bg_blue = 0; - mode_info->bg_alpha = 255; - - mode_info->fg_red = 255; - mode_info->fg_green = 255; - mode_info->fg_blue = 255; - mode_info->fg_alpha = 255; - - *framebuf = VGA_MEM + PAGE_OFFSET (framebuffer.front_page); - - grub_video_fb_fini (); - grub_free (framebuffer.temporary_buffer); - framebuffer.temporary_buffer = 0; - setup = 0; - - return GRUB_ERR_NONE; -} - - -static struct grub_video_adapter grub_video_vga_adapter = - { - .name = "VGA Video Driver", - .id = GRUB_VIDEO_DRIVER_VGA, - - .prio = GRUB_VIDEO_ADAPTER_PRIO_FALLBACK, - - .init = grub_video_vga_init, - .fini = grub_video_vga_fini, - .setup = grub_video_vga_setup, - .get_info = grub_video_fb_get_info, - .get_info_and_fini = grub_video_vga_get_info_and_fini, - .set_palette = grub_video_vga_set_palette, - .get_palette = grub_video_fb_get_palette, - .set_viewport = grub_video_fb_set_viewport, - .get_viewport = grub_video_fb_get_viewport, - .set_region = grub_video_fb_set_region, - .get_region = grub_video_fb_get_region, - .set_area_status = grub_video_fb_set_area_status, - .get_area_status = grub_video_fb_get_area_status, - .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_vga_blit_bitmap, - .blit_render_target = grub_video_vga_blit_render_target, - .scroll = grub_video_fb_scroll, - .swap_buffers = grub_video_vga_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_vga_set_active_render_target, - .get_active_render_target = grub_video_vga_get_active_render_target, - - .next = 0 - }; - -GRUB_MOD_INIT(vga) -{ - grub_video_register (&grub_video_vga_adapter); -} - -GRUB_MOD_FINI(vga) -{ - grub_video_unregister (&grub_video_vga_adapter); -} diff --git a/grub-core/video/ieee1275.c b/grub-core/video/ieee1275.c deleted file mode 100644 index ca3d3c3b2..000000000 --- a/grub-core/video/ieee1275.c +++ /dev/null @@ -1,369 +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 . - */ - -#define grub_video_render_target grub_video_fbrender_target - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* Only 8-bit indexed color is supported for now. */ - -static unsigned old_width, old_height; -static int restore_needed; -static char *display; -static grub_ieee1275_ihandle_t stdout_ihandle; -static int have_setcolors = 0; - -static struct -{ - struct grub_video_mode_info mode_info; - grub_uint8_t *ptr; -} framebuffer; - -static struct grub_video_palette_data serial_colors[] = - { - // {R, G, B} - {0x00, 0x00, 0x00, 0xFF}, // 0 = black - {0xA8, 0x00, 0x00, 0xFF}, // 1 = red - {0x00, 0xA8, 0x00, 0xFF}, // 2 = green - {0xFE, 0xFE, 0x54, 0xFF}, // 3 = yellow - {0x00, 0x00, 0xA8, 0xFF}, // 4 = blue - {0xA8, 0x00, 0xA8, 0xFF}, // 5 = magenta - {0x00, 0xA8, 0xA8, 0xFF}, // 6 = cyan - {0xFE, 0xFE, 0xFE, 0xFF} // 7 = white - }; - - -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 int -find_display_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; -} - -static void -find_display (void) -{ - grub_ieee1275_devices_iterate (find_display_hook); -} - -static grub_err_t -grub_video_ieee1275_init (void) -{ - grub_ssize_t actual; - - grub_memset (&framebuffer, 0, sizeof(framebuffer)); - - if (!grub_ieee1275_get_integer_property (grub_ieee1275_chosen, - "stdout", &stdout_ihandle, - sizeof (stdout_ihandle), &actual) - && actual == sizeof (stdout_ihandle)) - have_setcolors = 1; - - 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; - - if (grub_ieee1275_get_integer_property (dev, "depth", &tmp, - sizeof (tmp), 0)) - tmp = 4; - - out->mode_type = GRUB_VIDEO_MODE_TYPE_RGB; - out->bpp = tmp; - out->bytes_per_pixel = (out->bpp + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT; - out->number_of_colors = 256; - - switch (tmp) - { - case 4: - case 8: - out->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; - out->bpp = 8; - if (have_setcolors) - out->number_of_colors = 1 << tmp; - else - out->number_of_colors = 8; - break; - - /* FIXME: we may need byteswapping for the following. Currently it - was seen only on qemu and no byteswap was needed. */ - case 15: - out->red_mask_size = 5; - out->red_field_pos = 10; - out->green_mask_size = 5; - out->green_field_pos = 5; - out->blue_mask_size = 5; - out->blue_field_pos = 0; - break; - - case 16: - out->red_mask_size = 5; - out->red_field_pos = 11; - out->green_mask_size = 6; - out->green_field_pos = 5; - out->blue_mask_size = 5; - out->blue_field_pos = 0; - break; - - case 32: - out->reserved_mask_size = 8; - out->reserved_field_pos = 24; - /* FALLTHROUGH */ - - case 24: - 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; - break; - default: - return grub_error (GRUB_ERR_IO, "unsupported video depth %d", tmp); - } - - 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", ¤t_width, - sizeof (current_width), 0)) - return grub_error (GRUB_ERR_IO, "Couldn't retrieve display width."); - - if (grub_ieee1275_get_integer_property (dev, "height", ¤t_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_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_setup (mode_type, mode_mask, - &framebuffer.mode_info, - framebuffer.ptr, NULL, NULL); - if (err) - return err; - - grub_video_ieee1275_set_palette (0, framebuffer.mode_info.number_of_colors, - grub_video_fbstd_colors); - - return err; -} - -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) -{ - unsigned col; - struct grub_video_palette_data fb_palette_data[256]; - grub_err_t err; - - if (!(framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)) - return grub_video_fb_set_palette (start, count, palette_data); - - if (!have_setcolors) - return grub_video_fb_set_palette (0, ARRAY_SIZE (serial_colors), - serial_colors); - - if (start >= framebuffer.mode_info.number_of_colors) - return GRUB_ERR_NONE; - - if (start + count > framebuffer.mode_info.number_of_colors) - count = framebuffer.mode_info.number_of_colors - start; - - err = grub_video_fb_set_palette (start, count, palette_data); - if (err) - return err; - - /* Set colors. */ - grub_video_fb_get_palette (0, ARRAY_SIZE (fb_palette_data), - fb_palette_data); - - for (col = 0; col < ARRAY_SIZE (fb_palette_data); col++) - grub_ieee1275_set_color (stdout_ihandle, col, fb_palette_data[col].r, - fb_palette_data[col].g, - fb_palette_data[col].b); - return GRUB_ERR_NONE; -} - -static struct grub_video_adapter grub_video_ieee1275_adapter = - { - .name = "IEEE1275 video driver", - - .prio = GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE, - .id = GRUB_VIDEO_DRIVER_IEEE1275, - - .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, - .set_region = grub_video_fb_set_region, - .get_region = grub_video_fb_get_region, - .set_area_status = grub_video_fb_set_area_status, - .get_area_status = grub_video_fb_get_area_status, - .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_fb_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_fb_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/radeon_fuloong2e.c b/grub-core/video/radeon_fuloong2e.c deleted file mode 100644 index f1b4c591b..000000000 --- a/grub-core/video/radeon_fuloong2e.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008,2009,2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#define grub_video_render_target grub_video_fbrender_target - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define GRUB_RADEON_FULOONG2E_TOTAL_MEMORY_SPACE 1048576 - -static struct -{ - struct grub_video_mode_info mode_info; - struct grub_video_render_target *render_target; - - grub_uint8_t *ptr; - int mapped; - grub_uint32_t base; - grub_pci_device_t dev; -} framebuffer; - -static grub_err_t -grub_video_radeon_fuloong2e_video_init (void) -{ - /* Reset frame buffer. */ - grub_memset (&framebuffer, 0, sizeof(framebuffer)); - - return grub_video_fb_init (); -} - -static grub_err_t -grub_video_radeon_fuloong2e_video_fini (void) -{ - if (framebuffer.mapped) - grub_pci_device_unmap_range (framebuffer.dev, framebuffer.ptr, - GRUB_RADEON_FULOONG2E_TOTAL_MEMORY_SPACE); - - return grub_video_fb_fini (); -} - -#ifndef TEST -/* Helper for grub_video_radeon_fuloong2e_setup. */ -static int -find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) -{ - int *found = data; - 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) != GRUB_PCI_CLASS_DISPLAY_VGA - || pciid != 0x515a1002) - 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; -} -#endif - -static grub_err_t -grub_video_radeon_fuloong2e_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; - -#ifndef TEST - /* 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 != 640 && width != 0) || (height != 480 && height != 0) - || (depth != 16 && depth != 0)) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Only 640x480x16 is supported"); - - grub_pci_iterate (find_card, &found); - if (!found) - return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); -#endif - /* Fill mode info details. */ - framebuffer.mode_info.width = 640; - framebuffer.mode_info.height = 480; - 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 = 640 * 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; -#ifndef TEST - framebuffer.mode_info.blit_format - = grub_video_get_blit_format (&framebuffer.mode_info); -#endif - - /* We can safely discard volatile attribute. */ -#ifndef TEST - framebuffer.ptr - = (void *) grub_pci_device_map_range (framebuffer.dev, - framebuffer.base, - GRUB_RADEON_FULOONG2E_TOTAL_MEMORY_SPACE); -#endif - framebuffer.mapped = 1; - - /* Prevent garbage from appearing on the screen. */ - grub_memset (framebuffer.ptr, 0x55, - framebuffer.mode_info.height * framebuffer.mode_info.pitch); - -#ifndef TEST - 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); -#endif - return err; -} - -static grub_err_t -grub_video_radeon_fuloong2e_swap_buffers (void) -{ - /* TODO: Implement buffer swapping. */ - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_radeon_fuloong2e_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_radeon_fuloong2e_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_radeon_fuloong2e_adapter = - { - .name = "RADEON RV100 QZ (Fuloong2E) Video Driver", - .id = GRUB_VIDEO_DRIVER_RADEON_FULOONG2E, - - .prio = GRUB_VIDEO_ADAPTER_PRIO_NATIVE, - - .init = grub_video_radeon_fuloong2e_video_init, - .fini = grub_video_radeon_fuloong2e_video_fini, - .setup = grub_video_radeon_fuloong2e_setup, - .get_info = grub_video_fb_get_info, - .get_info_and_fini = grub_video_radeon_fuloong2e_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, - .set_region = grub_video_fb_set_region, - .get_region = grub_video_fb_get_region, - .set_area_status = grub_video_fb_set_area_status, - .get_area_status = grub_video_fb_get_area_status, - .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_radeon_fuloong2e_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_radeon_fuloong2e_set_active_render_target, - .get_active_render_target = grub_video_fb_get_active_render_target, - - .next = 0 - }; - -GRUB_MOD_INIT(video_radeon_fuloong2e) -{ - grub_video_register (&grub_video_radeon_fuloong2e_adapter); -} - -GRUB_MOD_FINI(video_radeon_fuloong2e) -{ - grub_video_unregister (&grub_video_radeon_fuloong2e_adapter); -} diff --git a/grub-core/video/readers/tga.c b/grub-core/video/readers/tga.c deleted file mode 100644 index 9c35bf29d..000000000 --- a/grub-core/video/readers/tga.c +++ /dev/null @@ -1,518 +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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -/* Uncomment following define to enable TGA debug. */ -//#define TGA_DEBUG - -#define dump_int_field(x) grub_dprintf ("tga", #x " = %d (0x%04x)\n", x, x); -#if defined(TGA_DEBUG) -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; -} GRUB_PACKED; - -struct tga_data -{ - struct grub_tga_header hdr; - int uses_rle; - int pktlen; - int bpp; - int is_rle; - grub_uint8_t pixel[4]; - grub_uint8_t palette[256][3]; - struct grub_video_bitmap *bitmap; - grub_file_t file; - unsigned image_width; - unsigned image_height; -}; - -static grub_err_t -fetch_pixel (struct tga_data *data) -{ - if (!data->uses_rle) - { - if (grub_file_read (data->file, &data->pixel[0], data->bpp) - != data->bpp) - return grub_errno; - return GRUB_ERR_NONE; - } - if (!data->pktlen) - { - grub_uint8_t type; - if (grub_file_read (data->file, &type, sizeof (type)) != sizeof(type)) - return grub_errno; - data->is_rle = !!(type & 0x80); - data->pktlen = (type & 0x7f) + 1; - if (data->is_rle && grub_file_read (data->file, &data->pixel[0], data->bpp) - != data->bpp) - return grub_errno; - } - if (!data->is_rle && grub_file_read (data->file, &data->pixel[0], data->bpp) - != data->bpp) - return grub_errno; - data->pktlen--; - return GRUB_ERR_NONE; -} - -static grub_err_t -tga_load_palette (struct tga_data *data) -{ - grub_size_t len = grub_le_to_cpu32 (data->hdr.color_map_length) * 3; - - if (len > sizeof (data->palette)) - len = sizeof (data->palette); - - if (grub_file_read (data->file, &data->palette, len) - != (grub_ssize_t) len) - return grub_errno; - -#ifndef GRUB_CPU_WORDS_BIGENDIAN - { - grub_size_t i; - for (i = 0; 3 * i < len; i++) - { - grub_uint8_t t; - t = data->palette[i][0]; - data->palette[i][0] = data->palette[i][2]; - data->palette[i][2] = t; - } - } -#endif - return GRUB_ERR_NONE; -} - -static grub_err_t -tga_load_index_color (struct tga_data *data) -{ - unsigned int x; - unsigned int y; - grub_uint8_t *ptr; - - for (y = 0; y < data->image_height; y++) - { - ptr = data->bitmap->data; - if ((data->hdr.image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0) - ptr += y * data->bitmap->mode_info.pitch; - else - ptr += (data->image_height - 1 - y) * data->bitmap->mode_info.pitch; - - for (x = 0; x < data->image_width; x++) - { - grub_err_t err; - err = fetch_pixel (data); - if (err) - return err; - - ptr[0] = data->palette[data->pixel[0]][0]; - ptr[1] = data->palette[data->pixel[0]][1]; - ptr[2] = data->palette[data->pixel[0]][2]; - - ptr += 3; - } - } - return GRUB_ERR_NONE; -} - -static grub_err_t -tga_load_grayscale (struct tga_data *data) -{ - unsigned int x; - unsigned int y; - grub_uint8_t *ptr; - - for (y = 0; y < data->image_height; y++) - { - ptr = data->bitmap->data; - if ((data->hdr.image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0) - ptr += y * data->bitmap->mode_info.pitch; - else - ptr += (data->image_height - 1 - y) * data->bitmap->mode_info.pitch; - - for (x = 0; x < data->image_width; x++) - { - grub_err_t err; - err = fetch_pixel (data); - if (err) - return err; - - ptr[0] = data->pixel[0]; - ptr[1] = data->pixel[0]; - ptr[2] = data->pixel[0]; - - ptr += 3; - } - } - return GRUB_ERR_NONE; -} - -static grub_err_t -tga_load_truecolor_R8G8B8 (struct tga_data *data) -{ - unsigned int x; - unsigned int y; - grub_uint8_t *ptr; - - for (y = 0; y < data->image_height; y++) - { - ptr = data->bitmap->data; - if ((data->hdr.image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0) - ptr += y * data->bitmap->mode_info.pitch; - else - ptr += (data->image_height - 1 - y) * data->bitmap->mode_info.pitch; - - for (x = 0; x < data->image_width; x++) - { - grub_err_t err; - err = fetch_pixel (data); - if (err) - return err; - -#ifdef GRUB_CPU_WORDS_BIGENDIAN - ptr[0] = data->pixel[0]; - ptr[1] = data->pixel[1]; - ptr[2] = data->pixel[2]; -#else - ptr[0] = data->pixel[2]; - ptr[1] = data->pixel[1]; - ptr[2] = data->pixel[0]; -#endif - ptr += 3; - } - } - return GRUB_ERR_NONE; -} - -static grub_err_t -tga_load_truecolor_R8G8B8A8 (struct tga_data *data) -{ - unsigned int x; - unsigned int y; - grub_uint8_t *ptr; - - for (y = 0; y < data->image_height; y++) - { - ptr = data->bitmap->data; - if ((data->hdr.image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0) - ptr += y * data->bitmap->mode_info.pitch; - else - ptr += (data->image_height - 1 - y) * data->bitmap->mode_info.pitch; - - for (x = 0; x < data->image_width; x++) - { - grub_err_t err; - err = fetch_pixel (data); - if (err) - return err; - -#ifdef GRUB_CPU_WORDS_BIGENDIAN - ptr[0] = data->pixel[0]; - ptr[1] = data->pixel[1]; - ptr[2] = data->pixel[2]; - ptr[3] = data->pixel[3]; -#else - ptr[0] = data->pixel[2]; - ptr[1] = data->pixel[1]; - ptr[2] = data->pixel[0]; - ptr[3] = data->pixel[3]; -#endif - - ptr += 4; - } - } - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_reader_tga (struct grub_video_bitmap **bitmap, - const char *filename) -{ - grub_ssize_t pos; - struct tga_data data; - - grub_memset (&data, 0, sizeof (data)); - - data.file = grub_buffile_open (filename, GRUB_FILE_TYPE_PIXMAP, 0); - if (! data.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 (data.file, &data.hdr, sizeof (data.hdr)) - != sizeof (data.hdr)) - { - grub_file_close (data.file); - return grub_errno; - } - - /* Skip ID field. */ - pos = grub_file_tell (data.file); - pos += data.hdr.id_length; - grub_file_seek (data.file, pos); - if (grub_errno != GRUB_ERR_NONE) - { - grub_file_close (data.file); - return grub_errno; - } - - grub_dprintf("tga", "tga: header\n"); - dump_int_field(data.hdr.id_length); - dump_int_field(data.hdr.color_map_type); - dump_int_field(data.hdr.image_type); - dump_int_field(data.hdr.color_map_first_index); - dump_int_field(data.hdr.color_map_length); - dump_int_field(data.hdr.color_map_bpp); - dump_int_field(data.hdr.image_x_origin); - dump_int_field(data.hdr.image_y_origin); - dump_int_field(data.hdr.image_width); - dump_int_field(data.hdr.image_height); - dump_int_field(data.hdr.image_bpp); - dump_int_field(data.hdr.image_descriptor); - - data.image_width = grub_le_to_cpu16 (data.hdr.image_width); - data.image_height = grub_le_to_cpu16 (data.hdr.image_height); - - grub_dprintf ("tga", "image height: %d\n", data.image_height); - grub_dprintf ("tga", "image width: %d\n", data.image_width); - - /* Check image height and width are within restrictions. */ - if ((data.image_height > IMAGE_HW_MAX_PX) || (data.image_width > IMAGE_HW_MAX_PX)) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "tga: invalid image size"); - - /* Check that bitmap encoding is supported. */ - switch (data.hdr.image_type) - { - case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR: - case GRUB_TGA_IMAGE_TYPE_RLE_BLACK_AND_WHITE: - case GRUB_TGA_IMAGE_TYPE_RLE_INDEXCOLOR: - data.uses_rle = 1; - break; - case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR: - case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_BLACK_AND_WHITE: - case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_INDEXCOLOR: - data.uses_rle = 0; - break; - - default: - grub_file_close (data.file); - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "unsupported bitmap format (unknown encoding %d)", data.hdr.image_type); - } - - data.bpp = data.hdr.image_bpp / 8; - - /* Check that bitmap depth is supported. */ - switch (data.hdr.image_type) - { - case GRUB_TGA_IMAGE_TYPE_RLE_BLACK_AND_WHITE: - case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_BLACK_AND_WHITE: - if (data.hdr.image_bpp != 8) - { - grub_file_close (data.file); - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "unsupported bitmap format (bpp=%d)", - data.hdr.image_bpp); - } - grub_video_bitmap_create (bitmap, data.image_width, - data.image_height, - GRUB_VIDEO_BLIT_FORMAT_RGB_888); - if (grub_errno != GRUB_ERR_NONE) - { - grub_file_close (data.file); - return grub_errno; - } - - data.bitmap = *bitmap; - /* Load bitmap data. */ - tga_load_grayscale (&data); - break; - - case GRUB_TGA_IMAGE_TYPE_RLE_INDEXCOLOR: - case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_INDEXCOLOR: - if (data.hdr.image_bpp != 8 - || data.hdr.color_map_bpp != 24 - || data.hdr.color_map_first_index != 0) - { - grub_file_close (data.file); - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "unsupported bitmap format (bpp=%d)", - data.hdr.image_bpp); - } - grub_video_bitmap_create (bitmap, data.image_width, - data.image_height, - GRUB_VIDEO_BLIT_FORMAT_RGB_888); - if (grub_errno != GRUB_ERR_NONE) - { - grub_file_close (data.file); - return grub_errno; - } - - data.bitmap = *bitmap; - /* Load bitmap data. */ - tga_load_palette (&data); - tga_load_index_color (&data); - break; - - case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR: - case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR: - switch (data.hdr.image_bpp) - { - case 24: - grub_video_bitmap_create (bitmap, data.image_width, - data.image_height, - GRUB_VIDEO_BLIT_FORMAT_RGB_888); - if (grub_errno != GRUB_ERR_NONE) - { - grub_file_close (data.file); - return grub_errno; - } - - data.bitmap = *bitmap; - /* Load bitmap data. */ - tga_load_truecolor_R8G8B8 (&data); - break; - - case 32: - grub_video_bitmap_create (bitmap, data.image_width, - data.image_height, - GRUB_VIDEO_BLIT_FORMAT_RGBA_8888); - if (grub_errno != GRUB_ERR_NONE) - { - grub_file_close (data.file); - return grub_errno; - } - - data.bitmap = *bitmap; - /* Load bitmap data. */ - tga_load_truecolor_R8G8B8A8 (&data); - break; - - default: - grub_file_close (data.file); - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "unsupported bitmap format (bpp=%d)", - data.hdr.image_bpp); - } - } - - /* If there was a loading problem, destroy bitmap. */ - if (grub_errno != GRUB_ERR_NONE) - { - grub_video_bitmap_destroy (*bitmap); - *bitmap = 0; - } - - grub_file_close (data.file); - return grub_errno; -} - -#if defined(TGA_DEBUG) -static grub_err_t -grub_cmd_tgatest (grub_command_t cmd_d __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/sis315_init.c b/grub-core/video/sis315_init.c deleted file mode 100644 index 09c3c7bbe..000000000 --- a/grub-core/video/sis315_init.c +++ /dev/null @@ -1,158 +0,0 @@ -static const struct { grub_uint8_t reg; grub_uint8_t val; } sr_dump [] = -{ - { 0x28, 0x81 }, - { 0x2a, 0x00 }, - { 0x29, 0xe1 }, - { 0x2b, 0x81 }, - { 0x2d, 0x00 }, - { 0x2c, 0xe1 }, - { 0x2e, 0x81 }, - { 0x30, 0x00 }, - { 0x2f, 0xe1 }, - { 0x28, 0x01 }, - { 0x29, 0x22 }, - { 0x28, 0x3b }, - { 0x29, 0x22 }, - { 0x2a, 0x01 }, - { 0x2e, 0x01 }, - { 0x2f, 0x22 }, - { 0x2e, 0x3b }, - { 0x2f, 0x22 }, - { 0x30, 0x01 }, - { 0x15, 0x00 }, - { 0x1b, 0x30 }, - - { 0x16, 0x0f }, - { 0x16, 0x8f }, - { 0x17, 0xba }, - { 0x16, 0x0f }, - { 0x16, 0x8f }, - { 0x1f, 0x00 }, - { 0x20, 0x20 }, - { 0x23, 0xf6 }, - { 0x24, 0x0d }, - { 0x25, 0x33 }, - { 0x21, 0x84 }, - { 0x22, 0x00 }, - { 0x27, 0x1f }, - { 0x31, 0x00 }, - { 0x33, 0x00 }, - { 0x32, 0x11 }, - - { 0x25, 0x33 }, - - { 0x05, 0x86 }, - { 0x01, 0x20 }, - { 0x32, 0x11 }, - { 0x1e, 0x00 }, - { 0x1d, 0x00 }, - { 0x00, 0x03 }, - { 0x01, 0x21 }, - { 0x02, 0x0f }, - { 0x03, 0x00 }, - { 0x04, 0x0e }, - - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x0c, 0x00 }, - { 0x0d, 0x00 }, - { 0x0e, 0x00 }, - { 0x37, 0x00 }, - - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x0c, 0x05 }, - { 0x0e, 0x00 }, - - { 0x0e, 0x00 }, - - { 0x10, 0x0b }, - { 0x31, 0x00 }, - { 0x2b, 0x01 }, - { 0x2c, 0xe1 }, - { 0x2b, 0x1b }, - { 0x2c, 0xe1 }, - { 0x2d, 0x01 }, - { 0x3d, 0x00 }, - { 0x08, 0x84 }, - { 0x09, 0x00 }, - { 0x3d, 0x01 }, - { 0x1f, 0x00 }, - { 0x06, 0x02 }, - - { 0x0f, 0x00 }, - { 0x17, 0xba }, - { 0x21, 0xa4 }, - { 0x32, 0x11 }, - { 0x07, 0x18 }, - - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - - { 0x01, 0x01 }, - { 0x21, 0x84 }, - { 0x01, 0x21 }, - { 0x16, 0x8f }, - { 0x18, 0xa9 }, - { 0x19, 0xa0 }, - { 0x1b, 0x30 }, - { 0x17, 0xb8 }, - { 0x19, 0xa3 }, - { 0x13, 0x00 }, - { 0x14, 0x00 }, - { 0x14, 0x02 }, - { 0x15, 0x00 }, - { 0x16, 0x0f }, - { 0x16, 0x8f }, - { 0x1d, 0x00 }, - { 0x14, 0x00 }, - { 0x14, 0x01 }, - { 0x15, 0x00 }, - { 0x16, 0x0f }, - { 0x16, 0x8f }, - { 0x1d, 0x00 }, - { 0x14, 0x01 }, - { 0x14, 0x01 }, - { 0x15, 0x10 }, - { 0x13, 0x35 }, - { 0x14, 0x51 }, - { 0x16, 0x0f }, - { 0x16, 0x8f }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x11 }, - { 0x1d, 0x11 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x1d, 0x00 }, - { 0x17, 0xba }, - { 0x19, 0xa0 }, - { 0x19, 0xa0 }, - { 0x01, 0x01 }, - { 0x16, 0x0f }, - { 0x18, 0xa9 }, - { 0x19, 0xa0 }, - { 0x1b, 0x30 }, - { 0x21, 0xa4 }, - { 0x05, 0x86 }, -}; - -static const grub_uint8_t gr[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; diff --git a/grub-core/video/sis315pro.c b/grub-core/video/sis315pro.c deleted file mode 100644 index ad3bb4dc7..000000000 --- a/grub-core/video/sis315pro.c +++ /dev/null @@ -1,459 +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 . - */ - -#define grub_video_render_target grub_video_fbrender_target - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define GRUB_SIS315PRO_PCIID 0x03251039 -#define GRUB_SIS315PRO_TOTAL_MEMORY_SPACE 0x800000 -#define GRUB_SIS315PRO_MMIO_SPACE 0x1000 - -static struct -{ - struct grub_video_mode_info mode_info; - - grub_uint8_t *ptr; - volatile grub_uint8_t *direct_ptr; - int mapped; - grub_uint32_t base; - grub_uint32_t mmiobase; - volatile grub_uint32_t *mmioptr; - grub_pci_device_t dev; - grub_port_t io; -} framebuffer; - -static grub_uint8_t -read_sis_cmd (grub_uint8_t addr) -{ - grub_outb (addr, framebuffer.io + 0x44); - return grub_inb (framebuffer.io + 0x45); -} - -static void -write_sis_cmd (grub_uint8_t val, grub_uint8_t addr) -{ - grub_outb (addr, framebuffer.io + 0x44); - grub_outb (val, framebuffer.io + 0x45); -} - -#ifndef TEST -static grub_err_t -grub_video_sis315pro_video_init (void) -{ - /* Reset frame buffer. */ - grub_memset (&framebuffer, 0, sizeof(framebuffer)); - - return grub_video_fb_init (); -} - -static grub_err_t -grub_video_sis315pro_video_fini (void) -{ - if (framebuffer.mapped) - { - grub_pci_device_unmap_range (framebuffer.dev, framebuffer.ptr, - GRUB_SIS315PRO_TOTAL_MEMORY_SPACE); - grub_pci_device_unmap_range (framebuffer.dev, framebuffer.direct_ptr, - GRUB_SIS315PRO_TOTAL_MEMORY_SPACE); - } - - return grub_video_fb_fini (); -} -#endif - -#include "sis315_init.c" - -#ifndef TEST -/* Helper for grub_video_sis315pro_setup. */ -static int -find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) -{ - int *found = data; - 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) != GRUB_PCI_CLASS_DISPLAY_VGA - || pciid != GRUB_SIS315PRO_PCIID) - return 0; - - *found = 1; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1); - framebuffer.mmiobase = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG2); - framebuffer.io = (grub_pci_read (addr) & GRUB_PCI_ADDR_IO_MASK) - + GRUB_MACHINE_PCI_IO_BASE; - framebuffer.dev = dev; - - return 1; -} -#endif - -static grub_err_t -grub_video_sis315pro_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; - unsigned i; - -#ifndef TEST - /* 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 != 640 && width != 0) || (height != 480 && height != 0) - || (depth != 8 && depth != 0)) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Only 640x480x8 is supported"); - - grub_pci_iterate (find_card, &found); - if (!found) - return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); -#endif - /* Fill mode info details. */ - framebuffer.mode_info.width = 640; - framebuffer.mode_info.height = 480; - framebuffer.mode_info.mode_type = (GRUB_VIDEO_MODE_TYPE_INDEX_COLOR - | GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED - | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); - framebuffer.mode_info.bpp = 8; - framebuffer.mode_info.bytes_per_pixel = 1; - framebuffer.mode_info.pitch = 640 * 1; - framebuffer.mode_info.number_of_colors = 16; - framebuffer.mode_info.red_mask_size = 0; - framebuffer.mode_info.red_field_pos = 0; - framebuffer.mode_info.green_mask_size = 0; - framebuffer.mode_info.green_field_pos = 0; - framebuffer.mode_info.blue_mask_size = 0; - framebuffer.mode_info.blue_field_pos = 0; - framebuffer.mode_info.reserved_mask_size = 0; - framebuffer.mode_info.reserved_field_pos = 0; -#ifndef TEST - framebuffer.mode_info.blit_format - = grub_video_get_blit_format (&framebuffer.mode_info); -#endif - -#ifndef TEST - if (found && (framebuffer.base == 0 || framebuffer.mmiobase == 0)) - { - grub_pci_address_t addr; - /* FIXME: choose address dynamically if needed. */ - framebuffer.base = 0x40000000; - framebuffer.mmiobase = 0x04000000; - framebuffer.io = 0xb300; - - addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_ADDRESS_REG0); - grub_pci_write (addr, framebuffer.base | GRUB_PCI_ADDR_MEM_PREFETCH); - - addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_ADDRESS_REG1); - grub_pci_write (addr, framebuffer.mmiobase); - - addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_ADDRESS_REG2); - grub_pci_write (addr, framebuffer.io | GRUB_PCI_ADDR_SPACE_IO); - - /* Set latency. */ - addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_CACHELINE); - grub_pci_write (addr, 0x80004700); - - /* Enable address spaces. */ - addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_COMMAND); - grub_pci_write (addr, 0x7); - - addr = grub_pci_make_address (framebuffer.dev, 0x30); - grub_pci_write (addr, 0x04060001); - - framebuffer.io += GRUB_MACHINE_PCI_IO_BASE; - } -#endif - - - /* We can safely discard volatile attribute. */ -#ifndef TEST - framebuffer.ptr - = grub_pci_device_map_range_cached (framebuffer.dev, - framebuffer.base, - GRUB_SIS315PRO_TOTAL_MEMORY_SPACE); - framebuffer.direct_ptr - = grub_pci_device_map_range (framebuffer.dev, - framebuffer.base, - GRUB_SIS315PRO_TOTAL_MEMORY_SPACE); - framebuffer.mmioptr = grub_pci_device_map_range (framebuffer.dev, - framebuffer.mmiobase, - GRUB_SIS315PRO_MMIO_SPACE); -#endif - framebuffer.mapped = 1; - -#ifndef TEST - /* Prevent garbage from appearing on the screen. */ - grub_memset (framebuffer.ptr, 0, - framebuffer.mode_info.height * framebuffer.mode_info.pitch); - grub_arch_sync_dma_caches (framebuffer.ptr, - framebuffer.mode_info.height - * framebuffer.mode_info.pitch); -#endif - - grub_outb (GRUB_VGA_IO_MISC_NEGATIVE_VERT_POLARITY - | GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY - | GRUB_VGA_IO_MISC_UPPER_64K - | GRUB_VGA_IO_MISC_EXTERNAL_CLOCK_0 - | GRUB_VGA_IO_MISC_28MHZ - | GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS - | GRUB_VGA_IO_MISC_COLOR, - GRUB_VGA_IO_MISC_WRITE + GRUB_MACHINE_PCI_IO_BASE); - - grub_vga_sr_write (0x86, 5); - for (i = 6; i <= 0x27; i++) - grub_vga_sr_write (0, i); - - for (i = 0x31; i <= 0x3d; i++) - grub_vga_sr_write (0, i); - - for (i = 0; i < ARRAY_SIZE (sr_dump); i++) - grub_vga_sr_write (sr_dump[i].val, sr_dump[i].reg); - - for (i = 0x30; i < 0x40; i++) - grub_vga_cr_write (0, i); - - grub_vga_cr_write (0x77, 0x40); - grub_vga_cr_write (0x77, 0x41); - grub_vga_cr_write (0x00, 0x42); - grub_vga_cr_write (0x5b, 0x43); - grub_vga_cr_write (0x00, 0x44); - grub_vga_cr_write (0x23, 0x48); - grub_vga_cr_write (0xaa, 0x49); - grub_vga_cr_write (0x02, 0x37); - grub_vga_cr_write (0x20, 0x5b); - grub_vga_cr_write (0x00, 0x83); - grub_vga_cr_write (0x80, 0x63); - - grub_vga_cr_write (0x0c, GRUB_VGA_CR_VSYNC_END); - grub_vga_cr_write (0x5f, GRUB_VGA_CR_HTOTAL); - grub_vga_cr_write (0x4f, GRUB_VGA_CR_HORIZ_END); - grub_vga_cr_write (0x50, GRUB_VGA_CR_HBLANK_START); - grub_vga_cr_write (0x82, GRUB_VGA_CR_HBLANK_END); - grub_vga_cr_write (0x54, GRUB_VGA_CR_HORIZ_SYNC_PULSE_START); - grub_vga_cr_write (0x80, GRUB_VGA_CR_HORIZ_SYNC_PULSE_END); - grub_vga_cr_write (0x0b, GRUB_VGA_CR_VERT_TOTAL); - grub_vga_cr_write (0x3e, GRUB_VGA_CR_OVERFLOW); - grub_vga_cr_write (0x00, GRUB_VGA_CR_BYTE_PANNING); - grub_vga_cr_write (0x40, GRUB_VGA_CR_CELL_HEIGHT); - grub_vga_cr_write (0x00, GRUB_VGA_CR_CURSOR_START); - grub_vga_cr_write (0x00, GRUB_VGA_CR_CURSOR_END); - grub_vga_cr_write (0x00, GRUB_VGA_CR_START_ADDR_HIGH_REGISTER); - grub_vga_cr_write (0x00, GRUB_VGA_CR_START_ADDR_LOW_REGISTER); - grub_vga_cr_write (0x00, GRUB_VGA_CR_CURSOR_ADDR_HIGH); - grub_vga_cr_write (0x00, GRUB_VGA_CR_CURSOR_ADDR_LOW); - grub_vga_cr_write (0xea, GRUB_VGA_CR_VSYNC_START); - grub_vga_cr_write (0x8c, GRUB_VGA_CR_VSYNC_END); - grub_vga_cr_write (0xdf, GRUB_VGA_CR_VDISPLAY_END); - grub_vga_cr_write (0x28, GRUB_VGA_CR_PITCH); - grub_vga_cr_write (0x40, GRUB_VGA_CR_UNDERLINE_LOCATION); - grub_vga_cr_write (0xe7, GRUB_VGA_CR_VERTICAL_BLANK_START); - grub_vga_cr_write (0x04, GRUB_VGA_CR_VERTICAL_BLANK_END); - grub_vga_cr_write (0xa3, GRUB_VGA_CR_MODE); - grub_vga_cr_write (0xff, GRUB_VGA_CR_LINE_COMPARE); - - grub_vga_cr_write (0x0c, GRUB_VGA_CR_VSYNC_END); - grub_vga_cr_write (0x5f, GRUB_VGA_CR_HTOTAL); - grub_vga_cr_write (0x4f, GRUB_VGA_CR_HORIZ_END); - grub_vga_cr_write (0x50, GRUB_VGA_CR_HBLANK_START); - grub_vga_cr_write (0x82, GRUB_VGA_CR_HBLANK_END); - grub_vga_cr_write (0x55, GRUB_VGA_CR_HORIZ_SYNC_PULSE_START); - grub_vga_cr_write (0x81, GRUB_VGA_CR_HORIZ_SYNC_PULSE_END); - grub_vga_cr_write (0x0b, GRUB_VGA_CR_VERT_TOTAL); - grub_vga_cr_write (0x3e, GRUB_VGA_CR_OVERFLOW); - grub_vga_cr_write (0xe9, GRUB_VGA_CR_VSYNC_START); - grub_vga_cr_write (0x8b, GRUB_VGA_CR_VSYNC_END); - grub_vga_cr_write (0xdf, GRUB_VGA_CR_VDISPLAY_END); - grub_vga_cr_write (0xe7, GRUB_VGA_CR_VERTICAL_BLANK_START); - grub_vga_cr_write (0x04, GRUB_VGA_CR_VERTICAL_BLANK_END); - grub_vga_cr_write (0x40, GRUB_VGA_CR_CELL_HEIGHT); - grub_vga_cr_write (0x50, GRUB_VGA_CR_PITCH); - - grub_vga_cr_write (0x00, 0x19); - grub_vga_cr_write (0x00, 0x1a); - grub_vga_cr_write (0x6c, 0x52); - grub_vga_cr_write (0x2e, 0x34); - grub_vga_cr_write (0x00, 0x31); - - - grub_vga_cr_write (0, GRUB_VGA_CR_START_ADDR_HIGH_REGISTER); - grub_vga_cr_write (0, GRUB_VGA_CR_START_ADDR_LOW_REGISTER); - - for (i = 0; i < 16; i++) - grub_vga_write_arx (i, i); - grub_vga_write_arx (1, GRUB_VGA_ARX_MODE); - grub_vga_write_arx (0, GRUB_VGA_ARX_OVERSCAN); - grub_vga_write_arx (0, GRUB_VGA_ARX_COLOR_PLANE_ENABLE); - grub_vga_write_arx (0, GRUB_VGA_ARX_HORIZONTAL_PANNING); - grub_vga_write_arx (0, GRUB_VGA_ARX_COLOR_SELECT); - - grub_outb (0xff, GRUB_VGA_IO_PIXEL_MASK + GRUB_MACHINE_PCI_IO_BASE); - - for (i = 0; i < ARRAY_SIZE (gr); i++) - grub_vga_gr_write (gr[i], i); - - for (i = 0; i < GRUB_VIDEO_FBSTD_NUMCOLORS; i++) - grub_vga_palette_write (i, grub_video_fbstd_colors[i].r, - grub_video_fbstd_colors[i].g, - grub_video_fbstd_colors[i].b); - -#if 1 - { - if (read_sis_cmd (0x5) != 0xa1) - write_sis_cmd (0x86, 0x5); - - write_sis_cmd (read_sis_cmd (0x20) | 0xa1, 0x20); - write_sis_cmd (read_sis_cmd (0x1e) | 0xda, 0x1e); - -#define IND_SIS_CMDQUEUE_SET 0x26 -#define IND_SIS_CMDQUEUE_THRESHOLD 0x27 - -#define COMMAND_QUEUE_THRESHOLD 0x1F -#define SIS_CMD_QUEUE_RESET 0x01 - -#define SIS_AGP_CMDQUEUE_ENABLE 0x80 /* 315/330/340 series SR26 */ -#define SIS_VRAM_CMDQUEUE_ENABLE 0x40 -#define SIS_MMIO_CMD_ENABLE 0x20 -#define SIS_CMD_QUEUE_SIZE_512k 0x00 -#define SIS_CMD_QUEUE_SIZE_1M 0x04 -#define SIS_CMD_QUEUE_SIZE_2M 0x08 -#define SIS_CMD_QUEUE_SIZE_4M 0x0C -#define SIS_CMD_QUEUE_RESET 0x01 -#define SIS_CMD_AUTO_CORR 0x02 - - - write_sis_cmd (COMMAND_QUEUE_THRESHOLD, IND_SIS_CMDQUEUE_THRESHOLD); - write_sis_cmd (SIS_CMD_QUEUE_RESET, IND_SIS_CMDQUEUE_SET); - framebuffer.mmioptr[0x85C4 / 4] = framebuffer.mmioptr[0x85C8 / 4]; - write_sis_cmd (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR, IND_SIS_CMDQUEUE_SET); - framebuffer.mmioptr[0x85C0 / 4] = (0x1000000 - (512 * 1024)); - } -#endif - -#ifndef TEST - err = grub_video_fb_setup (mode_type, mode_mask, - &framebuffer.mode_info, - framebuffer.ptr, NULL, NULL); - if (err) - return err; - - /* Copy default palette to initialize emulated palette. */ - err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_EXT_NUMCOLORS, - grub_video_fbstd_colors); -#endif - return err; -} - -#ifndef TEST - -static grub_err_t -grub_video_sis315pro_swap_buffers (void) -{ - grub_size_t s; - s = (framebuffer.mode_info.height - * framebuffer.mode_info.pitch - * framebuffer.mode_info.bytes_per_pixel); - grub_video_fb_swap_buffers (); - grub_arch_sync_dma_caches (framebuffer.ptr, s); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_video_sis315pro_get_info_and_fini (struct grub_video_mode_info *mode_info, - void **framebuf) -{ - grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info)); - *framebuf = (void *) framebuffer.direct_ptr; - - grub_video_fb_fini (); - - return GRUB_ERR_NONE; -} - -static struct grub_video_adapter grub_video_sis315pro_adapter = - { - .name = "SIS315PRO Video Driver", - .id = GRUB_VIDEO_DRIVER_SIS315PRO, - - .prio = GRUB_VIDEO_ADAPTER_PRIO_NATIVE, - - .init = grub_video_sis315pro_video_init, - .fini = grub_video_sis315pro_video_fini, - .setup = grub_video_sis315pro_setup, - .get_info = grub_video_fb_get_info, - .get_info_and_fini = grub_video_sis315pro_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, - .set_region = grub_video_fb_set_region, - .get_region = grub_video_fb_get_region, - .set_area_status = grub_video_fb_set_area_status, - .get_area_status = grub_video_fb_get_area_status, - .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_sis315pro_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_fb_set_active_render_target, - .get_active_render_target = grub_video_fb_get_active_render_target, - - .next = 0 - }; - -GRUB_MOD_INIT(video_sis315pro) -{ - grub_video_register (&grub_video_sis315pro_adapter); -} - -GRUB_MOD_FINI(video_sis315pro) -{ - grub_video_unregister (&grub_video_sis315pro_adapter); -} -#else -int -main () -{ - grub_video_sis315pro_setup (640, 400, 0, 0); -} -#endif diff --git a/grub-core/video/sm712.c b/grub-core/video/sm712.c deleted file mode 100644 index e8967308d..000000000 --- a/grub-core/video/sm712.c +++ /dev/null @@ -1,818 +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 . - */ - -#define grub_video_render_target grub_video_fbrender_target - -#if !defined (TEST) && !defined(GENINIT) -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#else -typedef unsigned char grub_uint8_t; -typedef unsigned short grub_uint16_t; -typedef unsigned int grub_uint32_t; -typedef int grub_err_t; -#include -#include -#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0])) -#endif - -#include "sm712_init.c" - -#pragma GCC diagnostic ignored "-Wcast-align" - -#define GRUB_SM712_TOTAL_MEMORY_SPACE 0x700400 -#define GRUB_SM712_REG_BASE 0x700000 -#define GRUB_SM712_PCIID 0x0712126f - -enum - { - GRUB_SM712_SR_TV_CONTROL = 0x65, - GRUB_SM712_SR_RAM_LUT = 0x66, - GRUB_SM712_SR_CLOCK_CONTROL1 = 0x68, - GRUB_SM712_SR_CLOCK_CONTROL2 = 0x69, - GRUB_SM712_SR_VCLK_NUM = 0x6c, - GRUB_SM712_SR_VCLK_DENOM = 0x6d, - GRUB_SM712_SR_VCLK2_NUM = 0x6e, - GRUB_SM712_SR_VCLK2_DENOM = 0x6f, - GRUB_SM712_SR_POPUP_ICON_LOW = 0x80, - GRUB_SM712_SR_POPUP_ICON_HIGH = 0x81, - GRUB_SM712_SR_POPUP_ICON_CTRL = 0x82, - GRUB_SM712_SR_POPUP_ICON_COLOR1 = 0x84, - GRUB_SM712_SR_POPUP_ICON_COLOR2 = 0x85, - GRUB_SM712_SR_POPUP_ICON_COLOR3 = 0x86, - - GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_LOW = 0x88, - GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_HIGH = 0x89, - GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_LOW = 0x8a, - GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_HIGH = 0x8b, - GRUB_SM712_SR_HW_CURSOR_FG_COLOR = 0x8c, - GRUB_SM712_SR_HW_CURSOR_BG_COLOR = 0x8d, - - GRUB_SM712_SR_POPUP_ICON_X_LOW = 0x90, - GRUB_SM712_SR_POPUP_ICON_X_HIGH = 0x91, - GRUB_SM712_SR_POPUP_ICON_Y_LOW = 0x92, - GRUB_SM712_SR_POPUP_ICON_Y_HIGH = 0x93, - GRUB_SM712_SR_PANEL_HW_VIDEO_CONTROL = 0xa0, - GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_LOW = 0xa1, - GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_HIGH = 0xa2, - GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_LOW = 0xa3, - GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_HIGH = 0xa4, - GRUB_SM712_SR_PANEL_HW_VIDEO_RED_CONSTANT = 0xa5, - GRUB_SM712_SR_PANEL_HW_VIDEO_GREEN_CONSTANT = 0xa6, - GRUB_SM712_SR_PANEL_HW_VIDEO_BLUE_CONSTANT = 0xa7, - GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_BOUNDARY = 0xa8, - GRUB_SM712_SR_PANEL_HW_VIDEO_LEFT_BOUNDARY = 0xa9, - GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_BOUNDARY = 0xaa, - GRUB_SM712_SR_PANEL_HW_VIDEO_RIGHT_BOUNDARY = 0xab, - GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_LEFT_OVERFLOW_BOUNDARY = 0xac, - GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_RIGHT_OVERFLOW_BOUNDARY = 0xad, - GRUB_SM712_SR_PANEL_HW_VIDEO_VERTICAL_STRETCH_FACTOR = 0xae, - GRUB_SM712_SR_PANEL_HW_VIDEO_HORIZONTAL_STRETCH_FACTOR = 0xaf, - }; -enum - { - GRUB_SM712_SR_TV_CRT_SRAM = 0x00, - GRUB_SM712_SR_TV_LCD_SRAM = 0x08 - }; -enum - { - GRUB_SM712_SR_TV_ALT_CLOCK = 0x00, - GRUB_SM712_SR_TV_FREE_RUN_CLOCK = 0x04 - }; -enum - { - GRUB_SM712_SR_TV_CLOCK_CKIN_NTSC = 0x00, - GRUB_SM712_SR_TV_CLOCK_REFCLK_PAL = 0x04 - }; -enum - { - GRUB_SM712_SR_TV_HSYNC = 0x00, - GRUB_SM712_SR_TV_COMPOSITE_HSYNC = 0x01 - }; -enum - { - GRUB_SM712_SR_RAM_LUT_NORMAL = 0, - GRUB_SM712_SR_RAM_LUT_LCD_RAM_OFF = 0x80, - GRUB_SM712_SR_RAM_LUT_CRT_RAM_OFF = 0x40, - GRUB_SM712_SR_RAM_LUT_LCD_RAM_NO_WRITE = 0x20, - GRUB_SM712_SR_RAM_LUT_CRT_RAM_NO_WRITE = 0x10, - GRUB_SM712_SR_RAM_LUT_CRT_8BIT = 0x08, - GRUB_SM712_SR_RAM_LUT_CRT_GAMMA = 0x04 - }; - -enum - { - GRUB_SM712_SR_CLOCK_CONTROL1_VCLK_FROM_CCR = 0x40, - GRUB_SM712_SR_CLOCK_CONTROL1_8DOT_CLOCK = 0x10, - }; - -enum - { - GRUB_SM712_SR_CLOCK_CONTROL2_PROGRAM_VCLOCK = 0x03 - }; - -#define GRUB_SM712_SR_POPUP_ICON_HIGH_MASK 0x7 -#define GRUB_SM712_SR_POPUP_ICON_HIGH_HW_CURSOR_EN 0x80 - enum - { - GRUB_SM712_SR_POPUP_ICON_CTRL_DISABLED = 0, - GRUB_SM712_SR_POPUP_ICON_CTRL_ZOOM_ENABLED = 0x40, - GRUB_SM712_SR_POPUP_ICON_CTRL_ENABLED = 0x80 - }; -#define RGB332_BLACK 0 -#define RGB332_WHITE 0xff - - enum - { - GRUB_SM712_CR_OVERFLOW_INTERLACE = 0x30, - GRUB_SM712_CR_INTERLACE_RETRACE = 0x31, - GRUB_SM712_CR_TV_VDISPLAY_START = 0x32, - GRUB_SM712_CR_TV_VDISPLAY_END_HIGH = 0x33, - GRUB_SM712_CR_TV_VDISPLAY_END_LOW = 0x34, - GRUB_SM712_CR_DDA_CONTROL_LOW = 0x35, - GRUB_SM712_CR_DDA_CONTROL_HIGH = 0x36, - GRUB_SM712_CR_TV_EQUALIZER = 0x38, - GRUB_SM712_CR_TV_SERRATION = 0x39, - GRUB_SM712_CR_HSYNC_CTRL = 0x3a, - GRUB_SM712_CR_DEBUG = 0x3c, - GRUB_SM712_CR_SHADOW_VGA_HTOTAL = 0x40, - GRUB_SM712_CR_SHADOW_VGA_HBLANK_START = 0x41, - GRUB_SM712_CR_SHADOW_VGA_HBLANK_END = 0x42, - GRUB_SM712_CR_SHADOW_VGA_HRETRACE_START = 0x43, - GRUB_SM712_CR_SHADOW_VGA_HRETRACE_END = 0x44, - GRUB_SM712_CR_SHADOW_VGA_VERTICAL_TOTAL = 0x45, - GRUB_SM712_CR_SHADOW_VGA_VBLANK_START = 0x46, - GRUB_SM712_CR_SHADOW_VGA_VBLANK_END = 0x47, - GRUB_SM712_CR_SHADOW_VGA_VRETRACE_START = 0x48, - GRUB_SM712_CR_SHADOW_VGA_VRETRACE_END = 0x49, - GRUB_SM712_CR_SHADOW_VGA_OVERFLOW = 0x4a, - GRUB_SM712_CR_SHADOW_VGA_CELL_HEIGHT = 0x4b, - GRUB_SM712_CR_SHADOW_VGA_HDISPLAY_END = 0x4c, - GRUB_SM712_CR_SHADOW_VGA_VDISPLAY_END = 0x4d, - GRUB_SM712_CR_DDA_LOOKUP_REG3_START = 0x90, - GRUB_SM712_CR_DDA_LOOKUP_REG2_START = 0x91, - GRUB_SM712_CR_DDA_LOOKUP_REG1_START = 0xa0, - GRUB_SM712_CR_VCENTERING_OFFSET = 0xa6, - GRUB_SM712_CR_HCENTERING_OFFSET = 0xa7, - }; - -#define GRUB_SM712_CR_DEBUG_NONE 0 - -#define SM712_DDA_REG3_COMPARE_SHIFT 2 -#define SM712_DDA_REG3_COMPARE_MASK 0xfc -#define SM712_DDA_REG3_DDA_SHIFT 8 -#define SM712_DDA_REG3_DDA_MASK 0x3 -#define SM712_DDA_REG2_DDA_MASK 0xff -#define SM712_DDA_REG2_VCENTER_MASK 0x3f - -static struct -{ - grub_uint8_t compare; - grub_uint16_t dda; - grub_uint8_t vcentering; -} dda_lookups[] = { - { 21, 469, 2}, - { 23, 477, 2}, - { 33, 535, 2}, - { 35, 682, 21}, - { 34, 675, 2}, - { 55, 683, 6}, -}; - -static struct -{ -#if !defined (TEST) && !defined(GENINIT) - struct grub_video_mode_info mode_info; -#endif - - volatile grub_uint8_t *ptr; - grub_uint8_t *cached_ptr; - int mapped; - grub_uint32_t base; -#if !defined (TEST) && !defined(GENINIT) - grub_pci_device_t dev; -#endif -} framebuffer; - -#if !defined (TEST) && !defined(GENINIT) -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, - GRUB_SM712_TOTAL_MEMORY_SPACE); - grub_pci_device_unmap_range (framebuffer.dev, framebuffer.cached_ptr, - GRUB_SM712_TOTAL_MEMORY_SPACE); - } - return grub_video_fb_fini (); -} -#endif - -static inline void -grub_sm712_write_reg (grub_uint8_t val, grub_uint16_t addr) -{ -#ifdef TEST - printf (" {1, 0x%x, 0x%x},\n", addr, val); -#elif defined (GENINIT) - printf (" .byte 0x%02x, 0x%02x\n", (addr - 0x3c0), val); - if ((addr - 0x3c0) & ~0x7f) - printf ("FAIL\n"); -#else - *(volatile grub_uint8_t *) (framebuffer.ptr + GRUB_SM712_REG_BASE - + addr) = val; -#endif -} - -static inline grub_uint8_t -grub_sm712_read_reg (grub_uint16_t addr) -{ -#ifdef TEST - printf (" {-1, 0x%x, 0x5},\n", addr); -#elif defined (GENINIT) - if ((addr - 0x3c0) & ~0x7f) - printf ("FAIL\n"); - printf (" .byte 0x%04x, 0x00\n", (addr - 0x3c0) | 0x80); -#else - return *(volatile grub_uint8_t *) (framebuffer.ptr + GRUB_SM712_REG_BASE - + addr); -#endif -} - -static inline grub_uint8_t -grub_sm712_sr_read (grub_uint8_t addr) -{ - grub_sm712_write_reg (addr, GRUB_VGA_IO_SR_INDEX); - return grub_sm712_read_reg (GRUB_VGA_IO_SR_DATA); -} - -static inline void -grub_sm712_sr_write (grub_uint8_t val, grub_uint8_t addr) -{ - grub_sm712_write_reg (addr, GRUB_VGA_IO_SR_INDEX); - grub_sm712_write_reg (val, GRUB_VGA_IO_SR_DATA); -} - -static inline void -grub_sm712_gr_write (grub_uint8_t val, grub_uint8_t addr) -{ - grub_sm712_write_reg (addr, GRUB_VGA_IO_GR_INDEX); - grub_sm712_write_reg (val, GRUB_VGA_IO_GR_DATA); -} - -static inline void -grub_sm712_cr_write (grub_uint8_t val, grub_uint8_t addr) -{ - grub_sm712_write_reg (addr, GRUB_VGA_IO_CR_INDEX); - grub_sm712_write_reg (val, GRUB_VGA_IO_CR_DATA); -} - -static inline void -grub_sm712_write_arx (grub_uint8_t val, grub_uint8_t addr) -{ - grub_sm712_read_reg (GRUB_VGA_IO_INPUT_STATUS1_REGISTER); - grub_sm712_write_reg (addr, GRUB_VGA_IO_ARX); - grub_sm712_read_reg (GRUB_VGA_IO_ARX_READ); - grub_sm712_write_reg (val, GRUB_VGA_IO_ARX); -} - -static inline void -grub_sm712_cr_shadow_write (grub_uint8_t val, grub_uint8_t addr) -{ - grub_uint8_t mapping[] = - { - [GRUB_VGA_CR_HTOTAL] = GRUB_SM712_CR_SHADOW_VGA_HTOTAL, - [GRUB_VGA_CR_HORIZ_END] = 0xff, - [GRUB_VGA_CR_HBLANK_START] = GRUB_SM712_CR_SHADOW_VGA_HBLANK_START, - [GRUB_VGA_CR_HBLANK_END] = GRUB_SM712_CR_SHADOW_VGA_HBLANK_END, - [GRUB_VGA_CR_HORIZ_SYNC_PULSE_START] = GRUB_SM712_CR_SHADOW_VGA_HRETRACE_START, - [GRUB_VGA_CR_HORIZ_SYNC_PULSE_END] = GRUB_SM712_CR_SHADOW_VGA_HRETRACE_END, - [GRUB_VGA_CR_VERT_TOTAL] = GRUB_SM712_CR_SHADOW_VGA_VERTICAL_TOTAL, - [GRUB_VGA_CR_OVERFLOW] = GRUB_SM712_CR_SHADOW_VGA_OVERFLOW, - [GRUB_VGA_CR_BYTE_PANNING] = 0xff, - [GRUB_VGA_CR_CELL_HEIGHT] = GRUB_SM712_CR_SHADOW_VGA_CELL_HEIGHT, - [GRUB_VGA_CR_CURSOR_START] = 0xff, - [GRUB_VGA_CR_CURSOR_END] = 0xff, - [GRUB_VGA_CR_START_ADDR_HIGH_REGISTER] = 0xff, - [GRUB_VGA_CR_START_ADDR_LOW_REGISTER] = 0xff, - [GRUB_VGA_CR_CURSOR_ADDR_HIGH] = 0xff, - [GRUB_VGA_CR_CURSOR_ADDR_LOW] = 0xff, - [GRUB_VGA_CR_VSYNC_START] = GRUB_SM712_CR_SHADOW_VGA_VRETRACE_START, - [GRUB_VGA_CR_VSYNC_END] = GRUB_SM712_CR_SHADOW_VGA_VRETRACE_END, - [GRUB_VGA_CR_VDISPLAY_END] = GRUB_SM712_CR_SHADOW_VGA_VDISPLAY_END, - [GRUB_VGA_CR_PITCH] = GRUB_SM712_CR_SHADOW_VGA_HDISPLAY_END, - [GRUB_VGA_CR_UNDERLINE_LOCATION] = 0xff, - - [GRUB_VGA_CR_VERTICAL_BLANK_START] = GRUB_SM712_CR_SHADOW_VGA_VBLANK_START, - [GRUB_VGA_CR_VERTICAL_BLANK_END] = GRUB_SM712_CR_SHADOW_VGA_VBLANK_END, - [GRUB_VGA_CR_MODE] = 0xff, - [GRUB_VGA_CR_LINE_COMPARE] = 0xff - }; - if (addr >= ARRAY_SIZE (mapping) || mapping[addr] == 0xff) - return; - grub_sm712_cr_write (val, mapping[addr]); -} - -static inline void -grub_sm712_write_dda_lookup (int idx, grub_uint8_t compare, grub_uint16_t dda, - grub_uint8_t vcentering) -{ - grub_sm712_cr_write (((compare << SM712_DDA_REG3_COMPARE_SHIFT) - & SM712_DDA_REG3_COMPARE_MASK) - | ((dda >> SM712_DDA_REG3_DDA_SHIFT) - & SM712_DDA_REG3_DDA_MASK), - GRUB_SM712_CR_DDA_LOOKUP_REG3_START + 2 * idx); - grub_sm712_cr_write (dda & SM712_DDA_REG2_DDA_MASK, - GRUB_SM712_CR_DDA_LOOKUP_REG2_START + 2 * idx); - grub_sm712_cr_write (vcentering & SM712_DDA_REG2_VCENTER_MASK, - GRUB_SM712_CR_DDA_LOOKUP_REG1_START + idx); -} - -#if !defined (TEST) && !defined(GENINIT) -/* Helper for grub_video_sm712_setup. */ -static int -find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) -{ - int *found = data; - 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) != GRUB_PCI_CLASS_DISPLAY_VGA - || pciid != GRUB_SM712_PCIID) - 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; -} -#endif - -static grub_err_t -grub_video_sm712_setup (unsigned int width, unsigned int height, - unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused))) -{ - unsigned i; -#if !defined (TEST) && !defined(GENINIT) - int depth; - grub_err_t err; - int found = 0; - - /* 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, &found); - if (!found) - return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); - /* Fill mode info details. */ - framebuffer.mode_info.width = 1024; - framebuffer.mode_info.height = 600; - framebuffer.mode_info.mode_type = (GRUB_VIDEO_MODE_TYPE_RGB - | GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED - | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); - 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); -#endif - -#if !defined (TEST) && !defined(GENINIT) - if (found && framebuffer.base == 0) - { - grub_pci_address_t addr; - /* FIXME: choose address dynamically if needed. */ - framebuffer.base = 0x04000000; - - addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_ADDRESS_REG0); - grub_pci_write (addr, framebuffer.base); - - /* Set latency. */ - addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_CACHELINE); - grub_pci_write (addr, 0x8); - - /* Enable address spaces. */ - addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_COMMAND); - grub_pci_write (addr, 0x7); - } -#endif - - /* We can safely discard volatile attribute. */ -#if !defined (TEST) && !defined(GENINIT) - framebuffer.ptr - = grub_pci_device_map_range (framebuffer.dev, - framebuffer.base, - GRUB_SM712_TOTAL_MEMORY_SPACE); - framebuffer.cached_ptr - = grub_pci_device_map_range_cached (framebuffer.dev, - framebuffer.base, - GRUB_SM712_TOTAL_MEMORY_SPACE); -#endif - framebuffer.mapped = 1; - - /* Initialise SM712. */ -#if !defined (TEST) && !defined(GENINIT) - /* FIXME */ - grub_vga_sr_write (0x11, 0x18); -#endif - -#if !defined (TEST) && !defined(GENINIT) - /* Prevent garbage from appearing on the screen. */ - grub_memset ((void *) framebuffer.cached_ptr, 0, - framebuffer.mode_info.height * framebuffer.mode_info.pitch); -#endif - - /* FIXME */ - grub_sm712_sr_write (0, 0x21); - grub_sm712_sr_write (0x7a, 0x62); - grub_sm712_sr_write (0x16, 0x6a); - grub_sm712_sr_write (0x2, 0x6b); - grub_sm712_write_reg (0, GRUB_VGA_IO_PIXEL_MASK); - grub_sm712_sr_write (GRUB_VGA_SR_RESET_ASYNC, GRUB_VGA_SR_RESET); - grub_sm712_write_reg (GRUB_VGA_IO_MISC_NEGATIVE_VERT_POLARITY - | GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY - | GRUB_VGA_IO_MISC_UPPER_64K - | GRUB_VGA_IO_MISC_EXTERNAL_CLOCK_0 - | GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS - | GRUB_VGA_IO_MISC_COLOR, GRUB_VGA_IO_MISC_WRITE); - grub_sm712_sr_write (GRUB_VGA_SR_RESET_ASYNC | GRUB_VGA_SR_RESET_SYNC, - GRUB_VGA_SR_RESET); - grub_sm712_sr_write (GRUB_VGA_SR_CLOCKING_MODE_8_DOT_CLOCK, - GRUB_VGA_SR_CLOCKING_MODE); - grub_sm712_sr_write (GRUB_VGA_ALL_PLANES, GRUB_VGA_SR_MAP_MASK_REGISTER); - grub_sm712_sr_write (0, GRUB_VGA_SR_CHAR_MAP_SELECT); - grub_sm712_sr_write (GRUB_VGA_SR_MEMORY_MODE_CHAIN4 - | GRUB_VGA_SR_MEMORY_MODE_SEQUENTIAL_ADDRESSING - | GRUB_VGA_SR_MEMORY_MODE_EXTERNAL_VIDEO_MEMORY, - GRUB_VGA_SR_MEMORY_MODE); - - for (i = 0; i < ARRAY_SIZE (sm712_sr_seq1); i++) - grub_sm712_sr_write (sm712_sr_seq1[i], 0x10 + i); - - for (i = 0; i < ARRAY_SIZE (sm712_sr_seq2); i++) - grub_sm712_sr_write (sm712_sr_seq2[i], 0x30 + i); - - /* Undocumented. */ - grub_sm712_sr_write (0x1a, 0x63); - /* Undocumented. */ - grub_sm712_sr_write (0x1a, 0x64); - - grub_sm712_sr_write (GRUB_SM712_SR_TV_CRT_SRAM | GRUB_SM712_SR_TV_ALT_CLOCK - | GRUB_SM712_SR_TV_CLOCK_CKIN_NTSC - | GRUB_SM712_SR_TV_HSYNC, - GRUB_SM712_SR_TV_CONTROL); - - grub_sm712_sr_write (GRUB_SM712_SR_RAM_LUT_NORMAL, GRUB_SM712_SR_RAM_LUT); - - /* Undocumented. */ - grub_sm712_sr_write (0x00, 0x67); - - grub_sm712_sr_write (GRUB_SM712_SR_CLOCK_CONTROL1_VCLK_FROM_CCR - | GRUB_SM712_SR_CLOCK_CONTROL1_8DOT_CLOCK, - GRUB_SM712_SR_CLOCK_CONTROL1); - grub_sm712_sr_write (GRUB_SM712_SR_CLOCK_CONTROL2_PROGRAM_VCLOCK, - GRUB_SM712_SR_CLOCK_CONTROL2); - - grub_sm712_sr_write (82, GRUB_SM712_SR_VCLK_NUM); - grub_sm712_sr_write (137, GRUB_SM712_SR_VCLK_DENOM); - - grub_sm712_sr_write (9, GRUB_SM712_SR_VCLK2_NUM); - grub_sm712_sr_write (2, GRUB_SM712_SR_VCLK2_DENOM); - /* FIXME */ - grub_sm712_sr_write (0x04, 0x70); - /* FIXME */ - grub_sm712_sr_write (0x45, 0x71); - /* Undocumented */ - grub_sm712_sr_write (0x30, 0x72); - /* Undocumented */ - grub_sm712_sr_write (0x30, 0x73); - /* Undocumented */ - grub_sm712_sr_write (0x40, 0x74); - /* Undocumented */ - grub_sm712_sr_write (0x20, 0x75); - - grub_sm712_sr_write (0xff, GRUB_SM712_SR_POPUP_ICON_LOW); - grub_sm712_sr_write (GRUB_SM712_SR_POPUP_ICON_HIGH_MASK, - GRUB_SM712_SR_POPUP_ICON_HIGH); - grub_sm712_sr_write (GRUB_SM712_SR_POPUP_ICON_CTRL_DISABLED, - GRUB_SM712_SR_POPUP_ICON_CTRL); - /* Undocumented */ - grub_sm712_sr_write (0x0, 0x83); - - grub_sm712_sr_write (8, GRUB_SM712_SR_POPUP_ICON_COLOR1); - grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_COLOR2); - grub_sm712_sr_write (0x42, GRUB_SM712_SR_POPUP_ICON_COLOR3); - - /* Undocumented */ - grub_sm712_sr_write (0x3a, 0x87); - - /* Why theese coordinates? */ - grub_sm712_sr_write (0x59, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_LOW); - grub_sm712_sr_write (0x02, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_X_HIGH); - grub_sm712_sr_write (0x44, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_LOW); - grub_sm712_sr_write (0x02, GRUB_SM712_SR_HW_CURSOR_UPPER_LEFT_Y_HIGH); - - grub_sm712_sr_write (RGB332_BLACK, GRUB_SM712_SR_HW_CURSOR_FG_COLOR); - grub_sm712_sr_write (RGB332_WHITE, GRUB_SM712_SR_HW_CURSOR_BG_COLOR); - - /* Undocumented */ - grub_sm712_sr_write (0x3a, 0x8e); - grub_sm712_sr_write (0x3a, 0x8f); - - grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_X_LOW); - grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_X_HIGH); - grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_Y_LOW); - grub_sm712_sr_write (0, GRUB_SM712_SR_POPUP_ICON_Y_HIGH); - - grub_sm712_sr_write (0, GRUB_SM712_SR_PANEL_HW_VIDEO_CONTROL); - grub_sm712_sr_write (0x10, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_LOW); - grub_sm712_sr_write (0x08, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_HIGH); - grub_sm712_sr_write (0x00, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_LOW); - grub_sm712_sr_write (0x02, GRUB_SM712_SR_PANEL_HW_VIDEO_COLOR_KEY_MASK_HIGH); - grub_sm712_sr_write (0xed, GRUB_SM712_SR_PANEL_HW_VIDEO_RED_CONSTANT); - grub_sm712_sr_write (0xed, GRUB_SM712_SR_PANEL_HW_VIDEO_GREEN_CONSTANT); - grub_sm712_sr_write (0xed, GRUB_SM712_SR_PANEL_HW_VIDEO_BLUE_CONSTANT); - - grub_sm712_sr_write (0x7b, GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_BOUNDARY); - grub_sm712_sr_write (0xfb, GRUB_SM712_SR_PANEL_HW_VIDEO_LEFT_BOUNDARY); - grub_sm712_sr_write (0xff, GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_BOUNDARY); - grub_sm712_sr_write (0xff, GRUB_SM712_SR_PANEL_HW_VIDEO_RIGHT_BOUNDARY); - /* Doesn't match documentation? */ - grub_sm712_sr_write (0x97, GRUB_SM712_SR_PANEL_HW_VIDEO_TOP_LEFT_OVERFLOW_BOUNDARY); - grub_sm712_sr_write (0xef, GRUB_SM712_SR_PANEL_HW_VIDEO_BOTTOM_RIGHT_OVERFLOW_BOUNDARY); - - grub_sm712_sr_write (0xbf, GRUB_SM712_SR_PANEL_HW_VIDEO_VERTICAL_STRETCH_FACTOR); - grub_sm712_sr_write (0xdf, GRUB_SM712_SR_PANEL_HW_VIDEO_HORIZONTAL_STRETCH_FACTOR); - - grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_SET_RESET_PLANE); - grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_SET_RESET_PLANE_ENABLE); - grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_COLOR_COMPARE); - grub_sm712_gr_write (GRUB_VGA_GR_DATA_ROTATE_NOP, GRUB_VGA_GR_DATA_ROTATE); - grub_sm712_gr_write (GRUB_VGA_NO_PLANES, GRUB_VGA_GR_READ_MAP_REGISTER); - grub_sm712_gr_write (GRUB_VGA_GR_MODE_256_COLOR, GRUB_VGA_GR_MODE); - grub_sm712_gr_write (GRUB_VGA_GR_GR6_MMAP_A0 - | GRUB_VGA_GR_GR6_GRAPHICS_MODE, GRUB_VGA_GR_GR6); - grub_sm712_gr_write (GRUB_VGA_ALL_PLANES, GRUB_VGA_GR_COLOR_COMPARE_DISABLE); - grub_sm712_gr_write (0xff, GRUB_VGA_GR_BITMASK); - - /* Write palette mapping. */ - for (i = 0; i < 16; i++) - grub_sm712_write_arx (i, i); - - grub_sm712_write_arx (GRUB_VGA_ARX_MODE_ENABLE_256COLOR - | GRUB_VGA_ARX_MODE_GRAPHICS, GRUB_VGA_ARX_MODE); - grub_sm712_write_arx (0, GRUB_VGA_ARX_OVERSCAN); - grub_sm712_write_arx (GRUB_VGA_ALL_PLANES, GRUB_VGA_ARX_COLOR_PLANE_ENABLE); - grub_sm712_write_arx (0, GRUB_VGA_ARX_HORIZONTAL_PANNING); - grub_sm712_write_arx (0, GRUB_VGA_ARX_COLOR_SELECT); - - /* FIXME: compute this generically. */ - { - struct grub_video_hw_config config = - { - .vertical_total = 806, - .vertical_blank_start = 0x300, - .vertical_blank_end = 0, - .vertical_sync_start = 0x303, - .vertical_sync_end = 0x9, - .line_compare = 0x3ff, - .vdisplay_end = 0x300, - .pitch = 0x80, - .horizontal_total = 164, - .horizontal_end = 128, - .horizontal_blank_start = 128, - .horizontal_blank_end = 0, - .horizontal_sync_pulse_start = 133, - .horizontal_sync_pulse_end = 22 - }; - grub_vga_set_geometry (&config, grub_sm712_cr_write); - config.horizontal_sync_pulse_start = 134; - config.horizontal_sync_pulse_end = 21; - config.vertical_sync_start = 0x301; - config.vertical_sync_end = 0x0; - config.line_compare = 0x0ff; - config.vdisplay_end = 0x258; - config.pitch = 0x7f; - grub_vga_set_geometry (&config, grub_sm712_cr_shadow_write); - } - - grub_sm712_cr_write (GRUB_VGA_CR_BYTE_PANNING_NORMAL, - GRUB_VGA_CR_BYTE_PANNING); - grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_START); - grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_END); - grub_sm712_cr_write (0, GRUB_VGA_CR_START_ADDR_HIGH_REGISTER); - grub_sm712_cr_write (0, GRUB_VGA_CR_START_ADDR_LOW_REGISTER); - grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_ADDR_HIGH); - grub_sm712_cr_write (0, GRUB_VGA_CR_CURSOR_ADDR_LOW); - grub_sm712_cr_write (GRUB_VGA_CR_UNDERLINE_LOCATION_DWORD_MODE, - GRUB_VGA_CR_UNDERLINE_LOCATION); - grub_sm712_cr_write (GRUB_VGA_CR_MODE_ADDRESS_WRAP - | GRUB_VGA_CR_MODE_BYTE_MODE - | GRUB_VGA_CR_MODE_TIMING_ENABLE - | GRUB_VGA_CR_MODE_NO_CGA - | GRUB_VGA_CR_MODE_NO_HERCULES, - GRUB_VGA_CR_MODE); - - grub_sm712_cr_write (0, GRUB_SM712_CR_OVERFLOW_INTERLACE); - grub_sm712_cr_write (0, GRUB_SM712_CR_INTERLACE_RETRACE); - grub_sm712_cr_write (0, GRUB_SM712_CR_TV_VDISPLAY_START); - grub_sm712_cr_write (0, GRUB_SM712_CR_TV_VDISPLAY_END_HIGH); - grub_sm712_cr_write (0, GRUB_SM712_CR_TV_VDISPLAY_END_LOW); - grub_sm712_cr_write (0x80, GRUB_SM712_CR_DDA_CONTROL_LOW); - grub_sm712_cr_write (0x02, GRUB_SM712_CR_DDA_CONTROL_HIGH); - - /* Undocumented */ - grub_sm712_cr_write (0x20, 0x37); - - grub_sm712_cr_write (0, GRUB_SM712_CR_TV_EQUALIZER); - grub_sm712_cr_write (0, GRUB_SM712_CR_TV_SERRATION); - grub_sm712_cr_write (0, GRUB_SM712_CR_HSYNC_CTRL); - - /* Undocumented */ - grub_sm712_cr_write (0x40, 0x3b); - - grub_sm712_cr_write (GRUB_SM712_CR_DEBUG_NONE, GRUB_SM712_CR_DEBUG); - - /* Undocumented */ - grub_sm712_cr_write (0xff, 0x3d); - grub_sm712_cr_write (0x46, 0x3e); - grub_sm712_cr_write (0x91, 0x3f); - - for (i = 0; i < ARRAY_SIZE (dda_lookups); i++) - grub_sm712_write_dda_lookup (i, dda_lookups[i].compare, dda_lookups[i].dda, - dda_lookups[i].vcentering); - - /* Undocumented */ - grub_sm712_cr_write (0, 0x9c); - grub_sm712_cr_write (0, 0x9d); - grub_sm712_cr_write (0, 0x9e); - grub_sm712_cr_write (0, 0x9f); - - grub_sm712_cr_write (0, GRUB_SM712_CR_VCENTERING_OFFSET); - grub_sm712_cr_write (0, GRUB_SM712_CR_HCENTERING_OFFSET); - - grub_sm712_write_reg (GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY - | GRUB_VGA_IO_MISC_UPPER_64K - | GRUB_VGA_IO_MISC_28MHZ - | GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS - | GRUB_VGA_IO_MISC_COLOR, - GRUB_VGA_IO_MISC_WRITE); - -#if !defined (TEST) && !defined(GENINIT) - /* Undocumented? */ - *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c00c) = 0; - *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c040) = 0; - *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c000) = 0x20000; - *(volatile grub_uint32_t *) ((char *) framebuffer.ptr + 0x40c010) = 0x1020100; -#endif - - (void) grub_sm712_sr_read (0x16); - -#if !defined (TEST) && !defined(GENINIT) - err = grub_video_fb_setup (mode_type, mode_mask, - &framebuffer.mode_info, - framebuffer.cached_ptr, NULL, NULL); - 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; -#else - return 0; -#endif -} - -#if !defined (TEST) && !defined(GENINIT) - -static grub_err_t -grub_video_sm712_swap_buffers (void) -{ - grub_size_t s; - s = (framebuffer.mode_info.height - * framebuffer.mode_info.pitch - * framebuffer.mode_info.bytes_per_pixel); - grub_video_fb_swap_buffers (); - grub_arch_sync_dma_caches (framebuffer.cached_ptr, s); - return GRUB_ERR_NONE; -} - -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, - - .prio = GRUB_VIDEO_ADAPTER_PRIO_NATIVE, - - .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_fb_set_palette, - .get_palette = grub_video_fb_get_palette, - .set_viewport = grub_video_fb_set_viewport, - .get_viewport = grub_video_fb_get_viewport, - .set_region = grub_video_fb_set_region, - .get_region = grub_video_fb_get_region, - .set_area_status = grub_video_fb_set_area_status, - .get_area_status = grub_video_fb_get_area_status, - .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_fb_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); -} -#else -int -main () -{ - grub_video_sm712_setup (1024, 600, 0, 0); -} -#endif diff --git a/grub-core/video/sm712_init.c b/grub-core/video/sm712_init.c deleted file mode 100644 index cdb0b7383..000000000 --- a/grub-core/video/sm712_init.c +++ /dev/null @@ -1,14 +0,0 @@ -/* Following sequence is a capture of sm712 initialisation sequence. */ -static grub_uint8_t sm712_sr_seq1[] = - { 0xc8, 0x40, 0x14, 0x60, 0x0, 0xa, 0x92, 0x0, - 0x51, 0x00, 0x01, 0x00, 0x0, 0x0, 0x00, 0x0, - 0xc4, 0x30, 0x02, 0x00, 0x1 }; - -static grub_uint8_t sm712_sr_seq2[] = - { 0x28, 0x03, 0x24, 0x09, 0xc0, 0x3a, 0x3a, 0x3a, - 0x3a, 0x3a, 0x3a, 0x3a, 0x00, 0x00, 0x03, 0xff, - 0x00, 0xfc, 0x00, 0x00, 0x20, 0x18, 0x00, 0xfc, - 0x20, 0x0c, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3a, - 0x06, 0x68, 0xa7, 0x7f, 0x83, 0x24, 0xff, 0x03, - 0x00, 0x60, 0x59, 0x3a, 0x3a, 0x00, 0x00, 0x3a, - 0x01, 0x80 }; diff --git a/grub-core/hello/hello.c b/hello/hello.c similarity index 83% rename from grub-core/hello/hello.c rename to hello/hello.c index 456b7c322..eff07d941 100644 --- a/grub-core/hello/hello.c +++ b/hello/hello.c @@ -26,14 +26,12 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - static grub_err_t -grub_cmd_hello (grub_extcmd_context_t ctxt __attribute__ ((unused)), +grub_cmd_hello (struct grub_extcmd *cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - grub_printf ("%s\n", _("Hello World")); + grub_printf ("Hello World\n"); return 0; } @@ -41,8 +39,8 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(hello) { - cmd = grub_register_extcmd ("hello", grub_cmd_hello, 0, 0, - N_("Say `Hello World'."), 0); + cmd = grub_register_extcmd ("hello", grub_cmd_hello, GRUB_COMMAND_FLAG_BOTH, + 0, N_("Say \"Hello World\"."), 0); } GRUB_MOD_FINI(hello) diff --git a/grub-core/hook/datehook.c b/hook/datehook.c similarity index 81% rename from grub-core/hook/datehook.c rename to hook/datehook.c index ac75908ef..4876e1198 100644 --- a/grub-core/hook/datehook.c +++ b/hook/datehook.c @@ -24,9 +24,7 @@ #include #include -GRUB_MOD_LICENSE ("GPLv3+"); - -static const char *grub_datetime_names[] = +static char *grub_datetime_names[] = { "YEAR", "MONTH", @@ -37,7 +35,7 @@ static const char *grub_datetime_names[] = "WEEKDAY", }; -static const char * +static char * grub_read_hook_datetime (struct grub_env_var *var, const char *val __attribute__ ((unused))) { @@ -50,7 +48,7 @@ grub_read_hook_datetime (struct grub_env_var *var, int i; for (i = 0; i < 7; i++) - if (grub_strcmp (var->name, grub_datetime_names[i]) == 0) + if (! grub_strcmp (var->name, grub_datetime_names[i])) { int n; @@ -86,23 +84,20 @@ grub_read_hook_datetime (struct grub_env_var *var, return buf; } -GRUB_MOD_INIT(datehook) +GRUB_MOD_INIT(datetime) { - unsigned i; + int i; - for (i = 0; i < ARRAY_SIZE (grub_datetime_names); i++) - { - grub_register_variable_hook (grub_datetime_names[i], - grub_read_hook_datetime, 0); - grub_env_export (grub_datetime_names[i]); - } + for (i = 0; i < 7; i++) + grub_register_variable_hook (grub_datetime_names[i], + grub_read_hook_datetime, 0); } -GRUB_MOD_FINI(datehook) +GRUB_MOD_FINI(datetime) { - unsigned i; + int i; - for (i = 0; i < ARRAY_SIZE (grub_datetime_names); 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/acpi.h b/include/grub/acpi.h index 1046f22d7..7933db824 100644 --- a/include/grub/acpi.h +++ b/include/grub/acpi.h @@ -19,24 +19,17 @@ #ifndef GRUB_ACPI_HEADER #define GRUB_ACPI_HEADER 1 -#ifndef GRUB_DSDT_TEST #include #include -#else -#define GRUB_PACKED __attribute__ ((packed)) -#endif - -#define GRUB_RSDP_SIGNATURE "RSD PTR " -#define GRUB_RSDP_SIGNATURE_SIZE 8 struct grub_acpi_rsdp_v10 { - grub_uint8_t signature[GRUB_RSDP_SIGNATURE_SIZE]; + grub_uint8_t signature[8]; grub_uint8_t checksum; grub_uint8_t oemid[6]; grub_uint8_t revision; grub_uint32_t rsdt_addr; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_acpi_rsdp_v20 { @@ -45,7 +38,7 @@ struct grub_acpi_rsdp_v20 grub_uint64_t xsdt_addr; grub_uint8_t checksum; grub_uint8_t reserved[3]; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_acpi_table_header { @@ -58,246 +51,25 @@ struct grub_acpi_table_header grub_uint32_t oemrev; grub_uint8_t creator_id[4]; grub_uint32_t creator_rev; -} GRUB_PACKED; - -#define GRUB_ACPI_FADT_SIGNATURE "FACP" +} __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[20]; - grub_uint32_t pm1a; - grub_uint8_t somefields2[8]; - grub_uint32_t pmtimer; - grub_uint8_t somefields3[32]; - grub_uint32_t flags; - grub_uint8_t somefields4[16]; + grub_uint8_t somefields1[88]; grub_uint64_t facs_xaddr; grub_uint64_t dsdt_xaddr; - grub_uint8_t somefields5[96]; -} GRUB_PACKED; + grub_uint8_t somefields2[96]; +} __attribute__ ((packed)); -#define GRUB_ACPI_MADT_SIGNATURE "APIC" - -/* Note: here GRUB_PACKED is not needed because we have grub_uint8_t only. */ -struct grub_acpi_madt_entry_header -{ - grub_uint8_t type; - grub_uint8_t len; -}; - -struct grub_acpi_madt -{ - struct grub_acpi_table_header hdr; - grub_uint32_t lapic_addr; - grub_uint32_t flags; - struct grub_acpi_madt_entry_header entries[0]; -} GRUB_PACKED; - -enum - { - GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC = 0, - GRUB_ACPI_MADT_ENTRY_TYPE_IOAPIC = 1, - GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE = 2, - GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC_NMI = 4, - GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC = 6, - GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC = 7, - GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE = 8 - }; - -struct grub_acpi_madt_entry_lapic -{ - struct grub_acpi_madt_entry_header hdr; - grub_uint8_t acpiid; - grub_uint8_t apicid; - grub_uint32_t flags; -} GRUB_PACKED; - -struct grub_acpi_madt_entry_ioapic -{ - struct grub_acpi_madt_entry_header hdr; - grub_uint8_t id; - grub_uint8_t pad; - grub_uint32_t address; - grub_uint32_t global_sys_interrupt; -} GRUB_PACKED; - -struct grub_acpi_madt_entry_interrupt_override -{ - struct grub_acpi_madt_entry_header hdr; - grub_uint8_t bus; - grub_uint8_t source; - grub_uint32_t global_sys_interrupt; - grub_uint16_t flags; -} GRUB_PACKED; - - -struct grub_acpi_madt_entry_lapic_nmi -{ - struct grub_acpi_madt_entry_header hdr; - grub_uint8_t acpiid; - grub_uint16_t flags; - grub_uint8_t lint; -} GRUB_PACKED; - -struct grub_acpi_madt_entry_sapic -{ - struct grub_acpi_madt_entry_header hdr; - grub_uint8_t id; - grub_uint8_t pad; - grub_uint32_t global_sys_interrupt_base; - grub_uint64_t addr; -} GRUB_PACKED; - -struct grub_acpi_madt_entry_lsapic -{ - struct grub_acpi_madt_entry_header hdr; - grub_uint8_t cpu_id; - grub_uint8_t id; - grub_uint8_t eid; - grub_uint8_t pad[3]; - grub_uint32_t flags; - grub_uint32_t cpu_uid; - grub_uint8_t cpu_uid_str[0]; -} GRUB_PACKED; - -struct grub_acpi_madt_entry_platform_int_source -{ - struct grub_acpi_madt_entry_header hdr; - grub_uint16_t flags; - grub_uint8_t inttype; - grub_uint8_t cpu_id; - grub_uint8_t cpu_eid; - grub_uint8_t sapic_vector; - grub_uint32_t global_sys_int; - grub_uint32_t src_flags; -} GRUB_PACKED; - -enum - { - GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED = 1 - }; - -struct grub_acpi_genaddr { - grub_uint8_t space_id; -#define GRUB_ACPI_GENADDR_MEM_SPACE 0x00 -#define GRUB_ACPI_GENADDR_IO_SPACE 0x01 - grub_uint8_t bit_width; - grub_uint8_t bit_offset; - grub_uint8_t access_size; -#define GRUB_ACPI_GENADDR_SIZE_LGCY 0x00 -#define GRUB_ACPI_GENADDR_SIZE_BYTE 0x01 -#define GRUB_ACPI_GENADDR_SIZE_WORD 0x02 -#define GRUB_ACPI_GENADDR_SIZE_DWORD 0x03 -#define GRUB_ACPI_GENADDR_SIZE_QWORD 0x04 - grub_uint64_t addr; -} GRUB_PACKED; - -#define GRUB_ACPI_SPCR_SIGNATURE "SPCR" - -struct grub_acpi_spcr { - struct grub_acpi_table_header hdr; - grub_uint8_t intf_type; -#define GRUB_ACPI_SPCR_INTF_TYPE_16550 0x00 -#define GRUB_ACPI_SPCR_INTF_TYPE_16550_DBGP 0x01 -#define GRUB_ACPI_SPCR_INTF_TYPE_16550_DBG2 0x12 - grub_uint8_t reserved_0[3]; - struct grub_acpi_genaddr base_addr; - grub_uint8_t interrupt_type; - grub_uint8_t irq; - grub_uint32_t gsi; - grub_uint8_t baud_rate; -#define GRUB_ACPI_SPCR_BAUD_CURRENT 0x00 -#define GRUB_ACPI_SPCR_BAUD_9600 0x03 -#define GRUB_ACPI_SPCR_BAUD_19200 0x04 -#define GRUB_ACPI_SPCR_BAUD_57600 0x06 -#define GRUB_ACPI_SPCR_BAUD_115200 0x07 - grub_uint8_t parity; - grub_uint8_t stop_bits; - grub_uint8_t flow_control; -#define GRUB_ACPI_SPCR_FC_DCD_TX (1 << 0) -#define GRUB_ACPI_SPCR_FC_RTSCTS (1 << 1) -#define GRUB_ACPI_SPCR_FC_XONXOFF (1 << 2) - grub_uint8_t terminal_type; - grub_uint8_t language; - grub_uint16_t pci_device_id; - grub_uint16_t pci_vendor_id; - grub_uint8_t pci_bus; - grub_uint8_t pci_device; - grub_uint8_t pci_function; - grub_uint32_t pci_flags; - grub_uint8_t pci_segment; - grub_uint32_t reserved_1; -} GRUB_PACKED; - -#ifndef GRUB_DSDT_TEST 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 *EXPORT_FUNC(grub_machine_acpi_get_rsdpv1) (void); -struct grub_acpi_rsdp_v20 *EXPORT_FUNC(grub_machine_acpi_get_rsdpv2) (void); -grub_uint8_t EXPORT_FUNC(grub_byte_checksum) (void *base, grub_size_t size); +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); -void grub_acpi_halt (void); -#endif - -#define GRUB_ACPI_SLP_EN (1 << 13) -#define GRUB_ACPI_SLP_TYP_OFFSET 10 - -enum - { - GRUB_ACPI_OPCODE_ZERO = 0, GRUB_ACPI_OPCODE_ONE = 1, - GRUB_ACPI_OPCODE_NAME = 8, GRUB_ACPI_OPCODE_ALIAS = 0x06, - GRUB_ACPI_OPCODE_BYTE_CONST = 0x0a, - GRUB_ACPI_OPCODE_WORD_CONST = 0x0b, - GRUB_ACPI_OPCODE_DWORD_CONST = 0x0c, - GRUB_ACPI_OPCODE_STRING_CONST = 0x0d, - GRUB_ACPI_OPCODE_SCOPE = 0x10, - GRUB_ACPI_OPCODE_BUFFER = 0x11, - GRUB_ACPI_OPCODE_PACKAGE = 0x12, - GRUB_ACPI_OPCODE_METHOD = 0x14, GRUB_ACPI_OPCODE_EXTOP = 0x5b, - GRUB_ACPI_OPCODE_ADD = 0x72, - GRUB_ACPI_OPCODE_CONCAT = 0x73, - GRUB_ACPI_OPCODE_SUBTRACT = 0x74, - GRUB_ACPI_OPCODE_MULTIPLY = 0x77, - GRUB_ACPI_OPCODE_DIVIDE = 0x78, - GRUB_ACPI_OPCODE_LSHIFT = 0x79, - GRUB_ACPI_OPCODE_RSHIFT = 0x7a, - GRUB_ACPI_OPCODE_AND = 0x7b, - GRUB_ACPI_OPCODE_NAND = 0x7c, - GRUB_ACPI_OPCODE_OR = 0x7d, - GRUB_ACPI_OPCODE_NOR = 0x7e, - GRUB_ACPI_OPCODE_XOR = 0x7f, - GRUB_ACPI_OPCODE_CONCATRES = 0x84, - GRUB_ACPI_OPCODE_MOD = 0x85, - GRUB_ACPI_OPCODE_INDEX = 0x88, - GRUB_ACPI_OPCODE_CREATE_DWORD_FIELD = 0x8a, - GRUB_ACPI_OPCODE_CREATE_WORD_FIELD = 0x8b, - GRUB_ACPI_OPCODE_CREATE_BYTE_FIELD = 0x8c, - GRUB_ACPI_OPCODE_TOSTRING = 0x9c, - GRUB_ACPI_OPCODE_IF = 0xa0, GRUB_ACPI_OPCODE_ONES = 0xff - }; -enum - { - GRUB_ACPI_EXTOPCODE_MUTEX = 0x01, - GRUB_ACPI_EXTOPCODE_EVENT_OP = 0x02, - GRUB_ACPI_EXTOPCODE_OPERATION_REGION = 0x80, - GRUB_ACPI_EXTOPCODE_FIELD_OP = 0x81, - GRUB_ACPI_EXTOPCODE_DEVICE_OP = 0x82, - GRUB_ACPI_EXTOPCODE_PROCESSOR_OP = 0x83, - GRUB_ACPI_EXTOPCODE_POWER_RES_OP = 0x84, - GRUB_ACPI_EXTOPCODE_THERMAL_ZONE_OP = 0x85, - GRUB_ACPI_EXTOPCODE_INDEX_FIELD_OP = 0x86, - GRUB_ACPI_EXTOPCODE_BANK_FIELD_OP = 0x87, - }; - -struct grub_acpi_fadt * -EXPORT_FUNC(grub_acpi_find_fadt) (void); - -void * -EXPORT_FUNC(grub_acpi_find_table) (const char *sig); - #endif /* ! GRUB_ACPI_HEADER */ diff --git a/include/grub/aout.h b/include/grub/aout.h index c8c1d94ec..04e85f8b0 100644 --- a/include/grub/aout.h +++ b/include/grub/aout.h @@ -52,7 +52,6 @@ #define GRUB_AOUT_HEADER 1 #include -#include struct grub_aout32_header { @@ -103,7 +102,6 @@ union grub_aout_header #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 */ @@ -116,14 +114,10 @@ union grub_aout_header #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, - void *load_addr, int load_size, - grub_size_t bss_size); - -#endif + grub_addr_t load_addr, int load_size, + grub_addr_t bss_end_addr); #endif /* ! GRUB_AOUT_HEADER */ diff --git a/include/grub/arc/arc.h b/include/grub/arc/arc.h deleted file mode 100644 index 6d14b9748..000000000 --- a/include/grub/arc/arc.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_ARC_HEADER -#define GRUB_ARC_HEADER 1 - -#include -#include - -typedef unsigned grub_arc_enum_t; -typedef grub_uint64_t grub_arc_ularge_t; -typedef unsigned long grub_arc_ulong_t; -typedef long grub_arc_long_t; -typedef unsigned short grub_arc_ushort_t; -typedef unsigned char grub_arc_uchar_t; - -typedef grub_arc_long_t grub_arc_err_t; -typedef grub_arc_ulong_t grub_arc_fileno_t; - -struct grub_arc_memory_descriptor -{ - grub_arc_enum_t type; - grub_arc_ulong_t start_page; - grub_arc_ulong_t num_pages; -}; - -enum grub_arc_memory_type - { - GRUB_ARC_MEMORY_EXCEPTION_BLOCK, - GRUB_ARC_MEMORY_SYSTEM_PARAMETER_BLOCK, -#ifdef GRUB_CPU_WORDS_BIGENDIAN - GRUB_ARC_MEMORY_FREE_CONTIGUOUS, -#endif - GRUB_ARC_MEMORY_FREE, - GRUB_ARC_MEMORY_BADRAM, - GRUB_ARC_MEMORY_LOADED, GRUB_ARC_MEMORY_FW_TEMPORARY, - GRUB_ARC_MEMORY_FW_PERMANENT, -#ifndef GRUB_CPU_WORDS_BIGENDIAN - GRUB_ARC_MEMORY_FREE_CONTIGUOUS, -#endif - }; - -struct grub_arc_timeinfo -{ - grub_arc_ushort_t y; - grub_arc_ushort_t m; - grub_arc_ushort_t d; - grub_arc_ushort_t h; - grub_arc_ushort_t min; - grub_arc_ushort_t s; - grub_arc_ushort_t ms; -}; - -struct grub_arc_display_status -{ - grub_arc_ushort_t x; - grub_arc_ushort_t y; - grub_arc_ushort_t w; - grub_arc_ushort_t h; - grub_arc_uchar_t fgcolor; - grub_arc_uchar_t bgcolor; - grub_arc_uchar_t high_intensity; - grub_arc_uchar_t underscored; - grub_arc_uchar_t reverse_video; -}; - -enum - { - GRUB_ARC_COMPONENT_FLAG_OUT = 0x40, - GRUB_ARC_COMPONENT_FLAG_IN = 0x20, - }; - -struct grub_arc_component -{ - grub_arc_enum_t class; - grub_arc_enum_t type; - grub_arc_enum_t flags; - grub_arc_ushort_t version; - grub_arc_ushort_t rev; - grub_arc_ulong_t key; - grub_arc_ulong_t affinity; - grub_arc_ulong_t configdatasize; - grub_arc_ulong_t idlen; - const char *idstr; -}; - -enum - { -#ifdef GRUB_CPU_WORDS_BIGENDIAN - GRUB_ARC_COMPONENT_TYPE_ARC = 1, -#else - GRUB_ARC_COMPONENT_TYPE_ARC, -#endif - GRUB_ARC_COMPONENT_TYPE_CPU, - GRUB_ARC_COMPONENT_TYPE_FPU, - GRUB_ARC_COMPONENT_TYPE_PRI_I_CACHE, - GRUB_ARC_COMPONENT_TYPE_PRI_D_CACHE, - GRUB_ARC_COMPONENT_TYPE_SEC_I_CACHE, - GRUB_ARC_COMPONENT_TYPE_SEC_D_CACHE, - GRUB_ARC_COMPONENT_TYPE_SEC_CACHE, - GRUB_ARC_COMPONENT_TYPE_EISA, - GRUB_ARC_COMPONENT_TYPE_TCA, - GRUB_ARC_COMPONENT_TYPE_SCSI, - GRUB_ARC_COMPONENT_TYPE_DTIA, - GRUB_ARC_COMPONENT_TYPE_MULTIFUNC, - GRUB_ARC_COMPONENT_TYPE_DISK_CONTROLLER, - GRUB_ARC_COMPONENT_TYPE_TAPE_CONTROLLER, - GRUB_ARC_COMPONENT_TYPE_CDROM_CONTROLLER, - GRUB_ARC_COMPONENT_TYPE_WORM_CONTROLLER, - GRUB_ARC_COMPONENT_TYPE_SERIAL_CONTROLLER, - GRUB_ARC_COMPONENT_TYPE_NET_CONTROLLER, - GRUB_ARC_COMPONENT_TYPE_DISPLAY_CONTROLLER, - GRUB_ARC_COMPONENT_TYPE_PARALLEL_CONTROLLER, - GRUB_ARC_COMPONENT_TYPE_POINTER_CONTROLLER, - GRUB_ARC_COMPONENT_TYPE_KBD_CONTROLLER, - GRUB_ARC_COMPONENT_TYPE_AUDIO_CONTROLLER, - GRUB_ARC_COMPONENT_TYPE_OTHER_CONTROLLER, - GRUB_ARC_COMPONENT_TYPE_DISK, - GRUB_ARC_COMPONENT_TYPE_FLOPPY, - GRUB_ARC_COMPONENT_TYPE_TAPE, - GRUB_ARC_COMPONENT_TYPE_MODEM, - GRUB_ARC_COMPONENT_TYPE_MONITOR, - GRUB_ARC_COMPONENT_TYPE_PRINTER, - GRUB_ARC_COMPONENT_TYPE_POINTER, - GRUB_ARC_COMPONENT_TYPE_KBD, - GRUB_ARC_COMPONENT_TYPE_TERMINAL, -#ifndef GRUB_CPU_WORDS_BIGENDIAN - GRUB_ARC_COMPONENT_TYPE_OTHER_PERIPHERAL, -#endif - GRUB_ARC_COMPONENT_TYPE_LINE, - GRUB_ARC_COMPONENT_TYPE_NET, - GRUB_ARC_COMPONENT_TYPE_MEMORY_UNIT, - }; - -enum grub_arc_file_access - { - GRUB_ARC_FILE_ACCESS_OPEN_RO, - GRUB_ARC_FILE_ACCESS_OPEN_WO, - GRUB_ARC_FILE_ACCESS_OPEN_RW, - }; - -struct grub_arc_fileinfo -{ - grub_arc_ularge_t start; - grub_arc_ularge_t end; - grub_arc_ularge_t current; - grub_arc_enum_t type; - grub_arc_ulong_t fnamelength; - grub_arc_uchar_t attr; - char filename[32]; -}; - -struct grub_arc_firmware_vector -{ - /* 0x00. */ - void *load; - void *invoke; - void *execute; - void *halt; - - /* 0x10. */ - void (*powerdown) (void); - void (*restart) (void); - void (*reboot) (void); - void (*exit) (void); - - /* 0x20. */ - void *reserved1; - const struct grub_arc_component * (*getpeer) (const struct grub_arc_component *comp); - const struct grub_arc_component * (*getchild) (const struct grub_arc_component *comp); - void *getparent; - - /* 0x30. */ - void *getconfigurationdata; - void *addchild; - void *deletecomponent; - void *getcomponent; - - /* 0x40. */ - void *saveconfiguration; - void *getsystemid; - struct grub_arc_memory_descriptor *(*getmemorydescriptor) (struct grub_arc_memory_descriptor *current); - void *reserved2; - - /* 0x50. */ - struct grub_arc_timeinfo *(*gettime) (void); - void *getrelativetime; - void *getdirectoryentry; - grub_arc_err_t (*open) (const char *path, grub_arc_enum_t mode, - grub_arc_fileno_t *fileno); - - /* 0x60. */ - grub_arc_err_t (*close) (grub_arc_fileno_t fileno); - grub_arc_err_t (*read) (grub_arc_fileno_t fileno, void *buf, - grub_arc_ulong_t n, - grub_arc_ulong_t *count); - grub_arc_err_t (*get_read_status) (grub_arc_fileno_t fileno); - grub_arc_err_t (*write) (grub_arc_fileno_t fileno, const void *buf, - grub_arc_ulong_t n, - grub_arc_ulong_t *count); - - /* 0x70. */ - grub_arc_err_t (*seek) (grub_arc_fileno_t fileno, - grub_arc_ularge_t *pos, grub_arc_enum_t mode); - void *mount; - const char * (*getenvironmentvariable) (const char *name); - void *setenvironmentvariable; - - /* 0x80. */ - grub_arc_err_t (*getfileinformation) (grub_arc_fileno_t fileno, - struct grub_arc_fileinfo *info); - void *setfileinformation; - void *flushallcaches; - void *testunicodecharacter; - - /* 0x90. */ - struct grub_arc_display_status * (*getdisplaystatus) (grub_arc_fileno_t fileno); -}; - -struct grub_arc_adapter -{ - grub_arc_ulong_t adapter_type; - grub_arc_ulong_t adapter_vector_length; - void *adapter_vector; -}; - -struct grub_arc_system_parameter_block -{ - grub_arc_ulong_t signature; - grub_arc_ulong_t length; - grub_arc_ushort_t version; - grub_arc_ushort_t revision; - void *restartblock; - void *debugblock; - void *gevector; - void *utlbmissvector; - grub_arc_ulong_t firmware_vector_length; - struct grub_arc_firmware_vector *firmwarevector; - grub_arc_ulong_t private_vector_length; - void *private_vector; - grub_arc_ulong_t adapter_count; - struct grub_arc_adapter adapters[0]; -}; - - -#define GRUB_ARC_SYSTEM_PARAMETER_BLOCK ((struct grub_arc_system_parameter_block *) 0xa0001000) -#define GRUB_ARC_FIRMWARE_VECTOR (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmwarevector) -#define GRUB_ARC_STDIN 0 -#define GRUB_ARC_STDOUT 1 - -typedef int (*grub_arc_iterate_devs_hook_t) - (const char *name, const struct grub_arc_component *comp, void *data); - -int EXPORT_FUNC (grub_arc_iterate_devs) (grub_arc_iterate_devs_hook_t hook, - void *hook_data, - int alt_names); - -char *EXPORT_FUNC (grub_arc_alt_name_to_norm) (const char *name, const char *suffix); - -int EXPORT_FUNC (grub_arc_is_device_serial) (const char *name, int alt_names); - - -#define FOR_ARC_CHILDREN(comp, parent) for (comp = GRUB_ARC_FIRMWARE_VECTOR->getchild (parent); comp; comp = GRUB_ARC_FIRMWARE_VECTOR->getpeer (comp)) - -extern void grub_arcdisk_init (void); -extern void grub_arcdisk_fini (void); - - -#endif diff --git a/include/grub/archelp.h b/include/grub/archelp.h deleted file mode 100644 index 2611d7f45..000000000 --- a/include/grub/archelp.h +++ /dev/null @@ -1,63 +0,0 @@ -/* archelp.h -- Archive helper functions */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_ARCHELP_HEADER -#define GRUB_ARCHELP_HEADER 1 - -#include -#include - -typedef enum - { - GRUB_ARCHELP_ATTR_TYPE = 0160000, - GRUB_ARCHELP_ATTR_FILE = 0100000, - GRUB_ARCHELP_ATTR_DIR = 0040000, - GRUB_ARCHELP_ATTR_LNK = 0120000, - GRUB_ARCHELP_ATTR_NOTIME = 0x80000000, - GRUB_ARCHELP_ATTR_END = 0xffffffff - } grub_archelp_mode_t; - -struct grub_archelp_data; - -struct grub_archelp_ops -{ - grub_err_t - (*find_file) (struct grub_archelp_data *data, char **name, - grub_int32_t *mtime, - grub_archelp_mode_t *mode); - - char * - (*get_link_target) (struct grub_archelp_data *data); - - void - (*rewind) (struct grub_archelp_data *data); -}; - -grub_err_t -grub_archelp_dir (struct grub_archelp_data *data, - struct grub_archelp_ops *ops, - const char *path_in, - grub_fs_dir_hook_t hook, void *hook_data); - -grub_err_t -grub_archelp_open (struct grub_archelp_data *data, - struct grub_archelp_ops *ops, - const char *name_in); - -#endif diff --git a/include/grub/arm/coreboot/console.h b/include/grub/arm/coreboot/console.h deleted file mode 100644 index 13a14b783..000000000 --- a/include/grub/arm/coreboot/console.h +++ /dev/null @@ -1,29 +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 . - */ - -#ifndef GRUB_MACHINE_CONSOLE_HEADER -#define GRUB_MACHINE_CONSOLE_HEADER 1 - -void grub_video_coreboot_fb_init (void); -void grub_video_coreboot_fb_early_init (void); -void grub_video_coreboot_fb_late_init (void); -void grub_video_coreboot_fb_fini (void); - -extern struct grub_linuxbios_table_framebuffer *grub_video_coreboot_fbtable; - -#endif /* ! GRUB_MACHINE_CONSOLE_HEADER */ diff --git a/include/grub/arm/coreboot/kernel.h b/include/grub/arm/coreboot/kernel.h deleted file mode 100644 index 269505342..000000000 --- a/include/grub/arm/coreboot/kernel.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_KERNEL_MACHINE_HEADER -#define GRUB_KERNEL_MACHINE_HEADER 1 - -#ifndef ASM_FILE - -#include -#include - -struct grub_fdt_board -{ - const char *vendor, *part; - const grub_uint8_t *dtb; - grub_size_t dtb_size; -}; - -extern struct grub_fdt_board grub_fdt_boards[]; -void grub_machine_timer_init (void); -void grub_pl050_init (void); -void grub_cros_init (void); -void grub_rk3288_spi_init (void); -extern grub_addr_t EXPORT_VAR (start_of_ram); -#endif /* ! ASM_FILE */ - -#define GRUB_KERNEL_MACHINE_STACK_SIZE GRUB_KERNEL_ARM_STACK_SIZE - -#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/arm/cros_ec.h b/include/grub/arm/cros_ec.h deleted file mode 100644 index 45a372572..000000000 --- a/include/grub/arm/cros_ec.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef GRUB_ARM_CROS_EC_H -#define GRUB_ARM_CROS_EC_H 1 - -#include -#include - -#define GRUB_CROS_EC_KEYSCAN_COLS 13 -#define GRUB_CROS_EC_KEYSCAN_ROWS 8 - -struct grub_cros_ec_keyscan { - grub_uint8_t data[GRUB_CROS_EC_KEYSCAN_COLS]; -}; - -int -grub_cros_ec_scan_keyboard (const struct grub_fdtbus_dev *dev, - struct grub_cros_ec_keyscan *scan); - -int -grub_cros_ec_validate (const struct grub_fdtbus_dev *dev); - -#endif diff --git a/include/grub/arm/efi/memory.h b/include/grub/arm/efi/memory.h deleted file mode 100644 index 2c64918e3..000000000 --- a/include/grub/arm/efi/memory.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef GRUB_MEMORY_CPU_HEADER -#include - -#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff - -#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h deleted file mode 100644 index 5b8fb14e0..000000000 --- a/include/grub/arm/linux.h +++ /dev/null @@ -1,52 +0,0 @@ -/* linux.h - ARM linux specific definitions */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_ARM_LINUX_HEADER -#define GRUB_ARM_LINUX_HEADER 1 - -#include "system.h" - -#include - -#if defined GRUB_MACHINE_UBOOT -# include -# define LINUX_ADDRESS (start_of_ram + 0x8000) -# define LINUX_INITRD_ADDRESS (start_of_ram + 0x03000000) -# define LINUX_FDT_ADDRESS (LINUX_INITRD_ADDRESS - 0x10000) -# define grub_arm_firmware_get_boot_data grub_uboot_get_boot_data -# define grub_arm_firmware_get_machine_type grub_uboot_get_machine_type -#elif defined (GRUB_MACHINE_COREBOOT) -#include -#include -# define LINUX_ADDRESS (start_of_ram + 0x8000) -# define LINUX_INITRD_ADDRESS (start_of_ram + 0x03000000) -# define LINUX_FDT_ADDRESS (LINUX_INITRD_ADDRESS - 0x10000) -static inline const void * -grub_arm_firmware_get_boot_data (void) -{ - return grub_fdtbus_get_fdt (); -} -static inline grub_uint32_t -grub_arm_firmware_get_machine_type (void) -{ - return GRUB_ARM_MACHINE_TYPE_FDT; -} -#endif - -#endif /* ! GRUB_ARM_LINUX_HEADER */ diff --git a/include/grub/arm/reloc.h b/include/grub/arm/reloc.h deleted file mode 100644 index ae92e21f1..000000000 --- a/include/grub/arm/reloc.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_ARM_RELOC_H -#define GRUB_ARM_RELOC_H 1 - -grub_err_t grub_arm_reloc_abs32 (grub_uint32_t *addr, Elf32_Addr sym_addr); - -int -grub_arm_thm_call_check_offset (grub_int32_t offset, int is_thumb); -grub_int32_t -grub_arm_thm_call_get_offset (grub_uint16_t *target); -grub_err_t -grub_arm_thm_call_set_offset (grub_uint16_t *target, grub_int32_t offset); - -grub_int32_t -grub_arm_thm_jump19_get_offset (grub_uint16_t *target); -void -grub_arm_thm_jump19_set_offset (grub_uint16_t *target, grub_int32_t offset); -int -grub_arm_thm_jump19_check_offset (grub_int32_t offset); - -grub_int32_t -grub_arm_jump24_get_offset (grub_uint32_t *target); -int -grub_arm_jump24_check_offset (grub_int32_t offset); -void -grub_arm_jump24_set_offset (grub_uint32_t *target, - grub_int32_t offset); - -grub_uint16_t -grub_arm_thm_movw_movt_get_value (grub_uint16_t *target); -void -grub_arm_thm_movw_movt_set_value (grub_uint16_t *target, grub_uint16_t value); - -#endif diff --git a/include/grub/arm/setjmp.h b/include/grub/arm/setjmp.h deleted file mode 100644 index 7990f2eb3..000000000 --- a/include/grub/arm/setjmp.h +++ /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 . - */ - -#ifndef GRUB_SETJMP_CPU_HEADER -#define GRUB_SETJMP_CPU_HEADER 1 - -typedef unsigned long grub_jmp_buf[10]; - -int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; -void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); - -#endif /* ! GRUB_SETJMP_CPU_HEADER */ diff --git a/include/grub/arm/startup.h b/include/grub/arm/startup.h deleted file mode 100644 index 9afb6c57c..000000000 --- a/include/grub/arm/startup.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef GRUB_STARTUP_CPU_HEADER -#define GRUB_STARTUP_CPU_HEADER - -struct grub_arm_startup_registers -{ - /* registers 0-11 */ - /* for U-boot r[1] is machine type */ - /* for U-boot r[2] is boot data */ - grub_uint32_t r[12]; - grub_uint32_t sp; - grub_uint32_t lr; -}; - -extern struct grub_arm_startup_registers grub_arm_saved_registers; - -#endif diff --git a/include/grub/arm/system.h b/include/grub/arm/system.h deleted file mode 100644 index f15ce9751..000000000 --- a/include/grub/arm/system.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef GRUB_SYSTEM_CPU_HEADER -#define GRUB_SYSTEM_CPU_HEADER - -#include -#include - -enum - { - GRUB_ARM_MACHINE_TYPE_RASPBERRY_PI = 3138, - GRUB_ARM_MACHINE_TYPE_FDT = 0xFFFFFFFF - }; - -void EXPORT_FUNC(grub_arm_disable_caches_mmu) (void); -void grub_arm_enable_caches_mmu (void); -void grub_arm_enable_mmu (grub_uint32_t *mmu_tables); -void grub_arm_clear_mmu_v6 (void); - -#endif /* ! GRUB_SYSTEM_CPU_HEADER */ - diff --git a/include/grub/arm/time.h b/include/grub/arm/time.h deleted file mode 100644 index c5a685225..000000000 --- a/include/grub/arm/time.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#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 ("wfi"); */ -} - -#endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/arm/types.h b/include/grub/arm/types.h deleted file mode 100644 index 4a806d05e..000000000 --- a/include/grub/arm/types.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#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 - -/* currently only support little-endian. */ -#undef GRUB_TARGET_WORDS_BIGENDIAN - -/* Unaligned accesses only supported if MMU enabled */ -//#define GRUB_HAVE_UNALIGNED_ACCESS 1 - -#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/arm64/efi/memory.h b/include/grub/arm64/efi/memory.h deleted file mode 100644 index c6cb32417..000000000 --- a/include/grub/arm64/efi/memory.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef GRUB_MEMORY_CPU_HEADER -#include - -#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffULL - -#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/arm64/reloc.h b/include/grub/arm64/reloc.h deleted file mode 100644 index c8765de97..000000000 --- a/include/grub/arm64/reloc.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_ARM64_RELOC_H -#define GRUB_ARM64_RELOC_H 1 - -struct grub_arm64_trampoline -{ - grub_uint32_t ldr; /* ldr x16, 8 */ - grub_uint32_t br; /* br x16 */ - grub_uint64_t addr; -}; - -int grub_arm_64_check_xxxx26_offset (grub_int64_t offset); -void -grub_arm64_set_xxxx26_offset (grub_uint32_t *place, grub_int64_t offset); -int -grub_arm64_check_hi21_signed (grub_int64_t offset); -void -grub_arm64_set_hi21 (grub_uint32_t *place, grub_int64_t offset); -void -grub_arm64_set_abs_lo12 (grub_uint32_t *place, grub_int64_t target); -void -grub_arm64_set_abs_lo12_ldst64 (grub_uint32_t *place, grub_int64_t target); - -#endif diff --git a/include/grub/arm64/setjmp.h b/include/grub/arm64/setjmp.h deleted file mode 100644 index 3ff7dfbf3..000000000 --- a/include/grub/arm64/setjmp.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_SETJMP_CPU_HEADER -#define GRUB_SETJMP_CPU_HEADER 1 - -typedef unsigned long long grub_jmp_buf[13]; - -int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; -void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); - -#endif /* ! GRUB_SETJMP_CPU_HEADER */ diff --git a/include/grub/arm64/time.h b/include/grub/arm64/time.h deleted file mode 100644 index c5a685225..000000000 --- a/include/grub/arm64/time.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#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 ("wfi"); */ -} - -#endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/arm64/types.h b/include/grub/arm64/types.h deleted file mode 100644 index d132c5eab..000000000 --- a/include/grub/arm64/types.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#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 - -/* currently only support little-endian. */ -#undef GRUB_TARGET_WORDS_BIGENDIAN - -/* Unaligned accesses only supported if MMU enabled */ -#undef GRUB_HAVE_UNALIGNED_ACCESS - -#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h index bcb4d9ba7..10421540a 100644 --- a/include/grub/at_keyboard.h +++ b/include/grub/at_keyboard.h @@ -19,22 +19,36 @@ #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_ENABLE 0xf4 #define KEYBOARD_COMMAND_REBOOT 0xfe -#define KEYBOARD_AT_TRANSLATE 0x40 -#define KEYBOARD_AT_DISABLE 0x10 +#define KEYBOARD_SCANCODE_SET1 0x40 #define KEYBOARD_ISMAKE(x) !((x) & 0x80) #define KEYBOARD_ISREADY(x) ((x) & 0x01) #define KEYBOARD_SCANCODE(x) ((x) & 0x7f) -extern void grub_at_keyboard_init (void); -extern void grub_at_keyboard_fini (void); -int grub_at_keyboard_is_alive (void); +#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 index e8a84b86a..940e67102 100644 --- a/include/grub/ata.h +++ b/include/grub/ata.h @@ -22,7 +22,6 @@ #include #include -#include /* XXX: For now this only works on i386. */ #include @@ -33,12 +32,6 @@ typedef enum GRUB_ATA_LBA48 } grub_ata_addressing_t; -#define GRUB_ATA_CH0_PORT1 0x1f0 -#define GRUB_ATA_CH1_PORT1 0x170 - -#define GRUB_ATA_CH0_PORT2 0x3f6 -#define GRUB_ATA_CH1_PORT2 0x376 - #define GRUB_ATA_REG_DATA 0 #define GRUB_ATA_REG_ERROR 1 #define GRUB_ATA_REG_FEATURES 1 @@ -83,9 +76,6 @@ enum grub_ata_commands GRUB_ATA_CMD_PACKET = 0xa0, GRUB_ATA_CMD_READ_SECTORS = 0x20, GRUB_ATA_CMD_READ_SECTORS_EXT = 0x24, - GRUB_ATA_CMD_READ_SECTORS_DMA = 0xc8, - GRUB_ATA_CMD_READ_SECTORS_DMA_EXT = 0x25, - GRUB_ATA_CMD_SECURITY_FREEZE_LOCK = 0xf5, GRUB_ATA_CMD_SET_FEATURES = 0xef, GRUB_ATA_CMD_SLEEP = 0xe6, @@ -93,76 +83,29 @@ enum grub_ata_commands GRUB_ATA_CMD_STANDBY_IMMEDIATE = 0xe0, GRUB_ATA_CMD_WRITE_SECTORS = 0x30, GRUB_ATA_CMD_WRITE_SECTORS_EXT = 0x34, - GRUB_ATA_CMD_WRITE_SECTORS_DMA_EXT = 0x35, - GRUB_ATA_CMD_WRITE_SECTORS_DMA = 0xca, }; enum grub_ata_timeout_milliseconds { GRUB_ATA_TOUT_STD = 1000, /* 1s standard timeout. */ - GRUB_ATA_TOUT_DATA = 10000, /* 10s DATA I/O timeout. */ - GRUB_ATA_TOUT_SPINUP = 10000, /* Give the device 10s on first try to spinon. */ + GRUB_ATA_TOUT_DATA = 10000 /* 10s DATA I/O timeout. */ }; -typedef union +struct grub_ata_device { - grub_uint8_t raw[11]; - struct - { - union - { - grub_uint8_t features; - grub_uint8_t error; - }; - union - { - grub_uint8_t sectors; - grub_uint8_t atapi_ireason; - }; - union - { - grub_uint8_t lba_low; - grub_uint8_t sectnum; - }; - union - { - grub_uint8_t lba_mid; - grub_uint8_t cyllsb; - grub_uint8_t atapi_cntlow; - }; - union - { - grub_uint8_t lba_high; - grub_uint8_t cylmsb; - grub_uint8_t atapi_cnthigh; - }; - grub_uint8_t disk; - union - { - grub_uint8_t cmd; - grub_uint8_t status; - }; - grub_uint8_t sectors48; - grub_uint8_t lba48_low; - grub_uint8_t lba48_mid; - grub_uint8_t lba48_high; - }; -} grub_ata_regs_t; + /* IDE port to use. */ + int port; -/* ATA pass through parameters and function. */ -struct grub_disk_ata_pass_through_parms -{ - grub_ata_regs_t taskfile; - void * buffer; - grub_size_t size; - int write; - void *cmd; - int cmdsize; - int dma; -}; + /* 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; -struct grub_ata -{ /* 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. */ @@ -170,7 +113,6 @@ struct grub_ata /* Sector count. */ grub_uint64_t size; - grub_uint32_t log_sector_size; /* CHS maximums. */ grub_uint16_t cylinders; @@ -180,46 +122,47 @@ struct grub_ata /* Set to 0 for ATA, set to 1 for ATAPI. */ int atapi; - int dma; - - grub_size_t maxbuffer; - - int *present; - - void *data; - - struct grub_ata_dev *dev; + struct grub_ata_device *next; }; -typedef struct grub_ata *grub_ata_t; +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); -typedef int (*grub_ata_dev_iterate_hook_t) (int id, int bus, void *data); - -struct grub_ata_dev +static inline void +grub_ata_regset (struct grub_ata_device *dev, int reg, int val) { - /* Call HOOK with each device name, until HOOK returns non-zero. */ - int (*iterate) (grub_ata_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull); + grub_outb (val, dev->ioaddress + reg); +} - /* Open the device named NAME, and set up SCSI. */ - grub_err_t (*open) (int id, int bus, struct grub_ata *scsi); +static inline grub_uint8_t +grub_ata_regget (struct grub_ata_device *dev, int reg) +{ + return grub_inb (dev->ioaddress + reg); +} - /* Close the scsi device SCSI. */ - void (*close) (struct grub_ata *ata); +static inline void +grub_ata_regset2 (struct grub_ata_device *dev, int reg, int val) +{ + grub_outb (val, dev->ioaddress2 + reg); +} - /* Read SIZE bytes from the device SCSI into BUF after sending the - command CMD of size CMDSIZE. */ - grub_err_t (*readwrite) (struct grub_ata *ata, - struct grub_disk_ata_pass_through_parms *parms, - int spinup); +static inline grub_uint8_t +grub_ata_regget2 (struct grub_ata_device *dev, int reg) +{ + return grub_inb (dev->ioaddress2 + reg); +} - /* The next scsi device. */ - struct grub_ata_dev *next; -}; +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); -typedef struct grub_ata_dev *grub_ata_dev_t; - -void grub_ata_dev_register (grub_ata_dev_t dev); -void grub_ata_dev_unregister (grub_ata_dev_t dev); + return GRUB_ERR_NONE; +} #endif /* ! GRUB_ATA_HEADER */ diff --git a/include/grub/auth.h b/include/grub/auth.h index 21d5190f0..747334451 100644 --- a/include/grub/auth.h +++ b/include/grub/auth.h @@ -33,6 +33,5 @@ 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); -grub_err_t grub_auth_check_cli_access (void); #endif /* ! GRUB_AUTH_HEADER */ diff --git a/include/grub/autoefi.h b/include/grub/autoefi.h index b7a252e07..5ae4b3a21 100644 --- a/include/grub/autoefi.h +++ b/include/grub/autoefi.h @@ -34,12 +34,22 @@ 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 grub_autoefi_finish_boot_services grub_efi_finish_boot_services # define EFI_PRESENT 1 #else # include @@ -50,14 +60,18 @@ static inline grub_err_t grub_autoefi_prepare (void) # 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_fixed(x,y) (x) +# define grub_efi_allocate_pages(x,y) (x) # define grub_efi_free_pages(x,y) GRUB_EFI_SUCCESS -# define grub_autoefi_finish_boot_services grub_efiemu_finish_boot_services # define EFI_PRESENT 1 #endif diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h index 431048936..6e300391a 100644 --- a/include/grub/bitmap.h +++ b/include/grub/bitmap.h @@ -23,9 +23,6 @@ #include #include #include -#include - -#define IMAGE_HW_MAX_PX 16384 struct grub_video_bitmap { @@ -62,42 +59,8 @@ grub_err_t EXPORT_FUNC (grub_video_bitmap_destroy) (struct grub_video_bitmap *bi grub_err_t EXPORT_FUNC (grub_video_bitmap_load) (struct grub_video_bitmap **bitmap, const char *filename); -/* Return bitmap width. */ -static inline unsigned int -grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap) -{ - if (!bitmap) - return 0; - - return bitmap->mode_info.width; -} - -/* Return bitmap height. */ -static inline unsigned int -grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap) -{ - if (!bitmap) - return 0; - - return bitmap->mode_info.height; -} - -/* - * Calculate and store the size of data buffer of 1bit bitmap in result. - * Equivalent to "*result = (width * height + 7) / 8" if no overflow occurs. - * Return true when overflow occurs or false if there is no overflow. - * This function is intentionally implemented as a macro instead of - * an inline function. Although a bit awkward, it preserves data types for - * safemath macros and reduces macro side effects as much as possible. - * - * XXX: Will report false overflow if width * height > UINT64_MAX. - */ -#define grub_video_bitmap_calc_1bpp_bufsz(width, height, result) \ -({ \ - grub_uint64_t _bitmap_pixels; \ - grub_mul ((width), (height), &_bitmap_pixels) ? 1 : \ - grub_cast (_bitmap_pixels / GRUB_CHAR_BIT + !!(_bitmap_pixels % GRUB_CHAR_BIT), (result)); \ -}) +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); diff --git a/include/grub/bitmap_scale.h b/include/grub/bitmap_scale.h index 7230bc91f..dce9fbbf2 100644 --- a/include/grub/bitmap_scale.h +++ b/include/grub/bitmap_scale.h @@ -38,48 +38,12 @@ enum grub_video_bitmap_scale_method GRUB_VIDEO_BITMAP_SCALE_METHOD_BILINEAR }; -typedef enum grub_video_bitmap_selection_method -{ - GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH, - GRUB_VIDEO_BITMAP_SELECTION_METHOD_CROP, - GRUB_VIDEO_BITMAP_SELECTION_METHOD_PADDING, - GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITWIDTH, - GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITHEIGHT -} grub_video_bitmap_selection_method_t; - -typedef enum grub_video_bitmap_v_align -{ - GRUB_VIDEO_BITMAP_V_ALIGN_TOP, - GRUB_VIDEO_BITMAP_V_ALIGN_CENTER, - GRUB_VIDEO_BITMAP_V_ALIGN_BOTTOM -} grub_video_bitmap_v_align_t; - -typedef enum grub_video_bitmap_h_align -{ - GRUB_VIDEO_BITMAP_H_ALIGN_LEFT, - GRUB_VIDEO_BITMAP_H_ALIGN_CENTER, - GRUB_VIDEO_BITMAP_H_ALIGN_RIGHT -} grub_video_bitmap_h_align_t; - 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 + enum grub_video_bitmap_scale_method scale_method); -grub_err_t -EXPORT_FUNC (grub_video_bitmap_scale_proportional) - (struct grub_video_bitmap **dst, - int dst_width, int dst_height, - struct grub_video_bitmap *src, - enum grub_video_bitmap_scale_method - scale_method, - grub_video_bitmap_selection_method_t - selection_method, - grub_video_bitmap_v_align_t v_align, - grub_video_bitmap_h_align_t h_align); - - #endif /* ! GRUB_BITMAP_SCALE_HEADER */ diff --git a/grub-core/lib/dummy/reboot.c b/include/grub/boot.h similarity index 69% rename from grub-core/lib/dummy/reboot.c rename to include/grub/boot.h index b8cbed8f8..235774863 100644 --- a/grub-core/lib/dummy/reboot.c +++ b/include/grub/boot.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. + * 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 @@ -16,17 +16,12 @@ * along with GRUB. If not, see . */ -#include -#include -#include -#include +#ifndef GRUB_BOOT_HEADER +#define GRUB_BOOT_HEADER 1 -void -grub_reboot (void) -{ - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); +#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) - /* Just stop here */ - - while (1); -} +#endif /* ! GRUB_BOOT_HEADER */ diff --git a/include/grub/bsdlabel.h b/include/grub/bsdlabel.h deleted file mode 100644 index 83e7b8b5a..000000000 --- a/include/grub/bsdlabel.h +++ /dev/null @@ -1,106 +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 . - */ - -#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. */ -enum - { - GRUB_PC_PARTITION_BSD_TYPE_UNUSED = 0, - GRUB_PC_PARTITION_BSD_TYPE_SWAP = 1, - GRUB_PC_PARTITION_BSD_TYPE_V6 = 2, - GRUB_PC_PARTITION_BSD_TYPE_V7 = 3, - GRUB_PC_PARTITION_BSD_TYPE_SYSV = 4, - GRUB_PC_PARTITION_BSD_TYPE_V71K = 5, - GRUB_PC_PARTITION_BSD_TYPE_V8 = 6, - GRUB_PC_PARTITION_BSD_TYPE_BSDFFS = 7, - GRUB_PC_PARTITION_BSD_TYPE_MSDOS = 8, - GRUB_PC_PARTITION_BSD_TYPE_BSDLFS = 9, - GRUB_PC_PARTITION_BSD_TYPE_OTHER = 10, - GRUB_PC_PARTITION_BSD_TYPE_HPFS = 11, - GRUB_PC_PARTITION_BSD_TYPE_ISO9660 = 12, - GRUB_PC_PARTITION_BSD_TYPE_BOOT = 13 - }; - -/* FreeBSD-specific types. */ -enum - { - GRUB_PC_PARTITION_FREEBSD_TYPE_VINUM = 14, - GRUB_PC_PARTITION_FREEBSD_TYPE_RAID = 15, - GRUB_PC_PARTITION_FREEBSD_TYPE_JFS2 = 21 - }; - -/* NetBSD-specific types. */ -enum - { - GRUB_PC_PARTITION_NETBSD_TYPE_ADOS = 14, - GRUB_PC_PARTITION_NETBSD_TYPE_HFS = 15, - GRUB_PC_PARTITION_NETBSD_TYPE_FILECORE = 16, - GRUB_PC_PARTITION_NETBSD_TYPE_EXT2FS = 17, - GRUB_PC_PARTITION_NETBSD_TYPE_NTFS = 18, - GRUB_PC_PARTITION_NETBSD_TYPE_RAID = 19, - GRUB_PC_PARTITION_NETBSD_TYPE_CCD = 20, - GRUB_PC_PARTITION_NETBSD_TYPE_JFS2 = 21, - GRUB_PC_PARTITION_NETBSD_TYPE_APPLEUFS = 22 - }; - -/* OpenBSD-specific types. */ -enum - { - GRUB_PC_PARTITION_OPENBSD_TYPE_ADOS = 14, - GRUB_PC_PARTITION_OPENBSD_TYPE_HFS = 15, - GRUB_PC_PARTITION_OPENBSD_TYPE_FILECORE = 16, - GRUB_PC_PARTITION_OPENBSD_TYPE_EXT2FS = 17, - GRUB_PC_PARTITION_OPENBSD_TYPE_NTFS = 18, - GRUB_PC_PARTITION_OPENBSD_TYPE_RAID = 19 - }; - -#define GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION 2 - -/* 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; -} GRUB_PACKED; - -/* The BSD disk label. Only define members useful for GRUB. */ -struct grub_partition_bsd_disk_label -{ - grub_uint32_t magic; - grub_uint16_t type; - grub_uint8_t unused1[18]; - grub_uint8_t packname[16]; - grub_uint8_t unused2[92]; - grub_uint32_t magic2; - grub_uint16_t checksum; - grub_uint16_t num_partitions; - grub_uint32_t boot_size; - grub_uint32_t superblock_size; -} GRUB_PACKED; - -#endif /* ! GRUB_PC_PARTITION_HEADER */ diff --git a/include/grub/btrfs.h b/include/grub/btrfs.h deleted file mode 100644 index 9d93fb6c1..000000000 --- a/include/grub/btrfs.h +++ /dev/null @@ -1,71 +0,0 @@ -/* btrfs.c - B-tree file system. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_BTRFS_H -#define GRUB_BTRFS_H 1 - -enum - { - GRUB_BTRFS_ITEM_TYPE_INODE_ITEM = 0x01, - GRUB_BTRFS_ITEM_TYPE_INODE_REF = 0x0c, - GRUB_BTRFS_ITEM_TYPE_DIR_ITEM = 0x54, - GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM = 0x6c, - GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM = 0x84, - GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF = 0x90, - GRUB_BTRFS_ITEM_TYPE_DEVICE = 0xd8, - GRUB_BTRFS_ITEM_TYPE_CHUNK = 0xe4 - }; - -enum - { - GRUB_BTRFS_ROOT_VOL_OBJECTID = 5, - GRUB_BTRFS_TREE_ROOT_OBJECTID = 0x100, - }; - -struct grub_btrfs_root_item -{ - grub_uint8_t dummy[0xb0]; - grub_uint64_t tree; - grub_uint64_t inode; -}; - -struct grub_btrfs_key -{ - grub_uint64_t object_id; - grub_uint8_t type; - grub_uint64_t offset; -} GRUB_PACKED; - - -struct grub_btrfs_root_backref -{ - grub_uint64_t inode_id; - grub_uint64_t seqnr; - grub_uint16_t n; - char name[0]; -}; - -struct grub_btrfs_inode_ref -{ - grub_uint64_t idxid; - grub_uint16_t n; - char name[0]; -}; - -#endif diff --git a/include/grub/buffer.h b/include/grub/buffer.h deleted file mode 100644 index bb5e3cd92..000000000 --- a/include/grub/buffer.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2021 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_BUFFER_H -#define GRUB_BUFFER_H 1 - -#include -#include -#include -#include -#include - -struct grub_buffer -{ - grub_uint8_t *data; - grub_size_t sz; - grub_size_t pos; - grub_size_t used; -}; - -/* - * grub_buffer_t represents a simple variable sized byte buffer with - * read and write cursors. It currently only implements - * functionality required by the only user in GRUB (append byte[s], - * peeking data at a specified position and updating the read cursor. - * Some things that this doesn't do yet are: - * - Reading a portion of the buffer by copying data from the current - * read position in to a caller supplied destination buffer and then - * automatically updating the read cursor. - * - Dropping the read part at the start of the buffer when an append - * requires more space. - */ -typedef struct grub_buffer *grub_buffer_t; - -/* Allocate a new buffer with the specified initial size. */ -extern grub_buffer_t grub_buffer_new (grub_size_t sz); - -/* Free the buffer and its resources. */ -extern void grub_buffer_free (grub_buffer_t buf); - -/* Return the number of unread bytes in this buffer. */ -static inline grub_size_t -grub_buffer_get_unread_bytes (grub_buffer_t buf) -{ - return buf->used - buf->pos; -} - -/* - * Ensure that the buffer size is at least the requested - * number of bytes. - */ -extern grub_err_t grub_buffer_ensure_space (grub_buffer_t buf, grub_size_t req); - -/* - * Append the specified number of bytes from the supplied - * data to the buffer. - */ -static inline grub_err_t -grub_buffer_append_data (grub_buffer_t buf, const void *data, grub_size_t len) -{ - grub_size_t req; - - if (grub_add (buf->used, len, &req)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); - - if (grub_buffer_ensure_space (buf, req) != GRUB_ERR_NONE) - return grub_errno; - - grub_memcpy (&buf->data[buf->used], data, len); - buf->used = req; - - return GRUB_ERR_NONE; -} - -/* Append the supplied character to the buffer. */ -static inline grub_err_t -grub_buffer_append_char (grub_buffer_t buf, char c) -{ - return grub_buffer_append_data (buf, &c, 1); -} - -/* - * Forget and return the underlying data buffer. The caller - * becomes the owner of this buffer, and must free it when it - * is no longer required. - */ -extern void *grub_buffer_take_data (grub_buffer_t buf); - -/* Reset this buffer. Note that this does not deallocate any resources. */ -void grub_buffer_reset (grub_buffer_t buf); - -/* - * Return a pointer to the underlying data buffer at the specified - * offset from the current read position. Note that this pointer may - * become invalid if the buffer is mutated further. - */ -static inline void * -grub_buffer_peek_data_at (grub_buffer_t buf, grub_size_t off) -{ - if (grub_add (buf->pos, off, &off)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); - return NULL; - } - - if (off >= buf->used) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("peek out of range")); - return NULL; - } - - return &buf->data[off]; -} - -/* - * Return a pointer to the underlying data buffer at the current - * read position. Note that this pointer may become invalid if the - * buffer is mutated further. - */ -static inline void * -grub_buffer_peek_data (grub_buffer_t buf) -{ - return grub_buffer_peek_data_at (buf, 0); -} - -/* Advance the read position by the specified number of bytes. */ -extern grub_err_t grub_buffer_advance_read_pos (grub_buffer_t buf, grub_size_t n); - -#endif /* GRUB_BUFFER_H */ diff --git a/include/grub/bufio.h b/include/grub/bufio.h index 0ff72d103..acdd0c882 100644 --- a/include/grub/bufio.h +++ b/include/grub/bufio.h @@ -22,9 +22,7 @@ #include -grub_file_t EXPORT_FUNC (grub_bufio_open) (grub_file_t io, grub_size_t size); -grub_file_t EXPORT_FUNC (grub_buffile_open) (const char *name, - enum grub_file_type type, - grub_size_t size); +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 index 7aa8d7933..27e44f0a2 100644 --- a/include/grub/cache.h +++ b/include/grub/cache.h @@ -33,24 +33,4 @@ grub_arch_sync_caches (void *address __attribute__ ((unused)), void EXPORT_FUNC(grub_arch_sync_caches) (void *address, grub_size_t len); #endif -#ifndef GRUB_MACHINE_EMU -#if defined (__aarch64__) || defined (__ia64__) || defined (__powerpc__) || \ - defined (__sparc__) - -#elif defined (__i386__) || defined (__x86_64__) -static inline void -grub_arch_sync_dma_caches (volatile void *address __attribute__ ((unused)), - grub_size_t len __attribute__ ((unused))) -{ -} -#else -void EXPORT_FUNC(grub_arch_sync_dma_caches) (volatile void *address, grub_size_t len); -#endif -#endif - -#ifdef __arm__ -void -grub_arm_cache_enable (void); -#endif - #endif /* ! GRUB_CACHE_HEADER */ diff --git a/include/grub/cbfs_core.h b/include/grub/cbfs_core.h deleted file mode 100644 index 98112fb67..000000000 --- a/include/grub/cbfs_core.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008 Jordan Crouse - * Copyright (C) 2012 Google, Inc. - * Copyright (C) 2013 The Chromium OS Authors. All rights reserved. - * - * This file is dual-licensed. You can choose between: - * - The GNU GPL, version 2, as published by the Free Software Foundation - * - The revised BSD license (without advertising clause) - * - * --------------------------------------------------------------------------- - * 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; version 2 of the License. - * - * 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 St, Fifth Floor, Boston, MA, 02110-1301 USA - * --------------------------------------------------------------------------- - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 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. - * --------------------------------------------------------------------------- - */ - -#ifndef _CBFS_CORE_H_ -#define _CBFS_CORE_H_ - -#include - -/** These are standard values for the known compression - alogrithms that coreboot knows about for stages and - payloads. Of course, other CBFS users can use whatever - values they want, as long as they understand them. */ - -#define CBFS_COMPRESS_NONE 0 -#define CBFS_COMPRESS_LZMA 1 - -/** These are standard component types for well known - components (i.e - those that coreboot needs to consume. - Users are welcome to use any other value for their - components */ - -#define CBFS_TYPE_STAGE 0x10 -#define CBFS_TYPE_PAYLOAD 0x20 -#define CBFS_TYPE_OPTIONROM 0x30 -#define CBFS_TYPE_BOOTSPLASH 0x40 -#define CBFS_TYPE_RAW 0x50 -#define CBFS_TYPE_VSA 0x51 -#define CBFS_TYPE_MBI 0x52 -#define CBFS_TYPE_MICROCODE 0x53 -#define CBFS_COMPONENT_CMOS_DEFAULT 0xaa -#define CBFS_COMPONENT_CMOS_LAYOUT 0x01aa - -#define CBFS_HEADER_MAGIC 0x4F524243 -#define CBFS_HEADER_VERSION1 0x31313131 -#define CBFS_HEADER_VERSION2 0x31313132 -#define CBFS_HEADER_VERSION CBFS_HEADER_VERSION2 - -#define CBFS_HEADER_INVALID_ADDRESS ((void*)(0xffffffff)) - -/** this is the master cbfs header - it need to be located somewhere available - to bootblock (to load romstage). Where it actually lives is up to coreboot. - On x86, a pointer to this header will live at 0xFFFFFFFC. - For other platforms, you need to define CONFIG_CBFS_HEADER_ROM_OFFSET */ - -struct cbfs_header { - grub_uint32_t magic; - grub_uint32_t version; - grub_uint32_t romsize; - grub_uint32_t bootblocksize; - grub_uint32_t align; - grub_uint32_t offset; - grub_uint32_t architecture; - grub_uint32_t pad[1]; -} GRUB_PACKED; - -/* "Unknown" refers to CBFS headers version 1, - * before the architecture was defined (i.e., x86 only). - */ -#define CBFS_ARCHITECTURE_UNKNOWN 0xFFFFFFFF -#define CBFS_ARCHITECTURE_X86 0x00000001 -#define CBFS_ARCHITECTURE_ARMV7 0x00000010 - -/** This is a component header - every entry in the CBFS - will have this header. - - This is how the component is arranged in the ROM: - - -------------- <- 0 - component header - -------------- <- sizeof(struct component) - component name - -------------- <- offset - data - ... - -------------- <- offset + len -*/ - -#define CBFS_FILE_MAGIC "LARCHIVE" - -struct cbfs_file { - char magic[8]; - grub_uint32_t len; - grub_uint32_t type; - grub_uint32_t checksum; - grub_uint32_t offset; -} GRUB_PACKED; - -/*** Component sub-headers ***/ - -/* Following are component sub-headers for the "standard" - component types */ - -/** This is the sub-header for stage components. Stages are - loaded by coreboot during the normal boot process */ - -struct cbfs_stage { - grub_uint32_t compression; /** Compression type */ - grub_uint64_t entry; /** entry point */ - grub_uint64_t load; /** Where to load in memory */ - grub_uint32_t len; /** length of data to load */ - grub_uint32_t memlen; /** total length of object in memory */ -} GRUB_PACKED; - -/** this is the sub-header for payload components. Payloads - are loaded by coreboot at the end of the boot process */ - -struct cbfs_payload_segment { - grub_uint32_t type; - grub_uint32_t compression; - grub_uint32_t offset; - grub_uint64_t load_addr; - grub_uint32_t len; - grub_uint32_t mem_len; -} GRUB_PACKED; - -struct cbfs_payload { - struct cbfs_payload_segment segments; -}; - -#define PAYLOAD_SEGMENT_CODE 0x45444F43 -#define PAYLOAD_SEGMENT_DATA 0x41544144 -#define PAYLOAD_SEGMENT_BSS 0x20535342 -#define PAYLOAD_SEGMENT_PARAMS 0x41524150 -#define PAYLOAD_SEGMENT_ENTRY 0x52544E45 - -struct cbfs_optionrom { - grub_uint32_t compression; - grub_uint32_t len; -} GRUB_PACKED; - -#endif diff --git a/include/grub/charset.h b/include/grub/charset.h index df79aae53..fc050da24 100644 --- a/include/grub/charset.h +++ b/include/grub/charset.h @@ -36,169 +36,20 @@ #define GRUB_UINT8_5_TRAILINGBITS 0x1f #define GRUB_UINT8_6_TRAILINGBITS 0x3f -#define GRUB_MAX_UTF8_PER_UTF16 4 -/* You need at least one UTF-8 byte to have one UTF-16 word. - You need at least three UTF-8 bytes to have 2 UTF-16 words (surrogate pairs). - */ -#define GRUB_MAX_UTF16_PER_UTF8 1 -#define GRUB_MAX_UTF8_PER_CODEPOINT 4 - #define GRUB_UCS2_LIMIT 0x10000 #define GRUB_UTF16_UPPER_SURROGATE(code) \ - (0xD800 | ((((code) - GRUB_UCS2_LIMIT) >> 10) & 0x3ff)) + (0xD800 + ((((code) - GRUB_UCS2_LIMIT) >> 12) & 0xfff)) #define GRUB_UTF16_LOWER_SURROGATE(code) \ - (0xDC00 | (((code) - GRUB_UCS2_LIMIT) & 0x3ff)) + (0xDC00 + (((code) - GRUB_UCS2_LIMIT) & 0xfff)) -/* Process one character from UTF8 sequence. - At beginning set *code = 0, *count = 0. Returns 0 on failure and - 1 on success. *count holds the number of trailing bytes. */ -static inline int -grub_utf8_process (grub_uint8_t c, grub_uint32_t *code, int *count) -{ - if (*count) - { - if ((c & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT) - { - *count = 0; - /* invalid */ - return 0; - } - else - { - *code <<= 6; - *code |= (c & GRUB_UINT8_6_TRAILINGBITS); - (*count)--; - /* Overlong. */ - if ((*count == 1 && *code <= 0x1f) - || (*count == 2 && *code <= 0xf)) - { - *code = 0; - *count = 0; - return 0; - } - return 1; - } - } - - if ((c & GRUB_UINT8_1_LEADINGBIT) == 0) - { - *code = c; - return 1; - } - if ((c & GRUB_UINT8_3_LEADINGBITS) == GRUB_UINT8_2_LEADINGBITS) - { - *count = 1; - *code = c & GRUB_UINT8_5_TRAILINGBITS; - /* Overlong */ - if (*code <= 1) - { - *count = 0; - *code = 0; - return 0; - } - return 1; - } - if ((c & GRUB_UINT8_4_LEADINGBITS) == GRUB_UINT8_3_LEADINGBITS) - { - *count = 2; - *code = c & GRUB_UINT8_4_TRAILINGBITS; - return 1; - } - if ((c & GRUB_UINT8_5_LEADINGBITS) == GRUB_UINT8_4_LEADINGBITS) - { - *count = 3; - *code = c & GRUB_UINT8_3_TRAILINGBITS; - return 1; - } - return 0; -} - - -/* 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, it is - replaced by a question mark ('?'). - If SRCEND is not NULL, then *SRCEND is set to the next byte after the - last byte used in SRC. */ -static inline grub_size_t +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) - { - int was_count = count; - if (srcsize != (grub_size_t)-1) - srcsize--; - if (!grub_utf8_process (*src++, &code, &count)) - { - code = '?'; - count = 0; - /* Character c may be valid, don't eat it. */ - if (was_count) - src--; - } - if (count != 0) - continue; - if (code == 0) - break; - 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; -} - -/* Determine the last position where the UTF-8 string [beg, end) can - be safely cut. */ -static inline grub_size_t -grub_getend (const char *beg, const char *end) -{ - const char *ptr; - for (ptr = end - 1; ptr >= beg; ptr--) - if ((*ptr & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT) - break; - if (ptr < beg) - return 0; - if ((*ptr & GRUB_UINT8_1_LEADINGBIT) == 0) - return ptr + 1 - beg; - if ((*ptr & GRUB_UINT8_3_LEADINGBITS) == GRUB_UINT8_2_LEADINGBITS - && ptr + 2 <= end) - return ptr + 2 - beg; - if ((*ptr & GRUB_UINT8_4_LEADINGBITS) == GRUB_UINT8_3_LEADINGBITS - && ptr + 3 <= end) - return ptr + 3 - beg; - if ((*ptr & GRUB_UINT8_5_LEADINGBITS) == GRUB_UINT8_4_LEADINGBITS - && ptr + 4 <= end) - return ptr + 4 - beg; - /* Invalid character or incomplete. Cut before it. */ - return ptr - beg; -} + const grub_uint8_t **srcend); /* Convert UTF-16 to UTF-8. */ static inline grub_uint8_t * -grub_utf16_to_utf8 (grub_uint8_t *dest, const grub_uint16_t *src, +grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src, grub_size_t size) { grub_uint32_t code_high = 0; @@ -212,7 +63,7 @@ grub_utf16_to_utf8 (grub_uint8_t *dest, const grub_uint16_t *src, if (code >= 0xDC00 && code <= 0xDFFF) { /* Surrogate pair. */ - code = ((code_high - 0xD800) << 10) + (code - 0xDC00) + 0x10000; + code = ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000; *dest++ = (code >> 18) | 0xF0; *dest++ = ((code >> 12) & 0x3F) | 0x80; @@ -223,8 +74,6 @@ grub_utf16_to_utf8 (grub_uint8_t *dest, const grub_uint16_t *src, { /* Error... */ *dest++ = '?'; - /* *src may be valid. Don't eat it. */ - src--; } code_high = 0; @@ -248,77 +97,25 @@ grub_utf16_to_utf8 (grub_uint8_t *dest, const grub_uint16_t *src, /* Error... */ *dest++ = '?'; } - else if (code < 0x10000) + else { *dest++ = (code >> 12) | 0xE0; *dest++ = ((code >> 6) & 0x3F) | 0x80; *dest++ = (code & 0x3F) | 0x80; } - else - { - *dest++ = (code >> 18) | 0xF0; - *dest++ = ((code >> 12) & 0x3F) | 0x80; - *dest++ = ((code >> 6) & 0x3F) | 0x80; - *dest++ = (code & 0x3F) | 0x80; - } } } return dest; } -#define GRUB_MAX_UTF8_PER_LATIN1 2 - -/* Convert Latin1 to UTF-8. */ -static inline grub_uint8_t * -grub_latin1_to_utf8 (grub_uint8_t *dest, const grub_uint8_t *src, - grub_size_t size) -{ - while (size--) - { - if (!(*src & 0x80)) - *dest++ = *src; - else - { - *dest++ = (*src >> 6) | 0xC0; - *dest++ = (*src & 0x3F) | 0x80; - } - src++; - } - - return dest; -} - /* Convert UCS-4 to UTF-8. */ -char *grub_ucs4_to_utf8_alloc (const grub_uint32_t *src, grub_size_t size); +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); -grub_ssize_t grub_utf8_to_ucs4_alloc (const char *msg, - grub_uint32_t **unicode_msg, - grub_uint32_t **last_position); - -/* Returns the number of bytes the string src would occupy is converted - to UTF-8, excluding \0. */ -grub_size_t -grub_get_num_of_utf8_bytes (const grub_uint32_t *src, grub_size_t size); - -/* Converts UCS-4 to UTF-8. Returns the number of bytes effectively written - excluding the trailing \0. */ -grub_size_t -grub_ucs4_to_utf8 (const grub_uint32_t *src, grub_size_t size, - grub_uint8_t *dest, grub_size_t destsize); -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); -/* Returns -2 if not enough space, -1 on invalid character. */ -grub_ssize_t -grub_encode_utf8_character (grub_uint8_t *dest, grub_uint8_t *destend, - grub_uint32_t code); - -const grub_uint32_t * -grub_unicode_get_comb_start (const grub_uint32_t *str, - const grub_uint32_t *cur); +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 index 56ccc71a9..f508e3bf6 100644 --- a/include/grub/cmos.h +++ b/include/grub/cmos.h @@ -20,10 +20,8 @@ #define GRUB_CMOS_H 1 #include -#if !defined (__powerpc__) && !defined (__sparc__) #include #include -#endif #define GRUB_CMOS_INDEX_SECOND 0 #define GRUB_CMOS_INDEX_SECOND_ALARM 1 @@ -57,72 +55,18 @@ grub_num_to_bcd (grub_uint8_t a) return (((a / 10) << 4) + (a % 10)); } -#if !defined (__powerpc__) && !defined (__sparc__) -static inline grub_err_t -grub_cmos_read (grub_uint8_t index, grub_uint8_t *val) +static inline grub_uint8_t +grub_cmos_read (grub_uint8_t index) { - if (index & 0x80) - { - grub_outb (index & 0x7f, GRUB_CMOS_ADDR_REG_HI); - *val = grub_inb (GRUB_CMOS_DATA_REG_HI); - } - else - { - grub_outb (index & 0x7f, GRUB_CMOS_ADDR_REG); - *val = grub_inb (GRUB_CMOS_DATA_REG); - } - return GRUB_ERR_NONE; + grub_outb (index, GRUB_CMOS_ADDR_REG); + return grub_inb (GRUB_CMOS_DATA_REG); } -static inline grub_err_t +static inline void grub_cmos_write (grub_uint8_t index, grub_uint8_t value) { - if (index & 0x80) - { - grub_outb (index & 0x7f, GRUB_CMOS_ADDR_REG_HI); - grub_outb (value, GRUB_CMOS_DATA_REG_HI); - } - else - { - grub_outb (index & 0x7f, GRUB_CMOS_ADDR_REG); - grub_outb (value, GRUB_CMOS_DATA_REG); - } - return GRUB_ERR_NONE; + grub_outb (index, GRUB_CMOS_ADDR_REG); + grub_outb (value, GRUB_CMOS_DATA_REG); } -#else -grub_err_t grub_cmos_find_port (void); -extern volatile grub_uint8_t *grub_cmos_port; - -static inline grub_err_t -grub_cmos_read (grub_uint8_t index, grub_uint8_t *val) -{ - if (!grub_cmos_port) - { - grub_err_t err; - err = grub_cmos_find_port (); - if (err) - return err; - } - grub_cmos_port[((index & 0x80) >> 6) | 0] = index & 0x7f; - *val = grub_cmos_port[((index & 0x80) >> 6) | 1]; - return GRUB_ERR_NONE; -} - -static inline grub_err_t -grub_cmos_write (grub_uint8_t index, grub_uint8_t val) -{ - if (!grub_cmos_port) - { - grub_err_t err; - err = grub_cmos_find_port (); - if (err) - return err; - } - grub_cmos_port[((index & 0x80) >> 6) | 0] = index; - grub_cmos_port[((index & 0x80) >> 6) | 1] = val; - return GRUB_ERR_NONE; -} - -#endif #endif /* GRUB_CMOS_H */ diff --git a/include/grub/color.h b/include/grub/color.h deleted file mode 100644 index cb004a9a1..000000000 --- a/include/grub/color.h +++ /dev/null @@ -1,30 +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 . - */ - -#ifndef GRUB_VIDEO_COLOR_HEADER -#define GRUB_VIDEO_COLOR_HEADER 1 - -#include - -int grub_video_get_named_color (const char *name, - grub_video_rgba_color_t *color); - -grub_err_t grub_video_parse_color (const char *s, - grub_video_rgba_color_t *color); - -#endif diff --git a/include/grub/command.h b/include/grub/command.h index 2a6f7f846..6e9942b60 100644 --- a/include/grub/command.h +++ b/include/grub/command.h @@ -22,38 +22,32 @@ #include #include #include -#include -typedef enum grub_command_flags - { - /* This is an extended command. */ - GRUB_COMMAND_FLAG_EXTCMD = 0x10, - /* This is an dynamic command. */ - GRUB_COMMAND_FLAG_DYNCMD = 0x20, - /* This command accepts block arguments. */ - GRUB_COMMAND_FLAG_BLOCKS = 0x40, - /* This command accepts unknown arguments as direct parameters. */ - GRUB_COMMAND_ACCEPT_DASH = 0x80, - /* This command accepts only options preceding direct arguments. */ - GRUB_COMMAND_OPTIONS_AT_START = 0x100, - /* Can be executed in an entries extractor. */ - GRUB_COMMAND_FLAG_EXTRACTOR = 0x200 - } grub_command_flags_t; +/* 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); -#define GRUB_COMMAND_PRIO_MASK 0xff -#define GRUB_COMMAND_FLAG_ACTIVE 0x100 - /* The command description. */ struct grub_command { /* The next element. */ struct grub_command *next; - struct grub_command **prev; /* The name. */ const char *name; @@ -65,7 +59,7 @@ struct grub_command grub_command_func_t func; /* The flags. */ - grub_command_flags_t flags; + unsigned flags; /* The summary of the command usage. */ const char *summary; @@ -86,11 +80,6 @@ EXPORT_FUNC(grub_register_command_prio) (const char *name, const char *summary, const char *description, int prio); -grub_command_t -EXPORT_FUNC(grub_register_command_lockdown) (const char *name, - grub_command_func_t func, - const char *summary, - const char *description); void EXPORT_FUNC(grub_unregister_command) (grub_command_t cmd); static inline grub_command_t @@ -126,8 +115,12 @@ grub_command_execute (const char *name, int argc, char **argv) return (cmd) ? cmd->func (cmd, argc, argv) : GRUB_ERR_FILE_NOT_FOUND; } -#define FOR_COMMANDS(var) FOR_LIST_ELEMENTS((var), grub_command_list) -#define FOR_COMMANDS_SAFE(var, next) FOR_LIST_ELEMENTS_SAFE((var), (next), grub_command_list) +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); diff --git a/include/grub/compiler-rt-emu.h b/include/grub/compiler-rt-emu.h deleted file mode 100644 index fde620ac1..000000000 --- a/include/grub/compiler-rt-emu.h +++ /dev/null @@ -1,265 +0,0 @@ -/* compiler-rt-emu.h - prototypes for compiler helpers. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010-2014 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_COMPILER_RT_HEADER -#define GRUB_COMPILER_RT_HEADER 1 - -#include -#include -#include - -#ifdef HAVE___UDIVSI3 -grub_uint32_t -EXPORT_FUNC (__udivsi3) (grub_uint32_t a, grub_uint32_t b); -#endif - -#ifdef HAVE___UMODSI3 -grub_uint32_t -EXPORT_FUNC (__umodsi3) (grub_uint32_t a, grub_uint32_t b); -#endif - -#ifdef HAVE___DIVSI3 -grub_int32_t -EXPORT_FUNC (__divsi3) (grub_int32_t a, grub_int32_t b); -#endif - -#ifdef HAVE___MODSI3 -grub_int32_t -EXPORT_FUNC (__modsi3) (grub_int32_t a, grub_int32_t b); -#endif - -#ifdef HAVE___DIVDI3 -grub_int64_t -EXPORT_FUNC (__divdi3) (grub_int64_t a, grub_int64_t b); -#endif - -#ifdef HAVE___MODDI3 -grub_int64_t -EXPORT_FUNC (__moddi3) (grub_int64_t a, grub_int64_t b); -#endif - -#ifdef HAVE___UDIVDI3 -grub_uint64_t -EXPORT_FUNC (__udivdi3) (grub_uint64_t a, grub_uint64_t b); -#endif - -#ifdef HAVE___UMODDI3 -grub_uint64_t -EXPORT_FUNC (__umoddi3) (grub_uint64_t a, grub_uint64_t b); -#endif - -#ifdef HAVE___CTZDI2 -unsigned -EXPORT_FUNC (__ctzdi2) (grub_uint64_t x); -#endif - -#ifdef HAVE___CTZSI2 -unsigned -EXPORT_FUNC (__ctzsi2) (grub_uint32_t x); -#endif - -#ifdef HAVE___CLZDI2 -int -EXPORT_FUNC (__clzdi2) (grub_uint64_t x); -#endif - -#ifdef HAVE___AEABI_UIDIV -grub_uint32_t -EXPORT_FUNC (__aeabi_uidiv) (grub_uint32_t a, grub_uint32_t b); -#endif - -#ifdef HAVE___AEABI_UIDIVMOD -grub_uint32_t -EXPORT_FUNC (__aeabi_uidivmod) (grub_uint32_t a, grub_uint32_t b); -#endif - -#ifdef HAVE___AEABI_IDIV -grub_int32_t -EXPORT_FUNC (__aeabi_idiv) (grub_int32_t a, grub_int32_t b); -#endif - -#ifdef HAVE___AEABI_IDIVMOD -grub_int32_t -EXPORT_FUNC (__aeabi_idivmod) (grub_int32_t a, grub_int32_t b); -#endif - -#ifdef HAVE___AEABI_ULCMP -int -EXPORT_FUNC (__aeabi_ulcmp) (grub_uint64_t a, grub_uint64_t b); -#endif - -/* Needed for allowing modules to be compiled as thumb. */ -#ifdef HAVE___MULDI3 -grub_uint64_t -EXPORT_FUNC (__muldi3) (grub_uint64_t a, grub_uint64_t b); -#endif - -#ifdef HAVE___AEABI_LMUL -grub_uint64_t -EXPORT_FUNC (__aeabi_lmul) (grub_uint64_t a, grub_uint64_t b); -#endif - -#ifdef HAVE___AEABI_MEMCPY -void * -EXPORT_FUNC (__aeabi_memcpy) (void *dest, const void *src, grub_size_t n); -#endif - -#ifdef HAVE___AEABI_MEMCPY4 -void * -EXPORT_FUNC (__aeabi_memcpy4) (void *dest, const void *src, grub_size_t n); -#endif - -#ifdef HAVE___AEABI_MEMCPY8 -void * -EXPORT_FUNC (__aeabi_memcpy8) (void *dest, const void *src, grub_size_t n); -#endif - -#ifdef HAVE___AEABI_MEMSET -void * -EXPORT_FUNC(__aeabi_memset) (void *s, int c, grub_size_t n); -#endif - -#ifdef HAVE___AEABI_MEMCLR -void * -EXPORT_FUNC(__aeabi_memclr) (void *s, grub_size_t n); -#endif - -#ifdef HAVE___AEABI_MEMCLR4 -void * -EXPORT_FUNC(__aeabi_memclr4) (void *s, grub_size_t n); -#endif - -#ifdef HAVE___AEABI_MEMCLR8 -void * -EXPORT_FUNC(__aeabi_memclr8) (void *s, grub_size_t n); -#endif - -#ifdef HAVE___AEABI_LASR -grub_uint64_t -EXPORT_FUNC (__aeabi_lasr) (grub_uint64_t u, int b); -#endif - -#ifdef HAVE___AEABI_LLSL -grub_uint64_t -EXPORT_FUNC (__aeabi_llsl) (grub_uint64_t u, int b); -#endif - -#ifdef HAVE___AEABI_LLSR -grub_uint64_t -EXPORT_FUNC (__aeabi_llsr) (grub_uint64_t u, int b); -#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 - -#ifdef HAVE___UCMPDI2 -int -EXPORT_FUNC(__ucmpdi2) (grub_uint64_t a, grub_uint64_t b); -#endif - -#ifdef HAVE___ASHLDI3 -grub_uint64_t -EXPORT_FUNC(__ashldi3) (grub_uint64_t u, int b); -#endif - -#ifdef HAVE___ASHRDI3 -grub_uint64_t -EXPORT_FUNC(__ashrdi3) (grub_uint64_t u, int b); -#endif - -#ifdef HAVE___LSHRDI3 -grub_uint64_t -EXPORT_FUNC (__lshrdi3) (grub_uint64_t u, int b); -#endif - -#ifdef HAVE___BSWAPSI2 -grub_uint32_t -EXPORT_FUNC(__bswapsi2) (grub_uint32_t u); -#endif - -#ifdef HAVE___BSWAPDI2 -grub_uint64_t -EXPORT_FUNC(__bswapdi2) (grub_uint64_t u); -#endif - -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); - -#ifdef HAVE___BZERO -void EXPORT_FUNC (__bzero) (void *s, grub_size_t n); -#endif - -#ifdef HAVE___REGISTER_FRAME_INFO -void EXPORT_FUNC (__register_frame_info) (void); -#endif - -#ifdef HAVE___DEREGISTER_FRAME_INFO -void EXPORT_FUNC (__deregister_frame_info) (void); -#endif -#ifdef HAVE____CHKSTK_MS -void EXPORT_FUNC (___chkstk_ms) (void); -#endif - -#ifdef HAVE___CHKSTK_MS -void EXPORT_FUNC (__chkstk_ms) (void); -#endif - -#endif - diff --git a/include/grub/compiler-rt.h b/include/grub/compiler-rt.h deleted file mode 100644 index 17828b322..000000000 --- a/include/grub/compiler-rt.h +++ /dev/null @@ -1,213 +0,0 @@ -/* compiler-rt.h - prototypes for compiler helpers. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010-2014 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_COMPILER_RT_HEADER -#define GRUB_COMPILER_RT_HEADER 1 - -#include -#include -#include -#include - -#if defined(GRUB_DIVISION_IN_SOFTWARE) && GRUB_DIVISION_IN_SOFTWARE - -grub_uint32_t -EXPORT_FUNC (__udivsi3) (grub_uint32_t a, grub_uint32_t b); - -grub_uint32_t -EXPORT_FUNC (__umodsi3) (grub_uint32_t a, grub_uint32_t b); - -grub_int32_t -EXPORT_FUNC (__divsi3) (grub_int32_t a, grub_int32_t b); - -grub_int32_t -EXPORT_FUNC (__modsi3) (grub_int32_t a, grub_int32_t b); - -grub_int64_t -EXPORT_FUNC (__divdi3) (grub_int64_t a, grub_int64_t b); - -grub_int64_t -EXPORT_FUNC (__moddi3) (grub_int64_t a, grub_int64_t b); - -grub_uint64_t -EXPORT_FUNC (__udivdi3) (grub_uint64_t a, grub_uint64_t b); - -grub_uint64_t -EXPORT_FUNC (__umoddi3) (grub_uint64_t a, grub_uint64_t b); - -#endif - -#if defined (__sparc__) || defined (__powerpc__) || defined (__mips__) || \ - defined (__arm__) || defined(__riscv) -unsigned -EXPORT_FUNC (__ctzdi2) (grub_uint64_t x); -#define NEED_CTZDI2 1 -#endif - -#if defined (__mips__) || defined (__arm__) || \ - (defined(__riscv) && (__riscv_xlen == 32)) -unsigned -EXPORT_FUNC (__ctzsi2) (grub_uint32_t x); -#define NEED_CTZSI2 1 -#endif - -#ifdef __arm__ -grub_uint32_t -EXPORT_FUNC (__aeabi_uidiv) (grub_uint32_t a, grub_uint32_t b); -grub_uint32_t -EXPORT_FUNC (__aeabi_uidivmod) (grub_uint32_t a, grub_uint32_t b); - -grub_int32_t -EXPORT_FUNC (__aeabi_idiv) (grub_int32_t a, grub_int32_t b); -grub_int32_t -EXPORT_FUNC (__aeabi_idivmod) (grub_int32_t a, grub_int32_t b); - -int -EXPORT_FUNC (__aeabi_ulcmp) (grub_uint64_t a, grub_uint64_t b); - -/* Needed for allowing modules to be compiled as thumb. */ -grub_uint64_t -EXPORT_FUNC (__muldi3) (grub_uint64_t a, grub_uint64_t b); -grub_uint64_t -EXPORT_FUNC (__aeabi_lmul) (grub_uint64_t a, grub_uint64_t b); - -void * -EXPORT_FUNC (__aeabi_memcpy) (void *dest, const void *src, grub_size_t n); -void * -EXPORT_FUNC (__aeabi_memcpy4) (void *dest, const void *src, grub_size_t n); -void * -EXPORT_FUNC (__aeabi_memcpy8) (void *dest, const void *src, grub_size_t n); -void * -EXPORT_FUNC(__aeabi_memset) (void *s, int c, grub_size_t n); -void EXPORT_FUNC(__aeabi_memclr) (void *s, grub_size_t n); -void EXPORT_FUNC(__aeabi_memclr4) (void *s, grub_size_t n); -void EXPORT_FUNC(__aeabi_memclr8) (void *s, grub_size_t n); - -grub_uint64_t -EXPORT_FUNC (__aeabi_lasr) (grub_uint64_t u, int b); - -grub_uint64_t -EXPORT_FUNC (__aeabi_llsl) (grub_uint64_t u, int b); - -grub_uint64_t -EXPORT_FUNC (__aeabi_llsr) (grub_uint64_t u, int b); - -#endif - -#if defined(__mips__) || defined(__riscv) || defined(__sparc__) -int -EXPORT_FUNC (__clzsi2) (grub_uint32_t val); -#endif - -#if defined(__mips__) || defined(__riscv) || defined(__sparc__) -int -EXPORT_FUNC (__clzdi2) (grub_uint64_t val); -#endif - -#if defined (__powerpc__) - -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 - -#if defined (__powerpc__) || defined(__mips__) || defined (__arm__) || \ - (defined(__riscv) && (__riscv_xlen == 32)) - -int -EXPORT_FUNC(__ucmpdi2) (grub_uint64_t a, grub_uint64_t b); - -grub_uint64_t -EXPORT_FUNC(__ashldi3) (grub_uint64_t u, int b); - -grub_uint64_t -EXPORT_FUNC(__ashrdi3) (grub_uint64_t u, int b); - -grub_uint64_t -EXPORT_FUNC (__lshrdi3) (grub_uint64_t u, int b); -#endif - -#if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || \ - defined (__arm__) || defined(__riscv) -grub_uint32_t -EXPORT_FUNC(__bswapsi2) (grub_uint32_t u); - -grub_uint64_t -EXPORT_FUNC(__bswapdi2) (grub_uint64_t u); -#endif - -#if defined (__APPLE__) && defined(__i386__) -#define GRUB_BUILTIN_ATTR __attribute__ ((regparm(0))) -#else -#define GRUB_BUILTIN_ATTR -#endif - -/* Prototypes for aliases. */ -int GRUB_BUILTIN_ATTR EXPORT_FUNC(memcmp) (const void *s1, const void *s2, grub_size_t n); -void *GRUB_BUILTIN_ATTR EXPORT_FUNC(memmove) (void *dest, const void *src, grub_size_t n); -void *GRUB_BUILTIN_ATTR EXPORT_FUNC(memcpy) (void *dest, const void *src, grub_size_t n); -void *GRUB_BUILTIN_ATTR EXPORT_FUNC(memset) (void *s, int c, grub_size_t n); - -#ifdef __APPLE__ -void GRUB_BUILTIN_ATTR EXPORT_FUNC (__bzero) (void *s, grub_size_t n); -#endif - -#if defined (__MINGW32__) || defined (__CYGWIN__) -void EXPORT_FUNC (__register_frame_info) (void); -void EXPORT_FUNC (__deregister_frame_info) (void); -void EXPORT_FUNC (___chkstk_ms) (void); -void EXPORT_FUNC (__chkstk_ms) (void); -#endif - -#endif - diff --git a/include/grub/compiler.h b/include/grub/compiler.h deleted file mode 100644 index 0c5519387..000000000 --- a/include/grub/compiler.h +++ /dev/null @@ -1,59 +0,0 @@ -/* compiler.h - macros for various compiler features */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010,2014 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_COMPILER_HEADER -#define GRUB_COMPILER_HEADER 1 - -/* 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 GRUB_ATTRIBUTE_ERROR(msg) \ - __attribute__ ((__error__ (msg))) -#else -# define GRUB_ATTRIBUTE_ERROR(msg) __attribute__ ((noreturn)) -#endif - -#if GNUC_PREREQ(4,4) -# define GNU_PRINTF gnu_printf -#else -# define GNU_PRINTF printf -#endif - -#if GNUC_PREREQ(3,4) -# define WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) -#else -# define WARN_UNUSED_RESULT -#endif - -#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) -# define CLANG_PREREQ(maj,min) \ - ((__clang_major__ > (maj)) || \ - (__clang_major__ == (maj) && __clang_minor__ >= (min))) -#else -# define CLANG_PREREQ(maj,min) 0 -#endif - -#endif /* ! GRUB_COMPILER_HEADER */ diff --git a/include/grub/coreboot/lbio.h b/include/grub/coreboot/lbio.h deleted file mode 100644 index 5076d36c7..000000000 --- a/include/grub/coreboot/lbio.h +++ /dev/null @@ -1,114 +0,0 @@ -/* memory.h - describe the memory map */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,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 . - */ - -#ifndef _GRUB_MACHINE_LBIO_HEADER -#define _GRUB_MACHINE_LBIO_HEADER 1 - -#include -#include - -struct grub_linuxbios_table_header -{ - grub_uint8_t signature[4]; - grub_uint32_t header_size; - grub_uint32_t header_checksum; - grub_uint32_t table_size; - grub_uint32_t table_checksum; - grub_uint32_t table_entries; -}; -typedef struct grub_linuxbios_table_header *grub_linuxbios_table_header_t; - -struct grub_linuxbios_timestamp_entry -{ - grub_uint32_t id; - grub_uint64_t tsc; -} GRUB_PACKED; - -struct grub_linuxbios_timestamp_table -{ - grub_uint64_t base_tsc; - grub_uint32_t capacity; - grub_uint32_t used; - struct grub_linuxbios_timestamp_entry entries[0]; -} GRUB_PACKED; - -struct grub_linuxbios_mainboard -{ - grub_uint8_t vendor; - grub_uint8_t part_number; - char strings[0]; -}; - -struct grub_linuxbios_table_item -{ - grub_uint32_t tag; - grub_uint32_t size; -}; -typedef struct grub_linuxbios_table_item *grub_linuxbios_table_item_t; - -enum - { - GRUB_LINUXBIOS_MEMBER_UNUSED = 0x00, - GRUB_LINUXBIOS_MEMBER_MEMORY = 0x01, - GRUB_LINUXBIOS_MEMBER_MAINBOARD = 0x03, - GRUB_LINUXBIOS_MEMBER_CONSOLE = 0x10, - GRUB_LINUXBIOS_MEMBER_LINK = 0x11, - GRUB_LINUXBIOS_MEMBER_FRAMEBUFFER = 0x12, - GRUB_LINUXBIOS_MEMBER_TIMESTAMPS = 0x16, - GRUB_LINUXBIOS_MEMBER_CBMEMC = 0x17 - }; - -struct grub_linuxbios_table_framebuffer { - grub_uint64_t lfb; - grub_uint32_t width; - grub_uint32_t height; - grub_uint32_t pitch; - grub_uint8_t bpp; - - grub_uint8_t red_field_pos; - grub_uint8_t red_mask_size; - grub_uint8_t green_field_pos; - grub_uint8_t green_mask_size; - grub_uint8_t blue_field_pos; - grub_uint8_t blue_mask_size; - grub_uint8_t reserved_field_pos; - grub_uint8_t reserved_mask_size; -} GRUB_PACKED; - -struct grub_linuxbios_mem_region -{ - grub_uint64_t addr; - grub_uint64_t size; -#define GRUB_MACHINE_MEMORY_AVAILABLE 1 - grub_uint32_t type; -} GRUB_PACKED; -typedef struct grub_linuxbios_mem_region *mem_region_t; - -grub_err_t -EXPORT_FUNC(grub_linuxbios_table_iterate) (int (*hook) (grub_linuxbios_table_item_t, - void *), - void *hook_data); - -grub_linuxbios_table_header_t -grub_linuxbios_get_tables (void); - -int -grub_linuxbios_check_signature (grub_linuxbios_table_header_t tbl_header); - -#endif diff --git a/include/grub/crypto.h b/include/grub/crypto.h index 31c87c302..48b52ee65 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -26,9 +26,8 @@ #include #include #include -#include -typedef enum +typedef enum { GPG_ERR_NO_ERROR, GPG_ERR_BAD_MPI, @@ -56,6 +55,7 @@ typedef enum 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, @@ -63,16 +63,12 @@ typedef enum GPG_ERR_WEAK_KEY, GPG_ERR_WRONG_KEY_USAGE, GPG_ERR_WRONG_PUBKEY_ALGO, - GPG_ERR_OUT_OF_MEMORY, - GPG_ERR_TOO_LARGE, - GPG_ERR_ENOMEM - } gpg_err_code_t; -typedef gpg_err_code_t gpg_error_t; -typedef gpg_error_t gcry_error_t; -typedef gpg_err_code_t gcry_err_code_t; -#define gcry_error_t gcry_err_code_t -#if 0 -enum gcry_cipher_modes + 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. */ @@ -82,12 +78,6 @@ enum gcry_cipher_modes GCRY_CIPHER_MODE_OFB = 5, /* Outer feedback. */ GCRY_CIPHER_MODE_CTR = 6 /* Counter. */ }; -#endif - -/* Don't rely on this. Check! */ -#define GRUB_CRYPTO_MAX_MDLEN 64 -#define GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE 16 -#define GRUB_CRYPTO_MAX_MD_CONTEXT_SIZE 256 /* Type for the cipher_setkey function. */ typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c, @@ -136,9 +126,6 @@ typedef struct gcry_cipher_spec gcry_cipher_decrypt_t decrypt; gcry_cipher_stencrypt_t stencrypt; gcry_cipher_stdecrypt_t stdecrypt; -#ifdef GRUB_UTIL - const char *modname; -#endif struct gcry_cipher_spec *next; } gcry_cipher_spec_t; @@ -174,80 +161,9 @@ typedef struct gcry_md_spec grub_size_t contextsize; /* allocate this amount of context */ /* Block size, needed for HMAC. */ grub_size_t blocksize; -#ifdef GRUB_UTIL - const char *modname; -#endif struct gcry_md_spec *next; } gcry_md_spec_t; -struct gcry_mpi; -typedef struct gcry_mpi *gcry_mpi_t; - -/* Type for the pk_generate function. */ -typedef gcry_err_code_t (*gcry_pk_generate_t) (int algo, - unsigned int nbits, - unsigned long use_e, - gcry_mpi_t *skey, - gcry_mpi_t **retfactors); - -/* Type for the pk_check_secret_key function. */ -typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo, - gcry_mpi_t *skey); - -/* Type for the pk_encrypt function. */ -typedef gcry_err_code_t (*gcry_pk_encrypt_t) (int algo, - gcry_mpi_t *resarr, - gcry_mpi_t data, - gcry_mpi_t *pkey, - int flags); - -/* Type for the pk_decrypt function. */ -typedef gcry_err_code_t (*gcry_pk_decrypt_t) (int algo, - gcry_mpi_t *result, - gcry_mpi_t *data, - gcry_mpi_t *skey, - int flags); - -/* Type for the pk_sign function. */ -typedef gcry_err_code_t (*gcry_pk_sign_t) (int algo, - gcry_mpi_t *resarr, - gcry_mpi_t data, - gcry_mpi_t *skey); - -/* Type for the pk_verify function. */ -typedef gcry_err_code_t (*gcry_pk_verify_t) (int algo, - gcry_mpi_t hash, - gcry_mpi_t *data, - gcry_mpi_t *pkey, - int (*cmp) (void *, gcry_mpi_t), - void *opaquev); - -/* Type for the pk_get_nbits function. */ -typedef unsigned (*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey); - -/* Module specification structure for message digests. */ -typedef struct gcry_pk_spec -{ - const char *name; - const char **aliases; - const char *elements_pkey; - const char *elements_skey; - const char *elements_enc; - const char *elements_sig; - const char *elements_grip; - int use; - gcry_pk_generate_t generate; - gcry_pk_check_secret_key_t check_secret_key; - gcry_pk_encrypt_t encrypt; - gcry_pk_decrypt_t decrypt; - gcry_pk_sign_t sign; - gcry_pk_verify_t verify; - gcry_pk_get_nbits_t get_nbits; -#ifdef GRUB_UTIL - const char *modname; -#endif -} gcry_pk_spec_t; - struct grub_crypto_cipher_handle { const struct gcry_cipher_spec *cipher; @@ -269,77 +185,35 @@ grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher, const unsigned char *key, unsigned keylen); -static inline void -grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher) -{ - grub_free (cipher); -} +void +grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher); -static inline 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 && (((grub_addr_t) in1ptr & (sizeof (grub_uint64_t) - 1)) - || ((grub_addr_t) in2ptr & (sizeof (grub_uint64_t) - 1)) - || ((grub_addr_t) outptr & (sizeof (grub_uint64_t) - 1)))) - { - *outptr = *in1ptr ^ *in2ptr; - in1ptr++; - in2ptr++; - outptr++; - size--; - } - while (size >= sizeof (grub_uint64_t)) - { - /* We've already checked that all pointers are aligned. */ - *(grub_uint64_t *) (void *) outptr - = (*(const grub_uint64_t *) (const void *) in1ptr - ^ *(const grub_uint64_t *) (const void *) in2ptr); - in1ptr += sizeof (grub_uint64_t); - in2ptr += sizeof (grub_uint64_t); - outptr += sizeof (grub_uint64_t); - size -= sizeof (grub_uint64_t); - } - while (size) - { - *outptr = *in1ptr ^ *in2ptr; - in1ptr++; - in2ptr++; - outptr++; - size--; - } -} +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, const void *in, grub_size_t size); + void *out, void *in, grub_size_t size); gcry_err_code_t grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher, - void *out, const void *in, grub_size_t size); + void *out, void *in, grub_size_t size); gcry_err_code_t grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher, - void *out, const void *in, grub_size_t size, + 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, const void *in, grub_size_t size, + void *out, void *in, grub_size_t size, void *iv); -void +void grub_cipher_register (gcry_cipher_spec_t *cipher); void grub_cipher_unregister (gcry_cipher_spec_t *cipher); -void +void grub_md_register (gcry_md_spec_t *digest); -void +void grub_md_unregister (gcry_md_spec_t *cipher); - -extern struct gcry_pk_spec *grub_crypto_pk_dsa; -extern struct gcry_pk_spec *grub_crypto_pk_ecdsa; -extern struct gcry_pk_spec *grub_crypto_pk_ecdh; -extern struct gcry_pk_spec *grub_crypto_pk_rsa; - void grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in, grub_size_t inlen); @@ -355,8 +229,7 @@ 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, - const void *data, +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); @@ -364,20 +237,16 @@ 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, - const void *data, grub_size_t datalen, void *out); + 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; -extern gcry_md_spec_t _gcry_digest_spec_crc32; -extern gcry_cipher_spec_t _gcry_cipher_spec_aes; #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) -#define GRUB_MD_CRC32 ((const gcry_md_spec_t *) &_gcry_digest_spec_crc32) -#define GRUB_CIPHER_AES ((const gcry_cipher_spec_t *) &_gcry_cipher_spec_aes) /* 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, @@ -399,24 +268,8 @@ int grub_password_get (char buf[], unsigned buf_size); /* For indistinguishibility. */ -#define GRUB_ACCESS_DENIED grub_error (GRUB_ERR_ACCESS_DENIED, N_("access denied")) +#define GRUB_ACCESS_DENIED grub_error (GRUB_ERR_ACCESS_DENIED, "Access denied.") extern void (*grub_crypto_autoload_hook) (const char *name); -void _gcry_assert_failed (const char *expr, const char *file, int line, - const char *func) __attribute__ ((noreturn)); - -void _gcry_burn_stack (int bytes); -void _gcry_log_error( const char *fmt, ... ) __attribute__ ((format (__printf__, 1, 2))); - - -#ifdef GRUB_UTIL -void grub_gcry_init_all (void); -void grub_gcry_fini_all (void); - -int -grub_get_random (void *out, grub_size_t len); - -#endif - #endif diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h deleted file mode 100644 index 81e631778..000000000 --- a/include/grub/cryptodisk.h +++ /dev/null @@ -1,210 +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 . - */ - -#ifndef GRUB_CRYPTODISK_HEADER -#define GRUB_CRYPTODISK_HEADER 1 - -#include -#include -#include -#include -#ifdef GRUB_UTIL -#include -#endif - -typedef enum - { - GRUB_CRYPTODISK_MODE_ECB, - GRUB_CRYPTODISK_MODE_CBC, - GRUB_CRYPTODISK_MODE_PCBC, - GRUB_CRYPTODISK_MODE_XTS, - GRUB_CRYPTODISK_MODE_LRW - } grub_cryptodisk_mode_t; - -typedef enum - { - GRUB_CRYPTODISK_MODE_IV_NULL, - GRUB_CRYPTODISK_MODE_IV_PLAIN, - GRUB_CRYPTODISK_MODE_IV_PLAIN64, - GRUB_CRYPTODISK_MODE_IV_ESSIV, - GRUB_CRYPTODISK_MODE_IV_BENBI, - GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64, - GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH - } grub_cryptodisk_mode_iv_t; - -#define GRUB_CRYPTODISK_MAX_UUID_LENGTH 71 - -/* LUKS1 specification defines the block size to always be 512 bytes. */ -#define GRUB_LUKS1_LOG_SECTOR_SIZE 9 - -/* By default dm-crypt increments the IV every 512 bytes. */ -#define GRUB_CRYPTODISK_IV_LOG_SIZE 9 - -#define GRUB_CRYPTODISK_GF_LOG_SIZE 7 -#define GRUB_CRYPTODISK_GF_SIZE (1U << GRUB_CRYPTODISK_GF_LOG_SIZE) -#define GRUB_CRYPTODISK_GF_LOG_BYTES (GRUB_CRYPTODISK_GF_LOG_SIZE - 3) -#define GRUB_CRYPTODISK_GF_BYTES (1U << GRUB_CRYPTODISK_GF_LOG_BYTES) -#define GRUB_CRYPTODISK_MAX_KEYLEN 128 -#define GRUB_CRYPTODISK_MAX_PASSPHRASE 256 - -#define GRUB_CRYPTODISK_MAX_KEYFILE_SIZE 8192 - -struct grub_cryptodisk; - -typedef gcry_err_code_t -(*grub_cryptodisk_rekey_func_t) (struct grub_cryptodisk *dev, - grub_uint64_t zoneno); - -struct grub_cryptomount_cached_key -{ - grub_uint8_t *key; - grub_size_t key_len; - - /* - * The key protector associated with this cache entry failed, so avoid it - * even if the cached entry (an instance of this structure) is empty. - */ - bool invalid; -}; - -struct grub_cryptomount_args -{ - /* scan: Flag to indicate that only bootable volumes should be decrypted */ - grub_uint32_t check_boot : 1; - /* scan: Only volumes matching this UUID should be decrpyted */ - char *search_uuid; - /* recover_key: Key data used to decrypt voume */ - grub_uint8_t *key_data; - /* recover_key: Length of key_data */ - grub_size_t key_len; - grub_file_t hdr_file; - /* recover_key: Names of the key protectors to use (NULL-terminated) */ - char **protectors; - /* recover_key: Key cache to avoid invoking the same key protector twice */ - struct grub_cryptomount_cached_key *key_cache; -}; -typedef struct grub_cryptomount_args *grub_cryptomount_args_t; - -struct grub_cryptodisk -{ - struct grub_cryptodisk *next; - struct grub_cryptodisk **prev; - - char *source; - /* - * The number of sectors the start of the encrypted data is offset into the - * underlying disk, where sectors are the size noted by log_sector_size. - */ - grub_disk_addr_t offset_sectors; - /* Total number of encrypted sectors of size (1 << log_sector_size). */ - grub_disk_addr_t total_sectors; - grub_disk_t source_disk; - int ref; - grub_crypto_cipher_handle_t cipher; - grub_crypto_cipher_handle_t secondary_cipher; - grub_crypto_cipher_handle_t essiv_cipher; - const gcry_md_spec_t *essiv_hash, *hash, *iv_hash; - grub_cryptodisk_mode_t mode; - grub_cryptodisk_mode_iv_t mode_iv; - int benbi_log; - unsigned long id, source_id; - enum grub_disk_dev_id source_dev_id; - char uuid[GRUB_CRYPTODISK_MAX_UUID_LENGTH + 1]; - grub_uint8_t lrw_key[GRUB_CRYPTODISK_GF_BYTES]; - grub_uint8_t *lrw_precalc; - grub_uint8_t iv_prefix[64]; - grub_size_t iv_prefix_len; - grub_uint8_t key[GRUB_CRYPTODISK_MAX_KEYLEN]; - grub_size_t keysize; -#ifdef GRUB_UTIL - char *cheat; - grub_util_fd_t cheat_fd; -#endif - const char *modname; - int log_sector_size; - grub_cryptodisk_rekey_func_t rekey; - int rekey_shift; - grub_uint8_t rekey_key[64]; - grub_uint64_t last_rekey; - int rekey_derived_size; - grub_disk_addr_t partition_start; -}; -typedef struct grub_cryptodisk *grub_cryptodisk_t; - -struct grub_cryptodisk_dev -{ - struct grub_cryptodisk_dev *next; - struct grub_cryptodisk_dev **prev; - - grub_cryptodisk_t (*scan) (grub_disk_t disk, grub_cryptomount_args_t cargs); - grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs); -}; -typedef struct grub_cryptodisk_dev *grub_cryptodisk_dev_t; - -extern grub_cryptodisk_dev_t EXPORT_VAR (grub_cryptodisk_list); - -#ifndef GRUB_LST_GENERATOR -static inline void -grub_cryptodisk_dev_register (grub_cryptodisk_dev_t cr) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_cryptodisk_list), GRUB_AS_LIST (cr)); -} -#endif - -static inline void -grub_cryptodisk_dev_unregister (grub_cryptodisk_dev_t cr) -{ - grub_list_remove (GRUB_AS_LIST (cr)); -} - -#define FOR_CRYPTODISK_DEVS(var) FOR_LIST_ELEMENTS((var), (grub_cryptodisk_list)) - -grub_err_t -grub_cryptodisk_setcipher (grub_cryptodisk_t crypt, const char *ciphername, const char *ciphermode); - -gcry_err_code_t -grub_cryptodisk_setkey (grub_cryptodisk_t dev, - grub_uint8_t *key, grub_size_t keysize); -gcry_err_code_t -grub_cryptodisk_decrypt (struct grub_cryptodisk *dev, - grub_uint8_t * data, grub_size_t len, - grub_disk_addr_t sector, grub_size_t log_sector_size); -grub_err_t -grub_cryptodisk_insert (grub_cryptodisk_t newdev, const char *name, - grub_disk_t source); -#ifdef GRUB_UTIL -grub_err_t -grub_cryptodisk_cheat_insert (grub_cryptodisk_t newdev, const char *name, - grub_disk_t source, const char *cheat); -void -grub_util_cryptodisk_get_abstraction (grub_disk_t disk, - void (*cb) (const char *val, void *data), - void *data); - -char * -grub_util_get_geli_uuid (const char *dev); -#endif - -grub_cryptodisk_t grub_cryptodisk_get_by_uuid (const char *uuid); -grub_cryptodisk_t grub_cryptodisk_get_by_source_disk (grub_disk_t disk); - -#ifdef GRUB_MACHINE_EFI -grub_err_t grub_cryptodisk_challenge_password (void); -void grub_cryptodisk_erasesecrets (void); -#endif -#endif diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h deleted file mode 100644 index 6b5b424c8..000000000 --- a/include/grub/cs5536.h +++ /dev/null @@ -1,198 +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 . - */ - -#ifndef GRUB_CS5536_HEADER -#define GRUB_CS5536_HEADER 1 - -#ifndef ASM_FILE -#include -#include -#include -#endif - -#define GRUB_CS5536_PCIID 0x208f1022 -#define GRUB_CS5536_MSR_MAILBOX_CONFIG_ENABLED 0x1 -#define GRUB_CS5536_MSR_MAILBOX_CONFIG 0xf0 -#define GRUB_CS5536_MSR_MAILBOX_ADDR 0xf4 -#define GRUB_CS5536_MSR_MAILBOX_DATA0 0xf8 -#define GRUB_CS5536_MSR_MAILBOX_DATA1 0xfc -#define GRUB_CS5536_MSR_IRQ_MAP_BAR 0x80000008 -#define GRUB_CS5536_MSR_SMB_BAR 0x8000000b - -#define GRUB_CS5536_SMBUS_REGS_SIZE 8 -#define GRUB_CS5536_GPIO_REGS_SIZE 256 -#define GRUB_CS5536_MFGPT_REGS_SIZE 64 -#define GRUB_CS5536_IRQ_MAP_REGS_SIZE 32 -#define GRUB_CS5536_PM_REGS_SIZE 128 -#define GRUB_CS5536_ACPI_REGS_SIZE 32 - -#define GRUB_CS5536_USB_OPTION_REGS_SIZE 0x1c -#define GRUB_CS5536_USB_OPTION_REG_UOCMUX 1 -#define GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_MASK 0x03 -#define GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_HC 0x02 - -#define GRUB_CS5536_DESTINATION_GLIU 0 -#define GRUB_CS5536_DESTINATION_GLPCI_SB 1 -#define GRUB_CS5536_DESTINATION_USB 2 -#define GRUB_CS5536_DESTINATION_IDE 3 -#define GRUB_CS5536_DESTINATION_DD 4 -#define GRUB_CS5536_DESTINATION_ACC 5 -#define GRUB_CS5536_DESTINATION_GLCP 7 - -#define GRUB_CS5536_P2D_DEST_SHIFT 61 -#define GRUB_CS5536_P2D_LOG_ALIGN 12 -#define GRUB_CS5536_P2D_ALIGN (1 << GRUB_CS5536_P2D_LOG_ALIGN) -#define GRUB_CS5536_P2D_BASE_SHIFT 20 -#define GRUB_CS5536_P2D_MASK_SHIFT 0 - -#define GRUB_CS5536_MSR_GL_IOD_START 0x000100e0 -#define GRUB_CS5536_IOD_DEST_SHIFT 61 -#define GRUB_CS5536_IOD_BASE_SHIFT 20 -#define GRUB_CS5536_IOD_MASK_SHIFT 0 -#define GRUB_CS5536_IOD_ADDR_MASK 0xfffff - -#define GRUB_CS5536_MSR_GPIO_BAR 0x8000000c -#define GRUB_CS5536_MSR_MFGPT_BAR 0x8000000d -#define GRUB_CS5536_MSR_ACPI_BAR 0x8000000e -#define GRUB_CS5536_MSR_PM_BAR 0x8000000f -#define GRUB_CS5536_MSR_DIVIL_LEG_IO 0x80000014 -#define GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 0x00000001 -#define GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1 0x00000002 -#define GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 0x10000000 -#define GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP 0x04000000 -#define GRUB_CS5536_MSR_DIVIL_LEG_IO_UART1_COM1 0x00070000 -#define GRUB_CS5536_MSR_DIVIL_LEG_IO_UART2_COM3 0x00500000 -#define GRUB_CS5536_MSR_DIVIL_RESET 0x80000017 -#define GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK 0x80000024 -#define GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK 0x80000025 -#define GRUB_CS5536_DIVIL_LPC_INTERRUPTS 0x1002 -#define GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL 0x8000004e -#define GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL_ENABLE 0x80 -#define GRUB_CS5536_MSR_DIVIL_UART1_CONF 0x8000003a -#define GRUB_CS5536_MSR_DIVIL_UART2_CONF 0x8000003e - -#define GRUB_CS5536_MSR_USB_OHCI_BASE 0x40000008 -#define GRUB_CS5536_MSR_USB_EHCI_BASE 0x40000009 -#define GRUB_CS5536_MSR_USB_CONTROLLER_BASE 0x4000000a -#define GRUB_CS5536_MSR_USB_OPTION_CONTROLLER_BASE 0x4000000b -#define GRUB_CS5536_MSR_USB_BASE_ADDR_MASK 0x00ffffff00ULL -#define GRUB_CS5536_MSR_USB_BASE_SMI_ENABLE 0x3f000000000000ULL -#define GRUB_CS5536_MSR_USB_BASE_BUS_MASTER 0x0400000000ULL -#define GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE 0x0200000000ULL -#define GRUB_CS5536_MSR_USB_BASE_PME_ENABLED 0x0800000000ULL -#define GRUB_CS5536_MSR_USB_BASE_PME_STATUS 0x1000000000ULL -#define GRUB_CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT 40 - -#define GRUB_CS5536_MSR_IDE_IO_BAR 0x60000008 -#define GRUB_CS5536_MSR_IDE_IO_BAR_UNITS 1 -#define GRUB_CS5536_MSR_IDE_IO_BAR_ADDR_MASK 0xfffffff0 -#define GRUB_CS5536_MSR_IDE_CFG 0x60000010 -#define GRUB_CS5536_MSR_IDE_CFG_CHANNEL_ENABLE 2 -#define GRUB_CS5536_MSR_IDE_TIMING 0x60000012 -#define GRUB_CS5536_MSR_IDE_TIMING_PIO0 0x98 -#define GRUB_CS5536_MSR_IDE_TIMING_DRIVE0_SHIFT 24 -#define GRUB_CS5536_MSR_IDE_TIMING_DRIVE1_SHIFT 16 -#define GRUB_CS5536_MSR_IDE_CAS_TIMING 0x60000013 -#define GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_PIO0 0x99 -#define GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_SHIFT 24 -#define GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE0_SHIFT 6 -#define GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE1_SHIFT 4 -#define GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 2 - -#define GRUB_CS5536_MSR_GL_PCI_CTRL 0x00000010 -#define GRUB_CS5536_MSR_GL_PCI_CTRL_MEMORY_ENABLE 1 -#define GRUB_CS5536_MSR_GL_PCI_CTRL_IO_ENABLE 2 -#define GRUB_CS5536_MSR_GL_PCI_CTRL_LATENCY_SHIFT 35 -#define GRUB_CS5536_MSR_GL_PCI_CTRL_OUT_THR_SHIFT 60 -#define GRUB_CS5536_MSR_GL_PCI_CTRL_IN_THR_SHIFT 56 - -#define GRUB_CS5536_MSR_GL_REGIONS_START 0x00000020 -#define GRUB_CS5536_MSR_GL_REGIONS_NUM 16 -#define GRUB_CS5536_MSR_GL_REGION_ENABLE 1 -#define GRUB_CS5536_MSR_GL_REGION_IO 0x100000000ULL -#define GRUB_CS5536_MSR_GL_REGION_BASE_MASK 0xfffff000ULL -#define GRUB_CS5536_MSR_GL_REGION_IO_BASE_SHIFT 12 -#define GRUB_CS5536_MSR_GL_REGION_TOP_MASK 0xfffff00000000000ULL -#define GRUB_CS5536_MSR_GL_REGION_IO_TOP_SHIFT 44 - -#define GRUB_CS5536_MSR_GL_P2D_START 0x00010020 - -#define GRUB_CS5536_SMB_REG_DATA 0x0 -#define GRUB_CS5536_SMB_REG_STATUS 0x1 -#define GRUB_CS5536_SMB_REG_STATUS_SDAST (1 << 6) -#define GRUB_CS5536_SMB_REG_STATUS_BER (1 << 5) -#define GRUB_CS5536_SMB_REG_STATUS_NACK (1 << 4) -#define GRUB_CS5536_SMB_REG_CTRL1 0x3 -#define GRUB_CS5536_SMB_REG_CTRL1_START 0x01 -#define GRUB_CS5536_SMB_REG_CTRL1_STOP 0x02 -#define GRUB_CS5536_SMB_REG_CTRL1_ACK 0x10 -#define GRUB_CS5536_SMB_REG_ADDR 0x4 -#define GRUB_CS5536_SMB_REG_ADDR_MASTER 0x0 -#define GRUB_CS5536_SMB_REG_CTRL2 0x5 -#define GRUB_CS5536_SMB_REG_CTRL2_ENABLE 0x1 -#define GRUB_CS5536_SMB_REG_CTRL3 0x6 - -#ifdef ASM_FILE -#define GRUB_ULL(x) x -#else -#define GRUB_ULL(x) x ## ULL -#endif - -#define GRUB_CS5536_LBAR_ADDR_MASK GRUB_ULL (0x000000000000fff8) -#define GRUB_CS5536_LBAR_ENABLE GRUB_ULL (0x0000000100000000) -#define GRUB_CS5536_LBAR_MASK_MASK GRUB_ULL (0x0000f00000000000) -#define GRUB_CS5536_LBAR_TURN_ON (GRUB_CS5536_LBAR_ENABLE | GRUB_CS5536_LBAR_MASK_MASK) - -/* PMON-compatible LBARs. */ -#define GRUB_CS5536_LBAR_GPIO 0xb000 -#define GRUB_CS5536_LBAR_ACC 0xb200 -#define GRUB_CS5536_LBAR_PM 0xb280 -#define GRUB_CS5536_LBAR_MFGPT 0xb300 -#define GRUB_CS5536_LBAR_ACPI 0xb340 -#define GRUB_CS5536_LBAR_IRQ_MAP 0xb360 -#define GRUB_CS5536_LBAR_IDE 0xb380 -#define GRUB_CS5536_LBAR_SMBUS 0xb390 - -#define GRUB_GPIO_SMBUS_PINS ((1 << 14) | (1 << 15)) -#define GRUB_GPIO_REG_OUT_EN 0x4 -#define GRUB_GPIO_REG_OUT_AUX1 0x10 -#define GRUB_GPIO_REG_IN_EN 0x20 -#define GRUB_GPIO_REG_IN_AUX1 0x34 - -#ifndef ASM_FILE -int EXPORT_FUNC (grub_cs5536_find) (grub_pci_device_t *devp); - -grub_uint64_t EXPORT_FUNC (grub_cs5536_read_msr) (grub_pci_device_t dev, - grub_uint32_t addr); -void EXPORT_FUNC (grub_cs5536_write_msr) (grub_pci_device_t dev, - grub_uint32_t addr, - grub_uint64_t val); -grub_err_t grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev, - grub_uint8_t addr, grub_uint8_t *res); -grub_err_t EXPORT_FUNC (grub_cs5536_read_spd) (grub_port_t smbbase, - grub_uint8_t dev, - struct grub_smbus_spd *res); -grub_err_t grub_cs5536_smbus_wait (grub_port_t smbbase); -grub_err_t EXPORT_FUNC (grub_cs5536_init_smbus) (grub_pci_device_t dev, - grub_uint16_t divisor, - grub_port_t *smbbase); - -void grub_cs5536_init_geode (grub_pci_device_t dev); -#endif - -#endif diff --git a/include/grub/datetime.h b/include/grub/datetime.h index bcec636f0..2dbba55e2 100644 --- a/include/grub/datetime.h +++ b/include/grub/datetime.h @@ -33,101 +33,16 @@ struct grub_datetime }; /* 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); -const char *grub_get_weekday_name (struct grub_datetime *datetime); +char *grub_get_weekday_name (struct grub_datetime *datetime); -void grub_unixtime2datetime (grub_int64_t nix, +void grub_unixtime2datetime (grub_int32_t nix, struct grub_datetime *datetime); -static inline int -grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int64_t *nix) -{ - grub_int32_t ret; - int y4, ay; - const grub_uint16_t monthssum[12] - = { 0, - 31, - 31 + 28, - 31 + 28 + 31, - 31 + 28 + 31 + 30, - 31 + 28 + 31 + 30 + 31, - 31 + 28 + 31 + 30 + 31 + 30, - 31 + 28 + 31 + 30 + 31 + 30 + 31, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, - 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30}; - const grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30, - 31, 31, 30, 31, 30, 31}; - const int SECPERMIN = 60; - const int SECPERHOUR = 60 * SECPERMIN; - const int SECPERDAY = 24 * SECPERHOUR; - const int SECPERYEAR = 365 * SECPERDAY; - const int SECPER4YEARS = 4 * SECPERYEAR + SECPERDAY; - - if (datetime->year > 2038 || datetime->year < 1901) - return 0; - if (datetime->month > 12 || datetime->month < 1) - return 0; - - /* 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 */ - ret = 3 * SECPERYEAR + SECPERDAY; - - /* Transform C divisions and modulos to mathematical ones */ - y4 = ((datetime->year - 1) >> 2) - (1973 / 4); - ay = datetime->year - 1973 - 4 * y4; - ret += y4 * SECPER4YEARS; - ret += ay * SECPERYEAR; - - ret += monthssum[datetime->month - 1] * SECPERDAY; - if (ay == 3 && datetime->month >= 3) - ret += SECPERDAY; - - ret += (datetime->day - 1) * SECPERDAY; - if ((datetime->day > months[datetime->month - 1] - && (!ay || datetime->month != 2 || datetime->day != 29)) - || datetime->day < 1) - return 0; - - ret += datetime->hour * SECPERHOUR; - if (datetime->hour > 23) - return 0; - ret += datetime->minute * 60; - if (datetime->minute > 59) - return 0; - - ret += datetime->second; - /* Accept leap seconds. */ - if (datetime->second > 60) - return 0; - - if ((datetime->year > 1980 && ret < 0) - || (datetime->year < 1960 && ret > 0)) - return 0; - *nix = ret; - return 1; -} - -#if (defined (__powerpc__) || defined (__sparc__)) && !defined (GRUB_UTIL) -grub_err_t -grub_get_datetime_cmos (struct grub_datetime *datetime); -grub_err_t -grub_set_datetime_cmos (struct grub_datetime *datetime); -#endif #endif /* ! KERNEL_DATETIME_HEADER */ diff --git a/include/grub/decompressor.h b/include/grub/decompressor.h deleted file mode 100644 index a6eefb01b..000000000 --- a/include/grub/decompressor.h +++ /dev/null @@ -1,34 +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 . - */ - -#ifndef GRUB_DECOMPRESSOR_HEADER -#define GRUB_DECOMPRESSOR_HEADER 1 - -void -grub_decompress_core (void *src, void *dst, unsigned long srcsize, - unsigned long dstsize); - -void -find_scratch (void *src, void *dst, unsigned long srcsize, - unsigned long dstsize); - -#define GRUB_DECOMPRESSOR_DICT_SIZE (1 << 16) - -extern void *grub_decompressor_scratch; - -#endif diff --git a/include/grub/deflate.h b/include/grub/deflate.h deleted file mode 100644 index c87c62f6c..000000000 --- a/include/grub/deflate.h +++ /dev/null @@ -1,30 +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 . - */ - -#ifndef GRUB_DEFLATE_HEADER -#define GRUB_DEFLATE_HEADER 1 - -grub_ssize_t -grub_zlib_decompress (char *inbuf, grub_size_t insize, grub_off_t off, - char *outbuf, grub_size_t outsize); - -grub_ssize_t -grub_deflate_decompress (char *inbuf, grub_size_t insize, grub_off_t off, - char *outbuf, grub_size_t outsize); - -#endif diff --git a/include/grub/device.h b/include/grub/device.h index 1d1a23900..f0e8a8ca8 100644 --- a/include/grub/device.h +++ b/include/grub/device.h @@ -25,6 +25,7 @@ struct grub_disk; struct grub_net; +struct grub_fs; struct grub_device { @@ -33,11 +34,8 @@ struct grub_device }; typedef struct grub_device *grub_device_t; -typedef int (*grub_device_iterate_hook_t) (const char *name, void *data); - 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) (grub_device_iterate_hook_t hook, - void *hook_data); +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 index fbf23df7f..e60b1f3de 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -19,16 +19,10 @@ #ifndef GRUB_DISK_HEADER #define GRUB_DISK_HEADER 1 -#include - #include #include #include #include -/* For NULL. */ -#include -/* For ALIGN_UP. */ -#include /* These are used to set a device id. When you add a new disk device, you must define a new id for it here. */ @@ -38,20 +32,17 @@ enum grub_disk_dev_id GRUB_DISK_DEVICE_OFDISK_ID, GRUB_DISK_DEVICE_LOOPBACK_ID, GRUB_DISK_DEVICE_EFIDISK_ID, - GRUB_DISK_DEVICE_DISKFILTER_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_CRYPTODISK_ID, - GRUB_DISK_DEVICE_ARCDISK_ID, - GRUB_DISK_DEVICE_HOSTDISK_ID, - GRUB_DISK_DEVICE_PROCFS_ID, - GRUB_DISK_DEVICE_CBFSDISK_ID, - GRUB_DISK_DEVICE_UBOOTDISK_ID, - GRUB_DISK_DEVICE_XEN, - GRUB_DISK_DEVICE_OBDISK_ID, + GRUB_DISK_DEVICE_FILE_ID, + GRUB_DISK_DEVICE_LUKS_ID }; struct grub_disk; @@ -59,16 +50,6 @@ struct grub_disk; struct grub_disk_memberlist; #endif -typedef enum - { - GRUB_DISK_PULL_NONE, - GRUB_DISK_PULL_REMOVABLE, - GRUB_DISK_PULL_RESCAN, - GRUB_DISK_PULL_MAX - } grub_disk_pull_t; - -typedef int (*grub_disk_dev_iterate_hook_t) (const char *name, void *data); - /* Disk device. */ struct grub_disk_dev { @@ -79,26 +60,24 @@ struct grub_disk_dev enum grub_disk_dev_id id; /* Call HOOK with each device name, until HOOK returns non-zero. */ - int (*disk_iterate) (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull); + int (*iterate) (int (*hook) (const char *name)); /* Open the device named NAME, and set up DISK. */ - grub_err_t (*disk_open) (const char *name, struct grub_disk *disk); + grub_err_t (*open) (const char *name, struct grub_disk *disk); /* Close the disk DISK. */ - void (*disk_close) (struct grub_disk *disk); + void (*close) (struct grub_disk *disk); /* Read SIZE sectors from the sector SECTOR of the disk DISK into BUF. */ - grub_err_t (*disk_read) (struct grub_disk *disk, grub_disk_addr_t sector, + 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 (*disk_write) (struct grub_disk *disk, grub_disk_addr_t sector, + 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 *(*disk_memberlist) (struct grub_disk *disk); - const char * (*disk_raidname) (struct grub_disk *disk); + struct grub_disk_memberlist *(*memberlist) (struct grub_disk *disk); #endif /* The next disk device. */ @@ -106,14 +85,8 @@ struct grub_disk_dev }; typedef struct grub_disk_dev *grub_disk_dev_t; -extern grub_disk_dev_t EXPORT_VAR (grub_disk_dev_list); - struct grub_partition; -typedef grub_err_t (*grub_disk_read_hook_t) (grub_disk_addr_t sector, - unsigned offset, unsigned length, - char *buf, void *data); - /* Disk. */ struct grub_disk { @@ -126,11 +99,8 @@ struct grub_disk /* The total number of sectors. */ grub_uint64_t total_sectors; - /* Logarithm of sector size. */ - unsigned int log_sector_size; - - /* Maximum number of sectors read divided by GRUB_DISK_CACHE_SIZE. */ - unsigned int max_agglomerate; + /* If partitions can be stored. */ + int has_partitions; /* The id used by the disk cache manager. */ unsigned long id; @@ -140,10 +110,8 @@ struct grub_disk /* 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. */ - grub_disk_read_hook_t read_hook; - - /* Caller-specific data passed to the read hook. */ - void *read_hook_data; + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length); /* Device-specific data. */ void *data; @@ -163,90 +131,19 @@ typedef struct grub_disk_memberlist *grub_disk_memberlist_t; #define GRUB_DISK_SECTOR_SIZE 0x200 #define GRUB_DISK_SECTOR_BITS 9 -/* - * Some drivers have problems with disks above reasonable sizes. - * Set max disk size at 1 EiB. - */ -#define GRUB_DISK_MAX_SECTORS (1ULL << (60 - GRUB_DISK_SECTOR_BITS)) - /* The maximum number of disk caches. */ #define GRUB_DISK_CACHE_NUM 1021 -/* - * The maximum number of disks in an mdraid device. - * - * GET_DISK_INFO nr_disks (total count) does not map to disk.number, - * which is an internal kernel index. Instead, do what mdadm does - * and keep scanning until we find enough valid disks. The limit is - * copied from there, which notes that it is sufficiently high given - * that the on-disk metadata for v1.x can only support 1920. - */ -#define GRUB_MDRAID_MAX_DISKS 4096 - -/* The size of a disk cache in 512B units. Must be at least as big as the - largest supported sector size, currently 16K. */ -#define GRUB_DISK_CACHE_BITS 6 -#define GRUB_DISK_CACHE_SIZE (1 << GRUB_DISK_CACHE_BITS) - -#define GRUB_DISK_MAX_MAX_AGGLOMERATE ((1 << (30 - GRUB_DISK_CACHE_BITS - GRUB_DISK_SECTOR_BITS)) - 1) - -/* Maximum number of sectors to read in LBA mode at once. */ -#define GRUB_DISK_MAX_LBA_SECTORS 63 - -/* Return value of grub_disk_native_sectors() in case disk size is unknown. */ -#define GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL - -#define GRUB_DISK_KiB_TO_SECTORS(x) ((x) << (10 - GRUB_DISK_SECTOR_BITS)) - -/* Convert sector number from one sector size to another. */ -static inline grub_disk_addr_t -grub_convert_sector (grub_disk_addr_t sector, - grub_size_t log_sector_size_from, - grub_size_t log_sector_size_to) -{ - if (log_sector_size_from == log_sector_size_to) - return sector; - else if (log_sector_size_from < log_sector_size_to) - { - sector = ALIGN_UP (sector, 1 << (log_sector_size_to - log_sector_size_from)); - return sector >> (log_sector_size_to - log_sector_size_from); - } - else - return sector << (log_sector_size_from - log_sector_size_to); -} - -/* Convert to GRUB native disk sized sector from disk sized sector. */ -static inline grub_disk_addr_t -grub_disk_from_native_sector (grub_disk_t disk, grub_disk_addr_t sector) -{ - return sector << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); -} - -/* Convert from GRUB native disk sized sector to disk sized sector. */ -static inline grub_disk_addr_t -grub_disk_to_native_sector (grub_disk_t disk, grub_disk_addr_t sector) -{ - return sector >> (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); -} +/* 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); -static inline int -grub_disk_dev_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data) -{ - grub_disk_dev_t p; - grub_disk_pull_t pull; - - for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) - for (p = grub_disk_dev_list; p; p = p->next) - if (p->disk_iterate && (p->disk_iterate) (hook, hook_data, pull)) - return 1; - - return 0; -} +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); @@ -255,63 +152,26 @@ grub_err_t EXPORT_FUNC(grub_disk_read) (grub_disk_t disk, grub_off_t offset, grub_size_t size, void *buf); -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); -extern grub_err_t (*EXPORT_VAR(grub_disk_write_weak)) (grub_disk_t disk, - grub_disk_addr_t sector, - grub_off_t offset, - grub_size_t size, - const 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_native_sectors) (grub_disk_t disk); - -#if DISK_CACHE_STATS -void -EXPORT_FUNC(grub_disk_cache_get_performance) (unsigned long *hits, unsigned long *misses); -#endif +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); -static inline void -grub_stop_disk_firmware (void) +/* ATA pass through parameters and function. */ +struct grub_disk_ata_pass_through_parms { - /* 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; - } -} - -/* 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; + grub_uint8_t taskfile[8]; + void * buffer; + int size; }; -extern struct grub_disk_cache EXPORT_VAR(grub_disk_cache_table)[GRUB_DISK_CACHE_NUM]; - -#if defined (GRUB_UTIL) -void grub_lvm_init (void); -void grub_ldm_init (void); -void grub_mdraid09_init (void); -void grub_mdraid1x_init (void); -void grub_diskfilter_init (void); -void grub_lvm_fini (void); -void grub_ldm_fini (void); -void grub_mdraid09_fini (void); -void grub_mdraid1x_fini (void); -void grub_diskfilter_fini (void); -#endif +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/diskfilter.h b/include/grub/diskfilter.h deleted file mode 100644 index f020d025b..000000000 --- a/include/grub/diskfilter.h +++ /dev/null @@ -1,218 +0,0 @@ -/* diskfilter.h - On disk structures for RAID. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 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 . - */ - -#ifndef GRUB_DISKFILTER_H -#define GRUB_DISKFILTER_H 1 - -#include -#include - -enum - { - GRUB_RAID_LAYOUT_RIGHT_MASK = 1, - GRUB_RAID_LAYOUT_SYMMETRIC_MASK = 2, - GRUB_RAID_LAYOUT_MUL_FROM_POS = 4, - - GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC = 0, - GRUB_RAID_LAYOUT_RIGHT_ASYMMETRIC = GRUB_RAID_LAYOUT_RIGHT_MASK, - GRUB_RAID_LAYOUT_LEFT_SYMMETRIC = GRUB_RAID_LAYOUT_SYMMETRIC_MASK, - GRUB_RAID_LAYOUT_RIGHT_SYMMETRIC = (GRUB_RAID_LAYOUT_RIGHT_MASK - | GRUB_RAID_LAYOUT_SYMMETRIC_MASK) - }; - - -struct grub_diskfilter_vg { - char *uuid; - grub_size_t uuid_len; - /* Optional. */ - char *name; - grub_uint64_t extent_size; - struct grub_diskfilter_pv *pvs; - struct grub_diskfilter_lv *lvs; - struct grub_diskfilter_vg *next; - -#ifdef GRUB_UTIL - struct grub_diskfilter *driver; -#endif -}; - -struct grub_diskfilter_pv_id { - union - { - char *uuid; - int id; - }; - grub_size_t uuidlen; -}; - -struct grub_diskfilter_pv { - struct grub_diskfilter_pv_id id; - /* Optional. */ - char *name; - grub_disk_t disk; - grub_disk_addr_t part_start; - grub_disk_addr_t part_size; - grub_disk_addr_t start_sector; /* Sector number where the data area starts. */ - struct grub_diskfilter_pv *next; - /* Optional. */ - grub_uint8_t *internal_id; -#ifdef GRUB_UTIL - char **partmaps; -#endif -}; - -struct grub_diskfilter_lv { - /* Name used for disk. */ - char *fullname; - char *idname; - /* Optional. */ - char *name; - int number; - unsigned int segment_count; - grub_size_t segment_alloc; - grub_uint64_t size; - int became_readable_at; - int scanned; - int visible; - - /* Pointer to segment_count segments. */ - struct grub_diskfilter_segment *segments; - struct grub_diskfilter_vg *vg; - struct grub_diskfilter_lv *next; - - /* Optional. */ - char *internal_id; -}; - -struct grub_diskfilter_segment { - grub_uint64_t start_extent; - grub_uint64_t extent_count; - enum - { - GRUB_DISKFILTER_STRIPED = 0, - GRUB_DISKFILTER_MIRROR = 1, - GRUB_DISKFILTER_RAID4 = 4, - GRUB_DISKFILTER_RAID5 = 5, - GRUB_DISKFILTER_RAID6 = 6, - GRUB_DISKFILTER_RAID10 = 10, - } type; - int layout; - /* valid only for raid10. */ - grub_uint64_t raid_member_size; - - unsigned int node_count; - unsigned int node_alloc; - struct grub_diskfilter_node *nodes; - - unsigned int stripe_size; -}; - -struct grub_diskfilter_node { - grub_disk_addr_t start; - /* Optional. */ - char *name; - struct grub_diskfilter_pv *pv; - struct grub_diskfilter_lv *lv; -}; - -struct grub_diskfilter_vg * -grub_diskfilter_get_vg_by_uuid (grub_size_t uuidlen, char *uuid); - -struct grub_diskfilter -{ - struct grub_diskfilter *next; - struct grub_diskfilter **prev; - - const char *name; - - struct grub_diskfilter_vg * (*detect) (grub_disk_t disk, - struct grub_diskfilter_pv_id *id, - grub_disk_addr_t *start_sector); -}; -typedef struct grub_diskfilter *grub_diskfilter_t; - -extern grub_diskfilter_t grub_diskfilter_list; -static inline void -grub_diskfilter_register_front (grub_diskfilter_t diskfilter) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_diskfilter_list), - GRUB_AS_LIST (diskfilter)); -} - -static inline void -grub_diskfilter_register_back (grub_diskfilter_t diskfilter) -{ - grub_diskfilter_t p, *q; - for (q = &grub_diskfilter_list, p = *q; p; q = &p->next, p = *q); - diskfilter->next = NULL; - diskfilter->prev = q; - *q = diskfilter; -} -static inline void -grub_diskfilter_unregister (grub_diskfilter_t diskfilter) -{ - grub_list_remove (GRUB_AS_LIST (diskfilter)); -} - -struct grub_diskfilter_vg * -grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb, - const char *name, grub_uint64_t disk_size, - grub_uint64_t stripe_size, - int layout, int level); - -typedef grub_err_t (*grub_raid5_recover_func_t) (struct grub_diskfilter_segment *array, - int disknr, char *buf, - grub_disk_addr_t sector, - grub_size_t size); - -typedef grub_err_t (*grub_raid6_recover_func_t) (struct grub_diskfilter_segment *array, - int disknr, int p, char *buf, - grub_disk_addr_t sector, - grub_size_t size); - -extern grub_raid5_recover_func_t grub_raid5_recover_func; -extern grub_raid6_recover_func_t grub_raid6_recover_func; - -typedef grub_err_t (* raid_recover_read_t)(void *data, int disk_nr, - grub_uint64_t addr, void *dest, - grub_size_t size); - -extern grub_err_t -grub_raid6_recover_gen (void *data, grub_uint64_t nstripes, int disknr, int p, - char *buf, grub_uint64_t sector, grub_size_t size, - int layout, raid_recover_read_t read_func); - -grub_err_t grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg); - -grub_err_t -grub_diskfilter_read_node (const struct grub_diskfilter_node *node, - grub_disk_addr_t sector, - grub_size_t size, char *buf); - -#ifdef GRUB_UTIL -struct grub_diskfilter_pv * -grub_diskfilter_get_pv_from_disk (grub_disk_t disk, - struct grub_diskfilter_vg **vg); -void -grub_diskfilter_get_partmap (grub_disk_t disk, - void (*cb) (const char *val, void *data), - void *data); -#endif - -#endif /* ! GRUB_RAID_H */ diff --git a/include/grub/dl.h b/include/grub/dl.h index b8135c8f3..ac0ecd336 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -21,52 +21,9 @@ #define GRUB_DL_H 1 #include -#ifndef ASM_FILE #include #include #include -#include -#include -#endif - -/* - * 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 ASM_FILE - -#ifndef GRUB_MOD_INIT - -#if !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_KERNEL) - -#define GRUB_MOD_INIT(name) \ -static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ -static void \ -grub_mod_init (grub_dl_t mod __attribute__ ((unused))) - -#define GRUB_MOD_FINI(name) \ -static void grub_mod_fini (void) __attribute__ ((used)); \ -static void \ -grub_mod_fini (void) - -#elif defined (GRUB_KERNEL) - -#define GRUB_MOD_INIT(name) \ -static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ -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) { grub_mod_fini (); } \ -static void \ -grub_mod_fini (void) - -#else #define GRUB_MOD_INIT(name) \ static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ @@ -84,73 +41,19 @@ grub_##name##_fini (void) { grub_mod_fini (); } \ static void \ grub_mod_fini (void) -#endif - -#endif - -#endif - -#ifndef ASM_FILE -#ifdef __APPLE__ -#define GRUB_MOD_SECTION(x) "_" #x ", _" #x "" -#else -#define GRUB_MOD_SECTION(x) "." #x -#endif -#else -#ifdef __APPLE__ -#define GRUB_MOD_SECTION(x) _ ## x , _ ##x -#else -#define GRUB_MOD_SECTION(x) . ## x -#endif -#endif - -/* Me, Vladimir Serbinenko, hereby I add this module check as per new - GNU module policy. Note that this license check is informative only. - Modules have to be licensed under GPLv3 or GPLv3+ (optionally - multi-licensed under other licences as well) independently of the - presence of this check and solely by linking (module loading in GRUB - constitutes linking) and GRUB core being licensed under GPLv3+. - Be sure to understand your license obligations. -*/ -#ifndef ASM_FILE -#if GNUC_PREREQ (3,2) -#define ATTRIBUTE_USED __used__ -#else -#define ATTRIBUTE_USED __unused__ -#endif -#define GRUB_MOD_LICENSE(license) \ - static const char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), ATTRIBUTE_USED)) = "LICENSE=" license; -#define GRUB_MOD_DEP(name) \ -static const char grub_module_depend_##name[] \ - __attribute__((section(GRUB_MOD_SECTION(moddeps)), ATTRIBUTE_USED)) = #name +#ifdef APPLE_CC #define GRUB_MOD_NAME(name) \ -static const char grub_module_name_##name[] \ - __attribute__((section(GRUB_MOD_SECTION(modname)), __used__)) = #name -#else -#ifdef __APPLE__ -.macro GRUB_MOD_LICENSE - .section GRUB_MOD_SECTION(module_license) - .ascii "LICENSE=" - .ascii $0 - .byte 0 -.endm -#else -.macro GRUB_MOD_LICENSE license - .section GRUB_MOD_SECTION(module_license), "a" - .ascii "LICENSE=" - .ascii "\license" - .byte 0 -.endm -#endif -#endif +static char grub_modname[] __attribute__ ((section ("_modname, _modname"), used)) = #name; -/* Under GPL license obligations you have to distribute your module - under GPLv3(+). However, you can also distribute the same code under - another license as long as GPLv3(+) version is provided. -*/ -#define GRUB_MOD_DUAL_LICENSE(x) +#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") -#ifndef ASM_FILE +#define GRUB_MOD_DEP(name) \ +__asm__ (".section .moddeps\n.asciz \"" #name "\"\n") +#endif struct grub_dl_segment { @@ -170,161 +73,52 @@ struct grub_dl_dep }; typedef struct grub_dl_dep *grub_dl_dep_t; -#ifndef GRUB_UTIL struct grub_dl { char *name; - grub_uint64_t ref_count; - int persistent; + int ref_count; grub_dl_dep_t dep; grub_dl_segment_t segment; Elf_Sym *symtab; - grub_size_t symsize; void (*init) (struct grub_dl *mod); void (*fini) (void); -#if !defined (__i386__) && !defined (__x86_64__) - void *got; - void *gotptr; - void *tramp; - void *trampptr; -#endif -#ifdef __mips__ - grub_uint32_t *reginfo; -#endif - void *base; - grub_size_t sz; - struct grub_dl *next; }; -#endif typedef struct grub_dl *grub_dl_t; -grub_dl_t grub_dl_load_file (const char *filename); +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); -grub_dl_t EXPORT_FUNC(grub_dl_load_core_noinit) (void *addr, grub_size_t size); int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod); -extern grub_uint64_t EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); -extern grub_uint64_t EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); -extern grub_uint64_t EXPORT_FUNC(grub_dl_ref_count) (grub_dl_t mod); - -extern grub_dl_t EXPORT_VAR(grub_dl_head); - -#ifndef GRUB_UTIL - -#define FOR_DL_MODULES(var) FOR_LIST_ELEMENTS ((var), (grub_dl_head)) - -#ifdef GRUB_MACHINE_EMU -void * -grub_osdep_dl_memalign (grub_size_t align, grub_size_t size); -void -grub_dl_osdep_dl_free (void *ptr); -#endif - -static inline void -grub_dl_init (grub_dl_t mod) +void grub_dl_unload_unneeded (void); +void grub_dl_unload_all (void); +#ifdef GRUB_UTIL +static inline int +grub_dl_ref (grub_dl_t mod) { - if (mod->init) - (mod->init) (mod); - - mod->next = grub_dl_head; - grub_dl_head = mod; -} - -static inline grub_dl_t -grub_dl_get (const char *name) -{ - grub_dl_t l; - - FOR_DL_MODULES(l) - if (grub_strcmp (name, l->name) == 0) - return l; - + (void) mod; return 0; } - -#ifdef GRUB_MACHINE_EMU -/* - * Under grub-emu, modules are faked and NULL is passed to GRUB_MOD_INIT. - * So we fake this out to avoid a NULL deref. - */ -static inline void -grub_dl_set_persistent (grub_dl_t mod __attribute__((unused))) -{ -} - -/* - * Under grub-emu, modules are faked and NULL is passed to GRUB_MOD_INIT. - * So we fake this out to avoid a NULL deref. - */ static inline int -grub_dl_is_persistent (grub_dl_t mod __attribute__((unused))) +grub_dl_unref (grub_dl_t mod) { + (void) mod; + return 0; } #else -static inline void -grub_dl_set_persistent (grub_dl_t mod) -{ - mod->persistent = 1; -} - -static inline int -grub_dl_is_persistent (grub_dl_t mod) -{ - return mod->persistent; -} +int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); +int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); #endif -#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, - int isfunc, grub_dl_t mod); + grub_dl_t mod); grub_err_t grub_arch_dl_check_header (void *ehdr); -#ifndef GRUB_UTIL -grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - Elf_Shdr *s, grub_dl_segment_t seg); -#endif +grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); -#if defined (_mips) +#if defined (_mips) && ! defined (GRUB_UTIL) #define GRUB_LINKER_HAVE_INIT 1 void grub_arch_dl_init_linker (void); #endif -#define GRUB_IA64_DL_TRAMP_ALIGN 16 -#define GRUB_IA64_DL_GOT_ALIGN 16 - -grub_err_t -grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, - grub_size_t *got); -grub_err_t -grub_arm64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, - grub_size_t *got); - -#if defined (__ia64__) -#define GRUB_ARCH_DL_TRAMP_ALIGN GRUB_IA64_DL_TRAMP_ALIGN -#define GRUB_ARCH_DL_GOT_ALIGN GRUB_IA64_DL_GOT_ALIGN -#define grub_arch_dl_get_tramp_got_size grub_ia64_dl_get_tramp_got_size -#elif defined (__aarch64__) -#define grub_arch_dl_get_tramp_got_size grub_arm64_dl_get_tramp_got_size -#else -grub_err_t -grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, - grub_size_t *got); -#endif - -#if defined (__powerpc__) || defined (__mips__) || defined (__arm__) || \ - (defined(__riscv) && (__riscv_xlen == 32)) -#define GRUB_ARCH_DL_TRAMP_ALIGN 4 -#define GRUB_ARCH_DL_GOT_ALIGN 4 -#endif - -#if defined (__aarch64__) || defined (__sparc__) || \ - defined (__loongarch_lp64) || \ - (defined(__riscv) && (__riscv_xlen == 64)) -#define GRUB_ARCH_DL_TRAMP_ALIGN 8 -#define GRUB_ARCH_DL_GOT_ALIGN 8 -#endif - -#endif - #endif /* ! GRUB_DL_H */ diff --git a/include/grub/dma.h b/include/grub/dma.h deleted file mode 100644 index 19992ebc1..000000000 --- a/include/grub/dma.h +++ /dev/null @@ -1,44 +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 . - */ - -#ifndef GRUB_DMA_H -#define GRUB_DMA_H 1 - -struct grub_pci_dma_chunk; - -struct grub_pci_dma_chunk *EXPORT_FUNC(grub_memalign_dma32) (grub_size_t align, - grub_size_t size); -void EXPORT_FUNC(grub_dma_free) (struct grub_pci_dma_chunk *ch); -volatile void *EXPORT_FUNC(grub_dma_get_virt) (struct grub_pci_dma_chunk *ch); -grub_uint32_t EXPORT_FUNC(grub_dma_get_phys) (struct grub_pci_dma_chunk *ch); - -static inline void * -grub_dma_phys2virt (grub_uint32_t phys, struct grub_pci_dma_chunk *chunk) -{ - return ((grub_uint8_t *) grub_dma_get_virt (chunk) - + (phys - grub_dma_get_phys (chunk))); -} - -static inline grub_uint32_t -grub_dma_virt2phys (volatile void *virt, struct grub_pci_dma_chunk *chunk) -{ - return (((grub_uint8_t *) virt - (grub_uint8_t *) grub_dma_get_virt (chunk)) - + grub_dma_get_phys (chunk)); -} - -#endif diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index b686e8afe..36363ae1e 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -49,9 +49,6 @@ #define GRUB_EFI_MEMORY_WP 0x0000000000001000LL #define GRUB_EFI_MEMORY_RP 0x0000000000002000LL #define GRUB_EFI_MEMORY_XP 0x0000000000004000LL -#define GRUB_EFI_MEMORY_NV 0x0000000000008000LL -#define GRUB_EFI_MEMORY_MORE_RELIABLE 0x0000000000010000LL -#define GRUB_EFI_MEMORY_RO 0x0000000000020000LL #define GRUB_EFI_MEMORY_RUNTIME 0x8000000000000000LL #define GRUB_EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 @@ -61,8 +58,6 @@ #define GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 #define GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE 0x00000020 -#define GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001ULL - #define GRUB_EFI_VARIABLE_NON_VOLATILE 0x0000000000000001 #define GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002 #define GRUB_EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004 @@ -89,229 +84,14 @@ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ } -#define GRUB_EFI_SERIAL_IO_GUID \ - { 0xbb25cf6f, 0xf1d4, 0x11d2, \ - { 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0xfd } \ - } - -#define GRUB_EFI_SIMPLE_NETWORK_GUID \ - { 0xa19832b9, 0xac25, 0x11d3, \ - { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ - } - -#define GRUB_EFI_PXE_GUID \ - { 0x03c4e603, 0xac28, 0x11d3, \ - { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ - } - #define GRUB_EFI_DEVICE_PATH_GUID \ { 0x09576e91, 0x6d3f, 0x11d2, \ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ } -#define GRUB_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \ - { 0x387477c1, 0x69c7, 0x11d2, \ - { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ - } - -#define GRUB_EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \ - { 0xdd9e7534, 0x7762, 0x4698, \ - { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } \ - } - -#define GRUB_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID \ - { 0x387477c2, 0x69c7, 0x11d2, \ - { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ - } - -#define GRUB_EFI_SIMPLE_POINTER_PROTOCOL_GUID \ - { 0x31878c87, 0xb75, 0x11d5, \ - { 0x9a, 0x4f, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ - } - -#define GRUB_EFI_ABSOLUTE_POINTER_PROTOCOL_GUID \ - { 0x8D59D32B, 0xC655, 0x4AE9, \ - { 0x9B, 0x15, 0xF2, 0x59, 0x04, 0x99, 0x2A, 0x43 } \ - } - -#define GRUB_EFI_DRIVER_BINDING_PROTOCOL_GUID \ - { 0x18A031AB, 0xB443, 0x4D1A, \ - { 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71 } \ - } - -#define GRUB_EFI_LOADED_IMAGE_PROTOCOL_GUID \ - { 0x5B1B31A1, 0x9562, 0x11d2, \ - { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \ - } - -#define GRUB_EFI_LOAD_FILE_PROTOCOL_GUID \ - { 0x56EC3091, 0x954C, 0x11d2, \ - { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \ - } - -#define GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID \ - { 0x4006c0c1, 0xfcb3, 0x403e, \ - { 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d } \ - } - -#define GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ - { 0x0964e5b22, 0x6459, 0x11d2, \ - { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ - } - -#define GRUB_EFI_TAPE_IO_PROTOCOL_GUID \ - { 0x1e93e633, 0xd65a, 0x459e, \ - { 0xab, 0x84, 0x93, 0xd9, 0xec, 0x26, 0x6d, 0x18 } \ - } - -#define GRUB_EFI_UNICODE_COLLATION_PROTOCOL_GUID \ - { 0x1d85cd7f, 0xf43d, 0x11d2, \ - { 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ - } - -#define GRUB_EFI_SCSI_IO_PROTOCOL_GUID \ - { 0x932f47e6, 0x2362, 0x4002, \ - { 0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85 } \ - } - -#define GRUB_EFI_USB2_HC_PROTOCOL_GUID \ - { 0x3e745226, 0x9818, 0x45b6, \ - { 0xa2, 0xac, 0xd7, 0xcd, 0x0e, 0x8b, 0xa2, 0xbc } \ - } - -#define GRUB_EFI_DEBUG_SUPPORT_PROTOCOL_GUID \ - { 0x2755590C, 0x6F3C, 0x42FA, \ - { 0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25 } \ - } - -#define GRUB_EFI_DEBUGPORT_PROTOCOL_GUID \ - { 0xEBA4E8D2, 0x3858, 0x41EC, \ - { 0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \ - } - -#define GRUB_EFI_DECOMPRESS_PROTOCOL_GUID \ - { 0xd8117cfe, 0x94a6, 0x11d4, \ - { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ - } - -#define GRUB_EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \ - { 0x8b843e20, 0x8132, 0x4852, \ - { 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } \ - } - -#define GRUB_EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID \ - { 0x379be4e, 0xd706, 0x437d, \ - { 0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } \ - } - -#define GRUB_EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \ - { 0x5c99a21, 0xc70f, 0x4ad2, \ - { 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e } \ - } - -#define GRUB_EFI_ACPI_TABLE_PROTOCOL_GUID \ - { 0xffe06bdd, 0x6107, 0x46a6, \ - { 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c} \ - } - -#define GRUB_EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \ - { 0x587e72d7, 0xcc50, 0x4f79, \ - { 0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f } \ - } - -#define GRUB_EFI_HII_DATABASE_PROTOCOL_GUID \ - { 0xef9fc172, 0xa1b2, 0x4693, \ - { 0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42 } \ - } - -#define GRUB_EFI_HII_STRING_PROTOCOL_GUID \ - { 0xfd96974, 0x23aa, 0x4cdc, \ - { 0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a } \ - } - -#define GRUB_EFI_HII_IMAGE_PROTOCOL_GUID \ - { 0x31a6406a, 0x6bdf, 0x4e46, \ - { 0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x9, 0x20 } \ - } - -#define GRUB_EFI_HII_FONT_PROTOCOL_GUID \ - { 0xe9ca4775, 0x8657, 0x47fc, \ - { 0x97, 0xe7, 0x7e, 0xd6, 0x5a, 0x8, 0x43, 0x24 } \ - } - -#define GRUB_EFI_HII_CONFIGURATION_ACCESS_PROTOCOL_GUID \ - { 0x330d4706, 0xf2a0, 0x4e4f, \ - { 0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85 } \ - } - -#define GRUB_EFI_COMPONENT_NAME2_PROTOCOL_GUID \ - { 0x6a7a5cff, 0xe8d9, 0x4f70, \ - { 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14} \ - } - -#define GRUB_EFI_USB_IO_PROTOCOL_GUID \ - { 0x2B2F68D6, 0x0CD2, 0x44cf, \ - { 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 } \ - } - -#define GRUB_EFI_TIANO_CUSTOM_DECOMPRESS_GUID \ - { 0xa31280ad, 0x481e, 0x41b6, \ - { 0x95, 0xe8, 0x12, 0x7f, 0x4c, 0x98, 0x47, 0x79 } \ - } - -#define GRUB_EFI_CRC32_GUIDED_SECTION_EXTRACTION_GUID \ - { 0xfc1bcdb0, 0x7d31, 0x49aa, \ - { 0x93, 0x6a, 0xa4, 0x60, 0x0d, 0x9d, 0xd0, 0x83 } \ - } - -#define GRUB_EFI_LZMA_CUSTOM_DECOMPRESS_GUID \ - { 0xee4e5898, 0x3914, 0x4259, \ - { 0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf } \ - } - -#define GRUB_EFI_TSC_FREQUENCY_GUID \ - { 0xdba6a7e3, 0xbb57, 0x4be7, \ - { 0x8a, 0xf8, 0xd5, 0x78, 0xdb, 0x7e, 0x56, 0x87 } \ - } - -#define GRUB_EFI_SYSTEM_RESOURCE_TABLE_GUID \ - { 0xb122a263, 0x3661, 0x4f68, \ - { 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80 } \ - } - -#define GRUB_EFI_DXE_SERVICES_TABLE_GUID \ - { 0x05ad34ba, 0x6f02, 0x4214, \ - { 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9 } \ - } - -#define GRUB_EFI_HOB_LIST_GUID \ - { 0x7739f24c, 0x93d7, 0x11d4, \ - { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ - } - -#define GRUB_EFI_IMAGE_SECURITY_DATABASE_GUID \ - { 0xd719b2cb, 0x3d3a, 0x4596, \ - { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f } \ - } - -#define GRUB_EFI_MEMORY_TYPE_INFORMATION_GUID \ - { 0x4c19049f, 0x4137, 0x4dd3, \ - { 0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa } \ - } - -#define GRUB_EFI_CONFORMANCE_PROFILES_TABLE_GUID \ - { 0x36122546, 0xf7e7, 0x4c8f, \ - { 0xbd, 0x9b, 0xeb, 0x85, 0x25, 0xb5, 0x0c, 0x0b } \ - } - -#define GRUB_EFI_DEBUG_IMAGE_INFO_TABLE_GUID \ - { 0x49152e77, 0x1ada, 0x4764, \ - { 0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b } \ - } - #define GRUB_EFI_MPS_TABLE_GUID \ { 0xeb9d2d2f, 0x2d88, 0x11d3, \ - { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } #define GRUB_EFI_ACPI_TABLE_GUID \ @@ -329,172 +109,6 @@ { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ } -#define GRUB_EFI_SMBIOS3_TABLE_GUID \ - { 0xf2fd1544, 0x9794, 0x4a2c, \ - { 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94 } \ - } - -#define GRUB_EFI_SAL_TABLE_GUID \ - { 0xeb9d2d32, 0x2d88, 0x11d3, \ - { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ - } - -#define GRUB_EFI_HCDP_TABLE_GUID \ - { 0xf951938d, 0x620b, 0x42ef, \ - { 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } \ - } - -#define GRUB_EFI_RT_PROPERTIES_TABLE_GUID \ - { 0xeb66918a, 0x7eef, 0x402a, \ - { 0x84, 0x2e, 0x93, 0x1d, 0x21, 0xc3, 0x8a, 0xe9 } \ - } - -#define GRUB_EFI_DEVICE_TREE_GUID \ - { 0xb1b621d5, 0xf19c, 0x41a5, \ - { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \ - } - -#define GRUB_EFI_VENDOR_APPLE_GUID \ - { 0x2B0585EB, 0xD8B8, 0x49A9, \ - { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \ - } - -#define GRUB_EFI_SHIM_LOCK_GUID \ - { 0x605dab50, 0xe046, 0x4300, \ - { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \ - } - -#define GRUB_EFI_RNG_PROTOCOL_GUID \ - { 0x3152bca5, 0xeade, 0x433d, \ - { 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \ - } - -#define LINUX_EFI_INITRD_MEDIA_GUID \ - { 0x5568e427, 0x68fc, 0x4f3d, \ - { 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 } \ - } - -#define GRUB_EFI_VENDOR_BOOT_LOADER_INTERFACE_GUID \ - { 0x4a67b082, 0x0a4c, 0x41cf, \ - {0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } \ - } - -#define GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID \ - { 0xf4560cf6, 0x40ec, 0x4b4a, \ - { 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89 } \ - } - -struct grub_efi_sal_system_table -{ - grub_uint32_t signature; - grub_uint32_t total_table_len; - grub_uint16_t sal_rev; - grub_uint16_t entry_count; - grub_uint8_t checksum; - grub_uint8_t reserved1[7]; - grub_uint16_t sal_a_version; - grub_uint16_t sal_b_version; - grub_uint8_t oem_id[32]; - grub_uint8_t product_id[32]; - grub_uint8_t reserved2[8]; - grub_uint8_t entries[0]; -}; - -enum - { - GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_ENTRYPOINT_DESCRIPTOR = 0, - GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_MEMORY_DESCRIPTOR = 1, - GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PLATFORM_FEATURES = 2, - GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_TRANSLATION_REGISTER_DESCRIPTOR = 3, - GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PURGE_TRANSLATION_COHERENCE = 4, - GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_AP_WAKEUP = 5 - }; - -struct grub_efi_sal_system_table_entrypoint_descriptor -{ - grub_uint8_t type; - grub_uint8_t pad[7]; - grub_uint64_t pal_proc_addr; - grub_uint64_t sal_proc_addr; - grub_uint64_t global_data_ptr; - grub_uint64_t reserved[2]; -}; - -struct grub_efi_sal_system_table_memory_descriptor -{ - grub_uint8_t type; - grub_uint8_t sal_used; - grub_uint8_t attr; - grub_uint8_t ar; - grub_uint8_t attr_mask; - grub_uint8_t mem_type; - grub_uint8_t usage; - grub_uint8_t unknown; - grub_uint64_t addr; - grub_uint64_t len; - grub_uint64_t unknown2; -}; - -struct grub_efi_sal_system_table_platform_features -{ - grub_uint8_t type; - grub_uint8_t flags; - grub_uint8_t reserved[14]; -}; - -struct grub_efi_sal_system_table_translation_register_descriptor -{ - grub_uint8_t type; - grub_uint8_t register_type; - grub_uint8_t register_number; - grub_uint8_t reserved[5]; - grub_uint64_t addr; - grub_uint64_t page_size; - grub_uint64_t reserver; -}; - -struct grub_efi_sal_system_table_purge_translation_coherence -{ - grub_uint8_t type; - grub_uint8_t reserved[3]; - grub_uint32_t ndomains; - grub_uint64_t coherence; -}; - -struct grub_efi_sal_system_table_ap_wakeup -{ - grub_uint8_t type; - grub_uint8_t mechanism; - grub_uint8_t reserved[6]; - grub_uint64_t vector; -}; - -enum - { - GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_BUSLOCK = 1, - GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IRQREDIRECT = 2, - GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IPIREDIRECT = 4, - GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_ITCDRIFT = 8, - }; - -typedef enum grub_efi_parity_type - { - GRUB_EFI_SERIAL_DEFAULT_PARITY, - GRUB_EFI_SERIAL_NO_PARITY, - GRUB_EFI_SERIAL_EVEN_PARITY, - GRUB_EFI_SERIAL_ODD_PARITY - } -grub_efi_parity_type_t; - -typedef enum grub_efi_stop_bits - { - GRUB_EFI_SERIAL_DEFAULT_STOP_BITS, - GRUB_EFI_SERIAL_1_STOP_BIT, - GRUB_EFI_SERIAL_1_5_STOP_BITS, - GRUB_EFI_SERIAL_2_STOP_BITS - } - grub_efi_stop_bits_t; - /* Enumerations. */ enum grub_efi_timer_delay { @@ -529,7 +143,6 @@ enum grub_efi_memory_type GRUB_EFI_MEMORY_MAPPED_IO, GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE, GRUB_EFI_PAL_CODE, - GRUB_EFI_PERSISTENT_MEMORY, GRUB_EFI_MAX_MEMORY_TYPE }; typedef enum grub_efi_memory_type grub_efi_memory_type_t; @@ -558,48 +171,23 @@ typedef enum grub_efi_reset_type grub_efi_reset_type_t; /* Types. */ typedef char grub_efi_boolean_t; -#if GRUB_CPU_SIZEOF_VOID_P == 8 -typedef grub_int64_t grub_efi_intn_t; -typedef grub_uint64_t grub_efi_uintn_t; -#define PRIxGRUB_EFI_UINTN_T PRIxGRUB_UINT64_T -#define PRIuGRUB_EFI_UINTN_T PRIuGRUB_UINT64_T -#else -typedef grub_int32_t grub_efi_intn_t; -typedef grub_uint32_t grub_efi_uintn_t; -#define PRIxGRUB_EFI_UINTN_T PRIxGRUB_UINT32_T -#define PRIuGRUB_EFI_UINTN_T PRIuGRUB_UINT32_T -#endif +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; -#define PRIxGRUB_EFI_UINT32_T PRIxGRUB_UINT32_T -#define PRIuGRUB_EFI_UINT32_T PRIuGRUB_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_uintn_t grub_efi_status_t; - -/* - * On x86, the EFI calling convention may deviate from the local one, so - * callback functions exposed to the firmware must carry the follow attribute - * annotation. (This includes protocols implemented by GRUB that are installed - * into the EFI protocol database.) - */ -#if defined(__i386__) -#define __grub_efi_api __attribute__((regparm(0))) -#elif defined(__x86_64__) -#define __grub_efi_api __attribute__((ms_abi)) -#else -#define __grub_efi_api -#endif +typedef grub_efi_intn_t grub_efi_status_t; #define GRUB_EFI_ERROR_CODE(value) \ - ((((grub_efi_status_t) 1) << (sizeof (grub_efi_status_t) * 8 - 1)) | (value)) + ((1L << (sizeof (grub_efi_status_t) * 8 - 1)) | (value)) #define GRUB_EFI_WARNING_CODE(value) (value) @@ -649,6 +237,15 @@ 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 @@ -659,7 +256,7 @@ struct grub_efi_memory_descriptor grub_efi_virtual_address_t virtual_start; grub_efi_uint64_t num_pages; grub_efi_uint64_t attribute; -} GRUB_PACKED; +}; typedef struct grub_efi_memory_descriptor grub_efi_memory_descriptor_t; /* Device Path definitions. */ @@ -667,8 +264,8 @@ struct grub_efi_device_path { grub_efi_uint8_t type; grub_efi_uint8_t subtype; - grub_efi_uint16_t length; -} GRUB_PACKED; + 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. */ @@ -676,8 +273,8 @@ 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) -#define GRUB_EFI_DEVICE_PATH_VALID(dp) ((dp) != NULL && GRUB_EFI_DEVICE_PATH_LENGTH (dp) >= 4) +#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) @@ -686,16 +283,13 @@ typedef struct grub_efi_device_path grub_efi_device_path_protocol_t; #define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE 0x01 #define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp) \ - (!GRUB_EFI_DEVICE_PATH_VALID (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))) + (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_VALID (dp) \ - ? ((grub_efi_device_path_t *) \ - ((char *) (dp) + GRUB_EFI_DEVICE_PATH_LENGTH (dp))) \ - : NULL) + ((grub_efi_device_path_t *) ((char *) (dp) \ + + GRUB_EFI_DEVICE_PATH_LENGTH (dp))) /* Hardware Device Path. */ #define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE 1 @@ -707,7 +301,7 @@ struct grub_efi_pci_device_path grub_efi_device_path_t header; grub_efi_uint8_t function; grub_efi_uint8_t device; -} GRUB_PACKED; +}; typedef struct grub_efi_pci_device_path grub_efi_pci_device_path_t; #define GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE 2 @@ -716,7 +310,7 @@ struct grub_efi_pccard_device_path { grub_efi_device_path_t header; grub_efi_uint8_t function; -} GRUB_PACKED; +}; typedef struct grub_efi_pccard_device_path grub_efi_pccard_device_path_t; #define GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE 3 @@ -724,10 +318,10 @@ typedef struct grub_efi_pccard_device_path grub_efi_pccard_device_path_t; struct grub_efi_memory_mapped_device_path { grub_efi_device_path_t header; - grub_efi_uint32_t memory_type; + grub_efi_memory_type_t memory_type; grub_efi_physical_address_t start_address; grub_efi_physical_address_t end_address; -} GRUB_PACKED; +}; typedef struct grub_efi_memory_mapped_device_path grub_efi_memory_mapped_device_path_t; #define GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE 4 @@ -735,9 +329,9 @@ typedef struct grub_efi_memory_mapped_device_path grub_efi_memory_mapped_device_ struct grub_efi_vendor_device_path { grub_efi_device_path_t header; - grub_packed_guid_t vendor_guid; + grub_efi_guid_t vendor_guid; grub_efi_uint8_t vendor_defined_data[0]; -} GRUB_PACKED; +}; typedef struct grub_efi_vendor_device_path grub_efi_vendor_device_path_t; #define GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE 5 @@ -746,7 +340,7 @@ struct grub_efi_controller_device_path { grub_efi_device_path_t header; grub_efi_uint32_t controller_number; -} GRUB_PACKED; +}; typedef struct grub_efi_controller_device_path grub_efi_controller_device_path_t; /* ACPI Device Path. */ @@ -759,7 +353,7 @@ struct grub_efi_acpi_device_path grub_efi_device_path_t header; grub_efi_uint32_t hid; grub_efi_uint32_t uid; -} GRUB_PACKED; +}; typedef struct grub_efi_acpi_device_path grub_efi_acpi_device_path_t; #define GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE 2 @@ -770,8 +364,8 @@ struct grub_efi_expanded_acpi_device_path grub_efi_uint32_t hid; grub_efi_uint32_t uid; grub_efi_uint32_t cid; - char hidstr[0]; -} GRUB_PACKED; + 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) \ @@ -794,7 +388,7 @@ struct grub_efi_atapi_device_path grub_efi_uint8_t primary_secondary; grub_efi_uint8_t slave_master; grub_efi_uint16_t lun; -} GRUB_PACKED; +}; typedef struct grub_efi_atapi_device_path grub_efi_atapi_device_path_t; #define GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE 2 @@ -804,7 +398,7 @@ struct grub_efi_scsi_device_path grub_efi_device_path_t header; grub_efi_uint16_t pun; grub_efi_uint16_t lun; -} GRUB_PACKED; +}; typedef struct grub_efi_scsi_device_path grub_efi_scsi_device_path_t; #define GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE 3 @@ -815,7 +409,7 @@ struct grub_efi_fibre_channel_device_path grub_efi_uint32_t reserved; grub_efi_uint64_t wwn; grub_efi_uint64_t lun; -} GRUB_PACKED; +}; typedef struct grub_efi_fibre_channel_device_path grub_efi_fibre_channel_device_path_t; #define GRUB_EFI_1394_DEVICE_PATH_SUBTYPE 4 @@ -825,7 +419,7 @@ struct grub_efi_1394_device_path grub_efi_device_path_t header; grub_efi_uint32_t reserved; grub_efi_uint64_t guid; -} GRUB_PACKED; +}; typedef struct grub_efi_1394_device_path grub_efi_1394_device_path_t; #define GRUB_EFI_USB_DEVICE_PATH_SUBTYPE 5 @@ -834,8 +428,8 @@ struct grub_efi_usb_device_path { grub_efi_device_path_t header; grub_efi_uint8_t parent_port_number; - grub_efi_uint8_t usb_interface; -} GRUB_PACKED; + 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 @@ -848,7 +442,7 @@ struct grub_efi_usb_class_device_path grub_efi_uint8_t device_class; grub_efi_uint8_t device_subclass; grub_efi_uint8_t device_protocol; -} GRUB_PACKED; +}; typedef struct grub_efi_usb_class_device_path grub_efi_usb_class_device_path_t; #define GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE 6 @@ -857,7 +451,7 @@ struct grub_efi_i2o_device_path { grub_efi_device_path_t header; grub_efi_uint32_t tid; -} GRUB_PACKED; +}; typedef struct grub_efi_i2o_device_path grub_efi_i2o_device_path_t; #define GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE 11 @@ -867,7 +461,7 @@ 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; -} GRUB_PACKED; +}; typedef struct grub_efi_mac_address_device_path grub_efi_mac_address_device_path_t; #define GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE 12 @@ -881,7 +475,7 @@ struct grub_efi_ipv4_device_path grub_efi_uint16_t remote_port; grub_efi_uint16_t protocol; grub_efi_uint8_t static_ip_address; -} GRUB_PACKED; +}; typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t; #define GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE 13 @@ -895,7 +489,7 @@ struct grub_efi_ipv6_device_path grub_efi_uint16_t remote_port; grub_efi_uint16_t protocol; grub_efi_uint8_t static_ip_address; -} GRUB_PACKED; +}; typedef struct grub_efi_ipv6_device_path grub_efi_ipv6_device_path_t; #define GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE 9 @@ -908,7 +502,7 @@ struct grub_efi_infiniband_device_path grub_efi_uint64_t remote_id; grub_efi_uint64_t target_port_id; grub_efi_uint64_t device_id; -} GRUB_PACKED; +}; typedef struct grub_efi_infiniband_device_path grub_efi_infiniband_device_path_t; #define GRUB_EFI_UART_DEVICE_PATH_SUBTYPE 14 @@ -921,31 +515,19 @@ struct grub_efi_uart_device_path grub_efi_uint8_t data_bits; grub_efi_uint8_t parity; grub_efi_uint8_t stop_bits; -} GRUB_PACKED; +}; typedef struct grub_efi_uart_device_path grub_efi_uart_device_path_t; -#define GRUB_EFI_SATA_DEVICE_PATH_SUBTYPE 18 - -struct grub_efi_sata_device_path -{ - grub_efi_device_path_t header; - grub_efi_uint16_t hba_port; - grub_efi_uint16_t multiplier_port; - grub_efi_uint16_t lun; -} GRUB_PACKED; -typedef struct grub_efi_sata_device_path grub_efi_sata_device_path_t; - -#define GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE 20 - -struct grub_efi_vlan_device_path -{ - grub_efi_device_path_t header; - grub_efi_uint16_t vlan_id; -} GRUB_PACKED; -typedef struct grub_efi_vlan_device_path grub_efi_vlan_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 @@ -957,10 +539,10 @@ struct grub_efi_hard_drive_device_path grub_efi_uint32_t partition_number; grub_efi_lba_t partition_start; grub_efi_lba_t partition_size; - grub_efi_uint8_t partition_signature[16]; - grub_efi_uint8_t partmap_type; + grub_efi_uint8_t partition_signature[8]; + grub_efi_uint8_t mbr_type; grub_efi_uint8_t signature_type; -} GRUB_PACKED; +}; typedef struct grub_efi_hard_drive_device_path grub_efi_hard_drive_device_path_t; #define GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE 2 @@ -971,7 +553,7 @@ struct grub_efi_cdrom_device_path grub_efi_uint32_t boot_entry; grub_efi_lba_t partition_start; grub_efi_lba_t partition_size; -} GRUB_PACKED; +}; typedef struct grub_efi_cdrom_device_path grub_efi_cdrom_device_path_t; #define GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE 3 @@ -979,9 +561,9 @@ typedef struct grub_efi_cdrom_device_path grub_efi_cdrom_device_path_t; struct grub_efi_vendor_media_device_path { grub_efi_device_path_t header; - grub_packed_guid_t vendor_guid; + grub_efi_guid_t vendor_guid; grub_efi_uint8_t vendor_defined_data[0]; -} GRUB_PACKED; +}; typedef struct grub_efi_vendor_media_device_path grub_efi_vendor_media_device_path_t; #define GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE 4 @@ -990,7 +572,7 @@ struct grub_efi_file_path_device_path { grub_efi_device_path_t header; grub_efi_char16_t path_name[0]; -} GRUB_PACKED; +}; typedef struct grub_efi_file_path_device_path grub_efi_file_path_device_path_t; #define GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE 5 @@ -998,8 +580,8 @@ typedef struct grub_efi_file_path_device_path grub_efi_file_path_device_path_t; struct grub_efi_protocol_device_path { grub_efi_device_path_t header; - grub_packed_guid_t guid; -} GRUB_PACKED; + 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 @@ -1007,8 +589,8 @@ typedef struct grub_efi_protocol_device_path grub_efi_protocol_device_path_t; struct grub_efi_piwg_device_path { grub_efi_device_path_t header; - grub_packed_guid_t guid; -} GRUB_PACKED; + grub_efi_guid_t guid __attribute__ ((packed)); +}; typedef struct grub_efi_piwg_device_path grub_efi_piwg_device_path_t; @@ -1023,7 +605,7 @@ struct grub_efi_bios_device_path grub_efi_uint16_t device_type; grub_efi_uint16_t status_flags; char description[0]; -} GRUB_PACKED; +}; typedef struct grub_efi_bios_device_path grub_efi_bios_device_path_t; struct grub_efi_open_protocol_information_entry @@ -1048,7 +630,7 @@ struct grub_efi_time grub_efi_int16_t time_zone; grub_efi_uint8_t daylight; grub_efi_uint8_t pad2; -} GRUB_PACKED; +} __attribute__ ((packed)); typedef struct grub_efi_time grub_efi_time_t; struct grub_efi_time_capabilities @@ -1066,32 +648,6 @@ struct grub_efi_input_key }; typedef struct grub_efi_input_key grub_efi_input_key_t; -typedef grub_efi_uint8_t grub_efi_key_toggle_state_t; -struct grub_efi_key_state -{ - grub_efi_uint32_t key_shift_state; - grub_efi_key_toggle_state_t key_toggle_state; -}; -typedef struct grub_efi_key_state grub_efi_key_state_t; - -#define GRUB_EFI_SHIFT_STATE_VALID 0x80000000 -#define GRUB_EFI_RIGHT_SHIFT_PRESSED 0x00000001 -#define GRUB_EFI_LEFT_SHIFT_PRESSED 0x00000002 -#define GRUB_EFI_RIGHT_CONTROL_PRESSED 0x00000004 -#define GRUB_EFI_LEFT_CONTROL_PRESSED 0x00000008 -#define GRUB_EFI_RIGHT_ALT_PRESSED 0x00000010 -#define GRUB_EFI_LEFT_ALT_PRESSED 0x00000020 -#define GRUB_EFI_RIGHT_LOGO_PRESSED 0x00000040 -#define GRUB_EFI_LEFT_LOGO_PRESSED 0x00000080 -#define GRUB_EFI_MENU_KEY_PRESSED 0x00000100 -#define GRUB_EFI_SYS_REQ_PRESSED 0x00000200 - -#define GRUB_EFI_TOGGLE_STATE_VALID 0x80 -#define GRUB_EFI_KEY_STATE_EXPOSED 0x40 -#define GRUB_EFI_SCROLL_LOCK_ACTIVE 0x01 -#define GRUB_EFI_NUM_LOCK_ACTIVE 0x02 -#define GRUB_EFI_CAPS_LOCK_ACTIVE 0x04 - struct grub_efi_simple_text_output_mode { grub_efi_int32_t max_mode; @@ -1119,210 +675,209 @@ struct grub_efi_boot_services grub_efi_table_header_t hdr; grub_efi_tpl_t - (__grub_efi_api *raise_tpl) (grub_efi_tpl_t new_tpl); + (*raise_tpl) (grub_efi_tpl_t new_tpl); void - (__grub_efi_api *restore_tpl) (grub_efi_tpl_t old_tpl); + (*restore_tpl) (grub_efi_tpl_t old_tpl); grub_efi_status_t - (__grub_efi_api *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); + (*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 - (__grub_efi_api *free_pages) (grub_efi_physical_address_t memory, - grub_efi_uintn_t pages); + (*free_pages) (grub_efi_physical_address_t memory, + grub_efi_uintn_t pages); grub_efi_status_t - (__grub_efi_api *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); + (*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 - (__grub_efi_api *allocate_pool) (grub_efi_memory_type_t pool_type, - grub_efi_uintn_t size, - void **buffer); + (*allocate_pool) (grub_efi_memory_type_t pool_type, + grub_efi_uintn_t size, + void **buffer); grub_efi_status_t - (__grub_efi_api *free_pool) (void *buffer); + (*free_pool) (void *buffer); grub_efi_status_t - (__grub_efi_api *create_event) (grub_efi_uint32_t type, - grub_efi_tpl_t notify_tpl, - void (__grub_efi_api *notify_function) (grub_efi_event_t, - void *context), - void *notify_context, - grub_efi_event_t *event); + (*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 - (__grub_efi_api *set_timer) (grub_efi_event_t event, - grub_efi_timer_delay_t type, - grub_efi_uint64_t trigger_time); + (*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 - (__grub_efi_api *wait_for_event) (grub_efi_uintn_t num_events, - grub_efi_event_t *event, - grub_efi_uintn_t *index); + (*signal_event) (grub_efi_event_t event); grub_efi_status_t - (__grub_efi_api *signal_event) (grub_efi_event_t event); + (*close_event) (grub_efi_event_t event); grub_efi_status_t - (__grub_efi_api *close_event) (grub_efi_event_t event); + (*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 - (__grub_efi_api *check_event) (grub_efi_event_t event); + (*reinstall_protocol_interface) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + void *old_interface, + void *new_interface); grub_efi_status_t - (__grub_efi_api *install_protocol_interface) (grub_efi_handle_t *handle, - grub_guid_t *protocol, - grub_efi_interface_type_t protocol_interface_type, - void *protocol_interface); + (*uninstall_protocol_interface) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + void *interface); grub_efi_status_t - (__grub_efi_api *reinstall_protocol_interface) (grub_efi_handle_t handle, - grub_guid_t *protocol, - void *old_interface, - void *new_interface); - - grub_efi_status_t - (__grub_efi_api *uninstall_protocol_interface) (grub_efi_handle_t handle, - grub_guid_t *protocol, - void *protocol_interface); - - grub_efi_status_t - (__grub_efi_api *handle_protocol) (grub_efi_handle_t handle, - grub_guid_t *protocol, - void **protocol_interface); + (*handle_protocol) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + void **interface); void *reserved; grub_efi_status_t - (__grub_efi_api *register_protocol_notify) (grub_guid_t *protocol, - grub_efi_event_t event, - void **registration); + (*register_protocol_notify) (grub_efi_guid_t *protocol, + grub_efi_event_t event, + void **registration); grub_efi_status_t - (__grub_efi_api *locate_handle) (grub_efi_locate_search_type_t search_type, - grub_guid_t *protocol, - void *search_key, - grub_efi_uintn_t *buffer_size, - grub_efi_handle_t *buffer); + (*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 - (__grub_efi_api *locate_device_path) (grub_guid_t *protocol, - grub_efi_device_path_t **device_path, - grub_efi_handle_t *device); + (*locate_device_path) (grub_efi_guid_t *protocol, + grub_efi_device_path_t **device_path, + grub_efi_handle_t *device); grub_efi_status_t - (__grub_efi_api *install_configuration_table) (grub_guid_t *guid, - void *table); + (*install_configuration_table) (grub_efi_guid_t *guid, void *table); grub_efi_status_t - (__grub_efi_api *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); + (*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 - (__grub_efi_api *start_image) (grub_efi_handle_t image_handle, - grub_efi_uintn_t *exit_data_size, - grub_efi_char16_t **exit_data); + (*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 - (__grub_efi_api *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); + (*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 - (__grub_efi_api *unload_image) (grub_efi_handle_t image_handle); + (*unload_image) (grub_efi_handle_t image_handle); grub_efi_status_t - (__grub_efi_api *exit_boot_services) (grub_efi_handle_t image_handle, - grub_efi_uintn_t map_key); + (*exit_boot_services) (grub_efi_handle_t image_handle, + grub_efi_uintn_t map_key); grub_efi_status_t - (__grub_efi_api *get_next_monotonic_count) (grub_efi_uint64_t *count); + (*get_next_monotonic_count) (grub_efi_uint64_t *count); grub_efi_status_t - (__grub_efi_api *stall) (grub_efi_uintn_t microseconds); + (*stall) (grub_efi_uintn_t microseconds); grub_efi_status_t - (__grub_efi_api *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); + (*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 - (__grub_efi_api *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); + (*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 - (__grub_efi_api *disconnect_controller) (grub_efi_handle_t controller_handle, - grub_efi_handle_t driver_image_handle, - grub_efi_handle_t child_handle); + (*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 - (__grub_efi_api *open_protocol) (grub_efi_handle_t handle, - grub_guid_t *protocol, - void **protocol_interface, - grub_efi_handle_t agent_handle, - grub_efi_handle_t controller_handle, - grub_efi_uint32_t attributes); + (*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 - (__grub_efi_api *close_protocol) (grub_efi_handle_t handle, - grub_guid_t *protocol, - grub_efi_handle_t agent_handle, - grub_efi_handle_t controller_handle); + (*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 - (__grub_efi_api *open_protocol_information) (grub_efi_handle_t handle, - grub_guid_t *protocol, - grub_efi_open_protocol_information_entry_t **entry_buffer, - grub_efi_uintn_t *entry_count); + (*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 - (__grub_efi_api *protocols_per_handle) (grub_efi_handle_t handle, - grub_packed_guid_t ***protocol_buffer, - grub_efi_uintn_t *protocol_buffer_count); + (*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 - (__grub_efi_api *locate_handle_buffer) (grub_efi_locate_search_type_t search_type, - grub_guid_t *protocol, - void *search_key, - grub_efi_uintn_t *no_handles, - grub_efi_handle_t **buffer); + (*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 - (__grub_efi_api *locate_protocol) (grub_guid_t *protocol, - void *registration, - void **protocol_interface); + (*locate_protocol) (grub_efi_guid_t *protocol, + void *registration, + void **interface); grub_efi_status_t - (__grub_efi_api *install_multiple_protocol_interfaces) (grub_efi_handle_t *handle, ...); + (*install_multiple_protocol_interfaces) (grub_efi_handle_t *handle, ...); grub_efi_status_t - (__grub_efi_api *uninstall_multiple_protocol_interfaces) (grub_efi_handle_t handle, ...); + (*uninstall_multiple_protocol_interfaces) (grub_efi_handle_t handle, ...); grub_efi_status_t - (__grub_efi_api *calculate_crc32) (void *data, - grub_efi_uintn_t data_size, - grub_efi_uint32_t *crc32); + (*calculate_crc32) (void *data, + grub_efi_uintn_t data_size, + grub_efi_uint32_t *crc32); void - (__grub_efi_api *copy_mem) (void *destination, void *source, grub_efi_uintn_t length); + (*copy_mem) (void *destination, void *source, grub_efi_uintn_t length); void - (__grub_efi_api *set_mem) (void *buffer, grub_efi_uintn_t size, grub_efi_uint8_t value); + (*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; @@ -1331,231 +886,128 @@ struct grub_efi_runtime_services grub_efi_table_header_t hdr; grub_efi_status_t - (__grub_efi_api *get_time) (grub_efi_time_t *time, - grub_efi_time_capabilities_t *capabilities); + (*get_time) (grub_efi_time_t *time, + grub_efi_time_capabilities_t *capabilities); grub_efi_status_t - (__grub_efi_api *set_time) (grub_efi_time_t *time); + (*set_time) (grub_efi_time_t *time); grub_efi_status_t - (__grub_efi_api *get_wakeup_time) (grub_efi_boolean_t *enabled, - grub_efi_boolean_t *pending, - grub_efi_time_t *time); + (*get_wakeup_time) (grub_efi_boolean_t *enabled, + grub_efi_boolean_t *pending, + grub_efi_time_t *time); grub_efi_status_t - (__grub_efi_api *set_wakeup_time) (grub_efi_boolean_t enabled, - grub_efi_time_t *time); + (*set_wakeup_time) (grub_efi_boolean_t enabled, + grub_efi_time_t *time); grub_efi_status_t - (__grub_efi_api *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); + (*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 - (__grub_efi_api *convert_pointer) (grub_efi_uintn_t debug_disposition, void **address); - -#define GRUB_EFI_GLOBAL_VARIABLE_GUID \ - { 0x8BE4DF61, 0x93CA, 0x11d2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C }} - + (*convert_pointer) (grub_efi_uintn_t debug_disposition, void **address); grub_efi_status_t - (__grub_efi_api *get_variable) (grub_efi_char16_t *variable_name, - const grub_guid_t *vendor_guid, - grub_efi_uint32_t *attributes, - grub_efi_uintn_t *data_size, - void *data); + (*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 - (__grub_efi_api *get_next_variable_name) (grub_efi_uintn_t *variable_name_size, - grub_efi_char16_t *variable_name, - grub_guid_t *vendor_guid); + (*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 - (__grub_efi_api *set_variable) (grub_efi_char16_t *variable_name, - const grub_guid_t *vendor_guid, - grub_efi_uint32_t attributes, - grub_efi_uintn_t data_size, - void *data); + (*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 - (__grub_efi_api *get_next_high_monotonic_count) (grub_efi_uint32_t *high_count); + (*get_next_high_monotonic_count) (grub_efi_uint32_t *high_count); void - (__grub_efi_api *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); + (*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_packed_guid_t vendor_guid; + grub_efi_guid_t vendor_guid; void *vendor_table; -} GRUB_PACKED; +} __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_serial_io_interface -{ - grub_efi_uint32_t revision; - void (*reset) (void); - - grub_efi_status_t - (__grub_efi_api *set_attributes) (struct grub_efi_serial_io_interface *this, - grub_efi_uint64_t speed, - grub_efi_uint32_t fifo_depth, - grub_efi_uint32_t timeout, - grub_efi_parity_type_t parity, - grub_uint8_t word_len, - grub_efi_stop_bits_t stop_bits); - - grub_efi_status_t - (__grub_efi_api *set_control_bits) (struct grub_efi_serial_io_interface *this, - grub_efi_uint32_t flags); - - void (__grub_efi_api *get_control_bits) (void); - - grub_efi_status_t - (__grub_efi_api *write) (struct grub_efi_serial_io_interface *this, - grub_efi_uintn_t *buf_size, - void *buffer); - - grub_efi_status_t - (__grub_efi_api *read) (struct grub_efi_serial_io_interface *this, - grub_efi_uintn_t *buf_size, - void *buffer); -}; - struct grub_efi_simple_input_interface { grub_efi_status_t - (__grub_efi_api *reset) (struct grub_efi_simple_input_interface *this, - grub_efi_boolean_t extended_verification); + (*reset) (struct grub_efi_simple_input_interface *this, + grub_efi_boolean_t extended_verification); grub_efi_status_t - (__grub_efi_api *read_key_stroke) (struct grub_efi_simple_input_interface *this, - grub_efi_input_key_t *key); + (*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_key_data { - grub_efi_input_key_t key; - grub_efi_key_state_t key_state; -}; -typedef struct grub_efi_key_data grub_efi_key_data_t; - -typedef grub_efi_status_t (__grub_efi_api *grub_efi_key_notify_function_t) ( - grub_efi_key_data_t *key_data - ); - -struct grub_efi_simple_text_input_ex_interface -{ - grub_efi_status_t - (__grub_efi_api *reset) (struct grub_efi_simple_text_input_ex_interface *this, - grub_efi_boolean_t extended_verification); - - grub_efi_status_t - (__grub_efi_api *read_key_stroke) (struct grub_efi_simple_text_input_ex_interface *this, - grub_efi_key_data_t *key_data); - - grub_efi_event_t wait_for_key; - - grub_efi_status_t - (__grub_efi_api *set_state) (struct grub_efi_simple_text_input_ex_interface *this, - grub_efi_key_toggle_state_t *key_toggle_state); - - grub_efi_status_t - (__grub_efi_api *register_key_notify) (struct grub_efi_simple_text_input_ex_interface *this, - grub_efi_key_data_t *key_data, - grub_efi_key_notify_function_t key_notification_function, - void **notify_handle); - - grub_efi_status_t - (__grub_efi_api *unregister_key_notify) (struct grub_efi_simple_text_input_ex_interface *this, - void *notification_handle); -}; -typedef struct grub_efi_simple_text_input_ex_interface grub_efi_simple_text_input_ex_interface_t; - struct grub_efi_simple_text_output_interface { grub_efi_status_t - (__grub_efi_api *reset) (struct grub_efi_simple_text_output_interface *this, - grub_efi_boolean_t extended_verification); + (*reset) (struct grub_efi_simple_text_output_interface *this, + grub_efi_boolean_t extended_verification); grub_efi_status_t - (__grub_efi_api *output_string) (struct grub_efi_simple_text_output_interface *this, - grub_efi_char16_t *string); + (*output_string) (struct grub_efi_simple_text_output_interface *this, + grub_efi_char16_t *string); grub_efi_status_t - (__grub_efi_api *test_string) (struct grub_efi_simple_text_output_interface *this, - grub_efi_char16_t *string); + (*test_string) (struct grub_efi_simple_text_output_interface *this, + grub_efi_char16_t *string); grub_efi_status_t - (__grub_efi_api *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); + (*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 - (__grub_efi_api *set_mode) (struct grub_efi_simple_text_output_interface *this, - grub_efi_uintn_t mode_number); + (*set_mode) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t mode_number); grub_efi_status_t - (__grub_efi_api *set_attributes) (struct grub_efi_simple_text_output_interface *this, - grub_efi_uintn_t attribute); + (*set_attributes) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t attribute); grub_efi_status_t - (__grub_efi_api *clear_screen) (struct grub_efi_simple_text_output_interface *this); + (*clear_screen) (struct grub_efi_simple_text_output_interface *this); grub_efi_status_t - (__grub_efi_api *set_cursor_position) (struct grub_efi_simple_text_output_interface *this, - grub_efi_uintn_t column, - grub_efi_uintn_t row); + (*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 - (__grub_efi_api *enable_cursor) (struct grub_efi_simple_text_output_interface *this, - grub_efi_boolean_t visible); + (*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; -typedef grub_uint8_t grub_efi_pxe_packet_t[1472]; - -typedef struct grub_efi_pxe_mode -{ - grub_uint8_t unused[52]; - grub_efi_pxe_packet_t dhcp_discover; - grub_efi_pxe_packet_t dhcp_ack; - grub_efi_pxe_packet_t proxy_offer; - grub_efi_pxe_packet_t pxe_discover; - grub_efi_pxe_packet_t pxe_reply; -} grub_efi_pxe_mode_t; - -typedef struct grub_efi_pxe -{ - grub_uint64_t rev; - void *start; - void *stop; - void *dhcp; - void *discover; - void *mftp; - void *udpwrite; - void *udpread; - void *setipfilter; - void *arp; - void *setparams; - void *setstationip; - void *setpackets; - struct grub_efi_pxe_mode *mode; -} grub_efi_pxe_t; - #define GRUB_EFI_BLACK 0x00 #define GRUB_EFI_BLUE 0x01 #define GRUB_EFI_GREEN 0x02 @@ -1621,23 +1073,23 @@ struct grub_efi_loaded_image grub_efi_memory_type_t image_code_type; grub_efi_memory_type_t image_data_type; - grub_efi_status_t (__grub_efi_api *unload) (grub_efi_handle_t image_handle); + 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 (__grub_efi_api *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 (__grub_efi_api *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); + 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; @@ -1657,187 +1109,83 @@ struct grub_efi_block_io_media }; typedef struct grub_efi_block_io_media grub_efi_block_io_media_t; -typedef grub_uint8_t grub_efi_mac_t[32]; - -struct grub_efi_simple_network_mode -{ - grub_uint32_t state; - grub_uint32_t hwaddr_size; - grub_uint32_t media_header_size; - grub_uint32_t max_packet_size; - grub_uint32_t nvram_size; - grub_uint32_t nvram_access_size; - grub_uint32_t receive_filter_mask; - grub_uint32_t receive_filter_setting; - grub_uint32_t max_mcast_filter_count; - grub_uint32_t mcast_filter_count; - grub_efi_mac_t mcast_filter[16]; - grub_efi_mac_t current_address; - grub_efi_mac_t broadcast_address; - grub_efi_mac_t permanent_address; - grub_uint8_t if_type; - grub_uint8_t mac_changeable; - grub_uint8_t multitx_supported; - grub_uint8_t media_present_supported; - grub_uint8_t media_present; -}; - -enum - { - GRUB_EFI_NETWORK_STOPPED, - GRUB_EFI_NETWORK_STARTED, - GRUB_EFI_NETWORK_INITIALIZED, - }; - -enum - { - GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST = 0x01, - GRUB_EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST = 0x02, - GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST = 0x04, - GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS = 0x08, - GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST = 0x10, - }; - -struct grub_efi_simple_network -{ - grub_uint64_t revision; - - grub_efi_status_t - (__grub_efi_api *start) (struct grub_efi_simple_network *this); - - grub_efi_status_t - (__grub_efi_api *stop) (struct grub_efi_simple_network *this); - - grub_efi_status_t - (__grub_efi_api *initialize) (struct grub_efi_simple_network *this, - grub_efi_uintn_t extra_rx, - grub_efi_uintn_t extra_tx); - - void (__grub_efi_api *reset) (void); - - grub_efi_status_t - (__grub_efi_api *shutdown) (struct grub_efi_simple_network *this); - - grub_efi_status_t - (__grub_efi_api *receive_filters) (struct grub_efi_simple_network *this, - grub_uint32_t enable, - grub_uint32_t disable, - grub_efi_boolean_t reset_mcast_filter, - grub_efi_uintn_t mcast_filter_count, - grub_efi_mac_address_t *mcast_filter); - - void (__grub_efi_api *station_address) (void); - void (__grub_efi_api *statistics) (void); - void (__grub_efi_api *mcastiptomac) (void); - void (__grub_efi_api *nvdata) (void); - - grub_efi_status_t - (__grub_efi_api *get_status) (struct grub_efi_simple_network *this, - grub_uint32_t *int_status, - void **txbuf); - - grub_efi_status_t - (__grub_efi_api *transmit) (struct grub_efi_simple_network *this, - grub_efi_uintn_t header_size, - grub_efi_uintn_t buffer_size, - void *buffer, - grub_efi_mac_t *src_addr, - grub_efi_mac_t *dest_addr, - grub_efi_uint16_t *protocol); - - grub_efi_status_t - (__grub_efi_api *receive) (struct grub_efi_simple_network *this, - grub_efi_uintn_t *header_size, - grub_efi_uintn_t *buffer_size, - void *buffer, - grub_efi_mac_t *src_addr, - grub_efi_mac_t *dest_addr, - grub_uint16_t *protocol); - - void (__grub_efi_api *waitforpacket) (void); - struct grub_efi_simple_network_mode *mode; -}; -typedef struct grub_efi_simple_network grub_efi_simple_network_t; - - struct grub_efi_block_io { grub_efi_uint64_t revision; grub_efi_block_io_media_t *media; - grub_efi_status_t (__grub_efi_api *reset) (struct grub_efi_block_io *this, - grub_efi_boolean_t extended_verification); - grub_efi_status_t (__grub_efi_api *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 (__grub_efi_api *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 (__grub_efi_api *flush_blocks) (struct grub_efi_block_io *this); + 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; -struct grub_efi_shim_lock_protocol -{ - /* - * verify() function (surprisingly) does not use specific EFI calling convention. - * So, it does not need to be tagged with __grub_efi_api attribute. - */ - grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size); -}; -typedef struct grub_efi_shim_lock_protocol grub_efi_shim_lock_protocol_t; +#if GRUB_TARGET_SIZEOF_VOID_P == 4 -typedef grub_guid_t grub_efi_rng_algorithm_t; +#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) -struct grub_efi_rng_protocol -{ - grub_efi_status_t (__grub_efi_api *get_info) (struct grub_efi_rng_protocol *this, - grub_efi_uintn_t *rng_algorithm_list_size, - grub_efi_rng_algorithm_t *rng_algorithm_list); - grub_efi_status_t (__grub_efi_api *get_rng) (struct grub_efi_rng_protocol *this, - grub_efi_rng_algorithm_t *rng_algorithm, - grub_efi_uintn_t rng_value_length, - grub_efi_uint8_t *rng_value); -}; -typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_t; +#else -struct grub_efi_load_file2 -{ - grub_efi_status_t (__grub_efi_api *load_file)(struct grub_efi_load_file2 *this, - grub_efi_device_path_t *file_path, - grub_efi_boolean_t boot_policy, - grub_efi_uintn_t *buffer_size, - void *buffer); -}; -typedef struct grub_efi_load_file2 grub_efi_load_file2_t; +#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) -struct initrd_media_device_path { - grub_efi_vendor_media_device_path_t vendor; - grub_efi_device_path_t end; -} GRUB_PACKED; -typedef struct initrd_media_device_path initrd_media_device_path_t; - -struct grub_efi_memory_attribute_protocol -{ - grub_efi_status_t (__grub_efi_api *get_memory_attributes) ( - struct grub_efi_memory_attribute_protocol *this, - grub_efi_physical_address_t base_address, - grub_efi_uint64_t length, - grub_efi_uint64_t *attributes); - grub_efi_status_t (__grub_efi_api *set_memory_attributes) ( - struct grub_efi_memory_attribute_protocol *this, - grub_efi_physical_address_t base_address, - grub_efi_uint64_t length, - grub_efi_uint64_t attributes); - grub_efi_status_t (__grub_efi_api *clear_memory_attributes) ( - struct grub_efi_memory_attribute_protocol *this, - grub_efi_physical_address_t base_address, - grub_efi_uint64_t length, - grub_efi_uint64_t attributes); -}; -typedef struct grub_efi_memory_attribute_protocol grub_efi_memory_attribute_protocol_t; +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/cc.h b/include/grub/efi/cc.h deleted file mode 100644 index 978e0cdfe..000000000 --- a/include/grub/efi/cc.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_EFI_CC_H -#define GRUB_EFI_CC_H 1 - -#include -#include -#include - -#define GRUB_EFI_CC_MEASUREMENT_PROTOCOL_GUID \ - { 0x96751a3d, 0x72f4, 0x41a6, \ - { 0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae, 0x6b } \ - }; - -struct grub_efi_cc_version -{ - grub_efi_uint8_t Major; - grub_efi_uint8_t Minor; -}; -typedef struct grub_efi_cc_version grub_efi_cc_version_t; - -/* EFI_CC Type/SubType definition. */ -#define GRUB_EFI_CC_TYPE_NONE 0 -#define GRUB_EFI_CC_TYPE_SEV 1 -#define GRUB_EFI_CC_TYPE_TDX 2 - -struct grub_efi_cc_type -{ - grub_efi_uint8_t Type; - grub_efi_uint8_t SubType; -}; -typedef struct grub_efi_cc_type grub_efi_cc_type_t; - -typedef grub_efi_uint32_t grub_efi_cc_event_log_bitmap_t; -typedef grub_efi_uint32_t grub_efi_cc_event_log_format_t; -typedef grub_efi_uint32_t grub_efi_cc_event_algorithm_bitmap_t; -typedef grub_efi_uint32_t grub_efi_cc_mr_index_t; - -/* Intel TDX measure register index. */ -#define GRUB_TDX_MR_INDEX_MRTD 0 -#define GRUB_TDX_MR_INDEX_RTMR0 1 -#define GRUB_TDX_MR_INDEX_RTMR1 2 -#define GRUB_TDX_MR_INDEX_RTMR2 3 -#define GRUB_TDX_MR_INDEX_RTMR3 4 - -#define GRUB_EFI_CC_EVENT_LOG_FORMAT_TCG_2 0x00000002 -#define GRUB_EFI_CC_BOOT_HASH_ALG_SHA384 0x00000004 -#define GRUB_EFI_CC_EVENT_HEADER_VERSION 1 - -struct grub_efi_cc_event_header -{ - /* Size of the event header itself (sizeof(EFI_TD_EVENT_HEADER)). */ - grub_efi_uint32_t HeaderSize; - - /* - * Header version. For this version of this specification, - * the value shall be 1. - */ - grub_efi_uint16_t HeaderVersion; - - /* Index of the MR that shall be extended. */ - grub_efi_cc_mr_index_t MrIndex; - - /* Type of the event that shall be extended (and optionally logged). */ - grub_efi_uint32_t EventType; -} GRUB_PACKED; -typedef struct grub_efi_cc_event_header grub_efi_cc_event_header_t; - -struct grub_efi_cc_event -{ - /* Total size of the event including the Size component, the header and the Event data. */ - grub_efi_uint32_t Size; - grub_efi_cc_event_header_t Header; - grub_efi_uint8_t Event[0]; -} GRUB_PACKED; -typedef struct grub_efi_cc_event grub_efi_cc_event_t; - -struct grub_efi_cc_boot_service_capability -{ - /* Allocated size of the structure. */ - grub_efi_uint8_t Size; - - /* - * Version of the grub_efi_cc_boot_service_capability_t structure itself. - * For this version of the protocol, the Major version shall be set to 1 - * and the Minor version shall be set to 1. - */ - grub_efi_cc_version_t StructureVersion; - - /* - * Version of the EFI TD protocol. - * For this version of the protocol, the Major version shall be set to 1 - * and the Minor version shall be set to 1. - */ - grub_efi_cc_version_t ProtocolVersion; - - /* Supported hash algorithms. */ - grub_efi_cc_event_algorithm_bitmap_t HashAlgorithmBitmap; - - /* Bitmap of supported event log formats. */ - grub_efi_cc_event_log_bitmap_t SupportedEventLogs; - - /* Indicates the CC type. */ - grub_efi_cc_type_t CcType; -}; -typedef struct grub_efi_cc_boot_service_capability grub_efi_cc_boot_service_capability_t; - -struct grub_efi_cc_protocol -{ - grub_efi_status_t - (__grub_efi_api *get_capability) (struct grub_efi_cc_protocol *this, - grub_efi_cc_boot_service_capability_t *ProtocolCapability); - - grub_efi_status_t - (__grub_efi_api *get_event_log) (struct grub_efi_cc_protocol *this, - grub_efi_cc_event_log_format_t EventLogFormat, - grub_efi_physical_address_t *EventLogLocation, - grub_efi_physical_address_t *EventLogLastEntry, - grub_efi_boolean_t *EventLogTruncated); - - grub_efi_status_t - (__grub_efi_api *hash_log_extend_event) (struct grub_efi_cc_protocol *this, - grub_efi_uint64_t Flags, - grub_efi_physical_address_t DataToHash, - grub_efi_uint64_t DataToHashLen, - grub_efi_cc_event_t *EfiCcEvent); - - grub_efi_status_t - (__grub_efi_api *map_pcr_to_mr_index) (struct grub_efi_cc_protocol *this, - grub_efi_uint32_t PcrIndex, - grub_efi_cc_mr_index_t *MrIndex); -}; -typedef struct grub_efi_cc_protocol grub_efi_cc_protocol_t; - -#endif diff --git a/include/grub/efi/console_control.h b/include/grub/efi/console_control.h index 008ac5896..7c358fcdb 100644 --- a/include/grub/efi/console_control.h +++ b/include/grub/efi/console_control.h @@ -23,8 +23,6 @@ #ifndef GRUB_EFI_CONSOLE_CONTROL_HEADER #define GRUB_EFI_CONSOLE_CONTROL_HEADER 1 -#include - #define GRUB_EFI_CONSOLE_CONTROL_GUID \ { 0xf42f7782, 0x12e, 0x4c12, \ { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } \ @@ -41,18 +39,18 @@ typedef enum grub_efi_screen_mode grub_efi_screen_mode_t; struct grub_efi_console_control_protocol { grub_efi_status_t - (__grub_efi_api *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); + (*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 - (__grub_efi_api *set_mode) (struct grub_efi_console_control_protocol *this, - grub_efi_screen_mode_t mode); + (*set_mode) (struct grub_efi_console_control_protocol *this, + grub_efi_screen_mode_t mode); grub_efi_status_t - (__grub_efi_api *lock_std_in) (struct grub_efi_console_control_protocol *this, - grub_efi_char16_t *password); + (*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; diff --git a/include/grub/efi/debug.h b/include/grub/efi/debug.h deleted file mode 100644 index c2d2a03b0..000000000 --- a/include/grub/efi/debug.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* debug.h - declare variables and functions for EFI debugging support */ - -#ifndef GRUB_EFI_DEBUG_HEADER -#define GRUB_EFI_DEBUG_HEADER 1 - -#include -#include - - -void grub_efi_register_debug_commands (void); - -static inline void -grub_efi_print_gdb_info (void) -{ - grub_addr_t text; - - text = grub_efi_section_addr (".text"); - if (!text) - return; - - grub_printf ("dynamic_load_symbols %p\n", (void *)text); -} - -#endif /* ! GRUB_EFI_DEBUG_HEADER */ diff --git a/include/grub/efi/edid.h b/include/grub/efi/edid.h deleted file mode 100644 index 43c0c4372..000000000 --- a/include/grub/efi/edid.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2012 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_EFI_EDID_HEADER -#define GRUB_EFI_EDID_HEADER 1 - -/* Based on UEFI specification. */ - -#define GRUB_EFI_EDID_ACTIVE_GUID \ - { 0xbd8c1056, 0x9f36, 0x44ec, { 0x92, 0xa8, 0xa6, 0x33, 0x7f, 0x81, 0x79, 0x86 }} - -#define GRUB_EFI_EDID_DISCOVERED_GUID \ - {0x1c0c34f6,0xd380,0x41fa, {0xa0,0x49,0x8a,0xd0,0x6c,0x1a,0x66,0xaa}} - -#define GRUB_EFI_EDID_OVERRIDE_GUID \ - {0x48ecb431,0xfb72,0x45c0, {0xa9,0x22,0xf4,0x58,0xfe,0x4,0xb,0xd5}} - -struct grub_efi_edid_override; - -typedef grub_efi_status_t -(*grub_efi_edid_override_get_edid) (struct grub_efi_edid_override *this, - grub_efi_handle_t *childhandle, - grub_efi_uint32_t *attributes, - grub_efi_uintn_t *edidsize, - grub_efi_uint8_t *edid); -struct grub_efi_edid_override { - grub_efi_edid_override_get_edid get_edid; -}; - -typedef struct grub_efi_edid_override grub_efi_edid_override_t; - - -struct grub_efi_active_edid -{ - grub_uint32_t size_of_edid; - grub_uint8_t *edid; -}; - -#endif diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index a5cd99e5a..5852a476f 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -23,116 +23,42 @@ #include #include #include -#include - -#define GRUB_LINUX_ARM_MAGIC_SIGNATURE 0x016f2818 - -struct linux_arch_kernel_header { - grub_uint32_t code0; - grub_uint32_t code1; - grub_uint64_t reserved[6]; - grub_uint32_t magic; - grub_uint32_t hdr_offset; /* Offset of PE/COFF header. */ - struct grub_pe_image_header pe_image_header; -}; /* Functions. */ -void *EXPORT_FUNC(grub_efi_locate_protocol) (grub_guid_t *protocol, +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_guid_t *protocol, + 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_guid_t *protocol, + grub_efi_guid_t *protocol, grub_efi_uint32_t attributes); -grub_efi_status_t -EXPORT_FUNC(grub_efi_close_protocol) (grub_efi_handle_t handle, grub_guid_t *protocol); 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_real) (grub_efi_physical_address_t address, - grub_efi_uintn_t pages, - grub_efi_allocate_type_t alloctype, - grub_efi_memory_type_t memtype); -void * -EXPORT_FUNC(grub_efi_allocate_fixed) (grub_efi_physical_address_t address, +EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address, grub_efi_uintn_t pages); -void * -EXPORT_FUNC(grub_efi_allocate_any_pages) (grub_efi_uintn_t pages); void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, grub_efi_uintn_t pages); -grub_efi_uintn_t EXPORT_FUNC(grub_efi_find_mmap_size) (void); 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); -void grub_efi_memory_fini (void); 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); -grub_efi_device_path_t * -EXPORT_FUNC(grub_efi_find_last_device_path) (const grub_efi_device_path_t *dp); -grub_efi_device_path_t * -EXPORT_FUNC(grub_efi_duplicate_device_path) (const grub_efi_device_path_t *dp); -grub_err_t EXPORT_FUNC (grub_efi_finish_boot_services) (grub_efi_uintn_t *outbuf_size, void *outbuf, - grub_efi_uintn_t *map_key, - grub_efi_uintn_t *efi_desc_size, - grub_efi_uint32_t *efi_desc_version); +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); -grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable_with_attributes) (const char *variable, - const grub_guid_t *guid, - grub_size_t *datasize_out, - void **data_out, - grub_efi_uint32_t *attributes); -grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable) (const char *variable, - const grub_guid_t *guid, - grub_size_t *datasize_out, - void **data_out); -grub_err_t -EXPORT_FUNC (grub_efi_set_variable_with_attributes) (const char *var, - const grub_guid_t *guid, - void *data, - grub_size_t datasize, - grub_efi_uint32_t attributes); -grub_err_t -EXPORT_FUNC (grub_efi_set_variable) (const char *var, - const grub_guid_t *guid, - void *data, - grub_size_t datasize); -grub_err_t -EXPORT_FUNC (grub_efi_set_variable_to_string) (const char *name, const grub_guid_t *guid, - const char *value, grub_efi_uint32_t attributes); -int -EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, - const grub_efi_device_path_t *dp2); - -extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, - char **device, - char **path); - -void * -EXPORT_FUNC (grub_efi_find_configuration_table) (const grub_guid_t *target_guid); - -#if defined(__arm__) || defined(__aarch64__) || defined(__riscv) || defined(__loongarch__) -void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void); -grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *); -#endif -#include -grub_err_t grub_arch_efi_linux_load_image_header(grub_file_t file, - struct linux_arch_kernel_header *lh); -grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, grub_size_t size, - char *args); - -grub_addr_t grub_efi_section_addr (const char *section); void grub_efi_mm_init (void); void grub_efi_mm_fini (void); @@ -144,11 +70,4 @@ void grub_efi_set_prefix (void); extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table); extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle); -extern int EXPORT_VAR(grub_efi_is_finished); - -struct grub_net_card; - -grub_efi_handle_t -grub_efinet_get_device_handle (struct grub_net_card *card); - #endif /* ! GRUB_EFI_EFI_HEADER */ diff --git a/include/grub/efi/graphics_output.h b/include/grub/efi/graphics_output.h index 044e786b8..a29221919 100644 --- a/include/grub/efi/graphics_output.h +++ b/include/grub/efi/graphics_output.h @@ -28,29 +28,10 @@ typedef enum { GRUB_EFI_GOT_RGBA8, GRUB_EFI_GOT_BGRA8, - GRUB_EFI_GOT_BITMASK, - GRUB_EFI_GOT_BLT_ONLY, + GRUB_EFI_GOT_BITMASK } grub_efi_gop_pixel_format_t; -typedef enum - { - GRUB_EFI_BLT_VIDEO_FILL, - GRUB_EFI_BLT_VIDEO_TO_BLT_BUFFER, - GRUB_EFI_BLT_BUFFER_TO_VIDEO, - GRUB_EFI_BLT_VIDEO_TO_VIDEO, - GRUB_EFI_BLT_OPERATION_MAX - } - grub_efi_gop_blt_operation_t; - -struct grub_efi_gop_blt_pixel -{ - grub_uint8_t blue; - grub_uint8_t green; - grub_uint8_t red; - grub_uint8_t reserved; -}; - struct grub_efi_gop_pixel_bitmask { grub_uint32_t r; @@ -83,26 +64,26 @@ struct grub_efi_gop_mode struct grub_efi_gop; typedef grub_efi_status_t -(__grub_efi_api *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); +(*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_api *grub_efi_gop_set_mode_t) (struct grub_efi_gop *this, - grub_efi_uint32_t mode_number); +(*grub_efi_gop_set_mode_t) (struct grub_efi_gop *this, + grub_efi_uint32_t mode_number); typedef grub_efi_status_t -(__grub_efi_api *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); +(*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 { diff --git a/include/grub/efi/memory.h b/include/grub/efi/memory.h index 08fe62277..e5ea58d67 100644 --- a/include/grub/efi/memory.h +++ b/include/grub/efi/memory.h @@ -22,17 +22,27 @@ #include #include -/* The term "page" in UEFI refers only to a 4 KiB-aligned 4 KiB size region of - memory. It is not concerned with underlying translation management concepts, - but only used as the granule for memory allocations. */ -#define GRUB_EFI_PAGE_SHIFT 12 -#define GRUB_EFI_PAGE_SIZE (1 << GRUB_EFI_PAGE_SHIFT) -#define GRUB_EFI_BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> GRUB_EFI_PAGE_SHIFT) - #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 EXPORT_FUNC(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/pci.h b/include/grub/efi/pci.h deleted file mode 100644 index b17245549..000000000 --- a/include/grub/efi/pci.h +++ /dev/null @@ -1,319 +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 . - */ - -#ifndef GRUB_EFI_PCI_HEADER -#define GRUB_EFI_PCI_HEADER 1 - -#include - -#define GRUB_EFI_PCI_IO_GUID \ - { 0x4cf5b200, 0x68b8, 0x4ca5, { 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x02, 0x9a }} - -#define GRUB_EFI_PCI_ROOT_IO_GUID \ - { 0x2F707EBB, 0x4A1A, 0x11d4, { 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }} - -typedef enum - { - GRUB_EFI_PCI_IO_WIDTH_UINT8, - GRUB_EFI_PCI_IO_WIDTH_UINT16, - GRUB_EFI_PCI_IO_WIDTH_UINT32, - GRUB_EFI_PCI_IO_WIDTH_UINT64, - GRUB_EFI_PCI_IO_WIDTH_FIFO_UINT8, - GRUB_EFI_PCI_IO_WIDTH_FIFO_UINT16, - GRUB_EFI_PCI_IO_WIDTH_FIFO_UINT32, - GRUB_EFI_PCI_IO_WIDTH_FIFO_UINT64, - GRUB_EFI_PCI_IO_WIDTH_FILL_UINT8, - GRUB_EFI_PCI_IO_WIDTH_FILL_UINT16, - GRUB_EFI_PCI_IO_WIDTH_FILL_UINT32, - GRUB_EFI_PCI_IO_WIDTH_FILL_UINT64, - GRUB_EFI_PCI_IO_WIDTH_MAXIMUM, - } - grub_efi_pci_io_width_t; - -struct grub_efi_pci_io; - -typedef grub_efi_status_t -(*grub_efi_pci_io_mem_t) (struct grub_efi_pci_io *this, - grub_efi_pci_io_width_t width, - grub_efi_uint8_t bar_index, - grub_efi_uint64_t offset, - grub_efi_uintn_t count, - void *buffer); - -typedef grub_efi_status_t -(*grub_efi_pci_io_config_t) (struct grub_efi_pci_io *this, - grub_efi_pci_io_width_t width, - grub_efi_uint32_t offset, - grub_efi_uintn_t count, - void *buffer); -typedef struct -{ - grub_efi_pci_io_mem_t read; - grub_efi_pci_io_mem_t write; -} grub_efi_pci_io_access_t; - -typedef struct -{ - grub_efi_pci_io_config_t read; - grub_efi_pci_io_config_t write; -} grub_efi_pci_io_config_access_t; - -typedef enum - { - GRUB_EFI_PCI_IO_OPERATION_BUS_MASTER_READ, - GRUB_EFI_PCI_IO_OPERATION_BUS_MASTER_WRITE, - GRUB_EFI_PCI_IO_OPERATION_BUS_MASTER_COMMON_BUFFER, - GRUB_EFI_PCI_IO_OPERATION_BUS_MASTER_MAXIMUM - } - grub_efi_pci_io_operation_t; - -#define GRUB_EFI_PCI_IO_ATTRIBUTE_ISA_IO 0x0002 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO 0x0004 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY 0x0008 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_VGA_IO 0x0010 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO 0x0020 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO 0x0040 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x0080 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_IO 0x0100 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_MEMORY 0x0200 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_BUS_MASTER 0x0400 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED 0x0800 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE 0x1000 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE 0x2000 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM 0x4000 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE 0x8000 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_ISA_IO_16 0x10000 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 0x20000 -#define GRUB_EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 0x40000 - -typedef enum - { - GRUB_EFI_PCI_IO_ATTRIBUTE_OPERATION_GET, - GRUB_EFI_PCI_IO_ATTRIBUTE_OPERATION_SET, - GRUB_EFI_PCI_IO_ATTRIBUTE_OPERATION_ENABLE, - GRUB_EFI_PCI_IO_ATTRIBUTE_OPERATION_DISABLE, - GRUB_EFI_PCI_IO_ATTRIBUTE_OPERATION_SUPPORTED, - GRUB_EFI_PCI_IO_ATTRIBUTE_OPERATION_MAXIMUM - } - grub_efi_pci_io_attribute_operation_t; - -typedef grub_efi_status_t -(*grub_efi_pci_io_poll_io_mem_t) (struct grub_efi_pci_io *this, - grub_efi_pci_io_width_t width, - grub_efi_uint8_t bar_ndex, - grub_efi_uint64_t offset, - grub_efi_uint64_t mask, - grub_efi_uint64_t value, - grub_efi_uint64_t delay, - grub_efi_uint64_t *result); - -typedef grub_efi_status_t -(*grub_efi_pci_io_copy_mem_t) (struct grub_efi_pci_io *this, - grub_efi_pci_io_width_t width, - grub_efi_uint8_t dest_bar_index, - grub_efi_uint64_t dest_offset, - grub_efi_uint8_t src_bar_index, - grub_efi_uint64_t src_offset, - grub_efi_uintn_t count); - -typedef grub_efi_status_t -(*grub_efi_pci_io_map_t) (struct grub_efi_pci_io *this, - grub_efi_pci_io_operation_t operation, - void *host_address, - grub_efi_uintn_t *number_of_bytes, - grub_efi_uint64_t *device_address, - void **mapping); - -typedef grub_efi_status_t -(*grub_efi_pci_io_unmap_t) (struct grub_efi_pci_io *this, - void *mapping); - -typedef grub_efi_status_t -(*grub_efi_pci_io_allocate_buffer_t) (struct grub_efi_pci_io *this, - grub_efi_allocate_type_t type, - grub_efi_memory_type_t memory_type, - grub_efi_uintn_t pages, - void **host_address, - grub_efi_uint64_t attributes); - -typedef grub_efi_status_t -(*grub_efi_pci_io_free_buffer_t) (struct grub_efi_pci_io *this, - grub_efi_allocate_type_t type, - grub_efi_memory_type_t memory_type, - grub_efi_uintn_t pages, - void **host_address, - grub_efi_uint64_t attributes); - -typedef grub_efi_status_t -(*grub_efi_pci_io_flush_t) (struct grub_efi_pci_io *this); - -typedef grub_efi_status_t -(*grub_efi_pci_io_get_location_t) (struct grub_efi_pci_io *this, - grub_efi_uintn_t *segment_number, - grub_efi_uintn_t *bus_number, - grub_efi_uintn_t *device_number, - grub_efi_uintn_t *function_number); - -typedef grub_efi_status_t -(*grub_efi_pci_io_attributes_t) (struct grub_efi_pci_io *this, - grub_efi_pci_io_attribute_operation_t operation, - grub_efi_uint64_t attributes, - grub_efi_uint64_t *result); - -typedef grub_efi_status_t -(*grub_efi_pci_io_get_bar_attributes_t) (struct grub_efi_pci_io *this, - grub_efi_uint8_t bar_index, - grub_efi_uint64_t *supports, - void **resources); - -typedef grub_efi_status_t -(*grub_efi_pci_io_set_bar_attributes_t) (struct grub_efi_pci_io *this, - grub_efi_uint64_t attributes, - grub_efi_uint8_t bar_index, - grub_efi_uint64_t *offset, - grub_efi_uint64_t *length); -struct grub_efi_pci_io { - grub_efi_pci_io_poll_io_mem_t poll_mem; - grub_efi_pci_io_poll_io_mem_t poll_io; - grub_efi_pci_io_access_t mem; - grub_efi_pci_io_access_t io; - grub_efi_pci_io_config_access_t pci; - grub_efi_pci_io_copy_mem_t copy_mem; - grub_efi_pci_io_map_t map; - grub_efi_pci_io_unmap_t unmap; - grub_efi_pci_io_allocate_buffer_t allocate_buffer; - grub_efi_pci_io_free_buffer_t free_buffer; - grub_efi_pci_io_flush_t flush; - grub_efi_pci_io_get_location_t get_location; - grub_efi_pci_io_attributes_t attributes; - grub_efi_pci_io_get_bar_attributes_t get_bar_attributes; - grub_efi_pci_io_set_bar_attributes_t set_bar_attributes; - grub_efi_uint64_t rom_size; - void *rom_image; -}; -typedef struct grub_efi_pci_io grub_efi_pci_io_t; - -struct grub_efi_pci_root_io; - -typedef struct -{ - grub_efi_status_t(*read) (struct grub_efi_pci_root_io *this, - grub_efi_pci_io_width_t width, - grub_efi_uint64_t address, - grub_efi_uintn_t count, - void *buffer); - grub_efi_status_t(*write) (struct grub_efi_pci_root_io *this, - grub_efi_pci_io_width_t width, - grub_efi_uint64_t address, - grub_efi_uintn_t count, - void *buffer); -} grub_efi_pci_root_io_access_t; - -typedef enum - { - GRUB_EFI_PCI_ROOT_IO_OPERATION_BUS_MASTER_READ, - GRUB_EFI_PCI_ROOT_IO_OPERATION_BUS_MASTER_WRITE, - GRUB_EFI_PCI_ROOT_IO_OPERATION_BUS_MASTER_COMMON_BUFFER, - GRUB_EFI_PCI_ROOT_IO_OPERATION_BUS_MASTER_READ_64, - GRUB_EFI_PCI_ROOT_IO_OPERATION_BUS_MASTER_WRITE_64, - GRUB_EFI_PCI_ROOT_IO_OPERATION_BUS_MASTER_COMMON_BUFFER_64, - GRUB_EFI_PCI_ROOT_IO_OPERATION_BUS_MASTER_MAXIMUM - } - grub_efi_pci_root_io_operation_t; - -typedef grub_efi_status_t -(*grub_efi_pci_root_io_poll_io_mem_t) (struct grub_efi_pci_root_io *this, - grub_efi_pci_io_width_t width, - grub_efi_uint64_t address, - grub_efi_uint64_t mask, - grub_efi_uint64_t value, - grub_efi_uint64_t delay, - grub_efi_uint64_t *result); - -typedef grub_efi_status_t -(*grub_efi_pci_root_io_copy_mem_t) (struct grub_efi_pci_root_io *this, - grub_efi_pci_io_width_t width, - grub_efi_uint64_t dest_offset, - grub_efi_uint64_t src_offset, - grub_efi_uintn_t count); - - -typedef grub_efi_status_t -(*grub_efi_pci_root_io_map_t) (struct grub_efi_pci_root_io *this, - grub_efi_pci_root_io_operation_t operation, - void *host_address, - grub_efi_uintn_t *number_of_bytes, - grub_efi_uint64_t *device_address, - void **mapping); - -typedef grub_efi_status_t -(*grub_efi_pci_root_io_unmap_t) (struct grub_efi_pci_root_io *this, - void *mapping); - -typedef grub_efi_status_t -(*grub_efi_pci_root_io_allocate_buffer_t) (struct grub_efi_pci_root_io *this, - grub_efi_allocate_type_t type, - grub_efi_memory_type_t memory_type, - grub_efi_uintn_t pages, - void **host_address, - grub_efi_uint64_t attributes); - -typedef grub_efi_status_t -(*grub_efi_pci_root_io_free_buffer_t) (struct grub_efi_pci_root_io *this, - grub_efi_uintn_t pages, - void **host_address); - -typedef grub_efi_status_t -(*grub_efi_pci_root_io_flush_t) (struct grub_efi_pci_root_io *this); - -typedef grub_efi_status_t -(*grub_efi_pci_root_io_get_attributes_t) (struct grub_efi_pci_root_io *this, - grub_efi_uint64_t *supports, - void **resources); - -typedef grub_efi_status_t -(*grub_efi_pci_root_io_set_attributes_t) (struct grub_efi_pci_root_io *this, - grub_efi_uint64_t attributes, - grub_efi_uint64_t *offset, - grub_efi_uint64_t *length); - -typedef grub_efi_status_t -(*grub_efi_pci_root_io_configuration_t) (struct grub_efi_pci_root_io *this, - void **resources); - -struct grub_efi_pci_root_io { - grub_efi_handle_t parent; - grub_efi_pci_root_io_poll_io_mem_t poll_mem; - grub_efi_pci_root_io_poll_io_mem_t poll_io; - grub_efi_pci_root_io_access_t mem; - grub_efi_pci_root_io_access_t io; - grub_efi_pci_root_io_access_t pci; - grub_efi_pci_root_io_copy_mem_t copy_mem; - grub_efi_pci_root_io_map_t map; - grub_efi_pci_root_io_unmap_t unmap; - grub_efi_pci_root_io_allocate_buffer_t allocate_buffer; - grub_efi_pci_root_io_free_buffer_t free_buffer; - grub_efi_pci_root_io_flush_t flush; - grub_efi_pci_root_io_get_attributes_t get_attributes; - grub_efi_pci_root_io_set_attributes_t set_attributes; - grub_efi_pci_root_io_configuration_t configuration; -}; - -typedef struct grub_efi_pci_root_io grub_efi_pci_root_io_t; - -#endif /* !GRUB_EFI_PCI_HEADER */ diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h index 9887e14b2..21b56ae27 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h @@ -20,7 +20,6 @@ #define GRUB_EFI_PE32_HEADER 1 #include -#include /* The MSDOS compatibility stub. This was copied from the output of objcopy, and it is not necessary to care about what this means. */ @@ -46,30 +45,11 @@ #define GRUB_PE32_MSDOS_STUB_SIZE 0x80 -#define GRUB_PE32_MAGIC 0x5a4d - -struct grub_msdos_image_header -{ - /* This is always 'MZ'. (GRUB_PE32_MAGIC) */ - grub_uint16_t msdos_magic; - - grub_uint16_t reserved[29]; - - /* The file offset of the PE image header. */ - grub_uint32_t pe_image_header_offset; -}; - /* 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. - - However, there is firmware showing up in the field now with - page alignment constraints to guarantee that page protection - bits take effect. Because currently existing GRUB code can not - properly distinguish between in-memory and in-file layout, let's - bump all alignment to GRUB_EFI_PAGE_SIZE. */ -#define GRUB_PE32_SECTION_ALIGNMENT GRUB_EFI_PAGE_SIZE + 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 @@ -83,15 +63,8 @@ struct grub_pe32_coff_header grub_uint16_t characteristics; }; -#define GRUB_PE32_MACHINE_I386 0x14c -#define GRUB_PE32_MACHINE_IA64 0x200 -#define GRUB_PE32_MACHINE_X86_64 0x8664 -#define GRUB_PE32_MACHINE_ARMTHUMB_MIXED 0x01c2 -#define GRUB_PE32_MACHINE_ARM64 0xAA64 -#define GRUB_PE32_MACHINE_LOONGARCH32 0x6232 -#define GRUB_PE32_MACHINE_LOONGARCH64 0x6264 -#define GRUB_PE32_MACHINE_RISCV32 0x5032 -#define GRUB_PE32_MACHINE_RISCV64 0x5064 +#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 @@ -126,8 +99,12 @@ struct grub_pe32_optional_header 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; @@ -144,66 +121,22 @@ struct grub_pe32_optional_header 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; - 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; -}; - -struct grub_pe64_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; - - grub_uint64_t image_base; - - 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; +#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; @@ -226,13 +159,18 @@ struct grub_pe64_optional_header struct grub_pe32_data_directory reserved_entry; }; +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + #define GRUB_PE32_PE32_MAGIC 0x10b -#define GRUB_PE32_PE64_MAGIC 0x20b + +#else + +#define GRUB_PE32_PE32_MAGIC 0x20b + +#endif #define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION 10 -#define GRUB_PE32_NX_COMPAT 0x0100 - #define GRUB_PE32_NUM_DATA_DIRECTORIES 16 struct grub_pe32_section_table @@ -267,29 +205,20 @@ struct grub_pe32_section_table #define GRUB_PE32_SCN_ALIGN_SHIFT 20 #define GRUB_PE32_SCN_ALIGN_MASK 7 -#define GRUB_PE32_SIGNATURE_SIZE 4 -#if GRUB_TARGET_SIZEOF_VOID_P == 8 -#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE64_MAGIC -#else -#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE32_MAGIC -#endif - -struct grub_pe_image_header +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[GRUB_PE32_SIGNATURE_SIZE]; + char signature[4]; /* The COFF file header. */ struct grub_pe32_coff_header coff_header; -#if GRUB_TARGET_SIZEOF_VOID_P == 8 - /* The Optional header. */ - struct grub_pe64_optional_header optional_header; -#else /* The Optional header. */ struct grub_pe32_optional_header optional_header; -#endif }; struct grub_pe32_fixup_block @@ -301,24 +230,17 @@ struct grub_pe32_fixup_block #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_ARM_MOV32A 5 -#define GRUB_PE32_REL_BASED_RISCV_HI20 5 -#define GRUB_PE32_REL_BASED_SECTION 6 -#define GRUB_PE32_REL_BASED_REL 7 -#define GRUB_PE32_REL_BASED_ARM_MOV32T 7 -#define GRUB_PE32_REL_BASED_RISCV_LOW12I 7 -#define GRUB_PE32_REL_BASED_RISCV_LOW12S 8 -#define GRUB_PE32_REL_BASED_LOONGARCH32_MARK_LA 8 -#define GRUB_PE32_REL_BASED_LOONGARCH64_MARK_LA 8 -#define GRUB_PE32_REL_BASED_IA64_IMM64 9 -#define GRUB_PE32_REL_BASED_DIR64 10 -#define GRUB_PE32_REL_BASED_HIGH3ADJ 11 +#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 { @@ -333,7 +255,7 @@ struct grub_pe32_symbol grub_uint16_t type; grub_uint8_t storage_class; grub_uint8_t num_aux; -} GRUB_PACKED; +} __attribute__ ((packed)); #define GRUB_PE32_SYM_CLASS_EXTERNAL 2 #define GRUB_PE32_SYM_CLASS_STATIC 3 @@ -346,7 +268,7 @@ struct grub_pe32_reloc grub_uint32_t offset; grub_uint32_t symtab_index; grub_uint16_t type; -} GRUB_PACKED; +} __attribute__ ((packed)); #define GRUB_PE32_REL_I386_DIR32 0x6 #define GRUB_PE32_REL_I386_REL32 0x14 diff --git a/include/grub/efi/sb.h b/include/grub/efi/sb.h deleted file mode 100644 index 49a9ad01c..000000000 --- a/include/grub/efi/sb.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2020 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_EFI_SB_H -#define GRUB_EFI_SB_H 1 - -#include -#include - -#define GRUB_EFI_SECUREBOOT_MODE_UNSET 0 -#define GRUB_EFI_SECUREBOOT_MODE_UNKNOWN 1 -#define GRUB_EFI_SECUREBOOT_MODE_DISABLED 2 -#define GRUB_EFI_SECUREBOOT_MODE_ENABLED 3 - -#ifdef GRUB_MACHINE_EFI -extern grub_uint8_t -EXPORT_FUNC (grub_efi_get_secureboot) (void); - -extern bool -EXPORT_FUNC (grub_is_shim_lock_enabled) (void); - -extern void -grub_shim_lock_verifier_setup (void); -#else -static inline grub_uint8_t -grub_efi_get_secureboot (void) -{ - return GRUB_EFI_SECUREBOOT_MODE_UNSET; -} -#endif -#endif /* GRUB_EFI_SB_H */ diff --git a/grub-core/kern/loongarch64/efi/startup.S b/include/grub/efi/time.h similarity index 65% rename from grub-core/kern/loongarch64/efi/startup.S rename to include/grub/efi/time.h index 87cfb23ea..540f6fc04 100644 --- a/grub-core/kern/loongarch64/efi/startup.S +++ b/include/grub/efi/time.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 Free Software Foundation, Inc. + * 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 @@ -16,19 +16,15 @@ * along with GRUB. If not, see . */ +#ifndef GRUB_EFI_TIME_HEADER +#define GRUB_EFI_TIME_HEADER 1 + #include - .file "startup.S" - .text +/* This is destined to overflow when one hour passes by. */ +#define GRUB_TICKS_PER_SECOND ((1UL << 31) / 60 / 60 * 2) -FUNCTION(_start) - /* - * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in $a1/$a0. - */ +/* Return the real time in ticks. */ +grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void); - la $a2, EXT_C(grub_efi_image_handle) - st.d $a0, $a2, 0 - la $a2, EXT_C(grub_efi_system_table) - st.d $a1, $a2, 0 - - b EXT_C(grub_main) +#endif /* ! GRUB_EFI_TIME_HEADER */ diff --git a/include/grub/efi/tpm.h b/include/grub/efi/tpm.h deleted file mode 100644 index 6c6802ee5..000000000 --- a/include/grub/efi/tpm.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_EFI_TPM_HEADER -#define GRUB_EFI_TPM_HEADER 1 - -#define EFI_TPM_GUID {0xf541796d, 0xa62e, 0x4954, {0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd }}; -#define EFI_TPM2_GUID {0x607f766c, 0x7455, 0x42be, {0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f }}; - -#define TCG_ALG_SHA 0x00000004 - -/* These structs are as defined in the TCG EFI Protocol Specification, family 2.0. */ - -struct __TCG_VERSION -{ - grub_efi_uint8_t Major; - grub_efi_uint8_t Minor; - grub_efi_uint8_t RevMajor; - grub_efi_uint8_t RevMinor; -}; -typedef struct __TCG_VERSION TCG_VERSION; - -struct __TCG_EFI_BOOT_SERVICE_CAPABILITY -{ - /* Size of this structure. */ - grub_efi_uint8_t Size; - TCG_VERSION StructureVersion; - TCG_VERSION ProtocolSpecVersion; - /* Hash algorithms supported by this TPM. */ - grub_efi_uint8_t HashAlgorithmBitmap; - /* 1 if TPM present. */ - char TPMPresentFlag; - /* 1 if TPM deactivated. */ - char TPMDeactivatedFlag; -}; -typedef struct __TCG_EFI_BOOT_SERVICE_CAPABILITY TCG_EFI_BOOT_SERVICE_CAPABILITY; - -struct tdTCG_PCR_EVENT -{ - grub_efi_uint32_t PCRIndex; - grub_efi_uint32_t EventType; - grub_efi_uint8_t digest[20]; - grub_efi_uint32_t EventSize; - grub_efi_uint8_t Event[1]; -}; -typedef struct tdTCG_PCR_EVENT TCG_PCR_EVENT; - -struct grub_efi_tpm_protocol -{ - grub_efi_status_t - (__grub_efi_api *status_check) (struct grub_efi_tpm_protocol *this, - TCG_EFI_BOOT_SERVICE_CAPABILITY *ProtocolCapability, - grub_efi_uint32_t *TCGFeatureFlags, - grub_efi_physical_address_t *EventLogLocation, - grub_efi_physical_address_t *EventLogLastEntry); - - grub_efi_status_t - (__grub_efi_api *hash_all) (struct grub_efi_tpm_protocol *this, - grub_efi_uint8_t *HashData, - grub_efi_uint64_t HashLen, - grub_efi_uint32_t AlgorithmId, - grub_efi_uint64_t *HashedDataLen, - grub_efi_uint8_t **HashedDataResult); - - grub_efi_status_t - (__grub_efi_api *log_event) (struct grub_efi_tpm_protocol *this, - TCG_PCR_EVENT *TCGLogData, - grub_efi_uint32_t *EventNumber, - grub_efi_uint32_t Flags); - - grub_efi_status_t - (__grub_efi_api *pass_through_to_tpm) (struct grub_efi_tpm_protocol *this, - grub_efi_uint32_t TpmInputParameterBlockSize, - grub_efi_uint8_t *TpmInputParameterBlock, - grub_efi_uint32_t TpmOutputParameterBlockSize, - grub_efi_uint8_t *TpmOutputParameterBlock); - - grub_efi_status_t - (__grub_efi_api *log_extend_event) (struct grub_efi_tpm_protocol *this, - grub_efi_physical_address_t HashData, - grub_efi_uint64_t HashDataLen, - grub_efi_uint32_t AlgorithmId, - TCG_PCR_EVENT *TCGLogData, - grub_efi_uint32_t *EventNumber, - grub_efi_physical_address_t *EventLogLastEntry); -}; - -typedef struct grub_efi_tpm_protocol grub_efi_tpm_protocol_t; - -typedef grub_efi_uint32_t EFI_TCG2_EVENT_LOG_BITMAP; -typedef grub_efi_uint32_t EFI_TCG2_EVENT_LOG_FORMAT; -typedef grub_efi_uint32_t EFI_TCG2_EVENT_ALGORITHM_BITMAP; - -struct tdEFI_TCG2_VERSION -{ - grub_efi_uint8_t Major; - grub_efi_uint8_t Minor; -} GRUB_PACKED; -typedef struct tdEFI_TCG2_VERSION EFI_TCG2_VERSION; - -struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY -{ - grub_efi_uint8_t Size; - EFI_TCG2_VERSION StructureVersion; - EFI_TCG2_VERSION ProtocolVersion; - EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap; - EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs; - grub_efi_boolean_t TPMPresentFlag; - grub_efi_uint16_t MaxCommandSize; - grub_efi_uint16_t MaxResponseSize; - grub_efi_uint32_t ManufacturerID; - grub_efi_uint32_t NumberOfPcrBanks; - EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks; -}; -typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY EFI_TCG2_BOOT_SERVICE_CAPABILITY; - -typedef grub_efi_uint32_t TCG_PCRINDEX; -typedef grub_efi_uint32_t TCG_EVENTTYPE; - -struct tdEFI_TCG2_EVENT_HEADER -{ - grub_efi_uint32_t HeaderSize; - grub_efi_uint16_t HeaderVersion; - TCG_PCRINDEX PCRIndex; - TCG_EVENTTYPE EventType; -} GRUB_PACKED; -typedef struct tdEFI_TCG2_EVENT_HEADER EFI_TCG2_EVENT_HEADER; - -struct tdEFI_TCG2_EVENT -{ - grub_efi_uint32_t Size; - EFI_TCG2_EVENT_HEADER Header; - grub_efi_uint8_t Event[1]; -} GRUB_PACKED; -typedef struct tdEFI_TCG2_EVENT EFI_TCG2_EVENT; - -struct grub_efi_tpm2_protocol -{ - grub_efi_status_t - (__grub_efi_api *get_capability) (struct grub_efi_tpm2_protocol *this, - EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability); - - grub_efi_status_t - (__grub_efi_api *get_event_log) (struct grub_efi_tpm2_protocol *this, - EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat, - grub_efi_physical_address_t *EventLogLocation, - grub_efi_physical_address_t *EventLogLastEntry, - grub_efi_boolean_t *EventLogTruncated); - - grub_efi_status_t - (__grub_efi_api *hash_log_extend_event) (struct grub_efi_tpm2_protocol *this, - grub_efi_uint64_t Flags, - grub_efi_physical_address_t DataToHash, - grub_efi_uint64_t DataToHashLen, - EFI_TCG2_EVENT *EfiTcgEvent); - - grub_efi_status_t - (__grub_efi_api *submit_command) (struct grub_efi_tpm2_protocol *this, - grub_efi_uint32_t InputParameterBlockSize, - grub_efi_uint8_t *InputParameterBlock, - grub_efi_uint32_t OutputParameterBlockSize, - grub_efi_uint8_t *OutputParameterBlock); - - grub_efi_status_t - (__grub_efi_api *get_active_pcr_banks) (struct grub_efi_tpm2_protocol *this, - grub_efi_uint32_t *ActivePcrBanks); - - grub_efi_status_t - (__grub_efi_api *set_active_pcr_banks) (struct grub_efi_tpm2_protocol *this, - grub_efi_uint32_t ActivePcrBanks); - - grub_efi_status_t - (__grub_efi_api *get_result_of_set_active_pcr_banks) (struct grub_efi_tpm2_protocol *this, - grub_efi_uint32_t *OperationPresent, - grub_efi_uint32_t *Response); -}; - -typedef struct grub_efi_tpm2_protocol grub_efi_tpm2_protocol_t; - -#endif diff --git a/include/grub/efi/uga_draw.h b/include/grub/efi/uga_draw.h index 1ea157a7e..93504307c 100644 --- a/include/grub/efi/uga_draw.h +++ b/include/grub/efi/uga_draw.h @@ -32,7 +32,7 @@ enum grub_efi_uga_blt_operation GRUB_EFI_UGA_VIDEO_TO_BLT, GRUB_EFI_UGA_BLT_TO_VIDEO, GRUB_EFI_UGA_VIDEO_TO_VIDEO, - GRUB_EFI_UGA_BLT_MAX + GRUB_EFI_UGA_GLT_MAX }; struct grub_efi_uga_pixel @@ -46,30 +46,30 @@ struct grub_efi_uga_pixel struct grub_efi_uga_draw_protocol { grub_efi_status_t - (__grub_efi_api *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); + (*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 - (__grub_efi_api *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); + (*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 - (__grub_efi_api *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); + (*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; diff --git a/include/grub/efiemu/efiemu.h b/include/grub/efiemu/efiemu.h index d6a868e94..3980d32cd 100644 --- a/include/grub/efiemu/efiemu.h +++ b/include/grub/efiemu/efiemu.h @@ -21,7 +21,6 @@ #include #include -#include #define GRUB_EFIEMU_PAGESIZE 4096 @@ -41,7 +40,7 @@ struct grub_efi_system_table32 grub_efi_uint32_t boot_services; grub_efi_uint32_t num_table_entries; grub_efi_uint32_t configuration_table; -} GRUB_PACKED; +} __attribute__ ((packed)); typedef struct grub_efi_system_table32 grub_efi_system_table32_t; struct grub_efi_system_table64 @@ -60,7 +59,7 @@ struct grub_efi_system_table64 grub_efi_uint64_t boot_services; grub_efi_uint64_t num_table_entries; grub_efi_uint64_t configuration_table; -} GRUB_PACKED; +} __attribute__ ((packed)); typedef struct grub_efi_system_table64 grub_efi_system_table64_t; struct grub_efiemu_runtime_services32 @@ -77,7 +76,7 @@ struct grub_efiemu_runtime_services32 grub_efi_uint32_t set_variable; grub_efi_uint32_t get_next_high_monotonic_count; grub_efi_uint32_t reset_system; -} GRUB_PACKED; +} __attribute__ ((packed)); typedef struct grub_efiemu_runtime_services32 grub_efiemu_runtime_services32_t; struct grub_efiemu_runtime_services64 @@ -94,7 +93,7 @@ struct grub_efiemu_runtime_services64 grub_efi_uint64_t set_variable; grub_efi_uint64_t get_next_high_monotonic_count; grub_efi_uint64_t reset_system; -} GRUB_PACKED; +} __attribute__ ((packed)); typedef struct grub_efiemu_runtime_services64 grub_efiemu_runtime_services64_t; extern grub_efi_system_table32_t *grub_efiemu_system_table32; @@ -114,9 +113,9 @@ extern grub_efi_system_table64_t *grub_efiemu_system_table64; : (grub_efiemu_system_table32->x \ = (y))) #define GRUB_EFIEMU_SYSTEM_TABLE_PTR(x) ((grub_efiemu_sizeof_uintn_t () == 8)\ - ? (void *) (grub_addr_t) \ + ? UINT_TO_PTR \ (grub_efiemu_system_table64->x) \ - : (void *) (grub_addr_t) \ + : UINT_TO_PTR \ (grub_efiemu_system_table32->x)) #define GRUB_EFIEMU_SYSTEM_TABLE_VAR(x) ((grub_efiemu_sizeof_uintn_t () == 8) \ ? (void *) \ @@ -152,12 +151,9 @@ struct grub_efiemu_elf_sym 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, - const char *filename, - grub_size_t core_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, const char *filename, - grub_size_t core_size, +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, @@ -168,34 +164,33 @@ grub_err_t grub_efiemu_loadcore_load64 (void *core, 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, - const char *filename); +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_guid_t guid; + grub_efi_guid_t guid; void * (*get_table) (void *data); void (*unload) (void *data); void *data; }; struct grub_efiemu_configuration_table32 { - grub_packed_guid_t vendor_guid; + grub_efi_guid_t vendor_guid; grub_efi_uint32_t vendor_table; -} GRUB_PACKED; +} __attribute__ ((packed)); typedef struct grub_efiemu_configuration_table32 grub_efiemu_configuration_table32_t; struct grub_efiemu_configuration_table64 { - grub_packed_guid_t vendor_guid; + grub_efi_guid_t vendor_guid; grub_efi_uint64_t vendor_table; -} GRUB_PACKED; +} __attribute__ ((packed)); typedef struct grub_efiemu_configuration_table64 grub_efiemu_configuration_table64_t; -grub_err_t grub_efiemu_unregister_configuration_table (grub_guid_t guid); +grub_err_t grub_efiemu_unregister_configuration_table (grub_efi_guid_t guid); grub_err_t -grub_efiemu_register_configuration_table (grub_guid_t guid, +grub_efiemu_register_configuration_table (grub_efi_guid_t guid, void * (*get_table) (void *data), void (*unload) (void *data), void *data); @@ -204,9 +199,15 @@ grub_efiemu_register_configuration_table (grub_guid_t guid, 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); @@ -216,20 +217,20 @@ int grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size, grub_efi_uintn_t *map_key, grub_efi_uintn_t *descriptor_size, grub_efi_uint32_t *descriptor_version); - - grub_err_t -grub_efiemu_finish_boot_services (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 (grub_memory_hook_t hook, void *hook_data); +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, @@ -269,7 +270,8 @@ grub_err_t grub_efiemu_write_value (void * addr, grub_uint32_t value, int minus_handle, int ptv_needed, int size); grub_err_t grub_efiemu_write_sym_markers (void); grub_err_t grub_efiemu_pnvram (void); -const char *grub_efiemu_get_default_core_name (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); @@ -281,6 +283,4 @@ grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size, __attribute__ ((unused)), grub_efi_memory_descriptor_t *virtual_map); -grub_err_t grub_machine_efiemu_init_tables (void); - #endif /* ! GRUB_EFI_EMU_HEADER */ diff --git a/include/grub/efiemu/runtime.h b/include/grub/efiemu/runtime.h index 2ff429845..1eb474a5d 100644 --- a/include/grub/efiemu/runtime.h +++ b/include/grub/efiemu/runtime.h @@ -25,13 +25,13 @@ struct grub_efiemu_ptv_rel grub_efi_memory_type_t plustype; grub_efi_memory_type_t minustype; grub_uint32_t size; -} GRUB_PACKED; +} __attribute__ ((packed)); struct efi_variable { - grub_packed_guid_t guid; + grub_efi_guid_t guid; grub_uint32_t namelen; grub_uint32_t size; grub_efi_uint32_t attributes; -} GRUB_PACKED; +} __attribute__ ((packed)); #endif /* ! GRUB_EFI_EMU_RUNTIME_HEADER */ diff --git a/include/grub/elf.h b/include/grub/elf.h index bd313a70b..e54989cde 100644 --- a/include/grub/elf.h +++ b/include/grub/elf.h @@ -23,7 +23,6 @@ /* Standard ELF types. */ #include -#include /* Type for a 16-bit quantity. */ typedef grub_uint16_t Elf32_Half; @@ -57,9 +56,6 @@ typedef grub_uint16_t Elf64_Section; typedef Elf32_Half Elf32_Versym; typedef Elf64_Half Elf64_Versym; -/* Type for number of section header table entries */ -typedef Elf32_Word Elf32_Shnum; -typedef Elf64_Xword Elf64_Shnum; /* The ELF file header. This appears at the start of every ELF file. */ @@ -149,7 +145,6 @@ typedef struct #define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ #define ELFOSABI_MODESTO 11 /* Novell Modesto. */ #define ELFOSABI_OPENBSD 12 /* OpenBSD. */ -#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ #define ELFOSABI_ARM 97 /* ARM */ #define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ @@ -250,9 +245,6 @@ typedef struct #define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ #define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ #define EM_NUM 95 -#define EM_AARCH64 183 /* ARM 64-bit architecture */ -#define EM_RISCV 243 /* RISC-V */ -#define EM_LOONGARCH 258 /* LoongArch */ /* If it is necessary to assign new unofficial EM_* values, please pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the @@ -563,7 +555,6 @@ typedef struct #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_GNU_STACK 0x6474e551 /* GCC stack segment */ #define PT_LOSUNW 0x6ffffffa #define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ #define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ @@ -571,7 +562,6 @@ typedef struct #define PT_HIOS 0x6fffffff /* End of OS-specific */ #define PT_LOPROC 0x70000000 /* Start of processor-specific */ #define PT_HIPROC 0x7fffffff /* End of processor-specific */ -#define PN_XNUM 0xffff /* Legal values for p_flags (segment flags). */ @@ -1139,7 +1129,6 @@ typedef struct #define R_X86_64_PC16 13 #define R_X86_64_8 14 #define R_X86_64_PC8 15 -#define R_X86_64_PC64 24 /* Legal values for ST_TYPE subfield of st_info (symbol type). */ @@ -1865,148 +1854,148 @@ typedef Elf32_Addr Elf32_Conflict; flag */ /* PowerPC relocations defined by the ABIs */ -#define GRUB_ELF_R_PPC_NONE 0 -#define GRUB_ELF_R_PPC_ADDR32 1 /* 32bit absolute address */ -#define GRUB_ELF_R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ -#define GRUB_ELF_R_PPC_ADDR16 3 /* 16bit absolute address */ -#define GRUB_ELF_R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ -#define GRUB_ELF_R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ -#define GRUB_ELF_R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ -#define GRUB_ELF_R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ -#define GRUB_ELF_R_PPC_ADDR14_BRTAKEN 8 -#define GRUB_ELF_R_PPC_ADDR14_BRNTAKEN 9 -#define GRUB_ELF_R_PPC_REL24 10 /* PC relative 26 bit */ -#define GRUB_ELF_R_PPC_REL14 11 /* PC relative 16 bit */ -#define GRUB_ELF_R_PPC_REL14_BRTAKEN 12 -#define GRUB_ELF_R_PPC_REL14_BRNTAKEN 13 -#define GRUB_ELF_R_PPC_GOT16 14 -#define GRUB_ELF_R_PPC_GOT16_LO 15 -#define GRUB_ELF_R_PPC_GOT16_HI 16 -#define GRUB_ELF_R_PPC_GOT16_HA 17 -#define GRUB_ELF_R_PPC_PLTREL24 18 -#define GRUB_ELF_R_PPC_COPY 19 -#define GRUB_ELF_R_PPC_GLOB_DAT 20 -#define GRUB_ELF_R_PPC_JMP_SLOT 21 -#define GRUB_ELF_R_PPC_RELATIVE 22 -#define GRUB_ELF_R_PPC_LOCAL24PC 23 -#define GRUB_ELF_R_PPC_UADDR32 24 -#define GRUB_ELF_R_PPC_UADDR16 25 -#define GRUB_ELF_R_PPC_REL32 26 -#define GRUB_ELF_R_PPC_PLT32 27 -#define GRUB_ELF_R_PPC_PLTREL32 28 -#define GRUB_ELF_R_PPC_PLT16_LO 29 -#define GRUB_ELF_R_PPC_PLT16_HI 30 -#define GRUB_ELF_R_PPC_PLT16_HA 31 -#define GRUB_ELF_R_PPC_SDAREL16 32 -#define GRUB_ELF_R_PPC_SECTOFF 33 -#define GRUB_ELF_R_PPC_SECTOFF_LO 34 -#define GRUB_ELF_R_PPC_SECTOFF_HI 35 -#define GRUB_ELF_R_PPC_SECTOFF_HA 36 +#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 GRUB_ELF_R_PPC_NUM 37 +#define R_PPC_NUM 37 /* PowerPC64 relocations defined by the ABIs */ -#define GRUB_ELF_R_PPC64_NONE GRUB_ELF_R_PPC_NONE -#define GRUB_ELF_R_PPC64_ADDR32 GRUB_ELF_R_PPC_ADDR32 /* 32bit absolute address. */ -#define GRUB_ELF_R_PPC64_ADDR24 GRUB_ELF_R_PPC_ADDR24 /* 26bit address, word aligned. */ -#define GRUB_ELF_R_PPC64_ADDR16 GRUB_ELF_R_PPC_ADDR16 /* 16bit absolute address. */ -#define GRUB_ELF_R_PPC64_ADDR16_LO GRUB_ELF_R_PPC_ADDR16_LO /* lower 16bits of abs. address. */ -#define GRUB_ELF_R_PPC64_ADDR16_HI GRUB_ELF_R_PPC_ADDR16_HI /* high 16bits of abs. address. */ -#define GRUB_ELF_R_PPC64_ADDR16_HA GRUB_ELF_R_PPC_ADDR16_HA /* adjusted high 16bits. */ -#define GRUB_ELF_R_PPC64_ADDR14 GRUB_ELF_R_PPC_ADDR14 /* 16bit address, word aligned. */ -#define GRUB_ELF_R_PPC64_ADDR14_BRTAKEN GRUB_ELF_R_PPC_ADDR14_BRTAKEN -#define GRUB_ELF_R_PPC64_ADDR14_BRNTAKEN GRUB_ELF_R_PPC_ADDR14_BRNTAKEN -#define GRUB_ELF_R_PPC64_REL24 GRUB_ELF_R_PPC_REL24 /* PC relative 26 bit, word aligned. */ -#define GRUB_ELF_R_PPC64_REL14 GRUB_ELF_R_PPC_REL14 /* PC relative 16 bit. */ -#define GRUB_ELF_R_PPC64_REL14_BRTAKEN GRUB_ELF_R_PPC_REL14_BRTAKEN -#define GRUB_ELF_R_PPC64_REL14_BRNTAKEN GRUB_ELF_R_PPC_REL14_BRNTAKEN -#define GRUB_ELF_R_PPC64_GOT16 GRUB_ELF_R_PPC_GOT16 -#define GRUB_ELF_R_PPC64_GOT16_LO GRUB_ELF_R_PPC_GOT16_LO -#define GRUB_ELF_R_PPC64_GOT16_HI GRUB_ELF_R_PPC_GOT16_HI -#define GRUB_ELF_R_PPC64_GOT16_HA GRUB_ELF_R_PPC_GOT16_HA +#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 GRUB_ELF_R_PPC64_COPY GRUB_ELF_R_PPC_COPY -#define GRUB_ELF_R_PPC64_GLOB_DAT GRUB_ELF_R_PPC_GLOB_DAT -#define GRUB_ELF_R_PPC64_JMP_SLOT GRUB_ELF_R_PPC_JMP_SLOT -#define GRUB_ELF_R_PPC64_RELATIVE GRUB_ELF_R_PPC_RELATIVE +#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 GRUB_ELF_R_PPC64_UADDR32 GRUB_ELF_R_PPC_UADDR32 -#define GRUB_ELF_R_PPC64_UADDR16 GRUB_ELF_R_PPC_UADDR16 -#define GRUB_ELF_R_PPC64_REL32 GRUB_ELF_R_PPC_REL32 -#define GRUB_ELF_R_PPC64_PLT32 GRUB_ELF_R_PPC_PLT32 -#define GRUB_ELF_R_PPC64_PLTREL32 GRUB_ELF_R_PPC_PLTREL32 -#define GRUB_ELF_R_PPC64_PLT16_LO GRUB_ELF_R_PPC_PLT16_LO -#define GRUB_ELF_R_PPC64_PLT16_HI GRUB_ELF_R_PPC_PLT16_HI -#define GRUB_ELF_R_PPC64_PLT16_HA GRUB_ELF_R_PPC_PLT16_HA +#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 GRUB_ELF_R_PPC64_SECTOFF GRUB_ELF_R_PPC_SECTOFF -#define GRUB_ELF_R_PPC64_SECTOFF_LO GRUB_ELF_R_PPC_SECTOFF_LO -#define GRUB_ELF_R_PPC64_SECTOFF_HI GRUB_ELF_R_PPC_SECTOFF_HI -#define GRUB_ELF_R_PPC64_SECTOFF_HA GRUB_ELF_R_PPC_SECTOFF_HA -#define GRUB_ELF_R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2. */ -#define GRUB_ELF_R_PPC64_ADDR64 38 /* doubleword64 S + A. */ -#define GRUB_ELF_R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A). */ -#define GRUB_ELF_R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A). */ -#define GRUB_ELF_R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A). */ -#define GRUB_ELF_R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A). */ -#define GRUB_ELF_R_PPC64_UADDR64 43 /* doubleword64 S + A. */ -#define GRUB_ELF_R_PPC64_REL64 44 /* doubleword64 S + A - P. */ -#define GRUB_ELF_R_PPC64_PLT64 45 /* doubleword64 L + A. */ -#define GRUB_ELF_R_PPC64_PLTREL64 46 /* doubleword64 L + A - P. */ -#define GRUB_ELF_R_PPC64_TOC16 47 /* half16* S + A - .TOC. */ -#define GRUB_ELF_R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.). */ -#define GRUB_ELF_R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.). */ -#define GRUB_ELF_R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.). */ -#define GRUB_ELF_R_PPC64_TOC 51 /* doubleword64 .TOC. */ -#define GRUB_ELF_R_PPC64_PLTGOT16 52 /* half16* M + A. */ -#define GRUB_ELF_R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A). */ -#define GRUB_ELF_R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A). */ -#define GRUB_ELF_R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A). */ +#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 GRUB_ELF_R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2. */ -#define GRUB_ELF_R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2. */ -#define GRUB_ELF_R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2. */ -#define GRUB_ELF_R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2. */ -#define GRUB_ELF_R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2. */ -#define GRUB_ELF_R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2. */ -#define GRUB_ELF_R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2. */ -#define GRUB_ELF_R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2. */ -#define GRUB_ELF_R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2. */ -#define GRUB_ELF_R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2. */ -#define GRUB_ELF_R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2. */ +#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 GRUB_ELF_R_PPC64_NUM 67 +#define R_PPC64_NUM 67 /* The remaining relocs are from the Embedded ELF ABI, and are not in the SVR4 ELF ABI. */ -#define GRUB_ELF_R_PPC_EMB_NADDR32 101 -#define GRUB_ELF_R_PPC_EMB_NADDR16 102 -#define GRUB_ELF_R_PPC_EMB_NADDR16_LO 103 -#define GRUB_ELF_R_PPC_EMB_NADDR16_HI 104 -#define GRUB_ELF_R_PPC_EMB_NADDR16_HA 105 -#define GRUB_ELF_R_PPC_EMB_SDAI16 106 -#define GRUB_ELF_R_PPC_EMB_SDA2I16 107 -#define GRUB_ELF_R_PPC_EMB_SDA2REL 108 -#define GRUB_ELF_R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ -#define GRUB_ELF_R_PPC_EMB_MRKREF 110 -#define GRUB_ELF_R_PPC_EMB_RELSEC16 111 -#define GRUB_ELF_R_PPC_EMB_RELST_LO 112 -#define GRUB_ELF_R_PPC_EMB_RELST_HI 113 -#define GRUB_ELF_R_PPC_EMB_RELST_HA 114 -#define GRUB_ELF_R_PPC_EMB_BIT_FLD 115 -#define GRUB_ELF_R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ +#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 GRUB_ELF_R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ -#define GRUB_ELF_R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ -#define GRUB_ELF_R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ -#define GRUB_ELF_R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ -#define GRUB_ELF_R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ -#define GRUB_ELF_R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ +#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 GRUB_ELF_R_PPC_TOC16 255 +#define R_PPC_TOC16 255 /* PowerPC64 specific values for the Dyn d_tag field. */ #define DT_PPC64_GLINK (DT_LOPROC + 0) @@ -2015,18 +2004,15 @@ typedef Elf32_Addr Elf32_Conflict; /* 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 -#define EF_ARM_SOFT_FLOAT 0x200 -#define EF_ARM_VFP_FLOAT 0x400 -#define EF_ARM_MAVERICK_FLOAT 0x800 +#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. */ @@ -2035,21 +2021,13 @@ typedef Elf32_Addr Elf32_Conflict; #define EF_ARM_MAPSYMSFIRST 0x10 #define EF_ARM_EABIMASK 0XFF000000 -/* Constants defined in AAELF. */ -#define EF_ARM_BE8 0x00800000 -#define EF_ARM_LE8 0x00400000 - #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 -#define EF_ARM_EABI_VER3 0x03000000 -#define EF_ARM_EABI_VER4 0x04000000 -#define EF_ARM_EABI_VER5 0x05000000 /* Additional symbol types for Thumb */ -#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ -#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ +#define STT_ARM_TFUNC 0xd /* ARM-specific values for sh_flags */ #define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ @@ -2059,178 +2037,50 @@ typedef Elf32_Addr Elf32_Conflict; /* ARM-specific program header flags */ #define PF_ARM_SB 0x10000000 /* Segment contains the location addressed by the static base */ -#define PF_ARM_PI 0x20000000 /* Position-independent segment. */ -#define PF_ARM_ABS 0x40000000 /* Absolute segment. */ - -/* Processor specific values for the Phdr p_type field. */ -#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */ - -/* Processor specific values for the Shdr sh_type field. */ -#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */ -#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */ -#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ - - -/* AArch64 relocs. */ -#define R_AARCH64_NONE 0 /* No relocation. */ -#define R_AARCH64_ABS64 257 /* Direct 64 bit. */ -#define R_AARCH64_ABS32 258 /* Direct 32 bit. */ -#define R_AARCH64_PREL32 261 -#define R_AARCH64_ADR_PREL_PG_HI21 275 -#define R_AARCH64_ADD_ABS_LO12_NC 277 -#define R_AARCH64_LDST64_ABS_LO12_NC 286 -#define R_AARCH64_JUMP26 282 /* 26-bit relative. */ -#define R_AARCH64_CALL26 283 /* 26-bit relative. */ -#define R_AARCH64_ADR_GOT_PAGE 311 -#define R_AARCH64_LD64_GOT_LO12_NC 312 -#define R_AARCH64_COPY 1024 /* Copy symbol at runtime. */ -#define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */ -#define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */ -#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */ -#define R_AARCH64_TLS_DTPMOD64 1028 /* Module number, 64 bit. */ -#define R_AARCH64_TLS_DTPREL64 1029 /* Module-relative offset, 64 bit. */ -#define R_AARCH64_TLS_TPREL64 1030 /* TP-relative offset, 64 bit. */ -#define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */ /* 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_LDR_PC_G0 4 +#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_CALL 10 +#define R_ARM_THM_PC22 10 #define R_ARM_THM_PC8 11 -#define R_ARM_BREL_ADJ 12 -#define R_ARM_TLS_DESC 13 +#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_TLS_DTPMOD32 17 -#define R_ARM_TLS_DTPOFF32 18 -#define R_ARM_TLS_TPOFF32 19 #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_GOTOFF32 24 /* 32 bit offset to GOT */ -#define R_ARM_BASE_PREL 25 /* 32 bit PC relative offset to GOT */ -#define R_ARM_GOT_BREL 26 /* 32 bit GOT entry */ +#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_CALL 28 -#define R_ARM_JUMP24 29 -#define R_ARM_THM_JUMP24 30 -#define R_ARM_BASE_ABS 31 #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_TARGET1 38 -#define R_ARM_SBREL31 39 -#define R_ARM_V4BX 40 -#define R_ARM_TARGET2 41 -#define R_ARM_PREL31 42 -#define R_ARM_MOVW_ABS_NC 43 -#define R_ARM_MOVT_ABS 44 -#define R_ARM_MOVW_PREL_NC 45 -#define R_ARM_MOVT_PREL 46 -#define R_ARM_THM_MOVW_ABS_NC 47 -#define R_ARM_THM_MOVT_ABS 48 -#define R_ARM_THM_MOVW_PREL_NC 49 -#define R_ARM_THM_MOVT_PREL 50 -#define R_ARM_THM_JUMP19 51 -#define R_ARM_THM_JUMP6 52 -#define R_ARM_THM_ALU_PREL_11_0 53 -#define R_ARM_THM_PC12 54 -#define R_ARM_ABS32_NOI 55 -#define R_ARM_REL32_NOI 56 -#define R_ARM_ALU_PC_G0_NC 57 -#define R_ARM_ALU_PC_G0 58 -#define R_ARM_ALU_PC_G1_NC 59 -#define R_ARM_ALU_PC_G1 60 -#define R_ARM_ALU_PC_G2 61 -#define R_ARM_LDR_PC_G1 62 -#define R_ARM_LDR_PC_G2 63 -#define R_ARM_LDRS_PC_G0 64 -#define R_ARM_LDRS_PC_G1 65 -#define R_ARM_LDRS_PC_G2 66 -#define R_ARM_LDC_PC_G0 67 -#define R_ARM_LDC_PC_G1 68 -#define R_ARM_LDC_PC_G2 69 -#define R_ARM_ALU_SB_G0_NC 70 -#define R_ARM_ALU_SB_G0 71 -#define R_ARM_ALU_SB_G1_NC 72 -#define R_ARM_ALU_SB_G1 73 -#define R_ARM_ALU_SB_G2 74 -#define R_ARM_LDR_SB_G0 75 -#define R_ARM_LDR_SB_G1 76 -#define R_ARM_LDR_SB_G2 77 -#define R_ARM_LDRS_SB_G0 78 -#define R_ARM_LDRS_SB_G1 79 -#define R_ARM_LDRS_SB_G2 80 -#define R_ARM_LDC_SB_G0 81 -#define R_ARM_LDC_SB_G1 82 -#define R_ARM_LDC_SB_G2 83 -#define R_ARM_MOVW_BREL_NC 84 -#define R_ARM_MOVT_BREL 85 -#define R_ARM_MOVW_BREL 86 -#define R_ARM_THM_MOVW_BREL_NC 87 -#define R_ARM_THM_MOVT_BREL 88 -#define R_ARM_THM_MOVW_BREL 89 -#define R_ARM_TLS_GOTDESC 90 -#define R_ARM_TLS_CALL 91 -#define R_ARM_TLS_DESCSEQ 92 -#define R_ARM_THM_TLS_CALL 93 -#define R_ARM_PLT32_ABS 94 -#define R_ARM_GOT_ABS 95 -#define R_ARM_GOT_PREL 96 -#define R_ARM_GOT_BREL12 97 -#define R_ARM_GOTOFF12 98 -#define R_ARM_GOTRELAX 99 #define R_ARM_GNU_VTENTRY 100 #define R_ARM_GNU_VTINHERIT 101 -#define R_ARM_THM_JUMP11 102 /* thumb unconditional branch */ -#define R_ARM_THM_JUMP8 103 /* thumb conditional branch */ -#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic - thread local data */ -#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic - thread local data */ -#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS - block */ -#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of - static TLS block offset */ -#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static - TLS block */ -#define R_ARM_TLS_LDO12 109 -#define R_ARM_TLS_LE12 110 -#define R_ARM_IE12GP 111 -#define R_ARM_PRIVATE_0 112 -#define R_ARM_PRIVATE_1 113 -#define R_ARM_PRIVATE_2 114 -#define R_ARM_PRIVATE_3 115 -#define R_ARM_PRIVATE_4 116 -#define R_ARM_PRIVATE_5 117 -#define R_ARM_PRIVATE_6 118 -#define R_ARM_PRIVATE_7 119 -#define R_ARM_PRIVATE_8 120 -#define R_ARM_PRIVATE_9 121 -#define R_ARM_PRIVATE_10 122 -#define R_ARM_PRIVATE_11 123 -#define R_ARM_PRIVATE_12 124 -#define R_ARM_PRIVATE_13 125 -#define R_ARM_PRIVATE_14 126 -#define R_ARM_PRIVATE_15 127 -#define R_ARM_ME_TOO 128 -#define R_ARM_THM_TLS_DESCSEQ16 129 -#define R_ARM_THM_TLS_DESCSEQ32 130 -#define R_ARM_THM_GOT_BREL12 131 -#define R_ARM_IRELATIVE 140 +#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 @@ -2480,107 +2330,10 @@ typedef Elf32_Addr Elf32_Conflict; #define R_X86_64_NUM 24 -/* RISC-V relocations */ -#define R_RISCV_NONE 0 -#define R_RISCV_32 1 -#define R_RISCV_64 2 -#define R_RISCV_RELATIVE 3 -#define R_RISCV_COPY 4 -#define R_RISCV_JUMP_SLOT 5 -#define R_RISCV_TLS_DTPMOD32 6 -#define R_RISCV_TLS_DTPMOD64 7 -#define R_RISCV_TLS_DTPREL32 8 -#define R_RISCV_TLS_DTPREL64 9 -#define R_RISCV_TLS_TPREL32 10 -#define R_RISCV_TLS_TPREL64 11 - -#define R_RISCV_BRANCH 16 -#define R_RISCV_JAL 17 -#define R_RISCV_CALL 18 -#define R_RISCV_CALL_PLT 19 -#define R_RISCV_GOT_HI20 20 -#define R_RISCV_TLS_GOT_HI20 21 -#define R_RISCV_TLS_GD_HI20 22 -#define R_RISCV_PCREL_HI20 23 -#define R_RISCV_PCREL_LO12_I 24 -#define R_RISCV_PCREL_LO12_S 25 -#define R_RISCV_HI20 26 -#define R_RISCV_LO12_I 27 -#define R_RISCV_LO12_S 28 -#define R_RISCV_TPREL_HI20 29 -#define R_RISCV_TPREL_LO12_I 30 -#define R_RISCV_TPREL_LO12_S 31 -#define R_RISCV_TPREL_ADD 32 -#define R_RISCV_ADD8 33 -#define R_RISCV_ADD16 34 -#define R_RISCV_ADD32 35 -#define R_RISCV_ADD64 36 -#define R_RISCV_SUB8 37 -#define R_RISCV_SUB16 38 -#define R_RISCV_SUB32 39 -#define R_RISCV_SUB64 40 -#define R_RISCV_GNU_VTINHERIT 41 -#define R_RISCV_GNU_VTENTRY 42 -#define R_RISCV_ALIGN 43 -#define R_RISCV_RVC_BRANCH 44 -#define R_RISCV_RVC_JUMP 45 -#define R_RISCV_LUI 46 -#define R_RISCV_GPREL_I 47 -#define R_RISCV_GPREL_S 48 -#define R_RISCV_TPREL_I 49 -#define R_RISCV_TPREL_S 50 -#define R_RISCV_RELAX 51 -#define R_RISCV_SUB6 52 -#define R_RISCV_SET6 53 -#define R_RISCV_SET8 54 -#define R_RISCV_SET16 55 -#define R_RISCV_SET32 56 -#define R_RISCV_32_PCREL 57 - -/* LoongArch relocations */ -#define R_LARCH_NONE 0 -#define R_LARCH_64 2 -#define R_LARCH_MARK_LA 20 -#define R_LARCH_SOP_PUSH_PCREL 22 -#define R_LARCH_SOP_PUSH_ABSOLUTE 23 -#define R_LARCH_SOP_PUSH_PLT_PCREL 29 -#define R_LARCH_SOP_SUB 32 -#define R_LARCH_SOP_SL 33 -#define R_LARCH_SOP_SR 34 -#define R_LARCH_SOP_ADD 35 -#define R_LARCH_SOP_AND 36 -#define R_LARCH_SOP_IF_ELSE 37 -#define R_LARCH_SOP_POP_32_S_10_5 38 -#define R_LARCH_SOP_POP_32_U_10_12 39 -#define R_LARCH_SOP_POP_32_S_10_12 40 -#define R_LARCH_SOP_POP_32_S_10_16 41 -#define R_LARCH_SOP_POP_32_S_10_16_S2 42 -#define R_LARCH_SOP_POP_32_S_5_20 43 -#define R_LARCH_SOP_POP_32_S_0_5_10_16_S2 44 -#define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45 -#define R_LARCH_B26 66 -#define R_LARCH_ABS_HI20 67 -#define R_LARCH_ABS_LO12 68 -#define R_LARCH_ABS64_LO20 69 -#define R_LARCH_ABS64_HI12 70 -#define R_LARCH_PCALA_HI20 71 -#define R_LARCH_PCALA_LO12 72 - -extern grub_err_t grub_elf32_get_shnum (Elf32_Ehdr *e, Elf32_Shnum *shnum); -extern grub_err_t grub_elf32_get_shstrndx (Elf32_Ehdr *e, Elf32_Word *shstrndx); -extern grub_err_t grub_elf32_get_phnum (Elf32_Ehdr *e, Elf32_Word *phnum); - -extern grub_err_t grub_elf64_get_shnum (Elf64_Ehdr *e, Elf64_Shnum *shnum); -extern grub_err_t grub_elf64_get_shstrndx (Elf64_Ehdr *e, Elf64_Word *shstrndx); -extern grub_err_t grub_elf64_get_phnum (Elf64_Ehdr *e, Elf64_Word *phnum); - -#ifdef GRUB_TARGET_WORDSIZE #if GRUB_TARGET_WORDSIZE == 32 typedef Elf32_Addr Elf_Addr; -typedef Elf32_Nhdr Elf_Nhdr; typedef Elf32_Ehdr Elf_Ehdr; -typedef Elf32_Phdr Elf_Phdr; typedef Elf32_Half Elf_Half; typedef Elf32_Off Elf_Off; typedef Elf32_Rel Elf_Rel; @@ -2591,26 +2344,17 @@ typedef Elf32_Sword Elf_Sword; typedef Elf32_Sym Elf_Sym; typedef Elf32_Word Elf_Word; typedef Elf32_Xword Elf_Xword; -typedef Elf32_Shnum Elf_Shnum; #define ELF_ST_BIND(val) ELF32_ST_BIND(val) #define ELF_ST_TYPE(val) ELF32_ST_TYPE(val) -#define ELF_ST_INFO(a,b) ELF32_ST_INFO(a,b) - #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) -#define grub_elf_get_shnum grub_elf32_get_shnum -#define grub_elf_get_shstrndx grub_elf32_get_shstrndx -#define grub_elf_get_phnum grub_elf32_get_phnum - #elif GRUB_TARGET_WORDSIZE == 64 typedef Elf64_Addr Elf_Addr; -typedef Elf64_Nhdr Elf_Nhdr; typedef Elf64_Ehdr Elf_Ehdr; -typedef Elf64_Phdr Elf_Phdr; typedef Elf64_Half Elf_Half; typedef Elf64_Off Elf_Off; typedef Elf64_Rel Elf_Rel; @@ -2621,20 +2365,13 @@ typedef Elf64_Sword Elf_Sword; typedef Elf64_Sym Elf_Sym; typedef Elf64_Word Elf_Word; typedef Elf64_Xword Elf_Xword; -typedef Elf64_Shnum Elf_Shnum; -#define ELF_ST_BIND(val) ELF64_ST_BIND(val) -#define ELF_ST_TYPE(val) ELF64_ST_TYPE(val) -#define ELF_ST_INFO(a,b) ELF64_ST_INFO(a,b) +#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) -#define grub_elf_get_shnum grub_elf64_get_shnum -#define grub_elf_get_shstrndx grub_elf64_get_shstrndx -#define grub_elf_get_phnum grub_elf64_get_phnum - #endif /* GRUB_TARGET_WORDSIZE == 64 */ -#endif #endif /* ! GRUB_ELF_H */ diff --git a/include/grub/elfload.h b/include/grub/elfload.h index dbb609c9b..77ee41675 100644 --- a/include/grub/elfload.h +++ b/include/grub/elfload.h @@ -33,50 +33,26 @@ struct grub_elf_file Elf32_Ehdr ehdr32; } ehdr; void *phdrs; - char *filename; }; typedef struct grub_elf_file *grub_elf_t; -typedef int (*grub_elf32_phdr_iterate_hook_t) - (grub_elf_t elf, Elf32_Phdr *phdr, void *arg); -typedef int (*grub_elf64_phdr_iterate_hook_t) - (grub_elf_t elf, Elf64_Phdr *phdr, void *arg); +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 *, enum grub_file_type type); -grub_elf_t grub_elf_file (grub_file_t file, const char *filename); +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_uint32_t *); -enum grub_elf_load_flags - { - GRUB_ELF_LOAD_FLAGS_NONE = 0, - GRUB_ELF_LOAD_FLAGS_LOAD_PT_DYNAMIC = 1, - GRUB_ELF_LOAD_FLAGS_BITS = 6, - GRUB_ELF_LOAD_FLAGS_ALL_BITS = 0, - GRUB_ELF_LOAD_FLAGS_28BITS = 2, - GRUB_ELF_LOAD_FLAGS_30BITS = 4, - GRUB_ELF_LOAD_FLAGS_62BITS = 6, - }; -grub_err_t grub_elf32_load (grub_elf_t, const char *filename, - void *load_offset, enum grub_elf_load_flags flags, grub_addr_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_uint64_t *); -grub_err_t grub_elf64_load (grub_elf_t, const char *filename, - void *load_offset, enum grub_elf_load_flags flags, grub_addr_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 *); -grub_err_t grub_elf32_load_phdrs (grub_elf_t elf); -grub_err_t grub_elf64_load_phdrs (grub_elf_t elf); - -#define FOR_ELF32_PHDRS(elf, phdr) \ - for (grub_elf32_load_phdrs (elf), phdr = elf->phdrs; \ - phdr && phdr < (Elf32_Phdr *) elf->phdrs + elf->ehdr.ehdr32.e_phnum; phdr++) -#define FOR_ELF64_PHDRS(elf, phdr) \ - for (grub_elf64_load_phdrs (elf), phdr = elf->phdrs; \ - phdr && phdr < (Elf64_Phdr *) elf->phdrs + elf->ehdr.ehdr64.e_phnum; phdr++) #endif /* ! GRUB_ELFLOAD_HEADER */ diff --git a/include/grub/emu/config.h b/include/grub/emu/config.h deleted file mode 100644 index 875d5896c..000000000 --- a/include/grub/emu/config.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_CONFIG_EMU_HEADER -#define GRUB_CONFIG_EMU_HEADER 1 - -#include -#include -#include -#include - -const char * -grub_util_get_config_filename (void); -const char * -grub_util_get_pkgdatadir (void); -const char * -grub_util_get_pkglibdir (void); -const char * -grub_util_get_localedir (void); - -struct grub_util_config -{ - int is_cryptodisk_enabled; - char *grub_distributor; -}; - -void -grub_util_load_config (struct grub_util_config *cfg); - -void -grub_util_parse_config (FILE *f, struct grub_util_config *cfg, int simple); - -#endif diff --git a/include/grub/emu/exec.h b/include/grub/emu/exec.h deleted file mode 100644 index 1b61b4a2e..000000000 --- a/include/grub/emu/exec.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_EMU_EXEC_H -#define GRUB_EMU_EXEC_H 1 - -#include -#include - -#include -#include - -pid_t -grub_util_exec_pipe (const char *const *argv, int *fd); -pid_t -grub_util_exec_pipe_stderr (const char *const *argv, int *fd); - -int -grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file, - const char *stdout_file, const char *stderr_file); -int -EXPORT_FUNC(grub_util_exec) (const char *const *argv); -int -grub_util_exec_redirect (const char *const *argv, const char *stdin_file, - const char *stdout_file); -int -grub_util_exec_redirect_null (const char *const *argv); - -#endif diff --git a/include/grub/emu/getroot.h b/include/grub/emu/getroot.h deleted file mode 100644 index 73fa2d34a..000000000 --- a/include/grub/emu/getroot.h +++ /dev/null @@ -1,104 +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 . - */ - -#ifndef GRUB_UTIL_GETROOT_HEADER -#define GRUB_UTIL_GETROOT_HEADER 1 - -#include -#include - -#include -#include - -enum grub_dev_abstraction_types { - GRUB_DEV_ABSTRACTION_NONE, - GRUB_DEV_ABSTRACTION_LVM, - GRUB_DEV_ABSTRACTION_RAID, - GRUB_DEV_ABSTRACTION_LUKS, - GRUB_DEV_ABSTRACTION_GELI, -}; - -char *grub_find_device (const char *dir, dev_t dev); -void grub_util_pull_device (const char *osname); -char **grub_guess_root_devices (const char *dir); -int grub_util_get_dev_abstraction (const char *os_dev); -char *grub_make_system_path_relative_to_its_root (const char *path); -char * -grub_make_system_path_relative_to_its_root_os (const char *path); -char *grub_util_get_grub_dev (const char *os_dev); -#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) -void grub_util_follow_gpart_up (const char *name, grub_disk_addr_t *off_out, - char **name_out); -#endif - -#include - -#ifdef __linux__ -char ** -grub_find_root_devices_from_mountinfo (const char *dir, char **relroot); -#endif - -/* Devmapper functions provided by getroot_devmapper.c. */ -void -grub_util_pull_devmapper (const char *os_dev); -int -grub_util_device_is_mapped_stat (struct stat *st); -void grub_util_devmapper_cleanup (void); -enum grub_dev_abstraction_types -grub_util_get_dm_abstraction (const char *os_dev); -char * -grub_util_get_vg_uuid (const char *os_dev); -char * -grub_util_devmapper_part_to_disk (struct stat *st, - int *is_part, const char *os_dev); -char * -grub_util_get_devmapper_grub_dev (const char *os_dev); - -void -grub_util_pull_lvm_by_command (const char *os_dev); -char ** -grub_util_find_root_devices_from_poolname (char *poolname); - -grub_disk_addr_t -grub_util_find_partition_start (const char *dev); - -/* OS-specific functions provided by getroot_*.c. */ -enum grub_dev_abstraction_types -grub_util_get_dev_abstraction_os (const char *os_dev); -char * -grub_util_part_to_disk (const char *os_dev, struct stat *st, - int *is_part); -int -grub_util_pull_device_os (const char *osname, - enum grub_dev_abstraction_types ab); -char * -grub_util_get_grub_dev_os (const char *os_dev); -grub_disk_addr_t -grub_util_find_partition_start_os (const char *dev); - -char * -grub_util_guess_bios_drive (const char *orig_path); -char * -grub_util_guess_efi_drive (const char *orig_path); -char * -grub_util_guess_baremetal_drive (const char *orig_path); -void -grub_util_fprint_full_disk_name (FILE *f, - const char *drive, grub_device_t dev); - -#endif /* ! GRUB_UTIL_GETROOT_HEADER */ diff --git a/include/grub/emu/hostdisk.h b/include/grub/emu/hostdisk.h deleted file mode 100644 index e006f0b38..000000000 --- a/include/grub/emu/hostdisk.h +++ /dev/null @@ -1,98 +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 . - */ - -#ifndef GRUB_BIOSDISK_MACHINE_UTIL_HEADER -#define GRUB_BIOSDISK_MACHINE_UTIL_HEADER 1 - -#include -#include -#include -#include - -grub_util_fd_t -grub_util_fd_open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags, - grub_disk_addr_t *max); - -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); -int grub_util_biosdisk_is_present (const char *name); -int grub_util_biosdisk_is_floppy (grub_disk_t disk); -const char * -grub_util_biosdisk_get_compatibility_hint (grub_disk_t disk); -grub_err_t grub_util_biosdisk_flush (struct grub_disk *disk); -grub_err_t -grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat); -const char * -grub_util_cryptodisk_get_uuid (grub_disk_t disk); -char * -grub_util_get_ldm (grub_disk_t disk, grub_disk_addr_t start); -int -grub_util_is_ldm (grub_disk_t disk); -#ifdef GRUB_UTIL -grub_err_t -grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors, - unsigned int max_nsectors, - grub_embed_type_t embed_type, - grub_disk_addr_t **sectors); -#endif -const char * -grub_hostdisk_os_dev_to_grub_drive (const char *os_dev, int add); - - -char * -grub_util_get_os_disk (const char *os_dev); - -int -grub_util_get_dm_node_linear_info (dev_t dev, - int *maj, int *min, - grub_disk_addr_t *st); - - -/* Supplied by hostdisk_*.c. */ -grub_int64_t -grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize); -/* REturns partition offset in 512B blocks. */ -grub_disk_addr_t -grub_hostdisk_find_partition_start_os (const char *dev); -void -grub_hostdisk_flush_initial_buffer (const char *os_dev); - -#ifdef __GNU__ -int -grub_util_hurd_get_disk_info (const char *dev, grub_uint32_t *secsize, grub_disk_addr_t *offset, - grub_disk_addr_t *size, char **parent); -#endif - -struct grub_util_hostdisk_data -{ - char *dev; - int access_mode; - grub_util_fd_t fd; - int is_disk; - int device_map; -}; - -void grub_host_init (void); -void grub_host_fini (void); -void grub_hostfs_init (void); -void grub_hostfs_fini (void); - -#endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ diff --git a/include/grub/emu/hostfile.h b/include/grub/emu/hostfile.h deleted file mode 100644 index a61568e36..000000000 --- a/include/grub/emu/hostfile.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_HOSTFILE_EMU_HEADER -#define GRUB_HOSTFILE_EMU_HEADER 1 - -#include -#include -#include -#include -#include - -int -grub_util_is_directory (const char *path); -int -grub_util_is_special_file (const char *path); -int -EXPORT_FUNC(grub_util_is_regular) (const char *path); - -char * -grub_util_path_concat (size_t n, ...); -char * -grub_util_path_concat_ext (size_t n, ...); - -int -grub_util_fd_seek (grub_util_fd_t fd, grub_uint64_t off); -ssize_t -EXPORT_FUNC(grub_util_fd_read) (grub_util_fd_t fd, char *buf, size_t len); -ssize_t -EXPORT_FUNC(grub_util_fd_write) (grub_util_fd_t fd, const char *buf, size_t len); - -grub_util_fd_t -EXPORT_FUNC(grub_util_fd_open) (const char *os_dev, int flags); -const char * -EXPORT_FUNC(grub_util_fd_strerror) (void); -int -grub_util_fd_sync (grub_util_fd_t fd); -void -grub_util_disable_fd_syncs (void); -int -EXPORT_FUNC(grub_util_fd_close) (grub_util_fd_t fd); - -grub_uint64_t -grub_util_get_fd_size (grub_util_fd_t fd, const char *name, unsigned *log_secsize); -char * -grub_util_make_temporary_file (void); -char * -grub_util_make_temporary_dir (void); -void -grub_util_unlink_recursive (const char *name); -grub_uint32_t -grub_util_get_mtime (const char *name); - -#endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h deleted file mode 100644 index fefbec499..000000000 --- a/include/grub/emu/misc.h +++ /dev/null @@ -1,83 +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 . - */ - -#ifndef GRUB_EMU_MISC_H -#define GRUB_EMU_MISC_H 1 - -#include -#include - -#include - -#include -#include -#include -#include -#include - -extern int verbosity; -extern const char *EXPORT_VAR(program_name); - -void grub_init_all (void); -void grub_fini_all (void); - -void grub_find_zpool_from_dir (const char *dir, - char **poolname, char **poolfs); - -char *grub_make_system_path_relative_to_its_root (const char *path) - WARN_UNUSED_RESULT; -int -grub_util_device_is_mapped (const char *dev); - -#define GRUB_HOST_PRIuLONG_LONG "llu" -#define GRUB_HOST_PRIxLONG_LONG "llx" - -void * EXPORT_FUNC(xcalloc) (grub_size_t nmemb, grub_size_t size) WARN_UNUSED_RESULT; -void * EXPORT_FUNC(xmalloc) (grub_size_t size) WARN_UNUSED_RESULT; -void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) WARN_UNUSED_RESULT; -char * EXPORT_FUNC(xstrdup) (const char *str) WARN_UNUSED_RESULT; -char * EXPORT_FUNC(xasprintf) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))) WARN_UNUSED_RESULT; - -void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); -void EXPORT_FUNC(grub_util_info) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); -void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2), noreturn)); - -void EXPORT_FUNC(grub_util_set_kexecute) (void); -int EXPORT_FUNC(grub_util_get_kexecute) (void) WARN_UNUSED_RESULT; - -grub_uint64_t EXPORT_FUNC (grub_util_get_cpu_time_ms) (void); - -#ifdef HAVE_DEVICE_MAPPER -int grub_device_mapper_supported (void); -#endif - -#ifdef GRUB_BUILD -#define grub_util_fopen fopen -#else -FILE * -grub_util_fopen (const char *path, const char *mode); -#endif - -int grub_util_file_sync (FILE *f); - -grub_err_t grub_util_tpm_open (const char *tpm_dev); -grub_err_t grub_util_tpm_close (void); -grub_size_t EXPORT_FUNC(grub_util_tpm_read) (void *output, grub_size_t size); -grub_size_t EXPORT_FUNC(grub_util_tpm_write) (const void *input, grub_size_t size); - -#endif /* GRUB_EMU_MISC_H */ diff --git a/include/grub/emu/net.h b/include/grub/emu/net.h deleted file mode 100644 index a5d4fcbe4..000000000 --- a/include/grub/emu/net.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_EMUNET_HEADER -#define GRUB_EMUNET_HEADER 1 - -#include -#include - -grub_ssize_t -EXPORT_FUNC(grub_emunet_send) (const void *packet, grub_size_t sz); - -grub_ssize_t -EXPORT_FUNC(grub_emunet_receive) (void *packet, grub_size_t sz); - -int -EXPORT_FUNC(grub_emunet_create) (grub_size_t *mtu); - -void -EXPORT_FUNC(grub_emunet_close) (void); - -#endif diff --git a/include/grub/env.h b/include/grub/env.h index 6b9379a30..ae4fd8745 100644 --- a/include/grub/env.h +++ b/include/grub/env.h @@ -26,8 +26,8 @@ struct grub_env_var; -typedef const char *(*grub_env_read_hook_t) (struct grub_env_var *var, - const char *val); +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); @@ -39,35 +39,24 @@ struct grub_env_var grub_env_write_hook_t write_hook; struct grub_env_var *next; struct grub_env_var **prevp; - struct grub_env_var *sorted_next; int global; }; grub_err_t EXPORT_FUNC(grub_env_set) (const char *name, const char *val); -const char *EXPORT_FUNC(grub_env_get) (const char *name); -bool EXPORT_FUNC(grub_env_get_bool) (const char *name, bool if_unset); +char *EXPORT_FUNC(grub_env_get) (const char *name); void EXPORT_FUNC(grub_env_unset) (const char *name); -struct grub_env_var *EXPORT_FUNC(grub_env_update_get_sorted) (void); - -#define FOR_SORTED_ENV(var) for (var = grub_env_update_get_sorted (); var; var = var->sorted_next) - +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 (void); +grub_err_t grub_env_context_open (int export); grub_err_t grub_env_context_close (void); -grub_err_t EXPORT_FUNC(grub_env_export) (const char *name); +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); -grub_err_t -grub_env_extractor_open (int source); - -grub_err_t -grub_env_extractor_close (int source); - - #endif /* ! GRUB_ENV_HEADER */ diff --git a/include/grub/err.h b/include/grub/err.h index 202fa8a7a..e44705389 100644 --- a/include/grub/err.h +++ b/include/grub/err.h @@ -21,9 +21,6 @@ #define GRUB_ERR_HEADER 1 #include -#include - -#define GRUB_MAX_ERRMSG 256 typedef enum { @@ -53,49 +50,23 @@ typedef enum GRUB_ERR_BAD_FONT, GRUB_ERR_NOT_IMPLEMENTED_YET, GRUB_ERR_SYMLINK_LOOP, - GRUB_ERR_BAD_COMPRESSED_DATA, + GRUB_ERR_BAD_GZIP_DATA, GRUB_ERR_MENU, GRUB_ERR_TIMEOUT, GRUB_ERR_IO, - GRUB_ERR_ACCESS_DENIED, - GRUB_ERR_EXTRACTOR, - GRUB_ERR_NET_BAD_ADDRESS, - GRUB_ERR_NET_ROUTE_LOOP, - GRUB_ERR_NET_NO_ROUTE, - GRUB_ERR_NET_NO_ANSWER, - GRUB_ERR_NET_NO_CARD, - GRUB_ERR_WAIT, - GRUB_ERR_BUG, - GRUB_ERR_NET_PORT_CLOSED, - GRUB_ERR_NET_INVALID_RESPONSE, - GRUB_ERR_NET_UNKNOWN_ERROR, - GRUB_ERR_NET_PACKET_TOO_BIG, - GRUB_ERR_NET_NO_DOMAIN, - GRUB_ERR_EOF, - GRUB_ERR_BAD_SIGNATURE, - GRUB_ERR_BAD_FIRMWARE, - GRUB_ERR_STILL_REFERENCED, - GRUB_ERR_RECURSION_DEPTH + GRUB_ERR_ACCESS_DENIED } grub_err_t; -struct grub_error_saved -{ - grub_err_t grub_errno; - char errmsg[GRUB_MAX_ERRMSG]; -}; - extern grub_err_t EXPORT_VAR(grub_errno); -extern char EXPORT_VAR(grub_errmsg)[GRUB_MAX_ERRMSG]; +extern char EXPORT_VAR(grub_errmsg)[]; -grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...) - __attribute__ ((format (GNU_PRINTF, 2, 3))); +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); -extern int EXPORT_VAR(grub_err_printed_errors); int grub_err_printf (const char *fmt, ...) - __attribute__ ((format (GNU_PRINTF, 1, 2))); + __attribute__ ((format (printf, 1, 2))); #endif /* ! GRUB_ERR_HEADER */ diff --git a/include/grub/exfat.h b/include/grub/exfat.h deleted file mode 100644 index 2b8009cee..000000000 --- a/include/grub/exfat.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_EXFAT_H -#define GRUB_EXFAT_H 1 - -#include - -struct grub_exfat_bpb -{ - grub_uint8_t jmp_boot[3]; - grub_uint8_t oem_name[8]; - grub_uint8_t mbz[53]; - grub_uint64_t num_hidden_sectors; - grub_uint64_t num_total_sectors; - grub_uint32_t num_reserved_sectors; - grub_uint32_t sectors_per_fat; - grub_uint32_t cluster_offset; - grub_uint32_t cluster_count; - grub_uint32_t root_cluster; - grub_uint32_t num_serial; - grub_uint16_t fs_revision; - grub_uint16_t volume_flags; - grub_uint8_t bytes_per_sector_shift; - grub_uint8_t sectors_per_cluster_shift; - grub_uint8_t num_fats; - grub_uint8_t num_ph_drive; - grub_uint8_t reserved[8]; -} GRUB_PACKED; - -#ifdef GRUB_UTIL -#include - -grub_disk_addr_t -grub_exfat_get_cluster_sector (grub_disk_t disk, grub_uint64_t *sec_per_lcn); -#endif - -#endif diff --git a/include/grub/extcmd.h b/include/grub/extcmd.h index fe9248b8b..03eaba8f8 100644 --- a/include/grub/extcmd.h +++ b/include/grub/extcmd.h @@ -21,12 +21,10 @@ #include #include -#include struct grub_extcmd; -struct grub_extcmd_context; -typedef grub_err_t (*grub_extcmd_func_t) (struct grub_extcmd_context *ctxt, +typedef grub_err_t (*grub_extcmd_func_t) (struct grub_extcmd *cmd, int argc, char **args); /* The argcmd description. */ @@ -40,47 +38,18 @@ struct grub_extcmd const struct grub_arg_option *options; void *data; + + struct grub_arg_list *state; }; typedef struct grub_extcmd *grub_extcmd_t; -/* Command context for each instance of execution. */ -struct grub_extcmd_context -{ - struct grub_extcmd *extcmd; +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); - struct grub_arg_list *state; - - /* Script parameter, if any. */ - struct grub_script *script; -}; -typedef struct grub_extcmd_context *grub_extcmd_context_t; - -grub_extcmd_t EXPORT_FUNC(grub_register_extcmd) (const char *name, - grub_extcmd_func_t func, - grub_command_flags_t flags, - const char *summary, - const char *description, - const struct grub_arg_option *parser); - -grub_extcmd_t EXPORT_FUNC(grub_register_extcmd_lockdown) (const char *name, - grub_extcmd_func_t func, - grub_command_flags_t flags, - const char *summary, - const char *description, - const struct grub_arg_option *parser); - -grub_extcmd_t EXPORT_FUNC(grub_register_extcmd_prio) (const char *name, - grub_extcmd_func_t func, - grub_command_flags_t flags, - const char *summary, - const char *description, - const struct grub_arg_option *parser, - int prio); - -void EXPORT_FUNC(grub_unregister_extcmd) (grub_extcmd_t cmd); - -grub_err_t EXPORT_FUNC(grub_extcmd_dispatcher) (struct grub_command *cmd, - int argc, char **args, - struct grub_script *script); +void grub_unregister_extcmd (grub_extcmd_t cmd); #endif /* ! GRUB_EXTCMD_HEADER */ diff --git a/include/grub/fat.h b/include/grub/fat.h deleted file mode 100644 index 8d7e4a1e5..000000000 --- a/include/grub/fat.h +++ /dev/null @@ -1,77 +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 . - */ - -#ifndef GRUB_FAT_H -#define GRUB_FAT_H 1 - -#include - -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; /* 0x10 */ - grub_uint16_t num_root_entries; - grub_uint16_t num_total_sectors_16; - grub_uint8_t media; /* 0x15 */ - grub_uint16_t sectors_per_fat_16; - grub_uint16_t sectors_per_track; /* 0x18 */ - grub_uint16_t num_heads; /* 0x1A */ - grub_uint32_t num_hidden_sectors; /* 0x1C */ - grub_uint32_t num_total_sectors_32; /* 0x20 */ - 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]; - } GRUB_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]; - } GRUB_PACKED fat32; - } GRUB_PACKED version_specific; -} GRUB_PACKED; - -#ifdef GRUB_UTIL -#include - -grub_disk_addr_t -grub_fat_get_cluster_sector (grub_disk_t disk, grub_uint64_t *sec_per_lcn); -#endif - -#endif diff --git a/include/grub/fbblit.h b/include/grub/fbblit.h index 66d1005e7..af97dfb97 100644 --- a/include/grub/fbblit.h +++ b/include/grub/fbblit.h @@ -24,13 +24,159 @@ struct grub_video_fbblit_info; -/* NOTE: This function assumes that given coordinates are within bounds of - handled data. */ void -grub_video_fb_dispatch_blit (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); +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 index 35a80b820..c85fa12dd 100644 --- a/include/grub/fbfill.h +++ b/include/grub/fbfill.h @@ -30,17 +30,13 @@ struct grub_video_fbrender_target mode_type has been re-adjusted to requested render target settings. */ struct grub_video_mode_info mode_info; - /* We should not draw outside of viewport. */ - grub_video_rect_t viewport; - /* Set region to make a re-draw of a part of the screen. */ - grub_video_rect_t region; - /* Should be set to 0 if the viewport is inside of the region. */ - int area_enabled; - /* Internal structure - intersection of the viewport and the region. */ - grub_video_rect_t area; - /* Internal values - offsets from the left top point of the viewport. */ - int area_offset_x; - int area_offset_y; + 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. */ @@ -52,8 +48,28 @@ struct grub_video_fbrender_target }; void -grub_video_fb_fill_dispatch (struct grub_video_fbblit_info *target, - grub_video_color_t color, int x, int y, - unsigned int width, unsigned int height); +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 index 78a1ab3b4..065ccf9e3 100644 --- a/include/grub/fbutil.h +++ b/include/grub/fbutil.h @@ -31,29 +31,8 @@ struct grub_video_fbblit_info grub_uint8_t *data; }; -/* - * Don't use 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. - * - * This function assumes that bounds checking has been done in previous phase - * and they are opted out in here. - */ -static inline void * -grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source, - unsigned int x, unsigned int y) -{ - return source->data + (grub_addr_t) y * source->mode_info->pitch + (grub_addr_t) x * source->mode_info->bytes_per_pixel; -} - -/* Advance pointer by VAL bytes. If there is no unaligned access available, - VAL has to be divisible by size of pointed type. - */ -#ifdef GRUB_HAVE_UNALIGNED_ACCESS -#define GRUB_VIDEO_FB_ADVANCE_POINTER(ptr, val) ((ptr) = (typeof (ptr)) ((char *) ptr + val)) -#else -#define GRUB_VIDEO_FB_ADVANCE_POINTER(ptr, val) ((ptr) += (val) / sizeof (*(ptr))) -#endif +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); diff --git a/include/grub/fdt.h b/include/grub/fdt.h deleted file mode 100644 index e609c7e41..000000000 --- a/include/grub/fdt.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_FDT_HEADER -#define GRUB_FDT_HEADER 1 - -#include -#include - -/* Space required when preparing the /chosen node after boot has been called. */ -#define GRUB_EFI_LINUX_FDT_EXTRA_SPACE 0x400 - -#define FDT_MAGIC 0xD00DFEED - -typedef struct { - grub_uint32_t magic; - grub_uint32_t totalsize; - grub_uint32_t off_dt_struct; - grub_uint32_t off_dt_strings; - grub_uint32_t off_mem_rsvmap; - grub_uint32_t version; - grub_uint32_t last_comp_version; - grub_uint32_t boot_cpuid_phys; - grub_uint32_t size_dt_strings; - grub_uint32_t size_dt_struct; -} grub_fdt_header_t; - -struct grub_fdt_empty_tree { - grub_fdt_header_t header; - grub_uint64_t empty_rsvmap[2]; - struct { - grub_uint32_t node_start; - grub_uint8_t name[1]; - grub_uint32_t node_end; - grub_uint32_t tree_end; - } empty_node; -}; - -#define GRUB_FDT_EMPTY_TREE_SZ sizeof (struct grub_fdt_empty_tree) - -/* Size needed by a property entry: 1 token (FDT_PROPERTY), plus len and nameoff - fields, plus the property value, plus padding if needed. */ -#define grub_fdt_prop_entry_size(prop_len) \ - (3 * sizeof(grub_uint32_t) + ALIGN_UP(prop_len, sizeof(grub_uint32_t))) - -#define grub_fdt_get_header(fdt, field) \ - grub_be_to_cpu32(((const grub_fdt_header_t *)(fdt))->field) -#define grub_fdt_set_header(fdt, field, value) \ - ((grub_fdt_header_t *)(fdt))->field = grub_cpu_to_be32(value) - -#define grub_fdt_get_magic(fdt) \ - grub_fdt_get_header(fdt, magic) -#define grub_fdt_set_magic(fdt, value) \ - grub_fdt_set_header(fdt, magic, value) -#define grub_fdt_get_totalsize(fdt) \ - grub_fdt_get_header(fdt, totalsize) -#define grub_fdt_set_totalsize(fdt, value) \ - grub_fdt_set_header(fdt, totalsize, value) -#define grub_fdt_get_off_dt_struct(fdt) \ - grub_fdt_get_header(fdt, off_dt_struct) -#define grub_fdt_set_off_dt_struct(fdt, value) \ - grub_fdt_set_header(fdt, off_dt_struct, value) -#define grub_fdt_get_off_dt_strings(fdt) \ - grub_fdt_get_header(fdt, off_dt_strings) -#define grub_fdt_set_off_dt_strings(fdt, value) \ - grub_fdt_set_header(fdt, off_dt_strings, value) -#define grub_fdt_get_off_mem_rsvmap(fdt) \ - grub_fdt_get_header(fdt, off_mem_rsvmap) -#define grub_fdt_set_off_mem_rsvmap(fdt, value) \ - grub_fdt_set_header(fdt, off_mem_rsvmap, value) -#define grub_fdt_get_version(fdt) \ - grub_fdt_get_header(fdt, version) -#define grub_fdt_set_version(fdt, value) \ - grub_fdt_set_header(fdt, version, value) -#define grub_fdt_get_last_comp_version(fdt) \ - grub_fdt_get_header(fdt, last_comp_version) -#define grub_fdt_set_last_comp_version(fdt, value) \ - grub_fdt_set_header(fdt, last_comp_version, value) -#define grub_fdt_get_boot_cpuid_phys(fdt) \ - grub_fdt_get_header(fdt, boot_cpuid_phys) -#define grub_fdt_set_boot_cpuid_phys(fdt, value) \ - grub_fdt_set_header(fdt, boot_cpuid_phys, value) -#define grub_fdt_get_size_dt_strings(fdt) \ - grub_fdt_get_header(fdt, size_dt_strings) -#define grub_fdt_set_size_dt_strings(fdt, value) \ - grub_fdt_set_header(fdt, size_dt_strings, value) -#define grub_fdt_get_size_dt_struct(fdt) \ - grub_fdt_get_header(fdt, size_dt_struct) -#define grub_fdt_set_size_dt_struct(fdt, value) \ - grub_fdt_set_header(fdt, size_dt_struct, value) - -int EXPORT_FUNC(grub_fdt_create_empty_tree) (void *fdt, unsigned int size); -int EXPORT_FUNC(grub_fdt_check_header) (const void *fdt, unsigned int size); -int EXPORT_FUNC(grub_fdt_check_header_nosize) (const void *fdt); -int EXPORT_FUNC(grub_fdt_find_subnode) (const void *fdt, unsigned int parentoffset, - const char *name); -int EXPORT_FUNC(grub_fdt_first_node) (const void *fdt, unsigned int parentoffset); -int EXPORT_FUNC(grub_fdt_next_node) (const void *fdt, unsigned int currentoffset); -int EXPORT_FUNC(grub_fdt_add_subnode) (void *fdt, unsigned int parentoffset, - const char *name); -const char * -EXPORT_FUNC(grub_fdt_get_nodename) (const void *fdt, unsigned int nodeoffset); -const void *EXPORT_FUNC(grub_fdt_get_prop) (const void *fdt, unsigned int nodeoffset, const char *name, - grub_uint32_t *len); - -int EXPORT_FUNC(grub_fdt_set_prop) (void *fdt, unsigned int nodeoffset, const char *name, - const void *val, grub_uint32_t len); -#define grub_fdt_set_prop32(fdt, nodeoffset, name, val) \ -({ \ - grub_uint32_t _val = grub_cpu_to_be32(val); \ - grub_fdt_set_prop ((fdt), (nodeoffset), (name), &_val, 4); \ -}) - -#define grub_fdt_set_prop64(fdt, nodeoffset, name, val) \ -({ \ - grub_uint64_t _val = grub_cpu_to_be64(val); \ - grub_fdt_set_prop ((fdt), (nodeoffset), (name), &_val, 8); \ -}) - -/* Setup "reg" property for - * #address-cells = <0x2> - * #size-cells = <0x2> - */ -#define grub_fdt_set_reg64(fdt, nodeoffset, addr, size) \ -({ \ - grub_uint64_t reg_64[2]; \ - reg_64[0] = grub_cpu_to_be64(addr); \ - reg_64[1] = grub_cpu_to_be64(size); \ - grub_fdt_set_prop ((fdt), (nodeoffset), "reg", reg_64, 16); \ -}) - -#endif /* ! GRUB_FDT_HEADER */ diff --git a/include/grub/fdtbus.h b/include/grub/fdtbus.h deleted file mode 100644 index f519c40ec..000000000 --- a/include/grub/fdtbus.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2016 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_FDTBUS_HEADER -#define GRUB_FDTBUS_HEADER 1 - -#include -#include - -struct grub_fdtbus_dev -{ - struct grub_fdtbus_dev *next; - struct grub_fdtbus_dev *parent; - int node; - struct grub_fdtbus_driver *driver; -}; - -struct grub_fdtbus_driver -{ - struct grub_fdtbus_driver *next; - struct grub_fdtbus_driver **prev; - - const char *compatible; - - grub_err_t (*attach) (const struct grub_fdtbus_dev *dev); - void (*detach) (const struct grub_fdtbus_dev *dev); - - /* Message bus operations. */ - grub_err_t (*send) (const struct grub_fdtbus_dev *dev, const void *data, grub_size_t sz); - grub_err_t (*receive) (const struct grub_fdtbus_dev *dev, void *data, grub_size_t sz); - grub_err_t (*start) (const struct grub_fdtbus_dev *dev); - void (*stop) (const struct grub_fdtbus_dev *dev); -}; - -extern char EXPORT_VAR(grub_fdtbus_invalid_mapping)[1]; - -static inline int -grub_fdtbus_is_mapping_valid (volatile void *m) -{ - return m != grub_fdtbus_invalid_mapping; -} - -volatile void * -EXPORT_FUNC(grub_fdtbus_map_reg) (const struct grub_fdtbus_dev *dev, int reg, grub_size_t *size); - -const void * -EXPORT_FUNC(grub_fdtbus_get_fdt) (void); - -const char * -EXPORT_FUNC(grub_fdtbus_get_name) (const struct grub_fdtbus_dev *dev); - -const void * -EXPORT_FUNC(grub_fdtbus_get_prop) (const struct grub_fdtbus_dev *dev, - const char *name, - grub_uint32_t *len); - -void -EXPORT_FUNC(grub_fdtbus_register) (struct grub_fdtbus_driver *driver); - -void -EXPORT_FUNC(grub_fdtbus_unregister) (struct grub_fdtbus_driver *driver); - -int -EXPORT_FUNC(grub_fdtbus_is_compatible) (const char *compat_string, - const struct grub_fdtbus_dev *dev); - -/* Must be called before any register(). */ -/* dtb is assumed to be unfreeable and must remain - valid for lifetime of GRUB. - */ -void -grub_fdtbus_init (const void *dtb, grub_size_t size); - -#endif diff --git a/include/grub/file.h b/include/grub/file.h index a5bf3a792..2aacf936f 100644 --- a/include/grub/file.h +++ b/include/grub/file.h @@ -23,128 +23,10 @@ #include #include #include -#include - -enum grub_file_type - { - GRUB_FILE_TYPE_NONE = 0, - /* GRUB module to be loaded. */ - GRUB_FILE_TYPE_GRUB_MODULE, - /* Loopback file to be represented as disk. */ - GRUB_FILE_TYPE_LOOPBACK, - /* Linux kernel to be loaded. */ - GRUB_FILE_TYPE_LINUX_KERNEL, - /* Linux initrd. */ - GRUB_FILE_TYPE_LINUX_INITRD, - - /* Multiboot kernel. */ - GRUB_FILE_TYPE_MULTIBOOT_KERNEL, - /* Multiboot module. */ - GRUB_FILE_TYPE_MULTIBOOT_MODULE, - - /* Xen hypervisor - used on ARM only. */ - GRUB_FILE_TYPE_XEN_HYPERVISOR, - /* Xen module - used on ARM only. */ - GRUB_FILE_TYPE_XEN_MODULE, - - GRUB_FILE_TYPE_BSD_KERNEL, - GRUB_FILE_TYPE_FREEBSD_ENV, - GRUB_FILE_TYPE_FREEBSD_MODULE, - GRUB_FILE_TYPE_FREEBSD_MODULE_ELF, - GRUB_FILE_TYPE_NETBSD_MODULE, - GRUB_FILE_TYPE_OPENBSD_RAMDISK, - - GRUB_FILE_TYPE_XNU_INFO_PLIST, - GRUB_FILE_TYPE_XNU_MKEXT, - GRUB_FILE_TYPE_XNU_KEXT, - GRUB_FILE_TYPE_XNU_KERNEL, - GRUB_FILE_TYPE_XNU_RAMDISK, - GRUB_FILE_TYPE_XNU_HIBERNATE_IMAGE, - GRUB_FILE_XNU_DEVPROP, - - GRUB_FILE_TYPE_PLAN9_KERNEL, - - GRUB_FILE_TYPE_NTLDR, - GRUB_FILE_TYPE_TRUECRYPT, - GRUB_FILE_TYPE_FREEDOS, - GRUB_FILE_TYPE_PXECHAINLOADER, - GRUB_FILE_TYPE_PCCHAINLOADER, - - GRUB_FILE_TYPE_COREBOOT_CHAINLOADER, - - GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE, - - /* File holding signature. */ - GRUB_FILE_TYPE_SIGNATURE, - /* File holding public key to verify signature once. */ - GRUB_FILE_TYPE_PUBLIC_KEY, - /* File holding public key to add to trused keys. */ - GRUB_FILE_TYPE_PUBLIC_KEY_TRUST, - /* File of which we intend to print a blocklist to the user. */ - GRUB_FILE_TYPE_PRINT_BLOCKLIST, - /* File we intend to use for test loading or testing speed. */ - GRUB_FILE_TYPE_TESTLOAD, - /* File we open only to get its size. E.g. in ls output. */ - GRUB_FILE_TYPE_GET_SIZE, - /* Font file. */ - GRUB_FILE_TYPE_FONT, - /* File holding encryption key for encrypted ZFS. */ - GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY, - /* File holding the encryption key. */ - GRUB_FILE_TYPE_CRYPTODISK_ENCRYPTION_KEY, - /* File holding the encryption metadata header */ - GRUB_FILE_TYPE_CRYPTODISK_DETACHED_HEADER, - /* File we open n grub-fstest. */ - GRUB_FILE_TYPE_FSTEST, - /* File we open n grub-mount. */ - GRUB_FILE_TYPE_MOUNT, - /* File which we attempt to identify the type of. */ - GRUB_FILE_TYPE_FILE_ID, - /* File holding ACPI table. */ - GRUB_FILE_TYPE_ACPI_TABLE, - /* File holding Device Tree. */ - GRUB_FILE_TYPE_DEVICE_TREE_IMAGE, - /* File we intend show to user. */ - GRUB_FILE_TYPE_CAT, - GRUB_FILE_TYPE_HEXCAT, - /* One of pair of files we intend to compare. */ - GRUB_FILE_TYPE_CMP, - /* List of hashes for hashsum. */ - GRUB_FILE_TYPE_HASHLIST, - /* File hashed by hashsum. */ - GRUB_FILE_TYPE_TO_HASH, - /* Keyboard layout. */ - GRUB_FILE_TYPE_KEYBOARD_LAYOUT, - /* Picture file. */ - GRUB_FILE_TYPE_PIXMAP, - /* *.lst shipped by GRUB. */ - GRUB_FILE_TYPE_GRUB_MODULE_LIST, - /* config file. */ - GRUB_FILE_TYPE_CONFIG, - GRUB_FILE_TYPE_THEME, - GRUB_FILE_TYPE_GETTEXT_CATALOG, - GRUB_FILE_TYPE_FS_SEARCH, - GRUB_FILE_TYPE_AUDIO, - GRUB_FILE_TYPE_VBE_DUMP, - - GRUB_FILE_TYPE_LOADENV, - GRUB_FILE_TYPE_SAVEENV, - - GRUB_FILE_TYPE_VERIFY_SIGNATURE, - - GRUB_FILE_TYPE_MASK = 0xffff, - - /* --skip-sig is specified. */ - GRUB_FILE_TYPE_SKIP_SIGNATURE = 0x10000, - GRUB_FILE_TYPE_NO_DECOMPRESS = 0x20000 - }; /* File description. */ struct grub_file { - /* File name. */ - char *name; - /* The underlying device. */ grub_device_t device; @@ -153,72 +35,28 @@ struct grub_file /* The current offset. */ grub_off_t offset; - grub_off_t progress_offset; - - /* Progress info. */ - grub_uint64_t last_progress_time; - grub_off_t last_progress_offset; - grub_uint64_t estimated_speed; /* The file size. */ grub_off_t size; - /* If file is not easily seekable. Should be set by underlying layer. */ - int not_easily_seekable; - /* Filesystem-specific data. */ void *data; /* This is called when a sector is read. Used only for a disk device. */ - grub_disk_read_hook_t read_hook; - - /* Caller-specific data passed to the read hook. */ - void *read_hook_data; + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length); }; typedef struct grub_file *grub_file_t; -extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook); - -/* Filters with lower ID are executed first. */ -typedef enum grub_file_filter_id - { - GRUB_FILE_FILTER_VERIFY, - GRUB_FILE_FILTER_GZIO, - GRUB_FILE_FILTER_XZIO, - GRUB_FILE_FILTER_LZOPIO, - GRUB_FILE_FILTER_MAX, - GRUB_FILE_FILTER_COMPRESSION_FIRST = GRUB_FILE_FILTER_GZIO, - GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_LZOPIO, - } grub_file_filter_id_t; - -typedef grub_file_t (*grub_file_filter_t) (grub_file_t in, enum grub_file_type type); - -extern grub_file_filter_t EXPORT_VAR(grub_file_filters)[GRUB_FILE_FILTER_MAX]; - -static inline void -grub_file_filter_register (grub_file_filter_id_t id, grub_file_filter_t filter) -{ - grub_file_filters[id] = filter; -} - -static inline void -grub_file_filter_unregister (grub_file_filter_id_t id) -{ - grub_file_filters[id] = 0; -} - /* 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, enum grub_file_type type); +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); -/* Return value of grub_file_size() in case file size is unknown. */ -#define GRUB_FILE_SIZE_UNKNOWN 0xffffffffffffffffULL - static inline grub_off_t grub_file_size (const grub_file_t file) { @@ -231,16 +69,4 @@ grub_file_tell (const grub_file_t file) return file->offset; } -static inline int -grub_file_seekable (const grub_file_t file) -{ - return !file->not_easily_seekable; -} - -grub_file_t -grub_file_offset_open (grub_file_t parent, enum grub_file_type type, - grub_off_t start, grub_off_t size); -void -grub_file_offset_close (grub_file_t file); - #endif /* ! GRUB_FILE_HEADER */ diff --git a/include/grub/font.h b/include/grub/font.h index 708fa42ac..7c5c17403 100644 --- a/include/grub/font.h +++ b/include/grub/font.h @@ -22,30 +22,11 @@ #include #include #include -#include /* 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. */ -/* Full structure was moved here for inline function but still - shouldn't be used directly. - */ -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; -}; +struct grub_font; /* Font type used to access font functions. */ typedef struct grub_font *grub_font_t; @@ -88,18 +69,13 @@ struct grub_font_glyph grub_uint8_t bitmap[0]; }; -/* Part of code field which is really used as such. */ -#define GRUB_FONT_CODE_CHAR_MASK 0x001fffff -#define GRUB_FONT_CODE_RIGHT_JOINED 0x80000000 -#define GRUB_FONT_CODE_LEFT_JOINED 0x40000000 - /* 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. */ -grub_font_t EXPORT_FUNC(grub_font_load) (const char *filename); +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. @@ -111,19 +87,9 @@ 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); -/* Get the maximum height of any character in the font in pixels. */ -static inline int -grub_font_get_max_char_height (grub_font_t font) -{ - return font->max_char_height; -} +int EXPORT_FUNC (grub_font_get_max_char_height) (grub_font_t font); -/* Get the distance in pixels from the top of characters to the baseline. */ -static inline int -grub_font_get_ascent (grub_font_t font) -{ - return font->ascent; -} +int EXPORT_FUNC (grub_font_get_ascent) (grub_font_t font); int EXPORT_FUNC (grub_font_get_descent) (grub_font_t font); @@ -131,7 +97,8 @@ 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_xheight) (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); @@ -143,11 +110,9 @@ 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); -int -EXPORT_FUNC (grub_font_get_constructed_device_width) (grub_font_t hinted_font, - const struct grub_unicode_glyph *glyph_id); -struct grub_font_glyph * -EXPORT_FUNC (grub_font_construct_glyph) (grub_font_t hinted_font, - const struct grub_unicode_glyph *glyph_id); +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/fs.h b/include/grub/fs.h index df4c93b16..45f515768 100644 --- a/include/grub/fs.h +++ b/include/grub/fs.h @@ -23,83 +23,58 @@ #include #include #include -#include - -#include -/* For embedding types. */ -#ifdef GRUB_UTIL -#include -#endif /* Forward declaration is required, because of mutual reference. */ struct grub_file; struct grub_dirhook_info { - unsigned dir:1; - unsigned mtimeset:1; - unsigned case_insensitive:1; - unsigned inodeset:1; - grub_int64_t mtime; - grub_uint64_t inode; + int dir:1; + int mtimeset:1; + int case_insensitive:1; + grub_int32_t mtime; }; -typedef int (*grub_fs_dir_hook_t) (const char *filename, - const struct grub_dirhook_info *info, - void *data); - /* Filesystem descriptor. */ struct grub_fs { - /* The next filesystem. */ - struct grub_fs *next; - struct grub_fs **prev; - /* My name. */ const char *name; - /* My module */ - grub_dl_t mod; - /* Call HOOK with each file under DIR. */ - grub_err_t (*fs_dir) (grub_device_t device, const char *path, - grub_fs_dir_hook_t hook, void *hook_data); + 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 (*fs_open) (struct grub_file *file, const char *name); + grub_err_t (*open) (struct grub_file *file, const char *name); /* Read LEN bytes data from FILE into BUF. */ - grub_ssize_t (*fs_read) (struct grub_file *file, char *buf, grub_size_t len); + grub_ssize_t (*read) (struct grub_file *file, char *buf, grub_size_t len); /* Close the file FILE. */ - grub_err_t (*fs_close) (struct grub_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 (*fs_label) (grub_device_t device, char **label); + 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 (*fs_uuid) (grub_device_t device, char **uuid); + grub_err_t (*uuid) (grub_device_t device, char **uuid); /* Get writing time of filesystem. */ - grub_err_t (*fs_mtime) (grub_device_t device, grub_int64_t *timebuf); + grub_err_t (*mtime) (grub_device_t device, grub_int32_t *timebuf); #ifdef GRUB_UTIL - /* Determine sectors available for embedding. */ - grub_err_t (*fs_embed) (grub_device_t device, unsigned int *nsectors, - unsigned int max_nsectors, - grub_embed_type_t embed_type, - grub_disk_addr_t **sectors); - /* Whether this filesystem reserves first sector for DOS-style boot. */ int reserved_first_sector; - - /* Whether blocklist installs have a chance to work. */ - int blocklist_install; #endif + + /* The next filesystem. */ + struct grub_fs *next; }; typedef struct grub_fs *grub_fs_t; @@ -112,24 +87,10 @@ extern struct grub_fs grub_fs_blocklist; 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); -extern grub_fs_t EXPORT_VAR (grub_fs_list); - -#ifndef GRUB_LST_GENERATOR -static inline void -grub_fs_register (grub_fs_t fs) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_fs_list), GRUB_AS_LIST (fs)); -} -#endif - -static inline void -grub_fs_unregister (grub_fs_t fs) -{ - grub_list_remove (GRUB_AS_LIST (fs)); -} - -#define FOR_FILESYSTEMS(var) FOR_LIST_ELEMENTS((var), (grub_fs_list)) +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 index eb1ba4f6c..42d8da5f2 100644 --- a/include/grub/fshelp.h +++ b/include/grub/fshelp.h @@ -23,7 +23,6 @@ #include #include #include -#include typedef struct grub_fshelp_node *grub_fshelp_node_t; @@ -39,40 +38,28 @@ enum grub_fshelp_filetype GRUB_FSHELP_SYMLINK }; -typedef int (*grub_fshelp_iterate_dir_hook_t) (const char *filename, - enum grub_fshelp_filetype filetype, - grub_fshelp_node_t node, - void *data); - /* 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. */ + 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, - grub_fshelp_iterate_dir_hook_t hook, - void *hook_data), + 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); -grub_err_t -EXPORT_FUNC(grub_fshelp_find_file_lookup) (const char *path, - grub_fshelp_node_t rootnode, - grub_fshelp_node_t *foundnode, - grub_err_t (*lookup_file) (grub_fshelp_node_t dir, - const char *name, - grub_fshelp_node_t *foundnode, - enum grub_fshelp_filetype *foundtype), - 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 @@ -80,12 +67,16 @@ EXPORT_FUNC(grub_fshelp_find_file_lookup) (const char *path, 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, - grub_disk_read_hook_t read_hook, - void *read_hook_data, + 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 blocks_start); + 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/gcry/types.h b/include/grub/gcry/types.h deleted file mode 100644 index 892a2042d..000000000 --- a/include/grub/gcry/types.h +++ /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 . - */ - -#ifndef GRUB_GCRY_TYPES_HEADER -#define GRUB_GCRY_TYPES_HEADER 1 - -#include -#include - -#ifdef GRUB_CPU_WORDS_BIGENDIAN -#define WORDS_BIGENDIAN -#else -#undef WORDS_BIGENDIAN -#endif - -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; - -#endif diff --git a/include/grub/gcrypt/gpg-error.h b/include/grub/gcrypt/gpg-error.h deleted file mode 100644 index 1e4250284..000000000 --- a/include/grub/gcrypt/gpg-error.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef GRUB_GPG_ERROR_H -#define GRUB_GPG_ERROR_H 1 - -#include -typedef enum - { - GPG_ERR_SOURCE_USER_1 - } - gpg_err_source_t; -#define GPG_ERR_INLINE inline -static inline int -gpg_err_make (gpg_err_source_t source __attribute__ ((unused)), gpg_err_code_t code) -{ - return code; -} - -static inline gpg_err_code_t -gpg_err_code (gpg_error_t err) -{ - return err; -} - -static inline gpg_err_source_t -gpg_err_source (gpg_error_t err __attribute__ ((unused))) -{ - return GPG_ERR_SOURCE_USER_1; -} - -gcry_err_code_t -gpg_error_from_syserror (void); - -#endif diff --git a/include/grub/gdb.h b/include/grub/gdb.h deleted file mode 100644 index e73d13584..000000000 --- a/include/grub/gdb.h +++ /dev/null @@ -1,39 +0,0 @@ -/* gdb.h - Various definitions for the remote GDB stub */ -/* - * Copyright (C) 2006 Lubomir Kundrak - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef GRUB_GDB_HEADER -#define GRUB_GDB_HEADER 1 - -#define SIGFPE 8 -#define SIGTRAP 5 -#define SIGABRT 6 -#define SIGSEGV 11 -#define SIGILL 4 -#define SIGUSR1 30 -/* We probably don't need other ones. */ - -struct grub_serial_port; - -extern struct grub_serial_port *grub_gdb_port; - -void grub_gdb_breakpoint (void); -unsigned int grub_gdb_trap2sig (int); - -#endif /* ! GRUB_GDB_HEADER */ - diff --git a/include/grub/gfxmenu_view.h b/include/grub/gfxmenu_view.h index c9e12db82..7cbfa89d3 100644 --- a/include/grub/gfxmenu_view.h +++ b/include/grub/gfxmenu_view.h @@ -55,27 +55,18 @@ void grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view, const grub_video_rect_t *region); -void +void grub_gfxmenu_clear_timeout (void *data); -void +void grub_gfxmenu_print_timeout (int timeout, void *data); void grub_gfxmenu_set_chosen_entry (int entry, void *data); -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 grub_font_get_string_width (grub_font_t font, - const char *str); - - /* Implementation details -- this should not be used outside of the view itself. */ #include #include -#include #include #include #include @@ -85,22 +76,14 @@ struct grub_gfxmenu_view { grub_video_rect_t screen; - int need_to_check_sanity; - grub_video_rect_t terminal_rect; - int terminal_border; - grub_font_t title_font; grub_font_t message_font; char *terminal_font_name; - grub_video_rgba_color_t title_color; - grub_video_rgba_color_t message_color; - grub_video_rgba_color_t message_bg_color; - struct grub_video_bitmap *raw_desktop_image; - struct grub_video_bitmap *scaled_desktop_image; - grub_video_bitmap_selection_method_t desktop_image_scale_method; - grub_video_bitmap_h_align_t desktop_image_h_align; - grub_video_bitmap_v_align_t desktop_image_v_align; - grub_video_rgba_color_t desktop_color; + 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; diff --git a/include/grub/gfxterm.h b/include/grub/gfxterm.h index 7e1ff6dfc..295354baf 100644 --- a/include/grub/gfxterm.h +++ b/include/grub/gfxterm.h @@ -23,29 +23,22 @@ #include #include #include -#include 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, - grub_font_t font, int border_width); + 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); -struct grub_gfxterm_background -{ - struct grub_video_bitmap *bitmap; - int blend_text_bg; - grub_video_rgba_color_t default_bg_color; -}; - -extern struct grub_gfxterm_background EXPORT_VAR (grub_gfxterm_background); - -void EXPORT_FUNC (grub_gfxterm_video_update_color) (void); -void -EXPORT_FUNC (grub_gfxterm_get_dimensions) (unsigned *width, unsigned *height); - #endif /* ! GRUB_GFXTERM_HEADER */ diff --git a/include/grub/gfxwidgets.h b/include/grub/gfxwidgets.h index 8ce666c5c..f9678bf9e 100644 --- a/include/grub/gfxwidgets.h +++ b/include/grub/gfxwidgets.h @@ -36,7 +36,6 @@ struct grub_gfxmenu_box 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_border_width) (grub_gfxmenu_box_t self); 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); diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h index 292ea03f1..428ceb166 100644 --- a/include/grub/gpt_partition.h +++ b/include/grub/gpt_partition.h @@ -20,7 +20,15 @@ #define GRUB_GPT_PARTITION_HEADER 1 #include -#include + +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, \ @@ -28,19 +36,10 @@ } #define GRUB_GPT_PARTITION_TYPE_BIOS_BOOT \ - { grub_cpu_to_le32_compile_time (0x21686148), \ - grub_cpu_to_le16_compile_time (0x6449), \ - grub_cpu_to_le16_compile_time (0x6e6f), \ + { grub_cpu_to_le32 (0x21686148), grub_cpu_to_le16 (0x6449), grub_cpu_to_le16 (0x6e6f), \ { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } \ } -#define GRUB_GPT_PARTITION_TYPE_LDM \ - { grub_cpu_to_le32_compile_time (0x5808C8AAU),\ - grub_cpu_to_le16_compile_time (0x7E8F), \ - grub_cpu_to_le16_compile_time (0x42E0), \ - { 0x85, 0xD2, 0xE1, 0xE9, 0x04, 0x34, 0xCF, 0xB3 } \ - } - struct grub_gpt_header { grub_uint8_t magic[8]; @@ -57,22 +56,16 @@ struct grub_gpt_header grub_uint32_t maxpart; grub_uint32_t partentry_size; grub_uint32_t partentry_crc32; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_gpt_partentry { - grub_guid_t type; - grub_guid_t guid; + 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]; -}; - -grub_err_t -grub_gpt_partition_map_iterate (grub_disk_t disk, - grub_partition_iterate_hook_t hook, - void *hook_data); - +} __attribute__ ((packed)); #endif /* ! GRUB_GPT_PARTITION_HEADER */ diff --git a/include/grub/gui.h b/include/grub/gui.h index 3657623c8..7bd71acd3 100644 --- a/include/grub/gui.h +++ b/include/grub/gui.h @@ -22,14 +22,19 @@ #include #include #include -#include #ifndef GRUB_GUI_H #define GRUB_GUI_H 1 -/* The component ID identifying GUI components to be updated as the timeout - status changes. */ -#define GRUB_GFXMENU_TIMEOUT_COMPONENT_ID "__timeout__" +/* 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; @@ -67,8 +72,6 @@ struct grub_gui_list_ops { void (*set_view_info) (void *self, grub_gfxmenu_view_t view); - void (*refresh_list) (void *self, - grub_gfxmenu_view_t view); }; struct grub_gui_progress_ops @@ -76,80 +79,19 @@ struct grub_gui_progress_ops void (*set_state) (void *self, int visible, int start, int current, int end); }; -typedef void (*grub_gfxmenu_set_state_t) (void *self, int visible, int start, - int current, int end); - -struct grub_gfxmenu_timeout_notify -{ - struct grub_gfxmenu_timeout_notify *next; - grub_gfxmenu_set_state_t set_state; - grub_gui_component_t self; -}; - -extern struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications; - -static inline grub_err_t -grub_gfxmenu_timeout_register (grub_gui_component_t self, - grub_gfxmenu_set_state_t set_state) -{ - struct grub_gfxmenu_timeout_notify *ne = grub_malloc (sizeof (*ne)); - if (!ne) - return grub_errno; - ne->set_state = set_state; - ne->self = self; - ne->next = grub_gfxmenu_timeout_notifications; - grub_gfxmenu_timeout_notifications = ne; - return GRUB_ERR_NONE; -} - -static inline void -grub_gfxmenu_timeout_unregister (grub_gui_component_t self) -{ - struct grub_gfxmenu_timeout_notify **p, *q; - - for (p = &grub_gfxmenu_timeout_notifications, q = *p; - q; p = &(q->next), q = q->next) - if (q->self == self) - { - *p = q->next; - grub_free (q); - break; - } -} - typedef signed grub_fixed_signed_t; #define GRUB_FIXED_1 0x10000 -/* Special care is taken to round to nearest integer and not just truncate. */ -static inline signed -grub_divide_round (signed a, signed b) -{ - int neg = 0; - signed ret; - if (b < 0) - { - b = -b; - neg = !neg; - } - if (a < 0) - { - a = -a; - neg = !neg; - } - ret = (unsigned) (a + b / 2) / (unsigned) b; - return neg ? -ret : ret; -} - static inline signed grub_fixed_sfs_divide (signed a, grub_fixed_signed_t b) { - return grub_divide_round (a * GRUB_FIXED_1, 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 grub_divide_round (a, b); + return a / b; } static inline signed @@ -255,6 +197,23 @@ grub_gui_set_viewport (const grub_video_rect_t *r, grub_video_rect_t *old) 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) @@ -268,15 +227,4 @@ grub_video_have_common_points (const grub_video_rect_t *a, return 1; } -static inline int -grub_video_bounds_inside_region (const grub_video_rect_t *b, - const grub_video_rect_t *r) -{ - if (r->x > b->x || r->x + r->width < b->x + b->width) - return 0; - if (r->y > b->y || r->y + r->height < 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 index 34f9a090d..1baa2eede 100644 --- a/include/grub/gui_string_util.h +++ b/include/grub/gui_string_util.h @@ -30,4 +30,8 @@ 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/lib/dummy/halt.c b/include/grub/gzio.h similarity index 68% rename from grub-core/lib/dummy/halt.c rename to include/grub/gzio.h index 378d50f3f..cd7f39793 100644 --- a/grub-core/lib/dummy/halt.c +++ b/include/grub/gzio.h @@ -1,6 +1,7 @@ +/* gzio.h - prototypes for gzio */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. + * 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 @@ -16,17 +17,12 @@ * along with GRUB. If not, see . */ -#include -#include -#include -#include +#ifndef GRUB_GZIO_H +#define GRUB_GZIO_H 1 -void -grub_halt (void) -{ - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); +#include - /* Just stop here */ +grub_file_t grub_gzio_open (grub_file_t io, int transparent); +grub_file_t grub_gzfile_open (const char *name, int transparent); - while (1); -} +#endif /* ! GRUB_GZIO_H */ diff --git a/include/grub/handler.h b/include/grub/handler.h new file mode 100644 index 000000000..77dd7d9c1 --- /dev/null +++ b/include/grub/handler.h @@ -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 . + */ + +#ifndef GRUB_HANDLER_HEADER +#define GRUB_HANDLER_HEADER 1 + +#include +#include + +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 index e27993c42..d93b9a2c9 100644 --- a/include/grub/hfs.h +++ b/include/grub/hfs.h @@ -29,7 +29,7 @@ struct grub_hfs_extent /* The first physical block. */ grub_uint16_t first_block; grub_uint16_t count; -} GRUB_PACKED; +}; /* HFS stores extents in groups of 3. */ typedef struct grub_hfs_extent grub_hfs_datarecord_t[3]; @@ -39,9 +39,7 @@ typedef struct grub_hfs_extent grub_hfs_datarecord_t[3]; struct grub_hfs_sblock { grub_uint16_t magic; - grub_uint32_t ctime; - grub_uint32_t mtime; - grub_uint8_t unused[10]; + grub_uint8_t unused[18]; grub_uint32_t blksz; grub_uint8_t unused2[4]; grub_uint16_t first_block; @@ -50,23 +48,14 @@ struct grub_hfs_sblock /* A pascal style string that holds the volumename. */ grub_uint8_t volname[28]; - grub_uint8_t unused5[28]; - - grub_uint32_t ppc_bootdir; - grub_uint32_t intel_bootfile; - /* Folder opened when disk is mounted. Unused by GRUB. */ - grub_uint32_t showfolder; - grub_uint32_t os9folder; - grub_uint8_t unused6[4]; - grub_uint32_t osxfolder; - + grub_uint8_t unused5[52]; grub_uint64_t num_serial; grub_uint16_t embed_sig; struct grub_hfs_extent embed_extent; - grub_uint8_t unused7[4]; + grub_uint8_t unused6[4]; grub_hfs_datarecord_t extent_recs; grub_uint32_t catalog_size; grub_hfs_datarecord_t catalog_recs; -} GRUB_PACKED; +} __attribute__ ((packed)); #endif /* ! GRUB_HFS_HEADER */ diff --git a/include/grub/hfsplus.h b/include/grub/hfsplus.h deleted file mode 100644 index 2d8336aff..000000000 --- a/include/grub/hfsplus.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008,2009,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#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; -} GRUB_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]; -} GRUB_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[36]; - - grub_uint32_t ppc_bootdir; - grub_uint32_t intel_bootfile; - /* Folder opened when disk is mounted. Unused by GRUB. */ - grub_uint32_t showfolder; - grub_uint32_t os9folder; - grub_uint8_t unused4[4]; - grub_uint32_t osxfolder; - - 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 attr_file; - struct grub_hfsplus_forkdata startup_file; -} GRUB_PACKED; - -struct grub_hfsplus_compress_index -{ - grub_uint32_t start; - grub_uint32_t size; -}; - -struct grub_hfsplus_file -{ - struct grub_hfsplus_data *data; - struct grub_hfsplus_extent extents[8]; - struct grub_hfsplus_extent resource_extents[8]; - grub_uint64_t size; - grub_uint64_t resource_size; - grub_uint32_t fileid; - grub_int32_t mtime; - int compressed; - char *cbuf; - void *file; - struct grub_hfsplus_compress_index *compress_index; - grub_uint32_t cbuf_block; - grub_uint32_t compress_index_size; -}; - -struct grub_hfsplus_btree -{ - grub_uint32_t root; - grub_size_t nodesize; - - /* Catalog file node. */ - struct grub_hfsplus_file 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_hfsplus_btree attr_tree; - - int extoverflow_tree_ready; - - struct grub_hfsplus_file dirroot; - struct grub_hfsplus_file opened_file; - - /* This is the offset into the physical disk for an embedded HFS+ - filesystem (one inside a plain HFS wrapper). */ - grub_disk_addr_t embedded_offset; - int case_sensitive; -}; - -/* Internal representation of a catalog key. */ -struct grub_hfsplus_catkey_internal -{ - grub_uint32_t parent; - const grub_uint16_t *name; - grub_size_t namelen; -}; - -/* Internal representation of an extent overflow key. */ -struct grub_hfsplus_extkey_internal -{ - grub_uint32_t fileid; - grub_uint32_t start; - grub_uint8_t type; -}; - -struct grub_hfsplus_attrkey -{ - grub_uint16_t keylen; - grub_uint16_t unknown1[1]; - grub_uint32_t cnid; - grub_uint16_t unknown2[2]; - grub_uint16_t namelen; - grub_uint16_t name[0]; -} GRUB_PACKED; - -struct grub_hfsplus_attrkey_internal -{ - grub_uint32_t cnid; - const grub_uint16_t *name; - grub_size_t namelen; -}; - -struct grub_hfsplus_key_internal -{ - union - { - struct grub_hfsplus_extkey_internal extkey; - struct grub_hfsplus_catkey_internal catkey; - struct grub_hfsplus_attrkey_internal attrkey; - }; -}; - -/* 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[0]; -} GRUB_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; -} GRUB_PACKED; - -struct grub_hfsplus_key -{ - union - { - struct grub_hfsplus_extkey extkey; - struct grub_hfsplus_catkey catkey; - struct grub_hfsplus_attrkey attrkey; - grub_uint16_t keylen; - }; -} GRUB_PACKED; - -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; -} GRUB_PACKED; - -/* Return the offset of the record with the index INDEX, in the node - NODE which is part of the B+ tree BTREE. */ -static inline grub_uint16_t -grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree, - struct grub_hfsplus_btnode *node, unsigned index) -{ - char *cnode = (char *) node; - void *recptr; - if (btree->nodesize < index * sizeof (grub_uint16_t) + 2) - index = 0; - recptr = (&cnode[btree->nodesize - index * sizeof (grub_uint16_t) - 2]); - return grub_be_to_cpu16 (grub_get_unaligned16 (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, unsigned index) -{ - char *cnode = (char *) node; - grub_uint16_t offset; - offset = grub_hfsplus_btree_recoffset (btree, node, index); - if (offset > btree->nodesize - sizeof (struct grub_hfsplus_key)) - offset = 0; - return (struct grub_hfsplus_key *) &cnode[offset]; -} - -extern grub_err_t (*grub_hfsplus_open_compressed) (struct grub_hfsplus_file *node); -extern grub_ssize_t (*grub_hfsplus_read_compressed) (struct grub_hfsplus_file *node, - grub_off_t pos, - grub_size_t len, - char *buf); - -grub_ssize_t -grub_hfsplus_read_file (struct grub_hfsplus_file *node, - grub_disk_read_hook_t read_hook, void *read_hook_data, - grub_off_t pos, grub_size_t len, char *buf); -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, - grub_off_t *keyoffset); -grub_err_t -grub_mac_bless_inode (grub_device_t dev, grub_uint32_t inode, int is_dir, - int intel); -grub_err_t -grub_mac_bless_file (grub_device_t dev, const char *path_in, int intel); diff --git a/include/grub/i18n.h b/include/grub/i18n.h index 468602d92..0cba54765 100644 --- a/include/grub/i18n.h +++ b/include/grub/i18n.h @@ -22,10 +22,10 @@ #include #include -/* NLS can be disabled through the configure --disable-nls option. */ -#if (defined(ENABLE_NLS) && ENABLE_NLS) || !defined (GRUB_UTIL) +extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); -extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s) __attribute__ ((format_arg (1))); +/* NLS can be disabled through the configure --disable-nls option. */ +#if ENABLE_NLS # ifdef GRUB_UTIL @@ -34,33 +34,25 @@ extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s) __attribute__ ((f # endif /* GRUB_UTIL */ -#else /* ! (defined(ENABLE_NLS) && ENABLE_NLS) */ +#else /* ! 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". */ -static inline const char * __attribute__ ((always_inline,format_arg (1))) -gettext (const char *str) -{ - return str; -} +# 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) */ +#endif /* ENABLE_NLS */ #ifdef GRUB_UTIL -static inline const char * __attribute__ ((always_inline,format_arg (1))) -_ (const char *str) -{ - return gettext(str); -} +# define _(str) gettext(str) #else -static inline const char * __attribute__ ((always_inline,format_arg (1))) -_ (const char *str) -{ - return grub_gettext(str); -} +# define _(str) grub_gettext(str) #endif /* GRUB_UTIL */ #define N_(str) str diff --git a/include/grub/i386/bsd.h b/include/grub/i386/bsd.h index 523dd8621..4d55f04fb 100644 --- a/include/grub/i386/bsd.h +++ b/include/grub/i386/bsd.h @@ -20,8 +20,6 @@ #define GRUB_BSD_CPU_HEADER 1 #include -#include - #include #include #include @@ -29,6 +27,7 @@ #include #include + enum bsd_kernel_types { KERNEL_TYPE_NONE, @@ -64,63 +63,37 @@ struct grub_freebsd_bootinfo grub_uint32_t kern_end; grub_uint32_t environment; grub_uint32_t tags; -} GRUB_PACKED; +} __attribute__ ((packed)); -struct freebsd_tag_header +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; - grub_uint32_t len; }; -grub_err_t grub_freebsd_load_elfmodule32 (struct grub_relocator *relocator, - grub_file_t file, int argc, +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 (struct grub_relocator *relocator, - grub_file_t file, int argc, +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 (struct grub_relocator *relocator, - grub_file_t file, - const char *filename, +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 (struct grub_relocator *relocator, - grub_file_t file, - const char *filename, +grub_err_t grub_freebsd_load_elf_meta64 (grub_file_t file, grub_addr_t *kern_end); -grub_err_t grub_netbsd_load_elf_meta32 (struct grub_relocator *relocator, - grub_file_t file, - const char *filename, - grub_addr_t *kern_end); -grub_err_t grub_netbsd_load_elf_meta64 (struct grub_relocator *relocator, - grub_file_t file, - const char *filename, - grub_addr_t *kern_end); - -grub_err_t grub_bsd_add_meta (grub_uint32_t type, - const void *data, grub_uint32_t len); -grub_err_t grub_freebsd_add_meta_module (const char *filename, const char *type, +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); -struct grub_openbsd_ramdisk_descriptor -{ - grub_size_t max_size; - grub_uint8_t *target; - grub_uint32_t *size; -}; - -grub_err_t grub_openbsd_find_ramdisk32 (grub_file_t file, - const char *filename, - grub_addr_t kern_start, - void *kern_chunk_src, - struct grub_openbsd_ramdisk_descriptor *desc); -grub_err_t grub_openbsd_find_ramdisk64 (grub_file_t file, - const char *filename, - grub_addr_t kern_start, - void *kern_chunk_src, - struct grub_openbsd_ramdisk_descriptor *desc); - 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; diff --git a/include/grub/i386/cmos.h b/include/grub/i386/cmos.h index 27a2b214d..8b1fa3586 100644 --- a/include/grub/i386/cmos.h +++ b/include/grub/i386/cmos.h @@ -24,7 +24,5 @@ #define GRUB_CMOS_ADDR_REG 0x70 #define GRUB_CMOS_DATA_REG 0x71 -#define GRUB_CMOS_ADDR_REG_HI 0x72 -#define GRUB_CMOS_DATA_REG_HI 0x73 #endif /* GRUB_CPU_CMOS_H */ diff --git a/include/grub/i386/coreboot/console.h b/include/grub/i386/coreboot/console.h index 9cfa24759..2ffef7300 100644 --- a/include/grub/i386/coreboot/console.h +++ b/include/grub/i386/coreboot/console.h @@ -22,11 +22,4 @@ void grub_vga_text_init (void); void grub_vga_text_fini (void); -void grub_video_coreboot_fb_init (void); -void grub_video_coreboot_fb_early_init (void); -void grub_video_coreboot_fb_late_init (void); -void grub_video_coreboot_fb_fini (void); - -extern struct grub_linuxbios_table_framebuffer *grub_video_coreboot_fbtable; - #endif /* ! GRUB_MACHINE_CONSOLE_HEADER */ diff --git a/grub-core/kern/loongarch64/cache_flush.S b/include/grub/i386/coreboot/init.h similarity index 70% rename from grub-core/kern/loongarch64/cache_flush.S rename to include/grub/i386/coreboot/init.h index a587ed58f..e67007414 100644 --- a/grub-core/kern/loongarch64/cache_flush.S +++ b/include/grub/i386/coreboot/init.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 Free Software Foundation, Inc. + * 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 @@ -16,18 +16,13 @@ * along with GRUB. If not, see . */ +#ifndef GRUB_INIT_I386_LINUXBIOS_HEADER +#define GRUB_INIT_I386_LINUXBIOS_HEADER 1 + #include +#include - .file "cache_flush.S" - .text -/* - * No further work to do because cache consistency is maintained by hardware on - * LoongArch. - */ -FUNCTION(grub_arch_clean_dcache_range) - dbar 0 - jr $ra +void EXPORT_FUNC(grub_stop) (void) __attribute__ ((noreturn)); +void EXPORT_FUNC(grub_stop_floppy) (void); -FUNCTION(grub_arch_invalidate_icache_range) - ibar 0 - jr $ra +#endif diff --git a/include/grub/i386/coreboot/kernel.h b/include/grub/i386/coreboot/kernel.h index e69de29bb..fb60668cc 100644 --- a/include/grub/i386/coreboot/kernel.h +++ b/include/grub/i386/coreboot/kernel.h @@ -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 . + */ + +#ifndef GRUB_KERNEL_MACHINE_HEADER +#define GRUB_KERNEL_MACHINE_HEADER 1 + +#include + +#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 new file mode 100644 index 000000000..d3f36bba5 --- /dev/null +++ b/include/grub/i386/coreboot/loader.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/coreboot/memory.h b/include/grub/i386/coreboot/memory.h index 1501772ac..434ae622e 100644 --- a/include/grub/i386/coreboot/memory.h +++ b/include/grub/i386/coreboot/memory.h @@ -21,33 +21,49 @@ #define _GRUB_MEMORY_MACHINE_LB_HEADER 1 #include +#include #ifndef ASM_FILE #include #include -#include #endif -#include -#include +#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 0 +#define GRUB_LINUXBIOS_MEMBER_MEMORY 1 + 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); -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_err_t EXPORT_FUNC(grub_machine_mmap_iterate) + (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); #endif diff --git a/include/grub/i386/cpuid.h b/include/grub/i386/cpuid.h index f7ae4b0a4..09b313bb8 100644 --- a/include/grub/i386/cpuid.h +++ b/include/grub/i386/cpuid.h @@ -20,66 +20,5 @@ #define GRUB_CPU_CPUID_HEADER 1 extern unsigned char grub_cpuid_has_longmode; -extern unsigned char grub_cpuid_has_pae; - -#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 - -#ifdef __PIC__ -#define grub_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)) -#else -#define grub_cpuid(num,a,b,c,d) \ - asm volatile ("cpuid" \ - : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ - : "0" (num)) -#endif #endif diff --git a/include/grub/i386/efi/kernel.h b/include/grub/i386/efi/kernel.h index e69de29bb..c0549f41a 100644 --- a/include/grub/i386/efi/kernel.h +++ b/include/grub/i386/efi/kernel.h @@ -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 . + */ + +#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/lib/mips/qemu_mips/reboot.c b/include/grub/i386/efi/loader.h similarity index 78% rename from grub-core/lib/mips/qemu_mips/reboot.c rename to include/grub/i386/efi/loader.h index ba0f6ac3c..222dae82d 100644 --- a/grub-core/lib/mips/qemu_mips/reboot.c +++ b/include/grub/i386/efi/loader.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. + * 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 @@ -16,12 +16,7 @@ * along with GRUB. If not, see . */ -#include -#include +#ifndef GRUB_LOADER_MACHINE_HEADER +#define GRUB_LOADER_MACHINE_HEADER 1 -void -grub_reboot (void) -{ - grub_outl (42, 0xbfbf0000); - while (1); -} +#endif /* ! GRUB_LOADER_MACHINE_HEADER */ diff --git a/include/grub/i386/efi/memory.h b/include/grub/i386/efi/memory.h index 2c64918e3..c9a61bb77 100644 --- a/include/grub/i386/efi/memory.h +++ b/include/grub/i386/efi/memory.h @@ -1,6 +1 @@ -#ifndef GRUB_MEMORY_CPU_HEADER #include - -#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff - -#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/i386/efi/serial.h b/include/grub/i386/efi/serial.h deleted file mode 100644 index 2d8563414..000000000 --- a/include/grub/i386/efi/serial.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/ia64/efi/time.h b/include/grub/i386/efi/time.h similarity index 93% rename from include/grub/ia64/efi/time.h rename to include/grub/i386/efi/time.h index 897ce9c00..7a9241fff 100644 --- a/include/grub/ia64/efi/time.h +++ b/include/grub/i386/efi/time.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. + * 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 @@ -15,6 +15,7 @@ * You should have received a copy of the GNU General Public License * along with GRUB. If not, see . */ + #ifndef GRUB_MACHINE_TIME_HEADER #define GRUB_MACHINE_TIME_HEADER 1 diff --git a/include/grub/i386/floppy.h b/include/grub/i386/floppy.h deleted file mode 100644 index 0e3690549..000000000 --- a/include/grub/i386/floppy.h +++ /dev/null @@ -1,36 +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 . - */ - -#ifndef GRUB_FLOPPY_CPU_HEADER -#define GRUB_FLOPPY_CPU_HEADER 1 - -#define GRUB_FLOPPY_REG_DIGITAL_OUTPUT 0x3f2 - -#ifndef ASM_FILE -#include - -/* Stop the floppy drive from spinning, so that other software is - jumped to with a known state. */ -static inline void -grub_stop_floppy (void) -{ - grub_outb (0, GRUB_FLOPPY_REG_DIGITAL_OUTPUT); -} -#endif - -#endif diff --git a/include/grub/i386/gdb.h b/include/grub/i386/gdb.h deleted file mode 100644 index 92d2dacda..000000000 --- a/include/grub/i386/gdb.h +++ /dev/null @@ -1,78 +0,0 @@ -/* i386/gdb.h - i386 specific definitions for the remote GDB stub */ -/* - * Copyright (C) 2006 Lubomir Kundrak - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef GRUB_GDB_CPU_HEADER -#define GRUB_GDB_CPU_HEADER 1 - -#define GRUB_GDB_LAST_TRAP 31 -/* You may have to edit the bottom of machdep.S when adjusting - GRUB_GDB_LAST_TRAP. */ -#define GRUB_MACHINE_NR_REGS 16 - -#define EAX 0 -#define ECX 1 -#define EDX 2 -#define EBX 3 -#define ESP 4 -#define EBP 5 -#define ESI 6 -#define EDI 7 -#define EIP 8 -#define EFLAGS 9 -#define CS 10 -#define SS 11 -#define DS 12 -#define ES 13 -#define FS 14 -#define GS 15 - -#define PC EIP -#define FP EBP -#define SP ESP -#define PS EFLAGS - -#ifndef ASM_FILE - -#include - -#define GRUB_CPU_TRAP_GATE 15 - -struct grub_cpu_interrupt_gate -{ - grub_uint16_t offset_lo; - grub_uint16_t selector; - grub_uint8_t unused; - grub_uint8_t gate; - grub_uint16_t offset_hi; -} GRUB_PACKED; - -struct grub_cpu_idt_descriptor -{ - grub_uint16_t limit; - grub_uint32_t base; -} GRUB_PACKED; - -extern void (*grub_gdb_trapvec[]) (void); -void grub_gdb_idtinit (void); -void grub_gdb_idtrestore (void); -void grub_gdb_trap (int trap_no) __attribute__ ((regparm(3))); - -#endif /* ! ASM */ -#endif /* ! GRUB_GDB_CPU_HEADER */ - diff --git a/include/grub/arc/console.h b/include/grub/i386/ieee1275/console.h similarity index 92% rename from include/grub/arc/console.h rename to include/grub/i386/ieee1275/console.h index e054f54f5..854724ac1 100644 --- a/include/grub/arc/console.h +++ b/include/grub/i386/ieee1275/console.h @@ -22,8 +22,7 @@ #include /* Initialize the console system. */ -void grub_console_init_early (void); -void grub_console_init_lately (void); +void grub_console_init (void); /* Finish the console system. */ void grub_console_fini (void); diff --git a/include/grub/i386/ieee1275/kernel.h b/include/grub/i386/ieee1275/kernel.h index e69de29bb..dccf8cbe1 100644 --- a/include/grub/i386/ieee1275/kernel.h +++ b/include/grub/i386/ieee1275/kernel.h @@ -0,0 +1 @@ +#include diff --git a/grub-core/lib/i386/reboot_trampoline.S b/include/grub/i386/ieee1275/loader.h similarity index 67% rename from grub-core/lib/i386/reboot_trampoline.S rename to include/grub/i386/ieee1275/loader.h index c088cd081..20df2e1d6 100644 --- a/grub-core/lib/i386/reboot_trampoline.S +++ b/include/grub/i386/ieee1275/loader.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. + * 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 @@ -16,19 +16,14 @@ * along with GRUB. If not, see . */ +#ifndef GRUB_LOADER_MACHINE_HEADER +#define GRUB_LOADER_MACHINE_HEADER 1 + +#include #include -#include +#include - .p2align 4 +void grub_rescue_cmd_linux (int argc, char *argv[]); +void grub_rescue_cmd_initrd (int argc, char *argv[]); -VARIABLE(grub_reboot_start) - .code16 - - /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */ - movw $0x0472, %di - xorw %ax, %ax - movw %ax, (%di) - ljmp $0xf000, $0xfff0 - - .code32 -VARIABLE(grub_reboot_end) +#endif /* ! GRUB_LOADER_MACHINE_HEADER */ diff --git a/include/grub/i386/ieee1275/memory.h b/include/grub/i386/ieee1275/memory.h index 8dd6f7c8c..386ee4a05 100644 --- a/include/grub/i386/ieee1275/memory.h +++ b/include/grub/i386/ieee1275/memory.h @@ -1 +1 @@ -#include +#include diff --git a/include/grub/i386/ieee1275/time.h b/include/grub/i386/ieee1275/time.h new file mode 100644 index 000000000..6f474bada --- /dev/null +++ b/include/grub/i386/ieee1275/time.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/io.h b/include/grub/i386/io.h index e9cd80957..ae12a3e3d 100644 --- a/include/grub/i386/io.h +++ b/include/grub/i386/io.h @@ -28,7 +28,7 @@ grub_inb (unsigned short int port) { unsigned char _v; - asm volatile ("inb %w1,%0":"=a" (_v):"Nd" (port)); + __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port)); return _v; } @@ -37,7 +37,7 @@ grub_inw (unsigned short int port) { unsigned short _v; - asm volatile ("inw %w1,%0":"=a" (_v):"Nd" (port)); + __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (port)); return _v; } @@ -46,27 +46,27 @@ grub_inl (unsigned short int port) { unsigned int _v; - asm volatile ("inl %w1,%0":"=a" (_v):"Nd" (port)); + __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)); + __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)); + __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)); + __asm__ __volatile__ ("outl %0,%w1": :"a" (value), "Nd" (port)); } #endif /* _SYS_IO_H */ diff --git a/include/grub/ia64/kernel.h b/include/grub/i386/kernel.h similarity index 65% rename from include/grub/ia64/kernel.h rename to include/grub/i386/kernel.h index c5496a00b..5514c8ccf 100644 --- a/include/grub/ia64/kernel.h +++ b/include/grub/i386/kernel.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010 Free Software Foundation, Inc. + * 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 @@ -16,10 +16,20 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_CPU_KERNEL_HEADER -#define GRUB_CPU_KERNEL_HEADER 1 +#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 -#define GRUB_MOD_GAP 0x0 +#endif -#endif /* ! GRUB_CPU_KERNEL_HEADER */ +/* 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 index 6e0a8e5be..f02a722d6 100644 --- a/include/grub/i386/linux.h +++ b/include/grub/i386/linux.h @@ -16,12 +16,10 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_I386_LINUX_HEADER -#define GRUB_I386_LINUX_HEADER 1 +#ifndef GRUB_LINUX_MACHINE_HEADER +#define GRUB_LINUX_MACHINE_HEADER 1 -#include - -#define GRUB_LINUX_I386_MAGIC_SIGNATURE 0x53726448 /* "HdrS" */ +#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 @@ -43,17 +41,9 @@ #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 -#define VIDEO_CAPABILITY_SKIP_QUIRKS (1 << 0) -#define VIDEO_CAPABILITY_64BIT_BASE (1 << 1) /* Frame buffer base is 64-bit. */ - -/* Maximum number of MBR signatures to store. */ -#define EDD_MBR_SIG_MAX 16 - -/* Number of edd_info structs starting at EDDBUF. */ -#define EDDMAXNR 6 - #ifdef __x86_64__ #define GRUB_LINUX_EFI_SIGNATURE \ @@ -72,292 +62,29 @@ #define GRUB_LINUX_OFW_SIGNATURE \ (' ' << 24 | 'W' << 16 | 'F' << 8 | 'O') -#define LINUX_X86_XLF_KERNEL_64 (1<<0) -#define LINUX_X86_XLF_CAN_BE_LOADED_ABOVE_4G (1<<1) -#define LINUX_X86_XLF_EFI_HANDOVER_32 (1<<2) -#define LINUX_X86_XLF_EFI_HANDOVER_64 (1<<3) -#define LINUX_X86_XLF_EFI_KEXEC (1<<4) -#define LINUX_X86_XLF_5LEVEL (1<<5) -#define LINUX_X86_XLF_5LEVEL_ENABLED (1<<6) - -#define LINUX_X86_STARTUP64_OFFSET 0x200 - #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_BADRAM 5 +#define GRUB_E820_EXEC_CODE 5 -#define GRUB_E820_MAX_ENTRIES_ZEROPAGE 128 +#define GRUB_E820_MAX_ENTRY 128 -struct grub_screen_info -{ - grub_uint8_t orig_x; /* 0x00 */ - grub_uint8_t orig_y; /* 0x01 */ - grub_uint16_t ext_mem_k; /* 0x02 */ - grub_uint16_t orig_video_page; /* 0x04 */ - grub_uint8_t orig_video_mode; /* 0x06 */ - grub_uint8_t orig_video_cols; /* 0x07 */ - grub_uint8_t flags; /* 0x08 */ - grub_uint8_t unused2; /* 0x09 */ - grub_uint16_t orig_video_ega_bx; /* 0x0a */ - grub_uint16_t unused3; /* 0x0c */ - grub_uint8_t orig_video_lines; /* 0x0e */ - grub_uint8_t orig_video_isVGA; /* 0x0f */ - grub_uint16_t orig_video_points; /* 0x10 */ - - /* VESA graphic mode -- linear frame buffer */ - grub_uint16_t lfb_width; /* 0x12 */ - grub_uint16_t lfb_height; /* 0x14 */ - grub_uint16_t lfb_depth; /* 0x16 */ - grub_uint32_t lfb_base; /* 0x18 */ - grub_uint32_t lfb_size; /* 0x1c */ - grub_uint16_t cl_magic, cl_offset; /* 0x20 */ - grub_uint16_t lfb_linelength; /* 0x24 */ - grub_uint8_t red_size; /* 0x26 */ - grub_uint8_t red_pos; /* 0x27 */ - grub_uint8_t green_size; /* 0x28 */ - grub_uint8_t green_pos; /* 0x29 */ - grub_uint8_t blue_size; /* 0x2a */ - grub_uint8_t blue_pos; /* 0x2b */ - grub_uint8_t rsvd_size; /* 0x2c */ - grub_uint8_t rsvd_pos; /* 0x2d */ - grub_uint16_t vesapm_seg; /* 0x2e */ - grub_uint16_t vesapm_off; /* 0x30 */ - grub_uint16_t pages; /* 0x32 */ - grub_uint16_t vesa_attributes; /* 0x34 */ - grub_uint32_t capabilities; /* 0x36 */ - grub_uint32_t ext_lfb_base; /* 0x3a */ - grub_uint8_t _reserved[2]; /* 0x3e */ -} GRUB_PACKED; - -struct grub_apm_bios_info -{ - grub_uint16_t version; - grub_uint16_t cseg; - grub_uint32_t offset; - grub_uint16_t cseg_16; - grub_uint16_t dseg; - grub_uint16_t flags; - grub_uint16_t cseg_len; - grub_uint16_t cseg_16_len; - grub_uint16_t dseg_len; -}; - -struct grub_ist_info -{ - grub_uint32_t signature; - grub_uint32_t command; - grub_uint32_t event; - grub_uint32_t perf_level; -}; - -struct grub_sys_desc_table -{ - grub_uint16_t length; - grub_uint8_t table[14]; -}; - -struct grub_olpc_ofw_header { - grub_uint32_t ofw_magic; /* OFW signature */ - grub_uint32_t ofw_version; - grub_uint32_t cif_handler; /* callback into OFW */ - grub_uint32_t irq_desc_table; -} GRUB_PACKED; - -struct grub_setup_header -{ - grub_uint8_t setup_sects; /* The size of the setup in sectors */ - grub_uint16_t root_flags; /* If the root is mounted readonly */ - grub_uint32_t syssize; /* 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; /* 1fe */ - 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_uint8_t ext_loader_ver; /* Extended loader version */ - grub_uint8_t ext_loader_type; /* Extended loader type */ - grub_uint32_t cmd_line_ptr; /* Points to the kernel command line */ - grub_uint32_t initrd_addr_max; /* Maximum initrd address */ - grub_uint32_t kernel_alignment; /* Alignment of the kernel */ - grub_uint8_t relocatable_kernel; /* Is the kernel relocatable */ - grub_uint8_t min_alignment; - grub_uint16_t xloadflags; - grub_uint32_t cmdline_size; /* Size of the kernel command line */ - grub_uint32_t hardware_subarch; - grub_uint64_t hardware_subarch_data; - grub_uint32_t payload_offset; - grub_uint32_t payload_length; - grub_uint64_t setup_data; - grub_uint64_t pref_address; - grub_uint32_t init_size; - grub_uint32_t handover_offset; - grub_uint32_t kernel_info_offset; -} GRUB_PACKED; - -struct grub_boot_e820_entry +struct grub_e820_mmap { grub_uint64_t addr; grub_uint64_t size; grub_uint32_t type; -} GRUB_PACKED; +} __attribute__((packed)); -struct grub_edd_device_params -{ - grub_uint16_t length; - grub_uint16_t info_flags; - grub_uint32_t num_default_cylinders; - grub_uint32_t num_default_heads; - grub_uint32_t sectors_per_track; - grub_uint64_t number_of_sectors; - grub_uint16_t bytes_per_sector; - grub_uint32_t dpte_ptr; /* 0xFFFFFFFF for our purposes */ - grub_uint16_t key; /* = 0xBEDD */ - grub_uint8_t device_path_info_length; /* = 44 */ - grub_uint8_t reserved2; - grub_uint16_t reserved3; - grub_uint8_t host_bus_type[4]; - grub_uint8_t interface_type[8]; - union - { - struct - { - grub_uint16_t base_address; - grub_uint16_t reserved1; - grub_uint32_t reserved2; - } isa; - struct - { - grub_uint8_t bus; - grub_uint8_t slot; - grub_uint8_t function; - grub_uint8_t channel; - grub_uint32_t reserved; - } pci; - /* pcix is same as pci */ - struct - { - grub_uint64_t reserved; - } ibnd; - struct - { - grub_uint64_t reserved; - } xprs; - struct - { - grub_uint64_t reserved; - } htpt; - struct - { - grub_uint64_t reserved; - } unknown; - } interface_path; - union - { - struct - { - grub_uint8_t device; - grub_uint8_t reserved1; - grub_uint16_t reserved2; - grub_uint32_t reserved3; - grub_uint64_t reserved4; - } ata; - struct - { - grub_uint8_t device; - grub_uint8_t lun; - grub_uint8_t reserved1; - grub_uint8_t reserved2; - grub_uint32_t reserved3; - grub_uint64_t reserved4; - } atapi; - struct - { - grub_uint16_t id; - grub_uint64_t lun; - grub_uint16_t reserved1; - grub_uint32_t reserved2; - } scsi; - struct - { - grub_uint64_t serial_number; - grub_uint64_t reserved; - } usb; - struct - { - grub_uint64_t eui; - grub_uint64_t reserved; - } i1394; - struct - { - grub_uint64_t wwid; - grub_uint64_t lun; - } fibre; - struct - { - grub_uint64_t identity_tag; - grub_uint64_t reserved; - } i2o; - struct - { - grub_uint32_t array_number; - grub_uint32_t reserved1; - grub_uint64_t reserved2; - } raid; - struct - { - grub_uint8_t device; - grub_uint8_t reserved1; - grub_uint16_t reserved2; - grub_uint32_t reserved3; - grub_uint64_t reserved4; - } sata; - struct - { - grub_uint64_t reserved1; - grub_uint64_t reserved2; - } unknown; - } device_path; - grub_uint8_t reserved4; - grub_uint8_t checksum; -} GRUB_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. */ -struct grub_edd_info -{ - grub_uint8_t device; - grub_uint8_t version; - grub_uint16_t interface_support; - grub_uint16_t legacy_max_cylinder; - grub_uint8_t legacy_max_head; - grub_uint8_t legacy_sectors_per_track; - struct grub_edd_device_params params; -} GRUB_PACKED; - -enum - { - GRUB_VIDEO_LINUX_TYPE_TEXT = 0x01, - GRUB_VIDEO_LINUX_TYPE_VESA = 0x23, /* VESA VGA in graphic mode. */ - GRUB_VIDEO_LINUX_TYPE_EFIFB = 0x70, /* EFI Framebuffer. */ - GRUB_VIDEO_LINUX_TYPE_SIMPLE = 0x70 /* Linear framebuffer without any additional functions. */ - }; - -/* For the Linux/i386 boot protocol version 2.10. */ -struct linux_i386_kernel_header +/* 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 */ @@ -397,111 +124,158 @@ struct linux_i386_kernel_header 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_uint32_t initrd_addr_max; /* Highest address for initrd */ - grub_uint32_t kernel_alignment; - grub_uint8_t relocatable; - grub_uint8_t min_alignment; - grub_uint16_t xloadflags; - grub_uint32_t cmdline_size; - grub_uint32_t hardware_subarch; - grub_uint64_t hardware_subarch_data; - grub_uint32_t payload_offset; - grub_uint32_t payload_length; - grub_uint64_t setup_data; - grub_uint64_t pref_address; - grub_uint32_t init_size; - grub_uint32_t handover_offset; -} GRUB_PACKED; + 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 6.13.7 stable. This is used - * by the setup sectors of Linux, and must be simulated by GRUB - * on EFI, because the setup sectors depend on BIOS. - */ +/* 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 { - struct grub_screen_info screen_info; /* 0 */ - struct grub_apm_bios_info apm_bios_info; /* 40 */ - grub_uint8_t _pad2[4]; /* 54 */ - grub_uint64_t tboot_addr; /* 58 */ - struct grub_ist_info ist_info; /* 60 */ - grub_uint64_t acpi_rsdp_addr; /* 70 */ - grub_uint8_t _pad3[8]; /* 78 */ - grub_uint8_t hd0_info[16]; /* 80 */ - grub_uint8_t hd1_info[16]; /* 90 */ - struct grub_sys_desc_table sys_desc_table; /* a0 */ - struct grub_olpc_ofw_header olpc_ofw_header; /* b0 */ - grub_uint32_t ext_ramdisk_image; /* c0 */ - grub_uint32_t ext_ramdisk_size; /* c4 */ - grub_uint32_t ext_cmd_line_ptr; /* c8 */ - grub_uint8_t _pad4[112]; /* cc */ - grub_uint32_t cc_blob_address; /* 13c */ + 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]; - /* - * edid_info should be a struct with "unsigned char dummy[128]" and - * efi_info should be a struct as well, starting at 0x1c0. However, - * for backwards compatibility, GRUB can have efi_systab at 0x1b8 and - * padding at 0x1bc (or padding at both spots). This cuts into the end - * of edid_info. Make edid_info inline and only make it go up to 0x1b8. - */ - grub_uint8_t edid_info[0x1b8 - 0x140]; /* 140 */ union { struct - { - grub_uint32_t efi_systab; /* 1b8 */ - grub_uint32_t padding7_2; /* 1bc */ - grub_uint32_t efi_loader_signature; /* 1c0 */ - grub_uint32_t efi_memdesc_size; /* 1c4 */ - grub_uint32_t efi_memdesc_version; /* 1c8 */ - grub_uint32_t efi_memmap_size; /* 1cc */ - grub_uint32_t efi_memmap; /* 1d0 */ - } v0204; + { + 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_loader_signature; /* 1c0 */ - grub_uint32_t efi_systab; /* 1c4 */ - grub_uint32_t efi_memdesc_size; /* 1c8 */ - grub_uint32_t efi_memdesc_version; /* 1cc */ - grub_uint32_t efi_memmap; /* 1d0 */ - grub_uint32_t efi_memmap_size; /* 1d4 */ - } v0206; - struct - { - grub_uint32_t padding7_1; /* 1b8 */ - grub_uint32_t padding7_2; /* 1bc */ - grub_uint32_t efi_loader_signature; /* 1c0 */ - grub_uint32_t efi_systab; /* 1c4 */ - grub_uint32_t efi_memdesc_size; /* 1c8 */ - grub_uint32_t efi_memdesc_version; /* 1cc */ - grub_uint32_t efi_memmap; /* 1d0 */ - grub_uint32_t efi_memmap_size; /* 1d4 */ - grub_uint32_t efi_systab_hi; /* 1d8 */ - grub_uint32_t efi_memmap_hi; /* 1dc */ - } v0208; - } efi_info; + { + 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_k; /* 1e0 */ - grub_uint32_t scratch; /* 1e4 */ - grub_uint8_t e820_entries; /* 1e8 */ - grub_uint8_t eddbuf_entries; /* 1e9 */ - grub_uint8_t edd_mbr_sig_buf_entries; /* 1ea */ - grub_uint8_t kbd_status; /* 1eb */ - grub_uint8_t secure_boot; /* 1ec */ - grub_uint8_t _pad5[2]; /* 1ed */ - grub_uint8_t sentinel; /* 1ef */ - grub_uint8_t _pad6[1]; /* 1f0 */ - struct grub_setup_header hdr; /* 1f1 */ - grub_uint8_t _pad7[0x290 - 0x1f1 - sizeof(struct grub_setup_header)]; - grub_uint32_t edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 290 */ - struct grub_boot_e820_entry e820_table[GRUB_E820_MAX_ENTRIES_ZEROPAGE]; /* 2d0 */ - grub_uint8_t _pad8[48]; /* cd0 */ - struct grub_edd_info eddbuf[EDDMAXNR]; /* d00 */ - grub_uint8_t _pad9[276]; /* eec */ -} GRUB_PACKED; + 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_I386_LINUX_HEADER */ +#endif /* ! GRUB_LINUX_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/int.h b/include/grub/i386/loader.h similarity index 55% rename from include/grub/i386/pc/int.h rename to include/grub/i386/loader.h index a60104001..05954b6db 100644 --- a/include/grub/i386/pc/int.h +++ b/include/grub/i386/loader.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. + * 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 @@ -16,18 +16,22 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_INTERRUPT_MACHINE_HEADER -#define GRUB_INTERRUPT_MACHINE_HEADER 1 +#ifndef GRUB_LOADER_CPU_HEADER +#define GRUB_LOADER_CPU_HEADER 1 +#include +#include #include -#include -void EXPORT_FUNC (grub_bios_interrupt) (grub_uint8_t intno, - struct grub_bios_int_registers *regs) - __attribute__ ((regparm(3))); +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 struct grub_i386_idt *EXPORT_VAR(grub_realidt); +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 +#endif /* ! GRUB_LOADER_CPU_HEADER */ diff --git a/include/grub/i386/macho.h b/include/grub/i386/macho.h index e15167a50..f22c21190 100644 --- a/include/grub/i386/macho.h +++ b/include/grub/i386/macho.h @@ -21,12 +21,26 @@ #include -#define GRUB_MACHO_CPUTYPE_IS_HOST32(x) ((x) == GRUB_MACHO_CPUTYPE_IA32) -#define GRUB_MACHO_CPUTYPE_IS_HOST64(x) ((x) == GRUB_MACHO_CPUTYPE_AMD64) -#ifdef __x86_64__ -#define GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT(x) ((x) == GRUB_MACHO_CPUTYPE_AMD64) -#else -#define GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT(x) ((x) == GRUB_MACHO_CPUTYPE_IA32) -#endif +#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 index c64529630..466947cc6 100644 --- a/include/grub/i386/memory.h +++ b/include/grub/i386/memory.h @@ -20,62 +20,11 @@ #ifndef GRUB_MEMORY_CPU_HEADER #define GRUB_MEMORY_CPU_HEADER 1 -#define GRUB_PAGE_SHIFT 12 -#define GRUB_PAGE_SIZE (1UL << GRUB_PAGE_SHIFT) - /* The flag for protected mode. */ #define GRUB_MEMORY_CPU_CR0_PE_ON 0x1 -#define GRUB_MEMORY_CPU_CR4_PAE_ON 0x00000020 -#define GRUB_MEMORY_CPU_CR4_PSE_ON 0x00000010 +#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 -#define GRUB_MEMORY_MACHINE_UPPER_START 0x100000 /* 1 MiB */ -#define GRUB_MEMORY_MACHINE_LOWER_SIZE GRUB_MEMORY_MACHINE_UPPER_START - -/* Some PTE definitions. */ -#define GRUB_PAGE_PRESENT 0x00000001 -#define GRUB_PAGE_RW 0x00000002 -#define GRUB_PAGE_USER 0x00000004 - -#ifndef ASM_FILE - -#define GRUB_MMAP_MALLOC_LOW 1 - -#include - -struct grub_e820_mmap_entry -{ - grub_uint64_t addr; - grub_uint64_t len; - grub_uint32_t type; -} GRUB_PACKED; - -grub_uint64_t grub_mmap_get_upper (void); -grub_uint64_t grub_mmap_get_lower (void); -grub_uint64_t grub_mmap_get_post64 (void); - -typedef grub_addr_t grub_phys_addr_t; - -static inline grub_phys_addr_t -grub_vtop (void *a) -{ - return (grub_phys_addr_t) a; -} - -static inline void * -grub_map_memory (grub_phys_addr_t a, grub_size_t size __attribute__ ((unused))) -{ - return (void *) a; -} - -static inline void -grub_unmap_memory (void *a __attribute__ ((unused)), - grub_size_t size __attribute__ ((unused))) -{ -} - -#endif - #endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/i386/memory_raw.h b/include/grub/i386/memory_raw.h deleted file mode 100644 index 1292ba7db..000000000 --- a/include/grub/i386/memory_raw.h +++ /dev/null @@ -1,58 +0,0 @@ -/* memory_raw.h - describe the memory map on qemu/coreboot/multiboot/pc */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2007,2008,2009,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_MEMORY_CPU_RAW_HEADER -#define GRUB_MEMORY_CPU_RAW_HEADER 1 - -/* 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 0x9000 - -/* 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 0xf000 - -/* 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 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 - -#endif diff --git a/include/grub/i386/msr.h b/include/grub/i386/msr.h deleted file mode 100644 index 1e838c022..000000000 --- a/include/grub/i386/msr.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2019 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_I386_MSR_H -#define GRUB_I386_MSR_H 1 - -#include -#include -#include - -static inline grub_err_t -grub_cpu_is_msr_supported (void) -{ - grub_uint32_t eax, ebx, ecx, edx; - - /* - * The CPUID instruction should be used to determine whether MSRs - * are supported, CPUID.01H:EDX[5] = 1. - */ - if (!grub_cpu_is_cpuid_supported ()) - return GRUB_ERR_BAD_DEVICE; - - grub_cpuid (0, eax, ebx, ecx, edx); - - if (eax < 1) - return GRUB_ERR_BAD_DEVICE; - - grub_cpuid (1, eax, ebx, ecx, edx); - - if (!(edx & (1 << 5))) - return GRUB_ERR_BAD_DEVICE; - - return GRUB_ERR_NONE; -} - -/* - * TODO: Add a general protection exception handler. - * Accessing a reserved or unimplemented MSR address results in a GP#. - */ - -static inline grub_uint64_t -grub_rdmsr (grub_uint32_t msr_id) -{ - grub_uint32_t low, high; - - asm volatile ("rdmsr" : "=a" (low), "=d" (high) : "c" (msr_id)); - - return ((grub_uint64_t) high << 32) | low; -} - -static inline void -grub_wrmsr (grub_uint32_t msr_id, grub_uint64_t msr_value) -{ - grub_uint32_t low = msr_value, high = msr_value >> 32; - - asm volatile ("wrmsr" : : "c" (msr_id), "a" (low), "d" (high)); -} - -#endif /* GRUB_I386_MSR_H */ diff --git a/include/grub/i386/multiboot.h b/include/grub/i386/multiboot.h index 0b596fc20..584955449 100644 --- a/include/grub/i386/multiboot.h +++ b/include/grub/i386/multiboot.h @@ -19,40 +19,17 @@ #ifndef GRUB_MULTIBOOT_CPU_HEADER #define GRUB_MULTIBOOT_CPU_HEADER 1 -#define MULTIBOOT2_INITIAL_STATE { .eax = MULTIBOOT2_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_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 MULTIBOOT2_ARCHITECTURE_CURRENT MULTIBOOT2_ARCHITECTURE_I386 +/* The asm part of the multiboot loader. */ +void grub_multiboot_real_boot (grub_addr_t entry, + struct multiboot_info *mbi) + __attribute__ ((noreturn)); +void grub_multiboot2_real_boot (grub_addr_t entry, + struct multiboot_info *mbi) + __attribute__ ((noreturn)); -#ifdef GRUB_MACHINE_EFI -#ifdef __x86_64__ -#define MULTIBOOT_EFI_INITIAL_STATE { .rax = MULTIBOOT_BOOTLOADER_MAGIC, \ - .rcx = 0, \ - .rdx = 0, \ - } -#define MULTIBOOT2_EFI_INITIAL_STATE { .rax = MULTIBOOT2_BOOTLOADER_MAGIC, \ - .rcx = 0, \ - .rdx = 0, \ - } -#define MULTIBOOT_EFI_ENTRY_REGISTER rip -#define MULTIBOOT_EFI_MBI_REGISTER rbx -#endif -#endif - -#define MULTIBOOT_ELF32_MACHINE EM_386 -#define MULTIBOOT_ELF64_MACHINE EM_X86_64 +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; #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 index c33f9bac0..000000000 --- a/include/grub/i386/multiboot/boot.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/i386/multiboot/console.h b/include/grub/i386/multiboot/console.h deleted file mode 100644 index 774399a4e..000000000 --- a/include/grub/i386/multiboot/console.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/i386/multiboot/kernel.h b/include/grub/i386/multiboot/kernel.h deleted file mode 100644 index b41e86ebb..000000000 --- a/include/grub/i386/multiboot/kernel.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/i386/multiboot/memory.h b/include/grub/i386/multiboot/memory.h deleted file mode 100644 index 8dd6f7c8c..000000000 --- a/include/grub/i386/multiboot/memory.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/i386/multiboot/serial.h b/include/grub/i386/multiboot/serial.h deleted file mode 100644 index 2d8563414..000000000 --- a/include/grub/i386/multiboot/serial.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/i386/multiboot/time.h b/include/grub/i386/multiboot/time.h deleted file mode 100644 index 7177c7488..000000000 --- a/include/grub/i386/multiboot/time.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/i386/netbsd_bootinfo.h b/include/grub/i386/netbsd_bootinfo.h index 9b4f46041..776ecf3b0 100644 --- a/include/grub/i386/netbsd_bootinfo.h +++ b/include/grub/i386/netbsd_bootinfo.h @@ -49,108 +49,64 @@ #include + #define NETBSD_BTINFO_BOOTPATH 0 #define NETBSD_BTINFO_ROOTDEVICE 1 #define NETBSD_BTINFO_BOOTDISK 3 -#define NETBSD_BTINFO_CONSOLE 6 -#define NETBSD_BTINFO_SYMTAB 8 #define NETBSD_BTINFO_MEMMAP 9 -#define NETBSD_BTINFO_BOOTWEDGE 10 -#define NETBSD_BTINFO_MODULES 11 -#define NETBSD_BTINFO_FRAMEBUF 12 -#define NETBSD_BTINFO_USERCONFCOMMANDS 13 -#define NETBSD_BTINFO_EFI 14 - -struct grub_netbsd_bootinfo -{ - grub_uint32_t bi_count; - grub_uint32_t bi_data[0]; -}; struct grub_netbsd_btinfo_common { - grub_uint32_t len; + 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; }; -#define GRUB_NETBSD_MAX_BOOTPATH_LEN 80 +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 { - grub_uint32_t labelsector; /* label valid if != 0xffffffff */ + struct grub_netbsd_btinfo_common common; + int labelsector; /* label valid if != -1 */ struct { grub_uint16_t type, checksum; char packname[16]; } label; - grub_uint32_t biosdev; - grub_uint32_t partition; + int biosdev; + int partition; }; -struct grub_netbsd_btinfo_bootwedge { - grub_uint32_t biosdev; - grub_disk_addr_t startblk; - grub_uint64_t nblks; - grub_disk_addr_t matchblk; - grub_uint64_t matchnblks; - grub_uint8_t matchhash[16]; /* MD5 hash */ -} GRUB_PACKED; - -struct grub_netbsd_btinfo_symtab +struct grub_netbsd_bootinfo { - grub_uint32_t nsyms; - grub_uint32_t ssyms; - grub_uint32_t esyms; -}; - - -struct grub_netbsd_btinfo_serial -{ - char devname[16]; - grub_uint32_t addr; - grub_uint32_t speed; -}; - -struct grub_netbsd_btinfo_modules -{ - grub_uint32_t num; - grub_uint32_t last_addr; - struct grub_netbsd_btinfo_module - { - char name[80]; -#define GRUB_NETBSD_MODULE_RAW 0 -#define GRUB_NETBSD_MODULE_ELF 1 - grub_uint32_t type; - grub_uint32_t size; - grub_uint32_t addr; - } mods[0]; -}; - -struct grub_netbsd_btinfo_framebuf -{ - grub_uint64_t fbaddr; - grub_uint32_t flags; - grub_uint32_t width; - grub_uint32_t height; - grub_uint16_t pitch; - grub_uint8_t bpp; - - grub_uint8_t red_mask_size; - grub_uint8_t green_mask_size; - grub_uint8_t blue_mask_size; - - grub_uint8_t red_field_pos; - grub_uint8_t green_field_pos; - grub_uint8_t blue_field_pos; - - grub_uint8_t reserved[16]; -}; - -#define GRUB_NETBSD_MAX_ROOTDEVICE_LEN 16 - -struct grub_netbsd_btinfo_efi -{ - void *pa_systbl; /* Physical address of the EFI System Table */ + grub_uint32_t bi_count; + void *bi_data[1]; }; #endif diff --git a/include/grub/i386/openbsd_bootarg.h b/include/grub/i386/openbsd_bootarg.h index 8c28246d5..ccbe1ca12 100644 --- a/include/grub/i386/openbsd_bootarg.h +++ b/include/grub/i386/openbsd_bootarg.h @@ -17,7 +17,7 @@ */ /* $OpenBSD: bootarg.h,v 1.11 2003/06/02 20:20:54 mickey Exp $ */ - + /* * Copyright (c) 1996-1999 Michael Shalayeff * All rights reserved. @@ -61,33 +61,12 @@ #define OPENBSD_BOOTARG_END -1 #define OPENBSD_BOOTARG_MMAP 0 -#define OPENBSD_BOOTARG_PCIBIOS 4 -#define OPENBSD_BOOTARG_CONSOLE 5 struct grub_openbsd_bootargs { - grub_uint32_t ba_type; - grub_uint32_t ba_size; - grub_uint32_t ba_next; -} GRUB_PACKED; - -struct grub_openbsd_bootarg_console -{ - grub_uint32_t device; - grub_uint32_t speed; - grub_uint32_t addr; - grub_uint32_t frequency; -}; - -struct grub_openbsd_bootarg_pcibios -{ - grub_uint32_t characteristics; - grub_uint32_t revision; - grub_uint32_t pm_entry; - grub_uint32_t last_bus; -}; - -#define GRUB_OPENBSD_COM_MAJOR 8 -#define GRUB_OPENBSD_VGA_MAJOR 12 + int ba_type; + int ba_size; + struct grub_openbsd_bootargs *ba_next; +} __attribute__ ((packed)); #endif diff --git a/include/grub/i386/pc/apm.h b/include/grub/i386/pc/apm.h deleted file mode 100644 index 6d9e8c61d..000000000 --- a/include/grub/i386/pc/apm.h +++ /dev/null @@ -1,48 +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 . - */ - -#ifndef GRUB_APM_MACHINE_HEADER -#define GRUB_APM_MACHINE_HEADER 1 - -#include - -struct grub_apm_info -{ - grub_uint16_t cseg; - grub_uint32_t offset; - grub_uint16_t cseg_16; - grub_uint16_t dseg; - grub_uint16_t flags; - grub_uint16_t cseg_len; - grub_uint16_t cseg_16_len; - grub_uint16_t dseg_len; - grub_uint16_t version; -}; - -enum - { - GRUB_APM_FLAGS_16BITPROTECTED_SUPPORTED = 1, - GRUB_APM_FLAGS_32BITPROTECTED_SUPPORTED = 2, - GRUB_APM_FLAGS_CPUIDLE_SLOWS_DOWN = 4, - GRUB_APM_FLAGS_DISABLED = 8, - GRUB_APM_FLAGS_DISENGAGED = 16, - }; - -int grub_apm_get_info (struct grub_apm_info *info); - -#endif diff --git a/include/grub/i386/pc/biosdisk.h b/include/grub/i386/pc/biosdisk.h index 3d8071684..b87e0e433 100644 --- a/include/grub/i386/pc/biosdisk.h +++ b/include/grub/i386/pc/biosdisk.h @@ -69,7 +69,7 @@ struct grub_biosdisk_drp 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[16]; + grub_uint8_t device_path[8]; grub_uint8_t reserved2; grub_uint8_t checksum; @@ -77,7 +77,7 @@ struct grub_biosdisk_drp writes a garbage to the tail of drive parameters, regardless of a size specified in a caller. */ grub_uint8_t dummy[16]; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_biosdisk_cdrp { @@ -94,7 +94,7 @@ struct grub_biosdisk_cdrp grub_uint8_t sectors; grub_uint8_t heads; grub_uint8_t dummy[16]; -} GRUB_PACKED; +} __attribute__ ((packed)); /* Disk Address Packet. */ struct grub_biosdisk_dap @@ -104,6 +104,23 @@ struct grub_biosdisk_dap grub_uint16_t blocks; grub_uint32_t buffer; grub_uint64_t block; -} GRUB_PACKED; +} __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/boot.h b/include/grub/i386/pc/boot.h index a4d42ff3c..e88c62b71 100644 --- a/include/grub/i386/pc/boot.h +++ b/include/grub/i386/pc/boot.h @@ -19,8 +19,6 @@ #ifndef GRUB_BOOT_MACHINE_HEADER #define GRUB_BOOT_MACHINE_HEADER 1 -#include - /* The signature for bootloader. */ #define GRUB_BOOT_MACHINE_SIGNATURE 0xaa55 @@ -59,6 +57,9 @@ 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) @@ -67,7 +68,16 @@ #define GRUB_BOOT_MACHINE_PXE_DL 0x7f +#ifndef ASM_FILE + /* This is the blocklist used in the diskboot image. */ -#define grub_boot_blocklist grub_pc_bios_boot_blocklist +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 index 4776b181b..ca1da23a7 100644 --- a/include/grub/i386/pc/chainloader.h +++ b/include/grub/i386/pc/chainloader.h @@ -21,7 +21,10 @@ #include -void -grub_chainloader_patch_bpb (void *bs, grub_device_t dev, grub_uint8_t dl); +/* 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 index 191964f10..2a74d152c 100644 --- a/include/grub/i386/pc/console.h +++ b/include/grub/i386/pc/console.h @@ -19,11 +19,33 @@ #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 #include #include +#include + +/* 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); diff --git a/include/grub/backtrace.h b/include/grub/i386/pc/efiemu.h similarity index 80% rename from include/grub/backtrace.h rename to include/grub/i386/pc/efiemu.h index 395519762..f269dd085 100644 --- a/include/grub/backtrace.h +++ b/include/grub/i386/pc/efiemu.h @@ -16,11 +16,9 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_BACKTRACE_HEADER -#define GRUB_BACKTRACE_HEADER 1 +#ifndef GRUB_MACHINE_EFI_EMU_HEADER +#define GRUB_MACHINE_EFI_EMU_HEADER 1 -void grub_backtrace (void); -void grub_backtrace_pointer (void *ptr); -void grub_backtrace_print_address (void *addr); +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 new file mode 100644 index 000000000..2be80e773 --- /dev/null +++ b/include/grub/i386/pc/init.h @@ -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 . + */ + +#ifndef GRUB_INIT_MACHINE_HEADER +#define GRUB_INIT_MACHINE_HEADER 1 + +#include +#include +#include + +/* 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 EXPORT_FUNC(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/int_types.h b/include/grub/i386/pc/int_types.h deleted file mode 100644 index 2c5a69b63..000000000 --- a/include/grub/i386/pc/int_types.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_INTERRUPT_TYPES_MACHINE_HEADER -#define GRUB_INTERRUPT_TYPES_MACHINE_HEADER 1 - -#include - -#define GRUB_CPU_INT_FLAGS_CARRY 0x1 -#define GRUB_CPU_INT_FLAGS_PARITY 0x4 -#define GRUB_CPU_INT_FLAGS_ADJUST 0x10 -#define GRUB_CPU_INT_FLAGS_ZERO 0x40 -#define GRUB_CPU_INT_FLAGS_SIGN 0x80 -#define GRUB_CPU_INT_FLAGS_TRAP 0x100 -#define GRUB_CPU_INT_FLAGS_INTERRUPT 0x200 -#define GRUB_CPU_INT_FLAGS_DIRECTION 0x400 -#define GRUB_CPU_INT_FLAGS_OVERFLOW 0x800 -#ifdef GRUB_MACHINE_PCBIOS -#define GRUB_CPU_INT_FLAGS_DEFAULT GRUB_CPU_INT_FLAGS_INTERRUPT -#else -#define GRUB_CPU_INT_FLAGS_DEFAULT 0 -#endif - -struct grub_bios_int_registers -{ - grub_uint32_t eax; - grub_uint16_t es; - grub_uint16_t ds; - grub_uint16_t flags; - grub_uint16_t dummy; - grub_uint32_t ebx; - grub_uint32_t ecx; - grub_uint32_t edi; - grub_uint32_t esi; - grub_uint32_t edx; -}; - -struct grub_i386_idt -{ - grub_uint16_t limit; - grub_uint32_t base; -} GRUB_PACKED; - -#endif diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index 4f05b74e3..e830afae2 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -19,7 +19,29 @@ #ifndef KERNEL_MACHINE_HEADER #define KERNEL_MACHINE_HEADER 1 -#include +/* 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 @@ -29,12 +51,24 @@ #include #include +/* 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; -extern grub_uint32_t EXPORT_VAR(grub_boot_device); +/* The DOS partition number of the installed partition. */ +extern grub_int32_t grub_install_dos_part; -extern void (*EXPORT_VAR(grub_pc_net_config)) (char **device, char **path); +/* 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 */ diff --git a/include/grub/i386/pc/loader.h b/include/grub/i386/pc/loader.h new file mode 100644 index 000000000..3e031413b --- /dev/null +++ b/include/grub/i386/pc/loader.h @@ -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 . + */ + +#ifndef GRUB_LOADER_MACHINE_HEADER +#define GRUB_LOADER_MACHINE_HEADER 1 + +#include +#include + +/* 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 index d0c5c202e..841b06164 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -28,9 +28,32 @@ #endif #include -#include -#include +/* 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 @@ -41,6 +64,18 @@ /* 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 @@ -54,9 +89,51 @@ struct grub_machine_bios_data_area 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 diff --git a/include/grub/i386/pc/pxe.h b/include/grub/i386/pc/pxe.h index 66002bcd2..39f356c83 100644 --- a/include/grub/i386/pc/pxe.h +++ b/include/grub/i386/pc/pxe.h @@ -152,19 +152,22 @@ #define GRUB_PXE_BOOTP_BCAST 0x8000 #if 1 -#define GRUB_PXE_BOOTP_SIZE (1024 + 236) /* DHCP extended vendor field size. */ +#define GRUB_PXE_BOOTP_DHCPVEND 1024 /* DHCP extended vendor field size. */ #else -#define GRUB_PXE_BOOTP_SIZE (312 + 236) /* DHCP standard vendor field size. */ +#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 -#define GRUB_PXE_SIGNATURE "PXENV+" - struct grub_pxenv { grub_uint8_t signature[6]; /* 'PXENV+'. */ @@ -185,20 +188,7 @@ struct grub_pxenv 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. */ -} GRUB_PACKED; - -struct grub_pxe_bangpxe -{ - grub_uint8_t signature[4]; -#define GRUB_PXE_BANGPXE_SIGNATURE "!PXE" - grub_uint8_t length; - grub_uint8_t chksum; - grub_uint8_t rev; - grub_uint8_t reserved; - grub_uint32_t undiromid; - grub_uint32_t baseromid; - grub_uint32_t rm_entry; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_pxenv_get_cached_info { @@ -207,7 +197,39 @@ struct grub_pxenv_get_cached_info grub_uint16_t buffer_size; grub_uint32_t buffer; grub_uint16_t buffer_limit; -} GRUB_PACKED; +} __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 { @@ -217,12 +239,12 @@ struct grub_pxenv_tftp_open grub_uint8_t filename[128]; grub_uint16_t tftp_port; grub_uint16_t packet_size; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_pxenv_tftp_close { grub_uint16_t status; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_pxenv_tftp_read { @@ -230,7 +252,7 @@ struct grub_pxenv_tftp_read grub_uint16_t packet_number; grub_uint16_t buffer_size; grub_uint32_t buffer; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_pxenv_tftp_get_fsize { @@ -239,18 +261,18 @@ struct grub_pxenv_tftp_get_fsize grub_uint32_t gateway_ip; grub_uint8_t filename[128]; grub_uint32_t file_size; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_pxenv_udp_open { grub_uint16_t status; grub_uint32_t src_ip; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_pxenv_udp_close { grub_uint16_t status; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_pxenv_udp_write { @@ -261,7 +283,7 @@ struct grub_pxenv_udp_write grub_uint16_t dst_port; grub_uint16_t buffer_size; grub_uint32_t buffer; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_pxenv_udp_read { @@ -272,20 +294,20 @@ struct grub_pxenv_udp_read grub_uint16_t dst_port; grub_uint16_t buffer_size; grub_uint32_t buffer; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_pxenv_unload_stack { grub_uint16_t status; grub_uint8_t reserved[10]; -} GRUB_PACKED; +} __attribute__ ((packed)); -int EXPORT_FUNC(grub_pxe_call) (int func, void * data, grub_uint32_t pxe_rm_entry) __attribute__ ((regparm(3))); +struct grub_pxenv * EXPORT_FUNC(grub_pxe_scan) (void); +int EXPORT_FUNC(grub_pxe_call) (int func, void * data); -extern struct grub_pxe_bangpxe *grub_pxe_pxenv; +extern struct grub_pxenv *grub_pxe_pxenv; -void * -grub_pxe_get_cached (grub_uint16_t type); +void grub_pxe_unload (void); #endif diff --git a/include/grub/i386/pc/time.h b/include/grub/i386/pc/time.h index e93320f71..98399b687 100644 --- a/include/grub/i386/pc/time.h +++ b/include/grub/i386/pc/time.h @@ -21,4 +21,9 @@ #include +#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 index 71e7584eb..abf246fa1 100644 --- a/include/grub/i386/pc/vbe.h +++ b/include/grub/i386/pc/vbe.h @@ -19,8 +19,6 @@ #ifndef GRUB_VBE_MACHINE_HEADER #define GRUB_VBE_MACHINE_HEADER 1 -#include - /* Default video mode to be used. */ #define GRUB_VBE_DEFAULT_VIDEO_MODE 0x101 @@ -84,7 +82,7 @@ struct grub_vbe_info_block grub_uint8_t reserved[222]; grub_uint8_t oem_data[256]; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_vbe_mode_info_block { @@ -147,7 +145,7 @@ struct grub_vbe_mode_info_block that doesn't make structure to be 256 bytes. So additional one is added here. */ grub_uint8_t reserved4[189 + 1]; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_vbe_crtc_info_block { @@ -161,7 +159,7 @@ struct grub_vbe_crtc_info_block grub_uint32_t pixel_clock; grub_uint16_t refresh_rate; grub_uint8_t reserved[40]; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_vbe_palette_data { @@ -169,64 +167,64 @@ struct grub_vbe_palette_data grub_uint8_t green; grub_uint8_t red; grub_uint8_t alignment; -} GRUB_PACKED; +} __attribute__ ((packed)); -struct grub_vbe_flat_panel_info -{ - grub_uint16_t horizontal_size; - grub_uint16_t vertical_size; - grub_uint16_t panel_type; - grub_uint8_t red_bpp; - grub_uint8_t green_bpp; - grub_uint8_t blue_bpp; - grub_uint8_t reserved_bpp; - grub_uint32_t reserved_offscreen_mem_size; - grub_vbe_farptr_t reserved_offscreen_mem_ptr; +/* Prototypes for kernel real mode thunks. */ - grub_uint8_t reserved[14]; -} GRUB_PACKED; - -/* Prototypes for helper functions. */ /* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status. */ -grub_vbe_status_t -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 -grub_vbe_bios_get_mode_info (grub_uint32_t mode, - struct grub_vbe_mode_info_block *mode_info); -/* Call VESA BIOS 0x4f03 to return current VBE Mode, return status. */ -grub_vbe_status_t -grub_vbe_bios_get_mode (grub_uint32_t *mode); -/* Call VESA BIOS 0x4f05 to set memory window, return status. */ -grub_vbe_status_t -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 -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 -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 -grub_vbe_bios_get_scanline_length (grub_uint32_t *length); -/* Call VESA BIOS 0x4f07 to get display start, return status. */ -grub_vbe_status_t -grub_vbe_bios_get_display_start (grub_uint32_t *x, - grub_uint32_t *y); +grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_controller_info) (struct grub_vbe_info_block *controller_info); -grub_vbe_status_t grub_vbe_bios_getset_dac_palette_width (int set, int *width); +/* 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); -grub_vbe_status_t -grub_vbe_bios_get_pm_interface (grub_uint16_t *seg, grub_uint16_t *offset, - grub_uint16_t *length); #endif /* ! GRUB_VBE_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/vesa_modes_table.h b/include/grub/i386/pc/vesa_modes_table.h deleted file mode 100644 index 376ca376b..000000000 --- a/include/grub/i386/pc/vesa_modes_table.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef GRUB_VESA_MODE_TABLE_HEADER -#define GRUB_VESA_MODE_TABLE_HEADER 1 - -#include - -#define GRUB_VESA_MODE_TABLE_START 0x300 -#define GRUB_VESA_MODE_TABLE_END 0x373 - -struct grub_vesa_mode_table_entry { - grub_uint16_t width; - grub_uint16_t height; - grub_uint8_t depth; -}; - -extern struct grub_vesa_mode_table_entry -grub_vesa_mode_table[GRUB_VESA_MODE_TABLE_END - - GRUB_VESA_MODE_TABLE_START + 1]; - -#endif diff --git a/include/grub/uboot/disk.h b/include/grub/i386/pc/vga.h similarity index 56% rename from include/grub/uboot/disk.h rename to include/grub/i386/pc/vga.h index e380b4c89..b9822395b 100644 --- a/include/grub/uboot/disk.h +++ b/include/grub/i386/pc/vga.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. + * 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 @@ -16,28 +16,19 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_UBOOT_DISK_HEADER -#define GRUB_UBOOT_DISK_HEADER 1 +#ifndef GRUB_VGA_MACHINE_HEADER +#define GRUB_VGA_MACHINE_HEADER 1 #include -#include -#include +#include -void grub_ubootdisk_init (void); -void grub_ubootdisk_fini (void); +/* The VGA (at the beginning of upper memory). */ +#define GRUB_MEMORY_MACHINE_VGA_ADDR GRUB_MEMORY_MACHINE_UPPER -enum disktype -{ cd, fd, hd }; +/* Set the video mode to MODE and return the previous mode. */ +unsigned char EXPORT_FUNC(grub_vga_set_mode) (unsigned char mode); -struct ubootdisk_data -{ - void *cookie; - struct device_info *dev; - int opencount; - enum disktype type; - grub_uint32_t block_size; -}; +/* Return a pointer to the ROM font table. */ +unsigned char *EXPORT_FUNC(grub_vga_get_font) (void); -grub_err_t grub_ubootdisk_register (struct device_info *newdev); - -#endif /* ! GRUB_UBOOT_DISK_HEADER */ +#endif /* ! GRUB_VGA_MACHINE_HEADER */ diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h index dffeb5695..bab42adb6 100644 --- a/include/grub/i386/pci.h +++ b/include/grub/i386/pci.h @@ -70,8 +70,6 @@ grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) grub_outb (data, GRUB_PCI_DATA_REG + (addr & 3)); } -#ifndef GRUB_MACHINE_IEEE1275 - static inline volatile void * grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), grub_addr_t base, @@ -82,24 +80,10 @@ grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), static inline void grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), - volatile void *mem __attribute__ ((unused)), + void *mem __attribute__ ((unused)), grub_size_t size __attribute__ ((unused))) { } -#else - -volatile 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, - volatile void *mem, - grub_size_t size); - -#endif - #endif /* GRUB_CPU_PCI_H */ diff --git a/include/grub/i386/pit.h b/include/grub/i386/pit.h index 4bd49d4ca..ff9b9a6d7 100644 --- a/include/grub/i386/pit.h +++ b/include/grub/i386/pit.h @@ -22,82 +22,6 @@ #include #include -enum - { - /* The PIT channel value ports. You can write to and read from them. - Do not mess with timer 0 or 1. */ - GRUB_PIT_COUNTER_0 = 0x40, - GRUB_PIT_COUNTER_1 = 0x41, - GRUB_PIT_COUNTER_2 = 0x42, - /* The PIT control port. You can only write to it. Do not mess with - timer 0 or 1. */ - GRUB_PIT_CTRL = 0x43, - /* The speaker port. */ - GRUB_PIT_SPEAKER_PORT = 0x61, - }; - - -/* The speaker port. */ -enum - { - /* If 0, follow state of SPEAKER_DATA bit, otherwise enable output - from timer 2. */ - GRUB_PIT_SPK_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. */ - GRUB_PIT_SPK_DATA = 0x02, - - GRUB_PIT_SPK_TMR2_LATCH = 0x20 - }; - -/* The PIT control port. You can only write to it. Do not mess with - timer 0 or 1. */ -enum - { - GRUB_PIT_CTRL_SELECT_MASK = 0xc0, - GRUB_PIT_CTRL_SELECT_0 = 0x00, - GRUB_PIT_CTRL_SELECT_1 = 0x40, - GRUB_PIT_CTRL_SELECT_2 = 0x80, - - /* Read and load control. */ - GRUB_PIT_CTRL_READLOAD_MASK= 0x30, - GRUB_PIT_CTRL_COUNTER_LATCH = 0x00, /* Hold timer value until read. */ - GRUB_PIT_CTRL_READLOAD_LSB = 0x10, /* Read/load the LSB. */ - GRUB_PIT_CTRL_READLOAD_MSB = 0x20, /* Read/load the MSB. */ - GRUB_PIT_CTRL_READLOAD_WORD = 0x30, /* Read/load the LSB then the MSB. */ - - /* Mode control. */ - GRUB_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. */ - GRUB_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. */ - GRUB_PIT_CTRL_PROGR_ONE_SHOT = 0x02, - - /* Rate generator. Output is low for one period of the counter, and - high for the other. */ - GRUB_PIT_CTRL_RATE_GEN = 0x04, - - /* Square wave generator. Output is low for one half of the period, - and high for the other half. */ - GRUB_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. */ - GRUB_PIT_CTRL_SOFTSTROBE = 0x08, - - /* Hardware triggered strobe. Like software triggered strobe, but - only starts the counter when the gate pin is set to high. */ - GRUB_PIT_CTRL_HARDSTROBE = 0x0a, - - - /* Count mode. */ - GRUB_PIT_CTRL_COUNT_MASK = 0x01, - GRUB_PIT_CTRL_COUNT_BINARY = 0x00, /* 16-bit binary counter. */ - GRUB_PIT_CTRL_COUNT_BCD = 0x01 /* 4-decade BCD counter. */ - }; +void EXPORT_FUNC(grub_pit_wait) (grub_uint16_t tics); #endif /* ! KERNEL_CPU_PIT_HEADER */ diff --git a/include/grub/i386/pmtimer.h b/include/grub/i386/pmtimer.h deleted file mode 100644 index ac091806a..000000000 --- a/include/grub/i386/pmtimer.h +++ /dev/null @@ -1,37 +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 . - */ - -#ifndef KERNEL_CPU_PMTIMER_HEADER -#define KERNEL_CPU_PMTIMER_HEADER 1 - -#include -#include - -/* - Preconditions: - * Caller has ensured that both pmtimer and tsc are supported - * 1 <= num_pm_ticks <= 3580 - Return: - * Number of TSC ticks elapsed - * 0 on failure. -*/ -grub_uint64_t -EXPORT_FUNC(grub_pmtimer_wait_count_tsc) (grub_port_t pmtimer, - grub_uint16_t num_pm_ticks); - -#endif diff --git a/include/grub/i386/qemu/boot.h b/include/grub/i386/qemu/boot.h index 5f53eabfb..6fbb57750 100644 --- a/include/grub/i386/qemu/boot.h +++ b/include/grub/i386/qemu/boot.h @@ -22,4 +22,7 @@ /* 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/init.h b/include/grub/i386/qemu/init.h new file mode 100644 index 000000000..fd935c3a2 --- /dev/null +++ b/include/grub/i386/qemu/init.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h index f34206b3a..bc0b93d4f 100644 --- a/include/grub/i386/qemu/kernel.h +++ b/include/grub/i386/qemu/kernel.h @@ -19,7 +19,17 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 -#include +/* 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 @@ -28,7 +38,15 @@ extern grub_addr_t grub_core_entry_addr; -void grub_qemu_init_cirrus (void); +/* 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 */ diff --git a/include/grub/i386/qemu/loader.h b/include/grub/i386/qemu/loader.h new file mode 100644 index 000000000..d3f36bba5 --- /dev/null +++ b/include/grub/i386/qemu/loader.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/qemu/memory.h b/include/grub/i386/qemu/memory.h index 8dd6f7c8c..de559443d 100644 --- a/include/grub/i386/qemu/memory.h +++ b/include/grub/i386/qemu/memory.h @@ -1 +1,45 @@ -#include +/* 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 . + */ + +#ifndef _GRUB_MEMORY_MACHINE_HEADER +#define _GRUB_MEMORY_MACHINE_HEADER 1 + +#include +#include + +#ifndef ASM_FILE +#include +#include +#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/relocator.h b/include/grub/i386/relocator.h index 2a56c3b54..ef7fe23aa 100644 --- a/include/grub/i386/relocator.h +++ b/include/grub/i386/relocator.h @@ -21,80 +21,21 @@ #include #include -#include struct grub_relocator32_state { grub_uint32_t esp; - grub_uint32_t ebp; grub_uint32_t eax; grub_uint32_t ebx; grub_uint32_t ecx; grub_uint32_t edx; grub_uint32_t eip; - grub_uint32_t esi; - grub_uint32_t edi; }; -struct grub_relocator16_state -{ - grub_uint16_t cs; - grub_uint16_t ds; - grub_uint16_t es; - grub_uint16_t fs; - grub_uint16_t gs; - grub_uint16_t ss; - grub_uint16_t sp; - grub_uint16_t ip; - grub_uint32_t ebx; - grub_uint32_t edx; - grub_uint32_t esi; - grub_uint32_t ebp; - int a20; -}; - -struct grub_relocator64_state -{ - grub_uint64_t rsp; - grub_uint64_t rax; - grub_uint64_t rbx; - grub_uint64_t rcx; - grub_uint64_t rdx; - grub_uint64_t rip; - grub_uint64_t rsi; - grub_addr_t cr3; -}; - -#ifdef GRUB_MACHINE_EFI -#ifdef __x86_64__ -struct grub_relocator64_efi_state -{ - grub_uint64_t rax; - grub_uint64_t rbx; - grub_uint64_t rcx; - grub_uint64_t rdx; - grub_uint64_t rip; - grub_uint64_t rsi; -}; -#endif -#endif - -grub_err_t grub_relocator16_boot (struct grub_relocator *rel, - struct grub_relocator16_state state); - -grub_err_t grub_relocator32_boot (struct grub_relocator *rel, - struct grub_relocator32_state state, - int avoid_efi_bootservices); - -grub_err_t grub_relocator64_boot (struct grub_relocator *rel, - struct grub_relocator64_state state, - grub_addr_t min_addr, grub_addr_t max_addr); - -#ifdef GRUB_MACHINE_EFI -#ifdef __x86_64__ -grub_err_t grub_relocator64_efi_boot (struct grub_relocator *rel, - struct grub_relocator64_efi_state state); -#endif -#endif +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/relocator_private.h b/include/grub/i386/relocator_private.h deleted file mode 100644 index b7c96a664..000000000 --- a/include/grub/i386/relocator_private.h +++ /dev/null @@ -1 +0,0 @@ -#define GRUB_RELOCATOR16_STACK_SIZE 4096 diff --git a/include/grub/i386/setjmp.h b/include/grub/i386/setjmp.h index bf959a665..6b6b6fd15 100644 --- a/include/grub/i386/setjmp.h +++ b/include/grub/i386/setjmp.h @@ -21,8 +21,12 @@ typedef unsigned long grub_jmp_buf[6]; -int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE __attribute__ ((cdecl, +#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))); diff --git a/include/grub/i386/time.h b/include/grub/i386/time.h index 4da5ae93c..842882cf2 100644 --- a/include/grub/i386/time.h +++ b/include/grub/i386/time.h @@ -23,7 +23,7 @@ static __inline void grub_cpu_idle (void) { /* FIXME: this can't work until we handle interrupts. */ -/* asm volatile ("hlt"); */ +/* __asm__ __volatile__ ("hlt"); */ } #endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/i386/tsc.h b/include/grub/i386/tsc.h index 3c96d3e0b..dad9d062d 100644 --- a/include/grub/i386/tsc.h +++ b/include/grub/i386/tsc.h @@ -20,56 +20,122 @@ #define KERNEL_CPU_TSC_HEADER 1 #include -#include - -void grub_tsc_init (void); -/* In ms per 2^32 ticks. */ -extern grub_uint32_t EXPORT_VAR(grub_tsc_rate); -int -grub_tsc_calibrate_from_xen (void); -int -grub_tsc_calibrate_from_efi (void); -int -grub_tsc_calibrate_from_pmtimer (void); -int -grub_tsc_calibrate_from_pit (void); /* 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; - grub_uint32_t a,b,c,d; /* The CPUID instruction is a 'serializing' instruction, and avoids out-of-order execution of the RDTSC instruction. */ - grub_cpuid (0,a,b,c,d); +#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)); - /* - * Run cpuid after rdtsc instruction to ensure rdtsc is executed before - * subsequent instruction. - */ - grub_cpuid (0, a, b, c, d); + __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 !defined(GRUB_MACHINE_XEN) && !defined(GRUB_MACHINE_XEN_PVH) - grub_uint32_t a,b,c,d; if (! grub_cpu_is_cpuid_supported ()) return 0; - grub_cpuid(1,a,b,c,d); - - return (d & (1 << 4)) != 0; + grub_uint32_t features; +#ifdef APPLE_CC + __asm__ ("movl $1, %%eax\n\t" +#ifdef __x86_64__ + "push %%rbx\n" #else - return 1; + "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 index c20063f31..0ac64734c 100644 --- a/include/grub/i386/types.h +++ b/include/grub/i386/types.h @@ -28,6 +28,4 @@ /* i386 is little-endian. */ #undef GRUB_TARGET_WORDS_BIGENDIAN -#define GRUB_HAVE_UNALIGNED_ACCESS 1 - #endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/i386/vga_common.h b/include/grub/i386/vga_common.h new file mode 100644 index 000000000..f17fc018a --- /dev/null +++ b/include/grub/i386/vga_common.h @@ -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 . + */ + +#ifndef GRUB_VGA_COMMON_CPU_HEADER +#define GRUB_VGA_COMMON_CPU_HEADER 1 + +#include +#include +#include + +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/xen/hypercall.h b/include/grub/i386/xen/hypercall.h deleted file mode 100644 index 4e4c12a49..000000000 --- a/include/grub/i386/xen/hypercall.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_XEN_CPU_HYPERCALL_HEADER -#define GRUB_XEN_CPU_HYPERCALL_HEADER 1 - -#include - -int -EXPORT_FUNC (grub_xen_hypercall) (grub_uint32_t callno, grub_uint32_t a0, - grub_uint32_t a1, grub_uint32_t a2, - grub_uint32_t a3, grub_uint32_t a4, - grub_uint32_t a5) -#ifdef GRUB_MACHINE_XEN - __attribute__ ((regparm (3), cdecl)) -#endif - ; - -static inline int -grub_xen_sched_op (int cmd, void *arg) -{ - return grub_xen_hypercall (__HYPERVISOR_sched_op, cmd, (grub_uint32_t) arg, - 0, 0, 0, 0); -} - -static inline int -grub_xen_mmu_update (const struct mmu_update *reqs, - unsigned count, unsigned *done_out, unsigned foreigndom) -{ - return grub_xen_hypercall (__HYPERVISOR_mmu_update, (grub_uint32_t) reqs, - (grub_uint32_t) count, (grub_uint32_t) done_out, - (grub_uint32_t) foreigndom, 0, 0); -} - -static inline int -grub_xen_mmuext_op (mmuext_op_t * ops, - unsigned int count, - unsigned int *pdone, unsigned int foreigndom) -{ - return grub_xen_hypercall (__HYPERVISOR_mmuext_op, (grub_uint32_t) ops, - count, (grub_uint32_t) pdone, foreigndom, 0, 0); -} - -static inline int -grub_xen_event_channel_op (int op, void *arg) -{ - return grub_xen_hypercall (__HYPERVISOR_event_channel_op, op, - (grub_uint32_t) arg, 0, 0, 0, 0); -} - - -static inline int -grub_xen_update_va_mapping (void *addr, uint64_t pte, uint32_t flags) -{ - return grub_xen_hypercall (__HYPERVISOR_update_va_mapping, - (grub_uint32_t) addr, pte, pte >> 32, flags, 0, - 0); -} - -static inline int -grub_xen_grant_table_op (int a, void *b, int c) -{ - return grub_xen_hypercall (__HYPERVISOR_grant_table_op, a, - (grub_uint32_t) b, c, 0, 0, 0); -} - -static inline int -grub_xen_vm_assist (int cmd, int type) -{ - return grub_xen_hypercall (__HYPERVISOR_vm_assist, cmd, type, 0, 0, 0, 0); -} - -#endif diff --git a/include/grub/i386/xen/memory.h b/include/grub/i386/xen/memory.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/include/grub/i386/xen_pvh/boot.h b/include/grub/i386/xen_pvh/boot.h deleted file mode 100644 index 6cd23aa83..000000000 --- a/include/grub/i386/xen_pvh/boot.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/i386/xen_pvh/console.h b/include/grub/i386/xen_pvh/console.h deleted file mode 100644 index 305a46d8e..000000000 --- a/include/grub/i386/xen_pvh/console.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/i386/xen_pvh/int.h b/include/grub/i386/xen_pvh/int.h deleted file mode 100644 index 0f1f9ee62..000000000 --- a/include/grub/i386/xen_pvh/int.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/i386/xen_pvh/kernel.h b/include/grub/i386/xen_pvh/kernel.h deleted file mode 100644 index 2b7b8a129..000000000 --- a/include/grub/i386/xen_pvh/kernel.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_KERNEL_MACHINE_HEADER -#define GRUB_KERNEL_MACHINE_HEADER 1 - -#ifndef ASM_FILE - -#define GRUB_KERNEL_USE_RSDP_ADDR 1 - -extern grub_uint64_t EXPORT_VAR(grub_rsdp_addr); - -#endif /* ! ASM_FILE */ - -#endif /* GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/i386/xen_pvh/memory.h b/include/grub/i386/xen_pvh/memory.h deleted file mode 100644 index 8dd6f7c8c..000000000 --- a/include/grub/i386/xen_pvh/memory.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/i386/xen_pvh/time.h b/include/grub/i386/xen_pvh/time.h deleted file mode 100644 index 2298ee8f4..000000000 --- a/include/grub/i386/xen_pvh/time.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/i386/xnu.h b/include/grub/i386/xnu.h index 062a7ddbe..3be2c3bcc 100644 --- a/include/grub/i386/xnu.h +++ b/include/grub/i386/xnu.h @@ -28,8 +28,10 @@ #define GRUB_XNU_PAGESIZE 4096 typedef grub_uint32_t grub_xnu_ptr_t; -struct grub_xnu_boot_params_common +struct grub_xnu_boot_params { + grub_uint16_t verminor; + grub_uint16_t vermajor; /* Command line passed to xnu. */ grub_uint8_t cmdline[1024]; @@ -57,51 +59,17 @@ struct grub_xnu_boot_params_common 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_PACKED; - -struct grub_xnu_boot_params_v1 -{ - grub_uint16_t verminor; - grub_uint16_t vermajor; - struct grub_xnu_boot_params_common common; - grub_uint32_t efi_system_table; /* Size of grub_efi_uintn_t in bits. */ grub_uint8_t efi_uintnbits; -} GRUB_PACKED; -#define GRUB_XNU_BOOTARGSV1_VERMINOR 5 -#define GRUB_XNU_BOOTARGSV1_VERMAJOR 1 - -struct grub_xnu_boot_params_v2 -{ - grub_uint16_t verminor; - grub_uint16_t vermajor; - - /* Size of grub_efi_uintn_t in bits. */ - grub_uint8_t efi_uintnbits; - grub_uint8_t unused[3]; - - struct grub_xnu_boot_params_common common; - - grub_uint64_t efi_runtime_first_page_virtual; - grub_uint32_t efi_system_table; - grub_uint32_t unused2[9]; - grub_uint64_t ram_size; - grub_uint64_t fsbfreq; - grub_uint32_t unused3[734]; -} GRUB_PACKED; -#define GRUB_XNU_BOOTARGSV2_VERMINOR 0 -#define GRUB_XNU_BOOTARGSV2_VERMAJOR 2 - -union grub_xnu_boot_params_any -{ - struct grub_xnu_boot_params_v1 v1; - struct grub_xnu_boot_params_v2 v2; -}; +} __attribute__ ((packed)); +#define GRUB_XNU_BOOTARGS_VERMINOR 5 +#define GRUB_XNU_BOOTARGS_VERMAJOR 1 struct grub_xnu_devprop_header { @@ -146,4 +114,8 @@ 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/ia64/efi/memory.h b/include/grub/ia64/efi/memory.h deleted file mode 100644 index 2c64918e3..000000000 --- a/include/grub/ia64/efi/memory.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef GRUB_MEMORY_CPU_HEADER -#include - -#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff - -#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/ia64/reloc.h b/include/grub/ia64/reloc.h deleted file mode 100644 index 45c8fba27..000000000 --- a/include/grub/ia64/reloc.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_IA64_RELOC_H -#define GRUB_IA64_RELOC_H 1 - -struct grub_ia64_trampoline; - -void -grub_ia64_add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value); -void -grub_ia64_add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value); -void -grub_ia64_set_immu64 (grub_addr_t addr, grub_uint64_t value); -void -grub_ia64_make_trampoline (struct grub_ia64_trampoline *tr, grub_uint64_t addr); - -struct grub_ia64_trampoline -{ - /* nop.m */ - grub_uint8_t nop[5]; - /* movl r15 = addr*/ - grub_uint8_t addr_hi[6]; - grub_uint8_t e0; - grub_uint8_t addr_lo[4]; - grub_uint8_t jump[0x20]; -}; - -#endif diff --git a/include/grub/ia64/setjmp.h b/include/grub/ia64/setjmp.h deleted file mode 100644 index 0a6211379..000000000 --- a/include/grub/ia64/setjmp.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Define the machine-dependent type `jmp_buf'. Linux/IA-64 version. - Copyright (C) 1999, 2000, 2008 Free Software Foundation, Inc. - Contributed by David Mosberger-Tang . - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* User code must not depend on the internal representation of jmp_buf. */ - -#define _JBLEN 70 - -/* the __jmp_buf element type should be __float80 per ABI... */ -typedef long grub_jmp_buf[_JBLEN] __attribute__ ((aligned (16))); /* guarantees 128-bit alignment! */ - -int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; -void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); diff --git a/include/grub/ia64/time.h b/include/grub/ia64/time.h deleted file mode 100644 index 03ee79fa4..000000000 --- a/include/grub/ia64/time.h +++ /dev/null @@ -1,28 +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 . - */ - -#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/ia64/types.h b/include/grub/ia64/types.h deleted file mode 100644 index 91a546dd2..000000000 --- a/include/grub/ia64/types.h +++ /dev/null @@ -1,32 +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 . - */ - -#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 - -/* ia64 is little-endian (usually). */ -#undef GRUB_TARGET_WORDS_BIGENDIAN - - -#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/ieee1275/alloc.h b/include/grub/ieee1275/alloc.h deleted file mode 100644 index 67a785657..000000000 --- a/include/grub/ieee1275/alloc.h +++ /dev/null @@ -1,39 +0,0 @@ -/* alloc.h - Memory allocation for PowerVM, KVM on Power, and i386 */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 Free Software Foundation, Inc. - * Copyright (C) 2023 IBM Corporation - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_IEEE1275_ALLOC_HEADER -#define GRUB_IEEE1275_ALLOC_HEADER 1 - -#include - -#include - -struct regions_claim_request { - unsigned int flags; /* GRUB_MM_ADD_REGION_(NONE|CONSECUTIVE) */ - grub_uint32_t total; /* number of requested bytes */ - bool init_region; /* whether to add memory to the heap using grub_mm_init_region() */ - grub_uint64_t addr; /* result address */ - grub_size_t align; /* alignment restrictions */ -}; - -int EXPORT_FUNC(grub_regions_claim) (grub_uint64_t addr, grub_uint64_t len, - grub_memory_type_t type, void *data); - -#endif /* GRUB_IEEE1275_ALLOC_HEADER */ diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index c445d0499..62e8f3812 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -24,8 +24,13 @@ #include #include -#define GRUB_IEEE1275_CELL_FALSE ((grub_ieee1275_cell_t) 0) -#define GRUB_IEEE1275_CELL_TRUE ((grub_ieee1275_cell_t) -1) +/* Maps a device alias to a pathname. */ +struct grub_ieee1275_devalias +{ + char *name; + char *path; + char *type; +}; struct grub_ieee1275_mem_region { @@ -60,34 +65,9 @@ struct grub_ieee1275_common_hdr typedef grub_uint32_t grub_ieee1275_ihandle_t; typedef grub_uint32_t grub_ieee1275_phandle_t; -#define GRUB_IEEE1275_IHANDLE_INVALID ((grub_ieee1275_ihandle_t) 0) -#define GRUB_IEEE1275_PHANDLE_INVALID ((grub_ieee1275_phandle_t) -1) - -struct grub_ieee1275_devalias -{ - char *name; - char *path; - char *type; - char *parent_path; - grub_ieee1275_phandle_t phandle; - grub_ieee1275_phandle_t parent_dev; -}; - -extern void (*EXPORT_VAR(grub_ieee1275_net_config)) (const char *dev, - char **device, - char **path, - char *bootargs); - -/* Maps a device alias to a pathname. */ extern grub_ieee1275_phandle_t EXPORT_VAR(grub_ieee1275_chosen); extern grub_ieee1275_ihandle_t EXPORT_VAR(grub_ieee1275_mmu); -#ifdef __i386__ -#define GRUB_IEEE1275_ENTRY_FN_ATTRIBUTE __attribute__ ((regparm(3))) -#else -#define GRUB_IEEE1275_ENTRY_FN_ATTRIBUTE -#endif - -extern int (* EXPORT_VAR(grub_ieee1275_entry_fn)) (void *) GRUB_IEEE1275_ENTRY_FN_ATTRIBUTE; +extern int (* EXPORT_VAR(grub_ieee1275_entry_fn)) (void *); enum grub_ieee1275_flag { @@ -109,43 +89,17 @@ enum grub_ieee1275_flag /* OLPC / XO firmware hangs when accessing USB devices. */ GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY, - /* OpenFirmware hangs on qemu if one requests any memory below 1.5 MiB. */ - GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM, + /* Open Hack'Ware stops when trying to set colors */ + GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS, - /* OLPC / XO firmware has the cursor ON/OFF routines. */ - GRUB_IEEE1275_FLAG_HAS_CURSORONOFF, + /* Open Hack'Ware stops when grub_ieee1275_interpret is used. */ + GRUB_IEEE1275_FLAG_CANNOT_INTERPRET, - /* Some PowerMacs claim to use 2 address cells but in fact use only 1. - Other PowerMacs claim to use only 1 and really do so. Always assume - 1 address cell is used on PowerMacs. - */ - GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS, + /* Open Hack'Ware has no memory map, just claim what we need. */ + GRUB_IEEE1275_FLAG_FORCE_CLAIM, - GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS, - - GRUB_IEEE1275_FLAG_NO_OFNET_SUFFIX, - - GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN, - - GRUB_IEEE1275_FLAG_BROKEN_REPEAT, - - GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN, - - GRUB_IEEE1275_FLAG_RAW_DEVNAMES, - -#if defined(__powerpc__) - /* - * On PFW, the first time we boot a Linux partition, we may only get 256MB of - * real memory area, even if the partition has more memory. Set this flag if - * we think we're running under PFW. Then, if this flag is set, and the RMA is - * only 256MB in size, try asking for more with CAS. - */ - GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY, -#endif - - GRUB_IEEE1275_FLAG_POWER_VM, - - GRUB_IEEE1275_FLAG_POWER_KVM, + /* 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); @@ -155,7 +109,7 @@ extern void EXPORT_FUNC(grub_ieee1275_set_flag) (enum grub_ieee1275_flag flag); void EXPORT_FUNC(grub_ieee1275_init) (void); -int EXPORT_FUNC(grub_ieee1275_finddevice) (const char *name, +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, @@ -178,7 +132,7 @@ 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, - const void *buffer, grub_size_t len, + 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, @@ -203,34 +157,21 @@ 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, - const void *buf, + 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_ieee1275_set_address) (grub_ieee1275_ihandle_t ihandle, - grub_uint32_t target, - grub_uint32_t lun); -int EXPORT_FUNC(grub_ieee1275_no_data_command) (grub_ieee1275_ihandle_t ihandle, - const void *cmd_addr, - grub_ssize_t *result); -int EXPORT_FUNC(grub_ieee1275_decode_unit4) (grub_ieee1275_ihandle_t ihandle, - void *addr, grub_size_t size, - grub_uint32_t *phy_lo, - grub_uint32_t *phy_hi, - grub_uint32_t *lun_lo, - grub_uint32_t *lun_hi); -char *EXPORT_FUNC(grub_ieee1275_encode_uint4) (grub_ieee1275_ihandle_t ihandle, - grub_uint32_t phy_lo, - grub_uint32_t phy_hi, - grub_uint32_t lun_lo, - grub_uint32_t lun_hi, - grub_size_t *size); -int EXPORT_FUNC(grub_ieee1275_get_block_size) (grub_ieee1275_ihandle_t ihandle); -grub_err_t EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size); + +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, @@ -238,27 +179,5 @@ EXPORT_FUNC(grub_ieee1275_map) (grub_addr_t phys, grub_addr_t virt, 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)); -char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path); -char *EXPORT_FUNC(grub_ieee1275_canonicalise_devname) (const char *path); -char *EXPORT_FUNC(grub_ieee1275_get_device_type) (const char *path); -char *EXPORT_FUNC(grub_ieee1275_get_devname) (const char *path); - -void EXPORT_FUNC(grub_ieee1275_devalias_init_iterator) (struct grub_ieee1275_devalias *alias); -void EXPORT_FUNC(grub_ieee1275_devalias_free) (struct grub_ieee1275_devalias *alias); -int EXPORT_FUNC(grub_ieee1275_devalias_next) (struct grub_ieee1275_devalias *alias); -void EXPORT_FUNC(grub_ieee1275_children_peer) (struct grub_ieee1275_devalias *alias); -void EXPORT_FUNC(grub_ieee1275_children_first) (const char *devpath, - struct grub_ieee1275_devalias *alias); - -char *EXPORT_FUNC(grub_ieee1275_get_boot_dev) (void); - -#define FOR_IEEE1275_DEVALIASES(alias) for (grub_ieee1275_devalias_init_iterator (&(alias)); grub_ieee1275_devalias_next (&(alias));) - -#define FOR_IEEE1275_DEVCHILDREN(devpath, alias) for (grub_ieee1275_children_first ((devpath), &(alias)); \ - (alias).name; \ - grub_ieee1275_children_peer (&(alias))) #endif /* ! GRUB_IEEE1275_HEADER */ diff --git a/include/grub/ieee1275/obdisk.h b/include/grub/ieee1275/obdisk.h deleted file mode 100644 index 5da51f812..000000000 --- a/include/grub/ieee1275/obdisk.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2019 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_OBDISK_HEADER -#define GRUB_OBDISK_HEADER 1 - -extern void grub_obdisk_init (void); -extern void grub_obdisk_fini (void); - -#endif diff --git a/include/grub/ieee1275/tpm.h b/include/grub/ieee1275/tpm.h deleted file mode 100644 index fe5cb4713..000000000 --- a/include/grub/ieee1275/tpm.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_IEEE1275_TPM_HEADER -#define GRUB_IEEE1275_TPM_HEADER 1 - -#include -#include -#include - -extern grub_ieee1275_ihandle_t grub_ieee1275_tpm_ihandle; - -extern grub_err_t grub_ieee1275_tpm_init (void); - -#endif diff --git a/include/grub/kernel.h b/include/grub/kernel.h index 6121c1e66..9586a90b9 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -27,18 +27,14 @@ enum OBJ_TYPE_ELF, OBJ_TYPE_MEMDISK, OBJ_TYPE_CONFIG, - OBJ_TYPE_PREFIX, - OBJ_TYPE_PUBKEY, - OBJ_TYPE_DTB, - OBJ_TYPE_DISABLE_SHIM_LOCK, - OBJ_TYPE_DISABLE_CLI + OBJ_TYPE_FONT }; /* The module header. */ struct grub_module_header { /* The type of object. */ - grub_uint32_t type; + grub_uint8_t type; /* The size of object (including this header). */ grub_uint32_t size; }; @@ -46,88 +42,36 @@ struct grub_module_header /* "gmim" (GRUB Module Info Magic). */ #define GRUB_MODULE_MAGIC 0x676d696d -struct grub_module_info32 +struct grub_module_info { /* Magic number so we know we have modules present. */ grub_uint32_t magic; - /* The offset of the modules. */ - grub_uint32_t offset; - /* The size of all modules plus this header. */ - grub_uint32_t size; -}; - -struct grub_module_info64 -{ - /* Magic number so we know we have modules present. */ - grub_uint32_t magic; - grub_uint32_t padding; - /* The offset of the modules. */ - grub_uint64_t offset; - /* The size of all modules plus this header. */ - grub_uint64_t size; -}; - -#ifndef GRUB_UTIL -/* Space isn't reusable on some platforms. */ -/* On Qemu the preload space is readonly. */ -/* On emu there is no preload space. */ -/* On ieee1275 our code assumes that heap is p=v which isn't guaranteed for module space. */ -#if defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_EMU) \ - || defined (GRUB_MACHINE_EFI) \ - || (defined (GRUB_MACHINE_IEEE1275) && !defined (__sparc__)) -#define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 0 -#endif - -#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) \ - || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) \ - || defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_ARC) \ - || (defined (__sparc__) && defined (GRUB_MACHINE_IEEE1275)) \ - || defined (GRUB_MACHINE_UBOOT) || defined (GRUB_MACHINE_XEN) \ - || defined(GRUB_MACHINE_XEN_PVH) -/* FIXME: stack is between 2 heap regions. Move it. */ -#define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 1 -#endif - -#ifndef GRUB_KERNEL_PRELOAD_SPACE_REUSABLE -#error "Please check if preload space is reusable on this platform!" -#endif - #if GRUB_TARGET_SIZEOF_VOID_P == 8 -#define grub_module_info grub_module_info64 -#else -#define grub_module_info grub_module_info32 + 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 EXPORT_VAR (grub_modbase); +extern grub_addr_t grub_arch_modules_addr (void); -#define FOR_MODULES(var) for (\ - var = (grub_modbase && ((((struct grub_module_info *) grub_modbase)->magic) == GRUB_MODULE_MAGIC)) ? (struct grub_module_header *) \ - (grub_modbase + (((struct grub_module_info *) grub_modbase)->offset)) : 0;\ - var && (grub_addr_t) var \ - < (grub_modbase + (((struct grub_module_info *) grub_modbase)->size)); \ - var = (struct grub_module_header *) \ - (((grub_uint32_t *) var) + ((((struct grub_module_header *) var)->size + sizeof (grub_addr_t) - 1) / sizeof (grub_addr_t)) * (sizeof (grub_addr_t) / sizeof (grub_uint32_t)))) - -grub_addr_t grub_modules_get_end (void); - -#endif +extern void EXPORT_FUNC(grub_module_iterate) (int (*hook) (struct grub_module_header *)); /* The start point of the C code. */ -void grub_main (void) __attribute__ ((noreturn)); +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) (int flags); +void EXPORT_FUNC(grub_machine_fini) (void); /* The machine-specific prefix initialization. */ -void -grub_machine_get_bootlocation (char **device, char **path); +void grub_machine_set_prefix (void); /* Register all the exported symbols. This is automatically generated. */ void grub_register_exported_symbols (void); -extern void (*EXPORT_VAR(grub_net_poll_cards_idle)) (void); - #endif /* ! GRUB_KERNEL_HEADER */ diff --git a/include/grub/key_protector.h b/include/grub/key_protector.h deleted file mode 100644 index 00b15c13d..000000000 --- a/include/grub/key_protector.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2022 Microsoft Corporation - * Copyright (C) 2024 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_PROTECTOR_HEADER -#define GRUB_PROTECTOR_HEADER 1 - -#include -#include - -struct grub_key_protector -{ - struct grub_key_protector *next; - struct grub_key_protector **prev; - - const char *name; - - grub_err_t (*recover_key) (grub_uint8_t **key, grub_size_t *key_size); -}; - -grub_err_t -grub_key_protector_register (struct grub_key_protector *protector); - -grub_err_t -grub_key_protector_unregister (struct grub_key_protector *protector); - -grub_err_t -grub_key_protector_recover_key (const char *protector, - grub_uint8_t **key, - grub_size_t *key_size); - -#endif /* ! GRUB_PROTECTOR_HEADER */ diff --git a/include/grub/keyboard_layouts.h b/include/grub/keyboard_layouts.h deleted file mode 100644 index 1bad286f9..000000000 --- a/include/grub/keyboard_layouts.h +++ /dev/null @@ -1,150 +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 . - */ - -#ifndef GRUB_KEYBOARD_LAYOUTS_H -#define GRUB_KEYBOARD_LAYOUTS_H 1 - -#define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC "GRUBLAYO" -#define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE (sizeof(GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1) -#define GRUB_KEYBOARD_LAYOUTS_VERSION 10 - -#define GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE 160 - -struct grub_keyboard_layout -{ - grub_uint32_t keyboard_map[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - grub_uint32_t keyboard_map_shift[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - grub_uint32_t keyboard_map_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - grub_uint32_t keyboard_map_shift_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; -}; - -typedef enum grub_keyboard_key - { - GRUB_KEYBOARD_KEY_A = 0x04, - GRUB_KEYBOARD_KEY_B = 0x05, - GRUB_KEYBOARD_KEY_C = 0x06, - GRUB_KEYBOARD_KEY_D = 0x07, - GRUB_KEYBOARD_KEY_E = 0x08, - GRUB_KEYBOARD_KEY_F = 0x09, - GRUB_KEYBOARD_KEY_G = 0x0a, - GRUB_KEYBOARD_KEY_H = 0x0b, - GRUB_KEYBOARD_KEY_I = 0x0c, - GRUB_KEYBOARD_KEY_J = 0x0d, - GRUB_KEYBOARD_KEY_K = 0x0e, - GRUB_KEYBOARD_KEY_L = 0x0f, - GRUB_KEYBOARD_KEY_M = 0x10, - GRUB_KEYBOARD_KEY_N = 0x11, - GRUB_KEYBOARD_KEY_O = 0x12, - GRUB_KEYBOARD_KEY_P = 0x13, - GRUB_KEYBOARD_KEY_Q = 0x14, - GRUB_KEYBOARD_KEY_R = 0x15, - GRUB_KEYBOARD_KEY_S = 0x16, - GRUB_KEYBOARD_KEY_T = 0x17, - GRUB_KEYBOARD_KEY_U = 0x18, - GRUB_KEYBOARD_KEY_V = 0x19, - GRUB_KEYBOARD_KEY_W = 0x1a, - GRUB_KEYBOARD_KEY_X = 0x1b, - GRUB_KEYBOARD_KEY_Y = 0x1c, - GRUB_KEYBOARD_KEY_Z = 0x1d, - GRUB_KEYBOARD_KEY_1 = 0x1e, - GRUB_KEYBOARD_KEY_2 = 0x1f, - GRUB_KEYBOARD_KEY_3 = 0x20, - GRUB_KEYBOARD_KEY_4 = 0x21, - GRUB_KEYBOARD_KEY_5 = 0x22, - GRUB_KEYBOARD_KEY_6 = 0x23, - GRUB_KEYBOARD_KEY_7 = 0x24, - GRUB_KEYBOARD_KEY_8 = 0x25, - GRUB_KEYBOARD_KEY_9 = 0x26, - GRUB_KEYBOARD_KEY_0 = 0x27, - GRUB_KEYBOARD_KEY_ENTER = 0x28, - GRUB_KEYBOARD_KEY_ESCAPE = 0x29, - GRUB_KEYBOARD_KEY_BACKSPACE = 0x2a, - GRUB_KEYBOARD_KEY_TAB = 0x2b, - GRUB_KEYBOARD_KEY_SPACE = 0x2c, - GRUB_KEYBOARD_KEY_DASH = 0x2d, - GRUB_KEYBOARD_KEY_EQUAL = 0x2e, - GRUB_KEYBOARD_KEY_LBRACKET = 0x2f, - GRUB_KEYBOARD_KEY_RBRACKET = 0x30, - GRUB_KEYBOARD_KEY_BACKSLASH = 0x32, - GRUB_KEYBOARD_KEY_SEMICOLON = 0x33, - GRUB_KEYBOARD_KEY_DQUOTE = 0x34, - GRUB_KEYBOARD_KEY_RQUOTE = 0x35, - GRUB_KEYBOARD_KEY_COMMA = 0x36, - GRUB_KEYBOARD_KEY_DOT = 0x37, - GRUB_KEYBOARD_KEY_SLASH = 0x38, - GRUB_KEYBOARD_KEY_CAPS_LOCK = 0x39, - GRUB_KEYBOARD_KEY_F1 = 0x3a, - GRUB_KEYBOARD_KEY_F2 = 0x3b, - GRUB_KEYBOARD_KEY_F3 = 0x3c, - GRUB_KEYBOARD_KEY_F4 = 0x3d, - GRUB_KEYBOARD_KEY_F5 = 0x3e, - GRUB_KEYBOARD_KEY_F6 = 0x3f, - GRUB_KEYBOARD_KEY_F7 = 0x40, - GRUB_KEYBOARD_KEY_F8 = 0x41, - GRUB_KEYBOARD_KEY_F9 = 0x42, - GRUB_KEYBOARD_KEY_F10 = 0x43, - GRUB_KEYBOARD_KEY_F11 = 0x44, - GRUB_KEYBOARD_KEY_F12 = 0x45, - GRUB_KEYBOARD_KEY_SCROLL_LOCK = 0x47, - GRUB_KEYBOARD_KEY_INSERT = 0x49, - GRUB_KEYBOARD_KEY_HOME = 0x4a, - GRUB_KEYBOARD_KEY_PPAGE = 0x4b, - GRUB_KEYBOARD_KEY_DELETE = 0x4c, - GRUB_KEYBOARD_KEY_END = 0x4d, - GRUB_KEYBOARD_KEY_NPAGE = 0x4e, - GRUB_KEYBOARD_KEY_RIGHT = 0x4f, - GRUB_KEYBOARD_KEY_LEFT = 0x50, - GRUB_KEYBOARD_KEY_DOWN = 0x51, - GRUB_KEYBOARD_KEY_UP = 0x52, - GRUB_KEYBOARD_KEY_NUM_LOCK = 0x53, - GRUB_KEYBOARD_KEY_NUMSLASH = 0x54, - GRUB_KEYBOARD_KEY_NUMMUL = 0x55, - GRUB_KEYBOARD_KEY_NUMMINUS = 0x56, - GRUB_KEYBOARD_KEY_NUMPLUS = 0x57, - GRUB_KEYBOARD_KEY_NUMENTER = 0x58, - GRUB_KEYBOARD_KEY_NUM1 = 0x59, - GRUB_KEYBOARD_KEY_NUM2 = 0x5a, - GRUB_KEYBOARD_KEY_NUM3 = 0x5b, - GRUB_KEYBOARD_KEY_NUM4 = 0x5c, - GRUB_KEYBOARD_KEY_NUM5 = 0x5d, - GRUB_KEYBOARD_KEY_NUM6 = 0x5e, - GRUB_KEYBOARD_KEY_NUM7 = 0x5f, - GRUB_KEYBOARD_KEY_NUM8 = 0x60, - GRUB_KEYBOARD_KEY_NUM9 = 0x61, - GRUB_KEYBOARD_KEY_NUM0 = 0x62, - GRUB_KEYBOARD_KEY_NUMDOT = 0x63, - GRUB_KEYBOARD_KEY_102ND = 0x64, - GRUB_KEYBOARD_KEY_KPCOMMA = 0x85, - GRUB_KEYBOARD_KEY_JP_RO = 0x87, - GRUB_KEYBOARD_KEY_JP_YEN = 0x89, - GRUB_KEYBOARD_KEY_LEFT_CTRL = 0xe0, - GRUB_KEYBOARD_KEY_LEFT_SHIFT = 0xe1, - GRUB_KEYBOARD_KEY_LEFT_ALT = 0xe2, - GRUB_KEYBOARD_KEY_RIGHT_CTRL = 0xe4, - GRUB_KEYBOARD_KEY_RIGHT_SHIFT = 0xe5, - GRUB_KEYBOARD_KEY_RIGHT_ALT = 0xe6, - } grub_keyboard_key_t; - -unsigned EXPORT_FUNC(grub_term_map_key) (grub_keyboard_key_t code, int status); - -#ifndef GRUB_MACHINE_EMU -extern void grub_keylayouts_init (void); -extern void grub_keylayouts_fini (void); -#endif - -#endif /* GRUB_KEYBOARD_LAYOUTS */ diff --git a/include/grub/legacy_parse.h b/include/grub/legacy_parse.h deleted file mode 100644 index 751950590..000000000 --- a/include/grub/legacy_parse.h +++ /dev/null @@ -1,32 +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 . - */ - -#ifndef GRUB_LEGACY_PARSE_HEADER -#define GRUB_LEGACY_PARSE_HEADER 1 - -#include - -char *grub_legacy_parse (const char *buf, char **entryname, char **suffix); -char *grub_legacy_escape (const char *in, grub_size_t len); - -/* Entered has to be GRUB_AUTH_MAX_PASSLEN long, zero-padded. */ -int -grub_legacy_check_md5_password (int argc, char **args, - char *entered); - -#endif diff --git a/include/grub/lib/LzmaDec.h b/include/grub/lib/LzmaDec.h index 16914c961..1e66b74d7 100644 --- a/include/grub/lib/LzmaDec.h +++ b/include/grub/lib/LzmaDec.h @@ -27,7 +27,7 @@ #ifndef __LZMADEC_H #define __LZMADEC_H -#include "LzmaTypes.h" +#include "Types.h" /* #define _LZMA_PROB32 */ /* _LZMA_PROB32 can increase the speed on some CPUs, diff --git a/include/grub/lib/arg.h b/include/grub/lib/arg.h index f81af85ee..e6af60cf9 100644 --- a/include/grub/lib/arg.h +++ b/include/grub/lib/arg.h @@ -38,8 +38,6 @@ 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) -/* Flags for an option that can appear multiple times. */ -#define GRUB_ARG_OPTION_REPEATABLE (1 << 2) enum grub_key_type { @@ -53,18 +51,15 @@ struct grub_arg_option const char *longarg; int shortarg; int flags; - const char *doc; - const char *arg; + char *doc; + char *arg; grub_arg_type_t type; }; struct grub_arg_list { int set; - union { - char *arg; - char **args; - }; + char *arg; }; struct grub_extcmd; @@ -72,8 +67,6 @@ 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 EXPORT_FUNC(grub_arg_show_help) (struct grub_extcmd *cmd); -struct grub_arg_list* grub_arg_list_alloc (struct grub_extcmd *cmd, - int argc, char *argv[]); +void grub_arg_show_help (struct grub_extcmd *cmd); #endif /* ! GRUB_ARG_HEADER */ diff --git a/include/grub/lib/cmdline.h b/include/grub/lib/cmdline.h deleted file mode 100644 index cdca09b7a..000000000 --- a/include/grub/lib/cmdline.h +++ /dev/null @@ -1,32 +0,0 @@ -/* cmdline.h - linux command line handling */ -/* - * 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 . - */ - -#ifndef GRUB_CMDLINE_HEADER -#define GRUB_CMDLINE_HEADER 1 - -#include -#include - -#define LINUX_IMAGE "BOOT_IMAGE=" - -unsigned int grub_loader_cmdline_size (int argc, char *argv[]); -grub_err_t grub_create_loader_cmdline (int argc, char *argv[], char *buf, - grub_size_t size, enum grub_verify_string_type type); - -#endif /* ! GRUB_CMDLINE_HEADER */ diff --git a/include/grub/lib/crc.h b/include/grub/lib/crc.h index c5098a8c3..ff7284dc8 100644 --- a/include/grub/lib/crc.h +++ b/include/grub/lib/crc.h @@ -20,6 +20,6 @@ #ifndef GRUB_CRC_H #define GRUB_CRC_H 1 -grub_uint32_t grub_getcrc32c (grub_uint32_t crc, const void *buf, int size); +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 index c3e655921..368ba5368 100644 --- a/include/grub/lib/envblk.h +++ b/include/grub/lib/envblk.h @@ -35,8 +35,7 @@ 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, - void *hook_data, - int hook (const char *name, const char *value, void *hook_data)); + int hook (const char *name, const char *value)); void grub_envblk_close (grub_envblk_t envblk); static inline char * diff --git a/include/grub/libpciaccess.h b/include/grub/libpciaccess.h deleted file mode 100644 index 4d2b3bde5..000000000 --- a/include/grub/libpciaccess.h +++ /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 . - */ - -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/linux.h b/include/grub/linux.h deleted file mode 100644 index a96ac2048..000000000 --- a/include/grub/linux.h +++ /dev/null @@ -1,24 +0,0 @@ -#include - -struct grub_linux_initrd_component; - -struct grub_linux_initrd_context -{ - int nfiles; - struct grub_linux_initrd_component *components; - grub_size_t size; -}; - -grub_err_t -grub_initrd_init (int argc, char *argv[], - struct grub_linux_initrd_context *ctx); - -grub_size_t -grub_get_initrd_size (struct grub_linux_initrd_context *ctx); - -void -grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx); - -grub_err_t -grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, - void *target); diff --git a/include/grub/list.h b/include/grub/list.h index 21f4b4b44..b7703e214 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -21,51 +21,53 @@ #define GRUB_LIST_HEADER 1 #include -#include -#include +#include +#include struct grub_list { struct grub_list *next; - struct grub_list **prev; }; typedef struct grub_list *grub_list_t; -void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item); -void EXPORT_FUNC(grub_list_remove) (grub_list_t item); +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); -#define FOR_LIST_ELEMENTS(var, list) for ((var) = (list); (var); (var) = (var)->next) -#define FOR_LIST_ELEMENTS_NEXT(var, list) for ((var) = (var)->next; (var); (var) = (var)->next) -#define FOR_LIST_ELEMENTS_SAFE(var, nxt, list) for ((var) = (list), (nxt) = ((var) ? (var)->next : 0); (var); (var) = (nxt), ((nxt) = (var) ? (var)->next : 0)) +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) - GRUB_ATTRIBUTE_ERROR ("bad type cast between incompatible grub types"); + 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_bad_type_cast() grub_bad_type_cast_real(__LINE__, __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_FIELD_MATCH (ptr, grub_list_t, prev) ? \ - (grub_list_t) ptr : (grub_list_t) grub_bad_type_cast ()) + (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_FIELD_MATCH (*pptr, grub_list_t, prev) ? \ - (grub_list_t *) (void *) pptr : (grub_list_t *) grub_bad_type_cast ()) + (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; - struct grub_named_list **prev; char *name; }; typedef struct grub_named_list *grub_named_list_t; @@ -74,15 +76,47 @@ 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, prev) \ - && GRUB_FIELD_MATCH (ptr, grub_named_list_t, name))? \ - (grub_named_list_t) ptr : (grub_named_list_t) grub_bad_type_cast ()) + ((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, prev) \ - && GRUB_FIELD_MATCH (*pptr, grub_named_list_t, name))? \ - (grub_named_list_t *) (void *) pptr : (grub_named_list_t *) grub_bad_type_cast ()) + ((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 index 97f231054..319f3c551 100644 --- a/include/grub/loader.h +++ b/include/grub/loader.h @@ -26,27 +26,16 @@ #include /* Check if a loader is loaded. */ -int EXPORT_FUNC (grub_loader_is_loaded) (void); +int grub_loader_is_loaded (void); -/* Set loader functions. */ -enum -{ - GRUB_LOADER_FLAG_NORETURN = 1, - GRUB_LOADER_FLAG_PXE_NOT_UNLOAD = 2, - GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY = 4, -}; - -void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void), - grub_err_t (*unload) (void), - int flags); - -void EXPORT_FUNC (grub_loader_set_ex) (grub_err_t (*boot) (void *context), - grub_err_t (*unload) (void *context), - void *context, - int flags); +/* 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 EXPORT_FUNC (grub_loader_unset) (void); +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. */ @@ -67,18 +56,11 @@ typedef enum { } grub_loader_preboot_hook_prio_t; /* Register a preboot hook. */ -struct grub_preboot; - -struct grub_preboot *EXPORT_FUNC(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); +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 EXPORT_FUNC (grub_loader_unregister_preboot_hook) (struct grub_preboot *hnd); - -#ifndef GRUB_MACHINE_EMU -void grub_boot_init (void); -void grub_boot_fini (void); -#endif +void grub_loader_unregister_preboot_hook (void *hnd); #endif /* ! GRUB_LOADER_HEADER */ diff --git a/include/grub/loongarch64/efi/memory.h b/include/grub/loongarch64/efi/memory.h deleted file mode 100644 index d460267be..000000000 --- a/include/grub/loongarch64/efi/memory.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_MEMORY_CPU_HEADER -#include - -#define GRUB_EFI_MAX_USABLE_ADDRESS 0xfffffffffffULL - -#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/loongarch64/reloc.h b/include/grub/loongarch64/reloc.h deleted file mode 100644 index 8ba355385..000000000 --- a/include/grub/loongarch64/reloc.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_LOONGARCH64_RELOC_H -#define GRUB_LOONGARCH64_RELOC_H 1 -#include - -#define LOONGARCH64_STACK_MAX 16 - -struct grub_loongarch64_stack -{ - grub_uint64_t data[LOONGARCH64_STACK_MAX]; - int count; - int top; -}; - -typedef struct grub_loongarch64_stack* grub_loongarch64_stack_t; - -void grub_loongarch64_stack_init (grub_loongarch64_stack_t stack); -void grub_loongarch64_sop_push (grub_loongarch64_stack_t stack, - grub_int64_t offset); -void grub_loongarch64_sop_sub (grub_loongarch64_stack_t stack); -void grub_loongarch64_sop_sl (grub_loongarch64_stack_t stack); -void grub_loongarch64_sop_sr (grub_loongarch64_stack_t stack); -void grub_loongarch64_sop_add (grub_loongarch64_stack_t stack); -void grub_loongarch64_sop_and (grub_loongarch64_stack_t stack); -void grub_loongarch64_sop_if_else (grub_loongarch64_stack_t stack); -void grub_loongarch64_sop_32_s_10_5 (grub_loongarch64_stack_t stack, - grub_uint64_t *place); -void grub_loongarch64_sop_32_u_10_12 (grub_loongarch64_stack_t stack, - grub_uint64_t *place); -void grub_loongarch64_sop_32_s_10_12 (grub_loongarch64_stack_t stack, - grub_uint64_t *place); -void grub_loongarch64_sop_32_s_10_16 (grub_loongarch64_stack_t stack, - grub_uint64_t *place); -void grub_loongarch64_sop_32_s_10_16_s2 (grub_loongarch64_stack_t stack, - grub_uint64_t *place); -void grub_loongarch64_sop_32_s_5_20 (grub_loongarch64_stack_t stack, - grub_uint64_t *place); -void grub_loongarch64_sop_32_s_0_5_10_16_s2 (grub_loongarch64_stack_t stack, - grub_uint64_t *place); -void grub_loongarch64_sop_32_s_0_10_10_16_s2 (grub_loongarch64_stack_t stack, - grub_uint64_t *place); - -void grub_loongarch64_b26 (grub_uint32_t *place, grub_int64_t offset); -void grub_loongarch64_xxx_hi20 (grub_uint32_t *place, grub_int64_t offset); -void grub_loongarch64_xxx_lo12 (grub_uint32_t *place, grub_int64_t offset); -void grub_loongarch64_abs64_hi12 (grub_uint32_t *place, grub_int64_t offset); -void grub_loongarch64_abs64_lo20 (grub_uint32_t *place, grub_int64_t offset); - -#define GRUB_LOONGARCH64_RELOCATION(STACK, PLACE, OFFSET) \ - case R_LARCH_SOP_PUSH_ABSOLUTE: \ - grub_loongarch64_sop_push (STACK, OFFSET); \ - break; \ - case R_LARCH_SOP_SUB: \ - grub_loongarch64_sop_sub (STACK); \ - break; \ - case R_LARCH_SOP_SL: \ - grub_loongarch64_sop_sl (STACK); \ - break; \ - case R_LARCH_SOP_SR: \ - grub_loongarch64_sop_sr (STACK); \ - break; \ - case R_LARCH_SOP_ADD: \ - grub_loongarch64_sop_add (STACK); \ - break; \ - case R_LARCH_SOP_AND: \ - grub_loongarch64_sop_and (STACK); \ - break; \ - case R_LARCH_SOP_IF_ELSE: \ - grub_loongarch64_sop_if_else (STACK); \ - break; \ - case R_LARCH_SOP_POP_32_S_10_5: \ - grub_loongarch64_sop_32_s_10_5 (STACK, PLACE); \ - break; \ - case R_LARCH_SOP_POP_32_U_10_12: \ - grub_loongarch64_sop_32_u_10_12 (STACK, PLACE); \ - break; \ - case R_LARCH_SOP_POP_32_S_10_12: \ - grub_loongarch64_sop_32_s_10_12 (STACK, PLACE); \ - break; \ - case R_LARCH_SOP_POP_32_S_10_16: \ - grub_loongarch64_sop_32_s_10_16 (STACK, PLACE); \ - break; \ - case R_LARCH_SOP_POP_32_S_10_16_S2: \ - grub_loongarch64_sop_32_s_10_16_s2 (STACK, PLACE); \ - break; \ - case R_LARCH_SOP_POP_32_S_5_20: \ - grub_loongarch64_sop_32_s_5_20 (STACK, PLACE); \ - break; \ - case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: \ - grub_loongarch64_sop_32_s_0_5_10_16_s2 (STACK, PLACE); \ - break; \ - case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: \ - grub_loongarch64_sop_32_s_0_10_10_16_s2 (STACK, PLACE); \ - break; - -#endif /* GRUB_LOONGARCH64_RELOC_H */ diff --git a/include/grub/loongarch64/setjmp.h b/include/grub/loongarch64/setjmp.h deleted file mode 100644 index f9a14d4cf..000000000 --- a/include/grub/loongarch64/setjmp.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_SETJMP_CPU_HEADER -#define GRUB_SETJMP_CPU_HEADER 1 - -typedef grub_uint64_t grub_jmp_buf[12]; - -int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; -void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); - -#endif /* ! GRUB_SETJMP_CPU_HEADER */ diff --git a/include/grub/loongarch64/types.h b/include/grub/loongarch64/types.h deleted file mode 100644 index fddf38378..000000000 --- a/include/grub/loongarch64/types.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#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 - -/* LoongArch is little-endian. */ -#undef GRUB_TARGET_WORDS_BIGENDIAN - -/* Unaligned accesses are only supported if MMU is enabled. */ -#undef GRUB_HAVE_UNALIGNED_ACCESS - -#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/lvm.h b/include/grub/lvm.h index 30a609c20..a4bf3b288 100644 --- a/include/grub/lvm.h +++ b/include/grub/lvm.h @@ -21,11 +21,50 @@ #define GRUB_LVM_H 1 #include -#include /* 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 @@ -41,13 +80,13 @@ struct grub_lvm_label_header { 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 */ -} GRUB_PACKED; +} __attribute__ ((packed)); /* On disk */ struct grub_lvm_disk_locn { grub_uint64_t offset; /* Offset in bytes to start sector */ grub_uint64_t size; /* Bytes */ -} GRUB_PACKED; +} __attribute__ ((packed)); /* Fields with the suffix _xl should be xlate'd wherever they appear */ /* On disk */ @@ -60,7 +99,7 @@ struct grub_lvm_pv_header { /* 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 */ -} GRUB_PACKED; +} __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 @@ -72,7 +111,7 @@ struct grub_lvm_raw_locn { grub_uint64_t size; /* Bytes */ grub_uint32_t checksum; grub_uint32_t filler; -} GRUB_PACKED; +} __attribute__ ((packed)); /* On disk */ /* Structure size limited to one sector */ @@ -84,7 +123,7 @@ struct grub_lvm_mda_header { grub_uint64_t size; /* Size of metadata area */ struct grub_lvm_raw_locn raw_locns[0]; /* NULL-terminated list */ -} GRUB_PACKED; +} __attribute__ ((packed)); #endif /* ! GRUB_LVM_H */ diff --git a/include/grub/macho.h b/include/grub/macho.h index 2dea625f1..82145835f 100644 --- a/include/grub/macho.h +++ b/include/grub/macho.h @@ -25,16 +25,8 @@ struct grub_macho_fat_header { grub_uint32_t magic; grub_uint32_t nfat_arch; -} GRUB_PACKED; - -enum - { - GRUB_MACHO_CPUTYPE_IA32 = 0x00000007, - GRUB_MACHO_CPUTYPE_AMD64 = 0x01000007 - }; - +} __attribute__ ((packed)); #define GRUB_MACHO_FAT_MAGIC 0xcafebabe -#define GRUB_MACHO_FAT_EFI_MAGIC 0x0ef1fab9U typedef grub_uint32_t grub_macho_cpu_type_t; typedef grub_uint32_t grub_macho_cpu_subtype_t; @@ -47,7 +39,7 @@ struct grub_macho_fat_arch grub_uint32_t offset; grub_uint32_t size; grub_uint32_t align; -} GRUB_PACKED; +} __attribute__ ((packed)); /* File header for 32-bit. Always in native-endian. */ struct grub_macho_header32 @@ -60,7 +52,7 @@ struct grub_macho_header32 grub_uint32_t ncmds; grub_uint32_t sizeofcmds; grub_uint32_t flags; -} GRUB_PACKED; +} __attribute__ ((packed)); /* File header for 64-bit. Always in native-endian. */ struct grub_macho_header64 @@ -74,14 +66,22 @@ struct grub_macho_header64 grub_uint32_t sizeofcmds; grub_uint32_t flags; grub_uint32_t reserved; -} GRUB_PACKED; +} __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; -} GRUB_PACKED; +} __attribute__ ((packed)); typedef grub_uint32_t grub_macho_vmprot_t; @@ -100,7 +100,7 @@ struct grub_macho_segment32 grub_macho_vmprot_t initprot; grub_uint32_t nsects; grub_uint32_t flags; -} GRUB_PACKED; +} __attribute__ ((packed)); /* 64-bit segment command. */ struct grub_macho_segment64 @@ -117,50 +117,8 @@ struct grub_macho_segment64 grub_macho_vmprot_t initprot; grub_uint32_t nsects; grub_uint32_t flags; -} GRUB_PACKED; +} __attribute__ ((packed)); #define GRUB_MACHO_CMD_THREAD 5 -struct grub_macho_lzss_header -{ - char magic[8]; -#define GRUB_MACHO_LZSS_MAGIC "complzss" - grub_uint32_t unused; - grub_uint32_t uncompressed_size; - grub_uint32_t compressed_size; -}; - -/* 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; - struct grub_macho_lzss_header lzss; -} GRUB_PACKED; - -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]; -} GRUB_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]; -} GRUB_PACKED; - -#define GRUB_MACHO_LZSS_OFFSET 0x180 - -grub_size_t -grub_decompress_lzss (grub_uint8_t *dst, grub_uint8_t *dstend, - grub_uint8_t *src, grub_uint8_t *srcend); - #endif diff --git a/include/grub/machoload.h b/include/grub/machoload.h index f1157f410..8410162fb 100644 --- a/include/grub/machoload.h +++ b/include/grub/machoload.h @@ -33,57 +33,41 @@ struct grub_macho_file int ncmds32; grub_size_t cmdsize32; grub_uint8_t *cmds32; - grub_uint8_t *uncompressed32; - int compressed32; - grub_size_t compressed_size32; - grub_size_t uncompressed_size32; grub_ssize_t offset64; grub_ssize_t end64; int ncmds64; grub_size_t cmdsize64; grub_uint8_t *cmds64; - grub_uint8_t *uncompressed64; - int compressed64; - grub_size_t compressed_size64; - grub_size_t uncompressed_size64; }; typedef struct grub_macho_file *grub_macho_t; -grub_macho_t grub_macho_open (const char *, enum grub_file_type type, - int is_64bit); -grub_macho_t grub_macho_file (grub_file_t file, const char *filename, - int is_64bit); +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, - const char *filename); -grub_uint32_t grub_macho_get_entry_point32 (grub_macho_t macho, - const char *filename); + 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, - const char *filename); -grub_uint64_t grub_macho_get_entry_point64 (grub_macho_t macho, - const char *filename); + 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, const char *filename, - char *offset, int flags, int *darwin_version); -grub_err_t grub_macho_load64 (grub_macho_t macho, const char *filename, - char *offset, int flags, int *darwin_version); +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, const char *filename, - void *dest); +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, const char *filename, - void *dest); +grub_err_t grub_macho_readfile64 (grub_macho_t macho, void *dest); -void grub_macho_parse32 (grub_macho_t macho, const char *filename); -void grub_macho_parse64 (grub_macho_t macho, const char *filename); +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 index 6da114a1b..43f90e1dd 100644 --- a/include/grub/memory.h +++ b/include/grub/memory.h @@ -22,45 +22,11 @@ #include #include +#include -typedef enum grub_memory_type - { - GRUB_MEMORY_AVAILABLE = 1, - GRUB_MEMORY_RESERVED = 2, - GRUB_MEMORY_ACPI = 3, - GRUB_MEMORY_NVS = 4, - GRUB_MEMORY_BADRAM = 5, - GRUB_MEMORY_PERSISTENT = 7, - GRUB_MEMORY_PERSISTENT_LEGACY = 12, - GRUB_MEMORY_COREBOOT_TABLES = 16, - GRUB_MEMORY_CODE = 20, - /* This one is special: it's used internally but is never reported - by firmware. Don't use -1 as it's used internally for other purposes. */ - GRUB_MEMORY_HOLE = -2, - GRUB_MEMORY_MAX = 0x10000 - } grub_memory_type_t; - -typedef int (*grub_memory_hook_t) (grub_uint64_t, - grub_uint64_t, - grub_memory_type_t, - void *); - -grub_err_t grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data); - -#ifdef GRUB_MACHINE_EFI -grub_err_t -grub_efi_mmap_iterate (grub_memory_hook_t hook, void *hook_data, - int avoid_efi_boot_services); -#endif - -#if !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_EFI) -grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) (grub_memory_hook_t hook, - void *hook_data); -#else -grub_err_t grub_machine_mmap_iterate (grub_memory_hook_t hook, - void *hook_data); -#endif - +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); @@ -76,9 +42,8 @@ struct grub_mmap_region struct grub_mmap_region *next; grub_uint64_t start; grub_uint64_t end; - grub_memory_type_t type; + int type; int handle; - int priority; }; extern struct grub_mmap_region *grub_mmap_overlays; diff --git a/include/grub/menu.h b/include/grub/menu.h index ee2b5e910..78f461b92 100644 --- a/include/grub/menu.h +++ b/include/grub/menu.h @@ -32,9 +32,6 @@ struct grub_menu_entry /* The title name. */ const char *title; - /* The identifier. */ - const char *id; - /* If set means not everybody is allowed to boot this entry. */ int restricted; @@ -50,14 +47,6 @@ struct grub_menu_entry /* The sourcecode of the menu entry, used by the editor. */ const char *sourcecode; - /* Parameters to be passed to menu definition. */ - int argc; - char **args; - - int hotkey; - - int submenu; - /* The next element. */ struct grub_menu_entry *next; }; @@ -97,10 +86,12 @@ typedef struct grub_menu_execute_callback 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); -void grub_menu_init (void); -void grub_menu_fini (void); - #endif /* GRUB_MENU_HEADER */ diff --git a/include/grub/menu_viewer.h b/include/grub/menu_viewer.h index 604c07ad1..c6513c4e8 100644 --- a/include/grub/menu_viewer.h +++ b/include/grub/menu_viewer.h @@ -39,7 +39,7 @@ struct grub_menu_viewer void grub_menu_register_viewer (struct grub_menu_viewer *viewer); grub_err_t -grub_menu_try_text (struct grub_term_output *term, +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, diff --git a/include/grub/mips/arc/kernel.h b/include/grub/mips/arc/kernel.h deleted file mode 100644 index 50694866b..000000000 --- a/include/grub/mips/arc/kernel.h +++ /dev/null @@ -1,2 +0,0 @@ -#include - diff --git a/include/grub/mips/arc/memory.h b/include/grub/mips/arc/memory.h deleted file mode 100644 index 77bb03d3e..000000000 --- a/include/grub/mips/arc/memory.h +++ /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 . - */ - -#ifndef GRUB_MEMORY_MACHINE_HEADER -#define GRUB_MEMORY_MACHINE_HEADER 1 - -#ifdef GRUB_CPU_MIPSEL -#define GRUB_MACHINE_MEMORY_STACK_HIGH 0x806ffff0 -#else -#define GRUB_MACHINE_MEMORY_STACK_HIGH 0x881ffff0 -#endif - -#ifndef ASM_FILE - -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/arc/time.h b/include/grub/mips/arc/time.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/include/grub/mips/asm.h b/include/grub/mips/asm.h deleted file mode 100644 index 4c397f4a0..000000000 --- a/include/grub/mips/asm.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef GRUB_MIPS_ASM_HEADER -#define GRUB_MIPS_ASM_HEADER 1 - -#if defined(_MIPS_SIM) && defined(_ABIN32) && _MIPS_SIM == _ABIN32 -#define GRUB_ASM_T4 $a4 -#define GRUB_ASM_T5 $a5 -#define GRUB_ASM_SZREG 8 -#define GRUB_ASM_REG_S sd -#define GRUB_ASM_REG_L ld -#else -#define GRUB_ASM_T4 $t4 -#define GRUB_ASM_T5 $t5 -#define GRUB_ASM_SZREG 4 -#define GRUB_ASM_REG_S sw -#define GRUB_ASM_REG_L lw -#endif - -#endif diff --git a/include/grub/efi/fdtload.h b/include/grub/mips/cache.h similarity index 72% rename from include/grub/efi/fdtload.h rename to include/grub/mips/cache.h index 713c9424d..c3470571e 100644 --- a/include/grub/efi/fdtload.h +++ b/include/grub/mips/cache.h @@ -1,6 +1,7 @@ +/* cache.h - Flush the processor's cache. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013-2015 Free Software Foundation, Inc. + * 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 @@ -16,17 +17,11 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_FDTLOAD_CPU_HEADER -#define GRUB_FDTLOAD_CPU_HEADER 1 +#ifndef GRUB_CPU_CACHE_H +#define GRUB_CPU_CACHE_H 1 +#include #include -#include -void * -grub_fdt_load (grub_size_t additional_size); -void -grub_fdt_unload (void); -grub_err_t -grub_fdt_install (void); - -#endif +void EXPORT_FUNC(grub_cpu_flush_cache) (void *start, grub_size_t size, int type); +#endif diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index 07b08848d..8b68f7b6b 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * 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 @@ -19,6 +19,47 @@ #ifndef GRUB_KERNEL_CPU_HEADER #define GRUB_KERNEL_CPU_HEADER 1 -#include +#define GRUB_MOD_ALIGN 0x1 +/* Non-zero value is only needed for PowerMacs. */ +#define GRUB_MOD_GAP 0x0 -#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ +#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/kern/i386/xen/startup.S b/include/grub/mips/libgcc.h similarity index 60% rename from grub-core/kern/i386/xen/startup.S rename to include/grub/mips/libgcc.h index fbe8300a7..f06ea1c1c 100644 --- a/grub-core/kern/i386/xen/startup.S +++ b/include/grub/mips/libgcc.h @@ -1,7 +1,6 @@ -/* startup.S - bootstrap GRUB itself */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. + * 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 @@ -18,21 +17,22 @@ */ #include -#include - .file "startup.S" - .text - .globl start, _start - .code32 - -start: -_start: - leal LOCAL(stack_end), %esp - movl %esi, EXT_C(grub_xen_start_page_addr) - - call EXT_C(grub_main) - /* Doesn't return. */ - - .bss - .space (1 << 22) -LOCAL(stack_end): +#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 diff --git a/include/grub/mips/loongson.h b/include/grub/mips/loongson.h deleted file mode 100644 index e6f0241f2..000000000 --- a/include/grub/mips/loongson.h +++ /dev/null @@ -1,86 +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 . - */ - -#ifndef GRUB_LOONGSON_CPU_HEADER -#define GRUB_LOONGSON_CPU_HEADER 1 - -#include - -#define GRUB_CPU_LOONGSON_FLASH_START 0xbfc00000 -#define GRUB_CPU_LOONGSON_FLASH_TLB_REFILL 0xbfc00200 -#define GRUB_CPU_LOONGSON_FLASH_CACHE_ERROR 0xbfc00300 -#define GRUB_CPU_LOONGSON_FLASH_OTHER_EXCEPTION 0xbfc00380 - -#define GRUB_CPU_LOONGSON_DDR2_BASE 0xaffffe00 -#define GRUB_CPU_LOONGSON_DDR2_REG1_HI_8BANKS 0x00000001 -#define GRUB_CPU_LOONGSON_DDR2_REG_SIZE 0x8 -#define GRUB_CPU_LOONGSON_DDR2_REG_STEP 0x10 - -#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG GRUB_CPU_REGISTER_WRAP($16) -#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_ILINESIZE 0x10 -#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_DLINESIZE 0x8 -#define GRUB_CPU_LOONGSON_COP0_CACHE_DSIZE_SHIFT 6 -#define GRUB_CPU_LOONGSON_COP0_CACHE_ISIZE_SHIFT 9 -#define GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK 0x7 -#define GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET 12 - -#define GRUB_CPU_LOONGSON_COP0_I_INDEX_INVALIDATE 0 -#define GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE 9 -#define GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE 11 - -#define GRUB_CPU_LOONGSON_COP0_I_INDEX_BIT_OFFSET 5 -#define GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET 5 -#define GRUB_CPU_LOONGSON_COP0_S_INDEX_BIT_OFFSET 5 - -#define GRUB_CPU_LOONGSON_CACHE_ACCELERATED 7 -#define GRUB_CPU_LOONGSON_CACHE_UNCACHED 2 -#define GRUB_CPU_LOONGSON_CACHE_CACHED 3 -#define GRUB_CPU_LOONGSON_CACHE_TYPE_MASK 7 -#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_SMALL 4 -#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG 5 -#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_SMALL 16 -#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_BIG 32 - -#define GRUB_CPU_LOONGSON_I_CACHE_LOG_WAYS 2 -#define GRUB_CPU_LOONGSON_D_CACHE_LOG_WAYS 2 -#define GRUB_CPU_LOONGSON_S_CACHE_LOG_WAYS 2 - -/* FIXME: determine dynamically. */ -#define GRUB_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE 19 - -#define GRUB_CPU_LOONGSON_COP0_BADVADDR GRUB_CPU_REGISTER_WRAP($8) -#define GRUB_CPU_LOONGSON_COP0_CAUSE GRUB_CPU_REGISTER_WRAP($13) -#define GRUB_CPU_LOONGSON_COP0_EPC GRUB_CPU_REGISTER_WRAP($14) -#define GRUB_CPU_LOONGSON_COP0_PRID GRUB_CPU_REGISTER_WRAP($15) -#define GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO GRUB_CPU_REGISTER_WRAP($28) -#define GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI GRUB_CPU_REGISTER_WRAP($29) - -#define GRUB_CPU_LOONGSON_LIOCFG 0xbfe00108 -#define GRUB_CPU_LOONGSON_ROM_DELAY_OFFSET 2 -#define GRUB_CPU_LOONGSON_ROM_DELAY_MASK 0x1f -#define GRUB_CPU_LOONGSON_CORECFG 0xbfe00180 -#define GRUB_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE 0x100 -#define GRUB_CPU_LOONGSON_CORECFG_BUFFER_CPU 0x200 - -#define GRUB_CPU_LOONGSON_PCI_HIT1_SEL_LO 0xbfe00150 -#define GRUB_CPU_LOONGSON_PCI_HIT1_SEL_HI 0xbfe00154 - -#define GRUB_CPU_LOONGSON_GPIOCFG 0xbfe00120 -#define GRUB_CPU_YEELOONG_SHUTDOWN_GPIO 1 - -#endif diff --git a/include/grub/mips/loongson/at_keyboard.h b/include/grub/mips/loongson/at_keyboard.h deleted file mode 100644 index 8e58cfb17..000000000 --- a/include/grub/mips/loongson/at_keyboard.h +++ /dev/null @@ -1,27 +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 . - */ - -#ifndef GRUB_MACHINE_AT_KEYBOARD_HEADER -#define GRUB_MACHINE_AT_KEYBOARD_HEADER 1 - -#include - -#define KEYBOARD_REG_DATA (GRUB_MACHINE_PCI_IO_BASE | 0x60) -#define KEYBOARD_REG_STATUS (GRUB_MACHINE_PCI_IO_BASE | 0x64) - -#endif diff --git a/include/grub/mips/loongson/ec.h b/include/grub/mips/loongson/ec.h deleted file mode 100644 index 3f8ff9931..000000000 --- a/include/grub/mips/loongson/ec.h +++ /dev/null @@ -1,45 +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 . - */ - -#ifndef GRUB_EC_MACHINE_HEADER -#define GRUB_EC_MACHINE_HEADER 1 - -#include -#include -#include - -#define GRUB_MACHINE_EC_MAGIC_PORT1 0x381 -#define GRUB_MACHINE_EC_MAGIC_PORT2 0x382 -#define GRUB_MACHINE_EC_DATA_PORT 0x383 - -#define GRUB_MACHINE_EC_MAGIC_VAL1 0xf4 -#define GRUB_MACHINE_EC_MAGIC_VAL2 0xec - -#define GRUB_MACHINE_EC_COMMAND_REBOOT 1 - -static inline void -grub_write_ec (grub_uint8_t value) -{ - grub_outb (GRUB_MACHINE_EC_MAGIC_VAL1, - GRUB_MACHINE_PCI_IO_BASE + GRUB_MACHINE_EC_MAGIC_PORT1); - grub_outb (GRUB_MACHINE_EC_MAGIC_VAL2, - GRUB_MACHINE_PCI_IO_BASE + GRUB_MACHINE_EC_MAGIC_PORT2); - grub_outb (value, GRUB_MACHINE_PCI_IO_BASE + GRUB_MACHINE_EC_DATA_PORT); -} - -#endif diff --git a/include/grub/mips/loongson/pci.h b/include/grub/mips/loongson/pci.h deleted file mode 100644 index b3272e922..000000000 --- a/include/grub/mips/loongson/pci.h +++ /dev/null @@ -1,110 +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 . - */ - -#ifndef GRUB_MACHINE_PCI_H -#define GRUB_MACHINE_PCI_H 1 - -#ifndef ASM_FILE -#include -#include -#endif - -#define GRUB_LOONGSON_OHCI_PCIID 0x00351033 -#define GRUB_LOONGSON_EHCI_PCIID 0x00e01033 - -#define GRUB_MACHINE_PCI_IO_BASE_2F 0xbfd00000 -#define GRUB_MACHINE_PCI_IO_BASE_3A 0xb8000000 -#define GRUB_MACHINE_PCI_CONFSPACE_2F 0xbfe80000 -#define GRUB_MACHINE_PCI_CONFSPACE_3A 0xba000000 -#define GRUB_MACHINE_PCI_CONFSPACE_3A_EXT 0xbb000000 -#define GRUB_MACHINE_PCI_CONTROLLER_HEADER 0xbfe00000 - -#define GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR_2F 0xbfe00118 - -#define GRUB_PCI_NUM_DEVICES_2F 16 - -#ifndef ASM_FILE - -typedef enum { GRUB_BONITO_2F, GRUB_BONITO_3A } grub_bonito_type_t; -extern grub_bonito_type_t EXPORT_VAR (grub_bonito_type); - -#define GRUB_PCI_NUM_DEVICES (grub_bonito_type ? 32 \ - : GRUB_PCI_NUM_DEVICES_2F) -#define GRUB_PCI_NUM_BUS (grub_bonito_type ? 256 : 1) - -#define GRUB_MACHINE_PCI_IO_BASE (grub_bonito_type \ - ? GRUB_MACHINE_PCI_IO_BASE_3A \ - : GRUB_MACHINE_PCI_IO_BASE_2F) - -#define GRUB_MACHINE_PCI_CONF_CTRL_REG_2F (*(volatile grub_uint32_t *) \ - GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR_2F) -#define GRUB_MACHINE_PCI_IO_CTRL_REG_2F (*(volatile grub_uint32_t *) 0xbfe00110) -#define GRUB_MACHINE_PCI_CONF_CTRL_REG_3A (*(volatile grub_uint32_t *) \ - 0xbfe00118) - -#endif -#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 - -#ifndef ASM_FILE -grub_uint32_t -EXPORT_FUNC (grub_pci_read) (grub_pci_address_t addr); - -grub_uint16_t -EXPORT_FUNC (grub_pci_read_word) (grub_pci_address_t addr); - -grub_uint8_t -EXPORT_FUNC (grub_pci_read_byte) (grub_pci_address_t addr); - -void -EXPORT_FUNC (grub_pci_write) (grub_pci_address_t addr, grub_uint32_t data); - -void -EXPORT_FUNC (grub_pci_write_word) (grub_pci_address_t addr, grub_uint16_t data); - -void -EXPORT_FUNC (grub_pci_write_byte) (grub_pci_address_t addr, grub_uint8_t data); - -volatile void * -EXPORT_FUNC (grub_pci_device_map_range) (grub_pci_device_t dev, - grub_addr_t base, grub_size_t size); -void * -EXPORT_FUNC (grub_pci_device_map_range_cached) (grub_pci_device_t dev, - grub_addr_t base, - grub_size_t size); -void -EXPORT_FUNC (grub_pci_device_unmap_range) (grub_pci_device_t dev, - volatile void *mem, - grub_size_t size); -#endif - -#endif /* GRUB_MACHINE_PCI_H */ diff --git a/include/grub/mips/loongson/serial.h b/include/grub/mips/loongson/serial.h deleted file mode 100644 index b35455929..000000000 --- a/include/grub/mips/loongson/serial.h +++ /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 . - */ - -#ifndef GRUB_MACHINE_SERIAL_HEADER -#define GRUB_MACHINE_SERIAL_HEADER 1 - -#define GRUB_MACHINE_SERIAL_PORT0_DIVISOR_115200 2 -#define GRUB_MACHINE_SERIAL_PORT2_DIVISOR_115200 1 -#define GRUB_MACHINE_SERIAL_PORT0 0xbff003f8 -#define GRUB_MACHINE_SERIAL_PORT1 0xbfd003f8 -#define GRUB_MACHINE_SERIAL_PORT2 0xbfd002f8 - -#ifndef ASM_FILE -#define GRUB_MACHINE_SERIAL_PORTS { GRUB_MACHINE_SERIAL_PORT0, GRUB_MACHINE_SERIAL_PORT1, GRUB_MACHINE_SERIAL_PORT2 } -#else -#endif - -#endif diff --git a/include/grub/mips/memory.h b/include/grub/mips/memory.h deleted file mode 100644 index a85bbe752..000000000 --- a/include/grub/mips/memory.h +++ /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 . - */ - -#ifndef GRUB_MEMORY_CPU_HEADER -#define GRUB_MEMORY_CPU_HEADER 1 - -#ifndef ASM_FILE -#include -#include -#include -#endif - -#define GRUB_ARCH_LOWMEMVSTART 0x80000000 -#define GRUB_ARCH_LOWMEMPSTART 0x00000000 -#define GRUB_ARCH_LOWMEMMAXSIZE 0x10000000 -#define GRUB_ARCH_HIGHMEMPSTART 0x10000000 - -#ifndef ASM_FILE - -typedef grub_addr_t grub_phys_addr_t; - -static inline grub_phys_addr_t -grub_vtop (void *a) -{ - return ((grub_phys_addr_t) a) & 0x1fffffff; -} - -static inline void * -grub_map_memory (grub_phys_addr_t a, grub_size_t size __attribute__ ((unused))) -{ - return (void *) (a | 0x80000000); -} - -static inline void -grub_unmap_memory (void *a __attribute__ ((unused)), - grub_size_t size __attribute__ ((unused))) -{ -} - -grub_uint64_t grub_mmap_get_lower (void); -grub_uint64_t grub_mmap_get_upper (void); - -#endif - -#endif diff --git a/include/grub/mips/mips.h b/include/grub/mips/mips.h deleted file mode 100644 index bafb2bde0..000000000 --- a/include/grub/mips/mips.h +++ /dev/null @@ -1,30 +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 . - */ - -#ifndef GRUB_REGISTERS_CPU_HEADER -#define GRUB_REGISTERS_CPU_HEADER 1 - -#ifdef ASM_FILE -#define GRUB_CPU_REGISTER_WRAP(x) x -#else -#define GRUB_CPU_REGISTER_WRAP(x) #x -#endif - -#define GRUB_CPU_MIPS_COP0_TIMER_COUNT GRUB_CPU_REGISTER_WRAP($9) - -#endif diff --git a/include/grub/mips/multiboot.h b/include/grub/mips/multiboot.h deleted file mode 100644 index cdfb41e31..000000000 --- a/include/grub/mips/multiboot.h +++ /dev/null @@ -1,31 +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 . - */ - -#ifndef GRUB_MULTIBOOT_CPU_HEADER -#define GRUB_MULTIBOOT_CPU_HEADER 1 - -#define MULTIBOOT2_INITIAL_STATE { .gpr[4] = MULTIBOOT2_BOOTLOADER_MAGIC, \ - .jumpreg = 1 } -#define MULTIBOOT_ENTRY_REGISTER gpr[1] -#define MULTIBOOT_MBI_REGISTER gpr[5] -#define MULTIBOOT2_ARCHITECTURE_CURRENT MULTIBOOT2_ARCHITECTURE_MIPS32 - -#define MULTIBOOT_ELF32_MACHINE EM_MIPS -#define MULTIBOOT_ELF64_MACHINE EM_MIPS - -#endif /* ! GRUB_MULTIBOOT_CPU_HEADER */ diff --git a/include/grub/x86_64/efi/boot.h b/include/grub/mips/qemu-mips/boot.h similarity index 100% rename from include/grub/x86_64/efi/boot.h rename to include/grub/mips/qemu-mips/boot.h diff --git a/include/grub/mips/loongson/kernel.h b/include/grub/mips/qemu-mips/kernel.h similarity index 79% rename from include/grub/mips/loongson/kernel.h rename to include/grub/mips/qemu-mips/kernel.h index 05871910b..dbf74c1b2 100644 --- a/include/grub/mips/loongson/kernel.h +++ b/include/grub/mips/qemu-mips/kernel.h @@ -22,14 +22,14 @@ #include #include -#define GRUB_ARCH_MACHINE_YEELOONG 0 -#define GRUB_ARCH_MACHINE_FULOONG2F 1 -#define GRUB_ARCH_MACHINE_FULOONG2E 2 -#define GRUB_ARCH_MACHINE_YEELOONG_3A 3 - #ifndef ASM_FILE -extern grub_uint32_t EXPORT_VAR (grub_arch_machine) __attribute__ ((section(".text"))); +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 diff --git a/include/grub/mips/qemu_mips/loader.h b/include/grub/mips/qemu-mips/loader.h similarity index 100% rename from include/grub/mips/qemu_mips/loader.h rename to include/grub/mips/qemu-mips/loader.h diff --git a/include/grub/mips/qemu_mips/memory.h b/include/grub/mips/qemu-mips/memory.h similarity index 82% rename from include/grub/mips/qemu_mips/memory.h rename to include/grub/mips/qemu-mips/memory.h index 29b04a5ad..87e68674e 100644 --- a/include/grub/mips/qemu_mips/memory.h +++ b/include/grub/mips/qemu-mips/memory.h @@ -28,9 +28,13 @@ #define GRUB_MACHINE_MEMORY_STACK_HIGH 0x80f00000 #define GRUB_MACHINE_MEMORY_USABLE 0x81000000 -#ifndef ASM_FILE +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 -extern grub_uint32_t grub_arch_memsize __attribute__ ((section(".text"))); +#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)), diff --git a/include/grub/mips/qemu_mips/serial.h b/include/grub/mips/qemu-mips/serial.h similarity index 93% rename from include/grub/mips/qemu_mips/serial.h rename to include/grub/mips/qemu-mips/serial.h index c4d8d6326..1f8ce0804 100644 --- a/include/grub/mips/qemu_mips/serial.h +++ b/include/grub/mips/qemu-mips/serial.h @@ -19,6 +19,6 @@ #ifndef GRUB_MACHINE_SERIAL_HEADER #define GRUB_MACHINE_SERIAL_HEADER 1 -#define GRUB_MACHINE_SERIAL_PORTS { 0xb40003f8 } +#define GRUB_MACHINE_SERIAL_PORTS { 0x140003f8 } -#endif +#endif diff --git a/include/grub/mips/qemu-mips/time.h b/include/grub/mips/qemu-mips/time.h new file mode 100644 index 000000000..a73f64dea --- /dev/null +++ b/include/grub/mips/qemu-mips/time.h @@ -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 . + */ + +#ifndef KERNEL_MACHINE_TIME_HEADER +#define KERNEL_MACHINE_TIME_HEADER 1 + +#include + +#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 index 67b0a4c43..838ef832f 100644 --- a/include/grub/mips/relocator.h +++ b/include/grub/mips/relocator.h @@ -21,7 +21,6 @@ #include #include -#include struct grub_relocator32_state { @@ -31,8 +30,10 @@ struct grub_relocator32_state int jumpreg; }; -grub_err_t -grub_relocator32_boot (struct grub_relocator *rel, - struct grub_relocator32_state state); +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 index f8f6517ac..5e5985586 100644 --- a/include/grub/mips/setjmp.h +++ b/include/grub/mips/setjmp.h @@ -19,9 +19,9 @@ #ifndef GRUB_SETJMP_CPU_HEADER #define GRUB_SETJMP_CPU_HEADER 1 -typedef grub_uint64_t grub_jmp_buf[12]; +typedef unsigned long grub_jmp_buf[11]; -int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; +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 index f5c891a3a..e69de29bb 100644 --- a/include/grub/mips/time.h +++ b/include/grub/mips/time.h @@ -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 . - */ - -#ifndef KERNEL_CPU_TIME_HEADER -#define KERNEL_CPU_TIME_HEADER 1 - -#ifndef GRUB_UTIL - -#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_cpuclock) __attribute__ ((section(".text"))); -#endif - -static inline void -grub_cpu_idle(void) -{ -} - -#endif diff --git a/include/grub/mips/qemu_mips/at_keyboard.h b/include/grub/mips/yeeloong/at_keyboard.h similarity index 91% rename from include/grub/mips/qemu_mips/at_keyboard.h rename to include/grub/mips/yeeloong/at_keyboard.h index 37cc625d1..f279ac86d 100644 --- a/include/grub/mips/qemu_mips/at_keyboard.h +++ b/include/grub/mips/yeeloong/at_keyboard.h @@ -19,7 +19,7 @@ #ifndef GRUB_MACHINE_AT_KEYBOARD_HEADER #define GRUB_MACHINE_AT_KEYBOARD_HEADER 1 -#define KEYBOARD_REG_DATA 0xb4000060 -#define KEYBOARD_REG_STATUS 0xb4000064 +#define KEYBOARD_REG_DATA 0xbfd00060 +#define KEYBOARD_REG_STATUS 0xbfd00064 #endif diff --git a/include/grub/boottime.h b/include/grub/mips/yeeloong/boot.h similarity index 100% rename from include/grub/boottime.h rename to include/grub/mips/yeeloong/boot.h diff --git a/include/grub/mips/loongson/cmos.h b/include/grub/mips/yeeloong/cmos.h similarity index 92% rename from include/grub/mips/loongson/cmos.h rename to include/grub/mips/yeeloong/cmos.h index 0c8cc8dde..f2a32d736 100644 --- a/include/grub/mips/loongson/cmos.h +++ b/include/grub/mips/yeeloong/cmos.h @@ -24,7 +24,5 @@ #define GRUB_CMOS_ADDR_REG 0xbfd00070 #define GRUB_CMOS_DATA_REG 0xbfd00071 -#define GRUB_CMOS_ADDR_REG_HI 0xbfd00072 -#define GRUB_CMOS_DATA_REG_HI 0xbfd00073 #endif /* GRUB_CPU_CMOS_H */ diff --git a/include/grub/mips/qemu_mips/kernel.h b/include/grub/mips/yeeloong/kernel.h similarity index 89% rename from include/grub/mips/qemu_mips/kernel.h rename to include/grub/mips/yeeloong/kernel.h index 8b8b0149e..230455dbf 100644 --- a/include/grub/mips/qemu_mips/kernel.h +++ b/include/grub/mips/yeeloong/kernel.h @@ -20,10 +20,12 @@ #define GRUB_KERNEL_MACHINE_HEADER 1 #include +#include #ifndef ASM_FILE -void grub_qemu_init_cirrus (void); +void EXPORT_FUNC (grub_reboot) (void); +void EXPORT_FUNC (grub_halt) (void); #endif diff --git a/include/grub/i386/xen/kernel.h b/include/grub/mips/yeeloong/loader.h similarity index 100% rename from include/grub/i386/xen/kernel.h rename to include/grub/mips/yeeloong/loader.h diff --git a/include/grub/mips/loongson/memory.h b/include/grub/mips/yeeloong/memory.h similarity index 63% rename from include/grub/mips/loongson/memory.h rename to include/grub/mips/yeeloong/memory.h index aa41fa626..922db2404 100644 --- a/include/grub/mips/loongson/memory.h +++ b/include/grub/mips/yeeloong/memory.h @@ -26,8 +26,22 @@ #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)), @@ -43,8 +57,11 @@ grub_machine_mmap_unregister (int handle __attribute__ ((unused))) return GRUB_ERR_NONE; } -extern grub_uint32_t EXPORT_VAR (grub_arch_memsize) __attribute__ ((section(".text"))); -extern grub_uint32_t EXPORT_VAR (grub_arch_highmemsize) __attribute__ ((section(".text"))); +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 diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h new file mode 100644 index 000000000..c7bd31d4f --- /dev/null +++ b/include/grub/mips/yeeloong/pci.h @@ -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 . + */ + +#ifndef GRUB_MACHINE_PCI_H +#define GRUB_MACHINE_PCI_H 1 + +#include +#include + +#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/qemu_mips/console.h b/include/grub/mips/yeeloong/serial.h similarity index 80% rename from include/grub/mips/qemu_mips/console.h rename to include/grub/mips/yeeloong/serial.h index 2ffef7300..9390ea18a 100644 --- a/include/grub/mips/qemu_mips/console.h +++ b/include/grub/mips/yeeloong/serial.h @@ -16,10 +16,9 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_MACHINE_CONSOLE_HEADER -#define GRUB_MACHINE_CONSOLE_HEADER 1 +#ifndef GRUB_MACHINE_SERIAL_HEADER +#define GRUB_MACHINE_SERIAL_HEADER 1 -void grub_vga_text_init (void); -void grub_vga_text_fini (void); +#define GRUB_MACHINE_SERIAL_PORTS { 0xbff003f8 } -#endif /* ! GRUB_MACHINE_CONSOLE_HEADER */ +#endif diff --git a/include/grub/lockdown.h b/include/grub/mips/yeeloong/time.h similarity index 61% rename from include/grub/lockdown.h rename to include/grub/mips/yeeloong/time.h index 40531fa82..7f468bf12 100644 --- a/include/grub/lockdown.h +++ b/include/grub/mips/yeeloong/time.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2020 Free Software Foundation, Inc. + * 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 @@ -16,29 +16,22 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_LOCKDOWN_H -#define GRUB_LOCKDOWN_H 1 +#ifndef KERNEL_MACHINE_TIME_HEADER +#define KERNEL_MACHINE_TIME_HEADER 1 #include -#define GRUB_LOCKDOWN_DISABLED 0 -#define GRUB_LOCKDOWN_ENABLED 1 +#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); -#ifdef GRUB_MACHINE_EFI -extern void -EXPORT_FUNC (grub_lockdown) (void); -extern int -EXPORT_FUNC (grub_is_lockdown) (void); -#else static inline void -grub_lockdown (void) +grub_cpu_idle(void) { } -static inline int -grub_is_lockdown (void) -{ - return GRUB_LOCKDOWN_DISABLED; -} -#endif -#endif /* ! GRUB_LOCKDOWN_H */ +#endif /* ! KERNEL_MACHINE_TIME_HEADER */ diff --git a/include/grub/misc.h b/include/grub/misc.h index e087e7b3e..dcbafba87 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -24,98 +24,79 @@ #include #include #include -#include -#include + +/* 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 ALIGN_UP_OVERHEAD(addr, align) ((-(addr)) & ((typeof (addr)) (align) - 1)) -#define ALIGN_DOWN(addr, align) \ - ((addr) & ~((typeof (addr)) (align) - 1)) + ((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, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__) +#define grub_dprintf(condition, fmt, args...) grub_real_dprintf(__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_strncpy (char *dest, const char *src, int c) +grub_strcat (char *dest, const char *src) { char *p = dest; - while ((*p++ = *src++) != '\0' && --c) - ; + while (*p) + p++; + + while ((*p = *src) != '\0') + { + p++; + src++; + } return dest; } static inline char * -grub_stpcpy (char *dest, const char *src) +grub_strncat (char *dest, const char *src, int c) { - char *d = dest; - const char *s = src; + char *p = dest; - do - *d++ = *s; - while (*s++ != '\0'); + while (*p) + p++; - return d - 1; + while ((*p = *src) != '\0' && c--) + { + p++; + src++; + } + + *p = '\0'; + + return dest; } -static inline grub_size_t -grub_strlcpy (char *dest, const char *src, grub_size_t size) -{ - char *d = dest; - grub_size_t res = 0; - /* - * We do not subtract one from size here to avoid dealing with underflowing - * the value, which is why to_copy is always checked to be greater than one - * throughout this function. - */ - grub_size_t to_copy = size; - - /* Copy size - 1 bytes to dest. */ - if (to_copy > 1) - while ((*d++ = *src++) != '\0' && ++res && --to_copy > 1) - ; - - /* - * NUL terminate if size != 0. The previous step may have copied a NUL byte - * if it reached the end of the string, but we know dest[size - 1] must always - * be a NUL byte. - */ - if (size != 0) - dest[size - 1] = '\0'; - - /* If there is still space in dest, but are here, we reached the end of src. */ - if (to_copy > 1) - return res; - - /* - * If we haven't reached the end of the string, iterate through to determine - * the strings total length. - */ - while (*src++ != '\0' && ++res) - ; - - return res; -} - -/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ -static inline void * -grub_memcpy (void *dest, const void *src, grub_size_t n) -{ - return grub_memmove (dest, src, n); -} - -#if defined(__x86_64__) && !defined (GRUB_UTIL) -#if defined (__MINGW32__) || defined (__CYGWIN__) || defined (__MINGW64__) -#define GRUB_ASM_ATTR __attribute__ ((sysv_abi)) -#else -#define GRUB_ASM_ATTR -#endif +/* 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); @@ -125,60 +106,9 @@ 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); - -/* Copied from gnulib. - Written by Bruno Haible , 2005. */ -static inline 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 0; - 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 0; - if (*rhaystack != *rneedle) - /* Nothing in this round. */ - break; - } - } - } - } - else - return (char *) haystack; -} - +char *EXPORT_FUNC(grub_strstr) (const char *haystack, const char *needle); int EXPORT_FUNC(grub_isspace) (int c); - -static inline int -grub_isprint (int c) -{ - return (c >= ' ' && c <= '~'); -} +int EXPORT_FUNC(grub_isprint) (int c); static inline int grub_iscntrl (int c) @@ -192,18 +122,6 @@ grub_isalpha (int c) return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } -static inline int -grub_islower (int c) -{ - return (c >= 'a' && c <= 'z'); -} - -static inline int -grub_isupper (int c) -{ - return (c >= 'A' && c <= 'Z'); -} - static inline int grub_isgraph (int c) { @@ -216,12 +134,6 @@ grub_isdigit (int c) return (c >= '0' && c <= '9'); } -static inline int -grub_isxdigit (int c) -{ - return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); -} - static inline int grub_isalnum (int c) { @@ -251,16 +163,14 @@ grub_strcasecmp (const char *s1, const char *s2) { while (*s1 && *s2) { - if (grub_tolower ((grub_uint8_t) *s1) - != grub_tolower ((grub_uint8_t) *s2)) + if (grub_tolower (*s1) != grub_tolower (*s2)) break; s1++; s2++; } - return (int) grub_tolower ((grub_uint8_t) *s1) - - (int) grub_tolower ((grub_uint8_t) *s2); + return (int) grub_tolower (*s1) - (int) grub_tolower (*s2); } static inline int @@ -271,74 +181,25 @@ grub_strncasecmp (const char *s1, const char *s2, grub_size_t n) while (*s1 && *s2 && --n) { - if (grub_tolower ((grub_uint8_t) *s1) - != grub_tolower ((grub_uint8_t) *s2)) + if (grub_tolower (*s1) != grub_tolower (*s2)) break; s1++; s2++; } - return (int) grub_tolower ((grub_uint8_t) *s1) - - (int) grub_tolower ((grub_uint8_t) *s2); + return (int) grub_tolower (*s1) - (int) grub_tolower (*s2); } -/* - * Do a case insensitive compare of two UUID strings by ignoring all dashes. - * Note that the parameter n, is the number of significant characters to - * compare, where significant characters are any except the dash. - */ -static inline int -grub_uuidcasecmp (const char *uuid1, const char *uuid2, grub_size_t n) -{ - if (n == 0) - return 0; - while (*uuid1 && *uuid2 && --n) - { - /* Skip forward to non-dash on both UUIDs. */ - while ('-' == *uuid1) - ++uuid1; - - while ('-' == *uuid2) - ++uuid2; - - if (grub_tolower ((grub_uint8_t) *uuid1) != grub_tolower ((grub_uint8_t) *uuid2)) - break; - - uuid1++; - uuid2++; - } - - return (int) grub_tolower ((grub_uint8_t) *uuid1) - (int) grub_tolower ((grub_uint8_t) *uuid2); -} - -/* - * Note that these differ from the C standard's definitions of strtol, - * strtoul(), and strtoull() by the addition of two const qualifiers on the end - * pointer, which make the declaration match the *semantic* requirements of - * their behavior. This means that instead of: - * - * char *s = "1234 abcd"; - * char *end; - * unsigned long l; - * - * l = grub_strtoul(s, &end, 10); - * - * We must one of: - * - * const char *end; - * ... or ... - * l = grub_strtoul(s, (const char ** const)&end, 10); - */ -unsigned long EXPORT_FUNC(grub_strtoul) (const char * restrict str, const char ** const restrict end, int base); -unsigned long long EXPORT_FUNC(grub_strtoull) (const char * restrict str, const char ** const restrict end, int base); +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 * restrict str, const char ** const restrict end, int base) +grub_strtol (const char *str, char **end, int base) { int negative = 0; - unsigned long long magnitude; + unsigned long magnitude; while (*str && grub_isspace (*str)) str++; @@ -354,7 +215,7 @@ grub_strtol (const char * restrict str, const char ** const restrict end, int ba { if (magnitude > (unsigned long) GRUB_LONG_MAX + 1) { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + grub_error (GRUB_ERR_OUT_OF_RANGE, "negative overflow"); return GRUB_LONG_MIN; } return -((long) magnitude); @@ -363,125 +224,49 @@ grub_strtol (const char * restrict str, const char ** const restrict end, int ba { if (magnitude > GRUB_LONG_MAX) { - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + grub_error (GRUB_ERR_OUT_OF_RANGE, "positive overflow"); return GRUB_LONG_MAX; } return (long) magnitude; } } -char *EXPORT_FUNC(grub_strdup) (const char *s) WARN_UNUSED_RESULT; -char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n) WARN_UNUSED_RESULT; +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) WARN_UNUSED_RESULT; - -/* Replace all `ch' characters of `input' with `with' and copy the - result into `output'; return EOS address of `output'. */ -static inline char * -grub_strchrsub (char *output, const char *input, char ch, const char *with) -{ - while (*input) - { - if (*input == ch) - { - grub_strcpy (output, with); - output += grub_strlen (with); - input++; - continue; - } - *output++ = *input++; - } - *output = '\0'; - return output; -} - -extern void (*EXPORT_VAR (grub_xputs)) (const char *str); - -static inline int -grub_puts (const char *s) -{ - const char nl[2] = "\n"; - grub_xputs (s); - grub_xputs (nl); - - return 1; /* Cannot fail. */ -} - +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); -int EXPORT_FUNC(grub_debug_enabled) (const char *condition); void EXPORT_FUNC(grub_real_dprintf) (const char *file, const int line, const char *condition, - const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 4, 5))); -int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); -int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); + 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 (GNU_PRINTF, 3, 4))); + __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 (GNU_PRINTF, 1, 2))) WARN_UNUSED_RESULT; -char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args) WARN_UNUSED_RESULT; - + __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_uint64_t d, - grub_uint64_t *r); + grub_uint32_t d, grub_uint32_t *r); -extern bool EXPORT_FUNC(grub_is_cli_disabled) (void); -extern bool EXPORT_FUNC(grub_is_cli_need_auth) (void); -extern void EXPORT_FUNC(grub_cli_set_auth_needed) (void); - -/* Must match softdiv group in gentpl.py. */ -#if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \ - (defined(__riscv) && (__riscv_xlen == 32))) -#define GRUB_DIVISION_IN_SOFTWARE 1 -#else -#define GRUB_DIVISION_IN_SOFTWARE 0 +#ifdef NEED_ENABLE_EXECUTE_STACK +void EXPORT_FUNC(__enable_execute_stack) (void *addr); #endif -/* Some division functions need to be in kernel if compiler generates calls - to them. Otherwise we still need them for consistent tests but they go - into a separate module. */ -#if GRUB_DIVISION_IN_SOFTWARE -#define EXPORT_FUNC_IF_SOFTDIV EXPORT_FUNC -#else -#define EXPORT_FUNC_IF_SOFTDIV(x) x -#endif - -grub_int64_t -EXPORT_FUNC_IF_SOFTDIV(grub_divmod64s) (grub_int64_t n, - grub_int64_t d, - grub_int64_t *r); - -grub_uint32_t -EXPORT_FUNC_IF_SOFTDIV (grub_divmod32) (grub_uint32_t n, - grub_uint32_t d, - grub_uint32_t *r); - -grub_int32_t -EXPORT_FUNC_IF_SOFTDIV (grub_divmod32s) (grub_int32_t n, - grub_int32_t d, - grub_int32_t *r); - /* Inline functions. */ -static inline char * -grub_memchr (const void *p, int c, grub_size_t len) -{ - const char *s = (const char *) p; - const char *e = s + len; - - for (; s < e; s++) - if (*s == c) - return (char *) s; - - return 0; -} - - static inline unsigned int grub_abs (int x) { @@ -491,88 +276,31 @@ grub_abs (int x) 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. */ -#if defined (GRUB_MACHINE_EMU) || defined (GRUB_MACHINE_QEMU_MIPS) || \ - defined (GRUB_MACHINE_EFI) -void EXPORT_FUNC(grub_reboot) (void) __attribute__ ((noreturn)); -#else -void grub_reboot (void) __attribute__ ((noreturn)); -#endif +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 grub_halt (int no_apm) __attribute__ ((noreturn)); -#elif defined (__mips__) && !defined (GRUB_MACHINE_EMU) -void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn)); +void EXPORT_FUNC (grub_halt) (int no_apm); #else -void grub_halt (void) __attribute__ ((noreturn)); +void EXPORT_FUNC (grub_halt) (void); #endif -#ifdef GRUB_MACHINE_EMU -/* Flag to check if module loading is available. */ -extern const int EXPORT_VAR(grub_no_modules); -#else -#define grub_no_modules 0 -#endif - -static inline void -grub_error_save (struct grub_error_saved *save) -{ - grub_memcpy (save->errmsg, grub_errmsg, sizeof (save->errmsg)); - save->grub_errno = grub_errno; - grub_errno = GRUB_ERR_NONE; -} - -static inline void -grub_error_load (const struct grub_error_saved *save) -{ - grub_memcpy (grub_errmsg, save->errmsg, sizeof (grub_errmsg)); - grub_errno = save->grub_errno; -} - -/* - * grub_printf_fmt_checks() a fmt string for printf() against an expected - * format. It is intended for cases where the fmt string could come from - * an outside source and cannot be trusted. - * - * While expected fmt accepts a printf() format string it should be kept - * as simple as possible. The printf() format strings with positional - * parameters are NOT accepted, neither for fmt nor for fmt_expected. - * - * The fmt is accepted if it has equal or less arguments than fmt_expected - * and if the type of all arguments match. - * - * Returns GRUB_ERR_NONE if fmt is acceptable. - */ -grub_err_t EXPORT_FUNC (grub_printf_fmt_check) (const char *fmt, const char *fmt_expected); - -#if BOOT_TIME_STATS -struct grub_boot_time -{ - struct grub_boot_time *next; - grub_uint64_t tp; - const char *file; - int line; - char *msg; -}; - -extern struct grub_boot_time *EXPORT_VAR(grub_boot_time_head); - -void EXPORT_FUNC(grub_real_boot_time) (const char *file, - const int line, - const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 3, 4))); -#define grub_boot_time(...) grub_real_boot_time(GRUB_FILE, __LINE__, __VA_ARGS__) -#else -#define grub_boot_time(...) -#endif - -#define grub_max(a, b) (((a) > (b)) ? (a) : (b)) -#define grub_min(a, b) (((a) < (b)) ? (a) : (b)) - -#define grub_log2ull(n) (GRUB_TYPE_BITS (grub_uint64_t) - __builtin_clzll (n) - 1) - -grub_ssize_t -EXPORT_FUNC(grub_utf8_to_utf16_alloc) (const char *str8, grub_uint16_t **utf16_msg, grub_uint16_t **last_position); - #endif /* ! GRUB_MISC_HEADER */ diff --git a/include/grub/mm.h b/include/grub/mm.h index 51ec0b8f9..4caf80511 100644 --- a/include/grub/mm.h +++ b/include/grub/mm.h @@ -20,7 +20,6 @@ #ifndef GRUB_MM_H #define GRUB_MM_H 1 -#include #include #include #include @@ -29,98 +28,36 @@ # define NULL ((void *) 0) #endif -#define GRUB_MM_ADD_REGION_NONE 0 -#define GRUB_MM_ADD_REGION_CONSECUTIVE (1 << 0) - -/* - * Function used to request memory regions of `grub_size_t` bytes. The second - * parameter is a bitfield of `GRUB_MM_ADD_REGION` flags. - */ -typedef grub_err_t (*grub_mm_add_region_func_t) (grub_size_t, unsigned int); - -/* - * Set this function pointer to enable adding memory-regions at runtime in case - * a memory allocation cannot be satisfied with existing regions. - */ -#ifndef GRUB_MACHINE_EMU -extern grub_mm_add_region_func_t EXPORT_VAR(grub_mm_add_region_fn); -#endif - void grub_mm_init_region (void *addr, grub_size_t size); -void *EXPORT_FUNC(grub_calloc) (grub_size_t nmemb, 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); -#ifndef GRUB_MACHINE_EMU void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size); -#endif - -typedef grub_uint64_t grub_mem_attr_t; - -#define GRUB_MEM_ATTR_R ((grub_mem_attr_t) 0x0000000000000004) -#define GRUB_MEM_ATTR_W ((grub_mem_attr_t) 0x0000000000000002) -#define GRUB_MEM_ATTR_X ((grub_mem_attr_t) 0x0000000000000001) - -#ifdef GRUB_MACHINE_EFI -grub_err_t EXPORT_FUNC(grub_get_mem_attrs) (grub_addr_t addr, - grub_size_t size, - grub_mem_attr_t *attrs); -grub_err_t EXPORT_FUNC(grub_update_mem_attrs) (grub_addr_t addr, - grub_size_t size, - grub_mem_attr_t set_attrs, - grub_mem_attr_t clear_attrs); -#else /* !GRUB_MACHINE_EFI */ -static inline grub_err_t -grub_get_mem_attrs (grub_addr_t addr __attribute__((__unused__)), - grub_size_t size __attribute__((__unused__)), - grub_mem_attr_t *attrs) -{ - *attrs = GRUB_MEM_ATTR_R | GRUB_MEM_ATTR_W | GRUB_MEM_ATTR_X; - return GRUB_ERR_NONE; -} - -static inline grub_err_t -grub_update_mem_attrs (grub_addr_t addr __attribute__((__unused__)), - grub_size_t size __attribute__((__unused__)), - grub_mem_attr_t set_attrs __attribute__((__unused__)), - grub_mem_attr_t clear_attrs __attribute__((__unused__))) -{ - return GRUB_ERR_NONE; -} -#endif /* GRUB_MACHINE_EFI */ - -void grub_mm_check_real (const char *file, int line); -#define grub_mm_check() grub_mm_check_real (GRUB_FILE, __LINE__); /* For debugging. */ -#if defined(MM_DEBUG) && !defined(GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) +#if defined(MM_DEBUG) && !defined(GRUB_UTIL) /* Set this variable to 1 when you want to trace all memory function calls. */ extern int EXPORT_VAR(grub_mm_debug); -void EXPORT_FUNC(grub_mm_dump_free) (void); -void EXPORT_FUNC(grub_mm_dump) (unsigned lineno); - -#define grub_calloc(nmemb, size) \ - grub_debug_calloc (GRUB_FILE, __LINE__, nmemb, size) +void grub_mm_dump_free (void); +void grub_mm_dump (unsigned lineno); #define grub_malloc(size) \ - grub_debug_malloc (GRUB_FILE, __LINE__, size) + grub_debug_malloc (__FILE__, __LINE__, size) #define grub_zalloc(size) \ - grub_debug_zalloc (GRUB_FILE, __LINE__, size) + grub_debug_zalloc (__FILE__, __LINE__, size) #define grub_realloc(ptr,size) \ - grub_debug_realloc (GRUB_FILE, __LINE__, ptr, size) + grub_debug_realloc (__FILE__, __LINE__, ptr, size) #define grub_memalign(align,size) \ - grub_debug_memalign (GRUB_FILE, __LINE__, align, size) + grub_debug_memalign (__FILE__, __LINE__, align, size) #define grub_free(ptr) \ - grub_debug_free (GRUB_FILE, __LINE__, ptr) + grub_debug_free (__FILE__, __LINE__, ptr) -void *EXPORT_FUNC(grub_debug_calloc) (const char *file, int line, - grub_size_t nmemb, grub_size_t size); 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, diff --git a/include/grub/mm_private.h b/include/grub/mm_private.h deleted file mode 100644 index 96c2d816b..000000000 --- a/include/grub/mm_private.h +++ /dev/null @@ -1,115 +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 . - */ - -#ifndef GRUB_MM_PRIVATE_H -#define GRUB_MM_PRIVATE_H 1 - -#include -#include - -/* For context, see kern/mm.c */ - -/* Magic words. */ -#define GRUB_MM_FREE_MAGIC 0x2d3c2808 -#define GRUB_MM_ALLOC_MAGIC 0x6db08fa4 - -/* A header describing a block of memory - either allocated or free */ -typedef struct grub_mm_header -{ - /* - * The 'next' free block in this region's circular free list. - * Only meaningful if the block is free. - */ - struct grub_mm_header *next; - /* The block size, not in bytes but the number of cells of - * GRUB_MM_ALIGN bytes. Includes the header cell. - */ - grub_size_t size; - /* either free or alloc magic, depending on the block type. */ - grub_size_t magic; - /* pad to cell size: see the top of kern/mm.c. */ -#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) - -/* A region from which we can make allocations. */ -typedef struct grub_mm_region -{ - /* The first free block in this region. */ - struct grub_mm_header *first; - - /* - * The next region in the linked list of regions. Regions are initially - * sorted in order of increasing size, but can grow, in which case the - * ordering may not be preserved. - */ - struct grub_mm_region *next; - - /* - * A grub_mm_region will always be aligned to cell size. The pre-size is - * the number of bytes we were given but had to skip in order to get that - * alignment. - */ - grub_size_t pre_size; - - /* - * Likewise, the post-size is the number of bytes we wasted at the end - * of the allocation because it wasn't a multiple of GRUB_MM_ALIGN - */ - grub_size_t post_size; - - /* How many bytes are in this region? (free and allocated) */ - grub_size_t size; - - /* pad to a multiple of cell size */ - char padding[3 * GRUB_CPU_SIZEOF_VOID_P]; -} -*grub_mm_region_t; - -#ifndef GRUB_MACHINE_EMU -extern grub_mm_region_t EXPORT_VAR (grub_mm_base); -#endif - -static inline void -grub_mm_size_sanity_check (void) { - /* Ensure we preserve alignment when doing h = (grub_mm_header_t) (r + 1). */ - COMPILE_TIME_ASSERT ((sizeof (struct grub_mm_region) % - sizeof (struct grub_mm_header)) == 0); - - /* - * GRUB_MM_ALIGN is supposed to represent cell size, and a mm_header is - * supposed to be 1 cell. - */ - COMPILE_TIME_ASSERT (sizeof (struct grub_mm_header) == GRUB_MM_ALIGN); -} - -#endif diff --git a/include/grub/module_verifier.h b/include/grub/module_verifier.h deleted file mode 100644 index ba21c75e2..000000000 --- a/include/grub/module_verifier.h +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -#include - -#define GRUB_MODULE_VERIFY_SUPPORTS_REL 1 -#define GRUB_MODULE_VERIFY_SUPPORTS_RELA 2 - -struct grub_module_verifier_arch { - const char *name; - int voidp_sizeof; - int bigendian; - int machine; - int flags; - const int *supported_relocations; - const int *short_relocations; -}; - -void grub_module_verify64(const char * const filename, void *module_img, size_t module_size, const struct grub_module_verifier_arch *arch, const char **whitelist_empty); -void grub_module_verify32(const char * const filename, void *module_img, size_t module_size, const struct grub_module_verifier_arch *arch, const char **whitelist_empty); diff --git a/include/grub/msdos_partition.h b/include/grub/msdos_partition.h index fdc2904d3..273d8c95e 100644 --- a/include/grub/msdos_partition.h +++ b/include/grub/msdos_partition.h @@ -22,8 +22,6 @@ #include #include #include -#include -#include /* The signature. */ #define GRUB_PC_PARTITION_SIGNATURE 0xaa55 @@ -42,12 +40,9 @@ #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_PLAN9 0x39 -#define GRUB_PC_PARTITION_TYPE_LDM 0x42 #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_LINUX_SWAP 0x82 #define GRUB_PC_PARTITION_TYPE_EXT2FS 0x83 #define GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED 0x85 #define GRUB_PC_PARTITION_TYPE_VSTAFS 0x9e @@ -58,6 +53,75 @@ #define GRUB_PC_PARTITION_TYPE_GPT_DISK 0xee #define GRUB_PC_PARTITION_TYPE_LINUX_RAID 0xfd +/* Constants for BSD disk label. */ +#define GRUB_PC_PARTITION_BSD_LABEL_SECTOR 1 +#define GRUB_PC_PARTITION_BSD_LABEL_MAGIC 0x82564557 +#define GRUB_PC_PARTITION_BSD_MAX_ENTRIES 8 + +/* 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_msdos_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_msdos_partition_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; + struct grub_msdos_partition_bsd_entry entries[GRUB_PC_PARTITION_BSD_MAX_ENTRIES]; +} __attribute__ ((packed)); + /* The partition entry. */ struct grub_msdos_partition_entry { @@ -88,7 +152,7 @@ struct grub_msdos_partition_entry /* The length in sector units. */ grub_uint32_t length; -} GRUB_PACKED; +} __attribute__ ((packed)); /* The structure of MBR. */ struct grub_msdos_partition_mbr @@ -101,9 +165,26 @@ struct grub_msdos_partition_mbr /* The signature 0xaa55. */ grub_uint16_t signature; -} GRUB_PACKED; +} __attribute__ ((packed)); +struct grub_msdos_partition +{ + /* The DOS partition number. */ + int dos_part; + + /* The BSD partition number (a == 0). */ + int bsd_part; + + /* The DOS partition type. */ + int dos_type; + + /* The BSD partition type. */ + int bsd_type; + + /* The offset of the extended partition. */ + unsigned long ext_offset; +}; static inline int grub_msdos_partition_is_empty (int type) @@ -119,9 +200,12 @@ grub_msdos_partition_is_extended (int type) || type == GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED); } -grub_err_t -grub_partition_msdos_iterate (grub_disk_t disk, - grub_partition_iterate_hook_t hook, - void *hook_data); +static inline int +grub_msdos_partition_is_bsd (int type) +{ + return (type == GRUB_PC_PARTITION_TYPE_FREEBSD + || type == GRUB_PC_PARTITION_TYPE_OPENBSD + || type == GRUB_PC_PARTITION_TYPE_NETBSD); +} #endif /* ! GRUB_PC_PARTITION_HEADER */ diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h index d8847f753..665292e33 100644 --- a/include/grub/multiboot.h +++ b/include/grub/multiboot.h @@ -20,93 +20,31 @@ #ifndef GRUB_MULTIBOOT_HEADER #define GRUB_MULTIBOOT_HEADER 1 -#include - +#ifdef GRUB_USE_MULTIBOOT2 +#include +/* 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 +#endif #include #include -typedef enum - { - GRUB_MULTIBOOT_QUIRKS_NONE = 0, - GRUB_MULTIBOOT_QUIRK_BAD_KLUDGE = 1, - GRUB_MULTIBOOT_QUIRK_MODULES_AFTER_KERNEL = 2 - } grub_multiboot_quirks_t; -extern grub_multiboot_quirks_t grub_multiboot_quirks; - -extern struct grub_relocator *grub_multiboot_relocator; - void grub_multiboot (int argc, char *argv[]); void grub_module (int argc, char *argv[]); void grub_multiboot_set_accepts_video (int val); -grub_err_t grub_multiboot_make_mbi (grub_uint32_t *target); + +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); -void -grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize, - unsigned shndx, void *data); - -grub_uint32_t grub_multiboot_get_mmap_count (void); -grub_err_t grub_multiboot_set_video_mode (void); - -/* FIXME: support coreboot as well. */ -#if defined (GRUB_MACHINE_PCBIOS) -#define GRUB_MACHINE_HAS_VBE 1 -#else -#define GRUB_MACHINE_HAS_VBE 0 -#endif - -#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) -#define GRUB_MACHINE_HAS_VGA_TEXT 1 -#else -#define GRUB_MACHINE_HAS_VGA_TEXT 0 -#endif - -#if defined (GRUB_MACHINE_EFI) || defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) -#define GRUB_MACHINE_HAS_ACPI 1 -#else -#define GRUB_MACHINE_HAS_ACPI 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, const char *filename); - -struct mbi_load_data -{ - grub_file_t file; - const char *filename; - void *buffer; - unsigned int mbi_ver; - int relocatable; - grub_uint32_t min_addr; - grub_uint32_t max_addr; - grub_size_t align; - grub_uint32_t preference; - grub_uint32_t link_base_addr; - grub_uint32_t load_base_addr; - int avoid_efi_boot_services; -}; -typedef struct mbi_load_data mbi_load_data_t; - -/* Load ELF32 or ELF64. */ -grub_err_t -grub_multiboot_load_elf (mbi_load_data_t *mld); - -extern grub_size_t grub_multiboot_pure_size; -extern grub_size_t grub_multiboot_alloc_mbi; -extern grub_uint32_t grub_multiboot_payload_eip; #endif /* ! GRUB_MULTIBOOT_HEADER */ diff --git a/include/grub/multiboot2.h b/include/grub/multiboot2.h deleted file mode 100644 index b90aa6989..000000000 --- a/include/grub/multiboot2.h +++ /dev/null @@ -1,104 +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 . - */ - -#ifndef GRUB_MULTIBOOT2_HEADER -#define GRUB_MULTIBOOT2_HEADER 1 - -#include - -#include - -#include -#include - -extern struct grub_relocator *grub_multiboot2_relocator; - -void grub_multiboot2 (int argc, char *argv[]); -void grub_module2 (int argc, char *argv[]); - -void grub_multiboot2_set_accepts_video (int val); -grub_err_t grub_multiboot2_make_mbi (grub_uint32_t *target); -void grub_multiboot2_free_mbi (void); -grub_err_t grub_multiboot2_init_mbi (int argc, char *argv[]); -grub_err_t grub_multiboot2_add_module (grub_addr_t start, grub_size_t size, - int argc, char *argv[]); -void grub_multiboot2_set_bootdev (void); -void -grub_multiboot2_add_elfsyms (grub_size_t num, grub_size_t entsize, - unsigned shndx, void *data); - -grub_uint32_t grub_multiboot2_get_mmap_count (void); -grub_err_t grub_multiboot2_set_video_mode (void); - -/* FIXME: support coreboot as well. */ -#if defined (GRUB_MACHINE_PCBIOS) -#define GRUB_MACHINE_HAS_VBE 1 -#else -#define GRUB_MACHINE_HAS_VBE 0 -#endif - -#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) -#define GRUB_MACHINE_HAS_VGA_TEXT 1 -#else -#define GRUB_MACHINE_HAS_VGA_TEXT 0 -#endif - -#if defined (GRUB_MACHINE_EFI) || defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) -#define GRUB_MACHINE_HAS_ACPI 1 -#else -#define GRUB_MACHINE_HAS_ACPI 0 -#endif - -#define GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT 1 -#define GRUB_MULTIBOOT2_CONSOLE_FRAMEBUFFER 2 - -grub_err_t -grub_multiboot2_set_console (int console_type, int accepted_consoles, - int width, int height, int depth, - int console_required); -grub_err_t -grub_multiboot2_load (grub_file_t file, const char *filename); - -struct mbi_load_data -{ - grub_file_t file; - const char *filename; - void *buffer; - unsigned int mbi_ver; - int relocatable; - grub_uint32_t min_addr; - grub_uint32_t max_addr; - grub_size_t align; - grub_uint32_t preference; - grub_uint32_t link_base_addr; - grub_uint32_t load_base_addr; - int avoid_efi_boot_services; -}; -typedef struct mbi_load_data mbi_load_data_t; - -/* Load ELF32 or ELF64. */ -grub_err_t -grub_multiboot2_load_elf (mbi_load_data_t *mld); - -extern grub_size_t grub_multiboot2_pure_size; -extern grub_size_t grub_multiboot2_alloc_mbi; -extern grub_uint32_t grub_multiboot2_payload_eip; - - -#endif /* ! GRUB_MULTIBOOT_HEADER */ diff --git a/include/grub/net.h b/include/grub/net.h index 58a4f83fc..c6d71d5b6 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. + * 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 @@ -19,565 +19,54 @@ #ifndef GRUB_NET_HEADER #define GRUB_NET_HEADER 1 -#include +#include #include -#include -#include -#include -#include -#include +#include -enum - { - GRUB_NET_MAX_LINK_HEADER_SIZE = 64, - GRUB_NET_UDP_HEADER_SIZE = 8, - GRUB_NET_TCP_HEADER_SIZE = 20, - GRUB_NET_OUR_IPV4_HEADER_SIZE = 20, - GRUB_NET_OUR_IPV6_HEADER_SIZE = 40, - GRUB_NET_OUR_MAX_IP_HEADER_SIZE = 40, - GRUB_NET_TCP_RESERVE_SIZE = GRUB_NET_TCP_HEADER_SIZE - + GRUB_NET_OUR_IPV4_HEADER_SIZE - + GRUB_NET_MAX_LINK_HEADER_SIZE - }; +struct grub_net; -typedef enum grub_link_level_protocol_id +struct grub_net_dev { - GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET -} grub_link_level_protocol_id_t; - -typedef struct grub_net_link_level_address -{ - grub_link_level_protocol_id_t type; - union - { - grub_uint8_t mac[6]; - }; -} grub_net_link_level_address_t; - -typedef enum grub_net_interface_flags - { - GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE = 1, - GRUB_NET_INTERFACE_ADDRESS_IMMUTABLE = 2, - GRUB_NET_INTERFACE_PERMANENT = 4 - } grub_net_interface_flags_t; - -typedef enum grub_net_card_flags - { - GRUB_NET_CARD_HWADDRESS_IMMUTABLE = 1, - GRUB_NET_CARD_NO_MANUAL_INTERFACES = 2, - GRUB_NET_CARD_NO_CLOSE_ON_FINI_HW = 4 - } grub_net_card_flags_t; - -struct grub_net_card; - -struct grub_net_card_driver -{ - struct grub_net_card_driver *next; - struct grub_net_card_driver **prev; + /* The device name. */ const char *name; - grub_err_t (*open) (struct grub_net_card *dev); - void (*close) (struct grub_net_card *dev); - grub_err_t (*send) (struct grub_net_card *dev, - struct grub_net_buff *buf); - struct grub_net_buff * (*recv) (struct grub_net_card *dev); + + /* 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; -typedef struct grub_net_packet +struct grub_fs; + +struct grub_net { - struct grub_net_packet *next; - struct grub_net_packet *prev; - struct grub_net_packets *up; - struct grub_net_buff *nb; -} grub_net_packet_t; - -typedef struct grub_net_packets -{ - grub_net_packet_t *first; - grub_net_packet_t *last; - grub_size_t count; -} grub_net_packets_t; - -#ifdef GRUB_MACHINE_EFI -#include -#endif - -struct grub_net_slaac_mac_list -{ - struct grub_net_slaac_mac_list *next; - struct grub_net_slaac_mac_list **prev; - grub_net_link_level_address_t address; - int slaac_counter; - char *name; -}; - -struct grub_net_link_layer_entry; - -struct grub_net_card -{ - struct grub_net_card *next; - struct grub_net_card **prev; + /* The net name. */ const char *name; - struct grub_net_card_driver *driver; - grub_net_link_level_address_t default_address; - grub_net_card_flags_t flags; - int num_ifaces; - int opened; - unsigned idle_poll_delay_ms; - grub_uint64_t last_poll; - grub_size_t mtu; - struct grub_net_slaac_mac_list *slaac_list; - grub_ssize_t new_ll_entry; - struct grub_net_link_layer_entry *link_layer_table; - void *txbuf; - void *rcvbuf; - grub_size_t rcvbufsize; - grub_size_t txbufsize; - int txbusy; - union - { -#ifdef GRUB_MACHINE_EFI - struct - { - struct grub_efi_simple_network *efi_net; - grub_efi_handle_t efi_handle; - grub_size_t last_pkt_size; - }; -#endif - void *data; - int data_num; - }; -}; -struct grub_net_network_level_interface; + /* The underlying disk device. */ + grub_net_dev_t dev; -typedef enum grub_network_level_protocol_id -{ - GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV, - GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4, - GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6 -} grub_network_level_protocol_id_t; + /* The binding filesystem. */ + struct grub_fs *fs; -typedef enum -{ - DNS_OPTION_IPV4, - DNS_OPTION_IPV6, - DNS_OPTION_PREFER_IPV4, - DNS_OPTION_PREFER_IPV6 -} grub_dns_option_t; + /* FIXME: More data would be required, such as an IP address, a mask, + a gateway, etc. */ -typedef struct grub_net_network_level_address -{ - grub_network_level_protocol_id_t type; - union - { - grub_uint32_t ipv4; - grub_uint64_t ipv6[2]; - }; - grub_dns_option_t option; -} grub_net_network_level_address_t; - -typedef struct grub_net_network_level_netaddress -{ - grub_network_level_protocol_id_t type; - union - { - struct { - grub_uint32_t base; - int masksize; - } ipv4; - struct { - grub_uint64_t base[2]; - int masksize; - } ipv6; - }; -} grub_net_network_level_netaddress_t; - -struct grub_net_route -{ - struct grub_net_route *next; - struct grub_net_route **prev; - grub_net_network_level_netaddress_t target; - char *name; - struct grub_net_network_level_protocol *prot; - int is_gateway; - struct grub_net_network_level_interface *interface; - grub_net_network_level_address_t gw; -}; - -#define FOR_PACKETS(cont,var) for (var = (cont).first; var; var = var->next) - -static inline grub_err_t -grub_net_put_packet (grub_net_packets_t *pkts, struct grub_net_buff *nb) -{ - struct grub_net_packet *n; - - n = grub_malloc (sizeof (*n)); - if (!n) - return grub_errno; - - n->nb = nb; - n->next = NULL; - n->prev = NULL; - n->up = pkts; - if (pkts->first) - { - pkts->last->next = n; - pkts->last = n; - n->prev = pkts->last; - } - else - pkts->first = pkts->last = n; - - pkts->count++; - - return GRUB_ERR_NONE; -} - -static inline void -grub_net_remove_packet (grub_net_packet_t *pkt) -{ - pkt->up->count--; - - if (pkt->prev) - pkt->prev->next = pkt->next; - else - pkt->up->first = pkt->next; - if (pkt->next) - pkt->next->prev = pkt->prev; - else - pkt->up->last = pkt->prev; - grub_free (pkt); -} - -typedef struct grub_net_app_protocol *grub_net_app_level_t; - -typedef struct grub_net_socket *grub_net_socket_t; - -struct grub_net_app_protocol -{ - struct grub_net_app_protocol *next; - struct grub_net_app_protocol **prev; - const char *name; - grub_err_t (*dir) (grub_device_t device, const char *path, - int (*hook) (const char *filename, - const struct grub_dirhook_info *info)); - grub_err_t (*open) (struct grub_file *file, const char *filename); - grub_err_t (*seek) (struct grub_file *file, grub_off_t off); - grub_err_t (*close) (struct grub_file *file); - grub_err_t (*packets_pulled) (struct grub_file *file); -}; - -typedef struct grub_net -{ - char *server; - char *name; - grub_uint16_t port; - grub_net_app_level_t protocol; - grub_net_packets_t packs; - grub_off_t offset; - grub_fs_t fs; - int eof; - int stall; - int broken; -} *grub_net_t; - -extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); - -struct grub_net_network_level_interface -{ - struct grub_net_network_level_interface *next; - struct grub_net_network_level_interface **prev; - char *name; - struct grub_net_card *card; - grub_net_network_level_address_t address; - grub_net_link_level_address_t hwaddress; - grub_net_interface_flags_t flags; - struct grub_net_bootp_packet *dhcp_ack; - grub_size_t dhcp_acklen; - grub_uint16_t vlantag; - grub_uint32_t xid; /* DHCPv4 transaction id */ - grub_uint32_t srv_id; /* DHCPv4 server_identifier */ - grub_uint32_t my_ip; /* DHCPv4 offered IP address */ - unsigned dhcp_tmo_left; /* DHCPv4 running retransmission timeout */ - unsigned dhcp_tmo; /* DHCPv4 current retransmission timeout */ + /* Device-specific data. */ void *data; }; +typedef struct grub_net *grub_net_t; -struct grub_net_session; +/* FIXME: How to abstract networks? More consideration is necessary. */ -struct grub_net_session_level_protocol -{ - void (*close) (struct grub_net_session *session); - grub_ssize_t (*recv) (struct grub_net_session *session, void *buf, - grub_size_t size); - grub_err_t (*send) (struct grub_net_session *session, void *buf, - grub_size_t size); -}; - -struct grub_net_session -{ - struct grub_net_session_level_protocol *protocol; - void *data; -}; - -static inline void -grub_net_session_close (struct grub_net_session *session) -{ - session->protocol->close (session); -} - -static inline grub_err_t -grub_net_session_send (struct grub_net_session *session, void *buf, - grub_size_t size) -{ - return session->protocol->send (session, buf, size); -} - -static inline grub_ssize_t -grub_net_session_recv (struct grub_net_session *session, void *buf, - grub_size_t size) -{ - return session->protocol->recv (session, buf, size); -} - -struct grub_net_network_level_interface * -grub_net_add_addr (const char *name, - struct grub_net_card *card, - const grub_net_network_level_address_t *addr, - const grub_net_link_level_address_t *hwaddress, - grub_net_interface_flags_t flags); - -extern struct grub_net_network_level_interface *grub_net_network_level_interfaces; -#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) -#define FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE(var,next) for (var = grub_net_network_level_interfaces, next = (var ? var->next : 0); var; var = next, next = (var ? var->next : 0)) - - -extern grub_net_app_level_t grub_net_app_level_list; - -#ifndef GRUB_LST_GENERATOR -static inline void -grub_net_app_level_register (grub_net_app_level_t proto) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_net_app_level_list), - GRUB_AS_LIST (proto)); -} -#endif - -static inline void -grub_net_app_level_unregister (grub_net_app_level_t proto) -{ - grub_list_remove (GRUB_AS_LIST (proto)); -} - -#define FOR_NET_APP_LEVEL(var) FOR_LIST_ELEMENTS((var), \ - (grub_net_app_level_list)) - -extern struct grub_net_card *grub_net_cards; - -static inline void -grub_net_card_register (struct grub_net_card *card) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_net_cards), - GRUB_AS_LIST (card)); -} - -void -grub_net_card_unregister (struct grub_net_card *card); - -#define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next) -#define FOR_NET_CARDS_SAFE(var, next) for (var = grub_net_cards, next = (var ? var->next : 0); var; var = next, next = (var ? var->next : 0)) - - -extern struct grub_net_route *grub_net_routes; - -static inline void -grub_net_route_register (struct grub_net_route *route) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_net_routes), - GRUB_AS_LIST (route)); -} - -#define FOR_NET_ROUTES(var) for (var = grub_net_routes; var; var = var->next) -struct grub_net_session * -grub_net_open_tcp (char *address, grub_uint16_t port); - -grub_err_t -grub_net_resolve_address (const char *name, - grub_net_network_level_address_t *addr); - -grub_err_t -grub_net_resolve_net_address (const char *name, - grub_net_network_level_netaddress_t *addr); - -grub_err_t -grub_net_route_address (grub_net_network_level_address_t addr, - grub_net_network_level_address_t *gateway, - struct grub_net_network_level_interface **interf); - - -grub_err_t -grub_net_add_route (const char *name, - grub_net_network_level_netaddress_t target, - struct grub_net_network_level_interface *inter); - -grub_err_t -grub_net_add_route_gw (const char *name, - grub_net_network_level_netaddress_t target, - grub_net_network_level_address_t gw, - struct grub_net_network_level_interface *inter); - - -#define GRUB_NET_BOOTP_MAC_ADDR_LEN 16 - -typedef grub_uint8_t grub_net_bootp_mac_addr_t[GRUB_NET_BOOTP_MAC_ADDR_LEN]; - -struct grub_net_bootp_packet -{ - 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_net_bootp_mac_addr_t mac_addr; - char server_name[64]; - char boot_file[128]; - grub_uint8_t vendor[0]; -} GRUB_PACKED; - -#define GRUB_NET_BOOTP_RFC1048_MAGIC_0 0x63 -#define GRUB_NET_BOOTP_RFC1048_MAGIC_1 0x82 -#define GRUB_NET_BOOTP_RFC1048_MAGIC_2 0x53 -#define GRUB_NET_BOOTP_RFC1048_MAGIC_3 0x63 - -enum - { - GRUB_NET_BOOTP_PAD = 0, - GRUB_NET_BOOTP_NETMASK = 1, - GRUB_NET_BOOTP_ROUTER = 3, - GRUB_NET_BOOTP_DNS = 6, - GRUB_NET_BOOTP_HOSTNAME = 12, - GRUB_NET_BOOTP_DOMAIN = 15, - GRUB_NET_BOOTP_ROOT_PATH = 17, - GRUB_NET_BOOTP_EXTENSIONS_PATH = 18, - GRUB_NET_DHCP_REQUESTED_IP_ADDRESS = 50, - GRUB_NET_DHCP_OVERLOAD = 52, - GRUB_NET_DHCP_MESSAGE_TYPE = 53, - GRUB_NET_DHCP_SERVER_IDENTIFIER = 54, - GRUB_NET_DHCP_PARAMETER_REQUEST_LIST = 55, - GRUB_NET_BOOTP_CLIENT_ID = 61, - GRUB_NET_DHCP_TFTP_SERVER_NAME = 66, - GRUB_NET_DHCP_BOOTFILE_NAME = 67, - GRUB_NET_BOOTP_CLIENT_UUID = 97, - GRUB_NET_BOOTP_END = 255 - }; - -struct grub_net_network_level_interface * -grub_net_configure_by_dhcp_ack (const char *name, - struct grub_net_card *card, - grub_net_interface_flags_t flags, - const struct grub_net_bootp_packet *bp, - grub_size_t size, - int is_def, char **device, char **path); - -grub_err_t -grub_net_add_ipv4_local (struct grub_net_network_level_interface *inf, - int mask); - -void -grub_net_process_dhcp (struct grub_net_buff *nb, - struct grub_net_network_level_interface *iface); - -int -grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a, - const grub_net_link_level_address_t *b); -int -grub_net_addr_cmp (const grub_net_network_level_address_t *a, - const grub_net_network_level_address_t *b); - - -/* - Currently supported adresses: - IPv4: XXX.XXX.XXX.XXX - IPv6: XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX - */ -#define GRUB_NET_MAX_STR_ADDR_LEN sizeof ("XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX") - -/* - Currently suppoerted adresses: - ethernet: XX:XX:XX:XX:XX:XX - */ - -#define GRUB_NET_MAX_STR_HWADDR_LEN (sizeof ("XX:XX:XX:XX:XX:XX")) - -/* Max VLAN id = 4094 */ -#define GRUB_NET_MAX_STR_VLAN_LEN (sizeof ("vlanXXXX")) - -void -grub_net_addr_to_str (const grub_net_network_level_address_t *target, - char *buf); -void -grub_net_hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str); - -void -grub_net_vlan_to_str (grub_uint16_t vlantag, char *str); - -grub_err_t -grub_env_set_net_property (const char *intername, const char *suffix, - const char *value, grub_size_t len); - -void -grub_net_poll_cards (unsigned time, int *stop_condition); - -void grub_bootp_init (void); -void grub_bootp_fini (void); - -void grub_dns_init (void); -void grub_dns_fini (void); - -void grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter); - -void -grub_net_tcp_retransmit (void); - -void -grub_net_link_layer_add_address (struct grub_net_card *card, - const grub_net_network_level_address_t *nl, - const grub_net_link_level_address_t *ll, - int override); -int -grub_net_link_layer_resolve_check (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *proto_addr); -grub_err_t -grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *proto_addr, - grub_net_link_level_address_t *hw_addr); -grub_err_t -grub_net_dns_lookup (const char *name, - const struct grub_net_network_level_address *servers, - grub_size_t n_servers, - grub_size_t *naddresses, - struct grub_net_network_level_address **addresses, - int cache); -grub_err_t -grub_net_add_dns_server (const struct grub_net_network_level_address *s); -void -grub_net_remove_dns_server (const struct grub_net_network_level_address *s); - -grub_err_t -grub_net_search_config_file (char *config, grub_size_t config_buf_len); - -extern char *grub_net_default_server; - -#define GRUB_NET_TRIES 40 -#define GRUB_NET_INTERVAL 400 -#define GRUB_NET_INTERVAL_ADDITION 20 - -#define VLANTAG_IDENTIFIER 0x8100 +/* 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/net/arp.h b/include/grub/net/arp.h deleted file mode 100644 index 8eb211ba8..000000000 --- a/include/grub/net/arp.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_NET_ARP_HEADER -#define GRUB_NET_ARP_HEADER 1 -#include -#include - -extern grub_err_t grub_net_arp_receive (struct grub_net_buff *nb, - struct grub_net_card *card, - grub_uint16_t *vlantag); - -grub_err_t -grub_net_arp_send_request (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *proto_addr); - -#endif diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h deleted file mode 100644 index 534ee433c..000000000 --- a/include/grub/net/ethernet.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_NET_ETHERNET_HEADER -#define GRUB_NET_ETHERNET_HEADER 1 -#include -#include - -/* IANA Ethertype */ -typedef enum - { - GRUB_NET_ETHERTYPE_IP = 0x0800, - GRUB_NET_ETHERTYPE_ARP = 0x0806, - GRUB_NET_ETHERTYPE_IP6 = 0x86DD, - } grub_net_ethertype_t; - -grub_err_t -send_ethernet_packet (struct grub_net_network_level_interface *inf, - struct grub_net_buff *nb, - grub_net_link_level_address_t target_addr, - grub_net_ethertype_t ethertype); -grub_err_t -grub_net_recv_ethernet_packet (struct grub_net_buff *nb, - struct grub_net_card *card); - -#endif diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h deleted file mode 100644 index e21a5eebc..000000000 --- a/include/grub/net/ip.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_NET_IP_HEADER -#define GRUB_NET_IP_HEADER 1 -#include -#include - -typedef enum grub_net_ip_protocol - { - GRUB_NET_IP_ICMP = 1, - GRUB_NET_IP_TCP = 6, - GRUB_NET_IP_UDP = 17, - GRUB_NET_IP_ICMPV6 = 58 - } grub_net_ip_protocol_t; -#define GRUB_NET_IP_BROADCAST 0xFFFFFFFF - -static inline grub_uint64_t -grub_net_ipv6_get_id (const grub_net_link_level_address_t *addr) -{ - return grub_cpu_to_be64 (((grub_uint64_t) (addr->mac[0] ^ 2) << 56) - | ((grub_uint64_t) addr->mac[1] << 48) - | ((grub_uint64_t) addr->mac[2] << 40) - | 0xfffe000000ULL - | ((grub_uint64_t) addr->mac[3] << 16) - | ((grub_uint64_t) addr->mac[4] << 8) - | ((grub_uint64_t) addr->mac[5])); -} - -grub_uint16_t grub_net_ip_chksum(void *ipv, grub_size_t len); - -grub_err_t -grub_net_recv_ip_packets (struct grub_net_buff *nb, - struct grub_net_card *card, - const grub_net_link_level_address_t *hwaddress, - const grub_net_link_level_address_t *src_hwaddress, - grub_uint16_t *vlantag); - -grub_err_t -grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *target, - const grub_net_link_level_address_t *ll_target_addr, - struct grub_net_buff *nb, - grub_net_ip_protocol_t proto); - -grub_err_t -grub_net_recv_icmp_packet (struct grub_net_buff *nb, - struct grub_net_network_level_interface *inf, - const grub_net_link_level_address_t *ll_src, - const grub_net_network_level_address_t *src); -grub_err_t -grub_net_recv_icmp6_packet (struct grub_net_buff *nb, - struct grub_net_card *card, - struct grub_net_network_level_interface *inf, - const grub_net_link_level_address_t *ll_src, - const grub_net_network_level_address_t *source, - const grub_net_network_level_address_t *dest, - grub_uint8_t ttl); -grub_err_t -grub_net_recv_udp_packet (struct grub_net_buff *nb, - struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *src); -grub_err_t -grub_net_recv_tcp_packet (struct grub_net_buff *nb, - struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *source); - -grub_uint16_t -grub_net_ip_transport_checksum (struct grub_net_buff *nb, - grub_uint16_t proto, - const grub_net_network_level_address_t *src, - const grub_net_network_level_address_t *dst); - -struct grub_net_network_level_interface * -grub_net_ipv6_get_link_local (struct grub_net_card *card, - const grub_net_link_level_address_t *hwaddr); -grub_err_t -grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *proto_addr); - -grub_err_t -grub_net_icmp6_send_router_solicit (struct grub_net_network_level_interface *inf); -#endif diff --git a/include/grub/net/netbuff.h b/include/grub/net/netbuff.h deleted file mode 100644 index 1177c1220..000000000 --- a/include/grub/net/netbuff.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef GRUB_NETBUFF_HEADER -#define GRUB_NETBUFF_HEADER - -#include - -#define NETBUFF_ALIGN 2048 -#define NETBUFFMINLEN 64 - -struct grub_net_buff -{ - /* Pointer to the start of the buffer. */ - grub_uint8_t *head; - /* Pointer to the data. */ - grub_uint8_t *data; - /* Pointer to the tail. */ - grub_uint8_t *tail; - /* Pointer to the end of the buffer. */ - grub_uint8_t *end; -}; - -grub_err_t grub_netbuff_put (struct grub_net_buff *net_buff, grub_size_t len); -grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buff, grub_size_t len); -grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff, grub_size_t len); -grub_err_t grub_netbuff_pull (struct grub_net_buff *net_buff, grub_size_t len); -grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buff, grub_size_t len); -grub_err_t grub_netbuff_clear (struct grub_net_buff *net_buff); -struct grub_net_buff * grub_netbuff_alloc (grub_size_t len); -struct grub_net_buff * grub_netbuff_make_pkt (grub_size_t len); -void grub_netbuff_free (struct grub_net_buff *net_buff); - -#endif diff --git a/include/grub/net/tcp.h b/include/grub/net/tcp.h deleted file mode 100644 index 5a9305ab8..000000000 --- a/include/grub/net/tcp.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_NET_TCP_HEADER -#define GRUB_NET_TCP_HEADER 1 -#include -#include - -struct grub_net_tcp_socket; -typedef struct grub_net_tcp_socket *grub_net_tcp_socket_t; - -struct grub_net_tcp_listen; -typedef struct grub_net_tcp_listen *grub_net_tcp_listen_t; - -grub_net_tcp_socket_t -grub_net_tcp_open (char *server, - grub_uint16_t out_port, - grub_err_t (*recv_hook) (grub_net_tcp_socket_t sock, - struct grub_net_buff *nb, - void *data), - void (*error_hook) (grub_net_tcp_socket_t sock, - void *data), - void (*fin_hook) (grub_net_tcp_socket_t sock, - void *data), - void *hook_data); - -grub_net_tcp_listen_t -grub_net_tcp_listen (grub_uint16_t port, - const struct grub_net_network_level_interface *inf, - grub_err_t (*listen_hook) (grub_net_tcp_listen_t listen, - grub_net_tcp_socket_t sock, - void *data), - void *hook_data); - -void -grub_net_tcp_stop_listen (grub_net_tcp_listen_t listen); - -grub_err_t -grub_net_send_tcp_packet (const grub_net_tcp_socket_t socket, - struct grub_net_buff *nb, - int push); - -enum - { - GRUB_NET_TCP_CONTINUE_RECEIVING, - GRUB_NET_TCP_DISCARD, - GRUB_NET_TCP_ABORT - }; - -void -grub_net_tcp_close (grub_net_tcp_socket_t sock, int discard_received); - -grub_err_t -grub_net_tcp_accept (grub_net_tcp_socket_t sock, - grub_err_t (*recv_hook) (grub_net_tcp_socket_t sock, - struct grub_net_buff *nb, - void *data), - void (*error_hook) (grub_net_tcp_socket_t sock, - void *data), - void (*fin_hook) (grub_net_tcp_socket_t sock, - void *data), - void *hook_data); - -void -grub_net_tcp_stall (grub_net_tcp_socket_t sock); - -void -grub_net_tcp_unstall (grub_net_tcp_socket_t sock); - -#endif diff --git a/include/grub/net/udp.h b/include/grub/net/udp.h deleted file mode 100644 index 3cd8feb45..000000000 --- a/include/grub/net/udp.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_NET_UDP_HEADER -#define GRUB_NET_UDP_HEADER 1 -#include -#include - -struct udphdr -{ - grub_uint16_t src; - grub_uint16_t dst; - grub_uint16_t len; - grub_uint16_t chksum; -} GRUB_PACKED; - -struct grub_net_udp_socket; -typedef struct grub_net_udp_socket *grub_net_udp_socket_t; - -grub_net_udp_socket_t -grub_net_udp_open (grub_net_network_level_address_t addr, - grub_uint16_t out_port, - grub_err_t (*recv_hook) (grub_net_udp_socket_t sock, - struct grub_net_buff *nb, - void *data), - void *recv_hook_data); - -void -grub_net_udp_close (grub_net_udp_socket_t sock); - -grub_err_t -grub_net_send_udp_packet (const grub_net_udp_socket_t socket, - struct grub_net_buff *nb); - - -#endif diff --git a/include/grub/normal.h b/include/grub/normal.h index 218cbabcc..fe45ddf71 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -28,6 +28,9 @@ #include #include +/* 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 @@ -48,25 +51,13 @@ 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); -struct grub_term_screen_geometry -{ - /* The number of entries shown at a time. */ - int num_entries; - int first_entry_y; - int first_entry_x; - int entry_width; - int timeout_y; - int timeout_lines; - int border; - int right_margin; -}; - void grub_menu_init_page (int nested, int edit, - struct grub_term_screen_geometry *geo, struct grub_term_output *term); -void grub_normal_init_page (struct grub_term_output *term, int y); +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, int force_auth); +void grub_cmdline_run (int nested); /* Defined in `cmdline.c'. */ char *grub_cmdline_get (const char *prompt); @@ -82,96 +73,44 @@ 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); -int grub_parse_color_name_pair (grub_uint8_t *ret, const char *name); +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, - int margin_left, int margin_right, - struct grub_term_output *term); - -void -grub_print_ucs4_menu (const grub_uint32_t * str, +void grub_print_ucs4 (const grub_uint32_t * str, const grub_uint32_t * last_position, - int margin_left, int margin_right, - struct grub_term_output *term, - int skip_lines, int max_lines, grub_uint32_t contchar, - struct grub_term_pos *pos); -int -grub_ucs4_count_lines (const grub_uint32_t * str, - const grub_uint32_t * last_position, - int margin_left, int margin_right, - struct grub_term_output *term); -grub_size_t grub_getstringwidth (grub_uint32_t * str, - const grub_uint32_t * last_position, - struct grub_term_output *term); + 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, int autobooted); +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); +void read_command_list (void); /* Defined in `autofs.c'. */ -void read_fs_list (const char *prefix); +void read_fs_list (void); void grub_context_init (void); void grub_context_fini (void); -void read_crypto_list (const char *prefix); +void read_crypto_list (void); -void read_terminal_list (const char *prefix); +void read_terminal_list (void); void grub_set_more (int onoff); -void grub_normal_reset_more (void); - -void grub_xputs_normal (const char *str); - -extern int grub_extractor_level; - -grub_err_t -grub_normal_add_menu_entry (int argc, const char **args, char **classes, - const char *id, - const char *users, const char *hotkey, - const char *prefix, const char *sourcecode, - int submenu); - -grub_err_t -grub_normal_set_password (const char *user, const char *password); - -void grub_normal_free_menu (grub_menu_t menu); - -void grub_normal_auth_init (void); -void grub_normal_auth_fini (void); - -void -grub_xnputs (const char *str, grub_size_t msg_len); - -grub_command_t -grub_dyncmd_get_cmd (grub_command_t cmd); - -void -grub_gettext_reread_prefix (const char *val); - -enum grub_human_size_type - { - GRUB_HUMAN_SIZE_NORMAL, - GRUB_HUMAN_SIZE_SHORT, - GRUB_HUMAN_SIZE_SPEED, - }; - -const char * -grub_get_human_size (grub_uint64_t size, enum grub_human_size_type type); +int grub_normal_get_line_counter (void); +void grub_install_newline_hook (void); #endif /* ! GRUB_NORMAL_HEADER */ diff --git a/include/grub/ns8250.h b/include/grub/ns8250.h deleted file mode 100644 index 556c0fa60..000000000 --- a/include/grub/ns8250.h +++ /dev/null @@ -1,93 +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 . - */ - -#ifndef GRUB_NS8250_HEADER -#define GRUB_NS8250_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_TRIGGER14 0xC7 - -/* Enable the FIFO. */ -#define UART_ENABLE_FIFO_TRIGGER1 0x07 - -/* Turn on DTR, RTS, and OUT2. */ -#define UART_ENABLE_DTRRTS 0x03 - -/* Turn on DTR, RTS, and OUT2. */ -#define UART_ENABLE_OUT2 0x08 - -/* - * Default clock input of the UART (feeds the baud rate generator). - * - * The standard value here is 1.8432 MHz, which corresponds to - * 115200 bauds * 16 (16 times oversampling). - * - */ -#ifdef GRUB_MACHINE_MIPS_LOONGSON -#define UART_DEFAULT_BASE_CLOCK ((2 * 115200) << 4) -#else -#define UART_DEFAULT_BASE_CLOCK (115200 << 4) -#endif - -#ifndef ASM_FILE -#include - -grub_port_t -grub_ns8250_hw_get_port (const unsigned int unit); -#endif - -#endif /* ! GRUB_SERIAL_MACHINE_HEADER */ diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h index 77b182acf..31b99398b 100644 --- a/include/grub/ntfs.h +++ b/include/grub/ntfs.h @@ -20,110 +20,79 @@ #ifndef GRUB_NTFS_H #define GRUB_NTFS_H 1 -enum - { - GRUB_NTFS_FILE_MFT = 0, - GRUB_NTFS_FILE_MFTMIRR = 1, - GRUB_NTFS_FILE_LOGFILE = 2, - GRUB_NTFS_FILE_VOLUME = 3, - GRUB_NTFS_FILE_ATTRDEF = 4, - GRUB_NTFS_FILE_ROOT = 5, - GRUB_NTFS_FILE_BITMAP = 6, - GRUB_NTFS_FILE_BOOT = 7, - GRUB_NTFS_FILE_BADCLUS = 8, - GRUB_NTFS_FILE_QUOTA = 9, - GRUB_NTFS_FILE_UPCASE = 10, - }; +#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 -enum - { - GRUB_NTFS_AT_STANDARD_INFORMATION = 0x10, - GRUB_NTFS_AT_ATTRIBUTE_LIST = 0x20, - GRUB_NTFS_AT_FILENAME = 0x30, - GRUB_NTFS_AT_OBJECT_ID = 0x40, - GRUB_NTFS_AT_SECURITY_DESCRIPTOR = 0x50, - GRUB_NTFS_AT_VOLUME_NAME = 0x60, - GRUB_NTFS_AT_VOLUME_INFORMATION = 0x70, - GRUB_NTFS_AT_DATA = 0x80, - GRUB_NTFS_AT_INDEX_ROOT = 0x90, - GRUB_NTFS_AT_INDEX_ALLOCATION = 0xA0, - GRUB_NTFS_AT_BITMAP = 0xB0, - GRUB_NTFS_AT_SYMLINK = 0xC0, - GRUB_NTFS_AT_EA_INFORMATION = 0xD0, - GRUB_NTFS_AT_EA = 0xE0, - }; +#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 -enum - { - GRUB_NTFS_ATTR_READ_ONLY = 0x1, - GRUB_NTFS_ATTR_HIDDEN = 0x2, - GRUB_NTFS_ATTR_SYSTEM = 0x4, - GRUB_NTFS_ATTR_ARCHIVE = 0x20, - GRUB_NTFS_ATTR_DEVICE = 0x40, - GRUB_NTFS_ATTR_NORMAL = 0x80, - GRUB_NTFS_ATTR_TEMPORARY = 0x100, - GRUB_NTFS_ATTR_SPARSE = 0x200, - GRUB_NTFS_ATTR_REPARSE = 0x400, - GRUB_NTFS_ATTR_COMPRESSED = 0x800, - GRUB_NTFS_ATTR_OFFLINE = 0x1000, - GRUB_NTFS_ATTR_NOT_INDEXED = 0x2000, - GRUB_NTFS_ATTR_ENCRYPTED = 0x4000, - GRUB_NTFS_ATTR_DIRECTORY = 0x10000000, - GRUB_NTFS_ATTR_INDEX_VIEW = 0x20000000 - }; +#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 -enum - { - GRUB_NTFS_FLAG_COMPRESSED = 1, - GRUB_NTFS_FLAG_ENCRYPTED = 0x4000, - GRUB_NTFS_FLAG_SPARSE = 0x8000 - }; +#define FLAG_COMPRESSED 1 +#define FLAG_ENCRYPTED 0x4000 +#define FLAG_SPARSE 0x8000 -#define GRUB_NTFS_BLK_SHR GRUB_DISK_SECTOR_BITS +#define BLK_SHR GRUB_DISK_SECTOR_BITS -#define GRUB_NTFS_MAX_MFT (4096 >> GRUB_NTFS_BLK_SHR) -#define GRUB_NTFS_MAX_IDX (16384 >> GRUB_NTFS_BLK_SHR) +#define MAX_MFT (1024 >> BLK_SHR) +#define MAX_IDX (16384 >> BLK_SHR) -#define GRUB_NTFS_COM_LEN 4096 -#define GRUB_NTFS_COM_LOG_LEN 12 -#define GRUB_NTFS_COM_SEC (GRUB_NTFS_COM_LEN >> GRUB_NTFS_BLK_SHR) -#define GRUB_NTFS_LOG_COM_SEC (GRUB_NTFS_COM_LOG_LEN - GRUB_NTFS_BLK_SHR) +#define COM_LEN 4096 +#define COM_LOG_LEN 12 +#define COM_SEC (COM_LEN >> BLK_SHR) -#define GRUB_NTFS_ATTRIBUTE_HEADER_SIZE 16 +#define AF_ALST 1 +#define AF_MMFT 2 +#define AF_GPOS 4 -/* - * To make attribute validation clearer the offsets for each value in the - * attribute headers are defined as macros. - * - * These offsets are all from: - * https://flatcap.github.io/linux-ntfs/ntfs/concepts/attribute_header.html - */ +#define RF_COMP 1 +#define RF_CBLK 2 +#define RF_BLNK 4 -/* These offsets are part of the attribute header. */ -#define GRUB_NTFS_ATTRIBUTE_LENGTH 4 -#define GRUB_NTFS_ATTRIBUTE_RESIDENT 8 -#define GRUB_NTFS_ATTRIBUTE_NAME_LENGTH 9 -#define GRUB_NTFS_ATTRIBUTE_NAME_OFFSET 10 +#define valueat(buf,ofs,type) *((type*)(((char*)buf)+ofs)) -/* Offsets for values needed for resident data. */ -#define GRUB_NTFS_ATTRIBUTE_RES_LENGTH 16 -#define GRUB_NTFS_ATTRIBUTE_RES_OFFSET 20 +#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)) -/* Offsets for values needed for non-resident data. */ -#define GRUB_NTFS_ATTRIBUTE_DATA_RUNS 32 -#define GRUB_NTFS_ATTRIBUTE_COMPRESSION_UNIT_SIZE 34 - -enum - { - GRUB_NTFS_AF_ALST = 1, - GRUB_NTFS_AF_MMFT = 2, - GRUB_NTFS_AF_GPOS = 4, - }; - -enum - { - GRUB_NTFS_RF_BLNK = 1 - }; +#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 { @@ -137,38 +106,36 @@ struct grub_ntfs_bpb grub_uint16_t sectors_per_track; grub_uint16_t num_heads; grub_uint32_t num_hidden_sectors; - grub_uint32_t reserved_3; - grub_uint8_t bios_drive; - grub_uint8_t reserved_4[3]; + 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_5[3]; + grub_int8_t reserved_4[3]; grub_int8_t clusters_per_index; - grub_int8_t reserved_6[3]; + grub_int8_t reserved_5[3]; grub_uint64_t num_serial; grub_uint32_t checksum; -} GRUB_PACKED; +} __attribute__ ((packed)); + +#define grub_ntfs_file grub_fshelp_node struct grub_ntfs_attr { int flags; - grub_uint8_t *emft_buf, *edat_buf; - grub_uint8_t *attr_cur, *attr_nxt, *attr_end; + char *emft_buf, *edat_buf; + char *attr_cur, *attr_nxt, *attr_end; grub_uint32_t save_pos; - grub_uint8_t *sbuf; - grub_uint8_t *end; + char *sbuf; struct grub_ntfs_file *mft; }; -struct grub_ntfs_file +struct grub_fshelp_node { struct grub_ntfs_data *data; - grub_uint8_t *buf; + char *buf; grub_uint64_t size; - grub_uint64_t mtime; - grub_uint64_t ino; + grub_uint32_t ino; int inode_read; struct grub_ntfs_attr attr; }; @@ -178,46 +145,39 @@ struct grub_ntfs_data struct grub_ntfs_file cmft; struct grub_ntfs_file mmft; grub_disk_t disk; - grub_uint64_t mft_size; - grub_uint64_t idx_size; - int log_spc; - grub_uint64_t mft_start; + 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_table_element -{ - grub_uint32_t next_vcn; - grub_uint32_t next_lcn; -}; - struct grub_ntfs_comp { grub_disk_t disk; int comp_head, comp_tail; - struct grub_ntfs_comp_table_element comp_table[16]; - grub_uint32_t cbuf_ofs, cbuf_vcn; - int log_spc; - grub_uint8_t *cbuf; + 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; - grub_uint8_t *cur_run; + char *cur_run; struct grub_ntfs_attr *attr; struct grub_ntfs_comp comp; - void *file; }; -typedef grub_err_t (*grub_ntfscomp_func_t) (grub_uint8_t *dest, - grub_disk_addr_t ofs, - grub_size_t len, - struct grub_ntfs_rlst * ctx); +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 grub_ntfscomp_func_t grub_ntfscomp_func; +extern ntfscomp_func_t EXPORT_VAR (grub_ntfscomp_func); -grub_err_t grub_ntfs_read_run_list (struct grub_ntfs_rlst *ctx); +grub_err_t EXPORT_FUNC(grub_ntfs_read_run_list) (struct grub_ntfs_rlst *ctx); #endif /* ! GRUB_NTFS_H */ diff --git a/include/grub/offsets.h b/include/grub/offsets.h deleted file mode 100644 index 442dc31de..000000000 --- a/include/grub/offsets.h +++ /dev/null @@ -1,168 +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 . - */ - -#ifndef OFFSETS_HEADER -#define OFFSETS_HEADER 1 - -/* The offset of GRUB_COMPRESSED_SIZE. */ -#define GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE 0x08 - -/* The offset of GRUB_COMPRESSED_SIZE. */ -#define GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE 0x0c - -/* Offset of reed_solomon_redundancy. */ -#define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x10 - -/* Offset of field holding no reed solomon length. */ -#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH 0x14 - -#define GRUB_DECOMPRESSOR_I386_PC_BOOT_DEVICE 0x18 - -#define GRUB_DECOMPRESSOR_I386_PC_MAX_DECOMPRESSOR_SIZE (0x9000-0x8200) - -/* The segment where the kernel is loaded. */ -#define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 - -#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x9000 -#define GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR 0x100000 - -/* The upper memory area (starting at 640 kiB). */ -#define GRUB_MEMORY_I386_PC_UPPER 0xa0000 -#define GRUB_MEMORY_I386_QEMU_UPPER GRUB_MEMORY_I386_PC_UPPER - -/* The offset of GRUB_CORE_ENTRY_ADDR. */ -#define GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR 0x4 - -/* The offset of GRUB_CORE_ENTRY_ADDR. */ -#define GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR 0x8 - -#define GRUB_KERNEL_I386_QEMU_LINK_ADDR 0x9000 - -/* The offset of GRUB_TOTAL_MODULE_SIZE. */ -#define GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE 0x8 -#define GRUB_KERNEL_ARM_STACK_SIZE 0x40000 - -#define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 - -#define GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS 0x4400 -#define GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR 0x4400 - -#define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 -#define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR 0x200000 - -#define GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR 0x80200000 - -#define GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN 32 - -#define GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE 0x8 -#define GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE 0xc -#define GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR 0x10 - -#define GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE 0x08 - -#define GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR 0x80200000 -#define GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN 32 -#define GRUB_DECOMPRESSOR_MIPS_QEMU_MIPS_COMPRESSED_SIZE 0x8 -#define GRUB_DECOMPRESSOR_MIPS_QEMU_MIPS_UNCOMPRESSED_SIZE 0xc -#define GRUB_DECOMPRESSOR_MIPS_QEMU_MIPS_UNCOMPRESSED_ADDR 0x10 -#define GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE 0x08 - -#define GRUB_KERNEL_MIPS_ARC_LINK_ADDR 0x88200000 -#define GRUB_KERNEL_MIPSEL_ARC_LINK_ADDR 0x80700000 -#define GRUB_KERNEL_MIPS_ARC_LINK_ALIGN 32 - -#define GRUB_DECOMPRESSOR_MIPS_ARC_COMPRESSED_SIZE 0x8 -#define GRUB_DECOMPRESSOR_MIPS_ARC_UNCOMPRESSED_SIZE 0xc -#define GRUB_DECOMPRESSOR_MIPS_ARC_UNCOMPRESSED_ADDR 0x10 - -#define GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE 0x08 - -#define GRUB_KERNEL_I386_COREBOOT_LINK_ADDR 0x9000 -#define GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR 0x100000 - -#define GRUB_KERNEL_I386_IEEE1275_LINK_ADDR 0x10000 - -#define GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN 0x1000 -#define GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN 0x1 -#define GRUB_KERNEL_I386_MULTIBOOT_MOD_ALIGN GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN - -#define GRUB_KERNEL_X86_64_XEN_MOD_ALIGN 0x8 -#define GRUB_KERNEL_I386_XEN_MOD_ALIGN 0x8 -#define GRUB_KERNEL_I386_XEN_PVH_MOD_ALIGN 0x8 - -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_KERNEL_X86_64_XEN_MOD_GAP 0x0 -#define GRUB_KERNEL_I386_XEN_MOD_GAP 0x0 -#define GRUB_KERNEL_I386_XEN_PVH_MOD_GAP 0x0 -#define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0 -#define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0 -#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP 0x0 -#define GRUB_KERNEL_ARM_UBOOT_MOD_GAP 0x0 - -#define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000 -#define GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN 3 -#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN (1 << GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN) - -#define GRUB_KERNEL_MIPS_LOONGSON_MOD_ALIGN 0x4 -#define GRUB_KERNEL_MIPS_ARC_MOD_ALIGN 0x4 -#define GRUB_KERNEL_MIPS_QEMU_MIPS_MOD_ALIGN 0x4 - -#define GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN 0x8 -#define GRUB_KERNEL_ARM_UBOOT_TOTAL_MODULE_SIZE 0x4 - -#define GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN 0x8 -#define GRUB_KERNEL_ARM_COREBOOT_TOTAL_MODULE_SIZE 0x4 - -#define GRUB_KERNEL_ARM_STACK_SIZE 0x40000 -#define GRUB_KERNEL_ARM_COREBOOT_MOD_GAP (GRUB_KERNEL_ARM_STACK_SIZE + 1024) - -/* 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_KERNEL_POWERPC_IEEE1275_MOD_GAP 0x8000 - -#ifdef GRUB_MACHINE -#define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c -#define GRUB_OFFSETS_CONCAT(a,b,c) GRUB_OFFSETS_CONCAT_(a,b,c) -#define GRUB_KERNEL_MACHINE_MOD_ALIGN GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _MOD_ALIGN) -#define GRUB_KERNEL_MACHINE_MOD_GAP GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _MOD_GAP) -#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _TOTAL_MODULE_SIZE) - -#define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, GRUB_MACHINE, _KERNEL_SEG) -#define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, GRUB_MACHINE, _UPPER) -#if defined (GRUB_MACHINE_ARC) && defined (GRUB_CPU_MIPSEL) -#define GRUB_MACHINE_LINK_ADDR GRUB_KERNEL_MIPSEL_ARC_LINK_ADDR -#else -#define GRUB_MACHINE_LINK_ADDR GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _LINK_ADDR) -#endif - -#define GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _COMPRESSED_SIZE) -#define GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _UNCOMPRESSED_SIZE) -#define GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _UNCOMPRESSED_ADDR) -#endif - -#ifndef ASM_FILE -struct grub_pc_bios_boot_blocklist -{ - grub_uint64_t start; - grub_uint16_t len; - grub_uint16_t segment; -} GRUB_PACKED; -#endif - -#endif diff --git a/include/grub/osdep/hostfile.h b/include/grub/osdep/hostfile.h deleted file mode 100644 index 6d9f75ba3..000000000 --- a/include/grub/osdep/hostfile.h +++ /dev/null @@ -1,7 +0,0 @@ -#if defined (__AROS__) -#include "hostfile_aros.h" -#elif defined (__CYGWIN__) || defined (__MINGW32__) -#include "hostfile_windows.h" -#else -#include "hostfile_unix.h" -#endif diff --git a/include/grub/osdep/hostfile_aros.h b/include/grub/osdep/hostfile_aros.h deleted file mode 100644 index 3c67b7bc4..000000000 --- a/include/grub/osdep/hostfile_aros.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_EMU_HOSTFILE_H -#define GRUB_EMU_HOSTFILE_H 1 - -#include -#include - -#include -#include -#include -#include -#include -#include - -typedef struct dirent *grub_util_fd_dirent_t; -typedef DIR *grub_util_fd_dir_t; - -static inline grub_util_fd_dir_t -grub_util_fd_opendir (const char *name) -{ - return opendir (name); -} - -static inline void -grub_util_fd_closedir (grub_util_fd_dir_t dirp) -{ - closedir (dirp); -} - -static inline grub_util_fd_dirent_t -grub_util_fd_readdir (grub_util_fd_dir_t dirp) -{ - return readdir (dirp); -} - -static inline int -grub_util_rmdir (const char *pathname) -{ - return rmdir (pathname); -} - -static inline int -grub_util_unlink (const char *pathname) -{ - return unlink (pathname); -} - -static inline int -grub_util_rename (const char *from, const char *to) -{ - return rename (from, to); -} - -static inline ssize_t -grub_util_readlink (const char *name, char *buf, size_t bufsize) -{ - return readlink(name, buf, bufsize); -} - -#define grub_util_mkdir(a) (void) mkdir ((a), 0755) - -struct grub_util_fd -{ - enum { GRUB_UTIL_FD_FILE, GRUB_UTIL_FD_DISK } type; - grub_uint64_t off; - union - { - int fd; - struct { - struct IOExtTD *ioreq; - struct MsgPort *mp; - unsigned int is_floppy:1; - unsigned int is_64:1; - }; - }; -}; -typedef struct grub_util_fd *grub_util_fd_t; - -enum grub_util_fd_open_flags_t - { - GRUB_UTIL_FD_O_RDONLY = O_RDONLY, - GRUB_UTIL_FD_O_WRONLY = O_WRONLY, - GRUB_UTIL_FD_O_RDWR = O_RDWR, - GRUB_UTIL_FD_O_CREATTRUNC = O_CREAT | O_TRUNC, - GRUB_UTIL_FD_O_SYNC = (0 -#ifdef O_SYNC - | O_SYNC -#endif -#ifdef O_FSYNC - | O_FSYNC -#endif - ) - }; - -#define GRUB_UTIL_FD_INVALID NULL -#define GRUB_UTIL_FD_IS_VALID(x) ((x) != GRUB_UTIL_FD_INVALID) -#define GRUB_UTIL_FD_STAT_IS_FUNCTIONAL 0 - -#define DEFAULT_DIRECTORY "SYS:" GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME -#define DEFAULT_DEVICE_MAP DEFAULT_DIRECTORY "/device.map" - -#endif diff --git a/include/grub/osdep/hostfile_unix.h b/include/grub/osdep/hostfile_unix.h deleted file mode 100644 index 9e6d647b8..000000000 --- a/include/grub/osdep/hostfile_unix.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_EMU_HOSTFILE_H -#define GRUB_EMU_HOSTFILE_H 1 - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -typedef struct dirent *grub_util_fd_dirent_t; -typedef DIR *grub_util_fd_dir_t; - -static inline grub_util_fd_dir_t -grub_util_fd_opendir (const char *name) -{ - return opendir (name); -} - -static inline void -grub_util_fd_closedir (grub_util_fd_dir_t dirp) -{ - closedir (dirp); -} - -static inline grub_util_fd_dirent_t -grub_util_fd_readdir (grub_util_fd_dir_t dirp) -{ - return readdir (dirp); -} - -static inline int -grub_util_unlink (const char *pathname) -{ - return unlink (pathname); -} - -static inline int -grub_util_rmdir (const char *pathname) -{ - return rmdir (pathname); -} - -static inline int -grub_util_rename (const char *from, const char *to) -{ - return rename (from, to); -} - -static inline ssize_t -grub_util_readlink (const char *name, char *buf, size_t bufsize) -{ - return readlink(name, buf, bufsize); -} - -#define grub_util_mkdir(a) (void) mkdir ((a), 0755) - -#if defined (__NetBSD__) -/* NetBSD uses /boot for its boot block. */ -# define DEFAULT_DIRECTORY "/"GRUB_DIR_NAME -#else -# define DEFAULT_DIRECTORY "/"GRUB_BOOT_DIR_NAME"/"GRUB_DIR_NAME -#endif - -enum grub_util_fd_open_flags_t - { - GRUB_UTIL_FD_O_RDONLY = O_RDONLY, - GRUB_UTIL_FD_O_WRONLY = O_WRONLY, - GRUB_UTIL_FD_O_RDWR = O_RDWR, - GRUB_UTIL_FD_O_CREATTRUNC = O_CREAT | O_TRUNC, - GRUB_UTIL_FD_O_SYNC = (0 -#ifdef O_SYNC - | O_SYNC -#endif -#ifdef O_FSYNC - | O_FSYNC -#endif - ) - }; - -#define DEFAULT_DEVICE_MAP DEFAULT_DIRECTORY "/device.map" - -typedef int grub_util_fd_t; -#define GRUB_UTIL_FD_INVALID -1 -#define GRUB_UTIL_FD_IS_VALID(x) ((x) >= 0) -#define GRUB_UTIL_FD_STAT_IS_FUNCTIONAL 1 - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) || defined (__sun__) || defined(__OpenBSD__) || defined(__HAIKU__) -#define GRUB_DISK_DEVS_ARE_CHAR 1 -#else -#define GRUB_DISK_DEVS_ARE_CHAR 0 -#endif - -#endif diff --git a/include/grub/osdep/hostfile_windows.h b/include/grub/osdep/hostfile_windows.h deleted file mode 100644 index bf6451b6d..000000000 --- a/include/grub/osdep/hostfile_windows.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_EMU_HOSTFILE_H -#define GRUB_EMU_HOSTFILE_H 1 - -#include -#include - -#include -typedef HANDLE grub_util_fd_t; -#define GRUB_UTIL_FD_INVALID INVALID_HANDLE_VALUE -#define GRUB_UTIL_FD_IS_VALID(x) ((x) != GRUB_UTIL_FD_INVALID) -#define GRUB_UTIL_FD_STAT_IS_FUNCTIONAL 0 - -#define DEFAULT_DIRECTORY "C:\\"GRUB_BOOT_DIR_NAME"\\"GRUB_DIR_NAME -#define DEFAULT_DEVICE_MAP DEFAULT_DIRECTORY "/device.map" - -struct grub_util_fd_dirent -{ - char d_name[0]; -}; -struct grub_util_fd_dir; -typedef struct grub_util_fd_dirent *grub_util_fd_dirent_t; -typedef struct grub_util_fd_dir *grub_util_fd_dir_t; - -int -grub_util_rename (const char *from, const char *to); -int -grub_util_unlink (const char *name); -void -grub_util_mkdir (const char *dir); - -grub_util_fd_dir_t -grub_util_fd_opendir (const char *name); - -void -grub_util_fd_closedir (grub_util_fd_dir_t dirp); - -grub_util_fd_dirent_t -grub_util_fd_readdir (grub_util_fd_dir_t dirp); - -int -grub_util_rmdir (const char *pathname); - -enum grub_util_fd_open_flags_t - { - GRUB_UTIL_FD_O_RDONLY = 1, - GRUB_UTIL_FD_O_WRONLY = 2, - GRUB_UTIL_FD_O_RDWR = 3, - GRUB_UTIL_FD_O_CREATTRUNC = 4, - GRUB_UTIL_FD_O_SYNC = 0, - }; - -#if defined (__MINGW32__) && !defined (__MINGW64__) - -/* 32 bit on Mingw-w64 already redefines them if _FILE_OFFSET_BITS=64 */ -#ifndef _W64 -#define fseeko fseeko64 -#define ftello ftello64 -#endif - -#endif - -LPTSTR -grub_util_utf8_to_tchar (const char *in); -char * -grub_util_tchar_to_utf8 (LPCTSTR in); - -#endif diff --git a/include/grub/osdep/major.h b/include/grub/osdep/major.h deleted file mode 100644 index 84a9159af..000000000 --- a/include/grub/osdep/major.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2021 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - * - * Fix for glibc 2.25 which is deprecating the namespace pollution of - * sys/types.h injecting major(), minor(), and makedev() into the - * compilation environment. - */ - -#ifndef GRUB_OSDEP_MAJOR_H -#define GRUB_OSDEP_MAJOR_H 1 - -#include - -#ifdef MAJOR_IN_MKDEV -# include -#elif defined (MAJOR_IN_SYSMACROS) -# include -#endif -#endif /* GRUB_OSDEP_MAJOR_H */ diff --git a/include/grub/parser.h b/include/grub/parser.h index 64f9f5cc2..17f0c4303 100644 --- a/include/grub/parser.h +++ b/include/grub/parser.h @@ -22,6 +22,7 @@ #include #include +#include #include /* All the states for the command line. */ @@ -62,8 +63,7 @@ EXPORT_FUNC (grub_parser_cmdline_state) (grub_parser_state_t state, grub_err_t EXPORT_FUNC (grub_parser_split_cmdline) (const char *cmdline, - grub_reader_getline_t getline_func, - void *getline_func_data, + grub_reader_getline_t getline, int *argc, char ***argv); struct grub_parser @@ -80,17 +80,40 @@ struct grub_parser /* Clean up the parser. */ grub_err_t (*fini) (void); - grub_err_t (*parse_line) (char *line, - grub_reader_getline_t getline_func, - void *getline_func_data); + grub_err_t (*parse_line) (char *line, grub_reader_getline_t getline); }; typedef struct grub_parser *grub_parser_t; -grub_err_t grub_parser_execute (char *source); +extern struct grub_handler_class EXPORT_VAR(grub_parser_class); +grub_err_t EXPORT_FUNC(grub_parser_execute) (char *source); -grub_err_t -grub_rescue_parse_line (char *line, - grub_reader_getline_t getline_func, - void *getline_func_data); +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 index c4d71d0ee..faa89cea6 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -20,56 +20,38 @@ #define GRUB_PART_HEADER 1 #include -#include struct grub_disk; typedef struct grub_partition *grub_partition_t; -#ifdef GRUB_UTIL -typedef enum -{ - GRUB_EMBED_PCBIOS -} grub_embed_type_t; -#endif - -typedef int (*grub_partition_iterate_hook_t) (struct grub_disk *disk, - const grub_partition_t partition, - void *data); - /* Partition map type. */ struct grub_partition_map { - /* The next partition map type. */ - struct grub_partition_map *next; - struct grub_partition_map **prev; - /* 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, - grub_partition_iterate_hook_t hook, void *hook_data); -#ifdef GRUB_UTIL -#define GRUB_MIN_RECOMMENDED_MBR_GAP 1900 + int (*hook) (struct grub_disk *disk, + const grub_partition_t partition)); - /* Determine sectors available for embedding. */ - grub_err_t (*embed) (struct grub_disk *disk, unsigned int *nsectors, - unsigned int max_nsectors, - grub_embed_type_t embed_type, - grub_disk_addr_t **sectors, - int warn_short); -#endif + /* Return the partition named STR on the disk DISK. */ + grub_partition_t (*probe) (struct grub_disk *disk, + const char *str); + + /* Return the name of the partition PARTITION. */ + char *(*get_name) (const grub_partition_t partition); + + /* The next partition map type. */ + struct grub_partition_map *next; }; typedef struct grub_partition_map *grub_partition_map_t; /* Partition description. */ struct grub_partition { - /* The partition number. */ - int number; - - /* The start sector (relative to parent). */ + /* The start sector. */ grub_disk_addr_t start; /* The length in sector units. */ @@ -81,55 +63,31 @@ struct grub_partition /* The index of this partition in the partition table. */ int index; - /* Parent partition (physically contains this partition). */ - struct grub_partition *parent; + /* Partition map type specific data. */ + void *data; /* The type partition map. */ grub_partition_map_t partmap; - - /* The type of partition when it's on MSDOS. - Used for embedding detection. */ - grub_uint8_t msdostype; }; 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, - grub_partition_iterate_hook_t hook, - void *hook_data); + int (*hook) (struct grub_disk *disk, + const grub_partition_t partition)); char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition); +int EXPORT_FUNC(grub_partition_map_iterate) (int (*hook) (const grub_partition_map_t partmap)); -extern grub_partition_map_t EXPORT_VAR(grub_partition_map_list); +void EXPORT_FUNC(grub_partition_map_register) (grub_partition_map_t partmap); -#ifndef GRUB_LST_GENERATOR -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)); -} -#endif - -static inline void -grub_partition_map_unregister (grub_partition_map_t partmap) -{ - grub_list_remove (GRUB_AS_LIST (partmap)); -} - -#define FOR_PARTITION_MAPS(var) FOR_LIST_ELEMENTS((var), (grub_partition_map_list)) +void EXPORT_FUNC(grub_partition_map_unregister) (grub_partition_map_t partmap); 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; + return p->start; } static inline grub_uint64_t diff --git a/include/grub/parttool.h b/include/grub/parttool.h index 4799a22c5..8291e1161 100644 --- a/include/grub/parttool.h +++ b/include/grub/parttool.h @@ -21,8 +21,8 @@ struct grub_parttool_argdesc { - const char *name; - const char *desc; + char *name; + char *desc; enum {GRUB_PARTTOOL_ARG_END, GRUB_PARTTOOL_ARG_BOOL, GRUB_PARTTOOL_ARG_VAL} type; }; @@ -32,7 +32,7 @@ struct grub_parttool_args int set; union { - int b; + int bool; char *str; }; }; diff --git a/include/grub/pci.h b/include/grub/pci.h index d4ce92b2d..1f3ac7fc7 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -19,10 +19,8 @@ #ifndef GRUB_PCI_H #define GRUB_PCI_H 1 -#ifndef ASM_FILE #include #include -#endif #define GRUB_PCI_ADDR_SPACE_MASK 0x01 #define GRUB_PCI_ADDR_SPACE_MEMORY 0x00 @@ -68,46 +66,9 @@ #define GRUB_PCI_REG_MIN_GNT 0x3e #define GRUB_PCI_REG_MAX_LAT 0x3f -#define GRUB_PCI_COMMAND_IO_ENABLED 0x0001 -#define GRUB_PCI_COMMAND_MEM_ENABLED 0x0002 -#define GRUB_PCI_COMMAND_BUS_MASTER 0x0004 -#define GRUB_PCI_COMMAND_PARITY_ERROR 0x0040 -#define GRUB_PCI_COMMAND_SERR_ENABLE 0x0100 - -#define GRUB_PCI_STATUS_CAPABILITIES 0x0010 -#define GRUB_PCI_STATUS_66MHZ_CAPABLE 0x0020 -#define GRUB_PCI_STATUS_FAST_B2B_CAPABLE 0x0080 - -#define GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT 9 -#define GRUB_PCI_STATUS_DEVSEL_TIMING_MASK 0x0600 - -#define GRUB_PCI_CLASS_DISPLAY_VGA 0x0300 -#define GRUB_PCI_CLASS_SERIAL_USB 0x0c03 -#define GRUB_PCI_CLASS_COMMUNICATION_SERIAL 0x0700 -#define GRUB_PCI_CLASS_COMMUNICATION_MODEM 0x0703 - -#define GRUB_PCI_SERIAL_16550_COMPATIBLE 0x02 - -#ifndef ASM_FILE - -enum - { - GRUB_PCI_CLASS_NETWORK = 0x02 - }; -enum - { - GRUB_PCI_CAP_POWER_MANAGEMENT = 0x01 - }; - -enum - { - GRUB_PCI_VENDOR_BROADCOM = 0x14e4 - }; - - typedef grub_uint32_t grub_pci_id_t; -#ifdef GRUB_MACHINE_EMU +#ifdef GRUB_UTIL #include #else typedef grub_uint32_t grub_pci_address_t; @@ -138,20 +99,12 @@ grub_pci_get_function (grub_pci_device_t dev) #include #endif -typedef int (*grub_pci_iteratefunc_t) - (grub_pci_device_t dev, grub_pci_id_t pciid, void *data); +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, - void *hook_data); - -#include - -grub_uint8_t -EXPORT_FUNC (grub_pci_find_capability) (grub_pci_device_t dev, grub_uint8_t cap); - -#endif +void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook); #endif /* GRUB_PCI_H */ diff --git a/include/grub/powerpc/ieee1275/biosdisk.h b/include/grub/powerpc/ieee1275/biosdisk.h new file mode 100644 index 000000000..30584d6b7 --- /dev/null +++ b/include/grub/powerpc/ieee1275/biosdisk.h @@ -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 . + */ + +#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/uboot/console.h b/include/grub/powerpc/ieee1275/console.h similarity index 80% rename from include/grub/uboot/console.h rename to include/grub/powerpc/ieee1275/console.h index 993a53845..ed2b7202a 100644 --- a/include/grub/uboot/console.h +++ b/include/grub/powerpc/ieee1275/console.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. + * 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 @@ -17,13 +17,12 @@ */ #ifndef GRUB_CONSOLE_MACHINE_HEADER -#define GRUB_CONSOLE_MACHINE_HEADER 1 +#define GRUB_CONSOLE_MACHINE_HEADER 1 /* Initialize the console system. */ -void grub_console_init_early (void); -void grub_console_init_lately (void); +void grub_console_init (void); -/* Exit the console system. */ +/* 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 index 4eb207018..3c7683fad 100644 --- a/include/grub/powerpc/ieee1275/ieee1275.h +++ b/include/grub/powerpc/ieee1275/ieee1275.h @@ -25,7 +25,4 @@ #define GRUB_IEEE1275_CELL_SIZEOF 4 typedef grub_uint32_t grub_ieee1275_cell_t; -#define PRIxGRUB_IEEE1275_CELL_T PRIxGRUB_UINT32_T -#define PRIuGRUB_IEEE1275_CELL_T PRIuGRUB_UINT32_T - #endif /* ! GRUB_IEEE1275_MACHINE_HEADER */ diff --git a/include/grub/arm/uboot/kernel.h b/include/grub/powerpc/ieee1275/kernel.h similarity index 77% rename from include/grub/arm/uboot/kernel.h rename to include/grub/powerpc/ieee1275/kernel.h index ce0b149cc..a76c2a4df 100644 --- a/include/grub/arm/uboot/kernel.h +++ b/include/grub/powerpc/ieee1275/kernel.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. + * 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 @@ -19,14 +19,14 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 +#include + #ifndef ASM_FILE -#include -#include +/* The prefix which points to the directory where GRUB modules and its + configuration file are located. */ +extern char grub_prefix[]; -#endif /* ! ASM_FILE */ - -#define GRUB_KERNEL_MACHINE_STACK_SIZE GRUB_KERNEL_ARM_STACK_SIZE -#define GRUB_KERNEL_MACHINE_HEAP_SIZE (grub_size_t) (16 * 1024 * 1024) +#endif #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/grub-core/kern/arm/coreboot/coreboot.S b/include/grub/powerpc/ieee1275/loader.h similarity index 58% rename from grub-core/kern/arm/coreboot/coreboot.S rename to include/grub/powerpc/ieee1275/loader.h index a1104526c..606bfcd0b 100644 --- a/grub-core/kern/arm/coreboot/coreboot.S +++ b/include/grub/powerpc/ieee1275/loader.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2016 Free Software Foundation, Inc. + * 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 @@ -16,29 +16,17 @@ * along with GRUB. If not, see . */ -#include +#ifndef GRUB_LOADER_MACHINE_HEADER +#define GRUB_LOADER_MACHINE_HEADER 1 - .file "coreboot.S" - .text - .syntax unified -#if !defined (__thumb2__) - .arch armv7a - .arm -#else - .arch armv7 - .thumb -#endif +/* 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[]); -FUNCTION(grub_arm_pfr1) - mrc p15, 0, r0, c0, c1, 1 - bx lr - -FUNCTION(grub_armv7_get_timer_value) - isb - mrrc p15, 1, r0, r1, c14 - bx lr - -FUNCTION(grub_armv7_get_timer_frequency) - mrc p15, 0, r0, c14, c0, 0 - bx lr +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/lib/ieee1275/reboot.c b/include/grub/powerpc/ieee1275/memory.h similarity index 80% rename from grub-core/lib/ieee1275/reboot.c rename to include/grub/powerpc/ieee1275/memory.h index 91c8779f2..f8f2ff08d 100644 --- a/grub-core/lib/ieee1275/reboot.c +++ b/include/grub/powerpc/ieee1275/memory.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. + * 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 @@ -16,12 +16,11 @@ * along with GRUB. If not, see . */ -#include -#include +#ifndef GRUB_MEMORY_MACHINE_HEADER +#define GRUB_MEMORY_MACHINE_HEADER 1 -void -grub_reboot (void) -{ - grub_ieee1275_interpret ("reset-all", 0); - for (;;) ; -} +#include + +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 + +#endif diff --git a/include/grub/mips/loongson/time.h b/include/grub/powerpc/ieee1275/time.h similarity index 87% rename from include/grub/mips/loongson/time.h rename to include/grub/powerpc/ieee1275/time.h index 098573261..3f8ad26d7 100644 --- a/include/grub/mips/loongson/time.h +++ b/include/grub/powerpc/ieee1275/time.h @@ -20,8 +20,10 @@ #define KERNEL_MACHINE_TIME_HEADER 1 #include -#include -extern grub_uint32_t EXPORT_VAR (grub_arch_busclock) __attribute__ ((section(".text"))); +#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 new file mode 100644 index 000000000..f4262a0a4 --- /dev/null +++ b/include/grub/powerpc/ieee1275/util/biosdisk.h @@ -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 . + */ + +#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 index 3fc0b9e23..b4687337f 100644 --- a/include/grub/powerpc/kernel.h +++ b/include/grub/powerpc/kernel.h @@ -19,4 +19,14 @@ #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/libgcc.h b/include/grub/powerpc/libgcc.h new file mode 100644 index 000000000..6be122308 --- /dev/null +++ b/include/grub/powerpc/libgcc.h @@ -0,0 +1,74 @@ +/* + * 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 . + */ + +#include + +#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___TRAMPOLINE_SETUP +void EXPORT_FUNC (__trampoline_setup) (void); +#endif +#ifdef HAVE___UCMPDI2 +void EXPORT_FUNC (__ucmpdi2) (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/powerpc/memory.h b/include/grub/powerpc/memory.h deleted file mode 100644 index b748f33c5..000000000 --- a/include/grub/powerpc/memory.h +++ /dev/null @@ -1,47 +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 . - */ - -#ifndef GRUB_MEMORY_CPU_HEADER -#define GRUB_MEMORY_CPU_HEADER 1 - -#ifndef ASM_FILE - -typedef grub_addr_t grub_phys_addr_t; - -static inline grub_phys_addr_t -grub_vtop (void *a) -{ - return (grub_phys_addr_t) a; -} - -static inline void * -grub_map_memory (grub_phys_addr_t a, grub_size_t size __attribute__ ((unused))) -{ - return (void *) a; -} - -static inline void -grub_unmap_memory (void *a __attribute__ ((unused)), - grub_size_t size __attribute__ ((unused))) -{ -} - -#endif - -#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/powerpc/relocator.h b/include/grub/powerpc/relocator.h deleted file mode 100644 index c2780bbca..000000000 --- a/include/grub/powerpc/relocator.h +++ /dev/null @@ -1,37 +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 . - */ - -#ifndef GRUB_RELOCATOR_CPU_HEADER -#define GRUB_RELOCATOR_CPU_HEADER 1 - -#include -#include -#include - -#define GRUB_PPC_JUMP_REGISTER 31 - -struct grub_relocator32_state -{ - grub_uint32_t gpr[32]; -}; - -grub_err_t -grub_relocator32_boot (struct grub_relocator *rel, - struct grub_relocator32_state state); - -#endif /* ! GRUB_RELOCATOR_CPU_HEADER */ diff --git a/include/grub/powerpc/setjmp.h b/include/grub/powerpc/setjmp.h index 7c2d184fa..fa16f73d2 100644 --- a/include/grub/powerpc/setjmp.h +++ b/include/grub/powerpc/setjmp.h @@ -19,9 +19,9 @@ #ifndef GRUB_SETJMP_CPU_HEADER #define GRUB_SETJMP_CPU_HEADER 1 -typedef unsigned long grub_jmp_buf[21]; +typedef unsigned long grub_jmp_buf[20]; -int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; +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/priority_queue.h b/include/grub/priority_queue.h deleted file mode 100644 index 64cbc4512..000000000 --- a/include/grub/priority_queue.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_PRIORITY_QUEUE_HEADER -#define GRUB_PRIORITY_QUEUE_HEADER 1 - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct grub_priority_queue; -typedef struct grub_priority_queue *grub_priority_queue_t; -typedef int (*grub_comparator_t) (const void *a, const void *b); - -grub_priority_queue_t grub_priority_queue_new (grub_size_t elsize, - grub_comparator_t cmp); -void grub_priority_queue_destroy (grub_priority_queue_t pq); -void *grub_priority_queue_top (grub_priority_queue_t pq); -void grub_priority_queue_pop (grub_priority_queue_t pq); -grub_err_t grub_priority_queue_push (grub_priority_queue_t pq, const void *el); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/grub/procfs.h b/include/grub/procfs.h deleted file mode 100644 index 8cc331d94..000000000 --- a/include/grub/procfs.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_PROCFS_HEADER -#define GRUB_PROCFS_HEADER 1 - -#include -#include - -struct grub_procfs_entry -{ - struct grub_procfs_entry *next; - struct grub_procfs_entry **prev; - - const char *name; - char * (*get_contents) (grub_size_t *sz); -}; - -extern struct grub_procfs_entry *grub_procfs_entries; - -static inline void -grub_procfs_register (const char *name __attribute__ ((unused)), - struct grub_procfs_entry *entry) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_procfs_entries), - GRUB_AS_LIST (entry)); -} - -static inline void -grub_procfs_unregister (struct grub_procfs_entry *entry) -{ - grub_list_remove (GRUB_AS_LIST (entry)); -} - - -#endif diff --git a/include/grub/ps2.h b/include/grub/ps2.h deleted file mode 100644 index 4f2e527e4..000000000 --- a/include/grub/ps2.h +++ /dev/null @@ -1,43 +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 . - */ - -#ifndef GRUB_PS2_HEADER -#define GRUB_PS2_HEADER 1 - -#include - -#define GRUB_AT_ACK 0xfa -#define GRUB_AT_NACK 0xfe -#define GRUB_AT_TRIES 5 - -/* Make sure it's zeroed-out and set current_set at init. */ -struct grub_ps2_state -{ - int e0_received; - int f0_received; - grub_uint8_t led_status; - short at_keyboard_status; - grub_uint8_t current_set; -}; - -/* If there is a key pending, return it; otherwise return GRUB_TERM_NO_KEY. */ -int -grub_ps2_process_incoming_byte (struct grub_ps2_state *ps2_state, - grub_uint8_t data); - -#endif diff --git a/include/grub/pubkey.h b/include/grub/pubkey.h deleted file mode 100644 index fb8be9cbb..000000000 --- a/include/grub/pubkey.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_PUBKEY_HEADER -#define GRUB_PUBKEY_HEADER 1 - -#include - -struct grub_public_key * -grub_load_public_key (grub_file_t f); - -grub_err_t -grub_verify_signature (grub_file_t f, const char *fsig, - struct grub_public_key *pk); - - -struct grub_public_subkey * -grub_crypto_pk_locate_subkey (grub_uint64_t keyid, struct grub_public_key *pkey); - -struct grub_public_subkey * -grub_crypto_pk_locate_subkey_in_trustdb (grub_uint64_t keyid); - -#endif diff --git a/include/grub/raid.h b/include/grub/raid.h new file mode 100644 index 000000000..8fa4c3814 --- /dev/null +++ b/include/grub/raid.h @@ -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 . + */ + +#ifndef GRUB_RAID_H +#define GRUB_RAID_H 1 + +#include + +#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". */ + 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/random.h b/include/grub/random.h deleted file mode 100644 index 4b75c0e2b..000000000 --- a/include/grub/random.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2016 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_RANDOM_HEADER -#define GRUB_RANDOM_HEADER 1 - -#include -#include - -/* Not peer-reviewed. May not be any better than string of zeros. */ -grub_err_t -grub_crypto_get_random (void *buffer, grub_size_t sz); - -/* Do not use directly. Use grub_crypto_get_random instead. */ -int -grub_crypto_arch_get_random (void *buffer, grub_size_t sz); - -#endif diff --git a/include/grub/reader.h b/include/grub/reader.h index fd86b20cb..fd72a3252 100644 --- a/include/grub/reader.h +++ b/include/grub/reader.h @@ -22,8 +22,8 @@ #include -typedef grub_err_t (*grub_reader_getline_t) (char **, int, void *); +typedef grub_err_t (*grub_reader_getline_t) (char **, int); -void grub_rescue_run (void) __attribute__ ((noreturn)); +void grub_rescue_run (void); #endif /* ! GRUB_READER_HEADER */ diff --git a/include/grub/reed_solomon.h b/include/grub/reed_solomon.h deleted file mode 100644 index 596dff246..000000000 --- a/include/grub/reed_solomon.h +++ /dev/null @@ -1,30 +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 . - */ - -#ifndef GRUB_REED_SOLOMON_HEADER -#define GRUB_REED_SOLOMON_HEADER 1 - -void -grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size, - grub_size_t redundancy); - -void -grub_reed_solomon_recover (void *buffer, grub_size_t data_size, - grub_size_t redundancy); - -#endif diff --git a/include/grub/relocator.h b/include/grub/relocator.h deleted file mode 100644 index bda322057..000000000 --- a/include/grub/relocator.h +++ /dev/null @@ -1,88 +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 . - */ - -#ifndef GRUB_RELOCATOR_HEADER -#define GRUB_RELOCATOR_HEADER 1 - -#include -#include -#include -#include - -struct grub_relocator; -struct grub_relocator_chunk; -typedef const struct grub_relocator_chunk *grub_relocator_chunk_t; - -struct grub_relocator *grub_relocator_new (void); - -grub_err_t -grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, - grub_relocator_chunk_t *out, - grub_phys_addr_t target, grub_size_t size); - -void * -get_virtual_current_address (grub_relocator_chunk_t in); -grub_phys_addr_t -get_physical_target_address (grub_relocator_chunk_t in); - -grub_err_t -grub_relocator_alloc_chunk_align (struct grub_relocator *rel, - grub_relocator_chunk_t *out, - grub_phys_addr_t min_addr, - grub_phys_addr_t max_addr, - grub_size_t size, grub_size_t align, - int preference, - int avoid_efi_boot_services); - -/* - * Wrapper for grub_relocator_alloc_chunk_align() with purpose of - * protecting against integer underflow. - * - * Compare to its callee, max_addr has different meaning here. - * It covers entire chunk and not just start address of the chunk. - */ -static inline grub_err_t -grub_relocator_alloc_chunk_align_safe (struct grub_relocator *rel, - grub_relocator_chunk_t *out, - grub_phys_addr_t min_addr, - grub_phys_addr_t max_addr, - grub_size_t size, grub_size_t align, - int preference, - int avoid_efi_boot_services) -{ - /* Sanity check and ensure following equation (max_addr - size) is safe. */ - if (max_addr < size || (max_addr - size) < min_addr) - return GRUB_ERR_OUT_OF_RANGE; - - return grub_relocator_alloc_chunk_align (rel, out, min_addr, - max_addr - size, - size, align, preference, - avoid_efi_boot_services); -} - -/* Top 32-bit address minus s bytes and plus 1 byte. */ -#define UP_TO_TOP32(s) ((~(s) & 0xffffffff) + 1) - -#define GRUB_RELOCATOR_PREFERENCE_NONE 0 -#define GRUB_RELOCATOR_PREFERENCE_LOW 1 -#define GRUB_RELOCATOR_PREFERENCE_HIGH 2 - -void -grub_relocator_unload (struct grub_relocator *rel); - -#endif diff --git a/include/grub/relocator_private.h b/include/grub/relocator_private.h deleted file mode 100644 index d8e972e01..000000000 --- a/include/grub/relocator_private.h +++ /dev/null @@ -1,113 +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 . - */ - -#ifndef GRUB_RELOCATOR_PRIVATE_HEADER -#define GRUB_RELOCATOR_PRIVATE_HEADER 1 - -#include -#include -#include - -extern grub_size_t grub_relocator_align; -extern grub_size_t grub_relocator_forward_size; -extern grub_size_t grub_relocator_backward_size; -extern grub_size_t grub_relocator_jumper_size; - -void -grub_cpu_relocator_init (void); -grub_err_t -grub_relocator_prepare_relocs (struct grub_relocator *rel, - grub_addr_t addr, - void **relstart, grub_size_t *relsize); -void grub_cpu_relocator_forward (void *rels, void *src, void *tgt, - grub_size_t size); -void grub_cpu_relocator_backward (void *rels, void *src, void *tgt, - grub_size_t size); -void grub_cpu_relocator_jumper (void *rels, grub_addr_t addr); - -/* Remark: GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT_LOG = 1 or 2 - aren't supported. */ -#ifdef GRUB_MACHINE_IEEE1275 -#define GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS 1 -#define GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT_LOG 0 -#elif defined (GRUB_MACHINE_EFI) -#define GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS 1 -#define GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT_LOG 12 -#else -#define GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS 0 -#endif - -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS && GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT_LOG != 0 -#define GRUB_RELOCATOR_HAVE_LEFTOVERS 1 -#else -#define GRUB_RELOCATOR_HAVE_LEFTOVERS 0 -#endif - -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS -#define GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT (1 << GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT_LOG) -#endif - -struct grub_relocator_mmap_event -{ - enum { - IN_REG_START = 0, - IN_REG_END = 1, - REG_BEG_START = 2, - REG_BEG_END = REG_BEG_START | 1, -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - REG_FIRMWARE_START = 4, - REG_FIRMWARE_END = REG_FIRMWARE_START | 1, - /* To track the regions already in heap. */ - FIRMWARE_BLOCK_START = 6, - FIRMWARE_BLOCK_END = FIRMWARE_BLOCK_START | 1, -#endif -#if GRUB_RELOCATOR_HAVE_LEFTOVERS - REG_LEFTOVER_START = 8, - REG_LEFTOVER_END = REG_LEFTOVER_START | 1, -#endif - COLLISION_START = 10, - COLLISION_END = COLLISION_START | 1 - } type; - grub_phys_addr_t pos; - union - { - struct - { - grub_mm_region_t reg; - grub_mm_header_t hancestor; - grub_mm_region_t *regancestor; - grub_mm_header_t head; - }; -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS - struct grub_relocator_fw_leftover *leftover; -#endif - }; -}; - -/* Return 0 on failure, 1 on success. The failure here - can be very time-expensive, so please make sure fill events is accurate. */ -#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS -int grub_relocator_firmware_alloc_region (grub_phys_addr_t start, - grub_size_t size); -unsigned grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events); -unsigned grub_relocator_firmware_get_max_events (void); -void grub_relocator_firmware_free_region (grub_phys_addr_t start, - grub_size_t size); -#endif - -#endif diff --git a/include/grub/riscv32/efi/memory.h b/include/grub/riscv32/efi/memory.h deleted file mode 100644 index e61c474ff..000000000 --- a/include/grub/riscv32/efi/memory.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef GRUB_MEMORY_CPU_HEADER -#include - -#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffUL - -#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/riscv32/setjmp.h b/include/grub/riscv32/setjmp.h deleted file mode 100644 index 5a2123846..000000000 --- a/include/grub/riscv32/setjmp.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_SETJMP_CPU_HEADER -#define GRUB_SETJMP_CPU_HEADER 1 - -typedef unsigned long long grub_jmp_buf[14]; - -int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; -void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); - -#endif /* ! GRUB_SETJMP_CPU_HEADER */ diff --git a/include/grub/riscv32/time.h b/include/grub/riscv32/time.h deleted file mode 100644 index 20abd648b..000000000 --- a/include/grub/riscv32/time.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef KERNEL_CPU_TIME_HEADER -#define KERNEL_CPU_TIME_HEADER 1 - -static __inline void -grub_cpu_idle (void) -{ - /* TODO */ -} - -#endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/riscv32/types.h b/include/grub/riscv32/types.h deleted file mode 100644 index fac57a752..000000000 --- a/include/grub/riscv32/types.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#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 - -/* currently only support little-endian. */ -#undef GRUB_TARGET_WORDS_BIGENDIAN - -/* Unaligned accesses can be very slow, so avoid them */ -#undef GRUB_HAVE_UNALIGNED_ACCESS - -#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/riscv64/efi/memory.h b/include/grub/riscv64/efi/memory.h deleted file mode 100644 index c6cb32417..000000000 --- a/include/grub/riscv64/efi/memory.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef GRUB_MEMORY_CPU_HEADER -#include - -#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffULL - -#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/riscv64/setjmp.h b/include/grub/riscv64/setjmp.h deleted file mode 100644 index 5a2123846..000000000 --- a/include/grub/riscv64/setjmp.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_SETJMP_CPU_HEADER -#define GRUB_SETJMP_CPU_HEADER 1 - -typedef unsigned long long grub_jmp_buf[14]; - -int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; -void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); - -#endif /* ! GRUB_SETJMP_CPU_HEADER */ diff --git a/include/grub/riscv64/time.h b/include/grub/riscv64/time.h deleted file mode 100644 index 20abd648b..000000000 --- a/include/grub/riscv64/time.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef KERNEL_CPU_TIME_HEADER -#define KERNEL_CPU_TIME_HEADER 1 - -static __inline void -grub_cpu_idle (void) -{ - /* TODO */ -} - -#endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/riscv64/types.h b/include/grub/riscv64/types.h deleted file mode 100644 index c6bcad470..000000000 --- a/include/grub/riscv64/types.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#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 - -/* currently only support little-endian. */ -#undef GRUB_TARGET_WORDS_BIGENDIAN - -/* Unaligned accesses can be very slow, so avoid them */ -#undef GRUB_HAVE_UNALIGNED_ACCESS - -#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/safemath.h b/include/grub/safemath.h deleted file mode 100644 index e032f63a0..000000000 --- a/include/grub/safemath.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2020 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - * - * Arithmetic operations that protect against overflow. - */ - -#ifndef GRUB_SAFEMATH_H -#define GRUB_SAFEMATH_H 1 - -#include - -/* These appear in gcc 5.1 and clang 8.0. */ -#if GNUC_PREREQ(5, 1) || CLANG_PREREQ(8, 0) - -#define grub_add(a, b, res) __builtin_add_overflow(a, b, res) -#define grub_sub(a, b, res) __builtin_sub_overflow(a, b, res) -#define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res) - -#define grub_cast(a, res) grub_add ((a), 0, (res)) - -/* - * It's caller's responsibility to check "align" does not equal 0 and - * is power of 2. - */ -#define ALIGN_UP_OVF(v, align, res) \ -({ \ - bool __failed; \ - typeof(v) __a = ((typeof(v))(align) - 1); \ - \ - __failed = grub_add (v, __a, res); \ - if (__failed == false) \ - *(res) &= ~__a; \ - __failed; \ -}) - -#else -#error gcc 5.1 or newer or clang 8.0 or newer is required -#endif - -#endif /* GRUB_SAFEMATH_H */ diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index e5b4d8450..f6177b02a 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -1,7 +1,7 @@ /* normal_parser.h */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2007,2009,2010 Free Software Foundation, Inc. + * 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 @@ -23,7 +23,6 @@ #include #include #include -#include struct grub_script_mem; @@ -40,24 +39,14 @@ struct grub_script_cmd struct grub_script { - unsigned refcnt; struct grub_script_mem *mem; struct grub_script_cmd *cmd; - - /* grub_scripts from block arguments. */ - struct grub_script *next_siblings; - struct grub_script *children; }; typedef enum { - GRUB_SCRIPT_ARG_TYPE_VAR, - GRUB_SCRIPT_ARG_TYPE_TEXT, - GRUB_SCRIPT_ARG_TYPE_GETTEXT, - GRUB_SCRIPT_ARG_TYPE_DQVAR, - GRUB_SCRIPT_ARG_TYPE_DQSTR, - GRUB_SCRIPT_ARG_TYPE_SQSTR, - GRUB_SCRIPT_ARG_TYPE_BLOCK + GRUB_SCRIPT_ARG_TYPE_STR, + GRUB_SCRIPT_ARG_TYPE_VAR } grub_script_arg_type_t; /* A part of an argument. */ @@ -67,29 +56,10 @@ struct grub_script_arg char *str; - /* Parsed block argument. */ - struct grub_script *script; - /* Next argument part. */ struct grub_script_arg *next; }; -/* An argument vector. */ -struct grub_script_argv -{ - unsigned argc; - char **args; - struct grub_script *script; -}; - -/* Pluggable wildcard translator. */ -struct grub_script_wildcard_translator -{ - grub_err_t (*expand) (const char *str, char ***expansions); -}; -extern struct grub_script_wildcard_translator *grub_wildcard_translator; -extern struct grub_script_wildcard_translator grub_filename_translator; - /* A complete argument. It consists of a list of one or more `struct grub_script_arg's. */ struct grub_script_arglist @@ -109,6 +79,15 @@ struct grub_script_cmdline 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 { @@ -124,52 +103,44 @@ struct grub_script_cmdif struct grub_script_cmd *exec_on_false; }; -/* A for statement. */ -struct grub_script_cmdfor +/* A menu entry generate statement. */ +struct grub_script_cmd_menuentry { struct grub_script_cmd cmd; - /* The name used as looping variable. */ - struct grub_script_arg *name; + /* The arguments for this menu entry. */ + struct grub_script_arglist *arglist; - /* The words loop iterates over. */ - struct grub_script_arglist *words; + /* The sourcecode the entry will be generated from. */ + const char *sourcecode; - /* 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; + /* Options. XXX: Not used yet. */ + int options; }; /* State of the lexer as passed to the lexer. */ struct grub_lexer_param { + /* Set to 0 when the lexer is done. */ + int done; + + /* State of the state machine. */ + grub_parser_state_t state; + /* Function used by the lexer to get a new line when more input is expected, but not available. */ grub_reader_getline_t getline; - /* Caller-supplied data passed to `getline'. */ - void *getline_data; - /* 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; + /* The character stream that has to be parsed. */ + char *script; + char *newscript; /* XXX */ + /* 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. */ @@ -186,37 +157,13 @@ struct grub_lexer_param /* Size of RECORDING. */ int recordlen; - /* End of file reached. */ - int eof; + /* The token that is already parsed but not yet returned. */ + int tokenonhold; - /* 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; - - /* Flag to indicate resplit in progres. */ - unsigned resplit; - - /* Text that is unput. */ - char *prefix; - - /* Flex scanner. */ - void *yyscanner; - - /* Flex scanner buffer. */ - void *buffer; + /* Was the last token a newline? */ + int was_newline; }; -#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 { @@ -230,27 +177,12 @@ struct grub_parser_param /* The memory that was used while parsing and scanning. */ struct grub_script_mem *memused; - /* The block argument scripts. */ - struct grub_script *scripts; - /* The result of the parser. */ struct grub_script_cmd *parsed; struct grub_lexer_param *lexerstate; }; -void grub_script_init (void); -void grub_script_fini (void); - -void grub_script_mem_free (struct grub_script_mem *mem); - -void grub_script_argv_free (struct grub_script_argv *argv); -int grub_script_argv_make (struct grub_script_argv *argv, int argc, char **args); -int grub_script_argv_next (struct grub_script_argv *argv); -int grub_script_argv_append (struct grub_script_argv *argv, const char *s, - grub_size_t slen); -int grub_script_argv_split_append (struct grub_script_argv *argv, const char *s); - struct grub_script_arglist * grub_script_create_arglist (struct grub_parser_param *state); @@ -261,6 +193,8 @@ grub_script_add_arglist (struct grub_parser_param *state, 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, @@ -269,44 +203,32 @@ grub_script_create_cmdif (struct grub_parser_param *state, 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); +grub_script_create_cmdmenu (struct grub_parser_param *state, + struct grub_script_arglist *arglist, + char *sourcecode, + int options); 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_append_cmd (struct grub_parser_param *state, - struct grub_script_cmd *list, - struct grub_script_cmd *last); +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_func, - void *getline_func_data); + 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_func, - void *getline_func_data); -void grub_script_lexer_fini (struct grub_lexer_param *); +struct grub_lexer_param *grub_script_lexer_init (char *s, + grub_reader_getline_t getline); void grub_script_lexer_ref (struct grub_lexer_param *); void grub_script_lexer_deref (struct grub_lexer_param *); -unsigned grub_script_lexer_record_start (struct grub_parser_param *); -char *grub_script_lexer_record_stop (struct grub_parser_param *, unsigned); -int grub_script_lexer_yywrap (struct grub_parser_param *, const char *input); -void grub_script_lexer_record (struct grub_parser_param *, char *); +void grub_script_lexer_record_start (struct grub_lexer_param *); +char *grub_script_lexer_record_stop (struct grub_lexer_param *); /* Functions to track allocated memory. */ struct grub_script_mem *grub_script_mem_record (struct grub_parser_param *state); @@ -318,31 +240,16 @@ void *grub_script_malloc (struct grub_parser_param *state, grub_size_t size); 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 *, const char *); +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_cmdlist (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); -grub_err_t grub_script_execute_sourcecode (const char *source); -grub_err_t grub_script_execute_new_scope (const char *source, int argc, char **args); - -/* Break command for loops. */ -grub_err_t grub_script_break (grub_command_t cmd, int argc, char *argv[]); - -/* SHIFT command for GRUB script. */ -grub_err_t grub_script_shift (grub_command_t cmd, int argc, char *argv[]); - -/* SETPARAMS command for GRUB script functions. */ -grub_err_t grub_script_setparams (grub_command_t cmd, int argc, char *argv[]); - -/* RETURN command for functions. */ -grub_err_t grub_script_return (grub_command_t cmd, int argc, char *argv[]); /* This variable points to the parsed command. This is used to communicate with the bison code. */ @@ -359,52 +266,25 @@ struct grub_script_function /* The script function. */ struct grub_script *func; + /* The flags. */ + unsigned flags; + /* The next element. */ struct grub_script_function *next; - unsigned executing; + int references; }; typedef struct grub_script_function *grub_script_function_t; -extern grub_script_function_t grub_script_function_list; - -#define FOR_SCRIPT_FUNCTIONS(var) for((var) = grub_script_function_list; \ - (var); (var) = (var)->next) - 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); -grub_err_t 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); - -grub_err_t -grub_normal_parse_line (char *line, - grub_reader_getline_t getline_func, - void *getline_func_data); - -static inline struct grub_script * -grub_script_ref (struct grub_script *script) -{ - if (script) - script->refcnt++; - return script; -} - -static inline void -grub_script_unref (struct grub_script *script) -{ - if (! script) - return; - - if (script->refcnt == 0) - grub_script_free (script); - else - script->refcnt--; -} +char * +grub_script_execute_argument_to_string (struct grub_script_arg *arg); #endif /* ! GRUB_NORMAL_PARSER_HEADER */ diff --git a/include/grub/scsi.h b/include/grub/scsi.h index a919a7c64..fbe4582ca 100644 --- a/include/grub/scsi.h +++ b/include/grub/scsi.h @@ -19,8 +19,6 @@ #ifndef GRUB_SCSI_H #define GRUB_SCSI_H 1 -#include - typedef struct grub_scsi_dev *grub_scsi_dev_t; void grub_scsi_dev_register (grub_scsi_dev_t dev); @@ -28,38 +26,16 @@ void grub_scsi_dev_unregister (grub_scsi_dev_t dev); struct grub_scsi; -enum - { - GRUB_SCSI_SUBSYSTEM_USBMS, - GRUB_SCSI_SUBSYSTEM_PATA, - GRUB_SCSI_SUBSYSTEM_AHCI, - GRUB_SCSI_NUM_SUBSYSTEMS - }; - -extern const char grub_scsi_names[GRUB_SCSI_NUM_SUBSYSTEMS][5]; - -#define GRUB_SCSI_ID_SUBSYSTEM_SHIFT 24 -#define GRUB_SCSI_ID_BUS_SHIFT 8 -#define GRUB_SCSI_ID_LUN_SHIFT 0 - -static inline grub_uint32_t -grub_make_scsi_id (int subsystem, int bus, int lun) -{ - return (subsystem << GRUB_SCSI_ID_SUBSYSTEM_SHIFT) - | (bus << GRUB_SCSI_ID_BUS_SHIFT) | (lun << GRUB_SCSI_ID_LUN_SHIFT); -} - -typedef int (*grub_scsi_dev_iterate_hook_t) (int id, int bus, int luns, - void *data); - struct grub_scsi_dev { + /* The device name. */ + const char *name; + /* Call HOOK with each device name, until HOOK returns non-zero. */ - int (*iterate) (grub_scsi_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull); + int (*iterate) (int (*hook) (const char *name, int luns)); /* Open the device named NAME, and set up SCSI. */ - grub_err_t (*open) (int id, int bus, struct grub_scsi *scsi); + grub_err_t (*open) (const char *name, struct grub_scsi *scsi); /* Close the scsi device SCSI. */ void (*close) (struct grub_scsi *scsi); @@ -72,7 +48,7 @@ struct grub_scsi_dev /* 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, const char *buf); + grub_size_t size, char *buf); /* The next scsi device. */ struct grub_scsi_dev *next; @@ -80,14 +56,15 @@ struct grub_scsi_dev 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; - int bus; - /* Number of LUNs. */ int luns; @@ -97,11 +74,11 @@ struct grub_scsi /* Set to 0 when not removable, 1 when removable. */ int removable; - /* Size of the device in blocks - 1. */ - grub_uint64_t last_block; + /* Size of the device in blocks. */ + int size; /* Size of one block. */ - grub_uint32_t blocksize; + int blocksize; /* Device-specific data. */ void *data; diff --git a/include/grub/scsicmd.h b/include/grub/scsicmd.h index 3f1e6d28c..40f237a17 100644 --- a/include/grub/scsicmd.h +++ b/include/grub/scsicmd.h @@ -25,27 +25,15 @@ #define GRUB_SCSI_REMOVABLE_BIT 7 #define GRUB_SCSI_LUN_SHIFT 5 -struct grub_scsi_test_unit_ready -{ - grub_uint8_t opcode; - grub_uint8_t lun; /* 7-5 LUN, 4-0 reserved */ - grub_uint8_t reserved1; - grub_uint8_t reserved2; - grub_uint8_t reserved3; - grub_uint8_t control; - grub_uint8_t pad[6]; /* To be ATAPI compatible */ -} GRUB_PACKED; - struct grub_scsi_inquiry { grub_uint8_t opcode; - grub_uint8_t lun; /* 7-5 LUN, 4-1 reserved, 0 EVPD */ - grub_uint8_t page; /* page code if EVPD=1 */ - grub_uint8_t reserved; - grub_uint8_t alloc_length; - grub_uint8_t control; - grub_uint8_t pad[6]; /* To be ATAPI compatible */ -} GRUB_PACKED; + 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 { @@ -57,68 +45,21 @@ struct grub_scsi_inquiry_data char vendor[8]; char prodid[16]; char prodrev[4]; -} GRUB_PACKED; +} __attribute__((packed)); -struct grub_scsi_request_sense +struct grub_scsi_read_capacity { grub_uint8_t opcode; - grub_uint8_t lun; /* 7-5 LUN, 4-0 reserved */ - grub_uint8_t reserved1; - grub_uint8_t reserved2; - grub_uint8_t alloc_length; - grub_uint8_t control; - grub_uint8_t pad[6]; /* To be ATAPI compatible */ -} GRUB_PACKED; + grub_uint8_t lun; + grub_uint8_t reserved[8]; + grub_uint8_t pad[2]; +} __attribute__((packed)); -struct grub_scsi_request_sense_data +struct grub_scsi_read_capacity_data { - grub_uint8_t error_code; /* 7 Valid, 6-0 Err. code */ - grub_uint8_t segment_number; - grub_uint8_t sense_key; /*7 FileMark, 6 EndOfMedia, 5 ILI, 4-0 sense key */ - grub_uint32_t information; - grub_uint8_t additional_sense_length; - grub_uint32_t cmd_specific_info; - grub_uint8_t additional_sense_code; - grub_uint8_t additional_sense_code_qualifier; - grub_uint8_t field_replaceable_unit_code; - grub_uint8_t sense_key_specific[3]; - /* there can be additional sense field */ -} GRUB_PACKED; - -struct grub_scsi_read_capacity10 -{ - grub_uint8_t opcode; - grub_uint8_t lun; /* 7-5 LUN, 4-1 reserved, 0 reserved */ - grub_uint32_t logical_block_addr; /* only if PMI=1 */ - grub_uint8_t reserved1; - grub_uint8_t reserved2; - grub_uint8_t PMI; - grub_uint8_t control; - grub_uint16_t pad; /* To be ATAPI compatible */ -} GRUB_PACKED; - -struct grub_scsi_read_capacity10_data -{ - grub_uint32_t last_block; + grub_uint32_t size; grub_uint32_t blocksize; -} GRUB_PACKED; - -struct grub_scsi_read_capacity16 -{ - grub_uint8_t opcode; - grub_uint8_t lun; /* 7-5 LUN, 4-0 0x10 */ - grub_uint64_t logical_block_addr; /* only if PMI=1 */ - grub_uint32_t alloc_len; - grub_uint8_t PMI; - grub_uint8_t control; -} GRUB_PACKED; - -struct grub_scsi_read_capacity16_data -{ - grub_uint64_t last_block; - grub_uint32_t blocksize; - grub_uint8_t pad[20]; -} GRUB_PACKED; +} __attribute__((packed)); struct grub_scsi_read10 { @@ -129,7 +70,7 @@ struct grub_scsi_read10 grub_uint16_t size; grub_uint8_t reserved2; grub_uint16_t pad; -} GRUB_PACKED; +} __attribute__((packed)); struct grub_scsi_read12 { @@ -139,17 +80,7 @@ struct grub_scsi_read12 grub_uint32_t size; grub_uint8_t reserved; grub_uint8_t control; -} GRUB_PACKED; - -struct grub_scsi_read16 -{ - grub_uint8_t opcode; - grub_uint8_t lun; - grub_uint64_t lba; - grub_uint32_t size; - grub_uint8_t reserved; - grub_uint8_t control; -} GRUB_PACKED; +} __attribute__((packed)); struct grub_scsi_write10 { @@ -160,7 +91,7 @@ struct grub_scsi_write10 grub_uint16_t size; grub_uint8_t reserved2; grub_uint16_t pad; -} GRUB_PACKED; +} __attribute__((packed)); struct grub_scsi_write12 { @@ -170,31 +101,16 @@ struct grub_scsi_write12 grub_uint32_t size; grub_uint8_t reserved; grub_uint8_t control; -} GRUB_PACKED; - -struct grub_scsi_write16 -{ - grub_uint8_t opcode; - grub_uint8_t lun; - grub_uint64_t lba; - grub_uint32_t size; - grub_uint8_t reserved; - grub_uint8_t control; -} GRUB_PACKED; +} __attribute__((packed)); typedef enum { - grub_scsi_cmd_test_unit_ready = 0x00, - grub_scsi_cmd_request_sense = 0x03, grub_scsi_cmd_inquiry = 0x12, - grub_scsi_cmd_read_capacity10 = 0x25, + grub_scsi_cmd_read_capacity = 0x25, grub_scsi_cmd_read10 = 0x28, grub_scsi_cmd_write10 = 0x2a, - grub_scsi_cmd_read16 = 0x88, - grub_scsi_cmd_write16 = 0x8a, - grub_scsi_cmd_read_capacity16 = 0x9e, grub_scsi_cmd_read12 = 0xa8, - grub_scsi_cmd_write12 = 0xaa, + grub_scsi_cmd_write12 = 0xaa } grub_scsi_cmd_t; typedef enum diff --git a/include/grub/sdl.h b/include/grub/sdl.h deleted file mode 100644 index 8f10b8817..000000000 --- a/include/grub/sdl.h +++ /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 . - */ -#include - -void EXPORT_FUNC (SDL_Quit) (void); -void EXPORT_FUNC (SDL_Init) (void); -void EXPORT_FUNC (SDL_GetError) (void); -#ifdef HAVE_SDL2 -void EXPORT_FUNC (SDL_CreateWindow) (void); -void EXPORT_FUNC (SDL_GetWindowSurface) (void); -void EXPORT_FUNC (SDL_CreateRenderer) (void); -void EXPORT_FUNC (SDL_CreateRGBSurface) (void); -void EXPORT_FUNC (SDL_CreateTexture) (void); -void EXPORT_FUNC (SDL_UpdateTexture) (void); -void EXPORT_FUNC (SDL_SetPaletteColors) (void); -void EXPORT_FUNC (SDL_RenderClear) (void); -void EXPORT_FUNC (SDL_RenderCopy) (void); -void EXPORT_FUNC (SDL_RenderPresent) (void); -#else -void EXPORT_FUNC (SDL_Flip) (void); -void EXPORT_FUNC (SDL_SetColors) (void); -void EXPORT_FUNC (SDL_SetVideoMode) (void); -#endif diff --git a/include/grub/search.h b/include/grub/search.h index 3eabaf0cc..e8f9db285 100644 --- a/include/grub/search.h +++ b/include/grub/search.h @@ -19,22 +19,8 @@ #ifndef GRUB_SEARCH_HEADER #define GRUB_SEARCH_HEADER 1 -enum search_flags - { - SEARCH_FLAGS_NONE = 0, - SEARCH_FLAGS_NO_FLOPPY = 1, - SEARCH_FLAGS_EFIDISK_ONLY = 2, - SEARCH_FLAGS_CRYPTODISK_ONLY = 4 - }; - -void grub_search_fs_file (const char *key, const char *var, - enum search_flags flags, - char **hints, unsigned nhints); -void grub_search_fs_uuid (const char *key, const char *var, - enum search_flags flags, - char **hints, unsigned nhints); -void grub_search_label (const char *key, const char *var, - enum search_flags flags, - char **hints, unsigned nhints); +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 index d7e063578..1c35b4093 100644 --- a/include/grub/serial.h +++ b/include/grub/serial.h @@ -1,7 +1,7 @@ /* serial.h - serial device interface */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010 Free Software Foundation, Inc. + * 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 @@ -20,210 +20,48 @@ #ifndef GRUB_SERIAL_HEADER #define GRUB_SERIAL_HEADER 1 -#include -#if defined(__mips__) || defined (__i386__) || defined (__x86_64__) -#include -#endif -#include -#include -#include -#ifdef GRUB_MACHINE_IEEE1275 -#include -#endif -#ifdef GRUB_MACHINE_ARC -#include -#endif +/* Macros. */ -struct grub_serial_port; -struct grub_serial_config; +/* 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 -struct grub_serial_driver -{ - grub_err_t (*configure) (struct grub_serial_port *port, - struct grub_serial_config *config); - int (*fetch) (struct grub_serial_port *port); - void (*put) (struct grub_serial_port *port, const int c); - void (*fini) (struct grub_serial_port *port); -}; +/* For LSR bits. */ +#define UART_DATA_READY 0x01 +#define UART_EMPTY_TRANSMITTER 0x20 /* The type of parity. */ -typedef enum - { - GRUB_SERIAL_PARITY_NONE, - GRUB_SERIAL_PARITY_ODD, - GRUB_SERIAL_PARITY_EVEN, - } grub_serial_parity_t; +#define UART_NO_PARITY 0x00 +#define UART_ODD_PARITY 0x08 +#define UART_EVEN_PARITY 0x18 -typedef enum - { - GRUB_SERIAL_STOP_BITS_1, - GRUB_SERIAL_STOP_BITS_1_5, - GRUB_SERIAL_STOP_BITS_2, - } grub_serial_stop_bits_t; +/* 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 -struct grub_serial_config -{ - unsigned speed; - int word_len; - grub_serial_parity_t parity; - grub_serial_stop_bits_t stop_bits; - grub_uint64_t base_clock; - int rtscts; -}; +/* The type of the length of stop bit. */ +#define UART_1_STOP_BIT 0x00 +#define UART_2_STOP_BITS 0x04 -struct grub_serial_port -{ - struct grub_serial_port *next; - struct grub_serial_port **prev; - char *name; - struct grub_serial_driver *driver; - struct grub_serial_config config; - int configured; - int broken; +/* the switch of DLAB. */ +#define UART_DLAB 0x80 - /* This should be void *data but since serial is useful as an early console - when malloc isn't available it's a union. - */ - union - { - struct - { - bool use_mmio; - union - { -#if defined(__mips__) || defined (__i386__) || defined (__x86_64__) - grub_port_t port; -#endif - struct - { - grub_addr_t base; - /* Access size uses ACPI definition */ - grub_uint8_t access_size; - } mmio; - }; - }; - struct - { - grub_usb_device_t usbdev; - int configno; - int interfno; - char buf[64]; - int bufstart, bufend; - struct grub_usb_desc_endp *in_endp; - struct grub_usb_desc_endp *out_endp; - }; - struct grub_escc_descriptor *escc_desc; -#ifdef GRUB_MACHINE_IEEE1275 - struct - { - grub_ieee1275_ihandle_t handle; - struct ofserial_hash_ent *elem; - }; -#endif -#ifdef GRUB_MACHINE_EFI - struct grub_efi_serial_io_interface *interface; -#endif -#ifdef GRUB_MACHINE_ARC - struct - { - grub_arc_fileno_t handle; - int handle_valid; - }; -#endif - }; - grub_term_output_t term_out; - grub_term_input_t term_in; -}; +/* Enable the FIFO. */ +#define UART_ENABLE_FIFO 0xC7 -grub_err_t EXPORT_FUNC(grub_serial_register) (struct grub_serial_port *port); +/* Turn on DTR, RTS, and OUT2. */ +#define UART_ENABLE_MODEM 0x0B -void EXPORT_FUNC(grub_serial_unregister) (struct grub_serial_port *port); - - /* Convenience functions to perform primitive operations on a port. */ -static inline grub_err_t -grub_serial_port_configure (struct grub_serial_port *port, - struct grub_serial_config *config) -{ - return port->driver->configure (port, config); -} - -static inline int -grub_serial_port_fetch (struct grub_serial_port *port) -{ - return port->driver->fetch (port); -} - -static inline void -grub_serial_port_put (struct grub_serial_port *port, const int c) -{ - port->driver->put (port, c); -} - -static inline void -grub_serial_port_fini (struct grub_serial_port *port) -{ - port->driver->fini (port); -} - - /* Set default settings. */ -static inline grub_err_t -grub_serial_config_defaults (struct grub_serial_port *port) -{ - struct grub_serial_config config = - { -#ifdef GRUB_MACHINE_MIPS_LOONGSON - .speed = 115200, - /* On Loongson machines serial port has only 3 wires. */ - .rtscts = 0, -#else - .speed = 9600, - .rtscts = 1, -#endif - .word_len = 8, - .parity = GRUB_SERIAL_PARITY_NONE, - .stop_bits = GRUB_SERIAL_STOP_BITS_1, - .base_clock = 0 - }; - - return port->driver->configure (port, &config); -} - -#if defined(__mips__) || defined (__i386__) || defined (__x86_64__) -void grub_ns8250_init (void); -struct grub_serial_port *grub_ns8250_spcr_init (void); -struct grub_serial_port *grub_serial_ns8250_add_port (grub_port_t port, - struct grub_serial_config *config); -struct grub_serial_port *grub_serial_ns8250_add_mmio (grub_addr_t addr, - unsigned int acc_size, - struct grub_serial_config *config); -#endif -#ifdef GRUB_MACHINE_IEEE1275 -void grub_ofserial_init (void); -#endif -#ifdef GRUB_MACHINE_EFI -void -grub_efiserial_init (void); -#endif -#ifdef GRUB_MACHINE_ARC -void -grub_arcserial_init (void); -struct grub_serial_port *grub_arcserial_add_port (const char *path); -#endif - -#if defined(__i386__) || defined(__x86_64__) -extern void grub_pciserial_init (void); -#endif - -struct grub_serial_port *grub_serial_find (const char *name); -extern struct grub_serial_driver grub_ns8250_driver; -void EXPORT_FUNC(grub_serial_unregister_driver) (struct grub_serial_driver *driver); - -#ifndef GRUB_MACHINE_EMU -extern void grub_serial_init (void); -extern void grub_serial_fini (void); -#endif - -extern struct grub_serial_port *grub_serial_ports; -#define FOR_SERIAL_PORTS(var) FOR_LIST_ELEMENTS((var), (grub_serial_ports)) - -#endif +#endif /* ! GRUB_SERIAL_MACHINE_HEADER */ diff --git a/include/grub/setjmp.h b/include/grub/setjmp.h index 4bba034f4..70147a7d4 100644 --- a/include/grub/setjmp.h +++ b/include/grub/setjmp.h @@ -19,21 +19,12 @@ #ifndef GRUB_SETJMP_HEADER #define GRUB_SETJMP_HEADER 1 -#if defined(GRUB_UTIL) +#if defined(GRUB_UTIL) && !defined(GRUBOF) #include typedef jmp_buf grub_jmp_buf; #define grub_setjmp setjmp #define grub_longjmp longjmp #else - -#include - -#if GNUC_PREREQ(4,0) -#define RETURNS_TWICE __attribute__ ((returns_twice)) -#else -#define RETURNS_TWICE -#endif - /* This must define grub_jmp_buf, and declare grub_setjmp and grub_longjmp. */ # include diff --git a/include/grub/smbios.h b/include/grub/smbios.h deleted file mode 100644 index 15ec260b3..000000000 --- a/include/grub/smbios.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2019 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_SMBIOS_HEADER -#define GRUB_SMBIOS_HEADER 1 - -#include -#include - -#define GRUB_SMBIOS_TYPE_END_OF_TABLE ((grub_uint8_t)127) - -struct grub_smbios_ieps -{ - grub_uint8_t anchor[5]; /* "_DMI_" */ - grub_uint8_t checksum; - grub_uint16_t table_length; - grub_uint32_t table_address; - grub_uint16_t structures; - grub_uint8_t revision; -} GRUB_PACKED; - -struct grub_smbios_eps -{ - grub_uint8_t anchor[4]; /* "_SM_" */ - grub_uint8_t checksum; - grub_uint8_t length; /* 0x1f */ - grub_uint8_t version_major; - grub_uint8_t version_minor; - grub_uint16_t maximum_structure_size; - grub_uint8_t revision; - grub_uint8_t formatted[5]; - struct grub_smbios_ieps intermediate; -} GRUB_PACKED; - -struct grub_smbios_eps3 -{ - grub_uint8_t anchor[5]; /* "_SM3_" */ - grub_uint8_t checksum; - grub_uint8_t length; /* 0x18 */ - grub_uint8_t version_major; - grub_uint8_t version_minor; - grub_uint8_t docrev; - grub_uint8_t revision; - grub_uint8_t reserved; - grub_uint32_t maximum_table_length; - grub_uint64_t table_address; -} GRUB_PACKED; - -extern struct grub_smbios_eps *grub_machine_smbios_get_eps (void); -extern struct grub_smbios_eps3 *grub_machine_smbios_get_eps3 (void); - -extern struct grub_smbios_eps *EXPORT_FUNC (grub_smbios_get_eps) (void); - -#endif /* ! GRUB_SMBIOS_HEADER */ diff --git a/include/grub/smbus.h b/include/grub/smbus.h deleted file mode 100644 index 0b8e6718f..000000000 --- a/include/grub/smbus.h +++ /dev/null @@ -1,70 +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 . - */ - -#ifndef GRUB_SMBUS_HEADER -#define GRUB_SMBUS_HEADER 1 - -#define GRUB_SMB_RAM_START_ADDR 0x50 -#define GRUB_SMB_RAM_NUM_MAX 0x08 - -#define GRUB_SMBUS_SPD_MEMORY_TYPE_ADDR 2 -#define GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2 8 -#define GRUB_SMBUS_SPD_MEMORY_NUM_BANKS_ADDR 17 -#define GRUB_SMBUS_SPD_MEMORY_NUM_ROWS_ADDR 3 -#define GRUB_SMBUS_SPD_MEMORY_NUM_COLUMNS_ADDR 4 -#define GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_ADDR 5 -#define GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_MASK 0x7 -#define GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_ADDR 18 -#define GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE 5 -#define GRUB_SMBUS_SPD_MEMORY_TRAS_ADDR 30 -#define GRUB_SMBUS_SPD_MEMORY_TRTP_ADDR 38 - -#ifndef ASM_FILE - -struct grub_smbus_spd -{ - grub_uint8_t written_size; - grub_uint8_t log_total_flash_size; - grub_uint8_t memory_type; - union - { - grub_uint8_t unknown[253]; - struct { - grub_uint8_t num_rows; - grub_uint8_t num_columns; - grub_uint8_t num_of_ranks; - grub_uint8_t unused1[12]; - grub_uint8_t num_of_banks; - grub_uint8_t unused2[2]; - grub_uint8_t cas_latency; - grub_uint8_t unused3[9]; - grub_uint8_t rank_capacity; - grub_uint8_t unused4[1]; - grub_uint8_t tras; - grub_uint8_t unused5[7]; - grub_uint8_t trtp; - grub_uint8_t unused6[31]; - grub_uint8_t part_number[18]; - grub_uint8_t unused7[165]; - } ddr2; - }; -}; - -#endif - -#endif diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h index cc5a941e3..95f311ce5 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -25,9 +25,7 @@ #define BOOTDEV_REG %l6 #define PIC_REG %l7 -#define SCRATCH_PAD_BOOT 0x5000 -#define SCRATCH_PAD_DISKBOOT 0x4000 -#define SCRATCH_PAD_BOOT_SIZE 0x110 +#define SCRATCH_PAD 0x10000 #define GET_ABS(symbol, reg) \ add PIC_REG, (symbol - pic_base), reg @@ -40,23 +38,21 @@ #define GRUB_BOOT_MACHINE_SIGNATURE 0xbb44aa55 -#define GRUB_BOOT_MACHINE_BOOT_DEVPATH 0x08 +#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_KERNEL_SECTOR 0x88 -#define GRUB_BOOT_MACHINE_CODE_END 0x1fc +#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 0x200000 #define GRUB_BOOT_MACHINE_KERNEL_ADDR 0x4200 -#ifndef ASM_FILE -/* This is the blocklist used in the diskboot image. */ -struct grub_boot_blocklist -{ - grub_uint64_t start; - grub_uint32_t len; -} GRUB_PACKED; -#endif - #endif /* ! BOOT_MACHINE_HEADER */ diff --git a/include/grub/ieee1275/console.h b/include/grub/sparc64/ieee1275/console.h similarity index 76% rename from include/grub/ieee1275/console.h rename to include/grub/sparc64/ieee1275/console.h index a8094d381..ed2b7202a 100644 --- a/include/grub/ieee1275/console.h +++ b/include/grub/sparc64/ieee1275/console.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. + * 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 @@ -17,18 +17,12 @@ */ #ifndef GRUB_CONSOLE_MACHINE_HEADER -#define GRUB_CONSOLE_MACHINE_HEADER 1 - -#include +#define GRUB_CONSOLE_MACHINE_HEADER 1 /* Initialize the console system. */ -void grub_console_init_early (void); -void grub_console_init_lately (void); +void grub_console_init (void); /* Finish the console system. */ void grub_console_fini (void); -struct grub_serial_port * -grub_ofserial_add_port (const char *name); - #endif /* ! GRUB_CONSOLE_MACHINE_HEADER */ diff --git a/include/grub/sparc64/ieee1275/ieee1275.h b/include/grub/sparc64/ieee1275/ieee1275.h index ccc71aac6..527c46ae7 100644 --- a/include/grub/sparc64/ieee1275/ieee1275.h +++ b/include/grub/sparc64/ieee1275/ieee1275.h @@ -25,9 +25,6 @@ #define GRUB_IEEE1275_CELL_SIZEOF 8 typedef grub_uint64_t grub_ieee1275_cell_t; -#define PRIxGRUB_IEEE1275_CELL_T PRIxGRUB_UINT64_T -#define PRIuGRUB_IEEE1275_CELL_T PRIuGRUB_UINT64_T - /* Encoding of 'mode' argument to grub_ieee1275_map_physical() */ #define IEEE1275_MAP_WRITE 0x0001 /* Writable */ #define IEEE1275_MAP_READ 0x0002 /* Readable */ @@ -45,9 +42,5 @@ extern int EXPORT_FUNC(grub_ieee1275_claim_vaddr) (grub_addr_t vaddr, extern int EXPORT_FUNC(grub_ieee1275_alloc_physmem) (grub_addr_t *paddr, grub_size_t size, grub_uint32_t align); -extern grub_uint64_t EXPORT_FUNC(grub_ieee1275_num_blocks) (grub_uint32_t ihandle); -extern grub_uint64_t EXPORT_FUNC(grub_ieee1275_num_blocks64) (grub_uint32_t ihandle); - -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 index 9a00bea61..e63e1f616 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -19,13 +19,41 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 -#define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000 +#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 #ifndef ASM_FILE #include #include +/* 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/efiemu/i386/coredetect.c b/include/grub/sparc64/ieee1275/loader.h similarity index 71% rename from grub-core/efiemu/i386/coredetect.c rename to include/grub/sparc64/ieee1275/loader.h index a262b5328..12bb2a69b 100644 --- a/grub-core/efiemu/i386/coredetect.c +++ b/include/grub/sparc64/ieee1275/loader.h @@ -16,12 +16,12 @@ * along with GRUB. If not, see . */ -#include -#include -#include +#ifndef GRUB_LOADER_MACHINE_HEADER +#define GRUB_LOADER_MACHINE_HEADER 1 -const char * -grub_efiemu_get_default_core_name (void) -{ - return grub_cpuid_has_longmode ? "efiemu64.o" : "efiemu32.o"; -} +/* 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/i386/reboot.h b/include/grub/sparc64/ieee1275/memory.h similarity index 77% rename from include/grub/i386/reboot.h rename to include/grub/sparc64/ieee1275/memory.h index c2716f3fa..25e31002e 100644 --- a/include/grub/i386/reboot.h +++ b/include/grub/sparc64/ieee1275/memory.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. + * 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 @@ -16,13 +16,11 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_REBOOT_H -#define GRUB_REBOOT_H 1 +#ifndef GRUB_MEMORY_MACHINE_HEADER +#define GRUB_MEMORY_MACHINE_HEADER 1 -#ifndef ASM_FILE +#include -extern grub_uint8_t grub_reboot_end[], grub_reboot_start[]; - -#endif +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 #endif diff --git a/include/grub/mips/qemu_mips/time.h b/include/grub/sparc64/ieee1275/time.h similarity index 87% rename from include/grub/mips/qemu_mips/time.h rename to include/grub/sparc64/ieee1275/time.h index 164b61ef8..3f8ad26d7 100644 --- a/include/grub/mips/qemu_mips/time.h +++ b/include/grub/sparc64/ieee1275/time.h @@ -20,6 +20,10 @@ #define KERNEL_MACHINE_TIME_HEADER 1 #include -#include + +#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/util/windows.h b/include/grub/sparc64/kernel.h similarity index 68% rename from include/grub/util/windows.h rename to include/grub/sparc64/kernel.h index 630948393..9f404b05d 100644 --- a/include/grub/util/windows.h +++ b/include/grub/sparc64/kernel.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. + * 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 @@ -16,18 +16,15 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_WINDOWS_UTIL_HEADER -#define GRUB_WINDOWS_UTIL_HEADER 1 +#ifndef GRUB_KERNEL_CPU_HEADER +#define GRUB_KERNEL_CPU_HEADER 1 -#include +#define GRUB_MOD_ALIGN 0x2000 -LPTSTR -grub_util_get_windows_path (const char *unix_path); +/* Non-zero value is only needed for PowerMacs. */ +#define GRUB_MOD_GAP 0x0 -char * -grub_util_tchar_to_utf8 (LPCTSTR in); - -TCHAR * -grub_get_mount_point (const TCHAR *path); +#define GRUB_KERNEL_CPU_PREFIX 0x2 +#define GRUB_KERNEL_CPU_DATA_END 0x42 #endif diff --git a/grub-core/osdep/windows/sleep.c b/include/grub/sparc64/libgcc.h similarity index 69% rename from grub-core/osdep/windows/sleep.c rename to include/grub/sparc64/libgcc.h index 03b846bc7..e73abe29c 100644 --- a/grub-core/osdep/windows/sleep.c +++ b/include/grub/sparc64/libgcc.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. + * 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 @@ -16,16 +16,14 @@ * along with GRUB. If not, see . */ -#include #include -#include -#include -#include - -void -grub_millisleep (grub_uint32_t ms) -{ - Sleep (ms); -} +#ifdef HAVE___BSWAPSI2 +typedef int SItype __attribute__ ((mode (SI))); +SItype EXPORT_FUNC (__bswapsi2) (SItype); +#endif +#ifdef HAVE___BSWAPDI2 +typedef int DItype __attribute__ ((mode (DI))); +DItype EXPORT_FUNC (__bswapdi2) (DItype); +#endif diff --git a/include/grub/sparc64/setjmp.h b/include/grub/sparc64/setjmp.h index 00286a574..6096baef1 100644 --- a/include/grub/sparc64/setjmp.h +++ b/include/grub/sparc64/setjmp.h @@ -23,7 +23,7 @@ typedef grub_uint64_t grub_jmp_buf[3]; -int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; +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/speaker.h b/include/grub/speaker.h deleted file mode 100644 index a076fcfb7..000000000 --- a/include/grub/speaker.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef GRUB_SPEAKER_HEADER -#define GRUB_SPEAKER_HEADER 1 - -#include -#include - -/* The frequency of the PIT clock. */ -#define GRUB_SPEAKER_PIT_FREQUENCY 0x1234dd - -static inline void -grub_speaker_beep_off (void) -{ - unsigned char status; - - status = grub_inb (GRUB_PIT_SPEAKER_PORT); - grub_outb (status & ~(GRUB_PIT_SPK_TMR2 | GRUB_PIT_SPK_DATA), - GRUB_PIT_SPEAKER_PORT); -} - -static inline void -grub_speaker_beep_on (grub_uint16_t pitch) -{ - unsigned char status; - unsigned int counter; - - if (pitch < 20) - pitch = 20; - else if (pitch > 20000) - pitch = 20000; - - counter = GRUB_SPEAKER_PIT_FREQUENCY / pitch; - - /* Program timer 2. */ - grub_outb (GRUB_PIT_CTRL_SELECT_2 - | GRUB_PIT_CTRL_READLOAD_WORD - | GRUB_PIT_CTRL_SQUAREWAVE_GEN - | GRUB_PIT_CTRL_COUNT_BINARY, GRUB_PIT_CTRL); - grub_outb (counter & 0xff, GRUB_PIT_COUNTER_2); /* LSB */ - grub_outb ((counter >> 8) & 0xff, GRUB_PIT_COUNTER_2); /* MSB */ - - /* Start speaker. */ - status = grub_inb (GRUB_PIT_SPEAKER_PORT); - grub_outb (status | GRUB_PIT_SPK_TMR2 | GRUB_PIT_SPK_DATA, - GRUB_PIT_SPEAKER_PORT); -} - -#endif diff --git a/include/grub/stack_protector.h b/include/grub/stack_protector.h deleted file mode 100644 index e4849b2a0..000000000 --- a/include/grub/stack_protector.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2021 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_STACK_PROTECTOR_H -#define GRUB_STACK_PROTECTOR_H 1 - -#include -#include - -#ifdef GRUB_STACK_PROTECTOR -extern grub_addr_t EXPORT_VAR (__stack_chk_guard); -extern void __attribute__ ((noreturn)) EXPORT_FUNC (__stack_chk_fail) (void); -#if defined(_WIN64) && !defined(__CYGWIN__) /* MinGW, Windows 64-bit target. */ -static grub_addr_t __attribute__ ((weakref("__stack_chk_guard"))) EXPORT_VAR (_stack_chk_guard); -static void __attribute__ ((noreturn, weakref("__stack_chk_fail"))) EXPORT_FUNC (_stack_chk_fail) (void); -#endif - -extern grub_addr_t grub_stack_protector_init (void); - -static inline __attribute__((__always_inline__)) -void grub_update_stack_guard (void) -{ - grub_addr_t guard; - - guard = grub_stack_protector_init (); - if (guard) - __stack_chk_guard = guard; -} -#endif - -#endif /* GRUB_STACK_PROTECTOR_H */ diff --git a/include/grub/symbol.h b/include/grub/symbol.h index ed19f70db..63ed19436 100644 --- a/include/grub/symbol.h +++ b/include/grub/symbol.h @@ -25,42 +25,22 @@ #define LOCAL(sym) L_ ## sym /* Add an underscore to a C symbol in assembler code if needed. */ -#ifndef GRUB_UTIL - -#ifdef __APPLE__ -#define MACRO_DOLLAR(x) $$ ## x -#else -#define MACRO_DOLLAR(x) $ ## x -#endif - -#if HAVE_ASM_USCORE -#ifdef ASM_FILE +#ifdef HAVE_ASM_USCORE # define EXT_C(sym) _ ## sym #else -# define EXT_C(sym) "_" sym -#endif -#else # define EXT_C(sym) sym #endif -#ifdef __arm__ -#define END .end -#endif - -#if defined (__APPLE__) +#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__) +#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): -#elif defined (__arm__) -#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 -#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): -#endif #endif /* Mark an exported symbol. */ diff --git a/include/grub/syslinux_parse.h b/include/grub/syslinux_parse.h deleted file mode 100644 index 359576310..000000000 --- a/include/grub/syslinux_parse.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_SYSLINUX_PARSE_HEADER -#define GRUB_SYSLINUX_PARSE_HEADER 1 - -#include - -typedef enum - { - GRUB_SYSLINUX_UNKNOWN, - GRUB_SYSLINUX_ISOLINUX, - GRUB_SYSLINUX_PXELINUX, - GRUB_SYSLINUX_SYSLINUX, - } grub_syslinux_flavour_t; - -char * -grub_syslinux_config_file (const char *root, const char *target_root, - const char *cwd, const char *target_cwd, - const char *fname, grub_syslinux_flavour_t flav); - -#endif diff --git a/include/grub/term.h b/include/grub/term.h index 7f1a14c84..143aabe1e 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -19,67 +19,33 @@ #ifndef GRUB_TERM_HEADER #define GRUB_TERM_HEADER 1 -#define GRUB_TERM_NO_KEY 0 - /* Internal codes used by GRUB to represent terminal input. */ -/* Only for keys otherwise not having shifted modification. */ -#define GRUB_TERM_SHIFT 0x01000000 -#define GRUB_TERM_CTRL 0x02000000 -#define GRUB_TERM_ALT 0x04000000 - -/* Keys without associated character. */ -#define GRUB_TERM_EXTENDED 0x00800000 -#define GRUB_TERM_KEY_MASK 0x00ffffff - -#define GRUB_TERM_KEY_LEFT (GRUB_TERM_EXTENDED | 0x4b) -#define GRUB_TERM_KEY_RIGHT (GRUB_TERM_EXTENDED | 0x4d) -#define GRUB_TERM_KEY_UP (GRUB_TERM_EXTENDED | 0x48) -#define GRUB_TERM_KEY_DOWN (GRUB_TERM_EXTENDED | 0x50) -#define GRUB_TERM_KEY_HOME (GRUB_TERM_EXTENDED | 0x47) -#define GRUB_TERM_KEY_END (GRUB_TERM_EXTENDED | 0x4f) -#define GRUB_TERM_KEY_DC (GRUB_TERM_EXTENDED | 0x53) -#define GRUB_TERM_KEY_PPAGE (GRUB_TERM_EXTENDED | 0x49) -#define GRUB_TERM_KEY_NPAGE (GRUB_TERM_EXTENDED | 0x51) -#define GRUB_TERM_KEY_F1 (GRUB_TERM_EXTENDED | 0x3b) -#define GRUB_TERM_KEY_F2 (GRUB_TERM_EXTENDED | 0x3c) -#define GRUB_TERM_KEY_F3 (GRUB_TERM_EXTENDED | 0x3d) -#define GRUB_TERM_KEY_F4 (GRUB_TERM_EXTENDED | 0x3e) -#define GRUB_TERM_KEY_F5 (GRUB_TERM_EXTENDED | 0x3f) -#define GRUB_TERM_KEY_F6 (GRUB_TERM_EXTENDED | 0x40) -#define GRUB_TERM_KEY_F7 (GRUB_TERM_EXTENDED | 0x41) -#define GRUB_TERM_KEY_F8 (GRUB_TERM_EXTENDED | 0x42) -#define GRUB_TERM_KEY_F9 (GRUB_TERM_EXTENDED | 0x43) -#define GRUB_TERM_KEY_F10 (GRUB_TERM_EXTENDED | 0x44) -#define GRUB_TERM_KEY_F11 (GRUB_TERM_EXTENDED | 0x57) -#define GRUB_TERM_KEY_F12 (GRUB_TERM_EXTENDED | 0x58) -#define GRUB_TERM_KEY_INSERT (GRUB_TERM_EXTENDED | 0x52) -#define GRUB_TERM_KEY_CENTER (GRUB_TERM_EXTENDED | 0x4c) - -/* Hex value is used for ESC, since '\e' is nonstandard */ -#define GRUB_TERM_ESC 0x1b +#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 '\b' - -#define GRUB_PROGRESS_NO_UPDATE -1 -#define GRUB_PROGRESS_FAST 0 -#define GRUB_PROGRESS_SLOW 2 +#define GRUB_TERM_BACKSPACE 8 #ifndef ASM_FILE #include #include #include -#include -#include +#include /* These are used to represent the various color states we use. */ typedef enum { - /* Used for uninitialized grub_term_color_state variables */ - GRUB_TERM_COLOR_UNDEFINED = -1, /* The color used to display all text that does not use the user defined colors below. */ - GRUB_TERM_COLOR_STANDARD = 0, + GRUB_TERM_COLOR_STANDARD, /* The user defined colors for normal text. */ GRUB_TERM_COLOR_NORMAL, /* The user defined colors for highlighted text. */ @@ -97,147 +63,136 @@ grub_term_color_state; to NULL. */ /* Set when input characters shouldn't be echoed back. */ -#define GRUB_TERM_NO_ECHO (1 << 0) +#define GRUB_TERM_NO_ECHO (1 << 0) /* Set when the editing feature should be disabled. */ -#define GRUB_TERM_NO_EDIT (1 << 1) +#define GRUB_TERM_NO_EDIT (1 << 1) /* Set when the terminal cannot do fancy things. */ -#define GRUB_TERM_DUMB (1 << 2) -/* Which encoding does terminal expect stream to be. */ -#define GRUB_TERM_CODE_TYPE_SHIFT 3 -#define GRUB_TERM_CODE_TYPE_MASK (7 << GRUB_TERM_CODE_TYPE_SHIFT) -/* Only ASCII characters accepted. */ -#define GRUB_TERM_CODE_TYPE_ASCII (0 << GRUB_TERM_CODE_TYPE_SHIFT) -/* Expects CP-437 characters (ASCII + pseudographics). */ -#define GRUB_TERM_CODE_TYPE_CP437 (1 << GRUB_TERM_CODE_TYPE_SHIFT) -/* UTF-8 stream in logical order. Usually used for terminals - which just forward the stream to another computer. */ -#define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (2 << GRUB_TERM_CODE_TYPE_SHIFT) -/* UTF-8 in visual order. Like UTF-8 logical but for buggy endpoints. */ -#define GRUB_TERM_CODE_TYPE_UTF8_VISUAL (3 << GRUB_TERM_CODE_TYPE_SHIFT) -/* Glyph description in visual order. */ -#define GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS (4 << GRUB_TERM_CODE_TYPE_SHIFT) +#define GRUB_TERM_DUMB (1 << 2) /* Bitmasks for modifier keys returned by grub_getkeystatus. */ -#define GRUB_TERM_STATUS_RSHIFT (1 << 0) -#define GRUB_TERM_STATUS_LSHIFT (1 << 1) -#define GRUB_TERM_STATUS_RCTRL (1 << 2) -#define GRUB_TERM_STATUS_RALT (1 << 3) -#define GRUB_TERM_STATUS_SCROLL (1 << 4) -#define GRUB_TERM_STATUS_NUM (1 << 5) -#define GRUB_TERM_STATUS_CAPS (1 << 6) -#define GRUB_TERM_STATUS_LCTRL (1 << 8) -#define GRUB_TERM_STATUS_LALT (1 << 9) +#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; - struct grub_term_input **prev; /* The terminal name. */ const char *name; /* Initialize the terminal. */ - grub_err_t (*init) (struct grub_term_input *term); + grub_err_t (*init) (void); /* Clean up the terminal. */ - grub_err_t (*fini) (struct grub_term_input *term); + grub_err_t (*fini) (void); - /* Get a character if any input character is available. Otherwise return -1 */ - int (*getkey) (struct grub_term_input *term); + /* Check if any input character is available. */ + int (*checkkey) (void); + + /* Get a character. */ + int (*getkey) (void); /* Get keyboard modifier status. */ - int (*getkeystatus) (struct grub_term_input *term); - - void *data; + int (*getkeystatus) (void); }; typedef struct grub_term_input *grub_term_input_t; -/* Made in a way to fit into uint32_t and so be passed in a register. */ -struct grub_term_coordinate -{ - grub_uint16_t x; - grub_uint16_t y; -}; - struct grub_term_output { /* The next terminal. */ struct grub_term_output *next; - struct grub_term_output **prev; /* The terminal name. */ const char *name; /* Initialize the terminal. */ - grub_err_t (*init) (struct grub_term_output *term); + grub_err_t (*init) (void); /* Clean up the terminal. */ - grub_err_t (*fini) (struct grub_term_output *term); + grub_err_t (*fini) (void); /* Put a character. C is encoded in Unicode. */ - void (*putchar) (struct grub_term_output *term, - const struct grub_unicode_glyph *c); + void (*putchar) (grub_uint32_t c); /* Get the number of columns occupied by a given character C. C is encoded in Unicode. */ - grub_size_t (*getcharwidth) (struct grub_term_output *term, - const struct grub_unicode_glyph *c); + grub_ssize_t (*getcharwidth) (grub_uint32_t c); - /* Get the screen size. */ - struct grub_term_coordinate (*getwh) (struct grub_term_output *term); + /* 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). */ - struct grub_term_coordinate (*getxy) (struct grub_term_output *term); + grub_uint16_t (*getxy) (void); /* Go to the position (X, Y). */ - void (*gotoxy) (struct grub_term_output *term, - struct grub_term_coordinate pos); + void (*gotoxy) (grub_uint8_t x, grub_uint8_t y); /* Clear the screen. */ - void (*cls) (struct grub_term_output *term); + void (*cls) (void); /* Set the current color to be used */ - void (*setcolorstate) (struct grub_term_output *term, - grub_term_color_state state); + 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) (struct grub_term_output *term, int on); + void (*setcursor) (int on); /* Update the screen. */ - void (*refresh) (struct grub_term_output *term); - - /* gfxterm only: put in fullscreen mode. */ - grub_err_t (*fullscreen) (void); + void (*refresh) (void); /* The feature flags defined above. */ grub_uint32_t flags; - - /* Progress data. */ - grub_uint32_t progress_update_divisor; - grub_uint32_t progress_update_counter; - - void *data; }; typedef struct grub_term_output *grub_term_output_t; -#define GRUB_TERM_DEFAULT_NORMAL_COLOR 0x07 -#define GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR 0x70 -#define GRUB_TERM_DEFAULT_STANDARD_COLOR 0x07 - -/* Current color state. */ -extern grub_uint8_t EXPORT_VAR(grub_term_normal_color); -extern grub_uint8_t EXPORT_VAR(grub_term_highlight_color); - 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); @@ -253,27 +208,11 @@ grub_term_register_input (const char *name __attribute__ ((unused)), else { /* If this is the first terminal, enable automatically. */ - if (! term->init || term->init (term) == GRUB_ERR_NONE) + 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_input_inactive (const char *name __attribute__ ((unused)), - grub_term_input_t term) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), - GRUB_AS_LIST (term)); -} - -static inline void -grub_term_register_input_active (const char *name __attribute__ ((unused)), - grub_term_input_t term) -{ - if (! term->init || term->init (term) == 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) @@ -284,118 +223,144 @@ grub_term_register_output (const char *name __attribute__ ((unused)), else { /* If this is the first terminal, enable automatically. */ - if (! term->init || term->init (term) == GRUB_ERR_NONE) + 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_register_output_inactive (const char *name __attribute__ ((unused)), - grub_term_output_t term) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled), - GRUB_AS_LIST (term)); -} - -static inline void -grub_term_register_output_active (const char *name __attribute__ ((unused)), - grub_term_output_t term) -{ - if (! term->init || term->init (term) == 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 (term)); - grub_list_remove (GRUB_AS_LIST (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 (term)); - grub_list_remove (GRUB_AS_LIST (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_LIST_ELEMENTS((var), (grub_term_inputs)) -#define FOR_DISABLED_TERM_INPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_inputs_disabled)) -#define FOR_ACTIVE_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs)) -#define FOR_DISABLED_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs_disabled)) +#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 grub_putcode (grub_uint32_t code, struct grub_term_output *term); +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_getkey_noblock) (void); +int EXPORT_FUNC(grub_checkkey) (void); int EXPORT_FUNC(grub_getkeystatus) (void); -int EXPORT_FUNC(grub_key_is_interrupt) (int key); -void grub_cls (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); -struct grub_term_coordinate *grub_term_save_pos (void); -void grub_term_restore_pos (struct grub_term_coordinate *pos); +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(term).x ? : 80; + return ((term->getwh()&0xFF00)>>8); } static inline unsigned grub_term_height (struct grub_term_output *term) { - return term->getwh(term).y ? : 24; + return (term->getwh()&0xFF); } -static inline struct grub_term_coordinate +/* 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 (term); + return term->getxy (); } static inline void grub_term_refresh (struct grub_term_output *term) { if (term->refresh) - term->refresh (term); + term->refresh (); } static inline void -grub_term_gotoxy (struct grub_term_output *term, struct grub_term_coordinate pos) +grub_term_gotoxy (struct grub_term_output *term, grub_uint8_t x, grub_uint8_t y) { - term->gotoxy (term, pos); + term->gotoxy (x, y); } -static inline void -grub_term_setcolorstate (struct grub_term_output *term, +static inline void +grub_term_setcolorstate (struct grub_term_output *term, grub_term_color_state state) { if (term->setcolorstate) - term->setcolorstate (term, state); + term->setcolorstate (state); } -static inline void -grub_setcolorstate (grub_term_color_state 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) { - struct grub_term_output *term; - - FOR_ACTIVE_TERM_OUTPUTS(term) - grub_term_setcolorstate (term, state); + if (term->setcolor) + term->setcolor (normal_color, highlight_color); } /* Turn on/off the cursor. */ -static inline void +static inline void grub_term_setcursor (struct grub_term_output *term, int on) { if (term->setcursor) - term->setcursor (term, on); + term->setcursor (on); } -static inline void +static inline void grub_term_cls (struct grub_term_output *term) { if (term->cls) - (term->cls) (term); + (term->cls) (); else { grub_putcode ('\n', term); @@ -403,45 +368,30 @@ grub_term_cls (struct grub_term_output *term) } } -#if HAVE_FONT_SOURCE - -grub_size_t -grub_unicode_estimate_width (const struct grub_unicode_glyph *c); - -#else - -static inline grub_size_t -grub_unicode_estimate_width (const struct grub_unicode_glyph *c __attribute__ ((unused))) +static inline grub_ssize_t +grub_term_getcharwidth (struct grub_term_output *term, grub_uint32_t c) { - if (grub_unicode_get_comb_type (c->base)) - return 0; - return 1; -} - -#endif - -#define GRUB_TERM_TAB_WIDTH 8 - -static inline grub_size_t -grub_term_getcharwidth (struct grub_term_output *term, - const struct grub_unicode_glyph *c) -{ - if (c->base == '\t') - return GRUB_TERM_TAB_WIDTH; - if (term->getcharwidth) - return term->getcharwidth (term, c); - else if (((term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UTF8_LOGICAL) - || ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) - || ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS)) - return grub_unicode_estimate_width (c); + 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; @@ -459,10 +409,9 @@ grub_print_spaces (struct grub_term_output *term, int number_spaces) grub_putcode (' ', term); } -extern void (*EXPORT_VAR (grub_term_poll_usb)) (int wait_for_completion); -#define GRUB_TERM_REPEAT_PRE_INTERVAL 400 -#define GRUB_TERM_REPEAT_INTERVAL 50 +/* For convenience. */ +#define GRUB_TERM_ASCII_CHAR(c) ((c) & 0xff) #endif /* ! ASM_FILE */ diff --git a/include/grub/terminfo.h b/include/grub/terminfo.h index 8a109ecfd..e3a2c170a 100644 --- a/include/grub/terminfo.h +++ b/include/grub/terminfo.h @@ -23,65 +23,15 @@ #include #include -char *EXPORT_FUNC(grub_terminfo_get_current) (struct grub_term_output *term); -grub_err_t EXPORT_FUNC(grub_terminfo_set_current) (struct grub_term_output *term, - const char *); +char *grub_terminfo_get_current (void); +grub_err_t grub_terminfo_set_current (const char *); -#define GRUB_TERMINFO_READKEY_MAX_LEN 6 -struct grub_terminfo_input_state -{ - int input_buf[GRUB_TERMINFO_READKEY_MAX_LEN]; - int npending; -#if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275) - int last_key; - grub_uint64_t last_key_time; -#endif - int (*readkey) (struct grub_term_input *term); -}; - -struct grub_terminfo_output_state -{ - struct grub_term_output *next; - - char *name; - - char *gotoxy; - char *cls; - char *reverse_video_on; - char *reverse_video_off; - char *cursor_on; - char *cursor_off; - char *setcolor; - - struct grub_term_coordinate size; - struct grub_term_coordinate pos; - - void (*put) (struct grub_term_output *term, const int c); -}; - -grub_err_t EXPORT_FUNC(grub_terminfo_output_init) (struct grub_term_output *term); -void EXPORT_FUNC(grub_terminfo_gotoxy) (grub_term_output_t term, - struct grub_term_coordinate pos); -void EXPORT_FUNC(grub_terminfo_cls) (grub_term_output_t term); -struct grub_term_coordinate EXPORT_FUNC (grub_terminfo_getxy) (struct grub_term_output *term); -void EXPORT_FUNC (grub_terminfo_setcursor) (struct grub_term_output *term, - const int on); -void EXPORT_FUNC (grub_terminfo_setcolorstate) (struct grub_term_output *term, - const grub_term_color_state state); - - -grub_err_t EXPORT_FUNC (grub_terminfo_input_init) (struct grub_term_input *term); -int EXPORT_FUNC (grub_terminfo_getkey) (struct grub_term_input *term); -void EXPORT_FUNC (grub_terminfo_putchar) (struct grub_term_output *term, - const struct grub_unicode_glyph *c); -struct grub_term_coordinate EXPORT_FUNC (grub_terminfo_getwh) (struct grub_term_output *term); - - -grub_err_t EXPORT_FUNC (grub_terminfo_output_register) (struct grub_term_output *term, - const char *type); -grub_err_t EXPORT_FUNC (grub_terminfo_output_unregister) (struct grub_term_output *term); - -void grub_terminfo_init (void); -void grub_terminfo_fini (void); +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 index b83bdb14e..a7d3a2399 100644 --- a/include/grub/test.h +++ b/include/grub/test.h @@ -25,18 +25,10 @@ #include #include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - struct grub_test { /* The next test. */ struct grub_test *next; - struct grub_test **prev; /* The test name. */ char *name; @@ -58,20 +50,13 @@ int grub_test_run (grub_test_t test); void grub_test_nonzero (int cond, const char *file, const char *func, grub_uint32_t line, const char *fmt, ...) - __attribute__ ((format (GNU_PRINTF, 5, 6))); + __attribute__ ((format (printf, 5, 6))); /* Macro to fill in location details and an optional error message. */ -void grub_test_assert_helper (int cond, const char *file, - const char *func, grub_uint32_t line, - const char *condstr, const char *fmt, ...) - __attribute__ ((format (GNU_PRINTF, 6, 7))); - #define grub_test_assert(cond, ...) \ - grub_test_assert_helper(cond, GRUB_FILE, __FUNCTION__, __LINE__, \ - #cond, ## __VA_ARGS__); - -void grub_unit_test_init (void); -void grub_unit_test_fini (void); + grub_test_nonzero(cond, __FILE__, __FUNCTION__, __LINE__, \ + ## __VA_ARGS__, \ + "assert failed: %s", #cond) /* Macro to define a unit test. */ #define GRUB_UNIT_TEST(name, funp) \ @@ -87,39 +72,14 @@ void grub_unit_test_fini (void); /* Macro to define a functional test. */ #define GRUB_FUNCTIONAL_TEST(name, funp) \ - GRUB_MOD_INIT(name) \ + GRUB_MOD_INIT(functional_test_##funp) \ { \ - grub_test_register (#name, funp); \ + grub_test_register (name, funp); \ } \ \ - GRUB_MOD_FINI(name) \ + GRUB_MOD_FINI(functional_test_##funp) \ { \ - grub_test_unregister (#name); \ + grub_test_unregister (name); \ } -void -grub_video_checksum (const char *basename_in); -void -grub_video_checksum_end (void); -void -grub_terminal_input_fake_sequence (int *seq_in, int nseq_in); -void -grub_terminal_input_fake_sequence_end (void); -const char * -grub_video_checksum_get_modename (void); - - -#define GRUB_TEST_VIDEO_SMALL_N_MODES 7 -#define GRUB_TEST_VIDEO_ALL_N_MODES 31 - -extern struct grub_video_mode_info grub_test_video_modes[GRUB_TEST_VIDEO_ALL_N_MODES]; - -int -grub_test_use_gfxterm (void); -void grub_test_use_gfxterm_end (void); - -#ifdef __cplusplus -} -#endif - #endif /* ! GRUB_TEST_HEADER */ diff --git a/include/grub/time.h b/include/grub/time.h index 32f0afaf8..ae2617edb 100644 --- a/include/grub/time.h +++ b/include/grub/time.h @@ -21,16 +21,15 @@ #include #include -#if !defined(GRUB_MACHINE_EMU) && !defined(GRUB_UTIL) #include -#else -static inline void -grub_cpu_idle(void) -{ -} -#endif -#define NSEC_PER_SEC ((grub_int64_t) 1000000000) +#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 +#endif void EXPORT_FUNC(grub_millisleep) (grub_uint32_t ms); grub_uint64_t EXPORT_FUNC(grub_get_time_ms) (void); diff --git a/include/grub/tparm.h b/include/grub/tparm.h index 0c6f9e0f0..642a22f90 100644 --- a/include/grub/tparm.h +++ b/include/grub/tparm.h @@ -21,6 +21,6 @@ #define GRUB_TPARM_HEADER 1 /* Function prototypes. */ -const char *grub_terminfo_tparm (const char *string, ...); +char *grub_terminfo_tparm (const char *string, ...); #endif /* ! GRUB_TPARM_HEADER */ diff --git a/include/grub/tpm.h b/include/grub/tpm.h deleted file mode 100644 index d09783dac..000000000 --- a/include/grub/tpm.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2018 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_TPM_HEADER -#define GRUB_TPM_HEADER 1 - -#include - -#define GRUB_STRING_PCR 8 -#define GRUB_BINARY_PCR 9 - -#define SHA1_DIGEST_SIZE 20 - -#define TPM_BASE 0x0 -#define TPM_SUCCESS TPM_BASE -#define TPM_AUTHFAIL (TPM_BASE + 0x1) -#define TPM_BADINDEX (TPM_BASE + 0x2) - -#define TPM_TAG_RQU_COMMAND 0x00C1 -#define TPM_ORD_Extend 0x14 - -#define EV_IPL 0x0d - -grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size, - grub_uint8_t pcr, const char *description); -int grub_tpm_present (void); - -static inline bool -grub_is_tpm_fail_fatal (void) -{ - return grub_env_get_bool ("tpm_fail_fatal", false); -} - -#endif diff --git a/include/grub/trig.h b/include/grub/trig.h index f19617c90..2512a5f07 100644 --- a/include/grub/trig.h +++ b/include/grub/trig.h @@ -24,8 +24,8 @@ #define GRUB_TRIG_ANGLE_MASK 255 #define GRUB_TRIG_FRACTION_SCALE 16384 -extern const short grub_trig_sintab[]; -extern const short grub_trig_costab[]; +extern short grub_trig_sintab[]; +extern short grub_trig_costab[]; static __inline int grub_sin (int x) diff --git a/include/grub/types.h b/include/grub/types.h index 45079bf65..9eaafd0c1 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -20,26 +20,9 @@ #define GRUB_TYPES_HEADER 1 #include -#include -#ifndef GRUB_UTIL #include -#endif -#ifdef __MINGW32__ -#define GRUB_PACKED __attribute__ ((packed,gcc_struct)) -#else -#define GRUB_PACKED __attribute__ ((packed)) -#endif - -#ifdef GRUB_BUILD -# define GRUB_CPU_SIZEOF_VOID_P BUILD_SIZEOF_VOID_P -# define GRUB_CPU_SIZEOF_LONG BUILD_SIZEOF_LONG -# if BUILD_WORDS_BIGENDIAN -# define GRUB_CPU_WORDS_BIGENDIAN 1 -# else -# undef GRUB_CPU_WORDS_BIGENDIAN -# endif -#elif defined (GRUB_UTIL) +#ifdef GRUB_UTIL # define GRUB_CPU_SIZEOF_VOID_P SIZEOF_VOID_P # define GRUB_CPU_SIZEOF_LONG SIZEOF_LONG # ifdef WORDS_BIGENDIAN @@ -57,15 +40,15 @@ # 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 -#if GRUB_CPU_SIZEOF_LONG != 4 && GRUB_CPU_SIZEOF_LONG != 8 -# error "This architecture is not supported because sizeof(long) != 4 and sizeof(long) != 8" -#endif - -#if !defined (GRUB_UTIL) && !defined (GRUB_TARGET_WORDSIZE) +#ifndef GRUB_TARGET_WORDSIZE # if GRUB_TARGET_SIZEOF_VOID_P == 4 # define GRUB_TARGET_WORDSIZE 32 # elif GRUB_TARGET_SIZEOF_VOID_P == 8 @@ -73,132 +56,102 @@ # endif #endif -#ifndef __CHAR_BIT__ -# error __CHAR_BIT__ is not defined -#elif __CHAR_BIT__ != 8 -# error __CHAR_BIT__ is not equal 8 -#else -# define GRUB_CHAR_BIT __CHAR_BIT__ -#endif - -#define GRUB_TYPE_BITS(type) (sizeof(type) * GRUB_CHAR_BIT) - /* Define various wide integers. */ typedef signed char grub_int8_t; typedef short grub_int16_t; typedef int grub_int32_t; -# define PRIxGRUB_INT32_T "x" -# define PRIdGRUB_INT32_T "d" -#if GRUB_CPU_SIZEOF_LONG == 8 +#if GRUB_CPU_SIZEOF_VOID_P == 8 typedef long grub_int64_t; -# define PRIxGRUB_INT64_T "lx" -# define PRIdGRUB_INT64_T "ld" #else typedef long long grub_int64_t; -# define PRIxGRUB_INT64_T "llx" -# define PRIdGRUB_INT64_T "lld" #endif typedef unsigned char grub_uint8_t; typedef unsigned short grub_uint16_t; typedef unsigned grub_uint32_t; -# define PRIxGRUB_UINT32_T "x" -# define PRIuGRUB_UINT32_T "u" -#if GRUB_CPU_SIZEOF_LONG == 8 +#if GRUB_CPU_SIZEOF_VOID_P == 8 typedef unsigned long grub_uint64_t; -# define PRIxGRUB_UINT64_T "lx" -# define PRIuGRUB_UINT64_T "lu" #else typedef unsigned long long grub_uint64_t; -# define PRIxGRUB_UINT64_T "llx" -# define PRIuGRUB_UINT64_T "llu" #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; - -# define GRUB_SIZE_MAX 18446744073709551615UL -# define GRUB_SSIZE_MAX 9223372036854775807L - -# if GRUB_CPU_SIZEOF_LONG == 8 -# define PRIxGRUB_SIZE "lx" -# define PRIxGRUB_ADDR "lx" -# define PRIuGRUB_SIZE "lu" -# define PRIdGRUB_SSIZE "ld" -# else -# define PRIxGRUB_SIZE "llx" -# define PRIxGRUB_ADDR "llx" -# define PRIuGRUB_SIZE "llu" -# define PRIdGRUB_SSIZE "lld" -# endif #else typedef grub_uint32_t grub_addr_t; typedef grub_uint32_t grub_size_t; typedef grub_int32_t grub_ssize_t; - -# define GRUB_SIZE_MAX 4294967295UL -# define GRUB_SSIZE_MAX 2147483647L - -# define PRIxGRUB_SIZE "x" -# define PRIxGRUB_ADDR "x" -# define PRIuGRUB_SIZE "u" -# define PRIdGRUB_SSIZE "d" #endif -#define GRUB_SCHAR_MAX 127 -#define GRUB_SCHAR_MIN (-GRUB_SCHAR_MAX - 1) -#define GRUB_UCHAR_MAX 0xFF -#define GRUB_USHRT_MAX 65535 -#define GRUB_SHRT_MAX 0x7fff -#define GRUB_SHRT_MIN (-GRUB_SHRT_MAX - 1) -#define GRUB_UINT_MAX 4294967295U -#define GRUB_INT_MAX 0x7fffffff -#define GRUB_INT_MIN (-GRUB_INT_MAX - 1) -#define GRUB_INT32_MAX 2147483647 -#define GRUB_INT32_MIN (-GRUB_INT32_MAX - 1) - -#if GRUB_CPU_SIZEOF_LONG == 8 +#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 -# define GRUB_LONG_MIN (-GRUB_LONG_MAX - 1) -/* - * Cast to unsigned long long so that the "return value" is always a consistent - * type and to ensure an unsigned value regardless of type parameter. - */ -#define GRUB_TYPE_U_MAX(type) ((unsigned long long)((typeof (type))(~0))) -#define GRUB_TYPE_U_MIN(type) 0ULL - -typedef grub_uint64_t grub_properly_aligned_t; - -#define GRUB_PROPERLY_ALIGNED_ARRAY(name, size) grub_properly_aligned_t name[((size) + sizeof (grub_properly_aligned_t) - 1) / sizeof (grub_properly_aligned_t)] +#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; -#define PRIxGRUB_OFFSET PRIxGRUB_UINT64_T -#define PRIuGRUB_OFFSET PRIuGRUB_UINT64_T +typedef grub_uint64_t grub_off_t; /* The type for representing a disk block address. */ -typedef grub_uint64_t grub_disk_addr_t; -#define PRIxGRUB_DISK_ADDR PRIxGRUB_UINT64_T +typedef grub_uint64_t grub_disk_addr_t; /* Byte-orders. */ -static inline grub_uint16_t grub_swap_bytes16(grub_uint16_t _x) +#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 (grub_uint16_t) ((_x << 8) | (_x >> 8)); + return __builtin_bswap32(x); } -#define grub_swap_bytes16_compile_time(x) ((grub_uint16_t)((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))) -#define grub_swap_bytes32_compile_time(x) ((grub_uint32_t)((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000UL) >> 24))) -#define grub_swap_bytes64_compile_time(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) \ @@ -210,37 +163,6 @@ static inline grub_uint16_t grub_swap_bytes16(grub_uint16_t _x) | ((_x & (grub_uint64_t) 0xFF000000000000ULL) >> 40) \ | (_x >> 56)); \ }) - -#if (defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)) || defined(__clang__) -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 */ -static inline grub_uint32_t grub_swap_bytes32(grub_uint32_t _x) -{ - return ((_x << 24) - | ((_x & (grub_uint32_t) 0xFF00UL) << 8) - | ((_x & (grub_uint32_t) 0xFF0000UL) >> 8) - | (_x >> 24)); -} - -static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t _x) -{ - return ((_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 @@ -256,13 +178,21 @@ static inline grub_uint64_t grub_swap_bytes64(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)) -# define grub_cpu_to_be16_compile_time(x) ((grub_uint16_t) (x)) -# define grub_cpu_to_be32_compile_time(x) ((grub_uint32_t) (x)) -# define grub_cpu_to_be64_compile_time(x) ((grub_uint64_t) (x)) -# define grub_be_to_cpu64_compile_time(x) ((grub_uint64_t) (x)) -# define grub_cpu_to_le32_compile_time(x) grub_swap_bytes32_compile_time(x) -# define grub_cpu_to_le64_compile_time(x) grub_swap_bytes64_compile_time(x) -# define grub_cpu_to_le16_compile_time(x) grub_swap_bytes16_compile_time(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)) @@ -276,116 +206,27 @@ static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t _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) -# define grub_cpu_to_be16_compile_time(x) grub_swap_bytes16_compile_time(x) -# define grub_cpu_to_be32_compile_time(x) grub_swap_bytes32_compile_time(x) -# define grub_cpu_to_be64_compile_time(x) grub_swap_bytes64_compile_time(x) -# define grub_be_to_cpu64_compile_time(x) grub_swap_bytes64_compile_time(x) -# define grub_cpu_to_le16_compile_time(x) ((grub_uint16_t) (x)) -# define grub_cpu_to_le32_compile_time(x) ((grub_uint32_t) (x)) -# define grub_cpu_to_le64_compile_time(x) ((grub_uint64_t) (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 */ -struct grub_unaligned_uint16 -{ - grub_uint16_t val; -} GRUB_PACKED; -struct grub_unaligned_uint32 -{ - grub_uint32_t val; -} GRUB_PACKED; -struct grub_unaligned_uint64 -{ - grub_uint64_t val; -} GRUB_PACKED; - -typedef struct grub_unaligned_uint16 grub_unaligned_uint16_t; -typedef struct grub_unaligned_uint32 grub_unaligned_uint32_t; -typedef struct grub_unaligned_uint64 grub_unaligned_uint64_t; - -static inline grub_uint16_t grub_get_unaligned16 (const void *ptr) -{ - const struct grub_unaligned_uint16 *dd - = (const struct grub_unaligned_uint16 *) ptr; - return dd->val; -} - -static inline void grub_set_unaligned16 (void *ptr, grub_uint16_t val) -{ - struct grub_unaligned_uint16 *dd = (struct grub_unaligned_uint16 *) ptr; - dd->val = val; -} - -static inline grub_uint32_t grub_get_unaligned32 (const void *ptr) -{ - const struct grub_unaligned_uint32 *dd - = (const struct grub_unaligned_uint32 *) ptr; - return dd->val; -} - -static inline void grub_set_unaligned32 (void *ptr, grub_uint32_t val) -{ - struct grub_unaligned_uint32 *dd = (struct grub_unaligned_uint32 *) ptr; - dd->val = val; -} - -static inline grub_uint64_t grub_get_unaligned64 (const void *ptr) -{ - const struct grub_unaligned_uint64 *dd - = (const struct grub_unaligned_uint64 *) ptr; - return dd->val; -} - -static inline void grub_set_unaligned64 (void *ptr, grub_uint64_t val) -{ - struct grub_unaligned_uint64_t - { - grub_uint64_t d; - } GRUB_PACKED; - struct grub_unaligned_uint64_t *dd = (struct grub_unaligned_uint64_t *) ptr; - dd->d = val; -} - -/* - * The grub_absolute_pointer() macro borrows the idea from Linux kernel of using - * RELOC_HIDE() macro to stop GCC from checking the result of pointer arithmetic - * and also its conversion to be inside the symbol's boundary [1]. The check - * is sometimes false positive, especially it is controversial to emit the array - * bounds [-Warray-bounds] warning on all hardwired literal pointers since GCC - * 11/12 [2]. Unless a good solution can be settled, for the time being we - * would be in favor of the macro instead of GCC pragmas which cannot match the - * places the warning needs to be ignored in an exact way. - * - * [1] https://lists.linuxcoding.com/kernel/2006-q3/msg17979.html - * [2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578 - */ -#if defined(__GNUC__) -# define grub_absolute_pointer(val) \ -({ \ - grub_addr_t __ptr; \ - asm ("" : "=r" (__ptr) : "0" ((void *) (val))); \ - (void *) (__ptr); \ -}) +#if GRUB_TARGET_SIZEOF_VOID_P == 8 +# define grub_host_to_target_addr(x) grub_host_to_target64(x) #else -# define grub_absolute_pointer(val) ((void *) (val)) +# define grub_host_to_target_addr(x) grub_host_to_target32(x) #endif -struct grub_guid -{ - grub_uint32_t data1; - grub_uint16_t data2; - grub_uint16_t data3; - grub_uint8_t data4[8]; -} __attribute__ ((aligned(4))); -typedef struct grub_guid grub_guid_t; - -struct grub_packed_guid -{ - grub_uint32_t data1; - grub_uint16_t data2; - grub_uint16_t data3; - grub_uint8_t data4[8]; -} GRUB_PACKED; -typedef struct grub_packed_guid grub_packed_guid_t; - #endif /* ! GRUB_TYPES_HEADER */ diff --git a/include/grub/uboot/api_public.h b/include/grub/uboot/api_public.h deleted file mode 100644 index 0707f5cff..000000000 --- a/include/grub/uboot/api_public.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * (C) Copyright 2007-2008 Semihalf - * - * Written by: Rafal Jaworowski - * - * This file is dual licensed; you can use it under the terms of - * either the GPL, or the BSD license, at your option. - * - * I. GPL: - * - * This file is free software; you can 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 file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * Alternatively, - * - * II. BSD license: - * - * 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. - */ - -#ifndef _API_PUBLIC_H_ -#define _API_PUBLIC_H_ - -#define API_EINVAL 1 /* invalid argument(s) */ -#define API_ENODEV 2 /* no device */ -#define API_ENOMEM 3 /* no memory */ -#define API_EBUSY 4 /* busy, occupied etc. */ -#define API_EIO 5 /* I/O error */ -#define API_ESYSC 6 /* syscall error */ - -typedef int (*scp_t) (int, int *, ...); - -#define API_SIG_VERSION 1 -#define API_SIG_MAGIC "UBootAPI" -#define API_SIG_MAGLEN 8 - -struct api_signature -{ - char magic[API_SIG_MAGLEN]; /* magic string */ - grub_uint16_t version; /* API version */ - grub_uint32_t checksum; /* checksum of this sig struct */ - scp_t syscall; /* entry point to the API */ -}; - -enum -{ - API_RSVD = 0, - API_GETC, - API_PUTC, - API_TSTC, - API_PUTS, - API_RESET, - API_GET_SYS_INFO, - API_UDELAY, - API_GET_TIMER, - API_DEV_ENUM, - API_DEV_OPEN, - API_DEV_CLOSE, - API_DEV_READ, - API_DEV_WRITE, - API_ENV_ENUM, - API_ENV_GET, - API_ENV_SET, - API_DISPLAY_GET_INFO, - API_DISPLAY_DRAW_BITMAP, - API_DISPLAY_CLEAR, - API_MAXCALL -}; - -#define MR_ATTR_FLASH 0x0001 -#define MR_ATTR_DRAM 0x0002 -#define MR_ATTR_SRAM 0x0003 -#define MR_ATTR_MASK 0x000f - -struct mem_region -{ - unsigned long start; - unsigned long size; - int flags; -}; - -struct sys_info -{ - unsigned long clk_bus; - unsigned long clk_cpu; - unsigned long bar; - struct mem_region *mr; - int mr_no; /* number of memory regions */ -}; - -#undef CONFIG_SYS_64BIT_LBA -#ifdef CONFIG_SYS_64BIT_LBA -typedef u_int64_t lbasize_t; -#else -typedef unsigned long lbasize_t; -#endif -typedef unsigned long lbastart_t; - -#define DEV_TYP_NONE 0x0000 -#define DEV_TYP_NET 0x0001 - -#define DEV_TYP_STOR 0x0002 -#define DT_STOR_IDE 0x0010 -#define DT_STOR_SCSI 0x0020 -#define DT_STOR_USB 0x0040 -#define DT_STOR_MMC 0x0080 -#define DT_STOR_SATA 0x0100 - -#define DEV_STA_CLOSED 0x0000 /* invalid, closed */ -#define DEV_STA_OPEN 0x0001 /* open i.e. active */ - -struct device_info -{ - int type; - void *cookie; - - union - { - struct - { - lbasize_t block_count; /* no of blocks */ - unsigned long block_size; /* size of one block */ - } storage; - - struct - { - unsigned char hwaddr[6]; - } net; - } info; -#define di_stor info.storage -#define di_net info.net - - int state; -}; - -#define DISPLAY_TYPE_LCD 0x0001 -#define DISPLAY_TYPE_VIDEO 0x0002 - -struct display_info -{ - int type; - /* screen size in pixels */ - int pixel_width; - int pixel_height; - /* screen size in rows and columns of text */ - int screen_rows; - int screen_cols; -}; - -#endif /* _API_PUBLIC_H_ */ diff --git a/include/grub/uboot/image.h b/include/grub/uboot/image.h deleted file mode 100644 index 3e3f0346e..000000000 --- a/include/grub/uboot/image.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * (C) Copyright 2008 Semihalf - * - * (C) Copyright 2000-2005 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - ******************************************************************** - * NOTE: This header file defines an interface to U-Boot. Including - * this (unmodified) header file in another file is considered normal - * use of U-Boot, and does *not* fall under the heading of "derived - * work". - ******************************************************************** - */ - -#ifndef __GRUB_UBOOT_IMAGE_H__ -#define __GRUB_UBOOT_IMAGE_H__ - -/* - * Operating System Codes - */ -#define GRUB_UBOOT_IH_OS_INVALID 0 /* Invalid OS */ -#define GRUB_UBOOT_IH_OS_OPENBSD 1 /* OpenBSD */ -#define GRUB_UBOOT_IH_OS_NETBSD 2 /* NetBSD */ -#define GRUB_UBOOT_IH_OS_FREEBSD 3 /* FreeBSD */ -#define GRUB_UBOOT_IH_OS_4_4BSD 4 /* 4.4BSD */ -#define GRUB_UBOOT_IH_OS_LINUX 5 /* Linux */ -#define GRUB_UBOOT_IH_OS_SVR4 6 /* SVR4 */ -#define GRUB_UBOOT_IH_OS_ESIX 7 /* Esix */ -#define GRUB_UBOOT_IH_OS_SOLARIS 8 /* Solaris */ -#define GRUB_UBOOT_IH_OS_IRIX 9 /* Irix */ -#define GRUB_UBOOT_IH_OS_SCO 10 /* SCO */ -#define GRUB_UBOOT_IH_OS_DELL 11 /* Dell */ -#define GRUB_UBOOT_IH_OS_NCR 12 /* NCR */ -#define GRUB_UBOOT_IH_OS_LYNXOS 13 /* LynxOS */ -#define GRUB_UBOOT_IH_OS_VXWORKS 14 /* VxWorks */ -#define GRUB_UBOOT_IH_OS_PSOS 15 /* pSOS */ -#define GRUB_UBOOT_IH_OS_QNX 16 /* QNX */ -#define GRUB_UBOOT_IH_OS_U_BOOT 17 /* Firmware */ -#define GRUB_UBOOT_IH_OS_RTEMS 18 /* RTEMS */ -#define GRUB_UBOOT_IH_OS_ARTOS 19 /* ARTOS */ -#define GRUB_UBOOT_IH_OS_UNITY 20 /* Unity OS */ -#define GRUB_UBOOT_IH_OS_INTEGRITY 21 /* INTEGRITY */ -#define GRUB_UBOOT_IH_OS_OSE 22 /* OSE */ - -/* - * CPU Architecture Codes (supported by Linux) - */ -#define GRUB_UBOOT_IH_ARCH_INVALID 0 /* Invalid CPU */ -#define GRUB_UBOOT_IH_ARCH_ALPHA 1 /* Alpha */ -#define GRUB_UBOOT_IH_ARCH_ARM 2 /* ARM */ -#define GRUB_UBOOT_IH_ARCH_I386 3 /* Intel x86 */ -#define GRUB_UBOOT_IH_ARCH_IA64 4 /* IA64 */ -#define GRUB_UBOOT_IH_ARCH_MIPS 5 /* MIPS */ -#define GRUB_UBOOT_IH_ARCH_MIPS64 6 /* MIPS 64 Bit */ -#define GRUB_UBOOT_IH_ARCH_PPC 7 /* PowerPC */ -#define GRUB_UBOOT_IH_ARCH_S390 8 /* IBM S390 */ -#define GRUB_UBOOT_IH_ARCH_SH 9 /* SuperH */ -#define GRUB_UBOOT_IH_ARCH_SPARC 10 /* Sparc */ -#define GRUB_UBOOT_IH_ARCH_SPARC64 11 /* Sparc 64 Bit */ -#define GRUB_UBOOT_IH_ARCH_M68K 12 /* M68K */ -#define GRUB_UBOOT_IH_ARCH_MICROBLAZE 14 /* MicroBlaze */ -#define GRUB_UBOOT_IH_ARCH_NIOS2 15 /* Nios-II */ -#define GRUB_UBOOT_IH_ARCH_BLACKFIN 16 /* Blackfin */ -#define GRUB_UBOOT_IH_ARCH_AVR32 17 /* AVR32 */ -#define GRUB_UBOOT_IH_ARCH_ST200 18 /* STMicroelectronics ST200 */ -#define GRUB_UBOOT_IH_ARCH_SANDBOX 19 /* Sandbox architecture (test only) */ -#define GRUB_UBOOT_IH_ARCH_NDS32 20 /* ANDES Technology - NDS32 */ -#define GRUB_UBOOT_IH_ARCH_OPENRISC 21 /* OpenRISC 1000 */ - -/* - * Image Types - * - * "Standalone Programs" are directly runnable in the environment - * provided by U-Boot; it is expected that (if they behave - * well) you can continue to work in U-Boot after return from - * the Standalone Program. - * "OS Kernel Images" are usually images of some Embedded OS which - * will take over control completely. Usually these programs - * will install their own set of exception handlers, device - * drivers, set up the MMU, etc. - this means, that you cannot - * expect to re-enter U-Boot except by resetting the CPU. - * "RAMDisk Images" are more or less just data blocks, and their - * parameters (address, size) are passed to an OS kernel that is - * being started. - * "Multi-File Images" contain several images, typically an OS - * (Linux) kernel image and one or more data images like - * RAMDisks. This construct is useful for instance when you want - * to boot over the network using BOOTP etc., where the boot - * server provides just a single image file, but you want to get - * for instance an OS kernel and a RAMDisk image. - * - * "Multi-File Images" start with a list of image sizes, each - * image size (in bytes) specified by an "uint32_t" in network - * byte order. This list is terminated by an "(uint32_t)0". - * Immediately after the terminating 0 follow the images, one by - * one, all aligned on "uint32_t" boundaries (size rounded up to - * a multiple of 4 bytes - except for the last file). - * - * "Firmware Images" are binary images containing firmware (like - * U-Boot or FPGA images) which usually will be programmed to - * flash memory. - * - * "Script files" are command sequences that will be executed by - * U-Boot's command interpreter; this feature is especially - * useful when you configure U-Boot to use a real shell (hush) - * as command interpreter (=> Shell Scripts). - */ - -#define GRUB_UBOOT_IH_TYPE_INVALID 0 /* Invalid Image */ -#define GRUB_UBOOT_IH_TYPE_STANDALONE 1 /* Standalone Program */ -#define GRUB_UBOOT_IH_TYPE_KERNEL 2 /* OS Kernel Image */ -#define GRUB_UBOOT_IH_TYPE_RAMDISK 3 /* RAMDisk Image */ -#define GRUB_UBOOT_IH_TYPE_MULTI 4 /* Multi-File Image */ -#define GRUB_UBOOT_IH_TYPE_FIRMWARE 5 /* Firmware Image */ -#define GRUB_UBOOT_IH_TYPE_SCRIPT 6 /* Script file */ -#define GRUB_UBOOT_IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */ -#define GRUB_UBOOT_IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */ -#define GRUB_UBOOT_IH_TYPE_KWBIMAGE 9 /* Kirkwood Boot Image */ -#define GRUB_UBOOT_IH_TYPE_IMXIMAGE 10 /* Freescale IMXBoot Image */ -#define GRUB_UBOOT_IH_TYPE_UBLIMAGE 11 /* Davinci UBL Image */ -#define GRUB_UBOOT_IH_TYPE_OMAPIMAGE 12 /* TI OMAP Config Header Image */ -#define GRUB_UBOOT_IH_TYPE_AISIMAGE 13 /* TI Davinci AIS Image */ -#define GRUB_UBOOT_IH_TYPE_KERNEL_NOLOAD 14 /* OS Kernel Image, can run from any load address */ -#define GRUB_UBOOT_IH_TYPE_PBLIMAGE 15 /* Freescale PBL Boot Image */ - -/* - * Compression Types - */ -#define GRUB_UBOOT_IH_COMP_NONE 0 /* No Compression Used */ -#define GRUB_UBOOT_IH_COMP_GZIP 1 /* gzip Compression Used */ -#define GRUB_UBOOT_IH_COMP_BZIP2 2 /* bzip2 Compression Used */ -#define GRUB_UBOOT_IH_COMP_LZMA 3 /* lzma Compression Used */ -#define GRUB_UBOOT_IH_COMP_LZO 4 /* lzo Compression Used */ - -#define GRUB_UBOOT_IH_MAGIC 0x27051956 /* Image Magic Number */ -#define GRUB_UBOOT_IH_NMLEN 32 /* Image Name Length */ - -/* - * Legacy format image header, - * all data in network byte order (aka natural aka bigendian). - */ -struct grub_uboot_image_header { - grub_uint32_t ih_magic; /* Image Header Magic Number */ - grub_uint32_t ih_hcrc; /* Image Header CRC Checksum */ - grub_uint32_t ih_time; /* Image Creation Timestamp */ - grub_uint32_t ih_size; /* Image Data Size */ - grub_uint32_t ih_load; /* Data Load Address */ - grub_uint32_t ih_ep; /* Entry Point Address */ - grub_uint32_t ih_dcrc; /* Image Data CRC Checksum */ - grub_uint8_t ih_os; /* Operating System */ - grub_uint8_t ih_arch; /* CPU architecture */ - grub_uint8_t ih_type; /* Image Type */ - grub_uint8_t ih_comp; /* Compression Type */ - grub_uint8_t ih_name[GRUB_UBOOT_IH_NMLEN]; /* Image Name */ -}; - -#endif /* __IMAGE_H__ */ diff --git a/include/grub/uboot/uboot.h b/include/grub/uboot/uboot.h deleted file mode 100644 index 194130345..000000000 --- a/include/grub/uboot/uboot.h +++ /dev/null @@ -1,87 +0,0 @@ -/* uboot.h - declare variables and functions for U-Boot support */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_UBOOT_UBOOT_HEADER -#define GRUB_UBOOT_UBOOT_HEADER 1 - -#include -#include - -/* Functions. */ -void grub_uboot_mm_init (void); -void grub_uboot_init (void); -void grub_uboot_fini (void); - -void grub_uboot_return (int) __attribute__ ((noreturn)); - -grub_addr_t grub_uboot_get_real_bss_start (void); - -grub_err_t grub_uboot_probe_hardware (void); - -extern grub_addr_t EXPORT_VAR (start_of_ram); - -grub_uint32_t EXPORT_FUNC (grub_uboot_get_machine_type) (void); -grub_addr_t EXPORT_FUNC (grub_uboot_get_boot_data) (void); - - -/* - * The U-Boot API operates through a "syscall" interface, consisting of an - * entry point address and a set of syscall numbers. The location of this - * entry point is described in a structure allocated on the U-Boot heap. - * We scan through a defined region around the hint address passed to us - * from U-Boot. - */ - -#define UBOOT_API_SEARCH_LEN (3 * 1024 * 1024) -int grub_uboot_api_init (void); - -/* - * All functions below are wrappers around the uboot_syscall() function, - * implemented in grub-core/kern/uboot/uboot.c -*/ - -int grub_uboot_getc (void); -int grub_uboot_tstc (void); -void grub_uboot_putc (int c); -void grub_uboot_puts (const char *s); - -void EXPORT_FUNC (grub_uboot_reset) (void); - -struct sys_info *grub_uboot_get_sys_info (void); - -void grub_uboot_udelay (grub_uint32_t usec); -grub_uint32_t grub_uboot_get_timer (grub_uint32_t base); - -int EXPORT_FUNC (grub_uboot_dev_enum) (void); -struct device_info * EXPORT_FUNC (grub_uboot_dev_get) (int index); -int EXPORT_FUNC (grub_uboot_dev_open) (struct device_info *dev); -int EXPORT_FUNC (grub_uboot_dev_close) (struct device_info *dev); -int grub_uboot_dev_write (struct device_info *dev, const void *buf, - grub_size_t blocks, grub_uint32_t start); -int grub_uboot_dev_read (struct device_info *dev, void *buf, grub_size_t blocks, - grub_uint32_t start, grub_size_t * real_blocks); -int EXPORT_FUNC (grub_uboot_dev_recv) (struct device_info *dev, void *buf, - int size, int *real_size); -int EXPORT_FUNC (grub_uboot_dev_send) (struct device_info *dev, void *buf, - int size); - -char *grub_uboot_env_get (const char *name); -void grub_uboot_env_set (const char *name, const char *value); - -#endif /* ! GRUB_UBOOT_UBOOT_HEADER */ diff --git a/include/grub/udf.h b/include/grub/udf.h deleted file mode 100644 index 905306947..000000000 --- a/include/grub/udf.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_UDF_H -#define GRUB_UDF_H 1 - -#include - -#ifdef GRUB_UTIL -#include - -grub_disk_addr_t -grub_udf_get_cluster_sector (grub_disk_t disk, grub_uint64_t *sec_per_lcn); -#endif -#endif diff --git a/include/grub/unicode.h b/include/grub/unicode.h deleted file mode 100644 index 9360b0b97..000000000 --- a/include/grub/unicode.h +++ /dev/null @@ -1,362 +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 . - */ - -#ifndef GRUB_BIDI_HEADER -#define GRUB_BIDI_HEADER 1 - -#include -#include -#include - -struct grub_unicode_bidi_pair -{ - grub_uint32_t key; - grub_uint32_t replace; -}; - -struct grub_unicode_compact_range -{ - unsigned start:21; - unsigned len:9; - unsigned bidi_type:5; - unsigned comb_type:8; - unsigned bidi_mirror:1; - unsigned join_type:3; -} GRUB_PACKED; - -/* Old-style Arabic shaping. Used for "visual UTF-8" and - in grub-mkfont to find variant glyphs in absence of GPOS tables. */ -struct grub_unicode_arabic_shape -{ - grub_uint32_t code; - grub_uint32_t isolated; - grub_uint32_t right_linked; - grub_uint32_t both_linked; - grub_uint32_t left_linked; -}; - -extern struct grub_unicode_arabic_shape grub_unicode_arabic_shapes[]; - -enum grub_bidi_type - { - GRUB_BIDI_TYPE_L = 0, - GRUB_BIDI_TYPE_LRE, - GRUB_BIDI_TYPE_LRO, - GRUB_BIDI_TYPE_R, - GRUB_BIDI_TYPE_AL, - GRUB_BIDI_TYPE_RLE, - GRUB_BIDI_TYPE_RLO, - GRUB_BIDI_TYPE_PDF, - GRUB_BIDI_TYPE_EN, - GRUB_BIDI_TYPE_ES, - GRUB_BIDI_TYPE_ET, - GRUB_BIDI_TYPE_AN, - GRUB_BIDI_TYPE_CS, - GRUB_BIDI_TYPE_NSM, - GRUB_BIDI_TYPE_BN, - GRUB_BIDI_TYPE_B, - GRUB_BIDI_TYPE_S, - GRUB_BIDI_TYPE_WS, - GRUB_BIDI_TYPE_ON - }; - -enum grub_join_type - { - GRUB_JOIN_TYPE_NONJOINING = 0, - GRUB_JOIN_TYPE_LEFT = 1, - GRUB_JOIN_TYPE_RIGHT = 2, - GRUB_JOIN_TYPE_DUAL = 3, - GRUB_JOIN_TYPE_CAUSING = 4, - GRUB_JOIN_TYPE_TRANSPARENT = 5 - }; - -enum grub_comb_type - { - GRUB_UNICODE_COMB_NONE = 0, - GRUB_UNICODE_COMB_OVERLAY = 1, - GRUB_UNICODE_COMB_HEBREW_SHEVA = 10, - GRUB_UNICODE_COMB_HEBREW_HATAF_SEGOL = 11, - GRUB_UNICODE_COMB_HEBREW_HATAF_PATAH = 12, - GRUB_UNICODE_COMB_HEBREW_HATAF_QAMATS = 13, - GRUB_UNICODE_COMB_HEBREW_HIRIQ = 14, - GRUB_UNICODE_COMB_HEBREW_TSERE = 15, - GRUB_UNICODE_COMB_HEBREW_SEGOL = 16, - GRUB_UNICODE_COMB_HEBREW_PATAH = 17, - GRUB_UNICODE_COMB_HEBREW_QAMATS = 18, - GRUB_UNICODE_COMB_HEBREW_HOLAM = 19, - GRUB_UNICODE_COMB_HEBREW_QUBUTS = 20, - GRUB_UNICODE_COMB_HEBREW_DAGESH = 21, - GRUB_UNICODE_COMB_HEBREW_METEG = 22, - GRUB_UNICODE_COMB_HEBREW_RAFE = 23, - GRUB_UNICODE_COMB_HEBREW_SHIN_DOT = 24, - GRUB_UNICODE_COMB_HEBREW_SIN_DOT = 25, - GRUB_UNICODE_COMB_HEBREW_VARIKA = 26, - GRUB_UNICODE_COMB_ARABIC_FATHATAN = 27, - GRUB_UNICODE_COMB_ARABIC_DAMMATAN = 28, - GRUB_UNICODE_COMB_ARABIC_KASRATAN = 29, - GRUB_UNICODE_COMB_ARABIC_FATHAH = 30, - GRUB_UNICODE_COMB_ARABIC_DAMMAH = 31, - GRUB_UNICODE_COMB_ARABIC_KASRA = 32, - GRUB_UNICODE_COMB_ARABIC_SHADDA = 33, - GRUB_UNICODE_COMB_ARABIC_SUKUN = 34, - GRUB_UNICODE_COMB_ARABIC_SUPERSCRIPT_ALIF = 35, - GRUB_UNICODE_COMB_SYRIAC_SUPERSCRIPT_ALAPH = 36, - GRUB_UNICODE_STACK_ATTACHED_BELOW = 202, - GRUB_UNICODE_STACK_ATTACHED_ABOVE = 214, - GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT = 216, - GRUB_UNICODE_STACK_BELOW = 220, - GRUB_UNICODE_COMB_BELOW_RIGHT = 222, - GRUB_UNICODE_COMB_ABOVE_LEFT = 228, - GRUB_UNICODE_STACK_ABOVE = 230, - GRUB_UNICODE_COMB_ABOVE_RIGHT = 232, - GRUB_UNICODE_COMB_YPOGEGRAMMENI = 240, - /* If combining nature is indicated only by class and - not "combining type". */ - GRUB_UNICODE_COMB_ME = 253, - GRUB_UNICODE_COMB_MC = 254, - GRUB_UNICODE_COMB_MN = 255, - }; - -struct grub_unicode_combining -{ - grub_uint32_t code:21; - enum grub_comb_type type:8; -}; -/* This structure describes a glyph as opposed to character. */ -struct grub_unicode_glyph -{ - grub_uint32_t base:23; /* minimum: 21 */ - grub_uint16_t variant:9; /* minimum: 9 */ - - grub_uint8_t attributes:5; /* minimum: 5 */ - grub_uint8_t bidi_level:6; /* minimum: 6 */ - enum grub_bidi_type bidi_type:5; /* minimum: :5 */ - -#define GRUB_UNICODE_NCOMB_MAX ((1 << 8) - 1) - unsigned ncomb:8; - - /* Hint by unicode subsystem how wide this character usually is. - Real width is determined by font. Set only in UTF-8 stream. */ - int estimated_width:8; - - grub_size_t orig_pos; - union - { - struct grub_unicode_combining combining_inline[sizeof (void *) - / sizeof (struct grub_unicode_combining)]; - struct grub_unicode_combining *combining_ptr; - }; -}; - -#define GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR 0x1 -#define GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT 1 -#define GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED 0x2 -#define GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED \ - (GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED \ - << GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT) -/* Set iff the corresponding joining flags come from ZWJ or ZWNJ. */ -#define GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT 0x8 -#define GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT \ - (GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT \ - << GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN_LEFT_TO_RIGHT_SHIFT) -#define GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN \ - (GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED \ - | GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED \ - | GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT \ - | GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT) - -enum - { - GRUB_UNICODE_DOTLESS_LOWERCASE_I = 0x0131, - GRUB_UNICODE_DOTLESS_LOWERCASE_J = 0x0237, - GRUB_UNICODE_COMBINING_GRAPHEME_JOINER = 0x034f, - GRUB_UNICODE_HEBREW_WAW = 0x05d5, - GRUB_UNICODE_ARABIC_START = 0x0600, - GRUB_UNICODE_ARABIC_END = 0x0700, - GRUB_UNICODE_THAANA_ABAFILI = 0x07a6, - GRUB_UNICODE_THAANA_AABAAFILI = 0x07a7, - GRUB_UNICODE_THAANA_IBIFILI = 0x07a8, - GRUB_UNICODE_THAANA_EEBEEFILI = 0x07a9, - GRUB_UNICODE_THAANA_UBUFILI = 0x07aa, - GRUB_UNICODE_THAANA_OOBOOFILI = 0x07ab, - GRUB_UNICODE_THAANA_EBEFILI = 0x07ac, - GRUB_UNICODE_THAANA_EYBEYFILI = 0x07ad, - GRUB_UNICODE_THAANA_OBOFILI = 0x07ae, - GRUB_UNICODE_THAANA_OABOAFILI = 0x07af, - GRUB_UNICODE_THAANA_SUKUN = 0x07b0, - GRUB_UNICODE_ZWNJ = 0x200c, - GRUB_UNICODE_ZWJ = 0x200d, - GRUB_UNICODE_LRM = 0x200e, - GRUB_UNICODE_RLM = 0x200f, - GRUB_UNICODE_LRE = 0x202a, - GRUB_UNICODE_RLE = 0x202b, - GRUB_UNICODE_PDF = 0x202c, - GRUB_UNICODE_LRO = 0x202d, - GRUB_UNICODE_RLO = 0x202e, - GRUB_UNICODE_LEFTARROW = 0x2190, - GRUB_UNICODE_UPARROW = 0x2191, - GRUB_UNICODE_RIGHTARROW = 0x2192, - GRUB_UNICODE_DOWNARROW = 0x2193, - GRUB_UNICODE_UPDOWNARROW = 0x2195, - GRUB_UNICODE_LIGHT_HLINE = 0x2500, - GRUB_UNICODE_HLINE = 0x2501, - GRUB_UNICODE_LIGHT_VLINE = 0x2502, - GRUB_UNICODE_VLINE = 0x2503, - GRUB_UNICODE_LIGHT_CORNER_UL = 0x250c, - GRUB_UNICODE_CORNER_UL = 0x250f, - GRUB_UNICODE_LIGHT_CORNER_UR = 0x2510, - GRUB_UNICODE_CORNER_UR = 0x2513, - GRUB_UNICODE_LIGHT_CORNER_LL = 0x2514, - GRUB_UNICODE_CORNER_LL = 0x2517, - GRUB_UNICODE_LIGHT_CORNER_LR = 0x2518, - GRUB_UNICODE_CORNER_LR = 0x251b, - GRUB_UNICODE_BLACK_UP_TRIANGLE = 0x25b2, - GRUB_UNICODE_BLACK_RIGHT_TRIANGLE = 0x25ba, - GRUB_UNICODE_BLACK_DOWN_TRIANGLE = 0x25bc, - GRUB_UNICODE_BLACK_LEFT_TRIANGLE = 0x25c4, - GRUB_UNICODE_VARIATION_SELECTOR_1 = 0xfe00, - GRUB_UNICODE_VARIATION_SELECTOR_16 = 0xfe0f, - GRUB_UNICODE_TAG_START = 0xe0000, - GRUB_UNICODE_TAG_END = 0xe007f, - GRUB_UNICODE_VARIATION_SELECTOR_17 = 0xe0100, - GRUB_UNICODE_VARIATION_SELECTOR_256 = 0xe01ef, - GRUB_UNICODE_LAST_VALID = 0x10ffff - }; - -extern struct grub_unicode_compact_range grub_unicode_compact[]; -extern struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[]; - -#define GRUB_UNICODE_MAX_CACHED_CHAR 0x20000 -/* Unicode mandates an arbitrary limit. */ -#define GRUB_BIDI_MAX_EXPLICIT_LEVEL 61 - -struct grub_term_pos -{ - unsigned valid:1; - unsigned x:15, y:16; -}; - -grub_ssize_t -grub_bidi_logical_to_visual (const grub_uint32_t *logical, - grub_size_t logical_len, - struct grub_unicode_glyph **visual_out, - grub_size_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg), - void *getcharwidth_arg, - grub_size_t max_width, - grub_size_t start_width, grub_uint32_t codechar, - struct grub_term_pos *pos, - int primitive_wrap); - -enum grub_comb_type -grub_unicode_get_comb_type (grub_uint32_t c); -grub_size_t -grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, - struct grub_unicode_glyph *out); - -static inline const struct grub_unicode_combining * -grub_unicode_get_comb (const struct grub_unicode_glyph *in) -{ - if (in->ncomb == 0) - return NULL; - if (in->ncomb > ARRAY_SIZE (in->combining_inline)) - return in->combining_ptr; - return in->combining_inline; -} - -static inline void -grub_unicode_destroy_glyph (struct grub_unicode_glyph *glyph) -{ - if (glyph->ncomb > ARRAY_SIZE (glyph->combining_inline)) - grub_free (glyph->combining_ptr); - glyph->ncomb = 0; -} - -static inline struct grub_unicode_glyph * -grub_unicode_glyph_dup (const struct grub_unicode_glyph *in) -{ - struct grub_unicode_glyph *out = grub_malloc (sizeof (*out)); - if (!out) - return NULL; - grub_memcpy (out, in, sizeof (*in)); - if (in->ncomb > ARRAY_SIZE (out->combining_inline)) - { - out->combining_ptr = grub_calloc (in->ncomb, sizeof (out->combining_ptr[0])); - if (!out->combining_ptr) - { - grub_free (out); - return NULL; - } - grub_memcpy (out->combining_ptr, in->combining_ptr, - in->ncomb * sizeof (out->combining_ptr[0])); - } - else - grub_memcpy (&out->combining_inline, &in->combining_inline, - sizeof (out->combining_inline)); - return out; -} - -static inline void -grub_unicode_set_glyph (struct grub_unicode_glyph *out, - const struct grub_unicode_glyph *in) -{ - grub_memcpy (out, in, sizeof (*in)); - if (in->ncomb > ARRAY_SIZE (out->combining_inline)) - { - out->combining_ptr = grub_calloc (in->ncomb, sizeof (out->combining_ptr[0])); - if (!out->combining_ptr) - return; - grub_memcpy (out->combining_ptr, in->combining_ptr, - in->ncomb * sizeof (out->combining_ptr[0])); - } - else - grub_memcpy (&out->combining_inline, &in->combining_inline, - sizeof (out->combining_inline)); -} - -static inline struct grub_unicode_glyph * -grub_unicode_glyph_from_code (grub_uint32_t code) -{ - struct grub_unicode_glyph *ret; - ret = grub_zalloc (sizeof (*ret)); - if (!ret) - return NULL; - - ret->base = code; - - return ret; -} - -static inline void -grub_unicode_set_glyph_from_code (struct grub_unicode_glyph *glyph, - grub_uint32_t code) -{ - grub_memset (glyph, 0, sizeof (*glyph)); - - glyph->base = code; -} - -grub_uint32_t -grub_unicode_mirror_code (grub_uint32_t in); -grub_uint32_t -grub_unicode_shape_code (grub_uint32_t in, grub_uint8_t attr); - -const grub_uint32_t * -grub_unicode_get_comb_end (const grub_uint32_t *end, - const grub_uint32_t *cur); - -#endif diff --git a/include/grub/usb.h b/include/grub/usb.h index 0f346af12..dc90e7879 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -19,14 +19,9 @@ #ifndef GRUB_USB_H #define GRUB_USB_H 1 -#include #include #include -#define GRUB_USB_MAX_CONF 8 -#define GRUB_USB_MAX_IF 32 -#define GRUB_USB_MAX_TOGGLE 256 - 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; @@ -34,16 +29,13 @@ typedef struct grub_usb_controller_dev *grub_usb_controller_dev_t; typedef enum { GRUB_USB_ERR_NONE, - GRUB_USB_ERR_WAIT, 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_UNRECOVERABLE, - GRUB_USB_ERR_BADDEVICE + GRUB_USB_ERR_BITSTUFF } grub_usb_err_t; typedef enum @@ -54,12 +46,8 @@ typedef enum GRUB_USB_SPEED_HIGH } grub_usb_speed_t; -typedef int (*grub_usb_iterate_hook_t) (grub_usb_device_t dev, void *data); -typedef int (*grub_usb_controller_iterate_hook_t) (grub_usb_controller_t dev, - void *data); - /* Call HOOK with each device, until HOOK returns non-zero. */ -int grub_usb_iterate (grub_usb_iterate_hook_t hook, void *hook_data); +int grub_usb_iterate (int (*hook) (grub_usb_device_t dev)); grub_usb_err_t grub_usb_device_initialize (grub_usb_device_t dev); @@ -67,6 +55,9 @@ 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); @@ -77,8 +68,7 @@ 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 (grub_usb_controller_iterate_hook_t hook, - void *hook_data); +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, @@ -88,52 +78,32 @@ grub_usb_err_t grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype grub_usb_err_t grub_usb_bulk_read (grub_usb_device_t dev, - struct grub_usb_desc_endp *endpoint, - grub_size_t size, char *data); + int endpoint, grub_size_t size, char *data); grub_usb_err_t grub_usb_bulk_write (grub_usb_device_t dev, - struct grub_usb_desc_endp *endpoint, - grub_size_t size, char *data); + int endpoint, grub_size_t size, char *data); grub_usb_err_t grub_usb_root_hub (grub_usb_controller_t controller); - /* XXX: All handled by libusb for now. */ struct grub_usb_controller_dev { /* The device name. */ const char *name; - int (*iterate) (grub_usb_controller_iterate_hook_t hook, void *hook_data); + int (*iterate) (int (*hook) (grub_usb_controller_t dev)); - grub_usb_err_t (*setup_transfer) (grub_usb_controller_t dev, - grub_usb_transfer_t transfer); - - grub_usb_err_t (*check_transfer) (grub_usb_controller_t dev, - grub_usb_transfer_t transfer, - grub_size_t *actual); - - grub_usb_err_t (*cancel_transfer) (grub_usb_controller_t dev, - grub_usb_transfer_t transfer); + grub_usb_err_t (*transfer) (grub_usb_controller_t dev, + grub_usb_transfer_t transfer); int (*hubports) (grub_usb_controller_t dev); - grub_usb_err_t (*portstatus) (grub_usb_controller_t dev, unsigned int port, - unsigned int enable); + 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, int *changed); - - /* Per controller flag - port reset pending, don't do another reset */ - grub_uint64_t pending_reset; - - /* Max. number of transfer descriptors used per one bulk transfer */ - /* The reason is to prevent "exhausting" of TD by large bulk */ - /* transfer - number of TD is limited in USB host driver */ - /* Value is calculated/estimated in driver - some TDs should be */ - /* reserved for posible concurrent control or "interrupt" transfers */ - grub_size_t max_bulk_tds; + grub_usb_speed_t (*detect_dev) (grub_usb_controller_t dev, int port); /* The next host controller. */ struct grub_usb_controller_dev *next; @@ -154,15 +124,6 @@ struct grub_usb_interface struct grub_usb_desc_if *descif; struct grub_usb_desc_endp *descendp; - - /* A driver is handling this interface. Do we need to support multiple drivers - for single interface? - */ - int attached; - - void (*detach_hook) (struct grub_usb_device *dev, int config, int interface); - - void *detach_data; }; struct grub_usb_configuration @@ -171,19 +132,7 @@ struct grub_usb_configuration struct grub_usb_desc_config *descconf; /* Interfaces associated to this configuration. */ - struct grub_usb_interface interf[GRUB_USB_MAX_IF]; -}; - -struct grub_usb_hub_port -{ - grub_uint64_t soft_limit_time; - grub_uint64_t hard_limit_time; - enum { - PORT_STATE_NORMAL = 0, - PORT_STATE_WAITING_FOR_STABLE_POWER = 1, - PORT_STATE_FAILED_DEVICE = 2, - PORT_STATE_STABLE_POWER = 3, - } state; + struct grub_usb_interface interf[32]; }; struct grub_usb_device @@ -195,7 +144,7 @@ struct grub_usb_device struct grub_usb_controller controller; /* Device configurations (after opening the device). */ - struct grub_usb_configuration config[GRUB_USB_MAX_CONF]; + struct grub_usb_configuration config[8]; /* Device address. */ int addr; @@ -207,49 +156,14 @@ struct grub_usb_device int initialized; /* Data toggle values (used for bulk transfers only). */ - int toggle[GRUB_USB_MAX_TOGGLE]; + int toggle[16]; - /* Used by libusb wrapper. Schedulded for removal. */ + /* Device-specific data. */ void *data; - - /* Hub information. */ - - /* Array of children for a hub. */ - grub_usb_device_t *children; - - /* Number of hub ports. */ - unsigned nports; - - struct grub_usb_hub_port *ports; - - grub_usb_transfer_t hub_transfer; - - grub_uint32_t statuschange; - - struct grub_usb_desc_endp *hub_endpoint; - - /* EHCI Split Transfer information */ - int split_hubport; - - int split_hubaddr; }; -typedef enum grub_usb_ep_type - { - GRUB_USB_EP_CONTROL, - GRUB_USB_EP_ISOCHRONOUS, - GRUB_USB_EP_BULK, - GRUB_USB_EP_INTERRUPT - } grub_usb_ep_type_t; - -static inline enum grub_usb_ep_type -grub_usb_get_ep_type (struct grub_usb_desc_endp *ep) -{ - return ep->attrib & 3; -} - typedef enum { GRUB_USB_CLASS_NOTHERE, @@ -270,20 +184,12 @@ typedef enum typedef enum { - GRUB_USBMS_SUBCLASS_BULK = 0x06, - /* Experimental support for non-pure SCSI devices */ - GRUB_USBMS_SUBCLASS_RBC = 0x01, - GRUB_USBMS_SUBCLASS_MMC2 = 0x02, - GRUB_USBMS_SUBCLASS_UFI = 0x04, - GRUB_USBMS_SUBCLASS_SFF8070 = 0x05 + GRUB_USBMS_SUBCLASS_BULK = 0x06 } grub_usbms_subclass_t; typedef enum { - GRUB_USBMS_PROTOCOL_BULK = 0x50, - /* Experimental support for Control/Bulk/Interrupt (CBI) devices */ - GRUB_USBMS_PROTOCOL_CBI = 0x00, /* CBI with interrupt */ - GRUB_USBMS_PROTOCOL_CB = 0x01 /* CBI wthout interrupt */ + GRUB_USBMS_PROTOCOL_BULK = 0x50 } grub_usbms_protocol_t; static inline struct grub_usb_desc_if * @@ -295,39 +201,4 @@ grub_usb_get_config_interface (struct grub_usb_desc_config *config) return interf; } -typedef int (*grub_usb_attach_hook_class) (grub_usb_device_t usbdev, - int configno, int interfno); - -struct grub_usb_attach_desc -{ - struct grub_usb_attach_desc *next; - struct grub_usb_attach_desc **prev; - int class; - grub_usb_attach_hook_class hook; -}; - -void grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc); -void grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc); - -void grub_usb_poll_devices (int wait_for_completion); - -void grub_usb_device_attach (grub_usb_device_t dev); -grub_usb_err_t -grub_usb_bulk_read_extended (grub_usb_device_t dev, - struct grub_usb_desc_endp *endpoint, - grub_size_t size, char *data, - int timeout, grub_size_t *actual); -grub_usb_transfer_t -grub_usb_bulk_read_background (grub_usb_device_t dev, - struct grub_usb_desc_endp *endpoint, - grub_size_t size, void *data); -grub_usb_err_t -grub_usb_check_transfer (grub_usb_transfer_t trans, grub_size_t *actual); -void -grub_usb_cancel_transfer (grub_usb_transfer_t trans); -void -grub_ehci_init_device (volatile void *regs); -void -grub_ehci_pci_scan (void); - #endif /* GRUB_USB_H */ diff --git a/include/grub/usbdesc.h b/include/grub/usbdesc.h index aac5ab05a..2f711d755 100644 --- a/include/grub/usbdesc.h +++ b/include/grub/usbdesc.h @@ -28,16 +28,9 @@ typedef enum { GRUB_USB_DESCRIPTOR_STRING, GRUB_USB_DESCRIPTOR_INTERFACE, GRUB_USB_DESCRIPTOR_ENDPOINT, - GRUB_USB_DESCRIPTOR_DEBUG = 10, GRUB_USB_DESCRIPTOR_HUB = 0x29 } grub_usb_descriptor_t; -struct grub_usb_desc -{ - grub_uint8_t length; - grub_uint8_t type; -} GRUB_PACKED; - struct grub_usb_desc_device { grub_uint8_t length; @@ -54,7 +47,7 @@ struct grub_usb_desc_device grub_uint8_t strprod; grub_uint8_t strserial; grub_uint8_t configcnt; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_usb_desc_config { @@ -66,7 +59,7 @@ struct grub_usb_desc_config grub_uint8_t strconfig; grub_uint8_t attrib; grub_uint8_t maxpower; -} GRUB_PACKED; +} __attribute__ ((packed)); #if 0 struct grub_usb_desc_if_association @@ -79,7 +72,7 @@ struct grub_usb_desc_if_association grub_uint8_t subclass; grub_uint8_t protocol; grub_uint8_t function; -} GRUB_PACKED; +} __attribute__ ((packed)); #endif struct grub_usb_desc_if @@ -93,7 +86,7 @@ struct grub_usb_desc_if grub_uint8_t subclass; grub_uint8_t protocol; grub_uint8_t strif; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_usb_desc_endp { @@ -103,22 +96,14 @@ struct grub_usb_desc_endp grub_uint8_t attrib; grub_uint16_t maxpacket; grub_uint8_t interval; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_usb_desc_str { grub_uint8_t length; grub_uint8_t type; grub_uint16_t str[0]; -} GRUB_PACKED; - -struct grub_usb_desc_debug -{ - grub_uint8_t length; - grub_uint8_t type; - grub_uint8_t in_endp; - grub_uint8_t out_endp; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_usb_usb_hubdesc { @@ -129,6 +114,6 @@ struct grub_usb_usb_hubdesc grub_uint8_t pwdgood; grub_uint8_t current; /* Removable and power control bits follow. */ -} GRUB_PACKED; +} __attribute__ ((packed)); #endif /* GRUB_USBDESC_H */ diff --git a/include/grub/usbserial.h b/include/grub/usbserial.h deleted file mode 100644 index f81f97a51..000000000 --- a/include/grub/usbserial.h +++ /dev/null @@ -1,39 +0,0 @@ -/* serial.h - serial device interface */ -/* - * 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 . - */ - -#ifndef GRUB_USBSERIAL_HEADER -#define GRUB_USBSERIAL_HEADER 1 - -void grub_usbserial_fini (struct grub_serial_port *port); - -void grub_usbserial_detach (grub_usb_device_t usbdev, int configno, - int interfno); - -int -grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno, - struct grub_serial_driver *driver, int in_endp, - int out_endp); -enum - { - GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING = -1 - }; -int -grub_usbserial_fetch (struct grub_serial_port *port, grub_size_t header_size); - -#endif diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index 039ebed65..7e4a9d7ee 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -19,8 +19,6 @@ #ifndef GRUB_USBTRANS_H #define GRUB_USBTRANS_H 1 -#define MAX_USB_TRANSFER_LEN 0x0800 - typedef enum { GRUB_USB_TRANSFER_TYPE_IN, @@ -39,8 +37,7 @@ struct grub_usb_transaction int size; int toggle; grub_transfer_type_t pid; - grub_uint32_t data; - grub_size_t preceding; + char *data; }; typedef struct grub_usb_transaction *grub_usb_transaction_t; @@ -58,89 +55,44 @@ struct grub_usb_transfer grub_transaction_type_t type; - grub_transfer_type_t dir; - struct grub_usb_device *dev; struct grub_usb_transaction *transactions; - - int last_trans; - /* Index of last processed transaction in OHCI/UHCI driver. */ - - void *controller_data; - - /* Used when finishing transfer to copy data back. */ - struct grub_pci_dma_chunk *data_chunk; - void *data; }; typedef struct grub_usb_transfer *grub_usb_transfer_t; +#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) -enum - { - GRUB_USB_REQTYPE_TARGET_DEV = (0 << 0), - GRUB_USB_REQTYPE_TARGET_INTERF = (1 << 0), - GRUB_USB_REQTYPE_TARGET_ENDP = (2 << 0), - GRUB_USB_REQTYPE_TARGET_OTHER = (3 << 0), - GRUB_USB_REQTYPE_STANDARD = (0 << 5), - GRUB_USB_REQTYPE_CLASS = (1 << 5), - GRUB_USB_REQTYPE_VENDOR = (2 << 5), - GRUB_USB_REQTYPE_OUT = (0 << 7), - GRUB_USB_REQTYPE_IN = (1 << 7), - GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT = GRUB_USB_REQTYPE_TARGET_INTERF - | GRUB_USB_REQTYPE_CLASS | GRUB_USB_REQTYPE_OUT, - GRUB_USB_REQTYPE_VENDOR_OUT = GRUB_USB_REQTYPE_VENDOR | GRUB_USB_REQTYPE_OUT, - GRUB_USB_REQTYPE_CLASS_INTERFACE_IN = GRUB_USB_REQTYPE_TARGET_INTERF - | GRUB_USB_REQTYPE_CLASS | GRUB_USB_REQTYPE_IN, - GRUB_USB_REQTYPE_VENDOR_IN = GRUB_USB_REQTYPE_VENDOR | GRUB_USB_REQTYPE_IN - }; +#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 -enum - { - GRUB_USB_REQ_GET_STATUS = 0x00, - GRUB_USB_REQ_CLEAR_FEATURE = 0x01, - GRUB_USB_REQ_SET_FEATURE = 0x03, - GRUB_USB_REQ_SET_ADDRESS = 0x05, - GRUB_USB_REQ_GET_DESCRIPTOR = 0x06, - GRUB_USB_REQ_SET_DESCRIPTOR = 0x07, - GRUB_USB_REQ_GET_CONFIGURATION = 0x08, - GRUB_USB_REQ_SET_CONFIGURATION = 0x09, - GRUB_USB_REQ_GET_INTERFACE = 0x0A, - GRUB_USB_REQ_SET_INTERFACE = 0x0B, - GRUB_USB_REQ_SYNC_FRAME = 0x0C - }; +#define GRUB_USB_REQ_HUB_GET_PORT_STATUS 0x00 -#define GRUB_USB_FEATURE_ENDP_HALT 0x00 -#define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x01 -#define GRUB_USB_FEATURE_TEST_MODE 0x02 +#define GRUB_USB_FEATURE_ENDP_HALT 0x01 +#define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x02 +#define GRUB_USB_FEATURE_TEST_MODE 0x04 -enum - { - GRUB_USB_HUB_FEATURE_PORT_RESET = 0x04, - GRUB_USB_HUB_FEATURE_PORT_POWER = 0x08, - GRUB_USB_HUB_FEATURE_C_PORT_CONNECTED = 0x10, - GRUB_USB_HUB_FEATURE_C_PORT_ENABLED = 0x11, - GRUB_USB_HUB_FEATURE_C_PORT_SUSPEND = 0x12, - GRUB_USB_HUB_FEATURE_C_PORT_OVERCURRENT = 0x13, - GRUB_USB_HUB_FEATURE_C_PORT_RESET = 0x14 - }; - -enum - { - GRUB_USB_HUB_STATUS_PORT_CONNECTED = (1 << 0), - GRUB_USB_HUB_STATUS_PORT_ENABLED = (1 << 1), - GRUB_USB_HUB_STATUS_PORT_SUSPEND = (1 << 2), - GRUB_USB_HUB_STATUS_PORT_OVERCURRENT = (1 << 3), - GRUB_USB_HUB_STATUS_PORT_POWERED = (1 << 8), - GRUB_USB_HUB_STATUS_PORT_LOWSPEED = (1 << 9), - GRUB_USB_HUB_STATUS_PORT_HIGHSPEED = (1 << 10), - GRUB_USB_HUB_STATUS_C_PORT_CONNECTED = (1 << 16), - GRUB_USB_HUB_STATUS_C_PORT_ENABLED = (1 << 17), - GRUB_USB_HUB_STATUS_C_PORT_SUSPEND = (1 << 18), - GRUB_USB_HUB_STATUS_C_PORT_OVERCURRENT = (1 << 19), - GRUB_USB_HUB_STATUS_C_PORT_RESET = (1 << 20) - }; +#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 { @@ -149,7 +101,7 @@ struct grub_usb_packet_setup grub_uint16_t value; grub_uint16_t index; grub_uint16_t length; -} GRUB_PACKED; +} __attribute__((packed)); #endif /* GRUB_USBTRANS_H */ diff --git a/include/grub/emu/console.h b/include/grub/util/console.h similarity index 100% rename from include/grub/emu/console.h rename to include/grub/util/console.h diff --git a/include/grub/util/deviceiter.h b/include/grub/util/deviceiter.h new file mode 100644 index 000000000..a8af03cfe --- /dev/null +++ b/include/grub/util/deviceiter.h @@ -0,0 +1,11 @@ +#ifndef GRUB_DEVICEITER_MACHINE_UTIL_HEADER +#define GRUB_DEVICEITER_MACHINE_UTIL_HEADER 1 + +#include + +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/bus/usb/ehci-fdt.c b/include/grub/util/getroot.h similarity index 52% rename from grub-core/bus/usb/ehci-fdt.c rename to include/grub/util/getroot.h index 29b50bdd5..f9f7f9baa 100644 --- a/grub-core/bus/usb/ehci-fdt.c +++ b/include/grub/util/getroot.h @@ -1,7 +1,6 @@ -/* ehci.c - EHCI Support. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. + * 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 @@ -17,29 +16,20 @@ * along with GRUB. If not, see . */ -#include -#include -#include -#include -#include +#ifndef GRUB_UTIL_GETROOT_HEADER +#define GRUB_UTIL_GETROOT_HEADER 1 -static grub_err_t -ehci_attach(const struct grub_fdtbus_dev *dev) -{ - grub_dprintf ("ehci", "Found generic-ehci\n"); - - grub_ehci_init_device (grub_fdtbus_map_reg (dev, 0, 0)); - return 0; -} - -struct grub_fdtbus_driver ehci = -{ - .compatible = "generic-ehci", - .attach = ehci_attach +enum grub_dev_abstraction_types { + GRUB_DEV_ABSTRACTION_NONE, + GRUB_DEV_ABSTRACTION_LVM, + GRUB_DEV_ABSTRACTION_RAID, }; -void -grub_ehci_pci_scan (void) -{ - grub_fdtbus_register (&ehci); -} +char *grub_guess_root_device (const char *dir); +char *grub_get_prefix (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 new file mode 100644 index 000000000..21efb0d17 --- /dev/null +++ b/include/grub/util/hostdisk.h @@ -0,0 +1,27 @@ +/* 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 . + */ + +#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/util/install.h b/include/grub/util/install.h deleted file mode 100644 index 5c0a52ca2..000000000 --- a/include/grub/util/install.h +++ /dev/null @@ -1,304 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_UTIL_INSTALL_HEADER -#define GRUB_UTIL_INSTALL_HEADER 1 - -#include -#include - -#include -#include -#include - -#define GRUB_INSTALL_OPTIONS \ - { "modules", GRUB_INSTALL_OPTIONS_MODULES, N_("MODULES"), \ - 0, N_("pre-load specified modules MODULES"), 1 }, \ - { "dtb", GRUB_INSTALL_OPTIONS_DTB, N_("FILE"), \ - 0, N_("embed a specific DTB"), 1 }, \ - { "install-modules", GRUB_INSTALL_OPTIONS_INSTALL_MODULES, \ - N_("MODULES"), 0, \ - N_("install only MODULES and their dependencies [default=all]"), 1 }, \ - { "themes", GRUB_INSTALL_OPTIONS_INSTALL_THEMES, N_("THEMES"), \ - 0, N_("install THEMES [default=%s]"), 1 }, \ - { "fonts", GRUB_INSTALL_OPTIONS_INSTALL_FONTS, N_("FONTS"), \ - 0, N_("install FONTS [default=%s]"), 1 }, \ - { "locales", GRUB_INSTALL_OPTIONS_INSTALL_LOCALES, N_("LOCALES"),\ - 0, N_("install only LOCALES [default=all]"), 1 }, \ - { "compress", GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS, \ - "no|xz|gz|lzo", 0, \ - N_("compress GRUB files [optional]"), 1 }, \ - {"core-compress", GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS, \ - "xz|none|auto", \ - 0, N_("choose the compression to use for core image"), 2}, \ - /* TRANSLATORS: platform here isn't identifier. It can be translated. */ \ - { "directory", 'd', N_("DIR"), 0, \ - N_("use images and modules under DIR [default=%s/]"), 1 }, \ - { "override-directory", GRUB_INSTALL_OPTIONS_DIRECTORY2, \ - N_("DIR"), OPTION_HIDDEN, \ - N_("use images and modules under DIR [default=%s/]"), 1 }, \ - { "locale-directory", GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY, \ - N_("DIR"), 0, \ - N_("use translations under DIR [default=%s]"), 1 }, \ - { "themes-directory", GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY, \ - N_("DIR"), OPTION_HIDDEN, \ - N_("use themes under DIR [default=%s]"), 1 }, \ - { "grub-mkimage", GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE, \ - "FILE", OPTION_HIDDEN, 0, 1 }, \ - /* TRANSLATORS: "embed" is a verb (command description). "*/ \ - { "pubkey", 'k', N_("FILE"), 0, \ - N_("embed FILE as public key for signature checking"), 0}, \ - { "sbat", GRUB_INSTALL_OPTIONS_SBAT, N_("FILE"), 0, \ - N_("SBAT metadata"), 0 }, \ - { "disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, \ - N_("disable shim_lock verifier"), 0 }, \ - { "disable-cli", GRUB_INSTALL_OPTIONS_DISABLE_CLI, 0, 0, \ - N_("disabled command line interface access"), 0 }, \ - { "verbose", 'v', 0, 0, \ - N_("print verbose messages."), 1 } - -int -grub_install_parse (int key, char *arg); - -void -grub_install_push_module (const char *val); - -void -grub_install_pop_module (void); - -char * -grub_install_help_filter (int key, const char *text, - void *input __attribute__ ((unused))); - -enum grub_install_plat - { - GRUB_INSTALL_PLATFORM_I386_PC, - GRUB_INSTALL_PLATFORM_I386_EFI, - GRUB_INSTALL_PLATFORM_I386_QEMU, - GRUB_INSTALL_PLATFORM_I386_COREBOOT, - GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, - GRUB_INSTALL_PLATFORM_I386_IEEE1275, - GRUB_INSTALL_PLATFORM_X86_64_EFI, - GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, - GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275, - GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, - GRUB_INSTALL_PLATFORM_MIPSEL_ARC, - GRUB_INSTALL_PLATFORM_MIPS_ARC, - GRUB_INSTALL_PLATFORM_IA64_EFI, - GRUB_INSTALL_PLATFORM_ARM_UBOOT, - GRUB_INSTALL_PLATFORM_ARM_EFI, - GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, - GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, - GRUB_INSTALL_PLATFORM_I386_XEN, - GRUB_INSTALL_PLATFORM_X86_64_XEN, - GRUB_INSTALL_PLATFORM_I386_XEN_PVH, - GRUB_INSTALL_PLATFORM_ARM64_EFI, - GRUB_INSTALL_PLATFORM_ARM_COREBOOT, - GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI, - GRUB_INSTALL_PLATFORM_RISCV32_EFI, - GRUB_INSTALL_PLATFORM_RISCV64_EFI, - GRUB_INSTALL_PLATFORM_MAX - }; - -enum grub_install_options { - GRUB_INSTALL_OPTIONS_DIRECTORY = 'd', - GRUB_INSTALL_OPTIONS_VERBOSITY = 'v', - GRUB_INSTALL_OPTIONS_MODULES = 0x201, - GRUB_INSTALL_OPTIONS_INSTALL_MODULES, - GRUB_INSTALL_OPTIONS_INSTALL_THEMES, - GRUB_INSTALL_OPTIONS_INSTALL_FONTS, - GRUB_INSTALL_OPTIONS_INSTALL_LOCALES, - GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS, - GRUB_INSTALL_OPTIONS_DIRECTORY2, - GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY, - GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY, - GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE, - GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS, - GRUB_INSTALL_OPTIONS_DTB, - GRUB_INSTALL_OPTIONS_SBAT, - GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, - GRUB_INSTALL_OPTIONS_DISABLE_CLI -}; - -extern char *grub_install_source_directory; - -enum grub_install_plat -grub_install_get_target (const char *src); -void -grub_install_mkdir_p (const char *dst); - -void -grub_install_copy_files (const char *src, - const char *dst, - enum grub_install_plat platid); -char * -grub_install_get_platform_name (enum grub_install_plat platid); - -const char * -grub_install_get_platform_cpu (enum grub_install_plat platid); - -const char * -grub_install_get_platform_platform (enum grub_install_plat platid); - -char * -grub_install_get_platforms_string (void); - -typedef enum { - GRUB_COMPRESSION_AUTO, - GRUB_COMPRESSION_NONE, - GRUB_COMPRESSION_XZ, - GRUB_COMPRESSION_LZMA -} grub_compression_t; - -void -grub_install_make_image_wrap (const char *dir, const char *prefix, - const char *outname, char *memdisk_path, - char *config_path, - const char *format, int note); -void -grub_install_make_image_wrap_file (const char *dir, const char *prefix, - FILE *fp, const char *outname, - char *memdisk_path, - char *config_path, - const char *mkimage_target, int note); - -int -grub_install_copy_file (const char *src, - const char *dst, - int is_critical); - -struct grub_install_image_target_desc; - -void -grub_install_generate_image (const char *dir, const char *prefix, - FILE *out, - const char *outname, char *mods[], - char *memdisk_path, char **pubkey_paths, - size_t npubkeys, - char *config_path, - const struct grub_install_image_target_desc *image_target, - int note, - grub_compression_t comp, const char *dtb_file, - const char *sbat_path, const int disable_shim_lock, - const int disable_cli); - -const struct grub_install_image_target_desc * -grub_install_get_image_target (const char *arg); - -void -grub_util_bios_setup (const char *dir, - const char *boot_file, const char *core_file, - const char *dest, int force, - int fs_probe, int allow_floppy, - int add_rs_codes, int warn_short_mbr_gap); -void -grub_util_sparc_setup (const char *dir, - const char *boot_file, const char *core_file, - const char *dest, int force, - int fs_probe, int allow_floppy, - int add_rs_codes, int warn_short_mbr_gap); - -char * -grub_install_get_image_targets_string (void); - -const char * -grub_util_get_target_dirname (const struct grub_install_image_target_desc *t); - -void -grub_install_create_envblk_file (const char *name); - -const char * -grub_install_get_default_arm_platform (void); - -const char * -grub_install_get_default_x86_platform (void); - -int -grub_install_register_efi (grub_device_t efidir_grub_dev, - const char *efifile_path, - const char *efi_distributor); - -void -grub_install_register_ieee1275 (int is_prep, const char *install_device, - int partno, const char *relpath); - -void -grub_install_sgi_setup (const char *install_device, - const char *imgfile, const char *destname); - -int -grub_install_compress_gzip (const char *src, const char *dest); -int -grub_install_compress_lzop (const char *src, const char *dest); -int -grub_install_compress_xz (const char *src, const char *dest); - -void -grub_install_get_blocklist (grub_device_t root_dev, - const char *core_path, const char *core_img, - size_t core_size, - void (*callback) (grub_disk_addr_t sector, - unsigned offset, - unsigned length, - void *data), - void *hook_data); - -void -grub_util_create_envblk_file (const char *name); - -void -grub_util_glue_efi (const char *file32, const char *file64, const char *out); - -void -grub_util_render_label (const char *label_font, - const char *label_bgcolor, - const char *label_color, - const char *label_string, - const char *label); - -const char * -grub_util_get_target_name (const struct grub_install_image_target_desc *t); - -extern char *grub_install_copy_buffer; -#define GRUB_INSTALL_COPY_BUFFER_SIZE 1048576 - -int -grub_install_is_short_mbrgap_supported (void); - -/* - * grub-install-common tries to make backups of modules & auxiliary files, - * and restore the backup upon failure to install core.img. There are - * platforms with additional actions after modules & core got installed - * in place. It is a point of no return, as core.img cannot be reverted - * from this point onwards, and new modules should be kept installed. - * Before performing these additional actions call grub_set_install_backup_ponr() - * to set the grub_install_backup_ponr flag. This way failure to perform - * subsequent actions will not result in reverting new modules to the - * old ones, e.g. in case efivars updates fails. - */ -#ifdef HAVE_ATEXIT -extern void -grub_set_install_backup_ponr (void); -#else -static inline void -grub_set_install_backup_ponr (void) -{ -} -#endif - -#endif diff --git a/include/grub/util/libnvpair.h b/include/grub/util/libnvpair.h deleted file mode 100644 index a3acffb88..000000000 --- a/include/grub/util/libnvpair.h +++ /dev/null @@ -1,44 +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 . - */ - -#ifndef GRUB_LIBNVPAIR_UTIL_HEADER -#define GRUB_LIBNVPAIR_UTIL_HEADER 1 - -#include - -#ifdef HAVE_LIBNVPAIR_H -#include -#else /* ! HAVE_LIBNVPAIR_H */ - -#include /* FILE */ - -typedef void nvlist_t; - -#ifdef GRUB_UTIL_NVPAIR_IS_PREFIXED -#define NVLIST(x) opensolaris_nvlist_ ## x -#else -#define NVLIST(x) nvlist_ ## x -#endif - -int NVLIST(lookup_string) (nvlist_t *, const char *, char **); -int NVLIST(lookup_nvlist) (nvlist_t *, const char *, nvlist_t **); -int NVLIST(lookup_nvlist_array) (nvlist_t *, const char *, nvlist_t ***, unsigned int *); - -#endif /* ! HAVE_LIBNVPAIR_H */ - -#endif diff --git a/include/grub/util/libzfs.h b/include/grub/util/libzfs.h deleted file mode 100644 index a02caa335..000000000 --- a/include/grub/util/libzfs.h +++ /dev/null @@ -1,47 +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 . - */ - -#ifndef GRUB_LIBZFS_UTIL_HEADER -#define GRUB_LIBZFS_UTIL_HEADER 1 - -#include - -#ifdef HAVE_LIBZFS_H -#include -#else /* ! HAVE_LIBZFS_H */ - -#include - -typedef void libzfs_handle_t; -typedef void zpool_handle_t; - -extern libzfs_handle_t *libzfs_init (void); -extern void libzfs_fini (libzfs_handle_t *); - -extern zpool_handle_t *zpool_open (libzfs_handle_t *, const char *); -extern void zpool_close (zpool_handle_t *); - -extern int zpool_get_physpath (zpool_handle_t *, const char *); - -extern nvlist_t *zpool_get_config (zpool_handle_t *, nvlist_t **); - -#endif /* ! HAVE_LIBZFS_H */ - -libzfs_handle_t *grub_get_libzfs_handle (void); - -#endif diff --git a/include/grub/fileid.h b/include/grub/util/lvm.h similarity index 72% rename from include/grub/fileid.h rename to include/grub/util/lvm.h index ae75b6912..7a4c76c6b 100644 --- a/include/grub/fileid.h +++ b/include/grub/util/lvm.h @@ -1,6 +1,7 @@ +/* lvm.h - LVM support for GRUB utils. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. + * 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 @@ -16,14 +17,11 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_FILEID_HEADER -#define GRUB_FILEID_HEADER 1 - -#include - -int -grub_file_check_netbsd32 (grub_elf_t elf); -int -grub_file_check_netbsd64 (grub_elf_t elf); +#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 index e9e0a6724..373fff8bb 100644 --- a/include/grub/util/misc.h +++ b/include/grub/util/misc.h @@ -27,26 +27,67 @@ #include #include -#include -#include + +#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 grub_util_warn (const char *fmt, ...); +void grub_util_info (const char *fmt, ...); +void 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, - const char *name); +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, const char *name); + 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 *grub_canonicalize_file_name (const char *path); - void grub_util_init_nls (void); -void grub_util_host_init (int *argc, char ***argv); - -int grub_qsort_strcmp (const void *, const void *); - #endif /* ! GRUB_UTIL_MISC_HEADER */ diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h deleted file mode 100644 index 9d74f82c5..000000000 --- a/include/grub/util/mkimage.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_UTIL_MKIMAGE_HEADER -#define GRUB_UTIL_MKIMAGE_HEADER 1 - -struct grub_mkimage_layout -{ - size_t exec_size; - size_t kernel_size; - size_t bss_size; - size_t sbat_size; - grub_uint64_t start_address; - void *reloc_section; - size_t reloc_size; - size_t align; - grub_size_t ia64jmp_off; - grub_size_t tramp_off; - grub_size_t got_off; - grub_size_t got_size; - unsigned ia64jmpnum; - grub_uint32_t bss_start; - grub_uint32_t end; -}; - -/* Private header. Use only in mkimage-related sources. */ -char * -grub_mkimage_load_image32 (const char *kernel_path, - size_t total_module_size, - struct grub_mkimage_layout *layout, - const struct grub_install_image_target_desc *image_target); -char * -grub_mkimage_load_image64 (const char *kernel_path, - size_t total_module_size, - struct grub_mkimage_layout *layout, - const struct grub_install_image_target_desc *image_target); -void -grub_mkimage_generate_elf32 (const struct grub_install_image_target_desc *image_target, - int note, char *sbat, char **core_img, size_t *core_size, - Elf32_Addr target_addr, - struct grub_mkimage_layout *layout); -void -grub_mkimage_generate_elf64 (const struct grub_install_image_target_desc *image_target, - int note, char *sbat, char **core_img, size_t *core_size, - Elf64_Addr target_addr, - struct grub_mkimage_layout *layout); - -struct grub_install_image_target_desc -{ - const char *dirname; - const char *names[6]; - grub_size_t voidp_sizeof; - int bigendian; - enum { - IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, - IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_SPARC64_CDCORE, - IMAGE_I386_IEEE1275, - IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH, - IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC, - IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT, IMAGE_XEN, IMAGE_I386_PC_ELTORITO, - IMAGE_XEN_PVH - } id; - enum - { - PLATFORM_FLAGS_NONE = 0, - PLATFORM_FLAGS_DECOMPRESSORS = 2, - PLATFORM_FLAGS_MODULES_BEFORE_KERNEL = 4, - } flags; - unsigned total_module_size; - unsigned decompressor_compressed_size; - unsigned decompressor_uncompressed_size; - unsigned decompressor_uncompressed_addr; - unsigned reloc_table_offset; - unsigned link_align; - grub_uint16_t elf_target; - unsigned section_align; - signed vaddr_offset; - grub_uint64_t link_addr; - unsigned mod_gap, mod_align; - grub_compression_t default_compression; - grub_uint16_t pe_target; -}; - -#define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) -#define grub_host_to_target32(x) (grub_host_to_target32_real (image_target, (x))) -#define grub_target_to_host64(x) (grub_target_to_host64_real (image_target, (x))) -#define grub_host_to_target64(x) (grub_host_to_target64_real (image_target, (x))) -#define grub_host_to_target_addr(x) (grub_host_to_target_addr_real (image_target, (x))) -#define grub_target_to_host16(x) (grub_target_to_host16_real (image_target, (x))) -#define grub_host_to_target16(x) (grub_host_to_target16_real (image_target, (x))) - -static inline grub_uint32_t -grub_target_to_host32_real (const struct grub_install_image_target_desc *image_target, - grub_uint32_t in) -{ - if (image_target->bigendian) - return grub_be_to_cpu32 (in); - else - return grub_le_to_cpu32 (in); -} - -static inline grub_uint64_t -grub_target_to_host64_real (const struct grub_install_image_target_desc *image_target, - grub_uint64_t in) -{ - if (image_target->bigendian) - return grub_be_to_cpu64 (in); - else - return grub_le_to_cpu64 (in); -} - -static inline grub_uint64_t -grub_host_to_target64_real (const struct grub_install_image_target_desc *image_target, - grub_uint64_t in) -{ - if (image_target->bigendian) - return grub_cpu_to_be64 (in); - else - return grub_cpu_to_le64 (in); -} - -static inline grub_uint32_t -grub_host_to_target32_real (const struct grub_install_image_target_desc *image_target, - grub_uint32_t in) -{ - if (image_target->bigendian) - return grub_cpu_to_be32 (in); - else - return grub_cpu_to_le32 (in); -} - -static inline grub_uint16_t -grub_target_to_host16_real (const struct grub_install_image_target_desc *image_target, - grub_uint16_t in) -{ - if (image_target->bigendian) - return grub_be_to_cpu16 (in); - else - return grub_le_to_cpu16 (in); -} - -static inline grub_uint16_t -grub_host_to_target16_real (const struct grub_install_image_target_desc *image_target, - grub_uint16_t in) -{ - if (image_target->bigendian) - return grub_cpu_to_be16 (in); - else - return grub_cpu_to_le16 (in); -} - -static inline grub_uint64_t -grub_host_to_target_addr_real (const struct grub_install_image_target_desc *image_target, grub_uint64_t in) -{ - if (image_target->voidp_sizeof == 8) - return grub_host_to_target64_real (image_target, in); - else - return grub_host_to_target32_real (image_target, in); -} - -static inline grub_uint64_t -grub_target_to_host_real (const struct grub_install_image_target_desc *image_target, grub_uint64_t in) -{ - if (image_target->voidp_sizeof == 8) - return grub_target_to_host64_real (image_target, in); - else - return grub_target_to_host32_real (image_target, in); -} - -#define grub_target_to_host(val) grub_target_to_host_real(image_target, (val)) - -#endif diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h index b43c523cb..78f24d784 100644 --- a/include/grub/util/ofpath.h +++ b/include/grub/util/ofpath.h @@ -1,6 +1,6 @@ #ifndef GRUB_OFPATH_MACHINE_UTIL_HEADER #define GRUB_OFPATH_MACHINE_UTIL_HEADER 1 -char *grub_util_devname_to_ofpath (const char *devname); +char *grub_util_devname_to_ofpath (char *devname); #endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */ diff --git a/grub-core/lib/posix_wrap/localcharset.h b/include/grub/util/raid.h similarity index 72% rename from grub-core/lib/posix_wrap/localcharset.h rename to include/grub/util/raid.h index 502d86066..67020bb86 100644 --- a/grub-core/lib/posix_wrap/localcharset.h +++ b/include/grub/util/raid.h @@ -1,6 +1,7 @@ +/* raid.h - RAID support for GRUB utils. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009, 2010 Free Software Foundation, Inc. + * 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 @@ -16,13 +17,11 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_POSIX_LOCALCHARSET_H -#define GRUB_POSIX_LOCALCHARSET_H 1 - -static inline const char * -locale_charset (void) -{ - return "UTF-8"; -} +#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 index 8923a6e6c..f42df32f9 100644 --- a/include/grub/util/resolve.h +++ b/include/grub/util/resolve.h @@ -31,6 +31,5 @@ struct grub_util_path_list * grub_util_resolve_dependencies (const char *prefix, const char *dep_list_file, char *modules[]); -void grub_util_free_path_list (struct grub_util_path_list *path_list); #endif /* ! GRUB_UTIL_RESOLVE_HEADER */ diff --git a/include/grub/verify.h b/include/grub/verify.h deleted file mode 100644 index 672ae1692..000000000 --- a/include/grub/verify.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2017 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_VERIFY_HEADER -#define GRUB_VERIFY_HEADER 1 - -#include -#include - -enum grub_verify_flags - { - GRUB_VERIFY_FLAGS_NONE = 0, - GRUB_VERIFY_FLAGS_SKIP_VERIFICATION = 1, - GRUB_VERIFY_FLAGS_SINGLE_CHUNK = 2, - /* Defer verification to another authority. */ - GRUB_VERIFY_FLAGS_DEFER_AUTH = 4 - }; - -enum grub_verify_string_type - { - GRUB_VERIFY_KERNEL_CMDLINE, - GRUB_VERIFY_MODULE_CMDLINE, - GRUB_VERIFY_COMMAND, - }; - -struct grub_file_verifier -{ - struct grub_file_verifier *next; - struct grub_file_verifier **prev; - - const char *name; - - /* - * Check if file needs to be verified and set up context. - * init/read/fini is structured in the same way as hash interface. - */ - grub_err_t (*init) (grub_file_t io, enum grub_file_type type, - void **context, enum grub_verify_flags *flags); - - /* - * Right now we pass the whole file in one call but it may - * change in the future. If you insist on single buffer you - * need to set GRUB_VERIFY_FLAGS_SINGLE_CHUNK in verify_flags. - */ - grub_err_t (*write) (void *context, void *buf, grub_size_t size); - - grub_err_t (*fini) (void *context); - void (*close) (void *context); - - grub_err_t (*verify_string) (char *str, enum grub_verify_string_type type); -}; - -extern struct grub_file_verifier *EXPORT_VAR (grub_file_verifiers); - -extern void -grub_verifiers_init (void); - -static inline void -grub_verifier_register (struct grub_file_verifier *ver) -{ - grub_list_push (GRUB_AS_LIST_P (&grub_file_verifiers), GRUB_AS_LIST (ver)); -} - -static inline void -grub_verifier_unregister (struct grub_file_verifier *ver) -{ - grub_list_remove (GRUB_AS_LIST (ver)); -} - -extern grub_err_t -EXPORT_FUNC (grub_verify_string) (char *str, enum grub_verify_string_type type); - -#endif /* ! GRUB_VERIFY_HEADER */ diff --git a/include/grub/vga.h b/include/grub/vga.h deleted file mode 100644 index 1d8449c64..000000000 --- a/include/grub/vga.h +++ /dev/null @@ -1,129 +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 . - */ - -#ifndef GRUB_VGA_HEADER -#define GRUB_VGA_HEADER 1 - -#ifndef GRUB_MACHINE_MIPS_QEMU_MIPS -#include -#else -#include -#define GRUB_MACHINE_PCI_IO_BASE 0xb4000000 -#endif - -#include - -static inline void -grub_vga_gr_write (grub_uint8_t val, grub_uint8_t addr) -{ - grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_GR_INDEX); - grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_GR_DATA); -} - -static inline grub_uint8_t -grub_vga_gr_read (grub_uint8_t addr) -{ - grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_GR_INDEX); - return grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_GR_DATA); -} - -static inline void -grub_vga_cr_write (grub_uint8_t val, grub_uint8_t addr) -{ - grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_INDEX); - grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_DATA); -} - -static inline grub_uint8_t -grub_vga_cr_read (grub_uint8_t addr) -{ - grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_INDEX); - return grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_DATA); -} - -static inline void -grub_vga_cr_bw_write (grub_uint8_t val, grub_uint8_t addr) -{ - grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_BW_INDEX); - grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_BW_DATA); -} - -static inline grub_uint8_t -grub_vga_cr_bw_read (grub_uint8_t addr) -{ - grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_BW_INDEX); - return grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_BW_DATA); -} - -static inline void -grub_vga_sr_write (grub_uint8_t val, grub_uint8_t addr) -{ - grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_INDEX); - grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_DATA); -} - -static inline grub_uint8_t -grub_vga_sr_read (grub_uint8_t addr) -{ - grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_INDEX); - return grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_DATA); -} - -static inline void -grub_vga_palette_read (grub_uint8_t addr, grub_uint8_t *r, grub_uint8_t *g, - grub_uint8_t *b) -{ - grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_READ_INDEX); - *r = grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA); - *g = grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA); - *b = grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA); -} - -static inline void -grub_vga_palette_write (grub_uint8_t addr, grub_uint8_t r, grub_uint8_t g, - grub_uint8_t b) -{ - grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_WRITE_INDEX); - grub_outb (r, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA); - grub_outb (g, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA); - grub_outb (b, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_PALLETTE_DATA); -} - -static inline void -grub_vga_write_arx (grub_uint8_t val, grub_uint8_t addr) -{ - grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_INPUT_STATUS1_REGISTER); - grub_inb (GRUB_MACHINE_PCI_IO_BASE + 0x3ba); - - grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX); - grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX_READ); - grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX); -} - -static inline grub_uint8_t -grub_vga_read_arx (grub_uint8_t addr) -{ - grub_uint8_t val; - grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_INPUT_STATUS1_REGISTER); - grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX); - val = grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX_READ); - grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX); - return val; -} - -#endif diff --git a/include/grub/vgaregs.h b/include/grub/vgaregs.h deleted file mode 100644 index 0c9e985cf..000000000 --- a/include/grub/vgaregs.h +++ /dev/null @@ -1,307 +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 . - */ - -#ifndef GRUB_VGAREGS_HEADER -#define GRUB_VGAREGS_HEADER 1 - -#ifdef ASM_FILE -#define GRUB_VGA_IO_SR_INDEX 0x3c4 -#define GRUB_VGA_IO_SR_DATA 0x3c5 -#else - -enum - { - GRUB_VGA_IO_CR_BW_INDEX = 0x3b4, - GRUB_VGA_IO_CR_BW_DATA = 0x3b5, - GRUB_VGA_IO_ARX = 0x3c0, - GRUB_VGA_IO_ARX_READ = 0x3c1, - GRUB_VGA_IO_MISC_WRITE = 0x3c2, - GRUB_VGA_IO_SR_INDEX = 0x3c4, - GRUB_VGA_IO_SR_DATA = 0x3c5, - GRUB_VGA_IO_PIXEL_MASK = 0x3c6, - GRUB_VGA_IO_PALLETTE_READ_INDEX = 0x3c7, - GRUB_VGA_IO_PALLETTE_WRITE_INDEX = 0x3c8, - GRUB_VGA_IO_PALLETTE_DATA = 0x3c9, - GRUB_VGA_IO_GR_INDEX = 0x3ce, - GRUB_VGA_IO_GR_DATA = 0x3cf, - GRUB_VGA_IO_CR_INDEX = 0x3d4, - GRUB_VGA_IO_CR_DATA = 0x3d5, - GRUB_VGA_IO_INPUT_STATUS1_REGISTER = 0x3da - }; - -#define GRUB_VGA_IO_INPUT_STATUS1_VERTR_BIT 0x08 - -enum - { - GRUB_VGA_CR_HTOTAL = 0x00, - GRUB_VGA_CR_HORIZ_END = 0x01, - GRUB_VGA_CR_HBLANK_START = 0x02, - GRUB_VGA_CR_HBLANK_END = 0x03, - GRUB_VGA_CR_HORIZ_SYNC_PULSE_START = 0x04, - GRUB_VGA_CR_HORIZ_SYNC_PULSE_END = 0x05, - GRUB_VGA_CR_VERT_TOTAL = 0x06, - GRUB_VGA_CR_OVERFLOW = 0x07, - GRUB_VGA_CR_BYTE_PANNING = 0x08, - GRUB_VGA_CR_CELL_HEIGHT = 0x09, - GRUB_VGA_CR_CURSOR_START = 0x0a, - GRUB_VGA_CR_CURSOR_END = 0x0b, - GRUB_VGA_CR_START_ADDR_HIGH_REGISTER = 0x0c, - GRUB_VGA_CR_START_ADDR_LOW_REGISTER = 0x0d, - GRUB_VGA_CR_CURSOR_ADDR_HIGH = 0x0e, - GRUB_VGA_CR_CURSOR_ADDR_LOW = 0x0f, - GRUB_VGA_CR_VSYNC_START = 0x10, - GRUB_VGA_CR_VSYNC_END = 0x11, - GRUB_VGA_CR_VDISPLAY_END = 0x12, - GRUB_VGA_CR_PITCH = 0x13, - GRUB_VGA_CR_UNDERLINE_LOCATION = 0x14, - GRUB_VGA_CR_VERTICAL_BLANK_START = 0x15, - GRUB_VGA_CR_VERTICAL_BLANK_END = 0x16, - GRUB_VGA_CR_MODE = 0x17, - GRUB_VGA_CR_LINE_COMPARE = 0x18, - }; - -enum - { - GRUB_VGA_CR_BYTE_PANNING_NORMAL = 0 - }; - -enum - { - GRUB_VGA_CR_UNDERLINE_LOCATION_DWORD_MODE = 0x40 - }; - -enum - { - GRUB_VGA_IO_MISC_COLOR = 0x01, - GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS = 0x02, - GRUB_VGA_IO_MISC_28MHZ = 0x04, - GRUB_VGA_IO_MISC_EXTERNAL_CLOCK_0 = 0x08, - GRUB_VGA_IO_MISC_UPPER_64K = 0x20, - GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY = 0x40, - GRUB_VGA_IO_MISC_NEGATIVE_VERT_POLARITY = 0x80, - }; - -enum - { - GRUB_VGA_ARX_MODE = 0x10, - GRUB_VGA_ARX_OVERSCAN = 0x11, - GRUB_VGA_ARX_COLOR_PLANE_ENABLE = 0x12, - GRUB_VGA_ARX_HORIZONTAL_PANNING = 0x13, - GRUB_VGA_ARX_COLOR_SELECT = 0x14 - }; - -enum - { - GRUB_VGA_ARX_MODE_TEXT = 0x00, - GRUB_VGA_ARX_MODE_GRAPHICS = 0x01, - GRUB_VGA_ARX_MODE_ENABLE_256COLOR = 0x40 - }; - -#define GRUB_VGA_CR_WIDTH_DIVISOR 8 - -#define GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_SHIFT 7 -#define GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_MASK 0x02 -#define GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_SHIFT 3 -#define GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_MASK 0x40 - -#define GRUB_VGA_CR_OVERFLOW_VERT_TOTAL1_SHIFT 8 -#define GRUB_VGA_CR_OVERFLOW_VERT_TOTAL1_MASK 0x01 -#define GRUB_VGA_CR_OVERFLOW_VERT_TOTAL2_SHIFT 4 -#define GRUB_VGA_CR_OVERFLOW_VERT_TOTAL2_MASK 0x20 - -#define GRUB_VGA_CR_OVERFLOW_VSYNC_START1_SHIFT 6 -#define GRUB_VGA_CR_OVERFLOW_VSYNC_START1_MASK 0x04 -#define GRUB_VGA_CR_OVERFLOW_VSYNC_START2_SHIFT 2 -#define GRUB_VGA_CR_OVERFLOW_VSYNC_START2_MASK 0x80 - -#define GRUB_VGA_CR_OVERFLOW_HEIGHT1_SHIFT 7 -#define GRUB_VGA_CR_OVERFLOW_HEIGHT1_MASK 0x02 -#define GRUB_VGA_CR_OVERFLOW_HEIGHT2_SHIFT 3 -#define GRUB_VGA_CR_OVERFLOW_HEIGHT2_MASK 0xc0 -#define GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_SHIFT 4 -#define GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_MASK 0x10 - -#define GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK 0x40 -#define GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT 3 -#define GRUB_VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_MASK 0x20 -#define GRUB_VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_SHIFT 4 -#define GRUB_VGA_CR_CELL_HEIGHT_DOUBLE_SCAN 0x80 -enum - { - GRUB_VGA_CR_CURSOR_START_DISABLE = (1 << 5) - }; - -#define GRUB_VGA_CR_PITCH_DIVISOR 8 - -enum - { - GRUB_VGA_CR_MODE_NO_CGA = 0x01, - GRUB_VGA_CR_MODE_NO_HERCULES = 0x02, - GRUB_VGA_CR_MODE_ADDRESS_WRAP = 0x20, - GRUB_VGA_CR_MODE_BYTE_MODE = 0x40, - GRUB_VGA_CR_MODE_TIMING_ENABLE = 0x80 - }; - -enum - { - GRUB_VGA_SR_RESET = 0, - GRUB_VGA_SR_CLOCKING_MODE = 1, - GRUB_VGA_SR_MAP_MASK_REGISTER = 2, - GRUB_VGA_SR_CHAR_MAP_SELECT = 3, - GRUB_VGA_SR_MEMORY_MODE = 4, - }; - -enum - { - GRUB_VGA_SR_RESET_ASYNC = 1, - GRUB_VGA_SR_RESET_SYNC = 2 - }; - -enum - { - GRUB_VGA_SR_CLOCKING_MODE_8_DOT_CLOCK = 1 - }; - -enum - { - GRUB_VGA_SR_MEMORY_MODE_NORMAL = 0, - GRUB_VGA_SR_MEMORY_MODE_EXTERNAL_VIDEO_MEMORY = 2, - GRUB_VGA_SR_MEMORY_MODE_SEQUENTIAL_ADDRESSING = 4, - GRUB_VGA_SR_MEMORY_MODE_CHAIN4 = 8, - }; - -enum - { - GRUB_VGA_GR_SET_RESET_PLANE = 0, - GRUB_VGA_GR_SET_RESET_PLANE_ENABLE = 1, - GRUB_VGA_GR_COLOR_COMPARE = 2, - GRUB_VGA_GR_DATA_ROTATE = 3, - GRUB_VGA_GR_READ_MAP_REGISTER = 4, - GRUB_VGA_GR_MODE = 5, - GRUB_VGA_GR_GR6 = 6, - GRUB_VGA_GR_COLOR_COMPARE_DISABLE = 7, - GRUB_VGA_GR_BITMASK = 8, - GRUB_VGA_GR_MAX - }; - -#define GRUB_VGA_ALL_PLANES 0xf -#define GRUB_VGA_NO_PLANES 0x0 - -enum - { - GRUB_VGA_GR_DATA_ROTATE_NOP = 0 - }; - -enum - { - GRUB_VGA_TEXT_TEXT_PLANE = 0, - GRUB_VGA_TEXT_ATTR_PLANE = 1, - GRUB_VGA_TEXT_FONT_PLANE = 2 - }; - -enum - { - GRUB_VGA_GR_GR6_GRAPHICS_MODE = 1, - GRUB_VGA_GR_GR6_MMAP_A0 = (1 << 2), - GRUB_VGA_GR_GR6_MMAP_CGA = (3 << 2) - }; - -enum - { - GRUB_VGA_GR_MODE_READ_MODE1 = 0x08, - GRUB_VGA_GR_MODE_ODD_EVEN = 0x10, - GRUB_VGA_GR_MODE_ODD_EVEN_SHIFT = 0x20, - GRUB_VGA_GR_MODE_256_COLOR = 0x40 - }; - -struct grub_video_hw_config -{ - unsigned vertical_total; - unsigned vertical_blank_start; - unsigned vertical_blank_end; - unsigned vertical_sync_start; - unsigned vertical_sync_end; - unsigned line_compare; - unsigned vdisplay_end; - unsigned pitch; - unsigned horizontal_total; - unsigned horizontal_blank_start; - unsigned horizontal_blank_end; - unsigned horizontal_sync_pulse_start; - unsigned horizontal_sync_pulse_end; - unsigned horizontal_end; -}; - -static inline void -grub_vga_set_geometry (struct grub_video_hw_config *config, - void (*cr_write) (grub_uint8_t val, grub_uint8_t addr)) -{ - unsigned vertical_total = config->vertical_total - 2; - unsigned vertical_blank_start = config->vertical_blank_start - 1; - unsigned vdisplay_end = config->vdisplay_end - 1; - grub_uint8_t overflow, cell_height_reg; - - /* Disable CR0-7 write protection. */ - cr_write (0, GRUB_VGA_CR_VSYNC_END); - - overflow = ((vertical_total >> GRUB_VGA_CR_OVERFLOW_VERT_TOTAL1_SHIFT) - & GRUB_VGA_CR_OVERFLOW_VERT_TOTAL1_MASK) - | ((vertical_total >> GRUB_VGA_CR_OVERFLOW_VERT_TOTAL2_SHIFT) - & GRUB_VGA_CR_OVERFLOW_VERT_TOTAL2_MASK) - | ((config->vertical_sync_start >> GRUB_VGA_CR_OVERFLOW_VSYNC_START2_SHIFT) - & GRUB_VGA_CR_OVERFLOW_VSYNC_START2_MASK) - | ((config->vertical_sync_start >> GRUB_VGA_CR_OVERFLOW_VSYNC_START1_SHIFT) - & GRUB_VGA_CR_OVERFLOW_VSYNC_START1_MASK) - | ((vdisplay_end >> GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_SHIFT) - & GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END1_MASK) - | ((vdisplay_end >> GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_SHIFT) - & GRUB_VGA_CR_OVERFLOW_VERT_DISPLAY_ENABLE_END2_MASK) - | ((config->vertical_sync_start >> GRUB_VGA_CR_OVERFLOW_VSYNC_START1_SHIFT) - & GRUB_VGA_CR_OVERFLOW_VSYNC_START1_MASK) - | ((config->line_compare >> GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_SHIFT) - & GRUB_VGA_CR_OVERFLOW_LINE_COMPARE_MASK); - - cell_height_reg = ((vertical_blank_start - >> GRUB_VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_SHIFT) - & GRUB_VGA_CR_CELL_HEIGHT_VERTICAL_BLANK_MASK) - | ((config->line_compare >> GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_SHIFT) - & GRUB_VGA_CR_CELL_HEIGHT_LINE_COMPARE_MASK); - - cr_write (config->horizontal_total - 1, GRUB_VGA_CR_HTOTAL); - cr_write (config->horizontal_end - 1, GRUB_VGA_CR_HORIZ_END); - cr_write (config->horizontal_blank_start - 1, GRUB_VGA_CR_HBLANK_START); - cr_write (config->horizontal_blank_end, GRUB_VGA_CR_HBLANK_END); - cr_write (config->horizontal_sync_pulse_start, - GRUB_VGA_CR_HORIZ_SYNC_PULSE_START); - cr_write (config->horizontal_sync_pulse_end, - GRUB_VGA_CR_HORIZ_SYNC_PULSE_END); - cr_write (vertical_total & 0xff, GRUB_VGA_CR_VERT_TOTAL); - cr_write (overflow, GRUB_VGA_CR_OVERFLOW); - cr_write (cell_height_reg, GRUB_VGA_CR_CELL_HEIGHT); - cr_write (config->vertical_sync_start & 0xff, GRUB_VGA_CR_VSYNC_START); - cr_write (config->vertical_sync_end & 0x0f, GRUB_VGA_CR_VSYNC_END); - cr_write (vdisplay_end & 0xff, GRUB_VGA_CR_VDISPLAY_END); - cr_write (config->pitch & 0xff, GRUB_VGA_CR_PITCH); - cr_write (vertical_blank_start & 0xff, GRUB_VGA_CR_VERTICAL_BLANK_START); - cr_write (config->vertical_blank_end & 0xff, GRUB_VGA_CR_VERTICAL_BLANK_END); - cr_write (config->line_compare & 0xff, GRUB_VGA_CR_LINE_COMPARE); -} - -#endif - -#endif diff --git a/include/grub/video.h b/include/grub/video.h index 9dac0f379..57f2b37f2 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -21,21 +21,11 @@ #include #include -#include /* Video color in hardware dependent format. Users should not assume any specific coding format. */ typedef grub_uint32_t grub_video_color_t; -/* Video color in hardware independent format. */ -typedef struct grub_video_rgba_color -{ - grub_uint8_t red; - grub_uint8_t green; - grub_uint8_t blue; - grub_uint8_t alpha; -} grub_video_rgba_color_t; - /* This structure is driver specific and should not be accessed directly by outside code. */ struct grub_video_render_target; @@ -47,33 +37,20 @@ struct grub_video_bitmap; /* If following is set render target contains currenly displayed image after swapping buffers (otherwise it contains previously displayed image). */ -typedef enum grub_video_mode_type - { - GRUB_VIDEO_MODE_TYPE_RGB = 0x00000001, - GRUB_VIDEO_MODE_TYPE_INDEX_COLOR = 0x00000002, - GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP = 0x00000004, - GRUB_VIDEO_MODE_TYPE_YUV = 0x00000008, +#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. */ - GRUB_VIDEO_MODE_TYPE_COLOR_MASK = 0x0000000F, +/* Defines used to mask flags. */ +#define GRUB_VIDEO_MODE_TYPE_COLOR_MASK 0x0000000F - GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED = 0x00000010, - GRUB_VIDEO_MODE_TYPE_ALPHA = 0x00000020, - GRUB_VIDEO_MODE_TYPE_PURE_TEXT = 0x00000040, - GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP = 0x00000080, - GRUB_VIDEO_MODE_TYPE_OPERATIONAL_MASK = 0x000000F0, - - /* Defines used to specify requested bit depth. */ - GRUB_VIDEO_MODE_TYPE_DEPTH_MASK = 0x0000FF00, -#define GRUB_VIDEO_MODE_TYPE_DEPTH_POS 8 - - GRUB_VIDEO_MODE_TYPE_UNKNOWN = 0x00010000, - GRUB_VIDEO_MODE_TYPE_HERCULES = 0x00020000, - GRUB_VIDEO_MODE_TYPE_PLANAR = 0x00040000, - GRUB_VIDEO_MODE_TYPE_NONCHAIN4 = 0x00080000, - GRUB_VIDEO_MODE_TYPE_CGA = 0x00100000, - GRUB_VIDEO_MODE_TYPE_INFO_MASK = 0x00FF0000, - } grub_video_mode_type_t; +/* 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. */ @@ -101,11 +78,6 @@ enum grub_video_blit_format /* When needed, decode color or just use value as is. */ GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR, - /* Like index but only 16-colors and F0 is a special value for transparency. - Could be extended to 4 bits of alpha and 4 bits of color if necessary. - Used internally for text rendering. - */ - GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR_ALPHA, /* Two color bitmap; bits packed: rows are not padded to byte boundary. */ GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED @@ -130,7 +102,7 @@ struct grub_video_mode_info /* Mode type bitmask. Contains information like is it Index color or RGB mode. */ - grub_video_mode_type_t mode_type; + unsigned int mode_type; /* Bits per pixel. */ unsigned int bpp; @@ -144,9 +116,6 @@ struct grub_video_mode_info /* In index color mode, number of colors. In RGB mode this is 256. */ unsigned int number_of_colors; - unsigned int mode_number; -#define GRUB_VIDEO_MODE_NUMBER_INVALID 0xffffffff - /* Optimization hint how binary data is coded. */ enum grub_video_blit_format blit_format; @@ -198,15 +167,6 @@ struct grub_video_rect }; typedef struct grub_video_rect grub_video_rect_t; -struct grub_video_signed_rect -{ - signed x; - signed y; - unsigned width; - unsigned height; -}; -typedef struct grub_video_signed_rect grub_video_signed_rect_t; - struct grub_video_palette_data { grub_uint8_t r; /* Red color value (0-255). */ @@ -215,112 +175,20 @@ struct grub_video_palette_data grub_uint8_t a; /* Reserved bits value (0-255). */ }; -struct grub_video_edid_info -{ - grub_uint8_t header[8]; - grub_uint16_t manufacturer_id; - grub_uint16_t product_id; - grub_uint32_t serial_number; - grub_uint8_t week_of_manufacture; - grub_uint8_t year_of_manufacture; - grub_uint8_t version; - grub_uint8_t revision; - - grub_uint8_t video_input_definition; - grub_uint8_t max_horizontal_image_size; - grub_uint8_t max_vertical_image_size; - grub_uint8_t display_gamma; - grub_uint8_t feature_support; -#define GRUB_VIDEO_EDID_FEATURE_PREFERRED_TIMING_MODE (1 << 1) - - grub_uint8_t red_green_lo; - grub_uint8_t blue_white_lo; - grub_uint8_t red_x_hi; - grub_uint8_t red_y_hi; - grub_uint8_t green_x_hi; - grub_uint8_t green_y_hi; - grub_uint8_t blue_x_hi; - grub_uint8_t blue_y_hi; - grub_uint8_t white_x_hi; - grub_uint8_t white_y_hi; - - grub_uint8_t established_timings_1; - grub_uint8_t established_timings_2; - grub_uint8_t manufacturer_reserved_timings; - - grub_uint16_t standard_timings[8]; - - struct { - grub_uint16_t pixel_clock; - /* Only valid if the pixel clock is non-null. */ - grub_uint8_t horizontal_active_lo; - grub_uint8_t horizontal_blanking_lo; - grub_uint8_t horizontal_hi; - grub_uint8_t vertical_active_lo; - grub_uint8_t vertical_blanking_lo; - grub_uint8_t vertical_hi; - grub_uint8_t horizontal_sync_offset_lo; - grub_uint8_t horizontal_sync_pulse_width_lo; - grub_uint8_t vertical_sync_lo; - grub_uint8_t sync_hi; - grub_uint8_t horizontal_image_size_lo; - grub_uint8_t vertical_image_size_lo; - grub_uint8_t image_size_hi; - grub_uint8_t horizontal_border; - grub_uint8_t vertical_border; - grub_uint8_t flags; - } detailed_timings[4]; - - grub_uint8_t extension_flag; - grub_uint8_t checksum; -} GRUB_PACKED; - 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_VGA, - GRUB_VIDEO_DRIVER_CIRRUS, - GRUB_VIDEO_DRIVER_BOCHS, - GRUB_VIDEO_DRIVER_SDL, - GRUB_VIDEO_DRIVER_SIS315PRO, - GRUB_VIDEO_DRIVER_RADEON_FULOONG2E, - GRUB_VIDEO_DRIVER_COREBOOT, - GRUB_VIDEO_DRIVER_IEEE1275, - GRUB_VIDEO_ADAPTER_CAPTURE, - GRUB_VIDEO_DRIVER_XEN, - GRUB_VIDEO_DRIVER_RADEON_YEELOONG3A + GRUB_VIDEO_DRIVER_EFI_GOP } grub_video_driver_id_t; -typedef enum grub_video_adapter_prio - { - GRUB_VIDEO_ADAPTER_PRIO_FALLBACK = 60, - GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE_DIRTY = 70, - GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE = 80, - GRUB_VIDEO_ADAPTER_PRIO_NATIVE = 100 - } grub_video_adapter_prio_t; - -typedef enum grub_video_area_status - { - GRUB_VIDEO_AREA_DISABLED, - GRUB_VIDEO_AREA_ENABLED - } grub_video_area_status_t; - struct grub_video_adapter { - /* The next video adapter. */ - struct grub_video_adapter *next; - struct grub_video_adapter **prev; - /* The video adapter name. */ const char *name; grub_video_driver_id_t id; - grub_video_adapter_prio_t prio; - /* Initialize the video adapter. */ grub_err_t (*init) (void); @@ -328,8 +196,7 @@ struct grub_video_adapter grub_err_t (*fini) (void); grub_err_t (*setup) (unsigned int width, unsigned int height, - grub_video_mode_type_t mode_type, - grub_video_mode_type_t mode_mask); + unsigned int mode_type, unsigned int mode_mask); grub_err_t (*get_info) (struct grub_video_mode_info *mode_info); @@ -348,16 +215,6 @@ struct grub_video_adapter grub_err_t (*get_viewport) (unsigned int *x, unsigned int *y, unsigned int *width, unsigned int *height); - grub_err_t (*set_region) (unsigned int x, unsigned int y, - unsigned int width, unsigned int height); - - grub_err_t (*get_region) (unsigned int *x, unsigned int *y, - unsigned int *width, unsigned int *height); - - grub_err_t (*set_area_status) (grub_video_area_status_t area_status); - - grub_err_t (*get_area_status) (grub_video_area_status_t *area_status); - 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, @@ -397,41 +254,14 @@ struct grub_video_adapter grub_err_t (*get_active_render_target) (struct grub_video_render_target **target); - int (*iterate) (int (*hook) (const struct grub_video_mode_info *info, void *hook_arg), void *hook_arg); - - grub_err_t (*get_edid) (struct grub_video_edid_info *edid_info); - - void (*print_adapter_specific_info) (void); + /* The next video adapter. */ + struct grub_video_adapter *next; }; typedef struct grub_video_adapter *grub_video_adapter_t; -extern grub_video_adapter_t EXPORT_VAR(grub_video_adapter_list); - -#ifndef GRUB_LST_GENERATOR -/* Register video driver. */ -static inline void -grub_video_register (grub_video_adapter_t adapter) -{ - grub_video_adapter_t *p; - for (p = &grub_video_adapter_list; *p && (*p)->prio > adapter->prio; - p = &((*p)->next)); - adapter->next = *p; - *p = adapter; - - adapter->prev = p; - if (adapter->next) - adapter->next->prev = &adapter->next; -} -#endif - -/* Unregister video driver. */ -static inline void -grub_video_unregister (grub_video_adapter_t adapter) -{ - grub_list_remove (GRUB_AS_LIST (adapter)); -} - -#define FOR_VIDEO_ADAPTERS(var) FOR_LIST_ELEMENTS((var), (grub_video_adapter_list)) +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); @@ -442,17 +272,16 @@ grub_err_t EXPORT_FUNC (grub_video_get_info) (struct grub_video_mode_info *mode_ 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, +grub_err_t grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info, void **framebuffer); -enum grub_video_blit_format EXPORT_FUNC(grub_video_get_blit_format) (struct grub_video_mode_info *mode_info); +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 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, @@ -464,22 +293,6 @@ grub_err_t EXPORT_FUNC (grub_video_get_viewport) (unsigned int *x, unsigned int *width, unsigned int *height); -grub_err_t EXPORT_FUNC (grub_video_set_region) (unsigned int x, - unsigned int y, - unsigned int width, - unsigned int height); - -grub_err_t EXPORT_FUNC (grub_video_get_region) (unsigned int *x, - unsigned int *y, - unsigned int *width, - unsigned int *height); - -grub_err_t EXPORT_FUNC (grub_video_set_area_status) - (grub_video_area_status_t area_status); - -grub_err_t EXPORT_FUNC (grub_video_get_area_status) - (grub_video_area_status_t *area_status); - 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, @@ -497,7 +310,7 @@ grub_err_t EXPORT_FUNC (grub_video_unmap_color) (grub_video_color_t color, grub_uint8_t *blue, grub_uint8_t *alpha); -grub_err_t EXPORT_FUNC (grub_video_fill_rect) (grub_video_color_t color, +grub_err_t EXPORT_FUNC (grub_video_fill_rect) (grub_video_color_t color, int x, int y, unsigned int width, unsigned int height); @@ -532,173 +345,18 @@ grub_err_t EXPORT_FUNC (grub_video_set_active_render_target) (struct grub_video_ grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target); -grub_err_t EXPORT_FUNC (grub_video_edid_checksum) (struct grub_video_edid_info *edid_info); -grub_err_t EXPORT_FUNC (grub_video_edid_preferred_mode) (struct grub_video_edid_info *edid_info, - unsigned int *width, - unsigned int *height); - 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 (grub_video_mode_type_t flags, - grub_video_mode_type_t mask, - grub_video_mode_type_t flag, int def) +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); - -static __inline grub_video_rgba_color_t -grub_video_rgba_color_rgb (grub_uint8_t r, grub_uint8_t g, grub_uint8_t b) -{ - grub_video_rgba_color_t c; - c.red = r; - c.green = g; - c.blue = b; - c.alpha = 255; - return c; -} - -static __inline grub_video_color_t -grub_video_map_rgba_color (grub_video_rgba_color_t c) -{ - return grub_video_map_rgba (c.red, c.green, c.blue, c.alpha); -} - -#ifndef GRUB_MACHINE_EMU -extern void grub_font_init (void); -extern void grub_font_fini (void); -extern void grub_gfxterm_init (void); -extern void grub_gfxterm_fini (void); -extern void grub_video_sm712_init (void); -extern void grub_video_sm712_fini (void); -extern void grub_video_sis315pro_init (void); -extern void grub_video_radeon_fuloong2e_init (void); -extern void grub_video_sis315pro_fini (void); -extern void grub_video_radeon_fuloong2e_fini (void); -extern void grub_video_radeon_yeeloong3a_init (void); -extern void grub_video_radeon_yeeloong3a_fini (void); -#endif - -void -grub_video_set_adapter (grub_video_adapter_t adapter); -grub_video_adapter_t -grub_video_get_adapter (void); -grub_err_t -grub_video_capture_start (const struct grub_video_mode_info *mode_info, - struct grub_video_palette_data *palette, - unsigned int palette_size); -void -grub_video_capture_end (void); - -void * -grub_video_capture_get_framebuffer (void); - -extern grub_video_adapter_t EXPORT_VAR (grub_video_adapter_active); -extern void (*grub_video_capture_refresh_cb) (void); - -#define GRUB_VIDEO_MI_RGB555(x) \ - x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ - x.bpp = 15, \ - x.bytes_per_pixel = 2, \ - x.number_of_colors = 256, \ - x.red_mask_size = 5, \ - x.red_field_pos = 10, \ - x.green_mask_size = 5, \ - x.green_field_pos = 5, \ - x.blue_mask_size = 5, \ - x.blue_field_pos = 0 - -#define GRUB_VIDEO_MI_RGB565(x) \ - x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ - x.bpp = 16, \ - x.bytes_per_pixel = 2, \ - x.number_of_colors = 256, \ - x.red_mask_size = 5, \ - x.red_field_pos = 11, \ - x.green_mask_size = 6, \ - x.green_field_pos = 5, \ - x.blue_mask_size = 5, \ - x.blue_field_pos = 0 - -#define GRUB_VIDEO_MI_RGB888(x) \ - x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ - x.bpp = 24, \ - x.bytes_per_pixel = 3, \ - x.number_of_colors = 256, \ - x.red_mask_size = 8, \ - x.red_field_pos = 16, \ - x.green_mask_size = 8, \ - x.green_field_pos = 8, \ - x.blue_mask_size = 8, \ - x.blue_field_pos = 0 - -#define GRUB_VIDEO_MI_RGBA8888(x) \ - x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ - x.bpp = 32, \ - x.bytes_per_pixel = 4, \ - x.number_of_colors = 256, \ - x.reserved_mask_size = 8, \ - x.reserved_field_pos = 24, \ - x.red_mask_size = 8, \ - x.red_field_pos = 16, \ - x.green_mask_size = 8, \ - x.green_field_pos = 8, \ - x.blue_mask_size = 8, \ - x.blue_field_pos = 0 - - -#define GRUB_VIDEO_MI_BGR555(x) \ - x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ - x.bpp = 15, \ - x.bytes_per_pixel = 2, \ - x.number_of_colors = 256, \ - x.red_mask_size = 5, \ - x.red_field_pos = 0, \ - x.green_mask_size = 5, \ - x.green_field_pos = 5, \ - x.blue_mask_size = 5, \ - x.blue_field_pos = 10 - -#define GRUB_VIDEO_MI_BGR565(x) \ - x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ - x.bpp = 16, \ - x.bytes_per_pixel = 2, \ - x.number_of_colors = 256, \ - x.red_mask_size = 5, \ - x.red_field_pos = 0, \ - x.green_mask_size = 6, \ - x.green_field_pos = 5, \ - x.blue_mask_size = 5, \ - x.blue_field_pos = 11 - -#define GRUB_VIDEO_MI_BGR888(x) \ - x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ - x.bpp = 24, \ - x.bytes_per_pixel = 3, \ - x.number_of_colors = 256, \ - x.red_mask_size = 8, \ - x.red_field_pos = 0, \ - x.green_mask_size = 8, \ - x.green_field_pos = 8, \ - x.blue_mask_size = 8, \ - x.blue_field_pos = 16 - -#define GRUB_VIDEO_MI_BGRA8888(x) \ - x.mode_type = GRUB_VIDEO_MODE_TYPE_RGB, \ - x.bpp = 32, \ - x.bytes_per_pixel = 4, \ - x.number_of_colors = 256, \ - x.reserved_mask_size = 8, \ - x.reserved_field_pos = 24, \ - x.red_mask_size = 8, \ - x.red_field_pos = 0, \ - x.green_mask_size = 8, \ - x.green_field_pos = 8, \ - x.blue_mask_size = 8, \ - x.blue_field_pos = 16 +grub_video_driver_id_t +grub_video_get_driver_id (void); #endif /* ! GRUB_VIDEO_HEADER */ diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h index 4a64fb8b7..3046a597b 100644 --- a/include/grub/video_fb.h +++ b/include/grub/video_fb.h @@ -31,64 +31,45 @@ struct grub_video_fbblit_info; struct grub_video_fbrender_target; #define GRUB_VIDEO_FBSTD_NUMCOLORS 16 -#define GRUB_VIDEO_FBSTD_EXT_NUMCOLORS 256 - -extern struct grub_video_palette_data EXPORT_VAR(grub_video_fbstd_colors)[GRUB_VIDEO_FBSTD_EXT_NUMCOLORS]; +extern struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLORS]; grub_err_t -EXPORT_FUNC(grub_video_fb_init) (void); +grub_video_fb_init (void); grub_err_t -EXPORT_FUNC(grub_video_fb_fini) (void); +grub_video_fb_fini (void); grub_err_t -EXPORT_FUNC(grub_video_fb_get_info) (struct grub_video_mode_info *mode_info); +grub_video_fb_get_info (struct grub_video_mode_info *mode_info); grub_err_t -EXPORT_FUNC(grub_video_fb_get_palette) (unsigned int start, unsigned int count, - struct grub_video_palette_data *palette_data); +grub_video_fb_get_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data); grub_err_t -EXPORT_FUNC(grub_video_fb_set_palette) (unsigned int start, unsigned int count, - struct grub_video_palette_data *palette_data); +grub_video_fb_set_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data); grub_err_t -EXPORT_FUNC(grub_video_fb_set_viewport) (unsigned int x, unsigned int y, - unsigned int width, unsigned int height); +grub_video_fb_set_viewport (unsigned int x, unsigned int y, + unsigned int width, unsigned int height); grub_err_t -EXPORT_FUNC(grub_video_fb_get_viewport) (unsigned int *x, unsigned int *y, - unsigned int *width, - unsigned int *height); - -grub_err_t -EXPORT_FUNC(grub_video_fb_set_region) (unsigned int x, unsigned int y, - unsigned int width, unsigned int height); -grub_err_t -EXPORT_FUNC(grub_video_fb_get_region) (unsigned int *x, unsigned int *y, - unsigned int *width, - unsigned int *height); - -grub_err_t -EXPORT_FUNC(grub_video_fb_set_area_status) - (grub_video_area_status_t area_status); - -grub_err_t -EXPORT_FUNC(grub_video_fb_get_area_status) - (grub_video_area_status_t *area_status); +grub_video_fb_get_viewport (unsigned int *x, unsigned int *y, + unsigned int *width, unsigned int *height); grub_video_color_t -EXPORT_FUNC(grub_video_fb_map_color) (grub_uint32_t color_name); +grub_video_fb_map_color (grub_uint32_t color_name); grub_video_color_t -EXPORT_FUNC(grub_video_fb_map_rgb) (grub_uint8_t red, grub_uint8_t green, - grub_uint8_t blue); +grub_video_fb_map_rgb (grub_uint8_t red, grub_uint8_t green, + grub_uint8_t blue); grub_video_color_t -EXPORT_FUNC(grub_video_fb_map_rgba) (grub_uint8_t red, grub_uint8_t green, - grub_uint8_t blue, grub_uint8_t alpha); +grub_video_fb_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_fb_unmap_color) (grub_video_color_t color, - grub_uint8_t *red, grub_uint8_t *green, - grub_uint8_t *blue, grub_uint8_t *alpha); +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, @@ -97,55 +78,52 @@ grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source, grub_uint8_t *blue, grub_uint8_t *alpha); grub_err_t -EXPORT_FUNC(grub_video_fb_fill_rect) (grub_video_color_t color, int x, int y, - unsigned int width, unsigned int height); +grub_video_fb_fill_rect (grub_video_color_t color, int x, int y, + unsigned int width, unsigned int height); grub_err_t -EXPORT_FUNC(grub_video_fb_blit_bitmap) (struct grub_video_bitmap *bitmap, +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 -EXPORT_FUNC(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, +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 -EXPORT_FUNC(grub_video_fb_scroll) (grub_video_color_t color, int dx, int dy); +grub_video_fb_scroll (grub_video_color_t color, int dx, int dy); grub_err_t -EXPORT_FUNC(grub_video_fb_create_render_target) (struct grub_video_fbrender_target **result, +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 -EXPORT_FUNC(grub_video_fb_create_render_target_from_pointer) (struct grub_video_fbrender_target **result, +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 -EXPORT_FUNC(grub_video_fb_delete_render_target) (struct grub_video_fbrender_target *target); +grub_video_fb_delete_render_target (struct grub_video_fbrender_target *target); grub_err_t -EXPORT_FUNC(grub_video_fb_get_active_render_target) (struct grub_video_fbrender_target **target); +grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **target); grub_err_t -EXPORT_FUNC(grub_video_fb_set_active_render_target) (struct grub_video_fbrender_target *target); +grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *target); -typedef grub_err_t (*grub_video_fb_set_page_t) (int page); +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 -EXPORT_FUNC (grub_video_fb_setup) (unsigned int mode_type, unsigned int mode_mask, - struct grub_video_mode_info *mode_info, - volatile void *page0_ptr, - grub_video_fb_set_page_t set_page_in, - volatile void *page1_ptr); -grub_err_t -EXPORT_FUNC (grub_video_fb_swap_buffers) (void); -grub_err_t -EXPORT_FUNC (grub_video_fb_get_info_and_fini) (struct grub_video_mode_info *mode_info, - void **framebuf); +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/cmos.h b/include/grub/x86_64/cmos.h deleted file mode 100644 index 03722f805..000000000 --- a/include/grub/x86_64/cmos.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/x86_64/efi/kernel.h b/include/grub/x86_64/efi/kernel.h index e69de29bb..c0549f41a 100644 --- a/include/grub/x86_64/efi/kernel.h +++ b/include/grub/x86_64/efi/kernel.h @@ -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 . + */ + +#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/memory.h b/include/grub/x86_64/efi/memory.h index 46e9145a3..c9a61bb77 100644 --- a/include/grub/x86_64/efi/memory.h +++ b/include/grub/x86_64/efi/memory.h @@ -1,10 +1 @@ -#ifndef GRUB_MEMORY_CPU_HEADER #include - -#if defined (__code_model_large__) -#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff -#else -#define GRUB_EFI_MAX_USABLE_ADDRESS 0x7fffffff -#endif - -#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/x86_64/efi/serial.h b/include/grub/x86_64/efi/serial.h deleted file mode 100644 index 2d8563414..000000000 --- a/include/grub/x86_64/efi/serial.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/loongarch64/time.h b/include/grub/x86_64/efi/time.h similarity index 77% rename from include/grub/loongarch64/time.h rename to include/grub/x86_64/efi/time.h index eefcd2788..7a9241fff 100644 --- a/include/grub/loongarch64/time.h +++ b/include/grub/x86_64/efi/time.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2023 Free Software Foundation, Inc. + * 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 @@ -16,13 +16,9 @@ * along with GRUB. If not, see . */ -#ifndef KERNEL_CPU_TIME_HEADER -#define KERNEL_CPU_TIME_HEADER 1 +#ifndef GRUB_MACHINE_TIME_HEADER +#define GRUB_MACHINE_TIME_HEADER 1 -static inline void -grub_cpu_idle(void) -{ - asm volatile ("idle 0"); -} +#include -#endif +#endif /* ! GRUB_MACHINE_TIME_HEADER */ diff --git a/include/grub/x86_64/kernel.h b/include/grub/x86_64/kernel.h new file mode 100644 index 000000000..25ac57e40 --- /dev/null +++ b/include/grub/x86_64/kernel.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/x86_64/memory.h b/include/grub/x86_64/memory.h deleted file mode 100644 index 27fcd2534..000000000 --- a/include/grub/x86_64/memory.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/x86_64/setjmp.h b/include/grub/x86_64/setjmp.h index 6df8a1289..4ad968ed5 100644 --- a/include/grub/x86_64/setjmp.h +++ b/include/grub/x86_64/setjmp.h @@ -21,7 +21,7 @@ typedef unsigned long grub_jmp_buf[8]; -int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE GRUB_ASM_ATTR; -void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)) GRUB_ASM_ATTR; +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 index 4da5ae93c..842882cf2 100644 --- a/include/grub/x86_64/time.h +++ b/include/grub/x86_64/time.h @@ -23,7 +23,7 @@ static __inline void grub_cpu_idle (void) { /* FIXME: this can't work until we handle interrupts. */ -/* asm volatile ("hlt"); */ +/* __asm__ __volatile__ ("hlt"); */ } #endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/x86_64/types.h b/include/grub/x86_64/types.h index 0bbdc6d01..bdee5a109 100644 --- a/include/grub/x86_64/types.h +++ b/include/grub/x86_64/types.h @@ -20,22 +20,12 @@ #define GRUB_TYPES_CPU_HEADER 1 /* The size of void *. */ -#ifdef __ILP32__ -#define GRUB_TARGET_SIZEOF_VOID_P 4 -#else #define GRUB_TARGET_SIZEOF_VOID_P 8 -#endif /* The size of long. */ -#if defined(__MINGW32__) || defined(__ILP32__) -#define GRUB_TARGET_SIZEOF_LONG 4 -#else #define GRUB_TARGET_SIZEOF_LONG 8 -#endif /* x86_64 is little-endian. */ #undef GRUB_TARGET_WORDS_BIGENDIAN -#define GRUB_HAVE_UNALIGNED_ACCESS 1 - #endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/x86_64/xen/hypercall.h b/include/grub/x86_64/xen/hypercall.h deleted file mode 100644 index 90dd9007b..000000000 --- a/include/grub/x86_64/xen/hypercall.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_XEN_CPU_HYPERCALL_HEADER -#define GRUB_XEN_CPU_HYPERCALL_HEADER 1 - -#include - -int EXPORT_FUNC (grub_xen_sched_op) (int cmd, void *arg) GRUB_ASM_ATTR; -int grub_xen_update_va_mapping (void *addr, uint64_t pte, uint64_t flags) GRUB_ASM_ATTR; -int EXPORT_FUNC (grub_xen_event_channel_op) (int op, void *arg) GRUB_ASM_ATTR; - -int grub_xen_mmuext_op (mmuext_op_t * ops, - unsigned int count, - unsigned int *pdone, unsigned int foreigndom) GRUB_ASM_ATTR; -int EXPORT_FUNC (grub_xen_mmu_update) (const struct mmu_update * reqs, - unsigned count, unsigned *done_out, - unsigned foreigndom) GRUB_ASM_ATTR; -int EXPORT_FUNC (grub_xen_grant_table_op) (int, void *, int) GRUB_ASM_ATTR; - -#endif diff --git a/include/grub/xen.h b/include/grub/xen.h deleted file mode 100644 index 91cb7cf81..000000000 --- a/include/grub/xen.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_XEN_HEADER -#define GRUB_XEN_HEADER 1 - -#define __XEN_INTERFACE_VERSION__ 0x0003020a - -#define memset grub_memset - -#ifdef ASM_FILE -#define __ASSEMBLY__ -#include -#else - -#include -#include -#include - -#ifndef GRUB_SYMBOL_GENERATOR -typedef grub_int8_t int8_t; -typedef grub_int16_t int16_t; -typedef grub_uint8_t uint8_t; -typedef grub_uint16_t uint16_t; -typedef grub_uint32_t uint32_t; -typedef grub_uint64_t uint64_t; -#include - -#include -#include -#include -#include -#include -#include -#endif - -#include - -extern grub_size_t EXPORT_VAR (grub_xen_n_allocated_shared_pages); - - -#define GRUB_XEN_LOG_PAGE_SIZE 12 -#define GRUB_XEN_PAGE_SIZE (1 << GRUB_XEN_LOG_PAGE_SIZE) - -extern volatile struct xencons_interface *grub_xen_xcons; -extern volatile struct shared_info *EXPORT_VAR (grub_xen_shared_info); -extern volatile struct xenstore_domain_interface *grub_xen_xenstore; -extern volatile grant_entry_v1_t *grub_xen_grant_table; - -void EXPORT_FUNC (grub_xen_store_send) (const void *buf_, grub_size_t len); -void EXPORT_FUNC (grub_xen_store_recv) (void *buf_, grub_size_t len); -grub_err_t -EXPORT_FUNC (grub_xenstore_dir) (const char *dir, - int (*hook) (const char *dir, - void *hook_data), - void *hook_data); -void *EXPORT_FUNC (grub_xenstore_get_file) (const char *dir, - grub_size_t * len); -grub_err_t EXPORT_FUNC (grub_xenstore_write_file) (const char *dir, - const void *buf, - grub_size_t len); - -typedef unsigned int grub_xen_grant_t; - -void *EXPORT_FUNC (grub_xen_alloc_shared_page) (domid_t dom, - grub_xen_grant_t * grnum); -void EXPORT_FUNC (grub_xen_free_shared_page) (void *ptr); - -#define mb() asm volatile("mfence;sfence;" : : : "memory"); -extern struct start_info *EXPORT_VAR (grub_xen_start_page_addr); - -void grub_console_init (void); - -void grub_xendisk_fini (void); -void grub_xendisk_init (void); - -#ifdef __x86_64__ -typedef grub_uint64_t grub_xen_mfn_t; -#else -typedef grub_uint32_t grub_xen_mfn_t; -#endif -typedef unsigned int grub_xen_evtchn_t; - -#ifdef GRUB_MACHINE_XEN_PVH -extern struct hvm_start_info *pvh_start_info; -void grub_xen_setup_pvh (void); -#endif -#endif - -#endif diff --git a/include/grub/xen/relocator.h b/include/grub/xen/relocator.h deleted file mode 100644 index 35a0ad9c7..000000000 --- a/include/grub/xen/relocator.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_RELOCATOR_XEN_HEADER -#define GRUB_RELOCATOR_XEN_HEADER 1 - -#include -#include -#include - -#define XEN_MAX_MAPPINGS 3 - -struct grub_relocator_xen_state -{ - grub_addr_t start_info; - grub_addr_t paging_start[XEN_MAX_MAPPINGS]; - grub_addr_t paging_size[XEN_MAX_MAPPINGS]; - grub_addr_t mfn_list; - grub_addr_t stack; - grub_addr_t entry_point; -}; - -grub_err_t -grub_relocator_xen_boot (struct grub_relocator *rel, - struct grub_relocator_xen_state state, - grub_uint64_t remapper_pfn, - grub_addr_t remapper_virt, - grub_uint64_t trampoline_pfn, - grub_addr_t trampoline_virt); - -#endif diff --git a/include/grub/xen_file.h b/include/grub/xen_file.h deleted file mode 100644 index 658799952..000000000 --- a/include/grub/xen_file.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_XEN_FILE_HEADER -#define GRUB_XEN_FILE_HEADER 1 - -#include -#include -#include - -grub_elf_t grub_xen_file (grub_file_t file); - -struct grub_xen_file_info -{ - grub_uint64_t kern_start, kern_end; - grub_uint64_t virt_base; - grub_uint64_t entry_point; - grub_uint64_t hypercall_page; - grub_uint64_t paddr_offset; - grub_uint64_t p2m_base; - int has_hypercall_page; - int has_note; - int has_xen_guest; - int has_p2m_base; - int extended_cr3; - int unmapped_initrd; - enum - { - GRUB_XEN_FILE_I386 = 1, - GRUB_XEN_FILE_I386_PAE = 2, - GRUB_XEN_FILE_I386_PAE_BIMODE = 3, - GRUB_XEN_FILE_X86_64 = 4 - } arch; -}; - -grub_err_t -grub_xen_get_info32 (grub_elf_t elf, struct grub_xen_file_info *xi); -grub_err_t -grub_xen_get_info64 (grub_elf_t elf, struct grub_xen_file_info *xi); -grub_err_t grub_xen_get_info (grub_elf_t elf, struct grub_xen_file_info *xi); - -#endif diff --git a/include/grub/xnu.h b/include/grub/xnu.h index b7a7f450c..6089aad34 100644 --- a/include/grub/xnu.h +++ b/include/grub/xnu.h @@ -46,7 +46,7 @@ struct grub_xnu_hibernate_header Used only to skip it. */ grub_uint32_t extmapsize; -} GRUB_PACKED; +} __attribute__ ((packed)); /* In-memory structure for temporary keeping device tree. */ struct grub_xnu_devtree_key @@ -67,7 +67,7 @@ grub_xnu_extdesc { grub_uint32_t addr; grub_uint32_t size; -} GRUB_PACKED; +} __attribute__ ((packed)); /* Header describing extension in the memory. */ struct grub_xnu_extheader @@ -78,42 +78,38 @@ struct grub_xnu_extheader grub_uint32_t binarysize; grub_uint32_t nameaddr; grub_uint32_t namesize; -} GRUB_PACKED; +} __attribute__ ((packed)); struct grub_xnu_devtree_key *grub_xnu_create_key (struct grub_xnu_devtree_key **parent, - const char *name); + 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 (grub_addr_t *target, grub_size_t *size); +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, - const char *name); + 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, - const char *name); + char *name); grub_err_t grub_xnu_align_heap (int align); -grub_err_t grub_xnu_scan_dir_for_kexts (char *dirname, - const char *osbundlerequired, +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, - const char *osbundlerequired, +grub_err_t grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired, int maxrecursion); -grub_err_t grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target); +void *grub_xnu_heap_malloc (int size); grub_err_t grub_xnu_fill_devicetree (void); -extern struct grub_relocator *grub_xnu_relocator; - +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; -extern grub_addr_t grub_xnu_heap_target_start; -extern int grub_xnu_darwin_version; #endif diff --git a/include/grub/zfs/dmu.h b/include/grub/zfs/dmu.h deleted file mode 100644 index 4ad616c74..000000000 --- a/include/grub/zfs/dmu.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_DMU_H -#define _SYS_DMU_H -#define B_FALSE 0 -#define B_TRUE 1 - -#define DMU_OT_NEWTYPE 0x80 -#define DMU_OT_METADATA 0x40 -#define DMU_OT_BYTESWAP_MASK 0x3f - -#define DMU_OT(byteswap, metadata) \ - (DMU_OT_NEWTYPE | \ - ((metadata) ? DMU_OT_METADATA : 0) | \ - ((byteswap) & DMU_OT_BYTESWAP_MASK)) - -#define DMU_OT_IS_VALID(ot) (((ot) & DMU_OT_NEWTYPE) ? \ - ((ot) & DMU_OT_BYTESWAP_MASK) < DMU_BSWAP_NUMFUNCS : \ - (ot) < DMU_OT_NUMTYPES) - -#define DMU_OT_IS_METADATA(ot) (((ot) & DMU_OT_NEWTYPE) ? \ - ((ot) & DMU_OT_METADATA) : \ - dmu_ot[(ot)].ot_metadata) - -typedef enum dmu_object_byteswap { - DMU_BSWAP_UINT8, - DMU_BSWAP_UINT16, - DMU_BSWAP_UINT32, - DMU_BSWAP_UINT64, - DMU_BSWAP_ZAP, - DMU_BSWAP_DNODE, - DMU_BSWAP_OBJSET, - DMU_BSWAP_ZNODE, - DMU_BSWAP_OLDACL, - DMU_BSWAP_ACL, - DMU_BSWAP_NUMFUNCS -} dmu_object_byteswap_t; - -/* - * This file describes the interface that the DMU provides for its - * consumers. - * - * The DMU also interacts with the SPA. That interface is described in - * dmu_spa.h. - */ -typedef enum dmu_object_type { - DMU_OT_NONE, - /* general: */ - DMU_OT_OBJECT_DIRECTORY, /* ZAP */ - DMU_OT_OBJECT_ARRAY, /* UINT64 */ - DMU_OT_PACKED_NVLIST, /* UINT8 (XDR by nvlist_pack/unpack) */ - DMU_OT_PACKED_NVLIST_SIZE, /* UINT64 */ - DMU_OT_BPLIST, /* UINT64 */ - DMU_OT_BPLIST_HDR, /* UINT64 */ - /* spa: */ - DMU_OT_SPACE_MAP_HEADER, /* UINT64 */ - DMU_OT_SPACE_MAP, /* UINT64 */ - /* zil: */ - DMU_OT_INTENT_LOG, /* UINT64 */ - /* dmu: */ - DMU_OT_DNODE, /* DNODE */ - DMU_OT_OBJSET, /* OBJSET */ - /* dsl: */ - DMU_OT_DSL_DIR, /* UINT64 */ - DMU_OT_DSL_DIR_CHILD_MAP, /* ZAP */ - DMU_OT_DSL_DS_SNAP_MAP, /* ZAP */ - DMU_OT_DSL_PROPS, /* ZAP */ - DMU_OT_DSL_DATASET, /* UINT64 */ - /* zpl: */ - DMU_OT_ZNODE, /* ZNODE */ - DMU_OT_OLDACL, /* OLD ACL */ - DMU_OT_PLAIN_FILE_CONTENTS, /* UINT8 */ - DMU_OT_DIRECTORY_CONTENTS, /* ZAP */ - DMU_OT_MASTER_NODE, /* ZAP */ - DMU_OT_UNLINKED_SET, /* ZAP */ - /* zvol: */ - DMU_OT_ZVOL, /* UINT8 */ - DMU_OT_ZVOL_PROP, /* ZAP */ - /* other; for testing only! */ - DMU_OT_PLAIN_OTHER, /* UINT8 */ - DMU_OT_UINT64_OTHER, /* UINT64 */ - DMU_OT_ZAP_OTHER, /* ZAP */ - /* new object types: */ - DMU_OT_ERROR_LOG, /* ZAP */ - DMU_OT_SPA_HISTORY, /* UINT8 */ - DMU_OT_SPA_HISTORY_OFFSETS, /* spa_his_phys_t */ - DMU_OT_POOL_PROPS, /* ZAP */ - DMU_OT_DSL_PERMS, /* ZAP */ - DMU_OT_ACL, /* ACL */ - DMU_OT_SYSACL, /* SYSACL */ - DMU_OT_FUID, /* FUID table (Packed NVLIST UINT8) */ - DMU_OT_FUID_SIZE, /* FUID table size UINT64 */ - DMU_OT_NEXT_CLONES, /* ZAP */ - DMU_OT_SCRUB_QUEUE, /* ZAP */ - DMU_OT_USERGROUP_USED, /* ZAP */ - DMU_OT_USERGROUP_QUOTA, /* ZAP */ - DMU_OT_USERREFS, /* ZAP */ - DMU_OT_DDT_ZAP, /* ZAP */ - DMU_OT_DDT_STATS, /* ZAP */ - DMU_OT_SA, /* System attr */ - DMU_OT_SA_MASTER_NODE, /* ZAP */ - DMU_OT_SA_ATTR_REGISTRATION, /* ZAP */ - DMU_OT_SA_ATTR_LAYOUTS, /* ZAP */ - DMU_OT_DSL_KEYCHAIN = 54, - DMU_OT_NUMTYPES, - DMU_OTN_UINT8_DATA = DMU_OT(DMU_BSWAP_UINT8, B_FALSE), - DMU_OTN_UINT8_METADATA = DMU_OT(DMU_BSWAP_UINT8, B_TRUE), - DMU_OTN_UINT16_DATA = DMU_OT(DMU_BSWAP_UINT16, B_FALSE), - DMU_OTN_UINT16_METADATA = DMU_OT(DMU_BSWAP_UINT16, B_TRUE), - DMU_OTN_UINT32_DATA = DMU_OT(DMU_BSWAP_UINT32, B_FALSE), - DMU_OTN_UINT32_METADATA = DMU_OT(DMU_BSWAP_UINT32, B_TRUE), - DMU_OTN_UINT64_DATA = DMU_OT(DMU_BSWAP_UINT64, B_FALSE), - DMU_OTN_UINT64_METADATA = DMU_OT(DMU_BSWAP_UINT64, B_TRUE), - DMU_OTN_ZAP_DATA = DMU_OT(DMU_BSWAP_ZAP, B_FALSE), - DMU_OTN_ZAP_METADATA = DMU_OT(DMU_BSWAP_ZAP, B_TRUE), -} dmu_object_type_t; - -typedef enum dmu_objset_type { - DMU_OST_NONE, - DMU_OST_META, - DMU_OST_ZFS, - DMU_OST_ZVOL, - DMU_OST_OTHER, /* For testing only! */ - DMU_OST_ANY, /* Be careful! */ - DMU_OST_NUMTYPES -} dmu_objset_type_t; - -/* - * The names of zap entries in the DIRECTORY_OBJECT of the MOS. - */ -#define DMU_POOL_DIRECTORY_OBJECT 1 -#define DMU_POOL_CONFIG "config" -#define DMU_POOL_ROOT_DATASET "root_dataset" -#define DMU_POOL_SYNC_BPLIST "sync_bplist" -#define DMU_POOL_ERRLOG_SCRUB "errlog_scrub" -#define DMU_POOL_ERRLOG_LAST "errlog_last" -#define DMU_POOL_SPARES "spares" -#define DMU_POOL_DEFLATE "deflate" -#define DMU_POOL_HISTORY "history" -#define DMU_POOL_PROPS "pool_props" -#define DMU_POOL_L2CACHE "l2cache" -#define DMU_POOL_FEATURES_FOR_READ "features_for_read" - -#endif /* _SYS_DMU_H */ diff --git a/include/grub/zfs/dmu_objset.h b/include/grub/zfs/dmu_objset.h deleted file mode 100644 index 57d21db5c..000000000 --- a/include/grub/zfs/dmu_objset.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. - * Copyright (C) 2010 Robert Millan - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_DMU_OBJSET_H -#define _SYS_DMU_OBJSET_H - -#include - -#define OBJSET_PHYS_SIZE 2048 -#define OBJSET_PHYS_SIZE_V14 1024 - -typedef struct objset_phys { - dnode_phys_t os_meta_dnode; - zil_header_t os_zil_header; - grub_uint64_t os_type; - grub_uint64_t os_flags; - char os_pad[OBJSET_PHYS_SIZE - sizeof (dnode_phys_t)*3 - - sizeof (zil_header_t) - sizeof (grub_uint64_t)*2]; - dnode_phys_t os_userused_dnode; - dnode_phys_t os_groupused_dnode; -} objset_phys_t; - -#endif /* _SYS_DMU_OBJSET_H */ diff --git a/include/grub/zfs/dnode.h b/include/grub/zfs/dnode.h deleted file mode 100644 index e4993df1e..000000000 --- a/include/grub/zfs/dnode.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_DNODE_H -#define _SYS_DNODE_H - -#include - -/* - * Fixed constants. - */ -#define DNODE_SHIFT 9 /* 512 bytes */ -#define DNODE_BLOCK_SHIFT 14 /* 16k */ -#define DNODE_CORE_SIZE 64 /* 64 bytes for dnode sans blkptrs */ - -/* - * Derived constants. - */ -#define DNODE_SIZE (1 << DNODE_SHIFT) -#define DN_MAX_NBLKPTR ((DNODE_SIZE - DNODE_CORE_SIZE) >> SPA_BLKPTRSHIFT) -#define DN_MAX_BONUSLEN (DNODE_SIZE - DNODE_CORE_SIZE - (1 << SPA_BLKPTRSHIFT)) - -#define DNODES_PER_BLOCK_SHIFT (DNODE_BLOCK_SHIFT - DNODE_SHIFT) -#define DNODES_PER_BLOCK (1ULL << DNODES_PER_BLOCK_SHIFT) - -#define DNODE_FLAG_SPILL_BLKPTR (1<<2) - -#define DN_BONUS(dnp) ((void*)((dnp)->dn_bonus + \ - (((dnp)->dn_nblkptr - 1) * sizeof (blkptr_t)))) - -typedef struct dnode_phys { - grub_uint8_t dn_type; /* dmu_object_type_t */ - grub_uint8_t dn_indblkshift; /* ln2(indirect block size) */ - grub_uint8_t dn_nlevels; /* 1=dn_blkptr->data blocks */ - grub_uint8_t dn_nblkptr; /* length of dn_blkptr */ - grub_uint8_t dn_bonustype; /* type of data in bonus buffer */ - grub_uint8_t dn_checksum; /* ZIO_CHECKSUM type */ - grub_uint8_t dn_compress; /* ZIO_COMPRESS type */ - grub_uint8_t dn_flags; /* DNODE_FLAG_* */ - grub_uint16_t dn_datablkszsec; /* data block size in 512b sectors */ - grub_uint16_t dn_bonuslen; /* length of dn_bonus */ - grub_uint8_t dn_pad2[4]; - - /* accounting is protected by dn_dirty_mtx */ - grub_uint64_t dn_maxblkid; /* largest allocated block ID */ - grub_uint64_t dn_used; /* bytes (or sectors) of disk space */ - - grub_uint64_t dn_pad3[4]; - - blkptr_t dn_blkptr[1]; - grub_uint8_t dn_bonus[DN_MAX_BONUSLEN - sizeof (blkptr_t)]; - blkptr_t dn_spill; -} dnode_phys_t; - -#endif /* _SYS_DNODE_H */ diff --git a/include/grub/zfs/dsl_dataset.h b/include/grub/zfs/dsl_dataset.h deleted file mode 100644 index c17bf801e..000000000 --- a/include/grub/zfs/dsl_dataset.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_DSL_DATASET_H -#define _SYS_DSL_DATASET_H - -typedef struct dsl_dataset_phys { - grub_uint64_t ds_dir_obj; - grub_uint64_t ds_prev_snap_obj; - grub_uint64_t ds_prev_snap_txg; - grub_uint64_t ds_next_snap_obj; - grub_uint64_t ds_snapnames_zapobj; /* zap obj of snaps; ==0 for snaps */ - grub_uint64_t ds_num_children; /* clone/snap children; ==0 for head */ - grub_uint64_t ds_creation_time; /* seconds since 1970 */ - grub_uint64_t ds_creation_txg; - grub_uint64_t ds_deadlist_obj; - grub_uint64_t ds_used_bytes; - grub_uint64_t ds_compressed_bytes; - grub_uint64_t ds_uncompressed_bytes; - grub_uint64_t ds_unique_bytes; /* only relevant to snapshots */ - /* - * The ds_fsid_guid is a 56-bit ID that can change to avoid - * collisions. The ds_guid is a 64-bit ID that will never - * change, so there is a small probability that it will collide. - */ - grub_uint64_t ds_fsid_guid; - grub_uint64_t ds_guid; - grub_uint64_t ds_flags; - blkptr_t ds_bp; - grub_uint64_t ds_pad[8]; /* pad out to 320 bytes for good measure */ -} dsl_dataset_phys_t; - -#endif /* _SYS_DSL_DATASET_H */ diff --git a/include/grub/zfs/dsl_dir.h b/include/grub/zfs/dsl_dir.h deleted file mode 100644 index 6542a77fe..000000000 --- a/include/grub/zfs/dsl_dir.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_DSL_DIR_H -#define _SYS_DSL_DIR_H - -typedef struct dsl_dir_phys { - grub_uint64_t dd_creation_time; /* not actually used */ - grub_uint64_t dd_head_dataset_obj; - grub_uint64_t dd_parent_obj; - grub_uint64_t dd_clone_parent_obj; - grub_uint64_t dd_child_dir_zapobj; - /* - * how much space our children are accounting for; for leaf - * datasets, == physical space used by fs + snaps - */ - grub_uint64_t dd_used_bytes; - grub_uint64_t dd_compressed_bytes; - grub_uint64_t dd_uncompressed_bytes; - /* Administrative quota setting */ - grub_uint64_t dd_quota; - /* Administrative reservation setting */ - grub_uint64_t dd_reserved; - grub_uint64_t dd_props_zapobj; - grub_uint64_t dd_deleg_zapobj; /* dataset permissions */ - grub_uint64_t unused[7]; - grub_uint64_t keychain; - grub_uint64_t unused2[12]; -} dsl_dir_phys_t; - -#endif /* _SYS_DSL_DIR_H */ diff --git a/include/grub/zfs/sa_impl.h b/include/grub/zfs/sa_impl.h deleted file mode 100644 index 0845d1290..000000000 --- a/include/grub/zfs/sa_impl.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -#ifndef _SYS_SA_IMPL_H -#define _SYS_SA_IMPL_H - -typedef struct sa_hdr_phys { - grub_uint32_t sa_magic; - grub_uint16_t sa_layout_info; - grub_uint16_t sa_lengths[1]; -} sa_hdr_phys_t; - -#define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 16, 3, 0) -#define SA_TYPE_OFFSET 0x0 -#define SA_SIZE_OFFSET 0x8 -#define SA_MTIME_OFFSET 0x38 -#define SA_SYMLINK_OFFSET 0xa0 - -#endif /* _SYS_SA_IMPL_H */ diff --git a/include/grub/zfs/spa.h b/include/grub/zfs/spa.h deleted file mode 100644 index 5afbe4ecd..000000000 --- a/include/grub/zfs/spa.h +++ /dev/null @@ -1,328 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc. - * Copyright 2010 Sun Microsystems, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_ZFS_SPA_HEADER -#define GRUB_ZFS_SPA_HEADER 1 - -#define grub_zfs_to_cpu16(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) ? \ - grub_be_to_cpu16(x) \ - : grub_le_to_cpu16(x)) -#define grub_cpu_to_zfs16(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) ? \ - grub_cpu_to_be16(x) \ - : grub_cpu_to_le16(x)) - -#define grub_zfs_to_cpu32(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) ? \ - grub_be_to_cpu32(x) \ - : grub_le_to_cpu32(x)) -#define grub_cpu_to_zfs32(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) ? \ - grub_cpu_to_be32(x) \ - : grub_cpu_to_le32(x)) - -#define grub_zfs_to_cpu64(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) \ - ? grub_be_to_cpu64(x) \ - : grub_le_to_cpu64(x)) -#define grub_cpu_to_zfs64(x,a) (((a) == GRUB_ZFS_BIG_ENDIAN) ? grub_cpu_to_be64(x) \ - : grub_cpu_to_le64(x)) - -/* - * General-purpose 32-bit and 64-bit bitfield encodings. - */ -#define BF32_DECODE(x, low, len) P2PHASE((x) >> (low), 1U << (len)) -#define BF64_DECODE(x, low, len) P2PHASE((x) >> (low), ((grub_uint64_t) 1) << (len)) -#define BF32_ENCODE(x, low, len) (P2PHASE((x), 1U << (len)) << (low)) -#define BF64_ENCODE(x, low, len) (P2PHASE((x), ((grub_uint64_t) 1) << (len)) << (low)) - -#define BF32_GET(x, low, len) BF32_DECODE(x, low, len) -#define BF64_GET(x, low, len) BF64_DECODE(x, low, len) - -#define BF32_SET(x, low, len, val) \ - ((x) ^= BF32_ENCODE((x >> low) ^ (val), low, len)) -#define BF64_SET(x, low, len, val) \ - ((x) ^= BF64_ENCODE((x >> low) ^ (val), low, len)) - -#define BF32_GET_SB(x, low, len, shift, bias) \ - ((BF32_GET(x, low, len) + (bias)) << (shift)) -#define BF64_GET_SB(x, low, len, shift, bias) \ - ((BF64_GET(x, low, len) + (bias)) << (shift)) - -#define BF32_SET_SB(x, low, len, shift, bias, val) \ - BF32_SET(x, low, len, ((val) >> (shift)) - (bias)) -#define BF64_SET_SB(x, low, len, shift, bias, val) \ - BF64_SET(x, low, len, ((val) >> (shift)) - (bias)) - -#define SPA_MINBLOCKSHIFT 9 -#define SPA_MINBLOCKSIZE (1ULL << SPA_MINBLOCKSHIFT) - -/* - * Size of block to hold the configuration data (a packed nvlist) - */ -#define SPA_CONFIG_BLOCKSIZE (1 << 14) - -/* - * The DVA size encodings for LSIZE and PSIZE support blocks up to 32MB. - * The ASIZE encoding should be at least 64 times larger (6 more bits) - * to support up to 4-way RAID-Z mirror mode with worst-case gang block - * overhead, three DVAs per bp, plus one more bit in case we do anything - * else that expands the ASIZE. - */ -#define SPA_LSIZEBITS 16 /* LSIZE up to 32M (2^16 * 512) */ -#define SPA_PSIZEBITS 16 /* PSIZE up to 32M (2^16 * 512) */ -#define SPA_ASIZEBITS 24 /* ASIZE up to 64 times larger */ - -/* - * All SPA data is represented by 128-bit data virtual addresses (DVAs). - * The members of the dva_t should be considered opaque outside the SPA. - */ -typedef struct dva { - grub_uint64_t dva_word[2]; -} dva_t; - -/* - * Each block has a 256-bit checksum -- strong enough for cryptographic hashes. - */ -typedef struct zio_cksum { - union - { - grub_uint64_t zc_word[4]; - struct - { - grub_uint32_t zc_cut_cksum[5]; - grub_uint32_t zc_mac[3]; - }; - }; -} zio_cksum_t; - -/* - * Each block is described by its DVAs, time of birth, checksum, etc. - * The word-by-word, bit-by-bit layout of the blkptr is as follows: - * - * 64 56 48 40 32 24 16 8 0 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * 0 | vdev1 | GRID | ASIZE | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * 1 |G| offset1 | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * 2 | vdev2 | GRID | ASIZE | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * 3 |G| offset2 | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * 4 | vdev3 | GRID | ASIZE | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * 5 |G| offset3 | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * 6 |BDX|lvl| type | cksum |E| comp| PSIZE | LSIZE | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * 7 | padding | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * 8 | padding | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * 9 | physical birth txg | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * a | logical birth txg | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * b | fill count | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * c | checksum[0] | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * d | checksum[1] | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * e | checksum[2] | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * f | checksum[3] | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * - * Legend: - * - * vdev virtual device ID - * offset offset into virtual device - * LSIZE logical size - * PSIZE physical size (after compression) - * ASIZE allocated size (including RAID-Z parity and gang block headers) - * GRID RAID-Z layout information (reserved for future use) - * cksum checksum function - * comp compression function - * G gang block indicator - * B byteorder (endianness) - * D dedup - * X encryption - * E blkptr_t contains embedded data - * lvl level of indirection - * type DMU object type - * phys birth txg of block allocation; zero if same as logical birth txg - * log. birth transaction group in which the block was logically born - * fill count number of non-zero blocks under this bp - * checksum[4] 256-bit checksum of the data this bp describes - */ -#define SPA_BLKPTRSHIFT 7 /* blkptr_t is 128 bytes */ -#define SPA_DVAS_PER_BP 3 /* Number of DVAs in a bp */ - -typedef struct blkptr { - dva_t blk_dva[SPA_DVAS_PER_BP]; /* Data Virtual Addresses */ - grub_uint64_t blk_prop; /* size, compression, type, etc */ - grub_uint64_t blk_pad[2]; /* Extra space for the future */ - grub_uint64_t blk_phys_birth; /* txg when block was allocated */ - grub_uint64_t blk_birth; /* transaction group at birth */ - grub_uint64_t blk_fill; /* fill count */ - zio_cksum_t blk_cksum; /* 256-bit checksum */ -} blkptr_t; - -/* - * Macros to get and set fields in a bp or DVA. - */ -#define DVA_GET_ASIZE(dva) \ - BF64_GET_SB((dva)->dva_word[0], 0, 24, SPA_MINBLOCKSHIFT, 0) -#define DVA_SET_ASIZE(dva, x) \ - BF64_SET_SB((dva)->dva_word[0], 0, 24, SPA_MINBLOCKSHIFT, 0, x) - -#define DVA_GET_GRID(dva) BF64_GET((dva)->dva_word[0], 24, 8) -#define DVA_SET_GRID(dva, x) BF64_SET((dva)->dva_word[0], 24, 8, x) - -#define DVA_GET_VDEV(dva) BF64_GET((dva)->dva_word[0], 32, 32) -#define DVA_SET_VDEV(dva, x) BF64_SET((dva)->dva_word[0], 32, 32, x) - -#define DVA_GET_GANG(dva) BF64_GET((dva)->dva_word[1], 63, 1) -#define DVA_SET_GANG(dva, x) BF64_SET((dva)->dva_word[1], 63, 1, x) - -#define BP_GET_LSIZE(bp) \ - BF64_GET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1) -#define BP_SET_LSIZE(bp, x) \ - BF64_SET_SB((bp)->blk_prop, 0, 16, SPA_MINBLOCKSHIFT, 1, x) - -#define BP_GET_COMPRESS(bp) BF64_GET((bp)->blk_prop, 32, 7) -#define BP_SET_COMPRESS(bp, x) BF64_SET((bp)->blk_prop, 32, 7, x) - -#define BP_GET_CHECKSUM(bp) BF64_GET((bp)->blk_prop, 40, 8) -#define BP_SET_CHECKSUM(bp, x) BF64_SET((bp)->blk_prop, 40, 8, x) - -#define BP_GET_TYPE(bp) BF64_GET((bp)->blk_prop, 48, 8) -#define BP_SET_TYPE(bp, x) BF64_SET((bp)->blk_prop, 48, 8, x) - -#define BP_GET_LEVEL(bp) BF64_GET((bp)->blk_prop, 56, 5) -#define BP_SET_LEVEL(bp, x) BF64_SET((bp)->blk_prop, 56, 5, x) - -#define BP_IS_EMBEDDED(bp) BF64_GET((bp)->blk_prop, 39, 1) - -#define BP_GET_PROP_BIT_61(bp) BF64_GET((bp)->blk_prop, 61, 1) -#define BP_SET_PROP_BIT_61(bp, x) BF64_SET((bp)->blk_prop, 61, 1, x) - -#define BP_GET_DEDUP(bp) BF64_GET((bp)->blk_prop, 62, 1) -#define BP_SET_DEDUP(bp, x) BF64_SET((bp)->blk_prop, 62, 1, x) - -#define BP_GET_BYTEORDER(bp) (0 - BF64_GET((bp)->blk_prop, 63, 1)) -#define BP_SET_BYTEORDER(bp, x) BF64_SET((bp)->blk_prop, 63, 1, x) - -#define BP_PHYSICAL_BIRTH(bp) \ - ((bp)->blk_phys_birth ? (bp)->blk_phys_birth : (bp)->blk_birth) - -#define BP_SET_BIRTH(bp, logical, physical) \ -{ \ - (bp)->blk_birth = (logical); \ - (bp)->blk_phys_birth = ((logical) == (physical) ? 0 : (physical)); \ -} - -#define BP_GET_ASIZE(bp) \ - (DVA_GET_ASIZE(&(bp)->blk_dva[0]) + DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \ - DVA_GET_ASIZE(&(bp)->blk_dva[2])) - -#define BP_GET_UCSIZE(bp) \ - ((BP_GET_LEVEL(bp) > 0 || dmu_ot[BP_GET_TYPE(bp)].ot_metadata) ? \ - BP_GET_PSIZE(bp) : BP_GET_LSIZE(bp)); - -#define BP_GET_NDVAS(bp) \ - (!!DVA_GET_ASIZE(&(bp)->blk_dva[0]) + \ - !!DVA_GET_ASIZE(&(bp)->blk_dva[1]) + \ - !!DVA_GET_ASIZE(&(bp)->blk_dva[2])) - -#define BP_COUNT_GANG(bp) \ - (DVA_GET_GANG(&(bp)->blk_dva[0]) + \ - DVA_GET_GANG(&(bp)->blk_dva[1]) + \ - DVA_GET_GANG(&(bp)->blk_dva[2])) - -#define DVA_EQUAL(dva1, dva2) \ - ((dva1)->dva_word[1] == (dva2)->dva_word[1] && \ - (dva1)->dva_word[0] == (dva2)->dva_word[0]) - -#define BP_EQUAL(bp1, bp2) \ - (BP_PHYSICAL_BIRTH(bp1) == BP_PHYSICAL_BIRTH(bp2) && \ - DVA_EQUAL(&(bp1)->blk_dva[0], &(bp2)->blk_dva[0]) && \ - DVA_EQUAL(&(bp1)->blk_dva[1], &(bp2)->blk_dva[1]) && \ - DVA_EQUAL(&(bp1)->blk_dva[2], &(bp2)->blk_dva[2])) - -#define ZIO_CHECKSUM_EQUAL(zc1, zc2) \ - (0 == (((zc1).zc_word[0] - (zc2).zc_word[0]) | \ - ((zc1).zc_word[1] - (zc2).zc_word[1]) | \ - ((zc1).zc_word[2] - (zc2).zc_word[2]) | \ - ((zc1).zc_word[3] - (zc2).zc_word[3]))) - -#define DVA_IS_VALID(dva) (DVA_GET_ASIZE(dva) != 0) - -#define ZIO_SET_CHECKSUM(zcp, w0, w1, w2, w3) \ -{ \ - (zcp)->zc_word[0] = w0; \ - (zcp)->zc_word[1] = w1; \ - (zcp)->zc_word[2] = w2; \ - (zcp)->zc_word[3] = w3; \ -} - -#define BPE_GET_ETYPE(bp) BP_GET_CHECKSUM(bp) -#define BPE_GET_LSIZE(bp) \ - BF64_GET_SB((bp)->blk_prop, 0, 25, 0, 1) -#define BPE_GET_PSIZE(bp) \ - BF64_GET_SB((bp)->blk_prop, 25, 7, 0, 1) - -typedef enum bp_embedded_type { - BP_EMBEDDED_TYPE_DATA, - NUM_BP_EMBEDDED_TYPES -} bp_embedded_type_t; - -#define BPE_NUM_WORDS 14 -#define BPE_PAYLOAD_SIZE (BPE_NUM_WORDS * sizeof(grub_uint64_t)) -#define BPE_IS_PAYLOADWORD(bp, wp) \ - ((wp) != &(bp)->blk_prop && (wp) != &(bp)->blk_birth) - -#define BP_IDENTITY(bp) (&(bp)->blk_dva[0]) -#define BP_IS_GANG(bp) DVA_GET_GANG(BP_IDENTITY(bp)) -#define DVA_IS_EMPTY(dva) ((dva)->dva_word[0] == 0ULL && \ - (dva)->dva_word[1] == 0ULL) -#define BP_IS_HOLE(bp) DVA_IS_EMPTY(BP_IDENTITY(bp)) - -/* BP_IS_RAIDZ(bp) assumes no block compression */ -#define BP_IS_RAIDZ(bp) (DVA_GET_ASIZE(&(bp)->blk_dva[0]) > \ - BP_GET_PSIZE(bp)) - -#define BP_ZERO(bp) \ -{ \ - (bp)->blk_dva[0].dva_word[0] = 0; \ - (bp)->blk_dva[0].dva_word[1] = 0; \ - (bp)->blk_dva[1].dva_word[0] = 0; \ - (bp)->blk_dva[1].dva_word[1] = 0; \ - (bp)->blk_dva[2].dva_word[0] = 0; \ - (bp)->blk_dva[2].dva_word[1] = 0; \ - (bp)->blk_prop = 0; \ - (bp)->blk_pad[0] = 0; \ - (bp)->blk_pad[1] = 0; \ - (bp)->blk_phys_birth = 0; \ - (bp)->blk_birth = 0; \ - (bp)->blk_fill = 0; \ - ZIO_SET_CHECKSUM(&(bp)->blk_cksum, 0, 0, 0, 0); \ -} - -#define BP_SPRINTF_LEN 320 - -#endif /* ! GRUB_ZFS_SPA_HEADER */ diff --git a/include/grub/zfs/uberblock_impl.h b/include/grub/zfs/uberblock_impl.h deleted file mode 100644 index 1bf7f2b07..000000000 --- a/include/grub/zfs/uberblock_impl.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_UBERBLOCK_IMPL_H -#define _SYS_UBERBLOCK_IMPL_H - -/* - * The uberblock version is incremented whenever an incompatible on-disk - * format change is made to the SPA, DMU, or ZAP. - * - * Note: the first two fields should never be moved. When a storage pool - * is opened, the uberblock must be read off the disk before the version - * can be checked. If the ub_version field is moved, we may not detect - * version mismatch. If the ub_magic field is moved, applications that - * expect the magic number in the first word won't work. - */ -#define UBERBLOCK_MAGIC 0x00bab10c /* oo-ba-bloc! */ -#define UBERBLOCK_SHIFT 10 /* up to 1K */ - -typedef struct uberblock { - grub_uint64_t ub_magic; /* UBERBLOCK_MAGIC */ - grub_uint64_t ub_version; /* ZFS_VERSION */ - grub_uint64_t ub_txg; /* txg of last sync */ - grub_uint64_t ub_guid_sum; /* sum of all vdev guids */ - grub_uint64_t ub_timestamp; /* UTC time of last sync */ - blkptr_t ub_rootbp; /* MOS objset_phys_t */ -} uberblock_t; - -#define UBERBLOCK_SIZE (1ULL << UBERBLOCK_SHIFT) -#define VDEV_UBERBLOCK_SHIFT UBERBLOCK_SHIFT - -/* XXX Uberblock_phys_t is no longer in the kernel zfs */ -typedef struct uberblock_phys { - uberblock_t ubp_uberblock; - char ubp_pad[UBERBLOCK_SIZE - sizeof (uberblock_t) - - sizeof (zio_eck_t)]; - zio_eck_t ubp_zec; -} uberblock_phys_t; - - -#endif /* _SYS_UBERBLOCK_IMPL_H */ diff --git a/include/grub/zfs/vdev_impl.h b/include/grub/zfs/vdev_impl.h deleted file mode 100644 index 9b5f0a7a8..000000000 --- a/include/grub/zfs/vdev_impl.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_VDEV_IMPL_H -#define _SYS_VDEV_IMPL_H - -#define VDEV_SKIP_SIZE (8 << 10) -#define VDEV_BOOT_HEADER_SIZE (8 << 10) -#define VDEV_PHYS_SIZE (112 << 10) -#define VDEV_UBERBLOCK_RING (128 << 10) - -/* ZFS boot block */ -#define VDEV_BOOT_MAGIC 0x2f5b007b10cULL -#define VDEV_BOOT_VERSION 1 /* version number */ - -typedef struct vdev_boot_header { - grub_uint64_t vb_magic; /* VDEV_BOOT_MAGIC */ - grub_uint64_t vb_version; /* VDEV_BOOT_VERSION */ - grub_uint64_t vb_offset; /* start offset (bytes) */ - grub_uint64_t vb_size; /* size (bytes) */ - char vb_pad[VDEV_BOOT_HEADER_SIZE - 4 * sizeof (grub_uint64_t)]; -} vdev_boot_header_t; - -typedef struct vdev_phys { - char vp_nvlist[VDEV_PHYS_SIZE - sizeof (zio_eck_t)]; - zio_eck_t vp_zbt; -} vdev_phys_t; - -typedef struct vdev_label { - char vl_pad[VDEV_SKIP_SIZE]; /* 8K */ - vdev_boot_header_t vl_boot_header; /* 8K */ - vdev_phys_t vl_vdev_phys; /* 112K */ - char vl_uberblock[VDEV_UBERBLOCK_RING]; /* 128K */ -} vdev_label_t; /* 256K total */ - -/* - * Size and offset of embedded boot loader region on each label. - * The total size of the first two labels plus the boot area is 4MB. - */ -#define VDEV_BOOT_OFFSET (2 * sizeof (vdev_label_t)) -#define VDEV_BOOT_SIZE (7ULL << 19) /* 3.5M */ - -/* - * Size of label regions at the start and end of each leaf device. - */ -#define VDEV_LABEL_START_SIZE (2 * sizeof (vdev_label_t) + VDEV_BOOT_SIZE) -#define VDEV_LABEL_END_SIZE (2 * sizeof (vdev_label_t)) -#define VDEV_LABELS 4 - -#endif /* _SYS_VDEV_IMPL_H */ diff --git a/include/grub/zfs/zap_impl.h b/include/grub/zfs/zap_impl.h deleted file mode 100644 index 0e985d9f9..000000000 --- a/include/grub/zfs/zap_impl.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_ZAP_IMPL_H -#define _SYS_ZAP_IMPL_H - -#define ZAP_MAGIC 0x2F52AB2ABULL - -#define ZAP_HASHBITS 28 -#define MZAP_ENT_LEN 64 -#define MZAP_NAME_LEN (MZAP_ENT_LEN - 8 - 4 - 2) - -typedef struct mzap_ent_phys { - grub_uint64_t mze_value; - grub_uint32_t mze_cd; - grub_uint16_t mze_pad; /* in case we want to chain them someday */ - char mze_name[MZAP_NAME_LEN]; -} mzap_ent_phys_t; - -typedef struct mzap_phys { - grub_uint64_t mz_block_type; /* ZBT_MICRO */ - grub_uint64_t mz_salt; - grub_uint64_t mz_pad[6]; - mzap_ent_phys_t mz_chunk[1]; - /* actually variable size depending on block size */ -} mzap_phys_t; - -/* - * The (fat) zap is stored in one object. It is an array of - * 1<= 6] [zap_leaf_t] [ptrtbl] ... - * - */ - -#define ZBT_LEAF ((1ULL << 63) + 0) -#define ZBT_HEADER ((1ULL << 63) + 1) -#define ZBT_MICRO ((1ULL << 63) + 3) -/* any other values are ptrtbl blocks */ - -/* - * the embedded pointer table takes up half a block: - * block size / entry size (2^3) / 2 - */ -#define ZAP_EMBEDDED_PTRTBL_SHIFT(zap) (FZAP_BLOCK_SHIFT(zap) - 3 - 1) - -/* - * The embedded pointer table starts half-way through the block. Since - * the pointer table itself is half the block, it starts at (64-bit) - * word number (1<zap_f.zap_phys) \ - [(idx) + (1<. - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_ZAP_LEAF_H -#define _SYS_ZAP_LEAF_H - -#define ZAP_LEAF_MAGIC 0x2AB1EAF - -/* chunk size = 24 bytes */ -#define ZAP_LEAF_CHUNKSIZE 24 - -/* - * The amount of space within the chunk available for the array is: - * chunk size - space for type (1) - space for next pointer (2) - */ -#define ZAP_LEAF_ARRAY_BYTES (ZAP_LEAF_CHUNKSIZE - 3) - -typedef enum zap_chunk_type { - ZAP_CHUNK_FREE = 253, - ZAP_CHUNK_ENTRY = 252, - ZAP_CHUNK_ARRAY = 251, - ZAP_CHUNK_TYPE_MAX = 250 -} zap_chunk_type_t; - -/* - * TAKE NOTE: - * If zap_leaf_phys_t is modified, zap_leaf_byteswap() must be modified. - */ -typedef struct zap_leaf_phys { - struct zap_leaf_header { - grub_uint64_t lh_block_type; /* ZBT_LEAF */ - grub_uint64_t lh_pad1; - grub_uint64_t lh_prefix; /* hash prefix of this leaf */ - grub_uint32_t lh_magic; /* ZAP_LEAF_MAGIC */ - grub_uint16_t lh_nfree; /* number free chunks */ - grub_uint16_t lh_nentries; /* number of entries */ - grub_uint16_t lh_prefix_len; /* num bits used to id this */ - -/* above is accessable to zap, below is zap_leaf private */ - - grub_uint16_t lh_freelist; /* chunk head of free list */ - grub_uint8_t lh_pad2[12]; - } l_hdr; /* 2 24-byte chunks */ - - /* - * The header is followed by a hash table with - * ZAP_LEAF_HASH_NUMENTRIES(zap) entries. The hash table is - * followed by an array of ZAP_LEAF_NUMCHUNKS(zap) - * zap_leaf_chunk structures. These structures are accessed - * with the ZAP_LEAF_CHUNK() macro. - */ - - grub_uint16_t l_hash[0]; -} zap_leaf_phys_t; - -typedef union zap_leaf_chunk { - struct zap_leaf_entry { - grub_uint8_t le_type; /* always ZAP_CHUNK_ENTRY */ - grub_uint8_t le_int_size; /* size of ints */ - grub_uint16_t le_next; /* next entry in hash chain */ - grub_uint16_t le_name_chunk; /* first chunk of the name */ - grub_uint16_t le_name_length; /* bytes in name, incl null */ - grub_uint16_t le_value_chunk; /* first chunk of the value */ - grub_uint16_t le_value_length; /* value length in ints */ - grub_uint32_t le_cd; /* collision differentiator */ - grub_uint64_t le_hash; /* hash value of the name */ - } l_entry; - struct zap_leaf_array { - grub_uint8_t la_type; /* always ZAP_CHUNK_ARRAY */ - union - { - grub_uint8_t la_array[ZAP_LEAF_ARRAY_BYTES]; - grub_uint64_t la_array64; - } GRUB_PACKED; - grub_uint16_t la_next; /* next blk or CHAIN_END */ - } l_array; - struct zap_leaf_free { - grub_uint8_t lf_type; /* always ZAP_CHUNK_FREE */ - grub_uint8_t lf_pad[ZAP_LEAF_ARRAY_BYTES]; - grub_uint16_t lf_next; /* next in free list, or CHAIN_END */ - } l_free; -} zap_leaf_chunk_t; - -#endif /* _SYS_ZAP_LEAF_H */ diff --git a/include/grub/zfs/zfs.h b/include/grub/zfs/zfs.h deleted file mode 100644 index 4ee513887..000000000 --- a/include/grub/zfs/zfs.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004,2009 Free Software Foundation, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -#ifndef GRUB_ZFS_HEADER -#define GRUB_ZFS_HEADER 1 - -#include -#include -#include - -typedef enum grub_zfs_endian - { - GRUB_ZFS_UNKNOWN_ENDIAN = -2, - GRUB_ZFS_LITTLE_ENDIAN = -1, - GRUB_ZFS_BIG_ENDIAN = 0 - } grub_zfs_endian_t; - -/* - * On-disk version number. - */ -#define SPA_VERSION_INITIAL 1ULL -#define SPA_VERSION_BEFORE_FEATURES 33ULL -#define SPA_VERSION_FEATURES 5000ULL -#define SPA_VERSION_IS_SUPPORTED(v) \ - (((v) >= SPA_VERSION_INITIAL && (v) <= SPA_VERSION_BEFORE_FEATURES) || \ - ((v) == SPA_VERSION_FEATURES)) -/* - * The following are configuration names used in the nvlist describing a pool's - * configuration. - */ -#define ZPOOL_CONFIG_VERSION "version" -#define ZPOOL_CONFIG_POOL_NAME "name" -#define ZPOOL_CONFIG_POOL_STATE "state" -#define ZPOOL_CONFIG_POOL_TXG "txg" -#define ZPOOL_CONFIG_POOL_GUID "pool_guid" -#define ZPOOL_CONFIG_CREATE_TXG "create_txg" -#define ZPOOL_CONFIG_TOP_GUID "top_guid" -#define ZPOOL_CONFIG_VDEV_TREE "vdev_tree" -#define ZPOOL_CONFIG_TYPE "type" -#define ZPOOL_CONFIG_CHILDREN "children" -#define ZPOOL_CONFIG_ID "id" -#define ZPOOL_CONFIG_GUID "guid" -#define ZPOOL_CONFIG_PATH "path" -#define ZPOOL_CONFIG_DEVID "devid" -#define ZPOOL_CONFIG_METASLAB_ARRAY "metaslab_array" -#define ZPOOL_CONFIG_METASLAB_SHIFT "metaslab_shift" -#define ZPOOL_CONFIG_ASHIFT "ashift" -#define ZPOOL_CONFIG_ASIZE "asize" -#define ZPOOL_CONFIG_DTL "DTL" -#define ZPOOL_CONFIG_STATS "stats" -#define ZPOOL_CONFIG_WHOLE_DISK "whole_disk" -#define ZPOOL_CONFIG_ERRCOUNT "error_count" -#define ZPOOL_CONFIG_NOT_PRESENT "not_present" -#define ZPOOL_CONFIG_SPARES "spares" -#define ZPOOL_CONFIG_IS_SPARE "is_spare" -#define ZPOOL_CONFIG_NPARITY "nparity" -#define ZPOOL_CONFIG_PHYS_PATH "phys_path" -#define ZPOOL_CONFIG_L2CACHE "l2cache" -#define ZPOOL_CONFIG_HOLE_ARRAY "hole_array" -#define ZPOOL_CONFIG_VDEV_CHILDREN "vdev_children" -#define ZPOOL_CONFIG_IS_HOLE "is_hole" -#define ZPOOL_CONFIG_DDT_HISTOGRAM "ddt_histogram" -#define ZPOOL_CONFIG_DDT_OBJ_STATS "ddt_object_stats" -#define ZPOOL_CONFIG_DDT_STATS "ddt_stats" -#define ZPOOL_CONFIG_FEATURES_FOR_READ "features_for_read" -/* - * The persistent vdev state is stored as separate values rather than a single - * 'vdev_state' entry. This is because a device can be in multiple states, such - * as offline and degraded. - */ -#define ZPOOL_CONFIG_OFFLINE "offline" -#define ZPOOL_CONFIG_FAULTED "faulted" -#define ZPOOL_CONFIG_DEGRADED "degraded" -#define ZPOOL_CONFIG_REMOVED "removed" - -#define VDEV_TYPE_ROOT "root" -#define VDEV_TYPE_MIRROR "mirror" -#define VDEV_TYPE_REPLACING "replacing" -#define VDEV_TYPE_RAIDZ "raidz" -#define VDEV_TYPE_DISK "disk" -#define VDEV_TYPE_FILE "file" -#define VDEV_TYPE_MISSING "missing" -#define VDEV_TYPE_HOLE "hole" -#define VDEV_TYPE_SPARE "spare" -#define VDEV_TYPE_L2CACHE "l2cache" - -/* - * pool state. The following states are written to disk as part of the normal - * SPA lifecycle: ACTIVE, EXPORTED, DESTROYED, SPARE, L2CACHE. The remaining - * states are software abstractions used at various levels to communicate pool - * state. - */ -typedef enum pool_state { - POOL_STATE_ACTIVE = 0, /* In active use */ - POOL_STATE_EXPORTED, /* Explicitly exported */ - POOL_STATE_DESTROYED, /* Explicitly destroyed */ - POOL_STATE_SPARE, /* Reserved for hot spare use */ - POOL_STATE_L2CACHE, /* Level 2 ARC device */ - POOL_STATE_UNINITIALIZED, /* Internal spa_t state */ - POOL_STATE_UNAVAIL, /* Internal libzfs state */ - POOL_STATE_POTENTIALLY_ACTIVE /* Internal libzfs state */ -} pool_state_t; - -struct grub_zfs_data; - -grub_err_t grub_zfs_fetch_nvlist (grub_device_t dev, char **nvlist); -grub_err_t grub_zfs_getmdnobj (grub_device_t dev, const char *fsfilename, - grub_uint64_t *mdnobj); - -char *grub_zfs_nvlist_lookup_string (const char *nvlist, const char *name); -char *grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name); -int grub_zfs_nvlist_lookup_uint64 (const char *nvlist, const char *name, - grub_uint64_t *out); -char *grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, - const char *name, - grub_size_t array_index); -int grub_zfs_nvlist_lookup_nvlist_array_get_nelm (const char *nvlist, - const char *name); -grub_err_t -grub_zfs_add_key (grub_uint8_t *key_in, - grub_size_t keylen, - int passphrase); - -extern grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, - grub_uint64_t algo, - void *nonce, - char *buf, grub_size_t size, - const grub_uint32_t *expected_mac, - grub_zfs_endian_t endian); - -struct grub_zfs_key; - -extern grub_crypto_cipher_handle_t (*grub_zfs_load_key) (const struct grub_zfs_key *key, - grub_size_t keysize, - grub_uint64_t salt, - grub_uint64_t algo); - - - -#endif /* ! GRUB_ZFS_HEADER */ diff --git a/include/grub/zfs/zfs_acl.h b/include/grub/zfs/zfs_acl.h deleted file mode 100644 index 277738279..000000000 --- a/include/grub/zfs/zfs_acl.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_FS_ZFS_ACL_H -#define _SYS_FS_ZFS_ACL_H - -#ifndef _UID_T -#define _UID_T -typedef unsigned int uid_t; /* UID type */ -#endif /* _UID_T */ - -typedef struct zfs_oldace { - grub_uint32_t z_fuid; /* "who" */ - grub_uint32_t z_access_mask; /* access mask */ - grub_uint16_t z_flags; /* flags, i.e inheritance */ - grub_uint16_t z_type; /* type of entry allow/deny */ -} zfs_oldace_t; - -#define ACE_SLOT_CNT 6 - -typedef struct zfs_znode_acl_v0 { - grub_uint64_t z_acl_extern_obj; /* ext acl pieces */ - grub_uint32_t z_acl_count; /* Number of ACEs */ - grub_uint16_t z_acl_version; /* acl version */ - grub_uint16_t z_acl_pad; /* pad */ - zfs_oldace_t z_ace_data[ACE_SLOT_CNT]; /* 6 standard ACEs */ -} zfs_znode_acl_v0_t; - -#define ZFS_ACE_SPACE (sizeof (zfs_oldace_t) * ACE_SLOT_CNT) - -typedef struct zfs_znode_acl { - grub_uint64_t z_acl_extern_obj; /* ext acl pieces */ - grub_uint32_t z_acl_size; /* Number of bytes in ACL */ - grub_uint16_t z_acl_version; /* acl version */ - grub_uint16_t z_acl_count; /* ace count */ - grub_uint8_t z_ace_data[ZFS_ACE_SPACE]; /* space for embedded ACEs */ -} zfs_znode_acl_t; - - -#endif /* _SYS_FS_ZFS_ACL_H */ diff --git a/include/grub/zfs/zfs_znode.h b/include/grub/zfs/zfs_znode.h deleted file mode 100644 index efd6d10a6..000000000 --- a/include/grub/zfs/zfs_znode.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_FS_ZFS_ZNODE_H -#define _SYS_FS_ZFS_ZNODE_H - -#include - -#define MASTER_NODE_OBJ 1 -#define ZFS_ROOT_OBJ "ROOT" -#define ZPL_VERSION_STR "VERSION" -#define ZFS_SA_ATTRS "SA_ATTRS" - -#define ZPL_VERSION 5ULL - -#define ZFS_DIRENT_OBJ(de) BF64_GET(de, 0, 48) - -/* - * This is the persistent portion of the znode. It is stored - * in the "bonus buffer" of the file. Short symbolic links - * are also stored in the bonus buffer. - */ -typedef struct znode_phys { - grub_uint64_t zp_atime[2]; /* 0 - last file access time */ - grub_uint64_t zp_mtime[2]; /* 16 - last file modification time */ - grub_uint64_t zp_ctime[2]; /* 32 - last file change time */ - grub_uint64_t zp_crtime[2]; /* 48 - creation time */ - grub_uint64_t zp_gen; /* 64 - generation (txg of creation) */ - grub_uint64_t zp_mode; /* 72 - file mode bits */ - grub_uint64_t zp_size; /* 80 - size of file */ - grub_uint64_t zp_parent; /* 88 - directory parent (`..') */ - grub_uint64_t zp_links; /* 96 - number of links to file */ - grub_uint64_t zp_xattr; /* 104 - DMU object for xattrs */ - grub_uint64_t zp_rdev; /* 112 - dev_t for VBLK & VCHR files */ - grub_uint64_t zp_flags; /* 120 - persistent flags */ - grub_uint64_t zp_uid; /* 128 - file owner */ - grub_uint64_t zp_gid; /* 136 - owning group */ - grub_uint64_t zp_pad[4]; /* 144 - future */ - zfs_znode_acl_t zp_acl; /* 176 - 263 ACL */ - /* - * Data may pad out any remaining bytes in the znode buffer, eg: - * - * |<---------------------- dnode_phys (512) ------------------------>| - * |<-- dnode (192) --->|<----------- "bonus" buffer (320) ---------->| - * |<---- znode (264) ---->|<---- data (56) ---->| - * - * At present, we only use this space to store symbolic links. - */ -} znode_phys_t; - -#endif /* _SYS_FS_ZFS_ZNODE_H */ diff --git a/include/grub/zfs/zil.h b/include/grub/zfs/zil.h deleted file mode 100644 index 45d16f402..000000000 --- a/include/grub/zfs/zil.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_ZIL_H -#define _SYS_ZIL_H - -/* - * Intent log format: - * - * Each objset has its own intent log. The log header (zil_header_t) - * for objset N's intent log is kept in the Nth object of the SPA's - * intent_log objset. The log header points to a chain of log blocks, - * each of which contains log records (i.e., transactions) followed by - * a log block trailer (zil_trailer_t). The format of a log record - * depends on the record (or transaction) type, but all records begin - * with a common structure that defines the type, length, and txg. - */ - -/* - * Intent log header - this on disk structure holds fields to manage - * the log. All fields are 64 bit to easily handle cross architectures. - */ -typedef struct zil_header { - grub_uint64_t zh_claim_txg; /* txg in which log blocks were claimed */ - grub_uint64_t zh_replay_seq; /* highest replayed sequence number */ - blkptr_t zh_log; /* log chain */ - grub_uint64_t zh_claim_seq; /* highest claimed sequence number */ - grub_uint64_t zh_flags; /* header flags */ - grub_uint64_t zh_pad[4]; -} zil_header_t; - -/* - * zh_flags bit settings - */ -#define ZIL_REPLAY_NEEDED 0x1 /* replay needed - internal only */ - -#endif /* _SYS_ZIL_H */ diff --git a/include/grub/zfs/zio.h b/include/grub/zfs/zio.h deleted file mode 100644 index 997b0c4d4..000000000 --- a/include/grub/zfs/zio.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _ZIO_H -#define _ZIO_H - -#include - -#define ZEC_MAGIC 0x210da7ab10c7a11ULL /* zio data bloc tail */ - -typedef struct zio_eck { - grub_uint64_t zec_magic; /* for validation, endianness */ - zio_cksum_t zec_cksum; /* 256-bit checksum */ -} GRUB_PACKED zio_eck_t; - -/* - * Gang block headers are self-checksumming and contain an array - * of block pointers. - */ -#define SPA_GANGBLOCKSIZE SPA_MINBLOCKSIZE -#define SPA_GBH_NBLKPTRS ((SPA_GANGBLOCKSIZE - \ - sizeof (zio_eck_t)) / sizeof (blkptr_t)) -#define SPA_GBH_FILLER ((SPA_GANGBLOCKSIZE - \ - sizeof (zio_eck_t) - \ - (SPA_GBH_NBLKPTRS * sizeof (blkptr_t))) /\ - sizeof (grub_uint64_t)) - -#define ZIO_GET_IOSIZE(zio) \ - (BP_IS_GANG((zio)->io_bp) ? \ - SPA_GANGBLOCKSIZE : BP_GET_PSIZE((zio)->io_bp)) - -typedef struct zio_gbh { - blkptr_t zg_blkptr[SPA_GBH_NBLKPTRS]; - grub_uint64_t zg_filler[SPA_GBH_FILLER]; - zio_eck_t zg_tail; -} zio_gbh_phys_t; - -enum zio_checksum { - ZIO_CHECKSUM_INHERIT = 0, - ZIO_CHECKSUM_ON, - ZIO_CHECKSUM_OFF, - ZIO_CHECKSUM_LABEL, - ZIO_CHECKSUM_GANG_HEADER, - ZIO_CHECKSUM_ZILOG, - ZIO_CHECKSUM_FLETCHER_2, - ZIO_CHECKSUM_FLETCHER_4, - ZIO_CHECKSUM_SHA256, - ZIO_CHECKSUM_ZILOG2, - ZIO_CHECKSUM_SHA256_MAC, - ZIO_CHECKSUM_FUNCTIONS -}; - -#define ZIO_CHECKSUM_ON_VALUE ZIO_CHECKSUM_FLETCHER_2 -#define ZIO_CHECKSUM_DEFAULT ZIO_CHECKSUM_ON - -enum zio_compress { - ZIO_COMPRESS_INHERIT = 0, - ZIO_COMPRESS_ON, - ZIO_COMPRESS_OFF, - ZIO_COMPRESS_LZJB, - ZIO_COMPRESS_EMPTY, - ZIO_COMPRESS_GZIP1, - ZIO_COMPRESS_GZIP2, - ZIO_COMPRESS_GZIP3, - ZIO_COMPRESS_GZIP4, - ZIO_COMPRESS_GZIP5, - ZIO_COMPRESS_GZIP6, - ZIO_COMPRESS_GZIP7, - ZIO_COMPRESS_GZIP8, - ZIO_COMPRESS_GZIP9, - ZIO_COMPRESS_ZLE, - ZIO_COMPRESS_LZ4, - ZIO_COMPRESS_ZSTD, - ZIO_COMPRESS_FUNCTIONS -}; - -#endif /* _ZIO_H */ diff --git a/include/grub/zfs/zio_checksum.h b/include/grub/zfs/zio_checksum.h deleted file mode 100644 index e03c85a83..000000000 --- a/include/grub/zfs/zio_checksum.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. - * - * GRUB is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_ZIO_CHECKSUM_H -#define _SYS_ZIO_CHECKSUM_H - -extern void zio_checksum_SHA256 (const void *, grub_uint64_t, - grub_zfs_endian_t endian, zio_cksum_t *); -extern void fletcher_2 (const void *, grub_uint64_t, grub_zfs_endian_t endian, - zio_cksum_t *); -extern void fletcher_4 (const void *, grub_uint64_t, grub_zfs_endian_t endian, - zio_cksum_t *); - -#endif /* _SYS_ZIO_CHECKSUM_H */ diff --git a/include/multiboot.h b/include/multiboot.h index 7e5ac69ba..c529c5c5f 100644 --- a/include/multiboot.h +++ b/include/multiboot.h @@ -1,5 +1,5 @@ /* multiboot.h - Multiboot header file. */ -/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. +/* 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 @@ -24,7 +24,6 @@ /* 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 @@ -236,9 +235,8 @@ struct multiboot_mmap_entry #define MULTIBOOT_MEMORY_RESERVED 2 #define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 #define MULTIBOOT_MEMORY_NVS 4 -#define MULTIBOOT_MEMORY_BADRAM 5 multiboot_uint32_t type; -} GRUB_PACKED; +} __attribute__((packed)); typedef struct multiboot_mmap_entry multiboot_memory_map_t; struct multiboot_mod_list @@ -255,20 +253,6 @@ struct multiboot_mod_list }; typedef struct multiboot_mod_list multiboot_module_t; -/* APM BIOS info. */ -struct multiboot_apm_info -{ - grub_uint16_t version; - grub_uint16_t cseg; - grub_uint32_t offset; - grub_uint16_t cseg_16; - grub_uint16_t dseg; - grub_uint16_t flags; - grub_uint16_t cseg_len; - grub_uint16_t cseg_16_len; - grub_uint16_t dseg_len; -}; - #endif /* ! ASM_FILE */ #endif /* ! MULTIBOOT_HEADER */ diff --git a/include/multiboot2.h b/include/multiboot2.h index a039aa043..1b649d514 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -23,8 +23,7 @@ #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 +#define MULTIBOOT_SEARCH 8192 /* The magic field should contain this. */ #define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 @@ -36,55 +35,58 @@ #define MULTIBOOT_MOD_ALIGN 0x00001000 /* Alignment of the multiboot info structure. */ -#define MULTIBOOT_INFO_ALIGN 0x00000008 +#define MULTIBOOT_INFO_ALIGN 0x00000004 /* 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_TAG_TYPE_EFI32 11 -#define MULTIBOOT_TAG_TYPE_EFI64 12 -#define MULTIBOOT_TAG_TYPE_SMBIOS 13 -#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14 -#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15 -#define MULTIBOOT_TAG_TYPE_NETWORK 16 -#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17 -#define MULTIBOOT_TAG_TYPE_EFI_BS 18 -#define MULTIBOOT_TAG_TYPE_EFI32_IH 19 -#define MULTIBOOT_TAG_TYPE_EFI64_IH 20 -#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21 +/* Align all boot modules on i386 page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 -#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_HEADER_TAG_EFI_BS 7 -#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 -#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10 +/* Must pass memory information to OS. */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 -#define MULTIBOOT2_ARCHITECTURE_I386 0 -#define MULTIBOOT2_ARCHITECTURE_MIPS32 4 -#define MULTIBOOT_HEADER_TAG_OPTIONAL 1 +/* Must pass video information to OS. */ +#define MULTIBOOT_VIDEO_MODE 0x00000004 -#define MULTIBOOT_LOAD_PREFERENCE_NONE 0 -#define MULTIBOOT_LOAD_PREFERENCE_LOW 1 -#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2 +/* This flag indicates the use of the address fields in the header. */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 -#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 -#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 +/* 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 @@ -98,184 +100,96 @@ 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; + /* Feature flags. */ + multiboot_uint32_t flags; /* 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; + /* 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; -}; - -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; + /* 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; }; -struct multiboot_header_tag_module_align +/* The symbol table for a.out. */ +struct multiboot_aout_symbol_table { - multiboot_uint16_t type; - multiboot_uint16_t flags; + 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_header_tag_relocatable +struct multiboot_info { - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t min_addr; - multiboot_uint32_t max_addr; - multiboot_uint32_t align; - multiboot_uint32_t preference; -}; + /* Multiboot info version number */ + multiboot_uint32_t flags; -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 -#define MULTIBOOT_MEMORY_BADRAM 5 - multiboot_uint32_t type; - multiboot_uint32_t zero; -}; -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; + /* Available memory from BIOS */ 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; -}; + /* "root" partition */ + multiboot_uint32_t boot_device; -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]; -}; + /* Kernel command line */ + multiboot_uint32_t cmdline; -struct multiboot_vbe_info_block -{ - multiboot_uint8_t external_specification[512]; -}; + /* Boot-Module list */ + multiboot_uint32_t mods_count; + multiboot_uint32_t mods_addr; -struct multiboot_vbe_mode_info_block -{ - multiboot_uint8_t external_specification[256]; -}; + union + { + multiboot_aout_symbol_table_t aout_sym; + multiboot_elf_section_header_table_t elf_sec; + } u; -struct multiboot_tag_vbe -{ - multiboot_uint32_t type; - multiboot_uint32_t size; + /* 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; - 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; @@ -285,19 +199,12 @@ struct multiboot_tag_framebuffer_common #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_uint32_t framebuffer_palette_addr; multiboot_uint16_t framebuffer_palette_num_colors; - struct multiboot_color framebuffer_palette[0]; }; struct { @@ -310,106 +217,41 @@ struct multiboot_tag_framebuffer }; }; }; +typedef struct multiboot_info multiboot_info_t; -struct multiboot_tag_elf_sections +struct multiboot_color { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t num; - multiboot_uint32_t entsize; - multiboot_uint32_t shndx; - char sections[0]; + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; }; -struct multiboot_tag_apm +struct multiboot_mmap_entry { - 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; -}; + 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_tag_efi32 +struct multiboot_mod_list { - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t pointer; -}; + /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */ + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; -struct multiboot_tag_efi64 -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint64_t pointer; -}; + /* Module command line */ + multiboot_uint32_t cmdline; -struct multiboot_tag_smbios -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t major; - multiboot_uint8_t minor; - multiboot_uint8_t reserved[6]; - multiboot_uint8_t tables[0]; -}; - -struct multiboot_tag_old_acpi -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t rsdp[0]; -}; - -struct multiboot_tag_new_acpi -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t rsdp[0]; -}; - -struct multiboot_tag_network -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t dhcpack[0]; -}; - -struct multiboot_tag_efi_mmap -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t descr_size; - multiboot_uint32_t descr_vers; - multiboot_uint8_t efi_mmap[0]; -}; - -struct multiboot_tag_efi32_ih -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t pointer; -}; - -struct multiboot_tag_efi64_ih -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint64_t pointer; -}; - -struct multiboot_tag_load_base_addr -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t load_base_addr; + /* 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 */ diff --git a/include/xen/arch-x86/xen-x86_32.h b/include/xen/arch-x86/xen-x86_32.h deleted file mode 100644 index 9ca33d824..000000000 --- a/include/xen/arch-x86/xen-x86_32.h +++ /dev/null @@ -1,169 +0,0 @@ -/****************************************************************************** - * xen-x86_32.h - * - * Guest OS interface to x86 32-bit Xen. - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2004-2007, K A Fraser - */ - -#ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ -#define __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ - -/* - * Hypercall interface: - * Input: %ebx, %ecx, %edx, %esi, %edi, %ebp (arguments 1-6) - * Output: %eax - * Access is via hypercall page (set up by guest loader or via a Xen MSR): - * call hypercall_page + hypercall-number * 32 - * Clobbered: Argument registers (e.g., 2-arg hypercall clobbers %ebx,%ecx) - */ - -/* - * These flat segments are in the Xen-private section of every GDT. Since these - * are also present in the initial GDT, many OSes will be able to avoid - * installing their own GDT. - */ -#define FLAT_RING1_CS 0xe019 /* GDT index 259 */ -#define FLAT_RING1_DS 0xe021 /* GDT index 260 */ -#define FLAT_RING1_SS 0xe021 /* GDT index 260 */ -#define FLAT_RING3_CS 0xe02b /* GDT index 261 */ -#define FLAT_RING3_DS 0xe033 /* GDT index 262 */ -#define FLAT_RING3_SS 0xe033 /* GDT index 262 */ - -#define FLAT_KERNEL_CS FLAT_RING1_CS -#define FLAT_KERNEL_DS FLAT_RING1_DS -#define FLAT_KERNEL_SS FLAT_RING1_SS -#define FLAT_USER_CS FLAT_RING3_CS -#define FLAT_USER_DS FLAT_RING3_DS -#define FLAT_USER_SS FLAT_RING3_SS - -#define __HYPERVISOR_VIRT_START_PAE 0xF5800000 -#define __MACH2PHYS_VIRT_START_PAE 0xF5800000 -#define __MACH2PHYS_VIRT_END_PAE 0xF6800000 -#define HYPERVISOR_VIRT_START_PAE xen_mk_ulong(__HYPERVISOR_VIRT_START_PAE) -#define MACH2PHYS_VIRT_START_PAE xen_mk_ulong(__MACH2PHYS_VIRT_START_PAE) -#define MACH2PHYS_VIRT_END_PAE xen_mk_ulong(__MACH2PHYS_VIRT_END_PAE) - -/* Non-PAE bounds are obsolete. */ -#define __HYPERVISOR_VIRT_START_NONPAE 0xFC000000 -#define __MACH2PHYS_VIRT_START_NONPAE 0xFC000000 -#define __MACH2PHYS_VIRT_END_NONPAE 0xFC400000 -#define HYPERVISOR_VIRT_START_NONPAE \ - xen_mk_ulong(__HYPERVISOR_VIRT_START_NONPAE) -#define MACH2PHYS_VIRT_START_NONPAE \ - xen_mk_ulong(__MACH2PHYS_VIRT_START_NONPAE) -#define MACH2PHYS_VIRT_END_NONPAE \ - xen_mk_ulong(__MACH2PHYS_VIRT_END_NONPAE) - -#define __HYPERVISOR_VIRT_START __HYPERVISOR_VIRT_START_PAE -#define __MACH2PHYS_VIRT_START __MACH2PHYS_VIRT_START_PAE -#define __MACH2PHYS_VIRT_END __MACH2PHYS_VIRT_END_PAE - -#ifndef HYPERVISOR_VIRT_START -#define HYPERVISOR_VIRT_START xen_mk_ulong(__HYPERVISOR_VIRT_START) -#endif - -#define MACH2PHYS_VIRT_START xen_mk_ulong(__MACH2PHYS_VIRT_START) -#define MACH2PHYS_VIRT_END xen_mk_ulong(__MACH2PHYS_VIRT_END) -#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>2) -#ifndef machine_to_phys_mapping -#define machine_to_phys_mapping ((unsigned long *)MACH2PHYS_VIRT_START) -#endif - -/* 32-/64-bit invariability for control interfaces (domctl/sysctl). */ -#if defined(__XEN__) || defined(__XEN_TOOLS__) -#undef ___DEFINE_XEN_GUEST_HANDLE -#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ - typedef struct { type *p; } \ - __guest_handle_ ## name; \ - typedef struct { union { type *p; uint64_aligned_t q; }; } \ - __guest_handle_64_ ## name -#undef set_xen_guest_handle_raw -#define set_xen_guest_handle_raw(hnd, val) \ - do { if ( sizeof(hnd) == 8 ) *(uint64_t *)&(hnd) = 0; \ - (hnd).p = val; \ - } while ( 0 ) -#define int64_aligned_t int64_t __attribute__((aligned(8))) -#define uint64_aligned_t uint64_t __attribute__((aligned(8))) -#define __XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name -#define XEN_GUEST_HANDLE_64(name) __XEN_GUEST_HANDLE_64(name) -#endif - -#ifndef __ASSEMBLY__ - -struct cpu_user_regs { - uint32_t ebx; - uint32_t ecx; - uint32_t edx; - uint32_t esi; - uint32_t edi; - uint32_t ebp; - uint32_t eax; - uint16_t error_code; /* private */ - uint16_t entry_vector; /* private */ - uint32_t eip; - uint16_t cs; - uint8_t saved_upcall_mask; - uint8_t _pad0; - uint32_t eflags; /* eflags.IF == !saved_upcall_mask */ - uint32_t esp; - uint16_t ss, _pad1; - uint16_t es, _pad2; - uint16_t ds, _pad3; - uint16_t fs, _pad4; - uint16_t gs, _pad5; -}; -typedef struct cpu_user_regs cpu_user_regs_t; -DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t); - -/* - * Page-directory addresses above 4GB do not fit into architectural %cr3. - * When accessing %cr3, or equivalent field in vcpu_guest_context, guests - * must use the following accessor macros to pack/unpack valid MFNs. - */ -#define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20)) -#define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20)) - -struct arch_vcpu_info { - unsigned long cr2; - unsigned long pad[5]; /* sizeof(vcpu_info_t) == 64 */ -}; -typedef struct arch_vcpu_info arch_vcpu_info_t; - -struct xen_callback { - unsigned long cs; - unsigned long eip; -}; -typedef struct xen_callback xen_callback_t; - -#endif /* !__ASSEMBLY__ */ - -#endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_32_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/arch-x86/xen-x86_64.h b/include/xen/arch-x86/xen-x86_64.h deleted file mode 100644 index 17b438406..000000000 --- a/include/xen/arch-x86/xen-x86_64.h +++ /dev/null @@ -1,202 +0,0 @@ -/****************************************************************************** - * xen-x86_64.h - * - * Guest OS interface to x86 64-bit Xen. - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2004-2006, K A Fraser - */ - -#ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__ -#define __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__ - -/* - * Hypercall interface: - * Input: %rdi, %rsi, %rdx, %r10, %r8, %r9 (arguments 1-6) - * Output: %rax - * Access is via hypercall page (set up by guest loader or via a Xen MSR): - * call hypercall_page + hypercall-number * 32 - * Clobbered: argument registers (e.g., 2-arg hypercall clobbers %rdi,%rsi) - */ - -/* - * 64-bit segment selectors - * These flat segments are in the Xen-private section of every GDT. Since these - * are also present in the initial GDT, many OSes will be able to avoid - * installing their own GDT. - */ - -#define FLAT_RING3_CS32 0xe023 /* GDT index 260 */ -#define FLAT_RING3_CS64 0xe033 /* GDT index 261 */ -#define FLAT_RING3_DS32 0xe02b /* GDT index 262 */ -#define FLAT_RING3_DS64 0x0000 /* NULL selector */ -#define FLAT_RING3_SS32 0xe02b /* GDT index 262 */ -#define FLAT_RING3_SS64 0xe02b /* GDT index 262 */ - -#define FLAT_KERNEL_DS64 FLAT_RING3_DS64 -#define FLAT_KERNEL_DS32 FLAT_RING3_DS32 -#define FLAT_KERNEL_DS FLAT_KERNEL_DS64 -#define FLAT_KERNEL_CS64 FLAT_RING3_CS64 -#define FLAT_KERNEL_CS32 FLAT_RING3_CS32 -#define FLAT_KERNEL_CS FLAT_KERNEL_CS64 -#define FLAT_KERNEL_SS64 FLAT_RING3_SS64 -#define FLAT_KERNEL_SS32 FLAT_RING3_SS32 -#define FLAT_KERNEL_SS FLAT_KERNEL_SS64 - -#define FLAT_USER_DS64 FLAT_RING3_DS64 -#define FLAT_USER_DS32 FLAT_RING3_DS32 -#define FLAT_USER_DS FLAT_USER_DS64 -#define FLAT_USER_CS64 FLAT_RING3_CS64 -#define FLAT_USER_CS32 FLAT_RING3_CS32 -#define FLAT_USER_CS FLAT_USER_CS64 -#define FLAT_USER_SS64 FLAT_RING3_SS64 -#define FLAT_USER_SS32 FLAT_RING3_SS32 -#define FLAT_USER_SS FLAT_USER_SS64 - -#define __HYPERVISOR_VIRT_START 0xFFFF800000000000 -#define __HYPERVISOR_VIRT_END 0xFFFF880000000000 -#define __MACH2PHYS_VIRT_START 0xFFFF800000000000 -#define __MACH2PHYS_VIRT_END 0xFFFF804000000000 - -#ifndef HYPERVISOR_VIRT_START -#define HYPERVISOR_VIRT_START xen_mk_ulong(__HYPERVISOR_VIRT_START) -#define HYPERVISOR_VIRT_END xen_mk_ulong(__HYPERVISOR_VIRT_END) -#endif - -#define MACH2PHYS_VIRT_START xen_mk_ulong(__MACH2PHYS_VIRT_START) -#define MACH2PHYS_VIRT_END xen_mk_ulong(__MACH2PHYS_VIRT_END) -#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>3) -#ifndef machine_to_phys_mapping -#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START) -#endif - -/* - * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base) - * @which == SEGBASE_* ; @base == 64-bit base address - * Returns 0 on success. - */ -#define SEGBASE_FS 0 -#define SEGBASE_GS_USER 1 -#define SEGBASE_GS_KERNEL 2 -#define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */ - -/* - * int HYPERVISOR_iret(void) - * All arguments are on the kernel stack, in the following format. - * Never returns if successful. Current kernel context is lost. - * The saved CS is mapped as follows: - * RING0 -> RING3 kernel mode. - * RING1 -> RING3 kernel mode. - * RING2 -> RING3 kernel mode. - * RING3 -> RING3 user mode. - * However RING0 indicates that the guest kernel should return to iteself - * directly with - * orb $3,1*8(%rsp) - * iretq - * If flags contains VGCF_in_syscall: - * Restore RAX, RIP, RFLAGS, RSP. - * Discard R11, RCX, CS, SS. - * Otherwise: - * Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP. - * All other registers are saved on hypercall entry and restored to user. - */ -/* Guest exited in SYSCALL context? Return to guest with SYSRET? */ -#define _VGCF_in_syscall 8 -#define VGCF_in_syscall (1<<_VGCF_in_syscall) -#define VGCF_IN_SYSCALL VGCF_in_syscall - -#ifndef __ASSEMBLY__ - -struct iret_context { - /* Top of stack (%rsp at point of hypercall). */ - uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss; - /* Bottom of iret stack frame. */ -}; - -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) -/* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */ -#define __DECL_REG(name) union { \ - uint64_t r ## name, e ## name; \ - uint32_t _e ## name; \ -} -#else -/* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */ -#define __DECL_REG(name) uint64_t r ## name -#endif - -struct cpu_user_regs { - uint64_t r15; - uint64_t r14; - uint64_t r13; - uint64_t r12; - __DECL_REG(bp); - __DECL_REG(bx); - uint64_t r11; - uint64_t r10; - uint64_t r9; - uint64_t r8; - __DECL_REG(ax); - __DECL_REG(cx); - __DECL_REG(dx); - __DECL_REG(si); - __DECL_REG(di); - uint32_t error_code; /* private */ - uint32_t entry_vector; /* private */ - __DECL_REG(ip); - uint16_t cs, _pad0[1]; - uint8_t saved_upcall_mask; - uint8_t _pad1[3]; - __DECL_REG(flags); /* rflags.IF == !saved_upcall_mask */ - __DECL_REG(sp); - uint16_t ss, _pad2[3]; - uint16_t es, _pad3[3]; - uint16_t ds, _pad4[3]; - uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base. */ - uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */ -}; -typedef struct cpu_user_regs cpu_user_regs_t; -DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t); - -#undef __DECL_REG - -#define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12) -#define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12) - -struct arch_vcpu_info { - unsigned long cr2; - unsigned long pad; /* sizeof(vcpu_info_t) == 64 */ -}; -typedef struct arch_vcpu_info arch_vcpu_info_t; - -typedef unsigned long xen_callback_t; - -#endif /* !__ASSEMBLY__ */ - -#endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/arch-x86/xen.h b/include/xen/arch-x86/xen.h deleted file mode 100644 index 2ca71fcdd..000000000 --- a/include/xen/arch-x86/xen.h +++ /dev/null @@ -1,280 +0,0 @@ -/****************************************************************************** - * arch-x86/xen.h - * - * Guest OS interface to x86 Xen. - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2004-2006, K A Fraser - */ - -#include "../xen.h" - -#ifndef __XEN_PUBLIC_ARCH_X86_XEN_H__ -#define __XEN_PUBLIC_ARCH_X86_XEN_H__ - -/* Structural guest handles introduced in 0x00030201. */ -#if __XEN_INTERFACE_VERSION__ >= 0x00030201 -#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ - typedef struct { type *p; } __guest_handle_ ## name -#else -#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ - typedef type * __guest_handle_ ## name -#endif - -/* - * XEN_GUEST_HANDLE represents a guest pointer, when passed as a field - * in a struct in memory. - * XEN_GUEST_HANDLE_PARAM represent a guest pointer, when passed as an - * hypercall argument. - * XEN_GUEST_HANDLE_PARAM and XEN_GUEST_HANDLE are the same on X86 but - * they might not be on other architectures. - */ -#define __DEFINE_XEN_GUEST_HANDLE(name, type) \ - ___DEFINE_XEN_GUEST_HANDLE(name, type); \ - ___DEFINE_XEN_GUEST_HANDLE(const_##name, const type) -#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name) -#define __XEN_GUEST_HANDLE(name) __guest_handle_ ## name -#define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name) -#define XEN_GUEST_HANDLE_PARAM(name) XEN_GUEST_HANDLE(name) -#define set_xen_guest_handle_raw(hnd, val) do { (hnd).p = val; } while (0) -#ifdef __XEN_TOOLS__ -#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0) -#endif -#define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val) - -#if defined(__i386__) -#include "xen-x86_32.h" -#elif defined(__x86_64__) -#include "xen-x86_64.h" -#endif - -#ifndef __ASSEMBLY__ -typedef unsigned long xen_pfn_t; -#define PRI_xen_pfn "lx" -#endif - -#define XEN_HAVE_PV_GUEST_ENTRY 1 - -#define XEN_HAVE_PV_UPCALL_MASK 1 - -/* - * `incontents 200 segdesc Segment Descriptor Tables - */ -/* - * ` enum neg_errnoval - * ` HYPERVISOR_set_gdt(const xen_pfn_t frames[], unsigned int entries); - * ` - */ -/* - * A number of GDT entries are reserved by Xen. These are not situated at the - * start of the GDT because some stupid OSes export hard-coded selector values - * in their ABI. These hard-coded values are always near the start of the GDT, - * so Xen places itself out of the way, at the far end of the GDT. - * - * NB The LDT is set using the MMUEXT_SET_LDT op of HYPERVISOR_mmuext_op - */ -#define FIRST_RESERVED_GDT_PAGE 14 -#define FIRST_RESERVED_GDT_BYTE (FIRST_RESERVED_GDT_PAGE * 4096) -#define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8) - - -/* - * ` enum neg_errnoval - * ` HYPERVISOR_update_descriptor(u64 pa, u64 desc); - * ` - * ` @pa The machine physical address of the descriptor to - * ` update. Must be either a descriptor page or writable. - * ` @desc The descriptor value to update, in the same format as a - * ` native descriptor table entry. - */ - -/* Maximum number of virtual CPUs in legacy multi-processor guests. */ -#define XEN_LEGACY_MAX_VCPUS 32 - -#ifndef __ASSEMBLY__ - -typedef unsigned long xen_ulong_t; -#define PRI_xen_ulong "lx" - -/* - * ` enum neg_errnoval - * ` HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp); - * ` - * Sets the stack segment and pointer for the current vcpu. - */ - -/* - * ` enum neg_errnoval - * ` HYPERVISOR_set_trap_table(const struct trap_info traps[]); - * ` - */ -/* - * Send an array of these to HYPERVISOR_set_trap_table(). - * Terminate the array with a sentinel entry, with traps[].address==0. - * The privilege level specifies which modes may enter a trap via a software - * interrupt. On x86/64, since rings 1 and 2 are unavailable, we allocate - * privilege levels as follows: - * Level == 0: Noone may enter - * Level == 1: Kernel may enter - * Level == 2: Kernel may enter - * Level == 3: Everyone may enter - */ -#define TI_GET_DPL(_ti) ((_ti)->flags & 3) -#define TI_GET_IF(_ti) ((_ti)->flags & 4) -#define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl)) -#define TI_SET_IF(_ti,_if) ((_ti)->flags |= ((!!(_if))<<2)) -struct trap_info { - uint8_t vector; /* exception vector */ - uint8_t flags; /* 0-3: privilege level; 4: clear event enable? */ - uint16_t cs; /* code selector */ - unsigned long address; /* code offset */ -}; -typedef struct trap_info trap_info_t; -DEFINE_XEN_GUEST_HANDLE(trap_info_t); - -typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */ - -/* - * The following is all CPU context. Note that the fpu_ctxt block is filled - * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used. - * - * Also note that when calling DOMCTL_setvcpucontext and VCPU_initialise - * for HVM and PVH guests, not all information in this structure is updated: - * - * - For HVM guests, the structures read include: fpu_ctxt (if - * VGCT_I387_VALID is set), flags, user_regs, debugreg[*] - * - * - PVH guests are the same as HVM guests, but additionally use ctrlreg[3] to - * set cr3. All other fields not used should be set to 0. - */ -struct vcpu_guest_context { - /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */ - struct { char x[512]; } fpu_ctxt; /* User-level FPU registers */ -#define VGCF_I387_VALID (1<<0) -#define VGCF_IN_KERNEL (1<<2) -#define _VGCF_i387_valid 0 -#define VGCF_i387_valid (1<<_VGCF_i387_valid) -#define _VGCF_in_kernel 2 -#define VGCF_in_kernel (1<<_VGCF_in_kernel) -#define _VGCF_failsafe_disables_events 3 -#define VGCF_failsafe_disables_events (1<<_VGCF_failsafe_disables_events) -#define _VGCF_syscall_disables_events 4 -#define VGCF_syscall_disables_events (1<<_VGCF_syscall_disables_events) -#define _VGCF_online 5 -#define VGCF_online (1<<_VGCF_online) - unsigned long flags; /* VGCF_* flags */ - struct cpu_user_regs user_regs; /* User-level CPU registers */ - struct trap_info trap_ctxt[256]; /* Virtual IDT */ - unsigned long ldt_base, ldt_ents; /* LDT (linear address, # ents) */ - unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */ - unsigned long kernel_ss, kernel_sp; /* Virtual TSS (only SS1/SP1) */ - /* NB. User pagetable on x86/64 is placed in ctrlreg[1]. */ - unsigned long ctrlreg[8]; /* CR0-CR7 (control registers) */ - unsigned long debugreg[8]; /* DB0-DB7 (debug registers) */ -#ifdef __i386__ - unsigned long event_callback_cs; /* CS:EIP of event callback */ - unsigned long event_callback_eip; - unsigned long failsafe_callback_cs; /* CS:EIP of failsafe callback */ - unsigned long failsafe_callback_eip; -#else - unsigned long event_callback_eip; - unsigned long failsafe_callback_eip; -#ifdef __XEN__ - union { - unsigned long syscall_callback_eip; - struct { - unsigned int event_callback_cs; /* compat CS of event cb */ - unsigned int failsafe_callback_cs; /* compat CS of failsafe cb */ - }; - }; -#else - unsigned long syscall_callback_eip; -#endif -#endif - unsigned long vm_assist; /* VMASST_TYPE_* bitmap */ -#ifdef __x86_64__ - /* Segment base addresses. */ - uint64_t fs_base; - uint64_t gs_base_kernel; - uint64_t gs_base_user; -#endif -}; -typedef struct vcpu_guest_context vcpu_guest_context_t; -DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t); - -struct arch_shared_info { - unsigned long max_pfn; /* max pfn that appears in table */ - /* Frame containing list of mfns containing list of mfns containing p2m. */ - xen_pfn_t pfn_to_mfn_frame_list_list; - unsigned long nmi_reason; - uint64_t pad[32]; -}; -typedef struct arch_shared_info arch_shared_info_t; - -#endif /* !__ASSEMBLY__ */ - -/* - * ` enum neg_errnoval - * ` HYPERVISOR_fpu_taskswitch(int set); - * ` - * Sets (if set!=0) or clears (if set==0) CR0.TS. - */ - -/* - * ` enum neg_errnoval - * ` HYPERVISOR_set_debugreg(int regno, unsigned long value); - * - * ` unsigned long - * ` HYPERVISOR_get_debugreg(int regno); - * For 0<=reg<=7, returns the debug register value. - * For other values of reg, returns ((unsigned long)-EINVAL). - * (Unfortunately, this interface is defective.) - */ - -/* - * Prefix forces emulation of some non-trapping instructions. - * Currently only CPUID. - */ -#ifdef __ASSEMBLY__ -#define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ; -#define XEN_CPUID XEN_EMULATE_PREFIX cpuid -#else -#define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; " -#define XEN_CPUID XEN_EMULATE_PREFIX "cpuid" -#endif - -/* - * Debug console IO port, also called "port E9 hack". Each character written - * to this IO port will be printed on the hypervisor console, subject to log - * level restrictions. - */ -#define XEN_HVM_DEBUGCONS_IOPORT 0xe9 - -#endif /* __XEN_PUBLIC_ARCH_X86_XEN_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/elfnote.h b/include/xen/elfnote.h deleted file mode 100644 index 71cd4ec52..000000000 --- a/include/xen/elfnote.h +++ /dev/null @@ -1,281 +0,0 @@ -/****************************************************************************** - * elfnote.h - * - * Definitions used for the Xen ELF notes. - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2006, Ian Campbell, XenSource Ltd. - */ - -#ifndef __XEN_PUBLIC_ELFNOTE_H__ -#define __XEN_PUBLIC_ELFNOTE_H__ - -/* - * `incontents 200 elfnotes ELF notes - * - * The notes should live in a PT_NOTE segment and have "Xen" in the - * name field. - * - * Numeric types are either 4 or 8 bytes depending on the content of - * the desc field. - * - * LEGACY indicated the fields in the legacy __xen_guest string which - * this a note type replaces. - * - * String values (for non-legacy) are NULL terminated ASCII, also known - * as ASCIZ type. - */ - -/* - * NAME=VALUE pair (string). - */ -#define XEN_ELFNOTE_INFO 0 - -/* - * The virtual address of the entry point (numeric). - * - * LEGACY: VIRT_ENTRY - */ -#define XEN_ELFNOTE_ENTRY 1 - -/* The virtual address of the hypercall transfer page (numeric). - * - * LEGACY: HYPERCALL_PAGE. (n.b. legacy value is a physical page - * number not a virtual address) - */ -#define XEN_ELFNOTE_HYPERCALL_PAGE 2 - -/* The virtual address where the kernel image should be mapped (numeric). - * - * Defaults to 0. - * - * LEGACY: VIRT_BASE - */ -#define XEN_ELFNOTE_VIRT_BASE 3 - -/* - * The offset of the ELF paddr field from the actual required - * pseudo-physical address (numeric). - * - * This is used to maintain backwards compatibility with older kernels - * which wrote __PAGE_OFFSET into that field. This field defaults to 0 - * if not present. - * - * LEGACY: ELF_PADDR_OFFSET. (n.b. legacy default is VIRT_BASE) - */ -#define XEN_ELFNOTE_PADDR_OFFSET 4 - -/* - * The version of Xen that we work with (string). - * - * LEGACY: XEN_VER - */ -#define XEN_ELFNOTE_XEN_VERSION 5 - -/* - * The name of the guest operating system (string). - * - * LEGACY: GUEST_OS - */ -#define XEN_ELFNOTE_GUEST_OS 6 - -/* - * The version of the guest operating system (string). - * - * LEGACY: GUEST_VER - */ -#define XEN_ELFNOTE_GUEST_VERSION 7 - -/* - * The loader type (string). - * - * LEGACY: LOADER - */ -#define XEN_ELFNOTE_LOADER 8 - -/* - * The kernel supports PAE (x86/32 only, string = "yes", "no" or - * "bimodal"). - * - * For compatibility with Xen 3.0.3 and earlier the "bimodal" setting - * may be given as "yes,bimodal" which will cause older Xen to treat - * this kernel as PAE. - * - * LEGACY: PAE (n.b. The legacy interface included a provision to - * indicate 'extended-cr3' support allowing L3 page tables to be - * placed above 4G. It is assumed that any kernel new enough to use - * these ELF notes will include this and therefore "yes" here is - * equivalent to "yes[entended-cr3]" in the __xen_guest interface. - */ -#define XEN_ELFNOTE_PAE_MODE 9 - -/* - * The features supported/required by this kernel (string). - * - * The string must consist of a list of feature names (as given in - * features.h, without the "XENFEAT_" prefix) separated by '|' - * characters. If a feature is required for the kernel to function - * then the feature name must be preceded by a '!' character. - * - * LEGACY: FEATURES - */ -#define XEN_ELFNOTE_FEATURES 10 - -/* - * The kernel requires the symbol table to be loaded (string = "yes" or "no") - * LEGACY: BSD_SYMTAB (n.b. The legacy treated the presence or absence - * of this string as a boolean flag rather than requiring "yes" or - * "no". - */ -#define XEN_ELFNOTE_BSD_SYMTAB 11 - -/* - * The lowest address the hypervisor hole can begin at (numeric). - * - * This must not be set higher than HYPERVISOR_VIRT_START. Its presence - * also indicates to the hypervisor that the kernel can deal with the - * hole starting at a higher address. - */ -#define XEN_ELFNOTE_HV_START_LOW 12 - -/* - * List of maddr_t-sized mask/value pairs describing how to recognize - * (non-present) L1 page table entries carrying valid MFNs (numeric). - */ -#define XEN_ELFNOTE_L1_MFN_VALID 13 - -/* - * Whether or not the guest supports cooperative suspend cancellation. - * This is a numeric value. - * - * Default is 0 - */ -#define XEN_ELFNOTE_SUSPEND_CANCEL 14 - -/* - * The (non-default) location the initial phys-to-machine map should be - * placed at by the hypervisor (Dom0) or the tools (DomU). - * The kernel must be prepared for this mapping to be established using - * large pages, despite such otherwise not being available to guests. - * The kernel must also be able to handle the page table pages used for - * this mapping not being accessible through the initial mapping. - * (Only x86-64 supports this at present.) - */ -#define XEN_ELFNOTE_INIT_P2M 15 - -/* - * Whether or not the guest can deal with being passed an initrd not - * mapped through its initial page tables. - */ -#define XEN_ELFNOTE_MOD_START_PFN 16 - -/* - * The features supported by this kernel (numeric). - * - * Other than XEN_ELFNOTE_FEATURES on pre-4.2 Xen, this note allows a - * kernel to specify support for features that older hypervisors don't - * know about. The set of features 4.2 and newer hypervisors will - * consider supported by the kernel is the combination of the sets - * specified through this and the string note. - * - * LEGACY: FEATURES - */ -#define XEN_ELFNOTE_SUPPORTED_FEATURES 17 - -/* - * Physical entry point into the kernel. - * - * 32bit entry point into the kernel. When requested to launch the - * guest kernel in a HVM container, Xen will use this entry point to - * launch the guest in 32bit protected mode with paging disabled. - * Ignored otherwise. - */ -#define XEN_ELFNOTE_PHYS32_ENTRY 18 - -/* - * The number of the highest elfnote defined. - */ -#define XEN_ELFNOTE_MAX XEN_ELFNOTE_PHYS32_ENTRY - -/* - * System information exported through crash notes. - * - * The kexec / kdump code will create one XEN_ELFNOTE_CRASH_INFO - * note in case of a system crash. This note will contain various - * information about the system, see xen/include/xen/elfcore.h. - */ -#define XEN_ELFNOTE_CRASH_INFO 0x1000001 - -/* - * System registers exported through crash notes. - * - * The kexec / kdump code will create one XEN_ELFNOTE_CRASH_REGS - * note per cpu in case of a system crash. This note is architecture - * specific and will contain registers not saved in the "CORE" note. - * See xen/include/xen/elfcore.h for more information. - */ -#define XEN_ELFNOTE_CRASH_REGS 0x1000002 - - -/* - * xen dump-core none note. - * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_NONE - * in its dump file to indicate that the file is xen dump-core - * file. This note doesn't have any other information. - * See tools/libxc/xc_core.h for more information. - */ -#define XEN_ELFNOTE_DUMPCORE_NONE 0x2000000 - -/* - * xen dump-core header note. - * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_HEADER - * in its dump file. - * See tools/libxc/xc_core.h for more information. - */ -#define XEN_ELFNOTE_DUMPCORE_HEADER 0x2000001 - -/* - * xen dump-core xen version note. - * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_XEN_VERSION - * in its dump file. It contains the xen version obtained via the - * XENVER hypercall. - * See tools/libxc/xc_core.h for more information. - */ -#define XEN_ELFNOTE_DUMPCORE_XEN_VERSION 0x2000002 - -/* - * xen dump-core format version note. - * xm dump-core code will create one XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION - * in its dump file. It contains a format version identifier. - * See tools/libxc/xc_core.h for more information. - */ -#define XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION 0x2000003 - -#endif /* __XEN_PUBLIC_ELFNOTE_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/event_channel.h b/include/xen/event_channel.h deleted file mode 100644 index 49ac8cca5..000000000 --- a/include/xen/event_channel.h +++ /dev/null @@ -1,381 +0,0 @@ -/****************************************************************************** - * event_channel.h - * - * Event channels between domains. - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2003-2004, K A Fraser. - */ - -#ifndef __XEN_PUBLIC_EVENT_CHANNEL_H__ -#define __XEN_PUBLIC_EVENT_CHANNEL_H__ - -#include "xen.h" - -/* - * `incontents 150 evtchn Event Channels - * - * Event channels are the basic primitive provided by Xen for event - * notifications. An event is the Xen equivalent of a hardware - * interrupt. They essentially store one bit of information, the event - * of interest is signalled by transitioning this bit from 0 to 1. - * - * Notifications are received by a guest via an upcall from Xen, - * indicating when an event arrives (setting the bit). Further - * notifications are masked until the bit is cleared again (therefore, - * guests must check the value of the bit after re-enabling event - * delivery to ensure no missed notifications). - * - * Event notifications can be masked by setting a flag; this is - * equivalent to disabling interrupts and can be used to ensure - * atomicity of certain operations in the guest kernel. - * - * Event channels are represented by the evtchn_* fields in - * struct shared_info and struct vcpu_info. - */ - -/* - * ` enum neg_errnoval - * ` HYPERVISOR_event_channel_op(enum event_channel_op cmd, void *args) - * ` - * @cmd == EVTCHNOP_* (event-channel operation). - * @args == struct evtchn_* Operation-specific extra arguments (NULL if none). - */ - -/* ` enum event_channel_op { // EVTCHNOP_* => struct evtchn_* */ -#define EVTCHNOP_bind_interdomain 0 -#define EVTCHNOP_bind_virq 1 -#define EVTCHNOP_bind_pirq 2 -#define EVTCHNOP_close 3 -#define EVTCHNOP_send 4 -#define EVTCHNOP_status 5 -#define EVTCHNOP_alloc_unbound 6 -#define EVTCHNOP_bind_ipi 7 -#define EVTCHNOP_bind_vcpu 8 -#define EVTCHNOP_unmask 9 -#define EVTCHNOP_reset 10 -#define EVTCHNOP_init_control 11 -#define EVTCHNOP_expand_array 12 -#define EVTCHNOP_set_priority 13 -/* ` } */ - -typedef uint32_t evtchn_port_t; -DEFINE_XEN_GUEST_HANDLE(evtchn_port_t); - -/* - * EVTCHNOP_alloc_unbound: Allocate a port in domain and mark as - * accepting interdomain bindings from domain . A fresh port - * is allocated in and returned as . - * NOTES: - * 1. If the caller is unprivileged then must be DOMID_SELF. - * 2. may be DOMID_SELF, allowing loopback connections. - */ -struct evtchn_alloc_unbound { - /* IN parameters */ - domid_t dom, remote_dom; - /* OUT parameters */ - evtchn_port_t port; -}; -typedef struct evtchn_alloc_unbound evtchn_alloc_unbound_t; - -/* - * EVTCHNOP_bind_interdomain: Construct an interdomain event channel between - * the calling domain and . must identify - * a port that is unbound and marked as accepting bindings from the calling - * domain. A fresh port is allocated in the calling domain and returned as - * . - * - * In case the peer domain has already tried to set our event channel - * pending, before it was bound, EVTCHNOP_bind_interdomain always sets - * the local event channel pending. - * - * The usual pattern of use, in the guest's upcall (or subsequent - * handler) is as follows: (Re-enable the event channel for subsequent - * signalling and then) check for the existence of whatever condition - * is being waited for by other means, and take whatever action is - * needed (if any). - * - * NOTES: - * 1. may be DOMID_SELF, allowing loopback connections. - */ -struct evtchn_bind_interdomain { - /* IN parameters. */ - domid_t remote_dom; - evtchn_port_t remote_port; - /* OUT parameters. */ - evtchn_port_t local_port; -}; -typedef struct evtchn_bind_interdomain evtchn_bind_interdomain_t; - -/* - * EVTCHNOP_bind_virq: Bind a local event channel to VIRQ on specified - * vcpu. - * NOTES: - * 1. Virtual IRQs are classified as per-vcpu or global. See the VIRQ list - * in xen.h for the classification of each VIRQ. - * 2. Global VIRQs must be allocated on VCPU0 but can subsequently be - * re-bound via EVTCHNOP_bind_vcpu. - * 3. Per-vcpu VIRQs may be bound to at most one event channel per vcpu. - * The allocated event channel is bound to the specified vcpu and the - * binding cannot be changed. - */ -struct evtchn_bind_virq { - /* IN parameters. */ - uint32_t virq; /* enum virq */ - uint32_t vcpu; - /* OUT parameters. */ - evtchn_port_t port; -}; -typedef struct evtchn_bind_virq evtchn_bind_virq_t; - -/* - * EVTCHNOP_bind_pirq: Bind a local event channel to a real IRQ (PIRQ ). - * NOTES: - * 1. A physical IRQ may be bound to at most one event channel per domain. - * 2. Only a sufficiently-privileged domain may bind to a physical IRQ. - */ -struct evtchn_bind_pirq { - /* IN parameters. */ - uint32_t pirq; -#define BIND_PIRQ__WILL_SHARE 1 - uint32_t flags; /* BIND_PIRQ__* */ - /* OUT parameters. */ - evtchn_port_t port; -}; -typedef struct evtchn_bind_pirq evtchn_bind_pirq_t; - -/* - * EVTCHNOP_bind_ipi: Bind a local event channel to receive events. - * NOTES: - * 1. The allocated event channel is bound to the specified vcpu. The binding - * may not be changed. - */ -struct evtchn_bind_ipi { - uint32_t vcpu; - /* OUT parameters. */ - evtchn_port_t port; -}; -typedef struct evtchn_bind_ipi evtchn_bind_ipi_t; - -/* - * EVTCHNOP_close: Close a local event channel . If the channel is - * interdomain then the remote end is placed in the unbound state - * (EVTCHNSTAT_unbound), awaiting a new connection. - */ -struct evtchn_close { - /* IN parameters. */ - evtchn_port_t port; -}; -typedef struct evtchn_close evtchn_close_t; - -/* - * EVTCHNOP_send: Send an event to the remote end of the channel whose local - * endpoint is . - */ -struct evtchn_send { - /* IN parameters. */ - evtchn_port_t port; -}; -typedef struct evtchn_send evtchn_send_t; - -/* - * EVTCHNOP_status: Get the current status of the communication channel which - * has an endpoint at . - * NOTES: - * 1. may be specified as DOMID_SELF. - * 2. Only a sufficiently-privileged domain may obtain the status of an event - * channel for which is not DOMID_SELF. - */ -struct evtchn_status { - /* IN parameters */ - domid_t dom; - evtchn_port_t port; - /* OUT parameters */ -#define EVTCHNSTAT_closed 0 /* Channel is not in use. */ -#define EVTCHNSTAT_unbound 1 /* Channel is waiting interdom connection.*/ -#define EVTCHNSTAT_interdomain 2 /* Channel is connected to remote domain. */ -#define EVTCHNSTAT_pirq 3 /* Channel is bound to a phys IRQ line. */ -#define EVTCHNSTAT_virq 4 /* Channel is bound to a virtual IRQ line */ -#define EVTCHNSTAT_ipi 5 /* Channel is bound to a virtual IPI line */ - uint32_t status; - uint32_t vcpu; /* VCPU to which this channel is bound. */ - union { - struct { - domid_t dom; - } unbound; /* EVTCHNSTAT_unbound */ - struct { - domid_t dom; - evtchn_port_t port; - } interdomain; /* EVTCHNSTAT_interdomain */ - uint32_t pirq; /* EVTCHNSTAT_pirq */ - uint32_t virq; /* EVTCHNSTAT_virq */ - } u; -}; -typedef struct evtchn_status evtchn_status_t; - -/* - * EVTCHNOP_bind_vcpu: Specify which vcpu a channel should notify when an - * event is pending. - * NOTES: - * 1. IPI-bound channels always notify the vcpu specified at bind time. - * This binding cannot be changed. - * 2. Per-VCPU VIRQ channels always notify the vcpu specified at bind time. - * This binding cannot be changed. - * 3. All other channels notify vcpu0 by default. This default is set when - * the channel is allocated (a port that is freed and subsequently reused - * has its binding reset to vcpu0). - */ -struct evtchn_bind_vcpu { - /* IN parameters. */ - evtchn_port_t port; - uint32_t vcpu; -}; -typedef struct evtchn_bind_vcpu evtchn_bind_vcpu_t; - -/* - * EVTCHNOP_unmask: Unmask the specified local event-channel port and deliver - * a notification to the appropriate VCPU if an event is pending. - */ -struct evtchn_unmask { - /* IN parameters. */ - evtchn_port_t port; -}; -typedef struct evtchn_unmask evtchn_unmask_t; - -/* - * EVTCHNOP_reset: Close all event channels associated with specified domain. - * NOTES: - * 1. may be specified as DOMID_SELF. - * 2. Only a sufficiently-privileged domain may specify other than DOMID_SELF. - */ -struct evtchn_reset { - /* IN parameters. */ - domid_t dom; -}; -typedef struct evtchn_reset evtchn_reset_t; - -/* - * EVTCHNOP_init_control: initialize the control block for the FIFO ABI. - * - * Note: any events that are currently pending will not be resent and - * will be lost. Guests should call this before binding any event to - * avoid losing any events. - */ -struct evtchn_init_control { - /* IN parameters. */ - uint64_t control_gfn; - uint32_t offset; - uint32_t vcpu; - /* OUT parameters. */ - uint8_t link_bits; - uint8_t _pad[7]; -}; -typedef struct evtchn_init_control evtchn_init_control_t; - -/* - * EVTCHNOP_expand_array: add an additional page to the event array. - */ -struct evtchn_expand_array { - /* IN parameters. */ - uint64_t array_gfn; -}; -typedef struct evtchn_expand_array evtchn_expand_array_t; - -/* - * EVTCHNOP_set_priority: set the priority for an event channel. - */ -struct evtchn_set_priority { - /* IN parameters. */ - uint32_t port; - uint32_t priority; -}; -typedef struct evtchn_set_priority evtchn_set_priority_t; - -/* - * ` enum neg_errnoval - * ` HYPERVISOR_event_channel_op_compat(struct evtchn_op *op) - * ` - * Superceded by new event_channel_op() hypercall since 0x00030202. - */ -struct evtchn_op { - uint32_t cmd; /* enum event_channel_op */ - union { - struct evtchn_alloc_unbound alloc_unbound; - struct evtchn_bind_interdomain bind_interdomain; - struct evtchn_bind_virq bind_virq; - struct evtchn_bind_pirq bind_pirq; - struct evtchn_bind_ipi bind_ipi; - struct evtchn_close close; - struct evtchn_send send; - struct evtchn_status status; - struct evtchn_bind_vcpu bind_vcpu; - struct evtchn_unmask unmask; - } u; -}; -typedef struct evtchn_op evtchn_op_t; -DEFINE_XEN_GUEST_HANDLE(evtchn_op_t); - -/* - * 2-level ABI - */ - -#define EVTCHN_2L_NR_CHANNELS (sizeof(xen_ulong_t) * sizeof(xen_ulong_t) * 64) - -/* - * FIFO ABI - */ - -/* Events may have priorities from 0 (highest) to 15 (lowest). */ -#define EVTCHN_FIFO_PRIORITY_MAX 0 -#define EVTCHN_FIFO_PRIORITY_DEFAULT 7 -#define EVTCHN_FIFO_PRIORITY_MIN 15 - -#define EVTCHN_FIFO_MAX_QUEUES (EVTCHN_FIFO_PRIORITY_MIN + 1) - -typedef uint32_t event_word_t; - -#define EVTCHN_FIFO_PENDING 31 -#define EVTCHN_FIFO_MASKED 30 -#define EVTCHN_FIFO_LINKED 29 -#define EVTCHN_FIFO_BUSY 28 - -#define EVTCHN_FIFO_LINK_BITS 17 -#define EVTCHN_FIFO_LINK_MASK ((1 << EVTCHN_FIFO_LINK_BITS) - 1) - -#define EVTCHN_FIFO_NR_CHANNELS (1 << EVTCHN_FIFO_LINK_BITS) - -struct evtchn_fifo_control_block { - uint32_t ready; - uint32_t _rsvd; - uint32_t head[EVTCHN_FIFO_MAX_QUEUES]; -}; -typedef struct evtchn_fifo_control_block evtchn_fifo_control_block_t; - -#endif /* __XEN_PUBLIC_EVENT_CHANNEL_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h deleted file mode 100644 index b8a3d6ceb..000000000 --- a/include/xen/grant_table.h +++ /dev/null @@ -1,662 +0,0 @@ -/****************************************************************************** - * grant_table.h - * - * Interface for granting foreign access to page frames, and receiving - * page-ownership transfers. - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2004, K A Fraser - */ - -#ifndef __XEN_PUBLIC_GRANT_TABLE_H__ -#define __XEN_PUBLIC_GRANT_TABLE_H__ - -#include "xen.h" - -/* - * `incontents 150 gnttab Grant Tables - * - * Xen's grant tables provide a generic mechanism to memory sharing - * between domains. This shared memory interface underpins the split - * device drivers for block and network IO. - * - * Each domain has its own grant table. This is a data structure that - * is shared with Xen; it allows the domain to tell Xen what kind of - * permissions other domains have on its pages. Entries in the grant - * table are identified by grant references. A grant reference is an - * integer, which indexes into the grant table. It acts as a - * capability which the grantee can use to perform operations on the - * granter’s memory. - * - * This capability-based system allows shared-memory communications - * between unprivileged domains. A grant reference also encapsulates - * the details of a shared page, removing the need for a domain to - * know the real machine address of a page it is sharing. This makes - * it possible to share memory correctly with domains running in - * fully virtualised memory. - */ - -/*********************************** - * GRANT TABLE REPRESENTATION - */ - -/* Some rough guidelines on accessing and updating grant-table entries - * in a concurrency-safe manner. For more information, Linux contains a - * reference implementation for guest OSes (drivers/xen/grant_table.c, see - * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=drivers/xen/grant-table.c;hb=HEAD - * - * NB. WMB is a no-op on current-generation x86 processors. However, a - * compiler barrier will still be required. - * - * Introducing a valid entry into the grant table: - * 1. Write ent->domid. - * 2. Write ent->frame: - * GTF_permit_access: Frame to which access is permitted. - * GTF_accept_transfer: Pseudo-phys frame slot being filled by new - * frame, or zero if none. - * 3. Write memory barrier (WMB). - * 4. Write ent->flags, inc. valid type. - * - * Invalidating an unused GTF_permit_access entry: - * 1. flags = ent->flags. - * 2. Observe that !(flags & (GTF_reading|GTF_writing)). - * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0). - * NB. No need for WMB as reuse of entry is control-dependent on success of - * step 3, and all architectures guarantee ordering of ctrl-dep writes. - * - * Invalidating an in-use GTF_permit_access entry: - * This cannot be done directly. Request assistance from the domain controller - * which can set a timeout on the use of a grant entry and take necessary - * action. (NB. This is not yet implemented!). - * - * Invalidating an unused GTF_accept_transfer entry: - * 1. flags = ent->flags. - * 2. Observe that !(flags & GTF_transfer_committed). [*] - * 3. Check result of SMP-safe CMPXCHG(&ent->flags, flags, 0). - * NB. No need for WMB as reuse of entry is control-dependent on success of - * step 3, and all architectures guarantee ordering of ctrl-dep writes. - * [*] If GTF_transfer_committed is set then the grant entry is 'committed'. - * The guest must /not/ modify the grant entry until the address of the - * transferred frame is written. It is safe for the guest to spin waiting - * for this to occur (detect by observing GTF_transfer_completed in - * ent->flags). - * - * Invalidating a committed GTF_accept_transfer entry: - * 1. Wait for (ent->flags & GTF_transfer_completed). - * - * Changing a GTF_permit_access from writable to read-only: - * Use SMP-safe CMPXCHG to set GTF_readonly, while checking !GTF_writing. - * - * Changing a GTF_permit_access from read-only to writable: - * Use SMP-safe bit-setting instruction. - */ - -/* - * Reference to a grant entry in a specified domain's grant table. - */ -typedef uint32_t grant_ref_t; - -/* - * A grant table comprises a packed array of grant entries in one or more - * page frames shared between Xen and a guest. - * [XEN]: This field is written by Xen and read by the sharing guest. - * [GST]: This field is written by the guest and read by Xen. - */ - -/* - * Version 1 of the grant table entry structure is maintained purely - * for backwards compatibility. New guests should use version 2. - */ -#if __XEN_INTERFACE_VERSION__ < 0x0003020a -#define grant_entry_v1 grant_entry -#define grant_entry_v1_t grant_entry_t -#endif -struct grant_entry_v1 { - /* GTF_xxx: various type and flag information. [XEN,GST] */ - uint16_t flags; - /* The domain being granted foreign privileges. [GST] */ - domid_t domid; - /* - * GTF_permit_access: Frame that @domid is allowed to map and access. [GST] - * GTF_accept_transfer: Frame whose ownership transferred by @domid. [XEN] - */ - uint32_t frame; -}; -typedef struct grant_entry_v1 grant_entry_v1_t; - -/* The first few grant table entries will be preserved across grant table - * version changes and may be pre-populated at domain creation by tools. - */ -#define GNTTAB_NR_RESERVED_ENTRIES 8 -#define GNTTAB_RESERVED_CONSOLE 0 -#define GNTTAB_RESERVED_XENSTORE 1 - -/* - * Type of grant entry. - * GTF_invalid: This grant entry grants no privileges. - * GTF_permit_access: Allow @domid to map/access @frame. - * GTF_accept_transfer: Allow @domid to transfer ownership of one page frame - * to this guest. Xen writes the page number to @frame. - * GTF_transitive: Allow @domid to transitively access a subrange of - * @trans_grant in @trans_domid. No mappings are allowed. - */ -#define GTF_invalid (0U<<0) -#define GTF_permit_access (1U<<0) -#define GTF_accept_transfer (2U<<0) -#define GTF_transitive (3U<<0) -#define GTF_type_mask (3U<<0) - -/* - * Subflags for GTF_permit_access. - * GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST] - * GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN] - * GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN] - * GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags for the grant [GST] - * GTF_sub_page: Grant access to only a subrange of the page. @domid - * will only be allowed to copy from the grant, and not - * map it. [GST] - */ -#define _GTF_readonly (2) -#define GTF_readonly (1U<<_GTF_readonly) -#define _GTF_reading (3) -#define GTF_reading (1U<<_GTF_reading) -#define _GTF_writing (4) -#define GTF_writing (1U<<_GTF_writing) -#define _GTF_PWT (5) -#define GTF_PWT (1U<<_GTF_PWT) -#define _GTF_PCD (6) -#define GTF_PCD (1U<<_GTF_PCD) -#define _GTF_PAT (7) -#define GTF_PAT (1U<<_GTF_PAT) -#define _GTF_sub_page (8) -#define GTF_sub_page (1U<<_GTF_sub_page) - -/* - * Subflags for GTF_accept_transfer: - * GTF_transfer_committed: Xen sets this flag to indicate that it is committed - * to transferring ownership of a page frame. When a guest sees this flag - * it must /not/ modify the grant entry until GTF_transfer_completed is - * set by Xen. - * GTF_transfer_completed: It is safe for the guest to spin-wait on this flag - * after reading GTF_transfer_committed. Xen will always write the frame - * address, followed by ORing this flag, in a timely manner. - */ -#define _GTF_transfer_committed (2) -#define GTF_transfer_committed (1U<<_GTF_transfer_committed) -#define _GTF_transfer_completed (3) -#define GTF_transfer_completed (1U<<_GTF_transfer_completed) - -/* - * Version 2 grant table entries. These fulfil the same role as - * version 1 entries, but can represent more complicated operations. - * Any given domain will have either a version 1 or a version 2 table, - * and every entry in the table will be the same version. - * - * The interface by which domains use grant references does not depend - * on the grant table version in use by the other domain. - */ -#if __XEN_INTERFACE_VERSION__ >= 0x0003020a -/* - * Version 1 and version 2 grant entries share a common prefix. The - * fields of the prefix are documented as part of struct - * grant_entry_v1. - */ -struct grant_entry_header { - uint16_t flags; - domid_t domid; -}; -typedef struct grant_entry_header grant_entry_header_t; - -/* - * Version 2 of the grant entry structure. - */ -union grant_entry_v2 { - grant_entry_header_t hdr; - - /* - * This member is used for V1-style full page grants, where either: - * - * -- hdr.type is GTF_accept_transfer, or - * -- hdr.type is GTF_permit_access and GTF_sub_page is not set. - * - * In that case, the frame field has the same semantics as the - * field of the same name in the V1 entry structure. - */ - struct { - grant_entry_header_t hdr; - uint32_t pad0; - uint64_t frame; - } full_page; - - /* - * If the grant type is GTF_grant_access and GTF_sub_page is set, - * @domid is allowed to access bytes [@page_off,@page_off+@length) - * in frame @frame. - */ - struct { - grant_entry_header_t hdr; - uint16_t page_off; - uint16_t length; - uint64_t frame; - } sub_page; - - /* - * If the grant is GTF_transitive, @domid is allowed to use the - * grant @gref in domain @trans_domid, as if it was the local - * domain. Obviously, the transitive access must be compatible - * with the original grant. - * - * The current version of Xen does not allow transitive grants - * to be mapped. - */ - struct { - grant_entry_header_t hdr; - domid_t trans_domid; - uint16_t pad0; - grant_ref_t gref; - } transitive; - - uint32_t __spacer[4]; /* Pad to a power of two */ -}; -typedef union grant_entry_v2 grant_entry_v2_t; - -typedef uint16_t grant_status_t; - -#endif /* __XEN_INTERFACE_VERSION__ */ - -/*********************************** - * GRANT TABLE QUERIES AND USES - */ - -/* ` enum neg_errnoval - * ` HYPERVISOR_grant_table_op(enum grant_table_op cmd, - * ` void *args, - * ` unsigned int count) - * ` - * - * @args points to an array of a per-command data structure. The array - * has @count members - */ - -/* ` enum grant_table_op { // GNTTABOP_* => struct gnttab_* */ -#define GNTTABOP_map_grant_ref 0 -#define GNTTABOP_unmap_grant_ref 1 -#define GNTTABOP_setup_table 2 -#define GNTTABOP_dump_table 3 -#define GNTTABOP_transfer 4 -#define GNTTABOP_copy 5 -#define GNTTABOP_query_size 6 -#define GNTTABOP_unmap_and_replace 7 -#if __XEN_INTERFACE_VERSION__ >= 0x0003020a -#define GNTTABOP_set_version 8 -#define GNTTABOP_get_status_frames 9 -#define GNTTABOP_get_version 10 -#define GNTTABOP_swap_grant_ref 11 -#endif /* __XEN_INTERFACE_VERSION__ */ -/* ` } */ - -/* - * Handle to track a mapping created via a grant reference. - */ -typedef uint32_t grant_handle_t; - -/* - * GNTTABOP_map_grant_ref: Map the grant entry (,) for access - * by devices and/or host CPUs. If successful, is a tracking number - * that must be presented later to destroy the mapping(s). On error, - * is a negative status code. - * NOTES: - * 1. If GNTMAP_device_map is specified then is the address - * via which I/O devices may access the granted frame. - * 2. If GNTMAP_host_map is specified then a mapping will be added at - * either a host virtual address in the current address space, or at - * a PTE at the specified machine address. The type of mapping to - * perform is selected through the GNTMAP_contains_pte flag, and the - * address is specified in . - * 3. Mappings should only be destroyed via GNTTABOP_unmap_grant_ref. If a - * host mapping is destroyed by other means then it is *NOT* guaranteed - * to be accounted to the correct grant reference! - */ -struct gnttab_map_grant_ref { - /* IN parameters. */ - uint64_t host_addr; - uint32_t flags; /* GNTMAP_* */ - grant_ref_t ref; - domid_t dom; - /* OUT parameters. */ - int16_t status; /* => enum grant_status */ - grant_handle_t handle; - uint64_t dev_bus_addr; -}; -typedef struct gnttab_map_grant_ref gnttab_map_grant_ref_t; -DEFINE_XEN_GUEST_HANDLE(gnttab_map_grant_ref_t); - -/* - * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings - * tracked by . If or is zero, that - * field is ignored. If non-zero, they must refer to a device/host mapping - * that is tracked by - * NOTES: - * 1. The call may fail in an undefined manner if either mapping is not - * tracked by . - * 3. After executing a batch of unmaps, it is guaranteed that no stale - * mappings will remain in the device or host TLBs. - */ -struct gnttab_unmap_grant_ref { - /* IN parameters. */ - uint64_t host_addr; - uint64_t dev_bus_addr; - grant_handle_t handle; - /* OUT parameters. */ - int16_t status; /* => enum grant_status */ -}; -typedef struct gnttab_unmap_grant_ref gnttab_unmap_grant_ref_t; -DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_grant_ref_t); - -/* - * GNTTABOP_setup_table: Set up a grant table for comprising at least - * pages. The frame addresses are written to the . - * Only addresses are written, even if the table is larger. - * NOTES: - * 1. may be specified as DOMID_SELF. - * 2. Only a sufficiently-privileged domain may specify != DOMID_SELF. - * 3. Xen may not support more than a single grant-table page per domain. - */ -struct gnttab_setup_table { - /* IN parameters. */ - domid_t dom; - uint32_t nr_frames; - /* OUT parameters. */ - int16_t status; /* => enum grant_status */ -#if __XEN_INTERFACE_VERSION__ < 0x00040300 - XEN_GUEST_HANDLE(ulong) frame_list; -#else - XEN_GUEST_HANDLE(xen_pfn_t) frame_list; -#endif -}; -typedef struct gnttab_setup_table gnttab_setup_table_t; -DEFINE_XEN_GUEST_HANDLE(gnttab_setup_table_t); - -/* - * GNTTABOP_dump_table: Dump the contents of the grant table to the - * xen console. Debugging use only. - */ -struct gnttab_dump_table { - /* IN parameters. */ - domid_t dom; - /* OUT parameters. */ - int16_t status; /* => enum grant_status */ -}; -typedef struct gnttab_dump_table gnttab_dump_table_t; -DEFINE_XEN_GUEST_HANDLE(gnttab_dump_table_t); - -/* - * GNTTABOP_transfer_grant_ref: Transfer to a foreign domain. The - * foreign domain has previously registered its interest in the transfer via - * . - * - * Note that, even if the transfer fails, the specified page no longer belongs - * to the calling domain *unless* the error is GNTST_bad_page. - */ -struct gnttab_transfer { - /* IN parameters. */ - xen_pfn_t mfn; - domid_t domid; - grant_ref_t ref; - /* OUT parameters. */ - int16_t status; -}; -typedef struct gnttab_transfer gnttab_transfer_t; -DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_t); - - -/* - * GNTTABOP_copy: Hypervisor based copy - * source and destinations can be eithers MFNs or, for foreign domains, - * grant references. the foreign domain has to grant read/write access - * in its grant table. - * - * The flags specify what type source and destinations are (either MFN - * or grant reference). - * - * Note that this can also be used to copy data between two domains - * via a third party if the source and destination domains had previously - * grant appropriate access to their pages to the third party. - * - * source_offset specifies an offset in the source frame, dest_offset - * the offset in the target frame and len specifies the number of - * bytes to be copied. - */ - -#define _GNTCOPY_source_gref (0) -#define GNTCOPY_source_gref (1<<_GNTCOPY_source_gref) -#define _GNTCOPY_dest_gref (1) -#define GNTCOPY_dest_gref (1<<_GNTCOPY_dest_gref) - -struct gnttab_copy { - /* IN parameters. */ - struct { - union { - grant_ref_t ref; - xen_pfn_t gmfn; - } u; - domid_t domid; - uint16_t offset; - } source, dest; - uint16_t len; - uint16_t flags; /* GNTCOPY_* */ - /* OUT parameters. */ - int16_t status; -}; -typedef struct gnttab_copy gnttab_copy_t; -DEFINE_XEN_GUEST_HANDLE(gnttab_copy_t); - -/* - * GNTTABOP_query_size: Query the current and maximum sizes of the shared - * grant table. - * NOTES: - * 1. may be specified as DOMID_SELF. - * 2. Only a sufficiently-privileged domain may specify != DOMID_SELF. - */ -struct gnttab_query_size { - /* IN parameters. */ - domid_t dom; - /* OUT parameters. */ - uint32_t nr_frames; - uint32_t max_nr_frames; - int16_t status; /* => enum grant_status */ -}; -typedef struct gnttab_query_size gnttab_query_size_t; -DEFINE_XEN_GUEST_HANDLE(gnttab_query_size_t); - -/* - * GNTTABOP_unmap_and_replace: Destroy one or more grant-reference mappings - * tracked by but atomically replace the page table entry with one - * pointing to the machine address under . will be - * redirected to the null entry. - * NOTES: - * 1. The call may fail in an undefined manner if either mapping is not - * tracked by . - * 2. After executing a batch of unmaps, it is guaranteed that no stale - * mappings will remain in the device or host TLBs. - */ -struct gnttab_unmap_and_replace { - /* IN parameters. */ - uint64_t host_addr; - uint64_t new_addr; - grant_handle_t handle; - /* OUT parameters. */ - int16_t status; /* => enum grant_status */ -}; -typedef struct gnttab_unmap_and_replace gnttab_unmap_and_replace_t; -DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_and_replace_t); - -#if __XEN_INTERFACE_VERSION__ >= 0x0003020a -/* - * GNTTABOP_set_version: Request a particular version of the grant - * table shared table structure. This operation can only be performed - * once in any given domain. It must be performed before any grants - * are activated; otherwise, the domain will be stuck with version 1. - * The only defined versions are 1 and 2. - */ -struct gnttab_set_version { - /* IN/OUT parameters */ - uint32_t version; -}; -typedef struct gnttab_set_version gnttab_set_version_t; -DEFINE_XEN_GUEST_HANDLE(gnttab_set_version_t); - - -/* - * GNTTABOP_get_status_frames: Get the list of frames used to store grant - * status for . In grant format version 2, the status is separated - * from the other shared grant fields to allow more efficient synchronization - * using barriers instead of atomic cmpexch operations. - * specify the size of vector . - * The frame addresses are returned in the . - * Only addresses are returned, even if the table is larger. - * NOTES: - * 1. may be specified as DOMID_SELF. - * 2. Only a sufficiently-privileged domain may specify != DOMID_SELF. - */ -struct gnttab_get_status_frames { - /* IN parameters. */ - uint32_t nr_frames; - domid_t dom; - /* OUT parameters. */ - int16_t status; /* => enum grant_status */ - XEN_GUEST_HANDLE(uint64_t) frame_list; -}; -typedef struct gnttab_get_status_frames gnttab_get_status_frames_t; -DEFINE_XEN_GUEST_HANDLE(gnttab_get_status_frames_t); - -/* - * GNTTABOP_get_version: Get the grant table version which is in - * effect for domain . - */ -struct gnttab_get_version { - /* IN parameters */ - domid_t dom; - uint16_t pad; - /* OUT parameters */ - uint32_t version; -}; -typedef struct gnttab_get_version gnttab_get_version_t; -DEFINE_XEN_GUEST_HANDLE(gnttab_get_version_t); - -/* - * GNTTABOP_swap_grant_ref: Swap the contents of two grant entries. - */ -struct gnttab_swap_grant_ref { - /* IN parameters */ - grant_ref_t ref_a; - grant_ref_t ref_b; - /* OUT parameters */ - int16_t status; /* => enum grant_status */ -}; -typedef struct gnttab_swap_grant_ref gnttab_swap_grant_ref_t; -DEFINE_XEN_GUEST_HANDLE(gnttab_swap_grant_ref_t); - -#endif /* __XEN_INTERFACE_VERSION__ */ - -/* - * Bitfield values for gnttab_map_grant_ref.flags. - */ - /* Map the grant entry for access by I/O devices. */ -#define _GNTMAP_device_map (0) -#define GNTMAP_device_map (1<<_GNTMAP_device_map) - /* Map the grant entry for access by host CPUs. */ -#define _GNTMAP_host_map (1) -#define GNTMAP_host_map (1<<_GNTMAP_host_map) - /* Accesses to the granted frame will be restricted to read-only access. */ -#define _GNTMAP_readonly (2) -#define GNTMAP_readonly (1<<_GNTMAP_readonly) - /* - * GNTMAP_host_map subflag: - * 0 => The host mapping is usable only by the guest OS. - * 1 => The host mapping is usable by guest OS + current application. - */ -#define _GNTMAP_application_map (3) -#define GNTMAP_application_map (1<<_GNTMAP_application_map) - - /* - * GNTMAP_contains_pte subflag: - * 0 => This map request contains a host virtual address. - * 1 => This map request contains the machine addess of the PTE to update. - */ -#define _GNTMAP_contains_pte (4) -#define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte) - -#define _GNTMAP_can_fail (5) -#define GNTMAP_can_fail (1<<_GNTMAP_can_fail) - -/* - * Bits to be placed in guest kernel available PTE bits (architecture - * dependent; only supported when XENFEAT_gnttab_map_avail_bits is set). - */ -#define _GNTMAP_guest_avail0 (16) -#define GNTMAP_guest_avail_mask ((uint32_t)~0 << _GNTMAP_guest_avail0) - -/* - * Values for error status returns. All errors are -ve. - */ -/* ` enum grant_status { */ -#define GNTST_okay (0) /* Normal return. */ -#define GNTST_general_error (-1) /* General undefined error. */ -#define GNTST_bad_domain (-2) /* Unrecognsed domain id. */ -#define GNTST_bad_gntref (-3) /* Unrecognised or inappropriate gntref. */ -#define GNTST_bad_handle (-4) /* Unrecognised or inappropriate handle. */ -#define GNTST_bad_virt_addr (-5) /* Inappropriate virtual address to map. */ -#define GNTST_bad_dev_addr (-6) /* Inappropriate device address to unmap.*/ -#define GNTST_no_device_space (-7) /* Out of space in I/O MMU. */ -#define GNTST_permission_denied (-8) /* Not enough privilege for operation. */ -#define GNTST_bad_page (-9) /* Specified page was invalid for op. */ -#define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary. */ -#define GNTST_address_too_big (-11) /* transfer page address too large. */ -#define GNTST_eagain (-12) /* Operation not done; try again. */ -/* ` } */ - -#define GNTTABOP_error_msgs { \ - "okay", \ - "undefined error", \ - "unrecognised domain id", \ - "invalid grant reference", \ - "invalid mapping handle", \ - "invalid virtual address", \ - "invalid device address", \ - "no spare translation slot in the I/O MMU", \ - "permission denied", \ - "bad page", \ - "copy arguments cross page boundary", \ - "page address size too large", \ - "operation not done; try again" \ -} - -#endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/hvm/hvm_op.h b/include/xen/hvm/hvm_op.h deleted file mode 100644 index 0bdafdf59..000000000 --- a/include/xen/hvm/hvm_op.h +++ /dev/null @@ -1,296 +0,0 @@ -/* - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2007, Keir Fraser - */ - -#ifndef __XEN_PUBLIC_HVM_HVM_OP_H__ -#define __XEN_PUBLIC_HVM_HVM_OP_H__ - -#include "../xen.h" -#include "../trace.h" -#include "../event_channel.h" - -/* Get/set subcommands: extra argument == pointer to xen_hvm_param struct. */ -#define HVMOP_set_param 0 -#define HVMOP_get_param 1 -struct xen_hvm_param { - domid_t domid; /* IN */ - uint32_t index; /* IN */ - uint64_t value; /* IN/OUT */ -}; -typedef struct xen_hvm_param xen_hvm_param_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_param_t); - -#if __XEN_INTERFACE_VERSION__ < 0x00040900 - -/* Set the logical level of one of a domain's PCI INTx wires. */ -#define HVMOP_set_pci_intx_level 2 -struct xen_hvm_set_pci_intx_level { - /* Domain to be updated. */ - domid_t domid; - /* PCI INTx identification in PCI topology (domain:bus:device:intx). */ - uint8_t domain, bus, device, intx; - /* Assertion level (0 = unasserted, 1 = asserted). */ - uint8_t level; -}; -typedef struct xen_hvm_set_pci_intx_level xen_hvm_set_pci_intx_level_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_intx_level_t); - -/* Set the logical level of one of a domain's ISA IRQ wires. */ -#define HVMOP_set_isa_irq_level 3 -struct xen_hvm_set_isa_irq_level { - /* Domain to be updated. */ - domid_t domid; - /* ISA device identification, by ISA IRQ (0-15). */ - uint8_t isa_irq; - /* Assertion level (0 = unasserted, 1 = asserted). */ - uint8_t level; -}; -typedef struct xen_hvm_set_isa_irq_level xen_hvm_set_isa_irq_level_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_isa_irq_level_t); - -#define HVMOP_set_pci_link_route 4 -struct xen_hvm_set_pci_link_route { - /* Domain to be updated. */ - domid_t domid; - /* PCI link identifier (0-3). */ - uint8_t link; - /* ISA IRQ (1-15), or 0 (disable link). */ - uint8_t isa_irq; -}; -typedef struct xen_hvm_set_pci_link_route xen_hvm_set_pci_link_route_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_link_route_t); - -#endif /* __XEN_INTERFACE_VERSION__ < 0x00040900 */ - -/* Flushes all VCPU TLBs: @arg must be NULL. */ -#define HVMOP_flush_tlbs 5 - -typedef enum { - HVMMEM_ram_rw, /* Normal read/write guest RAM */ - HVMMEM_ram_ro, /* Read-only; writes are discarded */ - HVMMEM_mmio_dm, /* Reads and write go to the device model */ -#if __XEN_INTERFACE_VERSION__ < 0x00040700 - HVMMEM_mmio_write_dm, /* Read-only; writes go to the device model */ -#else - HVMMEM_unused, /* Placeholder; setting memory to this type - will fail for code after 4.7.0 */ -#endif - HVMMEM_ioreq_server /* Memory type claimed by an ioreq server; type - changes to this value are only allowed after - an ioreq server has claimed its ownership. - Only pages with HVMMEM_ram_rw are allowed to - change to this type; conversely, pages with - this type are only allowed to be changed back - to HVMMEM_ram_rw. */ -} hvmmem_type_t; - -/* Hint from PV drivers for pagetable destruction. */ -#define HVMOP_pagetable_dying 9 -struct xen_hvm_pagetable_dying { - /* Domain with a pagetable about to be destroyed. */ - domid_t domid; - uint16_t pad[3]; /* align next field on 8-byte boundary */ - /* guest physical address of the toplevel pagetable dying */ - uint64_t gpa; -}; -typedef struct xen_hvm_pagetable_dying xen_hvm_pagetable_dying_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_pagetable_dying_t); - -/* Get the current Xen time, in nanoseconds since system boot. */ -#define HVMOP_get_time 10 -struct xen_hvm_get_time { - uint64_t now; /* OUT */ -}; -typedef struct xen_hvm_get_time xen_hvm_get_time_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_time_t); - -#define HVMOP_xentrace 11 -struct xen_hvm_xentrace { - uint16_t event, extra_bytes; - uint8_t extra[TRACE_EXTRA_MAX * sizeof(uint32_t)]; -}; -typedef struct xen_hvm_xentrace xen_hvm_xentrace_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_xentrace_t); - -/* Following tools-only interfaces may change in future. */ -#if defined(__XEN__) || defined(__XEN_TOOLS__) - -/* Deprecated by XENMEM_access_op_set_access */ -#define HVMOP_set_mem_access 12 - -/* Deprecated by XENMEM_access_op_get_access */ -#define HVMOP_get_mem_access 13 - -#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ - -#define HVMOP_get_mem_type 15 -/* Return hvmmem_type_t for the specified pfn. */ -struct xen_hvm_get_mem_type { - /* Domain to be queried. */ - domid_t domid; - /* OUT variable. */ - uint16_t mem_type; - uint16_t pad[2]; /* align next field on 8-byte boundary */ - /* IN variable. */ - uint64_t pfn; -}; -typedef struct xen_hvm_get_mem_type xen_hvm_get_mem_type_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_mem_type_t); - -/* Following tools-only interfaces may change in future. */ -#if defined(__XEN__) || defined(__XEN_TOOLS__) - -/* - * Definitions relating to DMOP_create_ioreq_server. (Defined here for - * backwards compatibility). - */ - -#define HVM_IOREQSRV_BUFIOREQ_OFF 0 -#define HVM_IOREQSRV_BUFIOREQ_LEGACY 1 -/* - * Use this when read_pointer gets updated atomically and - * the pointer pair gets read atomically: - */ -#define HVM_IOREQSRV_BUFIOREQ_ATOMIC 2 - -#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ - -#if defined(__i386__) || defined(__x86_64__) - -/* - * HVMOP_set_evtchn_upcall_vector: Set a that should be used for event - * channel upcalls on the specified . If set, - * this vector will be used in preference to the - * domain global callback via (see - * HVM_PARAM_CALLBACK_IRQ). - */ -#define HVMOP_set_evtchn_upcall_vector 23 -struct xen_hvm_evtchn_upcall_vector { - uint32_t vcpu; - uint8_t vector; -}; -typedef struct xen_hvm_evtchn_upcall_vector xen_hvm_evtchn_upcall_vector_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_evtchn_upcall_vector_t); - -#endif /* defined(__i386__) || defined(__x86_64__) */ - -#define HVMOP_guest_request_vm_event 24 - -/* HVMOP_altp2m: perform altp2m state operations */ -#define HVMOP_altp2m 25 - -#define HVMOP_ALTP2M_INTERFACE_VERSION 0x00000001 - -struct xen_hvm_altp2m_domain_state { - /* IN or OUT variable on/off */ - uint8_t state; -}; -typedef struct xen_hvm_altp2m_domain_state xen_hvm_altp2m_domain_state_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_domain_state_t); - -struct xen_hvm_altp2m_vcpu_enable_notify { - uint32_t vcpu_id; - uint32_t pad; - /* #VE info area gfn */ - uint64_t gfn; -}; -typedef struct xen_hvm_altp2m_vcpu_enable_notify xen_hvm_altp2m_vcpu_enable_notify_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_vcpu_enable_notify_t); - -struct xen_hvm_altp2m_view { - /* IN/OUT variable */ - uint16_t view; - /* Create view only: default access type - * NOTE: currently ignored */ - uint16_t hvmmem_default_access; /* xenmem_access_t */ -}; -typedef struct xen_hvm_altp2m_view xen_hvm_altp2m_view_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_view_t); - -struct xen_hvm_altp2m_set_mem_access { - /* view */ - uint16_t view; - /* Memory type */ - uint16_t hvmmem_access; /* xenmem_access_t */ - uint32_t pad; - /* gfn */ - uint64_t gfn; -}; -typedef struct xen_hvm_altp2m_set_mem_access xen_hvm_altp2m_set_mem_access_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_set_mem_access_t); - -struct xen_hvm_altp2m_change_gfn { - /* view */ - uint16_t view; - uint16_t pad1; - uint32_t pad2; - /* old gfn */ - uint64_t old_gfn; - /* new gfn, INVALID_GFN (~0UL) means revert */ - uint64_t new_gfn; -}; -typedef struct xen_hvm_altp2m_change_gfn xen_hvm_altp2m_change_gfn_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_change_gfn_t); - -struct xen_hvm_altp2m_op { - uint32_t version; /* HVMOP_ALTP2M_INTERFACE_VERSION */ - uint32_t cmd; -/* Get/set the altp2m state for a domain */ -#define HVMOP_altp2m_get_domain_state 1 -#define HVMOP_altp2m_set_domain_state 2 -/* Set the current VCPU to receive altp2m event notifications */ -#define HVMOP_altp2m_vcpu_enable_notify 3 -/* Create a new view */ -#define HVMOP_altp2m_create_p2m 4 -/* Destroy a view */ -#define HVMOP_altp2m_destroy_p2m 5 -/* Switch view for an entire domain */ -#define HVMOP_altp2m_switch_p2m 6 -/* Notify that a page of memory is to have specific access types */ -#define HVMOP_altp2m_set_mem_access 7 -/* Change a p2m entry to have a different gfn->mfn mapping */ -#define HVMOP_altp2m_change_gfn 8 - domid_t domain; - uint16_t pad1; - uint32_t pad2; - union { - struct xen_hvm_altp2m_domain_state domain_state; - struct xen_hvm_altp2m_vcpu_enable_notify enable_notify; - struct xen_hvm_altp2m_view view; - struct xen_hvm_altp2m_set_mem_access set_mem_access; - struct xen_hvm_altp2m_change_gfn change_gfn; - uint8_t pad[64]; - } u; -}; -typedef struct xen_hvm_altp2m_op xen_hvm_altp2m_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_op_t); - -#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/hvm/params.h b/include/xen/hvm/params.h deleted file mode 100644 index 2ec2e7c80..000000000 --- a/include/xen/hvm/params.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2007, Keir Fraser - */ - -#ifndef __XEN_PUBLIC_HVM_PARAMS_H__ -#define __XEN_PUBLIC_HVM_PARAMS_H__ - -#include "hvm_op.h" - -/* - * Parameter space for HVMOP_{set,get}_param. - */ - -#define HVM_PARAM_CALLBACK_IRQ 0 -#define HVM_PARAM_CALLBACK_IRQ_TYPE_MASK xen_mk_ullong(0xFF00000000000000) -/* - * How should CPU0 event-channel notifications be delivered? - * - * If val == 0 then CPU0 event-channel notifications are not delivered. - * If val != 0, val[63:56] encodes the type, as follows: - */ - -#define HVM_PARAM_CALLBACK_TYPE_GSI 0 -/* - * val[55:0] is a delivery GSI. GSI 0 cannot be used, as it aliases val == 0, - * and disables all notifications. - */ - -#define HVM_PARAM_CALLBACK_TYPE_PCI_INTX 1 -/* - * val[55:0] is a delivery PCI INTx line: - * Domain = val[47:32], Bus = val[31:16] DevFn = val[15:8], IntX = val[1:0] - */ - -#if defined(__i386__) || defined(__x86_64__) -#define HVM_PARAM_CALLBACK_TYPE_VECTOR 2 -/* - * val[7:0] is a vector number. Check for XENFEAT_hvm_callback_vector to know - * if this delivery method is available. - */ -#elif defined(__arm__) || defined(__aarch64__) -#define HVM_PARAM_CALLBACK_TYPE_PPI 2 -/* - * val[55:16] needs to be zero. - * val[15:8] is interrupt flag of the PPI used by event-channel: - * bit 8: the PPI is edge(1) or level(0) triggered - * bit 9: the PPI is active low(1) or high(0) - * val[7:0] is a PPI number used by event-channel. - * This is only used by ARM/ARM64 and masking/eoi the interrupt associated to - * the notification is handled by the interrupt controller. - */ -#define HVM_PARAM_CALLBACK_TYPE_PPI_FLAG_MASK 0xFF00 -#define HVM_PARAM_CALLBACK_TYPE_PPI_FLAG_LOW_LEVEL 2 -#endif - -/* - * These are not used by Xen. They are here for convenience of HVM-guest - * xenbus implementations. - */ -#define HVM_PARAM_STORE_PFN 1 -#define HVM_PARAM_STORE_EVTCHN 2 - -#define HVM_PARAM_PAE_ENABLED 4 - -#define HVM_PARAM_IOREQ_PFN 5 - -#define HVM_PARAM_BUFIOREQ_PFN 6 -#define HVM_PARAM_BUFIOREQ_EVTCHN 26 - -#if defined(__i386__) || defined(__x86_64__) - -/* - * Viridian enlightenments - * - * (See http://download.microsoft.com/download/A/B/4/AB43A34E-BDD0-4FA6-BDEF-79EEF16E880B/Hypervisor%20Top%20Level%20Functional%20Specification%20v4.0.docx) - * - * To expose viridian enlightenments to the guest set this parameter - * to the desired feature mask. The base feature set must be present - * in any valid feature mask. - */ -#define HVM_PARAM_VIRIDIAN 9 - -/* Base+Freq viridian feature sets: - * - * - Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL) - * - APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR) - * - Virtual Processor index MSR (HV_X64_MSR_VP_INDEX) - * - Timer frequency MSRs (HV_X64_MSR_TSC_FREQUENCY and - * HV_X64_MSR_APIC_FREQUENCY) - */ -#define _HVMPV_base_freq 0 -#define HVMPV_base_freq (1 << _HVMPV_base_freq) - -/* Feature set modifications */ - -/* Disable timer frequency MSRs (HV_X64_MSR_TSC_FREQUENCY and - * HV_X64_MSR_APIC_FREQUENCY). - * This modification restores the viridian feature set to the - * original 'base' set exposed in releases prior to Xen 4.4. - */ -#define _HVMPV_no_freq 1 -#define HVMPV_no_freq (1 << _HVMPV_no_freq) - -/* Enable Partition Time Reference Counter (HV_X64_MSR_TIME_REF_COUNT) */ -#define _HVMPV_time_ref_count 2 -#define HVMPV_time_ref_count (1 << _HVMPV_time_ref_count) - -/* Enable Reference TSC Page (HV_X64_MSR_REFERENCE_TSC) */ -#define _HVMPV_reference_tsc 3 -#define HVMPV_reference_tsc (1 << _HVMPV_reference_tsc) - -/* Use Hypercall for remote TLB flush */ -#define _HVMPV_hcall_remote_tlb_flush 4 -#define HVMPV_hcall_remote_tlb_flush (1 << _HVMPV_hcall_remote_tlb_flush) - -/* Use APIC assist */ -#define _HVMPV_apic_assist 5 -#define HVMPV_apic_assist (1 << _HVMPV_apic_assist) - -/* Enable crash MSRs */ -#define _HVMPV_crash_ctl 6 -#define HVMPV_crash_ctl (1 << _HVMPV_crash_ctl) - -#define HVMPV_feature_mask \ - (HVMPV_base_freq | \ - HVMPV_no_freq | \ - HVMPV_time_ref_count | \ - HVMPV_reference_tsc | \ - HVMPV_hcall_remote_tlb_flush | \ - HVMPV_apic_assist | \ - HVMPV_crash_ctl) - -#endif - -/* - * Set mode for virtual timers (currently x86 only): - * delay_for_missed_ticks (default): - * Do not advance a vcpu's time beyond the correct delivery time for - * interrupts that have been missed due to preemption. Deliver missed - * interrupts when the vcpu is rescheduled and advance the vcpu's virtual - * time stepwise for each one. - * no_delay_for_missed_ticks: - * As above, missed interrupts are delivered, but guest time always tracks - * wallclock (i.e., real) time while doing so. - * no_missed_ticks_pending: - * No missed interrupts are held pending. Instead, to ensure ticks are - * delivered at some non-zero rate, if we detect missed ticks then the - * internal tick alarm is not disabled if the VCPU is preempted during the - * next tick period. - * one_missed_tick_pending: - * Missed interrupts are collapsed together and delivered as one 'late tick'. - * Guest time always tracks wallclock (i.e., real) time. - */ -#define HVM_PARAM_TIMER_MODE 10 -#define HVMPTM_delay_for_missed_ticks 0 -#define HVMPTM_no_delay_for_missed_ticks 1 -#define HVMPTM_no_missed_ticks_pending 2 -#define HVMPTM_one_missed_tick_pending 3 - -/* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */ -#define HVM_PARAM_HPET_ENABLED 11 - -/* Identity-map page directory used by Intel EPT when CR0.PG=0. */ -#define HVM_PARAM_IDENT_PT 12 - -/* Device Model domain, defaults to 0. */ -#define HVM_PARAM_DM_DOMAIN 13 - -/* ACPI S state: currently support S0 and S3 on x86. */ -#define HVM_PARAM_ACPI_S_STATE 14 - -/* TSS used on Intel when CR0.PE=0. */ -#define HVM_PARAM_VM86_TSS 15 - -/* Boolean: Enable aligning all periodic vpts to reduce interrupts */ -#define HVM_PARAM_VPT_ALIGN 16 - -/* Console debug shared memory ring and event channel */ -#define HVM_PARAM_CONSOLE_PFN 17 -#define HVM_PARAM_CONSOLE_EVTCHN 18 - -/* - * Select location of ACPI PM1a and TMR control blocks. Currently two locations - * are supported, specified by version 0 or 1 in this parameter: - * - 0: default, use the old addresses - * PM1A_EVT == 0x1f40; PM1A_CNT == 0x1f44; PM_TMR == 0x1f48 - * - 1: use the new default qemu addresses - * PM1A_EVT == 0xb000; PM1A_CNT == 0xb004; PM_TMR == 0xb008 - * You can find these address definitions in - */ -#define HVM_PARAM_ACPI_IOPORTS_LOCATION 19 - -/* Deprecated */ -#define HVM_PARAM_MEMORY_EVENT_CR0 20 -#define HVM_PARAM_MEMORY_EVENT_CR3 21 -#define HVM_PARAM_MEMORY_EVENT_CR4 22 -#define HVM_PARAM_MEMORY_EVENT_INT3 23 -#define HVM_PARAM_MEMORY_EVENT_SINGLE_STEP 25 -#define HVM_PARAM_MEMORY_EVENT_MSR 30 - -/* Boolean: Enable nestedhvm (hvm only) */ -#define HVM_PARAM_NESTEDHVM 24 - -/* Params for the mem event rings */ -#define HVM_PARAM_PAGING_RING_PFN 27 -#define HVM_PARAM_MONITOR_RING_PFN 28 -#define HVM_PARAM_SHARING_RING_PFN 29 - -/* SHUTDOWN_* action in case of a triple fault */ -#define HVM_PARAM_TRIPLE_FAULT_REASON 31 - -#define HVM_PARAM_IOREQ_SERVER_PFN 32 -#define HVM_PARAM_NR_IOREQ_SERVER_PAGES 33 - -/* Location of the VM Generation ID in guest physical address space. */ -#define HVM_PARAM_VM_GENERATION_ID_ADDR 34 - -/* - * Set mode for altp2m: - * disabled: don't activate altp2m (default) - * mixed: allow access to all altp2m ops for both in-guest and external tools - * external: allow access to external privileged tools only - * limited: guest only has limited access (ie. control VMFUNC and #VE) - */ -#define HVM_PARAM_ALTP2M 35 -#define XEN_ALTP2M_disabled 0 -#define XEN_ALTP2M_mixed 1 -#define XEN_ALTP2M_external 2 -#define XEN_ALTP2M_limited 3 - -/* - * Size of the x87 FPU FIP/FDP registers that the hypervisor needs to - * save/restore. This is a workaround for a hardware limitation that - * does not allow the full FIP/FDP and FCS/FDS to be restored. - * - * Valid values are: - * - * 8: save/restore 64-bit FIP/FDP and clear FCS/FDS (default if CPU - * has FPCSDS feature). - * - * 4: save/restore 32-bit FIP/FDP, FCS/FDS, and clear upper 32-bits of - * FIP/FDP. - * - * 0: allow hypervisor to choose based on the value of FIP/FDP - * (default if CPU does not have FPCSDS). - * - * If FPCSDS (bit 13 in CPUID leaf 0x7, subleaf 0x0) is set, the CPU - * never saves FCS/FDS and this parameter should be left at the - * default of 8. - */ -#define HVM_PARAM_X87_FIP_WIDTH 36 - -/* - * TSS (and its size) used on Intel when CR0.PE=0. The address occupies - * the low 32 bits, while the size is in the high 32 ones. - */ -#define HVM_PARAM_VM86_TSS_SIZED 37 - -/* Enable MCA capabilities. */ -#define HVM_PARAM_MCA_CAP 38 -#define XEN_HVM_MCA_CAP_LMCE (xen_mk_ullong(1) << 0) -#define XEN_HVM_MCA_CAP_MASK XEN_HVM_MCA_CAP_LMCE - -#define HVM_NR_PARAMS 39 - -#endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ diff --git a/include/xen/hvm/start_info.h b/include/xen/hvm/start_info.h deleted file mode 100644 index 648415976..000000000 --- a/include/xen/hvm/start_info.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2016, Citrix Systems, Inc. - */ - -#ifndef __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ -#define __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ - -/* - * Start of day structure passed to PVH guests and to HVM guests in %ebx. - * - * NOTE: nothing will be loaded at physical address 0, so a 0 value in any - * of the address fields should be treated as not present. - * - * 0 +----------------+ - * | magic | Contains the magic value XEN_HVM_START_MAGIC_VALUE - * | | ("xEn3" with the 0x80 bit of the "E" set). - * 4 +----------------+ - * | version | Version of this structure. Current version is 0. New - * | | versions are guaranteed to be backwards-compatible. - * 8 +----------------+ - * | flags | SIF_xxx flags. - * 12 +----------------+ - * | nr_modules | Number of modules passed to the kernel. - * 16 +----------------+ - * | modlist_paddr | Physical address of an array of modules - * | | (layout of the structure below). - * 24 +----------------+ - * | cmdline_paddr | Physical address of the command line, - * | | a zero-terminated ASCII string. - * 32 +----------------+ - * | rsdp_paddr | Physical address of the RSDP ACPI data structure. - * 40 +----------------+ - * - * The layout of each entry in the module structure is the following: - * - * 0 +----------------+ - * | paddr | Physical address of the module. - * 8 +----------------+ - * | size | Size of the module in bytes. - * 16 +----------------+ - * | cmdline_paddr | Physical address of the command line, - * | | a zero-terminated ASCII string. - * 24 +----------------+ - * | reserved | - * 32 +----------------+ - * - * The address and sizes are always a 64bit little endian unsigned integer. - * - * NB: Xen on x86 will always try to place all the data below the 4GiB - * boundary. - */ -#define XEN_HVM_START_MAGIC_VALUE 0x336ec578 - -/* - * C representation of the x86/HVM start info layout. - * - * The canonical definition of this layout is above, this is just a way to - * represent the layout described there using C types. - */ -struct hvm_start_info { - uint32_t magic; /* Contains the magic value 0x336ec578 */ - /* ("xEn3" with the 0x80 bit of the "E" set).*/ - uint32_t version; /* Version of this structure. */ - uint32_t flags; /* SIF_xxx flags. */ - uint32_t nr_modules; /* Number of modules passed to the kernel. */ - uint64_t modlist_paddr; /* Physical address of an array of */ - /* hvm_modlist_entry. */ - uint64_t cmdline_paddr; /* Physical address of the command line. */ - uint64_t rsdp_paddr; /* Physical address of the RSDP ACPI data */ - /* structure. */ -}; - -struct hvm_modlist_entry { - uint64_t paddr; /* Physical address of the module. */ - uint64_t size; /* Size of the module in bytes. */ - uint64_t cmdline_paddr; /* Physical address of the command line. */ - uint64_t reserved; -}; - -#endif /* __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ */ diff --git a/include/xen/io/blkif.h b/include/xen/io/blkif.h deleted file mode 100644 index c3e169ce2..000000000 --- a/include/xen/io/blkif.h +++ /dev/null @@ -1,608 +0,0 @@ -/****************************************************************************** - * blkif.h - * - * Unified block-device I/O interface for Xen guest OSes. - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2003-2004, Keir Fraser - * Copyright (c) 2012, Spectra Logic Corporation - */ - -#ifndef __XEN_PUBLIC_IO_BLKIF_H__ -#define __XEN_PUBLIC_IO_BLKIF_H__ - -#include "ring.h" -#include "../grant_table.h" - -/* - * Front->back notifications: When enqueuing a new request, sending a - * notification can be made conditional on req_event (i.e., the generic - * hold-off mechanism provided by the ring macros). Backends must set - * req_event appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()). - * - * Back->front notifications: When enqueuing a new response, sending a - * notification can be made conditional on rsp_event (i.e., the generic - * hold-off mechanism provided by the ring macros). Frontends must set - * rsp_event appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()). - */ - -#ifndef blkif_vdev_t -#define blkif_vdev_t uint16_t -#endif -#define blkif_sector_t uint64_t - -/* - * Feature and Parameter Negotiation - * ================================= - * The two halves of a Xen block driver utilize nodes within the XenStore to - * communicate capabilities and to negotiate operating parameters. This - * section enumerates these nodes which reside in the respective front and - * backend portions of the XenStore, following the XenBus convention. - * - * All data in the XenStore is stored as strings. Nodes specifying numeric - * values are encoded in decimal. Integer value ranges listed below are - * expressed as fixed sized integer types capable of storing the conversion - * of a properly formated node string, without loss of information. - * - * Any specified default value is in effect if the corresponding XenBus node - * is not present in the XenStore. - * - * XenStore nodes in sections marked "PRIVATE" are solely for use by the - * driver side whose XenBus tree contains them. - * - * XenStore nodes marked "DEPRECATED" in their notes section should only be - * used to provide interoperability with legacy implementations. - * - * See the XenBus state transition diagram below for details on when XenBus - * nodes must be published and when they can be queried. - * - ***************************************************************************** - * Backend XenBus Nodes - ***************************************************************************** - * - *------------------ Backend Device Identification (PRIVATE) ------------------ - * - * mode - * Values: "r" (read only), "w" (writable) - * - * The read or write access permissions to the backing store to be - * granted to the frontend. - * - * params - * Values: string - * - * A free formatted string providing sufficient information for the - * backend driver to open the backing device. (e.g. the path to the - * file or block device representing the backing store.) - * - * type - * Values: "file", "phy", "tap" - * - * The type of the backing device/object. - * - *--------------------------------- Features --------------------------------- - * - * feature-barrier - * Values: 0/1 (boolean) - * Default Value: 0 - * - * A value of "1" indicates that the backend can process requests - * containing the BLKIF_OP_WRITE_BARRIER request opcode. Requests - * of this type may still be returned at any time with the - * BLKIF_RSP_EOPNOTSUPP result code. - * - * feature-flush-cache - * Values: 0/1 (boolean) - * Default Value: 0 - * - * A value of "1" indicates that the backend can process requests - * containing the BLKIF_OP_FLUSH_DISKCACHE request opcode. Requests - * of this type may still be returned at any time with the - * BLKIF_RSP_EOPNOTSUPP result code. - * - * feature-discard - * Values: 0/1 (boolean) - * Default Value: 0 - * - * A value of "1" indicates that the backend can process requests - * containing the BLKIF_OP_DISCARD request opcode. Requests - * of this type may still be returned at any time with the - * BLKIF_RSP_EOPNOTSUPP result code. - * - * feature-persistent - * Values: 0/1 (boolean) - * Default Value: 0 - * Notes: 7 - * - * A value of "1" indicates that the backend can keep the grants used - * by the frontend driver mapped, so the same set of grants should be - * used in all transactions. The maximum number of grants the backend - * can map persistently depends on the implementation, but ideally it - * should be RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST. Using this - * feature the backend doesn't need to unmap each grant, preventing - * costly TLB flushes. The backend driver should only map grants - * persistently if the frontend supports it. If a backend driver chooses - * to use the persistent protocol when the frontend doesn't support it, - * it will probably hit the maximum number of persistently mapped grants - * (due to the fact that the frontend won't be reusing the same grants), - * and fall back to non-persistent mode. Backend implementations may - * shrink or expand the number of persistently mapped grants without - * notifying the frontend depending on memory constraints (this might - * cause a performance degradation). - * - * If a backend driver wants to limit the maximum number of persistently - * mapped grants to a value less than RING_SIZE * - * BLKIF_MAX_SEGMENTS_PER_REQUEST a LRU strategy should be used to - * discard the grants that are less commonly used. Using a LRU in the - * backend driver paired with a LIFO queue in the frontend will - * allow us to have better performance in this scenario. - * - *----------------------- Request Transport Parameters ------------------------ - * - * max-ring-page-order - * Values: - * Default Value: 0 - * Notes: 1, 3 - * - * The maximum supported size of the request ring buffer in units of - * lb(machine pages). (e.g. 0 == 1 page, 1 = 2 pages, 2 == 4 pages, - * etc.). - * - * max-ring-pages - * Values: - * Default Value: 1 - * Notes: DEPRECATED, 2, 3 - * - * The maximum supported size of the request ring buffer in units of - * machine pages. The value must be a power of 2. - * - *------------------------- Backend Device Properties ------------------------- - * - * discard-alignment - * Values: - * Default Value: 0 - * Notes: 4, 5 - * - * The offset, in bytes from the beginning of the virtual block device, - * to the first, addressable, discard extent on the underlying device. - * - * discard-granularity - * Values: - * Default Value: <"sector-size"> - * Notes: 4 - * - * The size, in bytes, of the individually addressable discard extents - * of the underlying device. - * - * discard-secure - * Values: 0/1 (boolean) - * Default Value: 0 - * Notes: 10 - * - * A value of "1" indicates that the backend can process BLKIF_OP_DISCARD - * requests with the BLKIF_DISCARD_SECURE flag set. - * - * info - * Values: (bitmap) - * - * A collection of bit flags describing attributes of the backing - * device. The VDISK_* macros define the meaning of each bit - * location. - * - * sector-size - * Values: - * - * The logical sector size, in bytes, of the backend device. - * - * physical-sector-size - * Values: - * - * The physical sector size, in bytes, of the backend device. - * - * sectors - * Values: - * - * The size of the backend device, expressed in units of its logical - * sector size ("sector-size"). - * - ***************************************************************************** - * Frontend XenBus Nodes - ***************************************************************************** - * - *----------------------- Request Transport Parameters ----------------------- - * - * event-channel - * Values: - * - * The identifier of the Xen event channel used to signal activity - * in the ring buffer. - * - * ring-ref - * Values: - * Notes: 6 - * - * The Xen grant reference granting permission for the backend to map - * the sole page in a single page sized ring buffer. - * - * ring-ref%u - * Values: - * Notes: 6 - * - * For a frontend providing a multi-page ring, a "number of ring pages" - * sized list of nodes, each containing a Xen grant reference granting - * permission for the backend to map the page of the ring located - * at page index "%u". Page indexes are zero based. - * - * protocol - * Values: string (XEN_IO_PROTO_ABI_*) - * Default Value: XEN_IO_PROTO_ABI_NATIVE - * - * The machine ABI rules governing the format of all ring request and - * response structures. - * - * ring-page-order - * Values: - * Default Value: 0 - * Maximum Value: MAX(ffs(max-ring-pages) - 1, max-ring-page-order) - * Notes: 1, 3 - * - * The size of the frontend allocated request ring buffer in units - * of lb(machine pages). (e.g. 0 == 1 page, 1 = 2 pages, 2 == 4 pages, - * etc.). - * - * num-ring-pages - * Values: - * Default Value: 1 - * Maximum Value: MAX(max-ring-pages,(0x1 << max-ring-page-order)) - * Notes: DEPRECATED, 2, 3 - * - * The size of the frontend allocated request ring buffer in units of - * machine pages. The value must be a power of 2. - * - * feature-persistent - * Values: 0/1 (boolean) - * Default Value: 0 - * Notes: 7, 8, 9 - * - * A value of "1" indicates that the frontend will reuse the same grants - * for all transactions, allowing the backend to map them with write - * access (even when it should be read-only). If the frontend hits the - * maximum number of allowed persistently mapped grants, it can fallback - * to non persistent mode. This will cause a performance degradation, - * since the the backend driver will still try to map those grants - * persistently. Since the persistent grants protocol is compatible with - * the previous protocol, a frontend driver can choose to work in - * persistent mode even when the backend doesn't support it. - * - * It is recommended that the frontend driver stores the persistently - * mapped grants in a LIFO queue, so a subset of all persistently mapped - * grants gets used commonly. This is done in case the backend driver - * decides to limit the maximum number of persistently mapped grants - * to a value less than RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST. - * - *------------------------- Virtual Device Properties ------------------------- - * - * device-type - * Values: "disk", "cdrom", "floppy", etc. - * - * virtual-device - * Values: - * - * A value indicating the physical device to virtualize within the - * frontend's domain. (e.g. "The first ATA disk", "The third SCSI - * disk", etc.) - * - * See docs/misc/vbd-interface.txt for details on the format of this - * value. - * - * Notes - * ----- - * (1) Multi-page ring buffer scheme first developed in the Citrix XenServer - * PV drivers. - * (2) Multi-page ring buffer scheme first used in some RedHat distributions - * including a distribution deployed on certain nodes of the Amazon - * EC2 cluster. - * (3) Support for multi-page ring buffers was implemented independently, - * in slightly different forms, by both Citrix and RedHat/Amazon. - * For full interoperability, block front and backends should publish - * identical ring parameters, adjusted for unit differences, to the - * XenStore nodes used in both schemes. - * (4) Devices that support discard functionality may internally allocate space - * (discardable extents) in units that are larger than the exported logical - * block size. If the backing device has such discardable extents the - * backend should provide both discard-granularity and discard-alignment. - * Providing just one of the two may be considered an error by the frontend. - * Backends supporting discard should include discard-granularity and - * discard-alignment even if it supports discarding individual sectors. - * Frontends should assume discard-alignment == 0 and discard-granularity - * == sector size if these keys are missing. - * (5) The discard-alignment parameter allows a physical device to be - * partitioned into virtual devices that do not necessarily begin or - * end on a discardable extent boundary. - * (6) When there is only a single page allocated to the request ring, - * 'ring-ref' is used to communicate the grant reference for this - * page to the backend. When using a multi-page ring, the 'ring-ref' - * node is not created. Instead 'ring-ref0' - 'ring-refN' are used. - * (7) When using persistent grants data has to be copied from/to the page - * where the grant is currently mapped. The overhead of doing this copy - * however doesn't suppress the speed improvement of not having to unmap - * the grants. - * (8) The frontend driver has to allow the backend driver to map all grants - * with write access, even when they should be mapped read-only, since - * further requests may reuse these grants and require write permissions. - * (9) Linux implementation doesn't have a limit on the maximum number of - * grants that can be persistently mapped in the frontend driver, but - * due to the frontent driver implementation it should never be bigger - * than RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST. - *(10) The discard-secure property may be present and will be set to 1 if the - * backing device supports secure discard. - */ - -/* - * STATE DIAGRAMS - * - ***************************************************************************** - * Startup * - ***************************************************************************** - * - * Tool stack creates front and back nodes with state XenbusStateInitialising. - * - * Front Back - * ================================= ===================================== - * XenbusStateInitialising XenbusStateInitialising - * o Query virtual device o Query backend device identification - * properties. data. - * o Setup OS device instance. o Open and validate backend device. - * o Publish backend features and - * transport parameters. - * | - * | - * V - * XenbusStateInitWait - * - * o Query backend features and - * transport parameters. - * o Allocate and initialize the - * request ring. - * o Publish transport parameters - * that will be in effect during - * this connection. - * | - * | - * V - * XenbusStateInitialised - * - * o Query frontend transport parameters. - * o Connect to the request ring and - * event channel. - * o Publish backend device properties. - * | - * | - * V - * XenbusStateConnected - * - * o Query backend device properties. - * o Finalize OS virtual device - * instance. - * | - * | - * V - * XenbusStateConnected - * - * Note: Drivers that do not support any optional features, or the negotiation - * of transport parameters, can skip certain states in the state machine: - * - * o A frontend may transition to XenbusStateInitialised without - * waiting for the backend to enter XenbusStateInitWait. In this - * case, default transport parameters are in effect and any - * transport parameters published by the frontend must contain - * their default values. - * - * o A backend may transition to XenbusStateInitialised, bypassing - * XenbusStateInitWait, without waiting for the frontend to first - * enter the XenbusStateInitialised state. In this case, default - * transport parameters are in effect and any transport parameters - * published by the backend must contain their default values. - * - * Drivers that support optional features and/or transport parameter - * negotiation must tolerate these additional state transition paths. - * In general this means performing the work of any skipped state - * transition, if it has not already been performed, in addition to the - * work associated with entry into the current state. - */ - -/* - * REQUEST CODES. - */ -#define BLKIF_OP_READ 0 -#define BLKIF_OP_WRITE 1 -/* - * All writes issued prior to a request with the BLKIF_OP_WRITE_BARRIER - * operation code ("barrier request") must be completed prior to the - * execution of the barrier request. All writes issued after the barrier - * request must not execute until after the completion of the barrier request. - * - * Optional. See "feature-barrier" XenBus node documentation above. - */ -#define BLKIF_OP_WRITE_BARRIER 2 -/* - * Commit any uncommitted contents of the backing device's volatile cache - * to stable storage. - * - * Optional. See "feature-flush-cache" XenBus node documentation above. - */ -#define BLKIF_OP_FLUSH_DISKCACHE 3 -/* - * Used in SLES sources for device specific command packet - * contained within the request. Reserved for that purpose. - */ -#define BLKIF_OP_RESERVED_1 4 -/* - * Indicate to the backend device that a region of storage is no longer in - * use, and may be discarded at any time without impact to the client. If - * the BLKIF_DISCARD_SECURE flag is set on the request, all copies of the - * discarded region on the device must be rendered unrecoverable before the - * command returns. - * - * This operation is analogous to performing a trim (ATA) or unamp (SCSI), - * command on a native device. - * - * More information about trim/unmap operations can be found at: - * http://t13.org/Documents/UploadedDocuments/docs2008/ - * e07154r6-Data_Set_Management_Proposal_for_ATA-ACS2.doc - * http://www.seagate.com/staticfiles/support/disc/manuals/ - * Interface%20manuals/100293068c.pdf - * - * Optional. See "feature-discard", "discard-alignment", - * "discard-granularity", and "discard-secure" in the XenBus node - * documentation above. - */ -#define BLKIF_OP_DISCARD 5 - -/* - * Recognized if "feature-max-indirect-segments" in present in the backend - * xenbus info. The "feature-max-indirect-segments" node contains the maximum - * number of segments allowed by the backend per request. If the node is - * present, the frontend might use blkif_request_indirect structs in order to - * issue requests with more than BLKIF_MAX_SEGMENTS_PER_REQUEST (11). The - * maximum number of indirect segments is fixed by the backend, but the - * frontend can issue requests with any number of indirect segments as long as - * it's less than the number provided by the backend. The indirect_grefs field - * in blkif_request_indirect should be filled by the frontend with the - * grant references of the pages that are holding the indirect segments. - * These pages are filled with an array of blkif_request_segment that hold the - * information about the segments. The number of indirect pages to use is - * determined by the number of segments an indirect request contains. Every - * indirect page can contain a maximum of - * (PAGE_SIZE / sizeof(struct blkif_request_segment)) segments, so to - * calculate the number of indirect pages to use we have to do - * ceil(indirect_segments / (PAGE_SIZE / sizeof(struct blkif_request_segment))). - * - * If a backend does not recognize BLKIF_OP_INDIRECT, it should *not* - * create the "feature-max-indirect-segments" node! - */ -#define BLKIF_OP_INDIRECT 6 - -/* - * Maximum scatter/gather segments per request. - * This is carefully chosen so that sizeof(blkif_ring_t) <= PAGE_SIZE. - * NB. This could be 12 if the ring indexes weren't stored in the same page. - */ -#define BLKIF_MAX_SEGMENTS_PER_REQUEST 11 - -/* - * Maximum number of indirect pages to use per request. - */ -#define BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST 8 - -/* - * NB. first_sect and last_sect in blkif_request_segment, as well as - * sector_number in blkif_request, are always expressed in 512-byte units. - * However they must be properly aligned to the real sector size of the - * physical disk, which is reported in the "physical-sector-size" node in - * the backend xenbus info. Also the xenbus "sectors" node is expressed in - * 512-byte units. - */ -struct blkif_request_segment { - grant_ref_t gref; /* reference to I/O buffer frame */ - /* @first_sect: first sector in frame to transfer (inclusive). */ - /* @last_sect: last sector in frame to transfer (inclusive). */ - uint8_t first_sect, last_sect; -}; - -/* - * Starting ring element for any I/O request. - */ -struct blkif_request { - uint8_t operation; /* BLKIF_OP_??? */ - uint8_t nr_segments; /* number of segments */ - blkif_vdev_t handle; /* only for read/write requests */ - uint64_t id; /* private guest value, echoed in resp */ - blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ - struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; -}; -typedef struct blkif_request blkif_request_t; - -/* - * Cast to this structure when blkif_request.operation == BLKIF_OP_DISCARD - * sizeof(struct blkif_request_discard) <= sizeof(struct blkif_request) - */ -struct blkif_request_discard { - uint8_t operation; /* BLKIF_OP_DISCARD */ - uint8_t flag; /* BLKIF_DISCARD_SECURE or zero */ -#define BLKIF_DISCARD_SECURE (1<<0) /* ignored if discard-secure=0 */ - blkif_vdev_t handle; /* same as for read/write requests */ - uint64_t id; /* private guest value, echoed in resp */ - blkif_sector_t sector_number;/* start sector idx on disk */ - uint64_t nr_sectors; /* number of contiguous sectors to discard*/ -}; -typedef struct blkif_request_discard blkif_request_discard_t; - -struct blkif_request_indirect { - uint8_t operation; /* BLKIF_OP_INDIRECT */ - uint8_t indirect_op; /* BLKIF_OP_{READ/WRITE} */ - uint16_t nr_segments; /* number of segments */ - uint64_t id; /* private guest value, echoed in resp */ - blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ - blkif_vdev_t handle; /* same as for read/write requests */ - grant_ref_t indirect_grefs[BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST]; -#ifdef __i386__ - uint64_t pad; /* Make it 64 byte aligned on i386 */ -#endif -}; -typedef struct blkif_request_indirect blkif_request_indirect_t; - -struct blkif_response { - uint64_t id; /* copied from request */ - uint8_t operation; /* copied from request */ - int16_t status; /* BLKIF_RSP_??? */ -}; -typedef struct blkif_response blkif_response_t; - -/* - * STATUS RETURN CODES. - */ - /* Operation not supported (only happens on barrier writes). */ -#define BLKIF_RSP_EOPNOTSUPP -2 - /* Operation failed for some unspecified reason (-EIO). */ -#define BLKIF_RSP_ERROR -1 - /* Operation completed successfully. */ -#define BLKIF_RSP_OKAY 0 - -/* - * Generate blkif ring structures and types. - */ -DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response); - -#define VDISK_CDROM 0x1 -#define VDISK_REMOVABLE 0x2 -#define VDISK_READONLY 0x4 - -#endif /* __XEN_PUBLIC_IO_BLKIF_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/io/console.h b/include/xen/io/console.h deleted file mode 100644 index 649601896..000000000 --- a/include/xen/io/console.h +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************** - * console.h - * - * Console I/O interface for Xen guest OSes. - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2005, Keir Fraser - */ - -#ifndef __XEN_PUBLIC_IO_CONSOLE_H__ -#define __XEN_PUBLIC_IO_CONSOLE_H__ - -typedef uint32_t XENCONS_RING_IDX; - -#define MASK_XENCONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1)) - -struct xencons_interface { - char in[1024]; - char out[2048]; - XENCONS_RING_IDX in_cons, in_prod; - XENCONS_RING_IDX out_cons, out_prod; -}; - -#endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/io/protocols.h b/include/xen/io/protocols.h deleted file mode 100644 index d05c40505..000000000 --- a/include/xen/io/protocols.h +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************** - * protocols.h - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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 __XEN_PROTOCOLS_H__ -#define __XEN_PROTOCOLS_H__ - -#define XEN_IO_PROTO_ABI_X86_32 "x86_32-abi" -#define XEN_IO_PROTO_ABI_X86_64 "x86_64-abi" -#define XEN_IO_PROTO_ABI_ARM "arm-abi" - -#if defined(__i386__) -# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_32 -#elif defined(__x86_64__) -# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_64 -#elif defined(__arm__) || defined(__aarch64__) -# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_ARM -#else -# error arch fixup needed here -#endif - -#endif diff --git a/include/xen/io/ring.h b/include/xen/io/ring.h deleted file mode 100644 index 91b3092e7..000000000 --- a/include/xen/io/ring.h +++ /dev/null @@ -1,312 +0,0 @@ -/****************************************************************************** - * ring.h - * - * Shared producer-consumer ring macros. - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Tim Deegan and Andrew Warfield November 2004. - */ - -#ifndef __XEN_PUBLIC_IO_RING_H__ -#define __XEN_PUBLIC_IO_RING_H__ - -#include "../xen-compat.h" - -#if __XEN_INTERFACE_VERSION__ < 0x00030208 -#define xen_mb() mb() -#define xen_rmb() rmb() -#define xen_wmb() wmb() -#endif - -typedef unsigned int RING_IDX; - -/* Round a 32-bit unsigned constant down to the nearest power of two. */ -#define __RD2(_x) (((_x) & 0x00000002) ? 0x2 : ((_x) & 0x1)) -#define __RD4(_x) (((_x) & 0x0000000c) ? __RD2((_x)>>2)<<2 : __RD2(_x)) -#define __RD8(_x) (((_x) & 0x000000f0) ? __RD4((_x)>>4)<<4 : __RD4(_x)) -#define __RD16(_x) (((_x) & 0x0000ff00) ? __RD8((_x)>>8)<<8 : __RD8(_x)) -#define __RD32(_x) (((_x) & 0xffff0000) ? __RD16((_x)>>16)<<16 : __RD16(_x)) - -/* - * Calculate size of a shared ring, given the total available space for the - * ring and indexes (_sz), and the name tag of the request/response structure. - * A ring contains as many entries as will fit, rounded down to the nearest - * power of two (so we can mask with (size-1) to loop around). - */ -#define __CONST_RING_SIZE(_s, _sz) \ - (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \ - sizeof(((struct _s##_sring *)0)->ring[0]))) -/* - * The same for passing in an actual pointer instead of a name tag. - */ -#define __RING_SIZE(_s, _sz) \ - (__RD32(((_sz) - (long)(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0]))) - -/* - * Macros to make the correct C datatypes for a new kind of ring. - * - * To make a new ring datatype, you need to have two message structures, - * let's say request_t, and response_t already defined. - * - * In a header where you want the ring datatype declared, you then do: - * - * DEFINE_RING_TYPES(mytag, request_t, response_t); - * - * These expand out to give you a set of types, as you can see below. - * The most important of these are: - * - * mytag_sring_t - The shared ring. - * mytag_front_ring_t - The 'front' half of the ring. - * mytag_back_ring_t - The 'back' half of the ring. - * - * To initialize a ring in your code you need to know the location and size - * of the shared memory area (PAGE_SIZE, for instance). To initialise - * the front half: - * - * mytag_front_ring_t front_ring; - * SHARED_RING_INIT((mytag_sring_t *)shared_page); - * FRONT_RING_INIT(&front_ring, (mytag_sring_t *)shared_page, PAGE_SIZE); - * - * Initializing the back follows similarly (note that only the front - * initializes the shared ring): - * - * mytag_back_ring_t back_ring; - * BACK_RING_INIT(&back_ring, (mytag_sring_t *)shared_page, PAGE_SIZE); - */ - -#define DEFINE_RING_TYPES(__name, __req_t, __rsp_t) \ - \ -/* Shared ring entry */ \ -union __name##_sring_entry { \ - __req_t req; \ - __rsp_t rsp; \ -}; \ - \ -/* Shared ring page */ \ -struct __name##_sring { \ - RING_IDX req_prod, req_event; \ - RING_IDX rsp_prod, rsp_event; \ - union { \ - struct { \ - uint8_t smartpoll_active; \ - } netif; \ - struct { \ - uint8_t msg; \ - } tapif_user; \ - uint8_t pvt_pad[4]; \ - } private; \ - uint8_t __pad[44]; \ - union __name##_sring_entry ring[1]; /* variable-length */ \ -}; \ - \ -/* "Front" end's private variables */ \ -struct __name##_front_ring { \ - RING_IDX req_prod_pvt; \ - RING_IDX rsp_cons; \ - unsigned int nr_ents; \ - struct __name##_sring *sring; \ -}; \ - \ -/* "Back" end's private variables */ \ -struct __name##_back_ring { \ - RING_IDX rsp_prod_pvt; \ - RING_IDX req_cons; \ - unsigned int nr_ents; \ - struct __name##_sring *sring; \ -}; \ - \ -/* Syntactic sugar */ \ -typedef struct __name##_sring __name##_sring_t; \ -typedef struct __name##_front_ring __name##_front_ring_t; \ -typedef struct __name##_back_ring __name##_back_ring_t - -/* - * Macros for manipulating rings. - * - * FRONT_RING_whatever works on the "front end" of a ring: here - * requests are pushed on to the ring and responses taken off it. - * - * BACK_RING_whatever works on the "back end" of a ring: here - * requests are taken off the ring and responses put on. - * - * N.B. these macros do NO INTERLOCKS OR FLOW CONTROL. - * This is OK in 1-for-1 request-response situations where the - * requestor (front end) never has more than RING_SIZE()-1 - * outstanding requests. - */ - -/* Initialising empty rings */ -#define SHARED_RING_INIT(_s) do { \ - (_s)->req_prod = (_s)->rsp_prod = 0; \ - (_s)->req_event = (_s)->rsp_event = 1; \ - (void)memset((_s)->private.pvt_pad, 0, sizeof((_s)->private.pvt_pad)); \ - (void)memset((_s)->__pad, 0, sizeof((_s)->__pad)); \ -} while(0) - -#define FRONT_RING_INIT(_r, _s, __size) do { \ - (_r)->req_prod_pvt = 0; \ - (_r)->rsp_cons = 0; \ - (_r)->nr_ents = __RING_SIZE(_s, __size); \ - (_r)->sring = (_s); \ -} while (0) - -#define BACK_RING_INIT(_r, _s, __size) do { \ - (_r)->rsp_prod_pvt = 0; \ - (_r)->req_cons = 0; \ - (_r)->nr_ents = __RING_SIZE(_s, __size); \ - (_r)->sring = (_s); \ -} while (0) - -/* How big is this ring? */ -#define RING_SIZE(_r) \ - ((_r)->nr_ents) - -/* Number of free requests (for use on front side only). */ -#define RING_FREE_REQUESTS(_r) \ - (RING_SIZE(_r) - ((_r)->req_prod_pvt - (_r)->rsp_cons)) - -/* Test if there is an empty slot available on the front ring. - * (This is only meaningful from the front. ) - */ -#define RING_FULL(_r) \ - (RING_FREE_REQUESTS(_r) == 0) - -/* Test if there are outstanding messages to be processed on a ring. */ -#define RING_HAS_UNCONSUMED_RESPONSES(_r) \ - ((_r)->sring->rsp_prod - (_r)->rsp_cons) - -#ifdef __GNUC__ -#define RING_HAS_UNCONSUMED_REQUESTS(_r) ({ \ - unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \ - unsigned int rsp = RING_SIZE(_r) - \ - ((_r)->req_cons - (_r)->rsp_prod_pvt); \ - req < rsp ? req : rsp; \ -}) -#else -/* Same as above, but without the nice GCC ({ ... }) syntax. */ -#define RING_HAS_UNCONSUMED_REQUESTS(_r) \ - ((((_r)->sring->req_prod - (_r)->req_cons) < \ - (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) ? \ - ((_r)->sring->req_prod - (_r)->req_cons) : \ - (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) -#endif - -/* Direct access to individual ring elements, by index. */ -#define RING_GET_REQUEST(_r, _idx) \ - (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req)) - -#define RING_GET_RESPONSE(_r, _idx) \ - (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp)) - -/* Loop termination condition: Would the specified index overflow the ring? */ -#define RING_REQUEST_CONS_OVERFLOW(_r, _cons) \ - (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r)) - -/* Ill-behaved frontend determination: Can there be this many requests? */ -#define RING_REQUEST_PROD_OVERFLOW(_r, _prod) \ - (((_prod) - (_r)->rsp_prod_pvt) > RING_SIZE(_r)) - -#define RING_PUSH_REQUESTS(_r) do { \ - xen_wmb(); /* back sees requests /before/ updated producer index */ \ - (_r)->sring->req_prod = (_r)->req_prod_pvt; \ -} while (0) - -#define RING_PUSH_RESPONSES(_r) do { \ - xen_wmb(); /* front sees resps /before/ updated producer index */ \ - (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt; \ -} while (0) - -/* - * Notification hold-off (req_event and rsp_event): - * - * When queueing requests or responses on a shared ring, it may not always be - * necessary to notify the remote end. For example, if requests are in flight - * in a backend, the front may be able to queue further requests without - * notifying the back (if the back checks for new requests when it queues - * responses). - * - * When enqueuing requests or responses: - * - * Use RING_PUSH_{REQUESTS,RESPONSES}_AND_CHECK_NOTIFY(). The second argument - * is a boolean return value. True indicates that the receiver requires an - * asynchronous notification. - * - * After dequeuing requests or responses (before sleeping the connection): - * - * Use RING_FINAL_CHECK_FOR_REQUESTS() or RING_FINAL_CHECK_FOR_RESPONSES(). - * The second argument is a boolean return value. True indicates that there - * are pending messages on the ring (i.e., the connection should not be put - * to sleep). - * - * These macros will set the req_event/rsp_event field to trigger a - * notification on the very next message that is enqueued. If you want to - * create batches of work (i.e., only receive a notification after several - * messages have been enqueued) then you will need to create a customised - * version of the FINAL_CHECK macro in your own code, which sets the event - * field appropriately. - */ - -#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify) do { \ - RING_IDX __old = (_r)->sring->req_prod; \ - RING_IDX __new = (_r)->req_prod_pvt; \ - xen_wmb(); /* back sees requests /before/ updated producer index */ \ - (_r)->sring->req_prod = __new; \ - xen_mb(); /* back sees new requests /before/ we check req_event */ \ - (_notify) = ((RING_IDX)(__new - (_r)->sring->req_event) < \ - (RING_IDX)(__new - __old)); \ -} while (0) - -#define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify) do { \ - RING_IDX __old = (_r)->sring->rsp_prod; \ - RING_IDX __new = (_r)->rsp_prod_pvt; \ - xen_wmb(); /* front sees resps /before/ updated producer index */ \ - (_r)->sring->rsp_prod = __new; \ - xen_mb(); /* front sees new resps /before/ we check rsp_event */ \ - (_notify) = ((RING_IDX)(__new - (_r)->sring->rsp_event) < \ - (RING_IDX)(__new - __old)); \ -} while (0) - -#define RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do) do { \ - (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \ - if (_work_to_do) break; \ - (_r)->sring->req_event = (_r)->req_cons + 1; \ - xen_mb(); \ - (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \ -} while (0) - -#define RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do) do { \ - (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \ - if (_work_to_do) break; \ - (_r)->sring->rsp_event = (_r)->rsp_cons + 1; \ - xen_mb(); \ - (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \ -} while (0) - -#endif /* __XEN_PUBLIC_IO_RING_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/io/xenbus.h b/include/xen/io/xenbus.h deleted file mode 100644 index 927f9db55..000000000 --- a/include/xen/io/xenbus.h +++ /dev/null @@ -1,80 +0,0 @@ -/***************************************************************************** - * xenbus.h - * - * Xenbus protocol details. - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (C) 2005 XenSource Ltd. - */ - -#ifndef _XEN_PUBLIC_IO_XENBUS_H -#define _XEN_PUBLIC_IO_XENBUS_H - -/* - * The state of either end of the Xenbus, i.e. the current communication - * status of initialisation across the bus. States here imply nothing about - * the state of the connection between the driver and the kernel's device - * layers. - */ -enum xenbus_state { - XenbusStateUnknown = 0, - - XenbusStateInitialising = 1, - - /* - * InitWait: Finished early initialisation but waiting for information - * from the peer or hotplug scripts. - */ - XenbusStateInitWait = 2, - - /* - * Initialised: Waiting for a connection from the peer. - */ - XenbusStateInitialised = 3, - - XenbusStateConnected = 4, - - /* - * Closing: The device is being closed due to an error or an unplug event. - */ - XenbusStateClosing = 5, - - XenbusStateClosed = 6, - - /* - * Reconfiguring: The device is being reconfigured. - */ - XenbusStateReconfiguring = 7, - - XenbusStateReconfigured = 8 -}; -typedef enum xenbus_state XenbusState; - -#endif /* _XEN_PUBLIC_IO_XENBUS_H */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/io/xs_wire.h b/include/xen/io/xs_wire.h deleted file mode 100644 index 585f0c8f5..000000000 --- a/include/xen/io/xs_wire.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Details of the "wire" protocol between Xen Store Daemon and client - * library or guest kernel. - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (C) 2005 Rusty Russell IBM Corporation - */ - -#ifndef _XS_WIRE_H -#define _XS_WIRE_H - -enum xsd_sockmsg_type -{ - XS_DEBUG, - XS_DIRECTORY, - XS_READ, - XS_GET_PERMS, - XS_WATCH, - XS_UNWATCH, - XS_TRANSACTION_START, - XS_TRANSACTION_END, - XS_INTRODUCE, - XS_RELEASE, - XS_GET_DOMAIN_PATH, - XS_WRITE, - XS_MKDIR, - XS_RM, - XS_SET_PERMS, - XS_WATCH_EVENT, - XS_ERROR, - XS_IS_DOMAIN_INTRODUCED, - XS_RESUME, - XS_SET_TARGET, - XS_RESTRICT, - XS_RESET_WATCHES -}; - -#define XS_WRITE_NONE "NONE" -#define XS_WRITE_CREATE "CREATE" -#define XS_WRITE_CREATE_EXCL "CREATE|EXCL" - -/* We hand errors as strings, for portability. */ -struct xsd_errors -{ - int errnum; - const char *errstring; -}; -#ifdef EINVAL -#define XSD_ERROR(x) { x, #x } -/* LINTED: static unused */ -static struct xsd_errors xsd_errors[] -#if defined(__GNUC__) -__attribute__((unused)) -#endif - = { - XSD_ERROR(EINVAL), - XSD_ERROR(EACCES), - XSD_ERROR(EEXIST), - XSD_ERROR(EISDIR), - XSD_ERROR(ENOENT), - XSD_ERROR(ENOMEM), - XSD_ERROR(ENOSPC), - XSD_ERROR(EIO), - XSD_ERROR(ENOTEMPTY), - XSD_ERROR(ENOSYS), - XSD_ERROR(EROFS), - XSD_ERROR(EBUSY), - XSD_ERROR(EAGAIN), - XSD_ERROR(EISCONN), - XSD_ERROR(E2BIG) -}; -#endif - -struct xsd_sockmsg -{ - uint32_t type; /* XS_??? */ - uint32_t req_id;/* Request identifier, echoed in daemon's response. */ - uint32_t tx_id; /* Transaction id (0 if not related to a transaction). */ - uint32_t len; /* Length of data following this. */ - - /* Generally followed by nul-terminated string(s). */ -}; - -enum xs_watch_type -{ - XS_WATCH_PATH = 0, - XS_WATCH_TOKEN -}; - -/* - * `incontents 150 xenstore_struct XenStore wire protocol. - * - * Inter-domain shared memory communications. */ -#define XENSTORE_RING_SIZE 1024 -typedef uint32_t XENSTORE_RING_IDX; -#define MASK_XENSTORE_IDX(idx) ((idx) & (XENSTORE_RING_SIZE-1)) -struct xenstore_domain_interface { - char req[XENSTORE_RING_SIZE]; /* Requests to xenstore daemon. */ - char rsp[XENSTORE_RING_SIZE]; /* Replies and async watch events. */ - XENSTORE_RING_IDX req_cons, req_prod; - XENSTORE_RING_IDX rsp_cons, rsp_prod; -}; - -/* Violating this is very bad. See docs/misc/xenstore.txt. */ -#define XENSTORE_PAYLOAD_MAX 4096 - -/* Violating these just gets you an error back */ -#define XENSTORE_ABS_PATH_MAX 3072 -#define XENSTORE_REL_PATH_MAX 2048 - -#endif /* _XS_WIRE_H */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/memory.h b/include/xen/memory.h deleted file mode 100644 index 20deef5cb..000000000 --- a/include/xen/memory.h +++ /dev/null @@ -1,665 +0,0 @@ -/****************************************************************************** - * memory.h - * - * Memory reservation and information. - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2005, Keir Fraser - */ - -#ifndef __XEN_PUBLIC_MEMORY_H__ -#define __XEN_PUBLIC_MEMORY_H__ - -#include "xen.h" -#include "physdev.h" - -/* - * Increase or decrease the specified domain's memory reservation. Returns the - * number of extents successfully allocated or freed. - * arg == addr of struct xen_memory_reservation. - */ -#define XENMEM_increase_reservation 0 -#define XENMEM_decrease_reservation 1 -#define XENMEM_populate_physmap 6 - -#if __XEN_INTERFACE_VERSION__ >= 0x00030209 -/* - * Maximum # bits addressable by the user of the allocated region (e.g., I/O - * devices often have a 32-bit limitation even in 64-bit systems). If zero - * then the user has no addressing restriction. This field is not used by - * XENMEM_decrease_reservation. - */ -#define XENMEMF_address_bits(x) (x) -#define XENMEMF_get_address_bits(x) ((x) & 0xffu) -/* NUMA node to allocate from. */ -#define XENMEMF_node(x) (((x) + 1) << 8) -#define XENMEMF_get_node(x) ((((x) >> 8) - 1) & 0xffu) -/* Flag to populate physmap with populate-on-demand entries */ -#define XENMEMF_populate_on_demand (1<<16) -/* Flag to request allocation only from the node specified */ -#define XENMEMF_exact_node_request (1<<17) -#define XENMEMF_exact_node(n) (XENMEMF_node(n) | XENMEMF_exact_node_request) -/* Flag to indicate the node specified is virtual node */ -#define XENMEMF_vnode (1<<18) -#endif - -struct xen_memory_reservation { - - /* - * XENMEM_increase_reservation: - * OUT: MFN (*not* GMFN) bases of extents that were allocated - * XENMEM_decrease_reservation: - * IN: GMFN bases of extents to free - * XENMEM_populate_physmap: - * IN: GPFN bases of extents to populate with memory - * OUT: GMFN bases of extents that were allocated - * (NB. This command also updates the mach_to_phys translation table) - * XENMEM_claim_pages: - * IN: must be zero - */ - XEN_GUEST_HANDLE(xen_pfn_t) extent_start; - - /* Number of extents, and size/alignment of each (2^extent_order pages). */ - xen_ulong_t nr_extents; - unsigned int extent_order; - -#if __XEN_INTERFACE_VERSION__ >= 0x00030209 - /* XENMEMF flags. */ - unsigned int mem_flags; -#else - unsigned int address_bits; -#endif - - /* - * Domain whose reservation is being changed. - * Unprivileged domains can specify only DOMID_SELF. - */ - domid_t domid; -}; -typedef struct xen_memory_reservation xen_memory_reservation_t; -DEFINE_XEN_GUEST_HANDLE(xen_memory_reservation_t); - -/* - * An atomic exchange of memory pages. If return code is zero then - * @out.extent_list provides GMFNs of the newly-allocated memory. - * Returns zero on complete success, otherwise a negative error code. - * On complete success then always @nr_exchanged == @in.nr_extents. - * On partial success @nr_exchanged indicates how much work was done. - * - * Note that only PV guests can use this operation. - */ -#define XENMEM_exchange 11 -struct xen_memory_exchange { - /* - * [IN] Details of memory extents to be exchanged (GMFN bases). - * Note that @in.address_bits is ignored and unused. - */ - struct xen_memory_reservation in; - - /* - * [IN/OUT] Details of new memory extents. - * We require that: - * 1. @in.domid == @out.domid - * 2. @in.nr_extents << @in.extent_order == - * @out.nr_extents << @out.extent_order - * 3. @in.extent_start and @out.extent_start lists must not overlap - * 4. @out.extent_start lists GPFN bases to be populated - * 5. @out.extent_start is overwritten with allocated GMFN bases - */ - struct xen_memory_reservation out; - - /* - * [OUT] Number of input extents that were successfully exchanged: - * 1. The first @nr_exchanged input extents were successfully - * deallocated. - * 2. The corresponding first entries in the output extent list correctly - * indicate the GMFNs that were successfully exchanged. - * 3. All other input and output extents are untouched. - * 4. If not all input exents are exchanged then the return code of this - * command will be non-zero. - * 5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER! - */ - xen_ulong_t nr_exchanged; -}; -typedef struct xen_memory_exchange xen_memory_exchange_t; -DEFINE_XEN_GUEST_HANDLE(xen_memory_exchange_t); - -/* - * Returns the maximum machine frame number of mapped RAM in this system. - * This command always succeeds (it never returns an error code). - * arg == NULL. - */ -#define XENMEM_maximum_ram_page 2 - -/* - * Returns the current or maximum memory reservation, in pages, of the - * specified domain (may be DOMID_SELF). Returns -ve errcode on failure. - * arg == addr of domid_t. - */ -#define XENMEM_current_reservation 3 -#define XENMEM_maximum_reservation 4 - -/* - * Returns the maximum GPFN in use by the guest, or -ve errcode on failure. - */ -#define XENMEM_maximum_gpfn 14 - -/* - * Returns a list of MFN bases of 2MB extents comprising the machine_to_phys - * mapping table. Architectures which do not have a m2p table do not implement - * this command. - * arg == addr of xen_machphys_mfn_list_t. - */ -#define XENMEM_machphys_mfn_list 5 -struct xen_machphys_mfn_list { - /* - * Size of the 'extent_start' array. Fewer entries will be filled if the - * machphys table is smaller than max_extents * 2MB. - */ - unsigned int max_extents; - - /* - * Pointer to buffer to fill with list of extent starts. If there are - * any large discontiguities in the machine address space, 2MB gaps in - * the machphys table will be represented by an MFN base of zero. - */ - XEN_GUEST_HANDLE(xen_pfn_t) extent_start; - - /* - * Number of extents written to the above array. This will be smaller - * than 'max_extents' if the machphys table is smaller than max_e * 2MB. - */ - unsigned int nr_extents; -}; -typedef struct xen_machphys_mfn_list xen_machphys_mfn_list_t; -DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn_list_t); - -/* - * For a compat caller, this is identical to XENMEM_machphys_mfn_list. - * - * For a non compat caller, this functions similarly to - * XENMEM_machphys_mfn_list, but returns the mfns making up the compatibility - * m2p table. - */ -#define XENMEM_machphys_compat_mfn_list 25 - -/* - * Returns the location in virtual address space of the machine_to_phys - * mapping table. Architectures which do not have a m2p table, or which do not - * map it by default into guest address space, do not implement this command. - * arg == addr of xen_machphys_mapping_t. - */ -#define XENMEM_machphys_mapping 12 -struct xen_machphys_mapping { - xen_ulong_t v_start, v_end; /* Start and end virtual addresses. */ - xen_ulong_t max_mfn; /* Maximum MFN that can be looked up. */ -}; -typedef struct xen_machphys_mapping xen_machphys_mapping_t; -DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t); - -/* Source mapping space. */ -/* ` enum phys_map_space { */ -#define XENMAPSPACE_shared_info 0 /* shared info page */ -#define XENMAPSPACE_grant_table 1 /* grant table page */ -#define XENMAPSPACE_gmfn 2 /* GMFN */ -#define XENMAPSPACE_gmfn_range 3 /* GMFN range, XENMEM_add_to_physmap only. */ -#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom, - * XENMEM_add_to_physmap_batch only. */ -#define XENMAPSPACE_dev_mmio 5 /* device mmio region - ARM only; the region is mapped in - Stage-2 using the Normal Memory - Inner/Outer Write-Back Cacheable - memory attribute. */ -/* ` } */ - -/* - * Sets the GPFN at which a particular page appears in the specified guest's - * pseudophysical address space. - * arg == addr of xen_add_to_physmap_t. - */ -#define XENMEM_add_to_physmap 7 -struct xen_add_to_physmap { - /* Which domain to change the mapping for. */ - domid_t domid; - - /* Number of pages to go through for gmfn_range */ - uint16_t size; - - unsigned int space; /* => enum phys_map_space */ - -#define XENMAPIDX_grant_table_status 0x80000000 - - /* Index into space being mapped. */ - xen_ulong_t idx; - - /* GPFN in domid where the source mapping page should appear. */ - xen_pfn_t gpfn; -}; -typedef struct xen_add_to_physmap xen_add_to_physmap_t; -DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t); - -/* A batched version of add_to_physmap. */ -#define XENMEM_add_to_physmap_batch 23 -struct xen_add_to_physmap_batch { - /* IN */ - /* Which domain to change the mapping for. */ - domid_t domid; - uint16_t space; /* => enum phys_map_space */ - - /* Number of pages to go through */ - uint16_t size; - -#if __XEN_INTERFACE_VERSION__ < 0x00040700 - domid_t foreign_domid; /* IFF gmfn_foreign. Should be 0 for other spaces. */ -#else - union xen_add_to_physmap_batch_extra { - domid_t foreign_domid; /* gmfn_foreign */ - uint16_t res0; /* All the other spaces. Should be 0 */ - } u; -#endif - - /* Indexes into space being mapped. */ - XEN_GUEST_HANDLE(xen_ulong_t) idxs; - - /* GPFN in domid where the source mapping page should appear. */ - XEN_GUEST_HANDLE(xen_pfn_t) gpfns; - - /* OUT */ - - /* Per index error code. */ - XEN_GUEST_HANDLE(int) errs; -}; -typedef struct xen_add_to_physmap_batch xen_add_to_physmap_batch_t; -DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_batch_t); - -#if __XEN_INTERFACE_VERSION__ < 0x00040400 -#define XENMEM_add_to_physmap_range XENMEM_add_to_physmap_batch -#define xen_add_to_physmap_range xen_add_to_physmap_batch -typedef struct xen_add_to_physmap_batch xen_add_to_physmap_range_t; -DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_range_t); -#endif - -/* - * Unmaps the page appearing at a particular GPFN from the specified guest's - * pseudophysical address space. - * arg == addr of xen_remove_from_physmap_t. - */ -#define XENMEM_remove_from_physmap 15 -struct xen_remove_from_physmap { - /* Which domain to change the mapping for. */ - domid_t domid; - - /* GPFN of the current mapping of the page. */ - xen_pfn_t gpfn; -}; -typedef struct xen_remove_from_physmap xen_remove_from_physmap_t; -DEFINE_XEN_GUEST_HANDLE(xen_remove_from_physmap_t); - -/*** REMOVED ***/ -/*#define XENMEM_translate_gpfn_list 8*/ - -/* - * Returns the pseudo-physical memory map as it was when the domain - * was started (specified by XENMEM_set_memory_map). - * arg == addr of xen_memory_map_t. - */ -#define XENMEM_memory_map 9 -struct xen_memory_map { - /* - * On call the number of entries which can be stored in buffer. On - * return the number of entries which have been stored in - * buffer. - */ - unsigned int nr_entries; - - /* - * Entries in the buffer are in the same format as returned by the - * BIOS INT 0x15 EAX=0xE820 call. - */ - XEN_GUEST_HANDLE(void) buffer; -}; -typedef struct xen_memory_map xen_memory_map_t; -DEFINE_XEN_GUEST_HANDLE(xen_memory_map_t); - -/* - * Returns the real physical memory map. Passes the same structure as - * XENMEM_memory_map. - * Specifying buffer as NULL will return the number of entries required - * to store the complete memory map. - * arg == addr of xen_memory_map_t. - */ -#define XENMEM_machine_memory_map 10 - -/* - * Set the pseudo-physical memory map of a domain, as returned by - * XENMEM_memory_map. - * arg == addr of xen_foreign_memory_map_t. - */ -#define XENMEM_set_memory_map 13 -struct xen_foreign_memory_map { - domid_t domid; - struct xen_memory_map map; -}; -typedef struct xen_foreign_memory_map xen_foreign_memory_map_t; -DEFINE_XEN_GUEST_HANDLE(xen_foreign_memory_map_t); - -#define XENMEM_set_pod_target 16 -#define XENMEM_get_pod_target 17 -struct xen_pod_target { - /* IN */ - uint64_t target_pages; - /* OUT */ - uint64_t tot_pages; - uint64_t pod_cache_pages; - uint64_t pod_entries; - /* IN */ - domid_t domid; -}; -typedef struct xen_pod_target xen_pod_target_t; - -#if defined(__XEN__) || defined(__XEN_TOOLS__) - -#ifndef uint64_aligned_t -#define uint64_aligned_t uint64_t -#endif - -/* - * Get the number of MFNs saved through memory sharing. - * The call never fails. - */ -#define XENMEM_get_sharing_freed_pages 18 -#define XENMEM_get_sharing_shared_pages 19 - -#define XENMEM_paging_op 20 -#define XENMEM_paging_op_nominate 0 -#define XENMEM_paging_op_evict 1 -#define XENMEM_paging_op_prep 2 - -struct xen_mem_paging_op { - uint8_t op; /* XENMEM_paging_op_* */ - domid_t domain; - - /* PAGING_PREP IN: buffer to immediately fill page in */ - uint64_aligned_t buffer; - /* Other OPs */ - uint64_aligned_t gfn; /* IN: gfn of page being operated on */ -}; -typedef struct xen_mem_paging_op xen_mem_paging_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_mem_paging_op_t); - -#define XENMEM_access_op 21 -#define XENMEM_access_op_set_access 0 -#define XENMEM_access_op_get_access 1 -/* - * XENMEM_access_op_enable_emulate and XENMEM_access_op_disable_emulate are - * currently unused, but since they have been in use please do not reuse them. - * - * #define XENMEM_access_op_enable_emulate 2 - * #define XENMEM_access_op_disable_emulate 3 - */ -#define XENMEM_access_op_set_access_multi 4 - -typedef enum { - XENMEM_access_n, - XENMEM_access_r, - XENMEM_access_w, - XENMEM_access_rw, - XENMEM_access_x, - XENMEM_access_rx, - XENMEM_access_wx, - XENMEM_access_rwx, - /* - * Page starts off as r-x, but automatically - * change to r-w on a write - */ - XENMEM_access_rx2rw, - /* - * Log access: starts off as n, automatically - * goes to rwx, generating an event without - * pausing the vcpu - */ - XENMEM_access_n2rwx, - /* Take the domain default */ - XENMEM_access_default -} xenmem_access_t; - -struct xen_mem_access_op { - /* XENMEM_access_op_* */ - uint8_t op; - /* xenmem_access_t */ - uint8_t access; - domid_t domid; - /* - * Number of pages for set op (or size of pfn_list for - * XENMEM_access_op_set_access_multi) - * Ignored on setting default access and other ops - */ - uint32_t nr; - /* - * First pfn for set op - * pfn for get op - * ~0ull is used to set and get the default access for pages - */ - uint64_aligned_t pfn; - /* - * List of pfns to set access for - * Used only with XENMEM_access_op_set_access_multi - */ - XEN_GUEST_HANDLE(const_uint64) pfn_list; - /* - * Corresponding list of access settings for pfn_list - * Used only with XENMEM_access_op_set_access_multi - */ - XEN_GUEST_HANDLE(const_uint8) access_list; -}; -typedef struct xen_mem_access_op xen_mem_access_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_mem_access_op_t); - -#define XENMEM_sharing_op 22 -#define XENMEM_sharing_op_nominate_gfn 0 -#define XENMEM_sharing_op_nominate_gref 1 -#define XENMEM_sharing_op_share 2 -#define XENMEM_sharing_op_debug_gfn 3 -#define XENMEM_sharing_op_debug_mfn 4 -#define XENMEM_sharing_op_debug_gref 5 -#define XENMEM_sharing_op_add_physmap 6 -#define XENMEM_sharing_op_audit 7 -#define XENMEM_sharing_op_range_share 8 - -#define XENMEM_SHARING_OP_S_HANDLE_INVALID (-10) -#define XENMEM_SHARING_OP_C_HANDLE_INVALID (-9) - -/* The following allows sharing of grant refs. This is useful - * for sharing utilities sitting as "filters" in IO backends - * (e.g. memshr + blktap(2)). The IO backend is only exposed - * to grant references, and this allows sharing of the grefs */ -#define XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG (xen_mk_ullong(1) << 62) - -#define XENMEM_SHARING_OP_FIELD_MAKE_GREF(field, val) \ - (field) = (XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG | val) -#define XENMEM_SHARING_OP_FIELD_IS_GREF(field) \ - ((field) & XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG) -#define XENMEM_SHARING_OP_FIELD_GET_GREF(field) \ - ((field) & (~XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG)) - -struct xen_mem_sharing_op { - uint8_t op; /* XENMEM_sharing_op_* */ - domid_t domain; - - union { - struct mem_sharing_op_nominate { /* OP_NOMINATE_xxx */ - union { - uint64_aligned_t gfn; /* IN: gfn to nominate */ - uint32_t grant_ref; /* IN: grant ref to nominate */ - } u; - uint64_aligned_t handle; /* OUT: the handle */ - } nominate; - struct mem_sharing_op_share { /* OP_SHARE/ADD_PHYSMAP */ - uint64_aligned_t source_gfn; /* IN: the gfn of the source page */ - uint64_aligned_t source_handle; /* IN: handle to the source page */ - uint64_aligned_t client_gfn; /* IN: the client gfn */ - uint64_aligned_t client_handle; /* IN: handle to the client page */ - domid_t client_domain; /* IN: the client domain id */ - } share; - struct mem_sharing_op_range { /* OP_RANGE_SHARE */ - uint64_aligned_t first_gfn; /* IN: the first gfn */ - uint64_aligned_t last_gfn; /* IN: the last gfn */ - uint64_aligned_t opaque; /* Must be set to 0 */ - domid_t client_domain; /* IN: the client domain id */ - uint16_t _pad[3]; /* Must be set to 0 */ - } range; - struct mem_sharing_op_debug { /* OP_DEBUG_xxx */ - union { - uint64_aligned_t gfn; /* IN: gfn to debug */ - uint64_aligned_t mfn; /* IN: mfn to debug */ - uint32_t gref; /* IN: gref to debug */ - } u; - } debug; - } u; -}; -typedef struct xen_mem_sharing_op xen_mem_sharing_op_t; -DEFINE_XEN_GUEST_HANDLE(xen_mem_sharing_op_t); - -/* - * Attempt to stake a claim for a domain on a quantity of pages - * of system RAM, but _not_ assign specific pageframes. Only - * arithmetic is performed so the hypercall is very fast and need - * not be preemptible, thus sidestepping time-of-check-time-of-use - * races for memory allocation. Returns 0 if the hypervisor page - * allocator has atomically and successfully claimed the requested - * number of pages, else non-zero. - * - * Any domain may have only one active claim. When sufficient memory - * has been allocated to resolve the claim, the claim silently expires. - * Claiming zero pages effectively resets any outstanding claim and - * is always successful. - * - * Note that a valid claim may be staked even after memory has been - * allocated for a domain. In this case, the claim is not incremental, - * i.e. if the domain's tot_pages is 3, and a claim is staked for 10, - * only 7 additional pages are claimed. - * - * Caller must be privileged or the hypercall fails. - */ -#define XENMEM_claim_pages 24 - -/* - * XENMEM_claim_pages flags - the are no flags at this time. - * The zero value is appropriate. - */ - -/* - * With some legacy devices, certain guest-physical addresses cannot safely - * be used for other purposes, e.g. to map guest RAM. This hypercall - * enumerates those regions so the toolstack can avoid using them. - */ -#define XENMEM_reserved_device_memory_map 27 -struct xen_reserved_device_memory { - xen_pfn_t start_pfn; - xen_ulong_t nr_pages; -}; -typedef struct xen_reserved_device_memory xen_reserved_device_memory_t; -DEFINE_XEN_GUEST_HANDLE(xen_reserved_device_memory_t); - -struct xen_reserved_device_memory_map { -#define XENMEM_RDM_ALL 1 /* Request all regions (ignore dev union). */ - /* IN */ - uint32_t flags; - /* - * IN/OUT - * - * Gets set to the required number of entries when too low, - * signaled by error code -ERANGE. - */ - unsigned int nr_entries; - /* OUT */ - XEN_GUEST_HANDLE(xen_reserved_device_memory_t) buffer; - /* IN */ - union { - struct physdev_pci_device pci; - } dev; -}; -typedef struct xen_reserved_device_memory_map xen_reserved_device_memory_map_t; -DEFINE_XEN_GUEST_HANDLE(xen_reserved_device_memory_map_t); - -#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ - -/* - * XENMEM_get_vnumainfo used by guest to get - * vNUMA topology from hypervisor. - */ -#define XENMEM_get_vnumainfo 26 - -/* vNUMA node memory ranges */ -struct xen_vmemrange { - uint64_t start, end; - unsigned int flags; - unsigned int nid; -}; -typedef struct xen_vmemrange xen_vmemrange_t; -DEFINE_XEN_GUEST_HANDLE(xen_vmemrange_t); - -/* - * vNUMA topology specifies vNUMA node number, distance table, - * memory ranges and vcpu mapping provided for guests. - * XENMEM_get_vnumainfo hypercall expects to see from guest - * nr_vnodes, nr_vmemranges and nr_vcpus to indicate available memory. - * After filling guests structures, nr_vnodes, nr_vmemranges and nr_vcpus - * copied back to guest. Domain returns expected values of nr_vnodes, - * nr_vmemranges and nr_vcpus to guest if the values where incorrect. - */ -struct xen_vnuma_topology_info { - /* IN */ - domid_t domid; - uint16_t pad; - /* IN/OUT */ - unsigned int nr_vnodes; - unsigned int nr_vcpus; - unsigned int nr_vmemranges; - /* OUT */ - union { - XEN_GUEST_HANDLE(uint) h; - uint64_t pad; - } vdistance; - union { - XEN_GUEST_HANDLE(uint) h; - uint64_t pad; - } vcpu_to_vnode; - union { - XEN_GUEST_HANDLE(xen_vmemrange_t) h; - uint64_t pad; - } vmemrange; -}; -typedef struct xen_vnuma_topology_info xen_vnuma_topology_info_t; -DEFINE_XEN_GUEST_HANDLE(xen_vnuma_topology_info_t); - -/* Next available subop number is 28 */ - -#endif /* __XEN_PUBLIC_MEMORY_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/physdev.h b/include/xen/physdev.h deleted file mode 100644 index b6faf8350..000000000 --- a/include/xen/physdev.h +++ /dev/null @@ -1,387 +0,0 @@ -/* - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2006, Keir Fraser - */ - -#ifndef __XEN_PUBLIC_PHYSDEV_H__ -#define __XEN_PUBLIC_PHYSDEV_H__ - -#include "xen.h" - -/* - * Prototype for this hypercall is: - * int physdev_op(int cmd, void *args) - * @cmd == PHYSDEVOP_??? (physdev operation). - * @args == Operation-specific extra arguments (NULL if none). - */ - -/* - * Notify end-of-interrupt (EOI) for the specified IRQ. - * @arg == pointer to physdev_eoi structure. - */ -#define PHYSDEVOP_eoi 12 -struct physdev_eoi { - /* IN */ - uint32_t irq; -}; -typedef struct physdev_eoi physdev_eoi_t; -DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t); - -/* - * Register a shared page for the hypervisor to indicate whether the guest - * must issue PHYSDEVOP_eoi. The semantics of PHYSDEVOP_eoi change slightly - * once the guest used this function in that the associated event channel - * will automatically get unmasked. The page registered is used as a bit - * array indexed by Xen's PIRQ value. - */ -#define PHYSDEVOP_pirq_eoi_gmfn_v1 17 -/* - * Register a shared page for the hypervisor to indicate whether the - * guest must issue PHYSDEVOP_eoi. This hypercall is very similar to - * PHYSDEVOP_pirq_eoi_gmfn_v1 but it doesn't change the semantics of - * PHYSDEVOP_eoi. The page registered is used as a bit array indexed by - * Xen's PIRQ value. - */ -#define PHYSDEVOP_pirq_eoi_gmfn_v2 28 -struct physdev_pirq_eoi_gmfn { - /* IN */ - xen_pfn_t gmfn; -}; -typedef struct physdev_pirq_eoi_gmfn physdev_pirq_eoi_gmfn_t; -DEFINE_XEN_GUEST_HANDLE(physdev_pirq_eoi_gmfn_t); - -/* - * Query the status of an IRQ line. - * @arg == pointer to physdev_irq_status_query structure. - */ -#define PHYSDEVOP_irq_status_query 5 -struct physdev_irq_status_query { - /* IN */ - uint32_t irq; - /* OUT */ - uint32_t flags; /* XENIRQSTAT_* */ -}; -typedef struct physdev_irq_status_query physdev_irq_status_query_t; -DEFINE_XEN_GUEST_HANDLE(physdev_irq_status_query_t); - -/* Need to call PHYSDEVOP_eoi when the IRQ has been serviced? */ -#define _XENIRQSTAT_needs_eoi (0) -#define XENIRQSTAT_needs_eoi (1U<<_XENIRQSTAT_needs_eoi) - -/* IRQ shared by multiple guests? */ -#define _XENIRQSTAT_shared (1) -#define XENIRQSTAT_shared (1U<<_XENIRQSTAT_shared) - -/* - * Set the current VCPU's I/O privilege level. - * @arg == pointer to physdev_set_iopl structure. - */ -#define PHYSDEVOP_set_iopl 6 -struct physdev_set_iopl { - /* IN */ - uint32_t iopl; -}; -typedef struct physdev_set_iopl physdev_set_iopl_t; -DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl_t); - -/* - * Set the current VCPU's I/O-port permissions bitmap. - * @arg == pointer to physdev_set_iobitmap structure. - */ -#define PHYSDEVOP_set_iobitmap 7 -struct physdev_set_iobitmap { - /* IN */ -#if __XEN_INTERFACE_VERSION__ >= 0x00030205 - XEN_GUEST_HANDLE(uint8) bitmap; -#else - uint8_t *bitmap; -#endif - uint32_t nr_ports; -}; -typedef struct physdev_set_iobitmap physdev_set_iobitmap_t; -DEFINE_XEN_GUEST_HANDLE(physdev_set_iobitmap_t); - -/* - * Read or write an IO-APIC register. - * @arg == pointer to physdev_apic structure. - */ -#define PHYSDEVOP_apic_read 8 -#define PHYSDEVOP_apic_write 9 -struct physdev_apic { - /* IN */ - unsigned long apic_physbase; - uint32_t reg; - /* IN or OUT */ - uint32_t value; -}; -typedef struct physdev_apic physdev_apic_t; -DEFINE_XEN_GUEST_HANDLE(physdev_apic_t); - -/* - * Allocate or free a physical upcall vector for the specified IRQ line. - * @arg == pointer to physdev_irq structure. - */ -#define PHYSDEVOP_alloc_irq_vector 10 -#define PHYSDEVOP_free_irq_vector 11 -struct physdev_irq { - /* IN */ - uint32_t irq; - /* IN or OUT */ - uint32_t vector; -}; -typedef struct physdev_irq physdev_irq_t; -DEFINE_XEN_GUEST_HANDLE(physdev_irq_t); - -#define MAP_PIRQ_TYPE_MSI 0x0 -#define MAP_PIRQ_TYPE_GSI 0x1 -#define MAP_PIRQ_TYPE_UNKNOWN 0x2 -#define MAP_PIRQ_TYPE_MSI_SEG 0x3 -#define MAP_PIRQ_TYPE_MULTI_MSI 0x4 - -#define PHYSDEVOP_map_pirq 13 -struct physdev_map_pirq { - domid_t domid; - /* IN */ - int type; - /* IN (ignored for ..._MULTI_MSI) */ - int index; - /* IN or OUT */ - int pirq; - /* IN - high 16 bits hold segment for ..._MSI_SEG and ..._MULTI_MSI */ - int bus; - /* IN */ - int devfn; - /* IN (also OUT for ..._MULTI_MSI) */ - int entry_nr; - /* IN */ - uint64_t table_base; -}; -typedef struct physdev_map_pirq physdev_map_pirq_t; -DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t); - -#define PHYSDEVOP_unmap_pirq 14 -struct physdev_unmap_pirq { - domid_t domid; - /* IN */ - int pirq; -}; - -typedef struct physdev_unmap_pirq physdev_unmap_pirq_t; -DEFINE_XEN_GUEST_HANDLE(physdev_unmap_pirq_t); - -#define PHYSDEVOP_manage_pci_add 15 -#define PHYSDEVOP_manage_pci_remove 16 -struct physdev_manage_pci { - /* IN */ - uint8_t bus; - uint8_t devfn; -}; - -typedef struct physdev_manage_pci physdev_manage_pci_t; -DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_t); - -#define PHYSDEVOP_restore_msi 19 -struct physdev_restore_msi { - /* IN */ - uint8_t bus; - uint8_t devfn; -}; -typedef struct physdev_restore_msi physdev_restore_msi_t; -DEFINE_XEN_GUEST_HANDLE(physdev_restore_msi_t); - -#define PHYSDEVOP_manage_pci_add_ext 20 -struct physdev_manage_pci_ext { - /* IN */ - uint8_t bus; - uint8_t devfn; - unsigned is_extfn; - unsigned is_virtfn; - struct { - uint8_t bus; - uint8_t devfn; - } physfn; -}; - -typedef struct physdev_manage_pci_ext physdev_manage_pci_ext_t; -DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_ext_t); - -/* - * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op() - * hypercall since 0x00030202. - */ -struct physdev_op { - uint32_t cmd; - union { - struct physdev_irq_status_query irq_status_query; - struct physdev_set_iopl set_iopl; - struct physdev_set_iobitmap set_iobitmap; - struct physdev_apic apic_op; - struct physdev_irq irq_op; - } u; -}; -typedef struct physdev_op physdev_op_t; -DEFINE_XEN_GUEST_HANDLE(physdev_op_t); - -#define PHYSDEVOP_setup_gsi 21 -struct physdev_setup_gsi { - int gsi; - /* IN */ - uint8_t triggering; - /* IN */ - uint8_t polarity; - /* IN */ -}; - -typedef struct physdev_setup_gsi physdev_setup_gsi_t; -DEFINE_XEN_GUEST_HANDLE(physdev_setup_gsi_t); - -/* leave PHYSDEVOP 22 free */ - -/* type is MAP_PIRQ_TYPE_GSI or MAP_PIRQ_TYPE_MSI - * the hypercall returns a free pirq */ -#define PHYSDEVOP_get_free_pirq 23 -struct physdev_get_free_pirq { - /* IN */ - int type; - /* OUT */ - uint32_t pirq; -}; - -typedef struct physdev_get_free_pirq physdev_get_free_pirq_t; -DEFINE_XEN_GUEST_HANDLE(physdev_get_free_pirq_t); - -#define XEN_PCI_MMCFG_RESERVED 0x1 - -#define PHYSDEVOP_pci_mmcfg_reserved 24 -struct physdev_pci_mmcfg_reserved { - uint64_t address; - uint16_t segment; - uint8_t start_bus; - uint8_t end_bus; - uint32_t flags; -}; -typedef struct physdev_pci_mmcfg_reserved physdev_pci_mmcfg_reserved_t; -DEFINE_XEN_GUEST_HANDLE(physdev_pci_mmcfg_reserved_t); - -#define XEN_PCI_DEV_EXTFN 0x1 -#define XEN_PCI_DEV_VIRTFN 0x2 -#define XEN_PCI_DEV_PXM 0x4 - -#define PHYSDEVOP_pci_device_add 25 -struct physdev_pci_device_add { - /* IN */ - uint16_t seg; - uint8_t bus; - uint8_t devfn; - uint32_t flags; - struct { - uint8_t bus; - uint8_t devfn; - } physfn; - /* - * Optional parameters array. - * First element ([0]) is PXM domain associated with the device (if - * XEN_PCI_DEV_PXM is set) - */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - uint32_t optarr[]; -#elif defined(__GNUC__) - uint32_t optarr[0]; -#endif -}; -typedef struct physdev_pci_device_add physdev_pci_device_add_t; -DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_add_t); - -#define PHYSDEVOP_pci_device_remove 26 -#define PHYSDEVOP_restore_msi_ext 27 -/* - * Dom0 should use these two to announce MMIO resources assigned to - * MSI-X capable devices won't (prepare) or may (release) change. - */ -#define PHYSDEVOP_prepare_msix 30 -#define PHYSDEVOP_release_msix 31 -struct physdev_pci_device { - /* IN */ - uint16_t seg; - uint8_t bus; - uint8_t devfn; -}; -typedef struct physdev_pci_device physdev_pci_device_t; -DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_t); - -#define PHYSDEVOP_DBGP_RESET_PREPARE 1 -#define PHYSDEVOP_DBGP_RESET_DONE 2 - -#define PHYSDEVOP_DBGP_BUS_UNKNOWN 0 -#define PHYSDEVOP_DBGP_BUS_PCI 1 - -#define PHYSDEVOP_dbgp_op 29 -struct physdev_dbgp_op { - /* IN */ - uint8_t op; - uint8_t bus; - union { - struct physdev_pci_device pci; - } u; -}; -typedef struct physdev_dbgp_op physdev_dbgp_op_t; -DEFINE_XEN_GUEST_HANDLE(physdev_dbgp_op_t); - -/* - * Notify that some PIRQ-bound event channels have been unmasked. - * ** This command is obsolete since interface version 0x00030202 and is ** - * ** unsupported by newer versions of Xen. ** - */ -#define PHYSDEVOP_IRQ_UNMASK_NOTIFY 4 - -#if __XEN_INTERFACE_VERSION__ < 0x00040600 -/* - * These all-capitals physdev operation names are superceded by the new names - * (defined above) since interface version 0x00030202. The guard above was - * added post-4.5 only though and hence shouldn't check for 0x00030202. - */ -#define PHYSDEVOP_IRQ_STATUS_QUERY PHYSDEVOP_irq_status_query -#define PHYSDEVOP_SET_IOPL PHYSDEVOP_set_iopl -#define PHYSDEVOP_SET_IOBITMAP PHYSDEVOP_set_iobitmap -#define PHYSDEVOP_APIC_READ PHYSDEVOP_apic_read -#define PHYSDEVOP_APIC_WRITE PHYSDEVOP_apic_write -#define PHYSDEVOP_ASSIGN_VECTOR PHYSDEVOP_alloc_irq_vector -#define PHYSDEVOP_FREE_VECTOR PHYSDEVOP_free_irq_vector -#define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY XENIRQSTAT_needs_eoi -#define PHYSDEVOP_IRQ_SHARED XENIRQSTAT_shared -#endif - -#if __XEN_INTERFACE_VERSION__ < 0x00040200 -#define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v1 -#else -#define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v2 -#endif - -#endif /* __XEN_PUBLIC_PHYSDEV_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/sched.h b/include/xen/sched.h deleted file mode 100644 index a30b11d96..000000000 --- a/include/xen/sched.h +++ /dev/null @@ -1,174 +0,0 @@ -/****************************************************************************** - * sched.h - * - * Scheduler state interactions - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2005, Keir Fraser - */ - -#ifndef __XEN_PUBLIC_SCHED_H__ -#define __XEN_PUBLIC_SCHED_H__ - -#include "event_channel.h" - -/* - * `incontents 150 sched Guest Scheduler Operations - * - * The SCHEDOP interface provides mechanisms for a guest to interact - * with the scheduler, including yield, blocking and shutting itself - * down. - */ - -/* - * The prototype for this hypercall is: - * ` long HYPERVISOR_sched_op(enum sched_op cmd, void *arg, ...) - * - * @cmd == SCHEDOP_??? (scheduler operation). - * @arg == Operation-specific extra argument(s), as described below. - * ... == Additional Operation-specific extra arguments, described below. - * - * Versions of Xen prior to 3.0.2 provided only the following legacy version - * of this hypercall, supporting only the commands yield, block and shutdown: - * long sched_op(int cmd, unsigned long arg) - * @cmd == SCHEDOP_??? (scheduler operation). - * @arg == 0 (SCHEDOP_yield and SCHEDOP_block) - * == SHUTDOWN_* code (SCHEDOP_shutdown) - * - * This legacy version is available to new guests as: - * ` long HYPERVISOR_sched_op_compat(enum sched_op cmd, unsigned long arg) - */ - -/* ` enum sched_op { // SCHEDOP_* => struct sched_* */ -/* - * Voluntarily yield the CPU. - * @arg == NULL. - */ -#define SCHEDOP_yield 0 - -/* - * Block execution of this VCPU until an event is received for processing. - * If called with event upcalls masked, this operation will atomically - * reenable event delivery and check for pending events before blocking the - * VCPU. This avoids a "wakeup waiting" race. - * @arg == NULL. - */ -#define SCHEDOP_block 1 - -/* - * Halt execution of this domain (all VCPUs) and notify the system controller. - * @arg == pointer to sched_shutdown_t structure. - * - * If the sched_shutdown_t reason is SHUTDOWN_suspend then this - * hypercall takes an additional extra argument which should be the - * MFN of the guest's start_info_t. - * - * In addition, which reason is SHUTDOWN_suspend this hypercall - * returns 1 if suspend was cancelled or the domain was merely - * checkpointed, and 0 if it is resuming in a new domain. - */ -#define SCHEDOP_shutdown 2 - -/* - * Poll a set of event-channel ports. Return when one or more are pending. An - * optional timeout may be specified. - * @arg == pointer to sched_poll_t structure. - */ -#define SCHEDOP_poll 3 - -/* - * Declare a shutdown for another domain. The main use of this function is - * in interpreting shutdown requests and reasons for fully-virtualized - * domains. A para-virtualized domain may use SCHEDOP_shutdown directly. - * @arg == pointer to sched_remote_shutdown_t structure. - */ -#define SCHEDOP_remote_shutdown 4 - -/* - * Latch a shutdown code, so that when the domain later shuts down it - * reports this code to the control tools. - * @arg == sched_shutdown_t, as for SCHEDOP_shutdown. - */ -#define SCHEDOP_shutdown_code 5 - -/* - * Setup, poke and destroy a domain watchdog timer. - * @arg == pointer to sched_watchdog_t structure. - * With id == 0, setup a domain watchdog timer to cause domain shutdown - * after timeout, returns watchdog id. - * With id != 0 and timeout == 0, destroy domain watchdog timer. - * With id != 0 and timeout != 0, poke watchdog timer and set new timeout. - */ -#define SCHEDOP_watchdog 6 -/* ` } */ - -struct sched_shutdown { - unsigned int reason; /* SHUTDOWN_* => enum sched_shutdown_reason */ -}; -typedef struct sched_shutdown sched_shutdown_t; -DEFINE_XEN_GUEST_HANDLE(sched_shutdown_t); - -struct sched_poll { - XEN_GUEST_HANDLE(evtchn_port_t) ports; - unsigned int nr_ports; - uint64_t timeout; -}; -typedef struct sched_poll sched_poll_t; -DEFINE_XEN_GUEST_HANDLE(sched_poll_t); - -struct sched_remote_shutdown { - domid_t domain_id; /* Remote domain ID */ - unsigned int reason; /* SHUTDOWN_* => enum sched_shutdown_reason */ -}; -typedef struct sched_remote_shutdown sched_remote_shutdown_t; -DEFINE_XEN_GUEST_HANDLE(sched_remote_shutdown_t); - -struct sched_watchdog { - uint32_t id; /* watchdog ID */ - uint32_t timeout; /* timeout */ -}; -typedef struct sched_watchdog sched_watchdog_t; -DEFINE_XEN_GUEST_HANDLE(sched_watchdog_t); - -/* - * Reason codes for SCHEDOP_shutdown. These may be interpreted by control - * software to determine the appropriate action. For the most part, Xen does - * not care about the shutdown code. - */ -/* ` enum sched_shutdown_reason { */ -#define SHUTDOWN_poweroff 0 /* Domain exited normally. Clean up and kill. */ -#define SHUTDOWN_reboot 1 /* Clean up, kill, and then restart. */ -#define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. */ -#define SHUTDOWN_crash 3 /* Tell controller we've crashed. */ -#define SHUTDOWN_watchdog 4 /* Restart because watchdog time expired. */ -#define SHUTDOWN_MAX 4 /* Maximum valid shutdown reason. */ -/* ` } */ - -#endif /* __XEN_PUBLIC_SCHED_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/trace.h b/include/xen/trace.h deleted file mode 100644 index a00c01733..000000000 --- a/include/xen/trace.h +++ /dev/null @@ -1,339 +0,0 @@ -/****************************************************************************** - * include/public/trace.h - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Mark Williamson, (C) 2004 Intel Research Cambridge - * Copyright (C) 2005 Bin Ren - */ - -#ifndef __XEN_PUBLIC_TRACE_H__ -#define __XEN_PUBLIC_TRACE_H__ - -#define TRACE_EXTRA_MAX 7 -#define TRACE_EXTRA_SHIFT 28 - -/* Trace classes */ -#define TRC_CLS_SHIFT 16 -#define TRC_GEN 0x0001f000 /* General trace */ -#define TRC_SCHED 0x0002f000 /* Xen Scheduler trace */ -#define TRC_DOM0OP 0x0004f000 /* Xen DOM0 operation trace */ -#define TRC_HVM 0x0008f000 /* Xen HVM trace */ -#define TRC_MEM 0x0010f000 /* Xen memory trace */ -#define TRC_PV 0x0020f000 /* Xen PV traces */ -#define TRC_SHADOW 0x0040f000 /* Xen shadow tracing */ -#define TRC_HW 0x0080f000 /* Xen hardware-related traces */ -#define TRC_GUEST 0x0800f000 /* Guest-generated traces */ -#define TRC_ALL 0x0ffff000 -#define TRC_HD_TO_EVENT(x) ((x)&0x0fffffff) -#define TRC_HD_CYCLE_FLAG (1UL<<31) -#define TRC_HD_INCLUDES_CYCLE_COUNT(x) ( !!( (x) & TRC_HD_CYCLE_FLAG ) ) -#define TRC_HD_EXTRA(x) (((x)>>TRACE_EXTRA_SHIFT)&TRACE_EXTRA_MAX) - -/* Trace subclasses */ -#define TRC_SUBCLS_SHIFT 12 - -/* trace subclasses for SVM */ -#define TRC_HVM_ENTRYEXIT 0x00081000 /* VMENTRY and #VMEXIT */ -#define TRC_HVM_HANDLER 0x00082000 /* various HVM handlers */ -#define TRC_HVM_EMUL 0x00084000 /* emulated devices */ - -#define TRC_SCHED_MIN 0x00021000 /* Just runstate changes */ -#define TRC_SCHED_CLASS 0x00022000 /* Scheduler-specific */ -#define TRC_SCHED_VERBOSE 0x00028000 /* More inclusive scheduling */ - -/* - * The highest 3 bits of the last 12 bits of TRC_SCHED_CLASS above are - * reserved for encoding what scheduler produced the information. The - * actual event is encoded in the last 9 bits. - * - * This means we have 8 scheduling IDs available (which means at most 8 - * schedulers generating events) and, in each scheduler, up to 512 - * different events. - */ -#define TRC_SCHED_ID_BITS 3 -#define TRC_SCHED_ID_SHIFT (TRC_SUBCLS_SHIFT - TRC_SCHED_ID_BITS) -#define TRC_SCHED_ID_MASK (((1UL<cpu_offset[cpu]). - */ -struct t_info { - uint16_t tbuf_size; /* Size in pages of each trace buffer */ - uint16_t mfn_offset[]; /* Offset within t_info structure of the page list per cpu */ - /* MFN lists immediately after the header */ -}; - -#endif /* __XEN_PUBLIC_TRACE_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/include/xen/xen-compat.h b/include/xen/xen-compat.h deleted file mode 100644 index 2508645b5..000000000 --- a/include/xen/xen-compat.h +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************** - * xen-compat.h - * - * Guest OS interface to Xen. Compatibility layer. - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2006, Christian Limpach - */ - -#ifndef __XEN_PUBLIC_XEN_COMPAT_H__ -#define __XEN_PUBLIC_XEN_COMPAT_H__ - -#define __XEN_LATEST_INTERFACE_VERSION__ 0x00040400 - -#if defined(__XEN__) || defined(__XEN_TOOLS__) -/* Xen is built with matching headers and implements the latest interface. */ -#define __XEN_INTERFACE_VERSION__ __XEN_LATEST_INTERFACE_VERSION__ -#elif !defined(__XEN_INTERFACE_VERSION__) -/* Guests which do not specify a version get the legacy interface. */ -#define __XEN_INTERFACE_VERSION__ 0x00000000 -#endif - -#if __XEN_INTERFACE_VERSION__ > __XEN_LATEST_INTERFACE_VERSION__ -#error "These header files do not support the requested interface version." -#endif - -#endif /* __XEN_PUBLIC_XEN_COMPAT_H__ */ diff --git a/include/xen/xen.h b/include/xen/xen.h deleted file mode 100644 index 692f97a5b..000000000 --- a/include/xen/xen.h +++ /dev/null @@ -1,998 +0,0 @@ -/****************************************************************************** - * xen.h - * - * Guest OS interface to Xen. - * - * 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 THE - * AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Copyright (c) 2004, K A Fraser - */ - -#ifndef __XEN_PUBLIC_XEN_H__ -#define __XEN_PUBLIC_XEN_H__ - -#include "xen-compat.h" - -#if defined(__i386__) || defined(__x86_64__) -#include "arch-x86/xen.h" -#elif defined(__arm__) || defined (__aarch64__) -#include "arch-arm.h" -#else -#error "Unsupported architecture" -#endif - -#ifndef __ASSEMBLY__ -/* Guest handles for primitive C types. */ -DEFINE_XEN_GUEST_HANDLE(char); -__DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char); -DEFINE_XEN_GUEST_HANDLE(int); -__DEFINE_XEN_GUEST_HANDLE(uint, unsigned int); -#if __XEN_INTERFACE_VERSION__ < 0x00040300 -DEFINE_XEN_GUEST_HANDLE(long); -__DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long); -#endif -DEFINE_XEN_GUEST_HANDLE(void); - -DEFINE_XEN_GUEST_HANDLE(uint64_t); -DEFINE_XEN_GUEST_HANDLE(xen_pfn_t); -DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); - -/* Turn a plain number into a C unsigned (long (long)) constant. */ -#define __xen_mk_uint(x) x ## U -#define __xen_mk_ulong(x) x ## UL -#ifndef __xen_mk_ullong -# define __xen_mk_ullong(x) x ## ULL -#endif -#define xen_mk_uint(x) __xen_mk_uint(x) -#define xen_mk_ulong(x) __xen_mk_ulong(x) -#define xen_mk_ullong(x) __xen_mk_ullong(x) - -#else - -/* In assembly code we cannot use C numeric constant suffixes. */ -#define xen_mk_uint(x) x -#define xen_mk_ulong(x) x -#define xen_mk_ullong(x) x - -#endif - -/* - * HYPERCALLS - */ - -/* `incontents 100 hcalls List of hypercalls - * ` enum hypercall_num { // __HYPERVISOR_* => HYPERVISOR_*() - */ - -#define __HYPERVISOR_set_trap_table 0 -#define __HYPERVISOR_mmu_update 1 -#define __HYPERVISOR_set_gdt 2 -#define __HYPERVISOR_stack_switch 3 -#define __HYPERVISOR_set_callbacks 4 -#define __HYPERVISOR_fpu_taskswitch 5 -#define __HYPERVISOR_sched_op_compat 6 /* compat since 0x00030101 */ -#define __HYPERVISOR_platform_op 7 -#define __HYPERVISOR_set_debugreg 8 -#define __HYPERVISOR_get_debugreg 9 -#define __HYPERVISOR_update_descriptor 10 -#define __HYPERVISOR_memory_op 12 -#define __HYPERVISOR_multicall 13 -#define __HYPERVISOR_update_va_mapping 14 -#define __HYPERVISOR_set_timer_op 15 -#define __HYPERVISOR_event_channel_op_compat 16 /* compat since 0x00030202 */ -#define __HYPERVISOR_xen_version 17 -#define __HYPERVISOR_console_io 18 -#define __HYPERVISOR_physdev_op_compat 19 /* compat since 0x00030202 */ -#define __HYPERVISOR_grant_table_op 20 -#define __HYPERVISOR_vm_assist 21 -#define __HYPERVISOR_update_va_mapping_otherdomain 22 -#define __HYPERVISOR_iret 23 /* x86 only */ -#define __HYPERVISOR_vcpu_op 24 -#define __HYPERVISOR_set_segment_base 25 /* x86/64 only */ -#define __HYPERVISOR_mmuext_op 26 -#define __HYPERVISOR_xsm_op 27 -#define __HYPERVISOR_nmi_op 28 -#define __HYPERVISOR_sched_op 29 -#define __HYPERVISOR_callback_op 30 -#define __HYPERVISOR_xenoprof_op 31 -#define __HYPERVISOR_event_channel_op 32 -#define __HYPERVISOR_physdev_op 33 -#define __HYPERVISOR_hvm_op 34 -#define __HYPERVISOR_sysctl 35 -#define __HYPERVISOR_domctl 36 -#define __HYPERVISOR_kexec_op 37 -#define __HYPERVISOR_tmem_op 38 -#define __HYPERVISOR_xc_reserved_op 39 /* reserved for XenClient */ -#define __HYPERVISOR_xenpmu_op 40 -#define __HYPERVISOR_dm_op 41 - -/* Architecture-specific hypercall definitions. */ -#define __HYPERVISOR_arch_0 48 -#define __HYPERVISOR_arch_1 49 -#define __HYPERVISOR_arch_2 50 -#define __HYPERVISOR_arch_3 51 -#define __HYPERVISOR_arch_4 52 -#define __HYPERVISOR_arch_5 53 -#define __HYPERVISOR_arch_6 54 -#define __HYPERVISOR_arch_7 55 - -/* ` } */ - -/* - * HYPERCALL COMPATIBILITY. - */ - -/* New sched_op hypercall introduced in 0x00030101. */ -#if __XEN_INTERFACE_VERSION__ < 0x00030101 -#undef __HYPERVISOR_sched_op -#define __HYPERVISOR_sched_op __HYPERVISOR_sched_op_compat -#endif - -/* New event-channel and physdev hypercalls introduced in 0x00030202. */ -#if __XEN_INTERFACE_VERSION__ < 0x00030202 -#undef __HYPERVISOR_event_channel_op -#define __HYPERVISOR_event_channel_op __HYPERVISOR_event_channel_op_compat -#undef __HYPERVISOR_physdev_op -#define __HYPERVISOR_physdev_op __HYPERVISOR_physdev_op_compat -#endif - -/* New platform_op hypercall introduced in 0x00030204. */ -#if __XEN_INTERFACE_VERSION__ < 0x00030204 -#define __HYPERVISOR_dom0_op __HYPERVISOR_platform_op -#endif - -/* - * VIRTUAL INTERRUPTS - * - * Virtual interrupts that a guest OS may receive from Xen. - * - * In the side comments, 'V.' denotes a per-VCPU VIRQ while 'G.' denotes a - * global VIRQ. The former can be bound once per VCPU and cannot be re-bound. - * The latter can be allocated only once per guest: they must initially be - * allocated to VCPU0 but can subsequently be re-bound. - */ -/* ` enum virq { */ -#define VIRQ_TIMER 0 /* V. Timebase update, and/or requested timeout. */ -#define VIRQ_DEBUG 1 /* V. Request guest to dump debug info. */ -#define VIRQ_CONSOLE 2 /* G. (DOM0) Bytes received on emergency console. */ -#define VIRQ_DOM_EXC 3 /* G. (DOM0) Exceptional event for some domain. */ -#define VIRQ_TBUF 4 /* G. (DOM0) Trace buffer has records available. */ -#define VIRQ_DEBUGGER 6 /* G. (DOM0) A domain has paused for debugging. */ -#define VIRQ_XENOPROF 7 /* V. XenOprofile interrupt: new sample available */ -#define VIRQ_CON_RING 8 /* G. (DOM0) Bytes received on console */ -#define VIRQ_PCPU_STATE 9 /* G. (DOM0) PCPU state changed */ -#define VIRQ_MEM_EVENT 10 /* G. (DOM0) A memory event has occured */ -#define VIRQ_XC_RESERVED 11 /* G. Reserved for XenClient */ -#define VIRQ_ENOMEM 12 /* G. (DOM0) Low on heap memory */ -#define VIRQ_XENPMU 13 /* V. PMC interrupt */ - -/* Architecture-specific VIRQ definitions. */ -#define VIRQ_ARCH_0 16 -#define VIRQ_ARCH_1 17 -#define VIRQ_ARCH_2 18 -#define VIRQ_ARCH_3 19 -#define VIRQ_ARCH_4 20 -#define VIRQ_ARCH_5 21 -#define VIRQ_ARCH_6 22 -#define VIRQ_ARCH_7 23 -/* ` } */ - -#define NR_VIRQS 24 - -/* - * ` enum neg_errnoval - * ` HYPERVISOR_mmu_update(const struct mmu_update reqs[], - * ` unsigned count, unsigned *done_out, - * ` unsigned foreigndom) - * ` - * @reqs is an array of mmu_update_t structures ((ptr, val) pairs). - * @count is the length of the above array. - * @pdone is an output parameter indicating number of completed operations - * @foreigndom[15:0]: FD, the expected owner of data pages referenced in this - * hypercall invocation. Can be DOMID_SELF. - * @foreigndom[31:16]: PFD, the expected owner of pagetable pages referenced - * in this hypercall invocation. The value of this field - * (x) encodes the PFD as follows: - * x == 0 => PFD == DOMID_SELF - * x != 0 => PFD == x - 1 - * - * Sub-commands: ptr[1:0] specifies the appropriate MMU_* command. - * ------------- - * ptr[1:0] == MMU_NORMAL_PT_UPDATE: - * Updates an entry in a page table belonging to PFD. If updating an L1 table, - * and the new table entry is valid/present, the mapped frame must belong to - * FD. If attempting to map an I/O page then the caller assumes the privilege - * of the FD. - * FD == DOMID_IO: Permit /only/ I/O mappings, at the priv level of the caller. - * FD == DOMID_XEN: Map restricted areas of Xen's heap space. - * ptr[:2] -- Machine address of the page-table entry to modify. - * val -- Value to write. - * - * There also certain implicit requirements when using this hypercall. The - * pages that make up a pagetable must be mapped read-only in the guest. - * This prevents uncontrolled guest updates to the pagetable. Xen strictly - * enforces this, and will disallow any pagetable update which will end up - * mapping pagetable page RW, and will disallow using any writable page as a - * pagetable. In practice it means that when constructing a page table for a - * process, thread, etc, we MUST be very dilligient in following these rules: - * 1). Start with top-level page (PGD or in Xen language: L4). Fill out - * the entries. - * 2). Keep on going, filling out the upper (PUD or L3), and middle (PMD - * or L2). - * 3). Start filling out the PTE table (L1) with the PTE entries. Once - * done, make sure to set each of those entries to RO (so writeable bit - * is unset). Once that has been completed, set the PMD (L2) for this - * PTE table as RO. - * 4). When completed with all of the PMD (L2) entries, and all of them have - * been set to RO, make sure to set RO the PUD (L3). Do the same - * operation on PGD (L4) pagetable entries that have a PUD (L3) entry. - * 5). Now before you can use those pages (so setting the cr3), you MUST also - * pin them so that the hypervisor can verify the entries. This is done - * via the HYPERVISOR_mmuext_op(MMUEXT_PIN_L4_TABLE, guest physical frame - * number of the PGD (L4)). And this point the HYPERVISOR_mmuext_op( - * MMUEXT_NEW_BASEPTR, guest physical frame number of the PGD (L4)) can be - * issued. - * For 32-bit guests, the L4 is not used (as there is less pagetables), so - * instead use L3. - * At this point the pagetables can be modified using the MMU_NORMAL_PT_UPDATE - * hypercall. Also if so desired the OS can also try to write to the PTE - * and be trapped by the hypervisor (as the PTE entry is RO). - * - * To deallocate the pages, the operations are the reverse of the steps - * mentioned above. The argument is MMUEXT_UNPIN_TABLE for all levels and the - * pagetable MUST not be in use (meaning that the cr3 is not set to it). - * - * ptr[1:0] == MMU_MACHPHYS_UPDATE: - * Updates an entry in the machine->pseudo-physical mapping table. - * ptr[:2] -- Machine address within the frame whose mapping to modify. - * The frame must belong to the FD, if one is specified. - * val -- Value to write into the mapping entry. - * - * ptr[1:0] == MMU_PT_UPDATE_PRESERVE_AD: - * As MMU_NORMAL_PT_UPDATE above, but A/D bits currently in the PTE are ORed - * with those in @val. - * - * @val is usually the machine frame number along with some attributes. - * The attributes by default follow the architecture defined bits. Meaning that - * if this is a X86_64 machine and four page table layout is used, the layout - * of val is: - * - 63 if set means No execute (NX) - * - 46-13 the machine frame number - * - 12 available for guest - * - 11 available for guest - * - 10 available for guest - * - 9 available for guest - * - 8 global - * - 7 PAT (PSE is disabled, must use hypercall to make 4MB or 2MB pages) - * - 6 dirty - * - 5 accessed - * - 4 page cached disabled - * - 3 page write through - * - 2 userspace accessible - * - 1 writeable - * - 0 present - * - * The one bits that does not fit with the default layout is the PAGE_PSE - * also called PAGE_PAT). The MMUEXT_[UN]MARK_SUPER arguments to the - * HYPERVISOR_mmuext_op serve as mechanism to set a pagetable to be 4MB - * (or 2MB) instead of using the PAGE_PSE bit. - * - * The reason that the PAGE_PSE (bit 7) is not being utilized is due to Xen - * using it as the Page Attribute Table (PAT) bit - for details on it please - * refer to Intel SDM 10.12. The PAT allows to set the caching attributes of - * pages instead of using MTRRs. - * - * The PAT MSR is as follows (it is a 64-bit value, each entry is 8 bits): - * PAT4 PAT0 - * +-----+-----+----+----+----+-----+----+----+ - * | UC | UC- | WC | WB | UC | UC- | WC | WB | <= Linux - * +-----+-----+----+----+----+-----+----+----+ - * | UC | UC- | WT | WB | UC | UC- | WT | WB | <= BIOS (default when machine boots) - * +-----+-----+----+----+----+-----+----+----+ - * | rsv | rsv | WP | WC | UC | UC- | WT | WB | <= Xen - * +-----+-----+----+----+----+-----+----+----+ - * - * The lookup of this index table translates to looking up - * Bit 7, Bit 4, and Bit 3 of val entry: - * - * PAT/PSE (bit 7) ... PCD (bit 4) .. PWT (bit 3). - * - * If all bits are off, then we are using PAT0. If bit 3 turned on, - * then we are using PAT1, if bit 3 and bit 4, then PAT2.. - * - * As you can see, the Linux PAT1 translates to PAT4 under Xen. Which means - * that if a guest that follows Linux's PAT setup and would like to set Write - * Combined on pages it MUST use PAT4 entry. Meaning that Bit 7 (PAGE_PAT) is - * set. For example, under Linux it only uses PAT0, PAT1, and PAT2 for the - * caching as: - * - * WB = none (so PAT0) - * WC = PWT (bit 3 on) - * UC = PWT | PCD (bit 3 and 4 are on). - * - * To make it work with Xen, it needs to translate the WC bit as so: - * - * PWT (so bit 3 on) --> PAT (so bit 7 is on) and clear bit 3 - * - * And to translate back it would: - * - * PAT (bit 7 on) --> PWT (bit 3 on) and clear bit 7. - */ -#define MMU_NORMAL_PT_UPDATE 0 /* checked '*ptr = val'. ptr is MA. */ -#define MMU_MACHPHYS_UPDATE 1 /* ptr = MA of frame to modify entry for */ -#define MMU_PT_UPDATE_PRESERVE_AD 2 /* atomically: *ptr = val | (*ptr&(A|D)) */ - -/* - * MMU EXTENDED OPERATIONS - * - * ` enum neg_errnoval - * ` HYPERVISOR_mmuext_op(mmuext_op_t uops[], - * ` unsigned int count, - * ` unsigned int *pdone, - * ` unsigned int foreigndom) - */ -/* HYPERVISOR_mmuext_op() accepts a list of mmuext_op structures. - * A foreigndom (FD) can be specified (or DOMID_SELF for none). - * Where the FD has some effect, it is described below. - * - * cmd: MMUEXT_(UN)PIN_*_TABLE - * mfn: Machine frame number to be (un)pinned as a p.t. page. - * The frame must belong to the FD, if one is specified. - * - * cmd: MMUEXT_NEW_BASEPTR - * mfn: Machine frame number of new page-table base to install in MMU. - * - * cmd: MMUEXT_NEW_USER_BASEPTR [x86/64 only] - * mfn: Machine frame number of new page-table base to install in MMU - * when in user space. - * - * cmd: MMUEXT_TLB_FLUSH_LOCAL - * No additional arguments. Flushes local TLB. - * - * cmd: MMUEXT_INVLPG_LOCAL - * linear_addr: Linear address to be flushed from the local TLB. - * - * cmd: MMUEXT_TLB_FLUSH_MULTI - * vcpumask: Pointer to bitmap of VCPUs to be flushed. - * - * cmd: MMUEXT_INVLPG_MULTI - * linear_addr: Linear address to be flushed. - * vcpumask: Pointer to bitmap of VCPUs to be flushed. - * - * cmd: MMUEXT_TLB_FLUSH_ALL - * No additional arguments. Flushes all VCPUs' TLBs. - * - * cmd: MMUEXT_INVLPG_ALL - * linear_addr: Linear address to be flushed from all VCPUs' TLBs. - * - * cmd: MMUEXT_FLUSH_CACHE - * No additional arguments. Writes back and flushes cache contents. - * - * cmd: MMUEXT_FLUSH_CACHE_GLOBAL - * No additional arguments. Writes back and flushes cache contents - * on all CPUs in the system. - * - * cmd: MMUEXT_SET_LDT - * linear_addr: Linear address of LDT base (NB. must be page-aligned). - * nr_ents: Number of entries in LDT. - * - * cmd: MMUEXT_CLEAR_PAGE - * mfn: Machine frame number to be cleared. - * - * cmd: MMUEXT_COPY_PAGE - * mfn: Machine frame number of the destination page. - * src_mfn: Machine frame number of the source page. - * - * cmd: MMUEXT_[UN]MARK_SUPER - * mfn: Machine frame number of head of superpage to be [un]marked. - */ -/* ` enum mmuext_cmd { */ -#define MMUEXT_PIN_L1_TABLE 0 -#define MMUEXT_PIN_L2_TABLE 1 -#define MMUEXT_PIN_L3_TABLE 2 -#define MMUEXT_PIN_L4_TABLE 3 -#define MMUEXT_UNPIN_TABLE 4 -#define MMUEXT_NEW_BASEPTR 5 -#define MMUEXT_TLB_FLUSH_LOCAL 6 -#define MMUEXT_INVLPG_LOCAL 7 -#define MMUEXT_TLB_FLUSH_MULTI 8 -#define MMUEXT_INVLPG_MULTI 9 -#define MMUEXT_TLB_FLUSH_ALL 10 -#define MMUEXT_INVLPG_ALL 11 -#define MMUEXT_FLUSH_CACHE 12 -#define MMUEXT_SET_LDT 13 -#define MMUEXT_NEW_USER_BASEPTR 15 -#define MMUEXT_CLEAR_PAGE 16 -#define MMUEXT_COPY_PAGE 17 -#define MMUEXT_FLUSH_CACHE_GLOBAL 18 -#define MMUEXT_MARK_SUPER 19 -#define MMUEXT_UNMARK_SUPER 20 -/* ` } */ - -#ifndef __ASSEMBLY__ -struct mmuext_op { - unsigned int cmd; /* => enum mmuext_cmd */ - union { - /* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR - * CLEAR_PAGE, COPY_PAGE, [UN]MARK_SUPER */ - xen_pfn_t mfn; - /* INVLPG_LOCAL, INVLPG_ALL, SET_LDT */ - unsigned long linear_addr; - } arg1; - union { - /* SET_LDT */ - unsigned int nr_ents; - /* TLB_FLUSH_MULTI, INVLPG_MULTI */ -#if __XEN_INTERFACE_VERSION__ >= 0x00030205 - XEN_GUEST_HANDLE(const_void) vcpumask; -#else - const void *vcpumask; -#endif - /* COPY_PAGE */ - xen_pfn_t src_mfn; - } arg2; -}; -typedef struct mmuext_op mmuext_op_t; -DEFINE_XEN_GUEST_HANDLE(mmuext_op_t); -#endif - -/* - * ` enum neg_errnoval - * ` HYPERVISOR_update_va_mapping(unsigned long va, u64 val, - * ` enum uvm_flags flags) - * ` - * ` enum neg_errnoval - * ` HYPERVISOR_update_va_mapping_otherdomain(unsigned long va, u64 val, - * ` enum uvm_flags flags, - * ` domid_t domid) - * ` - * ` @va: The virtual address whose mapping we want to change - * ` @val: The new page table entry, must contain a machine address - * ` @flags: Control TLB flushes - */ -/* These are passed as 'flags' to update_va_mapping. They can be ORed. */ -/* When specifying UVMF_MULTI, also OR in a pointer to a CPU bitmap. */ -/* UVMF_LOCAL is merely UVMF_MULTI with a NULL bitmap pointer. */ -/* ` enum uvm_flags { */ -#define UVMF_NONE (xen_mk_ulong(0)<<0) /* No flushing at all. */ -#define UVMF_TLB_FLUSH (xen_mk_ulong(1)<<0) /* Flush entire TLB(s). */ -#define UVMF_INVLPG (xen_mk_ulong(2)<<0) /* Flush only one entry. */ -#define UVMF_FLUSHTYPE_MASK (xen_mk_ulong(3)<<0) -#define UVMF_MULTI (xen_mk_ulong(0)<<2) /* Flush subset of TLBs. */ -#define UVMF_LOCAL (xen_mk_ulong(0)<<2) /* Flush local TLB. */ -#define UVMF_ALL (xen_mk_ulong(1)<<2) /* Flush all TLBs. */ -/* ` } */ - -/* - * Commands to HYPERVISOR_console_io(). - */ -#define CONSOLEIO_write 0 -#define CONSOLEIO_read 1 - -/* - * Commands to HYPERVISOR_vm_assist(). - */ -#define VMASST_CMD_enable 0 -#define VMASST_CMD_disable 1 - -/* x86/32 guests: simulate full 4GB segment limits. */ -#define VMASST_TYPE_4gb_segments 0 - -/* x86/32 guests: trap (vector 15) whenever above vmassist is used. */ -#define VMASST_TYPE_4gb_segments_notify 1 - -/* - * x86 guests: support writes to bottom-level PTEs. - * NB1. Page-directory entries cannot be written. - * NB2. Guest must continue to remove all writable mappings of PTEs. - */ -#define VMASST_TYPE_writable_pagetables 2 - -/* x86/PAE guests: support PDPTs above 4GB. */ -#define VMASST_TYPE_pae_extended_cr3 3 - -/* - * x86 guests: Sane behaviour for virtual iopl - * - virtual iopl updated from do_iret() hypercalls. - * - virtual iopl reported in bounce frames. - * - guest kernels assumed to be level 0 for the purpose of iopl checks. - */ -#define VMASST_TYPE_architectural_iopl 4 - -/* - * All guests: activate update indicator in vcpu_runstate_info - * Enable setting the XEN_RUNSTATE_UPDATE flag in guest memory mapped - * vcpu_runstate_info during updates of the runstate information. - */ -#define VMASST_TYPE_runstate_update_flag 5 - -/* - * x86/64 guests: strictly hide M2P from user mode. - * This allows the guest to control respective hypervisor behavior: - * - when not set, L4 tables get created with the respective slot blank, - * and whenever the L4 table gets used as a kernel one the missing - * mapping gets inserted, - * - when set, L4 tables get created with the respective slot initialized - * as before, and whenever the L4 table gets used as a user one the - * mapping gets zapped. - */ -#define VMASST_TYPE_m2p_strict 32 - -#if __XEN_INTERFACE_VERSION__ < 0x00040600 -#define MAX_VMASST_TYPE 3 -#endif - -/* Domain ids >= DOMID_FIRST_RESERVED cannot be used for ordinary domains. */ -#define DOMID_FIRST_RESERVED xen_mk_uint(0x7FF0) - -/* DOMID_SELF is used in certain contexts to refer to oneself. */ -#define DOMID_SELF xen_mk_uint(0x7FF0) - -/* - * DOMID_IO is used to restrict page-table updates to mapping I/O memory. - * Although no Foreign Domain need be specified to map I/O pages, DOMID_IO - * is useful to ensure that no mappings to the OS's own heap are accidentally - * installed. (e.g., in Linux this could cause havoc as reference counts - * aren't adjusted on the I/O-mapping code path). - * This only makes sense as HYPERVISOR_mmu_update()'s and - * HYPERVISOR_update_va_mapping_otherdomain()'s "foreigndom" argument. For - * HYPERVISOR_mmu_update() context it can be specified by any calling domain, - * otherwise it's only permitted if the caller is privileged. - */ -#define DOMID_IO xen_mk_uint(0x7FF1) - -/* - * DOMID_XEN is used to allow privileged domains to map restricted parts of - * Xen's heap space (e.g., the machine_to_phys table). - * This only makes sense as - * - HYPERVISOR_mmu_update()'s, HYPERVISOR_mmuext_op()'s, or - * HYPERVISOR_update_va_mapping_otherdomain()'s "foreigndom" argument, - * - with XENMAPSPACE_gmfn_foreign, - * and is only permitted if the caller is privileged. - */ -#define DOMID_XEN xen_mk_uint(0x7FF2) - -/* - * DOMID_COW is used as the owner of sharable pages */ -#define DOMID_COW xen_mk_uint(0x7FF3) - -/* DOMID_INVALID is used to identify pages with unknown owner. */ -#define DOMID_INVALID xen_mk_uint(0x7FF4) - -/* Idle domain. */ -#define DOMID_IDLE xen_mk_uint(0x7FFF) - -#ifndef __ASSEMBLY__ - -typedef uint16_t domid_t; - -/* - * Send an array of these to HYPERVISOR_mmu_update(). - * NB. The fields are natural pointer/address size for this architecture. - */ -struct mmu_update { - uint64_t ptr; /* Machine address of PTE. */ - uint64_t val; /* New contents of PTE. */ -}; -typedef struct mmu_update mmu_update_t; -DEFINE_XEN_GUEST_HANDLE(mmu_update_t); - -/* - * ` enum neg_errnoval - * ` HYPERVISOR_multicall(multicall_entry_t call_list[], - * ` uint32_t nr_calls); - * - * NB. The fields are logically the natural register size for this - * architecture. In cases where xen_ulong_t is larger than this then - * any unused bits in the upper portion must be zero. - */ -struct multicall_entry { - xen_ulong_t op, result; - xen_ulong_t args[6]; -}; -typedef struct multicall_entry multicall_entry_t; -DEFINE_XEN_GUEST_HANDLE(multicall_entry_t); - -#if __XEN_INTERFACE_VERSION__ < 0x00040400 -/* - * Event channel endpoints per domain (when using the 2-level ABI): - * 1024 if a long is 32 bits; 4096 if a long is 64 bits. - */ -#define NR_EVENT_CHANNELS EVTCHN_2L_NR_CHANNELS -#endif - -struct vcpu_time_info { - /* - * Updates to the following values are preceded and followed by an - * increment of 'version'. The guest can therefore detect updates by - * looking for changes to 'version'. If the least-significant bit of - * the version number is set then an update is in progress and the guest - * must wait to read a consistent set of values. - * The correct way to interact with the version number is similar to - * Linux's seqlock: see the implementations of read_seqbegin/read_seqretry. - */ - uint32_t version; - uint32_t pad0; - uint64_t tsc_timestamp; /* TSC at last update of time vals. */ - uint64_t system_time; /* Time, in nanosecs, since boot. */ - /* - * Current system time: - * system_time + - * ((((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul) >> 32) - * CPU frequency (Hz): - * ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift - */ - uint32_t tsc_to_system_mul; - int8_t tsc_shift; -#if __XEN_INTERFACE_VERSION__ > 0x040600 - uint8_t flags; - uint8_t pad1[2]; -#else - int8_t pad1[3]; -#endif -}; /* 32 bytes */ -typedef struct vcpu_time_info vcpu_time_info_t; - -#define XEN_PVCLOCK_TSC_STABLE_BIT (1 << 0) -#define XEN_PVCLOCK_GUEST_STOPPED (1 << 1) - -struct vcpu_info { - /* - * 'evtchn_upcall_pending' is written non-zero by Xen to indicate - * a pending notification for a particular VCPU. It is then cleared - * by the guest OS /before/ checking for pending work, thus avoiding - * a set-and-check race. Note that the mask is only accessed by Xen - * on the CPU that is currently hosting the VCPU. This means that the - * pending and mask flags can be updated by the guest without special - * synchronisation (i.e., no need for the x86 LOCK prefix). - * This may seem suboptimal because if the pending flag is set by - * a different CPU then an IPI may be scheduled even when the mask - * is set. However, note: - * 1. The task of 'interrupt holdoff' is covered by the per-event- - * channel mask bits. A 'noisy' event that is continually being - * triggered can be masked at source at this very precise - * granularity. - * 2. The main purpose of the per-VCPU mask is therefore to restrict - * reentrant execution: whether for concurrency control, or to - * prevent unbounded stack usage. Whatever the purpose, we expect - * that the mask will be asserted only for short periods at a time, - * and so the likelihood of a 'spurious' IPI is suitably small. - * The mask is read before making an event upcall to the guest: a - * non-zero mask therefore guarantees that the VCPU will not receive - * an upcall activation. The mask is cleared when the VCPU requests - * to block: this avoids wakeup-waiting races. - */ - uint8_t evtchn_upcall_pending; -#ifdef XEN_HAVE_PV_UPCALL_MASK - uint8_t evtchn_upcall_mask; -#else /* XEN_HAVE_PV_UPCALL_MASK */ - uint8_t pad0; -#endif /* XEN_HAVE_PV_UPCALL_MASK */ - xen_ulong_t evtchn_pending_sel; - struct arch_vcpu_info arch; - struct vcpu_time_info time; -}; /* 64 bytes (x86) */ -#ifndef __XEN__ -typedef struct vcpu_info vcpu_info_t; -#endif - -/* - * `incontents 200 startofday_shared Start-of-day shared data structure - * Xen/kernel shared data -- pointer provided in start_info. - * - * This structure is defined to be both smaller than a page, and the - * only data on the shared page, but may vary in actual size even within - * compatible Xen versions; guests should not rely on the size - * of this structure remaining constant. - */ -struct shared_info { - struct vcpu_info vcpu_info[XEN_LEGACY_MAX_VCPUS]; - - /* - * A domain can create "event channels" on which it can send and receive - * asynchronous event notifications. There are three classes of event that - * are delivered by this mechanism: - * 1. Bi-directional inter- and intra-domain connections. Domains must - * arrange out-of-band to set up a connection (usually by allocating - * an unbound 'listener' port and avertising that via a storage service - * such as xenstore). - * 2. Physical interrupts. A domain with suitable hardware-access - * privileges can bind an event-channel port to a physical interrupt - * source. - * 3. Virtual interrupts ('events'). A domain can bind an event-channel - * port to a virtual interrupt source, such as the virtual-timer - * device or the emergency console. - * - * Event channels are addressed by a "port index". Each channel is - * associated with two bits of information: - * 1. PENDING -- notifies the domain that there is a pending notification - * to be processed. This bit is cleared by the guest. - * 2. MASK -- if this bit is clear then a 0->1 transition of PENDING - * will cause an asynchronous upcall to be scheduled. This bit is only - * updated by the guest. It is read-only within Xen. If a channel - * becomes pending while the channel is masked then the 'edge' is lost - * (i.e., when the channel is unmasked, the guest must manually handle - * pending notifications as no upcall will be scheduled by Xen). - * - * To expedite scanning of pending notifications, any 0->1 pending - * transition on an unmasked channel causes a corresponding bit in a - * per-vcpu selector word to be set. Each bit in the selector covers a - * 'C long' in the PENDING bitfield array. - */ - xen_ulong_t evtchn_pending[sizeof(xen_ulong_t) * 8]; - xen_ulong_t evtchn_mask[sizeof(xen_ulong_t) * 8]; - - /* - * Wallclock time: updated only by control software. Guests should base - * their gettimeofday() syscall on this wallclock-base value. - */ - uint32_t wc_version; /* Version counter: see vcpu_time_info_t. */ - uint32_t wc_sec; /* Secs 00:00:00 UTC, Jan 1, 1970. */ - uint32_t wc_nsec; /* Nsecs 00:00:00 UTC, Jan 1, 1970. */ -#if !defined(__i386__) - uint32_t wc_sec_hi; -# define xen_wc_sec_hi wc_sec_hi -#elif !defined(__XEN__) && !defined(__XEN_TOOLS__) -# define xen_wc_sec_hi arch.wc_sec_hi -#endif - - struct arch_shared_info arch; - -}; -#ifndef __XEN__ -typedef struct shared_info shared_info_t; -#endif - -/* - * `incontents 200 startofday Start-of-day memory layout - * - * 1. The domain is started within contiguous virtual-memory region. - * 2. The contiguous region ends on an aligned 4MB boundary. - * 3. This the order of bootstrap elements in the initial virtual region: - * a. relocated kernel image - * b. initial ram disk [mod_start, mod_len] - * (may be omitted) - * c. list of allocated page frames [mfn_list, nr_pages] - * (unless relocated due to XEN_ELFNOTE_INIT_P2M) - * d. start_info_t structure [register rSI (x86)] - * in case of dom0 this page contains the console info, too - * e. unless dom0: xenstore ring page - * f. unless dom0: console ring page - * g. bootstrap page tables [pt_base and CR3 (x86)] - * h. bootstrap stack [register ESP (x86)] - * 4. Bootstrap elements are packed together, but each is 4kB-aligned. - * 5. The list of page frames forms a contiguous 'pseudo-physical' memory - * layout for the domain. In particular, the bootstrap virtual-memory - * region is a 1:1 mapping to the first section of the pseudo-physical map. - * 6. All bootstrap elements are mapped read-writable for the guest OS. The - * only exception is the bootstrap page table, which is mapped read-only. - * 7. There is guaranteed to be at least 512kB padding after the final - * bootstrap element. If necessary, the bootstrap virtual region is - * extended by an extra 4MB to ensure this. - * - * Note: Prior to 25833:bb85bbccb1c9. ("x86/32-on-64 adjust Dom0 initial page - * table layout") a bug caused the pt_base (3.g above) and cr3 to not point - * to the start of the guest page tables (it was offset by two pages). - * This only manifested itself on 32-on-64 dom0 kernels and not 32-on-64 domU - * or 64-bit kernels of any colour. The page tables for a 32-on-64 dom0 got - * allocated in the order: 'first L1','first L2', 'first L3', so the offset - * to the page table base is by two pages back. The initial domain if it is - * 32-bit and runs under a 64-bit hypervisor should _NOT_ use two of the - * pages preceding pt_base and mark them as reserved/unused. - */ -#ifdef XEN_HAVE_PV_GUEST_ENTRY -struct start_info { - /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME. */ - char magic[32]; /* "xen--". */ - unsigned long nr_pages; /* Total pages allocated to this domain. */ - unsigned long shared_info; /* MACHINE address of shared info struct. */ - uint32_t flags; /* SIF_xxx flags. */ - xen_pfn_t store_mfn; /* MACHINE page number of shared page. */ - uint32_t store_evtchn; /* Event channel for store communication. */ - union { - struct { - xen_pfn_t mfn; /* MACHINE page number of console page. */ - uint32_t evtchn; /* Event channel for console page. */ - } domU; - struct { - uint32_t info_off; /* Offset of console_info struct. */ - uint32_t info_size; /* Size of console_info struct from start.*/ - } dom0; - } console; - /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME). */ - unsigned long pt_base; /* VIRTUAL address of page directory. */ - unsigned long nr_pt_frames; /* Number of bootstrap p.t. frames. */ - unsigned long mfn_list; /* VIRTUAL address of page-frame list. */ - unsigned long mod_start; /* VIRTUAL address of pre-loaded module */ - /* (PFN of pre-loaded module if */ - /* SIF_MOD_START_PFN set in flags). */ - unsigned long mod_len; /* Size (bytes) of pre-loaded module. */ -#define MAX_GUEST_CMDLINE 1024 - int8_t cmd_line[MAX_GUEST_CMDLINE]; - /* The pfn range here covers both page table and p->m table frames. */ - unsigned long first_p2m_pfn;/* 1st pfn forming initial P->M table. */ - unsigned long nr_p2m_frames;/* # of pfns forming initial P->M table. */ -}; -typedef struct start_info start_info_t; - -/* New console union for dom0 introduced in 0x00030203. */ -#if __XEN_INTERFACE_VERSION__ < 0x00030203 -#define console_mfn console.domU.mfn -#define console_evtchn console.domU.evtchn -#endif -#endif /* XEN_HAVE_PV_GUEST_ENTRY */ - -/* These flags are passed in the 'flags' field of start_info_t. */ -#define SIF_PRIVILEGED (1<<0) /* Is the domain privileged? */ -#define SIF_INITDOMAIN (1<<1) /* Is this the initial control domain? */ -#define SIF_MULTIBOOT_MOD (1<<2) /* Is mod_start a multiboot module? */ -#define SIF_MOD_START_PFN (1<<3) /* Is mod_start a PFN? */ -#define SIF_VIRT_P2M_4TOOLS (1<<4) /* Do Xen tools understand a virt. mapped */ - /* P->M making the 3 level tree obsolete? */ -#define SIF_PM_MASK (0xFF<<8) /* reserve 1 byte for xen-pm options */ - -/* - * A multiboot module is a package containing modules very similar to a - * multiboot module array. The only differences are: - * - the array of module descriptors is by convention simply at the beginning - * of the multiboot module, - * - addresses in the module descriptors are based on the beginning of the - * multiboot module, - * - the number of modules is determined by a termination descriptor that has - * mod_start == 0. - * - * This permits to both build it statically and reference it in a configuration - * file, and let the PV guest easily rebase the addresses to virtual addresses - * and at the same time count the number of modules. - */ -struct xen_multiboot_mod_list -{ - /* Address of first byte of the module */ - uint32_t mod_start; - /* Address of last byte of the module (inclusive) */ - uint32_t mod_end; - /* Address of zero-terminated command line */ - uint32_t cmdline; - /* Unused, must be zero */ - uint32_t pad; -}; -/* - * `incontents 200 startofday_dom0_console Dom0_console - * - * The console structure in start_info.console.dom0 - * - * This structure includes a variety of information required to - * have a working VGA/VESA console. - */ -typedef struct dom0_vga_console_info { - uint8_t video_type; /* DOM0_VGA_CONSOLE_??? */ -#define XEN_VGATYPE_TEXT_MODE_3 0x03 -#define XEN_VGATYPE_VESA_LFB 0x23 -#define XEN_VGATYPE_EFI_LFB 0x70 - - union { - struct { - /* Font height, in pixels. */ - uint16_t font_height; - /* Cursor location (column, row). */ - uint16_t cursor_x, cursor_y; - /* Number of rows and columns (dimensions in characters). */ - uint16_t rows, columns; - } text_mode_3; - - struct { - /* Width and height, in pixels. */ - uint16_t width, height; - /* Bytes per scan line. */ - uint16_t bytes_per_line; - /* Bits per pixel. */ - uint16_t bits_per_pixel; - /* LFB physical address, and size (in units of 64kB). */ - uint32_t lfb_base; - uint32_t lfb_size; - /* RGB mask offsets and sizes, as defined by VBE 1.2+ */ - uint8_t red_pos, red_size; - uint8_t green_pos, green_size; - uint8_t blue_pos, blue_size; - uint8_t rsvd_pos, rsvd_size; -#if __XEN_INTERFACE_VERSION__ >= 0x00030206 - /* VESA capabilities (offset 0xa, VESA command 0x4f00). */ - uint32_t gbl_caps; - /* Mode attributes (offset 0x0, VESA command 0x4f01). */ - uint16_t mode_attrs; -#endif - } vesa_lfb; - } u; -} dom0_vga_console_info_t; -#define xen_vga_console_info dom0_vga_console_info -#define xen_vga_console_info_t dom0_vga_console_info_t - -typedef uint8_t xen_domain_handle_t[16]; - -__DEFINE_XEN_GUEST_HANDLE(uint8, uint8_t); -__DEFINE_XEN_GUEST_HANDLE(uint16, uint16_t); -__DEFINE_XEN_GUEST_HANDLE(uint32, uint32_t); -__DEFINE_XEN_GUEST_HANDLE(uint64, uint64_t); - -typedef struct { - uint8_t a[16]; -} xen_uuid_t; - -/* - * XEN_DEFINE_UUID(0x00112233, 0x4455, 0x6677, 0x8899, - * 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff) - * will construct UUID 00112233-4455-6677-8899-aabbccddeeff presented as - * {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, - * 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; - * - * NB: This is compatible with Linux kernel and with libuuid, but it is not - * compatible with Microsoft, as they use mixed-endian encoding (some - * components are little-endian, some are big-endian). - */ -#define XEN_DEFINE_UUID_(a, b, c, d, e1, e2, e3, e4, e5, e6) \ - {{((a) >> 24) & 0xFF, ((a) >> 16) & 0xFF, \ - ((a) >> 8) & 0xFF, ((a) >> 0) & 0xFF, \ - ((b) >> 8) & 0xFF, ((b) >> 0) & 0xFF, \ - ((c) >> 8) & 0xFF, ((c) >> 0) & 0xFF, \ - ((d) >> 8) & 0xFF, ((d) >> 0) & 0xFF, \ - e1, e2, e3, e4, e5, e6}} - -#if defined(__STDC_VERSION__) ? __STDC_VERSION__ >= 199901L : defined(__GNUC__) -#define XEN_DEFINE_UUID(a, b, c, d, e1, e2, e3, e4, e5, e6) \ - ((xen_uuid_t)XEN_DEFINE_UUID_(a, b, c, d, e1, e2, e3, e4, e5, e6)) -#else -#define XEN_DEFINE_UUID(a, b, c, d, e1, e2, e3, e4, e5, e6) \ - XEN_DEFINE_UUID_(a, b, c, d, e1, e2, e3, e4, e5, e6) -#endif /* __STDC_VERSION__ / __GNUC__ */ - -#endif /* !__ASSEMBLY__ */ - -/* Default definitions for macros used by domctl/sysctl. */ -#if defined(__XEN__) || defined(__XEN_TOOLS__) - -#ifndef int64_aligned_t -#define int64_aligned_t int64_t -#endif -#ifndef uint64_aligned_t -#define uint64_aligned_t uint64_t -#endif -#ifndef XEN_GUEST_HANDLE_64 -#define XEN_GUEST_HANDLE_64(name) XEN_GUEST_HANDLE(name) -#endif - -#ifndef __ASSEMBLY__ -struct xenctl_bitmap { - XEN_GUEST_HANDLE_64(uint8) bitmap; - uint32_t nr_bits; -}; -#endif - -#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ - -#endif /* __XEN_PUBLIC_XEN_H__ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/io/bufio.c b/io/bufio.c new file mode 100644 index 000000000..92f29279e --- /dev/null +++ b/io/bufio.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include + +#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/io/gzio.c similarity index 73% rename from grub-core/io/gzio.c rename to io/gzio.c index cb7eb1fe3..9bf609105 100644 --- a/grub-core/io/gzio.c +++ b/io/gzio.c @@ -40,12 +40,7 @@ #include #include #include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); +#include /* * Window Size @@ -63,9 +58,6 @@ struct grub_gzio { /* The underlying file object. */ grub_file_t file; - /* If input is in memory following fields are used instead of file. */ - grub_size_t mem_input_size, mem_input_off; - grub_uint8_t *mem_input; /* The offset at which the data starts in the underlying file. */ grub_off_t data_offset; /* The type of current block. */ @@ -95,14 +87,6 @@ struct grub_gzio struct huft *tl; /* The distance code table. */ struct huft *td; - /* The checksum algorithm */ - const gcry_md_spec_t *hdesc; - /* The wanted checksum */ - grub_uint32_t orig_checksum; - /* The uncompressed length */ - grub_size_t orig_len; - /* Context for checksum calculation */ - grub_uint8_t *hcontext; /* The lookup bits for the literal/length code table. */ int bl; /* The lookup bits for the distance code table. */ @@ -116,7 +100,7 @@ typedef struct grub_gzio *grub_gzio_t; static struct grub_fs grub_gzio_fs; /* Function prototypes */ -static void initialize_tables (grub_gzio_t); +static void initialize_tables (grub_file_t file); /* Eat variable-length header fields. */ static int @@ -149,24 +133,24 @@ eat_field (grub_file_t file, int len) #define OLD_GZIP_MAGIC grub_le_to_cpu16 (0x9E1F) /* Compression methods (see algorithm.doc) */ -#define GRUB_GZ_STORED 0 -#define GRUB_GZ_COMPRESSED 1 -#define GRUB_GZ_PACKED 2 -#define GRUB_GZ_LZHED 3 +#define STORED 0 +#define COMPRESSED 1 +#define PACKED 2 +#define LZHED 3 /* methods 4 to 7 reserved */ -#define GRUB_GZ_DEFLATED 8 -#define GRUB_GZ_MAX_METHODS 9 +#define DEFLATED 8 +#define MAX_METHODS 9 /* gzip flag byte */ -#define GRUB_GZ_ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -#define GRUB_GZ_CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ -#define GRUB_GZ_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define GRUB_GZ_ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define GRUB_GZ_COMMENT 0x10 /* bit 4 set: file comment present */ -#define GRUB_GZ_ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ -#define GRUB_GZ_RESERVED 0xC0 /* bit 6,7: reserved */ +#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 GRUB_GZ_UNSUPPORTED_FLAGS (GRUB_GZ_CONTINUATION | GRUB_GZ_ENCRYPTED | GRUB_GZ_RESERVED) +#define UNSUPPORTED_FLAGS (CONTINUATION | ENCRYPTED | RESERVED) /* inflate block codes */ #define INFLATE_STORED 0 @@ -178,7 +162,7 @@ typedef unsigned short ush; typedef unsigned long ulg; static int -test_gzip_header (grub_file_t file) +test_header (grub_file_t file) { struct { grub_uint16_t magic; @@ -189,7 +173,7 @@ test_gzip_header (grub_file_t file) grub_uint8_t os_type; } hdr; grub_uint16_t extra_len; - grub_uint32_t crc32; + grub_uint32_t orig_len; grub_gzio_t gzio = file->data; if (grub_file_tell (gzio->file) != 0) @@ -203,39 +187,44 @@ test_gzip_header (grub_file_t file) if (grub_file_read (gzio->file, &hdr, 10) != 10 || ((hdr.magic != GZIP_MAGIC) && (hdr.magic != OLD_GZIP_MAGIC))) - return 0; + { + 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 != GRUB_GZ_DEFLATED - || (hdr.flags & GRUB_GZ_UNSUPPORTED_FLAGS) - || ((hdr.flags & GRUB_GZ_EXTRA_FIELD) + 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 & GRUB_GZ_ORIG_NAME) && eat_field (gzio->file, -1)) - || ((hdr.flags & GRUB_GZ_COMMENT) && eat_field (gzio->file, -1))) - return 0; + || ((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); - /* FIXME: don't do this on not easily seekable files. */ - { - grub_file_seek (gzio->file, grub_file_size (gzio->file) - 8); - if (grub_file_read (gzio->file, &crc32, 4) != 4) - return 0; - gzio->orig_checksum = grub_le_to_cpu32 (crc32); - if (grub_file_read (gzio->file, &gzio->orig_len, 4) != 4) - 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 (gzio->orig_len); - } + grub_file_seek (gzio->file, grub_file_size (gzio->file) - 4); - initialize_tables (gzio); + 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; } @@ -366,10 +355,6 @@ static int dbits = 6; /* bits in base distance lookup table */ 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. - - Note that NEEDBITS() can fail if the file is corrupt/truncated. - The GOTOFAILIFERROR, RETURNIFERROR and RETURN1IFERROR macros can - help. */ static ush mask_bits[] = @@ -379,63 +364,29 @@ static ush mask_bits[] = 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff }; -#define NEEDBITS(n) do {while(k<(n)){b|=((ulg)get_byte(gzio))<>=(n);k-=(n);} while (0) -#define RETURNIFERROR if (grub_errno != GRUB_ERR_NONE) return -#define RETURN1IFERROR if (grub_errno != GRUB_ERR_NONE) return 1 -#define GOTOFAILIFERROR if (grub_errno != GRUB_ERR_NONE) goto fail static int -get_byte (grub_gzio_t gzio) +get_byte (grub_file_t file) { - grub_ssize_t bytes_read; - if (gzio->mem_input) - { - if (gzio->mem_input_off < gzio->mem_input_size) - return gzio->mem_input[gzio->mem_input_off++]; - return 0; - } + grub_gzio_t gzio = file->data; - if (gzio->file && (grub_file_tell (gzio->file) - == (grub_off_t) gzio->data_offset - || gzio->inbuf_d == INBUFSIZ)) + if (grub_file_tell (gzio->file) == (grub_off_t) gzio->data_offset + || gzio->inbuf_d == INBUFSIZ) { gzio->inbuf_d = 0; - bytes_read = grub_file_read (gzio->file, gzio->inbuf, INBUFSIZ); - /* - * Only trigger if we get 0 bytes. If we get negative bytes there should - * be an existing GRUB error code that we don't want to overwrite. - */ - if (bytes_read == 0) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "File is too short"); - return 0; - } + grub_file_read (gzio->file, gzio->inbuf, INBUFSIZ); } return gzio->inbuf[gzio->inbuf_d++]; } -static void -gzio_seek (grub_gzio_t gzio, grub_off_t off) -{ - if (gzio->mem_input) - { - if (off > gzio->mem_input_size) - grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("attempt to seek outside of the file")); - else - gzio->mem_input_off = off; - } - else - grub_file_seek (gzio->file, off); -} - /* 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_gzio_t); +static int inflate_codes_in_window (grub_file_t); /* Given a list of code lengths and a maximum table size, make a set of @@ -464,7 +415,7 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ 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 = {0}; /* table entry for structure assignment */ + 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) */ @@ -524,7 +475,6 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ } /* Make a table of values in order of bit lengths */ - grub_memset (v, N_MAX, sizeof (v)); p = b; i = 0; do @@ -572,7 +522,7 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ z = 1 << j; /* table entries for j-bit table */ /* allocate and link in new table */ - q = (struct huft *) grub_calloc (z + 1, sizeof (struct huft)); + q = (struct huft *) grub_malloc ((z + 1) * sizeof (struct huft)); if (! q) { if (h) @@ -606,18 +556,11 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ r.v.n = (ush) (*p); /* simple code is just the value */ p++; /* one compiler does not like *p++ */ } - else if (*p < N_MAX) + else { r.e = (uch) e[*p - s]; /* non-simple--look up in lists */ r.v.n = d[*p++ - s]; } - else - { - /* Detected an uninitialised value, abort. */ - if (h) - huft_free (u[0]); - return 2; - } /* fill code-like entries with r */ f = 1 << (k - w); @@ -670,7 +613,7 @@ huft_free (struct huft *t) */ static int -inflate_codes_in_window (grub_gzio_t gzio) +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 */ @@ -679,6 +622,7 @@ inflate_codes_in_window (grub_gzio_t gzio) 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; @@ -694,26 +638,19 @@ inflate_codes_in_window (grub_gzio_t gzio) { if (! gzio->code_state) { - - if (gzio->tl == NULL) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "NULL gzio->tl"); - return 1; - } - - NEEDBITS ((unsigned) gzio->bl); RETURN1IFERROR; + NEEDBITS ((unsigned) gzio->bl); if ((e = (t = gzio->tl + ((unsigned) b & ml))->e) > 16) do { if (e == 99) { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + grub_error (GRUB_ERR_BAD_GZIP_DATA, "an unused code found"); return 1; } DUMPBITS (t->b); e -= 16; - NEEDBITS (e); RETURN1IFERROR; + NEEDBITS (e); } while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16); DUMPBITS (t->b); @@ -735,35 +672,29 @@ inflate_codes_in_window (grub_gzio_t gzio) } /* get length of block to copy */ - NEEDBITS (e); RETURN1IFERROR; + NEEDBITS (e); n = t->v.n + ((unsigned) b & mask_bits[e]); DUMPBITS (e); - if (gzio->td == NULL) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "NULL gzio->td"); - return 1; - } - /* decode distance of block to copy */ - NEEDBITS ((unsigned) gzio->bd); RETURN1IFERROR; + NEEDBITS ((unsigned) gzio->bd); if ((e = (t = gzio->td + ((unsigned) b & md))->e) > 16) do { if (e == 99) { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + grub_error (GRUB_ERR_BAD_GZIP_DATA, "an unused code found"); return 1; } DUMPBITS (t->b); e -= 16; - NEEDBITS (e); RETURN1IFERROR; + NEEDBITS (e); } while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16); DUMPBITS (t->b); - NEEDBITS (e); RETURN1IFERROR; + NEEDBITS (e); d = w - t->v.n - ((unsigned) b & mask_bits[e]); DUMPBITS (e); gzio->code_state++; @@ -819,10 +750,11 @@ inflate_codes_in_window (grub_gzio_t gzio) /* get header for an inflated type 0 (stored) block. */ static void -init_stored_block (grub_gzio_t gzio) +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 */ @@ -832,12 +764,12 @@ init_stored_block (grub_gzio_t gzio) DUMPBITS (k & 7); /* get the length and its complement */ - NEEDBITS (16); RETURNIFERROR; + NEEDBITS (16); gzio->block_len = ((unsigned) b & 0xffff); DUMPBITS (16); - NEEDBITS (16); RETURNIFERROR; + NEEDBITS (16); if (gzio->block_len != (int) ((~b) & 0xffff)) - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + grub_error (GRUB_ERR_BAD_GZIP_DATA, "the length of a stored block does not match"); DUMPBITS (16); @@ -852,10 +784,11 @@ init_stored_block (grub_gzio_t gzio) Huffman tables. */ static void -init_fixed_block (grub_gzio_t gzio) +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++) @@ -870,7 +803,7 @@ init_fixed_block (grub_gzio_t gzio) if (huft_build (l, 288, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0) { if (grub_errno == GRUB_ERR_NONE) - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + grub_error (GRUB_ERR_BAD_GZIP_DATA, "failed in building a Huffman code table"); return; } @@ -882,7 +815,7 @@ init_fixed_block (grub_gzio_t gzio) if (huft_build (l, 30, 0, cpdist, cpdext, &gzio->td, &gzio->bd) > 1) { if (grub_errno == GRUB_ERR_NONE) - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + grub_error (GRUB_ERR_BAD_GZIP_DATA, "failed in building a Huffman code table"); huft_free (gzio->tl); gzio->tl = 0; @@ -898,7 +831,7 @@ init_fixed_block (grub_gzio_t gzio) /* get header for an inflated type 2 (dynamic Huffman codes) block. */ static void -init_dynamic_block (grub_gzio_t gzio) +init_dynamic_block (grub_file_t file) { int i; /* temporary variables */ unsigned j; @@ -911,31 +844,32 @@ init_dynamic_block (grub_gzio_t gzio) 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); RETURNIFERROR; + NEEDBITS (5); nl = 257 + ((unsigned) b & 0x1f); /* number of literal/length codes */ DUMPBITS (5); - NEEDBITS (5); RETURNIFERROR; + NEEDBITS (5); nd = 1 + ((unsigned) b & 0x1f); /* number of distance codes */ DUMPBITS (5); - NEEDBITS (4); RETURNIFERROR; + NEEDBITS (4); nb = 4 + ((unsigned) b & 0xf); /* number of bit length codes */ DUMPBITS (4); if (nl > 286 || nd > 30) { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too much data"); + 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); RETURNIFERROR; + NEEDBITS (3); ll[bitorder[j]] = (unsigned) b & 7; DUMPBITS (3); } @@ -946,7 +880,7 @@ init_dynamic_block (grub_gzio_t gzio) gzio->bl = 7; if (huft_build (ll, 19, 19, NULL, NULL, &gzio->tl, &gzio->bl) != 0) { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + grub_error (GRUB_ERR_BAD_GZIP_DATA, "failed in building a Huffman code table"); return; } @@ -955,16 +889,9 @@ init_dynamic_block (grub_gzio_t gzio) n = nl + nd; m = mask_bits[gzio->bl]; i = l = 0; - - if (gzio->tl == NULL) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "NULL gzio->tl"); - return; - } - while ((unsigned) i < n) { - NEEDBITS ((unsigned) gzio->bl); GOTOFAILIFERROR; + NEEDBITS ((unsigned) gzio->bl); j = (gzio->td = gzio->tl + ((unsigned) b & m))->b; DUMPBITS (j); j = gzio->td->v.n; @@ -972,26 +899,26 @@ init_dynamic_block (grub_gzio_t gzio) ll[i++] = l = j; /* save last length in l */ else if (j == 16) /* repeat last length 3 to 6 times */ { - NEEDBITS (2); GOTOFAILIFERROR; + NEEDBITS (2); j = 3 + ((unsigned) b & 3); DUMPBITS (2); if ((unsigned) i + j > n) { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found"); - goto fail; + 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); GOTOFAILIFERROR; + NEEDBITS (3); j = 3 + ((unsigned) b & 7); DUMPBITS (3); if ((unsigned) i + j > n) { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found"); - goto fail; + grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found"); + return; } while (j--) ll[i++] = 0; @@ -1000,13 +927,13 @@ init_dynamic_block (grub_gzio_t gzio) else /* j == 18: 11 to 138 zero length codes */ { - NEEDBITS (7); GOTOFAILIFERROR; + NEEDBITS (7); j = 11 + ((unsigned) b & 0x7f); DUMPBITS (7); if ((unsigned) i + j > n) { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found"); - goto fail; + grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found"); + return; } while (j--) ll[i++] = 0; @@ -1027,8 +954,7 @@ init_dynamic_block (grub_gzio_t gzio) gzio->bl = lbits; if (huft_build (ll, nl, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0) { - gzio->tl = 0; - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + grub_error (GRUB_ERR_BAD_GZIP_DATA, "failed in building a Huffman code table"); return; } @@ -1037,8 +963,7 @@ init_dynamic_block (grub_gzio_t gzio) { huft_free (gzio->tl); gzio->tl = 0; - gzio->td = 0; - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + grub_error (GRUB_ERR_BAD_GZIP_DATA, "failed in building a Huffman code table"); return; } @@ -1046,32 +971,27 @@ init_dynamic_block (grub_gzio_t gzio) /* indicate we're now working on a block */ gzio->code_state = 0; gzio->block_len++; - return; - - fail: - huft_free (gzio->tl); - gzio->td = NULL; - gzio->tl = NULL; } static void -get_new_block (grub_gzio_t gzio) +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); RETURNIFERROR; + NEEDBITS (1); gzio->last_block = (int) b & 1; DUMPBITS (1); /* read in block type */ - NEEDBITS (2); RETURNIFERROR; + NEEDBITS (2); gzio->block_type = (unsigned) b & 3; DUMPBITS (2); @@ -1082,13 +1002,13 @@ get_new_block (grub_gzio_t gzio) switch (gzio->block_type) { case INFLATE_STORED: - init_stored_block (gzio); + init_stored_block (file); break; case INFLATE_FIXED: - init_fixed_block (gzio); + init_fixed_block (file); break; case INFLATE_DYNAMIC: - init_dynamic_block (gzio); + init_dynamic_block (file); break; default: break; @@ -1097,8 +1017,10 @@ get_new_block (grub_gzio_t gzio) static void -inflate_window (grub_gzio_t gzio) +inflate_window (grub_file_t file) { + grub_gzio_t gzio = file->data; + /* initialize window */ gzio->wp = 0; @@ -1113,11 +1035,11 @@ inflate_window (grub_gzio_t gzio) if (gzio->last_block) break; - get_new_block (gzio); + get_new_block (file); } if (gzio->block_type > INFLATE_DYNAMIC) - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + grub_error (GRUB_ERR_BAD_GZIP_DATA, "unknown block type %d", gzio->block_type); if (grub_errno != GRUB_ERR_NONE) @@ -1136,7 +1058,7 @@ inflate_window (grub_gzio_t gzio) while (gzio->block_len && w < WSIZE && grub_errno == GRUB_ERR_NONE) { - gzio->slide[w++] = get_byte (gzio); + gzio->slide[w++] = get_byte (file); gzio->block_len--; } @@ -1149,7 +1071,7 @@ inflate_window (grub_gzio_t gzio) * Expand other kind of block. */ - if (inflate_codes_in_window (gzio)) + if (inflate_codes_in_window (file)) { huft_free (gzio->tl); huft_free (gzio->td); @@ -1158,33 +1080,19 @@ inflate_window (grub_gzio_t gzio) } } - gzio->saved_offset += gzio->wp; + gzio->saved_offset += WSIZE; - if (gzio->hcontext) - { - gzio->hdesc->write (gzio->hcontext, gzio->slide, gzio->wp); - - if (gzio->saved_offset == gzio->orig_len) - { - grub_uint32_t csum; - - gzio->hdesc->final (gzio->hcontext); - csum = grub_get_unaligned32 (gzio->hdesc->read (gzio->hcontext)); - csum = grub_be_to_cpu32 (csum); - if (csum != gzio->orig_checksum) - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, - "checksum mismatch %08x/%08x", - gzio->orig_checksum, csum); - } - } + /* XXX do CRC calculation here! */ } static void -initialize_tables (grub_gzio_t gzio) +initialize_tables (grub_file_t file) { + grub_gzio_t gzio = file->data; + gzio->saved_offset = 0; - gzio_seek (gzio, gzio->data_offset); + grub_file_seek (gzio->file, gzio->data_offset); /* Initialize the bit buffer. */ gzio->bk = 0; @@ -1197,28 +1105,19 @@ initialize_tables (grub_gzio_t gzio) /* Reset memory allocation stuff. */ huft_free (gzio->tl); huft_free (gzio->td); - gzio->tl = NULL; - gzio->td = NULL; - - if (gzio->hcontext) - gzio->hdesc->init(gzio->hcontext); } -/* - * Open a new decompressing object on the top of IO. - * Note that this function won't close IO, even if an error occurs. - */ -static grub_file_t -grub_gzio_open (grub_file_t io, enum grub_file_type type) +/* 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; - if (type & GRUB_FILE_TYPE_NO_DECOMPRESS) - return io; - - file = (grub_file_t) grub_zalloc (sizeof (*file)); + file = (grub_file_t) grub_malloc (sizeof (*file)); if (! file) return 0; @@ -1231,89 +1130,60 @@ grub_gzio_open (grub_file_t io, enum grub_file_type type) gzio->file = io; - gzio->hdesc = GRUB_MD_CRC32; - gzio->hcontext = grub_malloc(gzio->hdesc->contextsize); - file->device = io->device; + file->offset = 0; file->data = gzio; + file->read_hook = 0; file->fs = &grub_gzio_fs; - file->not_easily_seekable = 1; - if (! test_gzip_header (file)) + if (! test_header (file)) { - grub_errno = GRUB_ERR_NONE; - grub_free (gzio->hcontext); grub_free (gzio); grub_free (file); grub_file_seek (io, 0); - return io; + if (grub_errno == GRUB_ERR_BAD_FILE_TYPE && transparent) + { + grub_errno = GRUB_ERR_NONE; + return io; + } + else + return 0; } return file; } -static grub_uint8_t -mod_31 (grub_uint16_t v) +/* 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) { - /* At most 2 iterations for any number that - we can get here. - In any case faster than real division. */ - while (v > 0x1f) - v = (v & 0x1f) + (v >> 5); - if (v == 0x1f) + grub_file_t io, file; + + io = grub_file_open (name); + if (! io) return 0; - return v; -} -static int -test_zlib_header (grub_gzio_t gzio) -{ - grub_uint8_t cmf, flg; - - cmf = get_byte (gzio); - flg = get_byte (gzio); - - /* Check that compression method is DEFLATE. */ - if ((cmf & 0xf) != GRUB_GZ_DEFLATED) + file = grub_gzio_open (io, transparent); + if (! file) { - /* TRANSLATORS: It's about given file having some strange format, not - complete lack of gzip support. */ - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, N_("unsupported gzip format")); + grub_file_close (io); return 0; } - /* Usually it would be: (cmf * 256 + flg) % 31 != 0. */ - /* But 256 == 8 (31). */ - /* By multiplying by 4 and using 32 == 1 (31). We get our formula. */ - if (mod_31 (cmf + flg * 4) != 0) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, N_("unsupported gzip format")); - return 0; - } - - /* Dictionary isn't supported. */ - if (flg & 0x20) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, N_("unsupported gzip format")); - return 0; - } - - gzio->data_offset = 2; - initialize_tables (gzio); - - return 1; + return file; } static grub_ssize_t -grub_gzio_read_real (grub_gzio_t gzio, grub_off_t offset, - char *buf, grub_size_t len) +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 > offset + WSIZE) - initialize_tables (gzio); + if (gzio->saved_offset > file->offset + WSIZE) + initialize_tables (file); /* * This loop operates upon uncompressed data only. The only @@ -1321,20 +1191,15 @@ grub_gzio_read_real (grub_gzio_t gzio, grub_off_t offset, * 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 (gzio); - if (gzio->wp == 0) - goto out; - } - - if (gzio->wp == 0) - goto out; + inflate_window (file); srcaddr = (char *) ((offset & (WSIZE - 1)) + gzio->slide); size = gzio->saved_offset - offset; @@ -1349,27 +1214,12 @@ grub_gzio_read_real (grub_gzio_t gzio, grub_off_t offset, offset += size; } - out: if (grub_errno != GRUB_ERR_NONE) ret = -1; return ret; } -static grub_ssize_t -grub_gzio_read (grub_file_t file, char *buf, grub_size_t len) -{ - grub_ssize_t ret; - ret = grub_gzio_read_real (file->data, file->offset, buf, len); - - if (!grub_errno && ret != (grub_ssize_t) len) - { - grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "premature end of compressed"); - ret = -1; - } - return ret; -} - /* Release everything, including the underlying file object. */ static grub_err_t grub_gzio_close (grub_file_t file) @@ -1379,84 +1229,23 @@ grub_gzio_close (grub_file_t file) grub_file_close (gzio->file); huft_free (gzio->tl); huft_free (gzio->td); - grub_free (gzio->hcontext); grub_free (gzio); /* No need to close the same device twice. */ file->device = 0; - file->name = 0; return grub_errno; } -grub_ssize_t -grub_zlib_decompress (char *inbuf, grub_size_t insize, grub_off_t off, - char *outbuf, grub_size_t outsize) -{ - grub_gzio_t gzio = 0; - grub_ssize_t ret; - - gzio = grub_zalloc (sizeof (*gzio)); - if (! gzio) - return -1; - gzio->mem_input = (grub_uint8_t *) inbuf; - gzio->mem_input_size = insize; - gzio->mem_input_off = 0; - - if (!test_zlib_header (gzio)) - { - grub_free (gzio); - return -1; - } - - ret = grub_gzio_read_real (gzio, off, outbuf, outsize); - grub_free (gzio); - - /* FIXME: Check Adler. */ - return ret; -} - -grub_ssize_t -grub_deflate_decompress (char *inbuf, grub_size_t insize, grub_off_t off, - char *outbuf, grub_size_t outsize) -{ - grub_gzio_t gzio = 0; - grub_ssize_t ret; - - gzio = grub_zalloc (sizeof (*gzio)); - if (! gzio) - return -1; - gzio->mem_input = (grub_uint8_t *) inbuf; - gzio->mem_input_size = insize; - gzio->mem_input_off = 0; - - initialize_tables (gzio); - - ret = grub_gzio_read_real (gzio, off, outbuf, outsize); - grub_free (gzio); - - return ret; -} - static struct grub_fs grub_gzio_fs = { .name = "gzio", - .fs_dir = 0, - .fs_open = 0, - .fs_read = grub_gzio_read, - .fs_close = grub_gzio_close, - .fs_label = 0, + .dir = 0, + .open = 0, + .read = grub_gzio_read, + .close = grub_gzio_close, + .label = 0, .next = 0 }; - -GRUB_MOD_INIT(gzio) -{ - grub_file_filter_register (GRUB_FILE_FILTER_GZIO, grub_gzio_open); -} - -GRUB_MOD_FINI(gzio) -{ - grub_file_filter_unregister (GRUB_FILE_FILTER_GZIO); -} diff --git a/kern/command.c b/kern/command.c new file mode 100644 index 000000000..477240d57 --- /dev/null +++ b/kern/command.c @@ -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 . + */ + +#include +#include + +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/kern/corecmd.c similarity index 73% rename from grub-core/kern/corecmd.c rename to kern/corecmd.c index 62d434ba9..8b8df63cb 100644 --- a/grub-core/kern/corecmd.c +++ b/kern/corecmd.c @@ -26,7 +26,6 @@ #include #include #include -#include /* set ENVVAR=VALUE */ static grub_err_t @@ -36,14 +35,17 @@ grub_core_cmd_set (struct grub_command *cmd __attribute__ ((unused)), 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) { - struct grub_env_var *env; - FOR_SORTED_ENV (env) - { - val = (char *) grub_env_get (env->name); - grub_printf ("%s='%s'\n", env->name, val == NULL ? "" : val); - } + grub_env_iterate (print_env); return 0; } @@ -65,7 +67,7 @@ grub_core_cmd_unset (struct grub_command *cmd __attribute__ ((unused)), { if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("one argument expected")); + "no environment variable specified"); grub_env_unset (argv[0]); return 0; @@ -76,15 +78,17 @@ 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, N_("one argument expected")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified"); - if (argv[0][0] == '/' || argv[0][0] == '(' || argv[0][0] == '+') - mod = grub_dl_load_file (argv[0]); - else + 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); @@ -93,7 +97,7 @@ grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)), } static int -grub_mini_print_devices (const char *name, void *data __attribute__ ((unused))) +grub_mini_print_devices (const char *name) { grub_printf ("(%s) ", name); @@ -102,8 +106,7 @@ grub_mini_print_devices (const char *name, void *data __attribute__ ((unused))) static int grub_mini_print_files (const char *filename, - const struct grub_dirhook_info *info, - void *data __attribute__ ((unused))) + const struct grub_dirhook_info *info) { grub_printf ("%s%s ", filename, info->dir ? "/" : ""); @@ -117,20 +120,18 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)), { if (argc < 1) { - grub_device_iterate (grub_mini_print_devices, NULL); - grub_xputs ("\n"); + grub_device_iterate (grub_mini_print_devices); + grub_putchar ('\n'); grub_refresh (); } else { char *device_name; - grub_device_t dev = 0; + grub_device_t dev; grub_fs_t fs; char *path; device_name = grub_file_get_device_name (argv[0]); - if (grub_errno) - goto fail; dev = grub_device_open (device_name); if (! dev) goto fail; @@ -142,13 +143,13 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)), else path++; - if (! *path && ! device_name) + if (! path && ! device_name) { grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument"); goto fail; } - if (! *path) + if (! path) { if (grub_errno == GRUB_ERR_UNKNOWN_FS) grub_errno = GRUB_ERR_NONE; @@ -158,8 +159,8 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)), } else if (fs) { - (fs->fs_dir) (dev, path, grub_mini_print_files, NULL); - grub_xputs ("\n"); + (fs->dir) (dev, path, grub_mini_print_files); + grub_putchar ('\n'); grub_refresh (); } @@ -176,17 +177,12 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)), void grub_register_core_commands (void) { - grub_command_t cmd; - cmd = grub_register_command ("set", grub_core_cmd_set, - N_("[ENVVAR=VALUE]"), - N_("Set an environment variable.")); - if (cmd) - cmd->flags |= GRUB_COMMAND_FLAG_EXTRACTOR; + grub_register_command ("set", grub_core_cmd_set, + "[ENVVAR=VALUE]", "Set an environment variable."); grub_register_command ("unset", grub_core_cmd_unset, - N_("ENVVAR"), - N_("Remove an environment variable.")); + "ENVVAR", "Remove an environment variable."); grub_register_command ("ls", grub_core_cmd_ls, - N_("[ARG]"), N_("List devices or files.")); + "[ARG]", "List devices or files."); grub_register_command ("insmod", grub_core_cmd_insmod, - N_("MODULE"), N_("Insert a module.")); + "MODULE", "Insert a module."); } diff --git a/kern/device.c b/kern/device.c new file mode 100644 index 000000000..cd019fdaf --- /dev/null +++ b/kern/device.c @@ -0,0 +1,166 @@ +/* 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +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) + 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 new file mode 100644 index 000000000..5c30e1727 --- /dev/null +++ b/kern/disk.c @@ -0,0 +1,601 @@ +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} + + + +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_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 (); + + grub_free (disk->partition); + 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) +{ + *sector += *offset >> GRUB_DISK_SECTOR_BITS; + *offset &= GRUB_DISK_SECTOR_SIZE - 1; + + if (disk->partition) + { + grub_disk_addr_t start; + grub_uint64_t len; + + start = grub_partition_get_start (disk->partition); + len = grub_partition_get_len (disk->partition); + + 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, §or, &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, §or, &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/kern/dl.c similarity index 50% rename from grub-core/kern/dl.c rename to kern/dl.c index de8c3aa8d..4735a004a 100644 --- a/grub-core/kern/dl.c +++ b/kern/dl.c @@ -31,55 +31,79 @@ #include #include #include -#include -#include - -#ifdef GRUB_MACHINE_EFI -#include -#endif /* Platforms where modules are in a readonly area of memory. */ #if defined(GRUB_MACHINE_QEMU) #define GRUB_MODULES_MACHINE_READONLY #endif -#ifdef GRUB_MACHINE_EFI -#define DL_ALIGN GRUB_EFI_PAGE_SIZE -#else -#define DL_ALIGN 1 -#endif + -#pragma GCC diagnostic ignored "-Wcast-align" +struct grub_dl_list +{ + struct grub_dl_list *next; + grub_dl_t mod; +}; +typedef struct grub_dl_list *grub_dl_list_t; -grub_dl_t grub_dl_head = 0; +static grub_dl_list_t grub_dl_head; -grub_err_t -grub_dl_add (grub_dl_t mod); - -/* Keep global so that GDB scripts work. */ -grub_err_t +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_t *p, q; + grub_dl_list_t *p, q; for (p = &grub_dl_head, q = *p; q; p = &q->next, q = *p) - if (q == mod) + 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; +} + struct grub_symbol @@ -87,7 +111,6 @@ struct grub_symbol struct grub_symbol *next; const char *name; void *addr; - int isfunc; grub_dl_t mod; /* The module to which this symbol belongs. */ }; typedef struct grub_symbol *grub_symbol_t; @@ -112,22 +135,21 @@ grub_symbol_hash (const char *s) /* Resolve the symbol name NAME and return the address. Return NULL, if not found. */ -static grub_symbol_t +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; + 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, int isfunc, - grub_dl_t mod) +grub_dl_register_symbol (const char *name, void *addr, grub_dl_t mod) { grub_symbol_t sym; unsigned k; @@ -150,7 +172,6 @@ grub_dl_register_symbol (const char *name, void *addr, int isfunc, sym->addr = addr; sym->mod = mod; - sym->isfunc = isfunc; k = grub_symbol_hash (name); sym->next = grub_symtab[k]; @@ -205,24 +226,20 @@ static grub_err_t grub_dl_check_header (void *ehdr, grub_size_t size) { Elf_Ehdr *e = ehdr; - grub_err_t err; /* 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 (e->e_ident[EI_MAG0] != ELFMAG0 + 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, N_("invalid arch-independent ELF magic")); - - err = grub_arch_dl_check_header (ehdr); - if (err) - return err; + return grub_error (GRUB_ERR_BAD_OS, "invalid arch independent ELF magic"); return GRUB_ERR_NONE; } @@ -232,67 +249,12 @@ static grub_err_t grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) { unsigned i; - const Elf_Shdr *s; - grub_size_t tsize = 0, talign = 1, arch_addralign = 1; -#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \ - !defined (__loongarch__) - grub_size_t tramp; - grub_size_t tramp_align; - grub_size_t got; - grub_size_t got_align; - grub_err_t err; -#endif - char *ptr; - - arch_addralign = DL_ALIGN; - - for (i = 0, s = (const Elf_Shdr *)((const char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (const Elf_Shdr *)((const char *) s + e->e_shentsize)) - { - grub_size_t sh_addralign; - grub_size_t sh_size; - - if (s->sh_size == 0 || !(s->sh_flags & SHF_ALLOC)) - continue; - - sh_addralign = ALIGN_UP (s->sh_addralign, arch_addralign); - sh_size = ALIGN_UP (s->sh_size, sh_addralign); - - tsize = ALIGN_UP (tsize, sh_addralign) + sh_size; - talign = grub_max (talign, sh_addralign); - } - -#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \ - !defined (__loongarch__) - err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got); - if (err) - return err; - tramp_align = grub_max (GRUB_ARCH_DL_TRAMP_ALIGN, arch_addralign); - tsize += ALIGN_UP (tramp, tramp_align); - talign = grub_max (talign, tramp_align); - got_align = grub_max (GRUB_ARCH_DL_GOT_ALIGN, arch_addralign); - tsize += ALIGN_UP (got, got_align); - talign = grub_max (talign, got_align); -#endif - -#ifdef GRUB_MACHINE_EMU - mod->base = grub_osdep_dl_memalign (talign, tsize); -#else - mod->base = grub_memalign (talign, tsize); -#endif - if (!mod->base) - return grub_errno; - mod->sz = tsize; - ptr = mod->base; + 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)) { - grub_size_t sh_addralign = ALIGN_UP (s->sh_addralign, arch_addralign); - grub_size_t sh_size = ALIGN_UP (s->sh_size, sh_addralign); - if (s->sh_flags & SHF_ALLOC) { grub_dl_segment_t seg; @@ -305,18 +267,20 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) { void *addr; - ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, sh_addralign); - addr = ptr; - ptr += sh_size; + 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); - grub_memset ((char *) addr + s->sh_size, 0, sh_size - s->sh_size); break; case SHT_NOBITS: - grub_memset (addr, 0, sh_size); + grub_memset (addr, 0, s->sh_size); break; } @@ -325,23 +289,12 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) else seg->addr = 0; - seg->size = sh_size; + seg->size = s->sh_size; seg->section = i; seg->next = mod->segment; mod->segment = seg; } } -#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \ - !defined (__loongarch__) - ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, tramp_align); - mod->tramp = ptr; - mod->trampptr = ptr; - ptr += tramp; - ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, got_align); - mod->got = ptr; - mod->gotptr = ptr; - ptr += got; -#endif return GRUB_ERR_NONE; } @@ -361,21 +314,15 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) if (s->sh_type == SHT_SYMTAB) break; - /* Module without symbol table may still be used to pull in dependencies. - We verify at build time that such modules do not contain any relocations - that may reference symbol table. */ if (i == e->e_shnum) - return GRUB_ERR_NONE; + return grub_error (GRUB_ERR_BAD_MODULE, "no symbol table"); #ifdef GRUB_MODULES_MACHINE_READONLY mod->symtab = grub_malloc (s->sh_size); - if (!mod->symtab) - return grub_errno; - grub_memcpy (mod->symtab, (char *) e + s->sh_offset, 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 - mod->symsize = s->sh_entsize; sym = mod->symtab; size = s->sh_size; entsize = s->sh_entsize; @@ -398,20 +345,17 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) /* Resolve a global symbol. */ if (sym->st_name != 0 && sym->st_shndx == 0) { - grub_symbol_t nsym = grub_dl_resolve_symbol (name); - if (! nsym) + sym->st_value = (Elf_Addr) grub_dl_resolve_symbol (name); + if (! sym->st_value) return grub_error (GRUB_ERR_BAD_MODULE, - N_("symbol `%s' not found"), name); - sym->st_value = (Elf_Addr) nsym->addr; - if (nsym->isfunc) - sym->st_info = ELF_ST_INFO (bind, STT_FUNC); + "the symbol `%s' not found", 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, 0, mod)) + if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) return grub_errno; } break; @@ -419,21 +363,10 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) case STT_FUNC: sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod, sym->st_shndx); -#ifdef __ia64__ - { - /* FIXME: free descriptor once it's not used anymore. */ - char **desc; - desc = grub_malloc (2 * sizeof (char *)); - if (!desc) - return grub_errno; - desc[0] = (void *) sym->st_value; - desc[1] = mod->base; - sym->st_value = (grub_addr_t) desc; - } -#endif if (bind != STB_LOCAL) - if (grub_dl_register_symbol (name, (void *) sym->st_value, 1, mod)) + 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) @@ -458,8 +391,15 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) return GRUB_ERR_NONE; } -static Elf_Shdr * -grub_dl_find_section (Elf_Ehdr *e, const char *name) +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; @@ -471,51 +411,17 @@ grub_dl_find_section (Elf_Ehdr *e, const char *name) 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, name) == 0) - return s; - return NULL; -} + 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; + } -/* Me, Vladimir Serbinenko, hereby I add this module check as per new - GNU module policy. Note that this license check is informative only. - Modules have to be licensed under GPLv3 or GPLv3+ (optionally - multi-licensed under other licences as well) independently of the - presence of this check and solely by linking (module loading in GRUB - constitutes linking) and GRUB core being licensed under GPLv3+. - Be sure to understand your license obligations. -*/ -static grub_err_t -grub_dl_check_license (grub_dl_t mod, Elf_Ehdr *e) -{ - Elf_Shdr *s = grub_dl_find_section (e, ".module_license"); - - if (s == NULL) - return grub_error (GRUB_ERR_BAD_MODULE, - "no license section in module %.63s", mod->name); - - if (grub_strcmp ((char *) e + s->sh_offset, "LICENSE=GPLv3") == 0 - || grub_strcmp ((char *) e + s->sh_offset, "LICENSE=GPLv3+") == 0 - || grub_strcmp ((char *) e + s->sh_offset, "LICENSE=GPLv2+") == 0) - return GRUB_ERR_NONE; - - return grub_error (GRUB_ERR_BAD_MODULE, - "incompatible license in module %.63s: %.63s", mod->name, - (char *) e + s->sh_offset); -} - -static grub_err_t -grub_dl_resolve_name (grub_dl_t mod, Elf_Ehdr *e) -{ - Elf_Shdr *s; - - s = grub_dl_find_section (e, ".modname"); - if (!s) + if (i == e->e_shnum) return grub_error (GRUB_ERR_BAD_MODULE, "no module name found"); - mod->name = grub_strdup ((char *) e + s->sh_offset); - if (! mod->name) - return grub_errno; - return GRUB_ERR_NONE; } @@ -523,219 +429,87 @@ static grub_err_t grub_dl_resolve_dependencies (grub_dl_t mod, Elf_Ehdr *e) { Elf_Shdr *s; - - s = grub_dl_find_section (e, ".moddeps"); - - if (!s) - return GRUB_ERR_NONE; - - 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; -} - -grub_uint64_t -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); - - if (grub_add (mod->ref_count, 1, &mod->ref_count)) - grub_fatal ("Module reference count overflow"); - - return mod->ref_count; -} - -grub_uint64_t -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); - - if (grub_sub (mod->ref_count, 1, &mod->ref_count)) - grub_fatal ("Module reference count underflow"); - - return mod->ref_count; -} - -grub_uint64_t -grub_dl_ref_count (grub_dl_t mod) -{ - if (mod == NULL) - return 0; - - return mod->ref_count; -} - -static void -grub_dl_flush_cache (grub_dl_t mod) -{ - grub_dprintf ("modules", "flushing 0x%lx bytes at %p\n", - (unsigned long) mod->sz, mod->base); - grub_arch_sync_caches (mod->base, mod->sz); -} - -static grub_err_t -grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr) -{ - Elf_Ehdr *e = ehdr; - 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 (s->sh_type == SHT_REL || s->sh_type == SHT_RELA) + if (grub_strcmp (str + s->sh_name, ".moddeps") == 0) { - grub_dl_segment_t seg; - grub_err_t err; + const char *name = (char *) e + s->sh_offset; + const char *max = name + s->sh_size; - if (!(s->sh_flags & SHF_INFO_LINK)) - continue; - - /* Find the target segment. */ - for (seg = mod->segment; seg; seg = seg->next) - if (seg->section == s->sh_info) - break; - - if (seg) + while ((name < max) && (*name)) { - if (!mod->symtab) - return grub_error (GRUB_ERR_BAD_MODULE, "relocation without symbol table"); + grub_dl_t m; + grub_dl_dep_t dep; - err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg); - if (err) - return err; + 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; } -/* Only define this on EFI to save space in core. */ -#ifdef GRUB_MACHINE_EFI -static grub_err_t -grub_dl_set_mem_attrs (grub_dl_t mod, void *ehdr) +#ifndef GRUB_UTIL +int +grub_dl_ref (grub_dl_t mod) { - unsigned i; - const Elf_Shdr *s; - const Elf_Ehdr *e = ehdr; - grub_err_t err; -#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \ - !defined (__loongarch__) - grub_size_t arch_addralign = DL_ALIGN; - grub_addr_t tgaddr; - grub_size_t tgsz; -#endif + grub_dl_dep_t dep; - for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize)) - { - grub_dl_segment_t seg; - grub_uint64_t set_attrs = GRUB_MEM_ATTR_R; - grub_uint64_t clear_attrs = GRUB_MEM_ATTR_W | GRUB_MEM_ATTR_X; + for (dep = mod->dep; dep; dep = dep->next) + grub_dl_ref (dep->mod); - for (seg = mod->segment; seg; seg = seg->next) - /* Does this ELF section's index match GRUB DL segment? */ - if (seg->section == i) - break; - - /* No GRUB DL segment found for this ELF section, skip it. */ - if (!seg) - continue; - - if (seg->size == 0 || !(s->sh_flags & SHF_ALLOC)) - continue; - - if (s->sh_flags & SHF_WRITE) - { - set_attrs |= GRUB_MEM_ATTR_W; - clear_attrs &= ~GRUB_MEM_ATTR_W; - } - - if (s->sh_flags & SHF_EXECINSTR) - { - set_attrs |= GRUB_MEM_ATTR_X; - clear_attrs &= ~GRUB_MEM_ATTR_X; - } - - err = grub_update_mem_attrs ((grub_addr_t) seg->addr, seg->size, - set_attrs, clear_attrs); - if (err != GRUB_ERR_NONE) - return err; - } - -#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \ - !defined (__loongarch__) - tgaddr = grub_min ((grub_addr_t) mod->tramp, (grub_addr_t) mod->got); - tgsz = grub_max ((grub_addr_t) mod->trampptr, (grub_addr_t) mod->gotptr) - tgaddr; - - if (tgsz) - { - tgsz = ALIGN_UP (tgsz, arch_addralign); - - if (tgaddr < (grub_addr_t) mod->base || - tgsz > (grub_addr_t) -1 - tgaddr || - tgaddr + tgsz > (grub_addr_t) mod->base + mod->sz) - return grub_error (GRUB_ERR_BUG, - "BUG: trying to protect pages outside of module " - "allocation (\"%s\"): module base %p, size 0x%" - PRIxGRUB_SIZE "; tramp/GOT base 0x%" PRIxGRUB_ADDR - ", size 0x%" PRIxGRUB_SIZE, - mod->name, mod->base, mod->sz, tgaddr, tgsz); - err = grub_update_mem_attrs (tgaddr, tgsz, GRUB_MEM_ATTR_R | GRUB_MEM_ATTR_X, GRUB_MEM_ATTR_W); - if (err != GRUB_ERR_NONE) - return err; - } -#endif - - return GRUB_ERR_NONE; + return ++mod->ref_count; } -#else -static grub_err_t -grub_dl_set_mem_attrs (grub_dl_t mod __attribute__ ((unused)), void *ehdr __attribute__ ((unused))) + +int +grub_dl_unref (grub_dl_t mod) { - return GRUB_ERR_NONE; + 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_noinit (void *addr, grub_size_t size) +grub_dl_load_core (void *addr, grub_size_t size) { Elf_Ehdr *e; grub_dl_t mod; @@ -748,12 +522,12 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size) if (e->e_type != ET_REL) { - grub_error (GRUB_ERR_BAD_MODULE, N_("this ELF file is not of the right type")); + 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 + (grub_uint32_t) e->e_shentsize * e->e_shnum) + if (size < e->e_shoff + e->e_shentsize * e->e_shnum) { grub_error (GRUB_ERR_BAD_OS, "ELF sections outside core"); return 0; @@ -766,21 +540,11 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size) mod->ref_count = 1; grub_dprintf ("modules", "relocating to %p\n", mod); - /* Me, Vladimir Serbinenko, hereby I add this module check as per new - GNU module policy. Note that this license check is informative only. - Modules have to be licensed under GPLv3 or GPLv3+ (optionally - multi-licensed under other licences as well) independently of the - presence of this check and solely by linking (module loading in GRUB - constitutes linking) and GRUB core being licensed under GPLv3+. - Be sure to understand your license obligations. - */ if (grub_dl_resolve_name (mod, e) - || grub_dl_check_license (mod, e) || grub_dl_resolve_dependencies (mod, e) || grub_dl_load_segments (mod, e) || grub_dl_resolve_symbols (mod, e) - || grub_dl_relocate_symbols (mod, e) - || grub_dl_set_mem_attrs (mod, e)) + || grub_arch_dl_relocate_symbols (mod, e)) { mod->fini = 0; grub_dl_unload (mod); @@ -791,6 +555,7 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size) 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)) { @@ -801,25 +566,6 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size) return mod; } -grub_dl_t -grub_dl_load_core (void *addr, grub_size_t size) -{ - grub_dl_t mod; - - grub_boot_time ("Parsing module"); - - mod = grub_dl_load_core_noinit (addr, size); - - if (!mod) - return NULL; - - grub_boot_time ("Initing module %s", mod->name); - grub_dl_init (mod); - grub_boot_time ("Module %s inited", mod->name); - - return mod; -} - /* Load a module from the file FILENAME. */ grub_dl_t grub_dl_load_file (const char *filename) @@ -829,9 +575,7 @@ grub_dl_load_file (const char *filename) void *core = 0; grub_dl_t mod = 0; - grub_boot_time ("Loading module %s", filename); - - file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE); + file = grub_file_open (filename); if (! file) return 0; @@ -856,11 +600,13 @@ grub_dl_load_file (const char *filename) grub_file_close (file); mod = grub_dl_load_core (core, size); - grub_free (core); if (! mod) - return 0; + { + grub_free (core); + return 0; + } - mod->ref_count--; + mod->ref_count = 0; return mod; } @@ -870,22 +616,18 @@ grub_dl_load (const char *name) { char *filename; grub_dl_t mod; - const char *grub_dl_dir = grub_env_get ("prefix"); + char *grub_dl_dir = grub_env_get ("prefix"); mod = grub_dl_get (name); if (mod) return mod; - if (grub_no_modules) - return 0; - if (! grub_dl_dir) { - grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix"); + grub_error (GRUB_ERR_FILE_NOT_FOUND, "\"prefix\" is not set"); return 0; } - filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM "/%s.mod", - grub_dl_dir, name); + filename = grub_xasprintf ("%s/%s.mod", grub_dl_dir, name); if (! filename) return 0; @@ -906,6 +648,7 @@ 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; @@ -920,16 +663,19 @@ grub_dl_unload (grub_dl_t mod) { depn = dep->next; - grub_dl_unload (dep->mod); + if (! grub_dl_unref (dep->mod)) + grub_dl_unload (dep->mod); grub_free (dep); } -#ifdef GRUB_MACHINE_EMU - grub_dl_osdep_dl_free (mod->base); -#else - grub_free (mod->base); -#endif + 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); @@ -937,3 +683,40 @@ grub_dl_unload (grub_dl_t mod) 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 new file mode 100644 index 000000000..d8b225535 --- /dev/null +++ b/kern/efi/efi.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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 new file mode 100644 index 000000000..a0b4ff779 --- /dev/null +++ b/kern/efi/init.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +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 new file mode 100644 index 000000000..ceb8fc9ba --- /dev/null +++ b/kern/efi/mm.c @@ -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 . + */ + +#include +#include +#include +#include + +#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 new file mode 100644 index 000000000..d9948a822 --- /dev/null +++ b/kern/elf.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +/* 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; +} + + +/* 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; +} + + + +/* 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/env.c b/kern/env.c similarity index 82% rename from grub-core/kern/env.c rename to kern/env.c index 764068896..84b3a001d 100644 --- a/grub-core/kern/env.c +++ b/kern/env.c @@ -41,7 +41,7 @@ grub_env_hashval (const char *s) return i % HASHSZ; } -static struct grub_env_var * +struct grub_env_var * grub_env_find (const char *name) { struct grub_env_var *var; @@ -109,6 +109,9 @@ grub_env_set (const char *name, const char *val) 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; @@ -129,7 +132,7 @@ grub_env_set (const char *name, const char *val) return grub_errno; } -const char * +char * grub_env_get (const char *name) { struct grub_env_var *var; @@ -144,19 +147,6 @@ grub_env_get (const char *name) return var->value; } -bool -grub_env_get_bool (const char *name, bool if_unset) -{ - const char *val = grub_env_get (name); - - if (val == NULL || grub_strlen (val) < 1) - return if_unset; - if (grub_strcmp (val, "0") == 0 || grub_strcmp (val, "false") == 0 || - grub_strcmp (val, "disable") == 0 || grub_strcmp (val, "no") == 0) - return false; - return true; -} - void grub_env_unset (const char *name) { @@ -179,10 +169,11 @@ grub_env_unset (const char *name) grub_free (var); } -struct grub_env_var * -grub_env_update_get_sorted (void) +void +grub_env_iterate (int (*func) (struct grub_env_var *var)) { - struct grub_env_var *sorted_list = 0; + 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. */ @@ -192,20 +183,40 @@ grub_env_update_get_sorted (void) for (var = grub_current_context->vars[i]; var; var = var->next) { - struct grub_env_var *p, **q; + struct grub_env_sorted_var *p, **q; - for (q = &sorted_list, p = *q; p; q = &((*q)->sorted_next), 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->name, var->name) > 0) + if (grub_strcmp (p->var->name, var->name) > 0) break; } - var->sorted_next = *q; - *q = var; + sorted_var->next = *q; + *q = sorted_var; } } - return sorted_list; + /* 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 @@ -229,23 +240,3 @@ grub_register_variable_hook (const char *name, 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; -} diff --git a/grub-core/kern/err.c b/kern/err.c similarity index 87% rename from grub-core/kern/err.c rename to kern/err.c index 53c734de7..8272467f5 100644 --- a/grub-core/kern/err.c +++ b/kern/err.c @@ -22,13 +22,17 @@ #include #include +#define GRUB_MAX_ERRMSG 256 #define GRUB_ERROR_STACK_SIZE 10 grub_err_t grub_errno; char grub_errmsg[GRUB_MAX_ERRMSG]; -int grub_err_printed_errors; -static struct grub_error_saved grub_error_stack_items[GRUB_ERROR_STACK_SIZE]; +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; @@ -47,6 +51,18 @@ grub_error (grub_err_t n, const char *fmt, ...) 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) { @@ -54,7 +70,7 @@ grub_error_push (void) if (grub_error_stack_pos < GRUB_ERROR_STACK_SIZE) { /* Copy active error message to stack. */ - grub_error_stack_items[grub_error_stack_pos].grub_errno = grub_errno; + 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)); @@ -82,7 +98,7 @@ grub_error_pop (void) /* Pop error message from error stack to current active error. */ grub_error_stack_pos--; - grub_errno = grub_error_stack_items[grub_error_stack_pos].grub_errno; + 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)); @@ -106,10 +122,7 @@ grub_print_error (void) do { if (grub_errno != GRUB_ERR_NONE) - { - grub_err_printf (_("error: %s.\n"), grub_errmsg); - grub_err_printed_errors++; - } + grub_err_printf (_("error: %s.\n"), grub_errmsg); } while (grub_error_pop ()); diff --git a/grub-core/kern/file.c b/kern/file.c similarity index 54% rename from grub-core/kern/file.c rename to kern/file.c index 6e7efe89a..e17c35f95 100644 --- a/grub-core/kern/file.c +++ b/kern/file.c @@ -20,16 +20,9 @@ #include #include #include -#include #include #include #include -#include -#include - -void (*EXPORT_VAR (grub_grubnet_fini)) (void); - -grub_file_filter_t grub_file_filters[GRUB_FILE_FILTER_MAX]; /* Get the device part of the filename NAME. It is enclosed by parentheses. */ char * @@ -42,7 +35,7 @@ grub_file_get_device_name (const char *name) if (! p) { - grub_error (GRUB_ERR_BAD_FILENAME, N_("missing `%c' symbol"), ')'); + grub_error (GRUB_ERR_BAD_FILENAME, "missing `)'"); return 0; } @@ -59,31 +52,26 @@ grub_file_get_device_name (const char *name) } grub_file_t -grub_file_open (const char *name, enum grub_file_type type) +grub_file_open (const char *name) { - grub_device_t device = 0; - grub_file_t file = 0, last_file = 0; + grub_device_t device; + grub_file_t file = 0; char *device_name; - const char *file_name; - grub_file_filter_id_t filter; - - /* Reset grub_errno before we start. */ - grub_errno = GRUB_ERR_NONE; + char *file_name; device_name = grub_file_get_device_name (name); if (grub_errno) - goto fail; + return 0; /* Get the file part of NAME. */ - file_name = (name[0] == '(') ? grub_strchr (name, ')') : NULL; + file_name = grub_strchr (name, ')'); if (file_name) file_name++; else - file_name = name; + file_name = (char *) name; device = grub_device_open (device_name); grub_free (device_name); - device_name = NULL; if (! device) goto fail; @@ -93,16 +81,7 @@ grub_file_open (const char *name, enum grub_file_type type) file->device = device; - /* In case of relative pathnames and non-Unix systems (like Windows) - * name of host files may not start with `/'. Blocklists for host files - * are meaningless as well (for a start, host disk does not allow any direct - * access - it is just a marker). So skip host disk in this case. - */ - if (device->disk && file_name[0] != '/' -#if defined(GRUB_UTIL) || defined(GRUB_MACHINE_EMU) - && grub_strcmp (device->disk->name, "host") -#endif - ) + if (device->disk && file_name[0] != '/') /* This is a block list. */ file->fs = &grub_fs_blocklist; else @@ -112,37 +91,12 @@ grub_file_open (const char *name, enum grub_file_type type) goto fail; } - if ((file->fs->fs_open) (file, file_name) != GRUB_ERR_NONE) + if ((file->fs->open) (file, file_name) != GRUB_ERR_NONE) goto fail; - if (file->data == NULL) - goto fail; - - if (file->fs->mod) - grub_dl_ref (file->fs->mod); - - file->name = grub_strdup (name); - grub_errno = GRUB_ERR_NONE; - - for (filter = 0; file && filter < ARRAY_SIZE (grub_file_filters); - filter++) - if (grub_file_filters[filter]) - { - last_file = file; - file = grub_file_filters[filter] (file, type); - if (file && file != last_file) - { - file->name = grub_strdup (name); - grub_errno = GRUB_ERR_NONE; - } - } - if (!file) - grub_file_close (last_file); - return file; fail: - grub_free (device_name); if (device) grub_device_close (device); @@ -153,26 +107,19 @@ grub_file_open (const char *name, enum grub_file_type type) return 0; } -grub_disk_read_hook_t grub_file_progress_hook; - grub_ssize_t grub_file_read (grub_file_t file, void *buf, grub_size_t len) { grub_ssize_t res; - grub_disk_read_hook_t read_hook; - void *read_hook_data; if (file->offset > file->size) { grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("attempt to read past the end of file")); + "attempt to read past the end of file"); return -1; } - if (len == 0) - return 0; - - if (len > file->size - file->offset) + if (len == 0 || len > file->size - file->offset) len = file->size - file->offset; /* Prevent an overflow. */ @@ -181,17 +128,8 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len) if (len == 0) return 0; - read_hook = file->read_hook; - read_hook_data = file->read_hook_data; - if (!file->read_hook) - { - file->read_hook = grub_file_progress_hook; - file->read_hook_data = file; - file->progress_offset = file->offset; - } - res = (file->fs->fs_read) (file, buf, len); - file->read_hook = read_hook; - file->read_hook_data = read_hook_data; + + res = (file->fs->read) (file, buf, len); if (res > 0) file->offset += res; @@ -201,15 +139,11 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len) grub_err_t grub_file_close (grub_file_t file) { - if (file->fs->mod) - grub_dl_unref (file->fs->mod); - - if (file->fs->fs_close) - (file->fs->fs_close) (file); + if (file->fs->close) + (file->fs->close) (file); if (file->device) grub_device_close (file->device); - grub_free (file->name); grub_free (file); return grub_errno; } @@ -222,12 +156,11 @@ grub_file_seek (grub_file_t file, grub_off_t offset) if (offset > file->size) { grub_error (GRUB_ERR_OUT_OF_RANGE, - N_("attempt to seek outside of the file")); + "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/kern/fs.c similarity index 65% rename from grub-core/kern/fs.c rename to kern/fs.c index 80d325868..0c456377f 100644 --- a/grub-core/kern/fs.c +++ b/kern/fs.c @@ -26,25 +26,53 @@ #include #include #include -#include -grub_fs_t grub_fs_list = 0; +static grub_fs_t grub_fs_list; grub_fs_autoload_hook_t grub_fs_autoload_hook = 0; -/* Helper for grub_fs_probe. */ -static int -probe_dummy_iter (const char *filename __attribute__ ((unused)), - const struct grub_dirhook_info *info __attribute__ ((unused)), - void *data __attribute__ ((unused))) +void +grub_fs_register (grub_fs_t fs) { - return 1; + 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) { @@ -54,34 +82,15 @@ grub_fs_probe (grub_device_t device) for (p = grub_fs_list; p; p = p->next) { grub_dprintf ("fs", "Detecting %s...\n", p->name); - - /* This is evil: newly-created just mounted BtrFS after copying all - GRUB files has a very peculiar unrecoverable corruption which - will be fixed at sync but we'd rather not do a global sync and - syncing just files doesn't seem to help. Relax the check for - this time. */ -#ifdef GRUB_UTIL - if (grub_strcmp (p->name, "btrfs") == 0) - { - char *label = 0; - p->fs_uuid (device, &label); - if (label) - grub_free (label); - } - else -#endif - (p->fs_dir) (device, "/", probe_dummy_iter, NULL); + (p->dir) (device, "/", dummy_func); if (grub_errno == GRUB_ERR_NONE) return p; grub_error_push (); - /* The grub_error_push() does not touch grub_errmsg. */ - grub_dprintf ("fs", _("error: %s.\n"), grub_errmsg); grub_dprintf ("fs", "%s detection failed.\n", p->name); grub_error_pop (); - if (grub_errno != GRUB_ERR_BAD_FS - && grub_errno != GRUB_ERR_OUT_OF_RANGE) + if (grub_errno != GRUB_ERR_BAD_FS) return 0; grub_errno = GRUB_ERR_NONE; @@ -96,15 +105,14 @@ grub_fs_probe (grub_device_t device) { p = grub_fs_list; - (p->fs_dir) (device, "/", probe_dummy_iter, NULL); + (p->dir) (device, "/", dummy_func); if (grub_errno == GRUB_ERR_NONE) { count--; return p; } - if (grub_errno != GRUB_ERR_BAD_FS - && grub_errno != GRUB_ERR_OUT_OF_RANGE) + if (grub_errno != GRUB_ERR_BAD_FS) { count--; return 0; @@ -116,10 +124,10 @@ grub_fs_probe (grub_device_t device) count--; } } - else if (device->net && device->net->fs) + else if (device->net->fs) return device->net->fs; - grub_error (GRUB_ERR_UNKNOWN_FS, N_("unknown filesystem")); + grub_error (GRUB_ERR_UNKNOWN_FS, "unknown filesystem"); return 0; } @@ -130,18 +138,17 @@ grub_fs_probe (grub_device_t device) struct grub_fs_block { grub_disk_addr_t offset; - grub_disk_addr_t length; + unsigned long length; }; static grub_err_t grub_fs_blocklist_open (grub_file_t file, const char *name) { - const char *p = name; + char *p = (char *) name; unsigned num = 0; unsigned i; grub_disk_t disk = file->device->disk; struct grub_fs_block *blocks; - grub_size_t max_sectors; /* First, count the number of blocks. */ do @@ -154,12 +161,11 @@ grub_fs_blocklist_open (grub_file_t file, const char *name) while (p); /* Allocate a block list. */ - blocks = grub_calloc (num + 1, sizeof (struct grub_fs_block)); + blocks = grub_zalloc (sizeof (struct grub_fs_block) * (num + 1)); if (! blocks) return 0; file->size = 0; - max_sectors = grub_disk_from_native_sector (disk, disk->total_sectors); p = (char *) name; for (i = 0; i < num; i++) { @@ -169,27 +175,23 @@ grub_fs_blocklist_open (grub_file_t file, const char *name) if (grub_errno != GRUB_ERR_NONE || *p != '+') { grub_error (GRUB_ERR_BAD_FILENAME, - N_("invalid file name `%s'"), name); + "invalid file name `%s'", name); goto fail; } } p++; - if (*p == '\0' || *p == ',') - blocks[i].length = max_sectors - blocks[i].offset; - else - blocks[i].length = grub_strtoul (p, &p, 0); - + 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, - N_("invalid file name `%s'"), name); + "invalid file name `%s'", name); goto fail; } - if (max_sectors < blocks[i].offset + blocks[i].length) + if (disk->total_sectors < blocks[i].offset + blocks[i].length) { grub_error (GRUB_ERR_BAD_FILENAME, "beyond the total sectors"); goto fail; @@ -215,15 +217,12 @@ grub_fs_blocklist_read (grub_file_t file, char *buf, grub_size_t len) grub_disk_addr_t sector; grub_off_t offset; grub_ssize_t ret = 0; - grub_disk_t disk = file->device->disk; 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)); - disk->read_hook = file->read_hook; - disk->read_hook_data = file->read_hook_data; for (p = file->data; p->length && len > 0; p++) { if (sector < p->length) @@ -235,12 +234,9 @@ grub_fs_blocklist_read (grub_file_t file, char *buf, grub_size_t len) >> GRUB_DISK_SECTOR_BITS) > p->length - sector) size = ((p->length - sector) << GRUB_DISK_SECTOR_BITS) - offset; - if (grub_disk_read (disk, p->offset + sector, offset, + if (grub_disk_read (file->device->disk, p->offset + sector, offset, size, buf) != GRUB_ERR_NONE) - { - ret = -1; - break; - } + return -1; ret += size; len -= size; @@ -250,8 +246,6 @@ grub_fs_blocklist_read (grub_file_t file, char *buf, grub_size_t len) else sector -= p->length; } - disk->read_hook = NULL; - disk->read_hook_data = NULL; return ret; } @@ -259,9 +253,9 @@ grub_fs_blocklist_read (grub_file_t file, char *buf, grub_size_t len) struct grub_fs grub_fs_blocklist = { .name = "blocklist", - .fs_dir = 0, - .fs_open = grub_fs_blocklist_open, - .fs_read = grub_fs_blocklist_read, - .fs_close = 0, + .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/kern/generic/millisleep.c similarity index 100% rename from grub-core/kern/generic/millisleep.c rename to kern/generic/millisleep.c diff --git a/grub-core/kern/generic/rtc_get_time_ms.c b/kern/generic/rtc_get_time_ms.c similarity index 92% rename from grub-core/kern/generic/rtc_get_time_ms.c rename to kern/generic/rtc_get_time_ms.c index 3e39c8fe1..359233628 100644 --- a/grub-core/kern/generic/rtc_get_time_ms.c +++ b/kern/generic/rtc_get_time_ms.c @@ -21,7 +21,6 @@ #include #include -#include /* Calculate the time in milliseconds since the epoch based on the RTC. */ grub_uint64_t @@ -34,5 +33,5 @@ grub_rtc_get_time_ms (void) 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 ? : 1000, 0); + return grub_divmod64 (ticks_ms_per_sec, GRUB_TICKS_PER_SECOND, 0); } diff --git a/kern/handler.c b/kern/handler.c new file mode 100644 index 000000000..2bf85313c --- /dev/null +++ b/kern/handler.c @@ -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 . + */ + +#include + +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 new file mode 100644 index 000000000..5f80f28c1 --- /dev/null +++ b/kern/i386/coreboot/init.c @@ -0,0 +1,149 @@ +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; + } + + grub_machine_mmap_init (); + 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 new file mode 100644 index 000000000..b15369ee5 --- /dev/null +++ b/kern/i386/coreboot/mmap.c @@ -0,0 +1,97 @@ +/* + * 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 . + */ + +#include +#include +#include +#include + +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 (hook (table_item)) + return 1; + + return 0; +} + +void +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/kern/i386/coreboot/startup.S similarity index 75% rename from grub-core/kern/i386/coreboot/startup.S rename to kern/i386/coreboot/startup.S index df6adbabb..e94950aae 100644 --- a/grub-core/kern/i386/coreboot/startup.S +++ b/kern/i386/coreboot/startup.S @@ -18,7 +18,8 @@ #include #include -#include +#include +#include #include #include @@ -35,18 +36,22 @@ .globl start, _start start: _start: -#ifdef GRUB_MACHINE_MULTIBOOT - cmpl $MULTIBOOT_BOOTLOADER_MAGIC, %eax - jne 0f - movl %ebx, EXT_C(startup_multiboot_info) -0: -#endif + jmp codestart - /* initialize the stack */ - movl $GRUB_MEMORY_MACHINE_PROT_STACK, %esp + /* + * This is a special data area at a fixed offset from the beginning. + */ - /* jump to the main body of C code */ - jmp EXT_C(grub_main) + . = _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). @@ -60,3 +65,25 @@ multiboot_header: /* checksum */ .long -0x1BADB002 - MULTIBOOT_MEMORY_INFO +codestart: + cmpl $MULTIBOOT_BOOTLOADER_MAGIC, %eax + jne 0f + movl %ebx, EXT_C(startup_multiboot_info) +0: + + /* 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 new file mode 100644 index 000000000..57854964b --- /dev/null +++ b/kern/i386/dl.c @@ -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 . + */ + +#include +#include +#include +#include + +/* 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/kern/i386/efi/init.c similarity index 84% rename from grub-core/kern/i386/efi/init.c rename to kern/i386/efi/init.c index 46476e27e..f73f828c6 100644 --- a/grub-core/kern/i386/efi/init.c +++ b/kern/i386/efi/init.c @@ -26,7 +26,6 @@ #include #include #include -#include void grub_machine_init (void) @@ -36,13 +35,13 @@ grub_machine_init (void) } void -grub_machine_fini (int flags) +grub_machine_fini (void) { - if (!(flags & GRUB_LOADER_FLAG_NORETURN)) - return; - grub_efi_fini (); - - if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) - grub_efi_memory_fini (); +} + +void +grub_machine_set_prefix (void) +{ + grub_efi_set_prefix (); } diff --git a/grub-core/kern/i386/efi/startup.S b/kern/i386/efi/startup.S similarity index 64% rename from grub-core/kern/i386/efi/startup.S rename to kern/i386/efi/startup.S index fc5ea3dac..5b464ab83 100644 --- a/grub-core/kern/i386/efi/startup.S +++ b/kern/i386/efi/startup.S @@ -19,12 +19,40 @@ #include #include +#include .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. */ @@ -34,3 +62,5 @@ _start: movl %eax, EXT_C(grub_efi_system_table) call EXT_C(grub_main) ret + +#include "../realmode.S" diff --git a/include/grub/mips/qemu_mips/cmos.h b/kern/i386/halt.c similarity index 57% rename from include/grub/mips/qemu_mips/cmos.h rename to kern/i386/halt.c index 0759704e3..10805e42b 100644 --- a/include/grub/mips/qemu_mips/cmos.h +++ b/kern/i386/halt.c @@ -16,15 +16,27 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_CPU_CMOS_H -#define GRUB_CPU_CMOS_H 1 - -#include #include +#include +#include -#define GRUB_CMOS_ADDR_REG 0xb4000070 -#define GRUB_CMOS_DATA_REG 0xb4000071 -#define GRUB_CMOS_ADDR_REG_HI 0xb4000072 -#define GRUB_CMOS_DATA_REG_HI 0xb4000073 +const char bochs_shutdown[] = "Shutdown"; -#endif /* GRUB_CPU_CMOS_H */ +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/lib/emu/halt.c b/kern/i386/ieee1275/init.c similarity index 75% rename from grub-core/lib/emu/halt.c rename to kern/i386/ieee1275/init.c index 620935b5a..9fb98739b 100644 --- a/grub-core/lib/emu/halt.c +++ b/kern/i386/ieee1275/init.c @@ -1,6 +1,7 @@ +/* init.c -- Initialize GRUB on Open Firmware. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * 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 @@ -16,10 +17,12 @@ * along with GRUB. If not, see . */ -#include +#include +#include + +void grub_stop_floppy (void); void -grub_halt (void) +grub_stop_floppy (void) { - grub_reboot (); } diff --git a/grub-core/kern/i386/ieee1275/startup.S b/kern/i386/ieee1275/startup.S similarity index 68% rename from grub-core/kern/i386/ieee1275/startup.S rename to kern/i386/ieee1275/startup.S index 62cf348e0..35258adb6 100644 --- a/grub-core/kern/i386/ieee1275/startup.S +++ b/kern/i386/ieee1275/startup.S @@ -17,7 +17,9 @@ */ #include -#include +#include +#include +#include #include #include @@ -35,6 +37,34 @@ 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 new file mode 100644 index 000000000..ed57c43ca --- /dev/null +++ b/kern/i386/loader.S @@ -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 . + */ + + +/* + * 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/powerpc/cache.S b/kern/i386/misc.S similarity index 72% rename from grub-core/kern/powerpc/cache.S rename to kern/i386/misc.S index d85e68d42..7d57df9b9 100644 --- a/grub-core/kern/powerpc/cache.S +++ b/kern/i386/misc.S @@ -1,7 +1,6 @@ -/* cache.S - Flush the processor cache for a specific region. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2004,2007,2010 Free Software Foundation, Inc. + * 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 @@ -17,10 +16,14 @@ * along with GRUB. If not, see . */ - .text +#include - .align 2 - .globl grub_arch_sync_caches -grub_arch_sync_caches: -#include "cache_flush.S" - blr + .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/kern/i386/multiboot_mmap.c similarity index 82% rename from grub-core/kern/i386/multiboot_mmap.c rename to kern/i386/multiboot_mmap.c index e8f4f34b9..0f463c23c 100644 --- a/grub-core/kern/i386/multiboot_mmap.c +++ b/kern/i386/multiboot_mmap.c @@ -16,12 +16,15 @@ * along with GRUB. If not, see . */ +#include #include #include #include #include #include +grub_size_t grub_lower_mem, grub_upper_mem; + /* A pointer to the MBI in its initial location. */ struct multiboot_info *startup_multiboot_info; @@ -34,7 +37,7 @@ static struct multiboot_info kern_multiboot_info; static grub_uint8_t mmap_entries[sizeof (struct multiboot_mmap_entry) * 32]; void -grub_machine_mmap_init (void) +grub_machine_mmap_init () { if (! startup_multiboot_info) grub_fatal ("Unable to find Multiboot Information (is CONFIG_MULTIBOOT disabled in coreboot?)"); @@ -54,16 +57,27 @@ grub_machine_mmap_init (void) } 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 (grub_memory_hook_t hook, void *hook_data) +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, hook_data)) + if (hook (entry->addr, entry->len, entry->type)) break; entry = (void *) ((grub_addr_t) entry + entry->size + sizeof (entry->size)); diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c new file mode 100644 index 000000000..fa646df19 --- /dev/null +++ b/kern/i386/pc/init.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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/boot/i386/pc/lzma_decode.S b/kern/i386/pc/lzma_decode.S similarity index 92% rename from grub-core/boot/i386/pc/lzma_decode.S rename to kern/i386/pc/lzma_decode.S index 88c668d5e..a5a86848a 100644 --- a/grub-core/boot/i386/pc/lzma_decode.S +++ b/kern/i386/pc/lzma_decode.S @@ -77,6 +77,69 @@ #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) diff --git a/kern/i386/pc/mmap.c b/kern/i386/pc/mmap.c new file mode 100644 index 000000000..52d8fd597 --- /dev/null +++ b/kern/i386/pc/mmap.c @@ -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 . + */ + +#include +#include +#include +#include + +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 new file mode 100644 index 000000000..23f3f398e --- /dev/null +++ b/kern/i386/pc/startup.S @@ -0,0 +1,2144 @@ +/* + * 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 . + */ + + +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ABS(x) ((x) - _start + 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: + /* + * Guarantee that "main" is loaded at 0x0:0x8200. + */ +#ifdef APPLE_CC + codestart_abs = ABS(codestart) - 0x10000 + ljmp $0, $(codestart_abs) +#else + ljmp $0, $ABS(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... */ +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 */ +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_CC + translation_table_abs = ABS (translation_table) - 0x10000 + movw $(translation_table_abs), %si +#else + movw $ABS(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_getrtsecs() + * if a seconds value can be read, read it and return it (BCD), + * otherwise return 0xFF + * BIOS call "INT 1AH Function 02H" to check whether a character is pending + * Call with %ah = 0x2 + * Return: + * If RT Clock can give correct values + * %ch = hour (BCD) + * %cl = minutes (BCD) + * %dh = seconds (BCD) + * %dl = daylight savings time (00h std, 01h daylight) + * Carry flag = clear + * else + * Carry flag = set + * (this indicates that the clock is updating, or + * that it isn't running) + */ +FUNCTION(grub_getrtsecs) + pushl %ebp + + call prot_to_real /* enter real mode */ + .code16 + + clc + movb $0x2, %ah + int $0x1a + + DATA32 jnc gottime + movb $0xff, %dh + +gottime: + DATA32 call real_to_prot + .code32 + + movb %dh, %al + + 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 + + +/* + * unsigned char *grub_vga_get_font (void) + */ +FUNCTION(grub_vga_get_font) + pushl %ebp + pushl %ebx + + call prot_to_real + .code16 + movw $0x1130, %ax + movb $0x06, %bh + int $0x10 + movw %es, %bx + movw %bp, %dx + DATA32 call real_to_prot + .code32 + + movzwl %bx, %ecx + shll $4, %ecx + movw %dx, %ax + addl %ecx, %eax + + 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 new file mode 100644 index 000000000..82a17d3e0 --- /dev/null +++ b/kern/i386/pit.c @@ -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 . + */ + +#include +#include +#include + +#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/kern/i386/qemu/mmap.c similarity index 54% rename from grub-core/kern/i386/qemu/mmap.c rename to kern/i386/qemu/mmap.c index f449637ef..c7fc4f45e 100644 --- a/grub-core/kern/i386/qemu/mmap.c +++ b/kern/i386/qemu/mmap.c @@ -16,91 +16,58 @@ * along with GRUB. If not, see . */ -#include +#include #include #include #include #include #include #include -#include #define QEMU_CMOS_MEMSIZE_HIGH 0x35 #define QEMU_CMOS_MEMSIZE_LOW 0x34 -#define QEMU_CMOS_MEMSIZE2_HIGH 0x31 -#define QEMU_CMOS_MEMSIZE2_LOW 0x30 - #define min(a,b) ((a) > (b) ? (b) : (a)) extern char _start[]; extern char _end[]; -static grub_uint64_t mem_size, above_4g; +grub_size_t grub_lower_mem, grub_upper_mem; +grub_uint64_t mem_size; void -grub_machine_mmap_init (void) +grub_machine_mmap_init () { - grub_uint8_t high, low, b, c, d; - grub_cmos_read (QEMU_CMOS_MEMSIZE_HIGH, &high); - grub_cmos_read (QEMU_CMOS_MEMSIZE_LOW, &low); - mem_size = ((grub_uint64_t) high) << 24 - | ((grub_uint64_t) low) << 16; - if (mem_size > 0) - { - /* Don't ask... */ - mem_size += (16 * 1024 * 1024); - } - else - { - grub_cmos_read (QEMU_CMOS_MEMSIZE2_HIGH, &high); - grub_cmos_read (QEMU_CMOS_MEMSIZE2_LOW, &low); - mem_size - = ((((grub_uint64_t) high) << 18) | (((grub_uint64_t) low) << 10)) - + 1024 * 1024; - } + mem_size = grub_cmos_read (QEMU_CMOS_MEMSIZE_HIGH) << 24 | grub_cmos_read (QEMU_CMOS_MEMSIZE_LOW) << 16; - grub_cmos_read (0x5b, &b); - grub_cmos_read (0x5c, &c); - grub_cmos_read (0x5d, &d); - above_4g = (((grub_uint64_t) b) << 16) - | (((grub_uint64_t) c) << 24) - | (((grub_uint64_t) d) << 32); + /* Don't ask... */ + mem_size += (16 * 1024 * 1024); } grub_err_t -grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) +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_MEMORY_AVAILABLE, hook_data)) - return 1; - - if (hook ((grub_addr_t) _end, - 0xa0000 - (grub_addr_t) _end, - GRUB_MEMORY_AVAILABLE, hook_data)) + GRUB_MACHINE_MEMORY_AVAILABLE)) return 1; if (hook (GRUB_MEMORY_MACHINE_UPPER, 0x100000 - GRUB_MEMORY_MACHINE_UPPER, - GRUB_MEMORY_RESERVED, hook_data)) - return 1; - - /* Everything else is free. */ - if (hook (0x100000, - min (mem_size, (grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE) - 0x100000, - GRUB_MEMORY_AVAILABLE, hook_data)) + 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_MEMORY_RESERVED, hook_data)) + GRUB_MACHINE_MEMORY_RESERVED)) return 1; - if (above_4g != 0 && hook (0x100000000ULL, above_4g, - GRUB_MEMORY_AVAILABLE, hook_data)) + /* 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/kern/i386/qemu/startup.S similarity index 71% rename from grub-core/kern/i386/qemu/startup.S rename to kern/i386/qemu/startup.S index 0d89858d9..7484650b2 100644 --- a/grub-core/kern/i386/qemu/startup.S +++ b/kern/i386/qemu/startup.S @@ -18,7 +18,6 @@ #include #include - #include #include @@ -28,9 +27,19 @@ _start: jmp codestart - .org GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR + . = _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. @@ -42,7 +51,11 @@ codestart: value of `grub_core_entry_addr' in %esi. */ xorw %si, %si - movl $(_edata - _start), %ecx + /* ... which allows us to access `grub_kernel_image_size' + before relocation. */ + movl (grub_kernel_image_size - _start)(%esi), %ecx + + movl $_start, %edi cld rep @@ -50,12 +63,24 @@ codestart: 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 @@ -69,7 +94,6 @@ codestart: call EXT_C(grub_main) /* This should never happen. */ - cli -1: - hlt - jmp 1b + jmp EXT_C(grub_stop) + +#include "../realmode.S" diff --git a/grub-core/kern/i386/realmode.S b/kern/i386/realmode.S similarity index 77% rename from grub-core/kern/i386/realmode.S rename to kern/i386/realmode.S index 265cdcb9d..578c8d2a8 100644 --- a/grub-core/kern/i386/realmode.S +++ b/kern/i386/realmode.S @@ -16,7 +16,7 @@ * along with GRUB. If not, see . */ -#include +#include /* * Note: These functions defined in this file may be called from C. @@ -46,17 +46,11 @@ * This is the area for all of the special variables. */ + .p2align 2 /* force 4-byte alignment */ + protstack: .long GRUB_MEMORY_MACHINE_PROT_STACK - .macro PROT_TO_REAL - call prot_to_real - .endm - - .macro REAL_TO_PROT - calll real_to_prot - .endm - /* * This is the Global Descriptor Table * @@ -77,7 +71,7 @@ protstack: * description. */ - .p2align 5 /* force 32-byte alignment */ + .p2align 2 /* force 4-byte alignment */ gdt: .word 0, 0 .byte 0, 0, 0, 0 @@ -111,17 +105,10 @@ gdt: .byte 0, 0x92, 0, 0 - .p2align 5 /* this is the GDT descriptor */ gdtdesc: .word 0x27 /* limit */ .long gdt /* addr */ -LOCAL(realidt): - .word 0x400 - .long 0 -protidt: - .word 0 - .long 0 /* * These next two routines, "real_to_prot" and "prot_to_real" are structured @@ -137,22 +124,7 @@ real_to_prot: /* load the GDT register */ xorw %ax, %ax movw %ax, %ds -#ifdef GRUB_MACHINE_QEMU - /* - qemu is special: gdtdesc is in ROM. - %cs = 0xf000 - _start + GRUB_BOOT_MACHINE_SIZE = 0x100000 - So - _start + GRUB_BOOT_MACHINE_SIZE - 0x10000 points to the same point - as %cs. - gdtdesc - (_start + GRUB_BOOT_MACHINE_SIZE - 0x10000) - = gdtdesc - _start - GRUB_BOOT_MACHINE_SIZE + 0x10000 - but the later can be computed by assembly. - */ - lgdtl %cs:(gdtdesc - _start - GRUB_BOOT_MACHINE_SIZE + 0x10000) -#else - lgdtl gdtdesc -#endif + DATA32 ADDR32 lgdt gdtdesc /* turn on protected mode */ movl %cr0, %eax @@ -160,7 +132,7 @@ real_to_prot: movl %eax, %cr0 /* jump to relocation, flush prefetch queue, and reload %cs */ - ljmpl $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg + DATA32 ljmp $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg .code32 protcseg: @@ -188,39 +160,13 @@ protcseg: /* zero %eax */ xorl %eax, %eax - sidt LOCAL(realidt) - lidt protidt - /* return on the old (or initialized) stack! */ ret - /* prot_to_real assumes that this code is under 64K which is not - true for qemu. */ -#ifndef GRUB_MACHINE_QEMU -/* - * 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 . - */ prot_to_real: /* just in case, set GDT */ lgdt gdtdesc - sidt protidt - lidt LOCAL(realidt) - /* save the protected mode stack */ movl %esp, %eax movl %eax, protstack @@ -255,7 +201,7 @@ tmpcseg: movl %eax, %cr0 /* flush prefetch queue, reload %cs */ - ljmpl $0, $realcseg + DATA32 ljmp $0, $realcseg realcseg: /* we are in real mode now @@ -276,6 +222,21 @@ realcseg: #endif /* return on new stack! */ - retl -#endif + 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 new file mode 100644 index 000000000..36b35e27f --- /dev/null +++ b/kern/i386/tsc.c @@ -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 . + */ + +#include +#include +#include +#include +#include + +/* 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/kern/ieee1275/cmain.c similarity index 62% rename from grub-core/kern/ieee1275/cmain.c rename to kern/ieee1275/cmain.c index e74de3248..c1185f82c 100644 --- a/grub-core/kern/ieee1275/cmain.c +++ b/kern/ieee1275/cmain.c @@ -20,9 +20,10 @@ #include #include #include +#include #include -int (*grub_ieee1275_entry_fn) (void *) GRUB_IEEE1275_ENTRY_FN_ATTRIBUTE; +int (*grub_ieee1275_entry_fn) (void *); grub_ieee1275_phandle_t grub_ieee1275_chosen; grub_ieee1275_ihandle_t grub_ieee1275_mmu; @@ -43,23 +44,21 @@ 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[256]; + char tmp[32]; int is_smartfirmware = 0; int is_olpc = 0; - int is_qemu = 0; - grub_ssize_t actual; - -#ifdef __sparc__ - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0); -#endif grub_ieee1275_finddevice ("/", &root); grub_ieee1275_finddevice ("/options", &options); @@ -72,8 +71,7 @@ grub_ieee1275_find_options (void) rc = grub_ieee1275_get_property (openprom, "CodeGen-copyright", tmp, sizeof (tmp), 0); - if (rc >= 0 && !grub_strncmp (tmp, "SmartFirmware(tm)", - sizeof ("SmartFirmware(tm)") - 1)) + if (rc >= 0 && !grub_strncmp (tmp, SF, sizeof (SF) - 1)) is_smartfirmware = 1; rc = grub_ieee1275_get_property (root, "architecture", @@ -81,58 +79,6 @@ grub_ieee1275_find_options (void) if (rc >= 0 && !grub_strcmp (tmp, "OLPC")) is_olpc = 1; - rc = grub_ieee1275_get_property (root, "model", - tmp, sizeof (tmp), 0); - if (rc >= 0 && (!grub_strcmp (tmp, "Emulated PC") - || !grub_strcmp (tmp, "IBM pSeries (emulated by qemu)"))) { - is_qemu = 1; - } - - if (rc >= 0 && grub_strncmp (tmp, "IBM", 3) == 0) - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS); - - /* Old Macs have no key repeat, newer ones have fully working one. - The ones inbetween when repeated key generates an escaoe sequence - only the escape is repeated. With this workaround however a fast - e.g. down arrow-ESC is perceived as down arrow-down arrow which is - also annoying but is less so than the original bug of exiting from - the current window on arrow repeat. To avoid unaffected users suffering - from this workaround match only exact models known to have this bug. - */ - if (rc >= 0 && grub_strcmp (tmp, "PowerBook3,3") == 0) - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_REPEAT); - - rc = grub_ieee1275_get_property (root, "compatible", - tmp, sizeof (tmp), &actual); - if (rc >= 0) - { - char *ptr; - - if (grub_strncmp (tmp, "sun4v", 5) == 0) - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_RAW_DEVNAMES); - for (ptr = tmp; ptr - tmp < actual; ptr += grub_strlen (ptr) + 1) - { - if (grub_memcmp (ptr, "MacRISC", sizeof ("MacRISC") - 1) == 0 - && (ptr[sizeof ("MacRISC") - 1] == 0 - || grub_isdigit (ptr[sizeof ("MacRISC") - 1]))) - { - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS); - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_OFNET_SUFFIX); - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN); - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN); - break; - } - } - -#if defined(__powerpc__) - if (grub_strncmp (tmp, "IBM,", 4) == 0) - { - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY); - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_POWER_VM); - } -#endif - } - if (is_smartfirmware) { /* Broken in all versions */ @@ -187,21 +133,25 @@ grub_ieee1275_find_options (void) */ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY); - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF); } - if (is_qemu) + if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom)) { - /* OpenFirmware hangs on qemu if one requests any memory below 1.5 MiB. */ - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM); - - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF); -#if defined(__powerpc__) - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_POWER_KVM); -#endif + 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) { diff --git a/grub-core/kern/ieee1275/ieee1275.c b/kern/ieee1275/ieee1275.c similarity index 69% rename from grub-core/kern/ieee1275/ieee1275.c rename to kern/ieee1275/ieee1275.c index 36ca2dbfc..9e2919172 100644 --- a/grub-core/kern/ieee1275/ieee1275.c +++ b/kern/ieee1275/ieee1275.c @@ -19,7 +19,6 @@ #include #include -#include #define IEEE1275_PHANDLE_INVALID ((grub_ieee1275_cell_t) -1) #define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_cell_t) 0) @@ -28,7 +27,7 @@ int -grub_ieee1275_finddevice (const char *name, grub_ieee1275_phandle_t *phandlep) +grub_ieee1275_finddevice (char *name, grub_ieee1275_phandle_t *phandlep) { struct find_device_args { @@ -233,7 +232,7 @@ grub_ieee1275_instance_to_path (grub_ieee1275_ihandle_t ihandle, } int -grub_ieee1275_write (grub_ieee1275_ihandle_t ihandle, const void *buffer, +grub_ieee1275_write (grub_ieee1275_ihandle_t ihandle, void *buffer, grub_size_t len, grub_ssize_t *actualp) { struct write_args @@ -306,7 +305,7 @@ grub_ieee1275_seek (grub_ieee1275_ihandle_t ihandle, grub_disk_addr_t pos, 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) + args.pos_lo = (grub_ieee1275_cell_t) (pos & ((1ULL << (8 * GRUB_IEEE1275_CELL_SIZEOF)) - 1)); #endif @@ -398,6 +397,9 @@ grub_ieee1275_interpret (const char *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; @@ -480,91 +482,6 @@ grub_ieee1275_close (grub_ieee1275_ihandle_t ihandle) return 0; } -int -grub_ieee1275_decode_unit4 (grub_ieee1275_ihandle_t ihandle, - void *addr, grub_size_t size, - grub_uint32_t *phy_lo, grub_uint32_t *phy_hi, - grub_uint32_t *lun_lo, grub_uint32_t *lun_hi) -{ - struct decode_args - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t method; - grub_ieee1275_cell_t ihandle; - grub_ieee1275_cell_t size; - grub_ieee1275_cell_t addr; - grub_ieee1275_cell_t catch_result; - grub_ieee1275_cell_t tgt_h; - grub_ieee1275_cell_t tgt_l; - grub_ieee1275_cell_t lun_h; - grub_ieee1275_cell_t lun_l; - } - args; - - INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 5); - args.method = (grub_ieee1275_cell_t) "decode-unit"; - args.ihandle = ihandle; - args.size = size; - args.addr = (grub_ieee1275_cell_t) addr; - args.catch_result = 1; - - if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "decode-unit failed\n"); - return -1; - } - - *phy_lo = args.tgt_l; - *phy_hi = args.tgt_h; - *lun_lo = args.lun_l; - *lun_hi = args.lun_h; - return 0; -} - -char * -grub_ieee1275_encode_uint4 (grub_ieee1275_ihandle_t ihandle, - grub_uint32_t phy_lo, grub_uint32_t phy_hi, - grub_uint32_t lun_lo, grub_uint32_t lun_hi, - grub_size_t *size) -{ - char *addr; - struct encode_args - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t method; - grub_ieee1275_cell_t ihandle; - grub_ieee1275_cell_t tgt_h; - grub_ieee1275_cell_t tgt_l; - grub_ieee1275_cell_t lun_h; - grub_ieee1275_cell_t lun_l; - grub_ieee1275_cell_t catch_result; - grub_ieee1275_cell_t size; - grub_ieee1275_cell_t addr; - } - args; - - INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 3); - args.method = (grub_ieee1275_cell_t) "encode-unit"; - args.ihandle = ihandle; - - args.tgt_l = phy_lo; - args.tgt_h = phy_hi; - args.lun_l = lun_lo; - args.lun_h = lun_hi; - args.catch_result = 1; - - if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result)) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "encode-unit failed\n"); - return 0; - } - - addr = (void *)args.addr; - *size = args.size; - addr = grub_strdup ((char *)args.addr); - return addr; -} - int grub_ieee1275_claim (grub_addr_t addr, grub_size_t size, unsigned int align, grub_addr_t *result) @@ -590,9 +507,6 @@ grub_ieee1275_claim (grub_addr_t addr, grub_size_t size, unsigned int align, *result = args.base; if (args.base == IEEE1275_CELL_INVALID) return -1; - grub_dprintf ("mmap", "CLAIMED: 0x%" PRIxGRUB_IEEE1275_CELL_T " (%" - PRIuGRUB_IEEE1275_CELL_T " MiB) size: %" PRIuGRUB_SIZE " MiB\n", - args.base, args.base >> 20, ALIGN_UP (size, 1 << 20) >> 20); return 0; } @@ -618,7 +532,7 @@ grub_ieee1275_release (grub_addr_t addr, grub_size_t size) int grub_ieee1275_set_property (grub_ieee1275_phandle_t phandle, - const char *propname, const void *buf, + const char *propname, void *buf, grub_size_t size, grub_ssize_t *actual) { struct set_property_args @@ -693,117 +607,3 @@ grub_ieee1275_milliseconds (grub_uint32_t *msecs) *msecs = args.msecs; return 0; } - -int -grub_ieee1275_set_address (grub_ieee1275_ihandle_t ihandle, - grub_uint32_t target, grub_uint32_t lun) -{ - struct set_address - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t method; - grub_ieee1275_cell_t ihandle; - grub_ieee1275_cell_t tgt; - grub_ieee1275_cell_t lun; - grub_ieee1275_cell_t catch_result; - } - args; - - INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 1); - - /* - * IEEE 1275-1994 Standard for Boot (Initialization Configuration) - * Firmware: Core Requirements and Practices - * E.3.2.2 Bus-specific methods for bus nodes - * - * A package implementing the scsi-2 device type shall implement the - * following bus-specific method: - * - * set-address ( unit# target# -- ) - * Sets the SCSI target number (0x0..0xf) and unit number (0..7) to which - * subsequent commands apply. - */ - args.method = (grub_ieee1275_cell_t) "set-address"; - args.ihandle = ihandle; - args.tgt = target; - args.lun = lun; - - if (IEEE1275_CALL_ENTRY_FN (&args) == -1) - return -1; - - return args.catch_result; -} - -int -grub_ieee1275_no_data_command (grub_ieee1275_ihandle_t ihandle, - const void *cmd_addr, grub_ssize_t *result) -{ - struct set_address - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t method; - grub_ieee1275_cell_t ihandle; - grub_ieee1275_cell_t cmd_addr; - grub_ieee1275_cell_t error; - grub_ieee1275_cell_t catch_result; - } - args; - - INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2); - - /* - * IEEE 1275-1994 Standard for Boot (Initialization Configuration) - * Firmware: Core Requirements and Practices - * - * E.3.2.2 Bus-specific methods for bus nodes - * - * A package implementing the scsi-2 device type shall implement the - * following bus-specific method: - * - * no-data-command ( cmd-addr -- error? ) - * Executes a simple SCSI command, automatically retrying under - * certain conditions. cmd-addr is the address of a 6-byte command buffer - * containing an SCSI command that does not have a data transfer phase. - * Executes the command, retrying indefinitely with the same retry criteria - * as retry-command. - * - * error? is nonzero if an error occurred, zero otherwise. - * NOTE no-data-command is a convenience function. It provides - * no capabilities that are not present in retry-command, but for - * those commands that meet its restrictions, it is easier to use. - */ - args.method = (grub_ieee1275_cell_t) "no-data-command"; - args.ihandle = ihandle; - args.cmd_addr = (grub_ieee1275_cell_t) cmd_addr; - - if (IEEE1275_CALL_ENTRY_FN (&args) == -1) - return -1; - - if (result) - *result = args.error; - - return args.catch_result; -} - -int -grub_ieee1275_get_block_size (grub_ieee1275_ihandle_t ihandle) -{ - struct size_args_ieee1275 - { - 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 size; - } args; - - INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 2); - args.method = (grub_ieee1275_cell_t) "block-size"; - args.ihandle = ihandle; - args.result = 1; - - if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result)) - return 0; - - return args.size; -} diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c new file mode 100644 index 000000000..f3a4f4d81 --- /dev/null +++ b/kern/ieee1275/init.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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) (4 * 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) (4 * 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/kern/ieee1275/mmap.c similarity index 81% rename from grub-core/kern/ieee1275/mmap.c rename to kern/ieee1275/mmap.c index bf325eadf..6f0652770 100644 --- a/grub-core/kern/ieee1275/mmap.c +++ b/kern/ieee1275/mmap.c @@ -16,16 +16,16 @@ * along with GRUB. If not, see . */ -#include +#include #include #include grub_err_t -grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) +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[128]; + grub_uint32_t available[32]; grub_ssize_t available_size; grub_uint32_t address_cells = 1; grub_uint32_t size_cells = 1; @@ -49,15 +49,6 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) sizeof available, &available_size)) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "couldn't examine /memory/available property"); - if (available_size < 0 || (grub_size_t) available_size > sizeof (available)) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "/memory response buffer exceeded"); - - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS)) - { - address_cells = 1; - size_cells = 1; - } /* Decode each entry and call `hook'. */ i = 0; @@ -75,7 +66,7 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) if (size_cells == 2) size = (size << 32) | available[i++]; - if (hook (address, size, GRUB_MEMORY_AVAILABLE, hook_data)) + if (hook (address, size, GRUB_MACHINE_MEMORY_AVAILABLE)) break; } diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c new file mode 100644 index 000000000..13fccbf9a --- /dev/null +++ b/kern/ieee1275/openfw.c @@ -0,0 +1,426 @@ +/* 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 . + */ + +#include +#include +#include +#include +#include +#include + +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; + char *fullname; + + if (grub_ieee1275_get_property (child, "device_type", childtype, + IEEE1275_MAX_PROP_LEN, &actual)) + continue; + + if (grub_ieee1275_package_to_path (child, childpath, + IEEE1275_MAX_PATH_LEN, &actual)) + continue; + + if (grub_ieee1275_get_property (child, "name", childname, + IEEE1275_MAX_PROP_LEN, &actual)) + continue; + + fullname = grub_xasprintf ("%s/%s", devpath, childname); + if (!fullname) + { + grub_free (childname); + grub_free (childpath); + grub_free (childtype); + return 0; + } + + alias.type = childtype; + alias.path = childpath; + alias.name = fullname; + ret = hook (&alias); + grub_free (fullname); + if (ret) + break; + } + while (grub_ieee1275_peer (child, &child)); + + grub_free (childname); + grub_free (childpath); + grub_free (childtype); + + return ret; +} + +/* 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:,,,,,". */ + 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 new file mode 100644 index 000000000..379b0d886 --- /dev/null +++ b/kern/list.c @@ -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 . + */ + +#include +#include +#include + +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 new file mode 100644 index 000000000..e7566fab9 --- /dev/null +++ b/kern/main.c @@ -0,0 +1,180 @@ +/* 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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; + } +} + +/* 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 ELF module, 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 new file mode 100644 index 000000000..2c35b6da2 --- /dev/null +++ b/kern/mips/cache.S @@ -0,0 +1,7 @@ + +#include + +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 new file mode 100644 index 000000000..5667ee7b4 --- /dev/null +++ b/kern/mips/cache_flush.S @@ -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/kern/mips/dl.c b/kern/mips/dl.c new file mode 100644 index 000000000..485955e7f --- /dev/null +++ b/kern/mips/dl.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include + +/* 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/efiemu/i386/nocfgtables.c b/kern/mips/init.c similarity index 74% rename from grub-core/efiemu/i386/nocfgtables.c rename to kern/mips/init.c index 775f1d03a..5adcedcbb 100644 --- a/grub-core/efiemu/i386/nocfgtables.c +++ b/kern/mips/init.c @@ -1,4 +1,3 @@ -/* Register SMBIOS and ACPI tables. */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2009 Free Software Foundation, Inc. @@ -17,14 +16,20 @@ * along with GRUB. If not, see . */ -#include -#include -#include -#include -#include +#include +#include +#include -grub_err_t -grub_machine_efiemu_init_tables (void) +void +grub_machine_set_prefix (void) { - return GRUB_ERR_NONE; + 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 new file mode 100644 index 000000000..866c7a82a --- /dev/null +++ b/kern/mips/qemu-mips/init.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 new file mode 100644 index 000000000..5e3fb7ad5 --- /dev/null +++ b/kern/mips/startup.S @@ -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 . + */ + +#include +#include +#include + +#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 new file mode 100644 index 000000000..14e8a39a2 --- /dev/null +++ b/kern/mips/yeeloong/init.c @@ -0,0 +1,131 @@ +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void grub_video_sm712_init (void); +extern void grub_video_video_init (void); +extern void grub_video_bitmap_init (void); +extern void grub_font_manager_init (void); +extern void grub_term_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; +} + + +static void * +get_modules_end (void) +{ + 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 modinfo; + + 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)); + + return header; +} + +void +grub_machine_init (void) +{ + void *modend; + modend = get_modules_end (); + grub_mm_init_region (modend, (grub_arch_memsize << 20) + - (((grub_addr_t) 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_video_init (); + grub_video_bitmap_init (); + grub_font_manager_init (); + grub_term_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 new file mode 100644 index 000000000..4772e22b0 --- /dev/null +++ b/kern/misc.c @@ -0,0 +1,1068 @@ +/* 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +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 , 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 + +#ifdef NEED_ENABLE_EXECUTE_STACK +/* Some gcc versions generate a call to this function + in trampolines for nested functions. */ +void __enable_execute_stack (void *addr __attribute__ ((unused))) +{ +} +#endif + diff --git a/kern/mm.c b/kern/mm.c new file mode 100644 index 000000000..ef97b018e --- /dev/null +++ b/kern/mm.c @@ -0,0 +1,586 @@ +/* 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 . + */ + +/* + 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 +#include +#include +#include +#include +#include +#include + +#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; + + + +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 + + /* If this region is too small, ignore it. */ + if (size < GRUB_MM_ALIGN * 2) + return; + + /* Allocate a region from the head. */ + r = (grub_mm_region_t) (((grub_addr_t) addr + GRUB_MM_ALIGN - 1) + & (~(GRUB_MM_ALIGN - 1))); + size -= (char *) r - (char *) addr + sizeof (*r); + + 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; + p->magic = GRUB_MM_ALLOC_MAGIC; + } + else if (extra == 0 || 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; + p->size = n; + p->magic = GRUB_MM_ALLOC_MAGIC; + } + 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->size = n; + p->magic = GRUB_MM_ALLOC_MAGIC; + } + + /* 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", + __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 new file mode 100644 index 000000000..dd4608ba9 --- /dev/null +++ b/kern/parser.c @@ -0,0 +1,274 @@ +/* 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 . + */ + +#include +#include +#include +#include + + +/* 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) + *p = 0; + + *line = grub_strdup (source); + if (p) + *p = '\n'; + 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 new file mode 100644 index 000000000..4d5c63a95 --- /dev/null +++ b/kern/partition.c @@ -0,0 +1,133 @@ +/* + * 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 . + */ + +#include +#include +#include + +static grub_partition_map_t grub_partition_map_list; + +void +grub_partition_map_register (grub_partition_map_t partmap) +{ + partmap->next = grub_partition_map_list; + grub_partition_map_list = partmap; +} + +void +grub_partition_map_unregister (grub_partition_map_t partmap) +{ + grub_partition_map_t *p, q; + + for (p = &grub_partition_map_list, q = *p; q; p = &(q->next), q = q->next) + if (q == partmap) + { + *p = q->next; + break; + } +} + +int +grub_partition_map_iterate (int (*hook) (const grub_partition_map_t partmap)) +{ + grub_partition_map_t p; + + for (p = grub_partition_map_list; p; p = p->next) + if (hook (p)) + return 1; + + return 0; +} + +grub_partition_t +grub_partition_probe (struct grub_disk *disk, const char *str) +{ + grub_partition_t part = 0; + + auto int part_map_probe (const grub_partition_map_t partmap); + + int part_map_probe (const grub_partition_map_t partmap) + { + part = partmap->probe (disk, str); + if (part) + return 1; + + if (grub_errno == GRUB_ERR_BAD_PART_TABLE) + { + /* Continue to next partition map type. */ + grub_errno = GRUB_ERR_NONE; + return 0; + } + + return 1; + } + + /* Use the first partition map type found. */ + grub_partition_map_iterate (part_map_probe); + + return part; +} + +int +grub_partition_iterate (struct grub_disk *disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + grub_partition_map_t partmap = 0; + int ret = 0; + + auto int part_map_iterate (const grub_partition_map_t p); + auto int part_map_iterate_hook (grub_disk_t d, + const grub_partition_t partition); + + int part_map_iterate_hook (grub_disk_t d __attribute__ ((unused)), + const grub_partition_t partition __attribute__ ((unused))) + { + return 1; + } + + int part_map_iterate (const grub_partition_map_t p) + { + grub_dprintf ("partition", "Detecting %s...\n", p->name); + p->iterate (disk, part_map_iterate_hook); + + if (grub_errno != GRUB_ERR_NONE) + { + /* Continue to next partition map type. */ + grub_dprintf ("partition", "%s detection failed.\n", p->name); + grub_errno = GRUB_ERR_NONE; + return 0; + } + + grub_dprintf ("partition", "%s detection succeeded.\n", p->name); + partmap = p; + return 1; + } + + grub_partition_map_iterate (part_map_iterate); + if (partmap) + ret = partmap->iterate (disk, hook); + + return ret; +} + +char * +grub_partition_get_name (const grub_partition_t partition) +{ + return partition->partmap->get_name (partition); +} diff --git a/grub-core/kern/powerpc/cache_flush.S b/kern/powerpc/cache.S similarity index 91% rename from grub-core/kern/powerpc/cache_flush.S rename to kern/powerpc/cache.S index 1410f78b1..da982afa0 100644 --- a/grub-core/kern/powerpc/cache_flush.S +++ b/kern/powerpc/cache.S @@ -1,7 +1,7 @@ /* cache.S - Flush the processor cache for a specific region. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2004,2007,2010 Free Software Foundation, Inc. + * 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 @@ -17,9 +17,13 @@ * along with GRUB. If not, see . */ -#undef CACHE_LINE_BYTES #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. */ @@ -41,3 +45,4 @@ 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 new file mode 100644 index 000000000..ad19e5600 --- /dev/null +++ b/kern/powerpc/dl.c @@ -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 . + */ + +#include +#include +#include +#include + +/* 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/kern/powerpc/ieee1275/startup.S similarity index 84% rename from grub-core/kern/powerpc/ieee1275/startup.S rename to kern/powerpc/ieee1275/startup.S index 21c884b43..75e1ed852 100644 --- a/grub-core/kern/powerpc/ieee1275/startup.S +++ b/kern/powerpc/ieee1275/startup.S @@ -18,7 +18,7 @@ */ #include -#include +#include .extern __bss_start .extern _end @@ -28,37 +28,34 @@ .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 - -2: stb 2, 4(6) - addi 6, 6, 1 - andi. 7, 6, 3 - cmpi 0, 1, 7, 0 - bne 2b - lis 7, (_end - 4)@h ori 7, 7, (_end - 4)@l subf 7, 6, 7 - subi 8, 7, 1 - andi. 8, 8, 3 - addi 8, 8, 1 - sub 7, 7, 8 - 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 - mtctr 8 -2: stb 2, 4(6) /* We know r2 is already 0 from above. */ - addi 6, 6, 1 - bdnz 2b - /* Store r5 in grub_ieee1275_entry_fn. */ lis 9, grub_ieee1275_entry_fn@ha stw 5, grub_ieee1275_entry_fn@l(9) diff --git a/grub-core/kern/rescue_parser.c b/kern/rescue_parser.c similarity index 71% rename from grub-core/kern/rescue_parser.c rename to kern/rescue_parser.c index 799641a03..d3725e739 100644 --- a/grub-core/kern/rescue_parser.c +++ b/kern/rescue_parser.c @@ -23,43 +23,30 @@ #include #include #include -#include -grub_err_t -grub_rescue_parse_line (char *line, - grub_reader_getline_t getline, void *getline_data) +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, getline_data, &n, &args) - || n < 0) - { - grub_free(args); - return grub_errno; - } + if (grub_parser_split_cmdline (line, getline, &n, &args) || n < 0) + return grub_errno; if (n == 0) - { - grub_free(args); - return GRUB_ERR_NONE; - } + return GRUB_ERR_NONE; /* In case of an assignment set the environment accordingly instead of calling a function. */ - if (n == 1) + if (n == 1 && grub_strchr (line, '=')) { char *val = grub_strchr (args[0], '='); - - if (val) - { - val[0] = 0; - grub_env_set (args[0], val + 1); - val[0] = '='; - goto quit; - } + val[0] = 0; + grub_env_set (args[0], val + 1); + val[0] = '='; + goto quit; } /* Get the command name. */ @@ -76,15 +63,26 @@ grub_rescue_parse_line (char *line, } else { - grub_printf_ (N_("Unknown command `%s'.\n"), name); + grub_printf ("Unknown command `%s'\n", name); if (grub_command_find ("help")) grub_printf ("Try `help' for usage\n"); } quit: - /* Arguments are returned in single memory chunk separated by zeroes */ 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/kern/rescue_reader.c similarity index 70% rename from grub-core/kern/rescue_reader.c rename to kern/rescue_reader.c index a71ada8fb..f573cf41f 100644 --- a/grub-core/kern/rescue_reader.c +++ b/kern/rescue_reader.c @@ -30,44 +30,38 @@ 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, - void *data __attribute__ ((unused))) +grub_rescue_read_line (char **line, int cont) { int c; int pos = 0; - char str[4]; grub_printf ((cont) ? "> " : "grub rescue> "); grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE); - while ((c = grub_getkey ()) != '\n' && c != '\r') + while ((c = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && c != '\r') { if (grub_isprint (c)) { if (pos < GRUB_RESCUE_BUF_SIZE - 1) { - str[0] = c; - str[1] = 0; linebuf[pos++] = c; - grub_xputs (str); + grub_putchar (c); } } else if (c == '\b') { if (pos > 0) { - str[0] = c; - str[1] = ' '; - str[2] = c; - str[3] = 0; linebuf[--pos] = 0; - grub_xputs (str); + grub_putchar (c); + grub_putchar (' '); + grub_putchar (c); } } grub_refresh (); } - grub_xputs ("\n"); + grub_putchar ('\n'); grub_refresh (); *line = grub_strdup (linebuf); @@ -75,22 +69,9 @@ grub_rescue_read_line (char **line, int cont, return 0; } -void __attribute__ ((noreturn)) +void grub_rescue_run (void) { - /* Stall if the CLI has been disabled */ - if (grub_is_cli_disabled () || grub_is_cli_need_auth ()) - { - grub_printf ("Rescue mode has been disabled...\n"); - - do - { - /* Do not optimize out the loop. */ - asm volatile (""); - } - while (1); - } - grub_printf ("Entering rescue mode...\n"); while (1) @@ -101,11 +82,11 @@ grub_rescue_run (void) grub_print_error (); grub_errno = GRUB_ERR_NONE; - grub_rescue_read_line (&line, 0, NULL); + grub_rescue_read_line (&line, 0); if (! line || line[0] == '\0') continue; - grub_rescue_parse_line (line, grub_rescue_read_line, NULL); + grub_parser_get_current ()->parse_line (line, grub_rescue_read_line); grub_free (line); } } diff --git a/grub-core/kern/sparc64/cache.S b/kern/sparc64/cache.S similarity index 100% rename from grub-core/kern/sparc64/cache.S rename to kern/sparc64/cache.S diff --git a/kern/sparc64/dl.c b/kern/sparc64/dl.c new file mode 100644 index 000000000..7b6266cac --- /dev/null +++ b/kern/sparc64/dl.c @@ -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 . + */ + +#include +#include +#include +#include + +/* 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/kern/sparc64/ieee1275/crt0.S similarity index 56% rename from grub-core/kern/sparc64/ieee1275/crt0.S rename to kern/sparc64/ieee1275/crt0.S index 03b916f05..3749f3005 100644 --- a/grub-core/kern/sparc64/ieee1275/crt0.S +++ b/kern/sparc64/ieee1275/crt0.S @@ -18,47 +18,43 @@ */ #include #include -#include .text .align 4 .globl _start _start: ba codestart - mov %o4, %o0 + nop - .org GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE + . = 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 + GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN - 1), %o2 - or %o2, %lo(__bss_start + GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN - 1), %o2 - srl %o2, GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN, %o2 - sll %o2, GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN, %o2 - sethi %hi(_end + GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN - 1), %o3 - or %o3, %lo(_end + GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN - 1), %o3 - srl %o3, GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN, %o3 - sll %o3, GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN, %o3 + 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), %o5 - or %o5, %lo(GRUB_KERNEL_MACHINE_STACK_SIZE), %o5 - add %o3, %o5, %o6 - and %o6, ~0xff, %o6 - sub %o6, 2047, %o6 - sub %o2, 4, %o2 sub %o3, 4, %o3 1: lduw [%o2], %o5 @@ -66,39 +62,20 @@ codestart: subcc %o4, 4, %o4 sub %o2, 4, %o2 bne,pt %icc, 1b - sub %o3, 4, %o3 + sub %o3, 4, %o3 /* Now it's safe to clear out the BSS. */ sethi %hi(__bss_start), %o2 or %o2, %lo(__bss_start), %o2 -1: stb %g0, [%o2] - add %o2, 1, %o2 - and %o2, 7, %o3 - brnz %o3, 1b - nop - - sethi %hi(_end - 1), %o3 - or %o3, %lo(_end - 1), %o3 - srl %o3, 3, %o3 - sll %o3, 3, %o3 + 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(_end), %o3 - or %o3, %lo(_end), %o3 -1: stb %g0, [%o2] - add %o2, 1, %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 + stx %o0, [%o2 + %lo(grub_ieee1275_entry_fn)] call grub_main - stx %o0, [%o2 + %lo(grub_ieee1275_entry_fn)] -1: ba,a 1b nop +1: ba,a 1b diff --git a/grub-core/kern/sparc64/ieee1275/ieee1275.c b/kern/sparc64/ieee1275/ieee1275.c similarity index 64% rename from grub-core/kern/sparc64/ieee1275/ieee1275.c rename to kern/sparc64/ieee1275/ieee1275.c index 5a59aaf06..53be692c3 100644 --- a/grub-core/kern/sparc64/ieee1275/ieee1275.c +++ b/kern/sparc64/ieee1275/ieee1275.c @@ -89,59 +89,3 @@ grub_ieee1275_alloc_physmem (grub_addr_t *paddr, grub_size_t size, return args.catch_result; } - -grub_uint64_t -grub_ieee1275_num_blocks (grub_ieee1275_ihandle_t ihandle) -{ - struct nblocks_args_ieee1275 - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t method; - grub_ieee1275_cell_t ihandle; - grub_ieee1275_cell_t catch_result; - grub_ieee1275_cell_t blocks; - } - args; - - INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 2); - args.method = (grub_ieee1275_cell_t) "#blocks"; - args.ihandle = ihandle; - args.catch_result = 1; - - if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result != 0)) - return -1; - - /* - * If the number of blocks exceeds the range of an unsigned number, - * return 0 to alert the caller to try the #blocks64 command. - */ - if (args.blocks >= 0xffffffffULL) - return 0; - - return args.blocks; -} - -grub_uint64_t -grub_ieee1275_num_blocks64 (grub_ieee1275_ihandle_t ihandle) -{ - struct nblocks_args_ieee1275 - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t method; - grub_ieee1275_cell_t ihandle; - grub_ieee1275_cell_t catch_result; - grub_ieee1275_cell_t hi_blocks; - grub_ieee1275_cell_t lo_blocks; - } - args; - - INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3); - args.method = (grub_ieee1275_cell_t) "#blocks64"; - args.ihandle = ihandle; - args.catch_result = 1; - - if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result != 0)) - return -1; - - return ((args.hi_blocks << 32) | (args.lo_blocks)); -} diff --git a/kern/sparc64/ieee1275/init.c b/kern/sparc64/ieee1275/init.c new file mode 100644 index 000000000..115328f40 --- /dev/null +++ b/kern/sparc64/ieee1275/init.c @@ -0,0 +1,169 @@ +/* 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 *)(long)0x4000UL, 0x200000 - 0x4000); +} + +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 new file mode 100644 index 000000000..6e3a2b454 --- /dev/null +++ b/kern/term.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include + +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/kern/time.c similarity index 100% rename from grub-core/kern/time.c rename to kern/time.c diff --git a/kern/x86_64/dl.c b/kern/x86_64/dl.c new file mode 100644 index 000000000..090ad78b8 --- /dev/null +++ b/kern/x86_64/dl.c @@ -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 . + */ + +#include +#include +#include +#include + +/* 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 new file mode 100644 index 000000000..1946732ae --- /dev/null +++ b/kern/x86_64/efi/callwrap.S @@ -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 . + */ + +#include +#include +#include + +/* + * 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/kern/x86_64/efi/startup.S similarity index 63% rename from grub-core/kern/x86_64/efi/startup.S rename to kern/x86_64/efi/startup.S index 9357e5c5d..fb4fc7b64 100644 --- a/grub-core/kern/x86_64/efi/startup.S +++ b/kern/x86_64/efi/startup.S @@ -19,6 +19,7 @@ #include #include +#include .file "startup.S" .text @@ -27,9 +28,36 @@ 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) - andq $~0xf, %rsp call EXT_C(grub_main) - /* Doesn't return. */ + ret + diff --git a/grub-core/lib/LzFind.c b/lib/LzFind.c similarity index 98% rename from grub-core/lib/LzFind.c rename to lib/LzFind.c index dcb20d921..cd7a1cbab 100644 --- a/grub-core/lib/LzFind.c +++ b/lib/LzFind.c @@ -24,9 +24,6 @@ * See , for more information about LZMA. */ - -#include - #include #include @@ -69,9 +66,9 @@ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *a } Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } -static Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 curindex) { return p->buffer[curindex]; } +Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } -static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } +UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) { diff --git a/grub-core/lib/LzmaDec.c b/lib/LzmaDec.c similarity index 99% rename from grub-core/lib/LzmaDec.c rename to lib/LzmaDec.c index 952edb346..62ebee686 100644 --- a/grub-core/lib/LzmaDec.c +++ b/lib/LzmaDec.c @@ -26,9 +26,7 @@ #include -#pragma GCC diagnostic ignored "-Wshadow" -#include -#define memcpy grub_memcpy +#include #define kNumTopBits 24 #define kTopValue ((UInt32)1 << kNumTopBits) @@ -720,7 +718,7 @@ static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) p->needFlush = 0; } -static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) +void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) { p->needFlush = 1; p->remainLen = 0; diff --git a/grub-core/lib/LzmaEnc.c b/lib/LzmaEnc.c similarity index 93% rename from grub-core/lib/LzmaEnc.c rename to lib/LzmaEnc.c index 0fb2cf1d4..842d43ac1 100644 --- a/grub-core/lib/LzmaEnc.c +++ b/lib/LzmaEnc.c @@ -24,8 +24,6 @@ * See , for more information about LZMA. */ -#include - #include #include @@ -120,7 +118,7 @@ UInt32 GetPosSlot1(UInt32 pos) #define kNumLogBits (9 + (int)sizeof(size_t) / 2) #define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) -static void LzmaEnc_FastPosInit(Byte *g_FastPos) +void LzmaEnc_FastPosInit(Byte *g_FastPos) { int c = 2, slotFast; g_FastPos[0] = 0; @@ -374,6 +372,58 @@ typedef struct _CLzmaEnc 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; @@ -591,7 +641,7 @@ static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, while (symbol < 0x10000); } -static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) +void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) { UInt32 i; for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) @@ -923,8 +973,6 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) #define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) -#pragma GCC diagnostic ignored "-Wshadow" - static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) { UInt32 numAvailableBytes, lenMain, numDistancePairs; @@ -1211,7 +1259,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) { UInt32 i; reps[0] = prevOpt->backs[pos]; - for (i = 1; i < pos + 1; i++) + for (i = 1; i <= pos; i++) reps[i] = prevOpt->backs[i - 1]; for (; i < LZMA_NUM_REPS; i++) reps[i] = prevOpt->backs[i]; @@ -1359,7 +1407,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) startLen = lenTest + 1; /* if (_maxMode) */ - { + { UInt32 lenTest2 = lenTest + 1; UInt32 limit = lenTest2 + p->numFastBytes; UInt32 nextRepMatchPrice; @@ -1403,7 +1451,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) } } } - } + } } } /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ @@ -1719,7 +1767,7 @@ static void FillDistancesPrices(CLzmaEnc *p) p->matchPriceCount = 0; } -static void LzmaEnc_Construct(CLzmaEnc *p) +void LzmaEnc_Construct(CLzmaEnc *p) { RangeEnc_Construct(&p->rc); MatchFinder_Construct(&p->matchFinderBase); @@ -1752,7 +1800,7 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) return p; } -static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) +void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) { alloc->Free(alloc, p->litProbs); alloc->Free(alloc, p->saveState.litProbs); @@ -1760,7 +1808,7 @@ static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) p->saveState.litProbs = 0; } -static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) +void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) { #ifdef COMPRESS_MF_MT MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); @@ -1880,11 +1928,6 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize UInt32 posSlot; RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); p->state = kMatchNextStates[p->state]; - if (len < LZMA_MATCH_LEN_MIN) - { - p->result = SZ_ERROR_DATA; - return CheckErrors(p); - } LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); pos -= LZMA_NUM_REPS; GetPosSlot(pos, posSlot); @@ -1949,15 +1992,13 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) { UInt32 beforeSize = kNumOpts; -#ifdef COMPRESS_MF_MT Bool btMode; -#endif if (!RangeEnc_Alloc(&p->rc, alloc)) return SZ_ERROR_MEM; -#ifdef COMPRESS_MF_MT btMode = (p->matchFinderBase.btMode != 0); + #ifdef COMPRESS_MF_MT p->mtMode = (p->multiThread && !p->fastMode && btMode); -#endif + #endif { unsigned lclp = p->lc + p->lp; @@ -1998,7 +2039,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I return SZ_OK; } -static void LzmaEnc_Init(CLzmaEnc *p) +void LzmaEnc_Init(CLzmaEnc *p) { UInt32 i; p->state = 0; @@ -2057,7 +2098,7 @@ static void LzmaEnc_Init(CLzmaEnc *p) p->lpMask = (1 << p->lp) - 1; } -static void LzmaEnc_InitPrices(CLzmaEnc *p) +void LzmaEnc_InitPrices(CLzmaEnc *p) { if (!p->fastMode) { @@ -2098,6 +2139,15 @@ static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutSt 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; @@ -2105,7 +2155,16 @@ static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) p->seqBufInStream.rem = srcLen; } -static void LzmaEnc_Finish(CLzmaEncHandle pp) +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; @@ -2138,6 +2197,53 @@ static size_t MyWrite(void *pp, const void *data, size_t 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) { diff --git a/lib/arg.c b/lib/arg.c new file mode 100644 index 000000000..6a7bb8beb --- /dev/null +++ b/lib/arg.c @@ -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 . + */ + +#include +#include +#include +#include +#include +#include + +/* 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 new file mode 100644 index 000000000..f2e1b036d --- /dev/null +++ b/lib/charset.c @@ -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 . + */ + +/* 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 +#include +#include + +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/lib/cmos_datetime.c similarity index 62% rename from grub-core/lib/cmos_datetime.c rename to lib/cmos_datetime.c index 86cd91180..8db60b48c 100644 --- a/grub-core/lib/cmos_datetime.c +++ b/lib/cmos_datetime.c @@ -19,48 +19,31 @@ #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#if !defined (__powerpc__) && !defined (__sparc__) -#define grub_get_datetime_cmos grub_get_datetime -#define grub_set_datetime_cmos grub_set_datetime -#endif grub_err_t -grub_get_datetime_cmos (struct grub_datetime *datetime) +grub_get_datetime (struct grub_datetime *datetime) { int is_bcd, is_12hour; grub_uint8_t value, flag; - grub_err_t err; - err = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B, &flag); - if (err) - return err; + flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B); is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY); - err = grub_cmos_read (GRUB_CMOS_INDEX_YEAR, &value); - if (err) - return err; + 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; - err = grub_cmos_read (GRUB_CMOS_INDEX_MONTH, &value); - if (err) - return err; + value = grub_cmos_read (GRUB_CMOS_INDEX_MONTH); if (is_bcd) value = grub_bcd_to_num (value); datetime->month = value; - err = grub_cmos_read (GRUB_CMOS_INDEX_DAY_OF_MONTH, &value); - if (err) - return err; + value = grub_cmos_read (GRUB_CMOS_INDEX_DAY_OF_MONTH); if (is_bcd) value = grub_bcd_to_num (value); @@ -68,9 +51,7 @@ grub_get_datetime_cmos (struct grub_datetime *datetime) is_12hour = ! (flag & GRUB_CMOS_STATUS_B_24HOUR); - err = grub_cmos_read (GRUB_CMOS_INDEX_HOUR, &value); - if (err) - return err; + value = grub_cmos_read (GRUB_CMOS_INDEX_HOUR); if (is_12hour) { is_12hour = (value & 0x80); @@ -87,18 +68,13 @@ grub_get_datetime_cmos (struct grub_datetime *datetime) datetime->hour = value; - err = grub_cmos_read (GRUB_CMOS_INDEX_MINUTE, &value); - if (err) - return err; - + value = grub_cmos_read (GRUB_CMOS_INDEX_MINUTE); if (is_bcd) value = grub_bcd_to_num (value); datetime->minute = value; - err = grub_cmos_read (GRUB_CMOS_INDEX_SECOND, &value); - if (err) - return err; + value = grub_cmos_read (GRUB_CMOS_INDEX_SECOND); if (is_bcd) value = grub_bcd_to_num (value); @@ -108,15 +84,12 @@ grub_get_datetime_cmos (struct grub_datetime *datetime) } grub_err_t -grub_set_datetime_cmos (struct grub_datetime *datetime) +grub_set_datetime (struct grub_datetime *datetime) { int is_bcd, is_12hour; grub_uint8_t value, flag; - grub_err_t err; - err = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B, &flag); - if (err) - return err; + flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B); is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY); @@ -126,27 +99,21 @@ grub_set_datetime_cmos (struct grub_datetime *datetime) if (is_bcd) value = grub_num_to_bcd (value); - err = grub_cmos_write (GRUB_CMOS_INDEX_YEAR, value); - if (err) - return err; + grub_cmos_write (GRUB_CMOS_INDEX_YEAR, value); value = datetime->month; if (is_bcd) value = grub_num_to_bcd (value); - err = grub_cmos_write (GRUB_CMOS_INDEX_MONTH, value); - if (err) - return err; + grub_cmos_write (GRUB_CMOS_INDEX_MONTH, value); value = datetime->day; if (is_bcd) value = grub_num_to_bcd (value); - err = grub_cmos_write (GRUB_CMOS_INDEX_DAY_OF_MONTH, value); - if (err) - return err; + grub_cmos_write (GRUB_CMOS_INDEX_DAY_OF_MONTH, value); value = datetime->hour; @@ -168,27 +135,21 @@ grub_set_datetime_cmos (struct grub_datetime *datetime) if (is_12hour) value |= 0x80; - err = grub_cmos_write (GRUB_CMOS_INDEX_HOUR, value); - if (err) - return err; + grub_cmos_write (GRUB_CMOS_INDEX_HOUR, value); value = datetime->minute; if (is_bcd) value = grub_num_to_bcd (value); - err = grub_cmos_write (GRUB_CMOS_INDEX_MINUTE, value); - if (err) - return err; + grub_cmos_write (GRUB_CMOS_INDEX_MINUTE, value); value = datetime->second; if (is_bcd) value = grub_num_to_bcd (value); - err = grub_cmos_write (GRUB_CMOS_INDEX_SECOND, value); - if (err) - return err; + grub_cmos_write (GRUB_CMOS_INDEX_SECOND, value); return 0; } diff --git a/grub-core/lib/crc.c b/lib/crc.c similarity index 56% rename from grub-core/lib/crc.c rename to lib/crc.c index bf97cc63a..bc0d8aa8d 100644 --- a/grub-core/lib/crc.c +++ b/lib/crc.c @@ -20,55 +20,54 @@ #include #include -static grub_uint32_t crc32c_table [256]; - -/* Helper for init_crc32c_table. */ -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 grub_uint32_t crc32_table [256]; static void -init_crc32c_table (void) +init_crc32_table (void) { - grub_uint32_t polynomial = 0x1edc6f41; + 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++) { - crc32c_table[i] = reflect(i, 8) << 24; + crc32_table[i] = reflect(i, 8) << 24; for (j = 0; j < 8; j++) - crc32c_table[i] = (crc32c_table[i] << 1) ^ - (crc32c_table[i] & (1 << 31) ? polynomial : 0); - crc32c_table[i] = reflect(crc32c_table[i], 32); + 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_getcrc32c (grub_uint32_t crc, const void *buf, int size) +grub_getcrc32 (grub_uint32_t crc, void *buf, int size) { int i; - const grub_uint8_t *data = buf; + grub_uint8_t *data = buf; - if (! crc32c_table[1]) - init_crc32c_table (); + if (! crc32_table[1]) + init_crc32_table (); crc^= 0xffffffff; for (i = 0; i < size; i++) { - crc = (crc >> 8) ^ crc32c_table[(crc & 0xFF) ^ *data]; + crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ *data]; data++; } diff --git a/grub-core/lib/crypto.c b/lib/crypto.c similarity index 73% rename from grub-core/lib/crypto.c rename to lib/crypto.c index 396f76410..d11f0994f 100644 --- a/grub-core/lib/crypto.c +++ b/lib/crypto.c @@ -21,11 +21,6 @@ #include #include #include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); struct grub_crypto_hmac_handle { @@ -50,40 +45,8 @@ grub_burn_stack (grub_size_t size) grub_burn_stack (size - sizeof (buf)); } -void -_gcry_burn_stack (int size) -{ - grub_burn_stack (size); -} -void __attribute__ ((noreturn)) -_gcry_assert_failed (const char *expr, const char *file, int line, - const char *func) - -{ - grub_fatal ("assertion %s at %s:%d (%s) failed\n", expr, file, line, func); -} - - -void _gcry_log_error (const char *fmt, ...) -{ - va_list args; - const char *debug = grub_env_get ("debug"); - - if (! debug) - return; - - if (grub_strword (debug, "all") || grub_strword (debug, "gcrypt")) - { - grub_printf ("gcrypt error: "); - va_start (args, fmt); - grub_vprintf (fmt, args); - va_end (args); - grub_refresh (); - } -} - -void +void grub_cipher_register (gcry_cipher_spec_t *cipher) { cipher->next = grub_ciphers; @@ -102,14 +65,14 @@ grub_cipher_unregister (gcry_cipher_spec_t *cipher) } } -void +void grub_md_register (gcry_md_spec_t *digest) { digest->next = grub_digests; grub_digests = digest; } -void +void grub_md_unregister (gcry_md_spec_t *cipher) { gcry_md_spec_t **ciph; @@ -125,10 +88,7 @@ void grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in, grub_size_t inlen) { - GRUB_PROPERLY_ALIGNED_ARRAY (ctx, GRUB_CRYPTO_MAX_MD_CONTEXT_SIZE); - - if (hash->contextsize > sizeof (ctx)) - grub_fatal ("Too large md context"); + grub_uint8_t ctx[hash->contextsize]; hash->init (&ctx); hash->write (&ctx, in, inlen); hash->final (&ctx); @@ -199,99 +159,103 @@ grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher, 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, const void *in, grub_size_t size) + void *out, void *in, grub_size_t size) { - const grub_uint8_t *inptr, *end; - grub_uint8_t *outptr; - grub_size_t blocksize; + grub_uint8_t *inptr, *outptr, *end; if (!cipher->cipher->decrypt) return GPG_ERR_NOT_SUPPORTED; - blocksize = cipher->cipher->blocksize; - if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0) - || ((size & (blocksize - 1)) != 0)) + if (size % cipher->cipher->blocksize != 0) return GPG_ERR_INV_ARG; - end = (const grub_uint8_t *) in + size; + end = (grub_uint8_t *) in + size; for (inptr = in, outptr = out; inptr < end; - inptr += blocksize, outptr += blocksize) + 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, const void *in, grub_size_t size) + void *out, void *in, grub_size_t size) { - const grub_uint8_t *inptr, *end; - grub_uint8_t *outptr; - grub_size_t blocksize; + grub_uint8_t *inptr, *outptr, *end; if (!cipher->cipher->encrypt) return GPG_ERR_NOT_SUPPORTED; - blocksize = cipher->cipher->blocksize; - if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0) - || ((size & (blocksize - 1)) != 0)) + if (size % cipher->cipher->blocksize != 0) return GPG_ERR_INV_ARG; - end = (const grub_uint8_t *) in + size; + end = (grub_uint8_t *) in + size; for (inptr = in, outptr = out; inptr < end; - inptr += blocksize, outptr += blocksize) + 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, const void *in, grub_size_t size, + void *out, void *in, grub_size_t size, void *iv_in) { - grub_uint8_t *outptr; - const grub_uint8_t *inptr, *end; + grub_uint8_t *inptr, *outptr, *end; void *iv; - grub_size_t blocksize; - if (!cipher->cipher->encrypt) + if (!cipher->cipher->decrypt) return GPG_ERR_NOT_SUPPORTED; - blocksize = cipher->cipher->blocksize; - if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0) - || ((size & (blocksize - 1)) != 0)) + if (size % cipher->cipher->blocksize != 0) return GPG_ERR_INV_ARG; - end = (const grub_uint8_t *) in + size; + end = (grub_uint8_t *) in + size; iv = iv_in; for (inptr = in, outptr = out; inptr < end; - inptr += blocksize, outptr += blocksize) + inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize) { - grub_crypto_xor (outptr, inptr, iv, blocksize); + grub_crypto_xor (outptr, inptr, iv, cipher->cipher->blocksize); cipher->cipher->encrypt (cipher->ctx, outptr, outptr); iv = outptr; } - grub_memcpy (iv_in, iv, blocksize); + 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, const void *in, grub_size_t size, + void *out, void *in, grub_size_t size, void *iv) { - const grub_uint8_t *inptr, *end; - grub_uint8_t *outptr; - grub_uint8_t ivt[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE]; - grub_size_t blocksize; + grub_uint8_t *inptr, *outptr, *end; + grub_uint8_t ivt[cipher->cipher->blocksize]; if (!cipher->cipher->decrypt) return GPG_ERR_NOT_SUPPORTED; - blocksize = cipher->cipher->blocksize; - if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0) - || ((size & (blocksize - 1)) != 0)) + if (size % cipher->cipher->blocksize != 0) return GPG_ERR_INV_ARG; - if (blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE) - return GPG_ERR_INV_ARG; - end = (const grub_uint8_t *) in + size; + end = (grub_uint8_t *) in + size; for (inptr = in, outptr = out; inptr < end; - inptr += blocksize, outptr += blocksize) + inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize) { - grub_memcpy (ivt, inptr, blocksize); + grub_memcpy (ivt, inptr, cipher->cipher->blocksize); cipher->cipher->decrypt (cipher->ctx, outptr, inptr); - grub_crypto_xor (outptr, outptr, iv, blocksize); - grub_memcpy (iv, ivt, blocksize); + grub_crypto_xor (outptr, outptr, iv, cipher->cipher->blocksize); + grub_memcpy (iv, ivt, cipher->cipher->blocksize); } return GPG_ERR_NO_ERROR; } @@ -314,7 +278,7 @@ grub_crypto_hmac_init (const struct gcry_md_spec *md, if (!ctx) goto err; - if ( keylen > md->blocksize ) + if ( keylen > md->blocksize ) { helpkey = grub_malloc (md->mdlen); if (!helpkey) @@ -335,7 +299,7 @@ grub_crypto_hmac_init (const struct gcry_md_spec *md, grub_memcpy ( ipad, key, keylen ); grub_memcpy ( opad, key, keylen ); - for (i=0; i < md->blocksize; i++ ) + for (i=0; i < md->blocksize; i++ ) { ipad[i] ^= 0x36; opad[i] ^= 0x5c; @@ -369,8 +333,7 @@ grub_crypto_hmac_init (const struct gcry_md_spec *md, } void -grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd, - const void *data, +grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd, void *data, grub_size_t datalen) { hnd->md->write (hnd->ctx, data, datalen); @@ -412,7 +375,7 @@ 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, - const void *data, grub_size_t datalen, void *out) + void *data, grub_size_t datalen, void *out) { struct grub_crypto_hmac_handle *hnd; @@ -448,8 +411,7 @@ grub_crypto_memcmp (const void *a, const void *b, grub_size_t n) return !!counter; } -#ifndef GRUB_UTIL - +#ifndef GRUB_MKPASSWD int grub_password_get (char buf[], unsigned buf_size) { @@ -458,11 +420,11 @@ grub_password_get (char buf[], unsigned buf_size) while (1) { - key = grub_getkey (); + key = GRUB_TERM_ASCII_CHAR (grub_getkey ()); if (key == '\n' || key == '\r') break; - if (key == GRUB_TERM_ESC) + if (key == '\e') { cur_len = 0; break; @@ -470,8 +432,7 @@ grub_password_get (char buf[], unsigned buf_size) if (key == '\b') { - if (cur_len) - cur_len--; + cur_len--; continue; } @@ -484,10 +445,9 @@ grub_password_get (char buf[], unsigned buf_size) grub_memset (buf + cur_len, 0, buf_size - cur_len); - grub_xputs ("\n"); + grub_putchar ('\n'); grub_refresh (); - return (key != GRUB_TERM_ESC); + return (key != '\e'); } #endif - diff --git a/grub-core/lib/efi/datetime.c b/lib/efi/datetime.c similarity index 85% rename from grub-core/lib/efi/datetime.c rename to lib/efi/datetime.c index b03e4df5e..0a91c345a 100644 --- a/grub-core/lib/efi/datetime.c +++ b/lib/efi/datetime.c @@ -22,9 +22,6 @@ #include #include #include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); grub_err_t grub_get_datetime (struct grub_datetime *datetime) @@ -32,7 +29,8 @@ grub_get_datetime (struct grub_datetime *datetime) grub_efi_status_t status; struct grub_efi_time efi_time; - status = grub_efi_system_table->runtime_services->get_time (&efi_time, 0); + status = efi_call_2 (grub_efi_system_table->runtime_services->get_time, + &efi_time, 0); if (status) return grub_error (GRUB_ERR_INVALID_COMMAND, @@ -56,7 +54,8 @@ grub_set_datetime (struct grub_datetime *datetime) grub_efi_status_t status; struct grub_efi_time efi_time; - status = grub_efi_system_table->runtime_services->get_time (&efi_time, 0); + status = efi_call_2 (grub_efi_system_table->runtime_services->get_time, + &efi_time, 0); if (status) return grub_error (GRUB_ERR_INVALID_COMMAND, @@ -69,7 +68,8 @@ grub_set_datetime (struct grub_datetime *datetime) efi_time.minute = datetime->minute; efi_time.second = datetime->second; - status = grub_efi_system_table->runtime_services->set_time (&efi_time); + status = efi_call_1 (grub_efi_system_table->runtime_services->set_time, + &efi_time); if (status) return grub_error (GRUB_ERR_INVALID_COMMAND, diff --git a/grub-core/lib/envblk.c b/lib/envblk.c similarity index 96% rename from grub-core/lib/envblk.c rename to lib/envblk.c index 4862de50d..311927bd8 100644 --- a/grub-core/lib/envblk.c +++ b/lib/envblk.c @@ -143,7 +143,7 @@ grub_envblk_set (grub_envblk_t envblk, const char *name, const char *value) /* 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); + grub_memset (space + len - vl, '#', len - vl); } else /* Move the following characters forward. */ @@ -225,8 +225,7 @@ grub_envblk_delete (grub_envblk_t envblk, const char *name) void grub_envblk_iterate (grub_envblk_t envblk, - void *hook_data, - int hook (const char *name, const char *value, void *hook_data)) + int hook (const char *name, const char *value)) { char *p, *pend; @@ -235,7 +234,7 @@ grub_envblk_iterate (grub_envblk_t envblk, while (p < pend) { - if (*p != '#' && *p != '\n' && *p != '\r') + if (*p != '#') { char *name; char *value; @@ -286,7 +285,7 @@ grub_envblk_iterate (grub_envblk_t envblk, } *q = '\0'; - ret = hook (name, value, hook_data); + ret = hook (name, value); grub_free (name); if (ret) return; diff --git a/grub-core/lib/hexdump.c b/lib/hexdump.c similarity index 100% rename from grub-core/lib/hexdump.c rename to lib/hexdump.c diff --git a/grub-core/lib/i386/pc/biosnum.c b/lib/i386/pc/biosnum.c similarity index 95% rename from grub-core/lib/i386/pc/biosnum.c rename to lib/i386/pc/biosnum.c index 0f0e743c4..058c9d331 100644 --- a/grub-core/lib/i386/pc/biosnum.c +++ b/lib/i386/pc/biosnum.c @@ -19,12 +19,11 @@ #include #include #include -#include static int grub_get_root_biosnumber_default (void) { - const char *biosnum; + char *biosnum; int ret = -1; grub_device_t dev; diff --git a/lib/i386/relocator.c b/lib/i386/relocator.c new file mode 100644 index 000000000..453f73fdd --- /dev/null +++ b/lib/i386/relocator.c @@ -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 . + */ + +#include +#include + +#include +#include +#include + +#include + +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 new file mode 100644 index 000000000..6b803db13 --- /dev/null +++ b/lib/i386/relocator_asm.S @@ -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 . + */ + +#include +#include + +#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 new file mode 100644 index 000000000..06913470e --- /dev/null +++ b/lib/i386/relocator_backward.S @@ -0,0 +1,2 @@ +#define BACKWARD +#include "relocator_asm.S" diff --git a/grub-core/lib/i386/setjmp.S b/lib/i386/setjmp.S similarity index 96% rename from grub-core/lib/i386/setjmp.S rename to lib/i386/setjmp.S index 0b0740f11..a2002ae3d 100644 --- a/grub-core/lib/i386/setjmp.S +++ b/lib/i386/setjmp.S @@ -17,12 +17,9 @@ */ #include -#include .file "setjmp.S" -GRUB_MOD_LICENSE "GPLv3+" - .text /* diff --git a/grub-core/lib/libgcrypt/cipher/ChangeLog b/lib/libgcrypt/cipher/ChangeLog similarity index 97% rename from grub-core/lib/libgcrypt/cipher/ChangeLog rename to lib/libgcrypt/cipher/ChangeLog index 1b3694f58..8924f17e1 100644 --- a/grub-core/lib/libgcrypt/cipher/ChangeLog +++ b/lib/libgcrypt/cipher/ChangeLog @@ -1,93 +1,3 @@ -2010-08-19 Werner Koch - - * cipher.c (gcry_cipher_open): Remove double release of the module. - Fixes bug#1263. - -2010-06-10 Jeff Johnson (wk) - - * ecc.c (ecc_generate_ext): Parse transient-key flag. - (generate_key): Add arg TRANSIENT_KEY and use it to set the random - level. - -2010-04-12 Brad Hards (wk) - - Spelling fixes. - -2010-03-26 Werner Koch - - * tiger.c (asn): Unfetter the old TIGER from an OID. - (TIGER_CONTEXT): Add field VARIANT. - (tiger_init): Factor code out to ... - (do_init): New. - (tiger1_init, tiger2_init): New. - (_gcry_digest_spec_tiger1, _gcry_digest_spec_tiger2): New. - * md.c (digest_table): Add TIGER1 and TIGER2 variants. - -2009-12-11 Werner Koch - - * sha256.c (Cho, Maj, Sum0, Sum1): Turn macros into inline - functions. - (transform): Partly unroll to interweave the chain variables - - * sha512.c (ROTR, Ch, Maj, Sum0, Sum1): Turn macros into inline - functions. - (transform): Partly unroll to interweave the chain variables. - Suggested by Christian Grothoff. - -2009-12-10 Werner Koch - - * Makefile.am (o_flag_munging): New. - (tiger.o, tiger.lo): Use it. - - * cipher.c (do_ctr_encrypt): Add arg OUTBUFLEN. Check for - suitable value. Add check for valid inputlen. Wipe temporary - memory. - (do_ctr_decrypt): Likewise. - (do_cbc_encrypt, do_cbc_decrypt): Add arg OUTBUFLEN. Check for - suitable value. Move check for valid inputlen to here; change - returned error from INV_ARG to INV_LENGTH. - (do_ecb_encrypt, do_ecb_decrypt): Ditto. - (do_cfb_encrypt, do_cfb_decrypt): Ditto. - (do_ofb_encrypt, do_ofb_decrypt): Ditto. - (cipher_encrypt, cipher_encrypt): Adjust for above changes. - (gcry_cipher_encrypt, gcry_cipher_decrypt): Simplify. - -2009-12-09 Werner Koch - - * cipher.c (gcry_cipher_open): Allow for GCRY_CIPHER_MODE_AESWRAP. - (cipher_encrypt, cipher_decrypt): Ditto. - (do_aeswrap_encrypt, do_aeswrap_decrypt): New. - (struct gcry_cipher_handle): Add field marks. - (cipher_setkey, cipher_setiv): Update marks flags. - (cipher_reset): Reset marks. - (cipher_encrypt, cipher_decrypt): Add new arg OUTBUFLEN. - (gcry_cipher_encrypt, gcry_cipher_decrypt): Pass outbuflen to - cipher_encrypt. Replace GPG_ERR_TOO_SHORT by - GPG_ERR_BUFFER_TOO_SHORT. - -2009-08-21 Werner Koch - - * dsa.c (dsa_generate_ext): Release retfactors array before - setting it to NULL. Reported by Daiko Ueno. - -2009-07-02 Werner Koch - - * md.c (md_read): Fix incomplete check for NULL. - Reported by Fabian Kail. - -2009-03-31 Werner Koch - - * rsa.c (rsa_check_secret_key): Return GPG_ERR_BAD_SECKEY and not - GPG_ERR_PUBKEY_ALGO. - -2009-02-16 Werner Koch - - * rsa.c (generate_x931): Do not initialize TBL with automatic - variables. - * whirlpool.c, tiger.c, sha256.c, sha1.c, rmd160.c, md5.c - * md4.c, crc.c: Remove memory.h. This is garbage from gnupg. - Reported by Dan Fandrich. - 2009-01-22 Werner Koch * ecc.c (compute_keygrip): Remove superfluous const. @@ -3978,8 +3888,8 @@ Mon Feb 16 10:08:47 1998 Werner Koch (wk@isil.d.shuttle.de) (digest_algo_to_string): New. - Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + 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 diff --git a/grub-core/lib/libgcrypt/cipher/ac.c b/lib/libgcrypt/cipher/ac.c similarity index 99% rename from grub-core/lib/libgcrypt/cipher/ac.c rename to lib/libgcrypt/cipher/ac.c index 63f6fcd11..ee9498b23 100644 --- a/grub-core/lib/libgcrypt/cipher/ac.c +++ b/lib/libgcrypt/cipher/ac.c @@ -1,19 +1,19 @@ /* 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 . */ @@ -115,7 +115,7 @@ struct gcry_ac_key_pair -/* +/* * Functions for working with data sets. */ @@ -151,7 +151,7 @@ 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) { @@ -185,7 +185,7 @@ ac_data_mpi_copy (gcry_ac_mpi_t *data_mpis, unsigned int data_mpis_n, gcry_mpi_t mpi; char *label; - data_mpis_new = gcry_calloc (data_mpis_n, sizeof (*data_mpis_new)); + data_mpis_new = gcry_malloc (sizeof (*data_mpis_new) * data_mpis_n); if (! data_mpis_new) { err = gcry_error_from_errno (errno); @@ -256,7 +256,7 @@ _gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data) 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; @@ -524,13 +524,13 @@ _gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp, 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++) { @@ -572,7 +572,7 @@ _gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp, } /* Add MPI list. */ - arg_list = gcry_calloc (data_n + 1, sizeof (*arg_list)); + arg_list = gcry_malloc (sizeof (*arg_list) * (data_n + 1)); if (! arg_list) { err = gcry_error_from_errno (errno); @@ -666,7 +666,7 @@ _gcry_ac_data_from_sexp (gcry_ac_data_t *data_set, gcry_sexp_t sexp, /* Identifier matches. Now we have to distinguish two cases: - + (i) we are at the last identifier: leave loop @@ -725,7 +725,7 @@ _gcry_ac_data_from_sexp (gcry_ac_data_t *data_set, gcry_sexp_t sexp, skip_name = 0; /* Create data set from S-expression data. */ - + err = gcry_ac_data_new (&data_set_new); if (err) goto out; @@ -793,7 +793,7 @@ _gcry_ac_data_from_sexp (gcry_ac_data_t *data_set, gcry_sexp_t sexp, gcry_sexp_release (sexp_tmp); gcry_mpi_release (mpi); gcry_free (string); - + if (err) gcry_ac_data_destroy (data_set_new); @@ -1005,7 +1005,7 @@ _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; @@ -1072,7 +1072,7 @@ _gcry_ac_io_read_all (gcry_ac_io_t *ac_io, unsigned char **buffer, size_t *buffe err = gcry_error_from_errno (errno); break; } - + if (buffer_new != p) buffer_new = p; @@ -1132,7 +1132,7 @@ _gcry_ac_io_process (gcry_ac_io_t *ac_io, -/* +/* * Functions for converting data between the native ac and the * S-expression structure used by the pk interface. */ @@ -1283,7 +1283,7 @@ ac_data_construct (const char *identifier, int include_flags, /* We build a list of arguments to pass to gcry_sexp_build_array(). */ data_length = _gcry_ac_data_length (data); - arg_list = gcry_calloc (data_length, sizeof (*arg_list) * 2); + arg_list = gcry_malloc (sizeof (*arg_list) * (data_length * 2)); if (! arg_list) { err = gcry_error_from_errno (errno); @@ -1403,7 +1403,7 @@ _gcry_ac_open (gcry_ac_handle_t *handle, err = _gcry_pk_module_lookup (algorithm, &module); if (err) goto out; - + /* Allocate. */ handle_new = gcry_malloc (sizeof (*handle_new)); if (! handle_new) @@ -1420,7 +1420,7 @@ _gcry_ac_open (gcry_ac_handle_t *handle, *handle = handle_new; out: - + /* Deallocate resources. */ if (err) _gcry_pk_module_release (module); @@ -1443,7 +1443,7 @@ _gcry_ac_close (gcry_ac_handle_t handle) -/* +/* * Key management. */ @@ -1593,7 +1593,7 @@ _gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits, arg_list_n += 2; /* Allocate list. */ - arg_list = gcry_calloc (arg_list_n, sizeof (*arg_list)); + arg_list = gcry_malloc (sizeof (*arg_list) * arg_list_n); if (! arg_list) { err = gcry_error_from_errno (errno); @@ -1662,7 +1662,7 @@ _gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits, out: /* Deallocate resources. */ - + gcry_free (genkey_format); gcry_free (arg_list); gcry_sexp_release (genkey_sexp_request); @@ -1682,7 +1682,7 @@ _gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits, /* 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_pair_extract (gcry_ac_key_pair_t key_pair, gcry_ac_key_type_t which) { gcry_ac_key_t key; @@ -1851,7 +1851,7 @@ _gcry_ac_key_get_grip (gcry_ac_handle_t handle, -/* +/* * Functions performing cryptographic operations. */ @@ -2176,7 +2176,7 @@ em_randomize_nonzero (unsigned char *buffer, size_t buffer_n, for (i = 0; i < buffer_n; i++) buffer[i] = 0; - + do { /* Count zeros. */ @@ -2384,7 +2384,7 @@ emsa_pkcs_v1_5_encode (unsigned int flags, void *opts, unsigned int i; (void)flags; - + options = opts; buffer = NULL; md = NULL; @@ -2499,7 +2499,7 @@ typedef enum dencode_action dencode_action_t; /* Encode or decode a message according to the the encoding method - METHOD; ACTION specifies whether the message that is contained in + 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. */ @@ -2656,7 +2656,7 @@ _gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os, size_t *os_n) err = gcry_error_from_errno (errno); goto out; } - + _gcry_ac_mpi_to_os (mpi, buffer, buffer_n); *os = buffer; *os_n = buffer_n; @@ -2676,7 +2676,7 @@ _gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n) gcry_mpi_t xi; gcry_mpi_t x; gcry_mpi_t a; - + if (fips_mode ()) return; @@ -2692,7 +2692,7 @@ _gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n) gcry_mpi_add (x, x, xi); gcry_mpi_mul_ui (a, a, 256); } - + gcry_mpi_release (xi); gcry_mpi_release (a); @@ -2702,7 +2702,7 @@ _gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n) -/* +/* * Implementation of Encryption Schemes (ES) and Signature Schemes * with Appendix (SSA). */ @@ -2824,7 +2824,7 @@ ac_dencode_prepare (gcry_ac_handle_t handle, gcry_ac_key_t key, void *opts, err = gcry_error_from_errno (errno); goto out; } - + err = (*scheme.dencode_prepare) (handle, key, opts, options_em); if (err) goto out; @@ -3065,7 +3065,7 @@ _gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle, goto out; out: - + _gcry_ac_data_destroy (data_encrypted); gcry_mpi_release (mpi_encrypted); gcry_mpi_release (mpi_decrypted); @@ -3270,7 +3270,7 @@ _gcry_ac_data_verify_scheme (gcry_ac_handle_t handle, gcry_mpi_release (mpi_signature); mpi_signature = NULL; - + err = _gcry_ac_data_verify (handle, key, mpi_data, data_signed); out: @@ -3287,7 +3287,7 @@ _gcry_ac_data_verify_scheme (gcry_ac_handle_t handle, } -/* +/* * General functions. */ diff --git a/grub-core/lib/libgcrypt/cipher/arcfour.c b/lib/libgcrypt/cipher/arcfour.c similarity index 97% rename from grub-core/lib/libgcrypt/cipher/arcfour.c rename to lib/libgcrypt/cipher/arcfour.c index 6ef07fb20..6bb0555c6 100644 --- a/grub-core/lib/libgcrypt/cipher/arcfour.c +++ b/lib/libgcrypt/cipher/arcfour.c @@ -45,7 +45,7 @@ do_encrypt_stream( ARCFOUR_context *ctx, register int i = ctx->idx_i; register int j = ctx->idx_j; register byte *sbox = ctx->sbox; - register int t; + register int t; while ( length-- ) { @@ -56,7 +56,7 @@ do_encrypt_stream( ARCFOUR_context *ctx, 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; } @@ -80,7 +80,7 @@ do_arcfour_setkey (void *context, const byte *key, unsigned int keylen) byte karr[256]; ARCFOUR_context *ctx = (ARCFOUR_context *) context; - if (!initialized ) + if (!initialized ) { initialized = 1; selftest_failed = selftest(); @@ -98,14 +98,14 @@ do_arcfour_setkey (void *context, const byte *key, unsigned int keylen) ctx->sbox[i] = i; for (i=0; i < 256; i++ ) karr[i] = key[i%keylen]; - for (i=j=0; i < 256; i++ ) + 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; @@ -125,8 +125,8 @@ static const char* selftest(void) { ARCFOUR_context ctx; - byte scratch[16]; - + byte scratch[16]; + /* Test vector from Cryptlib labeled there: "from the State/Commerce Department". */ static byte key_1[] = @@ -153,3 +153,4 @@ 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/lib/libgcrypt/cipher/bithelp.h similarity index 100% rename from grub-core/lib/libgcrypt/cipher/bithelp.h rename to lib/libgcrypt/cipher/bithelp.h diff --git a/grub-core/lib/libgcrypt/cipher/blowfish.c b/lib/libgcrypt/cipher/blowfish.c similarity index 99% rename from grub-core/lib/libgcrypt/cipher/blowfish.c rename to lib/libgcrypt/cipher/blowfish.c index b4d2b9c9a..6ef68e371 100644 --- a/grub-core/lib/libgcrypt/cipher/blowfish.c +++ b/lib/libgcrypt/cipher/blowfish.c @@ -501,7 +501,7 @@ do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen) static int initialized; static const char *selftest_failed; - if( !initialized ) + if( !initialized ) { initialized = 1; selftest_failed = selftest(); @@ -513,7 +513,7 @@ do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen) for(i=0; i < BLOWFISH_ROUNDS+2; i++ ) c->p[i] = ps[i]; - for(i=0; i < 256; i++ ) + for(i=0; i < 256; i++ ) { c->s0[i] = ks0[i]; c->s1[i] = ks1[i]; @@ -521,7 +521,7 @@ do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen) c->s3[i] = ks3[i]; } - for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ ) + for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ ) { #ifdef WORDS_BIGENDIAN ((byte*)&data)[0] = key[j]; @@ -545,7 +545,7 @@ do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen) c->p[i] = datal; c->p[i+1] = datar; } - for(i=0; i < 256; i += 2 ) + for(i=0; i < 256; i += 2 ) { do_encrypt( c, &datal, &datar ); c->s0[i] = datal; diff --git a/grub-core/lib/libgcrypt/cipher/camellia-glue.c b/lib/libgcrypt/cipher/camellia-glue.c similarity index 99% rename from grub-core/lib/libgcrypt/cipher/camellia-glue.c rename to lib/libgcrypt/cipher/camellia-glue.c index a26362177..067af85bc 100644 --- a/grub-core/lib/libgcrypt/cipher/camellia-glue.c +++ b/lib/libgcrypt/cipher/camellia-glue.c @@ -32,7 +32,7 @@ * 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 @@ -50,7 +50,7 @@ #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_setup192 CAMELLIA_PREFIX(camellia_setup192) #define camellia_setup256 CAMELLIA_PREFIX(camellia_setup256) #endif /*CAMELLIA_EXT_SYM_PREFIX*/ @@ -99,7 +99,7 @@ camellia_setkey(void *c, const byte *key, unsigned keylen) +(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; } @@ -137,7 +137,7 @@ selftest(void) { CAMELLIA_context ctx; byte scratch[16]; - + /* These test vectors are from RFC-3713 */ const byte plaintext[]= { diff --git a/grub-core/lib/libgcrypt/cipher/camellia.c b/lib/libgcrypt/cipher/camellia.c similarity index 99% rename from grub-core/lib/libgcrypt/cipher/camellia.c rename to lib/libgcrypt/cipher/camellia.c index 2e28bce2a..79cd49b7c 100644 --- a/grub-core/lib/libgcrypt/cipher/camellia.c +++ b/lib/libgcrypt/cipher/camellia.c @@ -19,7 +19,7 @@ */ /* - * Algorithm Specification + * Algorithm Specification * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html */ @@ -937,7 +937,7 @@ void camellia_setup256(const unsigned char *key, u32 *subkey) 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; } @@ -1049,14 +1049,14 @@ void camellia_encrypt128(const u32 *subkey, u32 *io) 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); @@ -1267,7 +1267,7 @@ void camellia_decrypt256(const u32 *subkey, u32 *io) /* 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), @@ -1379,8 +1379,8 @@ void camellia_decrypt256(const u32 *subkey, u32 *io) * API for compatibility */ -void Camellia_Ekeygen(const int keyBitLength, - const unsigned char *rawKey, +void Camellia_Ekeygen(const int keyBitLength, + const unsigned char *rawKey, KEY_TABLE_TYPE keyTable) { switch(keyBitLength) { @@ -1399,9 +1399,9 @@ void Camellia_Ekeygen(const int keyBitLength, } -void Camellia_EncryptBlock(const int keyBitLength, - const unsigned char *plaintext, - const KEY_TABLE_TYPE keyTable, +void Camellia_EncryptBlock(const int keyBitLength, + const unsigned char *plaintext, + const KEY_TABLE_TYPE keyTable, unsigned char *ciphertext) { u32 tmp[4]; @@ -1430,9 +1430,9 @@ void Camellia_EncryptBlock(const int keyBitLength, PUTU32(ciphertext + 12, tmp[3]); } -void Camellia_DecryptBlock(const int keyBitLength, - const unsigned char *ciphertext, - const KEY_TABLE_TYPE keyTable, +void Camellia_DecryptBlock(const int keyBitLength, + const unsigned char *ciphertext, + const KEY_TABLE_TYPE keyTable, unsigned char *plaintext) { u32 tmp[4]; diff --git a/grub-core/lib/libgcrypt/cipher/camellia.h b/lib/libgcrypt/cipher/camellia.h similarity index 91% rename from grub-core/lib/libgcrypt/cipher/camellia.h rename to lib/libgcrypt/cipher/camellia.h index cccf786ca..4425a3a2b 100644 --- a/grub-core/lib/libgcrypt/cipher/camellia.h +++ b/lib/libgcrypt/cipher/camellia.h @@ -25,7 +25,7 @@ * 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 @@ -43,7 +43,7 @@ #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_setup192 CAMELLIA_PREFIX(camellia_setup192) #define camellia_setup256 CAMELLIA_PREFIX(camellia_setup256) #endif /*CAMELLIA_EXT_SYM_PREFIX*/ @@ -60,17 +60,17 @@ typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; void Camellia_Ekeygen(const int keyBitLength, - const unsigned char *rawKey, + const unsigned char *rawKey, KEY_TABLE_TYPE keyTable); void Camellia_EncryptBlock(const int keyBitLength, - const unsigned char *plaintext, - const KEY_TABLE_TYPE keyTable, + 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, +void Camellia_DecryptBlock(const int keyBitLength, + const unsigned char *cipherText, + const KEY_TABLE_TYPE keyTable, unsigned char *plaintext); diff --git a/grub-core/lib/libgcrypt/cipher/cast5.c b/lib/libgcrypt/cipher/cast5.c similarity index 99% rename from grub-core/lib/libgcrypt/cipher/cast5.c rename to lib/libgcrypt/cipher/cast5.c index 9905f5cb9..333d55e91 100644 --- a/grub-core/lib/libgcrypt/cipher/cast5.c +++ b/lib/libgcrypt/cipher/cast5.c @@ -569,7 +569,7 @@ do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen ) u32 z[4]; u32 k[16]; - if( !initialized ) + if( !initialized ) { initialized = 1; selftest_failed = selftest(); diff --git a/grub-core/lib/libgcrypt/cipher/cipher.c b/lib/libgcrypt/cipher/cipher.c similarity index 68% rename from grub-core/lib/libgcrypt/cipher/cipher.c rename to lib/libgcrypt/cipher/cipher.c index 9852d6a5a..2c33ee94f 100644 --- a/grub-core/lib/libgcrypt/cipher/cipher.c +++ b/lib/libgcrypt/cipher/cipher.c @@ -1,6 +1,6 @@ /* cipher.c - cipher dispatcher * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 - * 2005, 2007, 2008, 2009, 2011 Free Software Foundation, Inc. + * 2005, 2007, 2008 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -33,12 +33,9 @@ #define CTX_MAGIC_NORMAL 0x24091964 #define CTX_MAGIC_SECURE 0x46919042 -/* Try to use 16 byte aligned cipher context for better performance. - We use the aligned attribute, thus it is only possible to implement - this with gcc. */ #undef NEED_16BYTE_ALIGNED_CONTEXT -#if defined (__GNUC__) -# define NEED_16BYTE_ALIGNED_CONTEXT 1 +#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 @@ -61,39 +58,39 @@ static struct cipher_table_entry &dummy_extra_spec, GCRY_CIPHER_BLOWFISH }, #endif #if USE_DES - { &_gcry_cipher_spec_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, + { &_gcry_cipher_spec_arcfour, &dummy_extra_spec, GCRY_CIPHER_ARCFOUR }, #endif #if USE_CAST5 - { &_gcry_cipher_spec_cast5, + { &_gcry_cipher_spec_cast5, &dummy_extra_spec, GCRY_CIPHER_CAST5 }, #endif #if USE_AES - { &_gcry_cipher_spec_aes, + { &_gcry_cipher_spec_aes, &_gcry_cipher_extraspec_aes, GCRY_CIPHER_AES, 1 }, - { &_gcry_cipher_spec_aes192, + { &_gcry_cipher_spec_aes192, &_gcry_cipher_extraspec_aes192, GCRY_CIPHER_AES192, 1 }, - { &_gcry_cipher_spec_aes256, + { &_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, + { &_gcry_cipher_spec_twofish128, &dummy_extra_spec, GCRY_CIPHER_TWOFISH128 }, #endif #if USE_SERPENT - { &_gcry_cipher_spec_serpent128, + { &_gcry_cipher_spec_serpent128, &dummy_extra_spec, GCRY_CIPHER_SERPENT128 }, { &_gcry_cipher_spec_serpent192, &dummy_extra_spec, GCRY_CIPHER_SERPENT192 }, - { &_gcry_cipher_spec_serpent256, + { &_gcry_cipher_spec_serpent256, &dummy_extra_spec, GCRY_CIPHER_SERPENT256 }, #endif #if USE_RFC2268 @@ -101,20 +98,16 @@ static struct cipher_table_entry &dummy_extra_spec, GCRY_CIPHER_RFC2268_40 }, #endif #if USE_SEED - { &_gcry_cipher_spec_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, + { &_gcry_cipher_spec_camellia192, &dummy_extra_spec, GCRY_CIPHER_CAMELLIA192 }, { &_gcry_cipher_spec_camellia256, &dummy_extra_spec, GCRY_CIPHER_CAMELLIA256 }, -#endif -#ifdef USE_IDEA - { &_gcry_cipher_spec_idea, - &dummy_extra_spec, GCRY_CIPHER_IDEA }, #endif { NULL } }; @@ -125,7 +118,7 @@ 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 whether the default ciphers have already been +/* Flag to check wether the default ciphers have already been registered. */ static int default_ciphers_registered; @@ -144,20 +137,19 @@ static int default_ciphers_registered; while (0) -/* A VIA processor with the Padlock engine as well as the Intel AES_NI - instructions require 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 +/* 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 +#endif char c[1]; } cipher_context_alignment_t; @@ -174,7 +166,7 @@ struct gcry_cipher_handle /* The algorithm id. This is a hack required because the module interface does not easily allow to retrieve this value. */ - int algo; + int algo; /* A structure with function pointers for bulk operations. Due to limitations of the module system (we don't want to change the @@ -182,19 +174,16 @@ struct gcry_cipher_handle 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 (*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 (*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 (*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); - void (*ctr_enc)(void *context, unsigned char *iv, + void (*cbc_dec)(void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); } bulk; @@ -203,29 +192,19 @@ struct gcry_cipher_handle int mode; unsigned int flags; - struct { - unsigned int key:1; /* Set to 1 if a key has been set. */ - unsigned int iv:1; /* Set to 1 if a IV has been set. */ - } marks; - - /* The initialization vector. For best performance we make sure - that it is properly aligned. In particular some implementations - of bulk operations expect an 16 byte aligned IV. */ + /* The initialization vector. To help code optimization we make + sure that it is aligned on an unsigned long and u32 boundary. */ union { - cipher_context_alignment_t iv_align; - unsigned char iv[MAX_BLOCKSIZE]; + unsigned long dummy_iv; + u32 dummy_u32_iv; + unsigned char iv[MAX_BLOCKSIZE]; } u_iv; - /* The counter for CTR mode. This field is also used by AESWRAP and - thus we can't use the U_IV union. */ - union { - cipher_context_alignment_t iv_align; - unsigned char ctr[MAX_BLOCKSIZE]; - } u_ctr; - - /* Space to save an IV or CTR for chaining operations. */ unsigned char lastiv[MAX_BLOCKSIZE]; - int unused; /* Number of unused bytes in LASTIV. */ + 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 @@ -243,7 +222,7 @@ struct gcry_cipher_handle static gcry_err_code_t dummy_setkey (void *c, const unsigned char *key, unsigned int keylen) { - (void)c; + (void)c; (void)key; (void)keylen; return GPG_ERR_NO_ERROR; @@ -302,7 +281,7 @@ 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) @@ -405,8 +384,8 @@ _gcry_cipher_register (gcry_cipher_spec_t *cipher, ath_mutex_lock (&ciphers_registered_lock); err = _gcry_module_add (&ciphers_registered, 0, - (void *)cipher, - (void *)(extraspec? extraspec : &dummy_extra_spec), + (void *)cipher, + (void *)(extraspec? extraspec : &dummy_extra_spec), &mod); ath_mutex_unlock (&ciphers_registered_lock); @@ -436,7 +415,7 @@ gcry_cipher_unregister (gcry_module_t module) 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 +static int search_oid (const char *oid, int *algorithm, gcry_cipher_oid_spec_t *oid_spec) { gcry_module_t module; @@ -500,7 +479,7 @@ gcry_cipher_map_name (const char *string) } ath_mutex_unlock (&ciphers_registered_lock); - + return algorithm; } @@ -609,13 +588,15 @@ check_cipher_algo (int algorithm) else err = GPG_ERR_CIPHER_ALGO; ath_mutex_unlock (&ciphers_registered_lock); - + return err; } -/* Return the standard length in bits of the key for the cipher - algorithm with the identifier ALGORITHM. */ +/* 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) { @@ -633,13 +614,17 @@ cipher_get_keylen (int algorithm) 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 return 0 for an invalid algorithm. */ + 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) { @@ -657,6 +642,8 @@ cipher_get_blocksize (int algorithm) 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; @@ -691,10 +678,10 @@ gcry_cipher_open (gcry_cipher_hd_t *handle, /* 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 whether the cipher is marked + /* 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); @@ -706,6 +693,7 @@ gcry_cipher_open (gcry_cipher_hd_t *handle, { /* Not available for use. */ err = GPG_ERR_CIPHER_ALGO; + _gcry_module_release (module); } else { @@ -719,7 +707,7 @@ gcry_cipher_open (gcry_cipher_hd_t *handle, /* check flags */ if ((! err) - && ((flags & ~(0 + && ((flags & ~(0 | GCRY_CIPHER_SECURE | GCRY_CIPHER_ENABLE_SYNC | GCRY_CIPHER_CBC_CTS @@ -736,7 +724,6 @@ gcry_cipher_open (gcry_cipher_hd_t *handle, case GCRY_CIPHER_MODE_CFB: case GCRY_CIPHER_MODE_OFB: case GCRY_CIPHER_MODE_CTR: - case GCRY_CIPHER_MODE_AESWRAP: if ((cipher->encrypt == dummy_encrypt_block) || (cipher->decrypt == dummy_decrypt_block)) err = GPG_ERR_INV_CIPHER_MODE; @@ -782,7 +769,7 @@ gcry_cipher_open (gcry_cipher_hd_t *handle, h = gcry_calloc (1, size); if (! h) - err = gpg_err_code_from_syserror (); + err = gpg_err_code_from_errno (errno); else { size_t off = 0; @@ -818,10 +805,9 @@ gcry_cipher_open (gcry_cipher_hd_t *handle, h->bulk.cfb_dec = _gcry_aes_cfb_dec; h->bulk.cbc_enc = _gcry_aes_cbc_enc; h->bulk.cbc_dec = _gcry_aes_cbc_dec; - h->bulk.ctr_enc = _gcry_aes_ctr_enc; break; #endif /*USE_AES*/ - + default: break; } @@ -896,10 +882,7 @@ cipher_setkey (gcry_cipher_hd_t c, byte *key, unsigned int keylen) memcpy ((void *) ((char *) &c->context.c + c->cipher->contextsize), (void *) &c->context.c, c->cipher->contextsize); - c->marks.key = 1; } - else - c->marks.key = 0; return gcry_error (ret); } @@ -911,7 +894,7 @@ 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 (iv) { if (ivlen != c->cipher->blocksize) { @@ -922,10 +905,7 @@ cipher_setiv( gcry_cipher_hd_t c, const byte *iv, unsigned ivlen ) if (ivlen > c->cipher->blocksize) ivlen = c->cipher->blocksize; memcpy (c->u_iv.iv, iv, ivlen); - c->marks.iv = 1; } - else - c->marks.iv = 0; c->unused = 0; } @@ -938,92 +918,61 @@ cipher_reset (gcry_cipher_hd_t c) memcpy (&c->context.c, (char *) &c->context.c + c->cipher->contextsize, c->cipher->contextsize); - memset (&c->marks, 0, sizeof c->marks); memset (c->u_iv.iv, 0, c->cipher->blocksize); memset (c->lastiv, 0, c->cipher->blocksize); - memset (c->u_ctr.ctr, 0, c->cipher->blocksize); + memset (c->ctr, 0, c->cipher->blocksize); } - -static gcry_err_code_t -do_ecb_encrypt (gcry_cipher_hd_t c, - unsigned char *outbuf, unsigned int outbuflen, - const unsigned char *inbuf, unsigned int inbuflen) +static void +do_ecb_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, + unsigned int nblocks ) { - unsigned int blocksize = c->cipher->blocksize; - unsigned int n, nblocks; - - if (outbuflen < inbuflen) - return GPG_ERR_BUFFER_TOO_SHORT; - if ((inbuflen % blocksize)) - return GPG_ERR_INV_LENGTH; - - nblocks = inbuflen / c->cipher->blocksize; - + unsigned int n; + for (n=0; n < nblocks; n++ ) { - c->cipher->encrypt (&c->context.c, outbuf, (byte*)/*arggg*/inbuf); - inbuf += blocksize; - outbuf += blocksize; + c->cipher->encrypt ( &c->context.c, outbuf, (byte*)/*arggg*/inbuf ); + inbuf += c->cipher->blocksize; + outbuf += c->cipher->blocksize; } - return 0; } -static gcry_err_code_t -do_ecb_decrypt (gcry_cipher_hd_t c, - unsigned char *outbuf, unsigned int outbuflen, - const unsigned char *inbuf, unsigned int inbuflen) +static void +do_ecb_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, + unsigned int nblocks ) { - unsigned int blocksize = c->cipher->blocksize; - unsigned int n, nblocks; + unsigned int n; - if (outbuflen < inbuflen) - return GPG_ERR_BUFFER_TOO_SHORT; - if ((inbuflen % blocksize)) - return GPG_ERR_INV_LENGTH; - nblocks = inbuflen / c->cipher->blocksize; - - for (n=0; n < nblocks; n++ ) + for (n=0; n < nblocks; n++ ) { - c->cipher->decrypt (&c->context.c, outbuf, (byte*)/*arggg*/inbuf ); - inbuf += blocksize; - outbuf += blocksize; + c->cipher->decrypt ( &c->context.c, outbuf, (byte*)/*arggg*/inbuf ); + inbuf += c->cipher->blocksize; + outbuf += c->cipher->blocksize; } - - return 0; } -static gcry_err_code_t -do_cbc_encrypt (gcry_cipher_hd_t c, - unsigned char *outbuf, unsigned int outbuflen, - const unsigned char *inbuf, unsigned int inbuflen) +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 = inbuflen / blocksize; + unsigned nblocks = nbytes / blocksize; - if (outbuflen < ((c->flags & GCRY_CIPHER_CBC_MAC)? blocksize : inbuflen)) - return GPG_ERR_BUFFER_TOO_SHORT; - - if ((inbuflen % c->cipher->blocksize) - && !(inbuflen > c->cipher->blocksize - && (c->flags & GCRY_CIPHER_CBC_CTS))) - return GPG_ERR_INV_LENGTH; - - if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize) + if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) { - if ((inbuflen % blocksize) == 0) + 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)); + (c->flags & GCRY_CIPHER_CBC_MAC)); inbuf += nblocks * blocksize; if (!(c->flags & GCRY_CIPHER_CBC_MAC)) outbuf += nblocks * blocksize; @@ -1042,17 +991,17 @@ do_cbc_encrypt (gcry_cipher_hd_t c, } } - if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > 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 ((inbuflen % blocksize) == 0) + if ((nbytes % blocksize) == 0) restbytes = blocksize; else - restbytes = inbuflen % blocksize; + restbytes = nbytes % blocksize; outbuf -= blocksize; for (ivp = c->u_iv.iv, i = 0; i < restbytes; i++) @@ -1063,51 +1012,40 @@ do_cbc_encrypt (gcry_cipher_hd_t c, } for (; i < blocksize; i++) outbuf[i] = 0 ^ *ivp++; - + c->cipher->encrypt (&c->context.c, outbuf, outbuf); memcpy (c->u_iv.iv, outbuf, blocksize); } - - return 0; } -static gcry_err_code_t -do_cbc_decrypt (gcry_cipher_hd_t c, - unsigned char *outbuf, unsigned int outbuflen, - const unsigned char *inbuf, unsigned int inbuflen) +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 = inbuflen / blocksize; + unsigned int nblocks = nbytes / blocksize; - if (outbuflen < inbuflen) - return GPG_ERR_BUFFER_TOO_SHORT; - - if ((inbuflen % c->cipher->blocksize) - && !(inbuflen > c->cipher->blocksize - && (c->flags & GCRY_CIPHER_CBC_CTS))) - return GPG_ERR_INV_LENGTH; - - if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize) + if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) { nblocks--; - if ((inbuflen % blocksize) == 0) + 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); + 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++ ) + 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 @@ -1122,22 +1060,22 @@ do_cbc_decrypt (gcry_cipher_hd_t c, } } - if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize) + if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) { int restbytes; - - if ((inbuflen % blocksize) == 0) + + if ((nbytes % blocksize) == 0) restbytes = blocksize; else - restbytes = inbuflen % blocksize; - + 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]; @@ -1146,38 +1084,32 @@ do_cbc_decrypt (gcry_cipher_hd_t c, outbuf[i] ^= *ivp++; /* c->lastiv is now really lastlastiv, does this matter? */ } - - return 0; } -static gcry_err_code_t -do_cfb_encrypt (gcry_cipher_hd_t c, - unsigned char *outbuf, unsigned int outbuflen, - const unsigned char *inbuf, unsigned int inbuflen) +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 (outbuflen < inbuflen) - return GPG_ERR_BUFFER_TOO_SHORT; - - if ( inbuflen <= c->unused ) + + 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; - inbuflen; - inbuflen--, c->unused-- ) + nbytes; + nbytes--, c->unused-- ) *outbuf++ = (*ivp++ ^= *inbuf++); - return 0; + return; } if ( c->unused ) { /* XOR the input with the IV and store input into IV */ - inbuflen -= c->unused; + nbytes -= c->unused; for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- ) *outbuf++ = (*ivp++ ^= *inbuf++); } @@ -1185,17 +1117,17 @@ do_cfb_encrypt (gcry_cipher_hd_t c, /* 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 (inbuflen >= blocksize_x_2 && c->bulk.cfb_enc) + if (nbytes >= blocksize_x_2 && c->bulk.cfb_enc) { - unsigned int nblocks = inbuflen / blocksize; - c->bulk.cfb_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks); + 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; - inbuflen -= nblocks * blocksize; + nbytes -= nblocks * blocksize; } else { - while ( inbuflen >= blocksize_x_2 ) + while ( nbytes >= blocksize_x_2 ) { int i; /* Encrypt the IV. */ @@ -1203,11 +1135,11 @@ do_cfb_encrypt (gcry_cipher_hd_t c, /* 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++); - inbuflen -= blocksize; + nbytes -= blocksize; } } - if ( inbuflen >= blocksize ) + if ( nbytes >= blocksize ) { int i; /* Save the current IV and then encrypt the IV. */ @@ -1216,56 +1148,51 @@ do_cfb_encrypt (gcry_cipher_hd_t c, /* 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++); - inbuflen -= blocksize; + nbytes -= blocksize; } - if ( inbuflen ) + 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 -= inbuflen; - for(ivp=c->u_iv.iv; inbuflen; inbuflen-- ) + c->unused -= nbytes; + for(ivp=c->u_iv.iv; nbytes; nbytes-- ) *outbuf++ = (*ivp++ ^= *inbuf++); } - return 0; } -static gcry_err_code_t -do_cfb_decrypt (gcry_cipher_hd_t c, - unsigned char *outbuf, unsigned int outbuflen, - const unsigned char *inbuf, unsigned int inbuflen) +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 (outbuflen < inbuflen) - return GPG_ERR_BUFFER_TOO_SHORT; - - if (inbuflen <= c->unused) + + 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; - inbuflen; - inbuflen--, c->unused--) + nbytes; + nbytes--, c->unused--) { temp = *inbuf++; *outbuf++ = *ivp ^ temp; *ivp++ = temp; } - return 0; + return; } - + if (c->unused) { /* XOR the input with the IV and store input into IV. */ - inbuflen -= c->unused; + nbytes -= c->unused; for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- ) { temp = *inbuf++; @@ -1273,21 +1200,21 @@ do_cfb_decrypt (gcry_cipher_hd_t c, *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 (inbuflen >= blocksize_x_2 && c->bulk.cfb_dec) + if (nbytes >= blocksize_x_2 && c->bulk.cfb_dec) { - unsigned int nblocks = inbuflen / blocksize; - c->bulk.cfb_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks); + 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; - inbuflen -= nblocks * blocksize; + nbytes -= nblocks * blocksize; } else { - while (inbuflen >= blocksize_x_2 ) + while (nbytes >= blocksize_x_2 ) { /* Encrypt the IV. */ c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); @@ -1298,11 +1225,11 @@ do_cfb_decrypt (gcry_cipher_hd_t c, *outbuf++ = *ivp ^ temp; *ivp++ = temp; } - inbuflen -= blocksize; + nbytes -= blocksize; } } - if (inbuflen >= blocksize ) + if (nbytes >= blocksize ) { /* Save the current IV and then encrypt the IV. */ memcpy ( c->lastiv, c->u_iv.iv, blocksize); @@ -1314,109 +1241,99 @@ do_cfb_decrypt (gcry_cipher_hd_t c, *outbuf++ = *ivp ^ temp; *ivp++ = temp; } - inbuflen -= blocksize; + nbytes -= blocksize; } - if (inbuflen) - { + 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 -= inbuflen; - for (ivp=c->u_iv.iv; inbuflen; inbuflen-- ) + c->unused -= nbytes; + for (ivp=c->u_iv.iv; nbytes; nbytes-- ) { temp = *inbuf++; *outbuf++ = *ivp ^ temp; *ivp++ = temp; } } - return 0; } -static gcry_err_code_t -do_ofb_encrypt (gcry_cipher_hd_t c, - unsigned char *outbuf, unsigned int outbuflen, - const unsigned char *inbuf, unsigned int inbuflen) +static void +do_ofb_encrypt( gcry_cipher_hd_t c, + byte *outbuf, const byte *inbuf, unsigned nbytes ) { - unsigned char *ivp; + byte *ivp; size_t blocksize = c->cipher->blocksize; - if (outbuflen < inbuflen) - return GPG_ERR_BUFFER_TOO_SHORT; - - if ( inbuflen <= c->unused ) + 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; - inbuflen; - inbuflen--, c->unused-- ) + nbytes; + nbytes--, c->unused-- ) *outbuf++ = (*ivp++ ^ *inbuf++); - return 0; + return; } if( c->unused ) { - inbuflen -= 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 ( inbuflen >= blocksize ) + 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++); - inbuflen -= blocksize; + nbytes -= blocksize; } - if ( inbuflen ) + 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 -= inbuflen; - for(ivp=c->u_iv.iv; inbuflen; inbuflen-- ) + c->unused -= nbytes; + for(ivp=c->u_iv.iv; nbytes; nbytes-- ) *outbuf++ = (*ivp++ ^ *inbuf++); } - return 0; } -static gcry_err_code_t -do_ofb_decrypt (gcry_cipher_hd_t c, - unsigned char *outbuf, unsigned int outbuflen, - const unsigned char *inbuf, unsigned int inbuflen) +static void +do_ofb_decrypt( gcry_cipher_hd_t c, + byte *outbuf, const byte *inbuf, unsigned int nbytes ) { - unsigned char *ivp; + byte *ivp; size_t blocksize = c->cipher->blocksize; - - if (outbuflen < inbuflen) - return GPG_ERR_BUFFER_TOO_SHORT; - - if( inbuflen <= c->unused ) + + if( nbytes <= c->unused ) { /* Short enough to be encoded by the remaining XOR mask. */ - for (ivp=c->u_iv.iv+blocksize - c->unused; inbuflen; inbuflen--,c->unused--) + for (ivp=c->u_iv.iv+blocksize - c->unused; nbytes; nbytes--,c->unused--) *outbuf++ = *ivp++ ^ *inbuf++; - return 0; + return; } if ( c->unused ) { - inbuflen -= 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 ( inbuflen >= blocksize ) + while ( nbytes >= blocksize ) { int i; /* Encrypt the IV (and save the current one). */ @@ -1424,335 +1341,113 @@ do_ofb_decrypt (gcry_cipher_hd_t c, 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++; - inbuflen -= blocksize; + nbytes -= blocksize; } - if ( inbuflen ) + 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 -= inbuflen; - for (ivp=c->u_iv.iv; inbuflen; inbuflen-- ) + c->unused -= nbytes; + for (ivp=c->u_iv.iv; nbytes; nbytes-- ) *outbuf++ = *ivp++ ^ *inbuf++; } - return 0; } -static gcry_err_code_t -do_ctr_encrypt (gcry_cipher_hd_t c, - unsigned char *outbuf, unsigned int outbuflen, - const unsigned char *inbuf, unsigned int inbuflen) +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; - unsigned int blocksize = c->cipher->blocksize; - unsigned int nblocks; - if (outbuflen < inbuflen) - return GPG_ERR_BUFFER_TOO_SHORT; - - /* First process a left over encrypted counter. */ - if (c->unused) + for(n=0; n < nbytes; n++) { - gcry_assert (c->unused < blocksize); - i = blocksize - c->unused; - for (n=0; c->unused && n < inbuflen; c->unused--, n++, i++) - { - /* XOR input with encrypted counter and store in output. */ - outbuf[n] = inbuf[n] ^ c->lastiv[i]; - } - inbuf += n; - outbuf += n; - inbuflen -= n; - } + if ((n % c->cipher->blocksize) == 0) + { + c->cipher->encrypt (&c->context.c, tmp, c->ctr); - - /* Use a bulk method if available. */ - nblocks = inbuflen / blocksize; - if (nblocks && c->bulk.ctr_enc) - { - c->bulk.ctr_enc (&c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks); - inbuf += nblocks * blocksize; - outbuf += nblocks * blocksize; - inbuflen -= nblocks * blocksize; - } - - /* If we don't have a bulk method use the standard method. We also - use this method for the a remaining partial block. */ - if (inbuflen) - { - unsigned char tmp[MAX_BLOCKSIZE]; - - for (n=0; n < inbuflen; n++) - { - if ((n % blocksize) == 0) - { - c->cipher->encrypt (&c->context.c, tmp, c->u_ctr.ctr); - - for (i = blocksize; i > 0; i--) - { - c->u_ctr.ctr[i-1]++; - if (c->u_ctr.ctr[i-1] != 0) - break; - } - } - - /* XOR input with encrypted counter and store in output. */ - outbuf[n] = inbuf[n] ^ tmp[n % blocksize]; - } - - /* Save the unused bytes of the counter. */ - n %= blocksize; - c->unused = (blocksize - n) % blocksize; - if (c->unused) - memcpy (c->lastiv+n, tmp+n, c->unused); - - wipememory (tmp, sizeof tmp); - } - - return 0; -} - -static gcry_err_code_t -do_ctr_decrypt (gcry_cipher_hd_t c, - unsigned char *outbuf, unsigned int outbuflen, - const unsigned char *inbuf, unsigned int inbuflen) -{ - return do_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); -} - - -/* Perform the AES-Wrap algorithm as specified by RFC3394. We - implement this as a mode usable with any cipher algorithm of - blocksize 128. */ -static gcry_err_code_t -do_aeswrap_encrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen, - const byte *inbuf, unsigned int inbuflen ) -{ - int j, x; - unsigned int n, i; - unsigned char *r, *a, *b; - unsigned char t[8]; - -#if MAX_BLOCKSIZE < 8 -#error Invalid block size -#endif - /* We require a cipher with a 128 bit block length. */ - if (c->cipher->blocksize != 16) - return GPG_ERR_INV_LENGTH; - - /* The output buffer must be able to hold the input data plus one - additional block. */ - if (outbuflen < inbuflen + 8) - return GPG_ERR_BUFFER_TOO_SHORT; - /* Input data must be multiple of 64 bits. */ - if (inbuflen % 8) - return GPG_ERR_INV_ARG; - - n = inbuflen / 8; - - /* We need at least two 64 bit blocks. */ - if (n < 2) - return GPG_ERR_INV_ARG; - - r = outbuf; - a = outbuf; /* We store A directly in OUTBUF. */ - b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */ - - /* If an IV has been set we use that IV as the Alternative Initial - Value; if it has not been set we use the standard value. */ - if (c->marks.iv) - memcpy (a, c->u_iv.iv, 8); - else - memset (a, 0xa6, 8); - - /* Copy the inbuf to the outbuf. */ - memmove (r+8, inbuf, inbuflen); - - memset (t, 0, sizeof t); /* t := 0. */ - - for (j = 0; j <= 5; j++) - { - for (i = 1; i <= n; i++) - { - /* B := AES_k( A | R[i] ) */ - memcpy (b, a, 8); - memcpy (b+8, r+i*8, 8); - c->cipher->encrypt (&c->context.c, b, b); - /* t := t + 1 */ - for (x = 7; x >= 0; x--) + for (i = c->cipher->blocksize; i > 0; i--) { - t[x]++; - if (t[x]) + c->ctr[i-1]++; + if (c->ctr[i-1] != 0) break; } - /* A := MSB_64(B) ^ t */ - for (x=0; x < 8; x++) - a[x] = b[x] ^ t[x]; - /* R[i] := LSB_64(B) */ - memcpy (r+i*8, b+8, 8); - } - } + } - return 0; + /* XOR input with encrypted counter and store in output. */ + outbuf[n] = inbuf[n] ^ tmp[n % c->cipher->blocksize]; + } } -/* Perform the AES-Unwrap algorithm as specified by RFC3394. We - implement this as a mode usable with any cipher algorithm of - blocksize 128. */ -static gcry_err_code_t -do_aeswrap_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen, - const byte *inbuf, unsigned int inbuflen) +static void +do_ctr_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, + unsigned int nbytes ) { - int j, x; - unsigned int n, i; - unsigned char *r, *a, *b; - unsigned char t[8]; - -#if MAX_BLOCKSIZE < 8 -#error Invalid block size -#endif - /* We require a cipher with a 128 bit block length. */ - if (c->cipher->blocksize != 16) - return GPG_ERR_INV_LENGTH; - - /* The output buffer must be able to hold the input data minus one - additional block. Fixme: The caller has more restrictive checks - - we may want to fix them for this mode. */ - if (outbuflen + 8 < inbuflen) - return GPG_ERR_BUFFER_TOO_SHORT; - /* Input data must be multiple of 64 bits. */ - if (inbuflen % 8) - return GPG_ERR_INV_ARG; - - n = inbuflen / 8; - - /* We need at least three 64 bit blocks. */ - if (n < 3) - return GPG_ERR_INV_ARG; - - r = outbuf; - a = c->lastiv; /* We use c->LASTIV as buffer for A. */ - b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */ - - /* Copy the inbuf to the outbuf and save A. */ - memcpy (a, inbuf, 8); - memmove (r, inbuf+8, inbuflen-8); - n--; /* Reduce to actual number of data blocks. */ - - /* t := 6 * n */ - i = n * 6; /* The range is valid because: n = inbuflen / 8 - 1. */ - for (x=0; x < 8 && x < sizeof (i); x++) - t[7-x] = i >> (8*x); - for (; x < 8; x++) - t[7-x] = 0; - - for (j = 5; j >= 0; j--) - { - for (i = n; i >= 1; i--) - { - /* B := AES_k^1( (A ^ t)| R[i] ) */ - for (x = 0; x < 8; x++) - b[x] = a[x] ^ t[x]; - memcpy (b+8, r+(i-1)*8, 8); - c->cipher->decrypt (&c->context.c, b, b); - /* t := t - 1 */ - for (x = 7; x >= 0; x--) - { - t[x]--; - if (t[x] != 0xff) - break; - } - /* A := MSB_64(B) */ - memcpy (a, b, 8); - /* R[i] := LSB_64(B) */ - memcpy (r+(i-1)*8, b+8, 8); - } - } - - /* If an IV has been set we compare against this Alternative Initial - Value; if it has not been set we compare against the standard IV. */ - if (c->marks.iv) - j = memcmp (a, c->u_iv.iv, 8); - else - { - for (j=0, x=0; x < 8; x++) - if (a[x] != 0xa6) - { - j=1; - break; - } - } - return j? GPG_ERR_CHECKSUM : 0; + 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 constraints apply to INBUFLEN. + * Depending on the mode some contraints apply to NBYTES. */ static gcry_err_code_t -cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen, - const byte *inbuf, unsigned int inbuflen) +cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, + const byte *inbuf, unsigned int nbytes) { - gcry_err_code_t rc; + gcry_err_code_t rc = GPG_ERR_NO_ERROR; - switch (c->mode) - { - case GCRY_CIPHER_MODE_ECB: - rc = do_ecb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); - break; - - case GCRY_CIPHER_MODE_CBC: - rc = do_cbc_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); - break; - - case GCRY_CIPHER_MODE_CFB: - rc = do_cfb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); - break; - - case GCRY_CIPHER_MODE_OFB: - rc = do_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); - break; - - case GCRY_CIPHER_MODE_CTR: - rc = do_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); - break; - - case GCRY_CIPHER_MODE_AESWRAP: - rc = do_aeswrap_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); - break; - - case GCRY_CIPHER_MODE_STREAM: - c->cipher->stencrypt (&c->context.c, - outbuf, (byte*)/*arggg*/inbuf, inbuflen); - rc = 0; - 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, inbuflen); - rc = 0; - } - break; - - default: - log_fatal ("cipher_encrypt: invalid mode %d\n", c->mode ); - rc = GPG_ERR_INV_CIPHER_MODE; - break; + 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; + return rc; } @@ -1766,15 +1461,29 @@ gcry_cipher_encrypt (gcry_cipher_hd_t h, void *out, size_t outsize, { gcry_err_code_t err; - if (!in) /* Caller requested in-place encryption. */ - err = cipher_encrypt (h, out, outsize, out, outsize); + 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, outsize, in, inlen); + err = cipher_encrypt (h, out, in, inlen); - /* Failsafe: Make sure that the plaintext will never make it into - OUT if the encryption returned an error. */ if (err && out) - memset (out, 0x42, outsize); + memset (out, 0x42, outsize); /* Failsafe: Make sure that the + plaintext will never make it into + OUT. */ return gcry_error (err); } @@ -1784,67 +1493,60 @@ gcry_cipher_encrypt (gcry_cipher_hd_t h, void *out, size_t outsize, /**************** * 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 INBUFLEN. + * Depending on the mode some some contraints apply to NBYTES. */ static gcry_err_code_t -cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen, - const byte *inbuf, unsigned int inbuflen) +cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, + unsigned int nbytes) { - gcry_err_code_t rc; + gcry_err_code_t rc = GPG_ERR_NO_ERROR; - switch (c->mode) - { - case GCRY_CIPHER_MODE_ECB: - rc = do_ecb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); - break; - - case GCRY_CIPHER_MODE_CBC: - rc = do_cbc_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); - break; - - case GCRY_CIPHER_MODE_CFB: - rc = do_cfb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); - break; - - case GCRY_CIPHER_MODE_OFB: - rc = do_ofb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); - break; - - case GCRY_CIPHER_MODE_CTR: - rc = do_ctr_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); - break; - - case GCRY_CIPHER_MODE_AESWRAP: - rc = do_aeswrap_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); - break; - - case GCRY_CIPHER_MODE_STREAM: - c->cipher->stdecrypt (&c->context.c, - outbuf, (byte*)/*arggg*/inbuf, inbuflen); - rc = 0; - 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, inbuflen); - rc = 0; - } - break; - - default: - log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode ); - rc = GPG_ERR_INV_CIPHER_MODE; - break; + 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; + return rc; } @@ -1852,12 +1554,25 @@ 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; + gcry_err_code_t err = 0; - if (!in) /* Caller requested in-place encryption. */ - err = cipher_decrypt (h, out, outsize, out, outsize); + 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, outsize, in, inlen); + err = cipher_decrypt (h, out, in, inlen); return gcry_error (err); } @@ -1903,15 +1618,9 @@ 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->u_ctr.ctr, ctr, hd->cipher->blocksize); - hd->unused = 0; - } + memcpy (hd->ctr, ctr, hd->cipher->blocksize); else if (!ctr || !ctrlen) - { - memset (hd->u_ctr.ctr, 0, hd->cipher->blocksize); - hd->unused = 0; - } + memset (hd->ctr, 0, hd->cipher->blocksize); else return gpg_error (GPG_ERR_INV_ARG); return 0; @@ -1970,12 +1679,17 @@ gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen) break; case GCRYCTL_SET_CTR: /* Deprecated; use gcry_cipher_setctr. */ - rc = gpg_err_code (_gcry_cipher_setctr (h, buffer, buflen)); + 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 + rc = h->extraspec->set_extra_info (&h->context.c, CIPHER_INFO_NO_WEAK_KEY, NULL, 0); else rc = GPG_ERR_NOT_SUPPORTED; @@ -1983,7 +1697,7 @@ gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen) 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: + 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. */ @@ -1994,7 +1708,7 @@ gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen) unsigned char *ivp; unsigned char *dst = buffer; int n = h->unused; - + if (!n) n = h->cipher->blocksize; gcry_assert (n <= h->cipher->blocksize); @@ -2016,10 +1730,10 @@ gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen) /* 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 function always returns GPG_ERR_INV_OP. + 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) @@ -2056,11 +1770,11 @@ gcry_cipher_info (gcry_cipher_hd_t h, int cmd, void *buffer, size_t *nbytes) 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 occurred or not (i.e. while + and thereby detecting whether a error occured or not (i.e. while checking the block size) */ gcry_error_t @@ -2080,7 +1794,8 @@ gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes) if ((ui > 0) && (ui <= 512)) *nbytes = (size_t) ui / 8; else - /* The only reason for an error is an invalid algo. */ + /* The only reason is an invalid algo or a strange + blocksize. */ err = GPG_ERR_CIPHER_ALGO; } break; @@ -2124,7 +1839,7 @@ gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes) gcry_cipher_algo_info because it allows for proper type checking. */ size_t -gcry_cipher_get_algo_keylen (int algo) +gcry_cipher_get_algo_keylen (int algo) { size_t n; @@ -2140,7 +1855,7 @@ gcry_cipher_get_algo_keylen (int algo) gcry_cipher_algo_info because it allows for proper type checking. */ size_t -gcry_cipher_get_algo_blklen (int algo) +gcry_cipher_get_algo_blklen (int algo) { size_t n; @@ -2201,7 +1916,7 @@ _gcry_cipher_selftest (int algo, int extended, selftest_report_func_t report) { ec = GPG_ERR_CIPHER_ALGO; if (report) - report ("cipher", algo, "module", + report ("cipher", algo, "module", module && !(module->flags & FLAG_MODULE_DISABLED)? "no selftest available" : module? "algorithm disabled" : "algorithm not found"); diff --git a/lib/libgcrypt/cipher/crc.c b/lib/libgcrypt/cipher/crc.c new file mode 100644 index 000000000..d04fff894 --- /dev/null +++ b/lib/libgcrypt/cipher/crc.c @@ -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 +#include +#include +#include + +#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/lib/libgcrypt/cipher/des.c similarity index 99% rename from grub-core/lib/libgcrypt/cipher/des.c rename to lib/libgcrypt/cipher/des.c index 96b06ae36..f91df7771 100644 --- a/grub-core/lib/libgcrypt/cipher/des.c +++ b/lib/libgcrypt/cipher/des.c @@ -22,7 +22,7 @@ * 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. + * PUB 46-2 from December 1993. */ @@ -106,7 +106,7 @@ * * if ( (error_msg = selftest()) ) * { - * fprintf(stderr, "An error in the DES/Triple-DES implementation occurred: %s\n", error_msg); + * fprintf(stderr, "An error in the DES/Tripple-DES implementation occured: %s\n", error_msg); * abort(); * } */ @@ -388,7 +388,7 @@ static byte weak_keys[64][8] = }; 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 + 0x8A, 0x36, 0x65, 0x29, 0x6C, 0x1F, 0x7C, 0x3F, 0xD3, 0x41 }; @@ -888,12 +888,12 @@ selftest (void) 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, @@ -901,7 +901,7 @@ selftest (void) { 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 }, @@ -966,7 +966,7 @@ selftest (void) { 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."; @@ -1047,7 +1047,7 @@ do_tripledes_set_extra_info (void *context, int what, break; default: - ec = GPG_ERR_INV_OP; + ec = GPG_ERR_INV_OP; break; } return ec; @@ -1112,7 +1112,7 @@ do_des_decrypt( void *context, byte *outbuf, const byte *inbuf ) -/* +/* Self-test section. */ @@ -1123,7 +1123,7 @@ selftest_fips (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; - + (void)extended; /* No extended tests available. */ what = "low-level"; @@ -1160,7 +1160,7 @@ run_selftests (int algo, int extended, selftest_report_func_t report) default: ec = GPG_ERR_CIPHER_ALGO; break; - + } return ec; } @@ -1189,7 +1189,7 @@ gcry_cipher_spec_t _gcry_cipher_spec_tripledes = do_tripledes_setkey, do_tripledes_encrypt, do_tripledes_decrypt }; -cipher_extra_spec_t _gcry_cipher_extraspec_tripledes = +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/lib/libgcrypt/cipher/dsa.c similarity index 94% rename from grub-core/lib/libgcrypt/cipher/dsa.c rename to lib/libgcrypt/cipher/dsa.c index 883a815f2..100710f97 100644 --- a/grub-core/lib/libgcrypt/cipher/dsa.c +++ b/lib/libgcrypt/cipher/dsa.c @@ -74,7 +74,7 @@ static const char sample_secret_key[] = " 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)" " (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))"; /* A sample 1024 bit DSA key used for the selftests (public only). */ -static const char sample_public_key[] = +static const char sample_public_key[] = "(public-key" " (dsa" " (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" @@ -141,19 +141,14 @@ gen_k( gcry_mpi_t q ) unsigned int nbytes = (nbits+7)/8; char *rndbuf = NULL; - /* To learn why we don't use mpi_mod to get the requested bit size, - read the paper: "The Insecurity of the Digital Signature - Algorithm with Partially Known Nonces" by Nguyen and Shparlinski. - Journal of Cryptology, New York. Vol 15, nr 3 (2003) */ - if ( DBG_CIPHER ) log_debug("choosing a random k "); - for (;;) + for (;;) { if( DBG_CIPHER ) progress('.'); - if ( !rndbuf || nbits < 32 ) + if ( !rndbuf || nbits < 32 ) { gcry_free(rndbuf); rndbuf = gcry_random_bytes_secure( (nbits+7)/8, GCRY_STRONG_RANDOM ); @@ -161,20 +156,13 @@ gen_k( gcry_mpi_t q ) 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 these extra bytes here. - However the required management code is more complex and - thus we better use this simple method. */ + 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 ); - - /* Make sure we have the requested number of bits. This code - looks a bit funny but it is easy to understand if you - consider that mpi_set_highbit clears all higher bits. We - don't have a clear_highbit, thus we first set the high bit - and then clear it again. */ if ( mpi_test_bit( k, nbits-1 ) ) mpi_set_highbit( k, nbits-1 ); else @@ -184,7 +172,7 @@ gen_k( gcry_mpi_t q ) } if( !(mpi_cmp( k, q ) < 0) ) /* check: k < q */ - { + { if( DBG_CIPHER ) progress('+'); continue; /* no */ @@ -200,7 +188,7 @@ gen_k( gcry_mpi_t q ) gcry_free(rndbuf); if( DBG_CIPHER ) progress('\n'); - + return k; } @@ -327,7 +315,7 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, 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. */ } @@ -342,13 +330,13 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, x = mpi_alloc_secure( mpi_get_nlimbs(q) ); mpi_sub_ui( h, q, 1 ); /* put q-1 into h */ rndbuf = NULL; - do + do { if( DBG_CIPHER ) progress('.'); if( !rndbuf ) rndbuf = gcry_random_bytes_secure ((qbits+7)/8, random_level); - else + else { /* Change only some of the higher bits (= 2 bytes)*/ char *r = gcry_random_bytes_secure (2, random_level); memcpy(rndbuf, r, 2 ); @@ -357,7 +345,7 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, _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 ); @@ -367,7 +355,7 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, y = mpi_alloc( mpi_get_nlimbs(p) ); gcry_mpi_powm( y, g, x, p ); - if( DBG_CIPHER ) + if( DBG_CIPHER ) { progress('\n'); log_mpidump("dsa p", p ); @@ -418,8 +406,8 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, 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 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. */ @@ -479,15 +467,15 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, 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, + ec = _gcry_generate_fips186_2_prime (nbits, qbits, + initial_seed.seed, initial_seed.seedlen, - &prime_q, &prime_p, + &prime_q, &prime_p, r_counter, r_seed, r_seedlen); /* else */ @@ -505,33 +493,33 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, 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); + 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 + 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) + if (DBG_CIPHER) { progress('\n'); log_mpidump("dsa p", prime_p ); @@ -703,7 +691,7 @@ dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue, 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. */ @@ -712,7 +700,7 @@ dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue, if (genparms) { gcry_sexp_t domainsexp; - + /* Parse the optional qbits element. */ l1 = gcry_sexp_find_token (genparms, "qbits", 0); if (l1) @@ -720,7 +708,7 @@ dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue, char buf[50]; const char *s; size_t n; - + s = gcry_sexp_nth_data (l1, 1, &n); if (!s || n >= DIM (buf) - 1 ) { @@ -772,7 +760,7 @@ dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue, 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); @@ -816,7 +804,7 @@ dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue, { /* 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 + ec = gpg_err_code (gcry_sexp_build (&seedinfo, NULL, "(seed-values(counter %d)(seed %b)(h %m))", counter, (int)seedlen, seed, h_value)); @@ -891,7 +879,7 @@ dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue, 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. */ @@ -906,8 +894,8 @@ dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue, for (j=0; j < nfactors; j++) arg_list[i++] = (*retfactors) + j; arg_list[i] = NULL; - - ec = gpg_err_code (gcry_sexp_build_array + + ec = gpg_err_code (gcry_sexp_build_array (r_extrainfo, NULL, format, arg_list)); } } @@ -919,7 +907,6 @@ dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue, gcry_mpi_release ((*retfactors)[i]); (*retfactors)[i] = NULL; } - gcry_free (*retfactors); *retfactors = NULL; if (ec) { @@ -1035,19 +1022,19 @@ dsa_get_nbits (int algo, gcry_mpi_t *pkey) -/* +/* Self-test section. */ static const char * selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey) { - static const char sample_data[] = - "(data (flags raw)" - " (value #a0b1c2d3e4f500102030405060708090a1b2c3d4#))"; - static const char sample_data_bad[] = - "(data (flags raw)" - " (value #a0b1c2d3e4f510102030405060708090a1b2c3d4#))"; + 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; @@ -1058,7 +1045,7 @@ selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey) err = gcry_sexp_sscan (&data, NULL, sample_data, strlen (sample_data)); if (!err) - err = gcry_sexp_sscan (&data_bad, NULL, + err = gcry_sexp_sscan (&data_bad, NULL, sample_data_bad, strlen (sample_data_bad)); if (err) { @@ -1105,10 +1092,10 @@ selftests_dsa (selftest_report_func_t report) /* Convert the S-expressions into the internal representation. */ what = "convert"; - err = gcry_sexp_sscan (&skey, NULL, + err = gcry_sexp_sscan (&skey, NULL, sample_secret_key, strlen (sample_secret_key)); if (!err) - err = gcry_sexp_sscan (&pkey, NULL, + err = gcry_sexp_sscan (&pkey, NULL, sample_public_key, strlen (sample_public_key)); if (err) { @@ -1158,7 +1145,7 @@ run_selftests (int algo, int extended, selftest_report_func_t report) default: ec = GPG_ERR_PUBKEY_ALGO; break; - + } return ec; } @@ -1175,7 +1162,7 @@ static const char *dsa_names[] = gcry_pk_spec_t _gcry_pubkey_spec_dsa = { - "DSA", dsa_names, + "DSA", dsa_names, "pqgy", "pqgyx", "", "rs", "pqgy", GCRY_PK_USAGE_SIGN, dsa_generate, @@ -1186,8 +1173,9 @@ gcry_pk_spec_t _gcry_pubkey_spec_dsa = dsa_verify, dsa_get_nbits }; -pk_extra_spec_t _gcry_pubkey_extraspec_dsa = +pk_extra_spec_t _gcry_pubkey_extraspec_dsa = { run_selftests, dsa_generate_ext }; + diff --git a/grub-core/lib/libgcrypt/cipher/ecc.c b/lib/libgcrypt/cipher/ecc.c similarity index 73% rename from grub-core/lib/libgcrypt/cipher/ecc.c rename to lib/libgcrypt/cipher/ecc.c index b8487dc13..fcbd8e3a9 100644 --- a/grub-core/lib/libgcrypt/cipher/ecc.c +++ b/lib/libgcrypt/cipher/ecc.c @@ -1,18 +1,18 @@ /* ecc.c - Elliptic Curve Cryptography - Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc. + 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, @@ -33,21 +33,20 @@ 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. - - ECDH encrypt and decrypt code written by Andrey Jivsov, -*/ + been rewritten and moved to mpi/ec.c. */ /* TODO: - - If we support point compression we need to uncompress before - computing the keygrip + - 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. */ @@ -60,6 +59,7 @@ #include "mpi.h" #include "cipher.h" + /* Definition of a curve. */ typedef struct { @@ -68,8 +68,7 @@ typedef struct gcry_mpi_t b; /* Second coefficient of the Weierstrass equation. */ mpi_point_t G; /* Base point (generator). */ gcry_mpi_t n; /* Order of G. */ - const char *name; /* Name of curve or NULL. */ -} elliptic_curve_t; +} elliptic_curve_t; typedef struct @@ -91,7 +90,7 @@ static const struct { const char *name; /* Our name. */ const char *other; /* Other name. */ -} curve_aliases[] = +} curve_aliases[] = { { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID */ { "NIST P-192", "prime192v1" }, /* X9.62 name. */ @@ -101,11 +100,11 @@ static const struct { "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", "prime256v1" }, { "NIST P-256", "secp256r1" }, { "NIST P-384", "secp384r1" }, - { "NIST P-384", "1.3.132.0.34" }, + { "NIST P-384", "1.3.132.0.34" }, { "NIST P-521", "secp521r1" }, { "NIST P-521", "1.3.132.0.35" }, @@ -121,7 +120,11 @@ static const struct { NULL, NULL} }; -typedef struct { + + +/* 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. */ @@ -129,10 +132,7 @@ typedef struct { const char *a, *b; /* The coefficients. */ const char *n; /* The order of the base point. */ const char *g_x, *g_y; /* Base point. */ -} ecc_domain_parms_t; - -/* This static table defines all available curves. */ -static const ecc_domain_parms_t domain_parms[] = +} domain_parms[] = { { "NIST P-192", 192, 1, @@ -197,7 +197,7 @@ static const ecc_domain_parms_t domain_parms[] = "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" }, - { "brainpoolP160r1", 160, 0, + { "brainpoolP160r1", 160, 0, "0xe95e4a5f737059dc60dfc7ad95b3d8139515620f", "0x340e7be2a280eb74e2be61bada745d97e8f7c300", "0x1e589a8595423412134faa2dbdec95c8d8675e58", @@ -206,7 +206,7 @@ static const ecc_domain_parms_t domain_parms[] = "0x1667cb477a1a8ec338f94741669c976316da6321" }, - { "brainpoolP192r1", 192, 0, + { "brainpoolP192r1", 192, 0, "0xc302f41d932a36cda7a3463093d18db78fce476de1a86297", "0x6a91174076b1e0e19c39c031fe8685c1cae040e5c69a28ef", "0x469a28ef7c28cca3dc721d044f4496bcca7ef4146fbf25c9", @@ -369,6 +369,7 @@ curve_copy (elliptic_curve_t E) } + /* Helper to scan a hex string. */ static gcry_mpi_t scanval (const char *string) @@ -399,10 +400,10 @@ gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base) 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_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); @@ -411,6 +412,9 @@ gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base) } + + + /* Generate a random secret scalar k with an order of p At the beginning this was identical to the code is in elgamal.c. @@ -424,8 +428,7 @@ gen_k (gcry_mpi_t p, int security_level) nbits = mpi_get_nbits (p); k = mpi_snew (nbits); if (DBG_CIPHER) - log_debug ("choosing a random k of %u bits at seclevel %d\n", - nbits, security_level); + log_debug ("choosing a random k of %u bits\n", nbits); gcry_mpi_randomize (k, nbits, security_level); @@ -434,27 +437,23 @@ gen_k (gcry_mpi_t p, int security_level) return k; } - -/* Generate the crypto system setup. This function takes the NAME of - a curve or the desired number of bits and stores at R_CURVE the - parameters of the named curve or those of a suitable curve. The - chosen number of bits is stored on R_NBITS. */ +/**************** + * 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 -fill_in_curve (unsigned int nbits, const char *name, - elliptic_curve_t *curve, unsigned int *r_nbits) +generate_curve (unsigned int nbits, const char *name, + elliptic_curve_t *curve, unsigned int *r_nbits) { int idx, aliasno; - const char *resname = NULL; /* Set to a found curve name. */ if (name) { - /* First check our native curves. */ + /* First check nor native curves. */ for (idx = 0; domain_parms[idx].desc; idx++) if (!strcmp (name, domain_parms[idx].desc)) - { - resname = domain_parms[idx].desc; - break; - } + break; /* If not found consult the alias table. */ if (!domain_parms[idx].desc) { @@ -466,10 +465,7 @@ fill_in_curve (unsigned int nbits, const char *name, for (idx = 0; domain_parms[idx].desc; idx++) if (!strcmp (curve_aliases[aliasno].name, domain_parms[idx].desc)) - { - resname = domain_parms[idx].desc; - break; - } + break; } } } @@ -486,7 +482,8 @@ fill_in_curve (unsigned int nbits, const char *name, possible to bypass this check by specifying the curve parameters directly. */ if (fips_mode () && !domain_parms[idx].fips ) - return GPG_ERR_NOT_SUPPORTED; + return GPG_ERR_NOT_SUPPORTED; + *r_nbits = domain_parms[idx].nbits; curve->p = scanval (domain_parms[idx].p); @@ -496,7 +493,6 @@ fill_in_curve (unsigned int nbits, const char *name, 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); - curve->name = resname; return 0; } @@ -508,39 +504,33 @@ fill_in_curve (unsigned int nbits, const char *name, */ static gpg_err_code_t generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name, - int transient_key, gcry_mpi_t g_x, gcry_mpi_t g_y, - gcry_mpi_t q_x, gcry_mpi_t q_y, - const char **r_usedcurve) + 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; - gcry_random_level_t random_level; - *r_usedcurve = NULL; - - err = fill_in_curve (nbits, name, &E, &nbits); + err = generate_curve (nbits, name, &E, &nbits); if (err) return err; if (DBG_CIPHER) { - log_mpidump ("ecgen curve p", E.p); - log_mpidump ("ecgen curve a", E.a); - log_mpidump ("ecgen curve b", E.b); - log_mpidump ("ecgen curve n", E.n); - log_mpidump ("ecgen curve Gx", E.G.x); - log_mpidump ("ecgen curve Gy", E.G.y); - log_mpidump ("ecgen curve Gz", E.G.z); - if (E.name) - log_debug ("ecgen curve used: %s\n", E.name); + 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); } - random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM; - d = gen_k (E.n, random_level); + 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); @@ -562,29 +552,27 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name, if (g_x && g_y) { if (_gcry_mpi_ec_get_affine (g_x, g_y, &sk->E.G, ctx)) - log_fatal ("ecgen: Failed to get affine coordinates\n"); + 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 ("ecgen: Failed to get affine coordinates\n"); + log_fatal ("ecc generate: Failed to get affine coordinates\n"); } _gcry_mpi_ec_free (ctx); point_free (&Q); mpi_free (d); - - *r_usedcurve = E.name; curve_free (&E); - /* Now we can test our keys (this should never fail!). */ + /* 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. @@ -634,56 +622,54 @@ test_keys (ECC_secret_key *sk, unsigned int nbits) 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) { - int rc = 1; mpi_point_t Q; - gcry_mpi_t y_2, y2; - mpi_ec_t ctx = NULL; - - point_init (&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 */ - y2 = mpi_alloc (0); 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"); - goto leave; + 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"); - goto leave; + 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"); - goto leave; + 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"); - goto leave; + _gcry_mpi_ec_free (ctx); + return (1); } /* pubkey = [d]G over E */ _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx); @@ -692,16 +678,12 @@ check_secret_key (ECC_secret_key * sk) if (DBG_CIPHER) log_debug ("Bad check: There is NO correspondence between 'd' and 'Q'!\n"); - goto leave; + _gcry_mpi_ec_free (ctx); + return (1); } - rc = 0; /* Okay. */ - - leave: _gcry_mpi_ec_free (ctx); - mpi_free (y2); - mpi_free (y_2); point_free (&Q); - return rc; + return 0; } @@ -717,9 +699,6 @@ sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s) mpi_point_t I; mpi_ec_t ctx; - if (DBG_CIPHER) - log_mpidump ("ecdsa sign hash ", input ); - k = NULL; dr = mpi_alloc (0); sum = mpi_alloc (0); @@ -742,7 +721,7 @@ sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t 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); + _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx); if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx)) { if (DBG_CIPHER) @@ -758,12 +737,6 @@ sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s) mpi_mulm (s, k_1, sum, skey->E.n); /* s = k^(-1)*(hash+(d*r)) mod n */ } - if (DBG_CIPHER) - { - log_mpidump ("ecdsa sign result r ", r); - log_mpidump ("ecdsa sign result s ", s); - } - leave: _gcry_mpi_ec_free (ctx); point_free (&I); @@ -776,7 +749,6 @@ sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s) return err; } - /* * Check if R and S verifies INPUT. */ @@ -848,10 +820,10 @@ verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s) { if (DBG_CIPHER) { - log_mpidump (" x", x); - log_mpidump (" y", y); - log_mpidump (" r", r); - log_mpidump (" s", s); + 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; @@ -874,7 +846,7 @@ verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s) } - + /********************************************* ************** interface ****************** *********************************************/ @@ -907,16 +879,18 @@ ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p) 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 @@ -935,7 +909,7 @@ os2ec (mpi_point_t *result, gcry_mpi_t value) gcry_free (buf); return err; } - if (n < 1) + if (n < 1) { gcry_free (buf); return GPG_ERR_INV_OBJ; @@ -945,7 +919,7 @@ os2ec (mpi_point_t *result, gcry_mpi_t value) gcry_free (buf); return GPG_ERR_NOT_IMPLEMENTED; /* No support for point compression. */ } - if ( ((n-1)%2) ) + if ( ((n-1)%2) ) { gcry_free (buf); return GPG_ERR_INV_OBJ; @@ -971,7 +945,7 @@ os2ec (mpi_point_t *result, gcry_mpi_t value) mpi_free (x); mpi_free (y); - + return 0; } @@ -988,11 +962,10 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue, gcry_mpi_t g_x, g_y, q_x, q_y; char *curve_name = NULL; gcry_sexp_t l1; - int transient_key = 0; - const char *usedcurve = NULL; (void)algo; (void)evalue; + (void)r_extrainfo; if (genparms) { @@ -1005,14 +978,6 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue, if (!curve_name) return GPG_ERR_INV_OBJ; /* No curve name or value too large. */ } - - /* Parse the optional transient-key flag. */ - l1 = gcry_sexp_find_token (genparms, "transient-key", 0); - if (l1) - { - transient_key = 1; - gcry_sexp_release (l1); - } } /* NBITS is required if no curve name has been given. */ @@ -1023,45 +988,28 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue, g_y = mpi_new (0); q_x = mpi_new (0); q_y = mpi_new (0); - ec = generate_key (&sk, nbits, curve_name, transient_key, g_x, g_y, q_x, q_y, - &usedcurve); + ec = generate_key (&sk, nbits, curve_name, g_x, g_y, q_x, q_y); gcry_free (curve_name); if (ec) return ec; - if (usedcurve) /* Fixme: No error return checking. */ - gcry_sexp_build (r_extrainfo, NULL, "(curve %s)", usedcurve); 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; - mpi_free (g_x); - mpi_free (g_y); - mpi_free (q_x); - mpi_free (q_y); - 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 (); /* Fixme: relase mem? */ - - if (DBG_CIPHER) - { - log_mpidump ("ecgen result p", skey[0]); - log_mpidump ("ecgen result a", skey[1]); - log_mpidump ("ecgen result b", skey[2]); - log_mpidump ("ecgen result G", skey[3]); - log_mpidump ("ecgen result n", skey[4]); - log_mpidump ("ecgen result Q", skey[5]); - log_mpidump ("ecgen result d", skey[6]); - } + return gpg_err_code_from_syserror (); return 0; } @@ -1076,7 +1024,7 @@ ecc_generate (int algo, unsigned int nbits, unsigned long evalue, } -/* Return the parameters of the curve NAME in an MPI array. */ +/* Return the parameters of the curve NAME. */ static gcry_err_code_t ecc_get_param (const char *name, gcry_mpi_t *pkey) { @@ -1085,8 +1033,8 @@ ecc_get_param (const char *name, gcry_mpi_t *pkey) elliptic_curve_t E; mpi_ec_t ctx; gcry_mpi_t g_x, g_y; - - err = fill_in_curve (0, name, &E, &nbits); + + err = generate_curve (0, name, &E, &nbits); if (err) return err; @@ -1105,120 +1053,10 @@ ecc_get_param (const char *name, gcry_mpi_t *pkey) pkey[4] = E.n; pkey[5] = NULL; - mpi_free (g_x); - mpi_free (g_y); - return 0; } -/* Return the parameters of the curve NAME as an S-expression. */ -static gcry_sexp_t -ecc_get_param_sexp (const char *name) -{ - gcry_mpi_t pkey[6]; - gcry_sexp_t result; - int i; - - if (ecc_get_param (name, pkey)) - return NULL; - - if (gcry_sexp_build (&result, NULL, - "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))", - pkey[0], pkey[1], pkey[2], pkey[3], pkey[4])) - result = NULL; - - for (i=0; pkey[i]; i++) - gcry_mpi_release (pkey[i]); - - return result; -} - - -/* Return the name matching the parameters in PKEY. */ -static const char * -ecc_get_curve (gcry_mpi_t *pkey, int iterator, unsigned int *r_nbits) -{ - gpg_err_code_t err; - elliptic_curve_t E; - int idx; - gcry_mpi_t tmp; - const char *result = NULL; - - if (r_nbits) - *r_nbits = 0; - - if (!pkey) - { - idx = iterator; - if (idx >= 0 && idx < DIM (domain_parms)) - { - result = domain_parms[idx].desc; - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - } - return result; - } - - if (!pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4]) - return NULL; - - E.p = pkey[0]; - E.a = pkey[1]; - E.b = pkey[2]; - point_init (&E.G); - err = os2ec (&E.G, pkey[3]); - if (err) - { - point_free (&E.G); - return NULL; - } - E.n = pkey[4]; - - for (idx = 0; domain_parms[idx].desc; idx++) - { - tmp = scanval (domain_parms[idx].p); - if (!mpi_cmp (tmp, E.p)) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].a); - if (!mpi_cmp (tmp, E.a)) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].b); - if (!mpi_cmp (tmp, E.b)) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].n); - if (!mpi_cmp (tmp, E.n)) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_x); - if (!mpi_cmp (tmp, E.G.x)) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_y); - if (!mpi_cmp (tmp, E.G.y)) - { - result = domain_parms[idx].desc; - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - break; - } - } - } - } - } - } - mpi_free (tmp); - } - - point_free (&E.G); - - return result; -} - - static gcry_err_code_t ecc_check_secret_key (int algo, gcry_mpi_t *skey) { @@ -1227,9 +1065,8 @@ ecc_check_secret_key (int algo, gcry_mpi_t *skey) (void)algo; - /* FIXME: This check looks a bit fishy: Now long is the array? */ if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5] - || !skey[6]) + || !skey[6] || !skey[7] || !skey[8] || !skey[9] || !skey[10]) return GPG_ERR_BAD_MPI; sk.E.p = skey[0]; @@ -1313,7 +1150,6 @@ ecc_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey) 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) @@ -1357,221 +1193,6 @@ ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey, } -/* ecdh raw is classic 2-round DH protocol published in 1976. - * - * Overview of ecc_encrypt_raw and ecc_decrypt_raw. - * - * As with any PK operation, encrypt version uses a public key and - * decrypt -- private. - * - * Symbols used below: - * G - field generator point - * d - private long-term scalar - * dG - public long-term key - * k - ephemeral scalar - * kG - ephemeral public key - * dkG - shared secret - * - * ecc_encrypt_raw description: - * input: - * data[0] : private scalar (k) - * output: - * result[0] : shared point (kdG) - * result[1] : generated ephemeral public key (kG) - * - * ecc_decrypt_raw description: - * input: - * data[0] : a point kG (ephemeral public key) - * output: - * result[0] : shared point (kdG) - */ -static gcry_err_code_t -ecc_encrypt_raw (int algo, gcry_mpi_t *resarr, gcry_mpi_t k, - gcry_mpi_t *pkey, int flags) -{ - ECC_public_key pk; - mpi_ec_t ctx; - gcry_mpi_t result[2]; - int err; - - (void)algo; - (void)flags; - - if (!k - || !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; - } - - ctx = _gcry_mpi_ec_init (pk.E.p, pk.E.a); - - /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */ - { - mpi_point_t R; /* Result that we return. */ - gcry_mpi_t x, y; - - x = mpi_new (0); - y = mpi_new (0); - - point_init (&R); - - /* R = kQ <=> R = kdG */ - _gcry_mpi_ec_mul_point (&R, k, &pk.Q, ctx); - - if (_gcry_mpi_ec_get_affine (x, y, &R, ctx)) - log_fatal ("ecdh: Failed to get affine coordinates for kdG\n"); - - result[0] = ec2os (x, y, pk.E.p); - - /* R = kG */ - _gcry_mpi_ec_mul_point (&R, k, &pk.E.G, ctx); - - if (_gcry_mpi_ec_get_affine (x, y, &R, ctx)) - log_fatal ("ecdh: Failed to get affine coordinates for kG\n"); - - result[1] = ec2os (x, y, pk.E.p); - - mpi_free (x); - mpi_free (y); - - point_free (&R); - } - - _gcry_mpi_ec_free (ctx); - point_free (&pk.E.G); - point_free (&pk.Q); - - if (!result[0] || !result[1]) - { - mpi_free (result[0]); - mpi_free (result[1]); - return GPG_ERR_ENOMEM; - } - - /* Success. */ - resarr[0] = result[0]; - resarr[1] = result[1]; - - return 0; -} - -/* input: - * data[0] : a point kG (ephemeral public key) - * output: - * resaddr[0] : shared point kdG - * - * see ecc_encrypt_raw for details. - */ -static gcry_err_code_t -ecc_decrypt_raw (int algo, gcry_mpi_t *result, gcry_mpi_t *data, - gcry_mpi_t *skey, int flags) -{ - ECC_secret_key sk; - mpi_point_t R; /* Result that we return. */ - mpi_point_t kG; - mpi_ec_t ctx; - gcry_mpi_t r; - int err; - - (void)algo; - (void)flags; - - *result = NULL; - - if (!data || !data[0] - || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] - || !skey[5] || !skey[6] ) - return GPG_ERR_BAD_MPI; - - point_init (&kG); - err = os2ec (&kG, data[0]); - if (err) - { - point_free (&kG); - return err; - } - - - 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 (&kG); - 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 (&kG); - point_free (&sk.E.G); - point_free (&sk.Q); - return err; - } - sk.d = skey[6]; - - ctx = _gcry_mpi_ec_init (sk.E.p, sk.E.a); - - /* R = dkG */ - point_init (&R); - _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ctx); - - point_free (&kG); - - /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so: */ - { - gcry_mpi_t x, y; - - x = mpi_new (0); - y = mpi_new (0); - - if (_gcry_mpi_ec_get_affine (x, y, &R, ctx)) - log_fatal ("ecdh: Failed to get affine coordinates\n"); - - r = ec2os (x, y, sk.E.p); - mpi_free (x); - mpi_free (y); - } - - point_free (&R); - _gcry_mpi_ec_free (ctx); - point_free (&kG); - point_free (&sk.E.G); - point_free (&sk.Q); - - if (!r) - return GPG_ERR_ENOMEM; - - /* Success. */ - - *result = r; - - return 0; -} - static unsigned int ecc_get_nbits (int algo, gcry_mpi_t *pkey) @@ -1582,23 +1203,23 @@ ecc_get_nbits (int algo, gcry_mpi_t *pkey) } + /* 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) { -#define N_COMPONENTS 6 - static const char names[N_COMPONENTS+1] = "pabgnq"; + static const char names[] = "pabgnq"; gpg_err_code_t ec = 0; gcry_sexp_t l1; - gcry_mpi_t values[N_COMPONENTS]; + gcry_mpi_t values[6]; int idx; /* Clear the values for easier error cleanup. */ - for (idx=0; idx < N_COMPONENTS; idx++) + for (idx=0; idx < 6; idx++) values[idx] = NULL; - - /* Fill values with all provided parameters. */ - for (idx=0; idx < N_COMPONENTS; idx++) + + /* Fill values with all available parameters. */ + for (idx=0; idx < 6; idx++) { l1 = gcry_sexp_find_token (keyparam, names+idx, 1); if (l1) @@ -1612,20 +1233,19 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam) } } } - + /* 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[N_COMPONENTS]; - - for (idx = 0; idx < N_COMPONENTS; idx++) + gcry_mpi_t tmpvalues[6]; + + for (idx = 0; idx < 6; idx++) tmpvalues[idx] = NULL; curve = _gcry_sexp_nth_string (l1, 1); - gcry_sexp_release (l1); if (!curve) { ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */ @@ -1636,7 +1256,7 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam) if (ec) goto leave; - for (idx = 0; idx < N_COMPONENTS; idx++) + for (idx = 0; idx < 6; idx++) { if (!values[idx]) values[idx] = tmpvalues[idx]; @@ -1646,9 +1266,9 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam) } /* Check that all parameters are known and normalize all MPIs (that - should not be required but we use an internal function later and + 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 < N_COMPONENTS; idx++) + for (idx = 0; idx < 6; idx++) if (!values[idx]) { ec = GPG_ERR_NO_OBJ; @@ -1656,14 +1276,14 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam) } else _gcry_mpi_normalize (values[idx]); - + /* Hash them all. */ - for (idx = 0; idx < N_COMPONENTS; idx++) + 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) { @@ -1678,18 +1298,17 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam) } leave: - for (idx = 0; idx < N_COMPONENTS; idx++) + for (idx = 0; idx < 6; idx++) _gcry_mpi_release (values[idx]); - + return ec; -#undef N_COMPONENTS } -/* +/* Self-test section. */ @@ -1699,7 +1318,7 @@ selftests_ecdsa (selftest_report_func_t report) { const char *what; const char *errtxt; - + what = "low-level"; errtxt = NULL; /*selftest ();*/ if (errtxt) @@ -1732,7 +1351,7 @@ run_selftests (int algo, int extended, selftest_report_func_t report) default: ec = GPG_ERR_PUBKEY_ALGO; break; - + } return ec; } @@ -1746,12 +1365,6 @@ static const char *ecdsa_names[] = "ecc", NULL, }; -static const char *ecdh_names[] = - { - "ecdh", - "ecc", - NULL, - }; gcry_pk_spec_t _gcry_pubkey_spec_ecdsa = { @@ -1767,27 +1380,11 @@ gcry_pk_spec_t _gcry_pubkey_spec_ecdsa = ecc_get_nbits }; -gcry_pk_spec_t _gcry_pubkey_spec_ecdh = - { - "ECDH", ecdh_names, - "pabgnq", "pabgnqd", "se", "", "pabgnq", - GCRY_PK_USAGE_ENCR, - ecc_generate, - ecc_check_secret_key, - ecc_encrypt_raw, - ecc_decrypt_raw, - NULL, - NULL, - ecc_get_nbits - }; - - -pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa = +pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa = { run_selftests, ecc_generate_ext, compute_keygrip, - ecc_get_param, - ecc_get_curve, - ecc_get_param_sexp + ecc_get_param }; + diff --git a/grub-core/lib/libgcrypt/cipher/elgamal.c b/lib/libgcrypt/cipher/elgamal.c similarity index 98% rename from grub-core/lib/libgcrypt/cipher/elgamal.c rename to lib/libgcrypt/cipher/elgamal.c index ce4be8524..0b0c07cb4 100644 --- a/grub-core/lib/libgcrypt/cipher/elgamal.c +++ b/lib/libgcrypt/cipher/elgamal.c @@ -115,7 +115,7 @@ wiener_map( unsigned int n ) }; int i; - for(i=0; t[i].p_n; i++ ) + for(i=0; t[i].p_n; i++ ) { if( n <= t[i].p_n ) return t[i].q_n; @@ -158,7 +158,7 @@ test_keys ( ELG_secret_key *sk, unsigned int nbits, int nodie ) log_fatal ("Elgamal test key for %s %s failed\n", (failed & 1)? "encrypt+decrypt":"", (failed & 2)? "sign+verify":""); - if (failed && DBG_CIPHER) + if (failed && DBG_CIPHER) log_debug ("Elgamal test key for %s %s failed\n", (failed & 1)? "encrypt+decrypt":"", (failed & 2)? "sign+verify":""); @@ -199,15 +199,15 @@ gen_k( gcry_mpi_t p, int small_k ) if( DBG_CIPHER ) log_debug("choosing a random k "); mpi_sub_ui( p_1, p, 1); - for(;;) + for(;;) { - if( !rndbuf || nbits < 32 ) + 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 @@ -218,7 +218,7 @@ gen_k( gcry_mpi_t p, int small_k ) gcry_free(pp); } _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 ); - + for(;;) { if( !(mpi_cmp( k, p_1 ) < 0) ) /* check: k < (p-1) */ @@ -294,7 +294,7 @@ generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors ) if( DBG_CIPHER ) log_debug("choosing a random x of size %u", xbits ); rndbuf = NULL; - do + do { if( DBG_CIPHER ) progress('.'); @@ -314,21 +314,21 @@ generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors ) gcry_free(r); } } - else + 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 ) + if( DBG_CIPHER ) { progress('\n'); log_mpidump("elg p= ", p ); @@ -354,7 +354,7 @@ generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors ) 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 @@ -399,7 +399,7 @@ generate_using_x (ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t x, y = gcry_mpi_new (nbits); gcry_mpi_powm ( y, g, x, p ); - if ( DBG_CIPHER ) + if ( DBG_CIPHER ) { progress ('\n'); log_mpidump ("elg p= ", p ); @@ -493,7 +493,7 @@ decrypt(gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, ELG_secret_key *skey ) mpi_invm( t1, t1, skey->p ); mpi_mulm( output, b, t1, skey->p ); #if 0 - if( DBG_CIPHER ) + if( DBG_CIPHER ) { log_mpidump("elg decrypted x= ", skey->x); log_mpidump("elg decrypted p= ", skey->p); @@ -533,7 +533,7 @@ sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey ) mpi_mulm(b, t, inv, p_1 ); #if 0 - if( DBG_CIPHER ) + if( DBG_CIPHER ) { log_mpidump("elg sign p= ", skey->p); log_mpidump("elg sign g= ", skey->g); @@ -652,7 +652,7 @@ elg_generate_ext (int algo, unsigned int nbits, unsigned long evalue, skey[1] = sk.g; skey[2] = sk.y; skey[3] = sk.x; - + return ec; } @@ -671,7 +671,7 @@ elg_generate (int algo, unsigned int nbits, unsigned long evalue, skey[1] = sk.g; skey[2] = sk.y; skey[3] = sk.x; - + return GPG_ERR_NO_ERROR; } @@ -692,7 +692,7 @@ elg_check_secret_key (int algo, gcry_mpi_t *skey) sk.g = skey[1]; sk.y = skey[2]; sk.x = skey[3]; - + if (! check_secret_key (&sk)) err = GPG_ERR_BAD_SECKEY; } @@ -773,7 +773,7 @@ elg_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey) resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p)); sign (resarr[0], resarr[1], data, &sk); } - + return err; } @@ -837,9 +837,10 @@ gcry_pk_spec_t _gcry_pubkey_spec_elg = elg_get_nbits }; -pk_extra_spec_t _gcry_pubkey_extraspec_elg = +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/lib/libgcrypt/cipher/hash-common.c similarity index 97% rename from grub-core/lib/libgcrypt/cipher/hash-common.c rename to lib/libgcrypt/cipher/hash-common.c index 8c413bcba..656e180e2 100644 --- a/grub-core/lib/libgcrypt/cipher/hash-common.c +++ b/lib/libgcrypt/cipher/hash-common.c @@ -21,7 +21,7 @@ #include #include #include -#ifdef HAVE_STDINT_H +#ifdef HAVE_STDINT_H # include #endif @@ -35,10 +35,10 @@ 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, @@ -49,14 +49,14 @@ _gcry_hash_selftest_check_one (int algo, 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: @@ -64,7 +64,7 @@ _gcry_hash_selftest_check_one (int algo, break; case 1: /* Hash one million times an "a". */ - { + { char aaa[1000]; int i; @@ -82,7 +82,7 @@ _gcry_hash_selftest_check_one (int algo, if (!result) { digest = _gcry_md_read (hd, algo); - + if ( memcmp (digest, expect, expectlen) ) result = "digest mismatch"; } @@ -91,3 +91,4 @@ _gcry_hash_selftest_check_one (int algo, return result; } + diff --git a/grub-core/lib/libgcrypt/cipher/hash-common.h b/lib/libgcrypt/cipher/hash-common.h similarity index 93% rename from grub-core/lib/libgcrypt/cipher/hash-common.h rename to lib/libgcrypt/cipher/hash-common.h index fdebef42a..9c4e33359 100644 --- a/grub-core/lib/libgcrypt/cipher/hash-common.h +++ b/lib/libgcrypt/cipher/hash-common.h @@ -21,11 +21,11 @@ #define GCRY_HASH_COMMON_H -const char * _gcry_hash_selftest_check_one -/**/ (int algo, +const char * _gcry_hash_selftest_check_one +/**/ (int algo, int datamode, const void *data, size_t datalen, const void *expect, size_t expectlen); - + diff --git a/grub-core/lib/libgcrypt/cipher/hmac-tests.c b/lib/libgcrypt/cipher/hmac-tests.c similarity index 98% rename from grub-core/lib/libgcrypt/cipher/hmac-tests.c rename to lib/libgcrypt/cipher/hmac-tests.c index a32ece75d..56c9b203c 100644 --- a/grub-core/lib/libgcrypt/cipher/hmac-tests.c +++ b/lib/libgcrypt/cipher/hmac-tests.c @@ -17,7 +17,7 @@ * License along with this program; if not, see . */ -/* +/* 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 @@ -33,7 +33,7 @@ #include #include #include -#ifdef HAVE_STDINT_H +#ifdef HAVE_STDINT_H # include #endif @@ -47,7 +47,7 @@ succdess or a string describing the failure. */ static const char * check_one (int algo, - const void *data, size_t datalen, + const void *data, size_t datalen, const void *key, size_t keylen, const void *expect, size_t expectlen) { @@ -88,7 +88,7 @@ check_one (int algo, return "does not match"; } _gcry_md_close (hd); - return NULL; + return NULL; } @@ -123,7 +123,7 @@ selftests_sha1 (int extended, selftest_report_func_t report) "\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++; @@ -134,7 +134,7 @@ selftests_sha1 (int extended, selftest_report_func_t report) "\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++; @@ -160,7 +160,7 @@ selftests_sha1 (int extended, selftest_report_func_t report) static gpg_err_code_t selftests_sha224 (int extended, selftest_report_func_t report) { - static struct + static struct { const char * const desc; const char * const data; @@ -169,7 +169,7 @@ selftests_sha224 (int extended, selftest_report_func_t report) } tv[] = { { "data-28 key-4", - "what do ya want for nothing?", + "what do ya want for nothing?", "Jefe", { 0xa3, 0x0e, 0x01, 0x09, 0x8b, 0xc6, 0xdb, 0xbf, 0x45, 0x69, 0x0f, 0x3a, 0x7e, 0x9e, 0x6d, 0x0f, @@ -248,7 +248,7 @@ selftests_sha224 (int extended, selftest_report_func_t report) const char *what; const char *errtxt; int tvidx; - + for (tvidx=0; tv[tvidx].desc; tvidx++) { what = tv[tvidx].desc; @@ -274,7 +274,7 @@ selftests_sha224 (int extended, selftest_report_func_t report) static gpg_err_code_t selftests_sha256 (int extended, selftest_report_func_t report) { - static struct + static struct { const char * const desc; const char * const data; @@ -283,7 +283,7 @@ selftests_sha256 (int extended, selftest_report_func_t report) } tv[] = { { "data-28 key-4", - "what do ya want for nothing?", + "what do ya want for nothing?", "Jefe", { 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, @@ -362,7 +362,7 @@ selftests_sha256 (int extended, selftest_report_func_t report) const char *what; const char *errtxt; int tvidx; - + for (tvidx=0; tv[tvidx].desc; tvidx++) { hmac256_context_t hmachd; @@ -416,7 +416,7 @@ selftests_sha256 (int extended, selftest_report_func_t report) static gpg_err_code_t selftests_sha384 (int extended, selftest_report_func_t report) { - static struct + static struct { const char * const desc; const char * const data; @@ -425,7 +425,7 @@ selftests_sha384 (int extended, selftest_report_func_t report) } tv[] = { { "data-28 key-4", - "what do ya want for nothing?", + "what do ya want for nothing?", "Jefe", { 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31, 0x61, 0x7f, 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b, @@ -516,7 +516,7 @@ selftests_sha384 (int extended, selftest_report_func_t report) const char *what; const char *errtxt; int tvidx; - + for (tvidx=0; tv[tvidx].desc; tvidx++) { what = tv[tvidx].desc; @@ -542,7 +542,7 @@ selftests_sha384 (int extended, selftest_report_func_t report) static gpg_err_code_t selftests_sha512 (int extended, selftest_report_func_t report) { - static struct + static struct { const char * const desc; const char * const data; @@ -551,7 +551,7 @@ selftests_sha512 (int extended, selftest_report_func_t report) } tv[] = { { "data-28 key-4", - "what do ya want for nothing?", + "what do ya want for nothing?", "Jefe", { 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2, 0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3, @@ -654,7 +654,7 @@ selftests_sha512 (int extended, selftest_report_func_t report) const char *what; const char *errtxt; int tvidx; - + for (tvidx=0; tv[tvidx].desc; tvidx++) { what = tv[tvidx].desc; diff --git a/grub-core/lib/libgcrypt/cipher/md.c b/lib/libgcrypt/cipher/md.c similarity index 96% rename from grub-core/lib/libgcrypt/cipher/md.c rename to lib/libgcrypt/cipher/md.c index c3b3a4f3a..5dfbbd95a 100644 --- a/grub-core/lib/libgcrypt/cipher/md.c +++ b/lib/libgcrypt/cipher/md.c @@ -43,15 +43,15 @@ static struct digest_table_entry gcry_md_spec_t *digest; md_extra_spec_t *extraspec; unsigned int algorithm; - int fips_allowed; + int fips_allowed; } digest_table[] = { -#if USE_CRC +#if USE_CRC /* We allow the CRC algorithms even in FIPS mode because they are actually no cryptographic primitives. */ - { &_gcry_digest_spec_crc32, + { &_gcry_digest_spec_crc32, &dummy_extra_spec, GCRY_MD_CRC32, 1 }, - { &_gcry_digest_spec_crc32_rfc1510, + { &_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 }, @@ -69,7 +69,7 @@ static struct digest_table_entry &dummy_extra_spec, GCRY_MD_RMD160 }, #endif #if USE_SHA1 - { &_gcry_digest_spec_sha1, + { &_gcry_digest_spec_sha1, &_gcry_digest_extraspec_sha1, GCRY_MD_SHA1, 1 }, #endif #if USE_SHA256 @@ -87,10 +87,6 @@ static struct digest_table_entry #if USE_TIGER { &_gcry_digest_spec_tiger, &dummy_extra_spec, GCRY_MD_TIGER }, - { &_gcry_digest_spec_tiger1, - &dummy_extra_spec, GCRY_MD_TIGER1 }, - { &_gcry_digest_spec_tiger2, - &dummy_extra_spec, GCRY_MD_TIGER2 }, #endif #if USE_WHIRLPOOL { &_gcry_digest_spec_whirlpool, @@ -105,7 +101,7 @@ 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 whether the default ciphers have already been +/* Flag to check wether the default ciphers have already been registered. */ static int default_digests_registered; @@ -177,7 +173,7 @@ md_register_default (void) { gcry_err_code_t err = 0; int i; - + for (i = 0; !err && digest_table[i].digest; i++) { if ( fips_mode ()) @@ -230,7 +226,7 @@ gcry_md_lookup_func_oid (void *spec, void *data) } /* Internal function. Lookup a digest entry by it's name. */ -static gcry_module_t +static gcry_module_t gcry_md_lookup_name (const char *name) { gcry_module_t digest; @@ -271,11 +267,11 @@ _gcry_md_register (gcry_md_spec_t *digest, ath_mutex_lock (&digests_registered_lock); err = _gcry_module_add (&digests_registered, 0, - (void *) digest, - (void *)(extraspec? extraspec : &dummy_extra_spec), + (void *) digest, + (void *)(extraspec? extraspec : &dummy_extra_spec), &mod); ath_mutex_unlock (&digests_registered_lock); - + if (! err) { *module = mod; @@ -296,7 +292,7 @@ gcry_md_unregister (gcry_module_t module) } -static int +static int search_oid (const char *oid, int *algorithm, gcry_md_oid_spec_t *oid_spec) { gcry_module_t module; @@ -567,7 +563,7 @@ md_enable (gcry_md_hd_t hd, int algorithm) else digest = (gcry_md_spec_t *) module->spec; - + if (!err && algorithm == GCRY_MD_MD5 && fips_mode ()) { _gcry_inactivate_fips_mode ("MD5 used"); @@ -578,7 +574,7 @@ md_enable (gcry_md_hd_t hd, int algorithm) err = GPG_ERR_DIGEST_ALGO; } } - + if (!err) { size_t size = (sizeof (*entry) @@ -635,7 +631,7 @@ md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd) GcryDigestEntry *ar, *br; gcry_md_hd_t bhd; size_t n; - + if (ahd->bufpos) md_write (ahd, NULL, 0); @@ -697,7 +693,7 @@ md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd) - 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); @@ -787,7 +783,7 @@ 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) @@ -838,8 +834,8 @@ md_final (gcry_md_hd_t a) if (err) _gcry_fatal_error (err, NULL); - md_write (om, - (a->ctx->macpads)+(a->ctx->macpads_Bsize), + md_write (om, + (a->ctx->macpads)+(a->ctx->macpads_Bsize), a->ctx->macpads_Bsize); md_write (om, p, dlen); md_final (om); @@ -860,7 +856,7 @@ prepare_macpads (gcry_md_hd_t hd, const unsigned char *key, size_t keylen) if (!algo) return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled. */ - if ( keylen > hd->ctx->macpads_Bsize ) + if ( keylen > hd->ctx->macpads_Bsize ) { helpkey = gcry_malloc_secure (md_digest_length (algo)); if (!helpkey) @@ -876,7 +872,7 @@ prepare_macpads (gcry_md_hd_t hd, const unsigned char *key, size_t keylen) 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++ ) + for (i=0; i < hd->ctx->macpads_Bsize; i++ ) { ipad[i] ^= 0x36; opad[i] ^= 0x5c; @@ -890,7 +886,7 @@ 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: @@ -952,13 +948,10 @@ md_read( gcry_md_hd_t a, int algo ) if (! algo) { - /* Return the first algorithm */ - if (r) - { - if (r->next) - log_debug ("more than one algorithm in md_read(0)\n"); - return r->digest->read (&r->context.c); - } + /* 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 { @@ -1142,7 +1135,7 @@ md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen) * 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 occurred or not (i.e. while checking + * and thereby detecting whether a error occured or not (i.e. while checking * the block size) */ gcry_error_t @@ -1167,7 +1160,7 @@ gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes) { const char unsigned *asn; size_t asnlen; - + asn = md_asn_oid (algo, &asnlen, NULL); if (buffer && (*nbytes >= asnlen)) { @@ -1202,7 +1195,7 @@ md_start_debug ( gcry_md_hd_t md, const char *suffix ) if (fips_mode ()) return; - + if ( md->ctx->debug ) { log_debug("Oops: md debug already started\n"); @@ -1232,7 +1225,6 @@ md_stop_debug( gcry_md_hd_t md ) volatile u64 b = 42; volatile u64 c; c = a * b; - (void)c; } #endif } @@ -1269,7 +1261,7 @@ gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes) else { algo = *(int*)buffer; - + *nbytes = 0; for(r=h->ctx->list; r; r = r->next ) { if (r->module->mod_id == algo) @@ -1303,7 +1295,7 @@ _gcry_md_init (void) int -gcry_md_is_secure (gcry_md_hd_t a) +gcry_md_is_secure (gcry_md_hd_t a) { size_t value; @@ -1315,7 +1307,7 @@ gcry_md_is_secure (gcry_md_hd_t a) int -gcry_md_is_enabled (gcry_md_hd_t a, int algo) +gcry_md_is_enabled (gcry_md_hd_t a, int algo) { size_t value; @@ -1367,7 +1359,7 @@ _gcry_md_selftest (int algo, int extended, selftest_report_func_t report) { ec = GPG_ERR_DIGEST_ALGO; if (report) - report ("digest", algo, "module", + report ("digest", algo, "module", module && !(module->flags & FLAG_MODULE_DISABLED)? "no selftest available" : module? "algorithm disabled" : "algorithm not found"); diff --git a/grub-core/lib/libgcrypt/cipher/md4.c b/lib/libgcrypt/cipher/md4.c similarity index 98% rename from grub-core/lib/libgcrypt/cipher/md4.c rename to lib/libgcrypt/cipher/md4.c index 22fbf8d90..680cf87f5 100644 --- a/grub-core/lib/libgcrypt/cipher/md4.c +++ b/lib/libgcrypt/cipher/md4.c @@ -53,6 +53,7 @@ #include #include "g10lib.h" +#include "memory.h" #include "cipher.h" #include "bithelp.h" @@ -100,8 +101,7 @@ transform ( MD4_CONTEXT *ctx, const unsigned char *data ) #ifdef WORDS_BIGENDIAN { int i; - byte *p2; - const byte *p1; + byte *p2, *p1; for(i=0, p1=data, p2=(byte*)in; i < 16; i++, p2 += 4 ) { p2[3] = *p1++; @@ -198,7 +198,7 @@ md4_write ( void *context, const void *inbuf_arg, size_t inlen) 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; @@ -259,15 +259,15 @@ md4_final( void *context ) 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 */ - { + else /* need one extra block */ + { hd->buf[hd->count++] = 0x80; /* pad character */ while( hd->count < 64 ) hd->buf[hd->count++] = 0; @@ -325,3 +325,4 @@ gcry_md_spec_t _gcry_digest_spec_md4 = md4_init, md4_write, md4_final, md4_read, sizeof (MD4_CONTEXT) }; + diff --git a/grub-core/lib/libgcrypt/cipher/md5.c b/lib/libgcrypt/cipher/md5.c similarity index 97% rename from grub-core/lib/libgcrypt/cipher/md5.c rename to lib/libgcrypt/cipher/md5.c index a98678a9b..899dce89a 100644 --- a/grub-core/lib/libgcrypt/cipher/md5.c +++ b/lib/libgcrypt/cipher/md5.c @@ -20,8 +20,8 @@ * * 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 , 1995. - * heavily modified for GnuPG by Werner Koch + * Written by Ulrich Drepper , 1995. + * heavily modified for GnuPG by Werner Koch */ /* Test values: @@ -37,6 +37,7 @@ #include #include "g10lib.h" +#include "memory.h" #include "cipher.h" #include "bithelp.h" @@ -87,12 +88,11 @@ transform ( MD5_CONTEXT *ctx, const unsigned char *data ) register u32 C = ctx->C; register u32 D = ctx->D; u32 *cwp = correct_words; - + #ifdef WORDS_BIGENDIAN - { + { int i; - byte *p2; - const byte *p1; + byte *p2, *p1; for(i=0, p1=data, p2=(byte*)correct_words; i < 16; i++, p2 += 4 ) { p2[3] = *p1++; @@ -221,7 +221,7 @@ 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 ); @@ -242,7 +242,7 @@ md5_write( void *context, const void *inbuf_arg , size_t inlen) } _gcry_burn_stack (80+6*sizeof(void*)); - while( inlen >= 64 ) + while( inlen >= 64 ) { transform( hd, inbuf ); hd->count = 0; @@ -269,7 +269,7 @@ md5_final( void *context) MD5_CONTEXT *hd = context; u32 t, msb, lsb; byte *p; - + md5_write(hd, NULL, 0); /* flush */; t = hd->nblocks; diff --git a/grub-core/lib/libgcrypt/cipher/primegen.c b/lib/libgcrypt/cipher/primegen.c similarity index 96% rename from grub-core/lib/libgcrypt/cipher/primegen.c rename to lib/libgcrypt/cipher/primegen.c index b12e79b19..b869bee83 100644 --- a/grub-core/lib/libgcrypt/cipher/primegen.c +++ b/lib/libgcrypt/cipher/primegen.c @@ -31,7 +31,7 @@ #include "cipher.h" #include "ath.h" -static gcry_mpi_t gen_prime (unsigned int nbits, int secret, int randomlevel, +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, @@ -132,7 +132,7 @@ static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1; /* 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 { struct primepool_s *next; gcry_mpi_t prime; /* If this is NULL the entry is not used. */ @@ -163,7 +163,7 @@ save_pool_prime (gcry_mpi_t prime, gcry_random_level_t randomlevel) /* 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) @@ -182,7 +182,7 @@ save_pool_prime (gcry_mpi_t prime, gcry_random_level_t randomlevel) { /* Out of memory. Silently giving up. */ gcry_mpi_release (prime); - return; + return; } item->next = primepool; primepool = item; @@ -359,7 +359,7 @@ prime_generate_internal (int need_q_factor, 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); @@ -373,7 +373,7 @@ prime_generate_internal (int need_q_factor, /* 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) @@ -383,7 +383,7 @@ prime_generate_internal (int need_q_factor, } /* Allocate an array to track pool usage. */ - pool_in_use = gcry_calloc (n, sizeof *pool_in_use); + pool_in_use = gcry_malloc (n * sizeof *pool_in_use); if (!pool_in_use) { err = gpg_err_code_from_errno (errno); @@ -391,10 +391,10 @@ prime_generate_internal (int need_q_factor, } 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. - + 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; @@ -443,7 +443,7 @@ prime_generate_internal (int need_q_factor, is_locked = 1; for (i = 0; i < n; i++) { - perms[i] = 1; + 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 @@ -523,12 +523,12 @@ prime_generate_internal (int need_q_factor, gcry_free (perms); perms = NULL; progress ('!'); - goto next_try; + goto next_try; } } /* Generate next prime candidate: - p = 2 * q [ * q_factor] * factor_0 * factor_1 * ... * factor_n + 1. + p = 2 * q [ * q_factor] * factor_0 * factor_1 * ... * factor_n + 1. */ mpi_set (prime, q); mpi_mul_ui (prime, prime, 2); @@ -553,7 +553,7 @@ prime_generate_internal (int need_q_factor, } else count1 = 0; - + if (nprime > pbits) { if (++count2 > 20) @@ -624,14 +624,14 @@ prime_generate_internal (int need_q_factor, 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 @@ -662,7 +662,7 @@ prime_generate_internal (int need_q_factor, } if (DBG_CIPHER) progress('\n'); - } + } while (i < n + 2); mpi_free (factors[n+1]); @@ -671,7 +671,7 @@ prime_generate_internal (int need_q_factor, mpi_free (pmin1); } } - + if (! DBG_CIPHER) progress ('\n'); @@ -738,19 +738,19 @@ 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; - - if (prime_generate_internal ((mode == 1), &prime, pbits, qbits, g, - ret_factors, GCRY_WEAK_RANDOM, 0, 0, - NULL, NULL)) - prime = NULL; /* (Should be NULL in the error case anyway.) */ + + 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, +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; @@ -758,14 +758,14 @@ gen_prime (unsigned int nbits, int secret, int randomlevel, 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_xcalloc( no_of_small_prime_numbers, sizeof *mods); + 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); @@ -777,10 +777,10 @@ gen_prime (unsigned int nbits, int secret, int randomlevel, 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 @@ -789,17 +789,17 @@ gen_prime (unsigned int nbits, int secret, int randomlevel, 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 ) + 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++ ) + for (i=0; (x = small_prime_numbers[i]); i++ ) { while ( mods[i] + step >= x ) mods[i] -= x; @@ -808,7 +808,7 @@ gen_prime (unsigned int nbits, int secret, int randomlevel, } if ( x ) continue; /* Found a multiple of an already known prime. */ - + mpi_add_ui( ptest, prime, step ); /* Do a fast Fermat test now. */ @@ -816,7 +816,7 @@ gen_prime (unsigned int nbits, int secret, int randomlevel, 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 )) { @@ -828,13 +828,13 @@ gen_prime (unsigned int nbits, int secret, int randomlevel, } 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); @@ -842,7 +842,7 @@ gen_prime (unsigned int nbits, int secret, int randomlevel, mpi_free(pminus1); mpi_free(prime); gcry_free(mods); - return ptest; + return ptest; } } } @@ -883,7 +883,7 @@ check_prime( gcry_mpi_t prime, gcry_mpi_t val_2, int rm_rounds, gcry_mpi_powm( result, val_2, pminus1, prime ); mpi_free( pminus1 ); if ( mpi_cmp_ui( result, 1 ) ) - { + { /* Is composite. */ mpi_free( result ); progress('.'); @@ -924,7 +924,7 @@ is_prime (gcry_mpi_t n, int steps, unsigned int *count) unsigned nbits = mpi_get_nbits( n ); if (steps < 5) /* Make sure that we do at least 5 rounds. */ - steps = 5; + steps = 5; mpi_sub_ui( nminus1, n, 1 ); @@ -988,7 +988,7 @@ is_prime (gcry_mpi_t n, int steps, unsigned int *count) /* 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 initialize the array with the first M + 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++) @@ -996,7 +996,7 @@ is_prime (gcry_mpi_t n, int steps, unsigned int *count) 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. */ @@ -1010,7 +1010,7 @@ m_out_of_n ( char *array, int m, int n ) /* Need to handle this simple case separately. */ if( m == 1 ) - { + { for (i=0; i < n; i++ ) { if ( array[i] ) @@ -1060,7 +1060,7 @@ m_out_of_n ( char *array, int m, int n ) else k1 = k2 + 1; } - else + else { /* M is even. */ if( !array[n-1] ) @@ -1069,7 +1069,7 @@ m_out_of_n ( char *array, int m, int n ) k2 = k1 + 1; goto leave; } - + if( !(j1 & 1) ) { k1 = n - j1; @@ -1080,7 +1080,7 @@ m_out_of_n ( char *array, int m, int n ) } scan: jp = n - j1 - 1; - for (i=1; i <= jp; i++ ) + for (i=1; i <= jp; i++ ) { i1 = jp + 2 - i; if( array[i1-1] ) @@ -1128,7 +1128,7 @@ gcry_prime_generate (gcry_mpi_t *prime, unsigned int prime_bits, if (!prime) return gpg_error (GPG_ERR_INV_ARG); - *prime = NULL; + *prime = NULL; if (flags & GCRY_PRIME_FLAG_SPECIAL_FACTOR) mode = 1; @@ -1156,7 +1156,7 @@ gcry_prime_generate (gcry_mpi_t *prime, unsigned int prime_bits, mpi_free (factors_generated[i]); gcry_free (factors_generated); } - err = GPG_ERR_GENERAL; + err = GPG_ERR_GENERAL; } } @@ -1170,7 +1170,7 @@ gcry_prime_generate (gcry_mpi_t *prime, unsigned int prime_bits, return gcry_error (err); } -/* Check whether the number X is prime. */ +/* Check wether the number X is prime. */ gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags) { @@ -1207,29 +1207,29 @@ gcry_prime_group_generator (gcry_mpi_t *r_g, if (!factors || !r_g || !prime) return gpg_error (GPG_ERR_INV_ARG); - *r_g = NULL; + *r_g = NULL; for (n=0; factors[n]; n++) ; if (n < 2) return gpg_error (GPG_ERR_INV_ARG); - /* Extra sanity check - usually disabled. */ + /* 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 + + 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:"); @@ -1238,7 +1238,7 @@ gcry_prime_group_generator (gcry_mpi_t *r_g, } else progress('^'); - + for (i = 0; i < n; i++) { mpi_fdiv_q (tmp, pmin1, factors[i]); @@ -1250,13 +1250,13 @@ gcry_prime_group_generator (gcry_mpi_t *r_g, progress('\n'); } while (i < n); - + gcry_mpi_release (tmp); - gcry_mpi_release (b); - gcry_mpi_release (pmin1); - *r_g = g; + gcry_mpi_release (b); + gcry_mpi_release (pmin1); + *r_g = g; - return 0; + return 0; } /* Convenience function to release the factors array. */ @@ -1266,7 +1266,7 @@ 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); @@ -1279,11 +1279,11 @@ gcry_prime_release_factors (gcry_mpi_t *factors) 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 val_2 = mpi_alloc_set_ui (2); gcry_mpi_t prime; - + prime = gcry_mpi_copy (pfirst); - /* If P is even add 1. */ + /* If P is even add 1. */ mpi_set_bit (prime, 0); /* We use 64 Rabin-Miller rounds which is better and thus @@ -1299,7 +1299,7 @@ find_x931_prime (const gcry_mpi_t pfirst) } -/* Generate a prime using the algorithm from X9.31 appendix B.4. +/* 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. @@ -1308,7 +1308,7 @@ find_x931_prime (const gcry_mpi_t pfirst) 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, +_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) @@ -1327,20 +1327,20 @@ _gcry_derive_x931_prime (const gcry_mpi_t xp, { 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)) + if (mpi_is_neg (r1)) mpi_add (r1, r1, p1p2); /* yp0 = xp + (r1 - xp mod p1*p2) */ @@ -1350,7 +1350,7 @@ _gcry_derive_x931_prime (const gcry_mpi_t xp, mpi_free (r1); /* Fixup a negative value. */ - if (mpi_cmp (yp0, xp) < 0 ) + if (mpi_cmp (yp0, xp) < 0 ) mpi_add (yp0, yp0, p1p2); } @@ -1378,10 +1378,10 @@ _gcry_derive_x931_prime (const gcry_mpi_t xp, */ { - gcry_mpi_t val_2 = mpi_alloc_set_ui (2); + 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 (;;) @@ -1453,7 +1453,7 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits, ; /* 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) @@ -1468,7 +1468,7 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits, value_w = gcry_mpi_new (pbits); value_x = gcry_mpi_new (pbits); - restart: + restart: /* Generate Q. */ for (;;) { @@ -1479,7 +1479,7 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits, 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--) @@ -1492,16 +1492,16 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits, 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, + 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. */ @@ -1509,7 +1509,7 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits, /* 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; @@ -1518,12 +1518,12 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits, 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 + - ... + /* 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} + + (V_{n} mod 2^b)*2^{n*160} */ mpi_set_ui (value_w, 0); for (value_k=0; value_k <= value_n; value_k++) @@ -1542,7 +1542,7 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits, 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)); @@ -1631,7 +1631,7 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits, 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. @@ -1652,7 +1652,7 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits, 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; @@ -1690,10 +1690,10 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits, ; /* 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? + seed_plus = gcry_malloc (seedlen < sizeof seed_help_buffer? sizeof seed_help_buffer : seedlen); if (!seed_plus) { @@ -1709,7 +1709,7 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits, /* Step 4: b = L - 1 - (n * outlen) */ value_b = pbits - 1 - (value_n * qbits); - restart: + restart: /* Generate Q. */ for (;;) { @@ -1721,7 +1721,7 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits, 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); @@ -1736,12 +1736,12 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits, } } gcry_mpi_release (prime_q); prime_q = NULL; - ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG, + 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). */ @@ -1751,7 +1751,7 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits, /* 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); @@ -1761,12 +1761,12 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits, 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 + - ... + /* 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} + + (V_{n} mod 2^b)*2^{n*outlen} */ mpi_set_ui (value_w, 0); for (value_j=0; value_j <= value_n; value_j++) @@ -1783,7 +1783,7 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits, 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)); @@ -1813,7 +1813,7 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits, 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++; @@ -1859,3 +1859,4 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits, gcry_mpi_release (val_2); return ec; } + diff --git a/grub-core/lib/libgcrypt/cipher/pubkey.c b/lib/libgcrypt/cipher/pubkey.c similarity index 52% rename from grub-core/lib/libgcrypt/cipher/pubkey.c rename to lib/libgcrypt/cipher/pubkey.c index ca087ad75..08abcbfde 100644 --- a/grub-core/lib/libgcrypt/cipher/pubkey.c +++ b/lib/libgcrypt/cipher/pubkey.c @@ -1,6 +1,6 @@ /* pubkey.c - pubkey dispatcher - * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005, - * 2007, 2008, 2011 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005, + * 2007, 2008 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -55,7 +55,7 @@ static struct pubkey_table_entry gcry_pk_spec_t *pubkey; pk_extra_spec_t *extraspec; unsigned int algorithm; - int fips_allowed; + int fips_allowed; } pubkey_table[] = { #if USE_RSA @@ -75,8 +75,6 @@ static struct pubkey_table_entry #if USE_ECC { &_gcry_pubkey_spec_ecdsa, &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDSA, 0 }, - { &_gcry_pubkey_spec_ecdh, - &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDH, 0 }, #endif { NULL, 0 }, }; @@ -87,7 +85,7 @@ 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 whether the default pubkeys have already been +/* Flag to check wether the default pubkeys have already been registered. */ static int default_pubkeys_registered; @@ -199,7 +197,7 @@ 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) \ @@ -217,8 +215,8 @@ pk_register_default (void) err = _gcry_module_add (&pubkeys_registered, pubkey_table[i].algorithm, - (void *) pubkey_table[i].pubkey, - (void *) pubkey_table[i].extraspec, + (void *) pubkey_table[i].pubkey, + (void *) pubkey_table[i].extraspec, NULL); } @@ -242,7 +240,7 @@ gcry_pk_lookup_func_name (void *spec, void *data) } /* Internal function. Lookup a pubkey entry by it's name. */ -static gcry_module_t +static gcry_module_t gcry_pk_lookup_name (const char *name) { gcry_module_t pubkey; @@ -271,8 +269,8 @@ _gcry_pk_register (gcry_pk_spec_t *pubkey, ath_mutex_lock (&pubkeys_registered_lock); err = _gcry_module_add (&pubkeys_registered, 0, - (void *) pubkey, - (void *)(extraspec? extraspec : &dummy_extra_spec), + (void *) pubkey, + (void *)(extraspec? extraspec : &dummy_extra_spec), &mod); ath_mutex_unlock (&pubkeys_registered_lock); @@ -561,13 +559,13 @@ pubkey_generate (int algorithm, if (extraspec && extraspec->ext_generate) { /* Use the extended generate function. */ - ec = extraspec->ext_generate + 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 + ec = ((gcry_pk_spec_t *) pubkey->spec)->generate (algorithm, nbits, use_e, skey, retfactors); } _gcry_module_release (pubkey); @@ -617,7 +615,7 @@ pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data, /* Note: In fips mode DBG_CIPHER will enver evaluate to true but as an extra failsafe protection we explicitly test for fips mode - here. */ + here. */ if (DBG_CIPHER && !fips_mode ()) { log_debug ("pubkey_encrypt: algo=%d\n", algorithm); @@ -686,7 +684,7 @@ pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data, } rc = GPG_ERR_PUBKEY_ALGO; - + ready: ath_mutex_unlock (&pubkeys_registered_lock); @@ -760,10 +758,10 @@ pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data, { log_debug ("pubkey_verify: algo=%d\n", algorithm); for (i = 0; i < pubkey_get_npkey (algorithm); i++) - log_mpidump (" pkey", pkey[i]); + log_mpidump (" pkey:", pkey[i]); for (i = 0; i < pubkey_get_nsig (algorithm); i++) - log_mpidump (" sig", data[i]); - log_mpidump (" hash", hash); + log_mpidump (" sig:", data[i]); + log_mpidump (" hash:", hash); } ath_mutex_lock (&pubkeys_registered_lock); @@ -784,1018 +782,6 @@ pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data, } -/* Turn VALUE into an octet string and store it in an allocated buffer - at R_FRAME or - if R_RAME is NULL - copy it into the caller - provided buffer SPACE; either SPACE or R_FRAME may be used. If - SPACE if not NULL, the caller must provide a buffer of at least - NBYTES. If the resulting octet string is shorter than NBYTES pad - it to the left with zeroes. If VALUE does not fit into NBYTES - return an error code. */ -static gpg_err_code_t -octet_string_from_mpi (unsigned char **r_frame, void *space, - gcry_mpi_t value, size_t nbytes) -{ - gpg_err_code_t rc; - size_t nframe, noff, n; - unsigned char *frame; - - if (!r_frame == !space) - return GPG_ERR_INV_ARG; /* Only one may be used. */ - - if (r_frame) - *r_frame = NULL; - - rc = gcry_err_code (gcry_mpi_print (GCRYMPI_FMT_USG, - NULL, 0, &nframe, value)); - if (rc) - return rc; - if (nframe > nbytes) - return GPG_ERR_TOO_LARGE; /* Value too long to fit into NBYTES. */ - - noff = (nframe < nbytes)? nbytes - nframe : 0; - n = nframe + noff; - if (space) - frame = space; - else - { - frame = mpi_is_secure (value)? gcry_malloc_secure (n) : gcry_malloc (n); - if (!frame) - { - rc = gpg_err_code_from_syserror (); - return rc; - } - } - if (noff) - memset (frame, 0, noff); - nframe += noff; - rc = gcry_err_code (gcry_mpi_print (GCRYMPI_FMT_USG, - frame+noff, nframe-noff, NULL, value)); - if (rc) - { - gcry_free (frame); - return rc; - } - - if (r_frame) - *r_frame = frame; - return 0; -} - - -/* Encode {VALUE,VALUELEN} for an NBITS keys using the pkcs#1 block - type 2 padding. On sucess the result is stored as a new MPI at - R_RESULT. On error the value at R_RESULT is undefined. - - If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as - the seed instead of using a random string for it. This feature is - only useful for regression tests. Note that this value may not - contain zero bytes. - - We encode the value in this way: - - 0 2 RND(n bytes) 0 VALUE - - 0 is a marker we unfortunately can't encode because we return an - MPI which strips all leading zeroes. - 2 is the block type. - RND are non-zero random bytes. - - (Note that OpenPGP includes the cipher algorithm and a checksum in - VALUE; the caller needs to prepare the value accordingly.) - */ -static gcry_err_code_t -pkcs1_encode_for_encryption (gcry_mpi_t *r_result, unsigned int nbits, - const unsigned char *value, size_t valuelen, - const unsigned char *random_override, - size_t random_override_len) -{ - gcry_err_code_t rc = 0; - gcry_error_t err; - unsigned char *frame = NULL; - size_t nframe = (nbits+7) / 8; - int i; - size_t n; - unsigned char *p; - - if (valuelen + 7 > nframe || !nframe) - { - /* Can't encode a VALUELEN value in a NFRAME bytes frame. */ - return GPG_ERR_TOO_SHORT; /* The key is too short. */ - } - - if ( !(frame = gcry_malloc_secure (nframe))) - return gpg_err_code_from_syserror (); - - n = 0; - frame[n++] = 0; - frame[n++] = 2; /* block type */ - i = nframe - 3 - valuelen; - gcry_assert (i > 0); - - if (random_override) - { - int j; - - if (random_override_len != i) - { - gcry_free (frame); - return GPG_ERR_INV_ARG; - } - /* Check that random does not include a zero byte. */ - for (j=0; j < random_override_len; j++) - if (!random_override[j]) - { - gcry_free (frame); - return GPG_ERR_INV_ARG; - } - memcpy (frame + n, random_override, random_override_len); - n += random_override_len; - } - else - { - 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); - - err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe); - if (err) - rc = gcry_err_code (err); - else if (DBG_CIPHER) - log_mpidump ("PKCS#1 block type 2 encoded data", *r_result); - gcry_free (frame); - - return rc; -} - - -/* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding. - NBITS is the size of the secret key. On success the result is - stored as a newly allocated buffer at R_RESULT and its valid length at - R_RESULTLEN. On error NULL is stored at R_RESULT. */ -static gcry_err_code_t -pkcs1_decode_for_encryption (unsigned char **r_result, size_t *r_resultlen, - unsigned int nbits, gcry_mpi_t value) -{ - gcry_error_t err; - unsigned char *frame = NULL; - size_t nframe = (nbits+7) / 8; - size_t n; - - *r_result = NULL; - - if ( !(frame = gcry_malloc_secure (nframe))) - return gpg_err_code_from_syserror (); - - err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, value); - if (err) - { - gcry_free (frame); - return gcry_err_code (err); - } - - nframe = n; /* Set NFRAME to the actual length. */ - - /* FRAME = 0x00 || 0x02 || PS || 0x00 || M - - pkcs#1 requires that the first byte is zero. Our MPIs usually - strip leading zero bytes; thus we are not able to detect them. - However due to the way gcry_mpi_print is implemented we may see - leading zero bytes nevertheless. We handle this by making the - first zero byte optional. */ - if (nframe < 4) - { - gcry_free (frame); - return GPG_ERR_ENCODING_PROBLEM; /* Too short. */ - } - n = 0; - if (!frame[0]) - n++; - if (frame[n++] != 0x02) - { - gcry_free (frame); - return GPG_ERR_ENCODING_PROBLEM; /* Wrong block type. */ - } - - /* Skip the non-zero random bytes and the terminating zero byte. */ - for (; n < nframe && frame[n] != 0x00; n++) - ; - if (n+1 >= nframe) - { - gcry_free (frame); - return GPG_ERR_ENCODING_PROBLEM; /* No zero byte. */ - } - n++; /* Skip the zero byte. */ - - /* To avoid an extra allocation we reuse the frame buffer. The only - caller of this function will anyway free the result soon. */ - memmove (frame, frame + n, nframe - n); - *r_result = frame; - *r_resultlen = nframe - n; - - if (DBG_CIPHER) - log_printhex ("value extracted from PKCS#1 block type 2 encoded data:", - *r_result, *r_resultlen); - - return 0; -} - - -/* Encode {VALUE,VALUELEN} for an NBITS keys and hash algorith ALGO - using the pkcs#1 block type 1 padding. On success the result is - stored as a new MPI at R_RESULT. On error the value at R_RESULT is - undefined. - - We encode the value in this way: - - 0 1 PAD(n bytes) 0 ASN(asnlen bytes) VALUE(valuelen bytes) - - 0 is a marker we unfortunately can't encode because we return an - MPI which strips all leading zeroes. - 1 is the block type. - PAD consists of 0xff bytes. - 0 marks the end of the padding. - ASN is the DER encoding of the hash algorithm; along with the VALUE - it yields a valid DER encoding. - - (Note that PGP prior to version 2.3 encoded the message digest as: - 0 1 MD(16 bytes) 0 PAD(n bytes) 1 - The MD is always 16 bytes here because it's always MD5. GnuPG - does not not support pre-v2.3 signatures, but I'm including this - comment so the information is easily found if needed.) -*/ -static gcry_err_code_t -pkcs1_encode_for_signature (gcry_mpi_t *r_result, unsigned int nbits, - const unsigned char *value, size_t valuelen, - int algo) -{ - gcry_err_code_t rc = 0; - gcry_error_t err; - byte asn[100]; - byte *frame = NULL; - size_t nframe = (nbits+7) / 8; - int i; - size_t n; - size_t asnlen, dlen; - - asnlen = DIM(asn); - dlen = gcry_md_get_algo_dlen (algo); - - if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen)) - { - /* We don't have yet all of the above algorithms. */ - return GPG_ERR_NOT_IMPLEMENTED; - } - - if ( valuelen != dlen ) - { - /* Hash value does not match the length of digest for - the given algorithm. */ - return GPG_ERR_CONFLICT; - } - - if ( !dlen || dlen + asnlen + 4 > nframe) - { - /* Can't encode an DLEN byte digest MD into an NFRAME byte - frame. */ - return GPG_ERR_TOO_SHORT; - } - - if ( !(frame = gcry_malloc (nframe)) ) - return gpg_err_code_from_syserror (); - - /* 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. */ - err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe); - if (err) - rc = gcry_err_code (err); - else if (DBG_CIPHER) - log_mpidump ("PKCS#1 block type 1 encoded data", *r_result); - gcry_free (frame); - - return rc; -} - - -/* Mask generation function for OAEP. See RFC-3447 B.2.1. */ -static gcry_err_code_t -mgf1 (unsigned char *output, size_t outlen, unsigned char *seed, size_t seedlen, - int algo) -{ - size_t dlen, nbytes, n; - int idx; - gcry_md_hd_t hd; - gcry_error_t err; - - err = gcry_md_open (&hd, algo, 0); - if (err) - return gpg_err_code (err); - - dlen = gcry_md_get_algo_dlen (algo); - - /* We skip step 1 which would be assert(OUTLEN <= 2^32). The loop - in step 3 is merged with step 4 by concatenating no more octets - than what would fit into OUTPUT. The ceiling for the counter IDX - is implemented indirectly. */ - nbytes = 0; /* Step 2. */ - idx = 0; - while ( nbytes < outlen ) - { - unsigned char c[4], *digest; - - if (idx) - gcry_md_reset (hd); - - c[0] = (idx >> 24) & 0xFF; - c[1] = (idx >> 16) & 0xFF; - c[2] = (idx >> 8) & 0xFF; - c[3] = idx & 0xFF; - idx++; - - gcry_md_write (hd, seed, seedlen); - gcry_md_write (hd, c, 4); - digest = gcry_md_read (hd, 0); - - n = (outlen - nbytes < dlen)? (outlen - nbytes) : dlen; - memcpy (output+nbytes, digest, n); - nbytes += n; - } - - gcry_md_close (hd); - return GPG_ERR_NO_ERROR; -} - - -/* RFC-3447 (pkcs#1 v2.1) OAEP encoding. NBITS is the length of the - key measured in bits. ALGO is the hash function; it must be a - valid and usable algorithm. {VALUE,VALUELEN} is the message to - encrypt. {LABEL,LABELLEN} is the optional label to be associated - with the message, if LABEL is NULL the default is to use the empty - string as label. On success the encoded ciphertext is returned at - R_RESULT. - - If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as - the seed instead of using a random string for it. This feature is - only useful for regression tests. - - Here is figure 1 from the RFC depicting the process: - - +----------+---------+-------+ - DB = | lHash | PS | M | - +----------+---------+-------+ - | - +----------+ V - | seed |--> MGF ---> xor - +----------+ | - | | - +--+ V | - |00| xor <----- MGF <-----| - +--+ | | - | | | - V V V - +--+----------+----------------------------+ - EM = |00|maskedSeed| maskedDB | - +--+----------+----------------------------+ - */ -static gcry_err_code_t -oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo, - const unsigned char *value, size_t valuelen, - const unsigned char *label, size_t labellen, - const void *random_override, size_t random_override_len) -{ - gcry_err_code_t rc = 0; - gcry_error_t err; - unsigned char *frame = NULL; - size_t nframe = (nbits+7) / 8; - unsigned char *p; - size_t hlen; - size_t n; - - *r_result = NULL; - - /* Set defaults for LABEL. */ - if (!label || !labellen) - { - label = (const unsigned char*)""; - labellen = 0; - } - - hlen = gcry_md_get_algo_dlen (algo); - - /* We skip step 1a which would be to check that LABELLEN is not - greater than 2^61-1. See rfc-3447 7.1.1. */ - - /* Step 1b. Note that the obsolete rfc-2437 uses the check: - valuelen > nframe - 2 * hlen - 1 . */ - if (valuelen > nframe - 2 * hlen - 2 || !nframe) - { - /* Can't encode a VALUELEN value in a NFRAME bytes frame. */ - return GPG_ERR_TOO_SHORT; /* The key is too short. */ - } - - /* Allocate the frame. */ - frame = gcry_calloc_secure (1, nframe); - if (!frame) - return gpg_err_code_from_syserror (); - - /* Step 2a: Compute the hash of the label. We store it in the frame - where later the maskedDB will commence. */ - gcry_md_hash_buffer (algo, frame + 1 + hlen, label, labellen); - - /* Step 2b: Set octet string to zero. */ - /* This has already been done while allocating FRAME. */ - - /* Step 2c: Create DB by concatenating lHash, PS, 0x01 and M. */ - n = nframe - valuelen - 1; - frame[n] = 0x01; - memcpy (frame + n + 1, value, valuelen); - - /* Step 3d: Generate seed. We store it where the maskedSeed will go - later. */ - if (random_override) - { - if (random_override_len != hlen) - { - gcry_free (frame); - return GPG_ERR_INV_ARG; - } - memcpy (frame + 1, random_override, hlen); - } - else - gcry_randomize (frame + 1, hlen, GCRY_STRONG_RANDOM); - - /* Step 2e and 2f: Create maskedDB. */ - { - unsigned char *dmask; - - dmask = gcry_malloc_secure (nframe - hlen - 1); - if (!dmask) - { - rc = gpg_err_code_from_syserror (); - gcry_free (frame); - return rc; - } - rc = mgf1 (dmask, nframe - hlen - 1, frame+1, hlen, algo); - if (rc) - { - gcry_free (dmask); - gcry_free (frame); - return rc; - } - for (n = 1 + hlen, p = dmask; n < nframe; n++) - frame[n] ^= *p++; - gcry_free (dmask); - } - - /* Step 2g and 2h: Create maskedSeed. */ - { - unsigned char *smask; - - smask = gcry_malloc_secure (hlen); - if (!smask) - { - rc = gpg_err_code_from_syserror (); - gcry_free (frame); - return rc; - } - rc = mgf1 (smask, hlen, frame + 1 + hlen, nframe - hlen - 1, algo); - if (rc) - { - gcry_free (smask); - gcry_free (frame); - return rc; - } - for (n = 1, p = smask; n < 1 + hlen; n++) - frame[n] ^= *p++; - gcry_free (smask); - } - - /* Step 2i: Concatenate 0x00, maskedSeed and maskedDB. */ - /* This has already been done by using in-place operations. */ - - /* Convert the stuff into an MPI as expected by the caller. */ - err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, nframe, NULL); - if (err) - rc = gcry_err_code (err); - else if (DBG_CIPHER) - log_mpidump ("OAEP encoded data", *r_result); - gcry_free (frame); - - return rc; -} - - -/* RFC-3447 (pkcs#1 v2.1) OAEP decoding. NBITS is the length of the - key measured in bits. ALGO is the hash function; it must be a - valid and usable algorithm. VALUE is the raw decrypted message - {LABEL,LABELLEN} is the optional label to be associated with the - message, if LABEL is NULL the default is to use the empty string as - label. On success the plaintext is returned as a newly allocated - buffer at R_RESULT; its valid length is stored at R_RESULTLEN. On - error NULL is stored at R_RESULT. */ -static gcry_err_code_t -oaep_decode (unsigned char **r_result, size_t *r_resultlen, - unsigned int nbits, int algo, - gcry_mpi_t value, const unsigned char *label, size_t labellen) -{ - gcry_err_code_t rc; - unsigned char *frame = NULL; /* Encoded messages (EM). */ - unsigned char *masked_seed; /* Points into FRAME. */ - unsigned char *masked_db; /* Points into FRAME. */ - unsigned char *seed = NULL; /* Allocated space for the seed and DB. */ - unsigned char *db; /* Points into SEED. */ - unsigned char *lhash = NULL; /* Hash of the label. */ - size_t nframe; /* Length of the ciphertext (EM). */ - size_t hlen; /* Length of the hash digest. */ - size_t db_len; /* Length of DB and masked_db. */ - size_t nkey = (nbits+7)/8; /* Length of the key in bytes. */ - int failed = 0; /* Error indicator. */ - size_t n; - - *r_result = NULL; - - /* This code is implemented as described by rfc-3447 7.1.2. */ - - /* Set defaults for LABEL. */ - if (!label || !labellen) - { - label = (const unsigned char*)""; - labellen = 0; - } - - /* Get the length of the digest. */ - hlen = gcry_md_get_algo_dlen (algo); - - /* Hash the label right away. */ - lhash = gcry_malloc (hlen); - if (!lhash) - return gpg_err_code_from_syserror (); - gcry_md_hash_buffer (algo, lhash, label, labellen); - - /* Turn the MPI into an octet string. If the octet string is - shorter than the key we pad it to the left with zeroes. This may - happen due to the leading zero in OAEP frames and due to the - following random octets (seed^mask) which may have leading zero - bytes. This all is needed to cope with our leading zeroes - suppressing MPI implementation. The code implictly implements - Step 1b (bail out if NFRAME != N). */ - rc = octet_string_from_mpi (&frame, NULL, value, nkey); - if (rc) - { - gcry_free (lhash); - return GPG_ERR_ENCODING_PROBLEM; - } - nframe = nkey; - - /* Step 1c: Check that the key is long enough. */ - if ( nframe < 2 * hlen + 2 ) - { - gcry_free (frame); - gcry_free (lhash); - return GPG_ERR_ENCODING_PROBLEM; - } - - /* Step 2 has already been done by the caller and the - gcry_mpi_aprint above. */ - - /* Allocate space for SEED and DB. */ - seed = gcry_malloc_secure (nframe - 1); - if (!seed) - { - rc = gpg_err_code_from_syserror (); - gcry_free (frame); - gcry_free (lhash); - return rc; - } - db = seed + hlen; - - /* To avoid choosen ciphertext attacks from now on we make sure to - run all code even in the error case; this avoids possible timing - attacks as described by Manger. */ - - /* Step 3a: Hash the label. */ - /* This has already been done. */ - - /* Step 3b: Separate the encoded message. */ - masked_seed = frame + 1; - masked_db = frame + 1 + hlen; - db_len = nframe - 1 - hlen; - - /* Step 3c and 3d: seed = maskedSeed ^ mgf(maskedDB, hlen). */ - if (mgf1 (seed, hlen, masked_db, db_len, algo)) - failed = 1; - for (n = 0; n < hlen; n++) - seed[n] ^= masked_seed[n]; - - /* Step 3e and 3f: db = maskedDB ^ mgf(seed, db_len). */ - if (mgf1 (db, db_len, seed, hlen, algo)) - failed = 1; - for (n = 0; n < db_len; n++) - db[n] ^= masked_db[n]; - - /* Step 3g: Check lhash, an possible empty padding string terminated - by 0x01 and the first byte of EM being 0. */ - if (memcmp (lhash, db, hlen)) - failed = 1; - for (n = hlen; n < db_len; n++) - if (db[n] == 0x01) - break; - if (n == db_len) - failed = 1; - if (frame[0]) - failed = 1; - - gcry_free (lhash); - gcry_free (frame); - if (failed) - { - gcry_free (seed); - return GPG_ERR_ENCODING_PROBLEM; - } - - /* Step 4: Output M. */ - /* To avoid an extra allocation we reuse the seed buffer. The only - caller of this function will anyway free the result soon. */ - n++; - memmove (seed, db + n, db_len - n); - *r_result = seed; - *r_resultlen = db_len - n; - seed = NULL; - - if (DBG_CIPHER) - log_printhex ("value extracted from OAEP encoded data:", - *r_result, *r_resultlen); - - return 0; -} - - -/* RFC-3447 (pkcs#1 v2.1) PSS encoding. Encode {VALUE,VALUELEN} for - an NBITS key. Note that VALUE is already the mHash from the - picture below. ALGO is a valid hash algorithm and SALTLEN is the - length of salt to be used. On success the result is stored as a - new MPI at R_RESULT. On error the value at R_RESULT is undefined. - - If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as - the salt instead of using a random string for the salt. This - feature is only useful for regression tests. - - Here is figure 2 from the RFC (errata 595 applied) depicting the - process: - - +-----------+ - | M | - +-----------+ - | - V - Hash - | - V - +--------+----------+----------+ - M' = |Padding1| mHash | salt | - +--------+----------+----------+ - | - +--------+----------+ V - DB = |Padding2| salt | Hash - +--------+----------+ | - | | - V | +----+ - xor <--- MGF <---| |0xbc| - | | +----+ - | | | - V V V - +-------------------+----------+----+ - EM = | maskedDB | H |0xbc| - +-------------------+----------+----+ - - */ -static gcry_err_code_t -pss_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo, - const unsigned char *value, size_t valuelen, int saltlen, - const void *random_override, size_t random_override_len) -{ - gcry_err_code_t rc = 0; - gcry_error_t err; - size_t hlen; /* Length of the hash digest. */ - unsigned char *em = NULL; /* Encoded message. */ - size_t emlen = (nbits+7)/8; /* Length in bytes of EM. */ - unsigned char *h; /* Points into EM. */ - unsigned char *buf = NULL; /* Help buffer. */ - size_t buflen; /* Length of BUF. */ - unsigned char *mhash; /* Points into BUF. */ - unsigned char *salt; /* Points into BUF. */ - unsigned char *dbmask; /* Points into BUF. */ - unsigned char *p; - size_t n; - - /* This code is implemented as described by rfc-3447 9.1.1. */ - - /* Get the length of the digest. */ - hlen = gcry_md_get_algo_dlen (algo); - gcry_assert (hlen); /* We expect a valid ALGO here. */ - - /* Allocate a help buffer and setup some pointers. */ - buflen = 8 + hlen + saltlen + (emlen - hlen - 1); - buf = gcry_malloc (buflen); - if (!buf) - { - rc = gpg_err_code_from_syserror (); - goto leave; - } - mhash = buf + 8; - salt = mhash + hlen; - dbmask= salt + saltlen; - - /* Step 2: That would be: mHash = Hash(M) but our input is already - mHash thus we do only a consistency check and copy to MHASH. */ - if (valuelen != hlen) - { - rc = GPG_ERR_INV_LENGTH; - goto leave; - } - memcpy (mhash, value, hlen); - - /* Step 3: Check length constraints. */ - if (emlen < hlen + saltlen + 2) - { - rc = GPG_ERR_TOO_SHORT; - goto leave; - } - - /* Allocate space for EM. */ - em = gcry_malloc (emlen); - if (!em) - { - rc = gpg_err_code_from_syserror (); - goto leave; - } - h = em + emlen - 1 - hlen; - - /* Step 4: Create a salt. */ - if (saltlen) - { - if (random_override) - { - if (random_override_len != saltlen) - { - rc = GPG_ERR_INV_ARG; - goto leave; - } - memcpy (salt, random_override, saltlen); - } - else - gcry_randomize (salt, saltlen, GCRY_STRONG_RANDOM); - } - - /* Step 5 and 6: M' = Hash(Padding1 || mHash || salt). */ - memset (buf, 0, 8); /* Padding. */ - gcry_md_hash_buffer (algo, h, buf, 8 + hlen + saltlen); - - /* Step 7 and 8: DB = PS || 0x01 || salt. */ - /* Note that we use EM to store DB and later Xor in-place. */ - p = em + emlen - 1 - hlen - saltlen - 1; - memset (em, 0, p - em); - *p++ = 0x01; - memcpy (p, salt, saltlen); - - /* Step 9: dbmask = MGF(H, emlen - hlen - 1). */ - mgf1 (dbmask, emlen - hlen - 1, h, hlen, algo); - - /* Step 10: maskedDB = DB ^ dbMask */ - for (n = 0, p = dbmask; n < emlen - hlen - 1; n++, p++) - em[n] ^= *p; - - /* Step 11: Set the leftmost bits to zero. */ - em[0] &= 0xFF >> (8 * emlen - nbits); - - /* Step 12: EM = maskedDB || H || 0xbc. */ - em[emlen-1] = 0xbc; - - /* Convert EM into an MPI. */ - err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, em, emlen, NULL); - if (err) - rc = gcry_err_code (err); - else if (DBG_CIPHER) - log_mpidump ("PSS encoded data", *r_result); - - leave: - if (em) - { - wipememory (em, emlen); - gcry_free (em); - } - if (buf) - { - wipememory (buf, buflen); - gcry_free (buf); - } - return rc; -} - - -/* Verify a signature assuming PSS padding. VALUE is the hash of the - message (mHash) encoded as an MPI; its length must match the digest - length of ALGO. ENCODED is the output of the RSA public key - function (EM). NBITS is the size of the public key. ALGO is the - hash algorithm and SALTLEN is the length of the used salt. The - function returns 0 on success or on error code. */ -static gcry_err_code_t -pss_verify (gcry_mpi_t value, gcry_mpi_t encoded, unsigned int nbits, int algo, - size_t saltlen) -{ - gcry_err_code_t rc = 0; - size_t hlen; /* Length of the hash digest. */ - unsigned char *em = NULL; /* Encoded message. */ - size_t emlen = (nbits+7)/8; /* Length in bytes of EM. */ - unsigned char *salt; /* Points into EM. */ - unsigned char *h; /* Points into EM. */ - unsigned char *buf = NULL; /* Help buffer. */ - size_t buflen; /* Length of BUF. */ - unsigned char *dbmask; /* Points into BUF. */ - unsigned char *mhash; /* Points into BUF. */ - unsigned char *p; - size_t n; - - /* This code is implemented as described by rfc-3447 9.1.2. */ - - /* Get the length of the digest. */ - hlen = gcry_md_get_algo_dlen (algo); - gcry_assert (hlen); /* We expect a valid ALGO here. */ - - /* Allocate a help buffer and setup some pointers. - This buffer is used for two purposes: - +------------------------------+-------+ - 1. | dbmask | mHash | - +------------------------------+-------+ - emlen - hlen - 1 hlen - - +----------+-------+---------+-+-------+ - 2. | padding1 | mHash | salt | | mHash | - +----------+-------+---------+-+-------+ - 8 hlen saltlen hlen - */ - buflen = 8 + hlen + saltlen; - if (buflen < emlen - hlen - 1) - buflen = emlen - hlen - 1; - buflen += hlen; - buf = gcry_malloc (buflen); - if (!buf) - { - rc = gpg_err_code_from_syserror (); - goto leave; - } - dbmask = buf; - mhash = buf + buflen - hlen; - - /* Step 2: That would be: mHash = Hash(M) but our input is already - mHash thus we only need to convert VALUE into MHASH. */ - rc = octet_string_from_mpi (NULL, mhash, value, hlen); - if (rc) - goto leave; - - /* Convert the signature into an octet string. */ - rc = octet_string_from_mpi (&em, NULL, encoded, emlen); - if (rc) - goto leave; - - /* Step 3: Check length of EM. Because we internally use MPI - functions we can't do this properly; EMLEN is always the length - of the key because octet_string_from_mpi needs to left pad the - result with zero to cope with the fact that our MPIs suppress all - leading zeroes. Thus what we test here are merely the digest and - salt lengths to the key. */ - if (emlen < hlen + saltlen + 2) - { - rc = GPG_ERR_TOO_SHORT; /* For the hash and saltlen. */ - goto leave; - } - - /* Step 4: Check last octet. */ - if (em[emlen - 1] != 0xbc) - { - rc = GPG_ERR_BAD_SIGNATURE; - goto leave; - } - - /* Step 5: Split EM. */ - h = em + emlen - 1 - hlen; - - /* Step 6: Check the leftmost bits. */ - if ((em[0] & ~(0xFF >> (8 * emlen - nbits)))) - { - rc = GPG_ERR_BAD_SIGNATURE; - goto leave; - } - - /* Step 7: dbmask = MGF(H, emlen - hlen - 1). */ - mgf1 (dbmask, emlen - hlen - 1, h, hlen, algo); - - /* Step 8: maskedDB = DB ^ dbMask. */ - for (n = 0, p = dbmask; n < emlen - hlen - 1; n++, p++) - em[n] ^= *p; - - /* Step 9: Set leftmost bits in DB to zero. */ - em[0] &= 0xFF >> (8 * emlen - nbits); - - /* Step 10: Check the padding of DB. */ - for (n = 0; n < emlen - hlen - saltlen - 2 && !em[n]; n++) - ; - if (n != emlen - hlen - saltlen - 2 || em[n++] != 1) - { - rc = GPG_ERR_BAD_SIGNATURE; - goto leave; - } - - /* Step 11: Extract salt from DB. */ - salt = em + n; - - /* Step 12: M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt */ - memset (buf, 0, 8); - memcpy (buf+8, mhash, hlen); - memcpy (buf+8+hlen, salt, saltlen); - - /* Step 13: H' = Hash(M'). */ - gcry_md_hash_buffer (algo, buf, buf, 8 + hlen + saltlen); - - /* Step 14: Check H == H'. */ - rc = memcmp (h, buf, hlen) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR; - - leave: - if (em) - { - wipememory (em, emlen); - gcry_free (em); - } - if (buf) - { - wipememory (buf, buflen); - gcry_free (buf); - } - return rc; -} - - -/* Callback for the pubkey algorithm code to verify PSS signatures. - OPAQUE is the data provided by the actual caller. The meaning of - TMP depends on the actual algorithm (but there is only RSA); now - for RSA it is the output of running the public key function on the - input. */ -static int -pss_verify_cmp (void *opaque, gcry_mpi_t tmp) -{ - struct pk_encoding_ctx *ctx = opaque; - gcry_mpi_t hash = ctx->verify_arg; - - return pss_verify (hash, tmp, ctx->nbits - 1, ctx->hash_algo, ctx->saltlen); -} - - /* Internal function. */ static gcry_err_code_t sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names, @@ -1869,11 +855,7 @@ sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names, /* Clear the array for easier error cleanup. */ for (name = element_names, idx = 0; *name; name++, idx++) elements[idx] = NULL; - gcry_assert (idx >= 5); /* We know that ECC has at least 5 elements - (params only) or 6 (full public key). */ - if (idx == 5) - elements[5] = NULL; /* Extra clear for the params only case. */ - + 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++) @@ -1902,23 +884,23 @@ sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names, { 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; + 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]) @@ -1942,7 +924,7 @@ sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names, err = GPG_ERR_NO_OBJ; goto leave; } - + leave: if (err) { @@ -1966,7 +948,6 @@ sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names, * openpgp-elg * openpgp-elg-sig * ecdsa - * ecdh * 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 @@ -1974,10 +955,6 @@ sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names, * NOTE: we look through the list to find a list beginning with * "private-key" or "public-key" - the first one found is used. * - * If OVERRIDE_ELEMS is not NULL those elems override the parameter - * specification taken from the module. This ise used by - * gcry_pk_get_curve. - * * Returns: A pointer to an allocated array of MPIs if the return value is * zero; the caller has to release this array. * @@ -1993,8 +970,8 @@ sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names, * The are expected to be in GCRYMPI_FMT_USG */ static gcry_err_code_t -sexp_to_key (gcry_sexp_t sexp, int want_private, const char *override_elems, - gcry_mpi_t **retarray, gcry_module_t *retalgo) +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; @@ -2007,7 +984,7 @@ sexp_to_key (gcry_sexp_t sexp, int want_private, const char *override_elems, int is_ecc; /* Check that the first element is valid. */ - list = gcry_sexp_find_token (sexp, + 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. */ @@ -2025,18 +1002,16 @@ sexp_to_key (gcry_sexp_t sexp, int want_private, const char *override_elems, 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, "ecdh") - || !strcmp (name, "ecc") ); + algorithm which has many flavours. */ + is_ecc = ( !strcmp (name, "ecdsa") || !strcmp (name, "ecc") ); gcry_free (name); - + if (!module) { gcry_sexp_release (list); @@ -2048,15 +1023,10 @@ sexp_to_key (gcry_sexp_t sexp, int want_private, const char *override_elems, extraspec = module->extraspec; } - if (override_elems) - elems = override_elems; - else if (want_private) - elems = pubkey->elements_skey; - else - elems = pubkey->elements_pkey; + elems = want_private ? pubkey->elements_skey : pubkey->elements_pkey; array = gcry_calloc (strlen (elems) + 1, sizeof (*array)); if (!array) - err = gpg_err_code_from_syserror (); + err = gpg_err_code_from_errno (errno); if (!err) { if (is_ecc) @@ -2064,9 +1034,9 @@ sexp_to_key (gcry_sexp_t sexp, int want_private, const char *override_elems, else err = sexp_elements_extract (list, elems, array, pubkey->name); } - + gcry_sexp_release (list); - + if (err) { gcry_free (array); @@ -2080,7 +1050,7 @@ sexp_to_key (gcry_sexp_t sexp, int want_private, const char *override_elems, *retarray = array; *retalgo = module; } - + return err; } @@ -2096,7 +1066,7 @@ sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray, 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) @@ -2115,7 +1085,7 @@ sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_sexp_release (l2); return GPG_ERR_INV_OBJ; /* Invalid structure of object. */ } - else if (!strcmp (name, "flags")) + else if (!strcmp (name, "flags")) { /* Skip flags, since they are not used but here just for the sake of consistent S-expressions. */ @@ -2129,7 +1099,7 @@ sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray, } 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); @@ -2148,7 +1118,7 @@ sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray, elems = pubkey->elements_sig; array = gcry_calloc (strlen (elems) + 1 , sizeof *array ); if (!array) - err = gpg_err_code_from_syserror (); + err = gpg_err_code_from_errno (errno); if (!err) err = sexp_elements_extract (list, elems, array, NULL); @@ -2161,7 +1131,7 @@ sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray, ath_mutex_lock (&pubkeys_registered_lock); _gcry_module_release (module); ath_mutex_unlock (&pubkeys_registered_lock); - + gcry_free (array); } else @@ -2169,82 +1139,26 @@ sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray, *retarray = array; *retalgo = module; } - + return err; } -static inline int -get_hash_algo (const char *s, size_t n) -{ - static const 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; - int i; - - 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); - } - } - return algo; -} - /**************** * Take sexp and return an array of MPI as used for our internal decrypt * function. * s_data = (enc-val - * [(flags [raw, pkcs1, oaep, no-blinding])] - * [(hash-algo )] - * [(label